summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/.cvsignore16
-rw-r--r--cpukit/ChangeLog8894
-rw-r--r--cpukit/Makefile.am173
-rw-r--r--cpukit/acinclude.m421
-rw-r--r--cpukit/aclocal/canonical-target-name.m440
-rw-r--r--cpukit/aclocal/canonicalize-tools.m415
-rw-r--r--cpukit/aclocal/check-itron.m416
-rw-r--r--cpukit/aclocal/check-multiprocessing.m49
-rw-r--r--cpukit/aclocal/check-networking.m428
-rw-r--r--cpukit/aclocal/check-newlib.m430
-rw-r--r--cpukit/aclocal/check-posix.m423
-rw-r--r--cpukit/aclocal/check-rtems-debug.m47
-rw-r--r--cpukit/aclocal/check-tool.m411
-rw-r--r--cpukit/aclocal/enable-inlines.m411
-rw-r--r--cpukit/aclocal/enable-itron.m412
-rw-r--r--cpukit/aclocal/enable-multiprocessing.m412
-rw-r--r--cpukit/aclocal/enable-networking.m414
-rw-r--r--cpukit/aclocal/enable-posix.m433
-rw-r--r--cpukit/aclocal/enable-rtems-debug.m412
-rw-r--r--cpukit/aclocal/env-rtemscpu.m48
-rw-r--r--cpukit/aclocal/gcc-pipe.m421
-rw-r--r--cpukit/aclocal/gcc-weak.m419
-rw-r--r--cpukit/aclocal/multi.m452
-rw-r--r--cpukit/aclocal/multilib.m414
-rw-r--r--cpukit/aclocal/prog-cc.m436
-rw-r--r--cpukit/aclocal/prog-ccas.m48
-rw-r--r--cpukit/aclocal/prog-gnat.m445
-rw-r--r--cpukit/aclocal/rtems-ampolish.m411
-rw-r--r--cpukit/aclocal/rtems-top.m470
-rw-r--r--cpukit/aclocal/sysv-ipc.m4125
-rw-r--r--cpukit/aclocal/version.m42
-rwxr-xr-xcpukit/ampolish3276
-rw-r--r--cpukit/automake/compile.am7
-rw-r--r--cpukit/automake/local.am5
-rw-r--r--cpukit/automake/multilib.am36
-rw-r--r--cpukit/automake/subdirs.am32
-rw-r--r--cpukit/backward/asm.h12
-rw-r--r--cpukit/backward/chain.h12
-rw-r--r--cpukit/backward/clockdrv.h12
-rw-r--r--cpukit/backward/confdefs.h12
-rw-r--r--cpukit/backward/console.h12
-rw-r--r--cpukit/backward/dosfs.h12
-rw-r--r--cpukit/backward/ftpd.h12
-rw-r--r--cpukit/backward/imfs.h12
-rw-r--r--cpukit/backward/iosupp.h12
-rw-r--r--cpukit/backward/itron.h12
-rw-r--r--cpukit/backward/motorola/mc68230.h12
-rw-r--r--cpukit/backward/motorola/mc68681.h12
-rw-r--r--cpukit/backward/ringbuf.h12
-rw-r--r--cpukit/backward/rtc.h12
-rw-r--r--cpukit/backward/rtemsdialer.h12
-rw-r--r--cpukit/backward/rtemspppd.h12
-rw-r--r--cpukit/backward/spurious.h12
-rw-r--r--cpukit/backward/timerdrv.h12
-rw-r--r--cpukit/backward/vmeintr.h12
-rw-r--r--cpukit/backward/zilog/z8030.h12
-rw-r--r--cpukit/backward/zilog/z8036.h12
-rw-r--r--cpukit/backward/zilog/z8536.h12
-rw-r--r--cpukit/configure.ac323
-rw-r--r--cpukit/ftpd/.cvsignore2
-rw-r--r--cpukit/ftpd/Makefile.am13
-rw-r--r--cpukit/ftpd/ftpd.c2062
-rw-r--r--cpukit/ftpd/ftpd.h56
-rw-r--r--cpukit/ftpd/preinstall.am25
-rw-r--r--cpukit/httpd/.cvsignore2
-rw-r--r--cpukit/httpd/Makefile.am29
-rw-r--r--cpukit/httpd/NOTES36
-rw-r--r--cpukit/httpd/asp.c321
-rw-r--r--cpukit/httpd/balloc.c967
-rw-r--r--cpukit/httpd/cgi.c331
-rw-r--r--cpukit/httpd/default.c431
-rw-r--r--cpukit/httpd/ej.h46
-rw-r--r--cpukit/httpd/ejIntrn.h230
-rw-r--r--cpukit/httpd/ejlex.c721
-rw-r--r--cpukit/httpd/ejparse.c1804
-rw-r--r--cpukit/httpd/emfdb.c1050
-rw-r--r--cpukit/httpd/emfdb.h101
-rw-r--r--cpukit/httpd/form.c168
-rw-r--r--cpukit/httpd/h.c194
-rw-r--r--cpukit/httpd/handler.c411
-rw-r--r--cpukit/httpd/license.txt282
-rw-r--r--cpukit/httpd/md5.h50
-rw-r--r--cpukit/httpd/md5c.c337
-rw-r--r--cpukit/httpd/mime.c116
-rw-r--r--cpukit/httpd/misc.c675
-rw-r--r--cpukit/httpd/preinstall.am78
-rw-r--r--cpukit/httpd/ringq.c584
-rw-r--r--cpukit/httpd/rom.c193
-rw-r--r--cpukit/httpd/rtems_webserver.h17
-rw-r--r--cpukit/httpd/security.c235
-rw-r--r--cpukit/httpd/sock.c791
-rw-r--r--cpukit/httpd/sockGen.c1043
-rw-r--r--cpukit/httpd/socket.c1024
-rw-r--r--cpukit/httpd/sym.c474
-rw-r--r--cpukit/httpd/uemf.c293
-rw-r--r--cpukit/httpd/uemf.h1110
-rw-r--r--cpukit/httpd/um.c1435
-rw-r--r--cpukit/httpd/um.h183
-rw-r--r--cpukit/httpd/umui.c641
-rw-r--r--cpukit/httpd/url.c212
-rw-r--r--cpukit/httpd/value.c1213
-rw-r--r--cpukit/httpd/wbase64.c149
-rw-r--r--cpukit/httpd/webcomp.c188
-rw-r--r--cpukit/httpd/webmain.c499
-rw-r--r--cpukit/httpd/webpage.c141
-rw-r--r--cpukit/httpd/webrom.c15
-rw-r--r--cpukit/httpd/webs.c2966
-rw-r--r--cpukit/httpd/webs.h233
-rw-r--r--cpukit/httpd/websSSL.c706
-rw-r--r--cpukit/httpd/websSSL.h67
-rw-r--r--cpukit/httpd/websda.c244
-rw-r--r--cpukit/httpd/websda.h41
-rw-r--r--cpukit/httpd/websuemf.c217
-rw-r--r--cpukit/httpd/wsIntrn.h309
-rw-r--r--cpukit/include/rtems/bspIo.h39
-rw-r--r--cpukit/include/rtems/concat.h22
-rw-r--r--cpukit/include/rtems/fs.h59
-rw-r--r--cpukit/include/rtems/irq.h217
-rw-r--r--cpukit/include/rtems/pci.h1225
-rw-r--r--cpukit/include/rtems/stdint.h40
-rw-r--r--cpukit/include/rtems/tar.h53
-rw-r--r--cpukit/include/rtems/userenv.h88
-rw-r--r--cpukit/itron/.cvsignore2
-rw-r--r--cpukit/itron/Makefile.am119
-rw-r--r--cpukit/itron/include/itron.h55
-rw-r--r--cpukit/itron/include/itronsys/README9
-rw-r--r--cpukit/itron/include/itronsys/eventflags.h149
-rw-r--r--cpukit/itron/include/itronsys/fmempool.h128
-rw-r--r--cpukit/itron/include/itronsys/intr.h109
-rw-r--r--cpukit/itron/include/itronsys/mbox.h141
-rw-r--r--cpukit/itron/include/itronsys/msgbuffer.h163
-rw-r--r--cpukit/itron/include/itronsys/network.h81
-rw-r--r--cpukit/itron/include/itronsys/port.h193
-rw-r--r--cpukit/itron/include/itronsys/semaphore.h124
-rw-r--r--cpukit/itron/include/itronsys/status.h73
-rw-r--r--cpukit/itron/include/itronsys/sysmgmt.h322
-rw-r--r--cpukit/itron/include/itronsys/task.h301
-rw-r--r--cpukit/itron/include/itronsys/time.h188
-rw-r--r--cpukit/itron/include/itronsys/types.h124
-rw-r--r--cpukit/itron/include/itronsys/vmempool.h135
-rw-r--r--cpukit/itron/include/rtems/itron/README10
-rw-r--r--cpukit/itron/include/rtems/itron/config.h66
-rw-r--r--cpukit/itron/include/rtems/itron/eventflags.h64
-rw-r--r--cpukit/itron/include/rtems/itron/fmempool.h65
-rw-r--r--cpukit/itron/include/rtems/itron/intr.h34
-rw-r--r--cpukit/itron/include/rtems/itron/itronapi.h34
-rw-r--r--cpukit/itron/include/rtems/itron/mbox.h76
-rw-r--r--cpukit/itron/include/rtems/itron/msgbuffer.h76
-rw-r--r--cpukit/itron/include/rtems/itron/network.h34
-rw-r--r--cpukit/itron/include/rtems/itron/object.h123
-rw-r--r--cpukit/itron/include/rtems/itron/port.h64
-rw-r--r--cpukit/itron/include/rtems/itron/semaphore.h62
-rw-r--r--cpukit/itron/include/rtems/itron/sysmgmt.h34
-rw-r--r--cpukit/itron/include/rtems/itron/task.h105
-rw-r--r--cpukit/itron/include/rtems/itron/time.h34
-rw-r--r--cpukit/itron/include/rtems/itron/vmempool.h65
-rw-r--r--cpukit/itron/inline/rtems/itron/eventflags.inl155
-rw-r--r--cpukit/itron/inline/rtems/itron/fmempool.inl162
-rw-r--r--cpukit/itron/inline/rtems/itron/intr.inl34
-rw-r--r--cpukit/itron/inline/rtems/itron/mbox.inl155
-rw-r--r--cpukit/itron/inline/rtems/itron/msgbuffer.inl160
-rw-r--r--cpukit/itron/inline/rtems/itron/network.inl34
-rw-r--r--cpukit/itron/inline/rtems/itron/port.inl155
-rw-r--r--cpukit/itron/inline/rtems/itron/semaphore.inl187
-rw-r--r--cpukit/itron/inline/rtems/itron/sysmgmt.inl34
-rw-r--r--cpukit/itron/inline/rtems/itron/task.inl185
-rw-r--r--cpukit/itron/inline/rtems/itron/time.inl34
-rw-r--r--cpukit/itron/inline/rtems/itron/vmempool.inl165
-rw-r--r--cpukit/itron/macros/rtems/itron/eventflags.inl80
-rw-r--r--cpukit/itron/macros/rtems/itron/fmempool.inl82
-rw-r--r--cpukit/itron/macros/rtems/itron/intr.inl34
-rw-r--r--cpukit/itron/macros/rtems/itron/mbox.inl79
-rw-r--r--cpukit/itron/macros/rtems/itron/msgbuffer.inl82
-rw-r--r--cpukit/itron/macros/rtems/itron/network.inl34
-rw-r--r--cpukit/itron/macros/rtems/itron/port.inl79
-rw-r--r--cpukit/itron/macros/rtems/itron/semaphore.inl106
-rw-r--r--cpukit/itron/macros/rtems/itron/sysmgmt.inl34
-rw-r--r--cpukit/itron/macros/rtems/itron/task.inl106
-rw-r--r--cpukit/itron/macros/rtems/itron/time.inl34
-rw-r--r--cpukit/itron/macros/rtems/itron/vmempool.inl85
-rw-r--r--cpukit/itron/preinstall.am250
-rw-r--r--cpukit/itron/src/.cvsignore4
-rw-r--r--cpukit/itron/src/TODO13
-rw-r--r--cpukit/itron/src/can_wup.c52
-rw-r--r--cpukit/itron/src/chg_pri.c68
-rw-r--r--cpukit/itron/src/cre_mbf.c89
-rw-r--r--cpukit/itron/src/cre_mbx.c107
-rw-r--r--cpukit/itron/src/cre_sem.c98
-rw-r--r--cpukit/itron/src/cre_tsk.c120
-rw-r--r--cpukit/itron/src/del_mbf.c58
-rw-r--r--cpukit/itron/src/del_mbx.c68
-rw-r--r--cpukit/itron/src/del_sem.c68
-rw-r--r--cpukit/itron/src/del_tsk.c58
-rw-r--r--cpukit/itron/src/dis_dsp.c40
-rw-r--r--cpukit/itron/src/ena_dsp.c36
-rw-r--r--cpukit/itron/src/eventflags.c159
-rw-r--r--cpukit/itron/src/exd_tsk.c46
-rw-r--r--cpukit/itron/src/ext_tsk.c46
-rw-r--r--cpukit/itron/src/fmempool.c142
-rw-r--r--cpukit/itron/src/frsm_tsk.c60
-rw-r--r--cpukit/itron/src/get_tid.c41
-rw-r--r--cpukit/itron/src/itronintr.c110
-rw-r--r--cpukit/itron/src/itronsem.c60
-rw-r--r--cpukit/itron/src/itrontime.c247
-rw-r--r--cpukit/itron/src/mbox.c59
-rw-r--r--cpukit/itron/src/mboxtranslatereturncode.c48
-rw-r--r--cpukit/itron/src/msgbuffer.c60
-rw-r--r--cpukit/itron/src/msgbuffertranslatereturncode.c48
-rw-r--r--cpukit/itron/src/network.c71
-rw-r--r--cpukit/itron/src/port.c211
-rw-r--r--cpukit/itron/src/prcv_mbf.c34
-rw-r--r--cpukit/itron/src/prcv_mbx.c33
-rw-r--r--cpukit/itron/src/preq_sem.c33
-rw-r--r--cpukit/itron/src/psnd_mbf.c34
-rw-r--r--cpukit/itron/src/rcv_mbf.c34
-rw-r--r--cpukit/itron/src/rcv_mbx.c33
-rw-r--r--cpukit/itron/src/ref_mbf.c83
-rw-r--r--cpukit/itron/src/ref_mbx.c65
-rw-r--r--cpukit/itron/src/ref_sem.c65
-rw-r--r--cpukit/itron/src/ref_tsk.c99
-rw-r--r--cpukit/itron/src/rel_wai.c52
-rw-r--r--cpukit/itron/src/rot_rdq.c55
-rw-r--r--cpukit/itron/src/rsm_tsk.c60
-rw-r--r--cpukit/itron/src/sig_sem.c56
-rw-r--r--cpukit/itron/src/slp_tsk.c35
-rw-r--r--cpukit/itron/src/snd_mbf.c34
-rw-r--r--cpukit/itron/src/snd_mbx.c70
-rw-r--r--cpukit/itron/src/sta_tsk.c69
-rw-r--r--cpukit/itron/src/sus_tsk.c62
-rw-r--r--cpukit/itron/src/sysmgmt.c75
-rw-r--r--cpukit/itron/src/task.c227
-rw-r--r--cpukit/itron/src/ter_tsk.c58
-rw-r--r--cpukit/itron/src/trcv_mbf.c86
-rw-r--r--cpukit/itron/src/trcv_mbx.c76
-rw-r--r--cpukit/itron/src/tslp_tsk.c36
-rw-r--r--cpukit/itron/src/tsnd_mbf.c90
-rw-r--r--cpukit/itron/src/twai_sem.c69
-rw-r--r--cpukit/itron/src/vmempool.c145
-rw-r--r--cpukit/itron/src/wai_sem.c33
-rw-r--r--cpukit/itron/src/wup_tsk.c36
-rw-r--r--cpukit/libblock/.cvsignore2
-rw-r--r--cpukit/libblock/Makefile.am17
-rw-r--r--cpukit/libblock/README14
-rw-r--r--cpukit/libblock/include/rtems/bdbuf.h284
-rw-r--r--cpukit/libblock/include/rtems/blkdev.h154
-rw-r--r--cpukit/libblock/include/rtems/diskdevs.h209
-rw-r--r--cpukit/libblock/include/rtems/ide_part_table.h199
-rw-r--r--cpukit/libblock/include/rtems/ramdisk.h56
-rw-r--r--cpukit/libblock/preinstall.am7
-rw-r--r--cpukit/libblock/src/bdbuf.c1920
-rw-r--r--cpukit/libblock/src/blkdev.c249
-rw-r--r--cpukit/libblock/src/diskdevs.c635
-rw-r--r--cpukit/libblock/src/ide_part_table.c550
-rw-r--r--cpukit/libblock/src/ramdisk.c232
-rw-r--r--cpukit/libcsupport/.cvsignore2
-rw-r--r--cpukit/libcsupport/Makefile.am94
-rw-r--r--cpukit/libcsupport/include/chain.h365
-rw-r--r--cpukit/libcsupport/include/clockdrv.h54
-rw-r--r--cpukit/libcsupport/include/console.h72
-rw-r--r--cpukit/libcsupport/include/inttypes.h291
-rw-r--r--cpukit/libcsupport/include/iosupp.h46
-rw-r--r--cpukit/libcsupport/include/motorola/mc68230.h74
-rw-r--r--cpukit/libcsupport/include/motorola/mc68681.h309
-rw-r--r--cpukit/libcsupport/include/ringbuf.h55
-rw-r--r--cpukit/libcsupport/include/rtc.h41
-rw-r--r--cpukit/libcsupport/include/rtems/assoc.h46
-rw-r--r--cpukit/libcsupport/include/rtems/cdefs.h183
-rw-r--r--cpukit/libcsupport/include/rtems/error.h51
-rw-r--r--cpukit/libcsupport/include/rtems/libcsupport.h47
-rw-r--r--cpukit/libcsupport/include/rtems/libio.h645
-rw-r--r--cpukit/libcsupport/include/rtems/libio_.h258
-rw-r--r--cpukit/libcsupport/include/rtems/termiostypes.h181
-rw-r--r--cpukit/libcsupport/include/spurious.h42
-rw-r--r--cpukit/libcsupport/include/stdint.h284
-rw-r--r--cpukit/libcsupport/include/sys/cdefs.h180
-rw-r--r--cpukit/libcsupport/include/sys/filio.h59
-rw-r--r--cpukit/libcsupport/include/sys/ioccom.h99
-rw-r--r--cpukit/libcsupport/include/sys/ioctl.h66
-rw-r--r--cpukit/libcsupport/include/sys/sockio.h92
-rw-r--r--cpukit/libcsupport/include/sys/termios.h198
-rw-r--r--cpukit/libcsupport/include/sys/ttycom.h141
-rw-r--r--cpukit/libcsupport/include/sys/utsname.h55
-rw-r--r--cpukit/libcsupport/include/tar.h47
-rw-r--r--cpukit/libcsupport/include/timerdrv.h42
-rw-r--r--cpukit/libcsupport/include/vmeintr.h59
-rw-r--r--cpukit/libcsupport/include/zilog/z8036.h106
-rw-r--r--cpukit/libcsupport/include/zilog/z8530.h97
-rw-r--r--cpukit/libcsupport/include/zilog/z8536.h114
-rw-r--r--cpukit/libcsupport/preinstall.am114
-rw-r--r--cpukit/libcsupport/src/CASES23
-rw-r--r--cpukit/libcsupport/src/README37
-rw-r--r--cpukit/libcsupport/src/TODO14
-rw-r--r--cpukit/libcsupport/src/__brk.c32
-rw-r--r--cpukit/libcsupport/src/__getpid.c17
-rw-r--r--cpukit/libcsupport/src/__gettod.c120
-rw-r--r--cpukit/libcsupport/src/__sbrk.c32
-rw-r--r--cpukit/libcsupport/src/__times.c89
-rw-r--r--cpukit/libcsupport/src/access.c48
-rw-r--r--cpukit/libcsupport/src/assoc.c254
-rw-r--r--cpukit/libcsupport/src/assocnamebad.c39
-rw-r--r--cpukit/libcsupport/src/base_fs.c132
-rw-r--r--cpukit/libcsupport/src/cfgetispeed.c32
-rw-r--r--cpukit/libcsupport/src/cfgetospeed.c32
-rw-r--r--cpukit/libcsupport/src/cfsetispeed.c40
-rw-r--r--cpukit/libcsupport/src/cfsetospeed.c40
-rw-r--r--cpukit/libcsupport/src/chdir.c61
-rw-r--r--cpukit/libcsupport/src/chmod.c56
-rw-r--r--cpukit/libcsupport/src/chown.c49
-rw-r--r--cpukit/libcsupport/src/chroot.c54
-rw-r--r--cpukit/libcsupport/src/close.c58
-rw-r--r--cpukit/libcsupport/src/closedir.c74
-rw-r--r--cpukit/libcsupport/src/creat.c19
-rw-r--r--cpukit/libcsupport/src/ctermid.c37
-rw-r--r--cpukit/libcsupport/src/dup.c26
-rw-r--r--cpukit/libcsupport/src/dup2.c52
-rw-r--r--cpukit/libcsupport/src/envlock.c108
-rw-r--r--cpukit/libcsupport/src/error.c213
-rw-r--r--cpukit/libcsupport/src/eval.c123
-rw-r--r--cpukit/libcsupport/src/fchdir.c90
-rw-r--r--cpukit/libcsupport/src/fchmod.c48
-rw-r--r--cpukit/libcsupport/src/fcntl.c188
-rw-r--r--cpukit/libcsupport/src/fdatasync.c42
-rw-r--r--cpukit/libcsupport/src/fpathconf.c87
-rw-r--r--cpukit/libcsupport/src/fs_null_handlers.c41
-rw-r--r--cpukit/libcsupport/src/fstat.c80
-rw-r--r--cpukit/libcsupport/src/fsync.c45
-rw-r--r--cpukit/libcsupport/src/ftruncate.c57
-rw-r--r--cpukit/libcsupport/src/getcwd.c287
-rw-r--r--cpukit/libcsupport/src/getdents.c63
-rw-r--r--cpukit/libcsupport/src/getegid.c32
-rw-r--r--cpukit/libcsupport/src/geteuid.c33
-rw-r--r--cpukit/libcsupport/src/getgid.c47
-rw-r--r--cpukit/libcsupport/src/getgroups.c29
-rw-r--r--cpukit/libcsupport/src/getlogin.c64
-rw-r--r--cpukit/libcsupport/src/getpgrp.c31
-rw-r--r--cpukit/libcsupport/src/getpid.c44
-rw-r--r--cpukit/libcsupport/src/getppid.c28
-rw-r--r--cpukit/libcsupport/src/getpwent.c443
-rw-r--r--cpukit/libcsupport/src/getuid.c47
-rw-r--r--cpukit/libcsupport/src/gxx_wrappers.c244
-rw-r--r--cpukit/libcsupport/src/hosterr.c51
-rw-r--r--cpukit/libcsupport/src/ioctl.c60
-rw-r--r--cpukit/libcsupport/src/isatty.c31
-rw-r--r--cpukit/libcsupport/src/libio.c338
-rw-r--r--cpukit/libcsupport/src/libio_sockets.c75
-rw-r--r--cpukit/libcsupport/src/link.c104
-rw-r--r--cpukit/libcsupport/src/lseek.c101
-rw-r--r--cpukit/libcsupport/src/lstat.c22
-rw-r--r--cpukit/libcsupport/src/malloc.c621
-rw-r--r--cpukit/libcsupport/src/mallocfreespace.c44
-rw-r--r--cpukit/libcsupport/src/mkdir.c30
-rw-r--r--cpukit/libcsupport/src/mkfifo.c28
-rw-r--r--cpukit/libcsupport/src/mknod.c73
-rw-r--r--cpukit/libcsupport/src/mount.c291
-rw-r--r--cpukit/libcsupport/src/newlibc.c386
-rw-r--r--cpukit/libcsupport/src/no_libc.c59
-rw-r--r--cpukit/libcsupport/src/no_posix.c87
-rw-r--r--cpukit/libcsupport/src/open.c222
-rw-r--r--cpukit/libcsupport/src/opendir.c89
-rw-r--r--cpukit/libcsupport/src/pathconf.c41
-rw-r--r--cpukit/libcsupport/src/pipe.c26
-rw-r--r--cpukit/libcsupport/src/printk.c155
-rw-r--r--cpukit/libcsupport/src/privateenv.c163
-rw-r--r--cpukit/libcsupport/src/read.c71
-rw-r--r--cpukit/libcsupport/src/readdir.c90
-rw-r--r--cpukit/libcsupport/src/readdir_r.c26
-rw-r--r--cpukit/libcsupport/src/readlink.c57
-rw-r--r--cpukit/libcsupport/src/rewinddir.c39
-rw-r--r--cpukit/libcsupport/src/rmdir.c76
-rw-r--r--cpukit/libcsupport/src/scandir.c168
-rw-r--r--cpukit/libcsupport/src/seekdir.c44
-rw-r--r--cpukit/libcsupport/src/setpgid.c29
-rw-r--r--cpukit/libcsupport/src/setsid.c26
-rw-r--r--cpukit/libcsupport/src/stat.c104
-rw-r--r--cpukit/libcsupport/src/strlcat.c41
-rw-r--r--cpukit/libcsupport/src/strlcpy.c49
-rw-r--r--cpukit/libcsupport/src/symlink.c46
-rw-r--r--cpukit/libcsupport/src/sync.c89
-rw-r--r--cpukit/libcsupport/src/tcdrain.c36
-rw-r--r--cpukit/libcsupport/src/tcflow.c34
-rw-r--r--cpukit/libcsupport/src/tcflush.c34
-rw-r--r--cpukit/libcsupport/src/tcgetattr.c36
-rw-r--r--cpukit/libcsupport/src/tcgetprgrp.c34
-rw-r--r--cpukit/libcsupport/src/tcsendbreak.c34
-rw-r--r--cpukit/libcsupport/src/tcsetattr.c51
-rw-r--r--cpukit/libcsupport/src/tcsetpgrp.c34
-rw-r--r--cpukit/libcsupport/src/telldir.c47
-rw-r--r--cpukit/libcsupport/src/termios.c1502
-rw-r--r--cpukit/libcsupport/src/termiosinitialize.c54
-rw-r--r--cpukit/libcsupport/src/termiosreserveresources.c36
-rw-r--r--cpukit/libcsupport/src/truncate.c43
-rw-r--r--cpukit/libcsupport/src/ttyname.c111
-rw-r--r--cpukit/libcsupport/src/umask.c33
-rw-r--r--cpukit/libcsupport/src/unixlibc.c53
-rw-r--r--cpukit/libcsupport/src/unlink.c83
-rw-r--r--cpukit/libcsupport/src/unmount.c219
-rw-r--r--cpukit/libcsupport/src/utime.c46
-rw-r--r--cpukit/libcsupport/src/utsname.c53
-rw-r--r--cpukit/libcsupport/src/write.c78
-rw-r--r--cpukit/libfs/.cvsignore3
-rw-r--r--cpukit/libfs/Makefile.am56
-rw-r--r--cpukit/libfs/README13
-rw-r--r--cpukit/libfs/preinstall.am7
-rw-r--r--cpukit/libfs/src/dosfs/.cvsignore4
-rw-r--r--cpukit/libfs/src/dosfs/dosfs.h81
-rw-r--r--cpukit/libfs/src/dosfs/fat.c708
-rw-r--r--cpukit/libfs/src/dosfs/fat.h618
-rw-r--r--cpukit/libfs/src/dosfs/fat_fat_operations.c437
-rw-r--r--cpukit/libfs/src/dosfs/fat_fat_operations.h58
-rw-r--r--cpukit/libfs/src/dosfs/fat_file.c987
-rw-r--r--cpukit/libfs/src/dosfs/fat_file.h195
-rw-r--r--cpukit/libfs/src/dosfs/msdos.h434
-rw-r--r--cpukit/libfs/src/dosfs/msdos_conv.c273
-rw-r--r--cpukit/libfs/src/dosfs/msdos_create.c345
-rw-r--r--cpukit/libfs/src/dosfs/msdos_dir.c554
-rw-r--r--cpukit/libfs/src/dosfs/msdos_eval.c435
-rw-r--r--cpukit/libfs/src/dosfs/msdos_file.c485
-rw-r--r--cpukit/libfs/src/dosfs/msdos_format.c1007
-rw-r--r--cpukit/libfs/src/dosfs/msdos_free.c56
-rw-r--r--cpukit/libfs/src/dosfs/msdos_fsunmount.c71
-rw-r--r--cpukit/libfs/src/dosfs/msdos_handlers_dir.c36
-rw-r--r--cpukit/libfs/src/dosfs/msdos_handlers_file.c36
-rw-r--r--cpukit/libfs/src/dosfs/msdos_init.c64
-rw-r--r--cpukit/libfs/src/dosfs/msdos_initsupp.c149
-rw-r--r--cpukit/libfs/src/dosfs/msdos_misc.c943
-rw-r--r--cpukit/libfs/src/dosfs/msdos_mknod.c90
-rw-r--r--cpukit/libfs/src/dosfs/msdos_node_type.c58
-rw-r--r--cpukit/libfs/src/imfs/.cvsignore5
-rw-r--r--cpukit/libfs/src/imfs/deviceio.c257
-rw-r--r--cpukit/libfs/src/imfs/imfs.h539
-rw-r--r--cpukit/libfs/src/imfs/imfs_chown.c56
-rw-r--r--cpukit/libfs/src/imfs/imfs_config.c35
-rw-r--r--cpukit/libfs/src/imfs/imfs_creat.c137
-rw-r--r--cpukit/libfs/src/imfs/imfs_debug.c176
-rw-r--r--cpukit/libfs/src/imfs/imfs_directory.c351
-rw-r--r--cpukit/libfs/src/imfs/imfs_eval.c660
-rw-r--r--cpukit/libfs/src/imfs/imfs_fchmod.c65
-rw-r--r--cpukit/libfs/src/imfs/imfs_fcntl.c28
-rw-r--r--cpukit/libfs/src/imfs/imfs_fdatasync.c29
-rw-r--r--cpukit/libfs/src/imfs/imfs_free.c39
-rw-r--r--cpukit/libfs/src/imfs/imfs_fsunmount.c96
-rw-r--r--cpukit/libfs/src/imfs/imfs_getchild.c73
-rw-r--r--cpukit/libfs/src/imfs/imfs_gtkn.c90
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_device.c41
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_directory.c41
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_link.c41
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_memfile.c41
-rw-r--r--cpukit/libfs/src/imfs/imfs_init.c69
-rw-r--r--cpukit/libfs/src/imfs/imfs_initsupp.c125
-rw-r--r--cpukit/libfs/src/imfs/imfs_link.c75
-rw-r--r--cpukit/libfs/src/imfs/imfs_load_tar.c170
-rw-r--r--cpukit/libfs/src/imfs/imfs_mknod.c77
-rw-r--r--cpukit/libfs/src/imfs/imfs_mount.c53
-rw-r--r--cpukit/libfs/src/imfs/imfs_ntype.c32
-rw-r--r--cpukit/libfs/src/imfs/imfs_readlink.c44
-rw-r--r--cpukit/libfs/src/imfs/imfs_rmnod.c79
-rw-r--r--cpukit/libfs/src/imfs/imfs_stat.c68
-rw-r--r--cpukit/libfs/src/imfs/imfs_symlink.c62
-rw-r--r--cpukit/libfs/src/imfs/imfs_unixstub.c74
-rw-r--r--cpukit/libfs/src/imfs/imfs_unlink.c81
-rw-r--r--cpukit/libfs/src/imfs/imfs_unmount.c62
-rw-r--r--cpukit/libfs/src/imfs/imfs_utime.c41
-rw-r--r--cpukit/libfs/src/imfs/ioman.c107
-rw-r--r--cpukit/libfs/src/imfs/memfile.c1160
-rw-r--r--cpukit/libfs/src/imfs/miniimfs_init.c69
-rw-r--r--cpukit/libi2c/.cvsignore2
-rw-r--r--cpukit/libi2c/Makefile.am11
-rw-r--r--cpukit/libi2c/libi2c.c598
-rw-r--r--cpukit/libi2c/libi2c.h234
-rw-r--r--cpukit/libmisc/.cvsignore2
-rw-r--r--cpukit/libmisc/Makefile.am103
-rw-r--r--cpukit/libmisc/README23
-rw-r--r--cpukit/libmisc/capture/README255
-rw-r--r--cpukit/libmisc/capture/capture-cli.c1474
-rw-r--r--cpukit/libmisc/capture/capture-cli.h56
-rw-r--r--cpukit/libmisc/capture/capture.c1586
-rw-r--r--cpukit/libmisc/capture/capture.h884
-rw-r--r--cpukit/libmisc/cpuuse/README14
-rw-r--r--cpukit/libmisc/cpuuse/cpuuse.c139
-rw-r--r--cpukit/libmisc/cpuuse/cpuuse.h40
-rw-r--r--cpukit/libmisc/devnull/devnull.c184
-rw-r--r--cpukit/libmisc/devnull/devnull.h71
-rw-r--r--cpukit/libmisc/dummy/README23
-rw-r--r--cpukit/libmisc/dummy/dummy.c45
-rw-r--r--cpukit/libmisc/dumpbuf/dumpbuf.c79
-rw-r--r--cpukit/libmisc/dumpbuf/dumpbuf.h29
-rw-r--r--cpukit/libmisc/fsmount/README24
-rw-r--r--cpukit/libmisc/fsmount/fsmount.c200
-rw-r--r--cpukit/libmisc/fsmount/fsmount.h81
-rw-r--r--cpukit/libmisc/monitor/README97
-rw-r--r--cpukit/libmisc/monitor/mon-command.c745
-rw-r--r--cpukit/libmisc/monitor/mon-config.c136
-rw-r--r--cpukit/libmisc/monitor/mon-dname.c116
-rw-r--r--cpukit/libmisc/monitor/mon-driver.c140
-rw-r--r--cpukit/libmisc/monitor/mon-extension.c102
-rw-r--r--cpukit/libmisc/monitor/mon-itask.c122
-rw-r--r--cpukit/libmisc/monitor/mon-manager.c58
-rw-r--r--cpukit/libmisc/monitor/mon-monitor.c591
-rw-r--r--cpukit/libmisc/monitor/mon-mpci.c162
-rw-r--r--cpukit/libmisc/monitor/mon-object.c392
-rw-r--r--cpukit/libmisc/monitor/mon-prmisc.c269
-rw-r--r--cpukit/libmisc/monitor/mon-queue.c68
-rw-r--r--cpukit/libmisc/monitor/mon-server.c307
-rw-r--r--cpukit/libmisc/monitor/mon-symbols.c486
-rw-r--r--cpukit/libmisc/monitor/mon-task.c96
-rw-r--r--cpukit/libmisc/monitor/monitor.h458
-rw-r--r--cpukit/libmisc/monitor/symbols.h64
-rw-r--r--cpukit/libmisc/mw-fb/mw_fb.c194
-rw-r--r--cpukit/libmisc/mw-fb/mw_fb.h170
-rw-r--r--cpukit/libmisc/mw-fb/mw_uid.c248
-rw-r--r--cpukit/libmisc/mw-fb/mw_uid.h160
-rw-r--r--cpukit/libmisc/preinstall.am7
-rw-r--r--cpukit/libmisc/rtmonuse/rtmonuse.c208
-rw-r--r--cpukit/libmisc/rtmonuse/rtmonuse.h30
-rw-r--r--cpukit/libmisc/serdbg/README138
-rw-r--r--cpukit/libmisc/serdbg/serdbg.c94
-rw-r--r--cpukit/libmisc/serdbg/serdbg.h181
-rw-r--r--cpukit/libmisc/serdbg/serdbgcnf.h89
-rw-r--r--cpukit/libmisc/serdbg/serdbgio.c256
-rw-r--r--cpukit/libmisc/serdbg/termios_printk.c237
-rw-r--r--cpukit/libmisc/serdbg/termios_printk.h104
-rw-r--r--cpukit/libmisc/serdbg/termios_printk_cnf.h78
-rw-r--r--cpukit/libmisc/shell/README27
-rw-r--r--cpukit/libmisc/shell/cmds.c526
-rw-r--r--cpukit/libmisc/shell/shell.c691
-rw-r--r--cpukit/libmisc/shell/shell.h91
-rw-r--r--cpukit/libmisc/stackchk/README53
-rw-r--r--cpukit/libmisc/stackchk/check.c553
-rw-r--r--cpukit/libmisc/stackchk/internal.h95
-rw-r--r--cpukit/libmisc/stackchk/stackchk.h82
-rw-r--r--cpukit/libmisc/untar/README26
-rw-r--r--cpukit/libmisc/untar/untar.c373
-rw-r--r--cpukit/libmisc/untar/untar.h49
-rw-r--r--cpukit/libnetworking/.cvsignore2
-rw-r--r--cpukit/libnetworking/Makefile.am201
-rw-r--r--cpukit/libnetworking/README72
-rw-r--r--cpukit/libnetworking/arpa/ftp.h111
-rw-r--r--cpukit/libnetworking/arpa/inet.h140
-rw-r--r--cpukit/libnetworking/arpa/nameser.h453
-rw-r--r--cpukit/libnetworking/arpa/nameser_compat.h194
-rw-r--r--cpukit/libnetworking/bpfilter.h5
-rw-r--r--cpukit/libnetworking/dev/mii/mii.h206
-rw-r--r--cpukit/libnetworking/kern/kern_mib.c385
-rw-r--r--cpukit/libnetworking/kern/kern_subr.c203
-rw-r--r--cpukit/libnetworking/kern/kern_sysctl.c1541
-rw-r--r--cpukit/libnetworking/kern/uipc_domain.c228
-rw-r--r--cpukit/libnetworking/kern/uipc_mbuf.c750
-rw-r--r--cpukit/libnetworking/kern/uipc_socket.c1142
-rw-r--r--cpukit/libnetworking/kern/uipc_socket2.c964
-rw-r--r--cpukit/libnetworking/lib/README5
-rw-r--r--cpukit/libnetworking/lib/ftpfs.c1160
-rw-r--r--cpukit/libnetworking/lib/getprotoby.c46
-rw-r--r--cpukit/libnetworking/lib/rtems_bsdnet_ntp.c213
-rw-r--r--cpukit/libnetworking/lib/syslog.c190
-rw-r--r--cpukit/libnetworking/lib/tftpDriver.c1049
-rw-r--r--cpukit/libnetworking/libc/addr2ascii.3217
-rw-r--r--cpukit/libnetworking/libc/addr2ascii.c94
-rw-r--r--cpukit/libnetworking/libc/ascii2addr.c74
-rw-r--r--cpukit/libnetworking/libc/base64.c318
-rw-r--r--cpukit/libnetworking/libc/byteorder.377
-rw-r--r--cpukit/libnetworking/libc/ether_addr.c226
-rw-r--r--cpukit/libnetworking/libc/ethers.3193
-rw-r--r--cpukit/libnetworking/libc/gethostbydns.c775
-rw-r--r--cpukit/libnetworking/libc/gethostbyht.c202
-rw-r--r--cpukit/libnetworking/libc/gethostbyname.3305
-rw-r--r--cpukit/libnetworking/libc/gethostbynis.c142
-rw-r--r--cpukit/libnetworking/libc/gethostnamadr.c224
-rw-r--r--cpukit/libnetworking/libc/gethostname.c26
-rw-r--r--cpukit/libnetworking/libc/getnetbydns.c313
-rw-r--r--cpukit/libnetworking/libc/getnetbyht.c173
-rw-r--r--cpukit/libnetworking/libc/getnetbynis.c177
-rw-r--r--cpukit/libnetworking/libc/getnetent.3159
-rw-r--r--cpukit/libnetworking/libc/getnetnamadr.c190
-rw-r--r--cpukit/libnetworking/libc/getproto.c62
-rw-r--r--cpukit/libnetworking/libc/getprotoent.3147
-rw-r--r--cpukit/libnetworking/libc/getprotoent.c121
-rw-r--r--cpukit/libnetworking/libc/getprotoname.c69
-rw-r--r--cpukit/libnetworking/libc/getservbyname.c81
-rw-r--r--cpukit/libnetworking/libc/getservbyport.c76
-rw-r--r--cpukit/libnetworking/libc/getservent.3156
-rw-r--r--cpukit/libnetworking/libc/getservent.c281
-rw-r--r--cpukit/libnetworking/libc/herror.c122
-rw-r--r--cpukit/libnetworking/libc/inet.3210
-rw-r--r--cpukit/libnetworking/libc/inet_addr.c180
-rw-r--r--cpukit/libnetworking/libc/inet_lnaof.c61
-rw-r--r--cpukit/libnetworking/libc/inet_makeaddr.c64
-rw-r--r--cpukit/libnetworking/libc/inet_net_ntop.c140
-rw-r--r--cpukit/libnetworking/libc/inet_net_pton.c207
-rw-r--r--cpukit/libnetworking/libc/inet_neta.c84
-rw-r--r--cpukit/libnetworking/libc/inet_netof.c60
-rw-r--r--cpukit/libnetworking/libc/inet_network.c92
-rw-r--r--cpukit/libnetworking/libc/inet_ntoa.c60
-rw-r--r--cpukit/libnetworking/libc/inet_ntop.c193
-rw-r--r--cpukit/libnetworking/libc/inet_pton.c214
-rw-r--r--cpukit/libnetworking/libc/iso_addr.3111
-rw-r--r--cpukit/libnetworking/libc/iso_addr.c119
-rw-r--r--cpukit/libnetworking/libc/linkaddr.3138
-rw-r--r--cpukit/libnetworking/libc/linkaddr.c161
-rw-r--r--cpukit/libnetworking/libc/map_v4v6.c128
-rw-r--r--cpukit/libnetworking/libc/ns.3131
-rw-r--r--cpukit/libnetworking/libc/ns_addr.c229
-rw-r--r--cpukit/libnetworking/libc/ns_name.c595
-rw-r--r--cpukit/libnetworking/libc/ns_netint.c56
-rw-r--r--cpukit/libnetworking/libc/ns_ntoa.c102
-rw-r--r--cpukit/libnetworking/libc/ns_parse.c192
-rw-r--r--cpukit/libnetworking/libc/ns_print.c745
-rw-r--r--cpukit/libnetworking/libc/ns_ttl.c153
-rw-r--r--cpukit/libnetworking/libc/nsap_addr.c105
-rw-r--r--cpukit/libnetworking/libc/rcmd.3204
-rw-r--r--cpukit/libnetworking/libc/rcmd.c547
-rw-r--r--cpukit/libnetworking/libc/recv.c52
-rw-r--r--cpukit/libnetworking/libc/res_comp.c258
-rw-r--r--cpukit/libnetworking/libc/res_config.h20
-rw-r--r--cpukit/libnetworking/libc/res_data.c83
-rw-r--r--cpukit/libnetworking/libc/res_debug.c966
-rw-r--r--cpukit/libnetworking/libc/res_init.c502
-rw-r--r--cpukit/libnetworking/libc/res_mkquery.c199
-rw-r--r--cpukit/libnetworking/libc/res_mkupdate.c415
-rw-r--r--cpukit/libnetworking/libc/res_query.c410
-rw-r--r--cpukit/libnetworking/libc/res_send.c932
-rw-r--r--cpukit/libnetworking/libc/res_stubs.c75
-rw-r--r--cpukit/libnetworking/libc/res_update.c518
-rw-r--r--cpukit/libnetworking/libc/resolver.3352
-rw-r--r--cpukit/libnetworking/libc/send.c52
-rw-r--r--cpukit/libnetworking/libc/strsep.c85
-rw-r--r--cpukit/libnetworking/loop.h5
-rw-r--r--cpukit/libnetworking/machine/conf.h5
-rw-r--r--cpukit/libnetworking/machine/cpu.h5
-rw-r--r--cpukit/libnetworking/machine/cpufunc.h5
-rw-r--r--cpukit/libnetworking/machine/endian.h66
-rw-r--r--cpukit/libnetworking/machine/in_cksum.h226
-rw-r--r--cpukit/libnetworking/machine/limits.h5
-rw-r--r--cpukit/libnetworking/machine/vmparam.h5
-rw-r--r--cpukit/libnetworking/memory.h5
-rw-r--r--cpukit/libnetworking/net/bpf.h236
-rw-r--r--cpukit/libnetworking/net/bsd-comp.c1117
-rw-r--r--cpukit/libnetworking/net/ethernet.h387
-rw-r--r--cpukit/libnetworking/net/if.c780
-rw-r--r--cpukit/libnetworking/net/if.h291
-rw-r--r--cpukit/libnetworking/net/if_arp.h130
-rw-r--r--cpukit/libnetworking/net/if_dl.h86
-rw-r--r--cpukit/libnetworking/net/if_ethersubr.c899
-rw-r--r--cpukit/libnetworking/net/if_llc.h166
-rw-r--r--cpukit/libnetworking/net/if_loop.c300
-rw-r--r--cpukit/libnetworking/net/if_media.h527
-rw-r--r--cpukit/libnetworking/net/if_ppp.c1771
-rw-r--r--cpukit/libnetworking/net/if_ppp.h134
-rw-r--r--cpukit/libnetworking/net/if_pppvar.h141
-rw-r--r--cpukit/libnetworking/net/if_types.h255
-rw-r--r--cpukit/libnetworking/net/if_var.h256
-rw-r--r--cpukit/libnetworking/net/netisr.h86
-rw-r--r--cpukit/libnetworking/net/ppp-comp.h165
-rw-r--r--cpukit/libnetworking/net/ppp-deflate.c683
-rw-r--r--cpukit/libnetworking/net/ppp_defs.h184
-rw-r--r--cpukit/libnetworking/net/ppp_tty.c956
-rw-r--r--cpukit/libnetworking/net/pppcompress.c594
-rw-r--r--cpukit/libnetworking/net/pppcompress.h164
-rw-r--r--cpukit/libnetworking/net/radix.c1074
-rw-r--r--cpukit/libnetworking/net/radix.h162
-rw-r--r--cpukit/libnetworking/net/raw_cb.c148
-rw-r--r--cpukit/libnetworking/net/raw_cb.h75
-rw-r--r--cpukit/libnetworking/net/raw_usrreq.c315
-rw-r--r--cpukit/libnetworking/net/route.c959
-rw-r--r--cpukit/libnetworking/net/route.h298
-rw-r--r--cpukit/libnetworking/net/rtsock.c797
-rw-r--r--cpukit/libnetworking/net/slcompress.c612
-rw-r--r--cpukit/libnetworking/net/slcompress.h157
-rw-r--r--cpukit/libnetworking/netdb.h192
-rw-r--r--cpukit/libnetworking/netinet/icmp_var.h80
-rw-r--r--cpukit/libnetworking/netinet/if_ether.c651
-rw-r--r--cpukit/libnetworking/netinet/if_ether.h178
-rw-r--r--cpukit/libnetworking/netinet/igmp.c479
-rw-r--r--cpukit/libnetworking/netinet/igmp.h96
-rw-r--r--cpukit/libnetworking/netinet/igmp_var.h105
-rw-r--r--cpukit/libnetworking/netinet/in.c723
-rw-r--r--cpukit/libnetworking/netinet/in.h468
-rw-r--r--cpukit/libnetworking/netinet/in_cksum.c176
-rw-r--r--cpukit/libnetworking/netinet/in_cksum_arm.h276
-rw-r--r--cpukit/libnetworking/netinet/in_cksum_i386.h204
-rw-r--r--cpukit/libnetworking/netinet/in_cksum_m68k.h223
-rw-r--r--cpukit/libnetworking/netinet/in_cksum_powerpc.h173
-rw-r--r--cpukit/libnetworking/netinet/in_pcb.c760
-rw-r--r--cpukit/libnetworking/netinet/in_pcb.h157
-rw-r--r--cpukit/libnetworking/netinet/in_proto.c202
-rw-r--r--cpukit/libnetworking/netinet/in_rmx.c383
-rw-r--r--cpukit/libnetworking/netinet/in_systm.h62
-rw-r--r--cpukit/libnetworking/netinet/in_var.h238
-rw-r--r--cpukit/libnetworking/netinet/ip.h229
-rw-r--r--cpukit/libnetworking/netinet/ip_divert.c379
-rw-r--r--cpukit/libnetworking/netinet/ip_fw.c1074
-rw-r--r--cpukit/libnetworking/netinet/ip_fw.h183
-rw-r--r--cpukit/libnetworking/netinet/ip_icmp.c742
-rw-r--r--cpukit/libnetworking/netinet/ip_icmp.h208
-rw-r--r--cpukit/libnetworking/netinet/ip_input.c1488
-rw-r--r--cpukit/libnetworking/netinet/ip_mroute.c2303
-rw-r--r--cpukit/libnetworking/netinet/ip_mroute.h262
-rw-r--r--cpukit/libnetworking/netinet/ip_output.c1307
-rw-r--r--cpukit/libnetworking/netinet/ip_var.h216
-rw-r--r--cpukit/libnetworking/netinet/raw_ip.c486
-rw-r--r--cpukit/libnetworking/netinet/tcp.h137
-rw-r--r--cpukit/libnetworking/netinet/tcp_debug.c172
-rw-r--r--cpukit/libnetworking/netinet/tcp_debug.h69
-rw-r--r--cpukit/libnetworking/netinet/tcp_fsm.h92
-rw-r--r--cpukit/libnetworking/netinet/tcp_input.c2165
-rw-r--r--cpukit/libnetworking/netinet/tcp_output.c755
-rw-r--r--cpukit/libnetworking/netinet/tcp_seq.h102
-rw-r--r--cpukit/libnetworking/netinet/tcp_subr.c740
-rw-r--r--cpukit/libnetworking/netinet/tcp_timer.c387
-rw-r--r--cpukit/libnetworking/netinet/tcp_timer.h133
-rw-r--r--cpukit/libnetworking/netinet/tcp_usrreq.c839
-rw-r--r--cpukit/libnetworking/netinet/tcp_var.h422
-rw-r--r--cpukit/libnetworking/netinet/tcpip.h75
-rw-r--r--cpukit/libnetworking/netinet/udp.h51
-rw-r--r--cpukit/libnetworking/netinet/udp_usrreq.c728
-rw-r--r--cpukit/libnetworking/netinet/udp_var.h102
-rw-r--r--cpukit/libnetworking/nfs/bootp_subr.c1159
-rw-r--r--cpukit/libnetworking/nfs/krpc.h26
-rw-r--r--cpukit/libnetworking/nfs/nfs.h620
-rw-r--r--cpukit/libnetworking/nfs/nfsproto.h424
-rw-r--r--cpukit/libnetworking/nfs/rpcv2.h111
-rw-r--r--cpukit/libnetworking/nfs/xdr_subs.h90
-rw-r--r--cpukit/libnetworking/nfsclient/nfsargs.h95
-rw-r--r--cpukit/libnetworking/nfsclient/nfsdiskless.h100
-rw-r--r--cpukit/libnetworking/opt_atalk.h5
-rw-r--r--cpukit/libnetworking/opt_bdg.h5
-rw-r--r--cpukit/libnetworking/opt_compat.h5
-rw-r--r--cpukit/libnetworking/opt_inet.h5
-rw-r--r--cpukit/libnetworking/opt_inet6.h5
-rw-r--r--cpukit/libnetworking/opt_ipfw.h5
-rw-r--r--cpukit/libnetworking/opt_ipsec.h5
-rw-r--r--cpukit/libnetworking/opt_ipx.h5
-rw-r--r--cpukit/libnetworking/opt_mac.h5
-rw-r--r--cpukit/libnetworking/opt_mrouting.h5
-rw-r--r--cpukit/libnetworking/opt_netgraph.h5
-rw-r--r--cpukit/libnetworking/opt_ppp.h11
-rw-r--r--cpukit/libnetworking/opt_tcpdebug.h16
-rw-r--r--cpukit/libnetworking/poll.h6
-rw-r--r--cpukit/libnetworking/preinstall.am471
-rw-r--r--cpukit/libnetworking/resolv.h306
-rw-r--r--cpukit/libnetworking/rtems/bsdnet/_types.h44
-rw-r--r--cpukit/libnetworking/rtems/bsdnet/servers.h21
-rw-r--r--cpukit/libnetworking/rtems/dhcp.h47
-rw-r--r--cpukit/libnetworking/rtems/ftpfs.h37
-rw-r--r--cpukit/libnetworking/rtems/issetugid.c15
-rw-r--r--cpukit/libnetworking/rtems/mkrootfs.c335
-rw-r--r--cpukit/libnetworking/rtems/mkrootfs.h65
-rw-r--r--cpukit/libnetworking/rtems/rtems_bootp.c36
-rw-r--r--cpukit/libnetworking/rtems/rtems_bsdnet.h279
-rw-r--r--cpukit/libnetworking/rtems/rtems_bsdnet_internal.h193
-rw-r--r--cpukit/libnetworking/rtems/rtems_bsdnet_malloc_starvation.c19
-rw-r--r--cpukit/libnetworking/rtems/rtems_dhcp.c1133
-rw-r--r--cpukit/libnetworking/rtems/rtems_glue.c1233
-rw-r--r--cpukit/libnetworking/rtems/rtems_malloc_mbuf.c33
-rw-r--r--cpukit/libnetworking/rtems/rtems_mii_ioctl.c129
-rw-r--r--cpukit/libnetworking/rtems/rtems_mii_ioctl.h99
-rw-r--r--cpukit/libnetworking/rtems/rtems_mii_ioctl_kern.c204
-rw-r--r--cpukit/libnetworking/rtems/rtems_select.c178
-rw-r--r--cpukit/libnetworking/rtems/rtems_showicmpstat.c66
-rw-r--r--cpukit/libnetworking/rtems/rtems_showifstat.c157
-rw-r--r--cpukit/libnetworking/rtems/rtems_showipstat.c63
-rw-r--r--cpukit/libnetworking/rtems/rtems_showmbuf.c69
-rw-r--r--cpukit/libnetworking/rtems/rtems_showroute.c240
-rw-r--r--cpukit/libnetworking/rtems/rtems_showtcpstat.c106
-rw-r--r--cpukit/libnetworking/rtems/rtems_showudpstat.c52
-rw-r--r--cpukit/libnetworking/rtems/rtems_syscall.c792
-rw-r--r--cpukit/libnetworking/rtems/sghostname.c53
-rw-r--r--cpukit/libnetworking/rtems/tftp.h43
-rw-r--r--cpukit/libnetworking/sys/buf.h248
-rw-r--r--cpukit/libnetworking/sys/callout.h53
-rw-r--r--cpukit/libnetworking/sys/conf.h228
-rw-r--r--cpukit/libnetworking/sys/domain.h75
-rw-r--r--cpukit/libnetworking/sys/kernel.h264
-rw-r--r--cpukit/libnetworking/sys/libkern.h94
-rw-r--r--cpukit/libnetworking/sys/linker_set.h93
-rw-r--r--cpukit/libnetworking/sys/malloc.h355
-rw-r--r--cpukit/libnetworking/sys/mbuf.h440
-rw-r--r--cpukit/libnetworking/sys/mount.h123
-rw-r--r--cpukit/libnetworking/sys/poll.h104
-rw-r--r--cpukit/libnetworking/sys/proc.h8
-rw-r--r--cpukit/libnetworking/sys/protosw.h300
-rw-r--r--cpukit/libnetworking/sys/queue.h602
-rw-r--r--cpukit/libnetworking/sys/reboot.h106
-rw-r--r--cpukit/libnetworking/sys/resourcevar.h5
-rw-r--r--cpukit/libnetworking/sys/rtprio.h70
-rw-r--r--cpukit/libnetworking/sys/select.h75
-rw-r--r--cpukit/libnetworking/sys/signalvar.h171
-rw-r--r--cpukit/libnetworking/sys/socket.h407
-rw-r--r--cpukit/libnetworking/sys/socketvar.h280
-rw-r--r--cpukit/libnetworking/sys/sysctl.h642
-rw-r--r--cpukit/libnetworking/sys/syslog.h194
-rw-r--r--cpukit/libnetworking/sys/systm.h199
-rw-r--r--cpukit/libnetworking/sys/ttydefaults.h97
-rw-r--r--cpukit/libnetworking/sys/ucred.h64
-rw-r--r--cpukit/libnetworking/sys/uio.h99
-rw-r--r--cpukit/libnetworking/sys/un.h79
-rw-r--r--cpukit/libnetworking/syslog.h5
-rw-r--r--cpukit/libnetworking/vm/vm.h73
-rw-r--r--cpukit/libnetworking/vm/vm_extern.h102
-rw-r--r--cpukit/libnetworking/vm/vm_kern.h79
-rw-r--r--cpukit/libnetworking/vm/vm_param.h133
-rw-r--r--cpukit/librpc/.cvsignore2
-rw-r--r--cpukit/librpc/Makefile.am91
-rw-r--r--cpukit/librpc/README_RTEMS64
-rw-r--r--cpukit/librpc/include/rpc/auth.h260
-rw-r--r--cpukit/librpc/include/rpc/auth_unix.h84
-rw-r--r--cpukit/librpc/include/rpc/clnt.h317
-rw-r--r--cpukit/librpc/include/rpc/clnt_soc.h106
-rw-r--r--cpukit/librpc/include/rpc/clnt_stat.h83
-rw-r--r--cpukit/librpc/include/rpc/pmap_clnt.h85
-rw-r--r--cpukit/librpc/include/rpc/pmap_prot.h104
-rw-r--r--cpukit/librpc/include/rpc/pmap_rmt.h63
-rw-r--r--cpukit/librpc/include/rpc/rpc.h116
-rw-r--r--cpukit/librpc/include/rpc/rpc_com.h68
-rw-r--r--cpukit/librpc/include/rpc/rpc_msg.h199
-rw-r--r--cpukit/librpc/include/rpc/rpcent.h69
-rw-r--r--cpukit/librpc/include/rpc/svc.h289
-rw-r--r--cpukit/librpc/include/rpc/svc_auth.h56
-rw-r--r--cpukit/librpc/include/rpc/svc_soc.h123
-rw-r--r--cpukit/librpc/include/rpc/types.h68
-rw-r--r--cpukit/librpc/include/rpc/xdr.h309
-rw-r--r--cpukit/librpc/include/rpcsvc/bootparam_prot.x103
-rw-r--r--cpukit/librpc/include/rpcsvc/crypt.x91
-rw-r--r--cpukit/librpc/include/rpcsvc/key_prot.x282
-rw-r--r--cpukit/librpc/include/rpcsvc/klm_prot.x139
-rw-r--r--cpukit/librpc/include/rpcsvc/mount.x257
-rw-r--r--cpukit/librpc/include/rpcsvc/nfs_prot.x1265
-rw-r--r--cpukit/librpc/include/rpcsvc/nis.x466
-rw-r--r--cpukit/librpc/include/rpcsvc/nis_cache.x87
-rw-r--r--cpukit/librpc/include/rpcsvc/nis_callback.x76
-rw-r--r--cpukit/librpc/include/rpcsvc/nis_db.h162
-rw-r--r--cpukit/librpc/include/rpcsvc/nis_object.x317
-rw-r--r--cpukit/librpc/include/rpcsvc/nis_tags.h137
-rw-r--r--cpukit/librpc/include/rpcsvc/nislib.h317
-rw-r--r--cpukit/librpc/include/rpcsvc/nlm_prot.x183
-rw-r--r--cpukit/librpc/include/rpcsvc/pmap_prot.x284
-rw-r--r--cpukit/librpc/include/rpcsvc/rex.x235
-rw-r--r--cpukit/librpc/include/rpcsvc/rnusers.x122
-rw-r--r--cpukit/librpc/include/rpcsvc/rquota.x67
-rw-r--r--cpukit/librpc/include/rpcsvc/rstat.x151
-rw-r--r--cpukit/librpc/include/rpcsvc/rwall.x57
-rw-r--r--cpukit/librpc/include/rpcsvc/sm_inter.x122
-rw-r--r--cpukit/librpc/include/rpcsvc/spray.x90
-rw-r--r--cpukit/librpc/include/rpcsvc/yp.x379
-rw-r--r--cpukit/librpc/include/rpcsvc/yp_prot.h329
-rw-r--r--cpukit/librpc/include/rpcsvc/ypclnt.h93
-rw-r--r--cpukit/librpc/include/rpcsvc/yppasswd.x75
-rw-r--r--cpukit/librpc/include/rpcsvc/ypupdate_prot.x88
-rw-r--r--cpukit/librpc/include/rpcsvc/ypxfrd.x173
-rw-r--r--cpukit/librpc/preinstall.am89
-rw-r--r--cpukit/librpc/src/rpc/DISCLAIMER28
-rw-r--r--cpukit/librpc/src/rpc/README233
-rw-r--r--cpukit/librpc/src/rpc/auth_none.c134
-rw-r--r--cpukit/librpc/src/rpc/auth_unix.c341
-rw-r--r--cpukit/librpc/src/rpc/authunix_prot.c67
-rw-r--r--cpukit/librpc/src/rpc/bindresvport.3106
-rw-r--r--cpukit/librpc/src/rpc/bindresvport.c156
-rw-r--r--cpukit/librpc/src/rpc/clnt_generic.c141
-rw-r--r--cpukit/librpc/src/rpc/clnt_perror.c254
-rw-r--r--cpukit/librpc/src/rpc/clnt_raw.c243
-rw-r--r--cpukit/librpc/src/rpc/clnt_simple.c123
-rw-r--r--cpukit/librpc/src/rpc/clnt_tcp.c581
-rw-r--r--cpukit/librpc/src/rpc/clnt_udp.c568
-rw-r--r--cpukit/librpc/src/rpc/des_crypt.3130
-rw-r--r--cpukit/librpc/src/rpc/get_myaddress.c113
-rw-r--r--cpukit/librpc/src/rpc/getrpcent.398
-rw-r--r--cpukit/librpc/src/rpc/getrpcent.c302
-rw-r--r--cpukit/librpc/src/rpc/getrpcport.331
-rw-r--r--cpukit/librpc/src/rpc/getrpcport.c63
-rw-r--r--cpukit/librpc/src/rpc/netname.c136
-rw-r--r--cpukit/librpc/src/rpc/netnamer.c326
-rw-r--r--cpukit/librpc/src/rpc/pmap_clnt.c149
-rw-r--r--cpukit/librpc/src/rpc/pmap_getmaps.c87
-rw-r--r--cpukit/librpc/src/rpc/pmap_getport.c92
-rw-r--r--cpukit/librpc/src/rpc/pmap_prot.c59
-rw-r--r--cpukit/librpc/src/rpc/pmap_prot2.c118
-rw-r--r--cpukit/librpc/src/rpc/pmap_rmt.c434
-rw-r--r--cpukit/librpc/src/rpc/publickey.347
-rw-r--r--cpukit/librpc/src/rpc/publickey.538
-rw-r--r--cpukit/librpc/src/rpc/rpc.31767
-rw-r--r--cpukit/librpc/src/rpc/rpc.535
-rw-r--r--cpukit/librpc/src/rpc/rpc_callmsg.c192
-rw-r--r--cpukit/librpc/src/rpc/rpc_commondata.c41
-rw-r--r--cpukit/librpc/src/rpc/rpc_dtablesize.c61
-rw-r--r--cpukit/librpc/src/rpc/rpc_prot.c321
-rw-r--r--cpukit/librpc/src/rpc/rpc_secure.3254
-rw-r--r--cpukit/librpc/src/rpc/rpcdname.c80
-rw-r--r--cpukit/librpc/src/rpc/rstat.158
-rw-r--r--cpukit/librpc/src/rpc/rstat_svc.822
-rw-r--r--cpukit/librpc/src/rpc/rtems_portmapper.c491
-rw-r--r--cpukit/librpc/src/rpc/rtems_rpc.c59
-rw-r--r--cpukit/librpc/src/rpc/rtime.347
-rw-r--r--cpukit/librpc/src/rpc/rtime.c158
-rw-r--r--cpukit/librpc/src/rpc/svc.c491
-rw-r--r--cpukit/librpc/src/rpc/svc_auth.c216
-rw-r--r--cpukit/librpc/src/rpc/svc_auth_unix.c148
-rw-r--r--cpukit/librpc/src/rpc/svc_raw.c169
-rw-r--r--cpukit/librpc/src/rpc/svc_run.c84
-rw-r--r--cpukit/librpc/src/rpc/svc_simple.c155
-rw-r--r--cpukit/librpc/src/rpc/svc_tcp.c482
-rw-r--r--cpukit/librpc/src/rpc/svc_udp.c479
-rw-r--r--cpukit/librpc/src/xdr/xdr.3837
-rw-r--r--cpukit/librpc/src/xdr/xdr.c858
-rw-r--r--cpukit/librpc/src/xdr/xdr_array.c156
-rw-r--r--cpukit/librpc/src/xdr/xdr_float.c334
-rw-r--r--cpukit/librpc/src/xdr/xdr_mem.c242
-rw-r--r--cpukit/librpc/src/xdr/xdr_rec.c601
-rw-r--r--cpukit/librpc/src/xdr/xdr_reference.c138
-rw-r--r--cpukit/librpc/src/xdr/xdr_sizeof.c163
-rw-r--r--cpukit/librpc/src/xdr/xdr_stdio.c190
-rw-r--r--cpukit/posix/.cvsignore2
-rw-r--r--cpukit/posix/Makefile.am157
-rw-r--r--cpukit/posix/include/aio.h148
-rw-r--r--cpukit/posix/include/devctl.h41
-rw-r--r--cpukit/posix/include/mqueue.h156
-rw-r--r--cpukit/posix/include/rtems/posix/cancel.h33
-rw-r--r--cpukit/posix/include/rtems/posix/cond.h171
-rw-r--r--cpukit/posix/include/rtems/posix/condmp.h165
-rw-r--r--cpukit/posix/include/rtems/posix/config.h66
-rw-r--r--cpukit/posix/include/rtems/posix/key.h138
-rw-r--r--cpukit/posix/include/rtems/posix/mqueue.h251
-rw-r--r--cpukit/posix/include/rtems/posix/mqueuemp.h164
-rw-r--r--cpukit/posix/include/rtems/posix/mutex.h160
-rw-r--r--cpukit/posix/include/rtems/posix/mutexmp.h177
-rw-r--r--cpukit/posix/include/rtems/posix/posixapi.h37
-rw-r--r--cpukit/posix/include/rtems/posix/priority.h48
-rw-r--r--cpukit/posix/include/rtems/posix/psignal.h125
-rw-r--r--cpukit/posix/include/rtems/posix/pthread.h153
-rw-r--r--cpukit/posix/include/rtems/posix/pthreadmp.h164
-rw-r--r--cpukit/posix/include/rtems/posix/ptimer.h94
-rw-r--r--cpukit/posix/include/rtems/posix/semaphore.h184
-rw-r--r--cpukit/posix/include/rtems/posix/semaphoremp.h164
-rw-r--r--cpukit/posix/include/rtems/posix/threadsup.h40
-rw-r--r--cpukit/posix/include/rtems/posix/time.h54
-rw-r--r--cpukit/posix/include/rtems/posix/timer.h75
-rw-r--r--cpukit/posix/include/sched.h98
-rw-r--r--cpukit/posix/include/semaphore.h119
-rw-r--r--cpukit/posix/inline/rtems/posix/cond.inl105
-rw-r--r--cpukit/posix/inline/rtems/posix/key.inl73
-rw-r--r--cpukit/posix/inline/rtems/posix/mqueue.inl154
-rw-r--r--cpukit/posix/inline/rtems/posix/mutex.inl118
-rw-r--r--cpukit/posix/inline/rtems/posix/priority.inl41
-rw-r--r--cpukit/posix/inline/rtems/posix/pthread.inl73
-rw-r--r--cpukit/posix/inline/rtems/posix/semaphore.inl89
-rw-r--r--cpukit/posix/inline/rtems/posix/timer.inl94
-rw-r--r--cpukit/posix/macros/rtems/posix/cond.inl104
-rw-r--r--cpukit/posix/macros/rtems/posix/key.inl58
-rw-r--r--cpukit/posix/macros/rtems/posix/mqueue.inl105
-rw-r--r--cpukit/posix/macros/rtems/posix/mutex.inl111
-rw-r--r--cpukit/posix/macros/rtems/posix/priority.inl29
-rw-r--r--cpukit/posix/macros/rtems/posix/pthread.inl58
-rw-r--r--cpukit/posix/macros/rtems/posix/semaphore.inl68
-rw-r--r--cpukit/posix/macros/rtems/posix/timer.inl57
-rw-r--r--cpukit/posix/preinstall.am190
-rw-r--r--cpukit/posix/src/.cvsignore4
-rw-r--r--cpukit/posix/src/README.mqueue38
-rw-r--r--cpukit/posix/src/adasupp.c32
-rw-r--r--cpukit/posix/src/adjtime.c60
-rw-r--r--cpukit/posix/src/aio.c118
-rw-r--r--cpukit/posix/src/alarm.c82
-rw-r--r--cpukit/posix/src/cancel.c62
-rw-r--r--cpukit/posix/src/cancelrun.c63
-rw-r--r--cpukit/posix/src/cleanuppop.c60
-rw-r--r--cpukit/posix/src/cleanuppush.c56
-rw-r--r--cpukit/posix/src/clockgetcpuclockid.c32
-rw-r--r--cpukit/posix/src/clockgetenableattr.c32
-rw-r--r--cpukit/posix/src/clockgetres.c55
-rw-r--r--cpukit/posix/src/clockgettime.c69
-rw-r--r--cpukit/posix/src/clocksetenableattr.c32
-rw-r--r--cpukit/posix/src/clocksettime.c88
-rw-r--r--cpukit/posix/src/cond.c52
-rw-r--r--cpukit/posix/src/condattrdestroy.c35
-rw-r--r--cpukit/posix/src/condattrgetpshared.c36
-rw-r--r--cpukit/posix/src/condattrinit.c35
-rw-r--r--cpukit/posix/src/condattrsetpshared.c43
-rw-r--r--cpukit/posix/src/condbroadcast.c30
-rw-r--r--cpukit/posix/src/conddefaultattributes.c28
-rw-r--r--cpukit/posix/src/conddestroy.c80
-rw-r--r--cpukit/posix/src/condinit.c99
-rw-r--r--cpukit/posix/src/condmp.c45
-rw-r--r--cpukit/posix/src/condsignal.c30
-rw-r--r--cpukit/posix/src/condsignalsupp.c61
-rw-r--r--cpukit/posix/src/condtimedwait.c61
-rw-r--r--cpukit/posix/src/condwait.c36
-rw-r--r--cpukit/posix/src/condwaitsupp.c108
-rw-r--r--cpukit/posix/src/devctl.c26
-rw-r--r--cpukit/posix/src/execl.c21
-rw-r--r--cpukit/posix/src/execle.c21
-rw-r--r--cpukit/posix/src/execlp.c21
-rw-r--r--cpukit/posix/src/execv.c20
-rw-r--r--cpukit/posix/src/execve.c21
-rw-r--r--cpukit/posix/src/execvp.c20
-rw-r--r--cpukit/posix/src/fork.c18
-rw-r--r--cpukit/posix/src/getpagesize.c23
-rw-r--r--cpukit/posix/src/key.c46
-rw-r--r--cpukit/posix/src/keycreate.c90
-rw-r--r--cpukit/posix/src/keydelete.c58
-rw-r--r--cpukit/posix/src/keygetspecific.c48
-rw-r--r--cpukit/posix/src/keyrundestructors.c80
-rw-r--r--cpukit/posix/src/keysetspecific.c47
-rw-r--r--cpukit/posix/src/kill.c51
-rw-r--r--cpukit/posix/src/killinfo.c338
-rw-r--r--cpukit/posix/src/mprotect.c23
-rw-r--r--cpukit/posix/src/mqueue.c81
-rw-r--r--cpukit/posix/src/mqueueclose.c79
-rw-r--r--cpukit/posix/src/mqueuecreatesupp.c173
-rw-r--r--cpukit/posix/src/mqueuedeletesupp.c78
-rw-r--r--cpukit/posix/src/mqueuegetattr.c79
-rw-r--r--cpukit/posix/src/mqueuenametoid.c66
-rw-r--r--cpukit/posix/src/mqueuenotify.c107
-rw-r--r--cpukit/posix/src/mqueueopen.c158
-rw-r--r--cpukit/posix/src/mqueuereceive.c56
-rw-r--r--cpukit/posix/src/mqueuerecvsupp.c107
-rw-r--r--cpukit/posix/src/mqueuesend.c56
-rw-r--r--cpukit/posix/src/mqueuesendsupp.c117
-rw-r--r--cpukit/posix/src/mqueuesetattr.c81
-rw-r--r--cpukit/posix/src/mqueuetimedreceive.c57
-rw-r--r--cpukit/posix/src/mqueuetimedsend.c57
-rw-r--r--cpukit/posix/src/mqueuetranslatereturncode.c101
-rw-r--r--cpukit/posix/src/mqueueunlink.c87
-rw-r--r--cpukit/posix/src/mutex.c54
-rw-r--r--cpukit/posix/src/mutexattrdestroy.c37
-rw-r--r--cpukit/posix/src/mutexattrgetprioceiling.c38
-rw-r--r--cpukit/posix/src/mutexattrgetprotocol.c38
-rw-r--r--cpukit/posix/src/mutexattrgetpshared.c38
-rw-r--r--cpukit/posix/src/mutexattrinit.c37
-rw-r--r--cpukit/posix/src/mutexattrsetprioceiling.c41
-rw-r--r--cpukit/posix/src/mutexattrsetprotocol.c46
-rw-r--r--cpukit/posix/src/mutexattrsetpshared.c45
-rw-r--r--cpukit/posix/src/mutexdefaultattributes.c34
-rw-r--r--cpukit/posix/src/mutexdestroy.c87
-rw-r--r--cpukit/posix/src/mutexfromcorestatus.c52
-rw-r--r--cpukit/posix/src/mutexgetprioceiling.c55
-rw-r--r--cpukit/posix/src/mutexinit.c186
-rw-r--r--cpukit/posix/src/mutexlock.c35
-rw-r--r--cpukit/posix/src/mutexlocksupp.c67
-rw-r--r--cpukit/posix/src/mutexmp.c66
-rw-r--r--cpukit/posix/src/mutexsetprioceiling.c82
-rw-r--r--cpukit/posix/src/mutextimedlock.c40
-rw-r--r--cpukit/posix/src/mutextrylock.c35
-rw-r--r--cpukit/posix/src/mutexunlock.c66
-rw-r--r--cpukit/posix/src/nanosleep.c104
-rw-r--r--cpukit/posix/src/pause.c40
-rw-r--r--cpukit/posix/src/posixintervaltotimespec.c38
-rw-r--r--cpukit/posix/src/posixtimespecsubtract.c50
-rw-r--r--cpukit/posix/src/posixtimespectointerval.c42
-rw-r--r--cpukit/posix/src/psignal.c206
-rw-r--r--cpukit/posix/src/psignalchecksignal.c93
-rw-r--r--cpukit/posix/src/psignalclearprocesssignals.c42
-rw-r--r--cpukit/posix/src/psignalclearsignals.c89
-rw-r--r--cpukit/posix/src/psignalsetprocesssignals.c42
-rw-r--r--cpukit/posix/src/psignalunblockthread.c93
-rw-r--r--cpukit/posix/src/pthread.c392
-rw-r--r--cpukit/posix/src/pthreadatfork.c31
-rw-r--r--cpukit/posix/src/pthreadattrdestroy.c32
-rw-r--r--cpukit/posix/src/pthreadattrgetdetachstate.c31
-rw-r--r--cpukit/posix/src/pthreadattrgetinheritsched.c31
-rw-r--r--cpukit/posix/src/pthreadattrgetschedparam.c31
-rw-r--r--cpukit/posix/src/pthreadattrgetschedpolicy.c31
-rw-r--r--cpukit/posix/src/pthreadattrgetscope.c31
-rw-r--r--cpukit/posix/src/pthreadattrgetstackaddr.c31
-rw-r--r--cpukit/posix/src/pthreadattrgetstacksize.c31
-rw-r--r--cpukit/posix/src/pthreadattrinit.c33
-rw-r--r--cpukit/posix/src/pthreadattrsetdetachstate.c38
-rw-r--r--cpukit/posix/src/pthreadattrsetinheritsched.c41
-rw-r--r--cpukit/posix/src/pthreadattrsetschedparam.c31
-rw-r--r--cpukit/posix/src/pthreadattrsetschedpolicy.c43
-rw-r--r--cpukit/posix/src/pthreadattrsetscope.c43
-rw-r--r--cpukit/posix/src/pthreadattrsetstackaddr.c31
-rw-r--r--cpukit/posix/src/pthreadattrsetstacksize.c37
-rw-r--r--cpukit/posix/src/pthreadcreate.c256
-rw-r--r--cpukit/posix/src/pthreaddetach.c47
-rw-r--r--cpukit/posix/src/pthreadequal.c82
-rw-r--r--cpukit/posix/src/pthreadexit.c48
-rw-r--r--cpukit/posix/src/pthreadgetcpuclockid.c29
-rw-r--r--cpukit/posix/src/pthreadgetcputime.c31
-rw-r--r--cpukit/posix/src/pthreadgetschedparam.c59
-rw-r--r--cpukit/posix/src/pthreadjoin.c71
-rw-r--r--cpukit/posix/src/pthreadkill.c83
-rw-r--r--cpukit/posix/src/pthreadonce.c44
-rw-r--r--cpukit/posix/src/pthreadself.c27
-rw-r--r--cpukit/posix/src/pthreadsetcputime.c38
-rw-r--r--cpukit/posix/src/pthreadsetschedparam.c129
-rw-r--r--cpukit/posix/src/pthreadsigmask.c73
-rw-r--r--cpukit/posix/src/ptimer.c62
-rw-r--r--cpukit/posix/src/ptimer1.c568
-rw-r--r--cpukit/posix/src/sched.c157
-rw-r--r--cpukit/posix/src/semaphore.c54
-rw-r--r--cpukit/posix/src/semaphorecreatesupp.c129
-rw-r--r--cpukit/posix/src/semaphoredeletesupp.c65
-rw-r--r--cpukit/posix/src/semaphoremp.c146
-rw-r--r--cpukit/posix/src/semaphorenametoid.c51
-rw-r--r--cpukit/posix/src/semaphorewaitsupp.c71
-rw-r--r--cpukit/posix/src/semclose.c55
-rw-r--r--cpukit/posix/src/semdestroy.c58
-rw-r--r--cpukit/posix/src/semgetvalue.c50
-rw-r--r--cpukit/posix/src/seminit.c51
-rw-r--r--cpukit/posix/src/semopen.c125
-rw-r--r--cpukit/posix/src/sempost.c57
-rw-r--r--cpukit/posix/src/semtimedwait.c68
-rw-r--r--cpukit/posix/src/semtrywait.c35
-rw-r--r--cpukit/posix/src/semunlink.c77
-rw-r--r--cpukit/posix/src/semwait.c35
-rw-r--r--cpukit/posix/src/setcancelstate.c61
-rw-r--r--cpukit/posix/src/setcanceltype.c61
-rw-r--r--cpukit/posix/src/sigaction.c93
-rw-r--r--cpukit/posix/src/sigaddset.c42
-rw-r--r--cpukit/posix/src/sigdelset.c46
-rw-r--r--cpukit/posix/src/sigemptyset.c35
-rw-r--r--cpukit/posix/src/sigfillset.c35
-rw-r--r--cpukit/posix/src/sigismember.c44
-rw-r--r--cpukit/posix/src/signal_2.c52
-rw-r--r--cpukit/posix/src/sigpending.c40
-rw-r--r--cpukit/posix/src/sigprocmask.c39
-rw-r--r--cpukit/posix/src/sigqueue.c32
-rw-r--r--cpukit/posix/src/sigsuspend.c53
-rw-r--r--cpukit/posix/src/sigtimedwait.c140
-rw-r--r--cpukit/posix/src/sigwait.c44
-rw-r--r--cpukit/posix/src/sigwaitinfo.c33
-rw-r--r--cpukit/posix/src/sleep.c31
-rw-r--r--cpukit/posix/src/sysconf.c49
-rw-r--r--cpukit/posix/src/testcancel.c46
-rw-r--r--cpukit/posix/src/time.c52
-rw-r--r--cpukit/posix/src/types.c46
-rw-r--r--cpukit/posix/src/ualarm.c94
-rw-r--r--cpukit/posix/src/usleep.c34
-rw-r--r--cpukit/posix/src/wait.c21
-rw-r--r--cpukit/posix/src/waitpid.c23
-rw-r--r--cpukit/pppd/.cvsignore2
-rw-r--r--cpukit/pppd/Makefile.am21
-rw-r--r--cpukit/pppd/README29
-rw-r--r--cpukit/pppd/STATUS27
-rw-r--r--cpukit/pppd/auth.c1121
-rw-r--r--cpukit/pppd/cbcp.c456
-rw-r--r--cpukit/pppd/cbcp.h26
-rw-r--r--cpukit/pppd/ccp.c1226
-rw-r--r--cpukit/pppd/ccp.h48
-rw-r--r--cpukit/pppd/chap.c858
-rw-r--r--cpukit/pppd/chap.h124
-rw-r--r--cpukit/pppd/chap_ms.c338
-rw-r--r--cpukit/pppd/chap_ms.h33
-rw-r--r--cpukit/pppd/chat.c857
-rw-r--r--cpukit/pppd/demand.c347
-rw-r--r--cpukit/pppd/example/Makefile-user45
-rw-r--r--cpukit/pppd/example/README15
-rw-r--r--cpukit/pppd/example/init.c24
-rw-r--r--cpukit/pppd/example/netconfig.h36
-rw-r--r--cpukit/pppd/example/ppp.conf27
-rw-r--r--cpukit/pppd/example/pppd.options9
-rw-r--r--cpukit/pppd/example/pppdapp.c146
-rw-r--r--cpukit/pppd/example/system.h42
-rw-r--r--cpukit/pppd/fsm.c764
-rw-r--r--cpukit/pppd/fsm.h144
-rw-r--r--cpukit/pppd/ipcp.c1768
-rw-r--r--cpukit/pppd/ipcp.h73
-rw-r--r--cpukit/pppd/lcp.c1953
-rw-r--r--cpukit/pppd/lcp.h88
-rw-r--r--cpukit/pppd/magic.c58
-rw-r--r--cpukit/pppd/magic.h23
-rw-r--r--cpukit/pppd/md4.c298
-rw-r--r--cpukit/pppd/md4.h64
-rw-r--r--cpukit/pppd/md5.c308
-rw-r--r--cpukit/pppd/md5.h60
-rw-r--r--cpukit/pppd/options.c1525
-rw-r--r--cpukit/pppd/patchlevel.h6
-rw-r--r--cpukit/pppd/pathnames.h43
-rw-r--r--cpukit/pppd/pppd.81480
-rw-r--r--cpukit/pppd/pppd.h663
-rw-r--r--cpukit/pppd/preinstall.am43
-rw-r--r--cpukit/pppd/rtemsdialer.h24
-rw-r--r--cpukit/pppd/rtemsmain.c896
-rw-r--r--cpukit/pppd/rtemspppd.c228
-rw-r--r--cpukit/pppd/rtemspppd.h40
-rw-r--r--cpukit/pppd/sys-rtems.c1338
-rw-r--r--cpukit/pppd/upap.c638
-rw-r--r--cpukit/pppd/upap.h87
-rw-r--r--cpukit/pppd/utils.c833
-rw-r--r--cpukit/preinstall.am345
-rw-r--r--cpukit/rtems/.cvsignore2
-rw-r--r--cpukit/rtems/Makefile.am136
-rw-r--r--cpukit/rtems/include/rtems.h146
-rw-r--r--cpukit/rtems/include/rtems/rtems/asr.h114
-rw-r--r--cpukit/rtems/include/rtems/rtems/attr.h92
-rw-r--r--cpukit/rtems/include/rtems/rtems/cache.h140
-rw-r--r--cpukit/rtems/include/rtems/rtems/clock.h105
-rw-r--r--cpukit/rtems/include/rtems/rtems/config.h56
-rw-r--r--cpukit/rtems/include/rtems/rtems/dpmem.h159
-rw-r--r--cpukit/rtems/include/rtems/rtems/event.h178
-rw-r--r--cpukit/rtems/include/rtems/rtems/eventmp.h149
-rw-r--r--cpukit/rtems/include/rtems/rtems/eventset.h91
-rw-r--r--cpukit/rtems/include/rtems/rtems/intr.h162
-rw-r--r--cpukit/rtems/include/rtems/rtems/message.h330
-rw-r--r--cpukit/rtems/include/rtems/rtems/modes.h91
-rw-r--r--cpukit/rtems/include/rtems/rtems/mp.h55
-rw-r--r--cpukit/rtems/include/rtems/rtems/msgmp.h179
-rw-r--r--cpukit/rtems/include/rtems/rtems/options.h55
-rw-r--r--cpukit/rtems/include/rtems/rtems/part.h172
-rw-r--r--cpukit/rtems/include/rtems/rtems/partmp.h163
-rw-r--r--cpukit/rtems/include/rtems/rtems/ratemon.h216
-rw-r--r--cpukit/rtems/include/rtems/rtems/region.h301
-rw-r--r--cpukit/rtems/include/rtems/rtems/regionmp.h168
-rw-r--r--cpukit/rtems/include/rtems/rtems/rtemsapi.h37
-rw-r--r--cpukit/rtems/include/rtems/rtems/sem.h278
-rw-r--r--cpukit/rtems/include/rtems/rtems/semmp.h165
-rw-r--r--cpukit/rtems/include/rtems/rtems/signal.h87
-rw-r--r--cpukit/rtems/include/rtems/rtems/signalmp.h149
-rw-r--r--cpukit/rtems/include/rtems/rtems/status.h88
-rw-r--r--cpukit/rtems/include/rtems/rtems/support.h101
-rw-r--r--cpukit/rtems/include/rtems/rtems/taskmp.h169
-rw-r--r--cpukit/rtems/include/rtems/rtems/tasks.h470
-rw-r--r--cpukit/rtems/include/rtems/rtems/timer.h369
-rw-r--r--cpukit/rtems/include/rtems/rtems/types.h114
-rw-r--r--cpukit/rtems/inline/rtems/rtems/asr.inl130
-rw-r--r--cpukit/rtems/inline/rtems/rtems/attr.inl215
-rw-r--r--cpukit/rtems/inline/rtems/rtems/dpmem.inl97
-rw-r--r--cpukit/rtems/inline/rtems/rtems/event.inl23
-rw-r--r--cpukit/rtems/inline/rtems/rtems/eventset.inl97
-rw-r--r--cpukit/rtems/inline/rtems/rtems/message.inl85
-rw-r--r--cpukit/rtems/inline/rtems/rtems/modes.inl154
-rw-r--r--cpukit/rtems/inline/rtems/rtems/options.inl57
-rw-r--r--cpukit/rtems/inline/rtems/rtems/part.inl201
-rw-r--r--cpukit/rtems/inline/rtems/rtems/ratemon.inl145
-rw-r--r--cpukit/rtems/inline/rtems/rtems/region.inl129
-rw-r--r--cpukit/rtems/inline/rtems/rtems/sem.inl105
-rw-r--r--cpukit/rtems/inline/rtems/rtems/status.inl58
-rw-r--r--cpukit/rtems/inline/rtems/rtems/support.inl63
-rw-r--r--cpukit/rtems/inline/rtems/rtems/tasks.inl92
-rw-r--r--cpukit/rtems/inline/rtems/rtems/timer.inl144
-rw-r--r--cpukit/rtems/macros/rtems/rtems/asr.inl92
-rw-r--r--cpukit/rtems/macros/rtems/rtems/attr.inl122
-rw-r--r--cpukit/rtems/macros/rtems/rtems/dpmem.inl61
-rw-r--r--cpukit/rtems/macros/rtems/rtems/event.inl23
-rw-r--r--cpukit/rtems/macros/rtems/rtems/eventset.inl61
-rw-r--r--cpukit/rtems/macros/rtems/rtems/message.inl51
-rw-r--r--cpukit/rtems/macros/rtems/rtems/modes.inl94
-rw-r--r--cpukit/rtems/macros/rtems/rtems/options.inl41
-rw-r--r--cpukit/rtems/macros/rtems/rtems/part.inl119
-rw-r--r--cpukit/rtems/macros/rtems/rtems/ratemon.inl87
-rw-r--r--cpukit/rtems/macros/rtems/rtems/region.inl77
-rw-r--r--cpukit/rtems/macros/rtems/rtems/sem.inl65
-rw-r--r--cpukit/rtems/macros/rtems/rtems/status.inl41
-rw-r--r--cpukit/rtems/macros/rtems/rtems/support.inl46
-rw-r--r--cpukit/rtems/macros/rtems/rtems/tasks.inl60
-rw-r--r--cpukit/rtems/macros/rtems/rtems/timer.inl88
-rw-r--r--cpukit/rtems/preinstall.am284
-rw-r--r--cpukit/rtems/src/attr.c32
-rw-r--r--cpukit/rtems/src/clockget.c96
-rw-r--r--cpukit/rtems/src/clockset.c57
-rw-r--r--cpukit/rtems/src/clocktick.c55
-rw-r--r--cpukit/rtems/src/clocktodtoseconds.c67
-rw-r--r--cpukit/rtems/src/clocktodvalidate.c67
-rw-r--r--cpukit/rtems/src/dpmem.c59
-rw-r--r--cpukit/rtems/src/dpmemcreate.c88
-rw-r--r--cpukit/rtems/src/dpmemdelete.c65
-rw-r--r--cpukit/rtems/src/dpmemexternal2internal.c79
-rw-r--r--cpukit/rtems/src/dpmemident.c59
-rw-r--r--cpukit/rtems/src/dpmeminternal2external.c79
-rw-r--r--cpukit/rtems/src/event.c48
-rw-r--r--cpukit/rtems/src/eventmp.c193
-rw-r--r--cpukit/rtems/src/eventreceive.c69
-rw-r--r--cpukit/rtems/src/eventseize.c142
-rw-r--r--cpukit/rtems/src/eventsend.c75
-rw-r--r--cpukit/rtems/src/eventsurrender.c111
-rw-r--r--cpukit/rtems/src/eventtimeout.c91
-rw-r--r--cpukit/rtems/src/intr.c35
-rw-r--r--cpukit/rtems/src/intrbody.c74
-rw-r--r--cpukit/rtems/src/intrcatch.c58
-rw-r--r--cpukit/rtems/src/mp.c45
-rw-r--r--cpukit/rtems/src/msg.c81
-rw-r--r--cpukit/rtems/src/msgmp.c510
-rw-r--r--cpukit/rtems/src/msgqallocate.c60
-rw-r--r--cpukit/rtems/src/msgqbroadcast.c113
-rw-r--r--cpukit/rtems/src/msgqcreate.c165
-rw-r--r--cpukit/rtems/src/msgqdelete.c108
-rw-r--r--cpukit/rtems/src/msgqflush.c93
-rw-r--r--cpukit/rtems/src/msgqgetnumberpending.c90
-rw-r--r--cpukit/rtems/src/msgqident.c71
-rw-r--r--cpukit/rtems/src/msgqreceive.c114
-rw-r--r--cpukit/rtems/src/msgqsend.c61
-rw-r--r--cpukit/rtems/src/msgqsubmit.c151
-rw-r--r--cpukit/rtems/src/msgqtranslatereturncode.c72
-rw-r--r--cpukit/rtems/src/msgqurgent.c61
-rw-r--r--cpukit/rtems/src/part.c71
-rw-r--r--cpukit/rtems/src/partcreate.c129
-rw-r--r--cpukit/rtems/src/partdelete.c91
-rw-r--r--cpukit/rtems/src/partgetbuffer.c86
-rw-r--r--cpukit/rtems/src/partident.c62
-rw-r--r--cpukit/rtems/src/partmp.c307
-rw-r--r--cpukit/rtems/src/partreturnbuffer.c79
-rw-r--r--cpukit/rtems/src/ratemon.c61
-rw-r--r--cpukit/rtems/src/ratemoncancel.c68
-rw-r--r--cpukit/rtems/src/ratemoncreate.c80
-rw-r--r--cpukit/rtems/src/ratemondelete.c66
-rw-r--r--cpukit/rtems/src/ratemongetstatus.c83
-rw-r--r--cpukit/rtems/src/ratemonident.c59
-rw-r--r--cpukit/rtems/src/ratemonperiod.c167
-rw-r--r--cpukit/rtems/src/ratemontimeout.c85
-rw-r--r--cpukit/rtems/src/region.c75
-rw-r--r--cpukit/rtems/src/regioncreate.c114
-rw-r--r--cpukit/rtems/src/regiondelete.c76
-rw-r--r--cpukit/rtems/src/regionextend.c100
-rw-r--r--cpukit/rtems/src/regiongetfreeinfo.c82
-rw-r--r--cpukit/rtems/src/regiongetinfo.c79
-rw-r--r--cpukit/rtems/src/regiongetsegment.c128
-rw-r--r--cpukit/rtems/src/regiongetsegmentsize.c85
-rw-r--r--cpukit/rtems/src/regionident.c61
-rw-r--r--cpukit/rtems/src/regionmp.c315
-rw-r--r--cpukit/rtems/src/regionprocessqueue.c83
-rw-r--r--cpukit/rtems/src/regionresizesegment.c101
-rw-r--r--cpukit/rtems/src/regionreturnsegment.c106
-rw-r--r--cpukit/rtems/src/rtclock.c26
-rw-r--r--cpukit/rtems/src/rtemsidtoname.c50
-rw-r--r--cpukit/rtems/src/rtemstimer.c65
-rw-r--r--cpukit/rtems/src/sem.c94
-rw-r--r--cpukit/rtems/src/semcreate.c230
-rw-r--r--cpukit/rtems/src/semdelete.c136
-rw-r--r--cpukit/rtems/src/semflush.c102
-rw-r--r--cpukit/rtems/src/semident.c86
-rw-r--r--cpukit/rtems/src/semmp.c367
-rw-r--r--cpukit/rtems/src/semobtain.c125
-rw-r--r--cpukit/rtems/src/semrelease.c119
-rw-r--r--cpukit/rtems/src/semtranslatereturncode.c124
-rw-r--r--cpukit/rtems/src/signal.c51
-rw-r--r--cpukit/rtems/src/signalcatch.c69
-rw-r--r--cpukit/rtems/src/signalmp.c192
-rw-r--r--cpukit/rtems/src/signalsend.c94
-rw-r--r--cpukit/rtems/src/taskcreate.c230
-rw-r--r--cpukit/rtems/src/taskdelete.c104
-rw-r--r--cpukit/rtems/src/taskgetnote.c112
-rw-r--r--cpukit/rtems/src/taskident.c77
-rw-r--r--cpukit/rtems/src/taskinitusers.c87
-rw-r--r--cpukit/rtems/src/taskissuspended.c81
-rw-r--r--cpukit/rtems/src/taskmode.c129
-rw-r--r--cpukit/rtems/src/taskmp.c343
-rw-r--r--cpukit/rtems/src/taskrestart.c83
-rw-r--r--cpukit/rtems/src/taskresume.c85
-rw-r--r--cpukit/rtems/src/tasks.c293
-rw-r--r--cpukit/rtems/src/tasksetnote.c106
-rw-r--r--cpukit/rtems/src/tasksetpriority.c102
-rw-r--r--cpukit/rtems/src/taskstart.c88
-rw-r--r--cpukit/rtems/src/tasksuspend.c86
-rw-r--r--cpukit/rtems/src/taskvariableadd.c92
-rw-r--r--cpukit/rtems/src/taskvariabledelete.c85
-rw-r--r--cpukit/rtems/src/taskvariableget.c82
-rw-r--r--cpukit/rtems/src/taskwakeafter.c68
-rw-r--r--cpukit/rtems/src/taskwakewhen.c86
-rw-r--r--cpukit/rtems/src/timercancel.c65
-rw-r--r--cpukit/rtems/src/timercreate.c78
-rw-r--r--cpukit/rtems/src/timerdelete.c66
-rw-r--r--cpukit/rtems/src/timerfireafter.c102
-rw-r--r--cpukit/rtems/src/timerfirewhen.c90
-rw-r--r--cpukit/rtems/src/timergetinfo.c74
-rw-r--r--cpukit/rtems/src/timerident.c60
-rw-r--r--cpukit/rtems/src/timerreset.c81
-rw-r--r--cpukit/rtems/src/timerserver.c321
-rw-r--r--cpukit/rtems/src/timerserverfireafter.c111
-rw-r--r--cpukit/rtems/src/timerserverfirewhen.c98
-rw-r--r--cpukit/sapi/.cvsignore2
-rw-r--r--cpukit/sapi/Makefile.am33
-rw-r--r--cpukit/sapi/include/confdefs.h1188
-rw-r--r--cpukit/sapi/include/rtems/README133
-rw-r--r--cpukit/sapi/include/rtems/config.h186
-rw-r--r--cpukit/sapi/include/rtems/extension.h140
-rw-r--r--cpukit/sapi/include/rtems/fatal.h51
-rw-r--r--cpukit/sapi/include/rtems/init.h97
-rw-r--r--cpukit/sapi/include/rtems/io.h275
-rw-r--r--cpukit/sapi/include/rtems/mptables.h28
-rw-r--r--cpukit/sapi/include/rtems/sptables.h73
-rw-r--r--cpukit/sapi/inline/rtems/extension.inl93
-rw-r--r--cpukit/sapi/macros/rtems/extension.inl60
-rw-r--r--cpukit/sapi/preinstall.am62
-rw-r--r--cpukit/sapi/src/debug.c65
-rw-r--r--cpukit/sapi/src/exinit.c303
-rw-r--r--cpukit/sapi/src/extension.c55
-rw-r--r--cpukit/sapi/src/extensioncreate.c73
-rw-r--r--cpukit/sapi/src/extensiondelete.c60
-rw-r--r--cpukit/sapi/src/extensionident.c57
-rw-r--r--cpukit/sapi/src/fatal.c41
-rw-r--r--cpukit/sapi/src/io.c423
-rw-r--r--cpukit/sapi/src/itronapi.c123
-rw-r--r--cpukit/sapi/src/posixapi.c119
-rw-r--r--cpukit/sapi/src/rtemsapi.c101
-rw-r--r--cpukit/score/.cvsignore2
-rw-r--r--cpukit/score/Doxyfile1079
-rw-r--r--cpukit/score/Makefile.am164
-rw-r--r--cpukit/score/cpu/.cvsignore2
-rw-r--r--cpukit/score/cpu/Makefile.am12
-rw-r--r--cpukit/score/cpu/arm/.cvsignore2
-rw-r--r--cpukit/score/cpu/arm/ChangeLog414
-rw-r--r--cpukit/score/cpu/arm/Makefile.am19
-rw-r--r--cpukit/score/cpu/arm/cpu.c368
-rw-r--r--cpukit/score/cpu/arm/cpu_asm.S164
-rw-r--r--cpukit/score/cpu/arm/preinstall.am45
-rw-r--r--cpukit/score/cpu/arm/rtems/asm.h122
-rw-r--r--cpukit/score/cpu/arm/rtems/score/arm.h77
-rw-r--r--cpukit/score/cpu/arm/rtems/score/cpu.h845
-rw-r--r--cpukit/score/cpu/arm/rtems/score/cpu_asm.h39
-rw-r--r--cpukit/score/cpu/arm/rtems/score/types.h54
-rw-r--r--cpukit/score/cpu/avr/.cvsignore2
-rw-r--r--cpukit/score/cpu/avr/ChangeLog79
-rw-r--r--cpukit/score/cpu/avr/Makefile.am19
-rw-r--r--cpukit/score/cpu/avr/README5
-rw-r--r--cpukit/score/cpu/avr/cpu.c185
-rw-r--r--cpukit/score/cpu/avr/cpu_asm.c182
-rw-r--r--cpukit/score/cpu/avr/preinstall.am45
-rw-r--r--cpukit/score/cpu/avr/rtems/asm.h97
-rw-r--r--cpukit/score/cpu/avr/rtems/score/avr.h90
-rw-r--r--cpukit/score/cpu/avr/rtems/score/cpu.h1141
-rw-r--r--cpukit/score/cpu/avr/rtems/score/cpu_asm.h72
-rw-r--r--cpukit/score/cpu/avr/rtems/score/types.h54
-rw-r--r--cpukit/score/cpu/c4x/.cvsignore2
-rw-r--r--cpukit/score/cpu/c4x/ChangeLog343
-rw-r--r--cpukit/score/cpu/c4x/Makefile.am22
-rw-r--r--cpukit/score/cpu/c4x/cpu.c199
-rw-r--r--cpukit/score/cpu/c4x/cpu_asm.S769
-rw-r--r--cpukit/score/cpu/c4x/irq.c89
-rw-r--r--cpukit/score/cpu/c4x/preinstall.am54
-rw-r--r--cpukit/score/cpu/c4x/rtems/asm.h97
-rw-r--r--cpukit/score/cpu/c4x/rtems/score/c4x.h367
-rw-r--r--cpukit/score/cpu/c4x/rtems/score/cpu.h1260
-rw-r--r--cpukit/score/cpu/c4x/rtems/score/cpu_asm.h72
-rw-r--r--cpukit/score/cpu/c4x/rtems/score/types.h54
-rw-r--r--cpukit/score/cpu/c4x/rtems/tic4x/c4xio.h110
-rw-r--r--cpukit/score/cpu/h8300/.cvsignore2
-rw-r--r--cpukit/score/cpu/h8300/ChangeLog338
-rw-r--r--cpukit/score/cpu/h8300/Makefile.am19
-rw-r--r--cpukit/score/cpu/h8300/README31
-rw-r--r--cpukit/score/cpu/h8300/cpu.c174
-rw-r--r--cpukit/score/cpu/h8300/cpu_asm.S224
-rw-r--r--cpukit/score/cpu/h8300/preinstall.am41
-rw-r--r--cpukit/score/cpu/h8300/rtems/asm.h120
-rw-r--r--cpukit/score/cpu/h8300/rtems/score/cpu.h1188
-rw-r--r--cpukit/score/cpu/h8300/rtems/score/h8300.h43
-rw-r--r--cpukit/score/cpu/h8300/rtems/score/types.h54
-rw-r--r--cpukit/score/cpu/i386/.cvsignore2
-rw-r--r--cpukit/score/cpu/i386/ChangeLog349
-rw-r--r--cpukit/score/cpu/i386/Makefile.am20
-rw-r--r--cpukit/score/cpu/i386/cpu.c197
-rw-r--r--cpukit/score/cpu/i386/cpu_asm.S274
-rw-r--r--cpukit/score/cpu/i386/preinstall.am53
-rw-r--r--cpukit/score/cpu/i386/rtems/asm.h138
-rw-r--r--cpukit/score/cpu/i386/rtems/score/cpu.h515
-rw-r--r--cpukit/score/cpu/i386/rtems/score/i386.h246
-rw-r--r--cpukit/score/cpu/i386/rtems/score/idtr.h66
-rw-r--r--cpukit/score/cpu/i386/rtems/score/interrupts.h79
-rw-r--r--cpukit/score/cpu/i386/rtems/score/registers.h186
-rw-r--r--cpukit/score/cpu/i386/rtems/score/types.h55
-rw-r--r--cpukit/score/cpu/m68k/.cvsignore2
-rw-r--r--cpukit/score/cpu/m68k/ChangeLog451
-rw-r--r--cpukit/score/cpu/m68k/Makefile.am24
-rw-r--r--cpukit/score/cpu/m68k/cpu.c212
-rw-r--r--cpukit/score/cpu/m68k/cpu_asm.S265
-rw-r--r--cpukit/score/cpu/m68k/preinstall.am62
-rw-r--r--cpukit/score/cpu/m68k/rtems/asm.h140
-rw-r--r--cpukit/score/cpu/m68k/rtems/m68k/m68302.h660
-rw-r--r--cpukit/score/cpu/m68k/rtems/m68k/m68360.h889
-rw-r--r--cpukit/score/cpu/m68k/rtems/m68k/qsm.h204
-rw-r--r--cpukit/score/cpu/m68k/rtems/m68k/sim.h333
-rw-r--r--cpukit/score/cpu/m68k/rtems/score/cpu.h701
-rw-r--r--cpukit/score/cpu/m68k/rtems/score/m68k.h439
-rw-r--r--cpukit/score/cpu/m68k/rtems/score/types.h55
-rw-r--r--cpukit/score/cpu/mips/.cvsignore2
-rw-r--r--cpukit/score/cpu/mips/ChangeLog526
-rw-r--r--cpukit/score/cpu/mips/Makefile.am22
-rw-r--r--cpukit/score/cpu/mips/cpu.c288
-rw-r--r--cpukit/score/cpu/mips/cpu_asm.S1153
-rw-r--r--cpukit/score/cpu/mips/preinstall.am54
-rw-r--r--cpukit/score/cpu/mips/rtems/asm.h158
-rw-r--r--cpukit/score/cpu/mips/rtems/mips/idtcpu.h695
-rw-r--r--cpukit/score/cpu/mips/rtems/mips/iregdef.h332
-rw-r--r--cpukit/score/cpu/mips/rtems/score/cpu.h1229
-rw-r--r--cpukit/score/cpu/mips/rtems/score/mips.h283
-rw-r--r--cpukit/score/cpu/mips/rtems/score/types.h55
-rw-r--r--cpukit/score/cpu/nios2/.cvsignore2
-rw-r--r--cpukit/score/cpu/nios2/ChangeLog18
-rw-r--r--cpukit/score/cpu/nios2/Makefile.am25
-rw-r--r--cpukit/score/cpu/nios2/cpu.c197
-rw-r--r--cpukit/score/cpu/nios2/cpu_asm.S388
-rw-r--r--cpukit/score/cpu/nios2/irq.c94
-rw-r--r--cpukit/score/cpu/nios2/preinstall.am43
-rw-r--r--cpukit/score/cpu/nios2/rtems/asm.h97
-rw-r--r--cpukit/score/cpu/nios2/rtems/score/cpu.h1404
-rw-r--r--cpukit/score/cpu/nios2/rtems/score/cpu_asm.h74
-rw-r--r--cpukit/score/cpu/nios2/rtems/score/nios2.h62
-rw-r--r--cpukit/score/cpu/nios2/rtems/score/types.h54
-rw-r--r--cpukit/score/cpu/no_cpu/.cvsignore2
-rw-r--r--cpukit/score/cpu/no_cpu/ChangeLog301
-rw-r--r--cpukit/score/cpu/no_cpu/Makefile.am19
-rw-r--r--cpukit/score/cpu/no_cpu/cpu.c185
-rw-r--r--cpukit/score/cpu/no_cpu/cpu_asm.c182
-rw-r--r--cpukit/score/cpu/no_cpu/preinstall.am45
-rw-r--r--cpukit/score/cpu/no_cpu/rtems/asm.h125
-rw-r--r--cpukit/score/cpu/no_cpu/rtems/score/cpu.h1325
-rw-r--r--cpukit/score/cpu/no_cpu/rtems/score/cpu_asm.h72
-rw-r--r--cpukit/score/cpu/no_cpu/rtems/score/no_cpu.h69
-rw-r--r--cpukit/score/cpu/no_cpu/rtems/score/types.h63
-rw-r--r--cpukit/score/cpu/powerpc/.cvsignore2
-rw-r--r--cpukit/score/cpu/powerpc/ChangeLog689
-rw-r--r--cpukit/score/cpu/powerpc/Makefile.am31
-rw-r--r--cpukit/score/cpu/powerpc/cpu.c12
-rw-r--r--cpukit/score/cpu/powerpc/preinstall.am73
-rw-r--r--cpukit/score/cpu/powerpc/rtems/asm.h261
-rw-r--r--cpukit/score/cpu/powerpc/rtems/new-exceptions/cpu.h374
-rw-r--r--cpukit/score/cpu/powerpc/rtems/old-exceptions/cpu.h506
-rw-r--r--cpukit/score/cpu/powerpc/rtems/powerpc/registers.h349
-rw-r--r--cpukit/score/cpu/powerpc/rtems/score/cpu.h783
-rw-r--r--cpukit/score/cpu/powerpc/rtems/score/powerpc.h560
-rw-r--r--cpukit/score/cpu/powerpc/rtems/score/ppc.h19
-rw-r--r--cpukit/score/cpu/powerpc/rtems/score/types.h70
-rw-r--r--cpukit/score/cpu/sh/.cvsignore2
-rw-r--r--cpukit/score/cpu/sh/ChangeLog339
-rw-r--r--cpukit/score/cpu/sh/Makefile.am19
-rw-r--r--cpukit/score/cpu/sh/cpu.c254
-rw-r--r--cpukit/score/cpu/sh/preinstall.am45
-rw-r--r--cpukit/score/cpu/sh/rtems/asm.h136
-rw-r--r--cpukit/score/cpu/sh/rtems/score/cpu.h946
-rw-r--r--cpukit/score/cpu/sh/rtems/score/sh.h273
-rw-r--r--cpukit/score/cpu/sh/rtems/score/sh_io.h51
-rw-r--r--cpukit/score/cpu/sh/rtems/score/types.h65
-rw-r--r--cpukit/score/cpu/sparc/.cvsignore2
-rw-r--r--cpukit/score/cpu/sparc/ChangeLog341
-rw-r--r--cpukit/score/cpu/sparc/Makefile.am19
-rw-r--r--cpukit/score/cpu/sparc/README110
-rw-r--r--cpukit/score/cpu/sparc/cpu.c330
-rw-r--r--cpukit/score/cpu/sparc/cpu_asm.S806
-rw-r--r--cpukit/score/cpu/sparc/preinstall.am41
-rw-r--r--cpukit/score/cpu/sparc/rtems/asm.h119
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/cpu.h1003
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/sparc.h268
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/types.h54
-rw-r--r--cpukit/score/cpu/unix/.cvsignore3
-rw-r--r--cpukit/score/cpu/unix/ChangeLog348
-rw-r--r--cpukit/score/cpu/unix/Makefile.am21
-rw-r--r--cpukit/score/cpu/unix/cpu.c1137
-rw-r--r--cpukit/score/cpu/unix/preinstall.am41
-rw-r--r--cpukit/score/cpu/unix/rtems/asm.h36
-rw-r--r--cpukit/score/cpu/unix/rtems/score/cpu.h1111
-rw-r--r--cpukit/score/cpu/unix/rtems/score/types.h69
-rw-r--r--cpukit/score/cpu/unix/rtems/score/unix.h73
-rw-r--r--cpukit/score/include/rtems/debug.h79
-rw-r--r--cpukit/score/include/rtems/score/.cvsignore1
-rw-r--r--cpukit/score/include/rtems/score/address.h43
-rw-r--r--cpukit/score/include/rtems/score/apiext.h127
-rw-r--r--cpukit/score/include/rtems/score/apimutex.h172
-rw-r--r--cpukit/score/include/rtems/score/bitfield.h106
-rw-r--r--cpukit/score/include/rtems/score/chain.h198
-rw-r--r--cpukit/score/include/rtems/score/context.h153
-rw-r--r--cpukit/score/include/rtems/score/copyrt.h42
-rw-r--r--cpukit/score/include/rtems/score/coremsg.h424
-rw-r--r--cpukit/score/include/rtems/score/coremutex.h360
-rw-r--r--cpukit/score/include/rtems/score/coresem.h196
-rw-r--r--cpukit/score/include/rtems/score/heap.h519
-rw-r--r--cpukit/score/include/rtems/score/interr.h103
-rw-r--r--cpukit/score/include/rtems/score/isr.h212
-rw-r--r--cpukit/score/include/rtems/score/mpci.h424
-rw-r--r--cpukit/score/include/rtems/score/mppkt.h123
-rw-r--r--cpukit/score/include/rtems/score/object.h810
-rw-r--r--cpukit/score/include/rtems/score/objectmp.h190
-rw-r--r--cpukit/score/include/rtems/score/priority.h133
-rw-r--r--cpukit/score/include/rtems/score/stack.h62
-rw-r--r--cpukit/score/include/rtems/score/states.h120
-rw-r--r--cpukit/score/include/rtems/score/sysstate.h91
-rw-r--r--cpukit/score/include/rtems/score/thread.h751
-rw-r--r--cpukit/score/include/rtems/score/threadmp.h88
-rw-r--r--cpukit/score/include/rtems/score/threadq.h230
-rw-r--r--cpukit/score/include/rtems/score/tod.h314
-rw-r--r--cpukit/score/include/rtems/score/tqdata.h126
-rw-r--r--cpukit/score/include/rtems/score/userext.h300
-rw-r--r--cpukit/score/include/rtems/score/watchdog.h244
-rw-r--r--cpukit/score/include/rtems/score/wkspace.h82
-rw-r--r--cpukit/score/include/rtems/seterr.h45
-rw-r--r--cpukit/score/include/rtems/system.h268
-rw-r--r--cpukit/score/inline/rtems/score/address.inl136
-rw-r--r--cpukit/score/inline/rtems/score/chain.inl391
-rw-r--r--cpukit/score/inline/rtems/score/coremsg.inl228
-rw-r--r--cpukit/score/inline/rtems/score/coremutex.inl201
-rw-r--r--cpukit/score/inline/rtems/score/coresem.inl112
-rw-r--r--cpukit/score/inline/rtems/score/heap.inl370
-rw-r--r--cpukit/score/inline/rtems/score/isr.inl54
-rw-r--r--cpukit/score/inline/rtems/score/mppkt.inl57
-rw-r--r--cpukit/score/inline/rtems/score/object.inl307
-rw-r--r--cpukit/score/inline/rtems/score/objectmp.inl67
-rw-r--r--cpukit/score/inline/rtems/score/priority.inl201
-rw-r--r--cpukit/score/inline/rtems/score/stack.inl75
-rw-r--r--cpukit/score/inline/rtems/score/states.inl287
-rw-r--r--cpukit/score/inline/rtems/score/sysstate.inl123
-rw-r--r--cpukit/score/inline/rtems/score/thread.inl334
-rw-r--r--cpukit/score/inline/rtems/score/threadmp.inl61
-rw-r--r--cpukit/score/inline/rtems/score/tod.inl61
-rw-r--r--cpukit/score/inline/rtems/score/tqdata.inl69
-rw-r--r--cpukit/score/inline/rtems/score/userext.inl156
-rw-r--r--cpukit/score/inline/rtems/score/watchdog.inl258
-rw-r--r--cpukit/score/inline/rtems/score/wkspace.inl56
-rw-r--r--cpukit/score/macros/README14
-rw-r--r--cpukit/score/macros/rtems/score/address.inl75
-rw-r--r--cpukit/score/macros/rtems/score/chain.inl199
-rw-r--r--cpukit/score/macros/rtems/score/coremsg.inl148
-rw-r--r--cpukit/score/macros/rtems/score/coremutex.inl81
-rw-r--r--cpukit/score/macros/rtems/score/coresem.inl71
-rw-r--r--cpukit/score/macros/rtems/score/heap.inl221
-rw-r--r--cpukit/score/macros/rtems/score/isr.inl38
-rw-r--r--cpukit/score/macros/rtems/score/mppkt.inl40
-rw-r--r--cpukit/score/macros/rtems/score/object.inl198
-rw-r--r--cpukit/score/macros/rtems/score/objectmp.inl49
-rw-r--r--cpukit/score/macros/rtems/score/priority.inl169
-rw-r--r--cpukit/score/macros/rtems/score/stack.inl49
-rw-r--r--cpukit/score/macros/rtems/score/states.inl209
-rw-r--r--cpukit/score/macros/rtems/score/sysstate.inl89
-rw-r--r--cpukit/score/macros/rtems/score/thread.inl242
-rw-r--r--cpukit/score/macros/rtems/score/threadmp.inl50
-rw-r--r--cpukit/score/macros/rtems/score/tod.inl48
-rw-r--r--cpukit/score/macros/rtems/score/tqdata.inl49
-rw-r--r--cpukit/score/macros/rtems/score/userext.inl133
-rw-r--r--cpukit/score/macros/rtems/score/watchdog.inl171
-rw-r--r--cpukit/score/macros/rtems/score/wkspace.inl38
-rw-r--r--cpukit/score/mainpage.h5
-rw-r--r--cpukit/score/preinstall.am331
-rw-r--r--cpukit/score/src/Unlimited.txt387
-rw-r--r--cpukit/score/src/apiext.c107
-rw-r--r--cpukit/score/src/chain.c205
-rw-r--r--cpukit/score/src/coremsg.c125
-rw-r--r--cpukit/score/src/coremsgbroadcast.c115
-rw-r--r--cpukit/score/src/coremsgclose.c80
-rw-r--r--cpukit/score/src/coremsgflush.c58
-rw-r--r--cpukit/score/src/coremsgflushsupp.c108
-rw-r--r--cpukit/score/src/coremsgflushwait.c73
-rw-r--r--cpukit/score/src/coremsginsert.c117
-rw-r--r--cpukit/score/src/coremsgseize.c140
-rw-r--r--cpukit/score/src/coremsgsubmit.c179
-rw-r--r--cpukit/score/src/coremutex.c81
-rw-r--r--cpukit/score/src/coremutexflush.c55
-rw-r--r--cpukit/score/src/coremutexseize.c142
-rw-r--r--cpukit/score/src/coremutexsurrender.c156
-rw-r--r--cpukit/score/src/coresem.c66
-rw-r--r--cpukit/score/src/coresemflush.c61
-rw-r--r--cpukit/score/src/coresemseize.c84
-rw-r--r--cpukit/score/src/coresemsurrender.c79
-rw-r--r--cpukit/score/src/coretod.c63
-rw-r--r--cpukit/score/src/coretodset.c66
-rw-r--r--cpukit/score/src/coretodtickle.c71
-rw-r--r--cpukit/score/src/coretodtoseconds.c67
-rw-r--r--cpukit/score/src/coretodvalidate.c67
-rw-r--r--cpukit/score/src/heap.c267
-rw-r--r--cpukit/score/src/heapallocate.c81
-rw-r--r--cpukit/score/src/heapallocatealigned.c194
-rw-r--r--cpukit/score/src/heapextend.c104
-rw-r--r--cpukit/score/src/heapfree.c132
-rw-r--r--cpukit/score/src/heapgetfreeinfo.c63
-rw-r--r--cpukit/score/src/heapgetinfo.c83
-rw-r--r--cpukit/score/src/heapresizeblock.c170
-rw-r--r--cpukit/score/src/heapsizeofuserarea.c87
-rw-r--r--cpukit/score/src/heapwalk.c176
-rw-r--r--cpukit/score/src/interr.c64
-rw-r--r--cpukit/score/src/isr.c69
-rw-r--r--cpukit/score/src/iterateoverthreads.c50
-rw-r--r--cpukit/score/src/mpci.c528
-rw-r--r--cpukit/score/src/object.c68
-rw-r--r--cpukit/score/src/objectallocate.c72
-rw-r--r--cpukit/score/src/objectallocatebyindex.c77
-rw-r--r--cpukit/score/src/objectclearname.c50
-rw-r--r--cpukit/score/src/objectcomparenameraw.c61
-rw-r--r--cpukit/score/src/objectcomparenamestring.c57
-rw-r--r--cpukit/score/src/objectcopynameraw.c50
-rw-r--r--cpukit/score/src/objectcopynamestring.c53
-rw-r--r--cpukit/score/src/objectextendinformation.c295
-rw-r--r--cpukit/score/src/objectfree.c69
-rw-r--r--cpukit/score/src/objectget.c87
-rw-r--r--cpukit/score/src/objectgetbyindex.c77
-rw-r--r--cpukit/score/src/objectgetisr.c93
-rw-r--r--cpukit/score/src/objectgetnext.c94
-rw-r--r--cpukit/score/src/objectgetnoprotection.c87
-rw-r--r--cpukit/score/src/objectidtoname.c73
-rw-r--r--cpukit/score/src/objectinitializeinformation.c181
-rw-r--r--cpukit/score/src/objectmp.c280
-rw-r--r--cpukit/score/src/objectnametoid.c105
-rw-r--r--cpukit/score/src/objectshrinkinformation.c119
-rw-r--r--cpukit/score/src/thread.c111
-rw-r--r--cpukit/score/src/threadchangepriority.c117
-rw-r--r--cpukit/score/src/threadclearstate.c85
-rw-r--r--cpukit/score/src/threadclose.c77
-rw-r--r--cpukit/score/src/threadcreateidle.c100
-rw-r--r--cpukit/score/src/threaddelayended.c64
-rw-r--r--cpukit/score/src/threaddispatch.c144
-rw-r--r--cpukit/score/src/threadevaluatemode.c53
-rw-r--r--cpukit/score/src/threadget.c87
-rw-r--r--cpukit/score/src/threadhandler.c168
-rw-r--r--cpukit/score/src/threadidlebody.c55
-rw-r--r--cpukit/score/src/threadinitialize.c228
-rw-r--r--cpukit/score/src/threadloadenv.c76
-rw-r--r--cpukit/score/src/threadmp.c168
-rw-r--r--cpukit/score/src/threadq.c69
-rw-r--r--cpukit/score/src/threadqdequeue.c65
-rw-r--r--cpukit/score/src/threadqdequeuefifo.c89
-rw-r--r--cpukit/score/src/threadqdequeuepriority.c128
-rw-r--r--cpukit/score/src/threadqenqueue.c83
-rw-r--r--cpukit/score/src/threadqenqueuefifo.c101
-rw-r--r--cpukit/score/src/threadqenqueuepriority.c221
-rw-r--r--cpukit/score/src/threadqextract.c57
-rw-r--r--cpukit/score/src/threadqextractfifo.c76
-rw-r--r--cpukit/score/src/threadqextractpriority.c107
-rw-r--r--cpukit/score/src/threadqextractwithproxy.c66
-rw-r--r--cpukit/score/src/threadqfirst.c61
-rw-r--r--cpukit/score/src/threadqfirstfifo.c50
-rw-r--r--cpukit/score/src/threadqfirstpriority.c56
-rw-r--r--cpukit/score/src/threadqflush.c58
-rw-r--r--cpukit/score/src/threadqtimeout.c81
-rw-r--r--cpukit/score/src/threadready.c78
-rw-r--r--cpukit/score/src/threadreset.c68
-rw-r--r--cpukit/score/src/threadresettimeslice.c75
-rw-r--r--cpukit/score/src/threadrestart.c68
-rw-r--r--cpukit/score/src/threadresume.c98
-rw-r--r--cpukit/score/src/threadrotatequeue.c90
-rw-r--r--cpukit/score/src/threadsetpriority.c56
-rw-r--r--cpukit/score/src/threadsetstate.c87
-rw-r--r--cpukit/score/src/threadsettransient.c77
-rw-r--r--cpukit/score/src/threadstackallocate.c85
-rw-r--r--cpukit/score/src/threadstackfree.c60
-rw-r--r--cpukit/score/src/threadstart.c70
-rw-r--r--cpukit/score/src/threadstartmultitasking.c93
-rw-r--r--cpukit/score/src/threadsuspend.c86
-rw-r--r--cpukit/score/src/threadtickletimeslice.c90
-rw-r--r--cpukit/score/src/threadyieldprocessor.c76
-rw-r--r--cpukit/score/src/userext.c205
-rw-r--r--cpukit/score/src/watchdog.c42
-rw-r--r--cpukit/score/src/watchdogadjust.c87
-rw-r--r--cpukit/score/src/watchdoginsert.c123
-rw-r--r--cpukit/score/src/watchdogremove.c73
-rw-r--r--cpukit/score/src/watchdogtickle.c129
-rw-r--r--cpukit/score/src/wkspace.c91
-rw-r--r--cpukit/telnetd/.cvsignore2
-rw-r--r--cpukit/telnetd/Makefile.am21
-rw-r--r--cpukit/telnetd/README28
-rw-r--r--cpukit/telnetd/icmds.c49
-rw-r--r--cpukit/telnetd/preinstall.am45
-rw-r--r--cpukit/telnetd/pty.c408
-rw-r--r--cpukit/telnetd/pty.h70
-rw-r--r--cpukit/telnetd/telnetd.c136
-rw-r--r--cpukit/telnetd/telnetd.h39
-rw-r--r--cpukit/wrapup/.cvsignore2
-rw-r--r--cpukit/wrapup/Makefile.am105
-rw-r--r--cpukit/wrapup/preinstall.am24
-rw-r--r--cpukit/zlib/.cvsignore2
-rw-r--r--cpukit/zlib/ChangeLog816
-rw-r--r--cpukit/zlib/ChangeLog.zlib805
-rw-r--r--cpukit/zlib/Makefile154
-rw-r--r--cpukit/zlib/Makefile.am28
-rw-r--r--cpukit/zlib/Makefile.in154
-rw-r--r--cpukit/zlib/adler32.c2
-rw-r--r--cpukit/zlib/amiga/Makefile.pup66
-rw-r--r--cpukit/zlib/amiga/Makefile.sas65
-rw-r--r--cpukit/zlib/as400/bndsrc132
-rw-r--r--cpukit/zlib/as400/compile.clp123
-rw-r--r--cpukit/zlib/as400/readme.txt111
-rw-r--r--cpukit/zlib/as400/zlib.inc327
-rw-r--r--cpukit/zlib/compress.c2
-rwxr-xr-xcpukit/zlib/configure446
-rw-r--r--cpukit/zlib/contrib/README.contrib67
-rw-r--r--cpukit/zlib/contrib/ada/buffer_demo.adb106
-rw-r--r--cpukit/zlib/contrib/ada/mtest.adb156
-rw-r--r--cpukit/zlib/contrib/ada/read.adb156
-rw-r--r--cpukit/zlib/contrib/ada/readme.txt65
-rw-r--r--cpukit/zlib/contrib/ada/test.adb463
-rw-r--r--cpukit/zlib/contrib/ada/zlib-streams.adb225
-rw-r--r--cpukit/zlib/contrib/ada/zlib-streams.ads114
-rw-r--r--cpukit/zlib/contrib/ada/zlib-thin.adb141
-rw-r--r--cpukit/zlib/contrib/ada/zlib-thin.ads450
-rw-r--r--cpukit/zlib/contrib/ada/zlib.adb701
-rw-r--r--cpukit/zlib/contrib/ada/zlib.ads328
-rw-r--r--cpukit/zlib/contrib/ada/zlib.gpr20
-rw-r--r--cpukit/zlib/contrib/asm586/README.58643
-rw-r--r--cpukit/zlib/contrib/asm586/match.S354
-rw-r--r--cpukit/zlib/contrib/asm686/README.68634
-rw-r--r--cpukit/zlib/contrib/asm686/match.S327
-rw-r--r--cpukit/zlib/contrib/blast/Makefile8
-rw-r--r--cpukit/zlib/contrib/blast/README4
-rw-r--r--cpukit/zlib/contrib/blast/blast.c444
-rw-r--r--cpukit/zlib/contrib/blast/blast.h71
-rw-r--r--cpukit/zlib/contrib/blast/test.pkbin8 -> 0 bytes
-rw-r--r--cpukit/zlib/contrib/blast/test.txt1
-rw-r--r--cpukit/zlib/contrib/delphi/ZLib.pas557
-rw-r--r--cpukit/zlib/contrib/delphi/ZLibConst.pas11
-rw-r--r--cpukit/zlib/contrib/delphi/readme.txt76
-rw-r--r--cpukit/zlib/contrib/delphi/zlibd32.mak93
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib.build33
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib.chmbin72726 -> 0 bytes
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib.sln21
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs58
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs202
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs83
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib/CodecBase.cs198
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib/Deflater.cs106
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib/DotZLib.cs288
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj141
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib/GZipStream.cs301
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib/Inflater.cs105
-rw-r--r--cpukit/zlib/contrib/dotzlib/DotZLib/UnitTests.cs274
-rw-r--r--cpukit/zlib/contrib/dotzlib/LICENSE_1_0.txt23
-rw-r--r--cpukit/zlib/contrib/dotzlib/readme.txt58
-rw-r--r--cpukit/zlib/contrib/infback9/README1
-rw-r--r--cpukit/zlib/contrib/infback9/infback9.c608
-rw-r--r--cpukit/zlib/contrib/infback9/infback9.h29
-rw-r--r--cpukit/zlib/contrib/infback9/inffix9.h107
-rw-r--r--cpukit/zlib/contrib/infback9/inflate9.h47
-rw-r--r--cpukit/zlib/contrib/infback9/inftree9.c323
-rw-r--r--cpukit/zlib/contrib/infback9/inftree9.h55
-rw-r--r--cpukit/zlib/contrib/inflate86/inffas86.c1157
-rw-r--r--cpukit/zlib/contrib/inflate86/inffast.S1368
-rw-r--r--cpukit/zlib/contrib/iostream/test.cpp24
-rw-r--r--cpukit/zlib/contrib/iostream/zfstream.cpp329
-rw-r--r--cpukit/zlib/contrib/iostream/zfstream.h128
-rw-r--r--cpukit/zlib/contrib/iostream2/zstream.h307
-rw-r--r--cpukit/zlib/contrib/iostream2/zstream_test.cpp25
-rw-r--r--cpukit/zlib/contrib/iostream3/README35
-rw-r--r--cpukit/zlib/contrib/iostream3/TODO17
-rw-r--r--cpukit/zlib/contrib/iostream3/test.cc50
-rw-r--r--cpukit/zlib/contrib/iostream3/zfstream.cc479
-rw-r--r--cpukit/zlib/contrib/iostream3/zfstream.h466
-rw-r--r--cpukit/zlib/contrib/masm686/match.asm408
-rw-r--r--cpukit/zlib/contrib/masmx64/bld_ml64.bat2
-rw-r--r--cpukit/zlib/contrib/masmx86/gvmat32.asm909
-rw-r--r--cpukit/zlib/contrib/masmx86/gvmat32c.c206
-rw-r--r--cpukit/zlib/contrib/masmx86/inffas32.asm1036
-rwxr-xr-xcpukit/zlib/contrib/masmx86/mkasm.bat3
-rw-r--r--cpukit/zlib/contrib/masmx86/readme.txt21
-rw-r--r--cpukit/zlib/contrib/minizip/ChangeLogUnzip63
-rw-r--r--cpukit/zlib/contrib/minizip/Makefile25
-rw-r--r--cpukit/zlib/contrib/minizip/crypt.h132
-rw-r--r--cpukit/zlib/contrib/minizip/ioapi.c177
-rw-r--r--cpukit/zlib/contrib/minizip/ioapi.h75
-rw-r--r--cpukit/zlib/contrib/minizip/iowin32.c270
-rw-r--r--cpukit/zlib/contrib/minizip/iowin32.h21
-rw-r--r--cpukit/zlib/contrib/minizip/miniunz.c585
-rw-r--r--cpukit/zlib/contrib/minizip/minizip.c420
-rw-r--r--cpukit/zlib/contrib/minizip/mztools.c281
-rw-r--r--cpukit/zlib/contrib/minizip/mztools.h31
-rw-r--r--cpukit/zlib/contrib/minizip/unzip.c1595
-rw-r--r--cpukit/zlib/contrib/minizip/unzip.h352
-rw-r--r--cpukit/zlib/contrib/minizip/zip.c1188
-rw-r--r--cpukit/zlib/contrib/minizip/zip.h234
-rw-r--r--cpukit/zlib/contrib/pascal/example.pas599
-rw-r--r--cpukit/zlib/contrib/pascal/readme.txt76
-rw-r--r--cpukit/zlib/contrib/pascal/zlibd32.mak93
-rw-r--r--cpukit/zlib/contrib/pascal/zlibpas.pas236
-rw-r--r--cpukit/zlib/contrib/puff/Makefile8
-rw-r--r--cpukit/zlib/contrib/puff/README63
-rw-r--r--cpukit/zlib/contrib/puff/puff.c837
-rw-r--r--cpukit/zlib/contrib/puff/puff.h31
-rw-r--r--cpukit/zlib/contrib/puff/zeros.rawbin1213 -> 0 bytes
-rw-r--r--cpukit/zlib/contrib/testzlib/testzlib.c149
-rw-r--r--cpukit/zlib/contrib/testzlib/testzlib.sln21
-rw-r--r--cpukit/zlib/contrib/testzlib/testzlib.txt10
-rw-r--r--cpukit/zlib/contrib/testzlib/testzlib.vcproj124
-rw-r--r--cpukit/zlib/contrib/untgz/Makefile14
-rw-r--r--cpukit/zlib/contrib/untgz/Makefile.msc17
-rw-r--r--cpukit/zlib/contrib/untgz/untgz.c674
-rw-r--r--cpukit/zlib/contrib/vstudio/readme.txt55
-rw-r--r--cpukit/zlib/contrib/vstudio/vc7/miniunz.vcproj124
-rw-r--r--cpukit/zlib/contrib/vstudio/vc7/minizip.vcproj124
-rw-r--r--cpukit/zlib/contrib/vstudio/vc7/zlib.rc32
-rw-r--r--cpukit/zlib/contrib/vstudio/vc7/zlibstat.vcproj242
-rw-r--r--cpukit/zlib/contrib/vstudio/vc7/zlibvc.def92
-rw-r--r--cpukit/zlib/contrib/vstudio/vc7/zlibvc.sln66
-rw-r--r--cpukit/zlib/contrib/vstudio/vc7/zlibvc.vcproj436
-rw-r--r--cpukit/zlib/crc32.c14
-rw-r--r--cpukit/zlib/deflate.c2
-rw-r--r--cpukit/zlib/deflate.h2
-rw-r--r--cpukit/zlib/example.c565
-rw-r--r--cpukit/zlib/examples/README.examples29
-rw-r--r--cpukit/zlib/examples/fitblk.c235
-rw-r--r--cpukit/zlib/examples/gzappend.c500
-rw-r--r--cpukit/zlib/examples/gzjoin.c447
-rw-r--r--cpukit/zlib/examples/gzlog.c413
-rw-r--r--cpukit/zlib/examples/gzlog.h58
-rw-r--r--cpukit/zlib/examples/zlib_how.html522
-rw-r--r--cpukit/zlib/examples/zpipe.c191
-rw-r--r--cpukit/zlib/gzio.c2
-rw-r--r--cpukit/zlib/inftrees.c2
-rw-r--r--cpukit/zlib/inftrees.h8
-rw-r--r--cpukit/zlib/make_vms.com114
-rw-r--r--cpukit/zlib/minigzip.c320
-rw-r--r--cpukit/zlib/msdos/Makefile.bor109
-rw-r--r--cpukit/zlib/msdos/Makefile.dj2104
-rw-r--r--cpukit/zlib/msdos/Makefile.emx69
-rw-r--r--cpukit/zlib/msdos/Makefile.msc106
-rw-r--r--cpukit/zlib/msdos/Makefile.tc94
-rw-r--r--cpukit/zlib/old/Makefile.riscos151
-rw-r--r--cpukit/zlib/old/README3
-rw-r--r--cpukit/zlib/old/descrip.mms48
-rw-r--r--cpukit/zlib/old/os2/Makefile.os2136
-rw-r--r--cpukit/zlib/old/os2/zlib.def51
-rw-r--r--cpukit/zlib/old/visual-basic.txt160
-rw-r--r--cpukit/zlib/old/zlib.html971
-rw-r--r--cpukit/zlib/preinstall.am42
-rw-r--r--cpukit/zlib/projects/README.projects41
-rw-r--r--cpukit/zlib/projects/visualc6/README.txt73
-rw-r--r--cpukit/zlib/projects/visualc6/example.dsp278
-rw-r--r--cpukit/zlib/projects/visualc6/minigzip.dsp278
-rw-r--r--cpukit/zlib/projects/visualc6/zlib.dsp609
-rw-r--r--cpukit/zlib/projects/visualc6/zlib.dsw59
-rw-r--r--cpukit/zlib/qnx/package.qpg141
-rw-r--r--cpukit/zlib/trees.c2
-rw-r--r--cpukit/zlib/uncompr.c2
-rw-r--r--cpukit/zlib/win32/DLL_FAQ.txt397
-rw-r--r--cpukit/zlib/win32/Makefile.bor107
-rw-r--r--cpukit/zlib/win32/Makefile.emx69
-rw-r--r--cpukit/zlib/win32/Makefile.gcc141
-rw-r--r--cpukit/zlib/win32/Makefile.msc126
-rw-r--r--cpukit/zlib/win32/VisualC.txt3
-rw-r--r--cpukit/zlib/win32/zlib.def60
-rw-r--r--cpukit/zlib/win32/zlib1.rc39
-rw-r--r--cpukit/zlib/zconf.h15
-rw-r--r--cpukit/zlib/zconf.in.h330
-rw-r--r--cpukit/zlib/zutil.c6
-rw-r--r--cpukit/zlib/zutil.h4
1913 files changed, 322863 insertions, 35164 deletions
diff --git a/cpukit/.cvsignore b/cpukit/.cvsignore
new file mode 100644
index 0000000000..5c181fbb08
--- /dev/null
+++ b/cpukit/.cvsignore
@@ -0,0 +1,16 @@
+aclocal.m4
+autom4te*.cache
+config.cache
+config.guess
+config.h.in
+config.log
+config.status
+config.sub
+configure
+depcomp
+install-sh
+Makefile
+Makefile.in
+missing
+mkinstalldirs
+stamp-h.in
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog
new file mode 100644
index 0000000000..6eb21eb186
--- /dev/null
+++ b/cpukit/ChangeLog
@@ -0,0 +1,8894 @@
+2006-08-10 Till Straumann <strauman@slac.stanford.edu>
+
+ * libnetworking/rtems/rtems_mii_ioctl_kern.c:
+ fixed wrong calculation of 1000baseTx autonegotiation
+ result.
+
+2006-08-09 Kolja Waschk <waschk@telos.de>
+
+ * configure.ac, librpc/src/xdr/xdr_float.c, score/cpu/Makefile.am: New
+ port to Altera NIOS II.
+
+2006-08-08 Till Straumann <strauman@slac.stanford.edu>
+
+ * libnetworking/rtems/rtems_mii_ioctl_kern.c:
+ read ANER and include partner's autoneg
+ capability when determining active link parameters.
+
+2006-07-12 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 1110/networking
+ * libnetworking/machine/in_cksum.h: Replaced PPC and
+ i386 assembly algorithms (must not assume carry bit is preserved
+ across multiple asms). Added packet header as a 'm' input
+ operand for all CPU variants. Added carry bit to clobber list.
+
+2006-07-12 Till Straumann <strauman@slac.stanford.edu>
+
+ * pppd/sys-rtems.c: fixed error message so that the correct
+ ioctl is reported.
+
+2006-07-11 Joel Sherrill <joel@OARcorp.com>
+
+ PR 1124/rtems
+ * score/include/rtems/score/threadq.h, score/src/coremutexseize.c,
+ score/src/coremutexsurrender.c, score/src/threadqenqueue.c,
+ score/src/threadqenqueuefifo.c, score/src/threadqenqueuepriority.c:
+ The placement of the changing a thread's priority when using priority
+ ceiling should be on the successful transfer of the mutex -- not when
+ the thread tries to acquire. Plus the lack of a dispatch disable
+ point lead to the potential for a thread timing out and already
+ having inherited the ceiling priority.
+
+2006-07-09 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+
+ * libblock/src/bdbuf.c:
+ * libblock/include/bdbuf.h:
+ (PR1118) fetch priority for swapout task from a variable,
+ not a fixed configuration value.
+
+ * libfs/src/imfs/imfs.h:
+ * libfs/src/imfs/imfs_initsupp.c:
+ (PR1118) fetch bytes_per_block value from a configuration variable,
+ not from a preprocessor macro
+
+ * sapi/include/confdefs.h:
+ (PR1118) add configuration mechanisms for:
+ - ATA task priority
+ - swapout task priority
+ - libblock basic configuration
+ conditionally add ata driver to device driver table
+ conditionally add ide driver to device driver table
+
+ * libcsupport/include/sys/cdefs.h:
+ * libnetworking/include/sys/linker_set.h:
+ (PR1119) change attribute "unused" to "used" for sysctl data structures
+
+ * libmisc/shell/shell.c:
+ (PR1120) adapt stdio redirection to current newlib behaviour
+
+2006-06-28 Ralf Corsépius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Add ampolish3.
+
+2006-06-28 Ralf Corsépius <ralf.corsepius@rtems.org>
+ * ampolish3: New.
+ * aclocal/rtems-ampolish.m4: Reflect using in-sourcetree ampolish3.
+
+2006-06-24 Ralf Corsépius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/if_var.h: #include <sys/queue.h>.
+ Cosmetics from FreeBSD.
+
+2006-06-23 Ralf Corsépius <ralf.corsepius@rtems.org>
+
+ * libcsupport/include/rtems/cdefs.h: Partial update from freebsd.
+
+2006-06-22 Joel Sherrill <joel@OARcorp.com>
+
+ PR 1101/rtems
+ * libcsupport/src/base_fs.c: Remove extra endif.
+
+2006-06-22 Joel Sherrill <joel@OARcorp.com>
+
+ PR 1101/rtems
+ * libcsupport/src/base_fs.c, rtems/src/taskcreate.c, rtems/src/tasks.c,
+ score/src/coremutex.c: Remove dead code.
+
+2006-06-18 Ralf Corsépius <ralf.corsepius@rtems.org>
+
+ * libcsupport/include/rtems/libio.h: Add extern "C" {}.
+
+2006-06-18 Ralf Corsépius <ralf.corsepius@rtems.org>
+
+ * posix/src/mqueue.c: Remove duplicate #include <limits.h>.
+ PR 1088/rtems
+ * posix/src/ptimer.c: Add missing #include <limits.h>.
+
+2006-06-08 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/Makefile.am, posix/preinstall.am,
+ posix/include/rtems/posix/timer.h, posix/src/ptimer.c,
+ posix/src/ptimer1.c, sapi/src/posixapi.c,
+ score/include/rtems/score/object.h:
+
+2006-06-02 Joel Sherrill <joel@OARcorp.com>
+
+ * itron/src/trcv_mbf.c, posix/src/semopen.c,
+ rtems/src/taskvariableadd.c, score/macros/rtems/score/heap.inl: Fix
+ warnings.
+
+2006-05-31 Eric Norum <norume@aps.anl.gov>
+
+ * libnetworking/netinet/ip_icmp.c: Update icps_allecho counter.
+
+2006-05-30 Eric Norum <norume@aps.anl.gov>
+
+ * libnetworking/netinet/icmp_var.h, libnetworking/netinet/ip_icmp.c,
+ libnetworking/rtems/rtems_showicmpstat.c: Add flag to inhibit ICMP
+ replies.
+
+2006-05-25 Eric Norum <norume@aps.anl.gov>
+
+ * libnetworking/Makefile.am, libnetworking/Makefile.in,
+ libnetworking/rtems/rtems_bsdnet.h, libnetworking/rtems/rtems_glue.c,
+ libnetworking/rtems/rtems_malloc_mbuf.c: Provide customisable mbuf
+ allocation. Patch from Steven Johnson <sjohnson@sakuraindustries.com>
+
+2006-05-16 Ralf Corsépius <ralf.corsepius@rtems.org>
+
+ * aclocal/rtems-ampolish.m4: New.
+ * configure.ac: Use RTEMS_AMPOLISH3.
+
+2006-04-27 Eric Norum <norume@aps.anl.gov>
+
+ * telnetd/pty.c: Accept <CR><NUL> as equivalent to <CR><LF>.
+
+2006-04-27 Eric Norum <norume@aps.anl.gov>
+
+ * libmisc/capture/capture.h, libmisc/capture/capture.c
+ Add ability to free information on task delete.
+
+2006-04-18 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-4.6.99.3.
+
+2006-04-13 Joel Sherrill <joel@OARcorp.com>
+
+ PR 949/networking
+ * libnetworking/sys/socket.h: GNU/Linux is wrong in making
+ MSG_DONTWAIT public. It is strictly BSD and not SUSV. See
+ http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/socket.h.html
+ for clarification.
+
+2006-04-12 Lars Munch <lars@segv.dk>
+
+ PR 949/networking
+ * libnetworking/sys/socket.h: Make MSG_DONTWAIT public as in GNU/Linux.
+
+2006-04-06 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/inline/rtems/posix/mutex.inl,
+ posix/inline/rtems/posix/timer.inl,
+ posix/macros/rtems/posix/cond.inl,
+ posix/macros/rtems/posix/mutex.inl,
+ posix/macros/rtems/posix/timer.inl: Fix warnings.
+
+ * score/inline/rtems/score/threadmp.inl,
+ score/macros/rtems/score/threadmp.inl: Fix compile error.
+
+2006-04-05 Joel Sherrill <joel@OARcorp.com>
+ Victor V. Vengerov <Victor.Vengerov@oktetlabs.ru>
+
+ * score/include/rtems/score/mpci.h,
+ score/include/rtems/score/threadmp.h,
+ score/inline/rtems/score/threadmp.inl,
+ score/macros/rtems/score/threadmp.inl, score/src/threadmp.c,
+ score/src/threadqenqueue.c: Victor spotted the problem that
+ _MPCI_Receive_server_tcb and _Thread_MP_Receive were duplicate
+ variables and needed to be set to the same value. I took that
+ idea and just removed _Thread_MP_Receive. All uses are now
+ _MPCI_Receive_server_tcb.
+
+2006-03-27 Eric Norum <norume@aps.anl.gov>
+
+ * libmisc/monitor/prmisc.c: Eliminate undesired sign-extension.
+
+2006-03-08 Joel Sherrill <joel@OARcorp.com>
+
+ PR 761/rtems
+ * score/src/threadhandler.c: Add volatile cast so test is weak function
+ is present will do something. Otherwise, it can be assume by gcc to
+ always be a true condition.
+
+2006-03-08 Joel Sherrill <joel@OARcorp.com>
+
+ * itron/macros/rtems/itron/semaphore.inl,
+ itron/macros/rtems/itron/task.inl: Fix warnings.
+ * posix/macros/rtems/posix/cond.inl: Fix typo.
+ * score/macros/rtems/score/heap.inl: Fix missed type change.
+
+2006-03-07 Till Strauman <strauman@slac.stanford.edu>
+
+ PR 830/filesystem
+ * libcsupport/src/termios.c: termios ioctl(FIONREAD) reported wrong
+ number of characters. So add chars in low-level/raw buffer to total
+ count.
+
+2006-03-07 Steven Johnson <sjohnson@sakuraindustries.com>
+
+ PR 850/rtems
+ * score/src/watchdogtickle.c: A Watchdog (used to timeout an event)
+ with a delay of 1 sometimes does not seem to timeout. The problem
+ occurs, because for whatever reason when the watchdog tickle function
+ executes, the watchdog->delta_interval is 0. it is then decremented
+ before being tested, becomes huge and so doesnt time out. It is
+ thought there is a race condition where the watchdog->delta_interval
+ is calculated by reference to a head (also with a delay of 1). But
+ before it can be added after the head, the head is removed, so the
+ new head now has a delay of 0.
+
+2006-03-07 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+
+ PR 852/filesystem
+ * libblock/src/bdbuf.c: Increase performance of MSDOS file accesses by
+ using a simple read-ahead and write-combining scheme. Improvement is
+ dramatic.
+
+2006-03-07 Till Strauman <strauman@slac.stanford.edu>
+
+ PR 886/filesystem
+ * libcsupport/src/libio.c: fcntl(fd,F_GETFL) fails to set O_NONBLOCK if
+ the descriptor is in non-blocking mode.
+
+2006-03-07 Joel Sherrill <joel@OARcorp.com>
+
+ PR 866/rtems
+ * score/include/rtems/system.h, score/include/rtems/score/isr.h,
+ score/inline/rtems/score/thread.inl,
+ score/macros/rtems/score/thread.inl: Added memory barriers to enter
+ and exit of dispatching and interrupt critical sections so GCC will
+ not optimize and reorder code out of a critical section.
+
+2006-02-08 Thomas Rauscher <trauscher@loytec.com>
+
+ PR 890/networking
+ * httpd/webs.c: The webservers enters an infinite loop when a POST
+ request with less data than indicated in the Content-Length header is
+ received. It also consumes additional heap memory and a file
+ descriptor for each invalid POST.
+
+2006-02-01 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/inline/rtems/posix/cond.inl, posix/macros/rtems/posix/cond.inl,
+ posix/src/conddestroy.c: Remove warnings.
+
+2006-02-01 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/src/tasks.c, rtems/src/taskvariableadd.c,
+ rtems/src/taskvariabledelete.c, rtems/src/taskvariableget.c: Remove
+ warnings.
+
+2006-01-18 Ralf Corsépius <ralf.corsepius@rtems.org>
+
+ * posix/include/intr.h, posix/include/rtems/posix/intr.h
+ posix/inline/rtems/posix/intr.inl.
+ posix/macros/rtems/posix/intr.inl, posix/src/intr.c:
+ Remove (Unused, dead).
+ * posix/Makefile.am: Reflect changes above. Rework.
+
+2006-01-18 Ralf Corsépius <ralf.corsepius@rtems.org>
+
+ * posix/Makefile.am: Build devctl.
+
+2006-01-16 Ralf Corsépius <ralf.corsepius@rtems.org>
+
+ * rtems/Makefile.am: Rework.
+ * score/Makefile.am: Rework.
+
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ Large patch to improve Doxygen output. As a side-effect, grammar and
+ spelling errors were corrected, spacing errors were address, and some
+ variable names were improved.
+ * libmisc/monitor/mon-object.c, libmisc/monitor/monitor.h:
+ Account for changing OBJECTS_NO_CLASS to OBJECTS_CLASSIC_NO_CLASS.
+ * score/Doxyfile: Set output directory. Predefine some macro values.
+ Turn on graphical output.
+ * score/include/rtems/debug.h, score/include/rtems/seterr.h,
+ score/include/rtems/system.h, score/include/rtems/score/address.h,
+ score/include/rtems/score/apiext.h,
+ score/include/rtems/score/apimutex.h,
+ score/include/rtems/score/bitfield.h,
+ score/include/rtems/score/chain.h,
+ score/include/rtems/score/context.h,
+ score/include/rtems/score/coremsg.h,
+ score/include/rtems/score/coremutex.h,
+ score/include/rtems/score/coresem.h,
+ score/include/rtems/score/heap.h, score/include/rtems/score/interr.h,
+ score/include/rtems/score/isr.h, score/include/rtems/score/mpci.h,
+ score/include/rtems/score/mppkt.h,
+ score/include/rtems/score/object.h,
+ score/include/rtems/score/objectmp.h,
+ score/include/rtems/score/priority.h,
+ score/include/rtems/score/stack.h,
+ score/include/rtems/score/states.h,
+ score/include/rtems/score/sysstate.h,
+ score/include/rtems/score/thread.h,
+ score/include/rtems/score/threadmp.h,
+ score/include/rtems/score/threadq.h, score/include/rtems/score/tod.h,
+ score/include/rtems/score/tqdata.h,
+ score/include/rtems/score/userext.h,
+ score/include/rtems/score/watchdog.h,
+ score/include/rtems/score/wkspace.h,
+ score/inline/rtems/score/address.inl,
+ score/inline/rtems/score/chain.inl,
+ score/inline/rtems/score/coremutex.inl,
+ score/inline/rtems/score/coresem.inl,
+ score/inline/rtems/score/heap.inl,
+ score/inline/rtems/score/object.inl,
+ score/inline/rtems/score/stack.inl,
+ score/inline/rtems/score/thread.inl,
+ score/inline/rtems/score/tqdata.inl, score/macros/README,
+ score/src/heap.c, score/src/threadmp.c, score/src/threadready.c,
+ score/src/threadstartmultitasking.c: Improve generated Doxygen
+ output. Fix spelling and grammar errors in comments. Correct names of
+ some variables and propagate changes.
+
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ Large patch to improve Doxygen output. As a side-effect, grammar and
+ spelling errors were corrected, spacing errors were address, and some
+ variable names were improved.
+ * libmisc/monitor/mon-object.c, libmisc/monitor/monitor.h:
+ Account for changing OBJECTS_NO_CLASS to OBJECTS_CLASSIC_NO_CLASS.
+ * score/Doxyfile: Set output directory. Predefine some macro values.
+ Turn on graphical output.
+ * score/cpu/arm/rtems/score/cpu.h,
+ score/cpu/avr/rtems/score/cpu.h, score/cpu/c4x/rtems/score/cpu.h,
+ score/cpu/h8300/rtems/score/cpu.h, score/cpu/m68k/rtems/score/cpu.h,
+ score/cpu/mips/rtems/score/cpu.h, score/cpu/no_cpu/rtems/asm.h,
+ score/cpu/no_cpu/rtems/score/cpu.h,
+ score/cpu/no_cpu/rtems/score/types.h,
+ score/cpu/powerpc/rtems/new-exceptions/cpu.h,
+ score/cpu/powerpc/rtems/old-exceptions/cpu.h,
+ score/cpu/powerpc/rtems/score/cpu.h, score/cpu/sh/rtems/score/cpu.h,
+ score/cpu/sparc/rtems/score/cpu.h, score/cpu/unix/rtems/score/cpu.h,
+ score/include/rtems/debug.h, score/include/rtems/seterr.h,
+ score/include/rtems/system.h, score/include/rtems/score/address.h,
+ score/include/rtems/score/apiext.h,
+ score/include/rtems/score/apimutex.h,
+ score/include/rtems/score/bitfield.h,
+ score/include/rtems/score/chain.h,
+ score/include/rtems/score/context.h,
+ score/include/rtems/score/coremsg.h,
+ score/include/rtems/score/coremutex.h,
+ score/include/rtems/score/coresem.h,
+ score/include/rtems/score/heap.h, score/include/rtems/score/interr.h,
+ score/include/rtems/score/isr.h, score/include/rtems/score/mpci.h,
+ score/include/rtems/score/mppkt.h,
+ score/include/rtems/score/object.h,
+ score/include/rtems/score/objectmp.h,
+ score/include/rtems/score/priority.h,
+ score/include/rtems/score/stack.h,
+ score/include/rtems/score/states.h,
+ score/include/rtems/score/sysstate.h,
+ score/include/rtems/score/thread.h,
+ score/include/rtems/score/threadmp.h,
+ score/include/rtems/score/threadq.h, score/include/rtems/score/tod.h,
+ score/include/rtems/score/tqdata.h,
+ score/include/rtems/score/userext.h,
+ score/include/rtems/score/watchdog.h,
+ score/include/rtems/score/wkspace.h,
+ score/inline/rtems/score/address.inl,
+ score/inline/rtems/score/chain.inl,
+ score/inline/rtems/score/coremutex.inl,
+ score/inline/rtems/score/coresem.inl,
+ score/inline/rtems/score/heap.inl,
+ score/inline/rtems/score/object.inl,
+ score/inline/rtems/score/stack.inl,
+ score/inline/rtems/score/thread.inl,
+ score/inline/rtems/score/tqdata.inl, score/macros/README,
+ score/src/heap.c, score/src/threadmp.c, score/src/threadready.c,
+ score/src/threadstartmultitasking.c: Improve generated Doxygen
+ output. Fix spelling and grammar errors in comments. Correct names of
+ some variables and propagate changes.
+
+2006-01-15 Eric Norum <norume@aps.anl.gov>
+
+ * posix/inline/rtems/posix/cond.inl, posix/inline/rtems/posix/mutex.inl,
+ posix/macros/rtems/posix/cond.inl, posix/macros/rtems/posix/mutex.inl:
+ Keep compiler happy by making some casts explicit.
+
+2006-01-13 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove doxygen support having accidentially slipped
+ into, though yesterday's patch.
+
+2006-01-12 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am, ftpd/Makefile.am, httpd/Makefile.am,
+ itron/Makefile.am, libblock/Makefile.am, libcsupport/Makefile.am,
+ libfs/Makefile.am, libmisc/Makefile.am, libnetworking/Makefile.am,
+ librpc/Makefile.am, posix/Makefile.am, pppd/Makefile.am,
+ rtems/Makefile.am, sapi/Makefile.am, score/Makefile.am,
+ score/cpu/arm/Makefile.am, score/cpu/avr/Makefile.am,
+ score/cpu/c4x/Makefile.am, score/cpu/h8300/Makefile.am,
+ score/cpu/i386/Makefile.am, score/cpu/m68k/Makefile.am,
+ score/cpu/mips/Makefile.am, score/cpu/no_cpu/Makefile.am,
+ score/cpu/powerpc/Makefile.am, score/cpu/sh/Makefile.am,
+ score/cpu/sparc/Makefile.am, score/cpu/unix/Makefile.am,
+ telnetd/Makefile.am, zlib/Makefile.am: Remove all-local:.
+
+2006-01-10 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/src/error.c: include and use inttypes.h.
+
+2006-01-08 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/rtems/rtems_mii_ioctl.h: Fix formatting.
+
+2006-01-08 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/src/unixlibc.c, libfs/src/imfs/ioman.c: Change
+ rtems_io_register_name to take a const char *.
+
+2006-01-08 Joel Sherrill <joel@OARcorp.com>
+
+ * sapi/include/rtems/io.h, sapi/src/io.c: Change rtems_io_register_name
+ to take a const char *.
+
+2005-12-09 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 849/networking
+ * librpc/src/rpc/rtems_portmapper.c: Increased stack size
+ by ARGSIZE to prevent overrun.
+
+2005-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * configure.ac: New header guard for cpuopts.h.
+
+2005-11-13 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/Makefile.am: Re-add rtems/rtems_mii_ioctl.h,
+ rtems/rtems_mii_ioctl.c, rtems/rtems_mii_ioctl_kern.c.
+ Add dev/mii/mii.h, net/if_media.h (Moved from c/src/libchip).
+ * libnetworking/net/if_media.h, libnetworking/dev/mii/mii.h:
+ New (Moved from c/src/libchip).
+ * libnetworking/rtems/rtems_mii_ioctl.h: Reflect mii.h and
+ if_media.h having moved.
+
+2005-11-13 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * automake/local.am: Remove depend.
+
+2005-11-10 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * include/rtems/stdint.h: Disable RTEMS proprietary fixed-size types.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * configure.ac: Add RTEMS_NETWORKING to cpuopts.h.
+ Add RTEMS_DEPRECATED_TYPES to config.h.
+ Add AC_CONFIG_COMMANDS(preinstall-stamp) magic.
+ Misc. cleanups.
+
+2005-11-08 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/net/if.h: Add forward reference declaration to
+ struct mbuf so ifru_tap callback is properly typed.
+ * libnetworking/rtems/rtems_bsdnet.h: Add definition of _BSD_VISIBLE
+ which needs to be defined so various pieces of the .h files are
+ visible to device drives.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/Makefile.am: Comment out using
+ rtems/rtems_mii_ioctl.h, rtems/rtems_mii_ioctl.c,
+ rtems/rtems_mii_ioctl_kern.c.
+
+2005-11-07 Michael Siers <mikes@poliac.com>
+
+ * pppd/rtemspppd.c, pppd/rtemspppd.h: Per confirmation from Michael add
+ missing copyright notice.
+
+2005-11-06 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libi2c/libi2c.c: Include config.h.
+ * libi2c/libi2c.c, libi2c/libi2c.h,
+ libnetworking/rtems/rtems_mii_ioctl.h,
+ libnetworking/rtems/rtems_mii_ioctl_kern.c,
+ score/src/heap.c: Eliminate obsolete types.
+
+2005-11-03 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * httpd/Makefile.am: Remove bogus noinst_LIBRARIES.
+
+2005-11-02 Till Straumann <strauman@slac.stanford.edu>
+
+ * libnetworking/Makefile.am,
+ libnetworking/preinstall.am: Added simple implementation of ethernet
+ media ioctl SIOCSIFMEDIA/SIOCGIFMEDIA for mii compliant phys.
+ * libnetworking/rtems/rtems_mii_ioctl.c,
+ libnetworking/rtems/rtems_mii_ioctl.h,
+ libnetworking/rtems/rtems_mii_ioctl_kern.c: New files.
+
+2005-11-02 Till Straumann <strauman@slac.stanford.edu>
+
+ * libi2c/Makefile.am, libi2c/Makefile.in, libi2c/libi2c.c,
+ libi2c/libi2c.h: New files.
+ * Makefile.am, configure.ac, preinstall.am, wrapup/Makefile.am: added a
+ simple API/library for i2c devices and drivers for i2c 2-byte eeproms
+ and a ds1621 temperature sensor; API is documented in libi2c.h
+
+2005-11-02 Fredic Praca <freebsd-fr.org>
+
+ PR 842/networking
+ * libnetworking/libc/gethostbydns.c: Avoid use of dprintf(). Rename
+ dprintf to debugprintf().
+
+2005-11-02 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/zlib.c: Remove.
+ * libnetworking/net/zlib.h: Remove.
+ * libnetworking/Makefile.am: Reflect changes above.
+
+2005-11-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * pppd/Makefile.am: Fix typo.
+
+2005-10-31 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 840/rtems:
+ * include/rtems/irq.h: Fix several typos.
+
+2005-10-30 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * configure.ac: Add zlib.
+ * Makefile.am: Add zlib.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/zlib.h, libnetworking/net/zlib.c:
+ Update from FreeBSD.
+ * libnetworking/opt_ppp.h: New.
+ * libnetworking/net/ppp.h: Remove.
+ * libnetworking/net/if_ppp.c, libnetworking/net/ppp_tty.c:
+ Reflect changes above. Cosmetics from FreeBSD.
+ * libnetworking/Makefile.am: Don't install loop.h.
+ Add opt_ppp.h, remove net/ppp.h.
+ * include/rtems/concat.h: Add EXPAND0, CONCAT0.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * telnetd/Makefile.am: Only build if LIBSHELL is available.
+
+2005-10-26 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * pppd/Makefile.am, pppd/auth.c, pppd/chap.c, pppd/md5.c, pppd/md5.h,
+ pppd/pppd.h: Misc. minor fixes.
+
+2005-10-26 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * configure.ac: Add pppd.
+ * Makefile.am: Add pppd.
+
+2005-10-26 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * pppd/Makefile.am:
+ Install rtemsdialer.h, rtemspppd.h to $(includedir)/rtems.
+ * pppd/ipxcp.c, pppd/ipxcp.h: Remove (Unused).
+ * backward/rtemspppd.h, backward/rtemsdialer.h: New.
+ * Makefile.am: Add backward/rtemspppd.h, backward/rtemsdialer.h.
+
+2005-10-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * telnet/Makefile.am: Install libtelnetd.a.
+
+2005-10-25 Eric Norum <norume@aps.anl.gov>
+
+ * libnetworking/rtems/rtems_showifstat.c: Don't sign-extend address components.
+
+
+2005-10-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Add telnetd.
+ * configure.ac: Add telnetd.
+
+2005-10-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * telnetd/icmds.c: Rename register_icmds to
+ _rtems_telnet_register_icmds. Make main_* functions static.
+ * telnetd/pty.c: Make many functions static.
+ Rename rtems_telnetd_maximum_ptys to rtems_pty_maximum_ptys.
+ * telnetd/pty.h: Reflect changes above.
+ Rename get_pty to rtems_pty_get. New header guards.
+ * telnetd/telnetd.c: Reflect changes above.
+ * telnetd/telnetd.h: New header guards.
+
+2005-10-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * telnet/telnet.h, telnet/telnet.c: Rename
+ rtems_initialize_telnetd to rtems_telnetd_initialize,
+ main_telnetd to rtems_telnetd_main,
+ register_telnetd to rtems_telnetd_register.
+
+2005-10-25 Joel Sherrill <joel@OARcorp.com>
+
+ * sapi/include/confdefs.h, telnetd/pty.c, telnetd/pty.h: Attempt
+ to fix MAX_PTYS and provide a real configuration entry. This should
+ make telnetd some suitable for inclusion in cpukit.
+
+2005-10-17 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libfs/src/dosfs/msdos_misc.c: Revert to vers. 1.9.
+
+2005-10-06 Joel Sherrill <joel@OARcorp.com>
+
+ PR 828/filesystems
+ * libfs/src/dosfs/msdos_misc.c: Problem retracted. Revert patch.
+
+2005-10-04 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 829/rtems
+ * rtems/src/tasks.c, rtems/src/taskvariabledelete.c: If task variables
+ are deleted from a different context (i.e., executing context !=
+ owner of the task variable. The owner meaning the task that
+ registered the dtor in question) the argument passed to the task
+ variable dtor must be tvar and not *ptr which yields the executing
+ task's value of the task variable instead of the owner's.
+
+2005-09-29 Eric Norum <norume@aps.anl.gov>
+
+ PR 835/rtems_misc
+ * libmisc/cpuuse/cpuuse.c: Remove floating point calculations and the
+ C preprocessor conditions which enabled them.
+
+2005-09-25 Joel Sherrill <joel@OARcorp.com>
+
+ * sapi/include/rtems/init.h, sapi/src/exinit.c: Remove unused and
+ obsolete rtems_initialize_executive.
+
+2005-09-19 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/sys/mount.h: Cosmetical update from FreeBSD.
+ Remove non-implemented interfaces (vfs, nfs, fsstat, etc.).
+ * configure.ac: Check for sys/errno.h.
+
+2005-09-16 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/Makefile.am: Cosmetics.
+ * libnetworking/nfs/rpcv2.h: Update from FreeBSD.
+ * libnetworking/nfs/bootp_subr.c: Remove superfluous includes.
+ * libnetworking/nfs/xdr_subs.h: Partial update from FreeBSD.
+ * libnetworking/netinet/in.h: Partial update from FreeBSD.
+ * libnetworking/nfs/nfsproto.h: Partial update from FreeBSD.
+
+2005-09-02 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-4.6.99.2.
+
+2005-09-01 Joel Sherrill <joel@OARcorp.com>
+
+ PR 820/rtems
+ * score/inline/rtems/score/coremsg.inl,
+ score/macros/rtems/score/coremsg.inl, score/src/coremsginsert.c:
+ Increment of pending message count should be atomic with insertion on
+ the pending message chain. Determination of the need to call the
+ notification handler should also be in this atomic section of code.
+
+2005-09-01 Joel Sherrill <joel@OARcorp.com>
+
+ PR 796/rtems
+ * posix/src/semtimedwait.c: sem_timedwait is supposed to use absolute
+ time for timeout specification. This patch is a modified version of
+ the one suggested by Peter Dufault.
+
+2005-09-01 Nuno Costa <nuno-costa@iol.pt>
+
+ PR 804
+ * sapi/include/confdefs.h: Memory for POSIX timers not accounted for.
+ Patch adapted from edit comment in PR filed.
+
+2005-08-31 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 819/filesystem
+ * libcsupport/src/ttyname_r.c: Remove.
+ * libcsupport/src/ttyname.c: Partial update from FreeBSD.
+ * libcsupport/Makefile.am: Reflect changes above.
+
+2005-08-18 Andrew Sinclair <Andrew.Sinclair@elprotech.com>
+
+ PR 807/rtems
+ * rtems/src/timerfireafter.c, rtems/src/timerserverfireafter.c: First
+ patch returned without exitting dispatching critical section.
+
+2005-08-17 Nuno Costa <nuno-costa@iol.pt>
+
+ PR 805/rtems
+ * posix/include/rtems/posix/timer.h: Due to bad choice of error
+ constants by original submitter, it was impossible to create more
+ than 10 POSIX timers.
+
+2005-08-17 Andrew Sinclair <Andrew.Sinclair@elprotech.com>
+
+ PR 807/rtems
+ * rtems/src/timerfireafter.c, rtems/src/timerserverfireafter.c,
+ score/src/watchdoginsert.c: Tighten critical section checks on an ISR
+ using the same timer being inserted by a lower priority ISR or
+ interupt task.
+
+2005-08-17 Nickolay Semyonov <snob@oktetlabs.ru>
+
+ PR 744/filesystem
+ * libcsupport/src/unlink.c, libfs/src/dosfs/msdos_eval.c: DOSFS did not
+ support permissions on directories so the check performed by unlink
+ would always fail. The unlink code was modified to support a not
+ supported status being returned.
+
+2005-08-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * posix/include/mqueue.h, posix/src/mqueuetimedreceive.c:
+ ssize_t mq_timedreceive() (POSIX compliance).
+ * wrapup/Makefile.am: Use librtemscpu_a_LIBRARIES.
+
+2005-08-12 Chris Johns <chrisj@rtems.org>
+
+ PR 808/rtems_misc
+ * libcsupport/src/printk.c: Fix bug where specifying field width
+ crashed on pc386 BSP.
+
+2005-08-06 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/nfs/bootp_subr.c: Don't include
+ nfs/nfs.h, nfs/krpc.h.
+
+2005-08-05 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libfs/src/dosfs/msdos.h, libfs/src/dosfs/msdos_create.c,
+ libfs/src/dosfs/msdos_eval.c, libfs/src/dosfs/msdos_file.c,
+ libfs/src/dosfs/msdos_free.c, libfs/src/dosfs/msdos_fsunmount.c,
+ libfs/src/dosfs/msdos_init.c, libfs/src/dosfs/msdos_misc.c,
+ libfs/src/dosfs/msdos_mknod.c:
+ Introduce msdos_status_t (dosfs statii are at least 32bit, not int).
+
+2005-08-05 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Add libnetworking/memory.h
+ * libnetworking/Makefile.am: Remove memory.h
+
+2005-08-02 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 817/rtems
+ * libcsupport/src/gxx_wrappers.c: Rename
+ rtems_gxx_recursive_mutex_init_function to
+ rtems_gxx_recursive_mutex_init.
+
+2005-08-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/sys/syslog.h: Partial update from FreeBSD.
+
+2005-07-08 Eric Norum <norume@aps.anl.gov>
+
+ * libcsupport/src/open.c: Pass along errno from failed ftruncate().
+
+2005-07-06 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/lib/syslog.c: Fix spelling mistake.
+ * libnetworking/sys/uio.h: Partial update from FreeBSD.
+ * libnetworking/kern/kern_subr.c: Reflect changes above.
+
+2005-07-05 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 810/rtems
+ * libblock/include/rtems/ide_part_table.h: Add C++ guards.
+
+2005-06-17 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/net/if.h: Avoid use of struct mbuf to avoid unintended
+ dependencies added by the RTEMS specific tap interface.
+
+2005-06-09 Jacques Seronie Vivien <jacques.seronievivien@astrium.eads.net>
+
+ PR 790/rtems
+ * sapi/src/extensioncreate.c, sapi/src/extensionident.c: Correct use of
+ name. This was missed when the other ident services in rtems/src
+ where changed.
+
+2005-05-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/if.h: Partial update from FreeBSD.
+ * libnetworking/netinet/if_ether.h: Remove BYTE_PACK.
+ * libnetworking/netinet/ip_var.h: Remove BYTE_PACK.
+ * libnetworking/netinet/ip_divert.c: Fix broken comment.
+
+2005-05-26 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/lib/ftpfs.c, librpc/include/rpc/svc.h,
+ librpc/src/rpc/get_myaddress.c, librpc/src/rpc/pmap_getmaps.c,
+ librpc/src/rpc/pmap_getport.c: Remove warnings.
+
+2005-05-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/clnt.h, librpc/include/rpc/svc.h,
+ src/rpc/pmap_rmt.c: Use void* instead of caddr_t.
+ Cosmetics from FreeBSD.
+
+2005-05-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/auth_des.h: Remove (Unused, unsupported).
+ * librpc/include/rpc/rpc.h, librpc/Makefile.am: Reflect removing
+ auth_des.h.
+
+2005-05-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+ * librpc/include/rpc/rpc_com.h, librpc/include/rpc/rpc_msg.h,
+ librpc/src/rpc/svc_simple.c: Minor fixes.
+ * include/rpc/clnt.h, include/rpc/svc.h,
+ librpc/include/rpc/clnt.h, librpc/include/rpc/clnt_soc.h,
+ src/rpc/clnt_perror.c: More updates from FreeBSD.
+
+2005-05-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/svc.h: Partial update from FreeBSD.
+ * librpc/include/rpc/clnt.h: Partial update from FreeBSD.
+
+2005-05-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/clnt_soc.h, librpc/include/rpc/svc_soc.h:
+ New (Partial update from FreeBSD).
+ * librpc/Makefile.am: Reflect changes above.
+
+2005-05-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/des_crypt.h: Remove (Unused, unsupported).
+ * librpc/Makefile.am: Reflect changes above.
+
+2005-05-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/des.h: Remove (Unused, unsupported).
+ * librpc/Makefile.am: Reflect changes above.
+
+2005-05-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/src/rpc/auth_des.c,
+ librpc/src/rpc/auth_time.c,
+ librpc/src/rpc/authdes_prot.c,
+ librpc/src/rpc/clnt_unix.c,
+ librpc/src/rpc/crypt_client.c,
+ librpc/src/rpc/des_crypt.c,
+ librpc/src/rpc/des_soft.c,
+ librpc/src/rpc/getpublickey.c,
+ librpc/src/rpc/key_call.c,
+ librpc/src/rpc/key_prot_xdr.c,
+ librpc/src/rpc/svc_auth_des.c,
+ librpc/src/rpc/svc_unix.c: Remove (Unused, obsolete).
+ * librpc/Makefile.am: Reflect changes above.
+
+2005-05-25 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/src/rpc/PSD.doc/rpc.prog.ms,
+ librpc/src/rpc/PSD.doc/rpcgen.ms,
+ librpc/src/rpc/PSD.doc/nfs.rfc.ms,
+ librpc/src/rpc/PSD.doc/xdr.rfc.ms,
+ librpc/src/rpc/PSD.doc/rpc.rfc.ms,
+ librpc/src/rpc/PSD.doc/xdr.nts.ms:
+ Remove (Unused, obsolete).
+ * librpc/Makefile.am: Reflect changes above.
+
+2005-05-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/arpa/telnet.h: Remove (Unused, Non-POSIX/SUSV3).
+ * libnetworking/Makefile.am: Reflect removing arpa/telnet.h.
+
+2005-05-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/arpa/nameser.h: Update from FreeBSD.
+ * libnetworking/libc/ns_parse.c: Reflect changes above.
+ * libnetworking/netinet/ip.h: Remove BYTE_PACK.
+ Add __packed. Partial update from FreeBSD.
+ * libnetworking/netinet/ip_divert.c: Cosmetics from FreeBSD.
+
+2005-05-23 Eric Norum <norume@aps.anl.gov>
+
+ * libnetworking/rtems/rtems_showicmpstat.c
+ * libnetworking/netinet/ip_icmp.c: note that a panic has been avoided
+
+2005-05-23 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR rtems_misc/795
+ * Makefile.am: Remove ada.
+ * configure.ac: Remove ada.
+
+2005-05-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/netinet/ip_icmp.c: Partial update from FreeBSD.
+ * libnetworking/sys/mbuf.h: Partial update from FreeBSD.
+ * libnetworking/netinet/ip_icmp.h: Update from FreeBSD.
+ Abandon BYTE_PACK.
+ * libnetworking/netdb.h: Update from FreeBSD.
+
+2005-05-20 Sergei Organov <osv@javad.ru>
+
+ PR networking/772.
+ * libnetworking/rtems/rtems_select.c (socket_select): fixed bug
+ setting SB_WAIT flag of so_rcv instead of so_snd when FWRITE.
+
+2005-05-20 Sergei Organov <osv@topconrd.ru>
+
+ PR 749/networking
+ * libnetworking/rtems/rtems_showroute.c: Avoid NULL dereference.
+
+2005-05-14 Sergei Organov <osv@topconrd.ru>
+
+ PR 746/rtems
+ Optimize realloc(). The problem is that realloc() can neither grow
+ nor shrink efficiently the current memory region without support
+ from underlying heap/region modules. The patch introduces one new
+ routine for each of heap and region modules, _Heap_Resize_block(),
+ and rtems_region_resize_segment(), respectively, and uses the
+ latter to optimize realloc().
+
+ The implementation of _Heap_Resize_block() lead to changing of the
+ heap allocation strategy: now the heap manager, when splits larger
+ free block into used and new free parts, makes the first part of
+ the block used, not the last one as it was before. Due to this new
+ strategy, _Heap_Resize_block() never needs to change the user
+ pointer.
+
+ Caveat: unlike previous heap implementation, first few bytes of
+ the contents of the memory allocated from the heap are now almost
+ never all zero. This can trigger bugs in client code that have not
+ been visible before this patch.
+
+ * libcsupport/src/malloc.c (realloc): try to resize segment in
+ place using new rtems_region_resize_segment() routine before
+ falling back to the malloc()/free() method.
+ * score/src/heap.c:
+ (_Heap_Initialize): change initial heap layout to reflect new
+ allocation strategy of using of the lower part of a previously
+ free block when splitting it for the purpose of allocation.
+ (_Heap_Block_allocate): when split, make the lower part used, and
+ leave the upper part free. Return type changed from Heap_Block* to
+ uint32_t.
+ * score/include/rtems/score/heap.h:
+ (Heap_Statistics): added 'resizes' field.
+ (Heap_Resize_status): new enum.
+ (_Heap_Resize_block): new routine.
+ (_Heap_Block_allocate): return type changed from Heap_Block* to
+ uint32_t.
+ * score/src/heapwalk.c: reflect new heap layout in checks.
+ * score/src/heapsizeofuserarea.c: more assertions added.
+ * score/src/heapresizeblock.c: new file.
+ (_Heap_Resize_block): new routine.
+ * score/src/heapfree.c: reverse the checks _Heap_Is_block_in() and
+ _Heap_Is_prev_used() on entry to be in this order.
+ * score/src/heapallocate.c, score/src/heapallocatealigned.c:
+ ignore return value of _Heap_Block_allocate().
+ * score/Makefile.am (HEAP_C_FILES): added src/heapresizeblock.c.
+ * rtems/include/rtems/rtems/region.h:
+ (rtems_region_resize_segment): new interface routine.
+ (_Region_Process_queue): new internal routine called from
+ rtems_region_resize_segment() and rtems_region_return_segment().
+ * rtems/src/regionreturnsegment.c: move queue management code into
+ the new internal routine _Region_Process_queue() and call it.
+
+ * rtems/src/regionresizesegment.c: new file.
+ (rtems_region_resize_segment): new interface routine.
+ * rtems/src/regionprocessqueue.c: new file.
+ (_Region_Process_queue): new internal routine containing queue
+ management code factored out from 'regionreturnsegment.c'.
+ * rtems/Makefile.am (REGION_C_FILES): Added
+ src/regionresizesegment.c, and src/regionprocessqueue.c.
+ * ada/rtems.adb, ada/rtems.ads: Added Region_Resize_Segment.
+
+2005-05-20 Eric Norum <norume@aps.anl.gov>
+
+ PR 793/networking
+ * libnetworking/netinet/ip_icmp.c: Malicious ICMP packet causes panic.
+ Just ignore it.
+
+2005-05-18 Chris Johns <chrisj@rtems.org>
+
+ * libmisc/capture/capture-cli.c: Fix the output of ctload when
+ there exists a large number of tasks.
+
+2005-05-17 Jennifer Averett <jennifer.averett@oarcorp.com>
+
+ * Makefile.am, preinstall.am: Added a common irq.h
+ * include/rtems/irq.h: New file.
+
+2005-05-14 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/netinet/tcp_usrreq.c: Cosmetics from FreeBSD.
+ * libnetworking/netinet/tcp_subr.c: Partical update from FreeBSD.
+
+2005-05-12 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * configure.ac: Let --enable-deprecated default to "no".
+ * libnetworking/net/if_arp.h: Remove BYTE_PACK.
+ * libnetworking/net/if_llc.h: Update from FreeBSD, add __packed.
+ * libnetworking/net/route.h: Partial update from FreeBSD.
+ * libnetworking/netinet/if_ether.c: Partial update from FreeBSD.
+ * libnetworking/netinet/tcp_var.h: Partial update from FreeBSD.
+ * libnetworking/netinet/tcp_input.c: Reflect changes to tcp_var.h.
+ * libnetworking/netinet/tcp.h: Partial update from FreeBSD.
+ Remove BYTE_PACK.
+ * libnetworking/netinet/ip_var.h: Partial update from FreeBSD.
+ Remove some useless BYTE_PACKs.
+
+2005-05-12 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 784/networking
+ * libnetworking/net/if_arp.h, libnetworking/netinet/if_ether.h,
+ libnetworking/netinet/ip_icmp.h, libnetworking/netinet/ip_var.h,
+ libnetworking/netinet/tcp.h: Define BYTE_PACK.
+
+2005-05-11 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/rtsock.c: Abandon AF_NS.
+ * libnetworking/sys/socket.h: Abandon AF_NS, PF_NS.
+
+2005-05-10 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * httpd/socket.c: socklen_t.
+ * librpc/include/rpc/svc.h: Cosmetical update from FreeBSD.
+ * librpc/src/rpc/clnt_tcp.c, librpc/src/rpc/clnt_udp.c,
+ librpc/src/rpc/pmap_rmt.c, librpc/src/rpc/rtime.c,
+ librpc/src/rpc/svc_tcp.c, librpc/src/rpc/svc_udp.c: socklen_t.
+ * ftpd/ftpd.c: socklen_t.
+ * libnetworking/lib/rtems_bsdnet_ntp.c: socklen_t.
+ * libnetworking/libc/rcmd.c: socklen_t.
+ * libnetworking/libc/res_send.c: socklen_t.
+
+2005-05-10 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/if.h: Remove IFI_* (obsolete, unused).
+ * libnetworking/net/if_var.h: Remove if_ipending (obsolete, unused).
+
+2005-05-09 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/sys/un.h: Partial update from FreeBSD.
+ Remove non-implemented functions/variables.
+
+2005-05-09 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/rtems/bsdnet/_types.h: New.
+ * Makefile.am: Add rtems_bsdnet_HEADERS.
+ * libnetworking/Makefile.am: Remove rtems_bsdnet_HEADERS.
+ * preinstall.am, libnetworking/preinstall.am: Regenerate.
+ * libcsupport/include/sys/cdefs.h: Partial update from FreeBSD.
+ * libnetworking/arpa/inet.h: Partial update from FreeBSD.
+ * libnetworking/netinet/in.h: Partial update from FreeBSD.
+ * libnetworking/sys/socket.h: Partial update from FreeBSD.
+ * librpc/src/rpc/bindresvport.c: socklen_t.
+ * libnetworking/sys/mbuf.h: Ansification.
+ * libnetworking/kern/uipc_mbuf.c: Partial update from FreeBSD.
+ * libnetworking/libc/inet_addr.c: in_addr_t.
+ * libnetworking/lib/tftpDriver.c: socklen_t.
+ * libnetworking/libc/inet_lnaof.c: in_addr_t.
+ * libnetworking/libc/inet_makeaddr.c: in_addr_t.
+ * libnetworking/libc/inet_netof.c: in_addr_t.
+ * libnetworking/libc/inet_network.c: in_addr_t.
+ * libnetworking/libc/inet_ntop.c: Ansify, socklen_t.
+ * libnetworking/lib/ftpfs.c: socklen_t, PRIu32.
+
+2005-05-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/arpa/inet.h: Add in_addr_t, in_port_t.
+ * libnetworking/netinet/in.h: Sync in_port_t with arpa/inet.h.
+ * libnetworking/sys/socket.h: Include <sys/types.h>.
+ Remove in_port_t. Misc. updates from FreeBSD.
+
+2005-05-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/netinet/in.h: Partial update from FreeBSD.
+ Remove BYTE_PACK.
+ * libnetworking/netinet/ip.h: Add BYTE_PACK.
+ * libnetworking/sys/socket.h: Partial update from FreeBSD.
+
+2005-05-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/netinet/if_ether.c: Cosmetics from FreeBSD.
+ * libnetworking/libc/inet_addr.c: Cosmetics from FreeBSD.
+ * libnetworking/netinet/in.h: Cosmetics from FreeBSD.
+ * libnetworking/sys/socket.h: Cosmetics from FreeBSD.
+
+2005-05-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/sys/un.h: Cosmetical updates from FreeBSD.
+ * libnetworking/net/if_var.h: More partial updates from FreeBSD.
+ * libnetworking/rtems/rtems_bsdnet.h: Eliminate rtems_* fixed size
+ types.
+
+2005-05-06 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/rtems/rtems_showifstat.c: Remove warning.
+ * libnetworking/net/if.h: Revert include of sys/mbuf.h in this .h file
+ since it causes other problems.
+
+2005-05-06 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/src/termios.c: Removed warnings.
+
+2005-05-06 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/net/if.h, libnetworking/net/if_ppp.c,
+ libnetworking/net/ppp_tty.c: Removed warnings.
+
+2005-05-06 Joel Sherrill <joel@OARcorp.com>
+
+ * libblock/src/blkdev.c, libfs/src/dosfs/fat_file.c,
+ libfs/src/dosfs/fat_file.h, libfs/src/dosfs/msdos.h,
+ libfs/src/dosfs/msdos_create.c, libfs/src/dosfs/msdos_dir.c,
+ libfs/src/dosfs/msdos_initsupp.c, libfs/src/dosfs/msdos_misc.c:
+ Removed warnings.
+
+2005-05-04 Jennifer Averett <jennifer.averett@oarcorp.com>
+
+ * include/rtems/pci.h: Name change to support common PCI interface
+
+2005-05-03 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/include/ringbuf.h: Use uint8_t instead of char for raw
+ data buffer.
+
+2005-05-03 Joel Sherrill <joel@OARcorp.com>
+
+ PR 775/core
+ * rtems/src/regiongetfreeinfo.c: Return RTEMS_SUCCESSFUL instead of
+ RTEMS_INVALID_ADDRESS on success path.
+
+2005-05-03 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/src/imfs/imfs.h, libfs/src/imfs/imfs_load_tar.c: Use uint8_t
+ instead of char for raw data buffer.
+
+2005-05-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/kern/kern_mib.c, libnetworking/sys/libkern.h:
+ Update from FreeBSD.
+
+2005-04-30 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * configure.ac: fix evaluating --enable-ada.
+
+2005-04-29 Jennifer Averett <jennifer.averett@oarcorp.com>
+
+ * score/src/objectidtoname.c: Removed warnings
+
+2005-04-28 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/kern/kern_sysctl.c, libnetworking/libc/inet_ntop.c,
+ libnetworking/net/if_ppp.c, libnetworking/net/pppcompress.c,
+ libnetworking/net/slcompress.c, libnetworking/netinet/ip_output.c,
+ libnetworking/netinet/udp_usrreq.c, libnetworking/nfs/bootp_subr.c,
+ libnetworking/rtems/rtems_select.c,
+ libnetworking/rtems/rtems_showifstat.c,
+ libnetworking/rtems/rtems_showroute.c,
+ libnetworking/rtems/rtems_syscall.c: Fixed type mismatch and
+ uninitialized variable warnings.
+
+2005-04-28 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/objectidtoname.c: Fixed spacing.
+
+2005-04-28 Jennifer Averett <jennifer.averett@oarcorp.com>
+
+ * score/src/objectidtoname.c: Add enable dispatch
+
+2005-04-28 Jennifer Averett <jennifer.averett@oarcorp.com>
+
+ * configure.ac: Remove or32-rtems
+
+2005-04-23 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * score/cpu/Makefile.am: Remove or32 (target abandoned).
+
+2005-04-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/if.h: Update from FreeBSD.
+ * libnetworking/net/if_loop.c: Reflect updates.
+ * libnetworking/net/if_ppp.c: Reflect updates.
+ * libnetworking/net/if_types.h: Update from FreeBSD.
+ * libnetworking/net/ethernet.h: Add RTEMS outdated either_input.
+ * libnetworking/net/if.c: Partial update from FreeBSD.
+ * libnetworking/net/if_ethersubr.c: Partial update from FreeBSD.
+ * libnetworking/net/if_var.h: New (extracted from net/if.h).
+ * libnetworking/Makefile.am: Add net/if_var.h.
+
+2005-04-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/if.c, libnetworking/net/if.h,
+ libnetworking/sys/mbuf.h: Cosmetics from FreeBSD.
+
+2005-04-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/sys/mount.h: More updates from FreeBSD.
+ Remove ufs, mfs, dosfs, isofs.
+ * libnetworking/nfsclient/nfsargs.h: More updates from FreeBSD.
+
+2005-04-17 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/rtsock.c: More updates from FreeBSD.
+
+2005-04-17 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/sys/mount.h: Remove nfs_args.
+ * libnetworking/nfsclient/nfsargs.h: New (extracted from
+ sys/mount.h).
+ * libnetworking/nfsclient/nfsdiskless.h: New (Relocated from nfs/).
+ * libnetworking/nfs/nfsdiskless.h: Remove.
+ * libnetworking/net/netisr.h: Partial update from FreeBSD.
+ * libnetworking/net/rtsock.c: Cosmetical update from FreeBSD.
+ * libnetworking/sys/socket.h: Cosmetical update from FreeBSD.
+ * libnetworking/sys/queue.h: Cosmetical update from FreeBSD.
+ Remove special casing of arm/mips.
+ * libnetworking/nfs/bootp_subr.c: Reflect having introduced nfsclient/.
+ * libnetworking/Makefile.am: Remove changes above.
+
+2005-04-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/if_arp.h, libnetworking/netinet/ip.h,
+ libnetworking/netinet/ip_icmp.c: Partial updates from FreeBSD.
+
+2005-04-14 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/if_arp.h, libnetworking/net/if_ethersubr.c,
+ libnetworking/netinet/if_ether.h,
+ libnetworking/netinet/in.h: Partial updates from FreeBSD.
+
+2005-04-14 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/arpa/inet.h, libnetworking/net/if_dl.h:
+ Cosmetical update from FreeBSD.
+
+2005-04-09 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libmisc/monitor/mon-symbols.c: size_t.
+
+2005-03-14 Joel Sherrill <joel@OARcorp.com>
+
+ * include/rtems/pci.h: Continue PCI API unification. All use
+ pci_find_device().
+
+2005-03-14 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
+
+ * libnetworking/netinet/in_cksum_m68k.h: Change back to lcsum[12]_lbl
+ to temporary labels.
+
+2005-03-10 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/netinet/in_cksum_m68k.h: Change back to lcsum[12]_lbl
+ since my fix did not fix all issues.
+
+2005-03-05 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/netinet/in_cksum_m68k.h: Change lcsum[12]_lbl to
+ temporary inline assembly labels to remove compilation error.
+
+2005-03-04 Joel Sherrill <joel@OARcorp.com>
+
+ * include/rtems/pci.h: Clean up and reformatting. Make PCI initialize
+ function part of the unified PCI API.
+
+2005-03-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * configure.ac: Check for newlib with stdint.h/inttypes.h.
+ * Makefile.am: Conditionally use external stdint.h/inttypes.h for
+ newlib.
+
+2005-02-22 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * aclocal/rtems-top.m4: Rework rtems_updir handling to work around
+ ash cd'ing to '/' for 'cd .//'.
+
+2005-02-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 764/networking
+ * libnetworking/sys/sysctl.h: include <rtems/stdint.h>.
+
+2005-02-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * score/inline/rtems/score/address.inl,
+ score/inline/rtems/score/chain.inl,
+ score/inline/rtems/score/coremsg.inl,
+ score/inline/rtems/score/coremutex.inl,
+ score/inline/rtems/score/coresem.inl,
+ score/inline/rtems/score/heap.inl,
+ score/inline/rtems/score/isr.inl,
+ score/inline/rtems/score/mppkt.inl,
+ score/inline/rtems/score/object.inl,
+ score/inline/rtems/score/objectmp.inl,
+ score/inline/rtems/score/priority.inl,
+ score/inline/rtems/score/stack.inl,
+ score/inline/rtems/score/states.inl,
+ score/inline/rtems/score/sysstate.inl,
+ score/inline/rtems/score/thread.inl,
+ score/inline/rtems/score/threadmp.inl,
+ score/inline/rtems/score/tod.inl,
+ score/inline/rtems/score/tqdata.inl,
+ score/inline/rtems/score/userext.inl,
+ score/inline/rtems/score/watchdog.inl,
+ score/inline/rtems/score/wkspace.inl,
+ score/macros/rtems/score/address.inl,
+ score/macros/rtems/score/chain.inl,
+ score/macros/rtems/score/coremsg.inl,
+ score/macros/rtems/score/coremutex.inl,
+ score/macros/rtems/score/coresem.inl,
+ score/macros/rtems/score/heap.inl,
+ score/macros/rtems/score/isr.inl,
+ score/macros/rtems/score/mppkt.inl,
+ score/macros/rtems/score/object.inl,
+ score/macros/rtems/score/objectmp.inl,
+ score/macros/rtems/score/priority.inl,
+ score/macros/rtems/score/stack.inl,
+ score/macros/rtems/score/states.inl,
+ score/macros/rtems/score/sysstate.inl,
+ score/macros/rtems/score/thread.inl,
+ score/macros/rtems/score/threadmp.inl,
+ score/macros/rtems/score/tod.inl,
+ score/macros/rtems/score/tqdata.inl,
+ score/macros/rtems/score/userext.inl,
+ score/macros/rtems/score/watchdog.inl,
+ score/macros/rtems/score/wkspace.inl: New header guards.
+
+2005-02-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/inline/rtems/rtems/asr.inl,
+ rtems/inline/rtems/rtems/attr.inl,
+ rtems/inline/rtems/rtems/dpmem.inl,
+ rtems/inline/rtems/rtems/event.inl,
+ rtems/inline/rtems/rtems/eventset.inl,
+ rtems/inline/rtems/rtems/message.inl,
+ rtems/inline/rtems/rtems/modes.inl,
+ rtems/inline/rtems/rtems/options.inl,
+ rtems/inline/rtems/rtems/part.inl,
+ rtems/inline/rtems/rtems/ratemon.inl,
+ rtems/inline/rtems/rtems/region.inl,
+ rtems/inline/rtems/rtems/sem.inl,
+ rtems/inline/rtems/rtems/status.inl,
+ rtems/inline/rtems/rtems/support.inl,
+ rtems/inline/rtems/rtems/tasks.inl,
+ rtems/inline/rtems/rtems/timer.inl,
+ rtems/macros/rtems/rtems/asr.inl,
+ rtems/macros/rtems/rtems/attr.inl,
+ rtems/macros/rtems/rtems/dpmem.inl,
+ rtems/macros/rtems/rtems/event.inl,
+ rtems/macros/rtems/rtems/eventset.inl,
+ rtems/macros/rtems/rtems/message.inl,
+ rtems/macros/rtems/rtems/modes.inl,
+ rtems/macros/rtems/rtems/options.inl,
+ rtems/macros/rtems/rtems/part.inl,
+ rtems/macros/rtems/rtems/ratemon.inl,
+ rtems/macros/rtems/rtems/region.inl,
+ rtems/macros/rtems/rtems/sem.inl,
+ rtems/macros/rtems/rtems/status.inl,
+ rtems/macros/rtems/rtems/support.inl,
+ rtems/macros/rtems/rtems/tasks.inl,
+ rtems/macros/rtems/rtems/timer.inl: New header guards.
+
+2005-02-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * itron/inline/rtems/itron/eventflags.inl,
+ itron/inline/rtems/itron/fmempool.inl,
+ itron/inline/rtems/itron/intr.inl,
+ itron/inline/rtems/itron/mbox.inl,
+ itron/inline/rtems/itron/msgbuffer.inl,
+ itron/inline/rtems/itron/network.inl,
+ itron/inline/rtems/itron/port.inl,
+ itron/inline/rtems/itron/semaphore.inl,
+ itron/inline/rtems/itron/sysmgmt.inl,
+ itron/inline/rtems/itron/task.inl,
+ itron/inline/rtems/itron/time.inl,
+ itron/inline/rtems/itron/vmempool.inl,
+ itron/macros/rtems/itron/eventflags.inl,
+ itron/macros/rtems/itron/fmempool.inl,
+ itron/macros/rtems/itron/intr.inl,
+ itron/macros/rtems/itron/mbox.inl,
+ itron/macros/rtems/itron/msgbuffer.inl,
+ itron/macros/rtems/itron/network.inl,
+ itron/macros/rtems/itron/port.inl,
+ itron/macros/rtems/itron/semaphore.inl,
+ itron/macros/rtems/itron/sysmgmt.inl,
+ itron/macros/rtems/itron/task.inl,
+ itron/macros/rtems/itron/time.inl,
+ itron/macros/rtems/itron/vmempool.inl: New header guards.
+
+2005-02-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * posix/inline/rtems/posix/cond.inl,
+ posix/inline/rtems/posix/intr.inl,
+ posix/inline/rtems/posix/key.inl,
+ posix/inline/rtems/posix/mqueue.inl,
+ posix/inline/rtems/posix/mutex.inl,
+ posix/inline/rtems/posix/priority.inl,
+ posix/inline/rtems/posix/pthread.inl,
+ posix/inline/rtems/posix/semaphore.inl,
+ posix/inline/rtems/posix/timer.inl,
+ posix/macros/rtems/posix/cond.inl,
+ posix/macros/rtems/posix/intr.inl,
+ posix/macros/rtems/posix/key.inl,
+ posix/macros/rtems/posix/mqueue.inl,
+ posix/macros/rtems/posix/mutex.inl,
+ posix/macros/rtems/posix/priority.inl,
+ posix/macros/rtems/posix/pthread.inl,
+ posix/macros/rtems/posix/semaphore.inl,
+ posix/macros/rtems/posix/timer.inl: New header guards.
+
+2005-02-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * posix/include/aio.h, posix/include/devctl.h,
+ posix/include/intr.h, posix/include/mqueue.h,
+ posix/include/sched.h, posix/include/semaphore.h,
+ posix/include/rtems/posix/cancel.h,
+ posix/include/rtems/posix/cond.h,
+ posix/include/rtems/posix/condmp.h,
+ posix/include/rtems/posix/config.h,
+ posix/include/rtems/posix/intr.h,
+ posix/include/rtems/posix/key.h,
+ posix/include/rtems/posix/mqueue.h,
+ posix/include/rtems/posix/mqueuemp.h,
+ posix/include/rtems/posix/mutex.h,
+ posix/include/rtems/posix/mutexmp.h,
+ posix/include/rtems/posix/posixapi.h,
+ posix/include/rtems/posix/priority.h,
+ posix/include/rtems/posix/psignal.h,
+ posix/include/rtems/posix/pthread.h,
+ posix/include/rtems/posix/pthreadmp.h,
+ posix/include/rtems/posix/ptimer.h,
+ posix/include/rtems/posix/semaphore.h,
+ posix/include/rtems/posix/semaphoremp.h,
+ posix/include/rtems/posix/threadsup.h,
+ posix/include/rtems/posix/time.h,
+ posix/include/rtems/posix/timer.h: New header guards.
+
+2005-02-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * backward/asm.h, backward/chain.h, backward/clockdrv.h,
+ backward/confdefs.h, backward/console.h, backward/dosfs.h,
+ backward/ftpd.h, backward/imfs.h, backward/iosupp.h,
+ backward/itron.h, backward/ringbuf.h, backward/rtc.h,
+ backward/spurious.h, backward/timerdrv.h, backward/vmeintr.h,
+ backward/motorola/mc68230.h, backward/motorola/mc68681.h,
+ backward/zilog/z8030.h, backward/zilog/z8036.h,
+ backward/zilog/z8536.h:
+ New header guards.
+
+2005-02-19 Joel Sherrill <joel@OARcorp.com>
+
+ PR doc/763
+ * score/Doxyfile: Fixed path to no_cpu.
+
+2005-02-19 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * configure.ac: Check for external ampolish3.
+
+2005-02-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/vm/vm_extern.h, libnetworking/vm/vm_kern.h:
+ Update from FreeBSD.
+
+2005-02-17 Joel Sherrill <joel@OARcorp.com>
+
+ * include/rtems/pci.h: Merge differences from
+ libbsp/powerpc/shared/pci/pci.h.
+
+2005-02-17 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/vm/vm_param.h: Update from FreeBSD.
+
+2005-02-17 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libblock/include/rtems/diskdevs.h: Use uint32_t for ictrl req
+ argument (16bit target compliance).
+
+2005-02-17 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libblock/include/rtems/ramdisk.h:
+ size_t rtems_ramdisk_configuration_size.
+ * libblock/src/ramdisk.c: Adaptations for 16bit target compliance.
+
+2005-02-17 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/sys/sysctl.h (struct sysctl_oid): uint32_t
+ oid_kind (16bit target compliance).
+
+2005-02-12 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * configure.ac: Remove LIBSCORECPU.
+ * wrapup/Makefile.am: Reflect changes above.
+
+2005-02-10 Joel Sherrill <joel@OARcorp.com>
+
+ PR 753/rtems
+ * score/include/rtems/score/object.h,
+ score/src/objectinitializeinformation.c: Configured number of objects
+ needs to be of a type with more bits than Objects_Maximum to support
+ configuring unlimited objects. The type for configuring the maximum
+ number of objects should probably always be the same fundamental type
+ as Object Id. For 16-bit Id configurations, the constant
+ OBJECTS_UNLIMITED_OBJECTS was changed to 0x8000 to move in this
+ direction.
+
+2005-02-09 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libmisc/untar/untar.c (_rtems_octal2ulong): Replace.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * ftpd/Makefile.am: Split preinstallation rules in to separate
+ preinstall.am-files.
+ * ftpd/preinstall.am: New (Generated from corresponding Makefile.am).
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/Makefile.am: Split preinstallation rules in to separate
+ preinstall.am-files.
+ * librpc/preinstall.am: New (Generated from corresponding Makefile.am).
+
+2005-02-08 Eric Norum <norum@aps.anl.gov>
+
+ * libfs/Makefile.am, libfs/src/imfs/imfs.h, libfs/src/imfs/imfs_eval.c,
+ libfs/src/imfs/imfs_fchmod.c, libfs/src/imfs/imfs_handlers_memfile.c,
+ libfs/src/imfs/imfs_init.c, libfs/src/imfs/imfs_initsupp.c,
+ libfs/src/imfs/imfs_load_tar.c, libfs/src/imfs/linearfile.c,
+ libfs/src/imfs/memfile.c, libfs/src/imfs/miniimfs_init.c: Add
+ 'copy-on-write' semantics to rtems_tarfs_load().
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * httpd/Makefile.am: Split preinstallation rules in to separate
+ preinstall.am-files.
+ * httpd/preinstall.am: New (Generated from corresponding Makefile.am).
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * itron/Makefile.am, libcsupport/Makefile.am,
+ libnetworking/Makefile.am, posix/Makefile.am,
+ rtems/Makefile.am, sapi/Makefile.am,
+ score/Makefile.am, wrapup/Makefile.am,
+ Makefile.am: Split preinstallation rules in to separate
+ preinstall.am-files.
+ * itron/preinstall.am, libcsupport/preinstall.am,
+ libnetworking/preinstall.am, posix/preinstall.am,
+ rtems/preinstall.am, sapi/preinstall.am,
+ score/preinstall.am, wrapup/preinstall.am,
+ preinstall.am: New (Generated from corresponding Makefile.ams).
+ * configure.ac: Add AM_CONDITIONAL(AMPOLISH3)-stub.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * configure.ac: Add new header guard to cpuopts.h.
+ * Makefile.am: Add libfs, libblock, ftpd header install rules.
+ * libfs/Makefile.am, libblock/Makefile.am, ftpd/Makefile.am: Remove
+ header install rules.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * aclocal/rtems-top.m4 (rtems_updir): Quote sed args.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/if_ppp.c, libnetworking/net/if_pppvar.h:
+ Ansification, cosmetics from FreeBSD.
+
+2005-02-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libfs/src/imfs/imfs.h, libfs/src/imfs/imfs_load_tar.c,
+ libmisc/untar/untar.c, libmisc/untar/untar.h:
+ Various generalizations and fixes.
+
+2005-02-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Add include/rtems/tar.h.
+ Merge-in header rules from libmisc/Makefile.am
+ * libmisc/Makefile.am: Remove header rules.
+ Remove lib-specific CPPFLAGS.
+ * configure.ac: Add checks for <tar.h>
+
+2005-02-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * include/rtems/tar.h: New.
+
+2005-02-05 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libfs/Makefile.am: Build libfs/src/imfs/imfs_load_tar.c.
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/libc/res_init.c, libnetworking/netinet/in.h,
+ libnetworking/netinet/in_pcb.c, libnetworking/netinet/raw_ip.c:
+ Misc. part. updates from FreeBSD.
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * automake/compile.am: Remove depend: (Redundant).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/include/rtems/rtems/sem.h, rtems/src/semcreate.c,
+ rtems/src/semdelete.c, rtems/src/semflush.c,
+ rtems/src/semident.c, rtems/src/semobtain.c,
+ rtems/src/semrelease.c: Use rtems_id for semaphores.
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/include/rtems/libio.h: Use rtems_id for semaphores.
+ Use char* for buffer.
+ * backward/ftpd.h: New.
+ * Makefile.am: Reflect having added backward/ftpd.h.
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 756/rtems
+ * ftpd/ftpd.c, ftpd/ftpd.h, ftpd/Makefile.am: New (relocated from
+ /c/src/libnetworking/ftpd)
+ * ftpd/ftd.h: New header guards.
+ * ftpd/Makefile.am: Install libftd.a, install ftp.h to rtems/ftp.h.
+ * configure.ac: Add ftpd/Makefile.
+ * Makefile.am: Add ftpd.
+
+2005-02-03 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/clnt_stat.h, librpc/include/rpc/rpcent.h:
+ New (From FreeBSD).
+ * librpc/include/rpc/rpc.h: Partial update from FreeBSD.
+ * librpc/Makefile.am: Reflect changes above.
+
+2005-02-03 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/types.h: Partial update from FreeBSD.
+ Use stdint.h types instead of sys/types.h.
+ * librpc/src/rpc/bindresvport.c: Partial update from FreeBSD.
+
+2005-02-03 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 755/rtems
+ * libnetworking/libc/res_init.c, libnetworking/lib/rtems_bsdnet_ntp.c,
+ libnetworking/nfs/bootp_subr.c: Include <rtems/bsdnet/servers.h>.
+
+2005-02-03 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 755/rtems
+ * libnetworking/rtems_glue.c:
+ Rename rtems_bsdnet_nameservers to _rtems_bsdnet_nameservers.
+ Rename rtems_bsdnet_ntpservers to _rtems_bsdnet_ntpservers.
+ Add new rtems_bsdnet_nameservers, rtems_bsdnet_ntpservers as
+ pointers to _rtems_bsdnet_*servers arrays.
+ * libnetworking/rtems/rtems_bsdnet_internal.h: Remove
+ rtems_bsdnet_nameserver, rtems_bsdnet_nameserver_count.
+ * libnetworking/rtems/rtems_bsdnet.h: Remove
+ rtems_bsdnet_ntpserver, rtems_bsdnet_ntp_count.
+ * libnetworking/rtems/bsdnet/servers.h: New.
+ * libnetworking/opt_ipsec.h: New (BSD compatibility).
+ * libnetworking/Makefile.am: Reflect changes above.
+
+2005-02-02 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/rtems/ftpfs.h, libnetworking/rtems/mkrootfs.h,
+ libnetworking/rtems/rtems_bsdnet_internal.h,
+ libnetworking/rtems/rtems_bsdnet.h,
+ libnetworking/rtems/tftp.h: New header guards.
+
+2005-02-02 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/rtems/issetugid.c,
+ libnetworking/rtems/mkrootfs.c,
+ libnetworking/rtems/rtems_bootp.c,
+ libnetworking/rtems/rtems_bsdnet_malloc_starvation.c,
+ libnetworking/rtems/rtems_glue.c,
+ libnetworking/rtems/rtems_select.c,
+ libnetworking/rtems/rtems_showicmpstat.c,
+ libnetworking/rtems/rtems_showifstat.c,
+ libnetworking/rtems/rtems_showipstat.c,
+ libnetworking/rtems/rtems_showmbuf.c,
+ libnetworking/rtems/rtems_showroute.c,
+ libnetworking/rtems/rtems_showtcpstat.c,
+ libnetworking/rtems/rtems_showudpstat.c,
+ libnetworking/rtems/rtems_syscall.c,
+ libnetworking/rtems/sghostname.c: Include config.h.
+
+2005-02-01 Joel Sherrill <joel@OARcorp.com>
+
+ * libblock/include/rtems/bdbuf.h,
+ libblock/include/rtems/ide_part_table.h, libblock/src/blkdev.c,
+ libcsupport/include/rtems/termiostypes.h, libcsupport/src/termios.c,
+ posix/macros/rtems/posix/cond.inl,
+ posix/macros/rtems/posix/mutex.inl : Remove warnings.
+
+2005-02-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * aclocal/prog-cc.m4: Remove refs to gcc-isystem.m4.
+ * aclocal/gcc-isystem.m4: Remove (Unused).
+
+2005-01-28 Eric Norum <norume@aps.anl.gov>
+
+ * libnetworking/rtems/rtems_glue.c: Remove dead variable.
+
+2005-01-28 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * itron/include/itron.h,
+ itron/include/itronsys/eventflags.h,
+ itron/include/itronsys/fmempool.h,
+ itron/include/itronsys/intr.h,
+ itron/include/itronsys/mbox.h,
+ itron/include/itronsys/msgbuffer.h,
+ itron/include/itronsys/network.h,
+ itron/include/itronsys/port.h,
+ itron/include/itronsys/semaphore.h,
+ itron/include/itronsys/status.h,
+ itron/include/itronsys/sysmgmt.h,
+ itron/include/itronsys/task.h,
+ itron/include/itronsys/time.h,
+ itron/include/itronsys/types.h,
+ itron/include/itronsys/vmempool.h,
+ itron/include/rtems/itron/config.h,
+ itron/include/rtems/itron/eventflags.h,
+ itron/include/rtems/itron/fmempool.h,
+ itron/include/rtems/itron/intr.h,
+ itron/include/rtems/itron/itronapi.h,
+ itron/include/rtems/itron/mbox.h,
+ itron/include/rtems/itron/msgbuffer.h,
+ itron/include/rtems/itron/network.h,
+ itron/include/rtems/itron/object.h,
+ itron/include/rtems/itron/port.h,
+ itron/include/rtems/itron/semaphore.h,
+ itron/include/rtems/itron/sysmgmt.h,
+ itron/include/rtems/itron/task.h,
+ itron/include/rtems/itron/time.h,
+ itron/include/rtems/itron/vmempool.h: New header guards.
+
+2005-01-28 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libblock/include/rtems/bdbuf.h, libblock/include/rtems/blkdev.h,
+ libblock/include/rtems/diskdevs.h,
+ libblock/include/rtems/ide_part_table.h,
+ libblock/include/rtems/ramdisk.h,
+ libfs/src/dosfs/dosfs.h, libfs/src/imfs/imfs.h:
+ New header guards.
+
+2005-01-28 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/include/inttypes.h: New header guard.
+ Fix doxygen preamble.
+
+2005-01-28 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/include/motorola/mc68230.h,
+ libcsupport/include/motorola/mc68681.h,
+ libcsupport/include/chain.h,
+ libcsupport/include/clockdrv.h,
+ libcsupport/include/console.h,
+ libcsupport/include/iosupp.h,
+ libcsupport/include/ringbuf.h,
+ libcsupport/include/rtc.h,
+ libcsupport/include/spurious.h,
+ libcsupport/include/timerdrv.h,
+ libcsupport/include/vmeintr.h,
+ libcsupport/include/rtems/libio.h,
+ libcsupport/include/rtems/assoc.h,
+ libcsupport/include/rtems/error.h,
+ libcsupport/include/rtems/libcsupport.h,
+ libcsupport/include/rtems/libio_.h,
+ libcsupport/include/rtems/termiostypes.h,
+ libcsupport/include/rtems/cdefs.h,
+ libcsupport/include/zilog/z8036.h,
+ libcsupport/include/zilog/z8530.h,
+ libcsupport/include/zilog/z8536.h: New header guards.
+
+2005-01-28 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * include/rtems/bspIo.h, include/rtems/concat.h,
+ include/rtems/fs.h, include/rtems/pci.h,
+ include/rtems/stdint.h, include/rtems/userenv.h:
+ New header guards.
+
+2005-01-28 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/include/rtems.h, rtems/include/rtems/rtems/asr.h,
+ rtems/include/rtems/rtems/attr.h, rtems/include/rtems/rtems/cache.h,
+ rtems/include/rtems/rtems/clock.h,
+ rtems/include/rtems/rtems/config.h,
+ rtems/include/rtems/rtems/dpmem.h,
+ rtems/include/rtems/rtems/event.h,
+ rtems/include/rtems/rtems/eventmp.h,
+ rtems/include/rtems/rtems/eventset.h,
+ rtems/include/rtems/rtems/intr.h,
+ rtems/include/rtems/rtems/message.h,
+ rtems/include/rtems/rtems/modes.h, rtems/include/rtems/rtems/mp.h,
+ rtems/include/rtems/rtems/msgmp.h,
+ rtems/include/rtems/rtems/options.h,
+ rtems/include/rtems/rtems/part.h,
+ rtems/include/rtems/rtems/partmp.h,
+ rtems/include/rtems/rtems/ratemon.h,
+ rtems/include/rtems/rtems/region.h,
+ rtems/include/rtems/rtems/regionmp.h,
+ rtems/include/rtems/rtems/rtemsapi.h,
+ rtems/include/rtems/rtems/sem.h, rtems/include/rtems/rtems/semmp.h,
+ rtems/include/rtems/rtems/signal.h,
+ rtems/include/rtems/rtems/signalmp.h,
+ rtems/include/rtems/rtems/status.h,
+ rtems/include/rtems/rtems/support.h,
+ rtems/include/rtems/rtems/taskmp.h,
+ rtems/include/rtems/rtems/tasks.h,
+ rtems/include/rtems/rtems/timer.h,
+ rtems/include/rtems/rtems/types.h, sapi/include/rtems/config.h,
+ sapi/include/rtems/extension.h, sapi/include/rtems/fatal.h,
+ sapi/include/rtems/init.h, sapi/include/rtems/io.h,
+ sapi/include/rtems/mptables.h, sapi/include/rtems/sptables.h,
+ score/include/rtems/debug.h, score/include/rtems/seterr.h,
+ score/include/rtems/system.h, score/include/rtems/score/address.h,
+ score/include/rtems/score/apiext.h,
+ score/include/rtems/score/apimutex.h,
+ score/include/rtems/score/bitfield.h,
+ score/include/rtems/score/chain.h,
+ score/include/rtems/score/context.h,
+ score/include/rtems/score/copyrt.h,
+ score/include/rtems/score/coremsg.h,
+ score/include/rtems/score/coremutex.h,
+ score/include/rtems/score/coresem.h,
+ score/include/rtems/score/heap.h,
+ score/include/rtems/score/interr.h, score/include/rtems/score/isr.h,
+ score/include/rtems/score/mpci.h, score/include/rtems/score/mppkt.h,
+ score/include/rtems/score/object.h,
+ score/include/rtems/score/objectmp.h,
+ score/include/rtems/score/priority.h,
+ score/include/rtems/score/stack.h,
+ score/include/rtems/score/states.h,
+ score/include/rtems/score/sysstate.h,
+ score/include/rtems/score/thread.h,
+ score/include/rtems/score/threadmp.h,
+ score/include/rtems/score/threadq.h,
+ score/include/rtems/score/tod.h, score/include/rtems/score/tqdata.h,
+ score/include/rtems/score/userext.h,
+ score/include/rtems/score/watchdog.h,
+ score/include/rtems/score/wkspace.h: New header guard.
+
+2005-01-28 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * automake/compile.am: Remove RTEMS_CPPFLAGS.
+
+2005-01-28 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/if_pppvar.h: Ansify.
+
+2005-01-28 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * include/rtems/userenv.h: Set up LOGIN_NAME_MAX iff not having been
+ defined before.
+
+2005-01-28 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * sapi/src/debug.c, sapi/src/exinit.c, sapi/src/extension.c,
+ sapi/src/extensioncreate.c, sapi/src/extensiondelete.c,
+ sapi/src/extensionident.c, sapi/src/fatal.c, sapi/src/io.c,
+ sapi/src/itronapi.c, sapi/src/posixapi.c, sapi/src/rtemsapi.c:
+ Include config.h.
+
+2005-01-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/src/lstat.c, libcsupport/src/readdir_r.c:
+ Include config.h.
+
+2005-01-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libmisc/untar/untar.h: New prototype to eleminate warnings.
+ * libmisc/untar/untar.c: Cosmetics, add symlinks.
+
+2005-01-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/include/tar.h: New (SUSv3).
+ * Makefile.am: Integrate newlib-specific headers.
+ Add libcsupport/include/tar.h.
+ * libcsupport/Makefile.am: Remove newlib-specific headers.
+
+2005-01-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libmisc/fsmount/fsmount.c: Include config.h.
+
+2005-01-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * score/src/apiext.c, score/src/chain.c, score/src/coremsg.c,
+ score/src/coremsgbroadcast.c, score/src/coremsgclose.c,
+ score/src/coremsgflush.c, score/src/coremsgflushsupp.c,
+ score/src/coremsgflushwait.c, score/src/coremsginsert.c,
+ score/src/coremsgseize.c, score/src/coremsgsubmit.c,
+ score/src/coremutex.c, score/src/coremutexflush.c,
+ score/src/coremutexseize.c, score/src/coremutexsurrender.c,
+ score/src/coresem.c, score/src/coresemflush.c,
+ score/src/coresemseize.c, score/src/coresemsurrender.c,
+ score/src/coretod.c, score/src/coretodset.c,
+ score/src/coretodtickle.c, score/src/coretodtoseconds.c,
+ score/src/coretodvalidate.c, score/src/heap.c,
+ score/src/heapallocate.c, score/src/heapallocatealigned.c,
+ score/src/heapextend.c, score/src/heapfree.c,
+ score/src/heapgetfreeinfo.c, score/src/heapgetinfo.c,
+ score/src/heapsizeofuserarea.c, score/src/heapwalk.c,
+ score/src/interr.c, score/src/isr.c, score/src/iterateoverthreads.c,
+ score/src/mpci.c, score/src/object.c, score/src/objectallocate.c,
+ score/src/objectallocatebyindex.c, score/src/objectclearname.c,
+ score/src/objectcomparenameraw.c,
+ score/src/objectcomparenamestring.c, score/src/objectcopynameraw.c,
+ score/src/objectcopynamestring.c,
+ score/src/objectextendinformation.c, score/src/objectfree.c,
+ score/src/objectget.c, score/src/objectgetbyindex.c,
+ score/src/objectgetisr.c, score/src/objectgetnext.c,
+ score/src/objectgetnoprotection.c, score/src/objectidtoname.c,
+ score/src/objectinitializeinformation.c, score/src/objectmp.c,
+ score/src/objectnametoid.c, score/src/objectshrinkinformation.c,
+ score/src/thread.c, score/src/threadchangepriority.c,
+ score/src/threadclearstate.c, score/src/threadclose.c,
+ score/src/threadcreateidle.c, score/src/threaddelayended.c,
+ score/src/threaddispatch.c, score/src/threadevaluatemode.c,
+ score/src/threadget.c, score/src/threadhandler.c,
+ score/src/threadidlebody.c, score/src/threadinitialize.c,
+ score/src/threadloadenv.c, score/src/threadmp.c,
+ score/src/threadq.c, score/src/threadqdequeue.c,
+ score/src/threadqdequeuefifo.c, score/src/threadqdequeuepriority.c,
+ score/src/threadqenqueue.c, score/src/threadqenqueuefifo.c,
+ score/src/threadqenqueuepriority.c, score/src/threadqextract.c,
+ score/src/threadqextractfifo.c, score/src/threadqextractpriority.c,
+ score/src/threadqextractwithproxy.c, score/src/threadqfirst.c,
+ score/src/threadqfirstfifo.c, score/src/threadqfirstpriority.c,
+ score/src/threadqflush.c, score/src/threadqtimeout.c,
+ score/src/threadready.c, score/src/threadreset.c,
+ score/src/threadresettimeslice.c, score/src/threadrestart.c,
+ score/src/threadresume.c, score/src/threadrotatequeue.c,
+ score/src/threadsetpriority.c, score/src/threadsetstate.c,
+ score/src/threadsettransient.c, score/src/threadstackallocate.c,
+ score/src/threadstackfree.c, score/src/threadstart.c,
+ score/src/threadstartmultitasking.c, score/src/threadsuspend.c,
+ score/src/threadtickletimeslice.c, score/src/threadyieldprocessor.c,
+ score/src/userext.c, score/src/watchdog.c,
+ score/src/watchdogadjust.c, score/src/watchdoginsert.c,
+ score/src/watchdogremove.c, score/src/watchdogtickle.c,
+ score/src/wkspace.c: Include config.h.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * include/rtems/stdint.h: Add signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * score/include/rtems/score/heap.h: Use uintptr_t for _H_uptr_t.
+ * score/inline/rtems/score/address.inl: Remove
+ RTEMS_CPU_HAS_16_BIT_ADDRESSES.
+ Use uintptr_t for void* to address casts.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/include/stdint.h: Use __PTRDIFF_TYPE__ for intptr_t.
+
+2005-01-23 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * sapi/src/fatal.c, score/src/interr.c:
+ Remove volatile on return type.
+
+2005-01-20 Sergei Organov <osv@topconrd.ru>
+
+ PR 536/rtems
+ Heap manager re-implementation to consume less memory and still satisfy
+ alignment requirements.
+
+ * score/src/heap.c, score/src/heapallocate.c, score/src/heapextend.c,
+ score/src/heapfree.c, score/src/heapgetinfo.c,
+ score/src/heapgetfreeinfo.c, core/src/heapsizeofuserarea.c,
+ score/src/heapwalk.c, core/macros/rtems/score/heap.inl,
+ score/inline/rtems/score/heap.inl,
+ score/include/rtems/score/heap.h: Reimplemented.
+ * score/src/heapallocatealigned.c: new file
+ * score/Makefile.am: HEAP_C_FILES: add score/src/heapallocatealigned.c
+
+2005-01-20 Joel Sherrill <joel@OARcorp.com>
+
+ PR 745/rtems
+ * rtems/src/ratemoncreate.c, rtems/src/timercreate.c: Make sure
+ internal timer structures are initialized so object control reuse is
+ safe.
+
+2005-01-20 Joel Sherrill <joel@OARcorp.com>
+
+ PR 740/rtems
+ * score/src/heapgetfreeinfo.c: Return size of largest not of last block.
+
+2005-01-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libfs/src/dosfs/fat.c (fat_init_volume_info): Reflect
+ fs_info->sec_buf being a uint8_t.
+ * libfs/src/dosfs/msdos_create.c, libfs/src/dosfs/msdos_misc.c:
+ Eliminate warnings.
+
+2005-01-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libfs/src/dosfs/msdos_misc.c
+ (msdos_get_dotdot_dir_info_cluster_num_and_offset):
+ Remove cur_node (Unused).
+
+2005-01-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/src/termios.c: Remove unnecessary type casts.
+
+2005-01-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * sapi/include/rtems/io.h : size_t device_name_length.
+
+2005-01-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * sapi/include/rtems/fatal.h, score/include/rtems/score/interr.h:
+ Remove volatile on return type.
+
+2005-01-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * itron/inline/rtems/itron/task.inl (_ITRON_Task_Priority_to_Core,
+ _ITRON_tasks_Core_to_Priority): Correct return types.
+
+2005-01-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/src/attr.c, rtems/src/clockget.c, rtems/src/clockset.c,
+ rtems/src/clocktick.c, rtems/src/dpmem.c, rtems/src/dpmemcreate.c,
+ rtems/src/dpmemdelete.c, rtems/src/dpmemexternal2internal.c,
+ rtems/src/dpmemident.c, rtems/src/dpmeminternal2external.c,
+ rtems/src/event.c, rtems/src/eventmp.c, rtems/src/eventreceive.c,
+ rtems/src/eventseize.c, rtems/src/eventsend.c,
+ rtems/src/eventsurrender.c, rtems/src/eventtimeout.c,
+ rtems/src/intr.c, rtems/src/intrbody.c, rtems/src/intrcatch.c,
+ rtems/src/mp.c, rtems/src/msg.c, rtems/src/msgmp.c,
+ rtems/src/msgqallocate.c, rtems/src/msgqbroadcast.c,
+ rtems/src/msgqcreate.c, rtems/src/msgqdelete.c,
+ rtems/src/msgqflush.c, rtems/src/msgqgetnumberpending.c,
+ rtems/src/msgqident.c, rtems/src/msgqreceive.c,
+ rtems/src/msgqsend.c, rtems/src/msgqsubmit.c,
+ rtems/src/msgqtranslatereturncode.c, rtems/src/msgqurgent.c,
+ rtems/src/part.c, rtems/src/partcreate.c, rtems/src/partdelete.c,
+ rtems/src/partgetbuffer.c, rtems/src/partident.c,
+ rtems/src/partmp.c, rtems/src/partreturnbuffer.c,
+ rtems/src/ratemon.c, rtems/src/ratemoncancel.c,
+ rtems/src/ratemoncreate.c, rtems/src/ratemondelete.c,
+ rtems/src/ratemongetstatus.c, rtems/src/ratemonident.c,
+ rtems/src/ratemonperiod.c, rtems/src/ratemontimeout.c,
+ rtems/src/region.c, rtems/src/regioncreate.c,
+ rtems/src/regiondelete.c, rtems/src/regionextend.c,
+ rtems/src/regiongetfreeinfo.c, rtems/src/regiongetinfo.c,
+ rtems/src/regiongetsegment.c, rtems/src/regiongetsegmentsize.c,
+ rtems/src/regionident.c, rtems/src/regionmp.c,
+ rtems/src/regionreturnsegment.c, rtems/src/rtclock.c,
+ rtems/src/rtemsidtoname.c, rtems/src/rtemstimer.c, rtems/src/sem.c,
+ rtems/src/semcreate.c, rtems/src/semdelete.c, rtems/src/semflush.c,
+ rtems/src/semident.c, rtems/src/semmp.c, rtems/src/semobtain.c,
+ rtems/src/semrelease.c, rtems/src/semtranslatereturncode.c,
+ rtems/src/signal.c, rtems/src/signalcatch.c, rtems/src/signalmp.c,
+ rtems/src/signalsend.c, rtems/src/taskcreate.c,
+ rtems/src/taskdelete.c, rtems/src/taskgetnote.c,
+ rtems/src/taskident.c, rtems/src/taskinitusers.c,
+ rtems/src/taskissuspended.c, rtems/src/taskmode.c,
+ rtems/src/taskmp.c, rtems/src/taskrestart.c, rtems/src/taskresume.c,
+ rtems/src/tasks.c, rtems/src/tasksetnote.c,
+ rtems/src/tasksetpriority.c, rtems/src/taskstart.c,
+ rtems/src/tasksuspend.c, rtems/src/taskvariableadd.c,
+ rtems/src/taskvariabledelete.c, rtems/src/taskvariableget.c,
+ rtems/src/taskwakeafter.c, rtems/src/taskwakewhen.c,
+ rtems/src/timercancel.c, rtems/src/timercreate.c,
+ rtems/src/timerdelete.c, rtems/src/timerfireafter.c,
+ rtems/src/timerfirewhen.c, rtems/src/timergetinfo.c,
+ rtems/src/timerident.c, rtems/src/timerreset.c,
+ rtems/src/timerserver.c, rtems/src/timerserverfireafter.c,
+ rtems/src/timerserverfirewhen.c: Include config.h.
+
+2005-01-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * score/inline/rtems/score/userext.inl: Include <string.h>.
+
+2005-01-14 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 742/rtems
+ * score/include/rtems/system.h: Remove stringify().
+
+2005-01-13 Joel Sherrill <joel@oarcorp.com>
+ Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/src/gxx_wrapper.c: Reflect GCC-4.0's gthr-rtems.h.
+
+2005-01-09 Joel Sherrill <joel@oarcorp.com>
+
+ * librpc/include/rpc/clnt.h, librpc/src/rpc/authunix_prot.c,
+ librpc/src/rpc/clnt_tcp.c, librpc/src/rpc/pmap_prot2.c,
+ librpc/src/rpc/pmap_rmt.c, librpc/src/rpc/rtems_portmapper.c,
+ librpc/src/rpc/svc_simple.c: Fix warnings.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/auth_des.h, librpc/include/rpc/xdr.h,
+ librpc/src/rpc/auth_des.c, librpc/src/rpc/auth_unix.c,
+ librpc/src/rpc/rpc_prot.c, librpc/src/xdr/xdr.c:
+ Misc. ansi-fications, misc. updates from FreeBSD.
+
+2005-01-07 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/libc/res_debug.c: Added const to eliminate warnings.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/xdr.h: Remove questionable comments.
+ * librpc/include/rpc/auth.h: Remove __P, ansi-fy.
+ * librpc/src/rpc/auth_none.c: Reflect changes above.
+ Partial update from FreeBSD.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * posix/include/rtems/posix/cond.h,
+ posix/include/rtems/posix/mutex.h: Cosmetics.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/svc.h, librpc/include/rpc/xdr.h:
+ Remove __P(xx).
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * httpd/Makefile.am, itron/Makefile.am, libblock/Makefile.am,
+ libcsupport/Makefile.am, libfs/Makefile.am, libmisc/Makefile.am,
+ libnetworking/Makefile.am, librpc/Makefile.am, posix/Makefile.am,
+ rtems/Makefile.am, sapi/Makefile.am, score/Makefile.am:
+ Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-05 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * aclocal/rtems-flags.m4: Remove (Unused).
+
+2005-01-05 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * aclocal/prog-ccas.m4: Remove $(GCCSPECS).
+
+2005-01-05 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/src/eventsurrender.c: Remove bogus type casts.
+ * sapi/Makefile.am: Eliminate *_FILES.
+
+2005-01-05 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * aclocal/env-rtemscpu.m4: Remove CFLAGS_OPTIMIZE_V.
+ Remove CPU_CFLAGS.
+ * aclocal/prog-cc.m4: Don't invoke _RTEMS_FLAGS to set up
+ RTEMS_CFLAGS.
+ * automake/compile.am: AM_CFLAGS = RTEMS_CFLAGS.
+ Remove CPPFLAGS, CFLAGS, CPU_CFLAGS, CFLAGS_OPTIMIZE.
+ Cleanup comments.
+
+2005-01-05 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * aclocal/env-rtemscpu.m4: Remove CFLAGS_DEBUG_V.
+ * aclocal/prog-cc.m4: Remove RTEMS_USE_GCC.
+ * automake/compile.am: Cleanup comments. Remove ASFLAGS.
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * automake/compile.am, httpd/Makefile.am, itron/Makefile.am,
+ libblock/Makefile.am, libcsupport/Makefile.am, libfs/Makefile.am,
+ libmisc/Makefile.am, libnetworking/Makefile.am, librpc/Makefile.am,
+ posix/Makefile.am, rtems/Makefile.am, sapi/Makefile.am,
+ score/Makefile.am, wrapup/Makefile.am:
+ Remove build-variant support.
+
+2004-12-30 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * httpd/Makefile.am: Remove -DOS="RTEMS".
+ * httpd/rtems_webserver.h: Add doxygen preamble.
+ Add C++ guards.
+
+2004-12-29 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * score/include/rtems/score/chain.h:
+ Use uint32_t instead of unsigned32.
+ * score/src/chain.c: Remove superfluous type cast.
+
+2004-12-10 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * posix/include/aio.h, posix/include/devctl.h,
+ posix/include/intr.h, posix/include/mqueue.h,
+ posix/include/sched.h, posix/include/semaphore.h,
+ posix/src/ptimer.c, posix/src/ptimer1.c:
+ Include <unistd.h> instead of <sys/features.h> to pick up
+ _POSIX_* defines (Mandated by POSIX).
+
+2004-12-09 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * score/include/rtems/system.h: Don't define NULL, include
+ <stddef.h>.
+
+2004-12-03 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/if_ethersubr.c,
+ libnetworking/net/radix.h,
+ libnetworking/netinet/if_ether.h,
+ libnetworking/netinet/igmp_var.h,
+ libnetworking/netinet/in_var.h,
+ libnetworking/netinet/tcp_timer.h,
+ libnetworking/netinet/udp_usrreq.c,
+ libnetworking/rtems/rtems_glue.c:
+ Misc. updates from FreeBSD and bugfixes tripped by GCC-4.0.0.
+
+2004-12-02 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/kern/kern_sysctl.c,
+ libnetworking/sys/sysctl.h: Add SYSCTL_CHILDREN_SET.
+ (Update from FreeBSD for GCC-4.0.0).
+
+2004-12-02 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/kern/kern_sysctl.c, libnetworking/netinet/ip_mroute.c,
+ libnetworking/sys/socketvar.h: Remove warnings.
+
+2004-12-02 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/net/radix.c, libnetworking/net/radix.h,
+ libnetworking/net/route.h, libnetworking/netinet/if_ether.h,
+ libnetworking/netinet/in_var.h, libnetworking/netinet/tcp_timer.h,
+ libnetworking/netinet/udp_usrreq.c, libnetworking/netinet/udp_var.h,
+ libnetworking/sys/callout.h, libnetworking/sys/socketvar.h,
+ libnetworking/sys/sysctl.h: Cosmetics from FreeBSD.
+
+2004-12-02 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libmisc/capture/capture-cli.h, libmisc/capture/capture.h,
+ libmisc/monitor/monitor.h, libmisc/rtmonuse/rtmonuse.h,
+ libmisc/shell/shell.h: Partial doxygenification.
+ * libmisc/capture/capture.h: Use INT32_C for constants.
+
+2004-12-02 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/include/chain.h,
+ libcsupport/include/clockdrv.h,
+ libcsupport/include/console.h,
+ libcsupport/include/iosupp.h,
+ libcsupport/include/ringbuf.h,
+ libcsupport/include/rtc.h,
+ libcsupport/include/spurious.h,
+ libcsupport/include/timerdrv.h,
+ libcsupport/include/vmeintr.h,
+ libcsupport/include/motorola/mc68230.h,
+ libcsupport/include/motorola/mc68681.h,
+ libcsupport/include/rtems/assoc.h,
+ libcsupport/include/rtems/cdefs.h,
+ libcsupport/include/rtems/error.h,
+ libcsupport/include/rtems/libcsupport.h,
+ libcsupport/include/rtems/libio.h,
+ libcsupport/include/rtems/libio_.h,
+ libcsupport/include/rtems/termiostypes.h,
+ libcsupport/include/zilog/z8036.h,
+ libcsupport/include/zilog/z8530.h,
+ libcsupport/include/zilog/z8536.h: Add doxygen preamble.
+
+2004-11-29 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/src/mallocfreespace.c, rtems/Makefile.am,
+ rtems/include/rtems/rtems/region.h, score/Makefile.am,
+ score/include/rtems/score/heap.h, score/src/heapgetinfo.c: Add
+ capability to return information about just the free blocks in a
+ region or heap. Also changed the semantics of free space available
+ to be the largest block of memory that can be allocated.
+ * rtems/src/regiongetfreeinfo.c, score/src/heapgetfreeinfo.c: New files.
+ : score/include/rtems/score/object.h,
+ score/src/objectinitializeinformation.c: Remove warning.
+
+2004-11-22 Joel Sherrill <joel@OARcorp.com>
+
+ * score/include/rtems/score/object.h, score/src/objectclearname.c,
+ score/src/objectcopynamestring.c: Fixing warning led to making
+ changes to multiple prototypes for object support routines.
+
+2004-11-22 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/src/ttyname_r.c: Remove warning for using _fstat.
+
+2004-11-22 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * aclocal/enable-itron.m4, aclocal/check-itron.m4:
+ Allow building itron for unix.
+
+2004-11-22 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libnetworking/Makefile.am: Don't install bpfilter.h (Private
+ header).
+
+2004-11-22 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libblock/include/rtems/bdbuf.h,
+ libblock/include/rtems/blkdev.h,
+ libblock/include/rtems/diskdevs.h,
+ libblock/include/rtems/ide_part_table.h,
+ libblock/include/rtems/ramdisk.h:
+ Add doxygen preamble.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * sapi/include/confdefs.h, sapi/include/rtems/config.h,
+ sapi/include/rtems/extension.h, sapi/include/rtems/fatal.h,
+ sapi/include/rtems/init.h, sapi/include/rtems/io.h,
+ sapi/include/rtems/sptables.h, sapi/inline/rtems/extension.inl,
+ sapi/macros/rtems/extension.inl: Add doxygen preamble.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * score/include/rtems/debug.h, score/include/rtems/seterr.h,
+ score/include/rtems/system.h, score/include/rtems/score/address.h,
+ score/include/rtems/score/apiext.h,
+ score/include/rtems/score/apimutex.h,
+ score/include/rtems/score/bitfield.h,
+ score/include/rtems/score/chain.h,
+ score/include/rtems/score/context.h,
+ score/include/rtems/score/copyrt.h,
+ score/include/rtems/score/coremsg.h,
+ score/include/rtems/score/coremutex.h,
+ score/include/rtems/score/coresem.h,
+ score/include/rtems/score/heap.h,
+ score/include/rtems/score/interr.h, score/include/rtems/score/isr.h,
+ score/include/rtems/score/mpci.h, score/include/rtems/score/mppkt.h,
+ score/include/rtems/score/object.h,
+ score/include/rtems/score/objectmp.h,
+ score/include/rtems/score/priority.h,
+ score/include/rtems/score/stack.h,
+ score/include/rtems/score/states.h,
+ score/include/rtems/score/sysstate.h,
+ score/include/rtems/score/thread.h,
+ score/include/rtems/score/threadmp.h,
+ score/include/rtems/score/threadq.h,
+ score/include/rtems/score/tod.h, score/include/rtems/score/tqdata.h,
+ score/include/rtems/score/userext.h,
+ score/include/rtems/score/watchdog.h,
+ score/include/rtems/score/wkspace.h,
+ score/inline/rtems/score/address.inl,
+ score/inline/rtems/score/chain.inl,
+ score/inline/rtems/score/coremsg.inl,
+ score/inline/rtems/score/coremutex.inl,
+ score/inline/rtems/score/coresem.inl,
+ score/inline/rtems/score/heap.inl, score/inline/rtems/score/isr.inl,
+ score/inline/rtems/score/mppkt.inl,
+ score/inline/rtems/score/object.inl,
+ score/inline/rtems/score/objectmp.inl,
+ score/inline/rtems/score/priority.inl,
+ score/inline/rtems/score/stack.inl,
+ score/inline/rtems/score/states.inl,
+ score/inline/rtems/score/sysstate.inl,
+ score/inline/rtems/score/thread.inl,
+ score/inline/rtems/score/threadmp.inl,
+ score/inline/rtems/score/tod.inl,
+ score/inline/rtems/score/tqdata.inl,
+ score/inline/rtems/score/userext.inl,
+ score/inline/rtems/score/watchdog.inl,
+ score/inline/rtems/score/wkspace.inl,
+ score/macros/rtems/score/object.inl: Adjust doxygen @file.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * posix/include/aio.h, posix/include/devctl.h, posix/include/intr.h,
+ posix/include/mqueue.h, posix/include/sched.h,
+ posix/include/semaphore.h, posix/include/rtems/posix/cancel.h,
+ posix/include/rtems/posix/cond.h,
+ posix/include/rtems/posix/condmp.h,
+ posix/include/rtems/posix/config.h,
+ posix/include/rtems/posix/intr.h, posix/include/rtems/posix/key.h,
+ posix/include/rtems/posix/mqueue.h,
+ posix/include/rtems/posix/mqueuemp.h,
+ posix/include/rtems/posix/mutex.h,
+ posix/include/rtems/posix/mutexmp.h,
+ posix/include/rtems/posix/posixapi.h,
+ posix/include/rtems/posix/priority.h,
+ posix/include/rtems/posix/psignal.h,
+ posix/include/rtems/posix/pthread.h,
+ posix/include/rtems/posix/pthreadmp.h,
+ posix/include/rtems/posix/ptimer.h,
+ posix/include/rtems/posix/semaphore.h,
+ posix/include/rtems/posix/semaphoremp.h,
+ posix/include/rtems/posix/threadsup.h,
+ posix/include/rtems/posix/time.h, posix/include/rtems/posix/timer.h,
+ posix/inline/rtems/posix/cond.inl,
+ posix/inline/rtems/posix/intr.inl, posix/inline/rtems/posix/key.inl,
+ posix/inline/rtems/posix/mqueue.inl,
+ posix/inline/rtems/posix/mutex.inl,
+ posix/inline/rtems/posix/priority.inl,
+ posix/inline/rtems/posix/pthread.inl,
+ posix/inline/rtems/posix/semaphore.inl,
+ posix/inline/rtems/posix/timer.inl,
+ posix/macros/rtems/posix/cond.inl,
+ posix/macros/rtems/posix/intr.inl, posix/macros/rtems/posix/key.inl,
+ posix/macros/rtems/posix/mqueue.inl,
+ posix/macros/rtems/posix/mutex.inl,
+ posix/macros/rtems/posix/priority.inl,
+ posix/macros/rtems/posix/pthread.inl,
+ posix/macros/rtems/posix/semaphore.inl,
+ posix/macros/rtems/posix/timer.inl: Add doxygen preamble.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * itron/include/itron.h, itron/include/itronsys/eventflags.h,
+ itron/include/itronsys/fmempool.h, itron/include/itronsys/intr.h,
+ itron/include/itronsys/mbox.h, itron/include/itronsys/msgbuffer.h,
+ itron/include/itronsys/network.h, itron/include/itronsys/port.h,
+ itron/include/itronsys/semaphore.h, itron/include/itronsys/status.h,
+ itron/include/itronsys/sysmgmt.h, itron/include/itronsys/task.h,
+ itron/include/itronsys/time.h, itron/include/itronsys/types.h,
+ itron/include/itronsys/vmempool.h,
+ itron/include/rtems/itron/config.h,
+ itron/include/rtems/itron/eventflags.h,
+ itron/include/rtems/itron/fmempool.h,
+ itron/include/rtems/itron/intr.h,
+ itron/include/rtems/itron/itronapi.h,
+ itron/include/rtems/itron/mbox.h,
+ itron/include/rtems/itron/msgbuffer.h,
+ itron/include/rtems/itron/network.h,
+ itron/include/rtems/itron/object.h,
+ itron/include/rtems/itron/port.h,
+ itron/include/rtems/itron/semaphore.h,
+ itron/include/rtems/itron/sysmgmt.h,
+ itron/include/rtems/itron/task.h, itron/include/rtems/itron/time.h,
+ itron/include/rtems/itron/vmempool.h,
+ itron/inline/rtems/itron/eventflags.inl,
+ itron/inline/rtems/itron/fmempool.inl,
+ itron/inline/rtems/itron/intr.inl,
+ itron/inline/rtems/itron/mbox.inl,
+ itron/inline/rtems/itron/msgbuffer.inl,
+ itron/inline/rtems/itron/network.inl,
+ itron/inline/rtems/itron/port.inl,
+ itron/inline/rtems/itron/semaphore.inl,
+ itron/inline/rtems/itron/sysmgmt.inl,
+ itron/inline/rtems/itron/task.inl,
+ itron/inline/rtems/itron/time.inl,
+ itron/inline/rtems/itron/vmempool.inl,
+ itron/macros/rtems/itron/eventflags.inl,
+ itron/macros/rtems/itron/fmempool.inl,
+ itron/macros/rtems/itron/intr.inl,
+ itron/macros/rtems/itron/mbox.inl,
+ itron/macros/rtems/itron/msgbuffer.inl,
+ itron/macros/rtems/itron/network.inl,
+ itron/macros/rtems/itron/port.inl,
+ itron/macros/rtems/itron/semaphore.inl,
+ itron/macros/rtems/itron/sysmgmt.inl,
+ itron/macros/rtems/itron/task.inl,
+ itron/macros/rtems/itron/time.inl,
+ itron/macros/rtems/itron/vmempool.inl: Add doxygen preamble.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/types.h: Include <rtems/stdint.h>.
+ * librpc/src/rpc/clnt_raw.c, librpc/src/rpc/rpcdname.c,
+ librpc/src/rpc/rtems_portmapper.c, librpc/src/rpc/svc.c,
+ librpc/src/rpc/svc_simple.c: Misc. cast-related fixes.
+ Convert to ANSI.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * librpc/include/rpc/rpc.h (struct _rtems_rpc_task_variables):
+ Use pointers to types instead of void* to avoid casts.
+ * librpc/src/rpc/clnt_perror.c, librpc/src/rpc/clnt_raw.c,
+ librpc/src/rpc/clnt_simple.c, librpc/src/rpc/rpcdname.c,
+ librpc/src/rpc/svc.c, librpc/src/rpc/svc_auth.c,
+ librpc/src/rpc/svc_simple.c:
+ Eliminate lvalue casts gcc-3.4 warns about.
+
+2004-11-20 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libfs/src/dosfs/dosfs.h: Add doxygen preamble.
+ * libfs/src/dosfs/msdos.h: Remove RC_OK.
+ * libfs/src/dosfs/msdos_format.c: Remove unnecessary casts.
+
+2004-11-20 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 720/filesystem:
+ * libfs/src/dosfs/dosfs.h, libfs/src/dosfs/fat.c,
+ libfs/src/dosfs/fat.h, libfs/src/dosfs/msdos_format.c:
+ Adaptations to msdos_format.
+ (From Thomas Doerfler <Thomas.Doerfler@imd-systems.de>).
+
+ * libfs/src/dosfs/dosfs.h, libfs/src/dosfs/fat.c,
+ libfs/src/dosfs/fat.h, libfs/src/dosfs/msdos_format.c:
+ Adaptations to RTEMS-4.7.
+
+2004-11-20 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 720/filesystem:
+ * libfs/src/dosfs/msdos_format.c: New
+ (From Thomas Doerfler <Thomas.Doerfler@imd-systems.de>).
+ * libfs/Makefile.am: Reflect changes above:
+
+2004-11-20 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * libcsupport/include/stdint.h: Move mal-placed comment.
+
+2004-11-10 Joel Sherrill <joel@oarcorp.com>
+
+ * include/rtems/pci.h: BSPs use the name BSP_pci_configuration not pci.
+ Also need to address that this largely duplicates
+ libbsp/powerpc/pci/pci.h but that file is not used when both are
+ included due to the same double inclusion protection.
+
+2004-11-09 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/include/stdint.h: Fixed name in @file.
+
+2004-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/include/sys/_stdint.h: Remove.
+ * libcsupport/include/sys/_inttypes.h: Remove.
+ * libcsupport/include/stdint.h: Replace with former sys/_stdint.h.
+ Add INT<N>_C, various additions.
+ * libcsupport/include/inttypes.h: Replace with former
+ sys/_inttypes.h.
+ * libcsupport/Makefile.am: Reflect changes above.
+
+2004-11-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * backward/asm.h: Add doxygen preamble.
+ * backward/chain.h: Add doxygen preamble.
+ * backward/clockdrv.h: Add doxygen preamble.
+ * backward/confdefs.h: Add doxygen preamble.
+ * backward/console.h: Add doxygen preamble.
+ * backward/dosfs.h: Add doxygen preamble.
+ * backward/imfs.h: Add doxygen preamble.
+ * backward/iosupp.h: Add doxygen preamble.
+ * backward/itron.h: Add doxygen preamble.
+ * backward/ringbuf.h: Add doxygen preamble.
+ * backward/rtc.h: Add doxygen preamble.
+ * backward/spurious.h: Add doxygen preamble.
+ * backward/timerdrv.h: Add doxygen preamble.
+ * backward/vmeintr.h: Add doxygen preamble.
+ * backward/motorola/mc68230.h: Add doxygen preamble.
+ * backward/motorola/mc68681.h: Add doxygen preamble.
+ * backward/zilog/z8030.h: Add doxygen preamble.
+ * backward/zilog/z8036.h: Add doxygen preamble.
+ * backward/zilog/z8536.h: Add doxygen preamble.
+
+2004-11-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * libcsupport/include/sys/_stdint.h: Special-case int64_t (GCC has
+ __LONG_LONG_MAX__, while POSIX mandates LLONG_MAX. This break
+ __EXP(LONG_LONG_MAX)).
+
+2004-11-05 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/machine/endian.h: Protect BYTE_ORDER from double
+ definition.
+
+2004-11-05 Ralf Corsepius <ralf_corsepiu@rtems.org>
+
+ * configure.ac: Remove RTEMS_USES_INTTYPES_H. Require inttypes.h.
+ * include/rtems/stdint.h: Remove "wild guesses", require inttypes.h.
+ * libcsupport/include/inttypes.h: Cleanup.
+ * libcsupport/include/stdint.h: Cleanup.
+
+2004-11-04 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * include/sys/_stdint.h: Various changes.
+ Add *leastN_t types. Add INTN_{MIN|MAX} macros.
+ Add doxygen preamble.
+ * include/sys/_inttypes.h: Add doxygen preamble.
+ Reflect changes above.
+ * libcsupport/include/stdint.h: Add doxygen preamble.
+ * libcsupport/include/inttypes.h: Add doxygen preamble.
+ * configure.ac: Add doxygen preamble to cpuopts.h.
+
+2004-11-02 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/mqueueunlink.c, posix/src/semunlink.c,
+ score/inline/rtems/score/object.inl,
+ score/macros/rtems/score/object.inl: _Objects_Is_local_id() should be
+ avoided in single CPU configurations but always available in the
+ Objects Handlers API.
+
+2004-11-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/include/rtems.h,
+ rtems/inline/rtems/rtems/asr.inl,
+ rtems/inline/rtems/rtems/attr.inl,
+ rtems/inline/rtems/rtems/dpmem.inl,
+ rtems/inline/rtems/rtems/event.inl,
+ rtems/inline/rtems/rtems/eventset.inl,
+ rtems/inline/rtems/rtems/message.inl,
+ rtems/inline/rtems/rtems/modes.inl,
+ rtems/inline/rtems/rtems/options.inl,
+ rtems/inline/rtems/rtems/part.inl,
+ rtems/inline/rtems/rtems/ratemon.inl,
+ rtems/inline/rtems/rtems/region.inl,
+ rtems/inline/rtems/rtems/sem.inl,
+ rtems/inline/rtems/rtems/status.inl,
+ rtems/inline/rtems/rtems/support.inl,
+ rtems/inline/rtems/rtems/tasks.inl,
+ rtems/inline/rtems/rtems/timer.inl,
+ rtems/macros/rtems/rtems/asr.inl,
+ rtems/macros/rtems/rtems/attr.inl,
+ rtems/macros/rtems/rtems/dpmem.inl,
+ rtems/macros/rtems/rtems/event.inl,
+ rtems/macros/rtems/rtems/eventset.inl,
+ rtems/macros/rtems/rtems/message.inl,
+ rtems/macros/rtems/rtems/modes.inl,
+ rtems/macros/rtems/rtems/options.inl,
+ rtems/macros/rtems/rtems/part.inl,
+ rtems/macros/rtems/rtems/ratemon.inl,
+ rtems/macros/rtems/rtems/region.inl,
+ rtems/macros/rtems/rtems/sem.inl,
+ rtems/macros/rtems/rtems/status.inl,
+ rtems/macros/rtems/rtems/support.inl,
+ rtems/macros/rtems/rtems/tasks.inl,
+ rtems/macros/rtems/rtems/timer.inl: Add doxygen preamble.
+
+2004-11-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/include/rtems.h,
+ rtems/include/rtems/rtems/asr.h,
+ rtems/include/rtems/rtems/attr.h,
+ rtems/include/rtems/rtems/cache.h,
+ rtems/include/rtems/rtems/clock.h,
+ rtems/include/rtems/rtems/config.h,
+ rtems/include/rtems/rtems/dpmem.h,
+ rtems/include/rtems/rtems/event.h,
+ rtems/include/rtems/rtems/eventmp.h,
+ rtems/include/rtems/rtems/eventset.h,
+ rtems/include/rtems/rtems/intr.h,
+ rtems/include/rtems/rtems/message.h,
+ rtems/include/rtems/rtems/modes.h,
+ rtems/include/rtems/rtems/mp.h,
+ rtems/include/rtems/rtems/msgmp.h,
+ rtems/include/rtems/rtems/options.h,
+ rtems/include/rtems/rtems/part.h,
+ rtems/include/rtems/rtems/partmp.h,
+ rtems/include/rtems/rtems/ratemon.h,
+ rtems/include/rtems/rtems/region.h,
+ rtems/include/rtems/rtems/regionmp.h,
+ rtems/include/rtems/rtems/rtemsapi.h,
+ rtems/include/rtems/rtems/sem.h,
+ rtems/include/rtems/rtems/semmp.h,
+ rtems/include/rtems/rtems/signal.h,
+ rtems/include/rtems/rtems/signalmp.h,
+ rtems/include/rtems/rtems/status.h,
+ rtems/include/rtems/rtems/support.h,
+ rtems/include/rtems/rtems/taskmp.h,
+ rtems/include/rtems/rtems/tasks.h,
+ rtems/include/rtems/rtems/timer.h,
+ rtems/include/rtems/rtems/types.h: Add doxygen preamble.
+
+2004-11-01 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/monitor/mon-manager.c, libmisc/monitor/mon-object.c: Remove
+ references to _Object_Is_local in single processor configurations.
+
+2004-11-01 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/coresemsurrender.c, score/src/objectnametoid.c: All
+ _Objects_Is_Local... should only be called if multiprocessing is
+ enabled.
+
+2004-11-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/include/rtems/rtems/tasks.h, rtems/src/taskstart.c:
+ rtems_task_start(..., rtems_task_argument argument );
+
+2004-11-01 Joel Sherrill <joel@oarcorp.com>
+
+ * score/cpu/no_cpu/rtems/score/cpu.h, score/include/rtems/debug.h,
+ score/include/rtems/seterr.h, score/include/rtems/system.h,
+ score/include/rtems/score/address.h,
+ score/include/rtems/score/apiext.h,
+ score/include/rtems/score/apimutex.h,
+ score/include/rtems/score/bitfield.h,
+ score/include/rtems/score/chain.h,
+ score/include/rtems/score/context.h,
+ score/include/rtems/score/copyrt.h,
+ score/include/rtems/score/coremsg.h,
+ score/include/rtems/score/coremutex.h,
+ score/include/rtems/score/coresem.h,
+ score/include/rtems/score/heap.h, score/include/rtems/score/interr.h,
+ score/include/rtems/score/isr.h, score/include/rtems/score/mpci.h,
+ score/include/rtems/score/mppkt.h,
+ score/include/rtems/score/objectmp.h,
+ score/include/rtems/score/priority.h,
+ score/include/rtems/score/stack.h,
+ score/include/rtems/score/states.h,
+ score/include/rtems/score/sysstate.h,
+ score/include/rtems/score/thread.h,
+ score/include/rtems/score/threadmp.h,
+ score/include/rtems/score/threadq.h, score/include/rtems/score/tod.h,
+ score/include/rtems/score/tqdata.h,
+ score/include/rtems/score/userext.h,
+ score/include/rtems/score/watchdog.h,
+ score/include/rtems/score/wkspace.h,
+ score/inline/rtems/score/address.inl,
+ score/inline/rtems/score/chain.inl,
+ score/inline/rtems/score/coremsg.inl,
+ score/inline/rtems/score/coremutex.inl,
+ score/inline/rtems/score/coresem.inl,
+ score/inline/rtems/score/heap.inl, score/inline/rtems/score/isr.inl,
+ score/inline/rtems/score/mppkt.inl,
+ score/inline/rtems/score/objectmp.inl,
+ score/inline/rtems/score/priority.inl,
+ score/inline/rtems/score/stack.inl,
+ score/inline/rtems/score/states.inl,
+ score/inline/rtems/score/sysstate.inl,
+ score/inline/rtems/score/thread.inl,
+ score/inline/rtems/score/threadmp.inl,
+ score/inline/rtems/score/tod.inl,
+ score/inline/rtems/score/tqdata.inl,
+ score/inline/rtems/score/userext.inl,
+ score/inline/rtems/score/watchdog.inl,
+ score/inline/rtems/score/wkspace.inl: Add Doxygen comments -- working
+ modifications which are not complete and may have broken code.
+ Committing so work and testing can proceed.
+ * score/Doxyfile, score/mainpage.h: New files.
+
+2004-11-01 Joel Sherrill <joel@oarcorp.com>
+
+ * score/include/rtems/score/object.h,
+ score/inline/rtems/score/object.inl,
+ score/macros/rtems/score/object.inl: Add first cut of optional
+ 16 bit object Id as space reduction for small systems (TinyRTEMS).
+
+2004-11-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * monitor/monitor.h: Let rtems_monitor_config_dump return int.
+ * monitor/mon-config.c: Ditto. Use PRI*N macros.
+ * monitor/mon-itask.c, monitor/mon-prmisc.c: Use PRI*N macros.
+
+2004-11-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libmisc/monitor/monitor.h: Let rtems_monitor_config_dump return int.
+ * libmisc/monitor/mon-config.c: Ditto. Use PRI*N macros.
+ * libmisc/monitor/mon-itask.c, libmisc/monitor/mon-prmisc.c: Use
+ PRI*N macros.
+
+2004-11-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Remove -ansi (Cygwin breaks with it).
+ * libcsupport/include/stdint.h: Use sys/_stdint.h to setup fixed
+ size types.
+ * libcsupport/include/sys/_inttypes.h: Add SCN*N macros.
+
+2004-11-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/src/utsname.c: Revert yesterdays patch.
+
+2004-10-31 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/src/utsname.c: Fix typo.
+
+2004-10-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * score/src/coremsg.c: Eliminate unsigned32.
+ * score/include/rtems/system.h: Set __RTEMS_REVISION__ to 99.
+ * librpc/include/rpc/xdr.h: Use elipsis in xdrproc_t prototype.
+
+2004-10-28 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/include/inttypes.h: #include <sys/_inttypes.h>
+ * libcsupport/src/utsname.c: Don't include sptables.h.
+ Include <inttypes.h>. Use PRId32 instead of "%d".
+
+2004-10-28 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/include/rtems/_inttypes.h: Remove.
+ * libcsupport/include/rtems/_stdint.h: Remove.
+ * libcsupport/include/sys/_inttypes.h: New.
+ * libcsupport/include/sys/_stdint.h: New.
+ * libcsupport/Makefile.am: Reflect changes above.
+ * configure.ac: Reflect changes above.
+
+2004-10-28 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Remove RTEMS_CPUOPT([RTEMS_MULTILIBS],..).
+ (Unused).
+
+2004-10-27 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libmisc/monitor/mon-prmisc.c, libmisc/monitor/monitor.h: Let rtems_monitor_dump
+ return int's not uint32_t (They are printf return values).
+
+2004-10-27 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Add score/cpu/no_cpu/Makefile.
+
+2004-10-27 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am, configure.ac: Add httpd.
+ * httpd/asp.c, httpd/balloc.c, httpd/cgi.c, httpd/default.c,
+ httpd/ej.h, httpd/ejIntrn.h, httpd/ejlex.c, httpd/ejparse.c,
+ httpd/emfdb.c, httpd/emfdb.h, httpd/form.c, httpd/handler.c,
+ httpd/h.c, httpd/license.txt, httpd/Makefile.am, httpd/md5c.c,
+ httpd/md5.h, httpd/mime.c, httpd/misc.c, httpd/NOTES, httpd/ringq.c,
+ httpd/rom.c, httpd/rtems_webserver.h, httpd/security.c,
+ httpd/sock.c, httpd/socket.c, httpd/sockGen.c, httpd/sym.c,
+ httpd/uemf.c, httpd/uemf.h, httpd/um.c, httpd/um.h, httpd/umui.c,
+ httpd/url.c, httpd/value.c, httpd/wbase64.c, httpd/webcomp.c,
+ httpd/webmain.c, httpd/webpage.c, httpd/webrom.c, httpd/webs.c,
+ httpd/websda.c, httpd/websda.h, httpd/webs.h, httpd/websSSL.c,
+ httpd/websSSL.h, httpd/websuemf.c, httpd/wsIntrn.h: New (Moved from
+ c/src/libnetworking/rtems_webserver).
+ * httpd/Makefile.am: Install libhttpd.a.
+
+2004-10-26 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/include/rtems/_inttypes.h: Undefine __PRIN defines.
+ * libcsupport/include/rtems/_stdint.h: Apply GNUC-limits to GCC >= 3.3, only.
+ Add _rtems_*_t_defined defines. Add extern "C".
+
+2004-10-26 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/include/rtems/_stdint.h: New.
+ * libcsupport/include/rtems/_inttypes.h: New.
+ * libcsupport/Makefile.am: Reflect changes above.
+
+2004-10-26 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libfs/src/dosfs/msdos_conv.c:
+ Replace BSD fixed-size types with POSIX fixed-size types.
+ Replace SECONDSTO1980 with DAYSTO1980.
+ Make macros 16bit clean.
+
+2004-10-26 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/include/sys/ioccom.h: Cosmetical update from FreeBSD.
+ * libcsupport/include/sys/ioctl.h: Cosmetical update from FreeBSD.
+ Remove sys/compat_ioctl.h section (Meaningless with RTEMS).
+
+2004-10-25 Eric Norum <norume@aps.anl.gov>
+
+ * libnetworking/net/if_ethersubr.c: Working version of ether_sprintf().
+ * cpukit/librpc/include/rpc/xdr.h: No kernel/user distinction.
+
+2004-10-22 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/Makefile.am: Reflect changes below.
+ * libnetworking/net/slcompress.h: New (from FreeBSD).
+ * libnetworking/net/slcompress.c: New (from FreeBSD).
+
+2004-10-22 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/include/stdint.h: Add intptr_t uintptr_t.
+ * libnetworking/kern/kern_sysctl.c: Remove uintptr_t.
+ Cosmetics.
+ * libnetworking/opt_compat.h: New.
+
+2004-10-22 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/opt_atalk.h, libnetworking/opt_bdg.h,
+ libnetworking/opt_inet.h, libnetworking/opt_inet6.h,
+ libnetworking/opt_ipx.h, libnetworking/opt_mac.h,
+ libnetworking/opt_netgraph.h: New (Stubs).
+ * libnetworking/net/if_loop.c: Cosmetical update from FreeBSD.
+ * libnetworking/net/if_ethersubr.c: Update from FreeBSD.
+ * libnetworking/net/if.h: Update from FreeBSD.
+
+2004-10-21 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/net/ethernet.h: Remove BYTE_PACK.
+
+2004-10-21 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/net/if.h; Cosmetical updates from FreeBSD.
+ Remove if_poll* (Not implemented in RTEMS, abandoned by FreeBSD).
+ * libnetworking/net/if_ethersubr.c: Cosmetical updates from FreeBSD.
+ Add ether_sprintf.
+ * libnetworking/net/ethernet.h: Update from FreeBSD.
+
+2004-10-21 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libmisc/monitor/mon-prmisc.c, libmisc/monitor/monitor.h:
+ rtems_monitor_dump_char(char ch).
+
+2004-10-20 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * automake/compile.am: Remove RTEMS_CFLAGS_*_V.
+
+2004-10-15 Joel Sherrill <joel@OARcorp.com>
+
+ PR 692/rtems
+ * rtems/src/regiongetsegment.c, rtems/src/regionreturnsegment.c: The
+ Region Manager did not follow the proper protocol when blocking and
+ unblocking tasks waiting on buffers. This was a bug introduced with
+ the transition to an Allocation Mutex.
+
+2004-09-29 Joel Sherrill <joel@OARcorp.com>
+
+ * configure.ac, libmisc/cpuuse/README, libmisc/stackchk/README,
+ librpc/src/xdr/xdr_float.c, score/cpu/Makefile.am,
+ score/include/rtems/score/mppkt.h: i960 obsoleted and all references
+ removed.
+
+2004-09-29 Joel Sherrill <joel@OARcorp.com>
+
+ * score/cpu/i960/.cvsignore, score/cpu/i960/ChangeLog,
+ score/cpu/i960/Makefile.am, score/cpu/i960/asm.h,
+ score/cpu/i960/cpu.c, score/cpu/i960/cpu_asm.S,
+ score/cpu/i960/rtems/score/cpu.h, score/cpu/i960/rtems/score/i960.h,
+ score/cpu/i960/rtems/score/types.h: Removed.
+
+2004-09-27 Joel Sherrill <joel@OARcorp.com>
+
+ PR 294/rtems
+ * posix/src/pthread.c: POSIX thread exit handler now confirms that it
+ created the executing thread before implicitly exitting it.
+
+2004-09-27 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/stackchk/check.c: Spacing.
+
+2004-09-24 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Require automake > 1.9.
+
+2004-09-24 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Add score/cpu/avr/Makefile.am.
+ * score/cpu/Makefile.am: Add avr.
+ * libnetworking/Makefile.am: Don't include subdirs.am.
+
+2004-09-23 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * librpc/src/xdr/xdr_float.c: Add __AVR__.
+
+2004-09-21 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * aclocal/gcc-weak.m4: New (Extracted from cpukit/configure.ac).
+ * configure.ac: Add RTEMS_CHECK_GCC_WEAK.
+
+2004-09-17 Joel Sherrill <joel@OARcorp.com>
+
+ PR 677/misc
+ * libmisc/dumpbuf/dumpbuf.h, libmisc/fsmount/fsmount.h,
+ libmisc/rtmonuse/rtmonuse.h, libmisc/serdbg/serdbg.h,
+ libmisc/serdbg/serdbgcnf.h, libmisc/serdbg/termios_printk.h,
+ libmisc/serdbg/termios_printk_cnf.h, libmisc/untar/untar.h: Add
+ extern C wrappers.
+
+2004-09-17 Till Strauman <strauman@slac.stanford.edu>
+
+ PR 676/networking
+ * libnetworking/nfs/bootp_subr.c: /etc/resolv.conf contains NTP instead
+ of DNS servers.
+
+2004-08-18 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ PR 673/make_build
+ * aclocal/rtems-top.m4 (RTEMS_TOP): Add further quotes.
+
+2004-07-28 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-4.6.99.1.
+
+2004-07-25 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 620/networking
+ * libnetworking/lib/rtems_bsdnet_ntp.c,
+ libnetworking/rtems/rtems_bsdnet.h: Enhance NTP API.
+
+2004-07-25 Thomas Rauscher <trauscher@loytec.com>
+
+ PR 609/rtems
+ * score/src/threaddispatch.c: Close race condition between
+ _Thread_Dispatch and _Thread_Tickle_timeslice.
+
+2004-07-25 Victor Vengerov <Victor.Vengerov@oktetlabs.ru>
+
+ PR 654/rtems
+ * score/src/threadinitialize.c: Initialize the per thread watchdog
+ timer. When the thread control block is reused, we cannot depend on
+ it being zeroed.
+
+2004-07-24 Mick Davis <mickd@microsol.iinet.net.au>
+
+ PR 641/rtems
+ * rtems/src/eventsurrender.c: The problem here is that events may be
+ lost when sent to a task which enters rtems_event_receive() with options
+ set to wait with a timeout and to return on receipt of any event. The
+ events are sent from an interrupt source such as a timer service
+ routine. If more than one set of events is sent to the task before it
+ returns, the first event set may be overwritten.
+
+2004-07-24 Joel Sherrill <joel@OARcorp.com>
+
+ PR 661/rtems
+ * score/src/objectmp.c: Fix invalid dereference.
+
+2004-07-24 Joel Sherrill <joel@OARcorp.com>
+
+ PR 660/rtems
+ * score/cpu/m68k/rtems/score/m68k.h, score/cpu/mips/cpu_asm.S,
+ score/src/threadinitialize.c, score/src/threadstackallocate.c: Check
+ for overflow when allocating stack.
+
+2004-07-24 Joel Sherrill <joel@OARcorp.com>
+
+ PR 659/rtems
+ * score/src/heapsizeofuserarea.c: Check that address specified is in
+ the heap.
+
+2004-07-24 Joel Sherrill <joel@OARcorp.com>
+
+ PR 652/rtems
+ * rtems/src/signalsend.c: Return RTEMS_INVALID_NUMBER when sending an
+ empty signal set.
+
+2004-07-14 Joel Sherrill <joel@OARcorp.com>
+
+ PR 650/rtems
+ * score/src/coremsg.c: Check for mathemathical overflow when calculating
+ amount of memory to allocate for message buffers.
+
+2004-07-14 Joel Sherrill <joel@OARcorp.com>
+
+ PR 651/core
+ * rtems/src/taskident.c: Add NULL check for id.
+
+2004-06-29 Joel Sherrill <joel@OARcorp.com>
+
+ PR 631/rtems
+ * rtems/src/msgqcreate.c: Return unsatisfied from message_queue_create
+ when unable to allocate message buffer memory.
+
+2004-05-21 Joel Sherrill <joel@OARcorp.com>
+
+ PR 628/rtems
+ * posix/src/killinfo.c, posix/src/pthreadkill.c, posix/src/ptimer1.c,
+ posix/src/sigaction.c, posix/src/sigaddset.c, posix/src/sigsuspend.c:
+ Signal set of 0 is supposed to return EINVAL. In addition
+ timer_create needed to return an error if the clock was not
+ CLOCK_REALTIME.
+
+2004-05-21 Joel Sherrill <joel@OARcorp.com>
+
+ PR 629/rtems
+ * cpukit/src/mqueuecreatesupp.c: Return EINVAL is mq_maxmsg is
+ <= 0, not <.
+
+2004-05-21 Till Strauman <strauman@slac.stanford.edu>
+
+ PR 626/networking
+ * libnetworking/rtems/rtems_showifstat.c: Use unsigned char to avoid
+ printing leading FFFFFF for byte values > 127.
+
+2004-05-06 Joel Sherrill <joel@OARcorp.com>
+
+ PR 618/rtems
+ * rtems/include/rtems/rtems/status.h, rtems/src/clockget.c,
+ rtems/src/clockset.c, rtems/src/dpmemcreate.c,
+ rtems/src/dpmemexternal2internal.c,
+ rtems/src/dpmeminternal2external.c, rtems/src/eventmp.c,
+ rtems/src/eventreceive.c, rtems/src/eventsend.c,
+ rtems/src/msgqbroadcast.c, rtems/src/msgqcreate.c,
+ rtems/src/msgqflush.c, rtems/src/msgqgetnumberpending.c,
+ rtems/src/msgqreceive.c, rtems/src/msgqsubmit.c,
+ rtems/src/partcreate.c, rtems/src/partdelete.c,
+ rtems/src/partgetbuffer.c, rtems/src/ratemoncancel.c,
+ rtems/src/ratemoncreate.c, rtems/src/ratemondelete.c,
+ rtems/src/ratemongetstatus.c, rtems/src/ratemonident.c,
+ rtems/src/ratemonperiod.c, rtems/src/regioncreate.c,
+ rtems/src/regiondelete.c, rtems/src/regionextend.c,
+ rtems/src/regiongetsegment.c, rtems/src/regiongetsegmentsize.c,
+ rtems/src/regionreturnsegment.c, rtems/src/semcreate.c,
+ rtems/src/semdelete.c, rtems/src/semflush.c, rtems/src/semident.c,
+ rtems/src/taskcreate.c, rtems/src/taskgetnote.c,
+ rtems/src/taskmode.c, rtems/src/taskrestart.c,
+ rtems/src/taskresume.c, rtems/src/tasksetnote.c,
+ rtems/src/tasksuspend.c, rtems/src/taskvariableadd.c,
+ rtems/src/taskvariabledelete.c, rtems/src/taskvariableget.c,
+ rtems/src/taskwakewhen.c, rtems/src/timercreate.c,
+ rtems/src/timerdelete.c, rtems/src/timerfireafter.c,
+ rtems/src/timerfirewhen.c, rtems/src/timerserverfireafter.c,
+ rtems/src/timerserverfirewhen.c, score/include/rtems/score/object.h,
+ score/src/coretodvalidate.c, score/src/objectnametoid.c: Add NULL
+ checks.
+
+2004-04-30 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/kern/kern_sysctl.c: sysctl_register_all cannot be
+ static with RTEMS.
+
+2004-04-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/netinet/in.c: Partial update from FreeBSD.
+
+2004-04-26 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/kern/kern_sysctl.c: Partial updates from FreeBSD.
+
+2004-04-26 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/netinet/igmp_var.h: Cosmetic updates from FreeBSD.
+ * libnetworking/sys/sysctl.h: Update from FreeBSD.
+ * libnetworking/sys/socketvar.h: Update from FreeBSD.
+
+2004-04-24 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/sys/protosw.h: More partial updates from FreeBSD.
+
+2004-04-24 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/net/route.c: Reflect changes to radix.h.
+
+2004-04-22 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/net/radix.h, libnetworking/net/radix.c: Partial
+ update from FreeBSD.
+
+2004-04-22 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/sys/socket.h: Further update from FreeBSD
+ (Add sa_family_t).
+
+2004-04-22 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/sys/protosw.h: Partial update from FreeBSD.
+ * libnetworking/sys/socket.h: Partial update from FreeBSD.
+ * libnetworking/rtems/rtems_syscall.c: Reflect changes to socket.h.
+
+2004-04-22 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/kern/uipc_socket.c: Partial update from FreeBSD
+ (Remove adv-clause from copyright notice).
+ * libnetworking/netinet/igmp_var.h: Partial update from FreeBSD.
+
+2004-04-20 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/net/bpf.h, libnetworking/net/if.h,
+ libnetworking/net/if_dl.h, libnetworking/net/if_ppp.h,
+ libnetworking/net/netisr.h, libnetworking/net/pppcompress.c,
+ libnetworking/net/radix.c, libnetworking/net/radix.h,
+ libnetworking/net/raw_cb.h, libnetworking/net/route.h,
+ libnetworking/netinet/icmp_var.h, libnetworking/netinet/if_ether.h,
+ libnetworking/netinet/igmp_var.h, libnetworking/netinet/in.h,
+ libnetworking/netinet/in_pcb.h, libnetworking/netinet/in_systm.h,
+ libnetworking/netinet/in_var.h, libnetworking/netinet/ip_fw.h,
+ libnetworking/netinet/ip_icmp.h, libnetworking/netinet/ip_mroute.h,
+ libnetworking/netinet/ip_var.h, libnetworking/netinet/tcp_debug.h,
+ libnetworking/netinet/tcp_seq.h, libnetworking/netinet/tcp_timer.h,
+ libnetworking/netinet/tcp_var.h, libnetworking/netinet/udp_var.h,
+ libnetworking/nfs/nfs.h, libnetworking/rtems/rtems_bsdnet.h,
+ libnetworking/rtems/rtems_bsdnet_internal.h,
+ libnetworking/sys/buf.h, libnetworking/sys/callout.h,
+ libnetworking/sys/conf.h, libnetworking/sys/domain.h,
+ libnetworking/sys/malloc.h, libnetworking/sys/mbuf.h,
+ libnetworking/sys/mount.h, libnetworking/sys/protosw.h,
+ libnetworking/sys/queue.h, libnetworking/sys/rtprio.h,
+ libnetworking/sys/select.h, libnetworking/sys/signalvar.h,
+ libnetworking/sys/socket.h, libnetworking/sys/socketvar.h,
+ libnetworking/sys/sysctl.h, libnetworking/sys/syslog.h,
+ libnetworking/sys/ucred.h, libnetworking/sys/uio.h,
+ libnetworking/vm/vm.h, libnetworking/vm/vm_extern.h,
+ libnetworking/vm/vm_param.h: Use -D_KERNEL instead of -DKERNEL for
+ greater FreeBSD compliance.
+
+2004-04-20 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/Makefile.am: Add -D_KERNEL to CPPFLAGS.
+
+2004-04-20 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/net/bpf.h: Partial update from FreeBSD.
+
+2004-04-19 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/sys/sysctl.h: Partial update from FreeBSD.
+ * libnetworking/kern/kern_sysctl.c: Partial update from FreeBSD.
+
+2004-04-17 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libfs/src/imfs/imfs_debug.c, libfs/src/imfs/memfile.c:
+ Use fprintf(stdout,...) instead of printf.
+
+2004-04-17 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libblock/src/ide_part_table.c: Use fprintf(stdout,...) instead of
+ printf.
+
+2004-04-17 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libmisc/capture/capture-cli.c, libmisc/cpuuse/cpuuse.c,
+ libmisc/dumpbuf/dumpbuf.c, libmisc/fsmount/fsmount.c,
+ libmisc/monitor/mon-command.c, libmisc/monitor/mon-config.c,
+ libmisc/monitor/mon-dname.c, libmisc/monitor/mon-driver.c,
+ libmisc/monitor/mon-extension.c, libmisc/monitor/mon-itask.c,
+ libmisc/monitor/mon-monitor.c, libmisc/monitor/mon-mpci.c,
+ libmisc/monitor/mon-object.c, libmisc/monitor/mon-prmisc.c,
+ libmisc/monitor/mon-queue.c, libmisc/monitor/mon-symbols.c,
+ libmisc/monitor/mon-task.c, libmisc/rtmonuse/rtmonuse.c,
+ libmisc/shell/cmds.c, libmisc/shell/shell.c, libmisc/shell/shell.h,
+ libmisc/stackchk/check.c, libmisc/untar/untar.c: Use
+ fprintf(stdout,...) instead of printf.
+
+2004-04-14 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * sapi/include/rtems/sptables.h: Remove _RTEMS_version.
+
+2004-04-14 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/Makefile.am: Install include_sys_HEADERS for NEWLIB
+ only. Merge sys/cdefs.h into general include_sys_HEADERS.
+
+2004-04-13 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/include/rtems/rtems/types.h: Include <rtems/stdint.h>
+ instead of <stdint.h>.
+ Conditionally typedef rtems*signed64 types.
+ * score/include/rtems/system.h: Include <rtems/stdint.h> instead of
+ <stdint.h>.
+
+2004-04-13 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Rework stdint.h/inttypes.h support.
+ Add RTEMS_USES_STDINT_H. Add RTEMS_USES_INTTYPES_H.
+ Remove NEED_STDINT_H. Remove NEED_INTTYPES_H.
+ Remove termios-flag detection.
+ * libcsupport/Makefile.am: Install include/stdint.h and
+ include/inttypes.h for NEWLIB only.
+ * libcsupport/include/stdint.h: Rework; Now newlib specific.
+ * libcsupport/src/termios.c: Make newlib specific.
+ * include/rtems/stdint.h: Rework; Now wrapper to <stdint.h>.
+
+2004-04-12 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * acinclude.m4 (RTEMS_CPUOPT): Use AC_DEFINE_UNQUOTED.
+ * backward/motorola/mc68681.h, backward/motorola/mc68230.h,
+ backward/zilog/z8536.h, backward/zilog/z8036.h,
+ backward/zilog/z8030.h: New.
+ * Makefile.am: Reflect having added new files above.
+
+2004-04-09 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * wrapup/Makefile.am: Add libblock for !UNIX only.
+
+2004-04-09 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libblock/Makefile.am: Build libblock for !UNIX only.
+ * libcsupport/Makefile.am: Build $(TERMIOS_C_FILES) for !UNIX only.
+
+2004-04-09 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libblock/Makefile.am: Remove LIBC_DEFINES (Unsupported).
+ * libfs/Makefile.am: Remove LIBC_DEFINES (Unsupported).
+
+2004-04-08 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/Makefile.am: Install sys/ioccom.h for NEWLIB only.
+
+2004-04-08 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/Makefile.am: Remove $(LIBC_DEFINES) (Unsupported).
+ Install motorola-headers to $(includedir)/rtems/motorola.
+ Install zilog-headers to $(includedir)/rtems/zilog.
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * score/cpu/Makefile.am: Add unix to DIST_SUBDIRS.
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * aclocal/rtems-cpu-subdirs.m4: Remove (Unused).
+ * configure.ac: Remove RTEMS_CPU_SUBDIRS([score/cpu]).
+ Add RTEMS_CHECK_SYSV_UNIX.
+ Add score/cpu/*/Makefile.
+ * score/cpu/Makefile.am: Add DIST_SUBDIRS.
+
+2004-04-05 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Add AC_CHECK_SIZEOF([CPU_CONTEXT]..).
+ Add SIZEOF_CPU_CONTEXT to cpuopts.h.
+ Add RTEMS_PROG_CCAS.
+ * acinclude.m4: Use unquoted "here" document to propagate $3 to
+ cpuopts.tmp.
+
+2004-04-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/Makefile.am: AM_CPPFLAGS += -I$(srcdir).
+ * libnetworking/rtems/rtems_bsdnet_internal.h: Remove USHRT_MAX.
+
+2004-04-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/Makefile.am: Fix typo.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/poll.h: Replace with sys/poll.h wrapper.
+ * libnetworking/sys/poll.h: New (Original FreeBSD file).
+ * libnetworking/Makefile.am: Don't install opt_ipfw.h,
+ opt_mrouting.h, opt_tcpdebug.h. Add sys/poll.h.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libmisc/serdbg/serdbgcnf.h: Include <rtems/serdbg.h> instead of
+ <serdbg.h>
+ * libmisc/serdbg/termios_printk_cnf.h: Include <rtems/termios_printk.h>
+ instead of <termios_printk.h>.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libmisc/Makefile.am: Install serdbg.h, serdbgcnf.h,
+ termios_printk.h, termios_printk_cnf.h to $(includedir)/rtems.
+ * libmisc/serdbg/serdbg.c: Include <rtems/serdbg.h> instead of
+ <serdbg.h>.
+ * libmisc/serdbg/serdbgio.c: Include <rtems/serdbg.h> instead of
+ <serdbg.h>.
+ * libmisc/serdbg/termios_printk.c: Include <rtems/termios_printk.h>
+ instead of <termios_printk.h>.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libmisc/dummy/dummy.c: Include <rtems/confdefs.h> instead of <confdefs.h>.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * backward/confdefs.h: New.
+ * Makefile.am: Add backward/confdefs.h.
+ Add conditional DEPRECATED.
+ * configure.ac: Add --enable-deprecated.
+ Add conditional DEPRECATED.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * sapi/Makefile.am: Install confdefs.h to $(includedir)/rtems.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Add backward/*.h headers.
+ * itron/Makefile.am: Install itron.h to $(includedir)/rtems.
+ * libcsupport/Makefile.am: Install RTEMS specific headers to
+ $(includedir)/rtems.
+ * libfs/Makefile.am: Install imfs.h and dosfs.h to
+ $(includedir)/rtems.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libblock/include/rtems/bdbuf.h: Include <rtems/chain.h> instead of <chain.h>.
+ * libblock/include/rtems/ide_part_table.h: Include <rtems/chain.h> instead of <chain.h>.
+ * libcsupport/src/malloc.c: Include <rtems/chain.h> instead of <chain.h>.
+ * libcsupport/src/mount.c: Include <rtems/chain.h> instead of <chain.h>.
+ * libcsupport/src/unmount.c: Include <rtems/chain.h> instead of <chain.h>.
+ * libfs/src/imfs/imfs.h: Include <rtems/chain.h> instead of <chain.h>.
+ * libfs/src/imfs/imfs_directory.c: Include <rtems/chain.h> instead of <chain.h>.
+ * libfs/src/imfs/imfs_load_tar.c: Include <rtems/chain.h> instead of <chain.h>.
+ * sapi/include/confdefs.h: Include <rtems/clockdrv.h> instead of <clockdrv.h>.
+ * sapi/include/confdefs.h: Include <rtems/console.h> instead of <console.h>.
+ * libfs/src/imfs/imfs_load_tar.c: Include <rtems/imfs.h> instead of <imfs.h>.
+ * libmisc/shell/cmds.c: Include <rtems/imfs.h> instead of <imfs.h>.
+ * libmisc/fsmount/fsmount.c: Include <rtems/imfs.h> instead of <imfs.h>.
+ * sapi/include/confdefs.h: Include <rtems/imfs.h> instead of <imfs.h>.
+ * itron/src/can_wup.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/chg_pri.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/cre_mbf.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/cre_mbx.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/cre_sem.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/cre_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/del_mbf.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/del_mbx.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/del_sem.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/del_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/dis_dsp.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/ena_dsp.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/eventflags.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/exd_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/ext_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/fmempool.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/frsm_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/get_tid.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/itronintr.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/itronsem.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/itrontime.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/mbox.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/mboxtranslatereturncode.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/msgbuffer.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/msgbuffertranslatereturncode.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/network.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/port.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/prcv_mbf.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/prcv_mbx.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/preq_sem.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/psnd_mbf.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/rcv_mbf.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/rcv_mbx.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/ref_mbf.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/ref_mbx.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/ref_sem.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/ref_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/rel_wai.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/rot_rdq.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/rsm_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/sig_sem.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/slp_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/snd_mbf.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/snd_mbx.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/sta_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/sus_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/sysmgmt.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/task.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/ter_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/trcv_mbf.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/trcv_mbx.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/tslp_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/tsnd_mbf.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/twai_sem.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/vmempool.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/wai_sem.c: Include <rtems/itron.h> instead of <itron.h>.
+ * itron/src/wup_tsk.c: Include <rtems/itron.h> instead of <itron.h>.
+ * sapi/include/rtems/config.h: Include <rtems/itron.h> instead of <itron.h>.
+ * sapi/include/confdefs.h: Include <rtems/itron.h> instead of <itron.h>.
+ * sapi/src/itronapi.c: Include <rtems/itron.h> instead of <itron.h>.
+ * sapi/include/confdefs.h: Include <rtems/rtc.h> instead of <rtc.h>.
+ * sapi/include/confdefs.h: Include <rtems/timerdrv.h> instead of <timerdrv.h>.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * backward/asm.h, backward/chain.h, backward/clockdrv.h,
+ backward/console.h, backward/dosfs.h, backward/imfs.h,
+ backward/iosupp.h, backward/itron.h, backward/ringbuf.h,
+ backward/rtc.h, backward/spurious.h, backward/timerdrv.h,
+ backward/vmeintr.h: New.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/include/rtems/rtems/region.h:
+ Include stddef.h for size_t.
+ (rtems_region_get_segment_size): Use size_t instead of uint32_t for "size" (3rd arg).
+ * rtems/src/regiongetsegmentsize.c: Reflect changes above.
+ * libcsupport/src/malloc.c: Reflect changes above.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * aclocal/rtems-top.m4: Don't AC_SUBST(PROJECT_ROOT).
+ Add project_libdir, project_include and libdir.
+ * aclocal/env-rtemscpu.m4: Remove all references to RTEMS_BSP.
+ Remove project_libdir, project_include and libdir.
+ Unconditionally use CPU_CFLAGS, CFLAGS_OPTIMIZE_V, CFLAGS_DEBUG_V.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libnetworking/lib/ftpfs.c, libnetworking/lib/rtems_bsdnet_ntp.c,
+ libnetworking/lib/tftpDriver.c, libnetworking/machine/endian.h,
+ libnetworking/net/if_ppp.c, libnetworking/rtems/rtems_bsdnet.h,
+ libnetworking/rtems/rtems_bsdnet_internal.h,
+ libnetworking/rtems/rtems_glue.c,
+ libnetworking/rtems/rtems_syscall.c: Convert to using c99 fixed size
+ types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * score/include/rtems/debug.h, score/include/rtems/score/bitfield.h,
+ score/include/rtems/score/chain.h,
+ score/include/rtems/score/coremsg.h,
+ score/include/rtems/score/coremutex.h,
+ score/include/rtems/score/coresem.h,
+ score/include/rtems/score/heap.h,
+ score/include/rtems/score/interr.h, score/include/rtems/score/isr.h,
+ score/include/rtems/score/mpci.h, score/include/rtems/score/mppkt.h,
+ score/include/rtems/score/object.h,
+ score/include/rtems/score/objectmp.h,
+ score/include/rtems/score/priority.h,
+ score/include/rtems/score/stack.h,
+ score/include/rtems/score/states.h,
+ score/include/rtems/score/thread.h,
+ score/include/rtems/score/threadmp.h,
+ score/include/rtems/score/threadq.h,
+ score/include/rtems/score/tod.h, score/include/rtems/score/tqdata.h,
+ score/include/rtems/score/userext.h,
+ score/include/rtems/score/watchdog.h,
+ score/include/rtems/score/wkspace.h,
+ score/inline/rtems/score/address.inl,
+ score/inline/rtems/score/coremsg.inl,
+ score/inline/rtems/score/coresem.inl,
+ score/inline/rtems/score/heap.inl, score/inline/rtems/score/isr.inl,
+ score/inline/rtems/score/object.inl,
+ score/inline/rtems/score/priority.inl,
+ score/inline/rtems/score/stack.inl,
+ score/inline/rtems/score/thread.inl,
+ score/inline/rtems/score/tqdata.inl,
+ score/inline/rtems/score/userext.inl,
+ score/inline/rtems/score/wkspace.inl,
+ score/macros/rtems/score/address.inl,
+ score/macros/rtems/score/heap.inl,
+ score/macros/rtems/score/object.inl,
+ score/macros/rtems/score/priority.inl,
+ score/macros/rtems/score/userext.inl: Convert to using c99 fixed
+ size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * sapi/include/confdefs.h, sapi/include/rtems/config.h,
+ sapi/include/rtems/extension.h, sapi/include/rtems/fatal.h,
+ sapi/include/rtems/init.h, sapi/include/rtems/io.h,
+ sapi/src/exinit.c, sapi/src/extension.c, sapi/src/fatal.c,
+ sapi/src/io.c: Convert to using c99 fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/include/rtems.h,
+ rtems/include/rtems/rtems/asr.h,
+ rtems/include/rtems/rtems/attr.h,
+ rtems/include/rtems/rtems/clock.h,
+ rtems/include/rtems/rtems/config.h,
+ rtems/include/rtems/rtems/dpmem.h,
+ rtems/include/rtems/rtems/eventset.h,
+ rtems/include/rtems/rtems/message.h,
+ rtems/include/rtems/rtems/modes.h,
+ rtems/include/rtems/rtems/msgmp.h,
+ rtems/include/rtems/rtems/options.h,
+ rtems/include/rtems/rtems/part.h,
+ rtems/include/rtems/rtems/ratemon.h,
+ rtems/include/rtems/rtems/region.h,
+ rtems/include/rtems/rtems/regionmp.h,
+ rtems/include/rtems/rtems/sem.h,
+ rtems/include/rtems/rtems/support.h,
+ rtems/include/rtems/rtems/taskmp.h,
+ rtems/include/rtems/rtems/tasks.h,
+ rtems/include/rtems/rtems/timer.h,
+ rtems/inline/rtems/rtems/part.inl,
+ rtems/inline/rtems/rtems/region.inl,
+ rtems/macros/rtems/rtems/part.inl,
+ rtems/src/attr.c,
+ rtems/src/dpmem.c,
+ rtems/src/dpmemcreate.c,
+ rtems/src/dpmemexternal2internal.c,
+ rtems/src/dpmeminternal2external.c,
+ rtems/src/eventseize.c,
+ rtems/src/msg.c,
+ rtems/src/msgmp.c,
+ rtems/src/msgqallocate.c,
+ rtems/src/msgqbroadcast.c,
+ rtems/src/msgqcreate.c,
+ rtems/src/msgqflush.c,
+ rtems/src/msgqgetnumberpending.c,
+ rtems/src/msgqident.c,
+ rtems/src/msgqreceive.c,
+ rtems/src/msgqsend.c,
+ rtems/src/msgqsubmit.c,
+ rtems/src/msgqtranslatereturncode.c,
+ rtems/src/msgqurgent.c,
+ rtems/src/part.c,
+ rtems/src/partcreate.c,
+ rtems/src/partident.c,
+ rtems/src/partmp.c,
+ rtems/src/ratemon.c,
+ rtems/src/region.c,
+ rtems/src/regioncreate.c,
+ rtems/src/regionextend.c,
+ rtems/src/regiongetsegment.c,
+ rtems/src/regiongetsegmentsize.c,
+ rtems/src/regionmp.c,
+ rtems/src/regionreturnsegment.c,
+ rtems/src/rtemstimer.c,
+ rtems/src/sem.c,
+ rtems/src/semcreate.c,
+ rtems/src/semident.c,
+ rtems/src/semmp.c,
+ rtems/src/semobtain.c,
+ rtems/src/semtranslatereturncode.c,
+ rtems/src/taskcreate.c,
+ rtems/src/taskgetnote.c,
+ rtems/src/taskident.c,
+ rtems/src/taskinitusers.c,
+ rtems/src/taskmp.c,
+ rtems/src/taskrestart.c,
+ rtems/src/tasks.c,
+ rtems/src/tasksetnote.c,
+ rtems/src/taskstart.c,
+ rtems/src/timerserver.c: Convert to using c99 fixed size types.
+
+2004-04-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * score/src/Unlimited.txt, score/src/chain.c, score/src/coremsg.c,
+ score/src/coremsgbroadcast.c, score/src/coremsgclose.c,
+ score/src/coremsgflush.c, score/src/coremsgflushsupp.c,
+ score/src/coremsgseize.c, score/src/coremsgsubmit.c,
+ score/src/coremutex.c, score/src/coremutexflush.c,
+ score/src/coresem.c, score/src/coresemflush.c, score/src/coretod.c,
+ score/src/coretodtickle.c, score/src/coretodtoseconds.c,
+ score/src/coretodvalidate.c, score/src/heap.c,
+ score/src/heapallocate.c, score/src/heapextend.c,
+ score/src/heapfree.c, score/src/heapsizeofuserarea.c,
+ score/src/interr.c, score/src/iterateoverthreads.c,
+ score/src/mpci.c, score/src/object.c, score/src/objectallocate.c,
+ score/src/objectallocatebyindex.c, score/src/objectclearname.c,
+ score/src/objectcomparenameraw.c,
+ score/src/objectcomparenamestring.c, score/src/objectcopynameraw.c,
+ score/src/objectcopynamestring.c,
+ score/src/objectextendinformation.c, score/src/objectfree.c,
+ score/src/objectget.c, score/src/objectgetbyindex.c,
+ score/src/objectgetisr.c, score/src/objectgetnoprotection.c,
+ score/src/objectidtoname.c, score/src/objectinitializeinformation.c,
+ score/src/objectmp.c, score/src/objectnametoid.c,
+ score/src/objectshrinkinformation.c, score/src/thread.c,
+ score/src/threadcreateidle.c, score/src/threadget.c,
+ score/src/threadidlebody.c, score/src/threadinitialize.c,
+ score/src/threadmp.c, score/src/threadq.c,
+ score/src/threadqdequeuepriority.c,
+ score/src/threadqenqueuepriority.c,
+ score/src/threadqfirstpriority.c, score/src/threadqflush.c,
+ score/src/threadreset.c, score/src/threadrestart.c,
+ score/src/threadsettransient.c, score/src/threadstackallocate.c,
+ score/src/threadstart.c, score/src/userext.c,
+ score/src/watchdoginsert.c, score/src/wkspace.c: Convert to using
+ c99 fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ PR 561/rtems
+ * include/rtems/concat.h: New.
+ * Makefile.am: Add include/rtems/concat.h.
+
+ PR 589/rtems
+ * Makefile.am: Add include/rtems/pci.h.
+
+ * Makefile.am: Include automake/compile.am.
+ * configure.ac: RTEMS_TOP([..],[]).
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * aclocal/rtems-top.m4: Add MULTISUBDIR. Add MULTIBUILDTOP.
+ Add rtems_updir. Remove version.m4 check.
+ Add PROJECT_ROOT/with_project_root processing.
+ Add PROJECT_INCLUDE. Add PROJECT_LIB.
+ * aclocal/env-rtemscpu.a4: Remove cpukit_topdir.
+ Remove with_project_root processing. Remove PROJECT_INCLUDE,
+ PROJECT_LIB.
+
+2004-03-26 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libmisc/capture/capture-cli.c, libmisc/capture/capture.c,
+ libmisc/capture/capture.h, libmisc/cpuuse/cpuuse.c,
+ libmisc/devnull/devnull.c, libmisc/fsmount/fsmount.h,
+ libmisc/monitor/mon-config.c, libmisc/monitor/mon-dname.c,
+ libmisc/monitor/mon-driver.c, libmisc/monitor/mon-extension.c,
+ libmisc/monitor/mon-itask.c, libmisc/monitor/mon-monitor.c,
+ libmisc/monitor/mon-mpci.c, libmisc/monitor/mon-object.c,
+ libmisc/monitor/mon-prmisc.c, libmisc/monitor/mon-queue.c,
+ libmisc/monitor/mon-server.c, libmisc/monitor/mon-symbols.c,
+ libmisc/monitor/monitor.h, libmisc/monitor/symbols.h,
+ libmisc/mw-fb/mw_uid.c, libmisc/rtmonuse/rtmonuse.c,
+ libmisc/serdbg/serdbg.h, libmisc/serdbg/serdbgio.c,
+ libmisc/serdbg/termios_printk.c, libmisc/serdbg/termios_printk.h,
+ libmisc/shell/shell.c, libmisc/shell/shell.h, libmisc/stackchk/check.c,
+ libmisc/stackchk/internal.h: Convert to using c99 fixed size types.
+
+2004-03-23 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * itron/include/itronsys/mbox.h, itron/include/itronsys/types.h,
+ itron/include/rtems/itron/eventflags.h,
+ itron/include/rtems/itron/fmempool.h,
+ itron/include/rtems/itron/mbox.h,
+ itron/include/rtems/itron/msgbuffer.h,
+ itron/include/rtems/itron/port.h,
+ itron/include/rtems/itron/semaphore.h,
+ itron/include/rtems/itron/task.h,
+ itron/include/rtems/itron/vmempool.h,
+ itron/inline/rtems/itron/semaphore.inl,
+ itron/macros/rtems/itron/semaphore.inl, itron/src/eventflags.c,
+ itron/src/fmempool.c, itron/src/itronsem.c, itron/src/mbox.c,
+ itron/src/msgbuffer.c, itron/src/port.c, itron/src/snd_mbx.c,
+ itron/src/task.c, itron/src/trcv_mbx.c, itron/src/vmempool.c:
+ Convert to using c99 fixed size types.
+
+2004-03-23 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * posix/include/rtems/posix/cond.h,
+ posix/include/rtems/posix/intr.h, posix/include/rtems/posix/key.h,
+ posix/include/rtems/posix/mqueue.h,
+ posix/include/rtems/posix/mutex.h,
+ posix/include/rtems/posix/pthread.h,
+ posix/include/rtems/posix/semaphore.h,
+ posix/include/rtems/posix/threadsup.h,
+ posix/include/rtems/posix/timer.h, posix/src/cond.c,
+ posix/src/intr.c, posix/src/key.c, posix/src/keycreate.c,
+ posix/src/keydelete.c, posix/src/keygetspecific.c,
+ posix/src/keyrundestructors.c, posix/src/keysetspecific.c,
+ posix/src/killinfo.c, posix/src/mqueue.c,
+ posix/src/mqueuerecvsupp.c, posix/src/mqueuesendsupp.c,
+ posix/src/mqueuetranslatereturncode.c, posix/src/mutex.c,
+ posix/src/posixintervaltotimespec.c,
+ posix/src/posixtimespecsubtract.c, posix/src/psignal.c,
+ posix/src/pthread.c, posix/src/ptimer1.c, posix/src/semaphore.c,
+ posix/src/sysconf.c: Convert to using c99 fixed size types.
+
+2004-03-23 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * score/include/rtems/system.h: include <stdint.h>.
+
+2004-03-23 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ PR/589 rtems
+ * include/rtems/pci.h: New (Moved from c/src/libchip/network/pci.h).
+
+2004-03-23 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/src/malloc.c: Remove lvalue casts.
+
+2004-03-23 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libcsupport/include/chain.h, libcsupport/include/clockdrv.h,
+ libcsupport/include/ringbuf.h, libcsupport/include/spurious.h,
+ libcsupport/include/timerdrv.h, libcsupport/include/vmeintr.h,
+ libcsupport/include/motorola/mc68230.h,
+ libcsupport/include/rtems/assoc.h, libcsupport/include/rtems/libio.h,
+ libcsupport/include/rtems/libio_.h,
+ libcsupport/include/rtems/termiostypes.h,
+ libcsupport/include/zilog/z8036.h, libcsupport/include/zilog/z8530.h,
+ libcsupport/include/zilog/z8536.h, libcsupport/src/__gettod.c,
+ libcsupport/src/assoc.c, libcsupport/src/assocnamebad.c,
+ libcsupport/src/error.c, libcsupport/src/libio.c,
+ libcsupport/src/libio_sockets.c, libcsupport/src/malloc.c,
+ libcsupport/src/no_libc.c, libcsupport/src/termios.c,
+ libcsupport/src/termiosreserveresources.c: Convert to using c99
+ fixed-size types.
+
+2004-03-22 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * libfs/src/dosfs/fat.c, libfs/src/dosfs/fat.h,
+ libfs/src/dosfs/fat_fat_operations.c,
+ libfs/src/dosfs/fat_fat_operations.h, libfs/src/dosfs/fat_file.c,
+ libfs/src/dosfs/fat_file.h, libfs/src/dosfs/msdos.h,
+ libfs/src/dosfs/msdos_create.c, libfs/src/dosfs/msdos_dir.c,
+ libfs/src/dosfs/msdos_file.c, libfs/src/dosfs/msdos_initsupp.c,
+ libfs/src/dosfs/msdos_misc.c, libfs/src/imfs/deviceio.c,
+ libfs/src/imfs/imfs.h, libfs/src/imfs/imfs_directory.c,
+ libfs/src/imfs/imfs_fchmod.c, libfs/src/imfs/linearfile.c,
+ libfs/src/imfs/memfile.c: Convert to using c99 fixed-size types.
+
+2004-03-05 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/net/radix.c: Remove warning.
+
+2004-03-05 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/shell/cmds.c: Remove warning.
+
+2004-03-05 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/lib/ftpfs.c: Switch bcopy to memcpy.
+
+2004-03-05 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/src/newlibc.c, libcsupport/src/sync.c: Eliminate
+ warnings. Explicitly defeat __STRICT_ANSI__ since both
+ legitimately use routines beyond ANSI.
+
+2004-03-05 Joel Sherrill <joel@OARcorp.com>
+
+ * cpukit/libblock/src/bdbuf.c: Initialize pointer to avoid warning.
+
+2004-03-05 Joel Sherrill <joel@OARcorp.com>
+
+ * score/macros/rtems/score/chain.inl, score/src/objectidtoname.c:
+ Add cast to avoid type punning warning in gcc 3.3.
+2004-03-05 Joel Sherrill <joel@OARcorp.com>
+
+ *
+
+2004-03-05 Joel Sherrill <joel@OARcorp.com>
+
+ * libblock/src/bdbuf.c, libblock/src/ramdisk.c,
+ libcsupport/src/newlibc.c, libcsupport/src/sync.c,
+ libmisc/cpuuse/cpuuse.c, libmisc/monitor/mon-symbols.c,
+ libmisc/shell/cmds.c, libmisc/shell/shell.c,
+ libnetworking/kern/kern_sysctl.c, libnetworking/lib/ftpfs.c,
+ libnetworking/lib/tftpDriver.c, libnetworking/libc/gethostbydns.c,
+ libnetworking/libc/gethostbyht.c, libnetworking/libc/gethostnamadr.c,
+ libnetworking/libc/getnetbyht.c, libnetworking/libc/getnetnamadr.c,
+ libnetworking/libc/inet_addr.c, libnetworking/libc/linkaddr.c,
+ libnetworking/libc/map_v4v6.c, libnetworking/libc/ns_print.c,
+ libnetworking/libc/ns_ttl.c, libnetworking/libc/nsap_addr.c,
+ libnetworking/libc/rcmd.c, libnetworking/libc/res_debug.c,
+ libnetworking/libc/res_mkupdate.c, libnetworking/libc/res_query.c,
+ libnetworking/libc/res_send.c, libnetworking/libc/res_update.c,
+ libnetworking/net/radix.c, libnetworking/rtems/mkrootfs.c,
+ librpc/src/rpc/clnt_perror.c, librpc/src/rpc/rtems_rpc.c,
+ librpc/src/rpc/svc.c, sapi/include/confdefs.h,
+ score/macros/rtems/score/chain.inl, score/src/objectidtoname.c:
+
+2004-02-26 Thomas Rauscher <trauscher@loytec.com.
+
+ PR 584/RTEMS
+ * rtems/src/eventtimeout.c: Fix critical section window.
+
+2004-02-26 Joel Sherrill <joel@OARcorp.com>
+
+ PR 582/core
+ * posix/src/mqueue.c, posix/src/mqueuecreatesupp.c,
+ posix/src/mqueuedeletesupp.c, posix/src/mqueueunlink.c: Use memory
+ from workspace to avoid use of mutex during dispatch disable critical
+ section. Besides memory for object names should come from the
+ Workspace anyway.
+
+2004-02-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/version.m4: 4.6.99.0.
+
+2004-02-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/Makefile.am: Remove ACLOCAL_AMFLAGS.
+
+2004-01-30 Wilfried Busalski <w.busalski@lancier-monitoring.de>
+
+ PR pppd/564
+ * libnetworking/net/if_ppp.c, libnetworking/net/if_pppvar.h,
+ libnetworking/net/ppp_tty.c: ppp0 Interface lose packets if the
+ system use a slow baudrate for the modem or the tcp/ip-packet is
+ fragmented.
+
+2004-01-30 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog, rtems/Makefile.am, rtems/include/rtems/rtems/support.h:
+ Reverse developmental patches accidentally committed.
+
+2004-01-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * ChangeLog: Merge-in libnetworking/ChangeLog.
+ * ChangeLog: Merge-in libcsupport/ChangeLog.
+ * ChangeLog: Merge-in libblock/ChangeLog, libfs/ChangeLog.
+ * ChangeLog: Merge-in libmisc/ChangeLog, librpc/ChangeLog.
+ * ChangeLog: Merge-in itron/ChangeLog, posix/ChangeLog, score/ChangeLog,
+ sapi/ChangeLog, rtems/ChangeLog.
+ * libblock/ChangeLog, libfs/ChangeLog, libcsupport/ChangeLog,
+ libmisc/ChangeLog, librpc/ChangeLog, libnetworking/ChangeLog,
+ itron/ChangeLog, posix/ChangeLog, score/ChangeLog, sapi/ChangeLog,
+ rtems/ChangeLog: Remove.
+
+2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/rtems-top.m4: Remove PROJECT_ROOT. Prepend ../ to $1.
+ * aclocal/env-rtemscpu.m4: Reworked.
+ * configure.ac: RTEMS_TOP([.]).
+
+2004-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, itron/Makefile.am, posix/Makefile.am, score/Makefile.am,
+ sapi/Makefile.am, rtems/Makefile.am, libmisc/Makefile.am,
+ librpc/Makefile.am, libblock/Makefile.am, libfs/Makefile.am,
+ libcsupport/Makefile.am, libnetworking/Makefile.am: Add PREINSTALL_DIRS.
+
+2004-01-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Remove $(ARCH)/$(dirstamp). Add TMPINSTALL_FILES
+ to CLEANFILES.
+ * automake/local.am: Remove depend-am.
+ * automake/subdirs.am: Remove depend-recursive.
+ * score/Makefile.am: Re-add dirstamps to PREINSTALL_FILES. Add
+ PREINSTALL_FILES to CLEANFILES. Add cpuopts.h to DISTCLEANFILES.
+ * Makefile.am, itron/Makefile.am, posix/Makefile.am, sapi/Makefile.am,
+ rtems/Makefile.am, libmisc/Makefile.am, librpc/Makefile.am,
+ libblock/Makefile.am, libfs/Makefile.am, libcsupport/Makefile.am,
+ libnetworking/Makefile.am: Re-add dirstamps to PREINSTALL_FILES. Add
+ PREINSTALL_FILES to CLEANFILES.
+ * libnetworking/netinet/in_cksum.c: #include netinet/in_cksum_<cpu>.h.
+
+2004-01-13 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR/549 networking
+ * libnetworking/netinet/in_cksum_powerpc.h: New (copy of
+ in_cksum_powerpc.c).
+ * libnetworking/netinet/in_cksum_i386.h: New (copy of in_cksum_i386.c).
+ * libnetworking/netinet/in_cksum_arm.h: New (copy of in_cksum_arm.c).
+ * libnetworking/netinet/in_cksum_m68k.c: New (copy of in_cksum_m68k.c).
+ * libnetworking/netinet/in_cksum_i386.c,
+ libnetworking/netinet/in_cksum_arm.c,
+ libnetworking/netinet/in_cksum_powerpc.c,
+ libnetworking/netinet/in_cksum_m68k.c: Remove.
+ * libnetworking/netinet/Makefile.am: Reflect changes above.
+
+2004-01-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Requires automake >= 1.8.1.
+ * score/cpu/Makefile.am: Use @RTEMS_CPU@ instead of $(RTEMS_CPU).
+ PR 548/rtems
+ * libcsupport/Makefile.am: Add src/envlock.c.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/rtems-top.m4: Don't AC_SUBST PROJECT_ROOT. Remove
+ PROJECT_TOPdir (Unused).
+ * aclocal/env-rtemscpu.m4: Remove PROJECT_RELEASE. Expand
+ ${PROJECT_ROOT}. Remove RTEMS_ENABLE_BARE (Unused). Don't AC_SUBST
+ RTEMS_BSP.
+ * aclocal/enable-bare.m4: Remove (Unused).
+ * aclocal/rtems-top.m4: Remove check for cpukit/aclocal/version.m4.
+ Remove gnu-make endif HACK (Unused).
+ * wrapup/Makefile.am: Include compile.am. Use TMP_LIBS instead of LIBS
+ to avoid potential conflicts with auto*tools' LIBS. Reflect new
+ locations of libscorecpu*.a.
+ * Makefile.am: Remove AUTOMAKE_FILES.
+ * automake/compile.am: Replace contents with contents of
+ automake/amcompile.am.
+ * automake/amcompile.am, automake/lib.am: Remove.
+ * configure.ac, aclocal/enable-bare.m4, aclocal/enable-inlines.m4,
+ aclocal/enable-itron.m4, aclocal/enable-multiprocessing.m4,
+ aclocal/enable-networking.m4, aclocal/enable-posix.m4,
+ aclocal/enable-rtems-debug.m4, aclocal/multi.m4, aclocal/multilib.m4:
+ Use AS_HELP_STRING instead of AC_HELP_STRING (deprecated in
+ autoconf-2.59).
+ * automake/local.am: Remove clean-local, depend-gcc.
+ * itron/Makefile.am, posix/Makefile.am, score/Makefile.am: Include
+ compile.am, again.
+ * score/macros/rtems/score/README: Remove (Redundant with macros/README).
+ * sapi/Makefile.am, rtems/Makefile.am: Include compile.am, again.
+ * libmisc/Makefile.am: Include compile.am again. Misc fixes.
+ * librpc/Makefile.am: Include compile.am, again. Put man-pages into
+ EXTRA_DIST to work around automake not distributing conditionally
+ installed *_MANS. Distribute include/rpcsvc.
+ * libblock/Makefile.am: Include compile.am, again. Eliminate C_FILES.
+ Reformat.
+ * libfs/Makefile.am: Include compile.am, again. Reformat/Cleanup.
+ * libcsupport/Makefile.am: Reformat, add UNUSED_FILES.
+ * libcsupport/Makefile.am: Include compile.am, again. Eliminate
+ DOC_FILES.
+ * libnetworking/Makefile.am: Include compile.am, again. Cleanup.
+
+2004-01-08 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Cosmetics.
+ * aclocal/enable-networking.m4: Don't AC_SUBST(RTEMS_HAS_NETWORKING).
+ * aclocal/check-networking.m4: Don't AC_SUBST(HAS_NETWORKING).
+ * automake/amcompile.am: Remove $(ARCH).
+ * wrapup/Makefile.am: Add $(ARCH). Remove compile.am, lib.am. Include
+ amcompile.am.
+ * wrapup/Makefile.am: Use ../*/*$(LIB_VARIANT).a instead of
+ $(ARCH)/lib*.a.
+ * wrapup/Makefile.am: Reflect changes to libblock/Makefile.am. Reflect
+ changes to libcsupport/Makefile.am.
+ * itron/Makefile.am: Add libs to CLEANFILES. Set lib*_g_a_SOURCES =
+ lib*_a_SOURCES.
+ * itron/Makefile.am: Build libitron$(LIB_VARIANT).a instead of
+ $(ARCH)/libitron.a.
+ * posix/Makefile.am: Add libs to CLEANFILES Set lib*_g_a_SOURCES =
+ lib*_a_SOURCES.
+ * posix/Makefile.am: Build libposix$(LIB_VARIANT).a instead of
+ $(ARCH)/libposix.a.
+ * score/Makefile.am: Add libs to CLEANFILES Set lib*_g_a_SOURCES =
+ lib*_a_SOURCES.
+ * score/Makefile.am: Build libscore$(LIB_VARIANT).a instead of
+ $(ARCH)/libscore.a.
+ * sapi/Makefile.am: Add libs to CLEANFILES Set lib*_g_a_SOURCES =
+ lib*_a_SOURCES.
+ * sapi/Makefile.am: Build libsapi$(LIB_VARIANT).a instead of
+ $(ARCH)/libsapi.a.
+ * rtems/Makefile.am: Add libs to CLEANFILES Set lib*_g_a_SOURCES =
+ lib*_a_SOURCES.
+ * rtems/Makefile.am: Build librtems$(LIB_VARIANT).a instead of
+ $(ARCH)/librtems.a.
+ * libmisc/Makefile.am: Add libs to CLEANFILES Set lib*_g_a_SOURCES =
+ lib*_a_SOURCES.
+ * libmisc/Makefile.am: Build lib*$(LIB_VARIANT).a instead of
+ $(ARCH)/lib*.a.
+ * librpc/Makefile.am: Add libs to CLEANFILES. Set lib*_g_a_SOURCES =
+ lib*_a_SOURCES.
+ * librpc/Makefile.am: Build lib*$(LIB_VARIANT).a instead of
+ $(ARCH)/lib*.a.
+ * libblock/Makefile.am: Add libs to CLEANFILES Set lib*_g_a_SOURCES =
+ lib*_a_SOURCES.
+ * libblock/include/rtems/blkdev.h,
+ libblock/include/rtems/ide_part_table.h, libblock/src/bdbuf.c,
+ libblock/src/ide_part_table.c, libblock/src/ramdisk.c: Switch to using
+ c99 fixed size types instead of RTEMS-types.
+ * libblock/Makefile.am: Build libblock$(LIB_VARIANT).a instead of
+ $(ARCH)/libblock.a.
+ * libfs/Makefile.am: Add libs to CLEANFILES. Set lib*_g_a_SOURCES =
+ lib*_a_SOURCES.
+ * libfs/Makefile.am: Build lib*$(LIB_VARIANT).a instead of
+ $(ARCH)/lib*.a.
+ * libcsupport/Makefile.am: Add libs to CLEANFILES Set lib*_g_a_SOURCES =
+ lib*_a_SOURCES.
+ * libcsupport/Makefile.am: Build libcsupport$(LIB_VARIANT).a instead of
+ $(ARCH)/libcsupport.a.
+ * libnetworking/Makefile.am: Remove *C_FILES.
+ * libnetworking/Makefile.am: Add libs to CLEANFILES Set lib*_g_a_SOURCES
+ = lib*_a_SOURCES.
+ * libnetworking/Makefile.am: Build lib*$(LIB_VARIANT).a instead of
+ $(ARCH)/lib*.a.
+
+2004-01-07 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Reflect changes to library Makefile.ams.
+ * automake/amcompile.am: New.
+ * configure.ac: Add subdir-objects, AM_PROG_CC_C_O.
+ * itron/Makefile.am, posix/Makefile.am, score/Makefile.am,
+ sapi/Makefile.am, rtems/Makefile.am, libmisc/Makefile.am,
+ librpc/Makefile.am, libblock/Makefile.am, libfs/Makefile.am,
+ libcsupport/Makefile.am, libnetworking/Makefile.am: Build library using
+ EXTRA_LIBRARIES and automake rules.
+
+2004-01-07 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/rtems-cpu-subdirs.m4, score/cpu/Makefile.am: mips64orion port
+ removed as mips port more completely covers the MIPS family.
+ * score/cpu/mips64orion/.cvsignore, score/cpu/mips64orion/ChangeLog,
+ score/cpu/mips64orion/Makefile.am, score/cpu/mips64orion/asm.h,
+ score/cpu/mips64orion/configure.ac, score/cpu/mips64orion/cpu.c,
+ score/cpu/mips64orion/cpu_asm.S, score/cpu/mips64orion/cpu_asm.h,
+ score/cpu/mips64orion/idtcpu.h, score/cpu/mips64orion/idtmon.h,
+ score/cpu/mips64orion/iregdef.h, score/cpu/mips64orion/rtems/.cvsignore,
+ score/cpu/mips64orion/rtems/score/.cvsignore,
+ score/cpu/mips64orion/rtems/score/cpu.h,
+ score/cpu/mips64orion/rtems/score/mips64orion.h,
+ score/cpu/mips64orion/rtems/score/types.h: Removed.
+ * libnetworking/rtems/rtems_bsdnet_internal.h: Include rtems/cdefs.h so
+ things compile.
+
+2003-12-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * automake/compile.am: Use $(mkdir_p) instead of $(mkinstalldirs).
+
+2003-12-17 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-20031217-test.
+
+2003-12-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR 533/bsps
+ * score/startup/linkcmds: Update linkcmds for gcc 3.3.2.
+
+2003-12-16 Joel Sherrill <joel@OARcorp.com>
+
+ PR 543/rtems
+ * score/src/threadclose.c: Make the task delete extension run outside a
+ dispatch disabled critical section so extensions can free resources.
+ PR 542/filesystem
+ * libcsupport/include/rtems/libio_.h: Add rtems_libio_iop_to_descriptor
+ macro to convert iop to the corresponding integer file descriptor.
+
+2003-12-13 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/env-rtemscpu.m4: Remove stray '/' in PROJECT_LIB.
+ * wrapup/Makefile.am: Remove duplicate $(PROJECT_LIB) rule.
+ * aclocal/env-rtemscpu.m4: Add PROJECT_LIB.
+ * wrapup/Makefile.am: Use $(PROJECT_LIB) instead of
+ ${PROJECT_RELEASE}/lib.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, wrapup/Makefile.am: Use mkdir_p. Remove dirs from
+ PRE/TMPINSTALL_FILES.
+ * wrapup/Makefile.am: Reworked.
+ * aclocal/lead-dot.m4: Remove (Use the version in automake-1.8).
+ * automake/lib.am: Remove $(project_libdir)$(MULTISUBDIR).
+ * aclocal/env-rtemscpu.m4: Reflect new definition of project_lib.
+ * Makefile.am: Remove BUILT_SOURCES.
+ * configure.ac: Require automake >= 1.8, autoconf >= 2.59.
+ * itron/Makefile.am, posix/Makefile.am, score/Makefile.am,
+ sapi/Makefile.am, rtems/Makefile.am, libmisc/Makefile.am,
+ librpc/Makefile.am, libblock/Makefile.am, libfs/Makefile.am,
+ libcsupport/Makefile.am: Use mkdir_p. Remove dirs from
+ PRE/TMPINSTALL_FILES.
+ * libcsupport/Makefile.am: Remove BUILT_SOURCES.
+ * libnetworking/Makefile.am: Use mkdir_p. Remove dirs from
+ PRE/TMPINSTALL_FILES.
+
+2003-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/Makefile.am: Cosmetics.
+
+2003-12-11 Joel Sherrill <joel@OARcorp.com>
+
+ PR 540/rtems_misc
+ * libmisc/cpuuse/cpuuse.c, libmisc/rtmonuse/rtmonuse.c: Correct object
+ name printing.
+ PR 531/rtems_misc
+ * libmisc/rtmonuse/rtmonuse.c, libmisc/stackchk/check.c: Correct
+ indexing.
+
+2003-12-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libblock/src/ata.c: Remove.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * automake/compile.am: Add $(ARCH)/$(dirstamp) rules.
+ * wrapup/Makefile.am: Reflect $(dirstamp) changes.
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+ * aclocal/lead-dot.m4: New (from automake-1.7f).
+ * aclocal/rtems-top.m4: Require AM_SET_LEADING_DOT. Add
+ AC_SUBST(dirstamp).
+ * itron/Makefile.am: Add $(dirstamp) to compilation rules.
+ * itron/Makefile.am: Add $(dirstamp) to preinstallation rules. Remove
+ MACROS.
+ * posix/Makefile.am: Add $(dirstamp) to compilation rules.
+ * posix/Makefile.am: Add $(dirstamp) to preinstallation rules. Remove
+ MACROS.
+ * score/Makefile.am: Add $(dirstamp) to compilation rules.
+ * score/Makefile.am: Add $(dirstamp) to preinstallation rules. Remove
+ MACROS.
+ * sapi/Makefile.am: Add $(dirstamp) to compilation rules. Add
+ AM_CPPFLAGS += -I$(top_builddir).
+ * sapi/Makefile.am: Add $(dirstamp) to preinstallation rules. Remove
+ MACROS.
+ * rtems/Makefile.am: Add $(dirstamp) to compilation rules. Add
+ AM_CPPFLAGS += -I$(top_builddir).
+ * rtems/Makefile.am: Add $(dirstamp) to preinstallation rules. Remove
+ MACROS.
+ * libmisc/Makefile.am: Add $(dirstamp) to compilation rules. Fix misc.
+ typos.
+ * libmisc/Makefile.am: Add $(dirstamp) to preinstallation rules.
+ * librpc/Makefile.am: Add $(dirstamp) to compilation rules.
+ * librpc/Makefile.am: Add $(dirstamp) to preinstallation rules.
+ * libblock/Makefile.am: Add $(dirstamp) to compilation rules.
+ * libblock/Makefile.am: Add $(dirstamp) to preinstallation rules.
+ * libfs/Makefile.am: Add $(dirstamp) to compilation rules.
+ * libfs/Makefile.am: Add $(dirstamp) to preinstallation rules.
+ * libcsupport/Makefile.am: Add $(dirstamp) to compilation rules.
+ * libcsupport/Makefile.am: Add $(dirstamp) to preinstallation rules.
+ * libnetworking/Makefile.am: Add $(dirstamp) to compilation rules.
+ * libnetworking/Makefile.am: Fix libc_OBJS.
+ * libnetworking/Makefile.am: Add $(dirstamp) to preinstallation rules.
+ Restore libc/$(ARCH)/lib.a.
+
+2003-11-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Reflect having removed libnetworking/libc/Makefile.am,
+ libnetworking/lib/Makefile.am.
+ * configure.ac: Reflect changes to libmisc/*.
+ * libmisc/Makefile.am: Reformat.
+ * libmisc/capture/Makefile.am, libmisc/cpuuse/Makefile.am,
+ libmisc/devnull/Makefile.am, libmisc/dummy/Makefile.am,
+ libmisc/dumpbuf/Makefile.am, libmisc/fsmount/Makefile.am,
+ libmisc/monitor/Makefile.am, libmisc/mw-fb/Makefile.am,
+ libmisc/rtmonuse/Makefile.am, libmisc/serdbg/Makefile.am,
+ libmisc/shell/Makefile.am, libmisc/stackchk/Makefile.am,
+ libmisc/untar/Makefile.am: Remove.
+ * libmisc/Makefile.am: Merge-in the Makefile.ams above.
+ * libnetworking/libc/Makefile.am, libnetworking/lib/Makefile.am: Remove.
+ * libnetworking/Makefile.am: Merge-in the Makefile.ams above.
+
+2003-11-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Merge-in former libmisc/wrapup/Makefile.am.
+ * configure.ac: Reflect changes to libfs Makefile.ams. Remove
+ libmisc/wrapup/Makefile.
+ * configure.ac: Use here-documents to generate cpuopts.tmp. Various
+ fixes and changes to argument processing. Reflect changes to librpc
+ Makefile.ams.
+ * acinclude.m4: Use here-documents to generate cpuopts.tmp.
+ * aclocal/check-itron.m4: Remove HAS_IRON_API.
+ * aclocal/check-multiprocessing.m4: Remove HAS_MP.
+ * aclocal/check-posix.m4: Remove HAS_POSIX_API.
+ * libmisc/wrapup/Makefile.am, libmisc/wrapup/.cvsignore: Remove.
+ * libmisc/Makefile.am: Reflect changes above.
+ * librpc/src/rpc/Makefile.am, librpc/src/xdr/Makefile.am,
+ librpc/src/Makefile.am: Removed.
+ * librpc/Makefile.am: Merge-in src/rpc/Makefile.am, src/xdr/Makefile.am,
+ src/Makefile.am. Various fixes. Reformat.
+ * librpc/include/rpc/rpc.hinclude/rpc/rpc.h: Rename struct
+ rtems_rpc_task_variables into struct _rtems_rpc_task_variables (Avoid
+ symbol conflict between struct and variable). struct
+ _rtems_rpc_task_variables *rtems_rpc_task_variables; Reflect changes
+ above.
+ * librpc/src/rpc/clnt_perror.c, librpc/src/rpc/clnt_raw.c,
+ librpc/src/rpc/clnt_simple.c, librpc/src/rpc/rpcdname.c,
+ librpc/src/rpc/rtems_rpc.c, librpc/src/rpc/svc.c, librpc/
+ src/rpc/svc_auth.c, librpc/src/rpc/svc_raw.c,
+ librpc/src/rpc/svc_simple.c: Reflect changes above.
+ * libfs/Makefile.am: Merge-in src/Makefile.am, src/imfs/Makefile.am,
+ src/dosfs/Makefile.am.
+ * libfs/src/Makefile.am, libfs/src/imfs/Makefile.am,
+ libfs/src/dosfs/Makefile.am: Removed.
+
+2003-11-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/canonicalize-tools.m4, aclocal/check-itron.m4,
+ aclocal/check-multiprocessing.m4, aclocal/check-newlib.m4,
+ aclocal/check-posix.m4, aclocal/check-rtems-debug.m4,
+ aclocal/check-tool.m4, aclocal/enable-bare.m4,
+ aclocal/enable-inlines.m4, aclocal/enable-itron.m4,
+ aclocal/enable-multiprocessing.m4, aclocal/enable-networking.m4,
+ aclocal/enable-posix.m4, aclocal/enable-rtems-debug.m4,
+ aclocal/env-rtemscpu.m4, aclocal/gcc-isystem.m4, aclocal/gcc-pipe.m4,
+ aclocal/multi.m4, aclocal/multilib.m4, aclocal/prog-cc.m4,
+ aclocal/rtems-top.m4, aclocal/sysv-ipc.m4: Fix underquoting to silence
+ automake-1.8.
+
+2003-11-26 Joel Sherrill <joel@OARcorp.com>
+
+ PR 524/filesystem
+ * libcsupport/src/newlibc.c: Address 1K buffer leak from incomplete
+ cleanup of newlib reentrancy handler.
+ PR 523/filesystem
+ * libcsupport/src/malloc.c: Make malloc family safer for use from ISRs
+ and dispatching critical sections. If in a critical section while doing
+ a free(), then the free is deferred until the next malloc() attempt.
+
+2003-11-25 Joel Sherrill <joel@OARcorp.com>
+
+ PR 526/rtems
+ * score/src/threadcreateidle.c: Idle task name should be a string and
+ PR484 broke this.
+
+2003-11-25 Jennifer Averett <jennifer@OARcorp.com>
+
+ PR 519/filesystem
+ * libcsupport/include/rtems/libio_.h, libcsupport/src/eval.c,
+ libcsupport/src/rmdir.c, libcsupport/src/unlink.c: Check write
+ permissions in parent directory for file or directory delete.
+
+2003-11-24 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use RTEMS_INLINES instead of USE_INLINES. Elimimate
+ INLINESdir.
+ * aclocal/enable-inlines.m4: Ditto. Remove RTEMS_USE_MACROS.
+ * .cvsignore: Add config.h.in.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Make RTEMS_DEBUG an RTEMS_CPUOPT.
+ PR 525/rtems
+ * score/include/rtems/system.h: Use RTEMS_INLINES instead of USE_INLINES.
+ * score/include/rtems/score/chain.h, score/include/rtems/score/thread.h,
+ score/src/chain.c, score/src/coremutexseize.c, score/src/threadget.c:
+ Ditto.
+ * score/Makefile.am: Don't use gmake to preinstall.
+ * sapi/Makefile.am: Reworked.
+
+2003-11-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Reflect having removed libnetworking/wrapup.
+ * configure.ac: Ditto.
+ * itron/Makefile.am, posix/Makefile.am, rtems/Makefile.am,
+ libblock/Makefile.am: Reworked.
+ * libcsupport/include/rtems/cdefs.h: Use _RTEMS_CDEFS_H guards.
+ * libcsupport/include/rtems/cdefs.h: New.
+ * libcsupport/Makefile.am: Completely reworked.
+ * libnetworking/rtems/rtems_bsdnet_internal.h: Include rtems/cdefs.h
+ instead of sys/cdefs.h (Nonportable).
+ * libnetworking/wrapup/Makefile.am: Removed.
+ * libnetworking/Makefile.am: Reworked.
+
+2003-11-20 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * acinclude.m4: New.
+ * configure.ac: Don't use AUTOHEADER to generate cpuopts.h. Add local
+ autoheader config.h.
+ * aclocal/canonical-target-name.m4: Require AC_CANONICAL_HOST.
+ * aclocal/enable-inlines.m4: Remove USE_MACROS (Unused).
+ * itron/Makefile.am: Remove src/config.h. AM_CPPFLAGS +=
+ -I$(top_builddir).
+ * posix/Makefile.am: Remove src/config.h AM_CPPFLAGS +=
+ -I$(top_builddir).
+ * libmisc/capture/Makefile.am, libmisc/cpuuse/Makefile.am,
+ libmisc/devnull/Makefile.am, libmisc/dummy/Makefile.am,
+ libmisc/dumpbuf/Makefile.am, libmisc/monitor/Makefile.am,
+ libmisc/mw-fb/Makefile.am, libmisc/rtmonuse/Makefile.am,
+ libmisc/serdbg/Makefile.am, libmisc/shell/Makefile.am,
+ libmisc/stackchk/Makefile.am, libmisc/untar/Makefile.am: Remove
+ config.h. AM_CPPFLAGS += -I$(top_builddir).
+ * libblock/Makefile.am: AM_CPPFLAGS += -I$(top_builddir). Use
+ AM_CPPFLAGS instead of AM_CFLAGS.
+ * libblock/src/ata.c: Include config.h.
+ * libblock/src/bdbuf.c, libblock/src/blkdev.c, libblock/src/diskdevs.c,
+ libblock/src/ide_part_table.c, libblock/src/ramdisk.c: Ditto.
+ * libfs/src/dosfs/Makefile.am, libfs/src/imfs/Makefile.am: Remove
+ config.h AM_CPPFLAGS += -I$(top_builddir).
+ * itron/src/config.h, posix/src/config.h, libmisc/capture/config.h,
+ libmisc/cpuuse/config.h, libmisc/devnull/config.h,
+ libmisc/dummy/config.h, libmisc/dumpbuf/config.h,
+ libmisc/monitor/config.h, libmisc/mw-fb/config.h,
+ libmisc/rtmonuse/config.h, libmisc/serdbg/config.h,
+ libmisc/stackchk/config.h, libmisc/shell/config.h,
+ libmisc/untar/config.h, libfs/src/dosfs/config.h,
+ libfs/src/imfs/config.h, libcsupport/src/config.h: Remove.
+ * libcsupport/src/Makefile.am: AM_CPPFLAGS += -I$(top_builddir).
+
+2003-11-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libfs/Makefile.am: Cosmetics.
+
+2003-10-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/src/regiongetsegment.c: Remove unneccessary typecast in
+ assignment to thread->Wait.return_argment.
+
+2003-10-22 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
+
+ PR 515/filesystem
+ * libfs/src/dosfs/fat_fat_operations.c: Remove commented out code.
+
+2003-10-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR 509/filesystem
+ * libfs/src/dosfs/fat.c: _fat_block_read and _fat_block_write return
+ error codes instead of -1 in case of errors, as they are supposed to do
+ according to the comments documenting these functions.
+
+2003-10-22 Joel Sherrill <joel@OARcorp.com>
+
+ PR 512/core
+ * rtems/src/tasks.c, rtems/src/taskvariabledelete.c: Run task variable
+ destructor when task variable is deleted. Also some style cleanup.
+ PR 440/filesystem
+ * libfs/src/dosfs/fat_fat_operations.c: Improve write speed with FAT12
+ and FAT16 filesystems. Previously merged on 4.6 branch.
+ * libfs/ChangeLog: Correct line length.
+ PR 511/filesystem
+ * libcsupport/src/malloc.c: Add deferred free and protect against C
+ Program Heap operations while in a dispatch disable critical section or
+ ISR.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/check-posix.m4: Add m4-quotes. Require
+ RTEMS_CANONICAL_TARGET_CPU instead of RTEMS_CHECK_CPU.
+ * aclocal/canonical-host.m4: Remove.
+ * configure.ac: Remove RTEMS_CANONICAL_HOST.
+ * aclocal/sysv-ipc.m4: Remove reference to RTEMS_CANONICAL_HOST.
+ * aclocal/canonical-target-name.m4: Use AC_CANONICAL_HOST instead of
+ AC_CANONICAL_TARGET. Use $host instead of $target.
+ * aclocal/check-multiprocessing.m4: Add m4-quotes. Remove
+ RTEMS_CHECK_CPU.
+ * aclocal/check-itron.m4, aclocal/check-networking.m4: Add m4-quotes.
+ Require RTEMS_CANONICAL_TARGET_CPU instead of RTEMS_CHECK_CPU.
+ * aclocal/check-cpu.m4: Remove.
+ * aclocal/canonical-target-name.m4: Add m4-quotes.
+ * configure.ac: Merge-in former aclocal/check-cpu.m4.
+ * posix/src/cancelrun.c, posix/src/pthreadexit.c,
+ posix/src/pthreadjoin.c, posix/ src/sigtimedwait.c: Remove unnecessary
+ typecasts in assignments to thread->Wait.return_argument.
+ * score/src/coremsgseize.c, score/src/coremsgsubmit.c: Remove
+ unnecessary typecasts in assignments to thread->Wait.return_argument.
+ * libmisc/capture/capture-cli.c: Reflect new rtems_monitor_command_arg_t.
+ * librpc/src/rpc/Makefile.am, librpc/src/xdr/Makefile.am: Remove __P
+ from AM_CPPFLAGS. Rely on sys/cdefs.h providing it.
+ * libfs/src/dosfs/Makefile.am: noinst_HEADERS += fat.h.
+ * libfs/src/dosfs/msdos_file.c (msdos_file_read,
+ libfs/msdos_file_write): Use '0' as initial value for ret instead of
+ RC_OK.
+ * libfs/src/dosfs/msdos_conv.c: Remove isupper, islower, toupper,
+ tolower (Unused).
+
+2003-10-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Check for sys/cdefs.h.
+ * aclocal/env-rtems-cpu.m4: Add project_includedir. Deprecate
+ PROJECT_INCLUDE. Change project_includedir to $(PROJECT_ROOT)/include
+ for multilibs.
+
+2003-10-13 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/cleanuppop.c, posix/src/cleanuppush.c: Protect use of
+ _Workspace_Allocate and _Workspec_Free.
+
+2003-10-02 Phil Torre <ptorre@zetron.com>
+
+ PR 504/rtems
+ * score/include/rtems/score/coremutex.h: Add fatal error check for a
+ task blocking on a mutex when thread dispatching is disabled.
+ PR 504/rtems
+ * libcsupport/src/newlibc.c: Fix memory allocation of libc extension so
+ it is dispatch disabled safe See PR for detailed explanation.
+
+2003-09-26 Till Strauman <strauman@slac.stanford.edu>
+
+ PR 498/rtems
+ * libcsupport/src/printk.c: RTEMS printk() does not support the %i
+ format which is used by a lot of driver/BSP etc. code. The trivial patch
+ allows %i/%I as an alias for %d/%D.
+
+2003-09-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR 495/rtems_misc
+ * libmisc/capture/capture-cli.c, libmisc/monitor/mon-command.c,
+ libmisc/monitor/mon-config.c, libmisc/monitor/mon-monitor.c,
+ libmisc/monitor/mon-object.c, libmisc/monitor/mon-symbols.c,
+ libmisc/monitor/monitor.h, libmisc/shell/cmds.c: Move to making libmisc
+ 16/32 bit clean.
+
+2003-09-26 Joel Sherrill <joel@OARcorp.com>
+
+ * score/cpu/hppa1.1/.cvsignore, score/cpu/hppa1.1/ChangeLog,
+ score/cpu/hppa1.1/Makefile.am, score/cpu/hppa1.1/configure.ac,
+ score/cpu/hppa1.1/cpu.c, score/cpu/hppa1.1/cpu_asm.S,
+ score/cpu/hppa1.1/rtems/.cvsignore,
+ score/cpu/hppa1.1/rtems/score/.cvsignore,
+ score/cpu/hppa1.1/rtems/score/cpu.h,
+ score/cpu/hppa1.1/rtems/score/cpu_asm.h,
+ score/cpu/hppa1.1/rtems/score/hppa.h,
+ score/cpu/hppa1.1/rtems/score/types.h: Removed.
+ PR 492/filesystem
+ * libfs/src/dosfs/fat_file.c: Fix inconsistent types in va_args call.
+
+2003-09-24 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, librpc/Makefile.am: Merge-in include/Makefile.am.
+ * include/Makefile.am, librpc/include/Makefile.am: Remove.
+ * configure.ac: Reflect having removed include/Makefile.am and
+ librpc/include/Makefile.am.
+
+2003-09-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/monitor/monitor.h: Add rtems_monitor_commands[] (Illegally
+ applied by shell/). Remove ifdef(__mips64) (Make broken code visible
+ again).
+ * libmisc/monitor/mon-command.c: Add several ifndef RTEMS_UNIX to avoid
+ warnings.
+ * libmisc/monitor/mon-monitor.c: Remove RTEMS_CPU_HAS_16_BIT_ADDRESSES
+ (Make broken code visible again).
+ * libmisc/shell/cmds.c: Remove local decls of rtems_monitor_commands[].
+
+2003-09-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/monitor/monitor.h: Remove STREQ, STNEQ (pollute namespace),
+ RTEMS_MONITOR_PROMPT (pollutes namespace, useless).
+ * libmisc/monitor/mon-command.c: Add RTEMS_MONITOR_PROMPT.
+ * libmisc/monitor/mon-monitor.c: Apply private version of STREQ.
+ * libmisc/monitor/symbols.h: Convert to private header.
+ * libmisc/monitor/monitor.h: Don't include symbols.h. Add forward decls.
+ for symbols from symbols.h.
+ * libmisc/monitor/Makefile.am: Don't install symbols.h.
+ * libmisc/monitor/mon-symbols.c: Include "symbols.h".
+
+2003-09-15 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR 489/rtems
+ * score/include/rtems/score/thread.h: Change struct
+ Thread_Control_struct.libc_reent to using struct _reent*.
+ * score/inline/rtems/score/thread.inl: Reflect change above.
+ PR 489/rtems
+ * libcsupport/src/newlibc.c: Reflect struct
+ Thread_Control_struct.libc_reent having changed from void * to struct
+ _reent*.
+
+2003-09-15 Jay Monkman <jtm@smoothsmoothie.com>
+
+ PR 482/networking
+ * libnetworking/rtems/rtems_glue.c: Network interfaces can't be taken
+ down.
+ PR 481/networking
+ * libnetworking/net/ethernet.h, libnetworking/net/if_arp.h,
+ libnetworking/netinet/if_ether.h: Network structs should be packed.
+
+2003-09-13 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libcsupport/src/sync.c: Don't undef __STRICT_ANSI__. Use struct _reent
+ (struct reent doesn't exist).
+ PR 486/rtems
+ * libcsupport/src/newlib.c: Unconditionally include <stdio.h>.
+
+2003-09-11 Joel Sherrill <joel@OARcorp.com>
+
+ PR 488/rtems
+ * rtems/src/taskcreate.c, rtems/src/tasks.c: Ensure notepads are zeroed.
+
+2003-09-09 Ralf Corsepius <ralf_corsepius@rtems.com>
+
+ PR 487/filesystem
+ * libfs/src/dosfs/fat_file.c: Correct typing per gcc 3.3 warnings.
+
+2003-09-08 Mikec Ivica <mikici@acm.org>
+
+ * score/inline/rtems/score/userext.inl,
+ score/macros/rtems/score/userext.inl: Add missing cast.
+
+2003-09-08 Derick Hammond <derick@perkinstechnologies.com.au>
+
+ PR 484/rtems
+ * score/src/threadcreateidle.c: Idle task name was initialized
+ incorrectly.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * include/rtems/bspIo.h, include/rtems/fs.h, include/rtems/userenv.h,
+ itron/include/itron.h, itron/include/itronsys/eventflags.h,
+ itron/include/itronsys/fmempool.h, itron/include/itronsys/intr.h,
+ itron/include/itronsys/mbox.h, itron/include/itronsys/msgbuffer.h,
+ itron/include/itronsys/network.h, itron/include/itronsys/port.h,
+ itron/include/itronsys/semaphore.h, itron/include/itronsys/status.h,
+ itron/include/itronsys/sysmgmt.h, itron/include/itronsys/task.h,
+ itron/include/itronsys/time.h, itron/include/itronsys/types.h,
+ itron/include/itronsys/vmempool.h, itron/include/rtems/itron/config.h,
+ itron/include/rtems/itron/eventflags.h,
+ itron/include/rtems/itron/fmempool.h, itron/include/rtems/itron/intr.h,
+ itron/include/rtems/itron/itronapi.h, itron/include/rtems/itron/mbox.h,
+ itron/include/rtems/itron/msgbuffer.h,
+ itron/include/rtems/itron/network.h, itron/include/rtems/itron/object.h,
+ itron/include/rtems/itron/port.h, itron/include/rtems/itron/semaphore.h,
+ itron/include/rtems/itron/sysmgmt.h, itron/include/rtems/itron/task.h,
+ itron/include/rtems/itron/time.h, itron/include/rtems/itron/vmempool.h,
+ itron/inline/rtems/itron/eventflags.inl,
+ itron/inline/rtems/itron/fmempool.inl,
+ itron/inline/rtems/itron/intr.inl, itron/inline/rtems/itron/mbox.inl,
+ itron/inline/rtems/itron/msgbuffer.inl,
+ itron/inline/rtems/itron/network.inl, itron/inline/rtems/itron/port.inl,
+ itron/inline/rtems/itron/semaphore.inl,
+ itron/inline/rtems/itron/sysmgmt.inl, itron/inline/rtems/itron/task.inl,
+ itron/inline/rtems/itron/time.inl,
+ itron/inline/rtems/itron/vmempool.inl,
+ itron/macros/rtems/itron/eventflags.inl,
+ itron/macros/rtems/itron/fmempool.inl,
+ itron/macros/rtems/itron/intr.inl, itron/macros/rtems/itron/mbox.inl,
+ itron/macros/rtems/itron/msgbuffer.inl,
+ itron/macros/rtems/itron/network.inl, itron/macros/rtems/itron/port.inl,
+ itron/macros/rtems/itron/semaphore.inl,
+ itron/macros/rtems/itron/sysmgmt.inl, itron/macros/rtems/itron/task.inl,
+ itron/macros/rtems/itron/time.inl,
+ itron/macros/rtems/itron/vmempool.inl, itron/src/can_wup.c,
+ itron/src/chg_pri.c, itron/src/cre_mbf.c, itron/src/cre_mbx.c,
+ itron/src/cre_sem.c, itron/src/cre_tsk.c, itron/src/del_mbf.c,
+ itron/src/del_mbx.c, itron/src/del_sem.c, itron/src/del_tsk.c,
+ itron/src/dis_dsp.c, itron/src/ena_dsp.c, itron/src/eventflags.c,
+ itron/src/exd_tsk.c, itron/src/ext_tsk.c, itron/src/fmempool.c,
+ itron/src/frsm_tsk.c, itron/src/get_tid.c, itron/src/itronintr.c,
+ itron/src/itronsem.c, itron/src/itrontime.c, itron/src/mbox.c,
+ itron/src/mboxtranslatereturncode.c, itron/src/msgbuffer.c,
+ itron/src/msgbuffertranslatereturncode.c, itron/src/network.c,
+ itron/src/port.c, itron/src/prcv_mbf.c, itron/src/prcv_mbx.c,
+ itron/src/preq_sem.c, itron/src/psnd_mbf.c, itron/src/rcv_mbf.c,
+ itron/src/rcv_mbx.c, itron/src/ref_mbf.c, itron/src/ref_mbx.c,
+ itron/src/ref_sem.c, itron/src/ref_tsk.c, itron/src/rel_wai.c,
+ itron/src/rot_rdq.c, itron/src/rsm_tsk.c, itron/src/sig_sem.c,
+ itron/src/slp_tsk.c, itron/src/snd_mbf.c, itron/src/snd_mbx.c,
+ itron/src/sta_tsk.c, itron/src/sus_tsk.c, itron/src/sysmgmt.c,
+ itron/src/task.c, itron/src/ter_tsk.c, itron/src/trcv_mbf.c,
+ itron/src/trcv_mbx.c, itron/src/tslp_tsk.c, itron/src/tsnd_mbf.c,
+ itron/src/twai_sem.c, itron/src/vmempool.c, itron/src/wai_sem.c,
+ itron/src/wup_tsk.c, posix/include/rtems/posix/cond.h,
+ posix/include/rtems/posix/condmp.h, posix/include/rtems/posix/config.h,
+ posix/include/rtems/posix/intr.h, posix/include/rtems/posix/key.h,
+ posix/include/rtems/posix/mqueue.h,
+ posix/include/rtems/posix/mqueuemp.h, posix/include/rtems/posix/mutex.h,
+ posix/include/rtems/posix/mutexmp.h,
+ posix/include/rtems/posix/posixapi.h,
+ posix/include/rtems/posix/pthread.h,
+ posix/include/rtems/posix/pthreadmp.h,
+ posix/include/rtems/posix/ptimer.h,
+ posix/include/rtems/posix/semaphore.h,
+ posix/include/rtems/posix/semaphoremp.h,
+ posix/inline/rtems/posix/cond.inl, posix/inline/rtems/posix/intr.inl,
+ posix/inline/rtems/posix/key.inl, posix/inline/rtems/posix/mqueue.inl,
+ posix/inline/rtems/posix/mutex.inl,
+ posix/inline/rtems/posix/pthread.inl,
+ posix/inline/rtems/posix/semaphore.inl,
+ posix/inline/rtems/posix/timer.inl, posix/macros/rtems/posix/cond.inl,
+ posix/macros/rtems/posix/intr.inl, posix/macros/rtems/posix/key.inl,
+ posix/macros/rtems/posix/mqueue.inl, posix/macros/rtems/posix/mutex.inl,
+ posix/macros/rtems/posix/pthread.inl,
+ posix/macros/rtems/posix/semaphore.inl,
+ posix/macros/rtems/posix/timer.inl, posix/src/alarm.c, posix/src/kill.c,
+ posix/src/killinfo.c, posix/src/mqueuetranslatereturncode.c,
+ posix/src/pause.c, posix/src/pthreadattrdestroy.c,
+ posix/src/pthreadattrgetdetachstate.c,
+ posix/src/pthreadattrgetinheritsched.c,
+ posix/src/pthreadattrgetschedparam.c,
+ posix/src/pthreadattrgetschedpolicy.c, posix/src/pthreadattrgetscope.c,
+ posix/src/pthreadattrgetstackaddr.c,
+ posix/src/pthreadattrgetstacksize.c, posix/src/pthreadattrinit.c,
+ posix/src/pthreadattrsetdetachstate.c,
+ posix/src/pthreadattrsetinheritsched.c,
+ posix/src/pthreadattrsetschedparam.c,
+ posix/src/pthreadattrsetschedpolicy.c, posix/src/pthreadattrsetscope.c,
+ posix/src/pthreadattrsetstackaddr.c,
+ posix/src/pthreadattrsetstacksize.c, posix/src/pthreadcreate.c,
+ posix/src/pthreaddetach.c, posix/src/pthreadequal.c,
+ posix/src/pthreadexit.c, posix/src/pthreadgetcpuclockid.c,
+ posix/src/pthreadgetcputime.c, posix/src/pthreadgetschedparam.c,
+ posix/src/pthreadjoin.c, posix/src/pthreadkill.c,
+ posix/src/pthreadonce.c, posix/src/pthreadself.c,
+ posix/src/pthreadsetcputime.c, posix/src/pthreadsetschedparam.c,
+ posix/src/pthreadsigmask.c, posix/src/sigaction.c,
+ posix/src/sigaddset.c, posix/src/sigdelset.c, posix/src/sigemptyset.c,
+ posix/src/sigfillset.c, posix/src/sigismember.c, posix/src/signal_2.c,
+ posix/src/sigpending.c, posix/src/sigprocmask.c, posix/src/sigqueue.c,
+ posix/src/sigsuspend.c, posix/src/sigtimedwait.c, posix/src/sigwait.c,
+ posix/src/sigwaitinfo.c, posix/src/ualarm.c,
+ score/include/rtems/debug.h, score/include/rtems/seterr.h,
+ score/include/rtems/system.h, score/include/rtems/score/address.h,
+ score/include/rtems/score/apiext.h,
+ score/include/rtems/score/apimutex.h,
+ score/include/rtems/score/bitfield.h, score/include/rtems/score/chain.h,
+ score/include/rtems/score/context.h, score/include/rtems/score/copyrt.h,
+ score/include/rtems/score/coremsg.h,
+ score/include/rtems/score/coremutex.h,
+ score/include/rtems/score/coresem.h, score/include/rtems/score/heap.h,
+ score/include/rtems/score/interr.h, score/include/rtems/score/isr.h,
+ score/include/rtems/score/mpci.h, score/include/rtems/score/mppkt.h,
+ score/include/rtems/score/object.h,
+ score/include/rtems/score/objectmp.h,
+ score/include/rtems/score/priority.h, score/include/rtems/score/stack.h,
+ score/include/rtems/score/states.h,
+ score/include/rtems/score/sysstate.h,
+ score/include/rtems/score/thread.h,
+ score/include/rtems/score/threadmp.h,
+ score/include/rtems/score/threadq.h, score/include/rtems/score/tod.h,
+ score/include/rtems/score/tqdata.h, score/include/rtems/score/userext.h,
+ score/include/rtems/score/watchdog.h,
+ score/include/rtems/score/wkspace.h,
+ score/inline/rtems/score/address.inl,
+ score/inline/rtems/score/chain.inl,
+ score/inline/rtems/score/coremsg.inl,
+ score/inline/rtems/score/coremutex.inl,
+ score/inline/rtems/score/coresem.inl, score/inline/rtems/score/heap.inl,
+ score/inline/rtems/score/isr.inl, score/inline/rtems/score/mppkt.inl,
+ score/inline/rtems/score/object.inl,
+ score/inline/rtems/score/objectmp.inl,
+ score/inline/rtems/score/priority.inl,
+ score/inline/rtems/score/stack.inl, score/inline/rtems/score/states.inl,
+ score/inline/rtems/score/sysstate.inl,
+ score/inline/rtems/score/thread.inl,
+ score/inline/rtems/score/threadmp.inl, score/inline/rtems/score/tod.inl,
+ score/inline/rtems/score/tqdata.inl,
+ score/inline/rtems/score/userext.inl,
+ score/inline/rtems/score/watchdog.inl,
+ score/inline/rtems/score/wkspace.inl,
+ score/macros/rtems/score/address.inl,
+ score/macros/rtems/score/chain.inl,
+ score/macros/rtems/score/coremsg.inl,
+ score/macros/rtems/score/coremutex.inl,
+ score/macros/rtems/score/coresem.inl, score/macros/rtems/score/heap.inl,
+ score/macros/rtems/score/isr.inl, score/macros/rtems/score/mppkt.inl,
+ score/macros/rtems/score/object.inl,
+ score/macros/rtems/score/objectmp.inl,
+ score/macros/rtems/score/priority.inl,
+ score/macros/rtems/score/stack.inl, score/macros/rtems/score/states.inl,
+ score/macros/rtems/score/sysstate.inl,
+ score/macros/rtems/score/thread.inl,
+ score/macros/rtems/score/threadmp.inl, score/macros/rtems/score/tod.inl,
+ score/macros/rtems/score/tqdata.inl,
+ score/macros/rtems/score/userext.inl,
+ score/macros/rtems/score/watchdog.inl,
+ score/macros/rtems/score/wkspace.inl, score/src/apiext.c,
+ score/src/chain.c, score/src/coremsg.c, score/src/coremsgbroadcast.c,
+ score/src/coremsgclose.c, score/src/coremsgflush.c,
+ score/src/coremsgflushsupp.c, score/src/coremsgflushwait.c,
+ score/src/coremsginsert.c, score/src/coremsgseize.c,
+ score/src/coremsgsubmit.c, score/src/coremutex.c,
+ score/src/coremutexflush.c, score/src/coremutexseize.c,
+ score/src/coremutexsurrender.c, score/src/coresem.c,
+ score/src/coresemflush.c, score/src/coresemseize.c,
+ score/src/coresemsurrender.c, score/src/coretod.c,
+ score/src/coretodset.c, score/src/coretodtickle.c,
+ score/src/coretodtoseconds.c, score/src/coretodvalidate.c,
+ score/src/heap.c, score/src/heapallocate.c, score/src/heapextend.c,
+ score/src/heapfree.c, score/src/heapgetinfo.c,
+ score/src/heapsizeofuserarea.c, score/src/heapwalk.c,
+ score/src/interr.c, score/src/isr.c, score/src/iterateoverthreads.c,
+ score/src/mpci.c, score/src/object.c, score/src/objectallocate.c,
+ score/src/objectallocatebyindex.c, score/src/objectclearname.c,
+ score/src/objectcomparenameraw.c, score/src/objectcomparenamestring.c,
+ score/src/objectcopynameraw.c, score/src/objectcopynamestring.c,
+ score/src/objectextendinformation.c, score/src/objectfree.c,
+ score/src/objectget.c, score/src/objectgetbyindex.c,
+ score/src/objectgetisr.c, score/src/objectgetnext.c,
+ score/src/objectgetnoprotection.c, score/src/objectidtoname.c,
+ score/src/objectinitializeinformation.c, score/src/objectmp.c,
+ score/src/objectnametoid.c, score/src/objectshrinkinformation.c,
+ score/src/thread.c, score/src/threadchangepriority.c,
+ score/src/threadclearstate.c, score/src/threadclose.c,
+ score/src/threadcreateidle.c, score/src/threaddelayended.c,
+ score/src/threaddispatch.c, score/src/threadevaluatemode.c,
+ score/src/threadget.c, score/src/threadhandler.c,
+ score/src/threadidlebody.c, score/src/threadinitialize.c,
+ score/src/threadloadenv.c, score/src/threadmp.c, score/src/threadq.c,
+ score/src/threadqdequeue.c, score/src/threadqdequeuefifo.c,
+ score/src/threadqdequeuepriority.c, score/src/threadqenqueue.c,
+ score/src/threadqenqueuefifo.c, score/src/threadqenqueuepriority.c,
+ score/src/threadqextract.c, score/src/threadqextractfifo.c,
+ score/src/threadqextractpriority.c, score/src/threadqextractwithproxy.c,
+ score/src/threadqfirst.c, score/src/threadqfirstfifo.c,
+ score/src/threadqfirstpriority.c, score/src/threadqflush.c,
+ score/src/threadqtimeout.c, score/src/threadready.c,
+ score/src/threadreset.c, score/src/threadresettimeslice.c,
+ score/src/threadrestart.c, score/src/threadresume.c,
+ score/src/threadrotatequeue.c, score/src/threadsetpriority.c,
+ score/src/threadsetstate.c, score/src/threadsettransient.c,
+ score/src/threadstackallocate.c, score/src/threadstackfree.c,
+ score/src/threadstart.c, score/src/threadstartmultitasking.c,
+ score/src/threadsuspend.c, score/src/threadtickletimeslice.c,
+ score/src/threadyieldprocessor.c, score/src/userext.c,
+ score/src/watchdog.c, score/src/watchdogadjust.c,
+ score/src/watchdoginsert.c, score/src/watchdogremove.c,
+ score/src/watchdogtickle.c, score/src/wkspace.c,
+ sapi/include/confdefs.h, sapi/include/rtems/config.h,
+ sapi/include/rtems/extension.h, sapi/include/rtems/fatal.h,
+ sapi/include/rtems/init.h, sapi/include/rtems/io.h,
+ sapi/include/rtems/mptables.h, sapi/include/rtems/sptables.h,
+ sapi/include/rtems/sptables.h.in, sapi/inline/rtems/extension.inl,
+ sapi/macros/rtems/extension.inl, sapi/src/debug.c, sapi/src/exinit.c,
+ sapi/src/extension.c, sapi/src/extensioncreate.c,
+ sapi/src/extensiondelete.c, sapi/src/extensionident.c, sapi/src/fatal.c,
+ sapi/src/io.c, sapi/src/itronapi.c, sapi/src/posixapi.c,
+ sapi/src/rtemsapi.c, rtems/include/rtems.h,
+ rtems/include/rtems/rtems/asr.h, rtems/include/rtems/rtems/attr.h,
+ rtems/include/rtems/rtems/cache.h, rtems/include/rtems/rtems/clock.h,
+ rtems/include/rtems/rtems/config.h, rtems/include/rtems/rtems/dpmem.h,
+ rtems/include/rtems/rtems/event.h, rtems/include/rtems/rtems/eventmp.h,
+ rtems/include/rtems/rtems/eventset.h, rtems/include/rtems/rtems/intr.h,
+ rtems/include/rtems/rtems/message.h, rtems/include/rtems/rtems/modes.h,
+ rtems/include/rtems/rtems/mp.h, rtems/include/rtems/rtems/msgmp.h,
+ rtems/include/rtems/rtems/options.h, rtems/include/rtems/rtems/part.h,
+ rtems/include/rtems/rtems/partmp.h, rtems/include/rtems/rtems/ratemon.h,
+ rtems/include/rtems/rtems/region.h,
+ rtems/include/rtems/rtems/regionmp.h,
+ rtems/include/rtems/rtems/rtemsapi.h, rtems/include/rtems/rtems/sem.h,
+ rtems/include/rtems/rtems/semmp.h, rtems/include/rtems/rtems/signal.h,
+ rtems/include/rtems/rtems/signalmp.h,
+ rtems/include/rtems/rtems/status.h, rtems/include/rtems/rtems/support.h,
+ rtems/include/rtems/rtems/taskmp.h, rtems/include/rtems/rtems/tasks.h,
+ rtems/include/rtems/rtems/timer.h, rtems/include/rtems/rtems/types.h,
+ rtems/inline/rtems/rtems/asr.inl, rtems/inline/rtems/rtems/attr.inl,
+ rtems/inline/rtems/rtems/dpmem.inl, rtems/inline/rtems/rtems/event.inl,
+ rtems/inline/rtems/rtems/eventset.inl,
+ rtems/inline/rtems/rtems/message.inl,
+ rtems/inline/rtems/rtems/modes.inl,
+ rtems/inline/rtems/rtems/options.inl, rtems/inline/rtems/rtems/part.inl,
+ rtems/inline/rtems/rtems/ratemon.inl,
+ rtems/inline/rtems/rtems/region.inl, rtems/inline/rtems/rtems/sem.inl,
+ rtems/inline/rtems/rtems/status.inl,
+ rtems/inline/rtems/rtems/support.inl,
+ rtems/inline/rtems/rtems/tasks.inl, rtems/inline/rtems/rtems/timer.inl,
+ rtems/macros/rtems/rtems/asr.inl, rtems/macros/rtems/rtems/attr.inl,
+ rtems/macros/rtems/rtems/dpmem.inl, rtems/macros/rtems/rtems/event.inl,
+ rtems/macros/rtems/rtems/eventset.inl,
+ rtems/macros/rtems/rtems/message.inl,
+ rtems/macros/rtems/rtems/modes.inl,
+ rtems/macros/rtems/rtems/options.inl, rtems/macros/rtems/rtems/part.inl,
+ rtems/macros/rtems/rtems/ratemon.inl,
+ rtems/macros/rtems/rtems/region.inl, rtems/macros/rtems/rtems/sem.inl,
+ rtems/macros/rtems/rtems/status.inl,
+ rtems/macros/rtems/rtems/support.inl,
+ rtems/macros/rtems/rtems/tasks.inl, rtems/macros/rtems/rtems/timer.inl,
+ rtems/src/attr.c, rtems/src/clockget.c, rtems/src/clockset.c,
+ rtems/src/clocktick.c, rtems/src/dpmem.c, rtems/src/dpmemcreate.c,
+ rtems/src/dpmemdelete.c, rtems/src/dpmemexternal2internal.c,
+ rtems/src/dpmemident.c, rtems/src/dpmeminternal2external.c,
+ rtems/src/event.c, rtems/src/eventmp.c, rtems/src/eventreceive.c,
+ rtems/src/eventseize.c, rtems/src/eventsend.c,
+ rtems/src/eventsurrender.c, rtems/src/eventtimeout.c, rtems/src/intr.c,
+ rtems/src/intrbody.c, rtems/src/intrcatch.c, rtems/src/mp.c,
+ rtems/src/msg.c, rtems/src/msgmp.c, rtems/src/msgqallocate.c,
+ rtems/src/msgqbroadcast.c, rtems/src/msgqcreate.c,
+ rtems/src/msgqdelete.c, rtems/src/msgqflush.c,
+ rtems/src/msgqgetnumberpending.c, rtems/src/msgqident.c,
+ rtems/src/msgqreceive.c, rtems/src/msgqsend.c, rtems/src/msgqsubmit.c,
+ rtems/src/msgqtranslatereturncode.c, rtems/src/msgqurgent.c,
+ rtems/src/part.c, rtems/src/partcreate.c, rtems/src/partdelete.c,
+ rtems/src/partgetbuffer.c, rtems/src/partident.c, rtems/src/partmp.c,
+ rtems/src/partreturnbuffer.c, rtems/src/ratemon.c,
+ rtems/src/ratemoncancel.c, rtems/src/ratemoncreate.c,
+ rtems/src/ratemondelete.c, rtems/src/ratemongetstatus.c,
+ rtems/src/ratemonident.c, rtems/src/ratemonperiod.c,
+ rtems/src/ratemontimeout.c, rtems/src/region.c,
+ rtems/src/regioncreate.c, rtems/src/regiondelete.c,
+ rtems/src/regionextend.c, rtems/src/regiongetinfo.c,
+ rtems/src/regiongetsegment.c, rtems/src/regiongetsegmentsize.c,
+ rtems/src/regionident.c, rtems/src/regionmp.c,
+ rtems/src/regionreturnsegment.c, rtems/src/rtclock.c,
+ rtems/src/rtemsidtoname.c, rtems/src/rtemstimer.c, rtems/src/sem.c,
+ rtems/src/semcreate.c, rtems/src/semdelete.c, rtems/src/semflush.c,
+ rtems/src/semident.c, rtems/src/semmp.c, rtems/src/semobtain.c,
+ rtems/src/semrelease.c, rtems/src/semtranslatereturncode.c,
+ rtems/src/signal.c, rtems/src/signalcatch.c, rtems/src/signalmp.c,
+ rtems/src/signalsend.c, rtems/src/taskcreate.c, rtems/src/taskdelete.c,
+ rtems/src/taskgetnote.c, rtems/src/taskident.c,
+ rtems/src/taskinitusers.c, rtems/src/taskissuspended.c,
+ rtems/src/taskmode.c, rtems/src/taskmp.c, rtems/src/taskrestart.c,
+ rtems/src/taskresume.c, rtems/src/tasks.c, rtems/src/tasksetnote.c,
+ rtems/src/tasksetpriority.c, rtems/src/taskstart.c,
+ rtems/src/tasksuspend.c, rtems/src/taskvariableadd.c,
+ rtems/src/taskvariabledelete.c, rtems/src/taskvariableget.c,
+ rtems/src/taskwakeafter.c, rtems/src/taskwakewhen.c,
+ rtems/src/timercancel.c, rtems/src/timercreate.c,
+ rtems/src/timerdelete.c, rtems/src/timerfireafter.c,
+ rtems/src/timerfirewhen.c, rtems/src/timergetinfo.c,
+ rtems/src/timerident.c, rtems/src/timerreset.c, rtems/src/timerserver.c,
+ rtems/src/timerserverfireafter.c, rtems/src/timerserverfirewhen.c,
+ libmisc/cpuuse/cpuuse.c, libmisc/cpuuse/cpuuse.h,
+ libmisc/devnull/devnull.c, libmisc/devnull/devnull.h,
+ libmisc/dummy/dummy.c, libmisc/dumpbuf/dumpbuf.c,
+ libmisc/dumpbuf/dumpbuf.h, libmisc/fsmount/fsmount.c,
+ libmisc/fsmount/fsmount.h, libmisc/serdbg/serdbgio.c,
+ libmisc/serdbg/termios_printk.c, libmisc/stackchk/check.c,
+ libmisc/stackchk/internal.h, libmisc/stackchk/stackchk.h,
+ libmisc/untar/untar.c, libmisc/untar/untar.h,
+ libblock/include/rtems/ide_part_table.h, libblock/src/ata.c,
+ libblock/src/ide_part_table.c, libfs/src/dosfs/dosfs.h,
+ libfs/src/dosfs/fat.h, libfs/src/dosfs/fat_fat_operations.h,
+ libfs/src/dosfs/fat_file.h, libfs/src/dosfs/msdos.h,
+ libfs/src/dosfs/msdos_create.c, libfs/src/dosfs/msdos_dir.c,
+ libfs/src/dosfs/msdos_eval.c, libfs/src/dosfs/msdos_file.c,
+ libfs/src/dosfs/msdos_free.c, libfs/src/dosfs/msdos_fsunmount.c,
+ libfs/src/dosfs/msdos_handlers_dir.c,
+ libfs/src/dosfs/msdos_handlers_file.c, libfs/src/dosfs/msdos_init.c,
+ libfs/src/dosfs/msdos_initsupp.c, libfs/src/dosfs/msdos_misc.c,
+ libfs/src/dosfs/msdos_mknod.c, libfs/src/dosfs/msdos_node_type.c,
+ libfs/src/imfs/deviceio.c, libfs/src/imfs/imfs.h,
+ libfs/src/imfs/imfs_chown.c, libfs/src/imfs/imfs_config.c,
+ libfs/src/imfs/imfs_creat.c, libfs/src/imfs/imfs_debug.c,
+ libfs/src/imfs/imfs_directory.c, libfs/src/imfs/imfs_eval.c,
+ libfs/src/imfs/imfs_fchmod.c, libfs/src/imfs/imfs_fcntl.c,
+ libfs/src/imfs/imfs_fdatasync.c, libfs/src/imfs/imfs_free.c,
+ libfs/src/imfs/imfs_fsunmount.c, libfs/src/imfs/imfs_getchild.c,
+ libfs/src/imfs/imfs_gtkn.c, libfs/src/imfs/imfs_handlers_device.c,
+ libfs/src/imfs/imfs_handlers_directory.c,
+ libfs/src/imfs/imfs_handlers_link.c,
+ libfs/src/imfs/imfs_handlers_memfile.c, libfs/src/imfs/imfs_init.c,
+ libfs/src/imfs/imfs_initsupp.c, libfs/src/imfs/imfs_link.c,
+ libfs/src/imfs/imfs_mknod.c, libfs/src/imfs/imfs_mount.c,
+ libfs/src/imfs/imfs_ntype.c, libfs/src/imfs/imfs_readlink.c,
+ libfs/src/imfs/imfs_rmnod.c, libfs/src/imfs/imfs_stat.c,
+ libfs/src/imfs/imfs_symlink.c, libfs/src/imfs/imfs_unixstub.c,
+ libfs/src/imfs/imfs_unlink.c, libfs/src/imfs/imfs_unmount.c,
+ libfs/src/imfs/imfs_utime.c, libfs/src/imfs/ioman.c,
+ libfs/src/imfs/linearfile.c, libfs/src/imfs/memfile.c,
+ libfs/src/imfs/miniimfs_init.c, libcsupport/include/chain.h,
+ libcsupport/include/clockdrv.h, libcsupport/include/console.h,
+ libcsupport/include/iosupp.h, libcsupport/include/rtc.h,
+ libcsupport/include/spurious.h, libcsupport/include/timerdrv.h,
+ libcsupport/include/vmeintr.h, libcsupport/include/motorola/mc68230.h,
+ libcsupport/include/rtems/libcsupport.h,
+ libcsupport/include/rtems/libio.h, libcsupport/include/rtems/libio_.h,
+ libcsupport/include/rtems/termiostypes.h,
+ libcsupport/include/sys/termios.h, libcsupport/include/zilog/z8036.h,
+ libcsupport/include/zilog/z8530.h, libcsupport/include/zilog/z8536.h,
+ libcsupport/src/__brk.c, libcsupport/src/__gettod.c,
+ libcsupport/src/__sbrk.c, libcsupport/src/__times.c,
+ libcsupport/src/access.c, libcsupport/src/base_fs.c,
+ libcsupport/src/cfgetispeed.c, libcsupport/src/cfgetospeed.c,
+ libcsupport/src/cfsetispeed.c, libcsupport/src/cfsetospeed.c,
+ libcsupport/src/chdir.c, libcsupport/src/chmod.c,
+ libcsupport/src/chown.c, libcsupport/src/chroot.c,
+ libcsupport/src/close.c, libcsupport/src/ctermid.c,
+ libcsupport/src/dup.c, libcsupport/src/dup2.c, libcsupport/src/eval.c,
+ libcsupport/src/fchdir.c, libcsupport/src/fchmod.c,
+ libcsupport/src/fcntl.c, libcsupport/src/fdatasync.c,
+ libcsupport/src/fpathconf.c, libcsupport/src/fs_null_handlers.c,
+ libcsupport/src/fstat.c, libcsupport/src/fsync.c,
+ libcsupport/src/ftruncate.c, libcsupport/src/getdents.c,
+ libcsupport/src/getpwent.c, libcsupport/src/hosterr.c,
+ libcsupport/src/ioctl.c, libcsupport/src/isatty.c,
+ libcsupport/src/libio.c, libcsupport/src/libio_sockets.c,
+ libcsupport/src/link.c, libcsupport/src/lseek.c,
+ libcsupport/src/lstat.c, libcsupport/src/malloc.c,
+ libcsupport/src/mallocfreespace.c, libcsupport/src/mkdir.c,
+ libcsupport/src/mkfifo.c, libcsupport/src/mknod.c,
+ libcsupport/src/mount.c, libcsupport/src/newlibc.c,
+ libcsupport/src/no_libc.c, libcsupport/src/no_posix.c,
+ libcsupport/src/open.c, libcsupport/src/pathconf.c,
+ libcsupport/src/pipe.c, libcsupport/src/privateenv.c,
+ libcsupport/src/read.c, libcsupport/src/readlink.c,
+ libcsupport/src/rewinddir.c, libcsupport/src/rmdir.c,
+ libcsupport/src/seekdir.c, libcsupport/src/stat.c,
+ libcsupport/src/symlink.c, libcsupport/src/sync.c,
+ libcsupport/src/tcdrain.c, libcsupport/src/tcflow.c,
+ libcsupport/src/tcflush.c, libcsupport/src/tcgetattr.c,
+ libcsupport/src/tcgetprgrp.c, libcsupport/src/tcsendbreak.c,
+ libcsupport/src/tcsetattr.c, libcsupport/src/tcsetpgrp.c,
+ libcsupport/src/telldir.c, libcsupport/src/termios.c,
+ libcsupport/src/termiosinitialize.c, libcsupport/src/truncate.c,
+ libcsupport/src/umask.c, libcsupport/src/unixlibc.c,
+ libcsupport/src/unlink.c, libcsupport/src/unmount.c,
+ libcsupport/src/utime.c, libcsupport/src/write.c,
+ libnetworking/rtems/mkrootfs.c, libnetworking/rtems/mkrootfs.h: URL for
+ license changed.
+ PR 479/rtems_misc
+ * libcsupport/src/malloc.c: Per multiple standards realloc does not free
+ the original memory if the allocation of the requested larger block
+ fails.
+
+2003-09-03 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/msdos_create.c: Remove unused variable warning.
+
+2003-09-02 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/src/open.c: Fix typo.
+ * libcsupport/src/malloc.c: Remove test define left in.
+
+2003-09-02 Jiri Gaisler <jiri@gaisler.com>
+
+ PR 476/networking
+ * libnetworking/machine/in_cksum.h: Fix in_cksum calculation on SPARC.
+
+2003-09-02 Ilya Alexeev <ilya@continuum.ru>
+
+ PR 472/filesystem
+ src/malloc.c: Need to include apimutex.h when MALLOC_STATS is defined.
+
+2003-08-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/rtems-top.m4: Add RTEMS_API.
+ AC_DEFAULT_PREFIX([/opt/rtems-][RTEMS_API]).
+
+2003-08-18 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/rtems-debug.m4: Remove.
+ * aclocal/enable-rtems-debug.m4, aclocal/check-rtems-debug.m4: New
+ (Split out from rtems-debug.m4).
+ * automake/local.am: Remove "debug".
+ PR 449/rtems:
+ * posix/src/getegid.c, posix/src/geteuid.c, posix/src/getgid.c,
+ posix/src/getgroups.c, posix/src/getlogin.c, posix/src/getpgrp.c,
+ posix/src/getpid.c, posix/src/getppid.c, posix/src/getuid.c,
+ posix/src/setpgid.c, posix/src/setsid.c: Remove (Moved to
+ ../libcsupport/src).
+ * posix/Makefile.am: Reflect changes above.
+ PR 449/rtems:
+ * libcsupport/src/getegid.c, libcsupport/src/geteuid.c,
+ libcsupport/src/getgid.c, libcsupport/src/getgroups.c,
+ libcsupport/src/getlogin.c, libcsupport/src/getpgrp.c,
+ libcsupport/src/getpid.c, libcsupport/src/getppid.c,
+ libcsupport/src/getuid.c, libcsupport/src/setpgid.c,
+ libcsupport/src/setsid.c: New (Copied from ../posix/src).
+ * libcsupport/src/no_posix: Remove getpid and _getpid_r.
+ * libcsupport/Makefile.am: Reflect changes above.
+
+2003-08-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/fsmount/Makefile.am: Fix path to automake-includes.
+
+2003-08-14 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/mqueuenametoid.c, posix/src/semaphorenametoid.c: Added ID to
+ name lookup service and changed name of id/name translation status code.
+ This propagated to multiple functions. The user API service added was
+ rtems_object_id_to_name().
+ PR 92/rtems
+ * posix/Makefile.am, posix/src/alarm.c, posix/src/psignal.c: Added
+ ualarm() and usleep().
+ * posix/src/ualarm.c, posix/src/usleep.c: New files.
+ * score/Makefile.am, score/include/rtems/score/object.h,
+ score/include/rtems/score/objectmp.h, score/src/objectmp.c,
+ score/src/objectnametoid.c: Added ID to name lookup service and changed
+ name of id/name translation status code. This propagated to multiple
+ functions. The user API service added was rtems_object_id_to_name().
+ * score/src/objectidtoname.c: New file.
+ PR 408/filesystem
+ * score/score/Makefile.am, score/score/include/rtems/score/thread.h:
+ Added sync() service. As part of adding this service, the new RTEMS
+ service rtems_iterate_over_all_threads() was also added. This new
+ service makes it easier to iterate over all the tasks/threads in a
+ system and perform an action on them.
+ * score/score/src/iterateoverthreads.c: New file.
+ * score/ChangeLog: Fixed screwup.
+ * sapi/src/extensionident.c, rtems/Makefile.am, rtems/include/rtems.h,
+ rtems/include/rtems/rtems/status.h, rtems/src/dpmemident.c,
+ rtems/src/msgqident.c, rtems/src/partident.c, rtems/src/ratemonident.c,
+ rtems/src/regionident.c, rtems/src/semident.c, rtems/src/taskident.c,
+ rtems/src/timerident.c: Added ID to name lookup service and changed name
+ of id/name translation status code. This propagated to multiple
+ functions. The user API service added was rtems_object_id_to_name().
+ * rtems/src/rtemsidtoname.c: New file.
+ PR 408/filesystem
+ * libmisc/cpuuse/cpuuse.c: Added sync() service. As part of adding this
+ service, the new RTEMS service rtems_iterate_over_all_threads() was also
+ added. This new service makes it easier to iterate over all the
+ tasks/threads in a system and perform an action on them. This change is
+ to use the new thread iteration service.
+ * libcsupport/Makefile.am: Add fileio to list of interactive tests.
+ * libcsupport/src/sync.c: New (Copied from ../posix/src). New file.
+
+2003-08-13 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/fsmount/.cvsignore: New file.
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-08-11 Joel Sherrill <joel@OARcorp.com>
+
+ * configure.ac: Removed duplicate entry.
+
+2003-08-08 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add libmisc/fsmount/Makefile.
+
+2003-08-06 Till Strauman <strauman@slac.stanford.edu>
+
+ PR 435/networking
+ * libnetworking/rtems/rtems_showifstat.c: rtems_showifstat misses
+ printing the netmask.
+
+2003-08-06 Thomas Doerfler<Thomas.Doerfler@imd-systems.de>
+
+ PR 369/filesystem
+ * libmisc/Makefile.am, libmisc/shell/cmds.c, libmisc/wrapup/Makefile.am:
+ sample application to show the use of the DOSFS functions.
+ * libmisc/fsmount/Makefile.am, libmisc/fsmount/README,
+ libmisc/fsmount/fsmount.c, libmisc/fsmount/fsmount.h: New files.
+
+2003-08-05 Till Strauman <strauman@slac.stanford.edu>
+
+ PR 436/rtems_misc
+ * libmisc/monitor/mon-monitor.c: monitor registered commands list
+ manipulation bugs.
+ PR 442/filesystem
+ * libcsupport/src/open.c: file never closed if ftruncate() fails in
+ open().
+
+2003-08-05 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
+
+ PR 440/filesystem
+ * libfs/src/dosfs/fat_fat_operations.c: Improve write data speed for
+ DOSFS FAT12/FAT16 systems.
+ PR 439/filesystem
+ * libfs/src/dosfs/fat_file.c: flush temporary buffer when closing files.
+
+2003-08-05 <djc915@mail.usask.ca>
+
+ PR 443/filesystem
+ * libfs/src/imfs/deviceio.c: deviceio.c mishandles return codes.
+
+2003-08-04 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
+
+ PR 441/filesystem
+ * libfs/src/dosfs/msdos.h, libfs/src/dosfs/msdos_create.c,
+ libfs/src/dosfs/msdos_file.c, libfs/src/dosfs/msdos_init.c,
+ libfs/src/dosfs/msdos_mknod.c: add rename support to DOSFS.
+
+2003-07-24 Jennifer Averett <jennifer.averett@OARcorp.com>
+
+ PR 434/filesystem
+ * libfs/src/imfs/imfs_init.c, libfs/src/imfs/miniimfs_init.c: Modified
+ to return error code.
+ * libfs/src/imfs/imfs_initsup.c: Modified to set error upon memory
+ failure.
+
+2003-07-18 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 430/rtems
+ * score/include/rtems/score/watchdog.h: _Watchdog_Ticks_since_boot
+ should be a VOLATILE variable.
+ * score/src/watchdoginsert.c: 'restart' algorithm needs to enforce
+ reloading the list head in case a TICK interrupt during ISR_Flash()
+ modified the list. This is achieved by a proper VOLATILE cast. Also
+ _Watchdog_Sync_count++ should be protected by _ISR_Disable (prevent
+ corruption in case ISR calls watchdoginsert).
+ * score/src/watchdogadjust.c: ISR protection added.
+ * score/src/watchdogtickle.c: ISR protection added. NOTE: PowerPC BSPs
+ using the new exception processing MUST BE UPDATED to maintain
+ _ISR_Nest_level. See also PR288 which provides fixes for the affected
+ BSPs distributed with RTEMS.
+
+2003-07-16 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/ChangeLog: Correct format.
+
+2003-07-15 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Remove '/' after $(DESTDIR).
+ * wrapup/Makefile.am: Remove bogus $(MULTISUBDIR).
+
+2003-07-15 Chris Johns <cjohns@cybertec.com.au>
+
+ PR 431/filesystem
+ * libfs/src/dosfs/msdos.h: MSDOS Volume semaphore timeout is now NO
+ TIMEOUT. MSDOS volume opertations will wait for ever.
+
+2003-07-08 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Merge-in librpc/configure.ac.
+ * Makefile.am: Add librpc to SUBDIRS. Remove @subdirs@.
+ * configure.ac: Merge-in libcsupport/configure.ac.
+ * Makefile.am: Add libcsupport to SUBDIRS.
+ * configure.ac: Merge-in posix/configure.ac. Merge-in
+ itron/configure.ac. Misc. cosmetical changes.
+ * Makefile.am: Add posix, itron to SUBDIRS.
+ * configure.ac: Merge-in libnetworking/configure.ac. Remove "rtems-"
+ from RTEMS_VERSION. Add AC_CHECK_FUNCS([strsep strcasecmp snprintf]).
+ * Makefile.am: Add libmisc to SUBDIRS.
+ * configure.ac: Merge-in libmisc/configure.ac.
+ * Makefile.am: Add libmisc to SUBDIRS.
+ * configure.ac: Merge-in libfs/configure.ac.
+ * Makefile.am: Add libfs to SUBDIRS.
+ * configure.ac: Merge-in libblock/configure.ac.
+ * Makefile.am: Add libblock to SUBDIRS.
+ * configure.ac: Merge-in ada/configure.ac.
+ * Makefile.am: Add ada to SUBDIRS.
+ * itron/configure.ac: Remove (Merged-in into ../configure.ac).
+ * itron/Makefile.am: Reflect having merged configure.ac into
+ ../configure.ac.
+ * itron/src/config.h: New.
+ * posix/configure.ac: Remove (Merged-in into ../configure.ac).
+ * posix/Makefile.am: Reflect having merged configure.ac into
+ ../configure.ac.
+ * posix/src/config.h: New.
+ * score/cpu/Makefile.am: Add DIST_SUBDIRS = $(RTEMS_CPU).
+ * libmisc/configure.ac: Remove (Merged into ../configure.ac).
+ * libmisc/Makefile.am: Reflect having merged configure.ac into
+ ../configure.ac.
+ * libmisc/capture/config.h: New.
+ * libmisc/capture/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/cpuuse/config.h: New.
+ * libmisc/cpuuse/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/devnull/config.h: New.
+ * libmisc/devnull/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/dummy/config.h: New.
+ * libmisc/dummy/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/dumpbuf/config.h: New.
+ * libmisc/dumpbuf/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/monitor/config.h: New.
+ * libmisc/monitor/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/mw-fb/config.h: New.
+ * libmisc/mw-fb/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/rtmonuse/config.h: New.
+ * libmisc/rtmonuse/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/serdbg/config.h: New.
+ * libmisc/serdbg/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/shell/config.h: New.
+ * libmisc/shell/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/stackchk/config.h: New.
+ * libmisc/stackchk/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/untar/config.h: New.
+ * libmisc/untar/Makefile.am: Add config.h. Reflect having merged
+ configure.ac into ../configure.ac.
+ * libmisc/wrapup/Makefile.am: Reflect having merged configure.ac into
+ ../configure.ac.
+ * libmisc/capture/capture-cli.c, libmisc/capture/capture.c,
+ libmisc/cpuuse/cpuuse.c, libmisc/devnull/devnull.c,
+ libmisc/dummy/dummy.c, libmisc/dumpbuf/dumpbuf.c,
+ libmisc/monitor/mon-command.c, libmisc/monitor/mon-config.c,
+ libmisc/monitor/mon-dname.c, libmisc/monitor/mon-driver.c,
+ libmisc/monitor/mon-extension.c, libmisc/monitor/mon-itask.c,
+ libmisc/monitor/mon-manager.c, libmisc/monitor/mon-monitor.c,
+ libmisc/monitor/mon-mpci.c, libmisc/monitor/mon-object.c,
+ libmisc/monitor/mon-prmisc.c, libmisc/monitor/mon-queue.c,
+ libmisc/monitor/mon-server.c, libmisc/monitor/mon-symbols.c,
+ libmisc/monitor/mon-task.c, libmisc/mw-fb/mw_fb.c,
+ libmisc/mw-fb/mw_uid.c, libmisc/rtmonuse/rtmonuse.c,
+ libmisc/serdbg/serdbg.c, libmisc/serdbg/serdbgio.c,
+ libmisc/serdbg/termios_printk.c, libmisc/shell/cmds.c,
+ libmisc/stackchk/check.c, libmisc/untar/untar.c: Add config-header
+ support.
+ * librpc/configure.ac: Remove (Merged-in into ../configure.ac).
+ * librpc/Makefile.am, librpc/include/Makefile.am,
+ librpc/src/Makefile.am, librpc/src/rpc/Makefile.am,
+ librpc/src/xdr/Makefile.am: Reflect having merged configure.ac into
+ ../configure.ac.
+ * libblock/configure.ac: Remove (Merged into ../configure.ac).
+ * libblock/Makefile.am: Reflect having merged configure.ac into
+ ../configure.ac.
+ * libfs/configure.ac: Remove (Merged-in into ../configure.ac).
+ * libfs/Makefile.am, libfs/src/Makefile.am, libfs/src/dosfs/Makefile.am,
+ libfs/src/imfs/Makefile.am: Reflect having merged configure.ac into
+ ../configure.ac.
+ * libfs/src/dosfs/config.h: New.
+ * libfs/src/dosfs/Makefile.am: Add config.h.
+ * libfs/src/imfsfs/config.h: New.
+ * libfs/src/imfs/Makefile.am: Add config.h. Remove COMMON_C_FILES,
+ DOC_FILES (Unused).
+ * libfs/src/dosfs/fat.c: include config-header "config.h".
+ * libfs/src/dosfs/fat_fat_operations.c, libfs/src/dosfs/fat_file.c,
+ libfs/src/dosfs/msdos_conv.c: Ditto.
+ * libcsupport/configure.ac: Remove (Merged-in into ../configure.ac).
+ * libcsupport/Makefile.am: DOC_FILES = src/TODO src/CASES, Reflect
+ having merged configure.ac into ../configure.ac.
+ * libcsupport/src/config.h: New.
+ * libnetworking/configure.ac: Remove (Merged into ../configure.ac).
+ * libnetworking/Makefile.am, libnetworking/libc/Makefile.am,
+ libnetworking/lib/Makefile.am, libnetworking/wrapup/Makefile.am: Reflect
+ having merged configure.ac into ../configure.ac.
+ * libnetworking/kern/kern_mib.c: Use RTEMS_VERSION to setup osrelease.
+
+2003-07-08 Joel Sherrill <joel@OARcorp.com>
+
+ PR 419/rtems
+ * libcsupport/src/termios.c: Removed warning.
+
+2003-07-07 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/configure.ac: Remove RTEMS_BSP from
+ RTEMS_CHECK_MULTIPROCESSING.
+
+2003-07-07 Joel Sherrill <joel@OARcorp.com>
+
+ PR 417/rtems
+ * score/src/coresemsurrender.c: Correct incorrect check for
+ maximum_count reported by Sergei Organov <osv@topconrd.ru>.
+
+2003-07-03 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-ss-20030703.
+
+2003-07-02 Chris Johns <cjohns@cybertec.com.au>
+
+ * libfs/src/dosfs/Makefile.am, libfs/src/dosfs/msdos.h,
+ libfs/src/dosfs/msdos_conv.c, libfs/src/dosfs/msdos_create.c,
+ libfs/src/dosfs/msdos_dir.c, libfs/src/dosfs/msdos_misc.c: Patch from
+ Victor V. Vengerov <vvv@oktet.ru> to remove Linux code.
+ * libfs/src/dosfs/fat.c, libfs/src/dosfs/fat.h: Comment have been
+ updated.
+ * libcsupport/include/rtems/libio.h, libcsupport/src/termios.c: Add the
+ rtems_termios_bufsize call.
+
+2003-06-13 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/threadloadenv.c: Removed warnings.
+
+2003-06-12 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/objectmp.c, rtems/include/rtems/rtems/msgmp.h,
+ rtems/include/rtems/rtems/partmp.h,
+ rtems/include/rtems/rtems/regionmp.h, rtems/include/rtems/rtems/semmp.h,
+ rtems/src/msgmp.c, rtems/src/partmp.c, rtems/src/regionmp.c,
+ rtems/src/semmp.c: Removed warnings.
+
+2003-06-10 Phil Torre <ptorre@zetron.com>
+
+ PR 411/filesystem
+ * libfs/src/imfs/imfs_unlink.c: Fix bug where renaming a memfile and
+ then unlinking it causes a memory leak.
+
+2003-06-04 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/stackchk/check.c, libblock/src/ide_part_table.c: Removed
+ warnings.
+
+2003-05-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/include/rtems/rtems/types.h: Include stdint.h.
+ * libcsupport/Makefile.am: Conditionally install stdint.h/inttypes.h.
+ * libcsupport/configure.ac: Check for system-stdint.h/inttypes.h.
+
+2003-05-29 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/rtems/rtems_syscall.c: Removed warnings.
+
+2003-05-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR 409/core
+ * include/Makefile.am: Add rtems/stdint.h.
+ * include/rtems/stdint.h: New.
+ PR 321/bsps
+ * aclocal/env-rtemscpu.m4: Remove support for profile-variant.
+ * automake/compile.am, automake/local.am: Ditto.
+ PR 409:
+ * rtems/include/rtems/rtems/types.h: Include rtems/stdint.h. Apply
+ c99-types to typedef rtems_[un]signed[8|16|32|64].
+ PR 409:
+ * libcsupport/include/stdint.h: Include rtems/stdint.h.
+
+2003-05-15 cjohns@cybertec.com.au <cjohns@cybertec.com.au>
+
+ * libnetworking/netinet/in.h: PR406 - Added INET_ADDRSTRLEN per the
+ SUSv3 standard.
+
+2003-05-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * automake/compile.am: Remove LIBSUFFIX_VA (unused).
+
+2003-05-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/env-rtemscpu.m4: Merge-in env-rtemsbsp.m4.
+ * aclocal/env-rtemsbsp.m4, aclocal/enable-rtemsbsp.m4: Remove.
+ * aclocal/env-rtemscpu.m4: Remove stray '/' in setting up
+ project_libdir.
+
+2003-04-17 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
+
+ PR 399/rtems_misc
+ * libcsupport/src/termios.c: In canonical mode, when input is present in
+ the input buffer that contains an EOL character and some following
+ characters, a read call read data behind the EOL character, although it
+ should stop reading with the EOL character.
+
+2003-04-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/dummy/Makefile.am: Remove stray dummy.rel.
+ * libcsupport/src/no_posix.c: include <reent.h> instead of <sys/reent.h>.
+
+2003-04-17 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-ss-20030417.
+
+2003-04-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR 389/rtems
+ * libcsupport/src/no_posix.c: Correct _kill_r() prototype and make it
+ conditional on newlib.
+
+2003-04-15 Joel Sherrill <joel@OARcorp.com>
+
+ PR 388/networking
+ * libnetworking/kern/kern_sysctl.c: Revert previous patch and use
+ strlcpy() now that it is available. Also fixed some warnings.
+
+2003-04-11 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-ss-20020411.
+
+2003-04-03 Eri Valette <eric.valette@free.fr>
+
+ PR 381/core
+ * libcsupport/src/newlibc.c: Switch from using _REENT_INIT to
+ _REEINT_INIT_PTR to fix strange run-time problem where EIP was corrupted
+ on pc386 BSP.
+
+2003-03-27 Joel Sherrill <joel@OARcorp.com>
+
+ * libblock/Makefile.am: ATA code depends upon libchip/ide which is not
+ allowed in the cpukit source code since it must be buildable independent
+ of any BSP. These files were moved to libchip/ide.
+ * libblock/include/rtems/ata.h, libblock/include/rtems/ata_internal.h,
+ libblock/src/ata.c: Removed.
+ * libnetworking/kern/kern_sysctl.c: Converted from BSP strlcpy() to
+ strncpy().
+
+2003-03-25 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
+
+ PR 367/filesystem
+ * libblock/Makefile.am, libblock/include/rtems/ide_part_table.h,
+ libblock/src/ata.c, libblock/src/ide_part_table.c: Some bugs were still
+ present in the DOSFS implementation: - FAT12 did not work properly on
+ Big-Endian machines - Some synchronization and error handling problems
+ were present - Some legal codings for EOC were not recognized.
+ PR 367/filesystem
+ * libfs/src/dosfs/Makefile.am, libfs/src/dosfs/fat.c,
+ libfs/src/dosfs/fat.h, libfs/src/dosfs/fat_fat_operations.c,
+ libfs/src/dosfs/fat_file.c, libfs/src/dosfs/msdos.h,
+ libfs/src/dosfs/msdos_dir.c: Some bugs were still present in the DOSFS
+ implementation: - FAT12 did not work properly on Big-Endian machines. -
+ Some synchronization and error handling problems were present. - Some
+ legal codings for EOC were not recognized.
+
+2003-03-25 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/rtems/rtems_bsdnet_malloc_starvation.c: Fixed name of
+ include file.
+
+2003-03-18 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 356/bsps
+ * score/src/threadhandlerc: This patch makes RTEMS/PowerPC eabi
+ compliant. Let Thread_Handler verify that _init/_main are non-NULL
+ before calling them (gives the linker script/user more freedom to handle
+ special cases).
+ PR 356/bsps
+ * libnetworking/sys/linker_set.h: This patch makes RTEMS/PowerPC eabi
+ compliant. Declare all linker-script defined addresses as variables of
+ unknown size and not as short objects like 'int', 'void*' etc. Since
+ only addresses are used and never those variable's values, the type used
+ in a declaration is not important.
+
+2003-03-18 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libcsupport/configure.ac: AC_CHECK_FUNCS(strlcpy strlcat).
+ * libcsupport/src/strlcat.c, libcsupport/src/strlcpy.c: New (extracted
+ from pppd/utils.c).
+ * libcsupport/Makefile.am: Add BSD_C_FILES, strlcat.c, strlcpy.c.
+
+2003-03-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Remove '/' after $(DESTDIR) to work around Cygwin
+ mistreating paths.
+
+2003-03-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Reflect changes to project_libdir.
+ * aclocal/env-rtemscpu.m4: Remove obsolete comment. Add MULTISUBDIR to
+ project_libdir.
+ * aclocal/env-rtemscpu.m4: Remove RTEMS_ROOT (Unused).
+ * aclocal/env-rtemsbsp.m4: Remove RTEMS_ROOT (Unused). Remove
+ RTEMS_PROJECT_ROOT (Unused).
+ * aclocal/tool-paths.m4: Delete.
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+ * aclocal/rtems-top.m4: Add AC_CONFIG_AUX_DIR.
+ * configure.ac: AC_PREREQ(2.57).
+ * configure.ac: Remove sptables.h.in.
+ * itron/configure.ac: Remove AC_CONFIG_AUX_DIR.
+ * sapi/Makefile.am: Remove stray reference to sptables.h.in.
+ * sapi/include/rtems/sptables.h: New.
+ * sapi/include/rtems/sptables.h.in, sapi/include/.cvsignore,
+ sapi/include/rtems/.cvsignore, sapi/inline/.cvsignore,
+ sapi/inline/rtems/.cvsignore, sapi/macros/.cvsignore,
+ sapi/macros/rtems/.cvsignore, sapi/src/.cvsignore: Remove.
+ * libmisc/configure.ac, libblock/configure.ac, libfs/configure.ac,
+ libcsupport/configure.ac, libnetworking/configure.ac: Remove
+ AC_CONFIG_AUX_DIR.
+ * libnetworking/netinet/in_chksum.c: Remove duplicate case to include
+ in_chksum_arm.c.
+
+2003-02-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_SUBST(RTEMS_VERSION). AC_DEFINE(RTEMS_VERSION)
+ to propagate it through cpuopts.h.
+ * sapi/include/rtems/sptables.h.in: Remove RTEMS_VERSION (Moved to
+ cpuopts.h).
+
+2003-02-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: AC_SUBST(RTEMS_VERSION,_RTEMS_VERSION).
+
+2003-02-20 Wolfram Wadepohl <W.Wadepohl@indumat.de>
+
+ PR 357/rtems_misc
+ * libcsupport/src/termios.c (rtems_termios_open): Fixed code the
+ incorrectly checked that the wrong pointer during allocation was NULL.
+
+2003-02-20 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 351/networking
+ * libnetworking/nfs/bootp_subr.c: Fix ridiculous leak in bootp and use
+ strdup_bootp_realloc() everywhere for sake of consistency.
+
+2003-02-18 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/gcc-isystem.m4: New.
+ * aclocal/gcc-specs.m4: Remove.
+ * aclocal/prog-cc.m4: Remove RTEMS_GCC_SPECS. Add RTEMS_GCC_ISYSTEM.
+ Reformat setting up RTEMS_CPPFLAGS.
+ * automake/local.am: Introduce depend-gcc. Remove ${ARCH}.
+ * automake/compile.am: Remove GCCSPECS, GCC_SPECS, CONFIG.CC, CC, CPP.
+ Add ${ARCH}. depend-gcc.
+ * aclocal/prog-cc.m4: Set up RTEMS_CPPFLAGS.
+ * aclocal/env-rtemscpu.m4: Remove GCC_SPECS.
+ * aclocal/env-rtemsbsp.m4: Remove GCC_SPECS. capture/capture-cli.c: Add
+ proper definition to avoid compiler warnings. Apply int = getchar().
+ * libcsupport/src/privateenv.c: Fix prototype for free_user_env.
+
+2003-02-14 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 352/rtems_misc
+ * libmisc/shell/shell.c: make rtems_shell main task an FP enabled task.
+
+2003-02-14 Joel Sherrill <joel@OARcorp.com>
+
+ AMD a29k declared obsolete.
+ * score/cpu/Makefile.am: Removed reference.
+ * score/cpu/a29k/.cvsignore, score/cpu/a29k/ChangeLog,
+ score/cpu/a29k/Makefile.am, score/cpu/a29k/amd.ah, score/cpu/a29k/asm.h,
+ score/cpu/a29k/configure.ac, score/cpu/a29k/cpu.c,
+ score/cpu/a29k/cpu_asm.S, score/cpu/a29k/pswmacro.ah,
+ score/cpu/a29k/register.ah, score/cpu/a29k/sig.S,
+ score/cpu/a29k/rtems/.cvsignore, score/cpu/a29k/rtems/score/.cvsignore,
+ score/cpu/a29k/rtems/score/a29k.h, score/cpu/a29k/rtems/score/cpu.h,
+ score/cpu/a29k/rtems/score/cpu_asm.h,
+ score/cpu/a29k/rtems/score/types.h: Removed.
+
+2003-02-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/canonical-target-name.m4: Transform tic4x -> RTEMS_CPU=c4x.
+
+2003-02-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * itron/configure.ac: AM_INIT_AUTOMAKE([1.7.2]).
+ * itron/configure.ac: AC_PREREQ(2.57).
+ * posix/configure.ac: AM_INIT_AUTOMAKE([1.7.2]).
+ * posix/configure.ac: AC_PREREQ(2.57).
+ * librpc/configure.ac: AM_INIT_AUTOMAKE([1.7.2]).
+ * librpc/configure.ac: AC_PREREQ(2.57).
+ * libblock/configure.ac: AM_INIT_AUTOMAKE([1.7.2]).
+ * libblock/configure.ac: AC_PREREQ(2.57).
+ * libfs/configure.ac: AM_INIT_AUTOMAKE([1.7.2]).
+ * libfs/configure.ac: AC_PREREQ(2.57).
+ * libcsupport/configure.ac: AM_INIT_AUTOMAKE([1.7.2]).
+ * libcsupport/configure.ac: AC_PREREQ(2.57).
+ * libnetworking/configure.ac: AM_INIT_AUTOMAKE([1.7.2]).
+ * libnetworking/configure.ac: AC_PREREQ(2.57).
+
+2003-02-11 Mike Siers <mikes@poliac.com>
+
+ * libnetworking/rtems/rtems_glue.c: A small patch to the network daemon
+ task code. I just added code to check the return value of the
+ rtems_bsdnet_event_receive function. Only when this function returns a
+ SUCCESSFUL status, will the event flags be checked. This is more of a
+ code cleanup issue than a bug. The patch will just ensure the ipintr()
+ and arpintr() functions are only called when a event is signaled.
+
+2003-02-06 Mike Siers <mikes@poliac.com>
+
+ PR 342/networking
+ * libnetworking/kern/uipc_mbuf.c: The RTEMS version of the m_copyback is
+ changing the m_len value of the mbuf. I looked into the source from
+ another BSD system and the mbuf length is not changed inside this
+ function. The m_copyback function is only being used in the
+ net/rtsock.c file. So I think this problem is only visable under
+ certain routing table conditions.
+
+2003-02-06 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/include/sys/ioccom.h: Include <sys/types.h> not
+ <machine/types.h> so Linux port builds.
+
+2003-02-05 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 340/filesystem
+ * libcsupport/src/fcntl.c: Add missing _fcntl_r assumed to exist by
+ newlib.
+
+2003-02-05 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
+
+ PR 341/networking
+ * libnetworking/lib/ftpfs.c: Account for NULL at end of strings when
+ malloc()'ing memory.
+
+2003-02-05 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/include/sys/ioccom.h: Fix so not using internal RTEMS
+ types in libc code.
+
+2003-02-03 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 339/filesystem
+ * libcsupport/src/chroot.c: Fix violation of FS node object copy
+ semantics.
+
+2003-02-03 Steven Johnson <sjohnson@neurizon.net>
+
+ PR 338/filesystem
+ * libfs/src/imfs/ioman.c: Fix reentrancy problem with
+ rtems_io_lookup_name() (API change).
+
+2003-02-03 Joel Sherrill <joel@OARcorp.com>
+
+ PR 338/filesystem
+ * sapi/include/rtems/io.h, sapi/src/io.c: Side-effect of fixing
+ reentrancy problem with rtems_io_lookup_name() (API change).
+ PR 338/filesystem
+ * libcsupport/src/unixlibc.c: Side-effect of fixing reentrancy problem
+ with rtems_io_lookup_name() (API change).
+
+2003-01-28 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-ss-20030128.
+ * libnetworking/Makefile.am: Add kern/kern_sysctl.c to Makefile.am so
+ networking tests build. This was subsequently reported as PR337 before I
+ committed the fix.
+
+2003-01-27 Till Straumann <strauman@SLAC.Stanford.edu>
+
+ * libnetworking/libc/getproto.c, libnetworking/libc/getprotoname.c:
+ modification to call getprotoent_static() if fopen() on /etc/protocols
+ fails.
+
+2003-01-27 Juan Zamorano <jzamora@fi.upm.es>
+
+ * posix/src/ptimer1.c: Correct problem which could lead to overflow in
+ time math.
+
+2003-01-27 Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+
+ * libblock/src/blkdev.c: Per PR331 fix bug which is tripped by writing
+ 512 byte blocks to 512 byte aligned positions.
+
+2003-01-27 Dan Smisko <dan@balanced.com>
+
+ * libmisc/stackchk/check.c: Fix problem where _Objects_Get_information()
+ will dereference a null pointer when checking the interrupt stack. If
+ there's something at 0, you may be ok at run time but it is wrong.
+ * libmisc/monitor/mon-command.c: Correct two potential NULL references.
+
+2003-01-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * automake/local.am: Remove distclean-local. Remove PROJECT_TOOLS.
+
+2003-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * automake/compile.am: Remove CLEAN_DEPEND (Unused). Remove
+ CLOBBER_DEPEND (Unused).
+
+2003-01-15 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/netinet/tcp_subr.c, libnetworking/netinet/udp_usrreq.c:
+ Add args to INP_INFO_RLOCK, INP_INFO_RUNLOCK, INP_LOCK, INP_UNLOCK
+ macros.
+
+2003-01-10 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libcsupport/Makefile.am: Eliminate OBJS.
+
+2003-01-10 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/objectmp.c: Corrected use of name parameter to reflect that
+ it is actually the name not a pointer to the name.
+ * rtems/src/msg.c, rtems/src/part.c, rtems/src/sem.c, rtems/src/tasks.c:
+ Correct object class control structure initialization for
+ multiprocessing configurations.
+ * libcsupport/include/rtems/libio.h: Rename __dev_t to __rtems_dev_t to
+ avoid conflict with GNU/Linux header files.
+
+2003-01-03 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 303
+ * libcsupport/src/base_fs.c, libcsupport/src/getpwent.c,
+ libcsupport/src/privateenv.c: Fix violation of node_access copy
+ symantics.
+
+2003-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/ChangeLog: Corrected entry for sysconf.c which did not include
+ PR.
+
+2003-01-03 Jitendra Vegiraju <jvegiraju@netscape.net>
+
+ * libnetworking/sys/queue.h: Fix alignment problem on ARM.
+
+2003-01-03 Jay Monkman <jtm@smoothsmoothie.com>
+
+ * posix/src/mqueueopen.c: Actually open the message queue descriptor so
+ it is available for others to use.
+
+2003-01-03 Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+
+ * libblock/src/ata.c, libblock/src/bdbuf.c: Correct invocation of
+ rtems_task_mode() so the task's preemption mode setting is properly
+ maintained.
+ * libfs/src/dosfs/msdos_initsupp.c: Specify inherited priority as 0
+ since this is a FIFO queuing semaphore.
+
+2003-01-03 Chris Johns <cjohns@cybertec.com.au>
+
+ * libnetworking/Makefile.am: Added sys/linker_set.h.
+ * libnetworking/kern/Makefile.am: Added kern_mib.c and kern_sysctl.c.
+ * libnetworking/kern/uipc_socket.c: OID changed from KERN_SOMAXCONN to
+ KIPC_SOMAXCONN.
+ * libnetworking/kern/uipc_socket2.c: OID changed from KERN_MAXSOCKBUF to
+ KIPC_MAXSOCKBUF.
+ * libnetworking/net/if_ethersubr.c: FreeBSD 2.2.2 does not have a
+ _net_link node while 5.0 does.
+ * libnetworking/net/if_ppp.c: Removed the TEXT_SET define as these
+ macros are now implemented.
+ * libnetworking/net/rtsock.c: Enable sysctl support plus fix the bug
+ with the lastest FreeBSD sysctl header file.
+ * libnetworking/netinet/icmp_var.h: FreeBSD 2.2.2 does not have a
+ _net_inet_icmp node while 5.0 does.
+ * libnetworking/netinet/if_ether.c: FreeBSD 2.2.2 does not have a
+ _net_link_ether node while 5.0 does.
+ * libnetworking/netinet/igmp_var.h: FreeBSD 2.2.2 does not have a
+ _net_inet_igmp node while 5.0 does.
+ * libnetworking/netinet/in_pcb.c: Fixed the arguments to the sysctl
+ call. Add inp_gencnt and ipi_count. These are used when listing
+ connections.
+ * libnetworking/netinet/in_pcb.h: Added counters to aid the listing of
+ connections.
+ * libnetworking/netinet/in_var.h: Provide the _net_inet_ip and
+ _net_inet_raw nodes.
+ * libnetworking/netinet/ip_fw.c: Disable the firewall sysctl calls.
+ * libnetworking/netinet/tcp_subr.c: Merge tcp_pcblist from the lastest
+ FreeBSD source.
+ * libnetworking/netinet/tcp_var.h: Add structures needed by net-snmp to
+ list connections.
+ * libnetworking/netinet/udp_usrreq.c: Merged udp_pcblist from the
+ lastest FreeBSD source.
+ * libnetworking/netinet/udp_var.h: Added the sysctl id UDPCTL_PCBLIST.
+ Used by net-snmp.
+ * libnetworking/rtems_glue.c: Call sysctl_register_all when initialising
+ the network stack to register all the sysctl calls. These are in the
+ special sections and required an updated linker script.
+ * libnetworking/rtems/rtems_syscall.c: Add the sysctl call.
+ * libnetworking/sys/kernel.h: Use the lastest FreeBSD method of handling
+ sysctl structures. This now held in the sys/linker_set.h file.
+ * libnetworking/sys/queue.h: This is from the lastest FreeBSD code with
+ the circular code merged back in as it is not used in the lastest
+ FreeBSD kernel.
+ * libnetworking/sys/sysctl.h: The lastest sysctl. This was needed to use
+ with the new linker set method. The FreeBSD 2.2.2 version has asm hacks.
+ The lastest version of the FreeBSD does not have these hacks. It uses
+ gcc attribute directives.
+
+2002-12-26 Till Straumann <strauman@slac.stanford.edu
+
+ * libcsupport/src/fchdir.c: PR302 fix violation of FS node object copy
+ semantics.
+
+2002-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * automake/compile.am: Remove $(RTEMS_BSP_CFLAGS).
+
+2002-12-18 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/Makefile.am: Include netinet sources.
+
+2002-12-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Fix path to libxdr and librpc (Another typo in
+ from the 2002-12-12 patch).
+
+2002-12-13 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Fix typo in yesterday's patch.
+
+2002-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Don't create $ARCH. Use install-data-local to
+ install librtemscpu.a.
+ * wrapup/Makefile.am: Add libmisc.
+ * configure.ac: Add AC_CONFIG_SUBDIR(libmisc).
+ * itron/Makefile.am, posix/Makefile.am: Don't create $ARCH as
+ side-effect of compilation.
+ * score/Makefile.am: Don't create $ARCH.
+ * sapi/Makefile.am: Don't create $ARCH as side-effect of compilation.
+ * rtems/Makefile.am: Don't create $ARCH as side-effect of compilation.
+ Re-order all-local.
+ * libmisc/configure.ac: Require autoconf-2.57+automake-1.7.2.
+ * libmisc/capture/Makefile.am: Eliminate C_O_FILES.
+ * libmisc/cpuuse/Makefile.am, libmisc/devnull/Makefile.am,
+ libmisc/dummy/Makefile.am, libmisc/dumpbuf/Makefile.am,
+ libmisc/monitor/Makefile.am, libmisc/rtmonuse/Makefile.am,
+ libmisc/serdbg/Makefile.am, libmisc/shell/Makefile.am,
+ libmisc/stackchk/Makefile.am, libmisc/untar/Makefile.am: Ditto.
+ * libmisc/mw-fb/Makefile.am: Eliminate C_O_FILES. Eliminate SRCS. Moving
+ libmisc from rtems/c/src to rtems/cpukit.
+ * libmisc/Makefile.am: Reflect new path.
+ * libmisc/configure.ac: Reflect new path. Use RTEMS_ENV_RTEMSCPU
+ instead of RTEMS_ENV_RTEMSBSP. Remove RTEMS_PROJECT_ROOT.
+ * libmisc/capture/Makefile.am: Reflect new path. Remove OBJS from
+ all-local.
+ * libmisc/cpuuse/Makefile.am, libmisc/devnull/Makefile.am,
+ libmisc/dummy/Makefile.am, libmisc/dumpbuf/Makefile.am,
+ libmisc/monitor/Makefile.am, libmisc/mw-fb/Makefile.am,
+ libmisc/rtmonuse/Makefile.am, libmisc/serdbg/Makefile.am,
+ libmisc/shell/Makefile.am, libmisc/stackchk/Makefile.am,
+ libmisc/untar/Makefile.am: Ditto.
+ * libmisc/wrapup/Makefile.am: Reflect new path.
+ * libblock/Makefile.am: Eliminate C_O_FILES. Eliminate SRCS.
+ * libfs/src/imfs/Makefile.am: Eliminate C_O_FILES.
+ * libfs/src/dosfs/Makefile.am: Ditto.
+ * libnetworking/Makefile.am: Merge-in kern/Makefile.am, net/Makefile.am,
+ netinet/Makefile.am, netinet/Makefile.am, nfs/Makefile.am,
+ rtems/Makefile.am.
+ * libnetworking/kern/Makefile.am, libnetworking/net/Makefile.am,
+ libnetworking/netinet/Makefile.am, libnetworking/nfs/Makefile.am,
+ libnetworking/rtems/Makefile.am: Remove.
+ * libnetworking/wrapup/Makefile.am: Reflect changes above.
+ * libnetworking/configure.ac: Ditto.
+
+2002-12-11 Vladimir Nesic <vnesic@dkts.co.yu>
+
+ * posix/src/cancelrun.c, posix/src/cleanuppop.c: Get the last real node
+ not the permanent null last node.
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/kern/Makefile.am: Remove C_O_FILES. Don't let all-local
+ depend on $OBJS).
+ * libnetworking/lib/Makefile.am, libnetworking/libc/Makefile.am,
+ libnetworking/net/Makefile.am, libnetworking/netinet/Makefile.am,
+ libnetworking/nfs/Makefile.am, libnetworking/rtems/Makefile.am: Ditto.
+
+2002-12-10 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/configure.ac: Remove RTEMS_CHECK_CUSTOM_BSP.
+ * libmisc/capture/Makefile.am, libmisc/cpuuse/Makefile.am,
+ libmisc/devnull/Makefile.am, libmisc/dummy/Makefile.am,
+ libmisc/dumpbuf/Makefile.am, libmisc/monitor/Makefile.am,
+ libmisc/mw-fb/Makefile.am, libmisc/rtmonuse/Makefile.am,
+ libmisc/serdbg/Makefile.am, libmisc/shell/Makefile.am,
+ libmisc/stackchk/Makefile.am, libmisc/untar/Makefile.am,
+ libmisc/wrapup/Makefile.am: Don't include @RTEMS_BSP@.cfg.
+
+2002-12-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/env-rtemsbsp.m4, aclocal/env-rtemscpu.m4: Remove
+ RTEMS_CHECK_CUSTOM_BSP.
+ * aclocal/check-bsps.m4: Remove.
+ * wrapup/Makefile.am: Remove *_OBJS, use LIBS+= instead.
+ * configure.ac: Require autoconf >= 2.54, automake-1.7.2.
+ * wrapup/Makefile.am, configure.ac: Reflect changes to score/.
+ * wrapup/Makefile.am, configure.ac: Reflect changes to sapi/.
+ * configure.ac: Add AC_SUBST(INLINEdir).
+ * wrapup/Makefile.am, configure.ac: Reflect changes to rtems/.
+ * wrapup/Makefile.am: Reflect changes to posix/. Reflect changes to
+ itron/.
+ * itron/include/Makefile.am, itron/inline/Makefile.am,
+ itron/macros/Makefile.am, itron/src/Makefile.am: Remove.
+ * itron/Makefile.am: Merge-in removed Makefile.ams.
+ * itron/configure.ac: Reflect changes above.
+ * posix/include/Makefile.am, posix/inline/Makefile.am,
+ posix/macros/Makefile.am, posix/src/Makefile.am: Remove.
+ * posix/Makefile.am: Merge-in removed Makefile.ams.
+ * posix/configure.ac: Reflect changes above.
+ * score/Makefile.am: Fix macro-file installation.
+ * score/Makefile.am: Move include/rtems/score/cpuopts.h to STD_H_FILES.
+ * score/include/Makefile.am, score/inline/Makefile.am,
+ score/macros/Makefile.am, score/src/Makefile.am: Remove.
+ * score/Makefile.am: Merge-in removed Makefile.ams.
+ * sapi/include/Makefile.am, sapi/inline/Makefile.am,
+ sapi/macros/Makefile.am, sapi/src/Makefile.am: Remove.
+ * sapi/Makefile.am: Merge-in removed Makefile.ams.
+ * rtems/include/Makefile.am, rtems/inline/Makefile.am,
+ rtems/macros/Makefile.am, rtems/src/Makefile.am: Remove.
+ * rtems/Makefile.am: Merge-in removed Makefile.ams.
+
+2002-12-06 Vladimir Nesic <vnesic@dkts.co.yu>
+
+ * posix/inline/rtems/posix/cond.inl, posix/macros/rtems/posix/cond.inl:
+ Implemented PTHREAD_COND_INITIALIZER support. Vladimir implemented the
+ inline version and Joel adapted it to the macro version.
+
+2002-12-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * automake/compile.am: Rework *FLAGS, AM_*FLAGS handling.
+ * automake/multilib.am: Don't include @RTEMS_BSP@.cfg.
+ * automake/compile.am: Remove hard-coded CFLAGS_PROFILE_V. Add
+ autoconf-supplied CPU_CFLAGS, CFLAGS_OPTIMIZE_V, CFLAGS_DEBUG_V,
+ CFLAGS_PROFILE_V. Hard-code RTEMS_CFLAGS_PROFILE = -pg.
+ * aclocal/prog-cc.m4: Sync with toplevel/aclocal/prog-cc.m4. Remove
+ GCCSED.
+ * aclocal/env-rtemsbsp.m4: Add AC_ARG_VAR for CPU_CFLAGS,
+ CFLAGS_OPTIMIZE_V, CFLAGS_DEBUG_V, CFLAGS_PROFILE_V.
+ * aclocal/rtems-flags.m4: New.
+ * libcsupport/configure.ac: Add various checks to enhance portability.
+ * libcsupport/src/termios.c: Reflect changes to configure.ac.
+
+2002-12-06 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/src/malloc.c: Fixed code that incorrected did a disable
+ dispatch instead of locking and unlocking the allocator mutex.
+
+2002-12-02 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/include/rtems/posix/timer.h, posix/src/keygetspecific.c,
+ posix/src/posixtimespecsubtract.c, posix/src/ptimer1.c,
+ posix/src/semunlink.c: Added casts to eliminate warnings on 16-bit
+ targets like the h8300.
+ * score/include/rtems/score/object.h, score/include/rtems/score/tod.h,
+ rtems/include/rtems/rtems/support.h: Added casts to eliminate warnings
+ on 16 bit targets like the h8300.
+ * libmisc/stackchk/check.c: Better handling of task name.
+ * libblock/src/bdbuf.c: Added cast to remove warning.
+ * libfs/src/dosfs/fat.h, libfs/src/dosfs/msdos.h: Added casts to remove
+ warnings on 16 bit targets like the h8300.
+ * libcsupport/include/rtems/libio.h: Internally use a union of an
+ unsigned64 and major/minor device so we don't get into trouble shifting.
+ The h8300 seemed to be impossible to remove warnings otherwise.
+ Eventually the structure definition of a dev_t might be better anyway.
+ * libcsupport/include/sys/ioccom.h: Added casts to remove warnings on 16
+ bit targets.
+
+2002-11-29 Eric Norum <eric.norum@usask.ca>
+
+ PR 316
+ * posix/src/sysconf.c: Add support for _SC_GETPW_R_SIZE_MAX. Return
+ error rather than panic if argument is unsupported.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * automake/compile.am: Remove CFLAGS_DEBUG_OPTIMIZE_V (Unused).
+ * aclocal/sysv-ipc.m4: Adaptation to autoconf-2.5x.
+ * aclocal/check-newlib.m4: Sync with ../aclocal/check-newlib.m4.
+ * itron/configure.ac: Cosmetical fixes.
+ * itron/configure.ac: Fix package name.
+ * posix/configure.ac: Cosmetical fixes.
+ * posix/configure.ac, librpc/configure.ac, libblock/configure.ac: Fix
+ package name.
+ * libfs/configure.ac: Cosmetical fixes.
+ * libfs/configure.ac: Fix package name.
+ * libcsupport/configure.ac: Cosmetical fixes.
+ * libcsupport/configure.ac, libnetworking/configure.ac: Fix package name.
+
+2002-11-18 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * include/rtems/libio_.h: Remove.
+ * libcsupport/configure.ac: Check for sys/cdefs.h, Add NEED_SYS_CDEFS_H.
+ Add check for CHAR_BIT.
+ * libcsupport/Makefile.am: Conditionally install sys/cdefs.h iff using
+ newlib or if the host does not provide sys/cdefs.h (Fixes Linux/posix).
+ * libcsupport/configure.ac: Remove -ansi -fasm. Add checks to diagnose
+ potential system header conflicts.
+ * libcsupport/Makefile.am: Unconditionally install sys/cdefs.h.
+ * libnetworking/Makefile.am: Merge-in HEADER-handling from
+ net/Makefile.am, netinet/Makefile.am, nfs/Makefile.am.
+ * libnetworking/net/Makefile.am, libnetworking/netinet/Makefile.am,
+ libnetworking/nfs/Makefile.am: Remove *_HEADERS.
+
+2002-11-18 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-ss-20021118.
+
+2002-11-15 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * include/rtems/userenv.h: Rely upon <limits.h> for
+ _POSIX_LOGIN_NAME_MAX.
+ * aclocal/prog-cc.m4: Acknowledge configuration-time CFLAGS.
+ * automake/compile.am: Acknowledge configuration-time CFLAGS. Remove
+ CFLAGS_DEFAULT.
+ * libmisc/monitor/mon-commands.c: Removed warnings for RTEMS_UNIX.
+ * libblock/src/diskdevs.c: Include <unistd.h> to remove warning.
+ * libnetworking/Makefile.am: Merge-in arpa/Makefile.am,
+ machine/Makefile.am, sys/Makefile.am, vm/Makefile.am. Add . to SUBDIRS.
+ * libnetworking/arpa/Makefile.am, libnetworking/machine/Makefile.am,
+ libnetworking/sys/Makefile.am, libnetworking/vm/Makefile.am: Remove.
+ * libnetworking/configure.ac: Reflect changes above.
+
+2002-11-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/capture/Makefile.am, libmisc/serdbg/Makefile.am: Remove
+ AUTOMAKE_OPTIONS.
+ * libmisc/serdbg/serdbgio.c: Add #include <unistd.h>.
+ * libmisc/shell/Makefile.am, libmisc/wrapup/Makefile.am: Add
+ RTEMS_LIBSHELL conditional.
+ * libmisc/configure.ac: Check for stdio assignments. Add RTEMS_LIBSHELL
+ conditional.
+
+2002-11-14 Joel Sherrill <joel@OARcorp.com>
+
+ * score/macros/rtems/score/object.inl: Keep consistent with inline
+ version.
+
+2002-11-13 Paul Whitfield <paulw@microsol.iinet.net.au>
+
+ * rtems/src/regionreturnsegment.c: When RTEMS_REGION_SHRED_ON_FREE is
+ set, there should have been an & in front of size.
+
+2002-11-11 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-ss-20021111.
+
+2002-11-07 <strauman@slac.stanford.edu>
+
+ * libcsupport/src/mount.c: Per PR297, correct fs_mountme failure paths.
+
+2002-11-06 Chris Johns <ccj@acm.org>
+
+ * libnetworking/sys/select.h: Add C++ to C external.
+
+2002-11-04 Joel Sherrill <joel@OARcorp.com>
+
+ * librpc/src/rpc/pmap_rmt.c: Removed warnings.
+
+2002-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/kern/uipc_mbuf.c: Comment out m0 in m_copydata to
+ suppress warning.
+
+2002-11-01 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog, posix/ChangeLog: Corrected.
+ * libmisc/stackchk/check.c: Removed warnings.
+ * libcsupport/ChangeLog, libnetworking/ChangeLog: Corrected.
+
+2002-11-01 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/nfs/bootp_subr.c, libnetworking/rtems/rtems_bsdnet.h,
+ libnetworking/rtems/rtems_glue.c: Till Straumann's patch (PR295) to use
+ bootp option 129 to get command line string. Till Straumann's patch to
+ change inet_ntoa->inet_ntop.
+
+2002-10-31 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/heapgetinfo.c: Fixed comment.
+ * score/src/mpci.c: Removed warning.
+ * rtems/src/regiongetinfo.c: Corrected return value check.
+ * libmisc/stackchk/check.c: Removed warning.
+ * librpc/src/rpc/svc_run.c: Remove warning.
+ * libcsupport/src/mallocfreespace.c: Corrected sense of status check to
+ match change inside RTEMS.
+ * libcsupport/src/newlibc.c: Removed warning.
+ * libnetworking/libc/rcmd.c, libnetworking/netinet/in_cksum_arm.c:
+ Removed warnings.
+
+2002-10-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/check-bsp-cache.m4: Remove.
+
+2002-10-30 Eric Norum <eric.norum@usask.ca>
+
+ * include/rtems/bspIo.h: Add vprintk function for kernel printing from
+ routines which have already obtained the va_list pointer.
+ * posix/src/psignal.c: Fix counting problem which resulted in too many
+ entries being in the POSIX signals default behavior table.
+ * posix/src/psignal.c: Reflect changes to signal names in newlib.
+ * libcsupport/src/printk.c: Add vprintk function for kernel printing
+ from routines which have already obtained the va_list pointer.
+
+2002-10-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/multilib.m4: Remove RTEMS_ENABLE_MULTILIB_MASTER.
+
+2002-10-28 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/threadhandler.c: Prototype _init() and _main() if they are
+ needed to avoid a warning.
+ * rtems/src/timerserver.c: Add useless return to avoid warning.
+ * librpc/src/rpc/clnt_tcp.c, librpc/src/rpc/clnt_udp.c,
+ librpc/src/rpc/pmap_rmt.c, librpc/src/rpc/rtime.c,
+ librpc/src/rpc/svc_tcp.c: Add include of <sys/select.h> to eliminate
+ warning.
+ * librpc/src/rpc/rpcdname.c: Add prototype of getdomainname() to
+ eliminate warning.
+ * libcsupport/include/rtems/libio.h: Change
+ rtems_filesystem_node_types_t from enumeration to int to eliminate
+ warnings when values are overridden.
+ * Pass to eliminate warnings.
+ * libnetworking/kern/uipc_mbuf.c: Conditional SYSINIT() usage on
+ __rtems__. Fix return statement without a value.
+ * libnetworking/lib/ftpfs.c: read and write filesystem routines return
+ ssize_t.
+ * libnetworking/lib/syslog.c: Add include of <string.h> to eliminate
+ warning.
+ * libnetworking/lib/tftpDriver.c: read and write filesystem routines
+ return ssize_t.
+ * libnetworking/libc/gethostbydns.c: Prototype abort().
+ * libnetworking/libc/inet_ntoa.c: Prototype strcpy().
+ * libnetworking/libc/rcmd.c: Add include of <sys/select.h>.
+ * libnetworking/net/if_loop.c: Turn token at end of endif to comment.
+ * libnetworking/net/rtsock.c, libnetworking/nfs/bootp_subr.c:
+ Conditional SYSINIT() usage on __rtems__.
+ * libnetworking/rtems/rtems_bootp.c: Add include of
+ <rtems/rtems_bsdnet_internal.h>.
+ * libnetworking/rtems/rtems_bsdnet_internal.h: Added prototypes for
+ memcpy() and memset() since the BSD code tries to avoid using libc .h
+ files since it is used to being in the kernel.
+ * libnetworking/rtems/rtems_syscall.c: read and write filesystem
+ routines return ssize_t.
+
+2002-10-28 Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+
+ * libblock/*: Added ATA support.
+ * libblock/include/rtems/blkdev.h: Added last IO status.
+ * libblock/include/rtems/ata.h, libblock/include/rtems/ata_internal.h,
+ libblock/include/rtems/ide_part_table.h, libblock/src/ata.c,
+ libblock/src/ide_part_table.c: New files.
+
+2002-10-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/monitor/mon-command.c: Don't build rtems_monitor_line_editor
+ for RTEMS_UNIX to avoid gcc warning.
+
+2002-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac, itron/configure.ac, posix/configure.ac,
+ librpc/configure.ac, libblock/configure.ac, libfs/configure.ac,
+ libcsupport/configure.ac, libnetworking/configure.ac: Add nostdinc to
+ AM_INIT_AUTOMAKE.
+ * libnetworking/Makefile.am: Remove bogus reference to CHANGELOG.
+
+2002-10-24 Fabrizio Pirovano <pirovano.thysys@tiscalinet.it>
+
+ * libmisc/capture/capture.c, libmisc/monitor/mon-manager.c,
+ libmisc/stackchk/check.c: Patch to remove problems introduced by object
+ name rework.
+
+2002-10-24 <strauman@slac.stanford.edu>
+
+ * libcsupport/src/eval.c: Per PR293, added freenode calls for evaluate
+ link failures.
+
+2002-10-23 <strauman@slac.stanford.edu>
+
+ PR 290
+ * src/mount.c: Add check for ops->node_type_h.
+ PR 291
+ * src/mknod.c: Remove erroneous call to freenod.
+
+2002-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore, itron/.cvsignore, posix/.cvsignore, libmisc/.cvsignore,
+ librpc/.cvsignore, libblock/.cvsignore, libfs/.cvsignore,
+ libcsupport/.cvsignore, libnetworking/.cvsignore: Reformat. Add
+ autom4te*cache. Remove autom4te.cache.
+
+2002-10-21 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-20021021-test.
+
+2002-10-13 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/net/if_ethersubr.c: Add comments to #endif NETATALK to
+ stop gcc from complaining.
+
+2002-10-07 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-ss-20021007.
+
+2002-10-07 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/netinet/tcp_var.h: Corrected typo in ARM alignment patch
+ which broke all other ports.
+
+2002-10-04 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-JUNK.
+ * aclocal/version.m4: Updated to rtems-ss-20021004.
+
+2002-10-04 Jay Monkman <jtm@smoothsmoothie.com>
+
+ * libnetworking/netinet/in_cksum.c, libnetworking/netinet/ip_icmp.h,
+ libnetworking/netinet/ip_input.c, libnetworking/netinet/tcp_input.c,
+ libnetworking/netinet/tcp_subr.c, libnetworking/netinet/tcp_var.h,
+ libnetworking/sys/queue.h: Address alignment requirements for the ARM.
+ * libnetworking/rtems/rtems_glue.c: Add IP aliasing ioctls SIOCAIFADDR
+ and SIOCDIFADDR.
+
+2002-10-02 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/kern/uipc_socket.c: Make sure that small non-zero delays
+ work. Suggested cleanup from Eric Norum.
+
+2002-10-02 Jennifer Averett <jennifer@OARcorp.com>
+
+ * libfs/src/imfs/memfile.c: Fixed case where last close of unlinked file
+ did not remove the resources associated with that file. Reported by
+ Till Straumann <strauman@slac.stanford.edu> on the mailing list.
+
+2002-10-02 Eric Norum <eric.norum@usask.ca>
+
+ * libcsupport/src/getpwent.c: Per PR283, reimplement to address
+ reentrancy problems.
+ * libcsupport/src/getgrent.c: Removed as functionality is now just a
+ wrapper for common routines in src/getpwent.c.
+ * libcsupport/Makefile.am: Reflect file removal.
+ * libnetworking/rtems/mkrootfs.c: As part of PR283, remove redundant
+ code that creates /etc/passwd and /etc/group.
+
+2002-09-16 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/netinet/Makefile.am, libnetworking/netinet/udp_usrreq.c:
+ Back off some of the IP_FORWARD patch as it appears to not compile in
+ the current tree.
+
+2002-09-14 Vyacheslav V. Burdjanadze <wr@zelax.ru>
+
+ * libnetworking/kern/uipc_mbuf.c, libnetworking/sys/mbuf.h,
+ libnetworking/netinet/udp_usrreq.c: Add optional UDP broadcast
+ forwarding support.
+ * libnetworking/netinet/Makefile.am: Defined FORWARD_PROTOCOL to enabled
+ UDP broadcast forwarding.
+
+2002-09-14 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/psignal.c: Remove duplication from rtems/posix/psignal.h.
+ * rtems/src/dpmemcreate.c, rtems/src/dpmemident.c,
+ rtems/src/msgqcreate.c, rtems/src/msgqident.c, rtems/src/partcreate.c,
+ rtems/src/partident.c, rtems/src/ratemoncreate.c,
+ rtems/src/ratemonident.c, rtems/src/regioncreate.c,
+ rtems/src/regionident.c, rtems/src/semcreate.c, rtems/src/semident.c,
+ rtems/src/taskcreate.c, rtems/src/taskident.c, rtems/src/timercreate.c,
+ rtems/src/timerident.c: Added casts to Objects_Name to eliminate
+ warnings.
+ * libfs/src/dosfs/fat.c, libfs/src/imfs/deviceio.c,
+ libfs/src/imfs/imfs.h, libfs/src/imfs/imfs_directory.c,
+ libfs/src/imfs/imfs_fchmod.c, libfs/src/imfs/memfile.c: Eliminated
+ warnings. A lot of this focus was on changing read and write entry
+ points to return ssize_t as read(2) and write(2) now do.
+ * libcsupport/include/rtems/libio.h: Change rtems_filesystem_read_t and
+ rtems_filesystem_write_t to return ssize_t to match read(2) and write(2)
+ respectively.
+ * libnetworking/kern/uipc_socket.c: Fix case on SO_RCVTIMEO and
+ SO_SNDTIMEO where conversion into ticks can result in a 0 ticks timeout
+ which is the same as requesting no timeout. Reported by Sergei Organov
+ <osv@javad.ru>.
+
+2002-09-14 Eric Norum <eric.norum@usask.ca>
+
+ * libcsupport/src/readdir_r.c: New file.
+ * libcsupport/Makefile.am: Reflect above.
+
+2002-09-07 Joel Sherrill <joel@OARcorp.com>
+
+ * libblock/src/bdbuf.c: Previous fix for PR282 regressed mutex changes.
+
+2002-09-06 Alexander M. Kukuta <kam@oktet.ru>
+
+ * libblock/src/bdbuf.c: Per PR282, correct problem in function
+ rtems_bdbuf_read() where device ioctl() is called with the logical
+ device number used instead of corresponding physical device number.
+
+2002-09-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/netinet/in_cksum.c: #include <string.h> for puts in
+ generic routines.
+
+2002-08-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/shell/shell.c: #include <time.h>.
+ * libmisc/wrapup/Makefile.am: Eliminate LIBNAME.
+
+2002-08-30 Joel Sherrill <joel@OARcorp.com>
+
+ * sapi/src/io.c: Fixed some spacing.
+
+2002-08-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/Makefile.am: Remove cpuopt.h generation.
+ * configure.ac: Correct package name. Don't build ada if POSIX is
+ disabled. Generate cpuopt.h on the fly, filter out autoconf-2.53 PACKAGE
+ crap.
+ * aclocal/prog-gnat.m4: New.
+ * configure.ac: Add ada subdir handling.
+
+2002-08-21 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/adjtime.c: New file -- adjtime() support required by the
+ Network Time Protocol (NTP) port to RTEMS.
+ * posix/src/Makefile.am: Modified to reflect above.
+
+2002-08-20 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/bsp-alias.m4: Remove.
+
+2002-08-20 Joel Sherrill <joel@OARcorp.com>
+
+ * librpc/src/xdr/xdr_stdio.c: Per PR268, add include of <netinet/in.h>
+ to avoid warning on ntohl().
+
+2002-08-20 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/rtems/rtems_glue.c: Per PR270, the BSD network code
+ expects that the value of the number of seconds since boot is non-zero.
+ The RTEMS network initialization code assures this by waiting for a
+ second. A more efficient technique is to simply wait until the number
+ of seconds since boot is non-zero.
+
+2002-08-14 Joel Sherrill <joel@OARcorp.com>
+
+ * score/macros/rtems/score/coremsg.inl: Add <string.h> to remove warning.
+ * score/src/threadidlebody.c: Add return 0 to avoid warning.
+
+2002-08-12 Eric Norum <eric.norum@usask.ca>
+
+ * libcsupport/src/write.c (_write_r): Change prototype to match newlib's
+ reent.h.
+
+2002-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/capture/Makefile.am, libmisc/cpuuse/Makefile.am,
+ libmisc/devnull/Makefile.am, libmisc/dummy/Makefile.am,
+ libmisc/dumpbuf/Makefile.am, libmisc/monitor/Makefile.am,
+ libmisc/mw-fb/Makefile.am, libmisc/rtmonuse/Makefile.am,
+ libmisc/serdbg/Makefile.am, libmisc/shell/Makefile.am,
+ libmisc/stackchk/Makefile.am, libmisc/untar/Makefile.am: Use .$(OBJEXT)
+ instead of .o.
+ * librpc/src/rpc/rtems_portmapper.c: include <stdlib.h> (Get rid of
+ gcc31 warnings about abort/exit).
+
+2002-08-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/shell/Makefile.am: Remove shell.h from EXTRA_DIST.
+
+2002-08-09 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/cancelrun.c: Remove check for PTHREAD_CANCELED not being
+ defined to ensure that newlib patch includes it.
+ * libnetworking/libc/getservent.c: Per PR265, add #include
+ <netinet/in.h> for ntohl() function.
+
+2002-08-07 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add missing ',' to librpc activation. Add
+ AC_MSG_CHECKING/AC_MSG_RESULT.
+ * aclocal/check-networking.m4: Let AC_MSG_CHECKING refer to CPU.
+ * configure.ac: Fix bug in librpc activation, having introduced by
+ yesterday's patch.
+
+2002-08-07 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/version.m4: Updated to rtems-ss-20020807.
+ * libnetworking/netinet/in.h: Per PR263, added include of
+ <machine/endian.h> to <netinet/in.h> so it includes prototypes of
+ ntohl() family of routines.
+
+2002-08-07 Chris Johns <ccj@acm.org>
+
+ * score/src/coretodset.c: Correct calculation of ticks until next
+ section boundary. It was incorrectly based upon current time not the
+ time that is being set.
+
+2002-08-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/env-rtemsbsp.m4: Remove RTEMS_CONFIG_PER_BSP.
+ * aclocal/env-rtemscpu.m4: Remove RTEMS_CONFIG_PER_BSP. Use AS_IF
+ instead of if/then/else/fi.
+
+2002-08-06 Joel Sherrill <joel@OARcorp.com>
+
+ * configure.ac, librpc/configure.ac: or32 does not currently support
+ librpc.
+
+2002-08-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Use librtems.a.
+ * wrapup/Makefile.am: Use libsapi.a.
+ * sapi/src/Makefile.am: Add libsapi.a.
+ * rtems/src/Makefile.am: Add librtems.a.
+ * libnetworking/wrapup/Makefile.am: Don't install.
+
+2002-08-01 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/cpuuse/cpuuse.c (CPU_usage_Dump) : Corrected so it honors when
+ an object name is raw versus being a string.
+ * libnetworking/machine/param.h, libnetworking/sys/syslimits.h: In the
+ continued effort to eliminate .h conflicts between newlib and RTEMS,
+ these were moved to newlib.
+ * libnetworking/machine/Makefile.am, libnetworking/sys/Makefile.am:
+ Reflect above.
+
+2002-07-31 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Use libscore.a.
+ * aclocal/canonicalize-tools.m4, automake/lib.am: Remove LD.
+ * Makefile.am: Put preinstall-stamp into CLEANFILES.
+ * aclocal/rtems-top.m4: Use with_project_root and MULTIBUILDTOP to
+ compose PROJECT_TOPdir (Fixes hppa1.1/genoffset problem).
+ * wrapup/Makefile.am: LIBBLOCK_OBJS = ../libblock/$(ARCH)/libblock.a.
+ * posix/src/mqueuecreatesupp.c: #include <stdlib.h> (malloc).
+ * score/src/Makefile.am: Build into libscore.a.
+ * libblock/Makefile.am: Merge src/Makefile.am.
+ * libblock/src/Makefile.am: Remove.
+ * libblock/configure.ac: Remove src/Makefile.am.
+ * libfs/wrapup/Makefile.am, libfs/wrapup/.cvsignore: Remove.
+ * libfs/Makefile.am: Remove wrapup SUBDIR.
+ * libfs/configure.ac: Remove wrapup/Makefile.
+
+2002-07-31 Joel Sherrill <joel@OARcorp.com>
+
+ * aclocal/rtems-cpu-subdirs.m4: Removed the or16 port was just a stub
+ and only the OR32 port is getting worked on.
+
+2002-07-30 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/stackchk/check.c: Don't reference the RTEMS allocated
+ interrupt stack if the port doesn't configure using it.
+ * libcsupport/include/sys/utime.h: Removed as file is now part of the
+ RTEMS newlib support.
+ * libcsupport/Makefile.am: Reflect above.
+ * libcsupport/include/rtems/termiostypes.h: Avoid use of __P.
+ * libnetworking/sys/param.h: Removed as a simpler version of this file
+ is now part of the RTEMS newlib support.
+ * libnetworking/sys/Makefile.am: Modified to reflect above.
+ * libnetworking/machine/types.h: Removed as a simpler version of this
+ file is now part of the RTEMS newlib support.
+ * libnetworking/machine/Makefile.am, libnetworking/machine/endian.h,
+ libnetworking/nfs/bootp_subr.c,
+ libnetworking/rtems/rtems_bsdnet_internal.h,
+ libnetworking/sys/Makefile.am, libnetworking/sys/systm.h: Minor
+ modifications to use the simpler machine/types.h. Mostly more complete
+ sets of #include's to account for machine/types.h no longer doing this.
+
+2002-07-30 Jay Monkman <jtm@smoothsmoothie.com>
+
+ * libnetworking/netinet/in_cksum.c,
+ libnetworking/netinet/in_cksum_arm.c: Added ARM in_cksum support.
+
+2002-07-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * librpc/src/rpc/Makefile.am: Merge src/rpc/PSD.doc/Makefile.am.
+ * librpc/include/Makefile.am: Merge include/rpc/Makefile.am. Merge
+ include/rpcsvc/Makefile.am.
+ * librpc/include/rpc/Makefile.am, librpc/include/rpcsvc/Makefile.am,
+ librpc/src/rpc/PSD.doc/Makefile.am: Remove.
+ * librpc/configure.ac: Remove duplicate AC_PROG_RANLIB. Remove
+ include/rpc/Makefile. Remove include/rpcsvc/Makefile. Remove
+ src/rpc/PSD.doc/Makefile.
+
+2002-07-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * automake/compile.am: Use .$(OBJEXT) instead of .o.
+
+2002-07-24 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/wrapup/Makefile.am: Temporarily don't include serdbg since it
+ causes some BSPs to not link "main(){}" as required by autoconf.
+ * libnetworking/sys/select.h: Add a prototype of select() to avoid
+ warnings. In particular a C++ application using select() required a
+ prototype.
+ * libnetworking/Makefile.am, libnetworking/libc/res_send.c: Do not
+ install or use <poll.h> since RTEMS does not support it.
+
+2002-07-23 Joel Sherrill <joel@OARcorp.com>
+
+ * librpc/src/rpc/pmap_clnt.c (pmap_set): Changed prototype to match .h.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Use .$(OBJEXT) instead of .o.
+ * wrapup/Makefile.am: Use project_libdir instead of
+ $(PROJECT_RELEASE)/lib. Eliminate LIBNAME. Pickup *.o's instead of
+ *.rels for CPU_OBJS. Manually create $(project_libdir)$(MULTISUBDIR).
+ * automake/lib.am: Use project_libdir instead of $(PROJECT_RELEASE)/lib.
+ * aclocal/env-rtemsbsp.m4, aclocal/env-rtemscpu.m4: Remove
+ RTEMS_BSP_SPECS, PROJECT_RELEASE. Add project_libdir, libdir. New
+ GCC_SPECS. Various cleanups.
+ * aclocal/rtems-top.m4: New PROJECT_ROOT handling.
+ * automake/compile.am: Remove RTEMS_BSP_SPECS, LD* flags, LINK,
+ references to bsp_specs. Use project_libdir instead of
+ $(PROJECT_RELEASE)/lib.
+ * itron/src/Makefile.am: Use .$(OBJEXT) instead of .o.
+ * itron/src/Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+ * posix/src/Makefile.am: Use .$(OBJEXT) instead of .o.
+ * posix/src/Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+ * score/src/Makefile.am, sapi/src/Makefile.am, rtems/src/Makefile.am,
+ librpc/src/xdr/Makefile.am, librpc/src/rpc/Makefile.am: Use .$(OBJEXT)
+ instead of .o.
+ * librpc/src/xdr/Makefile.am, librpc/src/rpc/Makefile.am: Eliminate
+ LIBNAME.
+ * libblock/src/Makefile.am: Use .$(OBJEXT) instead of .o.
+ * libblock/src/Makefile.am: Eliminate LIBNAME. Cosmetical cleanups.
+ * libcsupport/Makefile.am: Use .$(OBJEXT) instead of .o.
+ * libcsupport/Makefile.am: Eliminate LIBNAME. Use AM_CPPFLAGS instead of
+ INCLUDES (Upcoming automake standard).
+ * libnetworking/kern/Makefile.am: Use .$(OBJEXT) instead of .o.
+ * libnetworking/lib/Makefile.am, libnetworking/libc/Makefile.am,
+ libnetworking/net/Makefile.am, libnetworking/netinet/Makefile.am,
+ libnetworking/nfs/Makefile.am, libnetworking/rtems/Makefile.am,
+ libnetworking/wrapup/Makefile.am: Ditto.
+ * libnetworking/kern/Makefile.am: Eliminate LIBNAME.
+ * libnetworking/lib/Makefile.am, libnetworking/libc/Makefile.am,
+ libnetworking/net/Makefile.am, libnetworking/netinet/Makefile.am,
+ libnetworking/nfs/Makefile.am, libnetworking/rtems/Makefile.am: Ditto.
+ * libnetworking/wrapup/Makefile.am: Use project_libdir instead of
+ $(PROJECT_RELEASE)/lib.
+
+2002-07-22 Joel Sherrill <joel@OARcorp.com>
+
+ * score/include/rtems/score/apimutex.h (_API_Mutex_Lock): Per PR253 add
+ the missing _ISR_Disable. This fix was already applied to the old
+ location (c/src/exec/score/...).
+
+2002-07-20 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/capture/capture.c, libmisc/capture/capture-cli.c: include
+ <string.h> for memset.
+
+2002-07-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/rtems-top.m4: Reflect relocation of c/src/exec to cpukit.
+ * aclocal/check-cpu.m4, aclocal/check-bsps.m4: Ditto.
+
+2002-07-17 Jay Monkman <jtm@smoothsmoothie.com>
+
+ * libnetworking/netinet/in.h, libnetworking/netinet/ip.h,
+ libnetworking/netinet/ip_var.h, libnetworking/netinet/tcp.h: Modified to
+ added packed attribute.o.
+
+2002-07-16 Joel Sherrill <joel@OARcorp.com>
+
+ * score/macros/rtems/score/object.inl: Corrected typos in
+ _Objects_Open, _Objects_Close, and _Objects_Namespace_remove.
+
+2002-07-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * automake/multilib.am: Add install-multi.
+ * aclocal/rtems-top.m4: Reflect new RTEMS_TOPdir to detecting
+ version.m4. Add --with-project-root. Reflect --with-project-root to
+ setting up PROJECT_ROOT.
+ * aclocal/env-rtemscpu.m4: Reflect new RTEMS_TOPdir (HACK).
+ * aclocal/check-cpu.m4, aclocal/check-bsps.m4: Reflect new RTEMS_TOPdir.
+ * configure.ac: RTEMS_TOP(..).
+ * itron/configure.ac, posix/configure.ac, librpc/configure.ac,
+ libblock/configure.ac, libfs/configure.ac, libcsupport/configure.ac,
+ libnetworking/configure.ac: RTEMS_TOP(../..).
+
+2002-07-05 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/include/rtems/posix/cancel.h, posix/src/cancel.c,
+ posix/src/cancelrun.c, posix/src/mqueue.c, posix/src/pthread.c,
+ posix/src/semaphore.c, posix/src/setcancelstate.c,
+ posix/src/setcanceltype.c, posix/src/testcancel.c: Per PR164, corrected
+ the behavior of thread cancellation and did some cleanup as a
+ side-effect.
+ * score/macros/rtems/score/object.inl: Corrected implementation of
+ _Objects_Open, _Objects_Close, and _Objects_Namespace_remove to be
+ consistent with the inline implementation.
+ * rtems/src/dpmemident.c, rtems/src/msgqident.c, rtems/src/partident.c,
+ rtems/src/ratemonident.c, rtems/src/regionident.c, rtems/src/semident.c,
+ rtems/src/timerident.c: Corrected use of name parameter to be
+ consistent with fixes implemented to string name processing which were
+ committed with the POSIX Message Queue update.
+
+2002-07-04 Joel Sherrill <joel@OARcorp.com>
+
+ * Jump table for single entry point removed.
+ * sapi/include/rtems/directives.h, sapi/src/entrytable.c: Removed.
+ * sapi/include/Makefile.am, sapi/src/Makefile.am, sapi/src/exinit.c:
+ Modified to reflect above.
+
+2002-07-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Install by using cpulibdir, cpulib_DATA.
+ * aclocal/check-bsp-cache.m4: Remove RTEMS_BSP_FAMILY.
+ * configure.ac: Remove RTEMS_PROJECT_ROOT.
+ * aclocal/project-root.m4: Remove.
+ * aclocal/enable-multiprocessing.m4: Fix typo.
+ * aclocal/prog-cc.m4: Remove obsolete comments. Comment out GCCSED.
+ * itron/configure.ac, posix/configure.ac, librpc/configure.ac,
+ libblock/configure.ac, libfs/configure.ac, libcsupport/configure.ac,
+ libnetworking/configure.ac: Remove RTEMS_PROJECT_ROOT.
+
+2002-07-01 Joel Sherrill <joel@OARcorp.com>
+
+ * Mega patch merge to change the format of the object IDs to loosen the
+ dependency between the SCORE and the various APIs. There was
+ considerable work to simplify the object name management and it appears
+ that the name_table field is no longer needed. This patch also includes
+ the addition of the internal mutex which is currently only used to
+ protect some types of allocation and deallocation. This significantly
+ can reduce context switch latency under certain circumstances. In
+ particular, some heap/region operations were O(n) and had dispatching
+ disabled. This should help enormously. With this merge, the patch is
+ not as clean as it should be. In particular, the documentation has not
+ been modified to reflect the new object ID layout, the IDs in the test
+ screens are not updated, and _Objects_Get_information needs to be a real
+ routine not inlined. As part of this patch a lot of MP code for
+ thread/proxy blocking was made conditional and cleaned up.
+ * itron/src/cre_mbf.c, itron/src/cre_sem.c, itron/src/eventflags.c,
+ itron/src/fmempool.c, itron/src/itronsem.c, itron/src/mbox.c,
+ itron/src/msgbuffer.c, itron/src/port.c, itron/src/task.c,
+ itron/src/vmempool.c: Modified as part of above.
+ * Mega patch merge to change the format of the object IDs to loosen the
+ dependency between the SCORE and the various APIs. There was
+ considerable work to simplify the object name management and it appears
+ that the name_table field is no longer needed. This patch also includes
+ the addition of the internal mutex which is currently only used to
+ protect some types of allocation and deallocation. This significantly
+ can reduce context switch latency under certain circumstances. In
+ particular, some heap/region operations were O(n) and had dispatching
+ disabled. This should help enormously. With this merge, the patch is
+ not as clean as it should be. In particular, the documentation has not
+ been modified to reflect the new object ID layout, the IDs in the test
+ screens are not updated, and _Objects_Get_information needs to be a real
+ routine not inlined. As part of this patch a lot of MP code for
+ thread/proxy blocking was made conditional and cleaned up.
+ * posix/include/rtems/posix/key.h, posix/src/cond.c,
+ posix/src/condinit.c, posix/src/intr.c, posix/src/key.c,
+ posix/src/keycreate.c, posix/src/keydelete.c, posix/src/killinfo.c,
+ posix/src/mqueue.c, posix/src/mqueuecreatesupp.c, posix/src/mutex.c,
+ posix/src/mutexinit.c, posix/src/psignal.c, posix/src/pthread.c,
+ posix/src/semaphore.c, posix/src/semaphorecreatesupp.c: Modified as part
+ of above.
+ * Mega patch merge to change the format of the object IDs to loosen the
+ dependency between the SCORE and the various APIs. There was
+ considerable work to simplify the object name management and it appears
+ that the name_table field is no longer needed. This patch also includes
+ the addition of the internal mutex which is currently only used to
+ protect some types of allocation and deallocation. This significantly
+ can reduce context switch latency under certain circumstances. In
+ particular, some heap/region operations were O(n) and had dispatching
+ disabled. This should help enormously. With this merge, the patch is
+ not as clean as it should be. In particular, the documentation has not
+ been modified to reflect the new object ID layout, the IDs in the test
+ screens are not updated, and _Objects_Get_information needs to be a real
+ routine not inlined. As part of this patch a lot of MP code for
+ thread/proxy blocking was made conditional and cleaned up.
+ * score/include/Makefile.am, score/include/rtems/score/coremsg.h,
+ score/include/rtems/score/coremutex.h,
+ score/include/rtems/score/coresem.h, score/include/rtems/score/object.h,
+ score/include/rtems/score/threadq.h,
+ score/inline/rtems/score/object.inl,
+ score/inline/rtems/score/thread.inl,
+ score/macros/rtems/score/object.inl, score/src/Makefile.am,
+ score/src/coremsg.c, score/src/coremutex.c, score/src/coresem.c,
+ score/src/mpci.c, score/src/objectcomparenameraw.c,
+ score/src/objectextendinformation.c,
+ score/src/objectinitializeinformation.c, score/src/objectnametoid.c,
+ score/src/thread.c, score/src/threadclose.c, score/src/threadget.c,
+ score/src/threadq.c, score/src/threadqextractwithproxy.c: Modified as
+ part of above.
+ * score/include/rtems/score/apimutex.h,
+ score/src/objectgetnoprotection.c: New files.
+ * Mega patch merge to change the format of the object IDs to loosen the
+ dependency between the SCORE and the various APIs. There was
+ considerable work to simplify the object name management and it appears
+ that the name_table field is no longer needed. This patch also includes
+ the addition of the internal mutex which is currently only used to
+ protect some types of allocation and deallocation. This significantly
+ can reduce context switch latency under certain circumstances. In
+ particular, some heap/region operations were O(n) and had dispatching
+ disabled. This should help enormously. With this merge, the patch is
+ not as clean as it should be. In particular, the documentation has not
+ been modified to reflect the new object ID layout, the IDs in the test
+ screens are not updated, and _Objects_Get_information needs to be a real
+ routine not inlined. As part of this patch a lot of MP code for
+ thread/proxy blocking was made conditional and cleaned up.
+ * sapi/include/confdefs.h, sapi/src/exinit.c, sapi/src/extension.c,
+ sapi/src/itronapi.c, sapi/src/posixapi.c, sapi/src/rtemsapi.c: Modified
+ as part of above.
+ * Mega patch merge to change the format of the object IDs to loosen the
+ dependency between the SCORE and the various APIs. There was
+ considerable work to simplify the object name management and it appears
+ that the name_table field is no longer needed. This patch also includes
+ the addition of the internal mutex which is currently only used to
+ protect some types of allocation and deallocation. This significantly
+ can reduce context switch latency under certain circumstances. In
+ particular, some heap/region operations were O(n) and had dispatching
+ disabled. This should help enormously. With this merge, the patch is
+ not as clean as it should be. In particular, the documentation has not
+ been modified to reflect the new object ID layout, the IDs in the test
+ screens are not updated, and _Objects_Get_information needs to be a real
+ routine not inlined. As part of this patch a lot of MP code for
+ thread/proxy blocking was made conditional and cleaned up.
+ * rtems/include/rtems.h, rtems/inline/rtems/rtems/region.inl,
+ rtems/macros/rtems/rtems/region.inl, rtems/src/dpmem.c,
+ rtems/src/dpmemcreate.c, rtems/src/msg.c, rtems/src/msgqcreate.c,
+ rtems/src/part.c, rtems/src/partcreate.c, rtems/src/ratemon.c,
+ rtems/src/ratemoncreate.c, rtems/src/region.c, rtems/src/regioncreate.c,
+ rtems/src/regiondelete.c, rtems/src/regionextend.c,
+ rtems/src/regiongetinfo.c, rtems/src/regiongetsegment.c,
+ rtems/src/regiongetsegmentsize.c, rtems/src/regionident.c,
+ rtems/src/regionreturnsegment.c, rtems/src/rtemstimer.c,
+ rtems/src/sem.c, rtems/src/semcreate.c, rtems/src/taskcreate.c,
+ rtems/src/taskident.c, rtems/src/tasks.c, rtems/src/timercreate.c:
+ Modified as part of above.
+ * libmisc/capture/capture-cli.c, libmisc/cpuuse/cpuuse.c,
+ libmisc/monitor/mon-monitor.c, libmisc/monitor/mon-object.c,
+ libmisc/monitor/monitor.h: Corrected use of _Objects_Information_table
+ now that it is a two dimensional array based upon API and class. In
+ addition, in the monitor, corrected an error which occured when a
+ target has 64 bit pointers.
+ * libmisc/stackchk/check.c: Corrected use of _Objects_Information_table
+ now that it is a two dimensional array based upon API and class.
+ * Mega patch merge to change the format of the object IDs to loosen the
+ dependency between the SCORE and the various APIs. There was
+ considerable work to simplify the object name management and it appears
+ that the name_table field is no longer needed. This patch also includes
+ the addition of the internal mutex which is currently only used to
+ protect some types of allocation and deallocation. This significantly
+ can reduce context switch latency under certain circumstances. In
+ particular, some heap/region operations were O(n) and had dispatching
+ disabled. This should help enormously. With this merge, the patch is
+ not as clean as it should be. In particular, the documentation has not
+ been modified to reflect the new object ID layout, the IDs in the test
+ screens are not updated, and _Objects_Get_information needs to be a real
+ routine not inlined. As part of this patch a lot of MP code for
+ thread/proxy blocking was made conditional and cleaned up.
+ * libblock/src/bdbuf.c: Modified as part of above.
+ * libcsupport/src/__times.c: Corrected from previous attempt to cleanup.
+
+2002-06-28 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/src/__times.c: Cleaned up comments, return more
+ information, and eliminated the fatal error on clock not set since it
+ cannot occur.
+
+2002-06-27 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
+
+ * Addition of a ftp client filesystem, comparable to the tftp one.
+ * libnetworking/lib/ftpfs.c, libnetworking/rtems/ftpfs.h: New files.
+ * libnetworking/lib/Makefile.am, libnetworking/rtems/Makefile.am:
+ Modified to reflect above.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/prog-ccas.m4: New.
+ * aclocal/canonicalize-tools.m4: Remove AS, OBJCOPY, NM, SIZE, STRIP.
+ RTEMS_GCC_PRINT.
+ * aclocal/check-multiprocessing.m4: Fix typo.
+ * automake/compile.am: Remove CXX support. Replace AS by CCAS. Remove
+ LINK_LIBS, LINK_OBJS, LINK_FILES.
+ * configure.ac: Use AC_CONFIG_AUX_DIR(..).
+ * itron/configure.ac, posix/configure.ac, librpc/configure.ac,
+ libblock/configure.ac, libfs/configure.ac, libcsupport/configure.ac,
+ libnetworking/configure.ac: Use AC_CONFIG_AUX_DIR(../..). Add
+ AC_PROG_RANLIB.
+
+2002-06-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove references to RTEMS_BSP.
+ * aclocal/check-multiprocessing.m4: Remove references to RTEMS_BSP.
+ Allow building w/ --enable-multiprocessing --enable-multilib.
+ * aclocal/enable-multiprocessing.m4: Eliminate RTEMS_HAS_MULTIPROCESSING.
+ * itron/configure.ac: Remove references to RTEMS_BSP.
+ * itron/src/Makefile.am: Add libitron.a.
+ * posix/configure.ac: Remove references to RTEMS_BSP.
+ * posix/src/Makefile.am: Add libposix.a.
+ * libmisc/wrapup/Makefile.am: Don't preinstall libmisc.a.
+ * libblock/src/Makefile.am: Don't preinstall libblock.a.
+ * libfs/wrapup/Makefile.am: Don't preinstall libfs.a.
+ * libnetworking/wrapup/Makefile.am: Don't preinstall libnetworking.a.
+
+2002-06-25 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
+
+ * With the addition of serdbg, the standard polled I/O functions for
+ gdbstub and/or printk are optionally routed to any termios-aware device
+ driver, that supports polled mode. See libmisc/serdbg/README.
+ * libmisc/serdbg/Makefile.am, libmisc/serdbg/README,
+ libmisc/serdbg/serdbg.c, libmisc/serdbg/serdbg.h,
+ libmisc/serdbg/serdbgcnf.h, libmisc/serdbg/serdbgio.c,
+ libmisc/serdbg/termios_printk.c, libmisc/serdbg/termios_printk.h,
+ libmisc/serdbg/termios_printk_cnf.h, libmisc/serdbg/.cvsignore: New
+ files.
+ * libmisc/configure.ac, libmisc/Makefile.am, libmisc/wrapup/Makefile.am:
+ Modified to reflect addition.
+
+2002-06-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Fix stupid typo in previous patch.
+ * configure.ac: Add librpc. AC_PROG_RANLIB.
+ * wrapup/Makefile.am: Add librpc. Use relative path to lib*.a for
+ POSIX_OBJS, ITRON_OBJS, NETWORKING_OBJS.
+ * librpc/configure.ac: RTEMS_TOP(../../../..).
+ AC_CONFIG_AUX_DIR(../../../..). Remove RTEMS_CANONICAL_HOST. Use
+ RTEMS_ENV_RTEMSCPU. Add AC_PROG_RANLIB.
+ * librpc/include/rpc/Makefile.am, librpc/include/Makefile.am,
+ librpc/include/rpcsvc/Makefile.am: Include
+ $(top_srcdir)/../automake/*.am.
+ * librpc/Makefile.am: Include $(top_srcdir)/../automake/*.am.
+ ACLOCAL_AMFLAGS = -I ../aclocal.
+ * librpc/src/rpc/PSD.doc/Makefile.am, librpc/src/rpc/Makefile.am,
+ librpc/src/xdr/Makefile.am, librpc/src/Makefile.am: Include
+ $(top_srcdir)/../automake/*.am.
+
+2002-06-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * aclocal/subdirs.m4: Remove.
+
+2002-06-18 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Use relative path to lib*.a for LIBCSUPPORT_OBJS,
+ LIBBLOCK_OBJS, LIBDOSFS_OBJS, LIBIMFS_OBJS.
+ * libblock/Makefile.am: Merge-in include/Makefile.am.
+ * libblock/include/Makefile.am: Remove.
+ * libblock/configure.ac: Reflect changes above.
+ * libnetworking/Makefile.am: Remove commented out net-apps.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/automake/*.am. Use aclocal.
+ * sapi/include/Makefile.am, sapi/Makefile.am, sapi/inline/Makefile.am,
+ sapi/macros/Makefile.am, sapi/src/Makefile.am,
+ score/include/Makefile.am, score/Makefile.am, score/cpu/Makefile.am,
+ score/inline/Makefile.am, score/macros/Makefile.am,
+ score/src/Makefile.am, wrapup/Makefile.am, include/Makefile.am,
+ rtems/include/Makefile.am, rtems/Makefile.am, rtems/inline/Makefile.am,
+ rtems/macros/Makefile.am, rtems/src/Makefile.am: Include
+ $(top_srcdir)/automake/*.am.
+ * aclocal/bsp-alias.m4: Copied over from aclocal/.
+ * aclocal/canonical-host.m4, aclocal/canonical-target-name.m4,
+ aclocal/canonicalize-tools.m4, aclocal/check-bsp-cache.m4,
+ aclocal/check-bsps.m4, aclocal/check-cpu.m4, aclocal/check-itron.m4,
+ aclocal/check-multiprocessing.m4, aclocal/check-networking.m4,
+ aclocal/check-newlib.m4, aclocal/check-posix.m4, aclocal/check-tool.m4,
+ aclocal/enable-bare.m4, aclocal/enable-inlines.m4,
+ aclocal/enable-itron.m4, aclocal/enable-multiprocessing.m4,
+ aclocal/enable-networking.m4, aclocal/enable-posix.m4,
+ aclocal/enable-rtemsbsp.m4, aclocal/env-rtemsbsp.m4,
+ aclocal/env-rtemscpu.m4, aclocal/gcc-pipe.m4, aclocal/gcc-specs.m4,
+ aclocal/multi.m4, aclocal/multilib.m4, aclocal/prog-cc.m4,
+ aclocal/project-root.m4, aclocal/rtems-cpu-subdirs.m4,
+ aclocal/rtems-debug.m4, aclocal/rtems-top.m4, aclocal/subdirs.m4,
+ aclocal/sysv-ipc.m4, aclocal/tool-paths.m4, aclocal/version.m4: Ditto.
+ * itron/include/Makefile.am: Include $(top_srcdir)/../automake/*.am.
+ * itron/Makefile.am: Include $(top_srcdir)/../automake/*.am. Use
+ ../aclocal.
+ * itron/inline/Makefile.am, itron/macros/Makefile.am,
+ itron/src/Makefile.am, posix/include/Makefile.am: Include
+ $(top_srcdir)/../automake/*.am.
+ * posix/Makefile.am: Include $(top_srcdir)/../automake/*.am. Use
+ ../aclocal.
+ * posix/inline/Makefile.am, posix/macros/Makefile.am,
+ posix/src/Makefile.am, libblock/include/Makefile.am: Include
+ $(top_srcdir)/../automake/*.am.
+ * libblock/Makefile.am: Include $(top_srcdir)/../automake/*.am. Use
+ ../aclocal.
+ * libblock/src/Makefile.am, libfs/src/dosfs/Makefile.am,
+ libfs/src/Makefile.am, libfs/src/imfs/Makefile.am: Include
+ $(top_srcdir)/../automake/*.am.
+ * libfs/Makefile.am: Include $(top_srcdir)/../automake/*.am. Use
+ ../aclocal.
+ * libfs/wrapup/Makefile.am: Include $(top_srcdir)/../automake/*.am.
+ * libcsupport/Makefile.am: Merge src/Makefile.am.
+ * libcsupport/configure.ac: Reflect changes above.
+ * libcsupport/src/Makefile.am: Remove.
+ * libcsupport/Makefile.am: Include $(top_srcdir)/../automake/*.am. Use
+ ../aclocal.
+ * libcsupport/src/Makefile.am, libnetworking/arpa/Makefile.am,
+ libnetworking/kern/Makefile.am: Include $(top_srcdir)/../automake/*.am.
+ * libnetworking/Makefile.am: Include $(top_srcdir)/../automake/*.am. Use
+ ../aclocal.
+ * libnetworking/lib/Makefile.am, libnetworking/libc/Makefile.am,
+ libnetworking/machine/Makefile.am, libnetworking/net/Makefile.am,
+ libnetworking/netinet/Makefile.am, libnetworking/nfs/Makefile.am,
+ libnetworking/rtems/Makefile.am, libnetworking/sys/Makefile.am,
+ libnetworking/vm/Makefile.am, libnetworking/wrapup/Makefile.am: Include
+ $(top_srcdir)/../automake/*.am.
+
+2002-06-15 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * automake/compile.am, automake/lib.am, automake/local.am,
+ automake/multilib.am, automake/subdirs.am: Copied over from automake/.
+ * Makefile.am: Add automake/*.am.
+
+2002-06-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/rtems/Makefile.am: include multilib.am instead of
+ RTEMS_BSP.cfg.
+
+2002-05-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/configure.ac: Remove RTEMS_CHECK_POSIX_API. Remove
+ RTEMS_ENABLE_POSIX. Remove RTEMS_CHECK_CUSTOM_BSP. Remove
+ RTEMS_ENABLE_POSIX.
+
+2002-05-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add libnetworking.
+ * wrapup/Makefile.am: Ditto. Relocate c/src/libnetworking.
+ * libnetworking/Makefile.am: Reflect moval.
+ * libnetworking/machine/Makefile.am, libnetworking/net/Makefile.am,
+ libnetworking/lib/Makefile.am, libnetworking/netinet/Makefile.am,
+ libnetworking/vm/Makefile.am, libnetworking/libc/Makefile.am,
+ libnetworking/sys/Makefile.am, libnetworking/arpa/Makefile.am,
+ libnetworking/nfs/Makefile.am, libnetworking/kern/Makefile.am,
+ libnetworking/rtems/Makefile.am, libnetworking/configure.ac: Ditto.
+ * libnetworking/wrapup/Makefile.am: Ditto. Remove references to
+ networking apps.
+
+2002-05-24 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/configure.ac, libmisc/Makefile.am: Remove references to rootfs.
+
+2002-05-18 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add libblock. Add libfs. Add AM_CONDITIONAL(UNIX).
+ * wrapup/Makefile.am: Add libblock, libfs/dosfs, libfs/imfs.
+ * libblock/configure.ac, libblock/Makefile.am,
+ libblock/include/Makefile.am, libblock/src/Makefile.am: Reflect move
+ from c/src/libblock to c/src/exec/libblock.
+ * libfs/configure.ac: Reflect move from c/src/libfs to c/src/exec/libfs.
+ * libfs/Makefile.am, libfs/src/Makefile.am, libfs/src/dosfs/Makefile.am,
+ libfs/src/imfs/Makefile.am, libfs/wrapup/Makefile.am: Ditto.
+ * libnetworking/rtems_telnetd/pty.c: Remove bsp.h. Include
+ <rtems/bspIo.h>.
+
+2002-05-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/rootfs/.cvsignore, libmisc/rootfs/Makefile.am,
+ libmisc/rootfs/mkrootfs.h, libmisc/rootfs/mkrootfs.c: Remove.
+ * libmisc/configure.ac: Remove rootfs and NETWORKING macros.
+ * libmisc/wrapup/Makefile.am: Remove rootfs and HAS_NETWORKING.
+ * libnetworking/rtems/mkrootfs.c: Add (relocated from libmisc/rootfs).
+ * libnetworking/rtems/mkrootfs.h: Ditto.
+ * libnetworking/rtems/Makefile.am: Reflect changes above.
+
+2002-05-16 Chris Johns <ccj@acm.org>
+
+ PR 194
+ * libmisc/*: Added the Capture engine.
+ * libmisc/capture/Makefile.am, libmisc/capture/README,
+ libmisc/capture/capture-cli.c, libmisc/capture/capture-cli.h,
+ libmisc/capture/capture.c, libmisc/capture/capture.h,
+ libmisc/capture/.cvsignore: New files.
+ * libmisc/Makefile.am, libmisc/configure.ac, libmisc/wrapup/Makefile.am:
+ Modified to reflect addition.
+
+2002-05-15 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add libcsupport.
+ * wrapup/Makefile.am: Ditto.
+ * Makefile.am: Add preinstall-stamp.
+
+2002-05-15 Chris Johns <ccj@acm.org>
+
+ * score/include/rtems/score/thread.h,
+ score/inline/rtems/score/thread.inl, score/src/threaddispatch.c,
+ score/src/threadinitialize.c: Move the C library re-enterrant support
+ directly into the thread dispatch code. RTEMS needs libc and so
+ requiring libc to use a user extension with its overhead is not the best
+ solution. This patch lowers the overhead to 2 pointer moves.
+
+2002-05-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/sys/ioctl.h, libnetworking/sys/sockio.h,
+ libnetworking/sys/filio.h: Remove.
+ * libnetworking/sys/Makefile.am: Reflect changes above.
+
+2002-05-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/Makefile.am: Work-around to autoconf-2.53 adding
+ PACKAGE_* to autoheaders - sed out *PACKAGE* from cpuopts-tmp.h.
+
+2002-05-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * posix/include/sys/utsname.h: Remove.
+ * posix/include/Makefile.am: Reflect changes above.
+ * posix/src/utsname.c: Remove.
+ * posix/src/Makefile.am: Reflect changes above.
+
+2002-05-01 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/machine/in_cksum.h: Per PR200 fix multi-line inline
+ assembly to satisfy gcc 3.1 and newer.
+
+2002-04-26 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/netinet/in_cksum_i386.c: Add volatile so the more
+ agressive optimization in gcc 3.1 does not reorder things.
+
+2002-04-18 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/rtems/system.h: Remove targopts.h.
+ * libnetworking/pppd/utils.c: Adapt to gcc-3.x.
+
+2002-04-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/rtems/system.h: Add the sparc to the target supporting
+ multlibs.
+
+2002-04-16 Chris Johns <ccj@acm.org>
+
+ * score/src/threadinitialize.c: Per PR181, clear the array of user
+ extension pointers. This lets user extensions that have hooked the
+ switch handler know if a task has been processed by the user extension
+ before. If a user extension is created after a task is started it may
+ not know it.
+
+2002-04-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove ENABLE_GCC28.
+
+2002-04-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/rtems/system.h: Add i386 to multilib-able targets.
+
+2002-04-11 Chris Johns <ccj@acm.org>
+
+ PR 59/networking
+ * libnetworking/c/src/libnetworking/rtems/rtems_bsdnet.h: Add the
+ drv_ctrl driver control block field to the ifconfig network driver
+ structure. This field is needed by the i82586 driver which was ported
+ from NetBSD as it had better hardware abstraction.
+
+2002-04-10 Victor V. Vengerov <vvv@oktet.ru>
+
+ PR 385/filesystem
+ * libblock/src/ramdisk.c: The "from" and "to" locations are calculated
+ as the start of the block within the ram that data is to be transferred
+ from/to for reads and writes respectively. However, within the loops,
+ the "from" and "to" locations are never updated. The loop should have
+ been updated as: from += rd->block_size; and to += rd->block_size;
+ within the for loops in the ramdisk_read and ramdisk_write routines,
+ respectively.
+
+2002-04-08 Chris Johns <ccj@acm.org>
+
+ * Per PR142, make task switch extension its own list.
+ * posix/src/pthread.c (_POSIX_Threads_User_extensions): Reflect above.
+ * Per PR141 and PR174, make task switch extension its own list and fix
+ all odd problems introduced by providing macro version.
+ * score/inline/rtems/score/userext.inl: Fix.
+ * Per PR142, make task switch extension its own list.
+ * score/include/rtems/score/userext.h: Reflect above by adding
+ User_extensions_Switch_control and adding it to User_extenions_Control.
+ * score/inline/rtems/score/userext.inl: Allocate all memory in one chunk
+ to minimize overhead. Address processing dedicated switch chain.
+ * Per PR142, make task switch extension its own list.
+ * score/include/rtems/score/userext.h: Reflect above by adding
+ User_extensions_Switch_control and adding it to User_extenions_Control.
+ * score/inline/rtems/score/userext.inl: Allocate all memory in one chunk
+ to minimize overhead. Address processing dedicated switch chain.
+ * Per PR142, make task switch extension its own list.
+ * rtems/src/tasks.c (_RTEMS_tasks_User_extensions): Reflect above.
+
+2002-04-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * include/rtems/bspIo.h: Fix cpp-guards, remove references to i386.
+ * posix/src/psignal.c: Include <stdlib.h>.
+ * libblock/src/ramdisk.c, libblock/src/blkdev.c,
+ libfs/src/imfs/imfs_getchild.c: include <string.h>.
+ * libfs/src/imfs/imfs_gtkn.c, libfs/src/imfs/ioman.c,
+ libfs/src/imfs/linearfile.c, libfs/src/imfs/memfile.c: Include
+ <string.h>.
+ * libnetworking/ChangeLog: Fix dates.
+
+2002-04-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/monitor/mon-monitor.c: Replace done with return (gcc3).
+ * libfs/src/dosfs/fat.h: Include <string.h>. Remove DBG1 and DBG2
+ (unused).
+ * Per PR169.
+ * libfs/src/dosfs/config.h.in, libfs/src/dosfs/stamp-h2.in: Removed from
+ CVS.
+
+2002-04-03 Alexander Kukuta <kam@oktet.ru>
+
+ * libblock/include/rtems/bdbuf.h: Address PR168 by changing
+ bdbuf_buffer.avl.bal and bdbuf_buffer.avl.cache to signed char instead
+ of char.
+
+2002-04-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * posix/src/getegid.c: Remove <errno.h>.
+ * posix/src/geteuid.c, posix/src/getgid.c, posix/src/getuid.c: Ditto.
+ * posix/src/getlogin.c: Move <errno.h>.
+
+2002-03-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/libc/rcmd.c: Replace __rtems w/ __rtems__.
+
+2002-03-27 Thomas.Doerfler@imd-systems.de
+
+ PR 144
+ * libnetworking/nfs/bootp_subr.c bootpc_init(): Performs a write to
+ memory address 0 when called for the first time. This is done when
+ trying to clear the variable "dhcp_hostname".
+
+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]).
+ * include/Makefile.am, Makefile.am, wrapup/Makefile.am: Remove
+ AUTOMAKE_OPTIONS.
+ * itron/configure.ac: AC_INIT(package,_RTEMS_VERSION,_RTEMS_BUGS).
+ AM_INIT_AUTOMAKE([no-define foreign 1.6]).
+ * itron/include/Makefile.am, itron/Makefile.am,
+ itron/inline/Makefile.am, itron/macros/Makefile.am,
+ itron/src/Makefile.am: Remove AUTOMAKE_OPTIONS.
+ * posix/configure.ac: AC_INIT(package,_RTEMS_VERSION,_RTEMS_BUGS).
+ AM_INIT_AUTOMAKE([no-define foreign 1.6]).
+ * posix/src/Makefile.am, posix/Makefile.am, posix/include/Makefile.am,
+ posix/inline/Makefile.am, posix/macros/Makefile.am,
+ score/cpu/Makefile.am, score/src/Makefile.am, score/Makefile.am,
+ score/include/Makefile.am, score/inline/Makefile.am,
+ score/macros/Makefile.am, sapi/Makefile.am, sapi/include/Makefile.am,
+ sapi/inline/Makefile.am, sapi/macros/Makefile.am, sapi/src/Makefile.am,
+ rtems/Makefile.am, rtems/include/Makefile.am, rtems/inline/Makefile.am,
+ rtems/macros/Makefile.am, rtems/src/Makefile.am: Remove AUTOMAKE_OPTIONS.
+ * libmisc/configure.ac: AC_INIT(package,_RTEMS_VERSION,_RTEMS_BUGS).
+ AM_INIT_AUTOMAKE([no-define foreign 1.6]).
+ * libmisc/Makefile.am, libmisc/cpuuse/Makefile.am,
+ libmisc/devnull/Makefile.am, libmisc/dummy/Makefile.am,
+ libmisc/dumpbuf/Makefile.am, libmisc/monitor/Makefile.am,
+ libmisc/mw-fb/Makefile.am, libmisc/rootfs/Makefile.am,
+ libmisc/rtmonuse/Makefile.am, libmisc/shell/Makefile.am,
+ libmisc/stackchk/Makefile.am, libmisc/untar/Makefile.am,
+ libmisc/wrapup/Makefile.am: Remove AUTOMAKE_OPTIONS.
+ * librpc/configure.ac: AC_INIT(package,_RTEMS_VERSION,_RTEMS_BUGS).
+ AM_INIT_AUTOMAKE([no-define foreign 1.6]).
+ * librpc/include/rpc/Makefile.am, librpc/include/Makefile.am,
+ librpc/include/rpcsvc/Makefile.am, librpc/Makefile.am,
+ librpc/src/rpc/PSD.doc/Makefile.am, librpc/src/rpc/Makefile.am,
+ librpc/src/xdr/Makefile.am, librpc/src/Makefile.am: Remove
+ AUTOMAKE_OPTIONS.
+ * libblock/configure.ac: AC_INIT(package,_RTEMS_VERSION,_RTEMS_BUGS).
+ AM_INIT_AUTOMAKE([no-define foreign 1.6]).
+ * libblock/include/Makefile.am, libblock/Makefile.am,
+ libblock/src/Makefile.am: Remove AUTOMAKE_OPTIONS.
+ * libfs/src/dosfs/fat_file.c: Remove bsp.h. fat_file_write(.. const
+ char*buf ..).
+ * libfs/src/dosfs/fat_file.h: fat_file_write(.. const char*buf ..).
+ * libfs/configure.ac: AC_INIT(package,_RTEMS_VERSION,_RTEMS_BUGS).
+ AM_INIT_AUTOMAKE([no-define foreign 1.6]).
+ * libfs/src/dosfs/Makefile.am, libfs/src/Makefile.am,
+ libfs/src/imfs/Makefile.am, libfs/Makefile.am, libfs/wrapup/Makefile.am:
+ Remove AUTOMAKE_OPTIONS.
+ * libnetworking/configure.ac:
+ AC_INIT(package,_RTEMS_VERSION,_RTEMS_BUGS). AM_INIT_AUTOMAKE([no-define
+ foreign 1.6]).
+ * libnetworking/arpa/Makefile.am, libnetworking/kern/Makefile.am,
+ libnetworking/Makefile.am, libnetworking/lib/Makefile.am,
+ libnetworking/libc/Makefile.am, libnetworking/machine/Makefile.am,
+ libnetworking/net/Makefile.am, libnetworking/netinet/Makefile.am,
+ libnetworking/nfs/Makefile.am, libnetworking/pppd/Makefile.am,
+ libnetworking/rtems/Makefile.am,
+ libnetworking/rtems_servers/Makefile.am,
+ libnetworking/rtems_telnetd/Makefile.am,
+ libnetworking/rtems_webserver/Makefile.am,
+ libnetworking/sys/Makefile.am, libnetworking/vm/Makefile.am,
+ libnetworking/wrapup/Makefile.am: Remove AUTOMAKE_OPTIONS.
+
+2002-03-27 Ilya Alexeev <ilya@continuum.ru>
+
+ PR 162
+ * libnetworking/net/if_ppp.c ppp_txdaemon(),
+ libnetworking/net/if_pppvar.h pppstart(): Local variables must not be
+ used in a device write routines. Now ppp_softc structure have own
+ character for writing to device (sc_outchar). I think that converting
+ local variables to static is not a right solution, because problems will
+ occur in the case of two or more ppp instances.
+ * libnetworking/net/ppp_tty.c pppstart(): Type of the ioffset variable
+ must be u_long, otherwise in the case of the big output packet endless
+ loop may occur.
+
+2002-03-25 Eric Norum <norume@aps.anl.gov>
+
+ PR 374/networking
+ * libnetworking/Makefile.am, libnetworking/rtems/rtems_bsdnet.h,
+ libnetworking/rtems/rtems_glue.c: The patch sent as part of PR270 got
+ applied to the wrong place. The effect was that (1) startup was no
+ faster than before and (2) malloc starvation messages came way too
+ quickly. The attached patch fixes both these problems and also provides
+ a mechanism for applications to handle malloc starvation conditions as
+ they see fit.
+ * libnetworking/rtems/rtems_bsdnet_malloc_starvation.c: New file.
+
+2002-03-21 Ilya Alexeev <ilya@continuum.ru>
+
+ * libnetworking/net/if_ppp.c, libnetworking/net/ppp_tty.c: Initial
+ preparations for multiple PPPD connections.
+
+2002-03-21 Alexander Kukuta <kam@oktet.ru>
+
+ * libblock/src/bdbuf.c (avl_insert, libblock/avl_remove): Reimplemented
+ from scratch to avoid using GPLed sources in RTEMS core.
+ * libblock/src/bdbuf.c, libblock/include/rtems/bdbuf.h: Remove "binary
+ tree" implementation which was used for debugging only.
+
+2002-03-20 Chris Johns <ccj@acm.org>
+
+ PR 192
+ * libmisc/monitor/mon-command.c: The RTEMS monitor makes everything
+ lowercase. The capture engine need to set triggers or watches on task
+ with uppercase names. Also stop the monitor repeating command when
+ enter is pressed.
+ PR 148.
+ * libmisc/monitor/mon-prmisc.c: Fixed to print task states correctly.
+
+2002-03-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR 140
+ * libfs/src/dosfs/config.h.in, libfs/src/dosfs/stamp-h2.in: Removed.
+ * libfs/.cvsignore: Add config.h*, stamp-h*.
+ * libfs/configure.ac: Remove AC_SRC_DIR(.../dosfs.h). Remove
+ AM_CONFIG_HEADER(src/dosfs/config.h). Remove
+ AM_CONFIG_HEADER(src/imfs/config.h). Add AM_CONFIG_HEADER(config.h).
+ * libfs/src/dosfs/Makefile.am, libfs/src/imfs/Makefile.am: INCLUDES =
+ -I../...
+
+2002-03-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR 130
+ * libfs/src/dosfs/Makefile.am: Reworked, Disable dosfs for UNIX.
+ * libfs/wrapup/Makefile.am: Disable dosfs for UNIX.
+
+2002-03-13 Victor V. Vengerov <vvv@oktet.ru>
+
+ * libblock/src/bdbuf.c (find_or_assign_buffer,
+ libblock/rtems_bdbuf_read, libblock/rtems_bdbuf_sync,
+ libblock/rtems_bdbuf_syncdev, libblock/bdbuf_swapout_task): Fix bug:
+ disable interrupts and set level properly before _CORE_mutex_Seize
+ invocation).
+
+2002-03-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/rtems/system.h: Add __RTEMS_REVISION__.
+
+2002-03-01 Eric Norum <eric.norum@usask.ca>
+
+ * posix/src/pthreadonce.c: Task is not preemptable while running a
+ pthread_once init function. This is slightly less heavy handed than
+ disabling dispatching and seems better than consuming a mutex.
+
+2002-02-28 Victor V. Vengerov <vvv@oktet.ru>
+
+ * DOS filesystem including FAT12, FAT16, and FAT32 support submitted.
+ * libfs/src/dosfs, libfs/src/dosfs/Makefile.am,
+ libfs/src/dosfs/stamp-h2.in, libfs/src/dosfs/config.h.in,
+ libfs/src/dosfs/dosfs.h, libfs/src/dosfs/fat.c, libfs/src/dosfs/fat.h,
+ libfs/src/dosfs/fat_fat_operations.c,
+ libfs/src/dosfs/fat_fat_operations.h, libfs/src/dosfs/fat_file.c,
+ libfs/src/dosfs/fat_file.h, libfs/src/dosfs/msdos.h,
+ libfs/src/dosfs/msdos_create.c, libfs/src/dosfs/msdos_dir.c,
+ libfs/src/dosfs/msdos_eval.c, libfs/src/dosfs/msdos_file.c,
+ libfs/src/dosfs/msdos_free.c, libfs/src/dosfs/msdos_fsunmount.c,
+ libfs/src/dosfs/msdos_handlers_dir.c,
+ libfs/src/dosfs/msdos_handlers_file.c, libfs/src/dosfs/msdos_init.c,
+ libfs/src/dosfs/msdos_initsupp.c, libfs/src/dosfs/msdos_misc.c,
+ libfs/src/dosfs/msdos_mknod.c, libfs/src/dosfs/msdos_node_type.c,
+ libfs/src/dosfs/.cvsignore: New files.
+ * libfs/configure.ac, libfs/src/Makefile.am, libfs/wrapup/Makefile.am:
+ Modified to reflect addition.
+
+2002-02-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/rtems/system.h: Add __RTEMS_MAJOR__, __RTEMS_MINOR__.
+
+2002-02-28 Joel Sherrill <joel@OARcorp.com>
+
+ * Submitted by Victor V. Vengerov <vvv@oktet.ru> and merged into the
+ RTEMS source.
+ * libblock/ChangeLog, libblock/Makefile.am, libblock/README,
+ libblock/configure.ac, libblock/include/Makefile.am,
+ libblock/include/rtems/bdbuf.h, libblock/include/rtems/blkdev.h,
+ libblock/include/rtems/diskdevs.h, libblock/include/rtems/ramdisk.h,
+ libblock/include/rtems/.cvsignore, libblock/include/.cvsignore,
+ libblock/src/Makefile.am, libblock/src/bdbuf.c, libblock/src/blkdev.c,
+ libblock/src/diskdevs.c, libblock/src/ramdisk.c,
+ libblock/src/.cvsignore, libblock/.cvsignore: New files.
+
+2002-02-27 Ilya Alexeev <ilya@continuum.ru>
+
+ * libnetworking/net/if_ppp.c, libnetworking/pppd/auth.c,
+ libnetworking/pppd/chat.c, libnetworking/pppd/pppd.h,
+ libnetworking/pppd/sys-rtems.c: Add server with pap-authorization
+ capabilities as well as eliminate some warnings.
+
+2002-02-27 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/net/radix.c: Properly handle fetching the default route
+ when there is no route. This was a bug in the original FreeBSD code and
+ this fix is from an updated version of their code.
+
+2002-02-16 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/lib/tftpDriver.clib/tftpDriver.c: Fix TFTP block number
+ checking.
+
+2002-02-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * posix/src/getegid.c: Add #include <rtems/userenv.h>. Remove #include
+ <rtems/libio_.h>.
+ * posix/src/geteuid.c, posix/src/getgid.c, posix/src/getlogin.c,
+ posix/src/getuid.c: Ditto.
+
+2002-02-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Readded reference to wrapup.
+ * posix/configure.ac: AC_CONFIG_SRCDIR([src/pthreads.c]).
+ * posix/src/psignal.c: #include <string.h>.
+ * libnetworking/pppd/sys-rtems.c: Remove unused variable status from
+ dodefaultroute.
+
+2002-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/lib/tftpDriver.c: Remove set_errno_and_return_minus_one,
+ include <rtems/seterr.h>.
+
+2002-02-01 Mike Siers <mikes@poliac.com>
+
+ * libnetworking/pppd/rtemspppd.c (rtems_pppd_disconnect): Modified to
+ avoid bringing the link down too fast. NOTE: Mike reports successfully
+ running at 56K baud on a direct link.
+
+2002-01-31 Mike Siers <mikes@poliac.com>
+
+ * libnetworking/pppd/rtemsdialer.h: New file missed in previous commit.
+ * libnetworking/*: Update of PPPD support which eliminates the
+ requirement that drivers be in the termios TASK_DRIVEN mode. Mike did
+ significant testing and reports that it seems to be more stable and
+ handle larger packets better. This patch replaces the termios tasks
+ with more general pppd network driver tasks. The functions pppinput()
+ and pppstart() get called from the interrupt service routine.
+ * libnetworking/Makefile.am, libnetworking/configure.ac,
+ libnetworking/net/Makefile.am, libnetworking/net/bpf.h,
+ libnetworking/net/ethernet.h, libnetworking/net/if.c,
+ libnetworking/net/if.h, libnetworking/net/if_arp.h,
+ libnetworking/net/if_dl.h, libnetworking/net/if_ethersubr.c,
+ libnetworking/net/if_llc.h, libnetworking/net/if_loop.c,
+ libnetworking/net/if_ppp.h, libnetworking/net/if_pppvar.h,
+ libnetworking/net/if_types.h, libnetworking/net/netisr.h,
+ libnetworking/net/ppp-comp.h, libnetworking/net/ppp_defs.h,
+ libnetworking/net/pppcompress.h, libnetworking/net/radix.c,
+ libnetworking/net/radix.h, libnetworking/net/raw_cb.c,
+ libnetworking/net/raw_cb.h, libnetworking/net/raw_usrreq.c,
+ libnetworking/net/route.c, libnetworking/net/route.h,
+ libnetworking/net/rtsock.c, libnetworking/pppd/Makefile.am,
+ libnetworking/pppd/README, libnetworking/pppd/STATUS,
+ libnetworking/pppd/auth.c, libnetworking/pppd/cbcp.c,
+ libnetworking/pppd/ccp.c, libnetworking/pppd/ccp.h,
+ libnetworking/pppd/chap.c, libnetworking/pppd/chap.h,
+ libnetworking/pppd/chap_ms.c, libnetworking/pppd/chap_ms.h,
+ libnetworking/pppd/chat.c, libnetworking/pppd/demand.c,
+ libnetworking/pppd/fsm.c, libnetworking/pppd/fsm.h,
+ libnetworking/pppd/ipcp.c, libnetworking/pppd/ipcp.h,
+ libnetworking/pppd/ipxcp.c, libnetworking/pppd/ipxcp.h,
+ libnetworking/pppd/lcp.c, libnetworking/pppd/lcp.h,
+ libnetworking/pppd/magic.c, libnetworking/pppd/magic.h,
+ libnetworking/pppd/options.c, libnetworking/pppd/patchlevel.h,
+ libnetworking/pppd/pathnames.h, libnetworking/pppd/pppd.8,
+ libnetworking/pppd/pppd.h, libnetworking/pppd/rtemsmain.c,
+ libnetworking/pppd/rtemspppd.c, libnetworking/pppd/rtemspppd.h,
+ libnetworking/pppd/sys-rtems.c, libnetworking/pppd/upap.c,
+ libnetworking/pppd/upap.h, libnetworking/pppd/utils.c,
+ libnetworking/pppd/example/README,
+ libnetworking/pppd/example/netconfig.h,
+ libnetworking/wrapup/Makefile.am: Modified.
+ * libnetworking/net/bsd-comp.c, libnetworking/net/if_ppp.c,
+ libnetworking/net/ppp-deflate.c, libnetworking/net/ppp.h,
+ libnetworking/net/ppp_tty.c, libnetworking/net/pppcompress.c,
+ libnetworking/net/zlib.c, libnetworking/net/zlib.h: New file.
+ * libnetworking/modem/, libnetworking/modem/.cvsignore,
+ libnetworking/modem/Makefile.am, libnetworking/modem/ppp.c,
+ libnetworking/modem/ppp.h, libnetworking/modem/ppp_tty.c,
+ libnetworking/modem/pppcompress.c: Subdirectory removed.
+
+2002-01-29 Joel Sherrill <joel@OARcorp.com>
+
+ * score/include/rtems/score/watchdog.h: Added WATCHDOG_MAXIMUM_INTERVAL.
+
+2002-01-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/shell/shell.c: Remove #undef __STRICT_ANSI__.
+
+2002-01-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/configure.ac: Fix tests for GCC.
+
+2002-01-24 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/configure.ac: Add check for weak function attribute. Remove
+ AM_CONDITIONAL([RTEMS_LIBSHELL]. Add AM_CONDITIONAL(LIBSHELL),
+ AM_CONDITIONAL(LIBSERDBG).
+ * libmisc/capture/Makefile.am, libmisc/cpuuse/Makefile.am,
+ libmisc/devnull/Makefile.am, libmisc/dummy/Makefile.am,
+ libmisc/dumpbuf/Makefile.am, libmisc/monitor/Makefile.am,
+ libmisc/mw-fb/Makefile.am, libmisc/rtmonuse/Makefile.am: Use *.a instead
+ of *-tmp.a.
+ * libmisc/serdbg/Makefile.am: Use *.a instead of *-tmp.a. Build iff
+ LIBSERDBG is true.
+ * libmisc/shell/Makefile.am: Use *.a instead of *-tmp.a. Build iff
+ LIBSHELL is true.
+ * libmisc/stackchk/Makefile.am, libmisc/untar/Makefile.am: Use *.a
+ instead of *-tmp.a.
+ * libmisc/wrapup/Makefile.am: Reflect changes above.
+
+2002-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/rtems_telnetd/pty.c: Move config.h to were it belongs.
+ Remove printf (Reported by Till Straumann <strauman@SLAC.Stanford.EDU>).
+
+2002-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/rtems/system.h: Fix typo in yesterday's change:
+ RTEMS_MULTILIBS.
+
+2002-01-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Apply @subdirs. Remove POSIX_SUBDIRS. Remove
+ ITRON_SUBDIRS.
+ * configure.ac: Rework enable_unixlib handling. Add RTEMS_MULTILIBS to
+ cpuopts.h.
+ * include/Makefile.am: Add rtems/fs.h, rtems/userenv.h. Add
+ $(PROJECT_INCLUDE)/rtems. Remove libio_.h.
+
+2002-01-07 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/Makefile.am: Add install-hook. Remove SIZE_RTEMS.
+ * include/rtems/fs.h: New, extracted from libio_.h.
+ * include/rtems/userenv.h: New. extracted from libio_.h.
+ * libmisc/rootfs/Makefile.am: Use include_rtems_HEADERS instead of
+ H_FILES.
+ * libfs/src/imfs/imfs_load_tar.c: Add include <sys/types.h>. Add include
+ <sys/stat.h>. Add include <fcntl.h>.
+ * libfs/src/imfs/imfs_rmnod.c: Add include <stdlib.h>.
+
+2002-01-07 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/optman/, posix/optman/.cvsignore, posix/optman/Makefile.am,
+ sapi/optman/, sapi/optman/.cvsignore, sapi/optman/Makefile.am,
+ sapi/optman/no-ext.c, sapi/optman/no-io.c, rtems/optman/,
+ rtems/optman/.cvsignore, rtems/optman/Makefile.am,
+ rtems/optman/no-dpmem.c, rtems/optman/no-event.c, rtems/optman/no-mp.c,
+ rtems/optman/no-msg.c, rtems/optman/no-part.c, rtems/optman/no-region.c,
+ rtems/optman/no-rtmon.c, rtems/optman/no-sem.c,
+ rtems/optman/no-signal.c, rtems/optman/no-timer.c: Removed entire
+ contents of optman/ directory since it has been moved.
+
+2002-01-06 Joel Sherrill <joel@OARcorp.com>
+
+ * wrapup/.cvsignore: Readded.
+ * include/.cvsignore: New file.
+
+2002-01-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/rtems/seterr.h: Add do {..} while (0) in defines. Rename
+ set_errno_and_return_minus_one into rtems_set_errno_and_return_minus_one.
+ * libmisc/mw-fb/mw_uid.c: Apply rtems_set_errno_and_return_minus_one.
+ * libfs/src/imfs/imfs_eval.c, libfs/src/imfs/memfile.c,
+ libfs/src/imfs/imfs_readlink.c, libfs/src/imfs/imfs_unlink.c,
+ libfs/src/imfs/imfs_link.c, libfs/src/imfs/imfs_chown.c,
+ libfs/src/imfs/ioman.c, libfs/src/imfs/imfs_mount.c,
+ libfs/src/imfs/imfs_directory.c, libfs/src/imfs/imfs_stat.c,
+ libfs/src/imfs/imfs_fchmod.c, libfs/src/imfs/imfs_symlink.c,
+ libfs/src/imfs/imfs_mknod.c, libfs/src/imfs/linearfile.c,
+ libfs/src/imfs/imfs_unmount.c: Include <rtems/seterr.h>. Apply
+ rtems_set_errno_and_return_minus_one.
+ * libfs/src/imfs/imfs.h: Apply rtems_set_errno_and_return_minus_one.
+ Comment out increment_and_check_linkcounts.
+
+2002-01-04 Joel Sherrill <joel@OARcorp.com>
+
+ * Makefile.am, configure.ac: Remove references to wrapup subdirectory.
+
+2001-12-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AS_IF instead of if/then/else. Add
+ AC_DEFINE_UNQUOTED(RTEMS_UNIX) for RTEMS_CPU==unix. Add
+ AC_DEFINE_UNQUOTED(RTEMS_UNIXLIB) for RTEMS_CPU==unix. Add
+ include/Makefile to CONFIG_FILES. Add AC_ENABLE_MULITLIB. Remove
+ wrapup/rtems, wrapup/itron, wrapup/posix. Remove */optman/Makefile from
+ CONFIG_FILES.
+ * Makefile.am: Add include to SUBDIRS.
+ * rtems/Makefile.am, sapi/Makefile.am: Remove optman from SUBDIRS.
+ * include/Makefile.am: New file.
+ * include/rtems/bspIo.h, include/rtems/libio_.h: Relocated from
+ lib/include.
+ * posix/configure.ac: Remove optman/Makefile from CONFIG_FILES.
+ * posix/Makefile.am: Remove optman from SUBDIRS.
+
+2001-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/posix/Makefile.am, wrapup/itron/Makefile.am,
+ wrapup/rtems/Makefile.am, Makefile.am, itron/src/Makefile.am: Add
+ multilib support.
+ * posix/optman/Makefile.am: Add multilib support. Remove ASM4FLAGS.
+ * posix/src/Makefile.am: Add multilib support.
+ * score/inline/rtems/score/object.inl,
+ score/macros/rtems/score/object.inl: Add add casts to Objects_Id in
+ _Objects_Build_ids to avoid implicit typecasts from enum to int16 on
+ bit16 targets (here: h8300).
+ * score/src/Makefile.am, sapi/optman/Makefile.am, sapi/src/Makefile.am,
+ rtems/src/Makefile.am, rtems/optman/Makefile.am: Add multilib support.
+
+2001-12-18 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/lib/tftpDriver.c: Allow chdir() to work on TFTP
+ `directories' (path names with a / at the end) while disallowing open()
+ operations on TFTP `directories'.
+
+2001-12-07 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/lib/tftpDriver.c: Restore write capability.
+
+2001-11-29 Victor V. Vengerov <vvv@oktet.ru>
+
+ * AVL trees implementation added.
+
+2001-11-28 Joel Sherrill <joel@OARcorp.com>,
+
+ PR 91
+ * score/include/rtems/score/isr.h, score/inline/rtems/score/isr.inl,
+ score/macros/rtems/score/isr.inl: Modified to allow any port to provide
+ its own implementation of the macro _ISR_Is_in_progress. If the port
+ overrides this macro, it must provide a non-inlined function
+ implementation.
+
+2001-11-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libfs/wrapup/Makefile.am: Remove HAS_IMFS.
+
+2001-11-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libfs/src/imfs/Makefile.am: Cleanup.
+ * libnetworking/arpa/Makefile.am: Remove stray lines.
+
+2001-11-20 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/threadhandler.c: When __USE__MAIN__ is defined by the
+ toolset, invoke the global constructors via __main. Reported as tested
+ by Alexandra Kossovsky <sasha@oktet.ru> and Victor V. Vengerov
+ <vvv@oktet.ru> in conjunction with a new set of tool RPMs
+ (gcc2.95.3newlib1.9.0-3). This was tracked as GNATS PR tools/84.
+
+2001-11-16 Victor V. Vengerov <vvv@oktet.ru>
+
+ * libblock/include/rtems/bdbuf.h,
+ libblock/src/bdbuf.c(rtems_bdbuf_syncdev): New.
+
+2001-11-07 Victor V. Vengerov <vvv@oktet.ru>
+
+ * libblock/ChangeLog: New file.
+ * libblock/src/, libblock/include/, libblock/include/rtems/: New
+ directories.
+ * libblock/README, libblock/configure.ac, libblock/Makefile.am,
+ libblock/src/Makefile.am, libblock/include/Makefile.am,
+ libblock/include/rtems/bdbuf.h include/rtems/blkdev.h
+ include/rtems/diskdevs.h include/rtems/ramdisk.h src/bdbuf.c
+ src/blkdev.c src/diskdevs.c src/ramdisk.c: New files.
+
+2001-11-07 Joel Sherrill <joel@OARcorp.com>
+
+ Discovered while fixing PR36 reported by Todor.Todorov@barco.com.
+ * itron/include/rtems/itron/object.h: Corrected _ITRON_Objects_Get() to
+ use _Objects_Get_by_index().
+ PR 36 (Reported by Todor.Todorov@barco.com)
+ * score/include/rtems/score/object.h: Added prototype for
+ _Objects_Get_by_index().
+ * score/src/objectget.c, score/src/objectgetisr.c: Corrected procedure
+ for getting index from Id so it is correct and optimal for both single
+ and multiprocessor configurations.
+
+2001-11-07 Jennifer Averett <jennifer@OARcorp.com>
+
+ Reported by Ibragimov Ilya <ibr@oktet.ru> and tracked as PR49.
+ * libfs/ src/imfs/imfs_directory.c: Do not calculate the offset twice.
+
+2001-10-26 Victor V. Vengerov <vvv@oktet.ru>
+
+ * libfs/src/imfs/imfs_load_tar.c: Minor modification so this will
+ compile with gcc-2.95.3 with the arguments "-m5200 -O4".
+
+2001-10-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/macros/Makefile.am: Replace INLINES w/ MACROS (Fix stupid typo
+ in previous patch).
+
+2001-10-23 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/macros/rtems/rtems/asr.nil: Fixed typo.
+
+2001-10-22 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/threadhandler.c: Use __USE_INIT_FINI__ since USE_INIT_FINI
+ pollutes the application namespace.
+
+2001-10-18 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/lib/tftpDriver.c: Properly handles ../ components in
+ chdir() and open() operations within the TFTP file system.
+
+2001-10-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use RTEMS_CPU_SUBDIRS to make autoconf-2.52 happy.
+ * configure.ac: Use AC_CONFIG_SUBDIRS for posix and itron. Reflect
+ changes to configuration of rtems, score and sapi subdirs.
+ * Makefile.am: require automake-1.5.
+ * itron/include/itronsys/Makefile.am, itron/include/rtems/Makefile.am,
+ itron/include/rtems/itron/Makefile.am, itron/inline/rtems/Makefile.am,
+ itron/inline/rtems/itron/Makefile.am, itron/macros/rtems/Makefile.am,
+ itron/macros/rtems/itron/Makefile.am: Remove.
+ * itron/include/Makefile.am, itron/inline/Makefile.am,
+ itron/macros/Makefile.am: handle subdirs.
+ * itron/configure.ac: Reflect changes above.
+ * posix/include/sys/Makefile.am, posix/include/rtems/Makefile.am,
+ posix/include/rtems/posix/Makefile.am: Remove.
+ * posix/include/Makefile.am: Handle subdirs.
+ * posix/inline/rtems/Makefile.am, posix/inline/rtems/posix/Makefile.am:
+ Remove.
+ * posix/inline/Makefile.am: Handle subdirs.
+ * posix/macros/rtems/Makefile.am, posix/macros/rtems/posix/Makefile.am:
+ Remove.
+ * posix/macros/Makefile.am: Handle subdirs.
+ * posix/configure.ac: Reflect changes above.
+ * score/include/rtems/Makefile.am, score/include/rtems/Makefile.am:
+ Remove.
+ * score/include/Makefile.am: Handle subdirs, require automake-1.5.
+ * score/macros/rtems/Makefile.am, score/macros/rtems/score/Makefile.am:
+ Remove.
+ * score/macros/Makefile.am: Handle subdirs, require automake-1.5.
+ * score/inline/rtems/Makefile.am, score/inline/rtems/score/Makefile.am:
+ Remove.
+ * score/inline/Makefile.am: Handle subdirs, require automake-1.5.
+ * score/Makefile.am: require automake-1.5.
+ * sapi/include/rtems/Makefile.am: Remove.
+ * sapi/include/Makefile.am: Handle subdirs, require automake-1.5.
+ * sapi/inline/rtems/Makefile.am: Remove.
+ * sapi/inline/Makefile.am: Handle subdirs, require automake-1.5.
+ * sapi/macros/rtems/Makefile.am: Remove.
+ * sapi/Makefile.am: require automake-1.5.
+ * rtems/include/rtems/Makefile.am,
+ rtems/include/rtems/rtems/Makefile.am: Remove.
+ * rtems/include/Makefile.am: Handle subdirs, require automake-1.5.
+ * rtems/inline/rtems/Makefile.am, rtems/inline/rtems/rtems/Makefile.am:
+ Remove.
+ * rtems/inline/Makefile.am: Handle subdirs, require automake-1.5.
+ * rtems/macros/rtems/Makefile.am, rtems/macros/rtems/rtems/Makefile.am:
+ Remove.
+ * rtems/macros: Handle subdirs, require automake-1.5.
+ * rtems/Makefile.am: require automake-1.5.
+
+2001-10-16 Joel Sherrill <joel@OARcorp.com>
+
+ * score/.cvsignore: Add stamp-h.in.
+ * score/include/Makefile.am: Fixed path to cpuopts-tmp.h.
+
+2001-10-16 Chris Johns <ccj@acm.org>
+
+ * sapi/include/confdefs.h, sapi/include/rtems/config.h,
+ sapi/include/rtems/io.h, sapi/optman/no-io.c, sapi/src/exinit.c,
+ sapi/src/io.c: Added a device driver register/unregister interface to
+ allow device drivers to be installed and removed at runtime. This means
+ you do not need devices present in the device table when you build.
+ * libfs/imfs/imfs_load_tar.c: Changed the code around to remove an
+ internal compiler error on the Coldfire target.
+
+2001-10-12 Mike Siers <mikes@poliac.com>
+
+ * Update to stable working state.
+ * libnetworking/modem_example/16550.h,
+ libnetworking/modem_example/README, libnetworking/modem_example/modem.c,
+ libnetworking/modem_example/modem.h, libnetworking/modem_example/ppp.c,
+ libnetworking/modem_example/ppp.h,
+ libnetworking/modem_example/pppcompress.c: Files removed.
+ * libnetworking/pppd/example/pppd.options: New file.
+ * libnetworking/pppd/README, libnetworking/pppd/STATUS,
+ libnetworking/pppd/cbcp.c, libnetworking/pppd/cbcp.h,
+ libnetworking/pppd/chat.c, libnetworking/pppd/pppd.h,
+ libnetworking/pppd/rtemsmain.c: Updated.
+
+2001-10-12 Joel Sherrill <joel@OARcorp.com>
+
+ * sapi/include/rtems/directives.h, libmisc/rootfs/mkrootfs.c,
+ libmisc/rootfs/mkrootfs.h: Fixed typo.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+ * itron/.cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * itron/configure.in: Remove.
+ * itron/configure.ac: New file, generated from configure.in by
+ autoupdate.
+ * posix/.cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * posix/configure.in: Remove.
+ * posix/configure.ac: New file, generated from configure.in by
+ autoupdate.
+ * libmisc/.cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * libmisc/configure.in: Remove.
+ * libmisc/configure.ac: New file, generated from configure.in by
+ autoupdate.
+ * librpc/.cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * librpc/configure.in: Remove.
+ * librpc/configure.ac: New file, generated from configure.in by
+ autoupdate.
+ * libfs/.cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * libfs/configure.in: Remove.
+ * libfs/configure.ac: New file, generated from configure.in by
+ autoupdate.
+ * libnetworking/.cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * libnetworking/configure.in: Remove.
+ * libnetworking/configure.ac: New file, generated from configure.in by
+ autoupdate.
+
+2001-10-10 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/src/imfs/imfs_getchild.c: Correct length of static string as
+ reported by Ibragimov Ilya <ibr@oktet.ru>.
+
+2001-09-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/rtems/score/Makefile.am,
+ score/include/rtems/Makefile.am, score/inline/rtems/score/Makefile.am,
+ score/macros/rtems/score/Makefile.am, sapi/include/rtems/Makefile.am,
+ sapi/include/Makefile.am, sapi/inline/rtems/Makefile.am,
+ sapi/macros/rtems/Makefile.am, rtems/include/rtems/rtems/Makefile.am,
+ rtems/include/Makefile.am, rtems/inline/rtems/rtems/Makefile.am,
+ rtems/macros/rtems/rtems/Makefile.am, libmisc/untar/Makefile.am,
+ libmisc/monitor/Makefile.am, libmisc/shell/Makefile.am,
+ libmisc/devnull/Makefile.am, libmisc/dumpbuf/Makefile.am,
+ libmisc/mw-fb/Makefile.am, libmisc/stackchk/Makefile.am,
+ libmisc/rtmonuse/Makefile.am, libmisc/cpuuse/Makefile.am,
+ libmisc/rootfs/Makefile.am, librpc/include/rpc/Makefile.am,
+ libfs/src/imfs/Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-09-28 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/mqueueopen.c, posix/src/semopen.c: Clarify type on va_arg.
+ * libmisc/dummy/dummy.c: Now a useful configuration that starts main().
+ * libmisc/wrapup/Makefile.am: Include a base level configuration in
+ RTEMS library.
+
+2001-09-27 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/ChangeLog: Fixed typo in date.
+
+2001-09-27 Eric Norum <eric.norum@usask.ca>
+
+ * score/src/threadhandler.c: Now process C++ global constructors (_init)
+ as part of the first task execution not in BSP space. This depends on
+ the toolset defining USE_INIT_FINI so you have to have the right toolset
+ version.
+ * libnetworking/lib/tftpDriver.c: Add limited chdir() support to the
+ TFTP filesystem.
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * itron/include/itronsys/Makefile.am,
+ itron/include/rtems/itron/Makefile.am, itron/include/Makefile.am,
+ itron/inline/rtems/itron/Makefile.am,
+ itron/macros/rtems/itron/Makefile.am, posix/include/sys/Makefile.am,
+ posix/include/rtems/posix/Makefile.am, posix/include/Makefile.am,
+ posix/inline/rtems/posix/Makefile.am,
+ posix/macros/rtems/posix/Makefile.am,
+ score/include/rtems/score/Makefile.am, score/include/rtems/Makefile.am,
+ score/inline/rtems/score/Makefile.am,
+ score/macros/rtems/score/Makefile.am, libnetworking/machine/Makefile.am,
+ libnetworking/net/Makefile.am, libnetworking/netinet/Makefile.am,
+ libnetworking/vm/Makefile.am, libnetworking/pppd/Makefile.am,
+ libnetworking/sys/Makefile.am, libnetworking/rtems_servers/Makefile.am,
+ libnetworking/arpa/Makefile.am, libnetworking/nfs/Makefile.am,
+ libnetworking/rtems_webserver/Makefile.am,
+ libnetworking/rtems/Makefile.am,
+ libnetworking/rtems_telnetd/Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-09-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/rtems/Makefile.am: Fix comments to make automake-1.5 happy.
+ * itron/src/Makefile.am: Revamp INCLUDES handling to make automake-1.5
+ happy.
+ * posix/optman/Makefile.am: Adapt ASM4FLAGS to automake-1.5 happy.
+ * posix/src/Makefile.am: Adapt INCLUDES to make automake-1.5 happy.
+ * sapi/optman/Makefile.am: Adapt ASM4FLAGS to automake-1.5.
+ * libfs/src/imfs/Makefile.am: Revamp INCLUDES handling to make
+ automake-1.5 happy.
+ * libnetworking/Makefile.am: Use PREINSTALL_FILES = to make automake-1.5
+ happy.
+
+2001-09-21 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/configure.in, libmisc/rootfs/Makefile.am: Added conditional to
+ make sure rootfs does not get built with networking is disabled. Also
+ added include of compile.am to rootfs/Makefile.am.
+ * libmisc/wrapup/Makefile.am: Added rootfs conditionally if networking
+ enabled.
+
+2001-09-19 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/lib/tftpDriver.c: Add some debugging capability.
+
+2001-09-19 Chris Johns <ccj@acm.org>
+
+ * Added support for populating the initial "root" filesystem with
+ information obtained via the DHCP response.
+ * libmisc/rootfs: New directory.
+ * libmisc/rootfs/.cvsignore, libmisc/rootfs/Makefile.am,
+ libmisc/rootfs/mkrootfs.c, libmisc/rootfs/mkrootfs.h: New files.
+ * libmisc/configure.in, libmisc/Makefile.am: Modified to reflect
+ addition.
+ * nfs/bootp_subr.c, rtems/rtems_bootp.c, rtems/rtems_bsdnet.h,
+ rtems/rtems_bsdnet_internal.h Added support for populating the initial
+ "root" filesystem with information obtained via the DHCP response.
+
+2001-09-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/aclocal/canonical-target-name.m4: Use AC_CANONICAL_TARGET
+ instead of AC_CANONICAL_SYSTEM.
+ * libmisc/aclocal/config-subdirs.m4: Use AS_MKDIR_P instead of
+ mkinstalldirs and mkdir.
+ * libmisc/aclocal/target.m4: Obsolete RTEMS_OUTPUT_BUILD_SUBDIRS, hack
+ RTEMS_CONFIG_BUILD_SUBDIRS, introduce _RTEMS_OUTPUT_BUILD_SUBDIRS.
+ * libmisc/aclocal/canonical-target-name.m4: Use AC_CANONICAL_TARGET
+ instead of AC_CANONICAL_SYSTEM.
+ * libmisc/aclocal/config-subdirs.m4: Use AS_MKDIR_P instead of
+ mkinstalldirs and mkdir.
+ * libmisc/aclocal/target.m4: Obsolete RTEMS_OUTPUT_BUILD_SUBDIRS, hack
+ RTEMS_CONFIG_BUILD_SUBDIRS, introduce _RTEMS_OUTPUT_BUILD_SUBDIRS.
+
+2001-09-14 Fernando Ruiz <fernando.ruiz@ctv.es>
+
+ * rtems/src/tasks.c: Dereference pointer passed to destructor.
+ * libmisc/shell/shell.c: Don't close file it wasn't open.
+
+2001-09-13 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/sysconf.c: Fix typo syntax error accidentally committed.
+ * posix/src/mprotect.c: New file. Stub required by some gcc's to pass
+ tests. In particular, about 350 ACATS tests fail if this is not present.
+ * posix/src/getpagesize.c: Ditto.
+ * posix/src/sysconf.c: Addition of Solaris value for _SC_STACK_PROT
+ required to pass about 350 ACATS test cases.
+ * posix/src/Makefile.am: Added new files.
+ * libmisc/devnull/devnull.c: Eliminate warning.
+
+2001-08-30 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/macros/rtems/posix/mqueue.inl: Add cast so negation works.
+ * score/ src/coremutex.c, score/src/coremutexseize.c,
+ score/src/coremutexsurrender.c, score/inline/rtems/score/coremutex.inl:
+ The per thread field resource_count should only be manipulated when a
+ mutex is priority ceiling or priority inherit. This was reported by
+ Chris Johns <ccj@acm.org> who also noticed that the use of switches for
+ all disciplines generated less efficient code than using explicit tests
+ for the one or two cases we were really interested in. Further review
+ of his modifications made it apparent that the "isa" methods to test
+ mutex discipline were not being used so this modification was swept into
+ the code as well.
+ * score/src/coremutexseize.c: Add missing code for proper handling of
+ nesting acquisitions. This only impacts building with inlines disabled
+ on the source with the "fast mutex" optimizations. This was post the 4.5
+ branch and did not impact released versions.
+ * rtems/inline/rtems/rtems/attr.inl: Correct typo and use correct
+ attribute RTEMS_SYSTEM_TASK. Reported by Chris Johns <ccj@acm.org>.
+
+2001-08-16 Mike Siers <mikes@poliac.com>
+
+ * libnetworking/pppd/STATUS: Updated by Joel based upon email from Mike.
+ * libnetworking/pppd/cbcp.c, libnetworking/pppd/cbcp.h: Readded files.
+ These support callback functionality that has not even been compiled
+ under RTEMS yet.
+ * libnetworking/pppd/*: Update of PPPD to 2.3.11 from 2.3.5 and addition
+ of an example application. - renamed error() function because of
+ namespace problems. - removed calls to the exit() function. - removed
+ extra files from the pppd source directory. - defined pppd task constant
+ values in rtemspppd.h. - modifyied example code to get actual tick per
+ second value. - placed the pppd 2.3.11 man page file (pppd.8) into the
+ pppd directory.
+ * libnetworking/pppd/cbcp.c, libnetworking/pppd/cbcp.h,
+ libnetworking/pppd/main.c, libnetworking/pppd/ppp_tty.c,
+ libnetworking/pppd/pppmain.c, libnetworking/pppd/rtems-ppp.c,
+ libnetworking/pppd/rtems-ppp.c: Deleted.
+ * libnetworking/pppd/pppd.8, libnetworking/pppd/rtemsmain.c,
+ libnetworking/pppd/rtemspppd.c, libnetworking/pppd/rtemspppd.h,
+ libnetworking/pppd/sys-rtems.c, libnetworking/pppd/utils.c,
+ libnetworking/pppd/example/Makefile, libnetworking/pppd/example/README,
+ libnetworking/pppd/example/init.c,
+ libnetworking/pppd/example/netconfig.h,
+ libnetworking/pppd/example/ppp.conf,
+ libnetworking/pppd/example/pppdapp.c,
+ libnetworking/pppd/example/system.h: New files.
+ * libnetworking/modem/ppp_tty.c, libnetworking/net/if_ppp.h,
+ libnetworking/pppd/Makefile.am, libnetworking/pppd/README,
+ libnetworking/pppd/STATUS, libnetworking/pppd/auth.c,
+ libnetworking/pppd/ccp.c, libnetworking/pppd/ccp.h,
+ libnetworking/pppd/chap.c, libnetworking/pppd/chap.h,
+ libnetworking/pppd/chap_ms.c, libnetworking/pppd/chap_ms.h,
+ libnetworking/pppd/chat.c, libnetworking/pppd/demand.c,
+ libnetworking/pppd/fsm.c, libnetworking/pppd/fsm.h,
+ libnetworking/pppd/ipcp.c, libnetworking/pppd/ipcp.h,
+ libnetworking/pppd/ipxcp.c, libnetworking/pppd/ipxcp.h,
+ libnetworking/pppd/lcp.c, libnetworking/pppd/lcp.h,
+ libnetworking/pppd/magic.c, libnetworking/pppd/magic.h,
+ libnetworking/pppd/options.c, libnetworking/pppd/patchlevel.h,
+ libnetworking/pppd/pathnames.h, libnetworking/pppd/pppd.h,
+ libnetworking/pppd/upap.c, libnetworking/pppd/upap.h: Modified.
+
+2001-08-16 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/mqueuesendsupp.c: Account for possibly blocking during the
+ core send operation.
+ * score/src/coremutexsurrender.c: Use holder thread not executing thread
+ because even though they may and often are the same it is not guaranteed
+ unless the proper attribute is set.
+ * score/include/rtems/score/coremsg.h, score/src/coremsgsubmit.c: Add a
+ new return status to account for blocking sends. Otherwise, the caller
+ will think that the returned message status will have the ultimate
+ results of the operation. If the send times out, the final status will
+ be in the return_code of the thread.
+ * rtems/src/msgqsubmit.c: Add a comment indicating that we do not have
+ to account for possibly blocking during the core send operation because
+ Classic API message queue send is always non-blocking.
+ * libnetworking/pppd/example/Makefile: Removed.
+ * libnetworking/pppd/example/Makefile-user: Added was Makefile. Renamed
+ to avoid bootstrap -c clobbering it.
+ * libnetworking/rtems_telnetd/.cvsignore: New file.
+
+2001-08-09 Keith Outwater <vac4050@cae597.rsc.raytheon.com>
+
+ * libmisc/monitor/mon-command.c: Add support for partial command
+ matching. The monitor used to have this functionality before it was
+ overhauled to support addition of user commands.
+
+2001-08-09 Joel Sherrill <joel@OARcorp.com>
+
+ * itron/src/snd_mbx.c, itron/src/tsnd_mbf.c, posix/src/mqueuesendsupp.c,
+ score/include/rtems/score/coremsg.h,
+ score/inline/rtems/score/coremsg.inl, score/src/coremsgsubmit.c,
+ rtems/src/msgqsubmit.c: Unblocking message queue operations should NOT
+ use _Thread_Executing for return status since it is permissible to
+ invoke message send operations from an ISR. This was reported by Suvrat
+ Gupta <suvrat@utstar.com>.
+
+2001-08-09 Fernando-Ruiz Casas <correo@fernando-ruiz.com>
+
+ * libmisc/shell/pty.c: Moved to libnetworking/rtems_telnetd.
+ * libmisc/shell/Makefile.am, libmisc/shell/README, libmisc/shell/cmds.c,
+ libmisc/shell/shell.c, libmisc/shell/shell.h: Updates.
+ * libfs/src/imfs/imfs_eval.c: The CD_UP problem in imfs_eval has been
+ touched. The order of the questions is the key.
+ * libnetworking/Makefile.am, libnetworking/configure.in,
+ libnetworking/rtems_servers/Makefile.am,
+ libnetworking/rtems_servers/telnetd.c,
+ libnetworking/rtems_servers/telnetd.h,
+ libnetworking/rtems_telnetd/Makefile.am,
+ libnetworking/rtems_telnetd/README, libnetworking/rtems_telnetd/icmds.c,
+ libnetworking/rtems_telnetd/pty.c, libnetworking/rtems_telnetd/pty.h,
+ libnetworking/rtems_telnetd/telnetd.c,
+ libnetworking/rtems_telnetd/telnetd.h, libnetworking/wrapup/Makefile.am:
+ - pty and telnetd have a new subdir rtems_telnetd to avoid the side
+ effect when ftpd change. - the tcp/ip stats have been implemented into
+ icmds.c and started when telnetd daemon is started.
+ * libnetworking/rtems_servers/telnetd.c,
+ libnetworking/rtems_servers/telnetd.h: Removed.
+ * libnetworking/rtems_telnetd: New directory.
+ * libnetworking/rtems_telnetd/Makefile.am,
+ libnetworking/rtems_telnetd/README, libnetworking/rtems_telnetd/icmds.c,
+ libnetworking/rtems_telnetd/pty.c, libnetworking/rtems_telnetd/pty.h,
+ libnetworking/rtems_telnetd/telnetd.c,
+ libnetworking/rtems_telnetd/telnetd.h: New files.
+
+2001-07-06 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
+
+ * libfs/src/imfs/deviceio.c: Make sure errno gets set to reflect the
+ status from the driver.
+
+2001-06-14 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/shell/telnetd.c, libmisc/shell/telnetd.h: Moved to
+ libnetworking/rtems_servers so the network stack to address network
+ depenendency.
+ * libmisc/shell/Makefile.am: Modified to reflect above.
+ * libnetworking/rtems_servers/telnetd.c, libnetworking/shell/telnetd.h:
+ Moved from libmisc/shell so the network stack to address network
+ depenendency.
+ * libnetworking/rtems_servers/Makefile.am: Modified to reflect above.
+
+2001-05-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/rtems_servers/Makefile.am: Deleted blank lines.
+
+2001-05-25 Sergei Organov <osv@javad.ru>
+
+ * score/macros/rtems/score/coresem.inl,
+ score/inline/rtems/score/coresem.inl: Cut and paste problem incorrectly
+ enabled interrupts twice with the first time being too early.
+
+2001-05-25 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/shell/cmds.c: Removed code from inappropriate source.
+ * libfs/src/imfs/imfs_initsupp.c: Create the root node with the desired
+ permissions. Nodes should be created with the right permissions because
+ chmod() is not supported by the miniIMFS so changing after creation is
+ not possible.
+
+2001-05-24 Joel Sherrill <joel@OARcorp.com>
+
+ * libcsupport/src/.cvsignore: New file.
+
+2001-05-24 Fernando Ruiz Casas <fernando.ruiz@ctv.es>
+
+ * posix/src/getegid.c, posix/src/geteuid.c, posix/src/getgid.c,
+ posix/src/getlogin.c, posix/src/getuid.c: Now save their values in
+ private user environment.
+ * libmisc/monitor/mon-prmisc.c: Correct print line.
+ * libmisc/shell/Makefile.am: Added new file telnetd.c.
+ * libmisc/shell/telnetd.c, libmisc/shell/telnetd.h, libmisc/shell/pty.c:
+ New files.
+ * libmisc/shell/shell.c, libmisc/shell/cmds.c, libmisc/shell/shell.h:
+ Numerous improvments: - The shell_init has a new parameter 'forever'
+ because in /dev/console you need that this process runs forever but in
+ tcp/ip not. (respawn?) - A new task for every session opened trought
+ tcp/ip telnet client. (the chargen,daytime and more are possible of
+ implementation but I ask me if they are necesary) - Exit from the
+ session delete the task and when the client fails too. - More cmds have
+ been implemented. (very reduced version of these) umask, chmod, id,
+ whoami, rm, cat, ... - A reduced line edit has been implemented. Ctrl-C
+ abort the input, Ctrl-d in the first position gives EOF (logout). '\b'
+ and DEL makes the rubout operation. I think that readline() for every
+ session spents a lot of resources.
+
+2001-05-17 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/macros/rtems/posix/mqueue.inl: Implemented missing routines to
+ support message queue FDs.
+ * score/macros/rtems/score/thread..inl: Implemented missing routines for
+ new libc reentrancy support.
+
+2001-05-14 Till Straumann <strauman@slac.stanford.edu>
+
+ * score/src/threaddispatch.c, score/src/threadhandler.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_.
+
+2001-05-14 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/dummy/Makefile.am, libmisc/wrapup/Makefile.am: Fixed to
+ generate a library of the same name.
+ * libnetworking/ChangeLog: Corrected -- entry should have been in
+ libchip.
+
+2001-05-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/rtems/score/.cvsignore: Add stamp-h, cpuopts.h,
+ cpuopts.h.in, cpuopts-tmp.h.
+ * libnetworking/libc/Makefile.am: Remove -D__STRICT_ANSI__.
+
+2001-05-09 Joel Sherrill <joel@OARcorp.com>
+
+ * sapi/src/exinit.c: Slightly rework initialization so there is a valid
+ thread as _Thread_Executing when the pre_tasking hook is called. This
+ allows one directives and malloc to potentially use mutex protection.
+
+2001-04-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/shell/cmds.c, libmisc/shell/shell.c: Remove fileno-hacks.
+ * libmisc/monitor/mon-symbols.c: Remove #undef __STRICT_ANSI__.
+
+2001-04-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.in, itron/configure.in, posix/configure.in,
+ libfs/configure.in: Add [-ansi -fasm] to RTEMS_PROG_CC_FOR_TARGET.
+
+2001-04-26 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/include/rtems/posix/mqueue.h,
+ posix/inline/rtems/posix/mqueue.inl, posix/src/mqueue.c,
+ posix/src/mqueueclose.c, posix/src/mqueuecreatesupp.c,
+ posix/src/mqueuegetattr.c, posix/src/mqueuenotify.c,
+ posix/src/mqueueopen.c, posix/src/mqueuerecvsupp.c,
+ posix/src/mqueuesendsupp.c, posix/src/mqueuesetattr.c: Per PR81 reworked
+ to add a message queue descriptor separate from the underlying message
+ queue. This allows non-blocking to follow the "open" not the underlying
+ queue.
+ * score/src/objectcomparenamestring.c: Fix typos.
+ * score/include/rtems/score/object.h,
+ score/inline/rtems/score/object.inl, score/
+ src/objectcomparenamestring.c: Address PR81 that reworked POSIX message
+ queues to add a descriptor separate from the underlying message queue.
+ This allows non-blocking to follow the "open" not the underlying queue.
+ As part of debugging this it became clear that
+ _Objects_Compare_name_string was broken and a simple version using
+ strncmp() was substituted.
+
+2001-04-24 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/src/imfs/memfile.c (memfile_open): Did not set iop->size and
+ thus the value was incorrect. Before this field was cleared, this
+ resulted in the value from the last time that IOP was used being still
+ in place. Discovered by Andrew Bythell <abythell@nortelnetworks.com>.
+
+2001-04-24 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/lib/rtems_bsdnet_ntp.c: Modifications to make the RTEMS
+ NTP synchronization a little more robust -- no NTP daemon yet, but at
+ least it trys a little harder when the primary NTP server is down.
+
+2001-04-22 Joel Sherrill <joel@OARcorp.com>
+
+ * itron/src/task.c (_ITRON_Task_User_extensions): Add new fields to be
+ correct in respect to newly added fields for separate switch list.
+
+2001-04-20 Radzislaw Galler <rgaller@et.put.poznan.pl>
+
+ * libnetworking/modem/ppp.c, libnetworking/pppd/main.c,
+ libnetworking/pppd/pppmain.c, libnetworking/pppd/rtems-ppp.c,
+ libnetworking/pppd/modem_example/modem.c,
+ libnetworking/pppd/modem_example/ppp.c: Translated Polish comments and
+ other strings into English.
+ * libnetworking/pppd/STATUS: updated to reflect the changes.
+
+2001-04-20 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/devnull/devnull.c (null_initialize): Added check to ensure
+ that the driver is only initialized once. Otherwise, it will abort when
+ the device /dev/null is present. (null_write): Do not dereference a NULL
+ pointer.
+ * libfs/src/imfs/imfs_debug.c (IMFS_print_jnode): Modified to print only
+ information that does not vary based on target or memory configuration.
+ The old prints are still there in case they are needed in the future to
+ debug. Printing target dependent addresses makes the test output vary
+ by target unnecessarily.
+
+2001-04-20 Jake Janovetz <janovetz@uiuc.edu>
+
+ * libnetworking/rtems_servers/ftpd.c: Correct argument so hooks work
+ again.
+
+2001-04-20 Fernando Ruiz Casas <correo@fernando-ruiz.com>
+
+ * Added initial shell functionality.
+ * libmisc/Makefile.am, libmisc/configure.in, libmisc/wrapup/Makefile.am:
+ Reflect having added shell.
+ * libmisc/shell/.cvsignore, libmisc/shell/Makefile.am,
+ libmisc/shell/README, libmisc/shell/cmds.c, libmisc/shell/shell.c,
+ libmisc/shell/shell.h: New files.
+
+2001-04-16 Joel Sherrill <joel@OARcorp.com>
+
+ * sapi/include/confdefs.h: Fix real-time clock support.
+
+2001-04-11 Joel Sherrill <joel@OARcorp.com>
+
+ * score/macros/rtems/score/userext.inl: Now works after merging patch
+ for functionality requested in PR174.
+ * score/inline/rtems/score/userext.inl: Added a comment explaining the
+ order in which routines appear since it is not the obvious order.
+
+2001-04-08 Joel Sherrill <joel@OARcorp.com>
+
+ * score/macros/rtems/score/object.inl: Corrected arguments.
+ * score/macros/rtems/score/userext.inl: Updated to reflect modifications
+ to inline version from PR142.
+ * score/inline/rtems/score/userext.inl: Cleanup as side-effect of above.
+ * rtems/src/tasks.c: Pre-initialized switch extension for list.
+ * rtems/macros/rtems/score/timer.inl: Corrected typo on end of line.
+
+2001-04-04 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/src/dosfs/Makefile.am: Per PR129 do not install as many files to
+ the $(includedir).
+
+2001-03-29 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR126, configuration structures now match docs.
+ * sapi/include/rtems/config.h: Use public data types.
+ * Per PR126, configuration structures now match docs.
+ * rtems/include/rtems/rtems/config.h: Use public data types.
+ * Per PR147 addressed problems when reseting and inserting a timer into
+ a timer chain that did not honor time passage since the last time the
+ timer server was scheduled and the new insertion.
+ * rtems/include/rtems/rtems/timer.h, rtems/src/timerreset.c,
+ rtems/src/timerserver.c, rtems/src/timerserverfireafter.c,
+ rtems/src/timerserverfirewhen.c: Broke up the "reset server" routine
+ into a set of very specific routines that allowed the server to be
+ unscheduled, timer chains to be "synchronized" with the current time
+ before inserting a new timer.
+
+2001-03-28 Joel Sherrill <joel@OARcorp.com>
+
+ * PR132 requested some tinkering ot lower memory.
+ * sapi/include/confdefs.h: Lowered footprint of device driver table and
+ statically configure user extensions. Now if no static extensions are
+ configured, then the table is not instantiated.
+
+2001-03-26 Zoltan Kocsi <zoltan@bendor.com.au>
+
+ * rtems/src/eventsurrender.c: Clear event condition when task is
+ unblocked. This makes sure that subsequent event send thinks the task is
+ still blocked and overwrites the initial events received.
+
+2001-03-23 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/src/imfs/memfile.c: Reapply fix from bug report from Jose
+ Sturniolo <jsturnio@nec.com.ar> where NULL pointer was dereferenced when
+ freeing a triply indirect file. The fix was applied to the 4.5 release
+ branch and not the development branch.
+
+2001-03-20 Till Straumann <strauman@SLAC.Stanford.EDU>
+
+ * PR158
+ * libnetworking/libc/rcmd.c, libnetworking/libc/rcmd.c: Enable the
+ rcmd() library call by commenting out the parts that deal with signals.
+ This enables RTEMS to 'rsh' command to a server connecting fd to remote
+ stdio. The 'server-side' parts of this file which deal with
+ authentication are disabled since they are not needed.
+
+2001-03-19 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/sys/utsname.h: Added C++ wrapper.
+
+2001-03-15 Ralf Corsepius <corsepius@faw.uni-ulm.de>
+
+ * libnetworking/include/.cvsignore: Remove dangling file.
+
+2001-03-15 Joel Sherrill <joel@OARcorp.com>
+
+ * sapi/src/extension.c: Split to reduce minimum code size per PR134.
+ * sapi/src/extensioncreate.c, sapi/src/extensiondelete.c,
+ sapi/src/extensionident.c: New files. src/Makefile.am: Modified to
+ reflect above.
+
+2001-03-01 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/src/imfs/.cvsignore: Added stamp-h1.in.
+
+2001-02-07 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.in: AC_DEFINE RTEMS_UNIX if RTEMS_CPU=unix.
+
+2001-02-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libmisc/monitor/mon-command.c: Use #if defined(RTEMS_UNIX).
+
+2001-02-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * itron/include/Makefile.am, itron/include/itronsys/Makefile.am,
+ itron/include/rtems/itron/Makefile.am,
+ itron/inline/rtems/itron/Makefile.am,
+ itron/macros/rtems/itron/Makefile.am, posix/include/Makefile.am,
+ posix/include/rtems/posix/Makefile.am, posix/include/sys/Makefile.am,
+ posix/inline/rtems/posix/Makefile.am,
+ posix/macros/rtems/posix/Makefile.am: Apply include_*HEADERS instead of
+ H_FILES.
+ * include/rtems/Makefile.am, include/rtems/score/Makefile.am,
+ inline/rtems/score/Makefile.am, macros/rtems/score/Makefile.am Apply
+ include_*HEADERS instead of H_FILES.
+ * sapi/include/Makefile.am, sapi/include/rtems/Makefile.am,
+ sapi/inline/rtems/Makefile.am, sapi/macros/rtems/Makefile.am,
+ rtems/include/Makefile.am, rtems/include/rtems/rtems/Makefile.am,
+ rtems/inline/rtems/rtems/Makefile.am,
+ rtems/macros/rtems/rtems/Makefile.am, rtems/ rtems/optman/Makefile.am,
+ libmisc/untar/Makefile.am, libmisc/monitor/Makefile.am,
+ libmisc/dummy/Makefile.am, libmisc/devnull/Makefile.am,
+ libmisc/dumpbuf/Makefile.am, libmisc/mw-fb/Makefile.am,
+ libmisc/stackchk/Makefile.am, libmisc/rtmonuse/Makefile.am,
+ libmisc/cpuuse/Makefile.am, librpc/include/rpc/Makefile.am,
+ libfs/src/imfs/Makefile.am, libnetworking/Makefile.am,
+ libnetworking/arpa/Makefile.am, libnetworking/machine/Makefile.am,
+ libnetworking/net/Makefile.am, libnetworking/ netinet/Makefile.am,
+ libnetworking/nfs/Makefile.am, libnetworking/rtems/Makefile.am,
+ libnetworking/ rtems_servers/Makefile.am,
+ libnetworking/rtems_webserver/Makefile.am,
+ libnetworking/sys/Makefile.am, libnetworking/vm/Makefile.am: Apply
+ include_*HEADERS instead of H_FILES.
+ * libnetworking/include/Makefile.am: Remove.
+ * libnetworking/Makefile.am: Add handling of *.h files.
+ * libnetworking/configure.in: Remove include/Makefile.
+
+2001-01-31 Sergei Organov <osv@javad.ru>
+
+ * libnetworking/rtems_servers/ftp.d: Following changes: - Hacks with
+ current dir and root dir removed in favor of new libio support for
+ task-local current and root directories. - Bug in `close_data_socket()'
+ introduced by previous change fixed. - `command_pasv()' changed to set
+ timeout on socket we are listening on and code fixed to don't close
+ socket twice on error. - `serr()' changed to clear `errno'. -
+ `data_socket()' changed to clear `errno' before `bind()'. - `session()'
+ changed to clear `errno' before processing session. -
+ `close_data_socket()' fixed to close both active and passive sockets. -
+ Initialize info->data_socket to -1 in `daemon()'. - Initialize `fname'
+ to empty string in `exec_command()'.
+
+2001-01-31 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/include/rtems/rtems/timer.h: Missed merging these modifications
+ in previous merge of new timer functionality.
+
+2001-01-29 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/objectextendinformation.c: Added include of string.h to
+ eliminate warning.
+ * Fixed bug where resetting a timer that was not at the head of one of
+ the task timer chains resulted in the Timer Server task waking up too
+ far in the future.
+ * Added rtems_timer_get_information() directive to support testing.
+ * src/timerserver.c, include/rtems/rtems/timer.h,
+ * rtems/src/timergetinfo.c: New file.
+ * rtems/src/Makefile.am: Modified to reflect above.
+
+2001-01-28 Ralf Corsepius <corsepiu@faw.uni-ulm.d>
+
+ * sapi/include/confdefs.h: define CONFIGURE_NEWLIB_EXTENSION 0 if not
+ using NEWLIB, cleanup related comment.
+
+2001-01-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * sapi/include/confdefs.h: include cpuopts.h, replace stubdr w/ devnull.
+
+2001-01-25 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/lib/tftpDriver.c: Reduce first timeout interval. This
+ improves throughput on systems which are dropping packets. Only the
+ first timeout is reduced. This keeps the number of extra packets down
+ on networks that are very busy and dropping lots of packets.
+
+2001-01-24 Sergei Organov <osv@javad.ru>
+
+ * libnetworking/rtems_servers/ftpd.c,
+ libnetworking/rtems_servers/ftpd.h: - Timeouts on sockets implemented.
+ 'idle' field added to configuration. No timeout by default to keep
+ backward compatibility. Note: SITE IDLE command not implemented yet. -
+ Basic global access control implemented. 'access' field added to
+ configuration. No access limitations by default to keep backward
+ compatibility. - Anchor data socket for active mode (using self IP and
+ port 20.) - Fixed default data port support (still not tested). - Don't
+ allow IP address different from originating host in PORT command to
+ improve security. - Fixed bug in MDTM command. - Check for correctness
+ of parsing of argument in command_port(). - Fixed squeeze_path() to
+ don't allow names like 'NAME/smth' where 'NAME' is not a directory. -
+ Command parsing a little bit improved: command names are now converted
+ to upper-case to be more compatible with RFC (command names are not
+ case-sensitive.). - Reformat comments so that they have RTEMS
+ look-and-feel. - Fixed DELE, SITE CHMOD, RMD, MKD broken by previous
+ changes. - True ASCII mode implemented (doesn't work for hooks and
+ /dev/null) - Passive mode implemented, PASV command added. - Default
+ port for data connection could be used (untested, can't find ftp client
+ that doesn't send PORT command). - SYST reply changed to UNIX, as former
+ RTEMS isn't registered name. - Reply codes reviewed and fixed.
+
+2001-01-24 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * posix/configure.in: Add src/config.h.
+ * posix/src/Makefile.am: Add INCLUDES += -I. to pickup config.h.
+ * posix/src/.cvsignore: Add config.h and stamp-h.
+ * posix/src/*.c: Add config.h support.
+
+2001-01-23 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/alarm.c: Eliminated use of C++ style comments.
+
+2001-01-22 Michael Hamel <mhamel@adi.co.nz>
+
+ * posix/include/rtems/posix/semaphore.h,
+ posix/inline/rtems/posix/semaphore.inl, posix/ src/ptimer1.c,
+ posix/include/rtems/posix/semaphore.h,
+ posix/inline/rtems/posix/semaphore.inl, posix/src/alarm.c,
+ posix/src/ptimer1.c, posix/src/semaphorenametoid.c, posix/src/semopen.c,
+ posix/src/semunlink.c, rtems/include/rtems.h, rtems/src/signalcatch.c:
+ Modifications to make CodeWarrior happy.
+
+2001-01-22 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/include/rtems/rtems/timer.h, rtems/src/timerserver.c: Add
+ priority argument to rtems_timer_initiate_server().
+
+2001-01-18 Joel Sherrill <joel@OARcorp.com>
+
+ * score/include/rtems/system.h, rtems/include/rtems/system.h: Only
+ include cpuopts.h when building a multilib configuration. Some ports
+ still need targopts.h but this small modification lets those ports work
+ non-multilib while fixing being fixed for multilib.
+
+2001-01-17 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: Deleted duplicate blank line.
+
+2001-01-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libfs/configure.in: Add src/imfs/config.h.
+ * libfs/src/imfs/Makefile.am: Add INCLUDES += -I. to pickup config.h.
+ * libfs/src/imfs/.cvsignore: Add config.h and stamp-h.
+ * libfs/src/imfs/*.c: Add config.h support.
+
+2001-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/inline/rtems/posix/mutex.inl (_POSIX_Mutex_Get_support):
+ Corrected name of routine in header.
+ * rtems/Added task-based timers to the Timer Manager. This added three
+ new directives: - rtems_timer_initiate_server -
+ rtems_timer_server_fire_after - rtems_timer_server_fire_when In the
+ process of doing this, a number of cleanups were made.
+ * rtems/src/timerserver.c, rtems/src/timerserverfireafter.c,
+ rtems/src/timerserverfirewhen.c: New files.
+ * rtems/include/timer/timer.h: Added new prototypes and supporting types.
+ * rtems/inline/rtems/rtems/timer.h, rtems/macros/rtems/rtems/timer.h:
+ Enhanced _Timer_Is_interval_class() to cover the class
+ TIMER_INTERVAL_ON_TASK.
+ * rtems/src/Makefile.am: Accounted for new files.
+ * rtems/src/rtemstimer.c: Added initialization of _Timer_Server variable.
+ * rtems/src/timercancel.c, rtems/src/timerreset.c: Account for addition
+ of timer classes. Also corrected the headers.
+ * rtems/src/timercreate.c, rtems/src/timerdelete.c,
+ rtems/src/timerfireafter.c, rtems/ src/timerfireafter.c,
+ rtems/src/timerident.c: Corrected header.
+ * rtems/src/taskmode.c: Ensure the this service does not dispatch before
+ tasking is enabled at initialization time.
+
+2001-01-12 Sergei Organov <osv@javad.ru>
+
+ * libnetworking/rtems_servers/ftpd.c,
+ libnetworking/rtems_servers/ftpd.h: - use pool of pre-created threads to
+ handle sessions instead of creating/deleting threads on the fly. - LIST
+ output is now similar to what "/bin/ls -al" would output, thus FTP
+ clients such Netscape are happy with it. - LIST NAME now works (both for
+ files and directories) - added support for NLST, CDUP, and MDTM FTP
+ commands to make more FTP clients happy . - keep track of CWD for every
+ session separately. - ability to specify root directory name for FTPD in
+ configuration table. FTPD will then create illusion for FTP clients that
+ this is actually root directory. - ignore options sent in commands, thus
+ LIST -al FILE works and doesn't try to list "-al" directory. - buffers
+ are allocated on stack instead of heap where possible to eliminate
+ malloc/free calls (avoid possible heap fragmentation troubles). - drop
+ using of task notepad to pass parameters - use function arguments
+ instead. - use snprintf() instead of sprintf() as the latter is unsafe.
+ - use of PF_INET in socket() instead of AF_INET.
+
+2001-01-12 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/clockgetres.c: Fixed match problem. We are not converting
+ an interval to a timespec -- it is actually a real number of
+ microseconds.
+ * posix/src/README.mqueue: Enhanced example.
+
+2001-01-12 Jake Janovetz <janovetz@uiuc.edu>
+
+ * libfs/src/imfs/imfs.h, libfs/src/imfs/imfs_creat.c,
+ libfs/src/imfs/imfs_debug.c, libfs/src/imfs/imfs_eval.c,
+ libfs/src/imfs/imfs_fchmod.c, libfs/src/imfs/imfs_handlers_memfile.c,
+ libfs/src/imfs/imfs_init.c, libfs/src/imfs/imfs_initsupp.c,
+ libfs/src/imfs/imfs_stat.c, libfs/src/imfs/memfile.c,
+ libfs/src/imfs/miniimfs_init.c: Final developmental update to "tarfs".
+ When rtems_tarfs_load() is called, it checks the permissions on each
+ file. If there is write permission, it just creates a standard file
+ using "creat()" and therefore, uses the IMFS MEMORY_FILE. If there is no
+ write permission, it creates a LINEAR_FILE node with the appropriate
+ properties. If the permission is ever changed to writeable, IMFS_fchmod
+ converts it to a regular memory file.
+
+2001-01-08 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/src/threadinitialize.c: Removed warning.
+
+2001-01-08 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/threadinitialize.c: Fix my bad hack of Ralf's fp_area
+ warning removal patch. :(.
+
+2001-01-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * itron/configure.in: Add src/config.h.
+ * itron/src/Makefile.am: Add INCLUDES += -I. to pickup config.h.
+ * itron/src/.cvsignore: Add config.h and stamp-h.
+ * itron/src/*.c: Add config.h support.
+
+2001-01-05 Joel Sherrill <joel@OARcorp.com>
+
+ * libmisc/devnull: New addition. Moved from libcpu/sh.
+ * libmisc/devnull/devnull.c, libmisc/devnull/devnull.h,
+ libmisc/devnull/.cvsignore, libmisc/ devnull/Makefile.am: New files.
+ * libmisc/Makefile.am, libmisc/configure.in, libmisc/wrapup/Makefile.am:
+ Modified to reflect addition of above.
+
+2001-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/isr.c: Modify to properly dereference _ISR_Vector_table now
+ that it is dynamically allocated.
+
+2001-01-02 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/CHANGELOG: Removed.
+ * libnetworking/README: Merged CHANGELOG contents as initial changes.
+
+2000-12-19 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/pthreadgetschedparam.c: Do not set output parameters if the
+ pointers are NULL.
+ * score/src/isr.c: Allocate the _ISR_Vector_table all the time not just
+ when we are allocating an interrupt stack.
+
+2000-12-14 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/lib/tftpDriver.c: Added write capability.
+
+2000-12-13 Joel Sherrill <joel@OARcorp.com>
+
+ * score/include/rtems/score/isr.h, score/src/isr.c: Allocate it from the
+ workspace rather than explicitly declaring it. This allows the size to
+ be a non-constant from the perspective of score/cpu.
+
+2000-12-12 Jake Janovetz <janovetz@uiuc.edu>
+
+ * libfs/src/imfs/linearfile.c, libfs/src/imfs/imfs_load_tar.c: New files.
+ * libfs/src/imfs/Makefile.am, libfs/src/imfs/imfs.h,
+ libfs/src/imfs/imfs_creat.c, libfs/src/imfs/imfs_debug.c,
+ libfs/src/imfs/imfs_eval.c, libfs/src/imfs/imfs_handlers_memfile.c,
+ libfs/src/imfs/imfs_init.c, libfs/src/imfs/imfs_initsupp.c,
+ libfs/src/imfs/imfs_stat.c, libfs/src/imfs/miniimfs_init.c: Added
+ "tarfs". This is not really a tar filesystem. It is a way to load a tar
+ image into the IMFS but actually leave bulky file contents in the
+ original tar image. It essentially adds the linear file type and
+ associated support and a loader routine.
+
+2000-12-08 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/libc/linkaddr.c: Initialized variable to remove warning.
+ * libnetworking/modem/ppp.c, libnetworking/modem/ppp_tty.c: Made
+ numerous variable declarations conditional on PPP_COMPRESS and
+ PPP_FILTER. Commented out variables that were not used because the code
+ using them was commented out. Removed totally unused variables.
+ * libnetworking/modem/pppcompress.c: Added parentheses to avoid warnings.
+ * libnetworking/pppd/pppmain.c: Removed numerous warnings.
+
+2000-12-06 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/pthreadgetcpuclockid.c: Add include of <rtems/system.h> to
+ eliminate warning.
+ * rtems/src/regiongetinfo.c: Removed unused variable to eliminate
+ warning.
+
+2000-12-01 Joel Sherrill <joel@OARcorp.com>
+
+ * configure.in: Removed error check for enabling macros with either
+ POSIX or ITRON API.
+ * Added macro support to ITRON API. This is known to compile.
+ * itron/Makefile.am: Added macros directory.
+ * itron/configure.in: Removed error check for enabling macros.
+ * itron/macros/.cvsignore, itron/macros/Makefile.am,
+ itron/macros/rtems/.cvsignore, itron/macros/rtems/Makefile.am,
+ itron/macros/rtems/itron/.cvsignore,
+ itron/macros/rtems/itron/Makefile.am,
+ itron/macros/rtems/itron/eventflags.inl,
+ itron/macros/rtems/itron/fmempool.inl,
+ itron/macros/rtems/itron/intr.inl, itron/macros/rtems/itron/mbox.inl,
+ itron/macros/rtems/itron/msgbuffer.inl,
+ itron/macros/rtems/itron/network.inl, itron/macros/rtems/itron/port.inl,
+ itron/macros/rtems/itron/semaphore.inl,
+ itron/macros/rtems/itron/sysmgmt.inl, itron/macros/rtems/itron/task.inl,
+ itron/macros/rtems/itron/time.inl,
+ itron/macros/rtems/itron/vmempool.inl: New files.
+ * posix/include/rtems/posix/cond.h: #if 0'ed out prototype of
+ _POSIX_Condition_variables_Get to avoid conflict with macro
+ implementation.
+ * Added macro support to POSIX API. This is known to compile.
+ * posix/macros/rtems/posix/cond.inl, posix/macros/rtems/posix/intr.inl,
+ posix/macros/rtems/posix/key.inl, posix/macros/rtems/posix/mqueue.inl,
+ posix/macros/rtems/posix/mutex.inl,
+ posix/macros/rtems/posix/priority.inl,
+ posix/macros/rtems/posix/pthread.inl,
+ posix/macros/rtems/posix/semaphore.inl,
+ posix/macros/rtems/posix/timer.inl: New files.
+ * posix/configure.in: Removed error check for enabling macros.
+ * posix/rtems/posix/mutex.h: #if 0'ed out prototypes for inlined
+ routines since you cannot have prototypes for macros.
+ * posix/macros/rtems/posix/Makefile.am: Added files.
+ * score/macros/rtems/score/coresem.inl: Removed comments since
+ convention calls for comments to be in inline versin.
+ * score/macros/rtems/score/object.inl (Objects_Get_local_object): Fixed
+ style to use _ prefix on variable names and use parentheses.
+ * score/macros/rtems/score/object.inl (_Objects_Namespace_remove): Added.
+
+2000-11-30 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/inline/rtems/posix/mqueue.inl: Removed explicit dependency on
+ abs().
+ * General effort to make things compile with macros not inlines
+ * score/inline/rtems/score/coremutex.inl: Added comment indicating for
+ macros there is another copy of _CORE_mutex_Seize_interrupt_trylock() in
+ src/coremutexseize.c.
+ * score/src/coremutexseize.c: Added body of
+ _CORE_mutex_Seize_interrupt_trylock() for macro case.
+ * score/macros/rtems/score/coremutex.inl: Added prototype for
+ _CORE_mutex_Seize_interrupt_trylock() since there is a real body when
+ macros are enabled.
+ * score/macros/rtems/score/coresem.inl: Added macro implementation of
+ _CORE_semaphore_Seize_isr_disable.
+ * score/macros/score/Makefile.am: Fixed typos.
+ * score/rtems/score/address.inl: Correct macro implementation of
+ _Addresses_Is_aligned() so it would compile.
+ * score/macros/rtems/score/coremsg.inl: Added closing parentheses.
+ * rtems/src/msgqsubmit.c: Modified multiprocessing conditional so this
+ would compile with both macros and inlines.
+ * rtems/macros/rtems/rtems/sem.inl: Added macro implementation of
+ _Semaphore_Get_interrupt_disable().
+ * libmisc/mw-fb/mw_uid.c: Removed unnecessary dependency on <bsp.h>.
+ * libnetworking/modem/ppp_tty.c: Changed to include
+ <rtems/termiostypes.h> since that is an RTEMS specific header file.
+ * libnetworking/sys/ttycom.h: Moved to lib/include/sys.
+ * libnetworking/Makefile.am: Modified to reflect above.
+
+2000-11-28 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/src/imfs/memfile.c: Bug report from Sturniolo Jose
+ <jsturnio@nec.com.ar> where NULL pointer was dereferenced.
+
+2000-11-28 Chris Johns <ccj@acm.org>
+
+ * score/src/heapallocate.c: Do not allow the size to overflow when
+ adjusting it. A test allocated a stack of -1 (~0). This actually
+ resulted in a stack being allocated but with a size of 0xb. The
+ allocator did not test the size to see if it rolled through 0 and so
+ allowed the allocation to happen, the thread to get created. The task
+ crashed as you would expect.
+
+2000-11-27 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/sysconf.c: Add support for _SC_CLK_TCK and _SC_OPEN_MAX.
+ * libnetworking/libc/res_init.c: Fix typo - adding missing # on include.
+
+2000-11-25 Eric Norum <eric.norum@usask.ca>
+
+ * libnetworking/libc/res_init.c: Move include to avoid compiler dumping
+ core.
+
+2000-11-25 Antti P Miettinen <antti.p.miettinen@nokia.com>
+
+ * libnetworking/wrapup/Makefile.am, libnetworking/configure.in,
+ libnetworking/Makefile.am: Added modem subdir.
+ * libnetworking/net/Makefile.am: Added if_pppvar.h, pppcompress.h.
+ * libnetworking/pppd/Makefile.am: Added pppmain.c (which needs work).
+ * libnetworking/pppd/chat.c, libnetworking/pppd/fsm.c,
+ libnetworking/pppd/fsm.h, libnetworking/pppd/ipxcp.c,
+ libnetworking/pppd/main.c, libnetworking/pppd/ppp_tty.c,
+ libnetworking/pppd/upap.c: Changes from Thomas Doerfler
+ <Thomas.Doerfler@imd-systems.de> and cosmetic changes by me. Actually
+ main.c and ppp_tty.c should be scratched. The modem subdir has the real
+ ppp_tty.c and the real pppd main is in pppmain.c.
+
+2000-11-17 Jennifer Averret <jennifer@OARcorp.com>
+
+ * libfs/src/imfs/imfs_eval.c: Always return imaginary node at mount
+ points.
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, itron/Makefile.am, posix/Makefile.am,
+ libmisc/Makefile.am, librpc/Makefile.am, libfs/Makefile.am,
+ libnetworking/Makefile.am: Use ... instead of RTEMS_TOPdir in
+ ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, itron/Makefile.am, posix/Makefile.am,
+ libmisc/Makefile.am, librpc/Makefile.am, libfs/Makefile.am,
+ libnetworking/Makefile.am: Switch to ACLOCAL_AMFLAGS = -I
+ $(RTEMS_TOPdir)/aclocal.
+
+2000-11-02 Joel Sherrill <joel@OARcorp.com>
+
+ * score/include/rtems/system.h: Use proper conditional (RTEMS_POSIX_API)
+ so prototypes for POSIX_MP_NOT_IMPLEMENTED(), POSIX_NOT_IMPLEMENTED(),
+ POSIX_BOTTOM_REACHED() are actually included.
+ * score/include/rtems/system.h: Add prototypes for
+ POSIX_MP_NOT_IMPLEMENTED(), POSIX_NOT_IMPLEMENTED(),
+ POSIX_BOTTOM_REACHED() removed from newlib.
+
+2000-11-01 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/src/imfs/Makefile.am, libfs/src/imfs/deviceio.c,
+ libfs/src/imfs/imfs_chown.c, libfs/src/imfs/imfs_config.c,
+ libfs/src/imfs/imfs_creat.c, libfs/src/imfs/imfs_debug.c,
+ libfs/src/imfs/imfs_directory.c, libfs/src/imfs/imfs_eval.c,
+ libfs/src/imfs/imfs_fchmod.c, libfs/src/imfs/imfs_free.c,
+ libfs/src/imfs/imfs_fsunmount.c, libfs/src/imfs/imfs_gtkn.c,
+ libfs/src/imfs/imfs_init.c, libfs/src/imfs/imfs_initsupp.c,
+ libfs/src/imfs/imfs_link.c, libfs/src/imfs/imfs_mknod.c,
+ libfs/src/imfs/imfs_mount.c, libfs/src/imfs/imfs_readlink.c,
+ libfs/src/imfs/imfs_rmnod.c, libfs/src/imfs/imfs_stat.c,
+ libfs/src/imfs/imfs_symlink.c, libfs/src/imfs/imfs_unixstub.c,
+ libfs/src/imfs/imfs_unlink.c, libfs/src/imfs/imfs_unmount.c,
+ libfs/src/imfs/imfs_utime.c, libfs/src/imfs/ioman.c,
+ libfs/src/imfs/memfile.c, libfs/src/imfs/miniimfs_init.c: assoc.h,
+ error.h, libio_.h, libio.h, and libcsupport.h moved from libc to
+ lib/include/rtems and now must be referenced as <rtems/XXX.h>. Now we
+ do not have to reach up and over to libc to pick them up.
+
+2000-10-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * posix/configure.in: Cleanup comments.
+
+2000-10-30 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/include/Makefile.am: Updated to reflect files merged into
+ newlib. This resulted in some definitions moving to other files and thus
+ some secondary effects in RTEMS source code.
+ * posix/include/unistd.h: Removed. Now use newlib's.
+ * posix/include/rtems/posix/mqueue.h: Add include of <signal.h>.
+ * posix/include/rtems/posix/threadsup.h: Add include of <sys/signal.h>.
+ * posix/src/execv.c, posix/src/execve.c, posix/src/execvp.c: Corrected
+ prototype to agree with newlib.
+ * posix/src/psignal.c: Rewrote reference to <siginfo.h> in comment since
+ that file no longer exists.
+ * posix/src/pthreadkill.c, posix/src/sigaction.c: Added include of
+ <signal.h>.
+ * posix/src/sigtimedwait.c: Rewrote reference to <siginfo.h> in comment
+ since that file no longer exists.
+ * POSIX include files merged into newlib. This resulted in some
+ definitions moving to other files and thus some secondary effects in
+ RTEMS source code.
+ * sapi/include/confdefs.h: Replaced include of <sys/siginfo.h> with
+ <signal.h> since that file no longer exists.
+ * POSIX include files merged into newlib. This resulted in some
+ definitions moving to other files and thus some secondary effects in
+ RTEMS source code.
+ * librpc/src/rpc/Makefile.am, librpc/src/rpc/auth_time.c,
+ librpc/src/rpc/clnt_simple.c, librpc/src/rpc/clnt_tcp.c,
+ librpc/src/rpc/clnt_udp.c, librpc/src/rpc/clnt_unix.c,
+ librpc/src/rpc/get_myaddress.c, librpc/src/rpc/pmap_clnt.c,
+ librpc/src/rpc/pmap_getmaps.c, librpc/src/rpc/pmap_getport.c,
+ librpc/src/rpc/pmap_rmt.c, librpc/src/rpc/rtime.c,
+ librpc/src/rpc/svc_tcp.c, librpc/src/rpc/svc_udp.c,
+ librpc/src/rpc/svc_unix.c: Use of _read, _write, and _close as macros
+ conflicted with newlib's use of these as routine names. They were
+ renamed to include "_RPC_" prefix.
+ * POSIX include files merged into newlib. This resulted in some
+ definitions moving to other files and thus some secondary effects in
+ RTEMS source code.
+ * libnetworking/machine/types.h: Added _CLOCKID_T_ and _TIMER_T_ to be
+ in sync with newlib's <machine/types.h>.
+ * libnetworking/rtems/rtems_bsdnet_internal.h: newlib now includes
+ definition of struct itimerval in <sys/time.h>.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, itron/Makefile.am, posix/Makefile.am,
+ libmisc/Makefile.am, librpc/Makefile.am, libnetworking/Makefile.am:
+ ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros. Switch to GNU
+ canonicalization.
+
+2000-10-24 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libfs/Makefile.am, libfs/configure.in: Introduce GNU canonicalization
+ to libfs/. The approach is currently a bit of a hack as GNU
+ canonicalization does not support the per-BSP build some of the other
+ directories require. As more of the tree is converted, this will become
+ less of an issue.
+
+2000-10-24 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/src/imfs/imfs_config.c: New file containing IMFS configuration
+ information split from libc/base_fs.c.
+ * libfs/src/imfs/ioman.c: New file. Moved from lib/libc. Missed
+ previously.
+ * libfs/src/imfs/Makefile.am: Added imfs_config.c and ioman.c.
+
+2000-10-19 Joel Sherrill <joel@OARcorp.com>
+
+ * libfs/.cvsignore, libfs/src/.cvsignore, libfs/src/imfs/.cvsignore,
+ libfs/wrapup/.cvsignore: New files.
+
+2000-10-19 Antti P Miettinen <anmietti@trshp.ntc.nokia.com>
+
+ * libnetworking/lib/tftpDriver.c: add comments to handlers struct
+ function pointers.
+ * libnetworking/rtems/rtems_glue.c: move pointer arithmetic to be
+ _after_ pointer has been checked against NULL.
+
+2000-10-18 Nick Simon <Nick.SIMON@syntegra.bt.co.uk>
+
+ * score/src/heapgetinfo.c, score/include/rtems/score/heap.h,
+ score/src/Makefile.am: Added _Heap_Get_information() and information
+ control block.
+ * score/src/heapgetinfo.c: New file.
+
+2000-10-18 Joel Sherrill <joel@OARcorp.com>
+
+ * sapi/include/confdefs.h: Set CONFIGURE_INIT_TASK_STACK_SIZE to 0 if
+ there is no Classic API Initialization Tasks Table defined.
+ * sapi/include/confdefs.h: Modified code that accounts for
+ initialization task/threads with greater than minimum stack sizes so it
+ would compile even if optional APIs are disabled.
+ * rtems/src/regiongetinfo.c, rtems/include/rtems/rtems/region.h,
+ rtems/include/rtems/rtems/types.h, rtems/src/Makefile.am: Added
+ region_get_information() and information control block.
+ * rtems/src/regiongetinfo.c: New file.
+
+2000-10-18 Chris Johns <ccj@acm.org>
+
+ * libfs created.
+ * libfs/src, libfs/src/imfs, libfs/wrapup: New directories.
+ * libfs/ChangeLog, libfs/Makefile.am, libfs/README, libfs/configure.in,
+ libfs/src/Makefile.am, libfs/wrapup/Makefile.am: New files.
+ * libfs/src/imfs/deviceio.c, libfs/src/imfs/imfs_getchild.c,
+ libfs/src/imfs/imfs_readlink.c, libfs/src/imfs/imfs.h,
+ libfs/src/imfs/imfs_gtkn.c, libfs/src/imfs/imfs_rmnod.c,
+ libfs/src/imfs/imfs_chown.c, libfs/src/imfs/imfs_handlers_device.c,
+ libfs/src/imfs/imfs_stat.c, libfs/src/imfs/imfs_creat.c,
+ libfs/src/imfs/imfs_handlers_directory.c, libfs/src/imfs/imfs_symlink.c,
+ libfs/src/imfs/imfs_debug.c, libfs/src/imfs/imfs_handlers_link.c,
+ libfs/src/imfs/imfs_unixstub.c, libfs/src/imfs/imfs_directory.c,
+ libfs/src/imfs/imfs_handlers_memfile.c, libfs/src/imfs/imfs_unlink.c,
+ libfs/src/imfs/imfs_eval.c, libfs/src/imfs/imfs_init.c,
+ libfs/src/imfs/imfs_unmount.c, libfs/src/imfs/imfs_fchmod.c,
+ libfs/src/imfs/imfs_initsupp.c, libfs/src/imfs/imfs_utime.c,
+ libfs/src/imfs/imfs_fcntl.c, libfs/src/imfs/imfs_link.c,
+ libfs/src/imfs/memfile.c, libfs/src/imfs/imfs_fdatasync.c,
+ libfs/src/imfs/imfs_mknod.c, libfs/src/imfs/miniimfs_init.c,
+ libfs/src/imfs/imfs_free.c, libfs/src/imfs/imfs_mount.c,
+ libfs/src/imfs/imfs_fsunmount.c, libfs/src/imfs/imfs_ntype.c: New files.
+ Moved from libc.
+ * libnetworking/pppd/ipxcp.c: Fixed a typo.
+
+2000-10-12 Joel Sherrill <joel@OARcorp.com>
+
+ * sapi/include/confdefs.h: Account for initialization tasks and threads
+ which use larger than minimum stack sizes.
+
+2000-09-29 Stephan Merker <merker@decrc.abb.de>
+
+ * rtems/include/rtems/rtems/ratemon.h, rtems/src/ratemonperiod.c,
+ rtems/src/ratemontimeout.c: Add next_length field so period length can
+ be changed by the the sequence period(X), period(not X) with no
+ intervening cancel or expiration.
+
+2000-09-28 Joel Sherrill <joel@OARcorp.com>
+
+ * sapi/include/rtems/io.h (rtems_driver_address_table): Added "_entry"
+ to all names.
+ * sapi/src/io.c: Accounted for above.
+ * libmisc/monitor/mon-driver.c: Accounted for addition of "_entry" to
+ fields in rtems_driver_address_table.
+ * libnetworking/rtems_webserver/Makefile.am,
+ libnetworking/rtems_webserver/base64.c,
+ libnetworking/rtems_webserver/base64.c: Renamed base64.c to wbase64.c.
+ * libnetworking/rtems_webserver/sock.c: Added file missed in merger.
+
+2000-09-25 Joel Sherrill <joel@OARcorp.com>
+
+ * score/rtems/system.h: Switched a29k and hppa1.1 to using cpuopts.h not
+ targopts.h to reduce dependency on BSP.
+
+2000-09-22 Joel Sherrill <joel@OARcorp.com>
+
+ * librpc/src/xdr/xdr_float.c: Added A29K support.
+ * libnetworking/machine/types.h, libnetworking/pppd/pppd.h,
+ libnetworking/rtems/rtems_bsdnet_internal.h,
+ libnetworking/rtems_webserver/webmain.c: machine/types.h should not
+ have included rtems.h. It is now including precisely the least amount
+ of low level, yet portable .h files to get the basic RTEMS types
+ defined. This rippled into other files since rtems_bsdnet_internal.h
+ used machine/types.h to include rtems.h.
+
+2000-09-20 Joel Sherrill <joel@OARcorp.com>
+
+ * score/src/objectgetbyindex.c: Do not enable dispatching on an error
+ path it was not disabled on.
+
+2000-09-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/rtems/Makefile.am: Use PROJECT_TOPdir in path to size_rtems.
+ * libnetworking/ChangeLog: Cleanup.
+
+2000-09-05 Joel Sherrill <joel@OARcorp.com>
+
+ * libnetworking/rtems/rtems_syscall.c: Changed from O_NONBLOCK to
+ internal RTEMS_LIBIO_FLAGS_NO_DELAY to avoid O_NONBLOCK/O_NDELAY
+ confusion and to work with the converted flags.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * wrapup/itron/Makefile.am, wrapup/posix/Makefile.am,
+ wrapup/rtems/Makefile.am, itron/src/Makefile.am, posix/src/Makefile.am,
+ posix/optman/Makefile.am, score/src/Makefile.am, sapi/src/Makefile.am,
+ sapi/optman/Makefile.am, rtems/optman/Makefile.am,
+ rtems/src/Makefile.am, libmisc/cpuuse/Makefile.am,
+ libmisc/dummy/Makefile.am, libmisc/dumpbuf/Makefile.am,
+ libmisc/monitor/Makefile.am, libmisc/rtmonuse/Makefile.am,
+ libmisc/stackchk/Makefile.am, libmisc/untar/Makefile.am,
+ libmisc/wrapup/Makefile.am, libmisc/mw-fb/Makefile.am,
+ librpc/src/rpc/Makefile.am, librpc/src/xdr/Makefile.am,
+ libnetworking/kern/Makefile.am, libnetworking/lib/Makefile.am,
+ libnetworking/libc/Makefile.am, libnetworking/net/Makefile.am,
+ libnetworking/netinet/Makefile.am, libnetworking/nfs/Makefile.am,
+ libnetworking/pppd/Makefile.am, libnetworking/rtems/Makefile.am,
+ libnetworking/rtems_servers/Makefile.am,
+ libnetworking/rtems_webserver/Makefile.am,
+ libnetworking/wrapup/Makefile.am: Include compile.am.
+
+2000-09-01 Rosimildo daSilva <rdasilva@connecttel.com>
+
+ * libnetworking/emfdb.c: Removed stray semi-colon. Reported on GoAhead
+ mailing lists by Jim Rudnicki <jdrudnicki@yahoo.com>.
+
+2000-08-31 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * libnetworking/netinet/tcp_input.c: Spelling corrections.
+
+2000-08-31 Joel Sherrill <joel@OARcorp.com>
+
+ * Merged version 2.1 of GoAhead webserver. This update was submitted by
+ Antti P Miettinen <antti.p.miettinen@nokia.com>.
+ * libnetworking/NOTES, libnetworking/base64.c, libnetworking/ejIntrn.h,
+ libnetworking/emfdb.c, libnetworking/emfdb.h, libnetworking/md5.h,
+ libnetworking/md5c.c, libnetworking/ um.c, libnetworking/um.h: New files.
+ * libnetworking/wbase64.c: Removed.
+ * libnetworking/Makefile.am, libnetworking/asp.c,
+ libnetworking/balloc.c, libnetworking/default.c, libnetworking/ej.h,
+ libnetworking/ejlex.c, libnetworking/ejparse.c, libnetworking/ form.c,
+ libnetworking/h.c, libnetworking/handler.c, libnetworking/mime.c,
+ libnetworking/misc.c, libnetworking/ringq.c, libnetworking/rom.c,
+ libnetworking/security.c, libnetworking/ socket.c, libnetworking/sym.c,
+ libnetworking/uemf.c, libnetworking/uemf.h, libnetworking/url.c,
+ libnetworking/value.c, libnetworking/webcomp.c, libnetworking/webmain.c,
+ libnetworking/ webpage.c, libnetworking/webrom.c, libnetworking/webs.c,
+ libnetworking/webs.h, libnetworking/websuemf.c, libnetworking/wsIntrn.h:
+ Modified.
+
+2000-08-30 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/Many files, score/Many files, libmisc/Many files: Moved
+ posix/include/rtems/posix/seterr.h to score/include/rtems/seterr.h so
+ it would be available within all APIs.
+ * libmisc/mw-fb/.cvsignore, libnetworking/rtems_webserver/license.txt:
+ New file.
+
+2000-08-30 Joel Sherrill <joel.sherrill@OARcorp.com>
+
+ * rtems/taskstart.c: Removed 1st cut at rtems_task_start_main_style.
+ Only committed this so it could be easily revisited as we discussing
+ moving main() to user space from BSP space.
+ * rtems/taskstart.c: Added 1st cut at rtems_task_start_main_style.
+
+2000-08-26 Rosimildo da Silva <rdasilva@connecttel.com>
+
+ * Added generic Micro FrameBuffer interface for MicroWindows. This
+ interface allows MicroWindows to under RTEMS. A sample driver has been
+ developed for the pc386 BSP. See pc386/fb_vga.c as a sample.
+ * Added Uniform Input Device interface for MicroWindows. See PC386 bsp
+ for sample drivers for mouse and keyboard (console).
+ * libmisc/mw-bf: New directory.
+ * libmisc/Makefile.am, libmisc/configure.in, libmisc/wrapup/Makefile.am:
+ Account for mw-fb.
+ * libmisc/mw-fb/Makefile.am, libmisc/mw-fb/mw_fb.c,
+ libmisc/mw-fb/mw_fb.h, libmisc/mw-fb/mw_uid.c, libmisc/mw-fb/mw_uid.h:
+ New file.
+
+2000-08-25 Joel Sherrill <joel.sherrill@OARcorp.com>
+
+ * posix/inline/rtems/posix/timer.inl, posix/include/rtems/posix/timer.h,
+ posix/ inline/rtems/posix/Makefile.am, posix/src/ptimer1.c: Redid the
+ style of src/ptimer1.c. Continued effort to make the POSIX Timer
+ implementation match that of other managers. Added data structures
+ required to use SuperCore Object Handler.
+
+2000-08-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * score/include/rtems/system.h: Include cpuopts.h for __i386__.
+
+2000-08-15 Joel Sherrill <joel@OARcorp.com>
+
+ * posix/src/ptimer1.c: Minor formatting fixes.
+ * posix/src/ptimer1.c: Removed unused routine PRINT_ERRNO_S.
+ * posix/src/ptimer1.c: Removed unnecessary routine COPY_ITIMERSPEC_S and
+ used structure copy instead.
+ * posix/src/ptimer1.c: Renamed timer_alive_t to POSIX_Timer_Control.
+ * posix/include/rtems/posix/timer.h: Ditto.
+ * posix/src/ptimer1.c: Switched to using
+ set_errno_and_return_minus_one() to ensure that errno was always set.
+ * posix/src/ptimer1.c (timer_settime): Converted use of rtems_clock_get
+ to use SuperCore _TOD_Current variable.
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog, itron/ChangeLog, posix/ChangeLog, score/ChangeLog,
+ sapi/ChangeLog, rtems/ChangeLog, libmisc/ChangeLog, librpc/ChangeLog,
+ libnetworking/ChangeLog: New file.
+
diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am
new file mode 100644
index 0000000000..868d4c4b36
--- /dev/null
+++ b/cpukit/Makefile.am
@@ -0,0 +1,173 @@
+##
+## $Id$
+##
+
+ACLOCAL_AMFLAGS = -I aclocal
+
+include $(top_srcdir)/automake/compile.am
+include $(top_srcdir)/automake/multilib.am
+
+# librtemscpu
+SUBDIRS = . score rtems sapi posix itron
+SUBDIRS += libcsupport libblock libfs
+SUBDIRS += libnetworking librpc
+SUBDIRS += libi2c
+SUBDIRS += libmisc
+SUBDIRS += wrapup
+
+SUBDIRS += zlib
+
+# applications
+SUBDIRS += httpd
+SUBDIRS += ftpd
+SUBDIRS += telnetd
+SUBDIRS += pppd
+
+EXTRA_DIST = ampolish3
+
+noinst_DATA = preinstall-stamp
+preinstall-stamp:
+ $(MAKE) $(AM_MAKEFLAGS) preinstall
+ touch preinstall-stamp
+CLEANFILES = preinstall-stamp
+
+include_HEADERS =
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS =
+
+include_rtems_rtemsdir = $(includedir)/rtems/rtems
+include_rtems_rtems_HEADERS =
+
+if DEPRECATED
+include_HEADERS += backward/asm.h backward/chain.h backward/clockdrv.h \
+ backward/confdefs.h backward/console.h backward/imfs.h backward/iosupp.h \
+ backward/ringbuf.h backward/rtc.h backward/spurious.h \
+ backward/timerdrv.h backward/vmeintr.h
+
+if HAS_NETWORKING
+include_HEADERS += backward/ftpd.h
+
+include_HEADERS += backward/rtemspppd.h
+include_HEADERS += backward/rtemsdialer.h
+endif
+
+include_motoroladir = $(includedir)/motorola
+include_motorola_HEADERS = backward/motorola/mc68681.h \
+ backward/motorola/mc68230.h
+
+include_zilogdir = $(includedir)/zilog
+include_zilog_HEADERS = backward/zilog/z8536.h backward/zilog/z8036.h \
+ backward/zilog/z8030.h
+
+if !UNIX
+include_HEADERS += backward/dosfs.h
+endif
+
+if HAS_ITRON
+include_HEADERS += backward/itron.h
+endif
+endif
+
+if NEWLIB
+include_sysdir = $(includedir)/sys
+include_sys_HEADERS =
+
+include_HEADERS += libnetworking/memory.h
+
+if RTEMS_PROVIDES_STDINT_H
+include_HEADERS += libcsupport/include/stdint.h
+endif
+if RTEMS_PROVIDES_INTTYPES_H
+include_HEADERS += libcsupport/include/inttypes.h
+endif
+include_HEADERS += libcsupport/include/tar.h
+
+include_sys_HEADERS += libcsupport/include/sys/ioccom.h \
+ libcsupport/include/sys/filio.h libcsupport/include/sys/ioctl.h \
+ libcsupport/include/sys/sockio.h libcsupport/include/sys/ttycom.h \
+ libcsupport/include/sys/termios.h libcsupport/include/sys/utsname.h \
+ libcsupport/include/sys/cdefs.h
+
+if HAS_NETWORKING
+include_rtems_bsdnetdir = $(includedir)/rtems/bsdnet
+include_rtems_bsdnet_HEADERS = libnetworking/rtems/bsdnet/servers.h
+include_rtems_bsdnet_HEADERS += libnetworking/rtems/bsdnet/_types.h
+endif
+endif
+
+include_rtems_HEADERS += include/rtems/bspIo.h include/rtems/userenv.h \
+ include/rtems/fs.h include/rtems/pci.h include/rtems/stdint.h \
+ include/rtems/concat.h include/rtems/tar.h
+
+## should be conditional and only installed for PowerPC, x86, and ARM
+include_rtems_HEADERS += include/rtems/irq.h
+
+## libfs
+include_rtems_HEADERS += libfs/src/imfs/imfs.h
+
+if !UNIX
+include_rtems_HEADERS += libfs/src/dosfs/dosfs.h
+endif
+
+## libblock
+if !UNIX
+include_rtems_HEADERS += libblock/include/rtems/bdbuf.h \
+ libblock/include/rtems/blkdev.h libblock/include/rtems/diskdevs.h \
+ libblock/include/rtems/ramdisk.h \
+ libblock/include/rtems/ide_part_table.h
+endif
+
+## ftpd
+if HAS_NETWORKING
+include_rtems_HEADERS += ftpd/ftpd.h
+endif
+
+## capture
+include_rtems_HEADERS += libmisc/capture/capture.h \
+ libmisc/capture/capture-cli.h
+
+## cpuuse
+include_rtems_HEADERS += libmisc/cpuuse/cpuuse.h
+
+## devnull
+include_rtems_HEADERS += libmisc/devnull/devnull.h
+
+## dumpbuf
+include_rtems_HEADERS += libmisc/dumpbuf/dumpbuf.h
+
+## monitor
+include_rtems_HEADERS += libmisc/monitor/monitor.h
+
+## mw-fb
+include_rtems_HEADERS += libmisc/mw-fb/mw_fb.h libmisc/mw-fb/mw_uid.h
+
+## shell
+if LIBSHELL
+include_rtems_HEADERS += libmisc/shell/shell.h
+endif
+
+## rtmonuse
+include_rtems_HEADERS += libmisc/rtmonuse/rtmonuse.h
+
+## i2c
+include_rtems_HEADERS += libi2c/libi2c.h
+
+## serdbg
+if LIBSERDBG
+include_rtems_HEADERS += libmisc/serdbg/serdbgcnf.h libmisc/serdbg/serdbg.h \
+ libmisc/serdbg/termios_printk_cnf.h libmisc/serdbg/termios_printk.h
+endif
+
+## stackchk
+include_rtems_HEADERS += libmisc/stackchk/stackchk.h
+
+## libuntar
+include_rtems_HEADERS += libmisc/untar/untar.h
+
+## fsmount
+include_rtems_HEADERS += libmisc/fsmount/fsmount.h
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/subdirs.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/acinclude.m4 b/cpukit/acinclude.m4
new file mode 100644
index 0000000000..ef4268e84b
--- /dev/null
+++ b/cpukit/acinclude.m4
@@ -0,0 +1,21 @@
+# RTEMS_CPUOPT(NAME,CONDITION,VALUE,EXPLANATION)
+
+AC_DEFUN([RTEMS_CPUOPT],
+[
+ if $2; then
+cat >>cpuopts.tmp <<_ACEOF
+
+/* $4 */
+#define $1 $3
+_ACEOF
+## FIXME: Duplicate the define to the autoheader
+## Sanity check - Should be removed in future
+ AC_DEFINE_UNQUOTED([$1],[$3],[$4])
+ else
+cat >>cpuopts.tmp <<\_ACEOF
+
+/* $4 */
+/* #undef $1 */
+_ACEOF
+ fi
+])
diff --git a/cpukit/aclocal/canonical-target-name.m4 b/cpukit/aclocal/canonical-target-name.m4
new file mode 100644
index 0000000000..963a71cda3
--- /dev/null
+++ b/cpukit/aclocal/canonical-target-name.m4
@@ -0,0 +1,40 @@
+dnl
+dnl $Id$
+dnl
+
+dnl canonicalize target cpu
+dnl NOTE: Most rtems targets do not fullfil autoconf's
+dnl target naming conventions "processor-vendor-os"
+dnl Therefore autoconf's AC_CANONICAL_TARGET will fail for them
+dnl and we have to fix it for rtems ourselves
+
+AC_DEFUN([RTEMS_CANONICAL_TARGET_CPU],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_MSG_CHECKING(rtems target cpu)
+case "${host}" in
+ # hpux unix port should go here
+ i[[34567]]86-*linux*) # unix "simulator" port
+ RTEMS_CPU=unix
+ ;;
+ i[[34567]]86-*freebsd*) # unix "simulator" port
+ RTEMS_CPU=unix
+ ;;
+ i[[34567]]86-pc-cygwin*) # Cygwin is just enough unix like :)
+ RTEMS_CPU=unix
+ ;;
+ no_cpu-*rtems*)
+ RTEMS_CPU=no_cpu
+ ;;
+ sparc-sun-solaris*) # unix "simulator" port
+ RTEMS_CPU=unix
+ ;;
+ tic4x-*rtems*) # gcc changed the name
+ RTEMS_CPU=c4x
+ ;;
+ *)
+ RTEMS_CPU=`echo $host | sed 's%^\([[^-]]*\)-\(.*\)$%\1%'`
+ ;;
+esac
+AC_SUBST(RTEMS_CPU)
+AC_MSG_RESULT($RTEMS_CPU)
+])
diff --git a/cpukit/aclocal/canonicalize-tools.m4 b/cpukit/aclocal/canonicalize-tools.m4
new file mode 100644
index 0000000000..540c9a4c29
--- /dev/null
+++ b/cpukit/aclocal/canonicalize-tools.m4
@@ -0,0 +1,15 @@
+dnl
+dnl $Id$
+dnl
+dnl Set target tools
+dnl
+
+AC_DEFUN([RTEMS_CANONICALIZE_TOOLS],
+[AC_REQUIRE([RTEMS_PROG_CC])dnl
+
+dnl FIXME: What shall be done if these tools are not available?
+ RTEMS_CHECK_TOOL(AR,ar,no)
+
+dnl special treatment of ranlib
+ RTEMS_CHECK_TOOL(RANLIB,ranlib,:)
+])
diff --git a/cpukit/aclocal/check-itron.m4 b/cpukit/aclocal/check-itron.m4
new file mode 100644
index 0000000000..3beefa985b
--- /dev/null
+++ b/cpukit/aclocal/check-itron.m4
@@ -0,0 +1,16 @@
+dnl $Id$
+dnl
+AC_DEFUN([RTEMS_CHECK_ITRON_API],
+[dnl
+AC_REQUIRE([RTEMS_ENABLE_ITRON])dnl
+
+AC_CACHE_CHECK([whether CPU supports libitron],
+ rtems_cv_HAS_ITRON_API,
+ [dnl
+ if test "${RTEMS_HAS_ITRON_API}" = "yes"; then
+ rtems_cv_HAS_ITRON_API="yes";
+ else
+ rtems_cv_HAS_ITRON_API="disabled";
+ fi
+ ])
+])
diff --git a/cpukit/aclocal/check-multiprocessing.m4 b/cpukit/aclocal/check-multiprocessing.m4
new file mode 100644
index 0000000000..ca4338b09a
--- /dev/null
+++ b/cpukit/aclocal/check-multiprocessing.m4
@@ -0,0 +1,9 @@
+dnl
+dnl $Id$
+dnl
+
+AC_DEFUN([RTEMS_CHECK_MULTIPROCESSING],
+[dnl
+AC_REQUIRE([RTEMS_ENV_RTEMSCPU])dnl
+AC_REQUIRE([RTEMS_ENABLE_MULTIPROCESSING])dnl
+])
diff --git a/cpukit/aclocal/check-networking.m4 b/cpukit/aclocal/check-networking.m4
new file mode 100644
index 0000000000..289c1b3eb2
--- /dev/null
+++ b/cpukit/aclocal/check-networking.m4
@@ -0,0 +1,28 @@
+dnl $Id$
+dnl
+AC_DEFUN([RTEMS_CHECK_NETWORKING],
+[dnl
+AC_REQUIRE([RTEMS_CANONICAL_TARGET_CPU])dnl
+AC_REQUIRE([RTEMS_ENABLE_NETWORKING])dnl
+
+AC_CACHE_CHECK([whether CPU supports networking],
+ rtems_cv_HAS_NETWORKING,
+ [dnl
+ case "$RTEMS_CPU" in
+ unix*)
+ rtems_cv_HAS_NETWORKING="no"
+ ;;
+ *)
+ if test "${RTEMS_HAS_NETWORKING}" = "yes"; then
+ rtems_cv_HAS_NETWORKING="yes";
+ else
+ rtems_cv_HAS_NETWORKING="disabled";
+ fi
+ ;;
+ esac])
+if test "$rtems_cv_HAS_NETWORKING" = "yes"; then
+ HAS_NETWORKING="yes";
+else
+ HAS_NETWORKING="no";
+fi
+])
diff --git a/cpukit/aclocal/check-newlib.m4 b/cpukit/aclocal/check-newlib.m4
new file mode 100644
index 0000000000..bbf5f68dc2
--- /dev/null
+++ b/cpukit/aclocal/check-newlib.m4
@@ -0,0 +1,30 @@
+dnl $Id$
+
+AC_DEFUN([RTEMS_CHECK_NEWLIB],
+[dnl
+AC_REQUIRE([RTEMS_PROG_CC_FOR_TARGET])dnl
+AC_REQUIRE([RTEMS_CANONICALIZE_TOOLS])dnl
+AC_CACHE_CHECK([for RTEMS newlib],
+ rtems_cv_use_newlib,
+ [
+dnl some versions of newlib provide not_required_by_rtems
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[extern void not_required_by_rtems() ;]],
+ [[not_required_by_rtems()]])],
+ [rtems_cv_use_newlib="yes"],[])
+
+dnl some versions of newlib provide rtems_provides_crt0()
+ AS_IF([test -z "$rtems_cv_use_newlib"],
+ [AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[extern void rtems_provides_crt0() ;]],
+ [[rtems_provides_crt0()]])],
+ [rtems_cv_use_newlib="yes"],[rtems_cv_use_newlib="no"])
+ ])
+ ])
+ RTEMS_USE_NEWLIB="$rtems_cv_use_newlib"
+ AC_SUBST(RTEMS_USE_NEWLIB)
+
+ AS_IF([test x"${RTEMS_USE_NEWLIB}" = x"yes"],
+ [ AC_DEFINE_UNQUOTED(RTEMS_NEWLIB,1,[if using newlib])]
+ )
+])
diff --git a/cpukit/aclocal/check-posix.m4 b/cpukit/aclocal/check-posix.m4
new file mode 100644
index 0000000000..be60c5f74a
--- /dev/null
+++ b/cpukit/aclocal/check-posix.m4
@@ -0,0 +1,23 @@
+dnl $Id$
+dnl
+AC_DEFUN([RTEMS_CHECK_POSIX_API],
+[dnl
+AC_REQUIRE([RTEMS_CANONICAL_TARGET_CPU])dnl
+AC_REQUIRE([RTEMS_ENABLE_POSIX])dnl
+
+AC_CACHE_CHECK([whether CPU supports libposix],
+ rtems_cv_HAS_POSIX_API,
+ [dnl
+ case "$RTEMS_CPU" in
+ unix*)
+ rtems_cv_HAS_POSIX_API="no"
+ ;;
+ *)
+ if test "${RTEMS_HAS_POSIX_API}" = "yes"; then
+ rtems_cv_HAS_POSIX_API="yes";
+ else
+ rtems_cv_HAS_POSIX_API="disabled";
+ fi
+ ;;
+ esac])
+])
diff --git a/cpukit/aclocal/check-rtems-debug.m4 b/cpukit/aclocal/check-rtems-debug.m4
new file mode 100644
index 0000000000..d8d1818520
--- /dev/null
+++ b/cpukit/aclocal/check-rtems-debug.m4
@@ -0,0 +1,7 @@
+## $Id$
+
+AC_DEFUN([RTEMS_CHECK_RTEMS_DEBUG],
+[AC_REQUIRE([RTEMS_ENABLE_RTEMS_DEBUG])
+AS_IF([test x"${enable_rtems_debug}" = x"yes"]
+ [AC_DEFINE_UNQUOTED(RTEMS_DEBUG,1,[if RTEMS_DEBUG is enabled])])
+])
diff --git a/cpukit/aclocal/check-tool.m4 b/cpukit/aclocal/check-tool.m4
new file mode 100644
index 0000000000..4c412c074a
--- /dev/null
+++ b/cpukit/aclocal/check-tool.m4
@@ -0,0 +1,11 @@
+dnl $Id$
+
+## Check for a cross tool, similar to AC_CHECK_TOOL, but do not fall back to
+## the un-prefixed version of PROG-TO-CHECK-FOR.
+dnl RTEMS_CHECK_TOOL(VARIABLE, PROG-TO-CHECK-FOR[, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN([RTEMS_CHECK_TOOL],
+[
+ AS_IF([test "x$build_alias" != "x$host_alias"],
+ [rtems_tool_prefix=${ac_tool_prefix}])
+ AC_CHECK_PROG($1, ${rtems_tool_prefix}$2, ${rtems_tool_prefix}$2, $3, $4)
+])
diff --git a/cpukit/aclocal/enable-inlines.m4 b/cpukit/aclocal/enable-inlines.m4
new file mode 100644
index 0000000000..2c79538dce
--- /dev/null
+++ b/cpukit/aclocal/enable-inlines.m4
@@ -0,0 +1,11 @@
+dnl $Id$
+
+AC_DEFUN([RTEMS_ENABLE_INLINES],
+[AC_ARG_ENABLE(rtems-inlines,
+AS_HELP_STRING(--enable-rtems-inlines,enable RTEMS inline functions (default:enabled, disable to use macros)),
+[case "${enableval}" in
+ yes) enable_rtems_inlines=yes ;;
+ no) enable_rtems_inlines=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for enable-rtems-inlines option) ;;
+esac],[enable_rtems_inlines=yes])
+])
diff --git a/cpukit/aclocal/enable-itron.m4 b/cpukit/aclocal/enable-itron.m4
new file mode 100644
index 0000000000..701d161ed7
--- /dev/null
+++ b/cpukit/aclocal/enable-itron.m4
@@ -0,0 +1,12 @@
+dnl $Id$
+
+AC_DEFUN([RTEMS_ENABLE_ITRON],
+[
+AC_ARG_ENABLE(itron,
+AS_HELP_STRING(--enable-itron,enable itron interface),
+[case "${enableval}" in
+ yes) RTEMS_HAS_ITRON_API=yes ;;
+ no) RTEMS_HAS_ITRON_API=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for enable-itron option) ;;
+esac],[RTEMS_HAS_ITRON_API=yes])
+])
diff --git a/cpukit/aclocal/enable-multiprocessing.m4 b/cpukit/aclocal/enable-multiprocessing.m4
new file mode 100644
index 0000000000..f664800e40
--- /dev/null
+++ b/cpukit/aclocal/enable-multiprocessing.m4
@@ -0,0 +1,12 @@
+dnl $Id$
+
+AC_DEFUN([RTEMS_ENABLE_MULTIPROCESSING],
+[
+AC_ARG_ENABLE(multiprocessing,
+AS_HELP_STRING(--enable-multiprocessing,enable multiprocessing interface),
+[case "${enable_multiprocessing}" in
+ yes) ;;
+ no) ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for enable-multiprocessing option) ;;
+esac],[enable_multiprocessing=no])
+])
diff --git a/cpukit/aclocal/enable-networking.m4 b/cpukit/aclocal/enable-networking.m4
new file mode 100644
index 0000000000..a7be7b4df7
--- /dev/null
+++ b/cpukit/aclocal/enable-networking.m4
@@ -0,0 +1,14 @@
+dnl $Id$
+
+AC_DEFUN([RTEMS_ENABLE_NETWORKING],
+[
+## AC_BEFORE([$0], [RTEMS_CHECK_NETWORKING])dnl
+
+AC_ARG_ENABLE(networking,
+AS_HELP_STRING(--enable-networking,enable TCP/IP stack),
+[case "${enableval}" in
+ yes) RTEMS_HAS_NETWORKING=yes ;;
+ no) RTEMS_HAS_NETWORKING=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for enable-networking option) ;;
+esac],[RTEMS_HAS_NETWORKING=yes])
+])
diff --git a/cpukit/aclocal/enable-posix.m4 b/cpukit/aclocal/enable-posix.m4
new file mode 100644
index 0000000000..fe0f314e76
--- /dev/null
+++ b/cpukit/aclocal/enable-posix.m4
@@ -0,0 +1,33 @@
+dnl $Id$
+
+AC_DEFUN([RTEMS_ENABLE_POSIX],
+[
+## AC_BEFORE([$0], [RTEMS_CHECK_POSIX_API])dnl
+
+AC_ARG_ENABLE(posix,
+AS_HELP_STRING(--enable-posix,enable posix interface),
+[case "${enableval}" in
+ yes) RTEMS_HAS_POSIX_API=yes ;;
+ no) RTEMS_HAS_POSIX_API=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for enable-posix option) ;;
+esac],[RTEMS_HAS_POSIX_API=yes])
+
+case "${host}" in
+ # hpux unix port should go here
+ i[[34567]]86-pc-linux*) # unix "simulator" port
+ RTEMS_HAS_POSIX_API=no
+ ;;
+ i[[34567]]86-*freebsd*) # unix "simulator" port
+ RTEMS_HAS_POSIX_API=no
+ ;;
+ no_cpu-*rtems*)
+ RTEMS_HAS_POSIX_API=no
+ ;;
+ sparc-sun-solaris*) # unix "simulator" port
+ RTEMS_HAS_POSIX_API=no
+ ;;
+ *)
+ ;;
+esac
+AC_SUBST(RTEMS_HAS_POSIX_API)
+])
diff --git a/cpukit/aclocal/enable-rtems-debug.m4 b/cpukit/aclocal/enable-rtems-debug.m4
new file mode 100644
index 0000000000..ada9fe30f4
--- /dev/null
+++ b/cpukit/aclocal/enable-rtems-debug.m4
@@ -0,0 +1,12 @@
+## $Id$
+
+AC_DEFUN([RTEMS_ENABLE_RTEMS_DEBUG],
+[
+AC_ARG_ENABLE(rtems-debug,
+AS_HELP_STRING(--enable-rtems-debug,enable RTEMS_DEBUG),
+[case "${enable_rtems_debug}" in
+ yes) enable_rtems_debug=yes ;;
+ no) enable_rtems_debug=no ;;
+ *) AC_MSG_ERROR([bad value ${enable_rtems_debug} for RTEMS_DEBUG]) ;;
+esac],[enable_rtems_debug=no])
+])
diff --git a/cpukit/aclocal/env-rtemscpu.m4 b/cpukit/aclocal/env-rtemscpu.m4
new file mode 100644
index 0000000000..65dea4ef49
--- /dev/null
+++ b/cpukit/aclocal/env-rtemscpu.m4
@@ -0,0 +1,8 @@
+dnl $Id$
+
+AC_DEFUN([RTEMS_ENV_RTEMSCPU],
+[
+ AC_REQUIRE([RTEMS_ENABLE_MULTILIB])
+
+ AM_CONDITIONAL([MULTILIB],[test x"$multilib" = x"yes"])
+])
diff --git a/cpukit/aclocal/gcc-pipe.m4 b/cpukit/aclocal/gcc-pipe.m4
new file mode 100644
index 0000000000..2a04629bb2
--- /dev/null
+++ b/cpukit/aclocal/gcc-pipe.m4
@@ -0,0 +1,21 @@
+dnl
+dnl $Id$
+dnl
+dnl Check whether the target compiler accepts -pipe
+dnl
+
+AC_DEFUN([RTEMS_GCC_PIPE],
+[AC_REQUIRE([RTEMS_PROG_CC])
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_CACHE_CHECK(whether $CC accepts --pipe,rtems_cv_gcc_pipe,
+[
+rtems_cv_gcc_pipe=no
+if test x"$GCC" = x"yes"; then
+ echo 'void f(){}' >conftest.c
+ if test -z "`${CC} --pipe -c conftest.c 2>&1`";then
+ rtems_cv_gcc_pipe=yes
+ fi
+ rm -f conftest*
+fi
+])
+])
diff --git a/cpukit/aclocal/gcc-weak.m4 b/cpukit/aclocal/gcc-weak.m4
new file mode 100644
index 0000000000..73cfb28e7e
--- /dev/null
+++ b/cpukit/aclocal/gcc-weak.m4
@@ -0,0 +1,19 @@
+AC_DEFUN([RTEMS_CHECK_GCC_WEAK],[
+AC_CACHE_CHECK([whether $CC supports function __attribute__((weak))],
+[rtems_cv_cc_attribute_weak],[
+ AS_IF([test x"$GCC" = xyes],[
+ save_CFLAGS=$CFLAGS
+ CFLAGS=-Werror])
+
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM(
+ [void myfunc(char c) __attribute__ ((weak));
+ void myfunc(char c) {}],
+ [])],
+ [rtems_cv_cc_attribute_weak=yes],
+ [rtems_cv_cc_attribute_weak=no])
+
+ AS_IF([test x"$GCC" = xyes],[
+ CFLAGS=$save_CFLAGS])
+])
+])
diff --git a/cpukit/aclocal/multi.m4 b/cpukit/aclocal/multi.m4
new file mode 100644
index 0000000000..d629840d25
--- /dev/null
+++ b/cpukit/aclocal/multi.m4
@@ -0,0 +1,52 @@
+#serial 99
+
+AC_DEFUN([AC_ENABLE_MULTILIB],
+[
+AC_ARG_ENABLE(multilib,
+AS_HELP_STRING(--enable-multilib,build many library versions (default=no)),
+[case "${enableval}" in
+ yes) multilib=yes ;;
+ no) multilib=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for multilib option) ;;
+ esac], [multilib=no])dnl
+
+AM_CONDITIONAL(MULTILIB,test x"${multilib}" = x"yes")
+
+dnl We may get other options which we don't document:
+dnl --with-target-subdir, --with-multisrctop, --with-multisubdir
+
+if test "[$]{srcdir}" = "."; then
+ if test "[$]{with_target_subdir}" != "."; then
+ multilib_basedir="[$]{srcdir}/[$]{with_multisrctop}../ifelse([$2],,,[$2])"
+ else
+ multilib_basedir="[$]{srcdir}/[$]{with_multisrctop}ifelse([$2],,,[$2])"
+ fi
+else
+ multilib_basedir="[$]{srcdir}/ifelse([$2],,,[$2])"
+fi
+AC_SUBST(multilib_basedir)
+
+if test "${multilib}" = "yes"; then
+ multilib_arg="--enable-multilib"
+else
+ multilib_arg=
+fi
+
+AC_OUTPUT_COMMANDS(
+[case " $CONFIG_FILES " in
+ *" ]m4_if([$1],,Makefile,[$1])[ "*)
+ ac_file=]m4_if([$1],,Makefile,[$1])[ . ${multilib_basedir}/config-ml.in
+esac],
+[
+ srcdir=${srcdir}
+ host=${host}
+ target=${target}
+ with_multisrctop="${with_multisrctop}"
+ with_target_subdir="${with_target_subdir}"
+ with_multisubdir="${with_multisubdir}"
+ ac_configure_args="${multilib_arg} ${ac_configure_args}"
+ CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ multilib_basedir=${multilib_basedir}
+ CC="${CC}"]
+)
+])
diff --git a/cpukit/aclocal/multilib.m4 b/cpukit/aclocal/multilib.m4
new file mode 100644
index 0000000000..90e6217780
--- /dev/null
+++ b/cpukit/aclocal/multilib.m4
@@ -0,0 +1,14 @@
+dnl This provides configure definitions used for multilib support
+
+AC_DEFUN([RTEMS_ENABLE_MULTILIB],
+[
+AC_ARG_ENABLE(multilib,
+AS_HELP_STRING(--enable-multilib,build many library versions (default=no)),
+[case "${enableval}" in
+ yes) multilib=yes ;;
+ no) multilib=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for multilib option) ;;
+ esac], [multilib=no])dnl
+
+AM_CONDITIONAL([MULTILIB],[test x"${multilib}" = x"yes"])
+])
diff --git a/cpukit/aclocal/prog-cc.m4 b/cpukit/aclocal/prog-cc.m4
new file mode 100644
index 0000000000..a62dae198e
--- /dev/null
+++ b/cpukit/aclocal/prog-cc.m4
@@ -0,0 +1,36 @@
+dnl
+dnl $Id$
+dnl
+dnl Check for target gcc
+dnl
+
+AC_DEFUN([RTEMS_PROG_CC],
+[
+AC_BEFORE([$0], [AC_PROG_CPP])dnl
+AC_BEFORE([$0], [AC_PROG_CC])dnl
+AC_BEFORE([$0], [RTEMS_CANONICALIZE_TOOLS])dnl
+
+RTEMS_CHECK_TOOL(CC,gcc)
+test -z "$CC" && \
+ AC_MSG_ERROR([no acceptable cc found in \$PATH])
+AC_PROG_CC
+AC_PROG_CPP
+])
+
+AC_DEFUN([RTEMS_PROG_CC_FOR_TARGET],
+[
+dnl check target cc
+RTEMS_PROG_CC
+dnl check if the target compiler may use --pipe
+RTEMS_GCC_PIPE
+test "$rtems_cv_gcc_pipe" = "yes" && CC="$CC --pipe"
+
+if test "$GCC" = yes; then
+RTEMS_CFLAGS="$RTEMS_CFLAGS -Wall"
+m4_if([$1],,[],[RTEMS_CFLAGS="$RTEMS_CFLAGS $1"])
+fi
+AC_SUBST(RTEMS_CFLAGS)
+
+RTEMS_CPPFLAGS="-I\$(PROJECT_INCLUDE)"
+AC_SUBST(RTEMS_CPPFLAGS)
+])
diff --git a/cpukit/aclocal/prog-ccas.m4 b/cpukit/aclocal/prog-ccas.m4
new file mode 100644
index 0000000000..c5b64f561f
--- /dev/null
+++ b/cpukit/aclocal/prog-ccas.m4
@@ -0,0 +1,8 @@
+## $Id$
+
+AC_DEFUN([RTEMS_PROG_CCAS],
+[
+AC_REQUIRE([RTEMS_PROG_CC])
+AC_SUBST(CCAS,["$CC"])
+AC_SUBST(CCASFLAGS,["-DASM \$(CFLAGS) \$(INCLUDES)"])
+])
diff --git a/cpukit/aclocal/prog-gnat.m4 b/cpukit/aclocal/prog-gnat.m4
new file mode 100644
index 0000000000..6e169a8dc7
--- /dev/null
+++ b/cpukit/aclocal/prog-gnat.m4
@@ -0,0 +1,45 @@
+## $Id$
+##
+## Partially borrowed from gcc-3.2
+##
+## WARNING: All the stuff below is pretty immature.
+
+AC_DEFUN([RTEMS_PROG_GNAT],
+[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
+AC_REQUIRE([RTEMS_PROG_CC_FOR_TARGET])
+
+AC_CHECK_TOOL([GNATMAKE],[gnatmake],[])
+AC_CACHE_CHECK([for compiler driver that understands Ada],
+ [rtems_cv_prog_CCADA],
+[cat >conftest.adb <<EOF
+procedure conftest is begin null; end conftest;
+EOF
+rtems_cv_prog_CCADA=
+# Have to do ac_tool_prefix and user overrides by hand.
+user_ccada=$CCADA
+user_cc=$CC
+for cand in ${ac_tool_prefix}$user_ccada $user_ccada \
+ ${ac_tool_prefix}$user_cc $user_cc \
+ ${ac_tool_prefix}gcc gcc \
+ ${ac_tool_prefix}cc cc \
+ ${ac_tool_prefix}gnatgcc gnatgcc \
+ ${ac_tool_prefix}gnatcc gnatcc \
+ ${ac_tool_prefix}adagcc adagcc \
+ ${ac_tool_prefix}adac adac ; do
+ # There is a bug in all released versions of GCC which causes the
+ # driver to exit successfully when the appropriate language module
+ # has not been installed. This is fixed in 2.95.4, 3.0.2, and 3.1.
+ # Therefore we must check for the error message as well as an
+ # unsuccessful exit.
+ errors=`($cand -c conftest.adb) 2>&1 || echo failure`
+ AS_IF([test -z "$errors"],
+ [rtems_cv_prog_CCADA=$cand
+ break])
+done
+rm -f conftest.*])
+AC_SUBST([CCADA],[$rtems_cv_prog_CCADA])
+
+AS_IF([test -n "$GNATMAKE" && test -n "$CCADA"],
+ [HAVE_GNAT=yes],
+ [HAVE_GNAT=no])
+])
diff --git a/cpukit/aclocal/rtems-ampolish.m4 b/cpukit/aclocal/rtems-ampolish.m4
new file mode 100644
index 0000000000..edb8fc4b51
--- /dev/null
+++ b/cpukit/aclocal/rtems-ampolish.m4
@@ -0,0 +1,11 @@
+# $Id$
+
+AC_DEFUN([RTEMS_AMPOLISH3],
+[
+AC_PATH_PROG([PERL],[perl],[])
+AC_SUBST(AMPOLISH3,["\$(PERL) \$(top_srcdir)/${rtems_updir}ampolish3"])
+AM_CONDITIONAL([AMPOLISH3],
+[test x"$USE_MAINTAINER_MODE" = x"yes" \
+ && test -n "${PERL}"])
+])
+
diff --git a/cpukit/aclocal/rtems-top.m4 b/cpukit/aclocal/rtems-top.m4
new file mode 100644
index 0000000000..107d3b79d7
--- /dev/null
+++ b/cpukit/aclocal/rtems-top.m4
@@ -0,0 +1,70 @@
+dnl $Id$
+
+m4_define([RTEMS_API],[4.7])
+
+dnl
+dnl RTEMS_TOP($1)
+dnl
+dnl $1 .. relative path from this configure.ac to the toplevel configure.ac
+dnl
+AC_DEFUN([RTEMS_TOP],
+[dnl
+AC_REQUIRE([RTEMS_VERSIONING])
+AC_REQUIRE([AM_SET_LEADING_DOT])
+AC_CONFIG_AUX_DIR([$1])
+AC_CHECK_PROGS(MAKE, gmake make)
+AC_BEFORE([$0], [AM_INIT_AUTOMAKE])dnl
+
+AC_PREFIX_DEFAULT([/opt/rtems-][RTEMS_API])
+
+AC_SUBST([RTEMS_TOPdir],["$1"])
+
+# HACK: The sed pattern below strips of "../", corresponding to "cpukit/"
+rtems_updir=m4_if([$2],[],[`echo "$1/" | sed 's,^\.\.\/,,'`],[$2/])
+
+AS_IF([test -n "$with_multisubdir"],
+ [MULTIBUILDTOP=`echo "/$with_multisubdir" | sed 's,/[[^\\/]]*,../,g'`])
+AC_SUBST(MULTIBUILDTOP)
+
+AS_IF([test -n "$with_multisubdir"],
+ [MULTISUBDIR="/$with_multisubdir"])
+AC_SUBST(MULTISUBDIR)
+
+AC_ARG_WITH([project-root],[
+AS_HELP_STRING(--with-project-root,directory to pre-install files into)],[
+## Make sure to have a terminating '/'
+case "${with_project_root}" in
+*/) ;;
+*) with_project_root="${with_project_root}/" ;;
+esac
+
+case "${with_project_root}" in
+ [[\\/$]]* | ?:[[\\/]]* ) # absolute directory
+ PROJECT_ROOT=${with_project_root}
+ ;;
+ *) # relative directory
+ sav0dir=`pwd` && cd ./${rtems_updir}
+ sav1dir=`pwd` && cd ../${MULTIBUILDTOP}
+ sav2dir=`pwd` && cd "$sav0dir"
+ mydir=`echo "$sav1dir" | sed "s,^$sav2dir${MULTISUBDIR}/,,"`
+ PROJECT_ROOT='$(top_builddir)'/${rtems_updir}'../$(MULTIBUILDTOP)'${mydir}/${with_project_root}
+ ;;
+esac],[
+## Defaults: Note: Two different defaults!
+## ../ for multilib
+## '.' for non-multilib
+AS_IF([test "$enable_multilib" = "yes"],[
+ PROJECT_ROOT='$(top_builddir)'/${rtems_updir}'../$(MULTIBUILDTOP)'],[
+ PROJECT_ROOT='$(top_builddir)'/${rtems_updir}])
+])
+
+AC_SUBST([PROJECT_INCLUDE],["${PROJECT_ROOT}lib/include"])
+AC_SUBST([PROJECT_LIB],["${PROJECT_ROOT}lib\$(MULTISUBDIR)"])
+
+libdir="${libdir}\$(MULTISUBDIR)"
+
+AC_SUBST([project_libdir],["\$(libdir)"])
+AC_SUBST([project_includedir],["\$(includedir)"])
+
+AC_SUBST([dirstamp],[\${am__leading_dot}dirstamp])
+])dnl
diff --git a/cpukit/aclocal/sysv-ipc.m4 b/cpukit/aclocal/sysv-ipc.m4
new file mode 100644
index 0000000000..0b263b5f4c
--- /dev/null
+++ b/cpukit/aclocal/sysv-ipc.m4
@@ -0,0 +1,125 @@
+dnl
+dnl $Id$
+dnl
+dnl Check for System V IPC calls used by Unix simulators
+dnl
+dnl 98/07/17 Dario Alcocer alcocer@netcom.com
+dnl Ralf Corsepius corsepiu@faw.uni-ulm.de
+dnl
+dnl Note: $host_os should probably *not* ever be used here to
+dnl determine if host supports System V IPC calls, since some
+dnl (e.g. FreeBSD 2.x) are configured by default to include only
+dnl a subset of the System V IPC calls. Therefore, to make sure
+dnl all of the required calls are found, test for each call explicitly.
+dnl
+dnl All of the calls use IPC_PRIVATE, so tests will not unintentionally
+dnl modify any existing key sets. See the man pages for semget, shmget,
+dnl msgget, semctl, shmctl and msgctl for details.
+
+AC_DEFUN([RTEMS_UNION_SEMUN],
+[
+AC_CACHE_CHECK([whether $host defines union semun],
+ rtems_cv_HAS_UNION_SEMUN,
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>]], [[union semun arg ;]])],[rtems_cv_HAS_UNION_SEMUN="yes"],[rtems_cv_HAS_UNION_SEMUN="no"])
+])
+if test "$rtems_cv_HAS_UNION_SEMUN" = "yes"; then
+ AC_DEFINE(HAS_UNION_SEMUN,[1],[if having union semum])
+fi
+])
+
+AC_DEFUN([RTEMS_SYSV_SEM],
+[AC_REQUIRE([AC_PROG_CC])
+AC_CACHE_CHECK(whether $host supports System V semaphores,
+rtems_cv_sysv_sem,
+[
+AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#if !HAS_UNION_SEMUN
+ union semun {
+ int val;
+ struct semid_ds *buf;
+ ushort *array;
+ } ;
+#endif
+int main () {
+ union semun arg ;
+
+ int id=semget(IPC_PRIVATE,1,IPC_CREAT|0400);
+ if (id == -1)
+ exit(1);
+ arg.val = 0; /* avoid implicit type cast to union */
+ if (semctl(id, 0, IPC_RMID, arg) == -1)
+ exit(1);
+ exit(0);
+}
+]])],[rtems_cv_sysv_sem="yes"],[rtems_cv_sysv_sem="no"],[:])
+])
+])
+
+AC_DEFUN([RTEMS_SYSV_SHM],
+[AC_REQUIRE([AC_PROG_CC])
+# AC_REQUIRE([RTEMS_CANONICAL_HOST])
+AC_CACHE_CHECK(whether $host supports System V shared memory,
+rtems_cv_sysv_shm,
+[
+AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+int main () {
+ int id=shmget(IPC_PRIVATE,1,IPC_CREAT|0400);
+ if (id == -1)
+ exit(1);
+ if (shmctl(id, IPC_RMID, 0) == -1)
+ exit(1);
+ exit(0);
+}
+]])],[rtems_cv_sysv_shm="yes"],[rtems_cv_sysv_shm="no"],[:])
+])
+])
+
+AC_DEFUN([RTEMS_SYSV_MSG],
+[AC_REQUIRE([AC_PROG_CC])
+# AC_REQUIRE([RTEMS_CANONICAL_HOST])
+AC_CACHE_CHECK(whether $host supports System V messages,
+rtems_cv_sysv_msg,
+[
+AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+int main () {
+ int id=msgget(IPC_PRIVATE,IPC_CREAT|0400);
+ if (id == -1)
+ exit(1);
+ if (msgctl(id, IPC_RMID, 0) == -1)
+ exit(1);
+ exit(0);
+}
+]])],[rtems_cv_sysv_msg="yes"],[rtems_cv_sysv_msg="no"],[:])
+])
+])
+
+AC_DEFUN([RTEMS_CHECK_SYSV_UNIX],
+[# AC_REQUIRE([RTEMS_CANONICAL_HOST])
+if test "$RTEMS_CPU" = "unix" ; then
+ RTEMS_UNION_SEMUN
+ RTEMS_SYSV_SEM
+ if test "$rtems_cv_sysv_sem" != "yes" ; then
+ AC_MSG_ERROR([System V semaphores don't work, required by simulator])
+ fi
+ RTEMS_SYSV_SHM
+ if test "$rtems_cv_sysv_shm" != "yes" ; then
+ AC_MSG_ERROR([System V shared memory doesn't work, required by simulator])
+ fi
+ RTEMS_SYSV_MSG
+ if test "$rtems_cv_sysv_msg" != "yes" ; then
+ AC_MSG_ERROR([System V messages don't work, required by simulator])
+ fi
+fi
+])
diff --git a/cpukit/aclocal/version.m4 b/cpukit/aclocal/version.m4
new file mode 100644
index 0000000000..0b6bfb1823
--- /dev/null
+++ b/cpukit/aclocal/version.m4
@@ -0,0 +1,2 @@
+AC_DEFUN([RTEMS_VERSIONING],
+m4_define([_RTEMS_VERSION],[4.6.99.3]))
diff --git a/cpukit/ampolish3 b/cpukit/ampolish3
new file mode 100755
index 0000000000..533f9505f1
--- /dev/null
+++ b/cpukit/ampolish3
@@ -0,0 +1,276 @@
+#! /usr/bin/perl -w
+
+# $Id$
+
+# Copyright (C) 2005, 2006 Ralf Corsépius, Ulm, Germany
+#
+# Permission to use, copy, modify, and distribute this software
+# is freely granted, provided that this notice is preserved.
+
+# Helper script to generate pre/tmpinstall rules for RTEMS Makefile.am.
+#
+# Usage: ampolish3 Makefile.am > preinstall.am
+#
+# Reads a Makefile.am from stdin and writes corresponding
+# pre/tmpinstall rules to stdout.
+
+sub replace($);
+sub print_dirstamp($$$);
+
+# Predefined directory mappings:
+#
+# final-installation directory => temp installation directory
+my %dirmap = (
+ '$(includedir)' => '$(PROJECT_INCLUDE)',
+ '$(libdir)' => '$(PROJECT_LIB)',
+ '$(project_libdir)' => '$(PROJECT_LIB)',
+ '$(project_includedir)' => '$(PROJECT_INCLUDE)'
+ );
+
+# Conventions on automake primaries:
+#
+# *_HEADERS -> preinstall
+# noinst*_HEADERS -> noinst
+# noinst_*_LIBRARIES -> noinst
+# project_*_LIBRARIES -> tmpinstall
+# *_LIBRARIES -> ignore (no preinstallation)
+# dist_project_*_DATA -> preinstall (bsp_specs,linkcmds)
+# project_*_DATA -> tmpinstall (*.o, *.a)
+# dist_*_DATA -> ignore (no preinstallation)
+# *SCRIPTS -> ignore (no preinstallation)
+# noinst_*_PROGRAMS -> noinst
+# project_*_PROGRAMS -> tmpinstall
+# *_PROGRAMS -> ignore (no preinstallation)
+
+## 1st pass: read in file
+my @buffer1 = () ;
+my %seen = ();
+my %predefs = ();
+
+{
+ my $mode = 0 ;
+ my $line = '';
+
+ while ( <> )
+ {
+ if ( $mode == 0 )
+ {
+ if ( /^([a-zA-Z0-9_]+\s*[\+]?[:=].*)\\$/o )
+ {
+ $line = "$1" ;
+ $mode = 1;
+ } else {
+ push @buffer1, $_ ;
+ }
+ } elsif ( $mode == 1 ) {
+ if ( /^(.*)\\$/o ) {
+ $line .= $1;
+ } else {
+ $line .= $_ ;
+ push @buffer1, $line ;
+ $line = '';
+ $mode = 0 ;
+ }
+ }
+ }
+}
+
+#foreach my $l ( @buffer1 ) { print STDERR "1:<$l>"; }
+
+# Filter out all Makefile code not relevant here
+my @buffer2 = ();
+foreach my $l ( @buffer1 ) {
+ if ( $l=~ /^\t.*$/o )
+ { #ignore: Production of a make rule.
+ } elsif ( $l =~ /^\s*([a-zA-Z0-9_]*dir)\s*\=\s*(.*)\s*$/o )
+ { # dirs
+ push @buffer2, "$l";
+ $dirmap{"\$\($1\)"} = replace($2);
+ } elsif ( $l =~ /^\s*noinst_(.*)\s*[\+]?\=(.*)$/o )
+ {
+ #ignore: noinst_* are not relevant here.
+ } elsif ( $l =~ /^\s*(nodist_|dist_|)(project_|)([a-zA-Z0-9_]+)_(HEADERS|LIBRARIES|DATA|SCRIPTS|PROGRAMS)\s*([\+]?\=)\s*(.*)/o )
+ {
+ if ( ( "$5" eq '=' ) ) {
+ my $v = $dirmap{"\$\($3dir\)"};
+ if ( $v =~ /\$\(PROJECT_[^\)]+\)$/ )
+ {
+ $predefs{"$v"} = 1;
+ }
+ }
+ foreach my $f ( split(' ',$6) ) {
+ push @buffer2, "$1$2$3_$4 +=$f\n";
+ }
+ } elsif ( $l =~ /^\s*(if|else|endif)\s*.*$/o )
+ { # conditionals
+ push @buffer2, "$l";
+ }
+
+ # Check if Makefile.am already contains CLEANFILES or DISTCLEANFILES
+ if ( $l =~ /^\s*(CLEANFILES|DISTCLEANFILES|SUBDIRS)\s*\=.*$/o )
+ {
+ $predefs{"$1"} = 1;
+ }
+}
+
+if ( $predefs{"\$(PROJECT_INCLUDE)"} ){
+ unshift @buffer2, "includedir = \$(includedir)\n";
+}
+if ( $predefs{"\$(PROJECT_LIB)"} ){
+ unshift @buffer2, "libdir = \$(libdir)\n";
+}
+
+# foreach my $l ( @buffer2 ) { print STDERR "2:<$l>"; }
+
+my @buffer3 = ();
+
+foreach my $l ( @buffer2 ) {
+ if ( $l =~ /^\s*([a-zA-Z0-9_]*dir)\s*\=\s*(.*)\s*$/o )
+ { # dirs
+ my $v = $dirmap{"\$\($1\)"};
+ print_dirstamp(\@buffer3,$v,"PREINSTALL_DIRS");
+ $seen{"PREINSTALL_DIRS"} = 1;
+ } elsif ( $l =~ /^\s*(nodist_|dist_|)(project_|)([a-zA-Z0-9_]+)_HEADERS\s*\+\=(.*)/o )
+ { # preinstall
+ my $v = $dirmap{"\$\($3dir\)"};
+ my $f = $4;
+ my $x ; my $i = rindex($f,'/');
+ if ($i < 0) { $x="$f";
+ } else { $x = substr($f,$i+1);
+ }
+ push @buffer3,
+ "$v/$x: $f $v/\$(dirstamp)\n",
+ "\t\$(INSTALL_DATA) \$< $v/$x\n",
+ "PREINSTALL_FILES += $v/$x\n\n";
+ $seen{"PREINSTALL_FILES"} = 1;
+ } elsif ( $l =~ /^\s*(nodist_|dist_|)(project_)([a-zA-Z0-9_]+)_LIBRARIES\s*\+\=(.*)/o )
+ { # tmpinstall
+ my $v = $dirmap{"\$\($3dir\)"};
+ my $f = $4;
+ my $x ; my $i = rindex($f,'/');
+ if ($i < 0) { $x="$f";
+ } else { $x = substr($f,$i+1);
+ }
+ push @buffer3,
+ "$v/$x: $f $v/\$(dirstamp)\n",
+ "\t\$(INSTALL_DATA) \$< $v/$x\n",
+ "TMPINSTALL_FILES += $v/$x\n\n";
+ $seen{"TMPINSTALL_FILES"} = 1;
+ } elsif ( $l =~ /^\s*(nodist_|dist_|)([a-zA-Z0-9_]+)_LIBRARIES\s*\+\=(.*)/o )
+ { # ignore
+ } elsif ( $l =~ /^\s*(dist_)(project_)([a-zA-Z0-9_]+)_DATA\s*\+\=(.*)/o )
+ { # preinstall
+ my $v = $dirmap{"\$\($3dir\)"};
+ my $f = $4;
+ my $x ; my $i = rindex($f,'/');
+ if ($i < 0) { $x="$f";
+ } else { $x = substr($f,$i+1);
+ }
+ push @buffer3,
+ "$v/$x: $f $v/\$(dirstamp)\n",
+ "\t\$(INSTALL_DATA) \$< $v/$x\n",
+ "PREINSTALL_FILES += $v/$x\n\n";
+ $seen{"PREINSTALL_FILES"} = 1;
+ } elsif ( $l =~ /^\s*(nodist_|)(project_)([a-zA-Z0-9_]+)_DATA\s*\+\=(.*)/o )
+ { # tmpinstall
+ my $v = $dirmap{"\$\($3dir\)"};
+ my $f = $4;
+ my $x ; my $i = rindex($f,'/');
+ if ($i < 0) { $x="$f";
+ } else { $x = substr($f,$i+1);
+ }
+ push @buffer3,
+ "$v/$x: $f $v/\$(dirstamp)\n",
+ "\t\$(INSTALL_DATA) \$< $v/$x\n",
+ "TMPINSTALL_FILES += $v/$x\n\n";
+ $seen{"TMPINSTALL_FILES"} = 1;
+ } elsif ( $l =~ /^\s*(dist_|)([a-zA-Z0-9_]+)_DATA\s*\+\=(.*)/o )
+ { # ignore
+ } elsif ( $l =~ /^\s*(nodist_|dist_|)([a-zA-Z0-9_]+)_SCRIPTS\s*\+\=(.*)/o )
+ { # ignore
+ } elsif ( $l =~ /^\s*(nodist_|dist_|)(project_)([a-zA-Z0-9_]+)_PROGRAMS\s*\+\=(.*)/o )
+ { # tmpinstall
+ my $v = $dirmap{"\$\($3dir\)"};
+
+ my $f = $4;
+ my $x ; my $i = rindex($f,'/');
+ if ($i < 0) { $x="$f";
+ } else { $x = substr($f,$i+1);
+ }
+ push @buffer3,
+ "$v/$x: $f $v/\$(dirstamp)\n",
+ "\t\$(INSTALL_PROGRAM) \$< $v/$x\n",
+ "TMPINSTALL_FILES += $v/$x\n\n";
+ $seen{"TMPINSTALL_FILES"} = 1;
+ } elsif ( $l =~ /^\s*(nodist_|dist_|)([a-zA-Z0-9_]+)_PROGRAMS\s*\+\=(.*)/o )
+ { # ignore
+ } elsif ( $l =~ /^\s*(if|else|endif)\s*.*$/o )
+ { # conditionals
+ push @buffer3, "$l";
+ }
+}
+
+# foreach my $l ( @buffer3 ) { print STDERR "3:<$l>"; }
+
+my $output;
+$output .= "## Automatically generated by ampolish3 - Do not edit\n\n";
+$output .= "if AMPOLISH3\n";
+$output .= "\$(srcdir)/preinstall.am: Makefile.am\n";
+$output .= "\t\$(AMPOLISH3) \$(srcdir)/Makefile.am > \$(srcdir)/preinstall.am\n";
+$output .= "endif\n\n";
+
+foreach my $k ( keys %seen )
+{
+ if ( $k =~ /PREINSTALL_FILES/o ) {
+ $output .= "all-am: \$(PREINSTALL_FILES)\n\n";
+
+ $output .= "$k =\n";
+ $output .= "CLEANFILES ";
+ if ( $predefs{"CLEANFILES"} ) { $output .= "+"; }
+ $output .= "= \$($k)\n";
+ $predefs{"CLEANFILES"} = 1;
+ } elsif ( $k =~ /TMPINSTALL_FILES/o ) {
+
+ $output .= "all-local: \$(TMPINSTALL_FILES)\n\n";
+
+ $output .= "$k =\n";
+ $output .= "CLEANFILES ";
+ if ( $predefs{"CLEANFILES"} ) { $output .= "+"; }
+ $output .= "= \$($k)\n";
+ $predefs{"CLEANFILES"} = 1;
+ } elsif ( $k =~ /.*DIRS/o ) {
+ $output .= "$k =\n";
+ $output .= "DISTCLEANFILES ";
+ if ( $predefs{"DISTCLEANFILES"} ) { $output .= "+"; }
+ $output .= "= \$($k)\n";
+ $predefs{"DISTCLEANFILES"} = 1;
+ }
+ $output .= "\n";
+}
+
+# Pretty printing
+$output .= join ( '', @buffer3 );
+$output =~ s/\nelse\n+endif/\nendif/g;
+$output =~ s/\n\n+endif/\nendif/g;
+$output =~ s/\nif [a-zA-Z0-9_!]+\n+endif//g;
+print STDOUT $output;
+
+exit 0;
+
+sub replace($)
+{
+ my ($v) = @_;
+ foreach my $i ( keys %dirmap )
+ {
+ $v =~ s/\Q$i/$dirmap{$i}/g;
+ }
+ return $v;
+}
+
+sub print_dirstamp($$$)
+{
+ my ($obuf,$file,$inst) = @_ ;
+ push @{$obuf}, "$file/\$(dirstamp):\n\t\@\$\(mkdir_p\) $file\n" ;
+ push @{$obuf}, "\t\@: \> $file/\$(dirstamp)\n" ;
+ push @{$obuf}, "$inst += $file/\$(dirstamp)\n\n" ;
+}
diff --git a/cpukit/automake/compile.am b/cpukit/automake/compile.am
new file mode 100644
index 0000000000..0d0f579674
--- /dev/null
+++ b/cpukit/automake/compile.am
@@ -0,0 +1,7 @@
+##
+## $Id$
+##
+
+AM_CPPFLAGS = -I$(top_builddir) -I$(PROJECT_INCLUDE)
+AM_CFLAGS = $(RTEMS_CFLAGS)
+AM_CCASFLAGS = -I$(top_builddir) -I$(PROJECT_INCLUDE) $(RTEMS_ASFLAGS)
diff --git a/cpukit/automake/local.am b/cpukit/automake/local.am
new file mode 100644
index 0000000000..68160311b5
--- /dev/null
+++ b/cpukit/automake/local.am
@@ -0,0 +1,5 @@
+## $Id$
+
+preinstall-am: $(PREINSTALL_FILES)
+preinstall: preinstall-am
+.PHONY: preinstall preinstall-am
diff --git a/cpukit/automake/multilib.am b/cpukit/automake/multilib.am
new file mode 100644
index 0000000000..9f2024f8d9
--- /dev/null
+++ b/cpukit/automake/multilib.am
@@ -0,0 +1,36 @@
+## $Id$
+
+if MULTILIB
+MULTISRCTOP =
+MULTIDIRS =
+MULTIDO = true
+MULTICLEAN = true
+endif
+
+# Multilib support rules
+.PHONY: all-multi install-multi mostlyclean-multi clean-multi distclean-multi \
+ maintainer-clean-multi
+
+if MULTILIB
+all-recursive: all-multi
+install-recursive: install-multi
+
+mostlyclean-recursive: mostlyclean-multi
+clean-recursive: clean-multi
+distclean-recursive: distclean-multi
+maintainer-clean-recursive: maintainer-clean-multi
+
+all-multi:
+ $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do
+install-multi:
+ $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do
+
+mostlyclean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean
+clean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean
+distclean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean
+maintainer-clean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean
+endif
diff --git a/cpukit/automake/subdirs.am b/cpukit/automake/subdirs.am
new file mode 100644
index 0000000000..00eba7cd1d
--- /dev/null
+++ b/cpukit/automake/subdirs.am
@@ -0,0 +1,32 @@
+## $Id$
+
+## Borrowed from automake-1.4 and adapted to RTEMS
+
+## NOTE: This is a temporary work-around to keep
+## RTEMS's non automake standard make targets working.
+## Once automake is fully integrated these make targets
+## and this file will probably be removed
+
+preinstall-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+## This trick allows "-k" to keep its natural meaning when running a
+## recursive rule.
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+preinstall: preinstall-recursive
+.PHONY: preinstall-recursive
diff --git a/cpukit/backward/asm.h b/cpukit/backward/asm.h
new file mode 100644
index 0000000000..722e70f7d5
--- /dev/null
+++ b/cpukit/backward/asm.h
@@ -0,0 +1,12 @@
+/**
+ * @file asm.h
+ * @deprecated
+ */
+
+#ifndef _ASM_H
+#define _ASM_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <asm.h> is deprecated, use <rtems/asm.h> instead
+#endif
+#include <rtems/asm.h>
+#endif
diff --git a/cpukit/backward/chain.h b/cpukit/backward/chain.h
new file mode 100644
index 0000000000..866a16d4aa
--- /dev/null
+++ b/cpukit/backward/chain.h
@@ -0,0 +1,12 @@
+/**
+ * @file chain.h
+ * @deprecated
+ */
+
+#ifndef _CHAIN_H
+#define _CHAIN_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <chain.h> is deprecated, use <rtems/chain.h> instead
+#endif
+#include <rtems/chain.h>
+#endif
diff --git a/cpukit/backward/clockdrv.h b/cpukit/backward/clockdrv.h
new file mode 100644
index 0000000000..1f25e30a30
--- /dev/null
+++ b/cpukit/backward/clockdrv.h
@@ -0,0 +1,12 @@
+/**
+ * @file clockdrv.h
+ * @deprecated
+ */
+
+#ifndef _CLOCKDRV_H
+#define _CLOCKDRV_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <clockdrv.h> is deprecated, use <rtems/clockdrv.h> instead
+#endif
+#include <rtems/clockdrv.h>
+#endif
diff --git a/cpukit/backward/confdefs.h b/cpukit/backward/confdefs.h
new file mode 100644
index 0000000000..9d15a2a197
--- /dev/null
+++ b/cpukit/backward/confdefs.h
@@ -0,0 +1,12 @@
+/**
+ * @file confdefs.h
+ * @deprecated
+ */
+
+#ifndef _CONFDEFS_H
+#define _CONFDEFS_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <confdefs.h> is deprecated, use <rtems/confdefs.h> instead
+#endif
+#include <rtems/confdefs.h>
+#endif
diff --git a/cpukit/backward/console.h b/cpukit/backward/console.h
new file mode 100644
index 0000000000..f43aeb0f49
--- /dev/null
+++ b/cpukit/backward/console.h
@@ -0,0 +1,12 @@
+/**
+ * @file console.h
+ * @deprecated
+ */
+
+#ifndef _CONSOLE_H
+#define _CONSOLE_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <console.h> is deprecated, use <rtems/console.h> instead
+#endif
+#include <rtems/console.h>
+#endif
diff --git a/cpukit/backward/dosfs.h b/cpukit/backward/dosfs.h
new file mode 100644
index 0000000000..1d0f60a664
--- /dev/null
+++ b/cpukit/backward/dosfs.h
@@ -0,0 +1,12 @@
+/**
+ * @file dosfs.h
+ * @deprecated
+ */
+
+#ifndef _DOSFS_H
+#define _DOSFS_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <dosfs.h> is deprecated, use <rtems/dosfs.h> instead
+#endif
+#include <rtems/dosfs.h>
+#endif
diff --git a/cpukit/backward/ftpd.h b/cpukit/backward/ftpd.h
new file mode 100644
index 0000000000..8fcf9a7767
--- /dev/null
+++ b/cpukit/backward/ftpd.h
@@ -0,0 +1,12 @@
+/**
+ * @file ftpd.h
+ * @deprecated
+ */
+
+#ifndef _FTPD_H
+#define _FTPD_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <ftpd.h> is deprecated, use <rtems/ftpd.h> instead
+#endif
+#include <rtems/ftpd.h>
+#endif
diff --git a/cpukit/backward/imfs.h b/cpukit/backward/imfs.h
new file mode 100644
index 0000000000..d8b5b2aece
--- /dev/null
+++ b/cpukit/backward/imfs.h
@@ -0,0 +1,12 @@
+/**
+ * @file imfs.h
+ * @deprecated
+ */
+
+#ifndef _IMFS_H
+#define _IMFS_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <imfs.h> is deprecated, use <rtems/imfs.h> instead
+#endif
+#include <rtems/imfs.h>
+#endif
diff --git a/cpukit/backward/iosupp.h b/cpukit/backward/iosupp.h
new file mode 100644
index 0000000000..4356a88bff
--- /dev/null
+++ b/cpukit/backward/iosupp.h
@@ -0,0 +1,12 @@
+/**
+ * @file iosupp.h
+ * @deprecated
+ */
+
+#ifndef _IOSUPP_H
+#define _IOSUPP_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <iosupp.h> is deprecated, use <rtems/iosupp.h> instead
+#endif
+#include <rtems/iosupp.h>
+#endif
diff --git a/cpukit/backward/itron.h b/cpukit/backward/itron.h
new file mode 100644
index 0000000000..119f3f5390
--- /dev/null
+++ b/cpukit/backward/itron.h
@@ -0,0 +1,12 @@
+/**
+ * @file itron.h
+ * @deprecated
+ */
+
+#ifndef _ITRON_H
+#define _ITRON_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <itron.h> is deprecated, use <rtems/itron.h> instead
+#endif
+#include <rtems/itron.h>
+#endif
diff --git a/cpukit/backward/motorola/mc68230.h b/cpukit/backward/motorola/mc68230.h
new file mode 100644
index 0000000000..50846f9cf2
--- /dev/null
+++ b/cpukit/backward/motorola/mc68230.h
@@ -0,0 +1,12 @@
+/**
+ * @file motorola/mc68230.h
+ * @deprecated
+ */
+
+#ifndef _MOTOROLA_MC68230_H
+#define _MOTOROLA_MC68230_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <motorola/mc68230.h> is deprecated, use <rtems/motorola/mc68230.h> instead
+#endif
+#include <rtems/motorola/mc68230.h>
+#endif
diff --git a/cpukit/backward/motorola/mc68681.h b/cpukit/backward/motorola/mc68681.h
new file mode 100644
index 0000000000..44560ad85d
--- /dev/null
+++ b/cpukit/backward/motorola/mc68681.h
@@ -0,0 +1,12 @@
+/**
+ * @file motorola/mc68681.h
+ * @deprecated
+ */
+
+#ifndef _MOTOROLA_MC68681_H
+#define _MOTOROLA_MC68681_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <motorola/mc68681.h> is deprecated, use <rtems/motorola/mc68681.h> instead
+#endif
+#include <rtems/motorola/mc68681.h>
+#endif
diff --git a/cpukit/backward/ringbuf.h b/cpukit/backward/ringbuf.h
new file mode 100644
index 0000000000..c80d73b6ee
--- /dev/null
+++ b/cpukit/backward/ringbuf.h
@@ -0,0 +1,12 @@
+/**
+ * @file ringbuf.h
+ * @deprecated
+ */
+
+#ifndef _RINGBUF_H
+#define _RINGBUF_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <ringbuf.h> is deprecated, use <rtems/ringbuf.h> instead
+#endif
+#include <rtems/ringbuf.h>
+#endif
diff --git a/cpukit/backward/rtc.h b/cpukit/backward/rtc.h
new file mode 100644
index 0000000000..6cdaf7c05b
--- /dev/null
+++ b/cpukit/backward/rtc.h
@@ -0,0 +1,12 @@
+/**
+ * @file rtc.h
+ * @deprecated
+ */
+
+#ifndef _RTC_H
+#define _RTC_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <rtc.h> is deprecated, use <rtems/rtc.h> instead
+#endif
+#include <rtems/rtc.h>
+#endif
diff --git a/cpukit/backward/rtemsdialer.h b/cpukit/backward/rtemsdialer.h
new file mode 100644
index 0000000000..2f9ef17d30
--- /dev/null
+++ b/cpukit/backward/rtemsdialer.h
@@ -0,0 +1,12 @@
+/**
+ * @file rtemsdialer.h
+ * @deprecated
+ */
+
+#ifndef _RTEMSDIALER_H
+#define _RTEMSDIALER_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <rtemsdialer.h> is deprecated, use <rtems/dialer.h> instead
+#endif
+#include <rtems/dialer.h>
+#endif
diff --git a/cpukit/backward/rtemspppd.h b/cpukit/backward/rtemspppd.h
new file mode 100644
index 0000000000..beb7b47a45
--- /dev/null
+++ b/cpukit/backward/rtemspppd.h
@@ -0,0 +1,12 @@
+/**
+ * @file rtemspppd.h
+ * @deprecated
+ */
+
+#ifndef _RTEMSPPPD_H
+#define _RTEMSPPPD_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <rtemspppd.h> is deprecated, use <rtems/pppd.h> instead
+#endif
+#include <rtems/pppd.h>
+#endif
diff --git a/cpukit/backward/spurious.h b/cpukit/backward/spurious.h
new file mode 100644
index 0000000000..df64309dd5
--- /dev/null
+++ b/cpukit/backward/spurious.h
@@ -0,0 +1,12 @@
+/**
+ * @file spurious.h
+ * @deprecated
+ */
+
+#ifndef _SPURIOUS_H
+#define _SPURIOUS_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <spurious.h> is deprecated, use <rtems/spurious.h> instead
+#endif
+#include <rtems/spurious.h>
+#endif
diff --git a/cpukit/backward/timerdrv.h b/cpukit/backward/timerdrv.h
new file mode 100644
index 0000000000..e4e2ad4603
--- /dev/null
+++ b/cpukit/backward/timerdrv.h
@@ -0,0 +1,12 @@
+/**
+ * @file timerdrv.h
+ * @deprecated
+ */
+
+#ifndef _TIMERDRV_H
+#define _TIMERDRV_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <timerdrv.h> is deprecated, use <rtems/timerdrv.h> instead
+#endif
+#include <rtems/timerdrv.h>
+#endif
diff --git a/cpukit/backward/vmeintr.h b/cpukit/backward/vmeintr.h
new file mode 100644
index 0000000000..db5c8e9f9e
--- /dev/null
+++ b/cpukit/backward/vmeintr.h
@@ -0,0 +1,12 @@
+/**
+ * @file vmeintr.h
+ * @deprecated
+ */
+
+#ifndef _VMEINTR_H
+#define _VMEINTR_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <vmeintr.h> is deprecated, use <rtems/vmeintr.h> instead
+#endif
+#include <rtems/vmeintr.h>
+#endif
diff --git a/cpukit/backward/zilog/z8030.h b/cpukit/backward/zilog/z8030.h
new file mode 100644
index 0000000000..e9ebd4b617
--- /dev/null
+++ b/cpukit/backward/zilog/z8030.h
@@ -0,0 +1,12 @@
+/**
+ * @file zilog/z8030.h
+ * @deprecated
+ */
+
+#ifndef _ZILOG_Z8030_H
+#define _ZILOG_Z8030_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <zilog/z8030.h> is deprecated, use <rtems/zilog/z8030.h> instead
+#endif
+#include <rtems/zilog/z8030.h>
+#endif
diff --git a/cpukit/backward/zilog/z8036.h b/cpukit/backward/zilog/z8036.h
new file mode 100644
index 0000000000..f035de42fc
--- /dev/null
+++ b/cpukit/backward/zilog/z8036.h
@@ -0,0 +1,12 @@
+/**
+ * @file zilog/z8036.h
+ * @deprecated
+ */
+
+#ifndef _ZILOG_Z8036_H
+#define _ZILOG_Z8036_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <zilog/z8036.h> is deprecated, use <rtems/zilog/z8036.h> instead
+#endif
+#include <rtems/zilog/z8036.h>
+#endif
diff --git a/cpukit/backward/zilog/z8536.h b/cpukit/backward/zilog/z8536.h
new file mode 100644
index 0000000000..e5aa408ecc
--- /dev/null
+++ b/cpukit/backward/zilog/z8536.h
@@ -0,0 +1,12 @@
+/**
+ * @file zilog/z8536.h
+ * @deprecated
+ */
+
+#ifndef _ZILOG_Z8536_H
+#define _ZILOG_Z8536_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <zilog/z8536.h> is deprecated, use <rtems/zilog/z8536.h> instead
+#endif
+#include <rtems/zilog/z8536.h>
+#endif
diff --git a/cpukit/configure.ac b/cpukit/configure.ac
new file mode 100644
index 0000000000..c80bbf5263
--- /dev/null
+++ b/cpukit/configure.ac
@@ -0,0 +1,323 @@
+## Process this file with autoconf to produce a configure script.
+##
+## $Id$
+
+AC_PREREQ(2.59)
+AC_INIT([rtems-cpukit],[_RTEMS_VERSION],[rtems-bugs@rtems.com])
+AC_CONFIG_SRCDIR([score])
+RTEMS_TOP([..],[])
+
+RTEMS_CANONICAL_TARGET_CPU
+
+AM_INIT_AUTOMAKE([no-define nostdinc subdir-objects foreign 1.9])
+AM_MAINTAINER_MODE
+
+RTEMS_ENABLE_MULTILIB
+RTEMS_ENABLE_MULTIPROCESSING
+RTEMS_ENABLE_POSIX
+RTEMS_ENABLE_ITRON
+RTEMS_ENABLE_INLINES
+RTEMS_ENABLE_RTEMS_DEBUG
+RTEMS_ENABLE_NETWORKING
+
+RTEMS_ENV_RTEMSCPU
+RTEMS_CHECK_RTEMS_DEBUG
+
+# Is this a supported CPU?
+AC_MSG_CHECKING([if cpu $RTEMS_CPU is supported])
+if test -d "$srcdir/score/cpu/$RTEMS_CPU"; then
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_ERROR(no)
+fi
+
+RTEMS_PROG_CC_FOR_TARGET([-fasm])
+RTEMS_PROG_CCAS
+RTEMS_CANONICALIZE_TOOLS
+AM_PROG_CC_C_O
+AC_PROG_RANLIB
+
+RTEMS_CHECK_NEWLIB
+
+RTEMS_CHECK_MULTIPROCESSING
+RTEMS_CHECK_POSIX_API
+RTEMS_CHECK_ITRON_API
+RTEMS_CHECK_NETWORKING
+
+AS_IF([test x"$HAS_NETWORKING" = x"yes"],[
+## FIXME: Should better use a feature-based test
+AC_MSG_CHECKING([whether CPU supports librpc])
+ case "$RTEMS_CPU" in
+ c4x ) LIBRPC=no;;
+ * ) LIBRPC=yes;;
+ esac
+AC_MSG_RESULT([$LIBRPC])
+])
+
+AC_ARG_ENABLE([deprecated],
+[AS_HELP_STRING(--enable-deprecated,allow using deprecated files)],
+[case "${enable_deprecated}" in
+ yes) ;;
+ no) ;;
+ *) enable_deprecated=no ;;
+esac],[enable_deprecated=no])
+AM_CONDITIONAL([DEPRECATED],[test "$enable_deprecated" = "yes"])
+
+AS_IF([ test "$enable_deprecated" = "yes" ],[
+AC_DEFINE_UNQUOTED([RTEMS_DEPRECATED_TYPES],[1],
+ [whether to support deprecated types])
+])
+
+# HACK: We should use a feature-based configuration.
+AS_IF([test x"${RTEMS_CPU}" = x"unix"],[
+# HACK: silently accept --enable-unixlib
+ test -n "${enable_unixlib}" || enable_unixlib="yes"
+])
+
+# BSD-isms, used throughout the sources
+# Not really used by this configure script
+# FIXME: They should be eliminated if possible.
+AC_CHECK_FUNCS([strsep strcasecmp snprintf])
+AC_CHECK_FUNCS([bcopy bcmp])
+AC_CHECK_FUNCS([isascii fileno])
+
+## Check if the installed toolchain has these headers
+AC_CHECK_HEADER([stdint.h])
+AC_CHECK_HEADER([inttypes.h])
+AC_CHECK_HEADER([tar.h])
+
+## BSD-ism, should not be used in RTEMS,
+## nevertheless it still is.
+AC_CHECK_HEADER([sys/errno.h],[],
+ [AC_MSG_ERROR([Missing required header sys/errno.h])])
+
+## if using newlib, we provide stdint.h and inttypes.h
+AM_CONDITIONAL([RTEMS_PROVIDES_STDINT_H],
+ [test x"${RTEMS_USE_NEWLIB}" = xyes \
+ && test x"${ac_cv_header_stdint_h}" = xno])
+AM_CONDITIONAL([RTEMS_PROVIDES_INTTYPES_H],
+ [test x"${RTEMS_USE_NEWLIB}" = xyes \
+ && test x"${ac_cv_header_inttypes_h}" = xno])
+
+## if using newlib, force using stdint.h
+AS_IF([test x"${RTEMS_USE_NEWLIB}" = xyes],
+[RTEMS_USES_STDINT_H=yes],
+[RTEMS_USES_STDINT_H=$ac_cv_header_stdint_h])
+
+AS_IF([test x"${RTEMS_USE_NEWLIB}" = xyes],
+[RTEMS_USES_TAR_H=yes],
+[RTEMS_USES_TAR_H=$ac_cv_header_tar_h])
+
+AS_IF([test x"${RTEMS_CPU}" = x"unix"],[
+## FIXME: This check is doubtful
+AS_IF([test "$HAS_MP" = "yes"],
+ [RTEMS_CHECK_SYSV_UNIX])
+
+## The code fragment below had been used in tools/cpu/unix/gensize.c.
+## FIXME:
+## * The pad very likely is not necessary.
+AC_CHECK_SIZEOF([CPU_CONTEXT],[],[
+#include <stdio.h>
+#include <setjmp.h>
+
+typedef struct {
+ jmp_buf regs;
+ int isr_level;
+ int pad[4]; /* just in case */
+} CPU_CONTEXT;
+])
+])
+
+cat >>cpuopts.tmp <<\_ACEOF
+/**
+ * @file rtems/score/cpuopts.h
+ */
+/* target cpu dependent options file */
+/* automatically generated -- DO NOT EDIT!! */
+#ifndef _RTEMS_SCORE_CPUOPTS_H
+#define _RTEMS_SCORE_CPUOPTS_H
+_ACEOF
+
+RTEMS_CPUOPT([RTEMS_DEBUG],
+ [test x"${enable_rtems_debug}" = x"yes"],
+ [1],
+ [if RTEMS_DEBUG is enabled])
+
+RTEMS_CPUOPT([RTEMS_INLINES],
+ [test x"${enable_rtems_inlines}" = x"yes"],
+ [1],
+ [if using inlines])
+
+RTEMS_CPUOPT([RTEMS_ITRON_API],
+ [test x"$rtems_cv_HAS_ITRON_API" = x"yes"],
+ [1],
+ [if itron api is supported])
+
+RTEMS_CPUOPT([RTEMS_MULTIPROCESSING],
+ [test x"$enable_multiprocessing" = xyes],
+ [1],
+ [if multiprocessing is enabled])
+
+RTEMS_CPUOPT([RTEMS_NEWLIB],
+ [test x"$RTEMS_USE_NEWLIB" = xyes],
+ [1],
+ [if using newlib])
+
+RTEMS_CPUOPT([RTEMS_POSIX_API],
+ [test x"$rtems_cv_HAS_POSIX_API" = xyes],
+ [1],
+ [if posix api is supported])
+
+RTEMS_CPUOPT([RTEMS_NETWORKING],
+ [test x"$rtems_cv_HAS_NETWORKING" = xyes],
+ [1],
+ [if networking is enabled])
+
+RTEMS_CPUOPT([RTEMS_UNIX],
+ [test x"$RTEMS_CPU" = xunix],
+ [1],
+ [to indicate RTEMS unix])
+
+RTEMS_CPUOPT([RTEMS_UNIXLIB],
+ [test x"${enable_unixlib}" = xyes],
+ [1],
+ [to indicate RTEMS using RTEMS's unixlib])
+
+RTEMS_CPUOPT([RTEMS_USES_STDINT_H],
+ [test x"${RTEMS_USES_STDINT_H}" = x"yes"],
+ [1],
+ [if RTEMS uses stdint.h])
+
+RTEMS_CPUOPT([RTEMS_USES_TAR_H],
+ [test x"${RTEMS_USES_TAR_H}" = x"yes"],
+ [1],
+ [if RTEMS uses tar.h])
+
+RTEMS_CPUOPT([RTEMS_VERSION],
+ [true],
+ ["]_RTEMS_VERSION["],
+ [RTEMS version string])
+
+RTEMS_CPUOPT([SIZEOF_CPU_CONTEXT],
+ [test x"$RTEMS_CPU" = x"unix"],
+ [$ac_cv_sizeof_CPU_CONTEXT],
+ [The size of a 'CPU_CONTEXT', as computed by sizeof])
+
+cat >>cpuopts.tmp <<\_ACEOF
+
+#endif /* _RTEMS_SCORE_CPUOPTS_H */
+_ACEOF
+
+AS_MKDIR_P(score/include/rtems/score)
+AS_IF([test -f score/include/rtems/score/cpuopts.h],
+[
+ AS_IF([cmp -s score/include/rtems/score/cpuopts.h cpuopts.tmp 2>/dev/null],
+ [
+ AC_MSG_NOTICE([score/include/rtems/score/cpuopts.h is unchanged])
+ rm -f cpuopts.tmp
+ ],[
+ AC_MSG_NOTICE([creating score/include/rtems/score/cpuopts.h])
+ rm -f score/include/rtems/score/cpuopts.h
+ mv cpuopts.tmp score/include/rtems/score/cpuopts.h
+ ])
+],[
+ AC_MSG_NOTICE([creating score/include/rtems/score/cpuopts.h])
+ rm -f score/include/rtems/score/cpuopts.h
+ mv cpuopts.tmp score/include/rtems/score/cpuopts.h
+])
+
+AC_ENABLE_MULTILIB([Makefile],[..])
+
+# libmisc/shell/* wants to assign file descriptors to stdio file descriptors.
+AC_MSG_CHECKING([for assignable stdio])
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include <stdio.h>],
+ [stdin = fopen("/tmp", "r")])],
+ [HAVE_ASSIGNABLE_STDIO=yes],
+ [HAVE_ASSIGNABLE_STDIO=no])
+AC_MSG_RESULT([$HAVE_ASSIGNABLE_STDIO])
+
+# libmisc/serdbg exploits weak symbols
+RTEMS_CHECK_GCC_WEAK
+
+AC_CHECK_HEADERS([sys/cdefs.h],[NEED_SYS_CDEFS_H=no],[NEED_SYS_CDEFS_H=yes])
+AC_CHECK_HEADERS([sys/queue.h],[NEED_SYS_QUEUE_H=no],[NEED_SYS_QUEUE_H=yes])
+
+# FIXME: These checks are only in here to provide
+# configuration-time diagnostics and are not really used.
+AC_CHECK_DECLS([_POSIX_LOGIN_NAME_MAX],,,[#include <limits.h>])
+AC_CHECK_DECLS([CHAR_BIT],,,[#include <limits.h>])
+
+## BSD-ism, excluded from POSIX, but available on most platforms
+AC_CHECK_DECLS([sbrk],,,[#include <unistd.h>])
+
+## Check if libc provides BSD's strlcpy/strlcat
+AC_CHECK_FUNCS(strlcpy strlcat)
+
+
+# ... far too many conditionals ...
+AM_CONDITIONAL(LIBRPC,[test "$LIBRPC" = "yes"])
+AM_CONDITIONAL(UNIX,[test x"${RTEMS_CPU}" = x"unix"])
+AM_CONDITIONAL(NEWLIB,test x"$RTEMS_USE_NEWLIB" = x"yes")
+
+AM_CONDITIONAL(INLINE,test x"$enable_rtems_inlines" = x"yes" )
+AM_CONDITIONAL(MACROS,test x"$enable_rtems_inlines" = x"no" )
+AM_CONDITIONAL(HAS_MP,test x"$enable_multiprocessing" = x"yes" )
+
+AM_CONDITIONAL(HAS_POSIX,test x"$rtems_cv_HAS_POSIX_API" = x"yes")
+AM_CONDITIONAL(HAS_ITRON,test x"$rtems_cv_HAS_ITRON_API" = x"yes")
+AM_CONDITIONAL(HAS_NETWORKING,test x"$HAS_NETWORKING" = x"yes")
+
+AM_CONDITIONAL([NEED_SYS_CDEFS_H],[test x"$NEED_SYS_CDEFS_H" = x"yes"])
+AM_CONDITIONAL([NEED_SYS_QUEUE_H],[test x"$NEED_SYS_QUEUE_H" = x"yes"])
+
+AM_CONDITIONAL([LIBSHELL],[test x"$HAVE_ASSIGNABLE_STDIO" = x"yes"])
+AM_CONDITIONAL([LIBSERDBG],[test x"$rtems_cv_cc_attribute_weak" = x"yes"])
+
+RTEMS_AMPOLISH3
+
+AC_CONFIG_HEADER(config.h)
+
+# Explicitly list all Makefiles here
+AC_CONFIG_FILES([
+Makefile
+rtems/Makefile
+sapi/Makefile
+score/Makefile
+score/cpu/Makefile
+score/cpu/arm/Makefile
+score/cpu/avr/Makefile
+score/cpu/c4x/Makefile
+score/cpu/h8300/Makefile
+score/cpu/i386/Makefile
+score/cpu/m68k/Makefile
+score/cpu/mips/Makefile
+score/cpu/nios2/Makefile
+score/cpu/powerpc/Makefile
+score/cpu/sh/Makefile
+score/cpu/sparc/Makefile
+score/cpu/unix/Makefile
+score/cpu/no_cpu/Makefile
+posix/Makefile
+itron/Makefile
+libblock/Makefile
+libfs/Makefile
+libcsupport/Makefile
+libnetworking/Makefile
+librpc/Makefile
+libmisc/Makefile
+libi2c/Makefile
+zlib/Makefile
+httpd/Makefile
+ftpd/Makefile
+telnetd/Makefile
+pppd/Makefile
+wrapup/Makefile])
+
+AC_CONFIG_COMMANDS([preinstall-stamp],
+[test -z "$with_multisubdir" && ${MAKE} preinstall-stamp],
+[MAKE=${MAKE}
+with_multisubdir="$with_multisubdir"])
+
+AC_OUTPUT
diff --git a/cpukit/ftpd/.cvsignore b/cpukit/ftpd/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/ftpd/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/ftpd/Makefile.am b/cpukit/ftpd/Makefile.am
new file mode 100644
index 0000000000..73f588ae29
--- /dev/null
+++ b/cpukit/ftpd/Makefile.am
@@ -0,0 +1,13 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+if HAS_NETWORKING
+project_lib_LIBRARIES = libftpd.a
+libftpd_a_SOURCES = ftpd.c ftpd.h
+endif
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/ftpd/ftpd.c b/cpukit/ftpd/ftpd.c
new file mode 100644
index 0000000000..c4562dbf45
--- /dev/null
+++ b/cpukit/ftpd/ftpd.c
@@ -0,0 +1,2062 @@
+/* FIXME: 1. Parse command is a hack. We can do better.
+ * 2. Some sort of access control?
+ * 3. OSV: hooks support seems to be bad, as it requires storing of
+ * entire input file in memory. Seem to be better to change it to
+ * something more reasonable, like having
+ * 'hook_write(void const *buf, int count)' routine that will be
+ * called multiple times while file is being received.
+ * 4. OSV: Remove hack with "/dev/null"?
+ *
+ * FTP Server Daemon
+ *
+ * Submitted by: Jake Janovetz <janovetz@tempest.ece.uiuc.edu>
+ *
+ * Changed by: Sergei Organov <osv@javad.ru> (OSV)
+ *
+ * Changes:
+ *
+ * 2001-01-31 Sergei Organov <osv@javad.ru>
+ *
+ * * Hacks with current dir and root dir removed in favor of new libio
+ * support for task-local current and root directories.
+ *
+ * 2001-01-30 Sergei Organov <osv@javad.ru>
+ *
+ * * Bug in `close_data_socket()' introduced by previous change fixed.
+ * * `command_pasv()' changed to set timeout on socket we are listening on
+ * and code fixed to don't close socket twice on error.
+ * * `serr()' changed to clear `errno'.
+ * * `data_socket()' changed to clear `errno' before `bind()'.
+ * * `session()' changed to clear `errno' before processing session.
+ *
+ * 2001-01-29 Sergei Organov <osv@javad.ru>
+ *
+ * * `close_data_socket()' fixed to close both active and passive sockets
+ * * Initialize info->data_socket to -1 in `daemon()'
+ * * Initialize `fname' to empty string in `exec_command()'
+ *
+ * 2001-01-22 Sergei Organov <osv@javad.ru>
+ *
+ * * Timeouts on sockets implemented. 'idle' field added to
+ * configuration. No timeout by default to keep backward compatibility.
+ * Note: SITE IDLE command not implemented yet.
+ * * Basic global access control implemented. 'access' field added to
+ * configuration. No access limitations by default to keep backward
+ * compatibility.
+ *
+ * 2001-01-17 Sergei Organov <osv@javad.ru>
+ *
+ * * Anchor data socket for active mode (using self IP and port 20.)
+ * * Fixed default data port support (still not tested).
+ * * Don't allow IP address different from originating host in
+ * PORT command to improve security.
+ * * Fixed bug in MDTM command.
+ * * Check for correctness of parsing of argument in command_port().
+ * * Fixed squeeze_path() to don't allow names like 'NAME/smth' where
+ * 'NAME' is not a directory.
+ * * Command parsing a little bit improved: command names are now
+ * converted to upper-case to be more compatible with RFC (command
+ * names are not case-sensitive.)
+ * * Reformat comments so that they have RTEMS look-and-feel.
+ *
+ * 2001-01-16 Sergei Organov <osv@javad.ru>
+ *
+ * * Fixed DELE, SITE CHMOD, RMD, MKD broken by previous changes
+ * * True ASCII mode implemented (doesn't work for hooks and /dev/null)
+ * * Passive mode implemented, PASV command added.
+ * * Default port for data connection could be used (untested, can't find
+ * ftp client that doesn't send PORT command)
+ * * SYST reply changed to UNIX, as former RTEMS isn't registered name.
+ * * Reply codes reviewed and fixed.
+ *
+ * 2001-01-08 Sergei Organov <osv@javad.ru>
+ *
+ * * use pool of pre-created threads to handle sessions
+ * * LIST output now similar to what "/bin/ls -al" would output, thus
+ * FTP clients could parse it.
+ * * LIST NAME now works (both for files and directories)
+ * * keep track of CWD for every session separately
+ * * ability to specify root directory name in configuration table
+ * * options sent in commands are ignored, thus LIST -al FILE works
+ * * added support for NLST, CDUP and MDTM commands
+ * * buffers are allocated on stack instead of heap where possible
+ * * drop using of task notepad to pass parameters - use function
+ * arguments instead
+ * * various bug-fixes, e.g., use of PF_INET in socket() instead of
+ * AF_INET, use snprintf() instead of sprintf() everywhere for safety,
+ * etc.
+ *
+ * $Id$
+ */
+
+/*************************************************************************
+ * ftpd.c
+ *************************************************************************
+ * Description:
+ *
+ * This file contains the daemon which services requests that appear
+ * on the FTP port. This server is compatible with FTP, but it
+ * also provides 'hooks' to make it usable in situations where files
+ * are not used/necessary. Once the server is started, it runs
+ * forever.
+ *
+ *
+ * Organization:
+ *
+ * The FTP daemon is started upon boot along with a (configurable)
+ * number of tasks to handle sessions. It runs all the time and
+ * waits for connections on the known FTP port (21). When
+ * a connection is made, it wakes-up a 'session' task. That
+ * session then interacts with the remote host. When the session
+ * is complete, the session task goes to sleep. The daemon still
+ * runs, however.
+ *
+ *
+ * Supported commands are:
+ *
+ * RETR xxx - Sends a file from the client.
+ * STOR xxx - Receives a file from the client. xxx = filename.
+ * LIST xxx - Sends a file list to the client.
+ * NLST xxx - Sends a file list to the client.
+ * USER - Does nothing.
+ * PASS - Does nothing.
+ * SYST - Replies with the system type (`RTEMS').
+ * DELE xxx - Delete file xxx.
+ * MKD xxx - Create directory xxx.
+ * RMD xxx - Remove directory xxx.
+ * PWD - Print working directory.
+ * CWD xxx - Change working directory.
+ * CDUP - Change to upper directory.
+ * SITE CHMOD xxx yyy - Change permissions on file yyy to xxx.
+ * PORT a,b,c,d,x,y - Setup for a data port to IP address a.b.c.d
+ * and port (x*256 + y).
+ * MDTM xxx - Send file modification date/time to the client.
+ * xxx = filename.
+ * PASV - Use passive mode data connection.
+ *
+ *
+ * The public routines contained in this file are:
+ *
+ * rtems_initialize_ftpd - Initializes and starts the server daemon,
+ * then returns to its caller.
+ *
+ *------------------------------------------------------------------------
+ * Jake Janovetz
+ * University of Illinois
+ * 1406 West Green Street
+ * Urbana IL 61801
+ *************************************************************************
+ * Change History:
+ * 12/01/97 - Creation (JWJ)
+ * 2001-01-08 - Changes by OSV
+ *************************************************************************/
+
+/*************************************************************************
+ * Meanings of first and second digits of reply codes:
+ *
+ * Reply: Description:
+ *-------- --------------
+ * 1yz Positive preliminary reply. The action is being started but
+ * expect another reply before sending another command.
+ * 2yz Positive completion reply. A new command can be sent.
+ * 3yz Positive intermediate reply. The command has been accepted
+ * but another command must be sent.
+ * 4yz Transient negative completion reply. The requested action did
+ * not take place, but the error condition is temporary so the
+ * command can be reissued later.
+ * 5yz Permanent negative completion reply. The command was not
+ * accepted and should not be retried.
+ *-------------------------------------------------------------------------
+ * x0z Syntax errors.
+ * x1z Information.
+ * x2z Connections. Replies referring to the control or data
+ * connections.
+ * x3z Authentication and accounting. Replies for the login or
+ * accounting commands.
+ * x4z Unspecified.
+ * x5z Filesystem status.
+ *************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/error.h>
+#include <rtems/libio.h>
+#include <rtems/userenv.h>
+#include <syslog.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/ftp.h>
+#include <netinet/in.h>
+
+#include "ftpd.h"
+
+
+#ifdef __GNUC__
+/* change to #if 1 to disable syslog entirely */
+#if 0
+#undef syslog
+#define syslog(a, b, ...) while(0){}
+#endif
+#endif
+
+#define FTPD_SERVER_MESSAGE "RTEMS FTP server (Version 1.1-JWJ) ready."
+
+#define FTPD_SYSTYPE "UNIX Type: L8"
+
+/* Seem to be unused */
+#if 0
+#define FTPD_WELCOME_MESSAGE \
+ "Welcome to the RTEMS FTP server.\n" \
+ "\n" \
+ "Login accepted.\n"
+#endif
+
+/* Various buffer sizes */
+enum
+{
+ FTPD_BUFSIZE = 256, /* Size for temporary buffers */
+ FTPD_DATASIZE = 1024, /* Size for file transfer buffers */
+ FTPD_STACKSIZE = 8 * 1024, /* Tasks stack size */
+};
+
+/* Event to be used by session tasks for waiting */
+enum
+{
+ FTPD_RTEMS_EVENT = RTEMS_EVENT_1
+};
+
+/* Configuration table */
+extern struct rtems_ftpd_configuration rtems_ftpd_configuration;
+
+/* this is not prototyped in strict ansi mode */
+FILE *fdopen (int fildes, const char *mode);
+
+/*PAGE
+ * SessionInfo structure.
+ *
+ * The following structure is allocated for each session.
+ */
+typedef struct
+{
+ struct sockaddr_in ctrl_addr; /* Control connection self address */
+ struct sockaddr_in data_addr; /* Data address set by PORT command */
+ struct sockaddr_in def_addr; /* Default address for data */
+ int use_default; /* 1 - use default address for data */
+ FILE *ctrl_fp; /* File pointer for control connection */
+ int ctrl_socket; /* Socket for ctrl connection */
+ int pasv_socket; /* Socket for PASV connection */
+ int data_socket; /* Socket for data connection */
+ int idle; /* Timeout in seconds */
+ int xfer_mode; /* Transfer mode (ASCII/binary) */
+ rtems_id tid; /* Task id */
+} FTPD_SessionInfo_t;
+
+
+/*
+ * TaskPool structure.
+ */
+typedef struct
+{
+ FTPD_SessionInfo_t *info;
+ FTPD_SessionInfo_t **queue;
+ int count;
+ int head;
+ int tail;
+ rtems_id mutex;
+ rtems_id sem;
+} FTPD_TaskPool_t;
+
+/*
+ * Task pool instance.
+ */
+static FTPD_TaskPool_t task_pool;
+
+/*
+ * Root directory
+ */
+
+static char const* ftpd_root = "/";
+
+/*
+ * Default idle timeout for sockets in seconds.
+ */
+static int ftpd_timeout = 0;
+
+/*
+ * Global access flags.
+ */
+static int ftpd_access = 0;
+
+/*PAGE
+ *
+ * serr
+ *
+ * Return error string corresponding to current 'errno'.
+ *
+ */
+static char const*
+serr(void)
+{
+ int err = errno;
+ errno = 0;
+ return strerror(err);
+}
+
+/*PAGE
+ *
+ * Utility routines for access control.
+ *
+ */
+
+static int
+can_read(void)
+{
+ return (ftpd_access & FTPD_NO_READ) == 0;
+}
+
+static int
+can_write(void)
+{
+ return (ftpd_access & FTPD_NO_WRITE) == 0;
+}
+
+/*PAGE
+ *
+ * Task pool management routines
+ *
+ */
+
+
+/*PAGE
+ *
+ * task_pool_done
+ *
+ * Cleanup task pool.
+ *
+ * Input parameters:
+ * count - number of entries in task pool to cleanup
+ *
+ * Output parameters:
+ * NONE
+ *
+ */
+static void
+task_pool_done(int count)
+{
+ int i;
+ for(i = 0; i < count; ++i)
+ rtems_task_delete(task_pool.info[i].tid);
+ if(task_pool.info)
+ free(task_pool.info);
+ if(task_pool.queue)
+ free(task_pool.queue);
+ if(task_pool.mutex != (rtems_id)-1)
+ rtems_semaphore_delete(task_pool.mutex);
+ if(task_pool.sem != (rtems_id)-1)
+ rtems_semaphore_delete(task_pool.sem);
+ task_pool.info = 0;
+ task_pool.queue = 0;
+ task_pool.count = 0;
+ task_pool.sem = -1;
+ task_pool.mutex = -1;
+}
+
+/*PAGE
+ *
+ * task_pool_init
+ *
+ * Initialize task pool.
+ *
+ * Input parameters:
+ * count - number of entries in task pool to create
+ * priority - priority tasks are started with
+ *
+ * Output parameters:
+ * returns 1 on success, 0 on failure.
+ *
+ */
+static void session(rtems_task_argument arg); /* Forward declare */
+
+static int
+task_pool_init(int count, rtems_task_priority priority)
+{
+ int i;
+ rtems_status_code sc;
+ char id = 'a';
+
+ task_pool.count = 0;
+ task_pool.head = task_pool.tail = 0;
+ task_pool.mutex = (rtems_id)-1;
+ task_pool.sem = (rtems_id)-1;
+
+ sc = rtems_semaphore_create(
+ rtems_build_name('F', 'T', 'P', 'M'),
+ 1,
+ RTEMS_DEFAULT_ATTRIBUTES
+ | RTEMS_BINARY_SEMAPHORE
+ | RTEMS_INHERIT_PRIORITY
+ | RTEMS_PRIORITY,
+ RTEMS_NO_PRIORITY,
+ &task_pool.mutex);
+
+ if(sc == RTEMS_SUCCESSFUL)
+ sc = rtems_semaphore_create(
+ rtems_build_name('F', 'T', 'P', 'S'),
+ count,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ RTEMS_NO_PRIORITY,
+ &task_pool.sem);
+
+ if(sc != RTEMS_SUCCESSFUL) {
+ task_pool_done(0);
+ syslog(LOG_ERR, "ftpd: Can not create semaphores");
+ return 0;
+ }
+
+ task_pool.info = (FTPD_SessionInfo_t*)
+ malloc(sizeof(FTPD_SessionInfo_t) * count);
+ task_pool.queue = (FTPD_SessionInfo_t**)
+ malloc(sizeof(FTPD_SessionInfo_t*) * count);
+ if (NULL == task_pool.info || NULL == task_pool.queue)
+ {
+ task_pool_done(0);
+ syslog(LOG_ERR, "ftpd: Not enough memory");
+ return 0;
+ }
+
+ for(i = 0; i < count; ++i)
+ {
+ FTPD_SessionInfo_t *info = &task_pool.info[i];
+ sc = rtems_task_create(rtems_build_name('F', 'T', 'P', id),
+ priority, FTPD_STACKSIZE,
+ RTEMS_PREEMPT | RTEMS_NO_TIMESLICE |
+ RTEMS_NO_ASR | RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
+ &info->tid);
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ sc = rtems_task_start(
+ info->tid, session, (rtems_task_argument)info);
+ if (sc != RTEMS_SUCCESSFUL)
+ task_pool_done(i);
+ }
+ else
+ task_pool_done(i + 1);
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ syslog(LOG_ERR, "ftpd: Could not create/start FTPD session: %s",
+ rtems_status_text(sc));
+ return 0;
+ }
+ task_pool.queue[i] = task_pool.info + i;
+ if (++id > 'z')
+ id = 'a';
+ }
+ task_pool.count = count;
+ return 1;
+}
+
+/*PAGE
+ *
+ * task_pool_obtain
+ *
+ * Obtain free task from task pool.
+ *
+ * Input parameters:
+ * NONE
+ *
+ * Output parameters:
+ * returns pointer to the corresponding SessionInfo structure on success,
+ * NULL if there are no free tasks in the pool.
+ *
+ */
+static FTPD_SessionInfo_t*
+task_pool_obtain()
+{
+ FTPD_SessionInfo_t* info = 0;
+ rtems_status_code sc;
+ sc = rtems_semaphore_obtain(task_pool.sem, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT);
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ rtems_semaphore_obtain(task_pool.mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ info = task_pool.queue[task_pool.head];
+ if(++task_pool.head >= task_pool.count)
+ task_pool.head = 0;
+ rtems_semaphore_release(task_pool.mutex);
+ }
+ return info;
+}
+
+/*PAGE
+ *
+ * task_pool_release
+ *
+ * Return task obtained by 'obtain()' back to the task pool.
+ *
+ * Input parameters:
+ * info - pointer to corresponding SessionInfo structure.
+ *
+ * Output parameters:
+ * NONE
+ *
+ */
+static void
+task_pool_release(FTPD_SessionInfo_t* info)
+{
+ rtems_semaphore_obtain(task_pool.mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ task_pool.queue[task_pool.tail] = info;
+ if(++task_pool.tail >= task_pool.count)
+ task_pool.tail = 0;
+ rtems_semaphore_release(task_pool.mutex);
+ rtems_semaphore_release(task_pool.sem);
+}
+
+/*
+ * End of task pool routines
+ */
+
+/*PAGE
+ *
+ * Function: send_reply
+ *
+ *
+ * This procedure sends a reply to the client via the control
+ * connection.
+ *
+ *
+ * Input parameters:
+ * code - 3-digit reply code.
+ * text - Reply text.
+ *
+ * Output parameters:
+ * NONE
+ */
+static void
+send_reply(FTPD_SessionInfo_t *info, int code, char *text)
+{
+ char const* s = (info->xfer_mode == TYPE_A) ? "\r" : "";
+ /* If a text reply exists, add it to the reply data. */
+ if (text != NULL)
+ fprintf(info->ctrl_fp, "%d %.70s%s\n", code, text, s);
+ else
+ fprintf(info->ctrl_fp, "%d%s\n", code, s);
+ fflush(info->ctrl_fp);
+}
+
+
+/*PAGE
+ *
+ * close_socket
+ *
+ * Close socket.
+ *
+ * Input parameters:
+ * s - socket descriptor.
+ * seconds - number of seconds the timeout should be,
+ * if >= 0 - infinite timeout (no timeout).
+ *
+ * Output parameters:
+ * returns 1 on success, 0 on failure.
+ */
+static int
+set_socket_timeout(int s, int seconds)
+{
+ int res = 0;
+ struct timeval tv;
+ int len = sizeof(tv);
+
+ if(seconds < 0)
+ seconds = 0;
+ tv.tv_usec = 0;
+ tv.tv_sec = seconds;
+ if(0 != setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, len))
+ syslog(LOG_ERR, "ftpd: Can't set send timeout on socket: %s.", serr());
+ else if(0 != setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, len))
+ syslog(LOG_ERR, "ftpd: Can't set receive timeout on socket: %s.", serr());
+ else
+ res = 1;
+ return res;
+}
+
+/*PAGE
+ *
+ * close_socket
+ *
+ * Close socket.
+ *
+ * Input parameters:
+ * s - socket descriptor to be closed.
+ *
+ * Output parameters:
+ * returns 1 on success, 0 on failure
+ */
+static int
+close_socket(int s)
+{
+ if (0 <= s)
+ {
+ if (0 != close(s))
+ {
+ shutdown(s, 2);
+ if (0 != close(s))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*PAGE
+ *
+ * data_socket
+ *
+ * Create data socket for session.
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ *
+ * Output parameters:
+ * returns socket descriptor, or -1 if failure
+ *
+ */
+static int
+data_socket(FTPD_SessionInfo_t *info)
+{
+ int s = info->pasv_socket;
+ if(0 > s)
+ {
+ int on = 1;
+ s = socket(PF_INET, SOCK_STREAM, 0);
+ if(0 > s)
+ send_reply(info, 425, "Can't create data socket.");
+ else if(0 > setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
+ {
+ close_socket(s);
+ s = -1;
+ }
+ else
+ {
+ struct sockaddr_in data_source;
+ int tries;
+
+ /* anchor socket to avoid multi-homing problems */
+ data_source = info->ctrl_addr;
+ data_source.sin_port = htons(20); /* ftp-data port */
+ for(tries = 1; tries < 10; ++tries)
+ {
+ errno = 0;
+ if(bind(s, (struct sockaddr *)&data_source, sizeof(data_source)) >= 0)
+ break;
+ if (errno != EADDRINUSE)
+ tries = 10;
+ else
+ rtems_task_wake_after(tries * 10);
+ }
+ if(tries >= 10)
+ {
+ send_reply(info, 425, "Can't bind data socket.");
+ close_socket(s);
+ s = -1;
+ }
+ else
+ {
+ struct sockaddr_in *data_dest =
+ (info->use_default) ? &info->def_addr : &info->data_addr;
+ if(0 > connect(s, (struct sockaddr *)data_dest, sizeof(*data_dest)))
+ {
+ send_reply(info, 425, "Can't connect data socket.");
+ close_socket(s);
+ s = -1;
+ }
+ }
+ }
+ }
+ info->data_socket = s;
+ info->use_default = 1;
+ if(s >= 0)
+ set_socket_timeout(s, info->idle);
+ return s;
+}
+
+/*PAGE
+ *
+ * close_data_socket
+ *
+ * Close data socket for session.
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ *
+ * Output parameters:
+ * NONE
+ *
+ */
+static void
+close_data_socket(FTPD_SessionInfo_t *info)
+{
+ /* As at most one data socket could be open simultaneously and in some cases
+ data_socket == pasv_socket, we select socket to close, then close it. */
+ int s = info->data_socket;
+ if(0 > s)
+ s = info->pasv_socket;
+ if(!close_socket(s))
+ syslog(LOG_ERR, "ftpd: Error closing data socket.");
+ info->data_socket = -1;
+ info->pasv_socket = -1;
+ info->use_default = 1;
+}
+
+/*PAGE
+ *
+ * close_stream
+ *
+ * Close control stream of session.
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ *
+ * Output parameters:
+ * NONE
+ *
+ */
+static void
+close_stream(FTPD_SessionInfo_t* info)
+{
+ if (NULL != info->ctrl_fp)
+ {
+ if (0 != fclose(info->ctrl_fp))
+ {
+ syslog(LOG_ERR, "ftpd: Could not close control stream: %s", serr());
+ }
+ else
+ info->ctrl_socket = -1;
+ }
+
+ if (!close_socket(info->ctrl_socket))
+ syslog(LOG_ERR, "ftpd: Could not close control socket: %s", serr());
+
+ info->ctrl_fp = NULL;
+ info->ctrl_socket = -1;
+}
+
+
+/*PAGE
+ *
+ * send_mode_reply
+ *
+ * Sends BINARY/ASCII reply string depending on current transfer mode.
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ *
+ * Output parameters:
+ * NONE
+ *
+ */
+static void
+send_mode_reply(FTPD_SessionInfo_t *info)
+{
+ if(info->xfer_mode == TYPE_I)
+ send_reply(info, 150, "Opening BINARY mode data connection.");
+ else
+ send_reply(info, 150, "Opening ASCII mode data connection.");
+}
+
+/*PAGE
+ *
+ * command_retrieve
+ *
+ * Perform the "RETR" command (send file to client).
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ * char *filename - source filename.
+ *
+ * Output parameters:
+ * NONE
+ *
+ */
+static void
+command_retrieve(FTPD_SessionInfo_t *info, char const *filename)
+{
+ int s = -1;
+ int fd = -1;
+ char buf[FTPD_DATASIZE];
+ int res = 0;
+
+ if(!can_read())
+ {
+ send_reply(info, 550, "Access denied.");
+ return;
+ }
+
+ if (0 > (fd = open(filename, O_RDONLY)))
+ {
+ send_reply(info, 550, "Error opening file.");
+ return;
+ }
+
+ send_mode_reply(info);
+
+ s = data_socket(info);
+
+ if (0 <= s)
+ {
+ int n = -1;
+
+ if(info->xfer_mode == TYPE_I)
+ {
+ while ((n = read(fd, buf, FTPD_DATASIZE)) > 0)
+ {
+ if(send(s, buf, n, 0) != n)
+ break;
+ }
+ }
+ else if (info->xfer_mode == TYPE_A)
+ {
+ int rest = 0;
+ while (rest == 0 && (n = read(fd, buf, FTPD_DATASIZE)) > 0)
+ {
+ char const* e = buf;
+ char const* b;
+ int i;
+ rest = n;
+ do
+ {
+ char lf = '\0';
+
+ b = e;
+ for(i = 0; i < rest; ++i, ++e)
+ {
+ if(*e == '\n')
+ {
+ lf = '\n';
+ break;
+ }
+ }
+ if(send(s, b, i, 0) != i)
+ break;
+ if(lf == '\n')
+ {
+ if(send(s, "\r\n", 2, 0) != 2)
+ break;
+ ++e;
+ ++i;
+ }
+ }
+ while((rest -= i) > 0);
+ }
+ }
+
+ if (0 == n)
+ {
+ if (0 == close(fd))
+ {
+ fd = -1;
+ res = 1;
+ }
+ }
+ }
+
+ if (-1 != fd)
+ close(fd);
+
+ if (0 == res)
+ send_reply(info, 451, "File read error.");
+ else
+ send_reply(info, 226, "Transfer complete.");
+
+ close_data_socket(info);
+
+ return;
+}
+
+
+/*PAGE
+ *
+ * discard
+ *
+ * Analog of `write' routine that just discards passed data
+ *
+ * Input parameters:
+ * fd - file descriptor (ignored)
+ * buf - data to write (ignored)
+ * count - number of bytes in `buf'
+ *
+ * Output parameters:
+ * returns `count'
+ *
+ */
+static ssize_t
+discard(int fd, void const* buf, size_t count)
+{
+ (void)fd;
+ (void)buf;
+ return count;
+}
+
+/*PAGE
+ *
+ * command_store
+ *
+ * Performs the "STOR" command (receive data from client).
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ * char *filename - Destination filename.
+ *
+ * Output parameters:
+ * NONE
+ */
+static void
+command_store(FTPD_SessionInfo_t *info, char const *filename)
+{
+ int s;
+ int n;
+ unsigned long size = 0;
+ struct rtems_ftpd_hook *usehook = NULL;
+ char buf[FTPD_DATASIZE];
+ int res = 1;
+ int bare_lfs = 0;
+ int null = 0;
+ typedef ssize_t (*WriteProc)(int, void const*, size_t);
+ WriteProc wrt = &write;
+
+ if(!can_write())
+ {
+ send_reply(info, 550, "Access denied.");
+ return;
+ }
+
+ send_mode_reply(info);
+
+ s = data_socket(info);
+ if(0 > s)
+ return;
+
+ null = !strcmp("/dev/null", filename);
+ if (null)
+ {
+ /* File "/dev/null" just throws data away.
+ * FIXME: this is hack. Using `/dev/null' filesystem entry would be
+ * better.
+ */
+ wrt = &discard;
+ }
+
+ if (!null && rtems_ftpd_configuration.hooks != NULL)
+ {
+
+ /* Search our list of hooks to see if we need to do something special. */
+ struct rtems_ftpd_hook *hook;
+ int i;
+
+ i = 0;
+ hook = &rtems_ftpd_configuration.hooks[i++];
+ while (hook->filename != NULL)
+ {
+ if (!strcmp(hook->filename, filename))
+ {
+ usehook = hook;
+ break;
+ }
+ hook = &rtems_ftpd_configuration.hooks[i++];
+ }
+ }
+
+ if (usehook != NULL)
+ {
+ /*
+ * OSV: FIXME: Small buffer could be used and hook routine
+ * called multiple times instead. Alternatively, the support could be
+ * removed entirely in favor of configuring RTEMS pseudo-device with
+ * given name.
+ */
+
+ char *bigBufr;
+ size_t filesize = rtems_ftpd_configuration.max_hook_filesize + 1;
+
+ /*
+ * Allocate space for our "file".
+ */
+ bigBufr = (char *)malloc(filesize);
+ if (bigBufr == NULL)
+ {
+ send_reply(info, 451, "Local resource failure: malloc.");
+ close_data_socket(info);
+ return;
+ }
+
+ /*
+ * Retrieve the file into our buffer space.
+ */
+ size = 0;
+ while ((n = recv(s, bigBufr + size, filesize - size, 0)) > 0)
+ {
+ size += n;
+ }
+ if (size >= filesize)
+ {
+ send_reply(info, 451, "File too long: buffer size exceeded.");
+ free(bigBufr);
+ close_data_socket(info);
+ return;
+ }
+
+ /*
+ * Call our hook.
+ */
+ res = (usehook->hook_function)(bigBufr, size) == 0;
+ free(bigBufr);
+ if(!res)
+ {
+ send_reply(info, 451, "File processing failed.");
+ close_data_socket(info);
+ return;
+ }
+ }
+ else
+ {
+ /* Data transfer to regular file or /dev/null. */
+ int fd = 0;
+
+ if(!null)
+ fd = creat(filename,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+
+ if (0 > fd)
+ {
+ send_reply(info, 550, "Error creating file.");
+ close_data_socket(info);
+ return;
+ }
+
+ if(info->xfer_mode == TYPE_I)
+ {
+ while ((n = recv(s, buf, FTPD_DATASIZE, 0)) > 0)
+ {
+ if (wrt(fd, buf, n) != n)
+ {
+ res = 0;
+ break;
+ }
+ }
+ }
+ else if(info->xfer_mode == TYPE_A)
+ {
+ int rest = 0;
+ int pended_cr = 0;
+ while (res && rest == 0 && (n = recv(s, buf, FTPD_DATASIZE, 0)) > 0)
+ {
+ char const* e = buf;
+ char const* b;
+ int i;
+
+ rest = n;
+ if(pended_cr && *e != '\n')
+ {
+ char const lf = '\r';
+ pended_cr = 0;
+ if(wrt(fd, &lf, 1) != 1)
+ {
+ res = 0;
+ break;
+ }
+ }
+ do
+ {
+ int count;
+ int sub = 0;
+
+ b = e;
+ for(i = 0; i < rest; ++i, ++e)
+ {
+ int pcr = pended_cr;
+ pended_cr = 0;
+ if(*e == '\r')
+ {
+ pended_cr = 1;
+ }
+ else if(*e == '\n')
+ {
+ if(pcr)
+ {
+ sub = 2;
+ ++i;
+ ++e;
+ break;
+ }
+ ++bare_lfs;
+ }
+ }
+ if(res == 0)
+ break;
+ count = i - sub - pended_cr;
+ if(count > 0 && wrt(fd, b, count) != count)
+ {
+ res = 0;
+ break;
+ }
+ if(sub == 2 && wrt(fd, e - 1, 1) != 1)
+ res = 0;
+ }
+ while((rest -= i) > 0);
+ }
+ }
+
+ if (0 > close(fd) || res == 0)
+ {
+ send_reply(info, 452, "Error writing file.");
+ close_data_socket(info);
+ return;
+ }
+ }
+
+ if (bare_lfs > 0)
+ {
+ snprintf(buf, FTPD_BUFSIZE,
+ "Transfer complete. WARNING! %d bare linefeeds received in ASCII mode.",
+ bare_lfs);
+ send_reply(info, 226, buf);
+ }
+ else
+ send_reply(info, 226, "Transfer complete.");
+ close_data_socket(info);
+
+}
+
+
+/*PAGE
+ *
+ * send_dirline
+ *
+ * Sends one line of LIST command reply corresponding to single file.
+ *
+ * Input parameters:
+ * s - socket descriptor to send data to
+ * wide - if 0, send only file name. If not 0, send 'stat' info as well in
+ * "ls -l" format.
+ * curTime - current time
+ * path - path to be prepended to what is given by 'add'
+ * add - path to be appended to what is given by 'path', the resulting path
+ * is then passed to 'stat()' routine
+ * name - file name to be reported in output
+ * buf - buffer for temporary data
+ *
+ * Output parameters:
+ * returns 0 on failure, 1 on success
+ *
+ */
+static int
+send_dirline(int s, int wide, time_t curTime, char const* path,
+ char const* add, char const* fname, char* buf)
+{
+ if(wide)
+ {
+ struct stat stat_buf;
+
+ int plen = strlen(path);
+ int alen = strlen(add);
+ if(plen == 0)
+ {
+ buf[plen++] = '/';
+ buf[plen] = '\0';
+ }
+ else
+ {
+ strcpy(buf, path);
+ if(alen > 0 && buf[plen - 1] != '/')
+ {
+ buf[plen++] = '/';
+ if(plen >= FTPD_BUFSIZE)
+ return 0;
+ buf[plen] = '\0';
+ }
+ }
+ if(plen + alen >= FTPD_BUFSIZE)
+ return 0;
+ strcpy(buf + plen, add);
+
+ if (stat(buf, &stat_buf) == 0)
+ {
+ int len;
+ struct tm bt;
+ time_t tf = stat_buf.st_mtime;
+ enum { SIZE = 80 };
+ enum { SIX_MONTHS = 365*24*60*60/2 };
+ char timeBuf[SIZE];
+ gmtime_r(&tf, &bt);
+ if(curTime > tf + SIX_MONTHS || tf > curTime + SIX_MONTHS)
+ strftime (timeBuf, SIZE, "%b %d %Y", &bt);
+ else
+ strftime (timeBuf, SIZE, "%b %d %H:%M", &bt);
+
+ len = snprintf(buf, FTPD_BUFSIZE,
+ "%c%c%c%c%c%c%c%c%c%c 1 %5d %5d %11u %s %s\r\n",
+ (S_ISLNK(stat_buf.st_mode)?('l'):
+ (S_ISDIR(stat_buf.st_mode)?('d'):('-'))),
+ (stat_buf.st_mode & S_IRUSR)?('r'):('-'),
+ (stat_buf.st_mode & S_IWUSR)?('w'):('-'),
+ (stat_buf.st_mode & S_IXUSR)?('x'):('-'),
+ (stat_buf.st_mode & S_IRGRP)?('r'):('-'),
+ (stat_buf.st_mode & S_IWGRP)?('w'):('-'),
+ (stat_buf.st_mode & S_IXGRP)?('x'):('-'),
+ (stat_buf.st_mode & S_IROTH)?('r'):('-'),
+ (stat_buf.st_mode & S_IWOTH)?('w'):('-'),
+ (stat_buf.st_mode & S_IXOTH)?('x'):('-'),
+ (int)stat_buf.st_uid,
+ (int)stat_buf.st_gid,
+ (int)stat_buf.st_size,
+ timeBuf,
+ fname
+ );
+
+ if(send(s, buf, len, 0) != len)
+ return 0;
+ }
+ }
+ else
+ {
+ int len = snprintf(buf, FTPD_BUFSIZE, "%s\r\n", fname);
+ if(send(s, buf, len, 0) != len)
+ return 0;
+ }
+ return 1;
+}
+
+/*PAGE
+ *
+ * command_list
+ *
+ * Send file list to client.
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ * char *fname - File (or directory) to list.
+ *
+ * Output parameters:
+ * NONE
+ */
+static void
+command_list(FTPD_SessionInfo_t *info, char const *fname, int wide)
+{
+ int s;
+ DIR *dirp = 0;
+ struct dirent *dp = 0;
+ struct stat stat_buf;
+ char buf[FTPD_BUFSIZE];
+ time_t curTime;
+ int sc = 1;
+
+ send_reply(info, 150, "Opening ASCII mode data connection for LIST.");
+
+ s = data_socket(info);
+ if(0 > s)
+ {
+ syslog(LOG_ERR, "ftpd: Error connecting to data socket.");
+ return;
+ }
+
+ if(fname[0] == '\0')
+ fname = ".";
+
+ if (0 > stat(fname, &stat_buf))
+ {
+ snprintf(buf, FTPD_BUFSIZE,
+ "%s: No such file or directory.\r\n", fname);
+ send(s, buf, strlen(buf), 0);
+ }
+ else if (S_ISDIR(stat_buf.st_mode) && (NULL == (dirp = opendir(fname))))
+ {
+ snprintf(buf, FTPD_BUFSIZE,
+ "%s: Can not open directory.\r\n", fname);
+ send(s, buf, strlen(buf), 0);
+ }
+ else
+ {
+ time(&curTime);
+ if(!dirp && *fname)
+ sc = sc && send_dirline(s, wide, curTime, fname, "", fname, buf);
+ else {
+ /* FIXME: need "." and ".." only when '-a' option is given */
+ sc = sc && send_dirline(s, wide, curTime, fname, "", ".", buf);
+ sc = sc && send_dirline(s, wide, curTime, fname,
+ (strcmp(fname, ftpd_root) ? ".." : ""), "..", buf);
+ while (sc && (dp = readdir(dirp)) != NULL)
+ sc = sc &&
+ send_dirline(s, wide, curTime, fname, dp->d_name, dp->d_name, buf);
+ }
+ }
+
+ if(dirp)
+ closedir(dirp);
+ close_data_socket(info);
+
+ if(sc)
+ send_reply(info, 226, "Transfer complete.");
+ else
+ send_reply(info, 426, "Connection aborted.");
+}
+
+
+/*PAGE
+ *
+ * command_cwd
+ *
+ * Change current working directory.
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ * dir - directory name passed in CWD command
+ *
+ * Output parameters:
+ * NONE
+ *
+ */
+static void
+command_cwd(FTPD_SessionInfo_t *info, char *dir)
+{
+ if(chdir(dir) == 0)
+ send_reply(info, 250, "CWD command successful.");
+ else
+ send_reply(info, 550, "CWD command failed.");
+}
+
+
+/*PAGE
+ *
+ * command_pwd
+ *
+ * Send current working directory to client.
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ *
+ * Output parameters:
+ * NONE
+ */
+static void
+command_pwd(FTPD_SessionInfo_t *info)
+{
+ char buf[FTPD_BUFSIZE];
+ char const* cwd;
+ errno = 0;
+ buf[0] = '"';
+ cwd = getcwd(buf + 1, FTPD_BUFSIZE - 4);
+ if(cwd)
+ {
+ int len = strlen(cwd);
+ static char const txt[] = "\" is the current directory.";
+ int size = sizeof(txt);
+ if(len + size + 1 >= FTPD_BUFSIZE)
+ size = FTPD_BUFSIZE - len - 2;
+ memcpy(buf + len + 1, txt, size);
+ buf[len + size] = '\0';
+ send_reply(info, 250, buf);
+ }
+ else {
+ snprintf(buf, FTPD_BUFSIZE, "Error: %s.", serr());
+ send_reply(info, 452, buf);
+ }
+}
+
+/*PAGE
+ *
+ * command_mdtm
+ *
+ * Handle FTP MDTM command (send file modification time to client)/
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ * fname - file name passed in MDTM command
+ *
+ * Output parameters:
+ * info->cwd is set to new CWD value.
+ */
+static void
+command_mdtm(FTPD_SessionInfo_t *info, char const* fname)
+{
+ struct stat stbuf;
+ char buf[FTPD_BUFSIZE];
+
+ if (0 > stat(fname, &stbuf))
+ {
+ snprintf(buf, FTPD_BUFSIZE, "%s: %s.", fname, serr());
+ send_reply(info, 550, buf);
+ }
+ else
+ {
+ struct tm *t = gmtime(&stbuf.st_mtime);
+ snprintf(buf, FTPD_BUFSIZE, "%04d%02d%02d%02d%02d%02d",
+ 1900 + t->tm_year,
+ t->tm_mon+1, t->tm_mday,
+ t->tm_hour, t->tm_min, t->tm_sec);
+ send_reply(info, 213, buf);
+ }
+}
+
+/*PAGE
+ *
+ * command_port
+ *
+ * This procedure fills address for data connection given the IP address and
+ * port of the remote machine.
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ * args - arguments to the "PORT" command.
+ *
+ * Output parameters:
+ * info->data_addr is set according to arguments of the PORT command.
+ * info->use_default is set to 0 on success, 1 on failure.
+ */
+static void
+command_port(FTPD_SessionInfo_t *info, char const *args)
+{
+ enum { NUM_FIELDS = 6 };
+ unsigned int a[NUM_FIELDS];
+ int n;
+
+ close_data_socket(info);
+
+ n = sscanf(args, "%u,%u,%u,%u,%u,%u", a+0, a+1, a+2, a+3, a+4, a+5);
+ if(NUM_FIELDS == n)
+ {
+ int i;
+ uint8_t b[NUM_FIELDS];
+
+ for(i = 0; i < NUM_FIELDS; ++i)
+ {
+ if(a[i] > 255)
+ break;
+ b[i] = (uint8_t)a[i];
+ }
+
+ if(i == NUM_FIELDS)
+ {
+ /* Note: while it contradicts with RFC959, we don't allow PORT command
+ * to specify IP address different than those of the originating client
+ * for the sake of safety. */
+ uint32_t const *ip = (uint32_t *)b;
+ if(*ip == info->def_addr.sin_addr.s_addr)
+ {
+ info->data_addr.sin_addr.s_addr = *ip;
+ info->data_addr.sin_port = *(uint16_t *)(b + 4);
+ info->data_addr.sin_family = AF_INET;
+ memset(info->data_addr.sin_zero, 0, sizeof(info->data_addr.sin_zero));
+
+ info->use_default = 0;
+ send_reply(info, 200, "PORT command successful.");
+ return; /* success */
+ }
+ else
+ {
+ send_reply(info, 425, "Address doesn't match peer's IP.");
+ return;
+ }
+ }
+ }
+ send_reply(info, 501, "Syntax error.");
+}
+
+
+/*PAGE
+ *
+ * command_pasv
+ *
+ * Handle FTP PASV command.
+ * Open socket, listen for and accept connection on it.
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ *
+ * Output parameters:
+ * info->pasv_socket is set to the descriptor of the data socket
+ */
+static void
+command_pasv(FTPD_SessionInfo_t *info)
+{
+ int s = -1;
+ int err = 1;
+
+ close_data_socket(info);
+
+ s = socket(PF_INET, SOCK_STREAM, 0);
+ if (s < 0)
+ syslog(LOG_ERR, "ftpd: Error creating PASV socket: %s", serr());
+ else
+ {
+ struct sockaddr_in addr;
+ socklen_t addrLen = sizeof(addr);
+
+ addr = info->ctrl_addr;
+ addr.sin_port = htons(0);
+
+ if (0 > bind(s, (struct sockaddr *)&addr, addrLen))
+ syslog(LOG_ERR, "ftpd: Error binding PASV socket: %s", serr());
+ else if (0 > listen(s, 1))
+ syslog(LOG_ERR, "ftpd: Error listening on PASV socket: %s", serr());
+ else if(set_socket_timeout(s, info->idle))
+ {
+ char buf[FTPD_BUFSIZE];
+ unsigned char const *ip, *p;
+
+ getsockname(s, (struct sockaddr *)&addr, &addrLen);
+ ip = (unsigned char const*)&(addr.sin_addr);
+ p = (unsigned char const*)&(addr.sin_port);
+ snprintf(buf, FTPD_BUFSIZE, "Entering passive mode (%u,%u,%u,%u,%u,%u).",
+ ip[0], ip[1], ip[2], ip[3], p[0], p[1]);
+ send_reply(info, 227, buf);
+
+ info->pasv_socket = accept(s, (struct sockaddr *)&addr, &addrLen);
+ if (0 > info->pasv_socket)
+ syslog(LOG_ERR, "ftpd: Error accepting PASV connection: %s", serr());
+ else
+ {
+ close_socket(s);
+ s = -1;
+ err = 0;
+ }
+ }
+ }
+ if(err)
+ {
+ /* (OSV) The note is from FreeBSD FTPD.
+ * Note: a response of 425 is not mentioned as a possible response to
+ * the PASV command in RFC959. However, it has been blessed as a
+ * legitimate response by Jon Postel in a telephone conversation
+ * with Rick Adams on 25 Jan 89. */
+ send_reply(info, 425, "Can't open passive connection.");
+ close_socket(s);
+ }
+}
+
+
+/*PAGE
+ *
+ * skip_options
+ *
+ * Utility routine to skip options (if any) from input command.
+ *
+ * Input parameters:
+ * p - pointer to pointer to command
+ *
+ * Output parameters:
+ * p - is changed to point to first non-option argument
+ */
+static void
+skip_options(char **p)
+{
+ char* buf = *p;
+ char* last = NULL;
+ while(1) {
+ while(isspace(*buf))
+ ++buf;
+ if(*buf == '-') {
+ if(*++buf == '-') { /* `--' should terminate options */
+ if(isspace(*++buf)) {
+ last = buf;
+ do ++buf;
+ while(isspace(*buf));
+ break;
+ }
+ }
+ while(*buf && !isspace(*buf))
+ ++buf;
+ last = buf;
+ }
+ else
+ break;
+ }
+ if(last)
+ *last = '\0';
+ *p = buf;
+}
+
+/*PAGE
+ *
+ * split_command
+ *
+ * Split command into command itself, options, and arguments. Command itself
+ * is converted to upper case.
+ *
+ * Input parameters:
+ * buf - initial command string
+ *
+ * Output parameter:
+ * buf - is modified by inserting '\0' at ends of split entities
+ * cmd - upper-cased command code
+ * opts - string containing all the options
+ * args - string containing all the arguments
+ */
+void
+split_command(char *buf, char **cmd, char **opts, char **args)
+{
+ char* eoc;
+ char* p = buf;
+ while(isspace(*p))
+ ++p;
+ *cmd = p;
+ while(*p && !isspace(*p))
+ {
+ *p = toupper(*p);
+ ++p;
+ }
+ eoc = p;
+ if(*p)
+ *p++ = '\0';
+ while(isspace(*p))
+ ++p;
+ *opts = p;
+ skip_options(&p);
+ *args = p;
+ if(*opts == p)
+ *opts = eoc;
+ while(*p && *p != '\r' && *p != '\n')
+ ++p;
+ if(*p)
+ *p++ = '\0';
+}
+
+/*PAGE
+ *
+ * exec_command
+ *
+ * Parse and execute FTP command.
+ *
+ * FIXME: This section is somewhat of a hack. We should have a better
+ * way to parse commands.
+ *
+ * Input parameters:
+ * info - corresponding SessionInfo structure
+ * cmd - command to be executed (upper-case)
+ * args - arguments of the command
+ *
+ * Output parameters:
+ * NONE
+ */
+static void
+exec_command(FTPD_SessionInfo_t *info, char* cmd, char* args)
+{
+ char fname[FTPD_BUFSIZE];
+ int wrong_command = 0;
+
+ fname[0] = '\0';
+
+ if (!strcmp("PORT", cmd))
+ {
+ command_port(info, args);
+ }
+ else if (!strcmp("PASV", cmd))
+ {
+ command_pasv(info);
+ }
+ else if (!strcmp("RETR", cmd))
+ {
+ sscanf(args, "%254s", fname);
+ command_retrieve(info, fname);
+ }
+ else if (!strcmp("STOR", cmd))
+ {
+ sscanf(args, "%254s", fname);
+ command_store(info, fname);
+ }
+ else if (!strcmp("LIST", cmd))
+ {
+ sscanf(args, "%254s", fname);
+ command_list(info, fname, 1);
+ }
+ else if (!strcmp("NLST", cmd))
+ {
+ sscanf(args, "%254s", fname);
+ command_list(info, fname, 0);
+ }
+ else if (!strcmp("MDTM", cmd))
+ {
+ sscanf(args, "%254s", fname);
+ command_mdtm(info, fname);
+ }
+ else if (!strcmp("SYST", cmd))
+ {
+ send_reply(info, 215, FTPD_SYSTYPE);
+ }
+ else if (!strcmp("TYPE", cmd))
+ {
+ if (args[0] == 'I')
+ {
+ info->xfer_mode = TYPE_I;
+ send_reply(info, 200, "Type set to I.");
+ }
+ else if (args[0] == 'A')
+ {
+ info->xfer_mode = TYPE_A;
+ send_reply(info, 200, "Type set to A.");
+ }
+ else
+ {
+ info->xfer_mode = TYPE_I;
+ send_reply(info, 504, "Type not implemented. Set to I.");
+ }
+ }
+ else if (!strcmp("USER", cmd) || !strcmp("PASS", cmd))
+ {
+ send_reply(info, 230, "User logged in.");
+ }
+ else if (!strcmp("DELE", cmd))
+ {
+ if(!can_write())
+ {
+ send_reply(info, 550, "Access denied.");
+ }
+ else if (
+ 1 == sscanf(args, "%254s", fname) &&
+ unlink(fname) == 0)
+ {
+ send_reply(info, 257, "DELE successful.");
+ }
+ else
+ {
+ send_reply(info, 550, "DELE failed.");
+ }
+ }
+ else if (!strcmp("SITE", cmd))
+ {
+ char* opts;
+ split_command(args, &cmd, &opts, &args);
+ if(!strcmp("CHMOD", cmd))
+ {
+ int mask;
+
+ if(!can_write())
+ {
+ send_reply(info, 550, "Access denied.");
+ }
+ else if(
+ 2 == sscanf(args, "%o %254s", &mask, fname) &&
+ chmod(fname, (mode_t)mask) == 0)
+ {
+ send_reply(info, 257, "CHMOD successful.");
+ }
+ else
+ {
+ send_reply(info, 550, "CHMOD failed.");
+ }
+ }
+ else
+ wrong_command = 1;
+ }
+ else if (!strcmp("RMD", cmd))
+ {
+ if(!can_write())
+ {
+ send_reply(info, 550, "Access denied.");
+ }
+ else if (
+ 1 == sscanf(args, "%254s", fname) &&
+ rmdir(fname) == 0)
+ {
+ send_reply(info, 257, "RMD successful.");
+ }
+ else
+ {
+ send_reply(info, 550, "RMD failed.");
+ }
+ }
+ else if (!strcmp("MKD", cmd))
+ {
+ if(!can_write())
+ {
+ send_reply(info, 550, "Access denied.");
+ }
+ else if (
+ 1 == sscanf(args, "%254s", fname) &&
+ mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) == 0)
+ {
+ send_reply(info, 257, "MKD successful.");
+ }
+ else
+ {
+ send_reply(info, 550, "MKD failed.");
+ }
+ }
+ else if (!strcmp("CWD", cmd))
+ {
+ sscanf(args, "%254s", fname);
+ command_cwd(info, fname);
+ }
+ else if (!strcmp("CDUP", cmd))
+ {
+ command_cwd(info, "..");
+ }
+ else if (!strcmp("PWD", cmd))
+ {
+ command_pwd(info);
+ }
+ else
+ wrong_command = 1;
+
+ if(wrong_command)
+ send_reply(info, 500, "Command not understood.");
+}
+
+
+/*PAGE
+ *
+ * session
+ *
+ * This task handles single session. It is waked up when the FTP daemon gets a
+ * service request from a remote machine. Here, we watch for commands that
+ * will come through the control connection. These commands are then parsed
+ * and executed until the connection is closed, either unintentionally or
+ * intentionally with the "QUIT" command.
+ *
+ * Input parameters:
+ * arg - pointer to corresponding SessionInfo.
+ *
+ * Output parameters:
+ * NONE
+ */
+static void
+session(rtems_task_argument arg)
+{
+ FTPD_SessionInfo_t *const info = (FTPD_SessionInfo_t *)arg;
+ int chroot_made = 0;
+
+ rtems_libio_set_private_env();
+
+ /* chroot() can fail here because the directory may not exist yet. */
+ chroot_made = chroot(ftpd_root) == 0;
+
+ while(1)
+ {
+ rtems_event_set set;
+
+ rtems_event_receive(FTPD_RTEMS_EVENT, RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT,
+ &set);
+
+ chroot_made = chroot_made || chroot(ftpd_root) == 0;
+ chdir("/");
+
+ errno = 0;
+
+ send_reply(info, 220, FTPD_SERVER_MESSAGE);
+
+ while (1)
+ {
+ char buf[FTPD_BUFSIZE];
+ char *cmd, *opts, *args;
+
+ if (fgets(buf, FTPD_BUFSIZE, info->ctrl_fp) == NULL)
+ {
+ syslog(LOG_INFO, "ftpd: Connection aborted.");
+ break;
+ }
+
+ split_command(buf, &cmd, &opts, &args);
+
+ if (!strcmp("QUIT", cmd))
+ {
+ send_reply(info, 221, "Goodbye.");
+ break;
+ }
+ else
+ {
+ exec_command(info, cmd, args);
+ }
+ }
+
+ /* Close connection and put ourselves back into the task pool. */
+ close_data_socket(info);
+ close_stream(info);
+ task_pool_release(info);
+ }
+}
+
+
+/*PAGE
+ *
+ * daemon
+ *
+ * This task runs forever. It waits for service requests on the FTP port
+ * (port 21 by default). When a request is received, it opens a new session
+ * to handle those requests until the connection is closed.
+ *
+ * Input parameters:
+ * NONE
+ *
+ * Output parameters:
+ * NONE
+ */
+static void
+daemon()
+{
+ int s;
+ socklen_t addrLen;
+ struct sockaddr_in addr;
+ FTPD_SessionInfo_t *info = NULL;
+
+
+ s = socket(PF_INET, SOCK_STREAM, 0);
+ if (s < 0)
+ syslog(LOG_ERR, "ftpd: Error creating socket: %s", serr());
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(rtems_ftpd_configuration.port);
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
+
+ if (0 > bind(s, (struct sockaddr *)&addr, sizeof(addr)))
+ syslog(LOG_ERR, "ftpd: Error binding control socket: %s", serr());
+ else if (0 > listen(s, 1))
+ syslog(LOG_ERR, "ftpd: Error listening on control socket: %s", serr());
+ else while (1)
+ {
+ int ss;
+ addrLen = sizeof(addr);
+ ss = accept(s, (struct sockaddr *)&addr, &addrLen);
+ if (0 > ss)
+ syslog(LOG_ERR, "ftpd: Error accepting control connection: %s", serr());
+ else if(!set_socket_timeout(ss, ftpd_timeout))
+ close_socket(ss);
+ else
+ {
+ info = task_pool_obtain();
+ if (NULL == info)
+ {
+ close_socket(ss);
+ }
+ else
+ {
+ info->ctrl_socket = ss;
+ if ((info->ctrl_fp = fdopen(info->ctrl_socket, "r+")) == NULL)
+ {
+ syslog(LOG_ERR, "ftpd: fdopen() on socket failed: %s", serr());
+ close_stream(info);
+ task_pool_release(info);
+ }
+ else
+ {
+ /* Initialize corresponding SessionInfo structure */
+ info->def_addr = addr;
+ if(0 > getsockname(ss, (struct sockaddr *)&addr, &addrLen))
+ {
+ syslog(LOG_ERR, "ftpd: getsockname(): %s", serr());
+ close_stream(info);
+ task_pool_release(info);
+ }
+ else
+ {
+ info->use_default = 1;
+ info->ctrl_addr = addr;
+ info->pasv_socket = -1;
+ info->data_socket = -1;
+ info->xfer_mode = TYPE_A;
+ info->data_addr.sin_port =
+ htons(ntohs(info->ctrl_addr.sin_port) - 1);
+ info->idle = ftpd_timeout;
+ /* Wakeup the session task. The task will call task_pool_release
+ after it closes connection. */
+ rtems_event_send(info->tid, FTPD_RTEMS_EVENT);
+ }
+ }
+ }
+ }
+ }
+ rtems_task_delete(RTEMS_SELF);
+}
+
+
+/*PAGE
+ *
+ * rtems_ftpd_start
+ *
+ * Here, we start the FTPD task which waits for FTP requests and services
+ * them. This procedure returns to its caller once the task is started.
+ *
+ *
+ * Input parameters:
+ *
+ * Output parameters:
+ * returns RTEMS_SUCCESSFUL on successful start of the daemon.
+ */
+int
+rtems_initialize_ftpd()
+{
+ rtems_status_code sc;
+ rtems_id tid;
+ rtems_task_priority priority;
+ int count;
+
+ if (rtems_ftpd_configuration.port == 0)
+ {
+ rtems_ftpd_configuration.port = FTPD_CONTROL_PORT;
+ }
+
+ if (rtems_ftpd_configuration.priority == 0)
+ {
+ rtems_ftpd_configuration.priority = 40;
+ }
+ priority = rtems_ftpd_configuration.priority;
+
+ ftpd_timeout = rtems_ftpd_configuration.idle;
+ if (ftpd_timeout < 0)
+ ftpd_timeout = 0;
+ rtems_ftpd_configuration.idle = ftpd_timeout;
+
+ ftpd_access = rtems_ftpd_configuration.access;
+
+ if (rtems_ftpd_configuration.tasks_count <= 0)
+ rtems_ftpd_configuration.tasks_count = 1;
+ count = rtems_ftpd_configuration.tasks_count;
+
+ if (!task_pool_init(count, priority))
+ {
+ syslog(LOG_ERR, "ftpd: Could not initialize task pool.");
+ return RTEMS_UNSATISFIED;
+ }
+
+ sc = rtems_task_create(rtems_build_name('F', 'T', 'P', 'D'),
+ priority, FTPD_STACKSIZE,
+ RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR |
+ RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
+ &tid);
+
+ if (sc == RTEMS_SUCCESSFUL)
+ {
+ sc = rtems_task_start(tid, daemon, 0);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_task_delete(tid);
+ }
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ task_pool_done(count);
+ syslog(LOG_ERR, "ftpd: Could not create/start FTP daemon: %s",
+ rtems_status_text(sc));
+ return RTEMS_UNSATISFIED;
+ }
+
+ ftpd_root = "/";
+ if (
+ rtems_ftpd_configuration.root &&
+ rtems_ftpd_configuration.root[0] == '/'
+ )
+ ftpd_root = rtems_ftpd_configuration.root;
+
+ rtems_ftpd_configuration.root = ftpd_root;
+
+ syslog(LOG_INFO, "ftpd: FTP daemon started (%d session%s max)",
+ count, ((count > 1) ? "s" : ""));
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/ftpd/ftpd.h b/cpukit/ftpd/ftpd.h
new file mode 100644
index 0000000000..445780452c
--- /dev/null
+++ b/cpukit/ftpd/ftpd.h
@@ -0,0 +1,56 @@
+/*
+ * FTP Server Information
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_FTPD_H
+#define _RTEMS_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)(char *, size_t);
+
+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 /* _RTEMS_FTPD_H */
diff --git a/cpukit/ftpd/preinstall.am b/cpukit/ftpd/preinstall.am
new file mode 100644
index 0000000000..cd99043c56
--- /dev/null
+++ b/cpukit/ftpd/preinstall.am
@@ -0,0 +1,25 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-local: $(TMPINSTALL_FILES)
+
+TMPINSTALL_FILES =
+CLEANFILES = $(TMPINSTALL_FILES)
+
+$(PROJECT_LIB)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_LIB)
+ @: > $(PROJECT_LIB)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
+
+if HAS_NETWORKING
+$(PROJECT_LIB)/libftpd.a: libftpd.a $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/libftpd.a
+TMPINSTALL_FILES += $(PROJECT_LIB)/libftpd.a
+endif
diff --git a/cpukit/httpd/.cvsignore b/cpukit/httpd/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/httpd/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/httpd/Makefile.am b/cpukit/httpd/Makefile.am
new file mode 100644
index 0000000000..a1aa779bf4
--- /dev/null
+++ b/cpukit/httpd/Makefile.am
@@ -0,0 +1,29 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+AM_CPPFLAGS += -DWEBS -DUEMF
+
+if HAS_NETWORKING
+if HAS_POSIX
+include_goaheaddir = $(includedir)/goahead
+
+include_HEADERS = rtems_webserver.h
+include_goahead_HEADERS = ej.h ejIntrn.h emfdb.h md5.h uemf.h um.h webs.h \
+ wsIntrn.h
+
+project_lib_LIBRARIES = libhttpd.a
+libhttpd_a_SOURCES = 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
+libhttpd_a_CPPFLAGS = $(AM_CPPFLAGS)
+endif
+endif
+
+EXTRA_DIST = webcomp.c webpage.c
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/httpd/NOTES b/cpukit/httpd/NOTES
new file mode 100644
index 0000000000..e2ef07eb34
--- /dev/null
+++ b/cpukit/httpd/NOTES
@@ -0,0 +1,36 @@
+#
+# $Id$
+#
+
+Notes on merging GoAhead Webs 2.1.4. 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.
+
+Porting
+=======
+ - added rtems complier flags to uemf.h and misc.c
+ - following source files are distributed with the web server
+ but not currently used by RTEMS
+ [cgi.c, sockGen.c, umui.c, websSSL.c, websda.c]
+
+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
+
diff --git a/cpukit/httpd/asp.c b/cpukit/httpd/asp.c
new file mode 100644
index 0000000000..7d20e683b7
--- /dev/null
+++ b/cpukit/httpd/asp.c
@@ -0,0 +1,321 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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;
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/balloc.c b/cpukit/httpd/balloc.c
new file mode 100644
index 0000000000..f43bc90acb
--- /dev/null
+++ b/cpukit/httpd/balloc.c
@@ -0,0 +1,967 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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
+
+#ifdef UEMF
+ #include "uemf.h"
+#else
+ #include "basic/basicInternal.h"
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+#ifndef NO_BALLOC
+/********************************* Defines ************************************/
+
+/*
+ * Define B_STATS if you wish to track memory block and stack usage
+ */
+#ifdef 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 *****************************/
+
+#ifdef 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 (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD))
+static void bFillBlock(void *buf, int bufsize);
+#endif
+
+#ifdef 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;
+
+#ifdef 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;
+ }
+#ifdef B_STATS
+ bStatsMemMalloc += bufsize;
+#endif
+ } else {
+ bFlags |= B_USER_BUF;
+ }
+
+ bFreeSize = bFreeLeft = bufsize;
+ bFreeBuf = bFreeNext = buf;
+ memset(bQhead, 0, sizeof(bQhead));
+#if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD))
+ bFillBlock(buf, bufsize);
+#endif
+#ifdef B_STATS
+ bStackStart = &buf;
+#endif
+#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD
+ verifyFreeBlock(buf, bufsize);
+#endif
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Close down the balloc module and free all malloced memory.
+ */
+
+void bclose()
+{
+#ifdef 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;
+ }
+ }
+#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD
+ verifyBallocSpace();
+#endif
+ if (size < 0) {
+ return NULL;
+ }
+
+#ifdef 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) {
+#ifdef 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;
+ }
+#ifdef B_STATS
+ bStatsMemMalloc += memSize;
+#endif
+#if (defined (B_FILL) || defined (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;
+#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD
+ verifyFreeBlock(bp, q);
+#endif
+#if (defined (B_FILL) || defined (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;
+#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD
+ verifyFreeBlock(bp, q);
+#endif
+ bFreeNext += memSize;
+ bFreeLeft -= memSize;
+#if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD))
+ bFillBlock(bp, memSize);
+#endif
+ bp->u.size = memSize - sizeof(bType);
+ bp->flags = 0;
+
+ } else if (bFlags & B_USE_MALLOC) {
+#ifdef 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;
+ }
+#ifdef B_STATS
+ bStatsMemMalloc += memSize;
+#endif
+#if (defined (B_FILL) || defined (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;
+ }
+ }
+
+#ifdef 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
+#ifdef 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;
+
+#ifdef 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);
+
+#ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD
+ verifyUsedBlock(bp,q);
+#endif
+#ifdef B_STATS
+ bStatsFree(B_ARGS, bp, q, bp->u.size+sizeof(bType));
+#endif
+ if (bp->flags & B_MALLOCED) {
+ free(bp);
+ return;
+ }
+
+#ifdef 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);
+ }
+}
+
+/******************************************************************************/
+#ifdef 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 (defined (B_FILL) || defined (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
+
+/******************************************************************************/
+#ifdef 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 */
+
+/******************************************************************************/
+#ifdef 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)
+{
+#ifdef 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 */
+/******************************************************************************/
diff --git a/cpukit/httpd/cgi.c b/cpukit/httpd/cgi.c
new file mode 100644
index 0000000000..c2328eab6e
--- /dev/null
+++ b/cpukit/httpd/cgi.c
@@ -0,0 +1,331 @@
+/*
+ * cgi.c -- CGI processing (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
+ *
+ * $Id$
+ */
+
+/********************************** Description *******************************/
+/*
+ * This module implements the /cgi-bin handler. CGI processing differs from
+ * goforms processing in that each CGI request is executed as a separate
+ * process, rather than within the webserver process. For each CGI request the
+ * environment of the new process must be set to include all the CGI variables
+ * and its standard input and output must be directed to the socket. This
+ * is done using temporary files.
+ */
+
+/*********************************** Includes *********************************/
+#include "wsIntrn.h"
+#ifdef UEMF
+ #include "uemf.h"
+#else
+ #include "basic/basicInternal.h"
+#endif
+
+/************************************ Locals **********************************/
+typedef struct { /* Struct for CGI tasks which have completed */
+ webs_t wp; /* pointer to session websRec */
+ char_t *stdIn; /* file desc. for task's temp input fd */
+ char_t *stdOut; /* file desc. for task's temp output fd */
+ char_t *cgiPath; /* path to executable process file */
+ char_t **argp; /* pointer to buf containing argv tokens */
+ char_t **envp; /* pointer to array of environment strings */
+ int handle; /* process handle of the task */
+ long fplacemark; /* seek location for CGI output file */
+} cgiRec;
+static cgiRec **cgiList; /* hAlloc chain list of wp's to be closed */
+static int cgiMax; /* Size of hAlloc list */
+
+/************************************* Code ***********************************/
+
+/*
+ * Process a form request. Returns 1 always to indicate it handled the URL
+ */
+int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
+ char_t *url, char_t *path, char_t* query)
+{
+ cgiRec *cgip;
+ sym_t *s;
+ char_t cgiBuf[FNAMESIZE], *stdIn, *stdOut, cwd[FNAMESIZE];
+ char_t *cp, *cgiName, *cgiPath, **argp, **envp, **ep;
+ int n, envpsize, argpsize, pHandle, cid;
+ a_assert(websValid(wp));
+ a_assert(url && *url);
+ a_assert(path && *path == '/');
+ websStats.cgiHits++;
+/*
+ * Extract the form name and then build the full path name. The form
+ * name will follow the first '/' in path.
+ */
+ gstrncpy(cgiBuf, path, TSZ(cgiBuf));
+ if ((cgiName = gstrchr(&cgiBuf[1], '/')) == NULL) {
+ websError(wp, 200, T("Missing CGI name"));
+ return 1;
+ }
+ cgiName++;
+ if ((cp = gstrchr(cgiName, '/')) != NULL) {
+ *cp = '\0';
+ }
+ fmtAlloc(&cgiPath, FNAMESIZE, T("%s/%s/%s"), websGetDefaultDir(),
+ CGI_BIN, cgiName);
+#ifndef VXWORKS
+/*
+ * See if the file exists and is executable. If not error out.
+ * Don't do this step for VxWorks, since the module may already
+ * be part of the OS image, rather than in the file system.
+ */
+ {
+ gstat_t sbuf;
+ if (gstat(cgiPath, &sbuf) != 0 || (sbuf.st_mode & S_IFREG) == 0) {
+ websError(wp, 200, T("CGI process file does not exist"));
+ bfree(B_L, cgiPath);
+ return 1;
+ }
+#if (defined (WIN) || defined (CE))
+ if (gstrstr(cgiPath, T(".exe")) == NULL &&
+ gstrstr(cgiPath, T(".bat")) == NULL) {
+#elif (defined (NW))
+ if (gstrstr(cgiPath, T(".nlm")) == NULL) {
+#else
+ if (gaccess(cgiPath, X_OK) != 0) {
+#endif /* WIN || CE */
+ websError(wp, 200, T("CGI process file is not executable"));
+ bfree(B_L, cgiPath);
+ return 1;
+ }
+ }
+#endif /* ! VXWORKS */
+
+
+/*
+ * Get the CWD for resetting after launching the child process CGI
+ */
+ ggetcwd(cwd, FNAMESIZE);
+/*
+ * Retrieve the directory of the child process CGI
+ */
+ if ((cp = gstrrchr(cgiPath, '/')) != NULL) {
+ *cp = '\0';
+ gchdir(cgiPath);
+ *cp = '/';
+ }
+/*
+ * Build command line arguments. Only used if there is no non-encoded
+ * = character. This is indicative of a ISINDEX query. POST separators
+ * are & and others are +. argp will point to a balloc'd array of
+ * pointers. Each pointer will point to substring within the
+ * query string. This array of string pointers is how the spawn or
+ * exec routines expect command line arguments to be passed. Since
+ * we don't know ahead of time how many individual items there are in
+ * the query string, the for loop includes logic to grow the array
+ * size via brealloc.
+ */
+ argpsize = 10;
+ argp = balloc(B_L, argpsize * sizeof(char_t *));
+ *argp = cgiPath;
+ n = 1;
+ if (gstrchr(query, '=') == NULL) {
+ websDecodeUrl(query, query, gstrlen(query));
+ for (cp = gstrtok(query, T(" ")); cp != NULL; ) {
+ *(argp+n) = cp;
+ n++;
+ if (n >= argpsize) {
+ argpsize *= 2;
+ argp = brealloc(B_L, argp, argpsize * sizeof(char_t *));
+ }
+ cp = gstrtok(NULL, T(" "));
+ }
+ }
+ *(argp+n) = NULL;
+/*
+ * Add all CGI variables to the environment strings to be passed
+ * to the spawned CGI process. This includes a few we don't
+ * already have in the symbol table, plus all those that are in
+ * the cgiVars symbol table. envp will point to a balloc'd array of
+ * pointers. Each pointer will point to a balloc'd string containing
+ * the keyword value pair in the form keyword=value. Since we don't
+ * know ahead of time how many environment strings there will be the
+ * for loop includes logic to grow the array size via brealloc.
+ */
+ envpsize = WEBS_SYM_INIT;
+ envp = balloc(B_L, envpsize * sizeof(char_t *));
+ n = 0;
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("PATH_TRANSLATED"), cgiPath);
+ n++;
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s/%s"),T("SCRIPT_NAME"),
+ CGI_BIN, cgiName);
+ n++;
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("REMOTE_USER"), wp->userName);
+ n++;
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("AUTH_TYPE"), wp->authType);
+ n++;
+ for (s = symFirst(wp->cgiVars); s != NULL; s = symNext(wp->cgiVars)) {
+ if (s->content.valid && s->content.type == string &&
+ gstrcmp(s->name.value.string, T("REMOTE_HOST")) != 0 &&
+ gstrcmp(s->name.value.string, T("HTTP_AUTHORIZATION")) != 0) {
+ fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), s->name.value.string,
+ s->content.value.string);
+ n++;
+ if (n >= envpsize) {
+ envpsize *= 2;
+ envp = brealloc(B_L, envp, envpsize * sizeof(char_t *));
+ }
+ }
+ }
+ *(envp+n) = NULL;
+/*
+ * Create temporary file name(s) for the child's stdin and stdout.
+ * For POST data the stdin temp file (and name) should already exist.
+ */
+ if (wp->cgiStdin == NULL) {
+ wp->cgiStdin = websGetCgiCommName();
+ }
+ stdIn = wp->cgiStdin;
+ stdOut = websGetCgiCommName();
+/*
+ * Now launch the process. If not successful, do the cleanup of resources.
+ * If successful, the cleanup will be done after the process completes.
+ */
+ if ((pHandle = websLaunchCgiProc(cgiPath, argp, envp, stdIn, stdOut))
+ == -1) {
+ websError(wp, 200, T("failed to spawn CGI task"));
+ for (ep = envp; *ep != NULL; ep++) {
+ bfreeSafe(B_L, *ep);
+ }
+ bfreeSafe(B_L, cgiPath);
+ bfreeSafe(B_L, argp);
+ bfreeSafe(B_L, envp);
+ bfreeSafe(B_L, stdOut);
+ } else {
+/*
+ * If the spawn was successful, put this wp on a queue to be
+ * checked for completion.
+ */
+ cid = hAllocEntry((void***) &cgiList, &cgiMax, sizeof(cgiRec));
+ cgip = cgiList[cid];
+ cgip->handle = pHandle;
+ cgip->stdIn = stdIn;
+ cgip->stdOut = stdOut;
+ cgip->cgiPath = cgiPath;
+ cgip->argp = argp;
+ cgip->envp = envp;
+ cgip->wp = wp;
+ cgip->fplacemark = 0;
+ websTimeoutCancel(wp);
+ }
+/*
+ * Restore the current working directory after spawning child CGI
+ */
+ gchdir(cwd);
+ return 1;
+}
+
+
+
+/******************************************************************************/
+/*
+ * Any entry in the cgiList need to be checked to see if it has
+ */
+void websCgiGatherOutput (cgiRec *cgip)
+{
+ gstat_t sbuf;
+ char_t cgiBuf[FNAMESIZE];
+ if ((gstat(cgip->stdOut, &sbuf) == 0) &&
+ (sbuf.st_size > cgip->fplacemark)) {
+ int fdout;
+ fdout = gopen(cgip->stdOut, O_RDONLY | O_BINARY, 0444 );
+/*
+ * Check to see if any data is available in the
+ * output file and send its contents to the socket.
+ */
+ if (fdout >= 0) {
+ webs_t wp = cgip->wp;
+ int nRead;
+/*
+ * Write the HTTP header on our first pass
+ */
+ if (cgip->fplacemark == 0) {
+ websWrite(wp, T("HTTP/1.0 200 OK\r\n"));
+ }
+ glseek(fdout, cgip->fplacemark, SEEK_SET);
+ while ((nRead = gread(fdout, cgiBuf, FNAMESIZE)) > 0) {
+ websWriteBlock(wp, cgiBuf, nRead);
+ cgip->fplacemark += nRead;
+ }
+ gclose(fdout);
+ }
+ }
+}
+
+
+
+/******************************************************************************/
+/*
+ * Any entry in the cgiList need to be checked to see if it has
+ * completed, and if so, process its output and clean up.
+ */
+void websCgiCleanup()
+{
+ cgiRec *cgip;
+ webs_t wp;
+ char_t **ep;
+ int cid, nTries;
+ for (cid = 0; cid < cgiMax; cid++) {
+ if ((cgip = cgiList[cid]) != NULL) {
+ wp = cgip->wp;
+ websCgiGatherOutput (cgip);
+ if (websCheckCgiProc(cgip->handle) == 0) {
+/*
+ * We get here if the CGI process has terminated. Clean up.
+ */
+ nTries = 0;
+/*
+ * Make sure we didn't miss something during a task switch.
+ * Maximum wait is 100 times 10 msecs (1 second).
+ */
+ while ((cgip->fplacemark == 0) && (nTries < 100)) {
+ websCgiGatherOutput(cgip);
+/*
+ * There are some cases when we detect app exit
+ * before the file is ready.
+ */
+ if (cgip->fplacemark == 0) {
+#ifdef WIN
+ Sleep(10);
+#endif /* WIN*/
+ }
+ nTries++;
+ }
+ if (cgip->fplacemark == 0) {
+ websError(wp, 200, T("CGI generated no output"));
+ } else {
+ websDone(wp, 200);
+ }
+/*
+ * Remove the temporary re-direction files
+ */
+ gunlink(cgip->stdIn);
+ gunlink(cgip->stdOut);
+/*
+ * Free all the memory buffers pointed to by cgip.
+ * The stdin file name (wp->cgiStdin) gets freed as
+ * part of websFree().
+ */
+ cgiMax = hFree((void***) &cgiList, cid);
+ for (ep = cgip->envp; ep != NULL && *ep != NULL; ep++) {
+ bfreeSafe(B_L, *ep);
+ }
+ bfreeSafe(B_L, cgip->cgiPath);
+ bfreeSafe(B_L, cgip->argp);
+ bfreeSafe(B_L, cgip->envp);
+ bfreeSafe(B_L, cgip->stdOut);
+ bfreeSafe(B_L, cgip);
+ }
+ }
+ }
+}
+/******************************************************************************/
diff --git a/cpukit/httpd/default.c b/cpukit/httpd/default.c
new file mode 100644
index 0000000000..2dfb2f70b2
--- /dev/null
+++ b/cpukit/httpd/default.c
@@ -0,0 +1,431 @@
+/*
+ * 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++;
+#ifdef 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;
+
+ /*
+ * 22 Jul 02 -- there were reports that a directory traversal exploit was
+ * possible in the WebServer running under Windows if directory paths
+ * outside the server's specified root web were given by URL-encoding the
+ * backslash character, like:
+ *
+ * GoAhead is vulnerable to a directory traversal bug. A request such as
+ *
+ * GoAhead-server/../../../../../../../ results in an error message
+ * 'Cannot open URL'.
+
+ * However, by encoding the '/' character, it is possible to break out of
+ * the
+ * web root and read arbitrary files from the server.
+ * Hence a request like:
+ *
+ * GoAhead-server/..%5C..%5C..%5C..%5C..%5C..%5C/winnt/win.ini returns the
+ * contents of the win.ini file.
+ * (Note that the description uses forward slashes (0x2F), but the example
+ * uses backslashes (0x5C). In my tests, forward slashes are correctly
+ * trapped, but backslashes are not. The code below substitutes forward
+ * slashes for backslashes before attempting to validate that there are no
+ * unauthorized paths being accessed.
+ */
+ token = gstrchr(path, '\\');
+ while (token != NULL)
+ {
+ *token = '/';
+ token = gstrchr(token, '\\');
+ }
+
+ 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);
+
+ websSetTimeMark(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);
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/ej.h b/cpukit/httpd/ej.h
new file mode 100644
index 0000000000..879dae91a7
--- /dev/null
+++ b/cpukit/httpd/ej.h
@@ -0,0 +1,46 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+#ifndef _h_EJ
+#define _h_EJ 1
+
+/******************************** Description *********************************/
+
+/*
+ * GoAhead Ejscript(TM) header. This defines the Ejscript API and internal
+ * structures.
+ */
+
+/********************************* Includes ***********************************/
+
+#ifndef 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 */
+
+/*****************************************************************************/
diff --git a/cpukit/httpd/ejIntrn.h b/cpukit/httpd/ejIntrn.h
new file mode 100644
index 0000000000..401da17891
--- /dev/null
+++ b/cpukit/httpd/ejIntrn.h
@@ -0,0 +1,230 @@
+/*
+ * ejIntrn.h -- Ejscript(TM) header
+ *
+ * Copyright (c) GoAhead Software, Inc., 1992-2000
+ *
+ * See the file "license.txt" for information on usage and redistribution
+ *
+ * $Id$
+ */
+
+#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>
+
+#ifdef CE
+#ifndef UEMF
+ #include <io.h>
+#endif
+#endif
+
+#ifdef LYNX
+ #include <unistd.h>
+#endif
+
+#ifdef QNX4
+ #include <dirent.h>
+#endif
+
+#ifdef 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 */
diff --git a/cpukit/httpd/ejlex.c b/cpukit/httpd/ejlex.c
new file mode 100644
index 0000000000..45181d9d83
--- /dev/null
+++ b/cpukit/httpd/ejlex.c
@@ -0,0 +1,721 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** Description *********************************/
+
+/*
+ * Ejscript lexical analyser. This implementes a lexical analyser for a
+ * a subset of the JavaScript language.
+ */
+
+/********************************** Includes **********************************/
+
+#include "ejIntrn.h"
+
+#ifdef 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);
+ /*
+ * commented out 04 Apr 02 Bg Porter -- we found a case where very long
+ * arguments to write() were being corrupted downstream in the trace call
+ * (the ep->token pointer was being overwritten with the trace message.
+ * restore this if it's useful for your debugging.
+ 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;
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/ejparse.c b/cpukit/httpd/ejparse.c
new file mode 100644
index 0000000000..fdbb9c1d8a
--- /dev/null
+++ b/cpukit/httpd/ejparse.c
@@ -0,0 +1,1804 @@
+/*
+ * ejparse.c -- Ejscript(TM) Parser
+ *
+ * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
+ *
+ * See the file "license.txt" for usage and redistribution license requirements
+ *
+ * $Id$
+ */
+
+/******************************** Description *********************************/
+
+/*
+ * Ejscript parser. This implementes a subset of the JavaScript language.
+ * Multiple Ejscript parsers can be opened at a time.
+ */
+
+/********************************** Includes **********************************/
+
+#include "ejIntrn.h"
+
+#ifdef CE
+ #include "CE/wincompat.h"
+#endif
+
+/********************************** Local Data ********************************/
+
+ej_t **ejHandles; /* List of ej handles */
+int ejMax = -1; /* Maximum size of */
+
+/****************************** Forward Declarations **************************/
+
+#ifndef B_STATS
+#define setString(a,b,c) setstring(b,c)
+#endif
+
+static ej_t *ejPtr(int eid);
+static void clearString(char_t **ptr);
+static void setString(B_ARGS_DEC, char_t **ptr, char_t *s);
+static void appendString(char_t **ptr, char_t *s);
+static int parse(ej_t *ep, int state, int flags);
+static int parseStmt(ej_t *ep, int state, int flags);
+static int parseDeclaration(ej_t *ep, int state, int flags);
+static int parseArgs(ej_t *ep, int state, int flags);
+static int parseCond(ej_t *ep, int state, int flags);
+static int parseExpr(ej_t *ep, int state, int flags);
+static int evalExpr(ej_t *ep, char_t *lhs, int rel, char_t *rhs);
+static int evalCond(ej_t *ep, char_t *lhs, int rel, char_t *rhs);
+static int evalFunction(ej_t *ep);
+static void freeFunc(ejfunc_t *func);
+static void ejRemoveNewlines(ej_t *ep, int state);
+
+/************************************* Code ***********************************/
+/*
+ * Initialize a Ejscript engine
+ */
+
+int ejOpenEngine(sym_fd_t variables, sym_fd_t functions)
+{
+ ej_t *ep;
+ int eid, vid;
+
+ if ((eid = hAllocEntry((void*) &ejHandles, &ejMax, sizeof(ej_t))) < 0) {
+ return -1;
+ }
+ ep = ejHandles[eid];
+ ep->eid = eid;
+
+/*
+ * Create a top level symbol table if one is not provided for variables and
+ * functions. Variables may create other symbol tables for block level
+ * declarations so we use hAlloc to manage a list of variable tables.
+ */
+ if ((vid = hAlloc((void***) &ep->variables)) < 0) {
+ ejMax = hFree((void*) &ejHandles, ep->eid);
+ return -1;
+ }
+ if (vid >= ep->variableMax) {
+ ep->variableMax = vid + 1;
+ }
+
+ if (variables == -1) {
+ ep->variables[vid] = symOpen(64) + EJ_OFFSET;
+ ep->flags |= FLAGS_VARIABLES;
+ } else {
+ ep->variables[vid] = variables + EJ_OFFSET;
+ }
+
+ if (functions == -1) {
+ ep->functions = symOpen(64);
+ ep->flags |= FLAGS_FUNCTIONS;
+ } else {
+ ep->functions = functions;
+ }
+
+ ejLexOpen(ep);
+
+/*
+ * Define standard constants
+ */
+ ejSetGlobalVar(ep->eid, T("null"), NULL);
+
+#ifdef EMF
+ ejEmfOpen(ep->eid);
+#endif
+ return ep->eid;
+}
+
+/******************************************************************************/
+/*
+ * Close
+ */
+
+void ejCloseEngine(int eid)
+{
+ ej_t *ep;
+ int i;
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return;
+ }
+
+#ifdef EMF
+ ejEmfClose(eid);
+#endif
+
+ bfreeSafe(B_L, ep->error);
+ ep->error = NULL;
+ bfreeSafe(B_L, ep->result);
+ ep->result = NULL;
+
+ ejLexClose(ep);
+
+ for (i = ep->variableMax - 1; i >= 0; i--) {
+ if (ep->flags & FLAGS_VARIABLES) {
+ symClose(ep->variables[i] - EJ_OFFSET);
+ }
+ ep->variableMax = hFree((void***) &ep->variables, i);
+ }
+
+ if (ep->flags & FLAGS_FUNCTIONS) {
+ symClose(ep->functions);
+ }
+
+ ejMax = hFree((void*) &ejHandles, ep->eid);
+ bfree(B_L, ep);
+}
+
+#ifndef __NO_EJ_FILE
+/******************************************************************************/
+/*
+ * Evaluate a Ejscript file
+ */
+
+char_t *ejEvalFile(int eid, char_t *path, char_t **emsg)
+{
+ gstat_t sbuf;
+ ej_t *ep;
+ char_t *script, *rs;
+ char *fileBuf;
+ int fd;
+
+ a_assert(path && *path);
+
+ if (emsg) {
+ *emsg = NULL;
+ }
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return NULL;
+ }
+
+ if ((fd = gopen(path, O_RDONLY | O_BINARY, 0666)) < 0) {
+ ejError(ep, T("Bad handle %d"), eid);
+ return NULL;
+ }
+
+ if (gstat(path, &sbuf) < 0) {
+ gclose(fd);
+ ejError(ep, T("Cant stat %s"), path);
+ return NULL;
+ }
+
+ if ((fileBuf = balloc(B_L, sbuf.st_size + 1)) == NULL) {
+ gclose(fd);
+ ejError(ep, T("Cant malloc %d"), sbuf.st_size);
+ return NULL;
+ }
+
+ if (gread(fd, fileBuf, sbuf.st_size) != (int)sbuf.st_size) {
+ gclose(fd);
+ bfree(B_L, fileBuf);
+ ejError(ep, T("Error reading %s"), path);
+ return NULL;
+ }
+
+ fileBuf[sbuf.st_size] = '\0';
+ gclose(fd);
+
+ if ((script = ballocAscToUni(fileBuf, sbuf.st_size)) == NULL) {
+ bfree(B_L, fileBuf);
+ ejError(ep, T("Cant malloc %d"), sbuf.st_size + 1);
+ return NULL;
+ }
+ bfree(B_L, fileBuf);
+
+ rs = ejEvalBlock(eid, script, emsg);
+
+ bfree(B_L, script);
+ return rs;
+}
+#endif /* __NO_EJ_FILE */
+
+/******************************************************************************/
+/*
+ * Create a new variable scope block so that consecutive ejEval calls may
+ * be made with the same varible scope. This space MUST be closed with
+ * ejCloseBlock when the evaluations are complete.
+ */
+
+int ejOpenBlock(int eid)
+{
+ ej_t *ep;
+ int vid;
+
+ if((ep = ejPtr(eid)) == NULL) {
+ return -1;
+ }
+
+ if ((vid = hAlloc((void***) &ep->variables)) < 0) {
+ return -1;
+ }
+
+ if (vid >= ep->variableMax) {
+ ep->variableMax = vid + 1;
+ }
+ ep->variables[vid] = symOpen(64) + EJ_OFFSET;
+ return vid;
+
+}
+
+/******************************************************************************/
+/*
+ * Close a variable scope block. The vid parameter is the return value from
+ * the call to ejOpenBlock
+ */
+
+int ejCloseBlock(int eid, int vid)
+{
+ ej_t *ep;
+
+ if((ep = ejPtr(eid)) == NULL) {
+ return -1;
+ }
+ symClose(ep->variables[vid] - EJ_OFFSET);
+ ep->variableMax = hFree((void***) &ep->variables, vid);
+ return 0;
+
+}
+
+/******************************************************************************/
+/*
+ * Create a new variable scope block and evaluate a script. All variables
+ * created during this context will be automatically deleted when complete.
+ */
+
+char_t *ejEvalBlock(int eid, char_t *script, char_t **emsg)
+{
+ char_t* returnVal;
+ int vid;
+
+ a_assert(script);
+
+ vid = ejOpenBlock(eid);
+ returnVal = ejEval(eid, script, emsg);
+ ejCloseBlock(eid, vid);
+
+ return returnVal;
+}
+
+/******************************************************************************/
+/*
+ * Parse and evaluate a Ejscript. The caller may provide a symbol table to
+ * use for variables and function definitions. Return char_t pointer on
+ * success otherwise NULL pointer is returned.
+ */
+
+char_t *ejEval(int eid, char_t *script, char_t **emsg)
+{
+ ej_t *ep;
+ ejinput_t *oldBlock;
+ int state;
+ void *endlessLoopTest;
+ int loopCounter;
+
+
+ a_assert(script);
+
+ if (emsg) {
+ *emsg = NULL;
+ }
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return NULL;
+ }
+
+ setString(B_L, &ep->result, T(""));
+
+/*
+ * Allocate a new evaluation block, and save the old one
+ */
+ oldBlock = ep->input;
+ ejLexOpenScript(ep, script);
+
+/*
+ * Do the actual parsing and evaluation
+ */
+ loopCounter = 0;
+ endlessLoopTest = NULL;
+
+ do {
+ state = parse(ep, STATE_BEGIN, FLAGS_EXE);
+
+ if (state == STATE_RET) {
+ state = STATE_EOF;
+ }
+/*
+ * prevent parser from going into infinite loop. If parsing the same
+ * line 10 times then fail and report Syntax error. Most normal error
+ * are caught in the parser itself.
+ */
+ if (endlessLoopTest == ep->input->script.servp) {
+ if (loopCounter++ > 10) {
+ state = STATE_ERR;
+ ejError(ep, T("Syntax error"));
+ }
+ } else {
+ endlessLoopTest = ep->input->script.servp;
+ loopCounter = 0;
+ }
+ } while (state != STATE_EOF && state != STATE_ERR);
+
+ ejLexCloseScript(ep);
+
+/*
+ * Return any error string to the user
+ */
+ if (state == STATE_ERR && emsg) {
+ *emsg = bstrdup(B_L, ep->error);
+ }
+
+/*
+ * Restore the old evaluation block
+ */
+ ep->input = oldBlock;
+
+ if (state == STATE_EOF) {
+ return ep->result;
+ }
+
+ if (state == STATE_ERR) {
+ return NULL;
+ }
+
+ return ep->result;
+}
+
+/******************************************************************************/
+/*
+ * Recursive descent parser for Ejscript
+ */
+
+static int parse(ej_t *ep, int state, int flags)
+{
+ a_assert(ep);
+
+ switch (state) {
+/*
+ * Any statement, function arguments or conditional expressions
+ */
+ case STATE_STMT:
+ if ((state = parseStmt(ep, state, flags)) != STATE_STMT_DONE &&
+ state != STATE_EOF && state != STATE_STMT_BLOCK_DONE &&
+ state != STATE_RET) {
+ state = STATE_ERR;
+ }
+ break;
+
+ case STATE_DEC:
+ if ((state = parseStmt(ep, state, flags)) != STATE_DEC_DONE &&
+ state != STATE_EOF) {
+ state = STATE_ERR;
+ }
+ break;
+
+ case STATE_EXPR:
+ if ((state = parseStmt(ep, state, flags)) != STATE_EXPR_DONE &&
+ state != STATE_EOF) {
+ state = STATE_ERR;
+ }
+ break;
+
+/*
+ * Variable declaration list
+ */
+ case STATE_DEC_LIST:
+ state = parseDeclaration(ep, state, flags);
+ break;
+
+/*
+ * Function argument string
+ */
+ case STATE_ARG_LIST:
+ state = parseArgs(ep, state, flags);
+ break;
+
+/*
+ * Logical condition list (relational operations separated by &&, ||)
+ */
+ case STATE_COND:
+ state = parseCond(ep, state, flags);
+ break;
+
+/*
+ * Expression list
+ */
+ case STATE_RELEXP:
+ state = parseExpr(ep, state, flags);
+ break;
+ }
+
+ if (state == STATE_ERR && ep->error == NULL) {
+ ejError(ep, T("Syntax error"));
+ }
+ return state;
+}
+
+/******************************************************************************/
+/*
+ * Parse any statement including functions and simple relational operations
+ */
+
+static int parseStmt(ej_t *ep, int state, int flags)
+{
+ ejfunc_t func;
+ ejfunc_t *saveFunc;
+ ejinput_t condScript, endScript, bodyScript, incrScript;
+ char_t *value, *identifier;
+ int done, expectSemi, thenFlags, elseFlags, tid, cond, forFlags;
+ int ejVarType;
+
+ a_assert(ep);
+
+/*
+ * Set these to NULL, else we try to free them if an error occurs.
+ */
+ endScript.putBackToken = NULL;
+ bodyScript.putBackToken = NULL;
+ incrScript.putBackToken = NULL;
+ condScript.putBackToken = NULL;
+
+ expectSemi = 0;
+ saveFunc = NULL;
+
+ for (done = 0; !done; ) {
+ tid = ejLexGetToken(ep, state);
+
+ switch (tid) {
+ default:
+ ejLexPutbackToken(ep, TOK_EXPR, ep->token);
+ done++;
+ break;
+
+ case TOK_ERR:
+ state = STATE_ERR;
+ done++;
+ break;
+
+ case TOK_EOF:
+ state = STATE_EOF;
+ done++;
+ break;
+
+ case TOK_NEWLINE:
+ break;
+
+ case TOK_SEMI:
+/*
+ * This case is when we discover no statement and just a lone ';'
+ */
+ if (state != STATE_STMT) {
+ ejLexPutbackToken(ep, tid, ep->token);
+ }
+ done++;
+ break;
+
+ case TOK_ID:
+/*
+ * This could either be a reference to a variable or an assignment
+ */
+ identifier = NULL;
+ setString(B_L, &identifier, ep->token);
+/*
+ * Peek ahead to see if this is an assignment
+ */
+ tid = ejLexGetToken(ep, state);
+ if (tid == TOK_ASSIGNMENT) {
+ if (parse(ep, STATE_RELEXP, flags) != STATE_RELEXP_DONE) {
+ clearString(&identifier);
+ goto error;
+ }
+ if (flags & FLAGS_EXE) {
+ if ( state == STATE_DEC ) {
+ ejSetLocalVar(ep->eid, identifier, ep->result);
+ } else {
+ ejVarType = ejGetVar(ep->eid, identifier, &value);
+ if (ejVarType > 0) {
+ ejSetLocalVar(ep->eid, identifier, ep->result);
+ } else {
+ ejSetGlobalVar(ep->eid, identifier, ep->result);
+ }
+ }
+ }
+
+ } else if (tid == TOK_INC_DEC ) {
+ value = NULL;
+ if (flags & FLAGS_EXE) {
+ ejVarType = ejGetVar(ep->eid, identifier, &value);
+ if (ejVarType < 0) {
+ ejError(ep, T("Undefined variable %s\n"), identifier);
+ goto error;
+ }
+ setString(B_L, &ep->result, value);
+ if (evalExpr(ep, value, (int) *ep->token, T("1")) < 0) {
+ state = STATE_ERR;
+ break;
+ }
+
+ if (ejVarType > 0) {
+ ejSetLocalVar(ep->eid, identifier, ep->result);
+ } else {
+ ejSetGlobalVar(ep->eid, identifier, ep->result);
+ }
+ }
+
+ } else {
+/*
+ * If we are processing a declaration, allow undefined vars
+ */
+ value = NULL;
+ if (state == STATE_DEC) {
+ if (ejGetVar(ep->eid, identifier, &value) > 0) {
+ ejError(ep, T("Variable already declared"),
+ identifier);
+ clearString(&identifier);
+ goto error;
+ }
+ ejSetLocalVar(ep->eid, identifier, NULL);
+ } else {
+ if ( flags & FLAGS_EXE ) {
+ if (ejGetVar(ep->eid, identifier, &value) < 0) {
+ ejError(ep, T("Undefined variable %s\n"),
+ identifier);
+ clearString(&identifier);
+ goto error;
+ }
+ }
+ }
+ setString(B_L, &ep->result, value);
+ ejLexPutbackToken(ep, tid, ep->token);
+ }
+ clearString(&identifier);
+
+ if (state == STATE_STMT) {
+ expectSemi++;
+ }
+ done++;
+ break;
+
+ case TOK_LITERAL:
+/*
+ * Set the result to the literal (number or string constant)
+ */
+ setString(B_L, &ep->result, ep->token);
+ if (state == STATE_STMT) {
+ expectSemi++;
+ }
+ done++;
+ break;
+
+ case TOK_FUNCTION:
+/*
+ * We must save any current ep->func value for the current stack frame
+ */
+ if (ep->func) {
+ saveFunc = ep->func;
+ }
+ memset(&func, 0, sizeof(ejfunc_t));
+ setString(B_L, &func.fname, ep->token);
+ ep->func = &func;
+
+ setString(B_L, &ep->result, T(""));
+ if (ejLexGetToken(ep, state) != TOK_LPAREN) {
+ freeFunc(&func);
+ goto error;
+ }
+
+ if (parse(ep, STATE_ARG_LIST, flags) != STATE_ARG_LIST_DONE) {
+ freeFunc(&func);
+ ep->func = saveFunc;
+ goto error;
+ }
+/*
+ * Evaluate the function if required
+ */
+ if (flags & FLAGS_EXE && evalFunction(ep) < 0) {
+ freeFunc(&func);
+ ep->func = saveFunc;
+ goto error;
+ }
+
+ freeFunc(&func);
+ ep->func = saveFunc;
+
+ if (ejLexGetToken(ep, state) != TOK_RPAREN) {
+ goto error;
+ }
+ if (state == STATE_STMT) {
+ expectSemi++;
+ }
+ done++;
+ break;
+
+ case TOK_IF:
+ if (state != STATE_STMT) {
+ goto error;
+ }
+ if (ejLexGetToken(ep, state) != TOK_LPAREN) {
+ goto error;
+ }
+/*
+ * Evaluate the entire condition list "(condition)"
+ */
+ if (parse(ep, STATE_COND, flags) != STATE_COND_DONE) {
+ goto error;
+ }
+ if (ejLexGetToken(ep, state) != TOK_RPAREN) {
+ goto error;
+ }
+/*
+ * This is the "then" case. We need to always parse both cases and
+ * execute only the relevant case.
+ */
+ if (*ep->result == '1') {
+ thenFlags = flags;
+ elseFlags = flags & ~FLAGS_EXE;
+ } else {
+ thenFlags = flags & ~FLAGS_EXE;
+ elseFlags = flags;
+ }
+/*
+ * Process the "then" case. Allow for RETURN statement
+ */
+ switch (parse(ep, STATE_STMT, thenFlags)) {
+ case STATE_RET:
+ return STATE_RET;
+ case STATE_STMT_DONE:
+ break;
+ default:
+ goto error;
+ }
+/*
+ * check to see if there is an "else" case
+ */
+ ejRemoveNewlines(ep, state);
+ tid = ejLexGetToken(ep, state);
+ if (tid != TOK_ELSE) {
+ ejLexPutbackToken(ep, tid, ep->token);
+ done++;
+ break;
+ }
+/*
+ * Process the "else" case. Allow for return.
+ */
+ switch (parse(ep, STATE_STMT, elseFlags)) {
+ case STATE_RET:
+ return STATE_RET;
+ case STATE_STMT_DONE:
+ break;
+ default:
+ goto error;
+ }
+ done++;
+ break;
+
+ case TOK_FOR:
+/*
+ * Format for the expression is:
+ *
+ * for (initial; condition; incr) {
+ * body;
+ * }
+ */
+ if (state != STATE_STMT) {
+ goto error;
+ }
+ if (ejLexGetToken(ep, state) != TOK_LPAREN) {
+ goto error;
+ }
+
+/*
+ * Evaluate the for loop initialization statement
+ */
+ if (parse(ep, STATE_EXPR, flags) != STATE_EXPR_DONE) {
+ goto error;
+ }
+ if (ejLexGetToken(ep, state) != TOK_SEMI) {
+ goto error;
+ }
+
+/*
+ * The first time through, we save the current input context just
+ * to each step: prior to the conditional, the loop increment and the
+ * loop body.
+ */
+ ejLexSaveInputState(ep, &condScript);
+ if (parse(ep, STATE_COND, flags) != STATE_COND_DONE) {
+ goto error;
+ }
+ cond = (*ep->result != '0');
+
+ if (ejLexGetToken(ep, state) != TOK_SEMI) {
+ goto error;
+ }
+
+/*
+ * Don't execute the loop increment statement or the body first time
+ */
+ forFlags = flags & ~FLAGS_EXE;
+ ejLexSaveInputState(ep, &incrScript);
+ if (parse(ep, STATE_EXPR, forFlags) != STATE_EXPR_DONE) {
+ goto error;
+ }
+ if (ejLexGetToken(ep, state) != TOK_RPAREN) {
+ goto error;
+ }
+
+/*
+ * Parse the body and remember the end of the body script
+ */
+ ejLexSaveInputState(ep, &bodyScript);
+ if (parse(ep, STATE_STMT, forFlags) != STATE_STMT_DONE) {
+ goto error;
+ }
+ ejLexSaveInputState(ep, &endScript);
+
+/*
+ * Now actually do the for loop. Note loop has been rotated
+ */
+ while (cond && (flags & FLAGS_EXE) ) {
+/*
+ * Evaluate the body
+ */
+ ejLexRestoreInputState(ep, &bodyScript);
+
+ switch (parse(ep, STATE_STMT, flags)) {
+ case STATE_RET:
+ return STATE_RET;
+ case STATE_STMT_DONE:
+ break;
+ default:
+ goto error;
+ }
+/*
+ * Evaluate the increment script
+ */
+ ejLexRestoreInputState(ep, &incrScript);
+ if (parse(ep, STATE_EXPR, flags) != STATE_EXPR_DONE) {
+ goto error;
+ }
+/*
+ * Evaluate the condition
+ */
+ ejLexRestoreInputState(ep, &condScript);
+ if (parse(ep, STATE_COND, flags) != STATE_COND_DONE) {
+ goto error;
+ }
+ cond = (*ep->result != '0');
+ }
+ ejLexRestoreInputState(ep, &endScript);
+ done++;
+ break;
+
+ case TOK_VAR:
+ if (parse(ep, STATE_DEC_LIST, flags) != STATE_DEC_LIST_DONE) {
+ goto error;
+ }
+ done++;
+ break;
+
+ case TOK_COMMA:
+ ejLexPutbackToken(ep, TOK_EXPR, ep->token);
+ done++;
+ break;
+
+ case TOK_LPAREN:
+ if (state == STATE_EXPR) {
+ if (parse(ep, STATE_RELEXP, flags) != STATE_RELEXP_DONE) {
+ goto error;
+ }
+ if (ejLexGetToken(ep, state) != TOK_RPAREN) {
+ goto error;
+ }
+ return STATE_EXPR_DONE;
+ }
+ done++;
+ break;
+
+ case TOK_RPAREN:
+ ejLexPutbackToken(ep, tid, ep->token);
+ return STATE_EXPR_DONE;
+
+ case TOK_LBRACE:
+/*
+ * This handles any code in braces except "if () {} else {}"
+ */
+ if (state != STATE_STMT) {
+ goto error;
+ }
+
+/*
+ * Parse will return STATE_STMT_BLOCK_DONE when the RBRACE is seen
+ */
+ do {
+ state = parse(ep, STATE_STMT, flags);
+ } while (state == STATE_STMT_DONE);
+
+/*
+ * Allow return statement.
+ */
+ if (state == STATE_RET) {
+ return state;
+ }
+
+ if (ejLexGetToken(ep, state) != TOK_RBRACE) {
+ goto error;
+ }
+ return STATE_STMT_DONE;
+
+ case TOK_RBRACE:
+ if (state == STATE_STMT) {
+ ejLexPutbackToken(ep, tid, ep->token);
+ return STATE_STMT_BLOCK_DONE;
+ }
+ goto error;
+
+ case TOK_RETURN:
+ if (parse(ep, STATE_RELEXP, flags) != STATE_RELEXP_DONE) {
+ goto error;
+ }
+ if (flags & FLAGS_EXE) {
+ while ( ejLexGetToken(ep, state) != TOK_EOF );
+ done++;
+ return STATE_RET;
+ }
+ break;
+ }
+ }
+
+ if (expectSemi) {
+ tid = ejLexGetToken(ep, state);
+ if (tid != TOK_SEMI && tid != TOK_NEWLINE) {
+ goto error;
+ }
+
+/*
+ * Skip newline after semi-colon
+ */
+ ejRemoveNewlines(ep, state);
+ }
+
+/*
+ * Free resources and return the correct status
+ */
+doneParse:
+ if (tid == TOK_FOR) {
+ ejLexFreeInputState(ep, &condScript);
+ ejLexFreeInputState(ep, &incrScript);
+ ejLexFreeInputState(ep, &endScript);
+ ejLexFreeInputState(ep, &bodyScript);
+ }
+
+ if (state == STATE_STMT) {
+ return STATE_STMT_DONE;
+ } else if (state == STATE_DEC) {
+ return STATE_DEC_DONE;
+ } else if (state == STATE_EXPR) {
+ return STATE_EXPR_DONE;
+ } else if (state == STATE_EOF) {
+ return state;
+ } else {
+ return STATE_ERR;
+ }
+
+/*
+ * Common error exit
+ */
+error:
+ state = STATE_ERR;
+ goto doneParse;
+}
+
+/******************************************************************************/
+/*
+ * Parse variable declaration list
+ */
+
+static int parseDeclaration(ej_t *ep, int state, int flags)
+{
+ int tid;
+
+ a_assert(ep);
+
+/*
+ * Declarations can be of the following forms:
+ * var x;
+ * var x, y, z;
+ * var x = 1 + 2 / 3, y = 2 + 4;
+ *
+ * We set the variable to NULL if there is no associated assignment.
+ */
+
+ do {
+ if ((tid = ejLexGetToken(ep, state)) != TOK_ID) {
+ return STATE_ERR;
+ }
+ ejLexPutbackToken(ep, tid, ep->token);
+
+/*
+ * Parse the entire assignment or simple identifier declaration
+ */
+ if (parse(ep, STATE_DEC, flags) != STATE_DEC_DONE) {
+ return STATE_ERR;
+ }
+
+/*
+ * Peek at the next token, continue if comma seen
+ */
+ tid = ejLexGetToken(ep, state);
+ if (tid == TOK_SEMI) {
+ return STATE_DEC_LIST_DONE;
+ } else if (tid != TOK_COMMA) {
+ return STATE_ERR;
+ }
+ } while (tid == TOK_COMMA);
+
+ if (tid != TOK_SEMI) {
+ return STATE_ERR;
+ }
+ return STATE_DEC_LIST_DONE;
+}
+
+/******************************************************************************/
+/*
+ * Parse function arguments
+ */
+
+static int parseArgs(ej_t *ep, int state, int flags)
+{
+ int tid, aid;
+
+ a_assert(ep);
+
+ do {
+ state = parse(ep, STATE_RELEXP, flags);
+ if (state == STATE_EOF || state == STATE_ERR) {
+ return state;
+ }
+ if (state == STATE_RELEXP_DONE) {
+ aid = hAlloc((void***) &ep->func->args);
+ ep->func->args[aid] = bstrdup(B_L, ep->result);
+ ep->func->nArgs++;
+ }
+/*
+ * Peek at the next token, continue if more args (ie. comma seen)
+ */
+ tid = ejLexGetToken(ep, state);
+ if (tid != TOK_COMMA) {
+ ejLexPutbackToken(ep, tid, ep->token);
+ }
+ } while (tid == TOK_COMMA);
+
+ if (tid != TOK_RPAREN && state != STATE_RELEXP_DONE) {
+ return STATE_ERR;
+ }
+ return STATE_ARG_LIST_DONE;
+}
+
+/******************************************************************************/
+/*
+ * Parse conditional expression (relational ops separated by ||, &&)
+ */
+
+static int parseCond(ej_t *ep, int state, int flags)
+{
+ char_t *lhs, *rhs;
+ int tid, operator;
+
+ a_assert(ep);
+
+ setString(B_L, &ep->result, T(""));
+ rhs = lhs = NULL;
+ operator = 0;
+
+ do {
+/*
+ * Recurse to handle one side of a conditional. Accumulate the
+ * left hand side and the final result in ep->result.
+ */
+ state = parse(ep, STATE_RELEXP, flags);
+ if (state != STATE_RELEXP_DONE) {
+ state = STATE_ERR;
+ break;
+ }
+
+ if (operator > 0) {
+ setString(B_L, &rhs, ep->result);
+ if (evalCond(ep, lhs, operator, rhs) < 0) {
+ state = STATE_ERR;
+ break;
+ }
+ }
+ setString(B_L, &lhs, ep->result);
+
+ tid = ejLexGetToken(ep, state);
+ if (tid == TOK_LOGICAL) {
+ operator = (int) *ep->token;
+
+ } else if (tid == TOK_RPAREN || tid == TOK_SEMI) {
+ ejLexPutbackToken(ep, tid, ep->token);
+ state = STATE_COND_DONE;
+ break;
+
+ } else {
+ ejLexPutbackToken(ep, tid, ep->token);
+ }
+
+ } while (state == STATE_RELEXP_DONE);
+
+ if (lhs) {
+ bfree(B_L, lhs);
+ }
+
+ if (rhs) {
+ bfree(B_L, rhs);
+ }
+ return state;
+}
+
+/******************************************************************************/
+/*
+ * Parse expression (leftHandSide operator rightHandSide)
+ */
+
+static int parseExpr(ej_t *ep, int state, int flags)
+{
+ char_t *lhs, *rhs;
+ int rel, tid;
+
+ a_assert(ep);
+
+ setString(B_L, &ep->result, T(""));
+ rhs = lhs = NULL;
+ rel = 0;
+ tid = 0;
+
+ do {
+/*
+ * This loop will handle an entire expression list. We call parse
+ * to evalutate each term which returns the result in ep->result.
+ */
+ if (tid == TOK_LOGICAL) {
+ if ((state = parse(ep, STATE_RELEXP, flags)) != STATE_RELEXP_DONE) {
+ state = STATE_ERR;
+ break;
+ }
+ } else {
+ if ((state = parse(ep, STATE_EXPR, flags)) != STATE_EXPR_DONE) {
+ state = STATE_ERR;
+ break;
+ }
+ }
+
+ if (rel > 0) {
+ setString(B_L, &rhs, ep->result);
+ if (tid == TOK_LOGICAL) {
+ if (evalCond(ep, lhs, rel, rhs) < 0) {
+ state = STATE_ERR;
+ break;
+ }
+ } else {
+ if (evalExpr(ep, lhs, rel, rhs) < 0) {
+ state = STATE_ERR;
+ break;
+ }
+ }
+ }
+ setString(B_L, &lhs, ep->result);
+
+ if ((tid = ejLexGetToken(ep, state)) == TOK_EXPR ||
+ tid == TOK_INC_DEC || tid == TOK_LOGICAL) {
+ rel = (int) *ep->token;
+
+ } else {
+ ejLexPutbackToken(ep, tid, ep->token);
+ state = STATE_RELEXP_DONE;
+ }
+
+ } while (state == STATE_EXPR_DONE);
+
+ if (rhs) {
+ bfree(B_L, rhs);
+ }
+
+ if (lhs) {
+ bfree(B_L, lhs);
+ }
+
+ return state;
+}
+
+/******************************************************************************/
+/*
+ * Evaluate a condition. Implements &&, ||, !
+ */
+
+static int evalCond(ej_t *ep, char_t *lhs, int rel, char_t *rhs)
+{
+ char_t buf[16];
+ int l, r, lval;
+
+ a_assert(lhs);
+ a_assert(rhs);
+ a_assert(rel > 0);
+
+ lval = 0;
+ if (gisdigit((int)*lhs) && gisdigit((int)*rhs)) {
+ l = gatoi(lhs);
+ r = gatoi(rhs);
+ switch (rel) {
+ case COND_AND:
+ lval = l && r;
+ break;
+ case COND_OR:
+ lval = l || r;
+ break;
+ default:
+ ejError(ep, T("Bad operator %d"), rel);
+ return -1;
+ }
+ } else {
+ if (!gisdigit((int)*lhs)) {
+ ejError(ep, T("Conditional must be numeric"), lhs);
+ } else {
+ ejError(ep, T("Conditional must be numeric"), rhs);
+ }
+ }
+
+ stritoa(lval, buf, sizeof(buf));
+ setString(B_L, &ep->result, buf);
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Evaluate an operation
+ */
+
+static int evalExpr(ej_t *ep, char_t *lhs, int rel, char_t *rhs)
+{
+ char_t *cp, buf[16];
+ int numeric, l, r, lval;
+
+ a_assert(lhs);
+ a_assert(rhs);
+ a_assert(rel > 0);
+
+/*
+ * All of the characters in the lhs and rhs must be numeric
+ */
+ numeric = 1;
+ for (cp = lhs; *cp; cp++) {
+ if (!gisdigit((int)*cp)) {
+ numeric = 0;
+ break;
+ }
+ }
+
+ if (numeric) {
+ for (cp = rhs; *cp; cp++) {
+ if (!gisdigit((int)*cp)) {
+ numeric = 0;
+ break;
+ }
+ }
+ }
+
+ if (numeric) {
+ l = gatoi(lhs);
+ r = gatoi(rhs);
+ switch (rel) {
+ case EXPR_PLUS:
+ lval = l + r;
+ break;
+ case EXPR_INC:
+ lval = l + 1;
+ break;
+ case EXPR_MINUS:
+ lval = l - r;
+ break;
+ case EXPR_DEC:
+ lval = l - 1;
+ break;
+ case EXPR_MUL:
+ lval = l * r;
+ break;
+ case EXPR_DIV:
+ if (r != 0) {
+ lval = l / r;
+ } else {
+ lval = 0;
+ }
+ break;
+ case EXPR_MOD:
+ if (r != 0) {
+ lval = l % r;
+ } else {
+ lval = 0;
+ }
+ break;
+ case EXPR_LSHIFT:
+ lval = l << r;
+ break;
+ case EXPR_RSHIFT:
+ lval = l >> r;
+ break;
+ case EXPR_EQ:
+ lval = l == r;
+ break;
+ case EXPR_NOTEQ:
+ lval = l != r;
+ break;
+ case EXPR_LESS:
+ lval = (l < r) ? 1 : 0;
+ break;
+ case EXPR_LESSEQ:
+ lval = (l <= r) ? 1 : 0;
+ break;
+ case EXPR_GREATER:
+ lval = (l > r) ? 1 : 0;
+ break;
+ case EXPR_GREATEREQ:
+ lval = (l >= r) ? 1 : 0;
+ break;
+ case EXPR_BOOL_COMP:
+ lval = (r == 0) ? 1 : 0;
+ break;
+ default:
+ ejError(ep, T("Bad operator %d"), rel);
+ return -1;
+ }
+
+ } else {
+ switch (rel) {
+ case EXPR_PLUS:
+ clearString(&ep->result);
+ appendString(&ep->result, lhs);
+ appendString(&ep->result, rhs);
+ return 0;
+ case EXPR_LESS:
+ lval = gstrcmp(lhs, rhs) < 0;
+ break;
+ case EXPR_LESSEQ:
+ lval = gstrcmp(lhs, rhs) <= 0;
+ break;
+ case EXPR_GREATER:
+ lval = gstrcmp(lhs, rhs) > 0;
+ break;
+ case EXPR_GREATEREQ:
+ lval = gstrcmp(lhs, rhs) >= 0;
+ break;
+ case EXPR_EQ:
+ lval = gstrcmp(lhs, rhs) == 0;
+ break;
+ case EXPR_NOTEQ:
+ lval = gstrcmp(lhs, rhs) != 0;
+ break;
+ case EXPR_INC:
+ case EXPR_DEC:
+ case EXPR_MINUS:
+ case EXPR_DIV:
+ case EXPR_MOD:
+ case EXPR_LSHIFT:
+ case EXPR_RSHIFT:
+ default:
+ ejError(ep, T("Bad operator"));
+ return -1;
+ }
+ }
+
+ stritoa(lval, buf, sizeof(buf));
+ setString(B_L, &ep->result, buf);
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Evaluate a function
+ */
+
+static int evalFunction(ej_t *ep)
+{
+ sym_t *sp;
+ int (*fn)(int eid, void *handle, int argc, char_t **argv);
+
+ if ((sp = symLookup(ep->functions, ep->func->fname)) == NULL) {
+ ejError(ep, T("Undefined procedure %s"), ep->func->fname);
+ return -1;
+ }
+
+ fn = (int (*)(int, void*, int, char_t**)) sp->content.value.integer;
+ if (fn == NULL) {
+ ejError(ep, T("Undefined procedure %s"), ep->func->fname);
+ return -1;
+ }
+
+ return (*fn)(ep->eid, (void*) ep->userHandle, ep->func->nArgs,
+ ep->func->args);
+}
+
+/******************************************************************************/
+/*
+ * Output a parse ej_error message
+ */
+
+void ejError(ej_t* ep, char_t* fmt, ...)
+{
+ va_list args;
+ ejinput_t *ip;
+ char_t *errbuf, *msgbuf;
+
+ a_assert(ep);
+ a_assert(fmt);
+ ip = ep->input;
+
+ va_start(args, fmt);
+ msgbuf = NULL;
+ fmtValloc(&msgbuf, E_MAX_ERROR, fmt, args);
+ va_end(args);
+
+ if (ep && ip) {
+ fmtAlloc(&errbuf, E_MAX_ERROR, T("%s\n At line %d, line => \n\n%s\n"),
+ msgbuf, ip->lineNumber, ip->line);
+ bfreeSafe(B_L, ep->error);
+ ep->error = errbuf;
+ }
+ bfreeSafe(B_L, msgbuf);
+}
+
+/******************************************************************************/
+/*
+ * Clear a string value
+ */
+
+static void clearString(char_t **ptr)
+{
+ a_assert(ptr);
+
+ if (*ptr) {
+ bfree(B_L, *ptr);
+ }
+ *ptr = NULL;
+}
+
+/******************************************************************************/
+/*
+ * Set a string value
+ */
+
+static void setString(B_ARGS_DEC, char_t **ptr, char_t *s)
+{
+ a_assert(ptr);
+
+ if (*ptr) {
+ bfree(B_ARGS, *ptr);
+ }
+ *ptr = bstrdup(B_ARGS, s);
+}
+
+/******************************************************************************/
+/*
+ * Append to the pointer value
+ */
+
+static void appendString(char_t **ptr, char_t *s)
+{
+ int len, oldlen;
+
+ a_assert(ptr);
+
+ if (*ptr) {
+ len = gstrlen(s);
+ oldlen = gstrlen(*ptr);
+ *ptr = brealloc(B_L, *ptr, (len + oldlen + 1) * sizeof(char_t));
+ gstrcpy(&(*ptr)[oldlen], s);
+ } else {
+ *ptr = bstrdup(B_L, s);
+ }
+}
+
+/******************************************************************************/
+/*
+ * Define a function
+ */
+
+int ejSetGlobalFunction(int eid, char_t *name,
+ int (*fn)(int eid, void *handle, int argc, char_t **argv))
+{
+ ej_t *ep;
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return -1;
+ }
+ return ejSetGlobalFunctionDirect(ep->functions, name, fn);
+}
+
+/******************************************************************************/
+/*
+ * Define a function directly into the function symbol table.
+ */
+
+int ejSetGlobalFunctionDirect(sym_fd_t functions, char_t *name,
+ int (*fn)(int eid, void *handle, int argc, char_t **argv))
+{
+ if (symEnter(functions, name, valueInteger((long) fn), 0) == NULL) {
+ return -1;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Remove ("undefine") a function
+ */
+
+int ejRemoveGlobalFunction(int eid, char_t *name)
+{
+ ej_t *ep;
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return -1;
+ }
+ return symDelete(ep->functions, name);
+}
+
+/******************************************************************************/
+/*
+ * Get a function definition
+ */
+
+void *ejGetGlobalFunction(int eid, char_t *name)
+{
+ ej_t *ep;
+ sym_t *sp;
+ int (*fn)(int eid, void *handle, int argc, char_t **argv);
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return NULL;
+ }
+
+ if ((sp = symLookup(ep->functions, name)) != NULL) {
+ fn = (int (*)(int, void*, int, char_t**)) sp->content.value.integer;
+ return (void*) fn;
+ }
+ return NULL;
+}
+
+/******************************************************************************/
+/*
+ * Utility routine to crack Ejscript arguments. Return the number of args
+ * seen. This routine only supports %s and %d type args.
+ *
+ * Typical usage:
+ *
+ * if (ejArgs(argc, argv, "%s %d", &name, &age) < 2) {
+ * error("Insufficient args\n");
+ * return -1;
+ * }
+ */
+
+int ejArgs(int argc, char_t **argv, char_t *fmt, ...)
+{
+ va_list vargs;
+ char_t *cp, **sp;
+ int *ip;
+ int argn;
+
+ va_start(vargs, fmt);
+
+ if (argv == NULL) {
+ return 0;
+ }
+
+ for (argn = 0, cp = fmt; cp && *cp && argv[argn]; ) {
+ if (*cp++ != '%') {
+ continue;
+ }
+
+ switch (*cp) {
+ case 'd':
+ ip = va_arg(vargs, int*);
+ *ip = gatoi(argv[argn]);
+ break;
+
+ case 's':
+ sp = va_arg(vargs, char_t**);
+ *sp = argv[argn];
+ break;
+
+ default:
+/*
+ * Unsupported
+ */
+ a_assert(0);
+ }
+ argn++;
+ }
+
+ va_end(vargs);
+ return argn;
+}
+
+/******************************************************************************/
+/*
+ * Define the user handle
+ */
+
+void ejSetUserHandle(int eid, int handle)
+{
+ ej_t *ep;
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return;
+ }
+ ep->userHandle = handle;
+}
+
+/******************************************************************************/
+/*
+ * Get the user handle
+ */
+
+int ejGetUserHandle(int eid)
+{
+ ej_t *ep;
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return -1;
+ }
+ return ep->userHandle;
+}
+
+/******************************************************************************/
+/*
+ * Get the current line number
+ */
+
+int ejGetLineNumber(int eid)
+{
+ ej_t *ep;
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return -1;
+ }
+ return ep->input->lineNumber;
+}
+
+/******************************************************************************/
+/*
+ * Set the result
+ */
+
+void ejSetResult(int eid, char_t *s)
+{
+ ej_t *ep;
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return;
+ }
+ setString(B_L, &ep->result, s);
+}
+
+/******************************************************************************/
+/*
+ * Get the result
+ */
+
+char_t *ejGetResult(int eid)
+{
+ ej_t *ep;
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return NULL;
+ }
+ return ep->result;
+}
+
+/******************************************************************************/
+/*
+ * Set a variable. Note: a variable with a value of NULL means declared but
+ * undefined. The value is defined in the top-most variable frame.
+ */
+
+void ejSetVar(int eid, char_t *var, char_t *value)
+{
+ ej_t *ep;
+ value_t v;
+
+ a_assert(var && *var);
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return;
+ }
+
+ if (value == NULL) {
+ v = valueString(value, 0);
+ } else {
+ v = valueString(value, VALUE_ALLOCATE);
+ }
+ symEnter(ep->variables[ep->variableMax - 1] - EJ_OFFSET, var, v, 0);
+}
+
+/******************************************************************************/
+/*
+ * Set a local variable. Note: a variable with a value of NULL means
+ * declared but undefined. The value is defined in the top-most variable frame.
+ */
+
+void ejSetLocalVar(int eid, char_t *var, char_t *value)
+{
+ ej_t *ep;
+ value_t v;
+
+ a_assert(var && *var);
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return;
+ }
+
+ if (value == NULL) {
+ v = valueString(value, 0);
+ } else {
+ v = valueString(value, VALUE_ALLOCATE);
+ }
+ symEnter(ep->variables[ep->variableMax - 1] - EJ_OFFSET, var, v, 0);
+}
+
+/******************************************************************************/
+/*
+ * Set a global variable. Note: a variable with a value of NULL means
+ * declared but undefined. The value is defined in the global variable frame.
+ */
+
+void ejSetGlobalVar(int eid, char_t *var, char_t *value)
+{
+ ej_t *ep;
+ value_t v;
+
+ a_assert(var && *var);
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return;
+ }
+
+ if (value == NULL) {
+ v = valueString(value, 0);
+ } else {
+ v = valueString(value, VALUE_ALLOCATE);
+ }
+ symEnter(ep->variables[0] - EJ_OFFSET, var, v, 0);
+}
+
+/******************************************************************************/
+/*
+ * Get a variable
+ */
+
+int ejGetVar(int eid, char_t *var, char_t **value)
+{
+ ej_t *ep;
+ sym_t *sp;
+ int i;
+
+ a_assert(var && *var);
+ a_assert(value);
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return -1;
+ }
+
+ i = ep->variableMax - 1;
+ if ((sp = symLookup(ep->variables[i] - EJ_OFFSET, var)) == NULL) {
+ i = 0;
+ if ((sp = symLookup(ep->variables[0] - EJ_OFFSET, var)) == NULL) {
+ return -1;
+ }
+ }
+ a_assert(sp->content.type == string);
+ *value = sp->content.value.string;
+ return i;
+}
+
+/******************************************************************************/
+/*
+ * Get the variable symbol table
+ */
+
+sym_fd_t ejGetVariableTable(int eid)
+{
+ ej_t *ep;
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return -1;
+ }
+ return *ep->variables;
+}
+
+/******************************************************************************/
+/*
+ * Get the functions symbol table
+ */
+
+sym_fd_t ejGetFunctionTable(int eid)
+{
+ ej_t *ep;
+
+ if ((ep = ejPtr(eid)) == NULL) {
+ return -1;
+ }
+ return ep->functions;
+}
+
+/******************************************************************************/
+/*
+ * Free an argument list
+ */
+
+static void freeFunc(ejfunc_t *func)
+{
+ int i;
+
+ for (i = func->nArgs - 1; i >= 0; i--) {
+ bfree(B_L, func->args[i]);
+ func->nArgs = hFree((void***) &func->args, i);
+ }
+
+ if (func->fname) {
+ bfree(B_L, func->fname);
+ func->fname = NULL;
+ }
+}
+
+/******************************************************************************/
+/*
+ * Get Ejscript pointer
+ */
+
+static ej_t *ejPtr(int eid)
+{
+ a_assert(0 <= eid && eid < ejMax);
+
+ if (eid < 0 || eid >= ejMax || ejHandles[eid] == NULL) {
+ ejError(NULL, T("Bad handle %d"), eid);
+ return NULL;
+ }
+ return ejHandles[eid];
+}
+
+/******************************************************************************/
+/*
+ * This function removes any new lines. Used for else cases, etc.
+ */
+static void ejRemoveNewlines(ej_t *ep, int state)
+{
+ int tid;
+
+ do {
+ tid = ejLexGetToken(ep, state);
+ } while (tid == TOK_NEWLINE);
+
+ ejLexPutbackToken(ep, tid, ep->token);
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/emfdb.c b/cpukit/httpd/emfdb.c
new file mode 100644
index 0000000000..708b51106b
--- /dev/null
+++ b/cpukit/httpd/emfdb.c
@@ -0,0 +1,1050 @@
+/*
+ * emfdb.c -- 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 *********************************/
+/*
+ * Textfile-based database support for WebServer 2.1.
+ */
+
+/********************************* Includes ***********************************/
+
+#include "emfdb.h"
+#include "wsIntrn.h"
+
+/********************************* Defines ************************************/
+
+#define KEYWORD_TABLE T("TABLE")
+#define KEYWORD_ROW T("ROW")
+
+/*********************************** Locals ***********************************/
+
+/*
+ * Variable to support the basicSet and basicGet functions.
+ */
+
+static char_t *basicProdDir = NULL;
+static char_t *basicDefaultDir = T("."); /* Default set to current */
+
+/*
+ * hAlloc chain list of table schemas to be closed
+ */
+
+static int dbMaxTables = 0;
+static dbTable_t **dbListTables = NULL;
+
+/****************************** Forward Declarations **************************/
+
+static int crack(char_t *buf, char_t **key, char_t **val);
+static char_t *trim(char_t *str);
+static int GetColumnIndex(int tid, char_t *colName);
+
+/******************************************************************************/
+/*
+ * Add a schema to the module-internal schema database
+ */
+
+int dbRegisterDBSchema(dbTable_t *pTableRegister)
+{
+ dbTable_t *pTable;
+ int tid;
+
+ a_assert(pTableRegister);
+
+ trace(4, T("DB: Registering database table <%s>\n"),
+ pTableRegister->name);
+
+/*
+ * Bump up the size of the table array
+ */
+ tid = hAllocEntry((void*) &dbListTables,
+ &dbMaxTables, sizeof(dbTable_t));
+
+/*
+ * Copy the table schema to the last spot in schema array
+ */
+ a_assert(dbListTables);
+ pTable = dbListTables[tid];
+ a_assert(pTable);
+
+/*
+ * Copy the name of the table
+ */
+ pTable->name = bstrdup(B_L, pTableRegister->name);
+
+/*
+ * Copy the number of columns
+ */
+ pTable->nColumns = pTableRegister->nColumns;
+
+/*
+ * Copy the column definitions
+ */
+ if (pTable->nColumns > 0) {
+ int i;
+ pTable->columnNames = balloc(B_L, sizeof(char_t *) * pTable->nColumns);
+ pTable->columnTypes = balloc(B_L, sizeof(int *) * pTable->nColumns);
+
+ for (i = 0; (i < pTableRegister->nColumns); i++) {
+ pTable->columnNames[i] =
+ bstrdup(B_L, pTableRegister->columnNames[i]);
+ pTable->columnTypes[i] = pTableRegister->columnTypes[i];
+ }
+
+ } else {
+ pTable->columnNames = NULL;
+ pTable->columnTypes = NULL;
+ }
+
+/*
+ * Zero out the table's data (very important!)
+ */
+ pTable->nRows = 0;
+ pTable->rows = NULL;
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * This is provided for compatibility with EMF. Tables are "registered"
+ * with staticly defined schemas. There is only one did in this package: 0.
+ */
+
+int dbOpen(char_t *tablename, char_t *filename,
+ int (*gettime)(int did), int flags)
+{
+ basicProdDir = NULL;
+ basicDefaultDir = T(".");
+ dbMaxTables = 0;
+ dbListTables = NULL;
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Delete all the rows of the tables, and all of the tables
+ */
+
+void dbClose(int did)
+{
+ int table, column;
+ dbTable_t *pTable;
+
+/*
+ * Before doing anything, delete all the contents of the database
+ */
+ dbZero(did);
+
+/*
+ * Now delete the tables
+ */
+ for (table = 0; table < dbMaxTables; table++) {
+ pTable = dbListTables[table];
+
+ if (pTable != NULL) {
+/*
+ * Delete the table schema
+ */
+ if (pTable->nColumns) {
+ for (column = 0; column < pTable->nColumns; column++) {
+ bfreeSafe(B_L, pTable->columnNames[column]);
+ }
+ bfreeSafe(B_L, pTable->columnNames);
+ bfreeSafe(B_L, pTable->columnTypes);
+ }
+/*
+ * Delete the table name
+ */
+ bfreeSafe(B_L, pTable->name);
+/*
+ * Free the table
+ */
+ bfreeSafe(B_L, pTable);
+ hFree((void *) &dbListTables, table);
+ }
+ }
+
+ if (dbListTables) {
+ bfree(B_L, dbListTables);
+ }
+
+/*
+ * Set the global table list to a safe value
+ */
+ dbListTables = NULL;
+ dbMaxTables = 0;
+}
+
+
+/******************************************************************************/
+/*
+ * Delete all the data records in all tables
+ */
+
+void dbZero(int did)
+{
+ int table, row, column, nRows, nColumns;
+ int *pRow;
+ dbTable_t *pTable;
+
+/*
+ * Delete all data from all tables
+ */
+ for (table = 0; table < dbMaxTables; table++) {
+ pTable = dbListTables[table];
+/*
+ * Delete the row data contained within the schema
+ */
+ if (pTable) {
+ nColumns = pTable->nColumns;
+ nRows = pTable->nRows;
+ for (row = 0; row < nRows; row++) {
+ pRow = pTable->rows[row];
+ if (pRow) {
+/*
+ * Only delete the contents of rows not previously deleted!
+ */
+ for (column = 0; column < nColumns; column++) {
+ if (pTable->columnTypes[column] == T_STRING) {
+ bfreeSafe(B_L, (char_t *)(pRow[column]));
+ pRow[column] = (int)NULL;
+ }
+ }
+
+ bfreeSafe(B_L, pRow);
+ hFree((void ***) &pTable->rows, row);
+ }
+ }
+
+ pTable->rows = NULL;
+ pTable->nRows = 0;
+ }
+ }
+}
+
+/******************************************************************************/
+/*
+ * Find the a row in the table with the given string in the given column
+ */
+
+int dbSearchStr(int did, char_t *tablename,
+ char_t *colName, char_t *value, int flags)
+{
+ int tid, nRows, nColumns, column;
+ dbTable_t *pTable;
+
+ a_assert(tablename);
+ a_assert(colName);
+ a_assert(value);
+
+ tid = dbGetTableId(0, tablename);
+ a_assert(tid >= 0);
+
+ if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
+ pTable = dbListTables[tid];
+ } else {
+ return DB_ERR_TABLE_NOT_FOUND;
+ }
+
+ nColumns = pTable->nColumns;
+ nRows = pTable->nRows;
+ column = GetColumnIndex(tid, colName);
+ a_assert (column >= 0);
+
+ if (column >= 0) {
+ char_t *compareVal;
+ int row, *pRow;
+/*
+ * Scan through rows until we find a match.
+ * Note that some of these rows may be deleted!
+ */
+ row = 0;
+ while (row < nRows) {
+ pRow = pTable->rows[row];
+ if (pRow) {
+ compareVal = (char_t *)(pRow[column]);
+ if (compareVal && (gstrcmp(compareVal, value) == 0)) {
+ return row;
+ }
+ }
+ row++;
+ }
+ } else {
+/*
+ * Return -2 if search column was not found
+ */
+ trace(3, T("DB: Unable to find column <%s> in table <%s>\n"),
+ colName, tablename);
+ return DB_ERR_COL_NOT_FOUND;
+ }
+
+ return -1;
+}
+
+/******************************************************************************/
+/*
+ * Add a new row to the given table. Return the new row ID.
+ */
+
+int dbAddRow(int did, char_t *tablename)
+{
+ int tid, size;
+ dbTable_t *pTable;
+
+ a_assert(tablename);
+
+ tid = dbGetTableId(0, tablename);
+ a_assert(tid >= 0);
+
+ if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
+ pTable = dbListTables[tid];
+ } else {
+ return DB_ERR_TABLE_NOT_FOUND;
+ }
+
+ a_assert(pTable);
+
+ if (pTable) {
+ trace(5, T("DB: Adding a row to table <%s>\n"), tablename);
+
+ size = pTable->nColumns * max(sizeof(int), sizeof(char_t *));
+ return hAllocEntry((void***) &(pTable->rows), &(pTable->nRows), size);
+ }
+
+ return -1;
+}
+
+/******************************************************************************/
+/*
+ * Delete a row in the table.
+ */
+
+int dbDeleteRow(int did, char_t *tablename, int row)
+{
+ int tid, nColumns, nRows;
+ dbTable_t *pTable;
+
+ a_assert(tablename);
+ tid = dbGetTableId(0, tablename);
+ a_assert(tid >= 0);
+
+ if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
+ pTable = dbListTables[tid];
+ } else {
+ return DB_ERR_TABLE_NOT_FOUND;
+ }
+
+ nColumns = pTable->nColumns;
+ nRows = pTable->nRows;
+
+ if ((row >= 0) && (row < nRows)) {
+ int *pRow = pTable->rows[row];
+
+ if (pRow) {
+ int column = 0;
+/*
+ * Free up any allocated strings
+ */
+ while (column < nColumns) {
+ if (pRow[column] &&
+ (pTable->columnTypes[column] == T_STRING)) {
+ bfree(B_L, (char_t *)pRow[column]);
+ }
+
+ column++;
+ }
+/*
+ * Zero out the row for safety
+ */
+ memset(pRow, 0, nColumns * max(sizeof(int), sizeof(char_t *)));
+
+ bfreeSafe(B_L, pRow);
+ pTable->nRows = hFree((void ***)&pTable->rows, row);
+ trace(5, T("DB: Deleted row <%d> from table <%s>\n"),
+ row, tablename);
+ }
+ return 0;
+ } else {
+ trace(3, T("DB: Unable to delete row <%d> from table <%s>\n"),
+ row, tablename);
+ }
+
+ return -1;
+}
+
+/*****************************************************************************/
+/*
+ * Grow the rows in the table to the nominated size.
+ */
+
+int dbSetTableNrow(int did, char_t *tablename, int nNewRows)
+{
+ int nRet, tid, nRows, nColumns;
+ dbTable_t *pTable;
+
+ a_assert(tablename);
+ tid = dbGetTableId(0, tablename);
+ a_assert(tid >= 0) ;
+
+ if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
+ pTable = dbListTables[tid];
+ } else {
+ return DB_ERR_TABLE_NOT_FOUND;
+ }
+
+ nRet = -1;
+
+ a_assert(pTable);
+ if (pTable) {
+ nColumns = pTable->nColumns;
+ nRows = pTable->nRows;
+ nRet = 0;
+
+ if (nRows >= nNewRows) {
+/*
+ * If number of rows already allocated exceeds requested number, do nothing
+ */
+ trace(4, T("DB: Ignoring row set to <%d> in table <%s>\n"),
+ nNewRows, tablename);
+ } else {
+ trace(4, T("DB: Setting rows to <%d> in table <%s>\n"),
+ nNewRows, tablename);
+ while (pTable->nRows < nNewRows) {
+ if (dbAddRow(did, tablename) < 0) {
+ return -1;
+ }
+ }
+ }
+ }
+
+ return nRet;
+}
+
+/******************************************************************************/
+/*
+ * Return the number of rows in the given table
+ */
+
+int dbGetTableNrow(int did, char_t *tablename)
+{
+ int tid;
+
+ a_assert(tablename);
+ tid = dbGetTableId(did, tablename);
+
+ if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
+ return (dbListTables[tid])->nRows;
+ } else {
+ return -1;
+ }
+}
+
+/******************************************************************************/
+/*
+ * Do table driven read of the database
+ */
+
+int dbReadInt(int did, char_t *table, char_t *column, int row, int *returnValue)
+{
+ int colIndex, *pRow, tid;
+ dbTable_t *pTable;
+
+ a_assert(table);
+ a_assert(column);
+ a_assert(returnValue);
+
+ tid = dbGetTableId(0, table);
+ a_assert(tid >= 0);
+
+/*
+ * Return -6 if table is not found
+ */
+ if (tid < 0) {
+ return DB_ERR_TABLE_NOT_FOUND;
+ }
+
+/*
+ * Return -7 if table id has been deleted
+ */
+ pTable = dbListTables[tid];
+ if (pTable == NULL) {
+ return DB_ERR_TABLE_DELETED;
+ }
+
+ a_assert(row >= 0);
+
+ if ((row >= 0) && (row < pTable->nRows)) {
+ colIndex = GetColumnIndex(tid, column);
+ a_assert(colIndex >= 0);
+
+ if (colIndex >= 0) {
+ pRow = pTable->rows[row];
+ if (pRow) {
+ *returnValue = pRow[colIndex];
+ return 0;
+ }
+ return DB_ERR_ROW_DELETED;
+ }
+ return DB_ERR_COL_NOT_FOUND;
+ }
+
+ return DB_ERR_ROW_NOT_FOUND;
+}
+
+/******************************************************************************/
+/*
+ * dbReadStr calls dbReadInt to do table driven read of database
+ */
+
+int dbReadStr(int did, char_t *table, char_t *column, int row,
+ char_t **returnValue)
+{
+ return dbReadInt(did, table, column, row, (int *)returnValue);
+}
+
+/******************************************************************************/
+/*
+ * The dbWriteInt function writes a value into a table at a given row and
+ * column. The existence of the row and column is verified before the
+ * write. 0 is returned on succes, -1 is returned on error.
+ */
+
+int dbWriteInt(int did, char_t *table, char_t *column, int row, int iData)
+{
+ int tid, colIndex, *pRow;
+ dbTable_t *pTable;
+
+ a_assert(table);
+ a_assert(column);
+
+/*
+ * Make sure that this table exists
+ */
+ tid = dbGetTableId(0, table);
+ a_assert(tid >= 0);
+
+ if (tid < 0) {
+ return DB_ERR_TABLE_NOT_FOUND;
+ }
+
+ pTable = dbListTables[tid];
+
+ if (pTable) {
+/*
+ * Make sure that the column exists
+ */
+ colIndex = GetColumnIndex(tid, column);
+ a_assert(colIndex >= 0);
+ if (colIndex >= 0) {
+/*
+ * Make sure that the row exists
+ */
+ a_assert((row >= 0) && (row < pTable->nRows));
+ if ((row >= 0) && (row < pTable->nRows)) {
+ pRow = pTable->rows[row];
+ if (pRow) {
+ pRow[colIndex] = iData;
+ return 0;
+ }
+ return DB_ERR_ROW_DELETED;
+ }
+ return DB_ERR_ROW_NOT_FOUND;
+ }
+ return DB_ERR_COL_NOT_FOUND;
+ }
+
+ return DB_ERR_TABLE_DELETED;
+}
+
+/******************************************************************************/
+/*
+ * The dbWriteStr function writes a string value into a table at a given row
+ * and column. The existence of the row and column is verified before the
+ * write. The column is also checked to confirm it is a string field.
+ * 0 is returned on succes, -1 is returned on error.
+ */
+
+int dbWriteStr(int did, char_t *table, char_t *column, int row, char_t *s)
+{
+ int tid, colIndex;
+ int *pRow;
+ char_t *ptr;
+ dbTable_t *pTable;
+
+ a_assert(table);
+ a_assert(column);
+
+ tid = dbGetTableId(0, table);
+ a_assert(tid >= 0);
+
+ if (tid < 0) {
+ return DB_ERR_TABLE_NOT_FOUND;
+ }
+
+/*
+ * Make sure that this table exists
+ */
+ pTable = dbListTables[tid];
+ a_assert(pTable);
+ if (!pTable) {
+ return DB_ERR_TABLE_DELETED;
+ }
+
+/*
+ * Make sure that this column exists
+ */
+ colIndex = GetColumnIndex(tid, column);
+ if (colIndex < 0) {
+ return DB_ERR_COL_NOT_FOUND;
+ }
+
+/*
+ * Make sure that this column is a string column
+ */
+ if (pTable->columnTypes[colIndex] != T_STRING) {
+ return DB_ERR_BAD_FORMAT;
+ }
+
+/*
+ * Make sure that the row exists
+ */
+ a_assert((row >= 0) && (row < pTable->nRows));
+ if ((row >= 0) && (row < pTable->nRows)) {
+ pRow = pTable->rows[row];
+ } else {
+ return DB_ERR_ROW_NOT_FOUND;
+ }
+
+ if (!pRow) {
+ return DB_ERR_ROW_DELETED;
+ }
+
+/*
+ * If the column already has a value, be sure to delete it to prevent
+ * memory leaks.
+ */
+ if (pRow[colIndex]) {
+ bfree(B_L, (char_t *) pRow[colIndex]);
+ }
+
+/*
+ * Make sure we make a copy of the string to write into the column.
+ * This allocated string will be deleted when the row is deleted.
+ */
+ ptr = bstrdup(B_L, s);
+ pRow[colIndex] = (int)ptr;
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Print a key-value pair to a file
+ */
+
+static int dbWriteKeyValue(int fd, char_t *key, char_t *value)
+{
+ int rc;
+ int len;
+ char_t *pLineOut;
+
+ a_assert(key && *key);
+ a_assert(value);
+
+ fmtAlloc(&pLineOut, BUF_MAX, T("%s=%s\n"), key, value);
+
+ if (pLineOut) {
+ len = gstrlen(pLineOut);
+#ifdef CE
+ rc = writeUniToAsc(fd, pLineOut, len);
+#else
+ rc = gwrite(fd, pLineOut, len);
+#endif
+ bfree(B_L, pLineOut);
+ } else {
+ rc = -1;
+ }
+
+ return rc;
+}
+
+/******************************************************************************/
+/*
+ * Persist a database to a file
+ */
+
+int dbSave(int did, char_t *filename, int flags)
+{
+ int row, column, nColumns, nRows, fd, rc;
+ int *colTypes, *pRow, nRet, tid;
+ char_t *path, *tmpFile, *tmpNum;
+ char_t **colNames;
+ dbTable_t *pTable;
+
+ trace(5, T("DB: About to save database to file\n"));
+
+ a_assert(dbMaxTables > 0);
+
+/*
+ * First write to a temporary file, then switch around later.
+ */
+ fmtAlloc(&tmpFile, FNAMESIZE, T("%s/data.tmp"), basicGetProductDir());
+ if ((fd = gopen(tmpFile,
+ O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) < 0) {
+ trace(1, T("WARNING: Failed to open file %s\n"), tmpFile);
+ bfree(B_L, tmpFile);
+ return -1;
+ }
+
+ nRet = 0;
+
+ for (tid = 0; (tid < dbMaxTables) && (nRet != -1); tid++) {
+ pTable = dbListTables[tid];
+
+ if (pTable) {
+/*
+ * Print the TABLE=tableName directive to the file
+ */
+ rc = dbWriteKeyValue(fd, KEYWORD_TABLE, pTable->name);
+
+ nColumns = pTable->nColumns;
+ nRows = pTable->nRows;
+
+ for (row = 0; (row < nRows) && (nRet == 0); row++) {
+ pRow = pTable->rows[row];
+/*
+ * if row is NULL, the row has been deleted, so don't
+ * write it out.
+ */
+ if ((pRow == NULL) || (pRow[0] == '\0') ||
+ (*(char_t *)(pRow[0]) == '\0')) {
+ continue;
+ }
+/*
+ * Print the ROW=rowNumber directive to the file
+ */
+ fmtAlloc(&tmpNum, 20, T("%d"), row);
+ rc = dbWriteKeyValue(fd, KEYWORD_ROW, tmpNum);
+ bfreeSafe(B_L, tmpNum);
+
+ colNames = pTable->columnNames;
+ colTypes = pTable->columnTypes;
+/*
+ * Print the key-value pairs (COLUMN=value) for data cells
+ */
+ for (column = 0; (column < nColumns) && (rc >= 0);
+ column++, colNames++, colTypes++) {
+ if (*colTypes == T_STRING) {
+ rc = dbWriteKeyValue(fd, *colNames,
+ (char_t *)(pRow[column]));
+ } else {
+ fmtAlloc(&tmpNum, 20, T("%d"), pRow[column]);
+ rc = dbWriteKeyValue(fd, *colNames, tmpNum);
+ bfreeSafe(B_L, tmpNum);
+ }
+ }
+
+ if (rc < 0) {
+ trace(1, T("WARNING: Failed to write to file %s\n"),
+ tmpFile);
+ nRet = -1;
+ }
+ }
+ }
+ }
+
+ gclose(fd);
+
+/*
+ * Replace the existing file with the temporary file, if no errors
+ */
+ if (nRet == 0) {
+ fmtAlloc(&path, FNAMESIZE, T("%s/%s"), basicGetProductDir(), filename);
+
+ gunlink(path);
+ if (grename(tmpFile, path) != 0) {
+ trace(1, T("WARNING: Failed to rename %s to %s\n"), tmpFile, path);
+ nRet = -1;
+ }
+
+ bfree(B_L, path);
+ }
+
+ bfree(B_L, tmpFile);
+
+ return nRet;
+}
+
+/******************************************************************************/
+/*
+ * Crack a keyword=value string into keyword and value. We can change buf.
+ */
+
+static int crack(char_t *buf, char_t **key, char_t **val)
+{
+ char_t *ptr;
+
+ if ((ptr = gstrrchr(buf, '\n')) != NULL ||
+ (ptr = gstrrchr(buf, '\r')) != NULL) {
+ *ptr = '\0';
+ }
+
+/*
+ * Find the = sign. It must exist.
+ */
+ if ((ptr = gstrstr(buf, T("="))) == NULL) {
+ return -1;
+ }
+
+ *ptr++ = '\0';
+ *key = trim(buf);
+ *val = trim(ptr);
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Parse the file. These files consist of key-value pairs, separated by the
+ * "=" sign. Parsing of tables starts with the "TABLE=value" pair, and rows
+ * are parsed starting with the "ROW=value" pair.
+ */
+
+int dbLoad(int did, char_t *filename, int flags)
+{
+ gstat_t sbuf;
+ char_t *buf, *keyword, *value, *path, *ptr;
+ char_t *tablename;
+ int fd, tid, row;
+ dbTable_t *pTable;
+
+ a_assert(did >= 0);
+
+ fmtAlloc(&path, FNAMESIZE, T("%s/%s"), basicGetProductDir(), filename);
+ trace(4, T("DB: About to read data file <%s>\n"), path);
+
+ if (gstat(path, &sbuf) < 0) {
+ trace(3, T("DB: Failed to stat persistent data file.\n"));
+ bfree(B_L, path);
+ return -1;
+ }
+
+ fd = gopen(path, O_RDONLY | O_BINARY, 0666);
+ bfree(B_L, path);
+
+ if (fd < 0) {
+ trace(3, T("DB: No persistent data file present.\n"));
+ return -1;
+ }
+
+ if (sbuf.st_size <= 0) {
+ trace(3, T("DB: Persistent data file is empty.\n"));
+ gclose(fd);
+ return -1;
+ }
+/*
+ * Read entire file into temporary buffer
+ */
+ buf = balloc(B_L, sbuf.st_size + 1);
+#ifdef CE
+ if (readAscToUni(fd, &buf, sbuf.st_size) != (int)sbuf.st_size) {
+#else
+ if (gread(fd, buf, sbuf.st_size) != (int)sbuf.st_size) {
+#endif
+ trace(3, T("DB: Persistent data read failed.\n"));
+ bfree(B_L, buf);
+ gclose(fd);
+ return -1;
+ }
+
+ gclose(fd);
+ *(buf + sbuf.st_size) = '\0';
+
+ row = -1;
+ tid = -1;
+ pTable = NULL;
+ ptr = gstrtok(buf, T("\n"));
+ tablename = NULL;
+
+ do {
+ if (crack(ptr, &keyword, &value) < 0) {
+ trace(5, T("DB: Failed to crack line %s\n"), ptr);
+ continue;
+ }
+
+ a_assert(keyword && *keyword);
+
+ if (gstrcmp(keyword, KEYWORD_TABLE) == 0) {
+/*
+ * Table name found, check to see if it's registered
+ */
+ if (tablename) {
+ bfree(B_L, tablename);
+ }
+
+ tablename = bstrdup(B_L, value);
+ tid = dbGetTableId(did, tablename);
+
+ if (tid >= 0) {
+ pTable = dbListTables[tid];
+ } else {
+ pTable = NULL;
+ }
+
+ } else if (gstrcmp(keyword, KEYWORD_ROW) == 0) {
+/*
+ * Row/Record indicator found, add a new row to table
+ */
+ if (tid >= 0) {
+ int nRows = dbGetTableNrow(did, tablename);
+
+ if (dbSetTableNrow(did, tablename, nRows + 1) == 0) {
+ row = nRows;
+ }
+ }
+
+ } else if (row != -1) {
+/*
+ * some other data found, assume it's a COLUMN=value
+ */
+ int nColumn = GetColumnIndex(tid, keyword);
+
+ if ((nColumn >= 0) && (pTable != NULL)) {
+ int nColumnType = pTable->columnTypes[nColumn];
+ if (nColumnType == T_STRING) {
+ dbWriteStr(did, tablename, keyword, row, value);
+ } else {
+ dbWriteInt(did, tablename, keyword, row, gstrtoi(value));
+ }
+ }
+ }
+ } while ((ptr = gstrtok(NULL, T("\n"))) != NULL);
+
+ if (tablename) {
+ bfree(B_L, tablename);
+ }
+
+ bfree(B_L, buf);
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Return a table id given the table name
+ */
+
+int dbGetTableId(int did, char_t *tablename)
+{
+ int tid;
+ dbTable_t *pTable;
+
+ a_assert(tablename);
+
+ for (tid = 0; (tid < dbMaxTables); tid++) {
+ if ((pTable = dbListTables[tid]) != NULL) {
+ if (gstrcmp(tablename, pTable->name) == 0) {
+ return tid;
+ }
+ }
+ }
+
+ return -1;
+}
+
+/******************************************************************************/
+/*
+ * Return a pointer to the table name, given its ID
+ */
+
+char_t *dbGetTableName(int did, int tid)
+{
+ if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
+ return (dbListTables[tid])->name;
+ }
+
+ return NULL;
+}
+
+/******************************************************************************/
+/*
+ * Trim leading white space.
+ */
+
+static char_t *trim(char_t *str)
+{
+ while (isspace((int)*str)) {
+ str++;
+ }
+ return str;
+}
+
+/******************************************************************************/
+/*
+ * Return a column index given the column name
+ */
+
+static int GetColumnIndex(int tid, char_t *colName)
+{
+ int column;
+ dbTable_t *pTable;
+
+ a_assert(colName);
+
+ if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
+ pTable = dbListTables[tid];
+
+ for (column = 0; (column < pTable->nColumns); column++) {
+ if (gstrcmp(colName, pTable->columnNames[column]) == 0)
+ return column;
+ }
+ }
+
+ return -1;
+}
+
+/******************************************************************************/
+/*
+ * Set the prefix-directory
+ */
+
+void basicSetProductDir(char_t *proddir)
+{
+ int len;
+
+ if (basicProdDir != NULL) {
+ bfree(B_L, basicProdDir);
+ }
+
+ basicProdDir = bstrdup(B_L, proddir);
+/*
+ * Make sure that prefix-directory doesn't end with a '/'
+ */
+ len = gstrlen(basicProdDir);
+ if ((len > 0) && *(basicProdDir + len - 1) == '/') {
+ *(basicProdDir+len-1) = '\0';
+ }
+}
+
+/******************************************************************************/
+/*
+ * Return the prefix-directory
+ */
+
+char_t *basicGetProductDir()
+{
+ if (basicProdDir) {
+ return basicProdDir;
+ } else {
+ return basicDefaultDir;
+ }
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/emfdb.h b/cpukit/httpd/emfdb.h
new file mode 100644
index 0000000000..882c1c80d2
--- /dev/null
+++ b/cpukit/httpd/emfdb.h
@@ -0,0 +1,101 @@
+/*
+ * 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
+
+#ifndef 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 */
+
+/******************************************************************************/
diff --git a/cpukit/httpd/form.c b/cpukit/httpd/form.c
new file mode 100644
index 0000000000..501cea72e2
--- /dev/null
+++ b/cpukit/httpd/form.c
@@ -0,0 +1,168 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/********************************** 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"));
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/h.c b/cpukit/httpd/h.c
new file mode 100644
index 0000000000..35b0bbbae6
--- /dev/null
+++ b/cpukit/httpd/h.c
@@ -0,0 +1,194 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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 ***********************************/
+
+#ifdef 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.
+ */
+
+#ifdef 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**);
+#ifdef 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.
+ */
+
+#ifdef 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);
+
+#ifdef B_STATS
+ if ((id = HALLOC(B_ARGS, (void***) list)) < 0) {
+#else
+ if ((id = hAlloc((void***) list)) < 0) {
+#endif
+ return -1;
+ }
+
+ if (size > 0) {
+#ifdef 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;
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/handler.c b/cpukit/httpd/handler.c
new file mode 100644
index 0000000000..dbbe4148d5
--- /dev/null
+++ b/cpukit/httpd/handler.c
@@ -0,0 +1,411 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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 char_t *websCondenseMultipleChars(char_t *strToCondense, char_t cCondense);
+
+/*********************************** 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);
+
+/*
+ * Eliminate security hole
+ */
+ websCondenseMultipleChars(wp->path, '/');
+ websCondenseMultipleChars(wp->url, '/');
+
+/*
+ * 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;
+}
+
+#ifdef OBSOLETE_CODE
+
+/******************************************************************************/
+/*
+ * 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;
+ }
+}
+
+#endif
+
+/******************************************************************************/
+/*
+ * Convert multiple adjacent occurrences of a given character to a single
+ * instance.
+ */
+
+static char_t *websCondenseMultipleChars(char_t *strToCondense, char_t cCondense)
+{
+ if (strToCondense != NULL) {
+ char_t *pStr, *pScan;
+
+ pStr = pScan = strToCondense;
+
+ while (*pScan && *pStr) {
+/*
+ * Advance scan pointer over multiple occurences of condense character
+ */
+ while ((*pScan == cCondense) && (*(pScan + 1) == cCondense)) {
+ pScan++;
+ }
+/*
+ * Copy character if an advance of the scan pointer has occurred
+ */
+ if (pStr != pScan) {
+ *pStr = *pScan;
+ }
+
+ pScan++;
+ pStr++;
+ }
+/*
+ * Zero terminate string if multiple adjacent characters were found and condensed
+ */
+ if (pStr != pScan) {
+ *pStr = 0;
+ }
+ }
+
+ return strToCondense;
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/license.txt b/cpukit/httpd/license.txt
new file mode 100644
index 0000000000..1fa9e67e79
--- /dev/null
+++ b/cpukit/httpd/license.txt
@@ -0,0 +1,282 @@
+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’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’ notes and
+other programmers’ 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’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’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
+
+
+
+
diff --git a/cpukit/httpd/md5.h b/cpukit/httpd/md5.h
new file mode 100644
index 0000000000..99df4eb735
--- /dev/null
+++ b/cpukit/httpd/md5.h
@@ -0,0 +1,50 @@
+/* MD5.H - header file for MD5C.C
+ *
+ * $Id$
+ */
+
+/* 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 */
diff --git a/cpukit/httpd/md5c.c b/cpukit/httpd/md5c.c
new file mode 100644
index 0000000000..1e5a3442fa
--- /dev/null
+++ b/cpukit/httpd/md5c.c
@@ -0,0 +1,337 @@
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ *
+ * $Id$
+ */
+
+/* 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;
+}
diff --git a/cpukit/httpd/mime.c b/cpukit/httpd/mime.c
new file mode 100644
index 0000000000..689360ea68
--- /dev/null
+++ b/cpukit/httpd/mime.c
@@ -0,0 +1,116 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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") },
+ { T("application/x-javascript"), T(".js") },
+
+#ifdef 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},
+};
+
+/*****************************************************************************/
diff --git a/cpukit/httpd/misc.c b/cpukit/httpd/misc.c
new file mode 100644
index 0000000000..e08b7c76b4
--- /dev/null
+++ b/cpukit/httpd/misc.c
@@ -0,0 +1,675 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/********************************* Includes ***********************************/
+
+#ifdef 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);
+#if !defined(__rtems__)
+static int strnlen(char_t *s, unsigned int n);
+#endif
+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, LynxOS and Mac OS X have their own basename function
+ */
+
+#if (!defined (LINUX) && !defined (LYNX) && !defined (MACOSX))
+char_t *basename(char_t *name)
+{
+ char_t *cp;
+
+#if (defined (NW) || defined (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 & ! MACOSX */
+
+/******************************************************************************/
+/*
+ * 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 (defined (WIN) || defined (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 {
+ /* 04 Apr 02 BgP -- changed so that %X correctly outputs
+ * uppercase hex digits when requested.
+ put_ulong(&buf, value, 16, 0, NULL, width, prec, f);
+ */
+ put_ulong(&buf, value, 16, ('X' == c) , 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;
+}
+
+/******************************************************************************/
+/*
+ * Return the length of a string limited by a given length
+ */
+
+#if !defined(__rtems__)
+static int strnlen(char_t *s, unsigned int n)
+{
+ unsigned int len;
+
+ len = gstrlen(s);
+ return min(len, n);
+}
+#endif
+
+/******************************************************************************/
+/*
+ * 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)
+{
+#ifdef UNICODE
+ if (MultiByteToWideChar(CP_ACP, 0, str, nBytes / sizeof(char_t), ubuf,
+ nBytes / sizeof(char_t)) < 0) {
+ return (char_t*) str;
+ }
+#else
+ strncpy(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)
+{
+#ifdef UNICODE
+ if (WideCharToMultiByte(CP_ACP, 0, ustr, nBytes, buf, nBytes, NULL,
+ NULL) < 0) {
+ return (char*) ustr;
+ }
+#else
+ strncpy(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);
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/preinstall.am b/cpukit/httpd/preinstall.am
new file mode 100644
index 0000000000..cd356f2969
--- /dev/null
+++ b/cpukit/httpd/preinstall.am
@@ -0,0 +1,78 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-local: $(TMPINSTALL_FILES)
+
+TMPINSTALL_FILES =
+CLEANFILES = $(TMPINSTALL_FILES)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES += $(PREINSTALL_FILES)
+
+$(PROJECT_LIB)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_LIB)
+ @: > $(PROJECT_LIB)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)
+ @: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
+
+if HAS_NETWORKING
+if HAS_POSIX
+$(PROJECT_INCLUDE)/goahead/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/goahead
+ @: > $(PROJECT_INCLUDE)/goahead/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/goahead/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems_webserver.h: rtems_webserver.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems_webserver.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems_webserver.h
+
+$(PROJECT_INCLUDE)/goahead/ej.h: ej.h $(PROJECT_INCLUDE)/goahead/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/ej.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/ej.h
+
+$(PROJECT_INCLUDE)/goahead/ejIntrn.h: ejIntrn.h $(PROJECT_INCLUDE)/goahead/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/ejIntrn.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/ejIntrn.h
+
+$(PROJECT_INCLUDE)/goahead/emfdb.h: emfdb.h $(PROJECT_INCLUDE)/goahead/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/emfdb.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/emfdb.h
+
+$(PROJECT_INCLUDE)/goahead/md5.h: md5.h $(PROJECT_INCLUDE)/goahead/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/md5.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/md5.h
+
+$(PROJECT_INCLUDE)/goahead/uemf.h: uemf.h $(PROJECT_INCLUDE)/goahead/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/uemf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/uemf.h
+
+$(PROJECT_INCLUDE)/goahead/um.h: um.h $(PROJECT_INCLUDE)/goahead/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/um.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/um.h
+
+$(PROJECT_INCLUDE)/goahead/webs.h: webs.h $(PROJECT_INCLUDE)/goahead/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/webs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/webs.h
+
+$(PROJECT_INCLUDE)/goahead/wsIntrn.h: wsIntrn.h $(PROJECT_INCLUDE)/goahead/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/goahead/wsIntrn.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/goahead/wsIntrn.h
+
+$(PROJECT_LIB)/libhttpd.a: libhttpd.a $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/libhttpd.a
+TMPINSTALL_FILES += $(PROJECT_LIB)/libhttpd.a
+endif
+endif
diff --git a/cpukit/httpd/ringq.c b/cpukit/httpd/ringq.c
new file mode 100644
index 0000000000..efb9c45a70
--- /dev/null
+++ b/cpukit/httpd/ringq.c
@@ -0,0 +1,584 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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 ***********************************/
+
+#ifdef 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';
+}
+
+/******************************************************************************/
+#ifdef 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);
+
+#ifdef 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));
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/rom.c b/cpukit/httpd/rom.c
new file mode 100644
index 0000000000..f9ff5312ac
--- /dev/null
+++ b/cpukit/httpd/rom.c
@@ -0,0 +1,193 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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 **********************************/
+
+#ifdef 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 */
+
+/******************************************************************************/
diff --git a/cpukit/httpd/rtems_webserver.h b/cpukit/httpd/rtems_webserver.h
new file mode 100644
index 0000000000..d2e1362865
--- /dev/null
+++ b/cpukit/httpd/rtems_webserver.h
@@ -0,0 +1,17 @@
+/**
+ * @file rtems/rtems_webserver.h
+ */
+
+#ifndef _rtems_rtems_webserver_h
+#define _rtems_rtems_webserver_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int rtems_initialize_webserver();
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/cpukit/httpd/security.c b/cpukit/httpd/security.c
new file mode 100644
index 0000000000..9064b5d56f
--- /dev/null
+++ b/cpukit/httpd/security.c
@@ -0,0 +1,235 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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, 405, T("Access Denied\nSecure access is required."));
+ trace(3, T("SEC: Non-secure access attempted on <%s>\n"), path);
+ /* bugfix 5/24/02 -- we were leaking the memory pointed to by
+ * 'accessLimit'. Thanks to Simon Byholm.
+ */
+ bfree(B_L, accessLimit);
+ 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, 401, 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, 401, 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, 405, 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);
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/sock.c b/cpukit/httpd/sock.c
new file mode 100644
index 0000000000..fce0b692cb
--- /dev/null
+++ b/cpukit/httpd/sock.c
@@ -0,0 +1,791 @@
+/*
+ * sock.c -- Posix Socket upper layer support module for general posix use
+ *
+ * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
+ *
+ * $Id$
+ */
+
+/******************************** Description *********************************/
+
+/*
+ * Posix Socket Module. This supports blocking and non-blocking buffered
+ * socket I/O.
+ */
+
+/********************************** Includes **********************************/
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef 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 (defined (WIN) || defined (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)
+{
+ #ifdef 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((char *)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 (defined (WIN) || defined (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 (defined (WIN) || defined (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 (defined (UEMF) || defined (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 (defined (WIN) || defined (CE))
+ sp->currentEvents &= ~FD_WRITE;
+#endif
+
+ return -1;
+
+ } else if (bytes == 0 && bytes != toWrite) {
+ *errCode = EWOULDBLOCK;
+#if (defined (WIN) || defined (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
+ */
+#ifndef UEMF
+#ifdef 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)
+{
+#ifdef 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 (defined (WIN) || defined (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 (defined (WIN) || defined (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;
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/sockGen.c b/cpukit/httpd/sockGen.c
new file mode 100644
index 0000000000..822aea6407
--- /dev/null
+++ b/cpukit/httpd/sockGen.c
@@ -0,0 +1,1043 @@
+
+/*
+ * sockGen.c -- Posix Socket support module for general posix use
+ *
+ * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
+ *
+ * $Id$
+ */
+
+/******************************** Description *********************************/
+
+/*
+ * Posix Socket Module. This supports blocking and non-blocking buffered
+ * socket I/O.
+ */
+
+#if (!defined (WIN) || defined (LITTLEFOOT) || defined (WEBS))
+
+/********************************** Includes **********************************/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef UEMF
+ #include "uemf.h"
+#else
+ #include <socket.h>
+ #include <types.h>
+ #include <unistd.h>
+ #include "emfInternal.h"
+#endif
+
+#ifdef VXWORKS
+ #include <hostLib.h>
+#endif
+
+/************************************ Locals **********************************/
+
+extern socket_t **socketList; /* List of open sockets */
+extern int socketMax; /* Maximum size of socket */
+extern int socketHighestFd; /* Highest socket fd opened */
+static int socketOpenCount = 0; /* Number of task using sockets */
+
+/***************************** Forward Declarations ***************************/
+
+static void socketAccept(socket_t *sp);
+static int socketDoEvent(socket_t *sp);
+static int tryAlternateConnect(int sock, struct sockaddr *sockaddr);
+
+/*********************************** Code *************************************/
+/*
+ * Open socket module
+ */
+
+int socketOpen()
+{
+#if (defined (CE) || defined (WIN))
+ WSADATA wsaData;
+#endif
+
+ if (++socketOpenCount > 1) {
+ return 0;
+ }
+
+#if (defined (CE) || defined (WIN))
+ if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) {
+ return -1;
+ }
+ if (wsaData.wVersion != MAKEWORD(1,1)) {
+ WSACleanup();
+ return -1;
+ }
+#endif
+
+ socketList = NULL;
+ socketMax = 0;
+ socketHighestFd = -1;
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Close the socket module, by closing all open connections
+ */
+
+void socketClose()
+{
+ int i;
+
+ if (--socketOpenCount <= 0) {
+ for (i = socketMax; i >= 0; i--) {
+ if (socketList && socketList[i]) {
+ socketCloseConnection(i);
+ }
+ }
+ socketOpenCount = 0;
+ }
+}
+
+/******************************************************************************/
+/*
+ * Open a client or server socket. Host is NULL if we want server capability.
+ */
+
+int socketOpenConnection(char *host, int port, socketAccept_t accept, int flags)
+{
+#if (!defined (NO_GETHOSTBYNAME) && !defined (VXWORKS))
+ struct hostent *hostent; /* Host database entry */
+#endif /* ! (NO_GETHOSTBYNAME || VXWORKS) */
+ socket_t *sp;
+ struct sockaddr_in sockaddr;
+ int sid, bcast, dgram, rc;
+
+ if (port > SOCKET_PORT_MAX) {
+ return -1;
+ }
+/*
+ * Allocate a socket structure
+ */
+ if ((sid = socketAlloc(host, port, accept, flags)) < 0) {
+ return -1;
+ }
+ sp = socketList[sid];
+ a_assert(sp);
+
+/*
+ * Create the socket address structure
+ */
+ memset((char *) &sockaddr, '\0', sizeof(struct sockaddr_in));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons((short) (port & 0xFFFF));
+
+ if (host == NULL) {
+ sockaddr.sin_addr.s_addr = INADDR_ANY;
+ } else {
+ sockaddr.sin_addr.s_addr = inet_addr(host);
+ if (sockaddr.sin_addr.s_addr == INADDR_NONE) {
+/*
+ * If the OS does not support gethostbyname functionality, the macro:
+ * NO_GETHOSTBYNAME should be defined to skip the use of gethostbyname.
+ * Unfortunatly there is no easy way to recover, the following code
+ * simply uses the basicGetHost IP for the sockaddr.
+ */
+
+#ifdef NO_GETHOSTBYNAME
+ if (strcmp(host, basicGetHost()) == 0) {
+ sockaddr.sin_addr.s_addr = inet_addr(basicGetAddress());
+ }
+ if (sockaddr.sin_addr.s_addr == INADDR_NONE) {
+ socketFree(sid);
+ return -1;
+ }
+#elif (defined (VXWORKS))
+ sockaddr.sin_addr.s_addr = (unsigned long) hostGetByName(host);
+ if (sockaddr.sin_addr.s_addr == NULL) {
+ errno = ENXIO;
+ socketFree(sid);
+ return -1;
+ }
+#else
+ hostent = gethostbyname(host);
+ if (hostent != NULL) {
+ memcpy((char *) &sockaddr.sin_addr,
+ (char *) hostent->h_addr_list[0],
+ (size_t) hostent->h_length);
+ } else {
+ char *asciiAddress;
+ char_t *address;
+
+ address = basicGetAddress();
+ asciiAddress = ballocUniToAsc(address, gstrlen(address));
+ sockaddr.sin_addr.s_addr = inet_addr(asciiAddress);
+ bfree(B_L, asciiAddress);
+ if (sockaddr.sin_addr.s_addr == INADDR_NONE) {
+ errno = ENXIO;
+ socketFree(sid);
+ return -1;
+ }
+ }
+#endif /* (NO_GETHOSTBYNAME || VXWORKS) */
+ }
+ }
+
+ bcast = sp->flags & SOCKET_BROADCAST;
+ if (bcast) {
+ sp->flags |= SOCKET_DATAGRAM;
+ }
+ dgram = sp->flags & SOCKET_DATAGRAM;
+
+/*
+ * Create the socket. Support for datagram sockets. Set the close on
+ * exec flag so children don't inherit the socket.
+ */
+ sp->sock = socket(AF_INET, dgram ? SOCK_DGRAM: SOCK_STREAM, 0);
+ if (sp->sock < 0) {
+ socketFree(sid);
+ return -1;
+ }
+#ifndef __NO_FCNTL
+ fcntl(sp->sock, F_SETFD, FD_CLOEXEC);
+#endif
+ socketHighestFd = max(socketHighestFd, sp->sock);
+
+/*
+ * If broadcast, we need to turn on broadcast capability.
+ */
+ if (bcast) {
+ int broadcastFlag = 1;
+ if (setsockopt(sp->sock, SOL_SOCKET, SO_BROADCAST,
+ (char *) &broadcastFlag, sizeof(broadcastFlag)) < 0) {
+ socketFree(sid);
+ return -1;
+ }
+ }
+
+/*
+ * Host is set if we are the client
+ */
+ if (host) {
+/*
+ * Connect to the remote server in blocking mode, then go into
+ * non-blocking mode if desired.
+ */
+ if (!dgram) {
+ if (! (sp->flags & SOCKET_BLOCK)) {
+/*
+ * sockGen.c is only used for Windows products when blocking
+ * connects are expected. This applies to FieldUpgrader
+ * agents and open source webserver connectws. Therefore the
+ * asynchronous connect code here is not compiled.
+ */
+#if (defined (WIN) || defined (CE)) && (!defined (LITTLEFOOT) && !defined (WEBS))
+ int flag;
+
+ sp->flags |= SOCKET_ASYNC;
+/*
+ * Set to non-blocking for an async connect
+ */
+ flag = 1;
+ if (ioctlsocket(sp->sock, FIONBIO, &flag) == SOCKET_ERROR) {
+ socketFree(sid);
+ return -1;
+ }
+#else
+ socketSetBlock(sid, 1);
+#endif /* #if (WIN || CE) && !(LITTLEFOOT || WEBS) */
+
+ }
+ if ((rc = connect(sp->sock, (struct sockaddr *) &sockaddr,
+ sizeof(sockaddr))) < 0 &&
+ (rc = tryAlternateConnect(sp->sock,
+ (struct sockaddr *) &sockaddr)) < 0) {
+#if (defined (WIN) || defined (CE))
+ if (socketGetError() != EWOULDBLOCK) {
+ socketFree(sid);
+ return -1;
+ }
+#else
+ socketFree(sid);
+ return -1;
+
+#endif /* WIN || CE */
+
+ }
+ }
+ } else {
+/*
+ * Bind to the socket endpoint and the call listen() to start listening
+ */
+ rc = 1;
+ setsockopt(sp->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc));
+ if (bind(sp->sock, (struct sockaddr *) &sockaddr,
+ sizeof(sockaddr)) < 0) {
+ socketFree(sid);
+ return -1;
+ }
+
+ if (! dgram) {
+ if (listen(sp->sock, SOMAXCONN) < 0) {
+ socketFree(sid);
+ return -1;
+ }
+#ifndef UEMF
+ sp->fileHandle = emfCreateFileHandler(sp->sock, SOCKET_READABLE,
+ (emfFileProc *) socketAccept, (void *) sp);
+#else
+ sp->flags |= SOCKET_LISTENING;
+#endif
+ }
+ sp->handlerMask |= SOCKET_READABLE;
+ }
+
+/*
+ * Set the blocking mode
+ */
+
+ if (flags & SOCKET_BLOCK) {
+ socketSetBlock(sid, 1);
+ } else {
+ socketSetBlock(sid, 0);
+ }
+ return sid;
+}
+
+
+/******************************************************************************/
+/*
+ * If the connection 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 tryAlternateConnect(int sock, struct sockaddr *sockaddr)
+{
+#ifdef VXWORKS
+ char *ptr;
+
+ ptr = (char *)sockaddr;
+ *ptr = *(ptr+1);
+ *(ptr+1) = 0;
+ return connect(sock, sockaddr, sizeof(struct sockaddr));
+#else
+ return -1;
+#endif /* VXWORKS */
+}
+
+/******************************************************************************/
+/*
+ * Close a socket
+ */
+
+void socketCloseConnection(int sid)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return;
+ }
+ socketFree(sid);
+}
+
+/******************************************************************************/
+/*
+ * Accept a connection. Called as a callback on incoming connection.
+ */
+
+static void socketAccept(socket_t *sp)
+{
+ struct sockaddr_in addr;
+ socket_t *nsp;
+ size_t len;
+ char *pString;
+ int newSock, nid;
+
+
+#ifdef NW
+ NETINET_DEFINE_CONTEXT;
+#endif
+
+ a_assert(sp);
+
+/*
+ * Accept the connection and prevent inheriting by children (F_SETFD)
+ */
+ len = sizeof(struct sockaddr_in);
+ if ((newSock = accept(sp->sock, (struct sockaddr *) &addr, (int *) &len)) < 0) {
+ return;
+ }
+#ifndef __NO_FCNTL
+ fcntl(newSock, F_SETFD, FD_CLOEXEC);
+#endif
+ socketHighestFd = max(socketHighestFd, newSock);
+
+/*
+ * Create a socket structure and insert into the socket list
+ */
+ nid = socketAlloc(sp->host, sp->port, sp->accept, sp->flags);
+ nsp = socketList[nid];
+ a_assert(nsp);
+ nsp->sock = newSock;
+ nsp->flags &= ~SOCKET_LISTENING;
+
+ if (nsp == NULL) {
+ return;
+ }
+/*
+ * Set the blocking mode before calling the accept callback.
+ */
+
+ socketSetBlock(nid, (nsp->flags & SOCKET_BLOCK) ? 1: 0);
+/*
+ * Call the user accept callback. The user must call socketCreateHandler
+ * to register for further events of interest.
+ */
+ if (sp->accept != NULL) {
+ pString = inet_ntoa(addr.sin_addr);
+ if ((sp->accept)(nid, pString, ntohs(addr.sin_port), sp->sid) < 0) {
+ socketFree(nid);
+ }
+#ifdef VXWORKS
+ free(pString);
+#endif
+ }
+}
+
+/******************************************************************************/
+/*
+ * Get more input from the socket and return in buf.
+ * Returns 0 for EOF, -1 for errors and otherwise the number of bytes read.
+ */
+
+int socketGetInput(int sid, char *buf, int toRead, int *errCode)
+{
+ struct sockaddr_in server;
+ socket_t *sp;
+ int len, bytesRead;
+
+ a_assert(buf);
+ a_assert(errCode);
+
+ *errCode = 0;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return -1;
+ }
+
+/*
+ * If we have previously seen an EOF condition, then just return
+ */
+ if (sp->flags & SOCKET_EOF) {
+ return 0;
+ }
+#if ((defined (WIN) || defined (CE)) && (!defined (LITTLEFOOT) && !defined (WEBS)))
+ if ( !(sp->flags & SOCKET_BLOCK)
+ && ! socketWaitForEvent(sp, FD_CONNECT, errCode)) {
+ return -1;
+ }
+#endif
+
+/*
+ * Read the data
+ */
+ if (sp->flags & SOCKET_DATAGRAM) {
+ len = sizeof(server);
+ bytesRead = recvfrom(sp->sock, buf, toRead, 0,
+ (struct sockaddr *) &server, &len);
+ } else {
+ bytesRead = recv(sp->sock, buf, toRead, 0);
+ }
+
+ /*
+ * BUG 01865 -- CPU utilization hangs on Windows. The original code used
+ * the 'errno' global variable, which is not set by the winsock functions
+ * as it is under *nix platforms. We use the platform independent
+ * socketGetError() function instead, which does handle Windows correctly.
+ * Other, *nix compatible platforms should work as well, since on those
+ * platforms, socketGetError() just returns the value of errno.
+ * Thanks to Jonathan Burgoyne for the fix.
+ */
+ if (bytesRead < 0)
+ {
+ *errCode = socketGetError();
+ if (*errCode == ECONNRESET)
+ {
+ sp->flags |= SOCKET_CONNRESET;
+ return 0;
+ }
+ return -1;
+ }
+ return bytesRead;
+}
+
+/******************************************************************************/
+/*
+ * Process an event on the event queue
+ */
+
+#ifndef UEMF
+
+static int socketEventProc(void *data, int mask)
+{
+ socket_t *sp;
+ ringq_t *rq;
+ int sid;
+
+ sid = (int) data;
+
+ a_assert(sid >= 0 && sid < socketMax);
+ a_assert(socketList[sid]);
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return 1;
+ }
+
+/*
+ * If now writable and flushing in the background, continue flushing
+ */
+ if (mask & SOCKET_WRITABLE) {
+ if (sp->flags & SOCKET_FLUSHING) {
+ rq = &sp->outBuf;
+ if (ringqLen(rq) > 0) {
+ socketFlush(sp->sid);
+ } else {
+ sp->flags &= ~SOCKET_FLUSHING;
+ }
+ }
+ }
+
+/*
+ * Now invoke the users socket handler. NOTE: the handler may delete the
+ * socket, so we must be very careful after calling the handler.
+ */
+ if (sp->handler && (sp->handlerMask & mask)) {
+ (sp->handler)(sid, mask & sp->handlerMask, sp->handler_data);
+ }
+ if (socketList && sid < socketMax && socketList[sid] == sp) {
+ socketRegisterInterest(sp, sp->handlerMask);
+ }
+ return 1;
+}
+#endif /* ! UEMF */
+
+/******************************************************************************/
+/*
+ * Define the events of interest
+ */
+
+void socketRegisterInterest(socket_t *sp, int handlerMask)
+{
+ a_assert(sp);
+
+ sp->handlerMask = handlerMask;
+#ifndef UEMF
+ if (handlerMask) {
+ sp->fileHandle = emfCreateFileHandler(sp->sock, handlerMask,
+ (emfFileProc *) socketEventProc, (void *) sp->sid);
+ } else {
+ emfDeleteFileHandler(sp->fileHandle);
+ sp->fileHandle = -1;
+ }
+#endif /* ! UEMF */
+}
+
+/******************************************************************************/
+/*
+ * Wait until an event occurs on a socket. Return 1 on success, 0 on failure.
+ * or -1 on exception (UEMF only)
+ */
+
+int socketWaitForEvent(socket_t *sp, int handlerMask, int *errCode)
+{
+ int mask;
+
+ a_assert(sp);
+
+ mask = sp->handlerMask;
+ sp->handlerMask |= handlerMask;
+ while (socketSelect(sp->sid, 1000)) {
+ if (sp->currentEvents & (handlerMask | SOCKET_EXCEPTION)) {
+ break;
+ }
+ }
+ sp->handlerMask = mask;
+ if (sp->currentEvents & SOCKET_EXCEPTION) {
+ return -1;
+ } else if (sp->currentEvents & handlerMask) {
+ return 1;
+ }
+ if (errCode) {
+ *errCode = errno = EWOULDBLOCK;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Return TRUE if there is a socket with an event ready to process,
+ */
+
+int socketReady(int sid)
+{
+ socket_t *sp;
+ int all;
+
+ all = 0;
+ if (sid < 0) {
+ sid = 0;
+ all = 1;
+ }
+
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (! all) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ if (sp->flags & SOCKET_CONNRESET) {
+ socketCloseConnection(sid);
+ return 0;
+ }
+ if (sp->currentEvents & sp->handlerMask) {
+ return 1;
+ }
+/*
+ * If there is input data, also call select to test for new events
+ */
+ if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) {
+ socketSelect(sid, 0);
+ return 1;
+ }
+ if (! all) {
+ break;
+ }
+ }
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Wait for a handle to become readable or writable and return a number of
+ * noticed events. Timeout is in milliseconds.
+ */
+
+#if (defined (WIN) || defined (CE) || defined (NW))
+
+int socketSelect(int sid, int timeout)
+{
+ struct timeval tv;
+ socket_t *sp;
+ fd_set readFds, writeFds, exceptFds;
+ int nEvents;
+ int all, socketHighestFd; /* Highest socket fd opened */
+
+ FD_ZERO(&readFds);
+ FD_ZERO(&writeFds);
+ FD_ZERO(&exceptFds);
+ socketHighestFd = -1;
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
+/*
+ * Set the select event masks for events to watch
+ */
+ all = nEvents = 0;
+
+ if (sid < 0) {
+ all++;
+ sid = 0;
+ }
+
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ continue;
+ }
+ a_assert(sp);
+/*
+ * Set the appropriate bit in the ready masks for the sp->sock.
+ */
+ if (sp->handlerMask & SOCKET_READABLE) {
+ FD_SET(sp->sock, &readFds);
+ nEvents++;
+ if (socketInputBuffered(sid) > 0) {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+ }
+ if (sp->handlerMask & SOCKET_WRITABLE) {
+ FD_SET(sp->sock, &writeFds);
+ nEvents++;
+ }
+ if (sp->handlerMask & SOCKET_EXCEPTION) {
+ FD_SET(sp->sock, &exceptFds);
+ nEvents++;
+ }
+ if (! all) {
+ break;
+ }
+ }
+
+/*
+ * Windows select() fails if no descriptors are set, instead of just sleeping
+ * like other, nice select() calls. So, if WIN, sleep.
+ */
+ if (nEvents == 0) {
+ Sleep(timeout);
+ return 0;
+ }
+
+/*
+ * Wait for the event or a timeout.
+ */
+ nEvents = select(socketHighestFd+1, &readFds, &writeFds, &exceptFds, &tv);
+
+ if (all) {
+ sid = 0;
+ }
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ continue;
+ }
+
+ if (FD_ISSET(sp->sock, &readFds) || socketInputBuffered(sid) > 0) {
+ sp->currentEvents |= SOCKET_READABLE;
+ }
+ if (FD_ISSET(sp->sock, &writeFds)) {
+ sp->currentEvents |= SOCKET_WRITABLE;
+ }
+ if (FD_ISSET(sp->sock, &exceptFds)) {
+ sp->currentEvents |= SOCKET_EXCEPTION;
+ }
+ if (! all) {
+ break;
+ }
+ }
+
+ return nEvents;
+}
+
+#else /* not WIN || CE || NW */
+
+int socketSelect(int sid, int timeout)
+{
+ socket_t *sp;
+ struct timeval tv;
+ fd_mask *readFds, *writeFds, *exceptFds;
+ int all, len, nwords, index, bit, nEvents;
+
+/*
+ * Allocate and zero the select masks
+ */
+ nwords = (socketHighestFd + NFDBITS) / NFDBITS;
+ len = nwords * sizeof(int);
+
+ readFds = balloc(B_L, len);
+ memset(readFds, 0, len);
+ writeFds = balloc(B_L, len);
+ memset(writeFds, 0, len);
+ exceptFds = balloc(B_L, len);
+ memset(exceptFds, 0, len);
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
+/*
+ * Set the select event masks for events to watch
+ */
+ all = nEvents = 0;
+
+ if (sid < 0) {
+ all++;
+ sid = 0;
+ }
+
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (all == 0) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ a_assert(sp);
+
+/*
+ * Initialize the ready masks and compute the mask offsets.
+ */
+ index = sp->sock / (NBBY * sizeof(fd_mask));
+ bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
+
+/*
+ * Set the appropriate bit in the ready masks for the sp->sock.
+ */
+ if (sp->handlerMask & SOCKET_READABLE) {
+ readFds[index] |= bit;
+ nEvents++;
+ if (socketInputBuffered(sid) > 0) {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+ }
+ if (sp->handlerMask & SOCKET_WRITABLE) {
+ writeFds[index] |= bit;
+ nEvents++;
+ }
+ if (sp->handlerMask & SOCKET_EXCEPTION) {
+ exceptFds[index] |= bit;
+ nEvents++;
+ }
+ if (! all) {
+ break;
+ }
+ }
+
+/*
+ * Wait for the event or a timeout. Reset nEvents to be the number of actual
+ * events now.
+ */
+ nEvents = select(socketHighestFd + 1, (fd_set *) readFds,
+ (fd_set *) writeFds, (fd_set *) exceptFds, &tv);
+
+ if (nEvents > 0) {
+ if (all) {
+ sid = 0;
+ }
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (all == 0) {
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ index = sp->sock / (NBBY * sizeof(fd_mask));
+ bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
+
+ if (readFds[index] & bit || socketInputBuffered(sid) > 0) {
+ sp->currentEvents |= SOCKET_READABLE;
+ }
+ if (writeFds[index] & bit) {
+ sp->currentEvents |= SOCKET_WRITABLE;
+ }
+ if (exceptFds[index] & bit) {
+ sp->currentEvents |= SOCKET_EXCEPTION;
+ }
+ if (! all) {
+ break;
+ }
+ }
+ }
+
+ bfree(B_L, readFds);
+ bfree(B_L, writeFds);
+ bfree(B_L, exceptFds);
+
+ return nEvents;
+}
+#endif /* WIN || CE */
+
+/******************************************************************************/
+/*
+ * Process socket events
+ */
+
+void socketProcess(int sid)
+{
+ socket_t *sp;
+ int all;
+
+ all = 0;
+ if (sid < 0) {
+ all = 1;
+ sid = 0;
+ }
+/*
+ * Process each socket
+ */
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (! all) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ if (socketReady(sid)) {
+ socketDoEvent(sp);
+ }
+ if (! all) {
+ break;
+ }
+ }
+}
+
+/******************************************************************************/
+/*
+ * Process an event on the event queue
+ */
+
+static int socketDoEvent(socket_t *sp)
+{
+ ringq_t *rq;
+ int sid;
+
+ a_assert(sp);
+
+ sid = sp->sid;
+ if (sp->currentEvents & SOCKET_READABLE) {
+ if (sp->flags & SOCKET_LISTENING) {
+ socketAccept(sp);
+ sp->currentEvents = 0;
+ return 1;
+ }
+
+ } else {
+/*
+ * If there is still read data in the buffers, trigger the read handler
+ * NOTE: this may busy spin if the read handler doesn't read the data
+ */
+ if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) {
+ sp->currentEvents |= SOCKET_READABLE;
+ }
+ }
+
+
+/*
+ * If now writable and flushing in the background, continue flushing
+ */
+ if (sp->currentEvents & SOCKET_WRITABLE) {
+ if (sp->flags & SOCKET_FLUSHING) {
+ rq = &sp->outBuf;
+ if (ringqLen(rq) > 0) {
+ socketFlush(sp->sid);
+ } else {
+ sp->flags &= ~SOCKET_FLUSHING;
+ }
+ }
+ }
+
+/*
+ * Now invoke the users socket handler. NOTE: the handler may delete the
+ * socket, so we must be very careful after calling the handler.
+ */
+ if (sp->handler && (sp->handlerMask & sp->currentEvents)) {
+ (sp->handler)(sid, sp->handlerMask & sp->currentEvents,
+ sp->handler_data);
+/*
+ * Make sure socket pointer is still valid, then reset the currentEvents.
+ */
+ if (socketList && sid < socketMax && socketList[sid] == sp) {
+ sp->currentEvents = 0;
+ }
+ }
+ return 1;
+}
+
+/******************************************************************************/
+/*
+ * Set the socket blocking mode
+ */
+
+int socketSetBlock(int sid, int on)
+{
+ socket_t *sp;
+ unsigned long flag;
+ int iflag;
+ int oldBlock;
+
+ flag = iflag = !on;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ a_assert(0);
+ return 0;
+ }
+ oldBlock = (sp->flags & SOCKET_BLOCK);
+ sp->flags &= ~(SOCKET_BLOCK);
+ if (on) {
+ sp->flags |= SOCKET_BLOCK;
+ }
+
+/*
+ * Put the socket into block / non-blocking mode
+ */
+ if (sp->flags & SOCKET_BLOCK) {
+#if (defined (CE) || defined (WIN))
+ ioctlsocket(sp->sock, FIONBIO, &flag);
+#elif (defined (ECOS))
+ int off;
+ off = 0;
+ ioctl(sp->sock, FIONBIO, &off);
+#elif (defined (VXWORKS) || defined (NW))
+ ioctl(sp->sock, FIONBIO, (int)&iflag);
+#else
+ fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) & ~O_NONBLOCK);
+#endif
+
+ } else {
+#if (defined (CE) || defined (WIN))
+ ioctlsocket(sp->sock, FIONBIO, &flag);
+#elif (defined (ECOS))
+ int on;
+ on = 1;
+ ioctl(sp->sock, FIONBIO, &on);
+#elif (defined (VXWORKS) || defined (NW))
+ ioctl(sp->sock, FIONBIO, (int)&iflag);
+#else
+ fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) | O_NONBLOCK);
+#endif
+ }
+ return oldBlock;
+}
+
+/******************************************************************************/
+/*
+ * Return true if a readable socket has buffered data. - not public
+ */
+
+int socketDontBlock()
+{
+ socket_t *sp;
+ int i;
+
+ for (i = 0; i < socketMax; i++) {
+ if ((sp = socketList[i]) == NULL ||
+ (sp->handlerMask & SOCKET_READABLE) == 0) {
+ continue;
+ }
+ if (socketInputBuffered(i) > 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Return true if a particular socket buffered data. - not public
+ */
+
+int socketSockBuffered(int sock)
+{
+ socket_t *sp;
+ int i;
+
+ for (i = 0; i < socketMax; i++) {
+ if ((sp = socketList[i]) == NULL || sp->sock != sock) {
+ continue;
+ }
+ return socketInputBuffered(i);
+ }
+ return 0;
+}
+
+#endif /* (!WIN) | LITTLEFOOT | WEBS */
+
+/******************************************************************************/
diff --git a/cpukit/httpd/socket.c b/cpukit/httpd/socket.c
new file mode 100644
index 0000000000..430139bd68
--- /dev/null
+++ b/cpukit/httpd/socket.c
@@ -0,0 +1,1024 @@
+
+/*
+ * sockGen.c -- Posix Socket 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.
+ */
+
+#if (!WIN) || LITTLEFOOT || WEBS
+
+/********************************** 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
+
+#if VXWORKS
+ #include <hostLib.h>
+#endif
+
+#if __rtems__
+ #include <sys/select.h>
+#endif
+
+/************************************ Locals **********************************/
+
+extern socket_t **socketList; /* List of open sockets */
+extern int socketMax; /* Maximum size of socket */
+extern int socketHighestFd; /* Highest socket fd opened */
+static int socketOpenCount = 0; /* Number of task using sockets */
+
+/***************************** Forward Declarations ***************************/
+
+static void socketAccept(socket_t *sp);
+static int socketDoEvent(socket_t *sp);
+static int tryAlternateConnect(int sock, struct sockaddr *sockaddr);
+
+/*********************************** Code *************************************/
+/*
+ * Open socket module
+ */
+
+int socketOpen()
+{
+#if CE || WIN
+ WSADATA wsaData;
+#endif
+
+ if (++socketOpenCount > 1) {
+ return 0;
+ }
+
+#if CE || WIN
+ if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) {
+ return -1;
+ }
+ if (wsaData.wVersion != MAKEWORD(1,1)) {
+ WSACleanup();
+ return -1;
+ }
+#endif
+ socketList = NULL;
+ socketMax = 0;
+ socketHighestFd = -1;
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Close the socket module, by closing all open connections
+ */
+
+void socketClose()
+{
+ int i;
+
+ if (--socketOpenCount <= 0) {
+ for (i = socketMax; i >= 0; i--) {
+ if (socketList && socketList[i]) {
+ socketCloseConnection(i);
+ }
+ }
+ socketOpenCount = 0;
+ }
+}
+
+/******************************************************************************/
+/*
+ * Open a client or server socket. Host is NULL if we want server capability.
+ */
+
+int socketOpenConnection(char *host, int port, socketAccept_t accept, int flags)
+{
+#if ! (NO_GETHOSTBYNAME || VXWORKS)
+ struct hostent *hostent; /* Host database entry */
+#endif /* ! (NO_GETHOSTBYNAME || VXWORKS) */
+ socket_t *sp;
+ struct sockaddr_in sockaddr;
+ int sid, bcast, dgram, rc;
+
+ if (port > SOCKET_PORT_MAX) {
+ return -1;
+ }
+/*
+ * Allocate a socket structure
+ */
+ if ((sid = socketAlloc(host, port, accept, flags)) < 0) {
+ return -1;
+ }
+ sp = socketList[sid];
+ a_assert(sp);
+
+/*
+ * Create the socket address structure
+ */
+ memset((char *) &sockaddr, '\0', sizeof(struct sockaddr_in));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons((short) (port & 0xFFFF));
+
+ if (host == NULL) {
+ sockaddr.sin_addr.s_addr = INADDR_ANY;
+ } else {
+ sockaddr.sin_addr.s_addr = inet_addr(host);
+ if (sockaddr.sin_addr.s_addr == INADDR_NONE) {
+/*
+ * If the OS does not support gethostbyname functionality, the macro:
+ * NO_GETHOSTBYNAME should be defined to skip the use of gethostbyname.
+ * Unfortunatly there is no easy way to recover, the following code
+ * simply uses the basicGetHost IP for the sockaddr.
+ */
+
+#if NO_GETHOSTBYNAME
+ if (strcmp(host, basicGetHost()) == 0) {
+ sockaddr.sin_addr.s_addr = inet_addr(basicGetAddress());
+ }
+ if (sockaddr.sin_addr.s_addr == INADDR_NONE) {
+ socketFree(sid);
+ return -1;
+ }
+#elif VXWORKS
+ sockaddr.sin_addr.s_addr = (unsigned long) hostGetByName(host);
+ if (sockaddr.sin_addr.s_addr == NULL) {
+ errno = ENXIO;
+ socketFree(sid);
+ return -1;
+ }
+#else
+ hostent = gethostbyname(host);
+ if (hostent != NULL) {
+ memcpy((char *) &sockaddr.sin_addr,
+ (char *) hostent->h_addr_list[0],
+ (size_t) hostent->h_length);
+ } else {
+ char *asciiAddress;
+ char_t *address;
+
+ address = basicGetAddress();
+ asciiAddress = ballocUniToAsc(address, gstrlen(address));
+ sockaddr.sin_addr.s_addr = inet_addr(asciiAddress);
+ bfree(B_L, asciiAddress);
+ if (sockaddr.sin_addr.s_addr == INADDR_NONE) {
+ errno = ENXIO;
+ socketFree(sid);
+ return -1;
+ }
+ }
+#endif /* (NO_GETHOSTBYNAME || VXWORKS) */
+ }
+ }
+
+ bcast = sp->flags & SOCKET_BROADCAST;
+ if (bcast) {
+ sp->flags |= SOCKET_DATAGRAM;
+ }
+ dgram = sp->flags & SOCKET_DATAGRAM;
+
+/*
+ * Create the socket. Support for datagram sockets. Set the close on
+ * exec flag so children don't inherit the socket.
+ */
+ sp->sock = socket(AF_INET, dgram ? SOCK_DGRAM: SOCK_STREAM, 0);
+ if (sp->sock < 0) {
+ socketFree(sid);
+ return -1;
+ }
+#ifndef __NO_FCNTL
+ fcntl(sp->sock, F_SETFD, FD_CLOEXEC);
+#endif
+ socketHighestFd = max(socketHighestFd, sp->sock);
+
+/*
+ * If broadcast, we need to turn on broadcast capability.
+ */
+ if (bcast) {
+ int broadcastFlag = 1;
+ if (setsockopt(sp->sock, SOL_SOCKET, SO_BROADCAST,
+ (char *) &broadcastFlag, sizeof(broadcastFlag)) < 0) {
+ socketFree(sid);
+ return -1;
+ }
+ }
+
+/*
+ * Host is set if we are the client
+ */
+ if (host) {
+/*
+ * Connect to the remote server in blocking mode, then go into
+ * non-blocking mode if desired.
+ */
+ if (!dgram) {
+ if (! (sp->flags & SOCKET_BLOCK)) {
+/*
+ * sockGen.c is only used for Windows products when blocking
+ * connects are expected. This applies to FieldUpgrader
+ * agents and open source webserver connectws. Therefore the
+ * asynchronous connect code here is not compiled.
+ */
+#if (WIN || CE) && !(LITTLEFOOT || WEBS)
+ int flag;
+
+ sp->flags |= SOCKET_ASYNC;
+/*
+ * Set to non-blocking for an async connect
+ */
+ flag = 1;
+ if (ioctlsocket(sp->sock, FIONBIO, &flag) == SOCKET_ERROR) {
+ socketFree(sid);
+ return -1;
+ }
+#else
+ socketSetBlock(sid, 1);
+#endif /* #if (WIN || CE) && !(LITTLEFOOT || WEBS) */
+
+ }
+ if ((rc = connect(sp->sock, (struct sockaddr *) &sockaddr,
+ sizeof(sockaddr))) < 0 &&
+ (rc = tryAlternateConnect(sp->sock,
+ (struct sockaddr *) &sockaddr)) < 0) {
+#if WIN || CE
+ if (socketGetError() != EWOULDBLOCK) {
+ socketFree(sid);
+ return -1;
+ }
+#else
+ socketFree(sid);
+ return -1;
+
+#endif /* WIN || CE */
+
+ }
+ }
+ } else {
+/*
+ * Bind to the socket endpoint and the call listen() to start listening
+ */
+ rc = 1;
+ setsockopt(sp->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc));
+ if (bind(sp->sock, (struct sockaddr *) &sockaddr,
+ sizeof(sockaddr)) < 0) {
+ socketFree(sid);
+ return -1;
+ }
+
+ if (! dgram) {
+ if (listen(sp->sock, SOMAXCONN) < 0) {
+ socketFree(sid);
+ return -1;
+ }
+#if !UEMF
+ sp->fileHandle = emfCreateFileHandler(sp->sock, SOCKET_READABLE,
+ (emfFileProc *) socketAccept, (void *) sp);
+#else
+ sp->flags |= SOCKET_LISTENING;
+#endif
+ }
+ sp->handlerMask |= SOCKET_READABLE;
+ }
+
+/*
+ * Set the blocking mode
+ */
+
+ if (flags & SOCKET_BLOCK) {
+ socketSetBlock(sid, 1);
+ } else {
+ socketSetBlock(sid, 0);
+ }
+ return sid;
+}
+
+/******************************************************************************/
+/*
+ * If the connection 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 tryAlternateConnect(int sock, struct sockaddr *sockaddr)
+{
+#if VXWORKS
+ char *ptr;
+
+ ptr = (char *)sockaddr;
+ *ptr = *(ptr+1);
+ *(ptr+1) = 0;
+ return connect(sock, sockaddr, sizeof(struct sockaddr));
+#else
+ return -1;
+#endif /* VXWORKS */
+}
+
+/******************************************************************************/
+/*
+ * Close a socket
+ */
+
+void socketCloseConnection(int sid)
+{
+ socket_t *sp;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return;
+ }
+ socketFree(sid);
+}
+
+/******************************************************************************/
+/*
+ * Accept a connection. Called as a callback on incoming connection.
+ */
+
+static void socketAccept(socket_t *sp)
+{
+ union {
+ struct sockaddr addr;
+ struct sockaddr_in addr_in;
+ } overlay;
+ struct sockaddr_in *addr;
+ socket_t *nsp;
+ socklen_t len;
+ char *pString;
+ int newSock, nid;
+
+ a_assert(sp);
+ addr = &overlay.addr_in;
+
+/*
+ * Accept the connection and prevent inheriting by children (F_SETFD)
+ */
+ len = sizeof(struct sockaddr_in);
+ if ((newSock = accept(sp->sock, &overlay.addr, &len)) < 0) {
+ return;
+ }
+#ifndef __NO_FCNTL
+ fcntl(newSock, F_SETFD, FD_CLOEXEC);
+#endif
+ socketHighestFd = max(socketHighestFd, newSock);
+
+/*
+ * Create a socket structure and insert into the socket list
+ */
+ nid = socketAlloc(sp->host, sp->port, sp->accept, sp->flags);
+ nsp = socketList[nid];
+ a_assert(nsp);
+ nsp->sock = newSock;
+ nsp->flags &= ~SOCKET_LISTENING;
+
+ if (nsp == NULL) {
+ return;
+ }
+/*
+ * Set the blocking mode before calling the accept callback.
+ */
+
+ socketSetBlock(nid, (nsp->flags & SOCKET_BLOCK) ? 1: 0);
+/*
+ * Call the user accept callback. The user must call socketCreateHandler
+ * to register for further events of interest.
+ */
+ if (sp->accept != NULL) {
+ pString = inet_ntoa(addr->sin_addr);
+ if ((sp->accept)(nid, pString, ntohs(addr->sin_port), sp->sid) < 0) {
+ socketFree(nid);
+ }
+#if VXWORKS
+ free(pString);
+#endif
+ }
+}
+
+/******************************************************************************/
+/*
+ * Get more input from the socket and return in buf.
+ * Returns 0 for EOF, -1 for errors and otherwise the number of bytes read.
+ */
+
+int socketGetInput(int sid, char *buf, int toRead, int *errCode)
+{
+ struct sockaddr_in server;
+ socket_t *sp;
+ socklen_t len;
+ int bytesRead;
+
+ a_assert(buf);
+ a_assert(errCode);
+
+ *errCode = 0;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return -1;
+ }
+
+/*
+ * If we have previously seen an EOF condition, then just return
+ */
+ if (sp->flags & SOCKET_EOF) {
+ return 0;
+ }
+#if (WIN || CE) && !(LITTLEFOOT || WEBS)
+ if ( !(sp->flags & SOCKET_BLOCK)
+ && ! socketWaitForEvent(sp, FD_CONNECT, errCode)) {
+ return -1;
+ }
+#endif
+
+/*
+ * Read the data
+ */
+ if (sp->flags & SOCKET_DATAGRAM) {
+ len = sizeof(server);
+ bytesRead = recvfrom(sp->sock, buf, toRead, 0,
+ (struct sockaddr *) &server, &len);
+ } else {
+ bytesRead = recv(sp->sock, buf, toRead, 0);
+ }
+ if (bytesRead < 0) {
+ if (errno == ECONNRESET) {
+ return 0;
+ }
+ *errCode = socketGetError();
+ return -1;
+ }
+ return bytesRead;
+}
+
+/******************************************************************************/
+/*
+ * Process an event on the event queue
+ */
+
+#ifndef UEMF
+
+static int socketEventProc(void *data, int mask)
+{
+ socket_t *sp;
+ ringq_t *rq;
+ int sid;
+
+ sid = (int) data;
+
+ a_assert(sid >= 0 && sid < socketMax);
+ a_assert(socketList[sid]);
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ return 1;
+ }
+
+/*
+ * If now writable and flushing in the background, continue flushing
+ */
+ if (mask & SOCKET_WRITABLE) {
+ if (sp->flags & SOCKET_FLUSHING) {
+ rq = &sp->outBuf;
+ if (ringqLen(rq) > 0) {
+ socketFlush(sp->sid);
+ } else {
+ sp->flags &= ~SOCKET_FLUSHING;
+ }
+ }
+ }
+
+/*
+ * Now invoke the users socket handler. NOTE: the handler may delete the
+ * socket, so we must be very careful after calling the handler.
+ */
+ if (sp->handler && (sp->handlerMask & mask)) {
+ (sp->handler)(sid, mask & sp->handlerMask, sp->handler_data);
+ }
+ if (socketList && sid < socketMax && socketList[sid] == sp) {
+ socketRegisterInterest(sp, sp->handlerMask);
+ }
+ return 1;
+}
+#endif /* ! UEMF */
+
+/******************************************************************************/
+/*
+ * Define the events of interest
+ */
+
+void socketRegisterInterest(socket_t *sp, int handlerMask)
+{
+ a_assert(sp);
+
+ sp->handlerMask = handlerMask;
+#if !UEMF
+ if (handlerMask) {
+ sp->fileHandle = emfCreateFileHandler(sp->sock, handlerMask,
+ (emfFileProc *) socketEventProc, (void *) sp->sid);
+ } else {
+ emfDeleteFileHandler(sp->fileHandle);
+ }
+#endif /* ! UEMF */
+}
+
+/******************************************************************************/
+/*
+ * Wait until an event occurs on a socket. Return 1 on success, 0 on failure.
+ * or -1 on exception (UEMF only)
+ */
+
+int socketWaitForEvent(socket_t *sp, int handlerMask, int *errCode)
+{
+ int mask;
+
+ a_assert(sp);
+
+ mask = sp->handlerMask;
+ sp->handlerMask |= handlerMask;
+ while (socketSelect(sp->sid, 1000)) {
+ if (sp->currentEvents & (handlerMask | SOCKET_EXCEPTION)) {
+ break;
+ }
+ }
+ sp->handlerMask = mask;
+ if (sp->currentEvents & SOCKET_EXCEPTION) {
+ return -1;
+ } else if (sp->currentEvents & handlerMask) {
+ return 1;
+ }
+ if (errCode) {
+ *errCode = errno = EWOULDBLOCK;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Return TRUE if there is a socket with an event ready to process,
+ */
+
+int socketReady(int sid)
+{
+ socket_t *sp;
+ int all;
+
+ all = 0;
+ if (sid < 0) {
+ sid = 0;
+ all = 1;
+ }
+
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (! all) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ if (sp->currentEvents & sp->handlerMask) {
+ return 1;
+ }
+/*
+ * If there is input data, also call select to test for new events
+ */
+ if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid)) {
+ socketSelect(sid, 0);
+ return 1;
+ }
+ if (! all) {
+ break;
+ }
+ }
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Wait for a handle to become readable or writable and return a number of
+ * noticed events. Timeout is in milliseconds.
+ */
+
+#if WIN || CE
+
+int socketSelect(int sid, int timeout)
+{
+ struct timeval tv;
+ socket_t *sp;
+ fd_set readFds, writeFds, exceptFds;
+ int nEvents;
+ int all, socketHighestFd; /* Highest socket fd opened */
+
+ FD_ZERO(&readFds);
+ FD_ZERO(&writeFds);
+ FD_ZERO(&exceptFds);
+ socketHighestFd = -1;
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
+/*
+ * Set the select event masks for events to watch
+ */
+ all = nEvents = 0;
+
+ if (sid < 0) {
+ all++;
+ sid = 0;
+ }
+
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ continue;
+ }
+ a_assert(sp);
+/*
+ * Set the appropriate bit in the ready masks for the sp->sock.
+ */
+ if (sp->handlerMask & SOCKET_READABLE) {
+ FD_SET(sp->sock, &readFds);
+ nEvents++;
+ if (socketInputBuffered(sid) > 0) {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+ }
+ if (sp->handlerMask & SOCKET_WRITABLE) {
+ FD_SET(sp->sock, &writeFds);
+ nEvents++;
+ }
+ if (sp->handlerMask & SOCKET_EXCEPTION) {
+ FD_SET(sp->sock, &exceptFds);
+ nEvents++;
+ }
+ if (! all) {
+ break;
+ }
+ }
+
+/*
+ * Windows select() fails if no descriptors are set, instead of just sleeping
+ * like other, nice select() calls. So, if WIN, sleep.
+ */
+ if (nEvents == 0) {
+ Sleep(timeout);
+ return 0;
+ }
+
+/*
+ * Wait for the event or a timeout.
+ */
+ nEvents = select(socketHighestFd+1, &readFds, &writeFds, &exceptFds, &tv);
+
+ if (all) {
+ sid = 0;
+ }
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ continue;
+ }
+
+ if (FD_ISSET(sp->sock, &readFds) || socketInputBuffered(sid) > 0) {
+ sp->currentEvents |= SOCKET_READABLE;
+ }
+ if (FD_ISSET(sp->sock, &writeFds)) {
+ sp->currentEvents |= SOCKET_WRITABLE;
+ }
+ if (FD_ISSET(sp->sock, &exceptFds)) {
+ sp->currentEvents |= SOCKET_EXCEPTION;
+ }
+ if (! all) {
+ break;
+ }
+ }
+
+ return nEvents;
+}
+
+#else /* not WIN || CE */
+
+int socketSelect(int sid, int timeout)
+{
+ socket_t *sp;
+ struct timeval tv;
+ fd_mask *readFds, *writeFds, *exceptFds;
+ int all, len, nwords, index, bit, nEvents;
+
+/*
+ * Allocate and zero the select masks
+ */
+ nwords = (socketHighestFd + NFDBITS) / NFDBITS;
+ len = nwords * sizeof(int);
+
+ readFds = balloc(B_L, len);
+ memset(readFds, 0, len);
+ writeFds = balloc(B_L, len);
+ memset(writeFds, 0, len);
+ exceptFds = balloc(B_L, len);
+ memset(exceptFds, 0, len);
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
+/*
+ * Set the select event masks for events to watch
+ */
+ all = nEvents = 0;
+
+ if (sid < 0) {
+ all++;
+ sid = 0;
+ }
+
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (all == 0) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ a_assert(sp);
+
+/*
+ * Initialize the ready masks and compute the mask offsets.
+ */
+ index = sp->sock / (NBBY * sizeof(fd_mask));
+ bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
+
+/*
+ * Set the appropriate bit in the ready masks for the sp->sock.
+ */
+ if (sp->handlerMask & SOCKET_READABLE) {
+ readFds[index] |= bit;
+ nEvents++;
+ if (socketInputBuffered(sid) > 0) {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+ }
+ if (sp->handlerMask & SOCKET_WRITABLE) {
+ writeFds[index] |= bit;
+ nEvents++;
+ }
+ if (sp->handlerMask & SOCKET_EXCEPTION) {
+ exceptFds[index] |= bit;
+ nEvents++;
+ }
+ if (! all) {
+ break;
+ }
+ }
+
+/*
+ * Wait for the event or a timeout. Reset nEvents to be the number of actual
+ * events now.
+ */
+ nEvents = select(socketHighestFd + 1, (fd_set *) readFds,
+ (fd_set *) writeFds, (fd_set *) exceptFds, &tv);
+
+ if (nEvents > 0) {
+ if (all) {
+ sid = 0;
+ }
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (all == 0) {
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ index = sp->sock / (NBBY * sizeof(fd_mask));
+ bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
+
+ if (readFds[index] & bit || socketInputBuffered(sid) > 0) {
+ sp->currentEvents |= SOCKET_READABLE;
+ }
+ if (writeFds[index] & bit) {
+ sp->currentEvents |= SOCKET_WRITABLE;
+ }
+ if (exceptFds[index] & bit) {
+ sp->currentEvents |= SOCKET_EXCEPTION;
+ }
+ if (! all) {
+ break;
+ }
+ }
+ }
+
+ bfree(B_L, readFds);
+ bfree(B_L, writeFds);
+ bfree(B_L, exceptFds);
+
+ return nEvents;
+}
+#endif /* WIN || CE */
+
+/******************************************************************************/
+/*
+ * Process socket events
+ */
+
+void socketProcess(int sid)
+{
+ socket_t *sp;
+ int all;
+
+ all = 0;
+ if (sid < 0) {
+ all = 1;
+ sid = 0;
+ }
+/*
+ * Process each socket
+ */
+ for (; sid < socketMax; sid++) {
+ if ((sp = socketList[sid]) == NULL) {
+ if (! all) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ if (socketReady(sid)) {
+ socketDoEvent(sp);
+ }
+ if (! all) {
+ break;
+ }
+ }
+}
+
+/******************************************************************************/
+/*
+ * Process an event on the event queue
+ */
+
+static int socketDoEvent(socket_t *sp)
+{
+ ringq_t *rq;
+ int sid;
+
+ a_assert(sp);
+
+ sid = sp->sid;
+ if (sp->currentEvents & SOCKET_READABLE) {
+ if (sp->flags & SOCKET_LISTENING) {
+ socketAccept(sp);
+ sp->currentEvents = 0;
+ return 1;
+ }
+
+ } else {
+/*
+ * If there is still read data in the buffers, trigger the read handler
+ * NOTE: this may busy spin if the read handler doesn't read the data
+ */
+ if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid)) {
+ sp->currentEvents |= SOCKET_READABLE;
+ }
+ }
+
+
+/*
+ * If now writable and flushing in the background, continue flushing
+ */
+ if (sp->currentEvents & SOCKET_WRITABLE) {
+ if (sp->flags & SOCKET_FLUSHING) {
+ rq = &sp->outBuf;
+ if (ringqLen(rq) > 0) {
+ socketFlush(sp->sid);
+ } else {
+ sp->flags &= ~SOCKET_FLUSHING;
+ }
+ }
+ }
+
+/*
+ * Now invoke the users socket handler. NOTE: the handler may delete the
+ * socket, so we must be very careful after calling the handler.
+ */
+ if (sp->handler && (sp->handlerMask & sp->currentEvents)) {
+ (sp->handler)(sid, sp->handlerMask & sp->currentEvents,
+ sp->handler_data);
+/*
+ * Make sure socket pointer is still valid, then reset the currentEvents.
+ */
+ if (socketList && sid < socketMax && socketList[sid] == sp) {
+ sp->currentEvents = 0;
+ }
+ }
+ return 1;
+}
+
+/******************************************************************************/
+/*
+ * Set the socket blocking mode
+ */
+
+int socketSetBlock(int sid, int on)
+{
+ socket_t *sp;
+ unsigned long flag;
+ int iflag;
+ int oldBlock;
+
+ flag = iflag = !on;
+
+ if ((sp = socketPtr(sid)) == NULL) {
+ a_assert(0);
+ return 0;
+ }
+ oldBlock = (sp->flags & SOCKET_BLOCK);
+ sp->flags &= ~(SOCKET_BLOCK);
+ if (on) {
+ sp->flags |= SOCKET_BLOCK;
+ }
+
+/*
+ * Put the socket into block / non-blocking mode
+ */
+ if (sp->flags & SOCKET_BLOCK) {
+#if CE || WIN
+ ioctlsocket(sp->sock, FIONBIO, &flag);
+#elif ECOS
+ int off;
+ off = 0;
+ ioctl(sp->sock, FIONBIO, &off);
+#elif VXWORKS
+ ioctl(sp->sock, FIONBIO, (int)&iflag);
+#else
+ fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) & ~O_NONBLOCK);
+#endif
+
+ } else {
+#if CE || WIN
+ ioctlsocket(sp->sock, FIONBIO, &flag);
+#elif ECOS
+ int on;
+ on = 1;
+ ioctl(sp->sock, FIONBIO, &on);
+#elif VXWORKS
+ ioctl(sp->sock, FIONBIO, (int)&iflag);
+#else
+ fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) | O_NONBLOCK);
+#endif
+ }
+ return oldBlock;
+}
+
+/******************************************************************************/
+/*
+ * Return true if a readable socket has buffered data. - not public
+ */
+
+int socketDontBlock()
+{
+ socket_t *sp;
+ int i;
+
+ for (i = 0; i < socketMax; i++) {
+ if ((sp = socketList[i]) == NULL ||
+ (sp->handlerMask & SOCKET_READABLE) == 0) {
+ continue;
+ }
+ if (socketInputBuffered(i) > 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Return true if a particular socket buffered data. - not public
+ */
+
+int socketSockBuffered(int sock)
+{
+ socket_t *sp;
+ int i;
+
+ for (i = 0; i < socketMax; i++) {
+ if ((sp = socketList[i]) == NULL || sp->sock != sock) {
+ continue;
+ }
+ return socketInputBuffered(i);
+ }
+ return 0;
+}
+
+#endif /* (!WIN) | LITTLEFOOT | WEBS */
+
+/******************************************************************************/
diff --git a/cpukit/httpd/sym.c b/cpukit/httpd/sym.c
new file mode 100644
index 0000000000..3df45e86d7
--- /dev/null
+++ b/cpukit/httpd/sym.c
@@ -0,0 +1,474 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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 ***********************************/
+
+#ifdef 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;
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/uemf.c b/cpukit/httpd/uemf.c
new file mode 100644
index 0000000000..ffe6a04cd1
--- /dev/null
+++ b/cpukit/httpd/uemf.c
@@ -0,0 +1,293 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/********************************** 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);
+/*#ifdef 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);
+ }
+ /*
+ * bugfix -- if etype is not E_LOG, E_ASSERT, or E_USER, the call to
+ * bfreeSafe(B_L, buf) below will fail, because 'buf' is randomly
+ * initialized. To be nice, we format a message saying that this is an
+ * unknown message type, and in doing so give buf a valid value. Thanks
+ * to Simon Byholm.
+ */
+ else {
+ fmtAlloc(&buf, E_MAX_ERROR, T("Unknown error"));
+ }
+ 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()
+{
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/uemf.h b/cpukit/httpd/uemf.h
new file mode 100644
index 0000000000..2e5b76dafb
--- /dev/null
+++ b/cpukit/httpd/uemf.h
@@ -0,0 +1,1110 @@
+/*
+ * uemf.h -- GoAhead Micro Embedded Management Framework Header
+ *
+ * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
+ *
+ * See the file "license.txt" for usage and redistribution license requirements
+ *
+ * $Id$
+ */
+
+#ifndef _h_UEMF
+#define _h_UEMF 1
+
+/******************************** Description *********************************/
+
+/*
+ * GoAhead Web Server header. This defines the Web public APIs
+ */
+
+/******************************* Per O/S Includes *****************************/
+
+#ifdef WIN
+ #include <direct.h>
+ #include <io.h>
+ #include <sys/stat.h>
+ #include <limits.h>
+ #include <tchar.h>
+ #include <windows.h>
+ #include <winnls.h>
+ #include <time.h>
+ #include <sys/types.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* WIN */
+
+#ifdef CE
+ #include <errno.h>
+ #include <limits.h>
+ #include <tchar.h>
+ #include <windows.h>
+ #include <winsock.h>
+ #include <winnls.h>
+ #include "CE/wincompat.h"
+ #include <winsock.h>
+#endif /* CE */
+
+#ifdef NW
+ #include <direct.h>
+ #include <io.h>
+ #include <sys/stat.h>
+ #include <time.h>
+ #include <sys/types.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <niterror.h>
+ #define EINTR EINUSE
+ #define WEBS 1
+ #include <limits.h>
+ #include <netdb.h>
+ #include <process.h>
+ #include <tiuser.h>
+ #include <sys/time.h>
+ #include <arpa/inet.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/filio.h>
+ #include <netinet/in.h>
+#endif /* NW */
+
+#ifdef SCOV5
+ #include <sys/types.h>
+ #include <stdio.h>
+ #include "sys/socket.h"
+ #include "sys/select.h"
+ #include "netinet/in.h"
+ #include "arpa/inet.h"
+ #include "netdb.h"
+#endif /* SCOV5 */
+
+#ifdef UNIX
+ #include <stdio.h>
+#endif /* UNIX */
+
+#if LINUX || __rtems__
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/param.h>
+ #include <limits.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <sys/socket.h>
+ #include <sys/select.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <time.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* LINUX */
+
+#ifdef LYNX
+ #include <limits.h>
+ #include <stdarg.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <time.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* LYNX */
+
+#ifdef MACOSX
+ #include <sys/stat.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* MACOSX */
+
+#ifdef UW
+ #include <stdio.h>
+#endif /* UW */
+
+#ifdef VXWORKS
+ #include <vxWorks.h>
+ #include <sockLib.h>
+ #include <selectLib.h>
+ #include <inetLib.h>
+ #include <ioLib.h>
+ #include <stdio.h>
+ #include <stat.h>
+ #include <time.h>
+ #include <usrLib.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* VXWORKS */
+
+#ifdef SOLARIS
+ #include <sys/types.h>
+ #include <limits.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <socket.h>
+ #include <sys/select.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <time.h>
+ #include <fcntl.h>
+ #include <errno.h>
+#endif /* SOLARIS */
+
+#ifdef QNX4
+ #include <sys/types.h>
+ #include <stdio.h>
+ #include <sys/socket.h>
+ #include <sys/select.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <sys/uio.h>
+ #include <sys/wait.h>
+#endif /* QNX4 */
+
+#ifdef ECOS
+ #include <limits.h>
+ #include <cyg/infra/cyg_type.h>
+ #include <cyg/kernel/kapi.h>
+ #include <time.h>
+ #include <network.h>
+ #include <errno.h>
+#endif /* ECOS */
+
+/********************************** Includes **********************************/
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <string.h>
+
+#ifndef WEBS
+#include "messages.h"
+#endif /* ! WEBS */
+
+/******************************* Per O/S Defines *****************************/
+
+#if defined(__rtems__)
+#define __NO_PACK 1
+#endif
+
+#ifdef UW
+ #define __NO_PACK 1
+#endif /* UW */
+
+#if (defined (SCOV5) || defined (VXWORKS) || defined (LINUX) || defined (LYNX) || defined (MACOSX) || defined (__rtems__))
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif /* O_BINARY */
+#define SOCKET_ERROR -1
+#endif /* SCOV5 || VXWORKS || LINUX || LYNX || MACOSX */
+
+#if (defined (WIN) || defined (CE))
+/*
+ * __NO_FCNTL means can't access fcntl function. Fcntl.h is still available.
+ */
+#define __NO_FCNTL 1
+
+#undef R_OK
+#define R_OK 4
+#undef W_OK
+#define W_OK 2
+#undef X_OK
+#define X_OK 1
+#undef F_OK
+#define F_OK 0
+#endif /* WIN || CE */
+
+#if (defined (LINUX) && !defined(__rtems__) && !defined (_STRUCT_TIMEVAL))
+struct timeval
+{
+ time_t tv_sec; /* Seconds. */
+ time_t tv_usec; /* Microseconds. */
+};
+#define _STRUCT_TIMEVAL 1
+#endif /* LINUX && ! _STRUCT_TIMEVAL */
+
+#ifdef ECOS
+ #define O_RDONLY 1
+ #define O_BINARY 2
+
+ #define __NO_PACK 1
+ #define __NO_EJ_FILE 1
+ #define __NO_CGI_BIN 1
+ #define __NO_FCNTL 1
+
+/*
+ * #define LIBKERN_INLINE to avoid kernel inline functions
+ */
+ #define LIBKERN_INLINE
+
+#endif /* ECOS */
+
+#ifdef QNX4
+ typedef long fd_mask;
+ #define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
+#endif /* QNX4 */
+
+#ifdef NW
+ #define fd_mask fd_set
+ #define INADDR_NONE -1l
+ #define Sleep delay
+
+ #define __NO_FCNTL 1
+
+ #undef R_OK
+ #define R_OK 4
+ #undef W_OK
+ #define W_OK 2
+ #undef X_OK
+ #define X_OK 1
+ #undef F_OK
+ #define F_OK 0
+#endif /* NW */
+
+/********************************** Unicode ***********************************/
+/*
+ * Constants and limits. Also FNAMESIZE and PATHSIZE are currently defined
+ * in param.h to be 128 and 512
+ */
+#define TRACE_MAX (4096 - 48)
+#define VALUE_MAX_STRING (4096 - 48)
+#define SYM_MAX (512)
+#define XML_MAX 4096 /* Maximum size for tags/tokens */
+#define BUF_MAX 4096 /* General sanity check for bufs */
+#define FMT_STATIC_MAX 256 /* Maximum for fmtStatic calls */
+
+#if (defined (LITTLEFOOT) || defined (WEBS))
+#define LF_BUF_MAX (510)
+#define LF_PATHSIZE LF_BUF_MAX
+#else
+#define LF_BUF_MAX BUF_MAX
+#define LF_PATHSIZE PATHSIZE
+#define UPPATHSIZE PATHSIZE
+#endif /* LITTLEFOOT || WEBS */
+
+#ifndef CHAR_T_DEFINED
+#define CHAR_T_DEFINED 1
+#ifdef UNICODE
+/*
+ * To convert strings to UNICODE. We have a level of indirection so things
+ * like T(__FILE__) will expand properly.
+ */
+#define T(x) __TXT(x)
+#define __TXT(s) L ## s
+typedef unsigned short char_t;
+typedef unsigned short uchar_t;
+
+/*
+ * Text size of buffer macro. A buffer bytes will hold (size / char size)
+ * characters.
+ */
+#define TSZ(x) (sizeof(x) / sizeof(char_t))
+
+/*
+ * How many ASCII bytes are required to represent this UNICODE string?
+ */
+#define TASTRL(x) ((wcslen(x) + 1) * sizeof(char_t))
+
+#else
+#define T(s) s
+typedef char char_t;
+#define TSZ(x) (sizeof(x))
+#define TASTRL(x) (strlen(x) + 1)
+#ifdef WIN
+typedef unsigned char uchar_t;
+#endif /* WIN */
+
+#endif /* UNICODE */
+
+#endif /* ! CHAR_T_DEFINED */
+
+/*
+ * "Boolean" constants
+ */
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/*
+ * GoAhead Copyright.
+ */
+#define GOAHEAD_COPYRIGHT \
+ T("Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.")
+
+/*
+ * The following include has to be after the unicode defines. By putting it
+ * here, many modules in various parts of the tree are cleaner.
+ */
+#if (defined (LITTLEFOOT) && defined (INMEM))
+ #include "lf/inmem.h"
+#endif /* LITTLEFOOT && INMEM */
+
+/*
+ * Type for unicode systems
+ */
+#ifdef UNICODE
+
+#define gmain wmain
+
+#define gasctime _wasctime
+#define gsprintf swprintf
+#define gprintf wprintf
+#define gfprintf fwprintf
+#define gsscanf swscanf
+#define gvsprintf vswprintf
+
+#define gstrcpy wcscpy
+#define gstrncpy wcsncpy
+#define gstrncat wcsncat
+#define gstrlen wcslen
+#define gstrcat wcscat
+#define gstrcmp wcscmp
+#define gstrncmp wcsncmp
+#define gstricmp wcsicmp
+#define gstrchr wcschr
+#define gstrrchr wcsrchr
+#define gstrtok wcstok
+#define gstrnset wcsnset
+#define gstrrchr wcsrchr
+#define gstrstr wcsstr
+#define gstrtol wcstol
+
+#define gfopen _wfopen
+#define gopen _wopen
+#define gclose close
+#define gcreat _wcreat
+#define gfgets fgetws
+#define gfputs fputws
+#define gfscanf fwscanf
+#define ggets _getws
+#define glseek lseek
+#define gunlink _wunlink
+#define gread read
+#define grename _wrename
+#define gwrite write
+#define gtmpnam _wtmpnam
+#define gtempnam _wtempnam
+#define gfindfirst _wfindfirst
+#define gfinddata_t _wfinddata_t
+#define gfindnext _wfindnext
+#define gfindclose _findclose
+#define gstat _wstat
+#define gaccess _waccess
+#define gchmod _wchmod
+
+typedef struct _stat gstat_t;
+
+#define gmkdir _wmkdir
+#define gchdir _wchdir
+#define grmdir _wrmdir
+#define ggetcwd _wgetcwd
+
+#define gtolower towlower
+#define gtoupper towupper
+#ifdef CE
+#define gisspace isspace
+#define gisdigit isdigit
+#define gisxdigit isxdigit
+#define gisupper isupper
+#define gislower islower
+#define gisprint isprint
+#else
+#define gremove _wremove
+#define gisspace iswspace
+#define gisdigit iswdigit
+#define gisxdigit iswxdigit
+#define gisupper iswupper
+#define gislower iswlower
+#endif /* if CE */
+#define gisalnum iswalnum
+#define gisalpha iswalpha
+#define gatoi(s) wcstol(s, NULL, 10)
+
+#define gctime _wctime
+#define ggetenv _wgetenv
+#define gexecvp _wexecvp
+
+#else /* ! UNICODE */
+
+#ifndef gopen
+#if INMEM
+#define gchdir imChdir
+#define gmkdir imMkdir
+#define grmdir imRmdir
+#define gclose imClose
+#define gclosedir imClosedir
+#define gchmod imChmod
+#define ggetcwd imGetcwd
+#define glseek imLseek
+#define gloadModule imLoadModule
+#define gopen imOpen
+#define gopendir imOpendir
+#define gread imRead
+#define greaddir imReaddir
+#define grename imRename
+#define gstat imStat
+#define gunlink imUnlink
+#define gwrite imWrite
+#else
+#if VXWORKS
+#define gchdir vxchdir
+#define gmkdir vxmkdir
+#define grmdir vxrmdir
+#elif (defined (LYNX) || defined (LINUX) || defined (MACOSX) || defined (SOLARIS))
+#define gchdir chdir
+#define gmkdir(s) mkdir(s,0755)
+#define grmdir rmdir
+#else
+#define gchdir chdir
+#define gmkdir mkdir
+#define grmdir rmdir
+#endif /* VXWORKS #elif LYNX || LINUX || MACOSX || SOLARIS*/
+#define gclose close
+#define gclosedir closedir
+#define gchmod chmod
+#define ggetcwd getcwd
+#define glseek lseek
+#define gloadModule loadModule
+#define gopen open
+#define gopendir opendir
+#define gread read
+#define greaddir readdir
+#define grename rename
+#define gstat stat
+#define gunlink unlink
+#define gwrite write
+#endif /* INMEM */
+#endif /* ! gopen */
+
+#define gasctime asctime
+#define gsprintf sprintf
+#define gprintf printf
+#define gfprintf fprintf
+#define gsscanf sscanf
+#define gvsprintf vsprintf
+
+#define gstrcpy strcpy
+#define gstrncpy strncpy
+#define gstrncat strncat
+#define gstrlen strlen
+#define gstrcat strcat
+#define gstrcmp strcmp
+#define gstrncmp strncmp
+#define gstricmp strcmpci
+#define gstrchr strchr
+#define gstrrchr strrchr
+#define gstrtok strtok
+#define gstrnset strnset
+#define gstrrchr strrchr
+#define gstrstr strstr
+#define gstrtol strtol
+
+#define gfopen fopen
+#define gcreat creat
+#define gfgets fgets
+#define gfputs fputs
+#define gfscanf fscanf
+#define ggets gets
+#define gtmpnam tmpnam
+#define gtempnam tempnam
+#define gfindfirst _findfirst
+#define gfinddata_t _finddata_t
+#define gfindnext _findnext
+#define gfindclose _findclose
+#define gaccess access
+
+typedef struct stat gstat_t;
+
+#define gremove remove
+
+#define gtolower tolower
+#define gtoupper toupper
+#define gisspace isspace
+#define gisdigit isdigit
+#define gisxdigit isxdigit
+#define gisalnum isalnum
+#define gisalpha isalpha
+#define gisupper isupper
+#define gislower islower
+#define gatoi atoi
+
+#define gctime ctime
+#define ggetenv getenv
+#define gexecvp execvp
+#ifndef VXWORKS
+#define gmain main
+#endif /* ! VXWORKS */
+#ifdef VXWORKS
+#define fcntl(a, b, c)
+#endif /* VXWORKS */
+#endif /* ! UNICODE */
+
+/*
+ * Include inmem.h here because it redefines many of the file access fucntions.
+ * Otherwise there would be lots more #if-#elif-#else-#endif ugliness.
+ */
+#ifdef INMEM
+ #include "lf/inmem.h"
+#endif
+
+/********************************** Defines ***********************************/
+
+#ifndef FNAMESIZE
+#define FNAMESIZE 254 /* Max length of file names */
+#endif /* FNAMESIZE */
+
+#define E_MAX_ERROR 4096
+#define URL_MAX 4096
+
+/*
+ * Error types
+ */
+#define E_ASSERT 0x1 /* Assertion error */
+#define E_LOG 0x2 /* Log error to log file */
+#define E_USER 0x3 /* Error that must be displayed */
+
+#define E_L T(__FILE__), __LINE__
+#define E_ARGS_DEC char_t *file, int line
+#define E_ARGS file, line
+
+#if (defined (ASSERT) || defined (ASSERT_CE))
+ #define a_assert(C) if (C) ; else error(E_L, E_ASSERT, T("%s"), T(#C))
+#else
+ #define a_assert(C) if (1) ; else
+#endif /* ASSERT || ASSERT_CE */
+
+/******************************************************************************/
+/* VALUE */
+/******************************************************************************/
+/*
+ * These values are not prefixed so as to aid code readability
+ */
+
+typedef enum {
+ undefined = 0,
+ byteint = 1,
+ shortint = 2,
+ integer = 3,
+ hex = 4,
+ percent = 5,
+ octal = 6,
+ big = 7,
+ flag = 8,
+ floating = 9,
+ string = 10,
+ bytes = 11,
+ symbol = 12,
+ errmsg = 13
+} vtype_t;
+
+#ifndef __NO_PACK
+#pragma pack(2)
+#endif /* _NO_PACK */
+
+typedef struct {
+
+ union {
+ char flag;
+ char byteint;
+ short shortint;
+ char percent;
+ long integer;
+ long hex;
+ long octal;
+ long big[2];
+#ifdef FLOATING_POINT_SUPPORT
+ double floating;
+#endif /* FLOATING_POINT_SUPPORT */
+ char_t *string;
+ char *bytes;
+ char_t *errmsg;
+ void *symbol;
+ } value;
+
+ vtype_t type;
+ unsigned int valid : 8;
+ unsigned int allocated : 8; /* String was balloced */
+} value_t;
+
+#ifndef __NO_PACK
+#pragma pack()
+#endif /* __NO_PACK */
+
+/*
+ * Allocation flags
+ */
+#define VALUE_ALLOCATE 0x1
+
+#define value_numeric(t) (t >= byteint && t <= big)
+#define value_str(t) (t >= string && t <= bytes)
+#define value_ok(t) (t > undefined && t <= symbol)
+
+#define VALUE_VALID { {0}, integer, 1 }
+#define VALUE_INVALID { {0}, undefined, 0 }
+
+/******************************************************************************/
+/*
+ * A ring queue allows maximum utilization of memory for data storage and is
+ * ideal for input/output buffering. This module provides a highly effecient
+ * 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 fillers responsibility to ensure
+ * the ringq is never filled such that servp == endp.
+ *
+ * It is the fillers 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.
+ */
+
+/*
+ * Ring queue buffer structure
+ */
+typedef struct {
+ unsigned char *buf; /* Holding buffer for data */
+ unsigned char *servp; /* Pointer to start of data */
+ unsigned char *endp; /* Pointer to end of data */
+ unsigned char *endbuf; /* Pointer to end of buffer */
+ int buflen; /* Length of ring queue */
+ int maxsize; /* Maximum size */
+ int increment; /* Growth increment */
+} ringq_t;
+
+/*
+ * Block allocation (balloc) definitions
+ */
+#ifdef B_STATS
+#ifndef B_L
+#define B_L T(__FILE__), __LINE__
+#define B_ARGS_DEC char_t *file, int line
+#define B_ARGS file, line
+#endif /* B_L */
+#endif /* B_STATS */
+
+/*
+ * Block classes are: 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192,
+ * 16384, 32768, 65536
+ */
+typedef struct {
+ union {
+ void *next; /* Pointer to next in q */
+ int size; /* Actual requested size */
+ } u;
+ int flags; /* Per block allocation flags */
+} bType;
+
+#define B_SHIFT 4 /* Convert size to class */
+#define B_ROUND ((1 << (B_SHIFT)) - 1)
+#define B_MAX_CLASS 13 /* Maximum class number + 1 */
+#define B_MALLOCED 0x80000000 /* Block was malloced */
+#define B_DEFAULT_MEM (64 * 1024) /* Default memory allocation */
+#define B_MAX_FILES (512) /* Maximum number of files */
+#define B_FILL_CHAR (0x77) /* Fill byte for buffers */
+#define B_FILL_WORD (0x77777777) /* Fill word for buffers */
+#define B_MAX_BLOCKS (64 * 1024) /* Maximum allocated blocks */
+
+/*
+ * Flags. The integrity value is used as an arbitrary value to fill the flags.
+ */
+#define B_INTEGRITY 0x8124000 /* Integrity value */
+#define B_INTEGRITY_MASK 0xFFFF000 /* Integrity mask */
+#define B_USE_MALLOC 0x1 /* Okay to use malloc if required */
+#define B_USER_BUF 0x2 /* User supplied buffer for mem */
+
+/*
+ * The symbol table record for each symbol entry
+ */
+
+typedef struct sym_t {
+ struct sym_t *forw; /* Pointer to next hash list */
+ value_t name; /* Name of symbol */
+ value_t content; /* Value of symbol */
+ int arg; /* Parameter value */
+} sym_t;
+
+typedef int sym_fd_t; /* Returned by symOpen */
+
+/*
+ * Script engines
+ */
+#define EMF_SCRIPT_JSCRIPT 0 /* javascript */
+#define EMF_SCRIPT_TCL 1 /* tcl */
+#define EMF_SCRIPT_EJSCRIPT 2 /* Ejscript */
+#define EMF_SCRIPT_MAX 3
+
+#define MAXINT INT_MAX
+#define BITSPERBYTE CHAR_BIT
+#define BITS(type) (BITSPERBYTE * (int) sizeof(type))
+#define STRSPACE T("\t \n\r\t")
+
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif /* max */
+
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif /* min */
+
+/******************************************************************************/
+/* CRON */
+/******************************************************************************/
+
+typedef struct {
+ char_t *minute;
+ char_t *hour;
+ char_t *day;
+ char_t *month;
+ char_t *dayofweek;
+} cron_t;
+
+extern long cronUntil(cron_t *cp, int period, time_t testTime);
+extern int cronAlloc(cron_t *cp, char_t *str);
+extern int cronFree(cron_t *cp);
+
+/******************************************************************************/
+/* SOCKET */
+/******************************************************************************/
+/*
+ * Socket flags
+ */
+
+#if ((defined (WIN) || defined (CE)) && defined (WEBS))
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#define ENETDOWN WSAENETDOWN
+#define ECONNRESET WSAECONNRESET
+#endif /* (WIN || CE) && WEBS) */
+
+#define SOCKET_EOF 0x1 /* Seen end of file */
+#define SOCKET_CONNECTING 0x2 /* Connect in progress */
+#define SOCKET_BROADCAST 0x4 /* Broadcast mode */
+#define SOCKET_PENDING 0x8 /* Message pending on this socket */
+#define SOCKET_FLUSHING 0x10 /* Background flushing */
+#define SOCKET_DATAGRAM 0x20 /* Use datagrams */
+#define SOCKET_ASYNC 0x40 /* Use async connect */
+#define SOCKET_BLOCK 0x80 /* Use blocking I/O */
+#define SOCKET_LISTENING 0x100 /* Socket is server listener */
+#define SOCKET_CLOSING 0x200 /* Socket is closing */
+#define SOCKET_CONNRESET 0x400 /* Socket connection was reset */
+
+#define SOCKET_PORT_MAX 0xffff /* Max Port size */
+
+/*
+ * Socket error values
+ */
+#define SOCKET_WOULDBLOCK 1 /* Socket would block on I/O */
+#define SOCKET_RESET 2 /* Socket has been reset */
+#define SOCKET_NETDOWN 3 /* Network is down */
+#define SOCKET_AGAIN 4 /* Issue the request again */
+#define SOCKET_INTR 5 /* Call was interrupted */
+#define SOCKET_INVAL 6 /* Invalid */
+
+/*
+ * Handler event masks
+ */
+#define SOCKET_READABLE 0x2 /* Make socket readable */
+#define SOCKET_WRITABLE 0x4 /* Make socket writable */
+#define SOCKET_EXCEPTION 0x8 /* Interested in exceptions */
+#define EMF_SOCKET_MESSAGE (WM_USER+13)
+
+#ifdef LITTLEFOOT
+#define SOCKET_BUFSIZ 510 /* Underlying buffer size */
+#else
+#define SOCKET_BUFSIZ 1024 /* Underlying buffer size */
+#endif /* LITTLEFOOT */
+
+typedef void (*socketHandler_t)(int sid, int mask, int data);
+typedef int (*socketAccept_t)(int sid, char *ipaddr, int port,
+ int listenSid);
+typedef struct {
+ char host[64]; /* Host name */
+ ringq_t inBuf; /* Input ring queue */
+ ringq_t outBuf; /* Output ring queue */
+ ringq_t lineBuf; /* Line ring queue */
+ socketAccept_t accept; /* Accept handler */
+ socketHandler_t handler; /* User I/O handler */
+ int handler_data; /* User handler data */
+ int handlerMask; /* Handler events of interest */
+ int sid; /* Index into socket[] */
+ int port; /* Port to listen on */
+ int flags; /* Current state flags */
+ int sock; /* Actual socket handle */
+ int fileHandle; /* ID of the file handler */
+ int interestEvents; /* Mask of events to watch for */
+ int currentEvents; /* Mask of ready events (FD_xx) */
+ int selectEvents; /* Events being selected */
+ int saveMask; /* saved Mask for socketFlush */
+ int error; /* Last error */
+} socket_t;
+
+/********************************* Prototypes *********************************/
+/*
+ * Balloc module
+ *
+ */
+
+extern void bclose();
+extern int bopen(void *buf, int bufsize, int flags);
+
+/*
+ * Define NO_BALLOC to turn off our balloc module altogether
+ * #define NO_BALLOC 1
+ */
+
+#ifdef NO_BALLOC
+#define balloc(B_ARGS, num) malloc(num)
+#define bfree(B_ARGS, p) free(p)
+#define bfreeSafe(B_ARGS, p) \
+ if (p) { free(p); } else
+#define brealloc(B_ARGS, p, num) realloc(p, num)
+extern char_t *bstrdupNoBalloc(char_t *s);
+extern char *bstrdupANoBalloc(char *s);
+#define bstrdup(B_ARGS, s) bstrdupNoBalloc(s)
+#define bstrdupA(B_ARGS, s) bstrdupANoBalloc(s)
+#define gstrdup(B_ARGS, s) bstrdupNoBalloc(s)
+
+#else /* BALLOC */
+
+#ifndef B_STATS
+#define balloc(B_ARGS, num) balloc(num)
+#define bfree(B_ARGS, p) bfree(p)
+#define bfreeSafe(B_ARGS, p) bfreeSafe(p)
+#define brealloc(B_ARGS, p, size) brealloc(p, size)
+#define bstrdup(B_ARGS, p) bstrdup(p)
+
+#ifdef UNICODE
+#define bstrdupA(B_ARGS, p) bstrdupA(p)
+#else /* UNICODE */
+#define bstrdupA bstrdup
+#endif /* UNICODE */
+
+#endif /* B_STATS */
+
+#define gstrdup bstrdup
+extern void *balloc(B_ARGS_DEC, int size);
+extern void bfree(B_ARGS_DEC, void *mp);
+extern void bfreeSafe(B_ARGS_DEC, void *mp);
+extern void *brealloc(B_ARGS_DEC, void *buf, int newsize);
+extern char_t *bstrdup(B_ARGS_DEC, char_t *s);
+
+#ifdef UNICODE
+extern char *bstrdupA(B_ARGS_DEC, char *s);
+#else /* UNICODE */
+#define bstrdupA bstrdup
+#endif /* UNICODE */
+#endif /* BALLOC */
+
+extern void bstats(int handle, void (*writefn)(int handle, char_t *fmt, ...));
+
+/*
+ * Flags. The integrity value is used as an arbitrary value to fill the flags.
+ */
+#define B_USE_MALLOC 0x1 /* Okay to use malloc if required */
+#define B_USER_BUF 0x2 /* User supplied buffer for mem */
+
+
+#if !LINUX && !__rtems__
+extern char_t *basename(char_t *name);
+#endif /* !LINUX */
+
+#if (defined (UEMF) && defined (WEBS))
+/*
+ * The open source webserver uses a different callback/timer mechanism
+ * than other emf derivative products such as FieldUpgrader agents
+ * so redefine those API for webserver so that they can coexist in the
+ * same address space as the others.
+ */
+#define emfSchedCallback websSchedCallBack
+#define emfUnschedCallback websUnschedCallBack
+#define emfReschedCallback websReschedCallBack
+#endif /* UEMF && WEBS */
+
+typedef void (emfSchedProc)(void *data, int id);
+extern int emfSchedCallback(int delay, emfSchedProc *proc, void *arg);
+extern void emfUnschedCallback(int id);
+extern void emfReschedCallback(int id, int delay);
+extern void emfSchedProcess();
+extern int emfInstGet();
+extern void emfInstSet(int inst);
+extern void error(E_ARGS_DEC, int flags, char_t *fmt, ...);
+extern void (*errorSetHandler(void (*function)(int etype, char_t *msg))) \
+ (int etype, char_t *msg);
+
+#ifdef B_STATS
+#define hAlloc(x) HALLOC(B_L, x)
+#define hAllocEntry(x, y, z) HALLOCENTRY(B_L, x, y, z)
+extern int HALLOC(B_ARGS_DEC, void ***map);
+extern int HALLOCENTRY(B_ARGS_DEC, void ***list, int *max, int size);
+#else
+extern int hAlloc(void ***map);
+extern int hAllocEntry(void ***list, int *max, int size);
+#endif /* B_STATS */
+
+extern int hFree(void ***map, int handle);
+
+extern int ringqOpen(ringq_t *rq, int increment, int maxsize);
+extern void ringqClose(ringq_t *rq);
+extern int ringqLen(ringq_t *rq);
+
+extern int ringqPutc(ringq_t *rq, char_t c);
+extern int ringqInsertc(ringq_t *rq, char_t c);
+extern int ringqPutStr(ringq_t *rq, char_t *str);
+extern int ringqGetc(ringq_t *rq);
+
+extern int fmtValloc(char_t **s, int n, char_t *fmt, va_list arg);
+extern int fmtAlloc(char_t **s, int n, char_t *fmt, ...);
+extern int fmtStatic(char_t *s, int n, char_t *fmt, ...);
+
+#ifdef UNICODE
+extern int ringqPutcA(ringq_t *rq, char c);
+extern int ringqInsertcA(ringq_t *rq, char c);
+extern int ringqPutStrA(ringq_t *rq, char *str);
+extern int ringqGetcA(ringq_t *rq);
+#else
+#define ringqPutcA ringqPutc
+#define ringqInsertcA ringqInsertc
+#define ringqPutStrA ringqPutStr
+#define ringqGetcA ringqGetc
+#endif /* UNICODE */
+
+extern int ringqPutBlk(ringq_t *rq, unsigned char *buf, int len);
+extern int ringqPutBlkMax(ringq_t *rq);
+extern void ringqPutBlkAdj(ringq_t *rq, int size);
+extern int ringqGetBlk(ringq_t *rq, unsigned char *buf, int len);
+extern int ringqGetBlkMax(ringq_t *rq);
+extern void ringqGetBlkAdj(ringq_t *rq, int size);
+extern void ringqFlush(ringq_t *rq);
+extern void ringqAddNull(ringq_t *rq);
+
+extern int scriptSetVar(int engine, char_t *var, char_t *value);
+extern int scriptEval(int engine, char_t *cmd, char_t **rslt, int chan);
+
+extern void socketClose();
+extern void socketCloseConnection(int sid);
+extern void socketCreateHandler(int sid, int mask, socketHandler_t
+ handler, int arg);
+extern void socketDeleteHandler(int sid);
+extern int socketEof(int sid);
+extern int socketCanWrite(int sid);
+extern void socketSetBufferSize(int sid, int in, int line, int out);
+extern int socketFlush(int sid);
+extern int socketGets(int sid, char_t **buf);
+extern int socketGetPort(int sid);
+extern int socketInputBuffered(int sid);
+extern int socketOpen();
+extern int socketOpenConnection(char *host, int port,
+ socketAccept_t accept, int flags);
+extern void socketProcess(int hid);
+extern int socketRead(int sid, char *buf, int len);
+extern int socketReady(int hid);
+extern int socketWrite(int sid, char *buf, int len);
+extern int socketWriteString(int sid, char_t *buf);
+extern int socketSelect(int hid, int timeout);
+extern int socketGetHandle(int sid);
+extern int socketSetBlock(int sid, int flags);
+extern int socketGetBlock(int sid);
+extern int socketAlloc(char *host, int port, socketAccept_t accept,
+ int flags);
+extern void socketFree(int sid);
+extern int socketGetError();
+extern socket_t *socketPtr(int sid);
+extern int socketWaitForEvent(socket_t *sp, int events, int *errCode);
+extern void socketRegisterInterest(socket_t *sp, int handlerMask);
+extern int socketGetInput(int sid, char *buf, int toRead, int *errCode);
+
+extern char_t *strlower(char_t *string);
+extern char_t *strupper(char_t *string);
+
+extern char_t *stritoa(int n, char_t *string, int width);
+
+extern sym_fd_t symOpen(int hash_size);
+extern void symClose(sym_fd_t sd);
+extern sym_t *symLookup(sym_fd_t sd, char_t *name);
+extern sym_t *symEnter(sym_fd_t sd, char_t *name, value_t v, int arg);
+extern int symDelete(sym_fd_t sd, char_t *name);
+extern void symWalk(sym_fd_t sd, void (*fn)(sym_t *symp));
+extern sym_t *symFirst(sym_fd_t sd);
+extern sym_t *symNext(sym_fd_t sd);
+extern int symSubOpen();
+extern void symSubClose();
+
+extern void trace(int lev, char_t *fmt, ...);
+extern void traceRaw(char_t *buf);
+extern void (*traceSetHandler(void (*function)(int level, char_t *buf)))
+ (int level, char_t *buf);
+
+extern value_t valueInteger(long value);
+extern value_t valueString(char_t *value, int flags);
+extern value_t valueErrmsg(char_t *value);
+extern void valueFree(value_t *v);
+extern int vxchdir(char *dirname);
+
+extern unsigned int hextoi(char_t *hexstring);
+extern unsigned int gstrtoi(char_t *s);
+extern time_t timeMsec();
+
+extern char_t *ascToUni(char_t *ubuf, char *str, int nBytes);
+extern char *uniToAsc(char *buf, char_t *ustr, int nBytes);
+extern char_t *ballocAscToUni(char *cp, int alen);
+extern char *ballocUniToAsc(char_t *unip, int ulen);
+
+extern char_t *basicGetHost();
+extern char_t *basicGetAddress();
+extern char_t *basicGetProduct();
+extern void basicSetHost(char_t *host);
+extern void basicSetAddress(char_t *addr);
+
+extern int harnessOpen(char_t **argv);
+extern void harnessClose(int status);
+extern void harnessTesting(char_t *msg, ...);
+extern void harnessPassed();
+extern void harnessFailed(int line);
+extern int harnessLevel();
+
+#endif /* _h_UEMF */
+
+/******************************************************************************/
diff --git a/cpukit/httpd/um.c b/cpukit/httpd/um.c
new file mode 100644
index 0000000000..e960f02719
--- /dev/null
+++ b/cpukit/httpd/um.c
@@ -0,0 +1,1435 @@
+/*
+ * um.c -- User Management
+ *
+ * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
+ *
+ * See the file "license.txt" for usage and redistribution license requirements
+ *
+ * $Id$
+ */
+
+/******************************** Description *********************************/
+/*
+ * User Management routines for adding/deleting/changing users and groups
+ * Also, routines for determining user access
+ */
+
+/********************************* Includes ***********************************/
+
+#include "um.h"
+#include "emfdb.h"
+#include "webs.h"
+
+/********************************** Defines ***********************************/
+
+#define UM_DB_FILENAME T("um.xml")
+#define UM_TXT_FILENAME T("umconfig.txt")
+
+/*
+ * Table names
+ */
+#define UM_USER_TABLENAME T("users")
+#define UM_GROUP_TABLENAME T("groups")
+#define UM_ACCESS_TABLENAME T("access")
+
+/*
+ * Column names
+ */
+#define UM_NAME T("name")
+#define UM_PASS T("password")
+#define UM_GROUP T("group")
+#define UM_PROT T("prot")
+#define UM_DISABLE T("disable")
+#define UM_METHOD T("method")
+#define UM_PRIVILEGE T("priv")
+#define UM_SECURE T("secure")
+
+/*
+ * XOR encryption mask
+ * Note: This string should be modified for individual sites
+ * in order to enhance user password security.
+ */
+#define UM_XOR_ENCRYPT T("*j7a(L#yZ98sSd5HfSgGjMj8;Ss;d)(*&^#@$a2s0i3g")
+
+/******************************** Local Data **********************************/
+
+#ifdef qHierarchicalAccess
+/*
+ * user-provided function to allow hierarchical access protection. See below.
+ * for details.
+ */
+extern bool_t dmfCanAccess(const char_t* usergroup, const char_t* group);
+#endif
+#ifdef UEMF
+/*
+ * User table definition
+ */
+#define NUMBER_OF_USER_COLUMNS 5
+
+char_t *userColumnNames[NUMBER_OF_USER_COLUMNS] = {
+ UM_NAME, UM_PASS, UM_GROUP, UM_PROT, UM_DISABLE
+};
+
+int userColumnTypes[NUMBER_OF_USER_COLUMNS] = {
+ T_STRING, T_STRING, T_STRING, T_INT, T_INT
+};
+
+dbTable_t userTable = {
+ UM_USER_TABLENAME,
+ NUMBER_OF_USER_COLUMNS,
+ userColumnNames,
+ userColumnTypes,
+ 0,
+ NULL
+};
+
+/*
+ * Group table definition
+ */
+#define NUMBER_OF_GROUP_COLUMNS 5
+
+char_t *groupColumnNames[NUMBER_OF_GROUP_COLUMNS] = {
+ UM_NAME, UM_PRIVILEGE, UM_METHOD, UM_PROT, UM_DISABLE
+};
+
+int groupColumnTypes[NUMBER_OF_GROUP_COLUMNS] = {
+ T_STRING, T_INT, T_INT, T_INT, T_INT
+};
+
+dbTable_t groupTable = {
+ UM_GROUP_TABLENAME,
+ NUMBER_OF_GROUP_COLUMNS,
+ groupColumnNames,
+ groupColumnTypes,
+ 0,
+ NULL
+};
+
+/*
+ * Access Limit table definition
+ */
+#define NUMBER_OF_ACCESS_COLUMNS 4
+
+char_t *accessColumnNames[NUMBER_OF_ACCESS_COLUMNS] = {
+ UM_NAME, UM_METHOD, UM_SECURE, UM_GROUP
+};
+
+int accessColumnTypes[NUMBER_OF_ACCESS_COLUMNS] = {
+ T_STRING, T_INT, T_INT, T_STRING
+};
+
+dbTable_t accessTable = {
+ UM_ACCESS_TABLENAME,
+ NUMBER_OF_ACCESS_COLUMNS,
+ accessColumnNames,
+ accessColumnTypes,
+ 0,
+ NULL
+};
+#endif /* #ifdef UEMF */
+
+/*
+ * Database Identifier returned from dbOpen()
+ */
+static int didUM = -1;
+
+/*
+ * Configuration database persist filename
+ */
+static char_t *saveFilename = NULL;
+
+static int umOpenCount = 0; /* count of apps using this module */
+
+/*************************** Forward Declarations *****************************/
+
+static bool_t umCheckName(char_t *name);
+
+/*********************************** Code *************************************/
+/*
+ * umOpen() registers the UM tables in the fake emf-database
+ */
+
+int umOpen()
+{
+ if (++umOpenCount != 1) {
+ return didUM;
+ }
+/*
+ * Do not initialize if intialization has already taken place
+ */
+ if (didUM == -1) {
+ didUM = dbOpen(UM_USER_TABLENAME, UM_DB_FILENAME, NULL, 0);
+#ifdef UEMF
+ dbRegisterDBSchema(&userTable);
+ dbRegisterDBSchema(&groupTable);
+ dbRegisterDBSchema(&accessTable);
+#endif
+ }
+
+ if (saveFilename == NULL) {
+ saveFilename = bstrdup(B_L, UM_TXT_FILENAME);
+ }
+
+ return didUM;
+}
+
+/******************************************************************************/
+/*
+ * umClose() frees up the UM tables in the fake emf-database
+ */
+
+void umClose()
+{
+ if (--umOpenCount > 0) {
+ return;
+ }
+/*
+ * Do not close if intialization has not taken place
+ */
+ if (didUM != -1) {
+ dbClose(didUM);
+ didUM = -1;
+ }
+
+ if (saveFilename != NULL) {
+ bfree(B_L, saveFilename);
+ saveFilename = NULL;
+ }
+}
+
+/******************************************************************************/
+/*
+ * umCommit() persists all of the UM tables
+ */
+
+int umCommit(char_t *filename)
+{
+ if (filename && *filename) {
+ if (saveFilename != NULL) {
+ bfree(B_L, saveFilename);
+ }
+
+ saveFilename = bstrdup(B_L, filename);
+ }
+
+ a_assert (saveFilename && *saveFilename);
+ trace(3, T("UM: Writing User Configuration to file <%s>\n"),
+ saveFilename);
+
+ return dbSave(didUM, saveFilename, 0);
+}
+
+/******************************************************************************/
+/*
+ * umRestore() loads up the UM tables with persisted data
+ */
+
+int umRestore(char_t *filename)
+{
+ if (filename && *filename) {
+ if (saveFilename != NULL) {
+ bfree(B_L, saveFilename);
+ }
+
+ saveFilename = bstrdup(B_L, filename);
+ }
+
+ a_assert(saveFilename && *saveFilename);
+
+ trace(3, T("UM: Loading User Configuration from file <%s>\n"),
+ saveFilename);
+
+/*
+ * First empty the database, otherwise we wind up with duplicates!
+ */
+ dbZero(didUM);
+ return dbLoad(didUM, saveFilename, 0);
+}
+
+/******************************************************************************/
+/*
+ * Encrypt/Decrypt a text string.
+ * Returns the number of characters encrypted.
+ */
+
+static int umEncryptString(char_t *textString)
+{
+ char_t *enMask;
+ char_t enChar;
+ int numChars;
+
+ a_assert(textString);
+
+ enMask = UM_XOR_ENCRYPT;
+ numChars = 0;
+
+ while (*textString) {
+ enChar = *textString ^ *enMask;
+/*
+ * Do not produce encrypted text with embedded linefeeds or tabs.
+ * Simply use existing character.
+ */
+ if (enChar && !gisspace(enChar))
+ *textString = enChar;
+/*
+ * Increment all pointers.
+ */
+ enMask++;
+ textString++;
+ numChars++;
+/*
+ * Wrap encryption mask pointer if at end of length.
+ */
+ if (*enMask == '\0') {
+ enMask = UM_XOR_ENCRYPT;
+ }
+ }
+
+ return numChars;
+}
+
+/******************************************************************************/
+/*
+ * umGetFirstRowData() - return a pointer to the first non-blank key value
+ * in the given column for the given table.
+ */
+
+static char_t *umGetFirstRowData(char_t *tableName, char_t *columnName)
+{
+ char_t *columnData;
+ int row;
+ int check;
+
+ a_assert(tableName && *tableName);
+ a_assert(columnName && *columnName);
+
+ row = 0;
+/*
+ * Move through table until we retrieve the first row with non-null
+ * column data.
+ */
+ columnData = NULL;
+ while ((check = dbReadStr(didUM, tableName, columnName, row++,
+ &columnData)) == 0 || (check == DB_ERR_ROW_DELETED)) {
+ if (columnData && *columnData) {
+ return columnData;
+ }
+ }
+
+ return NULL;
+}
+
+/******************************************************************************/
+/*
+ * umGetNextRowData() - return a pointer to the first non-blank
+ * key value following the given one.
+ */
+
+static char_t *umGetNextRowData(char_t *tableName, char_t *columnName,
+ char_t *keyLast)
+{
+ char_t *key;
+ int row;
+ int check;
+
+ a_assert(tableName && *tableName);
+ a_assert(columnName && *columnName);
+ a_assert(keyLast && *keyLast);
+/*
+ * Position row counter to row where the given key value was found
+ */
+ row = 0;
+ key = NULL;
+
+ while ((((check = dbReadStr(didUM, tableName, columnName, row++,
+ &key)) == 0) || (check == DB_ERR_ROW_DELETED)) &&
+ ((key == NULL) || (gstrcmp(key, keyLast) != 0))) {
+ }
+/*
+ * If the last key value was not found, return NULL
+ */
+ if (!key || gstrcmp(key, keyLast) != 0) {
+ return NULL;
+ }
+/*
+ * Move through table until we retrieve the next row with a non-null key
+ */
+ while (((check = dbReadStr(didUM, tableName, columnName, row++, &key))
+ == 0) || (check == DB_ERR_ROW_DELETED)) {
+ if (key && *key && (gstrcmp(key, keyLast) != 0)) {
+ return key;
+ }
+ }
+
+ return NULL;
+}
+
+/******************************************************************************/
+/*
+ * umAddUser() - Adds a user to the "users" table.
+ */
+
+int umAddUser(char_t *user, char_t *pass, char_t *group,
+ bool_t prot, bool_t disabled)
+{
+ int row;
+ char_t *password;
+
+ a_assert(user && *user);
+ a_assert(pass && *pass);
+ a_assert(group && *group);
+
+ trace(3, T("UM: Adding User <%s>\n"), user);
+
+/*
+ * Do not allow duplicates
+ */
+ if (umUserExists(user)) {
+ return UM_ERR_DUPLICATE;
+ }
+
+/*
+ * Make sure user name and password contain valid characters
+ */
+ if (!umCheckName(user)) {
+ return UM_ERR_BAD_NAME;
+ }
+
+ if (!umCheckName(pass)) {
+ return UM_ERR_BAD_PASSWORD;
+ }
+
+/*
+ * Make sure group exists
+ */
+ if (!umGroupExists(group)) {
+ return UM_ERR_NOT_FOUND;
+ }
+
+/*
+ * Now create the user record
+ */
+ row = dbAddRow(didUM, UM_USER_TABLENAME);
+
+ if (row < 0) {
+ return UM_ERR_GENERAL;
+ }
+
+ if (dbWriteStr(didUM, UM_USER_TABLENAME, UM_NAME, row, user) != 0) {
+ return UM_ERR_GENERAL;
+ }
+
+ password = bstrdup(B_L, pass);
+ umEncryptString(password);
+ dbWriteStr(didUM, UM_USER_TABLENAME, UM_PASS, row, password);
+ bfree(B_L, password);
+ dbWriteStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, group);
+ dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, prot);
+ dbWriteInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, disabled);
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * umDeleteUser() - remove a user from the "users" table
+ */
+
+int umDeleteUser(char_t *user)
+{
+ int row;
+
+ a_assert(user && *user);
+ trace(3, T("UM: Deleting User <%s>\n"), user);
+/*
+ * Check to see if user is delete-protected
+ */
+ if (umGetUserProtected(user)) {
+ return UM_ERR_PROTECTED;
+ }
+
+/*
+ * If found, delete the user from the database
+ */
+ if ((row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0)) >= 0) {
+ return dbDeleteRow(didUM, UM_USER_TABLENAME, row);
+ }
+
+ return UM_ERR_NOT_FOUND;
+}
+
+/******************************************************************************/
+/*
+ * umGetFirstUser() - Returns the user ID of the first user found in the
+ * "users" table.
+ */
+
+char_t *umGetFirstUser()
+{
+ return umGetFirstRowData(UM_USER_TABLENAME, UM_NAME);
+}
+
+/******************************************************************************/
+/*
+ * umGetNextUser() Returns the next user found in the "users" table after
+ * the given user.
+ */
+
+char_t *umGetNextUser(char_t *userLast)
+{
+ return umGetNextRowData(UM_USER_TABLENAME, UM_NAME, userLast);
+}
+
+/******************************************************************************/
+/*
+ * umUserExists() Returns TRUE if userid exists.
+ */
+
+bool_t umUserExists(char_t *user)
+{
+ a_assert(user && *user);
+
+ if (dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0) >= 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/******************************************************************************/
+/*
+ * umGetUserPassword() returns a de-crypted copy of the user password
+ */
+
+char_t *umGetUserPassword(char_t *user)
+{
+ char_t *password;
+ int row;
+
+ a_assert(user && *user);
+
+ password = NULL;
+ row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
+
+ if (row >= 0) {
+ char_t *pass = NULL;
+ dbReadStr(didUM, UM_USER_TABLENAME, UM_PASS, row, &pass);
+/*
+ * Decrypt password
+ * Note, this function returns a copy of the password, which must
+ * be deleted at some time in the future.
+ */
+ password = bstrdup(B_L, pass);
+ umEncryptString(password);
+ }
+
+ return password;
+}
+
+/******************************************************************************/
+/*
+ * umSetUserPassword() updates the user password in the user "table" after
+ * encrypting the given password
+ */
+
+int umSetUserPassword(char_t *user, char_t *pass)
+{
+ int row, nRet;
+ char_t *password;
+
+ a_assert(user && *user);
+ a_assert(pass && *pass);
+ trace(3, T("UM: Attempting to change the password for user <%s>\n"), user);
+/*
+ * Find the row of the user
+ */
+ if ((row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0)) < 0) {
+ return UM_ERR_NOT_FOUND;
+ }
+
+ password = bstrdup(B_L, pass);
+ umEncryptString(password);
+ nRet = dbWriteStr(didUM, UM_USER_TABLENAME, UM_PASS, row, password);
+ bfree(B_L, password);
+
+ return nRet;
+}
+
+/******************************************************************************/
+/*
+ * umGetUserGroup() returns the name of the user group
+ */
+
+char_t *umGetUserGroup(char_t *user)
+{
+ char_t *group;
+ int row;
+
+ a_assert(user && *user);
+ group = NULL;
+/*
+ * Find the row of the user
+ */
+ row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
+
+ if (row >= 0) {
+ dbReadStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, &group);
+ }
+
+ return group;
+}
+
+/******************************************************************************/
+/*
+ * umSetUserGroup() Sets the name of the user group for the user
+ */
+
+int umSetUserGroup(char_t *user, char_t *group)
+{
+ int row;
+
+ a_assert(user && *user);
+ a_assert(group && *group);
+/*
+ * Find the row of the user
+ */
+ row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
+
+ if (row >= 0) {
+ return dbWriteStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, group);
+ } else {
+ return UM_ERR_NOT_FOUND;
+ }
+}
+
+/******************************************************************************/
+/*
+ * umGetUserEnabled() - returns if the user is enabled
+ * Returns FALSE if the user is not found.
+ */
+
+bool_t umGetUserEnabled(char_t *user)
+{
+ int disabled, row;
+
+ a_assert(user && *user);
+
+ disabled = 1;
+/*
+ * Find the row of the user
+ */
+ row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
+
+ if (row >= 0) {
+ dbReadInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, &disabled);
+ }
+
+ return (bool_t)!disabled;
+}
+
+/******************************************************************************/
+/*
+ * umSetUserEnabled() Enables/disables the user
+ */
+int umSetUserEnabled(char_t *user, bool_t enabled)
+{
+ int row;
+
+ a_assert(user && *user);
+/*
+ * Find the row of the user
+ */
+ row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
+ if (row >= 0) {
+ return dbWriteInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, !enabled);
+ } else {
+ return UM_ERR_NOT_FOUND;
+ }
+}
+
+/******************************************************************************/
+/*
+ * umGetUserProtected() - determine deletability of user
+ */
+
+bool_t umGetUserProtected(char_t *user)
+{
+ int protect, row;
+
+ a_assert(user && *user);
+/*
+ * Find the row of the user
+ */
+ row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
+ protect = FALSE;
+
+ if (row >= 0) {
+ dbReadInt(didUM, UM_USER_TABLENAME, UM_PROT, row, &protect);
+ }
+
+ return (bool_t)protect;
+}
+
+/******************************************************************************/
+/*
+ * umSetUserProtected() sets the delete protection for the user
+ */
+int umSetUserProtected(char_t *user, bool_t protect)
+{
+ int row;
+
+ a_assert(user && *user);
+/*
+ * Find the row of the user
+ */
+ row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
+
+ if (row >= 0) {
+ return dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, protect);
+ } else {
+ return UM_ERR_NOT_FOUND;
+ }
+}
+
+
+/******************************************************************************/
+/*
+ * umAddGroup() adds a group to the "Group" table
+ */
+
+int umAddGroup(char_t *group, short priv, accessMeth_t am,
+ bool_t prot, bool_t disabled)
+{
+ int row;
+
+ a_assert(group && *group);
+ trace(3, T("UM: Adding group <%s>\n"), group);
+
+/*
+ * Do not allow duplicates
+ */
+ if (umGroupExists(group)) {
+ return UM_ERR_DUPLICATE;
+ }
+
+/*
+ * Only allow valid characters in key field
+ */
+ if (!umCheckName(group)) {
+ return UM_ERR_BAD_NAME;
+ }
+
+/*
+ * Add a new row to the table
+ */
+ if ((row = dbAddRow(didUM, UM_GROUP_TABLENAME)) < 0) {
+ return UM_ERR_GENERAL;
+ }
+
+/*
+ * Write the key field
+ */
+ if (dbWriteStr(didUM, UM_GROUP_TABLENAME, UM_NAME, row, group) != 0) {
+ return UM_ERR_GENERAL;
+ }
+
+/*
+ * Write the remaining fields
+ */
+ dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, priv);
+ dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int) am);
+ dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, prot);
+ dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, disabled);
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * umDeleteGroup() - Delete a user group, if not protected
+ */
+
+int umDeleteGroup(char_t *group)
+{
+ int row;
+
+ a_assert(group && *group);
+ trace(3, T("UM: Deleting Group <%s>\n"), group);
+
+/*
+ * Check to see if the group is in use
+ */
+ if (umGetGroupInUse(group)) {
+ return UM_ERR_IN_USE;
+ }
+
+/*
+ * Check to see if the group is delete-protected
+ */
+ if (umGetGroupProtected(group)) {
+ return UM_ERR_PROTECTED;
+ }
+
+/*
+ * Find the row of the group to delete
+ */
+ if ((row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0)) < 0) {
+ return UM_ERR_NOT_FOUND;
+ }
+
+ return dbDeleteRow(didUM, UM_GROUP_TABLENAME, row);
+}
+
+/******************************************************************************/
+/*
+ * umGroupExists() returns TRUE if group exists, FALSE otherwise
+ */
+
+bool_t umGroupExists(char_t *group)
+{
+ a_assert(group && *group);
+
+ if (dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0) >= 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+/******************************************************************************/
+/*
+ * umGetGroupInUse() returns TRUE if the group is referenced by a user or by
+ * an access limit.
+ */
+
+bool_t umGetGroupInUse(char_t *group)
+{
+ a_assert(group && *group);
+
+/*
+ * First, check the user table
+ */
+ if (dbSearchStr(didUM, UM_USER_TABLENAME, UM_GROUP, group, 0) >= 0) {
+ return TRUE;
+ }
+
+/*
+ * Second, check the access limit table
+ */
+ if (dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, group, 0) >= 0) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/******************************************************************************/
+/*
+ * umGetFirstGroup() - return a pointer to the first non-blank group name
+ */
+
+char_t *umGetFirstGroup()
+{
+ return umGetFirstRowData(UM_GROUP_TABLENAME, UM_NAME);
+}
+
+/******************************************************************************/
+/*
+ * umGetNextGroup() - return a pointer to the first non-blank group name
+ * following the given group name
+ */
+
+char_t *umGetNextGroup(char_t *groupLast)
+{
+ return umGetNextRowData(UM_GROUP_TABLENAME, UM_NAME, groupLast);
+}
+
+/******************************************************************************/
+/*
+ * Returns the default access method to use for a given group
+ */
+
+accessMeth_t umGetGroupAccessMethod(char_t *group)
+{
+ int am, row;
+
+ a_assert(group && *group);
+ row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
+
+ if (row >= 0) {
+ dbReadInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int *)&am);
+ } else {
+ am = AM_INVALID;
+ }
+
+ return (accessMeth_t) am;
+}
+
+/******************************************************************************/
+/*
+ * Set the default access method to use for a given group
+ */
+
+int umSetGroupAccessMethod(char_t *group, accessMeth_t am)
+{
+ int row;
+
+ a_assert(group && *group);
+ row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
+
+ if (row >= 0) {
+ return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int) am);
+ } else {
+ return UM_ERR_NOT_FOUND;
+ }
+}
+
+/******************************************************************************/
+/*
+ * Returns the privilege mask for a given group
+ */
+
+short umGetGroupPrivilege(char_t *group)
+{
+ int privilege, row;
+
+ a_assert(group && *group);
+ privilege = -1;
+ row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
+
+ if (row >= 0) {
+ dbReadInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, &privilege);
+ }
+
+ return (short) privilege;
+}
+
+/******************************************************************************/
+/*
+ * Set the privilege mask for a given group
+ */
+
+int umSetGroupPrivilege(char_t *group, short privilege)
+{
+ int row;
+
+ a_assert(group && *group);
+ row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
+
+ if (row >= 0) {
+ return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row,
+ (int)privilege);
+ } else {
+ return UM_ERR_NOT_FOUND;
+ }
+}
+
+/******************************************************************************/
+/*
+ * Returns the enabled setting for a given group.
+ * Returns FALSE if group is not found.
+ */
+
+bool_t umGetGroupEnabled(char_t *group)
+{
+ int disabled, row;
+
+ a_assert(group && *group);
+ row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
+ disabled = 1;
+
+ if (row >= 0) {
+ dbReadInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, &disabled);
+ }
+
+ return (bool_t) !disabled;
+}
+
+/******************************************************************************/
+/*
+ * Sets the enabled setting for a given group.
+ */
+
+int umSetGroupEnabled(char_t *group, bool_t enabled)
+{
+ int row;
+
+ a_assert(group && *group);
+ row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
+
+ if (row >= 0) {
+ return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row,
+ (int) !enabled);
+ } else {
+ return UM_ERR_NOT_FOUND;
+ }
+}
+
+/******************************************************************************/
+/*
+ * Returns the protected setting for a given group
+ * Returns FALSE if user is not found
+ */
+
+bool_t umGetGroupProtected(char_t *group)
+{
+ int protect, row;
+
+ a_assert(group && *group);
+
+ protect = 0;
+ row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
+ if (row >= 0) {
+ dbReadInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, &protect);
+ }
+
+ return (bool_t) protect;
+}
+
+/******************************************************************************/
+/*
+ * Sets the protected setting for a given group
+ */
+
+int umSetGroupProtected(char_t *group, bool_t protect)
+{
+ int row;
+
+ a_assert(group && *group);
+ row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
+
+ if (row >= 0) {
+ return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row,
+ (int) protect);
+ } else {
+ return UM_ERR_NOT_FOUND;
+ }
+}
+
+
+/******************************************************************************/
+/*
+ * umAddAccessLimit() adds an access limit to the "access" table
+ */
+
+int umAddAccessLimit(char_t *url, accessMeth_t am, short secure, char_t *group)
+{
+ int row;
+
+ a_assert(url && *url);
+ trace(3, T("UM: Adding Access Limit for <%s>\n"), url);
+
+/*
+ * Do not allow duplicates
+ */
+ if (umAccessLimitExists(url)) {
+ return UM_ERR_DUPLICATE;
+ }
+
+/*
+ * Add a new row to the table
+ */
+ if ((row = dbAddRow(didUM, UM_ACCESS_TABLENAME)) < 0) {
+ return UM_ERR_GENERAL;
+ }
+
+/*
+ * Write the key field
+ */
+ if(dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, row, url) < 0) {
+ return UM_ERR_GENERAL;
+ }
+
+/*
+ * Write the remaining fields
+ */
+ dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, (int)am);
+ dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, (int)secure);
+ dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, group);
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * umDeleteAccessLimit()
+ */
+
+int umDeleteAccessLimit(char_t *url)
+{
+ int row;
+
+ a_assert(url && *url);
+ trace(3, T("UM: Deleting Access Limit for <%s>\n"), url);
+/*
+ * Find the row of the access limit to delete
+ */
+ if ((row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0)) < 0) {
+ return UM_ERR_NOT_FOUND;
+ }
+
+ return dbDeleteRow(didUM, UM_ACCESS_TABLENAME, row);
+}
+
+/******************************************************************************/
+/*
+ * umGetFirstGroup() - return a pointer to the first non-blank access limit
+ */
+
+char_t *umGetFirstAccessLimit()
+{
+ return umGetFirstRowData(UM_ACCESS_TABLENAME, UM_NAME);
+}
+
+/******************************************************************************/
+/*
+ * umGetNextAccessLimit() - return a pointer to the first non-blank
+ * access limit following the given one
+ */
+
+char_t *umGetNextAccessLimit(char_t *urlLast)
+{
+ return umGetNextRowData(UM_ACCESS_TABLENAME, UM_NAME, urlLast);
+}
+
+/******************************************************************************/
+/*
+ * umAccessLimitExists() returns TRUE if this access limit exists
+ */
+
+bool_t umAccessLimitExists(char_t *url)
+{
+ a_assert(url && *url);
+
+ if (dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0) < 0) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+/******************************************************************************/
+/*
+ * umGetAccessLimit() returns the Access Method for the URL
+ */
+
+accessMeth_t umGetAccessLimitMethod(char_t *url)
+{
+ int am, row;
+
+ am = (int) AM_INVALID;
+ row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
+
+ if (row >= 0) {
+ dbReadInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, &am);
+ }
+
+ return (accessMeth_t) am;
+}
+
+/******************************************************************************/
+/*
+ * umSetAccessLimitMethod() - set Access Method for Access Limit
+ */
+
+int umSetAccessLimitMethod(char_t *url, accessMeth_t am)
+{
+ int row;
+
+ a_assert(url && *url);
+ row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
+
+ if (row >= 0) {
+ return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, (int) am);
+ } else {
+ return UM_ERR_NOT_FOUND;
+ }
+}
+
+/******************************************************************************/
+/*
+ * umGetAccessLimitSecure() - returns secure switch for access limit
+ */
+
+short umGetAccessLimitSecure(char_t *url)
+{
+ int secure, row;
+
+ a_assert(url && *url);
+ secure = -1;
+ row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
+
+ if (row >= 0) {
+ dbReadInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, &secure);
+ }
+
+ return (short)secure;
+}
+
+/******************************************************************************/
+/*
+ * umSetAccessLimitSecure() - sets the secure flag for the URL
+ */
+
+int umSetAccessLimitSecure(char_t *url, short secure)
+{
+ int row;
+
+ a_assert(url && *url);
+ row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
+
+ if (row >= 0) {
+ return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row,
+ (int)secure);
+ } else {
+ return UM_ERR_NOT_FOUND;
+ }
+}
+
+/******************************************************************************/
+/*
+ * umGetAccessLimitGroup() - returns the user group of the access limit
+ */
+
+char_t *umGetAccessLimitGroup(char_t *url)
+{
+ char_t *group;
+ int row;
+
+ a_assert(url && *url);
+ group = NULL;
+ row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
+
+ if (row >= 0) {
+ dbReadStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, &group);
+ }
+
+ return group;
+}
+
+/******************************************************************************/
+/*
+ * umSetAccessLimitGroup() - sets the user group for the access limit.
+ */
+
+int umSetAccessLimitGroup(char_t *url, char_t *group)
+{
+ int row;
+
+ a_assert(url && *url);
+ row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
+
+ if (row >= 0) {
+ return dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, group);
+ } else {
+ return UM_ERR_NOT_FOUND;
+ }
+}
+
+/******************************************************************************/
+/*
+ * Returns the access limit to use for a given URL, by checking for URLs up
+ * the directory tree. Creates a new string that must be deleted.
+ */
+
+char_t *umGetAccessLimit(char_t *url)
+{
+ char_t *urlRet, *urlCheck, *lastChar;
+ int len;
+
+ a_assert(url && *url);
+ urlRet = NULL;
+ urlCheck = bstrdup(B_L, url);
+ a_assert(urlCheck);
+ len = gstrlen(urlCheck);
+/*
+ * Scan back through URL to see if there is a "parent" access limit
+ */
+ while (len && !urlRet) {
+ if (umAccessLimitExists(urlCheck)) {
+ urlRet = bstrdup(B_L, urlCheck);
+ } else {
+/*
+ * Trim the end portion of the URL to the previous directory marker
+ */
+ lastChar = urlCheck + len;
+ lastChar--;
+
+ while ((lastChar >= urlCheck) && ((*lastChar == '/') ||
+ (*lastChar == '\\'))) {
+ *lastChar = 0;
+ lastChar--;
+ }
+
+ while ((lastChar >= urlCheck) && (*lastChar != '/') &&
+ (*lastChar != '\\')) {
+ *lastChar = 0;
+ lastChar--;
+ }
+
+ len = gstrlen(urlCheck);
+ }
+ }
+ bfree (B_L, urlCheck);
+
+ return urlRet;
+}
+
+/******************************************************************************/
+/*
+ * Returns the access method to use for a given URL
+ */
+
+accessMeth_t umGetAccessMethodForURL(char_t *url)
+{
+ accessMeth_t amRet;
+ char_t *urlHavingLimit, *group;
+
+ urlHavingLimit = umGetAccessLimit(url);
+ if (urlHavingLimit) {
+ group = umGetAccessLimitGroup(urlHavingLimit);
+
+ if (group && *group) {
+ amRet = umGetGroupAccessMethod(group);
+ } else {
+ amRet = umGetAccessLimitMethod(urlHavingLimit);
+ }
+
+ bfree(B_L, urlHavingLimit);
+ } else {
+ amRet = AM_FULL;
+ }
+
+ return amRet;
+}
+
+/******************************************************************************/
+/*
+ * Returns TRUE if user can access URL
+ */
+
+bool_t umUserCanAccessURL(char_t *user, char_t *url)
+{
+ accessMeth_t amURL;
+ char_t *group, *usergroup, *urlHavingLimit;
+ short priv;
+
+ a_assert(user && *user);
+ a_assert(url && *url);
+
+/*
+ * Make sure user exists
+ */
+ if (!umUserExists(user)) {
+ return FALSE;
+ }
+
+/*
+ * Make sure user is enabled
+ */
+ if (!umGetUserEnabled(user)) {
+ return FALSE;
+ }
+
+/*
+ * Make sure user has sufficient privileges (any will do)
+ */
+ usergroup = umGetUserGroup(user);
+ priv = umGetGroupPrivilege(usergroup);
+ if (priv == 0) {
+ return FALSE;
+ }
+
+/*
+ * Make sure user's group is enabled
+ */
+ if (!umGetGroupEnabled(usergroup)) {
+ return FALSE;
+ }
+
+/*
+ * The access method of the user group must not be AM_NONE
+ */
+ if (umGetGroupAccessMethod(usergroup) == AM_NONE) {
+ return FALSE;
+ }
+
+/*
+ * Check to see if there is an Access Limit for this URL
+ */
+ urlHavingLimit = umGetAccessLimit(url);
+ if (urlHavingLimit) {
+ amURL = umGetAccessLimitMethod(urlHavingLimit);
+ group = umGetAccessLimitGroup(urlHavingLimit);
+ bfree(B_L, urlHavingLimit);
+ } else {
+/*
+ * If there isn't an access limit for the URL, user has full access
+ */
+ return TRUE;
+ }
+
+/*
+ * If the access method for the URL is AM_NONE then
+ * the file "doesn't exist".
+ */
+ if (amURL == AM_NONE) {
+ return FALSE;
+ }
+
+/*
+ * If Access Limit has a group specified, then the user must be a
+ * member of that group
+ */
+ if (group && *group) {
+#ifdef qHierarchicalAccess
+ /*
+ * If we are compiling with the hierarchical access extensions, we
+ * instead call the user-provided function that checks to see whether
+ * the current user's access level is greater than or equal to the
+ * access level required for this URL.
+ */
+ return dmfCanAccess(usergroup, group);
+
+#else
+ if (usergroup && (gstrcmp(group, usergroup) != 0)) {
+ return FALSE;
+
+ }
+#endif
+ }
+
+/*
+ * Otherwise, user can access the URL
+ */
+ return TRUE;
+
+}
+
+/******************************************************************************/
+/*
+ * Returns TRUE if given name has only valid chars
+ */
+
+static bool_t umCheckName(char_t *name)
+{
+ a_assert(name && *name);
+
+ if (name && *name) {
+ while (*name) {
+ if (gisspace(*name)) {
+ return FALSE;
+ }
+
+ name++;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/um.h b/cpukit/httpd/um.h
new file mode 100644
index 0000000000..b520893275
--- /dev/null
+++ b/cpukit/httpd/um.h
@@ -0,0 +1,183 @@
+/*
+ * 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 ***********************************/
+
+#ifndef 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 */
+
+/******************************************************************************/
diff --git a/cpukit/httpd/umui.c b/cpukit/httpd/umui.c
new file mode 100644
index 0000000000..971b059bc7
--- /dev/null
+++ b/cpukit/httpd/umui.c
@@ -0,0 +1,641 @@
+/*
+ * umui.c -- User Management GoForm Processing
+ *
+ * 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 GoForm functions for User management
+ */
+
+/********************************* Includes ***********************************/
+
+#include "wsIntrn.h"
+#include "um.h"
+
+/********************************* Defines ************************************/
+
+#define NONE_OPTION T("<NONE>")
+#define MSG_START T("<body><h2>")
+#define MSG_END T("</h2></body>")
+
+/**************************** Forward Declarations ****************************/
+
+static void formAddUser(webs_t wp, char_t *path, char_t *query);
+static void formDeleteUser(webs_t wp, char_t *path, char_t *query);
+static void formDisplayUser(webs_t wp, char_t *path, char_t *query);
+static int aspGenerateUserList(int eid, webs_t wp,
+ int argc, char_t **argv);
+
+static void formAddGroup(webs_t wp, char_t *path, char_t *query);
+static void formDeleteGroup(webs_t wp, char_t *path, char_t *query);
+static int aspGenerateGroupList(int eid, webs_t wp,
+ int argc, char_t **argv);
+
+static void formAddAccessLimit(webs_t wp, char_t *path, char_t *query);
+static void formDeleteAccessLimit(webs_t wp, char_t *path, char_t *query);
+static int aspGenerateAccessLimitList(int eid, webs_t wp,
+ int argc, char_t **argv);
+
+static int aspGenerateAccessMethodList(int eid, webs_t wp,
+ int argc, char_t **argv);
+static int aspGeneratePrivilegeList(int eid, webs_t wp,
+ int argc, char_t **argv);
+
+static void formSaveUserManagement(webs_t wp, char_t *path, char_t *query);
+static void formLoadUserManagement(webs_t wp, char_t *path, char_t *query);
+
+static void websMsgStart(webs_t wp);
+static void websMsgEnd(webs_t wp);
+
+/*********************************** Code *************************************/
+/*
+ * Set up the User Management form handlers
+ */
+
+void formDefineUserMgmt(void)
+{
+ websAspDefine(T("MakeGroupList"), aspGenerateGroupList);
+ websAspDefine(T("MakeUserList"), aspGenerateUserList);
+ websAspDefine(T("MakeAccessLimitList"), aspGenerateAccessLimitList);
+ websAspDefine(T("MakeAccessMethodList"), aspGenerateAccessMethodList);
+ websAspDefine(T("MakePrivilegeList"), aspGeneratePrivilegeList);
+
+ websFormDefine(T("AddUser"), formAddUser);
+ websFormDefine(T("DeleteUser"), formDeleteUser);
+ websFormDefine(T("DisplayUser"), formDisplayUser);
+ websFormDefine(T("AddGroup"), formAddGroup);
+ websFormDefine(T("DeleteGroup"), formDeleteGroup);
+ websFormDefine(T("AddAccessLimit"), formAddAccessLimit);
+ websFormDefine(T("DeleteAccessLimit"), formDeleteAccessLimit);
+
+ websFormDefine(T("SaveUserManagement"), formSaveUserManagement);
+ websFormDefine(T("LoadUserManagement"), formLoadUserManagement);
+}
+
+/******************************************************************************/
+/*
+ * Add a user
+ */
+
+static void formAddUser(webs_t wp, char_t *path, char_t *query)
+{
+ char_t *userid, *pass1, *pass2, *group, *enabled, *ok;
+ bool_t bDisable;
+ int nCheck;
+
+ a_assert(wp);
+
+ userid = websGetVar(wp, T("user"), T(""));
+ pass1 = websGetVar(wp, T("password"), T(""));
+ pass2 = websGetVar(wp, T("passconf"), T(""));
+ group = websGetVar(wp, T("group"), T(""));
+ enabled = websGetVar(wp, T("enabled"), T(""));
+ ok = websGetVar(wp, T("ok"), T(""));
+
+ websHeader(wp);
+ websMsgStart(wp);
+
+ if (gstricmp(ok, T("ok")) != 0) {
+ websWrite(wp, T("Add User Cancelled"));
+ } else if (gstrcmp(pass1, pass2) != 0) {
+ websWrite(wp, T("Confirmation Password did not match."));
+ } else {
+ if (enabled && *enabled && (gstrcmp(enabled, T("on")) == 0)) {
+ bDisable = FALSE;
+ } else {
+ bDisable = TRUE;
+ }
+
+ nCheck = umAddUser(userid, pass1, group, 0, bDisable);
+ if (nCheck != 0) {
+ char_t * strError;
+
+ switch (nCheck) {
+ case UM_ERR_DUPLICATE:
+ strError = T("User already exists.");
+ break;
+
+ case UM_ERR_BAD_NAME:
+ strError = T("Invalid user name.");
+ break;
+
+ case UM_ERR_BAD_PASSWORD:
+ strError = T("Invalid password.");
+ break;
+
+ case UM_ERR_NOT_FOUND:
+ strError = T("Invalid or unselected group.");
+ break;
+
+ default:
+ strError = T("Error writing user record.");
+ break;
+ }
+
+ websWrite(wp, T("Unable to add user, \"%s\". %s"),
+ userid, strError);
+ } else {
+ websWrite(wp, T("User, \"%s\" was successfully added."),
+ userid);
+ }
+ }
+
+ websMsgEnd(wp);
+ websFooter(wp);
+ websDone(wp, 200);
+}
+
+/******************************************************************************/
+/*
+ * Delete a user
+ */
+
+static void formDeleteUser(webs_t wp, char_t *path, char_t *query)
+{
+ char_t *userid, *ok;
+
+ a_assert(wp);
+
+ userid = websGetVar(wp, T("user"), T(""));
+ ok = websGetVar(wp, T("ok"), T(""));
+
+ websHeader(wp);
+ websMsgStart(wp);
+
+ if (gstricmp(ok, T("ok")) != 0) {
+ websWrite(wp, T("Delete User Cancelled"));
+ } else if (umUserExists(userid) == FALSE) {
+ websWrite(wp, T("ERROR: User \"%s\" not found"), userid);
+ } else if (umGetUserProtected(userid)) {
+ websWrite(wp, T("ERROR: User, \"%s\" is delete-protected."), userid);
+ } else if (umDeleteUser(userid) != 0) {
+ websWrite(wp, T("ERROR: Unable to delete user, \"%s\" "), userid);
+ } else {
+ websWrite(wp, T("User, \"%s\" was successfully deleted."), userid);
+ }
+
+ websMsgEnd(wp);
+ websFooter(wp);
+ websDone(wp, 200);
+}
+
+/******************************************************************************/
+/*
+ * Display the user info
+ */
+
+static void formDisplayUser(webs_t wp, char_t *path, char_t *query)
+{
+ char_t *userid, *ok, *temp;
+ bool_t enabled;
+
+ a_assert(wp);
+
+ userid = websGetVar(wp, T("user"), T(""));
+ ok = websGetVar(wp, T("ok"), T(""));
+
+ websHeader(wp);
+ websWrite(wp, T("<body>"));
+
+ if (gstricmp(ok, T("ok")) != 0) {
+ websWrite(wp, T("Display User Cancelled"));
+ } else if (umUserExists(userid) == FALSE) {
+ websWrite(wp, T("ERROR: User <b>%s</b> not found.\n"), userid);
+ } else {
+ websWrite(wp, T("<h2>User ID: <b>%s</b></h2>\n"), userid);
+ temp = umGetUserGroup(userid);
+ websWrite(wp, T("<h3>User Group: <b>%s</b></h3>\n"), temp);
+ enabled = umGetUserEnabled(userid);
+ websWrite(wp, T("<h3>Enabled: <b>%d</b></h3>\n"), enabled);
+ }
+
+ websWrite(wp, T("</body>\n"));
+ websFooter(wp);
+ websDone(wp, 200);
+}
+
+
+/******************************************************************************/
+/*
+ * Generate HTML to create a list box containing the users
+ */
+
+static int aspGenerateUserList(int eid, webs_t wp, int argc, char_t **argv)
+{
+ char_t *userid;
+ int row, nBytesSent, nBytes;
+
+ a_assert(wp);
+
+ nBytes = websWrite(wp,
+ T("<SELECT NAME=\"user\" SIZE=\"3\" TITLE=\"Select a User\">"));
+ row = 0;
+ userid = umGetFirstUser();
+ nBytesSent = 0;
+
+ while (userid && (nBytes > 0)) {
+ nBytes = websWrite(wp, T("<OPTION VALUE=\"%s\">%s\n"),
+ userid, userid);
+ userid = umGetNextUser(userid);
+ nBytesSent += nBytes;
+ }
+
+ nBytesSent += websWrite(wp, T("</SELECT>"));
+
+ return nBytesSent;
+}
+
+/******************************************************************************/
+/*
+ * Add a group
+ */
+
+static void formAddGroup(webs_t wp, char_t *path, char_t *query)
+{
+ char_t *group, *enabled, *privilege, *method, *ok, *pChar;
+ int nCheck;
+ short priv;
+ accessMeth_t am;
+ bool_t bDisable;
+
+ a_assert(wp);
+
+ group = websGetVar(wp, T("group"), T(""));
+ method = websGetVar(wp, T("method"), T(""));
+ enabled = websGetVar(wp, T("enabled"), T(""));
+ privilege = websGetVar(wp, T("privilege"), T(""));
+ ok = websGetVar(wp, T("ok"), T(""));
+
+ websHeader(wp);
+ websMsgStart(wp);
+
+ if (gstricmp(ok, T("ok")) != 0) {
+ websWrite(wp, T("Add Group Cancelled."));
+ } else if ((group == NULL) || (*group == 0)) {
+ websWrite(wp, T("No Group Name was entered."));
+ } else if (umGroupExists(group)) {
+ websWrite(wp, T("ERROR: Group, \"%s\" already exists."), group);
+ } else {
+ if (privilege && *privilege) {
+/*
+ * privilege is a mulitple <SELECT> var, and must be parsed.
+ * Values for these variables are space delimited.
+ */
+ priv = 0;
+ for (pChar = privilege; *pChar; pChar++) {
+ if (*pChar == ' ') {
+ *pChar = '\0';
+ priv |= gatoi(privilege);
+ *pChar = ' ';
+ privilege = pChar + 1;
+ }
+ }
+ priv |= gatoi(privilege);
+ } else {
+ priv = 0;
+ }
+
+ if (method && *method) {
+ am = (accessMeth_t) gatoi(method);
+ } else {
+ am = AM_FULL;
+ }
+
+ if (enabled && *enabled && (gstrcmp(enabled, T("on")) == 0)) {
+ bDisable = FALSE;
+ } else {
+ bDisable = TRUE;
+ }
+
+ nCheck = umAddGroup(group, priv, am, 0, bDisable);
+ if (nCheck != 0) {
+ websWrite(wp, T("Unable to add group, \"%s\", code: %d "),
+ group, nCheck);
+ } else {
+ websWrite(wp, T("Group, \"%s\" was successfully added."),
+ group);
+ }
+ }
+
+ websMsgEnd(wp);
+ websFooter(wp);
+ websDone(wp, 200);
+}
+
+/******************************************************************************/
+/*
+ * Delete a group
+ */
+
+static void formDeleteGroup(webs_t wp, char_t *path, char_t *query)
+{
+ char_t *group, *ok;
+
+ a_assert(wp);
+
+ group = websGetVar(wp, T("group"), T(""));
+ ok = websGetVar(wp, T("ok"), T(""));
+
+ websHeader(wp);
+ websMsgStart(wp);
+
+ if (gstricmp(ok, T("ok")) != 0) {
+ websWrite(wp, T("Delete Group Cancelled."));
+ } else if ((group == NULL) || (*group == '\0')) {
+ websWrite(wp, T("ERROR: No group was selected."));
+ } else if (umGetGroupProtected(group)) {
+ websWrite(wp, T("ERROR: Group, \"%s\" is delete-protected."), group);
+ } else if (umGetGroupInUse(group)) {
+ websWrite(wp, T("ERROR: Group, \"%s\" is being used."), group);
+ } else if (umDeleteGroup(group) != 0) {
+ websWrite(wp, T("ERROR: Unable to delete group, \"%s\" "), group);
+ } else {
+ websWrite(wp, T("Group, \"%s\" was successfully deleted."), group);
+ }
+
+ websMsgEnd(wp);
+ websFooter(wp);
+ websDone(wp, 200);
+}
+
+/******************************************************************************/
+/*
+ * Generate HTML to create a list box containing the groups
+ */
+
+static int aspGenerateGroupList(int eid, webs_t wp, int argc, char_t **argv)
+{
+ char_t *group;
+ int row, nBytesSent, nBytes;
+
+ a_assert(wp);
+
+ row = 0;
+ nBytesSent = 0;
+ nBytes = websWrite(wp,
+ T("<SELECT NAME=\"group\" SIZE=\"3\" TITLE=\"Select a Group\">"));
+/*
+ * Add a special "<NONE>" element to allow de-selection
+ */
+ nBytes = websWrite(wp, T("<OPTION VALUE=\"\">[NONE]\n"));
+
+ group = umGetFirstGroup();
+ while (group && (nBytes > 0)) {
+ nBytes = websWrite(wp, T("<OPTION VALUE=\"%s\">%s\n"), group, group);
+ group = umGetNextGroup(group);
+ nBytesSent += nBytes;
+ }
+
+ nBytesSent += websWrite(wp, T("</SELECT>"));
+
+ return nBytesSent;
+}
+
+/******************************************************************************/
+/*
+ * Add an access limit
+ */
+
+static void formAddAccessLimit(webs_t wp, char_t *path, char_t *query)
+{
+ char_t *url, *method, *group, *secure, *ok;
+ int nCheck;
+ accessMeth_t am;
+ short nSecure;
+
+ a_assert(wp);
+
+ url = websGetVar(wp, T("url"), T(""));
+ group = websGetVar(wp, T("group"), T(""));
+ method = websGetVar(wp, T("method"), T(""));
+ secure = websGetVar(wp, T("secure"), T(""));
+ ok = websGetVar(wp, T("ok"), T(""));
+
+ websHeader(wp);
+ websMsgStart(wp);
+
+ if (gstricmp(ok, T("ok")) != 0) {
+ websWrite(wp, T("Add Access Limit Cancelled."));
+ } else if ((url == NULL) || (*url == 0)) {
+ websWrite(wp, T("ERROR: No URL was entered."));
+ } else if (umAccessLimitExists(url)) {
+ websWrite(wp, T("ERROR: An Access Limit for [%s] already exists."),
+ url);
+ } else {
+ if (method && *method) {
+ am = (accessMeth_t) gatoi(method);
+ } else {
+ am = AM_FULL;
+ }
+
+ if (secure && *secure) {
+ nSecure = (short) gatoi(secure);
+ } else {
+ nSecure = 0;
+ }
+
+ nCheck = umAddAccessLimit(url, am, nSecure, group);
+ if (nCheck != 0) {
+ websWrite(wp, T("Unable to add Access Limit for [%s]"), url);
+ } else {
+ websWrite(wp, T("Access limit for [%s], was successfully added."),
+ url);
+ }
+ }
+
+ websMsgEnd(wp);
+ websFooter(wp);
+ websDone(wp, 200);
+}
+
+/******************************************************************************/
+/*
+ * Delete an Access Limit
+ */
+
+static void formDeleteAccessLimit(webs_t wp, char_t *path, char_t *query)
+{
+ char_t *url, *ok;
+
+ a_assert(wp);
+
+ url = websGetVar(wp, T("url"), T(""));
+ ok = websGetVar(wp, T("ok"), T(""));
+
+ websHeader(wp);
+ websMsgStart(wp);
+
+ if (gstricmp(ok, T("ok")) != 0) {
+ websWrite(wp, T("Delete Access Limit Cancelled"));
+ } else if (umDeleteAccessLimit(url) != 0) {
+ websWrite(wp, T("ERROR: Unable to delete Access Limit for [%s]"),
+ url);
+ } else {
+ websWrite(wp, T("Access Limit for [%s], was successfully deleted."),
+ url);
+ }
+
+ websMsgEnd(wp);
+ websFooter(wp);
+ websDone(wp, 200);
+}
+
+/******************************************************************************/
+/*
+ * Generate HTML to create a list box containing the access limits
+ */
+
+static int aspGenerateAccessLimitList(int eid, webs_t wp,
+ int argc, char_t **argv)
+{
+ char_t *url;
+ int row, nBytesSent, nBytes;
+
+ a_assert(wp);
+
+ row = nBytesSent = 0;
+ url = umGetFirstAccessLimit();
+ nBytes = websWrite(wp,
+ T("<SELECT NAME=\"url\" SIZE=\"3\" TITLE=\"Select a URL\">"));
+
+ while (url && (nBytes > 0)) {
+ nBytes = websWrite(wp, T("<OPTION VALUE=\"%s\">%s\n"), url, url);
+ url = umGetNextAccessLimit(url);
+ nBytesSent += nBytes;
+ }
+
+ nBytesSent += websWrite(wp, T("</SELECT>"));
+
+ return nBytesSent;
+}
+
+/******************************************************************************/
+/*
+ * Generate HTML to create a list box containing the access methods
+ */
+
+static int aspGenerateAccessMethodList(int eid, webs_t wp,
+ int argc, char_t **argv)
+{
+ int nBytes;
+
+ a_assert(wp);
+
+ nBytes = websWrite(wp,
+ T("<SELECT NAME=\"method\" SIZE=\"3\" TITLE=\"Select a Method\">"));
+ nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">FULL ACCESS\n"),
+ AM_FULL);
+ nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">BASIC ACCESS\n"),
+ AM_BASIC);
+ nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\" SELECTED>DIGEST ACCESS\n"),
+ AM_DIGEST);
+ nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">NO ACCESS\n"),
+ AM_NONE);
+ nBytes += websWrite(wp, T("</SELECT>"));
+
+ return nBytes;
+}
+/******************************************************************************/
+/*
+ * Generate HTML to create a list box containing privileges
+ */
+
+static int aspGeneratePrivilegeList(int eid, webs_t wp,
+ int argc, char_t **argv)
+{
+ int nBytes;
+
+ a_assert(wp);
+
+ nBytes = websWrite(wp, T("<SELECT NAME=\"privilege\" SIZE=\"3\" "));
+ nBytes += websWrite(wp, T("MULTIPLE TITLE=\"Choose Privileges\">"));
+ nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">READ\n"), PRIV_READ);
+ nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">EXECUTE\n"), PRIV_WRITE);
+ nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">ADMINISTRATE\n"),
+ PRIV_ADMIN);
+ nBytes += websWrite(wp, T("</SELECT>"));
+
+ return nBytes;
+}
+
+/******************************************************************************/
+/*
+ * Save the user management configuration to a file
+ */
+
+static void formSaveUserManagement(webs_t wp, char_t *path, char_t *query)
+{
+ char_t *ok;
+
+ a_assert(wp);
+
+ ok = websGetVar(wp, T("ok"), T(""));
+
+ websHeader(wp);
+ websMsgStart(wp);
+
+ if (gstricmp(ok, T("ok")) != 0) {
+ websWrite(wp, T("Save Cancelled."));
+ } else if (umCommit(NULL) != 0) {
+ websWrite(wp, T("ERROR: Unable to save user configuration."));
+ } else {
+ websWrite(wp, T("User configuration was saved successfully."));
+ }
+
+ websMsgEnd(wp);
+ websFooter(wp);
+ websDone(wp, 200);
+}
+
+/******************************************************************************/
+/*
+ * Load the user management configuration from a file
+ */
+
+static void formLoadUserManagement(webs_t wp, char_t *path, char_t *query)
+{
+ char_t *ok;
+
+ a_assert(wp);
+
+ ok = websGetVar(wp, T("ok"), T(""));
+
+ websHeader(wp);
+ websMsgStart(wp);
+
+ if (gstricmp(ok, T("ok")) != 0) {
+ websWrite(wp, T("Load Cancelled."));
+ } else if (umRestore(NULL) != 0) {
+ websWrite(wp, T("ERROR: Unable to load user configuration."));
+ } else {
+ websWrite(wp, T("User configuration was re-loaded successfully."));
+ }
+
+ websMsgEnd(wp);
+ websFooter(wp);
+ websDone(wp, 200);
+}
+
+/******************************************************************************/
+/*
+ * Message start and end convenience functions
+ */
+
+static void websMsgStart(webs_t wp)
+{
+ websWrite(wp, MSG_START);
+}
+
+static void websMsgEnd(webs_t wp)
+{
+ websWrite(wp, MSG_END);
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/url.c b/cpukit/httpd/url.c
new file mode 100644
index 0000000000..07a99cc843
--- /dev/null
+++ b/cpukit/httpd/url.c
@@ -0,0 +1,212 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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;
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/value.c b/cpukit/httpd/value.c
new file mode 100644
index 0000000000..ac21ec6afe
--- /dev/null
+++ b/cpukit/httpd/value.c
@@ -0,0 +1,1213 @@
+/*
+ * value.c -- Generic type (holds all types)
+ *
+ * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
+ *
+ * $Id$
+ */
+
+/******************************** Description *********************************/
+
+/*
+ * This module provides a generic type that can hold all possible types.
+ * It is designed to provide maximum effeciency.
+ */
+
+/********************************* Includes ***********************************/
+
+#ifdef UEMF
+ #include "uemf.h"
+#else
+ #include "basic/basicInternal.h"
+#endif
+
+/*********************************** Locals ***********************************/
+#ifndef UEMF
+static value_t value_null; /* All zeros */
+
+/***************************** Forward Declarations ***************************/
+
+static void coerce_types(value_t* v1, value_t* v2);
+static int value_to_integer(value_t* vp);
+#endif /*!UEMF*/
+/*********************************** Code *************************************/
+/*
+ * Initialize a integer value.
+ */
+
+value_t valueInteger(long value)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = integer;
+ v.value.integer = value;
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Initialize a string value.
+ */
+
+value_t valueString(char_t* value, int flags)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = string;
+ if (flags & VALUE_ALLOCATE) {
+ v.allocated = 1;
+ v.value.string = gstrdup(B_L, value);
+ } else {
+ v.allocated = 0;
+ v.value.string = value;
+ }
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Free any storage allocated for a value.
+ */
+
+void valueFree(value_t* v)
+{
+ if (v->valid && v->allocated && v->type == string &&
+ v->value.string != NULL) {
+ bfree(B_L, v->value.string);
+ }
+#ifndef UEMF
+ if (v->valid && v->type == symbol && v->value.symbol.data != NULL &&
+ v->value.symbol.freeCb !=NULL) {
+ v->value.symbol.freeCb(v->value.symbol.data);
+ }
+#endif
+ v->type = undefined;
+ v->valid = 0;
+ v->allocated = 0;
+}
+
+#ifndef UEMF
+
+/******************************************************************************/
+/*
+ * Initialize an invalid value.
+ */
+
+value_t valueInvalid()
+{
+ value_t v;
+ v.valid = 0;
+ v.type = undefined;
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Initialize a flag value.
+ */
+
+value_t valueBool(int value)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.type = flag;
+ v.valid = 1;
+ v.value.flag = (char) value;
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Initialize a byteint value.
+ */
+
+value_t valueByteint(char value)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = byteint;
+ v.value.byteint = value;
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Initialize a shortint value.
+ */
+
+value_t valueShortint(short value)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = shortint;
+ v.value.shortint = value;
+ return v;
+}
+
+#ifdef FLOATING_POINT_SUPPORT
+/******************************************************************************/
+/*
+ * Initialize a floating value.
+ */
+
+value_t valueFloating(double value)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = floating;
+ v.value.floating = value;
+ return v;
+}
+#endif /* FLOATING_POINT_SUPPORT */
+
+/******************************************************************************/
+/*
+ * Initialize a big value.
+ */
+
+value_t valueBig(long high_word, long low_word)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = big;
+ v.value.big[BLOW] = low_word;
+ v.value.big[BHIGH] = high_word;
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Initialize a hex value.
+ */
+
+value_t valueHex(int value)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = hex;
+ v.value.integer = value;
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Initialize a octal value.
+ */
+
+value_t valueOctal(int value)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = octal;
+ v.value.integer = value;
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Initialize a percent value.
+ */
+
+value_t valuePercent(int value)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = percent;
+ v.value.percent = (char) value;
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Initialize an byte array. Note: no allocation, just store the ptr
+ */
+
+value_t valueBytes(char* value, int flags)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = bytes;
+ if (flags & VALUE_ALLOCATE) {
+ v.allocated = 1;
+ v.value.bytes = bstrdupA(B_L, value);
+ } else {
+ v.allocated = 0;
+ v.value.bytes = value;
+ }
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Initialize a symbol value.
+ * Value parameter can hold a pointer to any type of value
+ * Free parameter can be NULL, or a function pointer to a function that will
+ * free the value
+ */
+
+value_t valueSymbol(void *value, freeCallback freeCb)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = symbol;
+ v.value.symbol.data = value;
+ v.value.symbol.freeCb = freeCb;
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Initialize an error message value.
+ */
+
+value_t valueErrmsg(char_t* value)
+{
+ value_t v;
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+ v.type = errmsg;
+ v.value.errmsg = value;
+ return v;
+}
+
+/******************************************************************************/
+/*
+ * Copy a value. If the type is 'string' then allocate another string.
+ * Note: we allow the copy of a null value.
+ */
+
+value_t valueCopy(value_t v2)
+{
+ value_t v1;
+
+ v1 = v2;
+ if (v2.valid && v2.type == string && v2.value.string != NULL) {
+ v1.value.string = gstrdup(B_L, v2.value.string);
+ v1.allocated = 1;
+ }
+ return v1;
+}
+
+
+/******************************************************************************/
+/*
+ * Add a value.
+ */
+
+value_t valueAdd(value_t v1, value_t v2)
+{
+ value_t v;
+
+ a_assert(v1.valid);
+ a_assert(v2.valid);
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+
+ if (v1.type != v2.type)
+ coerce_types(&v1, &v2);
+
+ switch (v1.type) {
+ default:
+ case string:
+ case bytes:
+ a_assert(0);
+ break;
+
+#ifdef FLOATING_POINT_SUPPORT
+ case floating:
+ v1.value.floating += v2.value.floating;
+ return v1;
+#endif
+
+ case flag:
+ v1.value.bool |= v2.value.flag;
+ return v1;
+
+ case byteint:
+ case percent:
+ v1.value.byteint += v2.value.byteint;
+ return v1;
+
+ case shortint:
+ v1.value.shortint += v2.value.shortint;
+ return v1;
+
+ case hex:
+ case integer:
+ case octal:
+ v1.value.integer += v2.value.integer;
+ return v1;
+
+ case big:
+ v.type = big;
+ badd(v.value.big, v1.value.big, v2.value.big);
+ return v;
+ }
+
+ return v1;
+}
+
+
+/******************************************************************************/
+/*
+ * Subtract a value.
+ */
+
+value_t valueSub(value_t v1, value_t v2)
+{
+ value_t v;
+
+ a_assert(v1.valid);
+ a_assert(v2.valid);
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+
+ if (v1.type != v2.type)
+ coerce_types(&v1, &v2);
+ switch (v1.type) {
+ default:
+ a_assert(0);
+ break;
+
+#ifdef FLOATING_POINT_SUPPORT
+ case floating:
+ v1.value.floating -= v2.value.floating;
+ return v1;
+#endif
+
+ case flag:
+ v1.value.flag &= v2.value.flag;
+ return v1;
+
+ case byteint:
+ case percent:
+ v1.value.byteint -= v2.value.byteint;
+ return v1;
+
+ case shortint:
+ v1.value.shortint -= v2.value.shortint;
+ return v1;
+
+ case hex:
+ case integer:
+ case octal:
+ v1.value.integer -= v2.value.integer;
+ return v1;
+
+ case big:
+ v.type = big;
+ bsub(v.value.big, v1.value.big, v2.value.big);
+ return v;
+ }
+
+ return v1;
+}
+
+
+/******************************************************************************/
+/*
+ * Multiply a value.
+ */
+
+value_t valueMul(value_t v1, value_t v2)
+{
+ value_t v;
+
+ a_assert(v1.valid);
+ a_assert(v2.valid);
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+
+ if (v1.type != v2.type)
+ coerce_types(&v1, &v2);
+ switch (v1.type) {
+ default:
+ a_assert(0);
+ break;
+
+ case flag:
+ a_assert(v1.type != flag);
+ break;
+
+#ifdef FLOATING_POINT_SUPPORT
+ case floating:
+ v1.value.floating *= v2.value.floating;
+ return v1;
+#endif
+
+ case byteint:
+ case percent:
+ v1.value.byteint *= v2.value.byteint;
+ return v1;
+
+ case shortint:
+ v1.value.shortint *= v2.value.shortint;
+ return v1;
+
+ case hex:
+ case integer:
+ case octal:
+ v1.value.integer *= v2.value.integer;
+ return v1;
+
+ case big:
+ v.type = big;
+ bmul(v.value.big, v1.value.big, v2.value.big);
+ return v;
+ }
+
+ return v1;
+}
+
+
+/******************************************************************************/
+/*
+ * Divide a value.
+ */
+
+value_t valueDiv(value_t v1, value_t v2)
+{
+ value_t v;
+
+ a_assert(v1.valid);
+ a_assert(v2.valid);
+
+ memset(&v, 0x0, sizeof(v));
+ v.valid = 1;
+
+ if (v1.type != v2.type)
+ coerce_types(&v1, &v2);
+ switch (v1.type) {
+ default:
+ a_assert(0);
+ break;
+
+ case flag:
+ a_assert(v1.type != flag);
+ break;
+
+#ifdef FLOATING_POINT_SUPPORT
+ case floating:
+ v1.value.floating /= v2.value.floating;
+ return v1;
+#endif
+
+ case byteint:
+ case percent:
+ v1.value.byteint /= v2.value.byteint;
+ return v1;
+
+ case shortint:
+ v1.value.shortint /= v2.value.shortint;
+ return v1;
+
+ case hex:
+ case integer:
+ case octal:
+ v1.value.integer /= v2.value.integer;
+ return v1;
+
+ case big:
+ v.type = big;
+ bdiv(v.value.big, v1.value.big, v2.value.big);
+ return v;
+ }
+
+ return v1;
+}
+
+
+/******************************************************************************/
+/*
+ * Compare a value.
+ */
+
+int valueCmp(value_t v1, value_t v2)
+{
+ a_assert(v1.valid);
+ a_assert(v2.valid);
+
+ if (v1.type != v2.type)
+ coerce_types(&v1, &v2);
+ if (v1.type != v2.type) {
+/*
+ * Make v2 == v1
+ */
+ a_assert(v1.type == v2.type);
+ v2 = v1;
+ return 0;
+ }
+ switch (v1.type) {
+ case string:
+ if (v1.value.string == NULL && v2.value.string == NULL) {
+ return 0;
+ } else if (v1.value.string == NULL) {
+ return -1;
+ } else if (v2.value.string == NULL) {
+ return 1;
+ } else {
+ return gstrcmp(v1.value.string, v2.value.string);
+ }
+ /* Nobody here */
+
+ case flag:
+ if (v1.value.flag < v2.value.flag)
+ return -1;
+ else if (v1.value.flag == v2.value.flag)
+ return 0;
+ else return 1;
+
+#ifdef FLOATING_POINT_SUPPORT
+ case floating:
+ if (v1.value.floating < v2.value.floating)
+ return -1;
+ else if (v1.value.floating == v2.value.floating)
+ return 0;
+ else return 1;
+#endif
+
+ case byteint:
+ case percent:
+ if (v1.value.byteint < v2.value.byteint)
+ return -1;
+ else if (v1.value.byteint == v2.value.byteint)
+ return 0;
+ else return 1;
+
+ case shortint:
+ if (v1.value.shortint < v2.value.shortint)
+ return -1;
+ else if (v1.value.shortint == v2.value.shortint)
+ return 0;
+ else return 1;
+
+ case hex:
+ case integer:
+ case octal:
+ if (v1.value.integer < v2.value.integer)
+ return -1;
+ else if (v1.value.integer == v2.value.integer)
+ return 0;
+ else return 1;
+
+ case big:
+ return bcompare(v1.value.big, v2.value.big);
+
+ default:
+ a_assert(0);
+ return 0;
+ }
+}
+
+
+/******************************************************************************/
+/*
+ * If type mismatch, then coerce types to big.
+ * Note: Known bug, casting of negative bigs to floats doesn't work.
+ */
+
+static void coerce_types(register value_t* v1, register value_t* v2)
+{
+#ifdef FLOATING_POINT_SUPPORT
+ if (v1->type == floating) {
+ v2->type = floating;
+ v2->value.floating = (double) v2->value.integer;
+ if (v2->type == big)
+ v2->value.floating = (double) v2->value.big[BLOW] +
+ (double) v2->value.big[BHIGH] * (double) MAXINT;
+
+ } else if (v2->type == floating) {
+ v1->type = floating;
+ v1->value.floating = (double) v1->value.integer;
+ if (v1->type == big)
+ v1->value.floating = (double) v1->value.big[BLOW] +
+ (double) v1->value.big[BHIGH] * (double) MAXINT;
+
+ } else if (v1->type == big) {
+#else
+ if (v1->type == big) {
+#endif /* FLOATING_POINT_SUPPORT */
+ v2->value.big[BLOW] = value_to_integer(v2);
+ if (valueNegative(v2))
+ v2->value.big[BHIGH] = -1;
+ else
+ v2->value.big[BHIGH] = 0;
+ v2->type = big;
+
+ } else if (v2->type == big) {
+ if (valueNegative(v1))
+ v1->value.big[BHIGH] = -1;
+ else
+ v1->value.big[BHIGH] = 0;
+ v1->value.big[BLOW] = value_to_integer(v1);
+ v1->type = big;
+
+
+ } else if (v1->type == integer) {
+ v2->value.integer = value_to_integer(v2);
+ v2->type = integer;
+
+ } else if (v2->type == integer) {
+ v1->value.integer = value_to_integer(v1);
+ v1->type = integer;
+
+ } else if (v1->type != integer) {
+ v2->type = v1->type;
+
+ } else if (v2->type != integer) {
+ v1->type = v2->type;
+
+ }
+ a_assert(v1->type == v2->type);
+}
+
+
+/******************************************************************************/
+/*
+ * Return true if the value is numeric and negative. Otherwise return 0.
+ */
+
+int valueNegative(value_t* vp)
+{
+ switch (vp->type) {
+ default:
+ case string:
+ case bytes:
+ return 0;
+
+#ifdef FLOATING_POINT_SUPPORT
+ case floating:
+ if (vp->value.floating < 0)
+ return 1;
+ return 0;
+#endif
+
+ case flag:
+ if ((signed char)vp->value.flag < 0)
+ return 1;
+ return 0;
+
+ case byteint:
+ case percent:
+ if ((signed char)vp->value.byteint < 0)
+ return 1;
+ return 0;
+
+ case shortint:
+ if (vp->value.shortint < 0)
+ return 1;
+ return 0;
+
+ case hex:
+ case integer:
+ case octal:
+ if (vp->value.integer < 0)
+ return 1;
+ return 0;
+
+ case big:
+ if (vp->value.big[BHIGH] < 0)
+ return 1;
+ return 0;
+ }
+}
+
+/******************************************************************************/
+/*
+ * Return true if the value is numeric and zero. Otherwise return 0.
+ */
+
+int valueZero(value_t* vp)
+{
+ switch (vp->type) {
+ default:
+ case string:
+ case bytes:
+ return 0;
+
+#ifdef FLOATING_POINT_SUPPORT
+ case floating:
+ if (vp->value.floating == 0)
+ return 1;
+ return 0;
+#endif
+
+ case flag:
+ if (vp->value.flag == 0)
+ return 1;
+ return 0;
+
+ case byteint:
+ case percent:
+ if (vp->value.byteint == 0)
+ return 1;
+ return 0;
+
+ case shortint:
+ if (vp->value.shortint == 0)
+ return 1;
+ return 0;
+
+ case hex:
+ case integer:
+ case octal:
+ if (vp->value.integer == 0)
+ return 1;
+ return 0;
+
+ case big:
+ if (vp->value.big[BHIGH] == 0 && vp->value.big[BLOW] == 0)
+ return 1;
+ return 0;
+ }
+}
+
+
+/******************************************************************************/
+/*
+ * Cast a value to an integer. Cannot be called for floating, non-numerics
+ * or bigs.
+ */
+
+static int value_to_integer(value_t* vp)
+{
+ switch (vp->type) {
+ default:
+ case string:
+ case bytes:
+ case big:
+#ifdef FLOATING_POINT_SUPPORT
+ case floating:
+ a_assert(0);
+ return -1;
+#endif
+
+ case flag:
+ return (int) vp->value.flag;
+
+ case byteint:
+ case percent:
+ return (int) vp->value.byteint;
+
+ case shortint:
+ return (int) vp->value.shortint;
+
+ case hex:
+ case integer:
+ case octal:
+ return (int) vp->value.integer;
+ }
+}
+
+
+/******************************************************************************/
+/*
+ * Convert a value to a text based representation of its value
+ */
+
+void valueSprintf(char_t** out, int size, char_t* fmt, value_t vp)
+{
+ char_t *src, *dst, *tmp, *dst_start;
+
+ a_assert(out);
+
+ *out = NULL;
+
+ if (! vp.valid) {
+ *out = bstrdup(B_L, T("Invalid"));
+ return;
+ }
+
+ switch (vp.type) {
+ case flag:
+ if (fmt == NULL || *fmt == '\0') {
+ *out = bstrdup(B_L, (vp.value.flag) ? T("true") : T("false"));
+ } else {
+ fmtAlloc(out, size, fmt, (vp.value.flag) ? T("true") : T("false"));
+ }
+ break;
+
+#ifdef FLOATING_POINT_SUPPORT
+ case floating:
+ if (fmt == NULL || *fmt == '\0') {
+ fmtAlloc(out, size, T("%f"), vp.value.floating);
+ } else {
+ fmtAlloc(out, size, fmt, vp.value.floating);
+ }
+ break;
+#endif
+
+ case hex:
+ if (fmt == NULL || *fmt == '\0') {
+ fmtAlloc(out, size, T("0x%lx"), vp.value.hex);
+ } else {
+ fmtAlloc(out, size, fmt, vp.value.hex);
+ }
+ break;
+
+ case big:
+ if (*out == NULL) {
+ *out = btoa(vp.value.big, NULL, 0);
+ } else {
+ btoa(vp.value.big, *out, size);
+ }
+ break;
+
+ case integer:
+ if (fmt == NULL || *fmt == '\0') {
+ fmtAlloc(out, size, T("%ld"), vp.value.integer);
+ } else {
+ fmtAlloc(out, size, fmt, vp.value.integer);
+ }
+ break;
+
+ case octal:
+ if (fmt == NULL || *fmt == '\0') {
+ fmtAlloc(out, size, T("0%lo"), vp.value.octal);
+ } else {
+ fmtAlloc(out, size, fmt, vp.value.octal);
+ }
+ break;
+
+ case percent:
+ if (fmt == NULL || *fmt == '\0') {
+ fmtAlloc(out, size, T("%d%%"), vp.value.percent);
+ } else {
+ fmtAlloc(out, size, fmt, vp.value.percent);
+ }
+ break;
+
+ case byteint:
+ if (fmt == NULL || *fmt == '\0') {
+ fmtAlloc(out, size, T("%d"), (int) vp.value.byteint);
+ } else {
+ fmtAlloc(out, size, fmt, (int) vp.value.byteint);
+ }
+ break;
+
+ case shortint:
+ if (fmt == NULL || *fmt == '\0') {
+ fmtAlloc(out, size, T("%d"), (int) vp.value.shortint);
+ } else {
+ fmtAlloc(out, size, fmt, (int) vp.value.shortint);
+ }
+ break;
+
+ case string:
+ case errmsg:
+ src = vp.value.string;
+
+ if (src == NULL) {
+ *out = bstrdup(B_L, T("NULL"));
+ } else if (fmt && *fmt) {
+ fmtAlloc(out, size, fmt, src);
+
+ } else {
+
+ *out = balloc(B_L, size);
+ dst_start = dst = *out;
+ for (; *src != '\0'; src++) {
+ if (dst >= &dst_start[VALUE_MAX_STRING - 5])
+ break;
+ switch (*src) {
+ case '\a': *dst++ = '\\'; *dst++ = 'a'; break;
+ case '\b': *dst++ = '\\'; *dst++ = 'b'; break;
+ case '\f': *dst++ = '\\'; *dst++ = 'f'; break;
+ case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
+ case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
+ case '\t': *dst++ = '\\'; *dst++ = 't'; break;
+ case '\v': *dst++ = '\\'; *dst++ = 'v'; break;
+ case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
+ case '"': *dst++ = '\\'; *dst++ = '\"'; break;
+ default:
+ if (gisprint(*src)) {
+ *dst++ = *src;
+ } else {
+ fmtAlloc(&tmp, size, T("\\x%02x"),
+ (unsigned int) *src);
+ gstrcpy(dst, tmp);
+ bfreeSafe(B_L, tmp);
+ dst += 4;
+ }
+ break;
+ }
+ }
+ *dst++ = '\0';
+ }
+ break;
+
+#ifdef UNUSED
+ case bytes:
+ asrc = vp.value.bytes;
+
+ if (asrc == NULL) {
+ *out = bstrdup(B_L, T("NULL"));
+
+ } else if (fmt && *fmt) {
+ fmtAlloc(out, size, fmt, asrc);
+
+ } else {
+
+ dst_start = dst;
+ for (; *asrc != '\0'; asrc++) {
+ if (dst >= &dst_start[VALUE_MAX_STRING - 5])
+ break;
+ switch (*asrc) {
+ case '\a': *dst++ = '\\'; *dst++ = 'a'; break;
+ case '\b': *dst++ = '\\'; *dst++ = 'b'; break;
+ case '\f': *dst++ = '\\'; *dst++ = 'f'; break;
+ case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
+ case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
+ case '\t': *dst++ = '\\'; *dst++ = 't'; break;
+ case '\v': *dst++ = '\\'; *dst++ = 'v'; break;
+ case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
+ case '"': *dst++ = '\\'; *dst++ = '\"'; break;
+ default:
+ if (gisprint(*asrc)) {
+ *dst++ = *asrc;
+ } else {
+ fmtAlloc(dst, size,
+ T("\\x%02x"), (unsigned int) *asrc);
+ dst += 4;
+ }
+ break;
+ }
+ }
+ *dst++ = '\0';
+ }
+ break;
+#endif
+
+ default:
+ a_assert(0);
+ }
+}
+
+/******************************************************************************/
+/*
+ * Print a value to the named file descriptor
+ */
+
+void valueFprintf(FILE* fp, char_t* fmt, value_t vp)
+{
+ char_t *buf;
+
+ buf = NULL;
+ valueSprintf(&buf, VALUE_MAX_STRING, fmt, vp);
+ gfputs(buf, fp);
+ bfreeSafe(B_L, buf);
+ fflush(fp);
+}
+
+/******************************************************************************/
+/*
+ * Ascii to value conversion
+ */
+
+value_t valueAtov(char_t* s, int pref_type)
+{
+ vtype_t type;
+ value_t v;
+ long tmp[2], tmp2[2], base[2];
+ int i, len, num;
+
+ a_assert(0 <= pref_type && pref_type < 99); /* Sanity check */
+ a_assert(s);
+
+ v = value_null;
+ if (s == NULL) {
+ return value_null;
+ }
+
+ base[BLOW] = 10;
+ base[BHIGH] = 0;
+ len = gstrlen(s);
+
+/*
+ * Determine the value type
+ */
+ type = undefined;
+ if (pref_type <= 0) {
+ if (gisdigit(*s)) {
+ base[BHIGH] = 0;
+ if (s[len - 1] == '%') {
+ type = percent;
+ len --;
+ base[BLOW] = 10;
+ } else if (*s == '0') {
+ if (s[1] == 'x') {
+ type = hex;
+ s += 2;
+ len -= 2;
+ base[BLOW] = 16;
+ } else if (s[1] == '\0') {
+ type = integer;
+ base[BLOW] = 10;
+ } else {
+ type = octal;
+ s++;
+ len--;
+ base[BLOW] = 8;
+ }
+ } else {
+ type = integer;
+ base[BLOW] = 10;
+ }
+
+ } else {
+ if (gstrcmp(s, T("true")) == 0 || gstrcmp(s, T("false")) == 0) {
+ type = flag;
+ } else if (*s == '\'' && s[len - 1] == '\'') {
+ type = string;
+ s++;
+ len -= 2;
+ } else if (*s == '\"' && s[len - 1] == '\"') {
+ type = string;
+ s++;
+ len -= 2;
+ } else {
+ type = string;
+ }
+ }
+ v.type = type;
+
+ } else
+ v.type = pref_type;
+ v.valid = 1;
+
+/*
+ * Do the conversion. Always use big arithmetic
+ */
+ switch (v.type) {
+ case hex:
+ if (!isdigit(s[0])) {
+ if (gtolower(s[0]) >= 'a' || gtolower(s[0]) <= 'f') {
+ v.value.big[BLOW] = 10 + gtolower(s[0]) - 'a';
+ } else {
+ v.value.big[BLOW] = 0;
+ }
+ } else {
+ v.value.big[BLOW] = s[0] - '0';
+ }
+ v.value.big[BHIGH] = 0;
+ for (i = 1; i < len; i++) {
+ if (!isdigit(s[i])) {
+ if (gtolower(s[i]) < 'a' || gtolower(s[i]) > 'f') {
+ break;
+ }
+ num = 10 + gtolower(s[i]) - 'a';
+ } else {
+ num = s[i] - '0';
+ }
+ bmul(tmp, v.value.big, base);
+ binit(tmp2, 0, num);
+ badd(v.value.big, tmp, tmp2);
+ }
+ v.value.hex = v.value.big[BLOW];
+ break;
+
+ case shortint:
+ case byteint:
+ case integer:
+ case percent:
+ case octal:
+ case big:
+ v.value.big[BHIGH] = 0;
+ if (gisdigit(s[0]))
+ v.value.big[BLOW] = s[0] - '0';
+ else
+ v.value.big[BLOW] = 0;
+ for (i = 1; i < len && gisdigit(s[i]); i++) {
+ bmul(tmp, v.value.big, base);
+ binit(tmp2, 0, s[i] - '0');
+ badd(v.value.big, tmp, tmp2);
+ }
+ switch (v.type) {
+ case shortint:
+ v.value.shortint = (short) v.value.big[BLOW];
+ break;
+ case byteint:
+ v.value.byteint = (char) v.value.big[BLOW];
+ break;
+ case integer:
+ v.value.integer = (int) v.value.big[BLOW];
+ break;
+ case percent:
+ v.value.percent = (char) v.value.big[BLOW];
+ break;
+ case octal:
+ v.value.octal = (int) v.value.big[BLOW];
+ break;
+ default:
+ break;
+ }
+ break;
+
+#ifdef FLOATING_POINT_SUPPORT
+ case floating:
+ gsscanf(s, T("%f"), &v.value.floating);
+ break;
+#endif
+
+ case flag:
+ if (*s == 't')
+ v.value.flag = 1;
+ else v.value.flag = 0;
+ break;
+
+ case string:
+/*
+ * Note this always ballocs a string
+ */
+ v = valueString(s, VALUE_ALLOCATE);
+ break;
+
+ case bytes:
+ v = valueBytes((char*) s, VALUE_ALLOCATE);
+ break;
+
+#ifdef UNUSED
+ case literal:
+ v = value_literal(bstrdup(B_L, s));
+ v.value.literal[len] = '\0';
+ break;
+#endif
+
+ case undefined:
+ case symbol:
+ default:
+ v.valid = 0;
+ a_assert(0);
+ }
+ return v;
+}
+
+#endif /* !UEMF */
+/******************************************************************************/
diff --git a/cpukit/httpd/wbase64.c b/cpukit/httpd/wbase64.c
new file mode 100644
index 0000000000..87659eeb6a
--- /dev/null
+++ b/cpukit/httpd/wbase64.c
@@ -0,0 +1,149 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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';
+ }
+}
+/******************************************************************************/
diff --git a/cpukit/httpd/webcomp.c b/cpukit/httpd/webcomp.c
new file mode 100644
index 0000000000..6b19b3ba18
--- /dev/null
+++ b/cpukit/httpd/webcomp.c
@@ -0,0 +1,188 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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 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;
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/webmain.c b/cpukit/httpd/webmain.c
new file mode 100644
index 0000000000..c9c0b9cc15
--- /dev/null
+++ b/cpukit/httpd/webmain.c
@@ -0,0 +1,499 @@
+/*
+ * 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;
+}
diff --git a/cpukit/httpd/webpage.c b/cpukit/httpd/webpage.c
new file mode 100644
index 0000000000..a42a8b45c9
--- /dev/null
+++ b/cpukit/httpd/webpage.c
@@ -0,0 +1,141 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/******************************** 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));
+
+#ifdef 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));
+
+#ifdef 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)
+{
+#ifdef 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)
+{
+#ifdef 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)
+{
+
+#ifdef 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));
+
+#ifdef WEBS_PAGE_ROM
+ websRomPageSeek(wp, offset, SEEK_CUR);
+#else
+ lseek(wp->docfd, offset, SEEK_CUR);
+#endif
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/webrom.c b/cpukit/httpd/webrom.c
new file mode 100644
index 0000000000..23de2c6d60
--- /dev/null
+++ b/cpukit/httpd/webrom.c
@@ -0,0 +1,15 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+#include "wsIntrn.h"
+
+websRomPageIndexType websRomPageIndex[] = {
+ { 0, 0, 0 },
+};
diff --git a/cpukit/httpd/webs.c b/cpukit/httpd/webs.c
new file mode 100644
index 0000000000..4465a72afe
--- /dev/null
+++ b/cpukit/httpd/webs.c
@@ -0,0 +1,2966 @@
+/*
+ * webs.c -- GoAhead Embedded HTTP webs server
+ *
+ * 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 implements an embedded HTTP/1.1 web server. It supports
+ * loadable URL handlers that define the nature of URL processing performed.
+ */
+
+/********************************* Includes ***********************************/
+
+#include "wsIntrn.h"
+#ifdef DIGEST_ACCESS_SUPPORT
+ #include "websda.h"
+#endif
+
+/******************************** Global Data *********************************/
+
+websStatsType websStats; /* Web access stats */
+webs_t *webs; /* Open connection list head */
+sym_fd_t websMime; /* Set of mime types */
+int websMax; /* List size */
+int websPort; /* Listen port for server */
+char_t websHost[64]; /* Host name for the server */
+char_t websIpaddr[64]; /* IP address for the server */
+char_t *websHostUrl = NULL; /* URL to access server */
+char_t *websIpaddrUrl = NULL; /* URL to access server */
+
+/*********************************** Locals ***********************************/
+/*
+ * Standard HTTP error codes
+ */
+
+websErrorType websErrors[] = {
+ { 200, T("Data follows") },
+ { 204, T("No Content") },
+ { 301, T("Redirect") },
+ { 302, T("Redirect") },
+ { 304, T("Use local copy") },
+ { 400, T("Page not found") },
+ { 401, T("Unauthorized") },
+ { 403, T("Forbidden") },
+ { 404, T("Site or Page Not Found") },
+ { 405, T("Access Denied") },
+ { 500, T("Web Error") },
+ { 501, T("Not Implemented") },
+ { 503, T("Site Temporarily Unavailable. Try again.") },
+ { 0, NULL }
+};
+
+#ifdef WEBS_LOG_SUPPORT
+static char_t websLogname[64] = T("log.txt"); /* Log filename */
+static int websLogFd; /* Log file handle */
+#endif
+
+static int websListenSock; /* Listen socket */
+static char_t websRealm[64] = T("GoAhead"); /* Realm name */
+
+static int websOpenCount = 0; /* count of apps using this module */
+
+/**************************** Forward Declarations ****************************/
+
+
+/*static char_t *websErrorMsg(int code);*/
+static int websGetInput(webs_t wp, char_t **ptext, int *nbytes);
+static int websParseFirst(webs_t wp, char_t *text);
+static void websParseRequest(webs_t wp);
+static void websSocketEvent(int sid, int mask, int data);
+static int websGetTimeSinceMark(webs_t wp);
+
+#ifdef WEBS_LOG_SUPPORT
+static void websLog(webs_t wp, int code);
+#endif
+#ifdef WEBS_IF_MODIFIED_SUPPORT
+static time_t dateParse(time_t tip, char_t *cmd);
+#endif
+
+/*********************************** Code *************************************/
+/*
+ * Open the GoAhead WebServer
+ */
+
+int websOpenServer(int port, int retries)
+{
+ websMimeType *mt;
+
+ if (++websOpenCount != 1) {
+ return websPort;
+ }
+
+ a_assert(port > 0);
+ a_assert(retries >= 0);
+
+#ifdef WEBS_PAGE_ROM
+ websRomOpen();
+#endif
+
+ webs = NULL;
+ websMax = 0;
+/*
+ * Create a mime type lookup table for quickly determining the content type
+ */
+ websMime = symOpen(WEBS_SYM_INIT * 4);
+ a_assert(websMime >= 0);
+ for (mt = websMimeList; mt->type; mt++) {
+ symEnter(websMime, mt->ext, valueString(mt->type, 0), 0);
+ }
+
+/*
+ * Open the URL handler module. The caller should create the required
+ * URL handlers after calling this function.
+ */
+ if (websUrlHandlerOpen() < 0) {
+ return -1;
+ }
+ websFormOpen();
+
+#ifdef WEBS_LOG_SUPPORT
+/*
+ * Optional request log support
+ */
+ websLogFd = gopen(websLogname, O_CREAT | O_TRUNC | O_APPEND | O_WRONLY,
+ 0666);
+ a_assert(websLogFd >= 0);
+#endif
+
+ return websOpenListen(port, retries);
+}
+
+/******************************************************************************/
+/*
+ * Close the GoAhead WebServer
+ */
+
+void websCloseServer()
+{
+ webs_t wp;
+ int wid;
+
+ if (--websOpenCount > 0) {
+ return;
+ }
+
+/*
+ * Close the listen handle first then all open connections.
+ */
+ websCloseListen();
+
+/*
+ * Close each open browser connection and free all resources
+ */
+ for (wid = websMax; webs && wid >= 0; wid--) {
+ if ((wp = webs[wid]) == NULL) {
+ continue;
+ }
+ socketCloseConnection(wp->sid);
+ websFree(wp);
+ }
+
+#ifdef WEBS_LOG_SUPPORT
+ if (websLogFd >= 0) {
+ close(websLogFd);
+ websLogFd = -1;
+ }
+#endif
+
+#ifdef WEBS_PAGE_ROM
+ websRomClose();
+#endif
+ symClose(websMime);
+ websFormClose();
+ websUrlHandlerClose();
+}
+
+/******************************************************************************/
+/*
+ * Open the GoAhead WebServer listen port
+ */
+
+int websOpenListen(int port, int retries)
+{
+ int i, orig;
+
+ a_assert(port > 0);
+ a_assert(retries >= 0);
+
+ orig = port;
+/*
+ * Open the webs webs listen port. If we fail, try the next port.
+ */
+ for (i = 0; i <= retries; i++) {
+ websListenSock = socketOpenConnection(NULL, port, websAccept, 0);
+ if (websListenSock >= 0) {
+ break;
+ }
+ port++;
+ }
+ if (i > retries) {
+ error(E_L, E_USER, T("Couldn't open a socket on ports %d - %d"),
+ orig, port - 1);
+ return -1;
+ }
+
+/*
+ * Determine the full URL address to access the home page for this web server
+ */
+ websPort = port;
+ bfreeSafe(B_L, websHostUrl);
+ bfreeSafe(B_L, websIpaddrUrl);
+ websIpaddrUrl = websHostUrl = NULL;
+
+ if (port == 80) {
+ websHostUrl = bstrdup(B_L, websHost);
+ websIpaddrUrl = bstrdup(B_L, websIpaddr);
+ } else {
+ fmtAlloc(&websHostUrl, WEBS_MAX_URL + 80, T("%s:%d"), websHost, port);
+ fmtAlloc(&websIpaddrUrl, WEBS_MAX_URL + 80, T("%s:%d"),
+ websIpaddr, port);
+ }
+ trace(0, T("webs: Listening for HTTP requests at address %s\n"),
+ websIpaddrUrl);
+
+ return port;
+}
+
+/******************************************************************************/
+/*
+ * Close webs listen port
+ */
+
+void websCloseListen()
+{
+ if (websListenSock >= 0) {
+ socketCloseConnection(websListenSock);
+ websListenSock = -1;
+ }
+ bfreeSafe(B_L, websHostUrl);
+ bfreeSafe(B_L, websIpaddrUrl);
+ websIpaddrUrl = websHostUrl = NULL;
+}
+
+/******************************************************************************/
+/*
+ * Accept a connection
+ */
+
+int websAccept(int sid, char *ipaddr, int port, int listenSid)
+{
+ webs_t wp;
+ int wid;
+
+ a_assert(ipaddr && *ipaddr);
+ a_assert(sid >= 0);
+ a_assert(port >= 0);
+
+/*
+ * Allocate a new handle for this accepted connection. This will allocate
+ * a webs_t structure in the webs[] list
+ */
+ if ((wid = websAlloc(sid)) < 0) {
+ return -1;
+ }
+ wp = webs[wid];
+ a_assert(wp);
+ wp->listenSid = listenSid;
+
+ ascToUni(wp->ipaddr, ipaddr, min(sizeof(wp->ipaddr), strlen(ipaddr) + 1));
+
+/*
+ * Check if this is a request from a browser on this system. This is useful
+ * to know for permitting administrative operations only for local access
+ */
+ if (gstrcmp(wp->ipaddr, T("127.0.0.1")) == 0 ||
+ gstrcmp(wp->ipaddr, websIpaddr) == 0 ||
+ gstrcmp(wp->ipaddr, websHost) == 0) {
+ wp->flags |= WEBS_LOCAL_REQUEST;
+ }
+
+/*
+ * Arrange for websSocketEvent to be called when read data is available
+ */
+ socketCreateHandler(sid, SOCKET_READABLE, websSocketEvent, (int) wp);
+
+/*
+ * Arrange for a timeout to kill hung requests
+ */
+ wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout, (void *) wp);
+ trace(8, T("webs: accept request\n"));
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * The webs socket handler. Called in response to I/O. We just pass control
+ * to the relevant read or write handler. A pointer to the webs structure
+ * is passed as an (int) in iwp.
+ */
+
+static void websSocketEvent(int sid, int mask, int iwp)
+{
+ webs_t wp;
+
+ wp = (webs_t) iwp;
+ a_assert(wp);
+
+ if (! websValid(wp)) {
+ return;
+ }
+
+ if (mask & SOCKET_READABLE) {
+ websReadEvent(wp);
+ }
+ if (mask & SOCKET_WRITABLE) {
+ if (websValid(wp) && wp->writeSocket) {
+ (*wp->writeSocket)(wp);
+ }
+ }
+}
+
+/******************************************************************************/
+/*
+ * The webs read handler. This is the primary read event loop. It uses a
+ * state machine to track progress while parsing the HTTP request.
+ * Note: we never block as the socket is always in non-blocking mode.
+ */
+
+void websReadEvent(webs_t wp)
+{
+ char_t *text;
+ int rc, nbytes, len, done, fd;
+
+ a_assert(wp);
+ a_assert(websValid(wp));
+
+ websSetTimeMark(wp);
+
+/*
+ * Read as many lines as possible. socketGets is called to read the header
+ * and socketRead is called to read posted data.
+ */
+ text = NULL;
+ fd = -1;
+ for (done = 0; !done; ) {
+ if (text) {
+ bfree(B_L, text);
+ text = NULL;
+ }
+
+/*
+ * Get more input into "text". Returns 0, if more data is needed
+ * to continue, -1 if finished with the request, or 1 if all
+ * required data is available for current state.
+ */
+ while ((rc = websGetInput(wp, &text, &nbytes)) == 0) {
+ ;
+ }
+
+/*
+ * websGetInput returns -1 if it finishes with the request
+ */
+ if (rc < 0) {
+ break;
+ }
+
+/*
+ * This is the state machine for the web server.
+ */
+ switch(wp->state) {
+ case WEBS_BEGIN:
+/*
+ * Parse the first line of the Http header
+ */
+ if (websParseFirst(wp, text) < 0) {
+ done++;
+ break;
+ }
+ wp->state = WEBS_HEADER;
+ break;
+
+ case WEBS_HEADER:
+/*
+ * Store more of the HTTP header. As we are doing line reads, we
+ * need to separate the lines with '\n'
+ */
+ if (ringqLen(&wp->header) > 0) {
+ ringqPutStr(&wp->header, T("\n"));
+ }
+ ringqPutStr(&wp->header, text);
+ break;
+
+ case WEBS_POST_CLEN:
+/*
+ * POST request with content specified by a content length.
+ * If this is a CGI request, write the data to the cgi stdin.
+ * socketGets was used to get the data and it strips \n's so
+ * add them back in here.
+ */
+#ifndef __NO_CGI_BIN
+ if (wp->flags & WEBS_CGI_REQUEST) {
+ if (fd == -1) {
+ fd = gopen(wp->cgiStdin, O_CREAT | O_WRONLY | O_BINARY,
+ 0666);
+ }
+ gwrite(fd, text, gstrlen(text));
+ /*
+ * NOTE that the above comment is wrong -- if the content length
+ * is set, websGetInput() does NOT use socketGets(), it uses
+ * socketRead(), so the line below that adds an additional newline
+ * is destructive.
+ */
+ /*gwrite(fd, T("\n"), sizeof(char_t));*/
+/*
+ * Line removed as per BUG02488
+ *
+ nbytes += 1;
+ */
+ } else
+#endif
+ if (wp->query) {
+ if (wp->query[0] && !(wp->flags & WEBS_POST_DATA)) {
+/*
+ * Special case where the POST request also had query data
+ * specified in the URL, ie. url?query_data. In this case
+ * the URL query data is separated by a '&' from the posted
+ * query data.
+ */
+ len = gstrlen(wp->query);
+ wp->query = brealloc(B_L, wp->query, (len + gstrlen(text) +
+ 2) * sizeof(char_t));
+ wp->query[len++] = '&';
+ gstrcpy(&wp->query[len], text);
+
+ } else {
+/*
+ * The existing query data came from the POST request so just
+ * append it.
+ */
+ if (text != NULL)
+ {
+ len = gstrlen(wp->query);
+ wp->query = brealloc(B_L, wp->query, (len + gstrlen(text) +
+ 1) * sizeof(char_t));
+ if (wp->query) {
+ gstrcpy(&wp->query[len], text);
+ }
+ }
+ }
+
+ } else {
+ wp->query = bstrdup(B_L, text);
+ }
+/*
+ * Calculate how much more post data is to be read.
+ */
+ wp->flags |= WEBS_POST_DATA;
+ wp->clen -= nbytes;
+ if (wp->clen > 0) {
+ if (nbytes > 0) {
+ break;
+ }
+ done++;
+ break;
+ }
+/*
+ * No more data so process the request, (but be sure to close
+ * the input file first!).
+ */
+ if (fd != -1) {
+ gclose (fd);
+ fd = -1;
+ }
+ websUrlHandlerRequest(wp);
+ done++;
+ break;
+
+ case WEBS_POST:
+/*
+ * POST without content-length specification
+ * If this is a CGI request, write the data to the cgi stdin.
+ * socketGets was used to get the data and it strips \n's so
+ * add them back in here.
+ */
+
+#ifndef __NO_CGI_BIN
+ if (wp->flags & WEBS_CGI_REQUEST) {
+ if (fd == -1) {
+ fd = gopen(wp->cgiStdin, O_CREAT | O_WRONLY | O_BINARY,
+ 0666);
+ }
+ gwrite(fd, text, gstrlen(text));
+ gwrite(fd, T("\n"), sizeof(char_t));
+ } else
+#endif
+ if (wp->query && *wp->query && !(wp->flags & WEBS_POST_DATA)) {
+ len = gstrlen(wp->query);
+ wp->query = brealloc(B_L, wp->query, (len + gstrlen(text) +
+ 2) * sizeof(char_t));
+ if (wp->query) {
+ wp->query[len++] = '&';
+ gstrcpy(&wp->query[len], text);
+ }
+
+ } else {
+ wp->query = bstrdup(B_L, text);
+ }
+ wp->flags |= WEBS_POST_DATA;
+ done++;
+ break;
+
+ default:
+ websError(wp, 404, T("Bad state"));
+ done++;
+ break;
+ }
+ }
+
+ if (fd != -1) {
+ fd = gclose (fd);
+ }
+
+ if (text) {
+ bfree(B_L, text);
+ }
+}
+
+/******************************************************************************/
+/*
+ * Get input from the browser. Return TRUE (!0) if the request has been
+ * handled. Return -1 on errors or if the request has been processed,
+ * 1 if input read, and 0 to instruct the caller to call again for more input.
+ *
+ * Note: socketRead will Return the number of bytes read if successful. This
+ * may be less than the requested "bufsize" and may be zero. It returns -1 for
+ * errors. It returns 0 for EOF. Otherwise it returns the number of bytes
+ * read. Since this may be zero, callers should use socketEof() to
+ * distinguish between this and EOF.
+ */
+
+static int websGetInput(webs_t wp, char_t **ptext, int *pnbytes)
+{
+ char_t *text;
+ char buf[WEBS_SOCKET_BUFSIZ+1];
+ int nbytes, len, clen;
+
+ a_assert(websValid(wp));
+ a_assert(ptext);
+ a_assert(pnbytes);
+
+ *ptext = text = NULL;
+ *pnbytes = 0;
+
+/*
+ * If this request is a POST with a content length, we know the number
+ * of bytes to read so we use socketRead().
+ */
+ if (wp->state == WEBS_POST_CLEN) {
+ len = (wp->clen > WEBS_SOCKET_BUFSIZ) ? WEBS_SOCKET_BUFSIZ : wp->clen;
+ } else {
+ len = 0;
+ }
+
+ if (len > 0) {
+
+#ifdef WEBS_SSL_SUPPORT
+ if (wp->flags & WEBS_SECURE) {
+ nbytes = websSSLRead(wp->wsp, buf, len);
+ } else {
+ nbytes = socketRead(wp->sid, buf, len);
+ }
+#else
+ nbytes = socketRead(wp->sid, buf, len);
+#endif
+ if (nbytes < 0) { /* Error */
+ websDone(wp, 0);
+ return -1;
+
+ } else if (nbytes == 0) { /* EOF or No data available */
+ /* Bugfix for POST DoS attack with invalid content length */
+ if (socketEof(wp->sid)) {
+ websDone(wp, 0);
+ }
+ /* End of bugfix */
+ return -1;
+
+ } else { /* Valid data */
+/*
+ * Convert to UNICODE if necessary. First be sure the string
+ * is NULL terminated.
+ */
+ buf[nbytes] = '\0';
+ if ((text = ballocAscToUni(buf, nbytes)) == NULL) {
+ websError(wp, 503, T("Insufficient memory"));
+ return -1;
+ }
+ }
+
+ } else {
+#ifdef WEBS_SSL_SUPPORT
+ if (wp->flags & WEBS_SECURE) {
+ nbytes = websSSLGets(wp->wsp, &text);
+ } else {
+ nbytes = socketGets(wp->sid, &text);
+ }
+#else
+ nbytes = socketGets(wp->sid, &text);
+#endif
+
+ if (nbytes < 0) {
+ int eof;
+/*
+ * Error, EOF or incomplete
+ */
+#ifdef WEBS_SSL_SUPPORT
+ if (wp->flags & WEBS_SECURE) {
+/*
+ * If state is WEBS_BEGIN and the request is secure, a -1 will
+ * usually indicate SSL negotiation
+ */
+ if (wp->state == WEBS_BEGIN) {
+ eof = 1;
+ } else {
+ eof = websSSLEof(wp->wsp);
+ }
+ } else {
+ eof = socketEof(wp->sid);
+ }
+#else
+ eof = socketEof(wp->sid);
+#endif
+
+ if (eof) {
+/*
+ * If this is a post request without content length, process
+ * the request as we now have all the data. Otherwise just
+ * close the connection.
+ */
+ if (wp->state == WEBS_POST) {
+ websUrlHandlerRequest(wp);
+ } else {
+ websDone(wp, 0);
+ }
+ } else {
+/*
+ * If an error occurred and it wasn't an eof, close the connection
+ */
+#ifdef HP_FIX
+ websDone(wp, 0);
+#endif /*HP_FIX*/
+
+ }
+/*
+ * If state is WEBS_HEADER and the ringq is empty, then this is a
+ * simple request with no additional header fields to process and
+ * no empty line terminator.
+ */
+/*
+ * NOTE: this fix for earlier versions of browsers is troublesome
+ * because if we don't receive the entire header in the first pass
+ * this code assumes we were only expecting a one line header, which
+ * is not necessarily the case. So we weren't processing the whole
+ * header and weren't fufilling requests properly.
+ */
+#ifdef UNUSED
+ if (wp->state == WEBS_HEADER && ringqLen(&wp->header) <= 0) {
+ websParseRequest(wp);
+ websUrlHandlerRequest(wp);
+ }
+#endif
+ return -1;
+
+ } else if (nbytes == 0) {
+ if (wp->state == WEBS_HEADER) {
+/*
+ * Valid empty line, now finished with header
+ */
+ websParseRequest(wp);
+ if (wp->flags & WEBS_POST_REQUEST) {
+ if (wp->flags & WEBS_CLEN) {
+ wp->state = WEBS_POST_CLEN;
+ clen = wp->clen;
+ } else {
+ wp->state = WEBS_POST;
+ clen = 1;
+ }
+ if (clen > 0) {
+/*
+ * Return 0 to get more data.
+ */
+ return 0;
+ }
+ return 1;
+ }
+/*
+ * We've read the header so go and handle the request
+ */
+ websUrlHandlerRequest(wp);
+ }
+ return -1;
+ }
+ }
+ a_assert(text);
+ a_assert(nbytes > 0);
+ *ptext = text;
+ *pnbytes = nbytes;
+ return 1;
+}
+
+/******************************************************************************/
+/*
+ * Parse the first line of a HTTP request
+ */
+
+static int websParseFirst(webs_t wp, char_t *text)
+{
+ char_t *op, *proto, *protoVer, *url, *host, *query, *path, *port, *ext;
+ char_t *buf;
+ int testPort;
+
+ a_assert(websValid(wp));
+ a_assert(text && *text);
+
+/*
+ * Determine the request type: GET, HEAD or POST
+ */
+ op = gstrtok(text, T(" \t"));
+ if (op == NULL || *op == '\0') {
+ websError(wp, 400, T("Bad HTTP request"));
+ return -1;
+ }
+ if (gstrcmp(op, T("GET")) != 0) {
+ if (gstrcmp(op, T("POST")) == 0) {
+ wp->flags |= WEBS_POST_REQUEST;
+ } else if (gstrcmp(op, T("HEAD")) == 0) {
+ wp->flags |= WEBS_HEAD_REQUEST;
+ } else {
+ websError(wp, 400, T("Bad request type"));
+ return -1;
+ }
+ }
+
+/*
+ * Store result in the form (CGI) variable store
+ */
+ websSetVar(wp, T("REQUEST_METHOD"), op);
+
+ url = gstrtok(NULL, T(" \t\n"));
+ if (url == NULL || *url == '\0') {
+ websError(wp, 400, T("Bad HTTP request"));
+ return -1;
+ }
+ protoVer = gstrtok(NULL, T(" \t\n"));
+
+/*
+ * Parse the URL and store all the various URL components. websUrlParse
+ * returns an allocated buffer in buf which we must free. We support both
+ * proxied and non-proxied requests. Proxied requests will have http://host/
+ * at the start of the URL. Non-proxied will just be local path names.
+ */
+ host = path = port = proto = query = ext = NULL;
+ if (websUrlParse(url, &buf, &host, &path, &port, &query, &proto,
+ NULL, &ext) < 0) {
+ websError(wp, 400, T("Bad URL format"));
+ return -1;
+ }
+
+ wp->url = bstrdup(B_L, url);
+
+#ifndef __NO_CGI_BIN
+ if (gstrstr(url, CGI_BIN) != NULL) {
+ wp->flags |= WEBS_CGI_REQUEST;
+ if (wp->flags & WEBS_POST_REQUEST) {
+ wp->cgiStdin = websGetCgiCommName();
+ }
+ }
+#endif
+
+ wp->query = bstrdup(B_L, query);
+ wp->host = bstrdup(B_L, host);
+ wp->path = bstrdup(B_L, path);
+ wp->protocol = bstrdup(B_L, proto);
+ wp->protoVersion = bstrdup(B_L, protoVer);
+
+ if ((testPort = socketGetPort(wp->listenSid)) >= 0) {
+ wp->port = testPort;
+ } else {
+ wp->port = gatoi(port);
+ }
+
+ if (gstrcmp(ext, T(".asp")) == 0) {
+ wp->flags |= WEBS_ASP;
+ }
+ bfree(B_L, buf);
+
+ websUrlType(url, wp->type, TSZ(wp->type));
+
+#ifdef WEBS_PROXY_SUPPORT
+/*
+ * Determine if this is a request for local webs data. If it is not a proxied
+ * request from the browser, we won't see the "http://" or the system name, so
+ * we assume it must be talking to us directly for local webs data.
+ * Note: not fully implemented yet.
+ */
+ if (gstrstr(wp->url, T("http://")) == NULL ||
+ ((gstrcmp(wp->host, T("localhost")) == 0 ||
+ gstrcmp(wp->host, websHost) == 0) && (wp->port == websPort))) {
+ wp->flags |= WEBS_LOCAL_PAGE;
+ if (gstrcmp(wp->path, T("/")) == 0) {
+ wp->flags |= WEBS_HOME_PAGE;
+ }
+ }
+#endif
+
+ ringqFlush(&wp->header);
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Parse a full request
+ */
+
+#define isgoodchar(s) (gisalnum((s)) || ((s) == '/') || ((s) == '_') || \
+ ((s) == '.') || ((s) == '-') )
+
+static void websParseRequest(webs_t wp)
+{
+ char_t *authType, *upperKey, *cp, *browser, *lp, *key, *value;
+
+ a_assert(websValid(wp));
+
+/*
+ * Define default CGI values
+ */
+ websSetVar(wp, T("HTTP_AUTHORIZATION"), T(""));
+
+/*
+ * Parse the header and create the Http header keyword variables
+ * We rewrite the header as we go for non-local requests. NOTE: this
+ * modifies the header string directly and tokenizes each line with '\0'.
+ */
+ browser = NULL;
+ for (lp = (char_t*) wp->header.servp; lp && *lp; ) {
+ cp = lp;
+ if ((lp = gstrchr(lp, '\n')) != NULL) {
+ lp++;
+ }
+
+ if ((key = gstrtok(cp, T(": \t\n"))) == NULL) {
+ continue;
+ }
+
+ if ((value = gstrtok(NULL, T("\n"))) == NULL) {
+ value = T("");
+ }
+
+ while (gisspace(*value)) {
+ value++;
+ }
+ strlower(key);
+
+/*
+ * Create a variable (CGI) for each line in the header
+ */
+ fmtAlloc(&upperKey, (gstrlen(key) + 6), T("HTTP_%s"), key);
+ for (cp = upperKey; *cp; cp++) {
+ if (*cp == '-')
+ *cp = '_';
+ }
+ strupper(upperKey);
+ websSetVar(wp, upperKey, value);
+ bfree(B_L, upperKey);
+
+/*
+ * Track the requesting agent (browser) type
+ */
+ if (gstrcmp(key, T("user-agent")) == 0) {
+ wp->userAgent = bstrdup(B_L, value);
+
+/*
+ * Parse the user authorization. ie. password
+ */
+ } else if (gstricmp(key, T("authorization")) == 0) {
+/*
+ * Determine the type of Authorization Request
+ */
+ authType = bstrdup (B_L, value);
+ a_assert (authType);
+/*
+ * Truncate authType at the next non-alpha character
+ */
+ cp = authType;
+ while (gisalpha(*cp)) {
+ cp++;
+ }
+ *cp = '\0';
+
+ wp->authType = bstrdup(B_L, authType);
+ bfree(B_L, authType);
+
+ if (gstricmp(wp->authType, T("basic")) == 0) {
+ char_t userAuth[FNAMESIZE];
+/*
+ * The incoming value is username:password (Basic authentication)
+ */
+ if ((cp = gstrchr(value, ' ')) != NULL) {
+ *cp = '\0';
+ /*
+ * bugfix 5/24/02 -- we were leaking the memory pointed to by
+ * wp->authType that was allocated just before the if()
+ * statement that we are currently in. Thanks to Simon Byholm.
+ */
+ bfree(B_L, wp->authType);
+ wp->authType = bstrdup(B_L, value);
+ websDecode64(userAuth, ++cp, sizeof(userAuth));
+ } else {
+ websDecode64(userAuth, value, sizeof(userAuth));
+ }
+/*
+ * Split userAuth into userid and password
+ */
+ if ((cp = gstrchr(userAuth, ':')) != NULL) {
+ *cp++ = '\0';
+ }
+ if (cp) {
+ wp->userName = bstrdup(B_L, userAuth);
+ wp->password = bstrdup(B_L, cp);
+ } else {
+ wp->userName = bstrdup(B_L, T(""));
+ wp->password = bstrdup(B_L, T(""));
+ }
+/*
+ * Set the flags to indicate digest authentication
+ */
+ wp->flags |= WEBS_AUTH_BASIC;
+ } else {
+#ifdef DIGEST_ACCESS_SUPPORT
+/*
+ * The incoming value is slightly more complicated (Digest)
+ */
+ char_t *np; /* pointer to end of tag name */
+ char_t tp; /* temporary character holding space */
+ char_t *vp; /* pointer to value */
+ char_t *npv; /* pointer to end of value, "next" pointer */
+ char_t tpv; /* temporary character holding space */
+/*
+ * Set the flags to indicate digest authentication
+ */
+ wp->flags |= WEBS_AUTH_DIGEST;
+/*
+ * Move cp to Next word beyond "Digest",
+ * vp to first char after '='.
+ */
+ cp = value;
+ while (isgoodchar(*cp)) {
+ cp++;
+ }
+ while (!isgoodchar(*cp)) {
+ cp++;
+ }
+
+/*
+ * Find beginning of value
+ */
+ vp = gstrchr(cp, '=');
+ while (vp) {
+/*
+ * Zero-terminate tag name
+ */
+ np = cp;
+ while (isgoodchar(*np)) {
+ np++;
+ }
+ tp = *np;
+ *np = 0;
+/*
+ * Advance value pointer to first legit character
+ */
+ vp++;
+ while (!isgoodchar(*vp)) {
+ vp++;
+ }
+/*
+ * Zero-terminate value
+ */
+ npv = vp;
+ while (isgoodchar(*npv)) {
+ npv++;
+ }
+ tpv = *npv;
+ *npv = 0;
+/*
+ * Extract the fields
+ */
+ if (gstricmp(cp, T("username")) == 0) {
+ wp->userName = bstrdup(B_L, vp);
+ } else if (gstricmp(cp, T("response")) == 0) {
+ wp->digest = bstrdup(B_L, vp);
+ } else if (gstricmp(cp, T("opaque")) == 0) {
+ wp->opaque = bstrdup(B_L, vp);
+ } else if (gstricmp(cp, T("uri")) == 0) {
+ wp->uri = bstrdup(B_L, vp);
+ } else if (gstricmp(cp, T("realm")) == 0) {
+ wp->realm = bstrdup(B_L, vp);
+ } else if (gstricmp(cp, T("nonce")) == 0) {
+ wp->nonce = bstrdup(B_L, vp);
+ } else if (gstricmp(cp, T("nc")) == 0) {
+ wp->nc = bstrdup(B_L, vp);
+ } else if (gstricmp(cp, T("cnonce")) == 0) {
+ wp->cnonce = bstrdup(B_L, vp);
+ } else if (gstricmp(cp, T("qop")) == 0) {
+ wp->qop = bstrdup(B_L, vp);
+ }
+/*
+ * Restore tag name and value zero-terminations
+ */
+ *np = tp;
+ *npv = tpv;
+/*
+ * Advance tag name and value pointers
+ */
+ cp = npv;
+ while (*cp && isgoodchar(*cp)) {
+ cp++;
+ }
+ while (*cp && !isgoodchar(*cp)) {
+ cp++;
+ }
+
+ if (*cp) {
+ vp = gstrchr(cp, '=');
+ } else {
+ vp = NULL;
+ }
+ }
+#endif /* DIGEST_ACCESS_SUPPORT */
+ } /* if (gstrcmp(wp->authType)) */
+/*
+ * Parse the content length
+ */
+ } else if (gstrcmp(key, T("content-length")) == 0) {
+ /*
+ * 11 Oct 02 BgP -- The server would crash if an attacker sent a POST
+ * message with a content-length value <= 0. We assume that anyone
+ * sending this is malicious, and the POST is read from the socket,
+ * but it is ignored, and the socket is closed.
+ */
+ wp->clen = gatoi(value);
+ if (wp->clen > 0)
+ {
+ wp->flags |= WEBS_CLEN;
+ websSetVar(wp, T("CONTENT_LENGTH"), value);
+ }
+ else
+ {
+ wp->clen = 0;
+ }
+
+/*
+ * Parse the content type
+ */
+ } else if (gstrcmp(key, T("content-type")) == 0) {
+ websSetVar(wp, T("CONTENT_TYPE"), value);
+
+#ifdef WEBS_KEEP_ALIVE_SUPPORT
+ } else if (gstrcmp(key, T("connection")) == 0) {
+ strlower(value);
+ if (gstrcmp(value, T("keep-alive")) == 0) {
+ wp->flags |= WEBS_KEEP_ALIVE;
+ }
+#endif
+
+#ifdef WEBS_PROXY_SUPPORT
+/*
+ * This may be useful if you wish to keep a local cache of web pages
+ * for proxied requests.
+ */
+ } else if (gstrcmp(key, T("pragma")) == 0) {
+ char_t tmp[256];
+ gstrncpy(tmp, value, TSZ(tmp));
+ strlower(tmp);
+ if (gstrstr(tmp, T("no-cache"))) {
+ wp->flags |= WEBS_DONT_USE_CACHE;
+ }
+#endif /* WEBS_PROXY_SUPPORT */
+
+/*
+ * Store the cookie
+ */
+ } else if (gstrcmp(key, T("cookie")) == 0) {
+ wp->flags |= WEBS_COOKIE;
+ wp->cookie = bstrdup(B_L, value);
+
+#ifdef WEBS_IF_MODIFIED_SUPPORT
+/*
+ * See if the local page has been modified since the browser last
+ * requested this document. If not, just return a 302
+ */
+ } else if (gstrcmp(key, T("if-modified-since")) == 0) {
+ char_t *cmd;
+ time_t tip = 0;
+
+ if ((cp = gstrchr(value, ';')) != NULL) {
+ *cp = '\0';
+ }
+
+ fmtAlloc(&cmd, 64, T("%s"), value);
+
+ if ((wp->since = dateParse(tip, cmd)) != 0) {
+ wp->flags |= WEBS_IF_MODIFIED;
+ }
+
+ bfreeSafe(B_L, cmd);
+#endif /* WEBS_IF_MODIFIED_SUPPORT */
+ }
+ }
+}
+
+/******************************************************************************/
+/*
+ * Set the variable (CGI) environment for this request. Create variables
+ * for all standard CGI variables. Also decode the query string and create
+ * a variable for each name=value pair.
+ */
+
+void websSetEnv(webs_t wp)
+{
+ char_t portBuf[8];
+ char_t *keyword, *value, *valCheck, *valNew;
+
+ a_assert(websValid(wp));
+
+ websSetVar(wp, T("QUERY_STRING"), wp->query);
+ websSetVar(wp, T("GATEWAY_INTERFACE"), T("CGI/1.1"));
+ websSetVar(wp, T("SERVER_HOST"), websHost);
+ websSetVar(wp, T("SERVER_NAME"), websHost);
+ websSetVar(wp, T("SERVER_URL"), websHostUrl);
+ websSetVar(wp, T("REMOTE_HOST"), wp->ipaddr);
+ websSetVar(wp, T("REMOTE_ADDR"), wp->ipaddr);
+ websSetVar(wp, T("PATH_INFO"), wp->path);
+ stritoa(websPort, portBuf, sizeof(portBuf));
+ websSetVar(wp, T("SERVER_PORT"), portBuf);
+ websSetVar(wp, T("SERVER_ADDR"), websIpaddr);
+ fmtAlloc(&value, FNAMESIZE, T("%s/%s"), WEBS_NAME, WEBS_VERSION);
+ websSetVar(wp, T("SERVER_SOFTWARE"), value);
+ bfreeSafe(B_L, value);
+ websSetVar(wp, T("SERVER_PROTOCOL"), wp->protoVersion);
+
+/*
+ * Decode and create an environment query variable for each query keyword.
+ * We split into pairs at each '&', then split pairs at the '='.
+ * Note: we rely on wp->decodedQuery preserving the decoded values in the
+ * symbol table.
+ */
+ wp->decodedQuery = bstrdup(B_L, wp->query);
+ keyword = gstrtok(wp->decodedQuery, T("&"));
+ while (keyword != NULL) {
+ if ((value = gstrchr(keyword, '=')) != NULL) {
+ *value++ = '\0';
+ websDecodeUrl(keyword, keyword, gstrlen(keyword));
+ websDecodeUrl(value, value, gstrlen(value));
+ } else {
+ value = T("");
+ }
+
+ if (*keyword) {
+/*
+ * If keyword has already been set, append the new value to what has
+ * been stored.
+ */
+ if ((valCheck = websGetVar(wp, keyword, NULL)) != 0) {
+ fmtAlloc(&valNew, 256, T("%s %s"), valCheck, value);
+ websSetVar(wp, keyword, valNew);
+ bfreeSafe(B_L, valNew);
+ } else {
+ websSetVar(wp, keyword, value);
+ }
+ }
+ keyword = gstrtok(NULL, T("&"));
+ }
+
+#ifdef EMF
+/*
+ * Add GoAhead Embedded Management Framework defines
+ */
+ websSetEmfEnvironment(wp);
+#endif
+}
+
+/******************************************************************************/
+/*
+ * Define a webs (CGI) variable for this connection. Also create in relevant
+ * scripting engines. Note: the incoming value may be volatile.
+ */
+
+void websSetVar(webs_t wp, char_t *var, char_t *value)
+{
+ value_t v;
+
+ a_assert(websValid(wp));
+
+/*
+ * value_instring will allocate the string if required.
+ */
+ if (value) {
+ v = valueString(value, VALUE_ALLOCATE);
+ } else {
+ v = valueString(T(""), VALUE_ALLOCATE);
+ }
+ symEnter(wp->cgiVars, var, v, 0);
+}
+
+/******************************************************************************/
+/*
+ * Return TRUE if a webs variable exists for this connection.
+ */
+
+int websTestVar(webs_t wp, char_t *var)
+{
+ sym_t *sp;
+
+ a_assert(websValid(wp));
+
+ if (var == NULL || *var == '\0') {
+ return 0;
+ }
+
+ if ((sp = symLookup(wp->cgiVars, var)) == NULL) {
+ return 0;
+ }
+ return 1;
+}
+
+/******************************************************************************/
+/*
+ * Get a webs variable but return a default value if string not found.
+ * Note, defaultGetValue can be NULL to permit testing existence.
+ */
+
+char_t *websGetVar(webs_t wp, char_t *var, char_t *defaultGetValue)
+{
+ sym_t *sp;
+
+ a_assert(websValid(wp));
+ a_assert(var && *var);
+
+ if ((sp = symLookup(wp->cgiVars, var)) != NULL) {
+ a_assert(sp->content.type == string);
+ if (sp->content.value.string) {
+ return sp->content.value.string;
+ } else {
+ return T("");
+ }
+ }
+ return defaultGetValue;
+}
+
+/******************************************************************************/
+/*
+ * Return TRUE if a webs variable is set to a given value
+ */
+
+int websCompareVar(webs_t wp, char_t *var, char_t *value)
+{
+ a_assert(websValid(wp));
+ a_assert(var && *var);
+
+ if (gstrcmp(value, websGetVar(wp, var, T(" __UNDEF__ "))) == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Cancel the request timeout. Note may be called multiple times.
+ */
+
+void websTimeoutCancel(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ if (wp->timeout >= 0) {
+ emfUnschedCallback(wp->timeout);
+ wp->timeout = -1;
+ }
+}
+
+/******************************************************************************/
+/*
+ * Output a HTTP response back to the browser. If redirect is set to a
+ * URL, the browser will be sent to this location.
+ */
+
+void websResponse(webs_t wp, int code, char_t *message, char_t *redirect)
+{
+ char_t *date;
+
+ a_assert(websValid(wp));
+
+/*
+ * IE3.0 needs no Keep Alive for some return codes.
+ */
+ wp->flags &= ~WEBS_KEEP_ALIVE;
+
+/*
+ * Only output the header if a header has not already been output.
+ */
+ if ( !(wp->flags & WEBS_HEADER_DONE)) {
+ wp->flags |= WEBS_HEADER_DONE;
+/*
+ * Redirect behaves much better when sent with HTTP/1.0
+ */
+ if (redirect != NULL) {
+ websWrite(wp, T("HTTP/1.0 %d %s\r\n"), code, websErrorMsg(code));
+ } else {
+ websWrite(wp, T("HTTP/1.1 %d %s\r\n"), code, websErrorMsg(code));
+ }
+
+/*
+ * By license terms the following line of code must not be modified.
+ */
+ websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
+
+/*
+ * Timestamp/Date is usually the next to go
+ */
+ if ((date = websGetDateString(NULL)) != NULL) {
+ websWrite(wp, T("Date: %s\r\n"), date);
+ bfree(B_L, date);
+ }
+/*
+ * If authentication is required, send the auth header info
+ */
+ if (code == 401) {
+ if (!(wp->flags & WEBS_AUTH_DIGEST)) {
+ websWrite(wp, T("WWW-Authenticate: Basic realm=\"%s\"\r\n"),
+ websGetRealm());
+#ifdef DIGEST_ACCESS_SUPPORT
+ } else {
+ char_t *nonce, *opaque;
+
+ /* $$$ before... (note commas instead of semicolons...)
+ nonce = websCalcNonce(wp),
+ opaque = websCalcOpaque(wp),
+ $$$ after */
+ nonce = websCalcNonce(wp);
+ opaque = websCalcOpaque(wp);
+ /* ...$$$ end */
+ websWrite(wp,
+ T("WWW-Authenticate: Digest realm=\"%s\", domain=\"%s\",")
+ T("qop=\"%s\", nonce=\"%s\", opaque=\"%s\",")
+ T("algorithm=\"%s\", stale=\"%s\"\r\n"),
+ websGetRealm(),
+ websGetHostUrl(),
+ T("auth"),
+ nonce,
+ opaque, T("MD5"), T("FALSE"));
+ bfree(B_L, nonce);
+ bfree(B_L, opaque);
+#endif
+ }
+ }
+
+ if (wp->flags & WEBS_KEEP_ALIVE) {
+ websWrite(wp, T("Connection: keep-alive\r\n"));
+ }
+
+ websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n"));
+ websWrite(wp, T("Content-Type: text/html\r\n"));
+/*
+ * We don't do a string length here as the message may be multi-line.
+ * Ie. <CR><LF> will count as only one and we will have a content-length
+ * that is too short.
+ *
+ * websWrite(wp, T("Content-Length: %s\r\n"), message);
+ */
+ if (redirect) {
+ websWrite(wp, T("Location: %s\r\n"), redirect);
+ }
+ websWrite(wp, T("\r\n"));
+ }
+
+/*
+ * If the browser didn't do a HEAD only request, send the message as well.
+ */
+ if ((wp->flags & WEBS_HEAD_REQUEST) == 0 && message && *message) {
+ websWrite(wp, T("%s\r\n"), message);
+ }
+ websDone(wp, code);
+}
+
+/******************************************************************************/
+/*
+ * Redirect the user to another webs page
+ */
+
+void websRedirect(webs_t wp, char_t *url)
+{
+ char_t *msgbuf, *urlbuf, *redirectFmt;
+
+ a_assert(websValid(wp));
+ a_assert(url);
+
+ websStats.redirects++;
+ msgbuf = urlbuf = NULL;
+
+/*
+ * Some browsers require a http://host qualified URL for redirection
+ */
+ if (gstrstr(url, T("http://")) == NULL) {
+ if (*url == '/') {
+ url++;
+ }
+
+ redirectFmt = T("http://%s/%s");
+
+#ifdef WEBS_SSL_SUPPORT
+ if (wp->flags & WEBS_SECURE) {
+ redirectFmt = T("https://%s/%s");
+ }
+#endif
+
+ fmtAlloc(&urlbuf, WEBS_MAX_URL + 80, redirectFmt,
+ websGetVar(wp, T("HTTP_HOST"), websHostUrl), url);
+ url = urlbuf;
+ }
+
+/*
+ * Add human readable message for completeness. Should not be required.
+ */
+ fmtAlloc(&msgbuf, WEBS_MAX_URL + 80,
+ T("<html><head></head><body>\r\n\
+ This document has moved to a new <a href=\"%s\">location</a>.\r\n\
+ Please update your documents to reflect the new location.\r\n\
+ </body></html>\r\n"), url);
+
+ websResponse(wp, 302, msgbuf, url);
+
+ bfreeSafe(B_L, msgbuf);
+ bfreeSafe(B_L, urlbuf);
+}
+
+/******************************************************************************/
+/*
+ * Output an error message and cleanup
+ */
+
+#ifdef qRichErrorPage
+extern int dmfRichError(webs_t wp, int code, char_t* userMsg);
+#endif
+void websError(webs_t wp, int code, char_t *fmt, ...)
+{
+ va_list args;
+ char_t *msg, *userMsg, *buf;
+#ifdef qRichErrorPage
+ static int reEntry = 0;
+ int errorOk;
+#endif
+
+ a_assert(websValid(wp));
+ a_assert(fmt);
+
+ websStats.errors++;
+
+ va_start(args, fmt);
+ userMsg = NULL;
+ fmtValloc(&userMsg, WEBS_BUFSIZE, fmt, args);
+ va_end(args);
+
+#ifdef qRichErrorPage
+ if (!reEntry)
+ {
+ /*
+ * The dmfRichError function that we're about to call may very well call
+ * websError() as part of its work. If that happens, we do NOT want to
+ * get into a never-ending recursive call chain. When we get back here
+ * in a call from inside dmfRichError(), we check to see if we're
+ * already trying to call dmfRichError. If we are, we just revert to the
+ * old non-rich behavior and display a black on white error page.
+ */
+
+ reEntry = 1;
+ errorOk = dmfRichError(wp, code, userMsg);
+ reEntry = 0;
+ if (errorOk)
+ {
+ return;
+ }
+ /* ...else we need to fall through and execute the simple error page. */
+ }
+ /* implicit else... */
+#endif
+
+ msg = T("<html><head><title>Document Error: %s</title></head>\r\n\
+ <body><h2>Access Error: %s</h2>\r\n\
+ when trying to obtain <b>%s</b><br><p>%s</p></body></html>\r\n");
+/*
+ * Ensure we have plenty of room
+ */
+ buf = NULL;
+ fmtAlloc(&buf, WEBS_BUFSIZE, msg, websErrorMsg(code),
+ websErrorMsg(code), wp->url, userMsg);
+
+ websResponse(wp, code, buf, NULL);
+ bfreeSafe(B_L, buf);
+ bfreeSafe(B_L, userMsg);
+}
+
+/******************************************************************************/
+/*
+ * Return the error message for a given code
+ */
+
+/*static char_t *websErrorMsg(int code)*/
+char_t *websErrorMsg(int code)
+{
+ websErrorType *ep;
+
+ for (ep = websErrors; ep->code; ep++) {
+ if (code == ep->code) {
+ return ep->msg;
+ }
+ }
+ a_assert(0);
+ return T("");
+}
+
+/******************************************************************************/
+/*
+ * Do formatted output to the browser. This is the public ASP and form
+ * write procedure.
+ */
+
+int websWrite(webs_t wp, char_t *fmt, ...)
+{
+ va_list vargs;
+ char_t *buf;
+ int rc;
+
+ a_assert(websValid(wp));
+
+ va_start(vargs, fmt);
+
+ buf = NULL;
+ rc = 0;
+
+ if (fmtValloc(&buf, WEBS_BUFSIZE, fmt, vargs) >= WEBS_BUFSIZE) {
+ trace(0, T("webs: websWrite lost data, buffer overflow\n"));
+ }
+
+ va_end(vargs);
+ a_assert(buf);
+ if (buf) {
+ rc = websWriteBlock(wp, buf, gstrlen(buf));
+ bfree(B_L, buf);
+ }
+ return rc;
+}
+
+/******************************************************************************/
+/*
+ * Write a block of data of length "nChars" to the user's browser. Public
+ * write block procedure. If unicode is turned on this function expects
+ * buf to be a unicode string and it converts it to ASCII before writing.
+ * See websWriteDataNonBlock to always write binary or ASCII data with no
+ * unicode conversion. This returns the number of char_t's processed.
+ * It spins until nChars are flushed to the socket. For non-blocking
+ * behavior, use websWriteDataNonBlock.
+ */
+
+int websWriteBlock(webs_t wp, char_t *buf, int nChars)
+{
+ int len, done;
+ char *asciiBuf, *pBuf;
+
+ a_assert(wp);
+ a_assert(websValid(wp));
+ a_assert(buf);
+ a_assert(nChars >= 0);
+
+ done = len = 0;
+
+/*
+ * ballocUniToAsc will convert Unicode to strings to Ascii. If Unicode is
+ * not turned on then ballocUniToAsc will not do the conversion.
+ */
+ pBuf = asciiBuf = ballocUniToAsc(buf, nChars);
+
+ while (nChars > 0) {
+#ifdef WEBS_SSL_SUPPORT
+ if (wp->flags & WEBS_SECURE) {
+ if ((len = websSSLWrite(wp->wsp, pBuf, nChars)) < 0) {
+ bfree(B_L, asciiBuf);
+ return -1;
+ }
+ websSSLFlush(wp->wsp);
+ } else {
+ if ((len = socketWrite(wp->sid, pBuf, nChars)) < 0) {
+ bfree(B_L, asciiBuf);
+ return -1;
+ }
+ socketFlush(wp->sid);
+ }
+#else /* ! WEBS_SSL_SUPPORT */
+ if ((len = socketWrite(wp->sid, pBuf, nChars)) < 0) {
+ bfree(B_L, asciiBuf);
+ return -1;
+ }
+ socketFlush(wp->sid);
+#endif /* WEBS_SSL_SUPPORT */
+ nChars -= len;
+ pBuf += len;
+ done += len;
+ }
+
+ bfree(B_L, asciiBuf);
+ return done;
+}
+
+/******************************************************************************/
+/*
+ * Write a block of data of length "nChars" to the user's browser. Same as
+ * websWriteBlock except that it expects straight ASCII or binary and does no
+ * unicode conversion before writing the data. If the socket cannot hold all
+ * the data, it will return the number of bytes flushed to the socket before
+ * it would have blocked. This returns the number of chars processed or -1
+ * if socketWrite fails.
+ */
+
+int websWriteDataNonBlock(webs_t wp, char *buf, int nChars)
+{
+ int r;
+
+ a_assert(wp);
+ a_assert(websValid(wp));
+ a_assert(buf);
+ a_assert(nChars >= 0);
+
+#ifdef WEBS_SSL_SUPPORT
+ if (wp->flags & WEBS_SECURE) {
+ r = websSSLWrite(wp->wsp, buf, nChars);
+ websSSLFlush(wp->wsp);
+ } else {
+ r = socketWrite(wp->sid, buf, nChars);
+ socketFlush(wp->sid);
+ }
+#else
+ r = socketWrite(wp->sid, buf, nChars);
+ socketFlush(wp->sid);
+#endif
+
+ return r;
+}
+
+/******************************************************************************/
+/*
+ * Decode a URL (or part thereof). Allows insitu decoding.
+ */
+
+void websDecodeUrl(char_t *decoded, char_t *token, int len)
+{
+ char_t *ip, *op;
+ int num, i, c;
+
+ a_assert(decoded);
+ a_assert(token);
+
+ op = decoded;
+ for (ip = token; *ip && len > 0; ip++, op++) {
+ if (*ip == '+') {
+ *op = ' ';
+ } else if (*ip == '%' && gisxdigit(ip[1]) && gisxdigit(ip[2])) {
+
+/*
+ * Convert %nn to a single character
+ */
+ ip++;
+ for (i = 0, num = 0; i < 2; i++, ip++) {
+ c = tolower(*ip);
+ if (c >= 'a' && c <= 'f') {
+ num = (num * 16) + 10 + c - 'a';
+ } else {
+ num = (num * 16) + c - '0';
+ }
+ }
+ *op = (char_t) num;
+ ip--;
+
+ } else {
+ *op = *ip;
+ }
+ len--;
+ }
+ *op = '\0';
+}
+
+/******************************************************************************/
+#ifdef WEBS_LOG_SUPPORT
+/*
+ * Output a log message
+ */
+
+static void websLog(webs_t wp, int code)
+{
+ char_t *buf;
+ char *abuf;
+ int len;
+#define qAnlLog 1
+#ifdef qAnlLog
+ time_t timer;
+ char_t* newLine = NULL;
+ char_t* timeStr = NULL;
+#endif
+ a_assert(websValid(wp));
+
+ buf = NULL;
+
+#ifdef qAnlLog
+ time(&timer);
+ timeStr = ctime(&timer);
+ newLine = gstrchr(timeStr, '\n');
+ if (newLine)
+ {
+ *newLine = '\0';
+ }
+ fmtAlloc(&buf, WEBS_MAX_URL + 80, T("%s\t%s\t%s\tcode = %d\n"),
+ timeStr, wp->ipaddr, wp->url, code);
+#else
+ fmtAlloc(&buf, WEBS_MAX_URL + 80, T("%d %s %d %d\n"), time(0),
+ wp->url, code, wp->written);
+#endif
+ len = gstrlen(buf);
+ abuf = ballocUniToAsc(buf, len+1);
+ write(websLogFd, abuf, len);
+ bfreeSafe(B_L, buf);
+ bfreeSafe(B_L, abuf);
+}
+
+#endif /* WEBS_LOG_SUPPORT */
+
+/******************************************************************************/
+/*
+ * Request timeout. The timeout triggers if we have not read any data from
+ * the users browser in the last WEBS_TIMEOUT period. If we have heard from
+ * the browser, simply re-issue the timeout.
+ */
+
+void websTimeout(void *arg, int id)
+{
+ webs_t wp;
+ int delay, tm;
+
+ wp = (webs_t) arg;
+ a_assert(websValid(wp));
+
+ tm = websGetTimeSinceMark(wp) * 1000;
+ if (tm >= WEBS_TIMEOUT) {
+ websStats.timeouts++;
+ emfUnschedCallback(id);
+
+/*
+ * Clear the timeout id
+ */
+ wp->timeout = -1;
+ websDone(wp, 404);
+ } else {
+ delay = WEBS_TIMEOUT - tm;
+ a_assert(delay > 0);
+ emfReschedCallback(id, delay);
+ }
+}
+
+/******************************************************************************/
+/*
+ * Called when the request is done.
+ */
+
+void websDone(webs_t wp, int code)
+{
+ a_assert(websValid(wp));
+
+/*
+ * Disable socket handler in case keep alive set.
+ */
+ socketDeleteHandler(wp->sid);
+
+ if (code != 200) {
+ wp->flags &= ~WEBS_KEEP_ALIVE;
+ }
+
+#ifdef WEBS_PROXY_SUPPORT
+ if (! (wp->flags & WEBS_LOCAL_PAGE)) {
+ websStats.activeNetRequests--;
+ }
+#endif
+
+#ifdef WEBS_LOG_SUPPORT
+ if (! (wp->flags & WEBS_REQUEST_DONE)) {
+ websLog(wp, code);
+ }
+#endif
+
+/*
+ * Close any opened document by a handler
+ */
+ websPageClose(wp);
+
+/*
+ * Exit if secure.
+ */
+#ifdef WEBS_SSL_SUPPORT
+ if (wp->flags & WEBS_SECURE) {
+ websTimeoutCancel(wp);
+ websSSLFlush(wp->wsp);
+ socketCloseConnection(wp->sid);
+ websFree(wp);
+ return;
+ }
+#endif
+
+/*
+ * If using Keep Alive (HTTP/1.1) we keep the socket open for a period
+ * while waiting for another request on the socket.
+ */
+ if (wp->flags & WEBS_KEEP_ALIVE) {
+ if (socketFlush(wp->sid) == 0) {
+ wp->state = WEBS_BEGIN;
+ wp->flags |= WEBS_REQUEST_DONE;
+ if (wp->header.buf) {
+ ringqFlush(&wp->header);
+ }
+ socketCreateHandler(wp->sid, SOCKET_READABLE, websSocketEvent,
+ (int) wp);
+ websTimeoutCancel(wp);
+ wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout,
+ (void *) wp);
+ return;
+ }
+ } else {
+ websTimeoutCancel(wp);
+ socketSetBlock(wp->sid, 1);
+ socketFlush(wp->sid);
+ socketCloseConnection(wp->sid);
+ }
+ websFree(wp);
+}
+
+/******************************************************************************/
+/*
+ * Allocate a new webs structure
+ */
+
+int websAlloc(int sid)
+{
+ webs_t wp;
+ int wid;
+
+/*
+ * Allocate a new handle for this connection
+ */
+ if ((wid = hAllocEntry((void*) &webs, &websMax,
+ sizeof(struct websRec))) < 0) {
+ return -1;
+ }
+ wp = webs[wid];
+
+ wp->wid = wid;
+ wp->sid = sid;
+ wp->state = WEBS_BEGIN;
+ wp->docfd = -1;
+ wp->timeout = -1;
+ wp->dir = NULL;
+ wp->authType = NULL;
+ wp->protocol = NULL;
+ wp->protoVersion = NULL;
+ wp->password = NULL;
+ wp->userName = NULL;
+#ifdef DIGEST_ACCESS_SUPPORT
+ wp->realm = NULL;
+ wp->nonce = NULL;
+ wp->digest = NULL;
+ wp->uri = NULL;
+ wp->opaque = NULL;
+ wp->nc = NULL;
+ wp->cnonce = NULL;
+ wp->qop = NULL;
+#endif
+#ifdef WEBS_SSL_SUPPORT
+ wp->wsp = NULL;
+#endif
+
+ ringqOpen(&wp->header, WEBS_HEADER_BUFINC, WEBS_MAX_HEADER);
+
+/*
+ * Create storage for the CGI variables. We supply the symbol tables for
+ * both the CGI variables and for the global functions. The function table
+ * is common to all webs instances (ie. all browsers)
+ */
+ wp->cgiVars = symOpen(WEBS_SYM_INIT);
+
+ return wid;
+}
+
+/******************************************************************************/
+/*
+ * Free a webs structure
+ */
+
+void websFree(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ if (wp->path)
+ bfree(B_L, wp->path);
+ if (wp->url)
+ bfree(B_L, wp->url);
+ if (wp->host)
+ bfree(B_L, wp->host);
+ if (wp->lpath)
+ bfree(B_L, wp->lpath);
+ if (wp->query)
+ bfree(B_L, wp->query);
+ if (wp->decodedQuery)
+ bfree(B_L, wp->decodedQuery);
+ if (wp->authType)
+ bfree(B_L, wp->authType);
+ if (wp->password)
+ bfree(B_L, wp->password);
+ if (wp->userName)
+ bfree(B_L, wp->userName);
+ if (wp->cookie)
+ bfree(B_L, wp->cookie);
+ if (wp->userAgent)
+ bfree(B_L, wp->userAgent);
+ if (wp->dir)
+ bfree(B_L, wp->dir);
+ if (wp->protocol)
+ bfree(B_L, wp->protocol);
+ if (wp->protoVersion)
+ bfree(B_L, wp->protoVersion);
+ if (wp->cgiStdin)
+ bfree(B_L, wp->cgiStdin);
+
+
+#ifdef DIGEST_ACCESS_SUPPORT
+ if (wp->realm)
+ bfree(B_L, wp->realm);
+ if (wp->uri)
+ bfree(B_L, wp->uri);
+ if (wp->digest)
+ bfree(B_L, wp->digest);
+ if (wp->opaque)
+ bfree(B_L, wp->opaque);
+ if (wp->nonce)
+ bfree(B_L, wp->nonce);
+ if (wp->nc)
+ bfree(B_L, wp->nc);
+ if (wp->cnonce)
+ bfree(B_L, wp->cnonce);
+ if (wp->qop)
+ bfree(B_L, wp->qop);
+#endif
+#ifdef WEBS_SSL_SUPPORT
+ websSSLFree(wp->wsp);
+#endif
+ symClose(wp->cgiVars);
+
+ if (wp->header.buf) {
+ ringqClose(&wp->header);
+ }
+
+ websMax = hFree((void*) &webs, wp->wid);
+ bfree(B_L, wp);
+ a_assert(websMax >= 0);
+}
+
+/******************************************************************************/
+/*
+ * Return the server address
+ */
+
+char_t *websGetHost()
+{
+ return websHost;
+}
+
+/******************************************************************************/
+/*
+ * Return the the url to access the server. (ip address)
+ */
+
+char_t *websGetIpaddrUrl()
+{
+ return websIpaddrUrl;
+}
+
+/******************************************************************************/
+/*
+ * Return the server address
+ */
+
+char_t *websGetHostUrl()
+{
+ return websHostUrl;
+}
+
+/******************************************************************************/
+/*
+ * Return the listen port
+ */
+
+int websGetPort()
+{
+ return websPort;
+}
+
+/******************************************************************************/
+/*
+ * Get the number of bytes to write
+ */
+
+int websGetRequestBytes(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ return wp->numbytes;
+}
+
+/******************************************************************************/
+/*
+ * Get the directory for this request
+ */
+
+char_t *websGetRequestDir(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ if (wp->dir == NULL) {
+ return T("");
+ }
+
+ return wp->dir;
+}
+
+/******************************************************************************/
+/*
+ * Get the flags for this request
+ */
+
+int websGetRequestFlags(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ return wp->flags;
+}
+
+/******************************************************************************/
+/*
+ * Return the IP address
+ */
+
+char_t *websGetRequestIpaddr(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ return wp->ipaddr;
+}
+
+/******************************************************************************/
+/*
+ * Set the local path for the request
+ */
+
+char_t *websGetRequestLpath(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+#ifdef WEBS_PAGE_ROM
+ return wp->path;
+#else
+ return wp->lpath;
+#endif
+}
+
+/******************************************************************************/
+/*
+ * Get the path for this request
+ */
+
+char_t *websGetRequestPath(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ if (wp->path == NULL) {
+ return T("");
+ }
+
+ return wp->path;
+}
+
+/******************************************************************************/
+/*
+ * Return the password
+ */
+
+char_t *websGetRequestPassword(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ return wp->password;
+}
+
+/******************************************************************************/
+/*
+ * Return the request type
+ */
+
+char_t *websGetRequestType(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ return wp->type;
+}
+
+/******************************************************************************/
+/*
+ * Return the username
+ */
+
+char_t *websGetRequestUserName(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ return wp->userName;
+}
+
+/******************************************************************************/
+/*
+ * Get the number of bytes written
+ */
+
+int websGetRequestWritten(webs_t wp)
+{
+ a_assert(websValid(wp));
+
+ return wp->written;
+}
+
+/******************************************************************************/
+/*
+ * Set the hostname
+ */
+
+void websSetHost(char_t *host)
+{
+ gstrncpy(websHost, host, TSZ(websHost));
+}
+
+/******************************************************************************/
+/*
+ * Set the host URL
+ */
+
+void websSetHostUrl(char_t *url)
+{
+ a_assert(url && *url);
+
+ bfreeSafe(B_L, websHostUrl);
+ websHostUrl = gstrdup(B_L, url);
+}
+
+/******************************************************************************/
+/*
+ * Set the IP address
+ */
+
+void websSetIpaddr(char_t *ipaddr)
+{
+ a_assert(ipaddr && *ipaddr);
+
+ gstrncpy(websIpaddr, ipaddr, TSZ(websIpaddr));
+}
+
+/******************************************************************************/
+/*
+ * Set the number of bytes to write
+ */
+
+void websSetRequestBytes(webs_t wp, int bytes)
+{
+ a_assert(websValid(wp));
+ a_assert(bytes >= 0);
+
+ wp->numbytes = bytes;
+}
+
+/******************************************************************************/
+/*
+ * Set the flags for this request
+ */
+
+void websSetRequestFlags(webs_t wp, int flags)
+{
+ a_assert(websValid(wp));
+
+ wp->flags = flags;
+}
+
+/******************************************************************************/
+/*
+ * Set the local path for the request
+ */
+
+void websSetRequestLpath(webs_t wp, char_t *lpath)
+{
+ a_assert(websValid(wp));
+ a_assert(lpath && *lpath);
+
+ if (wp->lpath) {
+ bfree(B_L, wp->lpath);
+ }
+ wp->lpath = bstrdup(B_L, lpath);
+ websSetVar(wp, T("PATH_TRANSLATED"), wp->lpath);
+}
+
+/******************************************************************************/
+/*
+ * Update the URL path and the directory containing the web page
+ */
+
+void websSetRequestPath(webs_t wp, char_t *dir, char_t *path)
+{
+ char_t *tmp;
+
+ a_assert(websValid(wp));
+
+ if (dir) {
+ tmp = wp->dir;
+ wp->dir = bstrdup(B_L, dir);
+ if (tmp) {
+ bfree(B_L, tmp);
+ }
+ }
+ if (path) {
+ tmp = wp->path;
+ wp->path = bstrdup(B_L, path);
+ websSetVar(wp, T("PATH_INFO"), wp->path);
+ if (tmp) {
+ bfree(B_L, tmp);
+ }
+ }
+}
+
+/******************************************************************************/
+/*
+ * Set the Write handler for this socket
+ */
+
+void websSetRequestSocketHandler(webs_t wp, int mask, void (*fn)(webs_t wp))
+{
+ a_assert(websValid(wp));
+
+ wp->writeSocket = fn;
+ socketCreateHandler(wp->sid, SOCKET_WRITABLE, websSocketEvent, (int) wp);
+}
+
+/******************************************************************************/
+/*
+ * Set the number of bytes written
+ */
+
+void websSetRequestWritten(webs_t wp, int written)
+{
+ a_assert(websValid(wp));
+
+ wp->written = written;
+}
+
+/******************************************************************************/
+/*
+ * Reurn true if the webs handle is valid
+ */
+
+int websValid(webs_t wp)
+{
+ int wid;
+
+ for (wid = 0; wid < websMax; wid++) {
+ if (wp == webs[wid]) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Build an ASCII time string. If sbuf is NULL we use the current time,
+ * else we use the last modified time of sbuf;
+ */
+
+char_t *websGetDateString(websStatType *sbuf)
+{
+ char_t* cp, *r;
+ time_t now;
+
+ if (sbuf == NULL) {
+ time(&now);
+ } else {
+ now = sbuf->mtime;
+ }
+ if ((cp = gctime(&now)) != NULL) {
+ cp[gstrlen(cp) - 1] = '\0';
+ r = bstrdup(B_L, cp);
+ return r;
+ }
+ return NULL;
+}
+
+/******************************************************************************/
+/*
+ * Mark time. Set a timestamp so that, later, we can return the number of
+ * seconds since we made the mark. Note that the mark my not be a
+ * "real" time, but rather a relative marker.
+ */
+
+void websSetTimeMark(webs_t wp)
+{
+ wp->timestamp = time(0);
+}
+
+/******************************************************************************/
+/*
+ * Get the number of seconds since the last mark.
+ */
+
+static int websGetTimeSinceMark(webs_t wp)
+{
+ return time(0) - wp->timestamp;
+}
+
+/******************************************************************************/
+/*
+ * Store the new realm name
+ */
+
+void websSetRealm(char_t *realmName)
+{
+ a_assert(realmName);
+
+ gstrncpy(websRealm, realmName, TSZ(websRealm));
+}
+
+/******************************************************************************/
+/*
+ * Return the realm name (used for authorization)
+ */
+
+char_t *websGetRealm()
+{
+ return websRealm;
+}
+
+
+#ifdef WEBS_IF_MODIFIED_SUPPORT
+/******************************************************************************/
+/*
+ * These functions are intended to closely mirror the syntax for HTTP-date
+ * from RFC 2616 (HTTP/1.1 spec). This code was submitted by Pete Bergstrom.
+ */
+
+/*
+ * RFC1123Date = wkday "," SP date1 SP time SP "GMT"
+ * RFC850Date = weekday "," SP date2 SP time SP "GMT"
+ * ASCTimeDate = wkday SP date3 SP time SP 4DIGIT
+ *
+ * Each of these functions tries to parse the value and update the index to
+ * the point it leaves off parsing.
+ */
+
+typedef enum { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } MonthEnumeration;
+typedef enum { SUN, MON, TUE, WED, THU, FRI, SAT } WeekdayEnumeration;
+
+/******************************************************************************/
+/*
+ * Parse an N-digit value
+ */
+
+static int parseNDIGIT(char_t *buf, int digits, int *index)
+{
+ int tmpIndex, returnValue;
+
+ returnValue = 0;
+
+ for (tmpIndex = *index; tmpIndex < *index+digits; tmpIndex++) {
+ if (gisdigit(buf[tmpIndex])) {
+ returnValue = returnValue * 10 + (buf[tmpIndex] - T('0'));
+ }
+ }
+ *index = tmpIndex;
+
+ return returnValue;
+}
+
+/******************************************************************************/
+/*
+ * Return an index into the month array
+ */
+
+static int parseMonth(char_t *buf, int *index)
+{
+/*
+ * "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" |
+ * "Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec"
+ */
+ int tmpIndex, returnValue;
+
+ returnValue = -1;
+ tmpIndex = *index;
+
+ switch (buf[tmpIndex]) {
+ case 'A':
+ switch (buf[tmpIndex+1]) {
+ case 'p':
+ returnValue = APR;
+ break;
+ case 'u':
+ returnValue = AUG;
+ break;
+ }
+ break;
+ case 'D':
+ returnValue = DEC;
+ break;
+ case 'F':
+ returnValue = FEB;
+ break;
+ case 'J':
+ switch (buf[tmpIndex+1]) {
+ case 'a':
+ returnValue = JAN;
+ break;
+ case 'u':
+ switch (buf[tmpIndex+2]) {
+ case 'l':
+ returnValue = JUL;
+ break;
+ case 'n':
+ returnValue = JUN;
+ break;
+ }
+ break;
+ }
+ break;
+ case 'M':
+ switch (buf[tmpIndex+1]) {
+ case 'a':
+ switch (buf[tmpIndex+2]) {
+ case 'r':
+ returnValue = MAR;
+ break;
+ case 'y':
+ returnValue = MAY;
+ break;
+ }
+ break;
+ }
+ break;
+ case 'N':
+ returnValue = NOV;
+ break;
+ case 'O':
+ returnValue = OCT;
+ break;
+ case 'S':
+ returnValue = SEP;
+ break;
+ }
+
+ if (returnValue >= 0) {
+ *index += 3;
+ }
+
+ return returnValue;
+}
+
+/******************************************************************************/
+/*
+ * Parse a year value (either 2 or 4 digits)
+ */
+
+static int parseYear(char_t *buf, int *index)
+{
+ int tmpIndex, returnValue;
+
+ tmpIndex = *index;
+ returnValue = parseNDIGIT(buf, 4, &tmpIndex);
+
+ if (returnValue >= 0) {
+ *index = tmpIndex;
+ } else {
+ returnValue = parseNDIGIT(buf, 2, &tmpIndex);
+ if (returnValue >= 0) {
+/*
+ * Assume that any year earlier than the start of the
+ * epoch for time_t (1970) specifies 20xx
+ */
+ if (returnValue < 70) {
+ returnValue += 2000;
+ } else {
+ returnValue += 1900;
+ }
+
+ *index = tmpIndex;
+ }
+ }
+
+ return returnValue;
+}
+
+/******************************************************************************/
+/*
+ * The formulas used to build these functions are from "Calendrical Calculations",
+ * by Nachum Dershowitz, Edward M. Reingold, Cambridge University Press, 1997.
+ */
+
+#include <math.h>
+
+const int GregorianEpoch = 1;
+
+/******************************************************************************/
+/*
+ * Determine if year is a leap year
+ */
+
+int GregorianLeapYearP(long year)
+{
+ int result;
+ long tmp;
+
+ tmp = year % 400;
+
+ if ((year % 4 == 0) &&
+ (tmp != 100) &&
+ (tmp != 200) &&
+ (tmp != 300)) {
+ result = TRUE;
+ } else {
+ result = FALSE;
+ }
+
+ return result;
+}
+
+/******************************************************************************/
+/*
+ * Return the fixed date from the gregorian date
+ */
+
+long FixedFromGregorian(long month, long day, long year)
+{
+ long fixedDate;
+
+ fixedDate = (long)(GregorianEpoch - 1 + 365 * (year - 1) +
+ floor((year - 1) / 4.0) -
+ floor((double)(year - 1) / 100.0) +
+ floor((double)(year - 1) / 400.0) +
+ floor((367.0 * ((double)month) - 362.0) / 12.0));
+
+ if (month <= 2) {
+ fixedDate += 0;
+ } else if (TRUE == GregorianLeapYearP(year)) {
+ fixedDate += -1;
+ } else {
+ fixedDate += -2;
+ }
+
+ fixedDate += day;
+
+ return fixedDate;
+}
+
+/******************************************************************************/
+/*
+ * Return the gregorian year from a fixed date
+ */
+
+long GregorianYearFromFixed(long fixedDate)
+{
+ long result, d0, n400, d1, n100, d2, n4, d3, n1, d4, year;
+
+ d0 = fixedDate - GregorianEpoch;
+ n400 = (long)(floor((double)d0 / (double)146097));
+ d1 = d0 % 146097;
+ n100 = (long)(floor((double)d1 / (double)36524));
+ d2 = d1 % 36524;
+ n4 = (long)(floor((double)d2 / (double)1461));
+ d3 = d2 % 1461;
+ n1 = (long)(floor((double)d3 / (double)365));
+ d4 = (d3 % 365) + 1;
+ year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
+
+ if ((n100 == 4) || (n1 == 4)) {
+ result = year;
+ } else {
+ result = year + 1;
+ }
+
+ return result;
+}
+
+/******************************************************************************/
+/*
+ * Returns the Gregorian date from a fixed date
+ * (not needed for this use, but included for completeness
+ */
+
+#if 0
+GregorianFromFixed(long fixedDate, long *month, long *day, long *year)
+{
+ long priorDays, correction;
+
+ *year = GregorianYearFromFixed(fixedDate);
+ priorDays = fixedDate - FixedFromGregorian(1, 1, *year);
+
+ if (fixedDate < FixedFromGregorian(3,1,*year)) {
+ correction = 0;
+ } else if (true == GregorianLeapYearP(*year)) {
+ correction = 1;
+ } else {
+ correction = 2;
+ }
+
+ *month = (long)(floor((12.0 * (double)(priorDays + correction) + 373.0) / 367.0));
+ *day = fixedDate - FixedFromGregorian(*month, 1, *year);
+}
+#endif
+
+/******************************************************************************/
+/*
+ * Returns the difference between two Gregorian dates
+ */
+
+long GregorianDateDifference( long month1, long day1, long year1,
+ long month2, long day2, long year2)
+{
+ return FixedFromGregorian(month2, day2, year2) -
+ FixedFromGregorian(month1, day1, year1);
+}
+
+
+/******************************************************************************/
+/*
+ * Return the number of seconds into the current day
+ */
+
+#define SECONDS_PER_DAY 24*60*60
+
+static int parseTime(char_t *buf, int *index)
+{
+/*
+ * Format of buf is - 2DIGIT ":" 2DIGIT ":" 2DIGIT
+ */
+ int returnValue, tmpIndex, hourValue, minuteValue, secondValue;
+
+ hourValue = minuteValue = secondValue = -1;
+ returnValue = -1;
+ tmpIndex = *index;
+
+ hourValue = parseNDIGIT(buf, 2, &tmpIndex);
+
+ if (hourValue >= 0) {
+ tmpIndex++;
+ minuteValue = parseNDIGIT(buf, 2, &tmpIndex);
+ if (minuteValue >= 0) {
+ tmpIndex++;
+ secondValue = parseNDIGIT(buf, 2, &tmpIndex);
+ }
+ }
+
+ if ((hourValue >= 0) &&
+ (minuteValue >= 0) &&
+ (secondValue >= 0)) {
+ returnValue = (((hourValue * 60) + minuteValue) * 60) + secondValue;
+ *index = tmpIndex;
+ }
+
+ return returnValue;
+}
+
+/******************************************************************************/
+/*
+ * Return the equivalent of time() given a gregorian date
+ */
+
+static time_t dateToTimet(int year, int month, int day)
+{
+ long dayDifference;
+
+ /*
+ * Bug fix by Jeff Reeder (Jun 14, 2002): The 'month' parameter is
+ * numbered from 0 (Jan == 0), but FixedFromGregorian() takes
+ * months numbered from 1 (January == 1). We need to add 1
+ * to the month
+ */
+ dayDifference = FixedFromGregorian(month + 1, day, year) -
+ FixedFromGregorian(1, 1, 1970);
+
+ return dayDifference * SECONDS_PER_DAY;
+}
+
+/******************************************************************************/
+/*
+ * Return the number of seconds between Jan 1, 1970 and the parsed date
+ * (corresponds to documentation for time() function)
+ */
+
+static time_t parseDate1or2(char_t *buf, int *index)
+{
+/*
+ * Format of buf is either
+ * 2DIGIT SP month SP 4DIGIT
+ * or
+ * 2DIGIT "-" month "-" 2DIGIT
+ */
+ int dayValue, monthValue, yearValue, tmpIndex;
+ time_t returnValue;
+
+ returnValue = (time_t) -1;
+ tmpIndex = *index;
+
+ dayValue = monthValue = yearValue = -1;
+
+ if (buf[tmpIndex] == T(',')) {
+/*
+ * Skip over the ", "
+ */
+ tmpIndex += 2;
+
+ dayValue = parseNDIGIT(buf, 2, &tmpIndex);
+ if (dayValue >= 0) {
+/*
+ * Skip over the space or hyphen
+ */
+ tmpIndex++;
+ monthValue = parseMonth(buf, &tmpIndex);
+ if (monthValue >= 0) {
+/*
+ * Skip over the space or hyphen
+ */
+ tmpIndex++;
+ yearValue = parseYear(buf, &tmpIndex);
+ }
+ }
+
+ if ((dayValue >= 0) &&
+ (monthValue >= 0) &&
+ (yearValue >= 0)) {
+ if (yearValue < 1970) {
+/*
+ * Allow for Microsoft IE's year 1601 dates
+ */
+ returnValue = 0;
+ } else {
+ returnValue = dateToTimet(yearValue, monthValue, dayValue);
+ }
+ *index = tmpIndex;
+ }
+ }
+
+ return returnValue;
+}
+
+/******************************************************************************/
+/*
+ * Return the number of seconds between Jan 1, 1970 and the parsed date
+ */
+
+static time_t parseDate3Time(char_t *buf, int *index)
+{
+/*
+ * Format of buf is month SP ( 2DIGIT | ( SP 1DIGIT ))
+ */
+ int dayValue, monthValue, yearValue, timeValue, tmpIndex;
+ time_t returnValue;
+
+ returnValue = (time_t) -1;
+ tmpIndex = *index;
+
+ dayValue = monthValue = yearValue = timeValue = -1;
+
+ monthValue = parseMonth(buf, &tmpIndex);
+ if (monthValue >= 0) {
+/*
+ * Skip over the space
+ */
+ tmpIndex++;
+ if (buf[tmpIndex] == T(' ')) {
+/*
+ * Skip over this space too
+ */
+ tmpIndex++;
+ dayValue = parseNDIGIT(buf, 1, &tmpIndex);
+ } else {
+ dayValue = parseNDIGIT(buf, 2, &tmpIndex);
+ }
+/*
+ * Now get the time and time SP 4DIGIT
+ */
+ timeValue = parseTime(buf, &tmpIndex);
+ if (timeValue >= 0) {
+/*
+ * Now grab the 4DIGIT year value
+ */
+ yearValue = parseYear(buf, &tmpIndex);
+ }
+ }
+
+ if ((dayValue >= 0) &&
+ (monthValue >= 0) &&
+ (yearValue >= 0)) {
+ returnValue = dateToTimet(yearValue, monthValue, dayValue);
+ returnValue += timeValue;
+ *index = tmpIndex;
+ }
+
+ return returnValue;
+}
+
+
+/******************************************************************************/
+/*
+ * Although this looks like a trivial function, I found I was replicating the implementation
+ * seven times in the parseWeekday function. In the interests of minimizing code size
+ * and redundancy, it is broken out into a separate function. The cost of an extra
+ * function call I can live with given that it should only be called once per HTTP request.
+ */
+
+static int bufferIndexIncrementGivenNTest(char_t *buf, int testIndex, char_t testChar,
+ int foundIncrement, int notfoundIncrement)
+{
+ if (buf[testIndex] == testChar) {
+ return foundIncrement;
+ }
+
+ return notfoundIncrement;
+}
+
+/******************************************************************************/
+/*
+ * Return an index into a logical weekday array
+ */
+
+static int parseWeekday(char_t *buf, int *index)
+{
+/*
+ * Format of buf is either
+ * "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun"
+ * or
+ * "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday" | "Sunday"
+ */
+ int tmpIndex, returnValue;
+
+ returnValue = -1;
+ tmpIndex = *index;
+
+ switch (buf[tmpIndex]) {
+ case 'F':
+ returnValue = FRI;
+ *index += bufferIndexIncrementGivenNTest(buf, tmpIndex+3, 'd', sizeof("Friday"), 3);
+ break;
+ case 'M':
+ returnValue = MON;
+ *index += bufferIndexIncrementGivenNTest(buf, tmpIndex+3, 'd', sizeof("Monday"), 3);
+ break;
+ case 'S':
+ switch (buf[tmpIndex+1]) {
+ case 'a':
+ returnValue = SAT;
+ *index += bufferIndexIncrementGivenNTest(buf, tmpIndex+3, 'u', sizeof("Saturday"), 3);
+ break;
+ case 'u':
+ returnValue = SUN;
+ *index += bufferIndexIncrementGivenNTest(buf, tmpIndex+3, 'd', sizeof("Sunday"), 3);
+ break;
+ }
+ break;
+ case 'T':
+ switch (buf[tmpIndex+1]) {
+ case 'h':
+ returnValue = THU;
+ *index += bufferIndexIncrementGivenNTest(buf, tmpIndex+3, 'r', sizeof("Thursday"), 3);
+ break;
+ case 'u':
+ returnValue = TUE;
+ *index += bufferIndexIncrementGivenNTest(buf, tmpIndex+3, 's', sizeof("Tuesday"), 3);
+ break;
+ }
+ break;
+ case 'W':
+ returnValue = WED;
+ *index += bufferIndexIncrementGivenNTest(buf, tmpIndex+3, 'n', sizeof("Wednesday"), 3);
+ break;
+ }
+ return returnValue;
+}
+
+/******************************************************************************/
+/*
+ * Parse the date and time string.
+ */
+
+static time_t dateParse(time_t tip, char_t *cmd)
+{
+ int index, tmpIndex, weekday, timeValue;
+ time_t parsedValue, dateValue;
+
+ parsedValue = (time_t) 0;
+ index = timeValue = 0;
+ weekday = parseWeekday(cmd, &index);
+
+ if (weekday >= 0) {
+ tmpIndex = index;
+ dateValue = parseDate1or2(cmd, &tmpIndex);
+ if (dateValue >= 0) {
+ index = tmpIndex + 1;
+/*
+ * One of these two forms is being used
+ * wkday "," SP date1 SP time SP "GMT"
+ * weekday "," SP date2 SP time SP "GMT"
+ */
+ timeValue = parseTime(cmd, &index);
+ if (timeValue >= 0) {
+/*
+ * Now match up that "GMT" string for completeness
+ * Compute the final value if there were no problems in the parse
+ */
+ if ((weekday >= 0) &&
+ (dateValue >= 0) &&
+ (timeValue >= 0)) {
+ parsedValue = dateValue + timeValue;
+ }
+ }
+ } else {
+/*
+ * Try the other form - wkday SP date3 SP time SP 4DIGIT
+ */
+ tmpIndex = index;
+ parsedValue = parseDate3Time(cmd, &tmpIndex);
+ }
+ }
+
+ return parsedValue;
+}
+
+#endif /* WEBS_IF_MODIFIED_SUPPORT */
+
+/******************************************************************************/
diff --git a/cpukit/httpd/webs.h b/cpukit/httpd/webs.h
new file mode 100644
index 0000000000..9bc61ddf5e
--- /dev/null
+++ b/cpukit/httpd/webs.h
@@ -0,0 +1,233 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+#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.3")
+
+#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, ...);
+/* function websErrorMsg() made extern 03 Jun 02 BgP */
+extern char_t *websErrorMsg(int code);
+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 websSetTimeMark(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)
+ */
+#ifdef EMF
+extern void websFormExplain(webs_t wp, char_t *path, char_t *query);
+#endif
+
+#endif /* _h_WEBS */
+
+/******************************************************************************/
diff --git a/cpukit/httpd/websSSL.c b/cpukit/httpd/websSSL.c
new file mode 100644
index 0000000000..6c2e4ce5da
--- /dev/null
+++ b/cpukit/httpd/websSSL.c
@@ -0,0 +1,706 @@
+/*
+ * websSSL.c -- SSL envrionment creation
+ *
+ * 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 implements a patch into SSL implementations for the webs
+ * module.
+ */
+
+/********************************* Includes ***********************************/
+
+#include "wsIntrn.h"
+#include "webs.h"
+#include "websSSL.h"
+
+/******************************* Definitions **********************************/
+
+#define DEFAULT_CERT_FILE "./server.pem"
+#define DEFAULT_KEY_FILE "./certs/cakey.pem"
+#define DEFAULT_CA_FILE "./certs/cacert.pem"
+#define DEFAULT_CA_PATH "./certs/"
+#define SSL_PORT 443
+
+/*
+ * Define the components of the apps_startup() macro
+ */
+
+#ifdef SIGPIPE
+#define do_pipe_sig() signal(SIGPIPE,SIG_IGN)
+#else
+#define do_pipe_sig()
+#endif
+
+#ifdef OPENSSL
+#define SSLC_add_all_algorithms() SSLeay_add_all_algorithms()
+#else
+extern void SSLC_add_all_algorithms(void);
+#endif
+
+/*
+ * Define the apps_startup() macro
+ */
+
+# if defined(MSDOS) || defined(WIN16) || defined(WIN32)
+# ifdef _O_BINARY
+# define apps_startup() \
+ _fmode=_O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \
+ SSLC_add_all_algorithms()
+# else
+# define apps_startup() \
+ _fmode=O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \
+ SSLC_add_all_algorithms()
+# endif
+# else
+# define apps_startup() do_pipe_sig(); SSLC_add_all_algorithms();
+# endif
+
+/*************************** Forward Declarations *****************************/
+
+static int websSSLSetCertStuff(SSL_CTX *ctx,
+ char *cert_file,
+ char *key_file);
+static int websSSLVerifyCallback(int ok, X509_STORE_CTX *ctx);
+static RSA *websSSLTempRSACallback(SSL *s, int is_export, int keylength);
+
+static int websSSLReadEvent (webs_t wp);
+static int websSSLAccept(int sid, char *ipaddr, int port, int listenSid);
+static void websSSLSocketEvent(int sid, int mask, int data);
+
+/*********************************** Locals ***********************************/
+
+static int sslListenSock = -1; /* Listen socket */
+static SSL_CTX *sslctx = NULL;
+
+/******************************************************************************/
+/*
+ * Start up the SSL Context for the application, and start a listen on the
+ * SSL port (usually 443, and defined by SSL_PORT)
+ * Return 0 on success, -1 on failure.
+ */
+
+int websSSLOpen()
+{
+ char *certFile, *keyFile, *CApath, *CAfile;
+ SSL_METHOD *meth;
+
+/*
+ * Install and initialize the SSL library
+ */
+ apps_startup();
+ trace(7, T("SSL: Initializing SSL\n"));
+
+#ifdef SSLC
+ SSL_library_init();
+#endif
+
+ SSL_load_error_strings();
+
+#ifdef OPENSSL
+ SSLeay_add_ssl_algorithms();
+#endif
+
+/*
+ * Important! Enable both SSL versions 2 and 3
+ */
+ meth = SSLv23_server_method();
+ sslctx = SSL_CTX_new(meth);
+
+ a_assert(sslctx);
+
+ if (sslctx == NULL) {
+ trace(2, T("SSL: Unable to create SSL context!\n"));
+ return -1;
+ }
+
+/*
+ * Adjust some SSL Context variables
+ */
+ SSL_CTX_set_quiet_shutdown(sslctx, 1);
+ SSL_CTX_set_options(sslctx, 0);
+ SSL_CTX_sess_set_cache_size(sslctx, 128);
+
+/*
+ * Set the certificate verification locations
+ */
+ CApath = DEFAULT_CA_PATH;
+ CAfile = DEFAULT_CA_FILE;
+ if ((!SSL_CTX_load_verify_locations(sslctx, CAfile, CApath)) ||
+ (!SSL_CTX_set_default_verify_paths(sslctx))) {
+ trace(2, T("SSL: Unable to set cert verification locations!\n"));
+ websSSLClose();
+ return -1;
+ }
+
+/*
+ * Set the certificate and key files for the SSL context
+ */
+ certFile = DEFAULT_CERT_FILE;
+ keyFile = NULL;
+ if (websSSLSetCertStuff(sslctx, certFile, keyFile) != 0) {
+ websSSLClose();
+ return -1;
+ }
+
+/*
+ * Set the RSA callback for the SSL context
+ */
+ SSL_CTX_set_tmp_rsa_callback(sslctx, websSSLTempRSACallback);
+
+/*
+ * Set the verification callback for the SSL context
+ */
+ SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, websSSLVerifyCallback);
+
+/*
+ * Set the certificate authority list for the client
+ */
+ SSL_CTX_set_client_CA_list(sslctx, SSL_load_client_CA_file(CAfile));
+
+/*
+ * Open the socket
+ */
+ sslListenSock = socketOpenConnection(NULL, SSL_PORT,
+ websSSLAccept, SOCKET_BLOCK);
+
+ if (sslListenSock < 0) {
+ trace(2, T("SSL: Unable to open SSL socket on port <%d>!\n"),
+ SSL_PORT);
+ return -1;
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Return TRUE if websSSL has been opened
+ */
+
+int websSSLIsOpen()
+{
+ return (sslListenSock != -1);
+}
+
+/******************************************************************************/
+/*
+ * Stops the SSL
+ */
+
+void websSSLClose()
+{
+ trace(7, T("SSL: Closing SSL\n"));
+
+ if (sslctx != NULL) {
+ SSL_CTX_free(sslctx);
+ sslctx = NULL;
+ }
+
+ if (sslListenSock != -1) {
+ socketCloseConnection(sslListenSock);
+ sslListenSock = -1;
+ }
+
+#ifdef SSLC
+ SSL_library_cleanup();
+#endif
+}
+
+/******************************************************************************/
+/*
+ * Accept a connection
+ */
+
+int websSSLAccept(int sid, char *ipaddr, int port, int listenSid)
+{
+ webs_t wp;
+ int wid;
+
+ a_assert(ipaddr && *ipaddr);
+ a_assert(sid >= 0);
+ a_assert(port >= 0);
+
+/*
+ * Allocate a new handle for this accepted connection. This will allocate
+ * a webs_t structure in the webs[] list
+ */
+ if ((wid = websAlloc(sid)) < 0) {
+ return -1;
+ }
+ wp = webs[wid];
+ a_assert(wp);
+ wp->listenSid = listenSid;
+
+ ascToUni(wp->ipaddr, ipaddr, min(sizeof(wp->ipaddr), strlen(ipaddr)+1));
+
+/*
+ * Check if this is a request from a browser on this system. This is useful
+ * to know for permitting administrative operations only for local access
+ */
+ if (gstrcmp(wp->ipaddr, T("127.0.0.1")) == 0 ||
+ gstrcmp(wp->ipaddr, websIpaddr) == 0 ||
+ gstrcmp(wp->ipaddr, websHost) == 0) {
+ wp->flags |= WEBS_LOCAL_REQUEST;
+ }
+/*
+ * Since the acceptance came in on this channel, it must be secure
+ */
+ wp->flags |= WEBS_SECURE;
+
+/*
+ * Arrange for websSocketEvent to be called when read data is available
+ */
+ socketCreateHandler(sid, SOCKET_READABLE, websSSLSocketEvent, (int) wp);
+
+/*
+ * Arrange for a timeout to kill hung requests
+ */
+ wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout, (void *) wp);
+ trace(8, T("webs: accept request\n"));
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * The webs socket handler. Called in response to I/O. We just pass control
+ * to the relevant read or write handler. A pointer to the webs structure
+ * is passed as an (int) in iwp.
+ */
+
+static void websSSLSocketEvent(int sid, int mask, int iwp)
+{
+ webs_t wp;
+
+ wp = (webs_t) iwp;
+ a_assert(wp);
+
+ if (! websValid(wp)) {
+ return;
+ }
+
+ if (mask & SOCKET_READABLE) {
+ websSSLReadEvent(wp);
+ }
+ if (mask & SOCKET_WRITABLE) {
+ if (wp->writeSocket) {
+ (*wp->writeSocket)(wp);
+ }
+ }
+}
+
+/******************************************************************************/
+/*
+ * Handler for SSL Read Events
+ */
+
+static int websSSLReadEvent (webs_t wp)
+{
+ int ret, sock;
+ socket_t *sptr;
+ SSL *ssl;
+ BIO *bio, *bioSSL, *bioSock;
+#ifdef DEV
+ const char *ciphers;
+#endif
+
+ a_assert (wp);
+ a_assert(websValid(wp));
+
+ sptr = socketPtr(wp->sid);
+ a_assert(sptr);
+
+ sock = sptr->sock;
+
+/*
+ * Create a new BIO and SSL session for this web request
+ */
+ bio = BIO_new(BIO_f_buffer());
+ a_assert(bio);
+
+ if (!BIO_set_write_buffer_size(bio, 128)) {
+ return -1;
+ }
+
+ ssl = (SSL *) SSL_new(sslctx);
+ a_assert(ssl);
+
+ if (ssl == NULL) {
+ return -1;
+ }
+
+ SSL_set_session(ssl, NULL);
+
+ bioSSL = BIO_new(BIO_f_ssl());
+ a_assert(bioSSL);
+
+ bioSock = BIO_new_socket(sock, BIO_NOCLOSE);
+ a_assert(bioSock);
+
+ SSL_set_bio(ssl, bioSock, bioSock);
+ SSL_set_accept_state(ssl);
+
+ ret = BIO_set_ssl(bioSSL, ssl, BIO_CLOSE);
+ BIO_push(bio, bioSSL);
+
+#ifdef DEV
+ ciphers = SSL_get_cipher_list(ssl, 10);
+#endif
+
+/*
+ * Create the SSL data structure in the wp.
+ */
+#ifdef WEBS_SSL_SUPPORT
+ wp->wsp = balloc(B_L, sizeof(websSSL_t));
+ a_assert (wp->wsp);
+ (wp->wsp)->bio = bio;
+ (wp->wsp)->ssl = ssl;
+#endif
+
+/*
+ * Call the default Read Event
+ */
+ websReadEvent(wp);
+
+ return ret;
+}
+
+
+/******************************************************************************/
+/*
+ * SSL Verification Callback
+ */
+
+static int sslVerifyDepth = 0;
+static int sslVerifyError = X509_V_OK;
+
+int websSSLVerifyCallback(int ok, X509_STORE_CTX *ctx)
+{
+ char buf[256];
+ X509 *errCert;
+ int err;
+ int depth;
+
+ errCert = X509_STORE_CTX_get_current_cert(ctx);
+ err = X509_STORE_CTX_get_error(ctx);
+ depth = X509_STORE_CTX_get_error_depth(ctx);
+
+ X509_NAME_oneline(X509_get_subject_name(errCert), buf, 256);
+
+ if (!ok) {
+ if (sslVerifyDepth >= depth) {
+ ok = 1;
+ sslVerifyError = X509_V_OK;
+ } else {
+ ok=0;
+ sslVerifyError = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+ }
+ }
+
+ switch (err) {
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+#ifdef OPENSSL
+ X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
+#endif
+ break;
+
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ break;
+ }
+
+ return ok;
+}
+
+/******************************************************************************/
+/*
+ * Set the SSL certificate and key for the SSL context
+ */
+
+int websSSLSetCertStuff(SSL_CTX *ctx, char *certFile, char *keyFile)
+{
+ a_assert (ctx);
+ a_assert (certFile);
+
+ if (certFile != NULL) {
+ if (SSL_CTX_use_certificate_file(ctx, certFile,
+ SSL_FILETYPE_PEM) <= 0) {
+ trace(2, T("SSL: Unable to set certificate file <%s>\n"),
+ certFile);
+ return -1;
+ }
+
+ if (keyFile == NULL) {
+ keyFile = certFile;
+ }
+
+ if (SSL_CTX_use_PrivateKey_file(ctx, keyFile, SSL_FILETYPE_PEM) <= 0) {
+ trace(2, T("SSL: Unable to set private key file <%s>\n"),
+ keyFile);
+ return -1;
+ }
+
+/*
+ * Now we know that a key and cert have been set against
+ * the SSL context
+ */
+ if (!SSL_CTX_check_private_key(ctx)) {
+ trace(2, T("SSL: Check of private key file <%s> FAILED!\n"),
+ keyFile);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Set certificate file for SSL context
+ */
+
+int websSSLSetCertFile(char_t *certFile)
+{
+ a_assert (sslctx);
+ a_assert (certFile);
+
+ if (sslctx == NULL) {
+ return -1;
+ }
+
+ if (SSL_CTX_use_certificate_file(sslctx, certFile,
+ SSL_FILETYPE_PEM) <= 0) {
+ return -1;
+ }
+/*
+ * Confirm that the certificate and the private key jive.
+ */
+ if (!SSL_CTX_check_private_key(sslctx)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Set key file for SSL context
+ */
+
+int websSSLSetKeyFile(char_t *keyFile)
+{
+ a_assert (sslctx);
+ a_assert (keyFile);
+
+ if (sslctx == NULL) {
+ return -1;
+ }
+
+ if (SSL_CTX_use_PrivateKey_file(sslctx, keyFile, SSL_FILETYPE_PEM) <= 0) {
+ return -1;
+ }
+/*
+ * Confirm that the certificate and the private key jive.
+ */
+ if (!SSL_CTX_check_private_key(sslctx)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+#ifdef SSLC
+extern RSA *RSA_new(void);
+#endif
+
+/******************************************************************************/
+/*
+ * the Temporary RSA callback
+ */
+
+static RSA *websSSLTempRSACallback(SSL *ssl, int isExport, int keyLength)
+{
+ static RSA *rsaTemp = NULL;
+
+ if (rsaTemp == NULL) {
+
+#ifdef OPENSSL
+ rsaTemp = RSA_generate_key(keyLength, RSA_F4, NULL, NULL);
+#endif
+
+#ifdef SSLC
+ rsaTemp = RSA_new();
+#endif
+
+ }
+
+ return rsaTemp;
+}
+
+/******************************************************************************/
+/*
+ * Free SSL resources
+ */
+
+int websSSLFree(websSSL_t *wsp)
+{
+ if (wsp == NULL) {
+ return -1;
+ }
+
+/*
+ * Make sure we re-use sessions
+ */
+ if (wsp->ssl != NULL) {
+ SSL_set_shutdown(wsp->ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+ }
+
+ if (wsp->bio != NULL) {
+ BIO_free_all(wsp->bio);
+ }
+
+ bfree(B_L, wsp);
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ * Return Eof for the SSL BIO
+ */
+
+int websSSLEof(websSSL_t *wsp)
+{
+ a_assert(wsp);
+
+ if ((wsp == NULL) || (wsp->bio == NULL)) {
+ return -1;
+ }
+
+ return BIO_eof(wsp->bio);
+}
+
+/******************************************************************************/
+/*
+ * Perform a read of the SSL BIO
+ */
+
+int websSSLRead(websSSL_t *wsp, char_t *buf, int len)
+{
+ a_assert(wsp);
+ a_assert(buf);
+
+ if ((wsp == NULL) || (wsp->bio == NULL)) {
+ return -1;
+ }
+
+ return BIO_read(wsp->bio, buf, len);
+}
+
+/******************************************************************************/
+/*
+ * Perform a gets of the SSL BIO, returning an balloc'ed string
+ */
+
+#define BUF_BLOCK 256
+
+int websSSLGets(websSSL_t *wsp, char_t **buf)
+{
+ int rc, len, lenBuf;
+ char c;
+
+ a_assert(wsp);
+ a_assert(buf);
+
+ lenBuf = 0;
+ len = 0;
+
+ if ((wsp == NULL) || (wsp->bio == NULL)) {
+ return -1;
+ }
+
+ while (1) {
+
+ if ((rc = BIO_read(wsp->bio, &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 (len > 0 && BIO_eof(wsp->bio)) {
+ 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') {
+ if ((len > 0) && (len < lenBuf)) {
+ (*buf)[len] = 0;
+ }
+ return len;
+ } else if (c == '\r') {
+ continue;
+ }
+/*
+ * Append character to buf
+ */
+ if (len >= lenBuf) {
+ lenBuf += BUF_BLOCK;
+ *buf = brealloc(B_L, *buf, lenBuf);
+ }
+
+ a_assert(*buf);
+ (*buf)[len] = c;
+ len++;
+ }
+}
+
+/******************************************************************************/
+/*
+ * Perform a write to the SSL BIO
+ */
+
+int websSSLWrite(websSSL_t *wsp, char_t *buf, int len)
+{
+ a_assert(wsp);
+ a_assert(buf);
+
+ if ((wsp == NULL) || (wsp->bio == NULL)) {
+ return -1;
+ }
+
+ return BIO_write(wsp->bio, buf, len);
+}
+
+/******************************************************************************/
+/*
+ * Perform a flush of the SSL BIO
+ */
+
+int websSSLFlush(websSSL_t *wsp)
+{
+ a_assert(wsp);
+
+ if ((wsp == NULL) || (wsp->bio == NULL)) {
+ return -1;
+ }
+
+ return BIO_flush(wsp->bio);
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/websSSL.h b/cpukit/httpd/websSSL.h
new file mode 100644
index 0000000000..62bcc44930
--- /dev/null
+++ b/cpukit/httpd/websSSL.h
@@ -0,0 +1,67 @@
+/*
+ * websSSL.h -- SSL Patch 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_websSSL
+#define _h_websSSL 1
+
+/******************************** Description *********************************/
+
+/*
+ * Header file for the GoAhead Patch for SSL. This defines the interface to
+ * integrate SSL into the GoAhead Webserver.
+ */
+
+/********************************* Includes ***********************************/
+
+
+#ifdef OPENSSL
+#define SSLEAY /* turn off a few special case MONOLITH macros */
+#define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */
+#include <openssl/ssl.h>
+#else
+#include <sslc.h>
+#endif
+
+#ifndef UEMF
+ #include "basic/basic.h"
+ #include "emf/emf.h"
+#else
+ #include "uemf.h"
+#endif
+
+/********************************** Defines ***********************************/
+
+typedef struct {
+ SSL *ssl;
+ BIO *bio;
+} websSSL_t;
+
+
+/******************************** Prototypes **********************************/
+
+extern int websSSLOpen();
+extern int websSSLIsOpen();
+extern void websSSLClose();
+
+extern int websSSLWrite(websSSL_t *wsp, char_t *buf, int nChars);
+extern int websSSLGets(websSSL_t *wsp, char_t **buf);
+extern int websSSLRead(websSSL_t *wsp, char_t *buf, int nChars);
+extern int websSSLEof(websSSL_t *wsp);
+
+extern int websSSLFree(websSSL_t *wsp);
+extern int websSSLFlush(websSSL_t *wsp);
+
+extern int websSSLSetKeyFile(char_t *keyFile);
+extern int websSSLSetCertFile(char_t *certFile);
+
+
+#endif /* _h_websSSL */
+
+/*****************************************************************************/
diff --git a/cpukit/httpd/websda.c b/cpukit/httpd/websda.c
new file mode 100644
index 0000000000..a4a95775b8
--- /dev/null
+++ b/cpukit/httpd/websda.c
@@ -0,0 +1,244 @@
+/*
+ * websda.c -- Digest Access Authentication routines
+ *
+ * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
+ *
+ * See the file "license.txt" for usage and redistribution license requirements
+ *
+ * $Id$
+ */
+
+/******************************** Description *********************************/
+
+/*
+ * Routines for generating DAA data. The module uses the
+ * "RSA Data Security, Inc. MD5 Message-Digest Algorithm" found in md5c.c
+ */
+
+/********************************* Includes ***********************************/
+
+#ifndef CE
+#include <time.h>
+#endif
+#include "websda.h"
+#include "md5.h"
+
+/******************************** Local Data **********************************/
+
+#define RANDOMKEY T("onceuponatimeinparadise")
+#define NONCE_SIZE 34
+#define HASH_SIZE 16
+
+/*********************************** Code *************************************/
+/*
+ * websMD5binary returns the MD5 hash
+ */
+
+char *websMD5binary(unsigned char *buf, int length)
+{
+ const char *hex = "0123456789abcdef";
+ MD5_CONTEXT md5ctx;
+ unsigned char hash[HASH_SIZE];
+ char *r, *strReturn;
+ char result[(HASH_SIZE * 2) + 1];
+ int i;
+
+/*
+ * Take the MD5 hash of the string argument.
+ */
+ MD5Init(&md5ctx);
+ MD5Update(&md5ctx, buf, (unsigned int)length);
+ MD5Final(hash, &md5ctx);
+
+/*
+ * Prepare the resulting hash string
+ */
+ for (i = 0, r = result; i < 16; i++) {
+ *r++ = hex[hash[i] >> 4];
+ *r++ = hex[hash[i] & 0xF];
+ }
+
+/*
+ * Zero terminate the hash string
+ */
+ *r = '\0';
+
+/*
+ * Allocate a new copy of the hash string
+ */
+ strReturn = balloc(B_L, sizeof(result));
+ strcpy(strReturn, result);
+
+ return strReturn;
+}
+
+/*****************************************************************************/
+/*
+ * Convenience call to websMD5binary
+ * (Performs char_t to char conversion and back)
+ */
+
+char_t *websMD5(char_t *string)
+{
+ char_t *strReturn;
+
+ a_assert(string && *string);
+
+ if (string && *string) {
+ char *strTemp, *strHash;
+ int nLen;
+/*
+ * Convert input char_t string to char string
+ */
+ nLen = gstrlen(string);
+ strTemp = ballocUniToAsc(string, nLen + 1);
+/*
+ * Execute the digest calculation
+ */
+ strHash = websMD5binary((unsigned char *)strTemp, nLen);
+/*
+ * Convert the returned char string digest to a char_t string
+ */
+ nLen = strlen(strHash);
+ strReturn = ballocAscToUni(strHash, nLen);
+/*
+ * Free up the temporary allocated resources
+ */
+ bfree(B_L, strTemp);
+ bfree(B_L, strHash);
+ } else {
+ strReturn = NULL;
+ }
+
+ return strReturn;
+}
+
+/******************************************************************************/
+/*
+ * Get a Nonce value for passing along to the client. This function
+ * composes the string "RANDOMKEY:timestamp:myrealm" and
+ * calculates the MD5 digest placing it in output.
+ */
+
+char_t *websCalcNonce(webs_t wp)
+{
+ char_t *nonce, *prenonce;
+ struct tm *newtime;
+ time_t longTime;
+
+ a_assert(wp);
+/*
+ * Get time as long integer.
+ */
+ time(&longTime);
+/*
+ * Convert to local time.
+ */
+ newtime = localtime(&longTime);
+/*
+ * Create prenonce string.
+ */
+ prenonce = NULL;
+#ifdef DIGEST_ACCESS_SUPPORT
+ fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime),
+ wp->realm);
+#else
+ fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime),
+ RANDOMKEY);
+#endif
+ a_assert(prenonce);
+/*
+ * Create the nonce
+ */
+ nonce = websMD5(prenonce);
+/*
+ * Cleanup
+ */
+ bfreeSafe(B_L, prenonce);
+
+ return nonce;
+}
+
+/******************************************************************************/
+/*
+ * Get an Opaque value for passing along to the client
+ */
+
+char_t *websCalcOpaque(webs_t wp)
+{
+ char_t *opaque;
+ a_assert(wp);
+/*
+ * Temporary stub!
+ */
+ opaque = bstrdup(B_L, T("5ccc069c403ebaf9f0171e9517f40e41"));
+
+ return opaque;
+}
+
+/******************************************************************************/
+/*
+ * Get a Digest value using the MD5 algorithm
+ */
+
+char_t *websCalcDigest(webs_t wp)
+{
+#ifdef DIGEST_ACCESS_SUPPORT
+ char_t *digest, *a1, *a1prime, *a2, *a2prime, *preDigest, *method;
+
+ a_assert(wp);
+ digest = NULL;
+
+/*
+ * Calculate first portion of digest H(A1)
+ */
+ a1 = NULL;
+ fmtAlloc(&a1, 255, T("%s:%s:%s"), wp->userName, wp->realm, wp->password);
+ a_assert(a1);
+ a1prime = websMD5(a1);
+ bfreeSafe(B_L, a1);
+/*
+ * Calculate second portion of digest H(A2)
+ */
+ method = websGetVar(wp, T("REQUEST_METHOD"), NULL);
+ a_assert(method);
+ a2 = NULL;
+ fmtAlloc(&a2, 255, T("%s:%s"), method, wp->uri);
+ a_assert(a2);
+ a2prime = websMD5(a2);
+ bfreeSafe(B_L, a2);
+/*
+ * Construct final digest KD(H(A1):nonce:H(A2))
+ */
+ a_assert(a1prime);
+ a_assert(a2prime);
+ a_assert(wp->nonce);
+
+ preDigest = NULL;
+ if (!wp->qop) {
+ fmtAlloc(&preDigest, 255, T("%s:%s:%s"), a1prime, wp->nonce, a2prime);
+ } else {
+ fmtAlloc(&preDigest, 255, T("%s:%s:%s:%s:%s:%s"),
+ a1prime,
+ wp->nonce,
+ wp->nc,
+ wp->cnonce,
+ wp->qop,
+ a2prime);
+ }
+
+ a_assert(preDigest);
+ digest = websMD5(preDigest);
+/*
+ * Now clean up
+ */
+ bfreeSafe(B_L, a1prime);
+ bfreeSafe(B_L, a2prime);
+ bfreeSafe(B_L, preDigest);
+ return digest;
+#else
+ return NULL;
+#endif /* DIGEST_ACCESS_SUPPORT */
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/websda.h b/cpukit/httpd/websda.h
new file mode 100644
index 0000000000..3852ab8f53
--- /dev/null
+++ b/cpukit/httpd/websda.h
@@ -0,0 +1,41 @@
+/*
+ * websda.h -- GoAhead Digest Access Authentication 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_WEBSDA
+#define _h_WEBSDA 1
+
+/******************************** Description *********************************/
+
+/*
+ * GoAhead Digest Access Authentication header. This defines the Digest
+ * access authentication public APIs. Include this header for files that
+ * use DAA functions
+ */
+
+/********************************* Includes ***********************************/
+
+#ifndef UEMF
+ #include "basic/basic.h"
+ #include "emf/emf.h"
+#else
+ #include "uemf.h"
+#endif
+
+#include "webs.h"
+
+/****************************** Definitions ***********************************/
+
+extern char_t *websCalcNonce(webs_t wp);
+extern char_t *websCalcOpaque(webs_t wp);
+extern char_t *websCalcDigest(webs_t wp);
+
+#endif /* _h_WEBSDA */
+
+/******************************************************************************/
diff --git a/cpukit/httpd/websuemf.c b/cpukit/httpd/websuemf.c
new file mode 100644
index 0000000000..4ff1b92a7e
--- /dev/null
+++ b/cpukit/httpd/websuemf.c
@@ -0,0 +1,217 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+/********************************** 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;
+ /*
+ * NOTE -- to disable better reporting of ASP errors, change the
+ * following line of code to
+ * if (ejEval(ejid, cmd, NULL) ) {
+ */
+ if (ejEval(ejid, cmd, result) ) {
+ 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;
+ }
+ }
+}
+
+/******************************************************************************/
diff --git a/cpukit/httpd/wsIntrn.h b/cpukit/httpd/wsIntrn.h
new file mode 100644
index 0000000000..9fb11f9937
--- /dev/null
+++ b/cpukit/httpd/wsIntrn.h
@@ -0,0 +1,309 @@
+/*
+ * 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
+ *
+ * $Id$
+ */
+
+#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 logging 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>
+
+#ifdef NETWARE
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <io.h>
+#endif
+
+#ifdef WIN
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <io.h>
+#endif
+
+#ifdef CE
+#ifndef UEMF
+ #include <io.h>
+#endif
+#endif
+
+#ifdef NW
+ #include <fcntl.h>
+ #include <sys/stat.h>
+#endif
+
+#ifdef SCOV5
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <unistd.h>
+#endif
+
+#ifdef LYNX
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <unistd.h>
+#endif
+
+#ifdef UNIX
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <unistd.h>
+#endif
+
+#ifdef QNX4
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <unistd.h>
+ #include <unix.h>
+#endif
+
+#ifdef UW
+ #include <fcntl.h>
+ #include <sys/stat.h>
+#endif
+
+#ifdef VXWORKS
+ #include <vxWorks.h>
+ #include <fcntl.h>
+ #include <sys/stat.h>
+#endif
+
+#ifdef SOLARIS
+ #include <macros.h>
+ #include <fcntl.h>
+ #include <sys/stat.h>
+#endif
+
+#ifdef 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 */
+
+/*
+ * 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 */
+ 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)
+ */
+#ifdef EMF
+extern int websEmfOpen();
+extern void websEmfClose();
+extern void websSetEmfEnvironment(webs_t wp);
+#endif
+
+#ifdef 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 */
+
+/******************************************************************************/
diff --git a/cpukit/include/rtems/bspIo.h b/cpukit/include/rtems/bspIo.h
new file mode 100644
index 0000000000..775e8ce4be
--- /dev/null
+++ b/cpukit/include/rtems/bspIo.h
@@ -0,0 +1,39 @@
+/* bspIo.h
+ *
+ * This include file contains declaration of interface that
+ * will be provided by the file contained in this directory.
+ *
+ * COPYRIGHT (c) 1998 valette@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+#ifndef _RTEMS_BSPIO_H
+#define _RTEMS_BSPIO_H
+
+/*
+ * All the functions declared as extern after this comment
+ * MUST be implemented in each BSP. Using this function,
+ * this directory contains shared code that export higher level
+ * functionnality described after the next command.
+ */
+typedef void (*BSP_output_char_function_type) (char c);
+typedef char (*BSP_polling_getchar_function_type) (void);
+
+extern BSP_output_char_function_type BSP_output_char;
+extern BSP_polling_getchar_function_type BSP_poll_char;
+
+/*
+ * All the function declared as extern after this comment
+ * are available for each BSP by compiling and linking
+ * the files contained in this directory PROVIDED definition
+ * and initialisation of the previous variable are done.
+ */
+#include <stdarg.h>
+extern void vprintk(char *fmt, va_list ap);
+extern void printk(char *fmt, ...);
+
+#endif
diff --git a/cpukit/include/rtems/concat.h b/cpukit/include/rtems/concat.h
new file mode 100644
index 0000000000..79bdd8879c
--- /dev/null
+++ b/cpukit/include/rtems/concat.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2004,2005 Ralf Corsepius, Ulm, Germany.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_CONCAT_H
+#define _RTEMS_CONCAT_H
+
+/* ANSI concatenation macros. */
+
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+#define EXPAND0(x) x
+#define CONCAT0(a,b) EXPAND0(a)EXPAND0(b)
+
+#endif
diff --git a/cpukit/include/rtems/fs.h b/cpukit/include/rtems/fs.h
new file mode 100644
index 0000000000..6f4f54c259
--- /dev/null
+++ b/cpukit/include/rtems/fs.h
@@ -0,0 +1,59 @@
+/*
+ * Some basic filesystem types
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_FS_H
+#define _RTEMS_FS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * File descriptor Table Information
+ */
+
+/* Forward declarations */
+
+/* FIXME: shouldn't this better not be here? */
+typedef struct rtems_libio_tt rtems_libio_t;
+
+typedef struct rtems_filesystem_location_info_tt
+ rtems_filesystem_location_info_t;
+
+struct rtems_filesystem_mount_table_entry_tt;
+typedef struct rtems_filesystem_mount_table_entry_tt
+ rtems_filesystem_mount_table_entry_t;
+
+typedef struct _rtems_filesystem_file_handlers_r
+ rtems_filesystem_file_handlers_r;
+typedef struct _rtems_filesystem_operations_table
+ rtems_filesystem_operations_table;
+
+/*
+ * Structure used to determine a location/filesystem in the tree.
+ */
+
+struct rtems_filesystem_location_info_tt
+{
+ void *node_access;
+ rtems_filesystem_file_handlers_r *handlers;
+ rtems_filesystem_operations_table *ops;
+ rtems_filesystem_mount_table_entry_t *mt_entry;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/irq.h b/cpukit/include/rtems/irq.h
new file mode 100644
index 0000000000..12a501bd4a
--- /dev/null
+++ b/cpukit/include/rtems/irq.h
@@ -0,0 +1,217 @@
+/*
+ *
+ * This include file describe the data structure and the functions implemented
+ * by rtems to write interrupt handlers.
+ *
+ * CopyRight (C) 1998 valette@crf.canon.fr
+ *
+ * This code is heavilly inspired by the public specification of STREAM V2
+ * that can be found at :
+ *
+ * <http://www.chorus.com/Documentation/index.html> by following
+ * the STREAM API Specification Document link.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_IRQ_H
+#define _RTEMS_IRQ_H
+
+#ifndef ASM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Type definition for RTEMS managed interrupts
+ */
+typedef unsigned char rtems_irq_prio;
+struct __rtems_irq_connect_data__; /* forward declaratiuon */
+
+typedef unsigned int rtems_irq_number;
+typedef void *rtems_irq_hdl_param;
+typedef void (*rtems_irq_hdl) (rtems_irq_hdl_param);
+typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*);
+typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*);
+typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*);
+
+typedef struct __rtems_irq_connect_data__ {
+ /*
+ * IRQ line
+ */
+ rtems_irq_number name;
+ /*
+ * handler. See comment on handler properties below in function prototype.
+ */
+ rtems_irq_hdl hdl;
+ /*
+ * Handler handle to store private data
+ */
+ rtems_irq_hdl_param handle;
+ /*
+ * function for enabling interrupts at device level (ONLY!).
+ * The BSP code will automatically enable it at i8259s level.
+ * RATIONALE : anyway such code has to exist in current driver code.
+ * It is usually called immediately AFTER connecting the interrupt handler.
+ * RTEMS may well need such a function when restoring normal interrupt
+ * processing after a debug session.
+ *
+ */
+ rtems_irq_enable on;
+ /*
+ * function for disabling interrupts at device level (ONLY!).
+ * The code will disable it at i8259s level. RATIONALE : anyway
+ * such code has to exist for clean shutdown. It is usually called
+ * BEFORE disconnecting the interrupt. RTEMS may well need such
+ * a function when disabling normal interrupt processing for
+ * a debug session. May well be a NOP function.
+ */
+ rtems_irq_disable off;
+ /*
+ * function enabling to know what interrupt may currently occur
+ * if someone manipulates the i8259s interrupt mask without care...
+ */
+ rtems_irq_is_enabled isOn;
+
+#ifdef BSP_SHARED_HANDLER_SUPPORT
+ /*
+ * Set to -1 for vectors forced to have only 1 handler
+ */
+ void *next_handler;
+#endif
+
+} rtems_irq_connect_data;
+
+typedef struct {
+ /*
+ * size of all the table fields (*Tbl) described below.
+ */
+ unsigned int irqNb;
+ /*
+ * Default handler used when disconnecting interrupts.
+ */
+ rtems_irq_connect_data defaultEntry;
+ /*
+ * Table containing initials/current value.
+ */
+ rtems_irq_connect_data* irqHdlTbl;
+ /*
+ * actual value of BSP_ISA_IRQ_VECTOR_BASE...
+ */
+ rtems_irq_number irqBase;
+ /*
+ * software priorities associated with interrupts.
+ * if (*irqPrio [i] > intrPrio [j] it means that
+ * interrupt handler hdl connected for interrupt name i
+ * will not be interrupted by the handler connected for interrupt j
+ * The interrupt source will be physically masked at i8259 level.
+ */
+ rtems_irq_prio* irqPrioTbl;
+} rtems_irq_global_settings;
+
+/*-------------------------------------------------------------------------+
+| Function Prototypes.
++--------------------------------------------------------------------------*/
+/*
+ * ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
+ */
+/*
+ * function to connect a particular irq handler. This hanlder will NOT be called
+ * directly as the result of the corresponding interrupt. Instead, a RTEMS
+ * irq prologue will be called that will :
+ *
+ * 1) save the C scratch registers,
+ * 2) switch to a interrupt stack if the interrupt is not nested,
+ * 3) store the current i8259s' interrupt masks
+ * 4) modify them to disable the current interrupt at 8259 level (and may
+ * be others depending on software priorities)
+ * 5) aknowledge the i8259s',
+ * 6) demask the processor,
+ * 7) call the application handler
+ *
+ * As a result the hdl function provided
+ *
+ * a) can perfectly be written is C,
+ * b) may also well directly call the part of the RTEMS API that can be used
+ * from interrupt level,
+ * c) It only responsible for handling the jobs that need to be done at
+ * the device level including (aknowledging/re-enabling the interrupt at device,
+ * level, getting the data,...)
+ *
+ * When returning from the function, the following will be performed by
+ * the RTEMS irq epilogue :
+ *
+ * 1) masks the interrupts again,
+ * 2) restore the original i8259s' interrupt masks
+ * 3) switch back on the orinal stack if needed,
+ * 4) perform rescheduling when necessary,
+ * 5) restore the C scratch registers...
+ * 6) restore initial execution flow
+ *
+ */
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*);
+/*
+ * function to get the current RTEMS irq handler for ptr->name. It enables to
+ * define hanlder chain...
+ */
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr);
+/*
+ * function to get disconnect the RTEMS irq handler for ptr->name.
+ * This function checks that the value given is the current one for safety reason.
+ * The user can use the previous function to get it.
+ */
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data*);
+
+
+/*
+ * ------------------------ RTEMS Shared Irq Handler Mngt Routines ----------------
+ */
+#ifdef BSP_SHARED_HANDLER_SUPPORT
+int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data*);
+#endif
+
+
+/*
+ * ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
+ */
+/*
+ * (Re) Initialize the RTEMS interrupt management.
+ *
+ * The result of calling this function will be the same as if each individual
+ * handler (config->irqHdlTbl[i].hdl) different from "config->defaultEntry.hdl"
+ * has been individualy connected via
+ * BSP_install_rtems_irq_handler(&config->irqHdlTbl[i])
+ * And each handler currently equal to config->defaultEntry.hdl
+ * has been previously disconnected via
+ * BSP_remove_rtems_irq_handler (&config->irqHdlTbl[i])
+ *
+ * This is to say that all information given will be used and not just
+ * only the space.
+ *
+ * CAUTION : the various table address contained in config will be used
+ * directly by the interrupt mangement code in order to save
+ * data size so they must stay valid after the call => they should
+ * not be modified or declared on a stack.
+ */
+
+int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config);
+/*
+ * (Re) get info on current RTEMS interrupt management.
+ */
+int BSP_rtems_irq_mngt_get(rtems_irq_global_settings**);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ASM */
+#endif /* _RTEMS_IRQ_H */
diff --git a/cpukit/include/rtems/pci.h b/cpukit/include/rtems/pci.h
new file mode 100644
index 0000000000..162254c58d
--- /dev/null
+++ b/cpukit/include/rtems/pci.h
@@ -0,0 +1,1225 @@
+/*
+ *
+ * PCI defines and function prototypes
+ * Copyright 1994, Drew Eckhardt
+ * Copyright 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ * For more information, please consult the following manuals (look at
+ * http://www.pcisig.com/ for how to get them):
+ *
+ * PCI BIOS Specification
+ * PCI Local Bus Specification
+ * PCI to PCI Bridge Specification
+ * PCI System Design Guide
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_PCI_H
+#define _RTEMS_PCI_H
+
+/*
+ * Under PCI, each device has 256 bytes of configuration address space,
+ * of which the first 64 bytes are standardized as follows:
+ */
+#define PCI_VENDOR_ID 0x00 /* 16 bits */
+#define PCI_DEVICE_ID 0x02 /* 16 bits */
+
+#define PCI_COMMAND 0x04 /* 16 bits */
+#define PCI_COMMAND_IO 0x0001 /* Enable response in I/O space */
+#define PCI_COMMAND_MEMORY 0x0002 /* Enable response in Memory space */
+#define PCI_COMMAND_MASTER 0x0004 /* Enable bus mastering */
+#define PCI_COMMAND_SPECIAL 0x0008 /* Enable response to special cycles */
+#define PCI_COMMAND_INVALIDATE 0x0010 /* Use memory write and invalidate */
+#define PCI_COMMAND_VGA_PALETTE 0x0020 /* Enable palette snooping */
+#define PCI_COMMAND_PARITY 0x0040 /* Enable parity checking */
+#define PCI_COMMAND_WAIT 0x0080 /* Enable address/data stepping */
+#define PCI_COMMAND_SERR 0x0100 /* Enable SERR */
+#define PCI_COMMAND_FAST_BACK 0x0200 /* Enable back-to-back writes */
+
+#define PCI_STATUS 0x06 /* 16 bits */
+#define PCI_STATUS_66MHZ 0x0020 /* Support 66 Mhz PCI 2.1 bus */
+#define PCI_STATUS_UDF 0x0040 /* Support User Definable Features */
+#define PCI_STATUS_FAST_BACK 0x0080 /* Accept fast-back to back */
+#define PCI_STATUS_PARITY 0x0100 /* Detected parity error */
+#define PCI_STATUS_DEVSEL_MASK 0x0600 /* DEVSEL timing */
+#define PCI_STATUS_DEVSEL_FAST 0x0000
+#define PCI_STATUS_DEVSEL_MEDIUM 0x0200
+#define PCI_STATUS_DEVSEL_SLOW 0x0400
+#define PCI_STATUS_SIG_TARGET_ABORT 0x0800 /* Set on target abort */
+#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
+#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
+#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
+#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
+
+#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */
+#define PCI_REVISION_ID 0x08 /* Revision ID */
+#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
+#define PCI_CLASS_DEVICE 0x0a /* Device class */
+#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
+#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
+
+#define PCI_HEADER_TYPE 0x0e /* 8 bits */
+#define PCI_HEADER_TYPE_NORMAL 0
+#define PCI_HEADER_TYPE_BRIDGE 1
+#define PCI_HEADER_TYPE_CARDBUS 2
+
+#define PCI_BIST 0x0f /* 8 bits */
+#define PCI_BIST_CODE_MASK 0x0f /* Return result */
+#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
+#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
+
+/*
+ * Base addresses specify locations in memory or I/O space.
+ * Decoded size can be determined by writing a value of
+ * 0xffffffff to the register, and reading it back. Only
+ * 1 bits are decoded.
+ */
+#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
+#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
+#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
+#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
+#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
+#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
+#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
+#define PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
+#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M */
+#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
+#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
+#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
+#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
+/* bit 1 is reserved if address_space = 1 */
+
+/* Header type 0 (normal devices) */
+#define PCI_CARDBUS_CIS 0x28
+#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
+#define PCI_SUBSYSTEM_ID 0x2e
+#define PCI_ROM_ADDRESS 0x30/* Bits 31..11 address, 10..1 reserved */
+#define PCI_ROM_ADDRESS_ENABLE 0x01
+#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
+
+/* 0x34-0x3b are reserved */
+#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
+#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
+#define PCI_MIN_GNT 0x3e /* 8 bits */
+#define PCI_MAX_LAT 0x3f /* 8 bits */
+
+/* Header type 1 (PCI-to-PCI bridges) */
+#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
+#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
+#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
+#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
+#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
+#define PCI_IO_LIMIT 0x1d
+#define PCI_IO_RANGE_TYPE_MASK 0x0f /* I/O bridging type */
+#define PCI_IO_RANGE_TYPE_16 0x00
+#define PCI_IO_RANGE_TYPE_32 0x01
+#define PCI_IO_RANGE_MASK ~0x0f
+
+#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
+
+#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
+#define PCI_MEMORY_LIMIT 0x22
+#define PCI_MEMORY_RANGE_TYPE_MASK 0x0f
+#define PCI_MEMORY_RANGE_MASK ~0x0f
+#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
+#define PCI_PREF_MEMORY_LIMIT 0x26
+#define PCI_PREF_RANGE_TYPE_MASK 0x0f
+#define PCI_PREF_RANGE_TYPE_32 0x00
+#define PCI_PREF_RANGE_TYPE_64 0x01
+#define PCI_PREF_RANGE_MASK ~0x0f
+#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory */
+#define PCI_PREF_LIMIT_UPPER32 0x2c
+#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
+#define PCI_IO_LIMIT_UPPER16 0x32
+/* 0x34-0x3b is reserved */
+#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_BRIDGE_CONTROL 0x3e
+#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
+#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
+#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
+#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
+#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
+#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
+#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled */
+ /* on secondary interface */
+
+/* Header type 2 (CardBus bridges) */
+/* 0x14-0x15 reserved */
+#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */
+#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */
+#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */
+#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */
+#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */
+#define PCI_CB_MEMORY_BASE_0 0x1c
+#define PCI_CB_MEMORY_LIMIT_0 0x20
+#define PCI_CB_MEMORY_BASE_1 0x24
+#define PCI_CB_MEMORY_LIMIT_1 0x28
+#define PCI_CB_IO_BASE_0 0x2c
+#define PCI_CB_IO_BASE_0_HI 0x2e
+#define PCI_CB_IO_LIMIT_0 0x30
+#define PCI_CB_IO_LIMIT_0_HI 0x32
+#define PCI_CB_IO_BASE_1 0x34
+#define PCI_CB_IO_BASE_1_HI 0x36
+#define PCI_CB_IO_LIMIT_1 0x38
+#define PCI_CB_IO_LIMIT_1_HI 0x3a
+#define PCI_CB_IO_RANGE_MASK ~0x03
+/* 0x3c-0x3d are same as for htype 0 */
+
+#define PCI_CB_BRIDGE_CONTROL 0x3e
+#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge */
+ /* control register */
+#define PCI_CB_BRIDGE_CTL_SERR 0x02
+#define PCI_CB_BRIDGE_CTL_ISA 0x04
+#define PCI_CB_BRIDGE_CTL_VGA 0x08
+#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
+#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */
+#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for */
+ /* 16-bit cards */
+#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for */
+ /* both memory regions */
+#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
+#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
+
+#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
+#define PCI_CB_SUBSYSTEM_ID 0x42
+
+/* 16-bit PC Card legacy mode base address (ExCa) */
+#define PCI_CB_LEGACY_MODE_BASE 0x44
+
+/* 0x48-0x7f reserved */
+
+/* Device classes and subclasses */
+
+#define PCI_CLASS_NOT_DEFINED 0x0000
+#define PCI_CLASS_NOT_DEFINED_VGA 0x0001
+
+#define PCI_BASE_CLASS_STORAGE 0x01
+#define PCI_CLASS_STORAGE_SCSI 0x0100
+#define PCI_CLASS_STORAGE_IDE 0x0101
+#define PCI_CLASS_STORAGE_FLOPPY 0x0102
+#define PCI_CLASS_STORAGE_IPI 0x0103
+#define PCI_CLASS_STORAGE_RAID 0x0104
+#define PCI_CLASS_STORAGE_OTHER 0x0180
+
+#define PCI_BASE_CLASS_NETWORK 0x02
+#define PCI_CLASS_NETWORK_ETHERNET 0x0200
+#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201
+#define PCI_CLASS_NETWORK_FDDI 0x0202
+#define PCI_CLASS_NETWORK_ATM 0x0203
+#define PCI_CLASS_NETWORK_OTHER 0x0280
+
+#define PCI_BASE_CLASS_DISPLAY 0x03
+#define PCI_CLASS_DISPLAY_VGA 0x0300
+#define PCI_CLASS_DISPLAY_XGA 0x0301
+#define PCI_CLASS_DISPLAY_OTHER 0x0380
+
+#define PCI_BASE_CLASS_MULTIMEDIA 0x04
+#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400
+#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
+#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480
+
+#define PCI_BASE_CLASS_MEMORY 0x05
+#define PCI_CLASS_MEMORY_RAM 0x0500
+#define PCI_CLASS_MEMORY_FLASH 0x0501
+#define PCI_CLASS_MEMORY_OTHER 0x0580
+
+#define PCI_BASE_CLASS_BRIDGE 0x06
+#define PCI_CLASS_BRIDGE_HOST 0x0600
+#define PCI_CLASS_BRIDGE_ISA 0x0601
+#define PCI_CLASS_BRIDGE_EISA 0x0602
+#define PCI_CLASS_BRIDGE_MC 0x0603
+#define PCI_CLASS_BRIDGE_PCI 0x0604
+#define PCI_CLASS_BRIDGE_PCMCIA 0x0605
+#define PCI_CLASS_BRIDGE_NUBUS 0x0606
+#define PCI_CLASS_BRIDGE_CARDBUS 0x0607
+#define PCI_CLASS_BRIDGE_OTHER 0x0680
+
+#define PCI_BASE_CLASS_COMMUNICATION 0x07
+#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
+#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
+#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
+
+#define PCI_BASE_CLASS_SYSTEM 0x08
+#define PCI_CLASS_SYSTEM_PIC 0x0800
+#define PCI_CLASS_SYSTEM_DMA 0x0801
+#define PCI_CLASS_SYSTEM_TIMER 0x0802
+#define PCI_CLASS_SYSTEM_RTC 0x0803
+#define PCI_CLASS_SYSTEM_OTHER 0x0880
+
+#define PCI_BASE_CLASS_INPUT 0x09
+#define PCI_CLASS_INPUT_KEYBOARD 0x0900
+#define PCI_CLASS_INPUT_PEN 0x0901
+#define PCI_CLASS_INPUT_MOUSE 0x0902
+#define PCI_CLASS_INPUT_OTHER 0x0980
+
+#define PCI_BASE_CLASS_DOCKING 0x0a
+#define PCI_CLASS_DOCKING_GENERIC 0x0a00
+#define PCI_CLASS_DOCKING_OTHER 0x0a01
+
+#define PCI_BASE_CLASS_PROCESSOR 0x0b
+#define PCI_CLASS_PROCESSOR_386 0x0b00
+#define PCI_CLASS_PROCESSOR_486 0x0b01
+#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02
+#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10
+#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20
+#define PCI_CLASS_PROCESSOR_CO 0x0b40
+
+#define PCI_BASE_CLASS_SERIAL 0x0c
+#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00
+#define PCI_CLASS_SERIAL_ACCESS 0x0c01
+#define PCI_CLASS_SERIAL_SSA 0x0c02
+#define PCI_CLASS_SERIAL_USB 0x0c03
+#define PCI_CLASS_SERIAL_FIBER 0x0c04
+
+#define PCI_CLASS_OTHERS 0xff
+
+/*
+ * Vendor and card ID's: sort these numerically according to vendor
+ * (and according to card ID within vendor). Send all updates to
+ * <linux-pcisupport@cck.uni-kl.de>.
+ */
+#define PCI_VENDOR_ID_COMPAQ 0x0e11
+#define PCI_DEVICE_ID_COMPAQ_1280 0x3033
+#define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000
+#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10
+#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32
+#define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34
+#define PCI_DEVICE_ID_COMPAQ_NETFLEX3I 0xae35
+#define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40
+#define PCI_DEVICE_ID_COMPAQ_NETEL100PI 0xae43
+#define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011
+#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130
+#define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150
+
+#define PCI_VENDOR_ID_NCR 0x1000
+#define PCI_DEVICE_ID_NCR_53C810 0x0001
+#define PCI_DEVICE_ID_NCR_53C820 0x0002
+#define PCI_DEVICE_ID_NCR_53C825 0x0003
+#define PCI_DEVICE_ID_NCR_53C815 0x0004
+#define PCI_DEVICE_ID_NCR_53C860 0x0006
+#define PCI_DEVICE_ID_NCR_53C896 0x000b
+#define PCI_DEVICE_ID_NCR_53C895 0x000c
+#define PCI_DEVICE_ID_NCR_53C885 0x000d
+#define PCI_DEVICE_ID_NCR_53C875 0x000f
+#define PCI_DEVICE_ID_NCR_53C875J 0x008f
+
+#define PCI_VENDOR_ID_ATI 0x1002
+#define PCI_DEVICE_ID_ATI_68800 0x4158
+#define PCI_DEVICE_ID_ATI_215CT222 0x4354
+#define PCI_DEVICE_ID_ATI_210888CX 0x4358
+#define PCI_DEVICE_ID_ATI_215GB 0x4742
+#define PCI_DEVICE_ID_ATI_215GD 0x4744
+#define PCI_DEVICE_ID_ATI_215GI 0x4749
+#define PCI_DEVICE_ID_ATI_215GP 0x4750
+#define PCI_DEVICE_ID_ATI_215GQ 0x4751
+#define PCI_DEVICE_ID_ATI_215GT 0x4754
+#define PCI_DEVICE_ID_ATI_215GTB 0x4755
+#define PCI_DEVICE_ID_ATI_210888GX 0x4758
+#define PCI_DEVICE_ID_ATI_215LG 0x4c47
+#define PCI_DEVICE_ID_ATI_264LT 0x4c54
+#define PCI_DEVICE_ID_ATI_264VT 0x5654
+
+#define PCI_VENDOR_ID_VLSI 0x1004
+#define PCI_DEVICE_ID_VLSI_82C592 0x0005
+#define PCI_DEVICE_ID_VLSI_82C593 0x0006
+#define PCI_DEVICE_ID_VLSI_82C594 0x0007
+#define PCI_DEVICE_ID_VLSI_82C597 0x0009
+#define PCI_DEVICE_ID_VLSI_82C541 0x000c
+#define PCI_DEVICE_ID_VLSI_82C543 0x000d
+#define PCI_DEVICE_ID_VLSI_82C532 0x0101
+#define PCI_DEVICE_ID_VLSI_82C534 0x0102
+#define PCI_DEVICE_ID_VLSI_82C535 0x0104
+#define PCI_DEVICE_ID_VLSI_82C147 0x0105
+#define PCI_DEVICE_ID_VLSI_VAS96011 0x0702
+
+#define PCI_VENDOR_ID_ADL 0x1005
+#define PCI_DEVICE_ID_ADL_2301 0x2301
+
+#define PCI_VENDOR_ID_NS 0x100b
+#define PCI_DEVICE_ID_NS_87415 0x0002
+#define PCI_DEVICE_ID_NS_87410 0xd001
+
+#define PCI_VENDOR_ID_TSENG 0x100c
+#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202
+#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205
+#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206
+#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207
+#define PCI_DEVICE_ID_TSENG_ET6000 0x3208
+
+#define PCI_VENDOR_ID_WEITEK 0x100e
+#define PCI_DEVICE_ID_WEITEK_P9000 0x9001
+#define PCI_DEVICE_ID_WEITEK_P9100 0x9100
+
+#define PCI_VENDOR_ID_DEC 0x1011
+#define PCI_DEVICE_ID_DEC_BRD 0x0001
+#define PCI_DEVICE_ID_DEC_TULIP 0x0002
+#define PCI_DEVICE_ID_DEC_TGA 0x0004
+#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
+#define PCI_DEVICE_ID_DEC_TGA2 0x000D
+#define PCI_DEVICE_ID_DEC_FDDI 0x000F
+#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014
+#define PCI_DEVICE_ID_DEC_21142 0x0019
+#define PCI_DEVICE_ID_DEC_21052 0x0021
+#define PCI_DEVICE_ID_DEC_21150 0x0022
+#define PCI_DEVICE_ID_DEC_21152 0x0024
+
+#define PCI_VENDOR_ID_CIRRUS 0x1013
+#define PCI_DEVICE_ID_CIRRUS_7548 0x0038
+#define PCI_DEVICE_ID_CIRRUS_5430 0x00a0
+#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4
+#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8
+#define PCI_DEVICE_ID_CIRRUS_5436 0x00ac
+#define PCI_DEVICE_ID_CIRRUS_5446 0x00b8
+#define PCI_DEVICE_ID_CIRRUS_5480 0x00bc
+#define PCI_DEVICE_ID_CIRRUS_5464 0x00d4
+#define PCI_DEVICE_ID_CIRRUS_5465 0x00d6
+#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
+#define PCI_DEVICE_ID_CIRRUS_6832 0x1110
+#define PCI_DEVICE_ID_CIRRUS_7542 0x1200
+#define PCI_DEVICE_ID_CIRRUS_7543 0x1202
+#define PCI_DEVICE_ID_CIRRUS_7541 0x1204
+
+#define PCI_VENDOR_ID_IBM 0x1014
+#define PCI_DEVICE_ID_IBM_FIRE_CORAL 0x000a
+#define PCI_DEVICE_ID_IBM_TR 0x0018
+#define PCI_DEVICE_ID_IBM_82G2675 0x001d
+#define PCI_DEVICE_ID_IBM_MCA 0x0020
+#define PCI_DEVICE_ID_IBM_82351 0x0022
+#define PCI_DEVICE_ID_IBM_SERVERAID 0x002e
+#define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e
+#define PCI_DEVICE_ID_IBM_MPIC 0x0046
+#define PCI_DEVICE_ID_IBM_3780IDSP 0x007d
+#define PCI_DEVICE_ID_IBM_MPIC_2 0xffff
+
+#define PCI_VENDOR_ID_WD 0x101c
+#define PCI_DEVICE_ID_WD_7197 0x3296
+
+#define PCI_VENDOR_ID_AMD 0x1022
+#define PCI_DEVICE_ID_AMD_LANCE 0x2000
+#define PCI_DEVICE_ID_AMD_SCSI 0x2020
+
+#define PCI_VENDOR_ID_TRIDENT 0x1023
+#define PCI_DEVICE_ID_TRIDENT_9397 0x9397
+#define PCI_DEVICE_ID_TRIDENT_9420 0x9420
+#define PCI_DEVICE_ID_TRIDENT_9440 0x9440
+#define PCI_DEVICE_ID_TRIDENT_9660 0x9660
+#define PCI_DEVICE_ID_TRIDENT_9750 0x9750
+
+#define PCI_VENDOR_ID_AI 0x1025
+#define PCI_DEVICE_ID_AI_M1435 0x1435
+
+#define PCI_VENDOR_ID_MATROX 0x102B
+#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518
+#define PCI_DEVICE_ID_MATROX_MIL 0x0519
+#define PCI_DEVICE_ID_MATROX_MYS 0x051A
+#define PCI_DEVICE_ID_MATROX_MIL_2 0x051b
+#define PCI_DEVICE_ID_MATROX_MIL_2_AGP 0x051f
+#define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10
+
+#define PCI_VENDOR_ID_CT 0x102c
+#define PCI_DEVICE_ID_CT_65545 0x00d8
+#define PCI_DEVICE_ID_CT_65548 0x00dc
+#define PCI_DEVICE_ID_CT_65550 0x00e0
+#define PCI_DEVICE_ID_CT_65554 0x00e4
+#define PCI_DEVICE_ID_CT_65555 0x00e5
+
+#define PCI_VENDOR_ID_MIRO 0x1031
+#define PCI_DEVICE_ID_MIRO_36050 0x5601
+
+#define PCI_VENDOR_ID_NEC 0x1033
+#define PCI_DEVICE_ID_NEC_PCX2 0x0046
+
+#define PCI_VENDOR_ID_FD 0x1036
+#define PCI_DEVICE_ID_FD_36C70 0x0000
+
+#define PCI_VENDOR_ID_SI 0x1039
+#define PCI_DEVICE_ID_SI_5591_AGP 0x0001
+#define PCI_DEVICE_ID_SI_6202 0x0002
+#define PCI_DEVICE_ID_SI_503 0x0008
+#define PCI_DEVICE_ID_SI_ACPI 0x0009
+#define PCI_DEVICE_ID_SI_5597_VGA 0x0200
+#define PCI_DEVICE_ID_SI_6205 0x0205
+#define PCI_DEVICE_ID_SI_501 0x0406
+#define PCI_DEVICE_ID_SI_496 0x0496
+#define PCI_DEVICE_ID_SI_601 0x0601
+#define PCI_DEVICE_ID_SI_5107 0x5107
+#define PCI_DEVICE_ID_SI_5511 0x5511
+#define PCI_DEVICE_ID_SI_5513 0x5513
+#define PCI_DEVICE_ID_SI_5571 0x5571
+#define PCI_DEVICE_ID_SI_5591 0x5591
+#define PCI_DEVICE_ID_SI_5597 0x5597
+#define PCI_DEVICE_ID_SI_7001 0x7001
+
+#define PCI_VENDOR_ID_HP 0x103c
+#define PCI_DEVICE_ID_HP_J2585A 0x1030
+#define PCI_DEVICE_ID_HP_J2585B 0x1031
+
+#define PCI_VENDOR_ID_PCTECH 0x1042
+#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000
+#define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001
+#define PCI_DEVICE_ID_PCTECH_SAMURAI_0 0x3000
+#define PCI_DEVICE_ID_PCTECH_SAMURAI_1 0x3010
+#define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020
+
+#define PCI_VENDOR_ID_DPT 0x1044
+#define PCI_DEVICE_ID_DPT 0xa400
+
+#define PCI_VENDOR_ID_OPTI 0x1045
+#define PCI_DEVICE_ID_OPTI_92C178 0xc178
+#define PCI_DEVICE_ID_OPTI_82C557 0xc557
+#define PCI_DEVICE_ID_OPTI_82C558 0xc558
+#define PCI_DEVICE_ID_OPTI_82C621 0xc621
+#define PCI_DEVICE_ID_OPTI_82C700 0xc700
+#define PCI_DEVICE_ID_OPTI_82C701 0xc701
+#define PCI_DEVICE_ID_OPTI_82C814 0xc814
+#define PCI_DEVICE_ID_OPTI_82C822 0xc822
+#define PCI_DEVICE_ID_OPTI_82C825 0xd568
+
+#define PCI_VENDOR_ID_SGS 0x104a
+#define PCI_DEVICE_ID_SGS_2000 0x0008
+#define PCI_DEVICE_ID_SGS_1764 0x0009
+
+#define PCI_VENDOR_ID_BUSLOGIC 0x104B
+#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
+#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040
+#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130
+
+#define PCI_VENDOR_ID_TI 0x104c
+#define PCI_DEVICE_ID_TI_TVP4010 0x3d04
+#define PCI_DEVICE_ID_TI_TVP4020 0x3d07
+#define PCI_DEVICE_ID_TI_PCI1130 0xac12
+#define PCI_DEVICE_ID_TI_PCI1031 0xac13
+#define PCI_DEVICE_ID_TI_PCI1131 0xac15
+#define PCI_DEVICE_ID_TI_PCI1250 0xac16
+#define PCI_DEVICE_ID_TI_PCI1220 0xac17
+
+#define PCI_VENDOR_ID_OAK 0x104e
+#define PCI_DEVICE_ID_OAK_OTI107 0x0107
+
+#define PCI_VENDOR_ID_WINBOND2 0x1050
+#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940
+
+#define PCI_VENDOR_ID_MOTOROLA 0x1057
+#define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001
+#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002
+#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801
+
+#define PCI_VENDOR_ID_PROMISE 0x105a
+#define PCI_DEVICE_ID_PROMISE_20246 0x4d33
+#define PCI_DEVICE_ID_PROMISE_5300 0x5300
+
+#define PCI_VENDOR_ID_N9 0x105d
+#define PCI_DEVICE_ID_N9_I128 0x2309
+#define PCI_DEVICE_ID_N9_I128_2 0x2339
+#define PCI_DEVICE_ID_N9_I128_T2R 0x493d
+
+#define PCI_VENDOR_ID_UMC 0x1060
+#define PCI_DEVICE_ID_UMC_UM8673F 0x0101
+#define PCI_DEVICE_ID_UMC_UM8891A 0x0891
+#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a
+#define PCI_DEVICE_ID_UMC_UM8886A 0x886a
+#define PCI_DEVICE_ID_UMC_UM8881F 0x8881
+#define PCI_DEVICE_ID_UMC_UM8886F 0x8886
+#define PCI_DEVICE_ID_UMC_UM9017F 0x9017
+#define PCI_DEVICE_ID_UMC_UM8886N 0xe886
+#define PCI_DEVICE_ID_UMC_UM8891N 0xe891
+
+#define PCI_VENDOR_ID_X 0x1061
+#define PCI_DEVICE_ID_X_AGX016 0x0001
+
+#define PCI_VENDOR_ID_PICOP 0x1066
+#define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001
+#define PCI_DEVICE_ID_PICOP_PT80C524 0x8002
+
+#define PCI_VENDOR_ID_APPLE 0x106b
+#define PCI_DEVICE_ID_APPLE_BANDIT 0x0001
+#define PCI_DEVICE_ID_APPLE_GC 0x0002
+#define PCI_DEVICE_ID_APPLE_HYDRA 0x000e
+
+#define PCI_VENDOR_ID_NEXGEN 0x1074
+#define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78
+
+#define PCI_VENDOR_ID_QLOGIC 0x1077
+#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020
+#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022
+
+#define PCI_VENDOR_ID_CYRIX 0x1078
+#define PCI_DEVICE_ID_CYRIX_5510 0x0000
+#define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001
+#define PCI_DEVICE_ID_CYRIX_5520 0x0002
+#define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100
+#define PCI_DEVICE_ID_CYRIX_5530_SMI 0x0101
+#define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102
+#define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103
+#define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104
+
+#define PCI_VENDOR_ID_LEADTEK 0x107d
+#define PCI_DEVICE_ID_LEADTEK_805 0x0000
+
+#define PCI_VENDOR_ID_CONTAQ 0x1080
+#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600
+#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693
+
+#define PCI_VENDOR_ID_FOREX 0x1083
+
+#define PCI_VENDOR_ID_OLICOM 0x108d
+#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001
+#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011
+#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012
+#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013
+#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014
+#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021
+
+#define PCI_VENDOR_ID_SUN 0x108e
+#define PCI_DEVICE_ID_SUN_EBUS 0x1000
+#define PCI_DEVICE_ID_SUN_HAPPYMEAL 0x1001
+#define PCI_DEVICE_ID_SUN_SIMBA 0x5000
+#define PCI_DEVICE_ID_SUN_PBM 0x8000
+#define PCI_DEVICE_ID_SUN_SABRE 0xa000
+
+#define PCI_VENDOR_ID_CMD 0x1095
+#define PCI_DEVICE_ID_CMD_640 0x0640
+#define PCI_DEVICE_ID_CMD_643 0x0643
+#define PCI_DEVICE_ID_CMD_646 0x0646
+#define PCI_DEVICE_ID_CMD_647 0x0647
+#define PCI_DEVICE_ID_CMD_670 0x0670
+
+#define PCI_VENDOR_ID_VISION 0x1098
+#define PCI_DEVICE_ID_VISION_QD8500 0x0001
+#define PCI_DEVICE_ID_VISION_QD8580 0x0002
+
+#define PCI_VENDOR_ID_BROOKTREE 0x109e
+#define PCI_DEVICE_ID_BROOKTREE_848 0x0350
+#define PCI_DEVICE_ID_BROOKTREE_849A 0x0351
+#define PCI_DEVICE_ID_BROOKTREE_8474 0x8474
+
+#define PCI_VENDOR_ID_SIERRA 0x10a8
+#define PCI_DEVICE_ID_SIERRA_STB 0x0000
+
+#define PCI_VENDOR_ID_ACC 0x10aa
+#define PCI_DEVICE_ID_ACC_2056 0x0000
+
+#define PCI_VENDOR_ID_WINBOND 0x10ad
+#define PCI_DEVICE_ID_WINBOND_83769 0x0001
+#define PCI_DEVICE_ID_WINBOND_82C105 0x0105
+#define PCI_DEVICE_ID_WINBOND_83C553 0x0565
+
+#define PCI_VENDOR_ID_DATABOOK 0x10b3
+#define PCI_DEVICE_ID_DATABOOK_87144 0xb106
+
+#define PCI_VENDOR_ID_PLX 0x10b5
+#define PCI_DEVICE_ID_PLX_9050 0x9050
+#define PCI_DEVICE_ID_PLX_9060 0x9060
+#define PCI_DEVICE_ID_PLX_9060ES 0x906E
+#define PCI_DEVICE_ID_PLX_9060SD 0x906D
+#define PCI_DEVICE_ID_PLX_9080 0x9080
+
+#define PCI_VENDOR_ID_MADGE 0x10b6
+#define PCI_DEVICE_ID_MADGE_MK2 0x0002
+#define PCI_DEVICE_ID_MADGE_C155S 0x1001
+
+#define PCI_VENDOR_ID_3COM 0x10b7
+#define PCI_DEVICE_ID_3COM_3C339 0x3390
+#define PCI_DEVICE_ID_3COM_3C590 0x5900
+#define PCI_DEVICE_ID_3COM_3C595TX 0x5950
+#define PCI_DEVICE_ID_3COM_3C595T4 0x5951
+#define PCI_DEVICE_ID_3COM_3C595MII 0x5952
+#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000
+#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001
+#define PCI_DEVICE_ID_3COM_3C905TX 0x9050
+#define PCI_DEVICE_ID_3COM_3C905T4 0x9051
+#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055
+
+#define PCI_VENDOR_ID_SMC 0x10b8
+#define PCI_DEVICE_ID_SMC_EPIC100 0x0005
+
+#define PCI_VENDOR_ID_AL 0x10b9
+#define PCI_DEVICE_ID_AL_M1445 0x1445
+#define PCI_DEVICE_ID_AL_M1449 0x1449
+#define PCI_DEVICE_ID_AL_M1451 0x1451
+#define PCI_DEVICE_ID_AL_M1461 0x1461
+#define PCI_DEVICE_ID_AL_M1489 0x1489
+#define PCI_DEVICE_ID_AL_M1511 0x1511
+#define PCI_DEVICE_ID_AL_M1513 0x1513
+#define PCI_DEVICE_ID_AL_M1521 0x1521
+#define PCI_DEVICE_ID_AL_M1523 0x1523
+#define PCI_DEVICE_ID_AL_M1531 0x1531
+#define PCI_DEVICE_ID_AL_M1533 0x1533
+#define PCI_DEVICE_ID_AL_M3307 0x3307
+#define PCI_DEVICE_ID_AL_M4803 0x5215
+#define PCI_DEVICE_ID_AL_M5219 0x5219
+#define PCI_DEVICE_ID_AL_M5229 0x5229
+#define PCI_DEVICE_ID_AL_M5237 0x5237
+#define PCI_DEVICE_ID_AL_M7101 0x7101
+
+#define PCI_VENDOR_ID_MITSUBISHI 0x10ba
+
+#define PCI_VENDOR_ID_SURECOM 0x10bd
+#define PCI_DEVICE_ID_SURECOM_NE34 0x0e34
+
+#define PCI_VENDOR_ID_NEOMAGIC 0x10c8
+#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001
+#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002
+#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003
+#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004
+
+#define PCI_VENDOR_ID_ASP 0x10cd
+#define PCI_DEVICE_ID_ASP_ABP940 0x1200
+#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
+#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
+
+#define PCI_VENDOR_ID_MACRONIX 0x10d9
+#define PCI_DEVICE_ID_MACRONIX_MX98713 0x0512
+#define PCI_DEVICE_ID_MACRONIX_MX987x5 0x0531
+
+#define PCI_VENDOR_ID_CERN 0x10dc
+#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001
+#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002
+#define PCI_DEVICE_ID_CERN_HIPPI_DST 0x0021
+#define PCI_DEVICE_ID_CERN_HIPPI_SRC 0x0022
+
+#define PCI_VENDOR_ID_NVIDIA 0x10de
+
+#define PCI_VENDOR_ID_IMS 0x10e0
+#define PCI_DEVICE_ID_IMS_8849 0x8849
+
+#define PCI_VENDOR_ID_TEKRAM2 0x10e1
+#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c
+
+#define PCI_VENDOR_ID_TUNDRA 0x10e3
+#define PCI_DEVICE_ID_TUNDRA_CA91C042 0x0000
+
+#define PCI_VENDOR_ID_AMCC 0x10e8
+#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043
+#define PCI_DEVICE_ID_AMCC_PARASTATION 0x8062
+#define PCI_DEVICE_ID_AMCC_S5933 0x807d
+#define PCI_DEVICE_ID_AMCC_S5933_HEPC3 0x809c
+
+#define PCI_VENDOR_ID_INTERG 0x10ea
+#define PCI_DEVICE_ID_INTERG_1680 0x1680
+#define PCI_DEVICE_ID_INTERG_1682 0x1682
+
+#define PCI_VENDOR_ID_REALTEK 0x10ec
+#define PCI_DEVICE_ID_REALTEK_8029 0x8029
+#define PCI_DEVICE_ID_REALTEK_8129 0x8129
+#define PCI_DEVICE_ID_REALTEK_8139 0x8139
+
+#define PCI_VENDOR_ID_TRUEVISION 0x10fa
+#define PCI_DEVICE_ID_TRUEVISION_T1000 0x000c
+
+#define PCI_VENDOR_ID_INIT 0x1101
+#define PCI_DEVICE_ID_INIT_320P 0x9100
+#define PCI_DEVICE_ID_INIT_360P 0x9500
+
+#define PCI_VENDOR_ID_TTI 0x1103
+#define PCI_DEVICE_ID_TTI_HPT343 0x0003
+
+#define PCI_VENDOR_ID_VIA 0x1106
+#define PCI_DEVICE_ID_VIA_82C505 0x0505
+#define PCI_DEVICE_ID_VIA_82C561 0x0561
+#define PCI_DEVICE_ID_VIA_82C586_1 0x0571
+#define PCI_DEVICE_ID_VIA_82C576 0x0576
+#define PCI_DEVICE_ID_VIA_82C585 0x0585
+#define PCI_DEVICE_ID_VIA_82C586_0 0x0586
+#define PCI_DEVICE_ID_VIA_82C595 0x0595
+#define PCI_DEVICE_ID_VIA_82C597_0 0x0597
+#define PCI_DEVICE_ID_VIA_82C926 0x0926
+#define PCI_DEVICE_ID_VIA_82C416 0x1571
+#define PCI_DEVICE_ID_VIA_82C595_97 0x1595
+#define PCI_DEVICE_ID_VIA_82C586_2 0x3038
+#define PCI_DEVICE_ID_VIA_82C586_3 0x3040
+#define PCI_DEVICE_ID_VIA_86C100A 0x6100
+#define PCI_DEVICE_ID_VIA_82C597_1 0x8597
+
+#define PCI_VENDOR_ID_VORTEX 0x1119
+#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000
+#define PCI_DEVICE_ID_VORTEX_GDT6000B 0x0001
+#define PCI_DEVICE_ID_VORTEX_GDT6x10 0x0002
+#define PCI_DEVICE_ID_VORTEX_GDT6x20 0x0003
+#define PCI_DEVICE_ID_VORTEX_GDT6530 0x0004
+#define PCI_DEVICE_ID_VORTEX_GDT6550 0x0005
+#define PCI_DEVICE_ID_VORTEX_GDT6x17 0x0006
+#define PCI_DEVICE_ID_VORTEX_GDT6x27 0x0007
+#define PCI_DEVICE_ID_VORTEX_GDT6537 0x0008
+#define PCI_DEVICE_ID_VORTEX_GDT6557 0x0009
+#define PCI_DEVICE_ID_VORTEX_GDT6x15 0x000a
+#define PCI_DEVICE_ID_VORTEX_GDT6x25 0x000b
+#define PCI_DEVICE_ID_VORTEX_GDT6535 0x000c
+#define PCI_DEVICE_ID_VORTEX_GDT6555 0x000d
+#define PCI_DEVICE_ID_VORTEX_GDT6x17RP 0x0100
+#define PCI_DEVICE_ID_VORTEX_GDT6x27RP 0x0101
+#define PCI_DEVICE_ID_VORTEX_GDT6537RP 0x0102
+#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103
+#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104
+#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105
+#define PCI_DEVICE_ID_VORTEX_GDT6x17RP1 0x0110
+#define PCI_DEVICE_ID_VORTEX_GDT6x27RP1 0x0111
+#define PCI_DEVICE_ID_VORTEX_GDT6537RP1 0x0112
+#define PCI_DEVICE_ID_VORTEX_GDT6557RP1 0x0113
+#define PCI_DEVICE_ID_VORTEX_GDT6x11RP1 0x0114
+#define PCI_DEVICE_ID_VORTEX_GDT6x21RP1 0x0115
+#define PCI_DEVICE_ID_VORTEX_GDT6x17RP2 0x0120
+#define PCI_DEVICE_ID_VORTEX_GDT6x27RP2 0x0121
+#define PCI_DEVICE_ID_VORTEX_GDT6537RP2 0x0122
+#define PCI_DEVICE_ID_VORTEX_GDT6557RP2 0x0123
+#define PCI_DEVICE_ID_VORTEX_GDT6x11RP2 0x0124
+#define PCI_DEVICE_ID_VORTEX_GDT6x21RP2 0x0125
+
+#define PCI_VENDOR_ID_EF 0x111a
+#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000
+#define PCI_DEVICE_ID_EF_ATM_ASIC 0x0002
+
+#define PCI_VENDOR_ID_FORE 0x1127
+#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210
+#define PCI_DEVICE_ID_FORE_PCA200E 0x0300
+
+#define PCI_VENDOR_ID_IMAGINGTECH 0x112f
+#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000
+
+#define PCI_VENDOR_ID_PHILIPS 0x1131
+#define PCI_DEVICE_ID_PHILIPS_SAA7145 0x7145
+#define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146
+
+#define PCI_VENDOR_ID_CYCLONE 0x113c
+#define PCI_DEVICE_ID_CYCLONE_SDK 0x0001
+
+#define PCI_VENDOR_ID_ALLIANCE 0x1142
+#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO 0x3210
+#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422
+#define PCI_DEVICE_ID_ALLIANCE_AT24 0x6424
+#define PCI_DEVICE_ID_ALLIANCE_AT3D 0x643d
+
+#define PCI_VENDOR_ID_SK 0x1148
+#define PCI_DEVICE_ID_SK_FP 0x4000
+#define PCI_DEVICE_ID_SK_TR 0x4200
+#define PCI_DEVICE_ID_SK_GE 0x4300
+
+#define PCI_VENDOR_ID_VMIC 0x114a
+#define PCI_DEVICE_ID_VMIC_VME 0x7587
+
+#define PCI_VENDOR_ID_DIGI 0x114f
+#define PCI_DEVICE_ID_DIGI_EPC 0x0002
+#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH 0x0003
+#define PCI_DEVICE_ID_DIGI_XEM 0x0004
+#define PCI_DEVICE_ID_DIGI_XR 0x0005
+#define PCI_DEVICE_ID_DIGI_CX 0x0006
+#define PCI_DEVICE_ID_DIGI_XRJ 0x0009
+#define PCI_DEVICE_ID_DIGI_EPCJ 0x000a
+#define PCI_DEVICE_ID_DIGI_XR_920 0x0027
+
+#define PCI_VENDOR_ID_MUTECH 0x1159
+#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001
+
+#define PCI_VENDOR_ID_RENDITION 0x1163
+#define PCI_DEVICE_ID_RENDITION_VERITE 0x0001
+#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000
+
+#define PCI_VENDOR_ID_TOSHIBA 0x1179
+#define PCI_DEVICE_ID_TOSHIBA_601 0x0601
+#define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a
+#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f
+
+#define PCI_VENDOR_ID_RICOH 0x1180
+#define PCI_DEVICE_ID_RICOH_RL5C465 0x0465
+#define PCI_DEVICE_ID_RICOH_RL5C466 0x0466
+#define PCI_DEVICE_ID_RICOH_RL5C475 0x0475
+#define PCI_DEVICE_ID_RICOH_RL5C478 0x0478
+
+#define PCI_VENDOR_ID_ARTOP 0x1191
+#define PCI_DEVICE_ID_ARTOP_ATP8400 0x0004
+#define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005
+
+#define PCI_VENDOR_ID_ZEITNET 0x1193
+#define PCI_DEVICE_ID_ZEITNET_1221 0x0001
+#define PCI_DEVICE_ID_ZEITNET_1225 0x0002
+
+#define PCI_VENDOR_ID_OMEGA 0x119b
+#define PCI_DEVICE_ID_OMEGA_82C092G 0x1221
+
+#define PCI_VENDOR_ID_LITEON 0x11ad
+#define PCI_DEVICE_ID_LITEON_LNE100TX 0x0002
+
+#define PCI_VENDOR_ID_NP 0x11bc
+#define PCI_DEVICE_ID_NP_PCI_FDDI 0x0001
+
+#define PCI_VENDOR_ID_ATT 0x11c1
+#define PCI_DEVICE_ID_ATT_L56XMF 0x0440
+
+#define PCI_VENDOR_ID_SPECIALIX 0x11cb
+#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000
+#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000
+#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000
+
+#define PCI_VENDOR_ID_AURAVISION 0x11d1
+#define PCI_DEVICE_ID_AURAVISION_VXP524 0x01f7
+
+#define PCI_VENDOR_ID_IKON 0x11d5
+#define PCI_DEVICE_ID_IKON_10115 0x0115
+#define PCI_DEVICE_ID_IKON_10117 0x0117
+
+#define PCI_VENDOR_ID_ZORAN 0x11de
+#define PCI_DEVICE_ID_ZORAN_36057 0x6057
+#define PCI_DEVICE_ID_ZORAN_36120 0x6120
+
+#define PCI_VENDOR_ID_KINETIC 0x11f4
+#define PCI_DEVICE_ID_KINETIC_2915 0x2915
+
+#define PCI_VENDOR_ID_COMPEX 0x11f6
+#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112
+#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
+
+#define PCI_VENDOR_ID_RP 0x11fe
+#define PCI_DEVICE_ID_RP32INTF 0x0001
+#define PCI_DEVICE_ID_RP8INTF 0x0002
+#define PCI_DEVICE_ID_RP16INTF 0x0003
+#define PCI_DEVICE_ID_RP4QUAD 0x0004
+#define PCI_DEVICE_ID_RP8OCTA 0x0005
+#define PCI_DEVICE_ID_RP8J 0x0006
+#define PCI_DEVICE_ID_RPP4 0x000A
+#define PCI_DEVICE_ID_RPP8 0x000B
+#define PCI_DEVICE_ID_RP8M 0x000C
+
+#define PCI_VENDOR_ID_CYCLADES 0x120e
+#define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100
+#define PCI_DEVICE_ID_CYCLOM_Y_Hi 0x0101
+#define PCI_DEVICE_ID_CYCLOM_Z_Lo 0x0200
+#define PCI_DEVICE_ID_CYCLOM_Z_Hi 0x0201
+
+#define PCI_VENDOR_ID_ESSENTIAL 0x120f
+#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001
+
+#define PCI_VENDOR_ID_O2 0x1217
+#define PCI_DEVICE_ID_O2_6729 0x6729
+#define PCI_DEVICE_ID_O2_6730 0x673a
+#define PCI_DEVICE_ID_O2_6832 0x6832
+#define PCI_DEVICE_ID_O2_6836 0x6836
+
+#define PCI_VENDOR_ID_3DFX 0x121a
+#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001
+#define PCI_DEVICE_ID_3DFX_VOODOO2 0x0002
+
+#define PCI_VENDOR_ID_SIGMADES 0x1236
+#define PCI_DEVICE_ID_SIGMADES_6425 0x6401
+
+#define PCI_VENDOR_ID_CCUBE 0x123f
+
+#define PCI_VENDOR_ID_DIPIX 0x1246
+
+#define PCI_VENDOR_ID_STALLION 0x124d
+#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000
+#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002
+#define PCI_DEVICE_ID_STALLION_EIOPCI 0x0003
+
+#define PCI_VENDOR_ID_OPTIBASE 0x1255
+#define PCI_DEVICE_ID_OPTIBASE_FORGE 0x1110
+#define PCI_DEVICE_ID_OPTIBASE_FUSION 0x1210
+#define PCI_DEVICE_ID_OPTIBASE_VPLEX 0x2110
+#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC 0x2120
+#define PCI_DEVICE_ID_OPTIBASE_VQUEST 0x2130
+
+#define PCI_VENDOR_ID_SATSAGEM 0x1267
+#define PCI_DEVICE_ID_SATSAGEM_PCR2101 0x5352
+#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b
+
+#define PCI_VENDOR_ID_HUGHES 0x1273
+#define PCI_DEVICE_ID_HUGHES_DIRECPC 0x0002
+
+#define PCI_VENDOR_ID_ENSONIQ 0x1274
+#define PCI_DEVICE_ID_ENSONIQ_AUDIOPCI 0x5000
+
+#define PCI_VENDOR_ID_ALTEON 0x12ae
+#define PCI_DEVICE_ID_ALTEON_ACENIC 0x0001
+
+#define PCI_VENDOR_ID_PICTUREL 0x12c5
+#define PCI_DEVICE_ID_PICTUREL_PCIVST 0x0081
+
+#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2
+#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
+
+#define PCI_VENDOR_ID_CBOARDS 0x1307
+#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001
+
+#define PCI_VENDOR_ID_SYMPHONY 0x1c1c
+#define PCI_DEVICE_ID_SYMPHONY_101 0x0001
+
+#define PCI_VENDOR_ID_TEKRAM 0x1de1
+#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
+
+#define PCI_VENDOR_ID_3DLABS 0x3d3d
+#define PCI_DEVICE_ID_3DLABS_300SX 0x0001
+#define PCI_DEVICE_ID_3DLABS_500TX 0x0002
+#define PCI_DEVICE_ID_3DLABS_DELTA 0x0003
+#define PCI_DEVICE_ID_3DLABS_PERMEDIA 0x0004
+#define PCI_DEVICE_ID_3DLABS_MX 0x0006
+
+#define PCI_VENDOR_ID_AVANCE 0x4005
+#define PCI_DEVICE_ID_AVANCE_ALG2064 0x2064
+#define PCI_DEVICE_ID_AVANCE_2302 0x2302
+
+#define PCI_VENDOR_ID_NETVIN 0x4a14
+#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000
+
+#define PCI_VENDOR_ID_S3 0x5333
+#define PCI_DEVICE_ID_S3_PLATO_PXS 0x0551
+#define PCI_DEVICE_ID_S3_ViRGE 0x5631
+#define PCI_DEVICE_ID_S3_TRIO 0x8811
+#define PCI_DEVICE_ID_S3_AURORA64VP 0x8812
+#define PCI_DEVICE_ID_S3_TRIO64UVP 0x8814
+#define PCI_DEVICE_ID_S3_ViRGE_VX 0x883d
+#define PCI_DEVICE_ID_S3_868 0x8880
+#define PCI_DEVICE_ID_S3_928 0x88b0
+#define PCI_DEVICE_ID_S3_864_1 0x88c0
+#define PCI_DEVICE_ID_S3_864_2 0x88c1
+#define PCI_DEVICE_ID_S3_964_1 0x88d0
+#define PCI_DEVICE_ID_S3_964_2 0x88d1
+#define PCI_DEVICE_ID_S3_968 0x88f0
+#define PCI_DEVICE_ID_S3_TRIO64V2 0x8901
+#define PCI_DEVICE_ID_S3_PLATO_PXG 0x8902
+#define PCI_DEVICE_ID_S3_ViRGE_DXGX 0x8a01
+#define PCI_DEVICE_ID_S3_ViRGE_GX2 0x8a10
+#define PCI_DEVICE_ID_S3_ViRGE_MX 0x8c01
+#define PCI_DEVICE_ID_S3_ViRGE_MXP 0x8c02
+#define PCI_DEVICE_ID_S3_ViRGE_MXPMV 0x8c03
+#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00
+
+#define PCI_VENDOR_ID_INTEL 0x8086
+#define PCI_DEVICE_ID_INTEL_82375 0x0482
+#define PCI_DEVICE_ID_INTEL_82424 0x0483
+#define PCI_DEVICE_ID_INTEL_82378 0x0484
+#define PCI_DEVICE_ID_INTEL_82430 0x0486
+#define PCI_DEVICE_ID_INTEL_82434 0x04a3
+#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221
+#define PCI_DEVICE_ID_INTEL_82092AA_1 0x1222
+#define PCI_DEVICE_ID_INTEL_7116 0x1223
+#define PCI_DEVICE_ID_INTEL_82596 0x1226
+#define PCI_DEVICE_ID_INTEL_82865 0x1227
+#define PCI_DEVICE_ID_INTEL_82557 0x1229
+#define PCI_DEVICE_ID_INTEL_82437 0x122d
+#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e
+#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230
+#define PCI_DEVICE_ID_INTEL_82371MX 0x1234
+#define PCI_DEVICE_ID_INTEL_82437MX 0x1235
+#define PCI_DEVICE_ID_INTEL_82441 0x1237
+#define PCI_DEVICE_ID_INTEL_82380FB 0x124b
+#define PCI_DEVICE_ID_INTEL_82439 0x1250
+#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
+#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
+#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020
+#define PCI_DEVICE_ID_INTEL_82437VX 0x7030
+#define PCI_DEVICE_ID_INTEL_82439TX 0x7100
+#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
+#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
+#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
+#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
+#define PCI_DEVICE_ID_INTEL_82443LX_0 0x7180
+#define PCI_DEVICE_ID_INTEL_82443LX_1 0x7181
+#define PCI_DEVICE_ID_INTEL_82443BX_0 0x7190
+#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191
+#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192
+#define PCI_DEVICE_ID_INTEL_P6 0x84c4
+#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
+
+#define PCI_VENDOR_ID_KTI 0x8e2e
+#define PCI_DEVICE_ID_KTI_ET32P2 0x3000
+
+#define PCI_VENDOR_ID_ADAPTEC 0x9004
+#define PCI_DEVICE_ID_ADAPTEC_7810 0x1078
+#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078
+#define PCI_DEVICE_ID_ADAPTEC_7855 0x5578
+#define PCI_DEVICE_ID_ADAPTEC_5800 0x5800
+#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075
+#define PCI_DEVICE_ID_ADAPTEC_7860 0x6078
+#define PCI_DEVICE_ID_ADAPTEC_7861 0x6178
+#define PCI_DEVICE_ID_ADAPTEC_7870 0x7078
+#define PCI_DEVICE_ID_ADAPTEC_7871 0x7178
+#define PCI_DEVICE_ID_ADAPTEC_7872 0x7278
+#define PCI_DEVICE_ID_ADAPTEC_7873 0x7378
+#define PCI_DEVICE_ID_ADAPTEC_7874 0x7478
+#define PCI_DEVICE_ID_ADAPTEC_7895 0x7895
+#define PCI_DEVICE_ID_ADAPTEC_7880 0x8078
+#define PCI_DEVICE_ID_ADAPTEC_7881 0x8178
+#define PCI_DEVICE_ID_ADAPTEC_7882 0x8278
+#define PCI_DEVICE_ID_ADAPTEC_7883 0x8378
+#define PCI_DEVICE_ID_ADAPTEC_7884 0x8478
+#define PCI_DEVICE_ID_ADAPTEC_1030 0x8b78
+
+#define PCI_VENDOR_ID_ADAPTEC2 0x9005
+#define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010
+#define PCI_DEVICE_ID_ADAPTEC2_7890 0x001f
+#define PCI_DEVICE_ID_ADAPTEC2_3940U2 0x0050
+#define PCI_DEVICE_ID_ADAPTEC2_7896 0x005f
+
+#define PCI_VENDOR_ID_ATRONICS 0x907f
+#define PCI_DEVICE_ID_ATRONICS_2015 0x2015
+
+#define PCI_VENDOR_ID_HOLTEK 0x9412
+#define PCI_DEVICE_ID_HOLTEK_6565 0x6565
+
+#define PCI_VENDOR_ID_TIGERJET 0xe159
+#define PCI_DEVICE_ID_TIGERJET_300 0x0001
+
+#define PCI_VENDOR_ID_ARK 0xedd8
+#define PCI_DEVICE_ID_ARK_STING 0xa091
+#define PCI_DEVICE_ID_ARK_STINGARK 0xa099
+#define PCI_DEVICE_ID_ARK_2000MT 0xa0a1
+/*
+ * The PCI interface treats multi-function devices as independent
+ * devices. The slot/function address of each device is encoded
+ * in a single byte as follows:
+ *
+ * 7:3 = slot
+ * 2:0 = function
+ */
+#define PCI_DEVFN(_slot,_func) ((((_slot) & 0x1f) << 3) | ((_func) & 0x07))
+#define PCI_SLOT(_devfn) (((_devfn) >> 3) & 0x1f)
+#define PCI_FUNC(_devfn) ((_devfn) & 0x07)
+
+/*
+ * Error values that may be returned by the PCI bios.
+ */
+#define PCIBIOS_SUCCESSFUL 0x00
+#define PCIBIOS_FUNC_NOT_SUPPORTED 0x81
+#define PCIBIOS_BAD_VENDOR_ID 0x83
+#define PCIBIOS_DEVICE_NOT_FOUND 0x86
+#define PCIBIOS_BAD_REGISTER_NUMBER 0x87
+#define PCIBIOS_SET_FAILED 0x88
+#define PCIBIOS_BUFFER_TOO_SMALL 0x89
+
+/* T. Straumann, 7/31/2001: increased to 32 - PMC slots are not
+ * scanned on mvme2306 otherwise
+ */
+#define PCI_MAX_DEVICES 32
+#define PCI_MAX_FUNCTIONS 8
+
+typedef struct {
+ int (*read_config_byte)(unsigned char, unsigned char, unsigned char,
+ unsigned char, unsigned char *);
+ int (*read_config_word)(unsigned char, unsigned char, unsigned char,
+ unsigned char, unsigned short *);
+ int (*read_config_dword)(unsigned char, unsigned char, unsigned char,
+ unsigned char, unsigned int *);
+ int (*write_config_byte)(unsigned char, unsigned char, unsigned char,
+ unsigned char, unsigned char);
+ int (*write_config_word)(unsigned char, unsigned char, unsigned char,
+ unsigned char, unsigned short);
+ int (*write_config_dword)(unsigned char, unsigned char, unsigned char,
+ unsigned char, unsigned int);
+} pci_config_access_functions;
+
+/* Error codes for pci_initialize */
+#define PCIB_ERR_SUCCESS (0)
+#define PCIB_ERR_UNINITIALIZED (-1) /* PCI BIOS is not initilized */
+#define PCIB_ERR_NOTPRESENT (-2) /* PCI BIOS not present */
+#define PCIB_ERR_NOFUNC (-3) /* Function not supported */
+#define PCIB_ERR_BADVENDOR (-4) /* Bad Vendor ID */
+#define PCIB_ERR_DEVNOTFOUND (-5) /* Device not found */
+#define PCIB_ERR_BADREG (-6) /* Bad register number */
+
+extern int pci_initialize();
+
+typedef struct {
+ volatile unsigned char* pci_config_addr;
+ volatile unsigned char* pci_config_data;
+ const pci_config_access_functions* pci_functions;
+} pci_config;
+
+extern pci_config BSP_pci_configuration;
+
+extern inline int
+pci_read_config_byte(
+ unsigned char bus,
+ unsigned char slot,
+ unsigned char function,
+ unsigned char where,
+ unsigned char * val)
+{
+ return BSP_pci_configuration.pci_functions->read_config_byte(
+ bus, slot, function, where, val);
+}
+
+extern inline int
+pci_read_config_word(
+ unsigned char bus,
+ unsigned char slot,
+ unsigned char function,
+ unsigned char where,
+ unsigned short * val)
+{
+ return BSP_pci_configuration.pci_functions->read_config_word(
+ bus, slot, function, where, val);
+}
+
+extern inline int
+pci_read_config_dword(
+ unsigned char bus,
+ unsigned char slot,
+ unsigned char function,
+ unsigned char where,
+ unsigned int * val)
+{
+ return BSP_pci_configuration.pci_functions->read_config_dword(bus, slot, function, where, val);
+}
+
+extern inline int
+pci_write_config_byte(
+ unsigned char bus,
+ unsigned char slot,
+ unsigned char function,
+ unsigned char where,
+ unsigned char val)
+{
+ return BSP_pci_configuration.pci_functions->write_config_byte(
+ bus, slot, function, where, val);
+}
+
+extern inline int
+pci_write_config_word(
+ unsigned char bus,
+ unsigned char slot,
+ unsigned char function,
+ unsigned char where,
+ unsigned short val)
+{
+ return BSP_pci_configuration.pci_functions->write_config_word(
+ bus, slot, function, where, val);
+}
+
+extern inline int
+pci_write_config_dword(
+ unsigned char bus,
+ unsigned char slot,
+ unsigned char function,
+ unsigned char where,
+ unsigned int val)
+{
+ return BSP_pci_configuration.pci_functions->write_config_dword(
+ bus, slot, function, where, val);
+}
+
+/* scan for a specific device */
+/* find a particular PCI device
+ * (currently, only bus0 is scanned for device/fun0)
+ *
+ * RETURNS: zero on success, bus/dev/fun in *pbus / *pdev / *pfun
+ */
+int
+pci_find_device(
+ unsigned short vendorid,
+ unsigned short deviceid,
+ int instance,
+ int *pbus,
+ int *pdev,
+ int *pfun
+);
+
+/*
+ * Return the number of PCI busses in the system
+ */
+extern unsigned char pci_bus_count();
+
+#endif /* _RTEMS_PCI_H */
diff --git a/cpukit/include/rtems/stdint.h b/cpukit/include/rtems/stdint.h
new file mode 100644
index 0000000000..cdd4934198
--- /dev/null
+++ b/cpukit/include/rtems/stdint.h
@@ -0,0 +1,40 @@
+/**
+ * @file rtems/stdint.h
+ *
+ * Wrapper to <stdint.h>, switching to <inttypes.h> on systems
+ * only having <inttypes.h> (e.g. Solaris-5.7).
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RTEMS_STDINT_H
+#define _RTEMS_STDINT_H
+
+#include <rtems/score/cpuopts.h>
+
+#if RTEMS_USES_STDINT_H
+#include <stdint.h>
+
+#else
+#include <inttypes.h>
+#endif
+
+#if RTEMS_DEPRECATED_TYPES
+typedef uint8_t unsigned8; /* unsigned 8-bit integer */
+typedef uint16_t unsigned16; /* unsigned 16-bit integer */
+typedef uint32_t unsigned32; /* unsigned 32-bit integer */
+#if 0
+typedef uint64_t unsigned64; /* unsigned 64-bit integer */
+#endif
+
+typedef int8_t signed8; /* signed 8-bit integer */
+typedef int16_t signed16; /* signed 16-bit integer */
+typedef int32_t signed32; /* signed 32-bit integer */
+#if 0
+typedef int64_t signed64; /* signed 64-bit integer */
+#endif
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/tar.h b/cpukit/include/rtems/tar.h
new file mode 100644
index 0000000000..4be7b90f64
--- /dev/null
+++ b/cpukit/include/rtems/tar.h
@@ -0,0 +1,53 @@
+/*
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ *
+ * $Id$
+ */
+
+/** @file rtems/tar.h
+ * Wrapper to <tar.h> to accomodate systems not providing <tar.h> (Cygwin).
+ */
+
+#ifndef _RTEMS_TAR_H
+#define _RTEMS_TAR_H
+
+#include <rtems/score/cpuopts.h>
+
+#if RTEMS_USES_TAR_H
+#include <tar.h>
+#else
+/* General definitions */
+#define TMAGIC "ustar" /* ustar plus null byte. */
+#define TMAGLEN 6 /* Length of the above. */
+#define TVERSION "00" /* 00 without a null byte. */
+#define TVERSLEN 2 /* Length of the above. */
+
+/* Typeflag field definitions */
+#define REGTYPE '0' /* Regular file. */
+#define AREGTYPE '\0' /* Regular file. */
+#define LNKTYPE '1' /* Link. */
+#define SYMTYPE '2' /* Symbolic link. */
+#define CHRTYPE '3' /* Character special. */
+#define BLKTYPE '4' /* Block special. */
+#define DIRTYPE '5' /* Directory. */
+#define FIFOTYPE '6' /* FIFO special. */
+#define CONTTYPE '7' /* Reserved. */
+
+/* Mode field bit definitions (octal) */
+#define TSUID 04000 /* Set UID on execution. */
+#define TSGID 02000 /* Set GID on execution. */
+#define TSVTX 01000 /* On directories, restricted deletion flag. */
+#define TUREAD 00400 /* Read by owner. */
+#define TUWRITE 00200 /* Write by owner. */
+#define TUEXEC 00100 /* Execute/search by owner. */
+#define TGREAD 00040 /* Read by group. */
+#define TGWRITE 00020 /* Write by group. */
+#define TGEXEC 00010 /* Execute/search by group. */
+#define TOREAD 00004 /* Read by other. */
+#define TOWRITE 00002 /* Write by other. */
+#define TOEXEC 00001 /* Execute/search by other. */
+#endif /* RTEMS_USES_TAR_H */
+
+#endif /* _RTEMS_TAR_H */
diff --git a/cpukit/include/rtems/userenv.h b/cpukit/include/rtems/userenv.h
new file mode 100644
index 0000000000..80fb7897ec
--- /dev/null
+++ b/cpukit/include/rtems/userenv.h
@@ -0,0 +1,88 @@
+/*
+ * Libio Internal Information
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_USERENV_H
+#define _RTEMS_USERENV_H
+
+#include <rtems.h>
+#include <rtems/fs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * External structures
+ */
+
+/*
+ * According to IEEE Std 1003.1-2001,
+ * limits.h is supposed to provide _POSIX_LOGIN_NAME_MAX
+ * FIXME: We should not rely on this.
+ */
+#include <limits.h>
+
+#ifndef LOGIN_NAME_MAX
+#ifdef _POSIX_LOGIN_NAME_MAX
+#define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX
+#else
+/* Fallback */
+#define LOGIN_NAME_MAX 9
+#endif
+#endif
+
+typedef struct {
+ rtems_id task_id;
+ rtems_filesystem_location_info_t current_directory;
+ rtems_filesystem_location_info_t root_directory;
+ /* Default mode for all files. */
+ mode_t umask;
+ nlink_t link_counts;
+ /* _POSIX_types */
+ uid_t uid;
+ gid_t gid;
+ uid_t euid;
+ gid_t egid;
+ char login_buffer[LOGIN_NAME_MAX];
+
+ pid_t pgrp; /* process group id */
+} rtems_user_env_t;
+
+extern rtems_user_env_t * rtems_current_user_env;
+extern rtems_user_env_t rtems_global_user_env;
+
+#define rtems_filesystem_current (rtems_current_user_env->current_directory)
+#define rtems_filesystem_root (rtems_current_user_env->root_directory)
+#define rtems_filesystem_link_counts (rtems_current_user_env->link_counts)
+#define rtems_filesystem_umask (rtems_current_user_env->umask)
+
+#define _POSIX_types_Uid (rtems_current_user_env->uid)
+#define _POSIX_types_Gid (rtems_current_user_env->gid)
+#define _POSIX_types_Euid (rtems_current_user_env->euid)
+#define _POSIX_types_Egid (rtems_current_user_env->egid)
+#define _POSIX_types_Getlogin_buffer (rtems_current_user_env->login_buffer)
+
+
+/*
+ * Instantiate a private copy of the per user information for the calling task.
+ */
+
+rtems_status_code rtems_libio_set_private_env(void);
+rtems_status_code rtems_libio_share_private_env(rtems_id task_id) ;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/.cvsignore b/cpukit/itron/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/itron/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/itron/Makefile.am b/cpukit/itron/Makefile.am
new file mode 100644
index 0000000000..81ecdedd88
--- /dev/null
+++ b/cpukit/itron/Makefile.am
@@ -0,0 +1,119 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+EXTRA_DIST =
+
+if HAS_ITRON
+## include
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = include/itron.h
+
+## itronsys
+
+include_itronsysdir = $(includedir)/itronsys
+
+include_itronsys_HEADERS = include/itronsys/eventflags.h \
+ include/itronsys/fmempool.h include/itronsys/intr.h \
+ include/itronsys/mbox.h include/itronsys/msgbuffer.h \
+ include/itronsys/network.h include/itronsys/port.h \
+ include/itronsys/semaphore.h include/itronsys/status.h \
+ include/itronsys/sysmgmt.h include/itronsys/task.h \
+ include/itronsys/time.h include/itronsys/types.h \
+ include/itronsys/vmempool.h
+
+EXTRA_DIST += include/itronsys/README
+
+## rtems/itron
+include_rtems_itrondir = $(includedir)/rtems/itron
+
+include_rtems_itron_HEADERS = include/rtems/itron/config.h \
+ include/rtems/itron/eventflags.h include/rtems/itron/fmempool.h \
+ include/rtems/itron/intr.h include/rtems/itron/itronapi.h \
+ include/rtems/itron/mbox.h include/rtems/itron/msgbuffer.h \
+ include/rtems/itron/network.h include/rtems/itron/object.h \
+ include/rtems/itron/port.h include/rtems/itron/semaphore.h \
+ include/rtems/itron/sysmgmt.h include/rtems/itron/task.h \
+ include/rtems/itron/time.h include/rtems/itron/vmempool.h
+
+EXTRA_DIST += include/rtems/itron/README
+
+## Inline
+
+if INLINE
+include_rtems_itron_HEADERS += inline/rtems/itron/eventflags.inl \
+ inline/rtems/itron/fmempool.inl inline/rtems/itron/intr.inl \
+ inline/rtems/itron/mbox.inl inline/rtems/itron/msgbuffer.inl \
+ inline/rtems/itron/network.inl inline/rtems/itron/port.inl \
+ inline/rtems/itron/semaphore.inl inline/rtems/itron/sysmgmt.inl \
+ inline/rtems/itron/task.inl inline/rtems/itron/time.inl \
+ inline/rtems/itron/vmempool.inl
+else
+include_rtems_itron_HEADERS += macros/rtems/itron/eventflags.inl \
+ macros/rtems/itron/fmempool.inl macros/rtems/itron/intr.inl \
+ macros/rtems/itron/mbox.inl macros/rtems/itron/msgbuffer.inl \
+ macros/rtems/itron/network.inl macros/rtems/itron/port.inl \
+ macros/rtems/itron/semaphore.inl macros/rtems/itron/sysmgmt.inl \
+ macros/rtems/itron/task.inl macros/rtems/itron/time.inl \
+ macros/rtems/itron/vmempool.inl
+endif
+
+## Sources
+
+TASK_C_FILES = src/task.c src/cre_tsk.c src/del_tsk.c src/sta_tsk.c \
+ src/ext_tsk.c src/exd_tsk.c src/ter_tsk.c src/dis_dsp.c src/ena_dsp.c \
+ src/chg_pri.c src/rot_rdq.c src/rel_wai.c src/get_tid.c src/ref_tsk.c
+
+TASKSYNC_C_FILES = src/sus_tsk.c src/rsm_tsk.c src/frsm_tsk.c src/slp_tsk.c \
+ src/tslp_tsk.c src/wup_tsk.c src/can_wup.c
+
+SEMAPHORE_C_FILES = src/itronsem.c src/cre_sem.c src/del_sem.c \
+ src/preq_sem.c src/ref_sem.c src/sig_sem.c src/twai_sem.c src/wai_sem.c
+
+EVENTFLAGS_C_FILES = src/eventflags.c
+
+MAILBOX_C_FILES = src/mbox.c
+
+MSGBUFFER_C_FILES = src/msgbuffer.c src/msgbuffertranslatereturncode.c \
+ src/cre_mbf.c src/del_mbf.c src/prcv_mbf.c src/psnd_mbf.c src/rcv_mbf.c \
+ src/ref_mbf.c src/snd_mbf.c src/trcv_mbf.c src/tsnd_mbf.c
+
+RENDEZVOUS_C_FILES = src/port.c
+
+INTERRUPT_C_FILES = src/itronintr.c
+
+VARIABLE_MEMORY_POOL_C_FILES = src/vmempool.c
+
+FIXED_MEMORY_POOL_C_FILES = src/fmempool.c
+
+TIME_C_FILES = src/itrontime.c
+
+CONFIGURATION_C_FILES = src/sysmgmt.c
+
+NETWORK_C_FILES = src/network.c
+
+C_FILES = $(TASK_C_FILES) $(TASKSYNC_C_FILES) $(SEMAPHORE_C_FILES) \
+ $(EVENTFLAGS_C_FILES) $(MAILBOX_C_FILES) $(MSGBUFFER_C_FILES) \
+ $(RENDEZVOUS_C_FILES) $(INTERRUPT_C_FILES) \
+ $(VARIABLE_MEMORY_POOL_C_FILES) $(FIXED_MEMORY_POOL_C_FILES) \
+ $(TIME_C_FILES)
+
+AM_CPPFLAGS += -D__RTEMS_INSIDE__
+
+noinst_LIBRARIES = libitron.a
+libitron_a_SOURCES = $(C_FILES)
+libitron_a_CPPFLAGS = $(AM_CPPFLAGS)
+endif
+
+UNUSED_C_FILES = src/cre_mbx.c src/del_mbx.c src/mboxtranslatereturncode.c \
+ $(NETWORK_C_FILES) src/prcv_mbx.c src/rcv_mbx.c src/ref_mbx.c \
+ src/snd_mbx.c $(CONFIGURATION_C_FILES) src/trcv_mbx.c
+
+EXTRA_DIST += $(UNUSED_C_FILES) src/TODO
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/itron/include/itron.h b/cpukit/itron/include/itron.h
new file mode 100644
index 0000000000..f684c57222
--- /dev/null
+++ b/cpukit/itron/include/itron.h
@@ -0,0 +1,55 @@
+/**
+ * @file itron.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRON_H
+#define _ITRON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Include the basic requirements
+ */
+
+#include <rtems/system.h> /* basic RTEMS types defined by */
+ /* each port */
+#include <itronsys/types.h> /* define all the TRON types */
+ /* in terms of the RTEMS base types */
+#include <itronsys/status.h> /* define all ITRON status codes */
+
+/*
+ * Now include the per manager include files
+ */
+
+#include <itronsys/eventflags.h>
+#include <itronsys/fmempool.h>
+#include <itronsys/intr.h>
+#include <itronsys/mbox.h>
+#include <itronsys/msgbuffer.h>
+#include <itronsys/sysmgmt.h> /* network depends on this file */
+#include <itronsys/network.h>
+#include <itronsys/port.h>
+#include <itronsys/semaphore.h>
+#include <itronsys/task.h>
+#include <itronsys/time.h>
+#include <itronsys/vmempool.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/README b/cpukit/itron/include/itronsys/README
new file mode 100644
index 0000000000..8191ad3c5f
--- /dev/null
+++ b/cpukit/itron/include/itronsys/README
@@ -0,0 +1,9 @@
+#
+# $Id$
+#
+
+This directory contains the public interface of each manager.
+Each file in this directory is included from <itron.h>.
+
+The private header file for each ITRON manager is in
+../rtems/itron. \ No newline at end of file
diff --git a/cpukit/itron/include/itronsys/eventflags.h b/cpukit/itron/include/itronsys/eventflags.h
new file mode 100644
index 0000000000..d075a3688e
--- /dev/null
+++ b/cpukit/itron/include/itronsys/eventflags.h
@@ -0,0 +1,149 @@
+/**
+ * @file itronsys/eventflags.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_EVENTFLAGS_H
+#define _ITRONSYS_EVENTFLAGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Create Eventflags (cre_flg) Structure
+ */
+
+typedef struct t_cflg {
+ VP exinf; /* extended information */
+ ATR flgatr; /* eventflag attribute */
+ UINT iflgptn; /* initial eventflag */
+ /* additional information may be included depending on the implementation */
+} T_CFLG;
+
+/*
+ * flgatr
+ */
+
+#define TA_WSGL 0x00 /* multiple tasks are not allowed to wait (Wait
+ Single Task) */
+#define TA_WMUL 0x08 /* multiple tasks are allowed to wait (Wait
+ Multiple Task) */
+
+/*
+ * wfmode
+ */
+
+#define TWF_ANDW 0x00 /* AND wait */
+#define TWF_ORW 0x02 /* OR wait */
+#define TWF_CLR 0x01 /* clear specification */
+
+/*
+ * Reference Eventflags (ref_flg) Structure
+ */
+
+typedef struct t_rflg {
+ VP exinf; /* extended information */
+ BOOL_ID wtsk; /* indicates whether or not there is a waiting task */
+ UINT flgptn; /* eventflag bit pattern */
+ /* additional information may be included depending on the implementation */
+} T_RFLG;
+
+/*
+ * Eventflag Functions
+ */
+
+/*
+ * cre_flg - Create Eventflag
+ */
+
+ER cre_flg(
+ ID flgid,
+ T_CFLG *pk_cflg
+);
+
+/*
+ * del_flg - Delete Eventflag
+ */
+
+ER del_flg(
+ ID flgid
+);
+
+/*
+ * set_flg - Set Eventflag
+ */
+
+ER set_flg(
+ ID flgid,
+ UINT setptn
+);
+
+/*
+ * clr_flg - Clear Eventflag
+ */
+
+ER clr_flg(
+ ID flgid,
+ UINT clrptn
+);
+
+/*
+ * wai_flg - Wait on Eventflag
+ */
+
+ER wai_flg(
+ UINT *p_flgptn,
+ ID flgid,
+ UINT waiptn,
+ UINT wfmode
+);
+
+/*
+ * pol_flg - Wait for Eventflag(Polling)
+ */
+
+ER pol_flg(
+ UINT *p_flgptn,
+ ID flgid,
+ UINT waiptn,
+ UINT wfmode
+);
+
+/*
+ * twai_flg - Wait on Eventflag with Timeout
+ */
+
+ER twai_flg(
+ UINT *p_flgptn,
+ ID flgid,
+ UINT waiptn,
+ UINT wfmode,
+ TMO tmout
+);
+
+/*
+ * ref_flg - Reference Eventflag Status
+ */
+
+ER ref_flg(
+ T_RFLG *pk_rflg,
+ ID flgid
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/fmempool.h b/cpukit/itron/include/itronsys/fmempool.h
new file mode 100644
index 0000000000..05bd4cea1a
--- /dev/null
+++ b/cpukit/itron/include/itronsys/fmempool.h
@@ -0,0 +1,128 @@
+/**
+ * @file itronsys/fmempool.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_FMEMPOOL_H
+#define _ITRONSYS_FMEMPOOL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Create Fixed Memory Pool (cre_mpf) Structure
+ */
+
+ /* cre_mpf */
+typedef struct t_cmpf {
+ VP exinf; /* extended information */
+ ATR mpfatr; /* memorypool attributes */
+ INT mpfcnt; /* block count for entire memorypool */
+ INT blfsz; /* fixed-size memory block size */
+ /* additional information may be included depending on the implementation */
+} T_CMPF;
+
+/*
+ * mpfatr
+ */
+
+#define TA_TFIFO 0x00 /* waiting tasks are handled by FIFO */
+#define TA_TPRI 0x01 /* waiting tasks are handled by priority */
+
+
+/*
+ * Reference Fixed Memory Pool (ref_mpf) Structure
+ */
+
+ /* ref_mpf */
+typedef struct t_rmpf {
+ VP exinf; /* extended information */
+ BOOL_ID wtsk; /* indicates whether or not there are waiting tasks */
+ INT frbcnt; /* free block count */
+ /* additional information may be included depending on the implementation */
+} T_RMPF;
+
+/*
+ * Fixed Memory Pool Functions
+ */
+
+/*
+ * cre_mpf - Create Fixed-Size Memorypool
+ */
+
+ER cre_mpf(
+ ID mpfid,
+ T_CMPF *pk_cmpf
+);
+
+/*
+ * del_mpf - Delete Fixed-Size Memorypool
+ */
+
+ER del_mpf(
+ ID mpfid
+);
+
+/*
+ * get_blf - Get Fixed-Size Memory Block
+ */
+
+ER get_blf(
+ VP *p_blf,
+ ID mpfid
+);
+
+/*
+ * pget_blf - Poll and Get Fixed-Size Memory Block
+ */
+
+ER pget_blf(
+ VP *p_blf,
+ ID mpfid
+);
+
+/*
+ * tget_blf - Get Fixed-Size Memory Block with Timeout
+ */
+
+ER tget_blf(
+ VP *p_blf,
+ ID mpfid,
+ TMO tmout
+);
+
+/*
+ * rel_blf - Release Fixed-Size Memory Block
+ */
+
+ER rel_blf(
+ ID mpfid,
+ VP blf
+);
+
+/*
+ * ref_mpf - Reference Fixed-Size Memorypool Status
+ */
+
+ER ref_mpf(
+ T_RMPF *pk_rmpf,
+ ID mpfid
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/intr.h b/cpukit/itron/include/itronsys/intr.h
new file mode 100644
index 0000000000..4b8264a006
--- /dev/null
+++ b/cpukit/itron/include/itronsys/intr.h
@@ -0,0 +1,109 @@
+/**
+ * @file itronsys/intr.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_INTR_H
+#define _ITRONSYS_INTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Define Interrupt (def_int) Structure
+ */
+
+typedef struct t_dint {
+ ATR intatr; /* interrupt handler attributes */
+ FP inthdr; /* interrupt handler address */
+ /* additional information may be included depending on the implementation */
+} T_DINT;
+
+/*
+ * Interrupt Functions
+ */
+
+/*
+ * def_int - Define Interrupt Handler
+ */
+
+ER def_int(
+ UINT dintno,
+ T_DINT *pk_dint
+);
+
+/*
+ * ret_int - Return from Interrupt Handler
+ */
+
+void ret_int( void );
+
+/*
+ * ret_wup - Return and Wakeup Task
+ */
+
+void ret_wup(
+ ID tskid
+);
+
+/*
+ * loc_cpu - Lock CPU
+ */
+
+ER loc_cpu( void );
+
+/*
+ * unl_cpu - Unlock CPU
+ */
+
+ER unl_cpu( void );
+
+/*
+ * dis_int - Disable Interrupt
+ */
+
+ER dis_int(
+ UINT eintno
+);
+
+/*
+ * ena_int - Enable Interrupt
+ */
+
+ER ena_int(
+ UINT eintno
+);
+
+/*
+ * chg_iXX - Change Interrupt Mask(Level or Priority)
+ */
+
+ER chg_iXX(
+ UINT iXXXX
+);
+
+/*
+ * ref_iXX - Reference Interrupt Mask(Level or Priority)
+ */
+
+ER ref_iXX(
+ UINT *p_iXXXX
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/mbox.h b/cpukit/itron/include/itronsys/mbox.h
new file mode 100644
index 0000000000..518c6b7225
--- /dev/null
+++ b/cpukit/itron/include/itronsys/mbox.h
@@ -0,0 +1,141 @@
+/**
+ * @file itronsys/mbox.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_MBOX_H
+#define _ITRONSYS_MBOX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Create Mailbox (cre_mbx) Structure
+ */
+
+typedef struct t_cmbx {
+ VP exinf; /* extended information */
+ ATR mbxatr; /* mailbox attributes */
+ /* Following is implementation-dependent function */
+ INT bufcnt; /* maximum number of messages to let pend */
+ /* additional information may be included depending on the implementation */
+} T_CMBX;
+
+/*
+ * mbxatr
+ */
+
+#define TA_TFIFO 0x00 /* waiting tasks are handled by FIFO */
+#define TA_TPRI 0x01 /* waiting tasks are handled by priority */
+#define TA_MFIFO 0x00 /* messages are handled by FIFO */
+#define TA_MPRI 0x02 /* messages are handled by priority */
+
+typedef struct t_msg {
+ /*
+ * A region (header) reserved by the OS may be included first
+ * depending on the implementation.
+ *
+ * NOTE: The first two fields are RTEMS specific.
+ */
+
+ INT msgpri; /* priority of each message */
+ /* VB msgcont[]; XXX */
+ uint8_t msgcont[1];
+} T_MSG;
+
+/*
+ * Reference Mailbox (ref_mbx) Structure
+ */
+
+typedef struct t_rmbx {
+ VP exinf; /* extended information */
+ BOOL_ID wtsk; /* indicates whether or not there is a waiting task */
+ T_MSG *pk_msg; /* message to be sent next */
+ /* additional information may be included depending on the implementation */
+} T_RMBX;
+
+/*
+ * Mailbox Functions
+ */
+
+/*
+ * cre_mbx - Create Mailbox
+ */
+
+ER cre_mbx(
+ ID mbxid,
+ T_CMBX *pk_cmbx
+);
+
+/*
+ * del_mbx - Delete Mailbox
+ */
+
+ER del_mbx(
+ ID mbxid
+);
+
+/*
+ * snd_msg - Send Message to Mailbox
+ */
+
+ER snd_msg(
+ ID mbxid,
+ T_MSG *pk_msg
+);
+
+/*
+ * rcv_msg - Receive Message from Mailbox
+ */
+
+ER rcv_msg(
+ T_MSG **ppk_msg,
+ ID mbxid
+);
+
+/*
+ * prcv_msg - Poll and Receive Message from Mailbox
+ */
+
+ER prcv_msg(
+ T_MSG **ppk_msg,
+ ID mbxid
+);
+
+/*
+ * trcv_msg - Receive Message from Mailbox with Timeout
+ */
+
+ER trcv_msg(
+ T_MSG **ppk_msg,
+ ID mbxid,
+ TMO tmout
+);
+
+/*
+ * ref_mbx - Reference Mailbox Status
+ */
+
+ER ref_mbx(
+ T_RMBX *pk_rmbx,
+ ID mbxid
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/msgbuffer.h b/cpukit/itron/include/itronsys/msgbuffer.h
new file mode 100644
index 0000000000..812de95062
--- /dev/null
+++ b/cpukit/itron/include/itronsys/msgbuffer.h
@@ -0,0 +1,163 @@
+/**
+ * @file itronsys/msgbuffer.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_MSGBUFFER_H
+#define _ITRONSYS_MSGBUFFER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Create Message Buffer (cre_mbf) Structure
+ */
+
+typedef struct t_cmbf {
+ VP exinf; /* extended information */
+ ATR mbfatr; /* messagebuffer attributes */
+ INT bufsz; /* messagebuffer size */
+ INT maxmsz; /* maximum size of messages */
+ /* additional information may be included depending on the implementation */
+} T_CMBF;
+
+/*
+ * mbfatr
+ */
+
+#define TA_TFIFO 0x00 /* tasks waiting to receive messages are handled
+ by FIFO */
+#define TA_TPRI 0x01 /* tasks waiting to receive messages are handled
+ by priority */
+
+/*
+ * mbfid
+ */
+
+#define TMBF_OS (-4) /* messagebuffer used for OS error log */
+#define TMBF_DB (-3) /* messagebuffer used for debugging */
+
+/*
+ * Reference Message Buffer (ref_mbf) Structure
+ */
+
+typedef struct t_rmbf {
+ VP exinf; /* extended information */
+ BOOL_ID wtsk; /* indicates whether or not there is a */
+ /* task waiting to receive a message */
+ BOOL_ID stsk; /* indicates whether or not there is a */
+ /* task waiting to send a message */
+ INT msgsz; /* size of message to be sent next */
+ INT frbufsz; /* size of free buffer */
+ /* additional information may be included depending on the implementation */
+} T_RMBF;
+
+/*
+ * Message Buffer Functions
+ */
+
+/*
+ * cre_mbf - Create MessageBuffer
+ */
+
+ER cre_mbf(
+ ID mbfid,
+ T_CMBF *pk_cmbf
+);
+
+/*
+ * del_mbf - Delete MessageBuffer
+ */
+
+ER del_mbf(
+ ID mbfid
+);
+
+/*
+ * snd_mbf - Send Message to MessageBuffer
+ */
+
+ER snd_mbf(
+ ID mbfid,
+ VP msg,
+ INT msgsz
+);
+
+/*
+ * psnd_mbf - Poll and Send Message to MessageBuffer
+ */
+
+ER psnd_mbf(
+ ID mbfid,
+ VP msg,
+ INT msgsz
+);
+
+/*
+ * tsnd_mbf - Send Message to MessageBuffer with Timeout
+ */
+
+ER tsnd_mbf(
+ ID mbfid,
+ VP msg,
+ INT msgsz,
+ TMO tmout
+);
+
+/*
+ * rcv_mbf - Receive Message from MessageBuffer
+ */
+
+ER rcv_mbf(
+ VP msg,
+ INT *p_msgsz,
+ ID mbfid
+);
+
+/*
+ * prcv_mbf - Poll and Receive Message from MessageBuffer
+ */
+
+ER prcv_mbf(
+ VP msg,
+ INT *p_msgsz,
+ ID mbfid
+);
+
+/*
+ * trcv_mbf - Receive Message from MessageBuffer with Timeout
+ */
+
+ER trcv_mbf(
+ VP msg,
+ INT *p_msgsz,
+ ID mbfid,
+ TMO tmout
+);
+
+/*
+ * ref_mbf - Reference MessageBuffer Status
+ */
+
+ER ref_mbf(
+ T_RMBF *pk_rmbf,
+ ID mbfid
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/network.h b/cpukit/itron/include/itronsys/network.h
new file mode 100644
index 0000000000..9ea04704c4
--- /dev/null
+++ b/cpukit/itron/include/itronsys/network.h
@@ -0,0 +1,81 @@
+/**
+ * @file itronsys/network.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_NETWORK_H
+#define _ITRONSYS_NETWORK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * NODE srcnode, dstnode, nod:
+ */
+
+#define TND_SELF 0 /* specifies the local node */
+#define TND_OTHR (-1) /* specifies default remote node */
+
+/*
+ * Network Functions
+ */
+
+/*
+ * nrea_dat - Read Data from another Node
+ */
+
+ER nrea_dat(
+ INT *p_reasz,
+ VP dstadr,
+ NODE srcnode,
+ VP srcadr,
+ INT datsz
+);
+
+/*
+ * nwri_dat - Write Data to another Node
+ */
+
+ER nwri_dat(
+ INT *p_wrisz,
+ NODE dstnode,
+ VP dstadr,
+ VP srcadr,
+ INT datsz
+);
+
+/*
+ * nget_nod - Get Local Node Number
+ */
+
+ER nget_nod(
+ NODE *p_node
+);
+
+/*
+ * nget_ver - Get Version Information of another Node
+ */
+
+ER nget_ver(
+ T_VER *pk_ver,
+ NODE node
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/port.h b/cpukit/itron/include/itronsys/port.h
new file mode 100644
index 0000000000..128b347195
--- /dev/null
+++ b/cpukit/itron/include/itronsys/port.h
@@ -0,0 +1,193 @@
+/**
+ * @file itronsys/port.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_PORT_H
+#define _ITRONSYS_PORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Create Port (cre_por) Structure
+ */
+
+typedef struct t_cpor {
+ VP exinf; /* extended information */
+ ATR poratr; /* port attributes */
+ INT maxcmsz; /* maximum call message size */
+ INT maxrmsz; /* maximum reply message size */
+ /* additional information may be included depending on the implementation */
+} T_CPOR;
+
+/*
+ * poratr
+ */
+
+#define TA_NULL 0 /* specifies no particular attributes */
+
+/*
+ * TA_NULL should be used in place of zeroes to turn off all
+ * attribute features.
+ */
+
+/*
+ * Reference Port (ref_por) Structure
+ */
+
+typedef struct t_rpor {
+ VP exinf; /* extended information */
+ BOOL_ID wtsk; /* indicates whether or not there is a task */
+ /* waiting to call a rendezvous */
+ BOOL_ID atsk; /* indicates whether or not there is a task */
+ /* waiting to accept a rendezvous */
+ /* additional information may be included depending on the implementation */
+} T_RPOR;
+
+/*
+ * Port Functions
+ */
+
+/*
+ * cre_por - Create Port for Rendezvous
+ */
+
+ER cre_por(
+ ID porid,
+ T_CPOR *pk_cpor
+);
+
+/*
+ * del_por - Delete Port for Rendezvous
+ */
+
+ER del_por(
+ ID porid
+);
+
+/*
+ * cal_por - Call Port for Rendezvous Poll
+ */
+
+ER cal_por(
+ VP msg,
+ INT *p_rmsgsz,
+ ID porid,
+ UINT calptn,
+ INT cmsgsz
+);
+
+/*
+ * pcal_por - Poll and Call Port for Rendezvous
+ */
+
+ER pcal_por(
+ VP msg,
+ INT *p_rmsgsz,
+ ID porid,
+ UINT calptn,
+ INT cmsgsz
+);
+
+/*
+ * tcal_por - Call Port for Rendezvous with Timeout
+ */
+
+ER tcal_por(
+ VP msg,
+ INT *p_rmsgsz,
+ ID porid,
+ UINT calptn,
+ INT cmsgsz,
+ TMO tmout
+);
+
+/*
+ * acp_por - Accept Port for Rendezvous Poll
+ */
+
+ER acp_por(
+ RNO *p_rdvno,
+ VP msg,
+ INT *p_cmsgsz,
+ ID porid,
+ UINT acpptn
+);
+
+/*
+ * pacp_por - Poll and Accept Port for Rendezvous
+ */
+
+ER pacp_por(
+ RNO *p_rdvno,
+ VP msg,
+ INT *p_cmsgsz,
+ ID porid,
+ UINT acpptn
+);
+
+/*
+ * tacp_por - Accept Port for Rendezvous with Timeout
+ */
+
+ER tacp_por(
+ RNO *p_rdvno,
+ VP msg,
+ INT *p_cmsgsz,
+ ID porid,
+ UINT acpptn,
+ TMO tmout
+);
+
+/*
+ * fwd_por - Forward Rendezvous to Other Port
+ */
+
+ER fwd_por(
+ ID porid,
+ UINT calptn,
+ RNO rdvno,
+ VP msg,
+ INT cmsgsz
+);
+
+/*
+ * rpl_rdv - Reply Rendezvous
+ */
+
+ER rpl_rdv(
+ RNO rdvno,
+ VP msg,
+ INT rmsgsz
+);
+
+/*
+ * ref_por - Reference Port Status
+ */
+
+ER ref_por(
+ T_RPOR *pk_rpor,
+ ID porid
+);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/semaphore.h b/cpukit/itron/include/itronsys/semaphore.h
new file mode 100644
index 0000000000..0abf6d311d
--- /dev/null
+++ b/cpukit/itron/include/itronsys/semaphore.h
@@ -0,0 +1,124 @@
+/**
+ * @file itronsys/semaphore.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_SEMAPHORE_H
+#define _ITRONSYS_SEMAPHORE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Create Semaphore (cre_sem) Structure
+ */
+
+typedef struct t_csem {
+ VP exinf; /* extended information */
+ ATR sematr; /* semaphore attributes */
+ /* Following is the extended function for [level X]. */
+ INT isemcnt; /* initial semaphore count */
+ INT maxsem; /* maximum semaphore count */
+ /* additional information may be included depending on the implementation */
+} T_CSEM;
+
+/*
+ * sematr - Semaphore Attribute Values
+ */
+
+#define TA_TFIFO 0x00 /* waiting tasks are handled by FIFO */
+#define TA_TPRI 0x01 /* waiting tasks are handled by priority */
+
+#define _ITRON_SEMAPHORE_UNUSED_ATTRIBUTES ~(TA_TPRI)
+
+/*
+ * Reference Semaphore (ref_sem) Structure
+ */
+
+typedef struct t_rsem {
+ VP exinf; /* extended information */
+ BOOL_ID wtsk; /* indicates whether or not there is a waiting task */
+ INT semcnt; /* current semaphore count */
+ /* additional information may be included depending on the implementation */
+} T_RSEM;
+
+/*
+ * Semaphore Functions
+ */
+
+/*
+ * cre_sem - Create Semaphore
+ */
+
+ER cre_sem(
+ ID semid,
+ T_CSEM *pk_csem
+);
+
+/*
+ * del_sem - Delete Semaphore
+ */
+
+ER del_sem(
+ ID semid
+);
+
+/*
+ * sig_sem - Signal Semaphore
+ */
+
+ER sig_sem(
+ ID semid
+);
+
+/*
+ * wai_sem - Wait on Semaphore
+ */
+
+ER wai_sem(
+ ID semid
+);
+
+/*
+ * preq_sem - Poll and Request Semaphore
+ */
+
+ER preq_sem(
+ ID semid
+);
+
+/*
+ * twai_sem - Wait on Semaphore with Timeout
+ */
+
+ER twai_sem(
+ ID semid,
+ TMO tmout
+);
+
+/*
+ * ref_sem - Reference Semaphore Status
+ */
+
+ER ref_sem(
+ ID semid,
+ T_RSEM *pk_rsem
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/status.h b/cpukit/itron/include/itronsys/status.h
new file mode 100644
index 0000000000..1c24217449
--- /dev/null
+++ b/cpukit/itron/include/itronsys/status.h
@@ -0,0 +1,73 @@
+/**
+ * @file itronsys/status.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_STATUS_H
+#define _ITRONSYS_STATUS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define E_OK 0 /* Normal completion */
+#define E_SYS (-5) /* System error */
+#define E_NOMEM (-10) /* Insufficient memory */
+#define E_NOSPT (-17) /* Feature not supported */
+#define E_INOSPT (-18) /* Feature not supported by ITRON/FILE */
+ /* specification */
+#define E_RSFN (-20) /* Reserved function code number */
+#define E_RSATR (-24) /* Reserved attribute */
+#define E_PAR (-33) /* Parameter error */
+#define E_ID (-35) /* Invalid ID number */
+#define E_NOEXS (-52) /* Object does not exist */
+#define E_OBJ (-63) /* Invalid object state */
+#define E_MACV (-65) /* Memory access disabled or memory access */
+ /* violation */
+#define E_OACV (-66) /* Object access violation */
+#define E_CTX (-69) /* Context error */
+#define E_QOVR (-73) /* Queuing or nesting overflow */
+#define E_DLT (-81) /* Object being waited for was deleted */
+#define E_TMOUT (-85) /* Polling failure or timeout exceeded */
+#define E_RLWAI (-86) /* WAIT state was forcibly released */
+#define EN_NOND (-113) /* Target node does not exist or cannot be */
+ /* accessed */
+#define EN_OBJNO (-114) /* Specifies an object number which could not be */
+ /* accessed on the target node */
+#define EN_PROTO (-115) /* Protocol not supported on target node */
+#define EN_RSFN (-116) /* System call or function not supported on */
+ /* target node */
+#define EN_COMM (-117) /* No response from target node */
+#define EN_RLWAI (-118) /* Connection function response wait state was */
+ /* forcibly released */
+#define EN_PAR (-119) /* A value outside the range supported by the */
+ /* target node and/or transmission packet */
+ /* format was specified as a parameter */
+#define EN_RPAR (-120) /* A value outside the range supported by the */
+ /* issuing node and/or transmission packet */
+ /* format was returned as a return parameter */
+#define EN_CTXID (-121) /* An object on another node was specified to */
+ /* a system call issued from a task in dispatch */
+ /* disabled state or from a task-independent */
+ /* portion */
+#define EN_EXEC (-122) /* System call could not be executed due to */
+ /* insufficient resources on the target node */
+#define EN_NOSPT (-123) /* Connection function not supported */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/sysmgmt.h b/cpukit/itron/include/itronsys/sysmgmt.h
new file mode 100644
index 0000000000..d836168b05
--- /dev/null
+++ b/cpukit/itron/include/itronsys/sysmgmt.h
@@ -0,0 +1,322 @@
+/**
+ * @file itronsys/sysmgmt.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_SYSMGMT_H
+#define _ITRONSYS_SYSMGMT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Get Version (get_ver) Structure
+ */
+
+typedef struct t_ver {
+ UH maker; /* vendor */
+ UH id; /* format number */
+ UH spver; /* specification version */
+ UH prver; /* product version */
+ UH prno[4]; /* product control information */
+ UH cpu; /* CPU information */
+ UH var; /* variation descriptor */
+} T_VER;
+
+/*
+ * Specific MAKER codes established as of March, 1993 are as follows.
+ * Due to restrictions on the assignment of CPU codes described below, it is
+ * necessary to use maker codes in the range 0x000 through 0x00ff for vendors
+ * developing CPUs.
+ */
+
+/*
+ * CPU defines XXX need to name the constants
+ */
+
+#if 0
+#define 0x000 /* No version (test systems, etc.) */
+#define 0x001 /* University of Tokyo */
+#define 0x009 /* FUJITSU LIMITED */
+#define 0x00a /* Hitachi, Ltd. */
+#define 0x00b /* Matsushita Electric Industrial Co., Ltd. */
+#define 0x00c /* Mitsubishi Electric Corporation */
+#define 0x00d /* NEC Corporation */
+#define 0x00e /* Oki Electric Industry Co., Ltd. */
+#define 0x00f /* TOSHIBA CORPORATION */
+#endif
+
+/*
+ * The above have been assigned in alphabetical order.
+ */
+
+#if 0
+#define 0x010 /* ALPS ELECTRIC CO., LTD. */
+#define 0x011 /* WACOM Co., Ltd. */
+#define 0x012 /* Personal Media Corporation */
+#define 0x101 /* OMRON CORPORATION */
+#define 0x102 /* SEIKOSHA CO., LTD. */
+#define 0x103 /* SYSTEM ALGO CO., LTD. */
+#define 0x104 /* Tokyo Computer Service Co., Ltd. */
+#define 0x105 /* YAMAHA CORPORATION */
+#define 0x106 /* MORSON JAPAN */
+#define 0x107 /* TOSHIBA INFORMATION SYSTEMS (JAPAN) CORP. */
+#define 0x108 /* Miyazaki System Planning Office */
+#define 0x109 /* Three Ace Computer Corporation */
+#endif
+
+/*
+ * CPU Codes
+ *
+ * Figure 47 shows the format of cpu code. Some processors use the format
+ * given in Figure 47(1). The format given in Figure 47(2) is used for all
+ * other proprietary processors.
+ *
+ * The code assignment of the CPU1 region in the format given in Figure 47(1)
+ * is common to ITRON and BTRON specifications. The same number is used in
+ * the CPU type of the standard object format of BTRON specification
+ * operating systems implemented on a TRON-specification chip.
+ *
+ * When using the format given in Figure 47(2) the code used for MAKER1 is
+ * assigned by using the lower 8 bits of MAKER described in the previous
+ * subsection. The code assignment of CPU2 is left up to each maker.
+ *
+ *
+ *
+ * +---------------+---------------+---------------+---------------+
+ * (1) | 0 0 0 0 0 0 0 0 | CPU1 |
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ * +---------------+---------------+---------------+---------------+
+ * (2) | MAKER1 | CPU2 |
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ *
+ * Figure 47 Format of cpu Returned by get_ver
+ *
+ *
+ * Specific CPU codes established as of March, 1993 are as follows.
+ */
+
+#if 0
+/*
+ * XXX CONVERT THESE to #defines
+ */
+
+
+/*
+ * Contents of the CPU1 field
+ */
+
+#define (0x0) CPU unspecified, no CPU information given
+#define (0x1) TRONCHIP32 shared
+#define (0x2) reserved
+#define (0x3) reserved
+#define (0x4) reserved
+#define (0x5) reserved (<<L1R>> TRON-specification chip)
+#define (0x6) reserved (<<L1>> TRON-specification chip)
+#define (0x7) reserved (TRON-specification chip supporting the
+ LSID function)
+/* CPU vendors are unspecified for codes B'00000000 through B'00000111. */
+
+#define (0x8) reserved
+#define (0x9) GMICRO/100
+#define (0xa) GMICRO/200
+#define (0xb) GMICRO/300
+#define (0xc) reserved
+#define (0xd) TX1
+#define (0xe) TX2
+#define (0xf) reserved
+
+#define (0x10) reserved
+#define (0x11) reserved
+#define (0x12) reserved
+#define (0x13) O32
+#define (0x14) reserved
+#define (0x15) MN10400
+#define (0x16) reserved
+#define (0x17) reserved
+
+#define (0x18) GMICRO/400
+#define (0x19) GMICRO/500
+#define (0x1a) reserved
+#define (0x1b-0x3f)
+ reserved
+ * For GMICRO extended, TX series extended, and TRONCHIP64 chips.
+
+#define (0x40) Motorola 68000
+#define (0x41) Motorola 68010
+#define (0x42) Motorola 68020
+#define (0x43) Motorola 68030
+#define (0x44) Motorola 68040
+#define -(0x40-0x4f)
+#define Motorola 68000 family
+#define (0x50) National Semiconductor NS32032
+#define (0x50-0x5f)
+ National Semiconductor NS32000 family
+#define (0x60) Intel 8086, 8088
+#define (0x61) Intel 80186
+#define (0x62) Intel 80286
+#define (0x63) Intel 80386
+#define (0x64) Intel 80486
+#define (0x60-0x6f)
+ Intel iAPX86 family
+
+#define (0x70-0x7f)
+ NEC V Series
+
+#define (0x80-0xff)
+ reserved
+#endif
+
+/*
+ * Assigning Version Numbers
+ *
+ * The version numbers of ITRON and uITRON specifications take the following
+ * form.
+ *
+ * Ver X.YY.ZZ[.WW]
+ *
+ * where "X" represents major version number of the ITRON specification to
+ * distinguish ITRON1, ITRON2 and uITRON 3.0 specifications. Specific
+ * assignment is as follows.
+ *
+ * "X" = 1 ITRON1 specification
+ * = 2 ITRON2 or uITRON 2.0 specification
+ * = 3 uITRON 3.0 specification
+ *
+ * "YY" is a number used to distinguish versions according to changes and
+ * additions made to the specification. After the specification is published,
+ * this number is incremented in order "YY" = 00, 01, 02... according to
+ * version upgrades. The first digit of "YY" is 'A', 'B' or 'C' for draft
+ * standard versions and test versions within the TRON Association before the
+ * specification have been published.
+ *
+ * The "X.YY" part of the specification version numbers is returned by spver
+ * to get_ver system call. The corresponding hexadecimal value is used when
+ * "YY" includes 'A', 'B' or 'C'.
+ *
+ * "ZZ" represents a number used to distinguish versions related to the written
+ * style of a specification. This number is incremented in order
+ * "ZZ" = 00, 01, 02... when there have been changes in specification
+ * configuration, reordering of chapters or corrections of misprints.
+ * When a further distinction of the written style of specifications is
+ * desired, ".WW" may be added optionally after "ZZ". WW will be assumed
+ * to be zero if ".WW" is omitted.
+ */
+
+/*
+ * Reference System (ref_sys) Structure
+ */
+
+typedef struct t_rsys {
+ INT sysstat; /* system state */
+ /* additional information may be included depending on the implementation */
+} T_RSYS;
+
+/*
+ * sysstat
+ */
+
+#define TSS_TSK 0 /* normal state in which dispatching is enabled during
+ task portion execution */
+#define TSS_DDSP 1 /* state after dis_dsp has been executed during task
+ portion execution (dispatch disabled) */
+#define TSS_LOC 3 /* state after loc_cpu has been executed during task
+ portion execution (interrupt and dispatch disabled)
+ */
+#define TSS_INDP 4 /* state during execution of task-independent portions
+ (interrupt and timer handlers) */
+
+/*
+ * Reference Configuration (ref_cfg) Structure
+ */
+
+typedef struct t_rcfg {
+ /* details concerning members are implementation dependent */
+} T_RCFG;
+
+/*
+ * Define Service (def_svc) Structure
+ */
+
+typedef struct t_dsvc {
+ ATR svcatr; /* extended SVC handler attributes */
+ FP svchdr; /* extended SVC handler address */
+ /* additional information may be included depending on the implementation */
+} T_DSVC;
+
+/*
+ * Define Exception (def_exc) Structure
+ */
+
+typedef struct t_dexc {
+ ATR excatr; /* exception handler attributes */
+ FP exchdr; /* exception handler address */
+ /* additional information may be included depending on the implementation */
+} T_DEXC;
+
+/*
+ * System Management Functions
+ */
+
+/*
+ * get_ver - Get Version Information
+ */
+
+ER get_ver(
+ T_VER *pk_ver
+);
+
+/*
+ * ref_sys - Reference Semaphore Status
+ */
+
+ER ref_sys(
+ T_RSYS *pk_rsys
+);
+
+/*
+ * ref_cfg - Reference Configuration Information
+ */
+
+ER ref_cfg(
+ T_RCFG *pk_rcfg
+);
+
+/*
+ * def_svc - Define Extended SVC Handler
+ */
+
+ER def_svc(
+ FN s_fncd,
+ T_DSVC *pk_dsvc
+);
+
+/*
+ * def_exc - Define Exception Handler
+ */
+
+ER def_exc(
+ UINT exckind,
+ T_DEXC *pk_dexc
+);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/task.h b/cpukit/itron/include/itronsys/task.h
new file mode 100644
index 0000000000..a137f94758
--- /dev/null
+++ b/cpukit/itron/include/itronsys/task.h
@@ -0,0 +1,301 @@
+/**
+ * @file itronsys/task.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_TASK_H
+#define _ITRONSYS_TASK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Create Task (cre_tsk) Structure
+ */
+
+typedef struct t_ctsk {
+ VP exinf; /* extended information */
+ ATR tskatr; /* task attributes */
+ FP task; /* task start address */
+ PRI itskpri; /* initial task priority */
+ INT stksz; /* stack size */
+ /* additional information may be included depending on the implementation */
+} T_CTSK;
+
+/*
+ * Values for the tskatr field
+ */
+
+#define TA_ASM 0x00 /* program written in assembly language */
+#define TA_HLNG 0x01 /* program written in high-level language */
+#define TA_COP0 0x8000 /* uses coprocessor having ID = 0 */
+#define TA_COP1 0x4000 /* uses coprocessor having ID = 1 */
+#define TA_COP2 0x2000 /* uses coprocessor having ID = 2 */
+#define TA_COP3 0x1000 /* uses coprocessor having ID = 3 */
+#define TA_COP4 0x0800 /* uses coprocessor having ID = 4 */
+#define TA_COP5 0x0400 /* uses coprocessor having ID = 5 */
+#define TA_COP6 0x0200 /* uses coprocessor having ID = 6 */
+#define TA_COP7 0x0100 /* uses coprocessor having ID = 7 */
+
+/*
+ * Values for the tskid field
+ */
+
+#define TSK_SELF 0 /* task specifies itself */
+
+/* XXX is this a mistake in ITRON? FALSE was here and in the types list */
+#if 0
+
+#define FALSE 0 /* indicates a task-independent portion (return */
+ /* parameters only) */
+#endif
+
+/*
+ * Values for the tskpri field
+ */
+
+#define TPRI_INI 0 /* specifies the initial priority on */
+ /* task startup (chg_pri) */
+#define TPRI_RUN 0 /* specifies the highest priority during */
+ /* execution (rot_rdq) */
+
+
+/*
+ * Reference Task (ref_tsk) Structure
+ */
+
+typedef struct t_rtsk {
+ VP exinf; /* extended information */
+ PRI tskpri; /* current priority */
+ UINT tskstat; /* task state */
+ /*
+ * The following are represent extended features of support
+ * [level X] (implementation-dependent).
+ */
+ UINT tskwait; /* cause of wait */
+ ID wid; /* ID of object being waited for */
+ INT wupcnt; /* wakeup request count */
+ INT suscnt; /* SUSPEND request count */
+ ATR tskatr; /* task attributes */
+ FP task; /* task start address */
+ PRI itskpri; /* initial task priority */
+ INT stksz; /* stack size */
+} T_RTSK;
+
+/*
+ * Values for the tskstat field
+ */
+
+
+#define TTS_RUN 0x01 /* RUN */
+#define TTS_RDY 0x02 /* READY */
+#define TTS_WAI 0x04 /* WAIT */
+#define TTS_SUS 0x08 /* SUSPEND */
+#define TTS_WAS 0x0C /* WAIT-SUSPEND */
+#define TTS_DMT 0x10 /* DORMANT */
+
+/*
+ * Values for the tskwait field
+ */
+
+#define TTW_SLP 0x0001 /* wait due to slp_tsk or tslp_tsk */
+#define TTW_DLY 0x0002 /* wait due to dly_tsk */
+#define TTW_NOD 0x0008 /* connection function response wait */
+#define TTW_FLG 0x0010 /* wait due to wai_flg or twai_flg */
+#define TTW_SEM 0x0020 /* wait due to wai_sem or twai_sem */
+#define TTW_MBX 0x0040 /* wait due to rcv_msg or trcv_msg */
+#define TTW_SMBF 0x0080 /* wait due to snd_mbf or tsnd_mbf */
+#define TTW_MBF 0x0100 /* wait due to rcv_mbf or trcv_mbf */
+#define TTW_CAL 0x0200 /* wait for rendezvous call */
+#define TTW_ACP 0x0400 /* wait for rendezvous accept */
+#define TTW_RDV 0x0800 /* wait for rendezvous completion */
+#define TTW_MPL 0x1000 /* wait due to get_blk or tget_blk */
+#define TTW_MPF 0x2000 /* wait due to get_blf or tget_blf */
+
+/*
+ * Since the task states given by tskstat and tskwait are expressed
+ * by bit correspondences, they are convenient when looking for OR
+ * conditions (such as whether a task is in WAIT or READY state).
+ */
+
+/*
+ * Task Management Functions
+ */
+
+/*
+ * cre_tsk - Create Task
+ */
+
+ER cre_tsk(
+ ID tskid,
+ T_CTSK *pk_ctsk
+);
+
+/*
+ * del_tsk - Delete Task
+ */
+
+ER del_tsk(
+ ID tskid
+);
+
+/*
+ * sta_tsk - Start Task
+ */
+
+ER sta_tsk(
+ ID tskid,
+ INT stacd
+);
+
+/*
+ * ext_tsk - Exit Issuing Task
+ */
+
+void ext_tsk( void );
+
+/*
+ * exd_tsk - Exit and Delete Task
+ */
+
+void exd_tsk( void );
+
+/*
+ * ter_tsk - Terminate Other Task
+ */
+
+ER ter_tsk(
+ ID tskid
+);
+
+/*
+ * dis_dsp - Disable Dispatch
+ */
+
+ER dis_dsp( void );
+
+/*
+ * ena_dsp - Enable Dispatch
+ */
+
+ER ena_dsp( void );
+
+/*
+ * chg_pri - Change Task Priority
+ */
+
+ER chg_pri(
+ ID tskid,
+ PRI tskpri
+);
+
+/*
+ * rot_rdq - Rotate Tasks on the Ready Queue
+ */
+
+ER rot_rdq(
+ PRI tskpri
+);
+
+/*
+ * rel_wai - Release Wait of Other Task
+ */
+
+ER rel_wai(
+ ID tskid
+);
+
+/*
+ * get_tid - Get Task Identifier
+ */
+
+ER get_tid(
+ ID *p_tskid
+);
+
+/*
+ * ref_tsk - Reference Task Status
+ */
+
+ER ref_tsk(
+ T_RTSK *pk_rtsk,
+ ID tskid
+);
+
+
+/*
+ * Task-Dependent Synchronization Functions
+ */
+
+/*
+ * sus_tsk - Suspend Other Task
+ */
+
+ER sus_tsk(
+ ID tskid
+);
+
+/*
+ * rsm_tsk - Resume Suspended Task
+ */
+
+ER rsm_tsk(
+ ID tskid
+);
+
+/*
+ * frsm_tsk - Forcibly Resume Suspended Task
+ */
+
+ER frsm_tsk(
+ ID tskid
+);
+
+/*
+ * slp_tsk - Sleep Task Sleep Task with Timeout
+ */
+
+ER slp_tsk( void );
+
+/*
+ * tslp_tsk - Sleep Task with Timeout
+ */
+
+ER tslp_tsk(
+ TMO tmout
+);
+
+/*
+ * wup_tsk - Wakeup Other Task
+ */
+
+ER wup_tsk(
+ ID tskid
+);
+
+/*
+ * can_wup - Cancel Wakeup Request
+ */
+
+ER can_wup(
+ INT *p_wupcnt,
+ ID tskid
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/time.h b/cpukit/itron/include/itronsys/time.h
new file mode 100644
index 0000000000..938e8d9f21
--- /dev/null
+++ b/cpukit/itron/include/itronsys/time.h
@@ -0,0 +1,188 @@
+/**
+ * @file itronsys/time.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_TIME_H
+#define _ITRONSYS_TIME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * System Time Data Type
+ *
+ * Member configuration depends on the bit width of the processor and
+ * on the implementation. A total of 48 bits is recommended.
+ *
+ */
+
+typedef struct t_systime {
+ H utime; /* upper 16 bits */
+ UW ltime; /* lower 32 bits */
+} SYSTIME, CYCTIME, ALMTIME;
+
+/*
+ * XXX Look this up in the spec and figure out where it comes
+ * XXX from. dly_tim() references it but it was left out
+ * XXX of the initial cut at the header files.
+ */
+
+typedef int DLYTIME;
+
+/*
+ * XXX (def_cyc) Structure
+ */
+
+typedef struct t_dcyc {
+ VP exinf; /* extended information */
+ ATR cycatr; /* cyclic handler attributes */
+ FP cychdr; /* cyclic handler address */
+ UINT cycact; /* cyclic handler activation */
+ CYCTIME cyctim; /* cyclic startup period */
+} T_DCYC;
+
+/*
+ * cycact
+ */
+
+#define TCY_OFF 0x00 /* do not invoke cyclic handler */
+#define TCY_ON 0x01 /* invoke cyclic handler */
+#define TCY_INT 0x02 /* initialize cycle count */
+
+/*
+ * Reference Cyclic Handler (ref_cyc) Structure
+ */
+
+typedef struct t_rcyc {
+ VP exinf; /* extended information */
+ CYCTIME lfttim; /* time left before next handler startup */
+ UINT cycact; /* cyclic handler activation */
+ /* additional information may be included depending on the implementation */
+} T_RCYC;
+
+/*
+ * Define Alarm (def_alm) Structure
+ */
+
+typedef struct t_dalm {
+ VP exinf; /* extended information */
+ ATR almatr; /* alarm handler attributes */
+ FP almhdr; /* alarm handler address */
+ UINT tmmode; /* start time specification mode */
+ ALMTIME almtim; /* handler startup time */
+} T_DALM;
+
+/*
+ * tmmode
+ */
+
+#define TTM_ABS 0x00 /* specified as an absolute time */
+#define TTM_REL 0x01 /* specified as a relative time */
+
+/*
+ * Reference Alarm (ref_alm) Structure
+ */
+
+typedef struct t_ralm {
+ VP exinf; /* extended information */
+ ALMTIME lfttim; /* time left before next handler startup */
+ /* additional information may be included depending on the implementation */
+} T_RALM;
+
+/*
+ * Time Management Functions
+ */
+
+/*
+ * set_tim - Set System Clock
+ */
+
+ER set_tim(
+ SYSTIME *pk_tim
+);
+
+/*
+ * get_tim - Get System Clock
+ */
+
+ER get_tim(
+ SYSTIME *pk_tim
+);
+
+/*
+ * dly_tsk - Delay Task
+ */
+
+ER dly_tsk(
+ DLYTIME dlytim
+);
+
+/*
+ * def_cyc - Define Cyclic Handler
+ */
+
+ER def_cyc(
+ HNO cycno,
+ T_DCYC *pk_dcyc
+);
+
+/*
+ * act_cyc - Activate Cyclic Handler
+ */
+
+ER act_cyc(
+ HNO cycno,
+ UINT cycact
+);
+
+/*
+ * ref_cyc - Reference Cyclic Handler Status
+ */
+
+ER ref_cyc(
+ T_RCYC *pk_rcyc,
+ HNO cycno
+);
+
+/*
+ * def_alm - Define Alarm Handler
+ */
+
+ER def_alm(
+ HNO almno,
+ T_DALM *pk_dalm
+);
+
+/*
+ * ref_alm - Reference Alarm Handler Status
+ */
+
+ER ref_alm(
+ T_RALM *pk_ralm,
+ HNO almno
+);
+
+/*
+ * ret_tmr - Return from Timer Handler
+ */
+
+void ret_tmr( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/types.h b/cpukit/itron/include/itronsys/types.h
new file mode 100644
index 0000000000..1b3d80714d
--- /dev/null
+++ b/cpukit/itron/include/itronsys/types.h
@@ -0,0 +1,124 @@
+/**
+ * @file itronsys/types.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_TYPES_H
+#define _ITRONSYS_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* XXX some of these may need to be moved */
+/*
+ * XXX: These names are too short and conflict with numerous
+ * off the shell programs including paranoia.
+ */
+
+typedef int8_t B; /* signed 8-bit integer */
+typedef int16_t H; /* signed 16-bit integer */
+typedef int32_t W; /* signed 32-bit integer */
+typedef uint8_t UB; /* unsigned 8-bit integer */
+typedef uint16_t UH; /* unsigned 16-bit integer */
+typedef uint32_t UW; /* unsigned 32-bit integer */
+
+typedef uint32_t VW; /* unpredictable data type (32-bit size) */
+typedef uint16_t VH; /* unpredictable data type (16-bit size) */
+typedef uint8_t VB; /* unpredictable data type (8-bit size) */
+
+typedef void *VP; /* pointer to an unpredictable data type */
+
+typedef void (*FP)(); /* program start address */
+
+/*
+ * 6.4 Data Types
+ *
+ * The difference between VB, VH and VW and B, H and W is that only the
+ * number of bits is known for the former, not the data type of the
+ * contents. The latter clearly represent integers.
+ */
+
+/*
+ * Data Types Dependent on ITRON Specification
+ *
+ * In order to clarify the meanings of certain parameters, the
+ * following names are used for data types which appear frequently
+ * and/or have special meanings.
+ */
+
+typedef int32_t INT; /* Signed integer (bit width of processor) */
+typedef uint32_t UINT; /* Unsigned integer (bit width of processor) */
+typedef boolean BOOL; /* Boolean value. TRUE (1) or FALSE (0). */
+typedef int16_t FN; /* Function code. Signed integer. Maximum 2 bytes. */
+typedef int ID; /* Object ID number (???id) */
+ /* Value range depends on the system. Usually */
+ /* a signed integer. Certain ID values may */
+ /* represent objects on other nodes when the */
+ /* connection function is supported. */
+
+typedef uint32_t BOOL_ID;/* Boolean value or ID number */
+
+typedef int32_t HNO; /* Handler number */
+typedef int32_t RNO; /* Rendezvous number */
+typedef int32_t NODE; /* Node Number. Usually a signed integer. */
+typedef int32_t ATR; /* Object or handler attribute. */
+ /* An unsigned integer. */
+typedef int32_t ER; /* Error code. A signed integer. */
+typedef uint32_t PRI; /* Task priority. A signed integer. */
+typedef int32_t TMO; /* Timeout value. A signed integer. */
+ /* TMO_POL = 0 indicates polling, */
+ /* while TMO_FEVR = -1 indicates wait forever. */
+
+/*
+ * 6.6 Common Constants and Data Structure Packet Formats
+ */
+
+#define NADR (-1) /* invalid address or pointer value */
+
+#ifndef TRUE
+#define TRUE 1 /* true */
+#endif
+
+#ifndef FALSE
+#define FALSE 0 /* false */
+#endif
+
+/*
+ * ATR tskatr, intatr, cycatr, almatr, svcatr, excatr:
+ *
+ * TA_ASM indicates that the task or handler is directly started
+ * at the assembly language level. The TA_ASM attribute has the
+ * opposite meaning of TA_HLNG.
+ *
+ * NOTE: Really in <itronsys/task.h>
+ */
+
+#if 0
+#define TA_ASM 0x00 /* program written in assembly language */
+#define TA_HLNG 0x01 /* program written in high-level language */
+#endif
+
+/*
+ * TMO tmout:
+ */
+
+#define TMO_POL 0 /* polling */
+#define TMO_FEVR (-1) /* wait forever */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/itronsys/vmempool.h b/cpukit/itron/include/itronsys/vmempool.h
new file mode 100644
index 0000000000..0f6363a29d
--- /dev/null
+++ b/cpukit/itron/include/itronsys/vmempool.h
@@ -0,0 +1,135 @@
+/**
+ * @file itronsys/vmempool.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _ITRONSYS_VMEMPOOL_H
+#define _ITRONSYS_VMEMPOOL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Create Variable Memory Pool (cre_mpl) Structure
+ */
+
+typedef struct t_cmpl {
+ VP exinf; /* extended information */
+ ATR mplatr; /* memorypool attributes */
+ INT mplsz; /* memorypool size */
+ /* additional information may be included depending on the implementation */
+} T_CMPL;
+
+/*
+ * mplatr
+ */
+
+#define TA_TFIFO 0x00 /* waiting tasks are handled by FIFO */
+#define TA_TPRI 0x01 /* waiting tasks are handled by priority */
+
+/*
+ * mplid
+ */
+
+#define TMPL_OS (-4) /* memorypool used by OS */
+
+/*
+ * Reference Variable Memory Pool (ref_mpl) Structure
+ */
+
+typedef struct t_rmpl {
+ VP exinf; /* extended information */
+ BOOL_ID wtsk; /* indicates whether or not there are waiting tasks */
+ INT frsz; /* total size of free memory */
+ INT maxsz; /* size of largest contiguous memory */
+ /* additional information may be included depending on the implementation */
+} T_RMPL;
+
+/*
+ * Variable Memory Pool Functions
+ */
+
+/*
+ * cre_mpl - Create Variable-Size Memorypool
+ */
+
+ER cre_mpl(
+ ID mplid,
+ T_CMPL *pk_cmpl
+);
+
+/*
+ * del_mpl - Delete Variable-Size Memorypool
+ */
+
+ER del_mpl(
+ ID mplid
+);
+
+/*
+ * get_blk - Get Variable-Size Memory Block
+ */
+
+ER get_blk(
+ VP *p_blk,
+ ID mplid,
+ INT blksz
+);
+
+/*
+ * pget_blk - Poll and Get Variable-Size Memory Block
+ */
+
+ER pget_blk(
+ VP *p_blk,
+ ID mplid,
+ INT blksz
+);
+
+/*
+ * tget_blk - Get Variable-Size Memory Block with Timeout
+ */
+
+ER tget_blk(
+ VP *p_blk,
+ ID mplid,
+ INT blksz,
+ TMO tmout
+);
+
+/*
+ * rel_blk - Release Variable-Size Memory Block
+ */
+
+ER rel_blk(
+ ID mplid,
+ VP blk
+);
+
+/*
+ * ref_mpl - Reference Variable-Size Memorypool Status
+ */
+
+ER ref_mpl(
+ T_RMPL *pk_rmpl,
+ ID mplid
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/README b/cpukit/itron/include/rtems/itron/README
new file mode 100644
index 0000000000..9ac3bf3417
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/README
@@ -0,0 +1,10 @@
+#
+# $Id$
+#
+
+This directory contains the private interface of each manager.
+These files should only be included from the from the
+implementation of each manager.
+
+The public header file for each ITRON manager is in
+../../../tronsys. \ No newline at end of file
diff --git a/cpukit/itron/include/rtems/itron/config.h b/cpukit/itron/include/rtems/itron/config.h
new file mode 100644
index 0000000000..18776e2da2
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/config.h
@@ -0,0 +1,66 @@
+/**
+ * @file rtems/itron/config.h
+ */
+
+/* config.h
+ *
+ * This include file contains the table of user defined configuration
+ * parameters specific for the ITRON API.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_CONFIG_H
+#define _RTEMS_ITRON_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX
+ *
+ * The following records define the Configuration Table. The
+ * information contained in this table is required in all
+ * RTEMS systems, whether single or multiprocessor. This
+ * table primarily defines the following:
+ *
+ * + required number of each object type
+ */
+
+/*
+ * For now, we are only allowing the user to specify the entry point
+ * and stack size for ITRON initialization threads.
+ */
+
+typedef struct {
+ ID id;
+ T_CTSK attributes;
+} itron_initialization_tasks_table;
+
+typedef struct {
+ int maximum_tasks;
+ int maximum_semaphores;
+ int maximum_eventflags;
+ int maximum_mailboxes;
+ int maximum_message_buffers;
+ int maximum_ports;
+ int maximum_memory_pools;
+ int maximum_fixed_memory_pools;
+ int number_of_initialization_tasks;
+ itron_initialization_tasks_table *User_initialization_tasks_table;
+} itron_api_configuration_table;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/eventflags.h b/cpukit/itron/include/rtems/itron/eventflags.h
new file mode 100644
index 0000000000..5b1ab97b56
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/eventflags.h
@@ -0,0 +1,64 @@
+/**
+ * @file rtems/itron/eventflags.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_EVENTFLAGS_H
+#define _RTEMS_ITRON_EVENTFLAGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/itron/object.h>
+
+/*
+ * The following defines the control block used to manage each event flag.
+ */
+
+typedef struct {
+ ITRON_Objects_Control Object;
+ uint32_t XXX_more_stuff_goes_here;
+} ITRON_Eventflags_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+ITRON_EXTERN Objects_Information _ITRON_Eventflags_Information;
+
+/*
+ * _ITRON_Eventflags_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _ITRON_Eventflags_Manager_initialization(
+ uint32_t maximum_eventflags
+);
+
+/*
+ * XXX insert private stuff here
+ */
+
+#include <rtems/itron/eventflags.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/fmempool.h b/cpukit/itron/include/rtems/itron/fmempool.h
new file mode 100644
index 0000000000..2ef26fd411
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/fmempool.h
@@ -0,0 +1,65 @@
+/**
+ * @file rtems/itron/fmempool.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_FMEMPOOL_H
+#define _RTEMS_ITRON_FMEMPOOL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/itron/object.h>
+
+/*
+ * The following defines the control block used to manage each
+ * fixed memory pool.
+ */
+
+typedef struct {
+ ITRON_Objects_Control Object;
+ uint32_t XXX_more_stuff_goes_here;
+} ITRON_Fixed_memory_pool_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+ITRON_EXTERN Objects_Information _ITRON_Fixed_memory_pool_Information;
+
+/*
+ * _ITRON_Fixed_memory_pool_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _ITRON_Fixed_memory_pool_Manager_initialization(
+ uint32_t maximum_fixed_memory_pools
+);
+
+/*
+ * XXX insert private stuff here
+ */
+
+#include <rtems/itron/fmempool.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/intr.h b/cpukit/itron/include/rtems/itron/intr.h
new file mode 100644
index 0000000000..647c247555
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/intr.h
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/intr.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_INTR_H
+#define _RTEMS_ITRON_INTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert private stuff here
+ */
+
+#include <rtems/itron/intr.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/itronapi.h b/cpukit/itron/include/rtems/itron/itronapi.h
new file mode 100644
index 0000000000..b56b963610
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/itronapi.h
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/itronapi.h
+ */
+
+/*
+ * ITRON API Support
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_ITRONAPI_H
+#define _RTEMS_ITRON_ITRONAPI_H
+
+#include <rtems/config.h>
+
+/*
+ * _ITRON_API_Initialize
+ *
+ * Initialize the ITRON API.
+ */
+
+void _ITRON_API_Initialize(
+ rtems_configuration_table *configuration_table
+);
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/mbox.h b/cpukit/itron/include/rtems/itron/mbox.h
new file mode 100644
index 0000000000..94b13bb900
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/mbox.h
@@ -0,0 +1,76 @@
+/**
+ * @file rtems/itron/mbox.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_MBOX_H
+#define _RTEMS_ITRON_MBOX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/itron/object.h>
+#include <rtems/score/coremsg.h>
+
+/*
+ * The following defines the control block used to manage each mailbox.
+ */
+
+typedef struct {
+ ITRON_Objects_Control Object;
+ uint32_t count;
+ boolean do_message_priority;
+ CORE_message_queue_Control message_queue;
+} ITRON_Mailbox_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+ITRON_EXTERN Objects_Information _ITRON_Mailbox_Information;
+
+/*
+ * _ITRON_Mailbox_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _ITRON_Mailbox_Manager_initialization(
+ uint32_t maximum_mailboxes
+);
+
+/*
+ * _ITRON_Mailbox_Translate_core_message_queue_return_code
+ *
+ * DESCRIPTION:
+ *
+ * This routine translates a core message queue object status
+ * into the appropriate ITRON status code.
+ */
+
+ER _ITRON_Mailbox_Translate_core_message_queue_return_code(
+ CORE_message_queue_Status status
+);
+
+#include <rtems/itron/mbox.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/msgbuffer.h b/cpukit/itron/include/rtems/itron/msgbuffer.h
new file mode 100644
index 0000000000..9762c63e22
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/msgbuffer.h
@@ -0,0 +1,76 @@
+/**
+ * @file rtems/itron/msgbuffer.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_MSGBUFFER_H
+#define _RTEMS_ITRON_MSGBUFFER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/itron/object.h>
+#include <rtems/score/coremsg.h>
+
+/*
+ * The following defines the control block used to manage each
+ * message buffer.
+ */
+
+typedef struct {
+ ITRON_Objects_Control Object;
+ boolean is_priority_blocking;
+ CORE_message_queue_Control message_queue;
+} ITRON_Message_buffer_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+ITRON_EXTERN Objects_Information _ITRON_Message_buffer_Information;
+
+/*
+ * _ITRON_Message_buffer_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _ITRON_Message_buffer_Manager_initialization(
+ uint32_t maximum_message_buffers
+);
+
+/*
+ * _ITRON_Message_buffer_Translate_core_message_buffer_return_code
+ *
+ * DESCRIPTION:
+ *
+ * This routine translates a core message buffer object status
+ * into the appropriate ITRON status code.
+ */
+
+ER _ITRON_Message_buffer_Translate_core_message_buffer_return_code(
+ CORE_message_queue_Status status
+);
+
+#include <rtems/itron/msgbuffer.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/network.h b/cpukit/itron/include/rtems/itron/network.h
new file mode 100644
index 0000000000..a05d42b37f
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/network.h
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/network.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_NETWORK_H
+#define _RTEMS_ITRON_NETWORK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert private stuff here
+ */
+
+#include <rtems/itron/network.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/object.h b/cpukit/itron/include/rtems/itron/object.h
new file mode 100644
index 0000000000..6001651743
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/object.h
@@ -0,0 +1,123 @@
+/**
+ * @file rtems/itron/object.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_OBJECT_H
+#define _RTEMS_ITRON_OBJECT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+
+typedef Objects_Control ITRON_Objects_Control;
+
+/*
+ * Maximum length of an ITRON object name
+ *
+ * NOTE: Since ITRON objects do not have names, then then length is 0.
+ */
+
+#define ITRON_MAXIMUM_NAME_LENGTH 0
+
+/*
+ * _ITRON_Objects_Open
+ *
+ * Make this ITRON object visible to the system.
+ *
+ * NOTE: This macro hides the fact that ITRON objects don't have names.
+ */
+
+#define _ITRON_Objects_Open( _the_information, _the_object ) \
+ _Objects_Open( (_the_information), (_the_object), NULL )
+
+/*
+ * _ITRON_Objects_Close
+ *
+ * Make this ITRON object invisible from the system. Usually used as
+ * the first step of deleting an object.
+ */
+
+#define _ITRON_Objects_Close( _the_information, _the_object ) \
+ _Objects_Close( (_the_information), (_the_object) )
+
+/*
+ * _ITRON_Objects_Allocate_by_index
+ *
+ * Allocate the ITRON object specified by "_id". The ITRON id is the
+ * index portion of the traditional RTEMS ID. The Classic and POSIX
+ * APIs do not require that a specific object be allocated.
+ */
+
+#define _ITRON_Objects_Allocate_by_index( _the_information, _id, _sizeof ) \
+ _Objects_Allocate_by_index( (_the_information), (_id), (_sizeof) )
+
+/*
+ * _ITRON_Objects_Clarify_allocation_id_error
+ *
+ * This function is invoked when an object allocation ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Objects_Clarify_allocation_id_error( _the_information, _id ) \
+ (((_id) < -4) ? E_OACV : /* attempt to access a "system object" */ \
+ ((_id) <= 0) ? E_ID : /* bogus index of 0 - -3 */ \
+ ((_id) <= (_the_information)->maximum) ? E_OBJ : /* object is in use */ \
+ E_ID) /* simply a bad id */
+
+/*
+ * _ITRON_Objects_Clarify_get_id_error
+ *
+ * This function is invoked when an object get ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Objects_Clarify_get_id_error( _the_information, _id ) \
+ (((_id) < -4) ? E_OACV : /* attempt to access a "system object" */ \
+ ((_id) <= 0) ? E_ID : /* bogus index of 0 - -3 */ \
+ ((_id) <= (_the_information)->maximum) ? E_NOEXS : /* does not exist */ \
+ E_ID) /* simply a bad id */
+
+
+/*
+ * _ITRON_Objects_Free
+ *
+ * Free this ITRON object to the pool of inactive objects. This
+ * operation is the same as for the Classic and POSIX APIs.
+ */
+
+#define _ITRON_Objects_Free( _the_information, _the_object ) \
+ _Objects_Free( (_the_information), (_the_object) )
+
+
+/*
+ * _ITRON_Objects_Get
+ *
+ * Obtain (get) the pointer to the control block for the object
+ * specified by "id". The ITRON id passed in here is simply
+ * the "index" portion of the traditional RTEMS ID. This
+ * requires that this operation be slightly different
+ * from the object get used by the Classic and POSIX APIs.
+ */
+
+#define _ITRON_Objects_Get( _the_information, _id, _the_object ) \
+ _Objects_Get_by_index( (_the_information), (_id), (_the_object) )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/port.h b/cpukit/itron/include/rtems/itron/port.h
new file mode 100644
index 0000000000..f1c743a8b7
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/port.h
@@ -0,0 +1,64 @@
+/**
+ * @file rtems/itron/port.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_PORT_H
+#define _RTEMS_ITRON_PORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/itron/object.h>
+
+/*
+ * The following defines the control block used to manage each port.
+ */
+
+typedef struct {
+ ITRON_Objects_Control Object;
+ uint32_t XXX_more_stuff_goes_here;
+} ITRON_Port_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+ITRON_EXTERN Objects_Information _ITRON_Port_Information;
+
+/*
+ * _ITRON_Port_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _ITRON_Port_Manager_initialization(
+ uint32_t maximum_ports
+);
+
+/*
+ * XXX insert private stuff here
+ */
+
+#include <rtems/itron/port.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/semaphore.h b/cpukit/itron/include/rtems/itron/semaphore.h
new file mode 100644
index 0000000000..61f5913d84
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/semaphore.h
@@ -0,0 +1,62 @@
+/**
+ * @file rtems/itron/semaphore.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_SEMAPHORE_H
+#define _RTEMS_ITRON_SEMAPHORE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/itron/object.h>
+#include <rtems/score/coresem.h>
+
+/*
+ * The following defines the control block used to manage each semaphore.
+ */
+
+typedef struct {
+ ITRON_Objects_Control Object;
+ boolean is_priority_blocking;
+ CORE_semaphore_Control semaphore;
+} ITRON_Semaphore_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+ITRON_EXTERN Objects_Information _ITRON_Semaphore_Information;
+
+/*
+ * _ITRON_Semaphore_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _ITRON_Semaphore_Manager_initialization(
+ uint32_t maximum_semaphores
+);
+
+#include <rtems/itron/semaphore.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/sysmgmt.h b/cpukit/itron/include/rtems/itron/sysmgmt.h
new file mode 100644
index 0000000000..b78a35b600
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/sysmgmt.h
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/sysmgmt.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_SYSMGMT_H
+#define _RTEMS_ITRON_SYSMGMT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert private stuff here
+ */
+
+#include <rtems/itron/sysmgmt.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/task.h b/cpukit/itron/include/rtems/itron/task.h
new file mode 100644
index 0000000000..e7ad311b29
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/task.h
@@ -0,0 +1,105 @@
+/**
+ * @file rtems/itron/task.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_TASK_H
+#define _RTEMS_ITRON_TASK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/itron/object.h>
+#include <rtems/itron/config.h>
+#include <rtems/score/thread.h>
+
+/*
+ * This macro evaluates to TRUE if there should be a "context error."
+ * This is defined as a blocking directive being issed from
+ * task-independent portions or a task in dispatch disabled state.
+ *
+ * NOTE: Dispatching is disabled in interrupts so this should cover
+ * both cases.
+ */
+
+#define _ITRON_Is_in_non_task_state() \
+ (_Thread_Dispatch_disable_level != 0)
+
+/*
+ * This is the API specific information required by each thread for
+ * the ITRON API to function correctly.
+ */
+
+
+typedef struct {
+ uint32_t unused; /* no use for the API extension */
+ /* structure for ITRON identified yet */
+} ITRON_API_Control;
+
+/*
+ * The following defines the information control block used to
+ * manage this class of objects.
+ */
+
+ITRON_EXTERN Objects_Information _ITRON_Task_Information;
+
+/*
+ * These are used to manage the user initialization tasks.
+ */
+
+ITRON_EXTERN itron_initialization_tasks_table
+ *_ITRON_Task_User_initialization_tasks;
+ITRON_EXTERN uint32_t _ITRON_Task_Number_of_initialization_tasks;
+
+
+/*
+ * _ITRON_Task_Manager_initialization
+ *
+ * This routine initializes the ITRON Task Manager.
+ */
+
+void _ITRON_Task_Manager_initialization(
+ uint32_t maximum_tasks,
+ uint32_t number_of_initialization_tasks,
+ itron_initialization_tasks_table *user_tasks
+);
+
+/*
+ *
+ * _ITRON_Delete_task
+ */
+
+ER _ITRON_Delete_task(
+ Thread_Control *the_thread
+);
+
+/* XXX remove the need for this. Enable dispatch should not be hidden */
+
+#define _ITRON_return_errorno( _errno ) \
+do { \
+ _Thread_Enable_dispatch(); \
+ return _errno; \
+} while (0);
+
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/itron/task.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/time.h b/cpukit/itron/include/rtems/itron/time.h
new file mode 100644
index 0000000000..913b3bce06
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/time.h
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/time.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_TIME_H
+#define _RTEMS_ITRON_TIME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert private stuff here
+ */
+
+#include <rtems/itron/time.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/include/rtems/itron/vmempool.h b/cpukit/itron/include/rtems/itron/vmempool.h
new file mode 100644
index 0000000000..a89ba4d546
--- /dev/null
+++ b/cpukit/itron/include/rtems/itron/vmempool.h
@@ -0,0 +1,65 @@
+/**
+ * @file rtems/itron/vmempool.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_VMEMPOOL_H
+#define _RTEMS_ITRON_VMEMPOOL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/itron/object.h>
+
+/*
+ * The following defines the control block used to manage each variable
+ * memory pool.
+ */
+
+typedef struct {
+ ITRON_Objects_Control Object;
+ uint32_t XXX_more_stuff_goes_here;
+} ITRON_Variable_memory_pool_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+ITRON_EXTERN Objects_Information _ITRON_Variable_memory_pool_Information;
+
+/*
+ * _ITRON_Variable_memory_pool_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _ITRON_Variable_memory_pool_Manager_initialization(
+ uint32_t maximum_variable_memory_pools
+);
+
+/*
+ * XXX insert private stuff here
+ */
+
+#include <rtems/itron/vmempool.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/inline/rtems/itron/eventflags.inl b/cpukit/itron/inline/rtems/itron/eventflags.inl
new file mode 100644
index 0000000000..c2b8fbe936
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/eventflags.inl
@@ -0,0 +1,155 @@
+/**
+ * @file rtems/itron/eventflags.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_EVENTFLAGS_INL
+#define _RTEMS_ITRON_EVENTFLAGS_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Eventflags_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This routine allocates the eventflags associated with the specified
+ * eventflags ID from the pool of inactive eventflagss.
+ *
+ * Input parameters:
+ * flgid - id of eventflags to allocate
+ * status - pointer to status variable
+ *
+ * Output parameters:
+ * returns - pointer to the eventflags control block
+ * *status - status
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Eventflags_Control *_ITRON_Eventflags_Allocate(
+ ID flgid
+)
+{
+ return (ITRON_Eventflags_Control *)_ITRON_Objects_Allocate_by_index(
+ &_ITRON_Eventflags_Information,
+ flgid,
+ sizeof(ITRON_Eventflags_Control)
+ );
+}
+
+/*
+ * _ITRON_Eventflags_Clarify_allocation_id_error
+ *
+ * This function is invoked when an object allocation ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Eventflags_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Eventflags_Information, (_id) )
+
+/*
+ * _ITRON_Eventflags_Clarify_get_id_error
+ *
+ * This function is invoked when an object get ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Eventflags_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Eventflags_Information, (_id) )
+
+/*
+ * _ITRON_Eventflags_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a eventflags control block to the
+ * inactive chain of free eventflags control blocks.
+ *
+ * Input parameters:
+ * the_eventflags - pointer to eventflags control block
+ *
+ * Output parameters: NONE
+ */
+
+RTEMS_INLINE_ROUTINE void _ITRON_Eventflags_Free (
+ ITRON_Eventflags_Control *the_eventflags
+)
+{
+ _ITRON_Objects_Free( &_ITRON_Eventflags_Information, &the_eventflags->Object );
+}
+
+/*PAGE
+ *
+ * _ITRON_Eventflags_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps eventflags IDs to eventflags control blocks.
+ * If ID corresponds to a local eventflags, then it returns
+ * the_eventflags control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the eventflags ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_eventflags is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_eventflags is undefined.
+ *
+ * Input parameters:
+ * id - ITRON eventflags ID.
+ * the_location - pointer to a location variable
+ *
+ * Output parameters:
+ * *the_location - location of the object
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Eventflags_Control *_ITRON_Eventflags_Get (
+ ID id,
+ Objects_Locations *location
+)
+{
+ return (ITRON_Eventflags_Control *)
+ _ITRON_Objects_Get( &_ITRON_Eventflags_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _ITRON_Eventflags_Is_null
+ *
+ * This function returns TRUE if the_eventflags is NULL and FALSE otherwise.
+ *
+ * Input parameters:
+ * the_eventflags - pointer to eventflags control block
+ *
+ * Output parameters:
+ * TRUE - if the_eventflags is NULL
+ * FALSE - otherwise
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ITRON_Eventflags_Is_null (
+ ITRON_Eventflags_Control *the_eventflags
+)
+{
+ return ( the_eventflags == NULL );
+}
+
+/*
+ * XXX insert inline routines here
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/inline/rtems/itron/fmempool.inl b/cpukit/itron/inline/rtems/itron/fmempool.inl
new file mode 100644
index 0000000000..a76079ceec
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/fmempool.inl
@@ -0,0 +1,162 @@
+/**
+ * @file rtems/itron/fmempool.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_FMEMPOOL_INL
+#define _RTEMS_ITRON_FMEMPOOL_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Fixed_memory_pool_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This routine allocates the fixed_memory_pool associated with the specified
+ * fixed_memory_pool ID from the pool of inactive fixed_memory_pools.
+ *
+ * Input parameters:
+ * mpfid - id of fixed_memory_pool to allocate
+ * status - pointer to status variable
+ *
+ * Output parameters:
+ * returns - pointer to the fixed_memory_pool control block
+ * *status - status
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Fixed_memory_pool_Control
+ *_ITRON_Fixed_memory_pool_Allocate(
+ ID mpfid
+)
+{
+ return (ITRON_Fixed_memory_pool_Control *)_ITRON_Objects_Allocate_by_index(
+ &_ITRON_Fixed_memory_pool_Information,
+ mpfid,
+ sizeof(ITRON_Fixed_memory_pool_Control)
+ );
+}
+
+/*
+ * _ITRON_Fixed_memory_pool_Clarify_allocation_id_error
+ *
+ * This function is invoked when an object allocation ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Fixed_memory_pool_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Fixed_memory_pool_Information, (_id) )
+
+/*
+ * _ITRON_Fixed_memory_pool_Clarify_get_id_error
+ *
+ * This function is invoked when an object get ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Fixed_memory_pool_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( \
+ &_ITRON_Fixed_memory_pool_Information, (_id) )
+
+/*
+ * _ITRON_Fixed_memory_pool_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a fixed_memory_pool control block to the
+ * inactive chain of free fixed_memory_pool control blocks.
+ *
+ * Input parameters:
+ * the_fixed_memory_pool - pointer to fixed_memory_pool control block
+ *
+ * Output parameters: NONE
+ */
+
+RTEMS_INLINE_ROUTINE void _ITRON_Fixed_memory_pool_Free (
+ ITRON_Fixed_memory_pool_Control *the_fixed_memory_pool
+)
+{
+ _ITRON_Objects_Free(
+ &_ITRON_Fixed_memory_pool_Information,
+ &the_fixed_memory_pool->Object
+ );
+}
+
+/*PAGE
+ *
+ * _ITRON_Fixed_memory_pool_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps fixed memory pool IDs to control blocks.
+ * If ID corresponds to a local fixed memory pool, then it returns
+ * the_fixed memory pool control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the fixed memory pool ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the fixed memory pool is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the fixed memory pool is undefined.
+ *
+ * Input parameters:
+ * id - ITRON fixed memory pool ID.
+ * the_location - pointer to a location variable
+ *
+ * Output parameters:
+ * *the_location - location of the object
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Fixed_memory_pool_Control
+ *_ITRON_Fixed_memory_pool_Get (
+ ID id,
+ Objects_Locations *location
+)
+{
+ return (ITRON_Fixed_memory_pool_Control *)
+ _ITRON_Objects_Get( &_ITRON_Fixed_memory_pool_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _ITRON_Fixed_memory_pool_Is_null
+ *
+ * This function returns TRUE if the_fixed_memory_pool is NULL
+ * and FALSE otherwise.
+ *
+ * Input parameters:
+ * the_fixed_memory_pool - pointer to fixed_memory_pool control block
+ *
+ * Output parameters:
+ * TRUE - if the_fixed_memory_pool is NULL
+ * FALSE - otherwise
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ITRON_Fixed_memory_pool_Is_null (
+ ITRON_Fixed_memory_pool_Control *the_fixed_memory_pool
+)
+{
+ return ( the_fixed_memory_pool == NULL );
+}
+
+/*
+ * XXX insert inline routines here
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/inline/rtems/itron/intr.inl b/cpukit/itron/inline/rtems/itron/intr.inl
new file mode 100644
index 0000000000..39063c3309
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/intr.inl
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/intr.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_INTR_INL
+#define _RTEMS_ITRON_INTR_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert inline routines here
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/inline/rtems/itron/mbox.inl b/cpukit/itron/inline/rtems/itron/mbox.inl
new file mode 100644
index 0000000000..a8ea081b62
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/mbox.inl
@@ -0,0 +1,155 @@
+/**
+ * @file rtems/itron/mbox.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_MBOX_INL
+#define _RTEMS_ITRON_MBOX_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Mailbox_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This routine allocates the mailbox associated with the specified
+ * mailbox ID from the pool of inactive mailboxs.
+ *
+ * Input parameters:
+ * mbxid - id of mailbox to allocate
+ * status - pointer to status variable
+ *
+ * Output parameters:
+ * returns - pointer to the mailbox control block
+ * *status - status
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Mailbox_Control *_ITRON_Mailbox_Allocate(
+ ID mbxid
+)
+{
+ return (ITRON_Mailbox_Control *)_ITRON_Objects_Allocate_by_index(
+ &_ITRON_Mailbox_Information,
+ mbxid,
+ sizeof(ITRON_Mailbox_Control)
+ );
+}
+
+/*
+ * _ITRON_Mailbox_Clarify_allocation_id_error
+ *
+ * This function is invoked when an object allocation ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Mailbox_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Mailbox_Information, (_id) )
+
+/*
+ * _ITRON_Mailbox_Clarify_get_id_error
+ *
+ * This function is invoked when an object get ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Mailbox_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Mailbox_Information, (_id) )
+
+/*
+ * _ITRON_Mailbox_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a mailbox control block to the
+ * inactive chain of free mailbox control blocks.
+ *
+ * Input parameters:
+ * the_mailbox - pointer to mailbox control block
+ *
+ * Output parameters: NONE
+ */
+
+RTEMS_INLINE_ROUTINE void _ITRON_Mailbox_Free (
+ ITRON_Mailbox_Control *the_mailbox
+)
+{
+ _ITRON_Objects_Free( &_ITRON_Mailbox_Information, &the_mailbox->Object );
+}
+
+/*PAGE
+ *
+ * _ITRON_Mailbox_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps mailbox IDs to mailbox control blocks.
+ * If ID corresponds to a local mailbox, then it returns
+ * the_mailbox control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the mailbox ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_mailbox is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_mailbox is undefined.
+ *
+ * Input parameters:
+ * id - ITRON mailbox ID.
+ * the_location - pointer to a location variable
+ *
+ * Output parameters:
+ * *the_location - location of the object
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Mailbox_Control *_ITRON_Mailbox_Get (
+ ID id,
+ Objects_Locations *location
+)
+{
+ return (ITRON_Mailbox_Control *)
+ _ITRON_Objects_Get( &_ITRON_Mailbox_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _ITRON_Mailbox_Is_null
+ *
+ * This function returns TRUE if the_mailbox is NULL and FALSE otherwise.
+ *
+ * Input parameters:
+ * the_mailbox - pointer to mailbox control block
+ *
+ * Output parameters:
+ * TRUE - if the_mailbox is NULL
+ * FALSE - otherwise
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ITRON_Mailbox_Is_null (
+ ITRON_Mailbox_Control *the_mailbox
+)
+{
+ return ( the_mailbox == NULL );
+}
+
+/*
+ * XXX insert inline routines here
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/inline/rtems/itron/msgbuffer.inl b/cpukit/itron/inline/rtems/itron/msgbuffer.inl
new file mode 100644
index 0000000000..4790fdd158
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/msgbuffer.inl
@@ -0,0 +1,160 @@
+/**
+ * @file rtems/itron/msgbuffer.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_MSGBUFFER_INL
+#define _RTEMS_ITRON_MSGBUFFER_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Message_buffer_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This routine allocates the message buffer associated with the specified
+ * message buffer ID from the pool of inactive message buffers.
+ *
+ * Input parameters:
+ * mbfid - id of message buffer to allocate
+ * status - pointer to status variable
+ *
+ * Output parameters:
+ * returns - pointer to the message buffer control block
+ * *status - status
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Message_buffer_Control
+ *_ITRON_Message_buffer_Allocate(
+ ID mbfid
+)
+{
+ return (ITRON_Message_buffer_Control *)_ITRON_Objects_Allocate_by_index(
+ &_ITRON_Message_buffer_Information,
+ mbfid,
+ sizeof(ITRON_Message_buffer_Control)
+ );
+}
+
+/*
+ * _ITRON_Message_buffer_Clarify_allocation_id_error
+ *
+ * This function is invoked when an object allocation ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Message_buffer_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Message_buffer_Information, (_id) )
+
+/*
+ * _ITRON_Message_buffer_Clarify_get_id_error
+ *
+ * This function is invoked when an object get ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Message_buffer_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Message_buffer_Information, (_id) )
+
+/*
+ * _ITRON_Message_buffer_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a message buffer control block to the
+ * inactive chain of free message buffer control blocks.
+ *
+ * Input parameters:
+ * the_message_buffer - pointer to message_buffer control block
+ *
+ * Output parameters: NONE
+ */
+
+RTEMS_INLINE_ROUTINE void _ITRON_Message_buffer_Free (
+ ITRON_Message_buffer_Control *the_message_buffer
+)
+{
+ _ITRON_Objects_Free(
+ &_ITRON_Message_buffer_Information,
+ &the_message_buffer->Object
+ );
+}
+
+/*PAGE
+ *
+ * _ITRON_Message_buffer_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps message buffer IDs to message buffer control blocks.
+ * If ID corresponds to a local message buffer, then it returns
+ * the message buffer control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the message buffer ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the message buffer is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the message buffer is undefined.
+ *
+ * Input parameters:
+ * id - ITRON message_buffer ID.
+ * the_location - pointer to a location variable
+ *
+ * Output parameters:
+ * *the_location - location of the object
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Message_buffer_Control *_ITRON_Message_buffer_Get (
+ ID id,
+ Objects_Locations *location
+)
+{
+ return (ITRON_Message_buffer_Control *)
+ _ITRON_Objects_Get( &_ITRON_Message_buffer_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _ITRON_Message_buffer_Is_null
+ *
+ * This function returns TRUE if the_message_buffer is NULL
+ * and FALSE otherwise.
+ *
+ * Input parameters:
+ * the_message_buffer - pointer to message buffer control block
+ *
+ * Output parameters:
+ * TRUE - if the_message_buffer is NULL
+ * FALSE - otherwise
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ITRON_Message_buffer_Is_null (
+ ITRON_Message_buffer_Control *the_message_buffer
+)
+{
+ return ( the_message_buffer == NULL );
+}
+
+/*
+ * XXX insert inline routines here
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/inline/rtems/itron/network.inl b/cpukit/itron/inline/rtems/itron/network.inl
new file mode 100644
index 0000000000..6c8095c176
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/network.inl
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/network.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_NETWORK_INL
+#define _RTEMS_ITRON_NETWORK_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert inline routines here
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/inline/rtems/itron/port.inl b/cpukit/itron/inline/rtems/itron/port.inl
new file mode 100644
index 0000000000..6b17230153
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/port.inl
@@ -0,0 +1,155 @@
+/**
+ * @file rtems/itron/port.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_PORT_INL
+#define _RTEMS_ITRON_PORT_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Port_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This routine allocates the port associated with the specified
+ * port ID from the pool of inactive ports.
+ *
+ * Input parameters:
+ * porid - id of port to allocate
+ * status - pointer to status variable
+ *
+ * Output parameters:
+ * returns - pointer to the port control block
+ * *status - status
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Port_Control *_ITRON_Port_Allocate(
+ ID porid
+)
+{
+ return (ITRON_Port_Control *)_ITRON_Objects_Allocate_by_index(
+ &_ITRON_Port_Information,
+ porid,
+ sizeof(ITRON_Port_Control)
+ );
+}
+
+/*
+ * _ITRON_Port_Clarify_allocation_id_error
+ *
+ * This function is invoked when an object allocation ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Port_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Port_Information, (_id) )
+
+/*
+ * _ITRON_Port_Clarify_get_id_error
+ *
+ * This function is invoked when an object get ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Port_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Port_Information, (_id) )
+
+/*
+ * _ITRON_Port_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a port control block to the
+ * inactive chain of free port control blocks.
+ *
+ * Input parameters:
+ * the_port - pointer to port control block
+ *
+ * Output parameters: NONE
+ */
+
+RTEMS_INLINE_ROUTINE void _ITRON_Port_Free (
+ ITRON_Port_Control *the_port
+)
+{
+ _ITRON_Objects_Free( &_ITRON_Port_Information, &the_port->Object );
+}
+
+/*PAGE
+ *
+ * _ITRON_Port_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps port IDs to port control blocks.
+ * If ID corresponds to a local port, then it returns
+ * the_port control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the port ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_port is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_port is undefined.
+ *
+ * Input parameters:
+ * id - ITRON port ID.
+ * the_location - pointer to a location variable
+ *
+ * Output parameters:
+ * *the_location - location of the object
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Port_Control *_ITRON_Port_Get (
+ ID id,
+ Objects_Locations *location
+)
+{
+ return (ITRON_Port_Control *)
+ _ITRON_Objects_Get( &_ITRON_Port_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _ITRON_Port_Is_null
+ *
+ * This function returns TRUE if the_port is NULL and FALSE otherwise.
+ *
+ * Input parameters:
+ * the_port - pointer to port control block
+ *
+ * Output parameters:
+ * TRUE - if the_port is NULL
+ * FALSE - otherwise
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ITRON_Port_Is_null (
+ ITRON_Port_Control *the_port
+)
+{
+ return ( the_port == NULL );
+}
+
+/*
+ * XXX insert inline routines here
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/inline/rtems/itron/semaphore.inl b/cpukit/itron/inline/rtems/itron/semaphore.inl
new file mode 100644
index 0000000000..c57347f319
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/semaphore.inl
@@ -0,0 +1,187 @@
+/**
+ * @file rtems/itron/semaphore.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_SEMAPHORE_INL
+#define _RTEMS_ITRON_SEMAPHORE_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Semaphore_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This routine allocates the semaphore associated with the specified
+ * semaphore ID from the pool of inactive semaphores.
+ *
+ * Input parameters:
+ * semid - id of semaphore to allocate
+ * status - pointer to status variable
+ *
+ * Output parameters:
+ * returns - pointer to the semaphore control block
+ * *status - status
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Semaphore_Control *_ITRON_Semaphore_Allocate(
+ ID semid
+)
+{
+ return (ITRON_Semaphore_Control *)_ITRON_Objects_Allocate_by_index(
+ &_ITRON_Semaphore_Information,
+ semid,
+ sizeof(ITRON_Semaphore_Control)
+ );
+}
+
+/*
+ * _ITRON_Semaphore_Clarify_allocation_id_error
+ *
+ * This function is invoked when an object allocation ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Semaphore_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Semaphore_Information, (_id) )
+
+/*
+ * _ITRON_Semaphore_Clarify_get_id_error
+ *
+ * This function is invoked when an object get ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Semaphore_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Semaphore_Information, (_id) )
+
+/*
+ * _ITRON_Semaphore_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a semaphore control block to the
+ * inactive chain of free semaphore control blocks.
+ *
+ * Input parameters:
+ * the_semaphore - pointer to semaphore control block
+ *
+ * Output parameters: NONE
+ */
+
+RTEMS_INLINE_ROUTINE void _ITRON_Semaphore_Free (
+ ITRON_Semaphore_Control *the_semaphore
+)
+{
+ _ITRON_Objects_Free( &_ITRON_Semaphore_Information, &the_semaphore->Object );
+}
+
+/*PAGE
+ *
+ * _ITRON_Semaphore_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps semaphore IDs to semaphore control blocks.
+ * If ID corresponds to a local semaphore, then it returns
+ * the_semaphore control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the semaphore ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_semaphore is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_semaphore is undefined.
+ *
+ * Input parameters:
+ * id - ITRON semaphore ID.
+ * the_location - pointer to a location variable
+ *
+ * Output parameters:
+ * *the_location - location of the object
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Semaphore_Control *_ITRON_Semaphore_Get (
+ ID id,
+ Objects_Locations *location
+)
+{
+ return (ITRON_Semaphore_Control *)
+ _ITRON_Objects_Get( &_ITRON_Semaphore_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _ITRON_Semaphore_Is_null
+ *
+ * This function returns TRUE if the_semaphore is NULL and FALSE otherwise.
+ *
+ * Input parameters:
+ * the_semaphore - pointer to semaphore control block
+ *
+ * Output parameters:
+ * TRUE - if the_semaphore is NULL
+ * FALSE - otherwise
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ITRON_Semaphore_Is_null (
+ ITRON_Semaphore_Control *the_semaphore
+)
+{
+ return ( the_semaphore == NULL );
+}
+
+/*
+ * _ITRON_Semaphore_Translate_core_semaphore_return_code
+ *
+ * This function returns a ITRON status code based on the semaphore
+ * status code specified.
+ *
+ * Input parameters:
+ * the_semaphore_status - semaphore status code to translate
+ *
+ * Output parameters:
+ * ITRON status code - translated ITRON status code
+ *
+ */
+
+RTEMS_INLINE_ROUTINE ER _ITRON_Semaphore_Translate_core_semaphore_return_code (
+ uint32_t the_semaphore_status
+)
+{
+/* XXX need to be able to return "E_RLWAI" */
+ switch ( the_semaphore_status ) {
+ case CORE_SEMAPHORE_STATUS_SUCCESSFUL:
+ return E_OK;
+ case CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT:
+ return E_TMOUT;
+ case CORE_SEMAPHORE_WAS_DELETED:
+ return E_DLT;
+ case CORE_SEMAPHORE_TIMEOUT:
+ return E_TMOUT;
+ case CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED:
+ return E_QOVR;
+ case THREAD_STATUS_PROXY_BLOCKING:
+ return THREAD_STATUS_PROXY_BLOCKING;
+ }
+ return E_OK; /* unreached - only to remove warnings */
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/inline/rtems/itron/sysmgmt.inl b/cpukit/itron/inline/rtems/itron/sysmgmt.inl
new file mode 100644
index 0000000000..81b66c82bf
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/sysmgmt.inl
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/sysmgmt.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_SYSMGMT_INL
+#define _RTEMS_ITRON_SYSMGMT_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert inline routines here
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/inline/rtems/itron/task.inl b/cpukit/itron/inline/rtems/itron/task.inl
new file mode 100644
index 0000000000..02792e878b
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/task.inl
@@ -0,0 +1,185 @@
+/**
+ * @file rtems/itron/task.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_TASK_INL
+#define _RTEMS_ITRON_TASK_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Task_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This routine allocates the task associated with the specified
+ * task ID from the pool of inactive tasks.
+ *
+ * Input parameters:
+ * tskid - id of task to allocate
+ * status - pointer to status variable
+ *
+ * Output parameters:
+ * returns - pointer to the task control block
+ * *status - status
+ */
+
+RTEMS_INLINE_ROUTINE Thread_Control *_ITRON_Task_Allocate(
+ ID tskid
+)
+{
+ return (Thread_Control *)_ITRON_Objects_Allocate_by_index(
+ &_ITRON_Task_Information,
+ tskid,
+ sizeof(Thread_Control)
+ );
+}
+
+/*
+ * _ITRON_Task_Clarify_allocation_id_error
+ *
+ * This function is invoked when an object allocation ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Task_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Task_Information, (_id) )
+
+/*
+ * _ITRON_Task_Clarify_get_id_error
+ *
+ * This function is invoked when an object get ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Task_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Task_Information, (_id) )
+
+/*
+ * _ITRON_Task_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a task control block to the
+ * inactive chain of free task control blocks.
+ *
+ * Input parameters:
+ * the_task - pointer to task control block
+ *
+ * Output parameters: NONE
+ */
+
+RTEMS_INLINE_ROUTINE void _ITRON_Task_Free (
+ Thread_Control *the_task
+)
+{
+ _ITRON_Objects_Free( &_ITRON_Task_Information, &the_task->Object );
+}
+
+/*PAGE
+ *
+ * _ITRON_Task_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps task IDs to task control blocks.
+ * If ID corresponds to a local task, then it returns
+ * the_task control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the task ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_task is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_task is undefined.
+ *
+ * Input parameters:
+ * id - ITRON task ID.
+ * the_location - pointer to a location variable
+ *
+ * Output parameters:
+ * *the_location - location of the object
+ */
+
+RTEMS_INLINE_ROUTINE Thread_Control *_ITRON_Task_Get (
+ ID id,
+ Objects_Locations *location
+)
+{
+ if ( id == 0 ) {
+ _Thread_Disable_dispatch();
+ *location = OBJECTS_LOCAL;
+ return _Thread_Executing;
+ }
+
+ return (Thread_Control *)
+ _ITRON_Objects_Get( &_ITRON_Task_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _ITRON_Task_Is_null
+ *
+ * This function returns TRUE if the_task is NULL and FALSE otherwise.
+ *
+ * Input parameters:
+ * the_task - pointer to task control block
+ *
+ * Output parameters:
+ * TRUE - if the_task is NULL
+ * FALSE - otherwise
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ITRON_Task_Is_null (
+ Thread_Control *the_task
+)
+{
+ return ( the_task == NULL );
+}
+
+/*
+ * XXX insert inline routines here
+ */
+
+/*PAGE
+ *
+ * _ITRON_tasks_Priority_to_Core
+ */
+
+RTEMS_INLINE_ROUTINE Priority_Control _ITRON_Task_Priority_to_Core(
+ PRI ITRON_priority
+)
+{
+ return (Priority_Control) ITRON_priority;
+}
+
+/*PAGE
+ *
+ * _ITRON_tasks_Core_to_Priority
+ */
+
+RTEMS_INLINE_ROUTINE PRI _ITRON_Task_Core_to_Priority(
+ Priority_Control core_priority
+)
+{
+ return (PRI) core_priority;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/inline/rtems/itron/time.inl b/cpukit/itron/inline/rtems/itron/time.inl
new file mode 100644
index 0000000000..39f195cf3d
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/time.inl
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/time.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_TIME_INL
+#define _RTEMS_ITRON_TIME_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert inline routines here
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/inline/rtems/itron/vmempool.inl b/cpukit/itron/inline/rtems/itron/vmempool.inl
new file mode 100644
index 0000000000..4a4c1ccf3d
--- /dev/null
+++ b/cpukit/itron/inline/rtems/itron/vmempool.inl
@@ -0,0 +1,165 @@
+/**
+ * @file rtems/itron/vmempool.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_VMEMPOOL_INL
+#define _RTEMS_ITRON_VMEMPOOL_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Variable_memory_pool_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This routine allocates the variable memory pool associated with
+ * the specified variable memory pool ID from the pool of inactive
+ * variable memory pools.
+ *
+ * Input parameters:
+ * mplid - id of variable memory pool to allocate
+ * status - pointer to status variable
+ *
+ * Output parameters:
+ * returns - pointer to the variable memory pool control block
+ * *status - status
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Variable_memory_pool_Control
+ *_ITRON_Variable_memory_pool_Allocate(
+ ID mplid
+)
+{
+ return (ITRON_Variable_memory_pool_Control *)_ITRON_Objects_Allocate_by_index(
+ &_ITRON_Variable_memory_pool_Information,
+ mplid,
+ sizeof(ITRON_Variable_memory_pool_Control)
+ );
+}
+
+/*
+ * _ITRON_Variable_memory_pool_Clarify_allocation_id_error
+ *
+ * This function is invoked when an object allocation ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Variable_memory_pool_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Variable_memory_pool_Information, (_id) )
+
+/*
+ * _ITRON_Variable_memory_pool_Clarify_get_id_error
+ *
+ * This function is invoked when an object get ID error
+ * occurs to determine the specific ITRON error code to return.
+ */
+
+#define _ITRON_Variable_memory_pool_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Variable_memory_pool_Information, (_id) )
+
+/*
+ * _ITRON_Variable_memory_pool_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a variable memory pool control block to the
+ * inactive chain of free variable memory pool control blocks.
+ *
+ * Input parameters:
+ * the_variable_memory_pool - pointer to variable memory pool control block
+ *
+ * Output parameters: NONE
+ */
+
+RTEMS_INLINE_ROUTINE void _ITRON_Variable_memory_pool_Free (
+ ITRON_Variable_memory_pool_Control *the_variable_memory_pool
+)
+{
+ _ITRON_Objects_Free(
+ &_ITRON_Variable_memory_pool_Information,
+ &the_variable_memory_pool->Object
+ );
+}
+
+/*PAGE
+ *
+ * _ITRON_Variable_memory_pool_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps variable memory pool IDs to variable memory pool
+ * control blocks. If ID corresponds to a local variable memory pool,
+ * then it returns the variable memory pool control pointer which maps
+ * to ID and location is set to OBJECTS_LOCAL. if the variable memory
+ * pool ID is global and resides on a remote node, then location is set
+ * to OBJECTS_REMOTE, and the variable memory pool is undefined. Otherwise,
+ * location is set to OBJECTS ERROR and the variable memory pool is undefined.
+ *
+ * Input parameters:
+ * id - ITRON variable memory pool ID.
+ * the_location - pointer to a location variable
+ *
+ * Output parameters:
+ * *the_location - location of the object
+ */
+
+RTEMS_INLINE_ROUTINE ITRON_Variable_memory_pool_Control
+ *_ITRON_Variable_memory_pool_Get (
+ ID id,
+ Objects_Locations *location
+)
+{
+ return (ITRON_Variable_memory_pool_Control *) _ITRON_Objects_Get(
+ &_ITRON_Variable_memory_pool_Information,
+ id,
+ location
+ );
+}
+
+/*PAGE
+ *
+ * _ITRON_Variable_memory_pool_Is_null
+ *
+ * This function returns TRUE if the_variable_memory_pool is NULL
+ * and FALSE otherwise.
+ *
+ * Input parameters:
+ * the_variable_memory_pool - pointer to variable memory pool control block
+ *
+ * Output parameters:
+ * TRUE - if the_variable_memory_pool is NULL
+ * FALSE - otherwise
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ITRON_Variable_memory_pool_Is_null (
+ ITRON_Variable_memory_pool_Control *the_variable_memory_pool
+)
+{
+ return ( the_variable_memory_pool == NULL );
+}
+
+/*
+ * XXX insert inline routines here
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/macros/rtems/itron/eventflags.inl b/cpukit/itron/macros/rtems/itron/eventflags.inl
new file mode 100644
index 0000000000..b83d419f33
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/eventflags.inl
@@ -0,0 +1,80 @@
+/**
+ * @file rtems/itron/eventflags.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_EVENTFLAGS_INL
+#define _RTEMS_ITRON_EVENTFLAGS_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Eventflags_Allocate
+ */
+
+#define _ITRON_Eventflags_Allocate( _flgid ) \
+ (ITRON_Eventflags_Control *)_ITRON_Objects_Allocate_by_index( \
+ &_ITRON_Eventflags_Information, \
+ (_flgid), \
+ sizeof(ITRON_Eventflags_Control) \
+ )
+
+/*
+ * _ITRON_Eventflags_Clarify_allocation_id_error
+ */
+
+#define _ITRON_Eventflags_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Eventflags_Information, (_id) )
+
+/*
+ * _ITRON_Eventflags_Clarify_get_id_error
+ */
+
+#define _ITRON_Eventflags_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Eventflags_Information, (_id) )
+
+/*
+ * _ITRON_Eventflags_Free
+ */
+
+#define _ITRON_Eventflags_Free( _the_eventflags ) \
+ _ITRON_Objects_Free( &_ITRON_Eventflags_Information, \
+ &(_the_eventflags)->Object )
+
+
+/*
+ * _ITRON_Eventflags_Get
+ */
+
+#define _ITRON_Eventflags_Get( _id, _location ) \
+ (ITRON_Eventflags_Control *) \
+ _ITRON_Objects_Get( &_ITRON_Eventflags_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _ITRON_Eventflags_Is_null
+ */
+
+#define _ITRON_Eventflags_Is_null( _the_eventflags ) \
+ ( (_the_eventflags) == NULL );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/macros/rtems/itron/fmempool.inl b/cpukit/itron/macros/rtems/itron/fmempool.inl
new file mode 100644
index 0000000000..4a9fa252b7
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/fmempool.inl
@@ -0,0 +1,82 @@
+/**
+ * @file rtems/itron/fmempool.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_FMEMPOOL_INL
+#define _RTEMS_ITRON_FMEMPOOL_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Fixed_memory_pool_Allocate
+ */
+
+#define _ITRON_Fixed_memory_pool_Allocate( _mpfid ) \
+ (ITRON_Fixed_memory_pool_Control *)_ITRON_Objects_Allocate_by_index( \
+ &_ITRON_Fixed_memory_pool_Information, \
+ (_mpfid), \
+ sizeof(ITRON_Fixed_memory_pool_Control) \
+ )
+
+/*
+ * _ITRON_Fixed_memory_pool_Clarify_allocation_id_error
+ */
+
+#define _ITRON_Fixed_memory_pool_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Fixed_memory_pool_Information, (_id) )
+
+/*
+ * _ITRON_Fixed_memory_pool_Clarify_get_id_error
+ */
+
+#define _ITRON_Fixed_memory_pool_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( \
+ &_ITRON_Fixed_memory_pool_Information, (_id) )
+
+/*
+ * _ITRON_Fixed_memory_pool_Free
+ */
+
+#define _ITRON_Fixed_memory_pool_Free( _the_fixed_memory_pool ) \
+ _ITRON_Objects_Free( \
+ &_ITRON_Fixed_memory_pool_Information, \
+ &(_the_fixed_memory_pool)->Object \
+ )
+
+/*
+ * _ITRON_Fixed_memory_pool_Get
+ */
+
+#define _ITRON_Fixed_memory_pool_Get( _id, _location ) \
+ (ITRON_Fixed_memory_pool_Control *) \
+ _ITRON_Objects_Get( &_ITRON_Fixed_memory_pool_Information, \
+ (_id), (_location) )
+
+/*
+ * _ITRON_Fixed_memory_pool_Is_null
+ */
+
+#define _ITRON_Fixed_memory_pool_Is_null( _the_fixed_memory_pool ) \
+ ( (_the_fixed_memory_pool) == NULL )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/macros/rtems/itron/intr.inl b/cpukit/itron/macros/rtems/itron/intr.inl
new file mode 100644
index 0000000000..39063c3309
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/intr.inl
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/intr.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_INTR_INL
+#define _RTEMS_ITRON_INTR_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert inline routines here
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/macros/rtems/itron/mbox.inl b/cpukit/itron/macros/rtems/itron/mbox.inl
new file mode 100644
index 0000000000..c4e87203ad
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/mbox.inl
@@ -0,0 +1,79 @@
+/**
+ * @file rtems/itron/mbox.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_MBOX_INL
+#define _RTEMS_ITRON_MBOX_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Mailbox_Allocate
+ */
+
+#define _ITRON_Mailbox_Allocate( _mbxid ) \
+ (ITRON_Mailbox_Control *)_ITRON_Objects_Allocate_by_index( \
+ &_ITRON_Mailbox_Information, \
+ (_mbxid), \
+ sizeof(ITRON_Mailbox_Control) \
+ )
+
+/*
+ * _ITRON_Mailbox_Clarify_allocation_id_error
+ */
+
+#define _ITRON_Mailbox_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Mailbox_Information, (_id) )
+
+/*
+ * _ITRON_Mailbox_Clarify_get_id_error
+ */
+
+#define _ITRON_Mailbox_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Mailbox_Information, (_id) )
+
+/*
+ * _ITRON_Mailbox_Free
+ */
+
+#define _ITRON_Mailbox_Free( _the_mailbox ) \
+ _ITRON_Objects_Free( &_ITRON_Mailbox_Information, &(_the_mailbox)->Object )
+
+/*PAGE
+ *
+ * _ITRON_Mailbox_Get
+ */
+
+#define _ITRON_Mailbox_Get( _id, _location ) \
+ (ITRON_Mailbox_Control *) \
+ _ITRON_Objects_Get( &_ITRON_Mailbox_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _ITRON_Mailbox_Is_null
+ */
+
+#define _ITRON_Mailbox_Is_null( _the_mailbox ) \
+ ( (_the_mailbox) == NULL )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/macros/rtems/itron/msgbuffer.inl b/cpukit/itron/macros/rtems/itron/msgbuffer.inl
new file mode 100644
index 0000000000..6a4f8fc4b1
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/msgbuffer.inl
@@ -0,0 +1,82 @@
+/**
+ * @file rtems/itron/msgbuffer.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_MSGBUFFER_INL
+#define _RTEMS_ITRON_MSGBUFFER_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Message_buffer_Allocate
+ */
+
+#define _ITRON_Message_buffer_Allocate( _mbfid ) \
+ (ITRON_Message_buffer_Control *)_ITRON_Objects_Allocate_by_index( \
+ &_ITRON_Message_buffer_Information, \
+ (_mbfid), \
+ sizeof(ITRON_Message_buffer_Control) \
+ )
+
+/*
+ * _ITRON_Message_buffer_Clarify_allocation_id_error
+ */
+
+#define _ITRON_Message_buffer_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Message_buffer_Information, (_id) )
+
+/*
+ * _ITRON_Message_buffer_Clarify_get_id_error
+ */
+
+#define _ITRON_Message_buffer_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Message_buffer_Information, (_id) )
+
+/*
+ * _ITRON_Message_buffer_Free
+ */
+
+#define _ITRON_Message_buffer_Free( _the_message_buffer ) \
+ _ITRON_Objects_Free( \
+ &_ITRON_Message_buffer_Information, \
+ &(_the_message_buffer)->Object \
+ )
+
+/*PAGE
+ *
+ * _ITRON_Message_buffer_Get
+ */
+
+#define _ITRON_Message_buffer_Get( _id, _location ) \
+ (ITRON_Message_buffer_Control *) \
+ _ITRON_Objects_Get( &_ITRON_Message_buffer_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _ITRON_Message_buffer_Is_null
+ */
+
+#define _ITRON_Message_buffer_Is_null( _the_message_buffer ) \
+ ( (_the_message_buffer) == NULL )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/macros/rtems/itron/network.inl b/cpukit/itron/macros/rtems/itron/network.inl
new file mode 100644
index 0000000000..6c8095c176
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/network.inl
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/network.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_NETWORK_INL
+#define _RTEMS_ITRON_NETWORK_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert inline routines here
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/macros/rtems/itron/port.inl b/cpukit/itron/macros/rtems/itron/port.inl
new file mode 100644
index 0000000000..153611d8b9
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/port.inl
@@ -0,0 +1,79 @@
+/**
+ * @file rtems/itron/port.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_PORT_INL
+#define _RTEMS_ITRON_PORT_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Port_Allocate
+ */
+
+#define _ITRON_Port_Allocate( _porid ) \
+ (ITRON_Port_Control *)_ITRON_Objects_Allocate_by_index( \
+ &_ITRON_Port_Information, \
+ (_porid), \
+ sizeof(ITRON_Port_Control) \
+ )
+
+/*
+ * _ITRON_Port_Clarify_allocation_id_error
+ */
+
+#define _ITRON_Port_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Port_Information, (_id) )
+
+/*
+ * _ITRON_Port_Clarify_get_id_error
+ */
+
+#define _ITRON_Port_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Port_Information, (_id) )
+
+/*
+ * _ITRON_Port_Free
+ */
+
+#define _ITRON_Port_Free( _the_port ) \
+ _ITRON_Objects_Free( &_ITRON_Port_Information, &(_the_port)->Object )
+
+/*PAGE
+ *
+ * _ITRON_Port_Get
+ */
+
+#define _ITRON_Port_Get( _id, _location ) \
+ (ITRON_Port_Control *) \
+ _ITRON_Objects_Get( &_ITRON_Port_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _ITRON_Port_Is_null
+ */
+
+#define _ITRON_Port_Is_null( _the_port ) \
+ ( (_the_port) == NULL )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/macros/rtems/itron/semaphore.inl b/cpukit/itron/macros/rtems/itron/semaphore.inl
new file mode 100644
index 0000000000..bdf8020e3d
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/semaphore.inl
@@ -0,0 +1,106 @@
+/**
+ * @file rtems/itron/semaphore.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_SEMAPHORE_INL
+#define _RTEMS_ITRON_SEMAPHORE_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Semaphore_Allocate
+ */
+
+#define _ITRON_Semaphore_Allocate( _semid ) \
+ (ITRON_Semaphore_Control *)_ITRON_Objects_Allocate_by_index( \
+ &_ITRON_Semaphore_Information, \
+ (_semid), \
+ sizeof(ITRON_Semaphore_Control) \
+ )
+
+/*
+ * _ITRON_Semaphore_Clarify_allocation_id_error
+ */
+
+#define _ITRON_Semaphore_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Semaphore_Information, (_id) )
+
+/*
+ * _ITRON_Semaphore_Clarify_get_id_error
+ */
+
+#define _ITRON_Semaphore_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Semaphore_Information, (_id) )
+
+/*
+ * _ITRON_Semaphore_Free
+ */
+
+#define _ITRON_Semaphore_Free( _the_semaphore ) \
+ _ITRON_Objects_Free( &_ITRON_Semaphore_Information, &(_the_semaphore)->Object )
+
+/*PAGE
+ *
+ * _ITRON_Semaphore_Get
+ */
+
+#define _ITRON_Semaphore_Get( _id, _location ) \
+ (ITRON_Semaphore_Control *) \
+ _ITRON_Objects_Get( &_ITRON_Semaphore_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _ITRON_Semaphore_Is_null
+ */
+
+#define _ITRON_Semaphore_Is_null( _the_semaphore ) \
+ ( (_the_semaphore) == NULL )
+
+/*
+ * _ITRON_Semaphore_Translate_core_semaphore_return_code
+ */
+
+/* XXX fix me */
+static inline ER _ITRON_Semaphore_Translate_core_semaphore_return_code (
+ uint32_t the_semaphore_status
+)
+{
+/* XXX need to be able to return "E_RLWAI" */
+ switch ( the_semaphore_status ) {
+ case CORE_SEMAPHORE_STATUS_SUCCESSFUL:
+ return E_OK;
+ case CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT:
+ return E_TMOUT;
+ case CORE_SEMAPHORE_WAS_DELETED:
+ return E_DLT;
+ case CORE_SEMAPHORE_TIMEOUT:
+ return E_TMOUT;
+ case CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED:
+ return E_QOVR;
+ case THREAD_STATUS_PROXY_BLOCKING:
+ return THREAD_STATUS_PROXY_BLOCKING;
+ }
+ return E_OK; /* unreached - only to remove warnings */
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/macros/rtems/itron/sysmgmt.inl b/cpukit/itron/macros/rtems/itron/sysmgmt.inl
new file mode 100644
index 0000000000..81b66c82bf
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/sysmgmt.inl
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/sysmgmt.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_SYSMGMT_INL
+#define _RTEMS_ITRON_SYSMGMT_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert inline routines here
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/macros/rtems/itron/task.inl b/cpukit/itron/macros/rtems/itron/task.inl
new file mode 100644
index 0000000000..ae4551181d
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/task.inl
@@ -0,0 +1,106 @@
+/**
+ * @file rtems/itron/task.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_TASK_INL
+#define _RTEMS_ITRON_TASK_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Task_Allocate
+ */
+
+#define _ITRON_Task_Allocate( _tskid ) \
+ (Thread_Control *)_ITRON_Objects_Allocate_by_index( \
+ &_ITRON_Task_Information, \
+ (_tskid), \
+ sizeof(Thread_Control) \
+ )
+
+/*
+ * _ITRON_Task_Clarify_allocation_id_error
+ */
+
+#define _ITRON_Task_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Task_Information, (_id) )
+
+/*
+ * _ITRON_Task_Clarify_get_id_error
+ */
+
+#define _ITRON_Task_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Task_Information, (_id) )
+
+/*
+ * _ITRON_Task_Free
+ */
+
+#define _ITRON_Task_Free( _the_task ) \
+ _ITRON_Objects_Free( &_ITRON_Task_Information, &(_the_task)->Object )
+
+/*PAGE
+ *
+ * _ITRON_Task_Get
+ */
+
+/* XXX fix me */
+static inline Thread_Control *_ITRON_Task_Get (
+ ID id,
+ Objects_Locations *location
+)
+{
+ if ( id == 0 ) {
+ _Thread_Disable_dispatch();
+ *location = OBJECTS_LOCAL;
+ return _Thread_Executing;
+ }
+
+ return (Thread_Control *)
+ _ITRON_Objects_Get( &_ITRON_Task_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _ITRON_Task_Is_null
+ */
+
+#define _ITRON_Task_Is_null( _the_task ) \
+ ( (_the_task) == NULL )
+
+/*PAGE
+ *
+ * _ITRON_tasks_Priority_to_Core
+ */
+
+#define _ITRON_Task_Priority_to_Core( _ITRON_priority ) \
+ ((Priority_Control) (_ITRON_priority))
+
+/*PAGE
+ *
+ * _ITRON_tasks_Core_to_Priority
+ */
+
+#define _ITRON_Task_Core_to_Priority( _core_priority ) \
+ ((PRI) (_core_priority))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/itron/macros/rtems/itron/time.inl b/cpukit/itron/macros/rtems/itron/time.inl
new file mode 100644
index 0000000000..39f195cf3d
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/time.inl
@@ -0,0 +1,34 @@
+/**
+ * @file rtems/itron/time.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_TIME_INL
+#define _RTEMS_ITRON_TIME_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX insert inline routines here
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/macros/rtems/itron/vmempool.inl b/cpukit/itron/macros/rtems/itron/vmempool.inl
new file mode 100644
index 0000000000..503d4a3301
--- /dev/null
+++ b/cpukit/itron/macros/rtems/itron/vmempool.inl
@@ -0,0 +1,85 @@
+/**
+ * @file rtems/itron/vmempool.inl
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ITRON_VMEMPOOL_INL
+#define _RTEMS_ITRON_VMEMPOOL_INL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * _ITRON_Variable_memory_pool_Allocate
+ */
+
+#define _ITRON_Variable_memory_pool_Allocate( _mplid ) \
+ (ITRON_Variable_memory_pool_Control *)_ITRON_Objects_Allocate_by_index( \
+ &_ITRON_Variable_memory_pool_Information, \
+ (_mplid), \
+ sizeof(ITRON_Variable_memory_pool_Control) \
+ )
+
+/*
+ * _ITRON_Variable_memory_pool_Clarify_allocation_id_error
+ */
+
+#define _ITRON_Variable_memory_pool_Clarify_allocation_id_error( _id ) \
+ _ITRON_Objects_Clarify_allocation_id_error( \
+ &_ITRON_Variable_memory_pool_Information, (_id) )
+
+/*
+ * _ITRON_Variable_memory_pool_Clarify_get_id_error
+ */
+
+#define _ITRON_Variable_memory_pool_Clarify_get_id_error( _id ) \
+ _ITRON_Objects_Clarify_get_id_error( &_ITRON_Variable_memory_pool_Information, (_id) )
+
+/*
+ * _ITRON_Variable_memory_pool_Free
+ */
+
+#define _ITRON_Variable_memory_pool_Free( _the_variable_memory_pool ) \
+ _ITRON_Objects_Free( \
+ &_ITRON_Variable_memory_pool_Information, \
+ &(_the_variable_memory_pool)->Object \
+ )
+
+/*PAGE
+ *
+ * _ITRON_Variable_memory_pool_Get
+ */
+
+#define _ITRON_Variable_memory_pool_Get( _id, _location ) \
+ (ITRON_Variable_memory_pool_Control *) _ITRON_Objects_Get( \
+ &_ITRON_Variable_memory_pool_Information, \
+ (_id), \
+ (_location) \
+ )
+
+/*PAGE
+ *
+ * _ITRON_Variable_memory_pool_Is_null
+ */
+
+#define _ITRON_Variable_memory_pool_Is_null( _the_variable_memory_pool ) \
+ ( (_the_variable_memory_pool) == NULL )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/itron/preinstall.am b/cpukit/itron/preinstall.am
new file mode 100644
index 0000000000..60916a37e8
--- /dev/null
+++ b/cpukit/itron/preinstall.am
@@ -0,0 +1,250 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+if HAS_ITRON
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/itron.h: include/itron.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron.h
+
+$(PROJECT_INCLUDE)/itronsys/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/itronsys
+ @: > $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+
+$(PROJECT_INCLUDE)/itronsys/eventflags.h: include/itronsys/eventflags.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/eventflags.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/eventflags.h
+
+$(PROJECT_INCLUDE)/itronsys/fmempool.h: include/itronsys/fmempool.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/fmempool.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/fmempool.h
+
+$(PROJECT_INCLUDE)/itronsys/intr.h: include/itronsys/intr.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/intr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/intr.h
+
+$(PROJECT_INCLUDE)/itronsys/mbox.h: include/itronsys/mbox.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/mbox.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/mbox.h
+
+$(PROJECT_INCLUDE)/itronsys/msgbuffer.h: include/itronsys/msgbuffer.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/msgbuffer.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/msgbuffer.h
+
+$(PROJECT_INCLUDE)/itronsys/network.h: include/itronsys/network.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/network.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/network.h
+
+$(PROJECT_INCLUDE)/itronsys/port.h: include/itronsys/port.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/port.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/port.h
+
+$(PROJECT_INCLUDE)/itronsys/semaphore.h: include/itronsys/semaphore.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/semaphore.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/semaphore.h
+
+$(PROJECT_INCLUDE)/itronsys/status.h: include/itronsys/status.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/status.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/status.h
+
+$(PROJECT_INCLUDE)/itronsys/sysmgmt.h: include/itronsys/sysmgmt.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/sysmgmt.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/sysmgmt.h
+
+$(PROJECT_INCLUDE)/itronsys/task.h: include/itronsys/task.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/task.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/task.h
+
+$(PROJECT_INCLUDE)/itronsys/time.h: include/itronsys/time.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/time.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/time.h
+
+$(PROJECT_INCLUDE)/itronsys/types.h: include/itronsys/types.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/types.h
+
+$(PROJECT_INCLUDE)/itronsys/vmempool.h: include/itronsys/vmempool.h $(PROJECT_INCLUDE)/itronsys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itronsys/vmempool.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itronsys/vmempool.h
+
+$(PROJECT_INCLUDE)/rtems/itron/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/itron
+ @: > $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/itron/config.h: include/rtems/itron/config.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/config.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/config.h
+
+$(PROJECT_INCLUDE)/rtems/itron/eventflags.h: include/rtems/itron/eventflags.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/eventflags.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/eventflags.h
+
+$(PROJECT_INCLUDE)/rtems/itron/fmempool.h: include/rtems/itron/fmempool.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/fmempool.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/fmempool.h
+
+$(PROJECT_INCLUDE)/rtems/itron/intr.h: include/rtems/itron/intr.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/intr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/intr.h
+
+$(PROJECT_INCLUDE)/rtems/itron/itronapi.h: include/rtems/itron/itronapi.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/itronapi.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/itronapi.h
+
+$(PROJECT_INCLUDE)/rtems/itron/mbox.h: include/rtems/itron/mbox.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/mbox.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/mbox.h
+
+$(PROJECT_INCLUDE)/rtems/itron/msgbuffer.h: include/rtems/itron/msgbuffer.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/msgbuffer.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/msgbuffer.h
+
+$(PROJECT_INCLUDE)/rtems/itron/network.h: include/rtems/itron/network.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/network.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/network.h
+
+$(PROJECT_INCLUDE)/rtems/itron/object.h: include/rtems/itron/object.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/object.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/object.h
+
+$(PROJECT_INCLUDE)/rtems/itron/port.h: include/rtems/itron/port.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/port.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/port.h
+
+$(PROJECT_INCLUDE)/rtems/itron/semaphore.h: include/rtems/itron/semaphore.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/semaphore.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/semaphore.h
+
+$(PROJECT_INCLUDE)/rtems/itron/sysmgmt.h: include/rtems/itron/sysmgmt.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/sysmgmt.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/sysmgmt.h
+
+$(PROJECT_INCLUDE)/rtems/itron/task.h: include/rtems/itron/task.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/task.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/task.h
+
+$(PROJECT_INCLUDE)/rtems/itron/time.h: include/rtems/itron/time.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/time.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/time.h
+
+$(PROJECT_INCLUDE)/rtems/itron/vmempool.h: include/rtems/itron/vmempool.h $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/vmempool.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/vmempool.h
+
+if INLINE
+$(PROJECT_INCLUDE)/rtems/itron/eventflags.inl: inline/rtems/itron/eventflags.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/eventflags.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/eventflags.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/fmempool.inl: inline/rtems/itron/fmempool.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/fmempool.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/fmempool.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/intr.inl: inline/rtems/itron/intr.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/intr.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/intr.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/mbox.inl: inline/rtems/itron/mbox.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/mbox.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/mbox.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/msgbuffer.inl: inline/rtems/itron/msgbuffer.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/msgbuffer.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/msgbuffer.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/network.inl: inline/rtems/itron/network.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/network.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/network.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/port.inl: inline/rtems/itron/port.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/port.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/port.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/semaphore.inl: inline/rtems/itron/semaphore.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/semaphore.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/semaphore.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/sysmgmt.inl: inline/rtems/itron/sysmgmt.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/sysmgmt.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/sysmgmt.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/task.inl: inline/rtems/itron/task.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/task.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/task.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/time.inl: inline/rtems/itron/time.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/time.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/time.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/vmempool.inl: inline/rtems/itron/vmempool.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/vmempool.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/vmempool.inl
+
+else
+$(PROJECT_INCLUDE)/rtems/itron/eventflags.inl: macros/rtems/itron/eventflags.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/eventflags.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/eventflags.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/fmempool.inl: macros/rtems/itron/fmempool.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/fmempool.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/fmempool.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/intr.inl: macros/rtems/itron/intr.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/intr.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/intr.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/mbox.inl: macros/rtems/itron/mbox.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/mbox.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/mbox.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/msgbuffer.inl: macros/rtems/itron/msgbuffer.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/msgbuffer.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/msgbuffer.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/network.inl: macros/rtems/itron/network.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/network.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/network.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/port.inl: macros/rtems/itron/port.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/port.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/port.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/semaphore.inl: macros/rtems/itron/semaphore.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/semaphore.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/semaphore.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/sysmgmt.inl: macros/rtems/itron/sysmgmt.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/sysmgmt.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/sysmgmt.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/task.inl: macros/rtems/itron/task.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/task.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/task.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/time.inl: macros/rtems/itron/time.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/time.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/time.inl
+
+$(PROJECT_INCLUDE)/rtems/itron/vmempool.inl: macros/rtems/itron/vmempool.inl $(PROJECT_INCLUDE)/rtems/itron/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/itron/vmempool.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/itron/vmempool.inl
+endif
+endif
diff --git a/cpukit/itron/src/.cvsignore b/cpukit/itron/src/.cvsignore
new file mode 100644
index 0000000000..000074c626
--- /dev/null
+++ b/cpukit/itron/src/.cvsignore
@@ -0,0 +1,4 @@
+stamp-h
+stamp-h.in
+config.h
+config.h.in
diff --git a/cpukit/itron/src/TODO b/cpukit/itron/src/TODO
new file mode 100644
index 0000000000..8b87f58c8a
--- /dev/null
+++ b/cpukit/itron/src/TODO
@@ -0,0 +1,13 @@
+#
+# $Id$
+#
+
+The overall status including a major item todo list is in the Status
+chapter of the RTEMS ITRON API User's Guide. This file contains very
+short things that need to be addressed.
+
++ unlimited object not support for allocate by index. Support either
+ needs to be added for this type of object or the manager initialization
+ code needs to consider it a fatal error to configure the object class
+ in this mode.
+
diff --git a/cpukit/itron/src/can_wup.c b/cpukit/itron/src/can_wup.c
new file mode 100644
index 0000000000..4a7efc639d
--- /dev/null
+++ b/cpukit/itron/src/can_wup.c
@@ -0,0 +1,52 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+/*
+ * can_wup - Cancel Wakeup Request
+ */
+
+ER can_wup(
+ INT *p_wupcnt,
+ ID tskid
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _ITRON_Task_Get( tskid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Task_Clarify_get_id_error( tskid );
+
+ case OBJECTS_LOCAL:
+ /*
+ * XXX - FILL ME IN.
+ */
+ break;
+ }
+
+ _ITRON_return_errorno( E_OK );
+}
diff --git a/cpukit/itron/src/chg_pri.c b/cpukit/itron/src/chg_pri.c
new file mode 100644
index 0000000000..a548535db4
--- /dev/null
+++ b/cpukit/itron/src/chg_pri.c
@@ -0,0 +1,68 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+/*
+ * chg_pri - Change Task Priority
+ */
+
+ER chg_pri(
+ ID tskid,
+ PRI tskpri
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+ Priority_Control new_priority;
+
+ the_thread = _ITRON_Task_Get( tskid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Task_Clarify_get_id_error( tskid );
+
+ case OBJECTS_LOCAL:
+ if (_States_Is_dormant( the_thread->current_state ))
+ _ITRON_return_errorno( E_OBJ );
+
+ if (( tskpri <= 0 ) || ( tskpri >= 256 ))
+ _ITRON_return_errorno( E_PAR );
+
+ new_priority = _ITRON_Task_Priority_to_Core( tskpri );
+ the_thread->real_priority = new_priority;
+
+ /*
+ * The priority should not be changed until later if priority
+ * inheratance has occured.
+ */
+
+ if ( the_thread->resource_count == 0 ||
+ the_thread->current_priority > new_priority )
+ _Thread_Change_priority( the_thread, new_priority, FALSE );
+
+ break;
+ }
+
+ _ITRON_return_errorno( E_OK );
+}
diff --git a/cpukit/itron/src/cre_mbf.c b/cpukit/itron/src/cre_mbf.c
new file mode 100644
index 0000000000..0275be2cc5
--- /dev/null
+++ b/cpukit/itron/src/cre_mbf.c
@@ -0,0 +1,89 @@
+/*
+ * ITRON Message Buffer Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/task.h>
+
+/*
+ * cre_mbf - Create MessageBuffer
+ */
+
+ER cre_mbf(
+ ID mbfid,
+ T_CMBF *pk_cmbf
+)
+{
+ CORE_message_queue_Attributes the_msgq_attributes;
+ ITRON_Message_buffer_Control *the_message_buffer;
+
+ /*
+ * Bad pointer to the attributes structure
+ */
+
+ if ( !pk_cmbf )
+ return E_PAR;
+
+ /*
+ * Bits were set that were note defined.
+ */
+
+ if (pk_cmbf->mbfatr & ~(TA_TPRI))
+ return E_RSATR;
+
+ if (pk_cmbf->bufsz < 0 || pk_cmbf->maxmsz < 0)
+ return E_PAR;
+
+ if (pk_cmbf->bufsz < pk_cmbf->maxmsz)
+ return E_PAR;
+
+ _Thread_Disable_dispatch(); /* prevents deletion */
+
+ the_message_buffer = _ITRON_Message_buffer_Allocate(mbfid);
+ if ( !the_message_buffer ) {
+ _Thread_Enable_dispatch();
+ return _ITRON_Message_buffer_Clarify_allocation_id_error(mbfid);
+ }
+
+ if ( pk_cmbf->mbfatr & TA_TPRI )
+ the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
+ else
+ the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
+
+ _CORE_message_queue_Initialize(
+ &the_message_buffer->message_queue,
+ &the_msgq_attributes,
+ pk_cmbf->bufsz / pk_cmbf->maxmsz,
+ pk_cmbf->maxmsz
+ );
+
+ _ITRON_Objects_Open( &_ITRON_Message_buffer_Information,
+ &the_message_buffer->Object );
+
+ /*
+ * If multiprocessing were supported, this is where we would announce
+ * the existence of the semaphore to the rest of the system.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#endif
+
+ _Thread_Enable_dispatch();
+
+ return E_OK;
+}
diff --git a/cpukit/itron/src/cre_mbx.c b/cpukit/itron/src/cre_mbx.c
new file mode 100644
index 0000000000..bc4d766814
--- /dev/null
+++ b/cpukit/itron/src/cre_mbx.c
@@ -0,0 +1,107 @@
+/*
+ * ITRON 3.0 Mailbox Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/mbox.h>
+#include <rtems/itron/task.h>
+
+/*
+ * cre_mbx - Create Mailbox
+ *
+ * Creates a Mailbox according to the following spec:
+ *
+ * ------Parameters-------------------------
+ * ID mbxid MailboxID
+ * T_CMBX *pk_cmbx Packet to Create Mailbox
+ * -----------------------------------------
+ * -*pk_cmbx members*-
+ * VP exinf ExtendedInformation
+ * ATR mbxatr MailboxAttributes
+ * (the use of the following information
+ * is implementation dependent)
+ * INT bufcnt BufferMessageCount
+ * (CPU and/or implementation-dependent information
+ * may also be included)
+ *
+ * ----Return Parameters--------------------
+ * ER ercd ErrorCode
+ * -----------------------------------------
+ *
+ *
+ * ----C Language Interface-----------------
+ * ER ercd = cre_mbx ( ID mbxid, T_CMBX *pk_cmbx ) ;
+ * -----------------------------------------
+ *
+ */
+
+ER cre_mbx(
+ ID mbxid,
+ T_CMBX *pk_cmbx
+)
+{
+ register ITRON_Mailbox_Control *the_mailbox;
+ CORE_message_queue_Attributes the_mailbox_attributes;
+
+ if ( !pk_cmbx )
+ return E_PAR;
+
+ if ((pk_cmbx->mbxatr & (TA_TPRI | TA_MPRI)) != 0 )
+ return E_RSATR;
+
+ _Thread_Disable_dispatch(); /* protects object pointer */
+
+ the_mailbox = _ITRON_Mailbox_Allocate( mbxid );
+ if ( !the_mailbox ) {
+ _Thread_Enable_dispatch();
+ return _ITRON_Mailbox_Clarify_allocation_id_error( mbxid );
+ }
+
+ the_mailbox->count = pk_cmbx->bufcnt;
+ if (pk_cmbx->mbxatr & TA_MPRI)
+ the_mailbox->do_message_priority = TRUE;
+ else
+ the_mailbox->do_message_priority = FALSE;
+
+ if (pk_cmbx->mbxatr & TA_TPRI)
+ the_mailbox_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
+ else
+ the_mailbox_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
+
+ if ( !_CORE_message_queue_Initialize(
+ &the_mailbox->message_queue,
+ OBJECTS_ITRON_MAILBOXES,
+ &the_mailbox_attributes,
+ the_mailbox->count,
+ sizeof(T_MSG *),
+ NULL ) ) { /* Multiprocessing not supported */
+ _ITRON_Mailbox_Free(the_mailbox);
+ _ITRON_return_errorno( E_OBJ );
+ }
+
+ _ITRON_Objects_Open( &_ITRON_Mailbox_Information, &the_mailbox->Object );
+
+ /*
+ * If multiprocessing were supported, this is where we would announce
+ * the existence of the semaphore to the rest of the system.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#endif
+
+ _ITRON_return_errorno( E_OK );
+}
diff --git a/cpukit/itron/src/cre_sem.c b/cpukit/itron/src/cre_sem.c
new file mode 100644
index 0000000000..3e6e005728
--- /dev/null
+++ b/cpukit/itron/src/cre_sem.c
@@ -0,0 +1,98 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/semaphore.h>
+#include <rtems/itron/task.h>
+#include <rtems/score/tod.h>
+
+/*
+ * cre_sem - Create Semaphore
+ *
+ * This function implements the ITRON 3.0 cre_sem() service.
+ */
+
+ER cre_sem(
+ ID semid,
+ T_CSEM *pk_csem
+)
+{
+ CORE_semaphore_Attributes the_semaphore_attributes;
+ ITRON_Semaphore_Control *the_semaphore;
+
+ /*
+ * Bad pointer to the attributes structure
+ */
+
+ if ( !pk_csem )
+ return E_PAR;
+
+ /*
+ * Bits were set that were note defined.
+ */
+
+ if ( pk_csem->sematr & _ITRON_SEMAPHORE_UNUSED_ATTRIBUTES )
+ return E_RSATR;
+
+ /*
+ * Initial semaphore count exceeds the maximum.
+ */
+
+ if ( pk_csem->isemcnt > pk_csem->maxsem )
+ return E_PAR;
+
+ /*
+ * This error is not in the specification but this condition
+ * does not make sense.
+ */
+
+ if ( pk_csem->maxsem == 0 )
+ return E_PAR;
+
+ _Thread_Disable_dispatch(); /* prevents deletion */
+
+ the_semaphore = _ITRON_Semaphore_Allocate( semid );
+ if ( !the_semaphore ) {
+ _Thread_Enable_dispatch();
+ return _ITRON_Semaphore_Clarify_allocation_id_error( semid );
+ }
+
+ if ( pk_csem->sematr & TA_TPRI )
+ the_semaphore_attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY;
+ else
+ the_semaphore_attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
+
+ the_semaphore_attributes.maximum_count = pk_csem->maxsem;
+
+ _CORE_semaphore_Initialize(
+ &the_semaphore->semaphore,
+ &the_semaphore_attributes,
+ pk_csem->isemcnt
+ );
+
+ _ITRON_Objects_Open( &_ITRON_Semaphore_Information, &the_semaphore->Object );
+
+ /*
+ * If multiprocessing were supported, this is where we would announce
+ * the existence of the semaphore to the rest of the system.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#endif
+
+ _Thread_Enable_dispatch();
+ return E_OK;
+}
diff --git a/cpukit/itron/src/cre_tsk.c b/cpukit/itron/src/cre_tsk.c
new file mode 100644
index 0000000000..85a24e52d9
--- /dev/null
+++ b/cpukit/itron/src/cre_tsk.c
@@ -0,0 +1,120 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * cre_tsk - Create Task
+ */
+
+ER cre_tsk(
+ ID tskid,
+ T_CTSK *pk_ctsk
+)
+{
+ register Thread_Control *the_thread;
+ boolean status;
+ Priority_Control core_priority;
+
+ /*
+ * Validate Parameters.
+ */
+
+ if ( pk_ctsk == NULL )
+ return E_PAR;
+
+ if ((pk_ctsk->tskatr != TA_ASM ) &&
+ (pk_ctsk->tskatr != TA_HLNG) &&
+ (pk_ctsk->tskatr != TA_COP0) &&
+ (pk_ctsk->tskatr != TA_COP1) &&
+ (pk_ctsk->tskatr != TA_COP2) &&
+ (pk_ctsk->tskatr != TA_COP3) &&
+ (pk_ctsk->tskatr != TA_COP4) &&
+ (pk_ctsk->tskatr != TA_COP5) &&
+ (pk_ctsk->tskatr != TA_COP6) &&
+ (pk_ctsk->tskatr != TA_COP7))
+ return E_RSATR;
+
+ if (( pk_ctsk->itskpri <= 0 ) || ( pk_ctsk->itskpri >= 256 ))
+ return E_PAR;
+ if ( pk_ctsk->task == NULL )
+ return E_PAR;
+ if ( pk_ctsk->stksz < 0 )
+ return E_PAR;
+
+ /*
+ * Disable dispatching.
+ */
+
+ _Thread_Disable_dispatch();
+
+ /*
+ * allocate the thread.
+ */
+
+ the_thread = _ITRON_Task_Allocate( tskid );
+ if ( !the_thread )
+ _ITRON_return_errorno( _ITRON_Task_Clarify_allocation_id_error( tskid ) );
+
+ /*
+ * Initialize the core thread for this task.
+ */
+
+ core_priority = _ITRON_Task_Priority_to_Core( pk_ctsk->itskpri );
+ status = _Thread_Initialize(
+ &_ITRON_Task_Information,
+ the_thread,
+ NULL,
+ pk_ctsk->stksz,
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ TRUE, /* XXX - All tasks FP (if the HW supports it) for now */
+#else
+ FALSE,
+#endif
+ core_priority,
+ TRUE, /* preemptible */
+ THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE,
+ NULL, /* no budget algorithm callout */
+ 0,
+ NULL
+ );
+
+ if ( !status ) {
+ _ITRON_Task_Free( the_thread );
+ _ITRON_return_errorno( E_NOMEM );
+ }
+
+ /*
+ * This insures we evaluate the process-wide signals pending when we
+ * first run.
+ *
+ * NOTE: Since the thread starts with all unblocked, this is necessary.
+ */
+
+ the_thread->do_post_task_switch_extension = TRUE;
+
+ the_thread->Start.entry_point = (Thread_Entry) pk_ctsk->task;
+
+ _ITRON_return_errorno( E_OK );
+}
diff --git a/cpukit/itron/src/del_mbf.c b/cpukit/itron/src/del_mbf.c
new file mode 100644
index 0000000000..0fea912942
--- /dev/null
+++ b/cpukit/itron/src/del_mbf.c
@@ -0,0 +1,58 @@
+/*
+ * ITRON Message Buffer Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/task.h>
+
+/*
+ * del_mbf - Delete MessageBuffer
+ */
+
+ER del_mbf(
+ ID mbfid
+)
+{
+ ITRON_Message_buffer_Control *the_message_buffer;
+ Objects_Locations location;
+
+ the_message_buffer = _ITRON_Message_buffer_Get(mbfid, &location);
+ switch (location) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR: /* Multiprocessing not supported */
+ return _ITRON_Message_buffer_Clarify_get_id_error(mbfid);
+
+ case OBJECTS_LOCAL:
+ _CORE_message_queue_Flush(&the_message_buffer->message_queue);
+ _ITRON_Objects_Close( &_ITRON_Message_buffer_Information,
+ &the_message_buffer->Object);
+ _ITRON_Message_buffer_Free(the_message_buffer);
+
+ /*
+ * If multiprocessing were supported, this is where we would announce
+ * the existence of the semaphore to the rest of the system.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#endif
+ _Thread_Enable_dispatch();
+ return E_OK;
+ }
+
+ return E_OK;
+}
diff --git a/cpukit/itron/src/del_mbx.c b/cpukit/itron/src/del_mbx.c
new file mode 100644
index 0000000000..e06bea2fb5
--- /dev/null
+++ b/cpukit/itron/src/del_mbx.c
@@ -0,0 +1,68 @@
+/*
+ * ITRON 3.0 Mailbox Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/mbox.h>
+#include <rtems/itron/task.h>
+
+/*
+ * del_mbx - Delete Mailbox
+ *
+ *
+ * ------Parameters--------------
+ * ID mbxid The Mailbox's ID
+ * ------------------------------
+ *
+ * -----Return Parameters-------
+ * ER ercd Itron Error Code
+ * -----------------------------
+ *
+ * -----C Language Interface----
+ * ER ercd = del_mbx(ID mbxid);
+ * -----------------------------
+ *
+ */
+
+ER del_mbx(
+ ID mbxid
+)
+{
+ register ITRON_Mailbox_Control *the_mailbox;
+ Objects_Locations location;
+
+ the_mailbox= _ITRON_Mailbox_Get( mbxid, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE:
+ return _ITRON_Mailbox_Clarify_get_id_error( mbxid );
+
+ case OBJECTS_LOCAL:
+ _Objects_Close( &_ITRON_Mailbox_Information, &the_mailbox->Object );
+
+ _CORE_message_queue_Close(
+ &the_mailbox->message_queue,
+ NULL, /* Multiprocessing not supported */
+ CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED
+ );
+
+ _ITRON_Mailbox_Free(the_mailbox);
+ break;
+ }
+
+ _ITRON_return_errorno( E_OK );
+}
diff --git a/cpukit/itron/src/del_sem.c b/cpukit/itron/src/del_sem.c
new file mode 100644
index 0000000000..94368c4a41
--- /dev/null
+++ b/cpukit/itron/src/del_sem.c
@@ -0,0 +1,68 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/semaphore.h>
+#include <rtems/itron/task.h>
+#include <rtems/score/tod.h>
+
+/*
+ * del_sem - Delete Semaphore
+ *
+ * This function implements the ITRON 3.0 del_sem() service.
+ */
+
+ER del_sem(
+ ID semid
+)
+{
+ ITRON_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _ITRON_Semaphore_Get( semid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* Multiprocessing not supported */
+ case OBJECTS_ERROR:
+ return _ITRON_Semaphore_Clarify_get_id_error( semid );
+
+ case OBJECTS_LOCAL:
+ _CORE_semaphore_Flush(
+ &the_semaphore->semaphore,
+ NULL, /* Multiprocessing not supported */
+ CORE_SEMAPHORE_WAS_DELETED
+ );
+
+ _ITRON_Objects_Close(
+ &_ITRON_Semaphore_Information,
+ &the_semaphore->Object
+ );
+
+ _ITRON_Semaphore_Free( the_semaphore );
+
+ /*
+ * If multiprocessing were supported, this is where we would announce
+ * the destruction of the semaphore to the rest of the system.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#endif
+
+ _Thread_Enable_dispatch();
+ return E_OK;
+
+ }
+ return E_OK;
+}
diff --git a/cpukit/itron/src/del_tsk.c b/cpukit/itron/src/del_tsk.c
new file mode 100644
index 0000000000..9d1ddb72b5
--- /dev/null
+++ b/cpukit/itron/src/del_tsk.c
@@ -0,0 +1,58 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * del_tsk - Delete Task
+ */
+
+ER del_tsk(
+ ID tskid
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+ ER result = E_OK; /* to avoid warning */
+
+ the_thread = _ITRON_Task_Get( tskid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Task_Clarify_get_id_error( tskid );
+
+ case OBJECTS_LOCAL:
+
+ if ( _Thread_Is_executing( the_thread ) )
+ _ITRON_return_errorno( E_OBJ );
+
+ if ( !_States_Is_dormant( the_thread->current_state ) )
+ _ITRON_return_errorno( E_OBJ );
+
+ result = _ITRON_Delete_task( the_thread );
+ break;
+ }
+
+ _ITRON_return_errorno( result );
+}
diff --git a/cpukit/itron/src/dis_dsp.c b/cpukit/itron/src/dis_dsp.c
new file mode 100644
index 0000000000..0f1561abaa
--- /dev/null
+++ b/cpukit/itron/src/dis_dsp.c
@@ -0,0 +1,40 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * dis_dsp - Disable Dispatch
+ */
+
+ER dis_dsp( void )
+{
+ /*
+ * Disable dispatch for protection
+ */
+
+ _Thread_Disable_dispatch();
+
+ return E_OK;
+}
diff --git a/cpukit/itron/src/ena_dsp.c b/cpukit/itron/src/ena_dsp.c
new file mode 100644
index 0000000000..da25d99206
--- /dev/null
+++ b/cpukit/itron/src/ena_dsp.c
@@ -0,0 +1,36 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * ena_dsp - Enable Dispatch
+ */
+
+ER ena_dsp( void )
+{
+ _Thread_Enable_dispatch();
+
+ return E_OK;
+}
diff --git a/cpukit/itron/src/eventflags.c b/cpukit/itron/src/eventflags.c
new file mode 100644
index 0000000000..11039cc78d
--- /dev/null
+++ b/cpukit/itron/src/eventflags.c
@@ -0,0 +1,159 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/eventflags.h>
+
+/*
+ * _ITRON_Eventflags_Manager_initialization
+ *
+ * This routine initializes all event flags manager related data structures.
+ *
+ * Input parameters:
+ * maximum_eventflags - maximum configured eventflags
+ *
+ * Output parameters: NONE
+ */
+
+void _ITRON_Eventflags_Manager_initialization(
+ uint32_t maximum_eventflags
+)
+{
+ _Objects_Initialize_information(
+ &_ITRON_Eventflags_Information, /* object information table */
+ OBJECTS_ITRON_API, /* object API */
+ OBJECTS_ITRON_EVENTFLAGS, /* object class */
+ maximum_eventflags, /* maximum objects of this class */
+ sizeof( ITRON_Eventflags_Control ),
+ /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ ITRON_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Register the MP Process Packet routine.
+ *
+ * NOTE: No MP Support YET in RTEMS ITRON implementation.
+ */
+
+}
+
+/*
+ * cre_flg - Create Eventflag
+ */
+
+ER cre_flg(
+ ID flgid,
+ T_CFLG *pk_cflg
+)
+{
+ return E_OK;
+}
+
+/*
+ * del_flg - Delete Eventflag
+ */
+
+ER del_flg(
+ ID flgid
+)
+{
+ return E_OK;
+}
+
+/*
+ * set_flg - Set Eventflag
+ */
+
+ER set_flg(
+ ID flgid,
+ UINT setptn
+)
+{
+ return E_OK;
+}
+
+/*
+ * clr_flg - Clear Eventflag
+ */
+
+ER clr_flg(
+ ID flgid,
+ UINT clrptn
+)
+{
+ return E_OK;
+}
+
+/*
+ * wai_flg - Wait on Eventflag
+ */
+
+ER wai_flg(
+ UINT *p_flgptn,
+ ID flgid,
+ UINT waiptn,
+ UINT wfmode
+)
+{
+ return E_OK;
+}
+
+/*
+ * pol_flg - Wait for Eventflag(Polling)
+ */
+
+ER pol_flg(
+ UINT *p_flgptn,
+ ID flgid,
+ UINT waiptn,
+ UINT wfmode
+)
+{
+ return E_OK;
+}
+
+/*
+ * twai_flg - Wait on Eventflag with Timeout
+ */
+
+ER twai_flg(
+ UINT *p_flgptn,
+ ID flgid,
+ UINT waiptn,
+ UINT wfmode,
+ TMO tmout
+)
+{
+ return E_OK;
+}
+
+/*
+ * ref_flg - Reference Eventflag Status
+ */
+
+ER ref_flg(
+ T_RFLG *pk_rflg,
+ ID flgid
+)
+{
+ return E_OK;
+}
diff --git a/cpukit/itron/src/exd_tsk.c b/cpukit/itron/src/exd_tsk.c
new file mode 100644
index 0000000000..c99282f4d8
--- /dev/null
+++ b/cpukit/itron/src/exd_tsk.c
@@ -0,0 +1,46 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+#include <assert.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+/*
+ * exd_tsk - Exit and Delete Task
+ */
+
+void exd_tsk( void )
+{
+ Objects_Information *the_information;
+
+ _Thread_Disable_dispatch();
+
+ the_information = _Objects_Get_information( _Thread_Executing->Object.id );
+
+ /* This should never happen if _Thread_Get() works right */
+ assert( the_information );
+
+ _Thread_Set_state( _Thread_Executing, STATES_DORMANT );
+ _ITRON_Delete_task( _Thread_Executing );
+
+ _Thread_Enable_dispatch();
+}
diff --git a/cpukit/itron/src/ext_tsk.c b/cpukit/itron/src/ext_tsk.c
new file mode 100644
index 0000000000..20b83ff471
--- /dev/null
+++ b/cpukit/itron/src/ext_tsk.c
@@ -0,0 +1,46 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * ext_tsk - Exit Issuing Task
+ */
+
+void ext_tsk( void )
+{
+ /*
+ * Figure out what to do if this happens.
+ * We can not return regardless
+ if ( _ITRON_Is_in_non_task_state() )
+ return E_CTX;
+ */
+
+ _Thread_Disable_dispatch();
+
+ _Thread_Set_state( _Thread_Executing, STATES_DORMANT );
+ _Thread_Reset( _Thread_Executing, NULL, 0 );
+
+ _Thread_Enable_dispatch();
+}
diff --git a/cpukit/itron/src/fmempool.c b/cpukit/itron/src/fmempool.c
new file mode 100644
index 0000000000..567b7cb358
--- /dev/null
+++ b/cpukit/itron/src/fmempool.c
@@ -0,0 +1,142 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/fmempool.h>
+
+/*
+ * _ITRON_Fixed_memory_pool_Manager_initialization
+ *
+ * This routine initializes all fixed memory pool manager related
+ * data structures.
+ *
+ * Input parameters:
+ * maximum_fixed_memory_pools - maximum configured fixed memory pools
+ *
+ * Output parameters: NONE
+ */
+
+void _ITRON_Fixed_memory_pool_Manager_initialization(
+ uint32_t maximum_fixed_memory_pools
+)
+{
+ _Objects_Initialize_information(
+ &_ITRON_Fixed_memory_pool_Information, /* object information table */
+ OBJECTS_ITRON_API, /* object API */
+ OBJECTS_ITRON_FIXED_MEMORY_POOLS, /* object class */
+ maximum_fixed_memory_pools, /* maximum objects of this class */
+ sizeof( ITRON_Fixed_memory_pool_Control ),
+ /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ ITRON_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Register the MP Process Packet routine.
+ *
+ * NOTE: No MP Support YET in RTEMS ITRON implementation.
+ */
+
+}
+
+/*
+ * cre_mpf - Create Fixed-Size Memorypool
+ */
+
+ER cre_mpf(
+ ID mpfid,
+ T_CMPF *pk_cmpf
+)
+{
+ return E_OK;
+}
+
+/*
+ * del_mpf - Delete Fixed-Size Memorypool
+ */
+
+ER del_mpf(
+ ID mpfid
+)
+{
+ return E_OK;
+}
+
+/*
+ * get_blf - Get Fixed-Size Memory Block
+ */
+
+ER get_blf(
+ VP *p_blf,
+ ID mpfid
+)
+{
+ return E_OK;
+}
+
+/*
+ * pget_blf - Poll and Get Fixed-Size Memory Block
+ */
+
+ER pget_blf(
+ VP *p_blf,
+ ID mpfid
+)
+{
+ return E_OK;
+}
+
+/*
+ * tget_blf - Get Fixed-Size Memory Block with Timeout
+ */
+
+ER tget_blf(
+ VP *p_blf,
+ ID mpfid,
+ TMO tmout
+)
+{
+ return E_OK;
+}
+
+/*
+ * rel_blf - Release Fixed-Size Memory Block
+ */
+
+ER rel_blf(
+ ID mpfid,
+ VP blf
+)
+{
+ return E_OK;
+}
+
+/*
+ * ref_mpf - Reference Fixed-Size Memorypool Status
+ */
+
+ER ref_mpf(
+ T_RMPF *pk_rmpf,
+ ID mpfid
+)
+{
+ return E_OK;
+}
diff --git a/cpukit/itron/src/frsm_tsk.c b/cpukit/itron/src/frsm_tsk.c
new file mode 100644
index 0000000000..7df43bce44
--- /dev/null
+++ b/cpukit/itron/src/frsm_tsk.c
@@ -0,0 +1,60 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * frsm_tsk - Forcibly Resume Suspended Task
+ */
+
+ER frsm_tsk(
+ ID tskid
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _ITRON_Task_Get( tskid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Task_Clarify_get_id_error( tskid );
+
+ case OBJECTS_LOCAL:
+ if ( _Thread_Is_executing( the_thread ) )
+ _ITRON_return_errorno( E_OBJ );
+
+ if (_States_Is_dormant( the_thread->current_state ))
+ _ITRON_return_errorno( E_OBJ );
+
+ if ( ! _States_Is_suspended(the_thread->current_state) )
+ _ITRON_return_errorno( E_OK );
+
+ _Thread_Resume( the_thread, TRUE );
+ break;
+ }
+
+ _ITRON_return_errorno( E_OK );
+
+}
diff --git a/cpukit/itron/src/get_tid.c b/cpukit/itron/src/get_tid.c
new file mode 100644
index 0000000000..e455179fe1
--- /dev/null
+++ b/cpukit/itron/src/get_tid.c
@@ -0,0 +1,41 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+/*
+ * get_tid - Get Task Identifier
+ */
+
+ER get_tid(
+ ID *p_tskid
+)
+{
+ /*
+ * This does not support multiprocessing. The id handling will have
+ * to be enhanced to support multiprocessing.
+ */
+
+ *p_tskid = _Objects_Get_index( _Thread_Executing->Object.id );
+ return E_OK;
+}
diff --git a/cpukit/itron/src/itronintr.c b/cpukit/itron/src/itronintr.c
new file mode 100644
index 0000000000..13520cf5f0
--- /dev/null
+++ b/cpukit/itron/src/itronintr.c
@@ -0,0 +1,110 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/intr.h>
+
+/*
+ * def_int - Define Interrupt Handler
+ */
+
+ER def_int(
+ UINT dintno,
+ T_DINT *pk_dint
+)
+{
+ return E_OK;
+}
+
+/*
+ * ret_int - Return from Interrupt Handler
+ */
+
+void ret_int( void )
+{
+}
+
+/*
+ * ret_wup - Return and Wakeup Task
+ */
+
+void ret_wup(
+ ID tskid
+)
+{
+}
+
+/*
+ * loc_cpu - Lock CPU
+ */
+
+ER loc_cpu( void )
+{
+ return E_OK;
+}
+
+/*
+ * unl_cpu - Unlock CPU
+ */
+
+ER unl_cpu( void )
+{
+ return E_OK;
+}
+
+/*
+ * dis_int - Disable Interrupt
+ */
+
+ER dis_int(
+ UINT eintno
+)
+{
+ return E_OK;
+}
+
+/*
+ * ena_int - Enable Interrupt
+ */
+
+ER ena_int(
+ UINT eintno
+)
+{
+ return E_OK;
+}
+
+/*
+ * chg_iXX - Change Interrupt Mask(Level or Priority)
+ */
+
+ER chg_iXX(
+ UINT iXXXX
+)
+{
+ return E_OK;
+}
+
+/*
+ * ref_iXX - Reference Interrupt Mask(Level or Priority)
+ */
+
+ER ref_iXX(
+ UINT *p_iXXXX
+)
+{
+ return E_OK;
+}
diff --git a/cpukit/itron/src/itronsem.c b/cpukit/itron/src/itronsem.c
new file mode 100644
index 0000000000..755b3fe840
--- /dev/null
+++ b/cpukit/itron/src/itronsem.c
@@ -0,0 +1,60 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/semaphore.h>
+#include <rtems/itron/task.h>
+#include <rtems/score/tod.h>
+
+/*
+ * _ITRON_Semaphore_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine initializes all semaphore manager related data structures.
+ *
+ * Input parameters:
+ * maximum_semaphores - maximum configured semaphores
+ *
+ * Output parameters: NONE
+ */
+
+void _ITRON_Semaphore_Manager_initialization(
+ uint32_t maximum_semaphores
+)
+{
+ _Objects_Initialize_information(
+ &_ITRON_Semaphore_Information, /* object information table */
+ OBJECTS_ITRON_API, /* object API */
+ OBJECTS_ITRON_SEMAPHORES, /* object class */
+ maximum_semaphores, /* maximum objects of this class */
+ sizeof( ITRON_Semaphore_Control ), /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ ITRON_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Register the MP Process Packet routine.
+ *
+ * NOTE: No MP Support YET in RTEMS ITRON implementation.
+ */
+
+}
diff --git a/cpukit/itron/src/itrontime.c b/cpukit/itron/src/itrontime.c
new file mode 100644
index 0000000000..a2971dbdb5
--- /dev/null
+++ b/cpukit/itron/src/itrontime.c
@@ -0,0 +1,247 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/itron/time.h>
+
+/*
+ * set_tim - Set System Clock
+ */
+
+void converTime(SYSTIME ms, TOD_Control *time)
+{
+ int millisecond;
+
+/* XXX need to dereference structure */
+#if 0
+ milisecond = ms % 1000;
+ tempSecond = ms / 1000;
+#else
+ millisecond = 0;
+#endif
+}
+
+
+/*
+ * set_tim - Set System Clock
+ */
+
+ER set_tim(
+ SYSTIME *pk_tim
+)
+{
+ Watchdog_Interval temp; /* an integer in seconds after conversion from SYSTIME */
+ TOD_Control the_tod;
+
+/* convert *pk_tim which is 48 bits integer in binary into an ordinary
+ integer in milliseconds */
+
+/* XXX */ temp = 0;
+ if(temp > 0) {
+ _Thread_Disable_dispatch();
+ _TOD_Set(&the_tod, temp);
+ _Thread_Enable_dispatch();
+ if(_TOD_Validate(&the_tod)){
+ return E_OK;
+ }
+ }
+ return E_SYS;
+}
+
+/*
+ * get_tim - Get System Clock
+ */
+
+ER get_tim(
+ SYSTIME *pk_tim
+)
+{
+ return E_OK;
+}
+
+/*
+ * dly_tsk - Delay Task
+ */
+
+ER dly_tsk(
+ DLYTIME dlytim
+)
+{
+ Watchdog_Interval ticks;
+
+ ticks = TOD_MILLISECONDS_TO_TICKS(dlytim);
+
+ _Thread_Disable_dispatch();
+ if ( ticks == 0 ) {
+ _Thread_Yield_processor();
+ } else {
+ _Thread_Set_state( _Thread_Executing, STATES_DELAYING );
+ _Watchdog_Initialize(
+ &_Thread_Executing->Timer,
+ _Thread_Delay_ended,
+ _Thread_Executing->Object.id,
+ NULL
+ );
+ _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks );
+ }
+ _Thread_Enable_dispatch();
+ return E_OK;
+}
+
+/*
+ * def_cyc - Define Cyclic Handler
+ */
+
+ER def_cyc(
+ HNO cycno,
+ T_DCYC *pk_dcyc
+)
+{
+ Watchdog_Control *object;
+#if 0
+ Watchdog_Interval timeInterval;
+#endif
+
+/* XXX */ object = 0;
+ if ( pk_dcyc->cycatr != TA_HLNG)
+ return E_RSATR;
+#if 0
+ timeInterval = pk_dcyc->cyctim / 1000;
+ object->delta_interval = timeInterval;
+#endif
+ _Watchdog_Initialize(
+ object,
+ pk_dcyc->cychdr,
+ cycno,
+ pk_dcyc->exinf);
+ _Watchdog_Deactivate(object);
+
+ return E_OK;
+}
+
+/*
+ * act_cyc - Activate Cyclic Handler
+ */
+
+ER act_cyc(
+ HNO cycno,
+ UINT cycact
+)
+{
+ Watchdog_Control *object;
+
+ if(cycact != TCY_OFF || cycact != TCY_ON)
+ return E_PAR;
+
+#if 0
+ if( object->Object_ID != cycno)
+ return E_NOEXS;
+#endif
+
+ _Watchdog_Activate(object);
+
+ return E_OK;
+}
+
+/*
+ * ref_cyc - Reference Cyclic Handler Status
+ */
+
+ER ref_cyc(
+ T_RCYC *pk_rcyc,
+ HNO cycno
+)
+{
+#if 0
+ int timeElapse_since_actCyclic;
+#endif
+ T_DCYC *pk_dcyc;
+#if 0
+ Watchdog_Control *object;
+#endif
+
+/* XXX */ pk_dcyc = 0;
+
+/* XXX will to use a "get" routine to map from id to object pointer */
+/* XXX and the object pointer should be of type specific to this manager */
+#if 0
+ if( object->Object_ID == cycno))
+#else
+ if ( 1 )
+#endif
+ {
+ pk_rcyc->exinf = pk_dcyc->exinf;
+ pk_rcyc->cycact = pk_dcyc->cycact;
+#if 0
+ pk_rcyc->lfttim = pk_dcyc->cyctim - timeElapse_since_actCyclic;
+#endif
+
+ return E_OK;
+ }
+ else
+ return E_NOEXS;
+}
+
+/*
+ * def_alm - Define Alarm Handler
+ */
+
+ER def_alm(
+ HNO almno,
+ T_DALM *pk_dalm
+)
+{
+#if 0
+ Objects_Control *objectAlrm;
+ Watchdog_Interval timeInterval;
+
+ timeInterval = pk_dalm->almtim / 1000;
+ (void) _Watchdog_Remove(&objectAlrm);
+ _Watchdog_Initialize(
+ objectAlrm,
+ pk_dalm->almhdr,
+ almno,
+ pk_dalm->exinf);
+ _Watchdong_Insert_seconds(objectAlrm,timeInterval);
+ _Thread_Enable_dispatch();
+#endif
+
+ return E_OK;
+}
+
+/*
+ * ref_alm - Reference Alarm Handler Status
+ */
+
+ER ref_alm(
+ T_RALM *pk_ralm,
+ HNO almno
+)
+{
+
+ return E_OK;
+}
+
+/*
+ * ret_tmr - Return from Timer Handler
+ */
+
+void ret_tmr( void )
+{
+}
diff --git a/cpukit/itron/src/mbox.c b/cpukit/itron/src/mbox.c
new file mode 100644
index 0000000000..19a4ca1257
--- /dev/null
+++ b/cpukit/itron/src/mbox.c
@@ -0,0 +1,59 @@
+/*
+ * ITRON 3.0 Mailbox Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/mbox.h>
+#include <rtems/itron/task.h>
+
+/*
+ * _ITRON_Mailbox_Manager_initialization
+ *
+ * This routine initializes all mailboxes manager related data structures.
+ *
+ * Input parameters:
+ * maximum_mailboxes - maximum configured mailboxes
+ *
+ * Output parameters: NONE
+ */
+
+void _ITRON_Mailbox_Manager_initialization(
+ uint32_t maximum_mailboxes
+)
+{
+ _Objects_Initialize_information(
+ &_ITRON_Mailbox_Information, /* object information table */
+ OBJECTS_ITRON_API, /* object API */
+ OBJECTS_ITRON_MAILBOXES, /* object class */
+ maximum_mailboxes, /* maximum objects of this class */
+ sizeof( ITRON_Mailbox_Control ), /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ ITRON_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Register the MP Process Packet routine.
+ *
+ * NOTE: No MP Support YET in RTEMS ITRON implementation.
+ */
+
+}
diff --git a/cpukit/itron/src/mboxtranslatereturncode.c b/cpukit/itron/src/mboxtranslatereturncode.c
new file mode 100644
index 0000000000..acd34f8b24
--- /dev/null
+++ b/cpukit/itron/src/mboxtranslatereturncode.c
@@ -0,0 +1,48 @@
+/*
+ * ITRON 3.0 Mailbox Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/mbox.h>
+#include <rtems/itron/task.h>
+
+/*
+ * _ITRON_Mailbox_Translate_core_message_queue_return_code
+ *
+ * This routine translates a core message queue object status
+ * into the appropriate ITRON status code.
+ */
+
+ER _ITRON_Mailbox_Translate_core_message_queue_return_code(
+ CORE_message_queue_Status status
+)
+{
+ switch (status) {
+ case CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL:
+ return E_OK;
+ case CORE_MESSAGE_QUEUE_STATUS_TOO_MANY:
+ return E_TMOUT;
+ case CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE:
+ return E_PAR;
+ case CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT:
+ return E_TMOUT;
+ case CORE_MESSAGE_QUEUE_STATUS_TIMEOUT:
+ return E_TMOUT;
+ default:
+ return E_ID;
+ }
+}
diff --git a/cpukit/itron/src/msgbuffer.c b/cpukit/itron/src/msgbuffer.c
new file mode 100644
index 0000000000..fdf714ec1f
--- /dev/null
+++ b/cpukit/itron/src/msgbuffer.c
@@ -0,0 +1,60 @@
+/*
+ * ITRON Message Buffer Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/task.h>
+
+/*
+ * _ITRON_Message_buffer_Manager_initialization
+ *
+ * This routine initializes all message buffer manager related data
+ * structures.
+ *
+ * Input parameters:
+ * maximum_message_buffers - maximum configured message buffers
+ *
+ * Output parameters: NONE
+ */
+
+void _ITRON_Message_buffer_Manager_initialization(
+ uint32_t maximum_message_buffers
+)
+{
+ _Objects_Initialize_information(
+ &_ITRON_Message_buffer_Information, /* object information table */
+ OBJECTS_ITRON_API, /* object API */
+ OBJECTS_ITRON_MESSAGE_BUFFERS, /* object class */
+ maximum_message_buffers, /* maximum objects of this class */
+ sizeof( ITRON_Message_buffer_Control ),
+ /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ ITRON_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Register the MP Process Packet routine.
+ *
+ * NOTE: No MP Support YET in RTEMS ITRON implementation.
+ */
+}
diff --git a/cpukit/itron/src/msgbuffertranslatereturncode.c b/cpukit/itron/src/msgbuffertranslatereturncode.c
new file mode 100644
index 0000000000..4623f2742a
--- /dev/null
+++ b/cpukit/itron/src/msgbuffertranslatereturncode.c
@@ -0,0 +1,48 @@
+/*
+ * ITRON Message Buffer Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/task.h>
+
+/*
+ * _ITRON_Message_buffer_Translate_core_message_buffer_return_code
+ *
+ * This routine translates a core message buffer object status
+ * into the appropriate ITRON status code.
+ */
+
+ER _ITRON_Message_buffer_Translate_core_message_buffer_return_code(
+ CORE_message_queue_Status status
+)
+{
+ switch (status) {
+ case CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL:
+ return E_OK;
+ case CORE_MESSAGE_QUEUE_STATUS_TOO_MANY:
+ return E_TMOUT;
+ case CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE:
+ return E_PAR;
+ case CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT:
+ return E_TMOUT;
+ case CORE_MESSAGE_QUEUE_STATUS_TIMEOUT:
+ return E_TMOUT;
+ default:
+ return E_ID;
+ }
+}
diff --git a/cpukit/itron/src/network.c b/cpukit/itron/src/network.c
new file mode 100644
index 0000000000..2922d3af9e
--- /dev/null
+++ b/cpukit/itron/src/network.c
@@ -0,0 +1,71 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/network.h>
+
+/*
+ * nrea_dat - Read Data from another Node
+ */
+
+ER nrea_dat(
+ INT *p_reasz,
+ VP dstadr,
+ NODE srcnode,
+ VP srcadr,
+ INT datsz
+)
+{
+ return E_OK;
+}
+
+/*
+ * nwri_dat - Write Data to another Node
+ */
+
+ER nwri_dat(
+ INT *p_wrisz,
+ NODE dstnode,
+ VP dstadr,
+ VP srcadr,
+ INT datsz
+)
+{
+ return E_OK;
+}
+
+/*
+ * nget_nod - Get Local Node Number
+ */
+
+ER nget_nod(
+ NODE *p_node
+)
+{
+ return E_OK;
+}
+
+/*
+ * nget_ver - Get Version Information of another Node
+ */
+
+ER nget_ver(
+ T_VER *pk_ver,
+ NODE node
+)
+{
+ return E_OK;
+}
diff --git a/cpukit/itron/src/port.c b/cpukit/itron/src/port.c
new file mode 100644
index 0000000000..7f5693c385
--- /dev/null
+++ b/cpukit/itron/src/port.c
@@ -0,0 +1,211 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/port.h>
+
+/*
+ * _ITRON_Port_Manager_initialization
+ *
+ * This routine initializes all ports manager related data structures.
+ *
+ * Input parameters:
+ * maximum_ports - maximum configured ports
+ *
+ * Output parameters: NONE
+ */
+
+void _ITRON_Port_Manager_initialization(
+ uint32_t maximum_ports
+)
+{
+ _Objects_Initialize_information(
+ &_ITRON_Port_Information, /* object information table */
+ OBJECTS_ITRON_API, /* object API */
+ OBJECTS_ITRON_PORTS, /* object class */
+ maximum_ports, /* maximum objects of this class */
+ sizeof( ITRON_Port_Control ), /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ ITRON_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Register the MP Process Packet routine.
+ *
+ * NOTE: No MP Support YET in RTEMS ITRON implementation.
+ */
+
+}
+
+/*
+ * cre_por - Create Port for Rendezvous
+ */
+
+ER cre_por(
+ ID porid,
+ T_CPOR *pk_cpor
+)
+{
+ return E_OK;
+}
+
+/*
+ * del_por - Delete Port for Rendezvous
+ */
+
+ER del_por(
+ ID porid
+)
+{
+ return E_OK;
+}
+
+/*
+ * cal_por - Call Port for Rendezvous Poll
+ */
+
+ER cal_por(
+ VP msg,
+ INT *p_rmsgsz,
+ ID porid,
+ UINT calptn,
+ INT cmsgsz
+)
+{
+ return E_OK;
+}
+
+/*
+ * pcal_por - Poll and Call Port for Rendezvous
+ */
+
+ER pcal_por(
+ VP msg,
+ INT *p_rmsgsz,
+ ID porid,
+ UINT calptn,
+ INT cmsgsz
+)
+{
+ return E_OK;
+}
+
+/*
+ * tcal_por - Call Port for Rendezvous with Timeout
+ */
+
+ER tcal_por(
+ VP msg,
+ INT *p_rmsgsz,
+ ID porid,
+ UINT calptn,
+ INT cmsgsz,
+ TMO tmout
+)
+{
+ return E_OK;
+}
+
+/*
+ * acp_por - Accept Port for Rendezvous Poll
+ */
+
+ER acp_por(
+ RNO *p_rdvno,
+ VP msg,
+ INT *p_cmsgsz,
+ ID porid,
+ UINT acpptn
+)
+{
+ return E_OK;
+}
+
+/*
+ * pacp_por - Poll and Accept Port for Rendezvous
+ */
+
+ER pacp_por(
+ RNO *p_rdvno,
+ VP msg,
+ INT *p_cmsgsz,
+ ID porid,
+ UINT acpptn
+)
+{
+ return E_OK;
+}
+
+/*
+ * tacp_por - Accept Port for Rendezvous with Timeout
+ */
+
+ER tacp_por(
+ RNO *p_rdvno,
+ VP msg,
+ INT *p_cmsgsz,
+ ID porid,
+ UINT acpptn,
+ TMO tmout
+)
+{
+ return E_OK;
+}
+
+/*
+ * fwd_por - Forward Rendezvous to Other Port
+ */
+
+ER fwd_por(
+ ID porid,
+ UINT calptn,
+ RNO rdvno,
+ VP msg,
+ INT cmsgsz
+)
+{
+ return E_OK;
+}
+
+/*
+ * rpl_rdv - Reply Rendezvous
+ */
+
+ER rpl_rdv(
+ RNO rdvno,
+ VP msg,
+ INT rmsgsz
+)
+{
+ return E_OK;
+}
+
+/*
+ * ref_por - Reference Port Status
+ */
+
+ER ref_por(
+ T_RPOR *pk_rpor,
+ ID porid
+)
+{
+ return E_OK;
+}
diff --git a/cpukit/itron/src/prcv_mbf.c b/cpukit/itron/src/prcv_mbf.c
new file mode 100644
index 0000000000..e095d2ccb4
--- /dev/null
+++ b/cpukit/itron/src/prcv_mbf.c
@@ -0,0 +1,34 @@
+/*
+ * ITRON Message Buffer Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/task.h>
+
+/*
+ * prcv_mbf - Poll and Receive Message from MessageBuffer
+ */
+
+ER prcv_mbf(
+ VP msg,
+ INT *p_msgsz,
+ ID mbfid
+)
+{
+ return trcv_mbf(msg, p_msgsz, mbfid, TMO_POL);
+}
diff --git a/cpukit/itron/src/prcv_mbx.c b/cpukit/itron/src/prcv_mbx.c
new file mode 100644
index 0000000000..4986ae3744
--- /dev/null
+++ b/cpukit/itron/src/prcv_mbx.c
@@ -0,0 +1,33 @@
+/*
+ * ITRON 3.0 Mailbox Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/mbox.h>
+#include <rtems/itron/task.h>
+
+/*
+ * prcv_msg - Poll and Receive Message from Mailbox
+ */
+
+ER prcv_msg(
+ T_MSG **ppk_msg,
+ ID mbxid
+)
+{
+ return trcv_msg( ppk_msg, mbxid, TMO_POL );
+}
diff --git a/cpukit/itron/src/preq_sem.c b/cpukit/itron/src/preq_sem.c
new file mode 100644
index 0000000000..e68f92b5de
--- /dev/null
+++ b/cpukit/itron/src/preq_sem.c
@@ -0,0 +1,33 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/semaphore.h>
+#include <rtems/itron/task.h>
+#include <rtems/score/tod.h>
+
+/*
+ * preq_sem - Poll and Request Semaphore
+ *
+ * This function implements the ITRON 3.0 preq_sem() service.
+ */
+
+ER preq_sem(
+ ID semid
+)
+{
+ return twai_sem( semid, TMO_POL );
+}
diff --git a/cpukit/itron/src/psnd_mbf.c b/cpukit/itron/src/psnd_mbf.c
new file mode 100644
index 0000000000..bac72feb2a
--- /dev/null
+++ b/cpukit/itron/src/psnd_mbf.c
@@ -0,0 +1,34 @@
+/*
+ * ITRON Message Buffer Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/task.h>
+
+/*
+ * psnd_mbf - Poll and Send Message to MessageBuffer
+ */
+
+ER psnd_mbf(
+ ID mbfid,
+ VP msg,
+ INT msgsz
+)
+{
+ return tsnd_mbf( mbfid, msg, msgsz, TMO_POL );
+}
diff --git a/cpukit/itron/src/rcv_mbf.c b/cpukit/itron/src/rcv_mbf.c
new file mode 100644
index 0000000000..6427f36250
--- /dev/null
+++ b/cpukit/itron/src/rcv_mbf.c
@@ -0,0 +1,34 @@
+/*
+ * ITRON Message Buffer Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/task.h>
+
+/*
+ * rcv_mbf - Receive Message from MessageBuffer
+ */
+
+ER rcv_mbf(
+ VP msg,
+ INT *p_msgsz,
+ ID mbfid
+)
+{
+ return trcv_mbf(msg, p_msgsz, mbfid, TMO_FEVR);
+}
diff --git a/cpukit/itron/src/rcv_mbx.c b/cpukit/itron/src/rcv_mbx.c
new file mode 100644
index 0000000000..dde0f2697e
--- /dev/null
+++ b/cpukit/itron/src/rcv_mbx.c
@@ -0,0 +1,33 @@
+/*
+ * ITRON 3.0 Mailbox Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/mbox.h>
+#include <rtems/itron/task.h>
+
+/*
+ * rcv_msg - Receive Message from Mailbox
+ */
+
+ER rcv_msg(
+ T_MSG **ppk_msg,
+ ID mbxid
+)
+{
+ return trcv_msg( ppk_msg, mbxid, TMO_FEVR );
+}
diff --git a/cpukit/itron/src/ref_mbf.c b/cpukit/itron/src/ref_mbf.c
new file mode 100644
index 0000000000..f7f076e65b
--- /dev/null
+++ b/cpukit/itron/src/ref_mbf.c
@@ -0,0 +1,83 @@
+/*
+ * ITRON Message Buffer Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/task.h>
+
+/*
+ * ref_mbf - Reference Message Buffer Status
+ */
+
+ER ref_mbf(
+ T_RMBF *pk_rmbf,
+ ID mbfid
+)
+{
+ ITRON_Message_buffer_Control *the_message_buffer;
+ Objects_Locations location;
+ CORE_message_queue_Control *the_core_msgq;
+
+ if ( !pk_rmbf )
+ return E_PAR; /* XXX check this error code */
+
+ the_message_buffer = _ITRON_Message_buffer_Get( mbfid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* Multiprocessing not supported */
+ case OBJECTS_ERROR:
+ return _ITRON_Message_buffer_Clarify_get_id_error( mbfid );
+
+ case OBJECTS_LOCAL:
+ the_core_msgq = &the_message_buffer->message_queue;
+
+ /*
+ * Fill in the size of message to be sent
+ */
+
+ if (the_core_msgq->number_of_pending_messages == 0) {
+ pk_rmbf->msgsz = 0;
+ } else {
+ pk_rmbf->msgsz = ((CORE_message_queue_Buffer_control *)
+ the_core_msgq->Pending_messages.first)->Contents.size;
+ }
+
+ /*
+ * Fill in the size of free buffer
+ */
+
+ pk_rmbf->frbufsz =
+ (the_core_msgq->maximum_pending_messages -
+ the_core_msgq->number_of_pending_messages) *
+ the_core_msgq->maximum_message_size;
+
+
+ /*
+ * Fill in whether or not there is a waiting task
+ */
+
+ if ( !_Thread_queue_First(&the_core_msgq->Wait_queue ) )
+ pk_rmbf->wtsk = FALSE;
+ else
+ pk_rmbf->wtsk = TRUE;
+
+ pk_rmbf->stsk = FALSE;
+ _Thread_Enable_dispatch();
+ return E_OK;
+ }
+ return E_OK;
+}
diff --git a/cpukit/itron/src/ref_mbx.c b/cpukit/itron/src/ref_mbx.c
new file mode 100644
index 0000000000..6e100e011e
--- /dev/null
+++ b/cpukit/itron/src/ref_mbx.c
@@ -0,0 +1,65 @@
+/*
+ * ITRON 3.0 Mailbox Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/mbox.h>
+#include <rtems/itron/task.h>
+
+/*
+ * ref_mbx - Reference Mailbox Status
+ */
+
+ER ref_mbx(
+ T_RMBX *pk_rmbx,
+ ID mbxid
+)
+{
+ register ITRON_Mailbox_Control *the_mailbox;
+ Objects_Locations location;
+ Chain_Control *pending;
+
+ if ( !pk_rmbx )
+ return E_PAR;
+
+ the_mailbox = _ITRON_Mailbox_Get( mbxid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Mailbox_Clarify_get_id_error( mbxid );
+
+ case OBJECTS_LOCAL:
+
+ pending = &the_mailbox->message_queue.Pending_messages;
+ if ( _Chain_Is_empty( pending ) )
+ pk_rmbx->pk_msg = NULL;
+ else
+ pk_rmbx->pk_msg = (T_MSG *) pending->first;
+
+ /*
+ * Fill in whether or not there is a waiting task
+ */
+
+ if ( !_Thread_queue_First( &the_mailbox->message_queue.Wait_queue ) )
+ pk_rmbx->wtsk = FALSE;
+ else
+ pk_rmbx->wtsk = TRUE;
+
+ break;
+ }
+ _ITRON_return_errorno( E_OK );
+}
diff --git a/cpukit/itron/src/ref_sem.c b/cpukit/itron/src/ref_sem.c
new file mode 100644
index 0000000000..9a46cca38d
--- /dev/null
+++ b/cpukit/itron/src/ref_sem.c
@@ -0,0 +1,65 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/semaphore.h>
+#include <rtems/itron/task.h>
+#include <rtems/score/tod.h>
+
+/*
+ * ref_sem - Reference Semaphore Status
+ *
+ * This function implements the ITRON 3.0 ref_sem() service.
+ */
+
+ER ref_sem(
+ ID semid,
+ T_RSEM *pk_rsem
+)
+{
+ ITRON_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ if ( !pk_rsem )
+ return E_PAR; /* XXX check this error code */
+
+ the_semaphore = _ITRON_Semaphore_Get( semid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* Multiprocessing not supported */
+ case OBJECTS_ERROR:
+ return _ITRON_Semaphore_Clarify_get_id_error( semid );
+
+ case OBJECTS_LOCAL:
+ /*
+ * Fill in the current semaphore count
+ */
+
+ pk_rsem->semcnt = _CORE_semaphore_Get_count( &the_semaphore->semaphore );
+
+ /*
+ * Fill in whether or not there is a waiting task
+ */
+
+ if ( !_Thread_queue_First( &the_semaphore->semaphore.Wait_queue ) )
+ pk_rsem->wtsk = FALSE;
+ else
+ pk_rsem->wtsk = TRUE;
+
+ _Thread_Enable_dispatch();
+ return E_OK;
+ }
+ return E_OK;
+}
diff --git a/cpukit/itron/src/ref_tsk.c b/cpukit/itron/src/ref_tsk.c
new file mode 100644
index 0000000000..6b951a5c8a
--- /dev/null
+++ b/cpukit/itron/src/ref_tsk.c
@@ -0,0 +1,99 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * ref_tsk - Reference Task Status
+ */
+
+ER ref_tsk(
+ T_RTSK *pk_rtsk,
+ ID tskid
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+ Priority_Control core_priority;
+
+ if (!pk_rtsk)
+ return E_PAR;
+
+ the_thread = _ITRON_Task_Get( tskid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Task_Clarify_get_id_error( tskid );
+
+ case OBJECTS_LOCAL:
+
+ if ( location != OBJECTS_LOCAL )
+ return _ITRON_Task_Clarify_get_id_error( tskid );
+
+ /*
+ * The following are extended functions [level X ].
+ * XXX - tskwait, wid, wupcnt, and tskatr are presently not implemented.
+ */
+
+ pk_rtsk->tskwait = 0;
+ pk_rtsk->wid = 0;
+ pk_rtsk->wupcnt = 0;
+ pk_rtsk->suscnt = the_thread->suspend_count;
+ pk_rtsk->tskatr = 0; /* XXX - Not correctly implemented */
+ pk_rtsk->task = (FP) the_thread->Start.entry_point;
+ core_priority = the_thread->Start.initial_priority;
+ pk_rtsk->itskpri = _ITRON_Task_Core_to_Priority( core_priority );
+ pk_rtsk->stksz = the_thread->Start.Initial_stack.size;
+
+ /*
+ * The following are required.
+ */
+
+ pk_rtsk->exinf = NULL; /* extended information */
+ pk_rtsk->tskpri =
+ _ITRON_Task_Core_to_Priority(the_thread->current_priority);
+
+ /*
+ * Mask in the tskstat information
+ * Convert the task state XXX double check this
+ */
+
+ pk_rtsk->tskstat = 0;
+ if ( the_thread == _Thread_Executing )
+ pk_rtsk->tskstat |= TTS_RUN;
+ if ( _States_Is_ready(the_thread->current_state) )
+ pk_rtsk->tskstat |= TTS_RDY;
+ if ( _States_Is_dormant( the_thread->current_state) )
+ pk_rtsk->tskstat |= TTS_DMT;
+ if ( _States_Is_suspended(the_thread->current_state) )
+ pk_rtsk->tskstat |= TTS_SUS;
+ if ( _States_Is_blocked(the_thread->current_state) )
+ pk_rtsk->tskstat |= TTS_WAI;
+
+ break;
+ }
+
+ _ITRON_return_errorno( E_OK );
+
+}
diff --git a/cpukit/itron/src/rel_wai.c b/cpukit/itron/src/rel_wai.c
new file mode 100644
index 0000000000..49b247d660
--- /dev/null
+++ b/cpukit/itron/src/rel_wai.c
@@ -0,0 +1,52 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+/*
+ * rel_wai - Release Wait of Other Task
+ */
+
+ER rel_wai(
+ ID tskid
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _ITRON_Task_Get( tskid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Task_Clarify_get_id_error( tskid );
+
+ case OBJECTS_LOCAL:
+ /*
+ * XXX - FILL ME IN.
+ */
+
+ break;
+ }
+
+ _ITRON_return_errorno( E_OK );
+}
diff --git a/cpukit/itron/src/rot_rdq.c b/cpukit/itron/src/rot_rdq.c
new file mode 100644
index 0000000000..80e9e5c95e
--- /dev/null
+++ b/cpukit/itron/src/rot_rdq.c
@@ -0,0 +1,55 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+/*
+ * rot_rdq - Rotate Tasks on the Ready Queue
+ */
+
+ER rot_rdq(
+ PRI tskpri
+)
+{
+ PRI priority;
+
+
+ if (( tskpri <= 0 ) || ( tskpri >= 256 ))
+ return E_PAR;
+
+ _Thread_Disable_dispatch();
+
+ /*
+ * Yield of processor will rotate the queue for this processor.
+ */
+
+ priority = _ITRON_Task_Core_to_Priority(_Thread_Executing->current_priority);
+ if ( priority == tskpri )
+ _Thread_Yield_processor();
+ else {
+ _Thread_Rotate_Ready_Queue( _ITRON_Task_Core_to_Priority( tskpri ) );
+ }
+ _Thread_Enable_dispatch();
+
+ return E_OK;
+}
diff --git a/cpukit/itron/src/rsm_tsk.c b/cpukit/itron/src/rsm_tsk.c
new file mode 100644
index 0000000000..a41fbfe5e6
--- /dev/null
+++ b/cpukit/itron/src/rsm_tsk.c
@@ -0,0 +1,60 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * rsm_tsk - Resume Suspended Task
+ */
+
+ER rsm_tsk(
+ ID tskid
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _ITRON_Task_Get( tskid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Task_Clarify_get_id_error( tskid );
+
+ case OBJECTS_LOCAL:
+
+ if ( _Thread_Is_executing( the_thread ) )
+ _ITRON_return_errorno( E_OBJ );
+
+ if ( _States_Is_dormant( the_thread->current_state ))
+ _ITRON_return_errorno( E_OBJ );
+
+ if ( ! _States_Is_suspended(the_thread->current_state) )
+ _ITRON_return_errorno( E_OK );
+
+ _Thread_Resume( the_thread, FALSE );
+ break;
+ }
+
+ _ITRON_return_errorno( E_OK );
+}
diff --git a/cpukit/itron/src/sig_sem.c b/cpukit/itron/src/sig_sem.c
new file mode 100644
index 0000000000..cde504891c
--- /dev/null
+++ b/cpukit/itron/src/sig_sem.c
@@ -0,0 +1,56 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/semaphore.h>
+#include <rtems/itron/task.h>
+#include <rtems/score/tod.h>
+
+/*
+ * sig_sem - Signal Semaphore
+ *
+ * This function implements the ITRON 3.0 sig_sem() service.
+ */
+
+ER sig_sem(
+ ID semid
+)
+{
+ ITRON_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+ CORE_semaphore_Status status;
+
+ the_semaphore = _ITRON_Semaphore_Get( semid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* Multiprocessing not supported */
+ case OBJECTS_ERROR:
+ return _ITRON_Semaphore_Clarify_get_id_error( semid );
+
+ case OBJECTS_LOCAL:
+ /*
+ * XXX maxsemcnt
+ */
+
+ status = _CORE_semaphore_Surrender(
+ &the_semaphore->semaphore,
+ the_semaphore->Object.id,
+ NULL /* Multiprocessing not supported */
+ );
+ _Thread_Enable_dispatch();
+ return _ITRON_Semaphore_Translate_core_semaphore_return_code( status );
+ }
+ return E_OK;
+}
diff --git a/cpukit/itron/src/slp_tsk.c b/cpukit/itron/src/slp_tsk.c
new file mode 100644
index 0000000000..917ef11157
--- /dev/null
+++ b/cpukit/itron/src/slp_tsk.c
@@ -0,0 +1,35 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+
+/*
+ * slp_tsk - Sleep Task
+ */
+
+ER slp_tsk( void )
+{
+ return E_OK;
+}
diff --git a/cpukit/itron/src/snd_mbf.c b/cpukit/itron/src/snd_mbf.c
new file mode 100644
index 0000000000..3c46aad75e
--- /dev/null
+++ b/cpukit/itron/src/snd_mbf.c
@@ -0,0 +1,34 @@
+/*
+ * ITRON Message Buffer Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/task.h>
+
+/*
+ * snd_mbf - Send Message to MessageBuffer
+ */
+
+ER snd_mbf(
+ ID mbfid,
+ VP msg,
+ INT msgsz
+)
+{
+ return tsnd_mbf( mbfid, msg, msgsz, TMO_FEVR );
+}
diff --git a/cpukit/itron/src/snd_mbx.c b/cpukit/itron/src/snd_mbx.c
new file mode 100644
index 0000000000..f257ab3b41
--- /dev/null
+++ b/cpukit/itron/src/snd_mbx.c
@@ -0,0 +1,70 @@
+/*
+ * ITRON 3.0 Mailbox Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/mbox.h>
+#include <rtems/itron/task.h>
+
+/*
+ * snd_msg - Send Message to Mailbox
+ */
+
+ER snd_msg(
+ ID mbxid,
+ T_MSG *pk_msg
+)
+{
+ register ITRON_Mailbox_Control *the_mailbox;
+ Objects_Locations location;
+ uint32_t message_priority;
+ void *message_contents;
+ CORE_message_queue_Status msg_status;
+
+ if ( !pk_msg )
+ return E_PAR;
+
+ the_mailbox = _ITRON_Mailbox_Get( mbxid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Mailbox_Clarify_get_id_error( mbxid );
+
+ case OBJECTS_LOCAL:
+ if ( the_mailbox->do_message_priority )
+ message_priority = pk_msg->msgpri;
+ else
+ message_priority = CORE_MESSAGE_QUEUE_SEND_REQUEST;
+
+ message_contents = pk_msg;
+ msg_status = _CORE_message_queue_Submit(
+ &the_mailbox->message_queue,
+ &message_contents,
+ sizeof(T_MSG *),
+ the_mailbox->Object.id,
+ NULL, /* multiprocessing not supported */
+ message_priority,
+ FALSE, /* do not allow sender to block */
+ 0 /* no timeout */
+ );
+ break;
+ }
+
+ _ITRON_return_errorno(
+ _ITRON_Mailbox_Translate_core_message_queue_return_code( msg_status )
+ );
+}
diff --git a/cpukit/itron/src/sta_tsk.c b/cpukit/itron/src/sta_tsk.c
new file mode 100644
index 0000000000..a1beeade23
--- /dev/null
+++ b/cpukit/itron/src/sta_tsk.c
@@ -0,0 +1,69 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * sta_tsk - Start Task
+ */
+
+ER sta_tsk(
+ ID tskid,
+ INT stacd
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+ boolean status;
+
+ the_thread = _ITRON_Task_Get( tskid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Task_Clarify_get_id_error( tskid );
+
+ case OBJECTS_LOCAL:
+
+ if ( !_States_Is_dormant( the_thread->current_state ) )
+ _ITRON_return_errorno( E_OBJ );
+
+ status = _Thread_Start(
+ the_thread,
+ THREAD_START_NUMERIC, /* XXX should be able to say we have no arg */
+ the_thread->Start.entry_point,
+ 0, /* XXX supercore forces us to have an arg */
+ 0 /* unused */
+ );
+
+ /*
+ * This error can not happen entry_point is checked in create.
+ if ( !status )
+ _ITRON_return_errorno( E_OBJ );
+ */
+
+ break;
+ }
+
+ _ITRON_return_errorno( E_OK );
+}
diff --git a/cpukit/itron/src/sus_tsk.c b/cpukit/itron/src/sus_tsk.c
new file mode 100644
index 0000000000..7261a171df
--- /dev/null
+++ b/cpukit/itron/src/sus_tsk.c
@@ -0,0 +1,62 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * Task-Dependent Synchronization Functions
+ */
+
+/*
+ * sus_tsk - Suspend Other Task
+ */
+
+ER sus_tsk(
+ ID tskid
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _ITRON_Task_Get( tskid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Task_Clarify_get_id_error( tskid );
+
+ case OBJECTS_LOCAL:
+
+ if ( _Thread_Is_executing( the_thread ) )
+ _ITRON_return_errorno( E_OBJ );
+
+ if (the_thread->suspend_count == INT_MAX )
+ _ITRON_return_errorno( E_QOVR );
+
+ _Thread_Suspend( the_thread );
+ break;
+ }
+
+ _ITRON_return_errorno( E_OK );
+}
diff --git a/cpukit/itron/src/sysmgmt.c b/cpukit/itron/src/sysmgmt.c
new file mode 100644
index 0000000000..b997c3fd74
--- /dev/null
+++ b/cpukit/itron/src/sysmgmt.c
@@ -0,0 +1,75 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/sysmgmt.h>
+
+/*
+ * get_ver - Get Version Information
+ */
+
+ER get_ver(
+ T_VER *pk_ver
+)
+{
+ return E_OK;
+}
+
+/*
+ * ref_sys - Reference System Status
+ */
+
+ER ref_sys(
+ T_RSYS *pk_rsys
+)
+{
+ return E_OK;
+}
+
+/*
+ * ref_cfg - Reference Configuration Information
+ */
+
+ER ref_cfg(
+ T_RCFG *pk_rcfg
+)
+{
+ return E_OK;
+}
+
+/*
+ * def_svc - Define Extended SVC Handler
+ */
+
+ER def_svc(
+ FN s_fncd,
+ T_DSVC *pk_dsvc
+)
+{
+ return E_OK;
+}
+
+/*
+ * def_exc - Define Exception Handler
+ */
+
+ER def_exc(
+ UINT exckind,
+ T_DEXC *pk_dexc
+)
+{
+ return E_OK;
+}
diff --git a/cpukit/itron/src/task.c b/cpukit/itron/src/task.c
new file mode 100644
index 0000000000..2fcb3a3a0a
--- /dev/null
+++ b/cpukit/itron/src/task.c
@@ -0,0 +1,227 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+/*
+ * _ITRON_Task_Create_extension
+ *
+ * This routine is an extension routine that is invoked as part
+ * of creating any type of task or thread in the system. If the
+ * task is created via another API, then this routine is invoked
+ * and this API given the opportunity to initialize its extension
+ * area.
+ */
+
+boolean _ITRON_Task_Create_extension(
+ Thread_Control *executing,
+ Thread_Control *created
+)
+{
+ ITRON_API_Control *api;
+
+ api = _Workspace_Allocate( sizeof( ITRON_API_Control ) );
+
+ if ( !api )
+ return FALSE;
+
+ created->API_Extensions[ THREAD_API_ITRON ] = api;
+
+ /*
+ * Initialize the ITRON API extension
+ */
+
+ return TRUE;
+}
+
+/*
+ * _ITRON_Task_Delete_extension
+ *
+ * This extension routine is invoked when a task is deleted.
+ */
+
+User_extensions_routine _ITRON_Task_Delete_extension(
+ Thread_Control *executing,
+ Thread_Control *deleted
+)
+{
+ (void) _Workspace_Free( deleted->API_Extensions[ THREAD_API_ITRON ] );
+
+ deleted->API_Extensions[ THREAD_API_ITRON ] = NULL;
+}
+
+/*
+ * _ITRON_Task_Initialize_user_tasks
+ *
+ * This routine creates and starts all configured user
+ * initialzation threads.
+ */
+
+void _ITRON_Task_Initialize_user_tasks( void )
+{
+ uint32_t index;
+ uint32_t maximum;
+ ER return_value;
+ itron_initialization_tasks_table *user_tasks;
+
+ /*
+ * NOTE: This is slightly different from the Ada implementation.
+ */
+
+ user_tasks = _ITRON_Task_User_initialization_tasks;
+ maximum = _ITRON_Task_Number_of_initialization_tasks;
+
+ if ( !user_tasks || maximum == 0 )
+ return;
+
+ for ( index=0 ; index < maximum ; index++ ) {
+
+ return_value = cre_tsk(
+ user_tasks[ index ].id,
+ &user_tasks[ index ].attributes
+ );
+
+ if ( return_value != E_OK )
+ _Internal_error_Occurred( INTERNAL_ERROR_ITRON_API, TRUE, return_value );
+
+ return_value = sta_tsk( user_tasks[ index ].id, 0 );
+
+ if ( return_value != E_OK )
+ _Internal_error_Occurred( INTERNAL_ERROR_ITRON_API, TRUE, return_value );
+
+ }
+}
+
+/*PAGE
+ *
+ * _ITRON_Delete_task
+ */
+
+ER _ITRON_Delete_task(
+ Thread_Control *the_thread
+)
+{
+ Objects_Information *the_information;
+
+ the_information = _Objects_Get_information( the_thread->Object.id );
+ if ( !the_information ) {
+ return E_OBJ; /* XXX - should never happen */
+ }
+
+ _Thread_Close( the_information, the_thread );
+
+ _ITRON_Task_Free( the_thread );
+
+ return E_OK;
+}
+
+/*
+ * At this point in time, the ITRON API does not need any other
+ * extensions. See the POSIX and RTEMS API extensions for
+ * examples of how they can be used.
+ */
+
+/*
+ * Extension Tables
+ */
+
+API_extensions_Control _ITRON_Task_API_extensions = {
+ { NULL, NULL },
+ NULL, /* predriver */
+ _ITRON_Task_Initialize_user_tasks, /* postdriver */
+ NULL /* post switch */
+};
+
+User_extensions_Control _ITRON_Task_User_extensions = {
+ { NULL, NULL },
+ { { NULL, NULL }, NULL },
+ { _ITRON_Task_Create_extension, /* create */
+ NULL, /* start */
+ NULL, /* restart */
+ _ITRON_Task_Delete_extension, /* delete */
+ NULL, /* switch */
+ NULL, /* begin */
+ NULL, /* exitted */
+ NULL /* fatal */
+ }
+};
+
+/*
+ * _ITRON_Task_Manager_initialization
+ *
+ * This routine initializes all Task Manager related data structures.
+ *
+ * Input parameters:
+ * maximum_tasks - number of tasks to initialize
+ *
+ * Output parameters: NONE
+ */
+
+void _ITRON_Task_Manager_initialization(
+ uint32_t maximum_tasks,
+ uint32_t number_of_initialization_tasks,
+ itron_initialization_tasks_table *user_tasks
+)
+{
+
+ _ITRON_Task_Number_of_initialization_tasks = number_of_initialization_tasks;
+ _ITRON_Task_User_initialization_tasks = user_tasks;
+
+ /*
+ * There may not be any ITRON_initialization tasks configured.
+ */
+
+#if 0
+ if ( user_tasks == NULL || number_of_initialization_tasks == 0 )
+ _Internal_error_Occurred( INTERNAL_ERROR_ITRON_API, TRUE, -1 );
+#endif
+
+ _Objects_Initialize_information(
+ &_ITRON_Task_Information, /* object information table */
+ OBJECTS_ITRON_API, /* object API */
+ OBJECTS_ITRON_TASKS, /* object class */
+ maximum_tasks, /* maximum objects of this class */
+ sizeof( Thread_Control ), /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ ITRON_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Add all the extensions for this API
+ */
+
+ _User_extensions_Add_API_set( &_ITRON_Task_User_extensions );
+
+ _API_extensions_Add( &_ITRON_Task_API_extensions );
+
+ /*
+ * XXX MP not supported
+ * Register the MP Process Packet routine.
+ */
+
+}
diff --git a/cpukit/itron/src/ter_tsk.c b/cpukit/itron/src/ter_tsk.c
new file mode 100644
index 0000000000..f3111f5d46
--- /dev/null
+++ b/cpukit/itron/src/ter_tsk.c
@@ -0,0 +1,58 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * ter_tsk - Terminate Other Task - Set State to DORMANT
+ */
+
+ER ter_tsk(
+ ID tskid
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _ITRON_Task_Get( tskid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Task_Clarify_get_id_error( tskid );
+
+ case OBJECTS_LOCAL:
+
+ if ( _Thread_Is_executing( the_thread ) )
+ _ITRON_return_errorno( E_OBJ );
+
+ if ( _States_Is_dormant( the_thread->current_state ) )
+ _ITRON_return_errorno( E_OBJ );
+
+ _Thread_Restart( the_thread, NULL, 0 );
+ _Thread_Set_state( the_thread, STATES_DORMANT );
+ break;
+ }
+
+ _ITRON_return_errorno( E_OK );
+}
diff --git a/cpukit/itron/src/trcv_mbf.c b/cpukit/itron/src/trcv_mbf.c
new file mode 100644
index 0000000000..aee0a8661b
--- /dev/null
+++ b/cpukit/itron/src/trcv_mbf.c
@@ -0,0 +1,86 @@
+/*
+ * ITRON Message Buffer Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/task.h>
+
+/*
+ * trcv_mbf - Receive Message from MessageBuffer with Timeout
+ */
+
+ER trcv_mbf(
+ VP msg,
+ INT *p_msgsz,
+ ID mbfid,
+ TMO tmout
+)
+{
+ ITRON_Message_buffer_Control *the_message_buffer;
+ Objects_Locations location;
+ CORE_message_queue_Status status;
+ boolean wait;
+ Watchdog_Interval interval;
+ uint32_t msgsz;
+
+ interval = 0;
+ if (tmout == TMO_POL) {
+ wait = FALSE;
+ } else {
+ wait = TRUE;
+ if (tmout != TMO_FEVR)
+ interval = TOD_MILLISECONDS_TO_TICKS(tmout);
+ }
+
+ if (wait && _ITRON_Is_in_non_task_state() )
+ return E_CTX;
+
+ if (!p_msgsz || !msg || tmout <= -2)
+ return E_PAR;
+
+ the_message_buffer = _ITRON_Message_buffer_Get(mbfid, &location);
+ switch (location) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR: /* Multiprocessing not supported */
+ return _ITRON_Message_buffer_Clarify_get_id_error(mbfid);
+
+ case OBJECTS_LOCAL:
+ _CORE_message_queue_Seize(
+ &the_message_buffer->message_queue,
+ the_message_buffer->Object.id,
+ msg,
+ &msgsz,
+ wait,
+ interval
+ );
+ _Thread_Enable_dispatch();
+ *p_msgsz = msgsz;
+ status = (CORE_message_queue_Status)_Thread_Executing->Wait.return_code;
+ return
+ _ITRON_Message_buffer_Translate_core_message_buffer_return_code(status);
+ }
+
+ /*
+ * If multiprocessing were supported, this is where we would announce
+ * the existence of the semaphore to the rest of the system.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#endif
+ return E_OK;
+}
diff --git a/cpukit/itron/src/trcv_mbx.c b/cpukit/itron/src/trcv_mbx.c
new file mode 100644
index 0000000000..62a3098140
--- /dev/null
+++ b/cpukit/itron/src/trcv_mbx.c
@@ -0,0 +1,76 @@
+/*
+ * ITRON 3.0 Mailbox Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/mbox.h>
+#include <rtems/itron/task.h>
+
+/*
+ * trcv_msg - Receive Message from Mailbox with Timeout
+ */
+
+ER trcv_msg(
+ T_MSG **ppk_msg,
+ ID mbxid,
+ TMO tmout
+)
+{
+ register ITRON_Mailbox_Control *the_mailbox;
+ Watchdog_Interval interval;
+ boolean wait;
+ Objects_Locations location;
+ uint32_t size;
+
+ if (!ppk_msg)
+ return E_PAR;
+
+ interval = 0;
+ if ( tmout == TMO_POL ) {
+ wait = FALSE;
+ } else {
+ wait = TRUE;
+ if ( tmout != TMO_FEVR )
+ interval = TOD_MILLISECONDS_TO_TICKS(tmout);
+ }
+
+ if ( wait && _ITRON_Is_in_non_task_state() )
+ return E_CTX;
+
+ the_mailbox = _ITRON_Mailbox_Get( mbxid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ return _ITRON_Mailbox_Clarify_get_id_error( mbxid );
+
+ case OBJECTS_LOCAL:
+
+ _CORE_message_queue_Seize(
+ &the_mailbox->message_queue,
+ the_mailbox->Object.id,
+ ppk_msg,
+ &size,
+ wait,
+ interval
+ );
+ break;
+ }
+
+ _ITRON_return_errorno(
+ _ITRON_Mailbox_Translate_core_message_queue_return_code(
+ _Thread_Executing->Wait.return_code ) );
+}
diff --git a/cpukit/itron/src/tslp_tsk.c b/cpukit/itron/src/tslp_tsk.c
new file mode 100644
index 0000000000..54fe83cf45
--- /dev/null
+++ b/cpukit/itron/src/tslp_tsk.c
@@ -0,0 +1,36 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * tslp_tsk - Sleep Task with Timeout
+ */
+
+ER tslp_tsk(
+ TMO tmout
+)
+{
+ return E_OK;
+}
diff --git a/cpukit/itron/src/tsnd_mbf.c b/cpukit/itron/src/tsnd_mbf.c
new file mode 100644
index 0000000000..841d0b8756
--- /dev/null
+++ b/cpukit/itron/src/tsnd_mbf.c
@@ -0,0 +1,90 @@
+/*
+ * ITRON Message Buffer Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/task.h>
+
+#include <assert.h> /* only for blocking */
+
+/*
+ * tsnd_mbf - Send Message to MessageBuffer with Timeout
+ */
+
+ER tsnd_mbf(
+ ID mbfid,
+ VP msg,
+ INT msgsz,
+ TMO tmout
+)
+{
+ ITRON_Message_buffer_Control *the_message_buffer;
+ Objects_Locations location;
+ Watchdog_Interval interval;
+ boolean wait;
+ CORE_message_queue_Status msg_status;
+
+ if (msgsz <= 0 || !msg)
+ return E_PAR;
+
+ interval = 0;
+ if ( tmout == TMO_POL ) {
+ wait = FALSE;
+ } else {
+ wait = TRUE;
+ if ( tmout != TMO_FEVR )
+ interval = TOD_MILLISECONDS_TO_TICKS(tmout);
+ }
+
+ if ( wait && _ITRON_Is_in_non_task_state() )
+ return E_CTX;
+
+ the_message_buffer = _ITRON_Message_buffer_Get(mbfid, &location);
+ switch (location) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR: /* Multiprocessing not supported */
+ return _ITRON_Message_buffer_Clarify_get_id_error(mbfid);
+
+ case OBJECTS_LOCAL:
+ /* XXX Submit needs to take into account blocking */
+ msg_status = _CORE_message_queue_Submit(
+ &the_message_buffer->message_queue,
+ msg,
+ msgsz,
+ the_message_buffer->Object.id,
+ NULL,
+ CORE_MESSAGE_QUEUE_SEND_REQUEST,
+ wait, /* sender may block */
+ interval /* timeout interval */
+ );
+ _Thread_Enable_dispatch();
+ return _ITRON_Message_buffer_Translate_core_message_buffer_return_code(
+ msg_status
+ );
+ }
+
+ /*
+ * If multiprocessing were supported, this is where we would announce
+ * the existence of the semaphore to the rest of the system.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#endif
+
+ return E_OK;
+}
diff --git a/cpukit/itron/src/twai_sem.c b/cpukit/itron/src/twai_sem.c
new file mode 100644
index 0000000000..133d0647be
--- /dev/null
+++ b/cpukit/itron/src/twai_sem.c
@@ -0,0 +1,69 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/semaphore.h>
+#include <rtems/itron/task.h>
+#include <rtems/score/tod.h>
+
+/*
+ * twai_sem - Wait on Semaphore with Timeout
+ *
+ * This function implements the ITRON 3.0 twai_sem() service.
+ */
+
+ER twai_sem(
+ ID semid,
+ TMO tmout
+)
+{
+ ITRON_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+ Watchdog_Interval interval;
+ boolean wait;
+ CORE_semaphore_Status status;
+
+ interval = 0;
+ if ( tmout == TMO_POL ) {
+ wait = FALSE;
+ } else {
+ wait = TRUE;
+ if ( tmout != TMO_FEVR )
+ interval = TOD_MILLISECONDS_TO_TICKS(tmout);
+ }
+
+ if ( wait && _ITRON_Is_in_non_task_state() )
+ return E_CTX;
+
+ the_semaphore = _ITRON_Semaphore_Get( semid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* Multiprocessing not supported */
+ case OBJECTS_ERROR:
+ return _ITRON_Semaphore_Clarify_get_id_error( semid );
+
+ case OBJECTS_LOCAL:
+ _CORE_semaphore_Seize(
+ &the_semaphore->semaphore,
+ the_semaphore->Object.id,
+ wait, /* wait for a timeout */
+ interval /* timeout value */
+ );
+ _Thread_Enable_dispatch();
+ status = (CORE_semaphore_Status) _Thread_Executing->Wait.return_code;
+ return _ITRON_Semaphore_Translate_core_semaphore_return_code( status );
+ }
+ return E_OK;
+}
diff --git a/cpukit/itron/src/vmempool.c b/cpukit/itron/src/vmempool.c
new file mode 100644
index 0000000000..916c9d5e61
--- /dev/null
+++ b/cpukit/itron/src/vmempool.c
@@ -0,0 +1,145 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/vmempool.h>
+
+/*
+ * _ITRON_Variable_memory_pool_Manager_initialization
+ *
+ * This routine initializes all variable memory pool manager related
+ * data structures.
+ *
+ * Input parameters:
+ * maximum_variable_memory_pools - maximum configured variable memory pools
+ *
+ * Output parameters: NONE
+ */
+
+void _ITRON_Variable_memory_pool_Manager_initialization(
+ uint32_t maximum_variable_memory_pools
+)
+{
+ _Objects_Initialize_information(
+ &_ITRON_Variable_memory_pool_Information, /* object information table */
+ OBJECTS_ITRON_API, /* object API */
+ OBJECTS_ITRON_VARIABLE_MEMORY_POOLS, /* object class */
+ maximum_variable_memory_pools, /* maximum objects of this class */
+ sizeof( ITRON_Variable_memory_pool_Control ),
+ /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ ITRON_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Register the MP Process Packet routine.
+ *
+ * NOTE: No MP Support YET in RTEMS ITRON implementation.
+ */
+
+}
+
+/*
+ * cre_mpl - Create Variable-Size Memorypool
+ */
+
+ER cre_mpl(
+ ID mplid,
+ T_CMPL *pk_cmpl
+)
+{
+ return E_OK;
+}
+
+/*
+ * del_mpl - Delete Variable-Size Memorypool
+ */
+
+ER del_mpl(
+ ID mplid
+)
+{
+ return E_OK;
+}
+
+/*
+ * get_blk - Get Variable-Size Memory Block
+ */
+
+ER get_blk(
+ VP *p_blk,
+ ID mplid,
+ INT blksz
+)
+{
+ return E_OK;
+}
+
+/*
+ * pget_blk - Poll and Get Variable-Size Memory Block
+ */
+
+ER pget_blk(
+ VP *p_blk,
+ ID mplid,
+ INT blksz
+)
+{
+ return E_OK;
+}
+
+/*
+ * tget_blk - Get Variable-Size Memory Block with Timeout
+ */
+
+ER tget_blk(
+ VP *p_blk,
+ ID mplid,
+ INT blksz,
+ TMO tmout
+)
+{
+ return E_OK;
+}
+
+/*
+ * rel_blk - Release Variable-Size Memory Block
+ */
+
+ER rel_blk(
+ ID mplid,
+ VP blk
+)
+{
+ return E_OK;
+}
+
+/*
+ * ref_mpl - Reference Variable-Size Memorypool Status
+ */
+
+ER ref_mpl(
+ T_RMPL *pk_rmpl,
+ ID mplid
+)
+{
+ return E_OK;
+}
diff --git a/cpukit/itron/src/wai_sem.c b/cpukit/itron/src/wai_sem.c
new file mode 100644
index 0000000000..7c4364b594
--- /dev/null
+++ b/cpukit/itron/src/wai_sem.c
@@ -0,0 +1,33 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/itron/semaphore.h>
+#include <rtems/itron/task.h>
+#include <rtems/score/tod.h>
+
+/*
+ * wai_sem - Wait on Semaphore
+ *
+ * This function implements the ITRON 3.0 wai_sem() service.
+ */
+
+ER wai_sem(
+ ID semid
+)
+{
+ return twai_sem( semid, TMO_FEVR );
+}
diff --git a/cpukit/itron/src/wup_tsk.c b/cpukit/itron/src/wup_tsk.c
new file mode 100644
index 0000000000..bec817c0ba
--- /dev/null
+++ b/cpukit/itron/src/wup_tsk.c
@@ -0,0 +1,36 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/itron.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/itron/task.h>
+
+
+/*
+ * wup_tsk - Wakeup Other Task
+ */
+
+ER wup_tsk(
+ ID tskid
+)
+{
+ return E_OK;
+}
diff --git a/cpukit/libblock/.cvsignore b/cpukit/libblock/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/libblock/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/libblock/Makefile.am b/cpukit/libblock/Makefile.am
new file mode 100644
index 0000000000..6a047b5059
--- /dev/null
+++ b/cpukit/libblock/Makefile.am
@@ -0,0 +1,17 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+if !UNIX
+noinst_LIBRARIES = libblock.a
+libblock_a_SOURCES = src/bdbuf.c src/blkdev.c src/diskdevs.c src/ramdisk.c \
+ src/ide_part_table.c include/rtems/bdbuf.h include/rtems/blkdev.h \
+ include/rtems/diskdevs.h include/rtems/ramdisk.h \
+ include/rtems/ide_part_table.h
+endif
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/libblock/README b/cpukit/libblock/README
new file mode 100644
index 0000000000..671cc7f645
--- /dev/null
+++ b/cpukit/libblock/README
@@ -0,0 +1,14 @@
+#
+# $Id$
+#
+
+This directory contains the block device (HDD, CDROMs, etc) support code.
+It includes:
+ - block device driver interface
+ - generic open/close/read/write/ioctl primitives for block device drivers
+ - disk I/O buffering
+ - logical disk support
+ - RAM disk block device driver
+
+Victor V. Vengerov, <vvv@oktet.ru>
+November, 7 2001
diff --git a/cpukit/libblock/include/rtems/bdbuf.h b/cpukit/libblock/include/rtems/bdbuf.h
new file mode 100644
index 0000000000..c966b2836e
--- /dev/null
+++ b/cpukit/libblock/include/rtems/bdbuf.h
@@ -0,0 +1,284 @@
+/**
+ * @file rtems/bdbuf.h
+ *
+ * block device buffer management
+ */
+
+/*
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * @(#) $Id$
+ */
+
+#ifndef _RTEMS_BDBUF_H
+#define _RTEMS_BDBUF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/chain.h>
+
+#include "rtems/blkdev.h"
+#include "rtems/diskdevs.h"
+
+
+/*
+ * To manage buffers we using Buffer Descriptors.
+ * To speed-up buffer lookup descriptors are organized in AVL-Tree.
+ * The fields 'dev' and 'block' are search key.
+ */
+
+/* Buffer descriptors
+ * Descriptors organized in AVL-tree to speedup buffer lookup.
+ * dev and block fields are search key in AVL-tree.
+ * Modified buffers, free buffers and used buffers linked in 'mod', 'free' and
+ * 'lru' chains appropriately.
+ */
+
+typedef struct bdbuf_buffer {
+ Chain_Node link; /* Link in the lru, mod or free chains */
+
+ struct bdbuf_avl_node {
+ signed char cache; /* Cache */
+
+ struct bdbuf_buffer* left; /* Left Child */
+ struct bdbuf_buffer* right; /* Right Child */
+
+ signed char bal; /* The balance of the sub-tree */
+ } avl;
+
+ dev_t dev; /* device number */
+ blkdev_bnum block; /* block number on the device */
+
+ unsigned char *buffer; /* Pointer to the buffer memory area */
+ rtems_status_code status; /* Last I/O operation completion status */
+ int error; /* If status != RTEMS_SUCCESSFUL, this field contains
+ errno value which can be used by user later */
+ boolean modified:1; /* =1 if buffer was modified */
+ boolean in_progress:1; /* =1 if exchange with disk is in progress;
+ need to wait on semaphore */
+ boolean actual:1; /* Buffer contains actual data */
+ int use_count; /* Usage counter; incremented when somebody use
+ this buffer; decremented when buffer released
+ without modification or when buffer is flushed
+ by swapout task */
+
+ rtems_bdpool_id pool; /* Identifier of buffer pool to which this buffer
+ belongs */
+ CORE_mutex_Control transfer_sema;
+ /* Transfer operation semaphore */
+} bdbuf_buffer;
+
+
+
+/* bdbuf_config structure describes block configuration (size,
+ * amount, memory location) for buffering layer
+ */
+typedef struct rtems_bdbuf_config {
+ int size; /* Size of block */
+ int num; /* Number of blocks of appropriate size */
+ unsigned char *mem_area;
+ /* Pointer to the blocks location or NULL, in this
+ case memory for blocks will be allocated by
+ Buffering Layer with the help of RTEMS partition
+ manager */
+} rtems_bdbuf_config;
+
+extern rtems_bdbuf_config rtems_bdbuf_configuration[];
+extern int rtems_bdbuf_configuration_size;
+
+#define SWAPOUT_TASK_DEFAULT_PRIORITY 15
+extern rtems_task_priority swapout_task_priority;
+
+/* rtems_bdbuf_init --
+ * Prepare buffering layer to work - initialize buffer descritors
+ * and (if it is neccessary) buffers. Buffers will be allocated accoriding
+ * to the configuration table, each entry describes kind of block and
+ * amount requested. After initialization all blocks is placed into
+ * free elements lists.
+ *
+ * PARAMETERS:
+ * conf_table - pointer to the buffers configuration table
+ * size - number of entries in configuration table
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ */
+rtems_status_code
+rtems_bdbuf_init(rtems_bdbuf_config *conf_table, int size);
+
+
+/* rtems_bdbuf_get --
+ * Obtain block buffer. If specified block already cached (i.e. there's
+ * block in the _modified_, or _recently_used_), return address
+ * of appropriate buffer descriptor and increment reference counter to 1.
+ * If block is not cached, allocate new buffer and return it. Data
+ * shouldn't be read to the buffer from media; buffer may contains
+ * arbitrary data. This primitive may be blocked if there are no free
+ * buffer descriptors available and there are no unused non-modified
+ * (or synchronized with media) buffers available.
+ *
+ * PARAMETERS:
+ * device - device number (constructed of major and minor device number)
+ * block - linear media block number
+ * bd - address of variable to store pointer to the buffer descriptor
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ *
+ * SIDE EFFECTS:
+ * bufget_sema semaphore obtained by this primitive.
+ */
+rtems_status_code
+rtems_bdbuf_get(dev_t device, blkdev_bnum block, bdbuf_buffer **bdb_ptr);
+
+/* rtems_bdbuf_read --
+ * (Similar to the rtems_bdbuf_get, except reading data from media)
+ * Obtain block buffer. If specified block already cached, return address
+ * of appropriate buffer and increment reference counter to 1. If block is
+ * not cached, allocate new buffer and read data to it from the media.
+ * This primitive may be blocked on waiting until data to be read from
+ * media, if there are no free buffer descriptors available and there are
+ * no unused non-modified (or synchronized with media) buffers available.
+ *
+ * PARAMETERS:
+ * device - device number (consists of major and minor device number)
+ * block - linear media block number
+ * bd - address of variable to store pointer to the buffer descriptor
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ *
+ * SIDE EFFECTS:
+ * bufget_sema and transfer_sema semaphores obtained by this primitive.
+ */
+rtems_status_code
+rtems_bdbuf_read(dev_t device, blkdev_bnum block, bdbuf_buffer **bdb_ptr);
+
+/* rtems_bdbuf_release --
+ * Release buffer allocated before. This primitive decrease the
+ * usage counter. If it is zero, further destiny of buffer depends on
+ * 'modified' status. If buffer was modified, it is placed to the end of
+ * mod list and flush task waken up. If buffer was not modified,
+ * it is placed to the end of lru list, and bufget_sema released, allowing
+ * to reuse this buffer.
+ *
+ * PARAMETERS:
+ * bd_buf - pointer to the bdbuf_buffer structure previously obtained using
+ * get/read primitive.
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ *
+ * SIDE EFFECTS:
+ * flush_sema and bufget_sema semaphores may be released by this primitive.
+ */
+rtems_status_code
+rtems_bdbuf_release(bdbuf_buffer *bd_buf);
+
+/* rtems_bdbuf_release_modified --
+ * Release buffer allocated before, assuming that it is _modified_ by
+ * it's owner. This primitive decrease usage counter for buffer, mark
+ * buffer descriptor as modified. If usage counter is 0, insert it at
+ * end of mod chain and release flush_sema semaphore to activate the
+ * flush task.
+ *
+ * PARAMETERS:
+ * bd_buf - pointer to the bdbuf_buffer structure previously obtained using
+ * get/read primitive.
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ *
+ * SIDE EFFECTS:
+ * flush_sema semaphore may be released by this primitive.
+ */
+rtems_status_code
+rtems_bdbuf_release_modified(bdbuf_buffer *bd_buf);
+
+/* rtems_bdbuf_sync --
+ * Wait until specified buffer synchronized with disk. Invoked on exchanges
+ * critical for data consistency on the media. This primitive mark owned
+ * block as modified, decrease usage counter. If usage counter is 0,
+ * block inserted to the mod chain and flush_sema semaphore released.
+ * Finally, primitives blocked on transfer_sema semaphore.
+ *
+ * PARAMETERS:
+ * bd_buf - pointer to the bdbuf_buffer structure previously obtained using
+ * get/read primitive.
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ *
+ * SIDE EFFECTS:
+ * Primitive may be blocked on transfer_sema semaphore.
+ */
+rtems_status_code
+rtems_bdbuf_sync(bdbuf_buffer *bd_buf);
+
+/* rtems_bdbuf_syncdev --
+ * Synchronize with disk all buffers containing the blocks belonging to
+ * specified device.
+ *
+ * PARAMETERS:
+ * dev - block device number
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ */
+rtems_status_code
+rtems_bdbuf_syncdev(dev_t dev);
+
+/* rtems_bdbuf_find_pool --
+ * Find first appropriate buffer pool. This primitive returns the index
+ * of first buffer pool which block size is greater than or equal to
+ * specified size.
+ *
+ * PARAMETERS:
+ * block_size - requested block size
+ * pool - placeholder for result
+ *
+ * RETURNS:
+ * RTEMS status code: RTEMS_SUCCESSFUL if operation completed successfully,
+ * RTEMS_INVALID_SIZE if specified block size is invalid (not a power
+ * of 2), RTEMS_NOT_DEFINED if buffer pool for this or greater block size
+ * is not configured.
+ */
+rtems_status_code
+rtems_bdbuf_find_pool(int block_size, rtems_bdpool_id *pool);
+
+/* rtems_bdbuf_get_pool_info --
+ * Obtain characteristics of buffer pool with specified number.
+ *
+ * PARAMETERS:
+ * pool - buffer pool number
+ * block_size - block size for which buffer pool is configured returned
+ * there
+ * blocks - number of buffers in buffer pool returned there
+ *
+ * RETURNS:
+ * RTEMS status code: RTEMS_SUCCESSFUL if operation completed successfully,
+ * RTEMS_INVALID_NUMBER if appropriate buffer pool is not configured.
+ *
+ * NOTE:
+ * Buffer pools enumerated contiguously starting from 0.
+ */
+rtems_status_code
+rtems_bdbuf_get_pool_info(rtems_bdpool_id pool, int *block_size, int *blocks);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libblock/include/rtems/blkdev.h b/cpukit/libblock/include/rtems/blkdev.h
new file mode 100644
index 0000000000..fadbdce9c7
--- /dev/null
+++ b/cpukit/libblock/include/rtems/blkdev.h
@@ -0,0 +1,154 @@
+/**
+ * @file rtems/blkdev.h
+ * block device driver interface definitions
+ */
+
+/*
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * @(#) $Id$
+ */
+
+#ifndef _RTEMS_BLKDEV_H
+#define _RTEMS_BLKDEV_H
+
+#include <rtems.h>
+#include <sys/ioctl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Interface with device drivers
+ * Block device looks, initialized and behaves like traditional RTEMS device
+ * driver. Heart of the block device driver is in BIOREQUEST ioctl. This call
+ * puts I/O request to the block device queue, in priority order, for
+ * asynchronous processing. When driver executes request, req_done
+ * function invoked, so callee knows about it. Look for details below.
+ */
+
+
+/* Block device block number datatype */
+typedef uint32_t blkdev_bnum;
+
+/* Block device request type */
+typedef enum blkdev_request_op {
+ BLKDEV_REQ_READ, /* Read operation */
+ BLKDEV_REQ_WRITE /* Write operation */
+} blkdev_request_op;
+
+/* Type for block device request done callback function.
+ *
+ * PARAMETERS:
+ * arg - argument supplied in blkdev_request
+ * status - rtems status code for this operation
+ * errno - errno value to be passed to the user when
+ * status != RTEMS_SUCCESSFUL
+ */
+typedef void (* blkdev_request_cb)(void *arg,
+ rtems_status_code status,
+ int error);
+
+/* blkdev_sg_buffer
+ * Block device scatter/gather buffer structure
+ */
+typedef struct blkdev_sg_buffer {
+ uint32_t length; /* Buffer length */
+ void *buffer; /* Buffer pointer */
+} blkdev_sg_buffer;
+
+/* blkdev_request (Block Device Request) structure is
+ * used to read/write a number of blocks from/to device.
+ */
+typedef struct blkdev_request {
+ blkdev_request_op req; /* Block device operation (read or write) */
+ blkdev_request_cb req_done; /* Callback function */
+ void *done_arg; /* Argument to be passed to callback function*/
+ rtems_status_code status; /* Last I/O operation completion status */
+ int error; /* If status != RTEMS_SUCCESSFUL, this field
+ * contains error code
+ */
+ blkdev_bnum start; /* Start block number */
+ uint32_t count; /* Number of blocks to be exchanged */
+ uint32_t bufnum; /* Number of buffers provided */
+
+ blkdev_sg_buffer bufs[0];/* List of scatter/gather buffers */
+} blkdev_request;
+
+/* Block device IOCTL request codes */
+#define BLKIO_REQUEST _IOWR('B', 1, blkdev_request)
+#define BLKIO_GETBLKSIZE _IO('B', 2)
+#define BLKIO_GETSIZE _IO('B', 3)
+#define BLKIO_SYNCDEV _IO('B', 4)
+
+/* Device driver interface conventions suppose that driver may
+ * contain initialize/open/close/read/write/ioctl entry points. These
+ * primitives (except initialize) can be implemented in generic fashion,
+ * based upon supplied block device driver ioctl handler. Every block
+ * device driver should provide initialize entry point, which is register
+ * all block devices and appropriate ioctl handlers.
+ */
+
+#define GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES \
+ rtems_blkdev_generic_open, rtems_blkdev_generic_close, \
+ rtems_blkdev_generic_read, rtems_blkdev_generic_write, \
+ rtems_blkdev_generic_ioctl
+
+/* blkdev_generic_read --
+ * Generic block device read primitive. Implemented using block device
+ * buffer management primitives.
+ */
+rtems_device_driver
+rtems_blkdev_generic_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+);
+
+/* blkdev_generic_write --
+ * Generic block device driver write primitive. Implemented using block
+ * device buffer management primitives.
+ */
+rtems_device_driver
+rtems_blkdev_generic_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+);
+
+/* blkdev_generic_open --
+ * Generic block device open primitive.
+ */
+rtems_device_driver
+rtems_blkdev_generic_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+);
+
+/* blkdev_generic_close --
+ * Generic block device close primitive.
+ */
+rtems_device_driver
+rtems_blkdev_generic_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+);
+
+/* blkdev_generic_ioctl --
+ * Generic block device ioctl primitive.
+ */
+rtems_device_driver
+rtems_blkdev_generic_ioctl(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libblock/include/rtems/diskdevs.h b/cpukit/libblock/include/rtems/diskdevs.h
new file mode 100644
index 0000000000..eff763f9e0
--- /dev/null
+++ b/cpukit/libblock/include/rtems/diskdevs.h
@@ -0,0 +1,209 @@
+/**
+ * @file rtems/diskdevs.h
+ * Physical and logical block devices (disks) support
+ */
+
+/*
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * @(#) $Id$
+ */
+
+#ifndef _RTEMS_DISKDEVS_H
+#define _RTEMS_DISKDEVS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <stdlib.h>
+
+#include "rtems/blkdev.h"
+
+/* Buffer pool identifier */
+typedef int rtems_bdpool_id;
+
+/* Block device ioctl handler */
+typedef int (* block_device_ioctl) (dev_t dev, uint32_t req, void *argp);
+
+/* disk_device: Entry of this type created for every disk device (both for
+ * logical and physical disks).
+ * Array of arrays of pointers to disk_device structures maintained. First
+ * table indexed by major number and second table indexed by minor number.
+ * Such data organization allow quick lookup using data structure of
+ * moderated size.
+ */
+typedef struct disk_device {
+ dev_t dev; /* Device ID (major + minor) */
+ struct disk_device *phys_dev; /* Physical device ID (the same
+ as dev if this entry specifies
+ the physical device) */
+ char *name; /* Disk device name */
+ int uses; /* Use counter. Device couldn't be
+ removed if it is in use. */
+ int start; /* Starting block number (0 for
+ physical devices, block offset
+ on the related physical device
+ for logical device) */
+ int size; /* Size of physical or logical disk
+ in disk blocks */
+ int block_size; /* Size of device block (minimum
+ transfer unit) in bytes
+ (must be power of 2) */
+ int block_size_log2; /* log2 of block_size */
+ rtems_bdpool_id pool; /* Buffer pool assigned to this
+ device */
+ block_device_ioctl ioctl; /* ioctl handler for this block
+ device */
+} disk_device;
+
+/* rtems_disk_create_phys --
+ * Create physical disk entry. This function usually invoked from
+ * block device driver initialization code when physical device
+ * detected in the system. Device driver should provide ioctl handler
+ * to allow block device access operations. This primitive will register
+ * device in rtems (invoke rtems_io_register_name).
+ *
+ * PARAMETERS:
+ * dev - device identifier (major, minor numbers)
+ * block_size - size of disk block (minimum data transfer unit); must be
+ * power of 2
+ * disk_size - number of blocks on device
+ * handler - IOCTL handler (function providing basic block input/output
+ * request handling BIOREQUEST and other device management
+ * operations)
+ * name - character name of device (e.g. /dev/hda)
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if information about new physical disk added, or
+ * error code if error occured (device already registered, wrong block
+ * size value, no memory available).
+ */
+rtems_status_code
+rtems_disk_create_phys(dev_t dev, int block_size, int disk_size,
+ block_device_ioctl handler,
+ char *name);
+
+/* rtems_disk_create_log --
+ * Create logical disk entry. Logical disk is contiguous area on physical
+ * disk. Disk may be splitted to several logical disks in several ways:
+ * manually or using information stored in blocks on physical disk
+ * (DOS-like partition table, BSD disk label, etc). This function usually
+ * invoked from application when application-specific splitting are in use,
+ * or from generic code which handle different logical disk organizations.
+ * This primitive will register device in rtems (invoke
+ * rtems_io_register_name).
+ *
+ * PARAMETERS:
+ * dev - logical device identifier (major, minor numbers)
+ * phys - physical device (block device which holds this logical disk)
+ * identifier
+ * start - starting block number on the physical device
+ * size - logical disk size in blocks
+ * name - logical disk name
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if logical device successfully added, or error code
+ * if error occured (device already registered, no physical device
+ * exists, logical disk is out of physical disk boundaries, no memory
+ * available).
+ */
+rtems_status_code
+rtems_disk_create_log(dev_t dev, dev_t phys, int start, int size, char *name);
+
+/* rtems_disk_delete --
+ * Delete physical or logical disk device. Device may be deleted if its
+ * use counter (and use counters of all logical devices - if it is
+ * physical device) equal to 0. When physical device deleted,
+ * all logical devices deleted inherently. Appropriate devices removed
+ * from "/dev" filesystem.
+ *
+ * PARAMETERS:
+ * dev - device identifier (major, minor numbers)
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if block device successfully deleted, or error code
+ * if error occured (device is not defined, device is in use).
+ */
+rtems_status_code
+rtems_disk_delete(dev_t dev);
+
+/* rtems_disk_lookup --
+ * Find block device descriptor by its device identifier. This function
+ * increment usage counter to 1. User should release disk_device structure
+ * by invoking rtems_disk_release primitive.
+ *
+ * PARAMETERS:
+ * dev - device identifier (major, minor numbers)
+ *
+ * RETURNS:
+ * pointer to the block device descriptor, or NULL if no such device
+ * exists.
+ */
+disk_device *
+rtems_disk_lookup(dev_t dev);
+
+/* rtems_disk_release --
+ * Release disk_device structure (decrement usage counter to 1).
+ *
+ * PARAMETERS:
+ * dd - pointer to disk device structure
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL
+ *
+ * NOTE:
+ * It should be implemented as inline function.
+ */
+rtems_status_code
+rtems_disk_release(disk_device *dd);
+
+/* rtems_disk_next --
+ * Disk device enumerator. Looking for device having device number larger
+ * than dev and return disk device descriptor for it. If there are no
+ * such device, NULL value returned.
+ *
+ * PARAMETERS:
+ * dev - device number (use -1 to start search)
+ *
+ * RETURNS:
+ * Pointer to the disk descriptor for next disk device, or NULL if all
+ * devices enumerated. */
+disk_device *
+rtems_disk_next(dev_t dev);
+
+/* rtems_diskio_initialize --
+ * Initialization of disk device library (initialize all data structures,
+ * etc.)
+ *
+ * PARAMETERS:
+ * none
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if library initialized, or error code if error
+ * occured.
+ */
+rtems_status_code
+rtems_disk_io_initialize(void);
+
+/* rtems_diskio_done --
+ * Release all resources allocated for disk device interface.
+ *
+ * PARAMETERS:
+ * none
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if all resources released, or error code if error
+ * occured.
+ */
+rtems_status_code
+rtems_disk_io_done(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libblock/include/rtems/ide_part_table.h b/cpukit/libblock/include/rtems/ide_part_table.h
new file mode 100644
index 0000000000..abbbb121c4
--- /dev/null
+++ b/cpukit/libblock/include/rtems/ide_part_table.h
@@ -0,0 +1,199 @@
+/**
+ * @file rtems/ide_part_table.h
+ *
+ * Support for "MS-DOS-style" partition tables
+ */
+
+/*
+ * Copyright (C) 2002 OKTET Ltd., St.-Petersburg, Russia
+ *
+ * Author: Konstantin Abramenko <Konstantin.Abramenko@oktet.ru>
+ * Alexander Kukuta <Alexander.Kukuta@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ *****************************************************************************/
+
+#ifndef _RTEMS_IDE_PART_TABLE_H
+#define _RTEMS_IDE_PART_TABLE_H
+
+#include <assert.h>
+#include <rtems/chain.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <rtems.h>
+#include <rtems/blkdev.h>
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+#include <rtems/bdbuf.h>
+#include <rtems/seterr.h>
+
+/* Minor base number for all logical devices */
+#define RTEMS_IDE_SECTOR_BITS 9
+#define RTEMS_IDE_SECTOR_SIZE 512
+#define RTEMS_IDE_PARTITION_DESCRIPTOR_SIZE 16
+#define RTEMS_IDE_PARTITION_MAX_PARTITION_NUMBER 63
+#define RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER 4
+#define RTEMS_IDE_PARTITION_DEV_NAME_LENGTH_MAX 16
+
+#define RTEMS_IDE_PARTITION_MSDOS_SIGNATURE_DATA1 0x55
+#define RTEMS_IDE_PARTITION_MSDOS_SIGNATURE_DATA2 0xaa
+#define RTEMS_IDE_PARTITION_MSDOS_SIGNATURE_OFFSET 0x1fe
+#define RTEMS_IDE_PARTITION_TABLE_OFFSET 0x1be
+#define RTEMS_IDE_PARTITION_BOOTABLE_OFFSET 0
+#define RTEMS_IDE_PARTITION_SYS_TYPE_OFFSET 4
+#define RTEMS_IDE_PARTITION_START_OFFSET 8
+#define RTEMS_IDE_PARTITION_SIZE_OFFSET 12
+
+/*
+ * Conversion from and to little-endian byte order. (no-op on i386/i486)
+ */
+
+#if (CPU_BIG_ENDIAN == TRUE)
+# define LE_TO_CPU_U16(v) CPU_swap_u16(v)
+# define LE_TO_CPU_U32(v) CPU_swap_u32(v)
+# define CPU_TO_LE_U16(v) CPU_swap_u16(v)
+# define CPU_TO_LE_U32(v) CPU_swap_u32(v)
+#else
+# define LE_TO_CPU_U16(v) (v)
+# define LE_TO_CPU_U32(v) (v)
+# define CPU_TO_LE_U16(v) (v)
+# define CPU_TO_LE_U32(v) (v)
+#endif
+
+
+/*
+ * sector_data_t --
+ * corresponds to the sector on the device
+ */
+typedef struct sector_data_s
+{
+ uint32_t sector_num; /* sector number on the device */
+ uint8_t data[0]; /* raw sector data */
+} sector_data_t;
+
+
+/*
+ * Enum partition types
+ * see list at http://ata-atapi.com/hiwtab.htm
+ */
+enum {
+ EMPTY_PARTITION = 0x00,
+ DOS_FAT12_PARTITION = 0x01,
+ DOS_FAT16_PARTITION = 0x04,
+ EXTENDED_PARTITION = 0x05,
+ DOS_P32MB_PARTITION = 0x06,
+ FAT32_PARTITION = 0x0B,
+ FAT32_LBA_PARTITION = 0x0C,
+ FAT16_LBA_PARTITION = 0x0E,
+ DM6_PARTITION = 0x54,
+ EZD_PARTITION = 0x55,
+ DM6_AUX1PARTITION = 0x51,
+ DM6_AUX3PARTITION = 0x53,
+ LINUX_SWAP = 0x82,
+ LINUX_NATIVE = 0x83,
+ LINUX_EXTENDED = 0x85
+};
+
+
+/* Forward declaration */
+struct disk_desc_s;
+
+/*
+ * part_desc_t --
+ * contains all neccessary information about partition
+ */
+typedef struct part_desc_s {
+ uint8_t bootable; /* is the partition active */
+ uint8_t sys_type; /* type of partition */
+ uint8_t log_id; /* logical number of partition */
+ uint32_t start; /* first partition sector, in absolute numeration */
+ uint32_t size; /* size in sectors */
+ uint32_t end; /* last partition sector, end = start + size - 1 */
+ struct disk_desc_s *disk_desc; /* descriptor of disk, partition contains in */
+ struct part_desc_s *ext_part; /* extended partition containing this one */
+
+ /* partitions, containing in this one */
+ struct part_desc_s *sub_part[RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER];
+} part_desc_t;
+
+
+
+typedef struct disk_desc_s {
+ dev_t dev; /* device number */
+
+ /* device name in /dev filesystem */
+ char dev_name[RTEMS_IDE_PARTITION_DEV_NAME_LENGTH_MAX];
+
+ uint32_t sector_size; /* size of sector */
+ uint32_t sector_bits; /* the base-2 logarithm of sector_size */
+ uint32_t lba_size; /* total amount of sectors in lba address mode */
+ int last_log_id; /* used for logical disks enumerating */
+
+ /* primary partition descriptors */
+ part_desc_t *partitions[RTEMS_IDE_PARTITION_MAX_PARTITION_NUMBER];
+} disk_desc_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * rtems_ide_part_table_free --
+ * frees disk descriptor structure
+ *
+ * PARAMETERS:
+ * disk_desc - disc descriptor structure to free
+ *
+ * RETURNS:
+ * N/A
+ */
+void
+rtems_ide_part_table_free(disk_desc_t *disk_desc);
+
+
+/*
+ * rtems_ide_part_table_get --
+ * reads partition table structure from the device
+ * and creates disk description structure
+ *
+ * PARAMETERS:
+ * dev_name - path to physical device in /dev filesystem
+ * disk_desc - returned disc description structure
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if success, or -1 and corresponding errno else
+ */
+rtems_status_code
+rtems_ide_part_table_get(const char *dev_name, disk_desc_t *disk_desc);
+
+
+/*
+ * rtems_ide_part_table_initialize --
+ * initializes logical devices on the physical IDE drive
+ *
+ * PARAMETERS:
+ * dev_name - path to physical device in /dev filesystem
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if success, or -1 and corresponding errno else
+ */
+rtems_status_code
+rtems_ide_part_table_initialize(char *dev_name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_IDE_PART_TABLE_H */
diff --git a/cpukit/libblock/include/rtems/ramdisk.h b/cpukit/libblock/include/rtems/ramdisk.h
new file mode 100644
index 0000000000..64d9bad5e7
--- /dev/null
+++ b/cpukit/libblock/include/rtems/ramdisk.h
@@ -0,0 +1,56 @@
+/**
+ * @file rtems/ramdisk.h
+ * RAM disk block device implementation
+ */
+
+/*
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * @(#) $Id$
+ */
+
+#ifndef _RTEMS_RAMDISK_H
+#define _RTEMS_RAMDISK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+
+#include "rtems/blkdev.h"
+
+/* RAM disk configuration table entry */
+typedef struct rtems_ramdisk_config {
+ int block_size; /* RAM disk block size */
+ int block_num; /* Number of blocks on this RAM disk */
+ void *location; /* RAM disk permanent location (out of RTEMS controlled
+ memory), or NULL if RAM disk memory should be
+ allocated dynamically */
+} rtems_ramdisk_config;
+
+/* If application want to use RAM disk, it should specify configuration of
+ * available RAM disks.
+ * The following is definitions for RAM disk configuration table
+ */
+extern rtems_ramdisk_config rtems_ramdisk_configuration[];
+extern size_t rtems_ramdisk_configuration_size;
+
+/* ramdisk_initialize --
+ * RAM disk driver initialization entry point.
+ */
+rtems_device_driver
+ramdisk_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg);
+
+#define RAMDISK_DRIVER_TABLE_ENTRY \
+ { ramdisk_initialize, GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libblock/preinstall.am b/cpukit/libblock/preinstall.am
new file mode 100644
index 0000000000..dba6cc4d81
--- /dev/null
+++ b/cpukit/libblock/preinstall.am
@@ -0,0 +1,7 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
new file mode 100644
index 0000000000..8fb7d515be
--- /dev/null
+++ b/cpukit/libblock/src/bdbuf.c
@@ -0,0 +1,1920 @@
+/*
+ * Disk I/O buffering
+ * Buffer managment
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Peterburg, Russia
+ * Author: Andrey G. Ivanov <Andrey.Ivanov@oktet.ru>
+ * Victor V. Vengerov <vvv@oktet.ru>
+ * Alexander Kukuta <kam@oktet.ru>
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+#include <limits.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "rtems/bdbuf.h"
+
+/* Fatal errors: */
+#define BLKDEV_FATAL_ERROR(n) (((uint32_t)'B' << 24) | ((uint32_t)(n) & (uint32_t)0x00FFFFFF))
+#define BLKDEV_FATAL_BDBUF_CONSISTENCY BLKDEV_FATAL_ERROR(1)
+#define BLKDEV_FATAL_BDBUF_SWAPOUT BLKDEV_FATAL_ERROR(2)
+
+
+#define SWAPOUT_TASK_STACK_SIZE (RTEMS_MINIMUM_STACK_SIZE * 2)
+
+#define READ_MULTIPLE
+
+#if defined(READ_MULTIPLE)
+#define READ_AHEAD_MAX_BLK_CNT 32
+typedef struct {
+ blkdev_request req;
+ blkdev_sg_buffer sg[READ_AHEAD_MAX_BLK_CNT];
+} blkdev_request_read_ahead;
+/*
+ * list of bd_bufs related to one transfer request
+ */
+typedef struct {
+ int cnt;
+ bdbuf_buffer *bd_bufs[READ_AHEAD_MAX_BLK_CNT];
+} read_ahead_bd_buf_group;
+#endif
+
+typedef struct {
+ blkdev_request *req;
+ bdbuf_buffer **write_store;
+} write_tfer_done_arg_t;
+
+static rtems_task bdbuf_swapout_task(rtems_task_argument unused);
+
+static rtems_status_code bdbuf_release(bdbuf_buffer *bd_buf);
+/*
+ * The groups of the blocks with the same size are collected in the
+ * bd_pool. Note that a several of the buffer's groups with the
+ * same size can exists.
+ */
+typedef struct bdbuf_pool
+{
+ bdbuf_buffer *tree; /* Buffer descriptor lookup AVL tree root */
+
+ Chain_Control free; /* Free buffers list */
+ Chain_Control lru; /* Last recently used list */
+
+ int blksize; /* The size of the blocks (in bytes) */
+ int nblks; /* Number of blocks in this pool */
+ rtems_id bufget_sema; /* Buffer obtain counting semaphore */
+ void *mallocd_bufs; /* Pointer to the malloc'd buffer memory,
+ or NULL, if buffer memory provided in
+ buffer configuration */
+ bdbuf_buffer *bdbufs; /* Pointer to table of buffer descriptors
+ allocated for this buffer pool. */
+} bdbuf_pool;
+
+/* Buffering layer context definition */
+struct bdbuf_context {
+ bdbuf_pool *pool; /* Table of buffer pools */
+ int npools; /* Number of entries in pool table */
+
+ Chain_Control mod; /* Modified buffers list */
+ rtems_id flush_sema; /* Buffer flush semaphore; counting
+ semaphore; incremented when buffer
+ flushed to the disk; decremented when
+ buffer modified */
+ rtems_id swapout_task; /* Swapout task ID */
+};
+/*
+ * maximum number of blocks that might be chained together to one
+ * write driver call
+ */
+#define SWAP_OUT_MAX_BLK_CNT 32
+/*#define SWAP_OUT_MAX_BLK_CNT 1 */
+/*
+ * XXX: this is a global buffer. It is used in the swapout task
+ * and currently will be reused only after it is no longer in use
+ *
+ */
+static bdbuf_buffer *bd_buf_write_store[SWAP_OUT_MAX_BLK_CNT];
+
+/* Block device request with a single buffer provided */
+typedef struct blkdev_request1 {
+ blkdev_request req;
+ blkdev_sg_buffer sg[1];
+} blkdev_request1;
+
+/* The static context of buffering layer */
+static struct bdbuf_context bd_ctx;
+
+#define SAFE
+#ifdef SAFE
+typedef rtems_mode preemption_key;
+
+#define DISABLE_PREEMPTION(key) \
+ do { \
+ rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &(key)); \
+ } while (0)
+
+#define ENABLE_PREEMPTION(key) \
+ do { \
+ rtems_mode temp; \
+ rtems_task_mode((key), RTEMS_PREEMPT_MASK, &temp); \
+ } while (0)
+
+#else
+
+typedef boolean preemption_key;
+
+#define DISABLE_PREEMPTION(key) \
+ do { \
+ (key) = _Thread_Executing->is_preemptible; \
+ _Thread_Executing->is_preemptible = 0; \
+ } while (0)
+
+#define ENABLE_PREEMPTION(key) \
+ do { \
+ _Thread_Executing->is_preemptible = (key); \
+ if (_Thread_Evaluate_mode()) \
+ _Thread_Dispatch(); \
+ } while (0)
+
+#endif
+
+
+/* The default maximum height of 32 allows for AVL trees having
+ between 5,704,880 and 4,294,967,295 nodes, depending on order of
+ insertion. You may change this compile-time constant as you
+ wish. */
+#ifndef AVL_MAX_HEIGHT
+#define AVL_MAX_HEIGHT 32
+#endif
+
+/*
+ * avl_search --
+ * Searches for the node with specified dev/block.
+ *
+ * PARAMETERS:
+ * root - pointer to the root node of the AVL-Tree.
+ * dev, block - search key
+ *
+ * RETURNS:
+ * NULL if node with specified dev/block not found
+ * non-NULL - pointer to the node with specified dev/block
+ */
+static bdbuf_buffer *
+avl_search(bdbuf_buffer **root, dev_t dev, blkdev_bnum block)
+{
+ bdbuf_buffer *p = *root;
+
+ while ((p != NULL) && ((p->dev != dev) || (p->block != block)))
+ {
+ if ((p->dev < dev) || ((p->dev == dev) && (p->block < block)))
+ {
+ p = p->avl.right;
+ }
+ else
+ {
+ p = p->avl.left;
+ }
+ }
+
+ return p;
+}
+
+
+/* avl_search_for_sync --
+ * Search in AVL tree for first modified buffer belongs to specified
+ * disk device.
+ *
+ * PARAMETERS:
+ * root - pointer to tree root
+ * dd - disk device descriptor
+ *
+ * RETURNS:
+ * Block buffer, or NULL if no modified blocks on specified device
+ * exists.
+ */
+static bdbuf_buffer *
+avl_search_for_sync(bdbuf_buffer **root, disk_device *dd)
+{
+ dev_t dev = dd->phys_dev->dev;
+ blkdev_bnum block_start = dd->start;
+ blkdev_bnum block_end = dd->start + dd->size - 1;
+
+ bdbuf_buffer *buf_stack[AVL_MAX_HEIGHT];
+ bdbuf_buffer **buf_prev = buf_stack;
+ bdbuf_buffer *p = *root;
+
+ while (p != NULL)
+ {
+ if ((p->dev < dev) || ((p->dev == dev) && (p->block < block_start)))
+ {
+ p = p->avl.right;
+ }
+ else if ((p->dev > dev) || ((p->dev == dev) && (p->block > block_end)))
+ {
+ p = p->avl.left;
+ }
+ else if (p->modified)
+ {
+ return p;
+ }
+ else
+ {
+ if (p->avl.right != NULL)
+ {
+ *buf_prev++ = p->avl.right;
+ }
+ p = p->avl.left;
+ }
+
+ if ((p == NULL) && (buf_prev > buf_stack))
+ {
+ p = *--buf_prev;
+ }
+ }
+
+ return p;
+}
+
+
+/*
+ * avl_insert --
+ * Inserts the specified node to the AVl-Tree.
+ *
+ * PARAMETERS:
+ * root - Pointer to pointer to the root node
+ * node - Pointer to the node to add.
+ *
+ * RETURNS:
+ * 0 - The node added successfully
+ * -1 - An error occured
+ */
+static int
+avl_insert(bdbuf_buffer **root, bdbuf_buffer *node)
+{
+ dev_t dev = node->dev;
+ blkdev_bnum block = node->block;
+
+ bdbuf_buffer *p = *root;
+ bdbuf_buffer *q, *p1, *p2;
+ bdbuf_buffer *buf_stack[AVL_MAX_HEIGHT];
+ bdbuf_buffer **buf_prev = buf_stack;
+
+ boolean modified = FALSE;
+
+ if (p == NULL)
+ {
+ *root = node;
+ node->avl.left = NULL;
+ node->avl.right = NULL;
+ node->avl.bal = 0;
+ return 0;
+ }
+
+ while (p != NULL)
+ {
+ *buf_prev++ = p;
+
+ if ((p->dev < dev) || ((p->dev == dev) && (p->block < block)))
+ {
+ p->avl.cache = 1;
+ q = p->avl.right;
+ if (q == NULL)
+ {
+ q = node;
+ p->avl.right = q = node;
+ break;
+ }
+ }
+ else if ((p->dev != dev) || (p->block != block))
+ {
+ p->avl.cache = -1;
+ q = p->avl.left;
+ if (q == NULL)
+ {
+ q = node;
+ p->avl.left = q;
+ break;
+ }
+ }
+ else
+ {
+ return -1;
+ }
+
+ p = q;
+ }
+
+ q->avl.left = q->avl.right = NULL;
+ q->avl.bal = 0;
+ modified = TRUE;
+ buf_prev--;
+
+ while (modified)
+ {
+ if (p->avl.cache == -1)
+ {
+ switch (p->avl.bal)
+ {
+ case 1:
+ p->avl.bal = 0;
+ modified = FALSE;
+ break;
+
+ case 0:
+ p->avl.bal = -1;
+ break;
+
+ case -1:
+ p1 = p->avl.left;
+ if (p1->avl.bal == -1) /* simple LL-turn */
+ {
+ p->avl.left = p1->avl.right;
+ p1->avl.right = p;
+ p->avl.bal = 0;
+ p = p1;
+ }
+ else /* double LR-turn */
+ {
+ p2 = p1->avl.right;
+ p1->avl.right = p2->avl.left;
+ p2->avl.left = p1;
+ p->avl.left = p2->avl.right;
+ p2->avl.right = p;
+ if (p2->avl.bal == -1) p->avl.bal = +1; else p->avl.bal = 0;
+ if (p2->avl.bal == +1) p1->avl.bal = -1; else p1->avl.bal = 0;
+ p = p2;
+ }
+ p->avl.bal = 0;
+ modified = FALSE;
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch (p->avl.bal)
+ {
+ case -1:
+ p->avl.bal = 0;
+ modified = FALSE;
+ break;
+
+ case 0:
+ p->avl.bal = 1;
+ break;
+
+ case 1:
+ p1 = p->avl.right;
+ if (p1->avl.bal == 1) /* simple RR-turn */
+ {
+ p->avl.right = p1->avl.left;
+ p1->avl.left = p;
+ p->avl.bal = 0;
+ p = p1;
+ }
+ else /* double RL-turn */
+ {
+ p2 = p1->avl.left;
+ p1->avl.left = p2->avl.right;
+ p2->avl.right = p1;
+ p->avl.right = p2->avl.left;
+ p2->avl.left = p;
+ if (p2->avl.bal == +1) p->avl.bal = -1; else p->avl.bal = 0;
+ if (p2->avl.bal == -1) p1->avl.bal = +1; else p1->avl.bal = 0;
+ p = p2;
+ }
+ p->avl.bal = 0;
+ modified = FALSE;
+ break;
+
+ default:
+ break;
+ }
+ }
+ q = p;
+ if (buf_prev > buf_stack)
+ {
+ p = *--buf_prev;
+
+ if (p->avl.cache == -1)
+ {
+ p->avl.left = q;
+ }
+ else
+ {
+ p->avl.right = q;
+ }
+ }
+ else
+ {
+ *root = p;
+ break;
+ }
+ };
+
+ return 0;
+}
+
+
+/* avl_remove --
+ * removes the node from the tree.
+ *
+ * PARAMETERS:
+ * root_addr - Pointer to pointer to the root node
+ * node - Pointer to the node to remove
+ *
+ * RETURNS:
+ * 0 - Item removed
+ * -1 - No such item found
+ */
+static int
+avl_remove(bdbuf_buffer **root, const bdbuf_buffer *node)
+{
+ dev_t dev = node->dev;
+ blkdev_bnum block = node->block;
+
+ bdbuf_buffer *p = *root;
+ bdbuf_buffer *q, *r, *s, *p1, *p2;
+ bdbuf_buffer *buf_stack[AVL_MAX_HEIGHT];
+ bdbuf_buffer **buf_prev = buf_stack;
+
+ boolean modified = FALSE;
+
+ memset(buf_stack, 0, sizeof(buf_stack));
+
+ while (p != NULL)
+ {
+ *buf_prev++ = p;
+
+ if ((p->dev < dev) || ((p->dev == dev) && (p->block < block)))
+ {
+ p->avl.cache = 1;
+ p = p->avl.right;
+ }
+ else if ((p->dev != dev) || (p->block != block))
+ {
+ p->avl.cache = -1;
+ p = p->avl.left;
+ }
+ else
+ {
+ /* node found */
+ break;
+ }
+ }
+
+ if (p == NULL)
+ {
+ /* there is no such node */
+ return -1;
+ }
+
+ q = p;
+
+ buf_prev--;
+ if (buf_prev > buf_stack)
+ {
+ p = *(buf_prev - 1);
+ }
+ else
+ {
+ p = NULL;
+ }
+
+ /* at this moment q - is a node to delete, p is q's parent */
+ if (q->avl.right == NULL)
+ {
+ r = q->avl.left;
+ if (r != NULL)
+ {
+ r->avl.bal = 0;
+ }
+ q = r;
+ }
+ else
+ {
+ bdbuf_buffer **t;
+
+ r = q->avl.right;
+
+ if (r->avl.left == NULL)
+ {
+ r->avl.left = q->avl.left;
+ r->avl.bal = q->avl.bal;
+ r->avl.cache = 1;
+ *buf_prev++ = q = r;
+ }
+ else
+ {
+ t = buf_prev++;
+ s = r;
+
+ while (s->avl.left != NULL)
+ {
+ *buf_prev++ = r = s;
+ s = r->avl.left;
+ r->avl.cache = -1;
+ }
+
+ s->avl.left = q->avl.left;
+ r->avl.left = s->avl.right;
+ s->avl.right = q->avl.right;
+ s->avl.bal = q->avl.bal;
+ s->avl.cache = 1;
+
+ *t = q = s;
+ }
+ }
+
+ if (p != NULL)
+ {
+ if (p->avl.cache == -1)
+ {
+ p->avl.left = q;
+ }
+ else
+ {
+ p->avl.right = q;
+ }
+ }
+ else
+ {
+ *root = q;
+ }
+
+ modified = TRUE;
+
+ while (modified)
+ {
+ if (buf_prev > buf_stack)
+ {
+ p = *--buf_prev;
+ }
+ else
+ {
+ break;
+ }
+
+ if (p->avl.cache == -1)
+ {
+ /* rebalance left branch */
+ switch (p->avl.bal)
+ {
+ case -1:
+ p->avl.bal = 0;
+ break;
+ case 0:
+ p->avl.bal = 1;
+ modified = FALSE;
+ break;
+
+ case +1:
+ p1 = p->avl.right;
+
+ if (p1->avl.bal >= 0) /* simple RR-turn */
+ {
+ p->avl.right = p1->avl.left;
+ p1->avl.left = p;
+
+ if (p1->avl.bal == 0)
+ {
+ p1->avl.bal = -1;
+ modified = FALSE;
+ }
+ else
+ {
+ p->avl.bal = 0;
+ p1->avl.bal = 0;
+ }
+ p = p1;
+ }
+ else /* double RL-turn */
+ {
+ p2 = p1->avl.left;
+
+ p1->avl.left = p2->avl.right;
+ p2->avl.right = p1;
+ p->avl.right = p2->avl.left;
+ p2->avl.left = p;
+
+ if (p2->avl.bal == +1) p->avl.bal = -1; else p->avl.bal = 0;
+ if (p2->avl.bal == -1) p1->avl.bal = 1; else p1->avl.bal = 0;
+
+ p = p2;
+ p2->avl.bal = 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ /* rebalance right branch */
+ switch (p->avl.bal)
+ {
+ case +1:
+ p->avl.bal = 0;
+ break;
+
+ case 0:
+ p->avl.bal = -1;
+ modified = FALSE;
+ break;
+
+ case -1:
+ p1 = p->avl.left;
+
+ if (p1->avl.bal <= 0) /* simple LL-turn */
+ {
+ p->avl.left = p1->avl.right;
+ p1->avl.right = p;
+ if (p1->avl.bal == 0)
+ {
+ p1->avl.bal = 1;
+ modified = FALSE;
+ }
+ else
+ {
+ p->avl.bal = 0;
+ p1->avl.bal = 0;
+ }
+ p = p1;
+ }
+ else /* double LR-turn */
+ {
+ p2 = p1->avl.right;
+
+ p1->avl.right = p2->avl.left;
+ p2->avl.left = p1;
+ p->avl.left = p2->avl.right;
+ p2->avl.right = p;
+
+ if (p2->avl.bal == -1) p->avl.bal = 1; else p->avl.bal = 0;
+ if (p2->avl.bal == +1) p1->avl.bal = -1; else p1->avl.bal = 0;
+
+ p = p2;
+ p2->avl.bal = 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (buf_prev > buf_stack)
+ {
+ q = *(buf_prev - 1);
+
+ if (q->avl.cache == -1)
+ {
+ q->avl.left = p;
+ }
+ else
+ {
+ q->avl.right = p;
+ }
+ }
+ else
+ {
+ *root = p;
+ break;
+ }
+
+ }
+
+ return 0;
+}
+
+/* bdbuf_initialize_pool --
+ * Initialize single buffer pool.
+ *
+ * PARAMETERS:
+ * config - buffer pool configuration
+ * pool - pool number
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL, if buffer pool initialized successfully, or error
+ * code if error occured.
+ */
+static rtems_status_code
+bdbuf_initialize_pool(rtems_bdbuf_config *config, int pool)
+{
+ bdbuf_pool *p = bd_ctx.pool + pool;
+ unsigned char *bufs;
+ bdbuf_buffer *b;
+ rtems_status_code rc;
+ int i;
+
+ p->blksize = config->size;
+ p->nblks = config->num;
+ p->tree = NULL;
+
+ Chain_Initialize_empty(&p->free);
+ Chain_Initialize_empty(&p->lru);
+
+ /* Allocate memory for buffer descriptors */
+ p->bdbufs = calloc(config->num, sizeof(bdbuf_buffer));
+ if (p->bdbufs == NULL)
+ {
+ return RTEMS_NO_MEMORY;
+ }
+
+ /* Allocate memory for buffers if required */
+ if (config->mem_area == NULL)
+ {
+ bufs = p->mallocd_bufs = malloc(config->num * config->size);
+ if (bufs == NULL)
+ {
+ free(p->bdbufs);
+ return RTEMS_NO_MEMORY;
+ }
+ }
+ else
+ {
+ bufs = config->mem_area;
+ p->mallocd_bufs = NULL;
+ }
+
+ for (i = 0, b = p->bdbufs; i < p->nblks; i++, b++, bufs += p->blksize)
+ {
+ b->dev = -1; b->block = 0;
+ b->buffer = bufs;
+ b->actual = b->modified = b->in_progress = FALSE;
+ b->use_count = 0;
+ b->pool = pool;
+ _Chain_Append(&p->free, &b->link);
+ }
+
+ rc = rtems_semaphore_create(
+ rtems_build_name('B', 'U', 'F', 'G'),
+ p->nblks,
+ RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY |
+ RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL,
+ 0,
+ &p->bufget_sema);
+
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ free(p->bdbufs);
+ free(p->mallocd_bufs);
+ return rc;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* bdbuf_release_pool --
+ * Free resources allocated for buffer pool with specified number.
+ *
+ * PARAMETERS:
+ * pool - buffer pool number
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL
+ */
+static rtems_status_code
+bdbuf_release_pool(rtems_bdpool_id pool)
+{
+ bdbuf_pool *p = bd_ctx.pool + pool;
+ rtems_semaphore_delete(p->bufget_sema);
+ free(p->bdbufs);
+ free(p->mallocd_bufs);
+ return RTEMS_SUCCESSFUL;
+}
+
+/* rtems_bdbuf_init --
+ * Prepare buffering layer to work - initialize buffer descritors
+ * and (if it is neccessary)buffers. Buffers will be allocated accoriding
+ * to the configuration table, each entry describes kind of block and
+ * amount requested. After initialization all blocks is placed into
+ * free elements lists.
+ *
+ * PARAMETERS:
+ * conf_table - pointer to the buffers configuration table
+ * size - number of entries in configuration table
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ */
+rtems_status_code
+rtems_bdbuf_init(rtems_bdbuf_config *conf_table, int size)
+{
+ rtems_bdpool_id i;
+ rtems_status_code rc;
+
+ if (size <= 0)
+ return RTEMS_INVALID_SIZE;
+
+ bd_ctx.npools = size;
+
+ /*
+ * Allocate memory for buffer pool descriptors
+ */
+ bd_ctx.pool = calloc(size, sizeof(bdbuf_pool));
+ if (bd_ctx.pool == NULL)
+ {
+ return RTEMS_NO_MEMORY;
+ }
+
+ Chain_Initialize_empty(&bd_ctx.mod);
+
+ /* Initialize buffer pools and roll out if something failed */
+ for (i = 0; i < size; i++)
+ {
+ rc = bdbuf_initialize_pool(conf_table + i, i);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ rtems_bdpool_id j;
+ for (j = 0; j < i - 1; j++)
+ {
+ bdbuf_release_pool(j);
+ }
+ return rc;
+ }
+ }
+
+ /* Create buffer flush semaphore */
+ rc = rtems_semaphore_create(
+ rtems_build_name('B', 'F', 'L', 'U'), 0,
+ RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY |
+ RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, 0,
+ &bd_ctx.flush_sema);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ for (i = 0; i < size; i++)
+ bdbuf_release_pool(i);
+ free(bd_ctx.pool);
+ return rc;
+ }
+
+ /* Create and start swapout task */
+ rc = rtems_task_create(
+ rtems_build_name('B', 'S', 'W', 'P'),
+ ((swapout_task_priority > 0)
+ ? swapout_task_priority
+ : SWAPOUT_TASK_DEFAULT_PRIORITY),
+ SWAPOUT_TASK_STACK_SIZE,
+ RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &bd_ctx.swapout_task);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ rtems_semaphore_delete(bd_ctx.flush_sema);
+ for (i = 0; i < size; i++)
+ bdbuf_release_pool(i);
+ free(bd_ctx.pool);
+ return rc;
+ }
+
+ rc = rtems_task_start(bd_ctx.swapout_task, bdbuf_swapout_task, 0);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ rtems_task_delete(bd_ctx.swapout_task);
+ rtems_semaphore_delete(bd_ctx.flush_sema);
+ for (i = 0; i < size; i++)
+ bdbuf_release_pool(i);
+ free(bd_ctx.pool);
+ return rc;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* find_or_assign_buffer --
+ * Looks for buffer already assigned for this dev/block. If one is found
+ * obtain block buffer. If specified block already cached (i.e. there's
+ * block in the _modified_, or _recently_used_), return address
+ * of appropriate buffer descriptor and increment reference counter to 1.
+ * If block is not cached, allocate new buffer and return it. Data
+ * shouldn't be read to the buffer from media; buffer contains arbitrary
+ * data. This primitive may be blocked if there are no free buffer
+ * descriptors available and there are no unused non-modified (or
+ * synchronized with media) buffers available.
+ *
+ * PARAMETERS:
+ * device - device number (constructed of major and minor device number
+ * block - linear media block number
+ * ret_buf - address of the variable to store address of found descriptor
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ *
+ * SIDE EFFEECTS:
+ * bufget_sema may be obtained by this primitive
+ *
+ * NOTE:
+ * It is assumed that primitive invoked when thread preemption is disabled.
+ */
+static rtems_status_code
+find_or_assign_buffer(disk_device *dd,
+ blkdev_bnum block,
+ bdbuf_buffer **ret_buf)
+{
+ bdbuf_buffer *bd_buf;
+ bdbuf_pool *bd_pool;
+ rtems_status_code rc;
+ dev_t device;
+ ISR_Level level;
+
+ int blksize;
+
+ device = dd->dev;
+ bd_pool = bd_ctx.pool + dd->pool;
+ blksize = dd->block_size;
+
+again:
+ /* Looking for buffer descriptor used for this dev/block. */
+ bd_buf = avl_search(&bd_pool->tree, device, block);
+
+ if (bd_buf == NULL)
+ {
+ /* Try to obtain semaphore without waiting first. It is the most
+ frequent case when reasonable number of buffers configured. If
+ it is failed, obtain semaphore blocking on it. In this case
+ it should be checked that appropriate buffer hasn't been loaded
+ by another thread, because this thread is preempted */
+ rc = rtems_semaphore_obtain(bd_pool->bufget_sema, RTEMS_NO_WAIT, 0);
+ if (rc == RTEMS_UNSATISFIED)
+ {
+ rc = rtems_semaphore_obtain(bd_pool->bufget_sema,
+ RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ bd_buf = avl_search(&bd_pool->tree, device, block);
+ if (bd_buf != NULL)
+ rtems_semaphore_release(bd_pool->bufget_sema);
+ }
+ }
+
+ if (bd_buf == NULL)
+ {
+ /* Assign new buffer descriptor */
+ if (_Chain_Is_empty(&bd_pool->free))
+ {
+ bd_buf = (bdbuf_buffer *)Chain_Get(&bd_pool->lru);
+ if (bd_buf != NULL)
+ {
+ int avl_result;
+ avl_result = avl_remove(&bd_pool->tree, bd_buf);
+ if (avl_result != 0)
+ {
+ rtems_fatal_error_occurred(BLKDEV_FATAL_BDBUF_CONSISTENCY);
+ return RTEMS_INTERNAL_ERROR;
+ }
+ }
+ }
+ else
+ {
+ bd_buf = (bdbuf_buffer *)Chain_Get(&(bd_pool->free));
+ }
+
+ if (bd_buf == NULL)
+ {
+ goto again;
+ }
+ else
+ {
+ bd_buf->dev = device;
+ bd_buf->block = block;
+#ifdef AVL_GPL
+ bd_buf->avl.link[0] = NULL;
+ bd_buf->avl.link[1] = NULL;
+#else
+ bd_buf->avl.left = NULL;
+ bd_buf->avl.right = NULL;
+#endif
+ bd_buf->use_count = 1;
+ bd_buf->modified = bd_buf->actual = bd_buf->in_progress = FALSE;
+ bd_buf->status = RTEMS_SUCCESSFUL;
+
+ if (avl_insert(&bd_pool->tree, bd_buf) != 0)
+ {
+ rtems_fatal_error_occurred(BLKDEV_FATAL_BDBUF_CONSISTENCY);
+ return RTEMS_INTERNAL_ERROR;
+ }
+
+ *ret_buf = bd_buf;
+
+ return RTEMS_SUCCESSFUL;
+ }
+ }
+ else
+ {
+ /* Buffer descriptor already assigned for this dev/block */
+ if (bd_buf->use_count == 0)
+ {
+ /* If we are removing from lru list, obtain the bufget_sema
+ * first. If we are removing from mod list, obtain flush sema.
+ * It should be obtained without blocking because we know
+ * that our buffer descriptor is in the list. */
+ if (bd_buf->modified)
+ {
+ rc = rtems_semaphore_obtain(bd_ctx.flush_sema,
+ RTEMS_NO_WAIT, 0);
+ }
+ else
+ {
+ rc = rtems_semaphore_obtain(bd_pool->bufget_sema,
+ RTEMS_NO_WAIT, 0);
+ }
+ /* It is possible that we couldn't obtain flush or bufget sema
+ * although buffer in the appropriate chain is available:
+ * semaphore may be released to swapout task, but this task
+ * actually did not start to process it. */
+ if (rc == RTEMS_UNSATISFIED)
+ rc = RTEMS_SUCCESSFUL;
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ rtems_fatal_error_occurred(BLKDEV_FATAL_BDBUF_CONSISTENCY);
+ return RTEMS_INTERNAL_ERROR;
+ }
+
+ /* Buffer descriptor is linked to the lru or mod chain. Remove
+ it from there. */
+ Chain_Extract(&bd_buf->link);
+ }
+ bd_buf->use_count++;
+ while (bd_buf->in_progress != 0)
+ {
+ rtems_interrupt_disable(level);
+ _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE,
+ WATCHDOG_NO_TIMEOUT, level);
+ }
+
+ *ret_buf = bd_buf;
+ return RTEMS_SUCCESSFUL;
+ }
+}
+
+/* rtems_bdbuf_get --
+ * Obtain block buffer. If specified block already cached (i.e. there's
+ * block in the _modified_, or _recently_used_), return address
+ * of appropriate buffer descriptor and increment reference counter to 1.
+ * If block is not cached, allocate new buffer and return it. Data
+ * shouldn't be read to the buffer from media; buffer may contains
+ * arbitrary data. This primitive may be blocked if there are no free
+ * buffer descriptors available and there are no unused non-modified
+ * (or synchronized with media) buffers available.
+ *
+ * PARAMETERS:
+ * device - device number (constructed of major and minor device number)
+ * block - linear media block number
+ * bd - address of variable to store pointer to the buffer descriptor
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ *
+ * SIDE EFFECTS:
+ * bufget_sema semaphore obtained by this primitive.
+ */
+rtems_status_code
+rtems_bdbuf_get(dev_t device, blkdev_bnum block, bdbuf_buffer **bd)
+{
+ rtems_status_code rc;
+ disk_device *dd;
+ disk_device *pdd;
+ preemption_key key;
+
+ /*
+ * Convert logical dev/block to physical one
+ */
+ dd = rtems_disk_lookup(device);
+ if (dd == NULL)
+ return RTEMS_INVALID_ID;
+
+ if (block >= dd->size)
+ {
+ rtems_disk_release(dd);
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ pdd = dd->phys_dev;
+ block += dd->start;
+ rtems_disk_release(dd);
+
+ DISABLE_PREEMPTION(key);
+ rc = find_or_assign_buffer(pdd, block, bd);
+ ENABLE_PREEMPTION(key);
+
+ if (rc != RTEMS_SUCCESSFUL)
+ return rc;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* bdbuf_initialize_transfer_sema --
+ * Initialize transfer_sema mutex semaphore associated with buffer
+ * descriptor.
+ */
+static inline void
+bdbuf_initialize_transfer_sema(bdbuf_buffer *bd_buf)
+{
+ CORE_mutex_Attributes mutex_attr;
+ mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_BLOCKS;
+ mutex_attr.only_owner_release = FALSE;
+ mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
+ mutex_attr.priority_ceiling = 0;
+
+ _CORE_mutex_Initialize(&bd_buf->transfer_sema,
+ &mutex_attr, CORE_MUTEX_LOCKED);
+}
+
+/* bdbuf_write_transfer_done --
+ * Callout function. Invoked by block device driver when data transfer
+ * to device (write) is completed. This function may be invoked from
+ * interrupt handler.
+ *
+ * PARAMETERS:
+ * arg - arbitrary argument specified in block device request
+ * structure (in this case - pointer to the appropriate
+ * bdbuf_buffer buffer descriptor structure).
+ * status - I/O completion status
+ * error - errno error code if status != RTEMS_SUCCESSFUL
+ *
+ * RETURNS:
+ * none
+ */
+static void
+bdbuf_write_transfer_done(void *arg, rtems_status_code status, int error)
+{
+ int i;
+ write_tfer_done_arg_t *wtd_arg = arg;
+ blkdev_request *req = wtd_arg->req;
+ bdbuf_buffer **bd_buf_write_store = wtd_arg->write_store;
+ bdbuf_buffer *bd_buf;
+ for (i = 0;i < req->count;i++) {
+ bd_buf = bd_buf_write_store[i];
+ bd_buf->status = status;
+ bd_buf->error = RTEMS_IO_ERROR;
+
+ bd_buf->in_progress = FALSE;
+ _CORE_mutex_Surrender(&bd_buf->transfer_sema, 0, NULL);
+ _CORE_mutex_Flush(&bd_buf->transfer_sema, NULL,
+ CORE_MUTEX_STATUS_SUCCESSFUL);
+ }
+}
+
+/* bdbuf_read_transfer_done --
+ * Callout function. Invoked by block device driver when data transfer
+ * from device (read) is completed. This function may be invoked from
+ * interrupt handler.
+ *
+ * PARAMETERS:
+ * arg - arbitrary argument specified in block device request
+ * structure (in this case - pointer to the appropriate
+ * bdbuf_buffer buffer descriptor structure).
+ * status - I/O completion status
+ * error - errno error code if status != RTEMS_SUCCESSFUL
+ *
+ * RETURNS:
+ * none
+ */
+static void
+bdbuf_read_transfer_done(void *arg, rtems_status_code status, int error)
+{
+#if defined(READ_MULTIPLE)
+
+ read_ahead_bd_buf_group *bd_buf_group = arg;
+ bdbuf_buffer *bd_buf;
+ int i;
+ for (i = 0;i < bd_buf_group->cnt;i++) {
+ bd_buf = bd_buf_group->bd_bufs[i];
+
+ bd_buf->status = status;
+ bd_buf->error = RTEMS_IO_ERROR;
+ _CORE_mutex_Surrender(&bd_buf->transfer_sema, 0, NULL);
+ _CORE_mutex_Flush(&bd_buf->transfer_sema, NULL,
+ CORE_MUTEX_STATUS_SUCCESSFUL);
+ }
+#else
+ bdbuf_buffer *bd_buf = arg;
+ bd_buf->status = status;
+ bd_buf->error = RTEMS_IO_ERROR;
+ _CORE_mutex_Surrender(&bd_buf->transfer_sema, 0, NULL);
+ _CORE_mutex_Flush(&bd_buf->transfer_sema, NULL,
+ CORE_MUTEX_STATUS_SUCCESSFUL);
+#endif
+}
+
+/* rtems_bdbuf_read --
+ * (Similar to the rtems_bdbuf_get, except reading data from media)
+ * Obtain block buffer. If specified block already cached, return address
+ * of appropriate buffer and increment reference counter to 1. If block is
+ * not cached, allocate new buffer and read data to it from the media.
+ * This primitive may be blocked on waiting until data to be read from
+ * media, if there are no free buffer descriptors available and there are
+ * no unused non-modified (or synchronized with media) buffers available.
+ *
+ * PARAMETERS:
+ * device - device number (consists of major and minor device number)
+ * block - linear media block number
+ * bd - address of variable to store pointer to the buffer descriptor
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ *
+ * SIDE EFFECTS:
+ * bufget_sema and transfer_sema semaphores obtained by this primitive.
+ */
+#if !defined(READ_MULTIPLE)
+rtems_status_code
+rtems_bdbuf_read(dev_t device,
+ blkdev_bnum block,
+ bdbuf_buffer **bd)
+{
+ preemption_key key;
+ ISR_Level level;
+
+ bdbuf_buffer *bd_buf;
+ rtems_status_code rc;
+ int result;
+ disk_device *dd;
+ disk_device *pdd;
+ blkdev_request1 req;
+
+ dd = rtems_disk_lookup(device);
+ if (dd == NULL)
+ return RTEMS_INVALID_ID;
+
+ if (block >= dd->size)
+ {
+ rtems_disk_release(dd);
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ pdd = dd->phys_dev;
+ block += dd->start;
+
+ DISABLE_PREEMPTION(key);
+ rc = find_or_assign_buffer(pdd, block, &bd_buf);
+
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ ENABLE_PREEMPTION(key);
+ rtems_disk_release(dd);
+ return rc;
+ }
+
+ if (!bd_buf->actual)
+ {
+ bd_buf->in_progress = 1;
+
+ req.req.req = BLKDEV_REQ_READ;
+ req.req.req_done = bdbuf_read_transfer_done;
+ req.req.done_arg = bd_buf;
+ req.req.start = block;
+ req.req.count = 1;
+ req.req.bufnum = 1;
+ req.req.bufs[0].length = dd->block_size;
+ req.req.bufs[0].buffer = bd_buf->buffer;
+
+ bdbuf_initialize_transfer_sema(bd_buf);
+ result = dd->ioctl(pdd->dev, BLKIO_REQUEST, &req);
+ if (result == -1)
+ {
+ bd_buf->status = RTEMS_IO_ERROR;
+ bd_buf->error = errno;
+ bd_buf->actual = FALSE;
+ }
+ else
+ {
+ rtems_interrupt_disable(level);
+ _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE,
+ WATCHDOG_NO_TIMEOUT, level);
+ bd_buf->actual = TRUE;
+ }
+ bd_buf->in_progress = FALSE;
+ }
+ rtems_disk_release(dd);
+
+ ENABLE_PREEMPTION(key);
+
+ *bd = bd_buf;
+
+ return RTEMS_SUCCESSFUL;
+}
+#else /* READ_MULTIPLE */
+rtems_status_code
+rtems_bdbuf_read(dev_t device,
+ blkdev_bnum block,
+ bdbuf_buffer **bd)
+{
+ preemption_key key;
+ ISR_Level level;
+
+ bdbuf_buffer *bd_buf,*first_bd_buf;
+ rtems_status_code rc;
+ int result;
+ disk_device *dd;
+ disk_device *pdd;
+ blkdev_request_read_ahead req;
+ read_ahead_bd_buf_group bd_buf_group;
+ boolean find_more_buffers;
+ int i;
+
+ dd = rtems_disk_lookup(device);
+ if (dd == NULL)
+ return RTEMS_INVALID_ID;
+
+ if (block >= dd->size)
+ {
+ rtems_disk_release(dd);
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ pdd = dd->phys_dev;
+ block += dd->start;
+
+ DISABLE_PREEMPTION(key);
+ rc = find_or_assign_buffer(pdd, block, &first_bd_buf);
+
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ ENABLE_PREEMPTION(key);
+ rtems_disk_release(dd);
+ return rc;
+ }
+ if (!first_bd_buf->actual)
+ {
+
+ bd_buf_group.bd_bufs[0] = first_bd_buf;
+ bd_buf_group.cnt = 1;
+
+ first_bd_buf->in_progress = TRUE;
+
+ req.req.req = BLKDEV_REQ_READ;
+ req.req.req_done = bdbuf_read_transfer_done;
+ req.req.done_arg = &bd_buf_group;
+ req.req.start = block;
+ req.req.count = 1;
+ req.req.bufnum = 1;
+ req.req.bufs[0].length = dd->block_size;
+ req.req.bufs[0].buffer = first_bd_buf->buffer;
+
+ bdbuf_initialize_transfer_sema(first_bd_buf);
+ /*
+ * FIXME: check for following blocks to be:
+ * - still in range of partition size
+ * - not yet assigned
+ * - buffer available
+ * allocate for read call, if possible
+ */
+ find_more_buffers = TRUE;
+ while (find_more_buffers) {
+ block++;
+ /*
+ * still bd_buf_group entries free and
+ * still in range of this disk?
+ */
+ if ((bd_buf_group.cnt >= READ_AHEAD_MAX_BLK_CNT) ||
+ (block >= dd->size)) {
+ find_more_buffers = FALSE;
+ }
+ if (find_more_buffers) {
+ rc = find_or_assign_buffer(pdd, block, &bd_buf);
+ if (rc != RTEMS_SUCCESSFUL) {
+ find_more_buffers = FALSE;
+ }
+ else if (bd_buf->actual) {
+ find_more_buffers = FALSE;
+ bdbuf_release(bd_buf);
+ }
+ }
+ if (find_more_buffers) {
+ bdbuf_initialize_transfer_sema(bd_buf);
+ bd_buf->in_progress = TRUE;
+
+ req.req.bufs[req.req.count].length = dd->block_size;
+ req.req.bufs[req.req.count].buffer = bd_buf->buffer;
+ req.req.count++;
+ req.req.bufnum++;
+ bd_buf_group.bd_bufs[bd_buf_group.cnt] = bd_buf;
+ bd_buf_group.cnt++;
+ }
+ }
+
+ /* do the actual read call here
+ */
+ result = dd->ioctl(pdd->dev, BLKIO_REQUEST, &req);
+
+ /*
+ * cleanup:
+ * wait, until all bd_bufs are processed
+ * set status in all bd_bufs
+ */
+ for (i = 0;i < bd_buf_group.cnt;i++) {
+ bd_buf = bd_buf_group.bd_bufs[i];
+ if (result == -1)
+ {
+ bd_buf->status = RTEMS_IO_ERROR;
+ bd_buf->error = errno;
+ bd_buf->actual = FALSE;
+ }
+ else
+ {
+ rtems_interrupt_disable(level);
+ _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE,
+ WATCHDOG_NO_TIMEOUT, level);
+ bd_buf->actual = TRUE;
+ }
+ bd_buf->in_progress = FALSE;
+ /* release any pre-read buffers */
+ if (i > 0) {
+ bdbuf_release(bd_buf);
+ }
+ }
+ }
+ rtems_disk_release(dd);
+
+ ENABLE_PREEMPTION(key);
+
+ *bd = first_bd_buf;
+
+ return RTEMS_SUCCESSFUL;
+}
+#endif /* READ_MULTIPLE */
+
+
+/* bdbuf_release --
+ * Release buffer. Decrease buffer usage counter. If it is zero, further
+ * processing depends on modified attribute. If buffer was modified, it
+ * is inserted into mod chain and swapout task waken up. If buffer was
+ * not modified, it is returned to the end of lru chain making it available
+ * for further use.
+ *
+ * PARAMETERS:
+ * bd_buf - pointer to the released buffer descriptor.
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if buffer released successfully, or error code if
+ * error occured.
+ *
+ * NOTE:
+ * This is internal function. It is assumed that task made non-preemptive
+ * before its invocation.
+ */
+static rtems_status_code
+bdbuf_release(bdbuf_buffer *bd_buf)
+{
+ bdbuf_pool *bd_pool;
+ rtems_status_code rc = RTEMS_SUCCESSFUL;
+
+ if (bd_buf->use_count <= 0)
+ return RTEMS_INTERNAL_ERROR;
+
+ bd_pool = bd_ctx.pool + bd_buf->pool;
+
+ bd_buf->use_count--;
+
+ if (bd_buf->use_count == 0)
+ {
+ if (bd_buf->modified)
+ {
+
+ /* Buffer was modified. Insert buffer to the modified buffers
+ * list and initiate flushing. */
+ Chain_Append(&bd_ctx.mod, &bd_buf->link);
+
+ /* Release the flush_sema */
+ rc = rtems_semaphore_release(bd_ctx.flush_sema);
+ }
+ else
+ {
+ /* Buffer was not modified. Add this descriptor to the
+ * end of lru chain and make it available for reuse. */
+ Chain_Append(&bd_pool->lru, &bd_buf->link);
+ rc = rtems_semaphore_release(bd_pool->bufget_sema);
+ }
+ }
+ return rc;
+}
+
+
+/* rtems_bdbuf_release --
+ * Release buffer allocated before. This primitive decrease the
+ * usage counter. If it is zero, further destiny of buffer depends on
+ * 'modified' status. If buffer was modified, it is placed to the end of
+ * mod list and flush task waken up. If buffer was not modified,
+ * it is placed to the end of lru list, and bufget_sema released, allowing
+ * to reuse this buffer.
+ *
+ * PARAMETERS:
+ * bd_buf - pointer to the bdbuf_buffer structure previously obtained using
+ * get/read primitive.
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ *
+ * SIDE EFFECTS:
+ * flush_sema and bufget_sema semaphores may be released by this primitive.
+ */
+rtems_status_code
+rtems_bdbuf_release(bdbuf_buffer *bd_buf)
+{
+ preemption_key key;
+ rtems_status_code rc = RTEMS_SUCCESSFUL;
+
+ if (bd_buf == NULL)
+ return RTEMS_INVALID_ADDRESS;
+
+ DISABLE_PREEMPTION(key);
+
+ rc = bdbuf_release(bd_buf);
+
+ ENABLE_PREEMPTION(key);
+
+ return rc;
+}
+
+/* rtems_bdbuf_release_modified --
+ * Release buffer allocated before, assuming that it is _modified_ by
+ * it's owner. This primitive decrease usage counter for buffer, mark
+ * buffer descriptor as modified. If usage counter is 0, insert it at
+ * end of mod chain and release flush_sema semaphore to activate the
+ * flush task.
+ *
+ * PARAMETERS:
+ * bd_buf - pointer to the bdbuf_buffer structure previously obtained using
+ * get/read primitive.
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ *
+ * SIDE EFFECTS:
+ * flush_sema semaphore may be released by this primitive.
+ */
+rtems_status_code
+rtems_bdbuf_release_modified(bdbuf_buffer *bd_buf)
+{
+ preemption_key key;
+ rtems_status_code rc = RTEMS_SUCCESSFUL;
+
+ if (bd_buf == NULL)
+ return RTEMS_INVALID_ADDRESS;
+
+ DISABLE_PREEMPTION(key);
+
+ if (!bd_buf->modified)
+ {
+ bdbuf_initialize_transfer_sema(bd_buf);
+ }
+ bd_buf->modified = TRUE;
+ bd_buf->actual = TRUE;
+ rc = bdbuf_release(bd_buf);
+
+ ENABLE_PREEMPTION(key);
+
+ return rc;
+}
+
+/* rtems_bdbuf_sync --
+ * Wait until specified buffer synchronized with disk. Invoked on exchanges
+ * critical for data consistency on the media. This primitive mark owned
+ * block as modified, decrease usage counter. If usage counter is 0,
+ * block inserted to the mod chain and flush_sema semaphore released.
+ * Finally, primitives blocked on transfer_sema semaphore.
+ *
+ * PARAMETERS:
+ * bd_buf - pointer to the bdbuf_buffer structure previously obtained using
+ * get/read primitive.
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ *
+ * SIDE EFFECTS:
+ * Primitive may be blocked on transfer_sema semaphore.
+ */
+rtems_status_code
+rtems_bdbuf_sync(bdbuf_buffer *bd_buf)
+{
+ preemption_key key;
+ ISR_Level level;
+ rtems_status_code rc = RTEMS_SUCCESSFUL;
+
+ if (bd_buf == NULL)
+ return RTEMS_INVALID_ADDRESS;
+
+ DISABLE_PREEMPTION(key);
+
+ if (!bd_buf->modified)
+ {
+ bdbuf_initialize_transfer_sema(bd_buf);
+ }
+ bd_buf->modified = TRUE;
+ bd_buf->actual = TRUE;
+
+ rc = bdbuf_release(bd_buf);
+
+ if (rc == RTEMS_SUCCESSFUL)
+ {
+ rtems_interrupt_disable(level);
+ _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE,
+ WATCHDOG_NO_TIMEOUT, level);
+ }
+
+ ENABLE_PREEMPTION(key);
+
+ return rc;
+}
+
+/* rtems_bdbuf_syncdev --
+ * Synchronize with disk all buffers containing the blocks belonging to
+ * specified device.
+ *
+ * PARAMETERS:
+ * dev - block device number
+ *
+ * RETURNS:
+ * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
+ * or error code if error is occured)
+ */
+rtems_status_code
+rtems_bdbuf_syncdev(dev_t dev)
+{
+ preemption_key key;
+ ISR_Level level;
+
+ bdbuf_buffer *bd_buf;
+ disk_device *dd;
+ bdbuf_pool *pool;
+
+ dd = rtems_disk_lookup(dev);
+ if (dd == NULL)
+ return RTEMS_INVALID_ID;
+
+ pool = bd_ctx.pool + dd->pool;
+
+ DISABLE_PREEMPTION(key);
+ do {
+ bd_buf = avl_search_for_sync(&pool->tree, dd);
+ if (bd_buf != NULL /* && bd_buf->modified */)
+ {
+ rtems_interrupt_disable(level);
+ _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE,
+ WATCHDOG_NO_TIMEOUT, level);
+ }
+ } while (bd_buf != NULL);
+ ENABLE_PREEMPTION(key);
+ return rtems_disk_release(dd);
+}
+
+/* bdbuf_swapout_task --
+ * Body of task which take care on flushing modified buffers to the
+ * disk.
+ */
+static rtems_task
+bdbuf_swapout_task(rtems_task_argument unused)
+{
+ rtems_status_code rc;
+ int result;
+ int i;
+ ISR_Level level;
+ bdbuf_buffer *bd_buf;
+ bdbuf_buffer *nxt_bd_buf;
+ bdbuf_pool *bd_pool = NULL;
+ disk_device *dd = NULL;
+ struct {
+ blkdev_request req;
+ blkdev_sg_buffer sg[SWAP_OUT_MAX_BLK_CNT];
+ } req;
+ write_tfer_done_arg_t write_tfer_done_arg;
+
+ /*
+ * provide info needed for write_transfer_done function
+ */
+ write_tfer_done_arg.req = (blkdev_request *)&req.req;
+ write_tfer_done_arg.write_store = bd_buf_write_store;
+ nxt_bd_buf = NULL;
+ while (1)
+ {
+ req.req.req = BLKDEV_REQ_WRITE;
+ req.req.req_done = bdbuf_write_transfer_done;
+ req.req.done_arg = &write_tfer_done_arg;
+ req.req.count = 0;
+ req.req.bufnum = 0;
+ bd_buf = NULL;
+ do {
+ /*
+ * if a buffer was left over from last loop, then use this buffer
+ * otherwise fetch new buffer from chain.
+ * Wait for buffer, if this is the first one of the request,
+ * otherwise do not wait, if no buffer available
+ */
+ if (nxt_bd_buf == NULL) {
+ rc = rtems_semaphore_obtain(bd_ctx.flush_sema,
+ (req.req.count == 0)
+ ? RTEMS_WAIT
+ : RTEMS_NO_WAIT,
+ 0);
+ if (rc == RTEMS_SUCCESSFUL) {
+ nxt_bd_buf = (bdbuf_buffer *)Chain_Get(&bd_ctx.mod);
+ if (nxt_bd_buf != NULL) {
+ nxt_bd_buf->in_progress = TRUE;
+ /* IMD try: clear "modified" bit early */
+ /* (and not in bdbuf_write_transfer_done) to allow */
+ /* another modification during write processing */
+ nxt_bd_buf->modified = FALSE;
+
+ nxt_bd_buf->use_count++;
+ }
+ }
+ else if ((rc != RTEMS_UNSATISFIED) &&
+ (rc != RTEMS_TIMEOUT)) {
+ rtems_fatal_error_occurred(BLKDEV_FATAL_BDBUF_SWAPOUT);
+ }
+ }
+ /*
+ * It is possible that flush_sema semaphore will be released, but
+ * buffer to be removed from mod chain before swapout task start
+ * its processing.
+ */
+ if ((req.req.count == 0) || /* first bd_buf for this request */
+ ((nxt_bd_buf != NULL) &&
+ (nxt_bd_buf->dev == bd_buf->dev) && /* same device */
+ (nxt_bd_buf->block == bd_buf->block+1))) {/* next block */
+ bd_buf = nxt_bd_buf;
+ nxt_bd_buf = NULL;
+ }
+ else {
+ bd_buf = NULL;
+ }
+ /*
+ * here we have three possible states:
+ * bd_buf == NULL, nxt_bd_buf == NULL: no further block available
+ * bd_buf != NULL, nxt_bd_buf == NULL: append bd_buf to request
+ * bd_buf == NULL, nxt_bd_buf != NULL: nxt_bd_buf canot be appended
+ * to current request, keep it
+ * for next main loop
+ */
+ if (bd_buf != NULL) {
+ bd_pool = bd_ctx.pool + bd_buf->pool;
+ if (req.req.count == 0) {
+ /*
+ * this is the first block, so use its address
+ */
+ dd = rtems_disk_lookup(bd_buf->dev);
+ req.req.start = bd_buf->block + dd->start;
+ }
+ req.req.bufs[req.req.bufnum].length = dd->block_size;
+ req.req.bufs[req.req.bufnum].buffer = bd_buf->buffer;
+ /*
+ * keep bd_buf for postprocessing
+ */
+ bd_buf_write_store[req.req.bufnum] = bd_buf;
+ req.req.count++;
+ req.req.bufnum++;
+ }
+ } while ((bd_buf != NULL) &&
+ (req.req.count < SWAP_OUT_MAX_BLK_CNT));
+
+ /* transfer_sema initialized when bd_buf inserted in the mod chain
+ first time */
+ result = dd->ioctl(dd->phys_dev->dev, BLKIO_REQUEST, &req);
+
+ rtems_disk_release(dd);
+
+ for (i = 0;i < req.req.count;i++) {
+ bd_buf = bd_buf_write_store[i];
+ if (result == -1)
+ {
+
+ bd_buf->status = RTEMS_IO_ERROR;
+ bd_buf->error = errno;
+ /* Release tasks waiting on syncing this buffer */
+ _CORE_mutex_Flush(&bd_buf->transfer_sema, NULL,
+ CORE_MUTEX_STATUS_SUCCESSFUL);
+ }
+ else
+ {
+ if (bd_buf->in_progress)
+ {
+ rtems_interrupt_disable(level);
+ _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE, 0, level);
+ }
+ }
+ bd_buf->use_count--;
+
+ /* Another task have chance to use this buffer, or even
+ * modify it. If buffer is not in use, insert it in appropriate chain
+ * and release semaphore */
+ if (bd_buf->use_count == 0)
+ {
+ if (bd_buf->modified)
+ {
+ Chain_Append(&bd_ctx.mod, &bd_buf->link);
+ rc = rtems_semaphore_release(bd_ctx.flush_sema);
+ }
+ else
+ {
+ Chain_Append(&bd_pool->lru, &bd_buf->link);
+ rc = rtems_semaphore_release(bd_pool->bufget_sema);
+ }
+ }
+ }
+ }
+}
+
+/* rtems_bdbuf_find_pool --
+ * Find first appropriate buffer pool. This primitive returns the index
+ * of first buffer pool which block size is greater than or equal to
+ * specified size.
+ *
+ * PARAMETERS:
+ * block_size - requested block size
+ * pool - placeholder for result
+ *
+ * RETURNS:
+ * RTEMS status code: RTEMS_SUCCESSFUL if operation completed successfully,
+ * RTEMS_INVALID_SIZE if specified block size is invalid (not a power
+ * of 2), RTEMS_NOT_DEFINED if buffer pool for this or greater block size
+ * is not configured.
+ */
+rtems_status_code
+rtems_bdbuf_find_pool(int block_size, rtems_bdpool_id *pool)
+{
+ rtems_bdpool_id i;
+ bdbuf_pool *p;
+ int cursize = INT_MAX;
+ rtems_bdpool_id curid = -1;
+ rtems_boolean found = FALSE;
+ int j;
+
+ for (j = block_size; (j != 0) && ((j & 1) == 0); j >>= 1);
+ if (j != 1)
+ return RTEMS_INVALID_SIZE;
+
+ for (i = 0, p = bd_ctx.pool; i < bd_ctx.npools; i++, p++)
+ {
+ if ((p->blksize >= block_size) &&
+ (p->blksize < cursize))
+ {
+ curid = i;
+ cursize = p->blksize;
+ found = TRUE;
+ }
+ }
+
+ if (found)
+ {
+ if (pool != NULL)
+ *pool = curid;
+ return RTEMS_SUCCESSFUL;
+ }
+ else
+ {
+ return RTEMS_NOT_DEFINED;
+ }
+}
+
+/* rtems_bdbuf_get_pool_info --
+ * Obtain characteristics of buffer pool with specified number.
+ *
+ * PARAMETERS:
+ * pool - buffer pool number
+ * block_size - block size for which buffer pool is configured returned
+ * there
+ * blocks - number of buffers in buffer pool returned there
+ *
+ * RETURNS:
+ * RTEMS status code: RTEMS_SUCCESSFUL if operation completed successfully,
+ * RTEMS_INVALID_NUMBER if appropriate buffer pool is not configured.
+ *
+ * NOTE:
+ * Buffer pools enumerated contiguously starting from 0.
+ */
+rtems_status_code
+rtems_bdbuf_get_pool_info(rtems_bdpool_id pool, int *block_size,
+ int *blocks)
+{
+ if (pool >= bd_ctx.npools)
+ return RTEMS_INVALID_NUMBER;
+
+ if (block_size != NULL)
+ {
+ *block_size = bd_ctx.pool[pool].blksize;
+ }
+
+ if (blocks != NULL)
+ {
+ *blocks = bd_ctx.pool[pool].nblks;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/libblock/src/blkdev.c b/cpukit/libblock/src/blkdev.c
new file mode 100644
index 0000000000..e133e5eaf2
--- /dev/null
+++ b/cpukit/libblock/src/blkdev.c
@@ -0,0 +1,249 @@
+/*
+ * blkdev.h - block device driver generic support
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <sys/ioctl.h>
+
+#include "rtems/diskdevs.h"
+#include "rtems/bdbuf.h"
+
+/* rtems_blkdev_generic_read --
+ * Generic block device read primitive. Implemented using block device
+ * buffer management primitives.
+ */
+rtems_device_driver
+rtems_blkdev_generic_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_rw_args_t *args = arg;
+ int block_size_log2;
+ int block_size;
+ char *buf;
+ unsigned int count;
+ unsigned int block;
+ unsigned int blkofs;
+ dev_t dev;
+ disk_device *dd;
+
+ dev = rtems_filesystem_make_dev_t(major, minor);
+ dd = rtems_disk_lookup(dev);
+ if (dd == NULL)
+ return RTEMS_INVALID_NUMBER;
+
+ block_size_log2 = dd->block_size_log2;
+ block_size = dd->block_size;
+
+ buf = args->buffer;
+ count = args->count;
+ args->bytes_moved = 0;
+
+ block = args->offset >> block_size_log2;
+ blkofs = args->offset & (block_size - 1);
+
+ while (count > 0)
+ {
+ bdbuf_buffer *diskbuf;
+ int copy;
+ rtems_status_code rc;
+
+ rc = rtems_bdbuf_read(dev, block, &diskbuf);
+ if (rc != RTEMS_SUCCESSFUL)
+ return rc;
+ copy = block_size - blkofs;
+ if (copy > count)
+ copy = count;
+ memcpy(buf, (char *)diskbuf->buffer + blkofs, copy);
+ rc = rtems_bdbuf_release(diskbuf);
+ args->bytes_moved += copy;
+ if (rc != RTEMS_SUCCESSFUL)
+ return rc;
+ count -= copy;
+ buf += copy;
+ blkofs = 0;
+ block++;
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+/* rtems_blkdev_generic_write --
+ * Generic block device write primitive. Implemented using block device
+ * buffer management primitives.
+ */
+rtems_device_driver
+rtems_blkdev_generic_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_rw_args_t *args = arg;
+ int block_size_log2;
+ int block_size;
+ char *buf;
+ unsigned int count;
+ unsigned int block;
+ unsigned int blkofs;
+ dev_t dev;
+ rtems_status_code rc;
+ disk_device *dd;
+
+ dev = rtems_filesystem_make_dev_t(major, minor);
+ dd = rtems_disk_lookup(dev);
+ if (dd == NULL)
+ return RTEMS_INVALID_NUMBER;
+
+ block_size_log2 = dd->block_size_log2;
+ block_size = dd->block_size;
+
+ buf = args->buffer;
+ count = args->count;
+ args->bytes_moved = 0;
+
+ block = args->offset >> block_size_log2;
+ blkofs = args->offset & (block_size - 1);
+
+ while (count > 0)
+ {
+ bdbuf_buffer *diskbuf;
+ int copy;
+
+ if ((blkofs == 0) && (count >= block_size))
+ rc = rtems_bdbuf_get(dev, block, &diskbuf);
+ else
+ rc = rtems_bdbuf_read(dev, block, &diskbuf);
+ if (rc != RTEMS_SUCCESSFUL)
+ return rc;
+
+ copy = block_size - blkofs;
+ if (copy > count)
+ copy = count;
+ memcpy((char *)diskbuf->buffer + blkofs, buf, copy);
+ args->bytes_moved += copy;
+
+ rc = rtems_bdbuf_release_modified(diskbuf);
+ if (rc != RTEMS_SUCCESSFUL)
+ return rc;
+
+ count -= copy;
+ buf += copy;
+ blkofs = 0;
+ block++;
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+/* blkdev_generic_open --
+ * Generic block device open primitive.
+ */
+rtems_device_driver
+rtems_blkdev_generic_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ dev_t dev;
+ disk_device *dd;
+
+ dev = rtems_filesystem_make_dev_t(major, minor);
+ dd = rtems_disk_lookup(dev);
+ if (dd == NULL)
+ return RTEMS_INVALID_NUMBER;
+
+ dd->uses++;
+
+ rtems_disk_release(dd);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/* blkdev_generic_close --
+ * Generic block device close primitive.
+ */
+rtems_device_driver
+rtems_blkdev_generic_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ dev_t dev;
+ disk_device *dd;
+
+ dev = rtems_filesystem_make_dev_t(major, minor);
+ dd = rtems_disk_lookup(dev);
+ if (dd == NULL)
+ return RTEMS_INVALID_NUMBER;
+
+ dd->uses--;
+
+ rtems_disk_release(dd);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* blkdev_generic_ioctl --
+ * Generic block device ioctl primitive.
+ */
+rtems_device_driver
+rtems_blkdev_generic_ioctl(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_ioctl_args_t *args = arg;
+ dev_t dev;
+ disk_device *dd;
+ int rc;
+
+ dev = rtems_filesystem_make_dev_t(major, minor);
+ dd = rtems_disk_lookup(dev);
+ if (dd == NULL)
+ return RTEMS_INVALID_NUMBER;
+
+ switch (args->command)
+ {
+ case BLKIO_GETBLKSIZE:
+ args->ioctl_return = dd->block_size;
+ break;
+
+ case BLKIO_GETSIZE:
+ args->ioctl_return = dd->size;
+ break;
+
+ case BLKIO_SYNCDEV:
+ rc = rtems_bdbuf_syncdev(dd->dev);
+ args->ioctl_return = (rc == RTEMS_SUCCESSFUL ? 0 : -1);
+ break;
+
+ case BLKIO_REQUEST:
+ {
+ blkdev_request *req = args->buffer;
+ req->start += dd->start;
+ args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command,
+ req);
+ break;
+ }
+
+ default:
+ args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command,
+ args->buffer);
+ break;
+ }
+ rtems_disk_release(dd);
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/libblock/src/diskdevs.c b/cpukit/libblock/src/diskdevs.c
new file mode 100644
index 0000000000..25b8287610
--- /dev/null
+++ b/cpukit/libblock/src/diskdevs.c
@@ -0,0 +1,635 @@
+/*
+ * diskdevs.c - Physical and logical block devices (disks) support
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <stdlib.h>
+#include <unistd.h> /* unlink */
+#include <string.h>
+
+#include "rtems/diskdevs.h"
+#include "rtems/bdbuf.h"
+
+#define DISKTAB_INITIAL_SIZE 32
+
+/* Table of disk devices having the same major number */
+struct disk_device_table {
+ disk_device **minor; /* minor-indexed disk device table */
+ int size; /* Number of entries in the table */
+};
+
+/* Pointer to [major].minor[minor] indexed array of disk devices */
+static struct disk_device_table *disktab;
+
+/* Number of allocated entries in disktab table */
+static int disktab_size;
+
+/* Mutual exclusion semaphore for disk devices table */
+static rtems_id diskdevs_mutex;
+
+/* Flag meaning that disk I/O, buffering etc. already has been initialized. */
+static boolean disk_io_initialized = FALSE;
+
+/* diskdevs data structures protection flag.
+ * Normally, only table lookup operations performed. It is quite fast, so
+ * it is possible to done lookups when interrupts are disabled, avoiding
+ * obtaining the semaphore. This flags sets immediately after entering in
+ * mutex-protected section and cleared before leaving this section in
+ * "big" primitives like add/delete new device etc. Lookup function first
+ * disable interrupts and check this flag. If it is set, lookup function
+ * will be blocked on semaphore and lookup operation will be performed in
+ * semaphore-protected code. If it is not set (very-very frequent case),
+ * we can do lookup safely, enable interrupts and return result.
+ */
+static volatile rtems_boolean diskdevs_protected;
+
+/* create_disk_entry --
+ * Return pointer to the disk_entry structure for the specified device, or
+ * create one if it is not exists.
+ *
+ * PARAMETERS:
+ * dev - device id (major, minor)
+ *
+ * RETURNS:
+ * pointer to the disk device descriptor entry, or NULL if no memory
+ * available for its creation.
+ */
+static disk_device *
+create_disk_entry(dev_t dev)
+{
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+ struct disk_device **d;
+
+ rtems_filesystem_split_dev_t (dev, major, minor);
+
+ if (major >= disktab_size)
+ {
+ struct disk_device_table *p;
+ int newsize;
+ int i;
+ newsize = disktab_size * 2;
+ if (major >= newsize)
+ newsize = major + 1;
+ p = realloc(disktab, sizeof(struct disk_device_table) * newsize);
+ if (p == NULL)
+ return NULL;
+ p += disktab_size;
+ for (i = disktab_size; i < newsize; i++, p++)
+ {
+ p->minor = NULL;
+ p->size = 0;
+ }
+ disktab_size = newsize;
+ }
+
+ if ((disktab[major].minor == NULL) ||
+ (minor >= disktab[major].size))
+ {
+ int newsize;
+ disk_device **p;
+ int i;
+ int s = disktab[major].size;
+
+ if (s == 0)
+ newsize = DISKTAB_INITIAL_SIZE;
+ else
+ newsize = s * 2;
+ if (minor >= newsize)
+ newsize = minor + 1;
+
+ p = realloc(disktab[major].minor, sizeof(disk_device *) * newsize);
+ if (p == NULL)
+ return NULL;
+ disktab[major].minor = p;
+ p += s;
+ for (i = s; i < newsize; i++, p++)
+ *p = NULL;
+ disktab[major].size = newsize;
+ }
+
+ d = disktab[major].minor + minor;
+ if (*d == NULL)
+ {
+ *d = calloc(1, sizeof(disk_device));
+ }
+ return *d;
+}
+
+/* get_disk_entry --
+ * Get disk device descriptor by device number.
+ *
+ * PARAMETERS:
+ * dev - block device number
+ *
+ * RETURNS:
+ * Pointer to the disk device descriptor corresponding to the specified
+ * device number, or NULL if disk device with such number not exists.
+ */
+static inline disk_device *
+get_disk_entry(dev_t dev)
+{
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+ struct disk_device_table *dtab;
+
+ rtems_filesystem_split_dev_t (dev, major, minor);
+
+ if ((major >= disktab_size) || (disktab == NULL))
+ return NULL;
+
+ dtab = disktab + major;
+
+ if ((minor >= dtab->size) || (dtab->minor == NULL))
+ return NULL;
+
+ return dtab->minor[minor];
+}
+
+/* create_disk --
+ * Check that disk entry for specified device number is not defined
+ * and create it.
+ *
+ * PARAMETERS:
+ * dev - device identifier (major, minor numbers)
+ * name - character name of device (e.g. /dev/hda)
+ * disdev - placeholder for pointer to created disk descriptor
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if disk entry successfully created, or
+ * error code if error occured (device already registered,
+ * no memory available).
+ */
+static rtems_status_code
+create_disk(dev_t dev, char *name, disk_device **diskdev)
+{
+ disk_device *dd;
+ char *n;
+
+ dd = get_disk_entry(dev);
+ if (dd != NULL)
+ {
+ return RTEMS_RESOURCE_IN_USE;
+ }
+
+ if (name == NULL)
+ {
+ n = NULL;
+ }
+ else
+ {
+ int nlen = strlen(name) + 1;
+ n = malloc(nlen);
+ if (n == NULL)
+ return RTEMS_NO_MEMORY;
+ strncpy(n, name, nlen);
+ }
+
+ dd = create_disk_entry(dev);
+ if (dd == NULL)
+ {
+ free(n);
+ return RTEMS_NO_MEMORY;
+ }
+
+ dd->dev = dev;
+ dd->name = n;
+
+ *diskdev = dd;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* rtems_disk_create_phys --
+ * Create physical disk entry. This function usually invoked from
+ * block device driver initialization code when physical device
+ * detected in the system. Device driver should provide ioctl handler
+ * to allow block device access operations. This primitive will register
+ * device in rtems (invoke rtems_io_register_name).
+ *
+ * PARAMETERS:
+ * dev - device identifier (major, minor numbers)
+ * block_size - size of disk block (minimum data transfer unit); must be
+ * power of 2
+ * disk_size - number of blocks on device
+ * handler - IOCTL handler (function providing basic block input/output
+ * request handling BIOREQUEST and other device management
+ * operations)
+ * name - character name of device (e.g. /dev/hda)
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if information about new physical disk added, or
+ * error code if error occured (device already registered, wrong block
+ * size value, no memory available).
+ */
+rtems_status_code
+rtems_disk_create_phys(dev_t dev, int block_size, int disk_size,
+ block_device_ioctl handler,
+ char *name)
+{
+ int bs_log2;
+ int i;
+ disk_device *dd;
+ rtems_status_code rc;
+ rtems_bdpool_id pool;
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+
+ rtems_filesystem_split_dev_t (dev, major, minor);
+
+
+ for (bs_log2 = 0, i = block_size; (i & 1) == 0; i >>= 1, bs_log2++);
+ if ((bs_log2 < 9) || (i != 1)) /* block size < 512 or not power of 2 */
+ return RTEMS_INVALID_NUMBER;
+
+ rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (rc != RTEMS_SUCCESSFUL)
+ return rc;
+ diskdevs_protected = TRUE;
+
+ rc = rtems_bdbuf_find_pool(block_size, &pool);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ diskdevs_protected = FALSE;
+ rtems_semaphore_release(diskdevs_mutex);
+ return rc;
+ }
+
+ rc = create_disk(dev, name, &dd);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ diskdevs_protected = FALSE;
+ rtems_semaphore_release(diskdevs_mutex);
+ return rc;
+ }
+
+ dd->phys_dev = dd;
+ dd->uses = 0;
+ dd->start = 0;
+ dd->size = disk_size;
+ dd->block_size = block_size;
+ dd->block_size_log2 = bs_log2;
+ dd->ioctl = handler;
+ dd->pool = pool;
+
+ rc = rtems_io_register_name(name, major, minor);
+
+ diskdevs_protected = FALSE;
+ rtems_semaphore_release(diskdevs_mutex);
+
+ return rc;
+}
+
+/* rtems_disk_create_log --
+ * Create logical disk entry. Logical disk is contiguous area on physical
+ * disk. Disk may be splitted to several logical disks in several ways:
+ * manually or using information stored in blocks on physical disk
+ * (DOS-like partition table, BSD disk label, etc). This function usually
+ * invoked from application when application-specific splitting are in use,
+ * or from generic code which handle different logical disk organizations.
+ * This primitive will register device in rtems (invoke
+ * rtems_io_register_name).
+ *
+ * PARAMETERS:
+ * dev - logical device identifier (major, minor numbers)
+ * phys - physical device (block device which holds this logical disk)
+ * identifier
+ * start - starting block number on the physical device
+ * size - logical disk size in blocks
+ * name - logical disk name
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if logical device successfully added, or error code
+ * if error occured (device already registered, no physical device
+ * exists, logical disk is out of physical disk boundaries, no memory
+ * available).
+ */
+rtems_status_code
+rtems_disk_create_log(dev_t dev, dev_t phys, int start, int size, char *name)
+{
+ disk_device *dd;
+ disk_device *pdd;
+ rtems_status_code rc;
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+
+ rtems_filesystem_split_dev_t (dev, major, minor);
+
+ rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (rc != RTEMS_SUCCESSFUL)
+ return rc;
+ diskdevs_protected = TRUE;
+
+ pdd = get_disk_entry(phys);
+ if (pdd == NULL)
+ {
+ diskdevs_protected = FALSE;
+ rtems_semaphore_release(diskdevs_mutex);
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ rc = create_disk(dev, name, &dd);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ diskdevs_protected = FALSE;
+ rtems_semaphore_release(diskdevs_mutex);
+ return rc;
+ }
+
+ dd->phys_dev = pdd;
+ dd->uses = 0;
+ dd->start = start;
+ dd->size = size;
+ dd->block_size = pdd->block_size;
+ dd->block_size_log2 = pdd->block_size_log2;
+ dd->ioctl = pdd->ioctl;
+
+ rc = rtems_io_register_name(name, major, minor);
+
+ diskdevs_protected = FALSE;
+ rc = rtems_semaphore_release(diskdevs_mutex);
+
+ return rc;
+}
+
+/* rtems_disk_delete --
+ * Delete physical or logical disk device. Device may be deleted if its
+ * use counter (and use counters of all logical devices - if it is
+ * physical device) equal to 0. When physical device deleted,
+ * all logical devices deleted inherently. Appropriate devices removed
+ * from "/dev" filesystem.
+ *
+ * PARAMETERS:
+ * dev - device identifier (major, minor numbers)
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if block device successfully deleted, or error code
+ * if error occured (device is not defined, device is in use).
+ */
+rtems_status_code
+rtems_disk_delete(dev_t dev)
+{
+ rtems_status_code rc;
+ int used;
+ rtems_device_major_number maj;
+ rtems_device_minor_number min;
+
+ rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (rc != RTEMS_SUCCESSFUL)
+ return rc;
+ diskdevs_protected = TRUE;
+
+ /* Check if this device is in use -- calculate usage counter */
+ used = 0;
+ for (maj = 0; maj < disktab_size; maj++)
+ {
+ struct disk_device_table *dtab = disktab + maj;
+ if (dtab != NULL)
+ {
+ for (min = 0; min < dtab->size; min++)
+ {
+ disk_device *dd = dtab->minor[min];
+ if ((dd != NULL) && (dd->phys_dev->dev == dev))
+ used += dd->uses;
+ }
+ }
+ }
+
+ if (used != 0)
+ {
+ diskdevs_protected = FALSE;
+ rtems_semaphore_release(diskdevs_mutex);
+ return RTEMS_RESOURCE_IN_USE;
+ }
+
+ /* Delete this device and all of its logical devices */
+ for (maj = 0; maj < disktab_size; maj++)
+ {
+ struct disk_device_table *dtab = disktab +maj;
+ if (dtab != NULL)
+ {
+ for (min = 0; min < dtab->size; min++)
+ {
+ disk_device *dd = dtab->minor[min];
+ if ((dd != NULL) && (dd->phys_dev->dev == dev))
+ {
+ unlink(dd->name);
+ free(dd->name);
+ free(dd);
+ dtab->minor[min] = NULL;
+ }
+ }
+ }
+ }
+
+ diskdevs_protected = FALSE;
+ rc = rtems_semaphore_release(diskdevs_mutex);
+ return rc;
+}
+
+/* rtems_disk_lookup --
+ * Find block device descriptor by its device identifier.
+ *
+ * PARAMETERS:
+ * dev - device identifier (major, minor numbers)
+ *
+ * RETURNS:
+ * pointer to the block device descriptor, or NULL if no such device
+ * exists.
+ */
+disk_device *
+rtems_disk_lookup(dev_t dev)
+{
+ rtems_interrupt_level level;
+ disk_device *dd;
+ rtems_status_code rc;
+
+ rtems_interrupt_disable(level);
+ if (diskdevs_protected)
+ {
+ rtems_interrupt_enable(level);
+ rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT);
+ if (rc != RTEMS_SUCCESSFUL)
+ return NULL;
+ diskdevs_protected = TRUE;
+ dd = get_disk_entry(dev);
+ dd->uses++;
+ diskdevs_protected = FALSE;
+ rtems_semaphore_release(diskdevs_mutex);
+ return dd;
+ }
+ else
+ {
+ /* Frequent and quickest case */
+ dd = get_disk_entry(dev);
+ dd->uses++;
+ rtems_interrupt_enable(level);
+ return dd;
+ }
+}
+
+/* rtems_disk_release --
+ * Release disk_device structure (decrement usage counter to 1).
+ *
+ * PARAMETERS:
+ * dd - pointer to disk device structure
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL
+ */
+rtems_status_code
+rtems_disk_release(disk_device *dd)
+{
+ rtems_interrupt_level level;
+ rtems_interrupt_disable(level);
+ dd->uses--;
+ rtems_interrupt_enable(level);
+ return RTEMS_SUCCESSFUL;
+}
+
+/* rtems_disk_next --
+ * Disk device enumerator. Looking for device having device number larger
+ * than dev and return disk device descriptor for it. If there are no
+ * such device, NULL value returned.
+ *
+ * PARAMETERS:
+ * dev - device number (use -1 to start search)
+ *
+ * RETURNS:
+ * Pointer to the disk descriptor for next disk device, or NULL if all
+ * devices enumerated.
+ */
+disk_device *
+rtems_disk_next(dev_t dev)
+{
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+ struct disk_device_table *dtab;
+
+ dev++;
+ rtems_filesystem_split_dev_t (dev, major, minor);
+
+ if (major >= disktab_size)
+ return NULL;
+
+ dtab = disktab + major;
+ while (TRUE)
+ {
+ if ((dtab == NULL) || (minor > dtab->size))
+ {
+ major++; minor = 0;
+ if (major >= disktab_size)
+ return NULL;
+ dtab = disktab + major;
+ }
+ else if (dtab->minor[minor] == NULL)
+ {
+ minor++;
+ }
+ else
+ return dtab->minor[minor];
+ }
+}
+
+/* rtems_disk_initialize --
+ * Initialization of disk device library (initialize all data structures,
+ * etc.)
+ *
+ * PARAMETERS:
+ * none
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if library initialized, or error code if error
+ * occured.
+ */
+rtems_status_code
+rtems_disk_io_initialize(void)
+{
+ rtems_status_code rc;
+
+ if (disk_io_initialized)
+ return RTEMS_SUCCESSFUL;
+
+ disktab_size = DISKTAB_INITIAL_SIZE;
+ disktab = calloc(disktab_size, sizeof(struct disk_device_table));
+ if (disktab == NULL)
+ return RTEMS_NO_MEMORY;
+
+ diskdevs_protected = FALSE;
+ rc = rtems_semaphore_create(
+ rtems_build_name('D', 'D', 'E', 'V'), 1,
+ RTEMS_FIFO | RTEMS_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY |
+ RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, 0, &diskdevs_mutex);
+
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ free(disktab);
+ return rc;
+ }
+
+ rc = rtems_bdbuf_init(rtems_bdbuf_configuration,
+ rtems_bdbuf_configuration_size);
+
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ rtems_semaphore_delete(diskdevs_mutex);
+ free(disktab);
+ return rc;
+ }
+
+ disk_io_initialized = 1;
+ return RTEMS_SUCCESSFUL;
+}
+
+/* rtems_disk_io_done --
+ * Release all resources allocated for disk device interface.
+ *
+ * PARAMETERS:
+ * none
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if all resources released, or error code if error
+ * occured.
+ */
+rtems_status_code
+rtems_disk_io_done(void)
+{
+ rtems_device_major_number maj;
+ rtems_device_minor_number min;
+ rtems_status_code rc;
+
+ /* Free data structures */
+ for (maj = 0; maj < disktab_size; maj++)
+ {
+ struct disk_device_table *dtab = disktab + maj;
+ if (dtab != NULL)
+ {
+ for (min = 0; min < dtab->size; min++)
+ {
+ disk_device *dd = dtab->minor[min];
+ unlink(dd->name);
+ free(dd->name);
+ free(dd);
+ }
+ free(dtab);
+ }
+ }
+ free(disktab);
+
+ rc = rtems_semaphore_release(diskdevs_mutex);
+
+ /* XXX bdbuf should be released too! */
+ disk_io_initialized = 0;
+ return rc;
+}
diff --git a/cpukit/libblock/src/ide_part_table.c b/cpukit/libblock/src/ide_part_table.c
new file mode 100644
index 0000000000..2b5b46138b
--- /dev/null
+++ b/cpukit/libblock/src/ide_part_table.c
@@ -0,0 +1,550 @@
+/*****************************************************************************
+ *
+ * ide_part_table.c
+ *
+ * The implementation of library supporting "MS-DOS-style" partition table
+ *
+ *
+ * Copyright (C) 2002 OKTET Ltd., St.-Petersburg, Russia
+ *
+ * Author: Konstantin Abramenko <Konstantin.Abramenko@oktet.ru>
+ * Alexander Kukuta <Alexander.Kukuta@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ *****************************************************************************/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <rtems/ide_part_table.h>
+
+/*
+ * get_sector --
+ * gets sector from the disk
+ *
+ * PARAMETERS:
+ * dev - device number
+ * sector_num - number of sector to read
+ * sector - returned pointer to pointer to allocated
+ * sector_data_t structure
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL, if success;
+ * RTEMS_NO_MEMORY, if canot allocate memory for sector data;
+ * other error codes returned by rtems_bdbuf_read().
+ *
+ * NOTES:
+ * get_sector() operates with device via bdbuf library,
+ * and does not support devices with sector size other than 512 bytes
+ */
+static rtems_status_code
+get_sector(dev_t dev, uint32_t sector_num, sector_data_t **sector)
+{
+ sector_data_t *s;
+ bdbuf_buffer *buf;
+ rtems_status_code rc;
+
+ if (sector == NULL)
+ {
+ return RTEMS_INTERNAL_ERROR;
+ }
+
+ s = (sector_data_t *) malloc(sizeof(sector_data_t) + RTEMS_IDE_SECTOR_SIZE);
+ if (s == NULL)
+ {
+ return RTEMS_NO_MEMORY;
+ }
+
+ rc = rtems_bdbuf_read(dev, sector_num, &buf);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ free(s);
+ return rc;
+ }
+
+ memcpy(s->data, buf->buffer, RTEMS_IDE_SECTOR_SIZE);
+ s->sector_num = sector_num;
+
+ *sector = s;
+
+ rtems_bdbuf_release(buf);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * msdos_signature_check --
+ * checks if the partition table sector has msdos signature
+ *
+ * PARAMETERS:
+ * sector - sector to check
+ *
+ * RETURNS:
+ * TRUE if sector has msdos signature, FALSE otherwise
+ */
+static rtems_boolean
+msdos_signature_check (sector_data_t *sector)
+{
+ uint8_t *p = sector->data + RTEMS_IDE_PARTITION_MSDOS_SIGNATURE_OFFSET;
+
+ return ((p[0] == RTEMS_IDE_PARTITION_MSDOS_SIGNATURE_DATA1) &&
+ (p[1] == RTEMS_IDE_PARTITION_MSDOS_SIGNATURE_DATA2));
+}
+
+
+/*
+ * is_extended --
+ * checks if the partition type is extended
+ *
+ * PARAMETERS:
+ * type - type of partition to check
+ *
+ * RETURNS:
+ * TRUE if partition type is extended, FALSE otherwise
+ */
+static rtems_boolean
+is_extended(uint8_t type)
+{
+ return ((type == EXTENDED_PARTITION) || (type == LINUX_EXTENDED));
+}
+
+/*
+ * is_fat_partition --
+ * checks if the partition type is defined for FAT
+ *
+ * PARAMETERS:
+ * type - type of partition to check
+ *
+ * RETURNS:
+ * TRUE if partition type is extended, FALSE otherwise
+ */
+static rtems_boolean
+is_fat_partition(uint8_t type)
+{
+ static const uint8_t fat_part_types[] = {
+ DOS_FAT12_PARTITION,DOS_FAT16_PARTITION,
+ DOS_P32MB_PARTITION,
+ FAT32_PARTITION ,FAT32_LBA_PARTITION,
+ FAT16_LBA_PARTITION
+ };
+
+ return (NULL != memchr(fat_part_types,type,sizeof(fat_part_types)));
+}
+
+
+/*
+ * data_to_part_desc --
+ * parses raw partition table sector data
+ * to partition description structure
+ *
+ * PARAMETERS:
+ * data - raw partition table sector data
+ * new_part_desc - pointer to returned partition description structure
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL, if success;
+ * RTEMS_NO_MEMOTY, if cannot allocate memory for part_desc_t strucure;
+ * RTEMS_INTERNAL_ERROR, if other error occurs.
+ */
+static rtems_status_code
+data_to_part_desc(uint8_t *data, part_desc_t **new_part_desc)
+{
+ part_desc_t *part_desc;
+ uint32_t temp;
+
+ if (new_part_desc == NULL)
+ {
+ return RTEMS_INTERNAL_ERROR;
+ }
+
+ *new_part_desc = NULL;
+
+ if ((part_desc = calloc(1, sizeof(part_desc_t))) == NULL)
+ {
+ return RTEMS_NO_MEMORY;
+ }
+
+ part_desc->bootable = *(data + RTEMS_IDE_PARTITION_BOOTABLE_OFFSET);
+ part_desc->sys_type = *(data + RTEMS_IDE_PARTITION_SYS_TYPE_OFFSET);
+
+ /* read the offset start position and partition size in sectors */
+
+ /* due to incorrect data alignment one have to align data first */
+ memcpy(&temp, data + RTEMS_IDE_PARTITION_START_OFFSET, sizeof(uint32_t));
+ part_desc->start = LE_TO_CPU_U32(temp);
+
+ memcpy(&temp, data + RTEMS_IDE_PARTITION_SIZE_OFFSET, sizeof(uint32_t));
+ part_desc->size = LE_TO_CPU_U32(temp);
+
+ /*
+ * use partitions that are
+ * - extended
+ * or
+ * - FAT type and non-zero
+ */
+ if (is_extended(part_desc->sys_type) ||
+ ((is_fat_partition(part_desc->sys_type)) && (part_desc->size != 0))) {
+ *new_part_desc = part_desc;
+ }
+ else {
+ /* empty partition */
+ free(part_desc);
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * read_extended_partition --
+ * recursively reads extended partition sector from the device
+ * and constructs the partition table tree
+ *
+ * PARAMETERS:
+ * start - start sector of primary extended partition, used for
+ * calculation of absolute partition sector address
+ * ext_part - description of extended partition to process
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if success,
+ * RTEMS_NO_MEMOTY if cannot allocate memory for part_desc_t strucure,
+ * RTEMS_INTERNAL_ERROR if other error occurs.
+ */
+static rtems_status_code
+read_extended_partition(uint32_t start, part_desc_t *ext_part)
+{
+ int i;
+ dev_t dev;
+ sector_data_t *sector;
+ uint32_t here;
+ uint8_t *data;
+ part_desc_t *new_part_desc;
+ rtems_status_code rc;
+
+ if ((ext_part == NULL) || (ext_part->disk_desc == NULL))
+ {
+ return RTEMS_INTERNAL_ERROR;
+ }
+
+ dev = ext_part->disk_desc->dev;
+
+ /* get start sector of current extended partition */
+ here = ext_part->start;
+
+ /* get first extended partition sector */
+
+ rc = get_sector(dev, here, &sector);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ return rc;
+ }
+
+ if (!msdos_signature_check(sector))
+ {
+ return RTEMS_INTERNAL_ERROR;
+ }
+
+ /* read and process up to 4 logical partition descriptors */
+
+ data = sector->data + RTEMS_IDE_PARTITION_TABLE_OFFSET;
+
+ for (i = 0; i < RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER; i++)
+ {
+ /* if data_to_part_desc fails skip this partition
+ * and parse the next one
+ */
+ rc = data_to_part_desc(data, &new_part_desc);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ free(sector);
+ return rc;
+ }
+
+ if (new_part_desc == NULL)
+ {
+ data += RTEMS_IDE_PARTITION_DESCRIPTOR_SIZE;
+ continue;
+ }
+
+ ext_part->sub_part[i] = new_part_desc;
+ new_part_desc->ext_part = ext_part;
+ new_part_desc->disk_desc = ext_part->disk_desc;
+
+ if (is_extended(new_part_desc->sys_type))
+ {
+ new_part_desc->log_id = EMPTY_PARTITION;
+ new_part_desc->start += start;
+ read_extended_partition(start, new_part_desc);
+ }
+ else
+ {
+ disk_desc_t *disk_desc = new_part_desc->disk_desc;
+ disk_desc->partitions[disk_desc->last_log_id] = new_part_desc;
+ new_part_desc->log_id = ++disk_desc->last_log_id;
+ new_part_desc->start += here;
+ new_part_desc->end = new_part_desc->start + new_part_desc->size - 1;
+ }
+ data += RTEMS_IDE_PARTITION_DESCRIPTOR_SIZE;
+ }
+
+ free(sector);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * read_mbr --
+ * reads Master Boot Record (sector 0) of physical device and
+ * constructs disk description structure
+ *
+ * PARAMETERS:
+ * disk_desc - returned disc description structure
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if success,
+ * RTEMS_INTERNAL_ERROR otherwise
+ */
+static rtems_status_code
+read_mbr(disk_desc_t *disk_desc)
+{
+ int part_num;
+ sector_data_t *sector;
+ part_desc_t *part_desc;
+ uint8_t *data;
+ rtems_status_code rc;
+ dev_t dev = disk_desc->dev;
+
+ /* get MBR sector */
+ rc = get_sector(dev, 0, &sector);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ return rc;
+ }
+
+ /* check if the partition table structure is MS-DOS style */
+ if (!msdos_signature_check(sector))
+ {
+ return RTEMS_INTERNAL_ERROR;
+ }
+
+ /* read and process 4 primary partition descriptors */
+
+ data = sector->data + RTEMS_IDE_PARTITION_TABLE_OFFSET;
+
+ for (part_num = 0;
+ part_num < RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER;
+ part_num++)
+ {
+ rc = data_to_part_desc(data, &part_desc);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ free(sector);
+ return rc;
+ }
+
+ if (part_desc != NULL)
+ {
+ part_desc->log_id = part_num + 1;
+ part_desc->disk_desc = disk_desc;
+ part_desc->end = part_desc->start + part_desc->size - 1;
+ disk_desc->partitions[part_num] = part_desc;
+ }
+ else
+ {
+ disk_desc->partitions[part_num] = NULL;
+ }
+
+ data += RTEMS_IDE_PARTITION_DESCRIPTOR_SIZE;
+ }
+
+ free(sector);
+
+ disk_desc->last_log_id = RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER;
+
+ /* There cannot be more than one extended partition,
+ but we are to process each primary partition */
+ for (part_num = 0;
+ part_num < RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER;
+ part_num++)
+ {
+ if (is_extended(disk_desc->partitions[part_num]->sys_type))
+ {
+ read_extended_partition(disk_desc->partitions[part_num]->start,
+ disk_desc->partitions[part_num]);
+ }
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * partition free --
+ * frees partition description structure
+ *
+ * PARAMETERS:
+ * part_desc - returned disc description structure
+ *
+ * RETURNS:
+ * N/A
+ */
+static void
+partition_free(part_desc_t *part_desc)
+{
+ int part_num;
+
+ if (part_desc == NULL)
+ return;
+
+ if (is_extended(part_desc->sys_type))
+ {
+ for (part_num = 0;
+ part_num < RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER;
+ part_num++)
+ {
+ partition_free(part_desc->sub_part[part_num]);
+ }
+ }
+
+ free(part_desc);
+}
+
+
+/*
+ * rtems_ide_part_table_free - frees disk descriptor structure
+ *
+ * PARAMETERS:
+ * disk_desc - disc descriptor structure to free
+ *
+ * RETURNS:
+ * N/A
+ */
+void
+rtems_ide_part_table_free(disk_desc_t *disk_desc)
+{
+ int part_num;
+
+ for (part_num = 0; part_num < RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER; part_num++)
+ {
+ partition_free(disk_desc->partitions[part_num]);
+ }
+
+ free(disk_desc);
+}
+
+
+/*
+ * rtems_ide_part_table_get - reads partition table structure from the device
+ * and creates disk description structure
+ *
+ * PARAMETERS:
+ * dev_name - path to physical device in /dev filesystem
+ * disk_desc - returned disc description structure
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if success,
+ * RTEMS_INTERNAL_ERROR otherwise
+ */
+rtems_status_code
+rtems_ide_part_table_get(const char *dev_name, disk_desc_t *disk_desc)
+{
+ struct stat dev_stat;
+ rtems_status_code rc;
+
+ rc = stat(dev_name, &dev_stat);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ return RTEMS_INTERNAL_ERROR;
+ }
+
+ strncpy (disk_desc->dev_name, dev_name, 15);
+ disk_desc->dev = dev_stat.st_dev;
+ disk_desc->sector_size = (dev_stat.st_blksize) ? dev_stat.st_blksize :
+ RTEMS_IDE_SECTOR_SIZE;
+
+ rc = read_mbr(disk_desc);
+
+ return rc;
+}
+
+
+/*
+ * rtems_ide_part_table_initialize - initializes logical devices
+ * on the physical IDE drive
+ *
+ * PARAMETERS:
+ * dev_name - path to physical device in /dev filesystem
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if success,
+ * RTEMS_NO_MEMOTY if cannot have not enough memory,
+ * RTEMS_INTERNAL_ERROR if other error occurs.
+ */
+rtems_status_code
+rtems_ide_part_table_initialize(char *dev_name)
+{
+ int part_num;
+ dev_t dev;
+ disk_desc_t *disk_desc;
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+ rtems_status_code rc;
+ part_desc_t *part_desc;
+
+ /* logical device name /dev/hdxyy */
+ char name[RTEMS_IDE_PARTITION_DEV_NAME_LENGTH_MAX];
+
+ disk_desc = (disk_desc_t *) calloc(1, sizeof(disk_desc_t));
+ if (disk_desc == NULL)
+ {
+ return RTEMS_NO_MEMORY;
+ }
+
+ /* get partition table */
+ rc = rtems_ide_part_table_get(dev_name, disk_desc);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ return rc;
+ }
+
+ /* To avoid device numbers conflicts we have to use for logic disk the same
+ * device major number as ATA device has, and minor number that equals to
+ * sum of logic disk partition number and the minor number of physical disk
+ */
+
+ rtems_filesystem_split_dev_t (disk_desc->dev, major, minor);
+
+ /* create logical disks on the physical one */
+ for (part_num = 0; part_num < disk_desc->last_log_id; part_num++)
+ {
+ sprintf(name, "%s%d", dev_name, part_num + 1);
+ dev = rtems_filesystem_make_dev_t(major, ++minor);
+
+ part_desc = disk_desc->partitions[part_num];
+ if (part_desc == NULL)
+ {
+ continue;
+ }
+
+ rc = rtems_disk_create_log(dev, disk_desc->dev, part_desc->start,
+ part_desc->size, name);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"Cannot create device %s, error code %d\n", name, rc);
+ continue;
+ }
+ }
+
+ rtems_ide_part_table_free(disk_desc);
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/libblock/src/ramdisk.c b/cpukit/libblock/src/ramdisk.c
new file mode 100644
index 0000000000..b72e3ae795
--- /dev/null
+++ b/cpukit/libblock/src/ramdisk.c
@@ -0,0 +1,232 @@
+/* ramdisk.c -- RAM disk block device implementation
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "rtems/blkdev.h"
+#include "rtems/diskdevs.h"
+#include "rtems/ramdisk.h"
+
+#define RAMDISK_DEVICE_BASE_NAME "/dev/ramdisk"
+
+/* Internal RAM disk descriptor */
+struct ramdisk {
+ int block_size; /* RAM disk block size */
+ int block_num; /* Number of blocks on this RAM disk */
+ void *area; /* RAM disk memory area */
+ rtems_boolean initialized;/* RAM disk is initialized */
+ rtems_boolean malloced; /* != 0, if memory allocated by malloc for this
+ RAM disk */
+};
+
+static struct ramdisk *ramdisk;
+static int nramdisks;
+
+/* ramdisk_read --
+ * RAM disk READ request handler. This primitive copies data from RAM
+ * disk to supplied buffer and invoke the callout function to inform
+ * upper layer that reading is completed.
+ *
+ * PARAMETERS:
+ * req - pointer to the READ block device request info
+ *
+ * RETURNS:
+ * ioctl return value
+ */
+static int
+ramdisk_read(struct ramdisk *rd, blkdev_request *req)
+{
+ char *from;
+ uint32_t i;
+ blkdev_sg_buffer *sg;
+ uint32_t remains;
+
+ from = (char *)rd->area + (req->start * rd->block_size);
+ remains = rd->block_size * req->count;
+ sg = req->bufs;
+ for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
+ {
+ int count = sg->length;
+ if (count > remains)
+ count = remains;
+ memcpy(sg->buffer, from, count);
+ remains -= count;
+ from += count;
+ }
+ req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0);
+ return 0;
+}
+
+/* ramdisk_write --
+ * RAM disk WRITE request handler. This primitive copies data from
+ * supplied buffer to RAM disk and invoke the callout function to inform
+ * upper layer that writing is completed.
+ *
+ * PARAMETERS:
+ * req - pointer to the WRITE block device request info
+ *
+ * RETURNS:
+ * ioctl return value
+ */
+static int
+ramdisk_write(struct ramdisk *rd, blkdev_request *req)
+{
+ char *to;
+ uint32_t i;
+ blkdev_sg_buffer *sg;
+ uint32_t remains;
+
+ to = (char *)rd->area + (req->start * rd->block_size);
+ remains = rd->block_size * req->count;
+ sg = req->bufs;
+ for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
+ {
+ int count = sg->length;
+ if (count > remains)
+ count = remains;
+ memcpy(to, sg->buffer, count);
+ remains -= count;
+ to += count;
+ }
+ req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0);
+ return 0;
+}
+
+/* ramdisk_ioctl --
+ * IOCTL handler for RAM disk device.
+ *
+ * PARAMETERS:
+ * dev - device number (major, minor number)
+ * req - IOCTL request code
+ * argp - IOCTL argument
+ *
+ * RETURNS:
+ * IOCTL return value
+ */
+static int
+ramdisk_ioctl(dev_t dev, uint32_t req, void *argp)
+{
+ switch (req)
+ {
+ case BLKIO_REQUEST:
+ {
+ rtems_device_minor_number minor;
+ blkdev_request *r = argp;
+ struct ramdisk *rd;
+
+ minor = rtems_filesystem_dev_minor_t(dev);
+ if ((minor >= nramdisks) || !ramdisk[minor].initialized)
+ {
+ errno = ENODEV;
+ return -1;
+ }
+
+ rd = ramdisk + minor;
+
+ switch (r->req)
+ {
+ case BLKDEV_REQ_READ:
+ return ramdisk_read(rd, r);
+
+ case BLKDEV_REQ_WRITE:
+ return ramdisk_write(rd, r);
+
+ default:
+ errno = EBADRQC;
+ return -1;
+ }
+ break;
+ }
+
+ default:
+ errno = EBADRQC;
+ return -1;
+ }
+}
+
+/* ramdisk_initialize --
+ * RAM disk device driver initialization. Run through RAM disk
+ * configuration information and configure appropriate RAM disks.
+ *
+ * PARAMETERS:
+ * major - RAM disk major device number
+ * minor - minor device number, not applicable
+ * arg - initialization argument, not applicable
+ *
+ * RETURNS:
+ * none
+ */
+rtems_device_driver
+ramdisk_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_device_minor_number i;
+ rtems_ramdisk_config *c = rtems_ramdisk_configuration;
+ struct ramdisk *r;
+ rtems_status_code rc;
+
+ rc = rtems_disk_io_initialize();
+ if (rc != RTEMS_SUCCESSFUL)
+ return rc;
+
+ r = ramdisk = calloc(rtems_ramdisk_configuration_size,
+ sizeof(struct ramdisk));
+
+ for (i = 0; i < rtems_ramdisk_configuration_size; i++, c++, r++)
+ {
+ dev_t dev = rtems_filesystem_make_dev_t(major, i);
+ char name[sizeof(RAMDISK_DEVICE_BASE_NAME "0123456789")];
+ snprintf(name, sizeof(name), RAMDISK_DEVICE_BASE_NAME "%" PRIu32, i);
+ r->block_size = c->block_size;
+ r->block_num = c->block_num;
+ if (c->location == NULL)
+ {
+ r->malloced = TRUE;
+ r->area = malloc(r->block_size * r->block_num);
+ if (r->area == NULL) /* No enough memory for this disk */
+ {
+ r->initialized = FALSE;
+ continue;
+ }
+ else
+ {
+ r->initialized = TRUE;
+ }
+ }
+ else
+ {
+ r->malloced = FALSE;
+ r->initialized = TRUE;
+ r->area = c->location;
+ }
+ rc = rtems_disk_create_phys(dev, c->block_size, c->block_num,
+ ramdisk_ioctl, name);
+ if (rc != RTEMS_SUCCESSFUL)
+ {
+ if (r->malloced)
+ {
+ free(r->area);
+ }
+ r->initialized = FALSE;
+ }
+ }
+ nramdisks = rtems_ramdisk_configuration_size;
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/libcsupport/.cvsignore b/cpukit/libcsupport/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/libcsupport/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am
new file mode 100644
index 0000000000..e7c174f6b3
--- /dev/null
+++ b/cpukit/libcsupport/Makefile.am
@@ -0,0 +1,94 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+noinst_LIBRARIES = libcsupport.a
+libcsupport_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = include/chain.h include/console.h include/clockdrv.h \
+ include/iosupp.h include/ringbuf.h include/rtc.h include/spurious.h \
+ include/timerdrv.h include/vmeintr.h
+
+## motorola
+
+include_rtems_motoroladir = $(includedir)/rtems/motorola
+
+include_rtems_motorola_HEADERS = include/motorola/mc68230.h \
+ include/motorola/mc68681.h
+
+## rtems
+include_rtems_HEADERS += include/rtems/assoc.h include/rtems/error.h \
+ include/rtems/libcsupport.h include/rtems/libio.h include/rtems/libio_.h \
+ include/rtems/termiostypes.h include/rtems/cdefs.h
+
+## zilog
+
+include_rtems_zilogdir = $(includedir)/rtems/zilog
+
+include_rtems_zilog_HEADERS = include/zilog/z8036.h include/zilog/z8530.h \
+ include/zilog/z8536.h
+
+## General stuff
+ERROR_C_FILES = src/error.c
+
+ASSOCIATION_C_FILES = src/assoc.c src/assocnamebad.c
+
+BASE_FS_C_FILES = src/base_fs.c src/mount.c src/unmount.c src/libio.c \
+ src/libio_sockets.c src/eval.c src/fs_null_handlers.c src/privateenv.c
+
+TERMIOS_C_FILES = src/cfgetispeed.c src/cfgetospeed.c src/cfsetispeed.c \
+ src/cfsetospeed.c src/tcgetattr.c src/tcsetattr.c src/tcdrain.c \
+ src/tcflow.c src/tcflush.c src/tcgetprgrp.c src/tcsendbreak.c \
+ src/tcsetpgrp.c src/termios.c src/termiosinitialize.c \
+ src/termiosreserveresources.c
+
+SYSTEM_CALL_C_FILES = src/open.c src/close.c src/read.c src/write.c \
+ src/lseek.c src/ioctl.c src/mkdir.c src/mknod.c src/mkfifo.c src/rmdir.c \
+ src/chdir.c src/chmod.c src/fchdir.c src/fchmod.c src/chown.c src/link.c \
+ src/unlink.c src/umask.c src/ftruncate.c src/utime.c src/fstat.c \
+ src/fcntl.c src/fpathconf.c src/getdents.c src/fsync.c src/fdatasync.c \
+ src/pipe.c src/dup.c src/dup2.c src/symlink.c src/readlink.c src/creat.c \
+ src/chroot.c src/sync.c
+
+DIRECTORY_SCAN_C_FILES = src/opendir.c src/closedir.c src/readdir.c \
+ src/readdir_r.c src/rewinddir.c src/scandir.c src/seekdir.c \
+ src/telldir.c src/getcwd.c
+
+ID_C_FILES = src/getegid.c src/geteuid.c src/getgid.c src/getgroups.c \
+ src/getlogin.c src/getpgrp.c src/getpid.c src/getppid.c src/getuid.c \
+ src/setpgid.c src/setsid.c
+
+MALLOC_C_FILES = src/malloc.c src/mallocfreespace.c src/__brk.c \
+ src/__sbrk.c
+
+PASSWORD_GROUP_C_FILES = src/getpwent.c
+
+TERMINAL_IDENTIFICATION_C_FILES = src/ctermid.c src/isatty.c src/ttyname.c
+
+LIBC_GLUE_C_FILES = src/__getpid.c src/__gettod.c src/__times.c \
+ src/truncate.c src/access.c src/stat.c src/lstat.c src/pathconf.c \
+ src/newlibc.c src/no_posix.c src/no_libc.c src/utsname.c
+
+BSD_LIBC_C_FILES = src/strlcpy.c src/strlcat.c
+
+libcsupport_a_SOURCES = src/gxx_wrappers.c src/printk.c $(BSD_LIBC_C_FILES) \
+ $(BASE_FS_C_FILES) $(MALLOC_C_FILES) $(ERROR_C_FILES) \
+ $(ASSOCIATION_C_FILES)
+
+if UNIX
+libcsupport_a_SOURCES += src/unixlibc.c src/hosterr.c
+else
+libcsupport_a_SOURCES += $(LIBC_GLUE_C_FILES) $(PASSWORD_GROUP_C_FILES) \
+ $(TERMINAL_IDENTIFICATION_C_FILES) $(SYSTEM_CALL_C_FILES) \
+ $(DIRECTORY_SCAN_C_FILES) $(ID_C_FILES) src/envlock.c \
+ $(TERMIOS_C_FILES)
+endif
+
+EXTRA_DIST = src/TODO src/CASES src/README
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/libcsupport/include/chain.h b/cpukit/libcsupport/include/chain.h
new file mode 100644
index 0000000000..0379b8b596
--- /dev/null
+++ b/cpukit/libcsupport/include/chain.h
@@ -0,0 +1,365 @@
+/**
+ * @file rtems/chain.h
+ */
+
+/* chain.h
+ *
+ * This include file contains all the constants and structures associated
+ * with doubly linked chains. This file actually just provides an
+ * interface to the chain object in rtems.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $ld:
+ */
+
+#ifndef _RTEMS_CHAIN_H
+#define _RTEMS_CHAIN_H
+
+#include <rtems.h>
+
+/*
+ * Chain_Initialize
+ *
+ * This routine initializes the_chain structure to manage the
+ * contiguous array of number_nodes nodes which starts at
+ * starting_address. Each node is of node_size bytes.
+ *
+ * Chain_Control *the_chain, * IN *
+ * void *starting_address, * IN *
+ * uint32_t number_nodes, * IN *
+ * uint32_t node_size * IN *
+ */
+
+#define Chain_Initialize( the_chain, starting_address, \
+ number_nodes, node_size ) \
+ _Chain_Initialize( the_chain, starting_address, \
+ number_nodes, node_size ) \
+
+
+/*
+ * Chain_Initialize_empty
+ *
+ * This routine initializes the specified chain to contain zero nodes.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Initialize_empty( the_chain ) \
+ _Chain_Initialize_empty( the_chain )
+
+
+/*
+ * Chain_Are_nodes_equal
+ *
+ * This function returns TRUE if LEFT and RIGHT are equal,
+ * and FALSE otherwise.
+ *
+ * Chain_Node *left, * IN *
+ * Chain_Node *right * IN *
+ */
+
+#define Chain_Are_nodes_equal( left, right ) \
+ _Chain_Are_nodes_equal( left, right )
+
+
+/*
+ * Chain_Extract_unprotected
+ *
+ * This routine extracts the_node from the chain on which it resides.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * extract operation.
+ *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Extract_unprotected( the_node ) \
+ _Chain_Extract_unprotected( the_node )
+
+
+/*
+ * Chain_Extract
+ *
+ * This routine extracts the_node from the chain on which it resides.
+ * It disables interrupts to insure the atomicity of the
+ * extract operation.
+ *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Extract( the_node ) \
+ _Chain_Extract( the_node )
+
+
+/*
+ * Chain_Get_unprotected
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. If the_chain is empty, then NULL is returned.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * get operation.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Get_unprotected( the_chain ) \
+ _Chain_Get_unprotected( the_chain )
+
+
+/*
+ * Chain_Get
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. If the_chain is empty, then NULL is returned.
+ * It disables interrupts to insure the atomicity of the
+ * get operation.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Get( the_chain ) \
+ _Chain_Get( the_chain )
+
+
+/*
+ * Chain_Get_first_unprotected
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. It does NOT disable interrupts to insure
+ * the atomicity of the get operation.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Get_first_unprotected( the_chain ) \
+ _Chain_Get_first_unprotected( the_chain )
+
+
+/*
+ * Chain_Insert_unprotected
+ *
+ * This routine inserts the_node on a chain immediately following
+ * after_node. It does NOT disable interrupts to insure the atomicity
+ * of the extract operation.
+ *
+ * Chain_Node *after_node, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Insert_unprotected( after_node, the_node ) \
+ _Chain_Insert_unprotected( after_node, the_node )
+
+
+/*
+ * Chain_Insert
+ *
+ * This routine inserts the_node on a chain immediately following
+ * after_node. It disables interrupts to insure the atomicity
+ * of the extract operation.
+ *
+ * Chain_Node *after_node, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Insert( after_node, the_node ) \
+ _Chain_Insert( after_node, the_node )
+
+
+/*
+ * Chain_Append_unprotected
+ *
+ * This routine appends the_node onto the end of the_chain.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * append operation.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Append_unprotected( the_chain, the_node ) \
+ _Chain_Append_unprotected( the_chain, the_node )
+
+
+/*
+ * Chain_Append
+ *
+ * This routine appends the_node onto the end of the_chain.
+ * It disables interrupts to insure the atomicity of the
+ * append operation.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Append( the_chain, the_node ) \
+ _Chain_Append( the_chain, the_node )
+
+
+/*
+ * Chain_Prepend_unprotected
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * prepend operation.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Prepend_unprotected( the_chain, the_node ) \
+ _Chain_Prepend_unprotected( the_chain, the_node )
+
+
+/*
+ * Chain_Prepend
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ * It disables interrupts to insure the atomicity of the
+ * prepend operation.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Prepend( the_chain, the_node ) \
+ _Chain_Prepend( the_chain, the_node )
+
+
+/*
+ * Chain_Head
+ *
+ * This function returns a pointer to the first node on the chain.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Head( the_chain ) \
+ _Chain_Head( the_chain )
+
+
+/*
+ * Chain_Tail
+ *
+ * This function returns a pointer to the last node on the chain.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Tail( the_chain ) \
+ _Chain_Tail( the_chain )
+
+
+/*
+ * Chain_Is_head
+ *
+ * This function returns TRUE if the_node is the head of the_chain and
+ * FALSE otherwise.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Is_head( the_chain, the_node ) \
+ _Chain_Is_head( the_chain, the_node )
+
+
+/*
+ * Chain_Is_tail
+ *
+ * This function returns TRUE if the_node is the tail of the_chain and
+ * FALSE otherwise.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Is_tail( the_chain, the_node ) \
+ _Chain_Is_tail( the_chain, the_node )
+
+
+/*
+ * Chain_Is_first
+ *
+ * This function returns TRUE if the_node is the first node on a chain and
+ * FALSE otherwise.
+ *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Is_first( the_node ) \
+ _Chain_Is_first( the_node )
+
+
+/*
+ * Chain_Is_last
+ *
+ * This function returns TRUE if the_node is the last node on a chain and
+ * FALSE otherwise.
+ *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Is_last( the_node ) \
+ _Chain_Is_last( the_node )
+
+
+/*
+ * Chain_Is_empty
+ *
+ * This function returns TRUE if there are no nodes on the_chain and
+ * FALSE otherwise.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Is_empty( the_chain ) \
+ _Chain_Is_empty( the_chain )
+
+
+/*
+ * Chain_Has_only_one_node
+ *
+ * This function returns TRUE if there is only one node on the_chain and
+ * FALSE otherwise.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Has_only_one_node( the_chain ) \
+ _Chain_Has_only_one_node( the_chain )
+
+
+/*
+ * Chain_Is_null
+ *
+ * This function returns TRUE if the_chain is NULL and FALSE otherwise.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Is_null( the_chain ) \
+ _Chain_Is_null( the_chain )
+
+
+/*
+ * Chain_Is_null_node
+ *
+ * This function returns TRUE if the_node is NULL and FALSE otherwise.
+ *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Is_null_node( the_node ) \
+ _Chain_Is_null_node( the_node )
+
+
+#undef __RTEMS_APPLICATION__
+#include <rtems/score/chain.inl>
+#define __RTEMS_APPLICATION__
+#endif
+/* end of include file */
diff --git a/cpukit/libcsupport/include/clockdrv.h b/cpukit/libcsupport/include/clockdrv.h
new file mode 100644
index 0000000000..7882f6c453
--- /dev/null
+++ b/cpukit/libcsupport/include/clockdrv.h
@@ -0,0 +1,54 @@
+/**
+ * @file rtems/clockdrv.h
+ */
+
+/* clock.h
+ *
+ * This file describes the Clock Driver for all boards.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_CLOCKDRV_H
+#define _RTEMS_CLOCKDRV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* variables */
+
+extern volatile uint32_t Clock_driver_ticks;
+extern rtems_device_major_number rtems_clock_major;
+extern rtems_device_minor_number rtems_clock_minor;
+
+/* default clock driver entry */
+
+#define CLOCK_DRIVER_TABLE_ENTRY \
+ { Clock_initialize, NULL, NULL, NULL, NULL, Clock_control }
+
+rtems_device_driver Clock_initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver Clock_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libcsupport/include/console.h b/cpukit/libcsupport/include/console.h
new file mode 100644
index 0000000000..5bf3fe754a
--- /dev/null
+++ b/cpukit/libcsupport/include/console.h
@@ -0,0 +1,72 @@
+/**
+ * @file rtems/console.h
+ */
+
+/* console.h
+ *
+ * This file describes the Console Device Driver for all boards.
+ * This driver provides support for the standard C Library.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_CONSOLE_H
+#define _RTEMS_CONSOLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CONSOLE_DRIVER_TABLE_ENTRY \
+ { console_initialize, console_open, console_close, \
+ console_read, console_write, console_control }
+
+rtems_device_driver console_initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver console_open(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver console_close(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver console_read(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver console_write(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver console_control(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libcsupport/include/inttypes.h b/cpukit/libcsupport/include/inttypes.h
new file mode 100644
index 0000000000..cef7db622f
--- /dev/null
+++ b/cpukit/libcsupport/include/inttypes.h
@@ -0,0 +1,291 @@
+/*
+ * COPYRIGHT (c) 2004, 2005.
+ * Ralf Corsepius, Ulm/Germany.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ *
+ * $Id$
+ */
+
+/**
+ * @file inttypes.h
+ */
+
+#ifndef _INTTYPES_H
+#define _INTTYPES_H
+
+#include <stdint.h>
+
+#define __STRINGIFY(a) #a
+
+/* 8-bit types */
+#define __PRI8(x) __STRINGIFY(x)
+#define __SCN8(x) __STRINGIFY(hh##x)
+
+
+#define PRId8 __PRI8(d)
+#define PRIi8 __PRI8(i)
+#define PRIo8 __PRI8(o)
+#define PRIu8 __PRI8(u)
+#define PRIx8 __PRI8(x)
+#define PRIX8 __PRI8(X)
+
+#define SCNd8 __SCN8(d)
+#define SCNi8 __SCN8(i)
+#define SCNo8 __SCN8(o)
+#define SCNu8 __SCN8(u)
+#define SCNx8 __SCN8(x)
+
+
+#define PRIdLEAST8 __PRI8(d)
+#define PRIiLEAST8 __PRI8(i)
+#define PRIoLEAST8 __PRI8(o)
+#define PRIuLEAST8 __PRI8(u)
+#define PRIxLEAST8 __PRI8(x)
+#define PRIXLEAST8 __PRI8(X)
+
+#define SCNdLEAST8 __SCN8(d)
+#define SCNiLEAST8 __SCN8(i)
+#define SCNoLEAST8 __SCN8(o)
+#define SCNuLEAST8 __SCN8(u)
+#define SCNxLEAST8 __SCN8(x)
+
+
+#define PRIdFAST8 __PRI8(d)
+#define PRIiFAST8 __PRI8(i)
+#define PRIoFAST8 __PRI8(o)
+#define PRIuFAST8 __PRI8(u)
+#define PRIxFAST8 __PRI8(x)
+#define PRIXFAST8 __PRI8(X)
+
+#define SCNdFAST8 __SCN8(d)
+#define SCNiFAST8 __SCN8(i)
+#define SCNoFAST8 __SCN8(o)
+#define SCNuFAST8 __SCN8(u)
+#define SCNxFAST8 __SCN8(x)
+
+/* 16-bit types */
+#define __PRI16(x) __STRINGIFY(x)
+#define __SCN16(x) __STRINGIFY(h##x)
+
+
+#define PRId16 __PRI16(d)
+#define PRIi16 __PRI16(i)
+#define PRIo16 __PRI16(o)
+#define PRIu16 __PRI16(u)
+#define PRIx16 __PRI16(x)
+#define PRIX16 __PRI16(X)
+
+#define SCNd16 __SCN16(d)
+#define SCNi16 __SCN16(i)
+#define SCNo16 __SCN16(o)
+#define SCNu16 __SCN16(u)
+#define SCNx16 __SCN16(x)
+
+
+#define PRIdLEAST16 __PRI16(d)
+#define PRIiLEAST16 __PRI16(i)
+#define PRIoLEAST16 __PRI16(o)
+#define PRIuLEAST16 __PRI16(u)
+#define PRIxLEAST16 __PRI16(x)
+#define PRIXLEAST16 __PRI16(X)
+
+#define SCNdLEAST16 __SCN16(d)
+#define SCNiLEAST16 __SCN16(i)
+#define SCNoLEAST16 __SCN16(o)
+#define SCNuLEAST16 __SCN16(u)
+#define SCNxLEAST16 __SCN16(x)
+
+
+#define PRIdFAST16 __PRI16(d)
+#define PRIiFAST16 __PRI16(i)
+#define PRIoFAST16 __PRI16(o)
+#define PRIuFAST16 __PRI16(u)
+#define PRIxFAST16 __PRI16(x)
+#define PRIXFAST16 __PRI16(X)
+
+#define SCNdFAST16 __SCN16(d)
+#define SCNiFAST16 __SCN16(i)
+#define SCNoFAST16 __SCN16(o)
+#define SCNuFAST16 __SCN16(u)
+#define SCNxFAST16 __SCN16(x)
+
+/* 32-bit types */
+#if defined(__rtems_long32)
+#define __PRI32(x) __STRINGIFY(l##x)
+#define __SCN32(x) __STRINGIFY(l##x)
+#else
+#define __PRI32(x) __STRINGIFY(x)
+#define __SCN32(x) __STRINGIFY(x)
+#endif
+
+#define PRId32 __PRI32(d)
+#define PRIi32 __PRI32(i)
+#define PRIo32 __PRI32(o)
+#define PRIu32 __PRI32(u)
+#define PRIx32 __PRI32(x)
+#define PRIX32 __PRI32(X)
+
+#define SCNd32 __SCN32(d)
+#define SCNi32 __SCN32(i)
+#define SCNo32 __SCN32(o)
+#define SCNu32 __SCN32(u)
+#define SCNx32 __SCN32(x)
+
+
+#define PRIdLEAST32 __PRI32(d)
+#define PRIiLEAST32 __PRI32(i)
+#define PRIoLEAST32 __PRI32(o)
+#define PRIuLEAST32 __PRI32(u)
+#define PRIxLEAST32 __PRI32(x)
+#define PRIXLEAST32 __PRI32(X)
+
+#define SCNdLEAST32 __SCN32(d)
+#define SCNiLEAST32 __SCN32(i)
+#define SCNoLEAST32 __SCN32(o)
+#define SCNuLEAST32 __SCN32(u)
+#define SCNxLEAST32 __SCN32(x)
+
+
+#define PRIdFAST32 __PRI32(d)
+#define PRIiFAST32 __PRI32(i)
+#define PRIoFAST32 __PRI32(o)
+#define PRIuFAST32 __PRI32(u)
+#define PRIxFAST32 __PRI32(x)
+#define PRIXFAST32 __PRI32(X)
+
+#define SCNdFAST32 __SCN32(d)
+#define SCNiFAST32 __SCN32(i)
+#define SCNoFAST32 __SCN32(o)
+#define SCNuFAST32 __SCN32(u)
+#define SCNxFAST32 __SCN32(x)
+
+
+/* 64-bit types */
+#if defined(__rtems_longlong64)
+#define __PRI64(x) __STRINGIFY(ll##x)
+#define __SCN64(x) __STRINGIFY(ll##x)
+#elif defined(__rtems_long64)
+#define __PRI64(x) __STRINGIFY(l##x)
+#define __SCN64(x) __STRINGIFY(l##x)
+#else
+#define __PRI64(x) __STRINGIFY(x)
+#define __SCN64(x) __STRINGIFY(x)
+#endif
+
+#define PRId64 __PRI64(d)
+#define PRIi64 __PRI64(i)
+#define PRIo64 __PRI64(o)
+#define PRIu64 __PRI64(u)
+#define PRIx64 __PRI64(x)
+#define PRIX64 __PRI64(X)
+
+#define SCNd64 __SCN64(d)
+#define SCNi64 __SCN64(i)
+#define SCNo64 __SCN64(o)
+#define SCNu64 __SCN64(u)
+#define SCNx64 __SCN64(x)
+
+#if __int64_t_defined
+#define PRIdLEAST64 __PRI64(d)
+#define PRIiLEAST64 __PRI64(i)
+#define PRIoLEAST64 __PRI64(o)
+#define PRIuLEAST64 __PRI64(u)
+#define PRIxLEAST64 __PRI64(x)
+#define PRIXLEAST64 __PRI64(X)
+
+#define SCNdLEAST64 __SCN64(d)
+#define SCNiLEAST64 __SCN64(i)
+#define SCNoLEAST64 __SCN64(o)
+#define SCNuLEAST64 __SCN64(u)
+#define SCNxLEAST64 __SCN64(x)
+
+
+#define PRIdFAST64 __PRI64(d)
+#define PRIiFAST64 __PRI64(i)
+#define PRIoFAST64 __PRI64(o)
+#define PRIuFAST64 __PRI64(u)
+#define PRIxFAST64 __PRI64(x)
+#define PRIXFAST64 __PRI64(X)
+
+#define SCNdFAST64 __SCN64(d)
+#define SCNiFAST64 __SCN64(i)
+#define SCNoFAST64 __SCN64(o)
+#define SCNuFAST64 __SCN64(u)
+#define SCNxFAST64 __SCN64(x)
+#endif
+
+/* max-bit types */
+#if defined(__rtems_longlong64)
+#define __PRIMAX(x) __STRINGIFY(ll##x)
+#define __SCNMAX(x) __STRINGIFY(ll##x)
+#elif defined(__rtems_long64)
+#define __PRIMAX(x) __STRINGIFY(l##x)
+#define __SCNMAX(x) __STRINGIFY(l##x)
+#else
+#define __PRIMAX(x) __STRINGIFY(x)
+#define __SCNMAX(x) __STRINGIFY(x)
+#endif
+
+#define PRIdMAX __PRIMAX(d)
+#define PRIiMAX __PRIMAX(i)
+#define PRIoMAX __PRIMAX(o)
+#define PRIuMAX __PRIMAX(u)
+#define PRIxMAX __PRIMAX(x)
+#define PRIXMAX __PRIMAX(X)
+
+#define SCNdMAX __SCNMAX(d)
+#define SCNiMAX __SCNMAX(i)
+#define SCNoMAX __SCNMAX(o)
+#define SCNuMAX __SCNMAX(u)
+#define SCNxMAX __SCNMAX(x)
+
+/* ptr types */
+#if defined(__rtems_longlong64)
+#define __PRIPTR(x) __STRINGIFY(ll##x)
+#define __SCNPTR(x) __STRINGIFY(ll##x)
+#elif defined(__rtems_long64)
+#define __PRIPTR(x) __STRINGIFY(l##x)
+#define __SCNPTR(x) __STRINGIFY(l##x)
+#else
+#define __PRIPTR(x) __STRINGIFY(x)
+#define __SCNPTR(x) __STRINGIFY(x)
+#endif
+
+#define PRIdPTR __PRIPTR(d)
+#define PRIiPTR __PRIPTR(i)
+#define PRIoPTR __PRIPTR(o)
+#define PRIuPTR __PRIPTR(u)
+#define PRIxPTR __PRIPTR(x)
+#define PRIXPTR __PRIPTR(X)
+
+#define SCNdPTR __SCNPTR(d)
+#define SCNiPTR __SCNPTR(i)
+#define SCNoPTR __SCNPTR(o)
+#define SCNuPTR __SCNPTR(u)
+#define SCNxPTR __SCNPTR(x)
+
+
+typedef struct {
+ intmax_t quot;
+ intmax_t rem;
+} imaxdiv_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern intmax_t imaxabs(intmax_t j);
+extern imaxdiv_t imaxdiv(intmax_t numer, intmax_t denomer);
+extern intmax_t strtoimax(const char *__restrict, char **__restrict, int);
+extern uintmax_t strtoumax(const char *__restrict, char **__restrict, int);
+extern intmax_t wcstoimax(const wchar_t *__restrict, wchar_t **__restrict, int);
+extern uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libcsupport/include/iosupp.h b/cpukit/libcsupport/include/iosupp.h
new file mode 100644
index 0000000000..cd2ff02e06
--- /dev/null
+++ b/cpukit/libcsupport/include/iosupp.h
@@ -0,0 +1,46 @@
+/**
+ * @file rtems/iosupp.h
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_IOSUPP_H
+#define _RTEMS_IOSUPP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* character constants */
+
+#define BS 0x08 /* backspace */
+#define LF 0x0a /* line feed */
+#define CR 0x0d /* carriage return */
+#define XON 0x11 /* control-Q */
+#define XOFF 0x13 /* control-S */
+
+/* structures */
+
+#ifdef IOSUPP_INIT
+#define IOSUPP_EXTERN
+#else
+#undef IOSUPP_EXTERN
+#define IOSUPP_EXTERN extern
+#endif
+
+/* functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libcsupport/include/motorola/mc68230.h b/cpukit/libcsupport/include/motorola/mc68230.h
new file mode 100644
index 0000000000..d604958e88
--- /dev/null
+++ b/cpukit/libcsupport/include/motorola/mc68230.h
@@ -0,0 +1,74 @@
+/**
+ * @file rtems/motorola/mc68230.h
+ */
+
+/*
+ * mc68230.h -- Low level support code for the Motorola 68230 Parallel
+ * Interface/Timer (PIT)
+ *
+ * Modified by Doug McBride, Colorado Space Grant College
+ *
+ * Format taken partly from RTEMS code and mostly from Motorola IDP user's
+ * manual. RTEMS copyright information below.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_MOTOROLA_MC68230_H
+#define _RTEMS_MOTOROLA_MC68230_H
+
+/* Some Motorola IDP User manual defines: */
+#define PIT_ADDR 0x00c01003 /* base address of the PIT */
+#define REGOFF 0x04 /* Difference between addresses */
+#define VECT 64
+#define H1VECT 0x00
+#define H2VECT 0x01
+#define H3VECT 0x02
+#define H4VECT 0x03
+
+/*
+ * mc68230 register offsets
+ */
+#define PGCR 0x00
+#define PSRR 1*REGOFF
+#define PADDR 2*REGOFF
+#define PBDDR 3*REGOFF
+#define PCDDR 4*REGOFF
+#define PIVR 5*REGOFF
+#define PACR 6*REGOFF
+#define PBCR 7*REGOFF
+#define PADR 8*REGOFF
+#define PBDR 9*REGOFF
+#define PAAR 10*REGOFF
+#define PBAR 11*REGOFF
+#define PCDR 12*REGOFF
+#define PITSR 13*REGOFF
+#define TCR 16*REGOFF
+#define TIVR 17*REGOFF
+#define CPRH 19*REGOFF
+#define CPRM 20*REGOFF
+#define CPRL 21*REGOFF
+#define CNTRH 23*REGOFF
+#define CNTRM 24*REGOFF
+#define CNTRL 25*REGOFF
+#define TSR 26*REGOFF
+
+/* Some RTEMS style defines: */
+#ifndef VOL8
+#define VOL8( ptr ) ((volatile uint8_t *)(ptr))
+#endif
+
+#define MC68230_WRITE( reg, data ) \
+ *(VOL8(PIT_ADDR+reg)) = (data)
+
+#define MC68230_READ( reg, data ) \
+ (data) = *(VOL8(PIT_ADDR+reg))
+
+#endif
diff --git a/cpukit/libcsupport/include/motorola/mc68681.h b/cpukit/libcsupport/include/motorola/mc68681.h
new file mode 100644
index 0000000000..7b2f566da3
--- /dev/null
+++ b/cpukit/libcsupport/include/motorola/mc68681.h
@@ -0,0 +1,309 @@
+/**
+ * @file rtems/motorola/mc68681.h
+ *
+ *
+ * mc68681-duart.h -- Low level support code for the Motorola mc68681
+ * DUART.
+ */
+
+/*
+ *
+ * Originally written by rob@cygnus.com (Rob Savoye) for the libgloss
+ * IDP support.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_MOTOROLA_MC68681_H
+#define _RTEMS_MOTOROLA_MC68681_H
+
+/*
+ * In the dark ages when this controller was designed, it was actually
+ * possible to access data on unaligned byte boundaries with no penalty.
+ * Now we find this chip in configurations in which the registers are
+ * at 16-bit, 32-bit, and 64-bit boundaries at the whim of the board
+ * designer. If the registers are not at byte addresses, then
+ * set this multiplier before including this file to correct the offsets.
+ */
+
+#ifndef MC68681_OFFSET_MULTIPLIER
+#define MC68681_OFFSET_MULTIPLIER 1
+#endif
+
+#define __MC68681_REG(_R) ((_R) * MC68681_OFFSET_MULTIPLIER)
+
+/*
+ * mc68681 register offsets Read/Write Addresses
+ */
+#define MC68681_MODE_REG_1A __MC68681_REG(0) /* MR1A-MR Prior to Read */
+#define MC68681_MODE_REG_2A __MC68681_REG(0) /* MR2A-MR After Read */
+
+#define MC68681_COUNT_MODE_CURRENT_MSB __MC68681_REG(6) /* CTU */
+#define MC68681_COUNTER_TIMER_UPPER_REG __MC68681_REG(6) /* CTU */
+#define MC68681_COUNT_MODE_CURRENT_LSB __MC68681_REG(7) /* CTL */
+#define MC68681_COUNTER_TIMER_LOWER_REG __MC68681_REG(7) /* CTL */
+#define MC68681_INTERRUPT_VECTOR_REG __MC68681_REG(12) /* IVR */
+
+#define MC68681_MODE_REG_1B __MC68681_REG(8) /* MR1B-MR Prior to Read */
+#define MC68681_MODE_REG_2B __MC68681_REG(8) /* MR2BA-MR After Read */
+
+/*
+ * mc68681 register offsets Read Only Addresses
+ */
+#define MC68681_STATUS_REG_A __MC68681_REG(1) /* SRA */
+#define MC68681_MASK_ISR_REG __MC68681_REG(2) /* MISR */
+#define MC68681_RECEIVE_BUFFER_A __MC68681_REG(3) /* RHRA */
+#define MC68681_INPUT_PORT_CHANGE_REG __MC68681_REG(4) /* IPCR */
+#define MC68681_INTERRUPT_STATUS_REG __MC68681_REG(5) /* ISR */
+#define MC68681_STATUS_REG_B __MC68681_REG(9) /* SRB */
+#define MC68681_RECEIVE_BUFFER_B __MC68681_REG(11) /* RHRB */
+#define MC68681_INPUT_PORT __MC68681_REG(13) /* IP */
+#define MC68681_START_COUNT_CMD __MC68681_REG(14) /* SCC */
+#define MC68681_STOP_COUNT_CMD __MC68681_REG(15) /* STC */
+
+/*
+ * mc68681 register offsets Write Only Addresses
+ */
+#define MC68681_CLOCK_SELECT_REG_A __MC68681_REG(1) /* CSRA */
+#define MC68681_COMMAND_REG_A __MC68681_REG(2) /* CRA */
+#define MC68681_TRANSMIT_BUFFER_A __MC68681_REG(3) /* THRA */
+#define MC68681_AUX_CTRL_REG __MC68681_REG(4) /* ACR */
+#define MC68681_INTERRUPT_MASK_REG __MC68681_REG(5) /* IMR */
+#define MC68681_CLOCK_SELECT_REG_B __MC68681_REG(9) /* CSRB */
+#define MC68681_COMMAND_REG_B __MC68681_REG(10) /* CRB */
+#define MC68681_TRANSMIT_BUFFER_B __MC68681_REG(11) /* THRB */
+#define MC68681_OUTPUT_PORT_CONFIG_REG __MC68681_REG(13) /* OPCR */
+#define MC68681_OUTPUT_PORT_SET_REG __MC68681_REG(14) /* SOPBC */
+#define MC68681_OUTPUT_PORT_RESET_BITS __MC68681_REG(15) /* COPBC */
+
+
+#ifndef MC6681_VOL
+#define MC6681_VOL( ptr ) ((volatile unsigned char *)(ptr))
+#endif
+
+#define MC68681_WRITE( _base, _reg, _data ) \
+ *((volatile unsigned char *)_base+_reg) = (_data)
+
+#define MC68681_READ( _base, _reg ) \
+ *(((volatile unsigned char *)_base+_reg))
+
+
+
+#define MC68681_CLEAR 0x00
+
+#define MC68681_PORT_A 0
+#define MC68681_PORT_B 1
+
+/*
+ * DUART Command Register Definitions:
+ *
+ * MC68681_COMMAND_REG_A,MC68681_COMMAND_REG_B
+ */
+#define MC68681_MODE_REG_ENABLE_RX 0x01
+#define MC68681_MODE_REG_DISABLE_RX 0x02
+#define MC68681_MODE_REG_ENABLE_TX 0x04
+#define MC68681_MODE_REG_DISABLE_TX 0x08
+#define MC68681_MODE_REG_RESET_MR_PTR 0x10
+#define MC68681_MODE_REG_RESET_RX 0x20
+#define MC68681_MODE_REG_RESET_TX 0x30
+#define MC68681_MODE_REG_RESET_ERROR 0x40
+#define MC68681_MODE_REG_RESET_BREAK 0x50
+#define MC68681_MODE_REG_START_BREAK 0x60
+#define MC68681_MODE_REG_STOP_BREAK 0x70
+#define MC68681_MODE_REG_SET_RX_BRG 0x80
+#define MC68681_MODE_REG_CLEAR_RX_BRG 0x90
+#define MC68681_MODE_REG_SET_TX_BRG 0xa0
+#define MC68681_MODE_REG_CLEAR_TX_BRG 0xb0
+#define MC68681_MODE_REG_SET_STANDBY 0xc0
+#define MC68681_MODE_REG_SET_ACTIVE 0xd0
+
+/*
+ * Mode Register Definitions
+ *
+ * MC68681_MODE_REG_1A
+ * MC68681_MODE_REG_1B
+ */
+#define MC68681_5BIT_CHARS 0x00
+#define MC68681_6BIT_CHARS 0x01
+#define MC68681_7BIT_CHARS 0x02
+#define MC68681_8BIT_CHARS 0x03
+
+#define MC68681_ODD_PARITY 0x00
+#define MC68681_EVEN_PARITY 0x04
+
+#define MC68681_WITH_PARITY 0x00
+#define MC68681_FORCE_PARITY 0x08
+#define MC68681_NO_PARITY 0x10
+#define MC68681_MULTI_DROP 0x18
+
+#define MC68681_ERR_MODE_CHAR 0x00
+#define MC68681_ERR_MODE_BLOCK 0x20
+
+#define MC68681_RX_INTR_RX_READY 0x00
+#define MC68681_RX_INTR_FFULL 0x40
+
+#define MC68681_NO_RX_RTS_CTL 0x00
+#define MC68681_RX_RTS_CTRL 0x80
+
+
+/*
+ * Mode Register Definitions
+ *
+ * MC68681_MODE_REG_2A
+ * MC68681_MODE_REG_2B
+ */
+#define MC68681_STOP_BIT_LENGTH__563 0x00
+#define MC68681_STOP_BIT_LENGTH__625 0x01
+#define MC68681_STOP_BIT_LENGTH__688 0x02
+#define MC68681_STOP_BIT_LENGTH__75 0x03
+#define MC68681_STOP_BIT_LENGTH__813 0x04
+#define MC68681_STOP_BIT_LENGTH__875 0x05
+#define MC68681_STOP_BIT_LENGTH__938 0x06
+#define MC68681_STOP_BIT_LENGTH_1 0x07
+#define MC68681_STOP_BIT_LENGTH_1_563 0x08
+#define MC68681_STOP_BIT_LENGTH_1_625 0x09
+#define MC68681_STOP_BIT_LENGTH_1_688 0x0a
+#define MC68681_STOP_BIT_LENGTH_1_75 0x0b
+#define MC68681_STOP_BIT_LENGTH_1_813 0x0c
+#define MC68681_STOP_BIT_LENGTH_1_875 0x0d
+#define MC68681_STOP_BIT_LENGTH_1_938 0x0e
+#define MC68681_STOP_BIT_LENGTH_2 0x0f
+
+#define MC68681_CTS_ENABLE_TX 0x10
+#define MC68681_TX_RTS_CTRL 0x20
+
+#define MC68681_CHANNEL_MODE_NORMAL 0x00
+#define MC68681_CHANNEL_MODE_ECHO 0x40
+#define MC68681_CHANNEL_MODE_LOCAL_LOOP 0x80
+#define MC68681_CHANNEL_MODE_REMOTE_LOOP 0xc0
+
+/*
+ * Status Register Definitions
+ *
+ * MC68681_STATUS_REG_A, MC68681_STATUS_REG_B
+ */
+#define MC68681_RX_READY 0x01
+#define MC68681_FFULL 0x02
+#define MC68681_TX_READY 0x04
+#define MC68681_TX_EMPTY 0x08
+#define MC68681_OVERRUN_ERROR 0x10
+#define MC68681_PARITY_ERROR 0x20
+#define MC68681_FRAMING_ERROR 0x40
+#define MC68681_RECEIVED_BREAK 0x80
+
+
+/*
+ * Interupt Status Register Definitions.
+ *
+ * MC68681_INTERRUPT_STATUS_REG
+ */
+
+
+/*
+ * Interupt Mask Register Definitions
+ *
+ * MC68681_INTERRUPT_MASK_REG
+ */
+#define MC68681_IR_TX_READY_A 0x01
+#define MC68681_IR_RX_READY_A 0x02
+#define MC68681_IR_BREAK_A 0x04
+#define MC68681_IR_COUNTER_READY 0x08
+#define MC68681_IR_TX_READY_B 0x10
+#define MC68681_IR_RX_READY_B 0x20
+#define MC68681_IR_BREAK_B 0x40
+#define MC68681_IR_INPUT_PORT_CHANGE 0x80
+
+/*
+ * Status Register Definitions.
+ *
+ * MC68681_STATUS_REG_A,MC68681_STATUS_REG_B
+ */
+#define MC68681_STATUS_RXRDY 0x01
+#define MC68681_STATUS_FFULL 0x02
+#define MC68681_STATUS_TXRDY 0x04
+#define MC68681_STATUS_TXEMT 0x08
+#define MC68681_STATUS_OVERRUN_ERROR 0x10
+#define MC68681_STATUS_PARITY_ERROR 0x20
+#define MC68681_STATUS_FRAMING_ERROR 0x40
+#define MC68681_STATUS_RECEIVED_BREAK 0x80
+
+/*
+ * Definitions for the Interrupt Vector Register:
+ *
+ * MC68681_INTERRUPT_VECTOR_REG
+ */
+#define MC68681_INTERRUPT_VECTOR_INIT 0x0f
+
+/*
+ * Definitions for the Auxiliary Control Register
+ *
+ * MC68681_AUX_CTRL_REG
+ */
+#define MC68681_AUX_BRG_SET1 0x00
+#define MC68681_AUX_BRG_SET2 0x80
+
+
+/*
+ * The following Baud rates assume the X1 clock pin is driven with a
+ * 3.6864 MHz signal. If a different frequency is used the DUART channel
+ * is running at the follwoing baud rate:
+ * ((Table Baud Rate)*frequency)/3.6864 MHz
+ */
+
+/*
+ * Definitions for the Clock Select Register:
+ *
+ * MC68681_CLOCK_SELECT_REG_A,MC68681_CLOCK_SELECT_REG_A
+ *
+ * Note: ACR[7] is the MSB of the Auxiliary Control register
+ * X is the extend bit.
+ * CRA - 0x08 Set Rx BRG Select Extend Bit (X=1)
+ * CRA - 0x09 Clear Rx BRG Select Extend Bit (X=0)
+ * CRB - 0x0a Set Tx BRG Select Extend Bit (X=1)
+ * CRB - 0x0b Clear Tx BRG Select Extend Bit (x=1)
+ */
+#define MC68681_BAUD_RATE_MASK_50 0x00 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_75 0x00 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_110 0x01
+#define MC68681_BAUD_RATE_MASK_134_5 0x02
+#define MC68681_BAUD_RATE_MASK_150 0x03 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_200 0x03 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_300 0x04 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_600 0x05 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_1050 0x07 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_1200 0x06 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_1800 0x0a /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_2400 0x08 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_3600 0x04 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_4800 0x09
+#define MC68681_BAUD_RATE_MASK_7200 0x0a /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_9600 0xbb
+
+#define MC68681_BAUD_RATE_MASK_14_4K 0x05 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_19_2K 0xcc /* ACR[7]=1,X=0 */
+ /* ARC[7]=0,X=1 */
+#define MC68681_BAUD_RATE_MASK_28_8K 0x06 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_38_4K 0xcc /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_57_6K 0x07 /* ACR[7]=0,X=0 */
+ /* ARC[7]=1,X=1 */
+#define MC68681_BAUD_RATE_MASK_115_5K 0x08
+#define MC68681_BAUD_RATE_MASK_TIMER 0xdd
+#define MC68681_BAUD_RATE_MASK_TIMER_16X 0xee
+#define MC68681_BAUD_RATE_MASK_TIMER_1X 0xff
+
+#endif
diff --git a/cpukit/libcsupport/include/ringbuf.h b/cpukit/libcsupport/include/ringbuf.h
new file mode 100644
index 0000000000..39941d857d
--- /dev/null
+++ b/cpukit/libcsupport/include/ringbuf.h
@@ -0,0 +1,55 @@
+/**
+ * @file rtems/ringbuf.h
+ *
+ * This file provides simple ring buffer functionality.
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RTEMS_RINGBUF_H
+#define _RTEMS_RINGBUF_H
+
+#ifndef RINGBUF_QUEUE_LENGTH
+#define RINGBUF_QUEUE_LENGTH 128
+#endif
+
+typedef struct {
+ uint8_t buffer[RINGBUF_QUEUE_LENGTH];
+ volatile int head;
+ volatile int tail;
+} Ring_buffer_t;
+
+#define Ring_buffer_Initialize( _buffer ) \
+ do { \
+ (_buffer)->head = (_buffer)->tail = 0; \
+ } while ( 0 )
+
+#define Ring_buffer_Is_empty( _buffer ) \
+ ( (_buffer)->head == (_buffer)->tail )
+
+#define Ring_buffer_Is_full( _buffer ) \
+ ( (_buffer)->head == ((_buffer)->tail + 1) % RINGBUF_QUEUE_LENGTH )
+
+#define Ring_buffer_Add_character( _buffer, _ch ) \
+ do { \
+ uint32_t isrlevel; \
+ \
+ rtems_interrupt_disable( isrlevel ); \
+ (_buffer)->tail = ((_buffer)->tail+1) % RINGBUF_QUEUE_LENGTH; \
+ (_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
+ rtems_interrupt_enable( isrlevel ); \
+ } while ( 0 )
+
+#define Ring_buffer_Remove_character( _buffer, _ch ) \
+ do { \
+ uint32_t isrlevel; \
+ \
+ rtems_interrupt_disable( isrlevel ); \
+ (_buffer)->head = ((_buffer)->head+1) % RINGBUF_QUEUE_LENGTH; \
+ (_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
+ rtems_interrupt_enable( isrlevel ); \
+ } while ( 0 )
+
+#endif
diff --git a/cpukit/libcsupport/include/rtc.h b/cpukit/libcsupport/include/rtc.h
new file mode 100644
index 0000000000..1339e32c8c
--- /dev/null
+++ b/cpukit/libcsupport/include/rtc.h
@@ -0,0 +1,41 @@
+/**
+ * @file rtems/rtc.h
+ *
+ * This file describes the Real-Time Clock driver for all boards.
+ * This driver provides support for the standard RTEMS routines
+ * that set the tod based on an RTC.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2001.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTC_H
+#define _RTEMS_RTC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RTC_DRIVER_TABLE_ENTRY \
+ { rtc_initialize, NULL, NULL, NULL, NULL, NULL }
+
+rtems_device_driver rtc_initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libcsupport/include/rtems/assoc.h b/cpukit/libcsupport/include/rtems/assoc.h
new file mode 100644
index 0000000000..291bdbf6e9
--- /dev/null
+++ b/cpukit/libcsupport/include/rtems/assoc.h
@@ -0,0 +1,46 @@
+/**
+ * @file rtems/assoc.h
+ */
+
+/*
+ *
+ * Rtems associativity routines. Mainly used to convert a value from
+ * one space to another (eg: our errno's to host errno's and v.v)
+ *
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_ASSOC_H
+#define _RTEMS_RTEMS_ASSOC_H
+
+typedef struct {
+ const char *name;
+ uint32_t local_value;
+ uint32_t remote_value;
+} rtems_assoc_t;
+
+/*
+ * Flag/marker for optional default value in each table
+ */
+
+#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
+
+const rtems_assoc_t *rtems_assoc_ptr_by_name(const rtems_assoc_t *, const char *);
+const rtems_assoc_t *rtems_assoc_ptr_by_value(const rtems_assoc_t *, uint32_t );
+const rtems_assoc_t *rtems_assoc_ptr_by_remote(const rtems_assoc_t *, uint32_t );
+
+uint32_t rtems_assoc_remote_by_local(const rtems_assoc_t *, uint32_t );
+uint32_t rtems_assoc_local_by_remote(const rtems_assoc_t *, uint32_t );
+uint32_t rtems_assoc_remote_by_name(const rtems_assoc_t *, const char *);
+uint32_t rtems_assoc_local_by_name(const rtems_assoc_t *, const char *);
+const char *rtems_assoc_name_by_local(const rtems_assoc_t *, uint32_t );
+const char *rtems_assoc_name_by_remote(const rtems_assoc_t *, uint32_t );
+
+uint32_t rtems_assoc_remote_by_local_bitfield(const rtems_assoc_t *, uint32_t );
+char *rtems_assoc_name_by_local_bitfield(const rtems_assoc_t *, uint32_t , char *);
+char *rtems_assoc_name_by_remote_bitfield(const rtems_assoc_t *, uint32_t , char *);
+uint32_t rtems_assoc_local_by_remote_bitfield(const rtems_assoc_t *, uint32_t );
+
+
+#endif /* ! _INCLUDE_ASSOC_H */
diff --git a/cpukit/libcsupport/include/rtems/cdefs.h b/cpukit/libcsupport/include/rtems/cdefs.h
new file mode 100644
index 0000000000..8febd93ff6
--- /dev/null
+++ b/cpukit/libcsupport/include/rtems/cdefs.h
@@ -0,0 +1,183 @@
+/**
+ * @file rtems/cdefs.h
+ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Berkeley Software Design, Inc.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)cdefs.h 8.8 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/sys/cdefs.h,v 1.92 2006/03/13 00:49:28 deischen Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RTEMS_CDEFS_H_
+#define _RTEMS_CDEFS_H_
+
+#if defined(__cplusplus)
+#define __BEGIN_DECLS extern "C" {
+#define __END_DECLS }
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+
+/*
+ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+ * The __CONCAT macro is a bit tricky to use if it must work in non-ANSI
+ * mode -- there must be no spaces between its arguments, and for nested
+ * __CONCAT's, all the __CONCAT's must be at the left. __CONCAT can also
+ * concatenate double-quoted strings produced by the __STRING macro, but
+ * this only works with ANSI C.
+ *
+ * __XSTRING is like __STRING, but it expands any macros in its argument
+ * first. It is only available with ANSI C.
+ */
+#if defined(__STDC__) || defined(__cplusplus)
+#define __P(protos) protos /* full-blown ANSI C */
+#define __CONCAT1(x,y) x ## y
+#define __CONCAT(x,y) __CONCAT1(x,y)
+#define __STRING(x) #x /* stringify without expanding x */
+#define __XSTRING(x) __STRING(x) /* expand x, then stringify */
+
+#define __const const /* define reserved names to standard */
+#define __signed signed
+#define __volatile volatile
+#if defined(__cplusplus)
+#define __inline inline /* convert to C++ keyword */
+#else
+#ifndef __GNUC__
+#define __inline /* delete GCC keyword */
+#endif /* !__GNUC__ */
+#endif /* !__cplusplus */
+
+#else /* !(__STDC__ || __cplusplus) */
+#define __P(protos) () /* traditional C preprocessor */
+#define __CONCAT(x,y) x/**/y
+#define __STRING(x) "x"
+
+#ifndef __GNUC__
+#define __const /* delete pseudo-ANSI C keywords */
+#define __inline
+#define __signed
+#define __volatile
+/*
+ * In non-ANSI C environments, new programs will want ANSI-only C keywords
+ * deleted from the program and old programs will want them left alone.
+ * When using a compiler other than gcc, programs using the ANSI C keywords
+ * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
+ * When using "gcc -traditional", we assume that this is the intent; if
+ * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
+ */
+#ifndef NO_ANSI_KEYWORDS
+#define const /* delete ANSI C keywords */
+#define inline
+#define signed
+#define volatile
+#endif /* !NO_ANSI_KEYWORDS */
+#endif /* !__GNUC__ */
+#endif /* !(__STDC__ || __cplusplus) */
+
+/*
+ * GCC1 and some versions of GCC2 declare dead (non-returning) and
+ * pure (no side effects) functions using "volatile" and "const";
+ * unfortunately, these then cause warnings under "-ansi -pedantic".
+ * GCC2.5 uses a new, peculiar __attribute__((attrs)) style. All of
+ * these work for GNU C++ (modulo a slight glitch in the C++ grammar
+ * in the distribution version of 2.5.5).
+ */
+#if __GNUC__ < 2
+#define __dead
+#define __dead2
+#define __pure
+#define __pure2
+#define __unused
+#define __attribute__(x)
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ < 5
+#define __dead __volatile
+#define __dead2
+#define __pure __const
+#define __pure2
+#define __unused
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7
+#define __dead
+#define __dead2 __attribute__((__noreturn__))
+#define __pure
+#define __pure2 __attribute__((__const__))
+#define __unused
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ >= 3
+#define __dead
+#define __dead2 __attribute__((__noreturn__))
+#define __pure
+#define __pure2 __attribute__((__const__))
+#define __unused __attribute__((__unused__))
+#endif
+
+#ifdef __GNUC__
+#ifdef __STDC__
+#define __weak_reference(sym,alias) \
+ __asm__(".stabs \"_" #alias "\",11,0,0,0"); \
+ __asm__(".stabs \"_" #sym "\",1,0,0,0")
+#define __warn_references(sym,msg) \
+ __asm__(".stabs \"" msg "\",30,0,0,0"); \
+ __asm__(".stabs \"_" #sym "\",1,0,0,0")
+#else
+#define __weak_reference(sym,alias) \
+ __asm__(".stabs \"_/**/alias\",11,0,0,0"); \
+ __asm__(".stabs \"_/**/sym\",1,0,0,0")
+#define __warn_references(sym,msg) \
+ __asm__(".stabs msg,30,0,0,0"); \
+ __asm__(".stabs \"_/**/sym\",1,0,0,0")
+#endif
+#endif
+
+#define __IDSTRING(name,string) \
+ static const char name[] __attribute__((__unused__)) = string
+
+#ifndef __RCSID
+#define __RCSID(s) __IDSTRING(rcsid,s)
+#endif
+
+#ifndef __RCSID_SOURCE
+#define __RCSID_SOURCE(s) __IDSTRING(rcsid_source,s)
+#endif
+
+#ifndef __COPYRIGHT
+#define __COPYRIGHT(s) __IDSTRING(copyright,s)
+#endif
+
+#endif /* !_RTEMS_CDEFS_H_ */
diff --git a/cpukit/libcsupport/include/rtems/error.h b/cpukit/libcsupport/include/rtems/error.h
new file mode 100644
index 0000000000..5d9ba15e50
--- /dev/null
+++ b/cpukit/libcsupport/include/rtems/error.h
@@ -0,0 +1,51 @@
+/**
+ * @file rtems/error.h
+ */
+
+/*
+ * Defines and externs for rtems error reporting
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_ERROR_H
+#define _RTEMS_RTEMS_ERROR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * rtems_error() and rtems_panic() support
+ */
+
+#define RTEMS_ERROR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
+#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
+#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
+
+#define RTEMS_ERROR_MASK (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | \
+ RTEMS_ERROR_PANIC) /* all */
+
+const char *rtems_status_text(rtems_status_code);
+int rtems_error(int error_code, const char *printf_format, ...);
+#ifdef __GNUC__
+void rtems_panic(const char *printf_format, ...);
+/*
+ * We should be able to use this attribute but gcc complains that
+ * rtems_panic does in fact return. :(
+ *
+ * __attribute__ ((__noreturn__));
+ */
+#else
+void rtems_panic(const char *printf_format, ...);
+#endif
+
+extern int rtems_panic_in_progress;
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+/* end of include file */
diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h
new file mode 100644
index 0000000000..bdd13c5136
--- /dev/null
+++ b/cpukit/libcsupport/include/rtems/libcsupport.h
@@ -0,0 +1,47 @@
+/**
+ * @file rtems/libcsupport.h
+ */
+
+/* libcsupport.h
+ *
+ * This include file contains the information regarding the
+ * RTEMS specific support for the standard C library.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_LIBCSUPPORT_H
+#define _RTEMS_RTEMS_LIBCSUPPORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+void RTEMS_Malloc_Initialize(
+ void *start,
+ size_t length,
+ size_t sbrk_amount
+);
+
+extern void malloc_dump(void);
+extern void malloc_walk(size_t source, size_t printf_enabled);
+extern void libc_init(int reentrant);
+extern int host_errno(void);
+extern void fix_syscall_errno(void);
+extern size_t malloc_free_space();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h
new file mode 100644
index 0000000000..4b5e000bea
--- /dev/null
+++ b/cpukit/libcsupport/include/rtems/libio.h
@@ -0,0 +1,645 @@
+/**
+ * @file rtems/libio.h
+ */
+
+/*
+ * System call and file system interface definition
+ *
+ * General purpose communication channel for RTEMS to allow UNIX/POSIX
+ * system call behavior under RTEMS. Initially this supported only
+ * IO to devices but has since been enhanced to support networking
+ * and support for mounted file systems.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_LIBIO_H
+#define _RTEMS_RTEMS_LIBIO_H
+
+#include <rtems.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+/*
+ * Define data types which must be constructed using forward references.
+ */
+
+#include <rtems/fs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Valid RTEMS file types.
+ */
+
+#define RTEMS_FILESYSTEM_DIRECTORY 1
+#define RTEMS_FILESYSTEM_DEVICE 2
+#define RTEMS_FILESYSTEM_HARD_LINK 3
+#define RTEMS_FILESYSTEM_SYM_LINK 4
+#define RTEMS_FILESYSTEM_MEMORY_FILE 5
+typedef int rtems_filesystem_node_types_t;
+
+/*
+ * File Handler Operations Table
+ */
+
+typedef int (*rtems_filesystem_open_t)(
+ rtems_libio_t *iop,
+ const char *pathname,
+ uint32_t flag,
+ uint32_t mode
+);
+
+typedef int (*rtems_filesystem_close_t)(
+ rtems_libio_t *iop
+);
+
+typedef ssize_t (*rtems_filesystem_read_t)(
+ rtems_libio_t *iop,
+ void *buffer,
+ uint32_t count
+);
+
+typedef ssize_t (*rtems_filesystem_write_t)(
+ rtems_libio_t *iop,
+ const void *buffer,
+ uint32_t count
+);
+
+typedef int (*rtems_filesystem_ioctl_t)(
+ rtems_libio_t *iop,
+ uint32_t command,
+ void *buffer
+);
+
+typedef int (*rtems_filesystem_lseek_t)(
+ rtems_libio_t *iop,
+ off_t length,
+ int whence
+);
+
+typedef int (*rtems_filesystem_fstat_t)(
+ rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+);
+
+typedef int (*rtems_filesystem_fchmod_t)(
+ rtems_filesystem_location_info_t *loc,
+ mode_t mode
+);
+
+typedef int (*rtems_filesystem_ftruncate_t)(
+ rtems_libio_t *iop,
+ off_t length
+);
+
+typedef int (*rtems_filesystem_fpathconf_t)(
+ rtems_libio_t *iop,
+ int name
+);
+
+typedef int (*rtems_filesystem_fsync_t)(
+ rtems_libio_t *iop
+);
+
+typedef int (*rtems_filesystem_fdatasync_t)(
+ rtems_libio_t *iop
+);
+
+typedef int (*rtems_filesystem_fcntl_t)(
+ int cmd,
+ rtems_libio_t *iop
+);
+
+typedef int (*rtems_filesystem_rmnod_t)(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+struct _rtems_filesystem_file_handlers_r {
+ rtems_filesystem_open_t open_h;
+ rtems_filesystem_close_t close_h;
+ rtems_filesystem_read_t read_h;
+ rtems_filesystem_write_t write_h;
+ rtems_filesystem_ioctl_t ioctl_h;
+ rtems_filesystem_lseek_t lseek_h;
+ rtems_filesystem_fstat_t fstat_h;
+ rtems_filesystem_fchmod_t fchmod_h;
+ rtems_filesystem_ftruncate_t ftruncate_h;
+ rtems_filesystem_fpathconf_t fpathconf_h;
+ rtems_filesystem_fsync_t fsync_h;
+ rtems_filesystem_fdatasync_t fdatasync_h;
+ rtems_filesystem_fcntl_t fcntl_h;
+ rtems_filesystem_rmnod_t rmnod_h;
+};
+
+/*
+ * File System Operations Table
+ */
+
+/*
+ * XXX
+ * This routine does not allocate any space and rtems_filesystem_freenode_t
+ * is not called by the generic after calling this routine.
+ * ie. node_access does not have to contain valid data when the
+ * routine returns.
+ */
+
+typedef int (*rtems_filesystem_mknod_t)(
+ const char *path, /* IN */
+ mode_t mode, /* IN */
+ dev_t dev, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+);
+
+/*
+ * rtems_filesystem_freenode_t must be called by the generic after
+ * calling this routine
+ */
+
+typedef int (*rtems_filesystem_evalpath_t)(
+ const char *pathname, /* IN */
+ int flags, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+);
+
+typedef int (*rtems_filesystem_evalmake_t)(
+ const char *path, /* IN */
+ rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
+ const char **name /* OUT */
+);
+
+typedef int (*rtems_filesystem_link_t)(
+ rtems_filesystem_location_info_t *to_loc, /* IN */
+ rtems_filesystem_location_info_t *parent_loc, /* IN */
+ const char *name /* IN */
+);
+
+typedef int (*rtems_filesystem_unlink_t)(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+typedef int (*rtems_filesystem_chown_t)(
+ rtems_filesystem_location_info_t *pathloc, /* IN */
+ uid_t owner, /* IN */
+ gid_t group /* IN */
+);
+
+typedef int (*rtems_filesystem_freenode_t)(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+typedef int (* rtems_filesystem_mount_t ) (
+ rtems_filesystem_mount_table_entry_t *mt_entry /* in */
+);
+
+typedef int (* rtems_filesystem_fsmount_me_t )(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+typedef int (* rtems_filesystem_unmount_t ) (
+ rtems_filesystem_mount_table_entry_t *mt_entry /* in */
+);
+
+typedef int (* rtems_filesystem_fsunmount_me_t ) (
+ rtems_filesystem_mount_table_entry_t *mt_entry /* in */
+);
+
+typedef rtems_filesystem_node_types_t (* rtems_filesystem_node_type_t) (
+ rtems_filesystem_location_info_t *pathloc /* in */
+);
+
+typedef int (* rtems_filesystem_utime_t)(
+ rtems_filesystem_location_info_t *pathloc, /* IN */
+ time_t actime, /* IN */
+ time_t modtime /* IN */
+);
+
+typedef int (*rtems_filesystem_evaluate_link_t)(
+ rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
+ int flags /* IN */
+);
+
+typedef int (*rtems_filesystem_symlink_t)(
+ rtems_filesystem_location_info_t *loc, /* IN */
+ const char *link_name, /* IN */
+ const char *node_name
+);
+
+typedef int (*rtems_filesystem_readlink_t)(
+ rtems_filesystem_location_info_t *loc, /* IN */
+ char *buf, /* OUT */
+ size_t bufsize
+);
+
+/*
+ * operations table that must be defined for every file system.
+ */
+
+/*
+ * File system types
+ */
+struct _rtems_filesystem_operations_table {
+ rtems_filesystem_evalpath_t evalpath_h;
+ rtems_filesystem_evalmake_t evalformake_h;
+ rtems_filesystem_link_t link_h;
+ rtems_filesystem_unlink_t unlink_h;
+ rtems_filesystem_node_type_t node_type_h;
+ rtems_filesystem_mknod_t mknod_h;
+ rtems_filesystem_chown_t chown_h;
+ rtems_filesystem_freenode_t freenod_h;
+ rtems_filesystem_mount_t mount_h;
+ rtems_filesystem_fsmount_me_t fsmount_me_h;
+ rtems_filesystem_unmount_t unmount_h;
+ rtems_filesystem_fsunmount_me_t fsunmount_me_h;
+ rtems_filesystem_utime_t utime_h;
+ rtems_filesystem_evaluate_link_t eval_link_h;
+ rtems_filesystem_symlink_t symlink_h;
+ rtems_filesystem_readlink_t readlink_h;
+};
+
+#if 0
+/* Now in exec/include/rtems/fs.h */
+
+/*
+ * Structure used to determine a location/filesystem in the tree.
+ */
+
+struct rtems_filesystem_location_info_tt
+{
+ void *node_access;
+ rtems_filesystem_file_handlers_r *handlers;
+ rtems_filesystem_operations_table *ops;
+ rtems_filesystem_mount_table_entry_t *mt_entry;
+};
+#endif
+
+/*
+ * Structure used to contain file system specific information which
+ * is required to support fpathconf().
+ */
+
+typedef struct {
+ int link_max;
+ int max_canon;
+ int max_input;
+ int name_max;
+ int path_max;
+ int pipe_buf;
+ int posix_async_io;
+ int posix_chown_restrictions;
+ int posix_no_trunc;
+ int posix_prio_io;
+ int posix_sync_io;
+ int posix_vdisable;
+} rtems_filesystem_limits_and_options_t;
+
+/*
+ * Structure for a mount table entry.
+ */
+
+struct rtems_filesystem_mount_table_entry_tt {
+ Chain_Node Node;
+ rtems_filesystem_location_info_t mt_point_node;
+ rtems_filesystem_location_info_t mt_fs_root;
+ int options;
+ void *fs_info;
+
+ rtems_filesystem_limits_and_options_t pathconf_limits_and_options;
+
+ /*
+ * When someone adds a mounted filesystem on a real device,
+ * this will need to be used.
+ *
+ * The best option long term for this is probably an open file descriptor.
+ */
+ char *dev;
+};
+
+/*
+ * Valid RTEMS file systems options
+ */
+
+typedef enum
+{
+ RTEMS_FILESYSTEM_READ_ONLY,
+ RTEMS_FILESYSTEM_READ_WRITE,
+ RTEMS_FILESYSTEM_BAD_OPTIONS
+} rtems_filesystem_options_t;
+
+
+/*
+ * An open file data structure, indexed by 'fd'
+ * TODO:
+ * should really have a separate per/file data structure that this
+ * points to (eg: size, offset, driver, pathname should be in that)
+ */
+
+struct rtems_libio_tt {
+ rtems_driver_name_t *driver;
+ off_t size; /* size of file */
+ off_t offset; /* current offset into file */
+ uint32_t flags;
+ rtems_filesystem_location_info_t pathinfo;
+ rtems_id sem;
+ uint32_t data0; /* private to "driver" */
+ void *data1; /* ... */
+ void *file_info; /* used by file handlers */
+ rtems_filesystem_file_handlers_r *handlers; /* type specific handlers */
+};
+
+/*
+ * param block for read/write
+ * Note: it must include 'offset' instead of using iop's offset since
+ * we can have multiple outstanding i/o's on a device.
+ */
+
+typedef struct {
+ rtems_libio_t *iop;
+ off_t offset;
+ char *buffer;
+ uint32_t count;
+ uint32_t flags;
+ uint32_t bytes_moved;
+} rtems_libio_rw_args_t;
+
+/*
+ * param block for open/close
+ */
+
+typedef struct {
+ rtems_libio_t *iop;
+ uint32_t flags;
+ uint32_t mode;
+} rtems_libio_open_close_args_t;
+
+/*
+ * param block for ioctl
+ */
+
+typedef struct {
+ rtems_libio_t *iop;
+ uint32_t command;
+ void *buffer;
+ uint32_t ioctl_return;
+} rtems_libio_ioctl_args_t;
+
+/*
+ * Values for 'flag'
+ */
+
+#define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */
+#define LIBIO_FLAGS_READ 0x0002 /* reading */
+#define LIBIO_FLAGS_WRITE 0x0004 /* writing */
+#define LIBIO_FLAGS_OPEN 0x0100 /* device is open */
+#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
+#define LIBIO_FLAGS_CREATE 0x0400 /* create file */
+#define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800 /* close on process exec() */
+#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
+
+void rtems_libio_init(void);
+
+/*
+ * External I/O handlers
+ */
+
+typedef int (*rtems_libio_open_t)(
+ const char *pathname,
+ uint32_t flag,
+ uint32_t mode
+);
+
+typedef int (*rtems_libio_close_t)(
+ int fd
+);
+
+typedef int (*rtems_libio_read_t)(
+ int fd,
+ void *buffer,
+ uint32_t count
+);
+
+typedef int (*rtems_libio_write_t)(
+ int fd,
+ const void *buffer,
+ uint32_t count
+);
+
+typedef int (*rtems_libio_ioctl_t)(
+ int fd,
+ uint32_t command,
+ void *buffer
+);
+
+typedef int (*rtems_libio_lseek_t)(
+ int fd,
+ off_t offset,
+ int whence
+);
+
+/*
+ * The following macros are used to build up the permissions sets
+ * used to check permissions. These are similar in style to the
+ * mode_t bits and should stay compatible with them.
+ */
+
+#define RTEMS_LIBIO_PERMS_READ S_IROTH
+#define RTEMS_LIBIO_PERMS_WRITE S_IWOTH
+#define RTEMS_LIBIO_PERMS_RDWR (S_IROTH|S_IWOTH)
+#define RTEMS_LIBIO_PERMS_EXEC S_IXOTH
+#define RTEMS_LIBIO_PERMS_SEARCH RTEMS_LIBIO_PERMS_EXEC
+#define RTEMS_LIBIO_PERMS_RWX S_IRWXO
+
+/*
+ * Macros
+ */
+
+#if 0
+#define rtems_filesystem_make_dev_t( _major, _minor ) \
+ ((((dev_t)(_major)) << 32) | (dev_t)(_minor))
+
+#define rtems_filesystem_dev_major_t( _dev ) \
+ (rtems_device_major_number) ((_dev) >> 32)
+
+#define rtems_filesystem_dev_minor_t( _dev ) \
+ (rtems_device_minor_number) ((_dev) & 0xFFFFFFFF)
+#else
+
+#include <unistd.h>
+
+union __rtems_dev_t {
+ dev_t device;
+ struct {
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+ } __overlay;
+};
+
+static inline dev_t rtems_filesystem_make_dev_t(
+ rtems_device_major_number _major,
+ rtems_device_minor_number _minor
+)
+{
+ union __rtems_dev_t temp;
+
+ temp.__overlay.major = _major;
+ temp.__overlay.minor = _minor;
+ return temp.device;
+}
+
+static inline rtems_device_major_number rtems_filesystem_dev_major_t(
+ dev_t device
+)
+{
+ union __rtems_dev_t temp;
+
+ temp.device = device;
+ return temp.__overlay.major;
+}
+
+
+static inline rtems_device_minor_number rtems_filesystem_dev_minor_t(
+ dev_t device
+)
+{
+ union __rtems_dev_t temp;
+
+ temp.device = device;
+ return temp.__overlay.minor;
+}
+
+#endif
+
+#define rtems_filesystem_split_dev_t( _dev, _major, _minor ) \
+ do { \
+ (_major) = rtems_filesystem_dev_major_t ( _dev ); \
+ (_minor) = rtems_filesystem_dev_minor_t( _dev ); \
+ } while(0)
+
+/*
+ * Verifies that the permission flag is valid.
+ */
+#define rtems_libio_is_valid_perms( _perm ) \
+ (~ ((~RTEMS_LIBIO_PERMS_RWX) & _perm ))
+
+
+/*
+ * Prototypes for filesystem
+ */
+
+void rtems_filesystem_initialize( void );
+
+
+/*
+ * Callbacks from TERMIOS routines to device-dependent code
+ */
+
+#include <termios.h>
+
+typedef struct rtems_termios_callbacks {
+ int (*firstOpen)(int major, int minor, void *arg);
+ int (*lastClose)(int major, int minor, void *arg);
+ int (*pollRead)(int minor);
+ int (*write)(int minor, const char *buf, int len);
+ int (*setAttributes)(int minor, const struct termios *t);
+ int (*stopRemoteTx)(int minor);
+ int (*startRemoteTx)(int minor);
+ int outputUsesInterrupts;
+} rtems_termios_callbacks;
+
+/*
+ * Device-independent TERMIOS routines
+ */
+
+void rtems_termios_initialize (void);
+
+/*
+ * CCJ: Change before opening a tty. Newer code from Eric is coming
+ * so extra work to handle an open tty is not worth it. If the tty
+ * is open, close then open it again.
+ */
+rtems_status_code rtems_termios_bufsize (
+ int cbufsize, /* cooked buffer size */
+ int raw_input, /* raw input buffer size */
+ int raw_output /* raw output buffer size */
+);
+
+rtems_status_code rtems_termios_open (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg,
+ const rtems_termios_callbacks *callbacks
+);
+
+rtems_status_code rtems_termios_close(
+ void *arg
+);
+
+rtems_status_code rtems_termios_read(
+ void *arg
+);
+
+rtems_status_code rtems_termios_write(
+ void *arg
+);
+
+rtems_status_code rtems_termios_ioctl(
+ void *arg
+);
+
+int rtems_termios_enqueue_raw_characters(
+ void *ttyp,
+ char *buf,
+ int len
+);
+
+int rtems_termios_dequeue_characters(
+ void *ttyp,
+ int len
+);
+
+void rtems_termios_reserve_resources(
+ rtems_configuration_table *configuration,
+ uint32_t number_of_devices
+);
+
+int unmount(
+ const char *mount_path
+);
+
+int mount(
+ rtems_filesystem_mount_table_entry_t **mt_entry,
+ rtems_filesystem_operations_table *fs_ops,
+ rtems_filesystem_options_t fsoptions,
+ char *device,
+ char *mount_point
+);
+
+/*
+ * Boot Time Mount Table Structure
+ */
+
+typedef struct {
+ rtems_filesystem_operations_table *fs_ops;
+ rtems_filesystem_options_t fsoptions;
+ char *device;
+ char *mount_point;
+} rtems_filesystem_mount_table_t;
+
+extern rtems_filesystem_mount_table_t *rtems_filesystem_mount_table;
+extern int rtems_filesystem_mount_table_size;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_LIBIO_H */
diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h
new file mode 100644
index 0000000000..7fd1280e28
--- /dev/null
+++ b/cpukit/libcsupport/include/rtems/libio_.h
@@ -0,0 +1,258 @@
+/**
+ * @file rtems/libio_.h
+ */
+
+/*
+ * Libio Internal Information
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_LIBIO__H
+#define _RTEMS_RTEMS_LIBIO__H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h> /* include before standard IO */
+
+#include <sys/types.h>
+
+#include <errno.h>
+
+/*
+ * Semaphore to protect the io table
+ */
+
+#define RTEMS_LIBIO_SEM rtems_build_name('L', 'B', 'I', 'O')
+#define RTEMS_LIBIO_IOP_SEM(n) rtems_build_name('L', 'B', 'I', n)
+
+extern rtems_id rtems_libio_semaphore;
+extern rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers;
+
+/*
+ * File descriptor Table Information
+ */
+
+extern uint32_t rtems_libio_number_iops;
+extern rtems_libio_t *rtems_libio_iops;
+extern rtems_libio_t *rtems_libio_last_iop;
+extern rtems_libio_t *rtems_libio_iop_freelist;
+
+/*
+ * rtems_libio_iop
+ *
+ * Macro to return the file descriptor pointer.
+ */
+
+#define rtems_libio_iop(_fd) \
+ ((((uint32_t )(_fd)) < rtems_libio_number_iops) ? \
+ &rtems_libio_iops[_fd] : 0)
+
+/*
+ * rtems_libio_iop_to_descriptor
+ *
+ * Macro to convert an internal file descriptor pointer (iop) into
+ * the integer file descriptor used by the "section 2" system calls.
+ */
+
+#define rtems_libio_iop_to_descriptor(_iop) \
+ ((!(_iop)) ? -1 : (_iop - rtems_libio_iops))
+
+/*
+ * rtems_libio_check_is_open
+ *
+ * Macro to check if a file descriptor is actually open.
+ */
+
+#define rtems_libio_check_is_open(_iop) \
+ do { \
+ if (((_iop)->flags & LIBIO_FLAGS_OPEN) == 0) { \
+ errno = EBADF; \
+ return -1; \
+ } \
+ } while (0)
+
+/*
+ * rtems_libio_check_fd
+ *
+ * Macro to check if a file descriptor number is valid.
+ */
+
+#define rtems_libio_check_fd(_fd) \
+ do { \
+ if ((uint32_t ) (_fd) >= rtems_libio_number_iops) { \
+ errno = EBADF; \
+ return -1; \
+ } \
+ } while (0)
+
+/*
+ * rtems_libio_check_buffer
+ *
+ * Macro to check if a buffer pointer is valid.
+ */
+
+#define rtems_libio_check_buffer(_buffer) \
+ do { \
+ if ((_buffer) == 0) { \
+ errno = EINVAL; \
+ return -1; \
+ } \
+ } while (0)
+
+/*
+ * rtems_libio_check_count
+ *
+ * Macro to check if a count or length is valid.
+ */
+
+#define rtems_libio_check_count(_count) \
+ do { \
+ if ((_count) == 0) { \
+ return 0; \
+ } \
+ } while (0)
+
+/*
+ * rtems_libio_check_permissions
+ *
+ * Macro to check if a file descriptor is open for this operation.
+ */
+
+#define rtems_libio_check_permissions(_iop, _flag) \
+ do { \
+ if (((_iop)->flags & (_flag)) == 0) { \
+ rtems_set_errno_and_return_minus_one( EINVAL ); \
+ return -1; \
+ } \
+ } while (0)
+
+/*
+ * rtems_filesystem_freenode
+ *
+ * Macro to free a node.
+ */
+
+#define rtems_filesystem_freenode( _node ) \
+ do { \
+ if ( (_node)->ops )\
+ if ( (_node)->ops->freenod_h ) \
+ (*(_node)->ops->freenod_h)( (_node) ); \
+ } while (0)
+
+/*
+ * rtems_filesystem_is_separator
+ *
+ * Macro to determine if a character is a path name separator.
+ *
+ * NOTE: This macro handles MS-DOS and UNIX style names.
+ */
+
+#define rtems_filesystem_is_separator( _ch ) \
+ ( ((_ch) == '/') || ((_ch) == '\\') || ((_ch) == '\0'))
+
+/*
+ * rtems_filesystem_get_start_loc
+ *
+ * Macro to determine if path is absolute or relative.
+ */
+
+#define rtems_filesystem_get_start_loc( _path, _index, _loc ) \
+ do { \
+ if ( rtems_filesystem_is_separator( (_path)[ 0 ] ) ) { \
+ *(_loc) = rtems_filesystem_root; \
+ *(_index) = 1; \
+ } else { \
+ *(_loc) = rtems_filesystem_current; \
+ *(_index) = 0; \
+ } \
+ } while (0)
+
+#define rtems_filesystem_get_sym_start_loc( _path, _index, _loc ) \
+ do { \
+ if ( rtems_filesystem_is_separator( (_path)[ 0 ] ) ) { \
+ *(_loc) = rtems_filesystem_root; \
+ *(_index) = 1; \
+ } else { \
+ *(_index) = 0; \
+ } \
+ } while (0)
+
+
+/*
+ * External structures
+ */
+#include <rtems/userenv.h>
+
+extern rtems_user_env_t * rtems_current_user_env;
+extern rtems_user_env_t rtems_global_user_env;
+
+/*
+ * Instantiate a private copy of the per user information for the calling task.
+ */
+
+rtems_status_code rtems_libio_set_private_env(void);
+rtems_status_code rtems_libio_share_private_env(rtems_id task_id) ;
+
+/*
+ * File Descriptor Routine Prototypes
+ */
+
+rtems_libio_t *rtems_libio_allocate(void);
+
+uint32_t rtems_libio_fcntl_flags(
+ uint32_t fcntl_flags
+);
+
+uint32_t rtems_libio_to_fcntl_flags(
+ uint32_t flags
+);
+
+void rtems_libio_free(
+ rtems_libio_t *iop
+);
+
+int rtems_libio_is_open_files_in_fs(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+int rtems_libio_is_file_open(
+ void *node_access
+);
+
+/*
+ * File System Routine Prototypes
+ */
+
+int rtems_filesystem_evaluate_path(
+ const char *pathname,
+ int flags,
+ rtems_filesystem_location_info_t *pathloc,
+ int follow_link
+);
+
+int rtems_filesystem_evaluate_parent(
+ int flags,
+ rtems_filesystem_location_info_t *pathloc
+);
+
+void rtems_filesystem_initialize();
+
+int init_fs_mount_table();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libcsupport/include/rtems/termiostypes.h b/cpukit/libcsupport/include/rtems/termiostypes.h
new file mode 100644
index 0000000000..67233895d4
--- /dev/null
+++ b/cpukit/libcsupport/include/rtems/termiostypes.h
@@ -0,0 +1,181 @@
+/**
+ * @file rtems/termiostypes.h
+ */
+
+/*
+ * RTEMS termios device support internal data structures
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef TERMIOSTYPES_H
+#define TERMIOSTYPES_H
+
+#include <rtems.h>
+#include <rtems/libio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Wakeup callback data structure
+ */
+struct ttywakeup {
+ void (*sw_pfn)(struct termios *tty, void *arg);
+ void *sw_arg;
+};
+
+/*
+ * Variables associated with the character buffer
+ */
+struct rtems_termios_rawbuf {
+ char *theBuf;
+ volatile unsigned int Head;
+ volatile unsigned int Tail;
+ volatile unsigned int Size;
+ rtems_id Semaphore;
+};
+/*
+ * Variables associated with each termios instance.
+ * One structure for each hardware I/O device.
+ */
+struct rtems_termios_tty {
+ /*
+ * Linked-list of active TERMIOS devices
+ */
+ struct rtems_termios_tty *forw;
+ struct rtems_termios_tty *back;
+
+ /*
+ * How many times has this device been opened
+ */
+ int refcount;
+
+ /*
+ * This device
+ */
+ rtems_device_major_number major;
+ rtems_device_major_number minor;
+
+ /*
+ * Mutual-exclusion semaphores
+ */
+ rtems_id isem;
+ rtems_id osem;
+
+ /*
+ * The canonical (cooked) character buffer
+ */
+ char *cbuf;
+ int ccount;
+ int cindex;
+
+ /*
+ * Keep track of cursor (printhead) position
+ */
+ int column;
+ int read_start_column;
+
+ /*
+ * The ioctl settings
+ */
+ struct termios termios;
+ rtems_interval vtimeTicks;
+
+ /*
+ * Raw input character buffer
+ */
+ struct rtems_termios_rawbuf rawInBuf;
+ uint32_t rawInBufSemaphoreOptions;
+ rtems_interval rawInBufSemaphoreTimeout;
+ rtems_interval rawInBufSemaphoreFirstTimeout;
+ unsigned int rawInBufDropped; /* Statistics */
+
+ /*
+ * Raw output character buffer
+ */
+ struct rtems_termios_rawbuf rawOutBuf;
+ int t_dqlen; /* count of characters dequeued from device */
+ enum {rob_idle, rob_busy, rob_wait } rawOutBufState;
+
+ /*
+ * Callbacks to device-specific routines
+ */
+ rtems_termios_callbacks device;
+ volatile unsigned int flow_ctrl;
+ unsigned int lowwater,highwater;
+
+ /*
+ * I/O task IDs (for task-driven drivers)
+ */
+ rtems_id rxTaskId;
+ rtems_id txTaskId;
+ /*
+ * line discipline related stuff
+ */
+ int t_line; /* id of line discipline */
+ void *t_sc; /* hook for discipline-specific data structure */
+ /*
+ * Wakeup callback variables
+ */
+ struct ttywakeup tty_snd;
+ struct ttywakeup tty_rcv;
+ int tty_rcvwakeup;
+};
+
+struct linesw {
+ int (*l_open) (struct rtems_termios_tty *tp);
+ int (*l_close)(struct rtems_termios_tty *tp);
+ int (*l_read )(struct rtems_termios_tty *tp,rtems_libio_rw_args_t *args);
+ int (*l_write)(struct rtems_termios_tty *tp,rtems_libio_rw_args_t *args);
+ int (*l_rint )(int c,struct rtems_termios_tty *tp);
+ int (*l_start)(struct rtems_termios_tty *tp);
+ int (*l_ioctl)(struct rtems_termios_tty *tp,rtems_libio_ioctl_args_t *args);
+ int (*l_modem)(struct rtems_termios_tty *tp,int flags);
+};
+
+/*
+ * FIXME: this should move to libio.h!
+ * values for rtems_termios_callbacks.outputUsesInterrupts
+ */
+#define TERMIOS_POLLED 0
+#define TERMIOS_IRQ_DRIVEN 1
+#define TERMIOS_TASK_DRIVEN 2
+
+
+/*
+ * FIXME: this should move to termios.h!
+ */
+void rtems_termios_rxirq_occured(struct rtems_termios_tty *tty);
+/*
+ * FIXME: this should move to termios.h!
+ * put a string to output ring buffer
+ */
+void rtems_termios_puts (const void *buf,
+ int len,
+ struct rtems_termios_tty *tty);
+/*
+ * global hooks for line disciplines
+ */
+extern struct linesw linesw[];
+extern int nlinesw;
+
+#define TTYDISC 0 /* termios tty line discipline */
+#define TABLDISC 3 /* tablet discipline */
+#define SLIPDISC 4 /* serial IP discipline */
+#define PPPDISC 5 /* PPP discipline */
+#define MAXLDISC 8
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TERMIOSTYPES_H */
diff --git a/cpukit/libcsupport/include/spurious.h b/cpukit/libcsupport/include/spurious.h
new file mode 100644
index 0000000000..97ed533831
--- /dev/null
+++ b/cpukit/libcsupport/include/spurious.h
@@ -0,0 +1,42 @@
+/**
+ * @file rtems/spurious.h
+ */
+
+/* spurious.h
+ *
+ * This file describes the Spurious Interrupt Driver for all boards.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SPURIOUS_H
+#define _RTEMS_SPURIOUS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SPURIOUS_DRIVER_TABLE_ENTRY \
+ { Spurious_Initialize, NULL, NULL, NULL, NULL, NULL }
+
+rtems_device_driver Spurious_Initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *,
+ rtems_id,
+ uint32_t *
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libcsupport/include/stdint.h b/cpukit/libcsupport/include/stdint.h
new file mode 100644
index 0000000000..16ec546e95
--- /dev/null
+++ b/cpukit/libcsupport/include/stdint.h
@@ -0,0 +1,284 @@
+/*
+ * COPYRIGHT (c) 2004.
+ * Ralf Corsepius, Ulm/Germany.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ *
+ * $Id$
+ */
+
+/** @file stdint.h
+ * Newlib specific stdint.h
+ *
+ * @todo - Add fast<N>_t types.
+ * @todo - Add support for wint_t types.
+ */
+
+#ifndef _STDINT_H
+#define _STDINT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__GNUC__) && (__GNUC__ >= 3 ) \
+ && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 2 )
+#define __EXP(x) __##x##__
+#else
+#define __EXP(x) x
+#include <limits.h>
+#endif
+
+#if __EXP(SCHAR_MAX) == 0x7f
+typedef signed char int8_t ;
+typedef unsigned char uint8_t ;
+#define __int8_t_defined 1
+#endif
+
+#if __int8_t_defined
+typedef signed char int_least8_t;
+typedef unsigned char uint_least8_t;
+#define __int_least8_t_defined 1
+#endif
+
+#if __EXP(SHRT_MAX) == 0x7fff
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+#define __int16_t_defined 1
+#elif __EXP(INT_MAX) == 0x7fff
+typedef signed int int16_t;
+typedef unsigned int uint16_t;
+#define __int16_t_defined 1
+#elif __EXP(SCHAR_MAX) == 0x7fff
+typedef signed char int16_t;
+typedef unsigned char uint16_t;
+#define __int16_t_defined 1
+#endif
+
+#if __int16_t_defined
+typedef int16_t int_least16_t;
+typedef uint16_t uint_least16_t;
+#define __int_least16_t_defined 1
+
+#ifndef __int_least8_t_defined
+typedef int16_t int_least8_t;
+typedef uint16_t uint_least8_t;
+#define __int_least8_t_defined 1
+#endif
+#endif
+
+#if __EXP(INT_MAX) == 0x7fffffffL
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+#define __int32_t_defined 1
+#elif __EXP(LONG_MAX) == 0x7fffffffL
+typedef signed long int32_t;
+typedef unsigned long uint32_t;
+#define __int32_t_defined 1
+#define __rtems_long32 1
+#elif __EXP(SHRT_MAX) == 0x7fffffffL
+typedef signed short int32_t;
+typedef unsigned short uint32_t;
+#define __int32_t_defined 1
+#elif __EXP(SCHAR_MAX) == 0x7fffffffL
+typedef signed char int32_t;
+typedef unsigned char uint32_t;
+#define __int32_t_defined 1
+#endif
+
+#if __int32_t_defined
+typedef int32_t int_least32_t;
+typedef uint32_t uint_least32_t;
+#define __int_least32_t_defined 1
+
+#ifndef __int_least8_t_defined
+typedef int32_t int_least8_t;
+typedef uint32_t uint_least8_t;
+#define __int_least8_t_defined 1
+#endif
+
+#ifndef __int_least16_t_defined
+typedef int32_t int_least16_t;
+typedef uint32_t uint_least16_t;
+#define __int_least16_t_defined 1
+#endif
+#endif
+
+#if __EXP(LONG_MAX) > 0x7fffffff
+typedef signed long int64_t;
+typedef unsigned long uint64_t;
+#define __int64_t_defined 1
+#define __rtems_long64 1
+#elif defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff)
+typedef signed long long int64_t;
+typedef unsigned long long uint64_t;
+#define __int64_t_defined 1
+#define __rtems_longlong64 1
+#elif defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff)
+typedef signed long long int64_t;
+typedef unsigned long long uint64_t;
+#define __int64_t_defined 1
+#define __rtems_longlong64 1
+#elif __EXP(INT_MAX) > 0x7fffffff
+typedef signed int int64_t;
+typedef unsigned int uint64_t;
+#define __int64_t_defined 1
+#endif
+
+#if __int64_t_defined
+typedef int64_t int_least64_t;
+typedef uint64_t uint_least64_t;
+#define __int_least64_t_defined 1
+
+#ifndef __int_least8_t_defined
+typedef int64_t int_least8_t;
+typedef uint64_t uint_least8_t;
+#define __int_least8_t_defined 1
+#endif
+
+#ifndef __int_least16_t_defined
+typedef int64_t int_least16_t;
+typedef uint64_t uint_least16_t;
+#define __int_least16_t_defined 1
+#endif
+
+#ifndef __int_least32_t_defined
+typedef int64_t int_least32_t;
+typedef uint64_t uint_least32_t;
+#define __int_least32_t_defined 1
+#endif
+#endif
+
+#if __rtems_longlong64
+typedef signed long long intmax_t;
+typedef unsigned long long uintmax_t;
+#else
+typedef signed long intmax_t;
+typedef unsigned long uintmax_t;
+#endif
+
+/*
+ * GCC doesn't provide an propriate macro for [u]intptr_t
+ * For now, use __PTRDIFF_TYPE__
+ */
+#if defined(__PTRDIFF_TYPE__)
+typedef signed __PTRDIFF_TYPE__ intptr_t;
+typedef unsigned __PTRDIFF_TYPE__ uintptr_t;
+#else
+/* Fallback to hardcoded values, valid on cpu's with 32bit int/32bit void* */
+typedef signed long intptr_t;
+typedef unsigned long uintptr_t;
+#endif
+
+/* Limits of Specified-Width Integer Types */
+
+#if __int8_t_defined
+#define INT8_MIN -128
+#define INT8_MAX 127
+#define UINT8_MAX 255
+#endif
+
+#if __int_least8_t_defined
+#define INTLEAST8_MIN -128
+#define INTLEAST8_MAX 127
+#define UINTLEAST8_MAX 255
+#else
+#error required type int_least8_t missing
+#endif
+
+#if __int16_t_defined
+#define INT16_MIN -32768
+#define INT16_MAX 32767
+#define UINT16_MAX 65535
+#endif
+
+#if __int_least16_t_defined
+#define INTLEAST16_MIN -32768
+#define INTLEAST16_MAX 32767
+#define UINTLEAST16_MAX 65535
+#else
+#error required type int_least16_t missing
+#endif
+
+#if __int32_t_defined
+#define INT32_MIN -2147483648
+#define INT32_MAX 2147483647
+#define UINT32_MAX 4294967295
+#endif
+
+#if __int_least32_t_defined
+#define INTLEAST32_MIN -2147483648
+#define INTLEAST32_MAX 2147483647
+#define UINTLEAST32_MAX 4294967295
+#else
+#error required type int_least32_t missing
+#endif
+
+#if __int64_t_defined
+#define INT64_MIN -9223372036854775808
+#define INT64_MAX 9223372036854775807
+#define UINT64_MAX 18446744073709551615
+#endif
+
+#if __int_least64_t_defined
+#define INTLEAST64_MIN -9223372036854775808
+#define INTLEAST64_MAX 9223372036854775807
+#define UINTLEAST64_MAX 18446744073709551615
+#endif
+
+/* This must match size_t in stddef.h, currently long unsigned int */
+#define SIZE_MIN (-__EXP(LONG_MAX) - 1L)
+#define SIZE_MAX __EXP(LONG_MAX)
+
+/* This must match sig_atomic_t in <signal.h> (currently int) */
+#define SIG_ATOMIC_MIN (-__EXP(INT_MAX) - 1)
+#define SIG_ATOMIC_MAX __EXP(INT_MAX)
+
+/* This must match ptrdiff_t in <stddef.h> (currently long int) */
+#define PTRDIFF_MIN (-__EXP(LONG_MAX) - 1L)
+#define PTHDIFF_MAX __EXT(LONG_MAX)
+
+#undef __EXP
+
+/** Macros for minimum-width integer constant expressions */
+#define INT8_C(x) x
+#define UINT8_C(x) x##U
+
+#define INT16_C(x) x
+#define UINT16_C(x) x##U
+
+#if __rtems_long32
+#define INT32_C(x) x##L
+#define UINT32_C(x) x##UL
+#else
+#define INT32_C(x) x
+#define UINT32_C(x) x##U
+#endif
+
+#if __int64_t_defined
+#if __rtems_longlong64
+#define INT64_C(x) x##LL
+#define UINT64_C(x) x##ULL
+#else
+#define INT64_C(x) x##L
+#define UINT64_C(x) x##UL
+#endif
+#endif
+
+/** Macros for greatest-width integer constant expression */
+#if __rtems_longlong64
+#define INTMAX_C(x) x##LL
+#define UINTMAX_C(x) x##ULL
+#else
+#define INTMAX_C(x) x##L
+#define UINTMAX_C(x) x##UL
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STDINT_H */
diff --git a/cpukit/libcsupport/include/sys/cdefs.h b/cpukit/libcsupport/include/sys/cdefs.h
new file mode 100644
index 0000000000..0cbc601929
--- /dev/null
+++ b/cpukit/libcsupport/include/sys/cdefs.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Berkeley Software Design, Inc.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)cdefs.h 8.8 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/sys/cdefs.h,v 1.87 2005/03/07 15:40:25 stefanf Exp $
+ */
+
+/*
+ * $Id$
+ */
+#ifndef _SYS_CDEFS_H_
+#define _SYS_CDEFS_H_
+
+#if defined(__cplusplus)
+#define __BEGIN_DECLS extern "C" {
+#define __END_DECLS }
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+
+/*
+ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+ * The __CONCAT macro is a bit tricky -- make sure you don't put spaces
+ * in between its arguments. __CONCAT can also concatenate double-quoted
+ * strings produced by the __STRING macro, but this only works with ANSI C.
+ *
+ * __XSTRING is like __STRING, but it expands any macros in its argument
+ * first. It is only available with ANSI C.
+ */
+#if defined(__STDC__) || defined(__cplusplus)
+#define __P(protos) protos /* full-blown ANSI C */
+#define __CONCAT1(x,y) x ## y
+#define __CONCAT(x,y) __CONCAT1(x,y)
+#define __STRING(x) #x /* stringify without expanding x */
+#define __XSTRING(x) __STRING(x) /* expand x, then stringify */
+
+#define __const const /* define reserved names to standard */
+#define __signed signed
+#define __volatile volatile
+#if defined(__cplusplus)
+#define __inline inline /* convert to C++ keyword */
+#else
+#ifndef __GNUC__
+#define __inline /* delete GCC keyword */
+#endif /* !__GNUC__ */
+#endif /* !__cplusplus */
+
+#else /* !(__STDC__ || __cplusplus) */
+#define __P(protos) () /* traditional C preprocessor */
+#define __CONCAT(x,y) x/**/y
+#define __STRING(x) "x"
+
+#ifndef __GNUC__
+#define __const /* delete pseudo-ANSI C keywords */
+#define __inline
+#define __signed
+#define __volatile
+/*
+ * In non-ANSI C environments, new programs will want ANSI-only C keywords
+ * deleted from the program and old programs will want them left alone.
+ * When using a compiler other than gcc, programs using the ANSI C keywords
+ * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
+ * When using "gcc -traditional", we assume that this is the intent; if
+ * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
+ */
+#ifndef NO_ANSI_KEYWORDS
+#define const /* delete ANSI C keywords */
+#define inline
+#define signed
+#define volatile
+#endif /* !NO_ANSI_KEYWORDS */
+#endif /* !__GNUC__ */
+#endif /* !(__STDC__ || __cplusplus) */
+
+/*
+ * GCC1 and some versions of GCC2 declare dead (non-returning) and
+ * pure (no side effects) functions using "volatile" and "const";
+ * unfortunately, these then cause warnings under "-ansi -pedantic".
+ * GCC2.5 uses a new, peculiar __attribute__((attrs)) style. All of
+ * these work for GNU C++ (modulo a slight glitch in the C++ grammar
+ * in the distribution version of 2.5.5).
+ */
+#if __GNUC__ < 2
+#define __dead
+#define __dead2
+#define __pure
+#define __pure2
+#define __unused
+#define __used
+#define __attribute__(x)
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ < 5
+#define __dead __volatile
+#define __dead2
+#define __pure __const
+#define __pure2
+#define __unused
+#define __used
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7
+#define __dead
+#define __dead2 __attribute__((__noreturn__))
+#define __pure
+#define __pure2 __attribute__((__const__))
+#define __unused
+#define __used
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ >= 3
+#define __dead
+#define __dead2 __attribute__((__noreturn__))
+#define __pure
+#define __pure2 __attribute__((__const__))
+#define __unused __attribute__((__unused__))
+#define __used __attribute__((__used__))
+#endif
+
+#ifdef __GNUC__
+#ifdef __STDC__
+#define __weak_reference(sym,alias) \
+ __asm__(".stabs \"_" #alias "\",11,0,0,0"); \
+ __asm__(".stabs \"_" #sym "\",1,0,0,0")
+#define __warn_references(sym,msg) \
+ __asm__(".stabs \"" msg "\",30,0,0,0"); \
+ __asm__(".stabs \"_" #sym "\",1,0,0,0")
+#else
+#define __weak_reference(sym,alias) \
+ __asm__(".stabs \"_/**/alias\",11,0,0,0"); \
+ __asm__(".stabs \"_/**/sym\",1,0,0,0")
+#define __warn_references(sym,msg) \
+ __asm__(".stabs msg,30,0,0,0"); \
+ __asm__(".stabs \"_/**/sym\",1,0,0,0")
+#endif
+#endif
+
+#define __IDSTRING(name,string) \
+ static const char name[] __attribute__((__unused__)) = string
+
+#ifndef __RCSID
+#define __RCSID(s) __IDSTRING(rcsid,s)
+#endif
+
+#ifndef __RCSID_SOURCE
+#define __RCSID_SOURCE(s) __IDSTRING(rcsid_source,s)
+#endif
+
+#ifndef __COPYRIGHT
+#define __COPYRIGHT(s) __IDSTRING(copyright,s)
+#endif
+
+#endif /* !_SYS_CDEFS_H_ */
diff --git a/cpukit/libcsupport/include/sys/filio.h b/cpukit/libcsupport/include/sys/filio.h
new file mode 100644
index 0000000000..5a8b7e4bbb
--- /dev/null
+++ b/cpukit/libcsupport/include/sys/filio.h
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ *
+ * @(#)filio.h 8.1 (Berkeley) 3/28/94
+ * $Id$
+ */
+
+#ifndef _SYS_FILIO_H_
+#define _SYS_FILIO_H_
+
+#include <sys/ioccom.h>
+
+/* RTEMS defines all of these in sys/ioccom.h */
+#if 0
+/* Generic file-descriptor ioctl's. */
+#define FIOCLEX _IO('f', 1) /* set close on exec on fd */
+#define FIONCLEX _IO('f', 2) /* remove close on exec */
+#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
+#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
+#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */
+#define FIOSETOWN _IOW('f', 124, int) /* set owner */
+#define FIOGETOWN _IOR('f', 123, int) /* get owner */
+#endif
+
+#endif /* !_SYS_FILIO_H_ */
diff --git a/cpukit/libcsupport/include/sys/ioccom.h b/cpukit/libcsupport/include/sys/ioccom.h
new file mode 100644
index 0000000000..c6437856f2
--- /dev/null
+++ b/cpukit/libcsupport/include/sys/ioccom.h
@@ -0,0 +1,99 @@
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993, 1994
+ * 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.
+ * 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.
+ *
+ * @(#)ioccom.h 8.2 (Berkeley) 3/28/94
+ * $FreeBSD: src/sys/sys/ioccom.h,v 1.15 2004/04/07 04:19:49 imp Exp $
+ */
+/*
+ * $Id$
+ */
+
+#ifndef _SYS_IOCCOM_H_
+#define _SYS_IOCCOM_H_
+
+#include <sys/types.h>
+
+/*
+ * Ioctl's have the command encoded in the lower word, and the size of
+ * any in or out parameters in the upper word. The high 3 bits of the
+ * upper word are used to encode the in/out status of the parameter.
+ */
+#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */
+#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
+#define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16))
+#define IOCGROUP(x) (((x) >> 8) & 0xff)
+
+#define IOCPARM_MAX PAGE_SIZE /* max size of ioctl, mult. of PAGE_SIZE */
+#define IOC_VOID 0x20000000 /* no parameters */
+#define IOC_OUT 0x40000000 /* copy out parameters */
+#define IOC_IN 0x80000000 /* copy in parameters */
+#define IOC_INOUT (IOC_IN|IOC_OUT)
+#define IOC_DIRMASK 0xe0000000 /* mask for IN/OUT/VOID */
+
+#define _IOC(inout,group,num,len) \
+ ((u_int32_t)inout | \
+ (u_int32_t) ((u_int32_t)((u_int32_t)len & IOCPARM_MASK) << 16) | \
+ (u_int32_t)((group) << 8) | \
+ (u_int32_t)(num))
+#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0)
+#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t))
+#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t))
+/* this should be _IORW, but stdio got there first */
+#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t))
+
+/*
+ * IOCTL values
+ */
+
+#define RTEMS_IO_GET_ATTRIBUTES 1
+#define RTEMS_IO_SET_ATTRIBUTES 2
+#define RTEMS_IO_TCDRAIN 3
+#define RTEMS_IO_RCVWAKEUP 4
+#define RTEMS_IO_SNDWAKEUP 5
+
+/* copied from libnetworking/sys/filio.h and commented out there */
+/* Generic file-descriptor ioctl's. */
+#define FIOCLEX _IO('f', 1) /* set close on exec on fd */
+#define FIONCLEX _IO('f', 2) /* remove close on exec */
+#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
+#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
+#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */
+#define FIOSETOWN _IOW('f', 124, int) /* set owner */
+#define FIOGETOWN _IOR('f', 123, int) /* get owner */
+
+#ifndef KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int ioctl(int, int, ...);
+__END_DECLS
+
+#endif /* !KERNEL */
+
+#endif /* !_SYS_IOCCOM_H_ */
diff --git a/cpukit/libcsupport/include/sys/ioctl.h b/cpukit/libcsupport/include/sys/ioctl.h
new file mode 100644
index 0000000000..55e77d2ba2
--- /dev/null
+++ b/cpukit/libcsupport/include/sys/ioctl.h
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)ioctl.h 8.6 (Berkeley) 3/28/94
+ * $FreeBSD: src/sys/sys/ioctl.h,v 1.13 2004/06/11 11:16:26 phk Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _SYS_IOCTL_H_
+#define _SYS_IOCTL_H_
+
+#include <sys/ttycom.h>
+
+/*
+ * Pun for SunOS prior to 3.2. SunOS 3.2 and later support TIOCGWINSZ
+ * and TIOCSWINSZ (yes, even 3.2-3.5, the fact that it wasn't documented
+ * notwithstanding).
+ */
+struct ttysize {
+ unsigned short ts_lines;
+ unsigned short ts_cols;
+ unsigned short ts_xxx;
+ unsigned short ts_yyy;
+};
+#define TIOCGSIZE TIOCGWINSZ
+#define TIOCSSIZE TIOCSWINSZ
+
+#include <sys/ioccom.h>
+
+#include <sys/filio.h>
+#include <sys/sockio.h>
+
+#endif /* !_SYS_IOCTL_H_ */
diff --git a/cpukit/libcsupport/include/sys/sockio.h b/cpukit/libcsupport/include/sys/sockio.h
new file mode 100644
index 0000000000..5e54baffe8
--- /dev/null
+++ b/cpukit/libcsupport/include/sys/sockio.h
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993, 1994
+ * 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.
+ *
+ * @(#)sockio.h 8.1 (Berkeley) 3/28/94
+ * $Id$
+ */
+
+#ifndef _SYS_SOCKIO_H_
+#define _SYS_SOCKIO_H_
+
+#include <sys/ioccom.h>
+
+/* Socket ioctl's. */
+#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */
+#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */
+#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */
+#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */
+#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */
+#define SIOCSPGRP _IOW('s', 8, int) /* set process group */
+#define SIOCGPGRP _IOR('s', 9, int) /* get process group */
+
+#define SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */
+#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */
+#define SIOCGETVIFCNT _IOWR('r', 15, struct sioc_vif_req)/* get vif pkt cnt */
+#define SIOCGETSGCNT _IOWR('r', 16, struct sioc_sg_req) /* get s,g pkt cnt */
+
+#define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */
+#define OSIOCGIFADDR _IOWR('i', 13, struct ifreq) /* get ifnet address */
+#define SIOCGIFADDR _IOWR('i', 33, struct ifreq) /* get ifnet address */
+#define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */
+#define OSIOCGIFDSTADDR _IOWR('i', 15, struct ifreq) /* get p-p address */
+#define SIOCGIFDSTADDR _IOWR('i', 34, struct ifreq) /* get p-p address */
+#define SIOCSIFFLAGS _IOW('i', 16, struct ifreq) /* set ifnet flags */
+#define SIOCGIFFLAGS _IOWR('i', 17, struct ifreq) /* get ifnet flags */
+#define OSIOCGIFBRDADDR _IOWR('i', 18, struct ifreq) /* get broadcast addr */
+#define SIOCGIFBRDADDR _IOWR('i', 35, struct ifreq) /* get broadcast addr */
+#define SIOCSIFBRDADDR _IOW('i', 19, struct ifreq) /* set broadcast addr */
+#define OSIOCGIFCONF _IOWR('i', 20, struct ifconf) /* get ifnet list */
+#define SIOCGIFCONF _IOWR('i', 36, struct ifconf) /* get ifnet list */
+#define OSIOCGIFNETMASK _IOWR('i', 21, struct ifreq) /* get net addr mask */
+#define SIOCGIFNETMASK _IOWR('i', 37, struct ifreq) /* get net addr mask */
+#define SIOCSIFNETMASK _IOW('i', 22, struct ifreq) /* set net addr mask */
+#define SIOCGIFMETRIC _IOWR('i', 23, struct ifreq) /* get IF metric */
+#define SIOCSIFMETRIC _IOW('i', 24, struct ifreq) /* set IF metric */
+#define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */
+#define SIOCAIFADDR _IOW('i', 26, struct ifaliasreq)/* add/chg IF alias */
+
+#define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */
+#define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */
+#define SIOCGIFMTU _IOWR('i', 51, struct ifreq) /* get IF mtu */
+#define SIOCSIFMTU _IOW('i', 52, struct ifreq) /* set IF mtu */
+#define SIOCGIFPHYS _IOWR('i', 53, struct ifreq) /* get IF wire */
+#define SIOCSIFPHYS _IOW('i', 54, struct ifreq) /* set IF wire */
+#define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */
+#define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */
+
+/*
+ * RTEMS additions for setting/getting `tap' function on incoming packets.
+ */
+#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */
+#define SIOCGIFTAP _IOW('i', 81, struct ifreq) /* get tap function */
+
+#endif /* !_SYS_SOCKIO_H_ */
diff --git a/cpukit/libcsupport/include/sys/termios.h b/cpukit/libcsupport/include/sys/termios.h
new file mode 100644
index 0000000000..f619c95709
--- /dev/null
+++ b/cpukit/libcsupport/include/sys/termios.h
@@ -0,0 +1,198 @@
+/*
+ * POSIX termios implementation for RTEMS console device driver.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef TERMIOS_H
+#define TERMIOS_H
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 19
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+
+/* c_oflag bits */
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+/* c_cflag bit meaning */
+#define CBAUD 0010017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define CIBAUD 002003600000 /* input baud rate (not used) */
+#define CRTSCTS 020000000000 /* flow control */
+
+#define RTEMS_TERMIOS_NUMBER_BAUD_RATES 20
+
+/* c_lflag bits */
+#define ISIG 0000001
+#define ICANON 0000002
+#define XCASE 0000004
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+int tcdrain(int);
+int tcflow(int, int);
+int tcflush(int, int);
+int tcgetattr(int, struct termios *);
+int tcsetattr(int, int, struct termios *);
+int tcdrain(int);
+pid_t tcgetprgrp(int);
+int tcsetprgrp(int, pid_t);
+int tcsendbreak(int, int);
+
+speed_t cfgetospeed(const struct termios *tp);
+int cfsetospeed(struct termios *tp, speed_t speed);
+speed_t cfgetispeed(const struct termios *tp);
+int cfsetispeed(struct termios *tp, speed_t speed);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TERMIOS_H */
diff --git a/cpukit/libcsupport/include/sys/ttycom.h b/cpukit/libcsupport/include/sys/ttycom.h
new file mode 100644
index 0000000000..f2e491bc50
--- /dev/null
+++ b/cpukit/libcsupport/include/sys/ttycom.h
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ *
+ * @(#)ttycom.h 8.1 (Berkeley) 3/28/94
+ * $Id$
+ */
+
+#ifndef _SYS_TTYCOM_H_
+#define _SYS_TTYCOM_H_
+
+#include <sys/ioccom.h>
+
+/*
+ * Tty ioctl's except for those supported only for backwards compatibility
+ * with the old tty driver.
+ */
+
+/*
+ * Window/terminal size structure. This information is stored by the kernel
+ * in order to provide a consistent interface, but is not used by the kernel.
+ */
+struct winsize {
+ unsigned short ws_row; /* rows, in characters */
+ unsigned short ws_col; /* columns, in characters */
+ unsigned short ws_xpixel; /* horizontal size, pixels */
+ unsigned short ws_ypixel; /* vertical size, pixels */
+};
+
+#define TIOCMODG _IOR('t', 3, int) /* get modem control state */
+#define TIOCMODS _IOW('t', 4, int) /* set modem control state */
+#define TIOCM_LE 0001 /* line enable */
+#define TIOCM_DTR 0002 /* data terminal ready */
+#define TIOCM_RTS 0004 /* request to send */
+#define TIOCM_ST 0010 /* secondary transmit */
+#define TIOCM_SR 0020 /* secondary receive */
+#define TIOCM_CTS 0040 /* clear to send */
+#define TIOCM_CAR 0100 /* carrier detect */
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RNG 0200 /* ring */
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_DSR 0400 /* data set ready */
+ /* 8-10 compat */
+#define TIOCEXCL _IO('t', 13) /* set exclusive use of tty */
+#define TIOCNXCL _IO('t', 14) /* reset exclusive use of tty */
+ /* 15 unused */
+#define TIOCFLUSH _IOW('t', 16, int) /* flush buffers */
+ /* 17-18 compat */
+#define TIOCGETA _IOR('t', 19, struct termios) /* get termios struct */
+#define TIOCSETA _IOW('t', 20, struct termios) /* set termios struct */
+#define TIOCSETAW _IOW('t', 21, struct termios) /* drain output, set */
+#define TIOCSETAF _IOW('t', 22, struct termios) /* drn out, fls in, set */
+#define TIOCGETD _IOR('t', 26, int) /* get line discipline */
+#define TIOCSETD _IOW('t', 27, int) /* set line discipline */
+ /* 127-124 compat */
+#define TIOCSBRK _IO('t', 123) /* set break bit */
+#define TIOCCBRK _IO('t', 122) /* clear break bit */
+#define TIOCSDTR _IO('t', 121) /* set data terminal ready */
+#define TIOCCDTR _IO('t', 120) /* clear data terminal ready */
+#define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */
+#define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */
+ /* 117-116 compat */
+#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
+#define TIOCSTI _IOW('t', 114, char) /* simulate terminal input */
+#define TIOCNOTTY _IO('t', 113) /* void tty association */
+#define TIOCPKT _IOW('t', 112, int) /* pty: set/clear packet mode */
+#define TIOCPKT_DATA 0x00 /* data packet */
+#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */
+#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */
+#define TIOCPKT_STOP 0x04 /* stop output */
+#define TIOCPKT_START 0x08 /* start output */
+#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */
+#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */
+#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */
+#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
+#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
+#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */
+#define TIOCMBIS _IOW('t', 108, int) /* bis modem bits */
+#define TIOCMBIC _IOW('t', 107, int) /* bic modem bits */
+#define TIOCMGET _IOR('t', 106, int) /* get all modem bits */
+#define TIOCREMOTE _IOW('t', 105, int) /* remote input editing */
+#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */
+#define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */
+#define TIOCUCNTL _IOW('t', 102, int) /* pty: set/clr usr cntl mode */
+#define TIOCSTAT _IO('t', 101) /* simulate ^T status message */
+#define UIOCCMD(n) _IO('u', n) /* usr cntl op "n" */
+#define TIOCCONS _IOW('t', 98, int) /* become virtual console */
+#define TIOCSCTTY _IO('t', 97) /* become controlling tty */
+#define TIOCEXT _IOW('t', 96, int) /* pty: external processing */
+#define TIOCSIG _IO('t', 95) /* pty: generate signal */
+#define TIOCDRAIN _IO('t', 94) /* wait till output drained */
+#define TIOCMSDTRWAIT _IOW('t', 91, int) /* modem: set wait on close */
+#define TIOCMGDTRWAIT _IOR('t', 90, int) /* modem: get wait on close */
+#define TIOCTIMESTAMP _IOR('t', 89, struct timeval) /* enable/get timestamp
+ * of last input event */
+#define TIOCDCDTIMESTAMP _IOR('t', 88, struct timeval) /* enable/get timestamp
+ * of last DCd rise */
+#define TIOCSDRAINWAIT _IOW('t', 87, int) /* set ttywait timeout */
+#define TIOCGDRAINWAIT _IOR('t', 86, int) /* get ttywait timeout */
+#define TIOCDSIMICROCODE _IO('t', 85) /* download microcode to
+ * DSI Softmodem */
+
+#define TTYDISC 0 /* termios tty line discipline */
+#define TABLDISC 3 /* tablet discipline */
+#define SLIPDISC 4 /* serial IP discipline */
+#define PPPDISC 5 /* PPP discipline */
+
+#endif /* !_SYS_TTYCOM_H_ */
diff --git a/cpukit/libcsupport/include/sys/utsname.h b/cpukit/libcsupport/include/sys/utsname.h
new file mode 100644
index 0000000000..ebe2f52785
--- /dev/null
+++ b/cpukit/libcsupport/include/sys/utsname.h
@@ -0,0 +1,55 @@
+/* sys/utsname.h
+ *
+ * $Id$
+ */
+
+#ifndef __POSIX_SYS_UTSNAME_h
+#define __POSIX_SYS_UTSNAME_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/times.h>
+#include <sys/types.h>
+
+/*
+ * 4.4.1 Get System Name (Table 4-1), P1003.1b-1993, p. 90
+ *
+ * NOTE: The lengths of the strings in this structure are
+ * just long enough to reliably contain the RTEMS information.
+ * For example, the fields are not long enough to support
+ * Internet hostnames.
+ */
+
+struct utsname {
+ char sysname[ 32 ]; /* Name of this implementation of the operating system */
+ char nodename[ 32 ]; /* Name of this node within an implementation */
+ /* specified communication network */
+ char release[ 32 ]; /* Current release level of this implementation */
+ char version[ 32 ]; /* Current version level of this release */
+ char machine[ 32 ]; /* Name of the hardware type on which the system */
+ /* is running */
+};
+
+/*
+ * 4.4.1 Get System Name, P1003.1b-1993, p. 90
+ */
+
+int uname(
+ struct utsname *name
+);
+
+/*
+ * 4.5.2 Get Process Times, P1003.1b-1993, p. 92
+ */
+
+clock_t times(
+ struct tms *buffer
+);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* end of include file */
diff --git a/cpukit/libcsupport/include/tar.h b/cpukit/libcsupport/include/tar.h
new file mode 100644
index 0000000000..a8e9938d6d
--- /dev/null
+++ b/cpukit/libcsupport/include/tar.h
@@ -0,0 +1,47 @@
+/*
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ *
+ * $Id$
+ */
+
+/** @file tar.h
+ * Newlib specific tar.h
+ */
+
+#ifndef _TAR_H
+#define _TAR_H
+
+/* General definitions */
+#define TMAGIC "ustar" /* ustar plus null byte. */
+#define TMAGLEN 6 /* Length of the above. */
+#define TVERSION "00" /* 00 without a null byte. */
+#define TVERSLEN 2 /* Length of the above. */
+
+/* Typeflag field definitions */
+#define REGTYPE '0' /* Regular file. */
+#define AREGTYPE '\0' /* Regular file. */
+#define LNKTYPE '1' /* Link. */
+#define SYMTYPE '2' /* Symbolic link. */
+#define CHRTYPE '3' /* Character special. */
+#define BLKTYPE '4' /* Block special. */
+#define DIRTYPE '5' /* Directory. */
+#define FIFOTYPE '6' /* FIFO special. */
+#define CONTTYPE '7' /* Reserved. */
+
+/* Mode field bit definitions (octal) */
+#define TSUID 04000 /* Set UID on execution. */
+#define TSGID 02000 /* Set GID on execution. */
+#define TSVTX 01000 /* On directories, restricted deletion flag. */
+#define TUREAD 00400 /* Read by owner. */
+#define TUWRITE 00200 /* Write by owner. */
+#define TUEXEC 00100 /* Execute/search by owner. */
+#define TGREAD 00040 /* Read by group. */
+#define TGWRITE 00020 /* Write by group. */
+#define TGEXEC 00010 /* Execute/search by group. */
+#define TOREAD 00004 /* Read by other. */
+#define TOWRITE 00002 /* Write by other. */
+#define TOEXEC 00001 /* Execute/search by other. */
+
+#endif
diff --git a/cpukit/libcsupport/include/timerdrv.h b/cpukit/libcsupport/include/timerdrv.h
new file mode 100644
index 0000000000..7547a683ec
--- /dev/null
+++ b/cpukit/libcsupport/include/timerdrv.h
@@ -0,0 +1,42 @@
+/**
+ * @file rtems/timerdrv.h
+ *
+ * This file describes the Timer Driver for all boards.
+ */
+
+/*
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_TIMERDRV_H
+#define _RTEMS_TIMERDRV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* functions */
+
+void Timer_initialize( void );
+
+uint32_t Read_timer( void );
+
+rtems_status_code Empty_function( void );
+
+void Set_find_average_overhead(
+ rtems_boolean find_flag
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libcsupport/include/vmeintr.h b/cpukit/libcsupport/include/vmeintr.h
new file mode 100644
index 0000000000..73d07efebe
--- /dev/null
+++ b/cpukit/libcsupport/include/vmeintr.h
@@ -0,0 +1,59 @@
+/**
+ * @file rtems/vmeintr.h
+ *
+ * This file is the specification for the VMEbus interface library
+ * which should be provided by all BSPs for VMEbus Single Board
+ * Computers but currently only a few do so.
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_VMEINTR_H
+#define _RTEMS_VMEINTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This defines the mask which is used to determine which
+ * interrupt levels are affected by a call to this package.
+ * The LSB corresponds to VME interrupt 0 and the MSB
+ * to VME interrupt 7.
+ *
+ */
+
+typedef uint8_t VME_interrupt_Mask;
+
+/*
+ * VME_interrupt_Disable
+ *
+ */
+
+void VME_interrupt_Disable (
+ VME_interrupt_Mask mask /* IN */
+);
+
+/*
+ * VME_interrupt_Disable
+ *
+ */
+
+void VME_interrupt_Enable (
+ VME_interrupt_Mask mask /* IN */
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of include file */
diff --git a/cpukit/libcsupport/include/zilog/z8036.h b/cpukit/libcsupport/include/zilog/z8036.h
new file mode 100644
index 0000000000..7a2bba2324
--- /dev/null
+++ b/cpukit/libcsupport/include/zilog/z8036.h
@@ -0,0 +1,106 @@
+/**
+ * @file rtems/zilog/z8036.h
+ */
+
+/*
+ * This include file defines information related to a Zilog Z8036
+ * Counter/Timer/IO Chip. It is a memory mapped part.
+ *
+ * NOTE: This file shares as much as possible with the include
+ * file for the Z8536 via z8x36.h.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ZILOG_Z8036_H
+#define _RTEMS_ZILOG_Z8036_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* macros */
+
+#define Z8036( ptr ) ((volatile struct z8036_map *)(ptr))
+
+#define Z8x36_STATE0 ( z8036 ) \
+ { /*char *garbage = *(Z8036(z8036))->???; */ }
+
+
+#define Z8x36_WRITE( z8036, reg, data ) \
+ (Z8036(z8036))->reg = (data)
+
+
+#define Z8x36_READ( z8036, reg, data ) \
+ (Z8036(z8036))->reg = (data)
+
+/* structures */
+
+struct z8036_map {
+/* MAIN CONTROL REGISTERS (0x00-0x07) */
+ uint8_t MASTER_INTR; /* Master Interrupt Ctl Reg */
+ uint8_t MASTER_CFG; /* Master Configuration Ctl Reg */
+ uint8_t PORTA_VECTOR; /* Port A - Interrupt Vector */
+ uint8_t PORTB_VECTOR; /* Port B - Interrupt Vector */
+ uint8_t CNT_TMR_VECTOR; /* Counter/Timer Interrupt Vector */
+ uint8_t PORTC_DATA_POLARITY; /* Port C - Data Path Polarity */
+ uint8_t PORTC_DIRECTION; /* Port C - Data Direction */
+ uint8_t PORTC_SPECIAL_IO_CTL; /* Port C - Special IO Control */
+/* MOST OFTEN ACCESSED REGISTERS (0x08 - 0x0f) */
+ uint8_t PORTA_CMD_STATUS; /* Port A - Command Status Reg */
+ uint8_t PORTB_CMD_STATUS; /* Port B - Command Status Reg */
+ uint8_t CT1_CMD_STATUS; /* Ctr/Timer 1 - Command Status Reg */
+ uint8_t CT2_CMD_STATUS; /* Ctr/Timer 2 - Command Status Reg */
+ uint8_t CT3_CMD_STATUS; /* Ctr/Timer 3 - Command Status Reg */
+ uint8_t PORTA_DATA; /* Port A - Data */
+ uint8_t PORTB_DATA; /* Port B - Data */
+ uint8_t PORTC_DATA; /* Port C - Data */
+/* COUNTER/TIMER RELATED REGISTERS (0x10-0x1f) */
+ uint8_t CT1_CUR_CNT_MSB; /* Ctr/Timer 1 - Current Count (MSB) */
+ uint8_t CT1_CUR_CNT_LSB; /* Ctr/Timer 1 - Current Count (LSB) */
+ uint8_t CT2_CUR_CNT_MSB; /* Ctr/Timer 2 - Current Count (MSB) */
+ uint8_t CT2_CUR_CNT_LSB; /* Ctr/Timer 2 - Current Count (LSB) */
+ uint8_t CT3_CUR_CNT_MSB; /* Ctr/Timer 3 - Current Count (MSB) */
+ uint8_t CT3_CUR_CNT_LSB; /* Ctr/Timer 3 - Current Count (LSB) */
+ uint8_t CT1_TIME_CONST_MSB; /* Ctr/Timer 1 - Time Constant (MSB) */
+ uint8_t CT1_TIME_CONST_LSB; /* Ctr/Timer 1 - Time Constant (LSB) */
+ uint8_t CT2_TIME_CONST_MSB; /* Ctr/Timer 2 - Time Constant (MSB) */
+ uint8_t CT2_TIME_CONST_LSB; /* Ctr/Timer 2 - Time Constant (LSB) */
+ uint8_t CT3_TIME_CONST_MSB; /* Ctr/Timer 3 - Time Constant (MSB) */
+ uint8_t CT3_TIME_CONST_LSB; /* Ctr/Timer 3 - Time Constant (LSB) */
+ uint8_t CT1_MODE_SPEC; /* Ctr/Timer 1 - Mode Specification */
+ uint8_t CT2_MODE_SPEC; /* Ctr/Timer 2 - Mode Specification */
+ uint8_t CT3_MODE_SPEC; /* Ctr/Timer 3 - Mode Specification */
+ uint8_t CURRENT_VECTOR; /* Current Vector */
+/* PORT A SPECIFICATION REGISTERS (0x20 -0x27) */
+ uint8_t PORTA_MODE; /* Port A - Mode Specification */
+ uint8_t PORTA_HANDSHAKE; /* Port A - Handshake Specification */
+ uint8_t PORTA_DATA_POLARITY; /* Port A - Data Path Polarity */
+ uint8_t PORTA_DIRECTION; /* Port A - Data Direction */
+ uint8_t PORTA_SPECIAL_IO_CTL; /* Port A - Special IO Control */
+ uint8_t PORTA_PATT_POLARITY; /* Port A - Pattern Polarity */
+ uint8_t PORTA_PATT_TRANS; /* Port A - Pattern Transition */
+ uint8_t PORTA_PATT_MASK; /* Port A - Pattern Mask */
+/* PORT B SPECIFICATION REGISTERS (0x28-0x2f) */
+ uint8_t PORTB_MODE; /* Port B - Mode Specification */
+ uint8_t PORTB_HANDSHAKE; /* Port B - Handshake Specification */
+ uint8_t PORTB_DATA_POLARITY; /* Port B - Data Path Polarity */
+ uint8_t PORTB_DIRECTION; /* Port B - Data Direction */
+ uint8_t PORTB_SPECIAL_IO_CTL; /* Port B - Special IO Control */
+ uint8_t PORTB_PATT_POLARITY; /* Port B - Pattern Polarity */
+ uint8_t PORTB_PATT_TRANS; /* Port B - Pattern Transition */
+ uint8_t PORTB_PATT_MASK; /* Port B - Pattern Mask */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libcsupport/include/zilog/z8530.h b/cpukit/libcsupport/include/zilog/z8530.h
new file mode 100644
index 0000000000..13c63536c4
--- /dev/null
+++ b/cpukit/libcsupport/include/zilog/z8530.h
@@ -0,0 +1,97 @@
+/**
+ * @file rtems/zilog/z8530.h
+ */
+
+/*
+ * This include file defines information related to a Zilog Z8530
+ * SCC Chip. It is a IO mapped part.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ZILOG_Z8530_H
+#define _RTEMS_ZILOG_Z8530_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* macros */
+
+#define VOL8( ptr ) ((volatile uint8_t *)(ptr))
+
+#define Z8x30_STATE0 ( z8530 ) \
+ { char *garbage; \
+ (garbage) = *(VOL8(z8530)) \
+ }
+
+#define Z8x30_WRITE_CONTROL( z8530, reg, data ) \
+ *(VOL8(z8530)) = (reg); \
+ *(VOL8(z8530)) = (data)
+
+#define Z8x30_READ_CONTROL( z8530, reg, data ) \
+ *(VOL8(z8530)) = (reg); \
+ (data) = *(VOL8(z8530))
+
+#define Z8x30_WRITE_DATA( z8530, data ) \
+ *(VOL8(z8530)) = (data);
+
+#define Z8x30_READ_DATA( z8530, data ) \
+ (data) = *(VOL8(z8530));
+
+
+/* RR_0 Bit Definitions */
+
+#define RR_0_TX_BUFFER_EMPTY 0x04
+#define RR_0_RX_DATA_AVAILABLE 0x01
+
+/* read registers */
+
+#define RR_0 0x00
+#define RR_1 0x01
+#define RR_2 0x02
+#define RR_3 0x03
+#define RR_4 0x04
+#define RR_5 0x05
+#define RR_6 0x06
+#define RR_7 0x07
+#define RR_8 0x08
+#define RR_9 0x09
+#define RR_10 0x0A
+#define RR_11 0x0B
+#define RR_12 0x0C
+#define RR_13 0x0D
+#define RR_14 0x0E
+#define RR_15 0x0F
+
+/* write registers */
+
+#define WR_0 0x00
+#define WR_1 0x01
+#define WR_2 0x02
+#define WR_3 0x03
+#define WR_4 0x04
+#define WR_5 0x05
+#define WR_6 0x06
+#define WR_7 0x07
+#define WR_8 0x08
+#define WR_9 0x09
+#define WR_10 0x0A
+#define WR_11 0x0B
+#define WR_12 0x0C
+#define WR_13 0x0D
+#define WR_14 0x0E
+#define WR_15 0x0F
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libcsupport/include/zilog/z8536.h b/cpukit/libcsupport/include/zilog/z8536.h
new file mode 100644
index 0000000000..b67bd4cf9c
--- /dev/null
+++ b/cpukit/libcsupport/include/zilog/z8536.h
@@ -0,0 +1,114 @@
+/**
+ * @file rtems/zilog/z8536.h
+ */
+
+/*
+ * This include file defines information related to a Zilog Z8536
+ * Counter/Timer/IO Chip. It is a IO mapped part.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * NOTE: This file shares as much as possible with the include
+ * file for the Z8036 via z8x36.h.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ZILOG_Z8536_H
+#define _RTEMS_ZILOG_Z8536_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* macros */
+
+#define VOL8( ptr ) ((volatile uint8_t *)(ptr))
+
+#define Z8x36_STATE0 ( z8536 ) \
+ { char *garbage; \
+ (garbage) = *(VOL8(z8536+0xC)) \
+ }
+
+#define Z8x36_WRITE( z8536, reg, data ) \
+ *(VOL8(z8536+0xC)) = (reg); \
+ *(VOL8(z8536+0xC)) = (data)
+
+#define Z8x36_READ( z8536, reg, data ) \
+ *(VOL8(z8536+0xC)) = (reg); \
+ (data) = *(VOL8(z8536+0xC))
+
+/* structures */
+
+/* MAIN CONTROL REGISTERS (0x00-0x07) */
+#define MASTER_INTR 0x00 /* Master Interrupt Ctl Reg */
+#define MASTER_CFG 0x01 /* Master Configuration Ctl Reg */
+#define PORTA_VECTOR 0x02 /* Port A - Interrupt Vector */
+#define PORTB_VECTOR 0x03 /* Port B - Interrupt Vector */
+#define CNT_TMR_VECTOR 0x04 /* Counter/Timer Interrupt Vector */
+#define PORTC_DATA_POLARITY 0x05 /* Port C - Data Path Polarity */
+#define PORTC_DIRECTION 0x06 /* Port C - Data Direction */
+#define PORTC_SPECIAL_IO_CTL 0x07 /* Port C - Special IO Control */
+
+/* MOST OFTEN ACCESSED REGISTERS (0x08 - 0x0f) */
+#define PORTA_CMD_STATUS 0x08 /* Port A - Command Status Reg */
+#define PORTB_CMD_STATUS 0x09 /* Port B - Command Status Reg */
+#define CT1_CMD_STATUS 0x0a /* Ctr/Timer 1 - Command Status Reg */
+#define CT2_CMD_STATUS 0x0b /* Ctr/Timer 2 - Command Status Reg */
+#define CT3_CMD_STATUS 0x0c /* Ctr/Timer 3 - Command Status Reg */
+#define PORTA_DATA 0x0d /* Port A - Data */
+#define PORTB_DATA 0x0e /* Port B - Data */
+#define PORTC_DATA 0x0f /* Port C - Data */
+
+/* COUNTER/TIMER RELATED REGISTERS (0x10-0x1f) */
+#define CT1_CUR_CNT_MSB 0x10 /* Ctr/Timer 1 - Current Count (MSB) */
+#define CT1_CUR_CNT_LSB 0x11 /* Ctr/Timer 1 - Current Count (LSB) */
+#define CT2_CUR_CNT_MSB 0x12 /* Ctr/Timer 2 - Current Count (MSB) */
+#define CT2_CUR_CNT_LSB 0x13 /* Ctr/Timer 2 - Current Count (LSB) */
+#define CT3_CUR_CNT_MSB 0x14 /* Ctr/Timer 3 - Current Count (MSB) */
+#define CT3_CUR_CNT_LSB 0x15 /* Ctr/Timer 3 - Current Count (LSB) */
+#define CT1_TIME_CONST_MSB 0x16 /* Ctr/Timer 1 - Time Constant (MSB) */
+#define CT1_TIME_CONST_LSB 0x17 /* Ctr/Timer 1 - Time Constant (LSB) */
+#define CT2_TIME_CONST_MSB 0x18 /* Ctr/Timer 2 - Time Constant (MSB) */
+#define CT2_TIME_CONST_LSB 0x19 /* Ctr/Timer 2 - Time Constant (LSB) */
+#define CT3_TIME_CONST_MSB 0x1a /* Ctr/Timer 3 - Time Constant (MSB) */
+#define CT3_TIME_CONST_LSB 0x1b /* Ctr/Timer 3 - Time Constant (LSB) */
+#define CT1_MODE_SPEC 0x1c /* Ctr/Timer 1 - Mode Specification */
+#define CT2_MODE_SPEC 0x1d /* Ctr/Timer 2 - Mode Specification */
+#define CT3_MODE_SPEC 0x1e /* Ctr/Timer 3 - Mode Specification */
+#define CURRENT_VECTOR 0x1f /* Current Vector */
+
+/* PORT A SPECIFICATION REGISTERS (0x20 -0x27) */
+#define PORTA_MODE 0x20 /* Port A - Mode Specification */
+#define PORTA_HANDSHAKE 0x21 /* Port A - Handshake Specification */
+#define PORTA_DATA_POLARITY 0x22 /* Port A - Data Path Polarity */
+#define PORTA_DIRECTION 0x23 /* Port A - Data Direction */
+#define PORTA_SPECIAL_IO_CTL 0x24 /* Port A - Special IO Control */
+#define PORTA_PATT_POLARITY 0x25 /* Port A - Pattern Polarity */
+#define PORTA_PATT_TRANS 0x26 /* Port A - Pattern Transition */
+#define PORTA_PATT_MASK 0x27 /* Port A - Pattern Mask */
+
+/* PORT B SPECIFICATION REGISTERS (0x28-0x2f) */
+#define PORTB_MODE 0x28 /* Port B - Mode Specification */
+#define PORTB_HANDSHAKE 0x29 /* Port B - Handshake Specification */
+#define PORTB_DATA_POLARITY 0x2a /* Port B - Data Path Polarity */
+#define PORTB_DIRECTION 0x2b /* Port B - Data Direction */
+#define PORTB_SPECIAL_IO_CTL 0x2c /* Port B - Special IO Control */
+#define PORTB_PATT_POLARITY 0x2d /* Port B - Pattern Polarity */
+#define PORTB_PATT_TRANS 0x2e /* Port B - Pattern Transition */
+#define PORTB_PATT_MASK 0x2f /* Port B - Pattern Mask */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libcsupport/preinstall.am b/cpukit/libcsupport/preinstall.am
new file mode 100644
index 0000000000..bc79d773df
--- /dev/null
+++ b/cpukit/libcsupport/preinstall.am
@@ -0,0 +1,114 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/chain.h: include/chain.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/chain.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/chain.h
+
+$(PROJECT_INCLUDE)/rtems/console.h: include/console.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/console.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/console.h
+
+$(PROJECT_INCLUDE)/rtems/clockdrv.h: include/clockdrv.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/clockdrv.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/clockdrv.h
+
+$(PROJECT_INCLUDE)/rtems/iosupp.h: include/iosupp.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/iosupp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/iosupp.h
+
+$(PROJECT_INCLUDE)/rtems/ringbuf.h: include/ringbuf.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/ringbuf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/ringbuf.h
+
+$(PROJECT_INCLUDE)/rtems/rtc.h: include/rtc.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtc.h
+
+$(PROJECT_INCLUDE)/rtems/spurious.h: include/spurious.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/spurious.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/spurious.h
+
+$(PROJECT_INCLUDE)/rtems/timerdrv.h: include/timerdrv.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/timerdrv.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/timerdrv.h
+
+$(PROJECT_INCLUDE)/rtems/vmeintr.h: include/vmeintr.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/vmeintr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/vmeintr.h
+
+$(PROJECT_INCLUDE)/rtems/motorola/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/motorola
+ @: > $(PROJECT_INCLUDE)/rtems/motorola/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/motorola/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/motorola/mc68230.h: include/motorola/mc68230.h $(PROJECT_INCLUDE)/rtems/motorola/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/motorola/mc68230.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/motorola/mc68230.h
+
+$(PROJECT_INCLUDE)/rtems/motorola/mc68681.h: include/motorola/mc68681.h $(PROJECT_INCLUDE)/rtems/motorola/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/motorola/mc68681.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/motorola/mc68681.h
+
+$(PROJECT_INCLUDE)/rtems/assoc.h: include/rtems/assoc.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/assoc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/assoc.h
+
+$(PROJECT_INCLUDE)/rtems/error.h: include/rtems/error.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/error.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/error.h
+
+$(PROJECT_INCLUDE)/rtems/libcsupport.h: include/rtems/libcsupport.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/libcsupport.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/libcsupport.h
+
+$(PROJECT_INCLUDE)/rtems/libio.h: include/rtems/libio.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/libio.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/libio.h
+
+$(PROJECT_INCLUDE)/rtems/libio_.h: include/rtems/libio_.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/libio_.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/libio_.h
+
+$(PROJECT_INCLUDE)/rtems/termiostypes.h: include/rtems/termiostypes.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/termiostypes.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/termiostypes.h
+
+$(PROJECT_INCLUDE)/rtems/cdefs.h: include/rtems/cdefs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/cdefs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/cdefs.h
+
+$(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/zilog
+ @: > $(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/zilog/z8036.h: include/zilog/z8036.h $(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/zilog/z8036.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/zilog/z8036.h
+
+$(PROJECT_INCLUDE)/rtems/zilog/z8530.h: include/zilog/z8530.h $(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/zilog/z8530.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/zilog/z8530.h
+
+$(PROJECT_INCLUDE)/rtems/zilog/z8536.h: include/zilog/z8536.h $(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/zilog/z8536.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/zilog/z8536.h
+
diff --git a/cpukit/libcsupport/src/CASES b/cpukit/libcsupport/src/CASES
new file mode 100644
index 0000000000..4578ae5009
--- /dev/null
+++ b/cpukit/libcsupport/src/CASES
@@ -0,0 +1,23 @@
+#
+# $Id$
+#
+
+This is a list of cases to consider when implementing a file system:
+
+
++ Given a tree of this form:
+
+ a ----- b
+ /
+ c
+
+ Where a and b are directories and c is a link to directory b. Consider
+ this sequence:
+
+ - rmdir a/b
+ - mknod c/b/x
+ - unlink c
+
+
+
+
diff --git a/cpukit/libcsupport/src/README b/cpukit/libcsupport/src/README
new file mode 100644
index 0000000000..ee7a90501e
--- /dev/null
+++ b/cpukit/libcsupport/src/README
@@ -0,0 +1,37 @@
+--
+-- $Id$
+--
+
+Overview of newlib support (newlib is from CYGNUS)
+ Each task can have its own libc state including:
+ open stdio files
+ strtok
+ multi precision arithmetic state
+ etc.
+
+ This is implemented by a reentrancy data structure for each task.
+
+ When a task is "started" (in RTEMS sense) the reentrancy structure
+ is allocated. Its address is stored in notepad[NOTEPAD_LAST].
+
+ When task is switched to, the value of global variable _impure_ptr
+ is changed to the value of the new tasks reentrancy structure.
+
+ When a task is deleted
+ atexit() processing (for that task) happens
+ task's stdio buffers are flushed
+
+ When exit(3) is called
+ calling task's atexit processing done
+ global libc state atexit processing done
+ (this will include any atexit routines installed by drivers)
+ executive is shutdown
+ causes a context switch back to bsp land
+
+
+NOTE:
+ libc extension are installed by bsp_libc_init()
+ iff we are using clock interrupts.
+ This hack is necessary to allow the tmtests to avoid
+ timing the extensions.
+
diff --git a/cpukit/libcsupport/src/TODO b/cpukit/libcsupport/src/TODO
new file mode 100644
index 0000000000..38cb012326
--- /dev/null
+++ b/cpukit/libcsupport/src/TODO
@@ -0,0 +1,14 @@
+#
+# $Id$
+#
+
++ newlib 1.8.0 has the wrong prototype for at least read() and write().
+
++ There should be a "eat it" stub for all system calls which are
+ available to make filling out an operations table easier.
+ See device_lseek() for an example of where this would be nice.
+
++ Fix strerror() so it prints all error numbers.
+
++ Check the node allocation coment in the fchdir call.
++ Add an interface somewhere for this call. \ No newline at end of file
diff --git a/cpukit/libcsupport/src/__brk.c b/cpukit/libcsupport/src/__brk.c
new file mode 100644
index 0000000000..9082f3ab70
--- /dev/null
+++ b/cpukit/libcsupport/src/__brk.c
@@ -0,0 +1,32 @@
+/*
+ * RTEMS "Broken" __brk Implementation
+ *
+ * NOTE: sbrk() is provided by each BSP.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if !defined(RTEMS_UNIX)
+
+#include <errno.h>
+
+int __brk(
+ const void *endds
+)
+{
+ errno = EINVAL;
+ return -1;
+}
+#endif
diff --git a/cpukit/libcsupport/src/__getpid.c b/cpukit/libcsupport/src/__getpid.c
new file mode 100644
index 0000000000..85a4c0b013
--- /dev/null
+++ b/cpukit/libcsupport/src/__getpid.c
@@ -0,0 +1,17 @@
+/*
+ * Some C Libraries reference this routine since they think getpid is
+ * a real system call.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+
+pid_t __getpid(void)
+{
+ return getpid();
+}
diff --git a/cpukit/libcsupport/src/__gettod.c b/cpukit/libcsupport/src/__gettod.c
new file mode 100644
index 0000000000..918c2d3109
--- /dev/null
+++ b/cpukit/libcsupport/src/__gettod.c
@@ -0,0 +1,120 @@
+/*
+ * gettimeofday() - SVR4 and BSD4.3 extension required by Newlib
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+
+#include <rtems.h>
+
+#if !defined(RTEMS_UNIX)
+#ifdef RTEMS_NEWLIB
+#include <sys/reent.h>
+#endif
+
+#include <sys/time.h>
+#include <time.h>
+
+#include <errno.h>
+#include <assert.h>
+
+/*
+ * Seconds from January 1, 1970 to January 1, 1988. Used to account for
+ * differences between POSIX API and RTEMS core.
+ */
+
+#define POSIX_TIME_SECONDS_1970_THROUGH_1988 \
+ (((1987 - 1970 + 1) * TOD_SECONDS_PER_NON_LEAP_YEAR) + \
+ (4 * TOD_SECONDS_PER_DAY))
+
+/*
+ * NOTE: The solaris gettimeofday does not have a second parameter.
+ */
+
+int gettimeofday(
+ struct timeval *tp,
+ struct timezone *tzp
+)
+{
+ rtems_interrupt_level level;
+ uint32_t seconds;
+ uint32_t microseconds;
+
+ if ( !tp ) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ /*
+ * POSIX does not seem to allow for not having a TOD so we just
+ * grab the time of day.
+ *
+ * NOTE: XXX this routine should really be in the executive proper.
+ */
+
+ rtems_interrupt_disable(level);
+ seconds = _TOD_Seconds_since_epoch;
+ microseconds = _TOD_Current.ticks;
+ rtems_interrupt_enable(level);
+
+ tp->tv_sec = seconds + POSIX_TIME_SECONDS_1970_THROUGH_1988;
+ tp->tv_usec = microseconds * _TOD_Microseconds_per_tick;
+
+ /*
+ * newlib does not have timezone and daylight savings time
+ * yet. When it does this needs to be fixed.
+ */
+
+#if 0
+ if ( tzp ) {
+ tzp->tz_minuteswest = 0; /* at UTC */
+ tzp->tz_dsttime = 0; /* no daylight savings */
+ tzp->minuteswest = timezone / 60; /* from seconds to minutes */
+ tzp->dsttime = daylight;
+ }
+#endif
+ return 0;
+}
+
+#if defined(RTEMS_NEWLIB)
+
+/*
+ * "Reentrant" version
+ */
+
+int _gettimeofday_r(
+ struct _reent *ignored_reentrancy_stuff,
+ struct timeval *tp,
+ struct timezone *tzp
+)
+{
+ return gettimeofday( tp, tzp );
+}
+
+/*
+ * "System call" version
+ */
+
+int _gettimeofday(
+ struct timeval *tp,
+ struct timezone *tzp
+)
+{
+ return gettimeofday( tp, tzp );
+}
+
+#endif /* defined(RTEMS_NEWLIB) */
+
+#endif
diff --git a/cpukit/libcsupport/src/__sbrk.c b/cpukit/libcsupport/src/__sbrk.c
new file mode 100644
index 0000000000..91260f1b24
--- /dev/null
+++ b/cpukit/libcsupport/src/__sbrk.c
@@ -0,0 +1,32 @@
+/*
+ * RTEMS "Broken" __sbrk Implementation
+ *
+ * NOTE: sbrk is provided by the BSP.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if !defined(RTEMS_UNIX)
+
+#include <errno.h>
+
+void * __sbrk(
+ int incr
+)
+{
+ errno = EINVAL;
+ return (void *)0;
+}
+#endif
diff --git a/cpukit/libcsupport/src/__times.c b/cpukit/libcsupport/src/__times.c
new file mode 100644
index 0000000000..733befe8c9
--- /dev/null
+++ b/cpukit/libcsupport/src/__times.c
@@ -0,0 +1,89 @@
+/*
+ * times() - POSIX 1003.1b 4.5.2 - Get Process Times
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <sys/times.h>
+#include <time.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <assert.h>
+
+clock_t _times(
+ struct tms *ptms
+)
+{
+ rtems_interval ticks;
+
+ if ( !ptms ) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ /*
+ * This call does not depend on TOD being initialized and can't fail.
+ */
+
+ (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &ticks );
+
+ /*
+ * RTEMS technically has no notion of system versus user time
+ * since there is no separation of OS from application tasks.
+ * But we can at least make a distinction between the number
+ * of ticks since boot and the number of ticks executed by this
+ * this thread.
+ */
+
+ ptms->tms_utime = _Thread_Executing->ticks_executed;
+ ptms->tms_stime = ticks;
+ ptms->tms_cutime = 0;
+ ptms->tms_cstime = 0;
+
+ return ticks;
+}
+
+/*
+ * times()
+ *
+ * times() system call wrapper for _times() above.
+ */
+
+clock_t times(
+ struct tms *ptms
+)
+{
+ return _times( ptms );
+}
+
+/*
+ * _times_r
+ *
+ * This is the Newlib dependent reentrant version of times().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+clock_t _times_r(
+ struct _reent *ptr,
+ struct tms *ptms
+)
+{
+ return _times( ptms );
+}
+#endif
diff --git a/cpukit/libcsupport/src/access.c b/cpukit/libcsupport/src/access.c
new file mode 100644
index 0000000000..7365d6db7d
--- /dev/null
+++ b/cpukit/libcsupport/src/access.c
@@ -0,0 +1,48 @@
+/*
+ * access() - POSIX 1003.1b 5.6.3 - File Accessibility
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+int access(
+ const char *path,
+ int amode
+)
+{
+ struct stat statbuf;
+
+ if ( stat(path, &statbuf) )
+ return -1;
+
+ if ( amode & R_OK ) {
+ if (!( statbuf.st_mode & S_IREAD ))
+ return -1;
+ }
+
+ if ( amode & W_OK ) {
+ if ( !( statbuf.st_mode & S_IWRITE ) )
+ return -1;
+ }
+
+ if ( amode & X_OK ) {
+ if ( !( statbuf.st_mode & S_IEXEC ) )
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/assoc.c b/cpukit/libcsupport/src/assoc.c
new file mode 100644
index 0000000000..58c0b2e73f
--- /dev/null
+++ b/cpukit/libcsupport/src/assoc.c
@@ -0,0 +1,254 @@
+/*
+ * assoc.c
+ * rtems assoc routines
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/assoc.h>
+
+#include <string.h> /* strcat, strcmp */
+
+#define STREQ(a,b) (strcmp((a), (b)) == 0)
+#define rtems_assoc_is_default(ap) ((ap)->name && STREQ(ap->name, RTEMS_ASSOC_DEFAULT_NAME))
+
+const rtems_assoc_t *
+rtems_assoc_ptr_by_name(
+ const rtems_assoc_t *ap,
+ const char *name
+ )
+{
+ const rtems_assoc_t *default_ap = 0;
+
+ if (rtems_assoc_is_default(ap))
+ default_ap = ap++;
+
+ for ( ; ap->name; ap++)
+ if (strcmp(ap->name, name) == 0)
+ return ap;
+
+ return default_ap;
+}
+
+const rtems_assoc_t *
+rtems_assoc_ptr_by_local(
+ const rtems_assoc_t *ap,
+ uint32_t local_value
+ )
+{
+ const rtems_assoc_t *default_ap = 0;
+
+ if (rtems_assoc_is_default(ap))
+ default_ap = ap++;
+
+ for ( ; ap->name; ap++)
+ if (ap->local_value == local_value)
+ return ap;
+
+ return default_ap;
+}
+
+
+const rtems_assoc_t *
+rtems_assoc_ptr_by_remote(
+ const rtems_assoc_t *ap,
+ uint32_t remote_value
+ )
+{
+ const rtems_assoc_t *default_ap = 0;
+
+ if (rtems_assoc_is_default(ap))
+ default_ap = ap++;
+
+ for ( ; ap->name; ap++)
+ if (ap->remote_value == remote_value)
+ return ap;
+
+ return default_ap;
+}
+
+
+/*
+ * Get values
+ */
+
+uint32_t
+rtems_assoc_remote_by_local(
+ const rtems_assoc_t *ap,
+ uint32_t local_value
+ )
+{
+ const rtems_assoc_t *nap;
+ nap = rtems_assoc_ptr_by_local(ap, local_value);
+ if (nap)
+ return nap->remote_value;
+
+ return 0;
+}
+
+uint32_t
+rtems_assoc_local_by_remote(
+ const rtems_assoc_t *ap,
+ uint32_t remote_value
+ )
+{
+ const rtems_assoc_t *nap;
+ nap = rtems_assoc_ptr_by_remote(ap, remote_value);
+ if (nap)
+ return nap->local_value;
+
+ return 0;
+}
+
+uint32_t
+rtems_assoc_remote_by_name(
+ const rtems_assoc_t *ap,
+ const char *name
+ )
+{
+ const rtems_assoc_t *nap;
+ nap = rtems_assoc_ptr_by_name(ap, name);
+ if (nap)
+ return nap->remote_value;
+
+ return 0;
+}
+
+uint32_t
+rtems_assoc_local_by_name(
+ const rtems_assoc_t *ap,
+ const char *name
+ )
+{
+ const rtems_assoc_t *nap;
+ nap = rtems_assoc_ptr_by_name(ap, name);
+ if (nap)
+ return nap->local_value;
+
+ return 0;
+}
+
+/*
+ * what to return if a value is not found
+ * this is not reentrant, but it really shouldn't be invoked anyway
+ */
+
+const char *rtems_assoc_name_bad(
+ uint32_t bad_value
+);
+
+/* body in separate file to reduce dependency on printf */
+
+
+const char *
+rtems_assoc_name_by_local(
+ const rtems_assoc_t *ap,
+ uint32_t local_value
+ )
+{
+ const rtems_assoc_t *nap;
+ nap = rtems_assoc_ptr_by_local(ap, local_value);
+ if (nap)
+ return nap->name;
+
+ return rtems_assoc_name_bad(local_value);
+}
+
+const char *
+rtems_assoc_name_by_remote(
+ const rtems_assoc_t *ap,
+ uint32_t remote_value
+ )
+{
+ const rtems_assoc_t *nap;
+ nap = rtems_assoc_ptr_by_remote(ap, remote_value);
+ if (nap)
+ return nap->name;
+
+ return rtems_assoc_name_bad(remote_value);
+}
+
+/*
+ * Bitfield functions assume just 1 bit set in each of remote and local
+ * entries; they do not check for this.
+ */
+
+uint32_t rtems_assoc_remote_by_local_bitfield(
+ const rtems_assoc_t *ap,
+ uint32_t local_value
+ )
+{
+ uint32_t b;
+ uint32_t remote_value = 0;
+
+ for (b = 1; b; b <<= 1)
+ if (b & local_value)
+ remote_value |= rtems_assoc_remote_by_local(ap, b);
+
+ return remote_value;
+}
+
+
+uint32_t rtems_assoc_local_by_remote_bitfield(
+ const rtems_assoc_t *ap,
+ uint32_t remote_value
+ )
+{
+ uint32_t b;
+ uint32_t local_value = 0;
+
+ for (b = 1; b; b <<= 1)
+ if (b & remote_value)
+ local_value |= rtems_assoc_local_by_remote(ap, b);
+
+ return local_value;
+}
+
+char *
+rtems_assoc_name_by_remote_bitfield(
+ const rtems_assoc_t *ap,
+ uint32_t value,
+ char *buffer
+ )
+{
+ uint32_t b;
+
+ *buffer = 0;
+
+ for (b = 1; b; b <<= 1)
+ if (b & value)
+ {
+ if (*buffer)
+ strcat(buffer, " ");
+ strcat(buffer, rtems_assoc_name_by_remote(ap, b));
+ }
+
+ return buffer;
+}
+
+char *
+rtems_assoc_name_by_local_bitfield(
+ const rtems_assoc_t *ap,
+ uint32_t value,
+ char *buffer
+ )
+{
+ uint32_t b;
+
+ *buffer = 0;
+
+ for (b = 1; b; b <<= 1)
+ if (b & value)
+ {
+ if (*buffer)
+ strcat(buffer, " ");
+ strcat(buffer, rtems_assoc_name_by_local(ap, b));
+ }
+
+ return buffer;
+}
diff --git a/cpukit/libcsupport/src/assocnamebad.c b/cpukit/libcsupport/src/assocnamebad.c
new file mode 100644
index 0000000000..d1e7191342
--- /dev/null
+++ b/cpukit/libcsupport/src/assocnamebad.c
@@ -0,0 +1,39 @@
+/*
+ * assoc.c
+ * rtems assoc routines
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/assoc.h>
+
+#include <stdio.h> /* sprintf */
+#include <string.h> /* strcat, strcmp */
+
+#define STREQ(a,b) (strcmp((a), (b)) == 0)
+#define rtems_assoc_is_default(ap) ((ap)->name && STREQ(ap->name, RTEMS_ASSOC_DEFAULT_NAME))
+
+/*
+ * what to return if a value is not found
+ * this is not reentrant, but it really shouldn't be invoked anyway
+ */
+
+const char *
+rtems_assoc_name_bad(
+ uint32_t bad_value
+)
+{
+#ifdef RTEMS_DEBUG
+ static char bad_buffer[32];
+
+ sprintf(bad_buffer, "< %d [0x%x] >", bad_value, bad_value);
+#else
+ static char bad_buffer[32] = "<assoc.c: BAD NAME>";
+#endif
+ return bad_buffer;
+}
diff --git a/cpukit/libcsupport/src/base_fs.c b/cpukit/libcsupport/src/base_fs.c
new file mode 100644
index 0000000000..e5ddb24494
--- /dev/null
+++ b/cpukit/libcsupport/src/base_fs.c
@@ -0,0 +1,132 @@
+/*
+ * Base file system initialization
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+
+/*
+ * Global information for the base file system.
+ */
+
+rtems_user_env_t rtems_global_user_env;
+rtems_user_env_t * rtems_current_user_env = &rtems_global_user_env;
+
+/*
+ * Default mode for created files.
+ */
+
+
+/*
+ * rtems_filesystem_initialize
+ *
+ * Initialize the foundation of the file system. This is specified
+ * by the structure rtems_filesystem_mount_table. The usual
+ * configuration is a single instantiation of the IMFS or miniIMFS with
+ * a single "/dev" directory in it.
+ */
+
+void rtems_filesystem_initialize( void )
+{
+#if !defined(RTEMS_UNIX)
+ int status;
+ rtems_filesystem_mount_table_entry_t *entry;
+ rtems_filesystem_mount_table_t *mt;
+ rtems_filesystem_location_info_t loc;
+
+ /*
+ * Set the default umask to "022".
+ */
+
+ rtems_filesystem_umask = 022;
+
+
+ init_fs_mount_table();
+
+ /*
+ * mount the first filesystem.
+ */
+
+ if ( rtems_filesystem_mount_table_size == 0 )
+ rtems_fatal_error_occurred( 0xABCD0001 );
+
+ mt = &rtems_filesystem_mount_table[0];
+
+ status = mount(
+ &entry, mt->fs_ops, mt->fsoptions, mt->device, mt->mount_point );
+
+ if ( status == -1 )
+ rtems_fatal_error_occurred( 0xABCD0002 );
+
+ rtems_filesystem_link_counts = 0;
+
+ /* setup the 'current' and 'root' directories
+ *
+ * NOTE: cloning the pathlocs is not strictly
+ * necessary. Since we implicitely let
+ * all threads that don't call
+ * libio_set_private_env() share the same
+ * (initial) 'root' and 'current' locs,
+ * we (also implicitely) assume that the
+ * root filesystem doesn't care about
+ * reference counts.
+ * I just inserted the code snippet below
+ * to remind everybody of the fact by
+ * making it more explicit...
+ * Ideally, every thread would have to
+ * call either share_private_env() or
+ * set_private_env() - but then: that's
+ * gonna hit performance.
+ *
+ * Till Straumann, 10/25/2002
+ */
+ rtems_filesystem_root = entry->mt_fs_root;
+ /* Clone the root pathloc */
+ rtems_filesystem_evaluate_path("/", 0, &loc, 0);
+ rtems_filesystem_root = loc;
+ /* One more clone for the current node */
+ rtems_filesystem_evaluate_path("/", 0, &loc, 0);
+ rtems_filesystem_current = loc;
+
+ /* Note: the global_env's refcnt doesn't matter
+ * as the global env is never released
+ */
+
+
+ /*
+ * Traditionally RTEMS devices are under "/dev" so install this directory.
+ *
+ * If the mkdir() fails, we can't print anything so just fatal error.
+ *
+ * NOTE: UNIX root is 755 and owned by root/root (0/0). It is actually
+ * created that way by the IMFS.
+ */
+
+ status = mkdir( "/dev", 0777);
+ if ( status != 0 )
+ rtems_fatal_error_occurred( 0xABCD0003 );
+
+ /*
+ * You can't mount another filesystem properly until the mount point
+ * it will be mounted onto is created. Moreover, if it is going to
+ * use a device, then it is REALLY unfair to attempt this
+ * before device drivers are initialized. So we return via a base
+ * filesystem image and nothing auto-mounted at this point.
+ */
+
+#endif
+}
diff --git a/cpukit/libcsupport/src/cfgetispeed.c b/cpukit/libcsupport/src/cfgetispeed.c
new file mode 100644
index 0000000000..225c7311cc
--- /dev/null
+++ b/cpukit/libcsupport/src/cfgetispeed.c
@@ -0,0 +1,32 @@
+/*
+ * cfgetispeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+
+speed_t cfgetispeed(
+ const struct termios *tp
+)
+{
+ return (tp->c_cflag / (CIBAUD / CBAUD)) & CBAUD;
+}
+#endif
diff --git a/cpukit/libcsupport/src/cfgetospeed.c b/cpukit/libcsupport/src/cfgetospeed.c
new file mode 100644
index 0000000000..e239e54758
--- /dev/null
+++ b/cpukit/libcsupport/src/cfgetospeed.c
@@ -0,0 +1,32 @@
+/*
+ * cfgetospeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+
+speed_t cfgetospeed(
+ const struct termios *tp
+)
+{
+ return tp->c_cflag & CBAUD;
+}
+#endif
diff --git a/cpukit/libcsupport/src/cfsetispeed.c b/cpukit/libcsupport/src/cfsetispeed.c
new file mode 100644
index 0000000000..383762bee1
--- /dev/null
+++ b/cpukit/libcsupport/src/cfsetispeed.c
@@ -0,0 +1,40 @@
+/*
+ * cfsetispeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int cfsetispeed(
+ struct termios *tp,
+ speed_t speed
+)
+{
+ if ( speed & ~CBAUD )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ tp->c_cflag = (tp->c_cflag & ~CIBAUD) | (speed * (CIBAUD / CBAUD));
+ return 0;
+}
+#endif
diff --git a/cpukit/libcsupport/src/cfsetospeed.c b/cpukit/libcsupport/src/cfsetospeed.c
new file mode 100644
index 0000000000..0badcbbdc7
--- /dev/null
+++ b/cpukit/libcsupport/src/cfsetospeed.c
@@ -0,0 +1,40 @@
+/*
+ * cfsetospeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int cfsetospeed(
+ struct termios *tp,
+ speed_t speed
+)
+{
+ if ( speed & ~CBAUD )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ tp->c_cflag = (tp->c_cflag & ~CBAUD) | speed;
+ return 0;
+}
+#endif
diff --git a/cpukit/libcsupport/src/chdir.c b/cpukit/libcsupport/src/chdir.c
new file mode 100644
index 0000000000..b508ea20ed
--- /dev/null
+++ b/cpukit/libcsupport/src/chdir.c
@@ -0,0 +1,61 @@
+/*
+ * chdir() - POSIX 1003.1b - 5.2.1 - Change Current Working Directory
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <unistd.h>
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int chdir(
+ const char *pathname
+)
+{
+ rtems_filesystem_location_info_t loc;
+ int result;
+
+ /*
+ * Get the node where we wish to go.
+ */
+
+ result = rtems_filesystem_evaluate_path(
+ pathname, RTEMS_LIBIO_PERMS_SEARCH, &loc, TRUE );
+ if ( result != 0 )
+ return -1;
+
+ /*
+ * Verify you can change directory into this node.
+ */
+
+ if ( !loc.ops->node_type_h ) {
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ if ( (*loc.ops->node_type_h)( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ) {
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTDIR );
+ }
+
+ rtems_filesystem_freenode( &rtems_filesystem_current );
+
+ rtems_filesystem_current = loc;
+
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/chmod.c b/cpukit/libcsupport/src/chmod.c
new file mode 100644
index 0000000000..1007be6b26
--- /dev/null
+++ b/cpukit/libcsupport/src/chmod.c
@@ -0,0 +1,56 @@
+/*
+ * chmod() - POSIX 1003.1b 5.6.4 - Change File Modes
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int chmod(
+ const char *path,
+ mode_t mode
+)
+{
+ int status;
+ rtems_filesystem_location_info_t loc;
+ int result;
+
+ status = rtems_filesystem_evaluate_path( path, 0, &loc, TRUE );
+ if ( status != 0 )
+ return -1;
+
+ if ( !loc.handlers ){
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( EBADF );
+ }
+
+ if ( !loc.handlers->fchmod_h ){
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ result = (*loc.handlers->fchmod_h)( &loc, mode );
+
+ rtems_filesystem_freenode( &loc );
+
+ return result;
+}
diff --git a/cpukit/libcsupport/src/chown.c b/cpukit/libcsupport/src/chown.c
new file mode 100644
index 0000000000..8ac0a91979
--- /dev/null
+++ b/cpukit/libcsupport/src/chown.c
@@ -0,0 +1,49 @@
+/*
+ * chown() - POSIX 1003.1b 5.6.5 - Change Owner and Group of a File
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/stat.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int chown(
+ const char *path,
+ uid_t owner,
+ gid_t group
+)
+{
+ rtems_filesystem_location_info_t loc;
+ int result;
+
+ if ( rtems_filesystem_evaluate_path( path, 0x00, &loc, TRUE ) )
+ return -1;
+
+ if ( !loc.ops->chown_h ) {
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ result = (*loc.ops->chown_h)( &loc, owner, group );
+
+ rtems_filesystem_freenode( &loc );
+
+ return result;
+}
diff --git a/cpukit/libcsupport/src/chroot.c b/cpukit/libcsupport/src/chroot.c
new file mode 100644
index 0000000000..648b0b872d
--- /dev/null
+++ b/cpukit/libcsupport/src/chroot.c
@@ -0,0 +1,54 @@
+/*
+ * chroot() - Change Root Directory
+ * Author: fernando.ruiz@ctv.es
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <unistd.h>
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int chroot(
+ const char *pathname
+)
+{
+ int result;
+ rtems_filesystem_location_info_t loc;
+
+ /* an automatic call to new private env the first time */
+ if (rtems_current_user_env == &rtems_global_user_env) {
+ rtems_libio_set_private_env(); /* try to set a new private env*/
+ if (rtems_current_user_env == &rtems_global_user_env) /* not ok */
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ };
+
+ result = chdir(pathname);
+ if (result) {
+ rtems_set_errno_and_return_minus_one( errno );
+ };
+ /* clone the new root location */
+ if (rtems_filesystem_evaluate_path(".", 0, &loc, 0)) {
+ /* our cwd has changed, though - but there is no easy way of return :-( */
+ rtems_set_errno_and_return_minus_one( errno );
+ }
+ rtems_filesystem_freenode(&rtems_filesystem_root);
+ rtems_filesystem_root = loc;
+
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/close.c b/cpukit/libcsupport/src/close.c
new file mode 100644
index 0000000000..b9114f81e7
--- /dev/null
+++ b/cpukit/libcsupport/src/close.c
@@ -0,0 +1,58 @@
+/*
+ * close() - POSIX 1003.1b 6.3.1 - Close a File
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+
+int close(
+ int fd
+)
+{
+ rtems_libio_t *iop;
+ rtems_status_code rc;
+
+ rtems_libio_check_fd(fd);
+ iop = rtems_libio_iop(fd);
+ rtems_libio_check_is_open(iop);
+
+ rc = RTEMS_SUCCESSFUL;
+ if ( iop->handlers->close_h )
+ rc = (*iop->handlers->close_h)( iop );
+
+ rtems_filesystem_freenode( &iop->pathinfo );
+ rtems_libio_free( iop );
+
+ return rc;
+}
+
+/*
+ * _close_r
+ *
+ * This is the Newlib dependent reentrant version of close().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _close_r(
+ struct _reent *ptr,
+ int fd
+)
+{
+ return close( fd );
+}
+#endif
diff --git a/cpukit/libcsupport/src/closedir.c b/cpukit/libcsupport/src/closedir.c
new file mode 100644
index 0000000000..2204768a08
--- /dev/null
+++ b/cpukit/libcsupport/src/closedir.c
@@ -0,0 +1,74 @@
+/*
+ * closedir() - POSIX 1003.1b - XXX
+ *
+ * This was copied from Newlib 1.8.0.
+ *
+ *
+ * Copyright (c) 1983 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)closedir.c 5.9 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+/*
+ * close a directory.
+ */
+int
+closedir(dirp)
+ register DIR *dirp;
+{
+ int fd;
+
+ if ( !dirp )
+ rtems_set_errno_and_return_minus_one( EBADF );
+
+ fd = dirp->dd_fd;
+ dirp->dd_fd = -1;
+ dirp->dd_loc = 0;
+ (void)free((void *)dirp->dd_buf);
+ (void)free((void *)dirp);
+ return(close(fd));
+}
diff --git a/cpukit/libcsupport/src/creat.c b/cpukit/libcsupport/src/creat.c
new file mode 100644
index 0000000000..ed7a872d4a
--- /dev/null
+++ b/cpukit/libcsupport/src/creat.c
@@ -0,0 +1,19 @@
+/*
+ * $Id$
+ */
+
+/* creat() "system call" */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* This is needed by f2c and therefore the SPEC benchmarks. */
+
+#include <fcntl.h>
+
+int
+creat (const char *path, mode_t mode)
+{
+ return open (path, O_WRONLY | O_CREAT | O_TRUNC, mode);
+}
diff --git a/cpukit/libcsupport/src/ctermid.c b/cpukit/libcsupport/src/ctermid.c
new file mode 100644
index 0000000000..f0e2310fea
--- /dev/null
+++ b/cpukit/libcsupport/src/ctermid.c
@@ -0,0 +1,37 @@
+/*
+ * ctermid() - POSIX 1003.1b 4.7.1 - Generate Terminal Pathname
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <stdio.h>
+#include <string.h>
+
+static char *ctermid_name = "/dev/console";
+
+char *ctermid(
+ char *s
+)
+{
+ if ( !s )
+ return ctermid_name;
+
+ strcpy( s, ctermid_name );
+ return s;
+}
+
+#endif
diff --git a/cpukit/libcsupport/src/dup.c b/cpukit/libcsupport/src/dup.c
new file mode 100644
index 0000000000..684d72d92f
--- /dev/null
+++ b/cpukit/libcsupport/src/dup.c
@@ -0,0 +1,26 @@
+/*
+ * dup() - POSIX 1003.1b 6.2.1 Duplicate an Open File Descriptor
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+
+int dup(
+ int fildes
+)
+{
+ return fcntl( fildes, F_DUPFD, 0 );
+}
diff --git a/cpukit/libcsupport/src/dup2.c b/cpukit/libcsupport/src/dup2.c
new file mode 100644
index 0000000000..15998f797c
--- /dev/null
+++ b/cpukit/libcsupport/src/dup2.c
@@ -0,0 +1,52 @@
+/*
+ * dup2() - POSIX 1003.1b 6.2.1 Duplicate an Open File Descriptor
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <rtems/libio_.h>
+
+int dup2(
+ int fildes,
+ int fildes2
+)
+{
+ int status;
+ struct stat buf;
+
+ /*
+ * If fildes is not valid, then fildes2 should not be closed.
+ */
+
+ status = fstat( fildes, &buf );
+ if ( status == -1 )
+ return -1;
+
+ /*
+ * If fildes2 is not valid, then we should not do anything either.
+ */
+
+ status = fstat( fildes2, &buf );
+ if ( status == -1 )
+ return -1;
+
+ /*
+ * This fcntl handles everything else.
+ */
+
+ return fcntl( fildes, F_DUPFD, fildes2 );
+}
diff --git a/cpukit/libcsupport/src/envlock.c b/cpukit/libcsupport/src/envlock.c
new file mode 100644
index 0000000000..687eb32753
--- /dev/null
+++ b/cpukit/libcsupport/src/envlock.c
@@ -0,0 +1,108 @@
+/*
+ * Author: Till Straumann <strauman@slac.stanford.edu>, 3/2002
+ *
+ * $Id$
+ */
+
+/* provide locking for the global environment 'environ' */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <sys/reent.h>
+
+#include <assert.h>
+
+/*
+ * NOTES:
+ * - although it looks like a classical multiple-readers / single writer (MRSW)
+ * locking problem, we still use a single lock for the following reasons:
+ * 1) newlib has no provision / hook for calling different locking routines
+ * from setenv/putenv and getenv, respectively.
+ * 2) MRSW involves calling several semaphore-primitives, even in the most
+ * likely case of a first-reader's access. This probably takes more CPU
+ * time than just waiting until another reader is done; environment
+ * access is fast.
+ * - the lock implementation must allow nesting (same thread may call
+ * lock-lock-unlock-unlock).
+ * - NEWLIB-1.8.2 has an ugly BUG: if environ is NULL, _findenv_r() bails
+ * out leaving the lock held :-(
+ *
+ * Used by the following functions:
+ * findenv_r(), setenv_r(), and unsetenv_r() which are called by
+ * getenv(), getenv_r(), setenv(), and unsetenv().
+ *
+ */
+
+#if defined(ENVLOCK_DEDIDCATED_MUTEX)
+static rtems_id envLock=0;
+
+static void
+__rtems_envlock_init(void)
+{
+ extern char **environ;
+ rtems_status_code rc;
+
+ if (envLock) /* already initialized */
+ return;
+
+ assert(environ && "MUST have non-NULL 'environ' due to newlib bug");
+
+ rc = rtems_semaphore_create(
+ rtems_build_name('E','N','V','S'),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
+ 0,
+ &envLock);
+ if (RTEMS_SUCCESSFUL!=rc)
+ rtems_fatal_error_occurred(rc);
+}
+
+void
+__env_lock(struct _reent *r)
+{
+ /* Do lazy init */
+ if (!envLock)
+ __rtems_envlock_init();
+ /*
+ * Must not use a semaphore before pre-tasking hook is called.
+ * - it will corrupt memory :-(
+ */
+
+ if (_Thread_Executing)
+ rtems_semaphore_obtain(envLock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+}
+
+void
+__env_unlock(struct _reent *r)
+{
+ /*
+ * Must not use a semaphore before pre-tasking hook is called.
+ * - it will corrupt memory :-(
+ */
+ if (_Thread_Executing)
+ rtems_semaphore_release(envLock);
+}
+#else
+
+/*
+ * Reuse the libio mutex -- it is always initialized before we
+ * could possibly run.
+ */
+
+#include <rtems/libio_.h>
+
+void
+__env_lock(struct _reent *r)
+{
+ rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+}
+
+void
+__env_unlock(struct _reent *r)
+{
+ rtems_semaphore_release( rtems_libio_semaphore );
+}
+#endif
diff --git a/cpukit/libcsupport/src/error.c b/cpukit/libcsupport/src/error.c
new file mode 100644
index 0000000000..5af6c41bef
--- /dev/null
+++ b/cpukit/libcsupport/src/error.c
@@ -0,0 +1,213 @@
+/*
+ * report errors and panics to RTEMS' stderr.
+ * Currently just used by RTEMS monitor.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * These routines provide general purpose error reporting.
+ * rtems_error reports an error to stderr and allows use of
+ * printf style formatting. A newline is appended to all messages.
+ *
+ * error_flag can be specified as any of the following:
+ *
+ * RTEMS_ERROR_ERRNO -- include errno text in output
+ * RTEMS_ERROR_PANIC -- halts local system after output
+ * RTEMS_ERROR_ABORT -- abort after output
+ *
+ * It can also include a rtems_status value which can be OR'd
+ * with the above flags. *
+ *
+ * EXAMPLE
+ * #include <rtems.h>
+ * #include <rtems/error.h>
+ * rtems_error(0, "stray interrupt %d", intr);
+ *
+ * EXAMPLE
+ * if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL)
+ * {
+ * rtems_error(status | RTEMS_ERROR_ABORT,
+ * "could not create task");
+ * }
+ *
+ * EXAMPLE
+ * if ((fd = open(pathname, O_RDNLY)) < 0)
+ * {
+ * rtems_error(RTEMS_ERROR_ERRNO, "open of '%s' failed", pathname);
+ * goto failed;
+ * }
+ */
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+
+#include <rtems/error.h>
+#include <rtems/assoc.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h> /* _exit() */
+
+/* bug in hpux <errno.h>: no prototypes unless you are C++ */
+#ifdef hpux9
+char *strerror(int);
+#endif
+
+extern char *rtems_progname;
+int rtems_panic_in_progress;
+
+rtems_assoc_t rtems_status_assoc[] = {
+ { "successful completion", RTEMS_SUCCESSFUL, },
+ { "returned from a thread", RTEMS_TASK_EXITTED, },
+ { "multiprocessing not configured", RTEMS_MP_NOT_CONFIGURED, },
+ { "invalid object name", RTEMS_INVALID_NAME, },
+ { "invalid object id", RTEMS_INVALID_ID, },
+ { "too many", RTEMS_TOO_MANY, },
+ { "timed out waiting", RTEMS_TIMEOUT, },
+ { "object deleted while waiting", RTEMS_OBJECT_WAS_DELETED, },
+ { "specified size was invalid", RTEMS_INVALID_SIZE, },
+ { "address specified is invalid", RTEMS_INVALID_ADDRESS, },
+ { "number was invalid", RTEMS_INVALID_NUMBER, },
+ { "item has not been initialized", RTEMS_NOT_DEFINED, },
+ { "resources still outstanding", RTEMS_RESOURCE_IN_USE, },
+ { "request not satisfied", RTEMS_UNSATISFIED, },
+ { "thread is in wrong state", RTEMS_INCORRECT_STATE, },
+ { "thread already in state", RTEMS_ALREADY_SUSPENDED, },
+ { "illegal on calling thread", RTEMS_ILLEGAL_ON_SELF, },
+ { "illegal for remote object", RTEMS_ILLEGAL_ON_REMOTE_OBJECT, },
+ { "called from wrong environment", RTEMS_CALLED_FROM_ISR, },
+ { "invalid thread priority", RTEMS_INVALID_PRIORITY, },
+ { "invalid date/time", RTEMS_INVALID_CLOCK, },
+ { "invalid node id", RTEMS_INVALID_NODE, },
+ { "directive not configured", RTEMS_NOT_CONFIGURED, },
+ { "not owner of resource", RTEMS_NOT_OWNER_OF_RESOURCE , },
+ { "directive not implemented", RTEMS_NOT_IMPLEMENTED, },
+ { "RTEMS inconsistency detected", RTEMS_INTERNAL_ERROR, },
+ { "could not get enough memory", RTEMS_NO_MEMORY, },
+ { "driver IO error", RTEMS_IO_ERROR, },
+ { "internal multiprocessing only", THREAD_STATUS_PROXY_BLOCKING, },
+ { 0, 0, 0 },
+};
+
+
+const char *
+rtems_status_text(
+ rtems_status_code status
+)
+{
+ return rtems_assoc_name_by_local(rtems_status_assoc, status);
+}
+
+
+static int rtems_verror(
+ uint32_t error_flag,
+ const char *printf_format,
+ va_list arglist
+)
+{
+ int local_errno = 0;
+ int chars_written = 0;
+ rtems_status_code status;
+
+ if (error_flag & RTEMS_ERROR_PANIC)
+ {
+ if (rtems_panic_in_progress++)
+ _Thread_Disable_dispatch(); /* disable task switches */
+
+ /* don't aggravate things */
+ if (rtems_panic_in_progress > 2)
+ return 0;
+ }
+
+ (void) fflush(stdout); /* in case stdout/stderr same */
+
+ status = error_flag & ~RTEMS_ERROR_MASK;
+ if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */
+ local_errno = errno;
+
+ if (_System_state_Is_multiprocessing)
+ fprintf(stderr, "[%" PRIu32 "] ", _Configuration_MP_table->node);
+
+ if (rtems_progname && *rtems_progname)
+ chars_written += fprintf(stderr, "%s: ", rtems_progname);
+ chars_written += vfprintf(stderr, printf_format, arglist);
+
+ if (status)
+ chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status));
+
+ if (local_errno)
+ {
+ if ((local_errno > 0) && *strerror(local_errno))
+ chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno));
+ else
+ chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno);
+ }
+
+ chars_written += fprintf(stderr, "\n");
+
+ (void) fflush(stderr);
+
+ if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT))
+ {
+ if (error_flag & RTEMS_ERROR_PANIC)
+ {
+ rtems_error(0, "fatal error, exiting");
+ _exit(local_errno);
+ }
+ else
+ {
+ rtems_error(0, "fatal error, aborting");
+ abort();
+ }
+ }
+ return chars_written;
+}
+
+
+/*
+ * Report an error.
+ * error_flag is as above; printf_format is a normal
+ * printf(3) format string, with its concommitant arguments.
+ *
+ * Returns the number of characters written.
+ */
+
+int rtems_error(
+ int error_flag,
+ const char *printf_format,
+ ...
+ )
+{
+ va_list arglist;
+ int chars_written;
+
+ va_start(arglist, printf_format);
+ chars_written = rtems_verror(error_flag, printf_format, arglist);
+ va_end(arglist);
+
+ return chars_written;
+}
+
+/*
+ * rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...)
+ */
+
+void rtems_panic(
+ const char *printf_format,
+ ...
+ )
+{
+ va_list arglist;
+
+ va_start(arglist, printf_format);
+ (void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist);
+ va_end(arglist);
+}
diff --git a/cpukit/libcsupport/src/eval.c b/cpukit/libcsupport/src/eval.c
new file mode 100644
index 0000000000..7c9c0a7e47
--- /dev/null
+++ b/cpukit/libcsupport/src/eval.c
@@ -0,0 +1,123 @@
+/*
+ * rtems_filesystem_evaluate_path()
+ *
+ * Routine to seed the evaluate path routine.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int rtems_filesystem_evaluate_path(
+ const char *pathname,
+ int flags,
+ rtems_filesystem_location_info_t *pathloc,
+ int follow_link
+)
+{
+ int i;
+ int result;
+ rtems_filesystem_node_types_t type;
+
+ /*
+ * Verify Input parameters.
+ */
+
+ if ( !pathname )
+ rtems_set_errno_and_return_minus_one( EFAULT );
+
+ if ( !pathloc )
+ rtems_set_errno_and_return_minus_one( EIO ); /* should never happen */
+
+ /*
+ * Evaluate the path using the optable evalpath.
+ */
+
+ rtems_filesystem_get_start_loc( pathname, &i, pathloc );
+
+ if ( !pathloc->ops->evalpath_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ result = (*pathloc->ops->evalpath_h)( &pathname[i], flags, pathloc );
+
+ /*
+ * Get the Node type and determine if you need to follow the link or
+ * not.
+ */
+
+ if ( (result == 0) && follow_link ) {
+
+ if ( !pathloc->ops->node_type_h ){
+ rtems_filesystem_freenode( pathloc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ type = (*pathloc->ops->node_type_h)( pathloc );
+
+ if ( ( type == RTEMS_FILESYSTEM_HARD_LINK ) ||
+ ( type == RTEMS_FILESYSTEM_SYM_LINK ) ) {
+
+ if ( !pathloc->ops->eval_link_h ){
+ rtems_filesystem_freenode( pathloc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ /* what to do with the valid node pathloc points to
+ * if eval_link_h fails?
+ * Let the FS implementation deal with this case. It
+ * should probably free pathloc in either case:
+ * - if the link evaluation fails, it must free the
+ * original (valid) pathloc because we are going
+ * to return -1 and hence the FS generics won't
+ * cleanup pathloc.
+ * - if the link evaluation is successful, the updated
+ * pathloc will be passed up (and eventually released).
+ * Hence, the (valid) originial node that we submit to
+ * eval_link_h() should be released by the handler.
+ */
+
+ result = (*pathloc->ops->eval_link_h)( pathloc, flags );
+
+ }
+ }
+
+ return result;
+}
+
+
+int rtems_filesystem_evaluate_parent(
+ int flags,
+ rtems_filesystem_location_info_t *pathloc
+)
+{
+ rtems_filesystem_location_info_t parent;
+ int result;
+
+ if ( !pathloc )
+ rtems_set_errno_and_return_minus_one( EIO ); /* should never happen */
+
+ if ( !pathloc->ops->evalpath_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ parent = *pathloc;
+ result = (*pathloc->ops->evalpath_h)( "..", flags, &parent );
+ if (result != 0){
+ return -1;
+ }
+ rtems_filesystem_freenode( &parent );
+
+ return result;
+}
diff --git a/cpukit/libcsupport/src/fchdir.c b/cpukit/libcsupport/src/fchdir.c
new file mode 100644
index 0000000000..603288614d
--- /dev/null
+++ b/cpukit/libcsupport/src/fchdir.c
@@ -0,0 +1,90 @@
+/*
+ * fchdir() - compatible with SVr4, 4.4BSD and X/OPEN - Change Directory
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int fchdir(
+ int fd
+)
+{
+ rtems_libio_t *iop;
+ rtems_filesystem_location_info_t loc, saved;
+
+ rtems_libio_check_fd( fd );
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_is_open(iop);
+
+ /*
+ * Now process the fchmod().
+ */
+
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ );
+
+ /*
+ * Verify you can change directory into this node.
+ */
+
+ if ( !iop->pathinfo.ops ) {
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ if ( !iop->pathinfo.ops->node_type_h ) {
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ if ( (*iop->pathinfo.ops->node_type_h)( &iop->pathinfo ) !=
+ RTEMS_FILESYSTEM_DIRECTORY ) {
+ rtems_set_errno_and_return_minus_one( ENOTDIR );
+ }
+
+
+ /*
+ * FIXME : I feel there should be another call to
+ * actually take into account the extra reference to
+ * this node which we are making here. I can
+ * see the freenode interface but do not see
+ * allocnode node interface. It maybe node_type.
+ *
+ * FIXED: T.Straumann: it is evaluate_path()
+ * but note the race condition. Threads who
+ * share their rtems_filesystem_current better
+ * be synchronized!
+ */
+
+ saved = rtems_filesystem_current;
+ rtems_filesystem_current = iop->pathinfo;
+
+ /* clone the current node */
+ if (rtems_filesystem_evaluate_path(".", 0, &loc, 0)) {
+ /* cloning failed; restore original and bail out */
+ rtems_filesystem_current = saved;
+ return -1;
+ }
+ /* release the old one */
+ rtems_filesystem_freenode( &saved );
+
+ rtems_filesystem_current = loc;
+
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/fchmod.c b/cpukit/libcsupport/src/fchmod.c
new file mode 100644
index 0000000000..11d9c0e723
--- /dev/null
+++ b/cpukit/libcsupport/src/fchmod.c
@@ -0,0 +1,48 @@
+/*
+ * fchmod() - POSIX 1003.1b 5.6.4 - Change File Modes
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int fchmod(
+ int fd,
+ mode_t mode
+)
+{
+ rtems_libio_t *iop;
+
+ rtems_libio_check_fd( fd );
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_is_open(iop);
+
+ /*
+ * Now process the fchmod().
+ */
+
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
+
+ if ( !iop->handlers->fchmod_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->pathinfo.handlers->fchmod_h)( &iop->pathinfo, mode );
+}
diff --git a/cpukit/libcsupport/src/fcntl.c b/cpukit/libcsupport/src/fcntl.c
new file mode 100644
index 0000000000..641c25b1ae
--- /dev/null
+++ b/cpukit/libcsupport/src/fcntl.c
@@ -0,0 +1,188 @@
+/*
+ * fcntl() - POSIX 1003.1b 6.5.2 - File Control
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/libio_.h>
+
+static int vfcntl(
+ int fd,
+ int cmd,
+ va_list ap
+)
+{
+ rtems_libio_t *iop;
+ rtems_libio_t *diop;
+ int fd2;
+ int flags;
+ int mask;
+ int ret = 0;
+
+ rtems_libio_check_fd( fd );
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_is_open(iop);
+
+ /*
+ * Now process the fcntl().
+ */
+
+ /*
+ * This switch should contain all the cases from POSIX.
+ */
+
+ switch ( cmd ) {
+ case F_DUPFD: /* dup */
+ fd2 = va_arg( ap, int );
+ if ( fd2 )
+ diop = rtems_libio_iop( fd2 );
+ else {
+ /* allocate a file control block */
+ diop = rtems_libio_allocate();
+ if ( diop == 0 ) {
+ ret = -1;
+ break;
+ }
+ }
+
+ diop->handlers = iop->handlers;
+ diop->file_info = iop->file_info;
+ diop->flags = iop->flags;
+ diop->pathinfo = iop->pathinfo;
+ ret = (int) (diop - rtems_libio_iops);
+ break;
+
+ case F_GETFD: /* get f_flags */
+ ret = ((iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC) != 0);
+ break;
+
+ case F_SETFD: /* set f_flags */
+ /*
+ * Interpret the third argument as the "close on exec()" flag.
+ * If this argument is 1, then the file descriptor is to be closed
+ * if a new process is exec()'ed. Since RTEMS does not support
+ * processes, then we can ignore this one except to make
+ * F_GETFD work.
+ */
+
+ if ( va_arg( ap, int ) )
+ iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
+ else
+ iop->flags &= ~LIBIO_FLAGS_CLOSE_ON_EXEC;
+ break;
+
+ case F_GETFL: /* more flags (cloexec) */
+ ret = rtems_libio_to_fcntl_flags( iop->flags );
+ break;
+
+ case F_SETFL:
+ flags = rtems_libio_fcntl_flags( va_arg( ap, int ) );
+ mask = LIBIO_FLAGS_NO_DELAY | LIBIO_FLAGS_APPEND;
+
+ /*
+ * XXX If we are turning on append, should we seek to the end?
+ */
+
+ iop->flags = (iop->flags & ~mask) | (flags & mask);
+ break;
+
+ case F_GETLK:
+ errno = ENOTSUP;
+ ret = -1;
+ break;
+
+ case F_SETLK:
+ errno = ENOTSUP;
+ ret = -1;
+ break;
+
+ case F_SETLKW:
+ errno = ENOTSUP;
+ ret = -1;
+ break;
+
+ case F_SETOWN: /* for sockets. */
+ errno = ENOTSUP;
+ ret = -1;
+ break;
+
+ case F_GETOWN: /* for sockets. */
+ errno = ENOTSUP;
+ ret = -1;
+ break;
+
+ default:
+ errno = EINVAL;
+ ret = -1;
+ break;
+ }
+
+ /*
+ * If we got this far successfully, then we give the optional
+ * filesystem specific handler a chance to process this.
+ */
+
+ if (ret >= 0) {
+ if (iop->handlers->fcntl_h) {
+ int err = (*iop->handlers->fcntl_h)( cmd, iop );
+ if (err) {
+ errno = err;
+ ret = -1;
+ }
+ }
+ }
+ return ret;
+}
+
+int fcntl(
+ int fd,
+ int cmd,
+ ...
+)
+{
+ int ret;
+ va_list ap;
+ va_start( ap, cmd );
+ ret = vfcntl(fd,cmd,ap);
+ va_end(ap);
+ return ret;
+}
+
+
+/*
+ * _fcntl_r
+ *
+ * This is the Newlib dependent reentrant version of fcntl().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _fcntl_r(
+ struct _reent *ptr,
+ int fd,
+ int cmd,
+ int arg
+)
+{
+ return fcntl( fd, cmd, arg );
+}
+#endif
diff --git a/cpukit/libcsupport/src/fdatasync.c b/cpukit/libcsupport/src/fdatasync.c
new file mode 100644
index 0000000000..c2b4db43ae
--- /dev/null
+++ b/cpukit/libcsupport/src/fdatasync.c
@@ -0,0 +1,42 @@
+/*
+ * fdatasync() - POSIX 1003.1b 6.6.2 - Synchronize the Data of a File
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int fdatasync(
+ int fd
+)
+{
+ rtems_libio_t *iop;
+
+ rtems_libio_check_fd( fd );
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_is_open(iop);
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
+
+ /*
+ * Now process the fdatasync().
+ */
+
+ if ( !iop->handlers->fdatasync_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->handlers->fdatasync_h)( iop );
+}
diff --git a/cpukit/libcsupport/src/fpathconf.c b/cpukit/libcsupport/src/fpathconf.c
new file mode 100644
index 0000000000..accaae1585
--- /dev/null
+++ b/cpukit/libcsupport/src/fpathconf.c
@@ -0,0 +1,87 @@
+/*
+ * fpathconf() - POSIX 1003.1b - 5.7.1 - Configurable Pathname Varables
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+#include <unistd.h>
+#include <errno.h>
+
+long fpathconf(
+ int fd,
+ int name
+)
+{
+ long return_value;
+ rtems_libio_t *iop;
+ rtems_filesystem_limits_and_options_t *the_limits;
+
+ rtems_libio_check_fd(fd);
+ iop = rtems_libio_iop(fd);
+ rtems_libio_check_is_open(iop);
+ rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ);
+
+ /*
+ * Now process the information request.
+ */
+
+ the_limits = &iop->pathinfo.mt_entry->pathconf_limits_and_options;
+
+ switch ( name ) {
+ case _PC_LINK_MAX:
+ return_value = the_limits->link_max;
+ break;
+ case _PC_MAX_CANON:
+ return_value = the_limits->max_canon;
+ break;
+ case _PC_MAX_INPUT:
+ return_value = the_limits->max_input;
+ break;
+ case _PC_NAME_MAX:
+ return_value = the_limits->name_max;
+ break;
+ case _PC_PATH_MAX:
+ return_value = the_limits->path_max;
+ break;
+ case _PC_PIPE_BUF:
+ return_value = the_limits->pipe_buf;
+ break;
+ case _PC_CHOWN_RESTRICTED:
+ return_value = the_limits->posix_chown_restrictions;
+ break;
+ case _PC_NO_TRUNC:
+ return_value = the_limits->posix_no_trunc;
+ break;
+ case _PC_VDISABLE:
+ return_value = the_limits->posix_vdisable;
+ break;
+ case _PC_ASYNC_IO:
+ return_value = the_limits->posix_async_io;
+ break;
+ case _PC_PRIO_IO:
+ return_value = the_limits->posix_prio_io;
+ break;
+ case _PC_SYNC_IO:
+ return_value = the_limits->posix_sync_io;
+ break;
+ default:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ break;
+ }
+
+ return return_value;
+}
diff --git a/cpukit/libcsupport/src/fs_null_handlers.c b/cpukit/libcsupport/src/fs_null_handlers.c
new file mode 100644
index 0000000000..fb323d7452
--- /dev/null
+++ b/cpukit/libcsupport/src/fs_null_handlers.c
@@ -0,0 +1,41 @@
+/*
+ * Null Filesystem Operations Tables
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+#include <rtems/libio.h>
+
+/*
+ * Set of null operations handlers.
+ */
+
+rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers = {
+ NULL, /* open */
+ NULL, /* close */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* ioctl */
+ NULL, /* lseek */
+ NULL, /* fstat */
+ NULL, /* fchmod */
+ NULL, /* ftruncate */
+ NULL, /* fpathconf */
+ NULL, /* fsync */
+ NULL, /* fdatasync */
+ NULL, /* fcntl */
+ NULL /* rmnod */
+};
diff --git a/cpukit/libcsupport/src/fstat.c b/cpukit/libcsupport/src/fstat.c
new file mode 100644
index 0000000000..e388544f93
--- /dev/null
+++ b/cpukit/libcsupport/src/fstat.c
@@ -0,0 +1,80 @@
+/*
+ * fstat() - POSIX 1003.1b 5.6.2 - Get File Status
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int fstat(
+ int fd,
+ struct stat *sbuf
+)
+{
+ rtems_libio_t *iop;
+
+ /*
+ * Check to see if we were passed a valid pointer.
+ */
+
+ if ( !sbuf )
+ rtems_set_errno_and_return_minus_one( EFAULT );
+
+ /*
+ * Now process the stat() request.
+ */
+
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_fd( fd );
+ rtems_libio_check_is_open(iop);
+
+ if ( !iop->handlers )
+ rtems_set_errno_and_return_minus_one( EBADF );
+
+ if ( !iop->handlers->fstat_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ /*
+ * Zero out the stat structure so the various support
+ * versions of stat don't have to.
+ */
+ memset( sbuf, 0, sizeof(struct stat) );
+
+ return (*iop->handlers->fstat_h)( &iop->pathinfo, sbuf );
+}
+
+/*
+ * _fstat_r
+ *
+ * This is the Newlib dependent reentrant version of fstat().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _fstat_r(
+ struct _reent *ptr,
+ int fd,
+ struct stat *buf
+)
+{
+ return fstat( fd, buf );
+}
+#endif
diff --git a/cpukit/libcsupport/src/fsync.c b/cpukit/libcsupport/src/fsync.c
new file mode 100644
index 0000000000..cfd8e8d49b
--- /dev/null
+++ b/cpukit/libcsupport/src/fsync.c
@@ -0,0 +1,45 @@
+/*
+ * fsync() - POSIX 1003.1b 6.6.1 - Synchronize the State of a File
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int fsync(
+ int fd
+)
+{
+ rtems_libio_t *iop;
+
+ rtems_libio_check_fd( fd );
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_is_open(iop);
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
+
+ /*
+ * Now process the fsync().
+ */
+
+ if ( !iop->handlers )
+ rtems_set_errno_and_return_minus_one( EBADF );
+
+ if ( !iop->handlers->fsync_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->handlers->fsync_h)( iop );
+}
diff --git a/cpukit/libcsupport/src/ftruncate.c b/cpukit/libcsupport/src/ftruncate.c
new file mode 100644
index 0000000000..6619ca5f74
--- /dev/null
+++ b/cpukit/libcsupport/src/ftruncate.c
@@ -0,0 +1,57 @@
+/*
+ * ftruncate() - Truncate a File to the Specified Length
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int ftruncate(
+ int fd,
+ off_t length
+)
+{
+ rtems_libio_t *iop;
+ rtems_filesystem_location_info_t loc;
+
+ rtems_libio_check_fd( fd );
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_is_open(iop);
+
+ /*
+ * Now process the ftruncate() request.
+ */
+
+ /*
+ * Make sure we are not working on a directory
+ */
+
+ loc = iop->pathinfo;
+ if ( !loc.ops->node_type_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ if ( (*loc.ops->node_type_h)( &loc ) == RTEMS_FILESYSTEM_DIRECTORY )
+ rtems_set_errno_and_return_minus_one( EISDIR );
+
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
+
+ if ( !iop->handlers->ftruncate_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->handlers->ftruncate_h)( iop, length );
+}
diff --git a/cpukit/libcsupport/src/getcwd.c b/cpukit/libcsupport/src/getcwd.c
new file mode 100644
index 0000000000..fdde4eea81
--- /dev/null
+++ b/cpukit/libcsupport/src/getcwd.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 1989, 1991 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.
+ *
+ * Copied from newlib 1.8.1. RTEMS can not build all of the contents
+ * of the UNIX directory but we need this routine.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * Added these when moved to RTEMS
+ */
+
+#define _stat stat
+#define _opendir opendir
+#define _fstat fstat
+#define _readdir readdir
+#define _closedir closedir
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getcwd.c 5.11 (Berkeley) 2/24/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <reent.h>
+#include <_syslist.h>
+
+#define bcopy(a,b,c) memmove (b,a,c)
+
+#define ISDOT(dp) \
+ (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
+ (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
+
+#ifndef _REENT_ONLY
+
+char *
+getcwd (pt, size)
+ char *pt;
+ size_t size;
+{
+ register struct dirent *dp;
+ register DIR *dir = 0;
+ register dev_t dev;
+ register ino_t ino;
+ register int first;
+ register char *bpt, *bup;
+ struct stat s;
+ dev_t root_dev;
+ ino_t root_ino;
+ size_t ptsize, upsize;
+ int save_errno;
+ char *ept, *eup, *up;
+
+ /*
+ * If no buffer specified by the user, allocate one as necessary.
+ * If a buffer is specified, the size has to be non-zero. The path
+ * is built from the end of the buffer backwards.
+ */
+
+ if (pt)
+ {
+ ptsize = 0;
+ if (!size)
+ {
+ errno = EINVAL;
+ return (char *) NULL;
+ }
+ ept = pt + size;
+ }
+ else
+ {
+ if (!(pt = (char *) malloc (ptsize = 1024 - 4)))
+ {
+ return (char *) NULL;
+ }
+ ept = pt + ptsize;
+ }
+ bpt = ept - 1;
+ *bpt = '\0';
+
+ /*
+ * Allocate bytes (1024 - malloc space) for the string of "../"'s.
+ * Should always be enough (it's 340 levels). If it's not, allocate
+ * as necessary. Special * case the first stat, it's ".", not "..".
+ */
+
+ if (!(up = (char *) malloc (upsize = 1024 - 4)))
+ {
+ goto err;
+ }
+ eup = up + MAXPATHLEN;
+ bup = up;
+ up[0] = '.';
+ up[1] = '\0';
+
+ /* Save root values, so know when to stop. */
+ if (stat ("/", &s))
+ goto err;
+ root_dev = s.st_dev;
+ root_ino = s.st_ino;
+
+ errno = 0; /* XXX readdir has no error return. */
+
+ for (first = 1;; first = 0)
+ {
+ /* Stat the current level. */
+ if (_stat (up, &s))
+ goto err;
+
+ /* Save current node values. */
+ ino = s.st_ino;
+ dev = s.st_dev;
+
+ /* Check for reaching root. */
+ if (root_dev == dev && root_ino == ino)
+ {
+ *--bpt = '/';
+ /*
+ * It's unclear that it's a requirement to copy the
+ * path to the beginning of the buffer, but it's always
+ * been that way and stuff would probably break.
+ */
+ (void) bcopy (bpt, pt, ept - bpt);
+ free (up);
+ return pt;
+ }
+
+ /*
+ * Build pointer to the parent directory, allocating memory
+ * as necessary. Max length is 3 for "../", the largest
+ * possible component name, plus a trailing NULL.
+ */
+
+ if (bup + 3 + MAXNAMLEN + 1 >= eup)
+ {
+ if (!(up = (char *) realloc (up, upsize *= 2)))
+ {
+ goto err;
+ }
+ bup = up;
+ eup = up + upsize;
+ }
+ *bup++ = '.';
+ *bup++ = '.';
+ *bup = '\0';
+
+ /* Open and stat parent directory. */
+ if (!(dir = _opendir (up)) || _fstat (__dirfd (dir), &s))
+ goto err;
+
+ /* Add trailing slash for next directory. */
+ *bup++ = '/';
+
+ /*
+ * If it's a mount point, have to stat each element because
+ * the inode number in the directory is for the entry in the
+ * parent directory, not the inode number of the mounted file.
+ */
+
+ save_errno = 0;
+ if (s.st_dev == dev)
+ {
+ for (;;)
+ {
+ if (!(dp = _readdir (dir)))
+ goto notfound;
+ if (dp->d_ino == ino)
+ break;
+ }
+ }
+ else
+ for (;;)
+ {
+ if (!(dp = _readdir (dir)))
+ goto notfound;
+ if (ISDOT (dp))
+ continue;
+ bcopy (dp->d_name, bup, strlen (dp->d_name) + 1);
+
+ /* Save the first error for later. */
+ if (stat (up, &s))
+ {
+ if (!save_errno)
+ save_errno = errno;
+ errno = 0;
+ continue;
+ }
+ if (s.st_dev == dev && s.st_ino == ino)
+ break;
+ }
+
+ /*
+ * Check for length of the current name, preceding slash,
+ * leading slash.
+ */
+
+ if (bpt - pt <= strlen (dp->d_name) + (first ? 1 : 2))
+ {
+ size_t len, off;
+
+ if (!ptsize)
+ {
+ errno = ERANGE;
+ goto err;
+ }
+ off = bpt - pt;
+ len = ept - bpt;
+ if (!(pt = (char *) realloc (pt, ptsize *= 2)))
+ {
+ goto err;
+ }
+ bpt = pt + off;
+ ept = pt + ptsize;
+ (void) bcopy (bpt, ept - len, len);
+ bpt = ept - len;
+ }
+ if (!first)
+ *--bpt = '/';
+ bpt -= strlen (dp->d_name);
+ bcopy (dp->d_name, bpt, strlen (dp->d_name));
+ (void) _closedir (dir);
+ dir = 0;
+
+ /* Truncate any file name. */
+ *bup = '\0';
+ }
+
+notfound:
+ /*
+ * If readdir set errno, use it, not any saved error; otherwise,
+ * didn't find the current directory in its parent directory, set
+ * errno to ENOENT.
+ */
+
+ if (!errno)
+ errno = save_errno ? save_errno : ENOENT;
+ /* FALLTHROUGH */
+
+err:
+ if(dir)
+ (void) _closedir (dir);
+ if (ptsize)
+ free (pt);
+ free (up);
+ return (char *) NULL;
+}
+
+#endif /* _REENT_ONLY */
diff --git a/cpukit/libcsupport/src/getdents.c b/cpukit/libcsupport/src/getdents.c
new file mode 100644
index 0000000000..ca4c36727f
--- /dev/null
+++ b/cpukit/libcsupport/src/getdents.c
@@ -0,0 +1,63 @@
+/*
+ * getdents() - Get Directory Entries
+ *
+ * SVR4 and SVID extension required by Newlib readdir() family.
+ *
+ * This routine will dd_len / (sizeof dirent) directory entries relative to
+ * the current directory position index. These entries will be placed in
+ * character array pointed to by -dd_buf-
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int getdents(
+ int dd_fd,
+ char *dd_buf,
+ int dd_len
+)
+{
+ rtems_libio_t *iop;
+ rtems_filesystem_location_info_t loc;
+
+ /*
+ * Get the file control block structure associated with the file descriptor
+ */
+
+ iop = rtems_libio_iop( dd_fd );
+
+ /*
+ * Make sure we are working on a directory
+ */
+ loc = iop->pathinfo;
+ if ( !loc.ops->node_type_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ if ( (*loc.ops->node_type_h)( &loc ) != RTEMS_FILESYSTEM_DIRECTORY )
+ rtems_set_errno_and_return_minus_one( ENOTDIR );
+
+ /*
+ * Return the number of bytes that were actually transfered as a result
+ * of the read attempt.
+ */
+
+ if ( !iop->handlers->read_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->handlers->read_h)( iop, dd_buf, dd_len );
+}
diff --git a/cpukit/libcsupport/src/getegid.c b/cpukit/libcsupport/src/getegid.c
new file mode 100644
index 0000000000..4da7ba8d5b
--- /dev/null
+++ b/cpukit/libcsupport/src/getegid.c
@@ -0,0 +1,32 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+#include <rtems/userenv.h>
+
+/*
+ * MACRO in userenv.h
+gid_t _POSIX_types_Egid = 0;
+*/
+
+/*PAGE
+ *
+ * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs,
+ * P1003.1b-1993, p. 84
+ */
+
+gid_t getegid( void )
+{
+ return _POSIX_types_Egid;
+}
diff --git a/cpukit/libcsupport/src/geteuid.c b/cpukit/libcsupport/src/geteuid.c
new file mode 100644
index 0000000000..cb5b5add79
--- /dev/null
+++ b/cpukit/libcsupport/src/geteuid.c
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+
+#include <rtems/userenv.h>
+
+/*
+ * MACRO in userenv.h
+uid_t _POSIX_types_Euid = 0;
+*/
+
+/*PAGE
+ *
+ * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs,
+ * P1003.1b-1993, p. 84
+ */
+
+uid_t geteuid( void )
+{
+ return _POSIX_types_Euid;
+}
diff --git a/cpukit/libcsupport/src/getgid.c b/cpukit/libcsupport/src/getgid.c
new file mode 100644
index 0000000000..653445a99c
--- /dev/null
+++ b/cpukit/libcsupport/src/getgid.c
@@ -0,0 +1,47 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+
+#include <rtems/userenv.h>
+
+/*
+ * MACRO in userenv.h
+ *
+gid_t _POSIX_types_Gid = 0;
+*/
+
+/*PAGE
+ *
+ * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs,
+ * P1003.1b-1993, p. 84
+ */
+
+gid_t getgid( void )
+{
+ return _POSIX_types_Gid;
+}
+
+/*PAGE
+ *
+ * 4.2.2 Set User and Group IDs, P1003.1b-1993, p. 84
+ */
+
+int setgid(
+ gid_t gid
+)
+{
+ _POSIX_types_Gid = gid;
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/getgroups.c b/cpukit/libcsupport/src/getgroups.c
new file mode 100644
index 0000000000..c902c1f79d
--- /dev/null
+++ b/cpukit/libcsupport/src/getgroups.c
@@ -0,0 +1,29 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 4.2.3 Get Supplementary IDs, P1003.1b-1993, p. 86
+ */
+
+int getgroups(
+ int gidsetsize,
+ gid_t grouplist[]
+)
+{
+ return 0; /* no supplemental group ids */
+}
diff --git a/cpukit/libcsupport/src/getlogin.c b/cpukit/libcsupport/src/getlogin.c
new file mode 100644
index 0000000000..06b576f234
--- /dev/null
+++ b/cpukit/libcsupport/src/getlogin.c
@@ -0,0 +1,64 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <string.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+#include <rtems/userenv.h>
+
+#include <unistd.h>
+#include <pwd.h>
+
+/*PAGE
+ *
+ * 4.2.4 Get User Name, P1003.1b-1993, p. 87
+ *
+ * NOTE: P1003.1c/D10, p. 49 adds getlogin_r().
+ */
+
+/*
+ * MACRO in userenv.h
+ *
+static char _POSIX_types_Getlogin_buffer[ LOGIN_NAME_MAX ];
+*/
+
+char *getlogin( void )
+{
+ (void) getlogin_r( _POSIX_types_Getlogin_buffer, LOGIN_NAME_MAX );
+ return _POSIX_types_Getlogin_buffer;
+}
+
+/*PAGE
+ *
+ * 4.2.4 Get User Name, P1003.1b-1993, p. 87
+ *
+ * NOTE: P1003.1c/D10, p. 49 adds getlogin_r().
+ */
+
+int getlogin_r(
+ char *name,
+ size_t namesize
+)
+{
+ struct passwd *pw;
+ if ( namesize < LOGIN_NAME_MAX )
+ return ERANGE;
+
+ pw=getpwuid(getuid());
+ if (!pw) {
+ strcpy(name,"");
+ } else {
+ strncpy(name,pw->pw_name,LOGIN_NAME_MAX);
+ };
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/getpgrp.c b/cpukit/libcsupport/src/getpgrp.c
new file mode 100644
index 0000000000..0904d23883
--- /dev/null
+++ b/cpukit/libcsupport/src/getpgrp.c
@@ -0,0 +1,31 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 4.3.1 Get Process Group IDs, P1003.1b-1993, p. 89
+ */
+
+pid_t getpgrp( void )
+{
+ /*
+ * This always succeeds and returns the process group id. For rtems,
+ * this will always be the local node;
+ */
+
+ return _Objects_Local_node;
+}
diff --git a/cpukit/libcsupport/src/getpid.c b/cpukit/libcsupport/src/getpid.c
new file mode 100644
index 0000000000..0def44f140
--- /dev/null
+++ b/cpukit/libcsupport/src/getpid.c
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 4.1.1 Get Process and Parent Process IDs, P1003.1b-1993, p. 83
+ */
+
+pid_t getpid( void )
+{
+ return _Objects_Local_node;
+}
+
+/*
+ * _getpid_r
+ *
+ * This is the Newlib dependent reentrant version of getpid().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+pid_t _getpid_r(
+ struct _reent *ptr
+)
+{
+ return getpid();
+}
+#endif
diff --git a/cpukit/libcsupport/src/getppid.c b/cpukit/libcsupport/src/getppid.c
new file mode 100644
index 0000000000..193d17e9da
--- /dev/null
+++ b/cpukit/libcsupport/src/getppid.c
@@ -0,0 +1,28 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+
+pid_t _POSIX_types_Ppid = 0;
+
+/*PAGE
+ *
+ * 4.1.1 Get Process and Parent Process IDs, P1003.1b-1993, p. 83
+ */
+
+pid_t getppid( void )
+{
+ return _POSIX_types_Ppid;
+}
diff --git a/cpukit/libcsupport/src/getpwent.c b/cpukit/libcsupport/src/getpwent.c
new file mode 100644
index 0000000000..1236ccacca
--- /dev/null
+++ b/cpukit/libcsupport/src/getpwent.c
@@ -0,0 +1,443 @@
+/*
+ * POSIX 1003.1b - 9.2.2 - User Database Access Routines
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+
+#include <rtems/libio_.h>
+
+/*
+ * Static, thread-unsafe, buffers
+ */
+static FILE *passwd_fp;
+static char pwbuf[200];
+static struct passwd pwent;
+static FILE *group_fp;
+static char grbuf[200];
+static struct group grent;
+
+/*
+ * Initialize useable but dummy databases
+ */
+void init_etc_passwd_group(void)
+{
+ FILE *fp;
+ static char etc_passwd_initted = 0;
+
+ if (etc_passwd_initted)
+ return;
+ etc_passwd_initted = 1;
+ mkdir("/etc", 0777);
+
+ /*
+ * Initialize /etc/passwd
+ */
+ if ((fp = fopen("/etc/passwd", "r")) != NULL) {
+ fclose(fp);
+ }
+ else if ((fp = fopen("/etc/passwd", "w")) != NULL) {
+ fprintf(fp, "root:*:0:0:root::/:/bin/sh\n"
+ "rtems:*:1:1:RTEMS Application::/:/bin/sh\n"
+ "tty:!:2:2:tty owner::/:/bin/false\n" );
+ fclose(fp);
+ }
+
+ /*
+ * Initialize /etc/group
+ */
+ if ((fp = fopen("/etc/group", "r")) != NULL) {
+ fclose(fp);
+ }
+ else if ((fp = fopen("/etc/group", "w")) != NULL) {
+ fprintf( fp, "root:x:0:root\n"
+ "rtems:x:1:rtems\n"
+ "tty:x:2:tty\n" );
+ fclose(fp);
+ }
+}
+
+/*
+ * Extract a string value from the database
+ */
+static int
+scanString(FILE *fp, char **name, char **bufp, size_t *nleft, int nlFlag)
+{
+ int c;
+
+ *name = *bufp;
+ for (;;) {
+ c = getc(fp);
+ if (c == ':') {
+ if (nlFlag)
+ return 0;
+ break;
+ }
+ if (c == '\n') {
+ if (!nlFlag)
+ return 0;
+ break;
+ }
+ if (c == EOF)
+ return 0;
+ if (*nleft < 2)
+ return 0;
+ **bufp = c;
+ ++(*bufp);
+ --(*nleft);
+ }
+ **bufp = '\0';
+ ++(*bufp);
+ --(*nleft);
+ return 1;
+}
+
+/*
+ * Extract an integer value from the database
+ */
+static int
+scanInt(FILE *fp, int *val)
+{
+ int c;
+ unsigned int i = 0;
+ unsigned int limit = INT_MAX;
+ int sign = 0;
+ int d;
+
+ for (;;) {
+ c = getc(fp);
+ if (c == ':')
+ break;
+ if (sign == 0) {
+ if (c == '-') {
+ sign = -1;
+ limit++;
+ continue;
+ }
+ sign = 1;
+ }
+ if (!isdigit(c))
+ return 0;
+ d = c - '0';
+ if ((i > (limit / 10))
+ || ((i == (limit / 10)) && (d > (limit % 10))))
+ return 0;
+ i = i * 10 + d;
+ }
+ if (sign == 0)
+ return 0;
+ *val = i * sign;
+ return 1;
+}
+
+/*
+ * Extract a single password record from the database
+ */
+static int scanpw(
+ FILE *fp,
+ struct passwd *pwd,
+ char *buffer,
+ size_t bufsize
+)
+{
+ int pwuid, pwgid;
+
+ if (!scanString(fp, &pwd->pw_name, &buffer, &bufsize, 0)
+ || !scanString(fp, &pwd->pw_passwd, &buffer, &bufsize, 0)
+ || !scanInt(fp, &pwuid)
+ || !scanInt(fp, &pwgid)
+ || !scanString(fp, &pwd->pw_comment, &buffer, &bufsize, 0)
+ || !scanString(fp, &pwd->pw_gecos, &buffer, &bufsize, 0)
+ || !scanString(fp, &pwd->pw_dir, &buffer, &bufsize, 0)
+ || !scanString(fp, &pwd->pw_shell, &buffer, &bufsize, 1))
+ return 0;
+ pwd->pw_uid = pwuid;
+ pwd->pw_gid = pwgid;
+ return 1;
+}
+
+static int getpw_r(
+ const char *name,
+ int uid,
+ struct passwd *pwd,
+ char *buffer,
+ size_t bufsize,
+ struct passwd **result
+)
+{
+ FILE *fp;
+ int match;
+
+ init_etc_passwd_group();
+
+ if ((fp = fopen("/etc/passwd", "r")) == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ for(;;) {
+ if (!scanpw(fp, pwd, buffer, bufsize)) {
+ errno = EINVAL;
+ fclose(fp);
+ return -1;
+ }
+ if (name) {
+ match = (strcmp(pwd->pw_name, name) == 0);
+ }
+ else {
+ match = (pwd->pw_uid == uid);
+ }
+ if (match) {
+ fclose(fp);
+ *result = pwd;
+ return 0;
+ }
+ }
+ fclose(fp);
+ errno = EINVAL;
+ return -1;
+}
+
+int getpwnam_r(
+ const char *name,
+ struct passwd *pwd,
+ char *buffer,
+ size_t bufsize,
+ struct passwd **result
+)
+{
+ return getpw_r(name, 0, pwd, buffer, bufsize, result);
+}
+
+struct passwd *getpwnam(
+ const char *name
+)
+{
+ struct passwd *p;
+
+ if(getpwnam_r(name, &pwent, pwbuf, sizeof pwbuf, &p))
+ return NULL;
+ return p;
+}
+
+int getpwuid_r(
+ uid_t uid,
+ struct passwd *pwd,
+ char *buffer,
+ size_t bufsize,
+ struct passwd **result
+)
+{
+ return getpw_r(NULL, uid, pwd, buffer, bufsize, result);
+}
+
+struct passwd *getpwuid(
+ uid_t uid
+)
+{
+ struct passwd *p;
+
+ if(getpwuid_r(uid, &pwent, pwbuf, sizeof pwbuf, &p))
+ return NULL;
+ return p;
+}
+
+struct passwd *getpwent()
+{
+ if (passwd_fp == NULL)
+ return NULL;
+ if (!scanpw(passwd_fp, &pwent, pwbuf, sizeof pwbuf))
+ return NULL;
+ return &pwent;
+}
+
+void setpwent(void)
+{
+ init_etc_passwd_group();
+
+ if (passwd_fp != NULL)
+ fclose(passwd_fp);
+ passwd_fp = fopen("/etc/passwd", "r");
+}
+
+void endpwent(void)
+{
+ if (passwd_fp != NULL)
+ fclose(passwd_fp);
+}
+
+/*
+ * Extract a single group record from the database
+ */
+static int scangr(
+ FILE *fp,
+ struct group *grp,
+ char *buffer,
+ size_t bufsize
+)
+{
+ int grgid;
+ char *grmem, *cp;
+ int memcount;
+
+ if (!scanString(fp, &grp->gr_name, &buffer, &bufsize, 0)
+ || !scanString(fp, &grp->gr_passwd, &buffer, &bufsize, 0)
+ || !scanInt(fp, &grgid)
+ || !scanString(fp, &grmem, &buffer, &bufsize, 1))
+ return 0;
+ grp->gr_gid = grgid;
+
+ /*
+ * Determine number of members
+ */
+ for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) {
+ if(*cp == ',')
+ memcount++;
+ }
+
+ /*
+ * Hack to produce (hopefully) a suitably-aligned array of pointers
+ */
+ if (bufsize < (((memcount+1)*sizeof(char *)) + 15))
+ return 0;
+ grp->gr_mem = (char **)(((unsigned long)buffer + 15) & ~15);
+
+ /*
+ * Fill in pointer array
+ */
+ grp->gr_mem[0] = grmem;
+ for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) {
+ if(*cp == ',') {
+ *cp = '\0';
+ grp->gr_mem[memcount++] = cp + 1;
+ }
+ }
+ grp->gr_mem[memcount] = NULL;
+ return 1;
+}
+
+static int getgr_r(
+ const char *name,
+ int gid,
+ struct group *grp,
+ char *buffer,
+ size_t bufsize,
+ struct group **result
+)
+{
+ FILE *fp;
+ int match;
+
+ init_etc_passwd_group();
+
+ if ((fp = fopen("/etc/group", "r")) == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ for(;;) {
+ if (!scangr(fp, grp, buffer, bufsize)) {
+ errno = EINVAL;
+ fclose(fp);
+ return -1;
+ }
+ if (name) {
+ match = (strcmp(grp->gr_name, name) == 0);
+ }
+ else {
+ match = (grp->gr_gid == gid);
+ }
+ if (match) {
+ fclose(fp);
+ *result = grp;
+ return 0;
+ }
+ }
+ fclose(fp);
+ errno = EINVAL;
+ return -1;
+}
+
+int getgrnam_r(
+ const char *name,
+ struct group *grp,
+ char *buffer,
+ size_t bufsize,
+ struct group **result
+)
+{
+ return getgr_r(name, 0, grp, buffer, bufsize, result);
+}
+
+struct group *getgrnam(
+ const char *name
+)
+{
+ struct group *p;
+
+ if(getgrnam_r(name, &grent, grbuf, sizeof grbuf, &p))
+ return NULL;
+ return p;
+}
+
+int getgrgid_r(
+ gid_t gid,
+ struct group *grp,
+ char *buffer,
+ size_t bufsize,
+ struct group **result
+)
+{
+ return getgr_r(NULL, gid, grp, buffer, bufsize, result);
+}
+
+struct group *getgrgid(
+ gid_t gid
+)
+{
+ struct group *p;
+
+ if(getgrgid_r(gid, &grent, grbuf, sizeof grbuf, &p))
+ return NULL;
+ return p;
+}
+
+struct group *getgrent()
+{
+ if (group_fp == NULL)
+ return NULL;
+ if (!scangr(group_fp, &grent, grbuf, sizeof grbuf))
+ return NULL;
+ return &grent;
+}
+
+void setgrent(void)
+{
+ init_etc_passwd_group();
+
+ if (group_fp != NULL)
+ fclose(group_fp);
+ group_fp = fopen("/etc/group", "r");
+}
+
+void endgrent(void)
+{
+ if (group_fp != NULL)
+ fclose(group_fp);
+}
diff --git a/cpukit/libcsupport/src/getuid.c b/cpukit/libcsupport/src/getuid.c
new file mode 100644
index 0000000000..65e3184005
--- /dev/null
+++ b/cpukit/libcsupport/src/getuid.c
@@ -0,0 +1,47 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+
+#include <rtems/userenv.h>
+
+/*
+ * MACRO in userenv.h
+ *
+uid_t _POSIX_types_Uid = 0;
+*/
+
+/*PAGE
+ *
+ * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs,
+ * P1003.1b-1993, p. 84
+ */
+
+uid_t getuid( void )
+{
+ return _POSIX_types_Uid;
+}
+
+/*PAGE
+ *
+ * 4.2.2 Set User and Group IDs, P1003.1b-1993, p. 84
+ */
+
+int setuid(
+ uid_t uid
+)
+{
+ _POSIX_types_Uid = uid;
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/gxx_wrappers.c b/cpukit/libcsupport/src/gxx_wrappers.c
new file mode 100644
index 0000000000..d0789fc152
--- /dev/null
+++ b/cpukit/libcsupport/src/gxx_wrappers.c
@@ -0,0 +1,244 @@
+/*
+ * RTEMS threads compatibily routines for libgcc2.
+ *
+ * by: Rosimildo da Silva ( rdasilva@connecttel.com
+ *
+ * Used ideas from:
+ * W. Eric Norum
+ * Canadian Light Source
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@cls.usask.ca
+ *
+ * Eric sent some e-mail in the rtems-list as a start point for this
+ * module implementation.
+ *
+ * $Id$
+ */
+
+/*
+ * This file is only used if using gcc
+ */
+#if defined(__GNUC__)
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* We might not need, defined just in case */
+#define __RTEMS_INSIDE__ 1
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <rtems.h>
+#include <rtems/system.h>
+#include <rtems/error.h> /* rtems_panic */
+#include <rtems/rtems/tasks.h>
+
+/*
+ * These typedefs should match with the ones defined in the file
+ * gcc/gthr-rtems.h in the gcc distribution.
+ */
+typedef void *__gthread_key_t;
+typedef int __gthread_once_t;
+typedef void *__gthread_mutex_t;
+typedef void *__gthread_recursive_mutex_t;
+
+/* uncomment this if you need to debug this interface */
+
+/*
+#define DEBUG_GXX_WRAPPERS 1
+*/
+
+#ifdef DEBUG_GXX_WRAPPERS
+/* local function to return the ID of the calling thread */
+static rtems_id get_tid( void )
+{
+ rtems_id id = 0;
+ rtems_task_ident( RTEMS_SELF, 0, &id );
+ return id;
+}
+#endif
+
+
+int rtems_gxx_once(__gthread_once_t *once, void (*func) (void))
+{
+#ifdef DEBUG_GXX_WRAPPERS
+ printk( "gxx_wrappers: once=%x, func=%x\n", *once, func );
+#endif
+ if( *(volatile __gthread_once_t *)once == 0 )
+ {
+ rtems_mode saveMode;
+ rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &saveMode);
+ if( *(volatile __gthread_once_t *)once == 0 )
+ {
+ *(volatile __gthread_once_t *)once = 1;
+ (*func)();
+ }
+ rtems_task_mode(saveMode, RTEMS_PREEMPT_MASK, &saveMode);
+ }
+ return 0;
+}
+
+
+int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *))
+{
+ /* Ok, this can be a bit tricky. We are going to return a "key" as a
+ * pointer to the buffer that will hold the value of the key itself.
+ * We have to to this, because the others functions on this interface
+ * deal with the value of the key, as used with the POSIX API.
+ */
+ /* Do not pull your hair, trust me this works. :-) */
+ __gthread_key_t *new_key = ( __gthread_key_t * )malloc( sizeof( __gthread_key_t ) );
+ *key = ( __gthread_key_t )new_key;
+ *new_key = NULL;
+
+#ifdef DEBUG_GXX_WRAPPERS
+ printk( "gxx_wrappers: create key=%x, dtor=%x, new_key=%x\n", key, dtor, new_key );
+#endif
+ /* register with RTEMS the buffer that will hold the key values */
+ if( rtems_task_variable_add( RTEMS_SELF, (void **)new_key, NULL ) == RTEMS_SUCCESSFUL )
+ return 0;
+ return -1;
+}
+
+int rtems_gxx_key_dtor (__gthread_key_t key, void *ptr)
+{
+#ifdef DEBUG_GXX_WRAPPERS
+ printk( "gxx_wrappers: dtor key=%x, ptr=%x\n", key, ptr );
+#endif
+ *(void **)key = 0;
+ return 0;
+}
+
+int rtems_gxx_key_delete (__gthread_key_t key)
+{
+#ifdef DEBUG_GXX_WRAPPERS
+ printk( "gxx_wrappers: delete key=%x\n", key );
+#endif
+ /* register with RTEMS the buffer that will hold the key values */
+ if( rtems_task_variable_delete( RTEMS_SELF, (void **)key ) == RTEMS_SUCCESSFUL )
+ {
+ if( key ) free( (void *)key );
+ return 0;
+ }
+ return 0;
+}
+
+
+void *rtems_gxx_getspecific(__gthread_key_t key)
+{
+ void *p= 0;
+
+ /* register with RTEMS the buffer that will hold the key values */
+ if( rtems_task_variable_get( RTEMS_SELF, (void **)key, &p ) == RTEMS_SUCCESSFUL )
+ {
+ /* We do not have to do this, but what the heck ! */
+ p= *( void **)key;
+ }
+ else
+ {
+ /* fisrt time, always set to zero, it is unknown the value that the others
+ * threads are using at the moment of this call
+ */
+ if( rtems_task_variable_add( RTEMS_SELF, (void **)key, NULL ) != RTEMS_SUCCESSFUL )
+ {
+ rtems_panic ("rtems_gxx_getspecific");
+ }
+ *( void ** )key = (void *)0;
+ }
+
+#ifdef DEBUG_GXX_WRAPPERS
+ printk( "gxx_wrappers: getspecific key=%x, ptr=%x, id=%x\n", key, p, get_tid() );
+#endif
+ return p;
+}
+
+
+int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr)
+{
+#ifdef DEBUG_GXX_WRAPPERS
+ printk( "gxx_wrappers: setspecific key=%x, ptr=%x, id=%x\n", key, ptr, get_tid() );
+#endif
+ /* register with RTEMS the buffer that will hold the key values */
+ if( rtems_task_variable_add( RTEMS_SELF, (void **)key, NULL ) == RTEMS_SUCCESSFUL )
+ {
+ /* now let's set the proper value */
+ *( void ** )key = (void *)ptr;
+ return 0;
+ }
+ return -1;
+}
+
+
+/*
+ * MUTEX support
+ */
+void rtems_gxx_mutex_init (__gthread_mutex_t *mutex)
+{
+#ifdef DEBUG_GXX_WRAPPERS
+ printk( "gxx_wrappers: mutex init =%X\n", *mutex );
+#endif
+ if( rtems_semaphore_create( rtems_build_name ('G', 'C', 'C', '2'),
+ 1,
+ RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE
+ |RTEMS_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
+ 0,
+ (rtems_id *)mutex ) != RTEMS_SUCCESSFUL )
+ {
+ rtems_panic ("rtems_gxx_mutex_init");
+ }
+#ifdef DEBUG_GXX_WRAPPERS
+ printk( "gxx_wrappers: mutex init complete =%X\n", *mutex );
+#endif
+}
+
+int rtems_gxx_mutex_lock (__gthread_mutex_t *mutex)
+{
+#ifdef DEBUG_GXX_WRAPPERS
+ printk( "gxx_wrappers: lock mutex=%X\n", *mutex );
+#endif
+ return ( rtems_semaphore_obtain( (rtems_id)*mutex,
+ RTEMS_WAIT, RTEMS_NO_TIMEOUT ) == RTEMS_SUCCESSFUL) ? 0 : -1;
+}
+
+int rtems_gxx_mutex_trylock (__gthread_mutex_t *mutex)
+{
+#ifdef DEBUG_GXX_WRAPPERS
+ printk( "gxx_wrappers: trylock mutex=%X\n", *mutex );
+#endif
+ return (rtems_semaphore_obtain ((rtems_id)*mutex,
+ RTEMS_NO_WAIT, 0) == RTEMS_SUCCESSFUL) ? 0 : -1;
+}
+
+int rtems_gxx_mutex_unlock (__gthread_mutex_t *mutex)
+{
+#ifdef DEBUG_GXX_WRAPPERS
+ printk( "gxx_wrappers: unlock mutex=%X\n", *mutex );
+#endif
+ return (rtems_semaphore_release( (rtems_id)*mutex ) == RTEMS_SUCCESSFUL) ? 0 :-1;
+}
+
+void rtems_gxx_recursive_mutex_init(__gthread_recursive_mutex_t *mutex)
+{
+ rtems_gxx_mutex_init(mutex);
+}
+
+int rtems_gxx_recursive_mutex_lock(__gthread_recursive_mutex_t *mutex)
+{
+ return rtems_gxx_mutex_lock(mutex);
+}
+
+int rtems_gxx_recursive_mutex_trylock(__gthread_recursive_mutex_t *mutex)
+{
+ return rtems_gxx_mutex_trylock(mutex);
+}
+
+int rtems_gxx_recursive_mutex_unlock(__gthread_recursive_mutex_t *mutex)
+{
+ return rtems_gxx_mutex_unlock(mutex);
+}
+
+#endif /* __GNUC__ */
diff --git a/cpukit/libcsupport/src/hosterr.c b/cpukit/libcsupport/src/hosterr.c
new file mode 100644
index 0000000000..e5023a8a23
--- /dev/null
+++ b/cpukit/libcsupport/src/hosterr.c
@@ -0,0 +1,51 @@
+/*
+ * Routines to access a host errno
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_UNIX)
+#include <errno.h>
+
+int host_errno( void );
+
+/*
+ * fix_syscall_errno
+ *
+ * copy host errno, if any to thread aware errno, if any
+ */
+
+void fix_syscall_errno( void )
+{
+ errno = host_errno();
+}
+
+/*
+ * host_errno
+ *
+ * Get the host system errno, if any
+ * When using newlib (or possibly other libc's) on top of UNIX
+ * the errno returned by system calls may be unavailable due
+ * to trickery of making errno thread aware.
+ * This provides a kludge of getting at it.
+ */
+
+#undef errno
+extern int errno;
+int host_errno(void)
+{
+ return errno;
+}
+#endif
diff --git a/cpukit/libcsupport/src/ioctl.c b/cpukit/libcsupport/src/ioctl.c
new file mode 100644
index 0000000000..ea05340a9d
--- /dev/null
+++ b/cpukit/libcsupport/src/ioctl.c
@@ -0,0 +1,60 @@
+/*
+ * ioctl() system call
+ *
+ * This routine is not defined in the POSIX 1003.1b standard but is
+ * commonly supported on most UNIX and POSIX systems.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+#include <unistd.h>
+
+int ioctl(
+ int fd,
+ int command,
+ ...
+)
+{
+ va_list ap;
+ rtems_status_code rc;
+ rtems_libio_t *iop;
+ void *buffer;
+
+ rtems_libio_check_fd( fd );
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_is_open(iop);
+
+ va_start(ap, command);
+
+ buffer = va_arg(ap, void *);
+
+ /*
+ * Now process the ioctl().
+ */
+
+ if ( !iop->handlers )
+ rtems_set_errno_and_return_minus_one( EBADF );
+
+ if ( !iop->handlers->ioctl_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ rc = (*iop->handlers->ioctl_h)( iop, command, buffer );
+
+ return rc;
+}
diff --git a/cpukit/libcsupport/src/isatty.c b/cpukit/libcsupport/src/isatty.c
new file mode 100644
index 0000000000..d1ee06ee97
--- /dev/null
+++ b/cpukit/libcsupport/src/isatty.c
@@ -0,0 +1,31 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/stat.h>
+
+int isatty(
+ int fd
+)
+{
+ struct stat buf;
+
+ if (fstat (fd, &buf) < 0)
+ return 0;
+
+ if (S_ISCHR (buf.st_mode))
+ return 1;
+
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/libio.c b/cpukit/libcsupport/src/libio.c
new file mode 100644
index 0000000000..0c42b61854
--- /dev/null
+++ b/cpukit/libcsupport/src/libio.c
@@ -0,0 +1,338 @@
+/*
+ * This file contains the support infrastructure used to manage the
+ * table of integer style file descriptors used by the low level
+ * POSIX system calls like open(), read, fstat(), etc.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/libio_.h> /* libio_.h pulls in rtems */
+#include <rtems.h>
+#include <rtems/assoc.h> /* assoc.h not included by rtems.h */
+
+#include <stdio.h> /* O_RDONLY, et.al. */
+#include <fcntl.h> /* O_RDONLY, et.al. */
+#include <assert.h>
+#include <errno.h>
+
+/* define this to alias O_NDELAY to O_NONBLOCK, i.e.,
+ * O_NDELAY is accepted on input but fcntl(F_GETFL) returns
+ * O_NONBLOCK. This is because rtems has no distinction
+ * between the two (but some systems have).
+ * Note that accepting this alias creates a problem:
+ * an application trying to clear the non-blocking flag
+ * using a
+ *
+ * fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NDELAY);
+ *
+ * does (silently) ignore the operation.
+ */
+#undef ACCEPT_O_NDELAY_ALIAS
+
+#include <errno.h>
+#include <string.h> /* strcmp */
+#include <unistd.h>
+#include <stdlib.h> /* calloc() */
+
+#include <rtems/libio.h> /* libio.h not pulled in by rtems */
+
+/*
+ * File descriptor Table Information
+ */
+
+extern uint32_t rtems_libio_number_iops;
+rtems_id rtems_libio_semaphore;
+rtems_libio_t *rtems_libio_iops;
+rtems_libio_t *rtems_libio_iop_freelist;
+
+/*
+ * rtems_libio_init
+ *
+ * Called by BSP startup code to initialize the libio subsystem.
+ */
+
+void rtems_libio_init( void )
+{
+ rtems_status_code rc;
+ int i;
+ rtems_libio_t *iop;
+
+ if (rtems_libio_number_iops > 0)
+ {
+ rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops,
+ sizeof(rtems_libio_t));
+ if (rtems_libio_iops == NULL)
+ rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
+
+ iop = rtems_libio_iop_freelist = rtems_libio_iops;
+ for (i = 0 ; i < (rtems_libio_number_iops - 1) ; i++, iop++)
+ iop->data1 = iop + 1;
+ iop->data1 = NULL;
+ }
+
+ /*
+ * Create the binary semaphore used to provide mutual exclusion
+ * on the IOP Table.
+ */
+
+ rc = rtems_semaphore_create(
+ RTEMS_LIBIO_SEM,
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
+ RTEMS_NO_PRIORITY,
+ &rtems_libio_semaphore
+ );
+ if ( rc != RTEMS_SUCCESSFUL )
+ rtems_fatal_error_occurred( rc );
+
+ /*
+ * Initialize the base file system infrastructure.
+ */
+
+ rtems_filesystem_initialize();
+}
+
+/*
+ * rtems_libio_fcntl_flags
+ *
+ * Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
+ */
+
+rtems_assoc_t access_modes_assoc[] = {
+ { "READ", LIBIO_FLAGS_READ, O_RDONLY },
+ { "WRITE", LIBIO_FLAGS_WRITE, O_WRONLY },
+ { "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
+ { 0, 0, 0 },
+};
+
+rtems_assoc_t status_flags_assoc[] = {
+#ifdef ACCEPT_O_NDELAY_ALIAS
+ { "NO DELAY", LIBIO_FLAGS_NO_DELAY, O_NDELAY },
+#endif
+ { "NONBLOCK", LIBIO_FLAGS_NO_DELAY, O_NONBLOCK },
+ { "APPEND", LIBIO_FLAGS_APPEND, O_APPEND },
+ { "CREATE", LIBIO_FLAGS_CREATE, O_CREAT },
+ { 0, 0, 0 },
+};
+
+uint32_t rtems_libio_fcntl_flags(
+ uint32_t fcntl_flags
+)
+{
+ uint32_t flags = 0;
+ uint32_t access_modes;
+
+ /*
+ * Access mode is a small integer
+ */
+
+ access_modes = fcntl_flags & O_ACCMODE;
+ fcntl_flags &= ~O_ACCMODE;
+ flags = rtems_assoc_local_by_remote( access_modes_assoc, access_modes );
+
+ /*
+ * Everything else is single bits
+ */
+
+ flags |=
+ rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
+ return flags;
+}
+
+/*
+ * rtems_libio_to_fcntl_flags
+ *
+ * Convert RTEMS internal flags to UNIX fnctl(2) flags
+ */
+
+uint32_t rtems_libio_to_fcntl_flags(
+ uint32_t flags
+)
+{
+ uint32_t fcntl_flags = 0;
+
+ if ( (flags & LIBIO_FLAGS_READ_WRITE) == LIBIO_FLAGS_READ_WRITE ) {
+ fcntl_flags |= O_RDWR;
+ } else if ( (flags & LIBIO_FLAGS_READ) == LIBIO_FLAGS_READ) {
+ fcntl_flags |= O_RDONLY;
+ } else if ( (flags & LIBIO_FLAGS_WRITE) == LIBIO_FLAGS_WRITE) {
+ fcntl_flags |= O_WRONLY;
+ }
+
+ if ( (flags & LIBIO_FLAGS_NO_DELAY) == LIBIO_FLAGS_NO_DELAY ) {
+ fcntl_flags |= O_NONBLOCK;
+ }
+
+ if ( (flags & LIBIO_FLAGS_APPEND) == LIBIO_FLAGS_APPEND ) {
+ fcntl_flags |= O_APPEND;
+ }
+
+ if ( (flags & LIBIO_FLAGS_CREATE) == LIBIO_FLAGS_CREATE ) {
+ fcntl_flags |= O_CREAT;
+ }
+
+ return fcntl_flags;
+}
+
+/*
+ * rtems_libio_allocate
+ *
+ * This routine searches the IOP Table for an unused entry. If it
+ * finds one, it returns it. Otherwise, it returns NULL.
+ */
+
+rtems_libio_t *rtems_libio_allocate( void )
+{
+ rtems_libio_t *iop, *next;
+ rtems_status_code rc;
+
+ rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+
+ if (rtems_libio_iop_freelist) {
+ iop = rtems_libio_iop_freelist;
+ next = iop->data1;
+ (void) memset( iop, 0, sizeof(rtems_libio_t) );
+ iop->flags = LIBIO_FLAGS_OPEN;
+ rc = rtems_semaphore_create(
+ RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
+ RTEMS_NO_PRIORITY,
+ &iop->sem
+ );
+ if (rc != RTEMS_SUCCESSFUL)
+ goto failed;
+ rtems_libio_iop_freelist = next;
+ goto done;
+ }
+
+failed:
+ iop = 0;
+
+done:
+ rtems_semaphore_release( rtems_libio_semaphore );
+ return iop;
+}
+
+/*
+ * rtems_libio_free
+ *
+ * This routine frees the resources associated with an IOP (file descriptor)
+ * and clears the slot in the IOP Table.
+ */
+
+void rtems_libio_free(
+ rtems_libio_t *iop
+)
+{
+ rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+
+ if (iop->sem)
+ rtems_semaphore_delete(iop->sem);
+
+ iop->flags &= ~LIBIO_FLAGS_OPEN;
+ iop->data1 = rtems_libio_iop_freelist;
+ rtems_libio_iop_freelist = iop;
+
+ rtems_semaphore_release(rtems_libio_semaphore);
+}
+
+/*
+ * rtems_libio_is_open_files_in_fs
+ *
+ * This routine scans the entire file descriptor table to determine if the
+ * are any active file descriptors that refer to the at least one node in the
+ * file system that we are trying to dismount.
+ *
+ * If there is at least one node in the file system referenced by the mount
+ * table entry a 1 is returned, otherwise a 0 is returned.
+ */
+
+int rtems_libio_is_open_files_in_fs(
+ rtems_filesystem_mount_table_entry_t * fs_mt_entry
+)
+{
+ rtems_libio_t *iop;
+ int result = 0;
+ int i;
+
+ rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+
+ /*
+ * Look for any active file descriptor entry.
+ */
+
+ for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
+
+ if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
+
+ /*
+ * Check if this node is under the file system that we
+ * are trying to dismount.
+ */
+
+ if ( iop->pathinfo.mt_entry == fs_mt_entry ) {
+ result = 1;
+ break;
+ }
+ }
+ }
+
+ rtems_semaphore_release( rtems_libio_semaphore );
+
+ return result;
+}
+
+/*
+ * rtems_libio_is_file_open
+ *
+ * This routine scans the entire file descriptor table to determine if the
+ * given file refers to an active file descriptor.
+ *
+ * If the given file is open a 1 is returned, otherwise a 0 is returned.
+ */
+
+int rtems_libio_is_file_open(
+ void *node_access
+)
+{
+ rtems_libio_t *iop;
+ int result=0;
+ int i;
+
+ rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+
+ /*
+ * Look for any active file descriptor entry.
+ */
+
+ for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
+ if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
+
+ /*
+ * Check if this node is under the file system that we
+ * are trying to dismount.
+ */
+
+ if ( iop->pathinfo.node_access == node_access ) {
+ result = 1;
+ break;
+ }
+ }
+ }
+
+ rtems_semaphore_release( rtems_libio_semaphore );
+
+ return result;
+}
diff --git a/cpukit/libcsupport/src/libio_sockets.c b/cpukit/libcsupport/src/libio_sockets.c
new file mode 100644
index 0000000000..88db941083
--- /dev/null
+++ b/cpukit/libcsupport/src/libio_sockets.c
@@ -0,0 +1,75 @@
+/*
+ * This file contains the support infrastructure used to manage the
+ * table of integer style file descriptors used by the socket calls.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/libio_.h> /* libio_.h pulls in rtems */
+#include <rtems.h>
+
+#include <errno.h>
+
+/*
+ * Convert an RTEMS file descriptor to a BSD socket pointer.
+ */
+
+struct socket *rtems_bsdnet_fdToSocket(
+ int fd
+)
+{
+ rtems_libio_t *iop;
+
+ /* same as rtems_libio_check_fd(_fd) but different return */
+ if ((uint32_t )fd >= rtems_libio_number_iops) {
+ errno = EBADF;
+ return NULL;
+ }
+ iop = &rtems_libio_iops[fd];
+
+ /* same as rtems_libio_check_is_open(iop) but different return */
+ if ((iop->flags & LIBIO_FLAGS_OPEN) == 0) {
+ errno = EBADF;
+ return NULL;
+ }
+
+ if (iop->data1 == NULL)
+ errno = EBADF;
+ return iop->data1;
+}
+
+/*
+ * Create an RTEMS file descriptor for a socket
+ */
+
+int rtems_bsdnet_makeFdForSocket(
+ void *so,
+ const rtems_filesystem_file_handlers_r *h
+)
+{
+ rtems_libio_t *iop;
+ int fd;
+
+ iop = rtems_libio_allocate();
+ if (iop == 0) {
+ errno = ENFILE;
+ return -1;
+ }
+ fd = iop - rtems_libio_iops;
+ iop->flags |= LIBIO_FLAGS_WRITE | LIBIO_FLAGS_READ;
+ iop->data0 = fd;
+ iop->data1 = so;
+ iop->handlers = (rtems_filesystem_file_handlers_r *) h;
+ return fd;
+}
diff --git a/cpukit/libcsupport/src/link.c b/cpukit/libcsupport/src/link.c
new file mode 100644
index 0000000000..217342e844
--- /dev/null
+++ b/cpukit/libcsupport/src/link.c
@@ -0,0 +1,104 @@
+/*
+ * link() - POSIX 1003.1b - 5.3.4 - Create a new link
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int link(
+ const char *existing,
+ const char *new
+)
+{
+ rtems_filesystem_location_info_t existing_loc;
+ rtems_filesystem_location_info_t parent_loc;
+ int i;
+ int result;
+ const char *name_start;
+
+ /*
+ * Get the node we are linking to.
+ */
+
+ result = rtems_filesystem_evaluate_path( existing, 0, &existing_loc, TRUE );
+ if ( result != 0 )
+ return -1;
+
+ /*
+ * Get the parent of the node we are creating.
+ */
+
+ rtems_filesystem_get_start_loc( new, &i, &parent_loc );
+
+ if ( !parent_loc.ops->evalformake_h ) {
+ rtems_filesystem_freenode( &existing_loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ result = (*parent_loc.ops->evalformake_h)( &new[i], &parent_loc, &name_start );
+ if ( result != 0 ) {
+ rtems_filesystem_freenode( &existing_loc );
+ rtems_set_errno_and_return_minus_one( result );
+ }
+
+ /*
+ * Check to see if the caller is trying to link across file system
+ * boundaries.
+ */
+
+ if ( parent_loc.mt_entry != existing_loc.mt_entry ) {
+ rtems_filesystem_freenode( &existing_loc );
+ rtems_filesystem_freenode( &parent_loc );
+ rtems_set_errno_and_return_minus_one( EXDEV );
+ }
+
+ if ( !parent_loc.ops->link_h ) {
+ rtems_filesystem_freenode( &existing_loc );
+ rtems_filesystem_freenode( &parent_loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ result = (*parent_loc.ops->link_h)( &existing_loc, &parent_loc, name_start );
+
+ rtems_filesystem_freenode( &existing_loc );
+ rtems_filesystem_freenode( &parent_loc );
+
+ return result;
+}
+
+/*
+ * _link_r
+ *
+ * This is the Newlib dependent reentrant version of link().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _link_r(
+ struct _reent *ptr,
+ const char *existing,
+ const char *new
+)
+{
+ return link( existing, new );
+}
+#endif
diff --git a/cpukit/libcsupport/src/lseek.c b/cpukit/libcsupport/src/lseek.c
new file mode 100644
index 0000000000..7146ae80e9
--- /dev/null
+++ b/cpukit/libcsupport/src/lseek.c
@@ -0,0 +1,101 @@
+/*
+ * lseek() - POSIX 1003.1b 6.5.3 - Reposition Read/Write File Offset
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+off_t lseek(
+ int fd,
+ off_t offset,
+ int whence
+)
+{
+ rtems_libio_t *iop;
+ off_t old_offset;
+ off_t status;
+
+ rtems_libio_check_fd( fd );
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_is_open(iop);
+
+ /*
+ * Check as many errors as possible before touching iop->offset.
+ */
+
+ if ( !iop->handlers->lseek_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ /*
+ * Now process the lseek().
+ */
+
+ old_offset = iop->offset;
+ switch ( whence ) {
+ case SEEK_SET:
+ iop->offset = offset;
+ break;
+
+ case SEEK_CUR:
+ iop->offset += offset;
+ break;
+
+ case SEEK_END:
+ iop->offset = iop->size + offset;
+ break;
+
+ default:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ /*
+ * At this time, handlers assume iop->offset has the desired
+ * new offset.
+ */
+
+ status = (*iop->handlers->lseek_h)( iop, offset, whence );
+ if ( status == (off_t) -1 )
+ iop->offset = old_offset;
+
+ /*
+ * So if the operation failed, we have to restore iop->offset.
+ */
+
+ return status;
+}
+
+/*
+ * _lseek_r
+ *
+ * This is the Newlib dependent reentrant version of lseek().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+off_t _lseek_r(
+ struct _reent *ptr,
+ int fd,
+ off_t offset,
+ int whence
+)
+{
+ return lseek( fd, offset, whence );
+}
+#endif
diff --git a/cpukit/libcsupport/src/lstat.c b/cpukit/libcsupport/src/lstat.c
new file mode 100644
index 0000000000..d51296cbe9
--- /dev/null
+++ b/cpukit/libcsupport/src/lstat.c
@@ -0,0 +1,22 @@
+/*
+ * lstat() - BSD 4.3 and SVR4 - Get File Status
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define _STAT_NAME lstat
+#define _STAT_R_NAME _lstat_r
+#define _STAT_FOLLOW_LINKS FALSE
+
+#include "stat.c"
diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c
new file mode 100644
index 0000000000..8f961cf8f3
--- /dev/null
+++ b/cpukit/libcsupport/src/malloc.c
@@ -0,0 +1,621 @@
+/*
+ * RTEMS Malloc Family Implementation
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+#include <rtems/libcsupport.h>
+#include <rtems/score/apimutex.h>
+#ifdef RTEMS_NEWLIB
+#include <sys/reent.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <unistd.h> /* sbrk(2) */
+
+#include <rtems/chain.h>
+
+#ifdef MALLOC_ARENA_CHECK
+#define SENTINELSIZE 12
+#define SENTINEL "\xD1\xAC\xB2\xF1" "BITE ME"
+#define CALLCHAINSIZE 5
+struct mallocNode {
+ struct mallocNode *back;
+ struct mallocNode *forw;
+ int callChain[CALLCHAINSIZE];
+ size_t size;
+ void *memory;
+};
+static struct mallocNode mallocNodeHead = { &mallocNodeHead, &mallocNodeHead };
+void reportMallocError(const char *msg, struct mallocNode *mp)
+{
+ unsigned char *sp = (unsigned char *)mp->memory + mp->size;
+ int i, ind = 0;
+ static char cbuf[500];
+ ind += sprintf(cbuf+ind, "Malloc Error: %s\n", msg);
+ if ((mp->forw->back != mp) || (mp->back->forw != mp))
+ ind += sprintf(cbuf+ind, "mp:0x%x mp->forw:0x%x mp->forw->back:0x%x mp->back:0x%x mp->back->forw:0x%x\n",
+ mp, mp->forw, mp->forw->back, mp->back, mp->back->forw);
+ if (mp->memory != (mp + 1))
+ ind += sprintf(cbuf+ind, "mp+1:0x%x ", mp + 1);
+ ind += sprintf(cbuf+ind, "mp->memory:0x%x mp->size:%d\n", mp->memory, mp->size);
+ if (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0) {
+ ind += sprintf(cbuf+ind, "mp->sentinel: ");
+ for (i = 0 ; i < SENTINELSIZE ; i++)
+ ind += sprintf(cbuf+ind, " 0x%x", sp[i]);
+ ind += sprintf(cbuf+ind, "\n");
+ }
+ ind += sprintf(cbuf+ind, "Call chain:");
+ for (i = 0 ; i < CALLCHAINSIZE ; i++) {
+ if (mp->callChain[i] == 0)
+ break;
+ ind += sprintf(cbuf+ind, " 0x%x", mp->callChain[i]);
+ }
+ printk("\n\n%s\n\n", cbuf);
+}
+#endif
+
+Chain_Control RTEMS_Malloc_GC_list;
+
+rtems_id RTEMS_Malloc_Heap;
+size_t RTEMS_Malloc_Sbrk_amount;
+
+#ifdef RTEMS_DEBUG
+#define MALLOC_STATS
+#define MALLOC_DIRTY
+#endif
+
+#ifdef MALLOC_STATS
+#define MSBUMP(f,n) rtems_malloc_stats.f += (n)
+
+struct {
+ uint32_t space_available; /* current size of malloc area */
+ uint32_t malloc_calls; /* # calls to malloc */
+ uint32_t free_calls;
+ uint32_t realloc_calls;
+ uint32_t calloc_calls;
+ uint32_t max_depth; /* most ever malloc'd at 1 time */
+ uint64_t lifetime_allocated;
+ uint64_t lifetime_freed;
+} rtems_malloc_stats;
+
+#else /* No rtems_malloc_stats */
+#define MSBUMP(f,n)
+#endif
+
+void RTEMS_Malloc_Initialize(
+ void *start,
+ size_t length,
+ size_t sbrk_amount
+)
+{
+ rtems_status_code status;
+ void *starting_address;
+ uint32_t old_address;
+ uint32_t u32_address;
+
+ /*
+ * Initialize the garbage collection list to start with nothing on it.
+ */
+ Chain_Initialize_empty(&RTEMS_Malloc_GC_list);
+
+ /*
+ * If the starting address is 0 then we are to attempt to
+ * get length worth of memory using sbrk. Make sure we
+ * align the address that we get back.
+ */
+
+ starting_address = start;
+ RTEMS_Malloc_Sbrk_amount = sbrk_amount;
+
+ if (!starting_address) {
+ u32_address = (unsigned int)sbrk(length);
+
+ if (u32_address == (uint32_t ) -1) {
+ rtems_fatal_error_occurred( RTEMS_NO_MEMORY );
+ /* DOES NOT RETURN!!! */
+ }
+
+ if (u32_address & (CPU_HEAP_ALIGNMENT-1)) {
+ old_address = u32_address;
+ u32_address = (u32_address + CPU_HEAP_ALIGNMENT) & ~(CPU_HEAP_ALIGNMENT-1);
+
+ /*
+ * adjust the length by whatever we aligned by
+ */
+
+ length -= u32_address - old_address;
+ }
+
+ starting_address = (void *)u32_address;
+ }
+
+ /*
+ * If the BSP is not clearing out the workspace, then it is most likely
+ * not clearing out the initial memory for the heap. There is no
+ * standard supporting zeroing out the heap memory. But much code
+ * with UNIX history seems to assume that memory malloc'ed during
+ * initialization (before any free's) is zero'ed. This is true most
+ * of the time under UNIX because zero'ing memory when it is first
+ * given to a process eliminates the chance of a process seeing data
+ * left over from another process. This would be a security violation.
+ */
+
+ if ( rtems_cpu_configuration_get_do_zero_of_workspace() )
+ memset( starting_address, 0, length );
+
+ /*
+ * Unfortunately we cannot use assert if this fails because if this
+ * has failed we do not have a heap and if we do not have a heap
+ * STDIO cannot work because there will be no buffers.
+ */
+
+ status = rtems_region_create(
+ rtems_build_name( 'H', 'E', 'A', 'P' ),
+ starting_address,
+ length,
+ CPU_HEAP_ALIGNMENT,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &RTEMS_Malloc_Heap
+ );
+ if ( status != RTEMS_SUCCESSFUL )
+ rtems_fatal_error_occurred( status );
+
+#ifdef MALLOC_STATS
+ /* zero all the stats */
+ (void) memset( &rtems_malloc_stats, 0, sizeof(rtems_malloc_stats) );
+#endif
+
+ MSBUMP(space_available, length);
+}
+
+#ifdef RTEMS_NEWLIB
+void *malloc(
+ size_t size
+)
+{
+ void *return_this;
+ void *starting_address;
+ uint32_t the_size;
+ uint32_t sbrk_amount;
+ rtems_status_code status;
+ Chain_Node *to_be_freed;
+
+ MSBUMP(malloc_calls, 1);
+
+ if ( !size )
+ return (void *) 0;
+
+ /*
+ * Do not attempt to allocate memory if in a critical section or ISR.
+ */
+
+ if (_System_state_Is_up(_System_state_Get())) {
+ if (_Thread_Dispatch_disable_level > 0)
+ return (void *) 0;
+
+ if (_ISR_Nest_level > 0)
+ return (void *) 0;
+ }
+
+ /*
+ * If some free's have been deferred, then do them now.
+ */
+ while ((to_be_freed = Chain_Get(&RTEMS_Malloc_GC_list)) != NULL)
+ free(to_be_freed);
+
+ /*
+ * Try to give a segment in the current region if there is not
+ * enough space then try to grow the region using rtems_region_extend().
+ * If this fails then return a NULL pointer.
+ */
+
+#ifdef MALLOC_ARENA_CHECK
+ size += sizeof(struct mallocNode) + SENTINELSIZE;
+#endif
+ status = rtems_region_get_segment(
+ RTEMS_Malloc_Heap,
+ size,
+ RTEMS_NO_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &return_this
+ );
+
+ if ( status != RTEMS_SUCCESSFUL ) {
+ /*
+ * Round to the "requested sbrk amount" so hopefully we won't have
+ * to grow again for a while. This effectively does sbrk() calls
+ * in "page" amounts.
+ */
+
+ sbrk_amount = RTEMS_Malloc_Sbrk_amount;
+
+ if ( sbrk_amount == 0 )
+ return (void *) 0;
+
+ the_size = ((size + sbrk_amount) / sbrk_amount * sbrk_amount);
+
+ if ((starting_address = (void *)sbrk(the_size))
+ == (void*) -1)
+ return (void *) 0;
+
+ status = rtems_region_extend(
+ RTEMS_Malloc_Heap,
+ starting_address,
+ the_size
+ );
+ if ( status != RTEMS_SUCCESSFUL ) {
+ sbrk(-the_size);
+ errno = ENOMEM;
+ return (void *) 0;
+ }
+
+ MSBUMP(space_available, the_size);
+
+ status = rtems_region_get_segment(
+ RTEMS_Malloc_Heap,
+ size,
+ RTEMS_NO_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &return_this
+ );
+ if ( status != RTEMS_SUCCESSFUL ) {
+ errno = ENOMEM;
+ return (void *) 0;
+ }
+ }
+
+#ifdef MALLOC_STATS
+ if (return_this)
+ {
+ size_t actual_size;
+ uint32_t current_depth;
+ status = rtems_region_get_segment_size(
+ RTEMS_Malloc_Heap, return_this, &actual_size);
+ MSBUMP(lifetime_allocated, actual_size);
+ current_depth = rtems_malloc_stats.lifetime_allocated -
+ rtems_malloc_stats.lifetime_freed;
+ if (current_depth > rtems_malloc_stats.max_depth)
+ rtems_malloc_stats.max_depth = current_depth;
+ }
+#endif
+
+#ifdef MALLOC_DIRTY
+ (void) memset(return_this, 0xCF, size);
+#endif
+
+#ifdef MALLOC_ARENA_CHECK
+ {
+ struct mallocNode *mp = (struct mallocNode *)return_this;
+ int key, *fp, *nfp, i;
+ rtems_interrupt_disable(key);
+ mp->memory = mp + 1;
+ return_this = mp->memory;
+ mp->size = size - (sizeof(struct mallocNode) + SENTINELSIZE);
+ fp = (int *)&size - 2;
+ for (i = 0 ; i < CALLCHAINSIZE ; i++) {
+ mp->callChain[i] = fp[1];
+ nfp = (int *)(fp[0]);
+ if((nfp <= fp) || (nfp > (int *)(1 << 24)))
+ break;
+ fp = nfp;
+ }
+ while (i < CALLCHAINSIZE)
+ mp->callChain[i++] = 0;
+ memcpy((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE);
+ mp->forw = mallocNodeHead.forw;
+ mp->back = &mallocNodeHead;
+ mallocNodeHead.forw->back = mp;
+ mallocNodeHead.forw = mp;
+ rtems_interrupt_enable(key);
+ }
+#endif
+ return return_this;
+}
+
+void *calloc(
+ size_t nelem,
+ size_t elsize
+)
+{
+ register char *cptr;
+ int length;
+
+ MSBUMP(calloc_calls, 1);
+
+ length = nelem * elsize;
+ cptr = malloc( length );
+ if ( cptr )
+ memset( cptr, '\0', length );
+
+ MSBUMP(malloc_calls, -1); /* subtract off the malloc */
+
+ return cptr;
+}
+
+void *realloc(
+ void *ptr,
+ size_t size
+)
+{
+ size_t old_size;
+ rtems_status_code status;
+ char *new_area;
+
+ MSBUMP(realloc_calls, 1);
+
+ /*
+ * Do not attempt to allocate memory if in a critical section or ISR.
+ */
+
+ if (_System_state_Is_up(_System_state_Get())) {
+ if (_Thread_Dispatch_disable_level > 0)
+ return (void *) 0;
+
+ if (_ISR_Nest_level > 0)
+ return (void *) 0;
+ }
+
+ /*
+ * Continue with realloc().
+ */
+ if ( !ptr )
+ return malloc( size );
+
+ if ( !size ) {
+ free( ptr );
+ return (void *) 0;
+ }
+
+#ifdef MALLOC_ARENA_CHECK
+ {
+ void *np;
+ np = malloc(size);
+ if (!np) return np;
+ memcpy(np,ptr,size);
+ free(ptr);
+ return np;
+ }
+#endif
+ status =
+ rtems_region_resize_segment( RTEMS_Malloc_Heap, ptr, size, &old_size );
+
+ if( status == RTEMS_SUCCESSFUL ) {
+ return ptr;
+ }
+ else if ( status != RTEMS_UNSATISFIED ) {
+ errno = EINVAL;
+ return (void *) 0;
+ }
+
+ new_area = malloc( size );
+
+ MSBUMP(malloc_calls, -1); /* subtract off the malloc */
+
+ /*
+ * There used to be a free on this error case but it is wrong to
+ * free the memory per OpenGroup Single UNIX Specification V2
+ * and the C Standard.
+ */
+
+ if ( !new_area ) {
+ return (void *) 0;
+ }
+
+ status = rtems_region_get_segment_size( RTEMS_Malloc_Heap, ptr, &old_size );
+ if ( status != RTEMS_SUCCESSFUL ) {
+ errno = EINVAL;
+ return (void *) 0;
+ }
+
+ memcpy( new_area, ptr, (size < old_size) ? size : old_size );
+ free( ptr );
+
+ return new_area;
+
+}
+
+void free(
+ void *ptr
+)
+{
+ rtems_status_code status;
+
+ MSBUMP(free_calls, 1);
+
+ if ( !ptr )
+ return;
+
+ /*
+ * Do not attempt to free memory if in a critical section or ISR.
+ */
+
+ if (_System_state_Is_up(_System_state_Get())) {
+ if ((_Thread_Dispatch_disable_level > 0) || (_ISR_Nest_level > 0)) {
+ Chain_Append(&RTEMS_Malloc_GC_list, (Chain_Node *)ptr);
+ return;
+ }
+ }
+
+#ifdef MALLOC_ARENA_CHECK
+ {
+ struct mallocNode *mp = (struct mallocNode *)ptr - 1;
+ struct mallocNode *mp1;
+ int key;
+ rtems_interrupt_disable(key);
+ if ((mp->memory != (mp + 1))
+ || (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0))
+ reportMallocError("Freeing with inconsistent pointer/sentinel", mp);
+ mp1 = mallocNodeHead.forw;
+ while (mp1 != &mallocNodeHead) {
+ if (mp1 == mp)
+ break;
+ mp1 = mp1->forw;
+ }
+ if (mp1 != mp)
+ reportMallocError("Freeing, but not on allocated list", mp);
+ mp->forw->back = mp->back;
+ mp->back->forw = mp->forw;
+ mp->back = mp->forw = NULL;
+ ptr = mp;
+ rtems_interrupt_enable(key);
+ }
+#endif
+#ifdef MALLOC_STATS
+ {
+ size_t size;
+ status = rtems_region_get_segment_size( RTEMS_Malloc_Heap, ptr, &size );
+ if ( status == RTEMS_SUCCESSFUL ) {
+ MSBUMP(lifetime_freed, size);
+ }
+ }
+#endif
+
+ status = rtems_region_return_segment( RTEMS_Malloc_Heap, ptr );
+ if ( status != RTEMS_SUCCESSFUL ) {
+ errno = EINVAL;
+ assert( 0 );
+ }
+}
+
+#ifdef MALLOC_ARENA_CHECK
+void checkMallocArena(void)
+{
+ struct mallocNode *mp = mallocNodeHead.forw;
+ int key;
+ rtems_interrupt_disable(key);
+ while (mp != &mallocNodeHead) {
+ if ((mp->forw->back != mp)
+ || (mp->back->forw != mp))
+ reportMallocError("Pointers mangled", mp);
+ if((mp->memory != (mp + 1))
+ || (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0))
+ reportMallocError("Inconsistent pointer/sentinel", mp);
+ mp = mp->forw;
+ }
+ rtems_interrupt_enable(key);
+}
+#endif
+
+/* end if RTEMS_NEWLIB */
+#endif
+
+#ifdef MALLOC_STATS
+/*
+ * Dump the malloc statistics
+ * May be called via atexit() (installable by our bsp) or
+ * at any time by user
+ */
+
+void malloc_dump(void)
+{
+ uint32_t allocated = rtems_malloc_stats.lifetime_allocated -
+ rtems_malloc_stats.lifetime_freed;
+
+ printf("Malloc stats\n");
+ printf(" avail:%uk allocated:%uk (%d%%) "
+ "max:%uk (%d%%) lifetime:%Luk freed:%Luk\n",
+ (unsigned int) rtems_malloc_stats.space_available / 1024,
+ (unsigned int) allocated / 1024,
+ /* avoid float! */
+ (allocated * 100) / rtems_malloc_stats.space_available,
+ (unsigned int) rtems_malloc_stats.max_depth / 1024,
+ (rtems_malloc_stats.max_depth * 100) / rtems_malloc_stats.space_available,
+ (uint64_t ) rtems_malloc_stats.lifetime_allocated / 1024,
+ (uint64_t ) rtems_malloc_stats.lifetime_freed / 1024);
+ printf(" Call counts: malloc:%d free:%d realloc:%d calloc:%d\n",
+ rtems_malloc_stats.malloc_calls,
+ rtems_malloc_stats.free_calls,
+ rtems_malloc_stats.realloc_calls,
+ rtems_malloc_stats.calloc_calls);
+}
+
+
+void malloc_walk(size_t source, size_t printf_enabled)
+{
+ register Region_Control *the_region;
+ Objects_Locations location;
+
+ _RTEMS_Lock_allocator(); /* to prevent deletion */
+ the_region = _Region_Get( RTEMS_Malloc_Heap, &location );
+ if ( location == OBJECTS_LOCAL )
+ {
+ _Heap_Walk( &the_region->Memory, source, printf_enabled );
+ }
+ _RTEMS_Unlock_allocator();
+}
+
+#else
+
+void malloc_dump(void)
+{
+ return;
+}
+
+void malloc_walk(size_t source, size_t printf_enabled)
+{
+ return;
+}
+
+#endif
+
+/*
+ * "Reentrant" versions of the above routines implemented above.
+ */
+
+#ifdef RTEMS_NEWLIB
+void *_malloc_r(
+ struct _reent *ignored,
+ size_t size
+)
+{
+ return malloc( size );
+}
+
+void *_calloc_r(
+ struct _reent *ignored,
+ size_t nelem,
+ size_t elsize
+)
+{
+ return calloc( nelem, elsize );
+}
+
+void *_realloc_r(
+ struct _reent *ignored,
+ void *ptr,
+ size_t size
+)
+{
+ return realloc( ptr, size );
+}
+
+void _free_r(
+ struct _reent *ignored,
+ void *ptr
+)
+{
+ free( ptr );
+}
+
+#endif
diff --git a/cpukit/libcsupport/src/mallocfreespace.c b/cpukit/libcsupport/src/mallocfreespace.c
new file mode 100644
index 0000000000..448dca46e4
--- /dev/null
+++ b/cpukit/libcsupport/src/mallocfreespace.c
@@ -0,0 +1,44 @@
+/*
+ * RTEMS Malloc Get Status Information
+ *
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+#include <rtems/libcsupport.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+extern rtems_id RTEMS_Malloc_Heap;
+
+/*
+ * Find amount of free heap remaining
+ */
+
+size_t malloc_free_space( void )
+{
+ region_information_block heap_info;
+
+ if ( !rtems_region_get_free_information( RTEMS_Malloc_Heap, &heap_info ) ) {
+ return (size_t) heap_info.Free.largest;
+ }
+ return (size_t) -1;
+}
diff --git a/cpukit/libcsupport/src/mkdir.c b/cpukit/libcsupport/src/mkdir.c
new file mode 100644
index 0000000000..2fae8a733a
--- /dev/null
+++ b/cpukit/libcsupport/src/mkdir.c
@@ -0,0 +1,30 @@
+/*
+ * mkdir() - POSIX 1003.1b 5.4.1 - Make a Directory
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+
+int mkdir(
+ const char *pathname,
+ mode_t mode
+)
+{
+ return mknod( pathname, mode | S_IFDIR, 0LL);
+}
diff --git a/cpukit/libcsupport/src/mkfifo.c b/cpukit/libcsupport/src/mkfifo.c
new file mode 100644
index 0000000000..efe6207bf8
--- /dev/null
+++ b/cpukit/libcsupport/src/mkfifo.c
@@ -0,0 +1,28 @@
+/*
+ * mkfifo() - POSIX 1003.1b 5.4.1 - Make a FIFO Special File
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+int mkfifo(
+ const char *path,
+ mode_t mode
+)
+{
+ return mknod( path, mode | S_IFIFO, 0LL );
+}
diff --git a/cpukit/libcsupport/src/mknod.c b/cpukit/libcsupport/src/mknod.c
new file mode 100644
index 0000000000..c786c6d756
--- /dev/null
+++ b/cpukit/libcsupport/src/mknod.c
@@ -0,0 +1,73 @@
+/*
+ * mknod()
+ *
+ * This routine is not defined in the POSIX 1003.1b standard but is
+ * commonly supported on most UNIX and POSIX systems. It is the
+ * foundation for creating file system objects.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int mknod(
+ const char *pathname,
+ mode_t mode,
+ dev_t dev
+)
+{
+ rtems_filesystem_location_info_t temp_loc;
+ int i;
+ const char *name_start;
+ int result;
+
+ if ( !(mode & (S_IFREG|S_IFCHR|S_IFBLK|S_IFIFO) ) )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( S_ISFIFO(mode) )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ rtems_filesystem_get_start_loc( pathname, &i, &temp_loc );
+
+ if ( !temp_loc.ops->evalformake_h ) {
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ result = (*temp_loc.ops->evalformake_h)(
+ &pathname[i],
+ &temp_loc,
+ &name_start
+ );
+ if ( result != 0 )
+ return -1;
+
+ if ( !temp_loc.ops->mknod_h ) {
+ rtems_filesystem_freenode( &temp_loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ result = (*temp_loc.ops->mknod_h)( name_start, mode, dev, &temp_loc );
+
+ rtems_filesystem_freenode( &temp_loc );
+
+ return result;
+}
diff --git a/cpukit/libcsupport/src/mount.c b/cpukit/libcsupport/src/mount.c
new file mode 100644
index 0000000000..bec64eb701
--- /dev/null
+++ b/cpukit/libcsupport/src/mount.c
@@ -0,0 +1,291 @@
+/*
+ * mount()
+ *
+ * XXX
+ *
+ * XXX make sure no required ops are NULL
+ * XXX make sure no optional ops you are using are NULL
+ * XXX unmount should be required.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <rtems/chain.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <rtems/libio_.h>
+
+Chain_Control rtems_filesystem_mount_table_control;
+
+/*
+ * Prototypes that probably should be somewhere else.
+ */
+
+int init_fs_mount_table( void );
+static int Is_node_fs_root(
+ rtems_filesystem_location_info_t *loc
+);
+
+
+/*
+ * XXX
+ */
+
+#define FOUND 0
+#define NOT_FOUND -1
+
+/*
+ * mount
+ *
+ * This routine will attempt to mount a new file system at the specified
+ * mount point. A series of tests will be run to determine if any of the
+ * following reasons exist to prevent the mount operation:
+ *
+ * 1) The file system type or options are not valid
+ * 2) No new file system root node is specified
+ * 3) The selected file system has already been mounted
+ * 4) The mount point exists with the proper permissions to allow mounting
+ * 5) The selected mount point already has a file system mounted to it
+ *
+ */
+
+int mount(
+ rtems_filesystem_mount_table_entry_t **mt_entry,
+ rtems_filesystem_operations_table *fs_ops,
+ rtems_filesystem_options_t options,
+ char *device,
+ char *mount_point
+)
+{
+ rtems_filesystem_location_info_t loc;
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry = NULL;
+ rtems_filesystem_location_info_t *loc_to_free = NULL;
+ size_t size;
+
+/* XXX add code to check for required operations */
+
+ /*
+ * Is there a file system operations table?
+ */
+
+ if ( fs_ops == NULL ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * Are the file system options valid?
+ */
+
+ if ( options != RTEMS_FILESYSTEM_READ_ONLY &&
+ options != RTEMS_FILESYSTEM_READ_WRITE ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Do they support being mounted at all ? */
+ if ( !fs_ops->fsmount_me_h ) {
+ errno = ENOTSUP;
+ goto cleanup_and_bail;
+ }
+
+
+ /*
+ * Allocate a mount table entry
+ */
+
+ size = sizeof(rtems_filesystem_mount_table_entry_t);
+ if ( device )
+ size += strlen( device ) + 1;
+ temp_mt_entry = malloc( size );
+
+ if ( !temp_mt_entry ) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ temp_mt_entry->mt_fs_root.mt_entry = temp_mt_entry;
+ temp_mt_entry->options = options;
+ if ( device ) {
+ temp_mt_entry->dev =
+ (char *)temp_mt_entry + sizeof( rtems_filesystem_mount_table_entry_t );
+ strcpy( temp_mt_entry->dev, device );
+ } else
+ temp_mt_entry->dev = 0;
+
+ /*
+ * The mount_point should be a directory with read/write/execute
+ * permissions in the existing tree.
+ */
+
+ if ( mount_point ) {
+
+ if ( rtems_filesystem_evaluate_path(
+ mount_point, RTEMS_LIBIO_PERMS_RWX, &loc, TRUE ) == -1 )
+ goto cleanup_and_bail;
+
+ loc_to_free = &loc;
+
+ /*
+ * Test for node_type_h
+ */
+
+ if (!loc.ops->node_type_h) {
+ errno = ENOTSUP;
+ goto cleanup_and_bail;
+ }
+
+ /*
+ * Test to see if it is a directory
+ */
+
+ if ( loc.ops->node_type_h( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ) {
+ errno = ENOTDIR;
+ goto cleanup_and_bail;
+ }
+
+ /*
+ * You can only mount one file system onto a single mount point.
+ */
+
+ if ( Is_node_fs_root( &loc ) ){
+ errno = EBUSY;
+ goto cleanup_and_bail;
+ }
+
+ /*
+ * This must be a good mount point, so move the location information
+ * into the allocated mount entry. Note: the information that
+ * may have been allocated in loc should not be sent to freenode
+ * until the system is unmounted. It may be needed to correctly
+ * traverse the tree.
+ */
+
+ temp_mt_entry->mt_point_node.node_access = loc.node_access;
+ temp_mt_entry->mt_point_node.handlers = loc.handlers;
+ temp_mt_entry->mt_point_node.ops = loc.ops;
+ temp_mt_entry->mt_point_node.mt_entry = loc.mt_entry;
+
+ /*
+ * This link to the parent is only done when we are dealing with system
+ * below the base file system
+ */
+
+ if ( !loc.ops->mount_h ){
+ errno = ENOTSUP;
+ goto cleanup_and_bail;
+ }
+
+ if ( loc.ops->mount_h( temp_mt_entry ) ) {
+ goto cleanup_and_bail;
+ }
+ } else {
+
+ /*
+ * This is a mount of the base file system --> The
+ * mt_point_node.node_access will be set to null to indicate that this
+ * is the root of the entire file system.
+ */
+
+ temp_mt_entry->mt_fs_root.node_access = NULL;
+ temp_mt_entry->mt_fs_root.handlers = NULL;
+ temp_mt_entry->mt_fs_root.ops = NULL;
+
+ temp_mt_entry->mt_point_node.node_access = NULL;
+ temp_mt_entry->mt_point_node.handlers = NULL;
+ temp_mt_entry->mt_point_node.ops = NULL;
+ temp_mt_entry->mt_point_node.mt_entry = NULL;
+ }
+
+ if ( fs_ops->fsmount_me_h( temp_mt_entry ) ) {
+ /* try to undo the mount operation */
+ if ( loc.ops->unmount_h ) {
+ loc.ops->unmount_h( temp_mt_entry );
+ }
+ goto cleanup_and_bail;
+ }
+
+ /*
+ * Add the mount table entry to the mount table chain
+ */
+
+ Chain_Append( &rtems_filesystem_mount_table_control, &temp_mt_entry->Node );
+
+ *mt_entry = temp_mt_entry;
+
+ return 0;
+
+cleanup_and_bail:
+
+ free( temp_mt_entry );
+
+ if ( loc_to_free )
+ rtems_filesystem_freenode( loc_to_free );
+
+ return -1;
+}
+
+
+
+/*
+ * init_fs_mount_table
+ *
+ * This routine will initialize the chain control element that manages the
+ * mount table chain.
+ */
+
+int init_fs_mount_table()
+{
+ Chain_Initialize_empty ( &rtems_filesystem_mount_table_control );
+ return 0;
+}
+
+/*
+ * Is_node_fs_root
+ *
+ * This routine will run through the entries that currently exist in the
+ * mount table chain. For each entry in the mount table chain it will
+ * compare the mount tables root node to the node describing the selected
+ * mount point. If any match is found true is returned else false is
+ * returned.
+ *
+ */
+
+static int Is_node_fs_root(
+ rtems_filesystem_location_info_t *loc
+)
+{
+ Chain_Node *the_node;
+ rtems_filesystem_mount_table_entry_t *the_mount_entry;
+
+ /*
+ * For each mount table entry
+ */
+
+ for ( the_node = rtems_filesystem_mount_table_control.first;
+ !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
+ the_node = the_node->next ) {
+ the_mount_entry = (rtems_filesystem_mount_table_entry_t *) the_node;
+ if ( the_mount_entry->mt_fs_root.node_access == loc->node_access )
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/cpukit/libcsupport/src/newlibc.c b/cpukit/libcsupport/src/newlibc.c
new file mode 100644
index 0000000000..ef151c6e81
--- /dev/null
+++ b/cpukit/libcsupport/src/newlibc.c
@@ -0,0 +1,386 @@
+/*
+ * Implementation of hooks for the CYGNUS newlib libc
+ * These hooks set things up so that:
+ * + '_REENT' is switched at task switch time.
+ *
+ * COPYRIGHT (c) 1994 by Division Incorporated
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+
+#if defined(RTEMS_NEWLIB)
+#include <rtems/libcsupport.h>
+
+/* Since we compile with strict ANSI we need to undef it to get
+ * prototypes for extensions
+ */
+#undef __STRICT_ANSI__
+
+#include <stdlib.h> /* for free() */
+#include <string.h> /* for memset() */
+
+#include <sys/reent.h> /* for extern of _REENT (aka _impure_ptr) */
+#include <errno.h>
+
+/*
+ * NOTE:
+ * There is some problem with doing this on the hpux version
+ * of the UNIX simulator (symptom is printf core dumps), so
+ * we just don't for now.
+ * Not sure if this is a problem with hpux, newlib, or something else.
+ */
+
+#if defined(RTEMS_UNIX) && !defined(hpux)
+#define NEED_SETVBUF
+#endif
+
+#include <stdio.h>
+
+int _fwalk(struct _reent *ptr, int (*function) (FILE *) );
+
+int libc_reentrant; /* do we think we are reentrant? */
+struct _reent libc_global_reent;
+
+/*
+ * CYGNUS newlib routine that does atexit() processing and flushes
+ * stdio streams
+ * undocumented
+ */
+
+extern void _wrapup_reent(struct _reent *);
+extern void _reclaim_reent(struct _reent *);
+
+void libc_wrapup(void)
+{
+ /*
+ * In case RTEMS is already down, don't do this. It could be
+ * dangerous.
+ */
+
+ if (!_System_state_Is_up(_System_state_Get()))
+ return;
+
+ /*
+ * This was already done if the user called exit() directly .
+ _wrapup_reent(0);
+ */
+
+ if (_REENT != &libc_global_reent) {
+ _wrapup_reent(&libc_global_reent);
+#if 0
+ /* Don't reclaim this one, just in case we do printfs
+ * on the way out to ROM.
+ */
+ _reclaim_reent(&libc_global_reent);
+#endif
+ _REENT = &libc_global_reent;
+ }
+
+ /*
+ * Try to drain output buffers.
+ *
+ * Should this be changed to do *all* file streams?
+ * _fwalk (_REENT, fclose);
+ */
+
+ fclose (stdin);
+ fclose (stdout);
+ fclose (stderr);
+}
+
+/*
+ * reent struct allocation moved here from libc_start_hook() to avoid
+ * mutual exclusion problems when memory is allocated from the start hook.
+ *
+ * Memory is also now allocated from the workspace rather than the heap.
+ * -- ptorre 9/30/03
+ */
+rtems_boolean libc_create_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *creating_task
+)
+{
+ struct _reent *ptr;
+
+ /* NOTE: The RTEMS malloc is reentrant without a reent ptr since
+ * it is based on the Classic API Region Manager.
+ */
+
+#define REENT_MALLOCED 0
+#if REENT_MALLOCED
+ ptr = (struct _reent *) calloc(1, sizeof(struct _reent));
+#else
+ /* It is OK to allocate from the workspace because these
+ * hooks run with thread dispatching disabled.
+ */
+ ptr = (struct _reent *) _Workspace_Allocate(sizeof(struct _reent));
+#endif
+
+ if (ptr)
+ {
+
+#ifdef __GNUC__
+ /* GCC extension: structure constants */
+ _REENT_INIT_PTR((ptr));
+#else
+ /*
+ * WARNING: THIS IS VERY DEPENDENT ON NEWLIB!!!
+ * Last visual check was against newlib 1.8.2 but last known
+ * use was against 1.7.0. This is basically an exansion of
+ * REENT_INIT() in <sys/reent.h>.
+ */
+ memset(ptr, 0, sizeof(*ptr));
+ ptr->_stdin = &ptr->__sf[0];
+ ptr->_stdout = &ptr->__sf[1];
+ ptr->_stderr = &ptr->__sf[2];
+ ptr->_current_locale = "C";
+ ptr->_new._reent._rand_next = 1;
+#endif
+
+ creating_task->libc_reent = ptr;
+ return TRUE;
+ }
+ else
+ return FALSE;
+
+}
+
+/*
+ * Called for all user TASKS (system tasks are MPCI Receive Server and IDLE)
+ */
+
+rtems_extension libc_start_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *starting_task
+)
+{
+}
+
+/*
+ * Called for all user TASKS (system tasks are MPCI Receive Server and IDLE)
+ */
+
+#ifdef NEED_SETVBUF
+rtems_extension libc_begin_hook(rtems_tcb *current_task)
+{
+ setvbuf( stdout, NULL, _IOLBF, BUFSIZ );
+}
+#endif
+
+/*
+ * Function: libc_delete_hook
+ * Created: 94/12/10
+ *
+ * Description:
+ * Called when a task is deleted.
+ * Must restore the new lib reentrancy state for the new current
+ * task.
+ *
+ * Parameters:
+ *
+ *
+ * Returns:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ *
+ *
+ * Deficiencies/ToDo:
+ *
+ *
+ */
+
+int newlib_free_buffers(
+ FILE *fp
+)
+{
+ switch ( fileno(fp) ) {
+ case 0:
+ case 1:
+ case 2:
+ if (fp->_flags & __SMBF) {
+ free( fp->_bf._base );
+ fp->_flags &= ~__SMBF;
+ fp->_bf._base = fp->_p = (unsigned char *) NULL;
+ }
+ break;
+ default:
+ fclose(fp);
+ }
+ return 0;
+}
+
+rtems_extension libc_delete_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *deleted_task
+)
+{
+ struct _reent *ptr;
+
+ /*
+ * The reentrancy structure was allocated by newlib using malloc()
+ */
+
+ if (current_task == deleted_task) {
+ ptr = _REENT;
+ } else {
+ ptr = deleted_task->libc_reent;
+ }
+
+ if (ptr && ptr != &libc_global_reent) {
+/*
+ _wrapup_reent(ptr);
+ _reclaim_reent(ptr);
+*/
+ /*
+ * Just in case there are some buffers lying around.
+ */
+ _fwalk(ptr, newlib_free_buffers);
+#if REENT_MALLOCED
+ free(ptr);
+#else
+ _Workspace_Free(ptr);
+#endif
+ }
+
+ deleted_task->libc_reent = NULL;
+
+ /*
+ * Require the switch back to another task to install its own
+ */
+
+ if ( current_task == deleted_task ) {
+ _REENT = 0;
+ }
+}
+
+/*
+ * Function: libc_init
+ * Created: 94/12/10
+ *
+ * Description:
+ * Init libc for CYGNUS newlib
+ * Set up _REENT to use our global libc_global_reent.
+ * (newlib provides a global of its own, but we prefer our
+ * own name for it)
+ *
+ * If reentrancy is desired (which it should be), then
+ * we install the task extension hooks to maintain the
+ * newlib reentrancy global variable _REENT on task
+ * create, delete, switch, exit, etc.
+ *
+ * Parameters:
+ * reentrant non-zero if reentrant library desired.
+ *
+ * Returns:
+ *
+ * Side Effects:
+ * installs libc extensions if reentrant.
+ *
+ * Notes:
+ *
+ *
+ * Deficiencies/ToDo:
+ *
+ */
+
+void
+libc_init(int reentrant)
+{
+ rtems_extensions_table libc_extension;
+ rtems_status_code rc;
+ rtems_id extension_id;
+
+ libc_global_reent = (struct _reent) _REENT_INIT((libc_global_reent));
+ _REENT = &libc_global_reent;
+
+ if (reentrant) {
+ memset(&libc_extension, 0, sizeof(libc_extension));
+
+ libc_extension.thread_create = libc_create_hook;
+ libc_extension.thread_start = libc_start_hook;
+#ifdef NEED_SETVBUF
+ libc_extension.thread_begin = libc_begin_hook;
+#endif
+ libc_extension.thread_delete = libc_delete_hook;
+
+ _Thread_Set_libc_reent (&_REENT);
+
+ rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'),
+ &libc_extension, &extension_id);
+ if (rc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred( rc );
+
+ libc_reentrant = reentrant;
+ }
+}
+
+/*
+ * Function: _exit
+ * Created: 94/12/10
+ *
+ * Description:
+ * Called from exit() after it does atexit() processing and stdio fflush's
+ *
+ * called from bottom of exit() to really delete the task.
+ * If we are using reentrant libc, then let the delete extension
+ * do all the work, otherwise if a shutdown is in progress,
+ * then just do it.
+ *
+ * Parameters:
+ * exit status
+ *
+ * Returns:
+ * does not return
+ *
+ * Side Effects:
+ *
+ * Notes:
+ *
+ *
+ * Deficiencies/ToDo:
+ *
+ *
+ */
+
+#include <unistd.h>
+
+#if !defined(RTEMS_UNIX)
+void _exit(int status)
+{
+ /*
+ * We need to do the exit processing on the global reentrancy structure.
+ * This has already been done on the per task reentrancy structure
+ * associated with this task.
+ */
+
+ libc_wrapup();
+ rtems_shutdown_executive(status);
+ for (;;) ; /* to avoid warnings */
+}
+
+#else
+
+void exit(int status)
+{
+ libc_wrapup();
+ rtems_shutdown_executive(status);
+ for (;;) ; /* to avoid warnings */
+}
+#endif
+
+#endif
diff --git a/cpukit/libcsupport/src/no_libc.c b/cpukit/libcsupport/src/no_libc.c
new file mode 100644
index 0000000000..afcc30b49c
--- /dev/null
+++ b/cpukit/libcsupport/src/no_libc.c
@@ -0,0 +1,59 @@
+/*
+ * This file contains stubs for the reentrancy hooks when
+ * an unknown C library is used.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if !defined(RTEMS_NEWLIB) && !defined(RTEMS_UNIX)
+
+#include <rtems/libcsupport.h>
+
+#include <stdlib.h> /* for free() */
+
+void libc_init(
+ int reentrant
+)
+{
+}
+
+void libc_suspend_main(void)
+{
+}
+
+
+void libc_global_exit(
+ uint32_t code
+)
+{
+}
+
+void _exit(
+ int status
+)
+{
+}
+
+#else
+
+/* remove ANSI errors.
+ * A program must contain at least one external-declaration
+ * (X3.159-1989 p.82,L3).
+ */
+void no_libc_dummy_function( void )
+{
+}
+
+#endif
diff --git a/cpukit/libcsupport/src/no_posix.c b/cpukit/libcsupport/src/no_posix.c
new file mode 100644
index 0000000000..1b3bf35c21
--- /dev/null
+++ b/cpukit/libcsupport/src/no_posix.c
@@ -0,0 +1,87 @@
+/*
+ * Marginal implementations of some POSIX API routines
+ * to be used when POSIX is disabled.
+ *
+ * + kill
+ * + _kill_r
+ * + __kill
+ * + sleep
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <unistd.h>
+
+/*
+ * These are directly supported (and completely correct) in the posix api.
+ */
+
+#if !defined(RTEMS_POSIX_API)
+int kill( pid_t pid, int sig )
+{
+ return 0;
+}
+
+#if defined(RTEMS_NEWLIB)
+#include <reent.h>
+
+int _kill_r( struct _reent *ptr, pid_t pid, int sig )
+{
+ return 0;
+}
+#endif
+#endif
+
+int __kill( pid_t pid, int sig )
+{
+ return 0;
+}
+
+
+/*
+ * 3.4.3 Delay Process Execution, P1003.1b-1993, p. 81
+ *
+ * $Id$
+ */
+
+#include <time.h>
+#include <unistd.h>
+
+#include <rtems.h>
+
+#if !defined(RTEMS_POSIX_API)
+unsigned int sleep(
+ unsigned int seconds
+)
+{
+ rtems_status_code status;
+ rtems_interval ticks_per_second;
+ rtems_interval ticks;
+
+ status = rtems_clock_get(
+ RTEMS_CLOCK_GET_TICKS_PER_SECOND,
+ &ticks_per_second
+ );
+
+ ticks = seconds * ticks_per_second;
+
+ status = rtems_task_wake_after( ticks );
+
+ /*
+ * Returns the "unslept" amount of time. In RTEMS signals are not
+ * interruptable, so tasks really sleep all of the requested time.
+ */
+
+ return 0;
+}
+#endif
diff --git a/cpukit/libcsupport/src/open.c b/cpukit/libcsupport/src/open.c
new file mode 100644
index 0000000000..a67680a031
--- /dev/null
+++ b/cpukit/libcsupport/src/open.c
@@ -0,0 +1,222 @@
+/*
+ * open() - POSIX 1003.1 5.3.1 - Open a File
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+#include <fcntl.h>
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+#include <unistd.h>
+
+/*
+ * Returns file descriptor on success or -1 and errno set to one of the
+ * following:
+ *
+ * EACCESS - Seach permission is denied on a component of the path prefix,
+ * or the file exists and the permissions specified by the
+ * flags are denied, or the file does not exist and write
+ * permission is denied for the parent directory of the file
+ * to be created, or O_TRUNC is specified and write permission
+ * is denied.
+ * EEXIST - O_CREAT and O_EXCL are set and the named file exists.
+ * EINTR - The open( operation was interrupted by a signal.
+ * EINVAL - This implementation does not support synchronized IO for this
+ * file.
+ * EISDIR - The named file is a directory and the flags argument
+ * specified write or read/write access.
+ * EMFILE - Too many file descriptors are in used by this process.
+ * ENAMETOOLONG -
+ * The length of the path exceeds PATH_MAX or a pathname
+ * component is longer than NAME_MAX while POSIX_NO_TRUNC
+ * is in effect.
+ * ENFILE - Too many files are open in the system.
+ * ENOENT - O_CREAT is not set and and the anmed file does not exist,
+ * or O_CREAT is set and either the path prefix does not exist
+ * or the path argument points to an empty string.
+ * ENOSPC - The directory or file system that would contain the new file
+ * cannot be extended.
+ * ENOTDIR - A component of the path prefix is not a directory.
+ * ENXIO - O_NONBLOCK is set, the named file is a FIFO, O_WRONLY is
+ * set, and no process has the file open for reading.
+ * EROFS - The named file resides on a read-only file system and either
+ * O_WRONLY, O_RDWR, O_CREAT (if the file does not exist), or
+ * O_TRUNC is set in the flags argument.
+ */
+
+int open(
+ const char *pathname,
+ int flags,
+ ...
+)
+{
+ va_list ap;
+ int mode;
+ int rc;
+ rtems_libio_t *iop = 0;
+ int status;
+ rtems_filesystem_location_info_t loc;
+ rtems_filesystem_location_info_t *loc_to_free = NULL;
+ int eval_flags;
+
+
+ /*
+ * Set the Evaluation flags
+ */
+
+ eval_flags = 0;
+ status = flags + 1;
+ if ( ( status & _FREAD ) == _FREAD )
+ eval_flags |= RTEMS_LIBIO_PERMS_READ;
+ if ( ( status & _FWRITE ) == _FWRITE )
+ eval_flags |= RTEMS_LIBIO_PERMS_WRITE;
+
+
+ va_start(ap, flags);
+
+ mode = va_arg( ap, int );
+
+ /*
+ * NOTE: This comment is OBSOLETE. The proper way to do this now
+ * would be to support a magic mounted file system.
+ *
+ * Additional external I/O handlers would be supported by adding
+ * code to pick apart the pathname appropriately. The networking
+ * code does not require changes here since network file
+ * descriptors are obtained using socket(), not open().
+ */
+
+ /* allocate a file control block */
+ iop = rtems_libio_allocate();
+ if ( iop == 0 ) {
+ rc = ENFILE;
+ goto done;
+ }
+
+ /*
+ * See if the file exists.
+ */
+
+ status = rtems_filesystem_evaluate_path(
+ pathname, eval_flags, &loc, TRUE );
+
+ if ( status == -1 ) {
+ if ( errno != ENOENT ) {
+ rc = errno;
+ goto done;
+ }
+
+ /* If the file does not exist and we are not trying to create it--> error */
+ if ( !(flags & O_CREAT) ) {
+ rc = ENOENT;
+ goto done;
+ }
+
+ /* Create the node for the new regular file */
+ rc = mknod( pathname, S_IFREG | mode, 0LL );
+ if ( rc ) {
+ rc = errno;
+ goto done;
+ }
+
+ /* Sanity check to see if the file name exists after the mknod() */
+ status = rtems_filesystem_evaluate_path( pathname, 0x0, &loc, TRUE );
+ if ( status != 0 ) { /* The file did not exist */
+ rc = EACCES;
+ goto done;
+ }
+
+ } else if ((flags & (O_EXCL|O_CREAT)) == (O_EXCL|O_CREAT)) {
+ /* We were trying to create a file that already exists */
+ rc = EEXIST;
+ loc_to_free = &loc;
+ goto done;
+ }
+
+ loc_to_free = &loc;
+
+ /*
+ * Fill in the file control block based on the loc structure
+ * returned by successful path evaluation.
+ */
+
+ iop->handlers = loc.handlers;
+ iop->file_info = loc.node_access;
+ iop->flags |= rtems_libio_fcntl_flags( flags );
+ iop->pathinfo = loc;
+
+ if ( !iop->handlers->open_h ) {
+ rc = ENOTSUP;
+ goto done;
+ }
+
+ rc = (*iop->handlers->open_h)( iop, pathname, flags, mode );
+ if ( rc )
+ goto done;
+
+ /*
+ * Optionally truncate the file.
+ */
+
+ if ( (flags & O_TRUNC) == O_TRUNC ) {
+ rc = ftruncate( iop - rtems_libio_iops, 0 );
+ if ( rc ) {
+ if(errno) rc = errno;
+ close( iop - rtems_libio_iops );
+ /* those are released by close(): */
+ iop = 0;
+ loc_to_free = NULL;
+ }
+ }
+
+ /*
+ * Single exit and clean up path.
+ */
+
+done:
+ va_end(ap);
+
+ if ( rc ) {
+ if ( iop )
+ rtems_libio_free( iop );
+ if ( loc_to_free )
+ rtems_filesystem_freenode( loc_to_free );
+ rtems_set_errno_and_return_minus_one( rc );
+ }
+
+ return iop - rtems_libio_iops;
+}
+
+/*
+ * _open_r
+ *
+ * This is the Newlib dependent reentrant version of open().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _open_r(
+ struct _reent *ptr,
+ const char *buf,
+ int flags,
+ int mode
+)
+{
+ return open( buf, flags, mode );
+}
+#endif
diff --git a/cpukit/libcsupport/src/opendir.c b/cpukit/libcsupport/src/opendir.c
new file mode 100644
index 0000000000..98129bc294
--- /dev/null
+++ b/cpukit/libcsupport/src/opendir.c
@@ -0,0 +1,89 @@
+/*
+ * opendir() - POSIX 1003.1b - XXX
+ *
+ * This was copied from Newlib 1.8.0.
+ *
+ *
+ * Copyright (c) 1983 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)opendir.c 5.11 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * open a directory.
+ */
+DIR *
+opendir(name)
+ const char *name;
+{
+ register DIR *dirp;
+ register int fd;
+
+ if ((fd = open(name, 0)) == -1)
+ return NULL;
+ if (fcntl(fd, F_SETFD, 1) == -1 ||
+ (dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
+ close (fd);
+ return NULL;
+ }
+ /*
+ * If CLSIZE is an exact multiple of DIRBLKSIZ, use a CLSIZE
+ * buffer that it cluster boundary aligned.
+ * Hopefully this can be a big win someday by allowing page trades
+ * to user space to be done by getdirentries()
+ */
+ dirp->dd_buf = malloc (512);
+ dirp->dd_len = 512;
+
+ if (dirp->dd_buf == NULL) {
+ close (fd);
+ return NULL;
+ }
+ dirp->dd_fd = fd;
+ dirp->dd_loc = 0;
+ dirp->dd_seek = 0;
+ /*
+ * Set up seek point for rewinddir.
+ */
+ return dirp;
+}
diff --git a/cpukit/libcsupport/src/pathconf.c b/cpukit/libcsupport/src/pathconf.c
new file mode 100644
index 0000000000..d16f899e95
--- /dev/null
+++ b/cpukit/libcsupport/src/pathconf.c
@@ -0,0 +1,41 @@
+/*
+ * pathconf() - POSIX 1003.1b - 5.7.1 - Configurable Pathname Varables
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+long pathconf(
+ const char *path,
+ int name
+)
+{
+ int status;
+ int fd;
+
+ fd = open( path, O_RDONLY );
+ if ( fd == -1 )
+ return -1;
+
+ status = fpathconf( fd, name );
+
+ (void) close( fd );
+
+ return status;
+}
diff --git a/cpukit/libcsupport/src/pipe.c b/cpukit/libcsupport/src/pipe.c
new file mode 100644
index 0000000000..57a682e55b
--- /dev/null
+++ b/cpukit/libcsupport/src/pipe.c
@@ -0,0 +1,26 @@
+/*
+ * pipe() - POSIX 1003.1b 6.1.1 Create an Inter-Process Channel
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+int pipe(
+ int filsdes[2]
+)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/libcsupport/src/printk.c b/cpukit/libcsupport/src/printk.c
new file mode 100644
index 0000000000..4ce64153b9
--- /dev/null
+++ b/cpukit/libcsupport/src/printk.c
@@ -0,0 +1,155 @@
+/*-------------------------------------------------------------------------+
+| printk.c v1.1 - PC386 BSP - 1997/08/07
++--------------------------------------------------------------------------+
+| (C) Copyright 1997 -
+| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
+|
+| http://pandora.ist.utl.pt
+|
+| Instituto Superior Tecnico * Lisboa * PORTUGAL
++--------------------------------------------------------------------------+
+| Disclaimer:
+|
+| This file is provided "AS IS" without warranty of any kind, either
+| expressed or implied.
++--------------------------------------------------------------------------+
+| This code is based on code by: Jose Rufino - IST
+|
+| $Id$
++--------------------------------------------------------------------------*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <rtems/bspIo.h>
+
+/*-------------------------------------------------------------------------+
+| Function: printNum
+| Description: print number in a given base.
+| Global Variables: None.
+| Arguments: num - number to print, base - base used to print the number.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static void
+printNum(long unsigned int num, int base, int sign, int maxwidth, int lead)
+{
+ long unsigned int n;
+ int count;
+ char toPrint[20];
+
+ if ( (sign == 1) && ((long)num < 0) ) {
+ BSP_output_char('-');
+ num = -num;
+ if (maxwidth) maxwidth--;
+ }
+
+ count = 0;
+ while ((n = num / base) > 0) {
+ toPrint[count++] = (num - (n*base));
+ num = n ;
+ }
+ toPrint[count++] = num;
+
+ for (n=maxwidth ; n > count; n-- )
+ BSP_output_char(lead);
+
+ for (n = 0; n < count; n++){
+ BSP_output_char("0123456789ABCDEF"[(int)(toPrint[count-(n+1)])]);
+ }
+} /* printNum */
+
+
+/*-------------------------------------------------------------------------+
+| Function: printk
+| Description: a simplified version of printf intended for use when the
+ console is not yet initialized or in ISR's.
+| Global Variables: None.
+| Arguments: as in printf: fmt - format string, ... - unnamed arguments.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+void
+vprintk(char *fmt, va_list ap)
+{
+ char c, *str;
+ int lflag, base, sign, width, lead;
+ /* unsigned int level; */
+
+ /* _CPU_ISR_Disable(level); */
+
+ for (; *fmt != '\0'; fmt++)
+ {
+ lflag = 0;
+ base = 0;
+ sign = 0;
+ width = 0;
+ lead = ' ';
+ if (*fmt == '%')
+ {
+ fmt++;
+ if (*fmt == '0' ) {
+ lead = '0';
+ fmt++;
+ }
+ while (*fmt >= '0' && *fmt <= '9' ) {
+ width *= 10;
+ width += (*fmt - '0');
+ fmt++;
+ }
+
+ if ((c = *fmt) == 'l')
+ {
+ lflag = 1;
+ c = *++fmt;
+ }
+ switch (c)
+ {
+ case 'o': case 'O': base = 8; sign = 0; break;
+ case 'i': case 'I':
+ case 'd': case 'D': base = 10; sign = 1; break;
+ case 'u': case 'U': base = 10; sign = 0; break;
+ case 'x': case 'X': base = 16; sign = 0; break;
+ case 's':
+ for (str = va_arg(ap, char *); *str; str++)
+ BSP_output_char(*str);
+ break;
+ case 'c':
+#if 0
+#if defined(_TMS320C3x) || defined(_TMS320C4x)
+ BSP_output_char(va_arg(ap, int));
+#else
+ BSP_output_char(va_arg(ap, char));
+#endif
+#else
+ BSP_output_char(va_arg(ap, int));
+#endif
+ break;
+ default:
+ BSP_output_char(c);
+ break;
+ } /* switch*/
+
+ if (base)
+ printNum(lflag ? va_arg(ap, long int) : (long int)va_arg(ap, int),
+ base, sign, width, lead);
+ }
+ else
+ {
+ BSP_output_char(*fmt);
+ }
+ }
+ /* _CPU_ISR_Enable(level); */
+
+} /* vprintk */
+
+void
+printk(char *fmt, ...)
+{
+ va_list ap; /* points to each unnamed argument in turn */
+
+ va_start(ap, fmt); /* make ap point to 1st unnamed arg */
+ vprintk(fmt, ap);
+ va_end(ap); /* clean up when done */
+} /* printk */
diff --git a/cpukit/libcsupport/src/privateenv.c b/cpukit/libcsupport/src/privateenv.c
new file mode 100644
index 0000000000..e1a5e674e3
--- /dev/null
+++ b/cpukit/libcsupport/src/privateenv.c
@@ -0,0 +1,163 @@
+/*
+ * Instantatiate a private user environment for the calling thread.
+ *
+ * Submitted by: fernando.ruiz@ctv.es (correo@fernando-ruiz.com)
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h> /* free */
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+
+extern Chain_Control rtems_filesystem_mount_table_control;
+
+#define THE_ROOT_FS_LOC \
+ (((rtems_filesystem_mount_table_entry_t*)\
+ rtems_filesystem_mount_table_control.first)->mt_fs_root)
+
+/* cleanup a user environment
+ * NOTE: this must be called with
+ * thread dispatching disabled!
+ */
+static void
+free_user_env(void *venv)
+{
+ rtems_user_env_t *env = (rtems_user_env_t*) venv ;
+
+ if (env != &rtems_global_user_env
+#ifdef HAVE_USERENV_REFCNT
+ && --env->refcnt <= 0
+#endif
+ ) {
+ rtems_filesystem_freenode( &env->current_directory);
+ rtems_filesystem_freenode( &env->root_directory);
+ free(env);
+ }
+}
+
+rtems_status_code rtems_libio_set_private_env(void) {
+ rtems_status_code sc;
+ rtems_id task_id;
+ rtems_filesystem_location_info_t loc;
+
+ sc=rtems_task_ident(RTEMS_SELF,0,&task_id);
+ if (sc != RTEMS_SUCCESSFUL) return sc;
+
+ /* Only for the first time a malloc is necesary */
+ if (rtems_current_user_env==&rtems_global_user_env) {
+ rtems_user_env_t *tmp = malloc(sizeof(rtems_user_env_t));
+ if (!tmp)
+ return RTEMS_NO_MEMORY;
+
+#ifdef HAVE_USERENV_REFCNT
+ tmp->refcnt = 1;
+#endif
+
+ sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,(void(*)(void *))free_user_env);
+ if (sc != RTEMS_SUCCESSFUL) {
+ /* don't use free_user_env because the pathlocs are
+ * not initialized yet
+ */
+ free(tmp);
+ return sc;
+ }
+ rtems_current_user_env = tmp;
+ };
+
+ *rtems_current_user_env = rtems_global_user_env; /* get the global values*/
+ rtems_current_user_env->task_id=task_id; /* mark the local values*/
+
+ /* get a clean root */
+ rtems_filesystem_root = THE_ROOT_FS_LOC;
+
+ /* Clone the pathlocs. In contrast to most other
+ * code we must _not_ free the original locs because
+ * what we are trying to do here is forking off
+ * clones.
+ */
+
+ rtems_filesystem_evaluate_path("/", 0, &loc, 0);
+ rtems_filesystem_root = loc;
+ rtems_filesystem_evaluate_path("/", 0, &loc, 0);
+ rtems_filesystem_current = loc;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Share a same private environment beetween two task:
+ * Task_id (remote) and RTEMS_SELF(current).
+ */
+
+/* NOTE:
+ *
+ * THIS CODE HAS NO PROTECTION IMPLEMENTED
+ *
+ * Tasks who wish to share their environments must
+ *
+ * a) assert that no participants are concurrently
+ * executing
+ * libio_share_private_env() and/or libio_set_private_env()
+ *
+ * b) mutex access to rtems_filesystem_current, rtems_filesytem_root
+ * while changing any of those (chdir(), chroot()).
+ */
+
+#ifndef HAVE_USERENV_REFCNT
+rtems_status_code rtems_libio_share_private_env(rtems_id task_id) {
+ rtems_status_code sc;
+ rtems_user_env_t * shared_user_env;
+ rtems_id current_task_id;
+
+ sc=rtems_task_ident(RTEMS_SELF,0,&current_task_id);
+ if (sc != RTEMS_SUCCESSFUL) return sc;
+
+ if (rtems_current_user_env->task_id==current_task_id) {
+ /* kill the current user env & task_var*/
+ rtems_user_env_t *tmp = rtems_current_user_env;
+ sc = rtems_task_variable_delete(RTEMS_SELF,(void*)&rtems_current_user_env);
+ if (sc != RTEMS_SUCCESSFUL) return sc;
+ free_user_env(tmp);
+ };
+
+ /* AT THIS POINT, rtems_current_user_env is DANGLING */
+
+ sc = rtems_task_variable_get(task_id,(void*)&rtems_current_user_env,
+ (void*)&shared_user_env );
+ if (sc != RTEMS_SUCCESSFUL)
+ goto bailout;
+
+ sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free_user_env);
+ if (sc != RTEMS_SUCCESSFUL)
+ goto bailout;
+
+ /* the current_user_env is the same pointer that remote env */
+ rtems_current_user_env = shared_user_env;
+
+ /* increase the reference count */
+#ifdef HAVE_USERENV_REFCNT
+ rtems_current_user_env->refcnt++;
+#endif
+
+ return RTEMS_SUCCESSFUL;
+
+bailout:
+ /* fallback to the global env */
+ rtems_current_user_env = &rtems_global_user_env;
+ return sc;
+}
+#endif
diff --git a/cpukit/libcsupport/src/read.c b/cpukit/libcsupport/src/read.c
new file mode 100644
index 0000000000..a57426666c
--- /dev/null
+++ b/cpukit/libcsupport/src/read.c
@@ -0,0 +1,71 @@
+/*
+ * read() - POSIX 1003.1b 6.4.1 - Read From a File
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+ssize_t read(
+ int fd,
+ void *buffer,
+ size_t count
+)
+{
+ int rc; /* XXX change to a size_t when prototype is fixed */
+ rtems_libio_t *iop;
+
+ rtems_libio_check_fd( fd );
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_is_open(iop);
+ rtems_libio_check_buffer( buffer );
+ rtems_libio_check_count( count );
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ );
+
+ /*
+ * Now process the read().
+ */
+
+ if ( !iop->handlers->read_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ rc = (*iop->handlers->read_h)( iop, buffer, count );
+
+ if ( rc > 0 )
+ iop->offset += rc;
+
+ return rc;
+}
+
+/*
+ * _read_r
+ *
+ * This is the Newlib dependent reentrant version of read().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+_ssize_t _read_r(
+ struct _reent *ptr,
+ int fd,
+ void *buf,
+ size_t nbytes
+)
+{
+ return read( fd, buf, nbytes );
+}
+#endif
diff --git a/cpukit/libcsupport/src/readdir.c b/cpukit/libcsupport/src/readdir.c
new file mode 100644
index 0000000000..bcff3d951a
--- /dev/null
+++ b/cpukit/libcsupport/src/readdir.c
@@ -0,0 +1,90 @@
+/*
+ * readdir() - POSIX 1003.1b - XXX
+ *
+ * This was copied from Newlib 1.8.0.
+ *
+ *
+ * Copyright (c) 1983 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)readdir.c 5.7 (Berkeley) 6/1/90";
+#endif /* LIBC_SCCS and not lint */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <dirent.h>
+
+int getdents(
+ int dd_fd,
+ char *dd_buf,
+ int dd_len
+);
+
+/*
+ * get next entry in a directory.
+ */
+struct dirent *
+readdir(dirp)
+register DIR *dirp; {
+ register struct dirent *dp;
+
+ if ( !dirp )
+ return NULL;
+
+ for (;;) {
+ if (dirp->dd_loc == 0) {
+ dirp->dd_size = getdents (dirp->dd_fd,
+ dirp->dd_buf,
+ dirp->dd_len);
+
+ if (dirp->dd_size <= 0)
+ return NULL;
+ }
+ if (dirp->dd_loc >= dirp->dd_size) {
+ dirp->dd_loc = 0;
+ continue;
+ }
+ dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
+ if ((int)dp & 03) /* bogus pointer check */
+ return NULL;
+ if (dp->d_reclen <= 0 ||
+ dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc)
+ return NULL;
+ dirp->dd_loc += dp->d_reclen;
+ if (dp->d_ino == 0)
+ continue;
+ return (dp);
+ }
+}
diff --git a/cpukit/libcsupport/src/readdir_r.c b/cpukit/libcsupport/src/readdir_r.c
new file mode 100644
index 0000000000..7d598cd7e3
--- /dev/null
+++ b/cpukit/libcsupport/src/readdir_r.c
@@ -0,0 +1,26 @@
+/*
+ * readdir_r - reentrant version of readdir()
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+
+/*
+ * The RTEMS version of readdir is already thread-safe.
+ */
+
+int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
+{
+ *result = readdir(dirp);
+ if (*result)
+ *entry = **result;
+ return *result ? 0 : errno;
+}
diff --git a/cpukit/libcsupport/src/readlink.c b/cpukit/libcsupport/src/readlink.c
new file mode 100644
index 0000000000..f2ec9781c5
--- /dev/null
+++ b/cpukit/libcsupport/src/readlink.c
@@ -0,0 +1,57 @@
+/*
+ * readlink() - POSIX 1003.1b - X.X.X - XXX
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int readlink(
+ const char *pathname,
+ char *buf,
+ int bufsize
+)
+{
+ rtems_filesystem_location_info_t loc;
+ int result;
+
+ if (!buf)
+ rtems_set_errno_and_return_minus_one( EFAULT );
+
+ result = rtems_filesystem_evaluate_path( pathname, 0, &loc, FALSE );
+ if ( result != 0 )
+ return -1;
+
+ if ( !loc.ops->node_type_h ){
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ if ( (*loc.ops->node_type_h)( &loc ) != RTEMS_FILESYSTEM_SYM_LINK ){
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ if ( !loc.ops->readlink_h ){
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ result = (*loc.ops->readlink_h)( &loc, buf, bufsize );
+
+ rtems_filesystem_freenode( &loc );
+
+ return result;
+}
diff --git a/cpukit/libcsupport/src/rewinddir.c b/cpukit/libcsupport/src/rewinddir.c
new file mode 100644
index 0000000000..f4542d2db6
--- /dev/null
+++ b/cpukit/libcsupport/src/rewinddir.c
@@ -0,0 +1,39 @@
+/*
+ * rewinddir() - POSIX 1003.1b - XXX
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <assert.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+void rewinddir(
+ DIR *dirp
+)
+{
+ off_t status;
+
+ if ( !dirp )
+ return;
+
+ status = lseek( dirp->dd_fd, 0, SEEK_SET );
+
+ if( status == -1 )
+ return;
+
+ dirp->dd_loc = 0;
+}
diff --git a/cpukit/libcsupport/src/rmdir.c b/cpukit/libcsupport/src/rmdir.c
new file mode 100644
index 0000000000..59d43ff278
--- /dev/null
+++ b/cpukit/libcsupport/src/rmdir.c
@@ -0,0 +1,76 @@
+/*
+ * rmdir() - POSIX 1003.1b - 5.2.2 - Remove a Directory
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int rmdir(
+ const char *pathname
+)
+{
+ rtems_filesystem_location_info_t loc;
+ int result;
+
+ /*
+ * Get the node where we wish to go.
+ */
+
+ result = rtems_filesystem_evaluate_path( pathname, 0, &loc, FALSE );
+ if ( result != 0 )
+ return -1;
+
+ result = rtems_filesystem_evaluate_parent(RTEMS_LIBIO_PERMS_WRITE, &loc );
+ if (result != 0){
+ rtems_filesystem_freenode( &loc );
+ return -1;
+ }
+
+ /*
+ * Verify you can remove this node as a directory.
+ */
+
+ if ( !loc.ops->node_type_h ){
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ if ( (*loc.ops->node_type_h)( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ){
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTDIR );
+ }
+
+ /*
+ * Use the filesystems rmnod to remove the node.
+ */
+
+ if ( !loc.handlers->rmnod_h ){
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ result = (*loc.handlers->rmnod_h)( &loc );
+
+ rtems_filesystem_freenode( &loc );
+
+ return result;
+}
diff --git a/cpukit/libcsupport/src/scandir.c b/cpukit/libcsupport/src/scandir.c
new file mode 100644
index 0000000000..a17c070cc9
--- /dev/null
+++ b/cpukit/libcsupport/src/scandir.c
@@ -0,0 +1,168 @@
+/*
+ * scandir() - POSIX 1003.1b - XXX
+ *
+ * This was copied from Newlib 1.8.0.
+ *
+ *
+ * Copyright (c) 1983 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)scandir.c 5.10 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * Scan the directory dirname calling select to make a list of selected
+ * directory entries then sort using qsort and compare routine dcomp.
+ * Returns the number of entries and a pointer to a list of pointers to
+ * struct dirent (through namelist). Returns -1 if there were any errors.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * The DIRSIZ macro gives the minimum record length which will hold
+ * the directory entry. This requires the amount of space in struct dirent
+ * without the d_name field, plus enough space for the name with a terminating
+ * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
+ */
+#undef DIRSIZ
+/*
+#define DIRSIZ(dp) \
+ ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+*/
+
+#define DIRSIZ(dp) \
+ ((sizeof (struct dirent) - (NAME_MAX+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+
+#ifndef __P
+#define __P(args) ()
+#endif
+
+int
+scandir(dirname, namelist, select, dcomp)
+ const char *dirname;
+ struct dirent ***namelist;
+ int (*select) __P((struct dirent *));
+ int (*dcomp) __P((const void *, const void *));
+{
+ register struct dirent *d = NULL;
+ register struct dirent *p = NULL;
+ register struct dirent **names = NULL;
+ register size_t nitems = 0;
+ struct stat stb;
+ long arraysz;
+ DIR *dirp = NULL;
+ int i;
+
+ if ((dirp = opendir(dirname)) == NULL)
+ return(-1);
+ if (fstat(dirp->dd_fd, &stb) < 0)
+ goto cleanup_and_bail;
+
+ /*
+ * estimate the array size by taking the size of the directory file
+ * and dividing it by a multiple of the minimum size entry.
+ */
+ arraysz = (stb.st_size / 24);
+ names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
+ if (names == NULL)
+ goto cleanup_and_bail;
+
+ while ((d = readdir(dirp)) != NULL) {
+ if (select != NULL && !(*select)(d))
+ continue; /* just selected names */
+ /*
+ * Make a minimum size copy of the data
+ */
+ p = (struct dirent *)malloc(DIRSIZ(d));
+ if (p == NULL)
+ goto cleanup_and_bail;
+ p->d_ino = d->d_ino;
+ p->d_reclen = d->d_reclen;
+ p->d_namlen = d->d_namlen;
+ strncpy(p->d_name, d->d_name, p->d_namlen + 1);
+ /*
+ * Check to make sure the array has space left and
+ * realloc the maximum size.
+ */
+ if (++nitems >= arraysz) {
+ if (fstat(dirp->dd_fd, &stb) < 0)
+ goto cleanup_and_bail; /* just might have grown */
+ arraysz = stb.st_size / 12;
+ names = (struct dirent **)realloc((char *)names,
+ arraysz * sizeof(struct dirent *));
+ if (names == NULL)
+ goto cleanup_and_bail;
+ }
+ names[nitems-1] = p;
+ }
+ closedir(dirp);
+ if (nitems && dcomp != NULL){
+ qsort(names, nitems, sizeof(struct dirent *), dcomp);
+ }
+ *namelist = names;
+ return(nitems);
+
+cleanup_and_bail:
+
+ if ( dirp )
+ closedir( dirp );
+
+ if ( names ) {
+ for (i=0; i < nitems; i++ )
+ free( names[i] );
+ free( names );
+ }
+
+ return(-1);
+}
+
+/*
+ * Alphabetic order comparison routine for those who want it.
+ */
+int
+alphasort(d1, d2)
+ const void *d1;
+ const void *d2;
+{
+ return(strcmp((*(struct dirent **)d1)->d_name,
+ (*(struct dirent **)d2)->d_name));
+}
diff --git a/cpukit/libcsupport/src/seekdir.c b/cpukit/libcsupport/src/seekdir.c
new file mode 100644
index 0000000000..be96bb50d3
--- /dev/null
+++ b/cpukit/libcsupport/src/seekdir.c
@@ -0,0 +1,44 @@
+/*
+ * seekdir() - POSIX 1003.1b - XXX
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <assert.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+void seekdir(
+ DIR *dirp,
+ long loc
+)
+{
+ off_t status;
+
+ if ( !dirp )
+ return;
+
+ status = lseek( dirp->dd_fd, loc, SEEK_SET );
+
+ /*
+ * This is not a nice way to error out, but we have no choice here.
+ */
+
+ if ( status == -1 )
+ return;
+
+ dirp->dd_loc = 0;
+}
diff --git a/cpukit/libcsupport/src/setpgid.c b/cpukit/libcsupport/src/setpgid.c
new file mode 100644
index 0000000000..26786cc552
--- /dev/null
+++ b/cpukit/libcsupport/src/setpgid.c
@@ -0,0 +1,29 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 4.3.3 Set Process Group ID for Job Control, P1003.1b-1993, p. 89
+ */
+
+int setpgid(
+ pid_t pid,
+ pid_t pgid
+)
+{
+ rtems_set_errno_and_return_minus_one( ENOSYS );
+}
diff --git a/cpukit/libcsupport/src/setsid.c b/cpukit/libcsupport/src/setsid.c
new file mode 100644
index 0000000000..ae8cdbbd62
--- /dev/null
+++ b/cpukit/libcsupport/src/setsid.c
@@ -0,0 +1,26 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 4.3.2 Create Session and Set Process Group ID, P1003.1b-1993, p. 88
+ */
+
+pid_t setsid( void )
+{
+ rtems_set_errno_and_return_minus_one( EPERM );
+}
diff --git a/cpukit/libcsupport/src/stat.c b/cpukit/libcsupport/src/stat.c
new file mode 100644
index 0000000000..a39deda79e
--- /dev/null
+++ b/cpukit/libcsupport/src/stat.c
@@ -0,0 +1,104 @@
+/*
+ * stat() - POSIX 1003.1b 5.6.2 - Get File Status
+ *
+ * Reused from lstat().
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * lstat() and stat() share the same implementation with a minor
+ * difference on how links are evaluated.
+ */
+
+#ifndef _STAT_NAME
+#define _STAT_NAME stat
+#define _STAT_R_NAME _stat_r
+#define _STAT_FOLLOW_LINKS TRUE
+#endif
+
+
+#include <rtems.h>
+
+#if !defined(RTEMS_UNIX)
+
+#include <rtems/libio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int _STAT_NAME(
+ const char *path,
+ struct stat *buf
+)
+{
+ int status;
+ rtems_filesystem_location_info_t loc;
+
+ /*
+ * Check to see if we were passed a valid pointer.
+ */
+
+ if ( !buf )
+ rtems_set_errno_and_return_minus_one( EFAULT );
+
+ status = rtems_filesystem_evaluate_path( path, 0, &loc, _STAT_FOLLOW_LINKS );
+ if ( status != 0 )
+ return -1;
+
+ if ( !loc.handlers->fstat_h ){
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ /*
+ * Zero out the stat structure so the various support
+ * versions of stat don't have to.
+ */
+
+ memset( buf, 0, sizeof(struct stat) );
+
+ status = (*loc.handlers->fstat_h)( &loc, buf );
+
+ rtems_filesystem_freenode( &loc );
+
+ return status;
+}
+#endif
+
+/*
+ * _stat_r, _lstat_r
+ *
+ * This is the Newlib dependent reentrant version of stat() and lstat().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _STAT_R_NAME(
+ struct _reent *ptr,
+ const char *path,
+ struct stat *buf
+)
+{
+ return _STAT_NAME( path, buf );
+}
+#endif
diff --git a/cpukit/libcsupport/src/strlcat.c b/cpukit/libcsupport/src/strlcat.c
new file mode 100644
index 0000000000..e0424eef7b
--- /dev/null
+++ b/cpukit/libcsupport/src/strlcat.c
@@ -0,0 +1,41 @@
+/*
+ * utils.c - various utility functions used in pppd.
+ *
+ * Copyright (c) 1999 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.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#ifndef HAVE_STRLCAT
+/*
+ * strlcat - like strcat/strncat, doesn't overflow destination buffer,
+ * always leaves destination null-terminated (for len > 0).
+ */
+size_t
+strlcat(dest, src, len)
+ char *dest;
+ const char *src;
+ size_t len;
+{
+ size_t dlen = strlen(dest);
+
+ return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0));
+}
+#endif
diff --git a/cpukit/libcsupport/src/strlcpy.c b/cpukit/libcsupport/src/strlcpy.c
new file mode 100644
index 0000000000..2773e877cb
--- /dev/null
+++ b/cpukit/libcsupport/src/strlcpy.c
@@ -0,0 +1,49 @@
+/*
+ * utils.c - various utility functions used in pppd.
+ *
+ * Copyright (c) 1999 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.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#ifndef HAVE_STRLCPY
+/*
+ * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer,
+ * always leaves destination null-terminated (for len > 0).
+ */
+size_t
+strlcpy(dest, src, len)
+ char *dest;
+ const char *src;
+ size_t len;
+{
+ size_t ret = strlen(src);
+
+ if (len != 0) {
+ if (ret < len)
+ strcpy(dest, src);
+ else {
+ strncpy(dest, src, len - 1);
+ dest[len-1] = 0;
+ }
+ }
+ return ret;
+}
+#endif
diff --git a/cpukit/libcsupport/src/symlink.c b/cpukit/libcsupport/src/symlink.c
new file mode 100644
index 0000000000..59c15787bd
--- /dev/null
+++ b/cpukit/libcsupport/src/symlink.c
@@ -0,0 +1,46 @@
+/*
+ * symlink() - POSIX 1003.1b - X.X.X - XXX
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int symlink(
+ const char *actualpath,
+ const char *sympath
+)
+{
+ rtems_filesystem_location_info_t loc;
+ int i;
+ const char *name_start;
+ int result;
+
+ rtems_filesystem_get_start_loc( sympath, &i, &loc );
+ result = (*loc.ops->evalformake_h)( &sympath[i], &loc, &name_start );
+ if ( result != 0 )
+ return -1;
+
+ if ( !loc.ops->symlink_h ) {
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ result = (*loc.ops->symlink_h)( &loc, actualpath, name_start);
+
+ rtems_filesystem_freenode( &loc );
+
+ return result;
+}
diff --git a/cpukit/libcsupport/src/sync.c b/cpukit/libcsupport/src/sync.c
new file mode 100644
index 0000000000..8d1f52e725
--- /dev/null
+++ b/cpukit/libcsupport/src/sync.c
@@ -0,0 +1,89 @@
+/*
+ * sync() - XXX ??? where is this defined
+ *
+ * This function operates by as follows:
+ * for all threads
+ * for all FILE *
+ * fsync()
+ * fdatasync()
+ *
+ * COPYRIGHT (c) 1989-2003.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Since we compile with strict ANSI we need to undef it to get
+ * prototypes for extensions
+ */
+#undef __STRICT_ANSI__
+int fdatasync(int); /* still not always prototyped */
+
+
+#include <unistd.h>
+#include <stdio.h>
+
+#include <rtems.h>
+/*
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+*/
+
+/* XXX check standards -- Linux version appears to be void */
+void _fwalk(struct _reent *, void *);
+
+
+static void sync_wrapper(FILE *f)
+{
+ int fn = fileno(f);
+
+ fsync(fn);
+ fdatasync(fn);
+}
+
+/* iterate over all FILE *'s for this thread */
+static void sync_per_thread(Thread_Control *t)
+{
+ struct _reent *current_reent;
+
+ /*
+ * The sync_wrapper() function will operate on the current thread's
+ * reent structure so we will temporarily use that.
+ */
+ current_reent = _Thread_Executing->libc_reent;
+ _Thread_Executing->libc_reent = t->libc_reent;
+ _fwalk (t->libc_reent, sync_wrapper);
+ _Thread_Executing->libc_reent = current_reent;
+}
+
+int sync(void)
+{
+ extern struct _reent libc_global_reent;
+
+ /*
+ * Walk the one used initially by RTEMS.
+ */
+ _fwalk(&libc_global_reent, sync_wrapper);
+
+ /*
+ * XXX Do we walk the one used globally by newlib?
+ * XXX Do we need the RTEMS global one?
+ */
+
+ /*
+ * Now walk all the per-thread reentrancy structures.
+ */
+ rtems_iterate_over_all_threads(sync_per_thread);
+
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/tcdrain.c b/cpukit/libcsupport/src/tcdrain.c
new file mode 100644
index 0000000000..c2e9d5e2ee
--- /dev/null
+++ b/cpukit/libcsupport/src/tcdrain.c
@@ -0,0 +1,36 @@
+/*
+ * tcdrain() - POSIX 1003.1b 7.2.2 - Line Control Functions
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+/* #include <sys/ioctl.h> */
+
+#include <rtems/libio.h>
+
+int tcdrain(
+ int fd
+)
+{
+ return ioctl( fd, RTEMS_IO_TCDRAIN, 0 );
+}
+
+#endif
diff --git a/cpukit/libcsupport/src/tcflow.c b/cpukit/libcsupport/src/tcflow.c
new file mode 100644
index 0000000000..a1e054482c
--- /dev/null
+++ b/cpukit/libcsupport/src/tcflow.c
@@ -0,0 +1,34 @@
+/*
+ * tcflow() - POSIX 1003.1b 7.2.2 - Line Control Functions
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+/* #include <sys/ioctl.h> */
+
+#include <rtems/libio.h>
+
+int tcflow (int fd, int action)
+{
+ return 0;
+}
+
+#endif
diff --git a/cpukit/libcsupport/src/tcflush.c b/cpukit/libcsupport/src/tcflush.c
new file mode 100644
index 0000000000..0335b94e8a
--- /dev/null
+++ b/cpukit/libcsupport/src/tcflush.c
@@ -0,0 +1,34 @@
+/*
+ * tcflush() - POSIX 1003.1b 7.2.2 - Line Control Functions
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+/* #include <sys/ioctl.h> */
+
+#include <rtems/libio.h>
+
+int tcflush (int fd, int queue)
+{
+ return 0;
+}
+
+#endif
diff --git a/cpukit/libcsupport/src/tcgetattr.c b/cpukit/libcsupport/src/tcgetattr.c
new file mode 100644
index 0000000000..8d4eb0618b
--- /dev/null
+++ b/cpukit/libcsupport/src/tcgetattr.c
@@ -0,0 +1,36 @@
+/*
+ * tcgetattr() - POSIX 1003.1b 7.2.1 - Get and Set State
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+/* #include <sys/ioctl.h> */
+
+#include <rtems/libio.h>
+
+int tcgetattr(
+ int fd,
+ struct termios *tp
+)
+{
+ return ioctl( fd, RTEMS_IO_GET_ATTRIBUTES, tp );
+}
+#endif
diff --git a/cpukit/libcsupport/src/tcgetprgrp.c b/cpukit/libcsupport/src/tcgetprgrp.c
new file mode 100644
index 0000000000..769883d46d
--- /dev/null
+++ b/cpukit/libcsupport/src/tcgetprgrp.c
@@ -0,0 +1,34 @@
+/*
+ * tcgetprgrp() - POSIX 1003.1b 7.2.3 - Get Foreground Process Group ID
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+/* #include <sys/ioctl.h> */
+
+#include <rtems/libio.h>
+
+pid_t tcgetprgrp(int fd)
+{
+ return getpid();
+}
+
+#endif
diff --git a/cpukit/libcsupport/src/tcsendbreak.c b/cpukit/libcsupport/src/tcsendbreak.c
new file mode 100644
index 0000000000..af7ea4c85b
--- /dev/null
+++ b/cpukit/libcsupport/src/tcsendbreak.c
@@ -0,0 +1,34 @@
+/*
+ * tcsendbreak() - POSIX 1003.1b 7.2.2 - Line Control Functions
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+/* #include <sys/ioctl.h> */
+
+#include <rtems/libio.h>
+
+int tcsendbreak ( int fd, int duration )
+{
+ return 0;
+}
+
+#endif
diff --git a/cpukit/libcsupport/src/tcsetattr.c b/cpukit/libcsupport/src/tcsetattr.c
new file mode 100644
index 0000000000..187c1df584
--- /dev/null
+++ b/cpukit/libcsupport/src/tcsetattr.c
@@ -0,0 +1,51 @@
+/*
+ * tcsetattr() - POSIX 1003.1b 7.2.1 - Get and Set State
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+/* #include <sys/ioctl.h> */
+
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int tcsetattr(
+ int fd,
+ int opt,
+ struct termios *tp
+)
+{
+ switch (opt) {
+ default:
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ case TCSADRAIN:
+ if (ioctl( fd, RTEMS_IO_TCDRAIN, NULL ) < 0)
+ return -1;
+ /*
+ * Fall through to....
+ */
+ case TCSANOW:
+ return ioctl( fd, RTEMS_IO_SET_ATTRIBUTES, tp );
+ }
+}
+#endif
diff --git a/cpukit/libcsupport/src/tcsetpgrp.c b/cpukit/libcsupport/src/tcsetpgrp.c
new file mode 100644
index 0000000000..be3c900ad4
--- /dev/null
+++ b/cpukit/libcsupport/src/tcsetpgrp.c
@@ -0,0 +1,34 @@
+/*
+ * tcsetprgrp() - POSIX 1003.1b 7.2.4 - Set Foreground Process Group ID
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+/* #include <sys/ioctl.h> */
+
+#include <rtems/libio.h>
+
+int tcsetprgrp(int fd, pid_t pid)
+{
+ return 0;
+}
+
+#endif
diff --git a/cpukit/libcsupport/src/telldir.c b/cpukit/libcsupport/src/telldir.c
new file mode 100644
index 0000000000..d7b9f23b4d
--- /dev/null
+++ b/cpukit/libcsupport/src/telldir.c
@@ -0,0 +1,47 @@
+/*
+ * telldir() - XXX
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <assert.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+long telldir(
+ DIR *dirp
+)
+{
+ rtems_libio_t *iop;
+
+ if ( !dirp )
+ rtems_set_errno_and_return_minus_one( EBADF );
+
+ /*
+ * Get the file control block structure associated with the
+ * file descriptor
+ */
+
+ iop = rtems_libio_iop( dirp->dd_fd );
+
+ if (iop == NULL)
+ assert(0);
+
+ return (long)( iop->offset );
+}
diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
new file mode 100644
index 0000000000..1917c68735
--- /dev/null
+++ b/cpukit/libcsupport/src/termios.c
@@ -0,0 +1,1502 @@
+/*
+ * TERMIOS serial line support
+ *
+ * Author:
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/ttycom.h>
+
+#include <rtems/termiostypes.h>
+
+/*
+ * The size of the cooked buffer
+ */
+#define CBUFSIZE (rtems_termios_cbufsize)
+
+/*
+ * The sizes of the raw message buffers.
+ * On most architectures it is quite a bit more
+ * efficient if these are powers of two.
+ */
+#define RAW_INPUT_BUFFER_SIZE (rtems_termios_raw_input_size)
+#define RAW_OUTPUT_BUFFER_SIZE (rtems_termios_raw_output_size)
+
+/* fields for "flow_ctrl" status */
+#define FL_IREQXOF 1 /* input queue requests stop of incoming data */
+#define FL_ISNTXOF 2 /* XOFF has been sent to other side of line */
+#define FL_IRTSOFF 4 /* RTS has been turned off for other side.. */
+
+#define FL_ORCVXOF 0x10 /* XOFF has been received */
+#define FL_OSTOP 0x20 /* output has been stopped due to XOFF */
+
+#define FL_MDRTS 0x100 /* input controlled with RTS/CTS handshake */
+#define FL_MDXON 0x200 /* input controlled with XON/XOFF protocol */
+#define FL_MDXOF 0x400 /* output controlled with XON/XOFF protocol */
+
+#define NODISC(n) \
+ { NULL, NULL, NULL, NULL, \
+ NULL, NULL, NULL, NULL }
+/*
+ * FIXME: change linesw entries consistant with linesw entry usage...
+ */
+struct linesw linesw[MAXLDISC] =
+{
+ NODISC(0), /* 0- termios-built-in */
+ NODISC(1), /* 1- defunct */
+ NODISC(2), /* 2- NTTYDISC */
+ NODISC(3), /* TABLDISC */
+ NODISC(4), /* SLIPDISC */
+ NODISC(5), /* PPPDISC */
+ NODISC(6), /* loadable */
+ NODISC(7), /* loadable */
+};
+
+int nlinesw = sizeof (linesw) / sizeof (linesw[0]);
+
+extern struct rtems_termios_tty *rtems_termios_ttyHead;
+extern struct rtems_termios_tty *rtems_termios_ttyTail;
+extern rtems_id rtems_termios_ttyMutex;
+
+static int rtems_termios_cbufsize = 256;
+static int rtems_termios_raw_input_size = 128;
+static int rtems_termios_raw_output_size = 64;
+
+static rtems_task rtems_termios_rxdaemon(rtems_task_argument argument);
+static rtems_task rtems_termios_txdaemon(rtems_task_argument argument);
+/*
+ * some constants for I/O daemon task creation
+ */
+#define TERMIOS_TXTASK_PRIO 10
+#define TERMIOS_RXTASK_PRIO 9
+#define TERMIOS_TXTASK_STACKSIZE 1024
+#define TERMIOS_RXTASK_STACKSIZE 1024
+/*
+ * some events to be sent to the I/O tasks
+ */
+#define TERMIOS_TX_START_EVENT RTEMS_EVENT_1
+#define TERMIOS_TX_TERMINATE_EVENT RTEMS_EVENT_0
+
+#define TERMIOS_RX_PROC_EVENT RTEMS_EVENT_1
+#define TERMIOS_RX_TERMINATE_EVENT RTEMS_EVENT_0
+
+/*
+ * Open a termios device
+ */
+rtems_status_code
+rtems_termios_open (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg,
+ const rtems_termios_callbacks *callbacks
+ )
+{
+ rtems_status_code sc;
+ rtems_libio_open_close_args_t *args = arg;
+ struct rtems_termios_tty *tty;
+
+ /*
+ * See if the device has already been opened
+ */
+ sc = rtems_semaphore_obtain (rtems_termios_ttyMutex,
+ RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ return sc;
+ for (tty = rtems_termios_ttyHead ; tty != NULL ; tty = tty->forw) {
+ if ((tty->major == major) && (tty->minor == minor))
+ break;
+ }
+ if (tty == NULL) {
+ static char c = 'a';
+
+ /*
+ * Create a new device
+ */
+ tty = calloc (1, sizeof (struct rtems_termios_tty));
+ if (tty == NULL) {
+ rtems_semaphore_release (rtems_termios_ttyMutex);
+ return RTEMS_NO_MEMORY;
+ }
+ /*
+ * allocate raw input buffer
+ */
+ tty->rawInBuf.Size = RAW_INPUT_BUFFER_SIZE;
+ tty->rawInBuf.theBuf = malloc (tty->rawInBuf.Size);
+ if (tty->rawInBuf.theBuf == NULL) {
+ free(tty);
+ rtems_semaphore_release (rtems_termios_ttyMutex);
+ return RTEMS_NO_MEMORY;
+ }
+ /*
+ * allocate raw output buffer
+ */
+ tty->rawOutBuf.Size = RAW_OUTPUT_BUFFER_SIZE;
+ tty->rawOutBuf.theBuf = malloc (tty->rawOutBuf.Size);
+ if (tty->rawOutBuf.theBuf == NULL) {
+ free((void *)(tty->rawInBuf.theBuf));
+ free(tty);
+ rtems_semaphore_release (rtems_termios_ttyMutex);
+ return RTEMS_NO_MEMORY;
+ }
+ /*
+ * allocate cooked buffer
+ */
+ tty->cbuf = malloc (CBUFSIZE);
+ if (tty->cbuf == NULL) {
+ free((void *)(tty->rawOutBuf.theBuf));
+ free((void *)(tty->rawInBuf.theBuf));
+ free(tty);
+ rtems_semaphore_release (rtems_termios_ttyMutex);
+ return RTEMS_NO_MEMORY;
+ }
+ /*
+ * Initialize wakeup callbacks
+ */
+ tty->tty_snd.sw_pfn = NULL;
+ tty->tty_snd.sw_arg = NULL;
+ tty->tty_rcv.sw_pfn = NULL;
+ tty->tty_rcv.sw_arg = NULL;
+ tty->tty_rcvwakeup = 0;
+
+ /*
+ * link tty
+ */
+ tty->forw = rtems_termios_ttyHead;
+ tty->back = NULL;
+ if (rtems_termios_ttyHead != NULL)
+ rtems_termios_ttyHead->back = tty;
+ rtems_termios_ttyHead = tty;
+ if (rtems_termios_ttyTail == NULL)
+ rtems_termios_ttyTail = tty;
+
+ tty->minor = minor;
+ tty->major = major;
+
+ /*
+ * Set up mutex semaphores
+ */
+ sc = rtems_semaphore_create (
+ rtems_build_name ('T', 'R', 'i', c),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
+ RTEMS_NO_PRIORITY,
+ &tty->isem);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ sc = rtems_semaphore_create (
+ rtems_build_name ('T', 'R', 'o', c),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
+ RTEMS_NO_PRIORITY,
+ &tty->osem);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ sc = rtems_semaphore_create (
+ rtems_build_name ('T', 'R', 'x', c),
+ 0,
+ RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_FIFO,
+ RTEMS_NO_PRIORITY,
+ &tty->rawOutBuf.Semaphore);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ tty->rawOutBufState = rob_idle;
+
+ /*
+ * Set callbacks
+ */
+ tty->device = *callbacks;
+
+ /*
+ * Create I/O tasks
+ */
+ if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) {
+ sc = rtems_task_create (
+ rtems_build_name ('T', 'x', 'T', c),
+ TERMIOS_TXTASK_PRIO,
+ TERMIOS_TXTASK_STACKSIZE,
+ RTEMS_NO_PREEMPT | RTEMS_NO_TIMESLICE |
+ RTEMS_NO_ASR,
+ RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
+ &tty->txTaskId);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ sc = rtems_task_create (
+ rtems_build_name ('R', 'x', 'T', c),
+ TERMIOS_RXTASK_PRIO,
+ TERMIOS_RXTASK_STACKSIZE,
+ RTEMS_NO_PREEMPT | RTEMS_NO_TIMESLICE |
+ RTEMS_NO_ASR,
+ RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
+ &tty->rxTaskId);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+
+ }
+ if ((tty->device.pollRead == NULL) ||
+ (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN)){
+ sc = rtems_semaphore_create (
+ rtems_build_name ('T', 'R', 'r', c),
+ 0,
+ RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY,
+ RTEMS_NO_PRIORITY,
+ &tty->rawInBuf.Semaphore);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ }
+
+ /*
+ * Set default parameters
+ */
+ tty->termios.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
+ tty->termios.c_oflag = OPOST | ONLCR | XTABS;
+ tty->termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
+ tty->termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOK | ECHOE | ECHOCTL;
+
+ tty->termios.c_cc[VINTR] = '\003';
+ tty->termios.c_cc[VQUIT] = '\034';
+ tty->termios.c_cc[VERASE] = '\177';
+ tty->termios.c_cc[VKILL] = '\025';
+ tty->termios.c_cc[VEOF] = '\004';
+ tty->termios.c_cc[VEOL] = '\000';
+ tty->termios.c_cc[VEOL2] = '\000';
+ tty->termios.c_cc[VSTART] = '\021';
+ tty->termios.c_cc[VSTOP] = '\023';
+ tty->termios.c_cc[VSUSP] = '\032';
+ tty->termios.c_cc[VREPRINT] = '\022';
+ tty->termios.c_cc[VDISCARD] = '\017';
+ tty->termios.c_cc[VWERASE] = '\027';
+ tty->termios.c_cc[VLNEXT] = '\026';
+
+ /* start with no flow control, clear flow control flags */
+ tty->flow_ctrl = 0;
+ /*
+ * set low/highwater mark for XON/XOFF support
+ */
+ tty->lowwater = tty->rawInBuf.Size * 1/2;
+ tty->highwater = tty->rawInBuf.Size * 3/4;
+ /*
+ * Bump name characer
+ */
+ if (c++ == 'z')
+ c = 'a';
+
+ }
+ args->iop->data1 = tty;
+ if (!tty->refcount++) {
+ if (tty->device.firstOpen)
+ (*tty->device.firstOpen)(major, minor, arg);
+ /*
+ * start I/O tasks, if needed
+ */
+ if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) {
+ sc = rtems_task_start(tty->rxTaskId,
+ rtems_termios_rxdaemon,
+ (rtems_task_argument)tty);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+
+ sc = rtems_task_start(tty->txTaskId,
+ rtems_termios_txdaemon,
+ (rtems_task_argument)tty);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ }
+ }
+ rtems_semaphore_release (rtems_termios_ttyMutex);
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Drain output queue
+ */
+static void
+drainOutput (struct rtems_termios_tty *tty)
+{
+ rtems_interrupt_level level;
+ rtems_status_code sc;
+
+ if (tty->device.outputUsesInterrupts != TERMIOS_POLLED) {
+ rtems_interrupt_disable (level);
+ while (tty->rawOutBuf.Tail != tty->rawOutBuf.Head) {
+ tty->rawOutBufState = rob_wait;
+ rtems_interrupt_enable (level);
+ sc = rtems_semaphore_obtain (tty->rawOutBuf.Semaphore,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ rtems_interrupt_disable (level);
+ }
+ rtems_interrupt_enable (level);
+ }
+}
+
+rtems_status_code
+rtems_termios_close (void *arg)
+{
+ rtems_libio_open_close_args_t *args = arg;
+ struct rtems_termios_tty *tty = args->iop->data1;
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain (rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ if (--tty->refcount == 0) {
+ if (linesw[tty->t_line].l_close != NULL) {
+ /*
+ * call discipline-specific close
+ */
+ sc = linesw[tty->t_line].l_close(tty);
+ }
+ else {
+ /*
+ * default: just flush output buffer
+ */
+ drainOutput (tty);
+ }
+
+ if (tty->device.outputUsesInterrupts
+ == TERMIOS_TASK_DRIVEN) {
+ /*
+ * send "terminate" to I/O tasks
+ */
+ sc = rtems_event_send(
+ tty->rxTaskId,
+ TERMIOS_RX_TERMINATE_EVENT);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ sc = rtems_event_send(
+ tty->txTaskId,
+ TERMIOS_TX_TERMINATE_EVENT);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ }
+ if (tty->device.lastClose)
+ (*tty->device.lastClose)(tty->major, tty->minor, arg);
+ if (tty->forw == NULL) {
+ rtems_termios_ttyTail = tty->back;
+ if ( rtems_termios_ttyTail != NULL ) {
+ rtems_termios_ttyTail->forw = NULL;
+ }
+ }
+ else {
+ tty->forw->back = tty->back;
+ }
+ if (tty->back == NULL) {
+ rtems_termios_ttyHead = tty->forw;
+ if ( rtems_termios_ttyHead != NULL ) {
+ rtems_termios_ttyHead->back = NULL;
+ }
+ }
+ else {
+ tty->back->forw = tty->forw;
+ }
+ rtems_semaphore_delete (tty->isem);
+ rtems_semaphore_delete (tty->osem);
+ rtems_semaphore_delete (tty->rawOutBuf.Semaphore);
+ if ((tty->device.pollRead == NULL) ||
+ (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN))
+ rtems_semaphore_delete (tty->rawInBuf.Semaphore);
+ free (tty->rawInBuf.theBuf);
+ free (tty->rawOutBuf.theBuf);
+ free (tty->cbuf);
+ free (tty);
+ }
+ rtems_semaphore_release (rtems_termios_ttyMutex);
+ return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code rtems_termios_bufsize (
+ int cbufsize,
+ int raw_input,
+ int raw_output
+)
+{
+ rtems_termios_cbufsize = cbufsize;
+ rtems_termios_raw_input_size = raw_input;
+ rtems_termios_raw_output_size = raw_output;
+ return RTEMS_SUCCESSFUL;
+}
+
+static void
+termios_set_flowctrl(struct rtems_termios_tty *tty)
+{
+ rtems_interrupt_level level;
+ /*
+ * check for flow control options to be switched off
+ */
+
+ /* check for outgoing XON/XOFF flow control switched off */
+ if (( tty->flow_ctrl & FL_MDXON) &&
+ !(tty->termios.c_iflag & IXON)) {
+ /* clear related flags in flow_ctrl */
+ tty->flow_ctrl &= ~(FL_MDXON | FL_ORCVXOF);
+
+ /* has output been stopped due to received XOFF? */
+ if (tty->flow_ctrl & FL_OSTOP) {
+ /* disable interrupts */
+ rtems_interrupt_disable(level);
+ tty->flow_ctrl &= ~FL_OSTOP;
+ /* check for chars in output buffer (or rob_state?) */
+ if (tty->rawOutBufState != rob_idle) {
+ /* if chars available, call write function... */
+ (*tty->device.write)(tty->minor,
+ &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
+ }
+ /* reenable interrupts */
+ rtems_interrupt_enable(level);
+ }
+ }
+ /* check for incoming XON/XOFF flow control switched off */
+ if (( tty->flow_ctrl & FL_MDXOF) &&
+ !(tty->termios.c_iflag & IXOFF)) {
+ /* clear related flags in flow_ctrl */
+ tty->flow_ctrl &= ~(FL_MDXOF);
+ /* FIXME: what happens, if we had sent XOFF but not yet XON? */
+ tty->flow_ctrl &= ~(FL_ISNTXOF);
+ }
+
+ /* check for incoming RTS/CTS flow control switched off */
+ if (( tty->flow_ctrl & FL_MDRTS) &&
+ !(tty->termios.c_cflag & CRTSCTS)) {
+ /* clear related flags in flow_ctrl */
+ tty->flow_ctrl &= ~(FL_MDRTS);
+
+ /* restart remote Tx, if it was stopped */
+ if ((tty->flow_ctrl & FL_IRTSOFF) &&
+ (tty->device.startRemoteTx != NULL)) {
+ tty->device.startRemoteTx(tty->minor);
+ }
+ tty->flow_ctrl &= ~(FL_IRTSOFF);
+ }
+
+ /*
+ * check for flow control options to be switched on
+ */
+ /* check for incoming RTS/CTS flow control switched on */
+ if (tty->termios.c_cflag & CRTSCTS) {
+ tty->flow_ctrl |= FL_MDRTS;
+ }
+ /* check for incoming XON/XOF flow control switched on */
+ if (tty->termios.c_iflag & IXOFF) {
+ tty->flow_ctrl |= FL_MDXOF;
+ }
+ /* check for outgoing XON/XOF flow control switched on */
+ if (tty->termios.c_iflag & IXON) {
+ tty->flow_ctrl |= FL_MDXON;
+ }
+}
+
+rtems_status_code
+rtems_termios_ioctl (void *arg)
+{
+ rtems_libio_ioctl_args_t *args = arg;
+ struct rtems_termios_tty *tty = args->iop->data1;
+ struct ttywakeup *wakeup = (struct ttywakeup *)args->buffer;
+ rtems_status_code sc;
+
+ args->ioctl_return = 0;
+ sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL) {
+ args->ioctl_return = sc;
+ return sc;
+ }
+ switch (args->command) {
+ default:
+ if (linesw[tty->t_line].l_ioctl != NULL) {
+ sc = linesw[tty->t_line].l_ioctl(tty,args);
+ }
+ else {
+ sc = RTEMS_INVALID_NUMBER;
+ }
+ break;
+
+ case RTEMS_IO_GET_ATTRIBUTES:
+ *(struct termios *)args->buffer = tty->termios;
+ break;
+
+ case RTEMS_IO_SET_ATTRIBUTES:
+ tty->termios = *(struct termios *)args->buffer;
+
+ /* check for and process change in flow control options */
+ termios_set_flowctrl(tty);
+
+ if (tty->termios.c_lflag & ICANON) {
+ tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
+ tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT;
+ tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
+ }
+ else {
+ rtems_interval ticksPerSecond;
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticksPerSecond);
+ tty->vtimeTicks = tty->termios.c_cc[VTIME] * ticksPerSecond / 10;
+ if (tty->termios.c_cc[VTIME]) {
+ tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
+ tty->rawInBufSemaphoreTimeout = tty->vtimeTicks;
+ if (tty->termios.c_cc[VMIN])
+ tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
+ else
+ tty->rawInBufSemaphoreFirstTimeout = tty->vtimeTicks;
+ }
+ else {
+ if (tty->termios.c_cc[VMIN]) {
+ tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
+ tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT;
+ tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
+ }
+ else {
+ tty->rawInBufSemaphoreOptions = RTEMS_NO_WAIT;
+ }
+ }
+ }
+ if (tty->device.setAttributes)
+ (*tty->device.setAttributes)(tty->minor, &tty->termios);
+ break;
+
+ case RTEMS_IO_TCDRAIN:
+ drainOutput (tty);
+ break;
+
+ case RTEMS_IO_SNDWAKEUP:
+ tty->tty_snd = *wakeup;
+ break;
+
+ case RTEMS_IO_RCVWAKEUP:
+ tty->tty_rcv = *wakeup;
+ break;
+
+ /*
+ * FIXME: add various ioctl code handlers
+ */
+
+#if 1 /* FIXME */
+ case TIOCSETD:
+ /*
+ * close old line discipline
+ */
+ if (linesw[tty->t_line].l_close != NULL) {
+ sc = linesw[tty->t_line].l_close(tty);
+ }
+ tty->t_line=*(int*)(args->buffer);
+ tty->t_sc = NULL; /* ensure that no more valid data */
+ /*
+ * open new line discipline
+ */
+ if (linesw[tty->t_line].l_open != NULL) {
+ sc = linesw[tty->t_line].l_open(tty);
+ }
+ break;
+ case TIOCGETD:
+ *(int*)(args->buffer)=tty->t_line;
+ break;
+#endif
+ case FIONREAD:
+ {
+ int rawnc = tty->rawInBuf.Tail - tty->rawInBuf.Head;
+ if ( rawnc < 0 )
+ rawnc += tty->rawInBuf.Size;
+ /* Half guess that this is the right operation */
+ *(int *)args->buffer = tty->ccount - tty->cindex + rawnc;
+ }
+ break;
+ }
+ rtems_semaphore_release (tty->osem);
+ args->ioctl_return = sc;
+ return sc;
+}
+
+/*
+ * Send characters to device-specific code
+ */
+void
+rtems_termios_puts (
+ const void *_buf, int len, struct rtems_termios_tty *tty)
+{
+ const unsigned char *buf = _buf;
+ unsigned int newHead;
+ rtems_interrupt_level level;
+ rtems_status_code sc;
+
+ if (tty->device.outputUsesInterrupts == TERMIOS_POLLED) {
+ (*tty->device.write)(tty->minor, (void *)buf, len);
+ return;
+ }
+ newHead = tty->rawOutBuf.Head;
+ while (len) {
+ /*
+ * Performance improvement could be made here.
+ * Copy multiple bytes to raw buffer:
+ * if (len > 1) && (space to buffer end, or tail > 1)
+ * ncopy = MIN (len, space to buffer end or tail)
+ * memcpy (raw buffer, buf, ncopy)
+ * buf += ncopy
+ * len -= ncopy
+ *
+ * To minimize latency, the memcpy should be done
+ * with interrupts enabled.
+ */
+ newHead = (newHead + 1) % tty->rawOutBuf.Size;
+ rtems_interrupt_disable (level);
+ while (newHead == tty->rawOutBuf.Tail) {
+ tty->rawOutBufState = rob_wait;
+ rtems_interrupt_enable (level);
+ sc = rtems_semaphore_obtain (tty->rawOutBuf.Semaphore,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ rtems_interrupt_disable (level);
+ }
+ tty->rawOutBuf.theBuf[tty->rawOutBuf.Head] = *buf++;
+ tty->rawOutBuf.Head = newHead;
+ if (tty->rawOutBufState == rob_idle) {
+ /* check, whether XOFF has been received */
+ if (!(tty->flow_ctrl & FL_ORCVXOF)) {
+ (*tty->device.write)(tty->minor,
+ (char *)&tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
+ }
+ else {
+ /* remember that output has been stopped due to flow ctrl*/
+ tty->flow_ctrl |= FL_OSTOP;
+ }
+ tty->rawOutBufState = rob_busy;
+ }
+ rtems_interrupt_enable (level);
+ len--;
+ }
+}
+
+/*
+ * Handle output processing
+ */
+static void
+oproc (unsigned char c, struct rtems_termios_tty *tty)
+{
+ int i;
+
+ if (tty->termios.c_oflag & OPOST) {
+ switch (c) {
+ case '\n':
+ if (tty->termios.c_oflag & ONLRET)
+ tty->column = 0;
+ if (tty->termios.c_oflag & ONLCR) {
+ rtems_termios_puts ("\r", 1, tty);
+ tty->column = 0;
+ }
+ break;
+
+ case '\r':
+ if ((tty->termios.c_oflag & ONOCR) && (tty->column == 0))
+ return;
+ if (tty->termios.c_oflag & OCRNL) {
+ c = '\n';
+ if (tty->termios.c_oflag & ONLRET)
+ tty->column = 0;
+ break;
+ }
+ tty->column = 0;
+ break;
+
+ case '\t':
+ i = 8 - (tty->column & 7);
+ if ((tty->termios.c_oflag & TABDLY) == XTABS) {
+ tty->column += i;
+ rtems_termios_puts ( " ", i, tty);
+ return;
+ }
+ tty->column += i;
+ break;
+
+ case '\b':
+ if (tty->column > 0)
+ tty->column--;
+ break;
+
+ default:
+ if (tty->termios.c_oflag & OLCUC)
+ c = toupper(c);
+ if (!iscntrl(c))
+ tty->column++;
+ break;
+ }
+ }
+ rtems_termios_puts (&c, 1, tty);
+}
+
+rtems_status_code
+rtems_termios_write (void *arg)
+{
+ rtems_libio_rw_args_t *args = arg;
+ struct rtems_termios_tty *tty = args->iop->data1;
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ return sc;
+ if (linesw[tty->t_line].l_write != NULL) {
+ sc = linesw[tty->t_line].l_write(tty,args);
+ rtems_semaphore_release (tty->osem);
+ return sc;
+ }
+ if (tty->termios.c_oflag & OPOST) {
+ uint32_t count = args->count;
+ char *buffer = args->buffer;
+ while (count--)
+ oproc (*buffer++, tty);
+ args->bytes_moved = args->count;
+ }
+ else {
+ rtems_termios_puts (args->buffer, args->count, tty);
+ args->bytes_moved = args->count;
+ }
+ rtems_semaphore_release (tty->osem);
+ return sc;
+}
+
+/*
+ * Echo a typed character
+ */
+static void
+echo (unsigned char c, struct rtems_termios_tty *tty)
+{
+ if ((tty->termios.c_lflag & ECHOCTL) && iscntrl(c) && (c != '\t') && (c != '\n')) {
+ char echobuf[2];
+
+ echobuf[0] = '^';
+ echobuf[1] = c ^ 0x40;
+ rtems_termios_puts (echobuf, 2, tty);
+ tty->column += 2;
+ }
+ else {
+ oproc (c, tty);
+ }
+}
+
+/*
+ * Erase a character or line
+ * FIXME: Needs support for WERASE and ECHOPRT.
+ * FIXME: Some of the tests should check for IEXTEN, too.
+ */
+static void
+erase (struct rtems_termios_tty *tty, int lineFlag)
+{
+ if (tty->ccount == 0)
+ return;
+ if (lineFlag) {
+ if (!(tty->termios.c_lflag & ECHO)) {
+ tty->ccount = 0;
+ return;
+ }
+ if (!(tty->termios.c_lflag & ECHOE)) {
+ tty->ccount = 0;
+ echo (tty->termios.c_cc[VKILL], tty);
+ if (tty->termios.c_lflag & ECHOK)
+ echo ('\n', tty);
+ return;
+ }
+ }
+ while (tty->ccount) {
+ unsigned char c = tty->cbuf[--tty->ccount];
+
+ if (tty->termios.c_lflag & ECHO) {
+ if (!lineFlag && !(tty->termios.c_lflag & ECHOE)) {
+ echo (tty->termios.c_cc[VERASE], tty);
+ }
+ else if (c == '\t') {
+ int col = tty->read_start_column;
+ int i = 0;
+
+ /*
+ * Find the character before the tab
+ */
+ while (i != tty->ccount) {
+ c = tty->cbuf[i++];
+ if (c == '\t') {
+ col = (col | 7) + 1;
+ }
+ else if (iscntrl (c)) {
+ if (tty->termios.c_lflag & ECHOCTL)
+ col += 2;
+ }
+ else {
+ col++;
+ }
+ }
+
+ /*
+ * Back up over the tab
+ */
+ while (tty->column > col) {
+ rtems_termios_puts ("\b", 1, tty);
+ tty->column--;
+ }
+ }
+ else {
+ if (iscntrl (c) && (tty->termios.c_lflag & ECHOCTL)) {
+ rtems_termios_puts ("\b \b", 3, tty);
+ if (tty->column)
+ tty->column--;
+ }
+ if (!iscntrl (c) || (tty->termios.c_lflag & ECHOCTL)) {
+ rtems_termios_puts ("\b \b", 3, tty);
+ if (tty->column)
+ tty->column--;
+ }
+ }
+ }
+ if (!lineFlag)
+ break;
+ }
+}
+
+/*
+ * Process a single input character
+ */
+static int
+iproc (unsigned char c, struct rtems_termios_tty *tty)
+{
+ if (tty->termios.c_iflag & ISTRIP)
+ c &= 0x7f;
+ if (tty->termios.c_iflag & IUCLC)
+ c = tolower (c);
+ if (c == '\r') {
+ if (tty->termios.c_iflag & IGNCR)
+ return 0;
+ if (tty->termios.c_iflag & ICRNL)
+ c = '\n';
+ }
+ else if ((c == '\n') && (tty->termios.c_iflag & INLCR)) {
+ c = '\r';
+ }
+ if ((c != '\0') && (tty->termios.c_lflag & ICANON)) {
+ if (c == tty->termios.c_cc[VERASE]) {
+ erase (tty, 0);
+ return 0;
+ }
+ else if (c == tty->termios.c_cc[VKILL]) {
+ erase (tty, 1);
+ return 0;
+ }
+ else if (c == tty->termios.c_cc[VEOF]) {
+ return 1;
+ }
+ else if (c == '\n') {
+ if (tty->termios.c_lflag & (ECHO | ECHONL))
+ echo (c, tty);
+ tty->cbuf[tty->ccount++] = c;
+ return 1;
+ }
+ else if ((c == tty->termios.c_cc[VEOL])
+ || (c == tty->termios.c_cc[VEOL2])) {
+ if (tty->termios.c_lflag & ECHO)
+ echo (c, tty);
+ tty->cbuf[tty->ccount++] = c;
+ return 1;
+ }
+ }
+
+ /*
+ * FIXME: Should do IMAXBEL handling somehow
+ */
+ if (tty->ccount < (CBUFSIZE-1)) {
+ if (tty->termios.c_lflag & ECHO)
+ echo (c, tty);
+ tty->cbuf[tty->ccount++] = c;
+ }
+ return 0;
+}
+
+/*
+ * Process input character, with semaphore.
+ */
+static int
+siproc (unsigned char c, struct rtems_termios_tty *tty)
+{
+ int i;
+
+ /*
+ * Obtain output semaphore if character will be echoed
+ */
+ if (tty->termios.c_lflag & (ECHO|ECHOE|ECHOK|ECHONL|ECHOPRT|ECHOCTL|ECHOKE)) {
+ rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ i = iproc (c, tty);
+ rtems_semaphore_release (tty->osem);
+ }
+ else {
+ i = iproc (c, tty);
+ }
+ return i;
+}
+
+/*
+ * Fill the input buffer by polling the device
+ */
+static rtems_status_code
+fillBufferPoll (struct rtems_termios_tty *tty)
+{
+ int n;
+
+ if (tty->termios.c_lflag & ICANON) {
+ for (;;) {
+ n = (*tty->device.pollRead)(tty->minor);
+ if (n < 0) {
+ rtems_task_wake_after (1);
+ }
+ else {
+ if (siproc (n, tty))
+ break;
+ }
+ }
+ }
+ else {
+ rtems_interval then, now;
+ if (!tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME])
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
+ for (;;) {
+ n = (*tty->device.pollRead)(tty->minor);
+ if (n < 0) {
+ if (tty->termios.c_cc[VMIN]) {
+ if (tty->termios.c_cc[VTIME] && tty->ccount) {
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ if ((now - then) > tty->vtimeTicks) {
+ break;
+ }
+ }
+ }
+ else {
+ if (!tty->termios.c_cc[VTIME])
+ break;
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ if ((now - then) > tty->vtimeTicks) {
+ break;
+ }
+ }
+ rtems_task_wake_after (1);
+ }
+ else {
+ siproc (n, tty);
+ if (tty->ccount >= tty->termios.c_cc[VMIN])
+ break;
+ if (tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME])
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
+ }
+ }
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Fill the input buffer from the raw input queue
+ */
+static rtems_status_code
+fillBufferQueue (struct rtems_termios_tty *tty)
+{
+ rtems_interval timeout = tty->rawInBufSemaphoreFirstTimeout;
+ rtems_status_code sc;
+ int wait = (int)1;
+
+ while ( wait ) {
+ /*
+ * Process characters read from raw queue
+ */
+ while (tty->rawInBuf.Head != tty->rawInBuf.Tail) {
+ unsigned char c;
+ unsigned int newHead;
+
+ newHead = (tty->rawInBuf.Head + 1) % tty->rawInBuf.Size;
+ c = tty->rawInBuf.theBuf[newHead];
+ tty->rawInBuf.Head = newHead;
+ if(((tty->rawInBuf.Tail-newHead+tty->rawInBuf.Size)
+ % tty->rawInBuf.Size)
+ < tty->lowwater) {
+ tty->flow_ctrl &= ~FL_IREQXOF;
+ /* if tx stopped and XON should be sent... */
+ if (((tty->flow_ctrl & (FL_MDXON | FL_ISNTXOF))
+ == (FL_MDXON | FL_ISNTXOF))
+ && ((tty->rawOutBufState == rob_idle)
+ || (tty->flow_ctrl & FL_OSTOP))) {
+ /* XON should be sent now... */
+ (*tty->device.write)(tty->minor,
+ (void *)&(tty->termios.c_cc[VSTART]),
+ 1);
+ }
+ else if (tty->flow_ctrl & FL_MDRTS) {
+ tty->flow_ctrl &= ~FL_IRTSOFF;
+ /* activate RTS line */
+ if (tty->device.startRemoteTx != NULL) {
+ tty->device.startRemoteTx(tty->minor);
+ }
+ }
+ }
+
+ /* continue processing new character */
+ if (tty->termios.c_lflag & ICANON) {
+ if (siproc (c, tty))
+ wait = 0;
+ }
+ else {
+ siproc (c, tty);
+ if (tty->ccount >= tty->termios.c_cc[VMIN])
+ wait = 0;
+ }
+ timeout = tty->rawInBufSemaphoreTimeout;
+ }
+
+ /*
+ * Wait for characters
+ */
+ if ( wait ) {
+ sc = rtems_semaphore_obtain (tty->rawInBuf.Semaphore,
+ tty->rawInBufSemaphoreOptions,
+ timeout);
+ if (sc != RTEMS_SUCCESSFUL)
+ break;
+ }
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code
+rtems_termios_read (void *arg)
+{
+ rtems_libio_rw_args_t *args = arg;
+ struct rtems_termios_tty *tty = args->iop->data1;
+ uint32_t count = args->count;
+ char *buffer = args->buffer;
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ return sc;
+ if (linesw[tty->t_line].l_read != NULL) {
+ sc = linesw[tty->t_line].l_read(tty,args);
+ tty->tty_rcvwakeup = 0;
+ rtems_semaphore_release (tty->isem);
+ return sc;
+ }
+ if (tty->cindex == tty->ccount) {
+ tty->cindex = tty->ccount = 0;
+ tty->read_start_column = tty->column;
+ if (tty->device.pollRead != NULL
+ && tty->device.outputUsesInterrupts == TERMIOS_POLLED)
+ sc = fillBufferPoll (tty);
+ else
+ sc = fillBufferQueue (tty);
+ if (sc != RTEMS_SUCCESSFUL)
+ tty->cindex = tty->ccount = 0;
+ }
+ while (count && (tty->cindex < tty->ccount)) {
+ *buffer++ = tty->cbuf[tty->cindex++];
+ count--;
+ }
+ args->bytes_moved = args->count - count;
+ tty->tty_rcvwakeup = 0;
+ rtems_semaphore_release (tty->isem);
+ return sc;
+}
+
+/*
+ * signal receive interrupt to rx daemon
+ * NOTE: This routine runs in the context of the
+ * device receive interrupt handler.
+ */
+void rtems_termios_rxirq_occured(struct rtems_termios_tty *tty)
+{
+ /*
+ * send event to rx daemon task
+ */
+ rtems_event_send(tty->rxTaskId,TERMIOS_RX_PROC_EVENT);
+}
+
+/*
+ * Place characters on raw queue.
+ * NOTE: This routine runs in the context of the
+ * device receive interrupt handler.
+ * Returns the number of characters dropped because of overflow.
+ */
+int
+rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len)
+{
+ struct rtems_termios_tty *tty = ttyp;
+ unsigned int newTail;
+ char c;
+ int dropped = 0;
+ boolean flow_rcv = FALSE; /* TRUE, if flow control char received */
+ rtems_interrupt_level level;
+
+ if (linesw[tty->t_line].l_rint != NULL) {
+ while (len--) {
+ c = *buf++;
+ linesw[tty->t_line].l_rint(c,tty);
+ }
+
+ /*
+ * check to see if rcv wakeup callback was set
+ */
+ if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
+ (*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
+ tty->tty_rcvwakeup = 1;
+ }
+ return 0;
+ }
+
+ while (len--) {
+ c = *buf++;
+ /* FIXME: implement IXANY: any character restarts output */
+ /* if incoming XON/XOFF controls outgoing stream: */
+ if (tty->flow_ctrl & FL_MDXON) {
+ /* if received char is V_STOP and V_START (both are equal value) */
+ if (c == tty->termios.c_cc[VSTOP]) {
+ if (c == tty->termios.c_cc[VSTART]) {
+ /* received VSTOP and VSTART==VSTOP? */
+ /* then toggle "stop output" status */
+ tty->flow_ctrl = tty->flow_ctrl ^ FL_ORCVXOF;
+ }
+ else {
+ /* VSTOP received (other code than VSTART) */
+ /* stop output */
+ tty->flow_ctrl |= FL_ORCVXOF;
+ }
+ flow_rcv = TRUE;
+ }
+ else if (c == tty->termios.c_cc[VSTART]) {
+ /* VSTART received */
+ /* restart output */
+ tty->flow_ctrl &= ~FL_ORCVXOF;
+ flow_rcv = TRUE;
+ }
+ }
+ if (flow_rcv) {
+ /* restart output according to FL_ORCVXOF flag */
+ if ((tty->flow_ctrl & (FL_ORCVXOF | FL_OSTOP)) == FL_OSTOP) {
+ /* disable interrupts */
+ rtems_interrupt_disable(level);
+ tty->flow_ctrl &= ~FL_OSTOP;
+ /* check for chars in output buffer (or rob_state?) */
+ if (tty->rawOutBufState != rob_idle) {
+ /* if chars available, call write function... */
+ (*tty->device.write)(tty->minor,
+ &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1);
+ }
+ /* reenable interrupts */
+ rtems_interrupt_enable(level);
+ }
+ }
+ else {
+ newTail = (tty->rawInBuf.Tail + 1) % tty->rawInBuf.Size;
+ /* if chars_in_buffer > highwater */
+ rtems_interrupt_disable(level);
+ if ((((newTail - tty->rawInBuf.Head + tty->rawInBuf.Size)
+ % tty->rawInBuf.Size)
+ > tty->highwater) &&
+ !(tty->flow_ctrl & FL_IREQXOF)) {
+ /* incoming data stream should be stopped */
+ tty->flow_ctrl |= FL_IREQXOF;
+ if ((tty->flow_ctrl & (FL_MDXOF | FL_ISNTXOF))
+ == (FL_MDXOF ) ){
+ if ((tty->flow_ctrl & FL_OSTOP) ||
+ (tty->rawOutBufState == rob_idle)) {
+ /* if tx is stopped due to XOFF or out of data */
+ /* call write function here */
+ tty->flow_ctrl |= FL_ISNTXOF;
+ (*tty->device.write)(tty->minor,
+ (void *)&(tty->termios.c_cc[VSTOP]),
+ 1);
+ }
+ }
+ else if ((tty->flow_ctrl & (FL_MDRTS | FL_IRTSOFF))
+ == (FL_MDRTS ) ) {
+ tty->flow_ctrl |= FL_IRTSOFF;
+ /* deactivate RTS line */
+ if (tty->device.stopRemoteTx != NULL) {
+ tty->device.stopRemoteTx(tty->minor);
+ }
+ }
+ }
+ /* reenable interrupts */
+ rtems_interrupt_enable(level);
+
+ if (newTail == tty->rawInBuf.Head) {
+ dropped++;
+ }
+ else {
+ tty->rawInBuf.theBuf[newTail] = c;
+ tty->rawInBuf.Tail = newTail;
+
+ /*
+ * check to see if rcv wakeup callback was set
+ */
+ if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
+ (*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
+ tty->tty_rcvwakeup = 1;
+ }
+ }
+ }
+ }
+ tty->rawInBufDropped += dropped;
+ rtems_semaphore_release (tty->rawInBuf.Semaphore);
+ return dropped;
+}
+
+/*
+ * in task-driven mode, this function is called in Tx task context
+ * in interrupt-driven mode, this function is called in TxIRQ context
+ */
+int
+rtems_termios_refill_transmitter (struct rtems_termios_tty *tty)
+{
+ unsigned int newTail;
+ int nToSend;
+ rtems_interrupt_level level;
+ int len;
+
+ /* check for XOF/XON to send */
+ if ((tty->flow_ctrl & (FL_MDXOF | FL_IREQXOF | FL_ISNTXOF))
+ == (FL_MDXOF | FL_IREQXOF)) {
+ /* XOFF should be sent now... */
+ (*tty->device.write)(tty->minor,
+ (void *)&(tty->termios.c_cc[VSTOP]), 1);
+
+ rtems_interrupt_disable(level);
+ tty->t_dqlen--;
+ tty->flow_ctrl |= FL_ISNTXOF;
+ rtems_interrupt_enable(level);
+
+ nToSend = 1;
+ }
+ else if ((tty->flow_ctrl & (FL_IREQXOF | FL_ISNTXOF))
+ == FL_ISNTXOF) {
+ /* NOTE: send XON even, if no longer in XON/XOFF mode... */
+ /* XON should be sent now... */
+ /*
+ * FIXME: this .write call will generate another
+ * dequeue callback. This will advance the "Tail" in the data
+ * buffer, although the corresponding data is not yet out!
+ * Therefore the dequeue "length" should be reduced by 1
+ */
+ (*tty->device.write)(tty->minor,
+ (void *)&(tty->termios.c_cc[VSTART]), 1);
+
+ rtems_interrupt_disable(level);
+ tty->t_dqlen--;
+ tty->flow_ctrl &= ~FL_ISNTXOF;
+ rtems_interrupt_enable(level);
+
+ nToSend = 1;
+ }
+ else {
+ if ( tty->rawOutBuf.Head == tty->rawOutBuf.Tail ) {
+ /*
+ * buffer was empty
+ */
+ if (tty->rawOutBufState == rob_wait) {
+ /*
+ * this should never happen...
+ */
+ rtems_semaphore_release (tty->rawOutBuf.Semaphore);
+ }
+ return 0;
+ }
+
+ rtems_interrupt_disable(level);
+ len = tty->t_dqlen;
+ tty->t_dqlen = 0;
+ rtems_interrupt_enable(level);
+
+ newTail = (tty->rawOutBuf.Tail + len) % tty->rawOutBuf.Size;
+ tty->rawOutBuf.Tail = newTail;
+ if (tty->rawOutBufState == rob_wait) {
+ /*
+ * wake up any pending writer task
+ */
+ rtems_semaphore_release (tty->rawOutBuf.Semaphore);
+ }
+ if (newTail == tty->rawOutBuf.Head) {
+ /*
+ * Buffer has become empty
+ */
+ tty->rawOutBufState = rob_idle;
+ nToSend = 0;
+
+ /*
+ * check to see if snd wakeup callback was set
+ */
+ if ( tty->tty_snd.sw_pfn != NULL) {
+ (*tty->tty_snd.sw_pfn)(&tty->termios, tty->tty_snd.sw_arg);
+ }
+ }
+ /* check, whether output should stop due to received XOFF */
+ else if ((tty->flow_ctrl & (FL_MDXON | FL_ORCVXOF))
+ == (FL_MDXON | FL_ORCVXOF)) {
+ /* Buffer not empty, but output stops due to XOFF */
+ /* set flag, that output has been stopped */
+ rtems_interrupt_disable(level);
+ tty->flow_ctrl |= FL_OSTOP;
+ tty->rawOutBufState = rob_busy; /*apm*/
+ rtems_interrupt_enable(level);
+ nToSend = 0;
+ }
+ else {
+ /*
+ * Buffer not empty, start tranmitter
+ */
+ if (newTail > tty->rawOutBuf.Head)
+ nToSend = tty->rawOutBuf.Size - newTail;
+ else
+ nToSend = tty->rawOutBuf.Head - newTail;
+ /* when flow control XON or XOF, don't send blocks of data */
+ /* to allow fast reaction on incoming flow ctrl and low latency*/
+ /* for outgoing flow control */
+ if (tty->flow_ctrl & (FL_MDXON | FL_MDXOF)) {
+ nToSend = 1;
+ }
+ tty->rawOutBufState = rob_busy; /*apm*/
+ (*tty->device.write)(tty->minor,
+ &tty->rawOutBuf.theBuf[newTail],
+ nToSend);
+ }
+ tty->rawOutBuf.Tail = newTail; /*apm*/
+ }
+ return nToSend;
+}
+
+/*
+ * Characters have been transmitted
+ * NOTE: This routine runs in the context of the
+ * device transmit interrupt handler.
+ * The second argument is the number of characters transmitted so far.
+ * This value will always be 1 for devices which generate an interrupt
+ * for each transmitted character.
+ * It returns number of characters left to transmit
+ */
+int
+rtems_termios_dequeue_characters (void *ttyp, int len)
+{
+ struct rtems_termios_tty *tty = ttyp;
+ rtems_status_code sc;
+
+ /*
+ * sum up character count already sent
+ */
+ tty->t_dqlen += len;
+
+ if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) {
+ /*
+ * send wake up to transmitter task
+ */
+ sc = rtems_event_send(tty->txTaskId,
+ TERMIOS_TX_START_EVENT);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ return 0; /* nothing to output in IRQ... */
+ }
+ else if (tty->t_line == PPPDISC ) {
+ /*
+ * call any line discipline start function
+ */
+ if (linesw[tty->t_line].l_start != NULL) {
+ linesw[tty->t_line].l_start(tty);
+ }
+ return 0; /* nothing to output in IRQ... */
+ }
+ else {
+ return rtems_termios_refill_transmitter(tty);
+ }
+}
+
+/*
+ * this task actually processes any transmit events
+ */
+static rtems_task rtems_termios_txdaemon(rtems_task_argument argument)
+{
+ struct rtems_termios_tty *tty = (struct rtems_termios_tty *)argument;
+ rtems_event_set the_event;
+
+ while (1) {
+ /*
+ * wait for rtems event
+ */
+ rtems_event_receive((TERMIOS_TX_START_EVENT |
+ TERMIOS_TX_TERMINATE_EVENT),
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &the_event);
+ if ((the_event & TERMIOS_TX_TERMINATE_EVENT) != 0) {
+ tty->txTaskId = 0;
+ rtems_task_delete(RTEMS_SELF);
+ }
+ else {
+ /*
+ * call any line discipline start function
+ */
+ if (linesw[tty->t_line].l_start != NULL) {
+ linesw[tty->t_line].l_start(tty);
+ }
+ /*
+ * try to push further characters to device
+ */
+ rtems_termios_refill_transmitter(tty);
+ }
+ }
+}
+
+/*
+ * this task actually processes any receive events
+ */
+static rtems_task rtems_termios_rxdaemon(rtems_task_argument argument)
+{
+ struct rtems_termios_tty *tty = (struct rtems_termios_tty *)argument;
+ rtems_event_set the_event;
+ int c;
+ char c_buf;
+ while (1) {
+ /*
+ * wait for rtems event
+ */
+ rtems_event_receive((TERMIOS_RX_PROC_EVENT |
+ TERMIOS_RX_TERMINATE_EVENT),
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &the_event);
+ if ((the_event & TERMIOS_RX_TERMINATE_EVENT) != 0) {
+ tty->rxTaskId = 0;
+ rtems_task_delete(RTEMS_SELF);
+ }
+ else {
+ /*
+ * do something
+ */
+ c = tty->device.pollRead(tty->minor);
+ if (c != EOF) {
+ /*
+ * pollRead did call enqueue on its own
+ */
+ c_buf = c;
+ rtems_termios_enqueue_raw_characters (
+ tty,&c_buf,1);
+ }
+ }
+ }
+}
diff --git a/cpukit/libcsupport/src/termiosinitialize.c b/cpukit/libcsupport/src/termiosinitialize.c
new file mode 100644
index 0000000000..b6660fe342
--- /dev/null
+++ b/cpukit/libcsupport/src/termiosinitialize.c
@@ -0,0 +1,54 @@
+/*
+ * Termios initialization routine
+ *
+ * Author:
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+struct rtems_termios_tty *rtems_termios_ttyHead;
+struct rtems_termios_tty *rtems_termios_ttyTail;
+rtems_id rtems_termios_ttyMutex;
+
+void
+rtems_termios_initialize (void)
+{
+ rtems_status_code sc;
+
+ /*
+ * Create the mutex semaphore for the tty list
+ */
+ if (!rtems_termios_ttyMutex) {
+ sc = rtems_semaphore_create (
+ rtems_build_name ('T', 'R', 'm', 'i'),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
+ RTEMS_NO_PRIORITY,
+ &rtems_termios_ttyMutex);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+ }
+}
diff --git a/cpukit/libcsupport/src/termiosreserveresources.c b/cpukit/libcsupport/src/termiosreserveresources.c
new file mode 100644
index 0000000000..6637cfd2d9
--- /dev/null
+++ b/cpukit/libcsupport/src/termiosreserveresources.c
@@ -0,0 +1,36 @@
+/*
+ * Reserve enough resources to open every physical device once.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#if 0
+static int first_time; /* assumed to be zeroed by BSS initialization */
+#endif
+
+void rtems_termios_reserve_resources (
+ rtems_configuration_table *configuration,
+ uint32_t number_of_devices
+)
+{
+#if 0
+ rtems_api_configuration_table *rtems_config;
+
+
+ if (!configuration)
+ rtems_fatal_error_occurred (0xFFF0F001);
+ rtems_config = configuration->RTEMS_api_configuration;
+ if (!rtems_config)
+ rtems_fatal_error_occurred (0xFFF0F002);
+ if (!first_time)
+ rtems_config->maximum_semaphores += 1;
+ first_time = 1;
+ rtems_config->maximum_semaphores += (4 * number_of_devices);
+#endif
+}
diff --git a/cpukit/libcsupport/src/truncate.c b/cpukit/libcsupport/src/truncate.c
new file mode 100644
index 0000000000..7a0a98b4bd
--- /dev/null
+++ b/cpukit/libcsupport/src/truncate.c
@@ -0,0 +1,43 @@
+/*
+ * truncate() - Truncate a File to the Specified Length
+ *
+ * This routine is not defined in the POSIX 1003.1b standard but is
+ * commonly supported on most UNIX and POSIX systems. It is provided
+ * for compatibility.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+int truncate(
+ const char *path,
+ off_t length
+)
+{
+ int status;
+ int fd;
+
+ fd = open( path, O_WRONLY );
+ if ( fd == -1 )
+ return -1;
+
+ status = ftruncate( fd, length );
+
+ (void) close( fd );
+
+ return status;
+}
diff --git a/cpukit/libcsupport/src/ttyname.c b/cpukit/libcsupport/src/ttyname.c
new file mode 100644
index 0000000000..d483349235
--- /dev/null
+++ b/cpukit/libcsupport/src/ttyname.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1988, 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <termios.h>
+#include <unistd.h>
+#include <string.h>
+#include <paths.h>
+#include <_syslist.h>
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+static char ttyname_buf[sizeof (_PATH_DEV) + MAXNAMLEN] = _PATH_DEV;
+
+/*
+ * ttyname_r() - POSIX 1003.1b 4.7.2 - Demetermine Terminal Device Name
+ */
+int ttyname_r(
+ int fd,
+ char *name,
+ int namesize
+)
+{
+ struct stat sb;
+ struct termios tty;
+ struct dirent *dirp;
+ DIR *dp;
+ struct stat dsb;
+ char *rval;
+
+ /* Must be a terminal. */
+ if (tcgetattr (fd, &tty) < 0)
+ rtems_set_errno_and_return_minus_one(EBADF);
+
+ /* Must be a character device. */
+ if (fstat (fd, &sb) || !S_ISCHR (sb.st_mode))
+ rtems_set_errno_and_return_minus_one(EBADF);
+
+ if ((dp = opendir (_PATH_DEV)) == NULL)
+ rtems_set_errno_and_return_minus_one(EBADF);
+
+ for (rval = NULL; (dirp = readdir (dp)) != NULL ;)
+ {
+ if (dirp->d_ino != sb.st_ino)
+ continue;
+ strcpy (name + sizeof (_PATH_DEV) - 1, dirp->d_name);
+ if (stat (name, &dsb) || sb.st_dev != dsb.st_dev ||
+ sb.st_ino != dsb.st_ino)
+ continue;
+ rval = name;
+ break;
+ }
+ (void) closedir (dp);
+ return 0;
+}
+
+/*
+ * ttyname() - POSIX 1003.1b 4.7.2 - Demetermine Terminal Device Name
+ */
+
+char *ttyname(
+ int fd
+)
+{
+ if ( !ttyname_r( fd, ttyname_buf, sizeof(ttyname_buf) ) )
+ return ttyname_buf;
+ return NULL;
+}
diff --git a/cpukit/libcsupport/src/umask.c b/cpukit/libcsupport/src/umask.c
new file mode 100644
index 0000000000..32bf79e2b9
--- /dev/null
+++ b/cpukit/libcsupport/src/umask.c
@@ -0,0 +1,33 @@
+/*
+ * umask() - POSIX 1003.1b 5.3.3 - Set File Creation Mask
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/libio_.h>
+
+mode_t umask(
+ mode_t cmask
+)
+{
+ mode_t old_mask;
+
+ old_mask = rtems_filesystem_umask;
+ rtems_filesystem_umask = cmask;
+
+ return old_mask;
+}
diff --git a/cpukit/libcsupport/src/unixlibc.c b/cpukit/libcsupport/src/unixlibc.c
new file mode 100644
index 0000000000..79cc5e19c1
--- /dev/null
+++ b/cpukit/libcsupport/src/unixlibc.c
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ * UNIX Port C Library Support
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+rtems_status_code rtems_io_register_name(
+ const char *device_name,
+ rtems_device_major_number major,
+ rtems_device_minor_number minor
+)
+{
+ return 0; /* not supported */
+}
+
+rtems_status_code rtems_io_lookup_name(
+ const char *name,
+ rtems_driver_name_t *device_info
+)
+{
+ return 0; /* not supported */
+}
+
+#if defined(RTEMS_UNIXLIB)
+
+void libc_init(int reentrant)
+{
+}
+
+#else
+
+/* remove ANSI errors.
+ * A program must contain at least one external-declaration
+ * (X3.159-1989 p.82,L3).
+ */
+void unixlibc_dummy_function( void )
+{
+}
+
+#endif
diff --git a/cpukit/libcsupport/src/unlink.c b/cpukit/libcsupport/src/unlink.c
new file mode 100644
index 0000000000..b4fb6cbab1
--- /dev/null
+++ b/cpukit/libcsupport/src/unlink.c
@@ -0,0 +1,83 @@
+/*
+ * unlink() - POSIX 1003.1b - 5.5.1 - Remove an existing link
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int unlink(
+ const char *path
+)
+{
+ rtems_filesystem_location_info_t loc;
+ int result;
+
+ /*
+ * Get the node to be unlinked.
+ */
+
+ result = rtems_filesystem_evaluate_path( path, 0, &loc, FALSE );
+ if ( result != 0 )
+ return -1;
+
+ result = rtems_filesystem_evaluate_parent(RTEMS_LIBIO_PERMS_WRITE, &loc );
+ if (result != 0 && errno != ENOTSUP) {
+ rtems_filesystem_freenode( &loc );
+ return -1;
+ }
+
+ if ( !loc.ops->node_type_h ) {
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ if ( (*loc.ops->node_type_h)( &loc ) == RTEMS_FILESYSTEM_DIRECTORY ) {
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( EISDIR );
+ }
+
+ if ( !loc.ops->unlink_h ) {
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ result = (*loc.ops->unlink_h)( &loc );
+
+ rtems_filesystem_freenode( &loc );
+
+ return result;
+}
+
+/*
+ * _unlink_r
+ *
+ * This is the Newlib dependent reentrant version of unlink().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _unlink_r(
+ struct _reent *ptr,
+ const char *path
+)
+{
+ return unlink( path );
+}
+#endif
diff --git a/cpukit/libcsupport/src/unmount.c b/cpukit/libcsupport/src/unmount.c
new file mode 100644
index 0000000000..f37d3f2e56
--- /dev/null
+++ b/cpukit/libcsupport/src/unmount.c
@@ -0,0 +1,219 @@
+/*
+ * unmount() - Unmount a File System
+ *
+ * This routine is not defined in the POSIX 1003.1b standard but
+ * in some form is supported on most UNIX and POSIX systems. This
+ * routine is necessary to mount instantiations of a file system
+ * into the file system name space.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <rtems/chain.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+/*
+ * Data structures and routines private to mount/unmount pair.
+ */
+
+extern Chain_Control rtems_filesystem_mount_table_control;
+
+int search_mt_for_mount_point(
+ rtems_filesystem_location_info_t *location_of_mount_point
+);
+
+rtems_boolean rtems_filesystem_nodes_equal(
+ const rtems_filesystem_location_info_t *loc1,
+ const rtems_filesystem_location_info_t *loc2
+){
+ return ( loc1->node_access == loc2->node_access );
+}
+
+
+/*
+ * file_systems_below_this_mountpoint
+ *
+ * This routine will run through the entries that currently exist in the
+ * mount table chain. For each entry in the mount table chain it will
+ * compare the mount tables mt_fs_root to the new_fs_root_node. If any of the
+ * mount table file system root nodes matches the new file system root node
+ * this indicates that we are trying to mount a file system that has already
+ * been mounted. This is not a permitted operation. temp_loc is set to
+ * the root node of the file system being unmounted.
+ */
+
+rtems_boolean file_systems_below_this_mountpoint(
+ const char *path,
+ rtems_filesystem_location_info_t *fs_root_loc,
+ rtems_filesystem_mount_table_entry_t *fs_to_unmount
+)
+{
+ Chain_Node *the_node;
+ rtems_filesystem_mount_table_entry_t *the_mount_entry;
+
+ /*
+ * Search the mount table for any mount entries referencing this
+ * mount entry.
+ */
+
+ for ( the_node = rtems_filesystem_mount_table_control.first;
+ !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
+ the_node = the_node->next ) {
+ the_mount_entry = ( rtems_filesystem_mount_table_entry_t * )the_node;
+ if (the_mount_entry->mt_point_node.mt_entry == fs_root_loc->mt_entry ) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/*
+ * unmount
+ *
+ * This routine will attempt to unmount the file system that has been
+ * is mounted a path. If the operation is successful, 0 will
+ * be returned to the calling routine. Otherwise, 1 will be returned.
+ */
+
+int unmount(
+ const char *path
+)
+{
+ rtems_filesystem_location_info_t loc;
+ rtems_filesystem_location_info_t *fs_root_loc;
+ rtems_filesystem_location_info_t *fs_mount_loc;
+ rtems_filesystem_mount_table_entry_t *mt_entry;
+
+ /*
+ * Get
+ * The root node of the mounted filesytem.
+ * The node for the directory that the fileystem is mounted on.
+ * The mount entry that is being refered to.
+ */
+
+ if ( rtems_filesystem_evaluate_path( path, 0x0, &loc, TRUE ) )
+ return -1;
+
+ mt_entry = loc.mt_entry;
+ fs_mount_loc = &mt_entry->mt_point_node;
+ fs_root_loc = &mt_entry->mt_fs_root;
+
+ /*
+ * Verify this is the root node for the file system to be unmounted.
+ */
+
+ if ( !rtems_filesystem_nodes_equal( fs_root_loc, &loc) ){
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( EACCES );
+ }
+
+ /*
+ * Free the loc node and just use the nodes from the mt_entry .
+ */
+
+ rtems_filesystem_freenode( &loc );
+
+ /*
+ * Verify Unmount is supported by both filesystems.
+ */
+
+ if ( !fs_mount_loc->ops->unmount_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ if ( !fs_root_loc->ops->fsunmount_me_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+
+ /*
+ * Verify the current node is not in this filesystem.
+ * XXX - Joel I have a question here wasn't code added
+ * that made the current node thread based instead
+ * of system based? I thought it was but it doesn't
+ * look like it in this version.
+ */
+
+ if ( rtems_filesystem_current.mt_entry == mt_entry )
+ rtems_set_errno_and_return_minus_one( EBUSY );
+
+ /*
+ * Verify there are no file systems below the path specified
+ */
+
+ if ( file_systems_below_this_mountpoint( path, fs_root_loc, mt_entry ) != 0 )
+ rtems_set_errno_and_return_minus_one( EBUSY );
+
+ /*
+ * Run the file descriptor table to determine if there are any file
+ * descriptors that are currently active and reference nodes in the
+ * file system that we are trying to unmount
+ */
+
+ if ( rtems_libio_is_open_files_in_fs( mt_entry ) == 1 )
+ rtems_set_errno_and_return_minus_one( EBUSY );
+
+ /*
+ * Allow the file system being unmounted on to do its cleanup.
+ * If it fails it will set the errno to the approprate value
+ * and the fileystem will not be modified.
+ */
+
+ if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 )
+ return -1;
+
+ /*
+ * Allow the mounted filesystem to unmark the use of the root node.
+ *
+ * Run the unmount function for the subordinate file system.
+ *
+ * If we fail to unmount the filesystem remount it on the base filesystems
+ * directory node.
+ *
+ * NOTE: Fatal error is called in a case which should never happen
+ * This was response was questionable but the best we could
+ * come up with.
+ */
+
+ if ((fs_root_loc->ops->fsunmount_me_h )( mt_entry ) != 0){
+ if (( fs_mount_loc->ops->mount_h )( mt_entry ) != 0 )
+ rtems_fatal_error_occurred( 0 );
+ return -1;
+ }
+
+ /*
+ * Extract the mount table entry from the chain
+ */
+
+ Chain_Extract( ( Chain_Node * ) mt_entry );
+
+ /*
+ * Free the memory node that was allocated in mount
+ * Free the memory associated with the extracted mount table entry.
+ */
+
+ rtems_filesystem_freenode( fs_mount_loc );
+ free( mt_entry );
+
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/utime.c b/cpukit/libcsupport/src/utime.c
new file mode 100644
index 0000000000..3af884a5bb
--- /dev/null
+++ b/cpukit/libcsupport/src/utime.c
@@ -0,0 +1,46 @@
+/*
+ * utime() - POSIX 1003.1b 5.5.6 - Set File Access and Modification Times
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <utime.h>
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int utime(
+ const char *path,
+ const struct utimbuf *times
+)
+{
+ rtems_filesystem_location_info_t temp_loc;
+ int result;
+
+ if ( rtems_filesystem_evaluate_path( path, 0x00, &temp_loc, TRUE ) )
+ return -1;
+
+ if ( !temp_loc.ops->utime_h ){
+ rtems_filesystem_freenode( &temp_loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ result = (*temp_loc.ops->utime_h)( &temp_loc, times->actime, times->modtime );
+
+ rtems_filesystem_freenode( &temp_loc );
+
+ return result;
+}
diff --git a/cpukit/libcsupport/src/utsname.c b/cpukit/libcsupport/src/utsname.c
new file mode 100644
index 0000000000..6ba6c196c0
--- /dev/null
+++ b/cpukit/libcsupport/src/utsname.c
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include <errno.h>
+#include <sys/utsname.h>
+
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <inttypes.h>
+
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 4.4.1 Get System Name, P1003.1b-1993, p. 90
+ */
+
+int uname(
+ struct utsname *name
+)
+{
+ /* XXX: Here is what Solaris returns...
+ sysname = SunOS
+ nodename = node_name
+ release = 5.3
+ version = Generic_101318-12
+ machine = sun4m
+ */
+
+ if ( !name )
+ rtems_set_errno_and_return_minus_one( EFAULT );
+
+ strcpy( name->sysname, "RTEMS" );
+
+ sprintf( name->nodename, "Node %" PRId32, _Objects_Local_node );
+
+ strcpy( name->release, RTEMS_VERSION );
+
+ strcpy( name->version, "" );
+
+ sprintf( name->machine, "%s/%s", CPU_NAME, CPU_MODEL_NAME );
+
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/write.c b/cpukit/libcsupport/src/write.c
new file mode 100644
index 0000000000..4e08918ffb
--- /dev/null
+++ b/cpukit/libcsupport/src/write.c
@@ -0,0 +1,78 @@
+/*
+ * write() - POSIX 1003.1b 6.4.2 - Write to a File
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+/*
+ * write
+ *
+ * This routine writes count bytes from from buffer pointed to by buffer
+ * to the file associated with the open file descriptor, fildes.
+ */
+
+ssize_t write(
+ int fd,
+ const void *buffer,
+ size_t count
+)
+{
+ ssize_t rc;
+ rtems_libio_t *iop;
+
+ rtems_libio_check_fd( fd );
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_is_open(iop);
+ rtems_libio_check_buffer( buffer );
+ rtems_libio_check_count( count );
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
+
+ /*
+ * Now process the write() request.
+ */
+
+ if ( !iop->handlers->write_h )
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+ rc = (*iop->handlers->write_h)( iop, buffer, count );
+
+ if ( rc > 0 )
+ iop->offset += rc;
+
+ return rc;
+}
+
+/*
+ * _write_r
+ *
+ * This is the Newlib dependent reentrant version of write().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+_ssize_t _write_r(
+ struct _reent *ptr,
+ int fd,
+ const void *buf,
+ size_t nbytes
+)
+{
+ return write( fd, buf, nbytes );
+}
+#endif
diff --git a/cpukit/libfs/.cvsignore b/cpukit/libfs/.cvsignore
new file mode 100644
index 0000000000..b52c5e8c77
--- /dev/null
+++ b/cpukit/libfs/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+Makefile.in
+stamp-h*
diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am
new file mode 100644
index 0000000000..f49186b18a
--- /dev/null
+++ b/cpukit/libfs/Makefile.am
@@ -0,0 +1,56 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+EXTRA_DIST = README
+
+noinst_LIBRARIES = libimfs.a
+
+libimfs_a_SOURCES =
+
+if UNIX
+libimfs_a_SOURCES += src/imfs/imfs_unixstub.c
+else
+libimfs_a_SOURCES += src/imfs/imfs_chown.c src/imfs/imfs_config.c \
+ src/imfs/imfs_creat.c src/imfs/imfs_directory.c src/imfs/imfs_eval.c \
+ src/imfs/imfs_free.c src/imfs/imfs_fsunmount.c src/imfs/imfs_gtkn.c \
+ src/imfs/imfs_init.c src/imfs/imfs_initsupp.c src/imfs/imfs_link.c \
+ src/imfs/imfs_mknod.c src/imfs/imfs_mount.c src/imfs/imfs_fchmod.c \
+ src/imfs/imfs_unlink.c src/imfs/imfs_unmount.c src/imfs/imfs_utime.c \
+ src/imfs/imfs_ntype.c src/imfs/imfs_stat.c src/imfs/imfs_getchild.c \
+ src/imfs/memfile.c src/imfs/deviceio.c \
+ src/imfs/imfs_handlers_device.c src/imfs/imfs_handlers_directory.c \
+ src/imfs/imfs_handlers_link.c src/imfs/imfs_handlers_memfile.c \
+ src/imfs/imfs_debug.c src/imfs/imfs_rmnod.c src/imfs/imfs_symlink.c \
+ src/imfs/imfs_readlink.c src/imfs/imfs_fdatasync.c src/imfs/imfs_fcntl.c \
+ src/imfs/ioman.c src/imfs/miniimfs_init.c src/imfs/imfs_load_tar.c \
+ src/imfs/imfs.h
+endif
+
+# dosfs
+
+if !UNIX
+noinst_LIBRARIES += libdosfs.a
+
+# libdosfs_FATFS_C_FILES
+libdosfs_a_SOURCES = src/dosfs/fat.c src/dosfs/fat.h \
+ src/dosfs/fat_fat_operations.c src/dosfs/fat_fat_operations.h \
+ src/dosfs/fat_file.c src/dosfs/fat_file.h
+
+# libdosfs_DOSFS_C_FILES
+libdosfs_a_SOURCES += src/dosfs/msdos_create.c src/dosfs/msdos_dir.c \
+ src/dosfs/msdos_eval.c src/dosfs/msdos_file.c src/dosfs/msdos_free.c \
+ src/dosfs/msdos_fsunmount.c src/dosfs/msdos_handlers_dir.c \
+ src/dosfs/msdos_handlers_file.c src/dosfs/msdos_init.c \
+ src/dosfs/msdos_initsupp.c src/dosfs/msdos_misc.c \
+ src/dosfs/msdos_mknod.c src/dosfs/msdos_node_type.c \
+ src/dosfs/msdos_conv.c src/dosfs/msdos.h src/dosfs/msdos_format.c \
+ src/dosfs/dosfs.h
+endif
+
+# ---
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/libfs/README b/cpukit/libfs/README
new file mode 100644
index 0000000000..7409b93dca
--- /dev/null
+++ b/cpukit/libfs/README
@@ -0,0 +1,13 @@
+#
+# $Id$
+#
+
+This directory contains for the "file system" library. All supported
+file systems live under this tree.
+
+Currently the only supported file systems in this library are the IMFS
+and miniIMFS. The TFTP client filesystem is part of the libnetworking
+library.
+
+--Chris Johns and Joel Sherrill
+18 October 2000
diff --git a/cpukit/libfs/preinstall.am b/cpukit/libfs/preinstall.am
new file mode 100644
index 0000000000..dba6cc4d81
--- /dev/null
+++ b/cpukit/libfs/preinstall.am
@@ -0,0 +1,7 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
diff --git a/cpukit/libfs/src/dosfs/.cvsignore b/cpukit/libfs/src/dosfs/.cvsignore
new file mode 100644
index 0000000000..4b0640c9c5
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/.cvsignore
@@ -0,0 +1,4 @@
+config.h
+config.h.in
+stamp-h
+stamp-h.in
diff --git a/cpukit/libfs/src/dosfs/dosfs.h b/cpukit/libfs/src/dosfs/dosfs.h
new file mode 100644
index 0000000000..72353a2b7f
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/dosfs.h
@@ -0,0 +1,81 @@
+/**
+ * @file rtems/dosfs.h
+ *
+ * Application interface to MSDOS filesystem.
+ */
+
+/*
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#ifndef _RTEMS_DOSFS_H
+#define _RTEMS_DOSFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h>
+
+extern rtems_filesystem_operations_table msdos_ops;
+
+#define MSDOS_FMT_FATANY 0
+#define MSDOS_FMT_FAT12 1
+#define MSDOS_FMT_FAT16 2
+#define MSDOS_FMT_FAT32 3
+
+/*
+ * data to be filled out for formatter: parameters for format call
+ * any parameter set to 0 or NULL will be automatically detected/computed
+ */
+typedef struct {
+ const char *OEMName; /* OEM Name string or NULL */
+ const char *VolLabel; /* Volume Label string or NULL */
+ uint32_t sectors_per_cluster; /* request value: sectors per cluster */
+ uint32_t fat_num; /* request value: number of FATs on disk */
+ uint32_t files_per_root_dir; /* request value: file entries in root */
+ uint8_t fattype; /* request value: MSDOS_FMT_FAT12/16/32 */
+ uint8_t media; /* media code. default: 0xF8 */
+ boolean quick_format; /* TRUE: do not clear out data sectors */
+ uint32_t cluster_align; /* requested value: cluster alignment */
+ /* make sector number of first sector */
+ /* of first cluster divisible by this */
+ /* value. This can optimize clusters */
+ /* to be located at start of track */
+ /* or start of flash block */
+} msdos_format_request_param_t;
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int msdos_format
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| format device with msdos filesystem |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ const char *devname, /* device name */
+ const msdos_format_request_param_t *rqdata /* requested fmt parameters */
+ /* set to NULL for automatic */
+ /* determination */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libfs/src/dosfs/fat.c b/cpukit/libfs/src/dosfs/fat.c
new file mode 100644
index 0000000000..aa390d64cb
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/fat.c
@@ -0,0 +1,708 @@
+/*
+ * fat.c
+ *
+ * Low-level operations on a volume with FAT filesystem
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+
+/* _fat_block_read --
+ * This function reads 'count' bytes from device filesystem is mounted on,
+ * starts at 'start+offset' position where 'start' computed in sectors
+ * and 'offset' is offset inside sector (reading may cross sectors
+ * boundary; in this case assumed we want to read sequential sector(s))
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * start - sector num to start read from
+ * offset - offset inside sector 'start'
+ * count - count of bytes to read
+ * buff - buffer provided by user
+ *
+ * RETURNS:
+ * bytes read on success, or -1 if error occured
+ * and errno set appropriately
+ */
+ssize_t
+_fat_block_read(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t start,
+ uint32_t offset,
+ uint32_t count,
+ void *buff
+ )
+{
+ int rc = RC_OK;
+ register fat_fs_info_t *fs_info = mt_entry->fs_info;
+ ssize_t cmpltd = 0;
+ uint32_t blk = start;
+ uint32_t ofs = offset;
+ bdbuf_buffer *block = NULL;
+ uint32_t c = 0;
+
+ while (count > 0)
+ {
+ rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_READ, &block);
+ if (rc != RC_OK)
+ return -1;
+
+ c = MIN(count, (fs_info->vol.bps - ofs));
+ memcpy((buff + cmpltd), (block->buffer + ofs), c);
+
+ count -= c;
+ cmpltd += c;
+ blk++;
+ ofs = 0;
+ }
+ return cmpltd;
+}
+
+/* _fat_block_write --
+ * This function write 'count' bytes to device filesystem is mounted on,
+ * starts at 'start+offset' position where 'start' computed in sectors
+ * and 'offset' is offset inside sector (writing may cross sectors
+ * boundary; in this case assumed we want to write sequential sector(s))
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * start - sector num to start read from
+ * offset - offset inside sector 'start'
+ * count - count of bytes to write
+ * buff - buffer provided by user
+ *
+ * RETURNS:
+ * bytes written on success, or -1 if error occured
+ * and errno set appropriately
+ */
+ssize_t
+_fat_block_write(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t start,
+ uint32_t offset,
+ uint32_t count,
+ const void *buff)
+{
+ int rc = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ ssize_t cmpltd = 0;
+ uint32_t blk = start;
+ uint32_t ofs = offset;
+ bdbuf_buffer *block = NULL;
+ uint32_t c = 0;
+
+ while(count > 0)
+ {
+ c = MIN(count, (fs_info->vol.bps - ofs));
+
+ if (c == fs_info->vol.bps)
+ rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_GET, &block);
+ else
+ rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_READ, &block);
+ if (rc != RC_OK)
+ return -1;
+
+ memcpy((block->buffer + ofs), (buff + cmpltd), c);
+
+ fat_buf_mark_modified(fs_info);
+
+ count -= c;
+ cmpltd +=c;
+ blk++;
+ ofs = 0;
+ }
+ return cmpltd;
+}
+
+
+
+
+/* fat_cluster_read --
+ * wrapper for reading a whole cluster at once
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * cln - number of cluster to read
+ * buff - buffer provided by user
+ *
+ * RETURNS:
+ * bytes read on success, or -1 if error occured
+ * and errno set appropriately
+ */
+ssize_t
+fat_cluster_read(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ void *buff
+ )
+{
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t fsec = 0;
+
+ fsec = fat_cluster_num_to_sector_num(mt_entry, cln);
+
+ return _fat_block_read(mt_entry, fsec, 0,
+ fs_info->vol.spc << fs_info->vol.sec_log2, buff);
+}
+
+/* fat_cluster_write --
+ * wrapper for writting a whole cluster at once
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * cln - number of cluster to write
+ * buff - buffer provided by user
+ *
+ * RETURNS:
+ * bytes written on success, or -1 if error occured
+ * and errno set appropriately
+ */
+ssize_t
+fat_cluster_write(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ const void *buff
+ )
+{
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t fsec = 0;
+
+ fsec = fat_cluster_num_to_sector_num(mt_entry, cln);
+
+ return _fat_block_write(mt_entry, fsec, 0,
+ fs_info->vol.spc << fs_info->vol.sec_log2, buff);
+}
+
+/* fat_init_volume_info --
+ * Get inforamtion about volume on which filesystem is mounted on
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured
+ * and errno set appropriately
+ */
+int
+fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
+{
+ int rc = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ register fat_vol_t *vol = &fs_info->vol;
+ uint32_t data_secs = 0;
+ char boot_rec[FAT_MAX_BPB_SIZE];
+ char fs_info_sector[FAT_USEFUL_INFO_SIZE];
+ ssize_t ret = 0;
+ int fd;
+ struct stat stat_buf;
+ int i = 0;
+
+ rc = stat(mt_entry->dev, &stat_buf);
+ if (rc == -1)
+ return rc;
+
+ /* rtmes feature: no block devices, all are character devices */
+ if (!S_ISCHR(stat_buf.st_mode))
+ set_errno_and_return_minus_one(ENOTBLK);
+
+ /* check that device is registred as block device and lock it */
+ vol->dd = rtems_disk_lookup(stat_buf.st_dev);
+ if (vol->dd == NULL)
+ set_errno_and_return_minus_one(ENOTBLK);
+
+ vol->dev = stat_buf.st_dev;
+
+ fd = open(mt_entry->dev, O_RDONLY);
+ if (fd == -1)
+ {
+ rtems_disk_release(vol->dd);
+ return -1;
+ }
+
+ ret = read(fd, (void *)boot_rec, FAT_MAX_BPB_SIZE);
+ if ( ret != FAT_MAX_BPB_SIZE )
+ {
+ close(fd);
+ rtems_disk_release(vol->dd);
+ set_errno_and_return_minus_one( EIO );
+ }
+ close(fd);
+
+ vol->bps = FAT_GET_BR_BYTES_PER_SECTOR(boot_rec);
+
+ if ( (vol->bps != 512) &&
+ (vol->bps != 1024) &&
+ (vol->bps != 2048) &&
+ (vol->bps != 4096))
+ {
+ rtems_disk_release(vol->dd);
+ set_errno_and_return_minus_one( EINVAL );
+ }
+
+ for (vol->sec_mul = 0, i = (vol->bps >> FAT_SECTOR512_BITS); (i & 1) == 0;
+ i >>= 1, vol->sec_mul++);
+ for (vol->sec_log2 = 0, i = vol->bps; (i & 1) == 0;
+ i >>= 1, vol->sec_log2++);
+
+ vol->spc = FAT_GET_BR_SECTORS_PER_CLUSTER(boot_rec);
+ /*
+ * "sectors per cluster" of zero is invalid
+ * (and would hang the following loop)
+ */
+ if (vol->spc == 0)
+ {
+ rtems_disk_release(vol->dd);
+ set_errno_and_return_minus_one(EINVAL);
+ }
+
+ for (vol->spc_log2 = 0, i = vol->spc; (i & 1) == 0;
+ i >>= 1, vol->spc_log2++);
+
+ /*
+ * "bytes per cluster" value greater than 32K is invalid
+ */
+ if ((vol->bpc = vol->bps << vol->spc_log2) > MS_BYTES_PER_CLUSTER_LIMIT)
+ {
+ rtems_disk_release(vol->dd);
+ set_errno_and_return_minus_one(EINVAL);
+ }
+
+ for (vol->bpc_log2 = 0, i = vol->bpc; (i & 1) == 0;
+ i >>= 1, vol->bpc_log2++);
+
+ vol->fats = FAT_GET_BR_FAT_NUM(boot_rec);
+ vol->fat_loc = FAT_GET_BR_RESERVED_SECTORS_NUM(boot_rec);
+
+ vol->rdir_entrs = FAT_GET_BR_FILES_PER_ROOT_DIR(boot_rec);
+
+ /* calculate the count of sectors occupied by the root directory */
+ vol->rdir_secs = ((vol->rdir_entrs * FAT_DIRENTRY_SIZE) + (vol->bps - 1)) /
+ vol->bps;
+
+ vol->rdir_size = vol->rdir_secs << vol->sec_log2;
+
+ if ( (FAT_GET_BR_SECTORS_PER_FAT(boot_rec)) != 0)
+ vol->fat_length = FAT_GET_BR_SECTORS_PER_FAT(boot_rec);
+ else
+ vol->fat_length = FAT_GET_BR_SECTORS_PER_FAT32(boot_rec);
+
+ vol->data_fsec = vol->fat_loc + vol->fats * vol->fat_length +
+ vol->rdir_secs;
+
+ /* for FAT12/16 root dir starts at(sector) */
+ vol->rdir_loc = vol->fat_loc + vol->fats * vol->fat_length;
+
+ if ( (FAT_GET_BR_TOTAL_SECTORS_NUM16(boot_rec)) != 0)
+ vol->tot_secs = FAT_GET_BR_TOTAL_SECTORS_NUM16(boot_rec);
+ else
+ vol->tot_secs = FAT_GET_BR_TOTAL_SECTORS_NUM32(boot_rec);
+
+ data_secs = vol->tot_secs - vol->data_fsec;
+
+ vol->data_cls = data_secs / vol->spc;
+
+ /* determine FAT type at least */
+ if ( vol->data_cls < FAT_FAT12_MAX_CLN)
+ {
+ vol->type = FAT_FAT12;
+ vol->mask = FAT_FAT12_MASK;
+ vol->eoc_val = FAT_FAT12_EOC;
+ }
+ else
+ {
+ if ( vol->data_cls < FAT_FAT16_MAX_CLN)
+ {
+ vol->type = FAT_FAT16;
+ vol->mask = FAT_FAT16_MASK;
+ vol->eoc_val = FAT_FAT16_EOC;
+ }
+ else
+ {
+ vol->type = FAT_FAT32;
+ vol->mask = FAT_FAT32_MASK;
+ vol->eoc_val = FAT_FAT32_EOC;
+ }
+ }
+
+ if (vol->type == FAT_FAT32)
+ {
+ vol->rdir_cl = FAT_GET_BR_FAT32_ROOT_CLUSTER(boot_rec);
+
+ vol->mirror = FAT_GET_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_MIRROR;
+ if (vol->mirror)
+ vol->afat = FAT_GET_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_FAT_NUM;
+ else
+ vol->afat = 0;
+
+ vol->info_sec = FAT_GET_BR_FAT32_FS_INFO_SECTOR(boot_rec);
+ if( vol->info_sec == 0 )
+ {
+ rtems_disk_release(vol->dd);
+ set_errno_and_return_minus_one( EINVAL );
+ }
+ else
+ {
+ ret = _fat_block_read(mt_entry, vol->info_sec , 0,
+ FAT_FSI_LEADSIG_SIZE, fs_info_sector);
+ if ( ret < 0 )
+ {
+ rtems_disk_release(vol->dd);
+ return -1;
+ }
+
+ if (FAT_GET_FSINFO_LEAD_SIGNATURE(fs_info_sector) !=
+ FAT_FSINFO_LEAD_SIGNATURE_VALUE)
+ {
+ rtems_disk_release(vol->dd);
+ set_errno_and_return_minus_one( EINVAL );
+ }
+ else
+ {
+ ret = _fat_block_read(mt_entry, vol->info_sec , FAT_FSI_INFO,
+ FAT_USEFUL_INFO_SIZE, fs_info_sector);
+ if ( ret < 0 )
+ {
+ rtems_disk_release(vol->dd);
+ return -1;
+ }
+
+ vol->free_cls = FAT_GET_FSINFO_FREE_CLUSTER_COUNT(fs_info_sector);
+ vol->next_cl = FAT_GET_FSINFO_NEXT_FREE_CLUSTER(fs_info_sector);
+ rc = fat_fat32_update_fsinfo_sector(mt_entry, 0xFFFFFFFF,
+ 0xFFFFFFFF);
+ if ( rc != RC_OK )
+ {
+ rtems_disk_release(vol->dd);
+ return rc;
+ }
+ }
+ }
+ }
+ else
+ {
+ vol->rdir_cl = 0;
+ vol->mirror = 0;
+ vol->afat = 0;
+ vol->free_cls = 0xFFFFFFFF;
+ vol->next_cl = 0xFFFFFFFF;
+ }
+ vol->afat_loc = vol->fat_loc + vol->fat_length * vol->afat;
+
+ /* set up collection of fat-files fd */
+ fs_info->vhash = calloc(FAT_HASH_SIZE, sizeof(Chain_Control));
+ if ( fs_info->vhash == NULL )
+ {
+ rtems_disk_release(vol->dd);
+ set_errno_and_return_minus_one( ENOMEM );
+ }
+
+ for (i = 0; i < FAT_HASH_SIZE; i++)
+ _Chain_Initialize_empty(fs_info->vhash + i);
+
+ fs_info->rhash = calloc(FAT_HASH_SIZE, sizeof(Chain_Control));
+ if ( fs_info->rhash == NULL )
+ {
+ rtems_disk_release(vol->dd);
+ free(fs_info->vhash);
+ set_errno_and_return_minus_one( ENOMEM );
+ }
+ for (i = 0; i < FAT_HASH_SIZE; i++)
+ _Chain_Initialize_empty(fs_info->rhash + i);
+
+ fs_info->uino_pool_size = FAT_UINO_POOL_INIT_SIZE;
+ fs_info->uino_base = (vol->tot_secs << vol->sec_mul) << 4;
+ fs_info->index = 0;
+ fs_info->uino = (char *)calloc(fs_info->uino_pool_size, sizeof(char));
+ if ( fs_info->uino == NULL )
+ {
+ rtems_disk_release(vol->dd);
+ free(fs_info->vhash);
+ free(fs_info->rhash);
+ set_errno_and_return_minus_one( ENOMEM );
+ }
+ fs_info->sec_buf = (uint8_t *)calloc(vol->bps, sizeof(uint8_t));
+ if (fs_info->sec_buf == NULL)
+ {
+ rtems_disk_release(vol->dd);
+ free(fs_info->vhash);
+ free(fs_info->rhash);
+ free(fs_info->uino);
+ set_errno_and_return_minus_one( ENOMEM );
+ }
+
+ return RC_OK;
+}
+
+/* fat_shutdown_drive --
+ * Free all allocated resources and synchronize all necessary data
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured
+ * and errno set appropriately
+ */
+int
+fat_shutdown_drive(rtems_filesystem_mount_table_entry_t *mt_entry)
+{
+ int rc = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ int i = 0;
+
+ if (fs_info->vol.type & FAT_FAT32)
+ {
+ rc = fat_fat32_update_fsinfo_sector(mt_entry, fs_info->vol.free_cls,
+ fs_info->vol.next_cl);
+ if ( rc != RC_OK )
+ rc = -1;
+ }
+
+ fat_buf_release(fs_info);
+
+ if (rtems_bdbuf_syncdev(fs_info->vol.dev) != RTEMS_SUCCESSFUL)
+ rc = -1;
+
+ for (i = 0; i < FAT_HASH_SIZE; i++)
+ {
+ Chain_Node *node = NULL;
+ Chain_Control *the_chain = fs_info->vhash + i;
+
+ while ( (node = _Chain_Get(the_chain)) != NULL )
+ free(node);
+ }
+
+ for (i = 0; i < FAT_HASH_SIZE; i++)
+ {
+ Chain_Node *node = NULL;
+ Chain_Control *the_chain = fs_info->rhash + i;
+
+ while ( (node = _Chain_Get(the_chain)) != NULL )
+ free(node);
+ }
+
+ free(fs_info->vhash);
+ free(fs_info->rhash);
+
+ free(fs_info->uino);
+ free(fs_info->sec_buf);
+ rtems_disk_release(fs_info->vol.dd);
+
+ if (rc)
+ errno = EIO;
+ return rc;
+}
+
+/* fat_init_clusters_chain --
+ * Zeroing contents of all clusters in the chain
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * start_cluster_num - num of first cluster in the chain
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured
+ * and errno set appropriately
+ */
+int
+fat_init_clusters_chain(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t start_cln
+ )
+{
+ int rc = RC_OK;
+ ssize_t ret = 0;
+ register fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t cur_cln = start_cln;
+ char *buf;
+
+ buf = calloc(fs_info->vol.bpc, sizeof(char));
+ if ( buf == NULL )
+ set_errno_and_return_minus_one( EIO );
+
+ while ((cur_cln & fs_info->vol.mask) < fs_info->vol.eoc_val)
+ {
+ ret = fat_cluster_write(mt_entry, cur_cln, buf);
+ if ( ret == -1 )
+ {
+ free(buf);
+ return -1;
+ }
+
+ rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln);
+ if ( rc != RC_OK )
+ {
+ free(buf);
+ return rc;
+ }
+
+ }
+ free(buf);
+ return rc;
+}
+
+#define FAT_UNIQ_INO_BASE 0x0FFFFF00
+
+#define FAT_UNIQ_INO_IS_BUSY(index, arr) \
+ (((arr)[((index)>>3)]>>((index) & (8-1))) & 0x01)
+
+#define FAT_SET_UNIQ_INO_BUSY(index, arr) \
+ ((arr)[((index)>>3)] |= (0x01<<((index) & (8-1))))
+
+#define FAT_SET_UNIQ_INO_FREE(index, arr) \
+ ((arr)[((index)>>3)] &= (~(0x01<<((index) & (8-1)))))
+
+/* fat_get_unique_ino --
+ * Allocate unique ino from unique ino pool
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ *
+ * RETURNS:
+ * unique inode number on success, or 0 if there is no free unique inode
+ * number in the pool
+ *
+ * ATTENTION:
+ * 0 means FAILED !!!
+ *
+ */
+uint32_t
+fat_get_unique_ino(rtems_filesystem_mount_table_entry_t *mt_entry)
+{
+ register fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t j = 0;
+ rtems_boolean resrc_unsuff = FALSE;
+
+ while (!resrc_unsuff)
+ {
+ for (j = 0; j < fs_info->uino_pool_size; j++)
+ {
+ if (!FAT_UNIQ_INO_IS_BUSY(fs_info->index, fs_info->uino))
+ {
+ FAT_SET_UNIQ_INO_BUSY(fs_info->index, fs_info->uino);
+ return (fs_info->uino_base + fs_info->index);
+ }
+ fs_info->index++;
+ if (fs_info->index >= fs_info->uino_pool_size)
+ fs_info->index = 0;
+ }
+
+ if ((fs_info->uino_pool_size << 1) < (0x0FFFFFFF - fs_info->uino_base))
+ {
+ fs_info->uino_pool_size <<= 1;
+ fs_info->uino = realloc(fs_info->uino, fs_info->uino_pool_size);
+ if (fs_info->uino != NULL)
+ fs_info->index = fs_info->uino_pool_size;
+ else
+ resrc_unsuff = TRUE;
+ }
+ else
+ resrc_unsuff = TRUE;
+ }
+ return 0;
+}
+
+/* fat_free_unique_ino --
+ * Return unique ino to unique ino pool
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * ino - inode number to free
+ *
+ * RETURNS:
+ * None
+ */
+void
+fat_free_unique_ino(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t ino
+ )
+{
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+
+ FAT_SET_UNIQ_INO_FREE((ino - fs_info->uino_base), fs_info->uino);
+}
+
+/* fat_ino_is_unique --
+ * Test whether ino is from unique ino pool
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * ino - ino to be tested
+ *
+ * RETURNS:
+ * TRUE if ino is allocated from unique ino pool, FALSE otherwise
+ */
+inline rtems_boolean
+fat_ino_is_unique(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t ino
+ )
+{
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+
+ return (ino >= fs_info->uino_base);
+}
+
+/* fat_fat32_update_fsinfo_sector --
+ * Synchronize fsinfo sector for FAT32 volumes
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * free_count - count of free clusters
+ * next_free - the next free cluster num
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set appropriately)
+ */
+int
+fat_fat32_update_fsinfo_sector(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t free_count,
+ uint32_t next_free
+ )
+{
+ ssize_t ret1 = 0, ret2 = 0;
+ register fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t le_free_count = 0;
+ uint32_t le_next_free = 0;
+
+ le_free_count = CT_LE_L(free_count);
+ le_next_free = CT_LE_L(next_free);
+
+ ret1 = _fat_block_write(mt_entry,
+ fs_info->vol.info_sec,
+ FAT_FSINFO_FREE_CLUSTER_COUNT_OFFSET,
+ 4,
+ (char *)(&le_free_count));
+
+ ret2 = _fat_block_write(mt_entry,
+ fs_info->vol.info_sec,
+ FAT_FSINFO_NEXT_FREE_CLUSTER_OFFSET,
+ 4,
+ (char *)(&le_next_free));
+
+ if ( (ret1 < 0) || (ret2 < 0) )
+ return -1;
+
+ return RC_OK;
+}
diff --git a/cpukit/libfs/src/dosfs/fat.h b/cpukit/libfs/src/dosfs/fat.h
new file mode 100644
index 0000000000..f4d1c60408
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/fat.h
@@ -0,0 +1,618 @@
+/*
+ * fat.h
+ *
+ * Constants/data structures/prototypes for low-level operations on a volume
+ * with FAT filesystem
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#ifndef __DOSFS_FAT_H__
+#define __DOSFS_FAT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+
+#include <rtems/seterr.h>
+
+/* XXX: temporary hack :(( */
+#ifndef set_errno_and_return_minus_one
+#define set_errno_and_return_minus_one rtems_set_errno_and_return_minus_one
+#endif /* set_errno_and_return_minus_one */
+
+#include <rtems/score/cpu.h>
+#include <errno.h>
+#include <rtems/bdbuf.h>
+
+#ifndef RC_OK
+#define RC_OK 0x00000000
+#endif
+
+/*
+ * Remember that all FAT file system on disk data structure is
+ * "little endian"!
+ * (derived from linux)
+ */
+/*
+ * Conversion from and to little-endian byte order. (no-op on i386/i486)
+ *
+ * Naming: Ca_b_c, where a: F = from, T = to, b: LE = little-endian,
+ * BE = big-endian, c: W = word (16 bits), L = longword (32 bits)
+ */
+
+#if (CPU_BIG_ENDIAN == TRUE)
+# define CF_LE_W(v) CPU_swap_u16((uint16_t)(v))
+# define CF_LE_L(v) CPU_swap_u32((uint32_t)(v))
+# define CT_LE_W(v) CPU_swap_u16((uint16_t)(v))
+# define CT_LE_L(v) CPU_swap_u32((uint32_t)(v))
+#else
+# define CF_LE_W(v) (v)
+# define CF_LE_L(v) (v)
+# define CT_LE_W(v) (v)
+# define CT_LE_L(v) (v)
+#endif
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+#define FAT_HASH_SIZE 2
+#define FAT_HASH_MODULE FAT_HASH_SIZE
+
+
+#define FAT_SECTOR512_SIZE 512 /* sector size (bytes) */
+#define FAT_SECTOR512_BITS 9 /* log2(SECTOR_SIZE) */
+
+/* maximum + 1 number of clusters for FAT12 */
+#define FAT_FAT12_MAX_CLN 4085
+
+/* maximum + 1 number of clusters for FAT16 */
+#define FAT_FAT16_MAX_CLN 65525
+
+#define FAT_FAT12 0x01
+#define FAT_FAT16 0x02
+#define FAT_FAT32 0x04
+
+#define FAT_UNDEFINED_VALUE (uint32_t )0xFFFFFFFF
+
+#define FAT_FAT12_EOC 0x0FF8
+#define FAT_FAT16_EOC 0xFFF8
+#define FAT_FAT32_EOC (uint32_t )0x0FFFFFF8
+
+#define FAT_FAT12_FREE 0x0000
+#define FAT_FAT16_FREE 0x0000
+#define FAT_FAT32_FREE 0x00000000
+
+#define FAT_GENFAT_EOC (uint32_t )0xFFFFFFFF
+#define FAT_GENFAT_FREE (uint32_t )0x00000000
+
+#define FAT_FAT12_SHIFT 0x04
+
+#define FAT_FAT12_MASK 0x00000FFF
+#define FAT_FAT16_MASK 0x0000FFFF
+#define FAT_FAT32_MASK (uint32_t )0x0FFFFFFF
+
+#define FAT_MAX_BPB_SIZE 90
+#define FAT_TOTAL_MBR_SIZE 512
+
+/* size of useful information in FSInfo sector */
+#define FAT_USEFUL_INFO_SIZE 12
+
+#define FAT_GET_ADDR(x, ofs) ((uint8_t *)(x) + (ofs))
+
+#define FAT_GET_VAL8(x, ofs) (uint8_t)(*((uint8_t *)(x) + (ofs)))
+
+#define FAT_GET_VAL16(x, ofs) \
+ (uint16_t)( (*((uint8_t *)(x) + (ofs))) | \
+ ((*((uint8_t *)(x) + (ofs) + 1)) << 8) )
+
+#define FAT_GET_VAL32(x, ofs) \
+ (uint32_t)( (uint32_t)(*((uint8_t *)(x) + (ofs))) | \
+ ((uint32_t)(*((uint8_t *)(x) + (ofs) + 1)) << 8) | \
+ ((uint32_t)(*((uint8_t *)(x) + (ofs) + 2)) << 16) | \
+ ((uint32_t)(*((uint8_t *)(x) + (ofs) + 3)) << 24) )
+
+#define FAT_SET_VAL8(x, ofs,val) \
+ (*((uint8_t *)(x)+(ofs))=(uint8_t)(val))
+
+#define FAT_SET_VAL16(x, ofs,val) do { \
+ FAT_SET_VAL8((x),(ofs),(val)); \
+ FAT_SET_VAL8((x),(ofs)+1,(val)>>8);\
+ } while (0)
+
+#define FAT_SET_VAL32(x, ofs,val) do { \
+ FAT_SET_VAL16((x),(ofs),(val)); \
+ FAT_SET_VAL16((x),(ofs)+2,(val)>>16);\
+ } while (0)
+
+/* macros to access boot sector fields */
+#define FAT_GET_BR_JMPBOOT(x) FAT_GET_VAL8( x, 0)
+#define FAT_SET_BR_JMPBOOT(x,val) FAT_SET_VAL8( x, 0,val)
+
+#define FAT_GET_ADDR_BR_OEMNAME(x) FAT_GET_ADDR( x, 3)
+#define FAT_BR_OEMNAME_SIZE (8)
+
+#define FAT_GET_BR_BYTES_PER_SECTOR(x) FAT_GET_VAL16(x, 11)
+#define FAT_SET_BR_BYTES_PER_SECTOR(x,val) FAT_SET_VAL16(x, 11,val)
+
+#define FAT_GET_BR_SECTORS_PER_CLUSTER(x) FAT_GET_VAL8( x, 13)
+#define FAT_SET_BR_SECTORS_PER_CLUSTER(x,val)FAT_SET_VAL8( x, 13,val)
+
+#define FAT_GET_BR_RESERVED_SECTORS_NUM(x) FAT_GET_VAL16(x, 14)
+#define FAT_SET_BR_RESERVED_SECTORS_NUM(x,val) FAT_SET_VAL16(x, 14,val)
+
+#define FAT_GET_BR_FAT_NUM(x) FAT_GET_VAL8( x, 16)
+#define FAT_SET_BR_FAT_NUM(x,val) FAT_SET_VAL8( x, 16,val)
+
+#define FAT_GET_BR_FILES_PER_ROOT_DIR(x) FAT_GET_VAL16(x, 17)
+#define FAT_SET_BR_FILES_PER_ROOT_DIR(x,val) FAT_SET_VAL16(x, 17,val)
+
+#define FAT_GET_BR_TOTAL_SECTORS_NUM16(x) FAT_GET_VAL16(x, 19)
+#define FAT_SET_BR_TOTAL_SECTORS_NUM16(x,val)FAT_SET_VAL16(x, 19,val)
+
+#define FAT_GET_BR_MEDIA(x) FAT_GET_VAL8( x, 21)
+#define FAT_SET_BR_MEDIA(x,val) FAT_SET_VAL8( x, 21,val)
+
+#define FAT_GET_BR_SECTORS_PER_FAT(x) FAT_GET_VAL16(x, 22)
+#define FAT_SET_BR_SECTORS_PER_FAT(x,val) FAT_SET_VAL16(x, 22,val)
+
+#define FAT_GET_BR_SECTORS_PER_TRACK(x) FAT_GET_VAL16(x, 24)
+#define FAT_SET_BR_SECTORS_PER_TRACK(x,val) FAT_SET_VAL16(x, 24,val)
+
+#define FAT_GET_BR_NUMBER_OF_HEADS(x) FAT_GET_VAL16(x, 26)
+#define FAT_SET_BR_NUMBER_OF_HEADS(x,val) FAT_SET_VAL16(x, 26,val)
+
+#define FAT_GET_BR_HIDDEN_SECTORS(x) FAT_GET_VAL32(x, 28)
+#define FAT_SET_BR_HIDDEN_SECTORS(x,val) FAT_SET_VAL32(x, 28,val)
+
+#define FAT_GET_BR_TOTAL_SECTORS_NUM32(x) FAT_GET_VAL32(x, 32)
+#define FAT_SET_BR_TOTAL_SECTORS_NUM32(x,val) FAT_SET_VAL32(x, 32,val)
+ /* --- start of FAT12/16 specific fields */
+#define FAT_GET_BR_DRVNUM(x) FAT_GET_VAL8( x, 36)
+#define FAT_SET_BR_DRVNUM(x,val) FAT_SET_VAL8( x, 36,val)
+
+#define FAT_GET_BR_RSVD1(x) FAT_GET_VAL8( x, 37)
+#define FAT_SET_BR_RSVD1(x,val) FAT_SET_VAL8( x, 37,val)
+
+#define FAT_GET_BR_BOOTSIG(x) FAT_GET_VAL8( x, 38)
+#define FAT_SET_BR_BOOTSIG(x,val) FAT_SET_VAL8( x, 38,val)
+#define FAT_BR_BOOTSIG_VAL (0x29)
+
+#define FAT_GET_BR_VOLID(x) FAT_GET_VAL32(x, 39)
+#define FAT_SET_BR_VOLID(x,val) FAT_SET_VAL32(x, 39,val)
+
+#define FAT_GET_ADDR_BR_VOLLAB(x) FAT_GET_ADDR (x, 43)
+#define FAT_BR_VOLLAB_SIZE (11)
+
+#define FAT_GET_ADDR_BR_FILSYSTYPE(x) FAT_GET_ADDR (x, 54)
+#define FAT_BR_FILSYSTYPE_SIZE (8)
+ /* --- end of FAT12/16 specific fields */
+ /* --- start of FAT32 specific fields */
+#define FAT_GET_BR_SECTORS_PER_FAT32(x) FAT_GET_VAL32(x, 36)
+#define FAT_SET_BR_SECTORS_PER_FAT32(x,val) FAT_SET_VAL32(x, 36,val)
+
+#define FAT_GET_BR_EXT_FLAGS(x) FAT_GET_VAL16(x, 40)
+#define FAT_SET_BR_EXT_FLAGS(x,val) FAT_SET_VAL16(x, 40,val)
+
+#define FAT_GET_BR_FSVER(x) FAT_GET_VAL16(x, 42)
+#define FAT_SET_BR_FSVER(x,val) FAT_SET_VAL16(x, 42,val)
+
+#define FAT_GET_BR_FAT32_ROOT_CLUSTER(x) FAT_GET_VAL32(x, 44)
+#define FAT_SET_BR_FAT32_ROOT_CLUSTER(x,val) FAT_SET_VAL32(x, 44,val)
+
+#define FAT_GET_BR_FAT32_FS_INFO_SECTOR(x) FAT_GET_VAL16(x, 48)
+#define FAT_SET_BR_FAT32_FS_INFO_SECTOR(x,val) FAT_SET_VAL16(x, 48,val)
+
+#define FAT_GET_BR_FAT32_BK_BOOT_SECTOR(x) FAT_GET_VAL16(x, 50)
+#define FAT_SET_BR_FAT32_BK_BOOT_SECTOR(x,val) FAT_SET_VAL16(x, 50,val)
+
+#define FAT_GET_ADDR_BR_FAT32_RESERVED(x) FAT_GET_ADDR (x, 52)
+#define FAT_BR_FAT32_RESERVED_SIZE (12)
+
+#define FAT_GET_BR_FAT32_DRVNUM(x) FAT_GET_VAL8( x, 64)
+#define FAT_SET_BR_FAT32_DRVNUM(x,val) FAT_SET_VAL8( x, 64,val)
+
+#define FAT_GET_BR_FAT32_RSVD1(x) FAT_GET_VAL8( x, 65)
+#define FAT_SET_BR_FAT32_RSVD1(x,val) FAT_SET_VAL8( x, 65,val)
+
+#define FAT_GET_BR_FAT32_BOOTSIG(x) FAT_GET_VAL8( x, 66)
+#define FAT_SET_BR_FAT32_BOOTSIG(x,val) FAT_SET_VAL8( x, 66,val)
+#define FAT_BR_FAT32_BOOTSIG_VAL (0x29)
+
+#define FAT_GET_BR_FAT32_VOLID(x) FAT_GET_VAL32(x, 67)
+#define FAT_SET_BR_FAT32_VOLID(x,val) FAT_SET_VAL32(x, 67,val)
+
+#define FAT_GET_ADDR_BR_FAT32_VOLLAB(x) FAT_GET_ADDR (x, 71)
+#define FAT_BR_FAT32_VOLLAB_SIZE (11)
+
+#define FAT_GET_ADDR_BR_FAT32_FILSYSTYPE(x) FAT_GET_ADDR (x, 82)
+#define FAT_BR_FAT32_FILSYSTYPE_SIZE (8)
+ /* --- end of FAT32 specific fields */
+
+#define FAT_GET_BR_SIGNATURE(x) FAT_GET_VAL16(x,510)
+#define FAT_SET_BR_SIGNATURE(x,val) FAT_SET_VAL16(x,510,val)
+#define FAT_BR_SIGNATURE_VAL (0xAA55)
+
+ /*
+ * FAT32 FSINFO description
+ */
+#define FAT_GET_FSINFO_LEAD_SIGNATURE(x) FAT_GET_VAL32(x, 0)
+#define FAT_SET_FSINFO_LEAD_SIGNATURE(x,val) FAT_SET_VAL32(x, 0,val)
+#define FAT_FSINFO_LEAD_SIGNATURE_VALUE (0x41615252)
+
+#define FAT_GET_FSINFO_STRUC_SIGNATURE(x) FAT_GET_VAL32(x,484)
+#define FAT_SET_FSINFO_STRUC_SIGNATURE(x,val) FAT_SET_VAL32(x,484,val)
+#define FAT_FSINFO_STRUC_SIGNATURE_VALUE (0x61417272)
+
+#define FAT_GET_FSINFO_TRAIL_SIGNATURE(x) FAT_GET_VAL32(x,508)
+#define FAT_SET_FSINFO_TRAIL_SIGNATURE(x,val) FAT_SET_VAL32(x,508,val)
+#define FAT_FSINFO_TRAIL_SIGNATURE_VALUE (0x000055AA)
+/*
+ * I read FSInfo sector from offset 484 to access the information, so offsets
+ * of these fields a relative
+ */
+#define FAT_GET_FSINFO_FREE_CLUSTER_COUNT(x) FAT_GET_VAL32(x, 4)
+#define FAT_SET_FSINFO_FREE_CLUSTER_COUNT(x,val) FAT_SET_VAL32(x, 4,val)
+#define FAT_GET_FSINFO_NEXT_FREE_CLUSTER(x) FAT_GET_VAL32(x, 8)
+#define FAT_SET_FSINFO_NEXT_FREE_CLUSTER(x,val) FAT_SET_VAL32(x, 8,val)
+
+#define FAT_FSI_INFO 484
+#define FAT_FSINFO_STRUCT_OFFSET 488
+#define FAT_FSINFO_FREE_CLUSTER_COUNT_OFFSET (FAT_FSINFO_STRUCT_OFFSET+0)
+
+#define FAT_FSINFO_NEXT_FREE_CLUSTER_OFFSET (FAT_FSINFO_STRUCT_OFFSET+4)
+
+#define FAT_RSRVD_CLN 0x02
+
+#define FAT_FSI_LEADSIG_SIZE 0x04
+
+#define FAT_TOTAL_FSINFO_SIZE 512
+
+#define MS_BYTES_PER_CLUSTER_LIMIT 0x8000 /* 32K */
+
+#define FAT_BR_EXT_FLAGS_MIRROR 0x0080
+
+#define FAT_BR_EXT_FLAGS_FAT_NUM 0x000F
+
+#define FAT_BR_MEDIA_FIXED 0xf8
+
+#define FAT_DIRENTRY_SIZE 32
+
+#define FAT_DIRENTRIES_PER_SEC512 16
+
+/*
+ * Volume descriptor
+ * Description of the volume the FAT filesystem is located on - generally
+ * the fields of the structure correspond to Boot Sector and BPB Structure
+ * fields
+ */
+typedef struct fat_vol_s
+{
+ uint16_t bps; /* bytes per sector */
+ uint8_t sec_log2; /* log2 of bps */
+ uint8_t sec_mul; /* log2 of 512bts sectors number per sector */
+ uint8_t spc; /* sectors per cluster */
+ uint8_t spc_log2; /* log2 of spc */
+ uint16_t bpc; /* bytes per cluster */
+ uint8_t bpc_log2; /* log2 of bytes per cluster */
+ uint8_t fats; /* number of FATs */
+ uint8_t type; /* FAT type */
+ uint32_t mask;
+ uint32_t eoc_val;
+ uint16_t fat_loc; /* FAT start */
+ uint32_t fat_length; /* sectors per FAT */
+ uint32_t rdir_loc; /* root directory start */
+ uint16_t rdir_entrs; /* files per root directory */
+ uint32_t rdir_secs; /* sectors per root directory */
+ uint32_t rdir_size; /* root directory size in bytes */
+ uint32_t tot_secs; /* total count of sectors */
+ uint32_t data_fsec; /* first data sector */
+ uint32_t data_cls; /* count of data clusters */
+ uint32_t rdir_cl; /* first cluster of the root directory */
+ uint16_t info_sec; /* FSInfo Sector Structure location */
+ uint32_t free_cls; /* last known free clusters count */
+ uint32_t next_cl; /* next free cluster number */
+ uint8_t mirror; /* mirroring enabla/disable */
+ uint32_t afat_loc; /* active FAT location */
+ uint8_t afat; /* the number of active FAT */
+ dev_t dev; /* device ID */
+ disk_device *dd; /* disk device (see libblock) */
+ void *private_data; /* reserved */
+} fat_vol_t;
+
+
+typedef struct fat_cache_s
+{
+ uint32_t blk_num;
+ rtems_boolean modified;
+ uint8_t state;
+ bdbuf_buffer *buf;
+} fat_cache_t;
+
+/*
+ * This structure identifies the instance of the filesystem on the FAT
+ * ("fat-file") level.
+ */
+typedef struct fat_fs_info_s
+{
+ fat_vol_t vol; /* volume descriptor */
+ Chain_Control *vhash; /* "vhash" of fat-file descriptors */
+ Chain_Control *rhash; /* "rhash" of fat-file descriptors */
+ char *uino; /* array of unique ino numbers */
+ uint32_t index;
+ uint32_t uino_pool_size; /* size */
+ uint32_t uino_base;
+ fat_cache_t c; /* cache */
+ uint8_t *sec_buf; /* just placeholder for anything */
+} fat_fs_info_t;
+
+/*
+ * if the name we looking for is file we store not only first data cluster
+ * number, but and cluster number and offset for directory entry for this
+ * name
+ */
+typedef struct fat_auxiliary_s
+{
+ uint32_t cln;
+ uint32_t ofs;
+} fat_auxiliary_t;
+
+#define FAT_FAT_OFFSET(fat_type, cln) \
+ ((fat_type) & FAT_FAT12 ? ((cln) + ((cln) >> 1)) : \
+ (fat_type) & FAT_FAT16 ? ((cln) << 1) : \
+ ((cln) << 2))
+
+#define FAT_CLUSTER_IS_ODD(n) ((n) & 0x0001)
+
+#define FAT12_SHIFT 0x4 /* half of a byte */
+
+/* initial size of array of unique ino */
+#define FAT_UINO_POOL_INIT_SIZE 0x100
+
+/* cache support */
+#define FAT_CACHE_EMPTY 0x0
+#define FAT_CACHE_ACTUAL 0x1
+
+#define FAT_OP_TYPE_READ 0x1
+#define FAT_OP_TYPE_GET 0x2
+
+static inline uint32_t
+fat_cluster_num_to_sector_num(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln
+ )
+{
+ register fat_fs_info_t *fs_info = mt_entry->fs_info;
+
+ if ( (cln == 0) && (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)) )
+ return fs_info->vol.rdir_loc;
+
+ return (((cln - FAT_RSRVD_CLN) << fs_info->vol.spc_log2) +
+ fs_info->vol.data_fsec);
+}
+
+static inline uint32_t
+fat_cluster_num_to_sector512_num(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln
+ )
+{
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+
+ if (cln == 1)
+ return 1;
+
+ return (fat_cluster_num_to_sector_num(mt_entry, cln) <<
+ fs_info->vol.sec_mul);
+}
+
+static inline int
+fat_buf_access(fat_fs_info_t *fs_info, uint32_t blk, int op_type,
+ bdbuf_buffer **buf)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ uint8_t i;
+ rtems_boolean sec_of_fat;
+
+
+ if (fs_info->c.state == FAT_CACHE_EMPTY)
+ {
+ if (op_type == FAT_OP_TYPE_READ)
+ sc = rtems_bdbuf_read(fs_info->vol.dev, blk, &fs_info->c.buf);
+ else
+ sc = rtems_bdbuf_get(fs_info->vol.dev, blk, &fs_info->c.buf);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+ fs_info->c.blk_num = blk;
+ fs_info->c.modified = 0;
+ fs_info->c.state = FAT_CACHE_ACTUAL;
+ }
+
+ sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) &&
+ (fs_info->c.blk_num < fs_info->vol.rdir_loc));
+
+ if (fs_info->c.blk_num != blk)
+ {
+ if (fs_info->c.modified)
+ {
+ if (sec_of_fat && !fs_info->vol.mirror)
+ memcpy(fs_info->sec_buf, fs_info->c.buf->buffer,
+ fs_info->vol.bps);
+
+ sc = rtems_bdbuf_release_modified(fs_info->c.buf);
+ fs_info->c.state = FAT_CACHE_EMPTY;
+ fs_info->c.modified = 0;
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ if (sec_of_fat && !fs_info->vol.mirror)
+ {
+ bdbuf_buffer *b;
+
+ for (i = 1; i < fs_info->vol.fats; i++)
+ {
+ sc = rtems_bdbuf_get(fs_info->vol.dev,
+ fs_info->c.blk_num +
+ fs_info->vol.fat_length * i,
+ &b);
+ if ( sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(ENOMEM);
+ memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps);
+ sc = rtems_bdbuf_release_modified(b);
+ if ( sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(ENOMEM);
+ }
+ }
+ }
+ else
+ {
+ sc = rtems_bdbuf_release(fs_info->c.buf);
+ fs_info->c.state = FAT_CACHE_EMPTY;
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ }
+ if (op_type == FAT_OP_TYPE_READ)
+ sc = rtems_bdbuf_read(fs_info->vol.dev, blk, &fs_info->c.buf);
+ else
+ sc = rtems_bdbuf_get(fs_info->vol.dev, blk, &fs_info->c.buf);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+ fs_info->c.blk_num = blk;
+ fs_info->c.state = FAT_CACHE_ACTUAL;
+ }
+ *buf = fs_info->c.buf;
+ return RC_OK;
+}
+
+
+static inline int
+fat_buf_release(fat_fs_info_t *fs_info)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ uint8_t i;
+ rtems_boolean sec_of_fat;
+
+ if (fs_info->c.state == FAT_CACHE_EMPTY)
+ return RC_OK;
+
+ sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) &&
+ (fs_info->c.blk_num < fs_info->vol.rdir_loc));
+
+ if (fs_info->c.modified)
+ {
+ if (sec_of_fat && !fs_info->vol.mirror)
+ memcpy(fs_info->sec_buf, fs_info->c.buf->buffer, fs_info->vol.bps);
+
+ sc = rtems_bdbuf_release_modified(fs_info->c.buf);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+ fs_info->c.modified = 0;
+
+ if (sec_of_fat && !fs_info->vol.mirror)
+ {
+ bdbuf_buffer *b;
+
+ for (i = 1; i < fs_info->vol.fats; i++)
+ {
+ sc = rtems_bdbuf_get(fs_info->vol.dev,
+ fs_info->c.blk_num +
+ fs_info->vol.fat_length * i,
+ &b);
+ if ( sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(ENOMEM);
+ memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps);
+ sc = rtems_bdbuf_release_modified(b);
+ if ( sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(ENOMEM);
+ }
+ }
+ }
+ else
+ {
+ sc = rtems_bdbuf_release(fs_info->c.buf);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+ }
+ fs_info->c.state = FAT_CACHE_EMPTY;
+ return RC_OK;
+}
+
+static inline void
+fat_buf_mark_modified(fat_fs_info_t *fs_info)
+{
+ fs_info->c.modified = TRUE;
+}
+
+
+
+ssize_t
+_fat_block_read(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t start,
+ uint32_t offset,
+ uint32_t count,
+ void *buff);
+
+ssize_t
+_fat_block_write(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t start,
+ uint32_t offset,
+ uint32_t count,
+ const void *buff);
+
+ssize_t
+fat_cluster_read(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ void *buff);
+
+ssize_t
+fat_cluster_write(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ const void *buff);
+
+int
+fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry);
+
+int
+fat_init_clusters_chain(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t start_cln);
+
+uint32_t
+fat_cluster_num_to_sector_num(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln);
+
+int
+fat_shutdown_drive(rtems_filesystem_mount_table_entry_t *mt_entry);
+
+
+uint32_t
+fat_get_unique_ino(rtems_filesystem_mount_table_entry_t *mt_entry);
+
+rtems_boolean
+fat_ino_is_unique(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t ino);
+
+void
+fat_free_unique_ino(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t ino);
+
+int
+fat_fat32_update_fsinfo_sector(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t free_count,
+ uint32_t next_free
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DOSFS_FAT_H__ */
diff --git a/cpukit/libfs/src/dosfs/fat_fat_operations.c b/cpukit/libfs/src/dosfs/fat_fat_operations.c
new file mode 100644
index 0000000000..0e6411f799
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/fat_fat_operations.c
@@ -0,0 +1,437 @@
+/*
+ * fat_fat_operations.c
+ *
+ * General operations on File Allocation Table
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+
+/* fat_scan_fat_for_free_clusters --
+ * Allocate chain of free clusters from Files Allocation Table
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * chain - the number of the first allocated cluster (first cluster
+ * in the chain)
+ * count - count of clusters to allocate (chain length)
+ *
+ * RETURNS:
+ * RC_OK on success, or error code if error occured (errno set
+ * appropriately)
+ *
+ *
+ */
+int
+fat_scan_fat_for_free_clusters(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t *chain,
+ uint32_t count,
+ uint32_t *cls_added,
+ uint32_t *last_cl
+ )
+{
+ int rc = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t cl4find = 2;
+ uint32_t next_cln = 0;
+ uint32_t save_cln = 0;
+ uint32_t data_cls_val = fs_info->vol.data_cls + 2;
+ uint32_t i = 2;
+
+ *cls_added = 0;
+
+ if (count == 0)
+ return rc;
+
+ if (fs_info->vol.next_cl != FAT_UNDEFINED_VALUE)
+ cl4find = fs_info->vol.next_cl;
+
+ /*
+ * fs_info->vol.data_cls is exactly the count of data clusters
+ * starting at cluster 2, so the maximum valid cluster number is
+ * (fs_info->vol.data_cls + 1)
+ */
+ while (i < data_cls_val)
+ {
+ rc = fat_get_fat_cluster(mt_entry, cl4find, &next_cln);
+ if ( rc != RC_OK )
+ {
+ if (*cls_added != 0)
+ fat_free_fat_clusters_chain(mt_entry, (*chain));
+ return rc;
+ }
+
+ if (next_cln == FAT_GENFAT_FREE)
+ {
+ /*
+ * We are enforced to process allocation of the first free cluster
+ * by separate 'if' statement because otherwise undo function
+ * wouldn't work properly
+ */
+ if (*cls_added == 0)
+ {
+ *chain = cl4find;
+ rc = fat_set_fat_cluster(mt_entry, cl4find, FAT_GENFAT_EOC);
+ if ( rc != RC_OK )
+ {
+ /*
+ * this is the first cluster we tried to allocate so no
+ * cleanup activity needed
+ */
+ return rc;
+ }
+ }
+ else
+ {
+ /* set EOC value to new allocated cluster */
+ rc = fat_set_fat_cluster(mt_entry, cl4find, FAT_GENFAT_EOC);
+ if ( rc != RC_OK )
+ {
+ /* cleanup activity */
+ fat_free_fat_clusters_chain(mt_entry, (*chain));
+ return rc;
+ }
+
+ rc = fat_set_fat_cluster(mt_entry, save_cln, cl4find);
+ if ( rc != RC_OK )
+ {
+ /* cleanup activity */
+ fat_free_fat_clusters_chain(mt_entry, (*chain));
+ /* trying to save last allocated cluster for future use */
+ fat_set_fat_cluster(mt_entry, cl4find, FAT_GENFAT_FREE);
+ fat_buf_release(fs_info);
+ return rc;
+ }
+ }
+
+ save_cln = cl4find;
+ (*cls_added)++;
+
+ /* have we satisfied request ? */
+ if (*cls_added == count)
+ {
+ fs_info->vol.next_cl = save_cln;
+ if (fs_info->vol.free_cls != 0xFFFFFFFF)
+ fs_info->vol.free_cls -= (*cls_added);
+ *last_cl = save_cln;
+ fat_buf_release(fs_info);
+ return rc;
+ }
+ }
+ i++;
+ cl4find++;
+ if (cl4find >= data_cls_val)
+ cl4find = 2;
+ }
+
+ fs_info->vol.next_cl = save_cln;
+ if (fs_info->vol.free_cls != 0xFFFFFFFF)
+ fs_info->vol.free_cls -= (*cls_added);
+
+ *last_cl = save_cln;
+ fat_buf_release(fs_info);
+ return RC_OK;
+}
+
+/* fat_free_fat_clusters_chain --
+ * Free chain of clusters in Files Allocation Table.
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * chain - number of the first cluster in the chain
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set appropriately)
+ */
+int
+fat_free_fat_clusters_chain(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t chain
+ )
+{
+ int rc = RC_OK, rc1 = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t cur_cln = chain;
+ uint32_t next_cln = 0;
+ uint32_t freed_cls_cnt = 0;
+
+ while ((cur_cln & fs_info->vol.mask) < fs_info->vol.eoc_val)
+ {
+ rc = fat_get_fat_cluster(mt_entry, cur_cln, &next_cln);
+ if ( rc != RC_OK )
+ {
+ if(fs_info->vol.free_cls != FAT_UNDEFINED_VALUE)
+ fs_info->vol.free_cls += freed_cls_cnt;
+
+ fat_buf_release(fs_info);
+ return rc;
+ }
+
+ rc = fat_set_fat_cluster(mt_entry, cur_cln, FAT_GENFAT_FREE);
+ if ( rc != RC_OK )
+ rc1 = rc;
+
+ freed_cls_cnt++;
+ cur_cln = next_cln;
+ }
+
+ fs_info->vol.next_cl = chain;
+ if (fs_info->vol.free_cls != FAT_UNDEFINED_VALUE)
+ fs_info->vol.free_cls += freed_cls_cnt;
+
+ fat_buf_release(fs_info);
+ if (rc1 != RC_OK)
+ return rc1;
+
+ return RC_OK;
+}
+
+/* fat_get_fat_cluster --
+ * Fetches the contents of the cluster (link to next cluster in the chain)
+ * from Files Allocation Table.
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * cln - number of cluster to fetch the contents from
+ * ret_val - contents of the cluster 'cln' (link to next cluster in
+ * the chain)
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured
+ * and errno set appropriately
+ */
+int
+fat_get_fat_cluster(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ uint32_t *ret_val
+ )
+{
+ int rc = RC_OK;
+ register fat_fs_info_t *fs_info = mt_entry->fs_info;
+ bdbuf_buffer *block0 = NULL;
+ uint32_t sec = 0;
+ uint32_t ofs = 0;
+
+ /* sanity check */
+ if ( (cln < 2) || (cln > (fs_info->vol.data_cls + 1)) )
+ set_errno_and_return_minus_one(EIO);
+
+ sec = (FAT_FAT_OFFSET(fs_info->vol.type, cln) >> fs_info->vol.sec_log2) +
+ fs_info->vol.afat_loc;
+ ofs = FAT_FAT_OFFSET(fs_info->vol.type, cln) & (fs_info->vol.bps - 1);
+
+ rc = fat_buf_access(fs_info, sec, FAT_OP_TYPE_READ, &block0);
+ if (rc != RC_OK)
+ return rc;
+
+ switch ( fs_info->vol.type )
+ {
+ case FAT_FAT12:
+ /*
+ * we are enforced in complex computations for FAT12 to escape CPU
+ * align problems for some architectures
+ */
+ *ret_val = (*((uint8_t *)(block0->buffer + ofs)));
+ if ( ofs == (fs_info->vol.bps - 1) )
+ {
+ rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ,
+ &block0);
+ if (rc != RC_OK)
+ return rc;
+
+ *ret_val |= (*((uint8_t *)(block0->buffer)))<<8;
+ }
+ else
+ {
+ *ret_val |= (*((uint8_t *)(block0->buffer + ofs + 1)))<<8;
+ }
+
+ if ( FAT_CLUSTER_IS_ODD(cln) )
+ *ret_val = (*ret_val) >> FAT12_SHIFT;
+ else
+ *ret_val = (*ret_val) & FAT_FAT12_MASK;
+ break;
+
+ case FAT_FAT16:
+ *ret_val = *((uint16_t *)(block0->buffer + ofs));
+ *ret_val = CF_LE_W(*ret_val);
+ break;
+
+ case FAT_FAT32:
+ *ret_val = *((uint32_t *)(block0->buffer + ofs));
+ *ret_val = CF_LE_L(*ret_val);
+ break;
+
+ default:
+ set_errno_and_return_minus_one(EIO);
+ break;
+ }
+
+ return RC_OK;
+}
+
+/* fat_set_fat_cluster --
+ * Set the contents of the cluster (link to next cluster in the chain)
+ * from Files Allocation Table.
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * cln - number of cluster to set contents to
+ * in_val - value to set
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured
+ * and errno set appropriately
+ */
+int
+fat_set_fat_cluster(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ uint32_t in_val
+ )
+{
+ int rc = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t sec = 0;
+ uint32_t ofs = 0;
+ uint16_t fat16_clv = 0;
+ uint32_t fat32_clv = 0;
+ bdbuf_buffer *block0 = NULL;
+
+ /* sanity check */
+ if ( (cln < 2) || (cln > (fs_info->vol.data_cls + 1)) )
+ set_errno_and_return_minus_one(EIO);
+
+ sec = (FAT_FAT_OFFSET(fs_info->vol.type, cln) >> fs_info->vol.sec_log2) +
+ fs_info->vol.afat_loc;
+ ofs = FAT_FAT_OFFSET(fs_info->vol.type, cln) & (fs_info->vol.bps - 1);
+
+ rc = fat_buf_access(fs_info, sec, FAT_OP_TYPE_READ, &block0);
+ if (rc != RC_OK)
+ return rc;
+
+ switch ( fs_info->vol.type )
+ {
+ case FAT_FAT12:
+ if ( FAT_CLUSTER_IS_ODD(cln) )
+ {
+ fat16_clv = ((uint16_t )in_val) << FAT_FAT12_SHIFT;
+ *((uint8_t *)(block0->buffer + ofs)) =
+ (*((uint8_t *)(block0->buffer + ofs))) & 0x0F;
+
+ *((uint8_t *)(block0->buffer + ofs)) =
+ (*((uint8_t *)(block0->buffer + ofs))) |
+ (uint8_t )(fat16_clv & 0x00FF);
+
+ fat_buf_mark_modified(fs_info);
+
+ if ( ofs == (fs_info->vol.bps - 1) )
+ {
+ rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ,
+ &block0);
+ if (rc != RC_OK)
+ return rc;
+
+ *((uint8_t *)(block0->buffer)) &= 0x00;
+
+ *((uint8_t *)(block0->buffer)) =
+ (*((uint8_t *)(block0->buffer))) |
+ (uint8_t )((fat16_clv & 0xFF00)>>8);
+
+ fat_buf_mark_modified(fs_info);
+ }
+ else
+ {
+ *((uint8_t *)(block0->buffer + ofs + 1)) &= 0x00;
+
+ *((uint8_t *)(block0->buffer + ofs + 1)) =
+ (*((uint8_t *)(block0->buffer + ofs + 1))) |
+ (uint8_t )((fat16_clv & 0xFF00)>>8);
+ }
+ }
+ else
+ {
+ fat16_clv = ((uint16_t )in_val) & FAT_FAT12_MASK;
+ *((uint8_t *)(block0->buffer + ofs)) &= 0x00;
+
+ *((uint8_t *)(block0->buffer + ofs)) =
+ (*((uint8_t *)(block0->buffer + ofs))) |
+ (uint8_t )(fat16_clv & 0x00FF);
+
+ fat_buf_mark_modified(fs_info);
+
+ if ( ofs == (fs_info->vol.bps - 1) )
+ {
+ rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ,
+ &block0);
+ if (rc != RC_OK)
+ return rc;
+
+ *((uint8_t *)(block0->buffer)) =
+ (*((uint8_t *)(block0->buffer))) & 0xF0;
+
+ *((uint8_t *)(block0->buffer)) =
+ (*((uint8_t *)(block0->buffer))) |
+ (uint8_t )((fat16_clv & 0xFF00)>>8);
+
+ fat_buf_mark_modified(fs_info);
+ }
+ else
+ {
+ *((uint8_t *)(block0->buffer + ofs + 1)) =
+ (*((uint8_t *)(block0->buffer + ofs + 1))) & 0xF0;
+
+ *((uint8_t *)(block0->buffer + ofs+1)) =
+ (*((uint8_t *)(block0->buffer + ofs+1))) |
+ (uint8_t )((fat16_clv & 0xFF00)>>8);
+ }
+ }
+ break;
+
+ case FAT_FAT16:
+ *((uint16_t *)(block0->buffer + ofs)) =
+ (uint16_t )(CT_LE_W(in_val));
+ fat_buf_mark_modified(fs_info);
+ break;
+
+ case FAT_FAT32:
+ fat32_clv = CT_LE_L((in_val & FAT_FAT32_MASK));
+
+ *((uint32_t *)(block0->buffer + ofs)) =
+ (*((uint32_t *)(block0->buffer + ofs))) & (CT_LE_L(0xF0000000));
+
+ *((uint32_t *)(block0->buffer + ofs)) =
+ fat32_clv | (*((uint32_t *)(block0->buffer + ofs)));
+
+ fat_buf_mark_modified(fs_info);
+ break;
+
+ default:
+ set_errno_and_return_minus_one(EIO);
+ break;
+
+ }
+
+ return RC_OK;
+}
diff --git a/cpukit/libfs/src/dosfs/fat_fat_operations.h b/cpukit/libfs/src/dosfs/fat_fat_operations.h
new file mode 100644
index 0000000000..bf5cf04564
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/fat_fat_operations.h
@@ -0,0 +1,58 @@
+/*
+ * fat_fat_operations.h
+ *
+ * Constants/data structures/prototypes for operations on Files Allocation
+ * Table
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+#ifndef __DOSFS_FAT_FAT_OPERATIONS_H__
+#define __DOSFS_FAT_FAT_OPERATIONS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <rtems/libio_.h>
+
+#include <rtems/bdbuf.h>
+#include "fat.h"
+
+int
+fat_get_fat_cluster(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ uint32_t *ret_val);
+
+int
+fat_set_fat_cluster(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ uint32_t in_val);
+
+int
+fat_scan_fat_for_free_clusters(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t *chain,
+ uint32_t count,
+ uint32_t *cls_added,
+ uint32_t *last_cl
+);
+
+int
+fat_free_fat_clusters_chain(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t chain
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DOSFS_FAT_FAT_OPERATIONS_H__ */
diff --git a/cpukit/libfs/src/dosfs/fat_file.c b/cpukit/libfs/src/dosfs/fat_file.c
new file mode 100644
index 0000000000..69e1d9a7e0
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/fat_file.c
@@ -0,0 +1,987 @@
+/*
+ * fat_file.c
+ *
+ * General operations on "fat-file"
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * @(#) $Id$
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <time.h>
+
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "fat_file.h"
+
+static inline void
+_hash_insert(Chain_Control *hash, uint32_t key1, uint32_t key2,
+ fat_file_fd_t *el);
+
+static inline void
+_hash_delete(Chain_Control *hash, uint32_t key1, uint32_t key2,
+ fat_file_fd_t *el);
+
+static inline int
+_hash_search(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ Chain_Control *hash,
+ uint32_t key1,
+ uint32_t key2,
+ fat_file_fd_t **ret
+);
+
+static int
+fat_file_lseek(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t file_cln,
+ uint32_t *disk_cln
+);
+
+/* fat_file_open --
+ * Open fat-file. Two hash tables are accessed by key
+ * constructed from cluster num and offset of the node (i.e.
+ * files/directories are distinguished by location on the disk).
+ * First, hash table("vhash") consists of fat-file descriptors corresponded
+ * to "valid" files is accessed. Search is made by 2 fields equal to key
+ * constructed. If descriptor is found in the "vhash" - return it.
+ * Otherwise search is made in hash table("rhash") consits of fat-file
+ * descriptors corresponded to "removed-but-still-open" files with the
+ * same keys.
+ * If search failed, new fat-file descriptor is added to "vhash"
+ * with both key fields equal to constructed key. Otherwise new fat-file
+ * descriptor is added to "vhash" with first key field equal to key
+ * constructed and the second equal to an unique (unique among all values
+ * of second key fields) value.
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * cln - cluster num of the node
+ * ofs - offset of the node
+ * fat_fd - placeholder for returned fat-file descriptor
+ *
+ * RETURNS:
+ * RC_OK and pointer to opened descriptor on success, or -1 if error
+ * occured (errno set appropriately)
+ */
+int
+fat_file_open(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ uint32_t ofs,
+ fat_file_fd_t **fat_fd
+ )
+{
+ int rc = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ fat_file_fd_t *lfat_fd = NULL;
+ uint32_t key = 0;
+
+ /* construct key */
+ key = fat_construct_key(mt_entry, cln, ofs);
+
+ /* access "valid" hash table */
+ rc = _hash_search(mt_entry, fs_info->vhash, key, 0, &lfat_fd);
+ if ( rc == RC_OK )
+ {
+ /* return pointer to fat_file_descriptor allocated before */
+ (*fat_fd) = lfat_fd;
+ lfat_fd->links_num++;
+ return rc;
+ }
+
+ /* access "removed-but-still-open" hash table */
+ rc = _hash_search(mt_entry, fs_info->rhash, key, key, &lfat_fd);
+
+ lfat_fd = (*fat_fd) = (fat_file_fd_t*)malloc(sizeof(fat_file_fd_t));
+ if ( lfat_fd == NULL )
+ set_errno_and_return_minus_one( ENOMEM );
+
+ lfat_fd->links_num = 1;
+ lfat_fd->flags &= ~FAT_FILE_REMOVED;
+ lfat_fd->map.last_cln = FAT_UNDEFINED_VALUE;
+
+ if ( rc != RC_OK )
+ lfat_fd->ino = key;
+ else
+ {
+ lfat_fd->ino = fat_get_unique_ino(mt_entry);
+
+ if ( lfat_fd->ino == 0 )
+ {
+ free((*fat_fd));
+ /*
+ * XXX: kernel resource is unsufficient, but not the memory,
+ * but there is no suitable errno :(
+ */
+ set_errno_and_return_minus_one( ENOMEM );
+ }
+ }
+ _hash_insert(fs_info->vhash, key, lfat_fd->ino, lfat_fd);
+
+
+ /*
+ * other fields of fat-file descriptor will be initialized on upper
+ * level
+ */
+
+ return RC_OK;
+}
+
+
+/* fat_file_reopen --
+ * Increment by 1 number of links
+ *
+ * PARAMETERS:
+ * fat_fd - fat-file descriptor
+ *
+ * RETURNS:
+ * RC_OK
+ */
+int
+fat_file_reopen(fat_file_fd_t *fat_fd)
+{
+ fat_fd->links_num++;
+ return RC_OK;
+}
+
+/* fat_file_close --
+ * Close fat-file. If count of links to fat-file
+ * descriptor is greater than 1 (i.e. somebody esle holds pointer
+ * to this descriptor) just decrement it. Otherwise
+ * do the following. If this descriptor corresponded to removed fat-file
+ * then free clusters contained fat-file data, delete descriptor from
+ * "rhash" table and free memory allocated by descriptor. If descriptor
+ * correspondes to non-removed fat-file and 'ino' field has value from
+ * unique inode numbers pool then set count of links to descriptor to zero
+ * and leave it in hash, otherwise delete descriptor from "vhash" and free
+ * memory allocated by the descriptor
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ *
+ * RETURNS:
+ * RC_OK, or -1 if error occured (errno set appropriately)
+ */
+int
+fat_file_close(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd
+ )
+{
+ int rc = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t key = 0;
+
+ /*
+ * if links_num field of fat-file descriptor is greater than 1
+ * decrement the count of links and return
+ */
+ if (fat_fd->links_num > 1)
+ {
+ fat_fd->links_num--;
+ return rc;
+ }
+
+ key = fat_construct_key(mt_entry, fat_fd->info_cln, fat_fd->info_ofs);
+
+ if (fat_fd->flags & FAT_FILE_REMOVED)
+ {
+ rc = fat_file_truncate(mt_entry, fat_fd, 0);
+ if ( rc != RC_OK )
+ return rc;
+
+ _hash_delete(fs_info->rhash, key, fat_fd->ino, fat_fd);
+
+ if ( fat_ino_is_unique(mt_entry, fat_fd->ino) )
+ fat_free_unique_ino(mt_entry, fat_fd->ino);
+
+ free(fat_fd);
+ }
+ else
+ {
+ if (fat_ino_is_unique(mt_entry, fat_fd->ino))
+ {
+ fat_fd->links_num = 0;
+ }
+ else
+ {
+ _hash_delete(fs_info->vhash, key, fat_fd->ino, fat_fd);
+ free(fat_fd);
+ }
+ }
+ /*
+ * flush any modified "cached" buffer back to disk
+ */
+ rc = fat_buf_release(fs_info);
+
+ return rc;
+}
+
+/* fat_file_read --
+ * Read 'count' bytes from 'start' position from fat-file. This
+ * interface hides the architecture of fat-file, represents it as
+ * linear file
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ * start - offset in fat-file (in bytes) to read from
+ * count - count of bytes to read
+ * buf - buffer provided by user
+ *
+ * RETURNS:
+ * the number of bytes read on success, or -1 if error occured (errno
+ * set appropriately)
+ */
+ssize_t
+fat_file_read(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t start,
+ uint32_t count,
+ uint8_t *buf
+)
+{
+ int rc = RC_OK;
+ ssize_t ret = 0;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t cmpltd = 0;
+ uint32_t cur_cln = 0;
+ uint32_t cl_start = 0;
+ uint32_t save_cln = 0;
+ uint32_t ofs = 0;
+ uint32_t save_ofs;
+ uint32_t sec = 0;
+ uint32_t byte = 0;
+ uint32_t c = 0;
+
+ /* it couldn't be removed - otherwise cache update will be broken */
+ if (count == 0)
+ return cmpltd;
+
+ /*
+ * >= because start is offset and computed from 0 and file_size
+ * computed from 1
+ */
+ if ( start >= fat_fd->fat_file_size )
+ return FAT_EOF;
+
+ if ((count > fat_fd->fat_file_size) ||
+ (start > fat_fd->fat_file_size - count))
+ count = fat_fd->fat_file_size - start;
+
+ if ((FAT_FD_OF_ROOT_DIR(fat_fd)) &&
+ (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)))
+ {
+ sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->cln);
+ sec += (start >> fs_info->vol.sec_log2);
+ byte = start & (fs_info->vol.bps - 1);
+
+ ret = _fat_block_read(mt_entry, sec, byte, count, buf);
+ if ( ret < 0 )
+ return -1;
+
+ return ret;
+ }
+
+ cl_start = start >> fs_info->vol.bpc_log2;
+ save_ofs = ofs = start & (fs_info->vol.bpc - 1);
+
+ rc = fat_file_lseek(mt_entry, fat_fd, cl_start, &cur_cln);
+ if (rc != RC_OK)
+ return rc;
+
+ while (count > 0)
+ {
+ c = MIN(count, (fs_info->vol.bpc - ofs));
+
+ sec = fat_cluster_num_to_sector_num(mt_entry, cur_cln);
+ sec += (ofs >> fs_info->vol.sec_log2);
+ byte = ofs & (fs_info->vol.bps - 1);
+
+ ret = _fat_block_read(mt_entry, sec, byte, c, buf + cmpltd);
+ if ( ret < 0 )
+ return -1;
+
+ count -= c;
+ cmpltd += c;
+ save_cln = cur_cln;
+ rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln);
+ if ( rc != RC_OK )
+ return rc;
+
+ ofs = 0;
+ }
+
+ /* update cache */
+ /* XXX: check this - I'm not sure :( */
+ fat_fd->map.file_cln = cl_start +
+ ((save_ofs + cmpltd - 1) >> fs_info->vol.bpc_log2);
+ fat_fd->map.disk_cln = save_cln;
+
+ return cmpltd;
+}
+
+/* fat_file_write --
+ * Write 'count' bytes of data from user supplied buffer to fat-file
+ * starting at offset 'start'. This interface hides the architecture
+ * of fat-file, represents it as linear file
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ * start - offset(in bytes) to write from
+ * count - count
+ * buf - buffer provided by user
+ *
+ * RETURNS:
+ * number of bytes actually written to the file on success, or -1 if
+ * error occured (errno set appropriately)
+ */
+ssize_t
+fat_file_write(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t start,
+ uint32_t count,
+ const uint8_t *buf
+ )
+{
+ int rc = 0;
+ ssize_t ret = 0;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t cmpltd = 0;
+ uint32_t cur_cln = 0;
+ uint32_t save_cln = 0; /* FIXME: This might be incorrect, cf. below */
+ uint32_t cl_start = 0;
+ uint32_t ofs = 0;
+ uint32_t save_ofs;
+ uint32_t sec = 0;
+ uint32_t byte = 0;
+ uint32_t c = 0;
+
+ if ( count == 0 )
+ return cmpltd;
+
+ if ( start > fat_fd->fat_file_size )
+ set_errno_and_return_minus_one( EIO );
+
+ if ((count > fat_fd->size_limit) ||
+ (start > fat_fd->size_limit - count))
+ set_errno_and_return_minus_one( EIO );
+
+ rc = fat_file_extend(mt_entry, fat_fd, start + count, &c);
+ if (rc != RC_OK)
+ return rc;
+
+ /*
+ * check whether there was enough room on device to locate
+ * file of 'start + count' bytes
+ */
+ if (c != (start + count))
+ count = c - start;
+
+ if ((FAT_FD_OF_ROOT_DIR(fat_fd)) &&
+ (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)))
+ {
+ sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->cln);
+ sec += (start >> fs_info->vol.sec_log2);
+ byte = start & (fs_info->vol.bps - 1);
+
+ ret = _fat_block_write(mt_entry, sec, byte, count, buf);
+ if ( ret < 0 )
+ return -1;
+
+ return ret;
+ }
+
+ cl_start = start >> fs_info->vol.bpc_log2;
+ save_ofs = ofs = start & (fs_info->vol.bpc - 1);
+
+ rc = fat_file_lseek(mt_entry, fat_fd, cl_start, &cur_cln);
+ if (rc != RC_OK)
+ return rc;
+
+ while (count > 0)
+ {
+ c = MIN(count, (fs_info->vol.bpc - ofs));
+
+ sec = fat_cluster_num_to_sector_num(mt_entry, cur_cln);
+ sec += (ofs >> fs_info->vol.sec_log2);
+ byte = ofs & (fs_info->vol.bps - 1);
+
+ ret = _fat_block_write(mt_entry, sec, byte, c, buf + cmpltd);
+ if ( ret < 0 )
+ return -1;
+
+ count -= c;
+ cmpltd += c;
+ save_cln = cur_cln;
+ rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln);
+ if ( rc != RC_OK )
+ return rc;
+
+ ofs = 0;
+ }
+
+ /* update cache */
+ /* XXX: check this - I'm not sure :( */
+ fat_fd->map.file_cln = cl_start +
+ ((save_ofs + cmpltd - 1) >> fs_info->vol.bpc_log2);
+ fat_fd->map.disk_cln = save_cln;
+
+ return cmpltd;
+}
+
+/* fat_file_extend --
+ * Extend fat-file. If new length less than current fat-file size -
+ * do nothing. Otherwise calculate necessary count of clusters to add,
+ * allocate it and add new clusters chain to the end of
+ * existing clusters chain.
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ * new_length - new length
+ * a_length - placeholder for result - actual new length of file
+ *
+ * RETURNS:
+ * RC_OK and new length of file on success, or -1 if error occured (errno
+ * set appropriately)
+ */
+int
+fat_file_extend(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t new_length,
+ uint32_t *a_length
+ )
+{
+ int rc = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t chain = 0;
+ uint32_t bytes2add = 0;
+ uint32_t cls2add = 0;
+ uint32_t old_last_cl;
+ uint32_t last_cl = 0;
+ uint32_t bytes_remain = 0;
+ uint32_t cls_added;
+
+ *a_length = new_length;
+
+ if (new_length <= fat_fd->fat_file_size)
+ return RC_OK;
+
+ if ((FAT_FD_OF_ROOT_DIR(fat_fd)) &&
+ (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)))
+ set_errno_and_return_minus_one( ENOSPC );
+
+ bytes_remain = (fs_info->vol.bpc -
+ (fat_fd->fat_file_size & (fs_info->vol.bpc - 1))) &
+ (fs_info->vol.bpc - 1);
+
+ bytes2add = new_length - fat_fd->fat_file_size;
+
+ if (bytes2add > bytes_remain)
+ bytes2add -= bytes_remain;
+ else
+ bytes2add = 0;
+
+ /*
+ * if in last cluster allocated for the file there is enough room to
+ * handle extention (hence we don't need to add even one cluster to the
+ * file ) - return
+ */
+ if (bytes2add == 0)
+ return RC_OK;
+
+ cls2add = ((bytes2add - 1) >> fs_info->vol.bpc_log2) + 1;
+
+ rc = fat_scan_fat_for_free_clusters(mt_entry, &chain, cls2add,
+ &cls_added, &last_cl);
+
+ /* this means that low level I/O error occured */
+ if (rc != RC_OK)
+ return rc;
+
+ /* this means that no space left on device */
+ if ((cls_added == 0) && (bytes_remain == 0))
+ set_errno_and_return_minus_one(ENOSPC);
+
+ /* check wether we satisfied request for 'cls2add' clusters */
+ if (cls2add != cls_added)
+ *a_length = new_length -
+ ((cls2add - cls_added - 1) << fs_info->vol.bpc_log2) -
+ (bytes2add & (fs_info->vol.bpc - 1));
+
+ /* add new chain to the end of existed */
+ if ( fat_fd->fat_file_size == 0 )
+ {
+ fat_fd->map.disk_cln = fat_fd->cln = chain;
+ fat_fd->map.file_cln = 0;
+ }
+ else
+ {
+ if (fat_fd->map.last_cln != FAT_UNDEFINED_VALUE)
+ {
+ old_last_cl = fat_fd->map.last_cln;
+ }
+ else
+ {
+ rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM,
+ (fat_fd->fat_file_size - 1), &old_last_cl);
+ if ( rc != RC_OK )
+ {
+ fat_free_fat_clusters_chain(mt_entry, chain);
+ return rc;
+ }
+ }
+
+ rc = fat_set_fat_cluster(mt_entry, old_last_cl, chain);
+ if ( rc != RC_OK )
+ {
+ fat_free_fat_clusters_chain(mt_entry, chain);
+ return rc;
+ }
+ fat_buf_release(fs_info);
+ }
+
+ /* update number of the last cluster of the file if it changed */
+ if (cls_added != 0)
+ {
+ fat_fd->map.last_cln = last_cl;
+ if (fat_fd->fat_file_type == FAT_DIRECTORY)
+ {
+ rc = fat_init_clusters_chain(mt_entry, chain);
+ if ( rc != RC_OK )
+ {
+ fat_free_fat_clusters_chain(mt_entry, chain);
+ return rc;
+ }
+ }
+ }
+
+ return RC_OK;
+}
+
+/* fat_file_truncate --
+ * Truncate fat-file. If new length greater than current fat-file size -
+ * do nothing. Otherwise find first cluster to free and free all clusters
+ * in the chain starting from this cluster.
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ * new_length - new length
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set appropriately)
+ */
+int
+fat_file_truncate(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t new_length
+ )
+{
+ int rc = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t cur_cln = 0;
+ uint32_t cl_start = 0;
+ uint32_t new_last_cln = FAT_UNDEFINED_VALUE;
+
+
+ if ( new_length >= fat_fd->fat_file_size )
+ return rc;
+
+ assert(fat_fd->fat_file_size);
+
+ cl_start = (new_length + fs_info->vol.bpc - 1) >> fs_info->vol.bpc_log2;
+
+ if ((cl_start << fs_info->vol.bpc_log2) >= fat_fd->fat_file_size)
+ return RC_OK;
+
+ if (cl_start != 0)
+ {
+ rc = fat_file_lseek(mt_entry, fat_fd, cl_start - 1, &new_last_cln);
+ if (rc != RC_OK)
+ return rc;
+
+ }
+
+ rc = fat_file_lseek(mt_entry, fat_fd, cl_start, &cur_cln);
+ if (rc != RC_OK)
+ return rc;
+
+ rc = fat_free_fat_clusters_chain(mt_entry, cur_cln);
+ if (rc != RC_OK)
+ return rc;
+
+ if (cl_start != 0)
+ {
+ rc = fat_set_fat_cluster(mt_entry, new_last_cln, FAT_GENFAT_EOC);
+ if ( rc != RC_OK )
+ return rc;
+ fat_fd->map.file_cln = cl_start - 1;
+ fat_fd->map.disk_cln = new_last_cln;
+ fat_fd->map.last_cln = new_last_cln;
+ }
+ return RC_OK;
+}
+
+/* fat_file_ioctl --
+ * F_CLU_NUM:
+ * make mapping between serial number of the cluster in fat-file and
+ * its real number on the volume
+ *
+ * PARAMETERS:
+ * fat_fd - fat-file descriptor
+ * mt_entry - mount table entry
+ * cmd - command
+ * ...
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured and errno set appropriately
+ */
+int
+fat_file_ioctl(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ int cmd,
+ ...)
+{
+ int rc = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t cur_cln = 0;
+ uint32_t cl_start = 0;
+ uint32_t pos = 0;
+ uint32_t *ret;
+ va_list ap;
+
+ va_start(ap, cmd);
+
+ switch (cmd)
+ {
+ case F_CLU_NUM:
+ pos = va_arg(ap, uint32_t );
+ ret = va_arg(ap, uint32_t *);
+
+ /* sanity check */
+ if ( pos >= fat_fd->fat_file_size )
+ set_errno_and_return_minus_one( EIO );
+
+ if ((FAT_FD_OF_ROOT_DIR(fat_fd)) &&
+ (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)))
+ {
+ /* cluster 0 (zero) reserved for root dir */
+ *ret = 0;
+ return RC_OK;
+ }
+
+ cl_start = pos >> fs_info->vol.bpc_log2;
+
+ rc = fat_file_lseek(mt_entry, fat_fd, cl_start, &cur_cln);
+ if ( rc != RC_OK )
+ return rc;
+
+ *ret = cur_cln;
+ break;
+
+ default:
+ errno = EINVAL;
+ rc = -1;
+ break;
+ }
+ return rc;
+}
+
+/* fat_file_mark_removed --
+ * Remove the fat-file descriptor from "valid" hash table, insert it
+ * into "removed-but-still-open" hash table and set up "removed" bit.
+ *
+ * PARAMETERS:
+ * fat_fd - fat-file descriptor
+ * mt_entry - mount table entry
+ *
+ * RETURNS:
+ * None
+ */
+void
+fat_file_mark_removed(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd
+ )
+{
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t key = 0;
+
+ key = fat_construct_key(mt_entry, fat_fd->info_cln, fat_fd->info_ofs);
+
+ _hash_delete(fs_info->vhash, key, fat_fd->ino, fat_fd);
+
+ _hash_insert(fs_info->rhash, key, fat_fd->ino, fat_fd);
+
+ fat_fd->flags |= FAT_FILE_REMOVED;
+}
+
+/* fat_file_datasync --
+ * Synchronize fat-file - flush all buffered data to the media.
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured and errno set appropriately
+ */
+int
+fat_file_datasync(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd
+ )
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t cur_cln = fat_fd->cln;
+ bdbuf_buffer *block = NULL;
+ uint32_t sec = 0;
+ uint32_t i = 0;
+
+ if (fat_fd->fat_file_size == 0)
+ return RC_OK;
+
+ /*
+ * we can use only one bdbuf :( and we also know that cache is useless
+ * for sync operation, so don't use it
+ */
+ rc = fat_buf_release(fs_info);
+ if (rc != RC_OK)
+ return rc;
+
+ /* for each cluster of the file ... */
+ while ((cur_cln & fs_info->vol.mask) < fs_info->vol.eoc_val)
+ {
+ sec = fat_cluster_num_to_sector_num(mt_entry, cur_cln);
+ /* for each sector in cluster ... */
+ for ( i = 0; i < fs_info->vol.spc; i++ )
+ {
+ /* ... sync it */
+ sc = rtems_bdbuf_read(fs_info->vol.dev, (sec + i), &block);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one( EIO );
+
+ sc = rtems_bdbuf_sync(block);
+ if ( sc != RTEMS_SUCCESSFUL )
+ set_errno_and_return_minus_one( EIO );
+ }
+
+ rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln);
+ if ( rc != RC_OK )
+ return rc;
+ }
+ return rc;
+}
+
+/* fat_file_size --
+ * Calculate fat-file size - fat-file is nothing that clusters chain, so
+ * go through all clusters in the chain and count it. Only
+ * special case is root directory for FAT12/16 volumes.
+ * This function is used only for directories which are fat-files with
+ * non-zero length, hence 'fat_fd->cln' always contains valid data.
+ * Calculated size is stored in 'fat_file_size' field of fat-file
+ * descriptor.
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set appropriately)
+ */
+int
+fat_file_size(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd
+ )
+{
+ int rc = RC_OK;
+ fat_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t cur_cln = fat_fd->cln;
+ uint32_t save_cln = 0;
+
+ /* Have we requested root dir size for FAT12/16? */
+ if ((FAT_FD_OF_ROOT_DIR(fat_fd)) &&
+ (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)))
+ {
+ fat_fd->fat_file_size = fs_info->vol.rdir_size;
+ return rc;
+ }
+
+ fat_fd->fat_file_size = 0;
+
+ while ((cur_cln & fs_info->vol.mask) < fs_info->vol.eoc_val)
+ {
+ save_cln = cur_cln;
+ rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln);
+ if ( rc != RC_OK )
+ return rc;
+
+ fat_fd->fat_file_size += fs_info->vol.bpc;
+ }
+ fat_fd->map.last_cln = save_cln;
+ return rc;
+}
+
+/* hash support routines */
+
+/* _hash_insert --
+ * Insert elemnt into hash based on key 'key1'
+ *
+ * PARAMETERS:
+ * hash - hash element will be inserted into
+ * key1 - key on which insertion is based on
+ * key2 - not used during insertion
+ * el - element to insert
+ *
+ * RETURNS:
+ * None
+ */
+static inline void
+_hash_insert(Chain_Control *hash, uint32_t key1, uint32_t key2,
+ fat_file_fd_t *el)
+{
+ _Chain_Append((hash) + ((key1) % FAT_HASH_MODULE), &(el)->link);
+}
+
+
+/* _hash_delete --
+ * Remove element from hash
+ *
+ * PARAMETERS:
+ * hash - hash element will be removed from
+ * key1 - not used
+ * key2 - not used
+ * el - element to delete
+ *
+ * RETURNS:
+ * None
+ */
+static inline void
+_hash_delete(Chain_Control *hash, uint32_t key1, uint32_t key2,
+ fat_file_fd_t *el)
+{
+ _Chain_Extract(&(el)->link);
+}
+
+/* _hash_search --
+ * Search element in hash. If both keys match pointer to found element
+ * is returned
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * hash - hash element will be removed from
+ * key1 - search key
+ * key2 - search key
+ * ret - placeholder for result
+ *
+ * RETURNS:
+ * 0 and pointer to found element on success, -1 otherwise
+ */
+static inline int
+_hash_search(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ Chain_Control *hash,
+ uint32_t key1,
+ uint32_t key2,
+ fat_file_fd_t **ret
+ )
+{
+ uint32_t mod = (key1) % FAT_HASH_MODULE;
+ Chain_Node *the_node = ((Chain_Control *)((hash) + mod))->first;
+
+ for ( ; !_Chain_Is_tail((hash) + mod, the_node) ; )
+ {
+ fat_file_fd_t *ffd = (fat_file_fd_t *)the_node;
+ uint32_t ck =
+ fat_construct_key(mt_entry, ffd->info_cln, ffd->info_ofs);
+
+ if ( (key1) == ck)
+ {
+ if ( ((key2) == 0) || ((key2) == ffd->ino) )
+ {
+ *ret = (void *)the_node;
+ return 0;
+ }
+ }
+ the_node = the_node->next;
+ }
+ return -1;
+}
+
+static int
+fat_file_lseek(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t file_cln,
+ uint32_t *disk_cln
+ )
+{
+ int rc = RC_OK;
+/*
+ assert(fat_fd->fat_file_size);
+ */
+ if (file_cln == fat_fd->map.file_cln)
+ *disk_cln = fat_fd->map.disk_cln;
+ else
+ {
+ uint32_t cur_cln;
+ uint32_t count;
+ uint32_t i;
+
+ if (file_cln > fat_fd->map.file_cln)
+ {
+ cur_cln = fat_fd->map.disk_cln;
+ count = file_cln - fat_fd->map.file_cln;
+ }
+ else
+ {
+ cur_cln = fat_fd->cln;
+ count = file_cln;
+ }
+
+ /* skip over the clusters */
+ for (i = 0; i < count; i++)
+ {
+ rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln);
+ if ( rc != RC_OK )
+ return rc;
+ }
+
+ /* update cache */
+ fat_fd->map.file_cln = file_cln;
+ fat_fd->map.disk_cln = cur_cln;
+
+ *disk_cln = cur_cln;
+ }
+ return RC_OK;
+}
diff --git a/cpukit/libfs/src/dosfs/fat_file.h b/cpukit/libfs/src/dosfs/fat_file.h
new file mode 100644
index 0000000000..9b0766e6e7
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/fat_file.h
@@ -0,0 +1,195 @@
+/*
+ * fat_file.h
+ *
+ * Constants/data structures/prototypes for operations on "fat-file"
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+#ifndef __DOSFS_FAT_FILE_H__
+#define __DOSFS_FAT_FILE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <rtems/libio_.h>
+
+#include <time.h>
+
+/* "fat-file" representation
+ *
+ * the idea is: fat-file is nothing but a cluster chain, any open fat-file is
+ * represented in system by fat-file descriptor and has well-known
+ * file interface:
+ *
+ * fat_file_open()
+ * fat_file_close()
+ * fat_file_read()
+ * fat_file_write()
+ *
+ * Such interface hides the architecture of fat-file and represents it like
+ * linear file
+ */
+
+typedef rtems_filesystem_node_types_t fat_file_type_t;
+
+#define FAT_DIRECTORY RTEMS_FILESYSTEM_DIRECTORY
+#define FAT_FILE RTEMS_FILESYSTEM_MEMORY_FILE
+
+typedef struct fat_file_map_s
+{
+ uint32_t file_cln;
+ uint32_t disk_cln;
+ uint32_t last_cln;
+} fat_file_map_t;
+/*
+ * descriptor of a fat-file
+ *
+ * To each particular clusters chain
+ */
+typedef struct fat_file_fd_s
+{
+ Chain_Node link; /*
+ * fat-file descriptors organized into hash;
+ * collision lists are handled via link
+ * field
+ */
+ uint32_t links_num; /*
+ * the number of fat_file_open call on
+ * this fat-file
+ */
+ uint32_t ino; /* inode, file serial number :)))) */
+ fat_file_type_t fat_file_type;
+ uint32_t size_limit;
+ uint32_t fat_file_size; /* length */
+ uint32_t info_cln;
+ uint32_t cln;
+ uint16_t info_ofs;
+ unsigned char first_char;
+ uint8_t flags;
+ fat_file_map_t map;
+ time_t mtime;
+
+} fat_file_fd_t;
+
+
+#define FAT_FILE_REMOVED 0x01
+
+#define FAT_FILE_IS_REMOVED(p)\
+ (((p)->flags & FAT_FILE_REMOVED) ? 1 : 0)
+
+/* ioctl macros */
+#define F_CLU_NUM 0x01
+
+/*
+ * Each file and directory on a MSDOS volume is unique identified by it
+ * location, i.e. location of it 32 Bytes Directory Entry Structure. We can
+ * distinguish them by cluster number it locates on and offset inside this
+ * cluster. But root directory on any volumes (FAT12/16/32) has no 32 Bytes
+ * Directory Entry Structure corresponded to it. So we assume 32 Bytes
+ * Directory Entry Structure of root directory locates at cluster 1 (invalid
+ * cluaster number) and offset 0
+ */
+#define FAT_ROOTDIR_CLUSTER_NUM 0x01
+
+#define FAT_FD_OF_ROOT_DIR(fat_fd) \
+ ((fat_fd->info_cln == FAT_ROOTDIR_CLUSTER_NUM ) && \
+ (fat_fd->info_ofs == 0))
+
+#define FAT_EOF 0x00
+
+/* fat_construct_key --
+ * Construct key for hash access: convert (cluster num, offset) to
+ * (sector512 num, new offset) and than construct key as
+ * key = (sector512 num) << 4 | (new offset)
+ *
+ * PARAMETERS:
+ * cl - cluster number
+ * ofs - offset inside cluster 'cl'
+ * mt_entry - mount table entry
+ *
+ * RETURNS:
+ * constructed key
+ */
+static inline uint32_t
+fat_construct_key(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cl,
+ uint32_t ofs)
+{
+ return ( ((fat_cluster_num_to_sector512_num(mt_entry, cl) +
+ (ofs >> FAT_SECTOR512_BITS)) << 4) +
+ ((ofs >> 5) & (FAT_DIRENTRIES_PER_SEC512 - 1)) );
+}
+
+/* Prototypes for "fat-file" operations */
+int
+fat_file_open(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ uint32_t ofs,
+ fat_file_fd_t **fat_fd);
+
+int
+fat_file_reopen(fat_file_fd_t *fat_fd);
+
+int
+fat_file_close(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd);
+
+ssize_t
+fat_file_read(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t start,
+ uint32_t count,
+ uint8_t *buf);
+
+ssize_t
+fat_file_write(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t start,
+ uint32_t count,
+ const uint8_t *buf);
+
+int
+fat_file_extend(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t new_length,
+ uint32_t *a_length);
+
+int
+fat_file_truncate(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t new_length);
+
+int
+fat_file_datasync(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd);
+
+
+int
+fat_file_ioctl(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ int cmd,
+ ...);
+
+int
+fat_file_size(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd);
+
+void
+fat_file_mark_removed(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DOSFS_FAT_FILE_H__ */
diff --git a/cpukit/libfs/src/dosfs/msdos.h b/cpukit/libfs/src/dosfs/msdos.h
new file mode 100644
index 0000000000..f1b7528715
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos.h
@@ -0,0 +1,434 @@
+/*
+ * msdos.h
+ *
+ * The MSDOS filesystem constants/data structures/prototypes
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+#ifndef __DOSFS_MSDOS_H__
+#define __DOSFS_MSDOS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_file.h"
+
+#define MSDOS_NAME_NOT_FOUND_ERR 0xDD000001
+
+typedef uint32_t msdos_status_t;
+
+/*
+ * This structure identifies the instance of the filesystem on the MSDOS
+ * level.
+ */
+typedef struct msdos_fs_info_s
+{
+ fat_fs_info_t fat; /*
+ * volume
+ * description
+ */
+ rtems_filesystem_file_handlers_r *directory_handlers; /*
+ * a set of routines
+ * that handles the
+ * nodes of directory
+ * type
+ */
+ rtems_filesystem_file_handlers_r *file_handlers; /*
+ * a set of routines
+ * that handles the
+ * nodes of file
+ * type
+ */
+ rtems_id vol_sema; /*
+ * semaphore
+ * associated with
+ * the volume
+ */
+ uint8_t *cl_buf; /*
+ * just placeholder
+ * for anything
+ */
+} msdos_fs_info_t;
+
+/* a set of routines that handle the nodes which are directories */
+extern rtems_filesystem_file_handlers_r msdos_dir_handlers;
+
+/* a set of routines that handle the nodes which are files */
+extern rtems_filesystem_file_handlers_r msdos_file_handlers;
+
+/* Volume semaphore timeout value. This value can be changed to a number
+ * of ticks to help debugging or if you need such a */
+#define MSDOS_VOLUME_SEMAPHORE_TIMEOUT RTEMS_NO_TIMEOUT
+
+/* Node types */
+#define MSDOS_DIRECTORY RTEMS_FILESYSTEM_DIRECTORY
+#define MSDOS_REGULAR_FILE RTEMS_FILESYSTEM_MEMORY_FILE
+#define MSDOS_HARD_LINK RTEMS_FILESYSTEM_HARD_LINK /* pseudo type */
+
+typedef rtems_filesystem_node_types_t msdos_node_type_t;
+
+/*
+ * Macros for fetching fields from 32 bytes long FAT Directory Entry
+ * Structure
+ */
+#define MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE 32 /* 32 bytes */
+
+#define MSDOS_DIR_NAME(x) (char *)((x) + 0)
+#define MSDOS_DIR_ATTR(x) (uint8_t *)((x) + 11)
+#define MSDOS_DIR_NT_RES(x) (uint8_t *)((x) + 12)
+#define MSDOS_DIR_CRT_TIME_TENTH(x) (uint8_t *)((x) + 13)
+#define MSDOS_DIR_CRT_TIME(x) (uint16_t *)((x) + 14)
+#define MSDOS_DIR_CRT_DATE(x) (uint16_t *)((x) + 16)
+#define MSDOS_DIR_LAST_ACCESS_DATE(x) (uint16_t *)((x) + 18)
+#define MSDOS_DIR_FIRST_CLUSTER_HI(x) (uint16_t *)((x) + 20)
+#define MSDOS_DIR_WRITE_TIME(x) (uint16_t *)((x) + 22)
+#define MSDOS_DIR_WRITE_DATE(x) (uint16_t *)((x) + 24)
+#define MSDOS_DIR_FIRST_CLUSTER_LOW(x) (uint16_t *)((x) + 26)
+#define MSDOS_DIR_FILE_SIZE(x) (uint32_t *)((x) + 28)
+
+#define MSDOS_EXTRACT_CLUSTER_NUM(p) \
+ (uint32_t )( (CF_LE_W(*MSDOS_DIR_FIRST_CLUSTER_LOW(p))) | \
+ ((uint32_t )(CF_LE_W((*MSDOS_DIR_FIRST_CLUSTER_HI(p))))<<16) )
+
+/*
+ * Fields offset in 32 bytes long FAT Directory Entry
+ * Structure
+ */
+#define MSDOS_FILE_SIZE_OFFSET 28
+#define MSDOS_FILE_NAME_OFFSET 0
+#define MSDOS_FIRST_CLUSTER_HI_OFFSET 20
+#define MSDOS_FIRST_CLUSTER_LOW_OFFSET 26
+#define MSDOS_FILE_WDATE_OFFSET 24
+#define MSDOS_FILE_WTIME_OFFSET 22
+
+/*
+ * Possible values of DIR_Attr field of 32 bytes long FAT Directory Entry
+ * Structure
+ */
+#define MSDOS_ATTR_READ_ONLY 0x01
+#define MSDOS_ATTR_HIDDEN 0x02
+#define MSDOS_ATTR_SYSTEM 0x04
+#define MSDOS_ATTR_VOLUME_ID 0x08
+#define MSDOS_ATTR_DIRECTORY 0x10
+#define MSDOS_ATTR_ARCHIVE 0x20
+
+#define MSDOS_DT_2SECONDS_MASK 0x1F /* seconds divided by 2 */
+#define MSDOS_DT_2SECONDS_SHIFT 0
+#define MSDOS_DT_MINUTES_MASK 0x7E0 /* minutes */
+#define MSDOS_DT_MINUTES_SHIFT 5
+#define MSDOS_DT_HOURS_MASK 0xF800 /* hours */
+#define MSDOS_DT_HOURS_SHIFT 11
+
+#define MSDOS_DD_DAY_MASK 0x1F /* day of month */
+#define MSDOS_DD_DAY_SHIFT 0
+#define MSDOS_DD_MONTH_MASK 0x1E0 /* month */
+#define MSDOS_DD_MONTH_SHIFT 5
+#define MSDOS_DD_YEAR_MASK 0xFE00 /* year - 1980 */
+#define MSDOS_DD_YEAR_SHIFT 9
+
+
+/*
+ * Possible values of DIR_Name[0] field of 32 bytes long FAT Directory Entry
+ * Structure
+ */
+#define MSDOS_THIS_DIR_ENTRY_EMPTY 0xE5
+#define MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY 0x00
+
+
+/*
+ * Macros for names parsing and formatting
+ */
+#define msdos_is_valid_name_char(_ch) (1)
+#define msdos_is_separator(_ch) rtems_filesystem_is_separator(_ch)
+
+#define MSDOS_SHORT_BASE_LEN 8 /* 8 characters */
+#define MSDOS_SHORT_EXT_LEN 3 /* 3 characters */
+#define MSDOS_SHORT_NAME_LEN (MSDOS_SHORT_BASE_LEN+\
+ MSDOS_SHORT_EXT_LEN) /* 11 chars */
+#define MSDOS_NAME_MAX MSDOS_SHORT_NAME_LEN
+#define MSDOS_NAME_MAX_WITH_DOT (MSDOS_NAME_MAX + 1)
+
+#define MSDOS_DOT_NAME ". " /* ".", padded to MSDOS_NAME chars */
+#define MSDOS_DOTDOT_NAME ".. " /* "..", padded to MSDOS_NAME chars */
+
+typedef enum msdos_token_types_e
+{
+ MSDOS_NO_MORE_PATH,
+ MSDOS_CURRENT_DIR,
+ MSDOS_UP_DIR,
+ MSDOS_NAME,
+ MSDOS_INVALID_TOKEN
+} msdos_token_types_t;
+
+/* Others macros */
+#define MSDOS_RES_NT_VALUE 0x00
+#define MSDOS_INIT_DIR_SIZE 0x00
+
+/* "dot" entry offset in a directory */
+#define MSDOS_DOT_DIR_ENTRY_OFFSET 0x00 /* first entry in directory */
+
+/* "dotdot" entry offset in a directory */
+#define MSDOS_DOTDOT_DIR_ENTRY_OFFSET 0x20 /* second entry in directory */
+
+/* 'p' should be char* */
+#define DOT_NODE_P(p) ((char *)(p))
+#define DOTDOT_NODE_P(p) ((char *)((p) + MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE))
+
+/* Size limits for files and directories */
+#define MSDOS_MAX_DIR_LENGHT 0x200000 /* 2,097,152 bytes */
+#define MSDOS_MAX_FILE_SIZE 0xFFFFFFFF /* 4 Gb */
+
+/*
+ * The number of 32 bytes long FAT Directory Entry
+ * Structures per 512 bytes sector
+ */
+#define MSDOS_DPS512_NUM 16
+
+/* Prototypes */
+msdos_status_t
+msdos_initialize(rtems_filesystem_mount_table_entry_t *temp_mt_entry);
+
+msdos_status_t
+msdos_shut_down(rtems_filesystem_mount_table_entry_t *temp_mt_entry);
+
+msdos_status_t
+msdos_eval_path(const char *pathname, /* IN */
+ int flags, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */);
+
+msdos_status_t
+msdos_eval4make(const char *path, /* IN */
+ rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
+ const char **name /* OUT */);
+
+int
+msdos_unlink(rtems_filesystem_location_info_t *pathloc /* IN */);
+
+msdos_status_t
+msdos_free_node_info(rtems_filesystem_location_info_t *pathloc /* IN */);
+
+rtems_filesystem_node_types_t
+msdos_node_type(rtems_filesystem_location_info_t *pathloc);
+
+msdos_status_t
+msdos_mknod(const char *path, /* IN */
+ mode_t mode, /* IN */
+ dev_t dev, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */);
+
+msdos_status_t
+msdos_utime(rtems_filesystem_location_info_t *pathloc, /* IN */
+ time_t actime, /* IN */
+ time_t modtime /* IN */);
+
+int
+msdos_initialize_support(
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry,
+ rtems_filesystem_operations_table *op_table,
+ rtems_filesystem_file_handlers_r *file_handlers,
+ rtems_filesystem_file_handlers_r *directory_handlers
+);
+
+int
+msdos_file_open(
+ rtems_libio_t *iop, /* IN */
+ const char *pathname, /* IN */
+ uint32_t flag, /* IN */
+ uint32_t mode /* IN */
+);
+
+int
+msdos_file_close(rtems_libio_t *iop /* IN */);
+
+ssize_t
+msdos_file_read(
+ rtems_libio_t *iop, /* IN */
+ void *buffer, /* IN */
+ uint32_t count /* IN */
+);
+
+ssize_t
+msdos_file_write(
+ rtems_libio_t *iop, /* IN */
+ const void *buffer, /* IN */
+ uint32_t count /* IN */
+);
+
+int
+msdos_file_lseek(
+ rtems_libio_t *iop, /* IN */
+ off_t offset, /* IN */
+ int whence /* IN */
+);
+
+int
+msdos_file_stat(rtems_filesystem_location_info_t *loc, /* IN */
+ struct stat *buf /* OUT */);
+
+int
+msdos_file_ftruncate(
+ rtems_libio_t *iop, /* IN */
+ off_t length /* IN */
+);
+
+int
+msdos_file_sync(rtems_libio_t *iop);
+
+int
+msdos_file_datasync(rtems_libio_t *iop);
+
+int
+msdos_file_ioctl(
+ rtems_libio_t *iop, /* IN */
+ uint32_t command, /* IN */
+ void *buffer /* IN */
+);
+
+msdos_status_t
+msdos_file_rmnod(rtems_filesystem_location_info_t *pathloc /* IN */);
+
+msdos_status_t
+msdos_file_link(rtems_filesystem_location_info_t *to_loc,
+ rtems_filesystem_location_info_t *pa_loc,
+ const char *token);
+
+int
+msdos_dir_open(
+ rtems_libio_t *iop, /* IN */
+ const char *pathname, /* IN */
+ uint32_t flag, /* IN */
+ uint32_t mode /* IN */
+);
+
+int
+msdos_dir_close(rtems_libio_t *iop /* IN */);
+
+ssize_t
+msdos_dir_read(
+ rtems_libio_t *iop, /* IN */
+ void *buffer, /* IN */
+ uint32_t count /* IN */
+);
+
+int
+msdos_dir_lseek(
+ rtems_libio_t *iop, /* IN */
+ off_t offset, /* IN */
+ int whence /* IN */
+);
+
+int
+msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc /* IN */);
+
+int
+msdos_dir_sync(rtems_libio_t *iop);
+
+int
+msdos_dir_stat(
+ rtems_filesystem_location_info_t *loc, /* IN */
+ struct stat *buf /* OUT */
+);
+
+int
+msdos_creat_node(rtems_filesystem_location_info_t *parent_loc,
+ msdos_node_type_t type,
+ char *name,
+ mode_t mode,
+ const fat_file_fd_t *link_fd);
+
+/* Misc prototypes */
+msdos_token_types_t msdos_get_token(const char *path,
+ char *token,
+ int *token_len);
+
+int
+msdos_find_name(rtems_filesystem_location_info_t *parent_loc,
+ char *name);
+
+msdos_status_t
+msdos_get_name_node(rtems_filesystem_location_info_t *parent_loc,
+ char *name,
+ fat_auxiliary_t *paux,
+ char *name_dir_entry);
+
+int
+msdos_dir_info_remove(rtems_filesystem_location_info_t *pathloc);
+
+int
+msdos_filename_unix2dos(char *un, int unlen, char *dn);
+
+void
+msdos_date_unix2dos(unsigned int tsp, unsigned short *ddp,
+ unsigned short *dtp);
+
+unsigned int
+msdos_date_dos2unix(unsigned int dd, unsigned int dt);
+
+int
+msdos_set_first_cluster_num(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd);
+
+int
+msdos_set_file_size(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd);
+
+int
+msdos_set_first_char4file_name(rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cl,
+ uint32_t ofs,
+ unsigned char first_char);
+
+int
+msdos_set_dir_wrt_time_and_date(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd
+);
+
+
+int
+msdos_dir_is_empty(rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ rtems_boolean *ret_val);
+
+msdos_status_t
+msdos_find_name_in_fat_file(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ char *name,
+ fat_auxiliary_t *paux,
+ char *name_dir_entry);
+
+msdos_status_t
+msdos_find_node_by_cluster_num_in_fat_file(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t cl4find,
+ fat_auxiliary_t *paux,
+ char *dir_entry
+);
+
+int
+msdos_get_dotdot_dir_info_cluster_num_and_offset(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ fat_auxiliary_t *paux,
+ char *dir_entry
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DOSFS_MSDOS_H__ */
diff --git a/cpukit/libfs/src/dosfs/msdos_conv.c b/cpukit/libfs/src/dosfs/msdos_conv.c
new file mode 100644
index 0000000000..b30822600b
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_conv.c
@@ -0,0 +1,273 @@
+/*
+ * Adaptation of NetBSD code for RTEMS by Victor V. Vengerov <vvv@oktet.ru>
+ */
+/* $NetBSD: msdosfs_conv.c,v 1.10 1994/12/27 18:36:24 mycroft Exp $ */
+/*
+ * Written by Paul Popelka (paulp@uts.amdahl.com)
+ *
+ * You can do anything you want with this software, just don't say you wrote
+ * it, and don't remove this notice.
+ *
+ * This software is provided "as is".
+ *
+ * The author supplies this software to be publicly redistributed on the
+ * understanding that the author is not responsible for the correct
+ * functioning of this software in any circumstances and is not liable for
+ * any damages caused by this software.
+ *
+ * October 1992
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include "msdos.h"
+
+/* #define SECONDSPERDAY (24 * 60 * 60) */
+#define SECONDSPERDAY ((uint32_t) 86400)
+
+/*
+ * Days in each month in a regular year.
+ */
+static uint16_t regyear[] = {
+ 31, 28, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31
+};
+
+/*
+ * Days in each month in a leap year.
+ */
+static uint16_t leapyear[] = {
+ 31, 29, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31
+};
+
+/*
+ * Variables used to remember parts of the last time conversion. Maybe we
+ * can avoid a full conversion.
+ */
+static uint32_t lasttime;
+static uint32_t lastday;
+static uint16_t lastddate;
+static uint16_t lastdtime;
+
+/*
+ * Convert the unix version of time to dos's idea of time to be used in
+ * file timestamps. The passed in unix time is assumed to be in GMT.
+ */
+void
+msdos_date_unix2dos(unsigned int t, unsigned short *ddp,
+ unsigned short *dtp)
+{
+ uint32_t days;
+ uint32_t inc;
+ uint32_t year;
+ uint32_t month;
+ uint16_t *months;
+
+ /*
+ * If the time from the last conversion is the same as now, then
+ * skip the computations and use the saved result.
+ */
+ if (lasttime != t) {
+ lasttime = t;
+ lastdtime = (((t % 60) >> 1) << MSDOS_DT_2SECONDS_SHIFT)
+ + (((t / 60) % 60) << MSDOS_DT_MINUTES_SHIFT)
+ + (((t / 3600) % 24) << MSDOS_DT_HOURS_SHIFT);
+
+ /*
+ * If the number of days since 1970 is the same as the last
+ * time we did the computation then skip all this leap year
+ * and month stuff.
+ */
+ days = t / (SECONDSPERDAY);
+ if (days != lastday) {
+ lastday = days;
+ for (year = 1970;; year++) {
+ inc = year & 0x03 ? 365 : 366;
+ if (days < inc)
+ break;
+ days -= inc;
+ }
+ months = year & 0x03 ? regyear : leapyear;
+ for (month = 0; month < 12; month++) {
+ if (days < months[month])
+ break;
+ days -= months[month];
+ }
+ lastddate = ((days + 1) << MSDOS_DD_DAY_SHIFT)
+ + ((month + 1) << MSDOS_DD_MONTH_SHIFT);
+ /*
+ * Remember dos's idea of time is relative to 1980.
+ * unix's is relative to 1970. If somehow we get a
+ * time before 1980 then don't give totally crazy
+ * results.
+ */
+ if (year > 1980)
+ lastddate += (year - 1980) <<
+ MSDOS_DD_YEAR_SHIFT;
+ }
+ }
+ *dtp = lastdtime;
+ *ddp = lastddate;
+}
+
+/*
+ * The number of days between Jan 1, 1970 and Jan 1, 1980. In that
+ * interval there were 8 regular years and 2 leap years.
+ */
+/* #define DAYSTO1980 ((8 * 365) + (2 * 366)) */
+#define DAYSTO1980 ((uint32_t) 3652)
+
+static uint16_t lastdosdate;
+static uint32_t lastseconds;
+
+/*
+ * Convert from dos' idea of time to unix'. This will probably only be
+ * called from the stat(), and fstat() system calls and so probably need
+ * not be too efficient.
+ */
+unsigned int
+msdos_date_dos2unix(unsigned int dd, unsigned int dt)
+{
+ uint32_t seconds;
+ uint32_t m, month;
+ uint32_t y, year;
+ uint32_t days;
+ uint16_t *months;
+
+ seconds = ((dt & MSDOS_DT_2SECONDS_MASK) >> MSDOS_DT_2SECONDS_SHIFT)
+ + ((dt & MSDOS_DT_MINUTES_MASK) >> MSDOS_DT_MINUTES_SHIFT) * 60
+ + ((dt & MSDOS_DT_HOURS_MASK) >> MSDOS_DT_HOURS_SHIFT) * 3600;
+ /*
+ * If the year, month, and day from the last conversion are the
+ * same then use the saved value.
+ */
+ if (lastdosdate != dd) {
+ lastdosdate = dd;
+ days = 0;
+ year = (dd & MSDOS_DD_YEAR_MASK) >> MSDOS_DD_YEAR_SHIFT;
+ for (y = 0; y < year; y++)
+ days += y & 0x03 ? 365 : 366;
+ months = year & 0x03 ? regyear : leapyear;
+ /*
+ * Prevent going from 0 to 0xffffffff in the following
+ * loop.
+ */
+ month = (dd & MSDOS_DD_MONTH_MASK) >> MSDOS_DD_MONTH_SHIFT;
+ if (month == 0) {
+ month = 1;
+ }
+ for (m = 0; m < month - 1; m++)
+ days += months[m];
+ days += ((dd & MSDOS_DD_DAY_MASK) >> MSDOS_DD_DAY_SHIFT) - 1;
+ lastseconds = (days + DAYSTO1980) * SECONDSPERDAY;
+ }
+ return seconds + lastseconds;
+}
+
+static const uint8_t msdos_map[] = {
+/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 20 */ 0x00, 0x21, 0x00, 0x23, 0x24, 0x25, 0x26, 0x27, /* !"#$%&' */
+/* 28 */ 0x28, 0x29, 0x00, 0x00, 0x00, 0x2D, 0x2E, 0x00, /* ()*+,-./ */
+/* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 01234567 */
+/* 38 */ 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89:;<=>? */
+/* 40 */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* @ABCDEFG */
+/* 48 */ 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, /* HIJKLMNO */
+/* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* PQRSTUVW */
+/* 58 */ 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* XYZ[\]^_ */
+/* 60 */ 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* `abcdefg */
+/* 68 */ 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, /* hijklmno */
+/* 70 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* pqrstuvw */
+/* 78 */ 0x58, 0x59, 0x5A, 0x5B, 0x7C, 0x00, 0x7E, 0x00, /* xyz{|}~ */
+/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 88 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 98 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* B0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* B8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* C0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* C8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* D0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* D8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+/*
+ * Convert a unix filename to a DOS filename. Return -1 if wrong name is
+ * supplied.
+ */
+int
+msdos_filename_unix2dos(char *un, int unlen, char *dn)
+{
+ int i;
+ uint8_t c;
+
+ /*
+ * Fill the dos filename string with blanks. These are DOS's pad
+ * characters.
+ */
+ for (i = 0; i <= 10; i++)
+ dn[i] = ' ';
+
+ /*
+ * The filenames "." and ".." are handled specially, since they
+ * don't follow dos filename rules.
+ */
+ if (un[0] == '.' && unlen == 1) {
+ dn[0] = '.';
+ return 0;
+ }
+ if (un[0] == '.' && un[1] == '.' && unlen == 2) {
+ dn[0] = '.';
+ dn[1] = '.';
+ return 0;
+ }
+
+ /*
+ * Copy the unix filename into the dos filename string upto the end
+ * of string, a '.', or 8 characters. Whichever happens first stops
+ * us. This forms the name portion of the dos filename. Fold to
+ * upper case.
+ */
+ for (i = 0; i <= 7 && unlen && (c = *un) && c != '.'; i++) {
+ if ((dn[i] = msdos_map[c]) == 0)
+ return -1;
+ un++;
+ unlen--;
+ }
+
+ /*
+ * Strip any further characters up to a '.' or the end of the
+ * string.
+ */
+ while (unlen && (c = *un)) {
+ un++;
+ unlen--;
+ /* Make sure we've skipped over the dot before stopping. */
+ if (c == '.')
+ break;
+ }
+
+ /*
+ * Copy in the extension part of the name, if any. Force to upper
+ * case. Note that the extension is allowed to contain '.'s.
+ * Filenames in this form are probably inaccessable under dos.
+ */
+ for (i = 8; i <= 10 && unlen && (c = *un); i++) {
+ if ((dn[i] = msdos_map[c]) == 0)
+ return -1;
+ un++;
+ unlen--;
+ }
+ return 0;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_create.c b/cpukit/libfs/src/dosfs/msdos_create.c
new file mode 100644
index 0000000000..280e2de31c
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_create.c
@@ -0,0 +1,345 @@
+/*
+ * Routine to create a new MSDOS filesystem node
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ *
+ */
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rtems/libio_.h>
+#include <time.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "fat_file.h"
+
+#include "msdos.h"
+
+/* msdos_creat_node --
+ * Create a new node. If a new node is file, FAT 32 Bytes Directory
+ * Entry Structure is initialized, free space is found in parent
+ * directory and structure is written to the disk. In case of directory,
+ * all above steps present and also new cluster is allocated for a
+ * new directory and dot and dotdot nodes are created in alloceted cluster.
+ *
+ * PARAMETERS:
+ * parent_loc - parent (directory we are going to create node in)
+ * type - new node type (file or directory)
+ * name - new node name
+ * mode - mode
+ * link_info - fs_info of existing node for a pseudo "hard-link"
+ * (see msdos_file.c, msdos_link for documentation)
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set appropriately).
+ *
+ */
+int
+msdos_creat_node(
+ rtems_filesystem_location_info_t *parent_loc,
+ msdos_node_type_t type,
+ char *name,
+ mode_t mode,
+ const fat_file_fd_t *link_fd
+ )
+{
+ int rc = RC_OK;
+ ssize_t ret = 0;
+ msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info;
+ fat_file_fd_t *parent_fat_fd = parent_loc->node_access;
+ fat_file_fd_t *fat_fd = NULL;
+ time_t time_ret = 0;
+ uint16_t time_val = 0;
+ uint16_t date = 0;
+ fat_auxiliary_t aux;
+ char new_node [MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
+ char dot_dotdot[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2];
+ char link_node [MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
+ uint32_t sec = 0;
+ uint32_t byte = 0;
+
+ memset(new_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
+ memset(dot_dotdot, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2);
+
+ /* set up name */
+ strncpy(MSDOS_DIR_NAME(new_node), name, MSDOS_NAME_MAX);
+
+ /* fill reserved field */
+ *MSDOS_DIR_NT_RES(new_node) = MSDOS_RES_NT_VALUE;
+
+ /* set up last write date and time */
+ time_ret = time(NULL);
+ if ( time_ret == -1 )
+ return -1;
+
+ msdos_date_unix2dos(time_ret, &time_val, &date);
+ *MSDOS_DIR_WRITE_TIME(new_node) = CT_LE_W(time_val);
+ *MSDOS_DIR_WRITE_DATE(new_node) = CT_LE_W(date);
+
+ /* initialize directory/file size */
+ *MSDOS_DIR_FILE_SIZE(new_node) = MSDOS_INIT_DIR_SIZE;
+
+ if (type == MSDOS_DIRECTORY){
+ *MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_DIRECTORY;
+ }
+ else if (type == MSDOS_HARD_LINK) {
+ /*
+ * when we establish a (temporary) hard link,
+ * we must copy some information from the original
+ * node to the newly created
+ */
+ /*
+ * read the original directory entry
+ */
+ sec = fat_cluster_num_to_sector_num(parent_loc->mt_entry,
+ link_fd->info_cln);
+ sec += (link_fd->info_ofs >> fs_info->fat.vol.sec_log2);
+ byte = (link_fd->info_ofs & (fs_info->fat.vol.bps - 1));
+
+ ret = _fat_block_read(parent_loc->mt_entry,
+ sec, byte, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,
+ link_node);
+ if (ret < 0) {
+ return -1;
+ }
+ /*
+ * copy various attributes
+ */
+ *MSDOS_DIR_ATTR(new_node) =*MSDOS_DIR_ATTR(link_node);
+ *MSDOS_DIR_CRT_TIME_TENTH(new_node)=*MSDOS_DIR_CRT_TIME_TENTH(link_node);
+ *MSDOS_DIR_CRT_TIME(new_node) =*MSDOS_DIR_CRT_TIME(link_node);
+ *MSDOS_DIR_CRT_DATE(new_node) =*MSDOS_DIR_CRT_DATE(link_node);
+
+ /*
+ * copy/set "file size", "first cluster"
+ */
+ *MSDOS_DIR_FILE_SIZE(new_node) =*MSDOS_DIR_FILE_SIZE(link_node);
+
+ *MSDOS_DIR_FIRST_CLUSTER_LOW(new_node) =
+ *MSDOS_DIR_FIRST_CLUSTER_LOW(link_node);
+ *MSDOS_DIR_FIRST_CLUSTER_HI(new_node) =
+ *MSDOS_DIR_FIRST_CLUSTER_HI(link_node);
+ /*
+ * set "archive bit" due to changes
+ */
+ *MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_ARCHIVE;
+ /*
+ * set "last access" date to today
+ */
+ *MSDOS_DIR_LAST_ACCESS_DATE(new_node) = CT_LE_W(date);
+ }
+ else { /* regular file... */
+ *MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_ARCHIVE;
+ }
+
+ /*
+ * find free space in the parent directory and write new initialized
+ * FAT 32 Bytes Directory Entry Structure to the disk
+ */
+ rc = msdos_get_name_node(parent_loc, NULL, &aux, new_node);
+ if ( rc != RC_OK )
+ return rc;
+
+ /*
+ * if we create a new file we are done, if directory there are more steps
+ * to do
+ */
+ if (type == MSDOS_DIRECTORY)
+ {
+ /* open new directory as fat-file */
+ rc = fat_file_open(parent_loc->mt_entry, aux.cln, aux.ofs, &fat_fd);
+ if (rc != RC_OK)
+ goto err;
+
+ /*
+ * we opened fat-file for node we just created, so initialize fat-file
+ * descritor
+ */
+ fat_fd->info_cln = aux.cln;
+ fat_fd->info_ofs = aux.ofs;
+ fat_fd->fat_file_size = 0;
+ fat_fd->fat_file_type = FAT_DIRECTORY;
+ fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT;
+
+ /*
+ * dot and dotdot entries are identical to new node except the
+ * names
+ */
+ memcpy(DOT_NODE_P(dot_dotdot), new_node,
+ MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
+ memcpy(DOTDOT_NODE_P(dot_dotdot), new_node,
+ MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
+ memcpy(MSDOS_DIR_NAME(DOT_NODE_P(dot_dotdot)), MSDOS_DOT_NAME,
+ MSDOS_NAME_MAX);
+ memcpy(MSDOS_DIR_NAME(DOTDOT_NODE_P(dot_dotdot)), MSDOS_DOTDOT_NAME,
+ MSDOS_NAME_MAX);
+
+ /* set up cluster num for dotdot entry */
+ /*
+ * here we can ommit FAT32 condition because for all FAT types dirs
+ * right under root dir should contain 0 in dotdot entry but for
+ * FAT12/16 parent_fat_fd->cluster_num always contains such value
+ */
+ if ((FAT_FD_OF_ROOT_DIR(parent_fat_fd)) &&
+ (fs_info->fat.vol.type & FAT_FAT32))
+ {
+ *MSDOS_DIR_FIRST_CLUSTER_LOW(DOTDOT_NODE_P(dot_dotdot)) = 0x0000;
+ *MSDOS_DIR_FIRST_CLUSTER_HI(DOTDOT_NODE_P(dot_dotdot)) = 0x0000;
+ }
+ else
+ {
+ *MSDOS_DIR_FIRST_CLUSTER_LOW(DOTDOT_NODE_P(dot_dotdot)) =
+ CT_LE_W((uint16_t )((parent_fat_fd->cln) & 0x0000FFFF));
+ *MSDOS_DIR_FIRST_CLUSTER_HI(DOTDOT_NODE_P(dot_dotdot)) =
+ CT_LE_W((uint16_t )(((parent_fat_fd->cln) & 0xFFFF0000)>>16));
+ }
+
+ /*
+ * write dot and dotdot entries to new fat-file: currently fat-file
+ * correspondes to a new node is zero length, so it will be extended
+ * by one cluster and entries will be written
+ */
+ ret = fat_file_write(parent_loc->mt_entry, fat_fd, 0,
+ MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2,
+ (uint8_t *)dot_dotdot);
+ if (ret < 0)
+ {
+ rc = -1;
+ goto error;
+ }
+
+ /* increment fat-file size by cluster size */
+ fat_fd->fat_file_size += fs_info->fat.vol.bpc;
+
+ /* set up cluster num for dot entry */
+ *MSDOS_DIR_FIRST_CLUSTER_LOW(DOT_NODE_P(dot_dotdot)) =
+ CT_LE_W((uint16_t )((fat_fd->cln) & 0x0000FFFF));
+ *MSDOS_DIR_FIRST_CLUSTER_HI(DOT_NODE_P(dot_dotdot)) =
+ CT_LE_W((uint16_t )(((fat_fd->cln) & 0xFFFF0000) >> 16));
+
+ /* rewrite dot entry */
+ ret = fat_file_write(parent_loc->mt_entry, fat_fd, 0,
+ MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,
+ (uint8_t *)DOT_NODE_P(dot_dotdot));
+ if (ret < 0)
+ {
+ rc = -1;
+ goto error;
+ }
+
+ /* write first cluster num of a new directory to disk */
+ rc = msdos_set_first_cluster_num(parent_loc->mt_entry, fat_fd);
+ if (rc != RC_OK)
+ goto error;
+
+ fat_file_close(parent_loc->mt_entry, fat_fd);
+ }
+ return RC_OK;
+
+error:
+ fat_file_close(parent_loc->mt_entry, fat_fd);
+
+err:
+ /* mark 32bytes structure on the disk as free */
+ msdos_set_first_char4file_name(parent_loc->mt_entry, aux.cln, aux.ofs,
+ 0xE5);
+ return rc;
+}
+
+/* msdos_file_link --
+ * Replacement for a file "link" operation.
+ * MSDOS FAT FS does not support links, but this call is needed to
+ * allow "rename" operations. The current NEWLIB rename performs a link
+ * from the old to the new name and then deletes the old filename.
+ *
+ * This pseudo-"link" operation will create a new directory entry,
+ * copy the file size and cluster information from the "old"
+ * to the "new" directory entry and then clear the file size and cluster
+ * info from the "old" filename, leaving this file as
+ * a valid, but empty entry.
+ *
+ * When this "link" call is part of a "rename" sequence, the "old"
+ * entry will be deleted in a subsequent "rmnod" call
+ *
+ * This function has been implemented by Thomas Doerfler,
+ * <Thomas.Doerfler@imd-systems.de>
+ *
+ * PARAMETERS:
+ * to_loc - node description for "existing" node
+ * par_loc - node description for "new" node
+ * token - name of new node
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set appropriately)
+ */
+msdos_status_t
+msdos_file_link(rtems_filesystem_location_info_t *to_loc,
+ rtems_filesystem_location_info_t *par_loc,
+ const char *token
+)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = to_loc->mt_entry->fs_info;
+ fat_file_fd_t *to_fat_fd = to_loc->node_access;
+ char new_name[ MSDOS_NAME_MAX + 1 ];
+ int len;
+
+ /*
+ * check spelling and format new node name
+ */
+ if (MSDOS_NAME != msdos_get_token(token, new_name, &len)) {
+ set_errno_and_return_minus_one(ENAMETOOLONG);
+ }
+ /*
+ * verify, that the existing node can be linked to
+ * check that nodes are in same FS/volume?
+ */
+ if (to_loc->mt_entry->fs_info != par_loc->mt_entry->fs_info) {
+ set_errno_and_return_minus_one(EXDEV);
+ }
+ /*
+ * lock volume
+ */
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+
+ /*
+ * create new directory entry as "hard link",
+ * copying relevant info from existing file
+ */
+ rc = msdos_creat_node(par_loc,MSDOS_HARD_LINK,new_name,S_IFREG,
+ to_loc->node_access);
+ /*
+ * set file size and first cluster number of old entry to 0
+ */
+ if (rc == RC_OK) {
+ to_fat_fd->fat_file_size = 0;
+ to_fat_fd->cln = FAT_EOF;
+ rc = msdos_set_first_cluster_num(to_loc->mt_entry, to_fat_fd);
+ if (rc == RC_OK) {
+ rc = msdos_set_file_size(par_loc->mt_entry, to_fat_fd);
+ }
+ }
+ /*
+ * FIXME: check error/abort handling
+ */
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_dir.c b/cpukit/libfs/src/dosfs/msdos_dir.c
new file mode 100644
index 0000000000..38699a73a7
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_dir.c
@@ -0,0 +1,554 @@
+/*
+ * MSDOS directory handlers implementation
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <rtems/libio_.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "fat_file.h"
+
+#include "msdos.h"
+
+/* msdos_dir_open --
+ * Open fat-file which correspondes to the directory being opened and
+ * set offset field of file control block to zero.
+ *
+ * PARAMETERS:
+ * iop - file control block
+ * pathname - name
+ * flag - flags
+ * mode - mode
+ *
+ * RETURNS:
+ * RC_OK, if directory opened successfully, or -1 if error occured (errno
+ * set apropriately)
+ */
+int
+msdos_dir_open(rtems_libio_t *iop, const char *pathname, uint32_t flag,
+ uint32_t mode)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = iop->file_info;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one( EIO );
+
+ rc = fat_file_reopen(fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ iop->offset = 0;
+ rtems_semaphore_release(fs_info->vol_sema);
+ return RC_OK;
+}
+
+/* msdos_dir_close --
+ * Close fat-file which correspondes to the directory being closed
+ *
+ * PARAMETERS:
+ * iop - file control block
+ *
+ * RETURNS:
+ * RC_OK, if directory closed successfully, or -1 if error occured (errno
+ * set apropriately.
+ */
+int
+msdos_dir_close(rtems_libio_t *iop)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = iop->file_info;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one( EIO );
+
+ rc = fat_file_close(iop->pathinfo.mt_entry, fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return RC_OK;
+}
+
+/* msdos_format_dirent_with_dot --
+ * This routine convert a (short) MSDOS filename as present on disk
+ * (fixed 8+3 characters, filled with blanks, without separator dot)
+ * to a "normal" format, with between 0 and 8 name chars,
+ * a separating dot and up to 3 extension characters
+ * Rules to work:
+ * - copy any (0-8) "name" part characters that are non-blank
+ * - if an extension exists, append a dot
+ * - copy any (0-3) non-blank extension characters
+ * - append a '\0' (dont count it for the rturn code
+ *
+ * PARAMETERS:
+ * dst: pointer to destination char array (must be big enough)
+ * src: pointer to source characters
+ *
+ *
+ * RETURNS:
+ * the number of bytes (without trailing '\0'(written to destination
+ */
+static ssize_t
+msdos_format_dirent_with_dot(char *dst,const char *src)
+{
+ ssize_t len;
+ int i;
+ const char *src_tmp;
+
+ /*
+ * find last non-blank character of base name
+ */
+ for ((i = MSDOS_SHORT_BASE_LEN ,
+ src_tmp = src + MSDOS_SHORT_BASE_LEN-1);
+ ((i > 0) &&
+ (*src_tmp == ' '));
+ i--,src_tmp--)
+ {};
+ /*
+ * copy base name to destination
+ */
+ src_tmp = src;
+ len = i;
+ while (i-- > 0) {
+ *dst++ = *src_tmp++;
+ }
+ /*
+ * find last non-blank character of extension
+ */
+ for ((i = MSDOS_SHORT_EXT_LEN ,
+ src_tmp = src + MSDOS_SHORT_BASE_LEN+MSDOS_SHORT_EXT_LEN-1);
+ ((i > 0) &&
+ (*src_tmp == ' '));
+ i--,src_tmp--)
+ {};
+ /*
+ * extension is not empty
+ */
+ if (i > 0) {
+ *dst++ = '.'; /* append dot */
+ len += i + 1; /* extension + dot */
+ src_tmp = src + MSDOS_SHORT_BASE_LEN;
+ while (i-- > 0) {
+ *dst++ = *src_tmp++;
+ len++;
+ }
+ }
+ *dst = '\0'; /* terminate string */
+
+ return len;
+}
+
+/* msdos_dir_read --
+ * This routine will read the next directory entry based on the directory
+ * offset. The offset should be equal to -n- time the size of an
+ * individual dirent structure. If n is not an integer multiple of the
+ * sizeof a dirent structure, an integer division will be performed to
+ * determine directory entry that will be returned in the buffer. Count
+ * should reflect -m- times the sizeof dirent bytes to be placed in the
+ * buffer.
+ * If there are not -m- dirent elements from the current directory
+ * position to the end of the exisiting file, the remaining entries will
+ * be placed in the buffer and the returned value will be equal to
+ * -m actual- times the size of a directory entry.
+ *
+ * PARAMETERS:
+ * iop - file control block
+ * buffer - buffer provided by user
+ * count - count of bytes to read
+ *
+ * RETURNS:
+ * the number of bytes read on success, or -1 if error occured (errno
+ * set apropriately).
+ */
+ssize_t
+msdos_dir_read(rtems_libio_t *iop, void *buffer, uint32_t count)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = iop->file_info;
+ fat_file_fd_t *tmp_fat_fd = NULL;
+ struct dirent tmp_dirent;
+ uint32_t start = 0;
+ ssize_t ret = 0;
+ uint32_t cmpltd = 0;
+ uint32_t j = 0, i = 0;
+ uint32_t bts2rd = 0;
+ uint32_t cur_cln = 0;
+
+ /*
+ * cast start and count - protect against using sizes that are not exact
+ * multiples of the -dirent- size. These could result in unexpected
+ * results
+ */
+ start = iop->offset / sizeof(struct dirent);
+ count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
+
+ /*
+ * optimization: we know that root directory for FAT12/16 volumes is
+ * sequential set of sectors and any cluster is sequential set of sectors
+ * too, so read such set of sectors is quick operation for low-level IO
+ * layer.
+ */
+ bts2rd = (FAT_FD_OF_ROOT_DIR(fat_fd) &&
+ (fs_info->fat.vol.type & (FAT_FAT12 | FAT_FAT16))) ?
+ fat_fd->fat_file_size :
+ fs_info->fat.vol.bpc;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ while (count > 0)
+ {
+ /*
+ * fat-file is already opened by open call, so read it
+ * Always read directory fat-file from the beggining because of MSDOS
+ * directories feature :( - we should count elements currently
+ * present in the directory because there may be holes :)
+ */
+ ret = fat_file_read(iop->pathinfo.mt_entry, fat_fd, (j * bts2rd),
+ bts2rd, fs_info->cl_buf);
+ if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ set_errno_and_return_minus_one(EIO);
+ }
+
+ for (i = 0; i < ret; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
+ {
+ if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
+ MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return cmpltd;
+ }
+
+ /* have to look at the DIR_NAME as "raw" 8-bit data */
+ if ((*(uint8_t *)MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
+ MSDOS_THIS_DIR_ENTRY_EMPTY)
+ continue;
+
+ /*
+ * skip active entries until get the entry to start from
+ */
+ if (start)
+ {
+ start--;
+ continue;
+ }
+
+ /*
+ * Move the entry to the return buffer
+ *
+ * unfortunately there is no method to extract ino except to
+ * open fat-file descriptor :( ... so, open it
+ */
+
+ /* get number of cluster we are working with */
+ rc = fat_file_ioctl(iop->pathinfo.mt_entry, fat_fd, F_CLU_NUM,
+ j * bts2rd, &cur_cln);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ rc = fat_file_open(iop->pathinfo.mt_entry, cur_cln, i,
+ &tmp_fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ tmp_fat_fd->info_cln = cur_cln;
+ tmp_fat_fd->info_ofs = i;
+
+ /* fill in dirent structure */
+ /* XXX: from what and in what d_off should be computed ?! */
+ tmp_dirent.d_off = start + cmpltd;
+ tmp_dirent.d_reclen = sizeof(struct dirent);
+ tmp_dirent.d_ino = tmp_fat_fd->ino;
+ /*
+ * convert dir entry from fixed 8+3 format (without dot)
+ * to 0..8 + 1dot + 0..3 format
+ */
+ tmp_dirent.d_namlen = msdos_format_dirent_with_dot(
+ tmp_dirent.d_name,
+ (char *) fs_info->cl_buf + i); /* src text */
+ memcpy(buffer + cmpltd, &tmp_dirent, sizeof(struct dirent));
+
+ iop->offset = iop->offset + sizeof(struct dirent);
+ cmpltd += (sizeof(struct dirent));
+ count -= (sizeof(struct dirent));
+
+ /* inode number extracted, close fat-file */
+ rc = fat_file_close(iop->pathinfo.mt_entry, tmp_fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ if (count <= 0)
+ break;
+ }
+ j++;
+ }
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return cmpltd;
+}
+
+/* msdos_dir_write --
+ * no write for directory
+ */
+
+/* msdos_dir_lseek --
+ *
+ * This routine will behave in one of three ways based on the state of
+ * argument whence. Based on the state of its value the offset argument will
+ * be interpreted using one of the following methods:
+ *
+ * SEEK_SET - offset is the absolute byte offset from the start of the
+ * logical start of the dirent sequence that represents the
+ * directory
+ * SEEK_CUR - offset is used as the relative byte offset from the current
+ * directory position index held in the iop structure
+ * SEEK_END - N/A --> This will cause an assert.
+ *
+ * PARAMETERS:
+ * iop - file control block
+ * offset - offset
+ * whence - predefine directive
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno
+ * set apropriately).
+ */
+int
+msdos_dir_lseek(rtems_libio_t *iop, off_t offset, int whence)
+{
+ switch (whence)
+ {
+ case SEEK_SET:
+ case SEEK_CUR:
+ break;
+ /*
+ * Movement past the end of the directory via lseek is not a
+ * permitted operation
+ */
+ case SEEK_END:
+ default:
+ set_errno_and_return_minus_one( EINVAL );
+ break;
+ }
+ return RC_OK;
+}
+
+/* msdos_dir_stat --
+ *
+ * This routine will obtain the following information concerning the current
+ * directory:
+ * st_dev device id
+ * st_ino node serial number :)
+ * st_mode mode extracted from the node
+ * st_size total size in bytes
+ * st_blksize blocksize for filesystem I/O
+ * st_blocks number of blocks allocated
+ * stat_mtime time of last modification
+ *
+ * PARAMETERS:
+ * loc - this directory
+ * buf - stat buffer provided by user
+ *
+ * RETURNS:
+ * RC_OK and filled stat buffer on success, or -1 if error occured (errno
+ * set apropriately).
+ */
+int
+msdos_dir_stat(
+ rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+ )
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = loc->mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = loc->node_access;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ buf->st_dev = fs_info->fat.vol.dev;
+ buf->st_ino = fat_fd->ino;
+ buf->st_mode = S_IFDIR;
+ buf->st_rdev = 0ll;
+ buf->st_size = fat_fd->fat_file_size;
+ buf->st_blocks = fat_fd->fat_file_size >> FAT_SECTOR512_BITS;
+ buf->st_blksize = fs_info->fat.vol.bps;
+ buf->st_mtime = fat_fd->mtime;
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return RC_OK;
+}
+
+/* msdos_dir_truncate --
+ * No truncate for directory.
+ *
+ * PARAMETERS:
+ *
+ * RETURNS:
+ *
+ */
+
+/* msdos_dir_sync --
+ * The following routine does a syncronization on a MSDOS directory node.
+ * DIR_WrtTime, DIR_WrtDate and DIR_fileSize fields of 32 Bytes Directory
+ * Entry Structure should not be updated for directories, so only call
+ * to corresponding fat-file routine.
+ *
+ * PARAMETERS:
+ * iop - file control block
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set apropriately).
+ */
+int
+msdos_dir_sync(rtems_libio_t *iop)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ fat_file_fd_t *fat_fd = iop->file_info;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd);
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+}
+
+/* msdos_dir_rmnod --
+ * Remove directory node.
+ *
+ * Check that this directory node is not opened as fat-file, is empty and
+ * not filesystem root node. If all this conditions met then delete.
+ *
+ * PARAMETERS:
+ * pathloc - node description
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set apropriately).
+ */
+int
+msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = pathloc->node_access;
+ rtems_boolean is_empty = FALSE;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ /*
+ * We deny attemp to delete open directory (if directory is current
+ * directory we assume it is open one)
+ */
+ if (fat_fd->links_num > 1)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ set_errno_and_return_minus_one(EBUSY);
+ }
+
+ /*
+ * You cannot remove a node that still has children
+ */
+ rc = msdos_dir_is_empty(pathloc->mt_entry, fat_fd, &is_empty);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ if (!is_empty)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ set_errno_and_return_minus_one(ENOTEMPTY);
+ }
+
+ /*
+ * You cannot remove the file system root node.
+ */
+ if (pathloc->mt_entry->mt_fs_root.node_access == pathloc->node_access)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ set_errno_and_return_minus_one(EBUSY);
+ }
+
+ /*
+ * You cannot remove a mountpoint.
+ * not used - mount() not implemenetd yet.
+ */
+
+ /* mark file removed */
+ rc = msdos_set_first_char4file_name(pathloc->mt_entry, fat_fd->info_cln,
+ fat_fd->info_ofs,
+ MSDOS_THIS_DIR_ENTRY_EMPTY);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ fat_file_mark_removed(pathloc->mt_entry, fat_fd);
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_eval.c b/cpukit/libfs/src/dosfs/msdos_eval.c
new file mode 100644
index 0000000000..dd614ace23
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_eval.c
@@ -0,0 +1,435 @@
+/*
+ * MSDOS evaluation routines
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "fat_file.h"
+
+#include "msdos.h"
+
+/* msdos_set_handlers --
+ * Set handlers for the node with specified type(i.e. handlers for file
+ * or directory).
+ *
+ * PARAMETERS:
+ * loc - node description
+ *
+ * RETURNS:
+ * None
+ */
+static void
+msdos_set_handlers(rtems_filesystem_location_info_t *loc)
+{
+ msdos_fs_info_t *fs_info = loc->mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = loc->node_access;
+
+ if (fat_fd->fat_file_type == FAT_DIRECTORY)
+ loc->handlers = fs_info->directory_handlers;
+ else
+ loc->handlers = fs_info->file_handlers;
+}
+
+/* msdos_eval_path --
+ *
+ * The following routine evaluate path for a node that wishes to be
+ * accessed. Structure 'pathloc' is returned with a pointer to the
+ * node to be accessed.
+ *
+ * PARAMETERS:
+ * pathname - path for evaluation
+ * flags - flags
+ * pathloc - node description (IN/OUT)
+ *
+ * RETURNS:
+ * RC_OK and filled pathloc on success, or -1 if error occured
+ * (errno set appropriately)
+ *
+ */
+msdos_status_t
+msdos_eval_path(
+ const char *pathname,
+ int flags,
+ rtems_filesystem_location_info_t *pathloc
+ )
+{
+ msdos_status_t rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = NULL;
+ rtems_filesystem_location_info_t newloc;
+ int i = 0;
+ int len = 0;
+ msdos_token_types_t type = MSDOS_CURRENT_DIR;
+ char token[MSDOS_NAME_MAX + 1];
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ if (!pathloc->node_access)
+ {
+ errno = ENOENT;
+ rc = -1;
+ goto err;
+ }
+
+ fat_fd = pathloc->node_access;
+
+ rc = fat_file_reopen(fat_fd);
+ if (rc != RC_OK)
+ goto err;
+
+ while ((type != MSDOS_NO_MORE_PATH) && (type != MSDOS_INVALID_TOKEN))
+ {
+ type = msdos_get_token(&pathname[i], token, &len);
+ i += len;
+
+ fat_fd = pathloc->node_access;
+
+ switch (type)
+ {
+ case MSDOS_UP_DIR:
+ /*
+ * Only a directory can be decended into.
+ */
+ if (fat_fd->fat_file_type != FAT_DIRECTORY)
+ {
+ errno = ENOTSUP;
+ rc = -1;
+ goto error;
+ }
+
+ /*
+ * Am I at the root of this mounted filesystem?
+ */
+ if (pathloc->node_access ==
+ pathloc->mt_entry->mt_fs_root.node_access)
+ {
+ /*
+ * Am I at the root of all filesystems?
+ * XXX: MSDOS is not supposed to be base fs.
+ */
+ if (pathloc->node_access ==
+ rtems_filesystem_root.node_access)
+ {
+ break; /* Throw out the .. in this case */
+ }
+ else
+ {
+ newloc = pathloc->mt_entry->mt_point_node;
+ *pathloc = newloc;
+
+ rc = fat_file_close(pathloc->mt_entry, fat_fd);
+ if (rc != RC_OK)
+ goto err;
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return (*pathloc->ops->evalpath_h)(&(pathname[i-len]),
+ flags, pathloc);
+ }
+ }
+ else
+ {
+ rc = msdos_find_name(pathloc, token);
+ if (rc != RC_OK)
+ {
+ if (rc == MSDOS_NAME_NOT_FOUND_ERR)
+ {
+ errno = ENOENT;
+ rc = -1;
+ }
+ goto error;
+ }
+ }
+ break;
+
+ case MSDOS_NAME:
+ /*
+ * Only a directory can be decended into.
+ */
+ if (fat_fd->fat_file_type != FAT_DIRECTORY)
+ {
+ errno = ENOTSUP;
+ rc = -1;
+ goto error;
+ }
+
+ /*
+ * Otherwise find the token name in the present location and
+ * set the node access to the point we have found.
+ */
+ rc = msdos_find_name(pathloc, token);
+ if (rc != RC_OK)
+ {
+ if (rc == MSDOS_NAME_NOT_FOUND_ERR)
+ {
+ errno = ENOENT;
+ rc = -1;
+ }
+ goto error;
+ }
+ break;
+
+ case MSDOS_NO_MORE_PATH:
+ case MSDOS_CURRENT_DIR:
+ break;
+
+ case MSDOS_INVALID_TOKEN:
+ errno = ENAMETOOLONG;
+ rc = -1;
+ goto error;
+ break;
+
+ }
+ }
+
+ /*
+ * Always return the root node.
+ *
+ * If we are at a node that is a mount point. Set loc to the
+ * new fs root node and let let the mounted filesystem set the handlers.
+ *
+ * NOTE: The behavior of stat() on a mount point appears to be
+ * questionable.
+ * NOTE: MSDOS filesystem currently doesn't support mount functionality ->
+ * action not implemented
+ */
+ fat_fd = pathloc->node_access;
+
+ msdos_set_handlers(pathloc);
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return RC_OK;
+
+error:
+ fat_file_close(pathloc->mt_entry, fat_fd);
+
+err:
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+}
+
+/* msdos_eval4make --
+ * The following routine evaluate path for a new node to be created.
+ * 'pathloc' is returned with a pointer to the parent of the new node.
+ * 'name' is returned with a pointer to the first character in the
+ * new node name. The parent node is verified to be a directory.
+ *
+ * PARAMETERS:
+ * path - path for evaluation
+ * pathloc - IN/OUT (start point for evaluation/parent directory for
+ * creation)
+ * name - new node name
+ *
+ * RETURNS:
+ * RC_OK, filled pathloc for parent directory and name of new node on
+ * success, or -1 if error occured (errno set appropriately)
+ */
+msdos_status_t
+msdos_eval4make(
+ const char *path,
+ rtems_filesystem_location_info_t *pathloc,
+ const char **name
+ )
+{
+ msdos_status_t rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = NULL;
+ rtems_filesystem_location_info_t newloc;
+ msdos_token_types_t type;
+ int i = 0;
+ int len;
+ char token[ MSDOS_NAME_MAX + 1 ];
+ rtems_boolean done = 0;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ if (!pathloc->node_access)
+ {
+ errno = ENOENT;
+ rc = -1;
+ goto err;
+ }
+
+ fat_fd = pathloc->node_access;
+
+ rc = fat_file_reopen(fat_fd);
+ if (rc != RC_OK)
+ goto err;
+
+ while (!done)
+ {
+ type = msdos_get_token(&path[i], token, &len);
+ i += len;
+ fat_fd = pathloc->node_access;
+
+ switch (type)
+ {
+ case MSDOS_UP_DIR:
+ /*
+ * Only a directory can be decended into.
+ */
+ if (fat_fd->fat_file_type != FAT_DIRECTORY)
+ {
+ errno = ENOTDIR;
+ rc = -1;
+ goto error;
+ }
+
+ /*
+ * Am I at the root of this mounted filesystem?
+ */
+ if (pathloc->node_access ==
+ pathloc->mt_entry->mt_fs_root.node_access)
+ {
+ /*
+ * Am I at the root of all filesystems?
+ * XXX: MSDOS is not supposed to be base fs.
+ */
+ if (pathloc->node_access ==
+ rtems_filesystem_root.node_access)
+ {
+ break; /* Throw out the .. in this case */
+ }
+ else
+ {
+ newloc = pathloc->mt_entry->mt_point_node;
+ *pathloc = newloc;
+
+ rc = fat_file_close(pathloc->mt_entry, fat_fd);
+ if (rc != RC_OK)
+ goto err;
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return (*pathloc->ops->evalformake_h)(&path[i-len],
+ pathloc, name);
+ }
+ }
+ else
+ {
+ rc = msdos_find_name(pathloc, token);
+ if (rc != RC_OK)
+ {
+ if (rc == MSDOS_NAME_NOT_FOUND_ERR)
+ {
+ errno = ENOENT;
+ rc = -1;
+ }
+ goto error;
+ }
+ }
+ break;
+
+ case MSDOS_NAME:
+ /*
+ * Only a directory can be decended into.
+ */
+ if (fat_fd->fat_file_type != FAT_DIRECTORY)
+ {
+ errno = ENOTDIR;
+ rc = -1;
+ goto error;
+ }
+
+ /*
+ * Otherwise find the token name in the present location and
+ * set the node access to the point we have found.
+ */
+ rc = msdos_find_name(pathloc, token);
+ if (rc)
+ {
+ if (rc != MSDOS_NAME_NOT_FOUND_ERR)
+ {
+ errno = ENOENT;
+ rc = -1;
+ goto error;
+ }
+ else
+ done = TRUE;
+ }
+ break;
+
+ case MSDOS_NO_MORE_PATH:
+ errno = EEXIST;
+ rc = -1;
+ goto error;
+ break;
+
+ case MSDOS_CURRENT_DIR:
+ break;
+
+ case MSDOS_INVALID_TOKEN:
+ errno = ENAMETOOLONG;
+ rc = -1;
+ goto error;
+ break;
+
+ }
+ }
+
+ *name = &path[i - len];
+
+ /*
+ * We have evaluated the path as far as we can.
+ * Verify there is not any invalid stuff at the end of the name.
+ */
+ for( ; path[i] != '\0'; i++)
+ {
+ if (!msdos_is_separator(path[i]))
+ {
+ errno = ENOENT;
+ rc = -1;
+ goto error;
+ }
+ }
+
+ fat_fd = pathloc->node_access;
+
+ if (fat_fd->fat_file_type != FAT_DIRECTORY)
+ {
+ errno = ENOTDIR;
+ rc = -1;
+ goto error;
+ }
+
+ msdos_set_handlers(pathloc);
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return RC_OK;
+
+error:
+ fat_file_close(pathloc->mt_entry, fat_fd);
+
+err:
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_file.c b/cpukit/libfs/src/dosfs/msdos_file.c
new file mode 100644
index 0000000000..12cf5ac6e7
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_file.c
@@ -0,0 +1,485 @@
+/*
+ * MSDOS file handlers implementation
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "fat_file.h"
+
+#include "msdos.h"
+
+/* msdos_file_open --
+ * Open fat-file which correspondes to the file
+ *
+ * PARAMETERS:
+ * iop - file control block
+ * pathname - name
+ * flag - flags
+ * mode - mode
+ *
+ * RETURNS:
+ * RC_OK, if file opened successfully, or -1 if error occured
+ * and errno set appropriately
+ */
+int
+msdos_file_open(rtems_libio_t *iop, const char *pathname, uint32_t flag,
+ uint32_t mode)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = iop->file_info;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ rc = fat_file_reopen(fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ if (iop->flags & LIBIO_FLAGS_APPEND)
+ iop->offset = fat_fd->fat_file_size;
+
+ iop->size = fat_fd->fat_file_size;
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return RC_OK;
+}
+
+/* msdos_file_close --
+ * Close fat-file which correspondes to the file. If fat-file descriptor
+ * which correspondes to the file is not marked "removed", synchronize
+ * size, first cluster number, write time and date fields of the file.
+ *
+ * PARAMETERS:
+ * iop - file control block
+ *
+ * RETURNS:
+ * RC_OK, if file closed successfully, or -1 if error occured (errno set
+ * appropriately)
+ */
+int
+msdos_file_close(rtems_libio_t *iop)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = iop->file_info;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ /*
+ * if fat-file descriptor is not marked as "removed", synchronize
+ * size, first cluster number, write time and date fields of the file
+ */
+ if (!FAT_FILE_IS_REMOVED(fat_fd))
+ {
+ rc = msdos_set_first_cluster_num(iop->pathinfo.mt_entry, fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ rc = msdos_set_file_size(iop->pathinfo.mt_entry, fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ rc = msdos_set_dir_wrt_time_and_date(iop->pathinfo.mt_entry, fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+ }
+
+ rc = fat_file_close(iop->pathinfo.mt_entry, fat_fd);
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+}
+
+/* msdos_file_read --
+ * This routine read from file pointed to by file control block into
+ * the specified data buffer provided by user
+ *
+ * PARAMETERS:
+ * iop - file control block
+ * buffer - buffer provided by user
+ * count - the number of bytes to read
+ *
+ * RETURNS:
+ * the number of bytes read on success, or -1 if error occured (errno set
+ * appropriately)
+ */
+ssize_t
+msdos_file_read(rtems_libio_t *iop, void *buffer, uint32_t count)
+{
+ ssize_t ret = 0;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = iop->file_info;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ ret = fat_file_read(iop->pathinfo.mt_entry, fat_fd, iop->offset, count,
+ buffer);
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return ret;
+}
+
+/* msdos_file_write --
+ * This routine writes the specified data buffer into the file pointed to
+ * by file control block.
+ *
+ * PARAMETERS:
+ * iop - file control block
+ * buffer - data to write
+ * count - count of bytes to write
+ *
+ * RETURNS:
+ * the number of bytes written on success, or -1 if error occured
+ * and errno set appropriately
+ */
+ssize_t
+msdos_file_write(rtems_libio_t *iop,const void *buffer, uint32_t count)
+{
+ ssize_t ret = 0;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = iop->file_info;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ ret = fat_file_write(iop->pathinfo.mt_entry, fat_fd, iop->offset, count,
+ buffer);
+ if (ret < 0)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return -1;
+ }
+
+ /*
+ * update file size in both fat-file descriptor and file control block if
+ * file was extended
+ */
+ if (iop->offset + ret > fat_fd->fat_file_size)
+ fat_fd->fat_file_size = iop->offset + ret;
+
+ iop->size = fat_fd->fat_file_size;
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return ret;
+}
+
+/* msdos_file_lseek --
+ * Process lseek call to the file: extend file if lseek is up to the end
+ * of the file.
+ *
+ * PARAMETERS:
+ * iop - file control block
+ * offset - new offset
+ * whence - predefine directive
+ *
+ * RETURNS:
+ * new offset on success, or -1 if error occured (errno set
+ * appropriately).
+ */
+int
+msdos_file_lseek(rtems_libio_t *iop, off_t offset, int whence)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = iop->file_info;
+ uint32_t real_size = 0;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ rc = fat_file_extend(iop->pathinfo.mt_entry, fat_fd, iop->offset,
+ &real_size);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ if (real_size > fat_fd->fat_file_size)
+ fat_fd->fat_file_size = iop->offset = real_size;
+
+ iop->size = fat_fd->fat_file_size;
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return iop->offset;
+}
+
+/* msdos_file_stat --
+ *
+ * PARAMETERS:
+ * loc - node description
+ * buf - stat buffer provided by user
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set appropriately)
+ */
+int
+msdos_file_stat(
+ rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+ )
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = loc->mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = loc->node_access;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ buf->st_dev = fs_info->fat.vol.dev;
+ buf->st_ino = fat_fd->ino;
+ buf->st_mode = S_IFREG;
+ buf->st_rdev = 0ll;
+ buf->st_size = fat_fd->fat_file_size;
+ buf->st_blocks = fat_fd->fat_file_size >> FAT_SECTOR512_BITS;
+ buf->st_blksize = fs_info->fat.vol.bps;
+ buf->st_mtime = fat_fd->mtime;
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return RC_OK;
+}
+
+/* msdos_file_ftruncate --
+ * Truncate the file (if new length is greater then current do nothing).
+ *
+ * PARAMETERS:
+ * iop - file control block
+ * length - new length
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set appropriately).
+ */
+int
+msdos_file_ftruncate(rtems_libio_t *iop, off_t length)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = iop->file_info;
+
+ if (length >= fat_fd->fat_file_size)
+ return RC_OK;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ rc = fat_file_truncate(iop->pathinfo.mt_entry, fat_fd, length);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ /*
+ * fat_file_truncate do nothing if new length >= fat-file size, so update
+ * file size only if length < fat-file size
+ */
+ if (length < fat_fd->fat_file_size)
+ iop->size = fat_fd->fat_file_size = length;
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return RC_OK;
+}
+
+/* msdos_file_sync --
+ * Synchronize file - synchronize file data and if file is not removed
+ * synchronize file metadata.
+ *
+ * PARAMETERS:
+ * iop - file control block
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set appropriately)
+ */
+int
+msdos_file_sync(rtems_libio_t *iop)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ fat_file_fd_t *fat_fd = iop->file_info;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ /* synchronize file data */
+ rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ /*
+ * if fat-file descriptor is not marked "removed" - synchronize file
+ * metadata
+ */
+ if (!FAT_FILE_IS_REMOVED(fat_fd))
+ {
+ rc = msdos_set_first_cluster_num(iop->pathinfo.mt_entry, fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+ rc = msdos_set_file_size(iop->pathinfo.mt_entry, fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+ rc = msdos_set_dir_wrt_time_and_date(iop->pathinfo.mt_entry, fat_fd);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+ }
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return RC_OK;
+}
+
+/* msdos_file_datasync --
+ * Synchronize file - synchronize only file data (metadata is letf intact).
+ *
+ * PARAMETERS:
+ * iop - file control block
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set appropriately)
+ */
+int
+msdos_file_datasync(rtems_libio_t *iop)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ fat_file_fd_t *fat_fd = iop->file_info;
+ msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ /* synchronize file data */
+ rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd);
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return RC_OK;
+}
+
+
+/* msdos_file_ioctl --
+ *
+ *
+ * PARAMETERS:
+ * iop - file control block
+ * ...
+ *
+ * RETURNS:
+ *
+ */
+int
+msdos_file_ioctl(rtems_libio_t *iop,uint32_t command, void *buffer)
+{
+ int rc = RC_OK;
+
+ return rc;
+}
+
+/* msdos_file_rmnod --
+ * Remove node associated with a file - set up first name character to
+ * predefined value(and write it to the disk), and mark fat-file which
+ * correspondes to the file as "removed"
+ *
+ * PARAMETERS:
+ * pathloc - node description
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set appropriately)
+ */
+msdos_status_t
+msdos_file_rmnod(rtems_filesystem_location_info_t *pathloc)
+{
+ msdos_status_t rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = pathloc->node_access;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ /* mark file removed */
+ rc = msdos_set_first_char4file_name(pathloc->mt_entry, fat_fd->info_cln,
+ fat_fd->info_ofs,
+ MSDOS_THIS_DIR_ENTRY_EMPTY);
+ if (rc != RC_OK)
+ {
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+ }
+
+ fat_file_mark_removed(pathloc->mt_entry, fat_fd);
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return RC_OK;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_format.c b/cpukit/libfs/src/dosfs/msdos_format.c
new file mode 100644
index 0000000000..ba3e1042d8
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_format.c
@@ -0,0 +1,1007 @@
+/*===============================================================*\
+| Project: RTEMS msdos format functionality |
++-----------------------------------------------------------------+
+| File: msdos_format.c |
++-----------------------------------------------------------------+
+| Copyright (c) 2004 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file contains msdos_format function. This function |
+| formats a disk partition conforming to MS-DOS conventions |
+| |
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| http://www.rtems.com/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 29.10.04 creation doe |
+\*===============================================================*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "msdos.h"
+#include "dosfs.h"
+
+typedef struct {
+ uint32_t bytes_per_sector;
+ uint32_t totl_sector_cnt;
+ uint32_t rsvd_sector_cnt;
+
+ uint32_t sectors_per_cluster;
+ uint32_t sectors_per_fat;
+
+ uint32_t fat_start_sec;
+ uint32_t files_per_root_dir;
+ uint32_t root_dir_sectors;
+ uint32_t root_dir_start_sec;
+ uint32_t root_dir_fmt_sec_cnt;
+ uint32_t mbr_copy_sec; /* location of copy of mbr or 0 */
+ uint32_t fsinfo_sec; /* location of fsinfo sector or 0 */
+ uint8_t fat_num;
+ uint8_t media_code;
+ uint8_t fattype;
+ char OEMName[FAT_BR_OEMNAME_SIZE+1];
+ char VolLabel[FAT_BR_VOLLAB_SIZE+1];
+ boolean VolLabel_present;
+ uint32_t vol_id;
+} msdos_format_param_t;
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+static int msdos_format_write_sec
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| function to write to a sector |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ int fd, /* file descriptor index */
+ uint32_t start_sector, /* sector number to write to */
+ uint32_t sector_size, /* size of sector */
+ const char *buffer /* buffer with write data */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+{
+ int ret_val = 0;
+
+ if (0 > lseek(fd,((off_t)start_sector)*sector_size,SEEK_SET)) {
+ ret_val = -1;
+ }
+ if (ret_val == 0) {
+ if (0 > write(fd,buffer,sector_size)) {
+ ret_val = -1;
+ }
+ }
+
+ return ret_val;
+}
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+static int msdos_format_fill_sectors
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| function to fill sectors with byte |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ int fd, /* file descriptor index */
+ uint32_t start_sector, /* sector number to fill to */
+ uint32_t sector_cnt, /* number of sectors to fill to */
+ uint32_t sector_size, /* size of sector */
+ const char fill_byte /* byte to fill into sectors */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+{
+ int ret_val = 0;
+ char *fill_buffer = NULL;
+
+ /*
+ * allocate and fill buffer
+ */
+ if (ret_val == 0) {
+ fill_buffer = malloc(sector_size);
+ if (fill_buffer == NULL) {
+ errno = ENOMEM;
+ ret_val = -1;
+ }
+ else {
+ memset(fill_buffer,fill_byte,sector_size);
+ }
+ }
+ /*
+ * write to consecutive sectors
+ */
+ while ((ret_val == 0) &&
+ (sector_cnt > 0)) {
+ ret_val = msdos_format_write_sec(fd,start_sector,sector_size,fill_buffer);
+ start_sector++;
+ sector_cnt--;
+ }
+ /*
+ * cleanup
+ */
+ if (fill_buffer != NULL) {
+ free(fill_buffer);
+ fill_buffer = NULL;
+ }
+ return ret_val;
+}
+
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+static int msdos_format_gen_volid
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| function to generate a pseudo-random volume id |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ uint32_t *volid_ptr /* volume ID return pointer */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+{
+ int ret_val = 0;
+ int rc;
+ rtems_clock_time_value time_value;
+
+ rc = rtems_clock_get(RTEMS_CLOCK_GET_TIME_VALUE,&time_value);
+ if (rc == RTEMS_SUCCESSFUL) {
+ *volid_ptr = time_value.seconds + time_value.microseconds;
+ }
+ else {
+ *volid_ptr = rand();
+ }
+
+ return ret_val;
+}
+
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+static int msdos_format_eval_sectors_per_cluster
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| function to check/adjust sectors_per_cluster to legal values |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ int fattype, /* type code of FAT (FAT_FAT12 ...) */
+ uint32_t bytes_per_sector, /* byte count per sector (512) */
+ uint32_t fatdata_sec_cnt, /* sectors available for FAT and data */
+ uint8_t fat_num, /* number of fat copies */
+ uint32_t sectors_per_cluster, /* sectors per cluster (requested) */
+ uint32_t *sectors_per_cluster_adj, /* ret: sec per cluster (granted) */
+ uint32_t *sectors_per_fat_ptr /* ret: sectors needed for one FAT */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+{
+
+ boolean finished = FALSE;
+ int ret_val = 0;
+ uint32_t fatdata_cluster_cnt;
+ uint32_t fat_capacity;
+ uint32_t sectors_per_fat;
+ uint32_t data_cluster_cnt;
+ /*
+ * ensure, that maximum cluster size (32KByte) is not exceeded
+ */
+ while (MS_BYTES_PER_CLUSTER_LIMIT / bytes_per_sector < sectors_per_cluster) {
+ sectors_per_cluster /= 2;
+ }
+
+ do {
+ /*
+ * compute number of data clusters for current data:
+ * - compute cluster count for data AND fat
+ * - compute storage size for FAT
+ * - subtract from total cluster count
+ */
+ fatdata_cluster_cnt = fatdata_sec_cnt/sectors_per_cluster;
+ if (fattype == FAT_FAT12) {
+ fat_capacity = fatdata_cluster_cnt * 3 / 2;
+ }
+ else if (fattype == FAT_FAT16) {
+ fat_capacity = fatdata_cluster_cnt * 2;
+ }
+ else { /* FAT32 */
+ fat_capacity = fatdata_cluster_cnt * 4;
+ }
+
+ sectors_per_fat = ((fat_capacity
+ + (bytes_per_sector - 1))
+ / bytes_per_sector);
+
+ data_cluster_cnt = (fatdata_cluster_cnt -
+ (((sectors_per_fat * fat_num)
+ + (sectors_per_cluster - 1))
+ / sectors_per_cluster));
+ /*
+ * data cluster count too big? then make sectors bigger
+ */
+ if (((fattype == FAT_FAT12) && (data_cluster_cnt > FAT_FAT12_MAX_CLN)) ||
+ ((fattype == FAT_FAT16) && (data_cluster_cnt > FAT_FAT16_MAX_CLN))) {
+ sectors_per_cluster *= 2;
+ }
+ else {
+ finished = TRUE;
+ }
+ /*
+ * when maximum cluster size is exceeded, we have invalid data, abort...
+ */
+ if ((sectors_per_cluster * bytes_per_sector)
+ > MS_BYTES_PER_CLUSTER_LIMIT) {
+ ret_val = EINVAL;
+ finished = TRUE;
+ }
+ } while (!finished);
+
+ if (ret_val != 0) {
+ set_errno_and_return_minus_one(ret_val);
+ }
+ else {
+ *sectors_per_cluster_adj = sectors_per_cluster;
+ *sectors_per_fat_ptr = sectors_per_fat;
+ return 0;
+ }
+}
+
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+static int msdos_format_determine_fmt_params
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| determine parameters for formatting |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ const disk_device *dd, /* disk device structure */
+ const msdos_format_request_param_t *rqdata, /* requested fmt parameters */
+ msdos_format_param_t *fmt_params/* computed fmt parameters */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+{
+ int ret_val = 0;
+ uint32_t fatdata_sect_cnt;
+ uint32_t onebit;
+ uint32_t sectors_per_cluster_adj = 0;
+
+ memset(fmt_params,0,sizeof(*fmt_params));
+ /*
+ * this one is fixed in this implementation.
+ * At least one thing we don't have to magically guess...
+ */
+ if (ret_val == 0) {
+ fmt_params->bytes_per_sector = dd->block_size;
+ fmt_params->totl_sector_cnt = dd->size;
+ }
+ /*
+ * determine number of FATs
+ */
+ if (ret_val == 0) {
+ if ((rqdata == NULL) ||
+ (rqdata->fat_num == 0)) {
+ fmt_params->fat_num = 2;
+ }
+ else if (rqdata->fat_num <= 6) {
+ fmt_params->fat_num = rqdata->fat_num;
+ }
+ else {
+ ret_val = EINVAL;
+ }
+ }
+ /*
+ * Now we get sort of a loop when determining things:
+ * The FAT type (FAT12/16/32) is determined ONLY from the
+ * data cluster count:
+ * Disks with data cluster count < 4085 are FAT12.
+ * Disks with data cluster count < 65525 are FAT16.
+ * The rest is FAT32 (no FAT128 available yet :-)
+ *
+ * The number of data clusters is the
+ * total capacity
+ * minus reserved sectors
+ * minus root directory ares
+ * minus storage needed for the FAT (and its copy/copies).
+ *
+ * The last item once again depends on the FAT type and the cluster count.
+ *
+ * So here is what we do in this formatter:
+ * - If a FAT type is requested from the caller, we try to modify
+ * the cluster size, until the data cluster count is in range
+ * - If no FAT type is given, we estimate a useful FAT type from
+ * the disk capacity and then adapt the cluster size
+ */
+
+ /*
+ * determine characteristic values:
+ * - number of sectors
+ * - number of reserved sectors
+ * - number of used sectors
+ * - sectors per cluster
+ */
+ /*
+ * determine FAT type and sectors per cluster
+ * depends on
+ */
+ if (ret_val == 0) {
+ fmt_params->sectors_per_cluster = 1;
+ if ((rqdata != NULL) &&
+ (rqdata->fattype == MSDOS_FMT_FAT12)) {
+ fmt_params->fattype = FAT_FAT12;
+ }
+ else if ((rqdata != NULL) &&
+ (rqdata->fattype == MSDOS_FMT_FAT16)) {
+ fmt_params->fattype = FAT_FAT16;
+ }
+ else if ((rqdata != NULL) &&
+ (rqdata->fattype == MSDOS_FMT_FAT32)) {
+ fmt_params->fattype = FAT_FAT32;
+ }
+ else if ((rqdata != NULL) &&
+ (rqdata->fattype != MSDOS_FMT_FATANY)) {
+ ret_val = -1;
+ errno = EINVAL;
+ }
+ else {
+ /*
+ * limiting values for disk size, fat type, sectors per cluster
+ * NOTE: maximum sect_per_clust is arbitrarily choosen with values that
+ * are a compromise concerning capacity and efficency
+ */
+ if (fmt_params->totl_sector_cnt
+ < ((uint32_t)FAT_FAT12_MAX_CLN)*8) {
+ fmt_params->fattype = FAT_FAT12;
+ /* start trying with small clusters */
+ fmt_params->sectors_per_cluster = 2;
+ }
+ else if (fmt_params->totl_sector_cnt
+ < ((uint32_t)FAT_FAT16_MAX_CLN)*32) {
+ fmt_params->fattype = FAT_FAT16;
+ /* start trying with small clusters */
+ fmt_params->sectors_per_cluster = 2;
+ }
+ else {
+ fmt_params->fattype = FAT_FAT32;
+ /* start trying with small clusters... */
+ fmt_params->sectors_per_cluster = 1;
+ }
+ }
+ /*
+ * try to use user requested cluster size
+ */
+ if ((rqdata != NULL) &&
+ (rqdata->sectors_per_cluster > 0)) {
+ fmt_params->sectors_per_cluster =
+ rqdata->sectors_per_cluster;
+ }
+ /*
+ * check sectors per cluster.
+ * must be power of 2
+ * must be smaller than or equal to 128
+ * sectors_per_cluster*bytes_per_sector must not be bigger than 32K
+ */
+ for (onebit = 128;onebit >= 1;onebit = onebit>>1) {
+ if (fmt_params->sectors_per_cluster > onebit) {
+ fmt_params->sectors_per_cluster = onebit;
+ if (fmt_params->sectors_per_cluster
+ <= 32768L/fmt_params->bytes_per_sector) {
+ /* value is small enough so this value is ok */
+ onebit = 1;
+ }
+ }
+ }
+ }
+
+ if (ret_val == 0) {
+ if (fmt_params->fattype == FAT_FAT32) {
+ /* recommended: for FAT32, always set reserved sector count to 32 */
+ fmt_params->rsvd_sector_cnt = 32;
+ /* for FAT32, always set files per root directory 0 */
+ fmt_params->files_per_root_dir = 0;
+ /* location of copy of MBR */
+ fmt_params->mbr_copy_sec = 6;
+ /* location of fsinfo sector */
+ fmt_params->fsinfo_sec = 1;
+
+ }
+ else {
+ /* recommended: for FAT12/FAT16, always set reserved sector count to 1 */
+ fmt_params->rsvd_sector_cnt = 1;
+ /* recommended: for FAT16, set files per root directory to 512 */
+ /* for FAT12/FAT16, set files per root directory */
+ /* must fill up an even count of sectors */
+ if ((rqdata != NULL) &&
+ (rqdata->files_per_root_dir > 0)) {
+ fmt_params->files_per_root_dir = rqdata->files_per_root_dir;
+ }
+ else {
+ if (fmt_params->fattype == FAT_FAT16) {
+ fmt_params->files_per_root_dir = 512;
+ }
+ else {
+ fmt_params->files_per_root_dir = 64;
+ }
+ }
+ fmt_params->files_per_root_dir = (fmt_params->files_per_root_dir +
+ (2*fmt_params->bytes_per_sector/
+ FAT_DIRENTRY_SIZE-1));
+ fmt_params->files_per_root_dir -= (fmt_params->files_per_root_dir %
+ (2*fmt_params->bytes_per_sector
+ /FAT_DIRENTRY_SIZE));
+ }
+ fmt_params->root_dir_sectors =
+ (((fmt_params->files_per_root_dir * FAT_DIRENTRY_SIZE)
+ + fmt_params->bytes_per_sector - 1)
+ / fmt_params->bytes_per_sector);
+ }
+ if (ret_val == 0) {
+ fatdata_sect_cnt = (fmt_params->totl_sector_cnt -
+ fmt_params->rsvd_sector_cnt -
+ fmt_params->root_dir_sectors);
+
+ /*
+ * check values to get legal arrangement of FAT type and cluster count
+ */
+
+ ret_val = msdos_format_eval_sectors_per_cluster
+ (fmt_params->fattype,
+ fmt_params->bytes_per_sector,
+ fatdata_sect_cnt,
+ fmt_params->fat_num,
+ fmt_params->sectors_per_cluster,
+ &sectors_per_cluster_adj,
+ &(fmt_params->sectors_per_fat));
+ fmt_params->sectors_per_cluster = sectors_per_cluster_adj;
+ }
+
+ /*
+ * determine media code
+ */
+ if (ret_val == 0) {
+ if ((rqdata != NULL) &&
+ (rqdata->media != 0)) {
+ const char valid_media_codes[] =
+ {0xF0,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF};
+ if (NULL==memchr(valid_media_codes,
+ rqdata->media,
+ sizeof(valid_media_codes))) {
+ ret_val = -1;
+ errno = EINVAL;
+ }
+ else {
+ fmt_params->media_code = rqdata->media;
+ }
+ }
+ else {
+ fmt_params->media_code = FAT_BR_MEDIA_FIXED;
+ }
+ }
+ /*
+ * determine location and size of root directory
+ * for formatting
+ */
+ if (fmt_params->root_dir_sectors > 0) {
+ fmt_params->root_dir_start_sec =
+ fmt_params->rsvd_sector_cnt
+ + (fmt_params-> fat_num*fmt_params->sectors_per_fat);
+ fmt_params->root_dir_fmt_sec_cnt = fmt_params->root_dir_sectors;
+ }
+ else {
+ /*
+ * for FAT32: root directory is in cluster 2
+ */
+ fmt_params->root_dir_start_sec =
+ fmt_params->rsvd_sector_cnt
+ + (fmt_params-> fat_num*fmt_params->sectors_per_fat);
+ fmt_params->root_dir_fmt_sec_cnt = fmt_params->sectors_per_cluster;
+ }
+ /*
+ * determine usable OEMName
+ */
+ if (ret_val == 0) {
+ const char *from;
+ char *to = fmt_params->OEMName;
+ int cnt;
+ from = "RTEMS"; /* default: make "from" point to OS Name */
+ if ((rqdata != NULL) &&
+ (rqdata->OEMName != NULL)) {
+ from = rqdata->OEMName;
+ }
+ for (cnt = 0;
+ cnt < (sizeof(fmt_params->OEMName)-1);
+ cnt++) {
+ if (isprint(*from)) {
+ *to++ = *from++;
+ }
+ else {
+ /*
+ * non-printable character in given name, so keep stuck
+ * at that character and replace all following characters
+ * with a ' '
+ */
+ *to++=' ';
+ }
+ *to = '\0';
+ }
+ }
+
+ /*
+ * determine usable Volume Label
+ */
+ if (ret_val == 0) {
+ const char *from;
+ char *to = fmt_params->VolLabel;
+ int cnt;
+ from = ""; /* default: make "from" point to empty string */
+ if ((rqdata != NULL) &&
+ (rqdata->VolLabel != NULL)) {
+ from = rqdata->VolLabel;
+ fmt_params->VolLabel_present = TRUE;
+ }
+ for (cnt = 0;
+ cnt < (sizeof(fmt_params->VolLabel)-1);
+ cnt++) {
+ if (isprint(*from)) {
+ *to++ = *from++;
+ }
+ else {
+ /*
+ * non-printable character in given name, so keep stuck
+ * at that character and replace all following characters
+ * with a ' '
+ */
+ *to++=' ';
+ }
+ *to = '\0';
+ }
+ }
+
+ /*
+ * determine usable Volume ID
+ */
+ if (ret_val == 0) {
+ msdos_format_gen_volid(&(fmt_params->vol_id));
+ }
+ /*
+ * Phuuu.... That's it.
+ */
+ if (ret_val != 0) {
+ set_errno_and_return_minus_one(ret_val);
+ }
+ else {
+ return 0;
+ }
+}
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+static int msdos_format_gen_mbr
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| create master boot record content from parameter set |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ char mbr[], /* sector buffer */
+ const msdos_format_param_t *fmt_params/* computed fmt parameters */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+{
+ uint32_t total_sectors_num16 = 0;
+ uint32_t total_sectors_num32 = 0;
+
+ /* store total sector count in either 16 or 32 bit field in mbr */
+ if (fmt_params->totl_sector_cnt < 0x10000) {
+ total_sectors_num16 = fmt_params->totl_sector_cnt;
+ }
+ else {
+ total_sectors_num32 = fmt_params->totl_sector_cnt;
+ }
+ /*
+ * finally we are there: let's fill in the values into the MBR
+ */
+ memset(mbr,0,FAT_TOTAL_MBR_SIZE);
+ /*
+ * FIXME: fill jmpBoot and Boot code...
+ * with 0xEB,....
+ */
+ /*
+ * fill OEMName
+ */
+ memcpy(FAT_GET_ADDR_BR_OEMNAME(mbr),
+ fmt_params->OEMName,
+ FAT_BR_OEMNAME_SIZE);
+ FAT_SET_BR_BYTES_PER_SECTOR(mbr , fmt_params->bytes_per_sector);
+ FAT_SET_BR_SECTORS_PER_CLUSTER(mbr , fmt_params->sectors_per_cluster);
+ FAT_SET_BR_RESERVED_SECTORS_NUM(mbr, fmt_params->rsvd_sector_cnt);
+
+ /* number of FATs on medium */
+ FAT_SET_BR_FAT_NUM(mbr , 2); /* standard/recommended value */
+ FAT_SET_BR_FILES_PER_ROOT_DIR(mbr , fmt_params->files_per_root_dir);
+ FAT_SET_BR_TOTAL_SECTORS_NUM16(mbr , total_sectors_num16);
+ FAT_SET_BR_MEDIA(mbr , fmt_params->media_code);
+
+ FAT_SET_BR_SECTORS_PER_TRACK(mbr , 0); /* only needed for INT13... */
+ FAT_SET_BR_NUMBER_OF_HEADS(mbr , 0); /* only needed for INT13... */
+ FAT_SET_BR_HIDDEN_SECTORS(mbr , 0); /* only needed for INT13... */
+
+ FAT_SET_BR_TOTAL_SECTORS_NUM32(mbr , total_sectors_num32);
+ if (fmt_params->fattype != FAT_FAT32) {
+ FAT_SET_BR_SECTORS_PER_FAT(mbr ,fmt_params->sectors_per_fat);
+ FAT_SET_BR_DRVNUM(mbr , 0); /* only needed for INT13... */
+ FAT_SET_BR_RSVD1(mbr , 0); /* fill with zero */
+ FAT_SET_BR_BOOTSIG(mbr , FAT_BR_BOOTSIG_VAL);
+ FAT_SET_BR_VOLID(mbr , fmt_params->vol_id); /* volume id */
+ memcpy(FAT_GET_ADDR_BR_VOLLAB(mbr),
+ fmt_params->VolLabel,
+ FAT_BR_VOLLAB_SIZE);
+ memcpy(FAT_GET_ADDR_BR_FILSYSTYPE(mbr),
+ (fmt_params->fattype == FAT_FAT12)
+ ? "FAT12 "
+ : "FAT16 ",
+ FAT_BR_FILSYSTYPE_SIZE);
+ }
+ else {
+ FAT_SET_BR_SECTORS_PER_FAT32(mbr ,fmt_params->sectors_per_fat);
+ FAT_SET_BR_EXT_FLAGS(mbr , 0);
+ FAT_SET_BR_FSVER(mbr , 0); /* FAT32 Version:0.0 */
+ FAT_SET_BR_FAT32_ROOT_CLUSTER(mbr , 2); /* put root dir to cluster 2 */
+ FAT_SET_BR_FAT32_FS_INFO_SECTOR(mbr, 1); /* Put fsinfo to rsrvd sec 1*/
+ FAT_SET_BR_FAT32_BK_BOOT_SECTOR(mbr, fmt_params->mbr_copy_sec ); /* Put MBR copy to rsrvd sec */
+ memset(FAT_GET_ADDR_BR_FAT32_RESERVED(mbr),0,FAT_BR_FAT32_RESERVED_SIZE);
+
+ FAT_SET_BR_FAT32_DRVNUM(mbr , 0); /* only needed for INT13... */
+ FAT_SET_BR_FAT32_RSVD1(mbr , 0); /* fill with zero */
+ FAT_SET_BR_FAT32_BOOTSIG(mbr ,FAT_BR_FAT32_BOOTSIG_VAL);
+ FAT_SET_BR_FAT32_VOLID(mbr , 0); /* not set */
+ memset(FAT_GET_ADDR_BR_FAT32_VOLLAB(mbr) ,0,FAT_BR_VOLLAB_SIZE);
+ memcpy(FAT_GET_ADDR_BR_FAT32_FILSYSTYPE(mbr),
+ "FAT32 ",
+ FAT_BR_FILSYSTYPE_SIZE);
+ }
+ /*
+ * add boot record signature
+ */
+ FAT_SET_BR_SIGNATURE(mbr, FAT_BR_SIGNATURE_VAL);
+
+ /*
+ * add jump to boot loader at start of sector
+ */
+ FAT_SET_VAL8(mbr,0,0xeb);
+ FAT_SET_VAL8(mbr,1,0x3c);
+ FAT_SET_VAL8(mbr,2,0x90);
+ /*
+ * FIXME: a nice little PC boot loader would be nice here.
+ * but where can I get one for free?
+ */
+ /*
+ * Phuuu.... That's it.
+ */
+ return 0;
+}
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+static int msdos_format_gen_fsinfo
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| create FAT32 fsinfo sector |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ char fsinfo[] /* sector buffer */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+{
+
+ /*
+ * clear fsinfo sector data
+ */
+ memset(fsinfo,0,FAT_TOTAL_FSINFO_SIZE);
+ /*
+ * write LEADSIG, STRUCTSIG, TRAILSIG
+ */
+ FAT_SET_FSINFO_LEAD_SIGNATURE (fsinfo,FAT_FSINFO_LEAD_SIGNATURE_VALUE );
+ FAT_SET_FSINFO_STRUC_SIGNATURE(fsinfo,FAT_FSINFO_STRUC_SIGNATURE_VALUE);
+ FAT_SET_FSINFO_TRAIL_SIGNATURE(fsinfo,FAT_FSINFO_TRAIL_SIGNATURE_VALUE);
+/*
+ * write "empty" values for free cluster count and next cluster number
+ */
+ FAT_SET_FSINFO_FREE_CLUSTER_COUNT(fsinfo+FAT_FSI_INFO,
+ 0xffffffff);
+ FAT_SET_FSINFO_NEXT_FREE_CLUSTER (fsinfo+FAT_FSI_INFO,
+ 0xffffffff);
+ return 0;
+}
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int msdos_format
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| format device with msdos filesystem |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ const char *devname, /* device name */
+ const msdos_format_request_param_t *rqdata /* requested fmt parameters */
+ /* set to NULL for automatic */
+ /* determination */
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+{
+ char tmp_sec[FAT_TOTAL_MBR_SIZE];
+ int rc;
+ disk_device *dd = NULL;
+ struct stat stat_buf;
+ int ret_val = 0;
+ int fd = -1;
+ int i;
+ msdos_format_param_t fmt_params;
+
+ /*
+ * sanity check on device
+ */
+ if (ret_val == 0) {
+ rc = stat(devname, &stat_buf);
+ ret_val = rc;
+ }
+
+ /* rtems feature: no block devices, all are character devices */
+ if ((ret_val == 0) &&
+ (!S_ISCHR(stat_buf.st_mode))) {
+ errno = ENOTBLK;
+ ret_val = -1;
+ }
+
+ /* check that device is registered as block device and lock it */
+ if (ret_val == 0) {
+ dd = rtems_disk_lookup(stat_buf.st_dev);
+ if (dd == NULL) {
+ errno = ENOTBLK;
+ ret_val = -1;
+ }
+ }
+
+ /*
+ * open device for writing
+ */
+ if (ret_val == 0) {
+ fd = open(devname, O_WRONLY);
+ if (fd == -1)
+ {
+ ret_val= -1;
+ }
+ }
+
+ /*
+ * compute formatting parameters
+ */
+ if (ret_val == 0) {
+ ret_val = msdos_format_determine_fmt_params(dd,rqdata,&fmt_params);
+ }
+ /*
+ * if requested, write whole disk/partition with 0xe5
+ */
+ if ((ret_val == 0) &&
+ (rqdata != NULL) &&
+ !(rqdata->quick_format)) {
+ ret_val = msdos_format_fill_sectors
+ (fd,
+ 0, /* start sector */
+ fmt_params.totl_sector_cnt, /* sector count */
+ fmt_params.bytes_per_sector,
+ 0xe5);
+ }
+ /*
+ * create master boot record
+ */
+ if (ret_val == 0) {
+ ret_val = msdos_format_gen_mbr(tmp_sec,&fmt_params);
+ }
+ /*
+ * write master boot record to disk
+ * also write copy of MBR to disk
+ */
+ if (ret_val == 0) {
+ ret_val = msdos_format_write_sec(fd,
+ 0,
+ fmt_params.bytes_per_sector,
+ tmp_sec);
+ }
+ if ((ret_val == 0) &&
+ (fmt_params.mbr_copy_sec != 0)) {
+ /*
+ * write copy of MBR
+ */
+ ret_val = msdos_format_write_sec(fd,
+ fmt_params.mbr_copy_sec ,
+ fmt_params.bytes_per_sector,
+ tmp_sec);
+ }
+ /*
+ * for FAT32: initialize info sector on disk
+ */
+ if ((ret_val == 0) &&
+ (fmt_params.fsinfo_sec != 0)) {
+ ret_val = msdos_format_gen_fsinfo(tmp_sec);
+ }
+ /*
+ * write fsinfo sector
+ */
+ if ((ret_val == 0) &&
+ (fmt_params.fsinfo_sec != 0)) {
+ ret_val = msdos_format_write_sec(fd,
+ fmt_params.fsinfo_sec,
+ fmt_params.bytes_per_sector,
+ tmp_sec);
+ }
+ /*
+ * write FAT as all empty
+ * -> write all FAT sectors as zero
+ */
+ if (ret_val == 0) {
+ ret_val = msdos_format_fill_sectors
+ (fd,
+ fmt_params.rsvd_sector_cnt, /* start sector */
+ fmt_params.fat_num*fmt_params.sectors_per_fat,/* sector count */
+ fmt_params.bytes_per_sector,
+ 0x00);
+ }
+ /*
+ * clear/init root directory
+ * -> write all directory sectors as 0x00
+ */
+ if (ret_val == 0) {
+ ret_val = msdos_format_fill_sectors
+ (fd,
+ fmt_params.root_dir_start_sec, /* start sector */
+ fmt_params.root_dir_fmt_sec_cnt, /* sector count */
+ fmt_params.bytes_per_sector,
+ 0x00);
+ }
+ /*
+ * write volume label to first entry of directory
+ */
+ if ((ret_val == 0) && fmt_params.VolLabel_present) {
+ memset(tmp_sec,0,sizeof(tmp_sec));
+ memcpy(MSDOS_DIR_NAME(tmp_sec),fmt_params.VolLabel,MSDOS_SHORT_NAME_LEN);
+ *MSDOS_DIR_ATTR(tmp_sec) = MSDOS_ATTR_VOLUME_ID;
+ ret_val = msdos_format_write_sec
+ (fd,
+ fmt_params.root_dir_start_sec,
+ fmt_params.bytes_per_sector,
+ tmp_sec);
+ }
+ /*
+ * write FAT entry 0 as (0xffffff00|Media_type)EOC,
+ * write FAT entry 1 as EOC
+ * allocate directory in a FAT32 FS
+ */
+ if ((ret_val == 0) && fmt_params.VolLabel_present){
+ /*
+ * empty sector: all clusters are free/do not link further on
+ */
+ memset(tmp_sec,0,sizeof(tmp_sec));
+
+ switch(fmt_params.fattype) {
+ case FAT_FAT12:
+ /* LSBits of FAT entry 0: media_type */
+ FAT_SET_VAL8(tmp_sec,0,(fmt_params.media_code));
+ /* MSBits of FAT entry 0:0xf, LSBits of FAT entry 1: LSB of EOC */
+ FAT_SET_VAL8(tmp_sec,1,(0x0f | (FAT_FAT12_EOC << 4)));
+ /* MSBits of FAT entry 1: MSBits of EOC */
+ FAT_SET_VAL8(tmp_sec,2,(FAT_FAT12_EOC >> 4));
+ break;
+
+ case FAT_FAT16:
+ /* FAT entry 0: 0xff00|media_type */
+ FAT_SET_VAL16(tmp_sec,0,0xff00|fmt_params.media_code);
+ /* FAT entry 1: EOC */
+ FAT_SET_VAL16(tmp_sec,2,FAT_FAT16_EOC);
+ break;
+
+ case FAT_FAT32:
+ /* FAT entry 0: 0xffffff00|media_type */
+ FAT_SET_VAL32(tmp_sec,0,0xffffff00|fmt_params.media_code);
+ /* FAT entry 1: EOC */
+ FAT_SET_VAL32(tmp_sec,4,FAT_FAT32_EOC);
+ break;
+
+ default:
+ ret_val = -1;
+ errno = EINVAL;
+ }
+ if (fmt_params.fattype == FAT_FAT32) {
+ /*
+ * only first valid cluster (cluster number 2) belongs
+ * to root directory, and is end of chain
+ * mark this in every copy of the FAT
+ */
+ FAT_SET_VAL32(tmp_sec,8,FAT_FAT32_EOC);
+ }
+ for (i = 0;
+ (i < fmt_params.fat_num) && (ret_val == 0);
+ i++) {
+ ret_val = msdos_format_write_sec
+ (fd,
+ fmt_params.rsvd_sector_cnt
+ + (i * fmt_params.sectors_per_fat),
+ fmt_params.bytes_per_sector,
+ tmp_sec);
+ }
+ }
+ /*
+ * cleanup:
+ * sync and unlock disk
+ * free any data structures (not needed now)
+ */
+ if (fd != -1) {
+ close(fd);
+ }
+ if (dd != NULL) {
+ rtems_disk_release(dd);
+ }
+ return ret_val;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_free.c b/cpukit/libfs/src/dosfs/msdos_free.c
new file mode 100644
index 0000000000..db9ff9c984
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_free.c
@@ -0,0 +1,56 @@
+/*
+ * Free node handler implementation for the filesystem
+ * operations table.
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio_.h>
+
+#include <errno.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "fat_file.h"
+
+#include "msdos.h"
+
+/* msdos_free_node_info --
+ * Call fat-file close routine.
+ *
+ * PARAMETERS:
+ * pathloc - node description
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 code if error occured
+ *
+ */
+msdos_status_t
+msdos_free_node_info(rtems_filesystem_location_info_t *pathloc)
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info;
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ rc = fat_file_close(pathloc->mt_entry, pathloc->node_access);
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_fsunmount.c b/cpukit/libfs/src/dosfs/msdos_fsunmount.c
new file mode 100644
index 0000000000..796dd55aeb
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_fsunmount.c
@@ -0,0 +1,71 @@
+/*
+ * MSDOS shut down handler implementation
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <assert.h>
+#include <rtems.h>
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "fat_file.h"
+
+#include "msdos.h"
+
+/* msdos_shut_down --
+ * Shut down MSDOS filesystem - free all allocated resources (don't
+ * return if deallocation of some resource failed - free as much as
+ * possible).
+ *
+ * PARAMETERS:
+ * temp_mt_entry - mount table entry
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set apropriately).
+ *
+ */
+msdos_status_t
+msdos_shut_down(rtems_filesystem_mount_table_entry_t *temp_mt_entry)
+{
+ msdos_status_t rc = RC_OK;
+ msdos_fs_info_t *fs_info = temp_mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = temp_mt_entry->mt_fs_root.node_access;
+
+ /* close fat-file which correspondes to root directory */
+ if (fat_file_close(temp_mt_entry, fat_fd) != RC_OK)
+ {
+ /* no return - try to free as much as possible */
+ rc = -1;
+ }
+
+ if (fat_shutdown_drive(temp_mt_entry) != RC_OK)
+ {
+ /* no return - try to free as much as possible */
+ rc = -1;
+ }
+
+ rtems_semaphore_delete(fs_info->vol_sema);
+ free(fs_info->cl_buf);
+ free(temp_mt_entry->fs_info);
+
+ return rc;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c
new file mode 100644
index 0000000000..4a6d098b8e
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c
@@ -0,0 +1,36 @@
+/*
+ * Directory Handlers Table for MSDOS filesystem
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/libio.h>
+#include "msdos.h"
+
+rtems_filesystem_file_handlers_r msdos_dir_handlers = {
+ msdos_dir_open,
+ msdos_dir_close,
+ msdos_dir_read,
+ NULL, /* msdos_dir_write */
+ NULL, /* msdos_dir_ioctl */
+ msdos_dir_lseek,
+ msdos_dir_stat,
+ NULL,
+ NULL, /* msdos_dir_ftruncate */
+ NULL,
+ msdos_dir_sync,
+ msdos_dir_sync,
+ NULL, /* msdos_dir_fcntl */
+ msdos_dir_rmnod
+};
diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_file.c b/cpukit/libfs/src/dosfs/msdos_handlers_file.c
new file mode 100644
index 0000000000..857c5ad7a6
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_handlers_file.c
@@ -0,0 +1,36 @@
+/*
+ * File Operations Table for MSDOS filesystem
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/libio.h>
+#include "msdos.h"
+
+rtems_filesystem_file_handlers_r msdos_file_handlers = {
+ msdos_file_open,
+ msdos_file_close,
+ msdos_file_read,
+ msdos_file_write,
+ msdos_file_ioctl,
+ msdos_file_lseek,
+ msdos_file_stat,
+ NULL,
+ msdos_file_ftruncate,
+ NULL,
+ msdos_file_sync,
+ msdos_file_datasync,
+ NULL, /* msdos_file_fcntl */
+ msdos_file_rmnod
+};
diff --git a/cpukit/libfs/src/dosfs/msdos_init.c b/cpukit/libfs/src/dosfs/msdos_init.c
new file mode 100644
index 0000000000..afeaeae3c9
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_init.c
@@ -0,0 +1,64 @@
+/*
+ * Init routine for MSDOS
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+#include "msdos.h"
+
+rtems_filesystem_operations_table msdos_ops = {
+ msdos_eval_path,
+ msdos_eval4make,
+#if 0
+ NULL, /* msdos_link */
+#else
+ msdos_file_link, /* msdos_link (pseudo-functionality) */
+#endif
+ msdos_file_rmnod,
+ msdos_node_type,
+ msdos_mknod,
+ NULL, /* msdos_chown */
+ msdos_free_node_info,
+ NULL,
+ msdos_initialize,
+ NULL,
+ msdos_shut_down, /* msdos_shut_down */
+ NULL, /* msdos_utime */
+ NULL,
+ NULL,
+ NULL
+};
+
+/* msdos_initialize --
+ * MSDOS filesystem initialization
+ *
+ * PARAMETERS:
+ * temp_mt_entry - mount table entry
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set apropriately).
+ *
+ */
+msdos_status_t
+msdos_initialize(rtems_filesystem_mount_table_entry_t *temp_mt_entry)
+{
+ msdos_status_t rc;
+
+ rc = msdos_initialize_support(temp_mt_entry,
+ &msdos_ops,
+ &msdos_file_handlers,
+ &msdos_dir_handlers);
+ return rc;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_initsupp.c b/cpukit/libfs/src/dosfs/msdos_initsupp.c
new file mode 100644
index 0000000000..73a76f00c3
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_initsupp.c
@@ -0,0 +1,149 @@
+/*
+ * MSDOS Initialization support routine implementation
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <assert.h>
+#include <rtems.h>
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "fat_file.h"
+
+#include "msdos.h"
+
+/* msdos_initialize_support --
+ * MSDOS filesystem initialization
+ *
+ * PARAMETERS:
+ * temp_mt_entry - mount table entry
+ * op_table - filesystem operations table
+ * file_handlers - file operations table
+ * directory_handlers - directory operations table
+ *
+ * RETURNS:
+ * RC_OK and filled temp_mt_entry on success, or -1 if error occured
+ * (errno set apropriately)
+ *
+ */
+int
+msdos_initialize_support(
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry,
+ rtems_filesystem_operations_table *op_table,
+ rtems_filesystem_file_handlers_r *file_handlers,
+ rtems_filesystem_file_handlers_r *directory_handlers
+ )
+{
+ int rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = NULL;
+ fat_file_fd_t *fat_fd = NULL;
+ uint32_t cl_buf_size;
+
+ fs_info = (msdos_fs_info_t *)calloc(1, sizeof(msdos_fs_info_t));
+ if (!fs_info)
+ set_errno_and_return_minus_one(ENOMEM);
+
+ temp_mt_entry->fs_info = fs_info;
+
+ rc = fat_init_volume_info(temp_mt_entry);
+ if (rc != RC_OK)
+ {
+ free(fs_info);
+ return rc;
+ }
+
+ fs_info->file_handlers = file_handlers;
+ fs_info->directory_handlers = directory_handlers;
+
+ /*
+ * open fat-file which correspondes to root directory
+ * (so inode number 0x00000010 is always used for root directory)
+ */
+ rc = fat_file_open(temp_mt_entry, FAT_ROOTDIR_CLUSTER_NUM, 0, &fat_fd);
+ if (rc != RC_OK)
+ {
+ fat_shutdown_drive(temp_mt_entry);
+ free(fs_info);
+ return rc;
+ }
+
+ /* again: unfortunately "fat-file" is just almost fat file :( */
+ fat_fd->fat_file_type = FAT_DIRECTORY;
+ fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT;
+ fat_fd->info_cln = FAT_ROOTDIR_CLUSTER_NUM;
+ fat_fd->info_ofs = 0;
+ fat_fd->cln = fs_info->fat.vol.rdir_cl;
+
+ fat_fd->map.file_cln = 0;
+ fat_fd->map.disk_cln = fat_fd->cln;
+
+ /* if we have FAT12/16 */
+ if ( fat_fd->cln == 0 )
+ {
+ fat_fd->fat_file_size = fs_info->fat.vol.rdir_size;
+ cl_buf_size = (fs_info->fat.vol.bpc > fs_info->fat.vol.rdir_size) ?
+ fs_info->fat.vol.bpc :
+ fs_info->fat.vol.rdir_size;
+ }
+ else
+ {
+ rc = fat_file_size(temp_mt_entry, fat_fd);
+ if ( rc != RC_OK )
+ {
+ fat_file_close(temp_mt_entry, fat_fd);
+ fat_shutdown_drive(temp_mt_entry);
+ free(fs_info);
+ return rc;
+ }
+ cl_buf_size = fs_info->fat.vol.bpc;
+ }
+
+ fs_info->cl_buf = (uint8_t *)calloc(cl_buf_size, sizeof(char));
+ if (fs_info->cl_buf == NULL)
+ {
+ fat_file_close(temp_mt_entry, fat_fd);
+ fat_shutdown_drive(temp_mt_entry);
+ free(fs_info);
+ set_errno_and_return_minus_one(ENOMEM);
+ }
+
+ sc = rtems_semaphore_create(3,
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_FIFO,
+ 0,
+ &fs_info->vol_sema);
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fat_file_close(temp_mt_entry, fat_fd);
+ fat_shutdown_drive(temp_mt_entry);
+ free(fs_info->cl_buf);
+ free(fs_info);
+ set_errno_and_return_minus_one( EIO );
+ }
+
+ temp_mt_entry->mt_fs_root.node_access = fat_fd;
+ temp_mt_entry->mt_fs_root.handlers = directory_handlers;
+ temp_mt_entry->mt_fs_root.ops = op_table;
+
+ return rc;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_misc.c b/cpukit/libfs/src/dosfs/msdos_misc.c
new file mode 100644
index 0000000000..0924929deb
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_misc.c
@@ -0,0 +1,943 @@
+/*
+ * Miscellaneous routines implementation for MSDOS filesystem
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "fat_file.h"
+
+#include "msdos.h"
+
+/* msdos_get_token --
+ * Routine to get a token (name or separator) from the path.
+ *
+ * PARAMETERS:
+ * path - path to get token from
+ * ret_token - returned token
+ * token_len - length of returned token
+ *
+ * RETURNS:
+ * token type, token and token length
+ *
+ */
+msdos_token_types_t
+msdos_get_token(const char *path, char *ret_token, int *token_len)
+{
+ int rc = RC_OK;
+ register int i = 0;
+ msdos_token_types_t type = MSDOS_NAME;
+ char token[MSDOS_NAME_MAX_WITH_DOT+1];
+ register char c;
+
+ /*
+ * Copy a name into token. (Remember NULL is a token.)
+ */
+ c = path[i];
+ while ( (!msdos_is_separator(c)) && (i <= MSDOS_NAME_MAX_WITH_DOT) )
+ {
+ token[i] = c;
+ if ( i == MSDOS_NAME_MAX_WITH_DOT )
+ return MSDOS_INVALID_TOKEN;
+ if ( !msdos_is_valid_name_char(c) )
+ return MSDOS_INVALID_TOKEN;
+ c = path [++i];
+ }
+
+ /*
+ * Copy a seperator into token.
+ */
+ if ( i == 0 )
+ {
+ token[i] = c;
+ if ( token[i] != '\0' )
+ {
+ i++;
+ type = MSDOS_CURRENT_DIR;
+ }
+ else
+ type = MSDOS_NO_MORE_PATH;
+ }
+ else if (token[ i-1 ] != '\0')
+ token[i] = '\0';
+
+ /*
+ * Set token_len to the number of characters copied.
+ */
+ *token_len = i;
+
+ /*
+ * If we copied something that was not a seperator see if
+ * it was a special name.
+ */
+ if ( type == MSDOS_NAME )
+ {
+ if ( strcmp( token, "..") == 0 )
+ {
+ strcpy(ret_token, MSDOS_DOTDOT_NAME);
+ type = MSDOS_UP_DIR;
+ return type;
+ }
+
+ if ( strcmp( token, "." ) == 0 )
+ {
+ strcpy(ret_token, MSDOS_DOT_NAME);
+ type = MSDOS_CURRENT_DIR;
+ return type;
+ }
+
+ rc = msdos_filename_unix2dos(token, *token_len, ret_token);
+ if ( rc != RC_OK )
+ return MSDOS_INVALID_TOKEN;
+ }
+ ret_token[MSDOS_NAME_MAX] = '\0';
+ return type;
+}
+
+
+/* msdos_find_name --
+ * Find the node which correspondes to the name, open fat-file which
+ * correspondes to the found node and close fat-file which correspondes
+ * to the node we searched in.
+ *
+ * PARAMETERS:
+ * parent_loc - parent node description
+ * name - name to find
+ *
+ * RETURNS:
+ * RC_OK and updated 'parent_loc' on success, or -1 if error
+ * occured (errno set apropriately)
+ *
+ */
+int
+msdos_find_name(
+ rtems_filesystem_location_info_t *parent_loc,
+ char *name
+ )
+{
+ int rc = RC_OK;
+ msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = NULL;
+ fat_auxiliary_t aux;
+ unsigned short time_val = 0;
+ unsigned short date = 0;
+ char node_entry[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
+
+ memset(node_entry, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
+
+ /*
+ * find the node which correspondes to the name in the directory pointed by
+ * 'parent_loc'
+ */
+ rc = msdos_get_name_node(parent_loc, name, &aux, node_entry);
+ if (rc != RC_OK)
+ return rc;
+
+ /* open fat-file corresponded to the found node */
+ rc = fat_file_open(parent_loc->mt_entry, aux.cln, aux.ofs, &fat_fd);
+ if (rc != RC_OK)
+ return rc;
+
+ /*
+ * I don't like this if, but: we should do it , or should write new file
+ * size and first cluster num to the disk after each write operation
+ * (even if one byte is written - that is TOO non-optimize) because
+ * otherwise real values of these fields stored in fat-file descriptor
+ * may be accidentely rewritten with wrong values stored on the disk
+ */
+ if (fat_fd->links_num == 1)
+ {
+ fat_fd->info_cln = aux.cln;
+ fat_fd->info_ofs = aux.ofs;
+ fat_fd->cln = MSDOS_EXTRACT_CLUSTER_NUM(node_entry);
+ fat_fd->first_char = *MSDOS_DIR_NAME(node_entry);
+
+ time_val = *MSDOS_DIR_WRITE_TIME(node_entry);
+ date = *MSDOS_DIR_WRITE_DATE(node_entry);
+
+ fat_fd->mtime = msdos_date_dos2unix(CF_LE_W(time_val), CF_LE_W(date));
+
+ if ((*MSDOS_DIR_ATTR(node_entry)) & MSDOS_ATTR_DIRECTORY)
+ {
+ fat_fd->fat_file_type = FAT_DIRECTORY;
+ fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT;
+
+ rc = fat_file_size(parent_loc->mt_entry, fat_fd);
+ if (rc != RC_OK)
+ {
+ fat_file_close(parent_loc->mt_entry, fat_fd);
+ return rc;
+ }
+ }
+ else
+ {
+ fat_fd->fat_file_size = CF_LE_L(*MSDOS_DIR_FILE_SIZE(node_entry));
+ fat_fd->fat_file_type = FAT_FILE;
+ fat_fd->size_limit = MSDOS_MAX_FILE_SIZE;
+ }
+
+ /* these data is not actual for zero-length fat-file */
+ fat_fd->map.file_cln = 0;
+ fat_fd->map.disk_cln = fat_fd->cln;
+
+ if ((fat_fd->fat_file_size != 0) &&
+ (fat_fd->fat_file_size <= fs_info->fat.vol.bpc))
+ {
+ fat_fd->map.last_cln = fat_fd->cln;
+ }
+ else
+ {
+ fat_fd->map.last_cln = FAT_UNDEFINED_VALUE;
+ }
+ }
+
+ /* close fat-file corresponded to the node we searched in */
+ rc = fat_file_close(parent_loc->mt_entry, parent_loc->node_access);
+ if (rc != RC_OK)
+ {
+ fat_file_close(parent_loc->mt_entry, fat_fd);
+ return rc;
+ }
+
+ /* update node_info_ptr field */
+ parent_loc->node_access = fat_fd;
+
+ return rc;
+}
+
+/* msdos_get_name_node --
+ * This routine is used in two ways: for a new mode creation (a) or for
+ * search the node which correspondes to the name parameter (b).
+ * In case (a) 'name' should be set up to NULL and 'name_dir_entry' should
+ * point to initialized 32 bytes structure described a new node.
+ * In case (b) 'name' should contain a valid string.
+ *
+ * (a): reading fat-file which correspondes to directory we are going to
+ * create node in. If free slot is found write contents of
+ * 'name_dir_entry' into it. If reach end of fat-file and no free
+ * slot found, write 32 bytes to the end of fat-file.
+ *
+ * (b): reading fat-file which correspondes to directory and trying to
+ * find slot with the name field == 'name' parameter
+ *
+ *
+ * PARAMETERS:
+ * parent_loc - node description to create node in or to find name in
+ * name - NULL or name to find
+ * paux - identify a node location on the disk -
+ * cluster num and offset inside the cluster
+ * name_dir_entry - node to create/placeholder for found node (IN/OUT)
+ *
+ * RETURNS:
+ * RC_OK, filled aux_struct_ptr and name_dir_entry on success, or -1 if
+ * error occured (errno set apropriately)
+ *
+ */
+msdos_status_t
+msdos_get_name_node(
+ rtems_filesystem_location_info_t *parent_loc,
+ char *name,
+ fat_auxiliary_t *paux,
+ char *name_dir_entry
+ )
+{
+ msdos_status_t rc = RC_OK;
+ ssize_t ret = 0;
+ msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = parent_loc->node_access;
+ uint32_t dotdot_cln = 0;
+
+ /* find name in fat-file which correspondes to the directory */
+ rc = msdos_find_name_in_fat_file(parent_loc->mt_entry, fat_fd, name, paux,
+ name_dir_entry);
+ if ((rc != RC_OK) && (rc != MSDOS_NAME_NOT_FOUND_ERR))
+ return rc;
+
+ /* if we search for valid name and name not found -> return */
+ if ((rc == MSDOS_NAME_NOT_FOUND_ERR) && (name != NULL))
+ return rc;
+
+ /*
+ * if we try to create new entry and the directory is not big enough
+ * currently - try to enlarge directory
+ */
+ if ((rc == MSDOS_NAME_NOT_FOUND_ERR) && (name == NULL))
+ {
+ ret = fat_file_write(parent_loc->mt_entry, fat_fd,
+ fat_fd->fat_file_size,
+ MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,
+ (uint8_t *)name_dir_entry);
+ if (ret == -1)
+ return -1;
+
+ /* on success directory is enlarged by a new cluster */
+ fat_fd->fat_file_size += fs_info->fat.vol.bpc;
+
+ /* get cluster num where a new node located */
+ rc = fat_file_ioctl(parent_loc->mt_entry, fat_fd, F_CLU_NUM,
+ fat_fd->fat_file_size - 1, &paux->cln);
+
+ if (rc != RC_OK)
+ return rc;
+
+ /*
+ * if new cluster allocated succesfully then new node is at very
+ * beginning of the cluster (offset is computed in bytes)
+ */
+ paux->ofs = 0;
+ return RC_OK;
+ }
+
+ /*
+ * if we have deal with ".." - it is a special case :(((
+ *
+ * Really, we should return cluster num and offset not of ".." slot, but
+ * slot which correspondes to real directory name.
+ */
+ if ((rc == RC_OK) && (name != NULL))
+ {
+ if (strncmp(name, MSDOS_DOTDOT_NAME, MSDOS_SHORT_NAME_LEN) == 0)
+ {
+ dotdot_cln = MSDOS_EXTRACT_CLUSTER_NUM((name_dir_entry));
+
+ /* are we right under root dir ? */
+ if (dotdot_cln == 0)
+ {
+ /*
+ * we can relax about first_char field - it never should be
+ * used for root dir
+ */
+ paux->cln = FAT_ROOTDIR_CLUSTER_NUM;
+ paux->ofs = 0;
+ }
+ else
+ {
+ rc = msdos_get_dotdot_dir_info_cluster_num_and_offset(
+ parent_loc->mt_entry,
+ dotdot_cln,
+ paux,
+ name_dir_entry
+ );
+ if (rc != RC_OK)
+ return rc;
+ }
+ }
+ }
+ return rc;
+}
+
+/*
+ * msdos_get_dotdot_dir_info_cluster_num_and_offset
+ *
+ * Unfortunately, in general, we cann't work here in fat-file ideologic
+ * (open fat_file "..", get ".." and ".", open "..", find an entry ...)
+ * because if we open
+ * fat-file ".." it may happend that we have two different fat-file
+ * descriptors ( for real name of directory and ".." name ) for a single
+ * file ( cluster num of both pointers to the same cluster )
+ * But...we do it because we protected by semaphore
+ *
+ */
+
+/* msdos_get_dotdot_dir_info_cluster_num_and_offset --
+ * Get cluster num and offset not of ".." slot, but slot which correspondes
+ * to real directory name.
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * cln - data cluster num extracted drom ".." slot
+ * paux - identify a node location on the disk -
+ * number of cluster and offset inside the cluster
+ * dir_entry - placeholder for found node
+ *
+ * RETURNS:
+ * RC_OK, filled 'paux' and 'dir_entry' on success, or -1 if error occured
+ * (errno set apropriately)
+ *
+ */
+int
+msdos_get_dotdot_dir_info_cluster_num_and_offset(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cln,
+ fat_auxiliary_t *paux,
+ char *dir_entry
+ )
+{
+ int rc = RC_OK;
+ msdos_fs_info_t *fs_info = mt_entry->fs_info;
+ fat_file_fd_t *fat_fd = NULL;
+ char dot_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
+ char dotdot_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
+ uint32_t cl4find = 0;
+
+ memset(dot_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
+ memset(dotdot_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
+
+ /*
+ * open fat-file corresponded to ".."
+ */
+ rc = fat_file_open(mt_entry, paux->cln, paux->ofs, &fat_fd);
+ if (rc != RC_OK)
+ return rc;
+
+ fat_fd->info_cln = paux->cln;
+ fat_fd->info_ofs = paux->ofs;
+ fat_fd->cln = cln;
+ fat_fd->fat_file_type = FAT_DIRECTORY;
+ fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT;
+
+ fat_fd->map.file_cln = 0;
+ fat_fd->map.disk_cln = fat_fd->cln;
+
+ rc = fat_file_size(mt_entry, fat_fd);
+ if (rc != RC_OK)
+ {
+ fat_file_close(mt_entry, fat_fd);
+ return rc;
+ }
+
+ /* find "." node in opened directory */
+ rc = msdos_find_name_in_fat_file(mt_entry, fat_fd, MSDOS_DOT_NAME, paux,
+ dot_node);
+
+ if (rc != RC_OK)
+ {
+ fat_file_close(mt_entry, fat_fd);
+ return rc;
+ }
+
+ /* find ".." node in opened directory */
+ rc = msdos_find_name_in_fat_file(mt_entry, fat_fd, MSDOS_DOTDOT_NAME, paux,
+ dotdot_node);
+
+ if (rc != RC_OK)
+ {
+ fat_file_close(mt_entry, fat_fd);
+ return rc;
+ }
+
+ cl4find = MSDOS_EXTRACT_CLUSTER_NUM(dot_node);
+
+ /* close fat-file corresponded to ".." directory */
+ rc = fat_file_close(mt_entry, fat_fd);
+ if ( rc != RC_OK )
+ return rc;
+
+ if ( (MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node)) == 0)
+ {
+ /*
+ * we handle root dir for all FAT types in the same way with the
+ * ordinary directories ( through fat_file_* calls )
+ */
+ paux->cln = FAT_ROOTDIR_CLUSTER_NUM;
+ paux->ofs = 0;
+ }
+
+ /* open fat-file corresponded to second ".." */
+ rc = fat_file_open(mt_entry, paux->cln, paux->ofs, &fat_fd);
+ if (rc != RC_OK)
+ return rc;
+
+ fat_fd->info_cln = paux->cln;
+ fat_fd->info_ofs = paux->ofs;
+
+ if ((MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node)) == 0)
+ fat_fd->cln = fs_info->fat.vol.rdir_cl;
+ else
+ fat_fd->cln = MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node);
+
+ fat_fd->fat_file_type = FAT_DIRECTORY;
+ fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT;
+
+ fat_fd->map.file_cln = 0;
+ fat_fd->map.disk_cln = fat_fd->cln;
+
+ rc = fat_file_size(mt_entry, fat_fd);
+ if (rc != RC_OK)
+ {
+ fat_file_close(mt_entry, fat_fd);
+ return rc;
+ }
+
+ /* in this directory find slot with specified cluster num */
+ rc = msdos_find_node_by_cluster_num_in_fat_file(mt_entry, fat_fd, cl4find,
+ paux, dir_entry);
+ if (rc != RC_OK)
+ {
+ fat_file_close(mt_entry, fat_fd);
+ return rc;
+ }
+ rc = fat_file_close(mt_entry, fat_fd);
+ return rc;
+}
+
+
+/* msdos_set_dir_wrt_time_and_date --
+ * Write last write date and time for a file to the disk (to corresponded
+ * 32bytes node)
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set apropriately).
+ *
+ */
+int
+msdos_set_dir_wrt_time_and_date(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd
+ )
+{
+ ssize_t ret1 = 0, ret2 = 0;
+ msdos_fs_info_t *fs_info = mt_entry->fs_info;
+ unsigned short time_val;
+ unsigned short date;
+ uint32_t sec = 0;
+ uint32_t byte = 0;
+
+ msdos_date_unix2dos(fat_fd->mtime, &time_val, &date);
+
+ /*
+ * calculate input for _fat_block_write: convert (cluster num, offset) to
+ * (sector num, new offset)
+ */
+ sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->info_cln);
+ sec += (fat_fd->info_ofs >> fs_info->fat.vol.sec_log2);
+ /* byte points to start of 32bytes structure */
+ byte = fat_fd->info_ofs & (fs_info->fat.vol.bps - 1);
+
+ time_val = CT_LE_W(time_val);
+ ret1 = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_WTIME_OFFSET,
+ 2, (char *)(&time_val));
+ date = CT_LE_W(date);
+ ret2 = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_WDATE_OFFSET,
+ 2, (char *)(&date));
+
+ if ( (ret1 < 0) || (ret2 < 0) )
+ return -1;
+
+ return RC_OK;
+}
+
+/* msdos_set_first_cluster_num --
+ * Write number of first cluster of the file to the disk (to corresponded
+ * 32bytes slot)
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured
+ *
+ */
+int
+msdos_set_first_cluster_num(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd
+ )
+{
+ ssize_t ret1 = 0, ret2 = 0;
+ msdos_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t new_cln = fat_fd->cln;
+ uint16_t le_cl_low = 0;
+ uint16_t le_cl_hi = 0;
+ uint32_t sec = 0;
+ uint32_t byte = 0;
+
+ /*
+ * calculate input for _fat_block_write: convert (cluster num, offset) to
+ * (sector num, new offset)
+ */
+ sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->info_cln);
+ sec += (fat_fd->info_ofs >> fs_info->fat.vol.sec_log2);
+ /* byte from points to start of 32bytes structure */
+ byte = fat_fd->info_ofs & (fs_info->fat.vol.bps - 1);
+
+ le_cl_low = CT_LE_W((uint16_t )(new_cln & 0x0000FFFF));
+ ret1 = _fat_block_write(mt_entry, sec,
+ byte + MSDOS_FIRST_CLUSTER_LOW_OFFSET, 2,
+ (char *)(&le_cl_low));
+ le_cl_hi = CT_LE_W((uint16_t )((new_cln & 0xFFFF0000) >> 16));
+ ret2 = _fat_block_write(mt_entry, sec,
+ byte + MSDOS_FIRST_CLUSTER_HI_OFFSET, 2,
+ (char *)(&le_cl_hi));
+ if ( (ret1 < 0) || (ret2 < 0) )
+ return -1;
+
+ return RC_OK;
+}
+
+
+/* msdos_set_file size --
+ * Write file size of the file to the disk (to corresponded 32bytes slot)
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set apropriately).
+ *
+ */
+int
+msdos_set_file_size(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd
+ )
+{
+ ssize_t ret = 0;
+ msdos_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t le_new_length = 0;
+ uint32_t sec = 0;
+ uint32_t byte = 0;
+
+ sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->info_cln);
+ sec += (fat_fd->info_ofs >> fs_info->fat.vol.sec_log2);
+ byte = (fat_fd->info_ofs & (fs_info->fat.vol.bps - 1));
+
+ le_new_length = CT_LE_L((fat_fd->fat_file_size));
+ ret = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_SIZE_OFFSET, 4,
+ (char *)(&le_new_length));
+ if ( ret < 0 )
+ return -1;
+
+ return RC_OK;
+}
+
+/*
+ * We should not check whether this routine is called for root dir - it
+ * never can happend
+ */
+
+/* msdos_set_first_char4file_name --
+ * Write first character of the name of the file to the disk (to
+ * corresponded 32bytes slot)
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * cl - number of cluster
+ * ofs - offset inside cluster
+ * fchar - character to set up
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured (errno set apropriately)
+ *
+ */
+int
+msdos_set_first_char4file_name(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ uint32_t cl,
+ uint32_t ofs,
+ unsigned char fchar
+ )
+{
+ ssize_t ret = 0;
+ msdos_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t sec = 0;
+ uint32_t byte = 0;
+
+ sec = fat_cluster_num_to_sector_num(mt_entry, cl);
+ sec += (ofs >> fs_info->fat.vol.sec_log2);
+ byte = (ofs & (fs_info->fat.vol.bps - 1));
+
+ ret = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_NAME_OFFSET, 1,
+ &fchar);
+ if ( ret < 0)
+ return -1;
+
+ return RC_OK;
+}
+
+/* msdos_dir_is_empty --
+ * Check whether directory which correspondes to the fat-file descriptor is
+ * empty.
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ * ret_val - placeholder for result
+ *
+ * RETURNS:
+ * RC_OK on success, or -1 if error occured
+ *
+ */
+int
+msdos_dir_is_empty(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ rtems_boolean *ret_val
+ )
+{
+ ssize_t ret = 0;
+ msdos_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t j = 0, i = 0;
+
+ /* dir is not empty */
+ *ret_val = FALSE;
+
+ while ((ret = fat_file_read(mt_entry, fat_fd, j * fs_info->fat.vol.bps,
+ fs_info->fat.vol.bps,
+ fs_info->cl_buf)) != FAT_EOF)
+ {
+ if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
+ return -1;
+
+ assert(ret == fs_info->fat.vol.bps);
+
+ /* have to look at the DIR_NAME as "raw" 8-bit data */
+ for (i = 0;
+ i < fs_info->fat.vol.bps;
+ i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
+ {
+ if (((*(uint8_t *)MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
+ MSDOS_THIS_DIR_ENTRY_EMPTY) ||
+ (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)), MSDOS_DOT_NAME,
+ MSDOS_SHORT_NAME_LEN) == 0) ||
+ (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)),
+ MSDOS_DOTDOT_NAME,
+ MSDOS_SHORT_NAME_LEN) == 0))
+ continue;
+
+ if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
+ MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY)
+ {
+ *ret_val = TRUE;
+ return RC_OK;
+ }
+ return RC_OK;
+ }
+ j++;
+ }
+ *ret_val = TRUE;
+ return RC_OK;
+}
+
+
+/* msdos_find_name_in_fat_file --
+ * This routine is used in two ways: for a new mode creation (a) or for
+ * search the node which correspondes to the 'name' parameter (b).
+ * In case (a) name should be set up to NULL and 'name_dir_entry' should
+ * point to initialized 32 bytes structure described a new node.
+ * In case (b) 'name' should contain a valid string.
+ *
+ * (a): reading fat-file corresponded to directory we are going to create
+ * node in. If found free slot write contents of name_dir_entry into
+ * it.
+ *
+ * (b): reading fat-file corresponded to directory and trying to find slot
+ * with the name field == name parameter
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ * name - NULL or name to find
+ * paux - identify a node location on the disk -
+ * number of cluster and offset inside the cluster
+ * name_dir_entry - node to create/placeholder for found node
+ *
+ * RETURNS:
+ * RC_OK on success, or error code if error occured (errno set
+ * appropriately)
+ *
+ */
+msdos_status_t
+msdos_find_name_in_fat_file(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ char *name,
+ fat_auxiliary_t *paux,
+ char *name_dir_entry
+ )
+{
+ msdos_status_t rc = RC_OK;
+ ssize_t ret = 0;
+ msdos_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t i = 0, j = 0;
+ uint32_t bts2rd = 0;
+
+ if (FAT_FD_OF_ROOT_DIR(fat_fd) &&
+ (fs_info->fat.vol.type & (FAT_FAT12 | FAT_FAT16)))
+ bts2rd = fat_fd->fat_file_size;
+ else
+ bts2rd = fs_info->fat.vol.bpc;
+
+ while ((ret = fat_file_read(mt_entry, fat_fd, (j * bts2rd), bts2rd,
+ fs_info->cl_buf)) != FAT_EOF)
+ {
+ if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
+ set_errno_and_return_minus_one(EIO);
+
+ assert(ret == bts2rd);
+
+ /* have to look at the DIR_NAME as "raw" 8-bit data */
+ for (i = 0; i < bts2rd; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
+ {
+ /* is the entry empty ? */
+ if (((*(uint8_t *)MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
+ MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY) ||
+ ((*(uint8_t *)MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
+ MSDOS_THIS_DIR_ENTRY_EMPTY))
+ {
+ /* whether we are looking for an empty entry */
+ if (name == NULL)
+ {
+ /* get current cluster number */
+ rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM,
+ j * bts2rd, &paux->cln);
+ if (rc != RC_OK)
+ return rc;
+
+ /* offset is computed in bytes */
+ paux->ofs = i;
+
+ /* write new node entry */
+ ret = fat_file_write(mt_entry, fat_fd, j * bts2rd + i,
+ MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,
+ (uint8_t *)name_dir_entry);
+ if (ret != MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
+ return -1;
+
+ /*
+ * we don't update fat_file_size here - it should not
+ * increase
+ */
+ return RC_OK;
+ }
+
+ /*
+ * if name != NULL and there is no more entries in the
+ * directory - return name-not-found
+ */
+ if (((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
+ MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY))
+ return MSDOS_NAME_NOT_FOUND_ERR;
+ }
+ else
+ {
+ /* entry not empty and name != NULL -> compare names */
+ if (name != NULL)
+ {
+ if (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)), name,
+ MSDOS_SHORT_NAME_LEN) == 0)
+ {
+ /*
+ * we get the entry we looked for - fill auxiliary
+ * structure and copy all 32 bytes of the entry
+ */
+ rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM,
+ j * bts2rd, &paux->cln);
+ if (rc != RC_OK)
+ return rc;
+
+ /* offset is computed in bytes */
+ paux->ofs = i;
+ memcpy(name_dir_entry,(fs_info->cl_buf + i),
+ MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
+ return RC_OK;
+ }
+ }
+ }
+ }
+ j++;
+ }
+ return MSDOS_NAME_NOT_FOUND_ERR;
+}
+
+/* msdos_find_node_by_cluster_num_in_fat_file --
+ * Find node with specified number of cluster in fat-file.
+ *
+ * PARAMETERS:
+ * mt_entry - mount table entry
+ * fat_fd - fat-file descriptor
+ * cl4find - number of cluster to find
+ * paux - identify a node location on the disk -
+ * cluster num and offset inside the cluster
+ * dir_entry - placeholder for found node
+ *
+ * RETURNS:
+ * RC_OK on success, or error code if error occured
+ *
+ */
+msdos_status_t
+msdos_find_node_by_cluster_num_in_fat_file(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ fat_file_fd_t *fat_fd,
+ uint32_t cl4find,
+ fat_auxiliary_t *paux,
+ char *dir_entry
+ )
+{
+ msdos_status_t rc = RC_OK;
+ ssize_t ret = 0;
+ msdos_fs_info_t *fs_info = mt_entry->fs_info;
+ uint32_t bts2rd = 0;
+ uint32_t i = 0, j = 0;
+
+ if (FAT_FD_OF_ROOT_DIR(fat_fd) &&
+ (fs_info->fat.vol.type & (FAT_FAT12 | FAT_FAT16)))
+ bts2rd = fat_fd->fat_file_size;
+ else
+ bts2rd = fs_info->fat.vol.bpc;
+
+ while ((ret = fat_file_read(mt_entry, fat_fd, j * bts2rd, bts2rd,
+ fs_info->cl_buf)) != FAT_EOF)
+ {
+ if ( ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE )
+ set_errno_and_return_minus_one( EIO );
+
+ assert(ret == bts2rd);
+
+ for (i = 0; i < bts2rd; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
+ {
+ /* if this and all rest entries are empty - return not-found */
+ if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
+ MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY)
+ return MSDOS_NAME_NOT_FOUND_ERR;
+
+ /* have to look at the DIR_NAME as "raw" 8-bit data */
+ /* if this entry is empty - skip it */
+ if ((*(uint8_t *)MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
+ MSDOS_THIS_DIR_ENTRY_EMPTY)
+ continue;
+
+ /* if get a non-empty entry - compare clusters num */
+ if (MSDOS_EXTRACT_CLUSTER_NUM((fs_info->cl_buf + i)) == cl4find)
+ {
+ /* on success fill aux structure and copy all 32 bytes */
+ rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM, j * bts2rd,
+ &paux->cln);
+ if (rc != RC_OK)
+ return rc;
+
+ paux->ofs = i;
+ memcpy(dir_entry, fs_info->cl_buf + i,
+ MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
+ return RC_OK;
+ }
+ }
+ j++;
+ }
+ return MSDOS_NAME_NOT_FOUND_ERR;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_mknod.c b/cpukit/libfs/src/dosfs/msdos_mknod.c
new file mode 100644
index 0000000000..7c59d9800e
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_mknod.c
@@ -0,0 +1,90 @@
+/*
+ * Routine for node creation in MSDOS filesystem.
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <rtems.h>
+
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "fat_file.h"
+
+#include "msdos.h"
+
+/* msdos_mknod --
+ * The following function checks spelling and formats name for a new node,
+ * determines type of the node to be created and creates it.
+ *
+ * PARAMETERS:
+ * token - non-formatted name of a new node
+ * mode - node type
+ * dev - dev
+ * pathloc - parent directory description
+ *
+ * RETURNS:
+ * RC_OK on succes, or -1 if error occured and set errno
+ *
+ */
+msdos_status_t
+msdos_mknod(
+ const char *token,
+ mode_t mode,
+ dev_t dev,
+ rtems_filesystem_location_info_t *pathloc
+ )
+{
+ msdos_status_t rc = RC_OK;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info;
+ msdos_token_types_t type = 0;
+ char new_name[ MSDOS_NAME_MAX + 1 ];
+ int len;
+
+ /* check spelling and format new node name */
+ msdos_get_token(token, new_name, &len);
+
+ /*
+ * Figure out what type of msdos node this is.
+ */
+ if (S_ISDIR(mode))
+ {
+ type = MSDOS_DIRECTORY;
+ }
+ else if (S_ISREG(mode))
+ {
+ type = MSDOS_REGULAR_FILE;
+ }
+ else
+ set_errno_and_return_minus_one(EINVAL);
+
+ sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+ MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one(EIO);
+
+ /* Create an MSDOS node */
+ rc = msdos_creat_node(pathloc, type, new_name, mode, NULL);
+
+ rtems_semaphore_release(fs_info->vol_sema);
+ return rc;
+}
diff --git a/cpukit/libfs/src/dosfs/msdos_node_type.c b/cpukit/libfs/src/dosfs/msdos_node_type.c
new file mode 100644
index 0000000000..877cf60492
--- /dev/null
+++ b/cpukit/libfs/src/dosfs/msdos_node_type.c
@@ -0,0 +1,58 @@
+/*
+ * The following returns the type of node that the loc refers to.
+ *
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * @(#) $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <rtems.h>
+
+#include <rtems/libio_.h>
+
+#include "fat.h"
+#include "fat_fat_operations.h"
+#include "fat_file.h"
+
+#include "msdos.h"
+
+/* msdos_node_type --
+ * Determine type of the node that the pathloc refers to.
+ *
+ * PARAMETERS:
+ * pathloc - node description
+ *
+ * RETURNS:
+ * node type
+ *
+ */
+rtems_filesystem_node_types_t
+msdos_node_type(rtems_filesystem_location_info_t *pathloc)
+{
+ fat_file_fd_t *fat_fd;
+
+ /*
+ * we don't need to obtain the volume semaphore here because node_type_h
+ * call always follows evalpath_h call(hence link increment occured) and
+ * hence node_access memory can't be freed during processing node_type_h
+ * call
+ */
+ fat_fd = pathloc->node_access;
+
+ return fat_fd->fat_file_type;
+}
diff --git a/cpukit/libfs/src/imfs/.cvsignore b/cpukit/libfs/src/imfs/.cvsignore
new file mode 100644
index 0000000000..c62d89f265
--- /dev/null
+++ b/cpukit/libfs/src/imfs/.cvsignore
@@ -0,0 +1,5 @@
+config.h
+config.h.in
+stamp-h
+stamp-h.in
+stamp-h1.in
diff --git a/cpukit/libfs/src/imfs/deviceio.c b/cpukit/libfs/src/imfs/deviceio.c
new file mode 100644
index 0000000000..c0758396e3
--- /dev/null
+++ b/cpukit/libfs/src/imfs/deviceio.c
@@ -0,0 +1,257 @@
+/*
+ * IMFS Device Node Handlers
+ *
+ * This file contains the set of handlers used to map operations on
+ * IMFS device nodes onto calls to the RTEMS Classic API IO Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/assoc.h> /* assoc.h not included by rtems.h */
+#include <errno.h>
+
+#include "imfs.h"
+
+/*
+ * Convert RTEMS status to a UNIX errno
+ */
+
+rtems_assoc_t errno_assoc[] = {
+ { "OK", RTEMS_SUCCESSFUL, 0 },
+ { "BUSY", RTEMS_RESOURCE_IN_USE, EBUSY },
+ { "INVALID NAME", RTEMS_INVALID_NAME, EINVAL },
+ { "NOT IMPLEMENTED", RTEMS_NOT_IMPLEMENTED, ENOSYS },
+ { "TIMEOUT", RTEMS_TIMEOUT, ETIMEDOUT },
+ { "NO MEMORY", RTEMS_NO_MEMORY, ENOMEM },
+ { "NO DEVICE", RTEMS_UNSATISFIED, ENODEV },
+ { "INVALID NUMBER", RTEMS_INVALID_NUMBER, EBADF},
+ { "NOT RESOURCE OWNER", RTEMS_NOT_OWNER_OF_RESOURCE, EPERM},
+ { "IO ERROR", RTEMS_IO_ERROR, EIO},
+ { 0, 0, 0 },
+};
+
+static int
+rtems_deviceio_errno(rtems_status_code code)
+{
+ int rc;
+
+ if ((rc = rtems_assoc_remote_by_local(errno_assoc, (uint32_t ) code)))
+ {
+ errno = rc;
+ return -1;
+ }
+ return -1;
+}
+
+/*
+ * device_open
+ *
+ * This handler maps an open() operation onto rtems_io_open().
+ */
+
+int device_open(
+ rtems_libio_t *iop,
+ const char *pathname,
+ uint32_t flag,
+ uint32_t mode
+)
+{
+ rtems_libio_open_close_args_t args;
+ rtems_status_code status;
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = iop->file_info;
+
+ args.iop = iop;
+ args.flags = iop->flags;
+ args.mode = mode;
+
+ status = rtems_io_open(
+ the_jnode->info.device.major,
+ the_jnode->info.device.minor,
+ (void *) &args
+ );
+ if ( status )
+ return rtems_deviceio_errno(status);
+
+ return 0;
+}
+
+/*
+ * device_close
+ *
+ * This handler maps a close() operation onto rtems_io_close().
+ */
+
+int device_close(
+ rtems_libio_t *iop
+)
+{
+ rtems_libio_open_close_args_t args;
+ rtems_status_code status;
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = iop->file_info;
+
+ args.iop = iop;
+ args.flags = 0;
+ args.mode = 0;
+
+ status = rtems_io_close(
+ the_jnode->info.device.major,
+ the_jnode->info.device.minor,
+ (void *) &args
+ );
+ if ( status ) {
+ return rtems_deviceio_errno(status);
+ }
+ return 0;
+}
+
+/*
+ * device_read
+ *
+ * This handler maps a read() operation onto rtems_io_read().
+ */
+
+ssize_t device_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ uint32_t count
+)
+{
+ rtems_libio_rw_args_t args;
+ rtems_status_code status;
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = iop->file_info;
+
+ args.iop = iop;
+ args.offset = iop->offset;
+ args.buffer = buffer;
+ args.count = count;
+ args.flags = iop->flags;
+ args.bytes_moved = 0;
+
+ status = rtems_io_read(
+ the_jnode->info.device.major,
+ the_jnode->info.device.minor,
+ (void *) &args
+ );
+
+ if ( status )
+ return rtems_deviceio_errno(status);
+
+ return (ssize_t) args.bytes_moved;
+}
+
+/*
+ * device_write
+ *
+ * This handler maps a write() operation onto rtems_io_write().
+ */
+
+ssize_t device_write(
+ rtems_libio_t *iop,
+ const void *buffer,
+ uint32_t count
+)
+{
+ rtems_libio_rw_args_t args;
+ rtems_status_code status;
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = iop->file_info;
+
+ args.iop = iop;
+ args.offset = iop->offset;
+ args.buffer = (void *) buffer;
+ args.count = count;
+ args.flags = iop->flags;
+ args.bytes_moved = 0;
+
+ status = rtems_io_write(
+ the_jnode->info.device.major,
+ the_jnode->info.device.minor,
+ (void *) &args
+ );
+
+ if ( status )
+ return rtems_deviceio_errno(status);
+
+ return (ssize_t) args.bytes_moved;
+}
+
+/*
+ * device_ioctl
+ *
+ * This handler maps an ioctl() operation onto rtems_io_ioctl().
+ */
+
+int device_ioctl(
+ rtems_libio_t *iop,
+ uint32_t command,
+ void *buffer
+)
+{
+ rtems_libio_ioctl_args_t args;
+ rtems_status_code status;
+ IMFS_jnode_t *the_jnode;
+
+ args.iop = iop;
+ args.command = command;
+ args.buffer = buffer;
+
+ the_jnode = iop->file_info;
+
+ status = rtems_io_control(
+ the_jnode->info.device.major,
+ the_jnode->info.device.minor,
+ (void *) &args
+ );
+
+ if ( status )
+ return rtems_deviceio_errno(status);
+
+ return args.ioctl_return;
+}
+
+/*
+ * device_lseek
+ *
+ * This handler eats all lseek() operations.
+ */
+
+int device_lseek(
+ rtems_libio_t *iop,
+ off_t offset,
+ int whence
+)
+{
+ return 0;
+}
+
+/*
+ * device_stat
+ *
+ * The IMFS_stat() is used.
+ */
+
+/*
+ * device_rmnod
+ *
+ * The IMFS_rmnod() is used.
+ */
diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h
new file mode 100644
index 0000000000..a5e82a1579
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs.h
@@ -0,0 +1,539 @@
+/*
+ * Header file for the In-Memory File System
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_IMFS_H
+#define _RTEMS_IMFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <rtems/chain.h>
+
+#include <sys/types.h>
+#include <limits.h>
+#include <rtems/libio.h>
+
+/*
+ * File name macros
+ */
+
+#define IMFS_is_valid_name_char( _ch ) ( 1 )
+
+#define IMFS_is_separator( _ch ) \
+ rtems_filesystem_is_separator( _ch )
+
+/*
+ * Data types
+ */
+
+struct IMFS_jnode_tt;
+typedef struct IMFS_jnode_tt IMFS_jnode_t;
+
+typedef struct {
+ Chain_Control Entries;
+ rtems_filesystem_mount_table_entry_t *mt_fs;
+} IMFS_directory_t;
+
+typedef struct {
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+} IMFS_device_t;
+
+typedef struct {
+ IMFS_jnode_t *link_node;
+} IMFS_link_t;
+
+typedef struct {
+ const char *name;
+} IMFS_sym_link_t;
+
+/*
+ * IMFS "memfile" information
+ *
+ * The data structure for the in-memory "memfiles" is based on classic UNIX.
+ *
+ * block_ptr is a pointer to a block of IMFS_MEMFILE_BYTES_PER_BLOCK in
+ * length which could be data or a table of pointers to blocks.
+ *
+ * Setting IMFS_MEMFILE_BYTES_PER_BLOCK to different values has a significant
+ * impact on the maximum file size supported as well as the amount of
+ * memory wasted due to internal file fragmentation. The following
+ * is a list of maximum file sizes based on various settings
+ *
+ * max_filesize with blocks of 16 is 1,328
+ * max_filesize with blocks of 32 is 18,656
+ * max_filesize with blocks of 64 is 279,488
+ * max_filesize with blocks of 128 is 4,329,344
+ * max_filesize with blocks of 256 is 68,173,568
+ * max_filesize with blocks of 512 is 1,082,195,456
+ */
+
+#define IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK 128
+ extern int imfs_rq_memfile_bytes_per_block;
+ /*
+ * FIXME: make and use derivates from this,
+ * a shift count and a mask
+ */
+ extern int imfs_memfile_bytes_per_block;
+
+#define IMFS_MEMFILE_BYTES_PER_BLOCK imfs_memfile_bytes_per_block
+#define IMFS_MEMFILE_BLOCK_SLOTS \
+ (IMFS_MEMFILE_BYTES_PER_BLOCK / sizeof(void *))
+
+typedef uint8_t *block_p;
+typedef block_p *block_ptr;
+
+typedef struct {
+ off_t size; /* size of file in bytes */
+ block_ptr indirect; /* array of 128 data blocks pointers */
+ block_ptr doubly_indirect; /* 128 indirect blocks */
+ block_ptr triply_indirect; /* 128 doubly indirect blocks */
+} IMFS_memfile_t;
+
+typedef struct {
+ off_t size; /* size of file in bytes */
+ block_p direct; /* pointer to file image */
+} IMFS_linearfile_t;
+
+/*
+ * Important block numbers for "memfiles"
+ */
+
+#define FIRST_INDIRECT (0)
+#define LAST_INDIRECT (IMFS_MEMFILE_BLOCK_SLOTS - 1)
+
+#define FIRST_DOUBLY_INDIRECT (LAST_INDIRECT + 1)
+#define LAST_DOUBLY_INDIRECT \
+ (LAST_INDIRECT + \
+ (IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
+
+#define FIRST_TRIPLY_INDIRECT (LAST_DOUBLY_INDIRECT + 1)
+#define LAST_TRIPLY_INDIRECT \
+ (LAST_DOUBLY_INDIRECT +\
+ (IMFS_MEMFILE_BLOCK_SLOTS * \
+ IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
+
+#define IMFS_MEMFILE_MAXIMUM_SIZE \
+ (LAST_TRIPLY_INDIRECT * IMFS_MEMFILE_BYTES_PER_BLOCK)
+
+/*
+ * What types of IMFS file systems entities there can be.
+ */
+
+#define IMFS_jnode_types_t rtems_filesystem_node_types_t
+#define IMFS_DIRECTORY RTEMS_FILESYSTEM_DIRECTORY
+#define IMFS_DEVICE RTEMS_FILESYSTEM_DEVICE
+#define IMFS_HARD_LINK RTEMS_FILESYSTEM_HARD_LINK
+#define IMFS_SYM_LINK RTEMS_FILESYSTEM_SYM_LINK
+#define IMFS_MEMORY_FILE RTEMS_FILESYSTEM_MEMORY_FILE
+#define IMFS_LINEAR_FILE (IMFS_MEMORY_FILE + 1)
+
+#define IMFS_NUMBER_OF_TYPES (IMFS_LINEAR_FILE + 1)
+
+typedef union {
+ IMFS_directory_t directory;
+ IMFS_device_t device;
+ IMFS_link_t hard_link;
+ IMFS_sym_link_t sym_link;
+ IMFS_memfile_t file;
+ IMFS_linearfile_t linearfile;
+} IMFS_types_union;
+
+/*
+ * Maximum length of a "basename" of an IMFS file/node.
+ */
+
+#define IMFS_NAME_MAX 32
+
+/*
+ * The control structure for an IMFS jnode.
+ */
+
+struct IMFS_jnode_tt {
+ Chain_Node Node; /* for chaining them together */
+ IMFS_jnode_t *Parent; /* Parent node */
+ char name[IMFS_NAME_MAX+1]; /* "basename" */
+ mode_t st_mode; /* File mode */
+ nlink_t st_nlink; /* Link count */
+ ino_t st_ino; /* inode */
+
+ uid_t st_uid; /* User ID of owner */
+ gid_t st_gid; /* Group ID of owner */
+
+ time_t stat_atime; /* Time of last access */
+ time_t stat_mtime; /* Time of last modification */
+ time_t stat_ctime; /* Time of last status change */
+ IMFS_jnode_types_t type; /* Type of this entry */
+ IMFS_types_union info;
+};
+
+#define IMFS_update_atime( _jnode ) \
+ do { \
+ struct timeval tv; \
+ gettimeofday( &tv, 0 ); \
+ _jnode->stat_atime = (time_t) tv.tv_sec; \
+ } while (0)
+
+#define IMFS_update_mtime( _jnode ) \
+ do { \
+ struct timeval tv; \
+ gettimeofday( &tv, 0 ); \
+ _jnode->stat_mtime = (time_t) tv.tv_sec; \
+ } while (0)
+
+#define IMFS_update_ctime( _jnode ) \
+ do { \
+ struct timeval tv; \
+ gettimeofday( &tv, 0 ); \
+ _jnode->stat_ctime = (time_t) tv.tv_sec; \
+ } while (0)
+
+#define IMFS_atime_mtime_update( _jnode ) \
+ do { \
+ struct timeval tv; \
+ gettimeofday( &tv, 0 ); \
+ _jnode->stat_mtime = (time_t) tv.tv_sec; \
+ _jnode->stat_atime = (time_t) tv.tv_sec; \
+ } while (0)
+
+typedef struct {
+ ino_t ino_count;
+ rtems_filesystem_file_handlers_r *memfile_handlers;
+ rtems_filesystem_file_handlers_r *directory_handlers;
+} IMFS_fs_info_t;
+
+#if UNUSED
+/* FIXME: Unused, we might want to remove it */
+#define increment_and_check_linkcounts( _fs_info ) \
+ ((IMFS_fs_info_t * )_fs_info)->link_counts++; \
+ if ( ((IMFS_fs_info_t * )_fs_info)->link_counts > MAXSYMLINKS ) \
+ rtems_set_errno_and_return_minus_one( ELOOP )
+#endif
+
+#define decrement_linkcounts( _fs_info ) \
+ ((IMFS_fs_info_t * )_fs_info)->link_counts--;
+
+/*
+ * Type defination for tokens returned from IMFS_get_token
+ */
+
+typedef enum {
+ IMFS_NO_MORE_PATH,
+ IMFS_CURRENT_DIR,
+ IMFS_UP_DIR,
+ IMFS_NAME,
+ IMFS_INVALID_TOKEN
+} IMFS_token_types;
+
+/*
+ * Shared Data
+ */
+
+extern rtems_filesystem_file_handlers_r IMFS_directory_handlers;
+extern rtems_filesystem_file_handlers_r IMFS_device_handlers;
+extern rtems_filesystem_file_handlers_r IMFS_link_handlers;
+extern rtems_filesystem_file_handlers_r IMFS_memfile_handlers;
+extern rtems_filesystem_operations_table IMFS_ops;
+extern rtems_filesystem_operations_table miniIMFS_ops;
+extern rtems_filesystem_limits_and_options_t IMFS_LIMITS_AND_OPTIONS;
+
+/*
+ * Routines
+ */
+
+int IMFS_initialize(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+int miniIMFS_initialize(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+int IMFS_initialize_support(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ rtems_filesystem_operations_table *op_table,
+ rtems_filesystem_file_handlers_r *memfile_handlers,
+ rtems_filesystem_file_handlers_r *directory_handlers
+);
+
+int IMFS_fsunmount(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+int rtems_tarfs_load(
+ char *mountpoint,
+ uint8_t *tar_image,
+ size_t tar_size
+);
+
+/*
+ * Returns the number of characters copied from path to token.
+ */
+IMFS_token_types IMFS_get_token(
+ const char *path,
+ char *token,
+ int *token_len
+);
+
+void IMFS_dump( void );
+
+void IMFS_initialize_jnode(
+ IMFS_jnode_t *the_jnode,
+ IMFS_jnode_types_t type,
+ IMFS_jnode_t *the_parent,
+ char *name,
+ mode_t mode
+);
+
+IMFS_jnode_t *IMFS_find_match_in_dir(
+ IMFS_jnode_t *directory, /* IN */
+ char *name /* IN */
+);
+
+rtems_filesystem_node_types_t IMFS_node_type(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+int IMFS_stat(
+ rtems_filesystem_location_info_t *loc, /* IN */
+ struct stat *buf /* OUT */
+);
+
+int IMFS_Set_handlers(
+ rtems_filesystem_location_info_t *loc
+);
+
+int IMFS_evaluate_link(
+ rtems_filesystem_location_info_t *node, /* IN/OUT */
+ int flags /* IN */
+);
+
+int IMFS_eval_path(
+ const char *pathname, /* IN */
+ int flags, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+);
+
+
+int IMFS_link(
+ rtems_filesystem_location_info_t *to_loc, /* IN */
+ rtems_filesystem_location_info_t *parent_loc, /* IN */
+ const char *token /* IN */
+);
+
+int IMFS_unlink(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+int IMFS_chown(
+ rtems_filesystem_location_info_t *pathloc, /* IN */
+ uid_t owner, /* IN */
+ gid_t group /* IN */
+);
+
+int IMFS_freenodinfo(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+int IMFS_mknod(
+ const char *path, /* IN */
+ mode_t mode, /* IN */
+ dev_t dev, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+);
+
+IMFS_jnode_t *IMFS_create_node(
+ rtems_filesystem_location_info_t *parent_loc, /* IN */
+ IMFS_jnode_types_t type, /* IN */
+ char *name, /* IN */
+ mode_t mode, /* IN */
+ IMFS_types_union *info /* IN */
+);
+
+int IMFS_evaluate_for_make(
+ const char *path, /* IN */
+ rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
+ const char **name /* OUT */
+);
+
+int IMFS_mount(
+ rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
+);
+
+int IMFS_unmount(
+ rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
+);
+
+int IMFS_freenod(
+ rtems_filesystem_location_info_t *node /* IN/OUT */
+);
+
+int IMFS_memfile_remove(
+ IMFS_jnode_t *the_jnode /* IN/OUT */
+);
+
+int memfile_ftruncate(
+ rtems_libio_t *iop, /* IN */
+ off_t length /* IN */
+);
+
+int imfs_dir_open(
+ rtems_libio_t *iop, /* IN */
+ const char *pathname, /* IN */
+ uint32_t flag, /* IN */
+ uint32_t mode /* IN */
+);
+
+int imfs_dir_close(
+ rtems_libio_t *iop /* IN */
+);
+
+ssize_t imfs_dir_read(
+ rtems_libio_t *iop, /* IN */
+ void *buffer, /* IN */
+ uint32_t count /* IN */
+);
+
+int imfs_dir_lseek(
+ rtems_libio_t *iop, /* IN */
+ off_t offset, /* IN */
+ int whence /* IN */
+);
+
+int imfs_dir_fstat(
+ rtems_filesystem_location_info_t *loc, /* IN */
+ struct stat *buf /* OUT */
+);
+
+int imfs_dir_rmnod(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+int memfile_open(
+ rtems_libio_t *iop, /* IN */
+ const char *pathname, /* IN */
+ uint32_t flag, /* IN */
+ uint32_t mode /* IN */
+);
+
+int memfile_close(
+ rtems_libio_t *iop /* IN */
+);
+
+ssize_t memfile_read(
+ rtems_libio_t *iop, /* IN */
+ void *buffer, /* IN */
+ uint32_t count /* IN */
+);
+
+ssize_t memfile_write(
+ rtems_libio_t *iop, /* IN */
+ const void *buffer, /* IN */
+ uint32_t count /* IN */
+);
+
+int memfile_ioctl(
+ rtems_libio_t *iop, /* IN */
+ uint32_t command, /* IN */
+ void *buffer /* IN */
+);
+
+int memfile_lseek(
+ rtems_libio_t *iop, /* IN */
+ off_t offset, /* IN */
+ int whence /* IN */
+);
+
+int memfile_rmnod(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+int device_open(
+ rtems_libio_t *iop, /* IN */
+ const char *pathname, /* IN */
+ uint32_t flag, /* IN */
+ uint32_t mode /* IN */
+);
+
+int device_close(
+ rtems_libio_t *iop /* IN */
+);
+
+ssize_t device_read(
+ rtems_libio_t *iop, /* IN */
+ void *buffer, /* IN */
+ uint32_t count /* IN */
+);
+
+ssize_t device_write(
+ rtems_libio_t *iop, /* IN */
+ const void *buffer, /* IN */
+ uint32_t count /* IN */
+);
+
+int device_ioctl(
+ rtems_libio_t *iop, /* IN */
+ uint32_t command, /* IN */
+ void *buffer /* IN */
+);
+
+int device_lseek(
+ rtems_libio_t *iop, /* IN */
+ off_t offset, /* IN */
+ int whence /* IN */
+);
+
+int IMFS_utime(
+ rtems_filesystem_location_info_t *pathloc, /* IN */
+ time_t actime, /* IN */
+ time_t modtime /* IN */
+);
+
+int IMFS_fchmod(
+ rtems_filesystem_location_info_t *loc,
+ mode_t mode
+);
+
+int IMFS_symlink(
+ rtems_filesystem_location_info_t *parent_loc, /* IN */
+ const char *link_name,
+ const char *node_name
+);
+
+int IMFS_readlink(
+ rtems_filesystem_location_info_t *loc, /* IN */
+ char *buf, /* OUT */
+ size_t bufsize
+);
+
+int IMFS_fdatasync(
+ rtems_libio_t *iop
+);
+
+int IMFS_fcntl(
+ int cmd,
+ rtems_libio_t *iop
+);
+
+int IMFS_rmnod(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libfs/src/imfs/imfs_chown.c b/cpukit/libfs/src/imfs/imfs_chown.c
new file mode 100644
index 0000000000..7f0c7b5688
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_chown.c
@@ -0,0 +1,56 @@
+/*
+ * IMFS_chown
+ *
+ * This routine is the implementation of the chown() system
+ * call for the IMFS.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+#include "imfs.h"
+
+int IMFS_chown(
+ rtems_filesystem_location_info_t *pathloc, /* IN */
+ uid_t owner, /* IN */
+ gid_t group /* IN */
+)
+{
+ IMFS_jnode_t *jnode;
+#if defined(RTEMS_POSIX_API)
+ uid_t st_uid;
+#endif
+
+ jnode = (IMFS_jnode_t *) pathloc->node_access;
+
+ /*
+ * Verify I am the owner of the node or the super user.
+ */
+
+#if defined(RTEMS_POSIX_API)
+ st_uid = geteuid();
+
+ if ( ( st_uid != jnode->st_uid ) && ( st_uid != 0 ) )
+ rtems_set_errno_and_return_minus_one( EPERM );
+#endif
+
+ jnode->st_uid = owner;
+ jnode->st_gid = group;
+
+ IMFS_update_ctime( jnode );
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_config.c b/cpukit/libfs/src/imfs/imfs_config.c
new file mode 100644
index 0000000000..20da389fa2
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_config.c
@@ -0,0 +1,35 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio_.h>
+#include "imfs.h"
+
+/* XXX this structure should use real constants */
+
+rtems_filesystem_limits_and_options_t IMFS_LIMITS_AND_OPTIONS = {
+ 5, /* link_max */
+ 6, /* max_canon */
+ 7, /* max_input */
+ IMFS_NAME_MAX, /* name_max */
+ 255, /* path_max */
+ 2, /* pipe_buf */
+ 1, /* posix_async_io */
+ 2, /* posix_chown_restrictions */
+ 3, /* posix_no_trunc */
+ 4, /* posix_prio_io */
+ 5, /* posix_sync_io */
+ 6 /* posix_vdisable */
+};
diff --git a/cpukit/libfs/src/imfs/imfs_creat.c b/cpukit/libfs/src/imfs/imfs_creat.c
new file mode 100644
index 0000000000..94d9dac9c1
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_creat.c
@@ -0,0 +1,137 @@
+/*
+ * IMFS_create_node()
+ *
+ * Routine to create a new in memory file system node.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "imfs.h"
+#include <rtems/libio_.h>
+
+IMFS_jnode_t *IMFS_create_node(
+ rtems_filesystem_location_info_t *parent_loc,
+ IMFS_jnode_types_t type,
+ char *name,
+ mode_t mode,
+ IMFS_types_union *info
+)
+{
+ IMFS_jnode_t *node;
+ struct timeval tv;
+ IMFS_jnode_t *parent = NULL;
+ IMFS_fs_info_t *fs_info;
+ char *sym_name;
+
+ if ( parent_loc != NULL )
+ parent = parent_loc->node_access;
+
+ /*
+ * Allocate an IMFS jnode
+ */
+
+ node = calloc( 1, sizeof( IMFS_jnode_t ) );
+ if ( !node )
+ return NULL;
+
+ /*
+ * Fill in the basic information
+ */
+
+ node->st_nlink = 1;
+ node->type = type;
+ strncpy( node->name, name, IMFS_NAME_MAX );
+
+ /*
+ * Fill in the mode and permission information for the jnode structure.
+ */
+
+ node->st_mode = mode & ~rtems_filesystem_umask;
+
+#if defined(RTEMS_POSIX_API)
+ node->st_uid = geteuid();
+ node->st_gid = getegid();
+#else
+ node->st_uid = 0;
+ node->st_gid = 0;
+#endif
+
+ /*
+ * Now set all the times.
+ */
+
+ gettimeofday( &tv, 0 );
+
+ node->stat_atime = (time_t) tv.tv_sec;
+ node->stat_mtime = (time_t) tv.tv_sec;
+ node->stat_ctime = (time_t) tv.tv_sec;
+
+ /*
+ * Set the type specific information
+ */
+
+ switch (type) {
+ case IMFS_DIRECTORY:
+ Chain_Initialize_empty(&node->info.directory.Entries);
+ break;
+
+ case IMFS_HARD_LINK:
+ node->info.hard_link.link_node = info->hard_link.link_node;
+ break;
+
+ case IMFS_SYM_LINK:
+ sym_name = calloc( 1, strlen( info->sym_link.name ) + 1 );
+ strcpy( sym_name, info->sym_link.name );
+ node->info.sym_link.name = sym_name;
+ break;
+
+ case IMFS_DEVICE:
+ node->info.device.major = info->device.major;
+ node->info.device.minor = info->device.minor;
+ break;
+
+ case IMFS_LINEAR_FILE:
+ node->info.linearfile.size = 0;
+ node->info.linearfile.direct = 0;
+
+ case IMFS_MEMORY_FILE:
+ node->info.file.size = 0;
+ node->info.file.indirect = 0;
+ node->info.file.doubly_indirect = 0;
+ node->info.file.triply_indirect = 0;
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ /*
+ * If this node has a parent, then put it in that directory list.
+ */
+
+ if ( parent ) {
+ Chain_Append( &parent->info.directory.Entries, &node->Node );
+ node->Parent = parent;
+
+ fs_info = parent_loc->mt_entry->fs_info;
+ node->st_ino = ++fs_info->ino_count;
+ }
+
+
+ return node;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_debug.c b/cpukit/libfs/src/imfs/imfs_debug.c
new file mode 100644
index 0000000000..e42198a4b8
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_debug.c
@@ -0,0 +1,176 @@
+/*
+ * IMFS debug support routines
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h> /* for close */
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+
+/*
+ * IMFS_types
+ *
+ * Printable names for each of the IMFS file system types.
+ */
+
+char *IMFS_types[ IMFS_NUMBER_OF_TYPES ] = {
+ "directory",
+ "device",
+ "link",
+ "memory file",
+ "linear file"
+};
+
+/*
+ * IMFS_print_jnode
+ *
+ * This routine prints the contents of the specified jnode.
+ */
+
+void IMFS_print_jnode(
+ IMFS_jnode_t *the_jnode
+)
+{
+ assert( the_jnode );
+
+ fprintf(stdout, "%s", the_jnode->name );
+ switch( the_jnode->type ) {
+ case IMFS_DIRECTORY:
+ fprintf(stdout, "/" );
+ break;
+
+ case IMFS_DEVICE:
+ fprintf(stdout, " (device %d, %d)",
+ the_jnode->info.device.major, the_jnode->info.device.minor );
+ break;
+
+ case IMFS_LINEAR_FILE:
+ fprintf(stdout, " (file %d %p)",
+ (int)the_jnode->info.linearfile.size,
+ the_jnode->info.linearfile.direct
+ );
+ break;
+
+ case IMFS_MEMORY_FILE:
+ /* Useful when debugging .. varies between targets */
+#if 0
+ fprintf(stdout, " (file %d %p %p %p)",
+ (int)the_jnode->info.file.size,
+ the_jnode->info.file.indirect,
+ the_jnode->info.file.doubly_indirect,
+ the_jnode->info.file.triply_indirect
+ );
+#else
+ fprintf(stdout, " (file %d)", (int)the_jnode->info.file.size );
+#endif
+ break;
+
+ case IMFS_HARD_LINK:
+ fprintf(stdout, " links not printed\n" );
+ assert(0);
+ break;
+
+ case IMFS_SYM_LINK:
+ fprintf(stdout, " links not printed\n" );
+ assert(0);
+ break;
+
+ default:
+ fprintf(stdout, " bad type %d\n", the_jnode->type );
+ assert(0);
+ break;
+ }
+ puts("");
+}
+
+/*
+ * IMFS_dump_directory
+ *
+ * This routine prints the contents of a directory in the IMFS. If a
+ * directory is encountered, then this routine will recurse to process
+ * the subdirectory.
+ */
+
+void IMFS_dump_directory(
+ IMFS_jnode_t *the_directory,
+ int level
+)
+{
+ Chain_Node *the_node;
+ Chain_Control *the_chain;
+ IMFS_jnode_t *the_jnode;
+ int i;
+
+ assert( the_directory );
+
+ assert( level >= 0 );
+
+ assert( the_directory->type == IMFS_DIRECTORY );
+
+ the_chain = &the_directory->info.directory.Entries;
+
+ for ( the_node = the_chain->first;
+ !_Chain_Is_tail( the_chain, the_node );
+ the_node = the_node->next ) {
+
+ the_jnode = (IMFS_jnode_t *) the_node;
+
+ for ( i=0 ; i<=level ; i++ )
+ fprintf(stdout, "...." );
+ IMFS_print_jnode( the_jnode );
+ if ( the_jnode->type == IMFS_DIRECTORY )
+ IMFS_dump_directory( the_jnode, level + 1 );
+ }
+}
+
+/*
+ * IMFS_dump
+ *
+ * This routine dumps the entire IMFS that is mounted at the root
+ * directory.
+ *
+ * NOTE: Assuming the "/" directory is bad.
+ * Not checking that the starting directory is in an IMFS is bad.
+ */
+
+void IMFS_dump( void )
+{
+ fprintf(stdout, "*************** Dump of Entire IMFS ***************\n" );
+ fprintf(stdout, "/\n" );
+ IMFS_dump_directory( rtems_filesystem_root.node_access, 0 );
+ fprintf(stdout, "*************** End of Dump ***************\n" );
+}
+
+/*
+ * IMFS_memfile_maximum_size()
+ *
+ * This routine returns the size of the largest file which can be created
+ * using the IMFS memory file type.
+ *
+ */
+
+int IMFS_memfile_maximum_size( void )
+{
+ return IMFS_MEMFILE_MAXIMUM_SIZE;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_directory.c b/cpukit/libfs/src/imfs/imfs_directory.c
new file mode 100644
index 0000000000..b5ce125321
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_directory.c
@@ -0,0 +1,351 @@
+/*
+ * IMFS Directory Access Routines
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <rtems/chain.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <dirent.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+/*
+ * imfs_dir_open
+ *
+ * This rountine will verify that the node being opened as a directory is
+ * in fact a directory node. If it is then the offset into the directory
+ * will be set to 0 to position to the first directory entry.
+ */
+
+int imfs_dir_open(
+ rtems_libio_t *iop,
+ const char *pathname,
+ uint32_t flag,
+ uint32_t mode
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ /* Is the node a directory ? */
+ the_jnode = (IMFS_jnode_t *) iop->file_info;
+
+ if ( the_jnode->type != IMFS_DIRECTORY )
+ return -1; /* It wasn't a directory --> return error */
+
+ iop->offset = 0;
+ return 0;
+}
+
+/*
+ * imfs_dir_read
+ *
+ * This routine will read the next directory entry based on the directory
+ * offset. The offset should be equal to -n- time the size of an individual
+ * dirent structure. If n is not an integer multiple of the sizeof a
+ * dirent structure, an integer division will be performed to determine
+ * directory entry that will be returned in the buffer. Count should reflect
+ * -m- times the sizeof dirent bytes to be placed in the buffer.
+ * If there are not -m- dirent elements from the current directory position
+ * to the end of the exisiting file, the remaining entries will be placed in
+ * the buffer and the returned value will be equal to -m actual- times the
+ * size of a directory entry.
+ */
+
+ssize_t imfs_dir_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ uint32_t count
+)
+{
+ /*
+ * Read up to element iop->offset in the directory chain of the
+ * imfs_jnode_t struct for this file descriptor.
+ */
+ Chain_Node *the_node;
+ Chain_Control *the_chain;
+ IMFS_jnode_t *the_jnode;
+ int bytes_transferred;
+ int current_entry;
+ int first_entry;
+ int last_entry;
+ struct dirent tmp_dirent;
+
+ the_jnode = (IMFS_jnode_t *)iop->file_info;
+ the_chain = &the_jnode->info.directory.Entries;
+
+ if ( Chain_Is_empty( the_chain ) )
+ return 0;
+
+ /* Move to the first of the desired directory entries */
+ the_node = the_chain->first;
+
+ bytes_transferred = 0;
+ first_entry = iop->offset;
+ /* protect against using sizes that are not exact multiples of the */
+ /* -dirent- size. These could result in unexpected results */
+ last_entry = first_entry + (count/sizeof(struct dirent)) * sizeof(struct dirent);
+
+ /* The directory was not empty so try to move to the desired entry in chain*/
+ for (
+ current_entry = 0;
+ current_entry < last_entry;
+ current_entry = current_entry + sizeof(struct dirent) ){
+
+ if ( Chain_Is_tail( the_chain, the_node ) ){
+ /* We hit the tail of the chain while trying to move to the first */
+ /* entry in the read */
+ return bytes_transferred; /* Indicate that there are no more */
+ /* entries to return */
+ }
+
+ if( current_entry >= first_entry ) {
+ /* Move the entry to the return buffer */
+ tmp_dirent.d_off = current_entry;
+ tmp_dirent.d_reclen = sizeof( struct dirent );
+ the_jnode = (IMFS_jnode_t *) the_node;
+ tmp_dirent.d_ino = the_jnode->st_ino;
+ tmp_dirent.d_namlen = strlen( the_jnode->name );
+ strcpy( tmp_dirent.d_name, the_jnode->name );
+ memcpy(
+ buffer + bytes_transferred,
+ (void *)&tmp_dirent,
+ sizeof( struct dirent )
+ );
+ iop->offset = iop->offset + sizeof(struct dirent);
+ bytes_transferred = bytes_transferred + sizeof( struct dirent );
+ }
+
+ the_node = the_node->next;
+ }
+
+ /* Success */
+ return bytes_transferred;
+}
+
+
+
+/*
+ * imfs_dir_close
+ *
+ * This routine will be called by the generic close routine to cleanup any
+ * resources that have been allocated for the management of the file
+ */
+
+int imfs_dir_close(
+ rtems_libio_t *iop
+)
+{
+ /*
+ * The generic close routine handles the deallocation of the file control
+ * and associated memory. At present the imfs_dir_close simply
+ * returns a successful completion status.
+ */
+
+ return 0;
+}
+
+
+
+/*
+ * imfs_dir_lseek
+ *
+ * This routine will behave in one of three ways based on the state of
+ * argument whence. Based on the state of its value the offset argument will
+ * be interpreted using one of the following methods:
+ *
+ * SEEK_SET - offset is the absolute byte offset from the start of the
+ * logical start of the dirent sequence that represents the
+ * directory
+ * SEEK_CUR - offset is used as the relative byte offset from the current
+ * directory position index held in the iop structure
+ * SEEK_END - N/A --> This will cause an assert.
+ */
+
+int imfs_dir_lseek(
+ rtems_libio_t *iop,
+ off_t offset,
+ int whence
+)
+{
+ switch( whence ) {
+ case SEEK_SET: /* absolute move from the start of the file */
+ case SEEK_CUR: /* relative move */
+ iop->offset = (iop->offset/sizeof(struct dirent)) *
+ sizeof(struct dirent);
+ break;
+
+ case SEEK_END: /* Movement past the end of the directory via lseek */
+ /* is not a permitted operation */
+ default:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ break;
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * imfs_dir_fstat
+ *
+ * This routine will obtain the following information concerning the current
+ * directory:
+ * st_dev 0ll
+ * st_ino 1
+ * st_mode mode extracted from the jnode
+ * st_nlink number of links to this node
+ * st_uid uid extracted from the jnode
+ * st_gid gid extracted from the jnode
+ * st_rdev 0ll
+ * st_size the number of bytes in the directory
+ * This is calculated by taking the number of entries
+ * in the directory and multiplying by the size of a
+ * dirent structure
+ * st_blksize 0
+ * st_blocks 0
+ * stat_atime time of last access
+ * stat_mtime time of last modification
+ * stat_ctime time of the last change
+ *
+ * This information will be returned to the calling function in a -stat- struct
+ *
+ */
+
+int imfs_dir_fstat(
+ rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+)
+{
+ Chain_Node *the_node;
+ Chain_Control *the_chain;
+ IMFS_jnode_t *the_jnode;
+
+
+ the_jnode = (IMFS_jnode_t *) loc->node_access;
+
+ buf->st_dev = 0ll;
+ buf->st_ino = the_jnode->st_ino;
+ buf->st_mode = the_jnode->st_mode;
+ buf->st_nlink = the_jnode->st_nlink;
+ buf->st_uid = the_jnode->st_uid;
+ buf->st_gid = the_jnode->st_gid;
+ buf->st_rdev = 0ll;
+ buf->st_blksize = 0;
+ buf->st_blocks = 0;
+ buf->st_atime = the_jnode->stat_atime;
+ buf->st_mtime = the_jnode->stat_mtime;
+ buf->st_ctime = the_jnode->stat_ctime;
+
+ buf->st_size = 0;
+
+ the_chain = &the_jnode->info.directory.Entries;
+
+ /* Run through the chain and count the number of directory entries */
+ /* that are subordinate to this directory node */
+ for ( the_node = the_chain->first ;
+ !_Chain_Is_tail( the_chain, the_node ) ;
+ the_node = the_node->next ) {
+
+ buf->st_size = buf->st_size + sizeof( struct dirent );
+ }
+
+ return 0;
+}
+
+/*
+ * IMFS_dir_rmnod
+ *
+ * This routine is available from the optable to remove a node
+ * from the IMFS file system.
+ */
+
+int imfs_dir_rmnod(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = (IMFS_jnode_t *) pathloc->node_access;
+
+ /*
+ * You cannot remove a node that still has children
+ */
+
+ if ( ! Chain_Is_empty( &the_jnode->info.directory.Entries ) )
+ rtems_set_errno_and_return_minus_one( ENOTEMPTY );
+
+ /*
+ * You cannot remove the file system root node.
+ */
+
+ if ( pathloc->mt_entry->mt_fs_root.node_access == pathloc->node_access )
+ rtems_set_errno_and_return_minus_one( EBUSY );
+
+ /*
+ * You cannot remove a mountpoint.
+ */
+
+ if ( the_jnode->info.directory.mt_fs != NULL )
+ rtems_set_errno_and_return_minus_one( EBUSY );
+
+ /*
+ * Take the node out of the parent's chain that contains this node
+ */
+
+ if ( the_jnode->Parent != NULL ) {
+ Chain_Extract( (Chain_Node *) the_jnode );
+ the_jnode->Parent = NULL;
+ }
+
+ /*
+ * Decrement the link counter and see if we can free the space.
+ */
+
+ the_jnode->st_nlink--;
+ IMFS_update_ctime( the_jnode );
+
+ /*
+ * The file cannot be open and the link must be less than 1 to free.
+ */
+
+ if ( !rtems_libio_is_file_open( the_jnode ) && (the_jnode->st_nlink < 1) ) {
+
+ /*
+ * Is the rtems_filesystem_current is this node?
+ */
+
+ if ( rtems_filesystem_current.node_access == pathloc->node_access )
+ rtems_filesystem_current.node_access = NULL;
+
+ /*
+ * Free memory associated with a memory file.
+ */
+
+ free( the_jnode );
+ }
+
+ return 0;
+
+}
diff --git a/cpukit/libfs/src/imfs/imfs_eval.c b/cpukit/libfs/src/imfs/imfs_eval.c
new file mode 100644
index 0000000000..3d8df0b2e0
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_eval.c
@@ -0,0 +1,660 @@
+/*
+ * Evaluation IMFS Node Support Routines
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+#define RTEMS_LIBIO_PERMS_RX (RTEMS_LIBIO_PERMS_SEARCH | RTEMS_LIBIO_PERMS_READ)
+#define RTEMS_LIBIO_PERMS_WX (RTEMS_LIBIO_PERMS_SEARCH | RTEMS_LIBIO_PERMS_WRITE)
+
+#define MAXSYMLINK 5
+
+int IMFS_Set_handlers(
+ rtems_filesystem_location_info_t *loc
+)
+{
+ IMFS_jnode_t *node = loc->node_access;
+ IMFS_fs_info_t *fs_info;
+
+ fs_info = loc->mt_entry->fs_info;
+ switch( node->type ) {
+ case IMFS_DIRECTORY:
+ loc->handlers = fs_info->directory_handlers;
+ break;
+ case IMFS_DEVICE:
+ loc->handlers = &IMFS_device_handlers;
+ break;
+ case IMFS_SYM_LINK:
+ case IMFS_HARD_LINK:
+ loc->handlers = &IMFS_link_handlers;
+ break;
+ case IMFS_LINEAR_FILE:
+ loc->handlers = fs_info->memfile_handlers;
+ break;
+ case IMFS_MEMORY_FILE:
+ loc->handlers = fs_info->memfile_handlers;
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * IMFS_evaluate_permission
+ *
+ * The following routine evaluates that we have permission
+ * to do flags on the node.
+ */
+
+int IMFS_evaluate_permission(
+ rtems_filesystem_location_info_t *node,
+ int flags
+)
+{
+ uid_t st_uid;
+ gid_t st_gid;
+ IMFS_jnode_t *jnode;
+ int flags_to_test;
+
+ if ( !rtems_libio_is_valid_perms( flags ) ) {
+ assert( 0 );
+ rtems_set_errno_and_return_minus_one( EIO );
+ }
+
+ jnode = node->node_access;
+
+#if defined(RTEMS_POSIX_API)
+ st_uid = geteuid();
+ st_gid = getegid();
+#else
+ st_uid = jnode->st_uid;
+ st_gid = jnode->st_gid;
+#endif
+
+ /*
+ * Check if I am owner or a group member or someone else.
+ */
+
+ flags_to_test = flags;
+
+ if ( st_uid == jnode->st_uid )
+ flags_to_test <<= 6;
+ else if ( st_gid == jnode->st_gid )
+ flags_to_test <<= 3;
+ else
+ /* must be other - do nothing */;
+
+ /*
+ * If all of the flags are set we have permission
+ * to do this.
+ */
+ if ( ( flags_to_test & jnode->st_mode) == flags_to_test )
+ return 1;
+
+ return 0;
+}
+
+/*
+ * IMFS_evaluate_hard_link
+ *
+ * The following routine evaluates a hardlink to the actual node.
+ */
+
+int IMFS_evaluate_hard_link(
+ rtems_filesystem_location_info_t *node, /* IN/OUT */
+ int flags /* IN */
+)
+{
+ IMFS_jnode_t *jnode = node->node_access;
+ int result = 0;
+
+ /*
+ * Check for things that should never happen.
+ */
+
+ if ( jnode->type != IMFS_HARD_LINK )
+ rtems_fatal_error_occurred (0xABCD0000);
+
+ /*
+ * Set the hard link value and the handlers.
+ */
+
+ node->node_access = jnode->info.hard_link.link_node;
+
+ IMFS_Set_handlers( node );
+
+ /*
+ * Verify we have the correct permissions for this node.
+ */
+
+ if ( !IMFS_evaluate_permission( node, flags ) )
+ rtems_set_errno_and_return_minus_one( EACCES );
+
+ return result;
+}
+
+
+/*
+ * IMFS_evaluate_sym_link
+ *
+ * The following routine evaluates a symbolic link to the actual node.
+ */
+
+int IMFS_evaluate_sym_link(
+ rtems_filesystem_location_info_t *node, /* IN/OUT */
+ int flags /* IN */
+)
+{
+ IMFS_jnode_t *jnode = node->node_access;
+ int result = 0;
+ int i;
+
+ /*
+ * Check for things that should never happen.
+ */
+
+ if ( jnode->type != IMFS_SYM_LINK )
+ rtems_fatal_error_occurred (0xABCD0000);
+
+ if ( !jnode->Parent )
+ rtems_fatal_error_occurred( 0xBAD00000 );
+
+
+ /*
+ * Move the node_access to either the symbolic links parent or
+ * root depending on the symbolic links path.
+ */
+
+ node->node_access = jnode->Parent;
+
+ rtems_filesystem_get_sym_start_loc(
+ jnode->info.sym_link.name,
+ &i,
+ node
+ );
+
+ /*
+ * Use eval path to evaluate the path of the symbolic link.
+ */
+
+ result = IMFS_eval_path(
+ &jnode->info.sym_link.name[i],
+ flags,
+ node
+ );
+
+ IMFS_Set_handlers( node );
+
+ /*
+ * Verify we have the correct permissions for this node.
+ */
+
+ if ( !IMFS_evaluate_permission( node, flags ) )
+ rtems_set_errno_and_return_minus_one( EACCES );
+
+ return result;
+}
+
+/*
+ * IMFS_evaluate_link
+ *
+ * The following routine returns the real node pointed to by a link.
+ */
+
+int IMFS_evaluate_link(
+ rtems_filesystem_location_info_t *node, /* IN/OUT */
+ int flags /* IN */
+)
+{
+ IMFS_jnode_t *jnode;
+ int result = 0;
+
+ do {
+ jnode = node->node_access;
+
+ /*
+ * Increment and check the link counter.
+ */
+
+ rtems_filesystem_link_counts ++;
+ if ( rtems_filesystem_link_counts > MAXSYMLINK ) {
+ rtems_filesystem_link_counts = 0;
+ rtems_set_errno_and_return_minus_one( ELOOP );
+ }
+
+ /*
+ * Follow the Link node.
+ */
+
+ if ( jnode->type == IMFS_HARD_LINK )
+ result = IMFS_evaluate_hard_link( node, flags );
+
+ else if (jnode->type == IMFS_SYM_LINK )
+ result = IMFS_evaluate_sym_link( node, flags );
+
+ } while ( ( result == 0 ) && ( ( jnode->type == IMFS_SYM_LINK ) ||
+ ( jnode->type == IMFS_HARD_LINK ) ) );
+
+ /*
+ * Clear link counter.
+ */
+
+ rtems_filesystem_link_counts = 0;
+
+ return result;
+}
+
+
+/*
+ * IMFS_evaluate_for_make
+ *
+ * The following routine evaluate path for a new node to be created.
+ * pathloc is returned with a pointer to the parent of the new node.
+ * name is returned with a pointer to the first character in the
+ * new node name. The parent node is verified to be a directory.
+ */
+
+int IMFS_evaluate_for_make(
+ const char *path, /* IN */
+ rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
+ const char **name /* OUT */
+)
+{
+ int i = 0;
+ int len;
+ IMFS_token_types type;
+ char token[ IMFS_NAME_MAX + 1 ];
+ rtems_filesystem_location_info_t newloc;
+ IMFS_jnode_t *node;
+ int done = 0;
+ int result;
+
+ /*
+ * This was filled in by the caller and is valid in the
+ * mount table.
+ */
+ node = pathloc->node_access;
+
+ /*
+ * Evaluate all tokens until we are done or an error occurs.
+ */
+
+ while( !done ) {
+
+ type = IMFS_get_token( &path[i], token, &len );
+ i += len;
+
+ if ( !pathloc->node_access )
+ rtems_set_errno_and_return_minus_one( ENOENT );
+
+ /*
+ * I cannot move out of this directory without execute permission.
+ */
+
+ if ( type != IMFS_NO_MORE_PATH )
+ if ( node->type == IMFS_DIRECTORY )
+ if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_SEARCH ) )
+ rtems_set_errno_and_return_minus_one( EACCES );
+
+ node = pathloc->node_access;
+
+ switch( type ) {
+
+ case IMFS_UP_DIR:
+ /*
+ * Am I at the root of all filesystems? (chroot'ed?)
+ */
+
+ if ( pathloc->node_access == rtems_filesystem_root.node_access )
+ break; /* Throw out the .. in this case */
+
+
+ /*
+ * Am I at the root of this mounted filesystem?
+ */
+
+ if (pathloc->node_access == pathloc->mt_entry->mt_fs_root.node_access){
+
+ /*
+ * Am I at the root of all filesystems?
+ */
+
+ if ( pathloc->node_access == rtems_filesystem_root.node_access ) {
+ break;
+
+ } else {
+ newloc = pathloc->mt_entry->mt_point_node;
+ *pathloc = newloc;
+ return (*pathloc->ops->evalformake_h)( &path[i-len], pathloc, name );
+ }
+ } else {
+
+ if ( !node->Parent )
+ rtems_set_errno_and_return_minus_one( ENOENT );
+
+ node = node->Parent;
+ }
+
+ pathloc->node_access = node;
+ break;
+
+ case IMFS_NAME:
+
+ if ( node->type == IMFS_HARD_LINK ) {
+
+ result = IMFS_evaluate_link( pathloc, 0 );
+ if ( result == -1 )
+ return -1;
+
+ } else if ( node->type == IMFS_SYM_LINK ) {
+
+ result = IMFS_evaluate_link( pathloc, 0 );
+
+ if ( result == -1 )
+ return -1;
+ }
+
+ node = pathloc->node_access;
+ if ( !node )
+ rtems_set_errno_and_return_minus_one( ENOTDIR );
+
+ /*
+ * Only a directory can be decended into.
+ */
+
+ if ( node->type != IMFS_DIRECTORY )
+ rtems_set_errno_and_return_minus_one( ENOTDIR );
+
+ /*
+ * If we are at a node that is a mount point. Set loc to the
+ * new fs root node and let them finish evaluating the path.
+ */
+
+ if ( node->info.directory.mt_fs != NULL ) {
+ newloc = node->info.directory.mt_fs->mt_fs_root;
+ *pathloc = newloc;
+ return (*pathloc->ops->evalformake_h)( &path[i-len], pathloc, name );
+ }
+
+ /*
+ * Otherwise find the token name in the present location.
+ */
+
+ node = IMFS_find_match_in_dir( node, token );
+
+ /*
+ * If there is no node we have found the name of the node we
+ * wish to create.
+ */
+
+ if ( ! node )
+ done = TRUE;
+ else
+ pathloc->node_access = node;
+
+ break;
+
+ case IMFS_NO_MORE_PATH:
+ rtems_set_errno_and_return_minus_one( EEXIST );
+ break;
+
+ case IMFS_INVALID_TOKEN:
+ rtems_set_errno_and_return_minus_one( ENAMETOOLONG );
+ break;
+
+ case IMFS_CURRENT_DIR:
+ break;
+ }
+ }
+
+ *name = &path[ i - len ];
+
+ /*
+ * We have evaluated the path as far as we can.
+ * Verify there is not any invalid stuff at the end of the name.
+ */
+
+ for( ; path[i] != '\0'; i++) {
+ if ( !IMFS_is_separator( path[ i ] ) )
+ rtems_set_errno_and_return_minus_one( ENOENT );
+ }
+
+ /*
+ * Verify we can execute and write to this directory.
+ */
+
+ result = IMFS_Set_handlers( pathloc );
+
+ /*
+ * The returned node must be a directory
+ */
+ node = pathloc->node_access;
+ if ( node->type != IMFS_DIRECTORY )
+ rtems_set_errno_and_return_minus_one( ENOTDIR );
+
+ /*
+ * We must have Write and execute permission on the returned node.
+ */
+
+ if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_WX ) )
+ rtems_set_errno_and_return_minus_one( EACCES );
+
+ return result;
+}
+
+
+/*
+ * IMFS_eval_path
+ *
+ * The following routine evaluate path for a node that wishes to be
+ * accessed with mode. pathloc is returned with a pointer to the
+ * node to be accessed.
+ */
+
+int IMFS_eval_path(
+ const char *pathname, /* IN */
+ int flags, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+)
+{
+ int i = 0;
+ int len;
+ IMFS_token_types type = IMFS_CURRENT_DIR;
+ char token[ IMFS_NAME_MAX + 1 ];
+ rtems_filesystem_location_info_t newloc;
+ IMFS_jnode_t *node;
+ int result;
+
+ if ( !rtems_libio_is_valid_perms( flags ) ) {
+ assert( 0 );
+ rtems_set_errno_and_return_minus_one( EIO );
+ }
+
+ /*
+ * This was filled in by the caller and is valid in the
+ * mount table.
+ */
+
+ node = pathloc->node_access;
+
+ /*
+ * Evaluate all tokens until we are done or an error occurs.
+ */
+
+ while( (type != IMFS_NO_MORE_PATH) && (type != IMFS_INVALID_TOKEN) ) {
+
+ type = IMFS_get_token( &pathname[i], token, &len );
+ i += len;
+
+ if ( !pathloc->node_access )
+ rtems_set_errno_and_return_minus_one( ENOENT );
+
+ /*
+ * I cannot move out of this directory without execute permission.
+ */
+ if ( type != IMFS_NO_MORE_PATH )
+ if ( node->type == IMFS_DIRECTORY )
+ if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_SEARCH ) )
+ rtems_set_errno_and_return_minus_one( EACCES );
+
+ node = pathloc->node_access;
+
+ switch( type ) {
+ case IMFS_UP_DIR:
+ /*
+ * Am I at the root of all filesystems? (chroot'ed?)
+ */
+
+ if ( pathloc->node_access == rtems_filesystem_root.node_access )
+ break; /* Throw out the .. in this case */
+
+ /*
+ * Am I at the root of this mounted filesystem?
+ */
+
+ if (pathloc->node_access ==
+ pathloc->mt_entry->mt_fs_root.node_access) {
+
+ /*
+ * Am I at the root of all filesystems?
+ */
+
+ if ( pathloc->node_access == rtems_filesystem_root.node_access ) {
+ break; /* Throw out the .. in this case */
+ } else {
+ newloc = pathloc->mt_entry->mt_point_node;
+ *pathloc = newloc;
+ return (*pathloc->ops->evalpath_h)(&(pathname[i-len]),flags,pathloc);
+ }
+ } else {
+
+ if ( !node->Parent )
+ rtems_set_errno_and_return_minus_one( ENOENT );
+
+ node = node->Parent;
+ pathloc->node_access = node;
+
+ }
+
+ pathloc->node_access = node;
+ break;
+
+ case IMFS_NAME:
+ /*
+ * If we are at a link follow it.
+ */
+
+ if ( node->type == IMFS_HARD_LINK ) {
+
+ IMFS_evaluate_hard_link( pathloc, 0 );
+
+ node = pathloc->node_access;
+ if ( !node )
+ rtems_set_errno_and_return_minus_one( ENOTDIR );
+
+ } else if ( node->type == IMFS_SYM_LINK ) {
+
+ result = IMFS_evaluate_sym_link( pathloc, 0 );
+
+ node = pathloc->node_access;
+ if ( result == -1 )
+ return -1;
+ }
+
+ /*
+ * Only a directory can be decended into.
+ */
+
+ if ( node->type != IMFS_DIRECTORY )
+ rtems_set_errno_and_return_minus_one( ENOTDIR );
+
+ /*
+ * If we are at a node that is a mount point. Set loc to the
+ * new fs root node and let them finish evaluating the path.
+ */
+
+ if ( node->info.directory.mt_fs != NULL ) {
+ newloc = node->info.directory.mt_fs->mt_fs_root;
+ *pathloc = newloc;
+ return (*pathloc->ops->evalpath_h)( &pathname[i-len], flags, pathloc );
+ }
+
+ /*
+ * Otherwise find the token name in the present location.
+ */
+
+ node = IMFS_find_match_in_dir( node, token );
+ if ( !node )
+ rtems_set_errno_and_return_minus_one( ENOENT );
+
+ /*
+ * Set the node access to the point we have found.
+ */
+
+ pathloc->node_access = node;
+ break;
+
+ case IMFS_NO_MORE_PATH:
+ case IMFS_CURRENT_DIR:
+ break;
+
+ case IMFS_INVALID_TOKEN:
+ rtems_set_errno_and_return_minus_one( ENAMETOOLONG );
+ break;
+
+ }
+ }
+
+ /*
+ * Always return the root node.
+ *
+ * If we are at a node that is a mount point. Set loc to the
+ * new fs root node and let let the mounted filesystem set the handlers.
+ *
+ * NOTE: The behavior of stat() on a mount point appears to be questionable.
+ */
+
+ if ( node->type == IMFS_DIRECTORY ) {
+ if ( node->info.directory.mt_fs != NULL ) {
+ newloc = node->info.directory.mt_fs->mt_fs_root;
+ *pathloc = newloc;
+ return (*pathloc->ops->evalpath_h)( &pathname[i-len], flags, pathloc );
+ } else {
+ result = IMFS_Set_handlers( pathloc );
+ }
+ } else {
+ result = IMFS_Set_handlers( pathloc );
+ }
+
+ /*
+ * Verify we have the correct permissions for this node.
+ */
+
+ if ( !IMFS_evaluate_permission( pathloc, flags ) )
+ rtems_set_errno_and_return_minus_one( EACCES );
+
+ return result;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_fchmod.c b/cpukit/libfs/src/imfs/imfs_fchmod.c
new file mode 100644
index 0000000000..55c1cfe42f
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_fchmod.c
@@ -0,0 +1,65 @@
+/*
+ * IMFS file change mode routine.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+#include "imfs.h"
+
+int IMFS_fchmod(
+ rtems_filesystem_location_info_t *loc,
+ mode_t mode
+)
+{
+ IMFS_jnode_t *jnode;
+#if defined(RTEMS_POSIX_API)
+ uid_t st_uid;
+#endif
+ int IMFS_memfile_write(
+ IMFS_jnode_t *the_jnode,
+ off_t start,
+ const unsigned char *source,
+ unsigned int length
+ );
+
+
+ jnode = loc->node_access;
+
+ /*
+ * Verify I am the owner of the node or the super user.
+ */
+#if defined(RTEMS_POSIX_API)
+ st_uid = geteuid();
+
+ if ( ( st_uid != jnode->st_uid ) && ( st_uid != 0 ) )
+ rtems_set_errno_and_return_minus_one( EPERM );
+#endif
+
+ /*
+ * Change only the RWX permissions on the jnode to mode.
+ */
+ if ( mode & (~ (S_IRWXU | S_IRWXG | S_IRWXO ) ) )
+ rtems_set_errno_and_return_minus_one( EPERM );
+
+ jnode->st_mode &= ~(S_IRWXU | S_IRWXG | S_IRWXO);
+ jnode->st_mode |= mode;
+
+ IMFS_update_ctime( jnode );
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_fcntl.c b/cpukit/libfs/src/imfs/imfs_fcntl.c
new file mode 100644
index 0000000000..ca802b8331
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_fcntl.c
@@ -0,0 +1,28 @@
+/*
+ * IMFS_fcntl
+ *
+ * The following routine does a fcntl on an IMFS node.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "imfs.h"
+
+int IMFS_fcntl(
+ int cmd,
+ rtems_libio_t *iop
+)
+{
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_fdatasync.c b/cpukit/libfs/src/imfs/imfs_fdatasync.c
new file mode 100644
index 0000000000..6b107bfaf8
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_fdatasync.c
@@ -0,0 +1,29 @@
+/*
+ * IMFS_fdatasync
+ *
+ * The following routine does a sync on an IMFS node. The In Memory
+ * File System is always in sync, therefore this routine always returns
+ * pass.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "imfs.h"
+
+int IMFS_fdatasync(
+ rtems_libio_t *iop
+)
+{
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_free.c b/cpukit/libfs/src/imfs/imfs_free.c
new file mode 100644
index 0000000000..affbcaa044
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_free.c
@@ -0,0 +1,39 @@
+/*
+ * Free IMFS Node Support Routines
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+#include <rtems/libio_.h>
+#include "imfs.h"
+
+/*
+ * IMFS_freenodinfo
+ *
+ * This routine is the IMFS free node handler for the file system
+ * operations table.
+ *
+ * The In Memory File System keeps its nodes in memory. This routine
+ * is for file sytems that do not.
+ */
+
+int IMFS_freenodinfo(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+)
+{
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_fsunmount.c b/cpukit/libfs/src/imfs/imfs_fsunmount.c
new file mode 100644
index 0000000000..c87b2e665b
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_fsunmount.c
@@ -0,0 +1,96 @@
+/*
+ * IMFS Initialization
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h> /* for mkdir */
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <assert.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+
+#if defined(IMFS_DEBUG)
+#include <stdio.h>
+#endif
+
+/*
+ * IMFS_fsunmount
+ */
+
+#define jnode_get_control( jnode ) \
+ (&jnode->info.directory.Entries)
+
+#define jnode_has_no_children( jnode ) \
+ Chain_Is_empty( jnode_get_control( jnode ) )
+
+#define jnode_has_children( jnode ) \
+ ( ! jnode_has_no_children( jnode ) )
+
+#define jnode_get_first_child( jnode ) \
+ ((IMFS_jnode_t *)( Chain_Head( jnode_get_control( jnode ) )->next))
+
+int IMFS_fsunmount(
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry
+)
+{
+ IMFS_jnode_t *jnode;
+ IMFS_jnode_t *next;
+ rtems_filesystem_location_info_t loc;
+ int result = 0;
+
+ /*
+ * Traverse tree that starts at the mt_fs_root and deallocate memory
+ * associated memory space
+ */
+
+ jnode = (IMFS_jnode_t *)temp_mt_entry->mt_fs_root.node_access;
+ loc = temp_mt_entry->mt_fs_root;
+
+ /*
+ * Set this to null to indicate that it is being unmounted.
+ */
+
+ temp_mt_entry->mt_fs_root.node_access = NULL;
+
+ do {
+ next = jnode->Parent;
+ loc.node_access = (void *)jnode;
+ IMFS_Set_handlers( &loc );
+
+ if ( jnode->type != IMFS_DIRECTORY ) {
+ result = IMFS_unlink( &loc );
+ if (result != 0)
+ return -1;
+ jnode = next;
+ } else if ( jnode_has_no_children( jnode ) ) {
+ result = IMFS_unlink( &loc );
+ if (result != 0)
+ return -1;
+ jnode = next;
+ }
+ if ( jnode != NULL ) {
+ if ( jnode->type == IMFS_DIRECTORY ) {
+ if ( jnode_has_children( jnode ) )
+ jnode = jnode_get_first_child( jnode );
+ }
+ }
+ } while (jnode != NULL);
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_getchild.c b/cpukit/libfs/src/imfs/imfs_getchild.c
new file mode 100644
index 0000000000..67663db8ea
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_getchild.c
@@ -0,0 +1,73 @@
+/*
+ * IMFS_find_match_in_dir()
+ *
+ * This routine returns the child name in the given directory.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <assert.h>
+#include <string.h>
+#include "imfs.h"
+
+static char dotname[2] = ".";
+static char dotdotname[3] = "..";
+
+IMFS_jnode_t *IMFS_find_match_in_dir(
+ IMFS_jnode_t *directory,
+ char *name
+)
+{
+ Chain_Node *the_node;
+ Chain_Control *the_chain;
+ IMFS_jnode_t *the_jnode;
+
+ /*
+ * Check for fatal errors. A NULL directory show a problem in the
+ * the IMFS code.
+ */
+
+ assert( directory );
+ if ( !name )
+ return 0;
+
+ assert( name );
+ if ( !directory )
+ return 0;
+
+ /*
+ * Check for "." and ".."
+ */
+
+ if ( !strcmp( name, dotname ) )
+ return directory;
+
+ if ( !strcmp( name, dotdotname ) )
+ return directory->Parent;
+
+ the_chain = &directory->info.directory.Entries;
+
+ for ( the_node = the_chain->first;
+ !_Chain_Is_tail( the_chain, the_node );
+ the_node = the_node->next ) {
+
+ the_jnode = (IMFS_jnode_t *) the_node;
+
+ if ( !strcmp( name, the_jnode->name ) )
+ return the_jnode;
+ }
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_gtkn.c b/cpukit/libfs/src/imfs/imfs_gtkn.c
new file mode 100644
index 0000000000..09f1ab0174
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_gtkn.c
@@ -0,0 +1,90 @@
+/*
+ * IMFS_get_token
+ *
+ * Routine to get a token (name or separator) from the path
+ * the length of the token is returned in token_len.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+
+IMFS_token_types IMFS_get_token(
+ const char *path,
+ char *token,
+ int *token_len
+)
+{
+ register int i = 0;
+ IMFS_token_types type = IMFS_NAME;
+ register char c;
+
+ /*
+ * Copy a name into token. (Remember NULL is a token.)
+ */
+ c = path[i];
+ while ( (!IMFS_is_separator(c)) && (i <= IMFS_NAME_MAX) ) {
+
+ token[i] = c;
+
+ if ( i == IMFS_NAME_MAX )
+ return IMFS_INVALID_TOKEN;
+
+ if ( !IMFS_is_valid_name_char(c) )
+ type = IMFS_INVALID_TOKEN;
+
+ c = path [++i];
+ }
+
+ /*
+ * Copy a seperator into token.
+ */
+
+ if ( i == 0 ) {
+ token[i] = c;
+
+ if ( token[i] != '\0' ) {
+ i++;
+ type = IMFS_CURRENT_DIR;
+ } else {
+ type = IMFS_NO_MORE_PATH;
+ }
+ } else if (token[ i-1 ] != '\0') {
+ token[i] = '\0';
+ }
+
+ /*
+ * Set token_len to the number of characters copied.
+ */
+
+ *token_len = i;
+
+ /*
+ * If we copied something that was not a seperator see if
+ * it was a special name.
+ */
+
+ if ( type == IMFS_NAME ) {
+ if ( strcmp( token, "..") == 0 )
+ type = IMFS_UP_DIR;
+ else if ( strcmp( token, "." ) == 0 )
+ type = IMFS_CURRENT_DIR;
+ }
+
+ return type;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_device.c b/cpukit/libfs/src/imfs/imfs_handlers_device.c
new file mode 100644
index 0000000000..fa373b8b91
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_handlers_device.c
@@ -0,0 +1,41 @@
+/*
+ * Device Operations Table for the IMFS
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+#include "imfs.h"
+
+/*
+ * Handler table for IMFS device nodes
+ */
+
+rtems_filesystem_file_handlers_r IMFS_device_handlers = {
+ device_open,
+ device_close,
+ device_read,
+ device_write,
+ device_ioctl,
+ device_lseek,
+ IMFS_stat,
+ IMFS_fchmod,
+ NULL, /* ftruncate */
+ NULL, /* fpathconf */
+ NULL, /* fsync */
+ NULL, /* fdatasync */
+ NULL, /* fcntl */
+ IMFS_rmnod
+};
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_directory.c b/cpukit/libfs/src/imfs/imfs_handlers_directory.c
new file mode 100644
index 0000000000..b9453a0725
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_handlers_directory.c
@@ -0,0 +1,41 @@
+/*
+ * Operations Table for Directories for the IMFS
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+#include "imfs.h"
+
+/*
+ * Set of operations handlers for operations on directories.
+ */
+
+rtems_filesystem_file_handlers_r IMFS_directory_handlers = {
+ imfs_dir_open,
+ imfs_dir_close,
+ imfs_dir_read,
+ NULL, /* write */
+ NULL, /* ioctl */
+ imfs_dir_lseek,
+ imfs_dir_fstat,
+ IMFS_fchmod,
+ NULL, /* ftruncate */
+ NULL, /* fpathconf */
+ NULL, /* fsync */
+ IMFS_fdatasync,
+ IMFS_fcntl,
+ imfs_dir_rmnod
+};
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_link.c b/cpukit/libfs/src/imfs/imfs_handlers_link.c
new file mode 100644
index 0000000000..f4b926dcab
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_handlers_link.c
@@ -0,0 +1,41 @@
+/*
+ * Link Operations Table for the IMFS
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+#include "imfs.h"
+
+/*
+ * Handler table for IMFS device nodes
+ */
+
+rtems_filesystem_file_handlers_r IMFS_link_handlers = {
+ NULL, /* open */
+ NULL, /* close */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* ioctl */
+ NULL, /* lseek */
+ IMFS_stat, /* stat */
+ NULL, /* fchmod */
+ NULL, /* ftruncate */
+ NULL, /* fpathconf */
+ NULL, /* fsync */
+ NULL, /* fdatasync */
+ NULL, /* fcntl */
+ IMFS_rmnod
+};
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
new file mode 100644
index 0000000000..1db049b504
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
@@ -0,0 +1,41 @@
+/*
+ * Memfile Operations Tables for the IMFS
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+#include "imfs.h"
+
+/*
+ * Set of operations handlers for operations on memfile entities.
+ */
+
+rtems_filesystem_file_handlers_r IMFS_memfile_handlers = {
+ memfile_open,
+ memfile_close,
+ memfile_read,
+ memfile_write,
+ memfile_ioctl,
+ memfile_lseek,
+ IMFS_stat,
+ IMFS_fchmod,
+ memfile_ftruncate,
+ NULL, /* fpathconf */
+ IMFS_fdatasync, /* fsync */
+ IMFS_fdatasync,
+ IMFS_fcntl,
+ memfile_rmnod
+};
diff --git a/cpukit/libfs/src/imfs/imfs_init.c b/cpukit/libfs/src/imfs/imfs_init.c
new file mode 100644
index 0000000000..4ed08bd500
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_init.c
@@ -0,0 +1,69 @@
+/*
+ * IMFS Initialization
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h> /* for mkdir */
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <assert.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+
+#if defined(IMFS_DEBUG)
+#include <stdio.h>
+#endif
+
+/*
+ * IMFS file system operations table
+ */
+
+rtems_filesystem_operations_table IMFS_ops = {
+ IMFS_eval_path,
+ IMFS_evaluate_for_make,
+ IMFS_link,
+ IMFS_unlink,
+ IMFS_node_type,
+ IMFS_mknod,
+ IMFS_chown,
+ IMFS_freenodinfo,
+ IMFS_mount,
+ IMFS_initialize,
+ IMFS_unmount,
+ IMFS_fsunmount,
+ IMFS_utime,
+ IMFS_evaluate_link,
+ IMFS_symlink,
+ IMFS_readlink
+};
+
+/*
+ * IMFS_initialize
+ */
+
+int IMFS_initialize(
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry
+)
+{
+ return IMFS_initialize_support(
+ temp_mt_entry,
+ &IMFS_ops,
+ &IMFS_memfile_handlers,
+ &IMFS_directory_handlers
+ );
+}
diff --git a/cpukit/libfs/src/imfs/imfs_initsupp.c b/cpukit/libfs/src/imfs/imfs_initsupp.c
new file mode 100644
index 0000000000..29b014d374
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_initsupp.c
@@ -0,0 +1,125 @@
+/*
+ * IMFS Initialization
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h> /* for mkdir */
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <assert.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+#if defined(IMFS_DEBUG)
+#include <stdio.h>
+#endif
+
+/*
+ * IMFS_determine_bytes_per_block
+ */
+int imfs_memfile_bytes_per_block = 0;
+
+static int IMFS_determine_bytes_per_block(
+ int *dest_bytes_per_block,
+ int requested_bytes_per_block,
+ int default_bytes_per_block
+)
+{
+ rtems_boolean is_valid = FALSE;
+ int bit_mask;
+ /*
+ * check, whether requested bytes per block is valid
+ */
+ for (bit_mask = 16;
+ !is_valid && (bit_mask <= 512);
+ bit_mask <<= 1) {
+ if (bit_mask == requested_bytes_per_block) {
+ is_valid = TRUE;
+ }
+ }
+ *dest_bytes_per_block = ((is_valid)
+ ? requested_bytes_per_block
+ : default_bytes_per_block);
+ return 0;
+
+}
+
+
+/*
+ * IMFS_initialize
+ */
+
+int IMFS_initialize_support(
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry,
+ rtems_filesystem_operations_table *op_table,
+ rtems_filesystem_file_handlers_r *memfile_handlers,
+ rtems_filesystem_file_handlers_r *directory_handlers
+)
+{
+ IMFS_fs_info_t *fs_info;
+ IMFS_jnode_t *jnode;
+
+ /*
+ * determine/check value for imfs_memfile_bytes_per_block
+ */
+ IMFS_determine_bytes_per_block(&imfs_memfile_bytes_per_block,
+ imfs_rq_memfile_bytes_per_block,
+ IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK);
+
+ /*
+ * Create the root node
+ *
+ * NOTE: UNIX root is 755 and owned by root/root (0/0).
+ */
+
+ temp_mt_entry->mt_fs_root.node_access = IMFS_create_node(
+ NULL,
+ IMFS_DIRECTORY,
+ "",
+ ( S_IFDIR | 0755 ),
+ NULL
+ );
+
+ temp_mt_entry->mt_fs_root.handlers = directory_handlers;
+ temp_mt_entry->mt_fs_root.ops = op_table;
+ temp_mt_entry->pathconf_limits_and_options = IMFS_LIMITS_AND_OPTIONS;
+
+ /*
+ * Create custom file system data.
+ */
+ fs_info = calloc( 1, sizeof( IMFS_fs_info_t ) );
+ if ( !fs_info ){
+ free(temp_mt_entry->mt_fs_root.node_access);
+ rtems_set_errno_and_return_minus_one(ENOMEM);
+ }
+ temp_mt_entry->fs_info = fs_info;
+
+ /*
+ * Set st_ino for the root to 1.
+ */
+
+ fs_info->ino_count = 1;
+ fs_info->memfile_handlers = memfile_handlers;
+ fs_info->directory_handlers = directory_handlers;
+
+ jnode = temp_mt_entry->mt_fs_root.node_access;
+ jnode->st_ino = fs_info->ino_count;
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_link.c b/cpukit/libfs/src/imfs/imfs_link.c
new file mode 100644
index 0000000000..43c1613cfc
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_link.c
@@ -0,0 +1,75 @@
+/*
+ * IMFS_link
+ *
+ * The following rouine creates a new link node under parent with the
+ * name given in name. The link node is set to point to the node at
+ * to_loc.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int IMFS_link(
+ rtems_filesystem_location_info_t *to_loc, /* IN */
+ rtems_filesystem_location_info_t *parent_loc, /* IN */
+ const char *token /* IN */
+)
+{
+ IMFS_types_union info;
+ IMFS_jnode_t *new_node;
+ char new_name[ IMFS_NAME_MAX + 1 ];
+ int i;
+
+ /*
+ * Verify this node can be linked to.
+ */
+
+ info.hard_link.link_node = to_loc->node_access;
+ if ( info.hard_link.link_node->st_nlink >= LINK_MAX )
+ rtems_set_errno_and_return_minus_one( EMLINK );
+
+ /*
+ * Remove any separators at the end of the string.
+ */
+
+ IMFS_get_token( token, new_name, &i );
+
+ /*
+ * Create a new link node.
+ */
+
+ new_node = IMFS_create_node(
+ parent_loc,
+ IMFS_HARD_LINK,
+ new_name,
+ ( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )),
+ &info
+ );
+
+ if ( !new_node )
+ rtems_set_errno_and_return_minus_one( ENOMEM );
+
+ /*
+ * Increment the link count of the node being pointed to.
+ */
+
+ info.hard_link.link_node->st_nlink++;
+ IMFS_update_ctime( info.hard_link.link_node );
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_load_tar.c b/cpukit/libfs/src/imfs/imfs_load_tar.c
new file mode 100644
index 0000000000..e229f3be67
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_load_tar.c
@@ -0,0 +1,170 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/**************************************************************************
+ * This file implements the "mount" procedure for tar-based IMFS
+ * extensions. The TAR is not actually mounted under the IMFS.
+ * Directories from the TAR file are created as usual in the IMFS.
+ * File entries are created as IMFS_LINEAR_FILE nodes with their nods
+ * pointing to addresses in the TAR image.
+ *************************************************************************/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <string.h>
+
+#include <rtems.h>
+#include <rtems/libio_.h>
+#include <rtems/chain.h>
+#include <rtems/imfs.h>
+#include <rtems/untar.h>
+#include <rtems/tar.h>
+
+/**************************************************************************
+ * TAR file format:
+ *
+ * Offset Length Contents
+ * 0 100 bytes File name ('\0' terminated, 99 maxmum length)
+ * 100 8 bytes File mode (in octal ascii)
+ * 108 8 bytes User ID (in octal ascii)
+ * 116 8 bytes Group ID (in octal ascii)
+ * 124 12 bytes File size (s) (in octal ascii)
+ * 136 12 bytes Modify time (in octal ascii)
+ * 148 8 bytes Header checksum (in octal ascii)
+ * 156 1 bytes Link flag
+ * 157 100 bytes Linkname ('\0' terminated, 99 maxmum length)
+ * 257 8 bytes Magic ("ustar \0")
+ * 265 32 bytes User name ('\0' terminated, 31 maxmum length)
+ * 297 32 bytes Group name ('\0' terminated, 31 maxmum length)
+ * 329 8 bytes Major device ID (in octal ascii)
+ * 337 8 bytes Minor device ID (in octal ascii)
+ * 345 167 bytes Padding
+ * 512 (s+p)bytes File contents (s+p) := (((s) + 511) & ~511),
+ * round up to 512 bytes
+ *
+ * Checksum:
+ * int i, sum;
+ * char* header = tar_header_pointer;
+ * sum = 0;
+ * for(i = 0; i < 512; i++)
+ * sum += 0xFF & header[i];
+ *************************************************************************/
+
+#define MAX_NAME_FIELD_SIZE 99
+
+#define MIN(a,b) ((a)>(b)?(b):(a))
+
+/**************************************************************************
+ * rtems_tarfs_load
+ *
+ * Here we create the mountpoint directory and load the tarfs at
+ * that node. Once the IMFS has been mounted, we work through the
+ * tar image and perform as follows:
+ * - For directories, simply call mkdir(). The IMFS creates nodes as
+ * needed.
+ * - For files, we make our own calls to IMFS eval_for_make and
+ * create_node.
+ *************************************************************************/
+int
+rtems_tarfs_load(
+ char *mountpoint,
+ uint8_t *tar_image,
+ size_t tar_size
+)
+{
+ rtems_filesystem_location_info_t root_loc;
+ rtems_filesystem_location_info_t loc;
+ const char *hdr_ptr;
+ char filename[100];
+ char full_filename[256];
+ int hdr_chksum;
+ unsigned char linkflag;
+ unsigned long file_size;
+ unsigned long file_mode;
+ int offset;
+ unsigned long nblocks;
+ IMFS_jnode_t *node;
+ int status;
+
+ status = rtems_filesystem_evaluate_path(mountpoint, 0, &root_loc, 0);
+ if (status != 0)
+ return(-1);
+
+ if (root_loc.ops != &IMFS_ops)
+ return(-1);
+
+ /***********************************************************************
+ * Create an IMFS node structure pointing to tar image memory.
+ **********************************************************************/
+ offset = 0;
+ while (1)
+ {
+ if (offset + 512 > tar_size)
+ break;
+
+ /******************************************************************
+ * Read a header.
+ ******************************************************************/
+ hdr_ptr = (char *) &tar_image[offset];
+ offset += 512;
+ if (strncmp(&hdr_ptr[257], "ustar ", 7))
+ break;
+
+ strncpy(filename, hdr_ptr, MAX_NAME_FIELD_SIZE);
+ filename[MAX_NAME_FIELD_SIZE] = '\0';
+
+ linkflag = hdr_ptr[156];
+ file_mode = _rtems_octal2ulong(&hdr_ptr[100], 8);
+ file_size = _rtems_octal2ulong(&hdr_ptr[124], 12);
+ hdr_chksum = _rtems_octal2ulong(&hdr_ptr[148], 8);
+
+ if (_rtems_tar_header_checksum(hdr_ptr) != hdr_chksum)
+ break;
+
+ /******************************************************************
+ * Generate an IMFS node depending on the file type.
+ * - For directories, just create directories as usual. IMFS
+ * will take care of the rest.
+ * - For files, create a file node with special tarfs properties.
+ *****************************************************************/
+ if (linkflag == DIRTYPE)
+ {
+ strcpy(full_filename, mountpoint);
+ if (full_filename[strlen(full_filename)-1] != '/')
+ strcat(full_filename, "/");
+ strcat(full_filename, filename);
+ mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO);
+ }
+ /******************************************************************
+ * Create a LINEAR_FILE node
+ *****************************************************************/
+ else if (linkflag == REGTYPE)
+ {
+ const char *name;
+
+ loc = root_loc;
+ if (IMFS_evaluate_for_make(filename, &loc, &name) == 0)
+ {
+ node = IMFS_create_node(&loc,
+ IMFS_LINEAR_FILE, (char *)name,
+ (file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
+ NULL);
+ node->info.linearfile.size = file_size;
+ node->info.linearfile.direct = &tar_image[offset];
+ }
+
+ nblocks = (((file_size) + 511) & ~511) / 512;
+ offset += 512 * nblocks;
+ }
+ }
+
+ return(status);
+}
+
diff --git a/cpukit/libfs/src/imfs/imfs_mknod.c b/cpukit/libfs/src/imfs/imfs_mknod.c
new file mode 100644
index 0000000000..abb9ab4052
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_mknod.c
@@ -0,0 +1,77 @@
+/*
+ * IMFS_mknod
+ *
+ * Routine to create a node in the IMFS file system.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int IMFS_mknod(
+ const char *token, /* IN */
+ mode_t mode, /* IN */
+ dev_t dev, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+)
+{
+ IMFS_token_types type = 0;
+ IMFS_jnode_t *new_node;
+ int result;
+ char new_name[ IMFS_NAME_MAX + 1 ];
+ IMFS_types_union info;
+
+ IMFS_get_token( token, new_name, &result );
+
+ /*
+ * Figure out what type of IMFS node this is.
+ */
+
+ if ( S_ISDIR(mode) )
+ type = IMFS_DIRECTORY;
+ else if ( S_ISREG(mode) )
+ type = IMFS_MEMORY_FILE;
+ else if ( S_ISBLK(mode) || S_ISCHR(mode) ) {
+ type = IMFS_DEVICE;
+ rtems_filesystem_split_dev_t( dev, info.device.major, info.device.minor );
+ } else {
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ /*
+ * Allocate and fill in an IMFS jnode
+ */
+
+ new_node = IMFS_create_node(
+ pathloc,
+ type,
+ new_name,
+ mode,
+ &info
+ );
+
+ if ( !new_node )
+ rtems_set_errno_and_return_minus_one( ENOMEM );
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_mount.c b/cpukit/libfs/src/imfs/imfs_mount.c
new file mode 100644
index 0000000000..3ec16da3f7
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_mount.c
@@ -0,0 +1,53 @@
+/*
+ * IMFS_mount
+ *
+ * This routine will look at a mount table entry that we are going to
+ * add to the mount table. If the mount point rtems_filesystem
+ * location_info_t struct refers to a node that is a directory,
+ * the node will be marked as a mount point by setting its directory.mt_fs
+ * pointer to point to the mount table entry that we are about to add
+ * to the mount table chain.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int IMFS_mount(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+)
+{
+ IMFS_jnode_t *node;
+
+ node = mt_entry->mt_point_node.node_access;
+
+ /*
+ * Is the node that we are mounting onto a directory node ?
+ */
+
+ if ( node->type != IMFS_DIRECTORY )
+ rtems_set_errno_and_return_minus_one( ENOTDIR );
+
+ /*
+ * Set mt_fs pointer to point to the mount table entry for
+ * the mounted file system.
+ */
+
+ node->info.directory.mt_fs = mt_entry;
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_ntype.c b/cpukit/libfs/src/imfs/imfs_ntype.c
new file mode 100644
index 0000000000..f80182b144
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_ntype.c
@@ -0,0 +1,32 @@
+/*
+ * IMFS_node_type
+ *
+ * The following verifies that returns the type of node that the
+ * loc refers to.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include "imfs.h"
+
+rtems_filesystem_node_types_t IMFS_node_type(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+)
+{
+ IMFS_jnode_t *node;
+
+ node = pathloc->node_access;
+ return node->type;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_readlink.c b/cpukit/libfs/src/imfs/imfs_readlink.c
new file mode 100644
index 0000000000..6b3d1acafe
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_readlink.c
@@ -0,0 +1,44 @@
+/*
+ * IMFS_readlink
+ *
+ * The following rouine puts the symblic links destination name into
+ * buff.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int IMFS_readlink(
+ rtems_filesystem_location_info_t *loc,
+ char *buf, /* OUT */
+ size_t bufsize
+)
+{
+ IMFS_jnode_t *node;
+ int i;
+
+ node = loc->node_access;
+
+ if ( node->type != IMFS_SYM_LINK )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ for( i=0; ((i<bufsize) && (node->info.sym_link.name[i] != '\0')); i++ )
+ buf[i] = node->info.sym_link.name[i];
+
+ return i;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_rmnod.c b/cpukit/libfs/src/imfs/imfs_rmnod.c
new file mode 100644
index 0000000000..d5e32378ad
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_rmnod.c
@@ -0,0 +1,79 @@
+/*
+ * IMFS Node Removal Handler
+ *
+ * This file contains the handler used to remove a node when a file type
+ * does not require special actions.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+
+#include "imfs.h"
+
+/*
+ * IMFS_rmnod
+ */
+
+int IMFS_rmnod(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = (IMFS_jnode_t *) pathloc->node_access;
+
+ /*
+ * Take the node out of the parent's chain that contains this node
+ */
+
+ if ( the_jnode->Parent != NULL ) {
+ Chain_Extract( (Chain_Node *) the_jnode );
+ the_jnode->Parent = NULL;
+ }
+
+ /*
+ * Decrement the link counter and see if we can free the space.
+ */
+
+ the_jnode->st_nlink--;
+ IMFS_update_ctime( the_jnode );
+
+ /*
+ * The file cannot be open and the link must be less than 1 to free.
+ */
+
+ if ( !rtems_libio_is_file_open( the_jnode ) && (the_jnode->st_nlink < 1) ) {
+
+ /*
+ * Is rtems_filesystem_current this node?
+ */
+
+ if ( rtems_filesystem_current.node_access == pathloc->node_access )
+ rtems_filesystem_current.node_access = NULL;
+
+ /*
+ * Free memory associated with a memory file.
+ */
+
+ free( the_jnode );
+ }
+
+ return 0;
+
+}
diff --git a/cpukit/libfs/src/imfs/imfs_stat.c b/cpukit/libfs/src/imfs/imfs_stat.c
new file mode 100644
index 0000000000..422e954ed1
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_stat.c
@@ -0,0 +1,68 @@
+/*
+ * IMFS_stat
+ *
+ * This routine provides a stat for the IMFS file system.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int IMFS_stat(
+ rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+)
+{
+ IMFS_jnode_t *the_jnode;
+ IMFS_device_t *io;
+
+ the_jnode = loc->node_access;
+
+
+ switch ( the_jnode->type ) {
+
+ case IMFS_DEVICE:
+ io = &the_jnode->info.device;
+ buf->st_dev = rtems_filesystem_make_dev_t( io->major, io->minor );
+ break;
+
+ case IMFS_LINEAR_FILE:
+ case IMFS_MEMORY_FILE:
+ buf->st_size = the_jnode->info.file.size;
+ break;
+
+ case IMFS_SYM_LINK:
+ buf->st_size = 0;
+ break;
+
+ default:
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ break;
+ }
+
+ buf->st_mode = the_jnode->st_mode;
+ buf->st_nlink = the_jnode->st_nlink;
+ buf->st_ino = the_jnode->st_ino;
+ buf->st_uid = the_jnode->st_uid;
+ buf->st_gid = the_jnode->st_gid;
+
+ buf->st_atime = the_jnode->stat_atime;
+ buf->st_mtime = the_jnode->stat_mtime;
+ buf->st_ctime = the_jnode->stat_ctime;
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_symlink.c b/cpukit/libfs/src/imfs/imfs_symlink.c
new file mode 100644
index 0000000000..38072b9f69
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_symlink.c
@@ -0,0 +1,62 @@
+/*
+ * IMFS_symlink
+ *
+ * The following rouine creates a new symbolic link node under parent
+ * with the name given in name. The node is set to point to the node at
+ * to_loc.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int IMFS_symlink(
+ rtems_filesystem_location_info_t *parent_loc,
+ const char *link_name,
+ const char *node_name
+)
+{
+ IMFS_types_union info;
+ IMFS_jnode_t *new_node;
+ char new_name[ IMFS_NAME_MAX + 1 ];
+ int i;
+
+ /*
+ * Remove any separators at the end of the string.
+ */
+
+ IMFS_get_token( node_name, new_name, &i );
+
+ info.sym_link.name = link_name;
+
+ /*
+ * Create a new link node.
+ */
+
+ new_node = IMFS_create_node(
+ parent_loc,
+ IMFS_SYM_LINK,
+ new_name,
+ ( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )),
+ &info
+ );
+
+ if ( !new_node )
+ rtems_set_errno_and_return_minus_one( ENOMEM );
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_unixstub.c b/cpukit/libfs/src/imfs/imfs_unixstub.c
new file mode 100644
index 0000000000..d642b260d5
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_unixstub.c
@@ -0,0 +1,74 @@
+/*
+ * IMFS Stub for UNIX configuration
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h> /* for mkdir */
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <assert.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+
+#include <stdio.h>
+
+/*
+ * IMFS file system operations table
+ */
+
+rtems_filesystem_operations_table IMFS_ops = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+/*
+ * IMFS file system operations table
+ */
+
+rtems_filesystem_operations_table miniIMFS_ops = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
diff --git a/cpukit/libfs/src/imfs/imfs_unlink.c b/cpukit/libfs/src/imfs/imfs_unlink.c
new file mode 100644
index 0000000000..b416a09b8e
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_unlink.c
@@ -0,0 +1,81 @@
+/*
+ * IMFS_unlink
+ *
+ * Routine to remove a link node from the tree.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int IMFS_unlink(
+ rtems_filesystem_location_info_t *loc /* IN */
+)
+{
+ IMFS_jnode_t *node;
+ rtems_filesystem_location_info_t the_link;
+ int result = 0;
+
+ node = loc->node_access;
+
+ /*
+ * Decrement the link counter of node pointed to and free the
+ * space.
+ */
+
+ /*
+ * If this is the last last pointer to the node
+ * free the node.
+ */
+
+ if ( node->type == IMFS_HARD_LINK ) {
+
+ if ( !node->info.hard_link.link_node )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ the_link = *loc;
+ the_link.node_access = node->info.hard_link.link_node;
+ IMFS_Set_handlers( &the_link );
+
+ /*
+ * If removing the last hard link to a node, then we need
+ * to remove the node that is a link and the node itself.
+ */
+
+ if ( node->info.hard_link.link_node->st_nlink == 1)
+ {
+ result = (*the_link.handlers->rmnod_h)( &the_link );
+ if ( result != 0 )
+ return -1;
+ }
+ else
+ {
+ node->info.hard_link.link_node->st_nlink --;
+ IMFS_update_ctime( node->info.hard_link.link_node );
+ }
+ }
+
+ /*
+ * Now actually free the node we were asked to free.
+ */
+
+ result = (*loc->handlers->rmnod_h)( loc );
+
+ return result;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_unmount.c b/cpukit/libfs/src/imfs/imfs_unmount.c
new file mode 100644
index 0000000000..ee1482bfa5
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_unmount.c
@@ -0,0 +1,62 @@
+/*
+ * IMFS_unmount
+ *
+ * This routine will look at a mount table entry that we are going to
+ * add to the mount table. If the mount point
+ * rtems_filesystem_location_info_t struct refers to a node that is a
+ * directory that has a file system mounted on it, the node will be
+ * marked as a mount point by * setting its directory.mt_fs pointer
+ * to NULL. This indicates that a directory is no longer mounted on
+ * this node.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int IMFS_unmount(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+)
+{
+ IMFS_jnode_t *node;
+
+ node = mt_entry->mt_point_node.node_access;
+
+ /*
+ * Is the node that we are mounting onto a directory node ?
+ */
+
+ if ( node->type != IMFS_DIRECTORY )
+ rtems_set_errno_and_return_minus_one( ENOTDIR );
+
+ /*
+ * Did the node indicate that there was a directory mounted here?
+ */
+
+ if ( node->info.directory.mt_fs == NULL )
+ rtems_set_errno_and_return_minus_one( EINVAL ); /* XXX */
+
+ /*
+ * Set the mt_fs pointer to indicate that there is no longer
+ * a file system mounted to this point.
+ */
+
+ node->info.directory.mt_fs = NULL;
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/imfs_utime.c b/cpukit/libfs/src/imfs/imfs_utime.c
new file mode 100644
index 0000000000..0a120f02d3
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_utime.c
@@ -0,0 +1,41 @@
+/*
+ * IMFS_utime
+ *
+ * This routine is the implementation of the utime() system
+ * call for the IMFS.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <sys/time.h>
+
+#include <rtems/libio_.h>
+#include "imfs.h"
+
+int IMFS_utime(
+ rtems_filesystem_location_info_t *pathloc, /* IN */
+ time_t actime, /* IN */
+ time_t modtime /* IN */
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = (IMFS_jnode_t *) pathloc->node_access;
+
+ the_jnode->stat_atime = actime;
+ the_jnode->stat_mtime = modtime;
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/ioman.c b/cpukit/libfs/src/imfs/ioman.c
new file mode 100644
index 0000000000..1ab3b38c99
--- /dev/null
+++ b/cpukit/libfs/src/imfs/ioman.c
@@ -0,0 +1,107 @@
+/*
+ * This file emulates the old Classic RTEMS IO manager directives
+ * which register and lookup names using the in-memory filesystem.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <assert.h>
+
+#include <rtems.h>
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+#include "imfs.h"
+
+#if defined(__linux__)
+#define S_IFCHR __S_IFCHR
+#endif
+
+/*
+ * rtems_io_register_name
+ *
+ * This assumes that all registered devices are character devices.
+ */
+
+rtems_status_code rtems_io_register_name(
+ const char *device_name,
+ rtems_device_major_number major,
+ rtems_device_minor_number minor
+)
+{
+#if !defined(RTEMS_UNIX)
+ int status;
+ dev_t dev;
+
+ dev = rtems_filesystem_make_dev_t( major, minor );
+ status = mknod( device_name, 0777 | S_IFCHR, dev );
+
+ /* this is the only error returned by the old version */
+ if ( status )
+ return RTEMS_TOO_MANY;
+
+#endif
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * rtems_io_lookup_name
+ *
+ * This version is reentrant.
+ *
+ * XXX - This is dependent upon IMFS and should not be.
+ * Suggest adding a filesystem routine to fill in the device_info.
+ */
+
+rtems_status_code rtems_io_lookup_name(
+ const char *name,
+ rtems_driver_name_t *device_info
+)
+{
+#if !defined(RTEMS_UNIX)
+ IMFS_jnode_t *the_jnode;
+ rtems_filesystem_location_info_t loc;
+ int result;
+ rtems_filesystem_node_types_t node_type;
+
+ result = rtems_filesystem_evaluate_path( name, 0x00, &loc, TRUE );
+ the_jnode = loc.node_access;
+
+ if ( !loc.ops->node_type_h ) {
+ rtems_filesystem_freenode( &loc );
+ rtems_set_errno_and_return_minus_one( ENOTSUP );
+ }
+
+ node_type = (*loc.ops->node_type_h)( &loc );
+
+ if ( (result != 0) || node_type != RTEMS_FILESYSTEM_DEVICE ) {
+ rtems_filesystem_freenode( &loc );
+ return RTEMS_UNSATISFIED;
+ }
+
+ device_info->device_name = (char *) name;
+ device_info->device_name_length = strlen( name );
+ device_info->major = the_jnode->info.device.major;
+ device_info->minor = the_jnode->info.device.minor;
+
+ rtems_filesystem_freenode( &loc );
+
+#endif
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/libfs/src/imfs/memfile.c b/cpukit/libfs/src/imfs/memfile.c
new file mode 100644
index 0000000000..4b4dc8ccce
--- /dev/null
+++ b/cpukit/libfs/src/imfs/memfile.c
@@ -0,0 +1,1160 @@
+/*
+ * IMFS Device Node Handlers
+ *
+ * This file contains the set of handlers used to process operations on
+ * IMFS memory file nodes. The memory files are created in memory using
+ * malloc'ed memory. Thus any data stored in one of these files is lost
+ * at system shutdown unless special arrangements to copy the data to
+ * some type of non-volailte storage are made by the application.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include "imfs.h"
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+#define MEMFILE_STATIC
+
+/*
+ * Prototypes of private routines
+ */
+
+MEMFILE_STATIC int IMFS_memfile_extend(
+ IMFS_jnode_t *the_jnode,
+ off_t new_length
+);
+
+MEMFILE_STATIC int IMFS_memfile_addblock(
+ IMFS_jnode_t *the_jnode,
+ unsigned int block
+);
+
+MEMFILE_STATIC int IMFS_memfile_remove_block(
+ IMFS_jnode_t *the_jnode,
+ unsigned int block
+);
+
+MEMFILE_STATIC block_p *IMFS_memfile_get_block_pointer(
+ IMFS_jnode_t *the_jnode,
+ unsigned int block,
+ int malloc_it
+);
+
+MEMFILE_STATIC ssize_t IMFS_memfile_read(
+ IMFS_jnode_t *the_jnode,
+ off_t start,
+ unsigned char *destination,
+ unsigned int length
+);
+
+ssize_t IMFS_memfile_write( /* cannot be static as used in imfs_fchmod.c */
+ IMFS_jnode_t *the_jnode,
+ off_t start,
+ const unsigned char *source,
+ unsigned int length
+);
+
+int memfile_check_rmnod( IMFS_jnode_t *the_jnode );
+
+void *memfile_alloc_block(void);
+
+void memfile_free_block(
+ void *memory
+);
+
+/*
+ * memfile_open
+ *
+ * This routine processes the open() system call. Note that there is
+ * nothing special to be done at open() time.
+ */
+
+int memfile_open(
+ rtems_libio_t *iop,
+ const char *pathname,
+ uint32_t flag,
+ uint32_t mode
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = iop->file_info;
+
+ /*
+ * Perform 'copy on write' for linear files
+ */
+ if ((iop->flags & (LIBIO_FLAGS_WRITE | LIBIO_FLAGS_APPEND))
+ && (the_jnode->type == IMFS_LINEAR_FILE)) {
+ uint32_t count = the_jnode->info.linearfile.size;
+ const unsigned char *buffer = the_jnode->info.linearfile.direct;
+
+ the_jnode->type = IMFS_MEMORY_FILE;
+ the_jnode->info.file.size = 0;
+ the_jnode->info.file.indirect = 0;
+ the_jnode->info.file.doubly_indirect = 0;
+ the_jnode->info.file.triply_indirect = 0;
+ if ((count != 0)
+ && (IMFS_memfile_write(the_jnode, 0, buffer, count) == -1))
+ return -1;
+ }
+ if (iop->flags & LIBIO_FLAGS_APPEND)
+ iop->offset = the_jnode->info.file.size;
+
+ iop->size = the_jnode->info.file.size;
+ return 0;
+}
+
+/*
+ * memfile_close
+ *
+ * This routine processes the close() system call. Note that there is
+ * nothing to flush or memory to free at this point.
+ */
+
+int memfile_close(
+ rtems_libio_t *iop
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = iop->file_info;
+
+ if (iop->flags & LIBIO_FLAGS_APPEND)
+ iop->offset = the_jnode->info.file.size;
+
+ memfile_check_rmnod( the_jnode );
+ return 0;
+}
+
+/*
+ * memfile_read
+ *
+ * This routine processes the read() system call.
+ */
+
+ssize_t memfile_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ uint32_t count
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = iop->file_info;
+
+ return IMFS_memfile_read( the_jnode, iop->offset, buffer, count );
+}
+
+/*
+ * memfile_write
+ *
+ * This routine processes the write() system call.
+ */
+
+ssize_t memfile_write(
+ rtems_libio_t *iop,
+ const void *buffer,
+ uint32_t count
+)
+{
+ IMFS_jnode_t *the_jnode;
+ ssize_t status;
+
+ the_jnode = iop->file_info;
+
+ status = IMFS_memfile_write( the_jnode, iop->offset, buffer, count );
+ iop->size = the_jnode->info.file.size;
+
+ return status;
+}
+
+/*
+ * memfile_ioctl
+ *
+ * This routine processes the ioctl() system call.
+ *
+ * NOTE: No ioctl()'s are supported for in-memory files.
+ */
+
+int memfile_ioctl(
+ rtems_libio_t *iop,
+ uint32_t command,
+ void *buffer
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = iop->file_info;
+
+ return 0;
+}
+
+/*
+ * memfile_lseek
+ *
+ * This routine processes the lseek() system call.
+ */
+
+int memfile_lseek(
+ rtems_libio_t *iop,
+ off_t offset,
+ int whence
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = iop->file_info;
+
+ if (the_jnode->type == IMFS_LINEAR_FILE) {
+ if (iop->offset > the_jnode->info.linearfile.size)
+ iop->offset = the_jnode->info.linearfile.size;
+ }
+ else { /* Must be a block file (IMFS_MEMORY_FILE). */
+ if (IMFS_memfile_extend( the_jnode, iop->offset ))
+ rtems_set_errno_and_return_minus_one( ENOSPC );
+
+ iop->size = the_jnode->info.file.size;
+ }
+ return iop->offset;
+}
+
+/*
+ * memfile_stat
+ *
+ * This IMFS_stat() can be used.
+ */
+
+/*
+ * memfile_ftruncate
+ *
+ * This routine processes the ftruncate() system call.
+ */
+
+int memfile_ftruncate(
+ rtems_libio_t *iop,
+ off_t length
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = iop->file_info;
+
+ /*
+ * POSIX 1003.1b does not specify what happens if you truncate a file
+ * and the new length is greater than the current size. We treat this
+ * as an extend operation.
+ */
+
+ if ( length > the_jnode->info.file.size )
+ return IMFS_memfile_extend( the_jnode, length );
+
+ /*
+ * The in-memory files do not currently reclaim memory until the file is
+ * deleted. So we leave the previously allocated blocks in place for
+ * future use and just set the length.
+ */
+
+ the_jnode->info.file.size = length;
+ iop->size = the_jnode->info.file.size;
+
+ IMFS_update_atime( the_jnode );
+
+ return 0;
+}
+
+/*
+ * IMFS_memfile_extend
+ *
+ * This routine insures that the in-memory file is of the length
+ * specified. If necessary, it will allocate memory blocks to
+ * extend the file.
+ */
+
+MEMFILE_STATIC int IMFS_memfile_extend(
+ IMFS_jnode_t *the_jnode,
+ off_t new_length
+)
+{
+ unsigned int block;
+ unsigned int new_blocks;
+ unsigned int old_blocks;
+
+ /*
+ * Perform internal consistency checks
+ */
+
+ assert( the_jnode );
+ if ( !the_jnode )
+ rtems_set_errno_and_return_minus_one( EIO );
+
+ assert( the_jnode->type == IMFS_MEMORY_FILE );
+ if ( the_jnode->type != IMFS_MEMORY_FILE )
+ rtems_set_errno_and_return_minus_one( EIO );
+
+ if ( new_length >= IMFS_MEMFILE_MAXIMUM_SIZE )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( new_length <= the_jnode->info.file.size )
+ return 0;
+
+ /*
+ * Calculate the number of range of blocks to allocate
+ */
+
+ new_blocks = new_length / IMFS_MEMFILE_BYTES_PER_BLOCK;
+ old_blocks = the_jnode->info.file.size / IMFS_MEMFILE_BYTES_PER_BLOCK;
+
+ /*
+ * Now allocate each of those blocks.
+ */
+
+ for ( block=old_blocks ; block<=new_blocks ; block++ ) {
+ if ( IMFS_memfile_addblock( the_jnode, block ) ) {
+ for ( ; block>=old_blocks ; block-- ) {
+ IMFS_memfile_remove_block( the_jnode, block );
+ }
+ rtems_set_errno_and_return_minus_one( ENOSPC );
+ }
+ }
+
+ /*
+ * Set the new length of the file.
+ */
+
+ the_jnode->info.file.size = new_length;
+ return 0;
+}
+
+/*
+ * IMFS_memfile_addblock
+ *
+ * This routine adds a single block to the specified in-memory file.
+ */
+
+MEMFILE_STATIC int IMFS_memfile_addblock(
+ IMFS_jnode_t *the_jnode,
+ unsigned int block
+)
+{
+ block_p memory;
+ block_p *block_entry_ptr;
+
+ assert( the_jnode );
+ if ( !the_jnode )
+ rtems_set_errno_and_return_minus_one( EIO );
+
+ assert( the_jnode->type == IMFS_MEMORY_FILE );
+ if ( the_jnode->type != IMFS_MEMORY_FILE )
+ rtems_set_errno_and_return_minus_one( EIO );
+
+ block_entry_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 1 );
+ if ( *block_entry_ptr )
+ return 0;
+
+#if 0
+ fprintf(stdout, "%d %p", block, block_entry_ptr );
+ fflush(stdout);
+#endif
+
+ memory = memfile_alloc_block();
+ if ( !memory )
+ return 1;
+ *block_entry_ptr = memory;
+
+ return 0;
+}
+
+/*
+ * IMFS_memfile_remove_block
+ *
+ * This routine removes the specified block from the in-memory file.
+ *
+ * NOTE: This is a support routine and is called only to remove
+ * the last block or set of blocks in a file. Removing a
+ * block from the middle of a file would be exceptionally
+ * dangerous and the results unpredictable.
+ */
+
+MEMFILE_STATIC int IMFS_memfile_remove_block(
+ IMFS_jnode_t *the_jnode,
+ unsigned int block
+)
+{
+ block_p *block_entry_ptr;
+ block_p ptr;
+
+ block_entry_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
+ ptr = *block_entry_ptr;
+ *block_entry_ptr = 0;
+
+ memfile_free_block( ptr );
+
+ return 1;
+}
+
+/*
+ * memfile_free_blocks_in_table
+ *
+ * This is a support routine for IMFS_memfile_remove. It frees all the
+ * blocks in one of the indirection tables.
+ */
+
+void memfile_free_blocks_in_table(
+ block_p **block_table,
+ int entries
+)
+{
+ int i;
+ block_p *b;
+
+ /*
+ * Perform internal consistency checks
+ */
+
+ assert( block_table );
+ if ( !block_table )
+ return;
+
+ /*
+ * Now go through all the slots in the table and free the memory.
+ */
+
+ b = *block_table;
+
+ for ( i=0 ; i<entries ; i++ ) {
+ if ( b[i] ) {
+ memfile_free_block( b[i] );
+ b[i] = 0;
+ }
+ }
+
+ /*
+ * Now that all the blocks in the block table are free, we can
+ * free the block table itself.
+ */
+
+ memfile_free_block( *block_table );
+ *block_table = 0;
+}
+
+/*
+ * IMFS_memfile_remove
+ *
+ * This routine frees all memory associated with an in memory file.
+ *
+ * NOTE: This is an exceptionally conservative implementation.
+ * It will check EVERY pointer which is non-NULL and insure
+ * any child non-NULL pointers are freed. Optimistically, all that
+ * is necessary is to scan until a NULL pointer is found. There
+ * should be no allocated data past that point.
+ *
+ * In experimentation on the powerpc simulator, it was noted
+ * that using blocks which held 128 slots versus 16 slots made
+ * a significant difference in the performance of this routine.
+ *
+ * Regardless until the IMFS implementation is proven, it
+ * is better to stick to simple, easy to understand algorithms.
+ */
+
+int IMFS_memfile_remove(
+ IMFS_jnode_t *the_jnode
+)
+{
+ IMFS_memfile_t *info;
+ int i;
+ int j;
+ unsigned int to_free;
+ block_p *p;
+
+ /*
+ * Perform internal consistency checks
+ */
+
+ assert( the_jnode );
+ if ( !the_jnode )
+ rtems_set_errno_and_return_minus_one( EIO );
+
+ assert( the_jnode->type == IMFS_MEMORY_FILE );
+ if ( the_jnode->type != IMFS_MEMORY_FILE )
+ rtems_set_errno_and_return_minus_one( EIO );
+
+ /*
+ * Eventually this could be set smarter at each call to
+ * memfile_free_blocks_in_table to greatly speed this up.
+ */
+
+ to_free = IMFS_MEMFILE_BLOCK_SLOTS;
+
+ /*
+ * Now start freeing blocks in this order:
+ * + indirect
+ * + doubly indirect
+ * + triply indirect
+ */
+
+ info = &the_jnode->info.file;
+
+ if ( info->indirect ) {
+ memfile_free_blocks_in_table( &info->indirect, to_free );
+ }
+
+ if ( info->doubly_indirect ) {
+
+ for ( i=0 ; i<IMFS_MEMFILE_BLOCK_SLOTS ; i++ ) {
+ if ( info->doubly_indirect[i] ) {
+ memfile_free_blocks_in_table(
+ (block_p **)&info->doubly_indirect[i], to_free );
+ }
+ }
+ memfile_free_blocks_in_table( &info->doubly_indirect, to_free );
+
+ }
+
+ if ( info->triply_indirect ) {
+ for ( i=0 ; i<IMFS_MEMFILE_BLOCK_SLOTS ; i++ ) {
+ p = (block_p *) info->triply_indirect[i];
+ if ( !p ) /* ensure we have a valid pointer */
+ break;
+ for ( j=0 ; j<IMFS_MEMFILE_BLOCK_SLOTS ; j++ ) {
+ if ( p[j] ) {
+ memfile_free_blocks_in_table( (block_p **)&p[j], to_free);
+ }
+ }
+ memfile_free_blocks_in_table(
+ (block_p **)&info->triply_indirect[i], to_free );
+ }
+ memfile_free_blocks_in_table(
+ (block_p **)&info->triply_indirect, to_free );
+ }
+
+ return 0;
+}
+
+/*
+ * IMFS_memfile_read
+ *
+ * This routine read from memory file pointed to by the_jnode into
+ * the specified data buffer specified by destination. The file
+ * is NOT extended. An offset greater than the length of the file
+ * is considered an error. Read from an offset for more bytes than
+ * are between the offset and the end of the file will result in
+ * reading the data between offset and the end of the file (truncated
+ * read).
+ */
+
+MEMFILE_STATIC ssize_t IMFS_memfile_read(
+ IMFS_jnode_t *the_jnode,
+ off_t start,
+ unsigned char *destination,
+ unsigned int length
+)
+{
+ block_p *block_ptr;
+ unsigned int block;
+ unsigned int my_length;
+ unsigned int to_copy = 0;
+ unsigned int last_byte;
+ unsigned int copied;
+ unsigned int start_offset;
+ unsigned char *dest;
+
+ dest = destination;
+
+ /*
+ * Perform internal consistency checks
+ */
+
+ assert( the_jnode );
+ if ( !the_jnode )
+ rtems_set_errno_and_return_minus_one( EIO );
+
+ assert( the_jnode->type == IMFS_MEMORY_FILE ||
+ the_jnode->type == IMFS_LINEAR_FILE );
+ if ( the_jnode->type != IMFS_MEMORY_FILE &&
+ the_jnode->type != IMFS_LINEAR_FILE )
+ rtems_set_errno_and_return_minus_one( EIO );
+
+ /*
+ * Error checks on arguments
+ */
+
+ assert( dest );
+ if ( !dest )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ /*
+ * If there is nothing to read, then quick exit.
+ */
+
+ my_length = length;
+ if ( !my_length )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ /*
+ * Linear files (as created from a tar file are easier to handle
+ * than block files).
+ */
+ if (the_jnode->type == IMFS_LINEAR_FILE) {
+ unsigned char *file_ptr;
+
+ file_ptr = (unsigned char *)the_jnode->info.linearfile.direct;
+
+ if (my_length > (the_jnode->info.linearfile.size - start))
+ my_length = the_jnode->info.linearfile.size - start;
+
+ memcpy(dest, &file_ptr[start], my_length);
+
+ IMFS_update_atime( the_jnode );
+
+ return my_length;
+ }
+
+ /*
+ * If the last byte we are supposed to read is past the end of this
+ * in memory file, then shorten the length to read.
+ */
+
+ last_byte = start + length;
+ if ( last_byte > the_jnode->info.file.size )
+ my_length = the_jnode->info.file.size - start;
+
+ copied = 0;
+
+ /*
+ * Three phases to the read:
+ * + possibly the last part of one block
+ * + all of zero of more blocks
+ * + possibly the first part of one block
+ */
+
+ /*
+ * Phase 1: possibly the last part of one block
+ */
+
+ start_offset = start % IMFS_MEMFILE_BYTES_PER_BLOCK;
+ block = start / IMFS_MEMFILE_BYTES_PER_BLOCK;
+ if ( start_offset ) {
+ to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK - start_offset;
+ if ( to_copy > my_length )
+ to_copy = my_length;
+ block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
+ assert( block_ptr );
+ if ( !block_ptr )
+ return copied;
+ memcpy( dest, &(*block_ptr)[ start_offset ], to_copy );
+ dest += to_copy;
+ block++;
+ my_length -= to_copy;
+ copied += to_copy;
+ }
+
+ /*
+ * Phase 2: all of zero of more blocks
+ */
+
+ to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK;
+ while ( my_length >= IMFS_MEMFILE_BYTES_PER_BLOCK ) {
+ block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
+ assert( block_ptr );
+ if ( !block_ptr )
+ return copied;
+ memcpy( dest, &(*block_ptr)[ 0 ], to_copy );
+ dest += to_copy;
+ block++;
+ my_length -= to_copy;
+ copied += to_copy;
+ }
+
+ /*
+ * Phase 3: possibly the first part of one block
+ */
+
+ assert( my_length < IMFS_MEMFILE_BYTES_PER_BLOCK );
+
+ if ( my_length ) {
+ block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
+ assert( block_ptr );
+ if ( !block_ptr )
+ return copied;
+ memcpy( dest, &(*block_ptr)[ 0 ], my_length );
+ copied += my_length;
+ }
+
+ IMFS_update_atime( the_jnode );
+
+ return copied;
+}
+
+/*
+ * IMFS_memfile_write
+ *
+ * This routine writes the specified data buffer into the in memory
+ * file pointed to by the_jnode. The file is extended as needed.
+ */
+
+MEMFILE_STATIC ssize_t IMFS_memfile_write(
+ IMFS_jnode_t *the_jnode,
+ off_t start,
+ const unsigned char *source,
+ unsigned int length
+)
+{
+ block_p *block_ptr;
+ unsigned int block;
+ int status;
+ unsigned int my_length;
+ unsigned int to_copy = 0;
+ unsigned int last_byte;
+ unsigned int start_offset;
+ int copied;
+ const unsigned char *src;
+
+ src = source;
+
+ /*
+ * Perform internal consistency checks
+ */
+
+ assert( the_jnode );
+ if ( !the_jnode )
+ rtems_set_errno_and_return_minus_one( EIO );
+
+ assert( the_jnode->type == IMFS_MEMORY_FILE );
+ if ( the_jnode->type != IMFS_MEMORY_FILE )
+ rtems_set_errno_and_return_minus_one( EIO );
+
+ /*
+ * Error check arguments
+ */
+
+ assert( source );
+ if ( !source )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+
+ /*
+ * If there is nothing to write, then quick exit.
+ */
+
+ my_length = length;
+ if ( !my_length )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ /*
+ * If the last byte we are supposed to write is past the end of this
+ * in memory file, then extend the length.
+ */
+
+ last_byte = start + length;
+ if ( last_byte > the_jnode->info.file.size ) {
+ status = IMFS_memfile_extend( the_jnode, last_byte );
+ if ( status )
+ rtems_set_errno_and_return_minus_one( ENOSPC );
+ }
+
+ copied = 0;
+
+ /*
+ * Three phases to the write:
+ * + possibly the last part of one block
+ * + all of zero of more blocks
+ * + possibly the first part of one block
+ */
+
+ /*
+ * Phase 1: possibly the last part of one block
+ */
+
+ start_offset = start % IMFS_MEMFILE_BYTES_PER_BLOCK;
+ block = start / IMFS_MEMFILE_BYTES_PER_BLOCK;
+ if ( start_offset ) {
+ to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK - start_offset;
+ if ( to_copy > my_length )
+ to_copy = my_length;
+ block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
+ assert( block_ptr );
+ if ( !block_ptr )
+ return copied;
+#if 0
+fprintf(stdout, "write %d at %d in %d: %*s\n", to_copy, start_offset, block, to_copy, src );
+#endif
+ memcpy( &(*block_ptr)[ start_offset ], src, to_copy );
+ src += to_copy;
+ block++;
+ my_length -= to_copy;
+ copied += to_copy;
+ }
+
+ /*
+ * Phase 2: all of zero of more blocks
+ */
+
+ to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK;
+ while ( my_length >= IMFS_MEMFILE_BYTES_PER_BLOCK ) {
+ block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
+ assert( block_ptr );
+ if ( !block_ptr )
+ return copied;
+#if 0
+fprintf(stdout, "write %d in %d: %*s\n", to_copy, block, to_copy, src );
+#endif
+ memcpy( &(*block_ptr)[ 0 ], src, to_copy );
+ src += to_copy;
+ block++;
+ my_length -= to_copy;
+ copied += to_copy;
+ }
+
+ /*
+ * Phase 3: possibly the first part of one block
+ */
+
+ assert( my_length < IMFS_MEMFILE_BYTES_PER_BLOCK );
+
+ to_copy = my_length;
+ if ( my_length ) {
+ block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
+ assert( block_ptr );
+ if ( !block_ptr )
+ return copied;
+#if 0
+fprintf(stdout, "write %d in %d: %*s\n", to_copy, block, to_copy, src );
+#endif
+ memcpy( &(*block_ptr)[ 0 ], src, my_length );
+ my_length = 0;
+ copied += to_copy;
+ }
+
+ IMFS_atime_mtime_update( the_jnode );
+
+ return copied;
+}
+
+/*
+ * IMFS_memfile_get_block_pointer
+ *
+ * This routine looks up the block pointer associated with the given block
+ * number. If that block has not been allocated and "malloc_it" is
+ * TRUE, then the block is allocated. Otherwise, it is an error.
+ */
+
+#if 0
+block_p *IMFS_memfile_get_block_pointer_DEBUG(
+ IMFS_jnode_t *the_jnode,
+ unsigned int block,
+ int malloc_it
+);
+
+block_p *IMFS_memfile_get_block_pointer(
+ IMFS_jnode_t *the_jnode,
+ unsigned int block,
+ int malloc_it
+)
+{
+ block_p *p;
+
+ p = IMFS_memfile_get_block_pointer_DEBUG( the_jnode, block, malloc_it );
+ fprintf(stdout, "(%d -> %p) ", block, p );
+ return p;
+}
+
+block_p *IMFS_memfile_get_block_pointer_DEBUG(
+#else
+block_p *IMFS_memfile_get_block_pointer(
+#endif
+ IMFS_jnode_t *the_jnode,
+ unsigned int block,
+ int malloc_it
+)
+{
+ unsigned int my_block;
+ IMFS_memfile_t *info;
+ unsigned int singly;
+ unsigned int doubly;
+ unsigned int triply;
+ block_p *p;
+ block_p *p1;
+ block_p *p2;
+
+ /*
+ * Perform internal consistency checks
+ */
+
+ assert( the_jnode );
+ if ( !the_jnode )
+ return NULL;
+
+ assert( the_jnode->type == IMFS_MEMORY_FILE );
+ if ( the_jnode->type != IMFS_MEMORY_FILE )
+ return NULL;
+
+ info = &the_jnode->info.file;
+
+ my_block = block;
+
+ /*
+ * Is the block number in the simple indirect portion?
+ */
+
+ if ( my_block <= LAST_INDIRECT ) {
+#if 0
+fprintf(stdout, "(s %d) ", block );
+fflush(stdout);
+#endif
+ p = info->indirect;
+
+ if ( malloc_it ) {
+
+ if ( !p ) {
+ p = memfile_alloc_block();
+ if ( !p )
+ return 0;
+ info->indirect = p;
+ }
+ return &info->indirect[ my_block ];
+ }
+
+ if ( !p )
+ return 0;
+
+ return &info->indirect[ my_block ];
+ }
+
+ /*
+ * Is the block number in the doubly indirect portion?
+ */
+
+ if ( my_block <= LAST_DOUBLY_INDIRECT ) {
+#if 0
+fprintf(stdout, "(d %d) ", block );
+fflush(stdout);
+#endif
+
+ my_block -= FIRST_DOUBLY_INDIRECT;
+
+ singly = my_block % IMFS_MEMFILE_BLOCK_SLOTS;
+ doubly = my_block / IMFS_MEMFILE_BLOCK_SLOTS;
+
+ p = info->doubly_indirect;
+ if ( malloc_it ) {
+
+ if ( !p ) {
+ p = memfile_alloc_block();
+ if ( !p )
+ return 0;
+ info->doubly_indirect = p;
+ }
+
+ p1 = (block_p *)p[ doubly ];
+ if ( !p1 ) {
+ p1 = memfile_alloc_block();
+ if ( !p1 )
+ return 0;
+ p[ doubly ] = (block_p) p1;
+ }
+
+ return (block_p *)&p1[ singly ];
+ }
+
+ if ( !p )
+ return 0;
+
+ p = (block_p *)p[ doubly ];
+ if ( !p )
+ return 0;
+
+#if 0
+fprintf(stdout, "(d %d %d %d %d %p %p) ", block, my_block, doubly,
+ singly, p, &p[singly] );
+fflush(stdout);
+#endif
+ return (block_p *)&p[ singly ];
+ }
+
+#if 0
+fprintf(stdout, "(t %d) ", block );
+fflush(stdout);
+#endif
+ /*
+ * Is the block number in the triply indirect portion?
+ */
+
+ if ( my_block <= LAST_TRIPLY_INDIRECT ) {
+ my_block -= FIRST_TRIPLY_INDIRECT;
+
+ singly = my_block % IMFS_MEMFILE_BLOCK_SLOTS;
+ doubly = my_block / IMFS_MEMFILE_BLOCK_SLOTS;
+ triply = doubly / IMFS_MEMFILE_BLOCK_SLOTS;
+ doubly %= IMFS_MEMFILE_BLOCK_SLOTS;
+
+ p = info->triply_indirect;
+
+ if ( malloc_it ) {
+ if ( !p ) {
+ p = memfile_alloc_block();
+ if ( !p )
+ return 0;
+ info->triply_indirect = p;
+ }
+
+ p1 = (block_p *) p[ triply ];
+ if ( !p1 ) {
+ p1 = memfile_alloc_block();
+ if ( !p1 )
+ return 0;
+ p[ triply ] = (block_p) p1;
+ }
+
+ p2 = (block_p *)p1[ doubly ];
+ if ( !p2 ) {
+ p2 = memfile_alloc_block();
+ if ( !p2 )
+ return 0;
+ p1[ doubly ] = (block_p) p2;
+ }
+ return (block_p *)&p2[ singly ];
+ }
+
+ if ( !p )
+ return 0;
+
+#if 0
+fprintf(stdout, "(t %d %d %d %d %d) ", block, my_block, triply, doubly, singly );
+fflush(stdout);
+#endif
+ p1 = (block_p *) p[ triply ];
+ if ( !p1 )
+ return 0;
+
+ p2 = (block_p *)p1[ doubly ];
+ if ( !p )
+ return 0;
+
+ return (block_p *)&p2[ singly ];
+ }
+
+ /*
+ * This means the requested block number is out of range.
+ */
+
+ return 0;
+}
+
+/*
+ * memfile_alloc_block
+ *
+ * Allocate a block for an in-memory file.
+ */
+
+int memfile_blocks_allocated = 0;
+
+void *memfile_alloc_block(void)
+{
+ void *memory;
+
+ memory = (void *)calloc(1, IMFS_MEMFILE_BYTES_PER_BLOCK);
+ if ( memory )
+ memfile_blocks_allocated++;
+
+ return memory;
+}
+
+/*
+ * memfile_free_block
+ *
+ * Free a block from an in-memory file.
+ */
+
+void memfile_free_block(
+ void *memory
+)
+{
+#if 0
+fprintf(stdout, "(d %p) ", memory );
+fflush(stdout);
+#endif
+ free(memory);
+ memfile_blocks_allocated--;
+}
+
+
+/*
+ * memfile_rmnod
+ *
+ * This routine is available from the optable to remove a node
+ * from the IMFS file system.
+ */
+
+int memfile_rmnod(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = (IMFS_jnode_t *) pathloc->node_access;
+
+ /*
+ * Take the node out of the parent's chain that contains this node
+ */
+
+ if ( the_jnode->Parent != NULL ) {
+ Chain_Extract( (Chain_Node *) the_jnode );
+ the_jnode->Parent = NULL;
+ }
+
+ /*
+ * Decrement the link counter and see if we can free the space.
+ */
+
+ the_jnode->st_nlink--;
+ IMFS_update_ctime( the_jnode );
+
+ return memfile_check_rmnod( the_jnode );
+}
+
+
+int memfile_check_rmnod( IMFS_jnode_t *the_jnode ){
+
+ /*
+ * The file cannot be open and the link must be less than 1 to free.
+ */
+
+ if ( !rtems_libio_is_file_open( the_jnode ) && (the_jnode->st_nlink < 1) ) {
+
+ /*
+ * Is the rtems_filesystem_current is this node?
+ */
+
+ if ( rtems_filesystem_current.node_access == the_jnode )
+ rtems_filesystem_current.node_access = NULL;
+
+ /*
+ * Free memory associated with a memory file.
+ */
+ if (the_jnode->type != IMFS_LINEAR_FILE)
+ IMFS_memfile_remove( the_jnode );
+
+ free( the_jnode );
+ }
+
+ return 0;
+}
diff --git a/cpukit/libfs/src/imfs/miniimfs_init.c b/cpukit/libfs/src/imfs/miniimfs_init.c
new file mode 100644
index 0000000000..fdf2310cf3
--- /dev/null
+++ b/cpukit/libfs/src/imfs/miniimfs_init.c
@@ -0,0 +1,69 @@
+/*
+ * Mini-IMFS Initialization
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h> /* for mkdir */
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <assert.h>
+
+#include "imfs.h"
+#include <rtems/libio_.h>
+
+#if defined(IMFS_DEBUG)
+#include <stdio.h>
+#endif
+
+/*
+ * miniIMFS file system operations table
+ */
+
+rtems_filesystem_operations_table miniIMFS_ops = {
+ IMFS_eval_path,
+ IMFS_evaluate_for_make,
+ NULL, /* XXX IMFS_link, */
+ NULL, /* XXX IMFS_unlink, */
+ IMFS_node_type,
+ IMFS_mknod,
+ NULL, /* XXX IMFS_chown, */
+ NULL, /* XXX IMFS_freenodinfo, */
+ NULL, /* XXX IMFS_mount, */
+ miniIMFS_initialize,
+ NULL, /* XXX IMFS_unmount, */
+ NULL, /* XXX IMFS_fsunmount, */
+ NULL, /* XXX IMFS_utime, */
+ NULL, /* XXX IMFS_evaluate_link, */
+ NULL, /* XXX IMFS_symlink, */
+ NULL /* XXX IMFS_readlink */
+};
+
+/*
+ * miniIMFS_initialize
+ */
+
+int miniIMFS_initialize(
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry
+)
+{
+ return IMFS_initialize_support(
+ temp_mt_entry,
+ &miniIMFS_ops,
+ &rtems_filesystem_null_handlers, /* for memfiles */
+ &rtems_filesystem_null_handlers /* for directories */
+ );
+}
diff --git a/cpukit/libi2c/.cvsignore b/cpukit/libi2c/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/libi2c/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/libi2c/Makefile.am b/cpukit/libi2c/Makefile.am
new file mode 100644
index 0000000000..c422529bc8
--- /dev/null
+++ b/cpukit/libi2c/Makefile.am
@@ -0,0 +1,11 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+noinst_LIBRARIES = libi2c.a
+
+libi2c_a_SOURCES = libi2c.c libi2c.h
+
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/libi2c/libi2c.c b/cpukit/libi2c/libi2c.c
new file mode 100644
index 0000000000..cccce0136f
--- /dev/null
+++ b/cpukit/libi2c/libi2c.c
@@ -0,0 +1,598 @@
+/* $Id$ */
+
+/* libi2c Implementation */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <rtems.h>
+#include <rtems/error.h>
+#include <rtems/libio.h>
+
+#include <rtems/libi2c.h>
+
+#define DRVNM "libi2c:"
+
+#define MAX_NO_BUSSES 8 /* Also limited by the macro building minor numbers */
+#define MAX_NO_DRIVERS 16 /* Number of high level drivers we support */
+
+#define MINOR2ADDR(minor) ((minor)&((1<<10)-1))
+#define MINOR2BUS(minor) (((minor)>>10)&7)
+#define MINOR2DRV(minor) ((minor)>>13)
+
+/* Check the 'minor' argument, i.e., verify that
+ * we have a driver connected
+ */
+#define DECL_CHECKED_BH(b, bh, m, s)\
+ unsigned b = MINOR2BUS(m); \
+ rtems_libi2c_bus_t *bh; \
+ if ( b >= MAX_NO_BUSSES || 0 == (bh=busses[b].bush) ) { \
+ return s RTEMS_INVALID_NUMBER; \
+ }
+
+#define DECL_CHECKED_DRV(d, b, m) \
+ unsigned d = MINOR2DRV(m); \
+ unsigned b = MINOR2BUS(m); \
+ if ( b >= MAX_NO_BUSSES || 0 == busses[b].bush \
+ || d > MAX_NO_DRIVERS || (d && 0 == drvs[d-1].drv )) {\
+ return RTEMS_INVALID_NUMBER; \
+ }
+
+#define DISPATCH(rval, entry, dflt) \
+ do { \
+ rtems_driver_address_table *ops = drvs[--drv].drv->ops; \
+ rval = ops->entry ? ops->entry(major,minor,arg) : dflt; \
+ } while (0)
+
+
+rtems_device_major_number rtems_libi2c_major;
+
+static struct i2cbus
+{
+ rtems_libi2c_bus_t *bush;
+ volatile rtems_id mutex; /* lock this across start -> stop */
+ volatile short waiting;
+ volatile char started;
+ char *name;
+} busses[MAX_NO_BUSSES] = { { 0 } };
+
+static struct
+{
+ rtems_libi2c_drv_t *drv;
+} drvs[MAX_NO_DRIVERS] = { { 0} };
+
+static rtems_id libmutex = 0;
+
+#define LOCK(m) assert(!rtems_semaphore_obtain((m), RTEMS_WAIT, RTEMS_NO_TIMEOUT))
+#define UNLOCK(m) rtems_semaphore_release((m))
+
+#define LIBLOCK() LOCK(libmutex)
+#define LIBUNLOCK() UNLOCK(libmutex)
+
+#define MUTEX_ATTS \
+ ( RTEMS_PRIORITY \
+ | RTEMS_BINARY_SEMAPHORE \
+ |RTEMS_INHERIT_PRIORITY \
+ |RTEMS_NO_PRIORITY_CEILING \
+ |RTEMS_LOCAL )
+
+static rtems_id
+mutexCreate (rtems_name nm)
+{
+ rtems_status_code sc;
+ rtems_id rval;
+ if (RTEMS_SUCCESSFUL !=
+ (sc = rtems_semaphore_create (nm, 1, MUTEX_ATTS, 0, &rval))) {
+ rtems_error (sc, DRVNM " unable to create mutex\n");
+ return 0;
+ }
+ return rval;
+}
+
+/* Lock a bus avoiding to have a mutex, which is mostly
+ * unused, hanging around all the time. We just create
+ * and delete it on the fly...
+ *
+ * ASSUMES: argument checked by caller
+ */
+
+static void
+lock_bus (int busno)
+{
+ struct i2cbus *bus = &busses[busno];
+ LIBLOCK ();
+ if (!bus->waiting) {
+ /* nobody is holding the bus mutex - it's not there. Create it on the fly */
+ if (!
+ (bus->mutex =
+ mutexCreate (rtems_build_name ('i', '2', 'c', '0' + busno)))) {
+ LIBUNLOCK ();
+ rtems_panic (DRVNM " unable to create bus lock");
+ }
+ }
+ /* count number of people waiting on this bus; only the last one deletes the mutex */
+ bus->waiting++;
+ LIBUNLOCK ();
+ /* Now lock this bus */
+ LOCK (bus->mutex);
+}
+
+static void
+unlock_bus (int busno)
+{
+ struct i2cbus *bus = &busses[busno];
+ LIBLOCK ();
+ UNLOCK (bus->mutex);
+ if (!--bus->waiting) {
+ rtems_semaphore_delete (bus->mutex);
+ }
+ LIBUNLOCK ();
+}
+
+/* Note that 'arg' is always passed in as NULL */
+static rtems_status_code
+i2c_init (rtems_device_major_number major, rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code rval;
+ DECL_CHECKED_DRV (drv, busno, minor)
+
+ if (0 == drv) {
+ rval = 0;
+ } else {
+ /* this is probably never called */
+ DISPATCH (rval, initialization_entry, RTEMS_SUCCESSFUL);
+ }
+ return rval;
+}
+
+static rtems_status_code
+i2c_open (rtems_device_major_number major, rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code rval;
+ DECL_CHECKED_DRV (drv, busno, minor)
+
+ if (0 == drv) {
+ rval = RTEMS_SUCCESSFUL;
+ } else {
+ DISPATCH (rval, open_entry, RTEMS_SUCCESSFUL);
+ }
+ return rval;
+}
+
+static rtems_status_code
+i2c_close (rtems_device_major_number major, rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code rval;
+ DECL_CHECKED_DRV (drv, busno, minor)
+
+ if (0 == drv) {
+ rval = RTEMS_SUCCESSFUL;
+ } else {
+ DISPATCH (rval, close_entry, RTEMS_SUCCESSFUL);
+ }
+ return rval;
+}
+
+static rtems_status_code
+i2c_read (rtems_device_major_number major, rtems_device_minor_number minor,
+ void *arg)
+{
+ int rval; /* int so we can check for negative value */
+ rtems_libio_rw_args_t *rwargs = arg;
+ DECL_CHECKED_DRV (drv, busno, minor)
+
+ if (0 == rwargs->count) {
+ rwargs->bytes_moved = 0;
+ return RTEMS_SUCCESSFUL;
+ }
+
+ if (0 == drv) {
+ rval =
+ rtems_libi2c_start_read_bytes (minor, (unsigned char *) rwargs->buffer,
+ rwargs->count);
+ if (rval >= 0) {
+ rwargs->bytes_moved = rval;
+ rtems_libi2c_send_stop (minor);
+ rval = RTEMS_SUCCESSFUL;
+ } else {
+ rval = -rval;
+ }
+ } else {
+ DISPATCH (rval, read_entry, RTEMS_NOT_IMPLEMENTED);
+ }
+ return rval;
+}
+
+static rtems_status_code
+i2c_write (rtems_device_major_number major, rtems_device_minor_number minor,
+ void *arg)
+{
+ int rval; /* int so we can check for negative value */
+ rtems_libio_rw_args_t *rwargs = arg;
+ DECL_CHECKED_DRV (drv, busno, minor)
+
+ if (0 == rwargs->count) {
+ rwargs->bytes_moved = 0;
+ return RTEMS_SUCCESSFUL;
+ }
+
+ if (0 == drv) {
+ rval =
+ rtems_libi2c_start_write_bytes (minor, (unsigned char *) rwargs->buffer,
+ rwargs->count);
+ if (rval >= 0) {
+ rwargs->bytes_moved = rval;
+ rtems_libi2c_send_stop (minor);
+ rval = RTEMS_SUCCESSFUL;
+ } else {
+ rval = -rval;
+ }
+ } else {
+ DISPATCH (rval, write_entry, RTEMS_NOT_IMPLEMENTED);
+ }
+ return rval;
+}
+
+static rtems_status_code
+i2c_ioctl (rtems_device_major_number major, rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code rval;
+ DECL_CHECKED_DRV (drv, busno, minor)
+
+ if (0 == drv) {
+ rval = RTEMS_NOT_IMPLEMENTED;
+ } else {
+ DISPATCH (rval, control_entry, RTEMS_NOT_IMPLEMENTED);
+ }
+ return rval;
+}
+
+
+/* Our ops just dispatch to the registered drivers */
+static rtems_driver_address_table libi2c_io_ops = {
+ initialization_entry: i2c_init,
+ open_entry: i2c_open,
+ close_entry: i2c_close,
+ read_entry: i2c_read,
+ write_entry: i2c_write,
+ control_entry: i2c_ioctl,
+};
+
+
+int
+rtems_libi2c_initialize ()
+{
+ rtems_status_code sc;
+
+ if (!(libmutex = mutexCreate (rtems_build_name ('l', 'I', '2', 'C'))))
+ return -1;
+
+ sc = rtems_io_register_driver (0, &libi2c_io_ops, &rtems_libi2c_major);
+ if (RTEMS_SUCCESSFUL != 0) {
+ fprintf (stderr,
+ DRVNM " Claiming driver slot failed (rtems status code %i)\n",
+ sc);
+ rtems_semaphore_delete (libmutex);
+ libmutex = 0;
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+rtems_libi2c_register_bus (char *name, rtems_libi2c_bus_t * bus)
+{
+ int i;
+ rtems_status_code err;
+ char *nmcpy = malloc (name ? strlen (name) + 1 : 20);
+ char tmp, *chpt;
+ struct stat sbuf;
+
+ strcpy (nmcpy, name ? name : "/dev/i2c");
+
+
+ /* check */
+ if ('/' != *nmcpy) {
+ fprintf (stderr,
+ "Bad name; must be an absolute path starting with '/'\n");
+ return -RTEMS_INVALID_NAME;
+ }
+ /* file must not exist */
+ if (!stat (nmcpy, &sbuf)) {
+ fprintf (stderr, "Bad name; file exists already\n");
+ return -RTEMS_INVALID_NAME;
+ }
+
+ /* we already verified that there is at least one '/' */
+ chpt = strrchr (nmcpy, '/') + 1;
+ tmp = *chpt;
+ *chpt = 0;
+ i = stat (nmcpy, &sbuf);
+ *chpt = tmp;
+ if (i) {
+ fprintf (stderr, "Bad name '%s'; parent directory doesn't exist\n",
+ nmcpy);
+ return -RTEMS_INVALID_NAME;
+ }
+ /* should be a directory since name terminates in '/' */
+
+
+ if (!libmutex) {
+ fprintf (stderr, DRVNM " library not initialized\n");
+ return -RTEMS_NOT_DEFINED;
+ }
+
+ if (bus->size < sizeof (*bus)) {
+ fprintf (stderr, DRVNM " bus-ops size too small -- misconfiguration?\n");
+ return -RTEMS_NOT_CONFIGURED;
+ }
+
+ LIBLOCK ();
+ for (i = 0; i < MAX_NO_BUSSES; i++) {
+ if (!busses[i].bush) {
+ /* found a free slot */
+ busses[i].bush = bus;
+ busses[i].mutex = 0;
+ busses[i].waiting = 0;
+ busses[i].started = 0;
+
+ if (!name)
+ sprintf (nmcpy + strlen (nmcpy), "%i", i);
+
+ if ((err = busses[i].bush->ops->init (busses[i].bush))) {
+ /* initialization failed */
+ i = -err;
+ } else {
+ busses[i].name = nmcpy;;
+ nmcpy = 0;
+ }
+
+ break;
+ }
+ }
+ LIBUNLOCK ();
+
+ if (i >= MAX_NO_BUSSES) {
+ i = -RTEMS_TOO_MANY;
+ }
+
+ free (nmcpy);
+
+ return i;
+}
+
+static int
+not_started (int busno)
+{
+ int rval;
+ lock_bus (busno);
+ rval = !busses[busno].started;
+ unlock_bus (busno);
+ return rval;
+}
+
+rtems_status_code
+rtems_libi2c_send_start (uint32_t minor)
+{
+ int rval;
+ DECL_CHECKED_BH (busno, bush, minor, +)
+
+ lock_bus (busno);
+ rval = bush->ops->send_start (bush);
+
+ /* if this failed or is not the first start, unlock */
+ if (rval || busses[busno].started) {
+ /* HMM - what to do if the 1st start failed ?
+ * try to reset...
+ */
+ if (!busses[busno].started) {
+ /* just in case the bus driver fiddles with errno */
+ int errno_saved = errno;
+ bush->ops->init (bush);
+ errno = errno_saved;
+ } else if (rval) {
+ /* failed restart */
+ rtems_libi2c_send_stop (minor);
+ }
+ unlock_bus (busno);
+ } else {
+ /* successful 1st start; keep bus locked until stop is sent */
+ busses[busno].started = 1;
+ }
+ return rval;
+}
+
+rtems_status_code
+rtems_libi2c_send_stop (uint32_t minor)
+{
+ rtems_status_code rval;
+ DECL_CHECKED_BH (busno, bush, minor, +)
+
+ if (not_started (busno))
+ return RTEMS_NOT_OWNER_OF_RESOURCE;
+
+ rval = bush->ops->send_stop (bush);
+
+ busses[busno].started = 0;
+
+ unlock_bus (busno);
+ return rval;
+}
+
+rtems_status_code
+rtems_libi2c_send_addr (uint32_t minor, int rw)
+{
+ rtems_status_code sc;
+ DECL_CHECKED_BH (busno, bush, minor, +)
+
+ if (not_started (busno))
+ return RTEMS_NOT_OWNER_OF_RESOURCE;
+
+ sc = bush->ops->send_addr (bush, MINOR2ADDR (minor), rw);
+ if (RTEMS_SUCCESSFUL != sc)
+ rtems_libi2c_send_stop (minor);
+ return sc;
+}
+
+int
+rtems_libi2c_read_bytes (uint32_t minor, unsigned char *bytes, int nbytes)
+{
+ int sc;
+ DECL_CHECKED_BH (busno, bush, minor, -)
+
+ if (not_started (busno))
+ return -RTEMS_NOT_OWNER_OF_RESOURCE;
+
+ sc = bush->ops->read_bytes (bush, bytes, nbytes);
+ if (sc < 0)
+ rtems_libi2c_send_stop (minor);
+ return sc;
+}
+
+int
+rtems_libi2c_write_bytes (uint32_t minor, unsigned char *bytes, int nbytes)
+{
+ int sc;
+ DECL_CHECKED_BH (busno, bush, minor, -)
+
+ if (not_started (busno))
+ return -RTEMS_NOT_OWNER_OF_RESOURCE;
+
+ sc = bush->ops->write_bytes (bush, bytes, nbytes);
+ if (sc < 0)
+ rtems_libi2c_send_stop (minor);
+ return sc;
+}
+
+static int
+do_s_rw (uint32_t minor, unsigned char *bytes, int nbytes, int rw)
+{
+ rtems_status_code sc;
+ rtems_libi2c_bus_t *bush;
+
+ if ((sc = rtems_libi2c_send_start (minor)))
+ return -sc;
+
+ /* at this point, we hold the bus and are sure the minor number is valid */
+ bush = busses[MINOR2BUS (minor)].bush;
+
+ if ((sc = bush->ops->send_addr (bush, MINOR2ADDR (minor), rw))) {
+ rtems_libi2c_send_stop (minor);
+ return -sc;
+ }
+
+ if (rw)
+ sc = bush->ops->read_bytes (bush, bytes, nbytes);
+ else
+ sc = bush->ops->write_bytes (bush, bytes, nbytes);
+
+ if (sc < 0) {
+ rtems_libi2c_send_stop (minor);
+ }
+ return sc;
+}
+
+int
+rtems_libi2c_start_read_bytes (uint32_t minor, unsigned char *bytes,
+ int nbytes)
+{
+ return do_s_rw (minor, bytes, nbytes, 1);
+}
+
+int
+rtems_libi2c_start_write_bytes (uint32_t minor, unsigned char *bytes,
+ int nbytes)
+{
+ return do_s_rw (minor, bytes, nbytes, 0);
+}
+
+int
+rtems_libi2c_register_drv (char *name, rtems_libi2c_drv_t * drvtbl,
+ unsigned busno, unsigned i2caddr)
+{
+ int i;
+ rtems_status_code err;
+ rtems_device_minor_number minor;
+
+ if (!libmutex) {
+ fprintf (stderr, DRVNM " library not initialized\n");
+ return -RTEMS_NOT_DEFINED;
+ }
+
+ if (name && strchr (name, '/')) {
+ fprintf (stderr, "Invalid name: '%s' -- must not contain '/'\n", name);
+ return -RTEMS_INVALID_NAME;
+ }
+
+ if (busno >= MAX_NO_BUSSES || !busses[busno].bush || i2caddr >= 1 << 10) {
+ errno = EINVAL;
+ return -RTEMS_INVALID_NUMBER;
+ }
+
+ if (drvtbl->size < sizeof (*drvtbl)) {
+ fprintf (stderr, DRVNM " drv-ops size too small -- misconfiguration?\n");
+ return -RTEMS_NOT_CONFIGURED;
+ }
+
+ /* allocate slot */
+ LIBLOCK ();
+ for (i = 0; i < MAX_NO_DRIVERS; i++) {
+ /* driver # 0 is special, it is the built-in raw driver */
+ if (!drvs[i].drv) {
+ char *str;
+ dev_t dev;
+ uint32_t mode;
+
+ /* found a free slot; encode slot + 1 ! */
+ minor = ((i + 1) << 13) | RTEMS_LIBI2C_MAKE_MINOR (busno, i2caddr);
+
+ if (name) {
+ str = malloc (strlen (busses[busno].name) + strlen (name) + 2);
+ sprintf (str, "%s.%s", busses[busno].name, name);
+
+ dev = rtems_filesystem_make_dev_t (rtems_libi2c_major, minor);
+
+ mode = 0111 | S_IFCHR;
+ if (drvtbl->ops->read_entry)
+ mode |= 0444;
+ if (drvtbl->ops->write_entry)
+ mode |= 0222;
+
+ /* note that 'umask' is applied to 'mode' */
+ if (mknod (str, mode, dev)) {
+ fprintf (stderr,
+ "Creating device node failed: %s; you can try to do it manually...\n",
+ strerror (errno));
+ }
+
+ free (str);
+ }
+
+ drvs[i].drv = drvtbl;
+
+ if (drvtbl->ops->initialization_entry)
+ err =
+ drvs[i].drv->ops->initialization_entry (rtems_libi2c_major, minor,
+ 0);
+ else
+ err = RTEMS_SUCCESSFUL;
+
+ LIBUNLOCK ();
+ return err ? -err : minor;
+ }
+ }
+ LIBUNLOCK ();
+ return -RTEMS_TOO_MANY;
+}
diff --git a/cpukit/libi2c/libi2c.h b/cpukit/libi2c/libi2c.h
new file mode 100644
index 0000000000..1ef7f8b547
--- /dev/null
+++ b/cpukit/libi2c/libi2c.h
@@ -0,0 +1,234 @@
+#ifndef RTEMS_LIBI2C_H
+#define RTEMS_LIBI2C_H
+/*$Id$*/
+#include <rtems.h>
+
+#include <rtems/io.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple I2C driver API */
+
+/* Initialize the libary - may fail if no semaphore or no driver slot is available */
+int rtems_libi2c_initialize ();
+
+/* Bus Driver API
+ *
+ * Bus drivers provide access to low-level i2c functions
+ * such as 'send start', 'send address', 'get bytes' etc.
+ */
+
+/* first field must be a pointer to ops; driver
+ * may add its own fields after this.
+ * the struct that is registered with the library
+ * is not copied; a pointer will we passed
+ * to the callback functions (ops).
+ */
+typedef struct rtems_libi2c_bus_t_
+{
+ struct rtems_libi2c_bus_ops_ *ops;
+ int size; /* size of whole structure */
+} rtems_libi2c_bus_t;
+
+/* Access functions a low level driver must provide;
+ *
+ * All of these, except read_bytes and write_bytes
+ * return RTEMS_SUCCESSFUL on success and an error status
+ * otherwise. The read and write ops return the number
+ * of chars read/written or -(status code) on error.
+ */
+typedef struct rtems_libi2c_bus_ops_
+{
+ /* Initialize the bus; might be called again to reset the bus driver */
+ rtems_status_code (*init) (rtems_libi2c_bus_t * bushdl);
+ /* Send start condition */
+ rtems_status_code (*send_start) (rtems_libi2c_bus_t * bushdl);
+ /* Send stop condition */
+ rtems_status_code (*send_stop) (rtems_libi2c_bus_t * bushdl);
+ /* initiate transfer from (rw!=0) or to a device */
+ rtems_status_code (*send_addr) (rtems_libi2c_bus_t * bushdl,
+ uint32_t addr, int rw);
+ /* read a number of bytes */
+ int (*read_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
+ int nbytes);
+ /* write a number of bytes */
+ int (*write_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
+ int nbytes);
+} rtems_libi2c_bus_ops_t;
+
+
+/*
+ * Register a lowlevel driver
+ *
+ * TODO: better description
+ *
+ * This allocates a major number identifying *this* driver
+ * (i.e., libi2c) and the minor number encodes a bus# and a i2c address.
+ *
+ * The name will be registered in the filesystem (parent
+ * directories must exist). It may be NULL in which case
+ * the library will pick a default.
+ *
+ * RETURNS: bus # (>=0) or -1 on error (errno set).
+ */
+
+int rtems_libi2c_register_bus (char *name, rtems_libi2c_bus_t * bus);
+
+extern rtems_device_major_number rtems_libi2c_major;
+
+#define RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr) \
+ ((((busno)&((1<<3)-1))<<10) | ((i2caddr)&((1<<10)-1)))
+
+/* After the library is initialized, a major number is available.
+ * As soon as a low-level bus driver is registered (above routine
+ * returns a 'busno'), a device node can be created in the filesystem
+ * with a major/minor number pair of
+ *
+ * rtems_libi2c_major / RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr)
+ *
+ * and a 'raw' hi-level driver is then attached to this device
+ * node.
+ * This 'raw' driver has very simple semantics:
+ *
+ * 'open' sends a start condition
+ * 'read'/'write' address the device identified by the i2c bus# and address
+ * encoded in the minor number and read or write, respectively
+ * a stream of bytes from or to the device. Every time the
+ * direction is changed, a 're-start' condition followed by
+ * an 'address' cycle is generated on the i2c bus.
+ * 'close' sends a stop condition.
+ *
+ * Hence, using the 'raw' driver, e.g., 100 bytes at offset 0x200 can be
+ * read from an EEPROM by the following pseudo-code:
+ *
+ * mknod("/dev/i2c-54", mode, MKDEV(rtems_libi2c_major, RTEMS_LIBI2C_MAKE_MINOR(0,0x54)))
+ *
+ * int fd;
+ * char off[2]={0x02,0x00};
+ *
+ * fd = open("/dev/i2c-54",O_RDWR);
+ * write(fd,off,2);
+ * read(fd,buf,100);
+ * close(fd);
+ *
+ */
+
+/* Higher Level Driver API
+ *
+ * Higher level drivers know how to deal with specific i2c
+ * devices (independent of the bus interface chip) and provide
+ * an abstraction, i.e., the usual read/write/ioctl access.
+ *
+ * Using the above example, such a high level driver could
+ * prevent the user from issuing potentially destructive write
+ * operations (the aforementioned EEPROM interprets any 3rd
+ * and following byte written to the device as data, i.e., the
+ * contents could easily be changed!).
+ * The correct 'read-pointer offset' programming could be
+ * implemented in 'open' and 'ioctl' of a high-level driver and
+ * the user would then only have to perform harmless read
+ * operations, e.g.,
+ *
+ * fd = open("/dev/i2c.eeprom",O_RDONLY) / * opens and sets EEPROM read pointer * /
+ * ioctl(fd, IOCTL_SEEK, 0x200) / * repositions the read pointer * /
+ * read(fd, buf, 100)
+ * close(fd)
+ *
+ */
+
+/* struct provided at driver registration. The driver may store
+ * private data behind the mandatory first fields but the size
+ * must be set to the size of the entire struct, e.g.,
+ *
+ * struct driver_pvt {
+ * rtems_libi2c_drv_t pub;
+ * struct { ... } pvt;
+ * } my_driver = {
+ * { ops: my_ops,
+ * size: sizeof(my_driver)
+ * },
+ * { ...};
+ * };
+ *
+ * A pointer to this struct is passed to the callback ops.
+ */
+
+typedef struct rtems_libi2c_drv_t_
+{
+ rtems_driver_address_table *ops; /* the driver ops */
+ int size; /* size of whole structure (including appended private data) */
+} rtems_libi2c_drv_t;
+
+/*
+ * The high level driver must be registered with a particular
+ * bus number and i2c address.
+ *
+ * The registration procedure also creates a filesystem node,
+ * i.e., the returned minor number is not really needed.
+ *
+ * If the 'name' argument is NULL, no filesystem node is
+ * created (but this can be done 'manually' using rtems_libi2c_major
+ * and the return value of this routine).
+ *
+ * RETURNS minor number (FYI) or -1 on failure
+ */
+int
+rtems_libi2c_register_drv (char *name, rtems_libi2c_drv_t * drvtbl,
+ unsigned bus, unsigned i2caddr);
+
+/* Operations available to high level drivers */
+
+/* NOTES: The bus a device is attached to is LOCKED from the first send_start
+ * until send_stop is executed!
+ *
+ * Bus tenure MUST NOT span multiple system calls - otherwise, a single
+ * thread could get into the protected sections (or would deadlock if the
+ * mutex was not nestable).
+ * E.g., consider what happens if 'open' sends a 'start' and 'close'
+ * sends a 'stop' (i.e., the bus mutex would be locked in 'open' and
+ * released in 'close'. A single thread could try to open two devices
+ * on the same bus and would either deadlock or nest into the bus mutex
+ * and potentially mess up the i2c messages.
+ *
+ * The correct way is to *always* relinquish the i2c bus (i.e., send 'stop'
+ * from any driver routine prior to returning control to the caller.
+ * Consult the implementation of the generic driver routines (open, close, ...)
+ * below or the examples in i2c-2b-eeprom.c and i2c-2b-ds1621.c
+ *
+ * Drivers just pass the minor number on to these routines...
+ */
+rtems_status_code rtems_libi2c_send_start (rtems_device_minor_number minor);
+
+rtems_status_code rtems_libi2c_send_stop (rtems_device_minor_number minor);
+
+rtems_status_code
+rtems_libi2c_send_addr (rtems_device_minor_number minor, int rw);
+
+/* the read/write routines return the number of bytes transferred
+ * or -(status_code) on error.
+ */
+int
+rtems_libi2c_read_bytes (rtems_device_minor_number minor,
+ unsigned char *bytes, int nbytes);
+
+int
+rtems_libi2c_write_bytes (rtems_device_minor_number minor,
+ unsigned char *bytes, int nbytes);
+
+/* Send start, send address and read bytes */
+int
+rtems_libi2c_start_read_bytes (uint32_t minor, unsigned char *bytes,
+ int nbytes);
+
+/* Send start, send address and write bytes */
+int
+rtems_libi2c_start_write_bytes (uint32_t minor, unsigned char *bytes,
+ int nbytes);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libmisc/.cvsignore b/cpukit/libmisc/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/libmisc/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/libmisc/Makefile.am b/cpukit/libmisc/Makefile.am
new file mode 100644
index 0000000000..630102c1fa
--- /dev/null
+++ b/cpukit/libmisc/Makefile.am
@@ -0,0 +1,103 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+EXTRA_DIST = README
+
+noinst_LIBRARIES =
+
+## capture
+EXTRA_DIST += capture/README
+
+noinst_LIBRARIES += libcapture.a
+libcapture_a_SOURCES = capture/capture.c capture/capture-cli.c \
+ capture/capture.h capture/capture-cli.h
+
+## cpuuse
+EXTRA_DIST += cpuuse/README
+
+noinst_LIBRARIES += libcpuuse.a
+libcpuuse_a_SOURCES = cpuuse/cpuuse.c cpuuse/cpuuse.h
+
+## devnull
+
+noinst_LIBRARIES += libdevnull.a
+libdevnull_a_SOURCES = devnull/devnull.c devnull/devnull.h
+
+## dummy
+EXTRA_DIST += dummy/README
+
+noinst_LIBRARIES += libdummy.a
+libdummy_a_SOURCES = dummy/dummy.c
+
+## dumpbuf
+noinst_LIBRARIES += libdumpbuf.a
+libdumpbuf_a_SOURCES = dumpbuf/dumpbuf.c dumpbuf/dumpbuf.h
+
+## monitor
+noinst_LIBRARIES += libmonitor.a
+libmonitor_a_SOURCES = monitor/mon-command.c monitor/mon-symbols.c \
+ monitor/mon-prmisc.c monitor/mon-monitor.c monitor/mon-object.c \
+ monitor/mon-server.c monitor/mon-task.c monitor/mon-queue.c \
+ monitor/mon-driver.c monitor/mon-dname.c monitor/mon-itask.c \
+ monitor/mon-extension.c monitor/mon-manager.c monitor/mon-config.c \
+ monitor/symbols.h monitor/monitor.h
+if HAS_MP
+libmonitor_a_SOURCES += monitor/mon-mpci.c
+endif
+
+EXTRA_DIST += monitor/README
+
+## mw-fb
+noinst_LIBRARIES += libmw-fb.a
+libmw_fb_a_SOURCES = mw-fb/mw_fb.c mw-fb/mw_uid.c mw-fb/mw_fb.h \
+ mw-fb/mw_uid.h
+
+## shell
+
+if LIBSHELL
+noinst_LIBRARIES += libshell.a
+libshell_a_SOURCES = shell/cmds.c shell/shell.c shell/shell.h
+endif
+
+EXTRA_DIST += shell/README
+
+## rtmonuse
+noinst_LIBRARIES += librtmonuse.a
+librtmonuse_a_SOURCES = rtmonuse/rtmonuse.c rtmonuse/rtmonuse.h
+
+## serdbg
+
+if LIBSERDBG
+noinst_LIBRARIES += libserdbg.a
+libserdbg_a_SOURCES = serdbg/serdbg.c serdbg/serdbgio.c \
+ serdbg/termios_printk.c serdbg/serdbgcnf.h serdbg/serdbg.h \
+ serdbg/termios_printk_cnf.h serdbg/termios_printk.h
+endif
+
+EXTRA_DIST += serdbg/README
+
+## stackchk
+noinst_LIBRARIES += libstackchk.a
+libstackchk_a_SOURCES = stackchk/check.c stackchk/internal.h \
+ stackchk/stackchk.h
+
+EXTRA_DIST += stackchk/README
+
+## libuntar
+noinst_LIBRARIES += libuntar.a
+libuntar_a_SOURCES = untar/untar.c untar/untar.h
+
+EXTRA_DIST += untar/README
+
+## fsmount
+noinst_LIBRARIES += libfsmount.a
+libfsmount_a_SOURCES = fsmount/fsmount.c fsmount/fsmount.h
+
+EXTRA_DIST += fsmount/README
+
+## ---
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/libmisc/README b/cpukit/libmisc/README
new file mode 100644
index 0000000000..bbde4feeae
--- /dev/null
+++ b/cpukit/libmisc/README
@@ -0,0 +1,23 @@
+#
+# $Id$
+#
+
+This directory contains for the "miscellaneous" library. Currently
+this library contains a number of useful support libraries:
+
+ + Task Stack Overflow Checker
+ + Workspace Consistency Checker
+ + Task Execution Time Monitor
+ + Period Statistics Monitor
+ + Debug Monitor
+
+The following ideas have been mentioned for items which could go
+in this library, but this list is not all inclusive:
+
+ + there are no outstanding suggestions.
+
+The intent of this library is to provide a home for useful utility routines
+which are dependent upon RTEMS.
+
+--joel
+16 Sept 97
diff --git a/cpukit/libmisc/capture/README b/cpukit/libmisc/capture/README
new file mode 100644
index 0000000000..2ea76a4cfe
--- /dev/null
+++ b/cpukit/libmisc/capture/README
@@ -0,0 +1,255 @@
+#
+# $Id$
+#
+
+ RTEMS Performance Monitoring and Measurement Framework
+
+ Copyright 2002 Chris Johns (ccj@acm.org)
+ 23 April 2002
+
+This directory contains the source code for the performance monitoring and
+measurement framework. It is more commonly know as the capture engine.
+
+The capture engine is in an early phase of development. Please review the Status
+section of this document for the current status.
+
+Performance.
+
+The capture engine is designed to not effect the system it is
+monitoring. Resources such as memory are used as well as a small performance
+hit in task creation, deletion and context switch. The overhead is small and
+will not be noticed unless the system is operating close to the performance
+limit of the target.
+
+Structure.
+
+The capture engine is implemented in a couple of layers. This lowest layer is
+the capture engine. Its interface is in the file 'capture.h'. Typically this
+interface is directly used unless you are implementing a target interface. The
+user interface is via a target interface.
+
+Command Line Interface (CLI).
+
+This is a target interface that provides a number of user commands via the
+RTEMS monitor. To use you need to provide the following in your
+application initialisation:
+
+ #include <rtems/monitor.h>
+ #include <rtems/capture-cli.h>
+
+ rtems_monitor_init (0);
+ rtems_capture_cli_init (0);
+
+Check the file capture-cli.h for documentation of the interface. The parameter
+is a pointer to your board support package's time stamp handler. The time stamp
+handler is yet to be tested so it is recommended this is left as 0, unless you
+wish to test this part of the engine.
+
+The commands are:
+
+ copen - Open the capture engine.
+ cclose - Close the capture engine.
+ cenable - Enable the capture engine.
+ cdisable - Disable the capture engine.
+ ctlist - List the tasks known to the capture engine.
+ ctload - Display the current load (sort of top).
+ cwlist - List the watch and trigger controls.
+ cwadd - Add a watch.
+ cwdel - Delete a watch.
+ cwctl - Enable or disable a watch.
+ cwglob - Enable or disable the global watch.
+ cwceil - Set the watch ceiling.
+ cwfloor - Set the watch floor.
+ ctrace - Dump the trace records.
+ ctrig - Define a trigger.
+
+Open
+
+ usage: copen [-i] size
+
+Open the capture engine. The size parameter is the size of the capture engine
+trace buffer. A single record hold a single event, for example a task create or
+a context in or out. The option '-i' will enable the capture engine after it is
+opened.
+
+Close
+
+ usage: cclose
+
+Close the capture engine and release all resources held by the capture engine.
+
+Enable
+
+ usage: cenable
+
+Enable the capture engine if it has been opened.
+
+Disable
+
+ usage: cdisable
+
+Disable the capture engine. The enable and disable commands provide a means of
+removing the overhead of the capture engine from the context switch. This may
+be needed when testing if it is felt the capture engines overhead is effecting
+the system.
+
+Task List
+
+ usage: ctlist
+
+List the tasks the capture engine knows about. This may contain tasks that have
+been deleted.
+
+Task Load
+
+ usage: ctload
+
+List the tasks in the order of load in a similar way top does on Unix. The
+command sends ANSI terminal codes. You press enter to stop the update. The
+update period is fixed at 5 seconds. The output looks like:
+
+ Press ENTER to exit.
+
+ PID NAME RPRI CPRI STATE %CPU %STK FLGS EXEC TIME
+04010001 IDLE 255 255 READY 96.012% 0% a-----g 1
+08010009 CPlt 1 1 READY 3.815% 15% a------ 0
+08010003 ntwk 20 20 Wevnt 0.072% 0% at----g 0
+08010004 CSr0 20 20 Wevnt 0.041% 0% at----g 0
+08010001 main 250 250 DELAY 0.041% 0% a-----g 0
+08010008 test 100 100 Wevnt 0.000% 20% at-T-+g 0
+08010007 test 100 100 Wevnt 0.000% 0% at-T-+g 0
+08010005 CSt0 20 20 Wevnt 0.000% 0% at----g 0
+08010006 RMON 1 1 Wsem 0.000% 0% a------ 0
+
+There are 7 flags and from left to right are:
+
+1) 'a' the task is active, and 'd' the task has been deleted.
+2) 't' the task has been traced.
+3) 'F' the task has a from (TO_ANY) trigger.
+4) 'T' the task has a to (FROM_ANY) trigger.
+5) 'E' the task has an edge (FROM_TO) trigger.
+6) '+' the task as a watch control attached, 'w' a watch is enabled.
+7) 'g' the task is part of a global trigger.
+
+The %STK is the percentage of stack used by a task. Currently only tasks
+created while the capture engine is enabled can be monitored.
+
+The RPRI is the real priority. This is the priority set for the task. The
+current priority is the executing priority that may reflect a level set as a
+result of priority inversion.
+
+Watch List
+
+ usage: cwlist
+
+This command lists the watch and trigger controls the capture engine has. A
+control is a structure used by the capture engine to determine if a task is
+watched or triggers capturing.
+
+Watch Add
+
+ usage: cwadd [task name] [id]
+
+Add a watch for a task. You can provide a name or id or both. A name will cause
+all tasks with that name to have the watch added. An id results in a watch
+being for a specific task.
+
+Using a name is useful when the task is not yet created.
+
+Watch Delete
+
+ usage: cwdel [task name] [id]
+
+Delete a watch that has been added.
+
+Watch Control
+
+ usage: cwctl [task name] [id] on/off
+
+Enable or disable a watch. The name and id parameters are the same as the watch
+add command.
+
+Global Watch
+
+ usage: cwglob on/off
+
+Enable or disable the global watch. A global watch is an easy way to enable
+watches for all tasks with real priorities between the watch ceiling and floor
+priorities.
+
+Watch Priority Ceiling
+
+ usage: cwceil priority
+
+Set the watch priority ceiling. All tasks with a priority less than the ceiling
+priority are not watched. This allow you to ignore high priority system and
+driver tasks.
+
+Watch Priority Floor
+
+ usage: cwfloor priority
+
+Set the watch priority floor. All tasks with a priority greater than the floor
+priority level are not watched. This allows you to remove tasks such as IDLE
+from being monitored.
+
+Trace
+
+ usage: ctrace [-c] [-r records]
+
+Dump the trace record. The option '-c' will output the records in comma
+separated variables (CSV). The '-r' option controls the number of records
+dumped. This can help stop the command looping for-ever.
+
+Trigger
+
+ usage: ctrig type [from name] [from id] [to name] [to id]
+
+Set a trigger. The types of triggers are :
+
+ from : trigger on a context switch from a task
+ to : trigger on a context switch to a task
+ edge : trigger on a context switch from a task to a task
+
+The from and to trigger types requires a task name or task id or both be
+provided. The edge requires a from name and/or id and a to name and/or id be
+provided.
+
+Flush
+
+ usage: cflush [-n]
+
+Flush the trace record. The option '-n' stops the capture engine be
+primed. This means an exising trigger state will not be cleared and tracing
+will continue.
+
+Status.
+
+The following is a list of outstanding issues or bugs.
+
+1) The capture engine does not scan the existing list of tasks in the kernel
+ when initialised. This means tasks that exist but are not active are not
+ seen. Not sure how to implement this one.
+
+2) The blocking read of trace records has not been completely implemented or
+ tested. This will wait until I complete the csv support for the cli for a
+ serial UI or the tcp server is implemented.
+
+3) Task control block clean up is not implemented. The control block should be
+ dumped to the trace buffer. This requires extended record formats. This can
+ be implemented using an event flag to indicate an extended record follows
+ the trace record. This would allow a task delete record to be directly
+ followed by the task information.
+
+4) Complete csv (comma separated variable) support for the CLI.
+
+5) Implement a tcp server interface.
+
+6) Complete the capture engine API documentation.
+
+7) Test the user supplied time stamp handler.
+
+8) Task name support is only for the rtems_name type. This means the only the
+ classic API tasks are currently supported. Partial support for the different
+ task names is provided how-ever this is not clean and does not support the
+ variable length task name such as found in the POSIX tasks.
diff --git a/cpukit/libmisc/capture/capture-cli.c b/cpukit/libmisc/capture/capture-cli.c
new file mode 100644
index 0000000000..3ef000c403
--- /dev/null
+++ b/cpukit/libmisc/capture/capture-cli.c
@@ -0,0 +1,1474 @@
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Objective Design Systems Pty Ltd, 2002
+ All rights reserved Objective Design Systems Pty Ltd, 2002
+ Chris Johns (ccj@acm.org)
+
+ COPYRIGHT (c) 1989-1998.
+ On-Line Applications Research Corporation (OAR).
+
+ The license and distribution terms for this file may be
+ found in the file LICENSE in this distribution.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ RTEMS Performance Monitoring and Measurement Framework.
+
+ This is the Target Interface Command Line Interface. You need
+ start the RTEMS monitor.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <rtems.h>
+#include <rtems/capture-cli.h>
+#include <rtems/monitor.h>
+
+#define RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS (32)
+
+/*
+ * The user capture timestamper.
+ */
+static rtems_capture_timestamp capture_timestamp;
+
+/*
+ * Common variable to sync the load monitor task.
+ */
+static volatile int cli_load_thread_active;
+
+/*
+ * rtems_capture_cli_open
+ *
+ * DESCRIPTION:
+ *
+ * This function opens the capture engine. We need the size of the
+ * capture buffer.
+ *
+ */
+
+static const char* open_usage = "usage: copen [-i] size\n";
+
+static void
+rtems_capture_cli_open (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ uint32_t size = 0;
+ rtems_boolean enable = 0;
+ rtems_status_code sc;
+ int arg;
+
+ if (argc <= 1)
+ {
+ fprintf(stdout,open_usage);
+ return;
+ }
+
+ for (arg = 1; arg < argc; arg++)
+ {
+ if (argv[arg][0] == '-')
+ {
+ if (argv[arg][1] == 'i')
+ enable = 1;
+ else
+ fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ }
+ else
+ {
+ size = strtoul (argv[arg], 0, 0);
+
+ if (size < 100)
+ {
+ fprintf(stdout,"error: size must be greater than or equal to 100\n");
+ return;
+ }
+ }
+ }
+
+ sc = rtems_capture_open (size, capture_timestamp);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: open failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"capture engine opened.\n");
+
+ if (!enable)
+ return;
+
+ sc = rtems_capture_control (enable);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: open enable failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"capture engine enabled.\n");
+}
+
+/*
+ * rtems_capture_cli_close
+ *
+ * DESCRIPTION:
+ *
+ * This function closes the capture engine.
+ *
+ */
+
+static void
+rtems_capture_cli_close (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+
+ sc = rtems_capture_close ();
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: close failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"capture engine closed.\n");
+}
+
+/*
+ * rtems_capture_cli_enable
+ *
+ * DESCRIPTION:
+ *
+ * This function enables the capture engine.
+ *
+ */
+
+static void
+rtems_capture_cli_enable (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+
+ sc = rtems_capture_control (1);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: enable failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"capture engine enabled.\n");
+}
+
+/*
+ * rtems_capture_cli_disable
+ *
+ * DESCRIPTION:
+ *
+ * This function disables the capture engine.
+ *
+ */
+
+static void
+rtems_capture_cli_disable (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+
+ sc = rtems_capture_control (0);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: disable failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"capture engine disabled.\n");
+}
+
+/*
+ * rtems_capture_cli_task_list
+ *
+ * DESCRIPTION:
+ *
+ * This function lists the tasks the capture engine knows about.
+ *
+ */
+
+static void
+rtems_capture_cli_task_list (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_task_priority ceiling = rtems_capture_watch_get_ceiling ();
+ rtems_task_priority floor = rtems_capture_watch_get_floor ();
+ rtems_capture_task_t* task = rtems_capture_get_task_list ();
+ uint32_t ticks;
+ uint32_t tick_offset;
+ unsigned long long total_time;
+ int count = rtems_capture_task_count ();
+
+ if (capture_timestamp)
+ capture_timestamp (&ticks, &tick_offset);
+ else
+ {
+ ticks = _Watchdog_Ticks_since_boot;
+ tick_offset = 0;
+ }
+
+ total_time = (ticks * rtems_capture_task_time (task)) + tick_offset;
+
+ fprintf(stdout,"total %i\n", count);
+
+ while (task)
+ {
+ rtems_task_priority priority;
+ int stack_used;
+ int time_used;
+
+ stack_used = rtems_capture_task_stack_usage (task) * 100;
+ stack_used /= rtems_capture_task_stack_size (task);
+
+ if (stack_used > 100)
+ stack_used = 100;
+
+ time_used = (rtems_capture_task_time (task) * 100) / total_time;
+
+ if (time_used > 100)
+ time_used = 100;
+
+ priority = rtems_capture_task_real_priority (task);
+
+ fprintf(stdout," ");
+ rtems_monitor_dump_id (rtems_capture_task_id (task));
+ fprintf(stdout," ");
+ rtems_monitor_dump_name (rtems_capture_task_name (task));
+ fprintf(stdout," ");
+ rtems_monitor_dump_priority (rtems_capture_task_start_priority (task));
+ fprintf(stdout," ");
+ rtems_monitor_dump_priority (rtems_capture_task_real_priority (task));
+ fprintf(stdout," ");
+ rtems_monitor_dump_priority (rtems_capture_task_curr_priority (task));
+ fprintf(stdout," ");
+ rtems_monitor_dump_state (rtems_capture_task_state (task));
+ fprintf(stdout," %c%c%c%c%c",
+ rtems_capture_task_valid (task) ? 'a' : 'd',
+ rtems_capture_task_flags (task) & RTEMS_CAPTURE_TRACED ? 't' : '-',
+ rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_TO_ANY ? 'F' : '-',
+ rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_FROM_ANY ? 'T' : '-',
+ rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_FROM_TO ? 'E' : '-');
+ if ((floor > ceiling) && (ceiling > priority))
+ fprintf(stdout,"--");
+ else
+ fprintf(stdout,"%c%c",
+ rtems_capture_task_control (task) ?
+ (rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_WATCH ? 'w' : '+') : '-',
+ rtems_capture_watch_global_on () ? 'g' : '-');
+ fprintf(stdout," %3i%% %3i%% (%i)\n",
+ stack_used, time_used, rtems_capture_task_ticks (task));
+
+ task = rtems_capture_next_task (task);
+ }
+}
+
+/*
+ * rtems_capture_cli_task_load_thread
+ *
+ * DESCRIPTION:
+ *
+ * This function displays the load of the tasks on an ANSI terminal.
+ *
+ */
+
+static void
+rtems_capture_cli_task_load_thread (rtems_task_argument arg)
+{
+ rtems_task_priority ceiling = rtems_capture_watch_get_ceiling ();
+ rtems_task_priority floor = rtems_capture_watch_get_floor ();
+ int last_count = 0;
+
+ fprintf(stdout,"\x1b[2J Press ENTER to exit.\n\n");
+ fprintf(stdout," PID NAME RPRI CPRI STATE %%CPU %%STK FLGS EXEC TIME\n");
+
+ for (;;)
+ {
+ rtems_capture_task_t* tasks[RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS + 1];
+ unsigned long long load[RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS + 1];
+ rtems_capture_task_t* task;
+ unsigned long long total_time;
+ int count = 0;
+ int i;
+ int j;
+
+ cli_load_thread_active = 1;
+
+ /*
+ * Iterate over the tasks and sort the highest load tasks
+ * into our local arrays. We only handle a limited number of
+ * tasks.
+ */
+
+ memset (tasks, 0, sizeof (tasks));
+ memset (load, 0, sizeof (load));
+
+ task = rtems_capture_get_task_list ();
+
+ while (task)
+ {
+ if (rtems_capture_task_valid (task))
+ {
+ unsigned long long l = rtems_capture_task_delta_time (task);
+
+ count++;
+
+ for (i = 0; i < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS; i++)
+ {
+ if (tasks[i])
+ {
+ if ((l == 0) || (l < load[i]))
+ continue;
+
+ for (j = (RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS - 1); j >= i; j--)
+ {
+ tasks[j + 1] = tasks[j];
+ load[j + 1] = load[j];
+ }
+ }
+
+ tasks[i] = task;
+ load[i] = l;
+ break;
+ }
+ }
+ task = rtems_capture_next_task (task);
+ }
+
+ fprintf(stdout,"\x1b[4;0H");
+
+ total_time = 0;
+
+ for (i = 0; i < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS; i++)
+ total_time += load[i];
+
+ if (count > last_count)
+ j = count;
+ else
+ j = last_count;
+
+ for (i = 0; i < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS; i++)
+ {
+ rtems_task_priority priority;
+ int stack_used;
+ int task_load;
+ int k;
+
+ if (!tasks[i])
+ break;
+
+ j--;
+
+ stack_used = rtems_capture_task_stack_usage (tasks[i]) * 100;
+ stack_used /= rtems_capture_task_stack_size (tasks[i]);
+
+ if (stack_used > 100)
+ stack_used = 100;
+
+ task_load = (int) ((load[i] * 100000) / total_time);
+
+ priority = rtems_capture_task_real_priority (tasks[i]);
+
+ fprintf(stdout,"\x1b[K");
+ rtems_monitor_dump_id (rtems_capture_task_id (tasks[i]));
+ fprintf(stdout," ");
+ rtems_monitor_dump_name (rtems_capture_task_name (tasks[i]));
+ fprintf(stdout," ");
+ rtems_monitor_dump_priority (priority);
+ fprintf(stdout," ");
+ rtems_monitor_dump_priority (rtems_capture_task_curr_priority (tasks[i]));
+ fprintf(stdout," ");
+ k = rtems_monitor_dump_state (rtems_capture_task_state (tasks[i]));
+ fprintf(stdout,"%*c %3i.%03i%% ", 6 - k, ' ', task_load / 1000, task_load % 1000);
+ fprintf(stdout,"%3i%% %c%c%c%c%c", stack_used,
+ rtems_capture_task_valid (tasks[i]) ? 'a' : 'd',
+ rtems_capture_task_flags (tasks[i]) & RTEMS_CAPTURE_TRACED ? 't' : '-',
+ rtems_capture_task_control_flags (tasks[i]) & RTEMS_CAPTURE_TO_ANY ? 'F' : '-',
+ rtems_capture_task_control_flags (tasks[i]) & RTEMS_CAPTURE_FROM_ANY ? 'T' : '-',
+ rtems_capture_task_control_flags (tasks[i]) & RTEMS_CAPTURE_FROM_TO ? 'E' : '-');
+ if ((floor > ceiling) && (ceiling > priority))
+ fprintf(stdout,"--");
+ else
+ fprintf(stdout,"%c%c",
+ rtems_capture_task_control (tasks[i]) ?
+ (rtems_capture_task_control_flags (tasks[i]) &
+ RTEMS_CAPTURE_WATCH ? 'w' : '+') : '-',
+ rtems_capture_watch_global_on () ? 'g' : '-');
+
+ fprintf(stdout," %qi\n", rtems_capture_task_time (tasks[i]));
+ }
+
+ if (count < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS)
+ {
+ j = RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS - count;
+ while (j > 0)
+ {
+ fprintf(stdout,"\x1b[K\n");
+ j--;
+ }
+ }
+
+ last_count = count;
+
+ cli_load_thread_active = 0;
+
+ rtems_task_wake_after (TOD_MICROSECONDS_TO_TICKS (5000000));
+ }
+}
+
+/*
+ * rtems_capture_cli_task_load
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command.
+ *
+ */
+
+static void
+rtems_capture_cli_task_load (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+ rtems_task_priority priority;
+ rtems_name name;
+ rtems_id id;
+
+ sc = rtems_task_set_priority (RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &priority);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: cannot obtain the current priority: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ memcpy (&name, "CPlt", 4);
+
+ sc = rtems_task_create (name, priority, 1024,
+ RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
+ RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR,
+ &id);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: cannot create helper thread: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ sc = rtems_task_start (id, rtems_capture_cli_task_load_thread, 0);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: cannot start helper thread: %s\n", rtems_status_text (sc));
+ rtems_task_delete (id);
+ return;
+ }
+
+ for (;;)
+ {
+ int c = getchar ();
+
+ if ((c == '\r') || (c == '\n'))
+ {
+ int loops = 20;
+
+ while (loops && cli_load_thread_active)
+ rtems_task_wake_after (TOD_MICROSECONDS_TO_TICKS (100000));
+
+ rtems_task_delete (id);
+
+ fprintf(stdout,"load monitoring stopped.\n");
+
+ return;
+ }
+ }
+}
+
+/*
+ * rtems_capture_cli_watch_list
+ *
+ * DESCRIPTION:
+ *
+ * This function lists the controls in the capture engine.
+ *
+ */
+
+static void
+rtems_capture_cli_watch_list (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_capture_control_t* control = rtems_capture_get_control_list ();
+ rtems_task_priority ceiling = rtems_capture_watch_get_ceiling ();
+ rtems_task_priority floor = rtems_capture_watch_get_floor ();
+
+ fprintf(stdout,"watch priority ceiling is %i\n", ceiling);
+ fprintf(stdout,"watch priority floor is %i\n", floor);
+ fprintf(stdout,"global watch is %s\n",
+ rtems_capture_watch_global_on () ? "enabled" : "disabled");
+ fprintf(stdout,"total %d\n", rtems_capture_control_count ());
+
+ while (control)
+ {
+ int f;
+ int fshowed;
+ int lf;
+
+ fprintf(stdout," ");
+ rtems_monitor_dump_id (rtems_capture_control_id (control));
+ fprintf(stdout," ");
+ rtems_monitor_dump_name (rtems_capture_control_name (control));
+ fprintf(stdout," %c%c%c%c%c",
+ rtems_capture_control_flags (control) & RTEMS_CAPTURE_WATCH ? 'w' : '-',
+ rtems_capture_watch_global_on () ? 'g' : '-',
+ rtems_capture_control_flags (control) & RTEMS_CAPTURE_TO_ANY ? 'F' : '-',
+ rtems_capture_control_flags (control) & RTEMS_CAPTURE_FROM_ANY ? 'T' : '-',
+ rtems_capture_control_flags (control) & RTEMS_CAPTURE_FROM_TO ? 'E' : '-');
+
+ for (f = 0, fshowed = 0, lf = 1; f < RTEMS_CAPTURE_TRIGGER_TASKS; f++)
+ {
+ if (lf && ((fshowed % 16) == 0))
+ {
+ fprintf(stdout,"\n");
+ lf = 0;
+ }
+
+ /*
+ * FIXME: name test.
+ */
+ if (rtems_capture_control_from_name (control, f))
+ {
+ fprintf(stdout," %2i:", f);
+ rtems_monitor_dump_name (rtems_capture_control_from_name (control, f));
+ fprintf(stdout,"/");
+ rtems_monitor_dump_id (rtems_capture_control_from_id (control, f));
+ fshowed++;
+ lf = 1;
+ }
+ }
+
+ if (lf)
+ fprintf(stdout,"\n");
+
+ control = rtems_capture_next_control (control);
+ }
+}
+
+/*
+ * rtems_capture_cli_get_name_id
+ *
+ * DESCRIPTION:
+ *
+ * This function checks arguments for a name or an id.
+ *
+ */
+
+static rtems_boolean
+rtems_capture_cli_get_name_id (char* arg,
+ rtems_boolean* valid_name,
+ rtems_boolean* valid_id,
+ rtems_name* name,
+ rtems_id* id)
+{
+ uint32_t objclass;
+ int l;
+ int i;
+
+ if (*valid_name && *valid_id)
+ {
+ fprintf(stdout,"error: too many arguments\n");
+ return 0;
+ }
+
+ /*
+ * See if the arg is all hex digits.
+ */
+
+ l = strlen (arg);
+
+ for (i = 0; i < l; i++)
+ if (!isxdigit (arg[i]))
+ break;
+
+ *id = strtoul (arg, 0, 16);
+
+ objclass = _Objects_Get_class (*id);
+
+ if ((i == l))
+ *valid_id = 1;
+ else
+ {
+ memcpy (name, arg, sizeof (rtems_name));
+ *valid_name = 1;
+ }
+
+ return 1;
+}
+
+/*
+ * rtems_capture_cli_watch_add
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command that add a watch to the capture
+ * engine.
+ *
+ */
+
+static char const * watch_add_usage = "usage: cwadd [task name] [id]\n";
+
+static void
+rtems_capture_cli_watch_add (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+ int arg;
+ rtems_name name = 0;
+ rtems_id id = 0;
+ rtems_boolean valid_name = 0;
+ rtems_boolean valid_id = 0;
+
+ if (argc <= 1)
+ {
+ fprintf(stdout,watch_add_usage);
+ return;
+ }
+
+ for (arg = 1; arg < argc; arg++)
+ {
+ if (argv[arg][0] == '-')
+ {
+ fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ }
+ else
+ {
+ if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id, &name, &id))
+ return;
+ }
+ }
+
+ if (!valid_name && !valid_id)
+ {
+ fprintf(stdout,"error: no valid name or task id located\n");
+ return;
+ }
+
+ sc = rtems_capture_watch_add (name, id);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: watch add failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"watch added.\n");
+}
+
+/*
+ * rtems_capture_cli_watch_del
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command that deletes a watch from the capture
+ * engine.
+ *
+ */
+
+static char const * watch_del_usage = "usage: cwdel [task name] [id]\n";
+
+static void
+rtems_capture_cli_watch_del (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+ int arg;
+ rtems_name name = 0;
+ rtems_id id = 0;
+ rtems_boolean valid_name = 0;
+ rtems_boolean valid_id = 0;
+
+ if (argc <= 1)
+ {
+ fprintf(stdout,watch_del_usage);
+ return;
+ }
+
+ for (arg = 1; arg < argc; arg++)
+ {
+ if (argv[arg][0] == '-')
+ {
+ fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ }
+ else
+ {
+ if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id, &name, &id))
+ return;
+ }
+ }
+
+ if (!valid_name && !valid_id)
+ {
+ fprintf(stdout,"error: no valid name or task id located\n");
+ return;
+ }
+
+ sc = rtems_capture_watch_del (name, id);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: watch delete failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"watch delete.\n");
+}
+
+/*
+ * rtems_capture_cli_watch_control
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command that controls a watch.
+ *
+ */
+
+static char const * watch_control_usage = "usage: cwctl [task name] [id] on/off\n";
+
+static void
+rtems_capture_cli_watch_control (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+ int arg;
+ rtems_name name = 0;
+ rtems_id id = 0;
+ rtems_boolean valid_name = 0;
+ rtems_boolean valid_id = 0;
+ rtems_boolean enable = 0;
+
+ if (argc <= 2)
+ {
+ fprintf(stdout,watch_control_usage);
+ return;
+ }
+
+ for (arg = 1; arg < argc; arg++)
+ {
+ if (argv[arg][0] == '-')
+ {
+ fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ }
+ else
+ {
+ if (strcmp (argv[arg], "on") == 0)
+ enable = 1;
+ else if (strcmp (argv[arg], "off") == 0)
+ enable = 0;
+ else if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id, &name, &id))
+ return;
+ }
+ }
+
+ if (!valid_name && !valid_id)
+ {
+ fprintf(stdout,"error: no valid name or task id located\n");
+ return;
+ }
+
+ sc = rtems_capture_watch_ctrl (name, id, enable);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: watch control failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"watch %s.\n", enable ? "enabled" : "disabled");
+}
+
+/*
+ * rtems_capture_cli_watch_global
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command that sets a global watch.
+ *
+ */
+
+static char const * watch_global_usage = "usage: cwglob on/off\n";
+
+static void
+rtems_capture_cli_watch_global (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+ int arg;
+ rtems_boolean enable = 0;
+
+ if (argc <= 1)
+ {
+ fprintf(stdout,watch_global_usage);
+ return;
+ }
+
+ for (arg = 1; arg < argc; arg++)
+ {
+ if (argv[arg][0] == '-')
+ {
+ fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ }
+ else
+ {
+ if (strcmp (argv[arg], "on") == 0)
+ enable = 1;
+ else if (strcmp (argv[arg], "off") == 0)
+ enable = 0;
+ }
+ }
+
+ sc = rtems_capture_watch_global (enable);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: global watch failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"global watch %s.\n", enable ? "enabled" : "disabled");
+}
+
+/*
+ * rtems_capture_cli_watch_ceiling
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command that sets watch ceiling.
+ *
+ */
+
+static char const * watch_ceiling_usage = "usage: cwceil priority\n";
+
+static void
+rtems_capture_cli_watch_ceiling (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+ int arg;
+ rtems_task_priority priority = 0;
+
+ if (argc <= 1)
+ {
+ fprintf(stdout,watch_ceiling_usage);
+ return;
+ }
+
+ for (arg = 1; arg < argc; arg++)
+ {
+ if (argv[arg][0] == '-')
+ {
+ fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ }
+ else
+ {
+ priority = strtoul (argv[arg], 0, 0);
+ }
+ }
+
+ sc = rtems_capture_watch_ceiling (priority);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: watch ceiling failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"watch ceiling is %i.\n", priority);
+}
+
+/*
+ * rtems_capture_cli_watch_floor
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command that sets watch floor.
+ *
+ */
+
+static char const * watch_floor_usage = "usage: cwfloor priority\n";
+
+static void
+rtems_capture_cli_watch_floor (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+ int arg;
+ rtems_task_priority priority = 0;
+
+ if (argc <= 1)
+ {
+ fprintf(stdout,watch_floor_usage);
+ return;
+ }
+
+ for (arg = 1; arg < argc; arg++)
+ {
+ if (argv[arg][0] == '-')
+ {
+ fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ }
+ else
+ {
+ priority = strtoul (argv[arg], 0, 0);
+ }
+ }
+
+ sc = rtems_capture_watch_floor (priority);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: watch floor failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"watch floor is %i.\n", priority);
+}
+
+/*
+ * rtems_capture_cli_trigger_set
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command that sets a trigger.
+ *
+ */
+
+static char const *trigger_set_usage = "usage: ctrig type [from] [fromid] [to] [to id]\n";
+
+static void
+rtems_capture_cli_trigger_set (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+ int arg;
+ rtems_capture_trigger_t trigger = rtems_capture_from_to;
+ rtems_boolean trigger_set = 0;
+ rtems_name name = 0;
+ rtems_id id = 0;
+ rtems_boolean valid_name = 0;
+ rtems_boolean valid_id = 0;
+ rtems_name from_name = 0;
+ rtems_id from_id = 0;
+ rtems_boolean from_valid_name = 0;
+ rtems_boolean from_valid_id = 0;
+ rtems_name to_name = 0;
+ rtems_id to_id = 0;
+ rtems_boolean to_valid_name = 0;
+ rtems_boolean to_valid_id = 0;
+
+ if (argc <= 2)
+ {
+ fprintf(stdout,trigger_set_usage);
+ return;
+ }
+
+ for (arg = 1; arg < argc; arg++)
+ {
+ if (argv[arg][0] == '-')
+ {
+ fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ }
+ else
+ {
+ if (!trigger_set)
+ {
+ if (strcmp (argv[arg], "from") == 0)
+ trigger = rtems_capture_to_any;
+ else if (strcmp (argv[arg], "to") == 0)
+ trigger = rtems_capture_from_any;
+ else if (strcmp (argv[arg], "edge") == 0)
+ trigger = rtems_capture_from_any;
+ else
+ {
+ fprintf(stdout,"error: the first argument is the trigger type (from/to/edge)\n");
+ return;
+ }
+ trigger_set = 1;
+ }
+ else
+ {
+ if (trigger == rtems_capture_to_any)
+ {
+ if (from_valid_name && from_valid_id)
+ fprintf(stdout,"warning: extra arguments ignored\n");
+ else if (!rtems_capture_cli_get_name_id (argv[arg], &from_valid_name, &from_valid_id,
+ &from_name, &from_id))
+ return;
+ }
+ else if (trigger == rtems_capture_from_any)
+ {
+ if (to_valid_name && to_valid_id)
+ fprintf(stdout,"warning: extra arguments ignored\n");
+ else if (!rtems_capture_cli_get_name_id (argv[arg], &to_valid_name, &to_valid_id,
+ &to_name, &to_id))
+ return;
+ }
+ else if (trigger == rtems_capture_from_to)
+ {
+ if (from_valid_name && from_valid_id && to_valid_name && to_valid_id)
+ fprintf(stdout,"warning: extra arguments ignored\n");
+ else
+ {
+ if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id,
+ &name, &id))
+ return;
+
+ if (valid_name)
+ {
+ if (!from_valid_name && !from_valid_id)
+ {
+ from_valid_name = 1;
+ from_name = name;
+ }
+ else if (to_valid_name)
+ fprintf(stdout,"warning: extra arguments ignored\n");
+ else
+ {
+ to_valid_name = 1;
+ to_name = name;
+ }
+ }
+ if (valid_id)
+ {
+ if (!from_valid_id && !to_valid_name)
+ {
+ from_valid_id = 1;
+ from_id = id;
+ }
+ else if (to_valid_id)
+ fprintf(stdout,"warning: extra arguments ignored\n");
+ else
+ {
+ to_valid_id = 1;
+ to_id = id;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ((trigger == rtems_capture_to_any) && !from_valid_name && !from_valid_id)
+ {
+ fprintf(stdout,"error: a from trigger need a to name or id\n");
+ return;
+ }
+
+ if ((trigger == rtems_capture_from_any) && !to_valid_name && !to_valid_id)
+ {
+ fprintf(stdout,"error: a to trigger need a from name or id\n");
+ return;
+ }
+
+ if ((trigger == rtems_capture_from_to) &&
+ ((!from_valid_name && !from_valid_id) || (!to_valid_name && !to_valid_id)))
+ {
+ fprintf(stdout,"error: an edge trigger need a from and to name or id\n");
+ return;
+ }
+
+ sc = rtems_capture_set_trigger (from_name, from_id, to_name, to_id, trigger);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: setting the trigger failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"trigger set.\n");
+}
+
+/*
+ * rtems_capture_cli_trace_records
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command that dumps trace records.
+ *
+ */
+
+static void
+rtems_capture_cli_trace_records (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+ rtems_boolean csv = 0;
+ static int dump_total = 32;
+ int total;
+ int count;
+ uint32_t read;
+ rtems_capture_record_t* rec;
+ int arg;
+
+ for (arg = 1; arg < argc; arg++)
+ {
+ if (argv[arg][0] == '-')
+ {
+ if (argv[arg][1] == 'c')
+ csv = 1;
+ else if (argv[arg][1] == 'r')
+ {
+ int i;
+ int l;
+
+ arg++;
+ if (arg == argc)
+ {
+ fprintf(stdout,"error: option -r requires number\n");
+ return;
+ }
+
+ l = strlen (argv[arg]);
+
+ for (i = 0; i < l; i++)
+ if (!isdigit (argv[arg][i]))
+ {
+ fprintf(stdout,"error: option -r requires number and currently it is not\n");
+ return;
+ }
+
+ dump_total = strtoul (argv[arg], 0, 0);
+ }
+ else
+ fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ }
+ }
+
+ total = dump_total;
+
+ while (total)
+ {
+ sc = rtems_capture_read (0, 0, &read, &rec);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: trace read failed: %s\n", rtems_status_text (sc));
+ rtems_capture_flush (0);
+ return;
+ }
+
+ if (read == 0)
+ break;
+
+ for (count = 0; count < read; count++, rec++)
+ {
+ if (csv)
+ fprintf(stdout,"%08x,%03d,%03d,%04x,%d,%d\n",
+ (uint32_t ) rec->task,
+ (rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff,
+ (rec->events >> RTEMS_CAPTURE_CURR_PRIORITY_EVENT) & 0xff,
+ (rec->events >> RTEMS_CAPTURE_EVENT_START),
+ rec->ticks, rec->tick_offset);
+ else
+ {
+ unsigned long long t;
+ uint32_t event;
+ int e;
+
+ event = rec->events >> RTEMS_CAPTURE_EVENT_START;
+
+ t = rec->ticks;
+ t *= rtems_capture_tick_time ();
+ t += rec->tick_offset;
+
+ for (e = RTEMS_CAPTURE_EVENT_START; e < RTEMS_CAPTURE_EVENT_END; e++)
+ {
+ if (event & 1)
+ {
+ fprintf(stdout,"%9li.%06li ", (unsigned long) (t / 1000000),
+ (unsigned long) (t % 1000000));
+ rtems_monitor_dump_id (rtems_capture_task_id (rec->task));
+ fprintf(stdout," ");
+ rtems_monitor_dump_name (rtems_capture_task_name (rec->task));
+ fprintf(stdout," %3i %3i %s\n",
+ (rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff,
+ (rec->events >> RTEMS_CAPTURE_CURR_PRIORITY_EVENT) & 0xff,
+ rtems_capture_event_text (e));
+ }
+ event >>= 1;
+ }
+ }
+ }
+
+ if (read < total)
+ total -= read;
+ else
+ total = 0;
+
+ rtems_capture_release (read);
+ }
+}
+
+/*
+ * rtems_capture_cli_flush
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command that flushes and primes the capture
+ * engine.
+ *
+ */
+
+static void
+rtems_capture_cli_flush (
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose )
+{
+ rtems_status_code sc;
+ rtems_boolean prime = 1;
+ int arg;
+
+ for (arg = 1; arg < argc; arg++)
+ {
+ if (argv[arg][0] == '-')
+ {
+ if (argv[arg][1] == 'n')
+ prime = 0;
+ else
+ fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ }
+ }
+
+ sc = rtems_capture_flush (prime);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ fprintf(stdout,"error: flush failed: %s\n", rtems_status_text (sc));
+ return;
+ }
+
+ fprintf(stdout,"trace buffer flushed and %s.\n", prime ? "primed" : "not primed");
+}
+
+static rtems_monitor_command_entry_t rtems_capture_cli_cmds[] =
+{
+ {
+ "copen",
+ "usage: copen [-i] size\n",
+ 0,
+ rtems_capture_cli_open,
+ { 0 },
+ 0
+ },
+ {
+ "cclose",
+ "usage: cclose\n",
+ 0,
+ rtems_capture_cli_close,
+ { 0 },
+ 0
+ },
+ {
+ "cenable",
+ "usage: cenable\n",
+ 0,
+ rtems_capture_cli_enable,
+ { 0 },
+ 0
+ },
+ {
+ "cdisable",
+ "usage: cdisable\n",
+ 0,
+ rtems_capture_cli_disable,
+ { 0 },
+ 0
+ },
+ {
+ "ctlist",
+ "usage: ctlist \n",
+ 0,
+ rtems_capture_cli_task_list,
+ { 0 },
+ 0
+ },
+ {
+ "ctload",
+ "usage: ctload \n",
+ 0,
+ rtems_capture_cli_task_load,
+ { 0 },
+ 0
+ },
+ {
+ "cwlist",
+ "usage: cwlist\n",
+ 0,
+ rtems_capture_cli_watch_list,
+ { 0 },
+ 0
+ },
+ {
+ "cwadd",
+ "usage: cwadd [task name] [id]\n",
+ 0,
+ rtems_capture_cli_watch_add,
+ { 0 },
+ 0
+ },
+ {
+ "cwdel",
+ "usage: cwdel [task name] [id]\n",
+ 0,
+ rtems_capture_cli_watch_del,
+ { 0 },
+ 0
+ },
+ {
+ "cwctl",
+ "usage: cwctl [task name] [id] on/off\n",
+ 0,
+ rtems_capture_cli_watch_control,
+ { 0 },
+ 0
+ },
+ {
+ "cwglob",
+ "usage: cwglob on/off\n",
+ 0,
+ rtems_capture_cli_watch_global,
+ { 0 },
+ 0
+ },
+ {
+ "cwceil",
+ "usage: cwceil priority\n",
+ 0,
+ rtems_capture_cli_watch_ceiling,
+ { 0 },
+ 0
+ },
+ {
+ "cwfloor",
+ "usage: cwfloor priority\n",
+ 0,
+ rtems_capture_cli_watch_floor,
+ { 0 },
+ 0
+ },
+ {
+ "ctrace",
+ "usage: ctrace [-c] [-r records]\n",
+ 0,
+ rtems_capture_cli_trace_records,
+ { 0 },
+ 0
+ },
+ {
+ "ctrig",
+ "usage: ctrig type [from name] [from id] [to name] [to id]\n",
+ 0,
+ rtems_capture_cli_trigger_set,
+ { 0 },
+ 0
+ },
+ {
+ "cflush",
+ "usage: cflush [-n]\n",
+ 0,
+ rtems_capture_cli_flush,
+ { 0 },
+ 0
+ }
+};
+
+/*
+ * rtems_capture_cli_init
+ *
+ * DESCRIPTION:
+ *
+ * This function initialises the command line interface to the capture
+ * engine.
+ *
+ */
+
+rtems_status_code
+rtems_capture_cli_init (rtems_capture_timestamp timestamp)
+{
+ int cmd;
+
+ capture_timestamp = timestamp;
+
+ for (cmd = 0;
+ cmd < sizeof (rtems_capture_cli_cmds) / sizeof (rtems_monitor_command_entry_t);
+ cmd++)
+ rtems_monitor_insert_cmd (&rtems_capture_cli_cmds[cmd]);
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/libmisc/capture/capture-cli.h b/cpukit/libmisc/capture/capture-cli.h
new file mode 100644
index 0000000000..99c4e2252c
--- /dev/null
+++ b/cpukit/libmisc/capture/capture-cli.h
@@ -0,0 +1,56 @@
+/**
+ * @file rtems/capture-cli.h
+ */
+
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Objective Design Systems Pty Ltd, 2002
+ All rights reserved Objective Design Systems Pty Ltd, 2002
+ Chris Johns (ccj@acm.org)
+
+ COPYRIGHT (c) 1989-1998.
+ On-Line Applications Research Corporation (OAR).
+
+ The license and distribution terms for this file may be
+ found in the file LICENSE in this distribution.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ RTEMS Performance Monitoring and Measurement Framework.
+
+ This is the Target Interface Command Line Interface. You need
+ start the RTEMS monitor.
+
+*/
+
+#ifndef __CAPTURE_CLI_H_
+#define __CAPTURE_CLI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/capture.h>
+
+/**
+ * rtems_capture_cli_init
+ *
+ * DESCRIPTION:
+ *
+ * This function initialises the command line interface to the capture
+ * engine.
+ *
+ */
+rtems_status_code
+rtems_capture_cli_init (rtems_capture_timestamp timestamp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
new file mode 100644
index 0000000000..3e571382f5
--- /dev/null
+++ b/cpukit/libmisc/capture/capture.c
@@ -0,0 +1,1586 @@
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Objective Design Systems Pty Ltd, 2002
+ All rights reserved Objective Design Systems Pty Ltd, 2002
+ Chris Johns (ccj@acm.org)
+
+ COPYRIGHT (c) 1989-1998.
+ On-Line Applications Research Corporation (OAR).
+
+ The license and distribution terms for this file may be
+ found in the file LICENSE in this distribution.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ RTEMS Performance Monitoring and Measurement Framework.
+
+ This is the Capture Engine component.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "capture.h"
+#include <rtems/score/states.inl>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/wkspace.inl>
+
+/*
+ * These events are always recorded and are not part of the
+ * watch filters.
+ */
+#define RTEMS_CAPTURE_RECORD_EVENTS (RTEMS_CAPTURE_CREATED_BY_EVENT | \
+ RTEMS_CAPTURE_CREATED_EVENT | \
+ RTEMS_CAPTURE_STARTED_BY_EVENT | \
+ RTEMS_CAPTURE_STARTED_EVENT | \
+ RTEMS_CAPTURE_RESTARTED_BY_EVENT | \
+ RTEMS_CAPTURE_RESTARTED_EVENT | \
+ RTEMS_CAPTURE_DELETED_BY_EVENT | \
+ RTEMS_CAPTURE_DELETED_EVENT | \
+ RTEMS_CAPTURE_BEGIN_EVENT | \
+ RTEMS_CAPTURE_EXITTED_EVENT)
+
+/*
+ * Global capture flags.
+ */
+#define RTEMS_CAPTURE_ON (1 << 0)
+#define RTEMS_CAPTURE_NO_MEMORY (1 << 1)
+#define RTEMS_CAPTURE_OVERFLOW (1 << 2)
+#define RTEMS_CAPTURE_TRIGGERED (1 << 3)
+#define RTEMS_CAPTURE_READER_ACTIVE (1 << 4)
+#define RTEMS_CAPTURE_READER_WAITING (1 << 5)
+#define RTEMS_CAPTURE_GLOBAL_WATCH (1 << 6)
+
+/*
+ * RTEMS Capture Data.
+ */
+static rtems_capture_record_t* capture_records;
+static uint32_t capture_size;
+static uint32_t capture_count;
+static rtems_capture_record_t* capture_in;
+static uint32_t capture_out;
+static uint32_t capture_flags;
+static rtems_capture_task_t* capture_tasks;
+static rtems_capture_control_t* capture_controls;
+static int capture_extension_index;
+static rtems_id capture_id;
+static rtems_capture_timestamp capture_timestamp;
+static rtems_task_priority capture_ceiling;
+static rtems_task_priority capture_floor;
+static uint32_t capture_tick_period;
+static rtems_id capture_reader;
+int rtems_capture_free_info_on_task_delete;
+
+/*
+ * RTEMS Event text.
+ */
+static const char* capture_event_text[] =
+{
+ "CREATED_BY",
+ "CREATED",
+ "STARTED_BY",
+ "STARTED",
+ "RESTARTED_BY",
+ "RESTARTED",
+ "DELETED_BY",
+ "DELETED",
+ "BEGIN",
+ "EXITTED",
+ "SWITCHED_OUT",
+ "SWITCHED_IN",
+ "TIMESTAMP"
+};
+
+/*
+ * rtems_capture_get_time
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the current time. If a handler is provided
+ * by the user get the time from that.
+ */
+static inline void rtems_capture_get_time (uint32_t * ticks,
+ uint32_t * tick_offset)
+{
+ if (capture_timestamp)
+ capture_timestamp (ticks, tick_offset);
+ else
+ {
+ *ticks = _Watchdog_Ticks_since_boot;
+ *tick_offset = 0;
+ }
+}
+
+/*
+ * rtems_capture_match_names
+ *
+ * DESCRIPTION:
+ *
+ * This function compares rtems_names. It protects the
+ * capture engine from a change to the way names are supported
+ * in RTEMS.
+ *
+ */
+static inline rtems_boolean
+rtems_capture_match_names (rtems_name lhs, rtems_name rhs)
+{
+ return lhs == rhs;
+}
+
+/*
+ * rtems_capture_dup_name
+ *
+ * DESCRIPTION:
+ *
+ * This function duplicates an rtems_names. It protects the
+ * capture engine from a change to the way names are supported
+ * in RTEMS.
+ *
+ */
+static inline void
+rtems_capture_dup_name (rtems_name* dst, rtems_name src)
+{
+ *dst = src;
+}
+
+/*
+ * rtems_capture_name_in_group
+ *
+ * DESCRIPTION:
+ *
+ * This function sees if a name is in a group of names.
+ *
+ */
+static inline rtems_boolean
+rtems_capture_name_in_group (rtems_name task, rtems_name* tasks)
+{
+ if (tasks)
+ {
+ int i;
+ for (i = 0; i < RTEMS_CAPTURE_TRIGGER_TASKS; i++)
+ if (rtems_capture_match_names (task, *tasks++))
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * rtems_capture_match_name_id
+ *
+ * DESCRIPTION:
+ *
+ * This function matches a name and/or id.
+ */
+static inline rtems_boolean
+rtems_capture_match_name_id (rtems_name lhs_name,
+ rtems_id lhs_id,
+ rtems_name rhs_name,
+ rtems_id rhs_id)
+{
+ /*
+ * The left hand side name or id could be 0 which means a wildcard.
+ */
+ if ((lhs_name == 0) && (lhs_id == rhs_id))
+ return 1;
+ else if ((lhs_id == 0) || (lhs_id == rhs_id))
+ {
+ if (rtems_capture_match_names (lhs_name, rhs_name))
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * rtems_capture_init_stack_usage
+ *
+ * DESCRIPTION:
+ *
+ * This function setups a stack so its usage can be monitored.
+ */
+static inline void
+rtems_capture_init_stack_usage (rtems_capture_task_t* task)
+{
+ if (task->tcb)
+ {
+ uint32_t * s;
+ uint32_t i;
+
+ task->stack_size = task->tcb->Start.Initial_stack.size;
+ task->stack_clean = task->stack_size;
+
+ s = task->tcb->Start.Initial_stack.area;
+
+ for (i = 0; i < (task->stack_size - 128); i += 4)
+ *(s++) = 0xdeaddead;
+ }
+}
+
+/*
+ * rtems_capture_find_control
+ *
+ * DESCRIPTION:
+ *
+ * This function searches for a trigger given a name.
+ *
+ */
+static inline rtems_capture_control_t*
+rtems_capture_find_control (rtems_name name, rtems_id id)
+{
+ rtems_capture_control_t* control;
+
+ for (control = capture_controls; control != NULL; control = control->next)
+ if (rtems_capture_match_name_id (name, id, control->name, control->id))
+ break;
+ return control;
+}
+
+/*
+ * rtems_capture_create_control
+ *
+ * DESCRIPTION:
+ *
+ * This function creates a capture control for the capture engine.
+ *
+ */
+static inline rtems_capture_control_t*
+rtems_capture_create_control (rtems_name name, rtems_id id)
+{
+ rtems_interrupt_level level;
+ rtems_capture_control_t* control;
+ rtems_capture_task_t* task;
+
+ if ((name == 0) && (id == 0))
+ return NULL;
+
+ control = rtems_capture_find_control (name, id);
+
+ if (control == NULL)
+ {
+ control = _Workspace_Allocate (sizeof (rtems_capture_control_t));
+
+ if (control == NULL)
+ {
+ capture_flags |= RTEMS_CAPTURE_NO_MEMORY;
+ return NULL;
+ }
+
+ control->name = name;
+ control->id = id;
+ control->flags = 0;
+
+ memset (control->from, 0, sizeof (control->from));
+ memset (control->from_id, 0, sizeof (control->from_id));
+
+ rtems_interrupt_disable (level);
+
+ control->next = capture_controls;
+ capture_controls = control;
+
+ /*
+ * We need to scan the task list as set the control to the
+ * tasks.
+ */
+ for (task = capture_tasks; task != NULL; task = task->forw)
+ if (rtems_capture_match_name_id (name, id, task->name, task->id))
+ task->control = control;
+
+ rtems_interrupt_enable (level);
+ }
+
+ return control;
+}
+
+/*
+ * rtems_capture_create_capture_task
+ *
+ * DESCRIPTION:
+ *
+ * This function create the task control.
+ *
+ */
+static inline rtems_capture_task_t*
+rtems_capture_create_capture_task (rtems_tcb* new_task)
+{
+ rtems_interrupt_level level;
+ rtems_capture_task_t* task;
+ rtems_capture_control_t* control;
+
+ task = _Workspace_Allocate (sizeof (rtems_capture_task_t));
+
+ if (task == NULL)
+ {
+ capture_flags |= RTEMS_CAPTURE_NO_MEMORY;
+ return NULL;
+ }
+
+ rtems_capture_dup_name (&task->name, ((rtems_name) new_task->Object.name));
+
+ task->id = new_task->Object.id;
+ task->flags = 0;
+ task->in = 0;
+ task->out = 0;
+ task->tcb = new_task;
+ task->ticks = 0;
+ task->tick_offset = 0;
+ task->ticks_in = 0;
+ task->tick_offset_in = 0;
+ task->control = 0;
+ task->last_ticks = 0;
+ task->last_tick_offset = 0;
+
+ task->tcb->extensions[capture_extension_index] = task;
+
+ task->start_priority = new_task->Start.initial_priority;
+ task->stack_size = new_task->Start.Initial_stack.size;
+ task->stack_clean = task->stack_size;
+
+ rtems_interrupt_disable (level);
+
+ task->forw = capture_tasks;
+ if (task->forw)
+ task->forw->back = task;
+ task->back = NULL;
+ capture_tasks = task;
+
+ rtems_interrupt_enable (level);
+
+ /*
+ * We need to scan the default control list to initialise
+ * this control.
+ */
+
+ for (control = capture_controls; control != NULL; control = control->next)
+ if (rtems_capture_match_name_id (control->name, control->id,
+ task->name, task->id))
+ task->control = control;
+
+ return task;
+}
+
+/*
+ * rtems_capture_record
+ *
+ * DESCRIPTION:
+ *
+ * This function records a capture record into the capture buffer.
+ *
+ */
+static inline void
+rtems_capture_record (rtems_capture_task_t* task,
+ uint32_t events)
+{
+ /*
+ * Check the watch state if we have a task control, and
+ * the task's real priority is lower or equal to the ceiling.
+ */
+ if (task)
+ {
+ rtems_capture_control_t* control;
+
+ control = task->control;
+
+ /*
+ * Capure the record if we have an event that is always
+ * captured, or the task's real priority is greater than the
+ * watch ceiling, and the global watch or task watch is enabled.
+ */
+
+ if ((events & RTEMS_CAPTURE_RECORD_EVENTS) ||
+ ((task->tcb->real_priority >= capture_ceiling) &&
+ (task->tcb->real_priority <= capture_floor) &&
+ ((capture_flags & RTEMS_CAPTURE_GLOBAL_WATCH) ||
+ (control && (control->flags & RTEMS_CAPTURE_WATCH)))))
+ {
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable (level);
+
+ if (capture_count < capture_size)
+ {
+ capture_count++;
+ capture_in->task = task;
+ capture_in->events = (events |
+ (task->tcb->real_priority) |
+ (task->tcb->current_priority << 8));
+
+ if ((events & RTEMS_CAPTURE_RECORD_EVENTS) == 0)
+ task->flags |= RTEMS_CAPTURE_TRACED;
+
+ rtems_capture_get_time (&capture_in->ticks, &capture_in->tick_offset);
+
+ if (capture_in == &capture_records[capture_size - 1])
+ capture_in = capture_records;
+ else
+ capture_in++;
+ }
+ else
+ capture_flags |= RTEMS_CAPTURE_OVERFLOW;
+ rtems_interrupt_enable (level);
+ }
+ }
+}
+
+/*
+ * rtems_capture_create_task
+ *
+ * DESCRIPTION:
+ *
+ * This function is called when a task is created.
+ *
+ */
+static rtems_boolean
+rtems_capture_create_task (rtems_tcb* current_task,
+ rtems_tcb* new_task)
+{
+ rtems_capture_task_t* ct;
+ rtems_capture_task_t* nt;
+
+ ct = current_task->extensions[capture_extension_index];
+
+ /*
+ * The task ponters may not be known as the task may have
+ * been created before the capture engine was open. Add them.
+ */
+
+ if (ct == NULL)
+ ct = rtems_capture_create_capture_task (current_task);
+
+ /*
+ * Create the new task's capture control block.
+ */
+ nt = rtems_capture_create_capture_task (new_task);
+
+ /*
+ * If we are logging then record this fact.
+ */
+ rtems_capture_record (ct, RTEMS_CAPTURE_CREATED_BY_EVENT);
+ rtems_capture_record (nt, RTEMS_CAPTURE_CREATED_EVENT);
+
+ return 1 == 1;
+}
+
+/*
+ * rtems_capture_start_task
+ *
+ * DESCRIPTION:
+ *
+ * This function is called when a task is started.
+ *
+ */
+static rtems_extension
+rtems_capture_start_task (rtems_tcb* current_task,
+ rtems_tcb* started_task)
+{
+ /*
+ * Get the capture task control block so we can trace this
+ * event.
+ */
+ rtems_capture_task_t* ct;
+ rtems_capture_task_t* st;
+
+ ct = current_task->extensions[capture_extension_index];
+ st = started_task->extensions[capture_extension_index];
+
+ /*
+ * The task ponters may not be known as the task may have
+ * been created before the capture engine was open. Add them.
+ */
+
+ if (ct == NULL)
+ ct = rtems_capture_create_capture_task (current_task);
+
+ if (st == NULL)
+ st = rtems_capture_create_capture_task (started_task);
+
+ rtems_capture_record (ct, RTEMS_CAPTURE_STARTED_BY_EVENT);
+ rtems_capture_record (st, RTEMS_CAPTURE_STARTED_EVENT);
+
+ rtems_capture_init_stack_usage (st);
+}
+
+/*
+ * rtems_capture_restart_task
+ *
+ * DESCRIPTION:
+ *
+ * This function is called when a task is restarted.
+ *
+ */
+static rtems_extension
+rtems_capture_restart_task (rtems_tcb* current_task,
+ rtems_tcb* restarted_task)
+{
+ /*
+ * Get the capture task control block so we can trace this
+ * event.
+ */
+ rtems_capture_task_t* ct;
+ rtems_capture_task_t* rt;
+
+ ct = current_task->extensions[capture_extension_index];
+ rt = restarted_task->extensions[capture_extension_index];
+
+ /*
+ * The task ponters may not be known as the task may have
+ * been created before the capture engine was open. Add them.
+ */
+
+ if (ct == NULL)
+ ct = rtems_capture_create_capture_task (current_task);
+
+ if (rt == NULL)
+ rt = rtems_capture_create_capture_task (restarted_task);
+
+ rtems_capture_record (ct, RTEMS_CAPTURE_RESTARTED_BY_EVENT);
+ rtems_capture_record (rt, RTEMS_CAPTURE_RESTARTED_EVENT);
+
+ rtems_capture_task_stack_usage (rt);
+ rtems_capture_init_stack_usage (rt);
+}
+
+/*
+ * rtems_capture_delete_task
+ *
+ * DESCRIPTION:
+ *
+ * This function is called when a task is deleted.
+ *
+ */
+static rtems_extension
+rtems_capture_delete_task (rtems_tcb* current_task,
+ rtems_tcb* deleted_task)
+{
+ /*
+ * Get the capture task control block so we can trace this
+ * event.
+ */
+ rtems_capture_task_t* ct;
+ rtems_capture_task_t* dt;
+
+ /*
+ * The task ponters may not be known as the task may have
+ * been created before the capture engine was open. Add them.
+ */
+
+ ct = current_task->extensions[capture_extension_index];
+ dt = deleted_task->extensions[capture_extension_index];
+
+ if (ct == NULL)
+ ct = rtems_capture_create_capture_task (current_task);
+
+ if (dt == NULL)
+ dt = rtems_capture_create_capture_task (deleted_task);
+
+ rtems_capture_record (ct, RTEMS_CAPTURE_DELETED_BY_EVENT);
+ rtems_capture_record (dt, RTEMS_CAPTURE_DELETED_EVENT);
+
+ rtems_capture_task_stack_usage (dt);
+
+ /*
+ * This task's tcb will be invalid.
+ */
+ dt->tcb = 0;
+
+ /*
+ * Unlink
+ */
+ if (rtems_capture_free_info_on_task_delete) {
+ if (dt->forw)
+ dt->forw->back = dt->back;
+ if (dt->back)
+ dt->back->forw = dt->forw;
+ else
+ capture_tasks = dt->forw;
+ _Workspace_Free (dt);
+ }
+}
+
+/*
+ * rtems_capture_begin_task
+ *
+ * DESCRIPTION:
+ *
+ * This function is called when a task is begun.
+ *
+ */
+static rtems_extension
+rtems_capture_begin_task (rtems_tcb* begin_task)
+{
+ /*
+ * Get the capture task control block so we can trace this
+ * event.
+ */
+ rtems_capture_task_t* bt;
+
+ bt = begin_task->extensions[capture_extension_index];
+
+ /*
+ * The task ponters may not be known as the task may have
+ * been created before the capture engine was open. Add them.
+ */
+
+ if (bt == NULL)
+ bt = rtems_capture_create_capture_task (begin_task);
+
+ rtems_capture_record (bt, RTEMS_CAPTURE_BEGIN_EVENT);
+}
+
+/*
+ * rtems_capture_exitted_task
+ *
+ * DESCRIPTION:
+ *
+ * This function is called when a task is exitted. That is
+ * returned rather than was deleted.
+ *
+ */
+static rtems_extension
+rtems_capture_exitted_task (rtems_tcb* exitted_task)
+{
+ /*
+ * Get the capture task control block so we can trace this
+ * event.
+ */
+ rtems_capture_task_t* et;
+
+ et = exitted_task->extensions[capture_extension_index];
+
+ /*
+ * The task ponters may not be known as the task may have
+ * been created before the capture engine was open. Add them.
+ */
+
+ if (et == NULL)
+ et = rtems_capture_create_capture_task (exitted_task);
+
+ rtems_capture_record (et, RTEMS_CAPTURE_EXITTED_EVENT);
+
+ rtems_capture_task_stack_usage (et);
+}
+
+/*
+ * rtems_capture_switch_task
+ *
+ * DESCRIPTION:
+ *
+ * This function is called when a context is switched.
+ *
+ */
+static rtems_extension
+rtems_capture_switch_task (rtems_tcb* current_task,
+ rtems_tcb* heir_task)
+{
+ /*
+ * Only perform context switch trace processing if tracing is
+ * enabled.
+ */
+ if (capture_flags & RTEMS_CAPTURE_ON)
+ {
+ uint32_t ticks;
+ uint32_t tick_offset;
+
+ /*
+ * Get the cpature task control block so we can update the
+ * reference anbd perform any watch or trigger functions.
+ * The task ponters may not be known as the task may have
+ * been created before the capture engine was open. Add them.
+ */
+ rtems_capture_task_t* ct;
+ rtems_capture_task_t* ht;
+
+ if (_States_Is_transient (current_task->current_state))
+ {
+ rtems_id ct_id = current_task->Object.id;
+
+ for (ct = capture_tasks; ct; ct = ct->forw)
+ if (ct->id == ct_id)
+ break;
+ }
+ else
+ {
+ ct = current_task->extensions[capture_extension_index];
+
+ if (ct == NULL)
+ ct = rtems_capture_create_capture_task (current_task);
+ }
+
+ ht = heir_task->extensions[capture_extension_index];
+
+ if (ht == NULL)
+ ht = rtems_capture_create_capture_task (heir_task);
+
+ /*
+ * Update the execution time. Assume the tick will not overflow
+ * for now. This may need to change.
+ */
+ rtems_capture_get_time (&ticks, &tick_offset);
+
+ /*
+ * We could end up with null pointers for both the current task
+ * and the heir task.
+ */
+
+ if (ht)
+ {
+ ht->in++;
+ ht->ticks_in = ticks;
+ ht->tick_offset_in = tick_offset;
+ }
+
+ if (ct)
+ {
+ ct->out++;
+ ct->ticks += ticks - ct->ticks_in;
+
+ if (capture_timestamp)
+ {
+ tick_offset += capture_tick_period - ct->tick_offset_in;
+
+ if (tick_offset < capture_tick_period)
+ ct->tick_offset = tick_offset;
+ else
+ {
+ ct->ticks++;
+ ct->tick_offset = tick_offset - capture_tick_period;
+ }
+ }
+ else
+ {
+ ct->tick_offset += 100;
+ }
+ }
+
+ /*
+ * If we have not triggered then see if this is a trigger condition.
+ */
+ if (!(capture_flags & RTEMS_CAPTURE_TRIGGERED))
+ {
+ rtems_capture_control_t* cc = NULL;
+ rtems_capture_control_t* hc = NULL;
+
+ if (ct)
+ {
+ cc = ct->control;
+
+ /*
+ * Check the current task for a TO_ANY trigger.
+ */
+ if (cc && (cc->flags & RTEMS_CAPTURE_TO_ANY))
+ {
+ capture_flags |= RTEMS_CAPTURE_TRIGGERED;
+ goto triggered;
+ }
+ }
+
+ if (ht)
+ {
+ hc = ht->control;
+
+ /*
+ * Check the next task for a FROM_ANY.
+ */
+ if (hc && (hc->flags & RTEMS_CAPTURE_FROM_ANY))
+ {
+ capture_flags |= RTEMS_CAPTURE_TRIGGERED;
+ goto triggered;
+ }
+ }
+
+ /*
+ * Check is the trigger is from the current task
+ * to the next task.
+ */
+ if (cc && hc && (hc->flags & RTEMS_CAPTURE_FROM_TO))
+ if (rtems_capture_name_in_group (cc->name, hc->from))
+ {
+ capture_flags |= RTEMS_CAPTURE_TRIGGERED;
+ goto triggered;
+ }
+ }
+ else
+ {
+triggered:
+
+ rtems_capture_record (ct, RTEMS_CAPTURE_SWITCHED_OUT_EVENT);
+ rtems_capture_record (ht, RTEMS_CAPTURE_SWITCHED_IN_EVENT);
+ }
+ }
+}
+
+/*
+ * rtems_capture_open
+ *
+ * DESCRIPTION:
+ *
+ * This function initialises the realtime capture engine allocating the trace
+ * buffer. It is assumed we have a working heap at stage of initialisation.
+ *
+ */
+rtems_status_code
+rtems_capture_open (uint32_t size, rtems_capture_timestamp timestamp)
+{
+ rtems_extensions_table capture_extensions;
+ rtems_name name;
+ rtems_status_code sc;
+
+ /*
+ * See if the capture engine is already open.
+ */
+
+ if (capture_records)
+ return RTEMS_RESOURCE_IN_USE;
+
+ capture_records = malloc (size * sizeof (rtems_capture_record_t));
+
+ if (capture_records == NULL)
+ return RTEMS_NO_MEMORY;
+
+ capture_size = size;
+ capture_count = 0;
+ capture_in = capture_records;
+ capture_out = 0;
+ capture_flags = 0;
+ capture_tasks = NULL;
+ capture_ceiling = 0;
+ capture_floor = 255;
+
+ /*
+ * Create the extension table. This is copied so we
+ * can create it as a local.
+ */
+ capture_extensions.thread_create = rtems_capture_create_task;
+ capture_extensions.thread_start = rtems_capture_start_task;
+ capture_extensions.thread_restart = rtems_capture_restart_task;
+ capture_extensions.thread_delete = rtems_capture_delete_task;
+ capture_extensions.thread_switch = rtems_capture_switch_task;
+ capture_extensions.thread_begin = rtems_capture_begin_task;
+ capture_extensions.thread_exitted = rtems_capture_exitted_task;
+ capture_extensions.fatal = NULL;
+
+ /*
+ * Get the tick period from the BSP Configuration Table.
+ */
+ capture_tick_period = _Configuration_Table->microseconds_per_tick;
+
+ /*
+ * Register the user extension handlers for the CAPture Engine.
+ */
+ name = rtems_build_name ('C', 'A', 'P', 'E');
+ sc = rtems_extension_create (name, &capture_extensions, &capture_id);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ capture_id = 0;
+ free (capture_records);
+ capture_records = NULL;
+ }
+ else
+ {
+ capture_extension_index = rtems_get_index (capture_id);;
+ }
+
+ /*
+ * Iterate over the list of existing tasks.
+ */
+
+ return sc;
+}
+
+/*
+ * rtems_capture_close
+ *
+ * DESCRIPTION:
+ *
+ * This function shutdowns the capture engine and release any claimed
+ * resources.
+ */
+rtems_status_code
+rtems_capture_close ()
+{
+ rtems_interrupt_level level;
+ rtems_capture_task_t* task;
+ rtems_capture_control_t* control;
+ rtems_capture_record_t* records;
+ rtems_status_code sc;
+
+ rtems_interrupt_disable (level);
+
+ if (!capture_records)
+ {
+ rtems_interrupt_enable (level);
+ return RTEMS_SUCCESSFUL;
+ }
+
+ capture_flags &= ~RTEMS_CAPTURE_ON;
+
+ records = capture_records;
+ capture_records = NULL;
+
+ rtems_interrupt_enable (level);
+
+ /*
+ * Delete the extension first. This means we are now able to
+ * release the resources we have without them being used.
+ */
+
+ sc = rtems_extension_delete (capture_id);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ return sc;
+
+ task = capture_tasks;
+
+ while (task)
+ {
+ rtems_capture_task_t* delete = task;
+ task = task->forw;
+ _Workspace_Free (delete);
+ }
+
+ capture_tasks = NULL;
+
+ control = capture_controls;
+
+ while (control)
+ {
+ rtems_capture_control_t* delete = control;
+ control = control->next;
+ _Workspace_Free (delete);
+ }
+
+ capture_controls = NULL;
+
+ if (capture_records)
+ {
+ free (capture_records);
+ capture_records = NULL;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * rtems_capture_control
+ *
+ * DESCRIPTION:
+ *
+ * This function allows control of tracing at a global level.
+ */
+rtems_status_code
+rtems_capture_control (rtems_boolean enable)
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable (level);
+
+ if (!capture_records)
+ {
+ rtems_interrupt_enable (level);
+ return RTEMS_UNSATISFIED;
+ }
+
+ if (enable)
+ capture_flags |= RTEMS_CAPTURE_ON;
+ else
+ capture_flags &= ~RTEMS_CAPTURE_ON;
+
+ rtems_interrupt_enable (level);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * rtems_capture_flush
+ *
+ * DESCRIPTION:
+ *
+ * This function flushes the capture buffer. The prime parameter allows the
+ * capture engine to also be primed again.
+ */
+rtems_status_code
+rtems_capture_flush (rtems_boolean prime)
+{
+ rtems_interrupt_level level;
+ rtems_capture_task_t* task;
+
+ rtems_interrupt_disable (level);
+
+ for (task = capture_tasks; task != NULL; task = task->forw)
+ task->flags &= ~RTEMS_CAPTURE_TRACED;
+
+ if (prime)
+ capture_flags &= ~(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_OVERFLOW);
+ else
+ capture_flags &= ~RTEMS_CAPTURE_OVERFLOW;
+
+ capture_in = capture_records;
+ capture_out = 0;
+
+ rtems_interrupt_enable (level);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * rtems_capture_watch_add
+ *
+ * DESCRIPTION:
+ *
+ * This function defines a watch for a specific task given a name. A watch
+ * causes it to be traced either in or out of context. The watch can be
+ * optionally enabled or disabled with the set routine. It is disabled by
+ * default.
+ */
+rtems_status_code
+rtems_capture_watch_add (rtems_name name, rtems_id id)
+{
+ rtems_capture_control_t* control;
+
+ if ((name == 0) && (id == 0))
+ return RTEMS_UNSATISFIED;
+
+ control = rtems_capture_find_control (name, id);
+
+ if (control && !id)
+ return RTEMS_TOO_MANY;
+
+ if (!control)
+ control = rtems_capture_create_control (name, id);
+
+ if (!control)
+ return RTEMS_NO_MEMORY;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * rtems_capture_watch_del
+ *
+ * DESCRIPTION:
+ *
+ * This function removes a watch for a specific task given a name. The task
+ * description will still exist if referenced by a trace record in the trace
+ * buffer or a global watch is defined.
+ */
+rtems_status_code
+rtems_capture_watch_del (rtems_name name, rtems_id id)
+{
+ rtems_interrupt_level level;
+ rtems_capture_control_t* control;
+ rtems_capture_control_t** prev_control;
+ rtems_capture_task_t* task;
+ rtems_boolean found = 0;
+
+ /*
+ * Should this test be for wildcards ?
+ */
+
+ for (prev_control = &capture_controls, control = capture_controls;
+ control != NULL; )
+ {
+ if (rtems_capture_match_name_id (name, id, control->name, control->id))
+ {
+ rtems_interrupt_disable (level);
+
+ for (task = capture_tasks; task != NULL; task = task->forw)
+ if (task->control == control)
+ task->control = 0;
+
+ *prev_control = control->next;
+
+ rtems_interrupt_enable (level);
+
+ _Workspace_Free (control);
+
+ control = *prev_control;
+
+ found = 1;
+ }
+ else
+ {
+ prev_control = &control->next;
+ control = control->next;
+ }
+ }
+
+ if (found)
+ return RTEMS_SUCCESSFUL;
+
+ return RTEMS_INVALID_NAME;
+}
+
+/*
+ * rtems_capture_watch_set
+ *
+ * DESCRIPTION:
+ *
+ * This function allows control of a watch. The watch can be enabled or
+ * disabled.
+ */
+rtems_status_code
+rtems_capture_watch_ctrl (rtems_name name, rtems_id id, rtems_boolean enable)
+{
+ rtems_interrupt_level level;
+ rtems_capture_control_t* control;
+ rtems_boolean found = 0;
+
+ /*
+ * Find the control and then set the watch. It must exist before it can
+ * be controlled.
+ */
+ for (control = capture_controls; control != NULL; control = control->next)
+ {
+ if (rtems_capture_match_name_id (name, id, control->name, control->id))
+ {
+ rtems_interrupt_disable (level);
+
+ if (enable)
+ control->flags |= RTEMS_CAPTURE_WATCH;
+ else
+ control->flags &= ~RTEMS_CAPTURE_WATCH;
+
+ rtems_interrupt_enable (level);
+
+ found = 1;
+ }
+ }
+
+ if (found)
+ return RTEMS_SUCCESSFUL;
+
+ return RTEMS_INVALID_NAME;
+}
+
+/*
+ * rtems_capture_watch_global
+ *
+ * DESCRIPTION:
+ *
+ * This function allows control of a global watch. The watch can be enabled or
+ * disabled. A global watch configures all tasks below the ceiling and above
+ * the floor to be traced.
+ */
+rtems_status_code
+rtems_capture_watch_global (rtems_boolean enable)
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable (level);
+
+ /*
+ * We need to keep specific and global watches separate so
+ * a global enable/disable does not lose a specific watch.
+ */
+ if (enable)
+ capture_flags |= RTEMS_CAPTURE_GLOBAL_WATCH;
+ else
+ capture_flags &= ~RTEMS_CAPTURE_GLOBAL_WATCH;
+
+ rtems_interrupt_enable (level);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * rtems_capture_watch_global_on
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the global watch state.
+ */
+rtems_boolean
+rtems_capture_watch_global_on ()
+{
+ return capture_flags & RTEMS_CAPTURE_GLOBAL_WATCH ? 1 : 0;
+}
+
+/*
+ * rtems_capture_watch_ceiling
+ *
+ * DESCRIPTION:
+ *
+ * This function sets a watch ceiling. Tasks at or greating that the
+ * ceiling priority are not watched. This is a simple way to monitor
+ * an application and exclude system tasks running at a higher
+ * priority level.
+ */
+rtems_status_code
+rtems_capture_watch_ceiling (rtems_task_priority ceiling)
+{
+ capture_ceiling = ceiling;
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * rtems_capture_watch_get_ceiling
+ *
+ * DESCRIPTION:
+ *
+ * This function gets the watch ceiling.
+ */
+rtems_task_priority
+rtems_capture_watch_get_ceiling ()
+{
+ return capture_ceiling;
+}
+
+/*
+ * rtems_capture_watch_floor
+ *
+ * DESCRIPTION:
+ *
+ * This function sets a watch floor. Tasks at or less that the
+ * floor priority are not watched. This is a simple way to monitor
+ * an application and exclude system tasks running at a lower
+ * priority level.
+ */
+rtems_status_code
+rtems_capture_watch_floor (rtems_task_priority floor)
+{
+ capture_floor = floor;
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * rtems_capture_watch_get_floor
+ *
+ * DESCRIPTION:
+ *
+ * This function gets the watch floor.
+ */
+rtems_task_priority
+rtems_capture_watch_get_floor ()
+{
+ return capture_floor;
+}
+
+/*
+ * rtems_capture_set_trigger
+ *
+ * DESCRIPTION:
+ *
+ * This function sets an edge trigger. Left is the left side of
+ * the edge and right is right side of the edge. The trigger type
+ * can be -
+ *
+ * FROM_ANY : a switch from any task to the right side of the edge.
+ * TO_ANY : a switch from the left side of the edge to any task.
+ * FROM_TO : a switch from the left side of the edge to the right
+ * side of the edge.
+ *
+ * This set trigger routine will create a capture control for the
+ * target task. The task list is searched and any existing tasks
+ * are linked to the new control.
+ *
+ * We can have a number of tasks that have the same name so we
+ * search using names. This means a number of tasks can be
+ * linked to single control.
+ */
+rtems_status_code
+rtems_capture_set_trigger (rtems_name from,
+ rtems_id from_id,
+ rtems_name to,
+ rtems_id to_id,
+ rtems_capture_trigger_t trigger)
+{
+ rtems_capture_control_t* control;
+ int i;
+
+ /*
+ * Find the capture control blocks for the from and to
+ * tasks.
+ */
+ if (trigger == rtems_capture_to_any)
+ {
+ control = rtems_capture_create_control (from, from_id);
+ if (control == NULL)
+ return RTEMS_NO_MEMORY;
+ control->flags |= RTEMS_CAPTURE_TO_ANY;
+ }
+
+ if ((trigger == rtems_capture_from_to) ||
+ (trigger == rtems_capture_from_any))
+ {
+ control = rtems_capture_create_control (to, to_id);
+ if (control == NULL)
+ return RTEMS_NO_MEMORY;
+
+ if (trigger == rtems_capture_from_any)
+ control->flags |= RTEMS_CAPTURE_FROM_ANY;
+ else
+ {
+ control->flags |= RTEMS_CAPTURE_FROM_TO;
+ for (i = 0; i < RTEMS_CAPTURE_TRIGGER_TASKS; i++)
+ {
+ if (control->from[i] == 0)
+ {
+ control->from[i] = from;
+ control->from_id[i] = from_id;
+ break;
+ }
+ }
+ }
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * rtems_capture_read
+ *
+ * DESCRIPTION:
+ *
+ * This function reads a number of records from the capture buffer.
+ * The user can optionally block and wait until the buffer as a
+ * specific number of records available or a specific time has
+ * elasped.
+ *
+ * The function returns the number of record that is has that are
+ * in a continous block of memory. If the number of available records
+ * wrap then only those records are provided. This removes the need for
+ * caller to be concerned about buffer wrappings. If the number of
+ * requested records cannot be met due to the wrapping of the records
+ * less than the specified number will be returned.
+ *
+ * The user must release the records. This is achieved with a call to
+ * rtems_capture_release. Calls this function without a release will
+ * result in at least the same number of records being released.
+ *
+ * The 'threshold' parameter is the number of records that must be
+ * captured before returning. If a timeout period is specified (non-0)
+ * any captured records will be returned. These parameters stop
+ * thrashing occuring for a small number of records, yet allows
+ * a user configured latiency to be applied for single events.
+ *
+ * The 'timeout' parameter is in micro-seconds. A value of 0 will disable
+ * the timeout.
+ *
+ */
+rtems_status_code
+rtems_capture_read (uint32_t threshold,
+ uint32_t timeout,
+ uint32_t * read,
+ rtems_capture_record_t** recs)
+{
+ rtems_interrupt_level level;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ uint32_t count;
+
+ *read = 0;
+ *recs = NULL;
+
+ rtems_interrupt_disable (level);
+
+ /*
+ * Only one reader is allowed.
+ */
+
+ if (capture_flags & RTEMS_CAPTURE_READER_ACTIVE)
+ {
+ rtems_interrupt_enable (level);
+ return RTEMS_RESOURCE_IN_USE;
+ }
+
+ capture_flags |= RTEMS_CAPTURE_READER_ACTIVE;
+ *read = count = capture_count;
+
+ rtems_interrupt_enable (level);
+
+ *recs = &capture_records[capture_out];
+
+ for (;;)
+ {
+ /*
+ * See if the count wraps the end of the record buffer.
+ */
+ if (count && ((capture_out + count) >= capture_size))
+ *read = capture_size - capture_out;
+
+ /*
+ * Do we have a threshold and the current count has not wrapped
+ * around the end of the capture record buffer ?
+ */
+ if ((*read == count) && threshold)
+ {
+ /*
+ * Do we have enough records ?
+ */
+ if (*read < threshold)
+ {
+ rtems_event_set event_out;
+
+ rtems_task_ident (RTEMS_SELF, RTEMS_LOCAL, &capture_reader);
+
+ rtems_interrupt_disable (level);
+
+ capture_flags |= RTEMS_CAPTURE_READER_WAITING;
+
+ rtems_interrupt_enable (level);
+
+ sc = rtems_event_receive (RTEMS_EVENT_0,
+ RTEMS_WAIT | RTEMS_EVENT_ANY,
+ TOD_MICROSECONDS_TO_TICKS (timeout),
+ &event_out);
+
+ /*
+ * Let the user handle all other sorts of errors. This may
+ * not be the best solution, but oh well, it will do for
+ * now.
+ */
+ if ((sc != RTEMS_SUCCESSFUL) && (sc != RTEMS_TIMEOUT))
+ break;
+
+ rtems_interrupt_disable (level);
+
+ *read = count = capture_count;
+
+ rtems_interrupt_enable (level);
+
+ continue;
+ }
+ }
+
+ /*
+ * Always out if we reach here. To loop use continue.
+ */
+ break;
+ }
+
+ rtems_interrupt_disable (level);
+
+ capture_flags &= ~RTEMS_CAPTURE_READER_ACTIVE;
+
+ rtems_interrupt_enable (level);
+
+ return sc;
+}
+
+/*
+ * rtems_capture_release
+ *
+ * DESCRIPTION:
+ *
+ * This function releases the requested number of record slots back
+ * to the capture engine. The count must match the number read.
+ */
+rtems_status_code
+rtems_capture_release (uint32_t count)
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable (level);
+
+ if (count > capture_count)
+ count = capture_count;
+
+ capture_count -= count;
+
+ capture_out = (capture_count + count) % capture_size;
+
+ rtems_interrupt_enable (level);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * rtems_capture_tick_time
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the tick period in nano-seconds.
+ */
+uint32_t
+rtems_capture_tick_time ()
+{
+ return capture_tick_period;
+}
+
+/*
+ * rtems_capture_event_text
+ *
+ * DESCRIPTION:
+ *
+ * This function returns a string for an event based on the bit in the
+ * event. The functions takes the bit offset as a number not the bit
+ * set in a bit map.
+ */
+const char*
+rtems_capture_event_text (int event)
+{
+ if ((event < RTEMS_CAPTURE_EVENT_START) || (event > RTEMS_CAPTURE_EVENT_END))
+ return "invalid event id";
+ return capture_event_text[event - RTEMS_CAPTURE_EVENT_START];
+}
+
+/*
+ * rtems_capture_get_task_list
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the head of the list of tasks that the
+ * capture engine has detected.
+ */
+rtems_capture_task_t*
+rtems_capture_get_task_list ()
+{
+ return capture_tasks;
+}
+
+/*
+ * rtems_capture_task_stack_usage
+ *
+ * DESCRIPTION:
+ *
+ * This function updates the stack usage. The task control block
+ * is updated.
+ */
+uint32_t
+rtems_capture_task_stack_usage (rtems_capture_task_t* task)
+{
+ if (task->tcb)
+ {
+ uint32_t * st;
+ uint32_t * s;
+
+ /*
+ * @todo: Assumes all stacks move the same way.
+ */
+ st = task->tcb->Start.Initial_stack.area + task->stack_size;
+ s = task->tcb->Start.Initial_stack.area;
+
+ while (s < st)
+ {
+ if (*s != 0xdeaddead)
+ break;
+ s++;
+ }
+
+ task->stack_clean =
+ s - (uint32_t *) task->tcb->Start.Initial_stack.area;
+ }
+
+ return task->stack_clean;
+}
+
+/*
+ * rtems_capture_get_control_list
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the head of the list of control in the
+ * capture engine.
+ */
+rtems_capture_control_t*
+rtems_capture_get_control_list ()
+{
+ return capture_controls;
+}
diff --git a/cpukit/libmisc/capture/capture.h b/cpukit/libmisc/capture/capture.h
new file mode 100644
index 0000000000..6db1ee89f3
--- /dev/null
+++ b/cpukit/libmisc/capture/capture.h
@@ -0,0 +1,884 @@
+/**
+ * @file rtems/capture.h
+ */
+
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Objective Design Systems Pty Ltd, 2002
+ All rights reserved Objective Design Systems Pty Ltd, 2002
+ Chris Johns (ccj@acm.org)
+
+ COPYRIGHT (c) 1989-1998.
+ On-Line Applications Research Corporation (OAR).
+
+ The license and distribution terms for this file may be
+ found in the file LICENSE in this distribution.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ RTEMS Performance Monitoring and Measurement Framework.
+
+ This is the Capture Engine component.
+
+*/
+
+#ifndef __CAPTURE_H_
+#define __CAPTURE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+
+/**
+ * The number of tasks in a trigger group.
+ */
+#define RTEMS_CAPTURE_TRIGGER_TASKS (32)
+
+/**
+ * rtems_capture_control_t
+ *
+ * DESCRIPTION:
+ *
+ * RTEMS control holds the trigger and watch configuration for a group of
+ * tasks with the same name.
+ */
+typedef struct rtems_capture_control_s
+{
+ rtems_name name;
+ rtems_id id;
+ uint32_t flags;
+ rtems_name from[RTEMS_CAPTURE_TRIGGER_TASKS];
+ rtems_id from_id[RTEMS_CAPTURE_TRIGGER_TASKS];
+ struct rtems_capture_control_s* next;
+} rtems_capture_control_t;
+
+/**
+ * Control flags.
+ */
+#define RTEMS_CAPTURE_WATCH (1 << 0)
+#define RTEMS_CAPTURE_FROM_ANY (1 << 1)
+#define RTEMS_CAPTURE_TO_ANY (1 << 2)
+#define RTEMS_CAPTURE_FROM_TO (1 << 3)
+
+/**
+ * rtems_capture_control_t
+ *
+ * DESCRIPTION:
+ *
+ * RTEMS capture control provdes the information about a task, along
+ * with its trigger state. The control is referenced by each
+ * capture record. This is* information neeed by the decoder. The
+ * capture record cannot assume the task will exist when the record is
+ * dumped via the target interface so task info needed for tracing is
+ * copied and held here.
+ *
+ * The inline heper functions provide more details about the info
+ * contained in this structure.
+ *
+ * Note, the tracer code exploits the fact an rtems_name is a
+ * 32bit value.
+ */
+typedef struct rtems_capture_task_s
+{
+ rtems_name name;
+ rtems_id id;
+ uint32_t flags;
+ rtems_tcb* tcb;
+ uint32_t in;
+ uint32_t out;
+ rtems_task_priority start_priority;
+ uint32_t stack_size;
+ uint32_t stack_clean;
+ uint32_t ticks;
+ uint32_t tick_offset;
+ uint32_t ticks_in;
+ uint32_t tick_offset_in;
+ uint32_t last_ticks;
+ uint32_t last_tick_offset;
+ rtems_capture_control_t* control;
+ struct rtems_capture_task_s* forw;
+ struct rtems_capture_task_s* back;
+} rtems_capture_task_t;
+
+/**
+ * Task flags.
+ */
+#define RTEMS_CAPTURE_TRACED (1 << 0)
+
+/*
+ * rtems_capture_record_t
+ *
+ * DESCRIPTION:
+ *
+ * RTEMS capture record. This is a record that is written into
+ * the buffer. The events includes the priority of the task
+ * at the time of the context switch.
+ */
+typedef struct rtems_capture_record_s
+{
+ rtems_capture_task_t* task;
+ uint32_t events;
+ uint32_t ticks;
+ uint32_t tick_offset;
+} rtems_capture_record_t;
+
+/**
+ * The capture record event flags.
+ */
+#define RTEMS_CAPTURE_REAL_PRI_EVENT_MASK UINT32_C(0x000000ff)
+#define RTEMS_CAPTURE_CURR_PRI_EVENT_MASK UINT32_C(0x0000ff00)
+#define RTEMS_CAPTURE_REAL_PRIORITY_EVENT (0)
+#define RTEMS_CAPTURE_CURR_PRIORITY_EVENT (8)
+#define RTEMS_CAPTURE_EVENT_START (16)
+#define RTEMS_CAPTURE_CREATED_BY_EVENT UINT32_C(0x00010000)
+#define RTEMS_CAPTURE_CREATED_EVENT UINT32_C(0x00020000)
+#define RTEMS_CAPTURE_STARTED_BY_EVENT UINT32_C(0x00040000)
+#define RTEMS_CAPTURE_STARTED_EVENT UINT32_C(0x00080000)
+#define RTEMS_CAPTURE_RESTARTED_BY_EVENT UINT32_C(0x00100000)
+#define RTEMS_CAPTURE_RESTARTED_EVENT UINT32_C(0x00200000)
+#define RTEMS_CAPTURE_DELETED_BY_EVENT UINT32_C(0x00400000)
+#define RTEMS_CAPTURE_DELETED_EVENT UINT32_C(0x00800000)
+#define RTEMS_CAPTURE_BEGIN_EVENT UINT32_C(0x01000000)
+#define RTEMS_CAPTURE_EXITTED_EVENT UINT32_C(0x02000000)
+#define RTEMS_CAPTURE_SWITCHED_OUT_EVENT UINT32_C(0x04000000)
+#define RTEMS_CAPTURE_SWITCHED_IN_EVENT UINT32_C(0x08000000)
+#define RTEMS_CAPTURE_TIMESTAMP UINT32_C(0x10000000)
+#define RTEMS_CAPTURE_EVENT_END (28)
+
+/**
+ * rtems_capture_trigger_t
+ *
+ * DESCRIPTION:
+ *
+ * The types of triggers that exist. FIXME: add more here.
+ */
+typedef enum rtems_capture_trigger_t
+{
+ rtems_capture_to_any,
+ rtems_capture_from_any,
+ rtems_capture_from_to
+} rtems_capture_trigger_t;
+
+/**
+ * rtems_capture_timestamp
+ *
+ * DESCRIPTION:
+ *
+ * This defines the callout handler to obtain a time stamp. The
+ * value returned is time count since the last read.
+ *
+ */
+
+typedef void (*rtems_capture_timestamp)
+ (uint32_t * ticks, uint32_t * micro);
+
+/**
+ * rtems_capture_open
+ *
+ * DESCRIPTION:
+ *
+ * This function initialises the realtime trace manager allocating the capture
+ * buffer. It is assumed we have a working heap at stage of initialisation.
+ *
+ */
+rtems_status_code
+rtems_capture_open (uint32_t size,
+ rtems_capture_timestamp timestamp);
+
+/**
+ * rtems_capture_free_info_on_task_delete
+ *
+ * DESCRIPTION:
+ *
+ * If non-zero task informaion if freed when a task is deleted.
+ *
+ */
+extern int rtems_capture_free_info_on_task_delete;
+
+/**
+ * rtems_capture_close
+ *
+ * DESCRIPTION:
+ *
+ * This function shutdowns the tracer and release any claimed
+ * resources.
+ */
+rtems_status_code
+rtems_capture_close ();
+
+/**
+ * rtems_capture_control
+ *
+ * DESCRIPTION:
+ *
+ * This function allows control of tracing at a global level.
+ */
+rtems_status_code
+rtems_capture_control (rtems_boolean enable);
+
+/*
+ * rtems_capture_flush
+ *
+ * DESCRIPTION:
+ *
+ * This function flushes the trace buffer. The prime parameter allows the
+ * capture engine to also be primed again.
+ */
+rtems_status_code
+rtems_capture_flush (rtems_boolean prime);
+
+/**
+ * rtems_capture_watch_add
+ *
+ * DESCRIPTION:
+ *
+ * This function defines a watch for a specific task given a name. A watch
+ * causes it to be traced either in or out of context. The watch can be
+ * optionally enabled or disabled with the set routine. It is disabled by
+ * default.
+ */
+rtems_status_code
+rtems_capture_watch_add (rtems_name name, rtems_id id);
+
+/**
+ * rtems_capture_watch_del
+ *
+ * DESCRIPTION:
+ *
+ * This function removes a watch for a specific task given a name. The task
+ * description will still exist if referenced by a trace record in the trace
+ * buffer or a global watch is defined.
+ */
+rtems_status_code
+rtems_capture_watch_del (rtems_name name, rtems_id id);
+
+/**
+ * rtems_capture_watch_set
+ *
+ * DESCRIPTION:
+ *
+ * This function allows control of a watch. The watch can be enabled or
+ * disabled.
+ */
+rtems_status_code
+rtems_capture_watch_ctrl (rtems_name name, rtems_id id, rtems_boolean enable);
+
+/**
+ * rtems_capture_watch_global
+ *
+ * DESCRIPTION:
+ *
+ * This function allows control of a global watch. The watch can be enabled or
+ * disabled. A global watch configures all tasks below the ceiling and above
+ * the floor to be traced.
+ */
+rtems_status_code
+rtems_capture_watch_global (rtems_boolean enable);
+
+/**
+ * rtems_capture_watch_global_on
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the global watch state.
+ */
+rtems_boolean
+rtems_capture_watch_global_on ();
+
+/**
+ * rtems_capture_watch_ceiling
+ *
+ * DESCRIPTION:
+ *
+ * This function sets a watch ceiling. Tasks at or greating that the
+ * ceiling priority are not watched. This is a simple way to monitor
+ * an application and exclude system tasks running at a higher
+ * priority level.
+ */
+rtems_status_code
+rtems_capture_watch_ceiling (rtems_task_priority ceiling);
+
+/**
+ * rtems_capture_watch_get_ceiling
+ *
+ * DESCRIPTION:
+ *
+ * This function gets the watch ceiling.
+ */
+rtems_task_priority
+rtems_capture_watch_get_ceiling ();
+
+/**
+ * rtems_capture_watch_floor
+ *
+ * DESCRIPTION:
+ *
+ * This function sets a watch floor. Tasks at or less that the
+ * floor priority are not watched. This is a simple way to monitor
+ * an application and exclude system tasks running at a lower
+ * priority level.
+ */
+rtems_status_code
+rtems_capture_watch_floor (rtems_task_priority floor);
+
+/**
+ * rtems_capture_watch_get_floor
+ *
+ * DESCRIPTION:
+ *
+ * This function gets the watch floor.
+ */
+rtems_task_priority
+rtems_capture_watch_get_floor ();
+
+/**
+ * rtems_capture_set_trigger
+ *
+ * DESCRIPTION:
+ *
+ * This function sets an edge trigger. Left is the left side of
+ * the edge and right is right side of the edge. The trigger type
+ * can be -
+ *
+ * FROM_ANY : a switch from any task to the right side of the edge.
+ * TO_ANY : a switch from the left side of the edge to any task.
+ * FROM_TO : a switch from the left side of the edge to the right
+ * side of the edge.
+ *
+ * This set trigger routine will create a trace control for the
+ * target task. The task list is searched and any existing tasks
+ * are linked to the new control.
+ *
+ * We can have a number of tasks that have the same name so we
+ * search using names. This means a number of tasks can be
+ * linked to single control.
+ */
+rtems_status_code
+rtems_capture_set_trigger (rtems_name from,
+ rtems_id from_id,
+ rtems_name to,
+ rtems_id to_id,
+ rtems_capture_trigger_t trigger);
+
+/**
+ * rtems_capture_read
+ *
+ * DESCRIPTION:
+ *
+ * This function reads a number of records from the capture buffer.
+ * The user can optionally block and wait until the buffer as a
+ * specific number of records available or a specific time has
+ * elasped.
+ *
+ * The function returns the number of record that is has that are
+ * in a continous block of memory. If the number of available records
+ * wrap then only those records are provided. This removes the need for
+ * caller to be concerned about buffer wrappings. If the number of
+ * requested records cannot be met due to the wrapping of the records
+ * less than the specified number will be returned.
+ *
+ * The user must release the records. This is achieved with a call to
+ * rtems_capture_release. Calls this function without a release will
+ * result in at least the same number of records being released.
+ *
+ * The 'threshold' parameter is the number of records that must be
+ * captured before returning. If a timeout period is specified (non-0)
+ * any captured records will be returned. These parameters stop
+ * thrashing occuring for a small number of records, yet allows
+ * a user configured latiency to be applied for single events.
+ *
+ * The 'timeout' parameter is in micro-seconds. A value of 0 will disable
+ * the timeout.
+ *
+ */
+rtems_status_code
+rtems_capture_read (uint32_t threshold,
+ uint32_t timeout,
+ uint32_t * read,
+ rtems_capture_record_t** recs);
+
+/**
+ * rtems_capture_release
+ *
+ * DESCRIPTION:
+ *
+ * This function releases the requested number of record slots back
+ * to the capture engine. The count must match the number read.
+ */
+rtems_status_code
+rtems_capture_release (uint32_t count);
+
+/**
+ * rtems_capture_tick_time
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the tick period in micro-seconds.
+ */
+uint32_t
+rtems_capture_tick_time ();
+
+/*
+ * rtems_capture_tick_time
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the tick period in micro-seconds.
+ */
+uint32_t
+rtems_capture_tick_time ();
+
+/**
+ * rtems_capture_event_text
+ *
+ * DESCRIPTION:
+ *
+ * This function returns a string for an event based on the bit in the
+ * event. The functions takes the bit offset as a number not the bit
+ * set in a bit map.
+ */
+const char*
+rtems_capture_event_text (int event);
+
+/**
+ * rtems_capture_get_task_list
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the head of the list of tasks that the
+ * capture engine has detected.
+ */
+rtems_capture_task_t*
+rtems_capture_get_task_list ();
+
+/**
+ * rtems_capture_next_task
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the pointer to the next task in the list. The
+ * pointer NULL terminates the list.
+ */
+static inline rtems_capture_task_t*
+rtems_capture_next_task (rtems_capture_task_t* task)
+{
+ return task->forw;
+}
+
+/**
+ * rtems_capture_task_valid
+ *
+ * DESCRIPTION:
+ *
+ * This function returns true if the task control block points to
+ * a valid task.
+ */
+static inline rtems_boolean
+rtems_capture_task_valid (rtems_capture_task_t* task)
+{
+ return task->tcb != NULL;
+}
+
+/**
+ * rtems_capture_task_id
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the task id.
+ */
+static inline rtems_id
+rtems_capture_task_id (rtems_capture_task_t* task)
+{
+ return task->id;
+}
+
+/**
+ * rtems_capture_task_state
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the task state.
+ */
+static inline States_Control
+rtems_capture_task_state (rtems_capture_task_t* task)
+{
+ if (rtems_capture_task_valid (task))
+ return task->tcb->current_state;
+ return 0;
+}
+
+/**
+ * rtems_capture_task_name
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the task name.
+ */
+static inline rtems_name
+rtems_capture_task_name (rtems_capture_task_t* task)
+{
+ return task->name;
+}
+
+/**
+ * rtems_capture_task_flags
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the task flags.
+ */
+static inline uint32_t
+rtems_capture_task_flags (rtems_capture_task_t* task)
+{
+ return task->flags;
+}
+
+/**
+ * rtems_capture_task_control
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the task control if present.
+ */
+static inline rtems_capture_control_t*
+rtems_capture_task_control (rtems_capture_task_t* task)
+{
+ return task->control;
+}
+
+/**
+ * rtems_capture_task_control_flags
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the task control flags if a control is present.
+ */
+static inline uint32_t
+rtems_capture_task_control_flags (rtems_capture_task_t* task)
+{
+ if (!task->control)
+ return 0;
+ return task->control->flags;
+}
+
+/**
+ * rtems_capture_task_switched_in
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the number of times the task has
+ * been switched into context.
+ */
+static inline uint32_t
+rtems_capture_task_switched_in (rtems_capture_task_t* task)
+{
+ return task->in;
+}
+
+/**
+ * rtems_capture_task_switched_out
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the number of times the task has
+ * been switched out of context.
+ */
+static inline uint32_t
+rtems_capture_task_switched_out (rtems_capture_task_t* task)
+{
+ return task->out;
+}
+
+/**
+ * rtems_capture_task_curr_priority
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the tasks start priority. The tracer needs this
+ * to track where the task's priority goes.
+ */
+static inline rtems_task_priority
+rtems_capture_task_start_priority (rtems_capture_task_t* task)
+{
+ return task->start_priority;
+}
+
+/**
+ * rtems_capture_task_real_priority
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the tasks real priority.
+ */
+static inline rtems_task_priority
+rtems_capture_task_real_priority (rtems_capture_task_t* task)
+{
+ if (rtems_capture_task_valid (task))
+ return task->tcb->real_priority;
+ return 0;
+}
+
+/**
+ * rtems_capture_task_curr_priority
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the tasks current priority.
+ */
+static inline rtems_task_priority
+rtems_capture_task_curr_priority (rtems_capture_task_t* task)
+{
+ if (rtems_capture_task_valid (task))
+ return task->tcb->current_priority;
+ return 0;
+}
+
+/**
+ * rtems_capture_task_stack_usage
+ *
+ * DESCRIPTION:
+ *
+ * This function updates the stack usage. The task control block
+ * is updated.
+ */
+uint32_t
+rtems_capture_task_stack_usage (rtems_capture_task_t* task);
+
+/**
+ * rtems_capture_task_stack_size
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the task's stack size.
+ */
+static inline uint32_t
+rtems_capture_task_stack_size (rtems_capture_task_t* task)
+{
+ return task->stack_size;
+}
+
+/**
+ * rtems_capture_task_stack_used
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the amount of stack used.
+ */
+static inline uint32_t
+rtems_capture_task_stack_used (rtems_capture_task_t* task)
+{
+ return task->stack_size - task->stack_clean;
+}
+
+/**
+ * rtems_capture_task_ticks
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the current execution time as ticks.
+ */
+static inline uint32_t
+rtems_capture_task_ticks (rtems_capture_task_t* task)
+{
+ return task->ticks;
+}
+
+/**
+ * rtems_capture_task_tick_offset
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the current execution time tick offset.
+ */
+static inline uint32_t
+rtems_capture_task_tick_offset (rtems_capture_task_t* task)
+{
+ return task->tick_offset;
+}
+
+/**
+ * rtems_capture_task_time
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the current execution time.
+ */
+static inline unsigned long long
+rtems_capture_task_time (rtems_capture_task_t* task)
+{
+ unsigned long long t = task->ticks;
+ return (t * rtems_capture_tick_time ()) + task->tick_offset;;
+}
+
+/**
+ * rtems_capture_task_delta_time
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the execution time as a different between the
+ * last time the detla time was and now.
+ */
+static inline unsigned long long
+rtems_capture_task_delta_time (rtems_capture_task_t* task)
+{
+ unsigned long long t = task->ticks - task->last_ticks;
+ uint32_t o = task->tick_offset - task->last_tick_offset;
+
+ task->last_ticks = task->ticks;
+ task->last_tick_offset = task->tick_offset;
+
+ return (t * rtems_capture_tick_time ()) + o;
+}
+
+/**
+ * rtems_capture_task_count
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the number of tasks the capture
+ * engine knows about.
+ */
+static inline uint32_t
+rtems_capture_task_count ()
+{
+ rtems_capture_task_t* task = rtems_capture_get_task_list ();
+ uint32_t count = 0;
+
+ while (task)
+ {
+ count++;
+ task = rtems_capture_next_task (task);
+ }
+
+ return count;
+}
+
+/**
+ * rtems_capture_get_control_list
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the head of the list of controls in the
+ * capture engine.
+ */
+rtems_capture_control_t*
+rtems_capture_get_control_list ();
+
+/**
+ * rtems_capture_next_control
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the pointer to the next control in the list. The
+ * pointer NULL terminates the list.
+ */
+static inline rtems_capture_control_t*
+rtems_capture_next_control (rtems_capture_control_t* control)
+{
+ return control->next;
+}
+
+/**
+ * rtems_capture_control_id
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the control id.
+ */
+static inline rtems_id
+rtems_capture_control_id (rtems_capture_control_t* control)
+{
+ return control->id;
+}
+
+/**
+ * rtems_capture_control_name
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the control name.
+ */
+static inline rtems_name
+rtems_capture_control_name (rtems_capture_control_t* control)
+{
+ return control->name;
+}
+
+/**
+ * rtems_capture_control_flags
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the control flags.
+ */
+static inline uint32_t
+rtems_capture_control_flags (rtems_capture_control_t* control)
+{
+ return control->flags;
+}
+
+/**
+ * rtems_capture_control_from_name
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the control from task name.
+ */
+static inline rtems_name
+rtems_capture_control_from_name (rtems_capture_control_t* control, int from)
+{
+ if (from < RTEMS_CAPTURE_TRIGGER_TASKS)
+ return control->from[from];
+ return control->from[0];
+}
+
+/**
+ * rtems_capture_control_from_id
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the control from task id.
+ */
+static inline rtems_id
+rtems_capture_control_from_id (rtems_capture_control_t* control, int from)
+{
+ if (from < RTEMS_CAPTURE_TRIGGER_TASKS)
+ return control->from_id[from];
+ return control->from_id[0];
+}
+
+/**
+ * rtems_capture_control_count
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the number of controls the capture
+ * engine has.
+ */
+static inline uint32_t
+rtems_capture_control_count ()
+{
+ rtems_capture_control_t* control = rtems_capture_get_control_list ();
+ uint32_t count = 0;
+
+ while (control)
+ {
+ count++;
+ control = rtems_capture_next_control (control);
+ }
+
+ return count;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libmisc/cpuuse/README b/cpukit/libmisc/cpuuse/README
new file mode 100644
index 0000000000..bd3cc55e34
--- /dev/null
+++ b/cpukit/libmisc/cpuuse/README
@@ -0,0 +1,14 @@
+#
+# $Id$
+#
+
+This directory contains a CPU usage reported. It provides two
+primary features:
+
+ + provides an educated guess at each task's CPU usage
+
+NOTES:
+
+1. CPU usage is "docked" by a clock tick at each context switch.
+
+
diff --git a/cpukit/libmisc/cpuuse/cpuuse.c b/cpukit/libmisc/cpuuse/cpuuse.c
new file mode 100644
index 0000000000..2906f622df
--- /dev/null
+++ b/cpukit/libmisc/cpuuse/cpuuse.c
@@ -0,0 +1,139 @@
+/*
+ * CPU Usage Reporter
+ *
+ * COPYRIGHT (c) 1989-1999. 1996.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * cpuuse.c,v 1.20 2004/04/17 08:12:01 ralf Exp
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <rtems/cpuuse.h>
+
+uint32_t CPU_usage_Ticks_at_last_reset;
+
+/*PAGE
+ *
+ * CPU_usage_Dump
+ */
+
+void CPU_usage_Dump( void )
+{
+ uint32_t i;
+ uint32_t api_index;
+ Thread_Control *the_thread;
+ Objects_Information *information;
+ uint32_t u32_name;
+ char *cname;
+ char name[5];
+ uint32_t ival, fval;
+ uint32_t total_units = 0;
+
+ for ( api_index = 1 ;
+ api_index <= OBJECTS_APIS_LAST ;
+ api_index++ ) {
+ if ( !_Objects_Information_table[ api_index ] )
+ continue;
+ information = _Objects_Information_table[ api_index ][ 1 ];
+ if ( information ) {
+ for ( i=1 ; i <= information->maximum ; i++ ) {
+ the_thread = (Thread_Control *)information->local_table[ i ];
+
+ if ( the_thread )
+ total_units += the_thread->ticks_executed;
+ }
+ }
+ }
+
+ fprintf(stdout,"CPU Usage by thread\n");
+ fprintf(stdout, " ID NAME TICKS PERCENT\n" );
+
+ for ( api_index = 1 ;
+ api_index <= OBJECTS_APIS_LAST ;
+ api_index++ ) {
+ if ( !_Objects_Information_table[ api_index ] )
+ continue;
+ information = _Objects_Information_table[ api_index ][ 1 ];
+ if ( information ) {
+ for ( i=1 ; i <= information->maximum ; i++ ) {
+ the_thread = (Thread_Control *)information->local_table[ i ];
+
+ if ( !the_thread )
+ continue;
+
+ if ( information->is_string ) {
+ cname = the_thread->Object.name;
+ name[ 0 ] = cname[0];
+ name[ 1 ] = cname[1];
+ name[ 2 ] = cname[2];
+ name[ 3 ] = cname[3];
+ name[ 4 ] = '\0';
+ } else {
+ u32_name = (uint32_t )the_thread->Object.name;
+ name[ 0 ] = (u32_name >> 24) & 0xff;
+ name[ 1 ] = (u32_name >> 16) & 0xff;
+ name[ 2 ] = (u32_name >> 8) & 0xff;
+ name[ 3 ] = (u32_name >> 0) & 0xff;
+ name[ 4 ] = '\0';
+ }
+
+ if ( !isprint(name[0]) ) name[0] = '*';
+ if ( !isprint(name[1]) ) name[1] = '*';
+ if ( !isprint(name[2]) ) name[2] = '*';
+ if ( !isprint(name[3]) ) name[3] = '*';
+
+ ival = total_units ? the_thread->ticks_executed * 10000 / total_units : 0;
+ fval = ival % 100;
+ ival /= 100;
+ fprintf(stdout, "0x%08x %4s %8d %3d.%2.2d\n",
+ the_thread->Object.id,
+ name,
+ the_thread->ticks_executed,
+ ival,
+ fval
+ );
+ }
+ }
+ }
+
+ fprintf(stdout,
+ "\nTicks since last reset = %d\n",
+ _Watchdog_Ticks_since_boot - CPU_usage_Ticks_at_last_reset
+ );
+ fprintf(stdout, "\nTotal Units = %d\n", total_units );
+}
+
+/*PAGE
+ *
+ * CPU_usage_Reset
+ */
+
+static void CPU_usage_Per_thread_handler(
+ Thread_Control *the_thread
+)
+{
+ the_thread->ticks_executed = 0;
+}
+
+void CPU_usage_Reset( void )
+{
+ CPU_usage_Ticks_at_last_reset = _Watchdog_Ticks_since_boot;
+
+ rtems_iterate_over_all_threads(CPU_usage_Per_thread_handler);
+}
diff --git a/cpukit/libmisc/cpuuse/cpuuse.h b/cpukit/libmisc/cpuuse/cpuuse.h
new file mode 100644
index 0000000000..de874e0fcd
--- /dev/null
+++ b/cpukit/libmisc/cpuuse/cpuuse.h
@@ -0,0 +1,40 @@
+/* cpuuse.h
+ *
+ * This include file contains information necessary to utilize
+ * and install the cpu usage reporting mechanism.
+ *
+ * COPYRIGHT (c) 1989-1999. 1996.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef __CPU_USE_h
+#define __CPU_USE_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * CPU_usage_Dump
+ */
+
+void CPU_usage_Dump( void );
+
+/*
+ * CPU_usage_Reset
+ */
+
+void CPU_usage_Reset( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libmisc/devnull/devnull.c b/cpukit/libmisc/devnull/devnull.c
new file mode 100644
index 0000000000..cfc8a750ce
--- /dev/null
+++ b/cpukit/libmisc/devnull/devnull.c
@@ -0,0 +1,184 @@
+/* /dev/null
+ *
+ * Derived from rtems' stub driver.
+ *
+ * Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de)
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/devnull.h>
+#include <rtems/libio.h>
+
+/* null_initialize
+ *
+ * This routine is the null device driver init routine.
+ *
+ * Input parameters:
+ * major - device major number
+ * minor - device minor number
+ * pargp - pointer to parameter block
+ *
+ * Output parameters:
+ * rval - NULL_SUCCESSFUL
+ */
+
+uint32_t NULL_major;
+static char initialized;
+
+rtems_device_driver null_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ rtems_device_driver status;
+
+ if ( !initialized ) {
+ initialized = 1;
+
+ status = rtems_io_register_name(
+ "/dev/null",
+ major,
+ (rtems_device_minor_number) 0
+ );
+
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+
+ NULL_major = major;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* null_open
+ *
+ * This routine is the null device driver open routine.
+ *
+ * Input parameters:
+ * major - device major number
+ * minor - device minor number
+ * pargb - pointer to open parameter block
+ *
+ * Output parameters:
+ * rval - NULL_SUCCESSFUL
+ */
+
+rtems_device_driver null_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ return NULL_SUCCESSFUL;
+}
+
+
+/* null_close
+ *
+ * This routine is the null device driver close routine.
+ *
+ * Input parameters:
+ * major - device major number
+ * minor - device minor number
+ * pargb - pointer to close parameter block
+ *
+ * Output parameters:
+ * rval - NULL_SUCCESSFUL
+ */
+
+rtems_device_driver null_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ return NULL_SUCCESSFUL;
+}
+
+
+/* null_read
+ *
+ * This routine is the null device driver read routine.
+ *
+ * Input parameters:
+ * major - device major number
+ * minor - device minor number
+ * pargp - pointer to read parameter block
+ *
+ * Output parameters:
+ * rval - NULL_SUCCESSFUL
+ */
+
+rtems_device_driver null_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ return NULL_SUCCESSFUL;
+}
+
+
+/* null_write
+ *
+ * This routine is the null device driver write routine.
+ *
+ * Input parameters:
+ * major - device major number
+ * minor - device minor number
+ * pargp - pointer to write parameter block
+ *
+ * Output parameters:
+ * rval - NULL_SUCCESSFUL
+ */
+
+rtems_device_driver null_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) pargp;
+
+ if ( rw_args )
+ rw_args->bytes_moved = rw_args->count;
+
+ return NULL_SUCCESSFUL;
+}
+
+
+/* null_control
+ *
+ * This routine is the null device driver control routine.
+ *
+ * Input parameters:
+ * major - device major number
+ * minor - device minor number
+ * pargp - pointer to cntrl parameter block
+ *
+ * Output parameters:
+ * rval - NULL_SUCCESSFUL
+ */
+
+rtems_device_driver null_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ return NULL_SUCCESSFUL;
+}
diff --git a/cpukit/libmisc/devnull/devnull.h b/cpukit/libmisc/devnull/devnull.h
new file mode 100644
index 0000000000..6fdf3b6850
--- /dev/null
+++ b/cpukit/libmisc/devnull/devnull.h
@@ -0,0 +1,71 @@
+/* devnull.h
+ *
+ * Null device driver, derived from rtems' stub driver.
+ *
+ * Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de)
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef __NULL_DRIVER_h
+#define __NULL_DRIVER_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DEVNULL_DRIVER_TABLE_ENTRY \
+ { null_initialize, null_open, null_close, null_read, \
+ null_write, null_control }
+
+#define NULL_SUCCESSFUL RTEMS_SUCCESSFUL
+
+rtems_device_driver null_initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver null_open(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver null_close(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver null_read(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver null_write(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver null_control(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libmisc/dummy/README b/cpukit/libmisc/dummy/README
new file mode 100644
index 0000000000..03bb30834d
--- /dev/null
+++ b/cpukit/libmisc/dummy/README
@@ -0,0 +1,23 @@
+dummy.rel
+=========
+
+A relocatible objects which contains a dummy configuration for RTEMS.
+
+Helps linking standard c-program code with RTEMS, which shall *not* be run
+on a target, such as configure script code fragments generated by autoconf's
+AC_TRY_LINK.
+
+Example:
+
+tar xzvf somepkg.tar.gz
+cd somepkg
+
+LDFLAGS=/usr/local/rtems/<cpu>-rtems/<bsp>/lib/dummy.rel \
+CC="<cpu>-rtems-gcc \
+-B/usr/local/rtems/<cpu>-rtems/<bsp>/lib/ -specs bsp_specs -qrtems" \
+CC_FOR_BUILD="gcc" \
+configure --host=<cpu>-rtems --build=i686-pc-linux-gnu
+make
+
+History:
+Starting dummy.c with a copy of rtems-19990528/c/src/tests/samples/minimum/init.c
diff --git a/cpukit/libmisc/dummy/dummy.c b/cpukit/libmisc/dummy/dummy.c
new file mode 100644
index 0000000000..c59114375c
--- /dev/null
+++ b/cpukit/libmisc/dummy/dummy.c
@@ -0,0 +1,45 @@
+/* Init
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+rtems_task Init(
+ rtems_task_argument ignored
+)
+{
+}
+
+int main( int, char **, char **);
+
+/* configuration information */
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+#define CONFIGURE_MAXIMUM_TASKS 10
+#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 20
+#define CONFIGURE_INIT_TASK_ENTRY_POINT (void *)main
+
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+/* global variables */
diff --git a/cpukit/libmisc/dumpbuf/dumpbuf.c b/cpukit/libmisc/dumpbuf/dumpbuf.c
new file mode 100644
index 0000000000..120a464a90
--- /dev/null
+++ b/cpukit/libmisc/dumpbuf/dumpbuf.c
@@ -0,0 +1,79 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <rtems/dumpbuf.h>
+
+/*
+ * Put the body below Dump_Buffer so it won't get inlined.
+ */
+
+static inline void Dump_Line(
+ unsigned char *buffer,
+ int length
+);
+
+void Dump_Buffer(
+ unsigned char *buffer,
+ int length
+)
+{
+
+ int i, mod, max;
+
+ if ( !length ) return;
+
+ mod = length % 16;
+
+ max = length - mod;
+
+ for ( i=0 ; i<max ; i+=16 )
+ Dump_Line( &buffer[ i ], 16 );
+
+ if ( mod )
+ Dump_Line( &buffer[ max ], mod );
+}
+
+static inline void Dump_Line(
+ unsigned char *buffer,
+ int length
+)
+{
+
+ int i;
+ char line_buffer[120];
+
+ line_buffer[0] = '\0';
+
+ for( i=0 ; i<length ; i++ )
+ sprintf( line_buffer, "%s%02x ", line_buffer, buffer[ i ] );
+
+ for( ; i<16 ; i++ )
+ strcat( line_buffer, " " );
+
+ strcat( line_buffer, "|" );
+ for( i=0 ; i<length ; i++ )
+ sprintf( line_buffer, "%s%c", line_buffer,
+ isprint( buffer[ i ] ) ? buffer[ i ] : '.' );
+
+ for( ; i<16 ; i++ )
+ strcat( line_buffer, " " );
+
+ strcat( line_buffer, "|\n" );
+
+ fprintf(stdout, line_buffer );
+}
diff --git a/cpukit/libmisc/dumpbuf/dumpbuf.h b/cpukit/libmisc/dumpbuf/dumpbuf.h
new file mode 100644
index 0000000000..965d1297d0
--- /dev/null
+++ b/cpukit/libmisc/dumpbuf/dumpbuf.h
@@ -0,0 +1,29 @@
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef __DUMP_BUFFER_h
+#define __DUMP_BUFFER_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void Dump_Buffer(
+ unsigned char *buffer,
+ int length
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libmisc/fsmount/README b/cpukit/libmisc/fsmount/README
new file mode 100644
index 0000000000..88bfda62e7
--- /dev/null
+++ b/cpukit/libmisc/fsmount/README
@@ -0,0 +1,24 @@
+#
+#
+# fsmount information
+#
+# Author: Thomas Doerfler 02/07/2003
+#
+# README,v 1.1 1999/07/09 17:23:15 joel Exp
+#
+
+fsmount.c contains the function fsmount. It processes the
+fs table given as an parameter to create the listed mount points
+and mount the corresponding file systems to their mount points.
+See "c/src/tests/samples/fileio" for a sample on how to use this
+function.
+
+The field "report_reasons" specifies, what results of the mount point
+creation/mount operations should print to the console.
+
+The field "abort_reasons" specifies, what results of the mount point
+creation/mount operations should abort the function. Do not set the
+"abort_reasons" bit, unless you want to stop the processing of the
+fsmount table after the first successful mount.
+
+
diff --git a/cpukit/libmisc/fsmount/fsmount.c b/cpukit/libmisc/fsmount/fsmount.c
new file mode 100644
index 0000000000..7d1bf09139
--- /dev/null
+++ b/cpukit/libmisc/fsmount/fsmount.c
@@ -0,0 +1,200 @@
+/*===============================================================*\
+| Project: RTEMS fsmount |
++-----------------------------------------------------------------+
+| File: fsmount.c |
++-----------------------------------------------------------------+
+| Copyright (c) 2003 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file contains the fsmount functions. These functions |
+| are used to mount a list of filesystems (and create their mount |
+| points before) |
+| |
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| http://www.rtems.com/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 02.07.03 creation doe |
+\*===============================================================*/
+
+#ifndef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/fsmount.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <rtems/imfs.h>
+#include <sys/stat.h>
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int rtems_fsmount_create_mountpoint
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| This function will create the mount point given |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ const char *mount_point
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+{
+ int rc = 0;
+ char *tok_buffer = NULL;
+ char *token = NULL;
+ int token_len;
+ size_t total_len;
+ IMFS_token_types token_type;
+ struct stat file_info;
+ /*
+ * allocate temp memory to rebuild path name
+ */
+ tok_buffer = calloc(strlen(mount_point)+1,sizeof(char));
+ token = tok_buffer;
+ total_len = 0;
+ do {
+ /*
+ * scan through given string, one segment at a time
+ */
+ token_type = IMFS_get_token(mount_point+total_len,token,&token_len);
+ total_len += token_len;
+ strncpy(tok_buffer,mount_point,total_len);
+ tok_buffer[total_len] = '\0';
+
+ if ((token_type != IMFS_NO_MORE_PATH) &&
+ (token_type != IMFS_CURRENT_DIR) &&
+ (token_type != IMFS_INVALID_TOKEN)) {
+ /*
+ * check, whether segment exists
+ */
+ if (0 != stat(tok_buffer,&file_info)) {
+ /*
+ * if not, create directory
+ */
+ rc = mknod(tok_buffer,S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR,0);
+ }
+ }
+ } while ((rc == 0) &&
+ (token_type != IMFS_NO_MORE_PATH) &&
+ (token_type != IMFS_INVALID_TOKEN));
+
+ /*
+ * return token buffer to heap
+ */
+ if (tok_buffer != NULL) {
+ free(tok_buffer);
+ }
+ return rc;
+}
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int rtems_fsmount
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| This function will create the mount points listed and mount the file |
+| systems listed in the calling parameters |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ const fstab_t *fstab_ptr,
+ int fstab_count,
+ int *fail_idx
+ )
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+{
+ int rc = 0;
+ int tmp_rc;
+ int fstab_idx = 0;
+ rtems_filesystem_mount_table_entry_t *tmp_mt_entry;
+ boolean terminate = FALSE;
+
+ /*
+ * scan through all fstab entries;
+ */
+ while (!terminate &&
+ (fstab_idx < fstab_count)) {
+ tmp_rc = 0;
+ /*
+ * create mount point
+ */
+ if (tmp_rc == 0) {
+ tmp_rc = rtems_fsmount_create_mountpoint(fstab_ptr->mount_point);
+ if (tmp_rc != 0) {
+ if (0 != (fstab_ptr->report_reasons & FSMOUNT_MNTPNT_CRTERR)) {
+ fprintf(stdout,"fsmount: creation of mount point \"%s\" failed: %s\n",
+ fstab_ptr->mount_point,
+ strerror(errno));
+ }
+ if (0 != (fstab_ptr->abort_reasons & FSMOUNT_MNTPNT_CRTERR)) {
+ terminate = TRUE;
+ rc = tmp_rc;
+ }
+ }
+ }
+ /*
+ * mount device to given mount point
+ */
+ if (tmp_rc == RTEMS_SUCCESSFUL) {
+ tmp_rc = mount(&tmp_mt_entry,
+ fstab_ptr->fs_ops,
+ fstab_ptr->mount_options,
+ fstab_ptr->dev,
+ fstab_ptr->mount_point);
+ if (tmp_rc != RTEMS_SUCCESSFUL) {
+ if (0 != (fstab_ptr->report_reasons & FSMOUNT_MNT_FAILED)) {
+ fprintf(stdout,"fsmount: mounting of \"%s\" to"
+ " \"%s\" failed: %s\n",
+ fstab_ptr->dev,
+ fstab_ptr->mount_point,
+ strerror(errno));
+ }
+ if (0 != (fstab_ptr->abort_reasons & FSMOUNT_MNT_FAILED)) {
+ terminate = TRUE;
+ rc = tmp_rc;
+ }
+ }
+ else {
+ if (0 != (fstab_ptr->report_reasons & FSMOUNT_MNT_OK)) {
+ fprintf(stdout,"fsmount: mounting of \"%s\" to"
+ " \"%s\" succeeded\n",
+ fstab_ptr->dev,
+ fstab_ptr->mount_point);
+ }
+ if (0 != (fstab_ptr->abort_reasons & FSMOUNT_MNT_OK)) {
+ terminate = TRUE;
+ }
+ }
+ }
+ /*
+ * proceed to next entry
+ */
+ if (!terminate) {
+ fstab_ptr++;
+ fstab_idx++;
+ }
+ }
+ if (fail_idx != NULL) {
+ *fail_idx = fstab_idx;
+ }
+ return rc;
+}
diff --git a/cpukit/libmisc/fsmount/fsmount.h b/cpukit/libmisc/fsmount/fsmount.h
new file mode 100644
index 0000000000..395e35b93f
--- /dev/null
+++ b/cpukit/libmisc/fsmount/fsmount.h
@@ -0,0 +1,81 @@
+/*===============================================================*\
+| Project: RTEMS fsmount |
++-----------------------------------------------------------------+
+| File: fsmount.h |
++-----------------------------------------------------------------+
+| Copyright (c) 2003 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file contains the fsmount functions. These functions |
+| are used to mount a list of filesystems (and create their mount |
+| points before) |
+| |
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| http://www.rtems.com/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 02.07.03 creation doe |
+\*===============================================================*/
+
+#ifndef _FSMOUNT_H
+#define _FSMOUNT_H
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * bits to define, what errors will cause reporting (via printf) and
+ * abort of mount processing
+ * Use a combination of these bits
+ * for the fields "report_reasons" and "abort_reasons"
+ */
+#define FSMOUNT_MNT_OK 0x0001 /* mounted ok */
+#define FSMOUNT_MNTPNT_CRTERR 0x0002 /* cannot create mount point */
+#define FSMOUNT_MNT_FAILED 0x0004 /* mounting failed */
+
+typedef struct {
+ char *dev;
+ char *mount_point;
+ rtems_filesystem_operations_table *fs_ops;
+ rtems_filesystem_options_t mount_options;
+ uint16_t report_reasons;
+ uint16_t abort_reasons;
+} fstab_t;
+
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int rtems_fsmount
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| This function will create the mount points listed and mount the file |
+| systems listed in the calling parameters |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ const fstab_t *fstab_ptr, /* Ptr to filesystem mount table */
+ int fstab_count, /* number of entries in mount table*/
+ int *fail_idx /* return: index of failed entry */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0, if success, -1 and errno if failed |
+\*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FSMOUNT_H */
diff --git a/cpukit/libmisc/monitor/README b/cpukit/libmisc/monitor/README
new file mode 100644
index 0000000000..d5a73da140
--- /dev/null
+++ b/cpukit/libmisc/monitor/README
@@ -0,0 +1,97 @@
+#
+# $Id$
+#
+
+monitor task
+
+The monitor task is an optional task that knows about RTEMS
+data structures and can print out information about them.
+It is a work-in-progress and needs many more commands, but
+is useful now.
+
+The monitor works best when it is the highest priority task,
+so all your other tasks should ideally be at some priority
+greater than 1.
+
+To use the monitor:
+-------------------
+
+ #include <rtems/monitor.h>
+
+ ...
+
+ rtems_monitor_init(0);
+
+ The parameter to rtems_monitor_init() tells the monitor whether
+ to suspend itself on startup. A value of 0 causes the monitor
+ to immediately enter command mode; a non-zero value causes the
+ monitor to suspend itself after creation and wait for explicit
+ wakeup.
+
+
+ rtems_monitor_wakeup();
+
+ wakes up a suspended monitor and causes it to reenter command mode.
+
+Monitor commands
+----------------
+
+ The monitor prompt is 'rtems> '.
+ Can abbreviate commands to "uniquity"
+ There is a 'help' command. Here is the output from various
+ help commands:
+
+ Commands (may be abbreviated)
+
+ help -- get this message or command specific help
+ task -- show task information
+ queue -- show message queue information
+ symbol -- show entries from symbol table
+ pause -- pause monitor for a specified number of ticks
+ fatal -- invoke a fatal RTEMS error
+
+ task [id [id ...] ]
+ display information about the specified tasks.
+ Default is to display information about all tasks on this node
+
+ queue [id [id ... ] ]
+ display information about the specified message queues
+ Default is to display information about all queues on this node
+
+ symbol [ symbolname [symbolname ... ] ]
+ display value associated with specified symbol.
+ Defaults to displaying all known symbols.
+
+ pause [ticks]
+ monitor goes to "sleep" for specified ticks (default is 1)
+ monitor will resume at end of period or if explicitly awakened
+
+ fatal [status]
+ Invoke 'rtems_fatal_error_occurred' with 'status'
+ (default is RTEMS_INTERNAL_ERROR)
+
+ continue
+ put the monitor to sleep waiting for an explicit wakeup from the
+ program running.
+
+
+Sample output from 'task' command
+---------------------------------
+
+ rtems> task
+ ID NAME PRIO STAT MODES EVENTS WAITID WAITARG NOTES
+ ------------------------------------------------------------------------
+ 00010001 UI1 2 READY P:T:nA NONE15: 0x40606348
+ 00010002 RMON 1 READY nP NONE15: 0x40604110
+
+ 'RMON' is the monitor itself, so we have 1 "user" task.
+ Its modes are P:T:nA which translate to:
+
+ preemptable
+ timesliced
+ no ASRS
+
+ It has no events.
+ It has a notepad value for notepad 15 which is 0x40606348
+ (this is the libc thread state)
+
diff --git a/cpukit/libmisc/monitor/mon-command.c b/cpukit/libmisc/monitor/mon-command.c
new file mode 100644
index 0000000000..dc20dcb203
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-command.c
@@ -0,0 +1,745 @@
+/*
+ * Command parsing routines for RTEMS monitor
+ *
+ * TODO:
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/monitor.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef MONITOR_PROMPT
+#define MONITOR_PROMPT "rtems" /* will have '> ' appended */
+#endif
+
+/*
+ * 2001-01-30 KJO (vac4050@cae597.rsc.raytheon.com):
+ * Fixed rtems_monitor_command_lookup() to accept partial
+ * commands to uniqeness. Added support for setting
+ * the monitor prompt via an environment variable:
+ * RTEMS_MONITOR_PROMPT
+ *
+ * CCJ: 26-3-2000, adding command history and command line
+ * editing. This code is donated from My Right Boot and not
+ * covered by GPL, only the RTEMS license.
+ */
+
+/*
+ * Some key labels to define special keys.
+ */
+
+#define KEYS_EXTENDED (0x8000)
+#define KEYS_NORMAL_MASK (0x00ff)
+#define KEYS_INS (0)
+#define KEYS_DEL (1)
+#define KEYS_UARROW (2)
+#define KEYS_DARROW (3)
+#define KEYS_LARROW (4)
+#define KEYS_RARROW (5)
+#define KEYS_HOME (6)
+#define KEYS_END (7)
+#define KEYS_F1 (8)
+#define KEYS_F2 (9)
+#define KEYS_F3 (10)
+#define KEYS_F4 (11)
+#define KEYS_F5 (12)
+#define KEYS_F6 (13)
+#define KEYS_F7 (14)
+#define KEYS_F8 (15)
+#define KEYS_F9 (16)
+#define KEYS_F10 (17)
+
+#define RTEMS_COMMAND_BUFFER_SIZE (75)
+
+static char monitor_prompt[32];
+#ifndef RTEMS_UNIX
+static char buffer[RTEMS_COMMAND_BUFFER_SIZE];
+static int pos;
+static int logged_in;
+#endif
+/*
+ * History data.
+ */
+
+#define RTEMS_COMMAND_HISTORIES (20)
+
+#ifndef RTEMS_UNIX
+static char history_buffer[RTEMS_COMMAND_HISTORIES][RTEMS_COMMAND_BUFFER_SIZE];
+static int history_pos[RTEMS_COMMAND_HISTORIES];
+static int history;
+static int history_next;
+#endif
+
+/*
+ * Translation tables. Not sure if this is the best way to
+ * handle this, how-ever I wish to avoid the overhead of
+ * including a more complete and standard environment such
+ * as ncurses.
+ */
+
+struct translation_table
+{
+ char expecting;
+ struct translation_table *branch;
+ unsigned int key;
+};
+
+#ifndef RTEMS_UNIX
+static struct translation_table trans_two[] =
+{
+ { '~', 0, KEYS_INS },
+ { 0, 0, 0 }
+};
+
+static struct translation_table trans_three[] =
+{
+ { '~', 0, KEYS_DEL },
+ { 0, 0, 0 }
+};
+
+static struct translation_table trans_tab_csi[] =
+{
+ { '2', trans_two, 0 },
+ { '3', trans_three, 0 },
+ { 'A', 0, KEYS_UARROW },
+ { 'B', 0, KEYS_DARROW },
+ { 'D', 0, KEYS_LARROW },
+ { 'C', 0, KEYS_RARROW },
+ { 'F', 0, KEYS_END },
+ { 'H', 0, KEYS_HOME },
+ { 0, 0, 0 }
+};
+
+static struct translation_table trans_tab_O[] =
+{
+ { '1', 0, KEYS_F1 },
+ { '2', 0, KEYS_F2 },
+ { '3', 0, KEYS_F3 },
+ { '4', 0, KEYS_F4 },
+ { '5', 0, KEYS_F5 },
+ { '6', 0, KEYS_F6 },
+ { '7', 0, KEYS_F7 },
+ { '8', 0, KEYS_F8 },
+ { '9', 0, KEYS_F9 },
+ { ':', 0, KEYS_F10 },
+ { 'P', 0, KEYS_F1 },
+ { 'Q', 0, KEYS_F2 },
+ { 'R', 0, KEYS_F3 },
+ { 'S', 0, KEYS_F4 },
+ { 'T', 0, KEYS_F5 },
+ { 'U', 0, KEYS_F6 },
+ { 'V', 0, KEYS_F7 },
+ { 'W', 0, KEYS_F8 },
+ { 'X', 0, KEYS_F9 },
+ { 'Y', 0, KEYS_F10 },
+ { 0, 0, 0 }
+};
+
+static struct translation_table trans_tab[] =
+{
+ { '[', trans_tab_csi, 0 }, /* CSI command sequences */
+ { 'O', trans_tab_O, 0 }, /* O are the fuction keys */
+ { 0, 0, 0 }
+};
+#endif
+
+/*
+ * Perform a basic tranlation for some ANSI/VT100 key codes.
+ * This code could do with a timeout on the ESC as it is
+ * now lost from the input stream. It is not* used by the
+ * line editor below so considiered not worth the effort.
+ */
+
+#ifndef RTEMS_UNIX
+static unsigned int
+rtems_monitor_getchar (
+)
+{
+ struct translation_table *translation = 0;
+ for (;;)
+ {
+ char c = getchar ();
+ if (c == 27)
+ translation = trans_tab;
+ else
+ {
+ /*
+ * If no translation happing just pass through
+ * and return the key.
+ */
+ if (translation)
+ {
+ /*
+ * Scan the current table for the key, and if found
+ * see if this key is a fork. If so follow it and
+ * wait else return the extended key.
+ */
+ int index = 0;
+ int branched = 0;
+ while ((translation[index].expecting != '\0') ||
+ (translation[index].key != '\0'))
+ {
+ if (translation[index].expecting == c)
+ {
+ /*
+ * A branch is take if more keys are to come.
+ */
+ if (translation[index].branch == 0)
+ return KEYS_EXTENDED | translation[index].key;
+ else
+ {
+ translation = translation[index].branch;
+ branched = 1;
+ break;
+ }
+ }
+ index++;
+ }
+ /*
+ * Who knows what these keys are, just drop them.
+ */
+ if (!branched)
+ translation = 0;
+ }
+ else
+ return c;
+ }
+ }
+}
+#endif
+
+#ifndef RTEMS_UNIX
+/*
+ * The line editor with history.
+ */
+
+static int
+rtems_monitor_line_editor (
+ char *command
+)
+{
+ int repeating = 0;
+
+ memset (buffer, 0, RTEMS_COMMAND_BUFFER_SIZE);
+ history = history_next;
+ pos = 0;
+
+ if (!logged_in)
+ fprintf(stdout,"\nMonitor ready, press enter to login.\n\n");
+ else
+ fprintf(stdout,"%s $ ", monitor_prompt);
+
+ while (1)
+ {
+ unsigned int extended_key = rtems_monitor_getchar ();
+ char c = extended_key & KEYS_NORMAL_MASK;
+
+ /*
+ * Make the extended_key usable as a boolean.
+ */
+ extended_key &= ~KEYS_NORMAL_MASK;
+
+ if (!extended_key && !logged_in)
+ {
+ if (c == '\n')
+ {
+ logged_in = 1;
+ /*
+ * The prompt has changed from `>' to `$' to help know
+ * which version of the monitor code people are using.
+ */
+ fprintf(stdout,"%s $ ", monitor_prompt);
+ }
+ }
+ else
+ {
+ if (extended_key)
+ {
+ switch (c)
+ {
+ case KEYS_END:
+ fprintf(stdout,buffer + pos);
+ pos = (int) strlen (buffer);
+ break;
+
+ case KEYS_HOME:
+ fprintf(stdout,"\r%s $ ", monitor_prompt);
+ pos = 0;
+ break;
+
+ case KEYS_LARROW:
+ if (pos > 0)
+ {
+ pos--;
+ putchar ('\b');
+ }
+ break;
+
+ case KEYS_RARROW:
+ if ((pos < RTEMS_COMMAND_BUFFER_SIZE) && (buffer[pos] != '\0'))
+ {
+ putchar (buffer[pos]);
+ pos++;
+ }
+ break;
+
+ case KEYS_UARROW:
+ /*
+ * If we are moving up the histories then we need to save the working
+ * buffer.
+ */
+ if (history)
+ {
+ int end;
+ int bs;
+ if (history == history_next)
+ {
+ memcpy (history_buffer[history_next], buffer,
+ RTEMS_COMMAND_BUFFER_SIZE);
+ history_pos[history_next] = pos;
+ }
+ history--;
+ memcpy (buffer, history_buffer[history],
+ RTEMS_COMMAND_BUFFER_SIZE);
+ pos = history_pos[history];
+ fprintf(stdout,"\r%*c", RTEMS_COMMAND_BUFFER_SIZE, ' ');
+ fprintf(stdout,"\r%s $ %s", monitor_prompt, buffer);
+ end = (int) strlen (buffer);
+ for (bs = 0; bs < (end - pos); bs++)
+ putchar ('\b');
+ }
+ break;
+
+ case KEYS_DARROW:
+ if (history < history_next)
+ {
+ int end;
+ int bs;
+ history++;
+ memcpy (buffer, history_buffer[history],
+ RTEMS_COMMAND_BUFFER_SIZE);
+ pos = history_pos[history];
+ fprintf(stdout,"\r%*c", RTEMS_COMMAND_BUFFER_SIZE, ' ');
+ fprintf(stdout,"\r%s $ %s", monitor_prompt, buffer);
+ end = (int) strlen (buffer);
+ for (bs = 0; bs < (end - pos); bs++)
+ putchar ('\b');
+ }
+ break;
+
+ case KEYS_DEL:
+ if (buffer[pos] != '\0')
+ {
+ int end;
+ int bs;
+ strcpy (&buffer[pos], &buffer[pos + 1]);
+ fprintf(stdout,"\r%s $ %s", monitor_prompt, buffer);
+ end = (int) strlen (buffer);
+ for (bs = 0; bs < (end - pos); bs++)
+ putchar ('\b');
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch (c)
+ {
+ case '\b':
+ case '\x7e':
+ case '\x7f':
+ if (pos > 0)
+ {
+ int bs;
+ pos--;
+ strcpy (buffer + pos, buffer + pos + 1);
+ fprintf(stdout,"\b%s \b", buffer + pos);
+ for (bs = 0; bs < ((int) strlen (buffer) - pos); bs++)
+ putchar ('\b');
+ }
+ break;
+
+ case '\n':
+ /*
+ * Process the command.
+ */
+ fprintf(stdout,"\n");
+ repeating = 1;
+ /*
+ * Only process the history if we have a command and
+ *a history.
+ */
+ if (strlen (buffer))
+ {
+ if (history_next && (history == history_next))
+ {
+ /*
+ * Do not place the last command into the history
+ *if the same.
+ */
+ if (strcmp (history_buffer[history_next - 1], buffer))
+ repeating = 0;
+ }
+ else
+ repeating = 0;
+ }
+ if (!repeating)
+ {
+ memcpy (history_buffer[history_next], buffer,
+ RTEMS_COMMAND_BUFFER_SIZE);
+ history_pos[history_next] = pos;
+ if (history_next < (RTEMS_COMMAND_HISTORIES - 1))
+ history_next++;
+ else
+ {
+ memmove (history_buffer[0], history_buffer[1],
+ RTEMS_COMMAND_BUFFER_SIZE * (RTEMS_COMMAND_HISTORIES - 1));
+ memmove (&history_pos[0], &history_pos[1],
+ sizeof (history_pos[0]) * (RTEMS_COMMAND_HISTORIES - 1));
+ }
+ }
+ else
+ {
+#ifdef ENABLE_ENTER_REPEATS
+ if (history_next)
+ memcpy (buffer, history_buffer[history_next - 1],
+ RTEMS_COMMAND_BUFFER_SIZE);
+#endif
+ }
+ memmove (command, buffer, RTEMS_COMMAND_BUFFER_SIZE);
+ return repeating;
+ break;
+
+ default:
+ if ((pos < (RTEMS_COMMAND_BUFFER_SIZE - 1)) &&
+ (c >= ' ') && (c <= 'z'))
+ {
+ int end;
+ end = strlen (buffer);
+ if ((pos < end) && (end < RTEMS_COMMAND_BUFFER_SIZE))
+ {
+ int ch, bs;
+ for (ch = end + 1; ch > pos; ch--)
+ buffer[ch] = buffer[ch - 1];
+ fprintf(stdout,buffer + pos);
+ for (bs = 0; bs < (end - pos + 1); bs++)
+ putchar ('\b');
+ }
+ buffer[pos++] = c;
+ if (pos > end)
+ buffer[pos] = '\0';
+ putchar (c);
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+#endif
+
+/*
+ * make_argv(cp): token-count
+ * Break up the command line in 'cp' into global argv[] and argc (return
+ * value).
+ */
+
+int
+rtems_monitor_make_argv(
+ char *cp,
+ int *argc_p,
+ char **argv)
+{
+ int argc = 0;
+
+ while ((cp = strtok(cp, " \t\n\r")))
+ {
+ argv[argc++] = cp;
+ cp = (char *) NULL;
+ }
+ argv[argc] = (char *) NULL; /* end of argv */
+
+ return *argc_p = argc;
+}
+
+
+/*
+ * Read and break up a monitor command
+ *
+ * We have to loop on the gets call, since it will return NULL under UNIX
+ * RTEMS when we get a signal (eg: SIGALRM).
+ */
+
+int
+rtems_monitor_command_read(char *command,
+ int *argc,
+ char **argv)
+{
+ char *env_prompt;
+
+ env_prompt = getenv("RTEMS_MONITOR_PROMPT");
+
+ /*
+ * put node number in the prompt if we are multiprocessing
+ */
+ if (!rtems_configuration_get_user_multiprocessing_table ())
+ sprintf (monitor_prompt, "%s",
+ (env_prompt == NULL) ? MONITOR_PROMPT: env_prompt);
+ else if (rtems_monitor_default_node != rtems_monitor_node)
+ sprintf (monitor_prompt, "%d-%s-%d", rtems_monitor_node,
+ (env_prompt == NULL) ? MONITOR_PROMPT : env_prompt,
+ rtems_monitor_default_node);
+ else
+ sprintf (monitor_prompt, "%d-%s", rtems_monitor_node,
+ (env_prompt == NULL) ? MONITOR_PROMPT : env_prompt);
+
+#if defined(RTEMS_UNIX)
+ /* RTEMS on unix gets so many interrupt system calls this is hosed */
+ fprintf(stdout,"%s> ", monitor_prompt);
+ fflush (stdout);
+ while (gets(command) == (char *) 0)
+ ;
+#else
+ rtems_monitor_line_editor (command);
+#endif
+
+ return rtems_monitor_make_argv (command, argc, argv);
+}
+
+/*
+ * Look up a command in a command table
+ *
+ */
+
+rtems_monitor_command_entry_t *
+rtems_monitor_command_lookup(
+ rtems_monitor_command_entry_t *table,
+ int argc,
+ char **argv
+)
+{
+ int command_length;
+ rtems_monitor_command_entry_t *found_it = NULL;
+
+ command_length = strlen (argv[0]);
+
+ if ((table == 0) || (argv[0] == 0))
+ return 0;
+
+ while (table)
+ {
+ if (table->command)
+ {
+
+ /*
+ * Check for ambiguity
+ */
+ if (!strncmp (table->command, argv[0], command_length))
+ {
+ if (found_it)
+ {
+ return 0;
+ }
+
+ else
+ found_it = table;
+ }
+ }
+ table = table->next;
+ }
+
+ /*
+ * No ambiguity (the possible partial command was unique after all)
+ */
+ if (found_it)
+ {
+ if (found_it->command_function == 0)
+ return 0;
+
+ return found_it;
+ }
+
+ return 0;
+}
+
+static void
+rtems_monitor_show_help (
+ rtems_monitor_command_entry_t *help_cmd,
+ int max_cmd_len
+)
+{
+#define MAX_HELP_LINE_LENGTH (75 - max_cmd_len - 2)
+
+ if (help_cmd && help_cmd->command)
+ {
+ const char *help = help_cmd->usage;
+ int help_len = strlen (help);
+ int spaces = max_cmd_len - strlen (help_cmd->command);
+ int show_this_line = 0;
+ int line_one = 1;
+ int c;
+
+ fprintf(stdout,"%s", help_cmd->command);
+
+ if (help_len == 0)
+ {
+ fprintf(stdout," - No help associated.\n");
+ return;
+ }
+
+ while (help_len)
+ {
+ fprintf(stdout,"%*c", spaces, ' ');
+
+ if (line_one)
+ fprintf(stdout," - ");
+
+ spaces = max_cmd_len + 2;
+ line_one = 0;
+
+ /*
+ * See if greater then the line length if so, work back
+ * from the end for a space, tab or lf or cr.
+ */
+
+ if (help_len > MAX_HELP_LINE_LENGTH)
+ {
+ for (show_this_line = MAX_HELP_LINE_LENGTH - 1;
+ show_this_line;
+ show_this_line--)
+ if ((help[show_this_line] == ' ') ||
+ (help[show_this_line] == '\n') ||
+ (help[show_this_line] == '\r'))
+ break;
+
+ /*
+ * If show_this_line is 0, it is a very long word !!
+ */
+
+ if (show_this_line == 0)
+ show_this_line = MAX_HELP_LINE_LENGTH - 1;
+ }
+ else
+ show_this_line = help_len;
+
+ for (c = 0; c < show_this_line; c++)
+ if ((help[c] == '\r') || (help[c] == '\n'))
+ show_this_line = c;
+ else
+ putchar (help[c]);
+
+ fprintf(stdout,"\n");
+
+ help += show_this_line;
+ help_len -= show_this_line;
+
+ /*
+ * Move past the line feeds or what ever else is being skipped.
+ */
+
+ while (help_len)
+ {
+ if ((*help != '\r') && (*help != '\n'))
+ break;
+
+ if (*help != ' ')
+ {
+ help++;
+ help_len--;
+ break;
+ }
+ help++;
+ help_len--;
+ }
+ }
+ }
+}
+
+void
+rtems_monitor_command_usage(
+ rtems_monitor_command_entry_t *table,
+ char *command_string
+)
+{
+ rtems_monitor_command_entry_t *command = table;
+ int max_cmd_len = 0;
+
+ /* if first entry in table is a usage, then print it out */
+
+ if (command_string && (*command_string != '\0'))
+ {
+ char *argv[2];
+
+ argv[0] = command_string;
+ argv[1] = 0;
+
+ command = rtems_monitor_command_lookup (table, 1, argv);
+
+ if (command)
+ rtems_monitor_show_help (command, strlen (command_string));
+ else
+ fprintf(stdout,"Unrecognised command; try just 'help'\n");
+ return;
+ }
+
+ /*
+ * Find the largest command size.
+ */
+
+ while (command)
+ {
+ int len = command->command ? strlen (command->command) : 0 ;
+
+ if (len > max_cmd_len)
+ max_cmd_len = len;
+
+ command = command->next;
+ }
+
+ max_cmd_len++;
+
+ command = table;
+
+ /*
+ * Now some nice formatting for the help.
+ */
+
+ while (command)
+ {
+ rtems_monitor_show_help (command, max_cmd_len);
+ command = command->next;
+ }
+}
+
+
+void
+rtems_monitor_help_cmd(
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose
+)
+{
+ int arg;
+ rtems_monitor_command_entry_t *command;
+
+ command = command_arg->monitor_command_entry;
+
+ if (argc == 1)
+ rtems_monitor_command_usage(command, 0);
+ else
+ {
+ for (arg = 1; argv[arg]; arg++)
+ rtems_monitor_command_usage(command, argv[arg]);
+ }
+}
diff --git a/cpukit/libmisc/monitor/mon-config.c b/cpukit/libmisc/monitor/mon-config.c
new file mode 100644
index 0000000000..0a1780c0eb
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-config.c
@@ -0,0 +1,136 @@
+/*
+ * RTEMS Config display support
+ *
+ * TODO
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+#include <rtems/monitor.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h> /* strtoul() */
+
+#define DATACOL 15
+#define CONTCOL DATACOL /* continued col */
+
+/*
+ * Fill in entire monitor config table
+ * for sending to a remote monitor or printing on the local system
+ */
+
+void
+rtems_monitor_config_canonical(
+ rtems_monitor_config_t *canonical_config,
+ void *config_void
+)
+{
+ rtems_configuration_table *c = (rtems_configuration_table *) config_void;
+ rtems_api_configuration_table *r = c->RTEMS_api_configuration;
+
+ canonical_config->work_space_start = c->work_space_start;
+ canonical_config->work_space_size = c->work_space_size;
+ canonical_config->maximum_tasks = r->maximum_tasks;
+ canonical_config->maximum_timers = r->maximum_timers;
+ canonical_config->maximum_semaphores = r->maximum_semaphores;
+ canonical_config->maximum_message_queues = r->maximum_message_queues;
+ canonical_config->maximum_partitions = r->maximum_partitions;
+ canonical_config->maximum_regions = r->maximum_regions;
+ canonical_config->maximum_ports = r->maximum_ports;
+ canonical_config->maximum_periods = r->maximum_periods;
+ canonical_config->maximum_extensions = c->maximum_extensions;
+ canonical_config->microseconds_per_tick = c->microseconds_per_tick;
+ canonical_config->ticks_per_timeslice = c->ticks_per_timeslice;
+ canonical_config->number_of_initialization_tasks = r->number_of_initialization_tasks;
+}
+
+/*
+ * This is easy, since there is only 1 (altho we could get them from
+ * other nodes...)
+ */
+
+void *
+rtems_monitor_config_next(
+ void *object_info,
+ rtems_monitor_config_t *canonical_config,
+ rtems_id *next_id
+)
+{
+ rtems_configuration_table *c = _Configuration_Table;
+ int n = rtems_get_index(*next_id);
+
+ if (n >= 1)
+ goto failed;
+
+ _Thread_Disable_dispatch();
+
+ *next_id += 1;
+ return (void *) c;
+
+failed:
+ *next_id = RTEMS_OBJECT_ID_FINAL;
+ return 0;
+}
+
+
+void
+rtems_monitor_config_dump_header(
+ boolean verbose
+)
+{
+ fprintf(stdout,"\
+INITIAL (startup) Configuration Info\n");
+/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
+0 1 2 3 4 5 6 7 */
+ rtems_monitor_separator();
+}
+
+
+int
+rtems_monitor_config_dump(
+ rtems_monitor_config_t *monitor_config,
+ boolean verbose
+)
+{
+ int length = 0;
+
+ length = 0;
+ length += fprintf(stdout,"WORKSPACE");
+ length += rtems_monitor_pad(DATACOL, length);
+ length += fprintf(stdout,"start: %p; size: 0x%" PRIx32 "\n",
+ monitor_config->work_space_start,
+ monitor_config->work_space_size);
+
+ length = 0;
+ length += fprintf(stdout,"TIME");
+ length += rtems_monitor_pad(DATACOL, length);
+ length += fprintf(stdout,"usec/tick: %" PRId32 "; tick/timeslice: %" PRId32 "; tick/sec: %" PRId32 "\n",
+ monitor_config->microseconds_per_tick,
+ monitor_config->ticks_per_timeslice,
+ 1000000 / monitor_config->microseconds_per_tick);
+
+ length = 0;
+ length += fprintf(stdout,"MAXIMUMS");
+ length += rtems_monitor_pad(DATACOL, length);
+ length += fprintf(stdout,"tasks: %" PRId32 "; timers: %" PRId32 "; sems: %" PRId32 "; que's: %" PRId32 "; ext's: %" PRId32 "\n",
+ monitor_config->maximum_tasks,
+ monitor_config->maximum_timers,
+ monitor_config->maximum_semaphores,
+ monitor_config->maximum_message_queues,
+ monitor_config->maximum_extensions);
+ length = 0;
+ length += rtems_monitor_pad(CONTCOL, length);
+ length += fprintf(stdout,"partitions: %" PRId32 "; regions: %" PRId32 "; ports: %" PRId32 "; periods: %" PRId32 "\n",
+ monitor_config->maximum_partitions,
+ monitor_config->maximum_regions,
+ monitor_config->maximum_ports,
+ monitor_config->maximum_periods);
+ return length;
+}
diff --git a/cpukit/libmisc/monitor/mon-dname.c b/cpukit/libmisc/monitor/mon-dname.c
new file mode 100644
index 0000000000..4f9cc1aef2
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-dname.c
@@ -0,0 +1,116 @@
+/*
+ * RTEMS monitor driver names support.
+ *
+ * There are 2 "driver" things the monitor knows about.
+ *
+ * 1. Regular RTEMS drivers.
+ * This is a table indexed by major device number and
+ * containing driver entry points only.
+ *
+ * 2. Driver name table.
+ * A separate table of names for drivers.
+ * The table converts driver names to a major number
+ * as index into the driver table and a minor number
+ * for an argument to driver.
+ *
+ * Drivers are displayed with 'driver' command.
+ * Names are displayed with 'dname' command.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+
+#include <rtems/monitor.h>
+
+#include <stdio.h>
+#include <stdlib.h> /* strtoul() */
+#include <string.h> /* strncpy() */
+
+#define DATACOL 15
+#define CONTCOL DATACOL /* continued col */
+
+void
+rtems_monitor_dname_canonical(
+ rtems_monitor_dname_t *canonical_dname,
+ void *dname_void
+)
+{
+ rtems_driver_name_t *np = (rtems_driver_name_t *) dname_void;
+
+ (void) strncpy(canonical_dname->name_string, np->device_name, sizeof(canonical_dname->name_string));
+ canonical_dname->major = np->major;
+ canonical_dname->minor = np->minor;
+}
+
+void *
+rtems_monitor_dname_next(
+ void *object_information,
+ rtems_monitor_dname_t *canonical_dname,
+ rtems_id *next_id
+)
+{
+ uint32_t n = rtems_get_index(*next_id);
+ rtems_driver_name_t *table = _IO_Driver_name_table;
+ rtems_driver_name_t *np = 0;
+
+/* XXX should we be using _IO_Number_of_devices */
+ for (np = table + n ; n<_IO_Number_of_devices; n++, np++)
+ if (np->device_name)
+ goto done;
+
+ *next_id = RTEMS_OBJECT_ID_FINAL;
+ return 0;
+
+done:
+ _Thread_Disable_dispatch();
+
+ /*
+ * dummy up a fake id and name for this item
+ */
+
+ canonical_dname->id = n;
+ canonical_dname->name = rtems_build_name('-', '-', '-', '-');
+
+ *next_id += 1;
+ return np;
+}
+
+void
+rtems_monitor_dname_dump_header(
+ boolean verbose
+)
+{
+ fprintf(stdout,"\
+ Major:Minor Name\n");
+/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
+0 1 2 3 4 5 6 7 */
+ rtems_monitor_separator();
+}
+
+void
+rtems_monitor_dname_dump(
+ rtems_monitor_dname_t *monitor_dname,
+ boolean verbose
+)
+{
+ uint32_t length = 0;
+
+ length += rtems_monitor_pad(6, length);
+ length += rtems_monitor_dump_hex(monitor_dname->major);
+ length += fprintf(stdout,":");
+ length += rtems_monitor_dump_hex(monitor_dname->minor);
+
+ length += rtems_monitor_pad(16, length);
+ length += fprintf(stdout,"%.*s",
+ (int) sizeof(monitor_dname->name_string),
+ (char *) monitor_dname->name_string);
+
+ length += fprintf(stdout,"\n");
+ length = 0;
+}
diff --git a/cpukit/libmisc/monitor/mon-driver.c b/cpukit/libmisc/monitor/mon-driver.c
new file mode 100644
index 0000000000..12e84f414e
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-driver.c
@@ -0,0 +1,140 @@
+/*
+ * RTEMS monitor IO (device drivers) support
+ *
+ * There are 2 "driver" things the monitor knows about.
+ *
+ * 1. Regular RTEMS drivers.
+ * This is a table indexed by major device number and
+ * containing driver entry points only.
+ *
+ * 2. Driver name table.
+ * A separate table of names for drivers.
+ * The table converts driver names to a major number
+ * as index into the driver table and a minor number
+ * for an argument to driver.
+ *
+ * Drivers are displayed with 'driver' command.
+ * Names are displayed with 'name' command.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+
+#include <rtems/monitor.h>
+
+#include <stdio.h>
+#include <stdlib.h> /* strtoul() */
+
+#define DATACOL 15
+#define CONTCOL DATACOL /* continued col */
+
+
+void
+rtems_monitor_driver_canonical(
+ rtems_monitor_driver_t *canonical_driver,
+ void *driver_void
+)
+{
+ rtems_driver_address_table *d = (rtems_driver_address_table *) driver_void;
+
+ rtems_monitor_symbol_canonical_by_value(&canonical_driver->initialization,
+ (void *) d->initialization_entry);
+
+ rtems_monitor_symbol_canonical_by_value(&canonical_driver->open,
+ (void *) d->open_entry);
+ rtems_monitor_symbol_canonical_by_value(&canonical_driver->close,
+ (void *) d->close_entry);
+ rtems_monitor_symbol_canonical_by_value(&canonical_driver->read,
+ (void *) d->read_entry);
+ rtems_monitor_symbol_canonical_by_value(&canonical_driver->write,
+ (void *) d->write_entry);
+ rtems_monitor_symbol_canonical_by_value(&canonical_driver->control,
+ (void *) d->control_entry);
+}
+
+
+void *
+rtems_monitor_driver_next(
+ void *object_info,
+ rtems_monitor_driver_t *canonical_driver,
+ rtems_id *next_id
+)
+{
+ rtems_configuration_table *c = _Configuration_Table;
+ uint32_t n = rtems_get_index(*next_id);
+
+ if (n >= c->number_of_device_drivers)
+ goto failed;
+
+ _Thread_Disable_dispatch();
+
+ /*
+ * dummy up a fake id and name for this item
+ */
+
+ canonical_driver->id = n;
+ canonical_driver->name = rtems_build_name('-', '-', '-', '-');
+
+ *next_id += 1;
+ return (void *) (c->Device_driver_table + n);
+
+failed:
+ *next_id = RTEMS_OBJECT_ID_FINAL;
+ return 0;
+}
+
+
+void
+rtems_monitor_driver_dump_header(
+ boolean verbose
+)
+{
+ fprintf(stdout,"\
+ Major Entry points\n");
+/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
+0 1 2 3 4 5 6 7 */
+ rtems_monitor_separator();
+}
+
+void
+rtems_monitor_driver_dump(
+ rtems_monitor_driver_t *monitor_driver,
+ boolean verbose
+)
+{
+ uint32_t length = 0;
+
+ length += fprintf(stdout," %d", monitor_driver->id);
+
+ length += rtems_monitor_pad(13, length);
+ length += fprintf(stdout,"init: ");
+ length += rtems_monitor_symbol_dump(&monitor_driver->initialization, verbose);
+ length += fprintf(stdout,"; control: ");
+ length += rtems_monitor_symbol_dump(&monitor_driver->control, verbose);
+ length += fprintf(stdout,"\n");
+ length = 0;
+
+ length += rtems_monitor_pad(13, length);
+
+ length += fprintf(stdout,"open: ");
+ length += rtems_monitor_symbol_dump(&monitor_driver->open, verbose);
+ length += fprintf(stdout,"; close: ");
+ length += rtems_monitor_symbol_dump(&monitor_driver->close, verbose);
+ length += fprintf(stdout,"\n");
+ length = 0;
+
+ length += rtems_monitor_pad(13, length);
+
+ length += fprintf(stdout,"read: ");
+ length += rtems_monitor_symbol_dump(&monitor_driver->read, verbose);
+ length += fprintf(stdout,"; write: ");
+ length += rtems_monitor_symbol_dump(&monitor_driver->write, verbose);
+ length += fprintf(stdout,"\n");
+ length = 0;
+}
diff --git a/cpukit/libmisc/monitor/mon-extension.c b/cpukit/libmisc/monitor/mon-extension.c
new file mode 100644
index 0000000000..900fee5b87
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-extension.c
@@ -0,0 +1,102 @@
+/*
+ * RTEMS Monitor extension support
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/monitor.h>
+
+#include <stdio.h>
+
+void
+rtems_monitor_extension_canonical(
+ rtems_monitor_extension_t *canonical_extension,
+ void *extension_void
+)
+{
+ Extension_Control *rtems_extension = (Extension_Control *) extension_void;
+ rtems_extensions_table *e = &rtems_extension->Extension.Callouts;
+
+ rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_create,
+ (void *) e->thread_create);
+
+ rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_start,
+ (void *) e->thread_start);
+ rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_restart,
+ (void *) e->thread_restart);
+ rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_delete,
+ (void *) e->thread_delete);
+ rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_tswitch,
+ (void *) e->thread_switch);
+ rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_begin,
+ (void *) e->thread_begin);
+ rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_exitted,
+ (void *) e->thread_exitted);
+ rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_fatal,
+ (void *) e->fatal);
+}
+
+void
+rtems_monitor_extension_dump_header(
+ boolean verbose
+)
+{
+ fprintf(stdout,"\
+ ID NAME\n");
+/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
+0 1 2 3 4 5 6 7 */
+
+ rtems_monitor_separator();
+}
+
+
+/*
+ * Dump out the canonical form
+ */
+
+void
+rtems_monitor_extension_dump(
+ rtems_monitor_extension_t *monitor_extension,
+ boolean verbose
+)
+{
+ uint32_t length = 0;
+
+ length += rtems_monitor_dump_id(monitor_extension->id);
+ length += rtems_monitor_pad(11, length);
+ length += rtems_monitor_dump_name(monitor_extension->name);
+
+ length += rtems_monitor_pad(18, length);
+ length += fprintf(stdout,"create: ");
+ length += rtems_monitor_symbol_dump(&monitor_extension->e_create, verbose);
+ length += fprintf(stdout,"; start: ");
+ length += rtems_monitor_symbol_dump(&monitor_extension->e_start, verbose);
+ length += fprintf(stdout,"; restart: ");
+ length += rtems_monitor_symbol_dump(&monitor_extension->e_restart, verbose);
+ length += fprintf(stdout,"\n");
+ length = 0;
+
+ length += rtems_monitor_pad(18, length);
+ length += fprintf(stdout,"delete: ");
+ length += rtems_monitor_symbol_dump(&monitor_extension->e_delete, verbose);
+ length += fprintf(stdout,"; switch: ");
+ length += rtems_monitor_symbol_dump(&monitor_extension->e_tswitch, verbose);
+ length += fprintf(stdout,"; begin: ");
+ length += rtems_monitor_symbol_dump(&monitor_extension->e_begin, verbose);
+ length += fprintf(stdout,"\n");
+ length = 0;
+
+ length += rtems_monitor_pad(18, length);
+ length += fprintf(stdout,"exitted: ");
+ length += rtems_monitor_symbol_dump(&monitor_extension->e_exitted, verbose);
+ length += fprintf(stdout,"; fatal: ");
+ length += rtems_monitor_symbol_dump(&monitor_extension->e_fatal, verbose);
+ length += fprintf(stdout,"\n");
+ length = 0;
+ fprintf(stdout,"\n");
+}
diff --git a/cpukit/libmisc/monitor/mon-itask.c b/cpukit/libmisc/monitor/mon-itask.c
new file mode 100644
index 0000000000..81b54e52a3
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-itask.c
@@ -0,0 +1,122 @@
+/*
+ * RTEMS Monitor init task support
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+#include <rtems/monitor.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+
+/*
+ * As above, but just for init tasks
+ */
+void
+rtems_monitor_init_task_canonical(
+ rtems_monitor_init_task_t *canonical_itask,
+ void *itask_void
+)
+{
+ rtems_initialization_tasks_table *rtems_itask = itask_void;
+
+ rtems_monitor_symbol_canonical_by_value(&canonical_itask->entry,
+ (void *) rtems_itask->entry_point);
+
+ canonical_itask->argument = rtems_itask->argument;
+ canonical_itask->stack_size = rtems_itask->stack_size;
+ canonical_itask->priority = rtems_itask->initial_priority;
+ canonical_itask->modes = rtems_itask->mode_set;
+ canonical_itask->attributes = rtems_itask->attribute_set;
+}
+
+void *
+rtems_monitor_init_task_next(
+ void *object_info,
+ rtems_monitor_init_task_t *canonical_init_task,
+ rtems_id *next_id
+)
+{
+ rtems_configuration_table *c = _Configuration_Table;
+ rtems_initialization_tasks_table *itask;
+ uint32_t n = rtems_get_index(*next_id);
+
+ if (n >= c->RTEMS_api_configuration->number_of_initialization_tasks)
+ goto failed;
+
+ _Thread_Disable_dispatch();
+
+ itask = c->RTEMS_api_configuration->User_initialization_tasks_table + n;
+
+ /*
+ * dummy up a fake id and name for this item
+ */
+
+ canonical_init_task->id = n;
+ canonical_init_task->name = itask->name;
+
+ *next_id += 1;
+ return (void *) itask;
+
+failed:
+ *next_id = RTEMS_OBJECT_ID_FINAL;
+ return 0;
+}
+
+
+void
+rtems_monitor_init_task_dump_header(
+ boolean verbose
+)
+{
+ fprintf(stdout,"\
+ # NAME ENTRY ARGUMENT PRIO MODES ATTRIBUTES STACK SIZE\n");
+/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
+0 1 2 3 4 5 6 7 */
+ rtems_monitor_separator();
+}
+
+/*
+ */
+
+void
+rtems_monitor_init_task_dump(
+ rtems_monitor_init_task_t *monitor_itask,
+ boolean verbose
+)
+{
+ int length = 0;
+
+ length += rtems_monitor_dump_decimal(monitor_itask->id);
+
+ length += rtems_monitor_pad(7, length);
+ length += rtems_monitor_dump_name(monitor_itask->name);
+
+ length += rtems_monitor_pad(14, length);
+ length += rtems_monitor_symbol_dump(&monitor_itask->entry, verbose);
+
+ length += rtems_monitor_pad(25, length);
+ length += fprintf(stdout,"%" PRId32 " [0x%" PRIx32 "]",
+ monitor_itask->argument, monitor_itask->argument);
+
+ length += rtems_monitor_pad(39, length);
+ length += rtems_monitor_dump_priority(monitor_itask->priority);
+
+ length += rtems_monitor_pad(46, length);
+ length += rtems_monitor_dump_modes(monitor_itask->modes);
+
+ length += rtems_monitor_pad(54, length);
+ length += rtems_monitor_dump_attributes(monitor_itask->attributes);
+
+ length += rtems_monitor_pad(66, length);
+ length += fprintf(stdout,"%" PRId32 " [0x%" PRIx32 "]",
+ monitor_itask->stack_size, monitor_itask->stack_size);
+
+ fprintf(stdout,"\n");
+}
diff --git a/cpukit/libmisc/monitor/mon-manager.c b/cpukit/libmisc/monitor/mon-manager.c
new file mode 100644
index 0000000000..3a405608fb
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-manager.c
@@ -0,0 +1,58 @@
+/*
+ * RTEMS Monitor "manager" support.
+ * Used to traverse object (chain) lists and print them out.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/monitor.h>
+
+#include <stdio.h>
+
+/*
+ * "next" routine for all objects that are RTEMS manager objects
+ */
+
+void *
+rtems_monitor_manager_next(
+ void *table_void,
+ void *canonical,
+ rtems_id *next_id
+)
+{
+ Objects_Information *table = table_void;
+ rtems_monitor_generic_t *copy;
+ Objects_Control *object = 0;
+ Objects_Locations location;
+
+ /*
+ * When we are called, it must be local
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( ! _Objects_Is_local_id(*next_id) )
+ goto done;
+#endif
+
+ object = _Objects_Get_next(table, *next_id, &location, next_id);
+
+ if (object)
+ {
+ copy = (rtems_monitor_generic_t *) canonical;
+ copy->id = object->id;
+ if(table->is_string)
+ _Objects_Copy_name_raw(object->name, &copy->name, sizeof(copy->name));
+ else
+ _Objects_Copy_name_raw(&object->name, &copy->name, sizeof(copy->name));
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+done:
+#endif
+ return object;
+}
diff --git a/cpukit/libmisc/monitor/mon-monitor.c b/cpukit/libmisc/monitor/mon-monitor.c
new file mode 100644
index 0000000000..d45df2dfc0
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-monitor.c
@@ -0,0 +1,591 @@
+/*
+ * RTEMS monitor main body
+ *
+ * TODO:
+ * add stuff to RTEMS api
+ * rtems_get_name(id)
+ * rtems_get_type(id)
+ * rtems_build_id(node, type, num)
+ * Add a command to dump out info about an arbitrary id when
+ * types are added to id's
+ * rtems> id idnum
+ * idnum: node n, object: whatever, id: whatever
+ * allow id's to be specified as n:t:id, where 'n:t' is optional
+ * should have a separate monitor FILE stream (ala the debugger)
+ * remote request/response stuff should be cleaned up
+ * maybe we can use real rpc??
+ * 'info' command to print out:
+ * interrupt stack location, direction and size
+ * floating point config stuff
+ * interrupt config stuff
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <rtems/monitor.h>
+
+#define STREQ(a,b) (strcmp(a,b) == 0)
+
+/* set by trap handler */
+extern rtems_tcb *debugger_interrupted_task;
+extern rtems_context *debugger_interrupted_task_context;
+extern uint32_t debugger_trap;
+
+/*
+ * Various id's for the monitor
+ * They need to be public variables for access by other agencies
+ * such as debugger and remote servers'
+ */
+
+rtems_id rtems_monitor_task_id;
+
+uint32_t rtems_monitor_node; /* our node number */
+uint32_t rtems_monitor_default_node; /* current default for commands */
+
+/*
+ * The rtems symbol table
+ */
+
+rtems_symbol_table_t *rtems_monitor_symbols;
+
+/*
+ * User registered commands.
+ */
+
+rtems_monitor_command_entry_t rtems_registered_commands;
+
+/*
+ * The top-level commands
+ */
+
+rtems_monitor_command_entry_t rtems_monitor_commands[] = {
+ { "config",
+ "Show the system configuration.",
+ 0,
+ rtems_monitor_object_cmd,
+ { RTEMS_MONITOR_OBJECT_CONFIG },
+ &rtems_monitor_commands[1],
+ },
+ { "itask",
+ "List init tasks for the system",
+ 0,
+ rtems_monitor_object_cmd,
+ { RTEMS_MONITOR_OBJECT_INIT_TASK },
+ &rtems_monitor_commands[2],
+ },
+ { "mpci",
+ "Show the MPCI system configuration, if configured.",
+ 0,
+ rtems_monitor_object_cmd,
+ { RTEMS_MONITOR_OBJECT_MPCI },
+ &rtems_monitor_commands[3],
+ },
+ { "pause",
+ "Monitor goes to \"sleep\" for specified ticks (default is 1). "
+ "Monitor will resume at end of period or if explicitly awakened\n"
+ " pause [ticks]",
+ 0,
+ rtems_monitor_pause_cmd,
+ { 0 },
+ &rtems_monitor_commands[4],
+ },
+ { "continue",
+ "Put the monitor to sleep waiting for an explicit wakeup from the "
+ "program running.\n",
+ 0,
+ rtems_monitor_continue_cmd,
+ { 0 },
+ &rtems_monitor_commands[5],
+ },
+ { "go",
+ "Alias for 'continue'",
+ 0,
+ rtems_monitor_continue_cmd,
+ { 0 },
+ &rtems_monitor_commands[6],
+ },
+ { "node",
+ "Specify default node number for commands that take id's.\n"
+ " node [ node number ]",
+ 0,
+ rtems_monitor_node_cmd,
+ { 0 },
+ &rtems_monitor_commands[7],
+ },
+ { "symbol",
+ "Display value associated with specified symbol. "
+ "Defaults to displaying all known symbols.\n"
+ " symbol [ symbolname [symbolname ... ] ]",
+ 0,
+ rtems_monitor_symbol_cmd,
+ { .symbol_table = &rtems_monitor_symbols },
+ &rtems_monitor_commands[8],
+ },
+ { "extension",
+ "Display information about specified extensions. "
+ "Default is to display information about all extensions on this node.\n"
+ " extension [id [id ...] ]",
+ 0,
+ rtems_monitor_object_cmd,
+ { RTEMS_MONITOR_OBJECT_EXTENSION },
+ &rtems_monitor_commands[9],
+ },
+ { "task",
+ "Display information about the specified tasks. "
+ "Default is to display information about all tasks on this node.\n"
+ " task [id [id ...] ]",
+ 0,
+ rtems_monitor_object_cmd,
+ { RTEMS_MONITOR_OBJECT_TASK },
+ &rtems_monitor_commands[10],
+ },
+ { "queue",
+ "Display information about the specified message queues. "
+ "Default is to display information about all queues on this node.\n"
+ " queue [id [id ... ] ]",
+ 0,
+ rtems_monitor_object_cmd,
+ { RTEMS_MONITOR_OBJECT_QUEUE },
+ &rtems_monitor_commands[11],
+ },
+ { "object",
+ "Display information about specified RTEMS objects. "
+ "Object id's must include 'type' information. "
+ "(which may normally be defaulted)\n"
+ " object [id [id ...] ]",
+ 0,
+ rtems_monitor_object_cmd,
+ { RTEMS_MONITOR_OBJECT_INVALID },
+ &rtems_monitor_commands[12],
+ },
+ { "driver",
+ "Display the RTEMS device driver table.\n"
+ " driver [ major [ major ... ] ]",
+ 0,
+ rtems_monitor_object_cmd,
+ { RTEMS_MONITOR_OBJECT_DRIVER },
+ &rtems_monitor_commands[13],
+ },
+ { "dname",
+ "Displays information about named drivers.\n",
+ 0,
+ rtems_monitor_object_cmd,
+ { RTEMS_MONITOR_OBJECT_DNAME },
+ &rtems_monitor_commands[14],
+ },
+ { "exit",
+ "Invoke 'rtems_fatal_error_occurred' with 'status' "
+ "(default is RTEMS_SUCCESSFUL)\n"
+ " exit [status]",
+ 0,
+ rtems_monitor_fatal_cmd,
+ { .status_code = RTEMS_SUCCESSFUL },
+ &rtems_monitor_commands[15],
+ },
+ { "fatal",
+ "'exit' with fatal error; default error is RTEMS_TASK_EXITTED\n"
+ " fatal [status]",
+ 0,
+ rtems_monitor_fatal_cmd,
+ { .status_code = RTEMS_TASK_EXITTED }, /* exit value */
+ &rtems_monitor_commands[16],
+ },
+ { "quit",
+ "Alias for 'exit'\n",
+ 0,
+ rtems_monitor_fatal_cmd,
+ { .status_code = RTEMS_SUCCESSFUL }, /* exit value */
+ &rtems_monitor_commands[17],
+ },
+ { "help",
+ "Provide information about commands. "
+ "Default is show basic command summary.\n"
+ "help [ command [ command ] ]",
+ 0,
+ rtems_monitor_help_cmd,
+ { .monitor_command_entry = rtems_monitor_commands },
+ &rtems_monitor_commands[18],
+ },
+#ifdef CPU_INVOKE_DEBUGGER
+ { "debugger",
+ "Enter the debugger, if possible. "
+ "A continue from the debugger will return to the monitor.\n",
+ 0,
+ rtems_monitor_debugger_cmd,
+ { 0 },
+ &rtems_monitor_commands[19],
+ },
+#endif
+ { 0, 0, 0, 0, { 0 }, &rtems_registered_commands },
+};
+
+
+rtems_status_code
+rtems_monitor_suspend(rtems_interval timeout)
+{
+ rtems_event_set event_set;
+ rtems_status_code status;
+
+ status = rtems_event_receive(MONITOR_WAKEUP_EVENT,
+ RTEMS_DEFAULT_OPTIONS,
+ timeout,
+ &event_set);
+ return status;
+}
+
+void
+rtems_monitor_wakeup(void)
+{
+ rtems_status_code status;
+
+ status = rtems_event_send(rtems_monitor_task_id, MONITOR_WAKEUP_EVENT);
+}
+
+void
+rtems_monitor_debugger_cmd(
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose
+)
+{
+#ifdef CPU_INVOKE_DEBUGGER
+ CPU_INVOKE_DEBUGGER;
+#endif
+}
+
+void
+rtems_monitor_pause_cmd(
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose
+)
+{
+ if (argc == 1)
+ rtems_monitor_suspend(1);
+ else
+ rtems_monitor_suspend(strtoul(argv[1], 0, 0));
+}
+
+void
+rtems_monitor_fatal_cmd(
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose
+)
+{
+ if (argc == 1)
+ rtems_fatal_error_occurred(command_arg->status_code);
+ else
+ rtems_fatal_error_occurred(strtoul(argv[1], 0, 0));
+}
+
+void
+rtems_monitor_continue_cmd(
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose
+)
+{
+ rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
+}
+
+void
+rtems_monitor_node_cmd(
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose
+)
+{
+ uint32_t new_node = rtems_monitor_default_node;
+
+ switch (argc)
+ {
+ case 1: /* no node, just set back to ours */
+ new_node = rtems_monitor_node;
+ break;
+
+ case 2:
+ new_node = strtoul(argv[1], 0, 0);
+ break;
+
+ default:
+ fprintf(stdout,"invalid syntax, try 'help node'\n");
+ break;
+ }
+
+ if ((new_node >= 1) &&
+ _Configuration_MP_table &&
+ (new_node <= _Configuration_MP_table->maximum_nodes))
+ rtems_monitor_default_node = new_node;
+}
+
+
+/*
+ * Function: rtems_monitor_symbols_loadup
+ *
+ * Description:
+ * Create and load the monitor's symbol table.
+ * We are reading the output format of 'gnm' which looks like this:
+ *
+ * 400a7068 ? _Rate_monotonic_Information
+ * 400a708c ? _Thread_Dispatch_disable_level
+ * 400a7090 ? _Configuration_Table
+ *
+ * We ignore the type field.
+ *
+ * Side Effects:
+ * Creates and fills in 'rtems_monitor_symbols' table
+ *
+ * TODO
+ * there should be a BSP #define or something like that
+ * to do this; Assuming stdio is crazy.
+ * Someday this should know BFD
+ * Maybe we could get objcopy to just copy the symbol areas
+ * and copy that down.
+ *
+ */
+
+void
+rtems_monitor_symbols_loadup(void)
+{
+ FILE *fp;
+ char buffer[128];
+
+ if (rtems_monitor_symbols)
+ rtems_symbol_table_destroy(rtems_monitor_symbols);
+
+ rtems_monitor_symbols = rtems_symbol_table_create(10);
+ if (rtems_monitor_symbols == 0)
+ return;
+
+ fp = fopen("symbols", "r");
+
+ if (fp == 0)
+ return;
+
+ while (fgets(buffer, sizeof(buffer) - 1, fp))
+ {
+ char *symbol;
+ char *value;
+ char *ignored_type;
+
+ value = strtok(buffer, " \t\n");
+ ignored_type = strtok(0, " \t\n");
+ symbol = strtok(0, " \t\n");
+
+ if (symbol && ignored_type && value)
+ {
+ rtems_symbol_t *sp;
+ sp = rtems_symbol_create(rtems_monitor_symbols,
+ symbol,
+ (uint32_t ) strtoul(value, 0, 16));
+ if (sp == 0)
+ {
+ fprintf(stdout,"could not define symbol '%s'\n", symbol);
+ goto done;
+ }
+ }
+ else
+ {
+ fprintf(stdout,"parsing error on '%s'\n", buffer);
+ goto done;
+ }
+ }
+
+done:
+ return;
+}
+
+/*
+ * User registered commands.
+ */
+
+int
+rtems_monitor_insert_cmd (
+ rtems_monitor_command_entry_t *command
+)
+{
+ rtems_monitor_command_entry_t **p = &rtems_registered_commands.next;
+
+ command->next = 0;
+
+ while (*p) {
+ if ( STREQ(command->command, (*p)->command) )
+ return 0;
+ p = & (*p)->next;
+ }
+ *p = command;
+ return 1;
+}
+
+int
+rtems_monitor_erase_cmd (
+ rtems_monitor_command_entry_t *command
+)
+{
+ rtems_monitor_command_entry_t **p = & rtems_registered_commands.next;
+
+ while (*p) {
+ if ( STREQ(command->command, (*p)->command) ) {
+ *p = (*p)->next;
+ command->next = 0;
+ return 1;
+ }
+ p = & (*p)->next;
+ }
+ return 0;
+
+}
+
+/*
+ * Main monitor command loop
+ */
+
+void
+rtems_monitor_task(
+ rtems_task_argument monitor_flags
+)
+{
+ rtems_tcb *debugee = 0;
+ rtems_context *rp;
+ rtems_context_fp *fp;
+ char command_buffer[513];
+ int argc;
+ char *argv[64];
+ boolean verbose = FALSE;
+ struct termios term;
+
+ /*
+ * Make the stdin stream characte not line based.
+ */
+
+ if (tcgetattr (STDIN_FILENO, &term) < 0)
+ {
+ fprintf(stdout,"rtems-monitor: cannot get terminal attributes.\n");
+ }
+ else
+ {
+ /*
+ * No echo, no canonical processing.
+ */
+
+ term.c_lflag &= ~(ECHO | ICANON | IEXTEN);
+
+ /*
+ * No sigint on BREAK, CR-to-NL off, input parity off,
+ * don't strip 8th bit on input, output flow control off
+ */
+
+ term.c_lflag &= ~(INPCK | ISTRIP | IXON);
+ term.c_cc[VMIN] = 1;
+ term.c_cc[VTIME] = 0;
+
+ if (tcsetattr (STDIN_FILENO, TCSANOW, &term) < 0)
+ {
+ fprintf(stdout,"cannot set terminal attributes\n");
+ }
+ }
+
+ if (monitor_flags & RTEMS_MONITOR_SUSPEND)
+ (void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
+
+ for (;;)
+ {
+ extern rtems_tcb * _Thread_Executing;
+ rtems_monitor_command_entry_t *command;
+
+ debugee = _Thread_Executing;
+ rp = &debugee->Registers;
+#if (CPU_HARDWARE_FP == TRUE) || (CPU_SOFTWARE_FP == TRUE)
+ fp = debugee->fp_context; /* possibly 0 */
+#else
+ fp = 0;
+#endif
+
+ if (0 == rtems_monitor_command_read(command_buffer, &argc, argv))
+ continue;
+ if ((command = rtems_monitor_command_lookup(rtems_monitor_commands,
+ argc,
+ argv)) == 0)
+ {
+ /* no command */
+ fprintf(stdout,"Unrecognised command; try 'help'\n");
+ continue;
+ }
+
+ command->command_function(argc, argv, &command->command_arg, verbose);
+
+ fflush(stdout);
+ }
+}
+
+
+void
+rtems_monitor_kill(void)
+{
+ if (rtems_monitor_task_id)
+ rtems_task_delete(rtems_monitor_task_id);
+ rtems_monitor_task_id = 0;
+
+ rtems_monitor_server_kill();
+}
+
+void
+rtems_monitor_init(
+ uint32_t monitor_flags
+)
+{
+ rtems_status_code status;
+
+ rtems_monitor_kill();
+
+ status = rtems_task_create(RTEMS_MONITOR_NAME,
+ 1,
+ RTEMS_MINIMUM_STACK_SIZE * 2,
+ RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &rtems_monitor_task_id);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_error(status, "could not create monitor task");
+ return;
+ }
+
+ rtems_monitor_node = rtems_get_node(rtems_monitor_task_id);
+ rtems_monitor_default_node = rtems_monitor_node;
+
+ rtems_monitor_symbols_loadup();
+
+ if (monitor_flags & RTEMS_MONITOR_GLOBAL)
+ rtems_monitor_server_init(monitor_flags);
+
+ /*
+ * Start the monitor task itself
+ */
+
+ status = rtems_task_start(rtems_monitor_task_id,
+ rtems_monitor_task,
+ monitor_flags);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_error(status, "could not start monitor");
+ return;
+ }
+}
diff --git a/cpukit/libmisc/monitor/mon-mpci.c b/cpukit/libmisc/monitor/mon-mpci.c
new file mode 100644
index 0000000000..2cbd48eb3c
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-mpci.c
@@ -0,0 +1,162 @@
+/*
+ * RTEMS MPCI Config display support
+ *
+ * TODO
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+#include <rtems/monitor.h>
+
+#include <stdio.h>
+#include <stdlib.h> /* strtoul() */
+
+#define DATACOL 15
+
+/*
+ * Fill in entire monitor config table
+ * for sending to a remote monitor or printing on the local system
+ */
+
+void
+rtems_monitor_mpci_canonical(
+ rtems_monitor_mpci_t *canonical_mpci,
+ void *config_void
+)
+{
+ rtems_configuration_table *c = _Configuration_Table;
+ rtems_multiprocessing_table *m;
+ rtems_mpci_table *mt;
+
+ m = c->User_multiprocessing_table;
+ if (m == 0)
+ return;
+ mt = m->User_mpci_table;
+
+ canonical_mpci->node = m->node;
+ canonical_mpci->maximum_nodes = m->maximum_nodes;
+ canonical_mpci->maximum_global_objects = m->maximum_global_objects;
+ canonical_mpci->maximum_proxies = m->maximum_proxies;
+
+ canonical_mpci->default_timeout = mt->default_timeout;
+ canonical_mpci->maximum_packet_size = mt->maximum_packet_size;
+
+ rtems_monitor_symbol_canonical_by_value(&canonical_mpci->initialization,
+ (void *) mt->initialization);
+
+ rtems_monitor_symbol_canonical_by_value(&canonical_mpci->get_packet,
+ (void *) mt->get_packet);
+ rtems_monitor_symbol_canonical_by_value(&canonical_mpci->return_packet,
+ (void *) mt->return_packet);
+ rtems_monitor_symbol_canonical_by_value(&canonical_mpci->send_packet,
+ (void *) mt->send_packet);
+ rtems_monitor_symbol_canonical_by_value(&canonical_mpci->receive_packet,
+ (void *) mt->receive_packet);
+}
+
+/*
+ * This is easy, since there is only 1 (altho we could get them from
+ * other nodes...)
+ */
+
+void *
+rtems_monitor_mpci_next(
+ void *object_info,
+ rtems_monitor_mpci_t *canonical_mpci,
+ rtems_id *next_id
+)
+{
+ rtems_configuration_table *c = _Configuration_Table;
+ int n = rtems_get_index(*next_id);
+
+ if (n >= 1)
+ goto failed;
+
+ if ( ! c->User_multiprocessing_table)
+ goto failed;
+
+ _Thread_Disable_dispatch();
+
+ *next_id += 1;
+ return (void *) c;
+
+failed:
+ *next_id = RTEMS_OBJECT_ID_FINAL;
+ return 0;
+}
+
+
+void
+rtems_monitor_mpci_dump_header(
+ boolean verbose
+)
+{
+ fprintf(stdout,"\
+ max max max default max\n\
+ node nodes globals proxies timeout pktsize\n");
+/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
+0 1 2 3 4 5 6 7 */
+
+ rtems_monitor_separator();
+}
+
+
+void
+rtems_monitor_mpci_dump(
+ rtems_monitor_mpci_t *monitor_mpci,
+ boolean verbose
+)
+{
+ uint32_t length = 0;
+
+ length += rtems_monitor_pad(2, length);
+ length += fprintf(stdout," %d", monitor_mpci->node);
+ length += rtems_monitor_pad(11, length);
+ length += fprintf(stdout,"%d", monitor_mpci->maximum_nodes);
+
+ length += rtems_monitor_pad(18, length);
+ length += rtems_monitor_dump_decimal(monitor_mpci->maximum_global_objects);
+
+ length += rtems_monitor_pad(28, length);
+ length += rtems_monitor_dump_decimal(monitor_mpci->maximum_proxies);
+
+ length += rtems_monitor_pad(37, length);
+ length += rtems_monitor_dump_decimal(monitor_mpci->default_timeout);
+
+ length += rtems_monitor_pad(46, length);
+ length += rtems_monitor_dump_decimal(monitor_mpci->maximum_packet_size);
+
+ fprintf(stdout,"\n");
+ length = 0;
+ length += rtems_monitor_pad(DATACOL, length);
+
+ length += fprintf(stdout,"init: ");
+ length += rtems_monitor_symbol_dump(&monitor_mpci->initialization, verbose);
+
+ fprintf(stdout,"\n");
+ length = 0;
+ length += rtems_monitor_pad(DATACOL, length);
+
+ length += fprintf(stdout,"get: ");
+ length += rtems_monitor_symbol_dump(&monitor_mpci->get_packet, verbose);
+ length += fprintf(stdout,"; return: ");
+ length += rtems_monitor_symbol_dump(&monitor_mpci->return_packet, verbose);
+
+ fprintf(stdout,"\n");
+ length = 0;
+ length += rtems_monitor_pad(DATACOL, length);
+
+ length += fprintf(stdout,"send: ");
+ length += rtems_monitor_symbol_dump(&monitor_mpci->send_packet, verbose);
+ length += fprintf(stdout,"; receive: ");
+ length += rtems_monitor_symbol_dump(&monitor_mpci->receive_packet, verbose);
+
+ fprintf(stdout,"\n");
+ length = 0;
+}
diff --git a/cpukit/libmisc/monitor/mon-object.c b/cpukit/libmisc/monitor/mon-object.c
new file mode 100644
index 0000000000..b01fe74f5d
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-object.c
@@ -0,0 +1,392 @@
+/*
+ * RTEMS Monitor "object" support.
+ *
+ * Used to traverse object lists and print them out.
+ * An object can be an RTEMS object (chain based stuff) or
+ * a "misc" object such as a device driver.
+ *
+ * Each object has its own file in this directory (eg: extension.c)
+ * That file provides routines to convert a "native" structure
+ * to its canonical form, print a canonical structure, etc.
+ *
+ * TODO:
+ * should allow for non-numeric id's???
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+#include <rtems/monitor.h>
+
+#include <stdio.h>
+#include <stdlib.h> /* strtoul() */
+#include <string.h> /* memcpy() */
+
+#define NUMELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
+
+/*
+ * add:
+ * next
+ */
+
+rtems_monitor_object_info_t rtems_monitor_object_info[] =
+{
+ { RTEMS_MONITOR_OBJECT_CONFIG,
+ (void *) 0,
+ sizeof(rtems_monitor_config_t),
+ (rtems_monitor_object_next_fn) rtems_monitor_config_next,
+ (rtems_monitor_object_canonical_fn) rtems_monitor_config_canonical,
+ (rtems_monitor_object_dump_header_fn) rtems_monitor_config_dump_header,
+ (rtems_monitor_object_dump_fn) rtems_monitor_config_dump,
+ },
+ { RTEMS_MONITOR_OBJECT_MPCI,
+ (void *) 0,
+#if defined(RTEMS_MULTIPROCESSING)
+ sizeof(rtems_monitor_mpci_t),
+ (rtems_monitor_object_next_fn) rtems_monitor_mpci_next,
+ (rtems_monitor_object_canonical_fn) rtems_monitor_mpci_canonical,
+ (rtems_monitor_object_dump_header_fn) rtems_monitor_mpci_dump_header,
+ (rtems_monitor_object_dump_fn) rtems_monitor_mpci_dump,
+#else
+ 0,
+ (rtems_monitor_object_next_fn) 0,
+ (rtems_monitor_object_canonical_fn) 0,
+ (rtems_monitor_object_dump_header_fn) 0,
+ (rtems_monitor_object_dump_fn) 0,
+#endif
+ },
+ { RTEMS_MONITOR_OBJECT_INIT_TASK,
+ (void *) 0,
+ sizeof(rtems_monitor_init_task_t),
+ (rtems_monitor_object_next_fn) rtems_monitor_init_task_next,
+ (rtems_monitor_object_canonical_fn) rtems_monitor_init_task_canonical,
+ (rtems_monitor_object_dump_header_fn) rtems_monitor_init_task_dump_header,
+ (rtems_monitor_object_dump_fn) rtems_monitor_init_task_dump,
+ },
+ { RTEMS_MONITOR_OBJECT_TASK,
+ (void *) &_RTEMS_tasks_Information,
+ sizeof(rtems_monitor_task_t),
+ (rtems_monitor_object_next_fn) rtems_monitor_manager_next,
+ (rtems_monitor_object_canonical_fn) rtems_monitor_task_canonical,
+ (rtems_monitor_object_dump_header_fn) rtems_monitor_task_dump_header,
+ (rtems_monitor_object_dump_fn) rtems_monitor_task_dump,
+ },
+ { RTEMS_MONITOR_OBJECT_QUEUE,
+ (void *) &_Message_queue_Information,
+ sizeof(rtems_monitor_queue_t),
+ (rtems_monitor_object_next_fn) rtems_monitor_manager_next,
+ (rtems_monitor_object_canonical_fn) rtems_monitor_queue_canonical,
+ (rtems_monitor_object_dump_header_fn) rtems_monitor_queue_dump_header,
+ (rtems_monitor_object_dump_fn) rtems_monitor_queue_dump,
+ },
+ { RTEMS_MONITOR_OBJECT_EXTENSION,
+ (void *) &_Extension_Information,
+ sizeof(rtems_monitor_extension_t),
+ (rtems_monitor_object_next_fn) rtems_monitor_manager_next,
+ (rtems_monitor_object_canonical_fn) rtems_monitor_extension_canonical,
+ (rtems_monitor_object_dump_header_fn) rtems_monitor_extension_dump_header,
+ (rtems_monitor_object_dump_fn) rtems_monitor_extension_dump,
+ },
+ { RTEMS_MONITOR_OBJECT_DRIVER,
+ (void *) 0,
+ sizeof(rtems_monitor_driver_t),
+ (rtems_monitor_object_next_fn) rtems_monitor_driver_next,
+ (rtems_monitor_object_canonical_fn) rtems_monitor_driver_canonical,
+ (rtems_monitor_object_dump_header_fn) rtems_monitor_driver_dump_header,
+ (rtems_monitor_object_dump_fn) rtems_monitor_driver_dump,
+ },
+ { RTEMS_MONITOR_OBJECT_DNAME,
+ /* XXX now that the driver name table is allocated from the */
+ /* XXX Workspace, this does not work */
+ (void *) 0,
+ /* (void *) _IO_Driver_name_table, */
+ sizeof(rtems_monitor_dname_t),
+ (rtems_monitor_object_next_fn) rtems_monitor_dname_next,
+ (rtems_monitor_object_canonical_fn) rtems_monitor_dname_canonical,
+ (rtems_monitor_object_dump_header_fn) rtems_monitor_dname_dump_header,
+ (rtems_monitor_object_dump_fn) rtems_monitor_dname_dump,
+ },
+};
+
+/*
+ * Allow id's to be specified without the node number or
+ * type for convenience.
+ */
+
+rtems_id
+rtems_monitor_id_fixup(
+ rtems_id id,
+ uint32_t default_node,
+ rtems_monitor_object_type_t type
+)
+{
+ uint32_t node;
+
+ node = rtems_get_node(id);
+ if (node == 0)
+ {
+ if (rtems_get_class(id) != OBJECTS_CLASSIC_NO_CLASS)
+ type = rtems_get_class(id);
+
+ id = _Objects_Build_id(
+ OBJECTS_CLASSIC_API, type, default_node, rtems_get_index(id));
+ }
+ return id;
+}
+
+
+rtems_monitor_object_info_t *
+rtems_monitor_object_lookup(
+ rtems_monitor_object_type_t type
+)
+{
+ rtems_monitor_object_info_t *p;
+ for (p = &rtems_monitor_object_info[0];
+ p < &rtems_monitor_object_info[NUMELEMS(rtems_monitor_object_info)];
+ p++)
+ {
+ if (p->type == type)
+ return p;
+ }
+ return 0;
+}
+
+rtems_id
+rtems_monitor_object_canonical_next_remote(
+ rtems_monitor_object_type_t type,
+ rtems_id id,
+ void *canonical
+)
+{
+ rtems_id next_id;
+ rtems_status_code status;
+ rtems_monitor_server_request_t request;
+ rtems_monitor_server_response_t response;
+
+ /*
+ * Send request
+ */
+
+ request.command = RTEMS_MONITOR_SERVER_CANONICAL;
+ request.argument0 = (uint32_t ) type;
+ request.argument1 = (uint32_t ) id;
+
+ status = rtems_monitor_server_request(rtems_get_node(id), &request, &response);
+ if (status != RTEMS_SUCCESSFUL)
+ goto failed;
+
+ /*
+ * process response
+ */
+
+ next_id = (rtems_id) response.result0;
+ if (next_id != RTEMS_OBJECT_ID_FINAL)
+ (void) memcpy(canonical, &response.payload, response.result1);
+
+ return next_id;
+
+failed:
+ return RTEMS_OBJECT_ID_FINAL;
+
+}
+
+
+rtems_id
+rtems_monitor_object_canonical_next(
+ rtems_monitor_object_info_t *info,
+ rtems_id id,
+ void *canonical
+)
+{
+ rtems_id next_id;
+ void *raw_item;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( ! _Objects_Is_local_id(id) ) {
+ next_id = rtems_monitor_object_canonical_next_remote(
+ info->type,
+ id,
+ canonical
+ );
+ } else
+#endif
+ {
+ next_id = id;
+
+ raw_item = (void *) info->next(
+ info->object_information,
+ canonical,
+ &next_id
+ );
+
+ if (raw_item) {
+ info->canonical(canonical, raw_item);
+ _Thread_Enable_dispatch();
+ }
+ }
+ return next_id;
+}
+
+
+/*
+ * this is routine server invokes locally to get the type
+ */
+
+rtems_id
+rtems_monitor_object_canonical_get(
+ rtems_monitor_object_type_t type,
+ rtems_id id,
+ void *canonical,
+ uint32_t *size_p
+)
+{
+ rtems_monitor_object_info_t *info;
+ rtems_id next_id;
+
+ *size_p = 0;
+
+ info = rtems_monitor_object_lookup(type);
+
+ if (info == 0)
+ return RTEMS_OBJECT_ID_FINAL;
+
+ next_id = rtems_monitor_object_canonical_next(info, id, canonical);
+ *size_p = info->size;
+
+ return next_id;
+}
+
+
+void
+rtems_monitor_object_dump_1(
+ rtems_monitor_object_info_t *info,
+ rtems_id id,
+ boolean verbose
+)
+{
+ rtems_id next_id;
+ rtems_monitor_union_t canonical;
+
+ if ((next_id = rtems_monitor_object_canonical_next(
+ info,
+ id,
+ &canonical)) != RTEMS_OBJECT_ID_FINAL)
+ {
+ /*
+ * If the one we actually got is the one we wanted, then
+ * print it out.
+ * For ones that have an id field, this works fine,
+ * for all others, always dump it out.
+ *
+ * HACK: the way we determine whether there is an id is a hack.
+ *
+ * by the way: the reason we try to not have an id, is that some
+ * of the canonical structures are almost too big for shared
+ * memory driver (eg: mpci)
+ */
+
+ if ((info->next != rtems_monitor_manager_next) ||
+ (id == canonical.generic.id))
+ info->dump(&canonical, verbose);
+ }
+}
+
+void
+rtems_monitor_object_dump_all(
+ rtems_monitor_object_info_t *info,
+ boolean verbose
+)
+{
+ rtems_id next_id;
+ rtems_monitor_union_t canonical;
+
+ next_id = RTEMS_OBJECT_ID_INITIAL(OBJECTS_CLASSIC_API, info->type, rtems_monitor_default_node);
+
+ while ((next_id = rtems_monitor_object_canonical_next(
+ info,
+ next_id,
+ &canonical)) != RTEMS_OBJECT_ID_FINAL)
+ {
+ info->dump(&canonical, verbose);
+ }
+}
+
+void
+rtems_monitor_object_cmd(
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose
+)
+{
+ int arg;
+ rtems_monitor_object_info_t *info = 0;
+ rtems_monitor_object_type_t type ;
+
+ /* what is the default type? */
+ type = command_arg->monitor_object;
+
+ if (argc == 1)
+ {
+ if (type == RTEMS_MONITOR_OBJECT_INVALID)
+ {
+ fprintf(stdout,"A type must be specified to \"dump all\"\n");
+ goto done;
+ }
+
+ info = rtems_monitor_object_lookup(type);
+ if (info == 0)
+ goto not_found;
+
+ if (info->dump_header)
+ info->dump_header(verbose);
+ rtems_monitor_object_dump_all(info, verbose);
+ }
+ else
+ {
+ uint32_t default_node = rtems_monitor_default_node;
+ rtems_monitor_object_type_t last_type = RTEMS_MONITOR_OBJECT_INVALID;
+ rtems_id id;
+
+ for (arg=1; argv[arg]; arg++)
+ {
+ id = (rtems_id) strtoul(argv[arg], 0, 16);
+ id = rtems_monitor_id_fixup(id, default_node, type);
+ type = (rtems_monitor_object_type_t) rtems_get_class(id);
+
+ /*
+ * Allow the item type to change in the middle
+ * of the command. If the type changes, then
+ * just dump out a new header and keep on going.
+ */
+ if (type != last_type)
+ {
+ info = rtems_monitor_object_lookup(type);
+ if (info == 0)
+ goto not_found;
+
+ if (info->dump_header)
+ info->dump_header(verbose);
+ }
+
+ if (info == 0)
+ {
+not_found: fprintf(stdout,"Invalid or unsupported type %d\n", type);
+ goto done;
+ }
+
+ rtems_monitor_object_dump_1(info, id, verbose);
+
+ default_node = rtems_get_node(id);
+
+ last_type = type;
+ }
+ }
+done:
+ return;
+}
diff --git a/cpukit/libmisc/monitor/mon-prmisc.c b/cpukit/libmisc/monitor/mon-prmisc.c
new file mode 100644
index 0000000000..f836f0d973
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-prmisc.c
@@ -0,0 +1,269 @@
+/*
+ * Print misc stuff for the monitor dump routines
+ * Each routine returns the number of characters it output.
+ *
+ * TODO:
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/monitor.h>
+
+#include <rtems/assoc.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+void
+rtems_monitor_separator(void)
+{
+ fprintf(stdout,"------------------------------------------------------------------------------\n");
+}
+
+uint32_t
+rtems_monitor_pad(
+ uint32_t destination_column,
+ uint32_t current_column
+)
+{
+ int pad_length;
+
+ if (destination_column <= current_column)
+ pad_length = 1;
+ else
+ pad_length = destination_column - current_column;
+
+ return fprintf(stdout,"%*s", pad_length, "");
+}
+
+int
+rtems_monitor_dump_char(char ch)
+{
+ if (isprint(ch))
+ return fprintf(stdout,"%c", ch);
+ else
+ return fprintf(stdout,"%02x", (unsigned char)ch);
+}
+
+int
+rtems_monitor_dump_decimal(uint32_t num)
+{
+ return fprintf(stdout,"%4" PRId32, num);
+}
+
+int
+rtems_monitor_dump_hex(uint32_t num)
+{
+ return fprintf(stdout,"0x%" PRIx32, num);
+}
+
+int
+rtems_monitor_dump_assoc_bitfield(
+ rtems_assoc_t *ap,
+ char *separator,
+ uint32_t value
+ )
+{
+ uint32_t b;
+ uint32_t length = 0;
+ const char *name;
+
+ for (b = 1; b; b <<= 1)
+ if (b & value)
+ {
+ if (length)
+ length += fprintf(stdout,"%s", separator);
+
+ name = rtems_assoc_name_by_local(ap, b);
+
+ if (name)
+ length += fprintf(stdout,"%s", name);
+ else
+ length += fprintf(stdout,"0x%" PRIx32, b);
+ }
+
+ return length;
+}
+
+int
+rtems_monitor_dump_id(rtems_id id)
+{
+ return fprintf(stdout,"%08" PRIx32, id);
+}
+
+int
+rtems_monitor_dump_name(rtems_name name)
+{
+ uint32_t i;
+ int length = 0;
+ union {
+ uint32_t ui;
+ char c[4];
+ } u;
+
+ u.ui = (uint32_t ) name;
+
+#if (CPU_BIG_ENDIAN == TRUE)
+ for (i=0; i<sizeof(u.c); i++)
+ length += rtems_monitor_dump_char(u.c[i]);
+#else
+ for (i=0; i<sizeof(u.c); i++)
+ length += rtems_monitor_dump_char(u.c[sizeof(u.c)-1-i]);
+#endif
+ return length;
+}
+
+int
+rtems_monitor_dump_priority(rtems_task_priority priority)
+{
+ return fprintf(stdout,"%3" PRId32, priority);
+}
+
+
+rtems_assoc_t rtems_monitor_state_assoc[] = {
+ { "DORM", STATES_DORMANT },
+ { "SUSP", STATES_SUSPENDED },
+ { "TRANS", STATES_TRANSIENT },
+ { "DELAY", STATES_DELAYING },
+ { "Wbuf", STATES_WAITING_FOR_BUFFER },
+ { "Wseg", STATES_WAITING_FOR_SEGMENT },
+ { "Wmsg" , STATES_WAITING_FOR_MESSAGE },
+ { "Wevnt", STATES_WAITING_FOR_EVENT },
+ { "Wsem", STATES_WAITING_FOR_SEMAPHORE },
+ { "Wtime", STATES_WAITING_FOR_TIME },
+ { "Wrpc", STATES_WAITING_FOR_RPC_REPLY },
+ { "Wmutex", STATES_WAITING_FOR_MUTEX },
+ { "Wcvar", STATES_WAITING_FOR_CONDITION_VARIABLE },
+ { "Wjatx", STATES_WAITING_FOR_JOIN_AT_EXIT },
+ { "Wsig", STATES_WAITING_FOR_SIGNAL },
+ { "WRATE", STATES_WAITING_FOR_PERIOD },
+ { "Wisig", STATES_INTERRUPTIBLE_BY_SIGNAL },
+ { 0, 0, 0 },
+};
+
+int
+rtems_monitor_dump_state(States_Control state)
+{
+ int length = 0;
+
+ if (state == STATES_READY) /* assoc doesn't deal with this as it is 0 */
+ length += fprintf(stdout,"READY");
+
+ length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_state_assoc,
+ ":",
+ state);
+ return length;
+}
+
+rtems_assoc_t rtems_monitor_attribute_assoc[] = {
+ { "FL", RTEMS_FLOATING_POINT },
+ { "GL", RTEMS_GLOBAL },
+ { "PR", RTEMS_PRIORITY },
+ { "BI", RTEMS_BINARY_SEMAPHORE },
+ { "IN", RTEMS_INHERIT_PRIORITY },
+ { 0, 0, 0 },
+};
+
+int
+rtems_monitor_dump_attributes(rtems_attribute attributes)
+{
+ int length = 0;
+
+ if (attributes == RTEMS_DEFAULT_ATTRIBUTES) /* value is 0 */
+ length += fprintf(stdout,"DEFAULT");
+
+ length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_attribute_assoc,
+ ":",
+ attributes);
+ return length;
+}
+
+rtems_assoc_t rtems_monitor_modes_assoc[] = {
+ { "nP", RTEMS_NO_PREEMPT },
+ { "T", RTEMS_TIMESLICE },
+ { "nA", RTEMS_NO_ASR },
+ { 0, 0, 0 },
+};
+
+int
+rtems_monitor_dump_modes(rtems_mode modes)
+{
+ uint32_t length = 0;
+
+ if (modes == RTEMS_DEFAULT_MODES) /* value is 0 */
+ length += fprintf(stdout,"P:T:nA");
+
+ length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_modes_assoc,
+ ":",
+ modes);
+ return length;
+}
+
+rtems_assoc_t rtems_monitor_events_assoc[] = {
+ { "0", RTEMS_EVENT_0 },
+ { "1", RTEMS_EVENT_1 },
+ { "2", RTEMS_EVENT_2 },
+ { "3", RTEMS_EVENT_3 },
+ { "4", RTEMS_EVENT_4 },
+ { "5", RTEMS_EVENT_5 },
+ { "6", RTEMS_EVENT_6 },
+ { "7", RTEMS_EVENT_7 },
+ { "8", RTEMS_EVENT_8 },
+ { "9", RTEMS_EVENT_9 },
+ { "10", RTEMS_EVENT_10 },
+ { "11", RTEMS_EVENT_11 },
+ { "12", RTEMS_EVENT_12 },
+ { "13", RTEMS_EVENT_13 },
+ { "14", RTEMS_EVENT_14 },
+ { "15", RTEMS_EVENT_15 },
+ { "16", RTEMS_EVENT_16 },
+ { "17", RTEMS_EVENT_17 },
+ { "18", RTEMS_EVENT_18 },
+ { "19", RTEMS_EVENT_19 },
+ { "20", RTEMS_EVENT_20 },
+ { "21", RTEMS_EVENT_21 },
+ { "22", RTEMS_EVENT_22 },
+ { "23", RTEMS_EVENT_23 },
+ { "24", RTEMS_EVENT_24 },
+ { "25", RTEMS_EVENT_25 },
+ { "26", RTEMS_EVENT_26 },
+ { "27", RTEMS_EVENT_27 },
+ { "28", RTEMS_EVENT_28 },
+ { "29", RTEMS_EVENT_29 },
+ { "30", RTEMS_EVENT_30 },
+ { "31", RTEMS_EVENT_31 },
+ { 0, 0, 0 },
+};
+
+int
+rtems_monitor_dump_events(rtems_event_set events)
+{
+ uint32_t length = 0;
+
+ if (events == EVENT_SETS_NONE_PENDING) /* value is 0 */
+ length += fprintf(stdout,"NONE");
+
+ length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_events_assoc,
+ ":",
+ events);
+ return length;
+}
+
+int
+rtems_monitor_dump_notepad(uint32_t *notepad)
+{
+ int length = 0;
+ int i;
+
+ for (i=0; i < RTEMS_NUMBER_NOTEPADS; i++)
+ if (notepad[i])
+ length += fprintf(stdout,"%d: 0x%" PRIx32, i, notepad[i]);
+
+ return length;
+}
diff --git a/cpukit/libmisc/monitor/mon-queue.c b/cpukit/libmisc/monitor/mon-queue.c
new file mode 100644
index 0000000000..1714808fd8
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-queue.c
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/monitor.h>
+
+#include <stdio.h>
+
+void
+rtems_monitor_queue_canonical(
+ rtems_monitor_queue_t *canonical_queue,
+ void *queue_void
+)
+{
+ Message_queue_Control *rtems_queue = (Message_queue_Control *) queue_void;
+
+ canonical_queue->attributes = rtems_queue->attribute_set;
+ canonical_queue->maximum_message_size = rtems_queue->message_queue.maximum_message_size;
+ canonical_queue->maximum_pending_messages = rtems_queue->message_queue.maximum_pending_messages;
+ canonical_queue->number_of_pending_messages = rtems_queue->message_queue.number_of_pending_messages;
+}
+
+void
+rtems_monitor_queue_dump_header(
+ boolean verbose
+)
+{
+ fprintf(stdout,"\
+ ID NAME ATTRIBUTES PEND MAXPEND MAXSIZE\n");
+/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
+0 1 2 3 4 5 6 7 */
+ rtems_monitor_separator();
+}
+
+
+/*
+ * Dump out the "next" queue indicated by 'id'.
+ * Returns next one to check.
+ * Returns RTEMS_OBJECT_ID_FINAL when all done
+ */
+
+void
+rtems_monitor_queue_dump(
+ rtems_monitor_queue_t *monitor_queue,
+ boolean verbose
+)
+{
+ uint32_t length = 0;
+
+ length += rtems_monitor_dump_id(monitor_queue->id);
+ length += rtems_monitor_pad(11, length);
+ length += rtems_monitor_dump_name(monitor_queue->name);
+ length += rtems_monitor_pad(19, length);
+ length += rtems_monitor_dump_attributes(monitor_queue->attributes);
+ length += rtems_monitor_pad(31, length);
+ length += rtems_monitor_dump_decimal(monitor_queue->number_of_pending_messages);
+ length += rtems_monitor_pad(39, length);
+ length += rtems_monitor_dump_decimal(monitor_queue->maximum_pending_messages);
+ length += rtems_monitor_pad(48, length);
+ length += rtems_monitor_dump_decimal(monitor_queue->maximum_message_size);
+
+ fprintf(stdout,"\n");
+}
diff --git a/cpukit/libmisc/monitor/mon-server.c b/cpukit/libmisc/monitor/mon-server.c
new file mode 100644
index 0000000000..b04e5f2390
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-server.c
@@ -0,0 +1,307 @@
+/*
+ * RTEMS monitor server (handles requests for info from RTEMS monitors
+ * running on other nodes)
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <rtems/monitor.h>
+
+/*
+ * Various id's for the server
+ */
+
+rtems_id rtems_monitor_server_task_id;
+rtems_id rtems_monitor_server_request_queue_id; /* our server */
+rtems_id *rtems_monitor_server_request_queue_ids; /* all servers */
+rtems_id rtems_monitor_server_response_queue_id; /* our server */
+
+
+/*
+ * Send a request to a server task
+ */
+
+rtems_status_code
+rtems_monitor_server_request(
+ uint32_t server_node,
+ rtems_monitor_server_request_t *request,
+ rtems_monitor_server_response_t *response
+)
+{
+ rtems_id server_id;
+ rtems_status_code status;
+ uint32_t size;
+
+ /*
+ * What is id of monitor on target node?
+ * Look it up if we don't know it yet.
+ */
+
+ server_id = rtems_monitor_server_request_queue_ids[server_node];
+ if (server_id == 0)
+ {
+ status = rtems_message_queue_ident(RTEMS_MONITOR_QUEUE_NAME,
+ server_node,
+ &server_id);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_error(status, "ident of remote server failed");
+ goto done;
+ }
+
+ rtems_monitor_server_request_queue_ids[server_node] = server_id;
+ }
+
+ request->return_id = rtems_monitor_server_response_queue_id;
+
+ status = rtems_message_queue_send(server_id, request, sizeof(*request));
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_error(status, "monitor server request send failed");
+ goto done;
+ }
+
+ /*
+ * Await response, if requested
+ */
+
+ if (response)
+ {
+ status = rtems_message_queue_receive(rtems_monitor_server_response_queue_id,
+ response,
+ &size,
+ RTEMS_WAIT,
+ 100);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_error(status, "server did not respond");
+
+ /* maybe server task was restarted; look it up again next time */
+ rtems_monitor_server_request_queue_ids[server_node] = 0;
+
+ goto done;
+ }
+
+ if (response->command != RTEMS_MONITOR_SERVER_RESPONSE)
+ {
+ status = RTEMS_INCORRECT_STATE;
+ goto done;
+ }
+ }
+
+done:
+ return status;
+}
+
+
+
+/*
+ * monitor server task
+ */
+
+void
+rtems_monitor_server_task(
+ rtems_task_argument monitor_flags
+)
+{
+ rtems_monitor_server_request_t request;
+ rtems_monitor_server_response_t response;
+ rtems_status_code status;
+ uint32_t size;
+
+ for (;;)
+ {
+ status = rtems_message_queue_receive(
+ rtems_monitor_server_request_queue_id,
+ &request,
+ &size,
+ RTEMS_WAIT,
+ (rtems_interval) 0);
+
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_error(status, "monitor server msg queue receive error");
+ goto failed;
+ }
+
+ if (size != sizeof(request))
+ {
+ rtems_error(0, "monitor server bad size on receive");
+ goto failed;
+ }
+
+ switch (request.command)
+ {
+ case RTEMS_MONITOR_SERVER_CANONICAL:
+ {
+ rtems_monitor_object_type_t object_type;
+ rtems_id id;
+ rtems_id next_id;
+
+ object_type = (rtems_monitor_object_type_t) request.argument0;
+ id = (rtems_id) request.argument1;
+ next_id = rtems_monitor_object_canonical_get(object_type,
+ id,
+ &response.payload,
+ &size);
+
+ response.command = RTEMS_MONITOR_SERVER_RESPONSE;
+ response.result0 = next_id;
+ response.result1 = size;
+
+#define SERVER_OVERHEAD (RTEMS_offsetof(rtems_monitor_server_response_t, \
+ payload))
+
+ status = rtems_message_queue_send(request.return_id,
+ &response,
+ size + SERVER_OVERHEAD);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_error(status, "response send failed");
+ goto failed;
+ }
+ break;
+ }
+
+ default:
+ {
+ rtems_error(0, "invalid command to monitor server: %d", request.command);
+ goto failed;
+ }
+ }
+ }
+
+failed:
+ rtems_task_delete(RTEMS_SELF);
+}
+
+
+/*
+ * Kill off any old server
+ * Not sure if this is useful, but it doesn't help
+ */
+
+void
+rtems_monitor_server_kill(void)
+{
+ if (rtems_monitor_server_task_id)
+ rtems_task_delete(rtems_monitor_server_task_id);
+ rtems_monitor_server_task_id = 0;
+
+ if (rtems_monitor_server_request_queue_id)
+ rtems_message_queue_delete(rtems_monitor_server_request_queue_id);
+ rtems_monitor_server_request_queue_ids = 0;
+
+ if (rtems_monitor_server_response_queue_id)
+ rtems_message_queue_delete(rtems_monitor_server_response_queue_id);
+ rtems_monitor_server_response_queue_id = 0;
+
+ if (rtems_monitor_server_request_queue_ids)
+ free(rtems_monitor_server_request_queue_ids);
+ rtems_monitor_server_request_queue_ids = 0;
+}
+
+
+void
+rtems_monitor_server_init(
+ uint32_t monitor_flags
+)
+{
+ rtems_status_code status;
+
+ if (_System_state_Is_multiprocessing &&
+ (_Configuration_MP_table->maximum_nodes > 1))
+ {
+ uint32_t maximum_nodes = _Configuration_MP_table->maximum_nodes;
+
+ /*
+ * create the msg que our server will listen
+ * Since we only get msgs from other RTEMS monitors, we just
+ * need reserve space for 1 msg from each node.
+ */
+
+ status = rtems_message_queue_create(
+ RTEMS_MONITOR_QUEUE_NAME,
+ maximum_nodes,
+ sizeof(rtems_monitor_server_request_t),
+ RTEMS_GLOBAL,
+ &rtems_monitor_server_request_queue_id);
+
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_error(status, "could not create monitor server message queue");
+ goto done;
+ }
+
+ /*
+ * create the msg que our responses will come on
+ * Since monitor just does one thing at a time, we only need 1 item
+ * message queue.
+ */
+
+ status = rtems_message_queue_create(
+ RTEMS_MONITOR_RESPONSE_QUEUE_NAME,
+ 1, /* depth */
+ sizeof(rtems_monitor_server_response_t),
+ RTEMS_GLOBAL,
+ &rtems_monitor_server_response_queue_id);
+
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_error(status, "could not create monitor response message queue");
+ goto done;
+ }
+
+ /* need an id for queue of each other server we might talk to */
+ /* indexed by node, so add 1 to maximum_nodes */
+ rtems_monitor_server_request_queue_ids =
+ (rtems_id *) malloc((maximum_nodes + 1) * sizeof(rtems_id));
+ (void) memset(rtems_monitor_server_request_queue_ids,
+ 0,
+ (maximum_nodes + 1) * sizeof(rtems_id));
+
+ rtems_monitor_server_request_queue_ids[rtems_monitor_node] =
+ rtems_monitor_server_request_queue_id;
+
+ /*
+ * create the server task
+ */
+ status = rtems_task_create(RTEMS_MONITOR_SERVER_NAME,
+ 1,
+ 0 /* default stack */,
+ RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &rtems_monitor_server_task_id);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_error(status, "could not create monitor server task");
+ goto done;
+ }
+
+ /*
+ * Start the server task
+ */
+ status = rtems_task_start(rtems_monitor_server_task_id,
+ rtems_monitor_server_task,
+ monitor_flags);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_error(status, "could not start monitor server");
+ goto done;
+ }
+ }
+
+done:
+ return;
+}
diff --git a/cpukit/libmisc/monitor/mon-symbols.c b/cpukit/libmisc/monitor/mon-symbols.c
new file mode 100644
index 0000000000..ac98523704
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-symbols.c
@@ -0,0 +1,486 @@
+/*
+ * File: symbols.c
+ *
+ * Description:
+ * Symbol table manager for the RTEMS monitor.
+ * These routines may be used by other system resources also.
+ *
+ *
+ * TODO:
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+#include <rtems.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtems/monitor.h>
+#include "symbols.h"
+
+
+rtems_symbol_table_t *
+rtems_symbol_table_create()
+{
+ rtems_symbol_table_t *table;
+
+ table = (rtems_symbol_table_t *) malloc(sizeof(rtems_symbol_table_t));
+ memset((void *) table, 0, sizeof(*table));
+
+ table->growth_factor = 30; /* 30 percent */
+
+ return table;
+}
+
+void
+rtems_symbol_table_destroy(rtems_symbol_table_t *table)
+{
+ rtems_symbol_string_block_t *p, *pnext;
+
+ if (table)
+ {
+ if (table->addresses)
+ (void) free(table->addresses);
+ table->addresses = 0;
+ p = table->string_buffer_head;
+ while (p)
+ {
+ pnext = p->next;
+ free(p);
+ p = pnext;
+ }
+ table->string_buffer_head = 0;
+ table->string_buffer_current = 0;
+
+ free(table);
+ }
+}
+
+rtems_symbol_t *
+rtems_symbol_create(
+ rtems_symbol_table_t *table,
+ char *name,
+ uint32_t value
+ )
+{
+ size_t symbol_length;
+ size_t newsize;
+ rtems_symbol_t *sp;
+
+ symbol_length = strlen(name) + 1; /* include '\000' in length */
+
+ /* need to grow the table? */
+ if (table->next >= table->size)
+ {
+ if (table->size == 0)
+ newsize = 100;
+ else
+ newsize = table->size + (table->size / (100 / table->growth_factor));
+
+ table->addresses = (rtems_symbol_t *) realloc((void *) table->addresses, newsize * sizeof(rtems_symbol_t));
+ if (table->addresses == 0) /* blew it; lost orig */
+ goto failed;
+ table->size = newsize;
+ }
+
+ sp = &table->addresses[table->next];
+ sp->value = value;
+
+ /* Have to add it to string pool */
+ /* need to grow pool? */
+
+ if ((table->string_buffer_head == 0) ||
+ (table->strings_next + symbol_length) >= SYMBOL_STRING_BLOCK_SIZE)
+ {
+ rtems_symbol_string_block_t *p;
+
+ p = (rtems_symbol_string_block_t *) malloc(sizeof(rtems_symbol_string_block_t));
+ if (p == 0)
+ goto failed;
+ p->next = 0;
+ if (table->string_buffer_head == 0)
+ table->string_buffer_head = p;
+ else
+ table->string_buffer_current->next = p;
+ table->string_buffer_current = p;
+
+ table->strings_next = 0;
+ }
+
+ sp->name = table->string_buffer_current->buffer + table->strings_next;
+ (void) strcpy(sp->name, name);
+
+ table->strings_next += symbol_length;
+ table->sorted = 0;
+ table->next++;
+
+ return sp;
+
+/* XXX Not sure what to do here. We've possibly destroyed the initial
+ symbol table due to realloc failure */
+failed:
+ return 0;
+}
+
+/*
+ * Qsort entry point for compare by address
+ */
+
+static int
+rtems_symbol_compare(const void *e1,
+ const void *e2)
+{
+ rtems_symbol_t *s1, *s2;
+ s1 = (rtems_symbol_t *) e1;
+ s2 = (rtems_symbol_t *) e2;
+
+ if (s1->value < s2->value)
+ return -1;
+ if (s1->value > s2->value)
+ return 1;
+ return 0;
+}
+
+
+/*
+ * Sort the symbol table using qsort
+ */
+
+static void
+rtems_symbol_sort(rtems_symbol_table_t *table)
+{
+ qsort((void *) table->addresses, (size_t) table->next,
+ sizeof(rtems_symbol_t), rtems_symbol_compare);
+ table->sorted = 1;
+}
+
+
+/*
+ * Search the symbol table by address
+ * This code based on CYGNUS newlib bsearch, but changed
+ * to allow for finding closest symbol <= key
+ */
+
+rtems_symbol_t *
+rtems_symbol_value_lookup(
+ rtems_symbol_table_t *table,
+ uint32_t value
+ )
+{
+ rtems_symbol_t *sp;
+ rtems_symbol_t *base;
+ rtems_symbol_t *best = 0;
+ uint32_t distance;
+ uint32_t best_distance = ~0;
+ uint32_t elements;
+
+ if (table == 0)
+ table = rtems_monitor_symbols;
+
+ if ((table == 0) || (table->size == 0))
+ return 0;
+
+ if (table->sorted == 0)
+ rtems_symbol_sort(table);
+
+ base = table->addresses;
+ elements = table->next;
+
+ while (elements)
+ {
+ sp = base + (elements / 2);
+ if (value < sp->value)
+ elements /= 2;
+ else if (value > sp->value)
+ {
+ distance = value - sp->value;
+ if (distance < best_distance)
+ {
+ best_distance = distance;
+ best = sp;
+ }
+ base = sp + 1;
+ elements = (elements / 2) - (elements % 2 ? 0 : 1);
+ }
+ else
+ return sp;
+ }
+
+ if (value == base->value)
+ return base;
+
+ return best;
+}
+
+/*
+ * Search the symbol table for the exact matching address.
+ * If the symbol table has already been sorted, then
+ * call the regular symbol value lookup, however, it it
+ * has not yet been sorted, search it sequentially.
+ * This routine is primarily used for low level symbol
+ * lookups (eg. from exception handler and interrupt routines)
+ * where the penality of sorted is not wanted and where
+ * an exact match is needed such that symbol table order
+ * is not important.
+ */
+const rtems_symbol_t *
+rtems_symbol_value_lookup_exact(
+ rtems_symbol_table_t *table,
+ uint32_t value
+ )
+{
+ uint32_t s;
+ rtems_symbol_t *sp;
+
+ if (table == 0)
+ {
+ table = rtems_monitor_symbols;
+ if (table == 0)
+ return NULL;
+ }
+
+ if (table->sorted)
+ {
+ sp = rtems_symbol_value_lookup(table, value);
+ if ( rtems_symbol_value(sp) == value )
+ return sp;
+ else
+ return NULL; /* not an exact match */
+ }
+
+ for (s = 0, sp = table->addresses; s < table->next; s++, sp++)
+ {
+ if ( sp->value == value )
+ return sp;
+ }
+
+ return NULL;
+
+}
+
+
+/*
+ * Search the symbol table by string name (case independent)
+ */
+
+rtems_symbol_t *
+rtems_symbol_name_lookup(
+ rtems_symbol_table_t *table,
+ char *name
+ )
+{
+ uint32_t s;
+ rtems_symbol_t *sp;
+
+ if (table == 0)
+ {
+ table = rtems_monitor_symbols;
+ if (table == 0)
+ return NULL;
+ }
+
+ for (s = 0, sp = table->addresses; s < table->next; s++, sp++)
+ {
+ if ( strcasecmp(sp->name, name) == 0 )
+ return sp;
+ }
+
+ return NULL;
+}
+
+void *
+rtems_monitor_symbol_next(
+ void *object_info,
+ rtems_monitor_symbol_t *canonical,
+ rtems_id *next_id
+)
+{
+ rtems_symbol_table_t *table;
+ uint32_t n = rtems_get_index(*next_id);
+
+ table = *(rtems_symbol_table_t **) object_info;
+ if (table == 0)
+ goto failed;
+
+ if (n >= table->next)
+ goto failed;
+
+ /* NOTE: symbols do not have id and name fields */
+
+ if (table->sorted == 0)
+ rtems_symbol_sort(table);
+
+ _Thread_Disable_dispatch();
+
+ *next_id += 1;
+ return (void *) (table->addresses + n);
+
+failed:
+ *next_id = RTEMS_OBJECT_ID_FINAL;
+ return 0;
+}
+
+void
+rtems_monitor_symbol_canonical(
+ rtems_monitor_symbol_t *canonical_symbol,
+ rtems_symbol_t *sp
+)
+{
+ canonical_symbol->value = sp->value;
+ canonical_symbol->offset = 0;
+ strncpy(canonical_symbol->name, sp->name, sizeof(canonical_symbol->name));
+}
+
+
+void
+rtems_monitor_symbol_canonical_by_name(
+ rtems_monitor_symbol_t *canonical_symbol,
+ char *name
+)
+{
+ rtems_symbol_t *sp;
+
+ sp = rtems_symbol_name_lookup(0, name);
+
+ canonical_symbol->value = sp ? sp->value : 0;
+
+ strncpy(canonical_symbol->name, name, sizeof(canonical_symbol->name));
+ canonical_symbol->offset = 0;
+}
+
+void
+rtems_monitor_symbol_canonical_by_value(
+ rtems_monitor_symbol_t *canonical_symbol,
+ void *value_void_p
+)
+{
+ uint32_t value = (uint32_t ) value_void_p;
+ rtems_symbol_t *sp;
+
+ sp = rtems_symbol_value_lookup(0, value);
+ if (sp)
+ {
+ canonical_symbol->value = sp->value;
+ canonical_symbol->offset = value - sp->value;
+ strncpy(canonical_symbol->name, sp->name, sizeof(canonical_symbol->name));
+ }
+ else
+ {
+ canonical_symbol->value = value;
+ canonical_symbol->offset = 0;
+ canonical_symbol->name[0] = '\0';
+ }
+}
+
+
+uint32_t
+rtems_monitor_symbol_dump(
+ rtems_monitor_symbol_t *canonical_symbol,
+ boolean verbose
+)
+{
+ uint32_t length = 0;
+
+ /*
+ * print the name if it exists AND if value is non-zero
+ * Ie: don't print some garbage symbol for address 0
+ */
+
+ if (canonical_symbol->name[0] && (canonical_symbol->value != 0))
+ {
+ if (canonical_symbol->offset == 0)
+ length += fprintf(stdout,"%.*s",
+ (int) sizeof(canonical_symbol->name),
+ canonical_symbol->name);
+ else
+ length += fprintf(stdout,"<%.*s+0x%x>",
+ (int) sizeof(canonical_symbol->name),
+ canonical_symbol->name,
+ canonical_symbol->offset);
+ if (verbose)
+ length += fprintf(stdout," [0x%x]", canonical_symbol->value);
+ }
+ else
+ length += fprintf(stdout,"[0x%x]", canonical_symbol->value);
+
+ return length;
+}
+
+
+void
+rtems_monitor_symbol_dump_all(
+ rtems_symbol_table_t *table,
+ boolean verbose
+)
+{
+ uint32_t s;
+ rtems_symbol_t *sp;
+
+ if (table == 0)
+ {
+ table = rtems_monitor_symbols;
+ if (table == 0)
+ return;
+ }
+
+ if (table->sorted == 0)
+ rtems_symbol_sort(table);
+
+ for (s = 0, sp = table->addresses; s < table->next; s++, sp++)
+ {
+ rtems_monitor_symbol_t canonical_symbol;
+
+ rtems_monitor_symbol_canonical(&canonical_symbol, sp);
+ rtems_monitor_symbol_dump(&canonical_symbol, TRUE);
+ fprintf(stdout,"\n");
+ }
+}
+
+
+/*
+ * 'symbol' command
+ */
+
+void
+rtems_monitor_symbol_cmd(
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose
+)
+{
+ int arg;
+ rtems_symbol_table_t *table;
+
+ table = *command_arg->symbol_table;
+ if (table == 0)
+ {
+ table = rtems_monitor_symbols;
+ if (table == 0)
+ return;
+ }
+
+ /*
+ * Use object command to dump out whole symbol table
+ */
+ if (argc == 1)
+ rtems_monitor_symbol_dump_all(table, verbose);
+ else
+ {
+ rtems_monitor_symbol_t canonical_symbol;
+
+ for (arg=1; argv[arg]; arg++)
+ {
+ rtems_monitor_symbol_canonical_by_name(&canonical_symbol, argv[arg]);
+ rtems_monitor_symbol_dump(&canonical_symbol, verbose);
+ fprintf(stdout,"\n");
+ }
+ }
+}
diff --git a/cpukit/libmisc/monitor/mon-task.c b/cpukit/libmisc/monitor/mon-task.c
new file mode 100644
index 0000000000..98e097dc71
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-task.c
@@ -0,0 +1,96 @@
+/*
+ * RTEMS Monitor task support
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/monitor.h>
+
+#include <stdio.h>
+#include <string.h> /* memcpy() */
+
+void
+rtems_monitor_task_canonical(
+ rtems_monitor_task_t *canonical_task,
+ void *thread_void
+)
+{
+ Thread_Control *rtems_thread = (Thread_Control *) thread_void;
+ RTEMS_API_Control *api;
+
+ api = rtems_thread->API_Extensions[ THREAD_API_RTEMS ];
+
+ canonical_task->entry = rtems_thread->Start.entry_point;
+ canonical_task->argument = rtems_thread->Start.numeric_argument;
+ canonical_task->stack = rtems_thread->Start.Initial_stack.area;
+ canonical_task->stack_size = rtems_thread->Start.Initial_stack.size;
+ canonical_task->priority = rtems_thread->current_priority;
+ canonical_task->state = rtems_thread->current_state;
+ canonical_task->wait_id = rtems_thread->Wait.id;
+ canonical_task->events = api->pending_events;
+
+/* XXX modes and attributes only exist in the RTEMS API .. */
+/* XXX not directly in the core thread.. they will have to be derived */
+/* XXX if they are important enough to include anymore. */
+ canonical_task->modes = 0; /* XXX FIX ME.... rtems_thread->current_modes; */
+ canonical_task->attributes = 0 /* XXX FIX ME rtems_thread->API_Extensions[ THREAD_API_RTEMS ]->attribute_set */;
+ (void) memcpy(canonical_task->notepad, api ->Notepads, sizeof(canonical_task->notepad));
+/* XXX more to fix */
+/*
+ (void) memcpy(&canonical_task->wait_args, &rtems_thread->Wait.Extra, sizeof(canonical_task->wait_args));
+*/
+}
+
+
+void
+rtems_monitor_task_dump_header(
+ boolean verbose
+)
+{
+ fprintf(stdout,"\
+ ID NAME PRIO STAT MODES EVENTS WAITID WAITARG NOTES\n");
+/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
+0 1 2 3 4 5 6 7 */
+
+ rtems_monitor_separator();
+}
+
+/*
+ */
+
+void
+rtems_monitor_task_dump(
+ rtems_monitor_task_t *monitor_task,
+ boolean verbose
+)
+{
+ int length = 0;
+
+ length += rtems_monitor_dump_id(monitor_task->id);
+ length += rtems_monitor_pad(11, length);
+ length += rtems_monitor_dump_name(monitor_task->name);
+ length += rtems_monitor_pad(18, length);
+ length += rtems_monitor_dump_priority(monitor_task->priority);
+ length += rtems_monitor_pad(24, length);
+ length += rtems_monitor_dump_state(monitor_task->state);
+ length += rtems_monitor_pad(31, length);
+ length += rtems_monitor_dump_modes(monitor_task->modes);
+ length += rtems_monitor_pad(39, length);
+ length += rtems_monitor_dump_events(monitor_task->events);
+ if (monitor_task->wait_id)
+ {
+ length += rtems_monitor_pad(47, length);
+ length += rtems_monitor_dump_id(monitor_task->wait_id);
+ length += rtems_monitor_pad(57, length);
+ length += rtems_monitor_dump_hex(monitor_task->wait_args);
+ }
+
+ length += rtems_monitor_pad(65, length);
+ length += rtems_monitor_dump_notepad(monitor_task->notepad);
+ fprintf(stdout,"\n");
+}
diff --git a/cpukit/libmisc/monitor/monitor.h b/cpukit/libmisc/monitor/monitor.h
new file mode 100644
index 0000000000..3248e2f836
--- /dev/null
+++ b/cpukit/libmisc/monitor/monitor.h
@@ -0,0 +1,458 @@
+/**
+ * @file rtems/monitor.h
+ *
+ * The RTEMS monitor task.
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef __MONITOR_H
+#define __MONITOR_H
+
+#include <rtems/error.h> /* rtems_error() */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward decls from symbols.h */
+typedef struct _rtems_symbol_t rtems_symbol_t ;
+typedef struct _rtems_symbol_table_t rtems_symbol_table_t;
+
+/*
+ * Monitor types are derived from rtems object classes
+ */
+
+typedef enum {
+ RTEMS_MONITOR_OBJECT_INVALID = OBJECTS_CLASSIC_NO_CLASS,
+ RTEMS_MONITOR_OBJECT_TASK = OBJECTS_RTEMS_TASKS,
+ RTEMS_MONITOR_OBJECT_EXTENSION = OBJECTS_RTEMS_EXTENSIONS,
+ RTEMS_MONITOR_OBJECT_QUEUE = OBJECTS_RTEMS_MESSAGE_QUEUES,
+ RTEMS_MONITOR_OBJECT_SEMAPHORE = OBJECTS_RTEMS_SEMAPHORES,
+ RTEMS_MONITOR_OBJECT_PARTITION = OBJECTS_RTEMS_PARTITIONS,
+ RTEMS_MONITOR_OBJECT_REGION = OBJECTS_RTEMS_REGIONS,
+ RTEMS_MONITOR_OBJECT_PORT = OBJECTS_RTEMS_PORTS,
+
+ /* following monitor objects are not known to RTEMS, but
+ * we like to have "types" for them anyway */
+
+ RTEMS_MONITOR_OBJECT_DRIVER = OBJECTS_RTEMS_CLASSES_LAST+1,
+ RTEMS_MONITOR_OBJECT_DNAME,
+ RTEMS_MONITOR_OBJECT_CONFIG,
+ RTEMS_MONITOR_OBJECT_INIT_TASK,
+ RTEMS_MONITOR_OBJECT_MPCI,
+ RTEMS_MONITOR_OBJECT_SYMBOL
+} rtems_monitor_object_type_t;
+
+/*
+ * rtems_monitor_init() flags
+ */
+
+#define RTEMS_MONITOR_SUSPEND 0x0001 /* suspend monitor on startup */
+#define RTEMS_MONITOR_GLOBAL 0x0002 /* monitor should be global */
+
+
+/*
+ * Public interfaces for RTEMS data structures monitor is aware of.
+ * These are only used by the monitor.
+ *
+ * NOTE:
+ * All the canonical objects that correspond to RTEMS managed "objects"
+ * must have an identical first portion with 'id' and 'name' fields.
+ *
+ * Others do not have that restriction, even tho we would like them to.
+ * This is because some of the canonical structures are almost too big
+ * for shared memory driver (eg: mpci) and we are nickel and diming it.
+ */
+
+/*
+ * Type of a pointer that may be a symbol
+ */
+
+#define MONITOR_SYMBOL_LEN 20
+typedef struct {
+ char name[MONITOR_SYMBOL_LEN];
+ uint32_t value;
+ uint32_t offset;
+} rtems_monitor_symbol_t;
+
+typedef struct {
+ rtems_id id;
+ rtems_name name;
+ /* end of common portion */
+} rtems_monitor_generic_t;
+
+/*
+ * Task
+ */
+typedef struct {
+ rtems_id id;
+ rtems_name name;
+ /* end of common portion */
+ Thread_Entry entry;
+ uint32_t argument;
+ void *stack;
+ uint32_t stack_size;
+ rtems_task_priority priority;
+ States_Control state;
+ rtems_event_set events;
+ rtems_mode modes;
+ rtems_attribute attributes;
+ uint32_t notepad[RTEMS_NUMBER_NOTEPADS];
+ rtems_id wait_id;
+ uint32_t wait_args;
+} rtems_monitor_task_t;
+
+/*
+ * Init task
+ */
+
+typedef struct {
+ rtems_id id; /* not really an id */
+ rtems_name name;
+ /* end of common portion */
+ rtems_monitor_symbol_t entry;
+ uint32_t argument;
+ uint32_t stack_size;
+ rtems_task_priority priority;
+ rtems_mode modes;
+ rtems_attribute attributes;
+} rtems_monitor_init_task_t;
+
+
+/*
+ * Message queue
+ */
+typedef struct {
+ rtems_id id;
+ rtems_name name;
+ /* end of common portion */
+ rtems_attribute attributes;
+ uint32_t number_of_pending_messages;
+ uint32_t maximum_pending_messages;
+ uint32_t maximum_message_size;
+} rtems_monitor_queue_t;
+
+/*
+ * Extension
+ */
+typedef struct {
+ rtems_id id;
+ rtems_name name;
+ /* end of common portion */
+ rtems_monitor_symbol_t e_create;
+ rtems_monitor_symbol_t e_start;
+ rtems_monitor_symbol_t e_restart;
+ rtems_monitor_symbol_t e_delete;
+ rtems_monitor_symbol_t e_tswitch;
+ rtems_monitor_symbol_t e_begin;
+ rtems_monitor_symbol_t e_exitted;
+ rtems_monitor_symbol_t e_fatal;
+} rtems_monitor_extension_t;
+
+/*
+ * Device driver
+ */
+
+typedef struct {
+ rtems_id id; /* not really an id (should be tho) */
+ rtems_name name; /* ditto */
+ /* end of common portion */
+ rtems_monitor_symbol_t initialization; /* initialization procedure */
+ rtems_monitor_symbol_t open; /* open request procedure */
+ rtems_monitor_symbol_t close; /* close request procedure */
+ rtems_monitor_symbol_t read; /* read request procedure */
+ rtems_monitor_symbol_t write; /* write request procedure */
+ rtems_monitor_symbol_t control; /* special functions procedure */
+} rtems_monitor_driver_t;
+
+typedef struct {
+ rtems_id id; /* not used for drivers (yet) */
+ rtems_name name; /* not used for drivers (yet) */
+ /* end of common portion */
+ uint32_t major;
+ uint32_t minor;
+ char name_string[64];
+} rtems_monitor_dname_t;
+
+/*
+ * System config
+ */
+
+typedef struct {
+ void *work_space_start;
+ uint32_t work_space_size;
+ uint32_t maximum_tasks;
+ uint32_t maximum_timers;
+ uint32_t maximum_semaphores;
+ uint32_t maximum_message_queues;
+ uint32_t maximum_partitions;
+ uint32_t maximum_regions;
+ uint32_t maximum_ports;
+ uint32_t maximum_periods;
+ uint32_t maximum_extensions;
+ uint32_t microseconds_per_tick;
+ uint32_t ticks_per_timeslice;
+ uint32_t number_of_initialization_tasks;
+} rtems_monitor_config_t;
+
+/*
+ * MPCI config
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+typedef struct {
+ uint32_t node; /* local node number */
+ uint32_t maximum_nodes; /* maximum # nodes in system */
+ uint32_t maximum_global_objects; /* maximum # global objects */
+ uint32_t maximum_proxies; /* maximum # proxies */
+
+ uint32_t default_timeout; /* in ticks */
+ uint32_t maximum_packet_size;
+ rtems_monitor_symbol_t initialization;
+ rtems_monitor_symbol_t get_packet;
+ rtems_monitor_symbol_t return_packet;
+ rtems_monitor_symbol_t send_packet;
+ rtems_monitor_symbol_t receive_packet;
+} rtems_monitor_mpci_t;
+#endif
+
+/*
+ * The generic canonical information union
+ */
+
+typedef union {
+ rtems_monitor_generic_t generic;
+ rtems_monitor_task_t task;
+ rtems_monitor_queue_t queue;
+ rtems_monitor_extension_t extension;
+ rtems_monitor_driver_t driver;
+ rtems_monitor_dname_t dname;
+ rtems_monitor_config_t config;
+#if defined(RTEMS_MULTIPROCESSING)
+ rtems_monitor_mpci_t mpci;
+#endif
+ rtems_monitor_init_task_t itask;
+} rtems_monitor_union_t;
+
+/*
+ * Support for talking to other monitors
+ */
+
+/*
+ * Names of other monitors
+ */
+
+#define RTEMS_MONITOR_NAME (rtems_build_name('R', 'M', 'O', 'N'))
+#define RTEMS_MONITOR_SERVER_NAME (rtems_build_name('R', 'M', 'S', 'V'))
+#define RTEMS_MONITOR_QUEUE_NAME (rtems_build_name('R', 'M', 'S', 'Q'))
+#define RTEMS_MONITOR_RESPONSE_QUEUE_NAME (rtems_build_name('R', 'M', 'R', 'Q'))
+
+#define RTEMS_MONITOR_SERVER_RESPONSE 0x0001
+#define RTEMS_MONITOR_SERVER_CANONICAL 0x0002
+
+typedef struct
+{
+ uint32_t command;
+ rtems_id return_id;
+ uint32_t argument0;
+ uint32_t argument1;
+ uint32_t argument2;
+ uint32_t argument3;
+ uint32_t argument4;
+ uint32_t argument5;
+} rtems_monitor_server_request_t;
+
+typedef struct
+{
+ uint32_t command;
+ uint32_t result0;
+ uint32_t result1;
+ rtems_monitor_union_t payload;
+} rtems_monitor_server_response_t;
+
+extern rtems_id rtems_monitor_task_id;
+
+extern uint32_t rtems_monitor_node; /* our node number */
+extern uint32_t rtems_monitor_default_node; /* current default for commands */
+
+/*
+ * Monitor command function and table entry
+ */
+
+typedef struct rtems_monitor_command_entry_s rtems_monitor_command_entry_t;
+typedef union _rtems_monitor_command_arg_t rtems_monitor_command_arg_t;
+
+typedef void ( *rtems_monitor_command_function_t )(
+ int argc,
+ char **argv,
+ rtems_monitor_command_arg_t *command_arg,
+ boolean verbose
+ );
+
+union _rtems_monitor_command_arg_t {
+ rtems_monitor_object_type_t monitor_object ;
+ rtems_status_code status_code ;
+ rtems_symbol_table_t **symbol_table ;
+ rtems_monitor_command_entry_t *monitor_command_entry ;
+};
+
+struct rtems_monitor_command_entry_s {
+ char *command; /* command name */
+ char *usage; /* usage string for the command */
+ uint32_t arguments_required; /* # of required args */
+ rtems_monitor_command_function_t command_function;
+ /* Some argument for the command */
+ rtems_monitor_command_arg_t command_arg;
+ rtems_monitor_command_entry_t *next;
+};
+
+
+typedef void *(*rtems_monitor_object_next_fn)(void *, void *, rtems_id *);
+typedef void (*rtems_monitor_object_canonical_fn)(void *, void *);
+typedef void (*rtems_monitor_object_dump_header_fn)(boolean);
+typedef void (*rtems_monitor_object_dump_fn)(void *, boolean);
+
+typedef struct {
+ rtems_monitor_object_type_t type;
+ void *object_information;
+ int size; /* of canonical object */
+ rtems_monitor_object_next_fn next;
+ rtems_monitor_object_canonical_fn canonical;
+ rtems_monitor_object_dump_header_fn dump_header;
+ rtems_monitor_object_dump_fn dump;
+} rtems_monitor_object_info_t;
+
+
+/* monitor.c */
+void rtems_monitor_kill(void);
+void rtems_monitor_init(uint32_t );
+void rtems_monitor_wakeup(void);
+void rtems_monitor_pause_cmd(int, char **, rtems_monitor_command_arg_t*, boolean);
+void rtems_monitor_fatal_cmd(int, char **, rtems_monitor_command_arg_t*, boolean);
+void rtems_monitor_continue_cmd(int, char **, rtems_monitor_command_arg_t*, boolean);
+void rtems_monitor_debugger_cmd(int, char **, rtems_monitor_command_arg_t*, boolean);
+void rtems_monitor_node_cmd(int, char **, rtems_monitor_command_arg_t*, boolean);
+void rtems_monitor_symbols_loadup(void);
+int rtems_monitor_insert_cmd(rtems_monitor_command_entry_t *);
+int rtems_monitor_erase_cmd(rtems_monitor_command_entry_t *);
+
+void rtems_monitor_task(rtems_task_argument);
+
+/* server.c */
+void rtems_monitor_server_kill(void);
+rtems_status_code rtems_monitor_server_request(uint32_t , rtems_monitor_server_request_t *, rtems_monitor_server_response_t *);
+void rtems_monitor_server_task(rtems_task_argument);
+void rtems_monitor_server_init(uint32_t );
+
+/* command.c */
+int rtems_monitor_make_argv(char *, int *, char **);
+int rtems_monitor_command_read(char *, int *, char **);
+rtems_monitor_command_entry_t *rtems_monitor_command_lookup(
+ rtems_monitor_command_entry_t * table, int argc, char **argv);
+void rtems_monitor_command_usage(rtems_monitor_command_entry_t *, char *);
+void rtems_monitor_help_cmd(int, char **, rtems_monitor_command_arg_t *, boolean);
+
+/* prmisc.c */
+void rtems_monitor_separator(void);
+uint32_t rtems_monitor_pad(uint32_t dest_col, uint32_t curr_col);
+int rtems_monitor_dump_char(char ch);
+int rtems_monitor_dump_decimal(uint32_t num);
+int rtems_monitor_dump_hex(uint32_t num);
+int rtems_monitor_dump_id(rtems_id id);
+int rtems_monitor_dump_name(rtems_name name);
+int rtems_monitor_dump_priority(rtems_task_priority priority);
+int rtems_monitor_dump_state(States_Control state);
+int rtems_monitor_dump_modes(rtems_mode modes);
+int rtems_monitor_dump_attributes(rtems_attribute attributes);
+int rtems_monitor_dump_events(rtems_event_set events);
+int rtems_monitor_dump_notepad(uint32_t *notepad);
+
+/* object.c */
+rtems_id rtems_monitor_id_fixup(rtems_id, uint32_t , rtems_monitor_object_type_t);
+rtems_id rtems_monitor_object_canonical_get(rtems_monitor_object_type_t, rtems_id, void *, uint32_t *size_p);
+rtems_id rtems_monitor_object_canonical_next(rtems_monitor_object_info_t *, rtems_id, void *);
+void *rtems_monitor_object_next(void *, void *, rtems_id, rtems_id *);
+rtems_id rtems_monitor_object_canonical(rtems_id, void *);
+void rtems_monitor_object_cmd(int, char **, rtems_monitor_command_arg_t*, boolean);
+
+/* manager.c */
+void *rtems_monitor_manager_next(void *, void *, rtems_id *);
+
+/* config.c */
+void rtems_monitor_config_canonical(rtems_monitor_config_t *, void *);
+void *rtems_monitor_config_next(void *, rtems_monitor_config_t *, rtems_id *);
+void rtems_monitor_config_dump_header(boolean);
+int rtems_monitor_config_dump(rtems_monitor_config_t *, boolean verbose);
+
+/* mpci.c */
+#if defined(RTEMS_MULTIPROCESSING)
+void rtems_monitor_mpci_canonical(rtems_monitor_mpci_t *, void *);
+void *rtems_monitor_mpci_next(void *, rtems_monitor_mpci_t *, rtems_id *);
+void rtems_monitor_mpci_dump_header(boolean);
+void rtems_monitor_mpci_dump(rtems_monitor_mpci_t *, boolean verbose);
+#endif
+
+/* itask.c */
+void rtems_monitor_init_task_canonical(rtems_monitor_init_task_t *, void *);
+void *rtems_monitor_init_task_next(void *, rtems_monitor_init_task_t *, rtems_id *);
+void rtems_monitor_init_task_dump_header(boolean);
+void rtems_monitor_init_task_dump(rtems_monitor_init_task_t *, boolean verbose);
+
+/* extension.c */
+void rtems_monitor_extension_canonical(rtems_monitor_extension_t *, void *);
+void rtems_monitor_extension_dump_header(boolean verbose);
+void rtems_monitor_extension_dump(rtems_monitor_extension_t *, boolean);
+
+/* task.c */
+void rtems_monitor_task_canonical(rtems_monitor_task_t *, void *);
+void rtems_monitor_task_dump_header(boolean verbose);
+void rtems_monitor_task_dump(rtems_monitor_task_t *, boolean);
+
+/* queue.c */
+void rtems_monitor_queue_canonical(rtems_monitor_queue_t *, void *);
+void rtems_monitor_queue_dump_header(boolean verbose);
+void rtems_monitor_queue_dump(rtems_monitor_queue_t *, boolean);
+
+/* driver.c */
+void *rtems_monitor_driver_next(void *, rtems_monitor_driver_t *, rtems_id *);
+void rtems_monitor_driver_canonical(rtems_monitor_driver_t *, void *);
+void rtems_monitor_driver_dump_header(boolean);
+void rtems_monitor_driver_dump(rtems_monitor_driver_t *, boolean);
+
+/* dname.c */
+void *rtems_monitor_dname_next(void *, rtems_monitor_dname_t *, rtems_id *);
+void rtems_monitor_dname_canonical(rtems_monitor_dname_t *, void *);
+void rtems_monitor_dname_dump_header(boolean);
+void rtems_monitor_dname_dump(rtems_monitor_dname_t *, boolean);
+
+/* symbols.c */
+rtems_symbol_table_t *rtems_symbol_table_create();
+void rtems_symbol_table_destroy(rtems_symbol_table_t *table);
+
+rtems_symbol_t *rtems_symbol_create(rtems_symbol_table_t *, char *, uint32_t );
+rtems_symbol_t *rtems_symbol_value_lookup(rtems_symbol_table_t *, uint32_t );
+const rtems_symbol_t *rtems_symbol_value_lookup_exact(rtems_symbol_table_t *, uint32_t );
+rtems_symbol_t *rtems_symbol_name_lookup(rtems_symbol_table_t *, char *);
+void *rtems_monitor_symbol_next(void *object_info, rtems_monitor_symbol_t *, rtems_id *);
+void rtems_monitor_symbol_canonical(rtems_monitor_symbol_t *, rtems_symbol_t *);
+void rtems_monitor_symbol_canonical_by_name(rtems_monitor_symbol_t *, char *);
+void rtems_monitor_symbol_canonical_by_value(rtems_monitor_symbol_t *, void *);
+uint32_t rtems_monitor_symbol_dump(rtems_monitor_symbol_t *, boolean);
+void rtems_monitor_symbol_cmd(int, char **, rtems_monitor_command_arg_t*, boolean);
+
+
+extern rtems_symbol_table_t *rtems_monitor_symbols;
+
+/* FIXME: This should not be here */
+extern rtems_monitor_command_entry_t rtems_monitor_commands[];
+
+#define MONITOR_WAKEUP_EVENT RTEMS_EVENT_0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! __MONITOR_H */
diff --git a/cpukit/libmisc/monitor/symbols.h b/cpukit/libmisc/monitor/symbols.h
new file mode 100644
index 0000000000..6246379a94
--- /dev/null
+++ b/cpukit/libmisc/monitor/symbols.h
@@ -0,0 +1,64 @@
+/*
+ * RTEMS monitor symbol table functions
+ *
+ * Description:
+ * Entry points for symbol table routines.
+ *
+ *
+ *
+ * TODO:
+ *
+ * $Id$
+ */
+
+#ifndef _INCLUDE_SYMBOLS_H
+#define _INCLUDE_SYMBOLS_H
+
+#include <rtems/monitor.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _rtems_symbol_t {
+ uint32_t value;
+ char *name;
+} ;
+
+#define SYMBOL_STRING_BLOCK_SIZE 4080
+typedef struct rtems_symbol_string_block_s {
+ struct rtems_symbol_string_block_s *next;
+ char buffer[SYMBOL_STRING_BLOCK_SIZE];
+} rtems_symbol_string_block_t;
+
+struct _rtems_symbol_table_t {
+
+ uint32_t sorted; /* are symbols sorted right now? */
+ uint32_t growth_factor; /* % to grow by when needed */
+ uint32_t next; /* next symbol slot to use when adding */
+ uint32_t size; /* max # of symbols */
+
+ /*
+ * Symbol list -- sorted by address (when we do a lookup)
+ */
+
+ rtems_symbol_t *addresses; /* symbol array by address */
+
+ /*
+ * String pool, unsorted, a list of blocks of string data
+ */
+
+ rtems_symbol_string_block_t *string_buffer_head;
+ rtems_symbol_string_block_t *string_buffer_current;
+ uint32_t strings_next; /* next byte to use in this block */
+
+} ;
+
+#define rtems_symbol_name(sp) ((sp)->name)
+#define rtems_symbol_value(sp) ((sp)->value)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! _INCLUDE_SYMBOLS_H */
diff --git a/cpukit/libmisc/mw-fb/mw_fb.c b/cpukit/libmisc/mw-fb/mw_fb.c
new file mode 100644
index 0000000000..7ea715a18f
--- /dev/null
+++ b/cpukit/libmisc/mw-fb/mw_fb.c
@@ -0,0 +1,194 @@
+/*
+/////////////////////////////////////////////////////////////////////////////
+// $Header$
+//
+// Copyright (c) 2000 - Rosimildo da Silva
+//
+// MODULE DESCRIPTION:
+// Wrapper API around the ioctls calls for the Micro FrameBuffer
+// interface for Embedded Systems
+//
+// All functions returns 0 on success. Any other value should be
+// decoded as an error. A list of errors will be created over time.
+//
+// MODIFICATION/HISTORY:
+//
+// $Log$
+// Revision 1.3 2004/04/15 13:24:46 ralf
+// Remove stray white spaces.
+//
+// Revision 1.2 2003/07/08 08:38:48 ralf
+// 2003-07-08 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+//
+// * capture/capture-cli.c: Add config-header support.
+// * capture/capture.c: Add config-header support.
+// * cpuuse/cpuuse.c: Add config-header support.
+// * devnull/devnull.c: Add config-header support.
+// * dummy/dummy.c: Add config-header support.
+// * dumpbuf/dumpbuf.c: Add config-header support.
+// * monitor/mon-command.c: Add config-header support.
+// * monitor/mon-config.c: Add config-header support.
+// * monitor/mon-dname.c: Add config-header support.
+// * monitor/mon-driver.c: Add config-header support.
+// * monitor/mon-extension.c: Add config-header support.
+// * monitor/mon-itask.c: Add config-header support.
+// * monitor/mon-manager.c: Add config-header support.
+// * monitor/mon-monitor.c: Add config-header support.
+// * monitor/mon-mpci.c: Add config-header support.
+// * monitor/mon-object.c: Add config-header support.
+// * monitor/mon-prmisc.c: Add config-header support.
+// * monitor/mon-queue.c: Add config-header support.
+// * monitor/mon-server.c: Add config-header support.
+// * monitor/mon-symbols.c: Add config-header support.
+// * monitor/mon-task.c: Add config-header support.
+// * mw-fb/mw_fb.c: Add config-header support.
+// * mw-fb/mw_uid.c: Add config-header support.
+// * rtmonuse/rtmonuse.c: Add config-header support.
+// * serdbg/serdbg.c: Add config-header support.
+// * serdbg/serdbgio.c: Add config-header support.
+// * serdbg/termios_printk.c: Add config-header support.
+// * shell/cmds.c: Add config-header support.
+// * stackchk/check.c: Add config-header support.
+// * untar/untar.c: Add config-header support.
+//
+// Revision 1.1 2000/08/30 08:21:24 joel
+// 2000-08-26 Rosimildo da Silva <rdasilva@connecttel.com>
+//
+// * Added generic Micro FrameBuffer interface for MicroWindows.
+// This interface allows MicroWindows to under RTEMS. A sample
+// driver has been developed for the pc386 BSP. See
+// pc386/fb_vga.c as a sample.
+// * Added Uniform Input Device interface for MicroWindows.
+// See PC386 bsp for sample drivers for mouse and keyboard (console).
+// * mw-bf: New directory.
+// * Makefile.am, configure.in, wrapup/Makefile.am: Account for mw-fb.
+// * mw-fb/Makefile.am: New file.
+// * mw-fb/mw_fb.c: New file.
+// * mw-fb/mw_fb.h: New file.
+// * mw-fb/mw_uid.c: New file.
+// * mw-fb/mw_uid.h: New file.
+//
+//
+/////////////////////////////////////////////////////////////////////////////
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/ioctl.h>
+#include <rtems/mw_fb.h>
+
+
+/*
+ * This function returns the information regarding the display.
+ * It is called just after the driver be opened to get all needed
+ * information about the driver. No change in the mode of operation
+ * of the driver is done with this call.
+ */
+ int ufb_get_screen_info( int fd, struct fb_screeninfo *info )
+ {
+ return ioctl( fd, FB_SCREENINFO, ( void *)info);
+ }
+
+
+
+/*
+ * Returns the mode of the graphics subsystem
+ */
+ int ufb_get_mode( int fd, int *mode )
+ {
+ struct fb_exec_function exec;
+ exec.func_no = FB_FUNC_GET_MODE;
+ exec.param = ( void *)mode;
+ return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec );
+ }
+
+
+/*
+ * Returns the current collor pallete
+ */
+ int ufb_get_palette( int fd, struct fb_cmap *color )
+ {
+ return ioctl( fd, FB_GETPALETTE, ( void *)color );
+ }
+
+
+/*
+ * Set the current collor pallete
+ */
+ int ufb_set_palette( int fd, struct fb_cmap *color )
+ {
+ return ioctl( fd, FB_SETPALETTE, ( void *)color );
+ }
+
+/*
+ * Does all necessary initialization to put the device in
+ * graphics mode
+ */
+ int ufb_enter_graphics( int fd, int mode )
+ {
+ struct fb_exec_function exec;
+ exec.func_no = FB_FUNC_ENTER_GRAPHICS;
+ exec.param = ( void *)mode;
+ return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec );
+ }
+
+
+/*
+ * Switch the device back to the default mode of operation.
+ * In most cases it put the device back to plain text mode.
+ */
+ int ufb_exit_graphics( int fd )
+ {
+ struct fb_exec_function exec;
+ exec.func_no = FB_FUNC_EXIT_GRAPHICS;
+ exec.param = 0;
+ return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec );
+ }
+
+/*
+ * Tell the driver that the "virtual buffer" is dirty, and an update
+ * of it to the real device, maybe a serial/parallel LCD or whatever
+ * is required
+ */
+ int ufb_buffer_is_dirty( int fd )
+ {
+ struct fb_exec_function exec;
+ exec.func_no = FB_FUNC_IS_DIRTY;
+ exec.param = 0;
+ return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec );
+ }
+
+
+
+/*
+ * This function maps the physical ( kernel mode ) address of the framebuffer device
+ * and maps it to the user space address.
+ */
+ int ufb_mmap_to_user_space( int fd, void **fb_addr, void *physical_addr, unsigned long size )
+ {
+ #ifdef __rtems__
+ /* RTEMS runs in ring 0, and there is no distinction between
+ user space and kernel space, so we just return the same
+ pointer to the caller.
+ */
+ *fb_addr = physical_addr;
+ return 0;
+ #else
+ /* other kernels might want to map it to the user space,
+ maybe using mmap()
+ */
+ return 0;
+ #endif
+
+ }
+
+
+/*
+ * This function unmaps memory of the FB from the user's space
+ */
+ int ufb_unmmap_from_user_space( int fd, void *addr )
+ {
+ return 0;
+ }
diff --git a/cpukit/libmisc/mw-fb/mw_fb.h b/cpukit/libmisc/mw-fb/mw_fb.h
new file mode 100644
index 0000000000..fb7b6f6170
--- /dev/null
+++ b/cpukit/libmisc/mw-fb/mw_fb.h
@@ -0,0 +1,170 @@
+/*
+/////////////////////////////////////////////////////////////////////////////
+// $Header$
+//
+// Copyright (c) 2000 - Rosimildo da Silva
+//
+// MODULE DESCRIPTION:
+// Micro FrameBuffer interface for Embedded Systems.
+//
+// MODIFICATION/HISTORY:
+//
+// $Log$
+// Revision 1.1 2000/08/30 08:21:24 joel
+// 2000-08-26 Rosimildo da Silva <rdasilva@connecttel.com>
+//
+// * Added generic Micro FrameBuffer interface for MicroWindows.
+// This interface allows MicroWindows to under RTEMS. A sample
+// driver has been developed for the pc386 BSP. See
+// pc386/fb_vga.c as a sample.
+// * Added Uniform Input Device interface for MicroWindows.
+// See PC386 bsp for sample drivers for mouse and keyboard (console).
+// * mw-bf: New directory.
+// * Makefile.am, configure.in, wrapup/Makefile.am: Account for mw-fb.
+// * mw-fb/Makefile.am: New file.
+// * mw-fb/mw_fb.c: New file.
+// * mw-fb/mw_fb.h: New file.
+// * mw-fb/mw_uid.c: New file.
+// * mw-fb/mw_uid.h: New file.
+//
+//
+/////////////////////////////////////////////////////////////////////////////
+*/
+#ifndef _MW_FB_H
+#define _MW_FB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ioctls
+ 0x46 is 'F' */
+#define FB_SCREENINFO 0x4601
+#define FB_GETPALETTE 0x4602
+#define FB_SETPALETTE 0x4603
+#define FB_EXEC_FUNCTION 0x4604
+
+
+#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
+#define FB_TYPE_PLANES 1 /* Non interleaved planes */
+#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */
+#define FB_TYPE_TEXT 3 /* Text/attributes */
+#define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */
+#define FB_TYPE_VIRTUAL_BUFFER 5 /* Virtual Buffer */
+
+
+#define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */
+#define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */
+#define FB_VISUAL_TRUECOLOR 2 /* True color */
+#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */
+#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */
+#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */
+
+#define FB_ACCEL_NONE 0 /* no hardware accelerator */
+
+/* no dependency on any other header file */
+typedef unsigned long __u32;
+typedef unsigned short __u16;
+
+struct fb_screeninfo {
+ __u32 xres; /* visible resolution */
+ __u32 yres;
+ __u32 bits_per_pixel; /* guess what */
+ __u32 line_length; /* number of chars per line */
+ volatile char *smem_start; /* Start of frame buffer mem */
+ /* (physical address) */
+ __u32 smem_len; /* Length of frame buffer mem */
+ __u32 type; /* see FB_TYPE_* */
+ __u32 visual; /* see FB_VISUAL_* */
+
+};
+
+struct fb_cmap {
+ __u32 start; /* First entry */
+ __u32 len; /* Number of entries */
+ __u16 *red; /* Red values */
+ __u16 *green;
+ __u16 *blue;
+ __u16 *transp; /* transparency, can be NULL */
+};
+
+/* type of function to be executed at the driver level */
+#define FB_FUNC_ENTER_GRAPHICS 0
+#define FB_FUNC_EXIT_GRAPHICS 1
+#define FB_FUNC_IS_DIRTY 2
+#define FB_FUNC_GET_MODE 3
+
+struct fb_exec_function
+{
+ int func_no;
+ void *param;
+};
+
+
+/* Micro Framebuffer API Wrapper */
+
+/*
+ * This function returns the information regarding the display.
+ * It is called just after the driver be opened to get all needed
+ * information about the driver. No change in the mode of operation
+ * of the driver is done with this call.
+ */
+extern int ufb_get_screen_info( int fd, struct fb_screeninfo *info );
+
+
+/*
+ * Returns the mode of the graphics subsystem
+ */
+extern int ufb_get_mode( int fd, int *mode );
+
+
+/*
+ * Returns the current collor pallete
+ */
+extern int ufb_get_palette( int fd, struct fb_cmap *color );
+
+/*
+ * Set the current collor pallete
+ */
+extern int ufb_set_palette( int fd, struct fb_cmap *color );
+
+/*
+ * Does all necessary initialization to put the device in
+ * graphics mode
+ */
+extern int ufb_enter_graphics( int fd, int mode );
+
+
+/*
+ * Switch the device back to the default mode of operation.
+ * In most cases it put the device back to plain text mode.
+ */
+extern int ufb_exit_graphics( int fd );
+
+
+/*
+ * Tell the driver that the "virtual buffer" is dirty, and an update
+ * of it to the real device, maybe a serial/parallel LCD or whatever
+ * is required
+ */
+extern int ufb_buffer_is_dirty( int fd );
+
+
+/*
+ * This function maps the physical ( kernel mode ) address of the framebuffer device
+ * and maps it to the user space address.
+ */
+ int ufb_mmap_to_user_space( int fd, void **fb_addr, void *physical_addr, unsigned long size );
+
+
+
+/*
+ * This function unmaps memory of the FB from the user's space
+ */
+ int ufb_unmmap_from_user_space( int fd, void *addr );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MW_FB_H */
diff --git a/cpukit/libmisc/mw-fb/mw_uid.c b/cpukit/libmisc/mw-fb/mw_uid.c
new file mode 100644
index 0000000000..07cfca5571
--- /dev/null
+++ b/cpukit/libmisc/mw-fb/mw_uid.c
@@ -0,0 +1,248 @@
+/*
+/////////////////////////////////////////////////////////////////////////////
+// $Header$
+//
+// Copyright (c) 2000 - Rosimildo da Silva
+//
+// MODULE DESCRIPTION:
+// This module implements the input devices interface used by MicroWindows
+// in an embedded system environment.
+// It uses the RTEMS message queue as the repository for the messages posted
+// by the devices registered.
+//
+// MODIFICATION/HISTORY:
+//
+// $Log$
+// Revision 1.6 2004/03/26 06:59:18 ralf
+// 2004-03-26 Ralf Corsepius <ralf_corsepius@rtems.org>
+//
+// * libmisc/capture/capture-cli.c, libmisc/capture/capture.c,
+// libmisc/capture/capture.h, libmisc/cpuuse/cpuuse.c,
+// libmisc/devnull/devnull.c, libmisc/fsmount/fsmount.h,
+// libmisc/monitor/mon-config.c, libmisc/monitor/mon-dname.c,
+// libmisc/monitor/mon-driver.c, libmisc/monitor/mon-extension.c,
+// libmisc/monitor/mon-itask.c, libmisc/monitor/mon-monitor.c,
+// libmisc/monitor/mon-mpci.c, libmisc/monitor/mon-object.c,
+// libmisc/monitor/mon-prmisc.c, libmisc/monitor/mon-queue.c,
+// libmisc/monitor/mon-server.c, libmisc/monitor/mon-symbols.c,
+// libmisc/monitor/monitor.h, libmisc/monitor/symbols.h,
+// libmisc/mw-fb/mw_uid.c, libmisc/rtmonuse/rtmonuse.c,
+// libmisc/serdbg/serdbg.h, libmisc/serdbg/serdbgio.c,
+// libmisc/serdbg/termios_printk.c, libmisc/serdbg/termios_printk.h,
+// libmisc/shell/shell.c, libmisc/shell/shell.h, libmisc/stackchk/check.c,
+// libmisc/stackchk/internal.h: Convert to using c99 fixed size types.
+//
+// Revision 1.5 2003/07/08 08:38:48 ralf
+// 2003-07-08 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+//
+// * capture/capture-cli.c: Add config-header support.
+// * capture/capture.c: Add config-header support.
+// * cpuuse/cpuuse.c: Add config-header support.
+// * devnull/devnull.c: Add config-header support.
+// * dummy/dummy.c: Add config-header support.
+// * dumpbuf/dumpbuf.c: Add config-header support.
+// * monitor/mon-command.c: Add config-header support.
+// * monitor/mon-config.c: Add config-header support.
+// * monitor/mon-dname.c: Add config-header support.
+// * monitor/mon-driver.c: Add config-header support.
+// * monitor/mon-extension.c: Add config-header support.
+// * monitor/mon-itask.c: Add config-header support.
+// * monitor/mon-manager.c: Add config-header support.
+// * monitor/mon-monitor.c: Add config-header support.
+// * monitor/mon-mpci.c: Add config-header support.
+// * monitor/mon-object.c: Add config-header support.
+// * monitor/mon-prmisc.c: Add config-header support.
+// * monitor/mon-queue.c: Add config-header support.
+// * monitor/mon-server.c: Add config-header support.
+// * monitor/mon-symbols.c: Add config-header support.
+// * monitor/mon-task.c: Add config-header support.
+// * mw-fb/mw_fb.c: Add config-header support.
+// * mw-fb/mw_uid.c: Add config-header support.
+// * rtmonuse/rtmonuse.c: Add config-header support.
+// * serdbg/serdbg.c: Add config-header support.
+// * serdbg/serdbgio.c: Add config-header support.
+// * serdbg/termios_printk.c: Add config-header support.
+// * shell/cmds.c: Add config-header support.
+// * stackchk/check.c: Add config-header support.
+// * untar/untar.c: Add config-header support.
+//
+// Revision 1.4 2002/01/04 18:32:48 joel
+// 2002-01-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+//
+// * mw-fb/mw_uid.c: Apply rtems_set_errno_and_return_minus_one.
+//
+// Revision 1.3 2000/11/30 14:36:46 joel
+// 2000-11-30 Joel Sherrill <joel@OARcorp.com>
+//
+// * mw-fb/mw_uid.c: Removed unnecessary dependency on <bsp.h>.
+//
+// Revision 1.2 2000/08/30 17:12:55 joel
+// 2000-08-30 Joel Sherrill <joel@OARcorp.com>
+//
+// * Many files: Moved posix/include/rtems/posix/seterr.h to
+// score/include/rtems/seterr.h so it would be available within
+// all APIs.
+//
+// Revision 1.1 2000/08/30 08:21:24 joel
+// 2000-08-26 Rosimildo da Silva <rdasilva@connecttel.com>
+//
+// * Added generic Micro FrameBuffer interface for MicroWindows.
+// This interface allows MicroWindows to under RTEMS. A sample
+// driver has been developed for the pc386 BSP. See
+// pc386/fb_vga.c as a sample.
+// * Added Uniform Input Device interface for MicroWindows.
+// See PC386 bsp for sample drivers for mouse and keyboard (console).
+// * mw-bf: New directory.
+// * Makefile.am, configure.in, wrapup/Makefile.am: Account for mw-fb.
+// * mw-fb/Makefile.am: New file.
+// * mw-fb/mw_fb.c: New file.
+// * mw-fb/mw_fb.h: New file.
+// * mw-fb/mw_uid.c: New file.
+// * mw-fb/mw_uid.h: New file.
+//
+//
+/////////////////////////////////////////////////////////////////////////////
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <rtems.h>
+
+#include <rtems/mw_uid.h>
+#include <rtems/seterr.h>
+
+static rtems_id queue_id = 0;
+static int open_count = 0;
+
+/*
+#define MW_DEBUG_ON 1
+*/
+
+/* open a message queue with the kernel */
+int uid_open_queue( const char *q_name, int flags, size_t max_msgs )
+{
+ static rtems_name queue_name;
+
+ /*
+ * For the first device calling this function we would create the queue.
+ * It is assumed that this call is done at initialization, and no concerns
+ * regarding multi-threading is taken in consideration here.
+ */
+ if( !open_count )
+ {
+ rtems_status_code status;
+ queue_name = rtems_build_name( q_name[0],
+ q_name[1],
+ q_name[2],
+ q_name[3] );
+ status = rtems_message_queue_create( queue_name,
+ max_msgs,
+ sizeof( struct MW_UID_MESSAGE ),
+ RTEMS_FIFO | RTEMS_LOCAL,
+ &queue_id );
+ if( status != RTEMS_SUCCESSFUL )
+ {
+#ifdef MW_DEBUG_ON
+ printk( "UID_Queue: error creating queue: %d\n", status );
+#endif
+ return -1;
+ }
+#ifdef MW_DEBUG_ON
+ printk( "UID_Queue: id=%X\n", queue_id );
+#endif
+ }
+ open_count++;
+ return 0;
+}
+
+
+/* close message queue */
+int uid_close_queue( void )
+{
+ if( open_count == 1 )
+ {
+ rtems_message_queue_delete( queue_id );
+ queue_id = 0;
+ }
+ open_count--;
+ return 0;
+}
+
+/* reads for a message from the device */
+int uid_read_message( struct MW_UID_MESSAGE *m, unsigned long timeout )
+{
+ rtems_status_code status;
+ uint32_t size = 0;
+ unsigned long micro_secs = timeout*1000;
+ int wait = ( timeout != 0 );
+
+ status = rtems_message_queue_receive( queue_id,
+ (void*)m,
+ &size,
+ wait ? RTEMS_WAIT : RTEMS_NO_WAIT,
+ TOD_MICROSECONDS_TO_TICKS(micro_secs ) );
+
+ if( status == RTEMS_SUCCESSFUL )
+ {
+ return size;
+ }
+ else if( ( status == RTEMS_UNSATISFIED ) || ( status == RTEMS_TIMEOUT ) )
+ {
+ /* this macro returns -1 */
+ rtems_set_errno_and_return_minus_one( ETIMEDOUT );
+ }
+ /* Here we have one error condition */
+#ifdef MW_DEBUG_ON
+ printk( "UID_Queue: error reading queue: %d\n", status );
+#endif
+ return -1;
+}
+
+
+/*
+ * add a message to the queue of events. This method cna be used to
+ * simulate hardware events, and it can be very handy during development
+ * a new interface.
+ */
+int uid_send_message( struct MW_UID_MESSAGE *m )
+{
+ rtems_status_code status;
+ status = rtems_message_queue_send( queue_id, ( void * )m,
+ sizeof( struct MW_UID_MESSAGE ) );
+ return status == RTEMS_SUCCESSFUL ? 0 : -1;
+}
+
+/*
+ * register the device to insert events to the message
+ * queue named as the value passed in q_name
+ */
+int uid_register_device( int fd, const char *q_name )
+{
+ return ioctl( fd, MW_UID_REGISTER_DEVICE, q_name );
+}
+
+/* tell this device to stop adding events to the queue */
+int uid_unregister_device( int fd )
+{
+ return ioctl( fd, MW_UID_UNREGISTER_DEVICE, NULL );
+}
+
+/* set the keyboard */
+int uid_set_kbd_mode( int fd, int mode, int *old_mode )
+{
+ if (ioctl( fd, MV_KDGKBMODE, old_mode) < 0)
+ {
+ return -1;
+ }
+ if (ioctl(fd, MV_KDSKBMODE, mode ) < 0 )
+ {
+ return -1;
+ }
+ return 0;
+}
diff --git a/cpukit/libmisc/mw-fb/mw_uid.h b/cpukit/libmisc/mw-fb/mw_uid.h
new file mode 100644
index 0000000000..2bfc258057
--- /dev/null
+++ b/cpukit/libmisc/mw-fb/mw_uid.h
@@ -0,0 +1,160 @@
+/*
+/////////////////////////////////////////////////////////////////////////////
+// $Header$
+//
+// Copyright (c) 2000 - Rosimildo da Silva
+//
+// MODULE DESCRIPTION:
+// This module defines the interface for input devices used by MicroWindows
+// in an embedded system environment.
+//
+// MODIFICATION/HISTORY:
+//
+// $Log$
+// Revision 1.1 2000/08/30 08:21:24 joel
+// 2000-08-26 Rosimildo da Silva <rdasilva@connecttel.com>
+//
+// * Added generic Micro FrameBuffer interface for MicroWindows.
+// This interface allows MicroWindows to under RTEMS. A sample
+// driver has been developed for the pc386 BSP. See
+// pc386/fb_vga.c as a sample.
+// * Added Uniform Input Device interface for MicroWindows.
+// See PC386 bsp for sample drivers for mouse and keyboard (console).
+// * mw-bf: New directory.
+// * Makefile.am, configure.in, wrapup/Makefile.am: Account for mw-fb.
+// * mw-fb/Makefile.am: New file.
+// * mw-fb/mw_fb.c: New file.
+// * mw-fb/mw_fb.h: New file.
+// * mw-fb/mw_uid.c: New file.
+// * mw-fb/mw_uid.h: New file.
+//
+//
+/////////////////////////////////////////////////////////////////////////////
+*/
+#ifndef _MW_UID_H
+#define _MW_UID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 0x41XX -- IOCLT functions for the Micro Input Devices commands */
+#define MW_UID_REGISTER_DEVICE 0x4100
+#define MW_UID_UNREGISTER_DEVICE 0x4101
+
+
+/* devices supported by MicroWindows */
+enum MW_INPUT_DEVICE_TYPE
+{
+ MV_UID_INVALID = 0,
+ MV_UID_REL_POS = 1, /* mouse */
+ MV_UID_ABS_POS = 2, /* touch-screen */
+ MV_UID_KBD = 3, /* keyboard */
+ MV_UID_TIMER = 4 /* timer -- not used */
+};
+
+
+/* matching MicroWindows */
+#define MV_BUTTON_RIGHT 0x01
+#define MV_BUTTON_CENTER 0x02
+#define MV_BUTTON_LEFT 0x04
+
+/* modifiers of the keyboard type devices */
+#define MV_KEY_MODIFIER_SHIFT_DOWN 0x10
+#define MV_KEY_MODIFIER_ALT_DOWN 0x20
+
+/* indication of the LEDS */
+#define MV_KEY_MODIFIER_CAPS_ON 0x04
+#define MV_KEY_MODIFIER_NUN_LOCK_ON 0x02
+#define MV_KEY_SCROLL_LOCK_ON 0x01
+
+/* keyboard modes -- default ASCII */
+#define MV_KEY_MODE_ASCII 0x01
+/*
+ * This mode one event is sent when a key is pressed,
+ * and another one is send when a key is released.
+ */
+#define MV_KEY_MODE_SCANCODE 0x00
+
+
+/* these defines match with the linux keyboard range
+ for ioctls functions for the keyboard interface.
+ 0x4BXX --- keyboard related functions
+ */
+#define MV_KDGKBMODE 0x4B44 /* gets current keyboard mode */
+#define MV_KDSKBMODE 0x4B45 /* sets current keyboard mode */
+
+/*
+ * Message generated by input devices controlled by MicroWindows.
+ */
+struct MW_UID_MESSAGE
+{
+ enum MW_INPUT_DEVICE_TYPE type; /* device type */
+ union
+ {
+ /* fired when keyboard events are raised */
+ struct kbd_t {
+ unsigned short code; /* keycode or scancode */
+ unsigned char modifiers; /* key modifiers */
+ unsigned char mode; /* current Kbd mode */
+ } kbd;
+
+ /* fired when position events are raised, mouse, touch screen, etc */
+ struct pos_t {
+ unsigned short btns; /* indicates which buttons are pressed */
+ short x; /* x location */
+ short y; /* y location */
+ short z; /* z location, 0 for 2D */
+ } pos;
+
+ /* fired by a timer device periodically */
+ struct timer_t {
+ unsigned long frt; /* free running timer */
+ unsigned long seq; /* sequence number */
+ } tmr;
+
+ } m;
+};
+
+
+/*
+ * API for creating/closing/accessing the message queue used by the micro
+ * input device interface. All functions in this interface returns a
+ * zero ( 0 ) on success. One exception for that is the "read" routine
+ * that returns the number of bytes read. Negaive numbers indicate errors
+ *
+ * The implementation of the message queue for RTEMS uses a POSIX message
+ * queue interface. It should be very portable among systems with a POSIX
+ * support.
+ */
+
+/* creates the message queue that holds events from the input devices */
+extern int uid_open_queue( const char *q_name, int flags, size_t max_msgs );
+
+/* closes message queue */
+extern int uid_close_queue( void );
+
+/*
+ * reads a message from the queue. It waits up to the specified
+ * timeout in mili-seconds.
+ */
+extern int uid_read_message( struct MW_UID_MESSAGE *m, unsigned long timeout );
+
+/* write a message to the queue */
+extern int uid_write_message( struct MW_UID_MESSAGE *m );
+
+
+/* register device to insert data to the queue */
+extern int uid_register_device( int fd, const char *q_name );
+
+/* unregister device to stop adding messages to the queue */
+extern int uid_unregister_device( int fd );
+
+/* set the keyboard */
+extern int uid_set_kbd_mode( int fd, int mode, int *old_mode );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MW_UID_H */
diff --git a/cpukit/libmisc/preinstall.am b/cpukit/libmisc/preinstall.am
new file mode 100644
index 0000000000..dba6cc4d81
--- /dev/null
+++ b/cpukit/libmisc/preinstall.am
@@ -0,0 +1,7 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
diff --git a/cpukit/libmisc/rtmonuse/rtmonuse.c b/cpukit/libmisc/rtmonuse/rtmonuse.c
new file mode 100644
index 0000000000..14fca3b0eb
--- /dev/null
+++ b/cpukit/libmisc/rtmonuse/rtmonuse.c
@@ -0,0 +1,208 @@
+/*
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <rtems/rtmonuse.h>
+
+typedef struct {
+ rtems_id id;
+ uint32_t count;
+ uint32_t missed_count;
+ uint32_t min_cpu_time;
+ uint32_t max_cpu_time;
+ uint32_t total_cpu_time;
+ uint32_t min_wall_time;
+ uint32_t max_wall_time;
+ uint32_t total_wall_time;
+} Period_usage_t;
+
+Period_usage_t *Period_usage_Information;
+
+/*PAGE
+ *
+ * Period_usage_Initialize
+ */
+
+void Period_usage_Initialize( void )
+{
+ int maximum;
+
+ maximum = _Configuration_Table->RTEMS_api_configuration->maximum_periods;
+
+ Period_usage_Information = malloc( sizeof(Period_usage_t) * (maximum+1) );
+
+ Period_usage_Reset();
+}
+
+/*PAGE
+ *
+ * Period_usage_Reset
+ */
+
+void Period_usage_Reset( void )
+{
+ uint32_t i;
+ Period_usage_t *the_usage;
+
+ for ( i=0 ;
+ i<_Configuration_Table->RTEMS_api_configuration->maximum_periods ;
+ i++ ) {
+ the_usage = &Period_usage_Information[ i ];
+
+ the_usage->count = 0;
+ the_usage->missed_count = 0;
+ the_usage->min_cpu_time = 0xFFFFFFFF;
+ the_usage->max_cpu_time = 0;
+ the_usage->total_cpu_time = 0;
+ the_usage->min_wall_time = 0xFFFFFFFF;
+ the_usage->max_wall_time = 0;
+ the_usage->total_wall_time = 0;
+
+ }
+}
+
+/*PAGE
+ *
+ * Period_usage_Update
+ */
+
+void Period_usage_Update(
+ rtems_id id
+)
+{
+ rtems_rate_monotonic_period_status rm_status;
+ rtems_status_code status;
+ Period_usage_t *the_usage;
+
+ assert( Period_usage_Information );
+
+ status = rtems_rate_monotonic_get_status( id, &rm_status );
+ assert( status == RTEMS_SUCCESSFUL );
+
+ the_usage = &Period_usage_Information[ rtems_get_index( id ) ];
+
+ the_usage->id = id;
+ the_usage->count++;
+ if ( rm_status.state == RATE_MONOTONIC_EXPIRED )
+ the_usage->missed_count++;
+ the_usage->total_cpu_time += rm_status.ticks_executed_since_last_period;
+ the_usage->total_wall_time += rm_status.ticks_since_last_period;
+
+ /*
+ * Update CPU time
+ */
+
+ if ( rm_status.ticks_executed_since_last_period < the_usage->min_cpu_time )
+ the_usage->min_cpu_time = rm_status.ticks_executed_since_last_period;
+
+ if ( rm_status.ticks_executed_since_last_period > the_usage->max_cpu_time )
+ the_usage->max_cpu_time = rm_status.ticks_executed_since_last_period;
+
+ /*
+ * Update Wall time
+ */
+
+ if ( rm_status.ticks_since_last_period < the_usage->min_wall_time )
+ the_usage->min_wall_time = rm_status.ticks_since_last_period;
+
+ if ( rm_status.ticks_since_last_period > the_usage->max_wall_time )
+ the_usage->max_wall_time = rm_status.ticks_since_last_period;
+
+}
+
+/*PAGE
+ *
+ * Period_usage_Dump
+ */
+
+void Period_usage_Dump( void )
+{
+ uint32_t i;
+ Period_usage_t *the_usage;
+ Rate_monotonic_Control *the_period;
+ uint32_t u32_name;
+ char *cname;
+ char name[5];
+ uint32_t api_index;
+ Objects_Information *information;
+
+ if ( !Period_usage_Information ) {
+ fprintf(stdout, "Period statistics library is not initialized\n" );
+ return;
+ }
+
+ fprintf(stdout, "Period information by period\n" );
+ fprintf(stdout, " ID OWNER PERIODS MISSED CPU TIME WALL TIME\n" );
+
+ /*
+ * RTEMS does not use an index of zero for object ids.
+ */
+
+ for ( i=1 ;
+ i<=_Configuration_Table->RTEMS_api_configuration->maximum_periods ;
+ i++ ) {
+ the_usage = &Period_usage_Information[ i ];
+ if ( the_usage->count == 0 )
+ continue;
+
+ the_period =
+ (Rate_monotonic_Control *)_Rate_monotonic_Information.local_table[ i ];
+
+ name[ 0 ] = ' ';
+ name[ 1 ] = ' ';
+ name[ 2 ] = ' ';
+ name[ 3 ] = ' ';
+ name[ 4 ] = '\0';
+
+ if ( the_period->owner ) {
+ api_index = _Objects_Get_API(the_period->owner->Object.id);
+ information = _Objects_Information_table[ api_index ][ 1 ];
+
+ if ( information->is_string ) {
+ cname = the_period->owner->Object.name;
+ name[ 0 ] = cname[0];
+ name[ 1 ] = cname[1];
+ name[ 2 ] = cname[2];
+ name[ 3 ] = cname[3];
+ name[ 4 ] = '\0';
+ } else {
+ u32_name = (uint32_t )the_period->owner->Object.name;
+ name[ 0 ] = (u32_name >> 24) & 0xff;
+ name[ 1 ] = (u32_name >> 16) & 0xff;
+ name[ 2 ] = (u32_name >> 8) & 0xff;
+ name[ 3 ] = (u32_name >> 0) & 0xff;
+ name[ 4 ] = '\0';
+ }
+ }
+
+ if ( !isprint(name[0]) ) name[0] = '*';
+ if ( !isprint(name[1]) ) name[1] = '*';
+ if ( !isprint(name[2]) ) name[2] = '*';
+ if ( !isprint(name[3]) ) name[3] = '*';
+
+
+ fprintf(stdout,
+ "0x%08x %4s %6d %3d %d/%d/%5.2f %d/%d/%3.2f\n",
+ the_usage->id,
+ name,
+ the_usage->count,
+ the_usage->missed_count,
+ the_usage->min_cpu_time,
+ the_usage->max_cpu_time,
+ (double) the_usage->total_cpu_time / (double) the_usage->count,
+ the_usage->min_wall_time,
+ the_usage->max_wall_time,
+ (double) the_usage->total_wall_time / (double) the_usage->count
+ );
+ }
+}
diff --git a/cpukit/libmisc/rtmonuse/rtmonuse.h b/cpukit/libmisc/rtmonuse/rtmonuse.h
new file mode 100644
index 0000000000..27fb7c1c8a
--- /dev/null
+++ b/cpukit/libmisc/rtmonuse/rtmonuse.h
@@ -0,0 +1,30 @@
+/**
+ * @file rtems/rtmonuse.h
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef __RATE_MONOTONIC_USAGE_h
+#define __RATE_MONOTONIC_USAGE_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void Period_usage_Initialize( void );
+
+void Period_usage_Reset( void );
+
+void Period_usage_Update(
+ rtems_id id
+);
+
+void Period_usage_Dump( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libmisc/serdbg/README b/cpukit/libmisc/serdbg/README
new file mode 100644
index 0000000000..338249c928
--- /dev/null
+++ b/cpukit/libmisc/serdbg/README
@@ -0,0 +1,138 @@
+#
+# $Id$
+#
+
+This directory contains three useful packages related to the termios I/O
+system:
+
+PACKAGE SERDBGIO
+================
+"serdbgio" provides the "serial gdb" standard I/O functions "getDebugChar"
+and "putDebugChar" for any device driver supporting polled termios mode.
+
+The initialization function "serdbg_open" opens the v.24 port intended
+for the serial debug connection, and sets the desired baud rate. The
+"getDebugChar" and "putDebugChar" functions then interact with the
+corresponding driver using the calls intended for polled termios
+operation.
+
+Specification for the debug device, baud rate and other parameters is
+done in a global structure of type "serdbg_conf_t". A configuration
+mechanism quite similar to the overall RTEMS configuration is available.
+
+PACKAGE SERDBG
+==============
+"serdbg" provides a means to optionally initialize and/or start a
+serial gdb session as soon as possible, this means as soon as all
+drivers have been initialized. The serial debug I/O functions can
+either be integrated as special routines of the BSP drivers, or using
+the package "serdbgio"
+
+PACKAGE TERMIOS_PRINTK
+======================
+"termios_printk" provides a standard output function suitable to use
+with "printk". It uses the same technique as serdbgio, hooking the
+interface between a polled device driver and the termios system.
+
+
+REQUIREMENTS
+============
+
+- These two packages can be used with any polled termios device
+driver.
+- For standard initialization, they need a modified "bsppost.c"
+to perform the initialization calls.
+
+USAGE
+=====
+
+For using these packages add the following to your "init" module or
+your "system.h" file (Note: most macro settings fall back to a
+default, if not set.):
+
+/*
+ * CONFIGURE_USE_SERDBG
+ * set this macro, if you want to connect gdb over a serial line
+ * when set, the debug stub will be connected after driver
+ * initialization in "bsppost.c"
+ */
+#define CONFIGURE_USE_SERDBG
+
+
+/*
+ * CONFIGURE_SERDBG_SKIP_INIT_BKPT
+ * set this macro, if you do not want the gdb interface to wait for a
+ * debugger connection directly after initialization
+ * If you set this macro, the gdb stub will only hook various
+ * exception vectors when called from "bsppost.c".
+ */
+/* #define CONFIGURE_SERDBG_SKIP_INIT_BKPT */
+
+/*
+ * CONFIGURE_SERDBG_USE_POLLED_TERMIOS
+ * set this macro, if you want "serdbgio" to provide the I/O
+ * functions for the serial gdb connection
+ */
+#define CONFIGURE_SERDBG_USE_POLLED_TERMIOS
+
+/*
+ * CONFIGURE_SERDBG_DEVNAME
+ * use this macro to specify the serial device to use
+ * for "serdbgio".
+ * Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
+ */
+#define CONFIGURE_SERDBG_DEVNAME "/dev/tty03"
+
+/*
+ * CONFIGURE_SERDBG_BAUDRATE
+ * use this macro to specify the baud rate to use
+ * for "serdbgio".
+ * Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
+ */
+#define CONFIGURE_SERDBG_BAUDRATE 57600
+
+/*
+ * CONFIGURE_SERDBG_CALLOUT
+ * use this macro to specify a routine that will called during I/O polling
+ * Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
+ * This function of type "void pollfnc(void)" can be used for e.g.
+ * tickling a watchdog
+ */
+/* #define CONFIGURE_SERDBG_CALLOUT tickle_my_watchdog_fnc */
+
+#include <serdbgcnf.h>
+
+/*
+ * CONFIGURE_USE_TERMIOS_PRINTK
+ * set this macro, if you want printk output to be sent to a serial
+ * driver using the polled termios interface
+ * when set, the printk output function will be connected after driver
+ * initialization in "bsppost.c"
+ */
+#define CONFIGURE_USE_TERMIOS_PRINTK
+
+/*
+ * CONFIGURE_TERMIOS_PRINTK_DEVNAME
+ * use this macro to specify the serial device to use
+ * for printk output.
+ * Only used, when CONFIGURE_USE_TERMIOS_PRINTK is set
+ */
+#define CONFIGURE_TERMIOS_PRINTK_DEVNAME "/dev/console"
+
+/*
+ * CONFIGURE_TERMIOS_PRINTK_BAUDRATE
+ * use this macro to specify the baudrate to use
+ * for printk output.
+ * Only used, when CONFIGURE_USE_TERMIOS_PRINTK is set
+ */
+#define CONFIGURE_TERMIOS_PRINTK_BAUDRATE 9600
+
+/*
+ * CONFIGURE_TERMIOS_PRINTK_CALLOUT
+ * use this macro to specify a routine that will called during I/O polling
+ * This function of type "void pollfnc(void)" can be used for e.g.
+ * tickling a watchdog
+ */
+/* #define CONFIGURE_TERMIOS_PRINTK_CALLOUT tickle_my_watchdog_fnc */
+
+#include <termios_printk_cnf.h>
diff --git a/cpukit/libmisc/serdbg/serdbg.c b/cpukit/libmisc/serdbg/serdbg.c
new file mode 100644
index 0000000000..4bca324934
--- /dev/null
+++ b/cpukit/libmisc/serdbg/serdbg.c
@@ -0,0 +1,94 @@
+/*===============================================================*\
+| Project: RTEMS remote gdb over serial line |
++-----------------------------------------------------------------+
+| File: serdbg.c |
++-----------------------------------------------------------------+
+| Copyright (c) 2002 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file contains intialization and utility functions to add |
+| a gdb remote debug stub to an RTEMS system |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 04.04.02 creation doe |
+\*===============================================================*/
+/*
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <rtems/serdbg.h>
+
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int serdbg_init_dbg
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| initialize remote gdb session over serial line |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ void
+)
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| rtems_status_code |
+\*=========================================================================*/
+{
+ static boolean is_initialized = FALSE;
+
+ rtems_status_code rc = RTEMS_SUCCESSFUL;
+ extern void set_debug_traps(void);
+ extern void breakpoint(void);
+
+ if (is_initialized) {
+ return RTEMS_SUCCESSFUL;
+ }
+ is_initialized = TRUE;
+ /*
+ * try to open serial device
+ */
+ if (rc == RTEMS_SUCCESSFUL) {
+ if ((serdbg_conf.open_io != NULL) &&
+ (0 > serdbg_conf.open_io(serdbg_conf.devname,serdbg_conf.baudrate))) {
+ fprintf(stderr,
+ "remote_gdb_init: cannot open device %s "
+ "for gdb connection:%s\n",serdbg_conf.devname,strerror(errno));
+ rc = RTEMS_IO_ERROR;
+ }
+ }
+ /*
+ * initialize gdb stub
+ */
+ if (rc == RTEMS_SUCCESSFUL) {
+ set_debug_traps();
+ }
+ /*
+ * now activate gdb stub
+ */
+ if ((rc == RTEMS_SUCCESSFUL) &&
+ !serdbg_conf.skip_init_bkpt) {
+ breakpoint();
+ }
+
+ /*
+ * return to original function
+ * this may be already unter gdb control
+ */
+ return rc;
+}
diff --git a/cpukit/libmisc/serdbg/serdbg.h b/cpukit/libmisc/serdbg/serdbg.h
new file mode 100644
index 0000000000..963c117877
--- /dev/null
+++ b/cpukit/libmisc/serdbg/serdbg.h
@@ -0,0 +1,181 @@
+/*===============================================================*\
+| Project: RTEMS remote gdb over serial line |
++-----------------------------------------------------------------+
+| File: serdbg.h |
++-----------------------------------------------------------------+
+| Copyright (c) 2002 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file declares intialization functions to add |
+| a gdb remote debug stub to an RTEMS system |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 04.04.02 creation doe |
+\*===============================================================*/
+/*
+ * $Id$
+ */
+#ifndef _SERDBG_H
+#define _SERDBG_H
+
+#include <rtems.h>
+#include <termios.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct {
+ uint32_t baudrate; /* debug baud rate, e.g. 57600 */
+ void (*callout)(void); /* callout pointer during polling */
+ int (*open_io)(const char *dev_name,uint32_t baudrate); /* I/O open fnc */
+ const char *devname; /* debug device, e.g. "/dev/tty01" */
+ uint8_t skip_init_bkpt; /* if TRUE, do not stop when initializing */
+} serdbg_conf_t;
+
+/*
+ * must be defined in init module...
+ */
+extern serdbg_conf_t serdbg_conf;
+
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+void putDebugChar
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| send character to remote debugger |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ char c /* char to send */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int getDebugChar
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| get character from remote debugger |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ void /* <none> */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+void serdbg_exceptionHandler
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| hook directly to an exception vector |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ int vecnum, /* vector index to hook at */
+ void *vector /* address of handler function */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int serdbg_init
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| initialize remote gdb session over serial line |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ void
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| rtems_status_code |
+\*=========================================================================*/
+
+/*
+ * stuff from serdbgio.c
+ */
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int serdbg_open
+
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| try to open given serial debug port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ const char *dev_name, /* name of device to open */
+ uint32_t baudrate /* baud rate to use */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0 on success, -1 and errno otherwise |
+\*=========================================================================*/
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+void putDebugChar
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| send one character to serial port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ char c /* character to print */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int getDebugChar
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| wait for one character from serial port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ void /* none */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| received character |
+\*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SERDBG_H */
diff --git a/cpukit/libmisc/serdbg/serdbgcnf.h b/cpukit/libmisc/serdbg/serdbgcnf.h
new file mode 100644
index 0000000000..278fdf0db2
--- /dev/null
+++ b/cpukit/libmisc/serdbg/serdbgcnf.h
@@ -0,0 +1,89 @@
+/*===============================================================*\
+| Project: RTEMS configure remote gdb over serial line |
++-----------------------------------------------------------------+
+| File: serdbgcnf.h |
++-----------------------------------------------------------------+
+| Copyright (c) 2002 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file declares intialization functions to add |
+| a gdb remote debug stub to an RTEMS system |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 13.05.02 creation doe |
+\*===============================================================*/
+/*
+ * $Id$
+ */
+#ifndef _SERDBGCNF_H
+#define _SERDBGCNF_H
+
+#include <rtems/serdbg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef CONFIGURE_INIT
+
+/*
+ * fallback for baud rate to use
+ */
+#ifndef CONFIGURE_SERDBG_BAUDRATE
+#define CONFIGURE_SERDBG_BAUDRATE 9600
+#endif
+
+/*
+ * fallback for device name to use
+ */
+#ifndef CONFIGURE_SERDBG_DEVNAME
+#define CONFIGURE_SERDBG_DEVNAME "/dev/tty01"
+#endif
+
+/*
+ * fill in serdbg_conf structure
+ */
+serdbg_conf_t serdbg_conf = {
+ CONFIGURE_SERDBG_BAUDRATE,
+
+#ifdef CONFIGURE_SERDBG_CALLOUT
+ CONFIGURE_SERDBG_CALLOUT,
+#else
+ NULL,
+#endif
+
+#ifdef CONFIGURE_SERDBG_USE_POLLED_TERMIOS
+ serdbg_open,
+#else
+ NULL,
+#endif
+
+ CONFIGURE_SERDBG_DEVNAME,
+
+#ifdef CONFIGURE_SERDBG_SKIP_INIT_BKPT
+ TRUE,
+#else
+ FALSE,
+#endif
+};
+
+int serdbg_init(void) {
+#ifdef CONFIGURE_USE_SERDBG
+ extern int serdbg_init_dbg(void);
+ return serdbg_init_dbg();
+#else
+ return 0;
+#endif
+}
+
+#endif /* CONFIGURE_INIT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SERDBGCNF_H */
diff --git a/cpukit/libmisc/serdbg/serdbgio.c b/cpukit/libmisc/serdbg/serdbgio.c
new file mode 100644
index 0000000000..494a2fab0b
--- /dev/null
+++ b/cpukit/libmisc/serdbg/serdbgio.c
@@ -0,0 +1,256 @@
+/*===============================================================*\
+| File: serdbgio.c |
++-----------------------------------------------------------------+
+| Copyright (c) 2002 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| Hebststr. 8, 82178 Puchheim, Germany |
+| <Thomas.Doerfler@imd-systems.de> |
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| http://www.rtems.com/license/LICENSE. |
+| all rights reserved |
++-----------------------------------------------------------------+
+| TERMIOS serial gdb interface support |
+| the functions in this file allow the standard gdb stubs like |
+| "m68k-stub.c" to access any serial interfaces that work with |
+| RTEMS termios in polled mode |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 10.05.02 creation doe |
+|*****************************************************************|
+|* $Id$
+ *
+|*****************************************************************|
+\*===============================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio_.h>
+#include <errno.h>
+#include <unistd.h> /* close */
+#include <stdio.h>
+#include <fcntl.h>
+#include <termios.h>
+
+#include <rtems/termiostypes.h>
+#include <rtems/serdbg.h>
+
+
+/*
+ * internal variables
+ */
+int serdbg_fd = -1;
+struct rtems_termios_tty *serdbg_tty;
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int serdbg_open
+
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| try to open given serial debug port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ const char *dev_name, /* name of device to open */
+ uint32_t baudrate /* baud rate to use */
+)
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0 on success, -1 and errno otherwise |
+\*=========================================================================*/
+{
+ boolean err_occurred = FALSE;
+ rtems_libio_t *iop = NULL;
+ struct termios act_termios;
+ tcflag_t baudcode = B0;
+
+#define FD_STORE_CNT 3
+ int fd_store[FD_STORE_CNT];
+ int fd_store_used = 0;
+
+ /*
+ * translate baudrate into baud code
+ */
+ switch(baudrate) {
+ case 50: baudcode = B50; break;
+ case 75: baudcode = B75; break;
+ case 110: baudcode = B110; break;
+ case 134: baudcode = B134; break;
+ case 150: baudcode = B150; break;
+ case 200: baudcode = B200; break;
+ case 300: baudcode = B300; break;
+ case 600: baudcode = B600; break;
+ case 1200: baudcode = B1200; break;
+ case 1800: baudcode = B1800; break;
+ case 2400: baudcode = B2400; break;
+ case 4800: baudcode = B4800; break;
+ case 9600: baudcode = B9600; break;
+ case 19200: baudcode = B19200; break;
+ case 38400: baudcode = B38400; break;
+ case 57600: baudcode = B57600; break;
+ case 115200: baudcode = B115200; break;
+ case 230400: baudcode = B230400; break;
+ case 460800: baudcode = B460800; break;
+ default : err_occurred = TRUE; errno = EINVAL; break;
+ }
+
+ /*
+ * open device for serdbg operation
+ * skip any fds that are between 0..2, because they are
+ * reserved for stdin/out/err
+ */
+ if (!err_occurred &&
+ (dev_name != NULL) &&
+ (dev_name[0] != '\0')) {
+ do {
+ serdbg_fd = open(dev_name,O_RDWR);
+ if (serdbg_fd < 0) {
+ err_occurred = TRUE;
+ }
+ else {
+ if (serdbg_fd < 3) {
+ if (fd_store_used >= FD_STORE_CNT) {
+ err_occurred = TRUE;
+ }
+ else {
+ fd_store[fd_store_used++] = serdbg_fd;
+ }
+ }
+ }
+ } while (!err_occurred &&
+ (serdbg_fd < 3));
+ }
+ /*
+ * close any fds, that have been placed in fd_store
+ * so fd 0..2 are reusable again
+ */
+ while (--fd_store_used >= 0) {
+ close(fd_store[fd_store_used]);
+ }
+
+ /*
+ * capture tty structure
+ */
+ if (!err_occurred) {
+ iop = &rtems_libio_iops[serdbg_fd];
+ serdbg_tty = iop->data1;
+ }
+ /*
+ * set device baudrate
+ * (and transp mode, this is not really needed)
+ * ...
+ */
+ /*
+ * ... get fd settings
+ */
+ if (!err_occurred &&
+ (0 != tcgetattr(serdbg_fd,&act_termios))) {
+ err_occurred = TRUE;
+ }
+ if (!err_occurred) {
+ act_termios.c_iflag
+ &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
+ |INLCR|IGNCR|ICRNL|IXON);
+ act_termios.c_oflag
+ &= ~OPOST;
+
+ act_termios.c_lflag
+ &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+
+ cfsetospeed(&act_termios,baudcode);
+ cfsetispeed(&act_termios,baudcode);
+
+ if (0 != tcsetattr(serdbg_fd,TCSANOW,&act_termios)) {
+ err_occurred = TRUE;
+ }
+ }
+ return (err_occurred
+ ? -1
+ : 0);
+}
+
+void putDebugChar(char c) __attribute__ ((__weak__));
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+void putDebugChar
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| send one character to serial port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ char c /* character to print */
+)
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+{
+ /*
+ * call serdbg polling callout, if available
+ */
+ if (serdbg_conf.callout != NULL) {
+ serdbg_conf.callout();
+ }
+ /*
+ * check, whether debug serial port is available
+ */
+ if ((serdbg_tty != NULL) &&
+ (serdbg_tty->device.write != NULL)) {
+ /*
+ * send character to debug serial port
+ */
+ serdbg_tty->device.write(serdbg_tty->minor,&c,1);
+ }
+}
+
+int getDebugChar(void) __attribute__ ((__weak__));
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int getDebugChar
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| wait for one character from serial port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ void /* none */
+)
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| received character |
+\*=========================================================================*/
+{
+ int c = -1;
+ /*
+ * check, whether debug serial port is available
+ */
+ if ((serdbg_tty != NULL) &&
+ (serdbg_tty->device.pollRead != NULL)) {
+ do {
+ /*
+ * call serdbg polling callout, if available
+ */
+ if (serdbg_conf.callout != NULL) {
+ serdbg_conf.callout();
+ }
+ /*
+ * get character from debug serial port
+ */
+ c = serdbg_tty->device.pollRead(serdbg_tty->minor);
+ } while (c < 0);
+ }
+ return c;
+}
diff --git a/cpukit/libmisc/serdbg/termios_printk.c b/cpukit/libmisc/serdbg/termios_printk.c
new file mode 100644
index 0000000000..6e31bbcfd0
--- /dev/null
+++ b/cpukit/libmisc/serdbg/termios_printk.c
@@ -0,0 +1,237 @@
+/*===============================================================*\
+| File: termios_printk.c |
++-----------------------------------------------------------------+
+| Copyright (c) 2002 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| Hebststr. 8, 82178 Puchheim, Germany |
+| <Thomas.Doerfler@imd-systems.de> |
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| http://www.rtems.com/license/LICENSE. |
+| all rights reserved |
++-----------------------------------------------------------------+
+| TERMIOS printk support |
+| this module performs low-level printk output using |
+| a polled termios driver |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 13.05.02 creation doe |
+|*****************************************************************|
+|* $Id$
+ *
+|*****************************************************************|
+\*===============================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libio_.h>
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <termios.h>
+
+#include <rtems/termiostypes.h>
+#include <rtems/bspIo.h>
+#include <rtems/termios_printk.h>
+
+/*
+ * internal variables
+ */
+int termios_printk_fd = -1;
+struct rtems_termios_tty *termios_printk_tty;
+
+static void _termios_printk_null_char( char c ) {return;}
+
+BSP_output_char_function_type BSP_output_char = _termios_printk_null_char;
+BSP_polling_getchar_function_type BSP_poll_char;
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+void termios_printk_outputchar
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| send one character to serial port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ char c /* character to print */
+)
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+{
+ static const char cr = '\r';
+ /*
+ * check, whether printk serial port is available
+ */
+
+ if ((termios_printk_tty != NULL) &&
+ (termios_printk_tty->device.write != NULL)) {
+ /*
+ * call termios_printk polling callout, if available
+ */
+ if (termios_printk_conf.callout != NULL) {
+ termios_printk_conf.callout();
+ }
+ /*
+ * send character to debug serial port
+ */
+ if (c == '\n') {
+ termios_printk_tty->device.write(termios_printk_tty->minor,&cr,1);
+ }
+ termios_printk_tty->device.write(termios_printk_tty->minor,&c,1);
+ }
+}
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+char termios_printk_inputchar
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| wait for one character from serial port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ void /* none */
+)
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| received character |
+\*=========================================================================*/
+{
+ int c = -1;
+ /*
+ * check, whether debug serial port is available
+ */
+ if ((termios_printk_tty != NULL) &&
+ (termios_printk_tty->device.pollRead != NULL)) {
+ do {
+ /*
+ * call termios_printk polling callout, if available
+ */
+ if (termios_printk_conf.callout != NULL) {
+ termios_printk_conf.callout();
+ }
+ /*
+ * get character from debug serial port
+ */
+ c = termios_printk_tty->device.pollRead(termios_printk_tty->minor);
+ } while (c < 0);
+ }
+ return c;
+}
+
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int termios_printk_open
+
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| try to open given serial debug port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ const char *dev_name, /* name of device to open */
+ uint32_t baudrate /* baud rate to use */
+)
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0 on success, -1 and errno otherwise |
+\*=========================================================================*/
+{
+ boolean err_occurred = FALSE;
+ rtems_libio_t *iop = NULL;
+ struct termios act_termios;
+ tcflag_t baudcode = B0;
+
+ if (termios_printk_fd >= 0) {
+ /*
+ * already initialized
+ */
+ return 0;
+ }
+ /*
+ * translate baudrate into baud code
+ */
+ switch(baudrate) {
+ case 50: baudcode = B50; break;
+ case 75: baudcode = B75; break;
+ case 110: baudcode = B110; break;
+ case 134: baudcode = B134; break;
+ case 150: baudcode = B150; break;
+ case 200: baudcode = B200; break;
+ case 300: baudcode = B300; break;
+ case 600: baudcode = B600; break;
+ case 1200: baudcode = B1200; break;
+ case 1800: baudcode = B1800; break;
+ case 2400: baudcode = B2400; break;
+ case 4800: baudcode = B4800; break;
+ case 9600: baudcode = B9600; break;
+ case 19200: baudcode = B19200; break;
+ case 38400: baudcode = B38400; break;
+ case 57600: baudcode = B57600; break;
+ case 115200: baudcode = B115200; break;
+ case 230400: baudcode = B230400; break;
+ case 460800: baudcode = B460800; break;
+ default : err_occurred = TRUE; errno = EINVAL; break;
+ }
+ /*
+ * open device for serdbg operation
+ */
+ if (!err_occurred &&
+ (dev_name != NULL) &&
+ (dev_name[0] != '\0')) {
+ termios_printk_fd = open(dev_name,O_RDWR);
+ if (termios_printk_fd < 0) {
+ err_occurred = TRUE;
+ }
+ }
+ /*
+ * capture tty structure
+ */
+ if (!err_occurred) {
+ iop = &rtems_libio_iops[termios_printk_fd];
+ termios_printk_tty = iop->data1;
+ }
+ /*
+ * set device baudrate
+ * (and transp mode, this is not really needed)
+ * ...
+ */
+ /*
+ * ... get fd settings
+ */
+ if (!err_occurred &&
+ (0 != tcgetattr(termios_printk_fd,&act_termios))) {
+ err_occurred = TRUE;
+ }
+ if (!err_occurred) {
+
+ cfsetospeed(&act_termios,baudcode);
+ cfsetispeed(&act_termios,baudcode);
+
+ if (0 != tcsetattr(termios_printk_fd,TCSANOW,&act_termios)) {
+ err_occurred = TRUE;
+ }
+ }
+ if (!err_occurred) {
+ BSP_output_char = termios_printk_outputchar;
+ BSP_poll_char = termios_printk_inputchar;
+ }
+ return (err_occurred
+ ? -1
+ : 0);
+}
diff --git a/cpukit/libmisc/serdbg/termios_printk.h b/cpukit/libmisc/serdbg/termios_printk.h
new file mode 100644
index 0000000000..7392991753
--- /dev/null
+++ b/cpukit/libmisc/serdbg/termios_printk.h
@@ -0,0 +1,104 @@
+/*===============================================================*\
+| Project: RTEMS remote gdb over serial line |
++-----------------------------------------------------------------+
+| File: termios_printk.h |
++-----------------------------------------------------------------+
+| Copyright (c) 2002 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file declares intialization functions to add |
+| printk polled output via termios polled drivers |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 13.04.02 creation doe |
+\*===============================================================*/
+/*
+ * $Id$
+ */
+#ifndef _TERMIOS_PRINTK_H
+#define _TERMIOS_PRINTK_H
+
+#include <rtems.h>
+#include <termios.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ uint32_t baudrate; /* debug baud rate, e.g. 57600 */
+ void (*callout)(void); /* callout pointer during polling */
+ const char *devname; /* debug device, e.g. "/dev/tty01" */
+} termios_printk_conf_t;
+
+/*
+ * must be defined in init module...
+ */
+extern termios_printk_conf_t termios_printk_conf;
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+void termios_printk_outputchar
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| send one character to serial port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ char c /* character to print */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+char termios_printk_inputchar
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| wait for one character from serial port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ void /* none */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| received character |
+\*=========================================================================*/
+
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int termios_printk_open
+
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| try to open given serial debug port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ const char *dev_name, /* name of device to open */
+ uint32_t baudrate /* baud rate to use */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0 on success, -1 and errno otherwise |
+\*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TERMIOS_PRINTK_H */
diff --git a/cpukit/libmisc/serdbg/termios_printk_cnf.h b/cpukit/libmisc/serdbg/termios_printk_cnf.h
new file mode 100644
index 0000000000..2e8a7ac043
--- /dev/null
+++ b/cpukit/libmisc/serdbg/termios_printk_cnf.h
@@ -0,0 +1,78 @@
+/*===============================================================*\
+| Project: RTEMS configure remote gdb over serial line |
++-----------------------------------------------------------------+
+| File: termios_printk_cnf.h |
++-----------------------------------------------------------------+
+| Copyright (c) 2002 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file declares intialization functions to add |
+| printk support via polled termios |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 13.05.02 creation doe |
+\*===============================================================*/
+/*
+ * $Id$
+ */
+#ifndef _TERMIOS_PRINTK_CNF_H
+#define _TERMIOS_PRINTK_CNF_H
+
+#include <rtems/termios_printk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef CONFIGURE_INIT
+
+/*
+ * fallback for baud rate to use
+ */
+#ifndef CONFIGURE_TERMIOS_PRINTK_BAUDRATE
+#define CONFIGURE_TERMIOS_PRINTK_BAUDRATE 9600
+#endif
+
+/*
+ * fallback for device name to use
+ */
+#ifndef CONFIGURE_TERMIOS_PRINTK_DEVNAME
+#define CONFIGURE_TERMIOS_PRINTK_DEVNAME "/dev/console"
+#endif
+
+#ifdef CONFIGURE_USE_TERMIOS_PRINTK
+/*
+ * fill in termios_printk_conf structure
+ */
+termios_printk_conf_t termios_printk_conf = {
+ CONFIGURE_TERMIOS_PRINTK_BAUDRATE,
+
+#ifdef CONFIGURE_TERMIOS_PRINTK_CALLOUT
+ CONFIGURE_TERMIOS_PRINTK_CALLOUT,
+#else
+ NULL,
+#endif
+ CONFIGURE_TERMIOS_PRINTK_DEVNAME,
+};
+#endif
+
+int termios_printk_init(void) {
+#ifdef CONFIGURE_USE_TERMIOS_PRINTK
+ return termios_printk_open(termios_printk_conf.devname,
+ termios_printk_conf.baudrate);
+#else
+ return 0;
+#endif
+}
+
+#endif /* CONFIGURE_INIT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TERMIOS_PRINTK_CNF_H */
diff --git a/cpukit/libmisc/shell/README b/cpukit/libmisc/shell/README
new file mode 100644
index 0000000000..9798becc37
--- /dev/null
+++ b/cpukit/libmisc/shell/README
@@ -0,0 +1,27 @@
+#
+# $Id$
+#
+
+This directory contains a shell user extension
+primary features:
+
+ + create a user shell terminal task.
+
+This code has not been extensively tested. It is provided as a tool
+for RTEMS users to open more shell terminal.
+Suggestions and comments are appreciated.
+
+NOTES:
+
+1. printf() & getchar() works but you can't use
+ 0,1,2 like fildes. You need to use fileno(stdin),fileno(stdout),...
+
+2. You only need a termios dev to start a new session, add your new commands
+ and enjoy it.
+
+3. Telnetd daemon uses this (browse libnetworking/rtems_telnetd)
+ Enjoy it.
+
+FUTURE:
+
+1. Adding new commands in cmds.c to give file manegement to shell.
diff --git a/cpukit/libmisc/shell/cmds.c b/cpukit/libmisc/shell/cmds.c
new file mode 100644
index 0000000000..ba3a4b030e
--- /dev/null
+++ b/cpukit/libmisc/shell/cmds.c
@@ -0,0 +1,526 @@
+/*
+ * Author: Fernando RUIZ CASAS
+ *
+ * Work: fernando.ruiz@ctv.es
+ * Home: correo@fernando-ruiz.com
+ *
+ * This file is inspired in rtems_monitor & Chris John MyRightBoot
+ *
+ * But I want to make it more user friendly
+ * A 'monitor' command is added to adapt the call rtems monitor commands
+ * at my call procedure
+ *
+ * TODO: A lot of improvements of course.
+ * cp, mv, ...
+ * hexdump,
+ *
+ * More? Say me it, please...
+ *
+ * The BSP Specific are not welcome here.
+ *
+ * C&S welcome...
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <termios.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <stddef.h>
+
+#include <rtems.h>
+#include <rtems/monitor.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/imfs.h>
+#include <rtems/shell.h>
+
+/* ----------------------------------------------- *
+ - str to int "0xaffe" "0b010010" "0123" "192939"
+ * ----------------------------------------------- */
+int str2int(char * s) {
+ int sign=1;
+ int base=10;
+ int value=0;
+ int digit;
+ if (!s) return 0;
+ if (*s) {
+ if (*s=='-') {
+ sign=-1;
+ s++;
+ if (!*s) return 0;
+ };
+ if (*s=='0') {
+ s++;
+ switch(*s) {
+ case 'x':
+ case 'X':s++;
+ base=16;
+ break;
+ case 'b':
+ case 'B':s++;
+ base=2;
+ break;
+ default :base=8;
+ break;
+ }
+ };
+ while (*s) {
+ switch(*s) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':digit=*s-'0';
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':digit=*s-'A'+10;
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':digit=*s-'a'+10;
+ break;
+ default:return value*sign;
+ };
+ if (digit>base) return value*sign;
+ value=value*base+digit;
+ s++;
+ };
+ };
+ return value*sign;
+}
+/*----------------------------------------------------------------------------*
+ * RAM MEMORY COMMANDS
+ *----------------------------------------------------------------------------*/
+
+#define mdump_adr (current_shell_env->mdump_adr) /* static value */
+
+int main_mdump(int argc,char * argv[]) {
+ unsigned char n,m,max=0;
+ int adr=mdump_adr;
+ unsigned char * pb;
+ if (argc>1) adr=str2int(argv[1]);
+ if (argc>2) max=str2int(argv[2]);
+ max/=16;
+ if (!max) max=20;
+ for (m=0;m<max;m++) {
+ fprintf(stdout,"0x%08X ",adr);
+ pb=(unsigned char*) adr;
+ for (n=0;n<16;n++)
+ fprintf(stdout,"%02X%c",pb[n],n==7?'-':' ');
+ for (n=0;n<16;n++) {
+ fprintf(stdout,"%c",isprint(pb[n])?pb[n]:'.');
+ };
+ fprintf(stdout,"\n");
+ adr+=16;
+ };
+ mdump_adr=adr;
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+int main_mwdump(int argc,char * argv[]) {
+ unsigned char n,m,max=0;
+ int adr=mdump_adr;
+ unsigned short * pw;
+ if (argc>1) adr=str2int(argv[1]);
+ if (argc>2) max=str2int(argv[2]);
+ max/=16;
+ if (!max) max=20;
+ for (m=0;m<max;m++) {
+ fprintf(stdout,"0x%08X ",adr);
+ pw=(unsigned short*) adr;
+ for (n=0;n<8;n++)
+ fprintf(stdout,"%02X %02X%c",pw[n]/0x100,pw[n]%0x100,n==3?'-':' ');
+ for (n=0;n<8;n++) {
+ fprintf(stdout,"%c",isprint(pw[n]/0x100)?pw[n]/0x100:'.');
+ fprintf(stdout,"%c",isprint(pw[n]%0x100)?pw[n]%0x100:'.');
+ };
+ fprintf(stdout,"\n");
+ adr+=16;
+ };
+ mdump_adr=adr;
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+int main_medit(int argc,char * argv[]) {
+ unsigned char * pb;
+ int n,i;
+ if (argc<3) {
+ fprintf(stdout,"too few arguments\n");
+ return 0;
+ };
+ pb=(unsigned char*)str2int(argv[1]);
+ i=2;
+ n=0;
+ while (i<=argc) {
+ pb[n++]=str2int(argv[i++])%0x100;
+ }
+ mdump_adr=(int)pb;
+ return main_mdump(0,NULL);
+}
+/*----------------------------------------------------------------------------*/
+int main_mfill(int argc,char * argv[]) {
+ int adr;
+ int size;
+ unsigned char value;
+ if (argc<4) {
+ fprintf(stdout,"too few arguments\n");
+ return 0;
+ };
+ adr =str2int(argv[1]);
+ size =str2int(argv[2]);
+ value=str2int(argv[3])%0x100;
+ memset((unsigned char*)adr,size,value);
+ mdump_adr=adr;
+ return main_mdump(0,NULL);
+}
+/*----------------------------------------------------------------------------*/
+int main_mmove(int argc,char * argv[]) {
+ int src;
+ int dst;
+ int size;
+ if (argc<4) {
+ fprintf(stdout,"too few arguments\n");
+ return 0;
+ };
+ dst =str2int(argv[1]);
+ src =str2int(argv[2]);
+ size =str2int(argv[3]);
+ memcpy((unsigned char*)dst,(unsigned char*)src,size);
+ mdump_adr=dst;
+ return main_mdump(0,NULL);
+}
+/*----------------------------------------------------------------------------*/
+#ifdef MALLOC_STATS /* /rtems/s/src/lib/libc/malloc.c */
+int main_malloc_dump(int argc,char * argv[]) {
+ void malloc_dump(void);
+ malloc_dump();
+ return 0;
+}
+#endif
+/*----------------------------------------------------------------------------
+ * Reset. Assumes that the watchdog is present.
+ *----------------------------------------------------------------------------*/
+int main_reset (int argc, char **argv)
+{
+ rtems_interrupt_level level;
+ fprintf(stdout,"Waiting for watchdog ... ");
+ tcdrain(fileno(stdout));
+
+ rtems_interrupt_disable (level);
+ for (;;)
+ ;
+ return 0;
+}
+/*----------------------------------------------------------------------------
+ * Alias. make an alias
+ *----------------------------------------------------------------------------*/
+int main_alias (int argc, char **argv)
+{
+ if (argc<3) {
+ fprintf(stdout,"too few arguments\n");
+ return 1;
+ };
+ if (!shell_alias_cmd(argv[1],argv[2])) {
+ fprintf(stdout,"unable to make an alias(%s,%s)\n",argv[1],argv[2]);
+ };
+ return 0;
+}
+/*-----------------------------------------------------------*
+ * Directory commands
+ *-----------------------------------------------------------*/
+int main_ls(int argc, char *argv[])
+{
+ char * fname;
+ DIR *dirp;
+ struct dirent *dp;
+ struct stat stat_buf;
+ struct passwd * pwd;
+ struct group * grp;
+ char * user;
+ char * group;
+ char sbuf[256];
+ char nbuf[1024];
+ int n,size;
+
+ fname=".";
+ if (argc>1) fname=argv[1];
+
+ if ((dirp = opendir(fname)) == NULL)
+ {
+ fprintf(stdout,"%s: No such file or directory.\n", fname);
+ return errno;
+ }
+ n=0;
+ size=0;
+ while ((dp = readdir(dirp)) != NULL)
+ {
+ strcpy(nbuf,fname);
+ if (nbuf[strlen(nbuf)-1]!='/') strcat(nbuf,"/");
+ strcat(nbuf,dp->d_name); /* always the fullpathname. Avoid ftpd problem.*/
+ if (stat(nbuf, &stat_buf) == 0)
+ { /* AWFUL buts works...*/
+ strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M",gmtime(&stat_buf.st_mtime));
+ pwd=getpwuid(stat_buf.st_uid);
+ user=pwd?pwd->pw_name:"nouser";
+ grp=getgrgid(stat_buf.st_gid);
+ group=grp?grp->gr_name:"nogrp";
+ fprintf(stdout,"%c%c%c%c%c%c%c%c%c%c %3d %6.6s %6.6s %11d %s %s%c\n",
+ (S_ISLNK(stat_buf.st_mode)?('l'):
+ (S_ISDIR(stat_buf.st_mode)?('d'):('-'))),
+ (stat_buf.st_mode & S_IRUSR)?('r'):('-'),
+ (stat_buf.st_mode & S_IWUSR)?('w'):('-'),
+ (stat_buf.st_mode & S_IXUSR)?('x'):('-'),
+ (stat_buf.st_mode & S_IRGRP)?('r'):('-'),
+ (stat_buf.st_mode & S_IWGRP)?('w'):('-'),
+ (stat_buf.st_mode & S_IXGRP)?('x'):('-'),
+ (stat_buf.st_mode & S_IROTH)?('r'):('-'),
+ (stat_buf.st_mode & S_IWOTH)?('w'):('-'),
+ (stat_buf.st_mode & S_IXOTH)?('x'):('-'),
+ (int)stat_buf.st_nlink,
+ user,group,
+ (int)stat_buf.st_size,
+ sbuf,
+ dp->d_name,
+ S_ISDIR(stat_buf.st_mode)?'/':' ');
+ n++;
+ size+=stat_buf.st_size;
+ }
+ }
+ fprintf(stdout,"%d files %d bytes occupied\n",n,size);
+ closedir(dirp);
+ return 0;
+}
+/*-----------------------------------------------------------*/
+int main_pwd (int argc, char *argv[]) {
+ char dir[1024];
+ getcwd(dir,1024);
+ fprintf(stdout,"%s\n",dir);
+ return 0;
+}
+/*-----------------------------------------------------------*/
+int main_chdir (int argc, char *argv[]) {
+ char *dir;
+ dir="/";
+ if (argc>1) dir=argv[1];
+ if (chdir(dir)) {
+ fprintf(stdout,"chdir to '%s' failed:%s\n",dir,strerror(errno));
+ return errno;
+ };
+ return 0;
+}
+/*-----------------------------------------------------------*/
+int main_mkdir (int argc, char *argv[]) {
+ char *dir;
+ int n;
+ n=1;
+ while (n<argc) {
+ dir=argv[n++];
+ if (mkdir(dir,S_IRWXU|S_IRWXG|S_IRWXO)) {
+ fprintf(stdout,"mkdir '%s' failed:%s\n",dir,strerror(errno));
+ };
+ };
+ return errno;
+}
+/*-----------------------------------------------------------*/
+int main_rmdir (int argc, char *argv[])
+{
+ char *dir;
+ int n;
+ n=1;
+ while (n<argc) {
+ dir=argv[n++];
+ if (rmdir(dir)) fprintf(stdout,"rmdir '%s' failed:%s\n",dir,strerror(errno));
+ };
+ return errno;
+}
+/*-----------------------------------------------------------*/
+int main_chroot(int argc,char * argv[]) {
+ char * new_root="/";
+ if (argc==2) new_root=argv[1];
+ if (chroot(new_root)<0) {
+ fprintf(stdout,"error %s:chroot(%s);\n",strerror(errno),new_root);
+ return -1;
+ };
+ return 0;
+}
+/*-----------------------------------------------------------*/
+int main_cat (int argc, char *argv[])
+{
+ int n;
+ n=1;
+ while (n<argc) cat_file(stdout,argv[n++]);
+ return 0;
+}
+/*-----------------------------------------------------------*/
+int main_rm (int argc, char *argv[])
+{
+ int n;
+ n=1;
+ while (n<argc) {
+ if (unlink(argv[n])) {
+ fprintf(stdout,"error %s:rm %s\n",strerror(errno),argv[n]);
+ return -1;
+ };
+ n++;
+ };
+ return 0;
+}
+/*-----------------------------------------------------------*/
+/* date - print time and date */
+
+int main_date(int argc,char *argv[])
+{
+ time_t t;
+ time(&t);
+ fprintf(stdout,"%s", ctime(&t));
+ return 0;
+}
+/*-----------------------------------------------------------*/
+int main_logoff(int argc,char *argv[])
+{
+ fprintf(stdout,"logoff from the system...");
+ current_shell_env->exit_shell=TRUE;
+ return 0;
+}
+/*-----------------------------------------------------------*/
+int main_tty (int argc,char *argv[])
+{
+ fprintf(stdout,"%s\n",ttyname(fileno(stdin)));
+ return 0;
+}
+/*-----------------------------------------------------------*/
+int main_whoami(int argc,char *argv[])
+{
+ struct passwd * pwd;
+ pwd=getpwuid(getuid());
+ fprintf(stdout,"%s\n",pwd?pwd->pw_name:"nobody");
+ return 0;
+}
+/*-----------------------------------------------------------*/
+int main_id (int argc,char *argv[])
+{
+ struct passwd * pwd;
+ struct group * grp;
+ pwd=getpwuid(getuid());
+ grp=getgrgid(getgid());
+ fprintf(stdout,"uid=%d(%s),gid=%d(%s),",
+ getuid(),pwd?pwd->pw_name:"",
+ getgid(),grp?grp->gr_name:"");
+ pwd=getpwuid(geteuid());
+ grp=getgrgid(getegid());
+ fprintf(stdout,"euid=%d(%s),egid=%d(%s)\n",
+ geteuid(),pwd?pwd->pw_name:"",
+ getegid(),grp?grp->gr_name:"");
+ return 0;
+}
+/*-----------------------------------------------------------*/
+int main_umask(int argc,char *argv[])
+{
+ mode_t msk=umask(0);
+ if (argc == 2) msk=str2int(argv[1]);
+ umask(msk);
+ msk=umask(0);
+ fprintf(stdout,"0%o\n", (unsigned int) msk);
+ umask(msk);
+ return 0;
+}
+/*-----------------------------------------------------------*/
+int main_chmod(int argc,char *argv[])
+{
+ int n;
+ mode_t mode;
+ if (argc > 2){
+ mode=str2int(argv[1])&0777;
+ n=2;
+ while (n<argc) chmod(argv[n++],mode);
+ };
+ return 0;
+}
+/*-----------------------------------------------------------*
+ * with this you can call at all the rtems monitor commands.
+ * Not all work fine but you can show the rtems status and more.
+ *-----------------------------------------------------------*/
+int main_monitor(int argc,char * argv[]) {
+ rtems_monitor_command_entry_t *command;
+ rtems_task_ident(RTEMS_SELF,0,&rtems_monitor_task_id);
+ rtems_monitor_node = rtems_get_node(rtems_monitor_task_id);
+ rtems_monitor_default_node = rtems_monitor_node;
+ if ((command=rtems_monitor_command_lookup(rtems_monitor_commands,argc,argv)))
+ command->command_function(argc, argv, &command->command_arg, 0);
+ return 0;
+}
+/*-----------------------------------------------------------*/
+void register_cmds(void) {
+ rtems_monitor_command_entry_t *command;
+ /* monitor topic */
+ command=rtems_monitor_commands;
+ while (command) {
+ if (strcmp("exit",command->command)) /*Exclude EXIT (alias quit)*/
+ shell_add_cmd(command->command,"monitor",
+ command->usage ,main_monitor);
+ command=command->next;
+ };
+ /* dir[ectories] topic */
+ shell_add_cmd ("ls" ,"dir","ls [dir] # list files in the directory" ,main_ls );
+ shell_add_cmd ("chdir" ,"dir","chdir [dir] # change the current directory",main_chdir);
+ shell_add_cmd ("rmdir" ,"dir","rmdir dir # remove directory" ,main_rmdir);
+ shell_add_cmd ("mkdir" ,"dir","mkdir dir # make a directory" ,main_mkdir);
+ shell_add_cmd ("pwd" ,"dir","pwd # print work directory" ,main_pwd );
+ shell_add_cmd ("chroot","dir","chroot [dir] # change the root directory" ,main_chroot);
+ shell_add_cmd ("cat" ,"dir","cat n1 [n2 [n3...]]# show the ascii contents",main_cat );
+ shell_add_cmd ("rm" ,"dir","rm n1 [n2 [n3...]]# remove files" ,main_rm );
+ shell_add_cmd ("chmod" ,"dir","chmod 0777 n1 n2... #change filemode" ,main_chmod);
+
+ shell_alias_cmd("ls" ,"dir");
+ shell_alias_cmd("chdir" ,"cd");
+
+ /* misc. topic */
+ shell_add_cmd ("logoff","misc","logoff from the system" ,main_logoff);
+ shell_alias_cmd("logoff","exit");
+ shell_add_cmd ("date" ,"misc","date" ,main_date);
+ shell_add_cmd ("reset","misc","reset the BSP" ,main_reset);
+ shell_add_cmd ("alias","misc","alias old new" ,main_alias);
+ shell_add_cmd ("tty" ,"misc","show ttyname" ,main_tty );
+ shell_add_cmd ("whoami","misc","show current user" ,main_whoami);
+ shell_add_cmd ("id" ,"misc","show uid,gid,euid,egid" ,main_id );
+ shell_add_cmd ("umask" ,"misc","umask [new_umask]" ,main_umask );
+
+
+ /* memory topic */
+ shell_add_cmd ("mdump","mem" ,"mdump [adr [size]]" ,main_mdump);
+ shell_add_cmd ("wdump","mem" ,"wdump [adr [size]]" ,main_mwdump);
+ shell_add_cmd ("medit","mem" ,"medit adr value [value ...]" ,main_medit);
+ shell_add_cmd ("mfill","mem" ,"mfill adr size value" ,main_mfill);
+ shell_add_cmd ("mmove","mem" ,"mmove dst src size" ,main_mmove);
+#ifdef MALLOC_STATS /* /rtems/s/src/lib/libc/malloc.c */
+ shell_add_cmd ("malloc","mem","mem show memory malloc'ed" ,main_mem);
+#endif
+}
+/*-----------------------------------------------------------*/
diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c
new file mode 100644
index 0000000000..5a67d5dd24
--- /dev/null
+++ b/cpukit/libmisc/shell/shell.c
@@ -0,0 +1,691 @@
+/*
+ *
+ * Instantatiate a new terminal shell.
+ *
+ * Author:
+ *
+ * WORK: fernando.ruiz@ctv.es
+ * HOME: correo@fernando-ruiz.com
+ *
+ * Thanks at:
+ * Chris John
+ *
+ * $Id$
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <time.h>
+
+#include <rtems.h>
+#include <rtems/error.h>
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+#include <rtems/system.h>
+#include <rtems/shell.h>
+
+#include <termios.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pwd.h>
+
+/* ----------------------------------------------- *
+ * This is a stupidity but is cute.
+ * ----------------------------------------------- */
+uint32_t new_rtems_name(char * rtems_name) {
+ static char b[5];
+ sprintf(b,"%-4.4s",rtems_name);
+ return rtems_build_name(b[0],b[1],b[2],b[3]);
+}
+/* **************************************************************
+ * common linked list of shell commands.
+ * Because the help report is very long
+ * I have a topic for each command.
+ * Help list the topics
+ * help [topic] list the commands for the topic
+ * help [command] help for the command
+ * Can you see help rtems monitor report?
+ * ************************************************************** */
+
+struct shell_topic_tt;
+typedef struct shell_topic_tt shell_topic_t;
+
+struct shell_topic_tt {
+ char * topic;
+ shell_topic_t * next;
+};
+
+
+static shell_cmd_t * shell_first_cmd;
+static shell_topic_t * shell_first_topic;
+/* ----------------------------------------------- *
+ * Using Chain I can reuse the rtems code.
+ * I am more comfortable with this, sorry.
+ * ----------------------------------------------- */
+shell_topic_t * shell_lookup_topic(char * topic) {
+ shell_topic_t * shell_topic;
+ shell_topic=shell_first_topic;
+ while (shell_topic) {
+ if (!strcmp(shell_topic->topic,topic)) return shell_topic;
+ shell_topic=shell_topic->next;
+ };
+ return (shell_topic_t *) NULL;
+}
+/* ----------------------------------------------- */
+shell_topic_t * shell_add_topic(char * topic) {
+ shell_topic_t * current,*aux;
+ if (!shell_first_topic) {
+ aux=malloc(sizeof(shell_topic_t));
+ aux->topic=topic;
+ aux->next=(shell_topic_t*)NULL;
+ return shell_first_topic=aux;
+ } else {
+ current=shell_first_topic;
+ if (!strcmp(topic,current->topic)) return current;
+ while (current->next) {
+ if (!strcmp(topic,current->next->topic)) return current->next;
+ current=current->next;
+ };
+ aux=malloc(sizeof(shell_topic_t));
+ aux->topic=topic;
+ aux->next=(shell_topic_t*)NULL;
+ current->next=aux;
+ return aux;
+ };
+}
+/* ----------------------------------------------- */
+shell_cmd_t * shell_lookup_cmd(char * cmd) {
+ shell_cmd_t * shell_cmd;
+ shell_cmd=shell_first_cmd;
+ while (shell_cmd) {
+ if (!strcmp(shell_cmd->name,cmd)) return shell_cmd;
+ shell_cmd=shell_cmd->next;
+ };
+ return (shell_cmd_t *) NULL;
+}
+/* ----------------------------------------------- */
+shell_cmd_t * shell_add_cmd(char * cmd,
+ char * topic,
+ char * usage,
+ shell_command_t command) {
+ int shell_help(int argc,char * argv[]);
+ shell_cmd_t * shell_cmd,*shell_pvt;
+ if (!shell_first_cmd) {
+ shell_first_cmd=(shell_cmd_t *) malloc(sizeof(shell_cmd_t));
+ shell_first_cmd->name ="help";
+ shell_first_cmd->topic ="help";
+ shell_first_cmd->usage ="help [topic] # list of usage of commands";
+ shell_first_cmd->command=shell_help;
+ shell_first_cmd->alias =(shell_cmd_t *) NULL;
+ shell_first_cmd->next =(shell_cmd_t *) NULL;
+ shell_add_topic(shell_first_cmd->topic);
+ register_cmds();
+ };
+ if (!cmd) return (shell_cmd_t *) NULL;
+ if (!command) return (shell_cmd_t *) NULL;
+ shell_cmd=(shell_cmd_t *) malloc(sizeof(shell_cmd_t));
+ shell_cmd->name =cmd;
+ shell_cmd->topic =topic;
+ shell_cmd->usage =usage;
+ shell_cmd->command=command;
+ shell_cmd->alias =(shell_cmd_t *) NULL;
+ shell_cmd->next =(shell_cmd_t *) NULL;
+ shell_add_topic(shell_cmd->topic);
+ shell_pvt=shell_first_cmd;
+ while (shell_pvt->next) shell_pvt=shell_pvt->next;
+ return shell_pvt->next=shell_cmd;
+}
+/* ----------------------------------------------- *
+ * you can make an alias for every command.
+ * ----------------------------------------------- */
+shell_cmd_t * shell_alias_cmd(char * cmd, char * alias) {
+ shell_cmd_t * shell_cmd,* shell_aux;
+ shell_aux=(shell_cmd_t *) NULL;
+ if (alias) {
+ if ((shell_aux=shell_lookup_cmd(alias))!=NULL) {
+ return NULL;
+ };
+ if ((shell_cmd=shell_lookup_cmd(cmd))!=NULL) {
+ shell_aux=shell_add_cmd(alias,shell_cmd->topic,
+ shell_cmd->usage,shell_cmd->command);
+ if (shell_aux) shell_aux->alias=shell_cmd;
+ };
+ };
+ return shell_aux;
+}
+/* ----------------------------------------------- *
+ * Poor but enough..
+ * TODO: Redirection capture. "" evaluate, ... C&S welcome.
+ * ----------------------------------------------- */
+int shell_make_args(char * cmd,
+ int * pargc,
+ char * argv[]) {
+ int argc=0;
+ while ((cmd=strtok(cmd," \t\r\n"))!=NULL) {
+ argv[argc++]=cmd;
+ cmd=(char*)NULL;
+ };
+ argv[argc]=(char*)NULL;
+ return *pargc=argc;
+}
+/* ----------------------------------------------- *
+ * show the help for one command.
+ * ----------------------------------------------- */
+int shell_help_cmd(shell_cmd_t * shell_cmd) {
+ char * pc;
+ int col,line;
+ fprintf(stdout,"%-10.10s -",shell_cmd->name);
+ col=12;
+ line=1;
+ if (shell_cmd->alias) {
+ fprintf(stdout,"is an <alias> for command '%s'",shell_cmd->alias->name);
+ } else
+ if (shell_cmd->usage) {
+ pc=shell_cmd->usage;
+ while (*pc) {
+ switch(*pc) {
+ case '\r':break;
+ case '\n':putchar('\n');
+ col=0;
+ break;
+ default :putchar(*pc);
+ col++;
+ break;
+ };
+ pc++;
+ if(col>78) { /* What daring... 78?*/
+ if (*pc) {
+ putchar('\n');
+ col=0;
+ };
+ };
+ if (!col && *pc) {
+ fprintf(stdout," ");
+ col=12;line++;
+ };
+ };
+ };
+ puts("");
+ return line;
+}
+/* ----------------------------------------------- *
+ * show the help. The first command implemented.
+ * Can you see the header of routine? Known?
+ * The same with all the commands....
+ * ----------------------------------------------- */
+int shell_help(int argc,char * argv[]) {
+ int col,line,arg;
+ shell_topic_t *topic;
+ shell_cmd_t * shell_cmd=shell_first_cmd;
+ if (argc<2) {
+ fprintf(stdout,"help: ('r' repeat last cmd - 'e' edit last cmd)\n"
+ " TOPIC? The topics are\n");
+ topic=shell_first_topic;
+ col=0;
+ while (topic) {
+ if (!col){
+ col=fprintf(stdout," %s",topic->topic);
+ } else {
+ if ((col+strlen(topic->topic)+2)>78){
+ fprintf(stdout,"\n");
+ col=fprintf(stdout," %s",topic->topic);
+ } else {
+ col+=fprintf(stdout,", %s",topic->topic);
+ };
+ };
+ topic=topic->next;
+ };
+ fprintf(stdout,"\n");
+ return 1;
+ };
+ line=0;
+ for (arg=1;arg<argc;arg++) {
+ if (line>16) {
+ fprintf(stdout,"Press any key to continue...");getchar();
+ fprintf(stdout,"\n");
+ line=0;
+ };
+ topic=shell_lookup_topic(argv[arg]);
+ if (!topic){
+ if ((shell_cmd=shell_lookup_cmd(argv[arg]))==NULL) {
+ fprintf(stdout,"help: topic or cmd '%s' not found. Try <help> alone for a list\n",argv[arg]);
+ line++;
+ } else {
+ line+=shell_help_cmd(shell_cmd);
+ }
+ continue;
+ };
+ fprintf(stdout,"help: list for the topic '%s'\n",argv[arg]);
+ line++;
+ while (shell_cmd) {
+ if (!strcmp(topic->topic,shell_cmd->topic))
+ line+=shell_help_cmd(shell_cmd);
+ if (line>16) {
+ fprintf(stdout,"Press any key to continue...");getchar();
+ fprintf(stdout,"\n");
+ line=0;
+ };
+ shell_cmd=shell_cmd->next;
+ };
+ };
+ puts("");
+ return 0;
+}
+/* ----------------------------------------------- *
+ * TODO: Add improvements. History, edit vi or emacs, ...
+ * ----------------------------------------------- */
+int shell_scanline(char * line,int size,FILE * in,FILE * out) {
+ int c,col;
+ col=0;
+ if (*line) {
+ col=strlen(line);
+ if (out) fprintf(out,"%s",line);
+ };
+ tcdrain(fileno(in ));
+ if (out) tcdrain(fileno(out));
+ for (;;) {
+ line[col]=0;
+ c=fgetc(in);
+ switch (c) {
+ case 0x04:/*Control-d*/
+ if (col) break;
+ case EOF :return 0;
+ case '\n':break;
+ case '\f':if (out) fputc('\f',out);
+ case 0x03:/*Control-C*/
+ line[0]=0;
+ case '\r':if (out) fputc('\n',out);
+ return 1;
+ case 127:
+ case '\b':if (col) {
+ if (out) {
+ fputc('\b',out);
+ fputc(' ',out);
+ fputc('\b',out);
+ };
+ col--;
+ } else {
+ if (out) fputc('\a',out);
+ };
+ break;
+ default :if (!iscntrl(c)) {
+ if (col<size-1) {
+ line[col++]=c;
+ if (out) fputc(c,out);
+ } else {
+ if (out) fputc('\a',out);
+ };
+ } else {
+ if (out)
+ if (c=='\a') fputc('\a',out);
+ };
+ break;
+ };
+ };
+}
+/* ----------------------------------------------- *
+ * - The shell TASK
+ * Poor but enough..
+ * TODO: Redirection. Tty Signals. ENVVARs. Shell language.
+ * ----------------------------------------------- */
+shell_env_t global_shell_env ,
+ * current_shell_env=&global_shell_env;
+
+extern char **environ;
+
+void cat_file(FILE * out,char * name) {
+ FILE * fd;
+ int c;
+ if (out) {
+ fd=fopen(name,"r");
+ if (fd) {
+ while ((c=fgetc(fd))!=EOF) fputc(c,out);
+ fclose(fd);
+ };
+ };
+}
+
+void write_file(char * name,char * content) {
+ FILE * fd;
+ fd=fopen(name,"w");
+ if (fd) {
+ fwrite(content,1,strlen(content),fd);
+ fclose(fd);
+ };
+}
+
+void init_issue(void) {
+ static char issue_inited=FALSE;
+ struct stat buf;
+ if (issue_inited) return;
+ issue_inited=TRUE;
+ getpwnam("root"); /* dummy call to init /etc dir */
+ if (stat("/etc/issue",&buf))
+ write_file("/etc/issue",
+ "Welcome to @V\\n"
+ "Login into @S(@L)\\n");
+ if (stat("/etc/issue.net",&buf))
+ write_file("/etc/issue.net",
+ "Welcome to %v\n"
+ "running on %m\n");
+}
+
+int shell_login(FILE * in,FILE * out) {
+ FILE * fd;
+ int c;
+ time_t t;
+ int times;
+ char name[128];
+ char pass[128];
+ struct passwd * passwd;
+ init_issue();
+ setuid(0);
+ setgid(0);
+ rtems_current_user_env->euid=
+ rtems_current_user_env->egid=0;
+ if (out) {
+ if((current_shell_env->devname[5]!='p')||
+ (current_shell_env->devname[6]!='t')||
+ (current_shell_env->devname[7]!='y')) {
+ fd=fopen("/etc/issue","r");
+ if (fd) {
+ while ((c=fgetc(fd))!=EOF) {
+ if (c=='@') {
+ switch(c=fgetc(fd)) {
+ case 'L':fprintf(out,"%s",current_shell_env->devname);
+ break;
+ case 'B':fprintf(out,"0");
+ break;
+ case 'T':
+ case 'D':time(&t);
+ fprintf(out,"%s",ctime(&t));
+ break;
+ case 'S':fprintf(out,"RTEMS");
+ break;
+ case 'V':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
+ break;
+ case '@':fprintf(out,"@");
+ break;
+ default :fprintf(out,"@%c",c);
+ break;
+ };
+ } else
+ if (c=='\\') {
+ switch(c=fgetc(fd)) {
+ case '\\':fprintf(out,"\\");
+ break;
+ case 'b':fprintf(out,"\b"); break;
+ case 'f':fprintf(out,"\f"); break;
+ case 'n':fprintf(out,"\n"); break;
+ case 'r':fprintf(out,"\r"); break;
+ case 's':fprintf(out," "); break;
+ case 't':fprintf(out,"\t"); break;
+ case '@':fprintf(out,"@"); break;
+ };
+ } else {
+ fputc(c,out);
+ };
+ };
+ fclose(fd);
+ }
+ } else {
+ fd=fopen("/etc/issue.net","r");
+ if (fd) {
+ while ((c=fgetc(fd))!=EOF) {
+ if (c=='%') {
+ switch(c=fgetc(fd)) {
+ case 't':fprintf(out,"%s",current_shell_env->devname);
+ break;
+ case 'h':fprintf(out,"0");
+ break;
+ case 'D':fprintf(out," ");
+ break;
+ case 'd':time(&t);
+ fprintf(out,"%s",ctime(&t));
+ break;
+ case 's':fprintf(out,"RTEMS");
+ break;
+ case 'm':fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")");
+ break;
+ case 'r':fprintf(out,_RTEMS_version);
+ break;
+ case 'v':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
+ break;
+ case '%':fprintf(out,"%%");
+ break;
+ default :fprintf(out,"%%%c",c);
+ break;
+ };
+ } else {
+ fputc(c,out);
+ };
+ };
+ fclose(fd);
+ }
+ };
+ };
+ times=0;
+ strcpy(name,"");
+ strcpy(pass,"");
+ for (;;) {
+ times++;
+ if (times>3) break;
+ if (out) fprintf(out,"\nlogin: ");
+ if (!shell_scanline(name,sizeof(name),in,out )) break;
+ if (out) fprintf(out,"Password: ");
+ if (!shell_scanline(pass,sizeof(pass),in,NULL)) break;
+ if (out) fprintf(out,"\n");
+ if ((passwd=getpwnam(name))) {
+ if (strcmp(passwd->pw_passwd,"!")) { /* valid user */
+ setuid(passwd->pw_uid);
+ setgid(passwd->pw_gid);
+ rtems_current_user_env->euid=
+ rtems_current_user_env->egid=0;
+ chown(current_shell_env->devname,passwd->pw_uid,0);
+ rtems_current_user_env->euid=passwd->pw_uid;
+ rtems_current_user_env->egid=passwd->pw_gid;
+ if (!strcmp(passwd->pw_passwd,"*")) {
+ /* /etc/shadow */
+ return 0;
+ } else {
+ /* crypt() */
+ return 0;
+ };
+ };
+ };
+ if (out) fprintf(out,"Login incorrect\n");
+ strcpy(name,"");
+ strcpy(pass,"");
+ };
+ return -1;
+}
+
+rtems_task shell_shell(rtems_task_argument task_argument) {
+
+ shell_env_t * shell_env =(shell_env_t*) task_argument;
+ shell_cmd_t * shell_cmd;
+
+ rtems_status_code sc;
+
+ struct termios term;
+ char * devname;
+
+ char curdir[256];
+ char cmd[256];
+ char last_cmd[256]; /* to repeat 'r' */
+ int argc;
+ char * argv[128];
+
+ sc=rtems_task_variable_add(RTEMS_SELF,(void*)&current_shell_env,free);
+ if (sc!=RTEMS_SUCCESSFUL) {
+ rtems_error(sc,"rtems_task_variable_add(current_shell_env):");
+ rtems_task_delete(RTEMS_SELF);
+ };
+
+ current_shell_env=shell_env;
+
+ sc=rtems_libio_set_private_env();
+ if (sc!=RTEMS_SUCCESSFUL) {
+ rtems_error(sc,"rtems_libio_set_private_env():");
+ rtems_task_delete(RTEMS_SELF);
+ };
+
+
+ devname=shell_env->devname;
+ setuid(0);
+ setgid(0);
+ rtems_current_user_env->euid=
+ rtems_current_user_env->egid=0;
+
+ /*
+ * newlib delays the creation of default stdio 'til the
+ * first I/O operation, therefore we must perform dummy
+ * operations before we redirect stdio
+ */
+ ftell(stdin);
+ ftell(stdout);
+ ftell(stderr);
+
+ stdin =fopen(devname,"r+");
+
+ if (!stdin) {
+ fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno));
+ rtems_task_delete(RTEMS_SELF);
+ };
+ setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/
+ /* make a raw terminal,Linux MANuals */
+ if (tcgetattr (fileno(stdin), &term)>=0) {
+ term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+ term.c_oflag &= ~OPOST;
+ term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */
+ term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+ term.c_cflag = CLOCAL | CREAD |(shell_env->tcflag);
+ term.c_cc[VMIN] = 1;
+ term.c_cc[VTIME] = 0;
+ if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0) {
+ fprintf(stderr,"shell:cannot set terminal attributes(%s)\n",devname);
+ };
+ stdout=fopen(devname,"r+");
+ if (!stdout) {
+ fprintf(stderr,"shell:unable to open stdout.%s:%s\n",devname,strerror(errno));
+ };
+ setvbuf(stdout,NULL,_IONBF,0); /* Not buffered*/
+ stderr=fopen(devname,"r+");
+ if (!stderr) {
+ fprintf(stdout,"shell:unable to open stderr.%s:%s\n",devname,strerror(errno));
+ };
+ /* when the future user environment runs ok
+ * a freopen() reopens the terminals. Now this don't work
+ * (sorry but you can't use because FILENO_STDIN!=0. Better fileno(stdin))
+ */
+ };
+ shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/
+ do {
+ /* Set again root user and root filesystem, side effect of set_priv..*/
+ sc=rtems_libio_set_private_env();
+ if (sc!=RTEMS_SUCCESSFUL) {
+ rtems_error(sc,"rtems_libio_set_private_env():");
+ rtems_task_delete(RTEMS_SELF);
+ };
+ if (!shell_login(stdin,stdout)) {
+ cat_file(stdout,"/etc/motd");
+ strcpy(last_cmd,"");
+ strcpy(cmd,"");
+ fprintf(stdout,"\n"
+ "RTEMS SHELL (Ver.1.0-FRC):%s. "__DATE__". 'help' to list commands.\n",devname);
+ chdir("/"); /* XXX: chdir to getpwent homedir */
+ shell_env->exit_shell=FALSE;
+ for (;;) {
+ /* Prompt section */
+ /* XXX: show_prompt user adjustable */
+ getcwd(curdir,sizeof(curdir));
+ fprintf(stdout,"%s [%s] %c ",shell_env->taskname,curdir,geteuid()?'$':'#');
+ /* getcmd section */
+ if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) break; /*EOF*/
+ /* evaluate cmd section */
+ if (!strcmp(cmd,"e")) { /* edit last command */
+ strcpy(cmd,last_cmd);
+ continue;
+ } else
+ if (!strcmp(cmd,"r")) { /* repeat last command */
+ strcpy(cmd,last_cmd);
+ } else
+ if (strcmp(cmd,"")) { /* only for get a new prompt */
+ strcpy(last_cmd,cmd);
+ };
+ /* exec cmd section */
+ /* TODO:
+ * To avoid user crash catch the signals.
+ * Open a new stdio files with posibility of redirection *
+ * Run in a new shell task background. (unix &)
+ * Resuming. A little bash.
+ */
+ if (shell_make_args(cmd,&argc,argv)) {
+ if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) {
+ shell_env->errorlevel=shell_cmd->command(argc,argv);
+ } else {
+ fprintf(stdout,"shell:%s command not found\n",argv[0]);
+ shell_env->errorlevel=-1;
+ };
+ };
+ /* end exec cmd section */
+ if (shell_env->exit_shell) break;
+ cmd[0]=0;
+ };
+ fprintf(stdout,"\nGoodbye from RTEMS SHELL :-(\n");
+ };
+ } while (shell_env->forever);
+ fclose(stdin );
+ fclose(stdout);
+ fclose(stderr);
+ rtems_task_delete(RTEMS_SELF);
+}
+/* ----------------------------------------------- */
+rtems_status_code shell_init (char * task_name,
+ uint32_t task_stacksize,
+ rtems_task_priority task_priority,
+ char * devname,
+ tcflag_t tcflag,
+ int forever) {
+ rtems_id task_id;
+ rtems_status_code sc;
+ shell_env_t * shell_env;
+ sc=rtems_task_create(new_rtems_name(task_name),
+ task_priority,
+ task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_LOCAL | RTEMS_FLOATING_POINT,
+ &task_id);
+ if (sc!=RTEMS_SUCCESSFUL) {
+ rtems_error(sc,"creating task %s in shell_init()",task_name);
+ return sc;
+ };
+ shell_env=malloc(sizeof(shell_env_t));
+ if (!shell_env) {
+ rtems_task_delete(task_id);
+ sc=RTEMS_NO_MEMORY;
+ rtems_error(sc,"allocating shell_env %s in shell_init()",task_name);
+ return sc;
+ };
+ if (global_shell_env.magic!=new_rtems_name("SENV")) {
+ global_shell_env.magic =new_rtems_name("SENV");
+ global_shell_env.devname ="/dev/console";
+ global_shell_env.taskname ="GLOBAL";
+ global_shell_env.tcflag =0;
+ global_shell_env.exit_shell=0;
+ global_shell_env.forever =TRUE;
+ };
+ shell_env->magic =global_shell_env.magic;
+ shell_env->devname =devname;
+ shell_env->taskname =task_name;
+ shell_env->tcflag =tcflag;
+ shell_env->exit_shell=FALSE;
+ shell_env->forever =forever;
+ return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env);
+}
diff --git a/cpukit/libmisc/shell/shell.h b/cpukit/libmisc/shell/shell.h
new file mode 100644
index 0000000000..a662697d54
--- /dev/null
+++ b/cpukit/libmisc/shell/shell.h
@@ -0,0 +1,91 @@
+/**
+ * @file rtems/shell.h
+ *
+ * Instantatiate a new terminal shell.
+ */
+
+/*
+ * Author:
+ *
+ * WORK: fernando.ruiz@ctv.es
+ * HOME: correo@fernando-ruiz.com
+ *
+ * Thanks at:
+ * Chris John
+ *
+ * $Id$
+ */
+
+#ifndef __SHELL_H__
+#define __SHELL_H__
+
+#include <rtems.h>
+#include <stdio.h>
+#include <termios.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int (*shell_command_t)(int argc,char * argv[]);
+
+struct shell_cmd_tt ;
+typedef struct shell_cmd_tt shell_cmd_t;
+
+struct shell_cmd_tt {
+ char * name;
+ char * usage;
+ char * topic;
+ shell_command_t command;
+ shell_cmd_t * alias;
+ shell_cmd_t * next;
+};
+
+uint32_t new_rtems_name(char * rtems_name);
+shell_cmd_t * shell_lookup_cmd(char * cmd);
+shell_cmd_t * shell_add_cmd(char * cmd,
+ char * topic,
+ char * usage,
+ shell_command_t command);
+shell_cmd_t * shell_alias_cmd(char * cmd, char * alias);
+
+int shell_make_args(char * cmd,
+ int * pargc,
+ char * argv[]);
+
+typedef struct {
+ rtems_name magic; /* 'S','E','N','V': Shell Environment */
+ char * devname;
+ char * taskname;
+ tcflag_t tcflag;
+ /* user extensions */
+ int exit_shell; /* logout */
+ int forever ; /* repeat login */
+ int errorlevel;
+ int mdump_adr;
+} shell_env_t;
+
+int shell_scanline(char * line,int size,FILE * in,FILE * out) ;
+void cat_file(FILE * out,char *name);
+void write_file(char *name,char * content);
+
+rtems_status_code shell_init(char * task_name ,
+ uint32_t task_stacksize,/*0 default*/
+ rtems_task_priority task_priority ,
+ char * devname ,
+ tcflag_t tcflag ,
+ int forever );
+
+extern shell_env_t global_shell_env,
+ * current_shell_env;
+/*--------*/
+/* cmds.c */
+/*--------*/
+int str2int(char * s);
+void register_cmds(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libmisc/stackchk/README b/cpukit/libmisc/stackchk/README
new file mode 100644
index 0000000000..5421a77434
--- /dev/null
+++ b/cpukit/libmisc/stackchk/README
@@ -0,0 +1,53 @@
+#
+# $Id$
+#
+
+Introduction
+============
+
+This directory contains a stack bounds checker. It provides two
+primary features:
+
+ + check for stack overflow at each context switch
+ + provides an educated guess at each task's stack usage
+
+Enabling
+========
+
+Add the stack checker extension to the initial user extension set.
+If using confdefs.h to build your configuration table, this is
+as simple as adding -DSTACK_CHECK_ON to the gcc command line which
+compiles the file defining the configuration table. In the RTEMS
+test suites and samples, this is always init.c
+
+Background
+==========
+
+The stack overflow check at context switch works by looking for
+a 16 byte pattern at the logical end of the stack to be corrupted.
+The "guesser" assumes that the entire stack was prefilled with a known
+pattern and assumes that the pattern is still in place if the memory
+has not been used as a stack.
+
+Both of these can be fooled by pushing large holes onto the stack
+and not writing to them... or (much more unlikely) writing the
+magic patterns into memory.
+
+This code has not been extensively tested. It is provided as a tool
+for RTEMS users to catch the most common mistake in multitasking
+systems ... too little stack space. Suggestions and comments are appreciated.
+
+NOTES:
+
+1. Stack usage information is questionable on CPUs which push
+ large holes on stack.
+
+2. The stack checker has a tendency to generate a fault when
+ trying to print the helpful diagnostic message. If it comes
+ out, congratulations. If not, then the variable Stack_check_Blown_task
+ contains a pointer to the TCB of the offending task. This
+ is usually enough to go on.
+
+FUTURE:
+
+1. Determine how/if gcc will generate stack probe calls and support that.
diff --git a/cpukit/libmisc/stackchk/check.c b/cpukit/libmisc/stackchk/check.c
new file mode 100644
index 0000000000..87d5b585b6
--- /dev/null
+++ b/cpukit/libmisc/stackchk/check.c
@@ -0,0 +1,553 @@
+/*
+ * Stack Overflow Check User Extension Set
+ *
+ * NOTE: This extension set automatically determines at
+ * initialization time whether the stack for this
+ * CPU grows up or down and installs the correct
+ * extension routines for that direction.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+/*
+ * HACK
+ * the stack dump information should be printed by a "fatal" extension.
+ * Fatal extensions only get called via rtems_fatal_error_occurred()
+ * and not when rtems_shutdown_executive() is called.
+ * I hope/think this is changing so that fatal extensions are renamed
+ * to "shutdown" extensions.
+ * When that happens, this #define should be deleted and all the code
+ * it marks.
+ */
+#define DONT_USE_FATAL_EXTENSION
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <rtems/stackchk.h>
+#include "internal.h"
+
+/*
+ * This variable contains the name of the task which "blew" the stack.
+ * It is NULL if the system is all right.
+ */
+
+Thread_Control *Stack_check_Blown_task;
+
+/*
+ * The extension table for the stack checker.
+ */
+
+rtems_extensions_table Stack_check_Extension_table = {
+ Stack_check_Create_extension, /* rtems_task_create */
+ 0, /* rtems_task_start */
+ 0, /* rtems_task_restart */
+ 0, /* rtems_task_delete */
+ Stack_check_Switch_extension, /* task_switch */
+ Stack_check_Begin_extension, /* task_begin */
+ 0, /* task_exitted */
+#ifdef DONT_USE_FATAL_EXTENSION
+ 0, /* fatal */
+#else
+ Stack_check_Fatal_extension, /* fatal */
+#endif
+};
+
+/*
+ * The "magic pattern" used to mark the end of the stack.
+ */
+
+Stack_check_Control Stack_check_Pattern;
+
+/*
+ * Where the pattern goes in the stack area is dependent upon
+ * whether the stack grow to the high or low area of the memory.
+ *
+ */
+
+#if ( CPU_STACK_GROWS_UP == TRUE )
+
+#define Stack_check_Get_pattern_area( _the_stack ) \
+ ((Stack_check_Control *) ((char *)(_the_stack)->area + \
+ (_the_stack)->size - sizeof( Stack_check_Control ) ))
+
+#define Stack_check_Calculate_used( _low, _size, _high_water ) \
+ ((char *)(_high_water) - (char *)(_low))
+
+#define Stack_check_usable_stack_start(_the_stack) \
+ ((_the_stack)->area)
+
+#else
+
+#define Stack_check_Get_pattern_area( _the_stack ) \
+ ((Stack_check_Control *) ((char *)(_the_stack)->area + HEAP_OVERHEAD))
+
+#define Stack_check_Calculate_used( _low, _size, _high_water) \
+ ( ((char *)(_low) + (_size)) - (char *)(_high_water) )
+
+#define Stack_check_usable_stack_start(_the_stack) \
+ ((char *)(_the_stack)->area + sizeof(Stack_check_Control))
+
+#endif
+
+#define Stack_check_usable_stack_size(_the_stack) \
+ ((_the_stack)->size - sizeof(Stack_check_Control))
+
+
+/*
+ * Do we have an interrupt stack?
+ * XXX it would sure be nice if the interrupt stack were also
+ * stored in a "stack" structure!
+ */
+
+
+Stack_Control stack_check_interrupt_stack;
+
+/*
+ * Prototypes necessary for forward references
+ */
+
+void Stack_check_Dump_usage( void );
+
+/*
+ * Fill an entire stack area with BYTE_PATTERN.
+ * This will be used by a Fatal extension to check for
+ * amount of actual stack used
+ */
+
+void
+stack_check_dope_stack(Stack_Control *stack)
+{
+ memset(stack->area, BYTE_PATTERN, stack->size);
+}
+
+
+/*PAGE
+ *
+ * Stack_check_Initialize
+ */
+
+static int stack_check_initialized = 0;
+
+void Stack_check_Initialize( void )
+{
+#if 0
+ rtems_status_code status;
+ Objects_Id id_ignored;
+#endif
+ uint32_t *p;
+#if 0
+ uint32_t i;
+ uint32_t api_index;
+ Thread_Control *the_thread;
+ Objects_Information *information;
+#endif
+
+ if (stack_check_initialized)
+ return;
+
+ /*
+ * Dope the pattern and fill areas
+ */
+
+ for ( p = Stack_check_Pattern.pattern;
+ p < &Stack_check_Pattern.pattern[PATTERN_SIZE_WORDS];
+ p += 4
+ )
+ {
+ p[0] = 0xFEEDF00D; /* FEED FOOD to BAD DOG */
+ p[1] = 0x0BAD0D06;
+ p[2] = 0xDEADF00D; /* DEAD FOOD GOOD DOG */
+ p[3] = 0x600D0D06;
+ };
+
+#if 0
+ status = rtems_extension_create(
+ rtems_build_name( 'S', 'T', 'C', 'K' ),
+ &Stack_check_Extension_table,
+ &id_ignored
+ );
+ assert ( status == RTEMS_SUCCESSFUL );
+#endif
+
+ Stack_check_Blown_task = 0;
+
+ /*
+ * If installed by a task, that task will not get setup properly
+ * since it missed out on the create hook. This will cause a
+ * failure on first switch out of that task.
+ * So pretend here that we actually ran create and begin extensions.
+ */
+
+ /* XXX
+ *
+ * Technically this has not been done for any task created before this
+ * happened. So just run through them and fix the situation.
+ */
+#if 0
+ if (_Thread_Executing)
+ {
+ Stack_check_Create_extension(_Thread_Executing, _Thread_Executing);
+ }
+#endif
+
+#if 0
+ for ( api_index = 1;
+ api_index <= OBJECTS_APIS_LAST ;
+ api_index++ ) {
+ if ( !_Objects_Information_table[ api_index ] )
+ continue;
+ information = _Objects_Information_table[ api_index ][ 1 ];
+ if ( information ) {
+ for ( i=1 ; i <= information->maximum ; i++ ) {
+ the_thread = (Thread_Control *)information->local_table[ i ];
+ Stack_check_Create_extension( the_thread, the_thread );
+ }
+ }
+ }
+#endif
+
+ /*
+ * If appropriate, setup the interrupt stack for high water testing
+ * also.
+ */
+#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE)
+ if (_CPU_Interrupt_stack_low && _CPU_Interrupt_stack_high)
+ {
+ stack_check_interrupt_stack.area = _CPU_Interrupt_stack_low;
+ stack_check_interrupt_stack.size = (char *) _CPU_Interrupt_stack_high -
+ (char *) _CPU_Interrupt_stack_low;
+
+ stack_check_dope_stack(&stack_check_interrupt_stack);
+ }
+#endif
+
+#ifdef DONT_USE_FATAL_EXTENSION
+#ifdef RTEMS_DEBUG
+ /*
+ * this would normally be called by a fatal extension
+ * handler, but we don't run fatal extensions unless
+ * we fatal error.
+ */
+ atexit(Stack_check_Dump_usage);
+#endif
+#endif
+
+ stack_check_initialized = 1;
+}
+
+/*PAGE
+ *
+ * Stack_check_Create_extension
+ */
+
+boolean Stack_check_Create_extension(
+ Thread_Control *running,
+ Thread_Control *the_thread
+)
+{
+ if (!stack_check_initialized)
+ Stack_check_Initialize();
+
+ if (the_thread /* XXX && (the_thread != _Thread_Executing) */ )
+ stack_check_dope_stack(&the_thread->Start.Initial_stack);
+
+ return TRUE;
+}
+
+/*PAGE
+ *
+ * Stack_check_Begin_extension
+ */
+
+void Stack_check_Begin_extension(
+ Thread_Control *the_thread
+)
+{
+ Stack_check_Control *the_pattern;
+
+ if (!stack_check_initialized)
+ Stack_check_Initialize();
+
+ if ( the_thread->Object.id == 0 ) /* skip system tasks */
+ return;
+
+ the_pattern = Stack_check_Get_pattern_area(&the_thread->Start.Initial_stack);
+
+ *the_pattern = Stack_check_Pattern;
+}
+
+/*PAGE
+ *
+ * Stack_check_report_blown_task
+ * Report a blown stack. Needs to be a separate routine
+ * so that interrupt handlers can use this too.
+ *
+ * Caller must have set the Stack_check_Blown_task.
+ *
+ * NOTE: The system is in a questionable state... we may not get
+ * the following message out.
+ */
+
+void Stack_check_report_blown_task(void)
+{
+ Stack_Control *stack;
+ Thread_Control *running;
+
+ running = Stack_check_Blown_task;
+ stack = &running->Start.Initial_stack;
+
+ fprintf(
+ stderr,
+ "BLOWN STACK!!! Offending task(%p): id=0x%08x; name=0x%08x",
+ running,
+ running->Object.id,
+ (uint32_t )running->Object.name
+ );
+ fflush(stderr);
+
+ if (rtems_configuration_get_user_multiprocessing_table())
+ fprintf(
+ stderr,
+ "; node=%d\n",
+ rtems_configuration_get_user_multiprocessing_table()->node
+ );
+ else
+ fprintf(stderr, "\n");
+ fflush(stderr);
+
+ fprintf(
+ stderr,
+ " stack covers range 0x%08x - 0x%08x (%d bytes)\n",
+ (uint32_t ) stack->area,
+ (uint32_t ) stack->area + stack->size - 1,
+ (uint32_t ) stack->size);
+ fflush(stderr);
+
+ fprintf(
+ stderr,
+ " Damaged pattern begins at 0x%08lx and is %ld bytes long\n",
+ (unsigned long) Stack_check_Get_pattern_area(stack),
+ (long) PATTERN_SIZE_BYTES);
+ fflush(stderr);
+
+ rtems_fatal_error_occurred( (uint32_t ) "STACK BLOWN" );
+}
+
+/*PAGE
+ *
+ * Stack_check_Switch_extension
+ */
+
+void Stack_check_Switch_extension(
+ Thread_Control *running,
+ Thread_Control *heir
+)
+{
+ if ( running->Object.id == 0 ) /* skip system tasks */
+ return;
+
+ if (0 != memcmp( (void *) Stack_check_Get_pattern_area( &running->Start.Initial_stack)->pattern,
+ (void *) Stack_check_Pattern.pattern,
+ PATTERN_SIZE_BYTES))
+ {
+ Stack_check_Blown_task = running;
+ Stack_check_report_blown_task();
+ }
+}
+
+void *Stack_check_find_high_water_mark(
+ const void *s,
+ size_t n
+)
+{
+ const uint32_t *base, *ebase;
+ uint32_t length;
+
+ base = s;
+ length = n/4;
+
+#if ( CPU_STACK_GROWS_UP == TRUE )
+ /*
+ * start at higher memory and find first word that does not
+ * match pattern
+ */
+
+ base += length - 1;
+ for (ebase = s; base > ebase; base--)
+ if (*base != U32_PATTERN)
+ return (void *) base;
+#else
+ /*
+ * start at lower memory and find first word that does not
+ * match pattern
+ */
+
+ base += PATTERN_SIZE_WORDS;
+ for (ebase = base + length; base < ebase; base++)
+ if (*base != U32_PATTERN)
+ return (void *) base;
+#endif
+
+ return (void *)0;
+}
+
+/*PAGE
+ *
+ * Stack_check_Dump_threads_usage
+ * Try to print out how much stack was actually used by the task.
+ *
+ */
+
+void Stack_check_Dump_threads_usage(
+ Thread_Control *the_thread
+)
+{
+ uint32_t size, used;
+ void *low;
+ void *high_water_mark;
+ Stack_Control *stack;
+ uint32_t u32_name;
+ char name_str[5];
+ char *name;
+ Objects_Information *info;
+
+ if ( !the_thread )
+ return;
+
+ /*
+ * XXX HACK to get to interrupt stack
+ */
+
+ if (the_thread == (Thread_Control *) -1)
+ {
+ if (stack_check_interrupt_stack.area)
+ {
+ stack = &stack_check_interrupt_stack;
+ the_thread = 0;
+ }
+ else
+ return;
+ }
+ else
+ stack = &the_thread->Start.Initial_stack;
+
+ low = Stack_check_usable_stack_start(stack);
+ size = Stack_check_usable_stack_size(stack);
+
+ high_water_mark = Stack_check_find_high_water_mark(low, size);
+
+ if ( high_water_mark )
+ used = Stack_check_Calculate_used( low, size, high_water_mark );
+ else
+ used = 0;
+
+ name = name_str;
+ if ( the_thread ) {
+ info = _Objects_Get_information(the_thread->Object.id);
+ if ( info->is_string ) {
+ name = (char *) the_thread->Object.name;
+ } else {
+ u32_name = (uint32_t )the_thread->Object.name;
+ name[ 0 ] = (u32_name >> 24) & 0xff;
+ name[ 1 ] = (u32_name >> 16) & 0xff;
+ name[ 2 ] = (u32_name >> 8) & 0xff;
+ name[ 3 ] = (u32_name >> 0) & 0xff;
+ name[ 4 ] = '\0';
+ }
+ } else {
+ u32_name = rtems_build_name('I', 'N', 'T', 'R');
+ name[ 0 ] = (u32_name >> 24) & 0xff;
+ name[ 1 ] = (u32_name >> 16) & 0xff;
+ name[ 2 ] = (u32_name >> 8) & 0xff;
+ name[ 3 ] = (u32_name >> 0) & 0xff;
+ name[ 4 ] = '\0';
+ }
+
+ fprintf(stdout, "0x%08x %4s 0x%08x 0x%08x %8d %8d\n",
+ the_thread ? the_thread->Object.id : ~0,
+ name,
+ (uint32_t ) stack->area,
+ (uint32_t ) stack->area + (uint32_t ) stack->size - 1,
+ size,
+ used
+ );
+}
+
+/*PAGE
+ *
+ * Stack_check_Fatal_extension
+ */
+
+void Stack_check_Fatal_extension(
+ Internal_errors_Source source,
+ boolean is_internal,
+ uint32_t status
+)
+{
+#ifndef DONT_USE_FATAL_EXTENSION
+ if (status == 0)
+ Stack_check_Dump_usage();
+#endif
+}
+
+
+/*PAGE
+ *
+ * Stack_check_Dump_usage
+ */
+
+void Stack_check_Dump_usage( void )
+{
+ uint32_t i;
+ uint32_t api_index;
+ Thread_Control *the_thread;
+ uint32_t hit_running = 0;
+ Objects_Information *information;
+
+ if (stack_check_initialized == 0)
+ return;
+
+ fprintf(stdout,"Stack usage by thread\n");
+ fprintf(stdout,
+ " ID NAME LOW HIGH AVAILABLE USED\n"
+ );
+
+ for ( api_index = 1 ;
+ api_index <= OBJECTS_APIS_LAST ;
+ api_index++ ) {
+ if ( !_Objects_Information_table[ api_index ] )
+ continue;
+ information = _Objects_Information_table[ api_index ][ 1 ];
+ if ( information ) {
+ for ( i=1 ; i <= information->maximum ; i++ ) {
+ the_thread = (Thread_Control *)information->local_table[ i ];
+ Stack_check_Dump_threads_usage( the_thread );
+ if ( the_thread == _Thread_Executing )
+ hit_running = 1;
+ }
+ }
+ }
+
+ if ( !hit_running )
+ Stack_check_Dump_threads_usage( _Thread_Executing );
+
+ /* dump interrupt stack info if any */
+ Stack_check_Dump_threads_usage((Thread_Control *) -1);
+}
diff --git a/cpukit/libmisc/stackchk/internal.h b/cpukit/libmisc/stackchk/internal.h
new file mode 100644
index 0000000000..c437eb94c1
--- /dev/null
+++ b/cpukit/libmisc/stackchk/internal.h
@@ -0,0 +1,95 @@
+/* internal.h
+ *
+ * This include file contains internal information
+ * for the RTEMS stack checker.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef __INTERNAL_STACK_CHECK_h
+#define __INTERNAL_STACK_CHECK_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This structure is used to fill in and compare the "end of stack"
+ * marker pattern.
+ * pattern area must be a multiple of 4 words.
+ */
+
+#ifdef CPU_STACK_CHECK_SIZE
+#define PATTERN_SIZE_WORDS (((CPU_STACK_CHECK_SIZE / 4) + 3) & ~0x3)
+#else
+#define PATTERN_SIZE_WORDS (4)
+#endif
+
+#define PATTERN_SIZE_BYTES (PATTERN_SIZE_WORDS * sizeof(uint32_t ))
+
+typedef struct {
+ uint32_t pattern[ PATTERN_SIZE_WORDS ];
+} Stack_check_Control;
+
+/*
+ * The pattern used to fill the entire stack.
+ */
+
+#define BYTE_PATTERN 0xA5
+#define U32_PATTERN 0xA5A5A5A5
+
+/*
+ * Stack_check_Create_extension
+ */
+
+boolean Stack_check_Create_extension(
+ Thread_Control *running,
+ Thread_Control *the_thread
+);
+
+/*
+ * Stack_check_Begin_extension
+ */
+
+void Stack_check_Begin_extension(
+ Thread_Control *the_thread
+);
+
+/*
+ * Stack_check_Switch_extension
+ */
+
+void Stack_check_Switch_extension(
+ Thread_Control *running,
+ Thread_Control *heir
+);
+
+/*
+ * Stack_check_Fatal_extension
+ */
+
+void Stack_check_Fatal_extension(
+ Internal_errors_Source source,
+ boolean is_internal,
+ uint32_t status
+);
+
+/*
+ * Stack_check_Dump_usage
+ */
+
+void Stack_check_Dump_usage( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libmisc/stackchk/stackchk.h b/cpukit/libmisc/stackchk/stackchk.h
new file mode 100644
index 0000000000..efe4ce9803
--- /dev/null
+++ b/cpukit/libmisc/stackchk/stackchk.h
@@ -0,0 +1,82 @@
+/* stackchk.h
+ *
+ * This include file contains information necessary to utilize
+ * and install the stack checker mechanism.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef __STACK_CHECK_h
+#define __STACK_CHECK_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Stack_check_Initialize
+ */
+
+void Stack_check_Initialize( void );
+
+/*
+ * Stack_check_Dump_usage
+ */
+
+void Stack_check_Dump_usage( void );
+
+/*
+ * Stack_check_Create_extension
+ */
+
+boolean Stack_check_Create_extension(
+ Thread_Control *running,
+ Thread_Control *the_thread
+);
+
+/*
+ * Stack_check_Begin_extension
+ */
+
+void Stack_check_Begin_extension(
+ Thread_Control *the_thread
+);
+
+/*
+ * Stack_check_Switch_extension
+ */
+
+void Stack_check_Switch_extension(
+ Thread_Control *running,
+ Thread_Control *heir
+);
+
+/*
+ * Extension set definition
+ */
+
+#define STACK_CHECKER_EXTENSION \
+{ \
+ Stack_check_Create_extension, /* rtems_task_create */ \
+ 0, /* rtems_task_start */ \
+ 0, /* rtems_task_restart */ \
+ 0, /* rtems_task_delete */ \
+ Stack_check_Switch_extension, /* task_switch */ \
+ Stack_check_Begin_extension, /* task_begin */ \
+ 0, /* task_exitted */ \
+ 0 /* Stack_check_Fatal_extension */, /* fatal */ \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libmisc/untar/README b/cpukit/libmisc/untar/README
new file mode 100644
index 0000000000..24c9e7fa62
--- /dev/null
+++ b/cpukit/libmisc/untar/README
@@ -0,0 +1,26 @@
+#
+#
+# untar information
+#
+# Author: Jake Janovetz 7.6.1999
+#
+# $Id$
+#
+
+untar.c contains two procedures for extracting files from a UNIX
+tar file:
+
+ int Untar_FromMemory(unsigned char *tar_buf, unsigned long size);
+ int Untar_FromFile(char *tar_name);
+
+Untar_FromMemory(...) takes its input from a chunk of allocated memory.
+This is particularly useful when the tar is stored in Flash memory or
+comes from the FTP daemon by way of a hook.
+
+Untar_FromFile(...) is identical except the source is from an existing
+file. The fully qualified filename is passed through char *tar_name.
+
+
+
+BUGS: Please email janovetz@uiuc.edu
+-----
diff --git a/cpukit/libmisc/untar/untar.c b/cpukit/libmisc/untar/untar.c
new file mode 100644
index 0000000000..fcaadae5ab
--- /dev/null
+++ b/cpukit/libmisc/untar/untar.c
@@ -0,0 +1,373 @@
+/* FIXME:
+ * 1. Symbolic links are not created.
+ * 2. Untar_FromMemory has printfs.
+ * 3. Untar_FromMemory uses FILE *fp.
+ * 4. How to determine end of archive?
+ *
+ * Written by: Jake Janovetz <janovetz@tempest.ece.uiuc.edu>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <rtems/untar.h>
+
+
+/**************************************************************************
+ * TAR file format:
+ *
+ * Offset Length Contents
+ * 0 100 bytes File name ('\0' terminated, 99 maxmum length)
+ * 100 8 bytes File mode (in octal ascii)
+ * 108 8 bytes User ID (in octal ascii)
+ * 116 8 bytes Group ID (in octal ascii)
+ * 124 12 bytes File size (s) (in octal ascii)
+ * 136 12 bytes Modify time (in octal ascii)
+ * 148 8 bytes Header checksum (in octal ascii)
+ * 156 1 bytes Link flag
+ * 157 100 bytes Linkname ('\0' terminated, 99 maxmum length)
+ * 257 8 bytes Magic ("ustar \0")
+ * 265 32 bytes User name ('\0' terminated, 31 maxmum length)
+ * 297 32 bytes Group name ('\0' terminated, 31 maxmum length)
+ * 329 8 bytes Major device ID (in octal ascii)
+ * 337 8 bytes Minor device ID (in octal ascii)
+ * 345 155 bytes Prefix
+ * 512 (s+p)bytes File contents (s+p) := (((s) + 511) & ~511),
+ * round up to 512 bytes
+ *
+ * Checksum:
+ * int i, sum;
+ * char* header = tar_header_pointer;
+ * sum = 0;
+ * for(i = 0; i < 512; i++)
+ * sum += 0xFF & header[i];
+ *************************************************************************/
+
+#define MAX_NAME_FIELD_SIZE 99
+
+#define MIN(a,b) ((a)>(b)?(b):(a))
+
+
+/**************************************************************************
+ * This converts octal ASCII number representations into an
+ * unsigned long. Only support 32-bit numbers for now.
+ *************************************************************************/
+unsigned long
+_rtems_octal2ulong(const char *octascii, size_t len)
+{
+ size_t i;
+ unsigned long num;
+
+ num = 0;
+ for (i=0; i < len; i++)
+ {
+ if ((octascii[i] < '0') || (octascii[i] > '9'))
+ {
+ continue;
+ }
+ num = num * 8 + ((unsigned long)(octascii[i] - '0'));
+ }
+ return(num);
+}
+
+
+/**************************************************************************
+ * Function: Untar_FromMemory *
+ **************************************************************************
+ * Description: *
+ * *
+ * This is a simple subroutine used to rip links, directories, and *
+ * files out of a block of memory. *
+ * *
+ * *
+ * Inputs: *
+ * *
+ * char *tar_buf - Pointer to TAR buffer. *
+ * size_t size - Length of TAR buffer. *
+ * *
+ * *
+ * Output: *
+ * *
+ * int - UNTAR_SUCCESSFUL (0) on successful completion. *
+ * UNTAR_INVALID_CHECKSUM for an invalid header checksum. *
+ * UNTAR_INVALID_HEADER for an invalid header. *
+ * *
+ **************************************************************************
+ * Change History: *
+ * 12/30/1998 - Creation (JWJ) *
+ *************************************************************************/
+int
+Untar_FromMemory(char *tar_buf, size_t size)
+{
+ FILE *fp;
+ char *bufr;
+ size_t n;
+ char fname[100];
+ char linkname[100];
+ int sum;
+ int hdr_chksum;
+ int retval;
+ unsigned long ptr;
+ unsigned long i;
+ unsigned long nblocks;
+ unsigned long file_size;
+ unsigned char linkflag;
+
+
+ ptr = 0;
+ while (1)
+ {
+ if (ptr + 512 > size)
+ {
+ retval = UNTAR_SUCCESSFUL;
+ break;
+ }
+
+ /* Read the header */
+ bufr = &tar_buf[ptr];
+ ptr += 512;
+ if (strncmp(&bufr[257], "ustar ", 7))
+ {
+ retval = UNTAR_SUCCESSFUL;
+ break;
+ }
+
+ strncpy(fname, bufr, MAX_NAME_FIELD_SIZE);
+ fname[MAX_NAME_FIELD_SIZE] = '\0';
+
+ linkflag = bufr[156];
+ file_size = _rtems_octal2ulong(&bufr[124], 12);
+
+ /******************************************************************
+ * Compute the TAR checksum and check with the value in
+ * the archive. The checksum is computed over the entire
+ * header, but the checksum field is substituted with blanks.
+ ******************************************************************/
+ hdr_chksum = _rtems_octal2ulong(&bufr[148], 8);
+ sum = _rtems_tar_header_checksum(bufr);
+
+ if (sum != hdr_chksum)
+ {
+ retval = UNTAR_INVALID_CHECKSUM;
+ break;
+ }
+
+
+ /******************************************************************
+ * We've decoded the header, now figure out what it contains and
+ * do something with it.
+ *****************************************************************/
+ if (linkflag == SYMTYPE)
+ {
+ strncpy(linkname, &bufr[157], MAX_NAME_FIELD_SIZE);
+ linkname[MAX_NAME_FIELD_SIZE] = '\0';
+ symlink(linkname, fname);
+ }
+ else if (linkflag == REGTYPE)
+ {
+ nblocks = (((file_size) + 511) & ~511) / 512;
+ if ((fp = fopen(fname, "w")) == NULL)
+ {
+ fprintf(stdout,"Untar failed to create file %s\n", fname);
+ ptr += 512 * nblocks;
+ }
+ else
+ {
+ unsigned long sizeToGo = file_size;
+ size_t len;
+
+ /***************************************************************
+ * Read out the data. There are nblocks of data where nblocks
+ * is the file_size rounded to the nearest 512-byte boundary.
+ **************************************************************/
+ for (i=0; i<nblocks; i++)
+ {
+ len = ((sizeToGo < 512L)?(sizeToGo):(512L));
+ n = fwrite(&tar_buf[ptr], 1, len, fp);
+ if (n != len)
+ {
+ fprintf(stdout,"Error during write\n");
+ break;
+ }
+ ptr += 512;
+ sizeToGo -= n;
+ }
+ fclose(fp);
+ }
+ }
+ else if (linkflag == DIRTYPE)
+ {
+ mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO);
+ }
+ }
+
+ return(retval);
+}
+
+
+/**************************************************************************
+ * Function: Untar_FromFile *
+ **************************************************************************
+ * Description: *
+ * *
+ * This is a simple subroutine used to rip links, directories, and *
+ * files out of a TAR file. *
+ * *
+ * *
+ * Inputs: *
+ * *
+ * char *tar_name - TAR filename. *
+ * *
+ * *
+ * Output: *
+ * *
+ * int - UNTAR_SUCCESSFUL (0) on successful completion. *
+ * UNTAR_INVALID_CHECKSUM for an invalid header checksum. *
+ * UNTAR_INVALID_HEADER for an invalid header. *
+ * *
+ **************************************************************************
+ * Change History: *
+ * 12/30/1998 - Creation (JWJ) *
+ *************************************************************************/
+int
+Untar_FromFile(char *tar_name)
+{
+ int fd;
+ char *bufr;
+ size_t n;
+ char fname[100];
+ char linkname[100];
+ int sum;
+ int hdr_chksum;
+ int retval;
+ unsigned long i;
+ unsigned long nblocks;
+ unsigned long size;
+ unsigned char linkflag;
+
+
+ retval = UNTAR_SUCCESSFUL;
+ bufr = (char *)malloc(512);
+ if (bufr == NULL)
+ {
+ return(UNTAR_FAIL);
+ }
+
+ fd = open(tar_name, O_RDONLY);
+ while (1)
+ {
+ /* Read the header */
+ /* If the header read fails, we just consider it the end
+ of the tarfile. */
+ if ((n = read(fd, bufr, 512)) != 512)
+ {
+ break;
+ }
+
+ if (strncmp(&bufr[257], "ustar ", 7))
+ {
+ break;
+ }
+
+ strncpy(fname, bufr, MAX_NAME_FIELD_SIZE);
+ fname[MAX_NAME_FIELD_SIZE] = '\0';
+
+ linkflag = bufr[156];
+ size = _rtems_octal2ulong(&bufr[124], 12);
+
+ /******************************************************************
+ * Compute the TAR checksum and check with the value in
+ * the archive. The checksum is computed over the entire
+ * header, but the checksum field is substituted with blanks.
+ ******************************************************************/
+ hdr_chksum = _rtems_octal2ulong(&bufr[148], 8);
+ sum = _rtems_tar_header_checksum(bufr);
+
+ if (sum != hdr_chksum)
+ {
+ retval = UNTAR_INVALID_CHECKSUM;
+ break;
+ }
+
+ /******************************************************************
+ * We've decoded the header, now figure out what it contains and
+ * do something with it.
+ *****************************************************************/
+ if (linkflag == SYMTYPE)
+ {
+ strncpy(linkname, &bufr[157], MAX_NAME_FIELD_SIZE);
+ linkname[MAX_NAME_FIELD_SIZE] = '\0';
+ symlink(linkname,fname);
+ }
+ else if (linkflag == REGTYPE)
+ {
+ int out_fd;
+
+ /******************************************************************
+ * Read out the data. There are nblocks of data where nblocks
+ * is the size rounded to the nearest 512-byte boundary.
+ *****************************************************************/
+ nblocks = (((size) + 511) & ~511) / 512;
+
+ if ((out_fd = creat(fname, 0644)) == -1)
+ {
+ for (i=0; i<nblocks; i++)
+ {
+ n = read(fd, bufr, 512);
+ }
+ }
+ else
+ {
+ for (i=0; i<nblocks; i++)
+ {
+ n = read(fd, bufr, 512);
+ n = MIN(n, size - i*512);
+ write(out_fd, bufr, n);
+ }
+ close(out_fd);
+ }
+ }
+ else if (linkflag == DIRTYPE)
+ {
+ mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO);
+ }
+ }
+ free(bufr);
+ close(fd);
+
+ return(retval);
+}
+
+/************************************************************************
+ * Compute the TAR checksum and check with the value in
+ * the archive. The checksum is computed over the entire
+ * header, but the checksum field is substituted with blanks.
+ ************************************************************************/
+int
+_rtems_tar_header_checksum(const char *bufr)
+{
+ int i, sum;
+
+ sum = 0;
+ for (i=0; i<512; i++)
+ {
+ if ((i >= 148) && (i < 156))
+ sum += 0xff & ' ';
+ else
+ sum += 0xff & bufr[i];
+ }
+ return(sum);
+}
diff --git a/cpukit/libmisc/untar/untar.h b/cpukit/libmisc/untar/untar.h
new file mode 100644
index 0000000000..839b5008b7
--- /dev/null
+++ b/cpukit/libmisc/untar/untar.h
@@ -0,0 +1,49 @@
+/*
+ * Written by: Jake Janovetz <janovetz@tempest.ece.uiuc.edu>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_UNTAR_H
+#define _RTEMS_UNTAR_H
+
+#include <stddef.h>
+#include <rtems/tar.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UNTAR_SUCCESSFUL 0
+#define UNTAR_FAIL 1
+#define UNTAR_INVALID_CHECKSUM 2
+#define UNTAR_INVALID_HEADER 3
+
+
+int Untar_FromMemory(char *tar_buf, size_t size);
+int Untar_FromFile(char *tar_name);
+
+/**************************************************************************
+ * This converts octal ASCII number representations into an
+ * unsigned long. Only support 32-bit numbers for now.
+ *************************************************************************/
+extern unsigned long
+_rtems_octal2ulong(const char *octascii, size_t len);
+
+/************************************************************************
+ * Compute the TAR checksum and check with the value in
+ * the archive. The checksum is computed over the entire
+ * header, but the checksum field is substituted with blanks.
+ ************************************************************************/
+extern int
+_rtems_tar_header_checksum(const char *bufr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_UNTAR_H */
diff --git a/cpukit/libnetworking/.cvsignore b/cpukit/libnetworking/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/libnetworking/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/libnetworking/Makefile.am b/cpukit/libnetworking/Makefile.am
new file mode 100644
index 0000000000..d475f0de6f
--- /dev/null
+++ b/cpukit/libnetworking/Makefile.am
@@ -0,0 +1,201 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+AM_CPPFLAGS += -I$(srcdir)
+
+EXTRA_DIST = README
+
+# poll is not supported
+UNUSED_FILES = poll.h
+# Original FreeBSD file
+UNUSED_FILES += sys/poll.h
+
+UNUSED_FILES += net/ppp-deflate.c net/bsd-comp.c
+
+if HAS_NETWORKING
+# Add -DFORWARD_PROTOCOL to enable UDP forwarding -- requires missing net/pf.h
+libnetworking_CPPFLAGS = -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS \
+ -DDIAGNOSTIC -DBOOTP_COMPAT -D_KERNEL -D__BSD_VISIBLE
+
+noinst_LIBRARIES = libnetworking.a
+libnetworking_a_CPPFLAGS = $(AM_CPPFLAGS) $(libnetworking_CPPFLAGS)
+
+## poll.h is not in the list because RTEMS does not have poll()
+## and installing poll.h confuses autoconf.
+include_HEADERS = netdb.h
+include_HEADERS += resolv.h syslog.h
+
+libnetworking_a_SOURCES = opt_atalk.h opt_bdg.h opt_compat.h opt_inet6.h \
+ opt_inet.h opt_ipfw.h opt_ipx.h opt_mac.h opt_mrouting.h opt_netgraph.h \
+ opt_tcpdebug.h opt_ipsec.h loop.h
+libnetworking_a_SOURCES += opt_ppp.h
+libnetworking_a_SOURCES += bpfilter.h
+
+# arpa
+
+include_arpadir = $(includedir)/arpa
+
+include_arpa_HEADERS = arpa/ftp.h arpa/inet.h arpa/nameser.h \
+ arpa/nameser_compat.h
+
+## kern
+
+libnetworking_a_SOURCES += kern/kern_mib.c kern/kern_subr.c \
+ kern/kern_sysctl.c kern/uipc_domain.c kern/uipc_mbuf.c \
+ kern/uipc_socket.c kern/uipc_socket2.c
+
+## machine
+
+include_machinedir = $(includedir)/machine
+
+include_machine_HEADERS = machine/conf.h machine/cpu.h machine/cpufunc.h \
+ machine/endian.h machine/in_cksum.h machine/vmparam.h
+
+libnetworking_a_SOURCES += machine/limits.h
+
+## net
+
+include_netdir = $(includedir)/net
+
+include_net_HEADERS = net/bpf.h net/ethernet.h net/if.h net/if_arp.h \
+ net/if_dl.h net/if_llc.h net/if_ppp.h net/if_types.h net/if_var.h \
+ net/netisr.h net/ppp-comp.h net/ppp_defs.h net/radix.h net/raw_cb.h \
+ net/route.h net/if_pppvar.h net/pppcompress.h net/slcompress.h
+include_net_HEADERS += net/if_media.h
+
+libnetworking_a_SOURCES += net/if.c net/if_ethersubr.c net/if_loop.c \
+ net/radix.c net/route.c net/rtsock.c net/raw_cb.c net/raw_usrreq.c \
+ net/if_ppp.c net/ppp_tty.c net/pppcompress.c net/slcompress.c
+
+## netinet
+
+include_netinetdir = $(includedir)/netinet
+
+include_netinet_HEADERS = netinet/icmp_var.h netinet/if_ether.h \
+ netinet/igmp.h netinet/igmp_var.h netinet/in.h netinet/in_pcb.h \
+ netinet/in_systm.h netinet/in_var.h netinet/ip.h netinet/ip_fw.h \
+ netinet/ip_icmp.h netinet/ip_mroute.h netinet/ip_var.h netinet/tcp.h \
+ netinet/tcp_debug.h netinet/tcp_fsm.h netinet/tcp_seq.h \
+ netinet/tcp_timer.h netinet/tcp_var.h netinet/tcpip.h netinet/udp.h \
+ netinet/udp_var.h
+
+libnetworking_a_SOURCES += netinet/if_ether.c netinet/igmp.c netinet/in.c \
+ netinet/in_cksum.c netinet/in_pcb.c netinet/in_proto.c netinet/in_rmx.c \
+ netinet/ip_divert.c netinet/ip_fw.c netinet/ip_icmp.c netinet/ip_input.c \
+ netinet/ip_mroute.c netinet/ip_output.c netinet/raw_ip.c \
+ netinet/tcp_debug.c netinet/tcp_input.c netinet/tcp_output.c \
+ netinet/tcp_subr.c netinet/tcp_timer.c netinet/tcp_usrreq.c \
+ netinet/udp_usrreq.c netinet/in_cksum_arm.h netinet/in_cksum_i386.h \
+ netinet/in_cksum_m68k.h netinet/in_cksum_powerpc.h
+
+## nfs
+
+include_nfsdir = $(includedir)/nfs
+
+include_nfs_HEADERS = nfs/krpc.h
+include_nfs_HEADERS += nfs/nfs.h
+include_nfs_HEADERS += nfs/nfsproto.h
+include_nfs_HEADERS += nfs/rpcv2.h
+include_nfs_HEADERS += nfs/xdr_subs.h
+
+libnetworking_a_SOURCES += nfs/bootp_subr.c
+
+## nfsclient
+include_nfsclientdir = $(includedir)/nfsclient
+
+include_nfsclient_HEADERS = nfsclient/nfsargs.h nfsclient/nfsdiskless.h
+
+## rtems
+
+include_rtemsdir = $(includedir)/rtems
+
+include_rtems_HEADERS = rtems/rtems_bsdnet.h rtems/rtems_bsdnet_internal.h \
+ rtems/dhcp.h rtems/tftp.h rtems/ftpfs.h rtems/mkrootfs.h
+include_rtems_HEADERS += rtems/rtems_mii_ioctl.h
+
+libnetworking_a_SOURCES += rtems/sghostname.c rtems/issetugid.c \
+ rtems/rtems_glue.c rtems/rtems_malloc_mbuf.c rtems/rtems_syscall.c \
+ rtems/rtems_bootp.c rtems/rtems_dhcp.c \
+ rtems/rtems_showmbuf.c rtems/rtems_showroute.c rtems/rtems_showifstat.c \
+ rtems/rtems_showipstat.c rtems/rtems_showicmpstat.c \
+ rtems/rtems_showtcpstat.c rtems/rtems_showudpstat.c rtems/rtems_select.c \
+ rtems/mkrootfs.c rtems/rtems_bsdnet_malloc_starvation.c
+libnetworking_a_SOURCES += rtems/rtems_mii_ioctl.c rtems/rtems_mii_ioctl_kern.c
+
+## sys
+
+include_sysdir = $(includedir)/sys
+
+include_sys_HEADERS = sys/buf.h sys/callout.h sys/conf.h sys/domain.h \
+ sys/kernel.h sys/libkern.h sys/linker_set.h sys/malloc.h sys/mbuf.h \
+ sys/mount.h sys/proc.h sys/protosw.h sys/queue.h sys/reboot.h \
+ sys/resourcevar.h sys/rtprio.h sys/select.h sys/signalvar.h sys/socket.h \
+ sys/socketvar.h sys/sysctl.h sys/syslog.h sys/systm.h sys/ttydefaults.h \
+ sys/ucred.h sys/uio.h sys/un.h
+
+# vm
+
+include_vmdir = $(includedir)/vm
+
+include_vm_HEADERS = vm/vm.h vm/vm_extern.h vm/vm_kern.h vm/vm_param.h
+
+# dev
+include_dev_miidir = $(includedir)/dev/mii
+include_dev_mii_HEADERS = dev/mii/mii.h
+
+## libc
+
+libc_CPPFLAGS = -DNOPOLL -DNOSELECT -D__BSD_VISIBLE
+
+noinst_LIBRARIES += libc.a
+libc_a_CPPFLAGS = $(AM_CPPFLAGS) $(libc_CPPFLAGS)
+
+libc_a_SOURCES = libc/addr2ascii.c libc/ascii2addr.c libc/base64.c \
+ libc/gethostbydns.c libc/gethostbyht.c libc/gethostbynis.c \
+ libc/gethostnamadr.c libc/getnetbydns.c libc/getnetbyht.c \
+ libc/getnetbynis.c libc/getnetnamadr.c libc/getproto.c \
+ libc/getprotoent.c libc/getprotoname.c libc/getservbyname.c \
+ libc/getservbyport.c libc/getservent.c libc/herror.c libc/inet_addr.c \
+ libc/inet_lnaof.c libc/inet_makeaddr.c libc/inet_netof.c \
+ libc/inet_network.c libc/inet_ntoa.c libc/inet_ntop.c libc/inet_pton.c \
+ libc/linkaddr.c libc/map_v4v6.c libc/nsap_addr.c libc/ns_name.c \
+ libc/ns_netint.c libc/ns_parse.c libc/ns_print.c libc/ns_ttl.c \
+ libc/res_comp.c libc/res_data.c libc/res_debug.c libc/res_init.c \
+ libc/res_mkquery.c libc/res_mkupdate.c libc/res_query.c libc/res_send.c \
+ libc/res_stubs.c libc/res_update.c libc/strsep.c libc/rcmd.c
+endif
+
+UNUSED_FILES += libc/ether_addr.c libc/gethostname.c libc/inet_neta.c \
+ libc/inet_net_ntop.c libc/inet_net_pton.c libc/iso_addr.c libc/ns_addr.c \
+ libc/ns_ntoa.c libc/recv.c libc/res_config.h libc/send.c
+
+libc_mans = libc/addr2ascii.3 libc/byteorder.3 libc/ethers.3 \
+ libc/gethostbyname.3 libc/getnetent.3 libc/getprotoent.3 \
+ libc/getservent.3 libc/inet.3 libc/iso_addr.3 libc/linkaddr.3 libc/ns.3 \
+ libc/rcmd.3 libc/resolver.3
+EXTRA_DIST += $(libc_mans)
+
+if HAS_NETWORKING
+man_MANS = $(libc_MANS)
+
+## lib
+
+EXTRA_DIST += lib/README
+
+lib_CPPFLAGS = -DNOPOLL -DNOSELECT
+
+noinst_LIBRARIES += lib.a
+lib_a_CPPFLAGS = $(AM_CPPFLAGS) $(lib_CPPFLAGS) -D__BSD_VISIBLE
+
+lib_a_SOURCES = lib/getprotoby.c lib/rtems_bsdnet_ntp.c lib/ftpfs.c \
+ lib/syslog.c lib/tftpDriver.c
+endif
+
+EXTRA_DIST += $(UNUSED_FILES)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/libnetworking/README b/cpukit/libnetworking/README
new file mode 100644
index 0000000000..ed76f94183
--- /dev/null
+++ b/cpukit/libnetworking/README
@@ -0,0 +1,72 @@
+#
+# $Id$
+#
+
+This is a snapshot of my attempt to fit the FreeBSD networking code into
+RTEMS. Things seem to be working!
+
+Things that need to be done:
+ 1) More documentation!
+ 2) Figure out what's still not working :-)
+ 3) Rationalize the include files. Right now I have a special
+ hack in the Makefile to ensure that I pick up the FreeBSD versions
+ of the include files that are duplicated between RTEMS
+ and FreeBSD.
+ The network device driver source should move to the BSP source tree.
+ 4) Have a look at all the FIXME comments.
+ 5) Go through and make sure that all the source files are
+ free of undesired copyright restrictions.
+
+Initial Changes
+===============
+
+19-AUG-1998 snapshot
+ - Pulled BOOTP initialization out of rtems_glue. Applications which
+ don't used BOOTP are now about 5k smaller.
+ - Loopback interface is not installed by default, rather it is
+ attached like any other interface. Saves about 0.5 kbytes.
+ - Add rtems_bsdnet_show_if_stats();
+ - Moved test programs from below freebsd directory.
+
+18-AUG-1998 snapshot
+ - Removed some include files that were already part of RTEMS.
+ - Cleaned up machine/types.h to prepare for inclusion in RTEMS source.
+ - Added syslog library routines -- much simpler than KA9Q version.
+ Sockets can be shared among tasks (as long as the send is
+ protected by a mutex) so there's no need for a Syslog Daemon.
+
+16-AUG-1998 snapshot
+ - Table-driven configuration (networkconfig.h).
+ - Cleaned up rtems_bsdnet.h.
+ - BOOTP now retries properly -- Note to Joel:
+ The dichotomy between RTEMS and UNIX error codes is
+ a real pain!
+
+14-AUG-1998 snapshot
+ - Added dummy getprotobyname() and getprotobynum() functions.
+ - Added socket ioctl.
+ - Added application-level entry to manipulate routing tables.
+ - Added non-BOOTP network initialization.
+
+13-AUG-1998 snapshot
+ - Changed some BOOTP addresses from sockaddr_in to inaddr;
+ - Get DNS information from BOOTP reply.
+ - Got DNS lookups working.
+ Bloatware comes to RTEMS -- invoking gethostbyname() drags in
+ and extra 40 kbytes of code!
+ - Added hostname lookup program.
+
+12-AUG-1998 snapshot
+ - Added startup delay to network initialization.
+ - More statistic-printing routines.
+ - Added TFTP driver and test program
+ - Modified TFTP test program to use networkconfig.h.
+ - Removed unused include files.
+ - Added from ftp://ftp.ca.FreeBSD.ORG/pub/FreeBSD/FreeBSD-current/src/lib/libc/net.
+
+11-AUG-1998 snapshot.
+ - Added getpeername()
+ - Added M68k versions of IP checksum code
+ - Added TCP timing program to snapshot.
+
+02-AUG-1998 snapshot.
diff --git a/cpukit/libnetworking/arpa/ftp.h b/cpukit/libnetworking/arpa/ftp.h
new file mode 100644
index 0000000000..584d290bc9
--- /dev/null
+++ b/cpukit/libnetworking/arpa/ftp.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1983, 1989, 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.
+ *
+ * @(#)ftp.h 8.1 (Berkeley) 6/2/93
+ *
+ * $Id$
+ */
+
+#ifndef _ARPA_FTP_H_
+#define _ARPA_FTP_H_
+
+/* Definitions for FTP; see RFC-765. */
+
+/*
+ * 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 */
+
+/*
+ * Type codes
+ */
+#define TYPE_A 1 /* ASCII */
+#define TYPE_E 2 /* EBCDIC */
+#define TYPE_I 3 /* image */
+#define TYPE_L 4 /* local byte size */
+
+#ifdef FTP_NAMES
+char *typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local" };
+#endif
+
+/*
+ * Form codes
+ */
+#define FORM_N 1 /* non-print */
+#define FORM_T 2 /* telnet format effectors */
+#define FORM_C 3 /* carriage control (ASA) */
+#ifdef FTP_NAMES
+char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" };
+#endif
+
+/*
+ * Structure codes
+ */
+#define STRU_F 1 /* file (no record structure) */
+#define STRU_R 2 /* record structure */
+#define STRU_P 3 /* page structure */
+#ifdef FTP_NAMES
+char *strunames[] = {"0", "File", "Record", "Page" };
+#endif
+
+/*
+ * Mode types
+ */
+#define MODE_S 1 /* stream */
+#define MODE_B 2 /* block */
+#define MODE_C 3 /* compressed */
+#ifdef FTP_NAMES
+char *modenames[] = {"0", "Stream", "Block", "Compressed" };
+#endif
+
+/*
+ * Record Tokens
+ */
+#define REC_ESC '\377' /* Record-mode Escape */
+#define REC_EOR '\001' /* Record-mode End-of-Record */
+#define REC_EOF '\002' /* Record-mode End-of-File */
+
+/*
+ * Block Header
+ */
+#define BLK_EOR 0x80 /* Block is End-of-Record */
+#define BLK_EOF 0x40 /* Block is End-of-File */
+#define BLK_ERRORS 0x20 /* Block is suspected of containing errors */
+#define BLK_RESTART 0x10 /* Block is Restart Marker */
+
+#define BLK_BYTECOUNT 2 /* Bytes in this block */
+
+#endif /* !_FTP_H_ */
diff --git a/cpukit/libnetworking/arpa/inet.h b/cpukit/libnetworking/arpa/inet.h
new file mode 100644
index 0000000000..d1032cf0be
--- /dev/null
+++ b/cpukit/libnetworking/arpa/inet.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1983, 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.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * @(#)inet.h 8.1 (Berkeley) 6/2/93
+ * From: Id: inet.h,v 8.5 1997/01/29 08:48:09 vixie Exp $
+ * $FreeBSD: src/include/arpa/inet.h,v 1.25 2002/08/21 16:19:56 mike Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _ARPA_INET_H_
+#define _ARPA_INET_H_
+
+/* External definitions for functions in inet(3), addr2ascii(3) */
+
+#include <sys/cdefs.h>
+#include <rtems/bsdnet/_types.h>
+
+#define INET_ADDRSTRLEN 16
+#define INET6_ADDRSTRLEN 46
+
+#ifndef _IN_ADDR_T_DECLARED
+typedef uint32_t in_addr_t;
+#define _IN_ADDR_T_DECLARED
+#endif
+
+#ifndef _IN_PORT_T_DECLARED
+typedef uint16_t in_port_t;
+#define _IN_PORT_T_DECLARED
+#endif
+
+/*
+ * XXX socklen_t is used by a POSIX.1-2001 interface, but not required by
+ * POSIX.1-2001.
+ */
+#ifndef _SOCKLEN_T_DECLARED
+typedef __socklen_t socklen_t;
+#define _SOCKLEN_T_DECLARED
+#endif
+
+#ifndef _STRUCT_IN_ADDR_DECLARED
+struct in_addr {
+ in_addr_t s_addr;
+};
+#define _STRUCT_IN_ADDR_DECLARED
+#endif
+
+#if !defined(__rtems__) /* RTEMS -- Why rename these? */
+/* XXX all new diversions!! argh!! */
+#if __BSD_VISIBLE
+#define inet_addr __inet_addr
+#define inet_aton __inet_aton
+#define inet_lnaof __inet_lnaof
+#define inet_makeaddr __inet_makeaddr
+#define inet_neta __inet_neta
+#define inet_netof __inet_netof
+#define inet_network __inet_network
+#define inet_net_ntop __inet_net_ntop
+#define inet_net_pton __inet_net_pton
+#define inet_ntoa __inet_ntoa
+#define inet_pton __inet_pton
+#define inet_ntop __inet_ntop
+#define inet_nsap_addr __inet_nsap_addr
+#define inet_nsap_ntoa __inet_nsap_ntoa
+#endif /* __BSD_VISIBLE */
+#endif /* __rtems__ */
+
+__BEGIN_DECLS
+in_addr_t inet_addr(const char *);
+char *inet_ntoa(struct in_addr);
+const char *inet_ntop(int, const void * __restrict, char * __restrict,
+ socklen_t);
+int inet_pton(int, const char * __restrict, void * __restrict);
+
+#if __BSD_VISIBLE
+int ascii2addr(int, const char *, void *);
+char *addr2ascii(int, const void *, int, char *);
+int inet_aton(const char *, struct in_addr *);
+in_addr_t inet_lnaof(struct in_addr);
+struct in_addr inet_makeaddr(in_addr_t, in_addr_t);
+char * inet_neta(in_addr_t, char *, size_t);
+in_addr_t inet_netof(struct in_addr);
+in_addr_t inet_network(const char *);
+char *inet_net_ntop(int, const void *, int, char *, size_t);
+int inet_net_pton(int, const char *, void *, size_t);
+unsigned inet_nsap_addr(const char *, unsigned char *, int);
+char *inet_nsap_ntoa(int, const unsigned char *, char *);
+#endif /* __BSD_VISIBLE */
+__END_DECLS
+
+#endif /* !_ARPA_INET_H_ */
diff --git a/cpukit/libnetworking/arpa/nameser.h b/cpukit/libnetworking/arpa/nameser.h
new file mode 100644
index 0000000000..b4d6236aff
--- /dev/null
+++ b/cpukit/libnetworking/arpa/nameser.h
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 1983, 1989, 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.
+ */
+
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * From: Id: nameser.h,v 8.16 1998/02/06 00:35:58 halley Exp
+ * $FreeBSD: src/include/arpa/nameser.h,v 1.16 2002/03/23 17:24:55 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _ARPA_NAMESER_H_
+#define _ARPA_NAMESER_H_
+
+#define BIND_4_COMPAT
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+/*
+ * revision information. this is the release date in YYYYMMDD format.
+ * it can change every day so the right thing to do with it is use it
+ * in preprocessor commands such as "#if (__NAMESER > 19931104)". do not
+ * compare for equality; rather, use it to determine whether your libnameser.a
+ * is new enough to contain a certain feature.
+ */
+
+/* XXXRTH I made this bigger than __BIND in 4.9.5 T6B */
+#define __NAMESER 19961001 /* New interface version stamp. */
+
+/*
+ * Define constants based on RFC 883, RFC 1034, RFC 1035
+ */
+#define NS_PACKETSZ 512 /* maximum packet size */
+#define NS_MAXDNAME 1025 /* maximum domain name */
+#define NS_MAXCDNAME 255 /* maximum compressed domain name */
+#define NS_MAXLABEL 63 /* maximum length of domain label */
+#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
+#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
+#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
+#define NS_INT32SZ 4 /* #/bytes of data in a u_int32_t */
+#define NS_INT16SZ 2 /* #/bytes of data in a u_int16_t */
+#define NS_INT8SZ 1 /* #/bytes of data in a u_int8_t */
+#define NS_INADDRSZ 4 /* IPv4 T_A */
+#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
+#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
+#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
+
+/*
+ * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()
+ * in synch with it.
+ */
+typedef enum __ns_sect {
+ ns_s_qd = 0, /* Query: Question. */
+ ns_s_zn = 0, /* Update: Zone. */
+ ns_s_an = 1, /* Query: Answer. */
+ ns_s_pr = 1, /* Update: Prerequisites. */
+ ns_s_ns = 2, /* Query: Name servers. */
+ ns_s_ud = 2, /* Update: Update. */
+ ns_s_ar = 3, /* Query|Update: Additional records. */
+ ns_s_max = 4
+} ns_sect;
+
+/*
+ * This is a message handle. It is caller allocated and has no dynamic data.
+ * This structure is intended to be opaque to all but ns_parse.c, thus the
+ * leading _'s on the member names. Use the accessor functions, not the _'s.
+ */
+typedef struct __ns_msg {
+ const u_char *_msg, *_eom;
+ u_int16_t _id, _flags, _counts[ns_s_max];
+ const u_char *_sections[ns_s_max];
+ ns_sect _sect;
+ int _rrnum;
+ const u_char *_ptr;
+} ns_msg;
+
+/* Private data structure - do not use from outside library. */
+struct _ns_flagdata { int mask, shift; };
+extern struct _ns_flagdata _ns_flagdata[];
+
+/* Accessor macros - this is part of the public interface. */
+#define ns_msg_getflag(handle, flag) ( \
+ ((handle)._flags & _ns_flagdata[flag].mask) \
+ >> _ns_flagdata[flag].shift \
+ )
+#define ns_msg_id(handle) ((handle)._id + 0)
+#define ns_msg_base(handle) ((handle)._msg + 0)
+#define ns_msg_end(handle) ((handle)._eom + 0)
+#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
+#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
+
+/*
+ * This is a parsed record. It is caller allocated and has no dynamic data.
+ */
+typedef struct __ns_rr {
+ char name[NS_MAXDNAME]; /* XXX need to malloc */
+ u_int16_t type;
+ u_int16_t rr_class;
+ u_int32_t ttl;
+ u_int16_t rdlength;
+ const u_char *rdata;
+} ns_rr;
+
+/* Accessor macros - this is part of the public interface. */
+#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
+#define ns_rr_type(rr) ((rr).type + 0)
+#define ns_rr_class(rr) ((rr).rr_class + 0)
+#define ns_rr_ttl(rr) ((rr).ttl + 0)
+#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
+#define ns_rr_rdata(rr) ((rr).rdata + 0)
+
+/*
+ * These don't have to be in the same order as in the packet flags word,
+ * and they can even overlap in some cases, but they will need to be kept
+ * in synch with ns_parse.c:ns_flagdata[].
+ */
+typedef enum __ns_flag {
+ ns_f_qr, /* Question/Response. */
+ ns_f_opcode, /* Operation code. */
+ ns_f_aa, /* Authoritative Answer. */
+ ns_f_tc, /* Truncation occurred. */
+ ns_f_rd, /* Recursion Desired. */
+ ns_f_ra, /* Recursion Available. */
+ ns_f_z, /* MBZ. */
+ ns_f_ad, /* Authentic Data (DNSSEC). */
+ ns_f_cd, /* Checking Disabled (DNSSEC). */
+ ns_f_rcode, /* Response code. */
+ ns_f_max
+} ns_flag;
+
+/*
+ * Currently defined opcodes.
+ */
+typedef enum __ns_opcode {
+ ns_o_query = 0, /* Standard query. */
+ ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */
+ ns_o_status = 2, /* Name server status query (unsupported). */
+ /* Opcode 3 is undefined/reserved. */
+ ns_o_notify = 4, /* Zone change notification. */
+ ns_o_update = 5, /* Zone update message. */
+ ns_o_max = 6
+} ns_opcode;
+
+/*
+ * Currently defined response codes.
+ */
+typedef enum __ns_rcode {
+ ns_r_noerror = 0, /* No error occurred. */
+ ns_r_formerr = 1, /* Format error. */
+ ns_r_servfail = 2, /* Server failure. */
+ ns_r_nxdomain = 3, /* Name error. */
+ ns_r_notimpl = 4, /* Unimplemented. */
+ ns_r_refused = 5, /* Operation refused. */
+ /* these are for BIND_UPDATE */
+ ns_r_yxdomain = 6, /* Name exists */
+ ns_r_yxrrset = 7, /* RRset exists */
+ ns_r_nxrrset = 8, /* RRset does not exist */
+ ns_r_notauth = 9, /* Not authoritative for zone */
+ ns_r_notzone = 10, /* Zone of record different from zone section */
+ ns_r_max = 11
+} ns_rcode;
+
+/* BIND_UPDATE */
+typedef enum __ns_update_operation {
+ ns_uop_delete = 0,
+ ns_uop_add = 1,
+ ns_uop_max = 2
+} ns_update_operation;
+
+/*
+ * This RR-like structure is particular to UPDATE.
+ */
+struct ns_updrec {
+ struct ns_updrec *r_prev; /* prev record */
+ struct ns_updrec *r_next; /* next record */
+ u_int8_t r_section; /* ZONE/PREREQUISITE/UPDATE */
+ char * r_dname; /* owner of the RR */
+ u_int16_t r_class; /* class number */
+ u_int16_t r_type; /* type number */
+ u_int32_t r_ttl; /* time to live */
+ u_char * r_data; /* rdata fields as text string */
+ u_int16_t r_size; /* size of r_data field */
+ int r_opcode; /* type of operation */
+ /* following fields for private use by the resolver/server routines */
+ struct ns_updrec *r_grpnext; /* next record when grouped */
+ struct databuf *r_dp; /* databuf to process */
+ struct databuf *r_deldp; /* databuf's deleted/overwritten */
+ u_int16_t r_zone; /* zone number on server */
+};
+typedef struct ns_updrec ns_updrec;
+
+/*
+ * Currently defined type values for resources and queries.
+ */
+typedef enum __ns_type {
+ ns_t_a = 1, /* Host address. */
+ ns_t_ns = 2, /* Authoritative server. */
+ ns_t_md = 3, /* Mail destination. */
+ ns_t_mf = 4, /* Mail forwarder. */
+ ns_t_cname = 5, /* Canonical name. */
+ ns_t_soa = 6, /* Start of authority zone. */
+ ns_t_mb = 7, /* Mailbox domain name. */
+ ns_t_mg = 8, /* Mail group member. */
+ ns_t_mr = 9, /* Mail rename name. */
+ ns_t_null = 10, /* Null resource record. */
+ ns_t_wks = 11, /* Well known service. */
+ ns_t_ptr = 12, /* Domain name pointer. */
+ ns_t_hinfo = 13, /* Host information. */
+ ns_t_minfo = 14, /* Mailbox information. */
+ ns_t_mx = 15, /* Mail routing information. */
+ ns_t_txt = 16, /* Text strings. */
+ ns_t_rp = 17, /* Responsible person. */
+ ns_t_afsdb = 18, /* AFS cell database. */
+ ns_t_x25 = 19, /* X_25 calling address. */
+ ns_t_isdn = 20, /* ISDN calling address. */
+ ns_t_rt = 21, /* Router. */
+ ns_t_nsap = 22, /* NSAP address. */
+ ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
+ ns_t_sig = 24, /* Security signature. */
+ ns_t_key = 25, /* Security key. */
+ ns_t_px = 26, /* X.400 mail mapping. */
+ ns_t_gpos = 27, /* Geographical position (withdrawn). */
+ ns_t_aaaa = 28, /* Ip6 Address. */
+ ns_t_loc = 29, /* Location Information. */
+ ns_t_nxt = 30, /* Next domain (security). */
+ ns_t_eid = 31, /* Endpoint identifier. */
+ ns_t_nimloc = 32, /* Nimrod Locator. */
+ ns_t_srv = 33, /* Server Selection. */
+ ns_t_atma = 34, /* ATM Address */
+ ns_t_naptr = 35, /* Naming Authority PoinTeR */
+ ns_t_opt = 41, /* OPT pseudo-RR, RFC2761 */
+ /* Query type values which do not appear in resource records. */
+ ns_t_ixfr = 251, /* Incremental zone transfer. */
+ ns_t_axfr = 252, /* Transfer zone of authority. */
+ ns_t_mailb = 253, /* Transfer mailbox records. */
+ ns_t_maila = 254, /* Transfer mail agent records. */
+ ns_t_any = 255, /* Wildcard match. */
+ ns_t_max = 65536
+} ns_type;
+
+/*
+ * Values for class field
+ */
+typedef enum __ns_class {
+ ns_c_in = 1, /* Internet. */
+ /* Class 2 unallocated/unsupported. */
+ ns_c_chaos = 3, /* MIT Chaos-net. */
+ ns_c_hs = 4, /* MIT Hesiod. */
+ /* Query class values which do not appear in resource records */
+ ns_c_none = 254, /* for prereq. sections in update requests */
+ ns_c_any = 255, /* Wildcard match. */
+ ns_c_max = 65536
+} ns_class;
+
+/*
+ * Flags field of the KEY RR rdata
+ */
+#define NS_KEY_TYPEMASK 0xC000 /* Mask for "type" bits */
+#define NS_KEY_TYPE_AUTH_CONF 0x0000 /* Key usable for both */
+#define NS_KEY_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */
+#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */
+#define NS_KEY_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */
+/* The type bits can also be interpreted independently, as single bits: */
+#define NS_KEY_NO_AUTH 0x8000 /* Key unusable for authentication */
+#define NS_KEY_NO_CONF 0x4000 /* Key unusable for confidentiality */
+#define NS_KEY_EXPERIMENTAL 0x2000 /* Security is *mandatory* if bit=0 */
+#define NS_KEY_RESERVED3 0x1000 /* reserved - must be zero */
+#define NS_KEY_RESERVED4 0x0800 /* reserved - must be zero */
+#define NS_KEY_USERACCOUNT 0x0400 /* key is assoc. with a user acct */
+#define NS_KEY_ENTITY 0x0200 /* key is assoc. with entity eg host */
+#define NS_KEY_ZONEKEY 0x0100 /* key is zone key */
+#define NS_KEY_IPSEC 0x0080 /* key is for IPSEC (host or user)*/
+#define NS_KEY_EMAIL 0x0040 /* key is for email (MIME security) */
+#define NS_KEY_RESERVED10 0x0020 /* reserved - must be zero */
+#define NS_KEY_RESERVED11 0x0010 /* reserved - must be zero */
+#define NS_KEY_SIGNATORYMASK 0x000F /* key can sign RR's of same name */
+
+#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED3 | \
+ NS_KEY_RESERVED4 | \
+ NS_KEY_RESERVED10 | \
+ NS_KEY_RESERVED11 )
+
+/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
+#define NS_ALG_MD5RSA 1 /* MD5 with RSA */
+#define NS_ALG_EXPIRE_ONLY 253 /* No alg, no security */
+#define NS_ALG_PRIVATE_OID 254 /* Key begins with OID giving alg */
+
+/* Signatures */
+#define NS_MD5RSA_MIN_BITS 512 /* Size of a mod or exp in bits */
+#define NS_MD5RSA_MAX_BITS 2552
+ /* Total of binary mod and exp */
+#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3)
+ /* Max length of text sig block */
+#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4)
+
+/* Offsets into SIG record rdata to find various values */
+#define NS_SIG_TYPE 0 /* Type flags */
+#define NS_SIG_ALG 2 /* Algorithm */
+#define NS_SIG_LABELS 3 /* How many labels in name */
+#define NS_SIG_OTTL 4 /* Original TTL */
+#define NS_SIG_EXPIR 8 /* Expiration time */
+#define NS_SIG_SIGNED 12 /* Signature time */
+#define NS_SIG_FOOT 16 /* Key footprint */
+#define NS_SIG_SIGNER 18 /* Domain name of who signed it */
+
+/* How RR types are represented as bit-flags in NXT records */
+#define NS_NXT_BITS 8
+#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS)))
+#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
+#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS)))
+
+
+/*
+ * Inline versions of get/put short/long. Pointer is advanced.
+ */
+#define NS_GET16(s, cp) { \
+ register u_char *t_cp = (u_char *)(cp); \
+ (s) = ((u_int16_t)t_cp[0] << 8) \
+ | ((u_int16_t)t_cp[1]) \
+ ; \
+ (cp) += NS_INT16SZ; \
+}
+
+#define NS_GET32(l, cp) { \
+ register u_char *t_cp = (u_char *)(cp); \
+ (l) = ((u_int32_t)t_cp[0] << 24) \
+ | ((u_int32_t)t_cp[1] << 16) \
+ | ((u_int32_t)t_cp[2] << 8) \
+ | ((u_int32_t)t_cp[3]) \
+ ; \
+ (cp) += NS_INT32SZ; \
+}
+
+#define NS_PUT16(s, cp) { \
+ register u_int16_t t_s = (u_int16_t)(s); \
+ register u_char *t_cp = (u_char *)(cp); \
+ *t_cp++ = t_s >> 8; \
+ *t_cp = t_s; \
+ (cp) += NS_INT16SZ; \
+}
+
+#define NS_PUT32(l, cp) { \
+ register u_int32_t t_l = (u_int32_t)(l); \
+ register u_char *t_cp = (u_char *)(cp); \
+ *t_cp++ = t_l >> 24; \
+ *t_cp++ = t_l >> 16; \
+ *t_cp++ = t_l >> 8; \
+ *t_cp = t_l; \
+ (cp) += NS_INT32SZ; \
+}
+
+/*
+ * ANSI C identifier hiding.
+ */
+#define ns_get16 __ns_get16
+#define ns_get32 __ns_get32
+#define ns_put16 __ns_put16
+#define ns_put32 __ns_put32
+#define ns_initparse __ns_initparse
+#define ns_parserr __ns_parserr
+#define ns_sprintrr __ns_sprintrr
+#define ns_sprintrrf __ns_sprintrrf
+#define ns_format_ttl __ns_format_ttl
+#define ns_parse_ttl __ns_parse_ttl
+#define ns_name_ntop __ns_name_ntop
+#define ns_name_pton __ns_name_pton
+#define ns_name_unpack __ns_name_unpack
+#define ns_name_pack __ns_name_pack
+#define ns_name_compress __ns_name_compress
+#define ns_name_uncompress __ns_name_uncompress
+
+__BEGIN_DECLS
+u_int ns_get16(const u_char *);
+u_long ns_get32(const u_char *);
+void ns_put16(u_int, u_char *);
+void ns_put32(u_long, u_char *);
+int ns_initparse(const u_char *, int, ns_msg *);
+int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
+int ns_sprintrr(const ns_msg *, const ns_rr *,
+ const char *, const char *, char *, size_t);
+int ns_sprintrrf(const u_char *, size_t, const char *,
+ ns_class, ns_type, u_long, const u_char *,
+ size_t, const char *, const char *,
+ char *, size_t);
+int ns_format_ttl(u_long, char *, size_t);
+int ns_parse_ttl(const char *, u_long *);
+int ns_name_ntop(const u_char *, char *, size_t);
+int ns_name_pton(const char *, u_char *, size_t);
+int ns_name_unpack(const u_char *, const u_char *,
+ const u_char *, u_char *, size_t);
+int ns_name_pack(const u_char *, u_char *, int,
+ const u_char **, const u_char **);
+int ns_name_uncompress(const u_char *, const u_char *,
+ const u_char *, char *, size_t);
+int ns_name_compress(const char *, u_char *, size_t,
+ const u_char **, const u_char **);
+int ns_name_skip(const u_char **, const u_char *);
+__END_DECLS
+
+#ifdef BIND_4_COMPAT
+#include <arpa/nameser_compat.h>
+#endif
+
+#endif /* !_ARPA_NAMESER_H_ */
diff --git a/cpukit/libnetworking/arpa/nameser_compat.h b/cpukit/libnetworking/arpa/nameser_compat.h
new file mode 100644
index 0000000000..2ab5b47386
--- /dev/null
+++ b/cpukit/libnetworking/arpa/nameser_compat.h
@@ -0,0 +1,194 @@
+/* Copyright (c) 1983, 1989
+ * 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.
+ */
+
+/*
+ * from nameser.h 8.1 (Berkeley) 6/2/93
+ * From: Id: nameser_compat.h,v 8.9 1998/03/20 23:25:10 halley Exp
+ * $Id$
+ */
+
+#ifndef _ARPA_NAMESER_COMPAT_
+#define _ARPA_NAMESER_COMPAT_
+
+#define __BIND 19950621 /* (DEAD) interface version stamp. */
+
+#include <machine/endian.h>
+
+#if !defined(BYTE_ORDER) || \
+ (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \
+ BYTE_ORDER != PDP_ENDIAN)
+ /* you must determine what the correct bit order is for
+ * your compiler - the next line is an intentional error
+ * which will force your compiles to bomb until you fix
+ * the above macros.
+ */
+ error "Undefined or invalid BYTE_ORDER";
+#endif
+
+/*
+ * Structure for query header. The order of the fields is machine- and
+ * compiler-dependent, depending on the byte/bit order and the layout
+ * of bit fields. We use bit fields only in int variables, as this
+ * is all ANSI requires. This requires a somewhat confusing rearrangement.
+ */
+
+typedef struct {
+ unsigned id :16; /* query identification number */
+#if BYTE_ORDER == BIG_ENDIAN
+ /* fields in third byte */
+ unsigned qr: 1; /* response flag */
+ unsigned opcode: 4; /* purpose of message */
+ unsigned aa: 1; /* authoritive answer */
+ unsigned tc: 1; /* truncated message */
+ unsigned rd: 1; /* recursion desired */
+ /* fields in fourth byte */
+ unsigned ra: 1; /* recursion available */
+ unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
+ unsigned ad: 1; /* authentic data from named */
+ unsigned cd: 1; /* checking disabled by resolver */
+ unsigned rcode :4; /* response code */
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+ /* fields in third byte */
+ unsigned rd :1; /* recursion desired */
+ unsigned tc :1; /* truncated message */
+ unsigned aa :1; /* authoritive answer */
+ unsigned opcode :4; /* purpose of message */
+ unsigned qr :1; /* response flag */
+ /* fields in fourth byte */
+ unsigned rcode :4; /* response code */
+ unsigned cd: 1; /* checking disabled by resolver */
+ unsigned ad: 1; /* authentic data from named */
+ unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
+ unsigned ra :1; /* recursion available */
+#endif
+ /* remaining bytes */
+ unsigned qdcount :16; /* number of question entries */
+ unsigned ancount :16; /* number of answer entries */
+ unsigned nscount :16; /* number of authority entries */
+ unsigned arcount :16; /* number of resource entries */
+} HEADER;
+
+#define PACKETSZ NS_PACKETSZ
+#define MAXDNAME NS_MAXDNAME
+#define MAXCDNAME NS_MAXCDNAME
+#define MAXLABEL NS_MAXLABEL
+#define HFIXEDSZ NS_HFIXEDSZ
+#define QFIXEDSZ NS_QFIXEDSZ
+#define RRFIXEDSZ NS_RRFIXEDSZ
+#define INT32SZ NS_INT32SZ
+#define INT16SZ NS_INT16SZ
+#define INADDRSZ NS_INADDRSZ
+#define IN6ADDRSZ NS_IN6ADDRSZ
+#define INDIR_MASK NS_CMPRSFLGS
+#define NAMESERVER_PORT NS_DEFAULTPORT
+
+#define S_ZONE ns_s_zn
+#define S_PREREQ ns_s_pr
+#define S_UPDATE ns_s_ud
+#define S_ADDT ns_s_ar
+
+#define QUERY ns_o_query
+#define IQUERY ns_o_iquery
+#define STATUS ns_o_status
+#define NS_NOTIFY_OP ns_o_notify
+#define NS_UPDATE_OP ns_o_update
+
+#define NOERROR ns_r_noerror
+#define FORMERR ns_r_formerr
+#define SERVFAIL ns_r_servfail
+#define NXDOMAIN ns_r_nxdomain
+#define NOTIMP ns_r_notimpl
+#define REFUSED ns_r_refused
+#define YXDOMAIN ns_r_yxdomain
+#define YXRRSET ns_r_yxrrset
+#define NXRRSET ns_r_nxrrset
+#define NOTAUTH ns_r_notauth
+#define NOTZONE ns_r_notzone
+
+#define DELETE ns_uop_delete
+#define ADD ns_uop_add
+
+#define T_A ns_t_a
+#define T_NS ns_t_ns
+#define T_MD ns_t_md
+#define T_MF ns_t_mf
+#define T_CNAME ns_t_cname
+#define T_SOA ns_t_soa
+#define T_MB ns_t_mb
+#define T_MG ns_t_mg
+#define T_MR ns_t_mr
+#define T_NULL ns_t_null
+#define T_WKS ns_t_wks
+#define T_PTR ns_t_ptr
+#define T_HINFO ns_t_hinfo
+#define T_MINFO ns_t_minfo
+#define T_MX ns_t_mx
+#define T_TXT ns_t_txt
+#define T_RP ns_t_rp
+#define T_AFSDB ns_t_afsdb
+#define T_X25 ns_t_x25
+#define T_ISDN ns_t_isdn
+#define T_RT ns_t_rt
+#define T_NSAP ns_t_nsap
+#define T_NSAP_PTR ns_t_nsap_ptr
+#define T_SIG ns_t_sig
+#define T_KEY ns_t_key
+#define T_PX ns_t_px
+#define T_GPOS ns_t_gpos
+#define T_AAAA ns_t_aaaa
+#define T_LOC ns_t_loc
+#define T_NXT ns_t_nxt
+#define T_EID ns_t_eid
+#define T_NIMLOC ns_t_nimloc
+#define T_SRV ns_t_srv
+#define T_ATMA ns_t_atma
+#define T_NAPTR ns_t_naptr
+#define T_IXFR ns_t_ixfr
+#define T_AXFR ns_t_axfr
+#define T_MAILB ns_t_mailb
+#define T_MAILA ns_t_maila
+#define T_ANY ns_t_any
+
+#define C_IN ns_c_in
+#define C_CHAOS ns_c_chaos
+#define C_HS ns_c_hs
+/* BIND_UPDATE */
+#define C_NONE ns_c_none
+#define C_ANY ns_c_any
+
+#define GETSHORT NS_GET16
+#define GETLONG NS_GET32
+#define PUTSHORT NS_PUT16
+#define PUTLONG NS_PUT32
+
+#endif /* _ARPA_NAMESER_COMPAT_ */
diff --git a/cpukit/libnetworking/bpfilter.h b/cpukit/libnetworking/bpfilter.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/bpfilter.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/dev/mii/mii.h b/cpukit/libnetworking/dev/mii/mii.h
new file mode 100644
index 0000000000..14e45b0462
--- /dev/null
+++ b/cpukit/libnetworking/dev/mii/mii.h
@@ -0,0 +1,206 @@
+/* $NetBSD: mii.h,v 1.9 2001/05/31 03:07:14 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 Manuel Bouyer. All rights reserved.
+ *
+ * Modification to match BSD/OS 3.0 MII interface by Jason R. Thorpe,
+ * Numerical Aerospace Simulation Facility, NASA Ames Research Center.
+ *
+ * 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 Manuel Bouyer.
+ * 4. 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 BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD: /repoman/r/ncvs/src/sys/dev/mii/mii.h,v 1.4 2002/04/29 11:57:28 phk Exp $
+ */
+
+#ifndef _DEV_MII_MII_H_
+#define _DEV_MII_MII_H_
+
+/*
+ * Registers common to all PHYs.
+ */
+
+#define MII_NPHY 32 /* max # of PHYs per MII */
+
+/*
+ * MII commands, used if a device must drive the MII lines
+ * manually.
+ */
+#define MII_COMMAND_START 0x01
+#define MII_COMMAND_READ 0x02
+#define MII_COMMAND_WRITE 0x01
+#define MII_COMMAND_ACK 0x02
+
+#define MII_BMCR 0x00 /* Basic mode control register (rw) */
+#define BMCR_RESET 0x8000 /* reset */
+#define BMCR_LOOP 0x4000 /* loopback */
+#define BMCR_SPEED0 0x2000 /* speed selection (LSB) */
+#define BMCR_AUTOEN 0x1000 /* autonegotiation enable */
+#define BMCR_PDOWN 0x0800 /* power down */
+#define BMCR_ISO 0x0400 /* isolate */
+#define BMCR_STARTNEG 0x0200 /* restart autonegotiation */
+#define BMCR_FDX 0x0100 /* Set duplex mode */
+#define BMCR_CTEST 0x0080 /* collision test */
+#define BMCR_SPEED1 0x0040 /* speed selection (MSB) */
+
+#define BMCR_S10 0x0000 /* 10 Mb/s */
+#define BMCR_S100 BMCR_SPEED0 /* 100 Mb/s */
+#define BMCR_S1000 BMCR_SPEED1 /* 1000 Mb/s */
+
+#define BMCR_SPEED(x) ((x) & (BMCR_SPEED0|BMCR_SPEED1))
+
+#define MII_BMSR 0x01 /* Basic mode status register (ro) */
+#define BMSR_100T4 0x8000 /* 100 base T4 capable */
+#define BMSR_100TXFDX 0x4000 /* 100 base Tx full duplex capable */
+#define BMSR_100TXHDX 0x2000 /* 100 base Tx half duplex capable */
+#define BMSR_10TFDX 0x1000 /* 10 base T full duplex capable */
+#define BMSR_10THDX 0x0800 /* 10 base T half duplex capable */
+#define BMSR_100T2FDX 0x0400 /* 100 base T2 full duplex capable */
+#define BMSR_100T2HDX 0x0200 /* 100 base T2 half duplex capable */
+#define BMSR_EXTSTAT 0x0100 /* Extended status in register 15 */
+#define BMSR_MFPS 0x0040 /* MII Frame Preamble Suppression */
+#define BMSR_ACOMP 0x0020 /* Autonegotiation complete */
+#define BMSR_RFAULT 0x0010 /* Link partner fault */
+#define BMSR_ANEG 0x0008 /* Autonegotiation capable */
+#define BMSR_LINK 0x0004 /* Link status */
+#define BMSR_JABBER 0x0002 /* Jabber detected */
+#define BMSR_EXTCAP 0x0001 /* Extended capability */
+
+/*
+ * Note that the EXTSTAT bit indicates that there is extended status
+ * info available in register 15, but 802.3 section 22.2.4.3 also
+ * states that that all 1000 Mb/s capable PHYs will set this bit to 1.
+ */
+#if 0
+#define BMSR_MEDIAMASK (BMSR_100T4|BMSR_100TXFDX|BMSR_100TXHDX|BMSR_10TFDX| \
+ BMSR_10THDX|BMSR_ANEG)
+
+#else
+/* NetBSD uses: */
+#define BMSR_MEDIAMASK (BMSR_100T4|BMSR_100TXFDX|BMSR_100TXHDX| \
+ BMSR_10TFDX|BMSR_10THDX|BMSR_100T2FDX|BMSR_100T2HDX)
+#endif
+
+/*
+ * Convert BMSR media capabilities to ANAR bits for autonegotiation.
+ * Note the shift chopps off the BMSR_ANEG bit.
+ */
+#define BMSR_MEDIA_TO_ANAR(x) (((x) & BMSR_MEDIAMASK) >> 6)
+
+#define MII_PHYIDR1 0x02 /* ID register 1 (ro) */
+
+#define MII_PHYIDR2 0x03 /* ID register 2 (ro) */
+#define IDR2_OUILSB 0xfc00 /* OUI LSB */
+#define IDR2_MODEL 0x03f0 /* vendor model */
+#define IDR2_REV 0x000f /* vendor revision */
+
+#define MII_OUI(id1, id2) (((id1) << 6) | ((id2) >> 10))
+#define MII_MODEL(id2) (((id2) & IDR2_MODEL) >> 4)
+#define MII_REV(id2) ((id2) & IDR2_REV)
+
+#define MII_ANAR 0x04 /* Autonegotiation advertisement (rw) */
+ /* section 28.2.4.1 and 37.2.6.1 */
+#define ANAR_NP 0x8000 /* Next page (ro) */
+#define ANAR_ACK 0x4000 /* link partner abilities acknowledged (ro) */
+#define ANAR_RF 0x2000 /* remote fault (ro) */
+#define ANAR_FC 0x0400 /* local device supports PAUSE */
+#define ANAR_T4 0x0200 /* local device supports 100bT4 */
+#define ANAR_TX_FD 0x0100 /* local device supports 100bTx FD */
+#define ANAR_TX 0x0080 /* local device supports 100bTx */
+#define ANAR_10_FD 0x0040 /* local device supports 10bT FD */
+#define ANAR_10 0x0020 /* local device supports 10bT */
+#define ANAR_CSMA 0x0001 /* protocol selector CSMA/CD */
+
+#define ANAR_X_FD 0x0020 /* local device supports 1000BASE-X FD */
+#define ANAR_X_HD 0x0040 /* local device supports 1000BASE-X HD */
+#define ANAR_X_PAUSE_NONE (0 << 7)
+#define ANAR_X_PAUSE_SYM (1 << 7)
+#define ANAR_X_PAUSE_ASYM (2 << 7)
+#define ANAR_X_PAUSE_TOWARDS (3 << 7)
+
+#define MII_ANLPAR 0x05 /* Autonegotiation lnk partner abilities (rw) */
+ /* section 28.2.4.1 and 37.2.6.1 */
+#define ANLPAR_NP 0x8000 /* Next page (ro) */
+#define ANLPAR_ACK 0x4000 /* link partner accepted ACK (ro) */
+#define ANLPAR_RF 0x2000 /* remote fault (ro) */
+#define ANLPAR_FC 0x0400 /* link partner supports PAUSE */
+#define ANLPAR_T4 0x0200 /* link partner supports 100bT4 */
+#define ANLPAR_TX_FD 0x0100 /* link partner supports 100bTx FD */
+#define ANLPAR_TX 0x0080 /* link partner supports 100bTx */
+#define ANLPAR_10_FD 0x0040 /* link partner supports 10bT FD */
+#define ANLPAR_10 0x0020 /* link partner supports 10bT */
+#define ANLPAR_CSMA 0x0001 /* protocol selector CSMA/CD */
+
+#define ANLPAR_X_FD 0x0020 /* local device supports 1000BASE-X FD */
+#define ANLPAR_X_HD 0x0040 /* local device supports 1000BASE-X HD */
+#define ANLPAR_X_PAUSE_MASK (3 << 7)
+#define ANLPAR_X_PAUSE_NONE (0 << 7)
+#define ANLPAR_X_PAUSE_SYM (1 << 7)
+#define ANLPAR_X_PAUSE_ASYM (2 << 7)
+#define ANLPAR_X_PAUSE_TOWARDS (3 << 7)
+
+#define MII_ANER 0x06 /* Autonegotiation expansion (ro) */
+ /* section 28.2.4.1 and 37.2.6.1 */
+#define ANER_MLF 0x0010 /* multiple link detection fault */
+#define ANER_LPNP 0x0008 /* link parter next page-able */
+#define ANER_NP 0x0004 /* next page-able */
+#define ANER_PAGE_RX 0x0002 /* Page received */
+#define ANER_LPAN 0x0001 /* link parter autoneg-able */
+
+#define MII_ANNP 0x07 /* Autonegotiation next page */
+ /* section 28.2.4.1 and 37.2.6.1 */
+
+#define MII_ANLPRNP 0x08 /* Autonegotiation link partner rx next page */
+ /* section 32.5.1 and 37.2.6.1 */
+
+ /* This is also the 1000baseT control register */
+#define MII_100T2CR 0x09 /* 100base-T2 control register */
+#define GTCR_TEST_MASK 0xe000 /* see 802.3ab ss. 40.6.1.1.2 */
+#define GTCR_MAN_MS 0x1000 /* enable manual master/slave control */
+#define GTCR_ADV_MS 0x0800 /* 1 = adv. master, 0 = adv. slave */
+#define GTCR_PORT_TYPE 0x0400 /* 1 = DCE, 0 = DTE (NIC) */
+#define GTCR_ADV_1000TFDX 0x0200 /* adv. 1000baseT FDX */
+#define GTCR_ADV_1000THDX 0x0100 /* adv. 1000baseT HDX */
+
+ /* This is also the 1000baseT status register */
+#define MII_100T2SR 0x0a /* 100base-T2 status register */
+#define GTSR_MAN_MS_FLT 0x8000 /* master/slave config fault */
+#define GTSR_MS_RES 0x4000 /* result: 1 = master, 0 = slave */
+#define GTSR_LRS 0x2000 /* local rx status, 1 = ok */
+#define GTSR_RRS 0x1000 /* remove rx status, 1 = ok */
+#define GTSR_LP_1000TFDX 0x0800 /* link partner 1000baseT FDX capable */
+#define GTSR_LP_1000THDX 0x0400 /* link partner 1000baseT HDX capable */
+#define GTSR_LP_ASM_DIR 0x0200 /* link partner asym. pause dir. capable */
+#define GTSR_IDLE_ERR 0x00ff /* IDLE error count */
+
+#define MII_EXTSR 0x0f /* Extended status register */
+#define EXTSR_1000XFDX 0x8000 /* 1000X full-duplex capable */
+#define EXTSR_1000XHDX 0x4000 /* 1000X half-duplex capable */
+#define EXTSR_1000TFDX 0x2000 /* 1000T full-duplex capable */
+#define EXTSR_1000THDX 0x1000 /* 1000T half-duplex capable */
+
+#define EXTSR_MEDIAMASK (EXTSR_1000XFDX|EXTSR_1000XHDX| \
+ EXTSR_1000TFDX|EXTSR_1000THDX)
+
+#endif /* _DEV_MII_MII_H_ */
diff --git a/cpukit/libnetworking/kern/kern_mib.c b/cpukit/libnetworking/kern/kern_mib.c
new file mode 100644
index 0000000000..6471208786
--- /dev/null
+++ b/cpukit/libnetworking/kern/kern_mib.c
@@ -0,0 +1,385 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Karels at Berkeley Software Design, Inc.
+ *
+ * Quite extensively rewritten by Poul-Henning Kamp of the FreeBSD
+ * project, to make these variables more userfriendly.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
+ * $FreeBSD: src/sys/kern/kern_mib.c,v 1.74 2005/02/28 21:42:56 wes Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef __rtems__
+#include "opt_posix.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#ifndef __rtems__
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/jail.h>
+#include <sys/smp.h>
+#endif
+#include <sys/unistd.h>
+
+#ifdef __rtems__
+char machine[] = "SET ME";
+char osrelease[] = RTEMS_VERSION;
+char ostype[] = "RTEMS";
+#endif
+
+SYSCTL_NODE(, 0, sysctl, CTLFLAG_RW, 0,
+ "Sysctl internal magic");
+SYSCTL_NODE(, CTL_KERN, kern, CTLFLAG_RW, 0,
+ "High kernel, proc, limits &c");
+#ifndef __rtems__
+SYSCTL_NODE(, CTL_VM, vm, CTLFLAG_RW, 0,
+ "Virtual memory");
+SYSCTL_NODE(, CTL_VFS, vfs, CTLFLAG_RW, 0,
+ "File system");
+#endif
+SYSCTL_NODE(, CTL_NET, net, CTLFLAG_RW, 0,
+ "Network, (see socket.h)");
+#ifndef __rtems__
+SYSCTL_NODE(, CTL_DEBUG, debug, CTLFLAG_RW, 0,
+ "Debugging");
+SYSCTL_NODE(_debug, OID_AUTO, sizeof, CTLFLAG_RW, 0,
+ "Sizeof various things");
+SYSCTL_NODE(, CTL_HW, hw, CTLFLAG_RW, 0,
+ "hardware");
+SYSCTL_NODE(, CTL_MACHDEP, machdep, CTLFLAG_RW, 0,
+ "machine dependent");
+SYSCTL_NODE(, CTL_USER, user, CTLFLAG_RW, 0,
+ "user-level");
+SYSCTL_NODE(, CTL_P1003_1B, p1003_1b, CTLFLAG_RW, 0,
+ "p1003_1b, (see p1003_1b.h)");
+
+SYSCTL_NODE(, OID_AUTO, compat, CTLFLAG_RW, 0,
+ "Compatibility code");
+SYSCTL_NODE(, OID_AUTO, security, CTLFLAG_RW, 0,
+ "Security");
+#ifdef REGRESSION
+SYSCTL_NODE(, OID_AUTO, regression, CTLFLAG_RW, 0,
+ "Regression test MIB");
+#endif
+
+SYSCTL_STRING(_kern, OID_AUTO, ident, CTLFLAG_RD,
+ kern_ident, 0, "Kernel identifier");
+#endif /* __rtems__ */
+
+SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease, CTLFLAG_RD,
+ osrelease, 0, "Operating system release");
+
+SYSCTL_INT(_kern, KERN_OSREV, osrevision, CTLFLAG_RD,
+ 0, BSD, "Operating system revision");
+
+#ifndef __rtems__
+SYSCTL_STRING(_kern, KERN_VERSION, version, CTLFLAG_RD,
+ version, 0, "Kernel version");
+#endif
+
+SYSCTL_STRING(_kern, KERN_OSTYPE, ostype, CTLFLAG_RD,
+ ostype, 0, "Operating system type");
+
+#ifndef __rtems__
+extern int osreldate;
+SYSCTL_INT(_kern, KERN_OSRELDATE, osreldate, CTLFLAG_RD,
+ &osreldate, 0, "Operating system release date");
+
+SYSCTL_INT(_kern, KERN_MAXPROC, maxproc, CTLFLAG_RD,
+ &maxproc, 0, "Maximum number of processes");
+
+SYSCTL_INT(_kern, KERN_MAXPROCPERUID, maxprocperuid, CTLFLAG_RW,
+ &maxprocperuid, 0, "Maximum processes allowed per userid");
+
+SYSCTL_INT(_kern, OID_AUTO, maxusers, CTLFLAG_RD,
+ &maxusers, 0, "Hint for kernel tuning");
+
+SYSCTL_INT(_kern, KERN_ARGMAX, argmax, CTLFLAG_RD,
+ 0, ARG_MAX, "Maximum bytes of argument to execve(2)");
+
+SYSCTL_INT(_kern, KERN_POSIX1, posix1version, CTLFLAG_RD,
+ 0, _POSIX_VERSION, "Version of POSIX attempting to comply to");
+
+SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RD,
+ 0, NGROUPS_MAX, "Maximum number of groups a user can belong to");
+
+SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control, CTLFLAG_RD,
+ 0, 1, "Whether job control is available");
+
+#ifdef _POSIX_SAVED_IDS
+SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD,
+ 0, 1, "Whether saved set-group/user ID is available");
+#else
+SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD,
+ 0, 0, "Whether saved set-group/user ID is available");
+#endif
+
+char kernelname[MAXPATHLEN] = "/kernel"; /* XXX bloat */
+
+SYSCTL_STRING(_kern, KERN_BOOTFILE, bootfile, CTLFLAG_RW,
+ kernelname, sizeof kernelname, "Name of kernel file booted");
+
+#ifdef SMP
+SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD,
+ &mp_ncpus, 0, "Number of active CPUs");
+#else
+SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD,
+ 0, 1, "Number of active CPUs");
+#endif
+
+SYSCTL_INT(_hw, HW_BYTEORDER, byteorder, CTLFLAG_RD,
+ 0, BYTE_ORDER, "System byte order");
+
+SYSCTL_INT(_hw, HW_PAGESIZE, pagesize, CTLFLAG_RD,
+ 0, PAGE_SIZE, "System memory page size");
+
+static int
+sysctl_hw_physmem(SYSCTL_HANDLER_ARGS)
+{
+ u_long val;
+
+ val = ctob(physmem);
+ return (sysctl_handle_long(oidp, &val, 0, req));
+}
+
+SYSCTL_PROC(_hw, HW_PHYSMEM, physmem, CTLTYPE_ULONG | CTLFLAG_RD,
+ 0, 0, sysctl_hw_physmem, "LU", "");
+
+static int
+sysctl_hw_usermem(SYSCTL_HANDLER_ARGS)
+{
+ u_long val;
+
+ val = ctob(physmem - cnt.v_wire_count);
+ return (sysctl_handle_long(oidp, &val, 0, req));
+}
+
+SYSCTL_PROC(_hw, HW_USERMEM, usermem, CTLTYPE_ULONG | CTLFLAG_RD,
+ 0, 0, sysctl_hw_usermem, "LU", "");
+
+SYSCTL_ULONG(_hw, OID_AUTO, availpages, CTLFLAG_RD, &physmem, 0, "");
+
+static char machine_arch[] = MACHINE_ARCH;
+SYSCTL_STRING(_hw, HW_MACHINE_ARCH, machine_arch, CTLFLAG_RD,
+ machine_arch, 0, "System architecture");
+
+char hostname[MAXHOSTNAMELEN];
+
+static int
+sysctl_hostname(SYSCTL_HANDLER_ARGS)
+{
+ struct prison *pr;
+ char tmphostname[MAXHOSTNAMELEN];
+ int error;
+
+ pr = req->td->td_ucred->cr_prison;
+ if (pr != NULL) {
+ if (!jail_set_hostname_allowed && req->newptr)
+ return (EPERM);
+ /*
+ * Process is in jail, so make a local copy of jail
+ * hostname to get/set so we don't have to hold the jail
+ * mutex during the sysctl copyin/copyout activities.
+ */
+ mtx_lock(&pr->pr_mtx);
+ bcopy(pr->pr_host, tmphostname, MAXHOSTNAMELEN);
+ mtx_unlock(&pr->pr_mtx);
+
+ error = sysctl_handle_string(oidp, tmphostname,
+ sizeof pr->pr_host, req);
+
+ if (req->newptr != NULL && error == 0) {
+ /*
+ * Copy the locally set hostname to the jail, if
+ * appropriate.
+ */
+ mtx_lock(&pr->pr_mtx);
+ bcopy(tmphostname, pr->pr_host, MAXHOSTNAMELEN);
+ mtx_unlock(&pr->pr_mtx);
+ }
+ } else
+ error = sysctl_handle_string(oidp,
+ hostname, sizeof hostname, req);
+ return (error);
+}
+
+SYSCTL_PROC(_kern, KERN_HOSTNAME, hostname,
+ CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_PRISON,
+ 0, 0, sysctl_hostname, "A", "Hostname");
+
+static int regression_securelevel_nonmonotonic = 0;
+
+#ifdef REGRESSION
+SYSCTL_INT(_regression, OID_AUTO, securelevel_nonmonotonic, CTLFLAG_RW,
+ &regression_securelevel_nonmonotonic, 0, "securelevel may be lowered");
+#endif
+
+int securelevel = -1;
+struct mtx securelevel_mtx;
+
+MTX_SYSINIT(securelevel_lock, &securelevel_mtx, "securelevel mutex lock",
+ MTX_DEF);
+
+static int
+sysctl_kern_securelvl(SYSCTL_HANDLER_ARGS)
+{
+ struct prison *pr;
+ int error, level;
+
+ pr = req->td->td_ucred->cr_prison;
+
+ /*
+ * If the process is in jail, return the maximum of the global and
+ * local levels; otherwise, return the global level.
+ */
+ if (pr != NULL) {
+ mtx_lock(&pr->pr_mtx);
+ level = imax(securelevel, pr->pr_securelevel);
+ mtx_unlock(&pr->pr_mtx);
+ } else
+ level = securelevel;
+ error = sysctl_handle_int(oidp, &level, 0, req);
+ if (error || !req->newptr)
+ return (error);
+ /*
+ * Permit update only if the new securelevel exceeds the
+ * global level, and local level if any.
+ */
+ if (pr != NULL) {
+ mtx_lock(&pr->pr_mtx);
+ if (!regression_securelevel_nonmonotonic &&
+ (level < imax(securelevel, pr->pr_securelevel))) {
+ mtx_unlock(&pr->pr_mtx);
+ return (EPERM);
+ }
+ pr->pr_securelevel = level;
+ mtx_unlock(&pr->pr_mtx);
+ } else {
+ mtx_lock(&securelevel_mtx);
+ if (!regression_securelevel_nonmonotonic &&
+ (level < securelevel)) {
+ mtx_unlock(&securelevel_mtx);
+ return (EPERM);
+ }
+ securelevel = level;
+ mtx_unlock(&securelevel_mtx);
+ }
+ return (error);
+}
+
+SYSCTL_PROC(_kern, KERN_SECURELVL, securelevel,
+ CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0, sysctl_kern_securelvl,
+ "I", "Current secure level");
+
+char domainname[MAXHOSTNAMELEN];
+SYSCTL_STRING(_kern, KERN_NISDOMAINNAME, domainname, CTLFLAG_RW,
+ &domainname, sizeof(domainname), "Name of the current YP/NIS domain");
+
+u_long hostid;
+SYSCTL_ULONG(_kern, KERN_HOSTID, hostid, CTLFLAG_RW, &hostid, 0, "Host ID");
+
+/*
+ * This is really cheating. These actually live in the libc, something
+ * which I'm not quite sure is a good idea anyway, but in order for
+ * getnext and friends to actually work, we define dummies here.
+ */
+SYSCTL_STRING(_user, USER_CS_PATH, cs_path, CTLFLAG_RD,
+ "", 0, "PATH that finds all the standard utilities");
+SYSCTL_INT(_user, USER_BC_BASE_MAX, bc_base_max, CTLFLAG_RD,
+ 0, 0, "Max ibase/obase values in bc(1)");
+SYSCTL_INT(_user, USER_BC_DIM_MAX, bc_dim_max, CTLFLAG_RD,
+ 0, 0, "Max array size in bc(1)");
+SYSCTL_INT(_user, USER_BC_SCALE_MAX, bc_scale_max, CTLFLAG_RD,
+ 0, 0, "Max scale value in bc(1)");
+SYSCTL_INT(_user, USER_BC_STRING_MAX, bc_string_max, CTLFLAG_RD,
+ 0, 0, "Max string length in bc(1)");
+SYSCTL_INT(_user, USER_COLL_WEIGHTS_MAX, coll_weights_max, CTLFLAG_RD,
+ 0, 0, "Maximum number of weights assigned to an LC_COLLATE locale entry");
+SYSCTL_INT(_user, USER_EXPR_NEST_MAX, expr_nest_max, CTLFLAG_RD, 0, 0, "");
+SYSCTL_INT(_user, USER_LINE_MAX, line_max, CTLFLAG_RD,
+ 0, 0, "Max length (bytes) of a text-processing utility's input line");
+SYSCTL_INT(_user, USER_RE_DUP_MAX, re_dup_max, CTLFLAG_RD,
+ 0, 0, "Maximum number of repeats of a regexp permitted");
+SYSCTL_INT(_user, USER_POSIX2_VERSION, posix2_version, CTLFLAG_RD,
+ 0, 0,
+ "The version of POSIX 1003.2 with which the system attempts to comply");
+SYSCTL_INT(_user, USER_POSIX2_C_BIND, posix2_c_bind, CTLFLAG_RD,
+ 0, 0, "Whether C development supports the C bindings option");
+SYSCTL_INT(_user, USER_POSIX2_C_DEV, posix2_c_dev, CTLFLAG_RD,
+ 0, 0, "Whether system supports the C development utilities option");
+SYSCTL_INT(_user, USER_POSIX2_CHAR_TERM, posix2_char_term, CTLFLAG_RD,
+ 0, 0, "");
+SYSCTL_INT(_user, USER_POSIX2_FORT_DEV, posix2_fort_dev, CTLFLAG_RD,
+ 0, 0, "Whether system supports FORTRAN development utilities");
+SYSCTL_INT(_user, USER_POSIX2_FORT_RUN, posix2_fort_run, CTLFLAG_RD,
+ 0, 0, "Whether system supports FORTRAN runtime utilities");
+SYSCTL_INT(_user, USER_POSIX2_LOCALEDEF, posix2_localedef, CTLFLAG_RD,
+ 0, 0, "Whether system supports creation of locales");
+SYSCTL_INT(_user, USER_POSIX2_SW_DEV, posix2_sw_dev, CTLFLAG_RD,
+ 0, 0, "Whether system supports software development utilities");
+SYSCTL_INT(_user, USER_POSIX2_UPE, posix2_upe, CTLFLAG_RD,
+ 0, 0, "Whether system supports the user portability utilities");
+SYSCTL_INT(_user, USER_STREAM_MAX, stream_max, CTLFLAG_RD,
+ 0, 0, "Min Maximum number of streams a process may have open at one time");
+SYSCTL_INT(_user, USER_TZNAME_MAX, tzname_max, CTLFLAG_RD,
+ 0, 0, "Min Maximum number of types supported for timezone names");
+
+#include <sys/vnode.h>
+SYSCTL_INT(_debug_sizeof, OID_AUTO, vnode, CTLFLAG_RD,
+ 0, sizeof(struct vnode), "sizeof(struct vnode)");
+
+SYSCTL_INT(_debug_sizeof, OID_AUTO, proc, CTLFLAG_RD,
+ 0, sizeof(struct proc), "sizeof(struct proc)");
+
+#include <sys/conf.h>
+SYSCTL_INT(_debug_sizeof, OID_AUTO, cdev, CTLFLAG_RD,
+ 0, sizeof(struct cdev), "sizeof(struct cdev)");
+
+#include <sys/bio.h>
+#include <sys/buf.h>
+SYSCTL_INT(_debug_sizeof, OID_AUTO, bio, CTLFLAG_RD,
+ 0, sizeof(struct bio), "sizeof(struct bio)");
+SYSCTL_INT(_debug_sizeof, OID_AUTO, buf, CTLFLAG_RD,
+ 0, sizeof(struct buf), "sizeof(struct buf)");
+
+#include <sys/user.h>
+SYSCTL_INT(_debug_sizeof, OID_AUTO, kinfo_proc, CTLFLAG_RD,
+ 0, sizeof(struct kinfo_proc), "sizeof(struct kinfo_proc)");
+
+#endif /* __rtems__ */
diff --git a/cpukit/libnetworking/kern/kern_subr.c b/cpukit/libnetworking/kern/kern_subr.c
new file mode 100644
index 0000000000..8d17a81205
--- /dev/null
+++ b/cpukit/libnetworking/kern/kern_subr.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 1982, 1986, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ *
+ * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+
+int
+uiomove(void *cp, int n, struct uio *uio)
+{
+ register struct iovec *iov;
+ u_int cnt;
+ int error;
+
+#ifdef DIAGNOSTIC
+ if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
+ panic("uiomove: mode");
+#endif
+ while (n > 0 && uio->uio_resid) {
+ iov = uio->uio_iov;
+ cnt = iov->iov_len;
+ if (cnt == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ continue;
+ }
+ if (cnt > n)
+ cnt = n;
+
+ switch (uio->uio_segflg) {
+
+ case UIO_USERSPACE:
+ case UIO_USERISPACE:
+ if (uio->uio_rw == UIO_READ)
+ error = copyout(cp, iov->iov_base, cnt);
+ else
+ error = copyin(iov->iov_base, cp, cnt);
+ if (error)
+ return (error);
+ break;
+
+ case UIO_SYSSPACE:
+ if (uio->uio_rw == UIO_READ)
+ bcopy((caddr_t)cp, iov->iov_base, cnt);
+ else
+ bcopy(iov->iov_base, (caddr_t)cp, cnt);
+ break;
+ case UIO_NOCOPY:
+ break;
+ }
+ iov->iov_base += cnt;
+ iov->iov_len -= cnt;
+ uio->uio_resid -= cnt;
+ uio->uio_offset += cnt;
+ cp += cnt;
+ n -= cnt;
+ }
+ return (0);
+}
+
+#ifdef vax /* unused except by ct.c, other oddities XXX */
+/*
+ * Get next character written in by user from uio.
+ */
+int
+uwritec(uio)
+ struct uio *uio;
+{
+ register struct iovec *iov;
+ register int c;
+
+ if (uio->uio_resid <= 0)
+ return (-1);
+again:
+ if (uio->uio_iovcnt <= 0)
+ panic("uwritec");
+ iov = uio->uio_iov;
+ if (iov->iov_len == 0) {
+ uio->uio_iov++;
+ if (--uio->uio_iovcnt == 0)
+ return (-1);
+ goto again;
+ }
+ switch (uio->uio_segflg) {
+
+ case UIO_USERSPACE:
+ c = fubyte(iov->iov_base);
+ break;
+
+ case UIO_SYSSPACE:
+ c = *(u_char *) iov->iov_base;
+ break;
+
+ case UIO_USERISPACE:
+ c = fuibyte(iov->iov_base);
+ break;
+ }
+ if (c < 0)
+ return (-1);
+ iov->iov_base++;
+ iov->iov_len--;
+ uio->uio_resid--;
+ uio->uio_offset++;
+ return (c);
+}
+#endif /* vax */
+
+/*
+ * General routine to allocate a hash table.
+ */
+void *
+hashinit(elements, type, hashmask)
+ int elements, type;
+ u_long *hashmask;
+{
+ long hashsize;
+ LIST_HEAD(generic, generic) *hashtbl;
+ int i;
+
+ if (elements <= 0)
+ panic("hashinit: bad elements");
+ for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
+ continue;
+ hashsize >>= 1;
+ hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
+ for (i = 0; i < hashsize; i++)
+ LIST_INIT(&hashtbl[i]);
+ *hashmask = hashsize - 1;
+ return (hashtbl);
+}
+
+#define NPRIMES 27
+static int primes[] = { 1, 13, 31, 61, 127, 251, 509, 761, 1021, 1531, 2039,
+ 2557, 3067, 3583, 4093, 4603, 5119, 5623, 6143, 6653,
+ 7159, 7673, 8191, 12281, 16381, 24571, 32749 };
+
+/*
+ * General routine to allocate a prime number sized hash table.
+ */
+void *
+phashinit(elements, type, nentries)
+ int elements, type;
+ u_long *nentries;
+{
+ long hashsize;
+ LIST_HEAD(generic, generic) *hashtbl;
+ int i;
+
+ if (elements <= 0)
+ panic("phashinit: bad elements");
+ for (i = 1, hashsize = primes[1]; hashsize <= elements;) {
+ i++;
+ if (i == NPRIMES)
+ break;
+ hashsize = primes[i];
+ }
+ hashsize = primes[i - 1];
+ hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
+ for (i = 0; i < hashsize; i++)
+ LIST_INIT(&hashtbl[i]);
+ *nentries = hashsize;
+ return (hashtbl);
+}
diff --git a/cpukit/libnetworking/kern/kern_sysctl.c b/cpukit/libnetworking/kern/kern_sysctl.c
new file mode 100644
index 0000000000..6b32c82c6b
--- /dev/null
+++ b/cpukit/libnetworking/kern/kern_sysctl.c
@@ -0,0 +1,1541 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Karels at Berkeley Software Design, Inc.
+ *
+ * Quite extensively rewritten by Poul-Henning Kamp of the FreeBSD
+ * project, to make these variables more userfriendly.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
+ * $FreeBSD: src/sys/kern/kern_sysctl.c,v 1.135 2002/10/27 07:12:34 rwatson Exp $
+ */
+
+#include "opt_compat.h"
+#include "opt_mac.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#ifndef __rtems__
+#include <sys/mac.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sx.h>
+#include <sys/sysproto.h>
+#else
+#include <sys/buf.h>
+
+#include <stdio.h> /* for snprintf() */
+size_t strlcpy(char *, const char *, size_t);
+#endif
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+
+#ifndef __rtems__
+static MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl internal magic");
+static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids");
+static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer");
+#else
+/*
+ * Currently these mean nothing on RTEMS.
+ */
+#define M_SYSCTLOID 1
+#define M_SYSCTLTMP 2
+#define M_ZERO 0
+
+#define mtx_lock(l)
+#define mtx_unlock(l)
+
+#endif
+
+#ifndef __rtems__
+/*
+ * Locking - this locks the sysctl tree in memory.
+ */
+static struct sx sysctllock;
+#endif
+
+#ifdef __rtems__
+#define SYSCTL_LOCK()
+#define SYSCTL_UNLOCK()
+#define SYSCTL_INIT()
+#else
+#define SYSCTL_LOCK() sx_xlock(&sysctllock)
+#define SYSCTL_UNLOCK() sx_xunlock(&sysctllock)
+#define SYSCTL_INIT() sx_init(&sysctllock, "sysctl lock")
+#endif
+
+static int sysctl_root(SYSCTL_HANDLER_ARGS);
+
+struct sysctl_oid_list sysctl__children; /* root list */
+
+static struct sysctl_oid *
+sysctl_find_oidname(const char *name, struct sysctl_oid_list *list)
+{
+ struct sysctl_oid *oidp;
+
+ SLIST_FOREACH(oidp, list, oid_link) {
+ if (strcmp(oidp->oid_name, name) == 0) {
+ return (oidp);
+ }
+ }
+ return (NULL);
+}
+
+/*
+ * Initialization of the MIB tree.
+ *
+ * Order by number in each list.
+ */
+
+void
+sysctl_register_oid(struct sysctl_oid *oidp)
+{
+ struct sysctl_oid_list *parent = oidp->oid_parent;
+ struct sysctl_oid *p;
+ struct sysctl_oid *q;
+
+ /*
+ * First check if another oid with the same name already
+ * exists in the parent's list.
+ */
+ p = sysctl_find_oidname(oidp->oid_name, parent);
+ if (p != NULL) {
+ if ((p->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
+ p->oid_refcnt++;
+ return;
+ } else {
+ printf("can't re-use a leaf (%s)!\n", p->oid_name);
+ return;
+ }
+ }
+ /*
+ * If this oid has a number OID_AUTO, give it a number which
+ * is greater than any current oid.
+ * NOTE: DO NOT change the starting value here, change it in
+ * <sys/sysctl.h>, and make sure it is at least 256 to
+ * accomodate e.g. net.inet.raw as a static sysctl node.
+ */
+ if (oidp->oid_number == OID_AUTO) {
+ static int newoid = CTL_AUTO_START;
+
+ oidp->oid_number = newoid++;
+ if (newoid == 0x7fffffff)
+ panic("out of oids");
+ }
+#if 0
+ else if (oidp->oid_number >= CTL_AUTO_START) {
+ /* do not panic; this happens when unregistering sysctl sets */
+ printf("static sysctl oid too high: %d", oidp->oid_number);
+ }
+#endif
+
+ /*
+ * Insert the oid into the parent's list in order.
+ */
+ q = NULL;
+ SLIST_FOREACH(p, parent, oid_link) {
+ if (oidp->oid_number < p->oid_number)
+ break;
+ q = p;
+ }
+ if (q)
+ SLIST_INSERT_AFTER(q, oidp, oid_link);
+ else
+ SLIST_INSERT_HEAD(parent, oidp, oid_link);
+}
+
+void
+sysctl_unregister_oid(struct sysctl_oid *oidp)
+{
+ SLIST_REMOVE(oidp->oid_parent, oidp, sysctl_oid, oid_link);
+}
+
+/* Initialize a new context to keep track of dynamically added sysctls. */
+int
+sysctl_ctx_init(struct sysctl_ctx_list *c)
+{
+
+ if (c == NULL) {
+ return (EINVAL);
+ }
+ TAILQ_INIT(c);
+ return (0);
+}
+
+/* Free the context, and destroy all dynamic oids registered in this context */
+int
+sysctl_ctx_free(struct sysctl_ctx_list *clist)
+{
+ struct sysctl_ctx_entry *e, *e1;
+ int error;
+
+ error = 0;
+ /*
+ * First perform a "dry run" to check if it's ok to remove oids.
+ * XXX FIXME
+ * XXX This algorithm is a hack. But I don't know any
+ * XXX better solution for now...
+ */
+ TAILQ_FOREACH(e, clist, link) {
+ error = sysctl_remove_oid(e->entry, 0, 0);
+ if (error)
+ break;
+ }
+ /*
+ * Restore deregistered entries, either from the end,
+ * or from the place where error occured.
+ * e contains the entry that was not unregistered
+ */
+ if (error)
+ e1 = TAILQ_PREV(e, sysctl_ctx_list, link);
+ else
+ e1 = TAILQ_LAST(clist, sysctl_ctx_list);
+ while (e1 != NULL) {
+ sysctl_register_oid(e1->entry);
+ e1 = TAILQ_PREV(e1, sysctl_ctx_list, link);
+ }
+ if (error)
+ return(EBUSY);
+ /* Now really delete the entries */
+ e = TAILQ_FIRST(clist);
+ while (e != NULL) {
+ e1 = TAILQ_NEXT(e, link);
+ error = sysctl_remove_oid(e->entry, 1, 0);
+ if (error)
+ panic("sysctl_remove_oid: corrupt tree, entry: %s",
+ e->entry->oid_name);
+ free(e, M_SYSCTLOID);
+ e = e1;
+ }
+ return (error);
+}
+
+/* Add an entry to the context */
+struct sysctl_ctx_entry *
+sysctl_ctx_entry_add(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
+{
+ struct sysctl_ctx_entry *e;
+
+ if (clist == NULL || oidp == NULL)
+ return(NULL);
+ e = malloc(sizeof(struct sysctl_ctx_entry), M_SYSCTLOID, M_WAITOK);
+ e->entry = oidp;
+ TAILQ_INSERT_HEAD(clist, e, link);
+ return (e);
+}
+
+/* Find an entry in the context */
+struct sysctl_ctx_entry *
+sysctl_ctx_entry_find(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
+{
+ struct sysctl_ctx_entry *e;
+
+ if (clist == NULL || oidp == NULL)
+ return(NULL);
+ TAILQ_FOREACH(e, clist, link) {
+ if(e->entry == oidp)
+ return(e);
+ }
+ return (e);
+}
+
+/*
+ * Delete an entry from the context.
+ * NOTE: this function doesn't free oidp! You have to remove it
+ * with sysctl_remove_oid().
+ */
+int
+sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
+{
+ struct sysctl_ctx_entry *e;
+
+ if (clist == NULL || oidp == NULL)
+ return (EINVAL);
+ e = sysctl_ctx_entry_find(clist, oidp);
+ if (e != NULL) {
+ TAILQ_REMOVE(clist, e, link);
+ free(e, M_SYSCTLOID);
+ return (0);
+ } else
+ return (ENOENT);
+}
+
+/*
+ * Remove dynamically created sysctl trees.
+ * oidp - top of the tree to be removed
+ * del - if 0 - just deregister, otherwise free up entries as well
+ * recurse - if != 0 traverse the subtree to be deleted
+ */
+int
+sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse)
+{
+ struct sysctl_oid *p;
+ int error;
+
+ if (oidp == NULL)
+ return(EINVAL);
+ if ((oidp->oid_kind & CTLFLAG_DYN) == 0) {
+ printf("can't remove non-dynamic nodes!\n");
+ return (EINVAL);
+ }
+ /*
+ * WARNING: normal method to do this should be through
+ * sysctl_ctx_free(). Use recursing as the last resort
+ * method to purge your sysctl tree of leftovers...
+ * However, if some other code still references these nodes,
+ * it will panic.
+ */
+ if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
+ if (oidp->oid_refcnt == 1) {
+ SLIST_FOREACH(p, SYSCTL_CHILDREN(oidp), oid_link) {
+ if (!recurse)
+ return (ENOTEMPTY);
+ error = sysctl_remove_oid(p, del, recurse);
+ if (error)
+ return (error);
+ }
+ if (del)
+ free(SYSCTL_CHILDREN(oidp), M_SYSCTLOID);
+ }
+ }
+ if (oidp->oid_refcnt > 1 ) {
+ oidp->oid_refcnt--;
+ } else {
+ if (oidp->oid_refcnt == 0) {
+ printf("Warning: bad oid_refcnt=%u (%s)!\n",
+ oidp->oid_refcnt, oidp->oid_name);
+ return (EINVAL);
+ }
+ sysctl_unregister_oid(oidp);
+ if (del) {
+ if (oidp->descr)
+ free((void *)(uintptr_t)(const void *)oidp->descr, M_SYSCTLOID);
+ free((void *)(uintptr_t)(const void *)oidp->oid_name,
+ M_SYSCTLOID);
+ free(oidp, M_SYSCTLOID);
+ }
+ }
+ return (0);
+}
+
+/*
+ * Create new sysctls at run time.
+ * clist may point to a valid context initialized with sysctl_ctx_init().
+ */
+struct sysctl_oid *
+sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent,
+ int number, const char *name, int kind, void *arg1, int arg2,
+ int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, const char *descr)
+{
+ struct sysctl_oid *oidp;
+ ssize_t len;
+ char *newname;
+
+ /* You have to hook up somewhere.. */
+ if (parent == NULL)
+ return(NULL);
+ /* Check if the node already exists, otherwise create it */
+ oidp = sysctl_find_oidname(name, parent);
+ if (oidp != NULL) {
+ if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
+ oidp->oid_refcnt++;
+ /* Update the context */
+ if (clist != NULL)
+ sysctl_ctx_entry_add(clist, oidp);
+ return (oidp);
+ } else {
+ printf("can't re-use a leaf (%s)!\n", name);
+ return (NULL);
+ }
+ }
+ oidp = malloc(sizeof(struct sysctl_oid), M_SYSCTLOID, M_WAITOK|M_ZERO);
+ oidp->oid_parent = parent;
+ SLIST_NEXT(oidp, oid_link) = NULL;
+ oidp->oid_number = number;
+ oidp->oid_refcnt = 1;
+ len = strlen(name);
+ newname = malloc(len + 1, M_SYSCTLOID, M_WAITOK);
+ bcopy(name, newname, len + 1);
+ newname[len] = '\0';
+ oidp->oid_name = newname;
+ oidp->oid_handler = handler;
+ oidp->oid_kind = CTLFLAG_DYN | kind;
+ if ((kind & CTLTYPE) == CTLTYPE_NODE) {
+ /* Allocate space for children */
+ SYSCTL_CHILDREN_SET(oidp, malloc(sizeof(struct sysctl_oid_list),
+ M_SYSCTLOID, M_WAITOK));
+ SLIST_INIT(SYSCTL_CHILDREN(oidp));
+ } else {
+ oidp->oid_arg1 = arg1;
+ oidp->oid_arg2 = arg2;
+ }
+ oidp->oid_fmt = fmt;
+ if (descr) {
+ int len = strlen(descr) + 1;
+ oidp->descr = malloc(len, M_SYSCTLOID, M_WAITOK);
+ if (oidp->descr)
+ strcpy((char *)(uintptr_t)(const void *)oidp->descr, descr);
+ }
+ /* Update the context, if used */
+ if (clist != NULL)
+ sysctl_ctx_entry_add(clist, oidp);
+ /* Register this oid */
+ sysctl_register_oid(oidp);
+ return (oidp);
+}
+
+/*
+ * Register the kernel's oids on startup.
+ */
+SET_DECLARE(sysctl_set, struct sysctl_oid);
+
+#if defined(__rtems__)
+void
+#else
+static void
+#endif
+sysctl_register_all(void *arg)
+{
+ struct sysctl_oid **oidp;
+
+ SYSCTL_INIT();
+ SET_FOREACH(oidp, sysctl_set)
+ sysctl_register_oid(*oidp);
+}
+SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_all, 0);
+
+/*
+ * "Staff-functions"
+ *
+ * These functions implement a presently undocumented interface
+ * used by the sysctl program to walk the tree, and get the type
+ * so it can print the value.
+ * This interface is under work and consideration, and should probably
+ * be killed with a big axe by the first person who can find the time.
+ * (be aware though, that the proper interface isn't as obvious as it
+ * may seem, there are various conflicting requirements.
+ *
+ * {0,0} printf the entire MIB-tree.
+ * {0,1,...} return the name of the "..." OID.
+ * {0,2,...} return the next OID.
+ * {0,3} return the OID of the name in "new"
+ * {0,4,...} return the kind & format info for the "..." OID.
+ * {0,5,...} return the description the "..." OID.
+ */
+
+static void
+sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i)
+{
+ int k;
+ struct sysctl_oid *oidp;
+
+ SLIST_FOREACH(oidp, l, oid_link) {
+
+ for (k=0; k<i; k++)
+ printf(" ");
+
+ printf("%d %s ", oidp->oid_number, oidp->oid_name);
+
+ printf("%c%c",
+ oidp->oid_kind & CTLFLAG_RD ? 'R':' ',
+ oidp->oid_kind & CTLFLAG_WR ? 'W':' ');
+
+ if (oidp->oid_handler)
+ printf(" *Handler");
+
+ switch (oidp->oid_kind & CTLTYPE) {
+ case CTLTYPE_NODE:
+ printf(" Node\n");
+ if (!oidp->oid_handler) {
+ sysctl_sysctl_debug_dump_node(
+ oidp->oid_arg1, i+2);
+ }
+ break;
+ case CTLTYPE_INT: printf(" Int\n"); break;
+ case CTLTYPE_STRING: printf(" String\n"); break;
+ case CTLTYPE_QUAD: printf(" Quad\n"); break;
+ case CTLTYPE_OPAQUE: printf(" Opaque/struct\n"); break;
+ default: printf("\n");
+ }
+
+ }
+}
+
+static int
+sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS)
+{
+#ifndef __rtems__
+ int error;
+
+ error = suser(req->td);
+ if (error)
+ return error;
+#endif
+ sysctl_sysctl_debug_dump_node(&sysctl__children, 0);
+ return ENOENT;
+}
+
+SYSCTL_PROC(_sysctl, 0, debug, CTLTYPE_STRING|CTLFLAG_RD,
+ 0, 0, sysctl_sysctl_debug, "-", "");
+
+static int
+sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
+{
+ int *name = (int *) arg1;
+ u_int namelen = arg2;
+ int error = 0;
+ struct sysctl_oid *oid;
+ struct sysctl_oid_list *lsp = &sysctl__children, *lsp2;
+ char buf[10];
+
+ while (namelen) {
+ if (!lsp) {
+ snprintf(buf,sizeof(buf),"%d",*name);
+ if (req->oldidx)
+ error = SYSCTL_OUT(req, ".", 1);
+ if (!error)
+ error = SYSCTL_OUT(req, buf, strlen(buf));
+ if (error)
+ return (error);
+ namelen--;
+ name++;
+ continue;
+ }
+ lsp2 = 0;
+ SLIST_FOREACH(oid, lsp, oid_link) {
+ if (oid->oid_number != *name)
+ continue;
+
+ if (req->oldidx)
+ error = SYSCTL_OUT(req, ".", 1);
+ if (!error)
+ error = SYSCTL_OUT(req, oid->oid_name,
+ strlen(oid->oid_name));
+ if (error)
+ return (error);
+
+ namelen--;
+ name++;
+
+ if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE)
+ break;
+
+ if (oid->oid_handler)
+ break;
+
+ lsp2 = (struct sysctl_oid_list *)oid->oid_arg1;
+ break;
+ }
+ lsp = lsp2;
+ }
+ return (SYSCTL_OUT(req, "", 1));
+}
+
+SYSCTL_NODE(_sysctl, 1, name, CTLFLAG_RD, sysctl_sysctl_name, "");
+
+static int
+sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen,
+ int *next, int *len, int level, struct sysctl_oid **oidpp)
+{
+ struct sysctl_oid *oidp;
+
+ *len = level;
+ SLIST_FOREACH(oidp, lsp, oid_link) {
+ *next = oidp->oid_number;
+ *oidpp = oidp;
+
+ if (oidp->oid_kind & CTLFLAG_SKIP)
+ continue;
+
+ if (!namelen) {
+ if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
+ return 0;
+ if (oidp->oid_handler)
+ /* We really should call the handler here...*/
+ return 0;
+ lsp = (struct sysctl_oid_list *)oidp->oid_arg1;
+ if (!sysctl_sysctl_next_ls(lsp, 0, 0, next+1,
+ len, level+1, oidpp))
+ return 0;
+ goto emptynode;
+ }
+
+ if (oidp->oid_number < *name)
+ continue;
+
+ if (oidp->oid_number > *name) {
+ if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
+ return 0;
+ if (oidp->oid_handler)
+ return 0;
+ lsp = (struct sysctl_oid_list *)oidp->oid_arg1;
+ if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1,
+ next+1, len, level+1, oidpp))
+ return (0);
+ goto next;
+ }
+ if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
+ continue;
+
+ if (oidp->oid_handler)
+ continue;
+
+ lsp = (struct sysctl_oid_list *)oidp->oid_arg1;
+ if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, next+1,
+ len, level+1, oidpp))
+ return (0);
+ next:
+ namelen = 1;
+ emptynode:
+ *len = level;
+ }
+ return 1;
+}
+
+static int
+sysctl_sysctl_next(SYSCTL_HANDLER_ARGS)
+{
+ int *name = (int *) arg1;
+ u_int namelen = arg2;
+ int i, j, error;
+ struct sysctl_oid *oid;
+ struct sysctl_oid_list *lsp = &sysctl__children;
+ int newoid[CTL_MAXNAME];
+
+ i = sysctl_sysctl_next_ls(lsp, name, namelen, newoid, &j, 1, &oid);
+ if (i)
+ return ENOENT;
+ error = SYSCTL_OUT(req, newoid, j * sizeof (int));
+ return (error);
+}
+
+SYSCTL_NODE(_sysctl, 2, next, CTLFLAG_RD, sysctl_sysctl_next, "");
+
+static int
+name2oid (char *name, int *oid, int *len, struct sysctl_oid **oidpp)
+{
+ int i;
+ struct sysctl_oid *oidp;
+ struct sysctl_oid_list *lsp = &sysctl__children;
+ char *p;
+
+ if (!*name)
+ return ENOENT;
+
+ p = name + strlen(name) - 1 ;
+ if (*p == '.')
+ *p = '\0';
+
+ *len = 0;
+
+ for (p = name; *p && *p != '.'; p++)
+ ;
+ i = *p;
+ if (i == '.')
+ *p = '\0';
+
+ oidp = SLIST_FIRST(lsp);
+
+ while (oidp && *len < CTL_MAXNAME) {
+ if (strcmp(name, oidp->oid_name)) {
+ oidp = SLIST_NEXT(oidp, oid_link);
+ continue;
+ }
+ *oid++ = oidp->oid_number;
+ (*len)++;
+
+ if (!i) {
+ if (oidpp)
+ *oidpp = oidp;
+ return (0);
+ }
+
+ if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
+ break;
+
+ if (oidp->oid_handler)
+ break;
+
+ lsp = (struct sysctl_oid_list *)oidp->oid_arg1;
+ oidp = SLIST_FIRST(lsp);
+ name = p+1;
+ for (p = name; *p && *p != '.'; p++)
+ ;
+ i = *p;
+ if (i == '.')
+ *p = '\0';
+ }
+ return ENOENT;
+}
+
+static int
+sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
+{
+ char *p;
+ int error, oid[CTL_MAXNAME], len;
+ struct sysctl_oid *op = 0;
+
+ if (!req->newlen)
+ return ENOENT;
+ if (req->newlen >= MAXPATHLEN) /* XXX arbitrary, undocumented */
+ return (ENAMETOOLONG);
+
+ p = malloc(req->newlen+1, M_SYSCTL, M_WAITOK);
+
+ error = SYSCTL_IN(req, p, req->newlen);
+ if (error) {
+ free(p, M_SYSCTL);
+ return (error);
+ }
+
+ p [req->newlen] = '\0';
+
+ error = name2oid(p, oid, &len, &op);
+
+ free(p, M_SYSCTL);
+
+ if (error)
+ return (error);
+
+ error = SYSCTL_OUT(req, oid, len * sizeof *oid);
+ return (error);
+}
+
+SYSCTL_PROC(_sysctl, 3, name2oid, CTLFLAG_RW|CTLFLAG_ANYBODY, 0, 0,
+ sysctl_sysctl_name2oid, "I", "");
+
+static int
+sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
+{
+ struct sysctl_oid *oid;
+ int error;
+
+ error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
+ if (error)
+ return (error);
+
+ if (!oid->oid_fmt)
+ return (ENOENT);
+ error = SYSCTL_OUT(req, &oid->oid_kind, sizeof(oid->oid_kind));
+ if (error)
+ return (error);
+ error = SYSCTL_OUT(req, oid->oid_fmt, strlen(oid->oid_fmt) + 1);
+ return (error);
+}
+
+
+SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD, sysctl_sysctl_oidfmt, "");
+
+static int
+sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
+{
+ struct sysctl_oid *oid;
+ int error;
+
+ error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
+ if (error)
+ return (error);
+
+ if (!oid->descr)
+ return (ENOENT);
+ error = SYSCTL_OUT(req, oid->descr, strlen(oid->descr) + 1);
+ return (error);
+}
+
+SYSCTL_NODE(_sysctl, 5, oiddescr, CTLFLAG_RD, sysctl_sysctl_oiddescr, "");
+
+/*
+ * Default "handler" functions.
+ */
+
+/*
+ * Handle an int, signed or unsigned.
+ * Two cases:
+ * a variable: point arg1 at it.
+ * a constant: pass it in arg2.
+ */
+
+int
+sysctl_handle_int(SYSCTL_HANDLER_ARGS)
+{
+ int tmpout, error = 0;
+
+ /*
+ * Attempt to get a coherent snapshot by making a copy of the data.
+ */
+ if (arg1)
+ tmpout = *(int *)arg1;
+ else
+ tmpout = arg2;
+ error = SYSCTL_OUT(req, &tmpout, sizeof(int));
+
+ if (error || !req->newptr)
+ return (error);
+
+ if (!arg1)
+ error = EPERM;
+ else
+ error = SYSCTL_IN(req, arg1, sizeof(int));
+ return (error);
+}
+
+/*
+ * Handle a long, signed or unsigned. arg1 points to it.
+ */
+
+int
+sysctl_handle_long(SYSCTL_HANDLER_ARGS)
+{
+ int error = 0;
+ long tmpout;
+
+ /*
+ * Attempt to get a coherent snapshot by making a copy of the data.
+ */
+ if (!arg1)
+ return (EINVAL);
+ tmpout = *(long *)arg1;
+ error = SYSCTL_OUT(req, &tmpout, sizeof(long));
+
+ if (error || !req->newptr)
+ return (error);
+
+ error = SYSCTL_IN(req, arg1, sizeof(long));
+ return (error);
+}
+
+/*
+ * Handle our generic '\0' terminated 'C' string.
+ * Two cases:
+ * a variable string: point arg1 at it, arg2 is max length.
+ * a constant string: point arg1 at it, arg2 is zero.
+ */
+
+int
+sysctl_handle_string(SYSCTL_HANDLER_ARGS)
+{
+ int error=0;
+ char *tmparg;
+ size_t outlen;
+
+ /*
+ * Attempt to get a coherent snapshot by copying to a
+ * temporary kernel buffer.
+ */
+retry:
+ outlen = strlen((char *)arg1)+1;
+ tmparg = malloc(outlen, M_SYSCTLTMP, M_WAITOK);
+
+ if (strlcpy(tmparg, (char *)arg1, outlen) >= outlen) {
+ free(tmparg, M_SYSCTLTMP);
+ goto retry;
+ }
+
+ error = SYSCTL_OUT(req, tmparg, outlen);
+ free(tmparg, M_SYSCTLTMP);
+
+ if (error || !req->newptr)
+ return (error);
+
+ if ((req->newlen - req->newidx) >= arg2) {
+ error = EINVAL;
+ } else {
+ arg2 = (req->newlen - req->newidx);
+ error = SYSCTL_IN(req, arg1, arg2);
+ ((char *)arg1)[arg2] = '\0';
+ }
+
+ return (error);
+}
+
+/*
+ * Handle any kind of opaque data.
+ * arg1 points to it, arg2 is the size.
+ */
+
+int
+sysctl_handle_opaque(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ void *tmparg;
+
+ /*
+ * Attempt to get a coherent snapshot, either by wiring the
+ * user space buffer or copying to a temporary kernel buffer
+ * depending on the size of the data.
+ */
+ if (arg2 > PAGE_SIZE) {
+ sysctl_wire_old_buffer(req, arg2);
+ error = SYSCTL_OUT(req, arg1, arg2);
+ } else {
+ tmparg = malloc(arg2, M_SYSCTLTMP, M_WAITOK);
+ bcopy(arg1, tmparg, arg2);
+ error = SYSCTL_OUT(req, tmparg, arg2);
+ free(tmparg, M_SYSCTLTMP);
+ }
+
+ if (error || !req->newptr)
+ return (error);
+
+ error = SYSCTL_IN(req, arg1, arg2);
+
+ return (error);
+}
+
+/*
+ * Transfer functions to/from kernel space.
+ * XXX: rather untested at this point
+ */
+static int
+sysctl_old_kernel(struct sysctl_req *req, const void *p, size_t l)
+{
+ size_t i = 0;
+
+ if (req->oldptr) {
+ i = l;
+ if (req->oldlen <= req->oldidx)
+ i = 0;
+ else
+ if (i > req->oldlen - req->oldidx)
+ i = req->oldlen - req->oldidx;
+ if (i > 0)
+ bcopy(p, (char *)req->oldptr + req->oldidx, i);
+ }
+ req->oldidx += l;
+ if (req->oldptr && i != l)
+ return (ENOMEM);
+ return (0);
+}
+
+static int
+sysctl_new_kernel(struct sysctl_req *req, void *p, size_t l)
+{
+ if (!req->newptr)
+ return 0;
+ if (req->newlen - req->newidx < l)
+ return (EINVAL);
+ bcopy((char *)req->newptr + req->newidx, p, l);
+ req->newidx += l;
+ return (0);
+}
+
+int
+kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
+ size_t *oldlenp, void *new, size_t newlen, size_t *retval)
+{
+ int error = 0;
+ struct sysctl_req req;
+
+ bzero(&req, sizeof req);
+
+ req.td = td;
+
+ if (oldlenp) {
+ req.oldlen = *oldlenp;
+ }
+
+ if (old) {
+ req.oldptr= old;
+ }
+
+ if (new != NULL) {
+ req.newlen = newlen;
+ req.newptr = new;
+ }
+
+ req.oldfunc = sysctl_old_kernel;
+ req.newfunc = sysctl_new_kernel;
+ req.lock = REQ_LOCKED;
+
+ SYSCTL_LOCK();
+
+ error = sysctl_root(0, name, namelen, &req);
+
+ if (req.lock == REQ_WIRED)
+#ifdef __rtems__
+ printf ("kern_sysctl: vsunlock needs to be called!\n");
+#else
+ vsunlock(req.oldptr, req.oldlen);
+#endif
+
+ SYSCTL_UNLOCK();
+
+ if (error && error != ENOMEM)
+ return (error);
+
+ if (retval) {
+ if (req.oldptr && req.oldidx > req.oldlen)
+ *retval = req.oldlen;
+ else
+ *retval = req.oldidx;
+ }
+ return (error);
+}
+
+int
+kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp,
+ void *new, size_t newlen, size_t *retval)
+{
+ int oid[CTL_MAXNAME];
+ size_t oidlen, plen;
+ int error;
+
+ plen = 0; /* RTEMS - to avoid warnings */
+
+ oid[0] = 0; /* sysctl internal magic */
+ oid[1] = 3; /* name2oid */
+ oidlen = sizeof(oid);
+
+ error = kernel_sysctl(td, oid, 2, oid, &oidlen,
+ (void *)name, strlen(name), &plen);
+ if (error)
+ return (error);
+
+ error = kernel_sysctl(td, oid, plen / sizeof(int), old, oldlenp,
+ new, newlen, retval);
+ return (error);
+}
+
+/*
+ * Transfer function to/from user space.
+ */
+static int
+sysctl_old_user(struct sysctl_req *req, const void *p, size_t l)
+{
+ int error = 0;
+ size_t i = 0;
+
+#ifndef __rtems__
+ if (req->lock == 1 && req->oldptr)
+ WITNESS_SLEEP(1, NULL);
+#endif
+ if (req->oldptr) {
+ i = l;
+ if (req->oldlen <= req->oldidx)
+ i = 0;
+ else
+ if (i > req->oldlen - req->oldidx)
+ i = req->oldlen - req->oldidx;
+ if (i > 0)
+ error = copyout(p, (char *)req->oldptr + req->oldidx,
+ i);
+ }
+ req->oldidx += l;
+ if (error)
+ return (error);
+ if (req->oldptr && i < l)
+ return (ENOMEM);
+ return (0);
+}
+
+static int
+sysctl_new_user(struct sysctl_req *req, void *p, size_t l)
+{
+ int error;
+
+ if (!req->newptr)
+ return 0;
+ if (req->newlen - req->newidx < l)
+ return (EINVAL);
+ error = copyin((char *)req->newptr + req->newidx, p, l);
+ req->newidx += l;
+ return (error);
+}
+
+/*
+ * Wire the user space destination buffer. If set to a value greater than
+ * zero, the len parameter limits the maximum amount of wired memory.
+ *
+ * XXX - The len parameter is currently ignored due to the lack of
+ * a place to save it in the sysctl_req structure so that the matching
+ * amount of memory can be unwired in the sysctl exit code.
+ */
+int
+sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
+{
+ if (req->lock == REQ_LOCKED && req->oldptr &&
+ req->oldfunc == sysctl_old_user) {
+#ifndef __rtems__
+ vslock(req->oldptr, req->oldlen);
+#endif
+ req->lock = REQ_WIRED;
+ }
+ return (0);
+}
+
+int
+sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
+ int *nindx, struct sysctl_req *req)
+{
+ struct sysctl_oid *oid;
+ int indx;
+
+ oid = SLIST_FIRST(&sysctl__children);
+ indx = 0;
+ while (oid && indx < CTL_MAXNAME) {
+ if (oid->oid_number == name[indx]) {
+ indx++;
+ if (oid->oid_kind & CTLFLAG_NOLOCK)
+ req->lock = REQ_UNLOCKED;
+ if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
+ if (oid->oid_handler != NULL ||
+ indx == namelen) {
+ *noid = oid;
+ if (nindx != NULL)
+ *nindx = indx;
+ return (0);
+ }
+ oid = SLIST_FIRST(
+ (struct sysctl_oid_list *)oid->oid_arg1);
+ } else if (indx == namelen) {
+ *noid = oid;
+ if (nindx != NULL)
+ *nindx = indx;
+ return (0);
+ } else {
+ return (ENOTDIR);
+ }
+ } else {
+ oid = SLIST_NEXT(oid, oid_link);
+ }
+ }
+ return (ENOENT);
+}
+
+/*
+ * Traverse our tree, and find the right node, execute whatever it points
+ * to, and return the resulting error code.
+ */
+
+static int
+sysctl_root(SYSCTL_HANDLER_ARGS)
+{
+ struct sysctl_oid *oid;
+ int error, indx;
+
+ error = sysctl_find_oid(arg1, arg2, &oid, &indx, req);
+ if (error)
+ return (error);
+
+ if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
+ /*
+ * You can't call a sysctl when it's a node, but has
+ * no handler. Inform the user that it's a node.
+ * The indx may or may not be the same as namelen.
+ */
+ if (oid->oid_handler == NULL)
+ return (EISDIR);
+ }
+
+ /* Is this sysctl writable? */
+ if (req->newptr && !(oid->oid_kind & CTLFLAG_WR))
+ return (EPERM);
+
+#ifndef __rtems__
+ KASSERT(req->td != NULL, ("sysctl_root(): req->td == NULL"));
+
+ /* Is this sysctl sensitive to securelevels? */
+ if (req->newptr && (oid->oid_kind & CTLFLAG_SECURE)) {
+ error = securelevel_gt(req->td->td_ucred, 0);
+ if (error)
+ return (error);
+ }
+
+ /* Is this sysctl writable by only privileged users? */
+ if (req->newptr && !(oid->oid_kind & CTLFLAG_ANYBODY)) {
+ int flags;
+
+ if (oid->oid_kind & CTLFLAG_PRISON)
+ flags = PRISON_ROOT;
+ else
+ flags = 0;
+ error = suser_cred(req->td->td_ucred, flags);
+ if (error)
+ return (error);
+ }
+#endif
+
+ if (!oid->oid_handler)
+ return EINVAL;
+
+ if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE)
+ error = oid->oid_handler(oid, (int *)arg1 + indx, arg2 - indx,
+ req);
+ else
+ error = oid->oid_handler(oid, oid->oid_arg1, oid->oid_arg2,
+ req);
+ return (error);
+}
+
+#ifndef _SYS_SYSPROTO_H_
+struct sysctl_args {
+ int *name;
+ u_int namelen;
+ void *old;
+ size_t *oldlenp;
+ void *new;
+ size_t newlen;
+};
+#endif
+
+/*
+ * MPSAFE
+ */
+int
+__sysctl(struct thread *td, struct sysctl_args *uap)
+{
+ int error, name[CTL_MAXNAME];
+ size_t j;
+
+ if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
+ return (EINVAL);
+
+ error = copyin(uap->name, &name, uap->namelen * sizeof(int));
+ if (error)
+ return (error);
+
+ mtx_lock(&Giant);
+
+ error = userland_sysctl(td, name, uap->namelen,
+ uap->old, uap->oldlenp, 0,
+ uap->new, uap->newlen, &j);
+ if (error && error != ENOMEM)
+ goto done2;
+ if (uap->oldlenp) {
+ int i = copyout(&j, uap->oldlenp, sizeof(j));
+ if (i)
+ error = i;
+ }
+done2:
+ mtx_unlock(&Giant);
+ return (error);
+}
+
+/*
+ * This is used from various compatibility syscalls too. That's why name
+ * must be in kernel space.
+ */
+int
+userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
+ size_t *oldlenp, int inkernel, void *new, size_t newlen, size_t *retval)
+{
+ int error = 0;
+ struct sysctl_req req, req2;
+
+ bzero(&req, sizeof req);
+
+ req.td = td;
+
+ if (oldlenp) {
+ if (inkernel) {
+ req.oldlen = *oldlenp;
+ } else {
+ error = copyin(oldlenp, &req.oldlen, sizeof(*oldlenp));
+ if (error)
+ return (error);
+ }
+ }
+
+ if (old) {
+#ifndef __rtems__
+ if (!useracc(old, req.oldlen, VM_PROT_WRITE))
+ return (EFAULT);
+#endif
+ req.oldptr= old;
+ }
+
+ if (new != NULL) {
+#ifndef __rtems__
+ if (!useracc(new, req.newlen, VM_PROT_READ))
+ return (EFAULT);
+#endif
+ req.newlen = newlen;
+ req.newptr = new;
+ }
+
+ req.oldfunc = sysctl_old_user;
+ req.newfunc = sysctl_new_user;
+ req.lock = REQ_LOCKED;
+
+ SYSCTL_LOCK();
+
+#ifdef MAC
+ error = mac_check_system_sysctl(td->td_ucred, name, namelen, old,
+ oldlenp, inkernel, new, newlen);
+ if (error) {
+ SYSCTL_UNLOCK();
+ return (error);
+ }
+#endif
+
+ do {
+ req2 = req;
+ error = sysctl_root(0, name, namelen, &req2);
+ } while (error == EAGAIN);
+
+ req = req2;
+#ifndef __rtems__
+ if (req.lock == REQ_WIRED)
+ vsunlock(req.oldptr, req.oldlen);
+#endif
+
+ SYSCTL_UNLOCK();
+
+ if (error && error != ENOMEM)
+ return (error);
+
+ if (retval) {
+ if (req.oldptr && req.oldidx > req.oldlen)
+ *retval = req.oldlen;
+ else
+ *retval = req.oldidx;
+ }
+ return (error);
+}
+
+#ifdef COMPAT_43
+#include <sys/socket.h>
+#include <vm/vm_param.h>
+
+#define KINFO_PROC (0<<8)
+#define KINFO_RT (1<<8)
+#define KINFO_VNODE (2<<8)
+#define KINFO_FILE (3<<8)
+#define KINFO_METER (4<<8)
+#define KINFO_LOADAVG (5<<8)
+#define KINFO_CLOCKRATE (6<<8)
+
+/* Non-standard BSDI extension - only present on their 4.3 net-2 releases */
+#define KINFO_BSDI_SYSINFO (101<<8)
+
+/*
+ * XXX this is bloat, but I hope it's better here than on the potentially
+ * limited kernel stack... -Peter
+ */
+
+static struct {
+ int bsdi_machine; /* "i386" on BSD/386 */
+/* ^^^ this is an offset to the string, relative to the struct start */
+ char *pad0;
+ long pad1;
+ long pad2;
+ long pad3;
+ u_long pad4;
+ u_long pad5;
+ u_long pad6;
+
+ int bsdi_ostype; /* "BSD/386" on BSD/386 */
+ int bsdi_osrelease; /* "1.1" on BSD/386 */
+ long pad7;
+ long pad8;
+ char *pad9;
+
+ long pad10;
+ long pad11;
+ int pad12;
+ long pad13;
+ quad_t pad14;
+ long pad15;
+
+ struct timeval pad16;
+ /* we dont set this, because BSDI's uname used gethostname() instead */
+ int bsdi_hostname; /* hostname on BSD/386 */
+
+ /* the actual string data is appended here */
+
+} bsdi_si;
+/*
+ * this data is appended to the end of the bsdi_si structure during copyout.
+ * The "char *" offsets are relative to the base of the bsdi_si struct.
+ * This contains "FreeBSD\02.0-BUILT-nnnnnn\0i386\0", and these strings
+ * should not exceed the length of the buffer here... (or else!! :-)
+ */
+static char bsdi_strings[80]; /* It had better be less than this! */
+
+#ifndef _SYS_SYSPROTO_H_
+struct getkerninfo_args {
+ int op;
+ char *where;
+ size_t *size;
+ int arg;
+};
+#endif
+
+/*
+ * MPSAFE
+ */
+int
+ogetkerninfo(struct thread *td, struct getkerninfo_args *uap)
+{
+ int error, name[6];
+ size_t size;
+ u_int needed = 0;
+
+ mtx_lock(&Giant);
+
+ switch (uap->op & 0xff00) {
+
+ case KINFO_RT:
+ name[0] = CTL_NET;
+ name[1] = PF_ROUTE;
+ name[2] = 0;
+ name[3] = (uap->op & 0xff0000) >> 16;
+ name[4] = uap->op & 0xff;
+ name[5] = uap->arg;
+ error = userland_sysctl(td, name, 6, uap->where, uap->size,
+ 0, 0, 0, &size);
+ break;
+
+ case KINFO_VNODE:
+ name[0] = CTL_KERN;
+ name[1] = KERN_VNODE;
+ error = userland_sysctl(td, name, 2, uap->where, uap->size,
+ 0, 0, 0, &size);
+ break;
+
+ case KINFO_PROC:
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC;
+ name[2] = uap->op & 0xff;
+ name[3] = uap->arg;
+ error = userland_sysctl(td, name, 4, uap->where, uap->size,
+ 0, 0, 0, &size);
+ break;
+
+ case KINFO_FILE:
+ name[0] = CTL_KERN;
+ name[1] = KERN_FILE;
+ error = userland_sysctl(td, name, 2, uap->where, uap->size,
+ 0, 0, 0, &size);
+ break;
+
+ case KINFO_METER:
+ name[0] = CTL_VM;
+ name[1] = VM_TOTAL;
+ error = userland_sysctl(td, name, 2, uap->where, uap->size,
+ 0, 0, 0, &size);
+ break;
+
+ case KINFO_LOADAVG:
+ name[0] = CTL_VM;
+ name[1] = VM_LOADAVG;
+ error = userland_sysctl(td, name, 2, uap->where, uap->size,
+ 0, 0, 0, &size);
+ break;
+
+ case KINFO_CLOCKRATE:
+ name[0] = CTL_KERN;
+ name[1] = KERN_CLOCKRATE;
+ error = userland_sysctl(td, name, 2, uap->where, uap->size,
+ 0, 0, 0, &size);
+ break;
+
+ case KINFO_BSDI_SYSINFO: {
+ /*
+ * this is pretty crude, but it's just enough for uname()
+ * from BSDI's 1.x libc to work.
+ *
+ * *size gives the size of the buffer before the call, and
+ * the amount of data copied after a successful call.
+ * If successful, the return value is the amount of data
+ * available, which can be larger than *size.
+ *
+ * BSDI's 2.x product apparently fails with ENOMEM if *size
+ * is too small.
+ */
+
+ u_int left;
+ char *s;
+
+ bzero((char *)&bsdi_si, sizeof(bsdi_si));
+ bzero(bsdi_strings, sizeof(bsdi_strings));
+
+ s = bsdi_strings;
+
+ bsdi_si.bsdi_ostype = (s - bsdi_strings) + sizeof(bsdi_si);
+ strcpy(s, ostype);
+ s += strlen(s) + 1;
+
+ bsdi_si.bsdi_osrelease = (s - bsdi_strings) + sizeof(bsdi_si);
+ strcpy(s, osrelease);
+ s += strlen(s) + 1;
+
+ bsdi_si.bsdi_machine = (s - bsdi_strings) + sizeof(bsdi_si);
+ strcpy(s, machine);
+ s += strlen(s) + 1;
+
+ needed = sizeof(bsdi_si) + (s - bsdi_strings);
+
+ if ((uap->where == NULL) || (uap->size == NULL)) {
+ /* process is asking how much buffer to supply.. */
+ size = needed;
+ error = 0;
+ break;
+ }
+
+ if ((error = copyin(uap->size, &size, sizeof(size))) != 0)
+ break;
+
+ /* if too much buffer supplied, trim it down */
+ if (size > needed)
+ size = needed;
+
+ /* how much of the buffer is remaining */
+ left = size;
+
+ if ((error = copyout((char *)&bsdi_si, uap->where, left)) != 0)
+ break;
+
+ /* is there any point in continuing? */
+ if (left > sizeof(bsdi_si)) {
+ left -= sizeof(bsdi_si);
+ error = copyout(&bsdi_strings,
+ uap->where + sizeof(bsdi_si), left);
+ }
+ break;
+ }
+
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+ if (error == 0) {
+ td->td_retval[0] = needed ? needed : size;
+ if (uap->size) {
+ error = copyout(&size, uap->size, sizeof(size));
+ }
+ }
+ mtx_unlock(&Giant);
+ return (error);
+}
+#endif /* COMPAT_43 */
diff --git a/cpukit/libnetworking/kern/uipc_domain.c b/cpukit/libnetworking/kern/uipc_domain.c
new file mode 100644
index 0000000000..81d741fe37
--- /dev/null
+++ b/cpukit/libnetworking/kern/uipc_domain.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ *
+ * @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/domain.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+/*
+ * System initialization
+ *
+ * Note: domain initialization wants to take place on a per domain basis
+ * as a result of traversing a linker set. Most likely, each domain
+ * want to call a registration function rather than being handled here
+ * in domaininit(). Probably this will look like:
+ *
+ * SYSINIT(unique, SI_SUB_PROTO_DOMAI, SI_ORDER_ANY, domain_add, xxx)
+ *
+ * Where 'xxx' is replaced by the address of a parameter struct to be
+ * passed to the doamin_add() function.
+ */
+
+#if !defined(__rtems__)
+static int x_save_spl; /* used by kludge*/
+static void kludge_splimp __P((void *));
+static void kludge_splx __P((void *));
+ void domaininit __P((void *));
+SYSINIT(splimp, SI_SUB_PROTO_BEGIN, SI_ORDER_FIRST, kludge_splimp, &x_save_spl)
+SYSINIT(domain, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, domaininit, NULL)
+SYSINIT(splx, SI_SUB_PROTO_END, SI_ORDER_FIRST, kludge_splx, &x_save_spl)
+#endif
+
+static void pffasttimo __P((void *));
+static void pfslowtimo __P((void *));
+
+struct domain *domains;
+
+#define ADDDOMAIN(x) { \
+ __CONCAT(x,domain.dom_next) = domains; \
+ domains = &__CONCAT(x,domain); \
+}
+
+extern struct linker_set domain_set;
+
+/* ARGSUSED*/
+void
+domaininit(dummy)
+ void *dummy;
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+
+/* - not in our sources
+#ifdef ISDN
+ ADDDOMAIN(isdn);
+#endif
+*/
+
+ for (dp = domains; dp; dp = dp->dom_next) {
+ if (dp->dom_init)
+ (*dp->dom_init)();
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++){
+#ifdef PRU_OLDSTYLE
+ /* See comments in uipc_socket2.c. */
+ if (pr->pr_usrreqs == 0 && pr->pr_ousrreq)
+ pr->pr_usrreqs = &pru_oldstyle;
+#endif
+ if (pr->pr_init)
+ (*pr->pr_init)();
+ }
+ }
+
+ if (max_linkhdr < 16) /* XXX */
+ max_linkhdr = 16;
+ max_hdr = max_linkhdr + max_protohdr;
+ max_datalen = MHLEN - max_hdr;
+ timeout(pffasttimo, (void *)0, 1);
+ timeout(pfslowtimo, (void *)0, 1);
+}
+
+
+#if !defined(__rtems__)
+/*
+ * The following two operations are kludge code. Most likely, they should
+ * be done as a "domainpreinit()" for the first function and then rolled
+ * in as the last act of "domaininit()" for the second.
+ *
+ * In point of fact, it is questionable why other initialization prior
+ * to this does not also take place at splimp by default.
+ */
+static void
+kludge_splimp(udata)
+ void *udata;
+{
+ int *savesplp = udata;
+
+ *savesplp = splimp();
+}
+
+static void
+kludge_splx(udata)
+ void *udata;
+{
+ int *savesplp = udata;
+
+ splx( *savesplp);
+}
+#endif /* !defined(__rtems__) */
+
+struct protosw *
+pffindtype(int family, int type)
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+
+ for (dp = domains; dp; dp = dp->dom_next)
+ if (dp->dom_family == family)
+ goto found;
+ return (0);
+found:
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_type && pr->pr_type == type)
+ return (pr);
+ return (0);
+}
+
+struct protosw *
+pffindproto(int family, int protocol, int type)
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+ struct protosw *maybe = 0;
+
+ if (family == 0)
+ return (0);
+ for (dp = domains; dp; dp = dp->dom_next)
+ if (dp->dom_family == family)
+ goto found;
+ return (0);
+found:
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
+ if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
+ return (pr);
+
+ if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
+ pr->pr_protocol == 0 && maybe == (struct protosw *)0)
+ maybe = pr;
+ }
+ return (maybe);
+}
+
+void
+pfctlinput(cmd, sa)
+ int cmd;
+ struct sockaddr *sa;
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+
+ for (dp = domains; dp; dp = dp->dom_next)
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_ctlinput)
+ (*pr->pr_ctlinput)(cmd, sa, (void *)0);
+}
+
+static void
+pfslowtimo(arg)
+ void *arg;
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+
+ for (dp = domains; dp; dp = dp->dom_next)
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_slowtimo)
+ (*pr->pr_slowtimo)();
+ timeout(pfslowtimo, (void *)0, hz/2);
+}
+
+static void
+pffasttimo(arg)
+ void *arg;
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+
+ for (dp = domains; dp; dp = dp->dom_next)
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_fasttimo)
+ (*pr->pr_fasttimo)();
+ timeout(pffasttimo, (void *)0, hz/5);
+}
diff --git a/cpukit/libnetworking/kern/uipc_mbuf.c b/cpukit/libnetworking/kern/uipc_mbuf.c
new file mode 100644
index 0000000000..cc01e7201e
--- /dev/null
+++ b/cpukit/libnetworking/kern/uipc_mbuf.c
@@ -0,0 +1,750 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1991, 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.
+ * 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.
+ *
+ * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/malloc.h>
+#define MBTYPES
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/syslog.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_extern.h>
+
+#if !defined(__rtems__)
+static void mbinit __P((void *)) __attribute__ ((unused));
+SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbinit, NULL)
+#endif
+
+struct mbuf *mbutl;
+char *mclrefcnt;
+struct mbstat mbstat;
+struct mbuf *mmbfree;
+union mcluster *mclfree;
+int max_linkhdr;
+int max_protohdr;
+int max_hdr;
+int max_datalen;
+
+/* "number of clusters of pages" */
+#define NCL_INIT 1
+
+#define NMB_INIT 16
+
+/*
+ * When MGET failes, ask protocols to free space when short of memory,
+ * then re-attempt to allocate an mbuf.
+ */
+struct mbuf *
+m_retry(i, t)
+ int i, t;
+{
+ register struct mbuf *m;
+
+ m_reclaim();
+#define m_retry(i, t) (struct mbuf *)0
+ MGET(m, i, t);
+#undef m_retry
+ if (m != NULL)
+ mbstat.m_wait++;
+ else
+ mbstat.m_drops++;
+ return (m);
+}
+
+/*
+ * As above; retry an MGETHDR.
+ */
+struct mbuf *
+m_retryhdr(i, t)
+ int i, t;
+{
+ register struct mbuf *m;
+
+ m_reclaim();
+#define m_retryhdr(i, t) (struct mbuf *)0
+ MGETHDR(m, i, t);
+#undef m_retryhdr
+ if (m != NULL)
+ mbstat.m_wait++;
+ else
+ mbstat.m_drops++;
+ return (m);
+}
+
+void
+m_reclaim(void)
+{
+ register struct domain *dp;
+ register struct protosw *pr;
+ int s = splimp();
+
+ for (dp = domains; dp; dp = dp->dom_next)
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+ if (pr->pr_drain)
+ (*pr->pr_drain)();
+ splx(s);
+ mbstat.m_drain++;
+}
+
+/*
+ * Space allocation routines.
+ * These are also available as macros
+ * for critical paths.
+ */
+struct mbuf *
+m_get(nowait, type)
+ int nowait, type;
+{
+ register struct mbuf *m;
+
+ MGET(m, nowait, type);
+ return (m);
+}
+
+struct mbuf *
+m_gethdr(nowait, type)
+ int nowait, type;
+{
+ register struct mbuf *m;
+
+ MGETHDR(m, nowait, type);
+ return (m);
+}
+
+struct mbuf *
+m_getclr(nowait, type)
+ int nowait, type;
+{
+ register struct mbuf *m;
+
+ MGET(m, nowait, type);
+ if (m == 0)
+ return (0);
+ bzero(mtod(m, caddr_t), MLEN);
+ return (m);
+}
+
+struct mbuf *
+m_free(struct mbuf *m)
+{
+ struct mbuf *n;
+
+ MFREE(m, n);
+ return (n);
+}
+
+void
+m_freem(struct mbuf *mb)
+{
+ struct mbuf *n;
+
+ if (mb == NULL)
+ return;
+ do {
+ MFREE(mb, n);
+ mb = n;
+ } while (mb);
+}
+
+/*
+ * Mbuffer utility routines.
+ */
+
+/*
+ * Lesser-used path for M_PREPEND:
+ * allocate new mbuf to prepend to chain,
+ * copy junk along.
+ */
+struct mbuf *
+m_prepend(struct mbuf *m, int len, int how)
+{
+ struct mbuf *mn;
+
+ MGET(mn, how, m->m_type);
+ if (mn == (struct mbuf *)NULL) {
+ m_freem(m);
+ return ((struct mbuf *)NULL);
+ }
+ if (m->m_flags & M_PKTHDR) {
+ M_COPY_PKTHDR(mn, m);
+ m->m_flags &= ~M_PKTHDR;
+ }
+ mn->m_next = m;
+ m = mn;
+ if (len < MHLEN)
+ MH_ALIGN(m, len);
+ m->m_len = len;
+ return (m);
+}
+
+/*
+ * Make a copy of an mbuf chain starting "off0" bytes from the beginning,
+ * continuing for "len" bytes. If len is M_COPYALL, copy to end of mbuf.
+ * The wait parameter is a choice of M_WAIT/M_DONTWAIT from caller.
+ */
+static int MCFail;
+
+struct mbuf *
+m_copym(struct mbuf *m, int off0, int len, int wait)
+{
+ struct mbuf *n, **np;
+ int off = off0;
+ struct mbuf *top;
+ int copyhdr = 0;
+
+ if (off < 0 || len < 0)
+ panic("m_copym");
+ if (off == 0 && m->m_flags & M_PKTHDR)
+ copyhdr = 1;
+ while (off > 0) {
+ if (m == NULL)
+ panic("m_copym");
+ if (off < m->m_len)
+ break;
+ off -= m->m_len;
+ m = m->m_next;
+ }
+ np = &top;
+ top = 0;
+ while (len > 0) {
+ if (m == NULL) {
+ if (len != M_COPYALL)
+ panic("m_copym");
+ break;
+ }
+ MGET(n, wait, m->m_type);
+ *np = n;
+ if (n == NULL)
+ goto nospace;
+ if (copyhdr) {
+ M_COPY_PKTHDR(n, m);
+ if (len == M_COPYALL)
+ n->m_pkthdr.len -= off0;
+ else
+ n->m_pkthdr.len = len;
+ copyhdr = 0;
+ }
+ n->m_len = min(len, m->m_len - off);
+ if (m->m_flags & M_EXT) {
+ n->m_data = m->m_data + off;
+ if(!m->m_ext.ext_ref)
+ mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
+ else
+ (*(m->m_ext.ext_ref))(m->m_ext.ext_buf,
+ m->m_ext.ext_size);
+ n->m_ext = m->m_ext;
+ n->m_flags |= M_EXT;
+ } else
+ bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
+ (unsigned)n->m_len);
+ if (len != M_COPYALL)
+ len -= n->m_len;
+ off = 0;
+ m = m->m_next;
+ np = &n->m_next;
+ }
+ if (top == NULL)
+ MCFail++;
+ return (top);
+nospace:
+ m_freem(top);
+ MCFail++;
+ return (NULL);
+}
+
+/*
+ * Copy an entire packet, including header (which must be present).
+ * An optimization of the common case `m_copym(m, 0, M_COPYALL, how)'.
+ */
+struct mbuf *
+m_copypacket(struct mbuf *m, int how)
+{
+ struct mbuf *top, *n, *o;
+
+ MGET(n, how, m->m_type);
+ top = n;
+ if (!n)
+ goto nospace;
+
+ M_COPY_PKTHDR(n, m);
+ n->m_len = m->m_len;
+ if (m->m_flags & M_EXT) {
+ n->m_data = m->m_data;
+ mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
+ n->m_ext = m->m_ext;
+ n->m_flags |= M_EXT;
+ } else {
+ bcopy(mtod(m, char *), mtod(n, char *), n->m_len);
+ }
+
+ m = m->m_next;
+ while (m) {
+ MGET(o, how, m->m_type);
+ if (!o)
+ goto nospace;
+
+ n->m_next = o;
+ n = n->m_next;
+
+ n->m_len = m->m_len;
+ if (m->m_flags & M_EXT) {
+ n->m_data = m->m_data;
+ mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
+ n->m_ext = m->m_ext;
+ n->m_flags |= M_EXT;
+ } else {
+ bcopy(mtod(m, char *), mtod(n, char *), n->m_len);
+ }
+
+ m = m->m_next;
+ }
+ return top;
+nospace:
+ m_freem(top);
+ MCFail++;
+ return 0;
+}
+
+/*
+ * Copy data from an mbuf chain starting "off" bytes from the beginning,
+ * continuing for "len" bytes, into the indicated buffer. Return -1 if requested
+ * size is bigger than available
+ */
+int
+m_copydata(const struct mbuf *m, int off, int len, caddr_t cp)
+{
+ u_int count;
+
+ if (off < 0 || len < 0)
+ panic("m_copydata");
+ while (off > 0) {
+ if (m == 0) {
+ /*printf("m_copydata: offset > mbuf length (");
+ while(m0) {
+ printf("[%d] ",m0->m_len);
+ m0 = m0->m_next;
+ }
+ printf(")\n");*/
+ return -1;
+ }
+ if (off < m->m_len)
+ break;
+ off -= m->m_len;
+ m = m->m_next;
+ }
+ while (len > 0) {
+ if (m == 0) {
+ /*printf("m_copydata: length > mbuf length (");
+ while(m0) {
+ printf("[%d] ",m0->m_len);
+ m0 = m0->m_next;
+ }
+ printf(")\n");*/
+
+ return -1;
+ }
+ count = min(m->m_len - off, len);
+ bcopy(mtod(m, caddr_t) + off, cp, count);
+ len -= count;
+ cp += count;
+ off = 0;
+ m = m->m_next;
+ }
+ return 0;
+}
+
+/*
+ * Concatenate mbuf chain n to m.
+ * Both chains must be of the same type (e.g. MT_DATA).
+ * Any m_pkthdr is not updated.
+ */
+void
+m_cat(struct mbuf *m, struct mbuf *n)
+{
+ while (m->m_next)
+ m = m->m_next;
+ while (n) {
+ if (m->m_flags & M_EXT ||
+ m->m_data + m->m_len + n->m_len >= &m->m_dat[MLEN]) {
+ /* just join the two chains */
+ m->m_next = n;
+ return;
+ }
+ /* splat the data from one into the other */
+ bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
+ (u_int)n->m_len);
+ m->m_len += n->m_len;
+ n = m_free(n);
+ }
+}
+
+void
+m_adj(struct mbuf *mp, int req_len)
+{
+ int len = req_len;
+ struct mbuf *m;
+ int count;
+
+ if ((m = mp) == NULL)
+ return;
+ if (len >= 0) {
+ /*
+ * Trim from head.
+ */
+ while (m != NULL && len > 0) {
+ if (m->m_len <= len) {
+ len -= m->m_len;
+ m->m_len = 0;
+ m = m->m_next;
+ } else {
+ m->m_len -= len;
+ m->m_data += len;
+ len = 0;
+ }
+ }
+ m = mp;
+ if (mp->m_flags & M_PKTHDR)
+ m->m_pkthdr.len -= (req_len - len);
+ } else {
+ /*
+ * Trim from tail. Scan the mbuf chain,
+ * calculating its length and finding the last mbuf.
+ * If the adjustment only affects this mbuf, then just
+ * adjust and return. Otherwise, rescan and truncate
+ * after the remaining size.
+ */
+ len = -len;
+ count = 0;
+ for (;;) {
+ count += m->m_len;
+ if (m->m_next == (struct mbuf *)0)
+ break;
+ m = m->m_next;
+ }
+ if (m->m_len >= len) {
+ m->m_len -= len;
+ if (mp->m_flags & M_PKTHDR)
+ mp->m_pkthdr.len -= len;
+ return;
+ }
+ count -= len;
+ if (count < 0)
+ count = 0;
+ /*
+ * Correct length for chain is "count".
+ * Find the mbuf with last data, adjust its length,
+ * and toss data from remaining mbufs on chain.
+ */
+ m = mp;
+ if (m->m_flags & M_PKTHDR)
+ m->m_pkthdr.len = count;
+ for (; m; m = m->m_next) {
+ if (m->m_len >= count) {
+ m->m_len = count;
+ break;
+ }
+ count -= m->m_len;
+ }
+ while (m->m_next)
+ (m = m->m_next) ->m_len = 0;
+ }
+}
+
+/*
+ * Rearange an mbuf chain so that len bytes are contiguous
+ * and in the data area of an mbuf (so that mtod and dtom
+ * will work for a structure of size len). Returns the resulting
+ * mbuf chain on success, frees it and returns null on failure.
+ * If there is room, it will add up to max_protohdr-len extra bytes to the
+ * contiguous region in an attempt to avoid being called next time.
+ */
+static int MPFail;
+
+struct mbuf *
+m_pullup(struct mbuf *n, int len)
+{
+ struct mbuf *m;
+ int count;
+ int space;
+
+ /*
+ * If first mbuf has no cluster, and has room for len bytes
+ * without shifting current data, pullup into it,
+ * otherwise allocate a new mbuf to prepend to the chain.
+ */
+ if ((n->m_flags & M_EXT) == 0 &&
+ n->m_data + len < &n->m_dat[MLEN] && n->m_next) {
+ if (n->m_len >= len)
+ return (n);
+ m = n;
+ n = n->m_next;
+ len -= m->m_len;
+ } else {
+ if (len > MHLEN)
+ goto bad;
+ MGET(m, M_DONTWAIT, n->m_type);
+ if (m == NULL)
+ goto bad;
+ m->m_len = 0;
+ if (n->m_flags & M_PKTHDR) {
+ M_COPY_PKTHDR(m, n);
+ n->m_flags &= ~M_PKTHDR;
+ }
+ }
+ space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
+ do {
+ count = min(min(max(len, max_protohdr), space), n->m_len);
+ bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
+ (unsigned)count);
+ len -= count;
+ m->m_len += count;
+ n->m_len -= count;
+ space -= count;
+ if (n->m_len)
+ n->m_data += count;
+ else
+ n = m_free(n);
+ } while (len > 0 && n);
+ if (len > 0) {
+ (void) m_free(m);
+ goto bad;
+ }
+ m->m_next = n;
+ return (m);
+ bad:
+ m_freem(n);
+ MPFail++;
+ return (NULL);
+}
+
+/*
+ * Partition an mbuf chain in two pieces, returning the tail --
+ * all but the first len0 bytes. In case of failure, it returns NULL and
+ * attempts to restore the chain to its original state.
+ */
+struct mbuf *
+m_split(struct mbuf *m0, int len0, int wait)
+{
+ struct mbuf *m, *n;
+ u_int len = len0, remain;
+
+ for (m = m0; m && len > m->m_len; m = m->m_next)
+ len -= m->m_len;
+ if (m == NULL)
+ return (NULL);
+ remain = m->m_len - len;
+ if (m0->m_flags & M_PKTHDR) {
+ MGETHDR(n, wait, m0->m_type);
+ if (n == NULL)
+ return (NULL);
+ n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
+ n->m_pkthdr.len = m0->m_pkthdr.len - len0;
+ m0->m_pkthdr.len = len0;
+ if (m->m_flags & M_EXT)
+ goto extpacket;
+ if (remain > MHLEN) {
+ /* m can't be the lead packet */
+ MH_ALIGN(n, 0);
+ n->m_next = m_split(m, len, wait);
+ if (n->m_next == 0) {
+ (void) m_free(n);
+ return (0);
+ } else
+ return (n);
+ } else
+ MH_ALIGN(n, remain);
+ } else if (remain == 0) {
+ n = m->m_next;
+ m->m_next = NULL;
+ return (n);
+ } else {
+ MGET(n, wait, m->m_type);
+ if (n == 0)
+ return (0);
+ M_ALIGN(n, remain);
+ }
+extpacket:
+ if (m->m_flags & M_EXT) {
+ n->m_flags |= M_EXT;
+ n->m_ext = m->m_ext;
+ if(!m->m_ext.ext_ref)
+ mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
+ else
+ (*(m->m_ext.ext_ref))(m->m_ext.ext_buf,
+ m->m_ext.ext_size);
+ m->m_ext.ext_size = 0; /* For Accounting XXXXXX danger */
+ n->m_data = m->m_data + len;
+ } else {
+ bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
+ }
+ n->m_len = remain;
+ m->m_len = len;
+ n->m_next = m->m_next;
+ m->m_next = NULL;
+ return (n);
+}
+/*
+ * Routine to copy from device local memory into mbufs.
+ */
+struct mbuf *
+m_devget(char *buf, int totlen, int off0, struct ifnet *ifp,
+ void (*copy)(char *from, caddr_t to, u_int len))
+{
+ struct mbuf *m;
+ struct mbuf *top = NULL, **mp = &top;
+ int len;
+ int off = off0;
+ char *cp;
+ char *epkt;
+
+ cp = buf;
+ epkt = cp + totlen;
+ if (off) {
+ cp += off + 2 * sizeof(u_short);
+ totlen -= 2 * sizeof(u_short);
+ }
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == 0)
+ return (0);
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = totlen;
+ m->m_len = MHLEN;
+
+ while (totlen > 0) {
+ if (top) {
+ MGET(m, M_DONTWAIT, MT_DATA);
+ if (m == 0) {
+ m_freem(top);
+ return (0);
+ }
+ m->m_len = MLEN;
+ }
+ len = min(totlen, epkt - cp);
+ if (len >= MINCLSIZE) {
+ MCLGET(m, M_DONTWAIT);
+ if (m->m_flags & M_EXT)
+ m->m_len = len = min(len, MCLBYTES);
+ else
+ len = m->m_len;
+ } else {
+ /*
+ * Place initial small packet/header at end of mbuf.
+ */
+ if (len < m->m_len) {
+ if (top == 0 && len + max_linkhdr <= m->m_len)
+ m->m_data += max_linkhdr;
+ m->m_len = len;
+ } else
+ len = m->m_len;
+ }
+ if (copy)
+ copy(cp, mtod(m, caddr_t), (u_int)len);
+ else
+ bcopy(cp, mtod(m, caddr_t), (u_int)len);
+ cp += len;
+ *mp = m;
+ mp = &m->m_next;
+ totlen -= len;
+ if (cp == epkt)
+ cp = buf;
+ }
+ return (top);
+}
+
+/*
+ * Copy data from a buffer back into the indicated mbuf chain,
+ * starting "off" bytes from the beginning, extending the mbuf
+ * chain if necessary.
+ */
+int
+m_copyback(m0, off, len, cp)
+ struct mbuf *m0;
+ register int off;
+ register int len;
+ caddr_t cp;
+{
+ int mlen;
+ struct mbuf *m = m0, *n;
+ int totlen = 0;
+
+ if (m0 == NULL)
+ return 0;
+ while (off > (mlen = m->m_len)) {
+ off -= mlen;
+ totlen += mlen;
+ if (m->m_next == NULL) {
+ n = m_getclr(M_DONTWAIT, m->m_type);
+ if (n == NULL) {
+ /*panic("m_copyback() : malformed chain\n");*/
+ return -1;
+ }
+ n->m_len = min(MLEN, len + off);
+ m->m_next = n;
+ }
+ m = m->m_next;
+ }
+ while (len > 0) {
+ mlen = min (m->m_len - off, len);
+ bcopy(cp, off + mtod(m, caddr_t), (u_int)mlen);
+ cp += mlen;
+ len -= mlen;
+ mlen += off;
+ off = 0;
+ totlen += mlen;
+ if (len == 0) {
+ /* m->m_len = mlen; */
+ break;
+ }
+ if (m->m_next == NULL) {
+ n = m_get(M_DONTWAIT, m->m_type);
+ if (n == 0) {
+ /*panic("m_copyback() : malformed chain 2\n");*/
+ return -1;
+ };
+ n->m_len = min(MLEN, len);
+ m->m_next = n;
+ }
+ /* m->m_len = mlen; */
+ m = m->m_next;
+ }
+/*out:*/
+ if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
+ m->m_pkthdr.len = totlen;
+ return 0;
+}
diff --git a/cpukit/libnetworking/kern/uipc_socket.c b/cpukit/libnetworking/kern/uipc_socket.c
new file mode 100644
index 0000000000..8ce3f0ef95
--- /dev/null
+++ b/cpukit/libnetworking/kern/uipc_socket.c
@@ -0,0 +1,1142 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 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.
+ * 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.
+ *
+ * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/domain.h>
+#include <sys/kernel.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/resourcevar.h>
+#include <sys/signalvar.h>
+#include <sys/sysctl.h>
+#include <limits.h>
+
+static int somaxconn = SOMAXCONN;
+SYSCTL_INT(_kern, KIPC_SOMAXCONN, somaxconn, CTLFLAG_RW, &somaxconn, 0, "");
+
+/*
+ * Socket operation routines.
+ * These routines are called by the routines in
+ * sys_socket.c or from a system process, and
+ * implement the semantics of socket operations by
+ * switching out to the protocol specific routines.
+ */
+/*ARGSUSED*/
+int
+socreate(dom, aso, type, proto, p)
+ int dom;
+ struct socket **aso;
+ register int type;
+ int proto;
+ struct proc *p;
+{
+ register struct protosw *prp;
+ register struct socket *so;
+ register int error;
+
+ if (proto)
+ prp = pffindproto(dom, proto, type);
+ else
+ prp = pffindtype(dom, type);
+ if (prp == 0 || prp->pr_usrreqs == 0)
+ return (EPROTONOSUPPORT);
+ if (prp->pr_type != type)
+ return (EPROTOTYPE);
+ MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_WAIT);
+ bzero((caddr_t)so, sizeof(*so));
+ TAILQ_INIT(&so->so_incomp);
+ TAILQ_INIT(&so->so_comp);
+ so->so_type = type;
+ so->so_state = SS_PRIV;
+ so->so_uid = 0;
+ so->so_proto = prp;
+ error = (*prp->pr_usrreqs->pru_attach)(so, proto);
+ if (error) {
+ so->so_state |= SS_NOFDREF;
+ sofree(so);
+ return (error);
+ }
+ *aso = so;
+ return (0);
+}
+
+int
+sobind(so, nam)
+ struct socket *so;
+ struct mbuf *nam;
+{
+ int s = splnet();
+ int error;
+
+ error = (*so->so_proto->pr_usrreqs->pru_bind)(so, nam);
+ splx(s);
+ return (error);
+}
+
+int
+solisten(so, backlog)
+ register struct socket *so;
+ int backlog;
+{
+ int s = splnet(), error;
+
+ error = (*so->so_proto->pr_usrreqs->pru_listen)(so);
+ if (error) {
+ splx(s);
+ return (error);
+ }
+ if (so->so_comp.tqh_first == NULL)
+ so->so_options |= SO_ACCEPTCONN;
+ if (backlog < 0 || backlog > somaxconn)
+ backlog = somaxconn;
+ so->so_qlimit = backlog;
+ splx(s);
+ return (0);
+}
+
+void
+sofree(so)
+ register struct socket *so;
+{
+ struct socket *head = so->so_head;
+
+ if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
+ return;
+ if (head != NULL) {
+ if (so->so_state & SS_INCOMP) {
+ TAILQ_REMOVE(&head->so_incomp, so, so_list);
+ head->so_incqlen--;
+ } else if (so->so_state & SS_COMP) {
+ TAILQ_REMOVE(&head->so_comp, so, so_list);
+ } else {
+ panic("sofree: not queued");
+ }
+ head->so_qlen--;
+ so->so_state &= ~(SS_INCOMP|SS_COMP);
+ so->so_head = NULL;
+ }
+ sbrelease(&so->so_snd);
+ sorflush(so);
+ FREE(so, M_SOCKET);
+}
+
+/*
+ * Close a socket on last file table reference removal.
+ * Initiate disconnect if connected.
+ * Free socket when disconnect complete.
+ */
+int
+soclose(so)
+ register struct socket *so;
+{
+ int s = splnet(); /* conservative */
+ int error = 0;
+
+ if (so->so_options & SO_ACCEPTCONN) {
+ struct socket *sp, *sonext;
+
+ for (sp = so->so_incomp.tqh_first; sp != NULL; sp = sonext) {
+ sonext = sp->so_list.tqe_next;
+ (void) soabort(sp);
+ }
+ for (sp = so->so_comp.tqh_first; sp != NULL; sp = sonext) {
+ sonext = sp->so_list.tqe_next;
+ (void) soabort(sp);
+ }
+ }
+ if (so->so_pcb == 0)
+ goto discard;
+ if (so->so_state & SS_ISCONNECTED) {
+ if ((so->so_state & SS_ISDISCONNECTING) == 0) {
+ error = sodisconnect(so);
+ if (error)
+ goto drop;
+ }
+ if (so->so_options & SO_LINGER) {
+ if ((so->so_state & SS_ISDISCONNECTING) &&
+ (so->so_state & SS_NBIO))
+ goto drop;
+ while (so->so_state & SS_ISCONNECTED) {
+ soconnsleep (so);
+ }
+ }
+ }
+drop:
+ if (so->so_pcb) {
+ int error2 = (*so->so_proto->pr_usrreqs->pru_detach)(so);
+ if (error == 0)
+ error = error2;
+ }
+discard:
+ if (so->so_state & SS_NOFDREF)
+ panic("soclose: NOFDREF");
+ so->so_state |= SS_NOFDREF;
+ sofree(so);
+ splx(s);
+ return (error);
+}
+
+/*
+ * Must be called at splnet...
+ */
+int
+soabort(so)
+ struct socket *so;
+{
+
+ return (*so->so_proto->pr_usrreqs->pru_abort)(so);
+}
+
+int
+soaccept(so, nam)
+ register struct socket *so;
+ struct mbuf *nam;
+{
+ int s = splnet();
+ int error;
+
+ if ((so->so_state & SS_NOFDREF) == 0)
+ panic("soaccept: !NOFDREF");
+ so->so_state &= ~SS_NOFDREF;
+ error = (*so->so_proto->pr_usrreqs->pru_accept)(so, nam);
+ splx(s);
+ return (error);
+}
+
+int
+soconnect(so, nam)
+ register struct socket *so;
+ struct mbuf *nam;
+{
+ int s;
+ int error;
+
+ if (so->so_options & SO_ACCEPTCONN)
+ return (EOPNOTSUPP);
+ s = splnet();
+ /*
+ * If protocol is connection-based, can only connect once.
+ * Otherwise, if connected, try to disconnect first.
+ * This allows user to disconnect by connecting to, e.g.,
+ * a null address.
+ */
+ if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&
+ ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
+ (error = sodisconnect(so))))
+ error = EISCONN;
+ else
+ error = (*so->so_proto->pr_usrreqs->pru_connect)(so, nam);
+ splx(s);
+ return (error);
+}
+
+int
+soconnect2(so1, so2)
+ register struct socket *so1;
+ struct socket *so2;
+{
+ int s = splnet();
+ int error;
+
+ error = (*so1->so_proto->pr_usrreqs->pru_connect2)(so1, so2);
+ splx(s);
+ return (error);
+}
+
+int
+sodisconnect(so)
+ register struct socket *so;
+{
+ int s = splnet();
+ int error;
+
+ if ((so->so_state & SS_ISCONNECTED) == 0) {
+ error = ENOTCONN;
+ goto bad;
+ }
+ if (so->so_state & SS_ISDISCONNECTING) {
+ error = EALREADY;
+ goto bad;
+ }
+ error = (*so->so_proto->pr_usrreqs->pru_disconnect)(so);
+bad:
+ splx(s);
+ return (error);
+}
+
+#define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
+/*
+ * Send on a socket.
+ * If send must go all at once and message is larger than
+ * send buffering, then hard error.
+ * Lock against other senders.
+ * If must go all at once and not enough room now, then
+ * inform user that this would block and do nothing.
+ * Otherwise, if nonblocking, send as much as possible.
+ * The data to be sent is described by "uio" if nonzero,
+ * otherwise by the mbuf chain "top" (which must be null
+ * if uio is not). Data provided in mbuf chain must be small
+ * enough to send all at once.
+ *
+ * Returns nonzero on error, timeout or signal; callers
+ * must check for short counts if EINTR/ERESTART are returned.
+ * Data and control buffers are freed on return.
+ */
+int
+sosend(so, addr, uio, top, control, flags)
+ register struct socket *so;
+ struct mbuf *addr;
+ struct uio *uio;
+ struct mbuf *top;
+ struct mbuf *control;
+ int flags;
+{
+ struct mbuf **mp;
+ register struct mbuf *m;
+ register long space, len, resid;
+ int clen = 0, error, s, dontroute, mlen;
+ int atomic = sosendallatonce(so) || top;
+
+ if (uio)
+ resid = uio->uio_resid;
+ else
+ resid = top->m_pkthdr.len;
+ /*
+ * In theory resid should be unsigned.
+ * However, space must be signed, as it might be less than 0
+ * if we over-committed, and we must use a signed comparison
+ * of space and resid. On the other hand, a negative resid
+ * causes us to loop sending 0-length segments to the protocol.
+ *
+ * Also check to make sure that MSG_EOR isn't used on SOCK_STREAM
+ * type sockets since that's an error.
+ */
+ if ((resid < 0) || (so->so_type == SOCK_STREAM && (flags & MSG_EOR))) {
+ error = EINVAL;
+ goto out;
+ }
+
+ dontroute =
+ (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
+ (so->so_proto->pr_flags & PR_ATOMIC);
+ if (control)
+ clen = control->m_len;
+#define snderr(errno) { error = errno; splx(s); goto release; }
+
+restart:
+ error = sblock(&so->so_snd, SBLOCKWAIT(flags));
+ if (error)
+ goto out;
+ do {
+ s = splnet();
+ if (so->so_state & SS_CANTSENDMORE)
+ snderr(EPIPE);
+ if (so->so_error) {
+ error = so->so_error;
+ so->so_error = 0;
+ splx(s);
+ goto release;
+ }
+ if ((so->so_state & SS_ISCONNECTED) == 0) {
+ /*
+ * `sendto' and `sendmsg' is allowed on a connection-
+ * based socket if it supports implied connect.
+ * Return ENOTCONN if not connected and no address is
+ * supplied.
+ */
+ if ((so->so_proto->pr_flags & PR_CONNREQUIRED) &&
+ (so->so_proto->pr_flags & PR_IMPLOPCL) == 0) {
+ if ((so->so_state & SS_ISCONFIRMING) == 0 &&
+ !(resid == 0 && clen != 0))
+ snderr(ENOTCONN);
+ } else if (addr == 0)
+ snderr(so->so_proto->pr_flags & PR_CONNREQUIRED ?
+ ENOTCONN : EDESTADDRREQ);
+ }
+ space = sbspace(&so->so_snd);
+ if (flags & MSG_OOB)
+ space += 1024;
+ if ((atomic && resid > so->so_snd.sb_hiwat) ||
+ clen > so->so_snd.sb_hiwat)
+ snderr(EMSGSIZE);
+ if (space < resid + clen && uio &&
+ (atomic || space < so->so_snd.sb_lowat || space < clen)) {
+ if (so->so_state & SS_NBIO)
+ snderr(EWOULDBLOCK);
+ sbunlock(&so->so_snd);
+ error = sbwait(&so->so_snd);
+ splx(s);
+ if (error)
+ goto out;
+ goto restart;
+ }
+ splx(s);
+ mp = &top;
+ space -= clen;
+ do {
+ if (uio == NULL) {
+ /*
+ * Data is prepackaged in "top".
+ */
+ resid = 0;
+ if (flags & MSG_EOR)
+ top->m_flags |= M_EOR;
+ } else do {
+ if (top == 0) {
+ MGETHDR(m, M_WAIT, MT_DATA);
+ mlen = MHLEN;
+ m->m_pkthdr.len = 0;
+ m->m_pkthdr.rcvif = (struct ifnet *)0;
+ } else {
+ MGET(m, M_WAIT, MT_DATA);
+ mlen = MLEN;
+ }
+ if (resid >= MINCLSIZE) {
+ MCLGET(m, M_WAIT);
+ if ((m->m_flags & M_EXT) == 0)
+ goto nopages;
+ mlen = MCLBYTES;
+ len = min(min(mlen, resid), space);
+ } else {
+nopages:
+ len = min(min(mlen, resid), space);
+ /*
+ * For datagram protocols, leave room
+ * for protocol headers in first mbuf.
+ */
+ if (atomic && top == 0 && len < mlen)
+ MH_ALIGN(m, len);
+ }
+ space -= len;
+ error = uiomove(mtod(m, caddr_t), (int)len, uio);
+ resid = uio->uio_resid;
+ m->m_len = len;
+ *mp = m;
+ top->m_pkthdr.len += len;
+ if (error)
+ goto release;
+ mp = &m->m_next;
+ if (resid <= 0) {
+ if (flags & MSG_EOR)
+ top->m_flags |= M_EOR;
+ break;
+ }
+ } while (space > 0 && atomic);
+ if (dontroute)
+ so->so_options |= SO_DONTROUTE;
+ s = splnet(); /* XXX */
+ error = (*so->so_proto->pr_usrreqs->pru_send)(so,
+ (flags & MSG_OOB) ? PRUS_OOB :
+ /*
+ * If the user set MSG_EOF, the protocol
+ * understands this flag and nothing left to
+ * send then use PRU_SEND_EOF instead of PRU_SEND.
+ */
+ ((flags & MSG_EOF) &&
+ (so->so_proto->pr_flags & PR_IMPLOPCL) &&
+ (resid <= 0)) ?
+ PRUS_EOF : 0,
+ top, addr, control);
+ splx(s);
+ if (dontroute)
+ so->so_options &= ~SO_DONTROUTE;
+ clen = 0;
+ control = 0;
+ top = 0;
+ mp = &top;
+ if (error)
+ goto release;
+ } while (resid && space > 0);
+ } while (resid);
+
+release:
+ sbunlock(&so->so_snd);
+out:
+ if (top)
+ m_freem(top);
+ if (control)
+ m_freem(control);
+ return (error);
+}
+
+/*
+ * Implement receive operations on a socket.
+ * We depend on the way that records are added to the sockbuf
+ * by sbappend*. In particular, each record (mbufs linked through m_next)
+ * must begin with an address if the protocol so specifies,
+ * followed by an optional mbuf or mbufs containing ancillary data,
+ * and then zero or more mbufs of data.
+ * In order to avoid blocking network interrupts for the entire time here,
+ * we splx() while doing the actual copy to user space.
+ * Although the sockbuf is locked, new data may still be appended,
+ * and thus we must maintain consistency of the sockbuf during that time.
+ *
+ * The caller may receive the data as a single mbuf chain by supplying
+ * an mbuf **mp0 for use in returning the chain. The uio is then used
+ * only for the count in uio_resid.
+ */
+int
+soreceive(so, paddr, uio, mp0, controlp, flagsp)
+ register struct socket *so;
+ struct mbuf **paddr;
+ struct uio *uio;
+ struct mbuf **mp0;
+ struct mbuf **controlp;
+ int *flagsp;
+{
+ register struct mbuf *m, **mp;
+ register int flags, len, error, s, offset;
+ struct protosw *pr = so->so_proto;
+ struct mbuf *nextrecord;
+ int moff, type = 0;
+ int orig_resid = uio->uio_resid;
+
+ mp = mp0;
+ if (paddr)
+ *paddr = 0;
+ if (controlp)
+ *controlp = 0;
+ if (flagsp)
+ flags = *flagsp &~ MSG_EOR;
+ else
+ flags = 0;
+ if (flags & MSG_OOB) {
+ m = m_get(M_WAIT, MT_DATA);
+ error = (*pr->pr_usrreqs->pru_rcvoob)(so, m, flags & MSG_PEEK);
+ if (error)
+ goto bad;
+ do {
+ error = uiomove(mtod(m, caddr_t),
+ (int) min(uio->uio_resid, m->m_len), uio);
+ m = m_free(m);
+ } while (uio->uio_resid && error == 0 && m);
+bad:
+ if (m)
+ m_freem(m);
+ return (error);
+ }
+ if (mp)
+ *mp = (struct mbuf *)0;
+ if (so->so_state & SS_ISCONFIRMING && uio->uio_resid)
+ (*pr->pr_usrreqs->pru_rcvd)(so, 0);
+
+restart:
+ error = sblock(&so->so_rcv, SBLOCKWAIT(flags));
+ if (error)
+ return (error);
+ s = splnet();
+
+ m = so->so_rcv.sb_mb;
+ /*
+ * If we have less data than requested, block awaiting more
+ * (subject to any timeout) if:
+ * 1. the current count is less than the low water mark, or
+ * 2. MSG_WAITALL is set, and it is possible to do the entire
+ * receive operation at once if we block (resid <= hiwat).
+ * 3. MSG_DONTWAIT is not set
+ * If MSG_WAITALL is set but resid is larger than the receive buffer,
+ * we have to do the receive in sections, and thus risk returning
+ * a short count if a timeout or signal occurs after we start.
+ */
+ if (m == 0 || (((flags & MSG_DONTWAIT) == 0 &&
+ so->so_rcv.sb_cc < uio->uio_resid) &&
+ (so->so_rcv.sb_cc < so->so_rcv.sb_lowat ||
+ ((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)) &&
+ m->m_nextpkt == 0 && (pr->pr_flags & PR_ATOMIC) == 0)) {
+#ifdef DIAGNOSTIC
+ if (m == 0 && so->so_rcv.sb_cc)
+ panic("receive 1");
+#endif
+ if (so->so_error) {
+ if (m)
+ goto dontblock;
+ error = so->so_error;
+ if ((flags & MSG_PEEK) == 0)
+ so->so_error = 0;
+ goto release;
+ }
+ if (so->so_state & SS_CANTRCVMORE) {
+ if (m)
+ goto dontblock;
+ else
+ goto release;
+ }
+ for (; m; m = m->m_next)
+ if (m->m_type == MT_OOBDATA || (m->m_flags & M_EOR)) {
+ m = so->so_rcv.sb_mb;
+ goto dontblock;
+ }
+ if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
+ (so->so_proto->pr_flags & PR_CONNREQUIRED)) {
+ error = ENOTCONN;
+ goto release;
+ }
+ if (uio->uio_resid == 0)
+ goto release;
+ if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) {
+ error = EWOULDBLOCK;
+ goto release;
+ }
+ sbunlock(&so->so_rcv);
+ error = sbwait(&so->so_rcv);
+ splx(s);
+ if (error)
+ return (error);
+ goto restart;
+ }
+dontblock:
+ nextrecord = m->m_nextpkt;
+ if (pr->pr_flags & PR_ADDR) {
+#ifdef DIAGNOSTIC
+ if (m->m_type != MT_SONAME)
+ panic("receive 1a");
+#endif
+ orig_resid = 0;
+ if (flags & MSG_PEEK) {
+ if (paddr)
+ *paddr = m_copy(m, 0, m->m_len);
+ m = m->m_next;
+ } else {
+ sbfree(&so->so_rcv, m);
+ if (paddr) {
+ *paddr = m;
+ so->so_rcv.sb_mb = m->m_next;
+ m->m_next = 0;
+ m = so->so_rcv.sb_mb;
+ } else {
+ MFREE(m, so->so_rcv.sb_mb);
+ m = so->so_rcv.sb_mb;
+ }
+ }
+ }
+ while (m && m->m_type == MT_CONTROL && error == 0) {
+ if (flags & MSG_PEEK) {
+ if (controlp)
+ *controlp = m_copy(m, 0, m->m_len);
+ m = m->m_next;
+ } else {
+ sbfree(&so->so_rcv, m);
+ if (controlp) {
+ if (pr->pr_domain->dom_externalize &&
+ mtod(m, struct cmsghdr *)->cmsg_type ==
+ SCM_RIGHTS)
+ error = (*pr->pr_domain->dom_externalize)(m);
+ *controlp = m;
+ so->so_rcv.sb_mb = m->m_next;
+ m->m_next = 0;
+ m = so->so_rcv.sb_mb;
+ } else {
+ MFREE(m, so->so_rcv.sb_mb);
+ m = so->so_rcv.sb_mb;
+ }
+ }
+ if (controlp) {
+ orig_resid = 0;
+ controlp = &(*controlp)->m_next;
+ }
+ }
+ if (m) {
+ if ((flags & MSG_PEEK) == 0)
+ m->m_nextpkt = nextrecord;
+ type = m->m_type;
+ if (type == MT_OOBDATA)
+ flags |= MSG_OOB;
+ }
+ moff = 0;
+ offset = 0;
+ while (m && uio->uio_resid > 0 && error == 0) {
+ if (m->m_type == MT_OOBDATA) {
+ if (type != MT_OOBDATA)
+ break;
+ } else if (type == MT_OOBDATA)
+ break;
+#ifdef DIAGNOSTIC
+ else if (m->m_type != MT_DATA && m->m_type != MT_HEADER)
+ panic("receive 3");
+#endif
+ so->so_state &= ~SS_RCVATMARK;
+ len = uio->uio_resid;
+ if (so->so_oobmark && len > so->so_oobmark - offset)
+ len = so->so_oobmark - offset;
+ if (len > m->m_len - moff)
+ len = m->m_len - moff;
+ /*
+ * If mp is set, just pass back the mbufs.
+ * Otherwise copy them out via the uio, then free.
+ * Sockbuf must be consistent here (points to current mbuf,
+ * it points to next record) when we drop priority;
+ * we must note any additions to the sockbuf when we
+ * block interrupts again.
+ */
+ if (mp == 0) {
+ splx(s);
+ error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio);
+ s = splnet();
+ if (error)
+ goto release;
+ } else
+ uio->uio_resid -= len;
+ if (len == m->m_len - moff) {
+ if (m->m_flags & M_EOR)
+ flags |= MSG_EOR;
+ if (flags & MSG_PEEK) {
+ m = m->m_next;
+ moff = 0;
+ } else {
+ nextrecord = m->m_nextpkt;
+ sbfree(&so->so_rcv, m);
+ if (mp) {
+ *mp = m;
+ mp = &m->m_next;
+ so->so_rcv.sb_mb = m = m->m_next;
+ *mp = (struct mbuf *)0;
+ } else {
+ MFREE(m, so->so_rcv.sb_mb);
+ m = so->so_rcv.sb_mb;
+ }
+ if (m)
+ m->m_nextpkt = nextrecord;
+ }
+ } else {
+ if (flags & MSG_PEEK)
+ moff += len;
+ else {
+ if (mp)
+ *mp = m_copym(m, 0, len, M_WAIT);
+ m->m_data += len;
+ m->m_len -= len;
+ so->so_rcv.sb_cc -= len;
+ }
+ }
+ if (so->so_oobmark) {
+ if ((flags & MSG_PEEK) == 0) {
+ so->so_oobmark -= len;
+ if (so->so_oobmark == 0) {
+ so->so_state |= SS_RCVATMARK;
+ break;
+ }
+ } else {
+ offset += len;
+ if (offset == so->so_oobmark)
+ break;
+ }
+ }
+ if (flags & MSG_EOR)
+ break;
+ /*
+ * If the MSG_WAITALL flag is set (for non-atomic socket),
+ * we must not quit until "uio->uio_resid == 0" or an error
+ * termination. If a signal/timeout occurs, return
+ * with a short count but without error.
+ * Keep sockbuf locked against other readers.
+ */
+ while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 &&
+ !sosendallatonce(so) && !nextrecord) {
+ if (so->so_error || so->so_state & SS_CANTRCVMORE)
+ break;
+ error = sbwait(&so->so_rcv);
+ if (error) {
+ sbunlock(&so->so_rcv);
+ splx(s);
+ return (0);
+ }
+ m = so->so_rcv.sb_mb;
+ if (m)
+ nextrecord = m->m_nextpkt;
+ }
+ }
+
+ if (m && pr->pr_flags & PR_ATOMIC) {
+ flags |= MSG_TRUNC;
+ if ((flags & MSG_PEEK) == 0)
+ (void) sbdroprecord(&so->so_rcv);
+ }
+ if ((flags & MSG_PEEK) == 0) {
+ if (m == 0)
+ so->so_rcv.sb_mb = nextrecord;
+ if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
+ (*pr->pr_usrreqs->pru_rcvd)(so, flags);
+ }
+ if (orig_resid == uio->uio_resid && orig_resid &&
+ (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
+ sbunlock(&so->so_rcv);
+ splx(s);
+ goto restart;
+ }
+
+ if (flagsp)
+ *flagsp |= flags;
+release:
+ sbunlock(&so->so_rcv);
+ splx(s);
+ return (error);
+}
+
+int
+soshutdown(so, how)
+ register struct socket *so;
+ register int how;
+{
+ register struct protosw *pr = so->so_proto;
+
+ how++;
+ if (how & FREAD)
+ sorflush(so);
+ if (how & FWRITE)
+ return ((*pr->pr_usrreqs->pru_shutdown)(so));
+ return (0);
+}
+
+void
+sorflush(so)
+ register struct socket *so;
+{
+ register struct sockbuf *sb = &so->so_rcv;
+ register struct protosw *pr = so->so_proto;
+ register int s;
+ struct sockbuf asb;
+
+ sb->sb_flags |= SB_NOINTR;
+ (void) sblock(sb, M_WAITOK);
+ s = splimp();
+ socantrcvmore(so);
+ sbunlock(sb);
+ asb = *sb;
+ bzero((caddr_t)sb, sizeof (*sb));
+ splx(s);
+ if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)
+ (*pr->pr_domain->dom_dispose)(asb.sb_mb);
+ sbrelease(&asb);
+}
+
+int
+sosetopt(so, level, optname, m0)
+ register struct socket *so;
+ int level, optname;
+ struct mbuf *m0;
+{
+ int error = 0;
+ register struct mbuf *m = m0;
+
+ if (level != SOL_SOCKET) {
+ if (so->so_proto && so->so_proto->pr_ctloutput)
+ return ((*so->so_proto->pr_ctloutput)
+ (PRCO_SETOPT, so, level, optname, &m0));
+ error = ENOPROTOOPT;
+ } else {
+ switch (optname) {
+
+ case SO_LINGER:
+ if (m == NULL || m->m_len != sizeof (struct linger)) {
+ error = EINVAL;
+ goto bad;
+ }
+ so->so_linger = mtod(m, struct linger *)->l_linger;
+ /* fall thru... */
+
+ case SO_DEBUG:
+ case SO_KEEPALIVE:
+ case SO_DONTROUTE:
+ case SO_USELOOPBACK:
+ case SO_BROADCAST:
+ case SO_REUSEADDR:
+ case SO_REUSEPORT:
+ case SO_OOBINLINE:
+ case SO_TIMESTAMP:
+ if (m == NULL || m->m_len < sizeof (int)) {
+ error = EINVAL;
+ goto bad;
+ }
+ if (*mtod(m, int *))
+ so->so_options |= optname;
+ else
+ so->so_options &= ~optname;
+ break;
+
+ case SO_SNDBUF:
+ case SO_RCVBUF:
+ case SO_SNDLOWAT:
+ case SO_RCVLOWAT:
+ {
+ int optval;
+
+ if (m == NULL || m->m_len < sizeof (int)) {
+ error = EINVAL;
+ goto bad;
+ }
+
+ /*
+ * Values < 1 make no sense for any of these
+ * options, so disallow them.
+ */
+ optval = *mtod(m, int *);
+ if (optval < 1) {
+ error = EINVAL;
+ goto bad;
+ }
+
+ switch (optname) {
+
+ case SO_SNDBUF:
+ case SO_RCVBUF:
+ if (sbreserve(optname == SO_SNDBUF ?
+ &so->so_snd : &so->so_rcv,
+ (u_long) optval) == 0) {
+ error = ENOBUFS;
+ goto bad;
+ }
+ break;
+
+ /*
+ * Make sure the low-water is never greater than
+ * the high-water.
+ */
+ case SO_SNDLOWAT:
+ so->so_snd.sb_lowat =
+ (optval > so->so_snd.sb_hiwat) ?
+ so->so_snd.sb_hiwat : optval;
+ break;
+ case SO_RCVLOWAT:
+ so->so_rcv.sb_lowat =
+ (optval > so->so_rcv.sb_hiwat) ?
+ so->so_rcv.sb_hiwat : optval;
+ break;
+ }
+ break;
+ }
+
+ case SO_SNDTIMEO:
+ case SO_RCVTIMEO:
+ {
+ struct timeval *tv;
+ unsigned long val;
+
+ if (m == NULL || m->m_len < sizeof (*tv)) {
+ error = EINVAL;
+ goto bad;
+ }
+ tv = mtod(m, struct timeval *);
+ if (tv->tv_sec >= (ULONG_MAX - hz) / hz) {
+ error = EDOM;
+ goto bad;
+ }
+
+ val = tv->tv_sec * hz + tv->tv_usec / tick;
+ if ((val == 0) && (tv->tv_sec || tv->tv_usec))
+ val = 1;
+
+ switch (optname) {
+
+ case SO_SNDTIMEO:
+ so->so_snd.sb_timeo = val;
+ break;
+ case SO_RCVTIMEO:
+ so->so_rcv.sb_timeo = val;
+ break;
+ }
+ break;
+ }
+
+ case SO_PRIVSTATE:
+ /* we don't care what the parameter is... */
+ so->so_state &= ~SS_PRIV;
+ break;
+
+ case SO_SNDWAKEUP:
+ case SO_RCVWAKEUP:
+ {
+ /* RTEMS addition. */
+ struct sockwakeup *sw;
+ struct sockbuf *sb;
+
+ if (m == NULL
+ || m->m_len != sizeof (struct sockwakeup)) {
+ error = EINVAL;
+ goto bad;
+ }
+ sw = mtod(m, struct sockwakeup *);
+ sb = (optname == SO_SNDWAKEUP
+ ? &so->so_snd
+ : &so->so_rcv);
+ sb->sb_wakeup = sw->sw_pfn;
+ sb->sb_wakeuparg = sw->sw_arg;
+ if (sw->sw_pfn)
+ sb->sb_flags |= SB_ASYNC;
+ else
+ sb->sb_flags &=~ SB_ASYNC;
+ break;
+ }
+
+ default:
+ error = ENOPROTOOPT;
+ break;
+ }
+ if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
+ (void) ((*so->so_proto->pr_ctloutput)
+ (PRCO_SETOPT, so, level, optname, &m0));
+ m = NULL; /* freed by protocol */
+ }
+ }
+bad:
+ if (m)
+ (void) m_free(m);
+ return (error);
+}
+
+int
+sogetopt(so, level, optname, mp)
+ register struct socket *so;
+ int level, optname;
+ struct mbuf **mp;
+{
+ register struct mbuf *m;
+
+ if (level != SOL_SOCKET) {
+ if (so->so_proto && so->so_proto->pr_ctloutput) {
+ return ((*so->so_proto->pr_ctloutput)
+ (PRCO_GETOPT, so, level, optname, mp));
+ } else
+ return (ENOPROTOOPT);
+ } else {
+ m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof (int);
+
+ switch (optname) {
+
+ case SO_LINGER:
+ m->m_len = sizeof (struct linger);
+ mtod(m, struct linger *)->l_onoff =
+ so->so_options & SO_LINGER;
+ mtod(m, struct linger *)->l_linger = so->so_linger;
+ break;
+
+ case SO_USELOOPBACK:
+ case SO_DONTROUTE:
+ case SO_DEBUG:
+ case SO_KEEPALIVE:
+ case SO_REUSEADDR:
+ case SO_REUSEPORT:
+ case SO_BROADCAST:
+ case SO_OOBINLINE:
+ case SO_TIMESTAMP:
+ *mtod(m, int *) = so->so_options & optname;
+ break;
+
+ case SO_PRIVSTATE:
+ *mtod(m, int *) = so->so_state & SS_PRIV;
+ break;
+
+ case SO_TYPE:
+ *mtod(m, int *) = so->so_type;
+ break;
+
+ case SO_ERROR:
+ *mtod(m, int *) = so->so_error;
+ so->so_error = 0;
+ break;
+
+ case SO_SNDBUF:
+ *mtod(m, int *) = so->so_snd.sb_hiwat;
+ break;
+
+ case SO_RCVBUF:
+ *mtod(m, int *) = so->so_rcv.sb_hiwat;
+ break;
+
+ case SO_SNDLOWAT:
+ *mtod(m, int *) = so->so_snd.sb_lowat;
+ break;
+
+ case SO_RCVLOWAT:
+ *mtod(m, int *) = so->so_rcv.sb_lowat;
+ break;
+
+ case SO_SNDTIMEO:
+ case SO_RCVTIMEO:
+ {
+ unsigned long val = (optname == SO_SNDTIMEO ?
+ so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
+
+ m->m_len = sizeof(struct timeval);
+ mtod(m, struct timeval *)->tv_sec = val / hz;
+ mtod(m, struct timeval *)->tv_usec =
+ (val % hz) * tick;
+ break;
+ }
+
+ case SO_SNDWAKEUP:
+ case SO_RCVWAKEUP:
+ {
+ struct sockbuf *sb;
+ struct sockwakeup *sw;
+
+ /* RTEMS additions. */
+ sb = (optname == SO_SNDWAKEUP
+ ? &so->so_snd
+ : &so->so_rcv);
+ m->m_len = sizeof (struct sockwakeup);
+ sw = mtod(m, struct sockwakeup *);
+ sw->sw_pfn = sb->sb_wakeup;
+ sw->sw_arg = sb->sb_wakeuparg;
+ break;
+ }
+
+ default:
+ (void)m_free(m);
+ return (ENOPROTOOPT);
+ }
+ *mp = m;
+ return (0);
+ }
+}
+
+void
+sohasoutofband(so)
+ register struct socket *so;
+{
+#if 0 /* FIXME: For now we just ignore out of band data */
+ struct proc *p;
+
+ if (so->so_pgid < 0)
+ gsignal(-so->so_pgid, SIGURG);
+ else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
+ psignal(p, SIGURG);
+ selwakeup(&so->so_rcv.sb_sel);
+#endif
+}
diff --git a/cpukit/libnetworking/kern/uipc_socket2.c b/cpukit/libnetworking/kern/uipc_socket2.c
new file mode 100644
index 0000000000..ab1ee2439f
--- /dev/null
+++ b/cpukit/libnetworking/kern/uipc_socket2.c
@@ -0,0 +1,964 @@
+/*
+ * This file has undergone several changes to reflect the
+ * differences between the RTEMS and FreeBSD kernels.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 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.
+ *
+ * @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/signalvar.h>
+#include <sys/sysctl.h>
+
+/*
+ * Primitive routines for operating on sockets and socket buffers
+ */
+
+u_long sb_max = SB_MAX; /* XXX should be static */
+SYSCTL_INT(_kern, KIPC_MAXSOCKBUF, maxsockbuf, CTLFLAG_RW, &sb_max, 0, "");
+
+static u_long sb_efficiency = 8; /* parameter for sbreserve() */
+SYSCTL_INT(_kern, OID_AUTO, sockbuf_waste_factor, CTLFLAG_RW, &sb_efficiency,
+ 0, "");
+
+/*
+ * Procedures to manipulate state flags of socket
+ * and do appropriate wakeups. Normal sequence from the
+ * active (originating) side is that soisconnecting() is
+ * called during processing of connect() call,
+ * resulting in an eventual call to soisconnected() if/when the
+ * connection is established. When the connection is torn down
+ * soisdisconnecting() is called during processing of disconnect() call,
+ * and soisdisconnected() is called when the connection to the peer
+ * is totally severed. The semantics of these routines are such that
+ * connectionless protocols can call soisconnected() and soisdisconnected()
+ * only, bypassing the in-progress calls when setting up a ``connection''
+ * takes no time.
+ *
+ * From the passive side, a socket is created with
+ * two queues of sockets: so_q0 for connections in progress
+ * and so_q for connections already made and awaiting user acceptance.
+ * As a protocol is preparing incoming connections, it creates a socket
+ * structure queued on so_q0 by calling sonewconn(). When the connection
+ * is established, soisconnected() is called, and transfers the
+ * socket structure to so_q, making it available to accept().
+ *
+ * If a socket is closed with sockets on either
+ * so_q0 or so_q, these sockets are dropped.
+ *
+ * If higher level protocols are implemented in
+ * the kernel, the wakeups done here will sometimes
+ * cause software-interrupt process scheduling.
+ */
+
+void
+soisconnecting(so)
+ register struct socket *so;
+{
+
+ so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
+ so->so_state |= SS_ISCONNECTING;
+}
+
+void
+soisconnected(so)
+ register struct socket *so;
+{
+ register struct socket *head = so->so_head;
+
+ so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
+ so->so_state |= SS_ISCONNECTED;
+ if (head && (so->so_state & SS_INCOMP)) {
+ TAILQ_REMOVE(&head->so_incomp, so, so_list);
+ head->so_incqlen--;
+ so->so_state &= ~SS_INCOMP;
+ TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
+ so->so_state |= SS_COMP;
+ sorwakeup(head);
+ soconnwakeup(head);
+ } else {
+ soconnwakeup(so);
+ sorwakeup(so);
+ sowwakeup(so);
+ }
+}
+
+void
+soisdisconnecting(so)
+ register struct socket *so;
+{
+
+ so->so_state &= ~SS_ISCONNECTING;
+ so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
+ soconnwakeup(so);
+ sowwakeup(so);
+ sorwakeup(so);
+}
+
+void
+soisdisconnected(so)
+ register struct socket *so;
+{
+
+ so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
+ so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
+ soconnwakeup(so);
+ sowwakeup(so);
+ sorwakeup(so);
+}
+
+/*
+ * Return a random connection that hasn't been serviced yet and
+ * is eligible for discard. There is a one in qlen chance that
+ * we will return a null, saying that there are no dropable
+ * requests. In this case, the protocol specific code should drop
+ * the new request. This insures fairness.
+ *
+ * This may be used in conjunction with protocol specific queue
+ * congestion routines.
+ */
+struct socket *
+sodropablereq(head)
+ register struct socket *head;
+{
+ register struct socket *so;
+ unsigned int i, j, qlen, m;
+
+ static int rnd;
+ static long old_mono_secs;
+ static unsigned int cur_cnt, old_cnt;
+
+ if ((i = (m = rtems_bsdnet_seconds_since_boot()) - old_mono_secs) != 0) {
+ old_mono_secs = m;
+ old_cnt = cur_cnt / i;
+ cur_cnt = 0;
+ }
+
+ so = TAILQ_FIRST(&head->so_incomp);
+ if (!so)
+ return (so);
+
+ qlen = head->so_incqlen;
+ if (++cur_cnt > qlen || old_cnt > qlen) {
+ rnd = (314159 * rnd + 66329) & 0xffff;
+ j = ((qlen + 1) * rnd) >> 16;
+
+ while (j-- && so)
+ so = TAILQ_NEXT(so, so_list);
+ }
+
+ return (so);
+}
+
+/*
+ * When an attempt at a new connection is noted on a socket
+ * which accepts connections, sonewconn is called. If the
+ * connection is possible (subject to space constraints, etc.)
+ * then we allocate a new structure, propoerly linked into the
+ * data structure of the original socket, and return this.
+ * Connstatus may be 0, or SO_ISCONFIRMING, or SO_ISCONNECTED.
+ *
+ * Currently, sonewconn() is defined as sonewconn1() in socketvar.h
+ * to catch calls that are missing the (new) second parameter.
+ */
+struct socket *
+sonewconn1(head, connstatus)
+ register struct socket *head;
+ int connstatus;
+{
+ register struct socket *so;
+
+ if (head->so_qlen > 3 * head->so_qlimit / 2)
+ return ((struct socket *)0);
+ MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_DONTWAIT);
+ if (so == NULL)
+ return ((struct socket *)0);
+ bzero((caddr_t)so, sizeof(*so));
+ so->so_head = head;
+ so->so_type = head->so_type;
+ so->so_options = head->so_options &~ SO_ACCEPTCONN;
+ so->so_linger = head->so_linger;
+ so->so_state = head->so_state | SS_NOFDREF;
+ so->so_proto = head->so_proto;
+ so->so_timeo = head->so_timeo;
+ so->so_pgid = head->so_pgid;
+ so->so_uid = head->so_uid;
+ (void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
+ if (connstatus) {
+ TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
+ so->so_state |= SS_COMP;
+ } else {
+ TAILQ_INSERT_TAIL(&head->so_incomp, so, so_list);
+ so->so_state |= SS_INCOMP;
+ head->so_incqlen++;
+ }
+ head->so_qlen++;
+ if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0)) {
+ if (so->so_state & SS_COMP) {
+ TAILQ_REMOVE(&head->so_comp, so, so_list);
+ } else {
+ TAILQ_REMOVE(&head->so_incomp, so, so_list);
+ head->so_incqlen--;
+ }
+ head->so_qlen--;
+ (void) free((caddr_t)so, M_SOCKET);
+ return ((struct socket *)0);
+ }
+ if (connstatus) {
+ sorwakeup(head);
+ soconnwakeup(head);
+ so->so_state |= connstatus;
+ }
+ return (so);
+}
+
+/*
+ * Socantsendmore indicates that no more data will be sent on the
+ * socket; it would normally be applied to a socket when the user
+ * informs the system that no more data is to be sent, by the protocol
+ * code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data
+ * will be received, and will normally be applied to the socket by a
+ * protocol when it detects that the peer will send no more data.
+ * Data queued for reading in the socket may yet be read.
+ */
+
+void
+socantsendmore(so)
+ struct socket *so;
+{
+
+ so->so_state |= SS_CANTSENDMORE;
+ sowwakeup(so);
+}
+
+void
+socantrcvmore(so)
+ struct socket *so;
+{
+
+ so->so_state |= SS_CANTRCVMORE;
+ sorwakeup(so);
+}
+
+/*
+ * Socket buffer (struct sockbuf) utility routines.
+ *
+ * Each socket contains two socket buffers: one for sending data and
+ * one for receiving data. Each buffer contains a queue of mbufs,
+ * information about the number of mbufs and amount of data in the
+ * queue, and other fields allowing select() statements and notification
+ * on data availability to be implemented.
+ *
+ * Data stored in a socket buffer is maintained as a list of records.
+ * Each record is a list of mbufs chained together with the m_next
+ * field. Records are chained together with the m_nextpkt field. The upper
+ * level routine soreceive() expects the following conventions to be
+ * observed when placing information in the receive buffer:
+ *
+ * 1. If the protocol requires each message be preceded by the sender's
+ * name, then a record containing that name must be present before
+ * any associated data (mbuf's must be of type MT_SONAME).
+ * 2. If the protocol supports the exchange of ``access rights'' (really
+ * just additional data associated with the message), and there are
+ * ``rights'' to be received, then a record containing this data
+ * should be present (mbuf's must be of type MT_RIGHTS).
+ * 3. If a name or rights record exists, then it must be followed by
+ * a data record, perhaps of zero length.
+ *
+ * Before using a new socket structure it is first necessary to reserve
+ * buffer space to the socket, by calling sbreserve(). This should commit
+ * some of the available buffer space in the system buffer pool for the
+ * socket (currently, it does nothing but enforce limits). The space
+ * should be released by calling sbrelease() when the socket is destroyed.
+ */
+
+int
+soreserve(so, sndcc, rcvcc)
+ register struct socket *so;
+ u_long sndcc, rcvcc;
+{
+
+ if (sbreserve(&so->so_snd, sndcc) == 0)
+ goto bad;
+ if (sbreserve(&so->so_rcv, rcvcc) == 0)
+ goto bad2;
+ if (so->so_rcv.sb_lowat == 0)
+ so->so_rcv.sb_lowat = 1;
+ if (so->so_snd.sb_lowat == 0)
+ so->so_snd.sb_lowat = MCLBYTES;
+ if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
+ so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
+ return (0);
+bad2:
+ sbrelease(&so->so_snd);
+bad:
+ return (ENOBUFS);
+}
+
+/*
+ * Allot mbufs to a sockbuf.
+ * Attempt to scale mbmax so that mbcnt doesn't become limiting
+ * if buffering efficiency is near the normal case.
+ */
+int
+sbreserve(sb, cc)
+ struct sockbuf *sb;
+ u_long cc;
+{
+
+ if (cc > sb_max * MCLBYTES / (MSIZE + MCLBYTES))
+ return (0);
+ sb->sb_hiwat = cc;
+ sb->sb_mbmax = min(cc * sb_efficiency, sb_max);
+ if (sb->sb_lowat > sb->sb_hiwat)
+ sb->sb_lowat = sb->sb_hiwat;
+ return (1);
+}
+
+/*
+ * Free mbufs held by a socket, and reserved mbuf space.
+ */
+void
+sbrelease(sb)
+ struct sockbuf *sb;
+{
+
+ sbflush(sb);
+ sb->sb_hiwat = sb->sb_mbmax = 0;
+}
+
+/*
+ * Routines to add and remove
+ * data from an mbuf queue.
+ *
+ * The routines sbappend() or sbappendrecord() are normally called to
+ * append new mbufs to a socket buffer, after checking that adequate
+ * space is available, comparing the function sbspace() with the amount
+ * of data to be added. sbappendrecord() differs from sbappend() in
+ * that data supplied is treated as the beginning of a new record.
+ * To place a sender's address, optional access rights, and data in a
+ * socket receive buffer, sbappendaddr() should be used. To place
+ * access rights and data in a socket receive buffer, sbappendrights()
+ * should be used. In either case, the new data begins a new record.
+ * Note that unlike sbappend() and sbappendrecord(), these routines check
+ * for the caller that there will be enough space to store the data.
+ * Each fails if there is not enough space, or if it cannot find mbufs
+ * to store additional information in.
+ *
+ * Reliable protocols may use the socket send buffer to hold data
+ * awaiting acknowledgement. Data is normally copied from a socket
+ * send buffer in a protocol with m_copy for output to a peer,
+ * and then removing the data from the socket buffer with sbdrop()
+ * or sbdroprecord() when the data is acknowledged by the peer.
+ */
+
+/*
+ * Append mbuf chain m to the last record in the
+ * socket buffer sb. The additional space associated
+ * the mbuf chain is recorded in sb. Empty mbufs are
+ * discarded and mbufs are compacted where possible.
+ */
+void
+sbappend(sb, m)
+ struct sockbuf *sb;
+ struct mbuf *m;
+{
+ register struct mbuf *n;
+
+ if (m == 0)
+ return;
+ n = sb->sb_mb;
+ if (n) {
+ while (n->m_nextpkt)
+ n = n->m_nextpkt;
+ do {
+ if (n->m_flags & M_EOR) {
+ sbappendrecord(sb, m); /* XXXXXX!!!! */
+ return;
+ }
+ } while (n->m_next && (n = n->m_next));
+ }
+ sbcompress(sb, m, n);
+}
+
+#ifdef SOCKBUF_DEBUG
+void
+sbcheck(sb)
+ register struct sockbuf *sb;
+{
+ register struct mbuf *m;
+ register int len = 0, mbcnt = 0;
+
+ for (m = sb->sb_mb; m; m = m->m_next) {
+ len += m->m_len;
+ mbcnt += MSIZE;
+ if (m->m_flags & M_EXT) /*XXX*/ /* pretty sure this is bogus */
+ mbcnt += m->m_ext.ext_size;
+ if (m->m_nextpkt)
+ panic("sbcheck nextpkt");
+ }
+ if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) {
+ printf("cc %d != %d || mbcnt %d != %d\n", len, sb->sb_cc,
+ mbcnt, sb->sb_mbcnt);
+ panic("sbcheck");
+ }
+}
+#endif
+
+/*
+ * As above, except the mbuf chain
+ * begins a new record.
+ */
+void
+sbappendrecord(sb, m0)
+ register struct sockbuf *sb;
+ register struct mbuf *m0;
+{
+ register struct mbuf *m;
+
+ if (m0 == 0)
+ return;
+ m = sb->sb_mb;
+ if (m)
+ while (m->m_nextpkt)
+ m = m->m_nextpkt;
+ /*
+ * Put the first mbuf on the queue.
+ * Note this permits zero length records.
+ */
+ sballoc(sb, m0);
+ if (m)
+ m->m_nextpkt = m0;
+ else
+ sb->sb_mb = m0;
+ m = m0->m_next;
+ m0->m_next = 0;
+ if (m && (m0->m_flags & M_EOR)) {
+ m0->m_flags &= ~M_EOR;
+ m->m_flags |= M_EOR;
+ }
+ sbcompress(sb, m, m0);
+}
+
+/*
+ * As above except that OOB data
+ * is inserted at the beginning of the sockbuf,
+ * but after any other OOB data.
+ */
+void
+sbinsertoob(sb, m0)
+ register struct sockbuf *sb;
+ register struct mbuf *m0;
+{
+ register struct mbuf *m;
+ register struct mbuf **mp;
+
+ if (m0 == 0)
+ return;
+ for (mp = &sb->sb_mb; *mp ; mp = &((*mp)->m_nextpkt)) {
+ m = *mp;
+ again:
+ switch (m->m_type) {
+
+ case MT_OOBDATA:
+ continue; /* WANT next train */
+
+ case MT_CONTROL:
+ m = m->m_next;
+ if (m)
+ goto again; /* inspect THIS train further */
+ }
+ break;
+ }
+ /*
+ * Put the first mbuf on the queue.
+ * Note this permits zero length records.
+ */
+ sballoc(sb, m0);
+ m0->m_nextpkt = *mp;
+ *mp = m0;
+ m = m0->m_next;
+ m0->m_next = 0;
+ if (m && (m0->m_flags & M_EOR)) {
+ m0->m_flags &= ~M_EOR;
+ m->m_flags |= M_EOR;
+ }
+ sbcompress(sb, m, m0);
+}
+
+/*
+ * Append address and data, and optionally, control (ancillary) data
+ * to the receive queue of a socket. If present,
+ * m0 must include a packet header with total length.
+ * Returns 0 if no space in sockbuf or insufficient mbufs.
+ */
+int
+sbappendaddr(sb, asa, m0, control)
+ register struct sockbuf *sb;
+ struct sockaddr *asa;
+ struct mbuf *m0, *control;
+{
+ register struct mbuf *m, *n;
+ int space = asa->sa_len;
+
+if (m0 && (m0->m_flags & M_PKTHDR) == 0)
+panic("sbappendaddr");
+ if (m0)
+ space += m0->m_pkthdr.len;
+ for (n = control; n; n = n->m_next) {
+ space += n->m_len;
+ if (n->m_next == 0) /* keep pointer to last control buf */
+ break;
+ }
+ if (space > sbspace(sb))
+ return (0);
+ if (asa->sa_len > MLEN)
+ return (0);
+ MGET(m, M_DONTWAIT, MT_SONAME);
+ if (m == 0)
+ return (0);
+ m->m_len = asa->sa_len;
+ bcopy((caddr_t)asa, mtod(m, caddr_t), asa->sa_len);
+ if (n)
+ n->m_next = m0; /* concatenate data to control */
+ else
+ control = m0;
+ m->m_next = control;
+ for (n = m; n; n = n->m_next)
+ sballoc(sb, n);
+ n = sb->sb_mb;
+ if (n) {
+ while (n->m_nextpkt)
+ n = n->m_nextpkt;
+ n->m_nextpkt = m;
+ } else
+ sb->sb_mb = m;
+ return (1);
+}
+
+int
+sbappendcontrol(sb, m0, control)
+ struct sockbuf *sb;
+ struct mbuf *control, *m0;
+{
+ register struct mbuf *m, *n;
+ int space = 0;
+
+ if (control == 0)
+ panic("sbappendcontrol");
+ for (m = control; ; m = m->m_next) {
+ space += m->m_len;
+ if (m->m_next == 0)
+ break;
+ }
+ n = m; /* save pointer to last control buffer */
+ for (m = m0; m; m = m->m_next)
+ space += m->m_len;
+ if (space > sbspace(sb))
+ return (0);
+ n->m_next = m0; /* concatenate data to control */
+ for (m = control; m; m = m->m_next)
+ sballoc(sb, m);
+ n = sb->sb_mb;
+ if (n) {
+ while (n->m_nextpkt)
+ n = n->m_nextpkt;
+ n->m_nextpkt = control;
+ } else
+ sb->sb_mb = control;
+ return (1);
+}
+
+/*
+ * Compress mbuf chain m into the socket
+ * buffer sb following mbuf n. If n
+ * is null, the buffer is presumed empty.
+ */
+void
+sbcompress(sb, m, n)
+ register struct sockbuf *sb;
+ register struct mbuf *m, *n;
+{
+ register int eor = 0;
+ register struct mbuf *o;
+
+ while (m) {
+ eor |= m->m_flags & M_EOR;
+ if (m->m_len == 0 &&
+ (eor == 0 ||
+ (((o = m->m_next) || (o = n)) &&
+ o->m_type == m->m_type))) {
+ m = m_free(m);
+ continue;
+ }
+ if (n && (n->m_flags & (M_EXT | M_EOR)) == 0 &&
+ (n->m_data + n->m_len + m->m_len) < &n->m_dat[MLEN] &&
+ n->m_type == m->m_type) {
+ bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len,
+ (unsigned)m->m_len);
+ n->m_len += m->m_len;
+ sb->sb_cc += m->m_len;
+ m = m_free(m);
+ continue;
+ }
+ if (n)
+ n->m_next = m;
+ else
+ sb->sb_mb = m;
+ sballoc(sb, m);
+ n = m;
+ m->m_flags &= ~M_EOR;
+ m = m->m_next;
+ n->m_next = 0;
+ }
+ if (eor) {
+ if (n)
+ n->m_flags |= eor;
+ else
+ printf("semi-panic: sbcompress\n");
+ }
+}
+
+/*
+ * Free all mbufs in a sockbuf.
+ * Check that all resources are reclaimed.
+ */
+void
+sbflush(sb)
+ register struct sockbuf *sb;
+{
+
+ if (sb->sb_flags & SB_LOCK)
+ panic("sbflush");
+ while (sb->sb_mbcnt)
+ sbdrop(sb, (int)sb->sb_cc);
+ if (sb->sb_cc || sb->sb_mb)
+ panic("sbflush 2");
+}
+
+/*
+ * Drop data from (the front of) a sockbuf.
+ */
+void
+sbdrop(sb, len)
+ register struct sockbuf *sb;
+ register int len;
+{
+ register struct mbuf *m, *mn;
+ struct mbuf *next;
+
+ next = (m = sb->sb_mb) ? m->m_nextpkt : 0;
+ while (len > 0) {
+ if (m == 0) {
+ if (next == 0)
+ panic("sbdrop");
+ m = next;
+ next = m->m_nextpkt;
+ continue;
+ }
+ if (m->m_len > len) {
+ m->m_len -= len;
+ m->m_data += len;
+ sb->sb_cc -= len;
+ break;
+ }
+ len -= m->m_len;
+ sbfree(sb, m);
+ MFREE(m, mn);
+ m = mn;
+ }
+ while (m && m->m_len == 0) {
+ sbfree(sb, m);
+ MFREE(m, mn);
+ m = mn;
+ }
+ if (m) {
+ sb->sb_mb = m;
+ m->m_nextpkt = next;
+ } else
+ sb->sb_mb = next;
+}
+
+/*
+ * Drop a record off the front of a sockbuf
+ * and move the next record to the front.
+ */
+void
+sbdroprecord(sb)
+ register struct sockbuf *sb;
+{
+ register struct mbuf *m, *mn;
+
+ m = sb->sb_mb;
+ if (m) {
+ sb->sb_mb = m->m_nextpkt;
+ do {
+ sbfree(sb, m);
+ MFREE(m, mn);
+ m = mn;
+ } while (m);
+ }
+}
+
+/*
+ * Create a "control" mbuf containing the specified data
+ * with the specified type for presentation on a socket buffer.
+ */
+struct mbuf *
+sbcreatecontrol(p, size, type, level)
+ caddr_t p;
+ register int size;
+ int type, level;
+{
+ register struct cmsghdr *cp;
+ struct mbuf *m;
+
+ if ((m = m_get(M_DONTWAIT, MT_CONTROL)) == NULL)
+ return ((struct mbuf *) NULL);
+ cp = mtod(m, struct cmsghdr *);
+ /* XXX check size? */
+ (void)memcpy(CMSG_DATA(cp), p, size);
+ size += sizeof(*cp);
+ m->m_len = size;
+ cp->cmsg_len = size;
+ cp->cmsg_level = level;
+ cp->cmsg_type = type;
+ return (m);
+}
+
+#ifdef PRU_OLDSTYLE
+/*
+ * The following routines mediate between the old-style `pr_usrreq'
+ * protocol implementations and the new-style `struct pr_usrreqs'
+ * calling convention.
+ */
+
+/* syntactic sugar */
+#define nomb (struct mbuf *)0
+
+static int
+old_abort(struct socket *so)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_ABORT, nomb, nomb, nomb);
+}
+
+static int
+old_accept(struct socket *so, struct mbuf *nam)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_ACCEPT, nomb, nam, nomb);
+}
+
+static int
+old_attach(struct socket *so, int proto)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_ATTACH, nomb,
+ (struct mbuf *)proto, /* XXX */
+ nomb);
+}
+
+static int
+old_bind(struct socket *so, struct mbuf *nam)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_BIND, nomb, nam, nomb);
+}
+
+static int
+old_connect(struct socket *so, struct mbuf *nam)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_CONNECT, nomb, nam, nomb);
+}
+
+static int
+old_connect2(struct socket *so1, struct socket *so2)
+{
+ return so1->so_proto->pr_ousrreq(so1, PRU_CONNECT2, nomb,
+ (struct mbuf *)so2, nomb);
+}
+
+static int
+old_control(struct socket *so, int cmd, caddr_t data, struct ifnet *ifp)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_CONTROL, (struct mbuf *)cmd,
+ (struct mbuf *)data,
+ (struct mbuf *)ifp);
+}
+
+static int
+old_detach(struct socket *so)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_DETACH, nomb, nomb, nomb);
+}
+
+static int
+old_disconnect(struct socket *so)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_DISCONNECT, nomb, nomb, nomb);
+}
+
+static int
+old_listen(struct socket *so)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_LISTEN, nomb, nomb, nomb);
+}
+
+static int
+old_peeraddr(struct socket *so, struct mbuf *nam)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_PEERADDR, nomb, nam, nomb);
+}
+
+static int
+old_rcvd(struct socket *so, int flags)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_RCVD, nomb,
+ (struct mbuf *)flags, /* XXX */
+ nomb);
+}
+
+static int
+old_rcvoob(struct socket *so, struct mbuf *m, int flags)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_RCVOOB, m,
+ (struct mbuf *)flags, /* XXX */
+ nomb);
+}
+
+static int
+old_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *addr,
+ struct mbuf *control)
+{
+ int req;
+
+ if (flags & PRUS_OOB) {
+ req = PRU_SENDOOB;
+ } else if(flags & PRUS_EOF) {
+ req = PRU_SEND_EOF;
+ } else {
+ req = PRU_SEND;
+ }
+ return so->so_proto->pr_ousrreq(so, req, m, addr, control);
+}
+
+static int
+old_sense(struct socket *so, struct stat *sb)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_SENSE, (struct mbuf *)sb,
+ nomb, nomb);
+}
+
+static int
+old_shutdown(struct socket *so)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_SHUTDOWN, nomb, nomb, nomb);
+}
+
+static int
+old_sockaddr(struct socket *so, struct mbuf *nam)
+{
+ return so->so_proto->pr_ousrreq(so, PRU_SOCKADDR, nomb, nam, nomb);
+}
+
+struct pr_usrreqs pru_oldstyle = {
+ old_abort, old_accept, old_attach, old_bind, old_connect,
+ old_connect2, old_control, old_detach, old_disconnect,
+ old_listen, old_peeraddr, old_rcvd, old_rcvoob, old_send,
+ old_sense, old_shutdown, old_sockaddr
+};
+
+#endif /* PRU_OLDSTYLE */
+
+/*
+ * Some routines that return EOPNOTSUPP for entry points that are not
+ * supported by a protocol. Fill in as needed.
+ */
+int
+pru_accept_notsupp(struct socket *so, struct mbuf *nam)
+{
+ return EOPNOTSUPP;
+}
+
+int
+pru_connect2_notsupp(struct socket *so1, struct socket *so2)
+{
+ return EOPNOTSUPP;
+}
+
+int
+pru_control_notsupp(struct socket *so, int cmd, caddr_t data,
+ struct ifnet *ifp)
+{
+ return EOPNOTSUPP;
+}
+
+int
+pru_listen_notsupp(struct socket *so)
+{
+ return EOPNOTSUPP;
+}
+
+int
+pru_rcvd_notsupp(struct socket *so, int flags)
+{
+ return EOPNOTSUPP;
+}
+
+int
+pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags)
+{
+ return EOPNOTSUPP;
+}
+
+/*
+ * This isn't really a ``null'' operation, but it's the default one
+ * and doesn't do anything destructive.
+ */
+int
+pru_sense_null(struct socket *so, struct stat *sb)
+{
+ sb->st_blksize = so->so_snd.sb_hiwat;
+ return 0;
+}
diff --git a/cpukit/libnetworking/lib/README b/cpukit/libnetworking/lib/README
new file mode 100644
index 0000000000..998bd5e708
--- /dev/null
+++ b/cpukit/libnetworking/lib/README
@@ -0,0 +1,5 @@
+#
+# $Id$
+#
+
+Sources from application-level (as opposed to kernel-level) libraries.
diff --git a/cpukit/libnetworking/lib/ftpfs.c b/cpukit/libnetworking/lib/ftpfs.c
new file mode 100644
index 0000000000..ea71eae395
--- /dev/null
+++ b/cpukit/libnetworking/lib/ftpfs.c
@@ -0,0 +1,1160 @@
+/*
+ * File Transfer Protocol client
+ *
+ * Transfer file to/from remote host
+ *
+ * This driver can be added to the RTEMS file system with a call to
+ * "rtems_bsdnet_initialize_ftp_filesystem () ".
+ * From then on, you can open, read and close files on a remote FTP server
+ * using the following syntax:
+ * To open a file "myfile.txt" in the directory "mydir" (relative to home
+ * directory) on a server named "myserver" using the user id
+ * "myuserid" and the password "my_very_secret_password" you must
+ * specify the following path:
+ *
+ * /FTP/myuserid:my_very_secret_password/@myserver/mydirectory/myfile.txt
+ *
+ * If the server is the default server specified in BOOTP, it can be ommitted:
+ *
+ * /FTP/myuserid:my_very_secret_password/mydirectory/myfile.txt
+ *
+ * WARNING: write accesses have not yet been tested.
+ *
+ *
+ * (c) Copyright 2002
+ * Thomas Doerfler
+ * IMD Ingenieurbuero fuer Microcomputertechnik
+ * Herbststr. 8
+ * 82178 Puchheim, Germany
+ * <Thomas.Doerfler@imd-systems.de>
+ *
+ * This code has been created after closly inspecting
+ * "tftpdriver.c" from Eric Norum.
+ *
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/rtems_bsdnet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <rtems/ftpfs.h>
+
+
+#ifndef set_errno_and_return_minus_one
+#define set_errno_and_return_minus_one( _error ) \
+ do { errno = (_error); return -1; } while(0)
+#endif
+
+/* #define DEBUG_OUT */
+
+/*
+ * Well-known port for FTP
+ */
+#define FTP_PORT_NUM 21
+
+/*
+ * Pathname prefix
+ */
+#define FTP_PATHNAME_PREFIX "/FTP/"
+/*
+ * reply codes
+ */
+#define FTP_REPLY_CONNECT 220 /* Connection established */
+#define FTP_REPLY_PASSREQ 331 /* user ok, password required */
+#define FTP_REPLY_LOGIN 230 /* login finished */
+#define FTP_REPLY_SUCCESS 200 /* xxx successful */
+#define FTP_REPLY_OPENCONN 150 /* opening connection for tfer */
+#define FTP_REPLY_TFERCMPL 226 /* transfer complete */
+
+extern rtems_filesystem_operations_table rtems_ftp_ops;
+extern rtems_filesystem_file_handlers_r rtems_ftp_handlers;
+
+/*
+ * FTP command strings
+ */
+#define FTP_USER_CMD "USER "
+#define FTP_PASS_CMD "PASS "
+#define FTP_BINARY_CMD "TYPE I"
+#define FTP_PORT_CMD "PORT "
+#define FTP_STOR_CMD "STOR "
+#define FTP_RETR_CMD "RETR "
+#define FTP_QUIT_CMD "QUIT"
+
+/*
+ * State of each FTP stream
+ */
+struct ftpStream {
+ /*
+ * Control connection socket
+ */
+ int ctrl_socket;
+ struct sockaddr_in myCtrlAddress;
+ struct sockaddr_in farCtrlAddress;
+ /*
+ * Data transfer socket
+ */
+ int port_socket;
+ int data_socket;
+ struct sockaddr_in myDataAddress;
+ struct sockaddr_in farDataAddress;
+ /*
+ * other stuff to remember
+ */
+ boolean eof_reached;
+};
+
+/*
+ * Number of streams open at the same time
+ */
+static rtems_id ftp_mutex;
+static int nStreams;
+static struct ftpStream ** volatile ftpStreams;
+
+extern rtems_filesystem_operations_table rtems_tftp_ops;
+extern rtems_filesystem_file_handlers_r rtems_tftp_handlers;
+
+/*
+ * Direct copy from the IMFS/TFTP. Look at this.
+ */
+
+rtems_filesystem_limits_and_options_t rtems_ftp_limits_and_options = {
+ 5, /* link_max */
+ 6, /* max_canon */
+ 7, /* max_input */
+ 255, /* name_max */
+ 255, /* path_max */
+ 2, /* pipe_buf */
+ 1, /* posix_async_io */
+ 2, /* posix_chown_restrictions */
+ 3, /* posix_no_trunc */
+ 4, /* posix_prio_io */
+ 5, /* posix_sync_io */
+ 6 /* posix_vdisable */
+};
+
+int rtems_ftp_mount_me(
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry
+)
+{
+ rtems_status_code sc;
+
+ temp_mt_entry->mt_fs_root.handlers = &rtems_ftp_handlers;
+ temp_mt_entry->mt_fs_root.ops = &rtems_ftp_ops;
+
+ /*
+ * We have no ftp filesystem specific data to maintain. This
+ * filesystem may only be mounted ONCE.
+ *
+ * And we maintain no real filesystem nodes, so there is no real root.
+ */
+
+ temp_mt_entry->fs_info = NULL;
+ temp_mt_entry->mt_fs_root.node_access = NULL;
+
+ /*
+ * These need to be looked at for full POSIX semantics.
+ */
+
+ temp_mt_entry->pathconf_limits_and_options = rtems_ftp_limits_and_options;
+
+
+ /*
+ * Now allocate a semaphore for mutual exclusion.
+ *
+ * NOTE: This could be in an fsinfo for this filesystem type.
+ */
+
+ sc = rtems_semaphore_create (rtems_build_name('F','T','P',' '),
+ 1,
+ RTEMS_FIFO |
+ RTEMS_BINARY_SEMAPHORE |
+ RTEMS_NO_INHERIT_PRIORITY |
+ RTEMS_NO_PRIORITY_CEILING |
+ RTEMS_LOCAL,
+ 0,
+ &ftp_mutex);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one( ENOMEM );
+
+ return 0;
+}
+
+/*
+ * Initialize the FTP driver
+ */
+
+int rtems_bsdnet_initialize_ftp_filesystem ()
+{
+ int status;
+ rtems_filesystem_mount_table_entry_t *entry;
+
+ status = mkdir( FTP_PATHNAME_PREFIX, S_IRWXU | S_IRWXG | S_IRWXO );
+ if ( status == -1 )
+ return status;
+
+ status = mount(
+ &entry,
+ &rtems_ftp_ops,
+ RTEMS_FILESYSTEM_READ_ONLY,
+ NULL,
+ FTP_PATHNAME_PREFIX
+ );
+
+ if ( status )
+ perror( "FTP mount failed" );
+
+ return status;
+}
+
+/*
+ * read and return message code from ftp control connection
+ */
+int rtems_ftp_get_message
+(
+ const struct ftpStream *fsp, /* ptr to ftp control structure */
+ int *msg_code /* ptr to return message code */
+)
+{
+ char rd_buffer[4];
+ size_t rd_size;
+ size_t tmp_size;
+ int eno = 0;
+ rtems_boolean finished = FALSE;
+ do {
+ /*
+ * fetch (at least) 4 characters from control connection
+ * FIXME: how about a timeout?
+ */
+ rd_size = 0;
+ while ((eno == 0) &&
+ (rd_size < sizeof(rd_buffer))) {
+ tmp_size = read(fsp->ctrl_socket,
+ (&rd_buffer)+rd_size,
+ sizeof(rd_buffer)-rd_size);
+ if (tmp_size < 0) {
+ eno = EIO;
+ }
+ else {
+#ifdef DEBUG_OUT
+ write(1,(&rd_buffer)+rd_size,tmp_size);
+#endif
+ rd_size += tmp_size;
+ }
+ }
+ /*
+ * check for 3 digits and space, otherwise not finished
+ */
+ if ((eno == 0) &&
+ (isdigit((unsigned int)rd_buffer[0])) &&
+ (isdigit((unsigned int)rd_buffer[1])) &&
+ (isdigit((unsigned int)rd_buffer[2])) &&
+ (rd_buffer[3] == ' ')) {
+ finished = TRUE;
+ rd_buffer[3] = '\0';
+ *msg_code = atol(rd_buffer);
+ }
+ /*
+ * skip rest until end-of-line
+ */
+ do {
+ tmp_size = read(fsp->ctrl_socket,
+ &rd_buffer,
+ 1);
+ if (tmp_size < 0) {
+ eno = EIO;
+ }
+#ifdef DEBUG_OUT
+ else {
+ write(1,(&rd_buffer),tmp_size);
+ }
+#endif
+ } while ((eno == 0) &&
+ (rd_buffer[0] != '\n'));
+ } while ((eno == 0) && !finished);
+ return eno;
+}
+
+/*
+ * split a pseudo file name into host, user, password, filename
+ * NOTE: this function will allocate space for these strings,
+ * the calling function should free the space, when no longer needed
+ * exception: when we return any error, we will also cleanup
+ * the strings
+ * valid forms:
+ * /FTP/user:pass/filepath
+ * /FTP/user:pass@hostname/filepath
+
+ * /FTP/user:pass/filepath
+ * /FTP/user:pass/@hostname/filepath
+ * NOTE: /FTP is already stripped from the name
+ */
+int rtems_ftp_split_names
+( const char *pathname, /* total path name (including prefix) */
+ char **usernamep, /* ptr to ptr to user name */
+ char **passwordp, /* ptr to ptr to password */
+ char **hostnamep, /* ptr to ptr to host name */
+ char **filenamep) /* ptr to ptr to hostremaining file name */
+{
+ const char *chunk_start;
+ const char *chunk_end;
+ size_t chunk_len;
+ int rc = 0;
+
+ /*
+ * ensure, that result pointers are NULL...
+ */
+ *usernamep = NULL;
+ *passwordp = NULL;
+ *hostnamep = NULL;
+ *filenamep = NULL;
+
+#if 1
+ chunk_start = pathname;
+#else /* no longer needed with IMFS */
+ /*
+ * check, that total path is long enough, skip prefix
+ */
+ if (rc == 0) {
+ if (strlen (pathname) <= strlen (FTP_PATHNAME_PREFIX)) {
+ rc = ENOENT;
+ }
+ else {
+ chunk_start = pathname + strlen (FTP_PATHNAME_PREFIX);
+ }
+ }
+#endif
+ /*
+ * fetch user name: terminated with ":"
+ */
+ if (rc == 0) {
+ chunk_end = strchr(chunk_start,':');
+ if ((chunk_end == NULL) || /* No ':' found or */
+ (chunk_end == chunk_start)) { /* ':' is first character-> no name */
+ rc = ENOENT;
+ }
+ else {
+ chunk_len = chunk_end-chunk_start;
+ *usernamep = malloc(chunk_len+1);
+ if (*usernamep == NULL) {
+ rc = ENOMEM;
+ }
+ else {
+ memcpy(*usernamep,chunk_start,chunk_len);
+ (*usernamep)[chunk_len] = '\0';
+ }
+ }
+ }
+ /*
+ * fetch password: terminated with "/" or "@"
+ */
+ if (rc == 0) {
+ chunk_start = chunk_end + 1; /* skip ":" after user name */
+ chunk_end = strchr(chunk_start,'/');
+ if ((chunk_end == NULL) || /* No '/' found or */
+ (chunk_end == chunk_start)) { /* '/' is first character-> no pwd */
+ rc = ENOENT;
+ }
+ else {
+ /*
+ * we have found a proper '/'
+ * this is the end of the password
+ */
+ chunk_len = chunk_end-chunk_start;
+ *passwordp = malloc(chunk_len+1);
+ if (*passwordp == NULL) {
+ rc = ENOMEM;
+ }
+ else {
+ memcpy(*passwordp,chunk_start,chunk_len);
+ (*passwordp)[chunk_len] = '\0';
+ }
+ }
+ }
+ /*
+ * if first char after '/' is '@', then this is the hostname
+ * fetch hostname terminated with "/"
+ * if exists at all. otherwise take default server from bootp
+ */
+ if (rc == 0) {
+ chunk_start = chunk_end+1;
+ if (*chunk_start == '@') {
+ /*
+ * hostname follows
+ */
+ chunk_start = chunk_start + 1; /* skip "@" after password */
+ chunk_end = strchr(chunk_start,'/');
+ if ((chunk_end == NULL) || /* No '/' found or */
+ (chunk_end == chunk_start)) { /* '/' is first character-> no host */
+ rc = ENOENT;
+ }
+ else {
+ /*
+ * we have found a proper '/'
+ */
+ chunk_len = chunk_end-chunk_start;
+ *hostnamep = malloc(chunk_len+1);
+ if (*hostnamep == NULL) {
+ rc = ENOMEM;
+ }
+ else {
+ memcpy(*hostnamep,chunk_start,chunk_len);
+ (*hostnamep)[chunk_len] = '\0';
+ }
+ }
+ }
+ else { /* chunk_start != '@' */
+ /*
+ * no host name given, keep string empty
+ */
+ *hostnamep = malloc(1);
+ if (*hostnamep == NULL) {
+ rc = ENOMEM;
+ }
+ else {
+ (*hostnamep)[0] = '\0';
+ }
+ }
+ }
+ /*
+ * fetch filename. This is all the rest...
+ */
+ if (rc == 0) {
+ chunk_start = chunk_end+1;
+ if (*chunk_start == '\0') { /* nothing left for filename */
+ rc = ENOENT;
+ }
+ else {
+ chunk_len = strlen(chunk_start);
+ *filenamep = malloc(chunk_len+1);
+ if (*filenamep == NULL) {
+ rc = ENOMEM;
+ }
+ else {
+ memcpy(*filenamep,chunk_start,chunk_len);
+ (*filenamep)[chunk_len] = '\0';
+ }
+ }
+ }
+
+ /*
+ * cleanup anything, if error occured
+ */
+ if (rc != 0) {
+ if (*hostnamep != NULL) {
+ free(*hostnamep);
+ *hostnamep = NULL;
+ }
+ if (*usernamep != NULL) {
+ free(*usernamep);
+ *usernamep = NULL;
+ }
+ if (*passwordp != NULL) {
+ free(*passwordp);
+ *passwordp = NULL;
+ }
+ if (*filenamep != NULL) {
+ free(*filenamep);
+ *filenamep = NULL;
+ }
+ }
+ return rc;
+}
+
+int rtems_ftp_evaluate_for_make(
+ const char *path, /* IN */
+ rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
+ const char **name /* OUT */
+)
+{
+ set_errno_and_return_minus_one( EIO );
+}
+
+/*
+ * XXX - Fix return values.
+ */
+
+int rtems_ftp_eval_path(
+ const char *pathname, /* IN */
+ int flags, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+)
+{
+
+ /*
+ * Read-only for now
+ */
+
+ if ( ((flags & O_RDONLY) != O_RDONLY ) &&
+ ((flags & O_WRONLY) != O_WRONLY )) {
+ set_errno_and_return_minus_one( ENOENT );
+ }
+ /*
+ * The File system is mounted at FTP_PATHNAME_PREFIX
+ * the caller of this routine has striped off this part of the
+ * name. Save the remainder of the name for use by the open routine.
+ */
+
+ pathloc->node_access = (void * ) pathname;
+ pathloc->handlers = &rtems_ftp_handlers;
+
+ return 0;
+}
+
+/*
+ * Open a FTP stream
+ */
+int rtems_ftp_open(
+ rtems_libio_t *iop,
+ const char *new_name,
+ uint32_t flag,
+ uint32_t mode
+)
+{
+ int s = 0;
+ char *filename = NULL;
+ char *uname = NULL;
+ char *upass = NULL;
+ char *hostname = NULL;
+ char port_buffer[sizeof(FTP_PORT_CMD)+6*4+1+1];
+ uint32_t my_ip;
+ uint16_t my_port;
+ int eno = 0;
+ rtems_status_code rc;
+ rtems_boolean is_write = FALSE;
+ rtems_boolean sema_obtained = FALSE;
+ struct ftpStream *fsp = NULL;
+ int msg_tmp = 0;
+ socklen_t sockaddr_size;
+ /*
+ * check for R/O or W/O flags
+ */
+ if (eno == 0) {
+ if ((0 != (iop->flags & LIBIO_FLAGS_WRITE)) &&
+ (0 != (iop->flags & LIBIO_FLAGS_READ))) {
+ eno = ENOTSUP;
+ }
+ else {
+ is_write = (0 != (iop->flags & LIBIO_FLAGS_WRITE));
+ }
+ }
+ /*
+ * split pathname into parts
+ */
+ if (eno == 0) {
+ eno = rtems_ftp_split_names(iop->file_info,
+ &uname,
+ &upass,
+ &hostname,
+ &filename);
+ }
+
+ /*
+ * Find a free stream
+ */
+ if (eno == 0) {
+ rc = rtems_semaphore_obtain (ftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (rc == RTEMS_SUCCESSFUL) {
+ sema_obtained = TRUE;
+ }
+ else {
+ eno = EBUSY;
+ }
+ }
+ if (eno == 0) {
+ for (s = 0 ; s < nStreams ; s++) {
+ if (ftpStreams[s] == NULL)
+ break;
+ }
+ if (s == nStreams) {
+ /*
+ * Reallocate stream pointers
+ * Guard against the case where realloc() returns NULL.
+ */
+ struct ftpStream **np;
+
+ np = realloc (ftpStreams, ++nStreams * sizeof *ftpStreams);
+ if (np == NULL) {
+ eno = ENOMEM;
+ }
+ else {
+ ftpStreams = np;
+ }
+ }
+ }
+ if (eno == 0) {
+ fsp = ftpStreams[s] = malloc (sizeof (struct ftpStream));
+ rtems_semaphore_release (ftp_mutex);
+ sema_obtained = FALSE;
+ if (fsp == NULL) {
+ eno = ENOMEM;
+ }
+ else {
+ iop->data0 = s;
+ iop->data1 = fsp;
+ fsp->ctrl_socket = -1; /* mark, that sockets not yet created */
+ fsp->port_socket = -1;
+ fsp->data_socket = -1;
+ fsp->eof_reached = FALSE;
+ }
+ }
+ if (eno == 0) {
+ /*
+ * Create the socket for control connection
+ */
+ if ((fsp->ctrl_socket = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
+ eno = ENOMEM;
+ }
+ }
+
+ if (eno == 0) {
+ /*
+ * Set the destination to the FTP server
+ * port on the remote machine.
+ */
+ memset(&(fsp->farCtrlAddress),sizeof(fsp->farCtrlAddress),0);
+ fsp->farCtrlAddress.sin_family = AF_INET;
+ if (*hostname == '\0') {
+ fsp->farCtrlAddress.sin_addr.s_addr = rtems_bsdnet_bootp_server_address.s_addr;
+ }
+ else if (1 != inet_aton(hostname,&(fsp->farCtrlAddress.sin_addr))) {
+ struct hostent *hent;
+ struct hostent *gethostbyname(const char *name);
+
+ hent = gethostbyname(hostname);
+ if (hent != NULL) {
+ memcpy(&fsp->farCtrlAddress.sin_addr,
+ hent->h_addr,
+ sizeof(fsp->farCtrlAddress.sin_addr));
+ }
+ else {
+ eno = ENOENT;
+ }
+ }
+ if (eno == 0) {
+ fsp->farCtrlAddress.sin_port = htons (FTP_PORT_NUM);
+ fsp->farCtrlAddress.sin_len = sizeof(fsp->farCtrlAddress);
+ if (0 > connect(fsp->ctrl_socket,
+ (struct sockaddr *)&(fsp->farCtrlAddress),
+ sizeof(fsp->farCtrlAddress))) {
+ eno = ENOENT;
+ }
+ }
+ if (eno == 0) {
+ /*
+ * fetch IP address of interface used
+ */
+ memset(&(fsp->myCtrlAddress),sizeof(fsp->myCtrlAddress),0);
+ fsp->myCtrlAddress.sin_family = AF_INET;
+ fsp->myCtrlAddress.sin_addr.s_addr = INADDR_ANY;
+ fsp->myCtrlAddress.sin_port = 0;
+ fsp->myCtrlAddress.sin_len = sizeof(fsp->myDataAddress);
+ sockaddr_size = sizeof(fsp->myCtrlAddress);
+ if (0 > getsockname(fsp->ctrl_socket,
+ (struct sockaddr *)&(fsp->myCtrlAddress),
+ &sockaddr_size)) {
+ eno = ENOMEM;
+ }
+ }
+ }
+ if (eno == 0) {
+ /*
+ * now we should get a connect message from the FTP server
+ */
+ eno = rtems_ftp_get_message(fsp,&msg_tmp);
+ if ((eno == 0) &&
+ (msg_tmp != FTP_REPLY_CONNECT)) {
+ eno = ENOENT;
+ }
+ }
+ if (eno == 0) {
+ /*
+ * send user ID to server
+ * NOTE: the following lines will be executed in order
+ * and will be aborted whenever an error occures... (see your ANSI C book)
+ */
+ if ((0 > send(fsp->ctrl_socket,FTP_USER_CMD,strlen(FTP_USER_CMD),0)) ||
+ (0 > send(fsp->ctrl_socket,uname, strlen(uname), 0)) ||
+ (0 > send(fsp->ctrl_socket,"\n", 1, 0))) {
+ eno = EIO;
+ }
+ }
+ if (eno == 0) {
+ /*
+ * now we should get a request for the password or a login...
+ */
+ eno = rtems_ftp_get_message(fsp,&msg_tmp);
+ if (eno == 0) {
+ if (msg_tmp == FTP_REPLY_PASSREQ) {
+ /*
+ * send password to server
+ */
+#ifdef DEBUG_OUT
+ write(1,FTP_PASS_CMD,strlen(FTP_PASS_CMD));
+ write(1,upass, strlen(upass) );
+ write(1,"\n", 1 );
+#endif
+ if ((0 > send(fsp->ctrl_socket,FTP_PASS_CMD,strlen(FTP_PASS_CMD),0)) ||
+ (0 > send(fsp->ctrl_socket,upass, strlen(upass), 0)) ||
+ (0 > send(fsp->ctrl_socket,"\n", 1, 0))) {
+ eno = EIO;
+ }
+ /*
+ * at least now a login reply should come up...
+ * this is checked some lines downwards the code
+ */
+ if (eno == 0) {
+ eno = rtems_ftp_get_message(fsp,&msg_tmp);
+ }
+ }
+ }
+ }
+ if (eno == 0) {
+ /*
+ * check for a login reply. this should be present now...
+ */
+ if (msg_tmp != FTP_REPLY_LOGIN) {
+ eno = EACCES; /* pseudo for wrong user/pass */
+ }
+ }
+ if (eno == 0) {
+ /*
+ * set binary mode for all transfers
+ */
+#ifdef DEBUG_OUT
+ write(1,FTP_BINARY_CMD,strlen(FTP_BINARY_CMD));
+ write(1,"\n", 1 );
+#endif
+ if ((0 > send(fsp->ctrl_socket,FTP_BINARY_CMD,strlen(FTP_BINARY_CMD),0)) ||
+ (0 > send(fsp->ctrl_socket,"\n", 1, 0))) {
+ eno = EIO;
+ }
+ else {
+ eno = rtems_ftp_get_message(fsp,&msg_tmp);
+ }
+ }
+ if (eno == 0) {
+ /*
+ * check for a "BINARY TYPE command successful" reply
+ */
+ if (msg_tmp != FTP_REPLY_SUCCESS) {
+ eno = EIO;
+ }
+ }
+ if (eno == 0) {
+ /*
+ * create and bind socket for data connection
+ */
+ if ((fsp->port_socket = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
+ eno = ENOMEM;
+ }
+ else {
+ memset(&(fsp->myDataAddress),sizeof(fsp->myDataAddress),0);
+ fsp->myDataAddress.sin_family = AF_INET;
+ fsp->myDataAddress.sin_addr.s_addr = INADDR_ANY;
+ fsp->myDataAddress.sin_port = 0; /* unique port will be assigned */
+ fsp->myDataAddress.sin_len = sizeof(fsp->myDataAddress);
+ if (0 > bind(fsp->port_socket,
+ (struct sockaddr *)&(fsp->myDataAddress),
+ sizeof(fsp->myDataAddress))) {
+ eno = EBUSY;
+ }
+ else {
+ /*
+ * fetch port number of data socket
+ */
+ memset(&(fsp->myDataAddress),sizeof(fsp->myDataAddress),0);
+ fsp->myDataAddress.sin_family = AF_INET;
+ fsp->myDataAddress.sin_addr.s_addr = INADDR_ANY;
+ fsp->myDataAddress.sin_port = 0;
+ fsp->myDataAddress.sin_len = sizeof(fsp->myDataAddress);
+ sockaddr_size = sizeof(fsp->myDataAddress);
+ if (0 > getsockname(fsp->port_socket,
+ (struct sockaddr *)&(fsp->myDataAddress),
+ &sockaddr_size)) {
+ eno = ENOMEM;
+ }
+ }
+ }
+ }
+ if (eno == 0) {
+ /*
+ * propagate data connection port to server
+ */
+ my_ip = ntohl(fsp->myCtrlAddress.sin_addr.s_addr);
+ my_port = ntohs(fsp->myDataAddress.sin_port);
+ sprintf(port_buffer,"%s%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu16 ",%" PRIu16 "\n",
+ FTP_PORT_CMD,
+ (my_ip >> 24) & 0x00ff,
+ (my_ip >> 16) & 0x00ff,
+ (my_ip >> 8) & 0x00ff,
+ (my_ip >> 0) & 0x00ff,
+ (my_port>> 8) & 0x00ff,
+ (my_port>> 0) & 0x00ff);
+#ifdef DEBUG_OUT
+ write(1,port_buffer,strlen(port_buffer));
+#endif
+ if (0 > send(fsp->ctrl_socket,port_buffer,strlen(port_buffer),0)) {
+ eno = EIO;
+ }
+ else {
+ eno = rtems_ftp_get_message(fsp,&msg_tmp);
+ }
+ }
+ if (eno == 0) {
+ /*
+ * check for a "PORT command successful" reply
+ */
+ if (msg_tmp != FTP_REPLY_SUCCESS) {
+ eno = EBUSY;
+ }
+ }
+ /*
+ * prepare port socket to listen for incoming connections
+ */
+ if (eno == 0) {
+ if (0 > listen(fsp->port_socket,1)) {
+ eno = EBUSY;
+ }
+ }
+ if (eno == 0) {
+ /*
+ * send retrive/store command with filename
+ */
+ if (is_write) {
+#ifdef DEBUG_OUT
+ write(1,FTP_STOR_CMD,strlen(FTP_STOR_CMD));
+ write(1,filename ,strlen(filename) );
+ write(1,"\n",1);
+#endif
+ if ((0 > send(fsp->ctrl_socket,FTP_STOR_CMD,strlen(FTP_STOR_CMD),0)) ||
+ (0 > send(fsp->ctrl_socket,filename, strlen(filename), 0)) ||
+ (0 > send(fsp->ctrl_socket,"\n", 1, 0))) {
+ eno = EIO;
+ }
+ }
+ else {
+#ifdef DEBUG_OUT
+ write(1,FTP_RETR_CMD,strlen(FTP_RETR_CMD));
+ write(1,filename ,strlen(filename) );
+ write(1,"\n",1);
+#endif
+ if ((0 > send(fsp->ctrl_socket,FTP_RETR_CMD,strlen(FTP_RETR_CMD),0)) ||
+ (0 > send(fsp->ctrl_socket,filename, strlen(filename), 0)) ||
+ (0 > send(fsp->ctrl_socket,"\n", 1, 0))) {
+ eno = EIO;
+ }
+ }
+ }
+#if 1
+ if (eno == 0) {
+ eno = rtems_ftp_get_message(fsp,&msg_tmp);
+ }
+ if (eno == 0) {
+ /*
+ * check for a "OPENING binary connection" reply
+ */
+ if (msg_tmp != FTP_REPLY_OPENCONN) {
+ eno = EACCES;
+ }
+ }
+#endif
+ /*
+ * wait for connect on data connection
+ * FIXME: this should become a select instead with a timeout
+ */
+ if (eno == 0) {
+ sockaddr_size = sizeof(fsp->farDataAddress);
+ fsp->data_socket = accept(fsp->port_socket,
+ (struct sockaddr *)&(fsp->farDataAddress),
+ &sockaddr_size);
+ if (0 > fsp->data_socket) {
+ eno = EIO;
+ }
+ }
+ /*
+ * FIXME: check, that fardataAddr is really from our ftp server
+ */
+
+ /*
+ * clean up temp strings...
+ */
+ if (uname != NULL) {
+ free(uname);
+ uname = NULL;
+ }
+ if (upass != NULL) {
+ free(upass);
+ upass = NULL;
+ }
+ if (hostname != NULL) {
+ free(hostname);
+ hostname = NULL;
+ }
+ if (filename != NULL) {
+ free(filename);
+ filename = NULL;
+ }
+ /*
+ * close part socket, no longer needed
+ */
+ if (fsp->port_socket != -1) {
+ close(fsp->port_socket);
+ fsp->port_socket = -1;
+ }
+ /*
+ * if error, clean up everything
+ */
+ if (eno != 0) {
+ if (fsp != NULL) {
+ /*
+ * check and close ctrl/data connection
+ */
+ if (fsp->data_socket != -1) {
+ close(fsp->data_socket);
+ fsp->data_socket = -1;
+ }
+ if (fsp->ctrl_socket != -1) {
+ close(fsp->ctrl_socket);
+ fsp->ctrl_socket = -1;
+ }
+ /*
+ * free ftpStream structure
+ */
+ ftpStreams[s] = NULL;
+ free(fsp);
+ fsp = NULL;
+ }
+ }
+ /*
+ * return sema, if still occupied
+ */
+ if (sema_obtained) {
+ rtems_semaphore_release (ftp_mutex);
+ sema_obtained = FALSE;
+ }
+#if 0
+ if (eno != 0) {
+ set_errno_and_return_minus_one(eno);
+ }
+ return 0;
+#else
+ return eno;
+#endif
+}
+
+/*
+ * Read from a FTP stream
+ */
+ssize_t rtems_ftp_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ uint32_t count
+)
+{
+ int eno = 0;
+ struct ftpStream *fsp;
+ size_t want_cnt;
+ ssize_t rd_cnt;
+ int msg_tmp = 0;
+
+ fsp = iop->data1;
+ want_cnt = count;
+ /*
+ * check, that data connection present
+ */
+ if (eno == 0) {
+ if ((fsp == NULL) ||
+ (fsp->data_socket < 0)) {
+ eno = EBADF;
+ }
+ }
+
+ /*
+ * perform read from data socket
+ * read multiple junks, if smaller than wanted
+ */
+ while ((eno == 0) &&
+ (want_cnt > 0) &&
+ !(fsp->eof_reached) ) {
+ rd_cnt = read(fsp->data_socket,buffer,want_cnt);
+ if (rd_cnt > 0) {
+ buffer += rd_cnt;
+ want_cnt -= rd_cnt;
+ }
+ else {
+ eno = rtems_ftp_get_message(fsp,&msg_tmp);
+ fsp->eof_reached = TRUE;
+ if ((eno == 0) &&
+ (msg_tmp != FTP_REPLY_TFERCMPL)) {
+ eno = EIO;
+ }
+ if (rd_cnt < 0) {
+ eno = EIO;
+ }
+ }
+ }
+ if (eno != 0) {
+ set_errno_and_return_minus_one(eno);
+ }
+ return count - want_cnt;
+}
+
+ssize_t rtems_ftp_write(
+ rtems_libio_t *iop,
+ const void *buffer,
+ uint32_t count
+)
+{
+ int eno = EIO;
+ struct ftpStream *fsp;
+ size_t want_cnt;
+ ssize_t wr_cnt;
+ int msg_tmp = 0;
+
+ fsp = iop->data1;
+ want_cnt = count;
+ /*
+ * check, that data connection present
+ */
+ if (eno == 0) {
+ if ((fsp == NULL) ||
+ (fsp->data_socket < 0)) {
+ eno = EBADF;
+ }
+ }
+
+ /*
+ * perform write to data socket
+ */
+ if (eno == 0) {
+ wr_cnt = write(fsp->data_socket,buffer,want_cnt);
+ if (wr_cnt > 0) {
+ buffer += wr_cnt;
+ want_cnt -= wr_cnt;
+ }
+ else {
+ eno = rtems_ftp_get_message(fsp,&msg_tmp);
+ if ((eno == 0) &&
+ (msg_tmp != FTP_REPLY_TFERCMPL)) {
+ eno = EIO;
+ }
+ if (wr_cnt < 0) {
+ eno = EIO;
+ }
+ }
+ }
+ if (eno != 0) {
+ set_errno_and_return_minus_one(eno);
+ }
+ return count - want_cnt;
+}
+
+/*
+ * Close a FTP stream
+ */
+int rtems_ftp_close(
+ rtems_libio_t *iop
+)
+{
+ int s = iop->data0;
+ struct ftpStream *fsp = iop->data1;
+
+ /*
+ * close ctrl/data connection, if needed
+ */
+ if (fsp->data_socket >= 0) {
+ close(fsp->data_socket);
+ fsp->data_socket = -1;
+ }
+ if (fsp->ctrl_socket >= 0) {
+ close(fsp->ctrl_socket);
+ fsp->ctrl_socket = -1;
+ }
+ /*
+ * free any used space...
+ */
+ rtems_semaphore_obtain (ftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ free (ftpStreams[s]);
+ ftpStreams[s] = NULL;
+ rtems_semaphore_release (ftp_mutex);
+
+ return 0;
+}
+
+rtems_device_driver rtems_ftp_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ return RTEMS_NOT_CONFIGURED;
+}
+
+/*
+ * Dummy version to let fopen(xxxx,"w") work properly.
+ */
+static int rtems_ftp_ftruncate(
+ rtems_libio_t *iop,
+ off_t count
+)
+{
+ return 0;
+}
+
+rtems_filesystem_node_types_t rtems_ftp_node_type(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+)
+{
+ return RTEMS_FILESYSTEM_MEMORY_FILE;
+}
+
+rtems_filesystem_operations_table rtems_ftp_ops = {
+ rtems_ftp_eval_path, /* eval_path */
+ rtems_ftp_evaluate_for_make, /* evaluate_for_make */
+ NULL, /* link */
+ NULL, /* unlink */
+ rtems_ftp_node_type, /* node_type */
+ NULL, /* mknod */
+ NULL, /* chown */
+ NULL, /* freenodinfo */
+ NULL, /* mount */
+ rtems_ftp_mount_me, /* initialize */
+ NULL, /* unmount */
+ NULL, /* fsunmount */
+ NULL, /* utime, */
+ NULL, /* evaluate_link */
+ NULL, /* symlink */
+ NULL, /* readlin */
+};
+
+rtems_filesystem_file_handlers_r rtems_ftp_handlers = {
+ rtems_ftp_open, /* open */
+ rtems_ftp_close, /* close */
+ rtems_ftp_read, /* read */
+ rtems_ftp_write, /* write */
+ NULL, /* ioctl */
+ NULL, /* lseek */
+ NULL, /* fstat */
+ NULL, /* fchmod */
+ rtems_ftp_ftruncate, /* ftruncate */
+ NULL, /* fpathconf */
+ NULL, /* fsync */
+ NULL, /* fdatasync */
+ NULL, /* fcntl */
+ NULL /* rmnod */
+};
diff --git a/cpukit/libnetworking/lib/getprotoby.c b/cpukit/libnetworking/lib/getprotoby.c
new file mode 100644
index 0000000000..cefa5c1ff2
--- /dev/null
+++ b/cpukit/libnetworking/lib/getprotoby.c
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ */
+
+#include <netdb.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+static const struct protoent prototab[] = {
+ { "ip", NULL, IPPROTO_IP },
+ { "icmp", NULL, IPPROTO_ICMP },
+ { "tcp", NULL, IPPROTO_TCP },
+ { "udp", NULL, IPPROTO_UDP },
+ };
+
+/*
+ * Dummy version of BSD getprotobyname()
+ */
+struct protoent *
+getprotobyname_static (const char *name)
+{
+ int i;
+
+ for (i = 0 ; i < (sizeof prototab / sizeof prototab[0]) ; i++) {
+ if (strcmp (name, prototab[i].p_name) == 0)
+ return (struct protoent *) &prototab[i];
+ }
+ return NULL;
+}
+
+/*
+ * Dummy version of BSD getprotobynumber()
+ */
+struct protoent *
+getprotobynumber_static (int proto)
+{
+ int i;
+
+ for (i = 0 ; i < (sizeof prototab / sizeof prototab[0]) ; i++) {
+ if (proto == prototab[i].p_proto)
+ return (struct protoent *) &prototab[i];
+ }
+ return NULL;
+}
diff --git a/cpukit/libnetworking/lib/rtems_bsdnet_ntp.c b/cpukit/libnetworking/lib/rtems_bsdnet_ntp.c
new file mode 100644
index 0000000000..3be505a972
--- /dev/null
+++ b/cpukit/libnetworking/lib/rtems_bsdnet_ntp.c
@@ -0,0 +1,213 @@
+/*
+ * Synchronize with an NTP server
+ *
+ * This program may be distributed and used for any purpose.
+ * I ask only that you:
+ * 1. Leave this author information intact.
+ * 2. Document any changes you make.
+ *
+ * W. Eric Norum
+ * Canadian Light Source
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@cls.usask.ca
+ *
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <limits.h>
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/error.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <rtems/bsdnet/servers.h>
+
+/*
+ * RTEMS base: 1988, January 1
+ * UNIX base: 1970, January 1
+ * NTP base: 1900, January 1
+ */
+#define UNIX_BASE_TO_NTP_BASE (((70UL*365UL)+17UL) * (24*60*60))
+
+struct ntpPacket {
+ struct ntpPacketSmall ntp;
+ char authenticator[96];
+};
+
+static int
+processPacket (struct ntpPacketSmall *p, int state, void *unused)
+{
+ time_t tbuf;
+ struct tm *lt;
+ rtems_time_of_day rt;
+ rtems_interval ticks_per_second;
+
+ if ( state )
+ return 0;
+
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
+ tbuf = ntohl (p->transmit_timestamp.integer) - UNIX_BASE_TO_NTP_BASE - rtems_bsdnet_timeoffset;
+ lt = gmtime (&tbuf);
+ rt.year = lt->tm_year + 1900;
+ rt.month = lt->tm_mon + 1;
+ rt.day = lt->tm_mday;
+ rt.hour = lt->tm_hour;
+ rt.minute = lt->tm_min;
+ rt.second = lt->tm_sec;
+ rt.ticks = ntohl (p->transmit_timestamp.fraction) / (ULONG_MAX / ticks_per_second);
+ if (rt.ticks >= ticks_per_second)
+ rt.ticks = ticks_per_second - 1;
+ rtems_clock_set (&rt);
+ return 0;
+}
+
+static int
+getServerTimespec(struct ntpPacketSmall *p, int state, void *usr_data)
+{
+struct timespec *ts = usr_data;
+unsigned long long tmp;
+
+ if ( 0 == state ) {
+ ts->tv_sec = ntohl( p->transmit_timestamp.integer );
+ ts->tv_sec -= rtems_bsdnet_timeoffset + UNIX_BASE_TO_NTP_BASE;
+
+ tmp = 1000000000 * (unsigned long long)ntohl(p->transmit_timestamp.fraction);
+
+ ts->tv_nsec = (unsigned long) (tmp>>32);
+ }
+ return 0;
+}
+
+int rtems_bsdnet_ntp_retry_count = 5;
+int rtems_bsdnet_ntp_timeout_secs = 5;
+int rtems_bsdnet_ntp_bcast_timeout_secs = 80;
+
+static int
+tryServer (int i, int s, rtems_bsdnet_ntp_callback_t callback, void *usr_data)
+{
+ int l = 0;
+ struct timeval tv;
+ socklen_t farlen;
+ struct sockaddr_in farAddr;
+ struct ntpPacketSmall packet;
+
+ if (i < 0)
+ tv.tv_sec = rtems_bsdnet_ntp_bcast_timeout_secs;
+ else
+ tv.tv_sec = rtems_bsdnet_ntp_timeout_secs;
+ tv.tv_usec = 0;
+ if (setsockopt (s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) < 0) {
+ fprintf (stderr, "rtems_bsdnet_get_ntp() Can't set socket receive timeout: %s\n", strerror (errno));
+ close (s);
+ return -1;
+ }
+ if (i >= 0) {
+ memset (&farAddr, 0, sizeof farAddr);
+ farAddr.sin_family = AF_INET;
+ farAddr.sin_port = htons (123);
+ farAddr.sin_addr = rtems_bsdnet_ntpserver[i];
+ memset (&packet, 0, sizeof packet);
+ packet.li_vn_mode = (3 << 3) | 3; /* NTP version 3, client */
+ if ( callback( &packet, 1, usr_data ) )
+ return -1;
+ l = sendto (s, &packet, sizeof packet, 0, (struct sockaddr *)&farAddr, sizeof farAddr);
+ if (l != sizeof packet) {
+ fprintf (stderr, "rtems_bsdnet_get_ntp() Can't send: %s\n", strerror (errno));
+ return -1;
+ }
+ } else {
+ if ( callback( &packet, -1, usr_data ) )
+ return -1;
+ }
+ farlen = sizeof farAddr;
+ i = recvfrom (s, &packet, sizeof packet, 0, (struct sockaddr *)&farAddr, &farlen);
+ if (i == 0)
+ fprintf (stderr, "rtems_bsdnet_get_ntp() Unexpected EOF");
+ if (i < 0) {
+ if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
+ return -1;
+ fprintf (stderr, "rtems_bsdnet_get_ntp() Can't receive: %s\n", strerror (errno));
+ }
+
+ if ( i >= sizeof packet &&
+ ((packet.li_vn_mode & (0x7 << 3)) == (3 << 3)) &&
+ ((packet.transmit_timestamp.integer != 0) || (packet.transmit_timestamp.fraction != 0)) &&
+ 0 == callback( &packet, 0 , usr_data) )
+ return 0;
+
+ return -1;
+}
+
+int rtems_bsdnet_get_ntp(int sock, rtems_bsdnet_ntp_callback_t callback, void *usr_data)
+{
+int s = -1;
+int i;
+int retry;
+struct sockaddr_in myAddr;
+int reuseFlag;
+int ret;
+
+ if ( !callback )
+ callback = getServerTimespec;
+
+ if ( sock < 0 ) {
+ s = socket (AF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+ fprintf (stderr, "rtems_bsdnet_get_ntp() Can't create socket: %s\n", strerror (errno));
+ return -1;
+ }
+ reuseFlag = 1;
+ if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseFlag, sizeof reuseFlag) < 0) {
+ fprintf (stderr, "rtems_bsdnet_get_ntp() Can't set socket reuse: %s\n", strerror (errno));
+ close (s);
+ return -1;
+ }
+ memset (&myAddr, 0, sizeof myAddr);
+ myAddr.sin_family = AF_INET;
+ myAddr.sin_port = htons (123);
+ myAddr.sin_addr.s_addr = htonl (INADDR_ANY);
+ if (bind (s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0) {
+ fprintf (stderr, "rtems_bsdnet_get_ntp() Can't bind socket: %s\n", strerror (errno));
+ close (s);
+ return -1;
+ }
+ sock = s;
+ }
+ ret = -1;
+ for (retry = 0 ; (ret == -1) && (retry < rtems_bsdnet_ntp_retry_count) ; retry++) {
+ /*
+ * If there's no server we just have to wait
+ * and hope that there's an NTP broadcast
+ * server out there somewhere.
+ */
+ if (rtems_bsdnet_ntpserver_count < 0) {
+ ret = tryServer (-1, sock, callback, usr_data);
+ }
+ else {
+ for (i = 0 ; (ret == -1) && (i < rtems_bsdnet_ntpserver_count) ; i++) {
+ ret = tryServer (i, sock, callback, usr_data);
+ }
+ }
+ }
+ if ( s >= 0 )
+ close (s);
+ return ret;
+}
+
+int
+rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority)
+{
+ if (interval != 0) {
+ fprintf (stderr, "Daemon-mode note yet supported.\n");
+ errno = EINVAL;
+ return -1;
+ }
+ return rtems_bsdnet_get_ntp( -1, processPacket, 0);
+}
diff --git a/cpukit/libnetworking/lib/syslog.c b/cpukit/libnetworking/lib/syslog.c
new file mode 100644
index 0000000000..6edd34a91d
--- /dev/null
+++ b/cpukit/libnetworking/lib/syslog.c
@@ -0,0 +1,190 @@
+/*
+ * RTEMS version of syslog and associated routines
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+
+#include <unistd.h>
+
+static int LogStatus = LOG_CONS;
+static const char *LogTag = "syslog";
+static int LogFacility = LOG_USER;
+static int LogMask = 0xff;
+
+static int LogFd = -1;
+static rtems_id LogSemaphore;
+extern struct in_addr rtems_bsdnet_log_host_address;
+
+#define SYSLOG_PORT 514
+
+void
+syslog (int pri, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ vsyslog (pri, fmt, ap);
+ va_end (ap);
+}
+
+/*
+ * FIXME: Should cbuf be static? It could be if we put the mutex
+ * around the entire body of this routine. Then we wouldn't
+ * have to worry about blowing stacks with a local variable
+ * that large. Could make cbuf bigger, too.
+ */
+void
+vsyslog (int pri, const char *fmt, va_list ap)
+{
+ int cnt;
+ char *cp;
+ char *msgp, cbuf[200];
+ int sent;
+
+ if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
+ syslog (LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID,
+ "syslog: unknown facility/priority: %#x", pri);
+ pri &= LOG_PRIMASK|LOG_FACMASK;
+ }
+
+ if (!LOG_MASK(LOG_PRI(pri)) & LogMask)
+ return;
+
+ if ((pri & LOG_FACMASK) == 0)
+ pri |= LogFacility;
+
+ cnt = sprintf (cbuf, "<%d>", pri);
+ cp = msgp = cbuf + cnt;
+ if (LogTag) {
+ const char *lp = LogTag;
+ while ((*cp = *lp++) != '\0')
+ cp++;
+ }
+ if (LogStatus & LOG_PID) {
+ rtems_id tid;
+ rtems_task_ident (RTEMS_SELF, 0, &tid);
+ cnt = sprintf (cp, "[%#lx]", (unsigned long)tid);
+ cp += cnt;
+ }
+ if (LogTag) {
+ *cp++ = ':';
+ *cp++ = ' ';
+ }
+ cnt = vsprintf (cp, fmt, ap);
+ cnt += cp - cbuf;
+ if (cbuf[cnt-1] == '\n')
+ cbuf[--cnt] = '\0';
+
+ if (LogStatus & LOG_PERROR)
+ printf ("%s\n", cbuf);
+
+ /*
+ * Grab the mutex
+ */
+ sent = 0;
+ if ((rtems_bsdnet_log_host_address.s_addr != INADDR_ANY)
+ && (LogFd >= 0)
+ && (rtems_semaphore_obtain (LogSemaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL)) {
+ /*
+ * Set the destination address/port
+ */
+ struct sockaddr_in farAddress;
+ farAddress.sin_family = AF_INET;
+ farAddress.sin_port = htons (SYSLOG_PORT);
+ farAddress.sin_addr = rtems_bsdnet_log_host_address;
+ memset (farAddress.sin_zero, '\0', sizeof farAddress.sin_zero);
+
+ /*
+ * Send the message
+ */
+ if (sendto (LogFd, cbuf, cnt, 0, (struct sockaddr *)&farAddress, sizeof farAddress) >= 0)
+ sent = 1;
+ rtems_semaphore_release (LogSemaphore);
+ }
+ if (!sent && (LogStatus & LOG_CONS) && !(LogStatus & LOG_PERROR))
+ printf ("%s\n", msgp);
+}
+
+void
+openlog (const char *ident, int logstat, int logfac)
+{
+ rtems_status_code sc;
+ struct sockaddr_in myAddress;
+
+ if (ident != NULL)
+ LogTag = ident;
+ LogStatus = logstat;
+ if (logfac != 0 && (logfac & ~LOG_FACMASK) == 0)
+ LogFacility = logfac;
+
+ /*
+ * Create the socket
+ */
+ if ((LogFd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
+ printf ("Can't create syslog socket: %d\n", errno);
+ return;
+ }
+
+ /*
+ * Bind socket to name
+ */
+ myAddress.sin_family = AF_INET;
+ myAddress.sin_addr.s_addr = INADDR_ANY;
+ myAddress.sin_port = 0;
+ memset (myAddress.sin_zero, '\0', sizeof myAddress.sin_zero);
+ if (bind (LogFd, (struct sockaddr *)&myAddress, sizeof (myAddress)) < 0) {
+ close (LogFd);
+ LogFd = -1;
+ printf ("Can't bind syslog socket: %d\n", errno);
+ return;
+ }
+
+ /*
+ * Create the mutex
+ */
+ sc = rtems_semaphore_create (rtems_build_name('s', 'L', 'o', 'g'),
+ 1,
+ RTEMS_PRIORITY |
+ RTEMS_BINARY_SEMAPHORE |
+ RTEMS_INHERIT_PRIORITY |
+ RTEMS_NO_PRIORITY_CEILING |
+ RTEMS_LOCAL,
+ 0,
+ &LogSemaphore);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("Can't create syslog semaphore: %d\n", sc);
+ close (LogFd);
+ LogFd = -1;
+ }
+}
+
+void
+closelog(void)
+{
+ if (LogFd >= 0) {
+ close (LogFd);
+ LogFd = -1;
+ rtems_semaphore_delete (LogSemaphore);
+ }
+}
+
+int
+setlogmask (int pmask)
+{
+ int omask;
+
+ omask = LogMask;
+ if (pmask != 0)
+ LogMask = pmask;
+ return (omask);
+}
diff --git a/cpukit/libnetworking/lib/tftpDriver.c b/cpukit/libnetworking/lib/tftpDriver.c
new file mode 100644
index 0000000000..180f032219
--- /dev/null
+++ b/cpukit/libnetworking/lib/tftpDriver.c
@@ -0,0 +1,1049 @@
+/*
+ * vim: set expandtab tabstop=4 shiftwidth=4 ai :
+ *
+ * Trivial File Transfer Protocol (RFC 1350)
+ *
+ * Transfer file to/from remote host
+ *
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ * $Id$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+#include <rtems/rtems_bsdnet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifdef RTEMS_TFTP_DRIVER_DEBUG
+int rtems_tftp_driver_debug = 1;
+#endif
+
+/*
+ * Range of UDP ports to try
+ */
+#define UDP_PORT_BASE 3180
+
+/*
+ * Pathname prefix
+ */
+#define TFTP_PATHNAME_PREFIX "/TFTP/"
+
+/*
+ * Root node_access value
+ * By using the address of a local static variable
+ * we ensure a unique value for this identifier.
+ */
+#define ROOT_NODE_ACCESS (&tftp_mutex)
+
+/*
+ * Default limits
+ */
+#define PACKET_FIRST_TIMEOUT_MILLISECONDS 400
+#define PACKET_TIMEOUT_MILLISECONDS 6000
+#define OPEN_RETRY_LIMIT 10
+#define IO_RETRY_LIMIT 10
+
+/*
+ * TFTP opcodes
+ */
+#define TFTP_OPCODE_RRQ 1
+#define TFTP_OPCODE_WRQ 2
+#define TFTP_OPCODE_DATA 3
+#define TFTP_OPCODE_ACK 4
+#define TFTP_OPCODE_ERROR 5
+
+/*
+ * Largest data transfer
+ */
+#define TFTP_BUFSIZE 512
+
+/*
+ * Packets transferred between machines
+ */
+union tftpPacket {
+ /*
+ * RRQ/WRQ packet
+ */
+ struct tftpRWRQ {
+ uint16_t opcode;
+ char filename_mode[TFTP_BUFSIZE];
+ } tftpRWRQ;
+
+ /*
+ * DATA packet
+ */
+ struct tftpDATA {
+ uint16_t opcode;
+ uint16_t blocknum;
+ uint8_t data[TFTP_BUFSIZE];
+ } tftpDATA;
+
+ /*
+ * ACK packet
+ */
+ struct tftpACK {
+ uint16_t opcode;
+ uint16_t blocknum;
+ } tftpACK;
+
+ /*
+ * ERROR packet
+ */
+ struct tftpERROR {
+ uint16_t opcode;
+ uint16_t errorCode;
+ char errorMessage[TFTP_BUFSIZE];
+ } tftpERROR;
+};
+
+/*
+ * State of each TFTP stream
+ */
+struct tftpStream {
+ /*
+ * Buffer for storing most recently-received packet
+ */
+ union tftpPacket pkbuf;
+
+ /*
+ * Last block number transferred
+ */
+ uint16_t blocknum;
+
+ /*
+ * Data transfer socket
+ */
+ int socket;
+ struct sockaddr_in myAddress;
+ struct sockaddr_in farAddress;
+
+ /*
+ * Indices into buffer
+ */
+ int nleft;
+ int nused;
+
+ /*
+ * Flags
+ */
+ int firstReply;
+ int eof;
+ int writing;
+};
+
+/*
+ * Number of streams open at the same time
+ */
+static rtems_id tftp_mutex;
+static int nStreams;
+static struct tftpStream ** volatile tftpStreams;
+
+typedef const char *tftp_node;
+extern rtems_filesystem_operations_table rtems_tftp_ops;
+extern rtems_filesystem_file_handlers_r rtems_tftp_handlers;
+
+/*
+ * Direct copy from the IMFS. Look at this.
+ */
+
+rtems_filesystem_limits_and_options_t rtems_tftp_limits_and_options = {
+ 5, /* link_max */
+ 6, /* max_canon */
+ 7, /* max_input */
+ 255, /* name_max */
+ 255, /* path_max */
+ 2, /* pipe_buf */
+ 1, /* posix_async_io */
+ 2, /* posix_chown_restrictions */
+ 3, /* posix_no_trunc */
+ 4, /* posix_prio_io */
+ 5, /* posix_sync_io */
+ 6 /* posix_vdisable */
+};
+
+static int rtems_tftp_mount_me(
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry
+)
+{
+ rtems_status_code sc;
+
+ temp_mt_entry->mt_fs_root.handlers = &rtems_tftp_handlers;
+ temp_mt_entry->mt_fs_root.ops = &rtems_tftp_ops;
+
+ /*
+ * We have no tftp filesystem specific data to maintain. This
+ * filesystem may only be mounted ONCE.
+ *
+ * And we maintain no real filesystem nodes, so there is no real root.
+ */
+
+ temp_mt_entry->fs_info = NULL;
+ temp_mt_entry->mt_fs_root.node_access = ROOT_NODE_ACCESS;
+
+ /*
+ * These need to be looked at for full POSIX semantics.
+ */
+
+ temp_mt_entry->pathconf_limits_and_options = rtems_tftp_limits_and_options;
+
+
+ /*
+ * Now allocate a semaphore for mutual exclusion.
+ *
+ * NOTE: This could be in an fsinfo for this filesystem type.
+ */
+
+ sc = rtems_semaphore_create (
+ rtems_build_name('T', 'F', 'T', 'P'),
+ 1,
+ RTEMS_FIFO |
+ RTEMS_BINARY_SEMAPHORE |
+ RTEMS_NO_INHERIT_PRIORITY |
+ RTEMS_NO_PRIORITY_CEILING |
+ RTEMS_LOCAL,
+ 0,
+ &tftp_mutex
+ );
+
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_set_errno_and_return_minus_one( ENOMEM );
+
+ return 0;
+}
+
+/*
+ * Initialize the TFTP driver
+ */
+
+int rtems_bsdnet_initialize_tftp_filesystem ()
+{
+ int status;
+ rtems_filesystem_mount_table_entry_t *entry;
+
+ status = mkdir( TFTP_PATHNAME_PREFIX, S_IRWXU | S_IRWXG | S_IRWXO );
+ if ( status == -1 )
+ return status;
+
+ status = mount(
+ &entry,
+ &rtems_tftp_ops,
+ RTEMS_FILESYSTEM_READ_WRITE,
+ NULL,
+ TFTP_PATHNAME_PREFIX
+ );
+
+ if ( status )
+ perror( "TFTP mount failed" );
+
+ return status;
+}
+
+/*
+ * Map error message
+ */
+static int
+tftpErrno (struct tftpStream *tp)
+{
+ unsigned int tftpError;
+ static const int errorMap[] = {
+ EINVAL,
+ ENOENT,
+ EPERM,
+ ENOSPC,
+ EINVAL,
+ ENXIO,
+ EEXIST,
+ ESRCH,
+ };
+
+ tftpError = ntohs (tp->pkbuf.tftpERROR.errorCode);
+ if (tftpError < (sizeof errorMap / sizeof errorMap[0]))
+ return errorMap[tftpError];
+ else
+ return 1000 + tftpError;
+}
+
+/*
+ * Send a message to make the other end shut up
+ */
+static void
+sendStifle (struct tftpStream *tp, struct sockaddr_in *to)
+{
+ int len;
+ struct {
+ uint16_t opcode;
+ uint16_t errorCode;
+ char errorMessage[12];
+ } msg;
+
+ /*
+ * Create the error packet (Unknown transfer ID).
+ */
+ msg.opcode = htons (TFTP_OPCODE_ERROR);
+ msg.errorCode = htons (5);
+ len = sizeof msg.opcode + sizeof msg.errorCode + 1;
+ len += sprintf (msg.errorMessage, "GO AWAY");
+
+ /*
+ * Send it
+ */
+ sendto (tp->socket, (char *)&msg, len, 0, (struct sockaddr *)to, sizeof *to);
+}
+
+/*
+ * Wait for a data packet
+ */
+static int
+getPacket (struct tftpStream *tp, int retryCount)
+{
+ int len;
+ struct timeval tv;
+
+ if (retryCount == 0) {
+ tv.tv_sec = PACKET_FIRST_TIMEOUT_MILLISECONDS / 1000;
+ tv.tv_usec = (PACKET_FIRST_TIMEOUT_MILLISECONDS % 1000) * 1000;
+ }
+ else {
+ tv.tv_sec = PACKET_TIMEOUT_MILLISECONDS / 1000;
+ tv.tv_usec = (PACKET_TIMEOUT_MILLISECONDS % 1000) * 1000;
+ }
+ setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
+ for (;;) {
+ union {
+ struct sockaddr s;
+ struct sockaddr_in i;
+ } from;
+ socklen_t fromlen = sizeof from;
+ len = recvfrom (tp->socket, &tp->pkbuf,
+ sizeof tp->pkbuf, 0,
+ &from.s, &fromlen);
+ if (len < 0)
+ break;
+ if (from.i.sin_addr.s_addr == tp->farAddress.sin_addr.s_addr) {
+ if (tp->firstReply) {
+ tp->firstReply = 0;
+ tp->farAddress.sin_port = from.i.sin_port;
+ }
+ if (tp->farAddress.sin_port == from.i.sin_port)
+ break;
+ }
+
+ /*
+ * Packet is from someone with whom we are
+ * not interested. Tell them to go away.
+ */
+ sendStifle (tp, &from.i);
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
+#ifdef RTEMS_TFTP_DRIVER_DEBUG
+ if (rtems_tftp_driver_debug) {
+ if (len >= (int) sizeof tp->pkbuf.tftpACK) {
+ int opcode = ntohs (tp->pkbuf.tftpDATA.opcode);
+ switch (opcode) {
+ default:
+ printf ("TFTP: OPCODE %d\n", opcode);
+ break;
+
+ case TFTP_OPCODE_DATA:
+ printf ("TFTP: RECV %d\n", ntohs (tp->pkbuf.tftpDATA.blocknum));
+ break;
+
+ case TFTP_OPCODE_ACK:
+ printf ("TFTP: GOT ACK %d\n", ntohs (tp->pkbuf.tftpACK.blocknum));
+ break;
+ }
+ }
+ else {
+ printf ("TFTP: %d-byte packet\n", len);
+ }
+ }
+#endif
+ return len;
+}
+
+/*
+ * Send an acknowledgement
+ */
+static int
+sendAck (struct tftpStream *tp)
+{
+#ifdef RTEMS_TFTP_DRIVER_DEBUG
+ if (rtems_tftp_driver_debug)
+ printf ("TFTP: ACK %d\n", tp->blocknum);
+#endif
+
+ /*
+ * Create the acknowledgement
+ */
+ tp->pkbuf.tftpACK.opcode = htons (TFTP_OPCODE_ACK);
+ tp->pkbuf.tftpACK.blocknum = htons (tp->blocknum);
+
+ /*
+ * Send it
+ */
+ if (sendto (tp->socket, (char *)&tp->pkbuf, sizeof tp->pkbuf.tftpACK, 0,
+ (struct sockaddr *)&tp->farAddress,
+ sizeof tp->farAddress) < 0)
+ return errno;
+ return 0;
+}
+
+/*
+ * Release a stream and clear the pointer to it
+ */
+static void
+releaseStream (int s)
+{
+ rtems_semaphore_obtain (tftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ free (tftpStreams[s]);
+ tftpStreams[s] = NULL;
+ rtems_semaphore_release (tftp_mutex);
+}
+
+static int rtems_tftp_evaluate_for_make(
+ const char *path, /* IN */
+ rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
+ const char **name /* OUT */
+)
+{
+ pathloc->node_access = NULL;
+ rtems_set_errno_and_return_minus_one( EIO );
+}
+
+/*
+ * Convert a path to canonical form
+ */
+static void
+fixPath (char *path)
+{
+ char *inp, *outp, *base;
+
+ outp = inp = path;
+ base = NULL;
+ for (;;) {
+ if (inp[0] == '.') {
+ if (inp[1] == '\0')
+ break;
+ if (inp[1] == '/') {
+ inp += 2;
+ continue;
+ }
+ if (inp[1] == '.') {
+ if (inp[2] == '\0') {
+ if ((base != NULL) && (outp > base)) {
+ outp--;
+ while ((outp > base) && (outp[-1] != '/'))
+ outp--;
+ }
+ break;
+ }
+ if (inp[2] == '/') {
+ inp += 3;
+ if (base == NULL)
+ continue;
+ if (outp > base) {
+ outp--;
+ while ((outp > base) && (outp[-1] != '/'))
+ outp--;
+ }
+ continue;
+ }
+ }
+ }
+ if (base == NULL)
+ base = inp;
+ while (inp[0] != '/') {
+ if ((*outp++ = *inp++) == '\0')
+ return;
+ }
+ *outp++ = '/';
+ while (inp[0] == '/')
+ inp++;
+ }
+ *outp = '\0';
+ return;
+}
+
+static int rtems_tftp_eval_path(
+ const char *pathname, /* IN */
+ int flags, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+)
+{
+ pathloc->handlers = &rtems_tftp_handlers;
+
+ /*
+ * Hack to provide the illusion of directories inside the TFTP file system.
+ * Paths ending in a / are assumed to be directories.
+ */
+ if (pathname[strlen(pathname)-1] == '/') {
+ int isRelative = (pathloc->node_access != ROOT_NODE_ACCESS);
+ char *cp;
+
+ /*
+ * Reject attempts to open() directories
+ */
+ if (flags & RTEMS_LIBIO_PERMS_RDWR)
+ rtems_set_errno_and_return_minus_one( EISDIR );
+ if (isRelative) {
+ cp = malloc (strlen(pathloc->node_access)+strlen(pathname)+1);
+ if (cp == NULL)
+ rtems_set_errno_and_return_minus_one( ENOMEM );
+ strcpy (cp, pathloc->node_access);
+ strcat (cp, pathname);
+ }
+ else {
+ cp = strdup (pathname);
+ if (cp == NULL)
+ rtems_set_errno_and_return_minus_one( ENOMEM );
+ }
+ fixPath (cp);
+ pathloc->node_access = cp;
+ return 0;
+ }
+ if (pathloc->node_access != ROOT_NODE_ACCESS)
+ pathloc->node_access = 0;
+
+ /*
+ * Reject it if it's not read-only or write-only.
+ */
+ flags &= RTEMS_LIBIO_PERMS_READ | RTEMS_LIBIO_PERMS_WRITE;
+ if ((flags != RTEMS_LIBIO_PERMS_READ) && (flags != RTEMS_LIBIO_PERMS_WRITE) )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ return 0;
+}
+
+/*
+ * The routine which does most of the work for the IMFS open handler
+ */
+static int rtems_tftp_open_worker(
+ rtems_libio_t *iop,
+ char *full_path_name,
+ uint32_t flags,
+ uint32_t mode
+)
+{
+ struct tftpStream *tp;
+ int retryCount;
+ struct in_addr farAddress;
+ int s;
+ int len;
+ char *cp1;
+ char *cp2;
+ char *remoteFilename;
+ rtems_interval now;
+ rtems_status_code sc;
+ char *hostname;
+
+ /*
+ * Extract the host name component
+ */
+ cp2 = full_path_name;
+ while (*cp2 == '/')
+ cp2++;
+ hostname = cp2;
+ while (*cp2 != '/') {
+ if (*cp2 == '\0')
+ return ENOENT;
+ cp2++;
+ }
+ *cp2++ = '\0';
+
+ /*
+ * Convert hostname to Internet address
+ */
+ if (strcmp (hostname, "BOOTP_HOST") == 0)
+ farAddress = rtems_bsdnet_bootp_server_address;
+ else
+ farAddress.s_addr = inet_addr (hostname);
+ if ((farAddress.s_addr == 0) || (farAddress.s_addr == ~0))
+ return ENOENT;
+
+ /*
+ * Extract file pathname component
+ */
+ while (*cp2 == '/')
+ cp2++;
+ if (strcmp (cp2, "BOOTP_FILE") == 0) {
+ cp2 = rtems_bsdnet_bootp_boot_file_name;
+ while (*cp2 == '/')
+ cp2++;
+ }
+ if (*cp2 == '\0')
+ return ENOENT;
+ remoteFilename = cp2;
+ if (strlen (remoteFilename) > (TFTP_BUFSIZE - 10))
+ return ENOENT;
+
+ /*
+ * Find a free stream
+ */
+ sc = rtems_semaphore_obtain (tftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ return EBUSY;
+ for (s = 0 ; s < nStreams ; s++) {
+ if (tftpStreams[s] == NULL)
+ break;
+ }
+ if (s == nStreams) {
+ /*
+ * Reallocate stream pointers
+ * Guard against the case where realloc() returns NULL.
+ */
+ struct tftpStream **np;
+
+ np = realloc (tftpStreams, ++nStreams * sizeof *tftpStreams);
+ if (np == NULL) {
+ rtems_semaphore_release (tftp_mutex);
+ return ENOMEM;
+ }
+ tftpStreams = np;
+ }
+ tp = tftpStreams[s] = malloc (sizeof (struct tftpStream));
+ rtems_semaphore_release (tftp_mutex);
+ if (tp == NULL)
+ return ENOMEM;
+ iop->data0 = s;
+ iop->data1 = tp;
+
+ /*
+ * Create the socket
+ */
+ if ((tp->socket = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
+ releaseStream (s);
+ return ENOMEM;
+ }
+
+ /*
+ * Bind the socket to a local address
+ */
+ retryCount = 0;
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ for (;;) {
+ int try = (now + retryCount) % 10;
+
+ tp->myAddress.sin_family = AF_INET;
+ tp->myAddress.sin_port = htons (UDP_PORT_BASE + nStreams * try + s);
+ tp->myAddress.sin_addr.s_addr = htonl (INADDR_ANY);
+ if (bind (tp->socket, (struct sockaddr *)&tp->myAddress, sizeof tp->myAddress) >= 0)
+ break;
+ if (++retryCount == 10) {
+ close (tp->socket);
+ releaseStream (s);
+ return EBUSY;
+ }
+ }
+
+ /*
+ * Set the UDP destination to the TFTP server
+ * port on the remote machine.
+ */
+ tp->farAddress.sin_family = AF_INET;
+ tp->farAddress.sin_addr = farAddress;
+ tp->farAddress.sin_port = htons (69);
+
+ /*
+ * Start the transfer
+ */
+ tp->firstReply = 1;
+ retryCount = 0;
+ for (;;) {
+ /*
+ * Create the request
+ */
+ if ((flags & O_ACCMODE) == O_RDONLY) {
+ tp->writing = 0;
+ tp->pkbuf.tftpRWRQ.opcode = htons (TFTP_OPCODE_RRQ);
+ }
+ else {
+ tp->writing = 1;
+ tp->pkbuf.tftpRWRQ.opcode = htons (TFTP_OPCODE_WRQ);
+ }
+ cp1 = (char *) tp->pkbuf.tftpRWRQ.filename_mode;
+ cp2 = (char *) remoteFilename;
+ while ((*cp1++ = *cp2++) != '\0')
+ continue;
+ cp2 = "octet";
+ while ((*cp1++ = *cp2++) != '\0')
+ continue;
+ len = cp1 - (char *)&tp->pkbuf.tftpRWRQ;
+
+ /*
+ * Send the request
+ */
+ if (sendto (tp->socket, (char *)&tp->pkbuf, len, 0,
+ (struct sockaddr *)&tp->farAddress,
+ sizeof tp->farAddress) < 0) {
+ close (tp->socket);
+ releaseStream (s);
+ return EIO;
+ }
+
+ /*
+ * Get reply
+ */
+ len = getPacket (tp, retryCount);
+ if (len >= (int) sizeof tp->pkbuf.tftpACK) {
+ int opcode = ntohs (tp->pkbuf.tftpDATA.opcode);
+ if (!tp->writing
+ && (opcode == TFTP_OPCODE_DATA)
+ && (ntohs (tp->pkbuf.tftpDATA.blocknum) == 1)) {
+ tp->nused = 0;
+ tp->blocknum = 1;
+ tp->nleft = len - 2 * sizeof (uint16_t );
+ tp->eof = (tp->nleft < TFTP_BUFSIZE);
+ if (sendAck (tp) != 0) {
+ close (tp->socket);
+ releaseStream (s);
+ return EIO;
+ }
+ break;
+ }
+ if (tp->writing
+ && (opcode == TFTP_OPCODE_ACK)
+ && (ntohs (tp->pkbuf.tftpACK.blocknum) == 0)) {
+ tp->nused = 0;
+ tp->blocknum = 1;
+ break;
+ }
+ if (opcode == TFTP_OPCODE_ERROR) {
+ int e = tftpErrno (tp);
+ close (tp->socket);
+ releaseStream (s);
+ return e;
+ }
+ }
+
+ /*
+ * Keep trying
+ */
+ if (++retryCount >= OPEN_RETRY_LIMIT) {
+ close (tp->socket);
+ releaseStream (s);
+ return EIO;
+ }
+ }
+ return 0;
+}
+
+/*
+ * The IMFS open handler
+ */
+static int rtems_tftp_open(
+ rtems_libio_t *iop,
+ const char *new_name,
+ uint32_t flags,
+ uint32_t mode
+)
+{
+ char *full_path_name;
+ char *s1;
+ int err;
+
+ /*
+ * Tack the `current directory' on to relative paths.
+ * We know that the current directory ends in a / character.
+ */
+ if (*new_name == '/') {
+ /*
+ * Skip the TFTP filesystem prefix.
+ */
+ int len = strlen (TFTP_PATHNAME_PREFIX);
+ if (strncmp (new_name, TFTP_PATHNAME_PREFIX, len))
+ return ENOENT;
+ new_name += len;
+ s1 = "";
+ }
+ else {
+ s1 = rtems_filesystem_current.node_access;
+ }
+ full_path_name = malloc (strlen (s1) + strlen (new_name) + 1);
+ if (full_path_name == NULL)
+ return ENOMEM;
+ strcpy (full_path_name, s1);
+ strcat (full_path_name, new_name);
+ fixPath (full_path_name);
+ err = rtems_tftp_open_worker (iop, full_path_name, flags, mode);
+ free (full_path_name);
+ return err;
+}
+
+/*
+ * Read from a TFTP stream
+ */
+static ssize_t rtems_tftp_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ uint32_t count
+)
+{
+ char *bp;
+ struct tftpStream *tp = iop->data1;
+ int retryCount;
+ int nwant;
+
+
+ /*
+ * Read till user request is satisfied or EOF is reached
+ */
+ bp = buffer;
+ nwant = count;
+ while (nwant) {
+ if (tp->nleft) {
+ int ncopy;
+ if (nwant < tp->nleft)
+ ncopy = nwant;
+ else
+ ncopy = tp->nleft;
+ memcpy (bp, &tp->pkbuf.tftpDATA.data[tp->nused], ncopy);
+ tp->nused += ncopy;
+ tp->nleft -= ncopy;
+ bp += ncopy;
+ nwant -= ncopy;
+ if (nwant == 0)
+ break;
+ }
+ if (tp->eof)
+ break;
+
+ /*
+ * Wait for the next packet
+ */
+ retryCount = 0;
+ for (;;) {
+ int len = getPacket (tp, retryCount);
+ if (len >= (int)sizeof tp->pkbuf.tftpACK) {
+ int opcode = ntohs (tp->pkbuf.tftpDATA.opcode);
+ uint16_t nextBlock = tp->blocknum + 1;
+ if ((opcode == TFTP_OPCODE_DATA)
+ && (ntohs (tp->pkbuf.tftpDATA.blocknum) == nextBlock)) {
+ tp->nused = 0;
+ tp->nleft = len - 2 * sizeof (uint16_t );
+ tp->eof = (tp->nleft < TFTP_BUFSIZE);
+ tp->blocknum++;
+ if (sendAck (tp) != 0)
+ rtems_set_errno_and_return_minus_one( EIO );
+ break;
+ }
+ if (opcode == TFTP_OPCODE_ERROR)
+ rtems_set_errno_and_return_minus_one( tftpErrno (tp) );
+ }
+
+ /*
+ * Keep trying?
+ */
+ if (++retryCount == IO_RETRY_LIMIT)
+ rtems_set_errno_and_return_minus_one( EIO );
+ if (sendAck (tp) != 0)
+ rtems_set_errno_and_return_minus_one( EIO );
+ }
+ }
+ return count - nwant;
+}
+
+/*
+ * Flush a write buffer and wait for acknowledgement
+ */
+static int rtems_tftp_flush ( struct tftpStream *tp )
+{
+ int wlen, rlen;
+ int retryCount = 0;
+
+ wlen = tp->nused + 2 * sizeof (uint16_t );
+ for (;;) {
+ tp->pkbuf.tftpDATA.opcode = htons (TFTP_OPCODE_DATA);
+ tp->pkbuf.tftpDATA.blocknum = htons (tp->blocknum);
+#ifdef RTEMS_TFTP_DRIVER_DEBUG
+ if (rtems_tftp_driver_debug)
+ printf ("TFTP: SEND %d (%d)\n", tp->blocknum, tp->nused);
+#endif
+ if (sendto (tp->socket, (char *)&tp->pkbuf, wlen, 0,
+ (struct sockaddr *)&tp->farAddress,
+ sizeof tp->farAddress) < 0)
+ return EIO;
+ rlen = getPacket (tp, retryCount);
+ /*
+ * Our last packet won't necessarily be acknowledged!
+ */
+ if ((rlen < 0) && (tp->nused < sizeof tp->pkbuf.tftpDATA.data))
+ return 0;
+ if (rlen >= (int)sizeof tp->pkbuf.tftpACK) {
+ int opcode = ntohs (tp->pkbuf.tftpACK.opcode);
+ if ((opcode == TFTP_OPCODE_ACK)
+ && (ntohs (tp->pkbuf.tftpACK.blocknum) == tp->blocknum)) {
+ tp->nused = 0;
+ tp->blocknum++;
+ return 0;
+ }
+ if (opcode == TFTP_OPCODE_ERROR)
+ return tftpErrno (tp);
+ }
+
+ /*
+ * Keep trying?
+ */
+ if (++retryCount == IO_RETRY_LIMIT)
+ return EIO;
+ }
+}
+
+/*
+ * Close a TFTP stream
+ */
+static int rtems_tftp_close(
+ rtems_libio_t *iop
+)
+{
+ struct tftpStream *tp = iop->data1;;
+
+ if (tp->writing)
+ rtems_tftp_flush (tp);
+ if (!tp->eof && !tp->firstReply) {
+ /*
+ * Tell the other end to stop
+ */
+ rtems_interval ticksPerSecond;
+ sendStifle (tp, &tp->farAddress);
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticksPerSecond);
+ rtems_task_wake_after (1 + ticksPerSecond / 10);
+ }
+ close (tp->socket);
+ releaseStream (iop->data0);
+ return RTEMS_SUCCESSFUL;
+}
+
+static ssize_t rtems_tftp_write(
+ rtems_libio_t *iop,
+ const void *buffer,
+ uint32_t count
+)
+{
+ const char *bp;
+ struct tftpStream *tp = iop->data1;
+ int nleft, nfree, ncopy;
+
+ /*
+ * Bail out if an error has occurred
+ */
+ if (!tp->writing)
+ return EIO;
+
+
+ /*
+ * Write till user request is satisfied
+ * Notice that the buffer is flushed as soon as it is filled rather
+ * than waiting for the next write or a close. This ensures that
+ * the flush in close writes a less than full buffer so the far
+ * end can detect the end-of-file condition.
+ */
+ bp = buffer;
+ nleft = count;
+ while (nleft) {
+ nfree = sizeof tp->pkbuf.tftpDATA.data - tp->nused;
+ if (nleft < nfree)
+ ncopy = nleft;
+ else
+ ncopy = nfree;
+ memcpy (&tp->pkbuf.tftpDATA.data[tp->nused], bp, ncopy);
+ tp->nused += ncopy;
+ nleft -= ncopy;
+ bp += ncopy;
+ if (tp->nused == sizeof tp->pkbuf.tftpDATA.data) {
+ int e = rtems_tftp_flush (tp);
+ if (e) {
+ tp->writing = 0;
+ rtems_set_errno_and_return_minus_one (e);
+ }
+ }
+ }
+ return count;
+}
+
+/*
+ * Dummy version to let fopen(xxxx,"w") work properly.
+ */
+static int rtems_tftp_ftruncate(
+ rtems_libio_t *iop,
+ off_t count
+)
+{
+ return 0;
+}
+
+static rtems_filesystem_node_types_t rtems_tftp_node_type(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+)
+{
+ if ((pathloc->node_access == NULL)
+ || (pathloc->node_access == ROOT_NODE_ACCESS))
+ return RTEMS_FILESYSTEM_MEMORY_FILE;
+ return RTEMS_FILESYSTEM_DIRECTORY;
+}
+
+static int rtems_tftp_free_node_info(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+)
+{
+ if (pathloc->node_access && (pathloc->node_access != ROOT_NODE_ACCESS)) {
+ free (pathloc->node_access);
+ pathloc->node_access = NULL;
+ }
+ return 0;
+}
+
+
+rtems_filesystem_operations_table rtems_tftp_ops = {
+ rtems_tftp_eval_path, /* eval_path */
+ rtems_tftp_evaluate_for_make, /* evaluate_for_make */
+ NULL, /* link */
+ NULL, /* unlink */
+ rtems_tftp_node_type, /* node_type */
+ NULL, /* mknod */
+ NULL, /* chown */
+ rtems_tftp_free_node_info, /* freenodinfo */
+ NULL, /* mount */
+ rtems_tftp_mount_me, /* initialize */
+ NULL, /* unmount */
+ NULL, /* fsunmount */
+ NULL, /* utime, */
+ NULL, /* evaluate_link */
+ NULL, /* symlink */
+ NULL, /* readlin */
+};
+
+rtems_filesystem_file_handlers_r rtems_tftp_handlers = {
+ rtems_tftp_open, /* open */
+ rtems_tftp_close, /* close */
+ rtems_tftp_read, /* read */
+ rtems_tftp_write, /* write */
+ NULL, /* ioctl */
+ NULL, /* lseek */
+ NULL, /* fstat */
+ NULL, /* fchmod */
+ rtems_tftp_ftruncate, /* ftruncate */
+ NULL, /* fpathconf */
+ NULL, /* fsync */
+ NULL, /* fdatasync */
+ NULL, /* fcntl */
+ NULL /* rmnod */
+};
diff --git a/cpukit/libnetworking/libc/addr2ascii.3 b/cpukit/libnetworking/libc/addr2ascii.3
new file mode 100644
index 0000000000..10c839ea74
--- /dev/null
+++ b/cpukit/libnetworking/libc/addr2ascii.3
@@ -0,0 +1,217 @@
+.\"
+.\" Copyright 1996 Massachusetts Institute of Technology
+.\"
+.\" Permission to use, copy, modify, and distribute this software and
+.\" its documentation for any purpose and without fee is hereby
+.\" granted, provided that both the above copyright notice and this
+.\" permission notice appear in all copies, that both the above
+.\" copyright notice and this permission notice appear in all
+.\" supporting documentation, and that the name of M.I.T. not be used
+.\" in advertising or publicity pertaining to distribution of the
+.\" software without specific, written prior permission. M.I.T. makes
+.\" no representations about the suitability of this software for any
+.\" purpose. It is provided "as is" without express or implied
+.\" warranty.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+.\" SHALL M.I.T. 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.
+.\"
+.\" $ANA: addr2ascii.3,v 1.1 1996/06/13 18:41:46 wollman Exp $
+.\" $Id$
+.\"
+.Dd June 13, 1996
+.Dt ADDR2ASCII 3
+.Os
+.Sh NAME
+.Nm addr2ascii ,
+.Nm ascii2addr
+.Nd Generic address formatting routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netinet/in.h>
+.Fd #include <arpa/inet.h>
+.Ft "char *"
+.Fn addr2ascii "int af" "const void *addrp" "int len" "char *buf"
+.Ft int
+.Fn ascii2addr "int af" "const char *ascii" "void *result"
+.Sh DESCRIPTION
+The routines
+.Fn addr2ascii
+and
+.Fn ascii2addr
+are used to convert network addresses between binary form and a
+printable form appropriate to the address family. Both functions take
+an
+.Fa af
+argument, specifying the address family to be used in the conversion
+process.
+(Currently, only the
+.Dv AF_INET
+and
+.Dv AF_LINK
+address families are supported.)
+.Pp
+The
+.Fn addr2ascii
+function
+is used to convert binary, network-format addresses into printable
+form. In addition to
+.Fa af ,
+there are three other arguments. The
+.Fa addrp
+argument is a pointer to the network address to be converted.
+The
+.Fa len
+argument is the length of the address. The
+.Fa buf
+argument is an optional pointer to a caller-allocated buffer to hold
+the result; if a null pointer is passed,
+.Fn addr2ascii
+uses a statically-allocated buffer.
+.Pp
+The
+.Fn ascii2addr
+function performs the inverse operation to
+.Fn addr2ascii .
+In addition to
+.Fa af ,
+it takes two parameters,
+.Fa ascii
+and
+.Fa result .
+The
+.Fa ascii
+parameter is a pointer to the string which is to be converted into
+binary. The
+.Fa result
+parameter is a pointer to an appropriate network address structure for
+the specified family.
+.Pp
+The following gives the appropriate structure to use for binary
+addresses in the specified family:
+.Pp
+.Bl -tag -width AF_INETxxxx -compact
+.It Dv AF_INET
+.Li struct in_addr
+.Pq in Aq Pa netinet/in.h
+.It Dv AF_LINK
+.Li struct sockaddr_dl
+.Pq in Aq Pa net/if_dl.h
+.\" .It Dv AF_INET6
+.\" .Li struct in6_addr
+.\" .Pq in Aq Pa netinet6/in6.h
+.El
+.Sh RETURN VALUES
+The
+.Fn addr2ascii
+function returns the address of the buffer it was passed, or a static
+buffer if the a null pointer was passed; on failure, it returns a null
+pointer.
+The
+.Fn ascii2addr
+function returns the length of the binary address in bytes, or -1 on
+failure.
+.Sh EXAMPLES
+The
+.Xr inet 3
+functions
+.Fn inet_ntoa
+and
+.Fn inet_aton
+could be implemented thusly:
+.Bd -literal -offset indent
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+char *
+inet_ntoa(struct in_addr addr)
+{
+ return addr2ascii(AF_INET, &addr, sizeof addr, 0);
+}
+
+int
+inet_aton(const char *ascii, struct in_addr *addr)
+{
+ return (ascii2addr(AF_INET, ascii, addr)
+ == sizeof(*addr));
+}
+.Ed
+.Pp
+In actuality, this cannot be done because
+.Fn addr2ascii
+and
+.Fn ascii2addr
+are implemented in terms of the
+.Xr inet 3
+functions, rather than the other way around.
+.Sh ERRORS
+When a failure is returned,
+.Li errno
+is set to one of the following values:
+.Bl -tag -width [EPROTONOSUPPORT]
+.It Bq Er ENAMETOOLONG
+The
+.Fn addr2ascii
+routine was passed a
+.Fa len
+parameter which was inappropriate for the address family given by
+.Fa af .
+.It Bq Er EPROTONOSUPPORT
+Either routine was passed an
+.Fa af
+parameter other than
+.Dv AF_INET
+or
+.Dv AF_LINK .
+.It Bq Er EINVAL
+The string passed to
+.Fn ascii2addr
+was improperly formatted for address family
+.Fa af .
+.El
+.Sh SEE ALSO
+.Xr inet 3 ,
+.Xr linkaddr 3 ,
+.Xr inet 4
+.Sh HISTORY
+An interface close to this one was originally suggested by Craig
+Partridge. This particular interface originally appeared in the
+.Tn INRIA
+.Tn IPv6
+implementation.
+.Sh AUTHORS
+Code and documentation by
+.An Garrett A. Wollman ,
+MIT Laboratory for Computer Science.
+.Sh BUGS
+The original implementations supported IPv6. This support should
+eventually be resurrected. The
+.Tn NRL
+implementation also included support for the
+.Dv AF_ISO
+and
+.Dv AF_NS
+address families.
+.Pp
+The genericity of this interface is somewhat questionable. A truly
+generic interface would provide a means for determining the length of
+the buffer to be used so that it could be dynamically allocated, and
+would always require a
+.Dq Li "struct sockaddr"
+to hold the binary address. Unfortunately, this is incompatible with existing
+practice. This limitation means that a routine for printing network
+addresses from arbitrary address families must still have internal
+knowledge of the maximum buffer length needed and the appropriate part
+of the address to use as the binary address.
diff --git a/cpukit/libnetworking/libc/addr2ascii.c b/cpukit/libnetworking/libc/addr2ascii.c
new file mode 100644
index 0000000000..dc651743b6
--- /dev/null
+++ b/cpukit/libnetworking/libc/addr2ascii.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 1996 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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.
+ *
+ * $ANA: addr2ascii.c,v 1.1 1996/06/13 18:41:46 wollman Exp $
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <net/if_dl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*-
+ * Convert a network address from binary to printable numeric format.
+ * This API is copied from INRIA's IPv6 implementation, but it is a
+ * bit bogus in two ways:
+ *
+ * 1) There is no value in passing both an address family and
+ * an address length; either one should imply the other,
+ * or we should be passing sockaddrs instead.
+ * 2) There should by contrast be /added/ a length for the buffer
+ * that we pass in, so that programmers are spared the need to
+ * manually calculate (read: ``guess'') the maximum length.
+ *
+ * Flash: the API is also the same in the NRL implementation, and seems to
+ * be some sort of standard, so we appear to be stuck with both the bad
+ * naming and the poor choice of arguments.
+ */
+char *
+addr2ascii(af, addrp, len, buf)
+ int af;
+ const void *addrp;
+ int len; /* should be size_t XXX */
+ char *buf; /* XXX should pass length of buffer */
+{
+ static char staticbuf[64]; /* 64 for AF_LINK > 16 for AF_INET */
+
+ if (!buf)
+ buf = staticbuf;
+
+ switch(af) {
+ case AF_INET:
+ if (len != sizeof(struct in_addr)) {
+ errno = ENAMETOOLONG;
+ return 0;
+ }
+ strcpy(buf, inet_ntoa(*(const struct in_addr *)addrp));
+ break;
+
+ case AF_LINK:
+ if (len != sizeof(struct sockaddr_dl)) {
+ errno = ENAMETOOLONG;
+ return 0;
+ }
+ strcpy(buf, link_ntoa((const struct sockaddr_dl *)addrp));
+ break;
+
+ default:
+ errno = EPROTONOSUPPORT;
+ return 0;
+ }
+ return buf;
+}
diff --git a/cpukit/libnetworking/libc/ascii2addr.c b/cpukit/libnetworking/libc/ascii2addr.c
new file mode 100644
index 0000000000..e140244737
--- /dev/null
+++ b/cpukit/libnetworking/libc/ascii2addr.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1996 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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.
+ *
+ * $ANA: ascii2addr.c,v 1.2 1996/06/13 18:46:02 wollman Exp $
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <net/if_dl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int
+ascii2addr(af, ascii, result)
+ int af;
+ const char *ascii;
+ void *result;
+{
+ struct in_addr *ina;
+ char strbuf[4*sizeof("123")]; /* long enough for V4 only */
+
+ switch(af) {
+ case AF_INET:
+ ina = result;
+ strbuf[0] = '\0';
+ strncat(strbuf, ascii, (sizeof strbuf)-1);
+ if (inet_aton(strbuf, ina))
+ return sizeof(struct in_addr);
+ errno = EINVAL;
+ break;
+
+ case AF_LINK:
+ link_addr(ascii, result);
+ /* oops... no way to detect failure */
+ return sizeof(struct sockaddr_dl);
+
+ default:
+ errno = EPROTONOSUPPORT;
+ break;
+ }
+
+ return -1;
+}
diff --git a/cpukit/libnetworking/libc/base64.c b/cpukit/libnetworking/libc/base64.c
new file mode 100644
index 0000000000..3017ccc01c
--- /dev/null
+++ b/cpukit/libnetworking/libc/base64.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software. No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#if !defined(__rtems__)
+#if !defined(LINT) && !defined(CODECENTER)
+static char rcsid[] = "$Id$";
+#endif /* not lint */
+#endif /* not rtems */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define Assert(Cond) if (!(Cond)) abort()
+
+static const char Base64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+ The following encoding technique is taken from RFC 1521 by Borenstein
+ and Freed. It is reproduced here in a slightly edited form for
+ convenience.
+
+ A 65-character subset of US-ASCII is used, enabling 6 bits to be
+ represented per printable character. (The extra 65th character, "=",
+ is used to signify a special processing function.)
+
+ The encoding process represents 24-bit groups of input bits as output
+ strings of 4 encoded characters. Proceeding from left to right, a
+ 24-bit input group is formed by concatenating 3 8-bit input groups.
+ These 24 bits are then treated as 4 concatenated 6-bit groups, each
+ of which is translated into a single digit in the base64 alphabet.
+
+ Each 6-bit group is used as an index into an array of 64 printable
+ characters. The character referenced by the index is placed in the
+ output string.
+
+ Table 1: The Base64 Alphabet
+
+ Value Encoding Value Encoding Value Encoding Value Encoding
+ 0 A 17 R 34 i 51 z
+ 1 B 18 S 35 j 52 0
+ 2 C 19 T 36 k 53 1
+ 3 D 20 U 37 l 54 2
+ 4 E 21 V 38 m 55 3
+ 5 F 22 W 39 n 56 4
+ 6 G 23 X 40 o 57 5
+ 7 H 24 Y 41 p 58 6
+ 8 I 25 Z 42 q 59 7
+ 9 J 26 a 43 r 60 8
+ 10 K 27 b 44 s 61 9
+ 11 L 28 c 45 t 62 +
+ 12 M 29 d 46 u 63 /
+ 13 N 30 e 47 v
+ 14 O 31 f 48 w (pad) =
+ 15 P 32 g 49 x
+ 16 Q 33 h 50 y
+
+ Special processing is performed if fewer than 24 bits are available
+ at the end of the data being encoded. A full encoding quantum is
+ always completed at the end of a quantity. When fewer than 24 input
+ bits are available in an input group, zero bits are added (on the
+ right) to form an integral number of 6-bit groups. Padding at the
+ end of the data is performed using the '=' character.
+
+ Since all base64 input is an integral number of octets, only the
+ -------------------------------------------------
+ following cases can arise:
+
+ (1) the final quantum of encoding input is an integral
+ multiple of 24 bits; here, the final unit of encoded
+ output will be an integral multiple of 4 characters
+ with no "=" padding,
+ (2) the final quantum of encoding input is exactly 8 bits;
+ here, the final unit of encoded output will be two
+ characters followed by two "=" padding characters, or
+ (3) the final quantum of encoding input is exactly 16 bits;
+ here, the final unit of encoded output will be three
+ characters followed by one "=" padding character.
+ */
+
+int
+b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
+ size_t datalength = 0;
+ u_char input[3];
+ u_char output[4];
+ size_t i;
+
+ while (2 < srclength) {
+ input[0] = *src++;
+ input[1] = *src++;
+ input[2] = *src++;
+ srclength -= 3;
+
+ output[0] = input[0] >> 2;
+ output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+ output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+ output[3] = input[2] & 0x3f;
+ Assert(output[0] < 64);
+ Assert(output[1] < 64);
+ Assert(output[2] < 64);
+ Assert(output[3] < 64);
+
+ if (datalength + 4 > targsize)
+ return (-1);
+ target[datalength++] = Base64[output[0]];
+ target[datalength++] = Base64[output[1]];
+ target[datalength++] = Base64[output[2]];
+ target[datalength++] = Base64[output[3]];
+ }
+
+ /* Now we worry about padding. */
+ if (0 != srclength) {
+ /* Get what's left. */
+ input[0] = input[1] = input[2] = '\0';
+ for (i = 0; i < srclength; i++)
+ input[i] = *src++;
+
+ output[0] = input[0] >> 2;
+ output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+ output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+ Assert(output[0] < 64);
+ Assert(output[1] < 64);
+ Assert(output[2] < 64);
+
+ if (datalength + 4 > targsize)
+ return (-1);
+ target[datalength++] = Base64[output[0]];
+ target[datalength++] = Base64[output[1]];
+ if (srclength == 1)
+ target[datalength++] = Pad64;
+ else
+ target[datalength++] = Base64[output[2]];
+ target[datalength++] = Pad64;
+ }
+ if (datalength >= targsize)
+ return (-1);
+ target[datalength] = '\0'; /* Returned value doesn't count \0. */
+ return (datalength);
+}
+
+/* skips all whitespace anywhere.
+ converts characters, four at a time, starting at (or after)
+ src from base - 64 numbers into three 8 bit bytes in the target area.
+ it returns the number of data bytes stored at the target, or -1 on error.
+ */
+
+int
+b64_pton(src, target, targsize)
+ char const *src;
+ u_char *target;
+ size_t targsize;
+{
+ int tarindex, state, ch;
+ char *pos;
+
+ state = 0;
+ tarindex = 0;
+
+ while ((ch = *src++) != '\0') {
+ if (isspace(ch)) /* Skip whitespace anywhere. */
+ continue;
+
+ if (ch == Pad64)
+ break;
+
+ pos = strchr(Base64, ch);
+ if (pos == 0) /* A non-base64 character. */
+ return (-1);
+
+ switch (state) {
+ case 0:
+ if (target) {
+ if ((size_t)tarindex >= targsize)
+ return (-1);
+ target[tarindex] = (pos - Base64) << 2;
+ }
+ state = 1;
+ break;
+ case 1:
+ if (target) {
+ if ((size_t)tarindex + 1 >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64) >> 4;
+ target[tarindex+1] = ((pos - Base64) & 0x0f)
+ << 4 ;
+ }
+ tarindex++;
+ state = 2;
+ break;
+ case 2:
+ if (target) {
+ if ((size_t)tarindex + 1 >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64) >> 2;
+ target[tarindex+1] = ((pos - Base64) & 0x03)
+ << 6;
+ }
+ tarindex++;
+ state = 3;
+ break;
+ case 3:
+ if (target) {
+ if ((size_t)tarindex >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64);
+ }
+ tarindex++;
+ state = 0;
+ break;
+ default:
+ abort();
+ }
+ }
+
+ /*
+ * We are done decoding Base-64 chars. Let's see if we ended
+ * on a byte boundary, and/or with erroneous trailing characters.
+ */
+
+ if (ch == Pad64) { /* We got a pad char. */
+ ch = *src++; /* Skip it, get next. */
+ switch (state) {
+ case 0: /* Invalid = in first position */
+ case 1: /* Invalid = in second position */
+ return (-1);
+
+ case 2: /* Valid, means one byte of info */
+ /* Skip any number of spaces. */
+ for ((void)NULL; ch != '\0'; ch = *src++)
+ if (!isspace(ch))
+ break;
+ /* Make sure there is another trailing = sign. */
+ if (ch != Pad64)
+ return (-1);
+ ch = *src++; /* Skip the = */
+ /* Fall through to "single trailing =" case. */
+ /* FALLTHROUGH */
+
+ case 3: /* Valid, means two bytes of info */
+ /*
+ * We know this char is an =. Is there anything but
+ * whitespace after it?
+ */
+ for ((void)NULL; ch != '\0'; ch = *src++)
+ if (!isspace(ch))
+ return (-1);
+
+ /*
+ * Now make sure for cases 2 and 3 that the "extra"
+ * bits that slopped past the last full byte were
+ * zeros. If we don't check them, they become a
+ * subliminal channel.
+ */
+ if (target && target[tarindex] != 0)
+ return (-1);
+ }
+ } else {
+ /*
+ * We ended by seeing the end of the string. Make sure we
+ * have no partial bytes lying around.
+ */
+ if (state != 0)
+ return (-1);
+ }
+
+ return (tarindex);
+}
diff --git a/cpukit/libnetworking/libc/byteorder.3 b/cpukit/libnetworking/libc/byteorder.3
new file mode 100644
index 0000000000..81bf604867
--- /dev/null
+++ b/cpukit/libnetworking/libc/byteorder.3
@@ -0,0 +1,77 @@
+.\" Copyright (c) 1983, 1991, 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.
+.\"
+.\" @(#)byteorder.3 8.1 (Berkeley) 6/4/93
+.\" $Id$
+.\"
+.Dd June 4, 1993
+.Dt BYTEORDER 3
+.Os BSD 4.2
+.Sh NAME
+.Nm htonl ,
+.Nm htons ,
+.Nm ntohl ,
+.Nm ntohs
+.Nd convert values between host and network byte order
+.Sh SYNOPSIS
+.Fd #include <sys/param.h>
+.Ft u_long
+.Fn htonl "u_long hostlong"
+.Ft u_short
+.Fn htons "u_short hostshort"
+.Ft u_long
+.Fn ntohl "u_long netlong"
+.Ft u_short
+.Fn ntohs "u_short netshort"
+.Sh DESCRIPTION
+These routines convert 16 and 32 bit quantities between network
+byte order and host byte order.
+On machines which have a byte order which is the same as the network
+order, routines are defined as null macros.
+.Pp
+These routines are most often used in conjunction with Internet
+addresses and ports as returned by
+.Xr gethostbyname 3
+and
+.Xr getservent 3 .
+.Sh SEE ALSO
+.Xr gethostbyname 3 ,
+.Xr getservent 3
+.Sh HISTORY
+The
+.Nm byteorder
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+On the
+.Tn VAX
+bytes are handled backwards from most everyone else in
+the world. This is not expected to be fixed in the near future.
diff --git a/cpukit/libnetworking/libc/ether_addr.c b/cpukit/libnetworking/libc/ether_addr.c
new file mode 100644
index 0000000000..9b7a9abf44
--- /dev/null
+++ b/cpukit/libnetworking/libc/ether_addr.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. 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 Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul 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.
+ *
+ * ethernet address conversion and lookup routines
+ *
+ * Written by Bill Paul <wpaul@ctr.columbia.edu>
+ * Center for Telecommunications Research
+ * Columbia University, New York City
+ *
+ * $Id$
+ */
+
+
+#include <stdio.h>
+#include <paths.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/ethernet.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+
+#ifndef _PATH_ETHERS
+#define _PATH_ETHERS "/etc/ethers"
+#endif
+
+/*
+ * Parse a string of text containing an ethernet address and hostname
+ * and separate it into its component parts.
+ */
+int ether_line(l, e, hostname)
+ char *l;
+ struct ether_addr *e;
+ char *hostname;
+{
+ int i, o[6];
+
+ i = sscanf(l, "%x:%x:%x:%x:%x:%x %s", &o[0], &o[1], &o[2],
+ &o[3], &o[4], &o[5],
+ hostname);
+ if (i != 7)
+ return (i);
+
+ for (i=0; i<6; i++)
+ e->octet[i] = o[i];
+ return (0);
+}
+
+/*
+ * Convert an ASCII representation of an ethernet address to
+ * binary form.
+ */
+struct ether_addr *ether_aton(a)
+ char *a;
+{
+ int i;
+ static struct ether_addr o;
+ unsigned int o0, o1, o2, o3, o4, o5;
+
+ i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5);
+
+ if (i != 6)
+ return (NULL);
+
+ o.octet[0]=o0;
+ o.octet[1]=o1;
+ o.octet[2]=o2;
+ o.octet[3]=o3;
+ o.octet[4]=o4;
+ o.octet[5]=o5;
+
+ return ((struct ether_addr *)&o);
+}
+
+/*
+ * Convert a binary representation of an ethernet address to
+ * an ASCII string.
+ */
+char *ether_ntoa(n)
+ struct ether_addr *n;
+{
+ int i;
+ static char a[18];
+
+ i = sprintf(a,"%x:%x:%x:%x:%x:%x",n->octet[0],n->octet[1],n->octet[2],
+ n->octet[3],n->octet[4],n->octet[5]);
+ if (i < 11)
+ return (NULL);
+ return ((char *)&a);
+}
+
+/*
+ * Map an ethernet address to a hostname. Use either /etc/ethers or
+ * NIS/YP.
+ */
+
+int ether_ntohost(hostname, e)
+ char *hostname;
+ struct ether_addr *e;
+{
+ FILE *fp;
+ char buf[BUFSIZ + 2];
+ struct ether_addr local_ether;
+ char local_host[MAXHOSTNAMELEN];
+#ifdef YP
+ char *result;
+ int resultlen;
+ char *ether_a;
+ char *yp_domain;
+#endif
+ if ((fp = fopen(_PATH_ETHERS, "r")) == NULL)
+ return (1);
+
+ while (fgets(buf,BUFSIZ,fp)) {
+ if (buf[0] == '#')
+ continue;
+#ifdef YP
+ if (buf[0] == '+') {
+ if (yp_get_default_domain(&yp_domain))
+ continue;
+ ether_a = ether_ntoa(e);
+ if (yp_match(yp_domain, "ethers.byaddr", ether_a,
+ strlen(ether_a), &result, &resultlen)) {
+ continue;
+ }
+ strncpy(buf, result, resultlen);
+ buf[resultlen] = '\0';
+ free(result);
+ }
+#endif
+ if (!ether_line(buf, &local_ether, local_host)) {
+ if (!bcmp((char *)&local_ether.octet[0],
+ (char *)&e->octet[0], 6)) {
+ /* We have a match */
+ strcpy(hostname, local_host);
+ fclose(fp);
+ return(0);
+ }
+ }
+ }
+ fclose(fp);
+ return (1);
+}
+
+/*
+ * Map a hostname to an ethernet address using /etc/ethers or
+ * NIS/YP.
+ */
+int ether_hostton(hostname, e)
+ char *hostname;
+ struct ether_addr *e;
+{
+ FILE *fp;
+ char buf[BUFSIZ + 2];
+ struct ether_addr local_ether;
+ char local_host[MAXHOSTNAMELEN];
+#ifdef YP
+ char *result;
+ int resultlen;
+ char *yp_domain;
+#endif
+ if ((fp = fopen(_PATH_ETHERS, "r")) == NULL)
+ return (1);
+
+ while (fgets(buf,BUFSIZ,fp)) {
+ if (buf[0] == '#')
+ continue;
+#ifdef YP
+ if (buf[0] == '+') {
+ if (yp_get_default_domain(&yp_domain))
+ continue;
+ if (yp_match(yp_domain, "ethers.byname", hostname,
+ strlen(hostname), &result, &resultlen)) {
+ continue;
+ }
+ strncpy(buf, result, resultlen);
+ buf[resultlen] = '\0';
+ free(result);
+ }
+#endif
+ if (!ether_line(buf, &local_ether, local_host)) {
+ if (!strcmp(hostname, local_host)) {
+ /* We have a match */
+ bcopy((char *)&local_ether.octet[0],
+ (char *)&e->octet[0], 6);
+ fclose(fp);
+ return(0);
+ }
+ }
+ }
+ fclose(fp);
+ return (1);
+}
diff --git a/cpukit/libnetworking/libc/ethers.3 b/cpukit/libnetworking/libc/ethers.3
new file mode 100644
index 0000000000..afea48320a
--- /dev/null
+++ b/cpukit/libnetworking/libc/ethers.3
@@ -0,0 +1,193 @@
+.\" Copyright (c) 1995
+.\" Bill Paul <wpaul@ctr.columbia.edu>. 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 Bill Paul.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Bill Paul 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.
+.\"
+.\" $Id$
+.\"
+.Dd April 12, 1995
+.Dt ETHERS 3
+.Os FreeBSD 2.1
+.Sh NAME
+.Nm ethers ,
+.Nm ether_line ,
+.Nm ether_aton ,
+.Nm ether_ntoa ,
+.Nm ether_ntohost ,
+.Nm ether_hostton
+.Nd Ethernet address conversion and lookup routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Fd #include <net/ethernet.h>
+.Ft int
+.Fn ether_line "char *l" "struct ether_addr *e" "char *hostname"
+.Ft struct ether_addr *
+.Fn ether_aton "char *a"
+.Ft char *
+.Fn ether_ntoa "struct ether_addr *n"
+.Ft int
+.Fn ether_ntohost "char *hostname" "struct ether_addr *e"
+.Ft int
+.Fn ether_hostton "char *hostname" "struct ether_addr *e"
+.Sh DESCRIPTION
+These functions operate on ethernet addresses using an
+.Ar ether_addr
+structure, which is defined in the header file
+.Aq Pa netinet/if_ether.h :
+.Bd -literal -offset indent
+/*
+ * The number of bytes in an ethernet (MAC) address.
+ */
+#define ETHER_ADDR_LEN 6
+
+/*
+ * Structure of a 48-bit Ethernet address.
+ */
+struct ether_addr {
+ u_char octet[ETHER_ADDR_LEN];
+};
+.Ed
+.Pp
+The function
+.Fn ether_line
+scans
+.Ar l ,
+an
+.Tn ASCII
+string in
+.Xr ethers 5
+format and sets
+.Ar e
+to the ethernet address specified in the string and
+.Ar h
+to the hostname. This function is used to parse lines from
+.Pa /etc/ethers
+into their component parts.
+.Pp
+The
+.Fn ether_aton
+function converts an
+.Tn ASCII
+representation of an ethernet address into an
+.Ar ether_addr
+structure. Likewise,
+.Fn ether_ntoa
+converts an ethernet address specified as an
+.Ar ether_addr
+structure into an
+.Tn ASCII
+string.
+.Pp
+The
+.Fn ether_ntohost
+and
+.Fn ether_hostton
+functions map ethernet addresses to their corresponding hostnames
+as specified in the
+.Pa /etc/ethers
+database.
+.Fn ether_ntohost
+converts from ethernet address to hostname, and
+.Fn ether_hostton
+converts from hostname to ethernet address.
+.Sh RETURN VALUES
+.Fn ether_line
+returns zero on success and non-zero if it was unable to parse
+any part of the supplied line
+.Ar l .
+It returns the extracted ethernet address in the supplied
+.Ar ether_addr
+structure
+.Ar e
+and the hostname in the supplied string
+.Ar h .
+.Pp
+On success,
+.Fn ether_ntoa
+returns a pointer to a string containing an
+.Tn ASCII
+representation of an ethernet address. If it is unable to convert
+the supplied
+.Ar ether_addr
+structure, it returns a
+.Dv NULL
+pointer. Likewise,
+.Fn ether_aton
+returns a pointer to an
+.Ar ether_addr
+structure on success and a
+.Dv NULL
+pointer on failure.
+.Pp
+The
+.Fn ether_ntohost
+and
+.Fn ether_hostton
+functions both return zero on success or non-zero if they were
+unable to find a match in the
+.Pa /etc/ethers
+database.
+.Sh NOTES
+The user must insure that the hostname strings passed to the
+the
+.Fn ether_line ,
+.Fn ether_ntohost
+and
+.Fn ether_hostton
+functions are large enough to contain the returned hostnames.
+.Sh NIS INTERACTION
+If the
+.Pa /etc/ethers
+contains a line with a single + in it, the
+.Fn ether_ntohost
+and
+.Fn ether_hostton
+functions will attempt to consult the NIS
+.Pa ethers.byname
+and
+.Pa ethers.byaddr
+maps in addition to the data in the
+.Pa /etc/ethers
+file.
+.Sh SEE ALSO
+.Xr yp 4 ,
+.Xr ethers 5
+.Sh BUGS
+.Pp
+The
+.Fn ether_aton
+and
+.Fn ether_ntoa
+functions returns values that are stored in static memory areas
+which may be overwritten the next time they are called.
+.Sh HISTORY
+This particular implementation of the
+.Nm ethers
+library functions were written for and first appeared in
+.Fx 2.1 .
diff --git a/cpukit/libnetworking/libc/gethostbydns.c b/cpukit/libnetworking/libc/gethostbydns.c
new file mode 100644
index 0000000000..6c53aa0662
--- /dev/null
+++ b/cpukit/libnetworking/libc/gethostbydns.c
@@ -0,0 +1,775 @@
+/*
+ * ++Copyright++ 1985, 1988, 1993
+ * -
+ * Copyright (c) 1985, 1988, 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.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
+static char fromrcsid[] = "From: Id: gethnamaddr.c,v 8.23 1998/04/07 04:59:46 vixie Exp $";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <syslog.h>
+
+#include "res_config.h"
+
+void abort(void); /* to avoid warning */
+
+#define SPRINTF(x) ((size_t)sprintf x)
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+static const char AskedForGot[] =
+ "gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
+
+static char *h_addr_ptrs[MAXADDRS + 1];
+
+static struct hostent host;
+static char *host_aliases[MAXALIASES];
+static char hostbuf[8*1024];
+static u_char host_addr[16]; /* IPv4 or IPv6 */
+
+#ifdef RESOLVSORT
+static void addrsort __P((char **, int));
+#endif
+
+#if PACKETSZ > 1024
+#define MAXPACKET PACKETSZ
+#else
+#define MAXPACKET 1024
+#endif
+
+typedef union {
+ HEADER hdr;
+ u_char buf[MAXPACKET];
+} querybuf;
+
+typedef union {
+ int32_t al;
+ char ac;
+} align;
+
+extern int h_errno;
+int _dns_ttl_;
+
+#ifdef DEBUG
+static void
+debugprintf(msg, num)
+ char *msg;
+ int num;
+{
+ if (_res.options & RES_DEBUG) {
+ int save = errno;
+
+ printf(msg, num);
+ errno = save;
+ }
+}
+#else
+#define debugprintf(msg, num) /*nada*/
+#endif
+
+#define BOUNDED_INCR(x) \
+ do { \
+ cp += x; \
+ if (cp > eom) { \
+ h_errno = NO_RECOVERY; \
+ return (NULL); \
+ } \
+ } while (0)
+
+#define BOUNDS_CHECK(ptr, count) \
+ do { \
+ if ((ptr) + (count) > eom) { \
+ h_errno = NO_RECOVERY; \
+ return (NULL); \
+ } \
+ } while (0)
+
+static struct hostent *
+gethostanswer(answer, anslen, qname, qtype)
+ const querybuf *answer;
+ int anslen;
+ const char *qname;
+ int qtype;
+{
+ register const HEADER *hp;
+ register const u_char *cp;
+ register int n;
+ const u_char *eom, *erdata;
+ char *bp, **ap, **hap;
+ int type, class, buflen, ancount, qdcount;
+ int haveanswer, had_error;
+ int toobig = 0;
+ char tbuf[MAXDNAME];
+ const char *tname;
+ int (*name_ok) __P((const char *));
+
+ tname = qname;
+ host.h_name = NULL;
+ eom = answer->buf + anslen;
+ switch (qtype) {
+ case T_A:
+ case T_AAAA:
+ name_ok = res_hnok;
+ break;
+ case T_PTR:
+ name_ok = res_dnok;
+ break;
+ default:
+ h_errno = NO_RECOVERY;
+ return (NULL); /* XXX should be abort(); */
+ }
+ /*
+ * find first satisfactory answer
+ */
+ hp = &answer->hdr;
+ ancount = ntohs(hp->ancount);
+ qdcount = ntohs(hp->qdcount);
+ bp = hostbuf;
+ buflen = sizeof hostbuf;
+ cp = answer->buf;
+ BOUNDED_INCR(HFIXEDSZ);
+ if (qdcount != 1) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !(*name_ok)(bp)) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ BOUNDED_INCR(n + QFIXEDSZ);
+ if (qtype == T_A || qtype == T_AAAA) {
+ /* res_send() has already verified that the query name is the
+ * same as the one we sent; this just gets the expanded name
+ * (i.e., with the succeeding search-domain tacked on).
+ */
+ n = strlen(bp) + 1; /* for the \0 */
+ if (n >= MAXHOSTNAMELEN) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ host.h_name = bp;
+ bp += n;
+ buflen -= n;
+ /* The qname can be abbreviated, but h_name is now absolute. */
+ qname = host.h_name;
+ }
+ ap = host_aliases;
+ *ap = NULL;
+ host.h_aliases = host_aliases;
+ hap = h_addr_ptrs;
+ *hap = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ haveanswer = 0;
+ had_error = 0;
+ _dns_ttl_ = -1;
+ while (ancount-- > 0 && cp < eom && !had_error) {
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !(*name_ok)(bp)) {
+ had_error++;
+ continue;
+ }
+ cp += n; /* name */
+ BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
+ type = _getshort(cp);
+ cp += INT16SZ; /* type */
+ class = _getshort(cp);
+ cp += INT16SZ; /* class */
+ if (qtype == T_A && type == T_A)
+ _dns_ttl_ = _getlong(cp);
+ cp += INT32SZ; /* TTL */
+ n = _getshort(cp);
+ cp += INT16SZ; /* len */
+ BOUNDS_CHECK(cp, n);
+ erdata = cp + n;
+ if (class != C_IN) {
+ /* XXX - debug? syslog? */
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
+ if (ap >= &host_aliases[MAXALIASES-1])
+ continue;
+ n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
+ if ((n < 0) || !(*name_ok)(tbuf)) {
+ had_error++;
+ continue;
+ }
+ cp += n;
+ if (cp != erdata) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ /* Store alias. */
+ *ap++ = bp;
+ n = strlen(bp) + 1; /* for the \0 */
+ if (n >= MAXHOSTNAMELEN) {
+ had_error++;
+ continue;
+ }
+ bp += n;
+ buflen -= n;
+ /* Get canonical name. */
+ n = strlen(tbuf) + 1; /* for the \0 */
+ if (n > buflen || n >= MAXHOSTNAMELEN) {
+ had_error++;
+ continue;
+ }
+ strcpy(bp, tbuf);
+ host.h_name = bp;
+ bp += n;
+ buflen -= n;
+ continue;
+ }
+ if (qtype == T_PTR && type == T_CNAME) {
+ n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
+ if (n < 0 || !res_dnok(tbuf)) {
+ had_error++;
+ continue;
+ }
+ cp += n;
+ if (cp != erdata) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ /* Get canonical name. */
+ n = strlen(tbuf) + 1; /* for the \0 */
+ if (n > buflen || n >= MAXHOSTNAMELEN) {
+ had_error++;
+ continue;
+ }
+ strcpy(bp, tbuf);
+ tname = bp;
+ bp += n;
+ buflen -= n;
+ continue;
+ }
+ if (type != qtype) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",
+ qname, p_class(C_IN), p_type(qtype),
+ p_type(type));
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ switch (type) {
+ case T_PTR:
+ if (strcasecmp(tname, bp) != 0) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ AskedForGot, qname, bp);
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !res_hnok(bp)) {
+ had_error++;
+ break;
+ }
+#if MULTI_PTRS_ARE_ALIASES
+ cp += n;
+ if (cp != erdata) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ if (!haveanswer)
+ host.h_name = bp;
+ else if (ap < &host_aliases[MAXALIASES-1])
+ *ap++ = bp;
+ else
+ n = -1;
+ if (n != -1) {
+ n = strlen(bp) + 1; /* for the \0 */
+ if (n >= MAXHOSTNAMELEN) {
+ had_error++;
+ break;
+ }
+ bp += n;
+ buflen -= n;
+ }
+ break;
+#else
+ host.h_name = bp;
+ if (_res.options & RES_USE_INET6) {
+ n = strlen(bp) + 1; /* for the \0 */
+ if (n >= MAXHOSTNAMELEN) {
+ had_error++;
+ break;
+ }
+ bp += n;
+ buflen -= n;
+ _map_v4v6_hostent(&host, &bp, &buflen);
+ }
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+#endif
+ case T_A:
+ case T_AAAA:
+ if (strcasecmp(host.h_name, bp) != 0) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ AskedForGot, host.h_name, bp);
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ if (n != host.h_length) {
+ cp += n;
+ continue;
+ }
+ if (!haveanswer) {
+ register int nn;
+
+ host.h_name = bp;
+ nn = strlen(bp) + 1; /* for the \0 */
+ bp += nn;
+ buflen -= nn;
+ }
+
+ bp += sizeof(align) - ((u_long)bp % sizeof(align));
+
+ if (bp + n >= &hostbuf[sizeof hostbuf]) {
+ debugprintf("size (%d) too big\n", n);
+ had_error++;
+ continue;
+ }
+ if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
+ if (!toobig++)
+ debugprintf("Too many addresses (%d)\n",
+ MAXADDRS);
+ cp += n;
+ continue;
+ }
+ bcopy(cp, *hap++ = bp, n);
+ bp += n;
+ buflen -= n;
+ cp += n;
+ if (cp != erdata) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ break;
+ default:
+ debugprintf("Impossible condition (type=%d)\n", type);
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ /* BIND has abort() here, too risky on bad data */
+ }
+ if (!had_error)
+ haveanswer++;
+ }
+ if (haveanswer) {
+ *ap = NULL;
+ *hap = NULL;
+# if defined(RESOLVSORT)
+ /*
+ * Note: we sort even if host can take only one address
+ * in its return structures - should give it the "best"
+ * address in that case, not some random one
+ */
+ if (_res.nsort && haveanswer > 1 && qtype == T_A)
+ addrsort(h_addr_ptrs, haveanswer);
+# endif /*RESOLVSORT*/
+ if (!host.h_name) {
+ n = strlen(qname) + 1; /* for the \0 */
+ if (n > buflen || n >= MAXHOSTNAMELEN)
+ goto no_recovery;
+ strcpy(bp, qname);
+ host.h_name = bp;
+ bp += n;
+ buflen -= n;
+ }
+ if (_res.options & RES_USE_INET6)
+ _map_v4v6_hostent(&host, &bp, &buflen);
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+ }
+ no_recovery:
+ h_errno = NO_RECOVERY;
+ return (NULL);
+}
+
+struct hostent *
+__dns_getanswer(answer, anslen, qname, qtype)
+ const char *answer;
+ int anslen;
+ const char *qname;
+ int qtype;
+{
+ switch(qtype) {
+ case T_AAAA:
+ host.h_addrtype = AF_INET6;
+ host.h_length = IN6ADDRSZ;
+ break;
+ case T_A:
+ default:
+ host.h_addrtype = AF_INET;
+ host.h_length = INADDRSZ;
+ break;
+ }
+
+ return(gethostanswer((const querybuf *)answer, anslen, qname, qtype));
+}
+
+struct hostent *
+_gethostbydnsname(name, af)
+ const char *name;
+ int af;
+{
+ querybuf buf;
+ register const char *cp;
+ char *bp;
+ int n, size, type, len;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+
+ switch (af) {
+ case AF_INET:
+ size = INADDRSZ;
+ type = T_A;
+ break;
+ case AF_INET6:
+ size = IN6ADDRSZ;
+ type = T_AAAA;
+ break;
+ default:
+ h_errno = NETDB_INTERNAL;
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+
+ host.h_addrtype = af;
+ host.h_length = size;
+
+ /*
+ * if there aren't any dots, it could be a user-level alias.
+ * this is also done in res_query() since we are not the only
+ * function that looks up host names.
+ */
+ if (!strchr(name, '.') && (cp = __hostalias(name)))
+ name = cp;
+
+ /*
+ * disallow names consisting only of digits/dots, unless
+ * they end in a dot.
+ */
+ if (isdigit((int)name[0]))
+ for (cp = name;; ++cp) {
+ if (!*cp) {
+ if (*--cp == '.')
+ break;
+ /*
+ * All-numeric, no dot at the end.
+ * Fake up a hostent as if we'd actually
+ * done a lookup.
+ */
+ if (inet_pton(af, name, host_addr) <= 0) {
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ strncpy(hostbuf, name, MAXDNAME);
+ hostbuf[MAXDNAME] = '\0';
+ bp = hostbuf + MAXDNAME;
+ len = sizeof hostbuf - MAXDNAME;
+ host.h_name = hostbuf;
+ host.h_aliases = host_aliases;
+ host_aliases[0] = NULL;
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ if (_res.options & RES_USE_INET6)
+ _map_v4v6_hostent(&host, &bp, &len);
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+ }
+ if (!isdigit((int)*cp) && *cp != '.')
+ break;
+ }
+ if ((isxdigit((int)name[0]) && strchr(name, ':') != NULL) ||
+ name[0] == ':')
+ for (cp = name;; ++cp) {
+ if (!*cp) {
+ if (*--cp == '.')
+ break;
+ /*
+ * All-IPv6-legal, no dot at the end.
+ * Fake up a hostent as if we'd actually
+ * done a lookup.
+ */
+ if (inet_pton(af, name, host_addr) <= 0) {
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ strncpy(hostbuf, name, MAXDNAME);
+ hostbuf[MAXDNAME] = '\0';
+ bp = hostbuf + MAXDNAME;
+ len = sizeof hostbuf - MAXDNAME;
+ host.h_name = hostbuf;
+ host.h_aliases = host_aliases;
+ host_aliases[0] = NULL;
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+ }
+ if (!isxdigit((int)*cp) && *cp != ':' && *cp != '.')
+ break;
+ }
+
+ if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) {
+ debugprintf("res_search failed (%d)\n", n);
+ return (NULL);
+ }
+ return (gethostanswer(&buf, n, name, type));
+}
+
+struct hostent *
+_gethostbydnsaddr(addr, len, af)
+ const char *addr; /* XXX should have been def'd as u_char! */
+ int len, af;
+{
+ const u_char *uaddr = (const u_char *)addr;
+ static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
+ static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
+ int n, size;
+ querybuf buf;
+ register struct hostent *hp;
+ char qbuf[MAXDNAME+1], *qp;
+#ifdef SUNSECURITY
+ register struct hostent *rhp;
+ char **haddr;
+ u_long old_options;
+ char hname2[MAXDNAME+1];
+#endif /*SUNSECURITY*/
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ if (af == AF_INET6 && len == IN6ADDRSZ &&
+ (!bcmp(uaddr, mapped, sizeof mapped) ||
+ !bcmp(uaddr, tunnelled, sizeof tunnelled))) {
+ /* Unmap. */
+ addr += sizeof mapped;
+ uaddr += sizeof mapped;
+ af = AF_INET;
+ len = INADDRSZ;
+ }
+ switch (af) {
+ case AF_INET:
+ size = INADDRSZ;
+ break;
+ case AF_INET6:
+ size = IN6ADDRSZ;
+ break;
+ default:
+ errno = EAFNOSUPPORT;
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ if (size != len) {
+ errno = EINVAL;
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ switch (af) {
+ case AF_INET:
+ (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
+ (uaddr[3] & 0xff),
+ (uaddr[2] & 0xff),
+ (uaddr[1] & 0xff),
+ (uaddr[0] & 0xff));
+ break;
+ case AF_INET6:
+ qp = qbuf;
+ for (n = IN6ADDRSZ - 1; n >= 0; n--) {
+ qp += SPRINTF((qp, "%x.%x.",
+ uaddr[n] & 0xf,
+ (uaddr[n] >> 4) & 0xf));
+ }
+ strcpy(qp, "ip6.int");
+ break;
+ default:
+ abort();
+ }
+ n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
+ if (n < 0) {
+ debugprintf("res_query failed (%d)\n", n);
+ return (NULL);
+ }
+ if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR)))
+ return (NULL); /* h_errno was set by gethostanswer() */
+#ifdef SUNSECURITY
+ if (af == AF_INET) {
+ /*
+ * turn off search as the name should be absolute,
+ * 'localhost' should be matched by defnames
+ */
+ strncpy(hname2, hp->h_name, MAXDNAME);
+ hname2[MAXDNAME] = '\0';
+ old_options = _res.options;
+ _res.options &= ~RES_DNSRCH;
+ _res.options |= RES_DEFNAMES;
+ if (!(rhp = gethostbyname(hname2))) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostbyaddr: No A record for %s (verifying [%s])",
+ hname2, inet_ntoa(*((struct in_addr *)addr)));
+ _res.options = old_options;
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ _res.options = old_options;
+ for (haddr = rhp->h_addr_list; *haddr; haddr++)
+ if (!memcmp(*haddr, addr, INADDRSZ))
+ break;
+ if (!*haddr) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostbyaddr: A record of %s != PTR record [%s]",
+ hname2, inet_ntoa(*((struct in_addr *)addr)));
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ }
+#endif /*SUNSECURITY*/
+ hp->h_addrtype = af;
+ hp->h_length = len;
+ bcopy(addr, host_addr, len);
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ if (af == AF_INET && (_res.options & RES_USE_INET6)) {
+ _map_v4v6_address((char*)host_addr, (char*)host_addr);
+ hp->h_addrtype = AF_INET6;
+ hp->h_length = IN6ADDRSZ;
+ }
+ h_errno = NETDB_SUCCESS;
+ return (hp);
+}
+
+#ifdef RESOLVSORT
+static void
+addrsort(ap, num)
+ char **ap;
+ int num;
+{
+ int i, j;
+ char **p;
+ short aval[MAXADDRS];
+ int needsort = 0;
+
+ p = ap;
+ for (i = 0; i < num; i++, p++) {
+ for (j = 0 ; (unsigned)j < _res.nsort; j++)
+ if (_res.sort_list[j].addr.s_addr ==
+ (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
+ break;
+ aval[i] = j;
+ if (needsort == 0 && i > 0 && j < aval[i-1])
+ needsort = i;
+ }
+ if (!needsort)
+ return;
+
+ while (needsort < num) {
+ for (j = needsort - 1; j >= 0; j--) {
+ if (aval[j] > aval[j+1]) {
+ char *hp;
+
+ i = aval[j];
+ aval[j] = aval[j+1];
+ aval[j+1] = i;
+
+ hp = ap[j];
+ ap[j] = ap[j+1];
+ ap[j+1] = hp;
+
+ } else
+ break;
+ }
+ needsort++;
+ }
+}
+#endif
+void
+_sethostdnsent(stayopen)
+ int stayopen;
+{
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return;
+ if (stayopen)
+ _res.options |= RES_STAYOPEN | RES_USEVC;
+}
+
+void
+_endhostdnsent()
+{
+ _res.options &= ~(RES_STAYOPEN | RES_USEVC);
+ res_close();
+}
diff --git a/cpukit/libnetworking/libc/gethostbyht.c b/cpukit/libnetworking/libc/gethostbyht.c
new file mode 100644
index 0000000000..29f2805367
--- /dev/null
+++ b/cpukit/libnetworking/libc/gethostbyht.c
@@ -0,0 +1,202 @@
+/*-
+ * Copyright (c) 1985, 1988, 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.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <arpa/nameser.h> /* XXX */
+#include <resolv.h> /* XXX */
+
+#define MAXALIASES 35
+
+static struct hostent host;
+static char *host_aliases[MAXALIASES];
+static char hostbuf[BUFSIZ+1];
+static FILE *hostf = NULL;
+static u_char host_addr[16]; /* IPv4 or IPv6 */
+static char *h_addr_ptrs[2];
+static int stayopen = 0;
+
+void
+_sethosthtent(f)
+ int f;
+{
+ if (!hostf)
+ hostf = fopen(_PATH_HOSTS, "r" );
+ else
+ rewind(hostf);
+ stayopen = f;
+}
+
+void
+_endhosthtent()
+{
+ if (hostf && !stayopen) {
+ (void) fclose(hostf);
+ hostf = NULL;
+ }
+}
+
+struct hostent *
+gethostent()
+{
+ char *p;
+ register char *cp, **q;
+ int af, len;
+
+ if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ again:
+ if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) {
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ if (*p == '#')
+ goto again;
+ if (!(cp = strpbrk(p, "#\n")))
+ goto again;
+ *cp = '\0';
+ if (!(cp = strpbrk(p, " \t")))
+ goto again;
+ *cp++ = '\0';
+ if (inet_pton(AF_INET6, p, host_addr) > 0) {
+ af = AF_INET6;
+ len = IN6ADDRSZ;
+ } else if (inet_pton(AF_INET, p, host_addr) > 0) {
+ if (_res.options & RES_USE_INET6) {
+ _map_v4v6_address((char*)host_addr, (char*)host_addr);
+ af = AF_INET6;
+ len = IN6ADDRSZ;
+ } else {
+ af = AF_INET;
+ len = INADDRSZ;
+ }
+ } else {
+ goto again;
+ }
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ host.h_length = len;
+ host.h_addrtype = af;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ host.h_name = cp;
+ q = host.h_aliases = host_aliases;
+ if ((cp = strpbrk(cp, " \t")) != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &host_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ if ((cp = strpbrk(cp, " \t")) != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+}
+
+struct hostent *
+_gethostbyhtname(name, af)
+ const char *name;
+ int af;
+{
+ register struct hostent *p;
+ register char **cp;
+
+ sethostent(0);
+ while ((p = gethostent()) != NULL) {
+ if (p->h_addrtype != af)
+ continue;
+ if (strcasecmp(p->h_name, name) == 0)
+ break;
+ for (cp = p->h_aliases; *cp != 0; cp++)
+ if (strcasecmp(*cp, name) == 0)
+ goto found;
+ }
+found:
+ endhostent();
+ return (p);
+}
+
+struct hostent *
+_gethostbyhtaddr(addr, len, af)
+ const char *addr;
+ int len, af;
+{
+ register struct hostent *p;
+
+ sethostent(0);
+ while ((p = gethostent()) != NULL)
+ if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
+ break;
+ endhostent();
+ return (p);
+}
diff --git a/cpukit/libnetworking/libc/gethostbyname.3 b/cpukit/libnetworking/libc/gethostbyname.3
new file mode 100644
index 0000000000..e21dc79f1d
--- /dev/null
+++ b/cpukit/libnetworking/libc/gethostbyname.3
@@ -0,0 +1,305 @@
+.\" Copyright (c) 1983, 1987, 1991, 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.
+.\"
+.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
+.\" $Id$
+.\"
+.Dd May 25, 1995
+.Dt GETHOSTBYNAME 3
+.Os BSD 4.2
+.Sh NAME
+.Nm gethostbyname ,
+.Nm gethostbyname2 ,
+.Nm gethostbyaddr ,
+.Nm gethostent ,
+.Nm sethostent ,
+.Nm endhostent ,
+.Nm herror ,
+.Nm hstrerror
+.Nd get network host entry
+.Sh SYNOPSIS
+.Fd #include <netdb.h>
+.Vt extern int h_errno;
+.Ft struct hostent *
+.Fn gethostbyname "const char *name"
+.Ft struct hostent *
+.Fn gethostbyname2 "const char *name" "int af"
+.Ft struct hostent *
+.Fn gethostbyaddr "const char *addr" "int len" "int type"
+.Ft struct hostent *
+.Fn gethostent void
+.Ft void
+.Fn sethostent "int stayopen"
+.Ft void
+.Fn endhostent void
+.Ft void
+.Fn herror "const char *string"
+.Ft const char *
+.Fn hstrerror "int err"
+.Sh DESCRIPTION
+The
+.Fn gethostbyname ,
+.Fn gethostbyname2
+and
+.Fn gethostbyaddr
+functions
+each return a pointer to an object with the
+following structure describing an internet host
+referenced by name or by address, respectively.
+This structure contains either the information obtained from the name server,
+.Xr named 8 ,
+or broken-out fields from a line in
+.Pa /etc/hosts .
+If the local name server is not running these routines do a lookup in
+.Pa /etc/hosts .
+.Bd -literal
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width h_addr_list
+.It Fa h_name
+Official name of the host.
+.It Fa h_aliases
+A NULL-terminated array of alternate names for the host.
+.It Fa h_addrtype
+The type of address being returned; usually
+.Dv AF_INET .
+.It Fa h_length
+The length, in bytes, of the address.
+.It Fa h_addr_list
+A NULL-terminated array of network addresses for the host.
+Host addresses are returned in network byte order.
+.It Fa h_addr
+The first address in
+.Fa h_addr_list ;
+this is for backward compatibility.
+.El
+.Pp
+When using the nameserver,
+.Fn gethostbyname
+and
+.Fn gethostbyname
+will search for the named host in the current domain and its parents
+unless the name ends in a dot.
+If the name contains no dot, and if the environment variable
+.Dq Ev HOSTALIASES
+contains the name of an alias file, the alias file will first be searched
+for an alias matching the input name.
+See
+.Xr hostname 7
+for the domain search procedure and the alias file format.
+.Pp
+The
+.Fn gethostbyname2
+function is an evolution of
+.Fn gethostbyname
+which is intended to allow lookups in address families other than
+.Dv AF_INET ,
+for example
+.Dv AF_INET6 .
+Currently the
+.Fa af
+argument must be specified as
+.Dv AF_INET
+else the function will return
+.Dv NULL
+after having set
+.Va h_errno
+to
+.Dv NETDB_INTERNAL
+.Pp
+The
+.Fn sethostent
+function
+may be used to request the use of a connected
+.Tn TCP
+socket for queries.
+If the
+.Fa stayopen
+flag is non-zero,
+this sets the option to send all queries to the name server using
+.Tn TCP
+and to retain the connection after each call to
+.Fn gethostbyname ,
+.Fn gethostbyname2
+or
+.Fn gethostbyaddr .
+Otherwise, queries are performed using
+.Tn UDP
+datagrams.
+.Pp
+The
+.Fn endhostent
+function
+closes the
+.Tn TCP
+connection.
+.Pp
+The
+.Fn herror
+function writes a message to the diagnostic output consisting of the
+string parameter
+.Fa s ,
+the constant string ": ", and a message corresponding to the value of
+.Va h_errno .
+.Pp
+The
+.Fn hstrerror
+function returns a string which is the message text corresponding to the
+value of the
+.Fa err
+parameter.
+.Sh FILES
+.Bl -tag -width /etc/resolv.conf -compact
+.It Pa /etc/hosts
+.It Pa /etc/host.conf
+.It Pa /etc/resolv.conf
+.El
+.Sh DIAGNOSTICS
+Error return status from
+.Fn gethostbyname ,
+.Fn gethostbyname2
+and
+.Fn gethostbyaddr
+is indicated by return of a null pointer.
+The external integer
+.Va h_errno
+may then be checked to see whether this is a temporary failure
+or an invalid or unknown host.
+The routine
+.Fn herror
+can be used to print an error message describing the failure.
+If its argument
+.Fa string
+is
+.Pf non Dv -NULL ,
+it is printed, followed by a colon and a space.
+The error message is printed with a trailing newline.
+.Pp
+The variable
+.Va h_errno
+can have the following values:
+.Bl -tag -width HOST_NOT_FOUND
+.It Dv HOST_NOT_FOUND
+No such host is known.
+.It Dv TRY_AGAIN
+This is usually a temporary error
+and means that the local server did not receive
+a response from an authoritative server.
+A retry at some later time may succeed.
+.It Dv NO_RECOVERY
+Some unexpected server failure was encountered.
+This is a non-recoverable error.
+.It Dv NO_DATA
+The requested name is valid but does not have an IP address;
+this is not a temporary error.
+This means that the name is known to the name server but there is no address
+associated with this name.
+Another type of request to the name server using this domain name
+will result in an answer;
+for example, a mail-forwarder may be registered for this domain.
+.El
+.Sh SEE ALSO
+.Xr resolver 3 ,
+.Xr hosts 5 ,
+.Xr hostname 7 ,
+.Xr named 8
+.Sh CAVEAT
+The
+.Fn gethostent
+function
+is defined, and
+.Fn sethostent
+and
+.Fn endhostent
+are redefined,
+when
+.Xr libc 3
+is built to use only the routines to lookup in
+.Pa /etc/hosts
+and not the name server.
+.Pp
+The
+.Fn gethostent
+function
+reads the next line of
+.Pa /etc/hosts ,
+opening the file if necessary.
+.Pp
+The
+.Fn sethostent
+function
+opens and/or rewinds the file
+.Pa /etc/hosts .
+If the
+.Fa stayopen
+argument is non-zero,
+the file will not be closed after each call to
+.Fn gethostbyname ,
+.Fn gethostbyname2
+or
+.Fn gethostbyaddr .
+.Pp
+The
+.Fn endhostent
+function
+closes the file.
+.Sh HISTORY
+The
+.Fn herror
+function appeared in
+.Bx 4.3 .
+The
+.Fn endhostent ,
+.Fn gethostbyaddr ,
+.Fn gethostbyname ,
+.Fn gethostent ,
+and
+.Fn sethostent
+functions appeared in
+.Bx 4.2 .
+The
+.Fn gethostbyname2
+function first appeared in bind-4.9.4.
+.Sh BUGS
+These functions use static data storage;
+if the data is needed for future use, it should be
+copied before any subsequent calls overwrite it.
+Only the Internet
+address format is currently understood.
diff --git a/cpukit/libnetworking/libc/gethostbynis.c b/cpukit/libnetworking/libc/gethostbynis.c
new file mode 100644
index 0000000000..45dbe5a85d
--- /dev/null
+++ b/cpukit/libnetworking/libc/gethostbynis.c
@@ -0,0 +1,142 @@
+/*-
+ * Copyright (c) 1994, Garrett Wollman
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)$Id$";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+#ifdef YP
+static char *host_aliases[MAXALIASES];
+static char hostaddr[MAXADDRS];
+static char *host_addrs[2];
+#endif /* YP */
+
+static struct hostent *
+_gethostbynis(name, map, af)
+ const char *name;
+ char *map;
+ int af;
+{
+#ifdef YP
+ register char *cp, **q;
+ char *result;
+ int resultlen;
+ static struct hostent h;
+ static char *domain = (char *)NULL;
+ static char ypbuf[YPMAXRECORD + 2];
+
+ switch(af) {
+ case AF_INET:
+ break;
+ default:
+ case AF_INET6:
+ errno = EAFNOSUPPORT;
+ return NULL;
+ }
+
+ if (domain == (char *)NULL)
+ if (yp_get_default_domain (&domain))
+ return ((struct hostent *)NULL);
+
+ if (yp_match(domain, map, name, strlen(name), &result, &resultlen))
+ return ((struct hostent *)NULL);
+
+ /* avoid potential memory leak */
+ bcopy((char *)result, (char *)&ypbuf, resultlen);
+ ypbuf[resultlen] = '\0';
+ free(result);
+ result = (char *)&ypbuf;
+
+ if ((cp = index(result, '\n')))
+ *cp = '\0';
+
+ cp = strpbrk(result, " \t");
+ *cp++ = '\0';
+ h.h_addr_list = host_addrs;
+ h.h_addr = hostaddr;
+ *((u_long *)h.h_addr) = inet_addr(result);
+ h.h_length = sizeof(u_long);
+ h.h_addrtype = AF_INET;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ h.h_name = cp;
+ q = h.h_aliases = host_aliases;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &host_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return (&h);
+#else
+ return (NULL);
+#endif /* YP */
+}
+
+struct hostent *
+_gethostbynisname(name, af)
+ const char *name;
+ int af;
+{
+ return _gethostbynis(name, "hosts.byname", af);
+}
+
+struct hostent *
+_gethostbynisaddr(addr, len, af)
+ const char *addr;
+ int len;
+ int af;
+{
+ return _gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr", af);
+}
diff --git a/cpukit/libnetworking/libc/gethostnamadr.c b/cpukit/libnetworking/libc/gethostnamadr.c
new file mode 100644
index 0000000000..92f7a21014
--- /dev/null
+++ b/cpukit/libnetworking/libc/gethostnamadr.c
@@ -0,0 +1,224 @@
+/*-
+ * Copyright (c) 1994, Garrett Wollman
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)$Id$";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <arpa/nameser.h> /* XXX hack for _res */
+#include <resolv.h> /* XXX hack for _res */
+
+#define _PATH_HOSTCONF "/etc/host.conf"
+
+enum service_type {
+ SERVICE_NONE = 0,
+ SERVICE_BIND,
+ SERVICE_HOSTS,
+ SERVICE_NIS };
+#define SERVICE_MAX SERVICE_NIS
+
+static struct {
+ const char *name;
+ enum service_type type;
+} service_names[] = {
+ { "hosts", SERVICE_HOSTS },
+ { "/etc/hosts", SERVICE_HOSTS },
+ { "hosttable", SERVICE_HOSTS },
+ { "htable", SERVICE_HOSTS },
+ { "bind", SERVICE_BIND },
+ { "dns", SERVICE_BIND },
+ { "domain", SERVICE_BIND },
+ { "yp", SERVICE_NIS },
+ { "yellowpages", SERVICE_NIS },
+ { "nis", SERVICE_NIS },
+ { 0, SERVICE_NONE }
+};
+
+static enum service_type service_order[SERVICE_MAX + 1];
+static int service_done = 0;
+
+static enum service_type
+get_service_name(const char *name) {
+ int i;
+ for(i = 0; service_names[i].type != SERVICE_NONE; i++) {
+ if(!strcasecmp(name, service_names[i].name)) {
+ return service_names[i].type;
+ }
+ }
+ return SERVICE_NONE;
+}
+
+static void
+init_services()
+{
+ char *cp, *p, buf[BUFSIZ];
+ register int cc = 0;
+ FILE *fd;
+
+ if ((fd = (FILE *)fopen(_PATH_HOSTCONF, "r")) == NULL) {
+ /* make some assumptions */
+ service_order[0] = SERVICE_BIND;
+ service_order[1] = SERVICE_HOSTS;
+ service_order[2] = SERVICE_NONE;
+ } else {
+ while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {
+ if(buf[0] == '#')
+ continue;
+
+ p = buf;
+ while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
+ ;
+ if (cp == NULL)
+ continue;
+ do {
+ if (isalpha((int)cp[0])) {
+ service_order[cc] = get_service_name(cp);
+ if(service_order[cc] != SERVICE_NONE)
+ cc++;
+ }
+ while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
+ ;
+ } while(cp != NULL && cc < SERVICE_MAX);
+ }
+ service_order[cc] = SERVICE_NONE;
+ fclose(fd);
+ }
+ service_done = 1;
+}
+
+struct hostent *
+gethostbyname(const char *name)
+{
+ struct hostent *hp;
+
+ if (_res.options & RES_USE_INET6) { /* XXX */
+ hp = gethostbyname2(name, AF_INET6); /* XXX */
+ if (hp) /* XXX */
+ return (hp); /* XXX */
+ } /* XXX */
+ return (gethostbyname2(name, AF_INET));
+}
+
+struct hostent *
+gethostbyname2(const char *name, int type)
+{
+ struct hostent *hp = 0;
+ int nserv = 0;
+
+ if (!service_done)
+ init_services();
+
+ while (!hp) {
+ switch (service_order[nserv]) {
+ case SERVICE_NONE:
+ return NULL;
+ case SERVICE_HOSTS:
+ hp = _gethostbyhtname(name, type);
+ break;
+ case SERVICE_BIND:
+ hp = _gethostbydnsname(name, type);
+ break;
+ case SERVICE_NIS:
+ hp = _gethostbynisname(name, type);
+ break;
+ }
+ nserv++;
+ }
+ return hp;
+}
+
+struct hostent *
+gethostbyaddr(const char *addr, int len, int type)
+{
+ struct hostent *hp = 0;
+ int nserv = 0;
+
+ if (!service_done)
+ init_services();
+
+ while (!hp) {
+ switch (service_order[nserv]) {
+ case SERVICE_NONE:
+ return 0;
+ case SERVICE_HOSTS:
+ hp = _gethostbyhtaddr(addr, len, type);
+ break;
+ case SERVICE_BIND:
+ hp = _gethostbydnsaddr(addr, len, type);
+ break;
+ case SERVICE_NIS:
+ hp = _gethostbynisaddr(addr, len, type);
+ break;
+ }
+ nserv++;
+ }
+ return hp;
+}
+
+#ifdef _THREAD_SAFE
+struct hostent_data;
+
+/*
+ * Temporary function (not thread safe)
+ */
+int gethostbyaddr_r(const char *addr, int len, int type,
+ struct hostent *result, struct hostent_data *buffer)
+{
+ struct hostent *hp;
+ int ret;
+ if ((hp = gethostbyaddr(addr, len, type)) == NULL) {
+ ret = -1;
+ } else {
+ memcpy(result, hp, sizeof(struct hostent));
+ ret = 0;
+ }
+ return(ret);
+}
+#endif
+
+void
+sethostent(stayopen)
+ int stayopen;
+{
+ _sethosthtent(stayopen);
+ _sethostdnsent(stayopen);
+}
+
+void
+endhostent()
+{
+ _endhosthtent();
+ _endhostdnsent();
+}
diff --git a/cpukit/libnetworking/libc/gethostname.c b/cpukit/libnetworking/libc/gethostname.c
new file mode 100644
index 0000000000..81dc2267c2
--- /dev/null
+++ b/cpukit/libnetworking/libc/gethostname.c
@@ -0,0 +1,26 @@
+/*
+ * $Id$
+ */
+
+#include "config.h"
+
+/*
+ * Solaris doesn't include the gethostname call by default.
+ */
+#include <sys/utsname.h>
+#include <sys/systeminfo.h>
+
+#include <netdb.h>
+
+/*
+ * PUBLIC: #ifndef HAVE_GETHOSTNAME
+ * PUBLIC: int gethostname __P((char *, int));
+ * PUBLIC: #endif
+ */
+int
+gethostname(host, len)
+ char *host;
+ int len;
+{
+ return (sysinfo(SI_HOSTNAME, host, len) == -1 ? -1 : 0);
+}
diff --git a/cpukit/libnetworking/libc/getnetbydns.c b/cpukit/libnetworking/libc/getnetbydns.c
new file mode 100644
index 0000000000..8f8c576332
--- /dev/null
+++ b/cpukit/libnetworking/libc/getnetbydns.c
@@ -0,0 +1,313 @@
+/*-
+ * Copyright (c) 1985, 1988, 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.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
+ * Dep. Matematica Universidade de Coimbra, Portugal, Europe
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <syslog.h>
+
+#include "res_config.h"
+
+extern int h_errno;
+
+#define BYADDR 0
+#define BYNAME 1
+#define MAXALIASES 35
+
+#if PACKETSZ > 1024
+#define MAXPACKET PACKETSZ
+#else
+#define MAXPACKET 1024
+#endif
+
+typedef union {
+ HEADER hdr;
+ u_char buf[MAXPACKET];
+} querybuf;
+
+typedef union {
+ long al;
+ char ac;
+} align;
+
+static struct netent *
+getnetanswer(answer, anslen, net_i)
+ querybuf *answer;
+ int anslen;
+ int net_i;
+{
+
+ register HEADER *hp;
+ register u_char *cp;
+ register int n;
+ u_char *eom;
+ int type, class, buflen, ancount, qdcount, haveanswer, i, nchar;
+ char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];
+ char *in, *st, *pauxt, *bp, **ap;
+ char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
+static struct netent net_entry;
+static char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
+
+ /*
+ * find first satisfactory answer
+ *
+ * answer --> +------------+ ( MESSAGE )
+ * | Header |
+ * +------------+
+ * | Question | the question for the name server
+ * +------------+
+ * | Answer | RRs answering the question
+ * +------------+
+ * | Authority | RRs pointing toward an authority
+ * | Additional | RRs holding additional information
+ * +------------+
+ */
+ eom = answer->buf + anslen;
+ hp = &answer->hdr;
+ ancount = ntohs(hp->ancount); /* #/records in the answer section */
+ qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
+ bp = netbuf;
+ buflen = sizeof(netbuf);
+ cp = answer->buf + HFIXEDSZ;
+ if (!qdcount) {
+ if (hp->aa)
+ h_errno = HOST_NOT_FOUND;
+ else
+ h_errno = TRY_AGAIN;
+ return (NULL);
+ }
+ while (qdcount-- > 0)
+ cp += __dn_skipname(cp, eom) + QFIXEDSZ;
+ ap = net_aliases;
+ *ap = NULL;
+ net_entry.n_aliases = net_aliases;
+ haveanswer = 0;
+ while (--ancount >= 0 && cp < eom) {
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !res_dnok(bp))
+ break;
+ cp += n;
+ ans[0] = '\0';
+ (void)strncpy(&ans[0], bp, sizeof(ans) - 1);
+ ans[sizeof(ans) - 1] = '\0';
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ cp += INT32SZ; /* TTL */
+ GETSHORT(n, cp);
+ if (class == C_IN && type == T_PTR) {
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !res_hnok(bp)) {
+ cp += n;
+ return (NULL);
+ }
+ cp += n;
+ *ap++ = bp;
+ bp += strlen(bp) + 1;
+ net_entry.n_addrtype =
+ (class == C_IN) ? AF_INET : AF_UNSPEC;
+ haveanswer++;
+ }
+ }
+ if (haveanswer) {
+ *ap = NULL;
+ switch (net_i) {
+ case BYADDR:
+ net_entry.n_name = *net_entry.n_aliases;
+ net_entry.n_net = 0L;
+ break;
+ case BYNAME:
+ in = *net_entry.n_aliases;
+ net_entry.n_name = &ans[0];
+ aux2[0] = '\0';
+ for (i = 0; i < 4; i++) {
+ for (st = in, nchar = 0;
+ *st != '.';
+ st++, nchar++)
+ ;
+ if (nchar != 1 || *in != '0' || flag) {
+ flag = 1;
+ (void)strncpy(paux1,
+ (i==0) ? in : in-1,
+ (i==0) ?nchar : nchar+1);
+ paux1[(i==0) ? nchar : nchar+1] = '\0';
+ pauxt = paux2;
+ paux2 = strcat(paux1, paux2);
+ paux1 = pauxt;
+ }
+ in = ++st;
+ }
+ net_entry.n_net = inet_network(paux2);
+ break;
+ }
+ net_entry.n_aliases++;
+ return (&net_entry);
+ }
+ h_errno = TRY_AGAIN;
+ return (NULL);
+}
+
+struct netent *
+_getnetbydnsaddr(net, net_type)
+ register unsigned long net;
+ register int net_type;
+{
+ unsigned int netbr[4];
+ int nn, anslen;
+ querybuf buf;
+ char qbuf[MAXDNAME];
+ unsigned long net2;
+ struct netent *net_entry;
+
+ if (net_type != AF_INET)
+ return (NULL);
+
+ for (nn = 4, net2 = net; net2; net2 >>= 8)
+ netbr[--nn] = net2 & 0xff;
+ switch (nn) {
+ case 3: /* Class A */
+ sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]);
+ break;
+ case 2: /* Class B */
+ sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]);
+ break;
+ case 1: /* Class C */
+ sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
+ netbr[1]);
+ break;
+ case 0: /* Class D - E */
+ sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
+ netbr[1], netbr[0]);
+ break;
+ }
+ anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
+ if (anslen < 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf("res_query failed\n");
+#endif
+ return (NULL);
+ }
+ net_entry = getnetanswer(&buf, anslen, BYADDR);
+ if (net_entry) {
+ unsigned u_net = net; /* maybe net should be unsigned ? */
+
+ /* Strip trailing zeros */
+ while ((u_net & 0xff) == 0 && u_net != 0)
+ u_net >>= 8;
+ net_entry->n_net = u_net;
+ return (net_entry);
+ }
+ return (NULL);
+}
+
+struct netent *
+_getnetbydnsname(net)
+ register const char *net;
+{
+ int anslen;
+ querybuf buf;
+ char qbuf[MAXDNAME];
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ strncpy(qbuf, net, sizeof(qbuf) - 1);
+ qbuf[sizeof(qbuf) - 1] = '\0';
+ anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
+ if (anslen < 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf("res_query failed\n");
+#endif
+ return (NULL);
+ }
+ return getnetanswer(&buf, anslen, BYNAME);
+}
+
+void
+_setnetdnsent(stayopen)
+ int stayopen;
+{
+ if (stayopen)
+ _res.options |= RES_STAYOPEN | RES_USEVC;
+}
+
+void
+_endnetdnsent()
+{
+ _res.options &= ~(RES_STAYOPEN | RES_USEVC);
+ res_close();
+}
diff --git a/cpukit/libnetworking/libc/getnetbyht.c b/cpukit/libnetworking/libc/getnetbyht.c
new file mode 100644
index 0000000000..f7b7b1091d
--- /dev/null
+++ b/cpukit/libnetworking/libc/getnetbyht.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 1983, 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.
+ */
+
+/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
+ * Dep. Matematica Universidade de Coimbra, Portugal, Europe
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * from getnetent.c 1.1 (Coimbra) 93/06/02
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93";
+static char orig_rcsid[] = "From: Id: getnetent.c,v 8.4 1997/06/01 20:34:37 vixie Exp";
+static chat rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+
+#define MAXALIASES 35
+
+static FILE *netf;
+static char line[BUFSIZ+1];
+static struct netent net;
+static char *net_aliases[MAXALIASES];
+static int _net_stayopen;
+
+void
+_setnethtent(f)
+ int f;
+{
+
+ if (netf == NULL)
+ netf = fopen(_PATH_NETWORKS, "r" );
+ else
+ rewind(netf);
+ _net_stayopen |= f;
+}
+
+void
+_endnethtent()
+{
+
+ if (netf) {
+ fclose(netf);
+ netf = NULL;
+ }
+ _net_stayopen = 0;
+}
+
+struct netent *
+getnetent()
+{
+ char *p;
+ register char *cp, **q;
+
+ if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)
+ return (NULL);
+again:
+ p = fgets(line, sizeof line, netf);
+ if (p == NULL)
+ return (NULL);
+ if (*p == '#')
+ goto again;
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ goto again;
+ *cp = '\0';
+ net.n_name = p;
+ cp = strpbrk(p, " \t");
+ if (cp == NULL)
+ goto again;
+ *cp++ = '\0';
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ p = strpbrk(cp, " \t");
+ if (p != NULL)
+ *p++ = '\0';
+ net.n_net = inet_network(cp);
+ net.n_addrtype = AF_INET;
+ q = net.n_aliases = net_aliases;
+ if (p != NULL)
+ cp = p;
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &net_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return (&net);
+}
+
+struct netent *
+_getnetbyhtname(name)
+ register const char *name;
+{
+ register struct netent *p;
+ register char **cp;
+
+ setnetent(_net_stayopen);
+ while ( (p = getnetent()) ) {
+ if (strcasecmp(p->n_name, name) == 0)
+ break;
+ for (cp = p->n_aliases; *cp != 0; cp++)
+ if (strcasecmp(*cp, name) == 0)
+ goto found;
+ }
+found:
+ if (!_net_stayopen)
+ endnetent();
+ return (p);
+}
+
+struct netent *
+_getnetbyhtaddr(net, type)
+ register unsigned long net;
+ register int type;
+{
+ register struct netent *p;
+
+ setnetent(_net_stayopen);
+ while ( (p = getnetent()) )
+ if (p->n_addrtype == type && p->n_net == net)
+ break;
+ if (!_net_stayopen)
+ endnetent();
+ return (p);
+}
diff --git a/cpukit/libnetworking/libc/getnetbynis.c b/cpukit/libnetworking/libc/getnetbynis.c
new file mode 100644
index 0000000000..0549016ba2
--- /dev/null
+++ b/cpukit/libnetworking/libc/getnetbynis.c
@@ -0,0 +1,177 @@
+/*-
+ * Copyright (c) 1994, Garrett Wollman
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)$Id$";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <arpa/nameser.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+#ifdef YP
+static char *host_aliases[MAXALIASES];
+#endif /* YP */
+
+static struct netent *
+_getnetbynis(name, map, af)
+ const char *name;
+ char *map;
+ int af;
+{
+#ifdef YP
+ register char *cp, **q;
+ static char *result;
+ int resultlen;
+ static struct netent h;
+ static char *domain = (char *)NULL;
+ static char ypbuf[YPMAXRECORD + 2];
+
+ switch(af) {
+ case AF_INET:
+ break;
+ default:
+ case AF_INET6:
+ errno = EAFNOSUPPORT;
+ return NULL;
+ }
+
+ if (domain == (char *)NULL)
+ if (yp_get_default_domain (&domain))
+ return (NULL);
+
+ if (yp_match(domain, map, name, strlen(name), &result, &resultlen))
+ return (NULL);
+
+ bcopy((char *)result, (char *)&ypbuf, resultlen);
+ ypbuf[resultlen] = '\0';
+ free(result);
+ result = (char *)&ypbuf;
+
+ if ((cp = index(result, '\n')))
+ *cp = '\0';
+
+ cp = strpbrk(result, " \t");
+ *cp++ = '\0';
+ h.n_name = result;
+
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+
+ h.n_net = inet_network(cp);
+ h.n_addrtype = AF_INET;
+
+ q = h.n_aliases = host_aliases;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &host_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return (&h);
+#else
+ return (NULL);
+#endif
+}
+
+struct netent *
+_getnetbynisname(name)
+ const char *name;
+{
+ return _getnetbynis(name, "networks.byname", AF_INET);
+}
+
+struct netent *
+_getnetbynisaddr(addr, af)
+ unsigned long addr;
+ int af;
+{
+ char *str, *cp;
+ unsigned long net2;
+ int nn;
+ unsigned int netbr[4];
+ char buf[MAXDNAME];
+
+ if (af != AF_INET) {
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+
+ for (nn = 4, net2 = addr; net2; net2 >>= 8) {
+ netbr[--nn] = net2 & 0xff;
+ }
+
+ switch (nn) {
+ case 3: /* Class A */
+ sprintf(buf, "%u", netbr[3]);
+ break;
+ case 2: /* Class B */
+ sprintf(buf, "%u.%u", netbr[2], netbr[3]);
+ break;
+ case 1: /* Class C */
+ sprintf(buf, "%u.%u.%u", netbr[1], netbr[2], netbr[3]);
+ break;
+ case 0: /* Class D - E */
+ sprintf(buf, "%u.%u.%u.%u", netbr[0], netbr[1],
+ netbr[2], netbr[3]);
+ break;
+ }
+
+ str = (char *)&buf;
+ cp = str + (strlen(str) - 2);
+
+ while(!strcmp(cp, ".0")) {
+ *cp = '\0';
+ cp = str + (strlen(str) - 2);
+ }
+
+ return _getnetbynis(str, "networks.byaddr", af);
+}
diff --git a/cpukit/libnetworking/libc/getnetent.3 b/cpukit/libnetworking/libc/getnetent.3
new file mode 100644
index 0000000000..aec93b5876
--- /dev/null
+++ b/cpukit/libnetworking/libc/getnetent.3
@@ -0,0 +1,159 @@
+.\" Copyright (c) 1983, 1991, 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.
+.\"
+.\" @(#)getnetent.3 8.1 (Berkeley) 6/4/93
+.\" $Id$
+.\"
+.Dd June 4, 1993
+.Dt GETNETENT 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getnetent ,
+.Nm getnetbyaddr ,
+.Nm getnetbyname ,
+.Nm setnetent ,
+.Nm endnetent
+.Nd get network entry
+.Sh SYNOPSIS
+.Fd #include <netdb.h>
+.Ft struct netent *
+.Fn getnetent void
+.Ft struct netent *
+.Fn getnetbyname "const char *name"
+.Ft struct netent *
+.Fn getnetbyaddr "unsigned long net" "int type"
+.Ft void
+.Fn setnetent "int stayopen"
+.Ft void
+.Fn endnetent void
+.Sh DESCRIPTION
+The
+.Fn getnetent ,
+.Fn getnetbyname ,
+and
+.Fn getnetbyaddr
+functions
+each return a pointer to an object with the
+following structure
+containing the broken-out
+fields of a line in the network data base,
+.Pa /etc/networks .
+.Bd -literal -offset indent
+struct netent {
+ char *n_name; /* official name of net */
+ char **n_aliases; /* alias list */
+ int n_addrtype; /* net number type */
+ unsigned long n_net; /* net number */
+};
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width n_addrtype
+.It Fa n_name
+The official name of the network.
+.It Fa n_aliases
+A zero terminated list of alternate names for the network.
+.It Fa n_addrtype
+The type of the network number returned; currently only AF_INET.
+.It Fa n_net
+The network number. Network numbers are returned in machine byte
+order.
+.El
+.Pp
+The
+.Fn getnetent
+function
+reads the next line of the file, opening the file if necessary.
+.Pp
+The
+.Fn setnetent
+function
+opens and rewinds the file. If the
+.Fa stayopen
+flag is non-zero,
+the net data base will not be closed after each call to
+.Fn getnetbyname
+or
+.Fn getnetbyaddr .
+.Pp
+The
+.Fn endnetent
+function
+closes the file.
+.Pp
+The
+.Fn getnetbyname
+function
+and
+.Fn getnetbyaddr
+sequentially search from the beginning
+of the file until a matching
+net name or
+net address and type is found,
+or until
+.Dv EOF
+is encountered. The
+.Fa type
+must be
+.Dv AF_INET .
+Network numbers are supplied in host order.
+.Sh FILES
+.Bl -tag -width /etc/networks -compact
+.It Pa /etc/networks
+.El
+.Sh DIAGNOSTICS
+Null pointer
+(0) returned on
+.Dv EOF
+or error.
+.Sh SEE ALSO
+.Xr networks 5
+.Pp
+.%T RFC 1101
+.Sh HISTORY
+The
+.Fn getnetent ,
+.Fn getnetbyaddr ,
+.Fn getnetbyname ,
+.Fn setnetent ,
+and
+.Fn endnetent
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+The data space used by
+these functions is static; if future use requires the data, it should be
+copied before any subsequent calls to these functions overwrite it.
+Only Internet network
+numbers are currently understood.
+Expecting network numbers to fit
+in no more than 32 bits is probably
+naive.
diff --git a/cpukit/libnetworking/libc/getnetnamadr.c b/cpukit/libnetworking/libc/getnetnamadr.c
new file mode 100644
index 0000000000..4d6597f98c
--- /dev/null
+++ b/cpukit/libnetworking/libc/getnetnamadr.c
@@ -0,0 +1,190 @@
+/*-
+ * Copyright (c) 1994, Garrett Wollman
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+
+#ifndef _PATH_NETCONF
+#define _PATH_NETCONF "/etc/host.conf"
+#endif
+
+enum service_type {
+ SERVICE_NONE = 0,
+ SERVICE_BIND,
+ SERVICE_TABLE,
+ SERVICE_NIS };
+#define SERVICE_MAX SERVICE_NIS
+
+static struct {
+ const char *name;
+ enum service_type type;
+} service_names[] = {
+ { "hosts", SERVICE_TABLE },
+ { "/etc/hosts", SERVICE_TABLE },
+ { "hosttable", SERVICE_TABLE },
+ { "htable", SERVICE_TABLE },
+ { "bind", SERVICE_BIND },
+ { "dns", SERVICE_BIND },
+ { "domain", SERVICE_BIND },
+ { "yp", SERVICE_NIS },
+ { "yellowpages", SERVICE_NIS },
+ { "nis", SERVICE_NIS },
+ { 0, SERVICE_NONE }
+};
+
+static enum service_type service_order[SERVICE_MAX + 1];
+static int service_done = 0;
+
+static enum service_type
+get_service_name(const char *name) {
+ int i;
+ for(i = 0; service_names[i].type != SERVICE_NONE; i++) {
+ if(!strcasecmp(name, service_names[i].name)) {
+ return service_names[i].type;
+ }
+ }
+ return SERVICE_NONE;
+}
+
+static void
+init_services()
+{
+ char *cp, *p, buf[BUFSIZ];
+ register int cc = 0;
+ FILE *fd;
+
+ if ((fd = (FILE *)fopen(_PATH_NETCONF, "r")) == NULL) {
+ /* make some assumptions */
+ service_order[0] = SERVICE_TABLE;
+ service_order[1] = SERVICE_NONE;
+ } else {
+ while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {
+ if(buf[0] == '#')
+ continue;
+
+ p = buf;
+ while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
+ ;
+ if (cp == NULL)
+ continue;
+ do {
+ if (isalpha(cp[0])) {
+ service_order[cc] = get_service_name(cp);
+ if(service_order[cc] != SERVICE_NONE)
+ cc++;
+ }
+ while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
+ ;
+ } while(cp != NULL && cc < SERVICE_MAX);
+ }
+ service_order[cc] = SERVICE_NONE;
+ fclose(fd);
+ }
+ service_done = 1;
+}
+
+struct netent *
+getnetbyname(const char *name)
+{
+ struct netent *hp = 0;
+ int nserv = 0;
+
+ if (!service_done)
+ init_services();
+
+ while (!hp) {
+ switch (service_order[nserv]) {
+ case SERVICE_NONE:
+ return NULL;
+ case SERVICE_TABLE:
+ hp = _getnetbyhtname(name);
+ break;
+ case SERVICE_BIND:
+ hp = _getnetbydnsname(name);
+ break;
+ case SERVICE_NIS:
+ hp = _getnetbynisname(name);
+ break;
+ }
+ nserv++;
+ }
+ return hp;
+}
+
+struct netent *
+getnetbyaddr(addr, af)
+ u_long addr;
+ int af;
+{
+ struct netent *hp = 0;
+ int nserv = 0;
+
+ if (!service_done)
+ init_services();
+
+ while (!hp) {
+ switch (service_order[nserv]) {
+ case SERVICE_NONE:
+ return 0;
+ case SERVICE_TABLE:
+ hp = _getnetbyhtaddr(addr, af);
+ break;
+ case SERVICE_BIND:
+ hp = _getnetbydnsaddr(addr, af);
+ break;
+ case SERVICE_NIS:
+ hp = _getnetbynisaddr(addr, af);
+ break;
+ }
+ nserv++;
+ }
+ return hp;
+}
+
+void
+setnetent(stayopen)
+ int stayopen;
+{
+ _setnethtent(stayopen);
+ _setnetdnsent(stayopen);
+}
+
+void
+endnetent()
+{
+ _endnethtent();
+ _endnetdnsent();
+}
diff --git a/cpukit/libnetworking/libc/getproto.c b/cpukit/libnetworking/libc/getproto.c
new file mode 100644
index 0000000000..67f59b4e86
--- /dev/null
+++ b/cpukit/libnetworking/libc/getproto.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1983, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getproto.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <netdb.h>
+
+extern int _proto_stayopen;
+
+extern struct protoent * getprotobynumber_static(int);
+
+struct protoent *
+getprotobynumber(proto)
+ register int proto;
+{
+ register struct protoent *p;
+
+ setprotoent(_proto_stayopen);
+ while ( (p = getprotoent()) )
+ if (p->p_proto == proto)
+ break;
+ if (!_proto_stayopen)
+ endprotoent();
+
+ if ( !p )
+ p = getprotobynumber_static(proto);
+ return (p);
+}
diff --git a/cpukit/libnetworking/libc/getprotoent.3 b/cpukit/libnetworking/libc/getprotoent.3
new file mode 100644
index 0000000000..784461d7e3
--- /dev/null
+++ b/cpukit/libnetworking/libc/getprotoent.3
@@ -0,0 +1,147 @@
+.\" Copyright (c) 1983, 1991, 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.
+.\"
+.\" @(#)getprotoent.3 8.1 (Berkeley) 6/4/93
+.\" $Id$
+.\"
+.Dd June 4, 1993
+.Dt GETPROTOENT 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getprotoent ,
+.Nm getprotobynumber ,
+.Nm getprotobyname ,
+.Nm setprotoent ,
+.Nm endprotoent
+.Nd get protocol entry
+.Sh SYNOPSIS
+.Fd #include <netdb.h>
+.Ft struct protoent *
+.Fn getprotoent void
+.Ft struct protoent *
+.Fn getprotobyname "const char *name"
+.Ft struct protoent *
+.Fn getprotobynumber "int proto"
+.Ft void
+.Fn setprotoent "int stayopen"
+.Ft void
+.Fn endprotoent void
+.Sh DESCRIPTION
+The
+.Fn getprotoent ,
+.Fn getprotobyname ,
+and
+.Fn getprotobynumber
+functions
+each return a pointer to an object with the
+following structure
+containing the broken-out
+fields of a line in the network protocol data base,
+.Pa /etc/protocols .
+.Bd -literal -offset indent
+.Pp
+struct protoent {
+ char *p_name; /* official name of protocol */
+ char **p_aliases; /* alias list */
+ int p_proto; /* protocol number */
+};
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width p_aliases
+.It Fa p_name
+The official name of the protocol.
+.It Fa p_aliases
+A zero terminated list of alternate names for the protocol.
+.It Fa p_proto
+The protocol number.
+.El
+.Pp
+The
+.Fn getprotoent
+function
+reads the next line of the file, opening the file if necessary.
+.Pp
+The
+.Fn setprotoent
+function
+opens and rewinds the file. If the
+.Fa stayopen
+flag is non-zero,
+the net data base will not be closed after each call to
+.Fn getprotobyname
+or
+.Fn getprotobynumber .
+.Pp
+The
+.Fn endprotoent
+function
+closes the file.
+.Pp
+The
+.Fn getprotobyname
+function
+and
+.Fn getprotobynumber
+sequentially search from the beginning
+of the file until a matching
+protocol name or
+protocol number is found,
+or until
+.Dv EOF
+is encountered.
+.Sh RETURN VALUES
+Null pointer
+(0) returned on
+.Dv EOF
+or error.
+.Sh FILES
+.Bl -tag -width /etc/protocols -compact
+.It Pa /etc/protocols
+.El
+.Sh SEE ALSO
+.Xr protocols 5
+.Sh HISTORY
+The
+.Fn getprotoent ,
+.Fn getprotobynumber ,
+.Fn getprotobyname ,
+.Fn setprotoent ,
+and
+.Fn endprotoent
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+These functions use a static data space;
+if the data is needed for future use, it should be
+copied before any subsequent calls overwrite it.
+Only the Internet
+protocols are currently understood.
diff --git a/cpukit/libnetworking/libc/getprotoent.c b/cpukit/libnetworking/libc/getprotoent.c
new file mode 100644
index 0000000000..0b9cefec68
--- /dev/null
+++ b/cpukit/libnetworking/libc/getprotoent.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 1983, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getprotoent.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MAXALIASES 35
+
+static FILE *protof = NULL;
+static char line[BUFSIZ+1];
+static struct protoent proto;
+static char *proto_aliases[MAXALIASES];
+int _proto_stayopen;
+
+void
+setprotoent(f)
+ int f;
+{
+ if (protof == NULL)
+ protof = fopen(_PATH_PROTOCOLS, "r" );
+ else
+ rewind(protof);
+ _proto_stayopen |= f;
+}
+
+void
+endprotoent()
+{
+ if (protof) {
+ fclose(protof);
+ protof = NULL;
+ }
+ _proto_stayopen = 0;
+}
+
+struct protoent *
+getprotoent()
+{
+ char *p;
+ register char *cp, **q;
+
+ if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
+ return (NULL);
+again:
+ if ((p = fgets(line, BUFSIZ, protof)) == NULL)
+ return (NULL);
+ if (*p == '#')
+ goto again;
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ goto again;
+ *cp = '\0';
+ proto.p_name = p;
+ cp = strpbrk(p, " \t");
+ if (cp == NULL)
+ goto again;
+ *cp++ = '\0';
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ p = strpbrk(cp, " \t");
+ if (p != NULL)
+ *p++ = '\0';
+ proto.p_proto = atoi(cp);
+ q = proto.p_aliases = proto_aliases;
+ if (p != NULL) {
+ cp = p;
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &proto_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ }
+ *q = NULL;
+ return (&proto);
+}
diff --git a/cpukit/libnetworking/libc/getprotoname.c b/cpukit/libnetworking/libc/getprotoname.c
new file mode 100644
index 0000000000..e21e4c4f2a
--- /dev/null
+++ b/cpukit/libnetworking/libc/getprotoname.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1983, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getprotoname.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <netdb.h>
+#include <string.h>
+
+extern int _proto_stayopen;
+
+extern struct protoent *getprotobyname_static(const char *);
+
+struct protoent *
+getprotobyname(name)
+ register const char *name;
+{
+ register struct protoent *p;
+ register char **cp;
+
+ setprotoent(_proto_stayopen);
+ while ( (p = getprotoent()) ) {
+ if (strcmp(p->p_name, name) == 0)
+ break;
+ for (cp = p->p_aliases; *cp != 0; cp++)
+ if (strcmp(*cp, name) == 0)
+ goto found;
+ }
+found:
+ if (!_proto_stayopen)
+ endprotoent();
+
+ if ( !p )
+ p = getprotobyname_static(name);
+ return (p);
+}
diff --git a/cpukit/libnetworking/libc/getservbyname.c b/cpukit/libnetworking/libc/getservbyname.c
new file mode 100644
index 0000000000..19936907d3
--- /dev/null
+++ b/cpukit/libnetworking/libc/getservbyname.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1983, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getservbyname.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <netdb.h>
+#include <string.h>
+
+extern int _serv_stayopen;
+
+struct servent *
+getservbyname(name, proto)
+ const char *name, *proto;
+{
+ register struct servent *p;
+ register char **cp;
+
+#ifdef YP
+ extern char *___getservbyname_yp;
+ extern char *___getservbyproto_yp;
+
+ ___getservbyname_yp = (char *)name;
+ ___getservbyproto_yp = (char *)proto;
+#endif
+
+ setservent(_serv_stayopen);
+ while ( (p = getservent()) ) {
+ if (strcmp(name, p->s_name) == 0)
+ goto gotname;
+ for (cp = p->s_aliases; *cp; cp++)
+ if (strcmp(name, *cp) == 0)
+ goto gotname;
+ continue;
+gotname:
+ if (proto == 0 || strcmp(p->s_proto, proto) == 0)
+ break;
+ }
+ if (!_serv_stayopen)
+ endservent();
+
+#ifdef YP
+ ___getservbyname_yp = NULL;
+ ___getservbyproto_yp = NULL;
+#endif
+
+ return (p);
+}
diff --git a/cpukit/libnetworking/libc/getservbyport.c b/cpukit/libnetworking/libc/getservbyport.c
new file mode 100644
index 0000000000..c8433954e1
--- /dev/null
+++ b/cpukit/libnetworking/libc/getservbyport.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1983, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getservbyport.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <netdb.h>
+#include <string.h>
+
+extern int _serv_stayopen;
+
+struct servent *
+getservbyport(port, proto)
+ int port;
+ const char *proto;
+{
+ register struct servent *p;
+
+#ifdef YP
+ extern int ___getservbyport_yp;
+ extern char *___getservbyproto_yp;
+
+ ___getservbyport_yp = port;
+ ___getservbyproto_yp = (char *)proto;
+#endif
+
+ setservent(_serv_stayopen);
+ while ( (p = getservent()) ) {
+ if (p->s_port != port)
+ continue;
+ if (proto == 0 || strcmp(p->s_proto, proto) == 0)
+ break;
+ }
+ if (!_serv_stayopen)
+ endservent();
+
+#ifdef YP
+ ___getservbyport_yp = 0;
+ ___getservbyproto_yp = NULL;
+#endif
+
+ return (p);
+}
diff --git a/cpukit/libnetworking/libc/getservent.3 b/cpukit/libnetworking/libc/getservent.3
new file mode 100644
index 0000000000..79c18a3beb
--- /dev/null
+++ b/cpukit/libnetworking/libc/getservent.3
@@ -0,0 +1,156 @@
+.\" Copyright (c) 1983, 1991, 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.
+.\"
+.\" From: @(#)getservent.3 8.3 (Berkeley) 1/12/94
+.\" $Id$
+.\"
+.Dd July 9, 1995
+.Dt GETSERVENT 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getservent ,
+.Nm getservbyport ,
+.Nm getservbyname ,
+.Nm setservent ,
+.Nm endservent
+.Nd get service entry
+.Sh SYNOPSIS
+.Fd #include <netdb.h>
+.Ft struct servent *
+.Fn getservent
+.Ft struct servent *
+.Fn getservbyname "const char *name" "const char *proto"
+.Ft struct servent *
+.Fn getservbyport "int port" "const char *proto"
+.Ft void
+.Fn setservent "int stayopen"
+.Ft void
+.Fn endservent void
+.Sh DESCRIPTION
+The
+.Fn getservent ,
+.Fn getservbyname ,
+and
+.Fn getservbyport
+functions
+each return a pointer to an object with the
+following structure
+containing the broken-out
+fields of a line in the network services data base,
+.Pa /etc/services .
+.Bd -literal -offset indent
+struct servent {
+ char *s_name; /* official name of service */
+ char **s_aliases; /* alias list */
+ int s_port; /* port service resides at */
+ char *s_proto; /* protocol to use */
+};
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width s_aliases
+.It Fa s_name
+The official name of the service.
+.It Fa s_aliases
+A zero terminated list of alternate names for the service.
+.It Fa s_port
+The port number at which the service resides.
+Port numbers are returned in network byte order.
+.It Fa s_proto
+The name of the protocol to use when contacting the
+service.
+.El
+.Pp
+The
+.Fn getservent
+function
+reads the next line of the file, opening the file if necessary.
+.Pp
+The
+.Fn setservent
+function
+opens and rewinds the file. If the
+.Fa stayopen
+flag is non-zero,
+the net data base will not be closed after each call to
+.Fn getservbyname
+or
+.Fn getservbyport .
+.Pp
+The
+.Fn endservent
+function
+closes the file.
+.Pp
+The
+.Fn getservbyname
+and
+.Fn getservbyport
+functions
+sequentially search from the beginning
+of the file until a matching
+protocol name or
+port number is found,
+or until
+.Dv EOF
+is encountered.
+If a protocol name is also supplied (non-
+.Dv NULL ) ,
+searches must also match the protocol.
+.ne 1i
+.Sh FILES
+.Bl -tag -width /etc/services -compact
+.It Pa /etc/services
+.El
+.Sh DIAGNOSTICS
+Null pointer
+(0) returned on
+.Dv EOF
+or error.
+.Sh SEE ALSO
+.Xr getprotoent 3 ,
+.Xr services 5
+.Sh HISTORY
+The
+.Fn getservent ,
+.Fn getservbyport ,
+.Fn getservbyname ,
+.Fn setservent ,
+and
+.Fn endservent
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+These functions use static data storage;
+if the data is needed for future use, it should be
+copied before any subsequent calls overwrite it.
+Expecting port numbers to fit in a 32 bit
+quantity is probably naive.
diff --git a/cpukit/libnetworking/libc/getservent.c b/cpukit/libnetworking/libc/getservent.c
new file mode 100644
index 0000000000..4619e47795
--- /dev/null
+++ b/cpukit/libnetworking/libc/getservent.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 1983, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+static int serv_stepping_yp = 0;
+extern int _yp_check __P(( char ** ));
+#endif
+
+
+#define MAXALIASES 35
+
+static FILE *servf = NULL;
+static char line[BUFSIZ+1];
+static struct servent serv;
+static char *serv_aliases[MAXALIASES];
+int _serv_stayopen;
+
+#ifdef YP
+char *___getservbyname_yp = NULL;
+char *___getservbyproto_yp = NULL;
+int ___getservbyport_yp = 0;
+static char *yp_domain = NULL;
+
+static int
+_getservbyport_yp(line)
+ char *line;
+{
+ char *result;
+ int resultlen;
+ char buf[YPMAXRECORD + 2];
+ int rv;
+
+ snprintf(buf, sizeof(buf), "%d/%s", ntohs(___getservbyport_yp),
+ ___getservbyproto_yp);
+
+ ___getservbyport_yp = 0;
+ ___getservbyproto_yp = NULL;
+
+ if(!yp_domain) {
+ if(yp_get_default_domain(&yp_domain))
+ return (0);
+ }
+
+ /*
+ * We have to be a little flexible here. Ideally you're supposed
+ * to have both a services.byname and a services.byport map, but
+ * some systems have only services.byname. FreeBSD cheats a little
+ * by putting the services.byport information in the same map as
+ * services.byname so that either case will work. We allow for both
+ * possibilities here: if there is no services.byport map, we try
+ * services.byname instead.
+ */
+ if ((rv = yp_match(yp_domain, "services.byport", buf, strlen(buf),
+ &result, &resultlen))) {
+ if (rv == YPERR_MAP) {
+ if (yp_match(yp_domain, "services.byname", buf,
+ strlen(buf), &result, &resultlen))
+ return(0);
+ } else
+ return(0);
+ }
+
+ /* getservent() expects lines terminated with \n -- make it happy */
+ snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
+
+ free(result);
+ return(1);
+}
+
+static int
+_getservbyname_yp(line)
+ char *line;
+{
+ char *result;
+ int resultlen;
+ char buf[YPMAXRECORD + 2];
+
+ if(!yp_domain) {
+ if(yp_get_default_domain(&yp_domain))
+ return (0);
+ }
+
+ snprintf(buf, sizeof(buf), "%s/%s", ___getservbyname_yp,
+ ___getservbyproto_yp);
+
+ ___getservbyname_yp = 0;
+ ___getservbyproto_yp = NULL;
+
+ if (yp_match(yp_domain, "services.byname", buf, strlen(buf),
+ &result, &resultlen)) {
+ return(0);
+ }
+
+ /* getservent() expects lines terminated with \n -- make it happy */
+ snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
+
+ free(result);
+ return(1);
+}
+
+static int
+_getservent_yp(line)
+ char *line;
+{
+ static char *key = NULL;
+ static int keylen;
+ char *lastkey, *result;
+ int resultlen;
+ int rv;
+
+ if(!yp_domain) {
+ if(yp_get_default_domain(&yp_domain))
+ return (0);
+ }
+
+ if (!serv_stepping_yp) {
+ if (key)
+ free(key);
+ if ((rv = yp_first(yp_domain, "services.byname", &key, &keylen,
+ &result, &resultlen))) {
+ serv_stepping_yp = 0;
+ return(0);
+ }
+ serv_stepping_yp = 1;
+ } else {
+ lastkey = key;
+ rv = yp_next(yp_domain, "services.byname", key, keylen, &key,
+ &keylen, &result, &resultlen);
+ free(lastkey);
+ if (rv) {
+ serv_stepping_yp = 0;
+ return (0);
+ }
+ }
+
+ /* getservent() expects lines terminated with \n -- make it happy */
+ snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
+
+ free(result);
+
+ return(1);
+}
+#endif
+
+void
+setservent(f)
+ int f;
+{
+ if (servf == NULL)
+ servf = fopen(_PATH_SERVICES, "r" );
+ else
+ rewind(servf);
+ _serv_stayopen |= f;
+}
+
+void
+endservent()
+{
+ if (servf) {
+ fclose(servf);
+ servf = NULL;
+ }
+ _serv_stayopen = 0;
+}
+
+struct servent *
+getservent()
+{
+ char *p;
+ register char *cp, **q;
+
+#ifdef YP
+ if (serv_stepping_yp && _getservent_yp(line)) {
+ p = (char *)&line;
+ goto unpack;
+ }
+tryagain:
+#endif
+ if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
+ return (NULL);
+again:
+ if ((p = fgets(line, BUFSIZ, servf)) == NULL)
+ return (NULL);
+#ifdef YP
+ if (*p == '+' && _yp_check(NULL)) {
+ if (___getservbyname_yp != NULL) {
+ if (!_getservbyname_yp(line))
+ goto tryagain;
+ }
+ else if (___getservbyport_yp != 0) {
+ if (!_getservbyport_yp(line))
+ goto tryagain;
+ }
+ else if (!_getservent_yp(line))
+ goto tryagain;
+ }
+unpack:
+#endif
+ if (*p == '#')
+ goto again;
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ goto again;
+ *cp = '\0';
+ serv.s_name = p;
+ p = strpbrk(p, " \t");
+ if (p == NULL)
+ goto again;
+ *p++ = '\0';
+ while (*p == ' ' || *p == '\t')
+ p++;
+ cp = strpbrk(p, ",/");
+ if (cp == NULL)
+ goto again;
+ *cp++ = '\0';
+ serv.s_port = htons((u_short)atoi(p));
+ serv.s_proto = cp;
+ q = serv.s_aliases = serv_aliases;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &serv_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return (&serv);
+}
diff --git a/cpukit/libnetworking/libc/herror.c b/cpukit/libnetworking/libc/herror.c
new file mode 100644
index 0000000000..ba1dae934d
--- /dev/null
+++ b/cpukit/libnetworking/libc/herror.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1987, 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.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <netdb.h>
+#include <string.h>
+#include <unistd.h>
+
+const char *h_errlist[] = {
+ "Resolver Error 0 (no error)",
+ "Unknown host", /* 1 HOST_NOT_FOUND */
+ "Host name lookup failure", /* 2 TRY_AGAIN */
+ "Unknown server error", /* 3 NO_RECOVERY */
+ "No address associated with name", /* 4 NO_ADDRESS */
+};
+int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
+
+int h_errno;
+
+/*
+ * herror --
+ * print the error indicated by the h_errno value.
+ */
+void
+herror(s)
+ const char *s;
+{
+#if 0
+ struct iovec iov[4];
+ register struct iovec *v = iov;
+
+ if (s && *s) {
+ v->iov_base = (char *)s;
+ v->iov_len = strlen(s);
+ v++;
+ v->iov_base = ": ";
+ v->iov_len = 2;
+ v++;
+ }
+ v->iov_base = (char *)hstrerror(h_errno);
+ v->iov_len = strlen(v->iov_base);
+ v++;
+ v->iov_base = "\n";
+ v->iov_len = 1;
+ writev(STDERR_FILENO, iov, (v - iov) + 1);
+#else
+ /*
+ * RTEMS: no writev yet
+ */
+ if (s && *s) {
+ write (2, s, strlen (s));
+ write (2, ": ", 2);
+ }
+ s = (char *)hstrerror(h_errno);
+ write (2, s, strlen (s));
+ write (2, "\n", 1);
+#endif
+}
+
+const char *
+hstrerror(err)
+ int err;
+{
+ if (err < 0)
+ return ("Resolver internal error");
+ else if (err < h_nerr)
+ return (h_errlist[err]);
+ return ("Unknown resolver error");
+}
diff --git a/cpukit/libnetworking/libc/inet.3 b/cpukit/libnetworking/libc/inet.3
new file mode 100644
index 0000000000..1052f538f2
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet.3
@@ -0,0 +1,210 @@
+.\" Copyright (c) 1983, 1990, 1991, 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.
+.\"
+.\" From: @(#)inet.3 8.1 (Berkeley) 6/4/93
+.\" $Id$
+.\"
+.Dd June 17, 1996
+.Dt INET 3
+.Os BSD 4.2
+.Sh NAME
+.Nm inet_aton ,
+.Nm inet_addr ,
+.Nm inet_network ,
+.Nm inet_ntoa ,
+.Nm inet_makeaddr ,
+.Nm inet_lnaof ,
+.Nm inet_netof
+.Nd Internet address manipulation routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Fd #include <netinet/in.h>
+.Fd #include <arpa/inet.h>
+.Ft int
+.Fn inet_aton "const char *cp" "struct in_addr *pin"
+.Ft unsigned long
+.Fn inet_addr "const char *cp"
+.Ft unsigned long
+.Fn inet_network "const char *cp"
+.Ft char *
+.Fn inet_ntoa "struct in_addr in"
+.Ft struct in_addr
+.Fn inet_makeaddr "unsigned long net" "unsigned long lna"
+.Ft unsigned long
+.Fn inet_lnaof "struct in_addr in"
+.Ft unsigned long
+.Fn inet_netof "struct in_addr in"
+.Sh DESCRIPTION
+The routines
+.Fn inet_aton ,
+.Fn inet_addr
+and
+.Fn inet_network
+interpret character strings representing
+numbers expressed in the Internet standard
+.Ql \&.
+notation.
+The
+.Fn inet_aton
+routine interprets the specified character string as an Internet address,
+placing the address into the structure provided.
+It returns 1 if the string was successfully interpreted,
+or 0 if the string is invalid.
+The
+.Fn inet_addr
+and
+.Fn inet_network
+functions return numbers suitable for use
+as Internet addresses and Internet network
+numbers, respectively.
+The routine
+.Fn inet_ntoa
+takes an Internet address and returns an
+.Tn ASCII
+string representing the address in
+.Ql \&.
+notation. The routine
+.Fn inet_makeaddr
+takes an Internet network number and a local
+network address and constructs an Internet address
+from it. The routines
+.Fn inet_netof
+and
+.Fn inet_lnaof
+break apart Internet host addresses, returning
+the network number and local network address part,
+respectively.
+.Pp
+All Internet addresses are returned in network
+order (bytes ordered from left to right).
+All network numbers and local address parts are
+returned as machine format integer values.
+.Sh INTERNET ADDRESSES
+Values specified using the
+.Ql \&.
+notation take one
+of the following forms:
+.Bd -literal -offset indent
+a.b.c.d
+a.b.c
+a.b
+a
+.Ed
+.Pp
+When four parts are specified, each is interpreted
+as a byte of data and assigned, from left to right,
+to the four bytes of an Internet address. Note
+that when an Internet address is viewed as a 32-bit
+integer quantity on the
+.Tn VAX
+the bytes referred to
+above appear as
+.Dq Li d.c.b.a .
+That is,
+.Tn VAX
+bytes are
+ordered from right to left.
+.Pp
+When a three part address is specified, the last
+part is interpreted as a 16-bit quantity and placed
+in the right-most two bytes of the network address.
+This makes the three part address format convenient
+for specifying Class B network addresses as
+.Dq Li 128.net.host .
+.Pp
+When a two part address is supplied, the last part
+is interpreted as a 24-bit quantity and placed in
+the right most three bytes of the network address.
+This makes the two part address format convenient
+for specifying Class A network addresses as
+.Dq Li net.host .
+.Pp
+When only one part is given, the value is stored
+directly in the network address without any byte
+rearrangement.
+.Pp
+All numbers supplied as
+.Dq parts
+in a
+.Ql \&.
+notation
+may be decimal, octal, or hexadecimal, as specified
+in the C language (i.e., a leading 0x or 0X implies
+hexadecimal; otherwise, a leading 0 implies octal;
+otherwise, the number is interpreted as decimal).
+.Pp
+The
+.Fn inet_aton
+and
+.Fn inet_ntoa
+functions are semi-deprecated in favor of the
+.Xr addr2ascii 3
+family. However, since those functions are not yet widely implemented,
+portable programs cannot rely on their presence and will continue
+to use the
+.Xr inet 3
+functions for some time.
+.Sh DIAGNOSTICS
+The constant
+.Dv INADDR_NONE
+is returned by
+.Fn inet_addr
+and
+.Fn inet_network
+for malformed requests.
+.Sh SEE ALSO
+.Xr addr2ascii 3 ,
+.Xr gethostbyname 3 ,
+.Xr getnetent 3 ,
+.Xr hosts 5 ,
+.Xr networks 5
+.Sh HISTORY
+These
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+The value
+.Dv INADDR_NONE
+(0xffffffff) is a valid broadcast address, but
+.Fn inet_addr
+cannot return that value without indicating failure.
+The newer
+.Fn inet_aton
+function does not share this problem.
+The problem of host byte ordering versus network byte ordering is
+confusing.
+The string returned by
+.Fn inet_ntoa
+resides in a static memory area.
+.Pp
+Inet_addr should return a
+.Fa struct in_addr .
diff --git a/cpukit/libnetworking/libc/inet_addr.c b/cpukit/libnetworking/libc/inet_addr.c
new file mode 100644
index 0000000000..3307991df5
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet_addr.c
@@ -0,0 +1,180 @@
+/*
+ * ++Copyright++ 1983, 1990, 1993
+ * -
+ * Copyright (c) 1983, 1990, 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.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+
+/*
+ * ASCII internet address interpretation routine.
+ * The value returned is in network order.
+ */
+in_addr_t
+inet_addr(cp)
+ const char *cp;
+{
+ struct in_addr val;
+
+ if (inet_aton(cp, &val))
+ return (val.s_addr);
+ return (INADDR_NONE);
+}
+
+/*
+ * Check whether "cp" is a valid ASCII representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+int
+inet_aton(cp, addr)
+ const char *cp;
+ struct in_addr *addr;
+{
+ in_addr_t val;
+ register int base, n;
+ register char c;
+ u_int parts[4];
+ register u_int *pp = parts;
+
+ c = *cp;
+ for (;;) {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, isdigit=decimal.
+ */
+ if (!isdigit((int)c))
+ return (0);
+ val = 0; base = 10;
+ if (c == '0') {
+ c = *++cp;
+ if (c == 'x' || c == 'X')
+ base = 16, c = *++cp;
+ else
+ base = 8;
+ }
+ for (;;) {
+ if (isascii((int)c) && isdigit((int)c)) {
+ val = (val * base) + (c - '0');
+ c = *++cp;
+ } else if (base == 16 && isascii((int)c) && isxdigit((int)c)) {
+ val = (val << 4) |
+ (c + 10 - (islower((int)c) ? 'a' : 'A'));
+ c = *++cp;
+ } else
+ break;
+ }
+ if (c == '.') {
+ /*
+ * Internet format:
+ * a.b.c.d
+ * a.b.c (with c treated as 16 bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3)
+ return (0);
+ *pp++ = val;
+ c = *++cp;
+ } else
+ break;
+ }
+ /*
+ * Check for trailing characters.
+ */
+ if (c != '\0' && (!isascii((int)c) || !isspace((int)c)))
+ return (0);
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+ n = pp - parts + 1;
+ switch (n) {
+
+ case 0:
+ return (0); /* initial nondigit */
+
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffff)
+ return (0);
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+ if (addr != NULL)
+ addr->s_addr = htonl(val);
+ return (1);
+}
diff --git a/cpukit/libnetworking/libc/inet_lnaof.c b/cpukit/libnetworking/libc/inet_lnaof.c
new file mode 100644
index 0000000000..ab429081ae
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet_lnaof.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1983, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * Return the local network address portion of an
+ * internet address; handles class a/b/c network
+ * number formats.
+ */
+in_addr_t
+inet_lnaof(in)
+ struct in_addr in;
+{
+ register u_long i = ntohl(in.s_addr);
+
+ if (IN_CLASSA(i))
+ return ((i)&IN_CLASSA_HOST);
+ else if (IN_CLASSB(i))
+ return ((i)&IN_CLASSB_HOST);
+ else
+ return ((i)&IN_CLASSC_HOST);
+}
diff --git a/cpukit/libnetworking/libc/inet_makeaddr.c b/cpukit/libnetworking/libc/inet_makeaddr.c
new file mode 100644
index 0000000000..79fbeedb4d
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet_makeaddr.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1983, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * Formulate an Internet address from network + host. Used in
+ * building addresses stored in the ifnet structure.
+ */
+struct in_addr
+inet_makeaddr(net, host)
+ in_addr_t net, host;
+{
+ u_long addr;
+
+ if (net < 128)
+ addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
+ else if (net < 65536)
+ addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
+ else if (net < 16777216L)
+ addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
+ else
+ addr = net | host;
+ addr = htonl(addr);
+ return (*(struct in_addr *)&addr);
+}
diff --git a/cpukit/libnetworking/libc/inet_net_ntop.c b/cpukit/libnetworking/libc/inet_net_ntop.c
new file mode 100644
index 0000000000..4c7893d417
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet_net_ntop.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char orig_rcsid[] = "From Id: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp";
+static const char rcsid[] = "$Id$";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits,
+ char *dst, size_t size));
+
+/*
+ * char *
+ * inet_net_ntop(af, src, bits, dst, size)
+ * convert network number from network to presentation format.
+ * generates CIDR style result always.
+ * return:
+ * pointer to dst, or NULL if an error occurred (check errno).
+ * author:
+ * Paul Vixie (ISC), July 1996
+ */
+char *
+inet_net_ntop(af, src, bits, dst, size)
+ int af;
+ const void *src;
+ int bits;
+ char *dst;
+ size_t size;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_net_ntop_ipv4(src, bits, dst, size));
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+}
+
+/*
+ * static char *
+ * inet_net_ntop_ipv4(src, bits, dst, size)
+ * convert IPv4 network number from network to presentation format.
+ * generates CIDR style result always.
+ * return:
+ * pointer to dst, or NULL if an error occurred (check errno).
+ * note:
+ * network byte order assumed. this means 192.5.5.240/28 has
+ * 0x11110000 in its fourth octet.
+ * author:
+ * Paul Vixie (ISC), July 1996
+ */
+static char *
+inet_net_ntop_ipv4(src, bits, dst, size)
+ const u_char *src;
+ int bits;
+ char *dst;
+ size_t size;
+{
+ char *odst = dst;
+ char *t;
+ u_int m;
+ int b;
+
+ if (bits < 0 || bits > 32) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ if (bits == 0) {
+ if (size < sizeof "0")
+ goto emsgsize;
+ *dst++ = '0';
+ *dst = '\0';
+ }
+
+ /* Format whole octets. */
+ for (b = bits / 8; b > 0; b--) {
+ if (size < sizeof "255.")
+ goto emsgsize;
+ t = dst;
+ dst += SPRINTF((dst, "%u", *src++));
+ if (b > 1) {
+ *dst++ = '.';
+ *dst = '\0';
+ }
+ size -= (size_t)(dst - t);
+ }
+
+ /* Format partial octet. */
+ b = bits % 8;
+ if (b > 0) {
+ if (size < sizeof ".255")
+ goto emsgsize;
+ t = dst;
+ if (dst != odst)
+ *dst++ = '.';
+ m = ((1 << b) - 1) << (8 - b);
+ dst += SPRINTF((dst, "%u", *src & m));
+ size -= (size_t)(dst - t);
+ }
+
+ /* Format CIDR /width. */
+ if (size < sizeof "/32")
+ goto emsgsize;
+ dst += SPRINTF((dst, "/%u", bits));
+ return (odst);
+
+ emsgsize:
+ errno = EMSGSIZE;
+ return (NULL);
+}
diff --git a/cpukit/libnetworking/libc/inet_net_pton.c b/cpukit/libnetworking/libc/inet_net_pton.c
new file mode 100644
index 0000000000..8915c2a5be
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet_net_pton.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char orig_rcsid[] = "From Id: inet_net_pton.c,v 1.8 1996/11/21 10:28:12 vixie Exp $";
+static const char rcsid[] = "$Id$";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+static int inet_net_pton_ipv4 __P((const char *src, u_char *dst,
+ size_t size));
+
+/*
+ * static int
+ * inet_net_pton(af, src, dst, size)
+ * convert network number from presentation to network format.
+ * accepts hex octets, hex strings, decimal octets, and /CIDR.
+ * "size" is in bytes and describes "dst".
+ * return:
+ * number of bits, either imputed classfully or specified with /CIDR,
+ * or -1 if some failure occurred (check errno). ENOENT means it was
+ * not a valid network specification.
+ * author:
+ * Paul Vixie (ISC), June 1996
+ */
+int
+inet_net_pton(af, src, dst, size)
+ int af;
+ const char *src;
+ void *dst;
+ size_t size;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_net_pton_ipv4(src, dst, size));
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+}
+
+/*
+ * static int
+ * inet_net_pton_ipv4(src, dst, size)
+ * convert IPv4 network number from presentation to network format.
+ * accepts hex octets, hex strings, decimal octets, and /CIDR.
+ * "size" is in bytes and describes "dst".
+ * return:
+ * number of bits, either imputed classfully or specified with /CIDR,
+ * or -1 if some failure occurred (check errno). ENOENT means it was
+ * not an IPv4 network specification.
+ * note:
+ * network byte order assumed. this means 192.5.5.240/28 has
+ * 0x11110000 in its fourth octet.
+ * author:
+ * Paul Vixie (ISC), June 1996
+ */
+static int
+inet_net_pton_ipv4(src, dst, size)
+ const char *src;
+ u_char *dst;
+ size_t size;
+{
+ static const char
+ xdigits[] = "0123456789abcdef",
+ digits[] = "0123456789";
+ int n, ch, tmp, dirty, bits;
+ const u_char *odst = dst;
+
+ ch = *src++;
+ if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
+ && isascii(src[1]) && isxdigit(src[1])) {
+ /* Hexadecimal: Eat nybble string. */
+ if (size <= 0)
+ goto emsgsize;
+ *dst = 0, dirty = 0;
+ src++; /* skip x or X. */
+ while ((ch = *src++) != '\0' &&
+ isascii(ch) && isxdigit(ch)) {
+ if (isupper(ch))
+ ch = tolower(ch);
+ n = strchr(xdigits, ch) - xdigits;
+ assert(n >= 0 && n <= 15);
+ *dst |= n;
+ if (!dirty++)
+ *dst <<= 4;
+ else if (size-- > 0)
+ *++dst = 0, dirty = 0;
+ else
+ goto emsgsize;
+ }
+ if (dirty)
+ size--;
+ } else if (isascii(ch) && isdigit(ch)) {
+ /* Decimal: eat dotted digit string. */
+ for (;;) {
+ tmp = 0;
+ do {
+ n = strchr(digits, ch) - digits;
+ assert(n >= 0 && n <= 9);
+ tmp *= 10;
+ tmp += n;
+ if (tmp > 255)
+ goto enoent;
+ } while ((ch = *src++) != '\0' &&
+ isascii(ch) && isdigit(ch));
+ if (size-- <= 0)
+ goto emsgsize;
+ *dst++ = (u_char) tmp;
+ if (ch == '\0' || ch == '/')
+ break;
+ if (ch != '.')
+ goto enoent;
+ ch = *src++;
+ if (!isascii(ch) || !isdigit(ch))
+ goto enoent;
+ }
+ } else
+ goto enoent;
+
+ bits = -1;
+ if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
+ /* CIDR width specifier. Nothing can follow it. */
+ ch = *src++; /* Skip over the /. */
+ bits = 0;
+ do {
+ n = strchr(digits, ch) - digits;
+ assert(n >= 0 && n <= 9);
+ bits *= 10;
+ bits += n;
+ } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
+ if (ch != '\0')
+ goto enoent;
+ if (bits > 32)
+ goto emsgsize;
+ }
+
+ /* Firey death and destruction unless we prefetched EOS. */
+ if (ch != '\0')
+ goto enoent;
+
+ /* If nothing was written to the destination, we found no address. */
+ if (dst == odst)
+ goto enoent;
+ /* If no CIDR spec was given, infer width from net class. */
+ if (bits == -1) {
+ if (*odst >= 240) /* Class E */
+ bits = 32;
+ else if (*odst >= 224) /* Class D */
+ bits = 4;
+ else if (*odst >= 192) /* Class C */
+ bits = 24;
+ else if (*odst >= 128) /* Class B */
+ bits = 16;
+ else /* Class A */
+ bits = 8;
+ /* If imputed mask is narrower than specified octets, widen. */
+ if (bits >= 8 && bits < ((dst - odst) * 8))
+ bits = (dst - odst) * 8;
+ }
+ /* Extend network to cover the actual mask. */
+ while (bits > ((dst - odst) * 8)) {
+ if (size-- <= 0)
+ goto emsgsize;
+ *dst++ = '\0';
+ }
+ return (bits);
+
+ enoent:
+ errno = ENOENT;
+ return (-1);
+
+ emsgsize:
+ errno = EMSGSIZE;
+ return (-1);
+}
diff --git a/cpukit/libnetworking/libc/inet_neta.c b/cpukit/libnetworking/libc/inet_neta.c
new file mode 100644
index 0000000000..59b156f7f6
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet_neta.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char orig_rcsid[] = "From Id: inet_neta.c,v 8.2 1996/08/08 06:54:44 vixie Exp";
+static const char rcsid[] = "$Id$";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/*
+ * char *
+ * inet_neta(src, dst, size)
+ * format a u_long network number into presentation format.
+ * return:
+ * pointer to dst, or NULL if an error occurred (check errno).
+ * note:
+ * format of ``src'' is as for inet_network().
+ * author:
+ * Paul Vixie (ISC), July 1996
+ */
+char *
+inet_neta(src, dst, size)
+ u_long src;
+ char *dst;
+ size_t size;
+{
+ char *odst = dst;
+ char *tp;
+
+ while (src & 0xffffffff) {
+ u_char b = (src & 0xff000000) >> 24;
+
+ src <<= 8;
+ if (b) {
+ if (size < sizeof "255.")
+ goto emsgsize;
+ tp = dst;
+ dst += SPRINTF((dst, "%u", b));
+ if (src != 0L) {
+ *dst++ = '.';
+ *dst = '\0';
+ }
+ size -= (size_t)(dst - tp);
+ }
+ }
+ if (dst == odst) {
+ if (size < sizeof "0.0.0.0")
+ goto emsgsize;
+ strcpy(dst, "0.0.0.0");
+ }
+ return (odst);
+
+ emsgsize:
+ errno = EMSGSIZE;
+ return (NULL);
+}
diff --git a/cpukit/libnetworking/libc/inet_netof.c b/cpukit/libnetworking/libc/inet_netof.c
new file mode 100644
index 0000000000..820036e62b
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet_netof.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1983, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * Return the network number from an internet
+ * address; handles class a/b/c network #'s.
+ */
+in_addr_t
+inet_netof(in)
+ struct in_addr in;
+{
+ register u_long i = ntohl(in.s_addr);
+
+ if (IN_CLASSA(i))
+ return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
+ else if (IN_CLASSB(i))
+ return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
+ else
+ return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
+}
diff --git a/cpukit/libnetworking/libc/inet_network.c b/cpukit/libnetworking/libc/inet_network.c
new file mode 100644
index 0000000000..386dbef6b2
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet_network.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1983, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+
+/*
+ * Internet network address interpretation routine.
+ * The library routines call this routine to interpret
+ * network numbers.
+ */
+in_addr_t
+inet_network(cp)
+ const char *cp;
+{
+ register u_long val, base, n, i;
+ register char c;
+ u_long parts[4], *pp = parts;
+
+again:
+ val = 0; base = 10;
+ if (*cp == '0')
+ base = 8, cp++;
+ if (*cp == 'x' || *cp == 'X')
+ base = 16, cp++;
+ while ((c = *cp) != 0) {
+ if (isdigit(c)) {
+ val = (val * base) + (c - '0');
+ cp++;
+ continue;
+ }
+ if (base == 16 && isxdigit(c)) {
+ val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
+ cp++;
+ continue;
+ }
+ break;
+ }
+ if (*cp == '.') {
+ if (pp >= parts + 3)
+ return (INADDR_NONE);
+ *pp++ = val, cp++;
+ goto again;
+ }
+ if (*cp && !isspace(*cp))
+ return (INADDR_NONE);
+ *pp++ = val;
+ n = pp - parts;
+ for (val = 0, i = 0; i < n; i++) {
+ val <<= 8;
+ val |= parts[i] & 0xff;
+ }
+ return (val);
+}
diff --git a/cpukit/libnetworking/libc/inet_ntoa.c b/cpukit/libnetworking/libc/inet_ntoa.c
new file mode 100644
index 0000000000..0844b6c5ad
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet_ntoa.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1983, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+
+/*
+ * Convert network-format internet address
+ * to base 256 d.d.d.d representation.
+ */
+char *
+inet_ntoa(in)
+ struct in_addr in;
+{
+ static char ret[18];
+ char *strcpy(char *dest, const char *src);
+
+ strcpy(ret, "[inet_ntoa error]");
+ (void) inet_ntop(AF_INET, &in, ret, sizeof ret);
+ return (ret);
+}
diff --git a/cpukit/libnetworking/libc/inet_ntop.c b/cpukit/libnetworking/libc/inet_ntop.c
new file mode 100644
index 0000000000..4abefc5076
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet_ntop.c
@@ -0,0 +1,193 @@
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#define SPRINTF(x) ((size_t)sprintf x)
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const u_char *src, char *dst, socklen_t size);
+static const char *inet_ntop6(const u_char *src, char *dst, socklen_t size);
+
+/* char *
+ * inet_ntop(af, src, dst, size)
+ * convert a network format address to presentation format.
+ * return:
+ * pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ * Paul Vixie, 1996.
+ */
+const char *
+inet_ntop(af, src, dst, size)
+ int af;
+ const void *src;
+ char *dst;
+ socklen_t size;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+ case AF_INET6:
+ return (inet_ntop6(src, dst, size));
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ * format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ * `dst' (as a const)
+ * notes:
+ * (1) uses no statics
+ * (2) takes a u_char* not an in_addr as input
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(src, dst, size)
+ const u_char *src;
+ char *dst;
+ socklen_t size;
+{
+ static const char fmt[] = "%u.%u.%u.%u";
+ char tmp[sizeof "255.255.255.255"];
+
+ if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ * convert IPv6 binary address into presentation (printable) format
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(src, dst, size)
+ const u_char *src;
+ char *dst;
+ socklen_t size;
+{
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+ struct { int base, len; } best, cur;
+ u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
+ int i;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof words);
+ for (i = 0; i < NS_IN6ADDRSZ; i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ best.len = 0;
+ cur.base = -1;
+ cur.len = 0;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base)
+ *tp++ = ':';
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0)
+ *tp++ = ':';
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 &&
+ (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+ if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
+ return (NULL);
+ tp += strlen(tp);
+ break;
+ }
+ tp += SPRINTF((tp, "%x", words[i]));
+ }
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) ==
+ (NS_IN6ADDRSZ / NS_INT16SZ))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((size_t)(tp - tmp) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
diff --git a/cpukit/libnetworking/libc/inet_pton.c b/cpukit/libnetworking/libc/inet_pton.c
new file mode 100644
index 0000000000..8d21111cfa
--- /dev/null
+++ b/cpukit/libnetworking/libc/inet_pton.c
@@ -0,0 +1,214 @@
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <string.h>
+#include <errno.h>
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4 __P((const char *src, u_char *dst));
+static int inet_pton6 __P((const char *src, u_char *dst));
+
+/* int
+ * inet_pton(af, src, dst)
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * return:
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ * Paul Vixie, 1996.
+ */
+int
+inet_pton(af, src, dst)
+ int af;
+ const char *src;
+ void *dst;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+ case AF_INET6:
+ return (inet_pton6(src, dst));
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+ /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ * 1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(src, dst)
+ const char *src;
+ u_char *dst;
+{
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ u_char tmp[NS_INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ u_int new = *tp * 10 + (pch - digits);
+
+ if (new > 255)
+ return (0);
+ *tp = new;
+ if (! saw_digit) {
+ if (++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return (0);
+ }
+ if (octets < 4)
+ return (0);
+
+ memcpy(dst, tmp, NS_INADDRSZ);
+ return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ * convert presentation level address to network order binary form.
+ * return:
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ * (1) does not touch `dst' unless it's returning 1.
+ * (2) :: in a full address is silently ignored.
+ * credit:
+ * inspired by Mark Andrews.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton6(src, dst)
+ const char *src;
+ u_char *dst;
+{
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, saw_xdigit;
+ u_int val;
+
+ memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+ endp = tp + NS_IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return (0);
+ curtok = src;
+ saw_xdigit = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (val > 0xffff)
+ return (0);
+ saw_xdigit = 1;
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!saw_xdigit) {
+ if (colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ }
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += NS_INADDRSZ;
+ saw_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if (saw_xdigit) {
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = tp - colonp;
+ int i;
+
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return (0);
+ memcpy(dst, tmp, NS_IN6ADDRSZ);
+ return (1);
+}
diff --git a/cpukit/libnetworking/libc/iso_addr.3 b/cpukit/libnetworking/libc/iso_addr.3
new file mode 100644
index 0000000000..0c9973bef4
--- /dev/null
+++ b/cpukit/libnetworking/libc/iso_addr.3
@@ -0,0 +1,111 @@
+.\" Copyright (c) 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.
+.\"
+.\" @(#)iso_addr.3 8.1 (Berkeley) 6/4/93
+.\" $Id$
+.\"
+.Dd June 4, 1993
+.Dt ISO_ADDR 3
+.Os
+.Sh NAME
+.Nm iso_addr ,
+.Nm iso_ntoa
+.Nd "elementary network address conversion routines for Open System Interconnection
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netiso/iso.h>
+.Ft struct iso_addr *
+.Fn iso_addr "char *cp"
+.Ft char *
+.Fn iso_ntoa "struct iso_addr *isoa"
+.Sh DESCRIPTION
+The routine
+.Fn iso_addr
+interprets character strings representing
+.Tn OSI
+addresses, returning binary information suitable
+for use in system calls.
+The routine
+.Fn iso_ntoa
+takes
+.Tn OSI
+addresses and returns
+.Tn ASCII
+strings representing NSAPs (network service
+access points) in a
+notation inverse to that accepted by
+.Fn iso_addr .
+.Pp
+Unfortunately, no universal standard exists for representing
+.Tn OSI
+network addresses.
+.Pp
+The format employed by
+.Fn iso_addr
+is a sequence of hexadecimal
+.Dq digits
+(optionally separated by periods),
+of the form:
+.Bd -filled -offset indent
+<hex digits>.<hex digits>.<hex digits>
+.Ed
+.Pp
+Each pair of hexadecimal digits represents a byte
+with the leading digit indicating the higher-ordered bits.
+A period following an even number of bytes has no
+effect (but may be used to increase legibility).
+A period following an odd number of bytes has the
+effect of causing the byte of address being translated
+to have its higher order bits filled with zeros.
+.Sh RETURN VALUES
+.Fn iso_ntoa
+always returns a null terminated string.
+.Fn iso_addr
+always returns a pointer to a struct iso_addr.
+(See
+.Sx BUGS . )
+.Sh SEE ALSO
+.Xr iso 4
+.Sh HISTORY
+The
+.Fn iso_addr
+and
+.Fn iso_ntoa
+functions appeared in
+.Bx 4.3 Reno .
+.Sh BUGS
+The returned values
+reside in a static memory area.
+.Pp
+The function
+.Fn iso_addr
+should diagnose improperly formed input, and there should be an unambiguous
+way to recognize this.
diff --git a/cpukit/libnetworking/libc/iso_addr.c b/cpukit/libnetworking/libc/iso_addr.c
new file mode 100644
index 0000000000..eb14e8a72b
--- /dev/null
+++ b/cpukit/libnetworking/libc/iso_addr.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1989, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)iso_addr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <netiso/iso.h>
+#include <string.h>
+
+/* States*/
+#define VIRGIN 0
+#define GOTONE 1
+#define GOTTWO 2
+/* Inputs */
+#define DIGIT (4*0)
+#define END (4*1)
+#define DELIM (4*2)
+
+struct iso_addr *
+iso_addr(addr)
+ register const char *addr;
+{
+ static struct iso_addr out_addr;
+ register char *cp = out_addr.isoa_genaddr;
+ char *cplim = cp + sizeof(out_addr.isoa_genaddr);
+ register int byte = 0, state = VIRGIN, new;
+
+ bzero((char *)&out_addr, sizeof(out_addr));
+ do {
+ if ((*addr >= '0') && (*addr <= '9')) {
+ new = *addr - '0';
+ } else if ((*addr >= 'a') && (*addr <= 'f')) {
+ new = *addr - 'a' + 10;
+ } else if ((*addr >= 'A') && (*addr <= 'F')) {
+ new = *addr - 'A' + 10;
+ } else if (*addr == 0)
+ state |= END;
+ else
+ state |= DELIM;
+ addr++;
+ switch (state /* | INPUT */) {
+ case GOTTWO | DIGIT:
+ *cp++ = byte; /*FALLTHROUGH*/
+ case VIRGIN | DIGIT:
+ state = GOTONE; byte = new; continue;
+ case GOTONE | DIGIT:
+ state = GOTTWO; byte = new + (byte << 4); continue;
+ default: /* | DELIM */
+ state = VIRGIN; *cp++ = byte; byte = 0; continue;
+ case GOTONE | END:
+ case GOTTWO | END:
+ *cp++ = byte; /* FALLTHROUGH */
+ case VIRGIN | END:
+ break;
+ }
+ break;
+ } while (cp < cplim);
+ out_addr.isoa_len = cp - out_addr.isoa_genaddr;
+ return (&out_addr);
+}
+
+static char hexlist[] = "0123456789abcdef";
+
+char *
+iso_ntoa(isoa)
+ const struct iso_addr *isoa;
+{
+ static char tmpbuf[sizeof(isoa->isoa_genaddr)*3];
+ const u_char *binary;
+ char *cp;
+ int i;
+
+ binary = isoa->isoa_genaddr;
+ cp = tmpbuf;
+
+ for (i = 0; i < isoa->isoa_len; i++) {
+ *cp++ = hexlist[*binary >> 4];
+ *cp++ = hexlist[*binary++ & 0xf];
+
+ if ((((i % 2) == 0) && ((i + 1) < isoa->isoa_len)))
+ *cp++ = '.';
+ }
+ *cp = '\0';
+ return tmpbuf;
+}
diff --git a/cpukit/libnetworking/libc/linkaddr.3 b/cpukit/libnetworking/libc/linkaddr.3
new file mode 100644
index 0000000000..6999add0e8
--- /dev/null
+++ b/cpukit/libnetworking/libc/linkaddr.3
@@ -0,0 +1,138 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Donn Seeley at BSDI.
+.\"
+.\" 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.
+.\"
+.\" From: @(#)linkaddr.3 8.1 (Berkeley) 7/28/93
+.\" $Id$
+.\"
+.Dd June 17, 1996
+.Dt LINK_ADDR 3
+.Os BSD 4.4
+.Sh NAME
+.Nm link_addr ,
+.Nm link_ntoa
+.Nd elementary address specification routines for link level access
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Fd #include <net/if_dl.h>
+.Ft void
+.Fn link_addr "const char *addr" "struct sockaddr_dl *sdl"
+.Ft char *
+.Fn link_ntoa "const struct sockaddr_dl *sdl"
+.Sh DESCRIPTION
+The routine
+.Fn link_addr
+interprets character strings representing
+link-level addresses, returning binary information suitable
+for use in system calls.
+The routine
+.Fn link_ntoa
+takes
+a link-level
+address and returns an
+.Tn ASCII
+string representing some of the information present,
+including the link level address itself, and the interface name
+or number, if present.
+This facility is experimental and is
+still subject to change.
+.Pp
+For
+.Fn link_addr ,
+the string
+.Fa addr
+may contain
+an optional network interface identifier of the form
+.Dq "name unit-number" ,
+suitable for the first argument to
+.Xr ifconfig 8 ,
+followed in all cases by a colon and
+an interface address in the form of
+groups of hexadecimal digits
+separated by periods.
+Each group represents a byte of address;
+address bytes are filled left to right from
+low order bytes through high order bytes.
+.Pp
+.\" A regular expression may make this format clearer:
+.\" .Bd -literal -offset indent
+.\" ([a-z]+[0-9]+:)?[0-9a-f]+(\e.[0-9a-f]+)*
+.\" .Ed
+.\" .Pp
+Thus
+.Li le0:8.0.9.13.d.30
+represents an ethernet address
+to be transmitted on the first Lance ethernet interface.
+.Pp
+The direct use of these functions is deprecated in favor of the
+.Xr addr2ascii 3
+interface; however, portable programs cannot rely on the latter as it is
+not yet widely implemented.
+.Sh RETURN VALUES
+.Fn link_ntoa
+always returns a null terminated string.
+.Fn link_addr
+has no return value.
+(See
+.Sx BUGS . )
+.Sh SEE ALSO
+.Xr addr2ascii 3
+.\" .Xr iso 4
+.Sh HISTORY
+The
+.Fn link_addr
+and
+.Fn link_ntoa
+functions appeared in
+.Bx 4.3 Reno .
+.Sh BUGS
+The returned values for link_ntoa
+reside in a static memory area.
+.Pp
+The function
+.Fn link_addr
+should diagnose improperly formed input, and there should be an unambiguous
+way to recognize this.
+.Pp
+If the
+.Va sdl_len
+field of the link socket address
+.Fa sdl
+is 0,
+.Fn link_ntoa
+will not insert a colon before the interface address bytes.
+If this translated address is given to
+.Fn link_addr
+without inserting an initial colon,
+the latter will not interpret it correctly.
diff --git a/cpukit/libnetworking/libc/linkaddr.c b/cpukit/libnetworking/libc/linkaddr.c
new file mode 100644
index 0000000000..2bad464b12
--- /dev/null
+++ b/cpukit/libnetworking/libc/linkaddr.c
@@ -0,0 +1,161 @@
+/*-
+ * Copyright (c) 1990, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if_dl.h>
+#include <string.h>
+
+/* States*/
+#define NAMING 0
+#define GOTONE 1
+#define GOTTWO 2
+#define RESET 3
+/* Inputs */
+#define DIGIT (4*0)
+#define END (4*1)
+#define DELIM (4*2)
+#define LETTER (4*3)
+
+void
+link_addr(addr, sdl)
+ register const char *addr;
+ register struct sockaddr_dl *sdl;
+{
+ register char *cp = sdl->sdl_data;
+ char *cplim = sdl->sdl_len + (char *)sdl;
+ register int byte = 0, state = NAMING,
+ new=0; /* new=0 to avoid warning */
+
+ bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1);
+ sdl->sdl_family = AF_LINK;
+ do {
+ state &= ~LETTER;
+ if ((*addr >= '0') && (*addr <= '9')) {
+ new = *addr - '0';
+ } else if ((*addr >= 'a') && (*addr <= 'f')) {
+ new = *addr - 'a' + 10;
+ } else if ((*addr >= 'A') && (*addr <= 'F')) {
+ new = *addr - 'A' + 10;
+ } else if (*addr == 0) {
+ state |= END;
+ } else if (state == NAMING &&
+ (((*addr >= 'A') && (*addr <= 'Z')) ||
+ ((*addr >= 'a') && (*addr <= 'z'))))
+ state |= LETTER;
+ else
+ state |= DELIM;
+ addr++;
+ switch (state /* | INPUT */) {
+ case NAMING | DIGIT:
+ case NAMING | LETTER:
+ *cp++ = addr[-1];
+ continue;
+ case NAMING | DELIM:
+ state = RESET;
+ sdl->sdl_nlen = cp - sdl->sdl_data;
+ continue;
+ case GOTTWO | DIGIT:
+ *cp++ = byte;
+ /* FALLTHROUGH */
+ case RESET | DIGIT:
+ state = GOTONE;
+ byte = new;
+ continue;
+ case GOTONE | DIGIT:
+ state = GOTTWO;
+ byte = new + (byte << 4);
+ continue;
+ default: /* | DELIM */
+ state = RESET;
+ *cp++ = byte;
+ byte = 0;
+ continue;
+ case GOTONE | END:
+ case GOTTWO | END:
+ *cp++ = byte;
+ /* FALLTHROUGH */
+ case RESET | END:
+ break;
+ }
+ break;
+ } while (cp < cplim);
+ sdl->sdl_alen = cp - LLADDR(sdl);
+ new = cp - (char *)sdl;
+ if (new > sizeof(*sdl))
+ sdl->sdl_len = new;
+ return;
+}
+
+static char hexlist[] = "0123456789abcdef";
+
+char *
+link_ntoa(sdl)
+ register const struct sockaddr_dl *sdl;
+{
+ static char obuf[64];
+ register char *out = obuf;
+ register int i;
+ register u_char *in = (u_char *)LLADDR(sdl);
+ u_char *inlim = in + sdl->sdl_alen;
+ int firsttime = 1;
+
+ if (sdl->sdl_nlen) {
+ bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen);
+ out += sdl->sdl_nlen;
+ if (sdl->sdl_alen)
+ *out++ = ':';
+ }
+ while (in < inlim) {
+ if (firsttime)
+ firsttime = 0;
+ else
+ *out++ = '.';
+ i = *in++;
+ if (i > 0xf) {
+ out[1] = hexlist[i & 0xf];
+ i >>= 4;
+ out[0] = hexlist[i];
+ out += 2;
+ } else
+ *out++ = hexlist[i];
+ }
+ *out = 0;
+ return (obuf);
+}
diff --git a/cpukit/libnetworking/libc/map_v4v6.c b/cpukit/libnetworking/libc/map_v4v6.c
new file mode 100644
index 0000000000..0f8658e117
--- /dev/null
+++ b/cpukit/libnetworking/libc/map_v4v6.c
@@ -0,0 +1,128 @@
+/*
+ * ++Copyright++ 1985, 1988, 1993
+ * -
+ * Copyright (c) 1985, 1988, 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.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <syslog.h>
+
+typedef union {
+ int32_t al;
+ char ac;
+} align;
+
+void
+_map_v4v6_address(src, dst)
+ const char *src;
+ char *dst;
+{
+ u_char *p = (u_char *)dst;
+ char tmp[INADDRSZ];
+ int i;
+
+ /* Stash a temporary copy so our caller can update in place. */
+ bcopy(src, tmp, INADDRSZ);
+ /* Mark this ipv6 addr as a mapped ipv4. */
+ for (i = 0; i < 10; i++)
+ *p++ = 0x00;
+ *p++ = 0xff;
+ *p++ = 0xff;
+ /* Retrieve the saved copy and we're done. */
+ bcopy(tmp, (void*)p, INADDRSZ);
+}
+
+void
+_map_v4v6_hostent(hp, bpp, lenp)
+ struct hostent *hp;
+ char **bpp;
+ int *lenp;
+{
+ char **ap;
+
+ if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
+ return;
+ hp->h_addrtype = AF_INET6;
+ hp->h_length = IN6ADDRSZ;
+ for (ap = hp->h_addr_list; *ap; ap++) {
+ int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
+
+ if (*lenp < (i + IN6ADDRSZ)) {
+ /* Out of memory. Truncate address list here. XXX */
+ *ap = NULL;
+ return;
+ }
+ *bpp += i;
+ *lenp -= i;
+ _map_v4v6_address(*ap, *bpp);
+ *ap = *bpp;
+ *bpp += IN6ADDRSZ;
+ *lenp -= IN6ADDRSZ;
+ }
+}
diff --git a/cpukit/libnetworking/libc/ns.3 b/cpukit/libnetworking/libc/ns.3
new file mode 100644
index 0000000000..e621ad2d90
--- /dev/null
+++ b/cpukit/libnetworking/libc/ns.3
@@ -0,0 +1,131 @@
+.\" Copyright (c) 1986, 1991, 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.
+.\"
+.\" @(#)ns.3 8.1 (Berkeley) 6/4/93
+.\" $Id$
+.\"
+.Dd June 4, 1993
+.Dt NS 3
+.Os BSD 4.3
+.Sh NAME
+.Nm ns_addr ,
+.Nm ns_ntoa
+.Nd Xerox
+.Tn NS Ns (tm)
+address conversion routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netns/ns.h>
+.Ft struct ns_addr
+.Fn ns_addr "char *cp"
+.Ft char *
+.Fn ns_ntoa "struct ns_addr ns"
+.Sh DESCRIPTION
+The routine
+.Fn ns_addr
+interprets character strings representing
+.Tn XNS
+addresses, returning binary information suitable
+for use in system calls.
+The routine
+.Fn ns_ntoa
+takes
+.Tn XNS
+addresses and returns
+.Tn ASCII
+strings representing the address in a
+notation in common use in the Xerox Development Environment:
+.Bd -filled -offset indent
+<network number>.<host number>.<port number>
+.Ed
+.Pp
+Trailing zero fields are suppressed, and each number is printed in hexadecimal,
+in a format suitable for input to
+.Fn ns_addr .
+Any fields lacking super-decimal digits will have a
+trailing
+.Ql H
+appended.
+.Pp
+Unfortunately, no universal standard exists for representing
+.Tn XNS
+addresses.
+An effort has been made to insure that
+.Fn ns_addr
+be compatible with most formats in common use.
+It will first separate an address into 1 to 3 fields using a single delimiter
+chosen from
+period
+.Ql \&. ,
+colon
+.Ql \&:
+or pound-sign
+.Ql \&# .
+Each field is then examined for byte separators (colon or period).
+If there are byte separators, each subfield separated is taken to be
+a small hexadecimal number, and the entirety is taken as a network-byte-ordered
+quantity to be zero extended in the high-network-order bytes.
+Next, the field is inspected for hyphens, in which case
+the field is assumed to be a number in decimal notation
+with hyphens separating the millenia.
+Next, the field is assumed to be a number:
+It is interpreted
+as hexadecimal if there is a leading
+.Ql 0x
+(as in C),
+a trailing
+.Ql H
+(as in Mesa), or there are any super-decimal digits present.
+It is interpreted as octal is there is a leading
+.Ql 0
+and there are no super-octal digits.
+Otherwise, it is converted as a decimal number.
+.Sh RETURN VALUES
+None. (See
+.Sx BUGS . )
+.Sh SEE ALSO
+.Xr hosts 5 ,
+.Xr networks 5
+.Sh HISTORY
+The
+.Fn ns_addr
+and
+.Fn ns_toa
+functions appeared in
+.Bx 4.3 .
+.Sh BUGS
+The string returned by
+.Fn ns_ntoa
+resides in a static memory area.
+The function
+.Fn ns_addr
+should diagnose improperly formed input, and there should be an unambiguous
+way to recognize this.
diff --git a/cpukit/libnetworking/libc/ns_addr.c b/cpukit/libnetworking/libc/ns_addr.c
new file mode 100644
index 0000000000..18fabe91f1
--- /dev/null
+++ b/cpukit/libnetworking/libc/ns_addr.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * J.Q. Johnson.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 6/7/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netns/ns.h>
+#include <stdio.h>
+#include <string.h>
+
+static struct ns_addr addr, zero_addr;
+
+static void Field(), cvtbase();
+
+struct ns_addr
+ns_addr(name)
+ const char *name;
+{
+ char separator;
+ char *hostname, *socketname, *cp;
+ char buf[50];
+
+ (void)strncpy(buf, name, sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+
+ /*
+ * First, figure out what he intends as a field separtor.
+ * Despite the way this routine is written, the prefered
+ * form 2-272.AA001234H.01777, i.e. XDE standard.
+ * Great efforts are made to insure backward compatability.
+ */
+ if ((hostname = strchr(buf, '#')) != NULL)
+ separator = '#';
+ else {
+ hostname = strchr(buf, '.');
+ if ((cp = strchr(buf, ':')) &&
+ ((hostname && cp < hostname) || (hostname == 0))) {
+ hostname = cp;
+ separator = ':';
+ } else
+ separator = '.';
+ }
+ if (hostname)
+ *hostname++ = 0;
+
+ addr = zero_addr;
+ Field(buf, addr.x_net.c_net, 4);
+ if (hostname == 0)
+ return (addr); /* No separator means net only */
+
+ socketname = strchr(hostname, separator);
+ if (socketname) {
+ *socketname++ = 0;
+ Field(socketname, (u_char *)&addr.x_port, 2);
+ }
+
+ Field(hostname, addr.x_host.c_host, 6);
+
+ return (addr);
+}
+
+static void
+Field(buf, out, len)
+ char *buf;
+ u_char *out;
+ int len;
+{
+ register char *bp = buf;
+ int i, ibase, base16 = 0, base10 = 0, clen = 0;
+ int hb[6], *hp;
+ char *fmt;
+
+ /*
+ * first try 2-273#2-852-151-014#socket
+ */
+ if ((*buf != '-') &&
+ (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
+ cvtbase(1000L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * try form 8E1#0.0.AA.0.5E.E6#socket
+ */
+ if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
+ cvtbase(256L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * try form 8E1#0:0:AA:0:5E:E6#socket
+ */
+ if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
+ cvtbase(256L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * This is REALLY stretching it but there was a
+ * comma notation separting shorts -- definitely non standard
+ */
+ if (1 < (i = sscanf(buf,"%x,%x,%x",
+ &hb[0], &hb[1], &hb[2]))) {
+ hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
+ hb[2] = htons(hb[2]);
+ cvtbase(65536L, 256, hb, i, out, len);
+ return;
+ }
+
+ /* Need to decide if base 10, 16 or 8 */
+ while (*bp) switch (*bp++) {
+
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '-':
+ break;
+
+ case '8': case '9':
+ base10 = 1;
+ break;
+
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ base16 = 1;
+ break;
+
+ case 'x': case 'X':
+ *--bp = '0';
+ base16 = 1;
+ break;
+
+ case 'h': case 'H':
+ base16 = 1;
+ /* fall into */
+
+ default:
+ *--bp = 0; /* Ends Loop */
+ }
+ if (base16) {
+ fmt = "%3x";
+ ibase = 4096;
+ } else if (base10 == 0 && *buf == '0') {
+ fmt = "%3o";
+ ibase = 512;
+ } else {
+ fmt = "%3d";
+ ibase = 1000;
+ }
+
+ for (bp = buf; *bp++; ) clen++;
+ if (clen == 0) clen++;
+ if (clen > 18) clen = 18;
+ i = ((clen - 1) / 3) + 1;
+ bp = clen + buf - 3;
+ hp = hb + i - 1;
+
+ while (hp > hb) {
+ (void)sscanf(bp, fmt, hp);
+ bp[0] = 0;
+ hp--;
+ bp -= 3;
+ }
+ (void)sscanf(buf, fmt, hp);
+ cvtbase((long)ibase, 256, hb, i, out, len);
+}
+
+static void
+cvtbase(oldbase,newbase,input,inlen,result,reslen)
+ long oldbase;
+ int newbase;
+ int input[];
+ int inlen;
+ unsigned char result[];
+ int reslen;
+{
+ int d, e;
+ long sum;
+
+ e = 1;
+ while (e > 0 && reslen > 0) {
+ d = 0; e = 0; sum = 0;
+ /* long division: input=input/newbase */
+ while (d < inlen) {
+ sum = sum*oldbase + (long) input[d];
+ e += (sum > 0);
+ input[d++] = sum / newbase;
+ sum %= newbase;
+ }
+ result[--reslen] = sum; /* accumulate remainder */
+ }
+ for (d=0; d < reslen; d++)
+ result[d] = 0;
+}
diff --git a/cpukit/libnetworking/libc/ns_name.c b/cpukit/libnetworking/libc/ns_name.c
new file mode 100644
index 0000000000..af10d2f062
--- /dev/null
+++ b/cpukit/libnetworking/libc/ns_name.c
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if !defined(__rtems__)
+#if !defined(LINT) && !defined(CODECENTER)
+static char rcsid[] = "$Id$";
+#endif /* not lint */
+#endif /* not rtems */
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+
+/* Data. */
+
+static char digits[] = "0123456789";
+
+/* Forward. */
+
+static int special(int);
+static int printable(int);
+static int dn_find(const u_char *, const u_char *,
+ const u_char * const *,
+ const u_char * const *);
+
+/* Public. */
+
+/*
+ * ns_name_ntop(src, dst, dstsiz)
+ * Convert an encoded domain name to printable ascii as per RFC1035.
+ * return:
+ * Number of bytes written to buffer, or -1 (with errno set)
+ * notes:
+ * The root is returned as "."
+ * All other domains are returned in non absolute form
+ */
+int
+ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
+ const u_char *cp;
+ char *dn, *eom;
+ u_char c;
+ u_int n;
+
+ cp = src;
+ dn = dst;
+ eom = dst + dstsiz;
+
+ while ((n = *cp++) != 0) {
+ if ((n & NS_CMPRSFLGS) != 0) {
+ /* Some kind of compression pointer. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (dn != dst) {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '.';
+ }
+ if (dn + n >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ for ((void)NULL; n > 0; n--) {
+ c = *cp++;
+ if (special(c)) {
+ if (dn + 1 >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\\';
+ *dn++ = (char)c;
+ } else if (!printable(c)) {
+ if (dn + 3 >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\\';
+ *dn++ = digits[c / 100];
+ *dn++ = digits[(c % 100) / 10];
+ *dn++ = digits[c % 10];
+ } else {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = (char)c;
+ }
+ }
+ }
+ if (dn == dst) {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '.';
+ }
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\0';
+ return (dn - dst);
+}
+
+/*
+ * ns_name_pton(src, dst, dstsiz)
+ * Convert a ascii string into an encoded domain name as per RFC1035.
+ * return:
+ * -1 if it fails
+ * 1 if string was fully qualified
+ * 0 is string was not fully qualified
+ * notes:
+ * Enforces label and domain length limits.
+ */
+
+int
+ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
+ u_char *label, *bp, *eom;
+ int c, n, escaped;
+ char *cp;
+
+ escaped = 0;
+ bp = dst;
+ eom = dst + dstsiz;
+ label = bp++;
+
+ while ((c = *src++) != 0) {
+ if (escaped) {
+ if ((cp = strchr(digits, c)) != NULL) {
+ n = (cp - digits) * 100;
+ if ((c = *src++) == 0 ||
+ (cp = strchr(digits, c)) == NULL) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ n += (cp - digits) * 10;
+ if ((c = *src++) == 0 ||
+ (cp = strchr(digits, c)) == NULL) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ n += (cp - digits);
+ if (n > 255) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ c = n;
+ }
+ escaped = 0;
+ } else if (c == '\\') {
+ escaped = 1;
+ continue;
+ } else if (c == '.') {
+ c = (bp - label - 1);
+ if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (label >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *label = c;
+ /* Fully qualified ? */
+ if (*src == '\0') {
+ if (c != 0) {
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = '\0';
+ }
+ if ((bp - dst) > MAXCDNAME) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ return (1);
+ }
+ if (c == 0) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ label = bp++;
+ continue;
+ }
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = (u_char)c;
+ }
+ c = (bp - label - 1);
+ if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (label >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *label = c;
+ if (c != 0) {
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = 0;
+ }
+ if ((bp - dst) > MAXCDNAME) { /* src too big */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * ns_name_unpack(msg, eom, src, dst, dstsiz)
+ * Unpack a domain name from a message, source may be compressed.
+ * return:
+ * -1 if it fails, or consumed octets if it succeeds.
+ */
+int
+ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
+ u_char *dst, size_t dstsiz)
+{
+ const u_char *srcp, *dstlim;
+ u_char *dstp;
+ int n, len, checked;
+
+ len = -1;
+ checked = 0;
+ dstp = dst;
+ srcp = src;
+ dstlim = dst + dstsiz;
+ if (srcp < msg || srcp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ /* Fetch next label in domain name. */
+ while ((n = *srcp++) != 0) {
+ /* Check for indirection. */
+ switch (n & NS_CMPRSFLGS) {
+ case 0:
+ /* Limit checks. */
+ if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ checked += n + 1;
+ *dstp++ = n;
+ memcpy(dstp, srcp, n);
+ dstp += n;
+ srcp += n;
+ break;
+
+ case NS_CMPRSFLGS:
+ if (srcp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (len < 0)
+ len = srcp - src + 1;
+ srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
+ if (srcp < msg || srcp >= eom) { /* Out of range. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ checked += 2;
+ /*
+ * Check for loops in the compressed name;
+ * if we've looked at the whole message,
+ * there must be a loop.
+ */
+ if (checked >= eom - msg) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ break;
+
+ default:
+ errno = EMSGSIZE;
+ return (-1); /* flag error */
+ }
+ }
+ *dstp = '\0';
+ if (len < 0)
+ len = srcp - src;
+ return (len);
+}
+
+/*
+ * ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
+ * Pack domain name 'domain' into 'comp_dn'.
+ * return:
+ * Size of the compressed name, or -1.
+ * notes:
+ * 'dnptrs' is an array of pointers to previous compressed names.
+ * dnptrs[0] is a pointer to the beginning of the message. The array
+ * ends with NULL.
+ * 'lastdnptr' is a pointer to the end of the array pointed to
+ * by 'dnptrs'.
+ * Side effects:
+ * The list of pointers in dnptrs is updated for labels inserted into
+ * the message as we compress the name. If 'dnptr' is NULL, we don't
+ * try to compress names. If 'lastdnptr' is NULL, we don't update the
+ * list.
+ */
+int
+ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
+ const u_char **dnptrs, const u_char **lastdnptr)
+{
+ u_char *dstp;
+ const u_char **cpp, **lpp, *eob, *msg;
+ const u_char *srcp;
+ int n, l;
+
+ srcp = src;
+ dstp = dst;
+ eob = dstp + dstsiz;
+ lpp = cpp = NULL;
+ if (dnptrs != NULL) {
+ if ((msg = *dnptrs++) != NULL) {
+ for (cpp = dnptrs; *cpp != NULL; cpp++)
+ (void)NULL;
+ lpp = cpp; /* end of list to search */
+ }
+ } else
+ msg = NULL;
+
+ /* make sure the domain we are about to add is legal */
+ l = 0;
+ do {
+ n = *srcp;
+ if ((n & NS_CMPRSFLGS) != 0) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ l += n + 1;
+ if (l > MAXCDNAME) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ srcp += n + 1;
+ } while (n != 0);
+
+ srcp = src;
+ do {
+ /* Look to see if we can use pointers. */
+ n = *srcp;
+ if (n != 0 && msg != NULL) {
+ l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
+ (const u_char * const *)lpp);
+ if (l >= 0) {
+ if (dstp + 1 >= eob) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dstp++ = (l >> 8) | NS_CMPRSFLGS;
+ *dstp++ = l % 256;
+ return (dstp - dst);
+ }
+ /* Not found, save it. */
+ if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
+ (dstp - msg) < 0x4000) {
+ *cpp++ = dstp;
+ *cpp = NULL;
+ }
+ }
+ /* copy label to buffer */
+ if (n & NS_CMPRSFLGS) { /* Should not happen. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (dstp + 1 + n >= eob) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ memcpy(dstp, srcp, n + 1);
+ srcp += n + 1;
+ dstp += n + 1;
+ } while (n != 0);
+
+ if (dstp > eob) {
+ if (msg != NULL)
+ *lpp = NULL;
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ return (dstp - dst);
+}
+
+/*
+ * ns_name_uncompress(msg, eom, src, dst, dstsiz)
+ * Expand compressed domain name to presentation format.
+ * return:
+ * Number of bytes read out of `src', or -1 (with errno set).
+ * note:
+ * Root domain returns as "." not "".
+ */
+int
+ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
+ char *dst, size_t dstsiz)
+{
+ u_char tmp[NS_MAXCDNAME];
+ int n;
+
+ if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
+ return (-1);
+ if (ns_name_ntop(tmp, dst, dstsiz) == -1)
+ return (-1);
+ return (n);
+}
+
+/*
+ * ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
+ * Compress a domain name into wire format, using compression pointers.
+ * return:
+ * Number of bytes consumed in `dst' or -1 (with errno set).
+ * notes:
+ * 'dnptrs' is an array of pointers to previous compressed names.
+ * dnptrs[0] is a pointer to the beginning of the message.
+ * The list ends with NULL. 'lastdnptr' is a pointer to the end of the
+ * array pointed to by 'dnptrs'. Side effect is to update the list of
+ * pointers for labels inserted into the message as we compress the name.
+ * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
+ * is NULL, we don't update the list.
+ */
+int
+ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
+ const u_char **dnptrs, const u_char **lastdnptr)
+{
+ u_char tmp[NS_MAXCDNAME];
+
+ if (ns_name_pton(src, tmp, sizeof tmp) == -1)
+ return (-1);
+ return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
+}
+
+/*
+ * ns_name_skip(ptrptr, eom)
+ * Advance *ptrptr to skip over the compressed name it points at.
+ * return:
+ * 0 on success, -1 (with errno set) on failure.
+ */
+int
+ns_name_skip(const u_char **ptrptr, const u_char *eom) {
+ const u_char *cp;
+ u_int n;
+
+ cp = *ptrptr;
+ while (cp < eom && (n = *cp++) != 0) {
+ /* Check for indirection. */
+ switch (n & NS_CMPRSFLGS) {
+ case 0: /* normal case, n == len */
+ cp += n;
+ continue;
+ case NS_CMPRSFLGS: /* indirection */
+ cp++;
+ break;
+ default: /* illegal type */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ break;
+ }
+ if (cp > eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *ptrptr = cp;
+ return (0);
+}
+
+/* Private. */
+
+/*
+ * special(ch)
+ * Thinking in noninternationalized USASCII (per the DNS spec),
+ * is this characted special ("in need of quoting") ?
+ * return:
+ * boolean.
+ */
+static int
+special(int ch) {
+ switch (ch) {
+ case 0x22: /* '"' */
+ case 0x2E: /* '.' */
+ case 0x3B: /* ';' */
+ case 0x5C: /* '\\' */
+ /* Special modifiers in zone files. */
+ case 0x40: /* '@' */
+ case 0x24: /* '$' */
+ return (1);
+ default:
+ return (0);
+ }
+}
+
+/*
+ * printable(ch)
+ * Thinking in noninternationalized USASCII (per the DNS spec),
+ * is this character visible and not a space when printed ?
+ * return:
+ * boolean.
+ */
+static int
+printable(int ch) {
+ return (ch > 0x20 && ch < 0x7f);
+}
+
+/*
+ * Thinking in noninternationalized USASCII (per the DNS spec),
+ * convert this character to lower case if it's upper case.
+ */
+static int
+mklower(int ch) {
+ if (ch >= 0x41 && ch <= 0x5A)
+ return (ch + 0x20);
+ return (ch);
+}
+
+/*
+ * dn_find(domain, msg, dnptrs, lastdnptr)
+ * Search for the counted-label name in an array of compressed names.
+ * return:
+ * offset from msg if found, or -1.
+ * notes:
+ * dnptrs is the pointer to the first name on the list,
+ * not the pointer to the start of the message.
+ */
+static int
+dn_find(const u_char *domain, const u_char *msg,
+ const u_char * const *dnptrs,
+ const u_char * const *lastdnptr)
+{
+ const u_char *dn, *cp, *sp;
+ const u_char * const *cpp;
+ u_int n;
+
+ for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
+ dn = domain;
+ sp = cp = *cpp;
+ while ((n = *cp++) != 0) {
+ /*
+ * check for indirection
+ */
+ switch (n & NS_CMPRSFLGS) {
+ case 0: /* normal case, n == len */
+ if (n != *dn++)
+ goto next;
+ for ((void)NULL; n > 0; n--)
+ if (mklower(*dn++) != mklower(*cp++))
+ goto next;
+ /* Is next root for both ? */
+ if (*dn == '\0' && *cp == '\0')
+ return (sp - msg);
+ if (*dn)
+ continue;
+ goto next;
+
+ case NS_CMPRSFLGS: /* indirection */
+ cp = msg + (((n & 0x3f) << 8) | *cp);
+ break;
+
+ default: /* illegal type */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ }
+ next: ;
+ }
+ errno = ENOENT;
+ return (-1);
+}
diff --git a/cpukit/libnetworking/libc/ns_netint.c b/cpukit/libnetworking/libc/ns_netint.c
new file mode 100644
index 0000000000..3c09da8f8c
--- /dev/null
+++ b/cpukit/libnetworking/libc/ns_netint.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if !defined(__rtems__)
+#if !defined(LINT) && !defined(CODECENTER)
+static char rcsid[] = "$Id$";
+#endif /* not lint */
+#endif /* not rtems */
+
+/* Import. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+u_int
+ns_get16(const u_char *src) {
+ u_int dst;
+
+ NS_GET16(dst, src);
+ return (dst);
+}
+
+u_long
+ns_get32(const u_char *src) {
+ u_long dst;
+
+ NS_GET32(dst, src);
+ return (dst);
+}
+
+void
+ns_put16(u_int src, u_char *dst) {
+ NS_PUT16(src, dst);
+}
+
+void
+ns_put32(u_long src, u_char *dst) {
+ NS_PUT32(src, dst);
+}
diff --git a/cpukit/libnetworking/libc/ns_ntoa.c b/cpukit/libnetworking/libc/ns_ntoa.c
new file mode 100644
index 0000000000..9d0be2e1dc
--- /dev/null
+++ b/cpukit/libnetworking/libc/ns_ntoa.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1986, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ns_ntoa.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netns/ns.h>
+#include <stdio.h>
+
+char *
+ns_ntoa(addr)
+ struct ns_addr addr;
+{
+ static char obuf[40];
+ union { union ns_net net_e; u_long long_e; } net;
+ u_short port = htons(addr.x_port);
+ register char *cp;
+ char *cp2;
+ register u_char *up = addr.x_host.c_host;
+ u_char *uplim = up + 6;
+ static char *spectHex();
+
+ net.net_e = addr.x_net;
+ sprintf(obuf, "%lx", (u_long)ntohl(net.long_e));
+ cp = spectHex(obuf);
+ cp2 = cp + 1;
+ while (*up==0 && up < uplim) up++;
+ if (up == uplim) {
+ if (port) {
+ sprintf(cp, ".0");
+ cp += 2;
+ }
+ } else {
+ sprintf(cp, ".%x", *up++);
+ while (up < uplim) {
+ while (*cp) cp++;
+ sprintf(cp, "%02x", *up++);
+ }
+ cp = spectHex(cp2);
+ }
+ if (port) {
+ sprintf(cp, ".%x", port);
+ spectHex(cp + 1);
+ }
+ return (obuf);
+}
+
+static char *
+spectHex(p0)
+ char *p0;
+{
+ int ok = 0;
+ int nonzero = 0;
+ register char *p = p0;
+ for (; *p; p++) switch (*p) {
+
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ *p += ('A' - 'a');
+ /* fall into . . . */
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ ok = 1;
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ nonzero = 1;
+ }
+ if (nonzero && !ok) { *p++ = 'H'; *p = 0; }
+ return (p);
+}
diff --git a/cpukit/libnetworking/libc/ns_parse.c b/cpukit/libnetworking/libc/ns_parse.c
new file mode 100644
index 0000000000..7c5ed343bf
--- /dev/null
+++ b/cpukit/libnetworking/libc/ns_parse.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if !defined(__rtems__)
+#if !defined(LINT) && !defined(CODECENTER)
+static char rcsid[] = "$Id$";
+#endif /* not lint */
+#endif /* not rtems */
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+
+/* These need to be in the same order as the nres.h:ns_flag enum. */
+struct _ns_flagdata _ns_flagdata[16] = {
+ { 0x8000, 15 }, /* qr. */
+ { 0x7800, 11 }, /* opcode. */
+ { 0x0400, 10 }, /* aa. */
+ { 0x0200, 9 }, /* tc. */
+ { 0x0100, 8 }, /* rd. */
+ { 0x0080, 7 }, /* ra. */
+ { 0x0040, 6 }, /* z. */
+ { 0x0020, 5 }, /* ad. */
+ { 0x0010, 4 }, /* cd. */
+ { 0x000f, 0 }, /* rcode. */
+ { 0x0000, 0 }, /* expansion (1/6). */
+ { 0x0000, 0 }, /* expansion (2/6). */
+ { 0x0000, 0 }, /* expansion (3/6). */
+ { 0x0000, 0 }, /* expansion (4/6). */
+ { 0x0000, 0 }, /* expansion (5/6). */
+ { 0x0000, 0 }, /* expansion (6/6). */
+};
+
+static int
+skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
+ const u_char *optr = ptr;
+
+ for ((void)NULL; count > 0; count--) {
+ int b, rdlength;
+
+ b = dn_skipname(ptr, eom);
+ if (b < 0)
+ goto emsgsize;
+ ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
+ if (section != ns_s_qd) {
+ if (ptr + NS_INT32SZ > eom)
+ goto emsgsize;
+ ptr += NS_INT32SZ/*TTL*/;
+ if (ptr + NS_INT16SZ > eom)
+ goto emsgsize;
+ NS_GET16(rdlength, ptr);
+ ptr += rdlength/*RData*/;
+ }
+ }
+ if (ptr > eom)
+ goto emsgsize;
+ return (ptr - optr);
+ emsgsize:
+ errno = EMSGSIZE;
+ return (-1);
+}
+
+int
+ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
+ const u_char *eom = msg + msglen;
+ int i;
+
+ memset(handle, 0x5e, sizeof *handle);
+ handle->_msg = msg;
+ handle->_eom = eom;
+ if (msg + NS_INT16SZ > eom)
+ goto emsgsize;
+ NS_GET16(handle->_id, msg);
+ if (msg + NS_INT16SZ > eom)
+ goto emsgsize;
+ NS_GET16(handle->_flags, msg);
+ for (i = 0; i < ns_s_max; i++) {
+ if (msg + NS_INT16SZ > eom)
+ goto emsgsize;
+ NS_GET16(handle->_counts[i], msg);
+ }
+ for (i = 0; i < ns_s_max; i++)
+ if (handle->_counts[i] == 0)
+ handle->_sections[i] = NULL;
+ else {
+ int b = skiprr(msg, eom, (ns_sect)i,
+ handle->_counts[i]);
+
+ if (b < 0)
+ return (-1);
+ handle->_sections[i] = msg;
+ msg += b;
+ }
+ if (msg != eom)
+ goto emsgsize;
+ handle->_sect = ns_s_max;
+ handle->_rrnum = -1;
+ handle->_ptr = NULL;
+ return (0);
+ emsgsize:
+ errno = EMSGSIZE;
+ return (-1);
+}
+
+int
+ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
+ int b;
+
+ /* Make section right. */
+ if (section < 0 || section >= ns_s_max)
+ goto enodev;
+ if ((int)section != (int)handle->_sect) {
+ handle->_sect = section;
+ handle->_rrnum = 0;
+ handle->_ptr = handle->_sections[(int)section];
+ }
+
+ /* Make rrnum right. */
+ if (rrnum == -1)
+ rrnum = handle->_rrnum;
+ if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
+ goto enodev;
+ if (rrnum < handle->_rrnum) {
+ handle->_rrnum = 0;
+ handle->_ptr = handle->_sections[(int)section];
+ }
+
+ b = skiprr(handle->_msg, handle->_eom, section,
+ rrnum - handle->_rrnum);
+ if (b < 0)
+ return (-1);
+ handle->_ptr += b;
+ handle->_rrnum = rrnum;
+
+ /* Do the parse. */
+ b = dn_expand(handle->_msg, handle->_eom,
+ handle->_ptr, rr->name, NS_MAXDNAME);
+ if (b < 0)
+ return (-1);
+ handle->_ptr += b;
+ if (handle->_ptr + NS_INT16SZ > handle->_eom)
+ goto emsgsize;
+ NS_GET16(rr->type, handle->_ptr);
+ if (handle->_ptr + NS_INT16SZ > handle->_eom)
+ goto emsgsize;
+ NS_GET16(rr->rr_class, handle->_ptr);
+ if (section == ns_s_qd) {
+ rr->ttl = 0;
+ rr->rdlength = 0;
+ rr->rdata = NULL;
+ } else {
+ if (handle->_ptr + NS_INT32SZ > handle->_eom)
+ goto emsgsize;
+ NS_GET32(rr->ttl, handle->_ptr);
+ if (handle->_ptr + NS_INT16SZ > handle->_eom)
+ goto emsgsize;
+ NS_GET16(rr->rdlength, handle->_ptr);
+ if (handle->_ptr + rr->rdlength > handle->_eom)
+ goto emsgsize;
+ rr->rdata = handle->_ptr;
+ handle->_ptr += rr->rdlength;
+ }
+ handle->_rrnum++;
+
+ /* All done. */
+ return (0);
+ enodev:
+ errno = ENODEV;
+ return (-1);
+ emsgsize:
+ errno = EMSGSIZE;
+ return (-1);
+}
diff --git a/cpukit/libnetworking/libc/ns_print.c b/cpukit/libnetworking/libc/ns_print.c
new file mode 100644
index 0000000000..f7d7d16c64
--- /dev/null
+++ b/cpukit/libnetworking/libc/ns_print.c
@@ -0,0 +1,745 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if !defined(__rtems__)
+#if !defined(LINT) && !defined(CODECENTER)
+static char rcsid[] = "$Id$";
+#endif /* not lint */
+#endif /* not rtems */
+
+/* Import. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+#include <ctype.h>
+
+#define SPRINTF(x) ((size_t)sprintf x)
+
+/* Forward. */
+
+static size_t prune_origin(const char *name, const char *origin);
+static int charstr(const u_char *rdata, const u_char *edata,
+ char **buf, size_t *buflen);
+static int addname(const u_char *msg, size_t msglen,
+ const u_char **p, const char *origin,
+ char **buf, size_t *buflen);
+static void addlen(size_t len, char **buf, size_t *buflen);
+static int addstr(const char *src, size_t len,
+ char **buf, size_t *buflen);
+static int addtab(size_t len, size_t target, int spaced,
+ char **buf, size_t *buflen);
+
+/* Macros. */
+
+#define T(x) \
+ do { \
+ if ((x) < 0) \
+ return (-1); \
+ } while (0)
+
+/* Public. */
+
+/*
+ * int
+ * ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen)
+ * Convert an RR to presentation format.
+ * return:
+ * Number of characters written to buf, or -1 (check errno).
+ */
+int
+ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
+ const char *name_ctx, const char *origin,
+ char *buf, size_t buflen)
+{
+ int n;
+
+ n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
+ ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
+ ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
+ name_ctx, origin, buf, buflen);
+ return (n);
+}
+
+/*
+ * int
+ * ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen,
+ * name_ctx, origin, buf, buflen)
+ * Convert the fields of an RR into presentation format.
+ * return:
+ * Number of characters written to buf, or -1 (check errno).
+ */
+int
+ns_sprintrrf(const u_char *msg, size_t msglen,
+ const char *name, ns_class class, ns_type type,
+ u_long ttl, const u_char *rdata, size_t rdlen,
+ const char *name_ctx, const char *origin,
+ char *buf, size_t buflen)
+{
+ const char *obuf = buf;
+ const u_char *edata = rdata + rdlen;
+ int spaced = 0;
+
+ const char *comment;
+ char tmp[100];
+ int len, x;
+
+ /*
+ * Owner.
+ */
+ if (name_ctx != NULL && strcasecmp(name_ctx, name) == 0) {
+ T(addstr("\t\t\t", 3, &buf, &buflen));
+ } else {
+ len = prune_origin(name, origin);
+ if (len == 0) {
+ T(addstr("@\t\t\t", 4, &buf, &buflen));
+ } else {
+ T(addstr(name, len, &buf, &buflen));
+ /* Origin not used and no trailing dot? */
+ if ((!origin || !origin[0] || name[len] == '\0') &&
+ name[len - 1] != '.') {
+ T(addstr(".", 1, &buf, &buflen));
+ len++;
+ }
+ T(spaced = addtab(len, 24, spaced, &buf, &buflen));
+ }
+ }
+
+ /*
+ * TTL, Class, Type.
+ */
+ T(x = ns_format_ttl(ttl, buf, buflen));
+ addlen(x, &buf, &buflen);
+ len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
+ T(addstr(tmp, len, &buf, &buflen));
+ T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
+
+ /*
+ * RData.
+ */
+ switch (type) {
+ case ns_t_a:
+ if (rdlen != NS_INADDRSZ)
+ goto formerr;
+ (void) inet_ntop(AF_INET, rdata, buf, buflen);
+ addlen(strlen(buf), &buf, &buflen);
+ break;
+
+ case ns_t_cname:
+ case ns_t_mb:
+ case ns_t_mg:
+ case ns_t_mr:
+ case ns_t_ns:
+ case ns_t_ptr:
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ break;
+
+ case ns_t_hinfo:
+ case ns_t_isdn:
+ /* First word. */
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Second word. */
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ break;
+
+ case ns_t_soa: {
+ u_long t;
+
+ /* Server name. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Administrator name. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ T(addstr(" (\n", 3, &buf, &buflen));
+ spaced = 0;
+
+ if ((edata - rdata) != 5*NS_INT32SZ)
+ goto formerr;
+
+ /* Serial number. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+ len = SPRINTF((tmp, "%lu", t));
+ T(addstr(tmp, len, &buf, &buflen));
+ T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+ T(addstr("; serial\n", 9, &buf, &buflen));
+ spaced = 0;
+
+ /* Refresh interval. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+ T(len = ns_format_ttl(t, buf, buflen));
+ addlen(len, &buf, &buflen);
+ T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+ T(addstr("; refresh\n", 10, &buf, &buflen));
+ spaced = 0;
+
+ /* Retry interval. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+ T(len = ns_format_ttl(t, buf, buflen));
+ addlen(len, &buf, &buflen);
+ T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+ T(addstr("; retry\n", 8, &buf, &buflen));
+ spaced = 0;
+
+ /* Expiry. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+ T(len = ns_format_ttl(t, buf, buflen));
+ addlen(len, &buf, &buflen);
+ T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+ T(addstr("; expiry\n", 9, &buf, &buflen));
+ spaced = 0;
+
+ /* Minimum TTL. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+ T(len = ns_format_ttl(t, buf, buflen));
+ addlen(len, &buf, &buflen);
+ T(addstr(" )", 2, &buf, &buflen));
+ T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+ T(addstr("; minimum\n", 10, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_mx:
+ case ns_t_afsdb:
+ case ns_t_rt: {
+ u_int t;
+
+ if (rdlen < NS_INT16SZ)
+ goto formerr;
+
+ /* Priority. */
+ t = ns_get16(rdata);
+ rdata += NS_INT16SZ;
+ len = SPRINTF((tmp, "%u ", t));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Target. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_px: {
+ u_int t;
+
+ if (rdlen < NS_INT16SZ)
+ goto formerr;
+
+ /* Priority. */
+ t = ns_get16(rdata);
+ rdata += NS_INT16SZ;
+ len = SPRINTF((tmp, "%u ", t));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Name1. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Name2. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_x25:
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ break;
+
+ case ns_t_txt:
+ while (rdata < edata) {
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ if (rdata < edata)
+ T(addstr(" ", 1, &buf, &buflen));
+ }
+ break;
+
+ case ns_t_nsap: {
+ char t[255*3];
+
+ (void) inet_nsap_ntoa(rdlen, rdata, t);
+ T(addstr(t, strlen(t), &buf, &buflen));
+ break;
+ }
+
+ case ns_t_aaaa:
+ if (rdlen != NS_IN6ADDRSZ)
+ goto formerr;
+ (void) inet_ntop(AF_INET6, rdata, buf, buflen);
+ addlen(strlen(buf), &buf, &buflen);
+ break;
+
+ case ns_t_loc: {
+ char t[255];
+
+ /* XXX protocol format checking? */
+ (void) loc_ntoa(rdata, t);
+ T(addstr(t, strlen(t), &buf, &buflen));
+ break;
+ }
+
+ case ns_t_naptr: {
+ u_int order, preference;
+ char t[50];
+
+ if (rdlen < 2*NS_INT16SZ)
+ goto formerr;
+
+ /* Order, Precedence. */
+ order = ns_get16(rdata); rdata += NS_INT16SZ;
+ preference = ns_get16(rdata); rdata += NS_INT16SZ;
+ len = SPRINTF((t, "%u %u ", order, preference));
+ T(addstr(t, len, &buf, &buflen));
+
+ /* Flags. */
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Service. */
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Regexp. */
+ T(len = charstr(rdata, edata, &buf, &buflen));
+ if (len < 0)
+ return (-1);
+ if (len == 0)
+ goto formerr;
+ rdata += len;
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Server. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ break;
+ }
+
+ case ns_t_srv: {
+ u_int priority, weight, port;
+ char t[50];
+
+ if (rdlen < NS_INT16SZ*3)
+ goto formerr;
+
+ /* Priority, Weight, Port. */
+ priority = ns_get16(rdata); rdata += NS_INT16SZ;
+ weight = ns_get16(rdata); rdata += NS_INT16SZ;
+ port = ns_get16(rdata); rdata += NS_INT16SZ;
+ len = SPRINTF((t, "%u %u %u ", priority, weight, port));
+ T(addstr(t, len, &buf, &buflen));
+
+ /* Server. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ break;
+ }
+
+ case ns_t_minfo:
+ case ns_t_rp:
+ /* Name1. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ T(addstr(" ", 1, &buf, &buflen));
+
+ /* Name2. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+ break;
+
+ case ns_t_wks: {
+ int n, lcnt;
+
+ if (rdlen < NS_INT32SZ + 1)
+ goto formerr;
+
+ /* Address. */
+ (void) inet_ntop(AF_INET, rdata, buf, buflen);
+ addlen(strlen(buf), &buf, &buflen);
+ rdata += NS_INADDRSZ;
+
+ /* Protocol. */
+ len = SPRINTF((tmp, " %u ( ", *rdata));
+ T(addstr(tmp, len, &buf, &buflen));
+ rdata += NS_INT8SZ;
+
+ /* Bit map. */
+ n = 0;
+ lcnt = 0;
+ while (rdata < edata) {
+ u_int c = *rdata++;
+ do {
+ if (c & 0200) {
+ if (lcnt == 0) {
+ T(addstr("\n\t\t\t\t", 5,
+ &buf, &buflen));
+ lcnt = 10;
+ spaced = 0;
+ }
+ len = SPRINTF((tmp, "%d ", n));
+ T(addstr(tmp, len, &buf, &buflen));
+ lcnt--;
+ }
+ c <<= 1;
+ } while (++n & 07);
+ }
+ T(addstr(")", 1, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_key: {
+ char base64_key[NS_MD5RSA_MAX_BASE64];
+ u_int keyflags, protocol, algorithm;
+ const char *leader;
+ int n;
+
+ if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
+ goto formerr;
+
+ /* Key flags, Protocol, Algorithm. */
+ keyflags = ns_get16(rdata); rdata += NS_INT16SZ;
+ protocol = *rdata++;
+ algorithm = *rdata++;
+ len = SPRINTF((tmp, "0x%04x %u %u",
+ keyflags, protocol, algorithm));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Public key data. */
+ len = b64_ntop(rdata, edata - rdata,
+ base64_key, sizeof base64_key);
+ if (len < 0)
+ goto formerr;
+ if (len > 15) {
+ T(addstr(" (", 2, &buf, &buflen));
+ leader = "\n\t\t";
+ spaced = 0;
+ } else
+ leader = " ";
+ for (n = 0; n < len; n += 48) {
+ T(addstr(leader, strlen(leader), &buf, &buflen));
+ T(addstr(base64_key + n, MIN(len - n, 48),
+ &buf, &buflen));
+ }
+ if (len > 15)
+ T(addstr(" )", 2, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_sig: {
+ char base64_key[NS_MD5RSA_MAX_BASE64];
+ u_int type, algorithm, labels, footprint;
+ const char *leader;
+ u_long t;
+ int n;
+
+ if (rdlen < 22)
+ goto formerr;
+
+ /* Type covered, Algorithm, Label count, Original TTL. */
+ type = ns_get16(rdata); rdata += NS_INT16SZ;
+ algorithm = *rdata++;
+ labels = *rdata++;
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ len = SPRINTF((tmp, " %s %d %lu ",
+ p_type(type), algorithm, t));
+ T(addstr(tmp, len, &buf, &buflen));
+ if (labels != (u_int)dn_count_labels(name))
+ goto formerr;
+
+ /* Signature expiry. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Time signed. */
+ t = ns_get32(rdata); rdata += NS_INT32SZ;
+ len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Signature Footprint. */
+ footprint = ns_get16(rdata); rdata += NS_INT16SZ;
+ len = SPRINTF((tmp, "%u ", footprint));
+ T(addstr(tmp, len, &buf, &buflen));
+
+ /* Signer's name. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+ /* Signature. */
+ len = b64_ntop(rdata, edata - rdata,
+ base64_key, sizeof base64_key);
+ if (len > 15) {
+ T(addstr(" (", 2, &buf, &buflen));
+ leader = "\n\t\t";
+ spaced = 0;
+ } else
+ leader = " ";
+ if (len < 0)
+ goto formerr;
+ for (n = 0; n < len; n += 48) {
+ T(addstr(leader, strlen(leader), &buf, &buflen));
+ T(addstr(base64_key + n, MIN(len - n, 48),
+ &buf, &buflen));
+ }
+ if (len > 15)
+ T(addstr(" )", 2, &buf, &buflen));
+
+ break;
+ }
+
+ case ns_t_nxt: {
+ int n, c;
+
+ /* Next domain name. */
+ T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+ /* Type bit map. */
+ n = edata - rdata;
+ for (c = 0; c < n*8; c++)
+ if (NS_NXT_BIT_ISSET(c, rdata)) {
+ len = SPRINTF((tmp, " %s", p_type(c)));
+ T(addstr(tmp, len, &buf, &buflen));
+ }
+ break;
+ }
+
+ default:
+ comment = "unknown RR type";
+ goto hexify;
+ }
+ return (buf - obuf);
+ formerr:
+ comment = "RR format error";
+ hexify: {
+ int n, m;
+ char *p;
+
+ len = SPRINTF((tmp, "\\#(\t\t; %s", comment));
+ T(addstr(tmp, len, &buf, &buflen));
+ while (rdata < edata) {
+ p = tmp;
+ p += SPRINTF((p, "\n\t"));
+ spaced = 0;
+ n = MIN(16, edata - rdata);
+ for (m = 0; m < n; m++)
+ p += SPRINTF((p, "%02x ", rdata[m]));
+ T(addstr(tmp, p - tmp, &buf, &buflen));
+ if (n < 16) {
+ T(addstr(")", 1, &buf, &buflen));
+ T(addtab(p - tmp + 1, 48, spaced, &buf, &buflen));
+ }
+ p = tmp;
+ p += SPRINTF((p, "; "));
+ for (m = 0; m < n; m++)
+ *p++ = (isascii(rdata[m]) && isprint(rdata[m]))
+ ? rdata[m]
+ : '.';
+ T(addstr(tmp, p - tmp, &buf, &buflen));
+ rdata += n;
+ }
+ return (buf - obuf);
+ }
+}
+
+/* Private. */
+
+/*
+ * size_t
+ * prune_origin(name, origin)
+ * Find out if the name is at or under the current origin.
+ * return:
+ * Number of characters in name before start of origin,
+ * or length of name if origin does not match.
+ * notes:
+ * This function should share code with samedomain().
+ */
+static size_t
+prune_origin(const char *name, const char *origin) {
+ const char *oname = name;
+
+ while (*name != '\0') {
+ if (origin != NULL && strcasecmp(name, origin) == 0)
+ return (name - oname - (name > oname));
+ while (*name != '\0') {
+ if (*name == '\\') {
+ name++;
+ /* XXX need to handle \nnn form. */
+ if (*name == '\0')
+ break;
+ } else if (*name == '.') {
+ name++;
+ break;
+ }
+ name++;
+ }
+ }
+ return (name - oname);
+}
+
+/*
+ * int
+ * charstr(rdata, edata, buf, buflen)
+ * Format a <character-string> into the presentation buffer.
+ * return:
+ * Number of rdata octets consumed
+ * 0 for protocol format error
+ * -1 for output buffer error
+ * side effects:
+ * buffer is advanced on success.
+ */
+static int
+charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
+ const u_char *odata = rdata;
+ size_t save_buflen = *buflen;
+ char *save_buf = *buf;
+
+ if (addstr("\"", 1, buf, buflen) < 0)
+ goto enospc;
+ if (rdata < edata) {
+ int n = *rdata;
+
+ if (rdata + 1 + n <= edata) {
+ rdata++;
+ while (n-- > 0) {
+ if (strchr("\n\"\\", *rdata) != NULL)
+ if (addstr("\\", 1, buf, buflen) < 0)
+ goto enospc;
+ if (addstr((const char *)rdata, 1,
+ buf, buflen) < 0)
+ goto enospc;
+ rdata++;
+ }
+ }
+ }
+ if (addstr("\"", 1, buf, buflen) < 0)
+ goto enospc;
+ return (rdata - odata);
+ enospc:
+ errno = ENOSPC;
+ *buf = save_buf;
+ *buflen = save_buflen;
+ return (-1);
+}
+
+static int
+addname(const u_char *msg, size_t msglen,
+ const u_char **pp, const char *origin,
+ char **buf, size_t *buflen)
+{
+ size_t newlen, save_buflen = *buflen;
+ char *save_buf = *buf;
+ int n;
+
+ n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen);
+ if (n < 0)
+ goto enospc; /* Guess. */
+ newlen = prune_origin(*buf, origin);
+ if ((origin == NULL || origin[0] == '\0' || (*buf)[newlen] == '\0') &&
+ (newlen == 0 || (*buf)[newlen - 1] != '.')) {
+ /* No trailing dot. */
+ if (newlen + 2 > *buflen)
+ goto enospc; /* No room for ".\0". */
+ (*buf)[newlen++] = '.';
+ (*buf)[newlen] = '\0';
+ }
+ if (newlen == 0) {
+ /* Use "@" instead of name. */
+ if (newlen + 2 > *buflen)
+ goto enospc; /* No room for "@\0". */
+ (*buf)[newlen++] = '@';
+ (*buf)[newlen] = '\0';
+ }
+ *pp += n;
+ addlen(newlen, buf, buflen);
+ **buf = '\0';
+ return (newlen);
+ enospc:
+ errno = ENOSPC;
+ *buf = save_buf;
+ *buflen = save_buflen;
+ return (-1);
+}
+
+static void
+addlen(size_t len, char **buf, size_t *buflen) {
+ assert(len <= *buflen);
+ *buf += len;
+ *buflen -= len;
+}
+
+static int
+addstr(const char *src, size_t len, char **buf, size_t *buflen) {
+ if (len > *buflen) {
+ errno = ENOSPC;
+ return (-1);
+ }
+ memcpy(*buf, src, len);
+ addlen(len, buf, buflen);
+ **buf = '\0';
+ return (0);
+}
+
+static int
+addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
+ size_t save_buflen = *buflen;
+ char *save_buf = *buf;
+ int t;
+
+ if (spaced || len >= target - 1) {
+ T(addstr(" ", 2, buf, buflen));
+ spaced = 1;
+ } else {
+ for (t = (target - len - 1) / 8; t >= 0; t--)
+ if (addstr("\t", 1, buf, buflen) < 0) {
+ *buflen = save_buflen;
+ *buf = save_buf;
+ return (-1);
+ }
+ spaced = 0;
+ }
+ return (spaced);
+}
diff --git a/cpukit/libnetworking/libc/ns_ttl.c b/cpukit/libnetworking/libc/ns_ttl.c
new file mode 100644
index 0000000000..75093c1dbc
--- /dev/null
+++ b/cpukit/libnetworking/libc/ns_ttl.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if !defined(__rtems__)
+#if !defined(LINT) && !defined(CODECENTER)
+static char rcsid[] = "$Id$";
+#endif /* not lint */
+#endif /* not rtems */
+
+/* Import. */
+
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#define SPRINTF(x) ((size_t)sprintf x)
+
+/* Forward. */
+
+static int fmt1(int t, char s, char **buf, size_t *buflen);
+
+/* Macros. */
+
+#define T(x) if ((x) < 0) return (-1); else (void)NULL
+
+/* Public. */
+
+int
+ns_format_ttl(u_long src, char *dst, size_t dstlen) {
+ char *odst = dst;
+ int secs, mins, hours, days, weeks, x;
+ char *p;
+
+ secs = src % 60; src /= 60;
+ mins = src % 60; src /= 60;
+ hours = src % 24; src /= 24;
+ days = src % 7; src /= 7;
+ weeks = src; src = 0;
+
+ x = 0;
+ if (weeks) {
+ T(fmt1(weeks, 'W', &dst, &dstlen));
+ x++;
+ }
+ if (days) {
+ T(fmt1(days, 'D', &dst, &dstlen));
+ x++;
+ }
+ if (hours) {
+ T(fmt1(hours, 'H', &dst, &dstlen));
+ x++;
+ }
+ if (mins) {
+ T(fmt1(mins, 'M', &dst, &dstlen));
+ x++;
+ }
+ if (secs || !(weeks || days || hours || mins)) {
+ T(fmt1(secs, 'S', &dst, &dstlen));
+ x++;
+ }
+
+ if (x > 1) {
+ int ch;
+
+ for (p = odst; (ch = *p) != '\0'; p++)
+ if (isascii(ch) && isupper(ch))
+ *p = tolower(ch);
+ }
+
+ return (dst - odst);
+}
+
+int
+ns_parse_ttl(const char *src, u_long *dst) {
+ u_long ttl, tmp;
+ int ch, digits, dirty;
+
+ ttl = 0;
+ tmp = 0;
+ digits = 0;
+ dirty = 0;
+ while ((ch = *src++) != '\0') {
+ if (!isascii(ch) || !isprint(ch))
+ goto einval;
+ if (isdigit(ch)) {
+ tmp *= 10;
+ tmp += (ch - '0');
+ digits++;
+ continue;
+ }
+ if (digits == 0)
+ goto einval;
+ if (islower(ch))
+ ch = toupper(ch);
+ switch (ch) {
+ case 'W': tmp *= 7;
+ case 'D': tmp *= 24;
+ case 'H': tmp *= 60;
+ case 'M': tmp *= 60;
+ case 'S': break;
+ default: goto einval;
+ }
+ ttl += tmp;
+ tmp = 0;
+ digits = 0;
+ dirty = 1;
+ }
+ if (digits > 0) {
+ if (dirty)
+ goto einval;
+ else
+ ttl += tmp;
+ }
+ *dst = ttl;
+ return (0);
+
+ einval:
+ errno = EINVAL;
+ return (-1);
+}
+
+/* Private. */
+
+static int
+fmt1(int t, char s, char **buf, size_t *buflen) {
+ char tmp[50];
+ size_t len;
+
+ len = SPRINTF((tmp, "%d%c", t, s));
+ if (len + 1 > *buflen)
+ return (-1);
+ strcpy(*buf, tmp);
+ *buf += len;
+ *buflen -= len;
+ return (0);
+}
diff --git a/cpukit/libnetworking/libc/nsap_addr.c b/cpukit/libnetworking/libc/nsap_addr.c
new file mode 100644
index 0000000000..a7af57a266
--- /dev/null
+++ b/cpukit/libnetworking/libc/nsap_addr.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <resolv.h>
+
+static char
+xtob(c)
+ register int c;
+{
+ return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
+}
+
+u_int
+inet_nsap_addr(ascii, binary, maxlen)
+ const char *ascii;
+ u_char *binary;
+ int maxlen;
+{
+ u_char c, nib;
+ u_int len = 0;
+
+ while ((c = *ascii++) != '\0' && len < (u_int)maxlen) {
+ if (c == '.' || c == '+' || c == '/')
+ continue;
+ if (!isascii(c))
+ return (0);
+ if (islower(c))
+ c = toupper(c);
+ if (isxdigit(c)) {
+ nib = xtob(c);
+ c = *ascii++;
+ if (c != '\0') {
+ c = toupper(c);
+ if (isxdigit(c)) {
+ *binary++ = (nib << 4) | xtob(c);
+ len++;
+ } else
+ return (0);
+ }
+ else
+ return (0);
+ }
+ else
+ return (0);
+ }
+ return (len);
+}
+
+char *
+inet_nsap_ntoa(binlen, binary, ascii)
+ int binlen;
+ register const u_char *binary;
+ register char *ascii;
+{
+ register int nib;
+ int i;
+ static char tmpbuf[255*3];
+ char *start;
+
+ if (ascii)
+ start = ascii;
+ else {
+ ascii = tmpbuf;
+ start = tmpbuf;
+ }
+
+ if (binlen > 255)
+ binlen = 255;
+
+ for (i = 0; i < binlen; i++) {
+ nib = *binary >> 4;
+ *ascii++ = nib + (nib < 10 ? '0' : '7');
+ nib = *binary++ & 0x0f;
+ *ascii++ = nib + (nib < 10 ? '0' : '7');
+ if (((i % 2) == 0 && (i + 1) < binlen))
+ *ascii++ = '.';
+ }
+ *ascii = '\0';
+ return (start);
+}
diff --git a/cpukit/libnetworking/libc/rcmd.3 b/cpukit/libnetworking/libc/rcmd.3
new file mode 100644
index 0000000000..e25057fa4e
--- /dev/null
+++ b/cpukit/libnetworking/libc/rcmd.3
@@ -0,0 +1,204 @@
+.\" Copyright (c) 1983, 1991, 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.
+.\"
+.\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93
+.\" $Id$
+.\"
+.Dd February 15, 1996
+.Dt RCMD 3
+.Os BSD 4.2
+.Sh NAME
+.Nm rcmd ,
+.Nm rresvport ,
+.Nm iruserok ,
+.Nm ruserok
+.Nd routines for returning a stream to a remote command
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft int
+.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p"
+.Ft int
+.Fn rresvport "int *port"
+.Ft int
+.Fn iruserok "u_long raddr" "int superuser" "const char *ruser" "const char *luser"
+.Ft int
+.Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser"
+.Sh DESCRIPTION
+The
+.Fn rcmd
+function
+is used by the super-user to execute a command on
+a remote machine using an authentication scheme based
+on reserved port numbers.
+The
+.Fn rresvport
+function
+returns a descriptor to a socket
+with an address in the privileged port space.
+The
+.Fn ruserok
+function
+is used by servers
+to authenticate clients requesting service with
+.Fn rcmd .
+All three functions are present in the same file and are used
+by the
+.Xr rshd 8
+server (among others).
+.Pp
+The
+.Fn rcmd
+function
+looks up the host
+.Fa *ahost
+using
+.Xr gethostbyname 3 ,
+returning \-1 if the host does not exist.
+Otherwise
+.Fa *ahost
+is set to the standard name of the host
+and a connection is established to a server
+residing at the well-known Internet port
+.Fa inport .
+.Pp
+If the connection succeeds,
+a socket in the Internet domain of type
+.Dv SOCK_STREAM
+is returned to the caller, and given to the remote
+command as
+.Em stdin
+and
+.Em stdout .
+If
+.Fa fd2p
+is non-zero, then an auxiliary channel to a control
+process will be set up, and a descriptor for it will be placed
+in
+.Fa *fd2p .
+The control process will return diagnostic
+output from the command (unit 2) on this channel, and will also
+accept bytes on this channel as being
+.Tn UNIX
+signal numbers, to be
+forwarded to the process group of the command.
+If
+.Fa fd2p
+is 0, then the
+.Em stderr
+(unit 2 of the remote
+command) will be made the same as the
+.Em stdout
+and no
+provision is made for sending arbitrary signals to the remote process,
+although you may be able to get its attention by using out-of-band data.
+.Pp
+The protocol is described in detail in
+.Xr rshd 8 .
+.Pp
+The
+.Fn rresvport
+function is used to obtain a socket with a privileged
+address bound to it. This socket is suitable for use
+by
+.Fn rcmd
+and several other functions. Privileged Internet ports are those
+in the range 0 to 1023. Only the super-user
+is allowed to bind an address of this sort to a socket.
+.Pp
+The
+.Fn iruserok
+and
+.Fn ruserok
+functions take a remote host's IP address or name, as returned by the
+.Xr gethostbyname 3
+routines, two user names and a flag indicating whether the local user's
+name is that of the super-user.
+Then, if the user is
+.Em NOT
+the super-user, it checks the
+.Pa /etc/hosts.equiv
+file.
+If that lookup is not done, or is unsuccessful, the
+.Pa .rhosts
+in the local user's home directory is checked to see if the request for
+service is allowed.
+.Pp
+If this file does not exist, is not a regular file, is owned by anyone
+other than the user or the super-user, or is writable by anyone other
+than the owner, the check automatically fails.
+Zero is returned if the machine name is listed in the
+.Dq Pa hosts.equiv
+file, or the host and remote user name are found in the
+.Dq Pa .rhosts
+file; otherwise
+.Fn iruserok
+and
+.Fn ruserok
+return \-1.
+If the local domain (as obtained from
+.Xr gethostname 3 )
+is the same as the remote domain, only the machine name need be specified.
+.Pp
+The
+.Fn iruserok
+function is strongly preferred for security reasons.
+It requires trusting the local DNS at most, while the
+.Fn ruserok
+function requires trusting the entire DNS, which can be spoofed.
+.Sh DIAGNOSTICS
+The
+.Fn rcmd
+function
+returns a valid socket descriptor on success.
+It returns \-1 on error and prints a diagnostic message on the standard error.
+.Pp
+The
+.Fn rresvport
+function
+returns a valid, bound socket descriptor on success.
+It returns \-1 on error with the global value
+.Va errno
+set according to the reason for failure.
+The error code
+.Dv EAGAIN
+is overloaded to mean ``All network ports in use.''
+.Sh SEE ALSO
+.Xr rlogin 1 ,
+.Xr rsh 1 ,
+.Xr intro 2 ,
+.Xr rexec 3 ,
+.Xr rexecd 8 ,
+.Xr rlogind 8 ,
+.Xr rshd 8
+.Sh HISTORY
+These
+functions appeared in
+.Bx 4.2 .
diff --git a/cpukit/libnetworking/libc/rcmd.c b/cpukit/libnetworking/libc/rcmd.c
new file mode 100644
index 0000000000..542da3f21a
--- /dev/null
+++ b/cpukit/libnetworking/libc/rcmd.c
@@ -0,0 +1,547 @@
+/*
+ * Copyright (c) 1983, 1993, 1994
+ * 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <signal.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+
+#include <sys/select.h>
+
+
+#define max(a, b) ((a > b) ? a : b)
+
+#ifdef __rtems__
+int rresvport();
+#define bzero(a,s) memset((a),0,(s))
+#define bcmp memcmp
+#define bcopy(s,d,i) memcpy(d,s,i)
+int bindresvport(int, struct sockaddr_in *);
+#else /* __rtems__ */
+
+extern int innetgr __P(( const char *, const char *, const char *, const char * ));
+
+int __ivaliduser __P((FILE *, u_long, const char *, const char *));
+static int __icheckhost __P((u_long, char *));
+
+#endif
+
+int
+rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
+ char **ahost;
+ u_short rport;
+ const char *locuser, *remuser, *cmd;
+ int *fd2p;
+{
+ struct hostent *hp;
+ struct sockaddr_in sin, from;
+ fd_set reads;
+#ifndef __rtems__
+ long oldmask;
+#endif
+ pid_t pid;
+ int s, lport, timo;
+ char c;
+
+ pid = getpid();
+ hp = gethostbyname(*ahost);
+ if (hp == NULL) {
+ herror(*ahost);
+ return (-1);
+ }
+ *ahost = hp->h_name;
+#ifndef __rtems__
+ oldmask = sigblock(sigmask(SIGURG));
+#endif
+ for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
+ s = rresvport(&lport);
+ if (s < 0) {
+ if (errno == EAGAIN)
+ (void)fprintf(stderr,
+ "rcmd: socket: All ports in use\n");
+ else
+ (void)fprintf(stderr, "rcmd: socket: %s\n",
+ strerror(errno));
+#ifndef __rtems__
+ sigsetmask(oldmask);
+#endif
+ return (-1);
+ }
+ fcntl(s, F_SETOWN, pid);
+ bzero(&sin, sizeof sin);
+ sin.sin_len = sizeof(struct sockaddr_in);
+ sin.sin_family = hp->h_addrtype;
+ sin.sin_port = rport;
+ bcopy(hp->h_addr_list[0], &sin.sin_addr, MIN(hp->h_length, sizeof sin.sin_addr));
+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+ break;
+ (void)close(s);
+ if (errno == EADDRINUSE) {
+ lport--;
+ continue;
+ }
+ if (errno == ECONNREFUSED && timo <= 16) {
+ (void)sleep(timo);
+ timo *= 2;
+ continue;
+ }
+ if (hp->h_addr_list[1] != NULL) {
+ int oerrno = errno;
+
+ (void)fprintf(stderr, "connect to address %s: ",
+ inet_ntoa(sin.sin_addr));
+ errno = oerrno;
+ perror(0);
+ hp->h_addr_list++;
+ bcopy(hp->h_addr_list[0], &sin.sin_addr, MIN(hp->h_length, sizeof sin.sin_addr));
+ (void)fprintf(stderr, "Trying %s...\n",
+ inet_ntoa(sin.sin_addr));
+ continue;
+ }
+ (void)fprintf(stderr, "%s: %s\n", hp->h_name, strerror(errno));
+#ifndef __rtems__
+ sigsetmask(oldmask);
+#endif
+ return (-1);
+ }
+ lport--;
+ if (fd2p == 0) {
+ write(s, "", 1);
+ lport = 0;
+ } else {
+ char num[8];
+ int s2 = rresvport(&lport), s3;
+ socklen_t len = sizeof(from);
+ int nfds;
+
+ if (s2 < 0)
+ goto bad;
+ listen(s2, 1);
+ (void)snprintf(num, sizeof(num), "%d", lport);
+ if (write(s, num, strlen(num)+1) != strlen(num)+1) {
+ (void)fprintf(stderr,
+ "rcmd: write (setting up stderr): %s\n",
+ strerror(errno));
+ (void)close(s2);
+ goto bad;
+ }
+ nfds = max(s, s2)+1;
+ if(nfds > FD_SETSIZE) {
+ fprintf(stderr, "rcmd: too many files\n");
+ (void)close(s2);
+ goto bad;
+ }
+again:
+ FD_ZERO(&reads);
+ FD_SET(s, &reads);
+ FD_SET(s2, &reads);
+ errno = 0;
+ if (select(nfds, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)){
+ if (errno != 0)
+ (void)fprintf(stderr,
+ "rcmd: select (setting up stderr): %s\n",
+ strerror(errno));
+ else
+ (void)fprintf(stderr,
+ "select: protocol failure in circuit setup\n");
+ (void)close(s2);
+ goto bad;
+ }
+ s3 = accept(s2, (struct sockaddr *)&from, &len);
+ /*
+ * XXX careful for ftp bounce attacks. If discovered, shut them
+ * down and check for the real auxiliary channel to connect.
+ */
+ if (from.sin_family == AF_INET && from.sin_port == htons(20)) {
+ close(s3);
+ goto again;
+ }
+ (void)close(s2);
+ if (s3 < 0) {
+ (void)fprintf(stderr,
+ "rcmd: accept: %s\n", strerror(errno));
+ lport = 0;
+ goto bad;
+ }
+ *fd2p = s3;
+ from.sin_port = ntohs((u_short)from.sin_port);
+ if (from.sin_family != AF_INET ||
+ from.sin_port >= IPPORT_RESERVED ||
+ from.sin_port < IPPORT_RESERVED / 2) {
+ (void)fprintf(stderr,
+ "socket: protocol failure in circuit setup.\n");
+ goto bad2;
+ }
+ }
+ (void)write(s, locuser, strlen(locuser)+1);
+ (void)write(s, remuser, strlen(remuser)+1);
+ (void)write(s, cmd, strlen(cmd)+1);
+ if (read(s, &c, 1) != 1) {
+ (void)fprintf(stderr,
+ "rcmd: %s: %s\n", *ahost, strerror(errno));
+ goto bad2;
+ }
+ if (c != 0) {
+ while (read(s, &c, 1) == 1) {
+ (void)write(STDERR_FILENO, &c, 1);
+ if (c == '\n')
+ break;
+ }
+ goto bad2;
+ }
+#ifndef __rtems__
+ sigsetmask(oldmask);
+#endif
+ return (s);
+bad2:
+ if (lport)
+ (void)close(*fd2p);
+bad:
+ (void)close(s);
+#ifndef __rtems__
+ sigsetmask(oldmask);
+#endif
+ return (-1);
+}
+
+int
+rresvport(alport)
+ int *alport;
+{
+ struct sockaddr_in sin;
+ int s;
+
+ bzero(&sin, sizeof sin);
+ sin.sin_len = sizeof(struct sockaddr_in);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0)
+ return (-1);
+#if 0 /* compat_exact_traditional_rresvport_semantics */
+ sin.sin_port = htons((u_short)*alport);
+ if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+ return (s);
+ if (errno != EADDRINUSE) {
+ (void)close(s);
+ return (-1);
+ }
+#endif
+ sin.sin_port = 0;
+ if (bindresvport(s, &sin) == -1) {
+ (void)close(s);
+ return (-1);
+ }
+ *alport = (int)ntohs(sin.sin_port);
+ return (s);
+}
+
+#ifndef __rtems__
+int __check_rhosts_file = 1;
+char *__rcmd_errstr;
+
+int
+ruserok(rhost, superuser, ruser, luser)
+ const char *rhost, *ruser, *luser;
+ int superuser;
+{
+ struct hostent *hp;
+ u_long addr;
+ char **ap;
+
+ if ((hp = gethostbyname(rhost)) == NULL)
+ return (-1);
+ for (ap = hp->h_addr_list; *ap; ++ap) {
+ bcopy(*ap, &addr, sizeof(addr));
+ if (iruserok(addr, superuser, ruser, luser) == 0)
+ return (0);
+ }
+ return (-1);
+}
+
+/*
+ * New .rhosts strategy: We are passed an ip address. We spin through
+ * hosts.equiv and .rhosts looking for a match. When the .rhosts only
+ * has ip addresses, we don't have to trust a nameserver. When it
+ * contains hostnames, we spin through the list of addresses the nameserver
+ * gives us and look for a match.
+ *
+ * Returns 0 if ok, -1 if not ok.
+ */
+int
+iruserok(raddr, superuser, ruser, luser)
+ u_long raddr;
+ int superuser;
+ const char *ruser, *luser;
+{
+ register char *cp;
+ struct stat sbuf;
+ struct passwd *pwd;
+ FILE *hostf;
+ uid_t uid;
+ int first;
+ char pbuf[MAXPATHLEN];
+
+ first = 1;
+ hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r");
+again:
+ if (hostf) {
+ if (__ivaliduser(hostf, raddr, luser, ruser) == 0) {
+ (void)fclose(hostf);
+ return (0);
+ }
+ (void)fclose(hostf);
+ }
+ if (first == 1 && (__check_rhosts_file || superuser)) {
+ first = 0;
+ if ((pwd = getpwnam(luser)) == NULL)
+ return (-1);
+ (void)strcpy(pbuf, pwd->pw_dir);
+ (void)strcat(pbuf, "/.rhosts");
+
+ /*
+ * Change effective uid while opening .rhosts. If root and
+ * reading an NFS mounted file system, can't read files that
+ * are protected read/write owner only.
+ */
+ uid = geteuid();
+ (void)seteuid(pwd->pw_uid);
+ hostf = fopen(pbuf, "r");
+ (void)seteuid(uid);
+
+ if (hostf == NULL)
+ return (-1);
+ /*
+ * If not a regular file, or is owned by someone other than
+ * user or root or if writeable by anyone but the owner, quit.
+ */
+ cp = NULL;
+ if (lstat(pbuf, &sbuf) < 0)
+ cp = ".rhosts lstat failed";
+ else if (!S_ISREG(sbuf.st_mode))
+ cp = ".rhosts not regular file";
+ else if (fstat(fileno(hostf), &sbuf) < 0)
+ cp = ".rhosts fstat failed";
+ else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
+ cp = "bad .rhosts owner";
+ else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
+ cp = ".rhosts writeable by other than owner";
+ /* If there were any problems, quit. */
+ if (cp) {
+ __rcmd_errstr = cp;
+ (void)fclose(hostf);
+ return (-1);
+ }
+ goto again;
+ }
+ return (-1);
+}
+
+/*
+ * XXX
+ * Don't make static, used by lpd(8).
+ *
+ * Returns 0 if ok, -1 if not ok.
+ */
+int
+__ivaliduser(hostf, raddr, luser, ruser)
+ FILE *hostf;
+ u_long raddr;
+ const char *luser, *ruser;
+{
+ register char *user, *p;
+ int ch;
+ char buf[MAXHOSTNAMELEN + 128]; /* host + login */
+ char hname[MAXHOSTNAMELEN];
+ struct hostent *hp;
+ /* Presumed guilty until proven innocent. */
+ int userok = 0, hostok = 0;
+#ifdef YP
+ char *ypdomain;
+
+ if (yp_get_default_domain(&ypdomain))
+ ypdomain = NULL;
+#else
+#define ypdomain NULL
+#endif
+ /* We need to get the damn hostname back for netgroup matching. */
+ if ((hp = gethostbyaddr((char *)&raddr, sizeof(u_long),
+ AF_INET)) == NULL)
+ return (-1);
+ strncpy(hname, hp->h_name, sizeof(hname));
+ hname[sizeof(hname) - 1] = '\0';
+
+ while (fgets(buf, sizeof(buf), hostf)) {
+ p = buf;
+ /* Skip lines that are too long. */
+ if (strchr(p, '\n') == NULL) {
+ while ((ch = getc(hostf)) != '\n' && ch != EOF);
+ continue;
+ }
+ if (*p == '\n' || *p == '#') {
+ /* comment... */
+ continue;
+ }
+ while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
+ *p = isupper(*p) ? tolower(*p) : *p;
+ p++;
+ }
+ if (*p == ' ' || *p == '\t') {
+ *p++ = '\0';
+ while (*p == ' ' || *p == '\t')
+ p++;
+ user = p;
+ while (*p != '\n' && *p != ' ' &&
+ *p != '\t' && *p != '\0')
+ p++;
+ } else
+ user = p;
+ *p = '\0';
+ /*
+ * Do +/- and +@/-@ checking. This looks really nasty,
+ * but it matches SunOS's behavior so far as I can tell.
+ */
+ switch(buf[0]) {
+ case '+':
+ if (!buf[1]) { /* '+' matches all hosts */
+ hostok = 1;
+ break;
+ }
+ if (buf[1] == '@') /* match a host by netgroup */
+ hostok = innetgr((char *)&buf[2],
+ (char *)&hname, NULL, ypdomain);
+ else /* match a host by addr */
+ hostok = __icheckhost(raddr,(char *)&buf[1]);
+ break;
+ case '-': /* reject '-' hosts and all their users */
+ if (buf[1] == '@') {
+ if (innetgr((char *)&buf[2],
+ (char *)&hname, NULL, ypdomain))
+ return(-1);
+ } else {
+ if (__icheckhost(raddr,(char *)&buf[1]))
+ return(-1);
+ }
+ break;
+ default: /* if no '+' or '-', do a simple match */
+ hostok = __icheckhost(raddr, buf);
+ break;
+ }
+ switch(*user) {
+ case '+':
+ if (!*(user+1)) { /* '+' matches all users */
+ userok = 1;
+ break;
+ }
+ if (*(user+1) == '@') /* match a user by netgroup */
+ userok = innetgr(user+2, NULL, ruser, ypdomain);
+ else /* match a user by direct specification */
+ userok = !(strcmp(ruser, user+1));
+ break;
+ case '-': /* if we matched a hostname, */
+ if (hostok) { /* check for user field rejections */
+ if (!*(user+1))
+ return(-1);
+ if (*(user+1) == '@') {
+ if (innetgr(user+2, NULL,
+ ruser, ypdomain))
+ return(-1);
+ } else {
+ if (!strcmp(ruser, user+1))
+ return(-1);
+ }
+ }
+ break;
+ default: /* no rejections: try to match the user */
+ if (hostok)
+ userok = !(strcmp(ruser,*user ? user : luser));
+ break;
+ }
+ if (hostok && userok)
+ return(0);
+ }
+ return (-1);
+}
+
+/*
+ * Returns "true" if match, 0 if no match.
+ */
+static int
+__icheckhost(raddr, lhost)
+ u_long raddr;
+ register char *lhost;
+{
+ register struct hostent *hp;
+ register u_long laddr;
+ register char **pp;
+
+ /* Try for raw ip address first. */
+ if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1)
+ return (raddr == laddr);
+
+ /* Better be a hostname. */
+ if ((hp = gethostbyname(lhost)) == NULL)
+ return (0);
+
+ /* Spin through ip addresses. */
+ for (pp = hp->h_addr_list; *pp; ++pp)
+ if (!bcmp(&raddr, *pp, sizeof(u_long)))
+ return (1);
+
+ /* No match. */
+ return (0);
+}
+#endif
diff --git a/cpukit/libnetworking/libc/recv.c b/cpukit/libnetworking/libc/recv.c
new file mode 100644
index 0000000000..a842244caf
--- /dev/null
+++ b/cpukit/libnetworking/libc/recv.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1988, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)recv.c 8.2 (Berkeley) 2/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <stddef.h>
+
+ssize_t
+recv(s, buf, len, flags)
+ int s, flags;
+ size_t len;
+ void *buf;
+{
+ return (recvfrom(s, buf, len, flags, NULL, 0));
+}
diff --git a/cpukit/libnetworking/libc/res_comp.c b/cpukit/libnetworking/libc/res_comp.c
new file mode 100644
index 0000000000..93043276f2
--- /dev/null
+++ b/cpukit/libnetworking/libc/res_comp.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 1985, 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.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
+static char orig_rcsid[] = "From: Id: res_comp.c,v 8.11 1997/05/21 19:31:04 halley Exp $";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#define BIND_4_COMPAT
+
+/*
+ * Expand compressed domain name 'comp_dn' to full domain name.
+ * 'msg' is a pointer to the begining of the message,
+ * 'eomorig' points to the first location after the message,
+ * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
+ * Return size of compressed name or -1 if there was an error.
+ */
+int
+dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
+ char *dst, int dstsiz)
+{
+ int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
+
+ if (n > 0 && dst[0] == '.')
+ dst[0] = '\0';
+ return (n);
+}
+
+/*
+ * Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
+ * Return the size of the compressed name or -1.
+ * 'length' is the size of the array pointed to by 'comp_dn'.
+ */
+int
+dn_comp(const char *src, u_char *dst, int dstsiz,
+ u_char **dnptrs, u_char **lastdnptr)
+{
+ return (ns_name_compress(src, dst, (size_t)dstsiz,
+ (const u_char **)dnptrs,
+ (const u_char **)lastdnptr));
+}
+
+/*
+ * Skip over a compressed domain name. Return the size or -1.
+ */
+int
+dn_skipname(const u_char *ptr, const u_char *eom) {
+ const u_char *saveptr = ptr;
+
+ if (ns_name_skip(&ptr, eom) == -1)
+ return (-1);
+ return (ptr - saveptr);
+}
+
+/*
+ * Verify that a domain name uses an acceptable character set.
+ */
+
+/*
+ * Note the conspicuous absence of ctype macros in these definitions. On
+ * non-ASCII hosts, we can't depend on string literals or ctype macros to
+ * tell us anything about network-format data. The rest of the BIND system
+ * is not careful about this, but for some reason, we're doing it right here.
+ */
+#define PERIOD 0x2e
+#define hyphenchar(c) ((c) == 0x2d)
+#define bslashchar(c) ((c) == 0x5c)
+#define periodchar(c) ((c) == PERIOD)
+#define asterchar(c) ((c) == 0x2a)
+#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
+ || ((c) >= 0x61 && (c) <= 0x7a))
+#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
+
+#define borderchar(c) (alphachar(c) || digitchar(c))
+#define middlechar(c) (borderchar(c) || hyphenchar(c))
+#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
+
+int
+res_hnok(dn)
+ const char *dn;
+{
+ int ppch = '\0', pch = PERIOD, ch = *dn++;
+
+ while (ch != '\0') {
+ int nch = *dn++;
+
+ if (periodchar(ch)) {
+ (void)NULL;
+ } else if (periodchar(pch)) {
+ if (!borderchar(ch))
+ return (0);
+ } else if (periodchar(nch) || nch == '\0') {
+ if (!borderchar(ch))
+ return (0);
+ } else {
+ if (!middlechar(ch))
+ return (0);
+ }
+ ppch = pch, pch = ch, ch = nch;
+ }
+ return (1);
+}
+
+/*
+ * hostname-like (A, MX, WKS) owners can have "*" as their first label
+ * but must otherwise be as a host name.
+ */
+int
+res_ownok(dn)
+ const char *dn;
+{
+ if (asterchar(dn[0])) {
+ if (periodchar(dn[1]))
+ return (res_hnok(dn+2));
+ if (dn[1] == '\0')
+ return (1);
+ }
+ return (res_hnok(dn));
+}
+
+/*
+ * SOA RNAMEs and RP RNAMEs can have any printable character in their first
+ * label, but the rest of the name has to look like a host name.
+ */
+int
+res_mailok(dn)
+ const char *dn;
+{
+ int ch, escaped = 0;
+
+ /* "." is a valid missing representation */
+ if (*dn == '\0')
+ return (1);
+
+ /* otherwise <label>.<hostname> */
+ while ((ch = *dn++) != '\0') {
+ if (!domainchar(ch))
+ return (0);
+ if (!escaped && periodchar(ch))
+ break;
+ if (escaped)
+ escaped = 0;
+ else if (bslashchar(ch))
+ escaped = 1;
+ }
+ if (periodchar(ch))
+ return (res_hnok(dn));
+ return (0);
+}
+
+/*
+ * This function is quite liberal, since RFC 1034's character sets are only
+ * recommendations.
+ */
+int
+res_dnok(dn)
+ const char *dn;
+{
+ int ch;
+
+ while ((ch = *dn++) != '\0')
+ if (!domainchar(ch))
+ return (0);
+ return (1);
+}
+
+#ifdef BIND_4_COMPAT
+/*
+ * This module must export the following externally-visible symbols:
+ * ___putlong
+ * ___putshort
+ * __getlong
+ * __getshort
+ * Note that one _ comes from C and the others come from us.
+ */
+void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
+void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
+u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); }
+u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); }
+#endif /*BIND_4_COMPAT*/
diff --git a/cpukit/libnetworking/libc/res_config.h b/cpukit/libnetworking/libc/res_config.h
new file mode 100644
index 0000000000..fbd1d694f7
--- /dev/null
+++ b/cpukit/libnetworking/libc/res_config.h
@@ -0,0 +1,20 @@
+/*
+ * $Id$
+ */
+
+#define DEBUG 1 /* enable debugging code (needed for dig) */
+#define RESOLVSORT /* allow sorting of addresses in gethostbyname */
+#define RFC1535 /* comply with RFC1535 (STRONGLY reccomended by vixie)*/
+#undef USELOOPBACK /* res_init() bind to localhost */
+#undef SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT */
+#define MULTI_PTRS_ARE_ALIASES 1 /* fold multiple PTR records into aliases */
+#define CHECK_SRVR_ADDR 1 /* confirm that the server requested sent the reply */
+#define BIND_UPDATE 1 /* update support */
+
+#if defined(__rtems__)
+u_int16_t _getshort(const u_char *src);
+u_int32_t _getlong(const u_char *src);
+int gethostname (char *name, size_t namelen);
+int sethostname (char *name, size_t namelen);
+int issetugid (void);
+#endif
diff --git a/cpukit/libnetworking/libc/res_data.c b/cpukit/libnetworking/libc/res_data.c
new file mode 100644
index 0000000000..fb7d2c66eb
--- /dev/null
+++ b/cpukit/libnetworking/libc/res_data.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1995,1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "res_config.h"
+
+const char *_res_opcodes[] = {
+ "QUERY",
+ "IQUERY",
+ "CQUERYM",
+ "CQUERYU", /* experimental */
+ "NOTIFY", /* experimental */
+ "UPDATE",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12",
+ "13",
+ "ZONEINIT",
+ "ZONEREF",
+};
+
+const char *_res_resultcodes[] = {
+ "NOERROR",
+ "FORMERR",
+ "SERVFAIL",
+ "NXDOMAIN",
+ "NOTIMP",
+ "REFUSED",
+ "YXDOMAIN",
+ "YXRRSET",
+ "NXRRSET",
+ "NOTAUTH",
+ "ZONEERR",
+ "11",
+ "12",
+ "13",
+ "14",
+ "NOCHANGE",
+};
+
+#ifdef BIND_UPDATE
+const char *_res_sectioncodes[] = {
+ "ZONE",
+ "PREREQUISITES",
+ "UPDATE",
+ "ADDITIONAL",
+};
+#endif
diff --git a/cpukit/libnetworking/libc/res_debug.c b/cpukit/libnetworking/libc/res_debug.c
new file mode 100644
index 0000000000..19fb9180c8
--- /dev/null
+++ b/cpukit/libnetworking/libc/res_debug.c
@@ -0,0 +1,966 @@
+/*
+ * Copyright (c) 1985
+ * 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.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software. No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <math.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#define SPRINTF(x) sprintf x
+
+extern const char *_res_opcodes[];
+extern const char *_res_resultcodes[];
+extern const char *_res_sectioncodes[];
+
+/*
+ * Print the current options.
+ */
+void
+fp_resstat(struct __res_state *statp, FILE *file) {
+ u_long mask;
+
+ fprintf(file, ";; res options:");
+ if (!statp)
+ statp = &_res;
+ for (mask = 1; mask != 0; mask <<= 1)
+ if (statp->options & mask)
+ fprintf(file, " %s", p_option(mask));
+ putc('\n', file);
+}
+
+static void
+do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file) {
+ int n, sflag, rrnum;
+ char buf[2048]; /* XXX need to malloc */
+ ns_opcode opcode;
+ ns_rr rr;
+
+ /*
+ * Print answer records.
+ */
+ sflag = (_res.pfcode & pflag);
+ if (_res.pfcode && !sflag)
+ return;
+
+ opcode = ns_msg_getflag(*handle, ns_f_opcode);
+ rrnum = 0;
+ for (;;) {
+ if (ns_parserr(handle, section, rrnum, &rr)) {
+ if (errno != ENODEV)
+ fprintf(file, ";; ns_parserr: %s\n",
+ strerror(errno));
+ else if (rrnum > 0 && sflag != 0 &&
+ (_res.pfcode & RES_PRF_HEAD1))
+ putc('\n', file);
+ return;
+ }
+ if (rrnum == 0 && sflag != 0 && (_res.pfcode & RES_PRF_HEAD1))
+ fprintf(file, ";; %s SECTION:\n",
+ p_section(section, opcode));
+ if (section == ns_s_qd)
+ fprintf(file, ";;\t%s, type = %s, class = %s\n",
+ ns_rr_name(rr),
+ p_type(ns_rr_type(rr)),
+ p_class(ns_rr_class(rr)));
+ else {
+ n = ns_sprintrr(handle, &rr, NULL, NULL,
+ buf, sizeof buf);
+ if (n < 0) {
+ fprintf(file, ";; ns_sprintrr: %s\n",
+ strerror(errno));
+ return;
+ }
+ fputs(buf, file);
+ fputc('\n', file);
+ }
+ rrnum++;
+ }
+}
+
+void
+p_query(const u_char *msg) {
+ fp_query(msg, stdout);
+}
+
+void
+fp_query(const u_char *msg, FILE *file) {
+ fp_nquery(msg, PACKETSZ, file);
+}
+
+/*
+ * Print the contents of a query.
+ * This is intended to be primarily a debugging routine.
+ */
+void
+fp_nquery(const u_char *msg, int len, FILE *file) {
+ ns_msg handle;
+ int qdcount, ancount, nscount, arcount;
+ u_int opcode, rcode, id;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return;
+
+ if (ns_initparse(msg, len, &handle) < 0) {
+ fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
+ return;
+ }
+ opcode = ns_msg_getflag(handle, ns_f_opcode);
+ rcode = ns_msg_getflag(handle, ns_f_rcode);
+ id = ns_msg_id(handle);
+ qdcount = ns_msg_count(handle, ns_s_qd);
+ ancount = ns_msg_count(handle, ns_s_an);
+ nscount = ns_msg_count(handle, ns_s_ns);
+ arcount = ns_msg_count(handle, ns_s_ar);
+
+ /*
+ * Print header fields.
+ */
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || rcode)
+ fprintf(file,
+ ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
+ _res_opcodes[opcode], _res_resultcodes[rcode], id);
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
+ putc(';', file);
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
+ fprintf(file, "; flags:");
+ if (ns_msg_getflag(handle, ns_f_qr))
+ fprintf(file, " qr");
+ if (ns_msg_getflag(handle, ns_f_aa))
+ fprintf(file, " aa");
+ if (ns_msg_getflag(handle, ns_f_tc))
+ fprintf(file, " tc");
+ if (ns_msg_getflag(handle, ns_f_rd))
+ fprintf(file, " rd");
+ if (ns_msg_getflag(handle, ns_f_ra))
+ fprintf(file, " ra");
+ if (ns_msg_getflag(handle, ns_f_z))
+ fprintf(file, " ??");
+ if (ns_msg_getflag(handle, ns_f_ad))
+ fprintf(file, " ad");
+ if (ns_msg_getflag(handle, ns_f_cd))
+ fprintf(file, " cd");
+ }
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
+ fprintf(file, "; %s: %d",
+ p_section(ns_s_qd, opcode), qdcount);
+ fprintf(file, ", %s: %d",
+ p_section(ns_s_an, opcode), ancount);
+ fprintf(file, ", %s: %d",
+ p_section(ns_s_ns, opcode), nscount);
+ fprintf(file, ", %s: %d",
+ p_section(ns_s_ar, opcode), arcount);
+ }
+ if ((!_res.pfcode) || (_res.pfcode &
+ (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
+ putc('\n',file);
+ }
+ /*
+ * Print the various sections.
+ */
+ do_section(&handle, ns_s_qd, RES_PRF_QUES, file);
+ do_section(&handle, ns_s_an, RES_PRF_ANS, file);
+ do_section(&handle, ns_s_ns, RES_PRF_AUTH, file);
+ do_section(&handle, ns_s_ar, RES_PRF_ADD, file);
+ if (qdcount == 0 && ancount == 0 &&
+ nscount == 0 && arcount == 0)
+ putc('\n', file);
+}
+
+const u_char *
+p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {
+ char name[MAXDNAME];
+ int n;
+
+ if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
+ return (NULL);
+ if (name[0] == '\0')
+ putc('.', file);
+ else
+ fputs(name, file);
+ return (cp + n);
+}
+
+const u_char *
+p_cdname(const u_char *cp, const u_char *msg, FILE *file) {
+ return (p_cdnname(cp, msg, PACKETSZ, file));
+}
+
+/* Return a fully-qualified domain name from a compressed name (with
+ length supplied). */
+
+const u_char *
+p_fqnname(cp, msg, msglen, name, namelen)
+ const u_char *cp, *msg;
+ int msglen;
+ char *name;
+ int namelen;
+{
+ int n, newlen;
+
+ if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
+ return (NULL);
+ newlen = strlen(name);
+ if (newlen == 0 || name[newlen - 1] != '.') {
+ if (newlen + 1 >= namelen) /* Lack space for final dot */
+ return (NULL);
+ else
+ strcpy(name + newlen, ".");
+ }
+ return (cp + n);
+}
+
+/* XXX: the rest of these functions need to become length-limited, too. */
+
+const u_char *
+p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
+ char name[MAXDNAME];
+ const u_char *n;
+
+ n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
+ if (n == NULL)
+ return (NULL);
+ fputs(name, file);
+ return (n);
+}
+
+/*
+ * Names of RR classes and qclasses. Classes and qclasses are the same, except
+ * that C_ANY is a qclass but not a class. (You can ask for records of class
+ * C_ANY, but you can't have any records of that class in the database.)
+ */
+const struct res_sym __p_class_syms[] = {
+ {C_IN, "IN"},
+ {C_CHAOS, "CHAOS"},
+ {C_HS, "HS"},
+ {C_HS, "HESIOD"},
+ {C_ANY, "ANY"},
+ {C_NONE, "NONE"},
+ {C_IN, (char *)0}
+};
+
+/*
+ * Names of message sections.
+ */
+const struct res_sym __p_default_section_syms[] = {
+ {ns_s_qd, "QUERY"},
+ {ns_s_an, "ANSWER"},
+ {ns_s_ns, "AUTHORITY"},
+ {ns_s_ar, "ADDITIONAL"},
+ {0, (char *)0}
+};
+
+const struct res_sym __p_update_section_syms[] = {
+ {S_ZONE, "ZONE"},
+ {S_PREREQ, "PREREQUISITE"},
+ {S_UPDATE, "UPDATE"},
+ {S_ADDT, "ADDITIONAL"},
+ {0, (char *)0}
+};
+
+/*
+ * Names of RR types and qtypes. Types and qtypes are the same, except
+ * that T_ANY is a qtype but not a type. (You can ask for records of type
+ * T_ANY, but you can't have any records of that type in the database.)
+ */
+const struct res_sym __p_type_syms[] = {
+ {T_A, "A", "address"},
+ {T_NS, "NS", "name server"},
+ {T_MD, "MD", "mail destination (deprecated)"},
+ {T_MF, "MF", "mail forwarder (deprecated)"},
+ {T_CNAME, "CNAME", "canonical name"},
+ {T_SOA, "SOA", "start of authority"},
+ {T_MB, "MB", "mailbox"},
+ {T_MG, "MG", "mail group member"},
+ {T_MR, "MR", "mail rename"},
+ {T_NULL, "NULL", "null"},
+ {T_WKS, "WKS", "well-known service (deprecated)"},
+ {T_PTR, "PTR", "domain name pointer"},
+ {T_HINFO, "HINFO", "host information"},
+ {T_MINFO, "MINFO", "mailbox information"},
+ {T_MX, "MX", "mail exchanger"},
+ {T_TXT, "TXT", "text"},
+ {T_RP, "RP", "responsible person"},
+ {T_AFSDB, "AFSDB", "DCE or AFS server"},
+ {T_X25, "X25", "X25 address"},
+ {T_ISDN, "ISDN", "ISDN address"},
+ {T_RT, "RT", "router"},
+ {T_NSAP, "NSAP", "nsap address"},
+ {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
+ {T_SIG, "SIG", "signature"},
+ {T_KEY, "KEY", "key"},
+ {T_PX, "PX", "mapping information"},
+ {T_GPOS, "GPOS", "geographical position (withdrawn)"},
+ {T_AAAA, "AAAA", "IPv6 address"},
+ {T_LOC, "LOC", "location"},
+ {T_NXT, "NXT", "next valid name (unimplemented)"},
+ {T_EID, "EID", "endpoint identifier (unimplemented)"},
+ {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"},
+ {T_SRV, "SRV", "server selection"},
+ {T_ATMA, "ATMA", "ATM address (unimplemented)"},
+ {T_IXFR, "IXFR", "incremental zone transfer"},
+ {T_AXFR, "AXFR", "zone transfer"},
+ {T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
+ {T_MAILA, "MAILA", "mail agent (deprecated)"},
+ {T_NAPTR, "NAPTR", "URN Naming Authority"},
+ {T_ANY, "ANY", "\"any\""},
+ {0, NULL, NULL}
+};
+
+int
+sym_ston(const struct res_sym *syms, const char *name, int *success) {
+ for ((void)NULL; syms->name != 0; syms++) {
+ if (strcasecmp (name, syms->name) == 0) {
+ if (success)
+ *success = 1;
+ return (syms->number);
+ }
+ }
+ if (success)
+ *success = 0;
+ return (syms->number); /* The default value. */
+}
+
+const char *
+sym_ntos(const struct res_sym *syms, int number, int *success) {
+ static char unname[20];
+
+ for ((void)NULL; syms->name != 0; syms++) {
+ if (number == syms->number) {
+ if (success)
+ *success = 1;
+ return (syms->name);
+ }
+ }
+
+ sprintf(unname, "%d", number);
+ if (success)
+ *success = 0;
+ return (unname);
+}
+
+const char *
+sym_ntop(const struct res_sym *syms, int number, int *success) {
+ static char unname[20];
+
+ for ((void)NULL; syms->name != 0; syms++) {
+ if (number == syms->number) {
+ if (success)
+ *success = 1;
+ return (syms->humanname);
+ }
+ }
+ sprintf(unname, "%d", number);
+ if (success)
+ *success = 0;
+ return (unname);
+}
+
+/*
+ * Return a string for the type.
+ */
+const char *
+p_type(int type) {
+ return (sym_ntos(__p_type_syms, type, (int *)0));
+}
+
+/*
+ * Return a string for the type.
+ */
+const char *
+p_section(int section, int opcode) {
+ const struct res_sym *symbols;
+
+ switch (opcode) {
+ case ns_o_update:
+ symbols = __p_update_section_syms;
+ break;
+ default:
+ symbols = __p_default_section_syms;
+ break;
+ }
+ return (sym_ntos(symbols, section, (int *)0));
+}
+
+/*
+ * Return a mnemonic for class.
+ */
+const char *
+p_class(int class) {
+ return (sym_ntos(__p_class_syms, class, (int *)0));
+}
+
+/*
+ * Return a mnemonic for an option
+ */
+const char *
+p_option(u_long option) {
+ static char nbuf[40];
+
+ switch (option) {
+ case RES_INIT: return "init";
+ case RES_DEBUG: return "debug";
+ case RES_AAONLY: return "aaonly(unimpl)";
+ case RES_USEVC: return "usevc";
+ case RES_PRIMARY: return "primry(unimpl)";
+ case RES_IGNTC: return "igntc";
+ case RES_RECURSE: return "recurs";
+ case RES_DEFNAMES: return "defnam";
+ case RES_STAYOPEN: return "styopn";
+ case RES_DNSRCH: return "dnsrch";
+ case RES_INSECURE1: return "insecure1";
+ case RES_INSECURE2: return "insecure2";
+ default: sprintf(nbuf, "?0x%lx?", (u_long)option);
+ return (nbuf);
+ }
+}
+
+/*
+ * Return a mnemonic for a time to live.
+ */
+const char *
+p_time(u_int32_t value) {
+ static char nbuf[40];
+
+ if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0)
+ sprintf(nbuf, "%u", value);
+ return (nbuf);
+}
+
+
+/*
+ * routines to convert between on-the-wire RR format and zone file format.
+ * Does not contain conversion to/from decimal degrees; divide or multiply
+ * by 60*60*1000 for that.
+ */
+
+static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
+ 1000000,10000000,100000000,1000000000};
+
+/* takes an XeY precision/size value, returns a string representation. */
+static const char *
+precsize_ntoa(prec)
+ u_int8_t prec;
+{
+ static char retbuf[sizeof "90000000.00"];
+ unsigned long val;
+ int mantissa, exponent;
+
+ mantissa = (int)((prec >> 4) & 0x0f) % 10;
+ exponent = (int)((prec >> 0) & 0x0f) % 10;
+
+ val = mantissa * poweroften[exponent];
+
+ (void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);
+ return (retbuf);
+}
+
+/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
+static u_int8_t
+precsize_aton(strptr)
+ const char **strptr;
+{
+ unsigned int mval = 0, cmval = 0;
+ u_int8_t retval = 0;
+ const char *cp;
+ int exponent;
+ int mantissa;
+
+ cp = *strptr;
+
+ while (isdigit((int)*cp))
+ mval = mval * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* centimeters */
+ cp++;
+ if (isdigit((int)*cp)) {
+ cmval = (*cp++ - '0') * 10;
+ if (isdigit((int)*cp)) {
+ cmval += (*cp++ - '0');
+ }
+ }
+ }
+ cmval = (mval * 100) + cmval;
+
+ for (exponent = 0; exponent < 9; exponent++)
+ if (cmval < poweroften[exponent+1])
+ break;
+
+ mantissa = cmval / poweroften[exponent];
+ if (mantissa > 9)
+ mantissa = 9;
+
+ retval = (mantissa << 4) | exponent;
+
+ *strptr = cp;
+
+ return (retval);
+}
+
+/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
+static u_int32_t
+latlon2ul(latlonstrptr,which)
+ char **latlonstrptr;
+ int *which;
+{
+ char *cp;
+ u_int32_t retval;
+ int deg = 0, min = 0, secs = 0, secsfrac = 0;
+
+ cp = *latlonstrptr;
+
+ while (isdigit((int)*cp))
+ deg = deg * 10 + (*cp++ - '0');
+
+ while (isspace((int)*cp))
+ cp++;
+
+ if (!(isdigit((int)*cp)))
+ goto fndhemi;
+
+ while (isdigit((int)*cp))
+ min = min * 10 + (*cp++ - '0');
+
+ while (isspace((int)*cp))
+ cp++;
+
+ if (!(isdigit((int)*cp)))
+ goto fndhemi;
+
+ while (isdigit((int)*cp))
+ secs = secs * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* decimal seconds */
+ cp++;
+ if (isdigit((int)*cp)) {
+ secsfrac = (*cp++ - '0') * 100;
+ if (isdigit((int)*cp)) {
+ secsfrac += (*cp++ - '0') * 10;
+ if (isdigit((int)*cp)) {
+ secsfrac += (*cp++ - '0');
+ }
+ }
+ }
+ }
+
+ while (!isspace((int)*cp)) /* if any trailing garbage */
+ cp++;
+
+ while (isspace((int)*cp))
+ cp++;
+
+ fndhemi:
+ switch (*cp) {
+ case 'N': case 'n':
+ case 'E': case 'e':
+ retval = ((unsigned)1<<31)
+ + (((((deg * 60) + min) * 60) + secs) * 1000)
+ + secsfrac;
+ break;
+ case 'S': case 's':
+ case 'W': case 'w':
+ retval = ((unsigned)1<<31)
+ - (((((deg * 60) + min) * 60) + secs) * 1000)
+ - secsfrac;
+ break;
+ default:
+ retval = 0; /* invalid value -- indicates error */
+ break;
+ }
+
+ switch (*cp) {
+ case 'N': case 'n':
+ case 'S': case 's':
+ *which = 1; /* latitude */
+ break;
+ case 'E': case 'e':
+ case 'W': case 'w':
+ *which = 2; /* longitude */
+ break;
+ default:
+ *which = 0; /* error */
+ break;
+ }
+
+ cp++; /* skip the hemisphere */
+
+ while (!isspace((int)*cp)) /* if any trailing garbage */
+ cp++;
+
+ while (isspace((int)*cp)) /* move to next field */
+ cp++;
+
+ *latlonstrptr = cp;
+
+ return (retval);
+}
+
+/* converts a zone file representation in a string to an RDATA on-the-wire
+ * representation. */
+int
+loc_aton(ascii, binary)
+ const char *ascii;
+ u_char *binary;
+{
+ const char *cp, *maxcp;
+ u_char *bcp;
+
+ u_int32_t latit = 0, longit = 0, alt = 0;
+ u_int32_t lltemp1 = 0, lltemp2 = 0;
+ int altmeters = 0, altfrac = 0, altsign = 1;
+ u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
+ u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
+ u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
+ int which1 = 0, which2 = 0;
+
+ cp = ascii;
+ maxcp = cp + strlen(ascii);
+
+ lltemp1 = latlon2ul(&cp, &which1);
+
+ lltemp2 = latlon2ul(&cp, &which2);
+
+ switch (which1 + which2) {
+ case 3: /* 1 + 2, the only valid combination */
+ if ((which1 == 1) && (which2 == 2)) { /* normal case */
+ latit = lltemp1;
+ longit = lltemp2;
+ } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
+ longit = lltemp1;
+ latit = lltemp2;
+ } else { /* some kind of brokenness */
+ return (0);
+ }
+ break;
+ default: /* we didn't get one of each */
+ return (0);
+ }
+
+ /* altitude */
+ if (*cp == '-') {
+ altsign = -1;
+ cp++;
+ }
+
+ if (*cp == '+')
+ cp++;
+
+ while (isdigit((int)*cp))
+ altmeters = altmeters * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* decimal meters */
+ cp++;
+ if (isdigit((int)*cp)) {
+ altfrac = (*cp++ - '0') * 10;
+ if (isdigit((int)*cp)) {
+ altfrac += (*cp++ - '0');
+ }
+ }
+ }
+
+ alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
+
+ while (!isspace((int)*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace((int)*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ siz = precsize_aton(&cp);
+
+ while (!isspace((int)*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace((int)*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ hp = precsize_aton(&cp);
+
+ while (!isspace((int)*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace((int)*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ vp = precsize_aton(&cp);
+
+ defaults:
+
+ bcp = binary;
+ *bcp++ = (u_int8_t) 0; /* version byte */
+ *bcp++ = siz;
+ *bcp++ = hp;
+ *bcp++ = vp;
+ PUTLONG(latit,bcp);
+ PUTLONG(longit,bcp);
+ PUTLONG(alt,bcp);
+
+ return (16); /* size of RR in octets */
+}
+
+/* takes an on-the-wire LOC RR and formats it in a human readable format. */
+const char *
+loc_ntoa(binary, ascii)
+ const u_char *binary;
+ char *ascii;
+{
+ static char *error = "?";
+ const u_char *cp = binary;
+
+ int latdeg, latmin, latsec, latsecfrac;
+ int longdeg, longmin, longsec, longsecfrac;
+ char northsouth, eastwest;
+ int altmeters, altfrac, altsign;
+
+ const u_int32_t referencealt = 100000 * 100;
+
+ int32_t latval, longval, altval;
+ u_int32_t templ;
+ u_int8_t sizeval, hpval, vpval, versionval;
+
+ char *sizestr, *hpstr, *vpstr;
+
+ versionval = *cp++;
+
+ if (versionval) {
+ (void) sprintf(ascii, "; error: unknown LOC RR version");
+ return (ascii);
+ }
+
+ sizeval = *cp++;
+
+ hpval = *cp++;
+ vpval = *cp++;
+
+ GETLONG(templ, cp);
+ latval = (templ - ((unsigned)1<<31));
+
+ GETLONG(templ, cp);
+ longval = (templ - ((unsigned)1<<31));
+
+ GETLONG(templ, cp);
+ if (templ < referencealt) { /* below WGS 84 spheroid */
+ altval = referencealt - templ;
+ altsign = -1;
+ } else {
+ altval = templ - referencealt;
+ altsign = 1;
+ }
+
+ if (latval < 0) {
+ northsouth = 'S';
+ latval = -latval;
+ } else
+ northsouth = 'N';
+
+ latsecfrac = latval % 1000;
+ latval = latval / 1000;
+ latsec = latval % 60;
+ latval = latval / 60;
+ latmin = latval % 60;
+ latval = latval / 60;
+ latdeg = latval;
+
+ if (longval < 0) {
+ eastwest = 'W';
+ longval = -longval;
+ } else
+ eastwest = 'E';
+
+ longsecfrac = longval % 1000;
+ longval = longval / 1000;
+ longsec = longval % 60;
+ longval = longval / 60;
+ longmin = longval % 60;
+ longval = longval / 60;
+ longdeg = longval;
+
+ altfrac = altval % 100;
+ altmeters = (altval / 100) * altsign;
+
+ if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
+ sizestr = error;
+ if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
+ hpstr = error;
+ if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
+ vpstr = error;
+
+ sprintf(ascii,
+ "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
+ latdeg, latmin, latsec, latsecfrac, northsouth,
+ longdeg, longmin, longsec, longsecfrac, eastwest,
+ altmeters, altfrac, sizestr, hpstr, vpstr);
+
+ if (sizestr != error)
+ free(sizestr);
+ if (hpstr != error)
+ free(hpstr);
+ if (vpstr != error)
+ free(vpstr);
+
+ return (ascii);
+}
+
+
+/* Return the number of DNS hierarchy levels in the name. */
+int
+dn_count_labels(const char *name) {
+ int i, len, count;
+
+ len = strlen(name);
+ for (i = 0, count = 0; i < len; i++) {
+ /* XXX need to check for \. or use named's nlabels(). */
+ if (name[i] == '.')
+ count++;
+ }
+
+ /* don't count initial wildcard */
+ if (name[0] == '*')
+ if (count)
+ count--;
+
+ /* don't count the null label for root. */
+ /* if terminating '.' not found, must adjust */
+ /* count to include last label */
+ if (len > 0 && name[len-1] != '.')
+ count++;
+ return (count);
+}
+
+
+/*
+ * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
+ * SIG records are required to be printed like this, by the Secure DNS RFC.
+ */
+char *
+p_secstodate (u_long secs) {
+ static char output[15]; /* YYYYMMDDHHMMSS and null */
+ time_t clock = secs;
+ struct tm *time;
+
+ time = gmtime(&clock);
+ time->tm_year += 1900;
+ time->tm_mon += 1;
+ sprintf(output, "%04d%02d%02d%02d%02d%02d",
+ time->tm_year, time->tm_mon, time->tm_mday,
+ time->tm_hour, time->tm_min, time->tm_sec);
+ return (output);
+}
diff --git a/cpukit/libnetworking/libc/res_init.c b/cpukit/libnetworking/libc/res_init.c
new file mode 100644
index 0000000000..6de47a922f
--- /dev/null
+++ b/cpukit/libnetworking/libc/res_init.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 1985, 1989, 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.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
+static char orig_rcsid[] = "From: Id: res_init.c,v 8.7 1996/11/18 09:10:04 vixie Exp $";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "res_config.h"
+
+/*
+ * RTEMS -- set up name servers from global variable
+ */
+#include <rtems/rtems_bsdnet_internal.h>
+#include <rtems/bsdnet/servers.h>
+
+static void res_setoptions(char *, char *);
+
+#ifdef RESOLVSORT
+static const char sort_mask[] = "/&";
+#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
+static u_int32_t net_mask(struct in_addr);
+#endif
+
+#if !defined(isascii) /* XXX - could be a function */
+# define isascii(c) (!(c & 0200))
+#endif
+
+/*
+ * Resolver state default settings.
+ */
+
+struct __res_state _res
+# if defined(__BIND_RES_TEXT)
+ = { RES_TIMEOUT, } /* Motorola, et al. */
+# endif
+ ;
+
+
+/*
+ * Set up default settings. If the configuration file exist, the values
+ * there will have precedence. Otherwise, the server address is set to
+ * INADDR_ANY and the default domain name comes from the gethostname().
+ *
+ * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
+ * rather than INADDR_ANY ("0.0.0.0") as the default name server address
+ * since it was noted that INADDR_ANY actually meant ``the first interface
+ * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
+ * it had to be "up" in order for you to reach your own name server. It
+ * was later decided that since the recommended practice is to always
+ * install local static routes through 127.0.0.1 for all your network
+ * interfaces, that we could solve this problem without a code change.
+ *
+ * The configuration file should always be used, since it is the only way
+ * to specify a default domain. If you are running a server on your local
+ * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
+ * in the configuration file.
+ *
+ * Return 0 if completes successfully, -1 on error
+ */
+int
+res_init()
+{
+ FILE *fp;
+ char *cp, **pp;
+ int n;
+ char buf[MAXDNAME];
+ int nserv = 0; /* number of nameserver records read from file */
+ int haveenv = 0;
+ int havesearch = 0;
+#ifdef RESOLVSORT
+ int nsort = 0;
+ char *net;
+#endif
+#ifndef RFC1535
+ int dots;
+#endif
+
+ /*
+ * These three fields used to be statically initialized. This made
+ * it hard to use this code in a shared library. It is necessary,
+ * now that we're doing dynamic initialization here, that we preserve
+ * the old semantics: if an application modifies one of these three
+ * fields of _res before res_init() is called, res_init() will not
+ * alter them. Of course, if an application is setting them to
+ * _zero_ before calling res_init(), hoping to override what used
+ * to be the static default, we can't detect it and unexpected results
+ * will follow. Zero for any of these fields would make no sense,
+ * so one can safely assume that the applications were already getting
+ * unexpected results.
+ *
+ * _res.options is tricky since some apps were known to diddle the bits
+ * before res_init() was first called. We can't replicate that semantic
+ * with dynamic initialization (they may have turned bits off that are
+ * set in RES_DEFAULT). Our solution is to declare such applications
+ * "broken". They could fool us by setting RES_INIT but none do (yet).
+ */
+ if (!_res.retrans)
+ _res.retrans = RES_TIMEOUT;
+ if (!_res.retry)
+ _res.retry = 4;
+ if (!(_res.options & RES_INIT))
+ _res.options = RES_DEFAULT;
+
+ /*
+ * This one used to initialize implicitly to zero, so unless the app
+ * has set it to something in particular, we can randomize it now.
+ */
+ if (!_res.id)
+ _res.id = res_randomid();
+
+#ifdef USELOOPBACK
+ _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
+#else
+ _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
+#endif
+ _res.nsaddr.sin_family = AF_INET;
+ _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
+ _res.nscount = 1;
+ _res.ndots = 1;
+ _res.pfcode = 0;
+
+ /*
+ * RTEMS -- Set up name servers
+ */
+ {
+ int n = 0;
+ while ((n < rtems_bsdnet_nameserver_count) && (nserv < MAXNS)) {
+ _res.nsaddr_list[nserv].sin_addr = rtems_bsdnet_nameserver[n];
+ _res.nsaddr_list[nserv].sin_family = AF_INET;
+ _res.nsaddr_list[nserv].sin_port = htons(NAMESERVER_PORT);
+ nserv++;
+ n++;
+ }
+ if (rtems_bsdnet_domain_name)
+ (void)strncpy(_res.defdname, rtems_bsdnet_domain_name, sizeof(_res.defdname) - 1);
+ }
+
+ /* Allow user to override the local domain definition */
+ if ((cp = getenv("LOCALDOMAIN")) != NULL) {
+ (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ haveenv++;
+
+ /*
+ * Set search list to be blank-separated strings
+ * from rest of env value. Permits users of LOCALDOMAIN
+ * to still have a search list, and anyone to set the
+ * one that they want to use as an individual (even more
+ * important now that the rfc1535 stuff restricts searches)
+ */
+ cp = _res.defdname;
+ pp = _res.dnsrch;
+ *pp++ = cp;
+ for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
+ if (*cp == '\n') /* silly backwards compat */
+ break;
+ else if (*cp == ' ' || *cp == '\t') {
+ *cp = 0;
+ n = 1;
+ } else if (n) {
+ *pp++ = cp;
+ n = 0;
+ havesearch = 1;
+ }
+ }
+ /* null terminate last domain if there are excess */
+ while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
+ cp++;
+ *cp = '\0';
+ *pp++ = 0;
+ }
+
+#define MATCH(line, name) \
+ (!strncmp(line, name, sizeof(name) - 1) && \
+ (line[sizeof(name) - 1] == ' ' || \
+ line[sizeof(name) - 1] == '\t'))
+
+ if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
+ /* read the config file */
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ /* skip comments */
+ if (*buf == ';' || *buf == '#')
+ continue;
+ /* read default domain name */
+ if (MATCH(buf, "domain")) {
+ if (haveenv) /* skip if have from environ */
+ continue;
+ cp = buf + sizeof("domain") - 1;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if ((*cp == '\0') || (*cp == '\n'))
+ continue;
+ strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
+ *cp = '\0';
+ havesearch = 0;
+ continue;
+ }
+ /* set search list */
+ if (MATCH(buf, "search")) {
+ if (haveenv) /* skip if have from environ */
+ continue;
+ cp = buf + sizeof("search") - 1;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if ((*cp == '\0') || (*cp == '\n'))
+ continue;
+ strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ if ((cp = strchr(_res.defdname, '\n')) != NULL)
+ *cp = '\0';
+ /*
+ * Set search list to be blank-separated strings
+ * on rest of line.
+ */
+ cp = _res.defdname;
+ pp = _res.dnsrch;
+ *pp++ = cp;
+ for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
+ if (*cp == ' ' || *cp == '\t') {
+ *cp = 0;
+ n = 1;
+ } else if (n) {
+ *pp++ = cp;
+ n = 0;
+ }
+ }
+ /* null terminate last domain if there are excess */
+ while (*cp != '\0' && *cp != ' ' && *cp != '\t')
+ cp++;
+ *cp = '\0';
+ *pp++ = 0;
+ havesearch = 1;
+ continue;
+ }
+ /* read nameservers to query */
+ if (MATCH(buf, "nameserver") && nserv < MAXNS) {
+ struct in_addr a;
+
+ cp = buf + sizeof("nameserver") - 1;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
+ _res.nsaddr_list[nserv].sin_addr = a;
+ _res.nsaddr_list[nserv].sin_family = AF_INET;
+ _res.nsaddr_list[nserv].sin_port =
+ htons(NAMESERVER_PORT);
+ nserv++;
+ }
+ continue;
+ }
+#ifdef RESOLVSORT
+ if (MATCH(buf, "sortlist")) {
+ struct in_addr a;
+
+ cp = buf + sizeof("sortlist") - 1;
+ while (nsort < MAXRESOLVSORT) {
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if (*cp == '\0' || *cp == '\n' || *cp == ';')
+ break;
+ net = cp;
+ while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
+ isascii((int)*cp) && !isspace((int)*cp))
+ cp++;
+ n = *cp;
+ *cp = 0;
+ if (inet_aton(net, &a)) {
+ _res.sort_list[nsort].addr = a;
+ if (ISSORTMASK(n)) {
+ *cp++ = n;
+ net = cp;
+ while (*cp && *cp != ';' &&
+ isascii((int)*cp) && !isspace((int)*cp))
+ cp++;
+ n = *cp;
+ *cp = 0;
+ if (inet_aton(net, &a)) {
+ _res.sort_list[nsort].mask = a.s_addr;
+ } else {
+ _res.sort_list[nsort].mask =
+ net_mask(_res.sort_list[nsort].addr);
+ }
+ } else {
+ _res.sort_list[nsort].mask =
+ net_mask(_res.sort_list[nsort].addr);
+ }
+ nsort++;
+ }
+ *cp = n;
+ }
+ continue;
+ }
+#endif
+ if (MATCH(buf, "options")) {
+ res_setoptions(buf + sizeof("options") - 1, "conf");
+ continue;
+ }
+ }
+ if (nserv > 1)
+ _res.nscount = nserv;
+#ifdef RESOLVSORT
+ _res.nsort = nsort;
+#endif
+ (void) fclose(fp);
+ }
+ if (_res.defdname[0] == 0 &&
+ gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
+ (cp = strchr(buf, '.')) != NULL)
+ strcpy(_res.defdname, cp + 1);
+
+ /* find components of local domain that might be searched */
+ if (havesearch == 0) {
+ pp = _res.dnsrch;
+ *pp++ = _res.defdname;
+ *pp = NULL;
+
+#ifndef RFC1535
+ dots = 0;
+ for (cp = _res.defdname; *cp; cp++)
+ dots += (*cp == '.');
+
+ cp = _res.defdname;
+ while (pp < _res.dnsrch + MAXDFLSRCH) {
+ if (dots < LOCALDOMAINPARTS)
+ break;
+ cp = strchr(cp, '.') + 1; /* we know there is one */
+ *pp++ = cp;
+ dots--;
+ }
+ *pp = NULL;
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG) {
+ printf(";; res_init()... default dnsrch list:\n");
+ for (pp = _res.dnsrch; *pp; pp++)
+ printf(";;\t%s\n", *pp);
+ printf(";;\t..END..\n");
+ }
+#endif
+#endif /* !RFC1535 */
+ }
+
+ if ((cp = getenv("RES_OPTIONS")) != NULL)
+ res_setoptions(cp, "env");
+ _res.options |= RES_INIT;
+ return (0);
+}
+
+static void
+res_setoptions(options, source)
+ char *options, *source;
+{
+ char *cp = options;
+ int i;
+
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_setoptions(\"%s\", \"%s\")...\n",
+ options, source);
+#endif
+ while (*cp) {
+ /* skip leading and inner runs of spaces */
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ /* search for and process individual options */
+ if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
+ i = atoi(cp + sizeof("ndots:") - 1);
+ if (i <= RES_MAXNDOTS)
+ _res.ndots = i;
+ else
+ _res.ndots = RES_MAXNDOTS;
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";;\tndots=%d\n", _res.ndots);
+#endif
+ } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
+#ifdef DEBUG
+ if (!(_res.options & RES_DEBUG)) {
+ printf(";; res_setoptions(\"%s\", \"%s\")..\n",
+ options, source);
+ _res.options |= RES_DEBUG;
+ }
+ printf(";;\tdebug\n");
+#endif
+ } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
+ _res.options |= RES_USE_INET6;
+ } else if (!strncmp(cp, "no_tld_query", sizeof("no_tld_query") - 1)) {
+ _res.options |= RES_NOTLDQUERY;
+ } else {
+ /* XXX - print a warning here? */
+ }
+ /* skip to next run of spaces */
+ while (*cp && *cp != ' ' && *cp != '\t')
+ cp++;
+ }
+}
+
+#ifdef RESOLVSORT
+/* XXX - should really support CIDR which means explicit masks always. */
+static u_int32_t
+net_mask(in) /* XXX - should really use system's version of this */
+ struct in_addr in;
+{
+ u_int32_t i = ntohl(in.s_addr);
+
+ if (IN_CLASSA(i))
+ return (htonl(IN_CLASSA_NET));
+ else if (IN_CLASSB(i))
+ return (htonl(IN_CLASSB_NET));
+ return (htonl(IN_CLASSC_NET));
+}
+#endif
+
+u_int
+res_randomid()
+{
+ struct timeval now;
+
+ gettimeofday(&now, NULL);
+ return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
+}
diff --git a/cpukit/libnetworking/libc/res_mkquery.c b/cpukit/libnetworking/libc/res_mkquery.c
new file mode 100644
index 0000000000..d3fabfa5ab
--- /dev/null
+++ b/cpukit/libnetworking/libc/res_mkquery.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 1985, 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.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
+static char orig_rcsid[] = "From: Id: res_mkquery.c,v 8.9 1997/04/24 22:22:36 vixie Exp $";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "res_config.h"
+
+/*
+ * Form all types of queries.
+ * Returns the size of the result or -1.
+ */
+int
+res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
+ int op; /* opcode of query */
+ const char *dname; /* domain name */
+ int class, type; /* class and type of query */
+ const u_char *data; /* resource record data */
+ int datalen; /* length of data */
+ const u_char *newrr_in; /* new rr for modify or append */
+ u_char *buf; /* buffer to put query */
+ int buflen; /* size of buffer */
+{
+ register HEADER *hp;
+ register u_char *cp;
+ register int n;
+ u_char *dnptrs[20], **dpp, **lastdnptr;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_mkquery(%d, %s, %d, %d)\n",
+ op, dname, class, type);
+#endif
+ /*
+ * Initialize header fields.
+ */
+ if ((buf == NULL) || (buflen < HFIXEDSZ))
+ return (-1);
+ memset(buf, 0, HFIXEDSZ);
+ hp = (HEADER *) buf;
+ hp->id = htons(++_res.id);
+ hp->opcode = op;
+ hp->rd = (_res.options & RES_RECURSE) != 0;
+ hp->rcode = NOERROR;
+ cp = buf + HFIXEDSZ;
+ buflen -= HFIXEDSZ;
+ dpp = dnptrs;
+ *dpp++ = buf;
+ *dpp++ = NULL;
+ lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
+ /*
+ * perform opcode specific processing
+ */
+ switch (op) {
+ case QUERY: /*FALLTHROUGH*/
+ case NS_NOTIFY_OP:
+ if ((buflen -= QFIXEDSZ) < 0)
+ return (-1);
+ if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
+ return (-1);
+ cp += n;
+ buflen -= n;
+ __putshort(type, cp);
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
+ hp->qdcount = htons(1);
+ if (op == QUERY || data == NULL)
+ break;
+ /*
+ * Make an additional record for completion domain.
+ */
+ buflen -= RRFIXEDSZ;
+ n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ buflen -= n;
+ __putshort(T_NULL, cp);
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
+ __putlong(0, cp);
+ cp += INT32SZ;
+ __putshort(0, cp);
+ cp += INT16SZ;
+ hp->arcount = htons(1);
+ break;
+
+ case IQUERY:
+ /*
+ * Initialize answer section
+ */
+ if (buflen < 1 + RRFIXEDSZ + datalen)
+ return (-1);
+ *cp++ = '\0'; /* no domain name */
+ __putshort(type, cp);
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
+ __putlong(0, cp);
+ cp += INT32SZ;
+ __putshort(datalen, cp);
+ cp += INT16SZ;
+ if (datalen) {
+ memcpy(cp, data, datalen);
+ cp += datalen;
+ }
+ hp->ancount = htons(1);
+ break;
+
+ default:
+ return (-1);
+ }
+ return (cp - buf);
+}
diff --git a/cpukit/libnetworking/libc/res_mkupdate.c b/cpukit/libnetworking/libc/res_mkupdate.c
new file mode 100644
index 0000000000..56362f650b
--- /dev/null
+++ b/cpukit/libnetworking/libc/res_mkupdate.c
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Based on the Dynamic DNS reference implementation by Viraj Bais
+ * <viraj_bais@ccm.fm.intel.com>
+ */
+
+#if !defined(__rtems__)
+#if !defined(lint) && !defined(SABER)
+static char rcsid[] = "$Id$";
+#endif /* not lint */
+#endif /* not rtems */
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "res_config.h"
+
+static int getnum_str(u_char **, u_char *);
+static int getword_str(char *, int, u_char **, u_char *);
+
+#define ShrinkBuffer(x) if ((buflen -= x) < 0) return (-2);
+
+/*
+ * Form update packets.
+ * Returns the size of the resulting packet if no error
+ * On error,
+ * returns -1 if error in reading a word/number in rdata
+ * portion for update packets
+ * -2 if length of buffer passed is insufficient
+ * -3 if zone section is not the first section in
+ * the linked list, or section order has a problem
+ * -4 on a number overflow
+ * -5 unknown operation or no records
+ */
+int
+res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
+ ns_updrec *rrecp_start = rrecp_in;
+ HEADER *hp;
+ u_char *cp, *sp1, *sp2, *startp, *endp;
+ int n, i, soanum, multiline;
+ ns_updrec *rrecp;
+ struct in_addr ina;
+ char buf2[MAXDNAME];
+ int section, numrrs = 0, counts[ns_s_max];
+ u_int16_t rtype, rclass;
+ u_int32_t n1, rttl;
+ u_char *dnptrs[20], **dpp, **lastdnptr;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+
+ /*
+ * Initialize header fields.
+ */
+ if ((buf == NULL) || (buflen < HFIXEDSZ))
+ return (-1);
+ memset(buf, 0, HFIXEDSZ);
+ hp = (HEADER *) buf;
+ hp->id = htons(++_res.id);
+ hp->opcode = ns_o_update;
+ hp->rcode = NOERROR;
+ sp1 = buf + 2*INT16SZ; /* save pointer to zocount */
+ cp = buf + HFIXEDSZ;
+ buflen -= HFIXEDSZ;
+ dpp = dnptrs;
+ *dpp++ = buf;
+ *dpp++ = NULL;
+ lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
+
+ if (rrecp_start == NULL)
+ return (-5);
+ else if (rrecp_start->r_section != S_ZONE)
+ return (-3);
+
+ memset(counts, 0, sizeof counts);
+ for (rrecp = rrecp_start; rrecp; rrecp = rrecp->r_grpnext) {
+ numrrs++;
+ section = rrecp->r_section;
+ if (section < 0 || section >= ns_s_max)
+ return (-1);
+ counts[section]++;
+ for (i = section + 1; i < ns_s_max; i++)
+ if (counts[i])
+ return (-3);
+ rtype = rrecp->r_type;
+ rclass = rrecp->r_class;
+ rttl = rrecp->r_ttl;
+ /* overload class and type */
+ if (section == S_PREREQ) {
+ rttl = 0;
+ switch (rrecp->r_opcode) {
+ case YXDOMAIN:
+ rclass = C_ANY;
+ rtype = T_ANY;
+ rrecp->r_size = 0;
+ break;
+ case NXDOMAIN:
+ rclass = C_NONE;
+ rtype = T_ANY;
+ rrecp->r_size = 0;
+ break;
+ case NXRRSET:
+ rclass = C_NONE;
+ rrecp->r_size = 0;
+ break;
+ case YXRRSET:
+ if (rrecp->r_size == 0)
+ rclass = C_ANY;
+ break;
+ default:
+ fprintf(stderr,
+ "res_mkupdate: incorrect opcode: %d\n",
+ rrecp->r_opcode);
+ fflush(stderr);
+ return (-1);
+ }
+ } else if (section == S_UPDATE) {
+ switch (rrecp->r_opcode) {
+ case DELETE:
+ rclass = rrecp->r_size == 0 ? C_ANY : C_NONE;
+ break;
+ case ADD:
+ break;
+ default:
+ fprintf(stderr,
+ "res_mkupdate: incorrect opcode: %d\n",
+ rrecp->r_opcode);
+ fflush(stderr);
+ return (-1);
+ }
+ }
+
+ /*
+ * XXX appending default domain to owner name is omitted,
+ * fqdn must be provided
+ */
+ if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,
+ lastdnptr)) < 0)
+ return (-1);
+ cp += n;
+ ShrinkBuffer(n + 2*INT16SZ);
+ PUTSHORT(rtype, cp);
+ PUTSHORT(rclass, cp);
+ if (section == S_ZONE) {
+ if (numrrs != 1 || rrecp->r_type != T_SOA)
+ return (-3);
+ continue;
+ }
+ ShrinkBuffer(INT32SZ + INT16SZ);
+ PUTLONG(rttl, cp);
+ sp2 = cp; /* save pointer to length byte */
+ cp += INT16SZ;
+ if (rrecp->r_size == 0) {
+ if (section == S_UPDATE && rclass != C_ANY)
+ return (-1);
+ else {
+ PUTSHORT(0, sp2);
+ continue;
+ }
+ }
+ startp = rrecp->r_data;
+ endp = startp + rrecp->r_size - 1;
+ /* XXX this should be done centrally. */
+ switch (rrecp->r_type) {
+ case T_A:
+ if (!getword_str(buf2, sizeof buf2, &startp, endp))
+ return (-1);
+ if (!inet_aton(buf2, &ina))
+ return (-1);
+ n1 = ntohl(ina.s_addr);
+ ShrinkBuffer(INT32SZ);
+ PUTLONG(n1, cp);
+ break;
+ case T_CNAME:
+ case T_MB:
+ case T_MG:
+ case T_MR:
+ case T_NS:
+ case T_PTR:
+ if (!getword_str(buf2, sizeof buf2, &startp, endp))
+ return (-1);
+ n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ShrinkBuffer(n);
+ break;
+ case T_MINFO:
+ case T_SOA:
+ case T_RP:
+ for (i = 0; i < 2; i++) {
+ if (!getword_str(buf2, sizeof buf2, &startp,
+ endp))
+ return (-1);
+ n = dn_comp(buf2, cp, buflen,
+ dnptrs, lastdnptr);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ShrinkBuffer(n);
+ }
+ if (rrecp->r_type == T_SOA) {
+ ShrinkBuffer(5 * INT32SZ);
+ while (isspace(*startp) || !*startp)
+ startp++;
+ if (*startp == '(') {
+ multiline = 1;
+ startp++;
+ } else
+ multiline = 0;
+ /* serial, refresh, retry, expire, minimum */
+ for (i = 0; i < 5; i++) {
+ soanum = getnum_str(&startp, endp);
+ if (soanum < 0)
+ return (-1);
+ PUTLONG(soanum, cp);
+ }
+ if (multiline) {
+ while (isspace(*startp) || !*startp)
+ startp++;
+ if (*startp != ')')
+ return (-1);
+ }
+ }
+ break;
+ case T_MX:
+ case T_AFSDB:
+ case T_RT:
+ n = getnum_str(&startp, endp);
+ if (n < 0)
+ return (-1);
+ PUTSHORT(n, cp);
+ ShrinkBuffer(INT16SZ);
+ if (!getword_str(buf2, sizeof buf2, &startp, endp))
+ return (-1);
+ n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ShrinkBuffer(n);
+ break;
+ case T_PX:
+ n = getnum_str(&startp, endp);
+ if (n < 0)
+ return (-1);
+ PUTSHORT(n, cp);
+ ShrinkBuffer(INT16SZ);
+ for (i = 0; i < 2; i++) {
+ if (!getword_str(buf2, sizeof buf2, &startp,
+ endp))
+ return (-1);
+ n = dn_comp(buf2, cp, buflen, dnptrs,
+ lastdnptr);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ShrinkBuffer(n);
+ }
+ break;
+ case T_WKS:
+ case T_HINFO:
+ case T_TXT:
+ case T_X25:
+ case T_ISDN:
+ case T_NSAP:
+ case T_LOC:
+ /* XXX - more fine tuning needed here */
+ ShrinkBuffer(rrecp->r_size);
+ memcpy(cp, rrecp->r_data, rrecp->r_size);
+ cp += rrecp->r_size;
+ break;
+ default:
+ return (-1);
+ } /*switch*/
+ n = (u_int16_t)((cp - sp2) - INT16SZ);
+ PUTSHORT(n, sp2);
+ } /*for*/
+
+ hp->qdcount = htons(counts[0]);
+ hp->ancount = htons(counts[1]);
+ hp->nscount = htons(counts[2]);
+ hp->arcount = htons(counts[3]);
+ return (cp - buf);
+}
+
+/*
+ * Get a whitespace delimited word from a string (not file)
+ * into buf. modify the start pointer to point after the
+ * word in the string.
+ */
+static int
+getword_str(char *buf, int size, u_char **startpp, u_char *endp) {
+ char *cp;
+ int c;
+
+ for (cp = buf; *startpp <= endp; ) {
+ c = **startpp;
+ if (isspace(c) || c == '\0') {
+ if (cp != buf) /* trailing whitespace */
+ break;
+ else { /* leading whitespace */
+ (*startpp)++;
+ continue;
+ }
+ }
+ (*startpp)++;
+ if (cp >= buf+size-1)
+ break;
+ *cp++ = (u_char)c;
+ }
+ *cp = '\0';
+ return (cp != buf);
+}
+
+/*
+ * Get a whitespace delimited number from a string (not file) into buf
+ * update the start pointer to point after the number in the string.
+ */
+static int
+getnum_str(u_char **startpp, u_char *endp) {
+ int c, n;
+ int seendigit = 0;
+ int m = 0;
+
+ for (n = 0; *startpp <= endp; ) {
+ c = **startpp;
+ if (isspace(c) || c == '\0') {
+ if (seendigit) /* trailing whitespace */
+ break;
+ else { /* leading whitespace */
+ (*startpp)++;
+ continue;
+ }
+ }
+ if (c == ';') {
+ while ((*startpp <= endp) &&
+ ((c = **startpp) != '\n'))
+ (*startpp)++;
+ if (seendigit)
+ break;
+ continue;
+ }
+ if (!isdigit(c)) {
+ if (c == ')' && seendigit) {
+ (*startpp)--;
+ break;
+ }
+ return (-1);
+ }
+ (*startpp)++;
+ n = n * 10 + (c - '0');
+ seendigit = 1;
+ }
+ return (n + m);
+}
+
+/*
+ * Allocate a resource record buffer & save rr info.
+ */
+ns_updrec *
+res_mkupdrec(int section, const char *dname,
+ u_int class, u_int type, u_long ttl) {
+ ns_updrec *rrecp = (ns_updrec *)calloc(1, sizeof(ns_updrec));
+
+ if (!rrecp || !(rrecp->r_dname = strdup(dname)))
+ return (NULL);
+ rrecp->r_class = class;
+ rrecp->r_type = type;
+ rrecp->r_ttl = ttl;
+ rrecp->r_section = section;
+ return (rrecp);
+}
+
+/*
+ * Free a resource record buffer created by res_mkupdrec.
+ */
+void
+res_freeupdrec(ns_updrec *rrecp) {
+ /* Note: freeing r_dp is the caller's responsibility. */
+ if (rrecp->r_dname != NULL)
+ free(rrecp->r_dname);
+ free(rrecp);
+}
diff --git a/cpukit/libnetworking/libc/res_query.c b/cpukit/libnetworking/libc/res_query.c
new file mode 100644
index 0000000000..784fa433bc
--- /dev/null
+++ b/cpukit/libnetworking/libc/res_query.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 1988, 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.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
+static char orig_rcsid = "From: Id: res_query.c,v 8.14 1997/06/09 17:47:05 halley Exp $";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "res_config.h"
+
+#if PACKETSZ > 1024
+#define MAXPACKET PACKETSZ
+#else
+#define MAXPACKET 1024
+#endif
+
+/*
+ * Formulate a normal query, send, and await answer.
+ * Returned answer is placed in supplied buffer "answer".
+ * Perform preliminary check of answer, returning success only
+ * if no error is indicated and the answer count is nonzero.
+ * Return the size of the response on success, -1 on error.
+ * Error number is left in h_errno.
+ *
+ * Caller must parse answer and determine whether it answers the question.
+ */
+int
+res_query(name, class, type, answer, anslen)
+ const char *name; /* domain name */
+ int class, type; /* class and type of query */
+ u_char *answer; /* buffer to put answer */
+ int anslen; /* size of answer buffer */
+{
+ u_char buf[MAXPACKET];
+ HEADER *hp = (HEADER *) answer;
+ int n;
+
+ hp->rcode = NOERROR; /* default */
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_query(%s, %d, %d)\n", name, class, type);
+#endif
+
+ n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
+ buf, sizeof(buf));
+ if (n <= 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_query: mkquery failed\n");
+#endif
+ h_errno = NO_RECOVERY;
+ return (n);
+ }
+ n = res_send(buf, n, answer, anslen);
+ if (n < 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_query: send error\n");
+#endif
+ h_errno = TRY_AGAIN;
+ return (n);
+ }
+
+ if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; rcode = %d, ancount=%d\n", hp->rcode,
+ ntohs(hp->ancount));
+#endif
+ switch (hp->rcode) {
+ case NXDOMAIN:
+ h_errno = HOST_NOT_FOUND;
+ break;
+ case SERVFAIL:
+ h_errno = TRY_AGAIN;
+ break;
+ case NOERROR:
+ h_errno = NO_DATA;
+ break;
+ case FORMERR:
+ case NOTIMP:
+ case REFUSED:
+ default:
+ h_errno = NO_RECOVERY;
+ break;
+ }
+ return (-1);
+ }
+ return (n);
+}
+
+/*
+ * Formulate a normal query, send, and retrieve answer in supplied buffer.
+ * Return the size of the response on success, -1 on error.
+ * If enabled, implement search rules until answer or unrecoverable failure
+ * is detected. Error code, if any, is left in h_errno.
+ */
+int
+res_search(name, class, type, answer, anslen)
+ const char *name; /* domain name */
+ int class, type; /* class and type of query */
+ u_char *answer; /* buffer to put answer */
+ int anslen; /* size of answer */
+{
+ const char *cp, * const *domain;
+ HEADER *hp = (HEADER *) answer;
+ u_int dots;
+ int trailing_dot, ret, saved_herrno;
+ int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+ errno = 0;
+ h_errno = HOST_NOT_FOUND; /* default, if we never query */
+ dots = 0;
+ for (cp = name; *cp; cp++)
+ dots += (*cp == '.');
+ trailing_dot = 0;
+ if (cp > name && *--cp == '.')
+ trailing_dot++;
+
+ /* If there aren't any dots, it could be a user-level alias */
+ if (!dots && (cp = hostalias(name)) != NULL)
+ return (res_query(cp, class, type, answer, anslen));
+
+ /*
+ * If there are dots in the name already, let's just give it a try
+ * 'as is'. The threshold can be set with the "ndots" option.
+ */
+ saved_herrno = -1;
+ if (dots >= _res.ndots) {
+ ret = res_querydomain(name, NULL, class, type, answer, anslen);
+ if (ret > 0)
+ return (ret);
+ saved_herrno = h_errno;
+ tried_as_is++;
+ }
+
+ /*
+ * We do at least one level of search if
+ * - there is no dot and RES_DEFNAME is set, or
+ * - there is at least one dot, there is no trailing dot,
+ * and RES_DNSRCH is set.
+ */
+ if ((!dots && (_res.options & RES_DEFNAMES)) ||
+ (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
+ int done = 0;
+
+ for (domain = (const char * const *)_res.dnsrch;
+ *domain && !done;
+ domain++) {
+
+ ret = res_querydomain(name, *domain, class, type,
+ answer, anslen);
+ if (ret > 0)
+ return (ret);
+
+ /*
+ * If no server present, give up.
+ * If name isn't found in this domain,
+ * keep trying higher domains in the search list
+ * (if that's enabled).
+ * On a NO_DATA error, keep trying, otherwise
+ * a wildcard entry of another type could keep us
+ * from finding this entry higher in the domain.
+ * If we get some other error (negative answer or
+ * server failure), then stop searching up,
+ * but try the input name below in case it's
+ * fully-qualified.
+ */
+ if (errno == ECONNREFUSED) {
+ h_errno = TRY_AGAIN;
+ return (-1);
+ }
+
+ switch (h_errno) {
+ case NO_DATA:
+ got_nodata++;
+ /* FALLTHROUGH */
+ case HOST_NOT_FOUND:
+ /* keep trying */
+ break;
+ case TRY_AGAIN:
+ if (hp->rcode == SERVFAIL) {
+ /* try next search element, if any */
+ got_servfail++;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ /* anything else implies that we're done */
+ done++;
+ }
+
+ /* if we got here for some reason other than DNSRCH,
+ * we only wanted one iteration of the loop, so stop.
+ */
+ if (!(_res.options & RES_DNSRCH))
+ done++;
+ }
+ }
+
+ /*
+ * If we have not already tried the name "as is", do that now.
+ * note that we do this regardless of how many dots were in the
+ * name or whether it ends with a dot unless NOTLDQUERY is set.
+ */
+ if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) {
+ ret = res_querydomain(name, NULL, class, type, answer, anslen);
+ if (ret > 0)
+ return (ret);
+ }
+
+ /* if we got here, we didn't satisfy the search.
+ * if we did an initial full query, return that query's h_errno
+ * (note that we wouldn't be here if that query had succeeded).
+ * else if we ever got a nodata, send that back as the reason.
+ * else send back meaningless h_errno, that being the one from
+ * the last DNSRCH we did.
+ */
+ if (saved_herrno != -1)
+ h_errno = saved_herrno;
+ else if (got_nodata)
+ h_errno = NO_DATA;
+ else if (got_servfail)
+ h_errno = TRY_AGAIN;
+ return (-1);
+}
+
+/*
+ * Perform a call on res_query on the concatenation of name and domain,
+ * removing a trailing dot from name if domain is NULL.
+ */
+int
+res_querydomain(name, domain, class, type, answer, anslen)
+ const char *name, *domain;
+ int class, type; /* class and type of query */
+ u_char *answer; /* buffer to put answer */
+ int anslen; /* size of answer */
+{
+ char nbuf[MAXDNAME];
+ const char *longname = nbuf;
+ int n, d;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_querydomain(%s, %s, %d, %d)\n",
+ name, domain?domain:"<Nil>", class, type);
+#endif
+ if (domain == NULL) {
+ /*
+ * Check for trailing '.';
+ * copy without '.' if present.
+ */
+ n = strlen(name);
+ if (n >= MAXDNAME) {
+ h_errno = NO_RECOVERY;
+ return (-1);
+ }
+ n--;
+ if (n >= 0 && name[n] == '.') {
+ strncpy(nbuf, name, n);
+ nbuf[n] = '\0';
+ } else
+ longname = name;
+ } else {
+ n = strlen(name);
+ d = strlen(domain);
+ if (n + d + 1 >= MAXDNAME) {
+ h_errno = NO_RECOVERY;
+ return (-1);
+ }
+ sprintf(nbuf, "%s.%s", name, domain);
+ }
+ return (res_query(longname, class, type, answer, anslen));
+}
+
+const char *
+hostalias(name)
+ const char *name;
+{
+ register char *cp1, *cp2;
+ FILE *fp;
+ char *file;
+ char buf[BUFSIZ];
+ static char abuf[MAXDNAME];
+
+ if (_res.options & RES_NOALIASES)
+ return (NULL);
+ if (issetugid())
+ return (NULL);
+ file = getenv("HOSTALIASES");
+ if (file == NULL || (fp = fopen(file, "r")) == NULL)
+ return (NULL);
+ setbuf(fp, NULL);
+ buf[sizeof(buf) - 1] = '\0';
+ while (fgets(buf, sizeof(buf), fp)) {
+ for (cp1 = buf; *cp1 && !isspace((int)*cp1); ++cp1)
+ ;
+ if (!*cp1)
+ break;
+ *cp1 = '\0';
+ if (!strcasecmp(buf, name)) {
+ while (isspace((int)*++cp1))
+ ;
+ if (!*cp1)
+ break;
+ for (cp2 = cp1 + 1; *cp2 && !isspace((int)*cp2); ++cp2)
+ ;
+ abuf[sizeof(abuf) - 1] = *cp2 = '\0';
+ strncpy(abuf, cp1, sizeof(abuf) - 1);
+ fclose(fp);
+ return (abuf);
+ }
+ }
+ fclose(fp);
+ return (NULL);
+}
diff --git a/cpukit/libnetworking/libc/res_send.c b/cpukit/libnetworking/libc/res_send.c
new file mode 100644
index 0000000000..d28165996d
--- /dev/null
+++ b/cpukit/libnetworking/libc/res_send.c
@@ -0,0 +1,932 @@
+/*
+ * Copyright (c) 1985, 1989, 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.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
+static char orig_rcsid[] = "From: Id: res_send.c,v 8.20 1998/04/06 23:27:51 halley Exp $";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Send query to name server and wait for reply.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#if !defined(__rtems__)
+#include <poll.h>
+#endif
+
+#include "res_config.h"
+
+#if !defined(__rtems__)
+
+#ifdef NOPOLL /* libc_r doesn't wrap poll yet() */
+static int use_poll = 0;
+#else
+static int use_poll = 1; /* adapt to poll() syscall availability */
+ /* 0 = not present, 1 = try it, 2 = exists */
+#endif
+#endif
+
+static int s = -1; /* socket used for communications */
+static int connected = 0; /* is the socket connected */
+static int vc = 0; /* is the socket a virtual circuit? */
+static res_send_qhook Qhook = NULL;
+static res_send_rhook Rhook = NULL;
+
+
+#define CAN_RECONNECT 1
+
+#ifndef DEBUG
+# define Dprint(cond, args) /*empty*/
+# define DprintQ(cond, args, query, size) /*empty*/
+# define Aerror(file, string, error, address) /*empty*/
+# define Perror(file, string, error) /*empty*/
+#else
+# define Dprint(cond, args) if (cond) {fprintf args;} else {}
+# define DprintQ(cond, args, query, size) if (cond) {\
+ fprintf args;\
+ __fp_nquery(query, size, stdout);\
+ } else {}
+ static void
+ Aerror(file, string, error, address)
+ FILE *file;
+ char *string;
+ int error;
+ struct sockaddr_in address;
+ {
+ int save = errno;
+
+ if (_res.options & RES_DEBUG) {
+ fprintf(file, "res_send: %s ([%s].%u): %s\n",
+ string,
+ inet_ntoa(address.sin_addr),
+ ntohs(address.sin_port),
+ strerror(error));
+ }
+ errno = save;
+ }
+ static void
+ Perror(file, string, error)
+ FILE *file;
+ char *string;
+ int error;
+ {
+ int save = errno;
+
+ if (_res.options & RES_DEBUG) {
+ fprintf(file, "res_send: %s: %s\n",
+ string, strerror(error));
+ }
+ errno = save;
+ }
+#endif
+
+void
+res_send_setqhook(hook)
+ res_send_qhook hook;
+{
+
+ Qhook = hook;
+}
+
+void
+res_send_setrhook(hook)
+ res_send_rhook hook;
+{
+
+ Rhook = hook;
+}
+
+/* int
+ * res_isourserver(ina)
+ * looks up "ina" in _res.ns_addr_list[]
+ * returns:
+ * 0 : not found
+ * >0 : found
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_isourserver(inp)
+ const struct sockaddr_in *inp;
+{
+ struct sockaddr_in ina;
+ int ns, ret;
+
+ ina = *inp;
+ ret = 0;
+ for (ns = 0; ns < _res.nscount; ns++) {
+ const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
+
+ if (srv->sin_family == ina.sin_family &&
+ srv->sin_port == ina.sin_port &&
+ (srv->sin_addr.s_addr == INADDR_ANY ||
+ srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {
+ ret++;
+ break;
+ }
+ }
+ return (ret);
+}
+
+/* int
+ * res_nameinquery(name, type, class, buf, eom)
+ * look for (name,type,class) in the query section of packet (buf,eom)
+ * requires:
+ * buf + HFIXEDSZ <= eom
+ * returns:
+ * -1 : format error
+ * 0 : not found
+ * >0 : found
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_nameinquery(name, type, class, buf, eom)
+ const char *name;
+ int type, class;
+ const u_char *buf, *eom;
+{
+ const u_char *cp = buf + HFIXEDSZ;
+ int qdcount = ntohs(((HEADER*)buf)->qdcount);
+
+ while (qdcount-- > 0) {
+ char tname[MAXDNAME+1];
+ int n, ttype, tclass;
+
+ n = dn_expand(buf, eom, cp, tname, sizeof tname);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ if (cp + 2 * INT16SZ > eom)
+ return (-1);
+ ttype = ns_get16(cp); cp += INT16SZ;
+ tclass = ns_get16(cp); cp += INT16SZ;
+ if (ttype == type &&
+ tclass == class &&
+ strcasecmp(tname, name) == 0)
+ return (1);
+ }
+ return (0);
+}
+
+/* int
+ * res_queriesmatch(buf1, eom1, buf2, eom2)
+ * is there a 1:1 mapping of (name,type,class)
+ * in (buf1,eom1) and (buf2,eom2)?
+ * returns:
+ * -1 : format error
+ * 0 : not a 1:1 mapping
+ * >0 : is a 1:1 mapping
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_queriesmatch(buf1, eom1, buf2, eom2)
+ const u_char *buf1, *eom1;
+ const u_char *buf2, *eom2;
+{
+ const u_char *cp = buf1 + HFIXEDSZ;
+ int qdcount = ntohs(((HEADER*)buf1)->qdcount);
+
+ if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
+ return (-1);
+
+ /*
+ * Only header section present in replies to
+ * dynamic update packets.
+ */
+ if ( (((HEADER *)buf1)->opcode == ns_o_update) &&
+ (((HEADER *)buf2)->opcode == ns_o_update) )
+ return (1);
+
+ if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
+ return (0);
+ while (qdcount-- > 0) {
+ char tname[MAXDNAME+1];
+ int n, ttype, tclass;
+
+ n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ if (cp + 2 * INT16SZ > eom1)
+ return (-1);
+ ttype = ns_get16(cp); cp += INT16SZ;
+ tclass = ns_get16(cp); cp += INT16SZ;
+ if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
+ return (0);
+ }
+ return (1);
+}
+
+int
+res_send(buf, buflen, ans, anssiz)
+ const u_char *buf;
+ int buflen;
+ u_char *ans;
+ int anssiz;
+{
+ HEADER *hp = (HEADER *) buf;
+ HEADER *anhp = (HEADER *) ans;
+ int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns, n;
+ u_int badns; /* XXX NSMAX can't exceed #/bits in this variable */
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ /* errno should have been set by res_init() in this case. */
+ return (-1);
+ }
+ if (anssiz < HFIXEDSZ) {
+ errno = EINVAL;
+ return (-1);
+ }
+ DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
+ (stdout, ";; res_send()\n"), buf, buflen);
+ v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
+ gotsomewhere = 0;
+ connreset = 0;
+ terrno = ETIMEDOUT;
+ badns = 0;
+
+ /*
+ * Send request, RETRY times, or until successful
+ */
+ for (try = 0; try < _res.retry; try++) {
+ for (ns = 0; ns < _res.nscount; ns++) {
+ struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
+ same_ns:
+ if (badns & (1 << ns)) {
+ res_close();
+ goto next_ns;
+ }
+
+ if (Qhook) {
+ int done = 0, loops = 0;
+
+ do {
+ res_sendhookact act;
+
+ act = (*Qhook)(&nsap, &buf, &buflen,
+ ans, anssiz, &resplen);
+ switch (act) {
+ case res_goahead:
+ done = 1;
+ break;
+ case res_nextns:
+ res_close();
+ goto next_ns;
+ case res_done:
+ return (resplen);
+ case res_modified:
+ /* give the hook another try */
+ if (++loops < 42) /*doug adams*/
+ break;
+ /*FALLTHROUGH*/
+ case res_error:
+ /*FALLTHROUGH*/
+ default:
+ return (-1);
+ }
+ } while (!done);
+ }
+
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; Querying server (# %d) address = %s\n",
+ ns + 1, inet_ntoa(nsap->sin_addr)));
+
+ if (v_circuit) {
+ int truncated;
+#if !defined(__rtems__)
+ struct iovec iov[2];
+#endif
+ u_short len;
+ u_char *cp;
+
+ /*
+ * Use virtual circuit;
+ * at most one attempt per server.
+ */
+ try = _res.retry;
+ truncated = 0;
+ if (s < 0 || !vc || hp->opcode == ns_o_update) {
+ if (s >= 0)
+ res_close();
+
+ s = socket(PF_INET, SOCK_STREAM, 0);
+ if (s < 0) {
+ terrno = errno;
+ Perror(stderr, "socket(vc)", errno);
+ return (-1);
+ }
+ errno = 0;
+ if (connect(s, (struct sockaddr *)nsap,
+ sizeof *nsap) < 0) {
+ terrno = errno;
+ Aerror(stderr, "connect/vc",
+ errno, *nsap);
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ vc = 1;
+ }
+ /*
+ * Send length & message
+ */
+ putshort((u_short)buflen, (u_char*)&len);
+#if !defined(__rtems__)
+ iov[0].iov_base = (caddr_t)&len;
+ iov[0].iov_len = INT16SZ;
+ iov[1].iov_base = (caddr_t)buf;
+ iov[1].iov_len = buflen;
+ if (writev(s, iov, 2) != (INT16SZ + buflen)) {
+#else
+ /*
+ * RTEMS doesn't have writev (yet)
+ */
+ if ((write (s, &len, INT16SZ) != INT16SZ)
+ || (write (s, buf, buflen) != buflen)) {
+#endif
+ terrno = errno;
+ Perror(stderr, "write failed", errno);
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ /*
+ * Receive length & response
+ */
+read_len:
+ cp = ans;
+ len = INT16SZ;
+ while ((n = read(s, (char *)cp, (int)len)) > 0) {
+ cp += n;
+ if ((len -= n) <= 0)
+ break;
+ }
+ if (n <= 0) {
+ terrno = errno;
+ Perror(stderr, "read failed", errno);
+ res_close();
+ /*
+ * A long running process might get its TCP
+ * connection reset if the remote server was
+ * restarted. Requery the server instead of
+ * trying a new one. When there is only one
+ * server, this means that a query might work
+ * instead of failing. We only allow one reset
+ * per query to prevent looping.
+ */
+ if (terrno == ECONNRESET && !connreset) {
+ connreset = 1;
+ res_close();
+ goto same_ns;
+ }
+ res_close();
+ goto next_ns;
+ }
+ resplen = ns_get16(ans);
+ if (resplen > anssiz) {
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; response truncated\n")
+ );
+ truncated = 1;
+ len = anssiz;
+ } else
+ len = resplen;
+ if (len < HFIXEDSZ) {
+ /*
+ * Undersized message.
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; undersized: %d\n", len));
+ terrno = EMSGSIZE;
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ cp = ans;
+ while (len != 0 &&
+ (n = read(s, (char *)cp, (int)len)) > 0) {
+ cp += n;
+ len -= n;
+ }
+ if (n <= 0) {
+ terrno = errno;
+ Perror(stderr, "read(vc)", errno);
+ res_close();
+ goto next_ns;
+ }
+ if (truncated) {
+ /*
+ * Flush rest of answer
+ * so connection stays in synch.
+ */
+ anhp->tc = 1;
+ len = resplen - anssiz;
+ while (len != 0) {
+ char junk[PACKETSZ];
+
+ n = (len > sizeof(junk)
+ ? sizeof(junk)
+ : len);
+ if ((n = read(s, junk, n)) > 0)
+ len -= n;
+ else
+ break;
+ }
+ }
+ /*
+ * The calling applicating has bailed out of
+ * a previous call and failed to arrange to have
+ * the circuit closed or the server has got
+ * itself confused. Anyway drop the packet and
+ * wait for the correct one.
+ */
+ if (hp->id != anhp->id) {
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; old answer (unexpected):\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto read_len;
+ }
+ } else {
+ /*
+ * Use datagrams.
+ */
+#ifndef NOPOLL
+ struct pollfd pfd;
+ int msec;
+#endif
+ struct timeval timeout;
+#ifndef NOSELECT
+ fd_set dsmask, *dsmaskp;
+ int dsmasklen;
+#endif
+ struct sockaddr_in from;
+ socklen_t fromlen;
+
+ if ((s < 0) || vc) {
+ if (vc)
+ res_close();
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+#ifndef CAN_RECONNECT
+ bad_dg_sock:
+#endif
+ terrno = errno;
+ Perror(stderr, "socket(dg)", errno);
+ return (-1);
+ }
+ connected = 0;
+ }
+#ifndef CANNOT_CONNECT_DGRAM
+ /*
+ * On a 4.3BSD+ machine (client and server,
+ * actually), sending to a nameserver datagram
+ * port with no nameserver will cause an
+ * ICMP port unreachable message to be returned.
+ * If our datagram socket is "connected" to the
+ * server, we get an ECONNREFUSED error on the next
+ * socket operation, and select returns if the
+ * error message is received. We can thus detect
+ * the absence of a nameserver without timing out.
+ * If we have sent queries to at least two servers,
+ * however, we don't want to remain connected,
+ * as we wish to receive answers from the first
+ * server to respond.
+ */
+ if (_res.nscount == 1 || (try == 0 && ns == 0)) {
+ /*
+ * Connect only if we are sure we won't
+ * receive a response from another server.
+ */
+ if (!connected) {
+ if (connect(s, (struct sockaddr *)nsap,
+ sizeof *nsap
+ ) < 0) {
+ Aerror(stderr,
+ "connect(dg)",
+ errno, *nsap);
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ connected = 1;
+ }
+ if (send(s, (char*)buf, buflen, 0) != buflen) {
+ Perror(stderr, "send", errno);
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ } else {
+ /*
+ * Disconnect if we want to listen
+ * for responses from more than one server.
+ */
+ if (connected) {
+#ifdef CAN_RECONNECT
+ struct sockaddr_in no_addr;
+
+ no_addr.sin_family = AF_INET;
+ no_addr.sin_addr.s_addr = INADDR_ANY;
+ no_addr.sin_port = 0;
+ (void) connect(s,
+ (struct sockaddr *)
+ &no_addr,
+ sizeof no_addr);
+#else
+ int s1 = socket(PF_INET, SOCK_DGRAM,0);
+ if (s1 < 0)
+ goto bad_dg_sock;
+ (void) dup2(s1, s);
+ (void) close(s1);
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; new DG socket\n"))
+#endif /* CAN_RECONNECT */
+ connected = 0;
+ errno = 0;
+ }
+#endif /* !CANNOT_CONNECT_DGRAM */
+ if (sendto(s, (char*)buf, buflen, 0,
+ (struct sockaddr *)nsap,
+ sizeof *nsap)
+ != buflen) {
+ Aerror(stderr, "sendto", errno, *nsap);
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+#ifndef CANNOT_CONNECT_DGRAM
+ }
+#endif /* !CANNOT_CONNECT_DGRAM */
+
+ /*
+ * Wait for reply
+ */
+#ifndef NOPOLL
+ othersyscall:
+ if (use_poll) {
+ msec = (_res.retrans << try) * 1000;
+ if (try > 0)
+ msec /= _res.nscount;
+ if (msec <= 0)
+ msec = 1000;
+ } else {
+#endif
+ timeout.tv_sec = (_res.retrans << try);
+ if (try > 0)
+ timeout.tv_sec /= _res.nscount;
+ if ((long) timeout.tv_sec <= 0)
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+#ifndef NOPOLL
+ }
+#endif
+ wait:
+ if (s < 0) {
+ Perror(stderr, "s out-of-bounds", EMFILE);
+ res_close();
+ goto next_ns;
+ }
+#ifndef NOPOLL
+ if (use_poll) {
+ struct sigaction sa, osa;
+ int sigsys_installed = 0;
+
+ pfd.fd = s;
+ pfd.events = POLLIN;
+ if (use_poll == 1) {
+ bzero(&sa, sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ if (sigaction(SIGSYS, &sa, &osa) >= 0)
+ sigsys_installed = 1;
+ }
+ n = poll(&pfd, 1, msec);
+ if (sigsys_installed == 1) {
+ int oerrno = errno;
+ sigaction(SIGSYS, &osa, NULL);
+ errno = oerrno;
+ }
+ /* XXX why does nosys() return EINVAL? */
+ if (n < 0 && (errno == ENOSYS ||
+ errno == EINVAL)) {
+ use_poll = 0;
+ goto othersyscall;
+ } else if (use_poll == 1)
+ use_poll = 2;
+ if (n < 0) {
+ if (errno == EINTR)
+ goto wait;
+ Perror(stderr, "poll", errno);
+ res_close();
+ goto next_ns;
+ }
+ } else {
+#endif
+#ifndef NOSELECT
+ dsmasklen = howmany(s + 1, NFDBITS) *
+ sizeof(fd_mask);
+ if (dsmasklen > sizeof(fd_set)) {
+ dsmaskp = (fd_set *)malloc(dsmasklen);
+ if (dsmaskp == NULL) {
+ res_close();
+ goto next_ns;
+ }
+ } else
+ dsmaskp = &dsmask;
+ /* only zero what we need */
+ bzero((char *)dsmaskp, dsmasklen);
+ FD_SET(s, dsmaskp);
+ n = select(s + 1, dsmaskp, (fd_set *)NULL,
+ (fd_set *)NULL, &timeout);
+ if (dsmaskp != &dsmask)
+ free(dsmaskp);
+ if (n < 0) {
+ if (errno == EINTR)
+ goto wait;
+ Perror(stderr, "select", errno);
+ res_close();
+ goto next_ns;
+ }
+#endif
+#ifndef NOPOLL
+ }
+#endif
+
+#ifdef NOSELECT
+ setsockopt (s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout);
+#else
+ if (n == 0) {
+ /*
+ * timeout
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; timeout\n"));
+ gotsomewhere = 1;
+ res_close();
+ goto next_ns;
+ }
+#endif
+ errno = 0;
+ fromlen = sizeof(struct sockaddr_in);
+ resplen = recvfrom(s, (char*)ans, anssiz, 0,
+ (struct sockaddr *)&from, &fromlen);
+ if (resplen <= 0) {
+#ifdef NOSELECT
+ if (errno == ETIMEDOUT) {
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; timeout\n"));
+ gotsomewhere = 1;
+ res_close();
+ goto next_ns;
+ }
+#endif
+ Perror(stderr, "recvfrom", errno);
+ res_close();
+ goto next_ns;
+ }
+ gotsomewhere = 1;
+ if (resplen < HFIXEDSZ) {
+ /*
+ * Undersized message.
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; undersized: %d\n",
+ resplen));
+ terrno = EMSGSIZE;
+ badns |= (1 << ns);
+ res_close();
+ goto next_ns;
+ }
+ if (hp->id != anhp->id) {
+ /*
+ * response from old query, ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; old answer:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto wait;
+ }
+#ifdef CHECK_SRVR_ADDR
+ if (!(_res.options & RES_INSECURE1) &&
+ !res_isourserver(&from)) {
+ /*
+ * response from wrong server? ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; not our server:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto wait;
+ }
+#endif
+ if (!(_res.options & RES_INSECURE2) &&
+ !res_queriesmatch(buf, buf + buflen,
+ ans, ans + anssiz)) {
+ /*
+ * response contains wrong query? ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; wrong query name:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto wait;
+ }
+ if (anhp->rcode == SERVFAIL ||
+ anhp->rcode == NOTIMP ||
+ anhp->rcode == REFUSED) {
+ DprintQ(_res.options & RES_DEBUG,
+ (stdout, "server rejected query:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ badns |= (1 << ns);
+ res_close();
+ /* don't retry if called from dig */
+ if (!_res.pfcode)
+ goto next_ns;
+ }
+ if (!(_res.options & RES_IGNTC) && anhp->tc) {
+ /*
+ * get rest of answer;
+ * use TCP with same server.
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; truncated answer\n"));
+ v_circuit = 1;
+ res_close();
+ goto same_ns;
+ }
+ } /*if vc/dg*/
+ Dprint((_res.options & RES_DEBUG) ||
+ ((_res.pfcode & RES_PRF_REPLY) &&
+ (_res.pfcode & RES_PRF_HEAD1)),
+ (stdout, ";; got answer:\n"));
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, "%s", ""),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ /*
+ * If using virtual circuits, we assume that the first server
+ * is preferred over the rest (i.e. it is on the local
+ * machine) and only keep that one open.
+ * If we have temporarily opened a virtual circuit,
+ * or if we haven't been asked to keep a socket open,
+ * close the socket.
+ */
+ if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
+ !(_res.options & RES_STAYOPEN)) {
+ res_close();
+ }
+ if (Rhook) {
+ int done = 0, loops = 0;
+
+ do {
+ res_sendhookact act;
+
+ act = (*Rhook)(nsap, buf, buflen,
+ ans, anssiz, &resplen);
+ switch (act) {
+ case res_goahead:
+ case res_done:
+ done = 1;
+ break;
+ case res_nextns:
+ res_close();
+ goto next_ns;
+ case res_modified:
+ /* give the hook another try */
+ if (++loops < 42) /*doug adams*/
+ break;
+ /*FALLTHROUGH*/
+ case res_error:
+ /*FALLTHROUGH*/
+ default:
+ return (-1);
+ }
+ } while (!done);
+
+ }
+ return (resplen);
+ next_ns: ;
+ } /*foreach ns*/
+ } /*foreach retry*/
+ res_close();
+ if (!v_circuit) {
+ if (!gotsomewhere)
+ errno = ECONNREFUSED; /* no nameservers found */
+ else
+ errno = ETIMEDOUT; /* no answer obtained */
+ } else
+ errno = terrno;
+ return (-1);
+}
+
+/*
+ * This routine is for closing the socket if a virtual circuit is used and
+ * the program wants to close it. This provides support for endhostent()
+ * which expects to close the socket.
+ *
+ * This routine is not expected to be user visible.
+ */
+void
+res_close()
+{
+ if (s >= 0) {
+ (void) close(s);
+ s = -1;
+ connected = 0;
+ vc = 0;
+ }
+}
diff --git a/cpukit/libnetworking/libc/res_stubs.c b/cpukit/libnetworking/libc/res_stubs.c
new file mode 100644
index 0000000000..92cf0fac54
--- /dev/null
+++ b/cpukit/libnetworking/libc/res_stubs.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 1996 Peter Wemm <peter@freebsd.org>.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+/*
+ * This file is for FreeBSD-3.0 that has a bind-4.9.5-P1 derived
+ * resolver in the libc. It provides aliases for functions that
+ * have moved since 4.9.4-P1.
+ *
+ * I'll save everybody the trouble and say it now: *THIS IS A HACK*!
+ *
+ * Yes, many of these are private functions to the resolver, but some are
+ * needed as there is no other way to provide the functionality and they've
+ * turned up all over the place. :-(
+ */
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+__weak_reference(__inet_addr, inet_addr);
+__weak_reference(__inet_aton, inet_aton);
+__weak_reference(__inet_lnaof, inet_lnaof);
+__weak_reference(__inet_makeaddr, inet_makeaddr);
+__weak_reference(__inet_neta, inet_neta);
+__weak_reference(__inet_netof, inet_netof);
+__weak_reference(__inet_network, inet_network);
+__weak_reference(__inet_net_ntop, inet_net_ntop);
+__weak_reference(__inet_net_pton, inet_net_pton);
+__weak_reference(__inet_ntoa, inet_ntoa);
+__weak_reference(__inet_pton, inet_pton);
+__weak_reference(__inet_ntop, inet_ntop);
+__weak_reference(__inet_nsap_addr, inet_nsap_addr);
+__weak_reference(__inet_nsap_ntoa, inet_nsap_ntoa);
+
+__weak_reference(__sym_ston, sym_ston);
+__weak_reference(__sym_ntos, sym_ntos);
+__weak_reference(__sym_ntop, sym_ntop);
+__weak_reference(__fp_resstat, fp_resstat);
+__weak_reference(__p_query, p_query);
+__weak_reference(__p_fqnname, p_fqnname);
+__weak_reference(__p_secstodate, p_secstodate);
+__weak_reference(__dn_count_labels, dn_count_labels);
+__weak_reference(__dn_comp, dn_comp);
+__weak_reference(__res_close, _res_close);
+__weak_reference(__dn_expand, dn_expand);
+__weak_reference(__res_init, res_init);
+__weak_reference(__res_query, res_query);
+__weak_reference(__res_search, res_search);
+__weak_reference(__res_querydomain, res_querydomain);
+__weak_reference(__res_mkquery, res_mkquery);
+__weak_reference(__res_send, res_send);
diff --git a/cpukit/libnetworking/libc/res_update.c b/cpukit/libnetworking/libc/res_update.c
new file mode 100644
index 0000000000..ef591e0674
--- /dev/null
+++ b/cpukit/libnetworking/libc/res_update.c
@@ -0,0 +1,518 @@
+#if !defined(__rtems__)
+#if !defined(lint) && !defined(SABER)
+static char rcsid[] = "$Id$";
+#endif /* not lint */
+#endif /* not rtems */
+
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Based on the Dynamic DNS reference implementation by Viraj Bais
+ * <viraj_bais@ccm.fm.intel.com>
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <limits.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * Separate a linked list of records into groups so that all records
+ * in a group will belong to a single zone on the nameserver.
+ * Create a dynamic update packet for each zone and send it to the
+ * nameservers for that zone, and await answer.
+ * Abort if error occurs in updating any zone.
+ * Return the number of zones updated on success, < 0 on error.
+ *
+ * On error, caller must deal with the unsynchronized zones
+ * eg. an A record might have been successfully added to the forward
+ * zone but the corresponding PTR record would be missing if error
+ * was encountered while updating the reverse zone.
+ */
+
+#define NSMAX 16
+
+struct ns1 {
+ char nsname[MAXDNAME];
+ struct in_addr nsaddr1;
+};
+
+struct zonegrp {
+ char z_origin[MAXDNAME];
+ int16_t z_class;
+ char z_soardata[MAXDNAME + 5 * INT32SZ];
+ struct ns1 z_ns[NSMAX];
+ int z_nscount;
+ ns_updrec * z_rr;
+ struct zonegrp *z_next;
+};
+
+
+int
+res_update(ns_updrec *rrecp_in) {
+ ns_updrec *rrecp, *tmprrecp;
+ u_char buf[PACKETSZ], answer[PACKETSZ], packet[2*PACKETSZ];
+ char name[MAXDNAME], zname[MAXDNAME], primary[MAXDNAME],
+ mailaddr[MAXDNAME];
+ u_char soardata[2*MAXCDNAME+5*INT32SZ];
+ char *dname, *svdname, *cp1, *target;
+ u_char *cp, *eom;
+ HEADER *hp = (HEADER *) answer;
+ struct zonegrp *zptr = NULL, *tmpzptr, *prevzptr, *zgrp_start = NULL;
+ int i, j, k = 0, n, ancount, nscount, arcount, rcode, rdatasize,
+ newgroup, done, myzone, seen_before, numzones = 0;
+ u_int16_t dlen, class, qclass, type, qtype;
+ u_int32_t ttl;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+
+ for (rrecp = rrecp_in; rrecp; rrecp = rrecp->r_next) {
+ dname = rrecp->r_dname;
+ n = strlen(dname);
+ if (dname[n-1] == '.')
+ dname[n-1] = '\0';
+ qtype = T_SOA;
+ qclass = rrecp->r_class;
+ done = 0;
+ seen_before = 0;
+
+ while (!done && dname) {
+ if (qtype == T_SOA) {
+ for (tmpzptr = zgrp_start;
+ tmpzptr && !seen_before;
+ tmpzptr = tmpzptr->z_next) {
+ if (strcasecmp(dname,
+ tmpzptr->z_origin) == 0 &&
+ tmpzptr->z_class == qclass)
+ seen_before++;
+ for (tmprrecp = tmpzptr->z_rr;
+ tmprrecp && !seen_before;
+ tmprrecp = tmprrecp->r_grpnext)
+ if (strcasecmp(dname, tmprrecp->r_dname) == 0
+ && tmprrecp->r_class == qclass) {
+ seen_before++;
+ break;
+ }
+ if (seen_before) {
+ /*
+ * Append to the end of
+ * current group.
+ */
+ for (tmprrecp = tmpzptr->z_rr;
+ tmprrecp->r_grpnext;
+ tmprrecp = tmprrecp->r_grpnext)
+ (void)NULL;
+ tmprrecp->r_grpnext = rrecp;
+ rrecp->r_grpnext = NULL;
+ done = 1;
+ break;
+ }
+ }
+ } else if (qtype == T_A) {
+ for (tmpzptr = zgrp_start;
+ tmpzptr && !done;
+ tmpzptr = tmpzptr->z_next)
+ for (i = 0; i < tmpzptr->z_nscount; i++)
+ if (tmpzptr->z_class == qclass &&
+ strcasecmp(tmpzptr->z_ns[i].nsname,
+ dname) == 0 &&
+ tmpzptr->z_ns[i].nsaddr1.s_addr != 0) {
+ zptr->z_ns[k].nsaddr1.s_addr =
+ tmpzptr->z_ns[i].nsaddr1.s_addr;
+ done = 1;
+ break;
+ }
+ }
+ if (done)
+ break;
+ n = res_mkquery(QUERY, dname, qclass, qtype, NULL,
+ 0, NULL, buf, sizeof buf);
+ if (n <= 0) {
+ fprintf(stderr, "res_update: mkquery failed\n");
+ return (n);
+ }
+ n = res_send(buf, n, answer, sizeof answer);
+ if (n < 0) {
+ fprintf(stderr, "res_update: send error for %s\n",
+ rrecp->r_dname);
+ return (n);
+ }
+ if (n < HFIXEDSZ)
+ return (-1);
+ ancount = ntohs(hp->ancount);
+ nscount = ntohs(hp->nscount);
+ arcount = ntohs(hp->arcount);
+ rcode = hp->rcode;
+ cp = answer + HFIXEDSZ;
+ eom = answer + n;
+ /* skip the question section */
+ n = dn_skipname(cp, eom);
+ if (n < 0 || cp + n + 2 * INT16SZ > eom)
+ return (-1);
+ cp += n + 2 * INT16SZ;
+
+ if (qtype == T_SOA) {
+ if (ancount == 0 && nscount == 0 && arcount == 0) {
+ /*
+ * if (rcode == NOERROR) then the dname exists but
+ * has no soa record associated with it.
+ * if (rcode == NXDOMAIN) then the dname does not
+ * exist and the server is replying out of NCACHE.
+ * in either case, proceed with the next try
+ */
+ dname = strchr(dname, '.');
+ if (dname != NULL)
+ dname++;
+ continue;
+ } else if ((rcode == NOERROR || rcode == NXDOMAIN) &&
+ ancount == 0 &&
+ nscount == 1 && arcount == 0) {
+ /*
+ * name/data does not exist, soa record supplied in the
+ * authority section
+ */
+ /* authority section must contain the soa record */
+ if ((n = dn_expand(answer, eom, cp, zname,
+ sizeof zname)) < 0)
+ return (n);
+ cp += n;
+ if (cp + 2 * INT16SZ > eom)
+ return (-1);
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ if (type != T_SOA || class != qclass) {
+ fprintf(stderr, "unknown answer\n");
+ return (-1);
+ }
+ myzone = 0;
+ svdname = dname;
+ while (dname)
+ if (strcasecmp(dname, zname) == 0) {
+ myzone = 1;
+ break;
+ } else if ((dname = strchr(dname, '.')) != NULL)
+ dname++;
+ if (!myzone) {
+ dname = strchr(svdname, '.');
+ if (dname != NULL)
+ dname++;
+ continue;
+ }
+ nscount = 0;
+ /* fallthrough */
+ } else if (rcode == NOERROR && ancount == 1) {
+ /*
+ * found the zone name
+ * new servers will supply NS records for the zone
+ * in authority section and A records for those
+ * nameservers in the additional section
+ * older servers have to be explicitly queried for
+ * NS records for the zone
+ */
+ /* answer section must contain the soa record */
+ if ((n = dn_expand(answer, eom, cp, zname,
+ sizeof zname)) < 0)
+ return (n);
+ else
+ cp += n;
+ if (cp + 2 * INT16SZ > eom)
+ return (-1);
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ if (type == T_CNAME) {
+ dname = strchr(dname, '.');
+ if (dname != NULL)
+ dname++;
+ continue;
+ }
+ if (strcasecmp(dname, zname) != 0 ||
+ type != T_SOA ||
+ class != rrecp->r_class) {
+ fprintf(stderr, "unknown answer\n");
+ return (-1);
+ }
+ /* FALLTHROUGH */
+ } else {
+ fprintf(stderr,
+ "unknown response: ans=%d, auth=%d, add=%d, rcode=%d\n",
+ ancount, nscount, arcount, hp->rcode);
+ return (-1);
+ }
+ if (cp + INT32SZ + INT16SZ > eom)
+ return (-1);
+ /* continue processing the soa record */
+ GETLONG(ttl, cp);
+ GETSHORT(dlen, cp);
+ if (cp + dlen > eom)
+ return (-1);
+ newgroup = 1;
+ zptr = zgrp_start;
+ prevzptr = NULL;
+ while (zptr) {
+ if (strcasecmp(zname, zptr->z_origin) == 0 &&
+ type == T_SOA && class == qclass) {
+ newgroup = 0;
+ break;
+ }
+ prevzptr = zptr;
+ zptr = zptr->z_next;
+ }
+ if (!newgroup) {
+ for (tmprrecp = zptr->z_rr;
+ tmprrecp->r_grpnext;
+ tmprrecp = tmprrecp->r_grpnext)
+ ;
+ tmprrecp->r_grpnext = rrecp;
+ rrecp->r_grpnext = NULL;
+ done = 1;
+ cp += dlen;
+ break;
+ } else {
+ if ((n = dn_expand(answer, eom, cp, primary,
+ sizeof primary)) < 0)
+ return (n);
+ cp += n;
+ /*
+ * We don't have to bounds check here because the
+ * next use of 'cp' is in dn_expand().
+ */
+ cp1 = (char *)soardata;
+ strcpy(cp1, primary);
+ cp1 += strlen(cp1) + 1;
+ if ((n = dn_expand(answer, eom, cp, mailaddr,
+ sizeof mailaddr)) < 0)
+ return (n);
+ cp += n;
+ strcpy(cp1, mailaddr);
+ cp1 += strlen(cp1) + 1;
+ if (cp + 5*INT32SZ > eom)
+ return (-1);
+ memcpy(cp1, cp, 5*INT32SZ);
+ cp += 5*INT32SZ;
+ cp1 += 5*INT32SZ;
+ rdatasize = (u_char *)cp1 - soardata;
+ zptr = calloc(1, sizeof(struct zonegrp));
+ if (zptr == NULL)
+ return (-1);
+ if (zgrp_start == NULL)
+ zgrp_start = zptr;
+ else
+ prevzptr->z_next = zptr;
+ zptr->z_rr = rrecp;
+ rrecp->r_grpnext = NULL;
+ strcpy(zptr->z_origin, zname);
+ zptr->z_class = class;
+ memcpy(zptr->z_soardata, soardata, rdatasize);
+ /* fallthrough to process NS and A records */
+ }
+ } else if (qtype == T_NS) {
+ if (rcode == NOERROR && ancount > 0) {
+ strcpy(zname, dname);
+ for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {
+ if (strcasecmp(zname, zptr->z_origin) == 0)
+ break;
+ }
+ if (zptr == NULL)
+ /* should not happen */
+ return (-1);
+ if (nscount > 0) {
+ /*
+ * answer and authority sections contain
+ * the same information, skip answer section
+ */
+ for (j = 0; j < ancount; j++) {
+ n = dn_skipname(cp, eom);
+ if (n < 0)
+ return (-1);
+ n += 2*INT16SZ + INT32SZ;
+ if (cp + n + INT16SZ > eom)
+ return (-1);
+ cp += n;
+ GETSHORT(dlen, cp);
+ cp += dlen;
+ }
+ } else
+ nscount = ancount;
+ /* fallthrough to process NS and A records */
+ } else {
+ fprintf(stderr, "cannot determine nameservers for %s:\
+ans=%d, auth=%d, add=%d, rcode=%d\n",
+ dname, ancount, nscount, arcount, hp->rcode);
+ return (-1);
+ }
+ } else if (qtype == T_A) {
+ if (rcode == NOERROR && ancount > 0) {
+ arcount = ancount;
+ ancount = nscount = 0;
+ /* fallthrough to process A records */
+ } else {
+ fprintf(stderr, "cannot determine address for %s:\
+ans=%d, auth=%d, add=%d, rcode=%d\n",
+ dname, ancount, nscount, arcount, hp->rcode);
+ return (-1);
+ }
+ }
+ /* process NS records for the zone */
+ j = 0;
+ for (i = 0; i < nscount; i++) {
+ if ((n = dn_expand(answer, eom, cp, name,
+ sizeof name)) < 0)
+ return (n);
+ cp += n;
+ if (cp + 3 * INT16SZ + INT32SZ > eom)
+ return (-1);
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ GETLONG(ttl, cp);
+ GETSHORT(dlen, cp);
+ if (cp + dlen > eom)
+ return (-1);
+ if (strcasecmp(name, zname) == 0 &&
+ type == T_NS && class == qclass) {
+ if ((n = dn_expand(answer, eom, cp,
+ name, sizeof name)) < 0)
+ return (n);
+ target = zptr->z_ns[j++].nsname;
+ strcpy(target, name);
+ }
+ cp += dlen;
+ }
+ if (zptr->z_nscount == 0)
+ zptr->z_nscount = j;
+ /* get addresses for the nameservers */
+ for (i = 0; i < arcount; i++) {
+ if ((n = dn_expand(answer, eom, cp, name,
+ sizeof name)) < 0)
+ return (n);
+ cp += n;
+ if (cp + 3 * INT16SZ + INT32SZ > eom)
+ return (-1);
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ GETLONG(ttl, cp);
+ GETSHORT(dlen, cp);
+ if (cp + dlen > eom)
+ return (-1);
+ if (type == T_A && dlen == INT32SZ && class == qclass) {
+ for (j = 0; j < zptr->z_nscount; j++)
+ if (strcasecmp(name, zptr->z_ns[j].nsname) == 0) {
+ memcpy(&zptr->z_ns[j].nsaddr1.s_addr, cp,
+ INT32SZ);
+ break;
+ }
+ }
+ cp += dlen;
+ }
+ if (zptr->z_nscount == 0) {
+ dname = zname;
+ qtype = T_NS;
+ continue;
+ }
+ done = 1;
+ for (k = 0; k < zptr->z_nscount; k++)
+ if (zptr->z_ns[k].nsaddr1.s_addr == 0) {
+ done = 0;
+ dname = zptr->z_ns[k].nsname;
+ qtype = T_A;
+ }
+
+ } /* while */
+ }
+
+ _res.options |= RES_DEBUG;
+ for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {
+
+ /* append zone section */
+ rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin,
+ zptr->z_class, ns_t_soa, 0);
+ if (rrecp == NULL) {
+ fprintf(stderr, "saverrec error\n");
+ fflush(stderr);
+ return (-1);
+ }
+ rrecp->r_grpnext = zptr->z_rr;
+ zptr->z_rr = rrecp;
+
+ n = res_mkupdate(zptr->z_rr, packet, sizeof packet);
+ if (n < 0) {
+ fprintf(stderr, "res_mkupdate error\n");
+ fflush(stderr);
+ return (-1);
+ } else
+ fprintf(stdout, "res_mkupdate: packet size = %d\n", n);
+
+ /*
+ * Override the list of NS records from res_init() with
+ * the authoritative nameservers for the zone being updated.
+ * Sort primary to be the first in the list of nameservers.
+ */
+ for (i = 0; i < zptr->z_nscount; i++) {
+ if (strcasecmp(zptr->z_ns[i].nsname,
+ zptr->z_soardata) == 0) {
+ struct in_addr tmpaddr;
+
+ if (i != 0) {
+ strcpy(zptr->z_ns[i].nsname,
+ zptr->z_ns[0].nsname);
+ strcpy(zptr->z_ns[0].nsname,
+ zptr->z_soardata);
+ tmpaddr = zptr->z_ns[i].nsaddr1;
+ zptr->z_ns[i].nsaddr1 =
+ zptr->z_ns[0].nsaddr1;
+ zptr->z_ns[0].nsaddr1 = tmpaddr;
+ }
+ break;
+ }
+ }
+ for (i = 0; i < MAXNS; i++) {
+ _res.nsaddr_list[i].sin_addr = zptr->z_ns[i].nsaddr1;
+ _res.nsaddr_list[i].sin_family = AF_INET;
+ _res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
+ }
+ _res.nscount = (zptr->z_nscount < MAXNS) ?
+ zptr->z_nscount : MAXNS;
+ n = res_send(packet, n, answer, sizeof(answer));
+ if (n < 0) {
+ fprintf(stderr, "res_send: send error, n=%d\n", n);
+ break;
+ } else
+ numzones++;
+ }
+
+ /* free malloc'ed memory */
+ while(zgrp_start) {
+ zptr = zgrp_start;
+ zgrp_start = zgrp_start->z_next;
+ res_freeupdrec(zptr->z_rr); /* Zone section we allocated. */
+ free((char *)zptr);
+ }
+
+ return (numzones);
+}
diff --git a/cpukit/libnetworking/libc/resolver.3 b/cpukit/libnetworking/libc/resolver.3
new file mode 100644
index 0000000000..8c6f18334f
--- /dev/null
+++ b/cpukit/libnetworking/libc/resolver.3
@@ -0,0 +1,352 @@
+.\" Copyright (c) 1985, 1991, 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.
+.\"
+.\" @(#)resolver.3 8.1 (Berkeley) 6/4/93
+.\" $Id$
+.\"
+.Dd June 4, 1993
+.Dt RESOLVER 3
+.Os BSD 4.3
+.Sh NAME
+.Nm res_query ,
+.Nm res_search ,
+.Nm res_mkquery ,
+.Nm res_send ,
+.Nm res_init ,
+.Nm dn_comp ,
+.Nm dn_expand
+.Nd resolver routines
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <netinet/in.h>
+.Fd #include <arpa/nameser.h>
+.Fd #include <resolv.h>
+.Ft int
+.Fo res_query
+.Fa "const char *dname"
+.Fa "int class"
+.Fa "int type"
+.Fa "u_char *answer"
+.Fa "int anslen"
+.Fc
+.Ft int
+.Fo res_search
+.Fa "const char *dname"
+.Fa "int class"
+.Fa "int type"
+.Fa "u_char *answer"
+.Fa "int anslen"
+.Fc
+.Ft int
+.Fo res_mkquery
+.Fa "int op"
+.Fa "const char *dname"
+.Fa "int class"
+.Fa "int type"
+.Fa "const u_char *data"
+.Fa "int datalen"
+.Fa "const u_char *newrr_in"
+.Fa "u_char *buf"
+.Fa "int buflen"
+.Fc
+.Ft int
+.Fo res_send
+.Fa "const u_char *msg"
+.Fa "int msglen"
+.Fa "u_char *answer"
+.Fa "int anslen"
+.Fc
+.Ft int
+.Fn res_init
+.Fo dn_comp
+.Fa "const char *exp_dn"
+.Fa "u_char *comp_dn"
+.Fa "int length"
+.Fa "u_char **dnptrs"
+.Fa "u_char **lastdnptr"
+.Fc
+.Ft int
+.Fo dn_expand
+.Fa "const u_char *msg"
+.Fa "const u_char *eomorig"
+.Fa "const u_char *comp_dn"
+.Fa "char *exp_dn"
+.Fa "int length"
+.Fc
+.Sh DESCRIPTION
+These routines are used for making, sending and interpreting
+query and reply messages with Internet domain name servers.
+.Pp
+Global configuration and state information that is used by the
+resolver routines is kept in the structure
+.Em _res .
+Most of the values have reasonable defaults and can be ignored.
+Options
+stored in
+.Em _res.options
+are defined in
+.Pa resolv.h
+and are as follows.
+Options are stored as a simple bit mask containing the bitwise ``or''
+of the options enabled.
+.Bl -tag -width RES_DEFNAMES
+.It Dv RES_INIT
+True if the initial name server address and default domain name are
+initialized (i.e.,
+.Fn res_init
+has been called).
+.It Dv RES_DEBUG
+Print debugging messages.
+.It Dv RES_AAONLY
+Accept authoritative answers only.
+With this option,
+.Fn res_send
+should continue until it finds an authoritative answer or finds an error.
+Currently this is not implemented.
+.It Dv RES_USEVC
+Use
+.Tn TCP
+connections for queries instead of
+.Tn UDP
+datagrams.
+.It Dv RES_STAYOPEN
+Used with
+.Dv RES_USEVC
+to keep the
+.Tn TCP
+connection open between
+queries.
+This is useful only in programs that regularly do many queries.
+.Tn UDP
+should be the normal mode used.
+.It Dv RES_IGNTC
+Unused currently (ignore truncation errors, i.e., don't retry with
+.Tn TCP ) .
+.It Dv RES_RECURSE
+Set the recursion-desired bit in queries.
+This is the default.
+.Pf ( Fn res_send
+does not do iterative queries and expects the name server
+to handle recursion.)
+.It Dv RES_DEFNAMES
+If set,
+.Fn res_search
+will append the default domain name to single-component names
+(those that do not contain a dot).
+This option is enabled by default.
+.It Dv RES_DNSRCH
+If this option is set,
+.Fn res_search
+will search for host names in the current domain and in parent domains; see
+.Xr hostname 7 .
+This is used by the standard host lookup routine
+.Xr gethostbyname 3 .
+This option is enabled by default.
+.It Dv RES_NOALIASES
+This option turns off the user level aliasing feature controlled by the
+.Dq Ev HOSTALIASES
+environment variable. Network daemons should set this option.
+.El
+.Pp
+The
+.Fn res_init
+routine
+reads the configuration file (if any; see
+.Xr resolver 5 )
+to get the default domain name,
+search list and
+the Internet address of the local name server(s).
+If no server is configured, the host running
+the resolver is tried.
+The current domain name is defined by the hostname
+if not specified in the configuration file;
+it can be overridden by the environment variable
+.Ev LOCALDOMAIN .
+This environment variable may contain several blank-separated
+tokens if you wish to override the
+.Em "search list"
+on a per-process basis. This is similar to the
+.Em search
+command in the configuration file.
+Another environment variable (
+.Dq Ev RES_OPTIONS
+can be set to
+override certain internal resolver options which are otherwise
+set by changing fields in the
+.Em _res
+structure or are inherited from the configuration file's
+.Em options
+command. The syntax of the
+.Dq Ev RES_OPTIONS
+environment variable is explained in
+.Xr resolver 5 .
+Initialization normally occurs on the first call
+to one of the following routines.
+.Pp
+The
+.Fn res_query
+function provides an interface to the server query mechanism.
+It constructs a query, sends it to the local server,
+awaits a response, and makes preliminary checks on the reply.
+The query requests information of the specified
+.Fa type
+and
+.Fa class
+for the specified fully-qualified domain name
+.Fa dname .
+The reply message is left in the
+.Fa answer
+buffer with length
+.Fa anslen
+supplied by the caller.
+.Pp
+The
+.Fn res_search
+routine makes a query and awaits a response like
+.Fn res_query ,
+but in addition, it implements the default and search rules
+controlled by the
+.Dv RES_DEFNAMES
+and
+.Dv RES_DNSRCH
+options.
+It returns the first successful reply.
+.Pp
+The remaining routines are lower-level routines used by
+.Fn res_query .
+The
+.Fn res_mkquery
+function
+constructs a standard query message and places it in
+.Fa buf .
+It returns the size of the query, or \-1 if the query is
+larger than
+.Fa buflen .
+The query type
+.Fa op
+is usually
+.Dv QUERY ,
+but can be any of the query types defined in
+.Aq Pa arpa/nameser.h .
+The domain name for the query is given by
+.Fa dname .
+.Fa Newrr
+is currently unused but is intended for making update messages.
+.Pp
+The
+.Fn res_send
+routine
+sends a pre-formatted query and returns an answer.
+It will call
+.Fn res_init
+if
+.Dv RES_INIT
+is not set, send the query to the local name server, and
+handle timeouts and retries.
+The length of the reply message is returned, or
+\-1 if there were errors.
+.Pp
+The
+.Fn dn_comp
+function
+compresses the domain name
+.Fa exp_dn
+and stores it in
+.Fa comp_dn .
+The size of the compressed name is returned or \-1 if there were errors.
+The size of the array pointed to by
+.Fa comp_dn
+is given by
+.Fa length .
+The compression uses
+an array of pointers
+.Fa dnptrs
+to previously-compressed names in the current message.
+The first pointer points to
+to the beginning of the message and the list ends with
+.Dv NULL .
+The limit to the array is specified by
+.Fa lastdnptr .
+A side effect of
+.Fn dn_comp
+is to update the list of pointers for
+labels inserted into the message
+as the name is compressed.
+If
+.Em dnptr
+is
+.Dv NULL, names are not compressed.
+If
+.Fa lastdnptr
+is
+.Dv NULL ,
+the list of labels is not updated.
+.Pp
+The
+.Fn dn_expand
+entry
+expands the compressed domain name
+.Fa comp_dn
+to a full domain name
+The compressed name is contained in a query or reply message;
+.Fa msg
+is a pointer to the beginning of the message.
+The uncompressed name is placed in the buffer indicated by
+.Fa exp_dn
+which is of size
+.Fa length .
+The size of compressed name is returned or \-1 if there was an error.
+.Sh FILES
+.Bl -tag -width Pa
+/etc/resolv.conf
+The configuration file
+see
+.Xr resolver 5 .
+.El
+.Sh SEE ALSO
+.Xr gethostbyname 3 ,
+.Xr resolver 5 ,
+.Xr hostname 7 ,
+.Xr named 8
+.Pp
+.%T RFC1032 ,
+.%T RFC1033 ,
+.%T RFC1034 ,
+.%T RFC1035 ,
+.%T RFC974
+.Rs
+.%T "Name Server Operations Guide for BIND"
+.Re
+.Sh HISTORY
+The
+.Nm
+function appeared in
+.Bx 4.3 .
diff --git a/cpukit/libnetworking/libc/send.c b/cpukit/libnetworking/libc/send.c
new file mode 100644
index 0000000000..ad14bd3cd2
--- /dev/null
+++ b/cpukit/libnetworking/libc/send.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1988, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)send.c 8.2 (Berkeley) 2/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <stddef.h>
+
+ssize_t
+send(s, msg, len, flags)
+ int s, flags;
+ size_t len;
+ const void *msg;
+{
+ return (sendto(s, msg, len, flags, NULL, 0));
+}
diff --git a/cpukit/libnetworking/libc/strsep.c b/cpukit/libnetworking/libc/strsep.c
new file mode 100644
index 0000000000..182319493d
--- /dev/null
+++ b/cpukit/libnetworking/libc/strsep.c
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 1990, 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <string.h>
+#include <stdio.h>
+
+/*
+ * Get next token from string *stringp, where tokens are possibly-empty
+ * strings separated by characters from delim.
+ *
+ * Writes NULs into the string at *stringp to end tokens.
+ * delim need not remain constant from call to call.
+ * On return, *stringp points past the last NUL written (if there might
+ * be further tokens), or is NULL (if there are definitely no more tokens).
+ *
+ * If *stringp is NULL, strsep returns NULL.
+ *
+ * PUBLIC: #ifndef HAVE_STRSEP
+ * PUBLIC: char *strsep __P((char **, const char *));
+ * PUBLIC: #endif
+ */
+char *
+strsep(stringp, delim)
+ register char **stringp;
+ register const char *delim;
+{
+ register char *s;
+ register const char *spanp;
+ register int c, sc;
+ char *tok;
+
+ if ((s = *stringp) == NULL)
+ return (NULL);
+ for (tok = s;;) {
+ c = *s++;
+ spanp = delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *stringp = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
diff --git a/cpukit/libnetworking/loop.h b/cpukit/libnetworking/loop.h
new file mode 100644
index 0000000000..34e0b828e4
--- /dev/null
+++ b/cpukit/libnetworking/loop.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+#define NLOOP 1
diff --git a/cpukit/libnetworking/machine/conf.h b/cpukit/libnetworking/machine/conf.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/machine/conf.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/machine/cpu.h b/cpukit/libnetworking/machine/cpu.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/machine/cpu.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/machine/cpufunc.h b/cpukit/libnetworking/machine/cpufunc.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/machine/cpufunc.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/machine/endian.h b/cpukit/libnetworking/machine/endian.h
new file mode 100644
index 0000000000..6faa8f1a71
--- /dev/null
+++ b/cpukit/libnetworking/machine/endian.h
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ */
+
+#ifndef _MACHINE_ENDIAN_H_
+#define _MACHINE_ENDIAN_H_
+
+#include <rtems.h>
+
+/*
+ * BSD-style endian declaration
+ */
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234
+
+#ifndef BYTE_ORDER
+#if CPU_BIG_ENDIAN
+# define BYTE_ORDER BIG_ENDIAN
+#elif CPU_LITTLE_ENDIAN
+# define BYTE_ORDER LITTLE_ENDIAN
+#else
+# error "Can't decide which end is which!"
+#endif
+#endif
+
+#if ( CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES == FALSE )
+
+#if ( CPU_BIG_ENDIAN == TRUE )
+
+/*
+ * Very simply on big endian CPUs
+ */
+
+#define ntohl(_x) (_x)
+#define ntohs(_x) (_x)
+#define htonl(_x) (_x)
+#define htons(_x) (_x)
+
+#define NTOHS(x)
+#define HTONS(x)
+#define NTOHL(x)
+#define HTONL(x)
+
+#elif ( CPU_LITTLE_ENDIAN == TRUE )
+
+/*
+ * A little more complicated on little endian CPUs
+ */
+
+#define ntohl(_x) ((long) CPU_swap_u32((uint32_t )_x))
+#define ntohs(_x) ((short) CPU_swap_u16((uint16_t )_x))
+#define htonl(_x) ((long) CPU_swap_u32((uint32_t )_x))
+#define htons(_x) ((short) CPU_swap_u16((uint16_t )_x))
+
+#define NTOHS(x) (x) = ntohs(x)
+#define HTONS(x) (x) = htons(x)
+#define NTOHL(x) (x) = ntohl(x)
+#define HTONL(x) (x) = htonl(x)
+
+#else
+#error "Unknown endian-ness for this cpu"
+#endif
+
+#endif /* CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES */
+
+#endif /* _MACHINE_ENDIAN_H_ */
diff --git a/cpukit/libnetworking/machine/in_cksum.h b/cpukit/libnetworking/machine/in_cksum.h
new file mode 100644
index 0000000000..e673f3854d
--- /dev/null
+++ b/cpukit/libnetworking/machine/in_cksum.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 1990 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.
+ *
+ * from tahoe: in_cksum.c 1.2 86/01/05
+ * from: @(#)in_cksum.c 1.3 (Berkeley) 1/19/91
+ * from: Id: in_cksum.c,v 1.8 1995/12/03 18:35:19 bde Exp
+ * $Id$
+ */
+
+#ifndef _MACHINE_IN_CKSUM_H_
+#define _MACHINE_IN_CKSUM_H_ 1
+
+#include <sys/cdefs.h>
+
+/*
+ * It it useful to have an Internet checksum routine which is inlineable
+ * and optimized specifically for the task of computing IP header checksums
+ * in the normal case (where there are no options and the header length is
+ * therefore always exactly five 32-bit words.
+ */
+
+/*
+ * Optimized version for the i386 family
+ */
+
+#if (defined(__GNUC__) && defined(__i386__))
+
+static __inline u_int
+in_cksum_hdr(const struct ip *ip)
+{
+ register u_int sum = ((const uint32_t*)ip)[0];
+ register u_int tmp;
+
+ __asm__ __volatile__(
+ " addl %2, %0 \n"
+ " adcl %3, %0 \n"
+ " adcl %4, %0 \n"
+ " adcl %5, %0 \n"
+ " adcl $0, %0 \n"
+ " movl %0, %1 \n"
+ " roll $16, %0 \n"
+ " addl %1, %0 \n"
+ :"+&r"(sum),"=&r"(tmp)
+ :"g"(((const uint32_t*)ip)[1]),
+ "g"(((const uint32_t*)ip)[2]),
+ "g"(((const uint32_t*)ip)[3]),
+ "g"(((const uint32_t*)ip)[4]),
+ "m"(*ip)
+ :"cc"
+ );
+
+ return (~sum) >>16;
+}
+
+static __inline void
+in_cksum_update(struct ip *ip)
+{
+ int __tmpsum;
+ __tmpsum = (int)ntohs(ip->ip_sum) + 256;
+ ip->ip_sum = htons(__tmpsum + (__tmpsum >> 16));
+}
+
+/*
+ * Optimized version for the MC68xxx and Coldfire families
+ */
+
+#elif (defined(__GNUC__) && (defined(__mc68000__) || defined(__m68k__)))
+
+static __inline__ u_int
+in_cksum_hdr(const struct ip *ip)
+{
+ register u_int *ap = (u_int *)ip;
+ register u_int sum = *ap++;
+ register u_int tmp;
+
+ __asm__ __volatile__("addl %2@+,%0\n\t"
+ "movel %2@+,%1\n\t"
+ "addxl %1,%0\n\t"
+ "movel %2@+,%1\n\t"
+ "addxl %1,%0\n\t"
+ "movel %2@,%1\n\t"
+ "addxl %1,%0\n\t"
+ "moveq #0,%1\n\t"
+ "addxl %1,%0\n" :
+ "=d" (sum), "=d" (tmp), "=a" (ap) :
+ "0" (sum), "2" (ap), "m"(*ip));
+ sum = (sum & 0xffff) + (sum >> 16);
+ if (sum > 0xffff)
+ sum -= 0xffff;
+ return ~sum & 0xffff;
+}
+
+/*
+ * Optimized version for the PowerPC family
+ */
+
+#elif (defined(__GNUC__) && (defined(__PPC__) || defined(__ppc__)))
+
+static __inline u_int
+in_cksum_hdr(const struct ip *ip)
+{
+register u_int sum, tmp;
+ __asm__ __volatile__(
+ " lwz %0, 0(%2) \n"
+ " lwz %1, 4(%2) \n"
+ " addc %0, %0, %1 \n" /* generate carry (XER[CA]) */
+ " lwz %1, 8(%2) \n"
+ " adde %0, %0, %1 \n" /* add + generate */
+ " lwz %1, 12(%2) \n"
+ " adde %0, %0, %1 \n"
+ " lwz %1, 16(%2) \n"
+ " adde %0, %0, %1 \n"
+ " addze %0, %0 \n" /* mop up XER[CA] */
+ " rotlwi %1, %0,16 \n" /* word-swapped copy in %1 */
+ " add %0, %0, %1 \n" /* see comment below */
+ " not %0, %0 \n"
+ " srwi %0, %0, 16 \n"
+ :"=&r"(sum),"=&r"(tmp):"b"(ip), "m"(*ip):"xer"
+ );
+ /* Note: if 'add' generates a carry out of the lower 16 bits
+ * then this is automatically added to the upper 16 bits
+ * where the correct result is found. (Stolen from linux.)
+ * %0 : upper-word lower-word
+ * + %1 : lower-word upper-word
+ * = word-sum word-sum
+ * ^+inter-word-carry
+ */
+ return sum;
+}
+
+static __inline void
+in_cksum_update(struct ip *ip)
+{
+ int __tmpsum;
+ __tmpsum = (int)ntohs(ip->ip_sum) + 256;
+ ip->ip_sum = htons(__tmpsum + (__tmpsum >> 16));
+}
+
+/*
+ * SPARC Version
+ */
+
+#elif (defined(__GNUC__) && defined(sparc))
+
+static __inline u_int
+in_cksum_hdr(const struct ip *ip)
+{
+ register u_int sum = 0;
+ register u_int tmp_o2;
+ register u_int tmp_o3;
+
+ __asm__ __volatile__ (" \
+ ld [%0], %1 ; \
+ ld [%0+4], %2 ; \
+ ld [%0+8], %3 ; \
+ addcc %1, %2, %1 ; \
+ ld [%0+12], %2 ; \
+ addxcc %1, %3, %1 ; \
+ ld [%0+16], %3 ; \
+ addxcc %1, %2, %1 ; \
+ addxcc %1, %3, %1 ; \
+ set 0x0ffff, %3 ; \
+ srl %1, 16, %2 ; \
+ and %1, %3, %1 ; \
+ addx %1, %2, %1 ; \
+ srl %1, 16, %2 ; \
+ add %1, %2, %1 ; \
+ not %1 ; \
+ and %1, %3, %1 ; \
+ " : "=r" (ip), "=r" (sum), "=r" (tmp_o2), "=r" (tmp_o3)
+ : "0" (ip), "1" (sum), "m"(*ip)
+ );
+ return sum;
+}
+
+#define in_cksum_update(ip) \
+ do { \
+ int __tmpsum; \
+ __tmpsum = (int)ntohs(ip->ip_sum) + 256; \
+ ip->ip_sum = htons(__tmpsum + (__tmpsum >> 16)); \
+ } while(0)
+/*
+ * Here is the generic, portable, inefficient algorithm.
+ */
+
+#else
+u_int in_cksum_hdr __P((const struct ip *));
+#define in_cksum_update(ip) \
+ do { \
+ int __tmpsum; \
+ __tmpsum = (int)ntohs(ip->ip_sum) + 256; \
+ ip->ip_sum = htons(__tmpsum + (__tmpsum >> 16)); \
+ } while(0)
+
+#endif
+
+#endif /* _MACHINE_IN_CKSUM_H_ */
diff --git a/cpukit/libnetworking/machine/limits.h b/cpukit/libnetworking/machine/limits.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/machine/limits.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/machine/vmparam.h b/cpukit/libnetworking/machine/vmparam.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/machine/vmparam.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/memory.h b/cpukit/libnetworking/memory.h
new file mode 100644
index 0000000000..7ef4cda388
--- /dev/null
+++ b/cpukit/libnetworking/memory.h
@@ -0,0 +1,5 @@
+/*
+ * Dummy include file for FreeBSD routines
+ */
+
+#include <string.h>
diff --git a/cpukit/libnetworking/net/bpf.h b/cpukit/libnetworking/net/bpf.h
new file mode 100644
index 0000000000..df21575640
--- /dev/null
+++ b/cpukit/libnetworking/net/bpf.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 1990, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
+ * Berkeley Laboratory.
+ *
+ * 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.
+ *
+ * @(#)bpf.h 8.1 (Berkeley) 6/10/93
+ * @(#)bpf.h 1.34 (LBL) 6/16/96
+ *
+ * $Id$
+ */
+
+#ifndef _NET_BPF_H_
+#define _NET_BPF_H_
+
+/* BSD style release date */
+#define BPF_RELEASE 199606
+
+typedef int32_t bpf_int32;
+typedef u_int32_t bpf_u_int32;
+
+/*
+ * Alignment macros. BPF_WORDALIGN rounds up to the next
+ * even multiple of BPF_ALIGNMENT.
+ */
+#define BPF_ALIGNMENT sizeof(bpf_int32)
+#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
+
+#define BPF_MAXINSNS 512
+#define BPF_MAXBUFSIZE 0x8000
+#define BPF_MINBUFSIZE 32
+
+/*
+ * Structure for BIOCSETF.
+ */
+struct bpf_program {
+ u_int bf_len;
+ struct bpf_insn *bf_insns;
+};
+
+/*
+ * Struct returned by BIOCGSTATS.
+ */
+struct bpf_stat {
+ u_int bs_recv; /* number of packets received */
+ u_int bs_drop; /* number of packets dropped */
+};
+
+/*
+ * Struct return by BIOCVERSION. This represents the version number of
+ * the filter language described by the instruction encodings below.
+ * bpf understands a program iff kernel_major == filter_major &&
+ * kernel_minor >= filter_minor, that is, if the value returned by the
+ * running kernel has the same major number and a minor number equal
+ * equal to or less than the filter being downloaded. Otherwise, the
+ * results are undefined, meaning an error may be returned or packets
+ * may be accepted haphazardly.
+ * It has nothing to do with the source code version.
+ */
+struct bpf_version {
+ u_short bv_major;
+ u_short bv_minor;
+};
+/* Current version number of filter architecture. */
+#define BPF_MAJOR_VERSION 1
+#define BPF_MINOR_VERSION 1
+
+#define BIOCGBLEN _IOR('B',102, u_int)
+#define BIOCSBLEN _IOWR('B',102, u_int)
+#define BIOCSETF _IOW('B',103, struct bpf_program)
+#define BIOCFLUSH _IO('B',104)
+#define BIOCPROMISC _IO('B',105)
+#define BIOCGDLT _IOR('B',106, u_int)
+#define BIOCGETIF _IOR('B',107, struct ifreq)
+#define BIOCSETIF _IOW('B',108, struct ifreq)
+#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
+#define BIOCGRTIMEOUT _IOR('B',110, struct timeval)
+#define BIOCGSTATS _IOR('B',111, struct bpf_stat)
+#define BIOCIMMEDIATE _IOW('B',112, u_int)
+#define BIOCVERSION _IOR('B',113, struct bpf_version)
+#define BIOCGRSIG _IOR('B',114, u_int)
+#define BIOCSRSIG _IOW('B',115, u_int)
+
+/*
+ * Structure prepended to each packet.
+ */
+struct bpf_hdr {
+ struct timeval bh_tstamp; /* time stamp */
+ bpf_u_int32 bh_caplen; /* length of captured portion */
+ bpf_u_int32 bh_datalen; /* original length of packet */
+ u_short bh_hdrlen; /* length of bpf header (this struct
+ plus alignment padding) */
+};
+/*
+ * Because the structure above is not a multiple of 4 bytes, some compilers
+ * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
+ * Only the kernel needs to know about it; applications use bh_hdrlen.
+ */
+#ifdef _KERNEL
+#define SIZEOF_BPF_HDR 18
+#endif
+
+/*
+ * Data-link level type codes.
+ */
+#define DLT_NULL 0 /* no link-layer encapsulation */
+#define DLT_EN10MB 1 /* Ethernet (10Mb) */
+#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
+#define DLT_AX25 3 /* Amateur Radio AX.25 */
+#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
+#define DLT_CHAOS 5 /* Chaos */
+#define DLT_IEEE802 6 /* IEEE 802 Networks */
+#define DLT_ARCNET 7 /* ARCNET */
+#define DLT_SLIP 8 /* Serial Line IP */
+#define DLT_PPP 9 /* Point-to-point Protocol */
+#define DLT_FDDI 10 /* FDDI */
+#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
+
+/*
+ * The instruction encodings.
+ */
+/* instruction classes */
+#define BPF_CLASS(code) ((code) & 0x07)
+#define BPF_LD 0x00
+#define BPF_LDX 0x01
+#define BPF_ST 0x02
+#define BPF_STX 0x03
+#define BPF_ALU 0x04
+#define BPF_JMP 0x05
+#define BPF_RET 0x06
+#define BPF_MISC 0x07
+
+/* ld/ldx fields */
+#define BPF_SIZE(code) ((code) & 0x18)
+#define BPF_W 0x00
+#define BPF_H 0x08
+#define BPF_B 0x10
+#define BPF_MODE(code) ((code) & 0xe0)
+#define BPF_IMM 0x00
+#define BPF_ABS 0x20
+#define BPF_IND 0x40
+#define BPF_MEM 0x60
+#define BPF_LEN 0x80
+#define BPF_MSH 0xa0
+
+/* alu/jmp fields */
+#define BPF_OP(code) ((code) & 0xf0)
+#define BPF_ADD 0x00
+#define BPF_SUB 0x10
+#define BPF_MUL 0x20
+#define BPF_DIV 0x30
+#define BPF_OR 0x40
+#define BPF_AND 0x50
+#define BPF_LSH 0x60
+#define BPF_RSH 0x70
+#define BPF_NEG 0x80
+#define BPF_JA 0x00
+#define BPF_JEQ 0x10
+#define BPF_JGT 0x20
+#define BPF_JGE 0x30
+#define BPF_JSET 0x40
+#define BPF_SRC(code) ((code) & 0x08)
+#define BPF_K 0x00
+#define BPF_X 0x08
+
+/* ret - BPF_K and BPF_X also apply */
+#define BPF_RVAL(code) ((code) & 0x18)
+#define BPF_A 0x10
+
+/* misc */
+#define BPF_MISCOP(code) ((code) & 0xf8)
+#define BPF_TAX 0x00
+#define BPF_TXA 0x80
+
+/*
+ * The instruction data structure.
+ */
+struct bpf_insn {
+ u_short code;
+ u_char jt;
+ u_char jf;
+ bpf_u_int32 k;
+};
+
+/*
+ * Macros for insn array initializers.
+ */
+#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
+#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
+
+#ifdef _KERNEL
+int bpf_validate(struct bpf_insn *, int);
+void bpf_tap(struct ifnet *, u_char *, u_int);
+void bpf_mtap(struct ifnet *, struct mbuf *);
+void bpfattach(struct ifnet *, u_int, u_int);
+void bpfilterattach(int);
+u_int bpf_filter(const struct bpf_insn *, u_char *, u_int, u_int);
+#endif
+
+/*
+ * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
+ */
+#define BPF_MEMWORDS 16
+
+#endif /* _NET_BPF_H_ */
diff --git a/cpukit/libnetworking/net/bsd-comp.c b/cpukit/libnetworking/net/bsd-comp.c
new file mode 100644
index 0000000000..294457cc2c
--- /dev/null
+++ b/cpukit/libnetworking/net/bsd-comp.c
@@ -0,0 +1,1117 @@
+/* $Id$ */
+
+/* Because this code is derived from the 4.3BSD compress source:
+ *
+ *
+ * Copyright (c) 1985, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James A. Woods, derived from original work by Spencer Thomas
+ * and Joseph Orost.
+ *
+ * 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.
+ */
+
+/*
+ * This version is for use with mbufs on BSD-derived systems.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/ppp_defs.h>
+#include <net/if_ppp.h>
+
+#define PACKETPTR struct mbuf *
+#include <net/ppp-comp.h>
+
+#if DO_BSD_COMPRESS
+/*
+ * PPP "BSD compress" compression
+ * The differences between this compression and the classic BSD LZW
+ * source are obvious from the requirement that the classic code worked
+ * with files while this handles arbitrarily long streams that
+ * are broken into packets. They are:
+ *
+ * When the code size expands, a block of junk is not emitted by
+ * the compressor and not expected by the decompressor.
+ *
+ * New codes are not necessarily assigned every time an old
+ * code is output by the compressor. This is because a packet
+ * end forces a code to be emitted, but does not imply that a
+ * new sequence has been seen.
+ *
+ * The compression ratio is checked at the first end of a packet
+ * after the appropriate gap. Besides simplifying and speeding
+ * things up, this makes it more likely that the transmitter
+ * and receiver will agree when the dictionary is cleared when
+ * compression is not going well.
+ */
+
+/*
+ * A dictionary for doing BSD compress.
+ */
+struct bsd_db {
+ int totlen; /* length of this structure */
+ u_int hsize; /* size of the hash table */
+ u_char hshift; /* used in hash function */
+ u_char n_bits; /* current bits/code */
+ u_char maxbits;
+ u_char debug;
+ u_char unit;
+ u_int16_t seqno; /* sequence # of next packet */
+ u_int hdrlen; /* header length to preallocate */
+ u_int mru;
+ u_int maxmaxcode; /* largest valid code */
+ u_int max_ent; /* largest code in use */
+ u_int in_count; /* uncompressed bytes, aged */
+ u_int bytes_out; /* compressed bytes, aged */
+ u_int ratio; /* recent compression ratio */
+ u_int checkpoint; /* when to next check the ratio */
+ u_int clear_count; /* times dictionary cleared */
+ u_int incomp_count; /* incompressible packets */
+ u_int incomp_bytes; /* incompressible bytes */
+ u_int uncomp_count; /* uncompressed packets */
+ u_int uncomp_bytes; /* uncompressed bytes */
+ u_int comp_count; /* compressed packets */
+ u_int comp_bytes; /* compressed bytes */
+ u_int16_t *lens; /* array of lengths of codes */
+ struct bsd_dict {
+ union { /* hash value */
+ u_int32_t fcode;
+ struct {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int16_t prefix; /* preceding code */
+ u_char suffix; /* last character of new code */
+ u_char pad;
+#else
+ u_char pad;
+ u_char suffix; /* last character of new code */
+ u_int16_t prefix; /* preceding code */
+#endif
+ } hs;
+ } f;
+ u_int16_t codem1; /* output of hash table -1 */
+ u_int16_t cptr; /* map code to hash table entry */
+ } dict[1];
+};
+
+#define BSD_OVHD 2 /* BSD compress overhead/packet */
+#define BSD_INIT_BITS BSD_MIN_BITS
+
+static void *bsd_comp_alloc __P((u_char *options, int opt_len));
+static void *bsd_decomp_alloc __P((u_char *options, int opt_len));
+static void bsd_free __P((void *state));
+static int bsd_comp_init __P((void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int debug));
+static int bsd_decomp_init __P((void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int mru, int debug));
+static int bsd_compress __P((void *state, struct mbuf **mret,
+ struct mbuf *mp, int slen, int maxolen));
+static void bsd_incomp __P((void *state, struct mbuf *dmsg));
+static int bsd_decompress __P((void *state, struct mbuf *cmp,
+ struct mbuf **dmpp));
+static void bsd_reset __P((void *state));
+static void bsd_comp_stats __P((void *state, struct compstat *stats));
+
+/*
+ * Procedures exported to if_ppp.c.
+ */
+struct compressor ppp_bsd_compress = {
+ CI_BSD_COMPRESS, /* compress_proto */
+ bsd_comp_alloc, /* comp_alloc */
+ bsd_free, /* comp_free */
+ bsd_comp_init, /* comp_init */
+ bsd_reset, /* comp_reset */
+ bsd_compress, /* compress */
+ bsd_comp_stats, /* comp_stat */
+ bsd_decomp_alloc, /* decomp_alloc */
+ bsd_free, /* decomp_free */
+ bsd_decomp_init, /* decomp_init */
+ bsd_reset, /* decomp_reset */
+ bsd_decompress, /* decompress */
+ bsd_incomp, /* incomp */
+ bsd_comp_stats, /* decomp_stat */
+};
+
+/*
+ * the next two codes should not be changed lightly, as they must not
+ * lie within the contiguous general code space.
+ */
+#define CLEAR 256 /* table clear output code */
+#define FIRST 257 /* first free entry */
+#define LAST 255
+
+#define MAXCODE(b) ((1 << (b)) - 1)
+#define BADCODEM1 MAXCODE(BSD_MAX_BITS)
+
+#define BSD_HASH(prefix,suffix,hshift) ((((u_int32_t)(suffix)) << (hshift)) \
+ ^ (u_int32_t)(prefix))
+#define BSD_KEY(prefix,suffix) ((((u_int32_t)(suffix)) << 16) \
+ + (u_int32_t)(prefix))
+
+#define CHECK_GAP 10000 /* Ratio check interval */
+
+#define RATIO_SCALE_LOG 8
+#define RATIO_SCALE (1<<RATIO_SCALE_LOG)
+#define RATIO_MAX (0x7fffffff>>RATIO_SCALE_LOG)
+
+static void bsd_clear __P((struct bsd_db *));
+static int bsd_check __P((struct bsd_db *));
+static void *bsd_alloc __P((u_char *, int, int));
+static int bsd_init __P((struct bsd_db *, u_char *, int, int, int, int,
+ int, int));
+
+/*
+ * clear the dictionary
+ */
+static void
+bsd_clear(db)
+ struct bsd_db *db;
+{
+ db->clear_count++;
+ db->max_ent = FIRST-1;
+ db->n_bits = BSD_INIT_BITS;
+ db->ratio = 0;
+ db->bytes_out = 0;
+ db->in_count = 0;
+ db->checkpoint = CHECK_GAP;
+}
+
+/*
+ * If the dictionary is full, then see if it is time to reset it.
+ *
+ * Compute the compression ratio using fixed-point arithmetic
+ * with 8 fractional bits.
+ *
+ * Since we have an infinite stream instead of a single file,
+ * watch only the local compression ratio.
+ *
+ * Since both peers must reset the dictionary at the same time even in
+ * the absence of CLEAR codes (while packets are incompressible), they
+ * must compute the same ratio.
+ */
+static int /* 1=output CLEAR */
+bsd_check(db)
+ struct bsd_db *db;
+{
+ u_int new_ratio;
+
+ if (db->in_count >= db->checkpoint) {
+ /* age the ratio by limiting the size of the counts */
+ if (db->in_count >= RATIO_MAX
+ || db->bytes_out >= RATIO_MAX) {
+ db->in_count -= db->in_count/4;
+ db->bytes_out -= db->bytes_out/4;
+ }
+
+ db->checkpoint = db->in_count + CHECK_GAP;
+
+ if (db->max_ent >= db->maxmaxcode) {
+ /* Reset the dictionary only if the ratio is worse,
+ * or if it looks as if it has been poisoned
+ * by incompressible data.
+ *
+ * This does not overflow, because
+ * db->in_count <= RATIO_MAX.
+ */
+ new_ratio = db->in_count << RATIO_SCALE_LOG;
+ if (db->bytes_out != 0)
+ new_ratio /= db->bytes_out;
+
+ if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE) {
+ bsd_clear(db);
+ return 1;
+ }
+ db->ratio = new_ratio;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Return statistics.
+ */
+static void
+bsd_comp_stats(state, stats)
+ void *state;
+ struct compstat *stats;
+{
+ struct bsd_db *db = (struct bsd_db *) state;
+ u_int out;
+
+ stats->unc_bytes = db->uncomp_bytes;
+ stats->unc_packets = db->uncomp_count;
+ stats->comp_bytes = db->comp_bytes;
+ stats->comp_packets = db->comp_count;
+ stats->inc_bytes = db->incomp_bytes;
+ stats->inc_packets = db->incomp_count;
+ stats->ratio = db->in_count;
+ out = db->bytes_out;
+ if (stats->ratio <= 0x7fffff)
+ stats->ratio <<= 8;
+ else
+ out >>= 8;
+ if (out != 0)
+ stats->ratio /= out;
+}
+
+/*
+ * Reset state, as on a CCP ResetReq.
+ */
+static void
+bsd_reset(state)
+ void *state;
+{
+ struct bsd_db *db = (struct bsd_db *) state;
+
+ db->seqno = 0;
+ bsd_clear(db);
+ db->clear_count = 0;
+}
+
+/*
+ * Allocate space for a (de) compressor.
+ */
+static void *
+bsd_alloc(options, opt_len, decomp)
+ u_char *options;
+ int opt_len, decomp;
+{
+ int bits;
+ u_int newlen, hsize, hshift, maxmaxcode;
+ struct bsd_db *db;
+
+ if (opt_len < CILEN_BSD_COMPRESS || options[0] != CI_BSD_COMPRESS
+ || options[1] != CILEN_BSD_COMPRESS
+ || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION)
+ return NULL;
+ bits = BSD_NBITS(options[2]);
+ switch (bits) {
+ case 9: /* needs 82152 for both directions */
+ case 10: /* needs 84144 */
+ case 11: /* needs 88240 */
+ case 12: /* needs 96432 */
+ hsize = 5003;
+ hshift = 4;
+ break;
+ case 13: /* needs 176784 */
+ hsize = 9001;
+ hshift = 5;
+ break;
+ case 14: /* needs 353744 */
+ hsize = 18013;
+ hshift = 6;
+ break;
+ case 15: /* needs 691440 */
+ hsize = 35023;
+ hshift = 7;
+ break;
+ case 16: /* needs 1366160--far too much, */
+ /* hsize = 69001; */ /* and 69001 is too big for cptr */
+ /* hshift = 8; */ /* in struct bsd_db */
+ /* break; */
+ default:
+ return NULL;
+ }
+
+ maxmaxcode = MAXCODE(bits);
+ newlen = sizeof(*db) + (hsize-1) * (sizeof(db->dict[0]));
+ MALLOC(db, struct bsd_db *, newlen, M_DEVBUF, M_NOWAIT);
+ if (!db)
+ return NULL;
+ bzero(db, sizeof(*db) - sizeof(db->dict));
+
+ if (!decomp) {
+ db->lens = NULL;
+ } else {
+ MALLOC(db->lens, u_int16_t *, (maxmaxcode+1) * sizeof(db->lens[0]),
+ M_DEVBUF, M_NOWAIT);
+ if (!db->lens) {
+ FREE(db, M_DEVBUF);
+ return NULL;
+ }
+ }
+
+ db->totlen = newlen;
+ db->hsize = hsize;
+ db->hshift = hshift;
+ db->maxmaxcode = maxmaxcode;
+ db->maxbits = bits;
+
+ return (void *) db;
+}
+
+static void
+bsd_free(state)
+ void *state;
+{
+ struct bsd_db *db = (struct bsd_db *) state;
+
+ if (db->lens)
+ FREE(db->lens, M_DEVBUF);
+ FREE(db, M_DEVBUF);
+}
+
+static void *
+bsd_comp_alloc(options, opt_len)
+ u_char *options;
+ int opt_len;
+{
+ return bsd_alloc(options, opt_len, 0);
+}
+
+static void *
+bsd_decomp_alloc(options, opt_len)
+ u_char *options;
+ int opt_len;
+{
+ return bsd_alloc(options, opt_len, 1);
+}
+
+/*
+ * Initialize the database.
+ */
+static int
+bsd_init(db, options, opt_len, unit, hdrlen, mru, debug, decomp)
+ struct bsd_db *db;
+ u_char *options;
+ int opt_len, unit, hdrlen, mru, debug, decomp;
+{
+ int i;
+
+ if (opt_len < CILEN_BSD_COMPRESS || options[0] != CI_BSD_COMPRESS
+ || options[1] != CILEN_BSD_COMPRESS
+ || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION
+ || BSD_NBITS(options[2]) != db->maxbits
+ || (decomp && db->lens == NULL))
+ return 0;
+
+ if (decomp) {
+ i = LAST+1;
+ while (i != 0)
+ db->lens[--i] = 1;
+ }
+ i = db->hsize;
+ while (i != 0) {
+ db->dict[--i].codem1 = BADCODEM1;
+ db->dict[i].cptr = 0;
+ }
+
+ db->unit = unit;
+ db->hdrlen = hdrlen;
+ db->mru = mru;
+#ifndef DEBUG
+ if (debug)
+#endif
+ db->debug = 1;
+
+ bsd_reset(db);
+
+ return 1;
+}
+
+static int
+bsd_comp_init(state, options, opt_len, unit, hdrlen, debug)
+ void *state;
+ u_char *options;
+ int opt_len, unit, hdrlen, debug;
+{
+ return bsd_init((struct bsd_db *) state, options, opt_len,
+ unit, hdrlen, 0, debug, 0);
+}
+
+static int
+bsd_decomp_init(state, options, opt_len, unit, hdrlen, mru, debug)
+ void *state;
+ u_char *options;
+ int opt_len, unit, hdrlen, mru, debug;
+{
+ return bsd_init((struct bsd_db *) state, options, opt_len,
+ unit, hdrlen, mru, debug, 1);
+}
+
+
+/*
+ * compress a packet
+ * One change from the BSD compress command is that when the
+ * code size expands, we do not output a bunch of padding.
+ */
+int /* new slen */
+bsd_compress(state, mret, mp, slen, maxolen)
+ void *state;
+ struct mbuf **mret; /* return compressed mbuf chain here */
+ struct mbuf *mp; /* from here */
+ int slen; /* uncompressed length */
+ int maxolen; /* max compressed length */
+{
+ struct bsd_db *db = (struct bsd_db *) state;
+ int hshift = db->hshift;
+ u_int max_ent = db->max_ent;
+ u_int n_bits = db->n_bits;
+ u_int bitno = 32;
+ u_int32_t accm = 0, fcode;
+ struct bsd_dict *dictp;
+ u_char c;
+ int hval, disp, ent, ilen;
+ u_char *rptr, *wptr;
+ u_char *cp_end;
+ int olen;
+ struct mbuf *m;
+
+#define PUTBYTE(v) { \
+ ++olen; \
+ if (wptr) { \
+ *wptr++ = (v); \
+ if (wptr >= cp_end) { \
+ m->m_len = wptr - mtod(m, u_char *); \
+ MGET(m->m_next, M_DONTWAIT, MT_DATA); \
+ m = m->m_next; \
+ if (m) { \
+ m->m_len = 0; \
+ if (maxolen - olen > MLEN) \
+ MCLGET(m, M_DONTWAIT); \
+ wptr = mtod(m, u_char *); \
+ cp_end = wptr + M_TRAILINGSPACE(m); \
+ } else \
+ wptr = NULL; \
+ } \
+ } \
+}
+
+#define OUTPUT(ent) { \
+ bitno -= n_bits; \
+ accm |= ((ent) << bitno); \
+ do { \
+ PUTBYTE(accm >> 24); \
+ accm <<= 8; \
+ bitno += 8; \
+ } while (bitno <= 24); \
+}
+
+ /*
+ * If the protocol is not in the range we're interested in,
+ * just return without compressing the packet. If it is,
+ * the protocol becomes the first byte to compress.
+ */
+ rptr = mtod(mp, u_char *);
+ ent = PPP_PROTOCOL(rptr);
+ if (ent < 0x21 || ent > 0xf9) {
+ *mret = NULL;
+ return slen;
+ }
+
+ /* Don't generate compressed packets which are larger than
+ the uncompressed packet. */
+ if (maxolen > slen)
+ maxolen = slen;
+
+ /* Allocate one mbuf to start with. */
+ MGET(m, M_DONTWAIT, MT_DATA);
+ *mret = m;
+ if (m != NULL) {
+ m->m_len = 0;
+ if (maxolen + db->hdrlen > MLEN)
+ MCLGET(m, M_DONTWAIT);
+ m->m_data += db->hdrlen;
+ wptr = mtod(m, u_char *);
+ cp_end = wptr + M_TRAILINGSPACE(m);
+ } else
+ wptr = cp_end = NULL;
+
+ /*
+ * Copy the PPP header over, changing the protocol,
+ * and install the 2-byte packet sequence number.
+ */
+ if (wptr) {
+ *wptr++ = PPP_ADDRESS(rptr); /* assumes the ppp header is */
+ *wptr++ = PPP_CONTROL(rptr); /* all in one mbuf */
+ *wptr++ = 0; /* change the protocol */
+ *wptr++ = PPP_COMP;
+ *wptr++ = db->seqno >> 8;
+ *wptr++ = db->seqno;
+ }
+ ++db->seqno;
+
+ olen = 0;
+ rptr += PPP_HDRLEN;
+ slen = mp->m_len - PPP_HDRLEN;
+ ilen = slen + 1;
+ for (;;) {
+ if (slen <= 0) {
+ mp = mp->m_next;
+ if (!mp)
+ break;
+ rptr = mtod(mp, u_char *);
+ slen = mp->m_len;
+ if (!slen)
+ continue; /* handle 0-length buffers */
+ ilen += slen;
+ }
+
+ slen--;
+ c = *rptr++;
+ fcode = BSD_KEY(ent, c);
+ hval = BSD_HASH(ent, c, hshift);
+ dictp = &db->dict[hval];
+
+ /* Validate and then check the entry. */
+ if (dictp->codem1 >= max_ent)
+ goto nomatch;
+ if (dictp->f.fcode == fcode) {
+ ent = dictp->codem1+1;
+ continue; /* found (prefix,suffix) */
+ }
+
+ /* continue probing until a match or invalid entry */
+ disp = (hval == 0) ? 1 : hval;
+ do {
+ hval += disp;
+ if (hval >= db->hsize)
+ hval -= db->hsize;
+ dictp = &db->dict[hval];
+ if (dictp->codem1 >= max_ent)
+ goto nomatch;
+ } while (dictp->f.fcode != fcode);
+ ent = dictp->codem1 + 1; /* finally found (prefix,suffix) */
+ continue;
+
+ nomatch:
+ OUTPUT(ent); /* output the prefix */
+
+ /* code -> hashtable */
+ if (max_ent < db->maxmaxcode) {
+ struct bsd_dict *dictp2;
+ /* expand code size if needed */
+ if (max_ent >= MAXCODE(n_bits))
+ db->n_bits = ++n_bits;
+
+ /* Invalidate old hash table entry using
+ * this code, and then take it over.
+ */
+ dictp2 = &db->dict[max_ent+1];
+ if (db->dict[dictp2->cptr].codem1 == max_ent)
+ db->dict[dictp2->cptr].codem1 = BADCODEM1;
+ dictp2->cptr = hval;
+ dictp->codem1 = max_ent;
+ dictp->f.fcode = fcode;
+
+ db->max_ent = ++max_ent;
+ }
+ ent = c;
+ }
+
+ OUTPUT(ent); /* output the last code */
+ db->bytes_out += olen;
+ db->in_count += ilen;
+ if (bitno < 32)
+ ++db->bytes_out; /* count complete bytes */
+
+ if (bsd_check(db))
+ OUTPUT(CLEAR); /* do not count the CLEAR */
+
+ /*
+ * Pad dribble bits of last code with ones.
+ * Do not emit a completely useless byte of ones.
+ */
+ if (bitno != 32)
+ PUTBYTE((accm | (0xff << (bitno-8))) >> 24);
+
+ if (m != NULL) {
+ m->m_len = wptr - mtod(m, u_char *);
+ m->m_next = NULL;
+ }
+
+ /*
+ * Increase code size if we would have without the packet
+ * boundary and as the decompressor will.
+ */
+ if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode)
+ db->n_bits++;
+
+ db->uncomp_bytes += ilen;
+ ++db->uncomp_count;
+ if (olen + PPP_HDRLEN + BSD_OVHD > maxolen) {
+ /* throw away the compressed stuff if it is longer than uncompressed */
+ if (*mret != NULL) {
+ m_freem(*mret);
+ *mret = NULL;
+ }
+ ++db->incomp_count;
+ db->incomp_bytes += ilen;
+ } else {
+ ++db->comp_count;
+ db->comp_bytes += olen + BSD_OVHD;
+ }
+
+ return olen + PPP_HDRLEN + BSD_OVHD;
+#undef OUTPUT
+#undef PUTBYTE
+}
+
+
+/*
+ * Update the "BSD Compress" dictionary on the receiver for
+ * incompressible data by pretending to compress the incoming data.
+ */
+static void
+bsd_incomp(state, dmsg)
+ void *state;
+ struct mbuf *dmsg;
+{
+ struct bsd_db *db = (struct bsd_db *) state;
+ u_int hshift = db->hshift;
+ u_int max_ent = db->max_ent;
+ u_int n_bits = db->n_bits;
+ struct bsd_dict *dictp;
+ u_int32_t fcode;
+ u_char c;
+ u_int32_t hval, disp;
+ int slen, ilen;
+ u_int bitno = 7;
+ u_char *rptr;
+ u_int ent;
+
+ /*
+ * If the protocol is not in the range we're interested in,
+ * just return without looking at the packet. If it is,
+ * the protocol becomes the first byte to "compress".
+ */
+ rptr = mtod(dmsg, u_char *);
+ ent = PPP_PROTOCOL(rptr);
+ if (ent < 0x21 || ent > 0xf9)
+ return;
+
+ db->seqno++;
+ ilen = 1; /* count the protocol as 1 byte */
+ rptr += PPP_HDRLEN;
+ slen = dmsg->m_len - PPP_HDRLEN;
+ for (;;) {
+ if (slen <= 0) {
+ dmsg = dmsg->m_next;
+ if (!dmsg)
+ break;
+ rptr = mtod(dmsg, u_char *);
+ slen = dmsg->m_len;
+ continue;
+ }
+ ilen += slen;
+
+ do {
+ c = *rptr++;
+ fcode = BSD_KEY(ent, c);
+ hval = BSD_HASH(ent, c, hshift);
+ dictp = &db->dict[hval];
+
+ /* validate and then check the entry */
+ if (dictp->codem1 >= max_ent)
+ goto nomatch;
+ if (dictp->f.fcode == fcode) {
+ ent = dictp->codem1+1;
+ continue; /* found (prefix,suffix) */
+ }
+
+ /* continue probing until a match or invalid entry */
+ disp = (hval == 0) ? 1 : hval;
+ do {
+ hval += disp;
+ if (hval >= db->hsize)
+ hval -= db->hsize;
+ dictp = &db->dict[hval];
+ if (dictp->codem1 >= max_ent)
+ goto nomatch;
+ } while (dictp->f.fcode != fcode);
+ ent = dictp->codem1+1;
+ continue; /* finally found (prefix,suffix) */
+
+ nomatch: /* output (count) the prefix */
+ bitno += n_bits;
+
+ /* code -> hashtable */
+ if (max_ent < db->maxmaxcode) {
+ struct bsd_dict *dictp2;
+ /* expand code size if needed */
+ if (max_ent >= MAXCODE(n_bits))
+ db->n_bits = ++n_bits;
+
+ /* Invalidate previous hash table entry
+ * assigned this code, and then take it over.
+ */
+ dictp2 = &db->dict[max_ent+1];
+ if (db->dict[dictp2->cptr].codem1 == max_ent)
+ db->dict[dictp2->cptr].codem1 = BADCODEM1;
+ dictp2->cptr = hval;
+ dictp->codem1 = max_ent;
+ dictp->f.fcode = fcode;
+
+ db->max_ent = ++max_ent;
+ db->lens[max_ent] = db->lens[ent]+1;
+ }
+ ent = c;
+ } while (--slen != 0);
+ }
+ bitno += n_bits; /* output (count) the last code */
+ db->bytes_out += bitno/8;
+ db->in_count += ilen;
+ (void)bsd_check(db);
+
+ ++db->incomp_count;
+ db->incomp_bytes += ilen;
+ ++db->uncomp_count;
+ db->uncomp_bytes += ilen;
+
+ /* Increase code size if we would have without the packet
+ * boundary and as the decompressor will.
+ */
+ if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode)
+ db->n_bits++;
+}
+
+
+/*
+ * Decompress "BSD Compress".
+ *
+ * Because of patent problems, we return DECOMP_ERROR for errors
+ * found by inspecting the input data and for system problems, but
+ * DECOMP_FATALERROR for any errors which could possibly be said to
+ * be being detected "after" decompression. For DECOMP_ERROR,
+ * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
+ * infringing a patent of Motorola's if we do, so we take CCP down
+ * instead.
+ *
+ * Given that the frame has the correct sequence number and a good FCS,
+ * errors such as invalid codes in the input most likely indicate a
+ * bug, so we return DECOMP_FATALERROR for them in order to turn off
+ * compression, even though they are detected by inspecting the input.
+ */
+int
+bsd_decompress(state, cmp, dmpp)
+ void *state;
+ struct mbuf *cmp, **dmpp;
+{
+ struct bsd_db *db = (struct bsd_db *) state;
+ u_int max_ent = db->max_ent;
+ u_int32_t accm = 0;
+ u_int bitno = 32; /* 1st valid bit in accm */
+ u_int n_bits = db->n_bits;
+ u_int tgtbitno = 32-n_bits; /* bitno when we have a code */
+ struct bsd_dict *dictp;
+ int explen, i, seq, len;
+ u_int incode, oldcode, finchar;
+ u_char *p, *rptr, *wptr;
+ struct mbuf *m, *dmp, *mret;
+ int adrs, ctrl, ilen;
+ int space, codelen, extra;
+
+ /*
+ * Save the address/control from the PPP header
+ * and then get the sequence number.
+ */
+ *dmpp = NULL;
+ rptr = mtod(cmp, u_char *);
+ adrs = PPP_ADDRESS(rptr);
+ ctrl = PPP_CONTROL(rptr);
+ rptr += PPP_HDRLEN;
+ len = cmp->m_len - PPP_HDRLEN;
+ seq = 0;
+ for (i = 0; i < 2; ++i) {
+ while (len <= 0) {
+ cmp = cmp->m_next;
+ if (cmp == NULL)
+ return DECOMP_ERROR;
+ rptr = mtod(cmp, u_char *);
+ len = cmp->m_len;
+ }
+ seq = (seq << 8) + *rptr++;
+ --len;
+ }
+
+ /*
+ * Check the sequence number and give up if it differs from
+ * the value we're expecting.
+ */
+ if (seq != db->seqno) {
+ if (db->debug)
+ printf("bsd_decomp%d: bad sequence # %d, expected %d\n",
+ db->unit, seq, db->seqno - 1);
+ return DECOMP_ERROR;
+ }
+ ++db->seqno;
+
+ /*
+ * Allocate one mbuf to start with.
+ */
+ MGETHDR(dmp, M_DONTWAIT, MT_DATA);
+ if (dmp == NULL)
+ return DECOMP_ERROR;
+ mret = dmp;
+ dmp->m_len = 0;
+ dmp->m_next = NULL;
+ MCLGET(dmp, M_DONTWAIT);
+ dmp->m_data += db->hdrlen;
+ wptr = mtod(dmp, u_char *);
+ space = M_TRAILINGSPACE(dmp) - PPP_HDRLEN + 1;
+
+ /*
+ * Fill in the ppp header, but not the last byte of the protocol
+ * (that comes from the decompressed data).
+ */
+ wptr[0] = adrs;
+ wptr[1] = ctrl;
+ wptr[2] = 0;
+ wptr += PPP_HDRLEN - 1;
+
+ ilen = len;
+ oldcode = CLEAR;
+ explen = 0;
+ for (;;) {
+ if (len == 0) {
+ cmp = cmp->m_next;
+ if (!cmp) /* quit at end of message */
+ break;
+ rptr = mtod(cmp, u_char *);
+ len = cmp->m_len;
+ ilen += len;
+ continue; /* handle 0-length buffers */
+ }
+
+ /*
+ * Accumulate bytes until we have a complete code.
+ * Then get the next code, relying on the 32-bit,
+ * unsigned accm to mask the result.
+ */
+ bitno -= 8;
+ accm |= *rptr++ << bitno;
+ --len;
+ if (tgtbitno < bitno)
+ continue;
+ incode = accm >> tgtbitno;
+ accm <<= n_bits;
+ bitno += n_bits;
+
+ if (incode == CLEAR) {
+ /*
+ * The dictionary must only be cleared at
+ * the end of a packet. But there could be an
+ * empty mbuf at the end.
+ */
+ if (len > 0 || cmp->m_next != NULL) {
+ while ((cmp = cmp->m_next) != NULL)
+ len += cmp->m_len;
+ if (len > 0) {
+ m_freem(mret);
+ if (db->debug)
+ printf("bsd_decomp%d: bad CLEAR\n", db->unit);
+ return DECOMP_FATALERROR; /* probably a bug */
+ }
+ }
+ bsd_clear(db);
+ explen = ilen = 0;
+ break;
+ }
+
+ if (incode > max_ent + 2 || incode > db->maxmaxcode
+ || (incode > max_ent && oldcode == CLEAR)) {
+ m_freem(mret);
+ if (db->debug) {
+ printf("bsd_decomp%d: bad code 0x%x oldcode=0x%x ",
+ db->unit, incode, oldcode);
+ printf("max_ent=0x%x explen=%d seqno=%d\n",
+ max_ent, explen, db->seqno);
+ }
+ return DECOMP_FATALERROR; /* probably a bug */
+ }
+
+ /* Special case for KwKwK string. */
+ if (incode > max_ent) {
+ finchar = oldcode;
+ extra = 1;
+ } else {
+ finchar = incode;
+ extra = 0;
+ }
+
+ codelen = db->lens[finchar];
+ explen += codelen + extra;
+ if (explen > db->mru + 1) {
+ m_freem(mret);
+ if (db->debug) {
+ printf("bsd_decomp%d: ran out of mru\n", db->unit);
+#ifdef DEBUG
+ while ((cmp = cmp->m_next) != NULL)
+ len += cmp->m_len;
+ printf(" len=%d, finchar=0x%x, codelen=%d, explen=%d\n",
+ len, finchar, codelen, explen);
+#endif
+ }
+ return DECOMP_FATALERROR;
+ }
+
+ /*
+ * For simplicity, the decoded characters go in a single mbuf,
+ * so we allocate a single extra cluster mbuf if necessary.
+ */
+ if ((space -= codelen + extra) < 0) {
+ dmp->m_len = wptr - mtod(dmp, u_char *);
+ MGET(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL) {
+ m_freem(mret);
+ return DECOMP_ERROR;
+ }
+ m->m_len = 0;
+ m->m_next = NULL;
+ dmp->m_next = m;
+ MCLGET(m, M_DONTWAIT);
+ space = M_TRAILINGSPACE(m) - (codelen + extra);
+ if (space < 0) {
+ /* now that's what I call *compression*. */
+ m_freem(mret);
+ return DECOMP_ERROR;
+ }
+ dmp = m;
+ wptr = mtod(dmp, u_char *);
+ }
+
+ /*
+ * Decode this code and install it in the decompressed buffer.
+ */
+ p = (wptr += codelen);
+ while (finchar > LAST) {
+ dictp = &db->dict[db->dict[finchar].cptr];
+#ifdef DEBUG
+ if (--codelen <= 0 || dictp->codem1 != finchar-1)
+ goto bad;
+#endif
+ *--p = dictp->f.hs.suffix;
+ finchar = dictp->f.hs.prefix;
+ }
+ *--p = finchar;
+
+#ifdef DEBUG
+ if (--codelen != 0)
+ printf("bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n",
+ db->unit, codelen, incode, max_ent);
+#endif
+
+ if (extra) /* the KwKwK case again */
+ *wptr++ = finchar;
+
+ /*
+ * If not first code in a packet, and
+ * if not out of code space, then allocate a new code.
+ *
+ * Keep the hash table correct so it can be used
+ * with uncompressed packets.
+ */
+ if (oldcode != CLEAR && max_ent < db->maxmaxcode) {
+ struct bsd_dict *dictp2;
+ u_int32_t fcode;
+ u_int32_t hval, disp;
+
+ fcode = BSD_KEY(oldcode,finchar);
+ hval = BSD_HASH(oldcode,finchar,db->hshift);
+ dictp = &db->dict[hval];
+
+ /* look for a free hash table entry */
+ if (dictp->codem1 < max_ent) {
+ disp = (hval == 0) ? 1 : hval;
+ do {
+ hval += disp;
+ if (hval >= db->hsize)
+ hval -= db->hsize;
+ dictp = &db->dict[hval];
+ } while (dictp->codem1 < max_ent);
+ }
+
+ /*
+ * Invalidate previous hash table entry
+ * assigned this code, and then take it over
+ */
+ dictp2 = &db->dict[max_ent+1];
+ if (db->dict[dictp2->cptr].codem1 == max_ent) {
+ db->dict[dictp2->cptr].codem1 = BADCODEM1;
+ }
+ dictp2->cptr = hval;
+ dictp->codem1 = max_ent;
+ dictp->f.fcode = fcode;
+
+ db->max_ent = ++max_ent;
+ db->lens[max_ent] = db->lens[oldcode]+1;
+
+ /* Expand code size if needed. */
+ if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) {
+ db->n_bits = ++n_bits;
+ tgtbitno = 32-n_bits;
+ }
+ }
+ oldcode = incode;
+ }
+ dmp->m_len = wptr - mtod(dmp, u_char *);
+
+ /*
+ * Keep the checkpoint right so that incompressible packets
+ * clear the dictionary at the right times.
+ */
+ db->bytes_out += ilen;
+ db->in_count += explen;
+ if (bsd_check(db) && db->debug) {
+ printf("bsd_decomp%d: peer should have cleared dictionary\n",
+ db->unit);
+ }
+
+ ++db->comp_count;
+ db->comp_bytes += ilen + BSD_OVHD;
+ ++db->uncomp_count;
+ db->uncomp_bytes += explen;
+
+ *dmpp = mret;
+ return DECOMP_OK;
+
+#ifdef DEBUG
+ bad:
+ if (codelen <= 0) {
+ printf("bsd_decomp%d: fell off end of chain ", db->unit);
+ printf("0x%x at 0x%x by 0x%x, max_ent=0x%x\n",
+ incode, finchar, db->dict[finchar].cptr, max_ent);
+ } else if (dictp->codem1 != finchar-1) {
+ printf("bsd_decomp%d: bad code chain 0x%x finchar=0x%x ",
+ db->unit, incode, finchar);
+ printf("oldcode=0x%x cptr=0x%x codem1=0x%x\n", oldcode,
+ db->dict[finchar].cptr, dictp->codem1);
+ }
+ m_freem(mret);
+ return DECOMP_FATALERROR;
+#endif /* DEBUG */
+}
+#endif /* DO_BSD_COMPRESS */
diff --git a/cpukit/libnetworking/net/ethernet.h b/cpukit/libnetworking/net/ethernet.h
new file mode 100644
index 0000000000..a744308f09
--- /dev/null
+++ b/cpukit/libnetworking/net/ethernet.h
@@ -0,0 +1,387 @@
+/*
+ * Fundamental constants relating to ethernet.
+ *
+ * $FreeBSD: src/sys/net/ethernet.h,v 1.24 2004/10/05 19:28:52 sam Exp $
+ *
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NET_ETHERNET_H_
+#define _NET_ETHERNET_H_
+
+/*
+ * Somce basic Ethernet constants.
+ */
+#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
+#define ETHER_TYPE_LEN 2 /* length of the Ethernet type field */
+#define ETHER_CRC_LEN 4 /* length of the Ethernet CRC */
+#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN)
+#define ETHER_MIN_LEN 64 /* minimum frame len, including CRC */
+#define ETHER_MAX_LEN 1518 /* maximum frame len, including CRC */
+#define ETHER_MAX_LEN_JUMBO 9018 /* max jumbo frame len, including CRC */
+
+#define ETHER_VLAN_ENCAP_LEN 4 /* len of 802.1Q VLAN encapsulation */
+/*
+ * Mbuf adjust factor to force 32-bit alignment of IP header.
+ * Drivers should do m_adj(m, ETHER_ALIGN) when setting up a
+ * receive so the upper layers get the IP header properly aligned
+ * past the 14-byte Ethernet header.
+ */
+#define ETHER_ALIGN 2 /* driver adjust for IP hdr alignment */
+
+/*
+ * Compute the maximum frame size based on ethertype (i.e. possible
+ * encapsulation) and whether or not an FCS is present.
+ */
+#define ETHER_MAX_FRAME(ifp, etype, hasfcs) \
+ ((ifp)->if_mtu + ETHER_HDR_LEN + \
+ ((hasfcs) ? ETHER_CRC_LEN : 0) + \
+ (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0))
+
+/*
+ * Ethernet-specific mbuf flags.
+ */
+#define M_HASFCS M_PROTO5 /* FCS included at end of frame */
+
+/*
+ * Ethernet CRC32 polynomials (big- and little-endian verions).
+ */
+#define ETHER_CRC_POLY_LE 0xedb88320
+#define ETHER_CRC_POLY_BE 0x04c11db6
+
+/*
+ * A macro to validate a length with
+ */
+#define ETHER_IS_VALID_LEN(foo) \
+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+/*
+ * Structure of a 10Mb/s Ethernet header.
+ */
+struct ether_header {
+ u_char ether_dhost[ETHER_ADDR_LEN];
+ u_char ether_shost[ETHER_ADDR_LEN];
+ u_short ether_type;
+};
+
+/*
+ * Structure of a 48-bit Ethernet address.
+ */
+struct ether_addr {
+ u_char octet[ETHER_ADDR_LEN];
+};
+
+#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
+
+/*
+ * NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields.
+ * However, there are some conflicts.
+ */
+
+#define ETHERTYPE_8023 0x0004 /* IEEE 802.3 packet */
+ /* 0x0101 .. 0x1FF Experimental */
+#define ETHERTYPE_PUP 0x0200 /* Xerox PUP protocol - see 0A00 */
+#define ETHERTYPE_PUPAT 0x0200 /* PUP Address Translation - see 0A01 */
+#define ETHERTYPE_SPRITE 0x0500 /* ??? */
+ /* 0x0400 Nixdorf */
+#define ETHERTYPE_NS 0x0600 /* XNS */
+#define ETHERTYPE_NSAT 0x0601 /* XNS Address Translation (3Mb only) */
+#define ETHERTYPE_DLOG1 0x0660 /* DLOG (?) */
+#define ETHERTYPE_DLOG2 0x0661 /* DLOG (?) */
+#define ETHERTYPE_IP 0x0800 /* IP protocol */
+#define ETHERTYPE_X75 0x0801 /* X.75 Internet */
+#define ETHERTYPE_NBS 0x0802 /* NBS Internet */
+#define ETHERTYPE_ECMA 0x0803 /* ECMA Internet */
+#define ETHERTYPE_CHAOS 0x0804 /* CHAOSnet */
+#define ETHERTYPE_X25 0x0805 /* X.25 Level 3 */
+#define ETHERTYPE_ARP 0x0806 /* Address resolution protocol */
+#define ETHERTYPE_NSCOMPAT 0x0807 /* XNS Compatibility */
+#define ETHERTYPE_FRARP 0x0808 /* Frame Relay ARP (RFC1701) */
+ /* 0x081C Symbolics Private */
+ /* 0x0888 - 0x088A Xyplex */
+#define ETHERTYPE_UBDEBUG 0x0900 /* Ungermann-Bass network debugger */
+#define ETHERTYPE_IEEEPUP 0x0A00 /* Xerox IEEE802.3 PUP */
+#define ETHERTYPE_IEEEPUPAT 0x0A01 /* Xerox IEEE802.3 PUP Address Translation */
+#define ETHERTYPE_VINES 0x0BAD /* Banyan VINES */
+#define ETHERTYPE_VINESLOOP 0x0BAE /* Banyan VINES Loopback */
+#define ETHERTYPE_VINESECHO 0x0BAF /* Banyan VINES Echo */
+
+/* 0x1000 - 0x100F Berkeley Trailer */
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHERTYPE_DCA 0x1234 /* DCA - Multicast */
+#define ETHERTYPE_VALID 0x1600 /* VALID system protocol */
+#define ETHERTYPE_DOGFIGHT 0x1989 /* Artificial Horizons ("Aviator" dogfight simulator [on Sun]) */
+#define ETHERTYPE_RCL 0x1995 /* Datapoint Corporation (RCL lan protocol) */
+
+ /* The following 3C0x types
+ are unregistered: */
+#define ETHERTYPE_NBPVCD 0x3C00 /* 3Com NBP virtual circuit datagram (like XNS SPP) not registered */
+#define ETHERTYPE_NBPSCD 0x3C01 /* 3Com NBP System control datagram not registered */
+#define ETHERTYPE_NBPCREQ 0x3C02 /* 3Com NBP Connect request (virtual cct) not registered */
+#define ETHERTYPE_NBPCRSP 0x3C03 /* 3Com NBP Connect repsonse not registered */
+#define ETHERTYPE_NBPCC 0x3C04 /* 3Com NBP Connect complete not registered */
+#define ETHERTYPE_NBPCLREQ 0x3C05 /* 3Com NBP Close request (virtual cct) not registered */
+#define ETHERTYPE_NBPCLRSP 0x3C06 /* 3Com NBP Close response not registered */
+#define ETHERTYPE_NBPDG 0x3C07 /* 3Com NBP Datagram (like XNS IDP) not registered */
+#define ETHERTYPE_NBPDGB 0x3C08 /* 3Com NBP Datagram broadcast not registered */
+#define ETHERTYPE_NBPCLAIM 0x3C09 /* 3Com NBP Claim NetBIOS name not registered */
+#define ETHERTYPE_NBPDLTE 0x3C0A /* 3Com NBP Delete Netbios name not registered */
+#define ETHERTYPE_NBPRAS 0x3C0B /* 3Com NBP Remote adaptor status request not registered */
+#define ETHERTYPE_NBPRAR 0x3C0C /* 3Com NBP Remote adaptor response not registered */
+#define ETHERTYPE_NBPRST 0x3C0D /* 3Com NBP Reset not registered */
+
+#define ETHERTYPE_PCS 0x4242 /* PCS Basic Block Protocol */
+#define ETHERTYPE_IMLBLDIAG 0x424C /* Information Modes Little Big LAN diagnostic */
+#define ETHERTYPE_DIDDLE 0x4321 /* THD - Diddle */
+#define ETHERTYPE_IMLBL 0x4C42 /* Information Modes Little Big LAN */
+#define ETHERTYPE_SIMNET 0x5208 /* BBN Simnet Private */
+#define ETHERTYPE_DECEXPER 0x6000 /* DEC Unassigned, experimental */
+#define ETHERTYPE_MOPDL 0x6001 /* DEC MOP dump/load */
+#define ETHERTYPE_MOPRC 0x6002 /* DEC MOP remote console */
+#define ETHERTYPE_DECnet 0x6003 /* DEC DECNET Phase IV route */
+#define ETHERTYPE_DN ETHERTYPE_DECnet /* libpcap, tcpdump */
+#define ETHERTYPE_LAT 0x6004 /* DEC LAT */
+#define ETHERTYPE_DECDIAG 0x6005 /* DEC diagnostic protocol (at interface initialization?) */
+#define ETHERTYPE_DECCUST 0x6006 /* DEC customer protocol */
+#define ETHERTYPE_SCA 0x6007 /* DEC LAVC, SCA */
+#define ETHERTYPE_AMBER 0x6008 /* DEC AMBER */
+#define ETHERTYPE_DECMUMPS 0x6009 /* DEC MUMPS */
+ /* 0x6010 - 0x6014 3Com Corporation */
+#define ETHERTYPE_TRANSETHER 0x6558 /* Trans Ether Bridging (RFC1701)*/
+#define ETHERTYPE_RAWFR 0x6559 /* Raw Frame Relay (RFC1701) */
+#define ETHERTYPE_UBDL 0x7000 /* Ungermann-Bass download */
+#define ETHERTYPE_UBNIU 0x7001 /* Ungermann-Bass NIUs */
+#define ETHERTYPE_UBDIAGLOOP 0x7002 /* Ungermann-Bass diagnostic/loopback */
+#define ETHERTYPE_UBNMC 0x7003 /* Ungermann-Bass ??? (NMC to/from UB Bridge) */
+#define ETHERTYPE_UBBST 0x7005 /* Ungermann-Bass Bridge Spanning Tree */
+#define ETHERTYPE_OS9 0x7007 /* OS/9 Microware */
+#define ETHERTYPE_OS9NET 0x7009 /* OS/9 Net? */
+ /* 0x7020 - 0x7029 LRT (England) (now Sintrom) */
+#define ETHERTYPE_RACAL 0x7030 /* Racal-Interlan */
+#define ETHERTYPE_PRIMENTS 0x7031 /* Prime NTS (Network Terminal Service) */
+#define ETHERTYPE_CABLETRON 0x7034 /* Cabletron */
+#define ETHERTYPE_CRONUSVLN 0x8003 /* Cronus VLN */
+#define ETHERTYPE_CRONUS 0x8004 /* Cronus Direct */
+#define ETHERTYPE_HP 0x8005 /* HP Probe */
+#define ETHERTYPE_NESTAR 0x8006 /* Nestar */
+#define ETHERTYPE_ATTSTANFORD 0x8008 /* AT&T/Stanford (local use) */
+#define ETHERTYPE_EXCELAN 0x8010 /* Excelan */
+#define ETHERTYPE_SG_DIAG 0x8013 /* SGI diagnostic type */
+#define ETHERTYPE_SG_NETGAMES 0x8014 /* SGI network games */
+#define ETHERTYPE_SG_RESV 0x8015 /* SGI reserved type */
+#define ETHERTYPE_SG_BOUNCE 0x8016 /* SGI bounce server */
+#define ETHERTYPE_APOLLODOMAIN 0x8019 /* Apollo DOMAIN */
+#define ETHERTYPE_TYMSHARE 0x802E /* Tymeshare */
+#define ETHERTYPE_TIGAN 0x802F /* Tigan, Inc. */
+#define ETHERTYPE_REVARP 0x8035 /* Reverse addr resolution protocol */
+#define ETHERTYPE_AEONIC 0x8036 /* Aeonic Systems */
+#define ETHERTYPE_IPXNEW 0x8037 /* IPX (Novell Netware?) */
+#define ETHERTYPE_LANBRIDGE 0x8038 /* DEC LANBridge */
+#define ETHERTYPE_DSMD 0x8039 /* DEC DSM/DDP */
+#define ETHERTYPE_ARGONAUT 0x803A /* DEC Argonaut Console */
+#define ETHERTYPE_VAXELN 0x803B /* DEC VAXELN */
+#define ETHERTYPE_DECDNS 0x803C /* DEC DNS Naming Service */
+#define ETHERTYPE_ENCRYPT 0x803D /* DEC Ethernet Encryption */
+#define ETHERTYPE_DECDTS 0x803E /* DEC Distributed Time Service */
+#define ETHERTYPE_DECLTM 0x803F /* DEC LAN Traffic Monitor */
+#define ETHERTYPE_DECNETBIOS 0x8040 /* DEC PATHWORKS DECnet NETBIOS Emulation */
+#define ETHERTYPE_DECLAST 0x8041 /* DEC Local Area System Transport */
+ /* 0x8042 DEC Unassigned */
+#define ETHERTYPE_PLANNING 0x8044 /* Planning Research Corp. */
+ /* 0x8046 - 0x8047 AT&T */
+#define ETHERTYPE_DECAM 0x8048 /* DEC Availability Manager for Distributed Systems DECamds (but someone at DEC says not) */
+#define ETHERTYPE_EXPERDATA 0x8049 /* ExperData */
+#define ETHERTYPE_VEXP 0x805B /* Stanford V Kernel exp. */
+#define ETHERTYPE_VPROD 0x805C /* Stanford V Kernel prod. */
+#define ETHERTYPE_ES 0x805D /* Evans & Sutherland */
+#define ETHERTYPE_LITTLE 0x8060 /* Little Machines */
+#define ETHERTYPE_COUNTERPOINT 0x8062 /* Counterpoint Computers */
+ /* 0x8065 - 0x8066 Univ. of Mass @ Amherst */
+#define ETHERTYPE_VEECO 0x8067 /* Veeco Integrated Auto. */
+#define ETHERTYPE_GENDYN 0x8068 /* General Dynamics */
+#define ETHERTYPE_ATT 0x8069 /* AT&T */
+#define ETHERTYPE_AUTOPHON 0x806A /* Autophon */
+#define ETHERTYPE_COMDESIGN 0x806C /* ComDesign */
+#define ETHERTYPE_COMPUGRAPHIC 0x806D /* Compugraphic Corporation */
+ /* 0x806E - 0x8077 Landmark Graphics Corp. */
+#define ETHERTYPE_MATRA 0x807A /* Matra */
+#define ETHERTYPE_DDE 0x807B /* Dansk Data Elektronik */
+#define ETHERTYPE_MERIT 0x807C /* Merit Internodal (or Univ of Michigan?) */
+ /* 0x807D - 0x807F Vitalink Communications */
+#define ETHERTYPE_VLTLMAN 0x8080 /* Vitalink TransLAN III Management */
+ /* 0x8081 - 0x8083 Counterpoint Computers */
+ /* 0x8088 - 0x808A Xyplex */
+#define ETHERTYPE_ATALK 0x809B /* AppleTalk */
+#define ETHERTYPE_AT ETHERTYPE_ATALK /* old NetBSD */
+#define ETHERTYPE_APPLETALK ETHERTYPE_ATALK /* HP-UX */
+ /* 0x809C - 0x809E Datability */
+#define ETHERTYPE_SPIDER 0x809F /* Spider Systems Ltd. */
+ /* 0x80A3 Nixdorf */
+ /* 0x80A4 - 0x80B3 Siemens Gammasonics Inc. */
+ /* 0x80C0 - 0x80C3 DCA (Digital Comm. Assoc.) Data Exchange Cluster */
+ /* 0x80C4 - 0x80C5 Banyan Systems */
+#define ETHERTYPE_PACER 0x80C6 /* Pacer Software */
+#define ETHERTYPE_APPLITEK 0x80C7 /* Applitek Corporation */
+ /* 0x80C8 - 0x80CC Intergraph Corporation */
+ /* 0x80CD - 0x80CE Harris Corporation */
+ /* 0x80CF - 0x80D2 Taylor Instrument */
+ /* 0x80D3 - 0x80D4 Rosemount Corporation */
+#define ETHERTYPE_SNA 0x80D5 /* IBM SNA Services over Ethernet */
+#define ETHERTYPE_VARIAN 0x80DD /* Varian Associates */
+ /* 0x80DE - 0x80DF TRFS (Integrated Solutions Transparent Remote File System) */
+ /* 0x80E0 - 0x80E3 Allen-Bradley */
+ /* 0x80E4 - 0x80F0 Datability */
+#define ETHERTYPE_RETIX 0x80F2 /* Retix */
+#define ETHERTYPE_AARP 0x80F3 /* AppleTalk AARP */
+ /* 0x80F4 - 0x80F5 Kinetics */
+#define ETHERTYPE_APOLLO 0x80F7 /* Apollo Computer */
+#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging (XXX conflicts) */
+ /* 0x80FF - 0x8101 Wellfleet Communications (XXX conflicts) */
+#define ETHERTYPE_BOFL 0x8102 /* Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.] */
+#define ETHERTYPE_WELLFLEET 0x8103 /* Wellfleet Communications */
+ /* 0x8107 - 0x8109 Symbolics Private */
+#define ETHERTYPE_TALARIS 0x812B /* Talaris */
+#define ETHERTYPE_WATERLOO 0x8130 /* Waterloo Microsystems Inc. (XXX which?) */
+#define ETHERTYPE_HAYES 0x8130 /* Hayes Microcomputers (XXX which?) */
+#define ETHERTYPE_VGLAB 0x8131 /* VG Laboratory Systems */
+ /* 0x8132 - 0x8137 Bridge Communications */
+#define ETHERTYPE_IPX 0x8137 /* Novell (old) NetWare IPX (ECONFIG E option) */
+#define ETHERTYPE_NOVELL 0x8138 /* Novell, Inc. */
+ /* 0x8139 - 0x813D KTI */
+#define ETHERTYPE_MUMPS 0x813F /* M/MUMPS data sharing */
+#define ETHERTYPE_AMOEBA 0x8145 /* Vrije Universiteit (NL) Amoeba 4 RPC (obsolete) */
+#define ETHERTYPE_FLIP 0x8146 /* Vrije Universiteit (NL) FLIP (Fast Local Internet Protocol) */
+#define ETHERTYPE_VURESERVED 0x8147 /* Vrije Universiteit (NL) [reserved] */
+#define ETHERTYPE_LOGICRAFT 0x8148 /* Logicraft */
+#define ETHERTYPE_NCD 0x8149 /* Network Computing Devices */
+#define ETHERTYPE_ALPHA 0x814A /* Alpha Micro */
+#define ETHERTYPE_SNMP 0x814C /* SNMP over Ethernet (see RFC1089) */
+ /* 0x814D - 0x814E BIIN */
+#define ETHERTYPE_TEC 0x814F /* Technically Elite Concepts */
+#define ETHERTYPE_RATIONAL 0x8150 /* Rational Corp */
+ /* 0x8151 - 0x8153 Qualcomm */
+ /* 0x815C - 0x815E Computer Protocol Pty Ltd */
+ /* 0x8164 - 0x8166 Charles River Data Systems */
+#define ETHERTYPE_XTP 0x817D /* Protocol Engines XTP */
+#define ETHERTYPE_SGITW 0x817E /* SGI/Time Warner prop. */
+#define ETHERTYPE_HIPPI_FP 0x8180 /* HIPPI-FP encapsulation */
+#define ETHERTYPE_STP 0x8181 /* Scheduled Transfer STP, HIPPI-ST */
+ /* 0x8182 - 0x8183 Reserved for HIPPI-6400 */
+ /* 0x8184 - 0x818C SGI prop. */
+#define ETHERTYPE_MOTOROLA 0x818D /* Motorola */
+#define ETHERTYPE_NETBEUI 0x8191 /* PowerLAN NetBIOS/NetBEUI (PC) */
+ /* 0x819A - 0x81A3 RAD Network Devices */
+ /* 0x81B7 - 0x81B9 Xyplex */
+ /* 0x81CC - 0x81D5 Apricot Computers */
+ /* 0x81D6 - 0x81DD Artisoft Lantastic */
+ /* 0x81E6 - 0x81EF Polygon */
+ /* 0x81F0 - 0x81F2 Comsat Labs */
+ /* 0x81F3 - 0x81F5 SAIC */
+ /* 0x81F6 - 0x81F8 VG Analytical */
+ /* 0x8203 - 0x8205 QNX Software Systems Ltd. */
+ /* 0x8221 - 0x8222 Ascom Banking Systems */
+ /* 0x823E - 0x8240 Advanced Encryption Systems */
+ /* 0x8263 - 0x826A Charles River Data Systems */
+ /* 0x827F - 0x8282 Athena Programming */
+ /* 0x829A - 0x829B Inst Ind Info Tech */
+ /* 0x829C - 0x82AB Taurus Controls */
+ /* 0x82AC - 0x8693 Walker Richer & Quinn */
+#define ETHERTYPE_ACCTON 0x8390 /* Accton Technologies (unregistered) */
+#define ETHERTYPE_TALARISMC 0x852B /* Talaris multicast */
+#define ETHERTYPE_KALPANA 0x8582 /* Kalpana */
+ /* 0x8694 - 0x869D Idea Courier */
+ /* 0x869E - 0x86A1 Computer Network Tech */
+ /* 0x86A3 - 0x86AC Gateway Communications */
+#define ETHERTYPE_SECTRA 0x86DB /* SECTRA */
+#define ETHERTYPE_IPV6 0x86DD /* IP protocol version 6 */
+#define ETHERTYPE_DELTACON 0x86DE /* Delta Controls */
+#define ETHERTYPE_ATOMIC 0x86DF /* ATOMIC */
+ /* 0x86E0 - 0x86EF Landis & Gyr Powers */
+ /* 0x8700 - 0x8710 Motorola */
+#define ETHERTYPE_RDP 0x8739 /* Control Technology Inc. RDP Without IP */
+#define ETHERTYPE_MICP 0x873A /* Control Technology Inc. Mcast Industrial Ctrl Proto. */
+ /* 0x873B - 0x873C Control Technology Inc. Proprietary */
+#define ETHERTYPE_TCPCOMP 0x876B /* TCP/IP Compression (RFC1701) */
+#define ETHERTYPE_IPAS 0x876C /* IP Autonomous Systems (RFC1701) */
+#define ETHERTYPE_SECUREDATA 0x876D /* Secure Data (RFC1701) */
+#define ETHERTYPE_FLOWCONTROL 0x8808 /* 802.3x flow control packet */
+#define ETHERTYPE_PPP 0x880B /* PPP (obsolete by PPPOE) */
+#define ETHERTYPE_HITACHI 0x8820 /* Hitachi Cable (Optoelectronic Systems Laboratory) */
+#define ETHERTYPE_MPLS 0x8847 /* MPLS Unicast */
+#define ETHERTYPE_MPLS_MCAST 0x8848 /* MPLS Multicast */
+#define ETHERTYPE_AXIS 0x8856 /* Axis Communications AB proprietary bootstrap/config */
+#define ETHERTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
+#define ETHERTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */
+#define ETHERTYPE_LANPROBE 0x8888 /* HP LanProbe test? */
+#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
+#define ETHERTYPE_LOOPBACK 0x9000 /* Loopback: used to test interfaces */
+#define ETHERTYPE_LBACK ETHERTYPE_LOOPBACK /* DEC MOP loopback */
+#define ETHERTYPE_XNSSM 0x9001 /* 3Com (Formerly Bridge Communications), XNS Systems Management */
+#define ETHERTYPE_TCPSM 0x9002 /* 3Com (Formerly Bridge Communications), TCP/IP Systems Management */
+#define ETHERTYPE_BCLOOP 0x9003 /* 3Com (Formerly Bridge Communications), loopback detection */
+#define ETHERTYPE_DEBNI 0xAAAA /* DECNET? Used by VAX 6220 DEBNI */
+#define ETHERTYPE_SONIX 0xFAF5 /* Sonix Arpeggio */
+#define ETHERTYPE_VITAL 0xFF00 /* BBN VITAL-LanBridge cache wakeups */
+ /* 0xFF00 - 0xFFOF ISC Bunker Ramo */
+
+#define ETHERTYPE_MAX 0xFFFF /* Maximum valid ethernet type, reserved */
+
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHERMTU (ETHER_MAX_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
+#define ETHERMIN (ETHER_MIN_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
+#define ETHERMTU_JUMBO (ETHER_MAX_LEN_JUMBO - ETHER_HDR_LEN - ETHER_CRC_LEN)
+
+#ifdef _KERNEL
+
+struct ifnet;
+struct mbuf;
+struct rtentry;
+struct sockaddr;
+
+extern uint32_t ether_crc32_le(const uint8_t *, size_t);
+extern uint32_t ether_crc32_be(const uint8_t *, size_t);
+extern void ether_demux(struct ifnet *, struct mbuf *);
+extern void ether_ifattach(struct ifnet *);
+extern void ether_ifdetach(struct ifnet *);
+extern int ether_ioctl(struct ifnet *, int, caddr_t);
+extern void ether_input (struct ifnet *, struct ether_header *, struct mbuf *);
+extern int ether_output(struct ifnet *,
+ struct mbuf *, struct sockaddr *, struct rtentry *);
+extern int ether_output_frame(struct ifnet *, struct mbuf *);
+extern char *ether_sprintf(const u_int8_t *);
+
+#else /* _KERNEL */
+
+#include <sys/cdefs.h>
+
+/*
+ * Ethernet address conversion/parsing routines.
+ */
+__BEGIN_DECLS
+struct ether_addr *ether_aton(const char *);
+int ether_hostton(const char *, struct ether_addr *);
+int ether_line(const char *, struct ether_addr *, char *);
+char *ether_ntoa(const struct ether_addr *);
+int ether_ntohost(char *, const struct ether_addr *);
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif /* !_NET_ETHERNET_H_ */
diff --git a/cpukit/libnetworking/net/if.c b/cpukit/libnetworking/net/if.c
new file mode 100644
index 0000000000..b7a7c1ee21
--- /dev/null
+++ b/cpukit/libnetworking/net/if.c
@@ -0,0 +1,780 @@
+/*
+ * Copyright (c) 1980, 1986, 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.
+ * 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.
+ *
+ * @(#)if.c 8.5 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/net/if.c,v 1.226 2005/04/15 01:51:26 cperciva Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/mbuf.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/kernel.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/syslog.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/if_var.h>
+#include <net/radix.h>
+
+/*
+ * System initialization
+ */
+
+static int ifconf(u_long, caddr_t);
+ void ifinit(void *);
+static void if_qflush(struct ifqueue *);
+static void if_slowtimo(void *);
+static void link_rtrequest(int, struct rtentry *, struct sockaddr *);
+
+SYSINIT(interfaces, SI_SUB_PROTO_IF, SI_ORDER_FIRST, ifinit, NULL)
+
+
+int ifqmaxlen = IFQ_MAXLEN;
+struct ifnet *ifnet;
+
+/*
+ * Network interface utility routines.
+ *
+ * Routines with ifa_ifwith* names take sockaddr *'s as
+ * parameters.
+ *
+ * This routine assumes that it will be called at splimp() or higher.
+ */
+/* ARGSUSED*/
+void
+ifinit(void *dummy)
+{
+ struct ifnet *ifp;
+
+ for (ifp = ifnet; ifp; ifp = ifp->if_next)
+ if (ifp->if_snd.ifq_maxlen == 0)
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ if_slowtimo(0);
+}
+
+int if_index = 0;
+struct ifaddr **ifnet_addrs;
+
+
+/*
+ * Attach an interface to the
+ * list of "active" interfaces.
+ */
+void
+if_attach(struct ifnet *ifp)
+{
+ unsigned socksize, ifasize;
+ int namelen, masklen;
+ char workbuf[64];
+ struct ifnet **p = &ifnet;
+ struct sockaddr_dl *sdl;
+ struct ifaddr *ifa;
+ static int if_indexlim = 8;
+
+
+ while (*p)
+ p = &((*p)->if_next);
+ *p = ifp;
+ ifp->if_index = ++if_index;
+ microtime(&ifp->if_lastchange);
+ if (ifnet_addrs == 0 || if_index >= if_indexlim) {
+ unsigned n = (if_indexlim <<= 1) * sizeof(ifa);
+ struct ifaddr **q = (struct ifaddr **)
+ malloc(n, M_IFADDR, M_WAITOK);
+ bzero((caddr_t)q, n);
+ if (ifnet_addrs) {
+ bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2);
+ free((caddr_t)ifnet_addrs, M_IFADDR);
+ }
+ ifnet_addrs = q;
+ }
+ /*
+ * create a Link Level name for this device
+ */
+ namelen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit);
+#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
+ masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
+ socksize = masklen + ifp->if_addrlen;
+#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
+ socksize = ROUNDUP(socksize);
+ if (socksize < sizeof(*sdl))
+ socksize = sizeof(*sdl);
+ ifasize = sizeof(*ifa) + 2 * socksize;
+ ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
+ if (ifa) {
+ bzero((caddr_t)ifa, ifasize);
+ sdl = (struct sockaddr_dl *)(ifa + 1);
+ sdl->sdl_len = socksize;
+ sdl->sdl_family = AF_LINK;
+ bcopy(workbuf, sdl->sdl_data, namelen);
+ sdl->sdl_nlen = namelen;
+ sdl->sdl_index = ifp->if_index;
+ sdl->sdl_type = ifp->if_type;
+ ifnet_addrs[if_index - 1] = ifa;
+ ifa->ifa_ifp = ifp;
+ ifa->ifa_next = ifp->if_addrlist;
+ ifa->ifa_rtrequest = link_rtrequest;
+ ifp->if_addrlist = ifa;
+ ifa->ifa_addr = (struct sockaddr *)sdl;
+
+ sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
+ ifa->ifa_netmask = (struct sockaddr *)sdl;
+ sdl->sdl_len = masklen;
+ while (namelen != 0)
+ sdl->sdl_data[--namelen] = 0xff;
+ }
+}
+/*
+ * Locate an interface based on a complete address.
+ */
+/*ARGSUSED*/
+struct ifaddr *
+ifa_ifwithaddr(struct sockaddr *addr)
+{
+ struct ifnet *ifp;
+ struct ifaddr *ifa;
+
+#define equal(a1, a2) \
+ (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
+ for (ifp = ifnet; ifp; ifp = ifp->if_next)
+ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr->sa_family != addr->sa_family)
+ continue;
+ if (equal(addr, ifa->ifa_addr))
+ return (ifa);
+ if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
+ equal(ifa->ifa_broadaddr, addr))
+ return (ifa);
+ }
+ return ((struct ifaddr *)0);
+}
+/*
+ * Locate the point to point interface with a given destination address.
+ */
+/*ARGSUSED*/
+struct ifaddr *
+ifa_ifwithdstaddr(struct sockaddr *addr)
+{
+ struct ifnet *ifp;
+ struct ifaddr *ifa;
+
+ for (ifp = ifnet; ifp; ifp = ifp->if_next)
+ if (ifp->if_flags & IFF_POINTOPOINT)
+ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr->sa_family != addr->sa_family)
+ continue;
+ if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))
+ return (ifa);
+ }
+ return ((struct ifaddr *)0);
+}
+
+/*
+ * Find an interface on a specific network. If many, choice
+ * is most specific found.
+ */
+struct ifaddr *
+ifa_ifwithnet(struct sockaddr *addr)
+{
+ struct ifnet *ifp;
+ struct ifaddr *ifa;
+ struct ifaddr *ifa_maybe = (struct ifaddr *) 0;
+ u_int af = addr->sa_family;
+ char *addr_data = addr->sa_data, *cplim;
+
+ if (af == AF_LINK) {
+ struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
+ if (sdl->sdl_index && sdl->sdl_index <= if_index)
+ return (ifnet_addrs[sdl->sdl_index - 1]);
+ }
+ for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
+ char *cp, *cp2, *cp3;
+
+ if (ifa->ifa_addr->sa_family != af)
+ next: continue;
+ if (ifp->if_flags & IFF_POINTOPOINT) {
+ if (ifa->ifa_dstaddr != 0
+ && equal(addr, ifa->ifa_dstaddr))
+ return (ifa);
+ } else {
+ /*
+ * if we have a special address handler,
+ * then use it instead of the generic one.
+ */
+ if (ifa->ifa_claim_addr) {
+ if ((*ifa->ifa_claim_addr)(ifa, addr)) {
+ return (ifa);
+ } else {
+ continue;
+ }
+ }
+
+ /*
+ * Scan all the bits in the ifa's address.
+ * If a bit dissagrees with what we are
+ * looking for, mask it with the netmask
+ * to see if it really matters.
+ * (A byte at a time)
+ */
+ if (ifa->ifa_netmask == 0)
+ continue;
+ cp = addr_data;
+ cp2 = ifa->ifa_addr->sa_data;
+ cp3 = ifa->ifa_netmask->sa_data;
+ cplim = ifa->ifa_netmask->sa_len
+ + (char *)ifa->ifa_netmask;
+ while (cp3 < cplim)
+ if ((*cp++ ^ *cp2++) & *cp3++)
+ goto next; /* next address! */
+ /*
+ * If the netmask of what we just found
+ * is more specific than what we had before
+ * (if we had one) then remember the new one
+ * before continuing to search
+ * for an even better one.
+ */
+ if (ifa_maybe == 0 ||
+ rn_refines((caddr_t)ifa->ifa_netmask,
+ (caddr_t)ifa_maybe->ifa_netmask))
+ ifa_maybe = ifa;
+ }
+ }
+ }
+ return (ifa_maybe);
+}
+
+/*
+ * Find an interface address specific to an interface best matching
+ * a given address.
+ */
+struct ifaddr *
+ifaof_ifpforaddr(struct sockaddr *addr, struct ifnet *ifp)
+{
+ struct ifaddr *ifa;
+ char *cp, *cp2, *cp3;
+ char *cplim;
+ struct ifaddr *ifa_maybe = 0;
+ u_int af = addr->sa_family;
+
+ if (af >= AF_MAX)
+ return (0);
+ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr->sa_family != af)
+ continue;
+ if (ifa_maybe == 0)
+ ifa_maybe = ifa;
+ if (ifa->ifa_netmask == 0) {
+ if (equal(addr, ifa->ifa_addr) ||
+ (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
+ return (ifa);
+ continue;
+ }
+ if (ifp->if_flags & IFF_POINTOPOINT) {
+ if (equal(addr, ifa->ifa_dstaddr))
+ return (ifa);
+ } else {
+ cp = addr->sa_data;
+ cp2 = ifa->ifa_addr->sa_data;
+ cp3 = ifa->ifa_netmask->sa_data;
+ cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
+ for (; cp3 < cplim; cp3++)
+ if ((*cp++ ^ *cp2++) & *cp3)
+ break;
+ if (cp3 == cplim)
+ return (ifa);
+ }
+ }
+ return (ifa_maybe);
+}
+
+#include <net/route.h>
+
+/*
+ * Default action when installing a route with a Link Level gateway.
+ * Lookup an appropriate real ifa to point to.
+ * This should be moved to /sys/net/link.c eventually.
+ */
+static void
+link_rtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa)
+{
+ struct ifaddr *ifa;
+ struct sockaddr *dst;
+ struct ifnet *ifp;
+
+ if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
+ ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
+ return;
+ ifa = ifaof_ifpforaddr(dst, ifp);
+ if (ifa) {
+ IFAFREE(rt->rt_ifa);
+ rt->rt_ifa = ifa;
+ ifa->ifa_refcnt++;
+ if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
+ ifa->ifa_rtrequest(cmd, rt, sa);
+ }
+}
+
+/*
+ * Mark an interface down and notify protocols of
+ * the transition.
+ * NOTE: must be called at splnet or eqivalent.
+ */
+void
+if_down(struct ifnet *ifp)
+{
+ struct ifaddr *ifa;
+
+ ifp->if_flags &= ~IFF_UP;
+ microtime(&ifp->if_lastchange);
+ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
+ pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
+ if_qflush(&ifp->if_snd);
+ rt_ifmsg(ifp);
+}
+
+/*
+ * Mark an interface up and notify protocols of
+ * the transition.
+ * NOTE: must be called at splnet or eqivalent.
+ */
+void
+if_up(struct ifnet *ifp)
+{
+
+ ifp->if_flags |= IFF_UP;
+ microtime(&ifp->if_lastchange);
+#ifdef notyet
+ struct ifaddr *ifa;
+ /* this has no effect on IP, and will kill all iso connections XXX */
+ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
+ pfctlinput(PRC_IFUP, ifa->ifa_addr);
+#endif
+ rt_ifmsg(ifp);
+}
+
+/*
+ * Flush an interface queue.
+ */
+static void
+if_qflush(struct ifqueue *ifq)
+{
+ struct mbuf *m, *n;
+
+ n = ifq->ifq_head;
+ while ((m = n) != 0) {
+ n = m->m_act;
+ m_freem(m);
+ }
+ ifq->ifq_head = 0;
+ ifq->ifq_tail = 0;
+ ifq->ifq_len = 0;
+}
+
+/*
+ * Handle interface watchdog timer routines. Called
+ * from softclock, we decrement timers (if set) and
+ * call the appropriate interface routine on expiration.
+ */
+static void
+if_slowtimo(void *arg)
+{
+ struct ifnet *ifp;
+ int s = splimp();
+
+ for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+ if (ifp->if_timer == 0 || --ifp->if_timer)
+ continue;
+ if (ifp->if_watchdog)
+ (*ifp->if_watchdog)(ifp);
+ }
+ splx(s);
+ timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ);
+}
+
+/*
+ * Map interface name to
+ * interface structure pointer.
+ */
+struct ifnet *
+ifunit(char *name)
+{
+ char *cp;
+ struct ifnet *ifp;
+ int unit;
+ unsigned len;
+ char *ep, c;
+
+ for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)
+ if (*cp >= '0' && *cp <= '9')
+ break;
+ if (*cp == '\0' || cp == name + IFNAMSIZ)
+ return ((struct ifnet *)0);
+ /*
+ * Save first char of unit, and pointer to it,
+ * so we can put a null there to avoid matching
+ * initial substrings of interface names.
+ */
+ len = cp - name + 1;
+ c = *cp;
+ ep = cp;
+ for (unit = 0; *cp >= '0' && *cp <= '9'; )
+ unit = unit * 10 + *cp++ - '0';
+ if (*cp != '\0')
+ return 0; /* no trailing garbage allowed */
+ *ep = 0;
+ for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+ if (bcmp(ifp->if_name, name, len))
+ continue;
+ if (unit == ifp->if_unit)
+ break;
+ }
+ *ep = c;
+ return (ifp);
+}
+
+/*
+ * Interface ioctls.
+ */
+int
+ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
+{
+ struct ifnet *ifp;
+ struct ifreq *ifr;
+ int error;
+
+ switch (cmd) {
+
+ case SIOCGIFCONF:
+ case OSIOCGIFCONF:
+ return (ifconf(cmd, data));
+ }
+ ifr = (struct ifreq *)data;
+ ifp = ifunit(ifr->ifr_name);
+ if (ifp == 0)
+ return (ENXIO);
+ switch (cmd) {
+
+ case SIOCGIFFLAGS:
+ ifr->ifr_flags = ifp->if_flags;
+ break;
+
+ case SIOCGIFMETRIC:
+ ifr->ifr_metric = ifp->if_metric;
+ break;
+
+ case SIOCGIFMTU:
+ ifr->ifr_mtu = ifp->if_mtu;
+ break;
+
+ case SIOCGIFPHYS:
+ ifr->ifr_phys = ifp->if_physical;
+ break;
+
+ case SIOCSIFFLAGS:
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error)
+ return (error);
+ if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
+ int s = splimp();
+ if_down(ifp);
+ splx(s);
+ }
+ if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
+ int s = splimp();
+ if_up(ifp);
+ splx(s);
+ }
+ ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
+ (ifr->ifr_flags &~ IFF_CANTCHANGE);
+ if (ifp->if_ioctl)
+ (void) (*ifp->if_ioctl)(ifp, cmd, data);
+ microtime(&ifp->if_lastchange);
+ break;
+
+ case SIOCSIFMETRIC:
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error)
+ return (error);
+ ifp->if_metric = ifr->ifr_metric;
+ microtime(&ifp->if_lastchange);
+ break;
+
+ case SIOCSIFPHYS:
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error)
+ return error;
+ if (!ifp->if_ioctl)
+ return EOPNOTSUPP;
+ error = (*ifp->if_ioctl)(ifp, cmd, data);
+ if (error == 0)
+ microtime(&ifp->if_lastchange);
+ return(error);
+
+ case SIOCSIFMTU:
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error)
+ return (error);
+ if (ifp->if_ioctl == NULL)
+ return (EOPNOTSUPP);
+ /*
+ * 72 was chosen below because it is the size of a TCP/IP
+ * header (40) + the minimum mss (32).
+ */
+ if (ifr->ifr_mtu < 72 || ifr->ifr_mtu > 65535)
+ return (EINVAL);
+ error = (*ifp->if_ioctl)(ifp, cmd, data);
+ if (error == 0)
+ microtime(&ifp->if_lastchange);
+ return(error);
+
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error)
+ return (error);
+ if (ifp->if_ioctl == NULL)
+ return (EOPNOTSUPP);
+ error = (*ifp->if_ioctl)(ifp, cmd, data);
+ if (error == 0 )
+ microtime(&ifp->if_lastchange);
+ return(error);
+
+ case SIOCSIFMEDIA:
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error)
+ return (error);
+ if (ifp->if_ioctl == NULL)
+ return (EOPNOTSUPP);
+ error = (*ifp->if_ioctl)(ifp, cmd, data);
+ if (error == 0)
+ microtime(&ifp->if_lastchange);
+ return error;
+
+ case SIOCGIFMEDIA:
+ if (ifp->if_ioctl == NULL)
+ return (EOPNOTSUPP);
+ return ((*ifp->if_ioctl)(ifp, cmd, data));
+
+ default:
+ if (so->so_proto == 0)
+ return (EOPNOTSUPP);
+#ifndef COMPAT_43
+ return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
+ data,
+ ifp));
+#else
+ {
+ int ocmd = cmd;
+
+ switch (cmd) {
+
+ case SIOCSIFDSTADDR:
+ case SIOCSIFADDR:
+ case SIOCSIFBRDADDR:
+ case SIOCSIFNETMASK:
+#if BYTE_ORDER != BIG_ENDIAN
+ if (ifr->ifr_addr.sa_family == 0 &&
+ ifr->ifr_addr.sa_len < 16) {
+ ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
+ ifr->ifr_addr.sa_len = 16;
+ }
+#else
+ if (ifr->ifr_addr.sa_len == 0)
+ ifr->ifr_addr.sa_len = 16;
+#endif
+ break;
+
+ case OSIOCGIFADDR:
+ cmd = SIOCGIFADDR;
+ break;
+
+ case OSIOCGIFDSTADDR:
+ cmd = SIOCGIFDSTADDR;
+ break;
+
+ case OSIOCGIFBRDADDR:
+ cmd = SIOCGIFBRDADDR;
+ break;
+
+ case OSIOCGIFNETMASK:
+ cmd = SIOCGIFNETMASK;
+ }
+ error = ((*so->so_proto->pr_usrreqs->pru_control)(so,
+ cmd,
+ data,
+ ifp));
+ switch (ocmd) {
+
+ case OSIOCGIFADDR:
+ case OSIOCGIFDSTADDR:
+ case OSIOCGIFBRDADDR:
+ case OSIOCGIFNETMASK:
+ *(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
+ }
+ return (error);
+
+ }
+#endif
+
+ /*
+ * RTEMS additions for setting/getting `tap' function
+ */
+ case SIOCSIFTAP:
+ ifp->if_tap = ifr->ifr_tap;
+ return 0;
+
+ case SIOCGIFTAP:
+ ifr->ifr_tap = ifp->if_tap;
+ return 0;
+ }
+ return (0);
+}
+
+/*
+ * Set/clear promiscuous mode on interface ifp based on the truth value
+ * of pswitch. The calls are reference counted so that only the first
+ * "on" request actually has an effect, as does the final "off" request.
+ * Results are undefined if the "off" and "on" requests are not matched.
+ */
+int
+ifpromisc(struct ifnet *ifp, int pswitch)
+{
+ struct ifreq ifr;
+
+ if (pswitch) {
+ /*
+ * If the device is not configured up, we cannot put it in
+ * promiscuous mode.
+ */
+ if ((ifp->if_flags & IFF_UP) == 0)
+ return (ENETDOWN);
+ if (ifp->if_pcount++ != 0)
+ return (0);
+ ifp->if_flags |= IFF_PROMISC;
+ log(LOG_INFO, "%s%d: promiscuous mode enabled\n",
+ ifp->if_name, ifp->if_unit);
+ } else {
+ if (--ifp->if_pcount > 0)
+ return (0);
+ ifp->if_flags &= ~IFF_PROMISC;
+ }
+ ifr.ifr_flags = ifp->if_flags;
+ return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
+}
+
+/*
+ * Return interface configuration
+ * of system. List may be used
+ * in later ioctl's (above) to get
+ * other information.
+ */
+/*ARGSUSED*/
+static int
+ifconf(u_long cmd, caddr_t data)
+{
+ struct ifconf *ifc = (struct ifconf *)data;
+ struct ifnet *ifp = ifnet;
+ struct ifaddr *ifa;
+ struct ifreq ifr, *ifrp;
+ int space = ifc->ifc_len, error = 0;
+
+ ifrp = ifc->ifc_req;
+ for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) {
+ char workbuf[64];
+ int ifnlen;
+
+ ifnlen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit);
+ if(ifnlen + 1 > sizeof ifr.ifr_name) {
+ error = ENAMETOOLONG;
+ } else {
+ strcpy(ifr.ifr_name, workbuf);
+ }
+
+ if ((ifa = ifp->if_addrlist) == 0) {
+ bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
+ error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
+ sizeof (ifr));
+ if (error)
+ break;
+ space -= sizeof (ifr), ifrp++;
+ } else
+ for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) {
+ struct sockaddr *sa = ifa->ifa_addr;
+#ifdef COMPAT_43
+ if (cmd == OSIOCGIFCONF) {
+ struct osockaddr *osa =
+ (struct osockaddr *)&ifr.ifr_addr;
+ ifr.ifr_addr = *sa;
+ osa->sa_family = sa->sa_family;
+ error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
+ sizeof (ifr));
+ ifrp++;
+ } else
+#endif
+ if (sa->sa_len <= sizeof(*sa)) {
+ ifr.ifr_addr = *sa;
+ error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
+ sizeof (ifr));
+ ifrp++;
+ } else {
+ space -= sa->sa_len - sizeof(*sa);
+ if (space < sizeof (ifr))
+ break;
+ error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
+ sizeof (ifr.ifr_name));
+ if (error == 0)
+ error = copyout((caddr_t)sa,
+ (caddr_t)&ifrp->ifr_addr, sa->sa_len);
+ ifrp = (struct ifreq *)
+ (sa->sa_len + (caddr_t)&ifrp->ifr_addr);
+ }
+ if (error)
+ break;
+ space -= sizeof (ifr);
+ }
+ }
+ ifc->ifc_len -= space;
+ return (error);
+}
+
+SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers");
+SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");
diff --git a/cpukit/libnetworking/net/if.h b/cpukit/libnetworking/net/if.h
new file mode 100644
index 0000000000..8f7b6d95ba
--- /dev/null
+++ b/cpukit/libnetworking/net/if.h
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 1982, 1986, 1989, 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.
+ * 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.
+ *
+ * @(#)if.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if.h,v 1.95 2005/02/25 19:46:41 brooks Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NET_IF_H_
+#define _NET_IF_H_
+
+#include <sys/cdefs.h>
+
+#if defined(__rtems__)
+/*
+ * FIXME - HACK: BSD defines __BSD_VISIBLE in sys/cdefs.h
+ * RTEMS sys/cdefs.h doesn't, so we enforce it here.
+ */
+#ifndef __BSD_VISIBLE
+#define __BSD_VISIBLE 1
+#endif
+#endif
+
+#ifdef _KERNEL
+#include <sys/queue.h>
+#endif
+
+#if __BSD_VISIBLE
+/*
+ * <net/if.h> does not depend on <sys/time.h> on most other systems. This
+ * helps userland compatibility. (struct timeval ifi_lastchange)
+ */
+#ifndef _KERNEL
+#include <sys/time.h>
+#endif
+
+struct ifnet;
+struct ether_header;
+#endif
+
+/*
+ * Length of interface external name, including terminating '\0'.
+ * Note: this is the same size as a generic device's external name.
+ */
+#define IF_NAMESIZE 16
+#if __BSD_VISIBLE
+#define IFNAMSIZ IF_NAMESIZE
+#define IF_MAXUNIT 0x7fff /* historical value */
+#endif
+#if __BSD_VISIBLE
+
+/*
+ * Structure used to query names of interface cloners.
+ */
+
+struct if_clonereq {
+ int ifcr_total; /* total cloners (out) */
+ int ifcr_count; /* room for this many in user buffer */
+ char *ifcr_buffer; /* buffer for cloner names */
+};
+
+/*
+ * Structure describing information about an interface
+ * which may be of interest to management entities.
+ */
+struct if_data {
+ /* generic interface information */
+ u_char ifi_type; /* ethernet, tokenring, etc */
+ u_char ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */
+ u_char ifi_addrlen; /* media address length */
+ u_char ifi_hdrlen; /* media header length */
+ u_char ifi_recvquota; /* polling quota for receive intrs */
+ u_char ifi_xmitquota; /* polling quota for xmit intrs */
+ u_long ifi_mtu; /* maximum transmission unit */
+ u_long ifi_metric; /* routing metric (external only) */
+ u_long ifi_baudrate; /* linespeed */
+ /* volatile statistics */
+ u_long ifi_ipackets; /* packets received on interface */
+ u_long ifi_ierrors; /* input errors on interface */
+ u_long ifi_opackets; /* packets sent on interface */
+ u_long ifi_oerrors; /* output errors on interface */
+ u_long ifi_collisions; /* collisions on csma interfaces */
+ u_long ifi_ibytes; /* total number of octets received */
+ u_long ifi_obytes; /* total number of octets sent */
+ u_long ifi_imcasts; /* packets received via multicast */
+ u_long ifi_omcasts; /* packets sent via multicast */
+ u_long ifi_iqdrops; /* dropped on input, this interface */
+ u_long ifi_noproto; /* destined for unsupported protocol */
+ u_long ifi_recvtiming; /* usec spent receiving when timing */
+ u_long ifi_xmittiming; /* usec spent xmitting when timing */
+ struct timeval ifi_lastchange; /* time of last administrative change */
+};
+
+#define IFF_UP 0x1 /* interface is up */
+#define IFF_BROADCAST 0x2 /* broadcast address valid */
+#define IFF_DEBUG 0x4 /* turn on debugging */
+#define IFF_LOOPBACK 0x8 /* is a loopback net */
+#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */
+#define IFF_SMART 0x20 /* interface manages own routes */
+#define IFF_RUNNING 0x40 /* resources allocated */
+#define IFF_NOARP 0x80 /* no address resolution protocol */
+#define IFF_PROMISC 0x100 /* receive all packets */
+#define IFF_ALLMULTI 0x200 /* receive all multicast packets */
+#define IFF_OACTIVE 0x400 /* tx hardware queue is full */
+#define IFF_SIMPLEX 0x800 /* can't hear own transmissions */
+#define IFF_LINK0 0x1000 /* per link layer defined bit */
+#define IFF_LINK1 0x2000 /* per link layer defined bit */
+#define IFF_LINK2 0x4000 /* per link layer defined bit */
+#define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */
+#define IFF_MULTICAST 0x8000 /* supports multicast */
+#define IFF_POLLING 0x10000 /* Interface is in polling mode. */
+#define IFF_PPROMISC 0x20000 /* user-requested promisc mode */
+#define IFF_MONITOR 0x40000 /* user-requested monitor mode */
+#define IFF_STATICARP 0x80000 /* static ARP */
+#define IFF_NEEDSGIANT 0x100000 /* hold Giant over if_start calls */
+
+/* flags set internally only: */
+#define IFF_CANTCHANGE \
+ (IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
+ IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_SMART|IFF_PROMISC|\
+ IFF_POLLING)
+
+/*
+ * Values for if_link_state.
+ */
+#define LINK_STATE_UNKNOWN 0 /* link invalid/unknown */
+#define LINK_STATE_DOWN 1 /* link is down */
+#define LINK_STATE_UP 2 /* link is up */
+
+/*
+ * Some convenience macros used for setting ifi_baudrate.
+ * XXX 1000 vs. 1024? --thorpej@netbsd.org
+ */
+#define IF_Kbps(x) ((x) * 1000) /* kilobits/sec. */
+#define IF_Mbps(x) (IF_Kbps((x) * 1000)) /* megabits/sec. */
+#define IF_Gbps(x) (IF_Mbps((x) * 1000)) /* gigabits/sec. */
+
+#define IFQ_MAXLEN 50
+#define IFNET_SLOWHZ 1 /* granularity is 1 second */
+
+/*
+ * Message format for use in obtaining information about interfaces
+ * from getkerninfo and the routing socket
+ */
+struct if_msghdr {
+ u_short ifm_msglen; /* to skip over non-understood messages */
+ u_char ifm_version; /* future binary compatibility */
+ u_char ifm_type; /* message type */
+ int ifm_addrs; /* like rtm_addrs */
+ int ifm_flags; /* value of if_flags */
+ u_short ifm_index; /* index for associated ifp */
+ struct if_data ifm_data;/* statistics and other data about if */
+};
+
+/*
+ * Message format for use in obtaining information about interface addresses
+ * from getkerninfo and the routing socket
+ */
+struct ifa_msghdr {
+ u_short ifam_msglen; /* to skip over non-understood messages */
+ u_char ifam_version; /* future binary compatibility */
+ u_char ifam_type; /* message type */
+ int ifam_addrs; /* like rtm_addrs */
+ int ifam_flags; /* value of ifa_flags */
+ u_short ifam_index; /* index for associated ifp */
+ int ifam_metric; /* value of ifa_metric */
+};
+
+/* forward declaration */
+struct mbuf;
+
+/*
+ * Interface request structure used for socket
+ * ioctl's. All interface ioctl's must have parameter
+ * definitions which begin with ifr_name. The
+ * remainder may be interface specific.
+ */
+struct ifreq {
+ char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ union {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_dstaddr;
+ struct sockaddr ifru_broadaddr;
+ short ifru_flags[2];
+ int ifru_metric;
+ int ifru_mtu;
+ int ifru_phys;
+ int ifru_media;
+ caddr_t ifru_data;
+ int (*ifru_tap)(struct ifnet *, struct ether_header *, struct mbuf *);
+ } ifr_ifru;
+#define ifr_addr ifr_ifru.ifru_addr /* address */
+#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
+#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+#define ifr_flags ifr_ifru.ifru_flags[0] /* flags (low 16 bits) */
+#define ifr_flagshigh ifr_ifru.ifru_flags[1] /* flags (high 16 bits) */
+#define ifr_metric ifr_ifru.ifru_metric /* metric */
+#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
+#define ifr_phys ifr_ifru.ifru_phys /* physical wire */
+#define ifr_media ifr_ifru.ifru_media /* physical media */
+#define ifr_data ifr_ifru.ifru_data /* for use by interface */
+#define ifr_tap ifr_ifru.ifru_tap /* tap function */
+};
+
+struct ifaliasreq {
+ char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ struct sockaddr ifra_addr;
+ struct sockaddr ifra_broadaddr;
+ struct sockaddr ifra_mask;
+};
+
+struct ifmediareq {
+ char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ int ifm_current; /* current media options */
+ int ifm_mask; /* don't care mask */
+ int ifm_status; /* media status */
+ int ifm_active; /* active options */
+ int ifm_count; /* # entries in ifm_ulist array */
+ int *ifm_ulist; /* media words */
+};
+
+/*
+ * Structure used to retrieve aux status data from interfaces.
+ * Kernel suppliers to this interface should respect the formatting
+ * needed by ifconfig(8): each line starts with a TAB and ends with
+ * a newline. The canonical example to copy and paste is in if_tun.c.
+ */
+
+#define IFSTATMAX 800 /* 10 lines of text */
+struct ifstat {
+ char ifs_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ char ascii[IFSTATMAX + 1];
+};
+
+/*
+ * Structure used in SIOCGIFCONF request.
+ * Used to retrieve interface configuration
+ * for machine (useful for programs which
+ * must know all networks accessible).
+ */
+struct ifconf {
+ int ifc_len; /* size of associated buffer */
+ union {
+ caddr_t ifcu_buf;
+ struct ifreq *ifcu_req;
+ } ifc_ifcu;
+#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
+#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
+};
+#endif /* __BSD_VISIBLE */
+
+#ifdef _KERNEL
+
+/* XXX - this should go away soon. */
+#include <net/if_var.h>
+
+void ifafree __P((struct ifaddr *));
+
+int looutput __P((struct ifnet *,
+ struct mbuf *, struct sockaddr *, struct rtentry *));
+#endif
+
+#endif /* !_NET_IF_H_ */
diff --git a/cpukit/libnetworking/net/if_arp.h b/cpukit/libnetworking/net/if_arp.h
new file mode 100644
index 0000000000..165471777f
--- /dev/null
+++ b/cpukit/libnetworking/net/if_arp.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1986, 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.
+ * 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.
+ *
+ * @(#)if_arp.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if_arp.h,v 1.21 2005/01/07 01:45:34 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NET_IF_ARP_H_
+#define _NET_IF_ARP_H_
+
+/*
+ * Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description. ARP packets are variable
+ * in size; the arphdr structure defines the fixed-length portion.
+ * Protocol type values are the same as those for 10 Mb/s Ethernet.
+ * It is followed by the variable-sized fields ar_sha, arp_spa,
+ * arp_tha and arp_tpa in that order, according to the lengths
+ * specified. Field names used correspond to RFC 826.
+ */
+struct arphdr {
+ u_short ar_hrd; /* format of hardware address */
+#define ARPHRD_ETHER 1 /* ethernet hardware format */
+#define ARPHRD_IEEE802 6 /* token-ring hardware format */
+#define ARPHRD_ARCNET 7 /* arcnet hardware format */
+#define ARPHRD_FRELAY 15 /* frame relay hardware format */
+#define ARPHRD_IEEE1394 24 /* firewire hardware format */
+ u_short ar_pro; /* format of protocol address */
+ u_char ar_hln; /* length of hardware address */
+ u_char ar_pln; /* length of protocol address */
+ u_short ar_op; /* one of: */
+#define ARPOP_REQUEST 1 /* request to resolve address */
+#define ARPOP_REPLY 2 /* response to previous request */
+#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */
+#define ARPOP_REVREPLY 4 /* response giving protocol address */
+#define ARPOP_INVREQUEST 8 /* request to identify peer */
+#define ARPOP_INVREPLY 9 /* response identifying peer */
+/*
+ * The remaining fields are variable in size,
+ * according to the sizes above.
+ */
+#ifdef COMMENT_ONLY
+ u_char ar_sha[]; /* sender hardware address */
+ u_char ar_spa[]; /* sender protocol address */
+ u_char ar_tha[]; /* target hardware address */
+ u_char ar_tpa[]; /* target protocol address */
+#endif
+};
+
+#define ar_sha(ap) (((caddr_t)((ap)+1)) + 0)
+#define ar_spa(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln)
+#define ar_tha(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln + (ap)->ar_pln)
+#define ar_tpa(ap) (((caddr_t)((ap)+1)) + 2*(ap)->ar_hln + (ap)->ar_pln)
+
+#define arphdr_len2(ar_hln, ar_pln) \
+ (sizeof(struct arphdr) + 2*(ar_hln) + 2*(ar_pln))
+#define arphdr_len(ap) (arphdr_len2((ap)->ar_hln, (ap)->ar_pln))
+
+/*
+ * ARP ioctl request
+ */
+struct arpreq {
+ struct sockaddr arp_pa; /* protocol address */
+ struct sockaddr arp_ha; /* hardware address */
+ int arp_flags; /* flags */
+};
+/* arp_flags and at_flags field values */
+#define ATF_INUSE 0x01 /* entry in use */
+#define ATF_COM 0x02 /* completed entry (enaddr valid) */
+#define ATF_PERM 0x04 /* permanent entry */
+#define ATF_PUBL 0x08 /* publish entry (respond for other host) */
+#define ATF_USETRAILERS 0x10 /* has requested trailers */
+
+#ifdef _KERNEL
+/*
+ * Structure shared between the ethernet driver modules and
+ * the address resolution code. For example, each ec_softc or il_softc
+ * begins with this structure.
+ * The code is written so that each *_softc _must_ begin with a
+ * struct arpcom, which in turn _must_ begin with a struct ifnet.
+ */
+struct arpcom {
+ /*
+ * The ifnet struct _must_ be at the head of this structure.
+ */
+ struct ifnet ac_if; /* network-visible interface */
+ u_char ac_enaddr[6]; /* ethernet hardware address */
+#if defined(__rtems__)
+/* Cruft from ancient BSD - should be removed once RTEMS is updated */
+ struct ether_multi *ac_multiaddrs; /* list of ether multicast addrs */
+ int ac_multicnt; /* length of ac_multiaddrs list */
+#else
+ int now_unused; /* XXX was length of ac_multiaddrs list */
+ void *ac_netgraph; /* ng_ether(4) netgraph node info */
+#endif
+};
+#define IFP2AC(ifp) ((struct arpcom *)(ifp))
+
+#endif
+
+#endif /* !_NET_IF_ARP_H_ */
diff --git a/cpukit/libnetworking/net/if_dl.h b/cpukit/libnetworking/net/if_dl.h
new file mode 100644
index 0000000000..e739316be8
--- /dev/null
+++ b/cpukit/libnetworking/net/if_dl.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1990, 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.
+ * 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.
+ *
+ * @(#)if_dl.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if_dl.h,v 1.14 2005/01/07 01:45:34 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NET_IF_DL_H_
+#define _NET_IF_DL_H_
+
+/*
+ * A Link-Level Sockaddr may specify the interface in one of two
+ * ways: either by means of a system-provided index number (computed
+ * anew and possibly differently on every reboot), or by a human-readable
+ * string such as "il0" (for managerial convenience).
+ *
+ * Census taking actions, such as something akin to SIOCGCONF would return
+ * both the index and the human name.
+ *
+ * High volume transactions (such as giving a link-level ``from'' address
+ * in a recvfrom or recvmsg call) may be likely only to provide the indexed
+ * form, (which requires fewer copy operations and less space).
+ *
+ * The form and interpretation of the link-level address is purely a matter
+ * of convention between the device driver and its consumers; however, it is
+ * expected that all drivers for an interface of a given if_type will agree.
+ */
+
+/*
+ * Structure of a Link-Level sockaddr:
+ */
+struct sockaddr_dl {
+ u_char sdl_len; /* Total length of sockaddr */
+ u_char sdl_family; /* AF_LINK */
+ u_short sdl_index; /* if != 0, system given index for interface */
+ u_char sdl_type; /* interface type */
+ u_char sdl_nlen; /* interface name length, no trailing 0 reqd. */
+ u_char sdl_alen; /* link level address length */
+ u_char sdl_slen; /* link layer selector length */
+ char sdl_data[46]; /* minimum work area, can be larger;
+ contains both if name and ll address */
+};
+
+#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))
+
+#ifndef _KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+void link_addr(const char *, struct sockaddr_dl *);
+char *link_ntoa(const struct sockaddr_dl *);
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif
diff --git a/cpukit/libnetworking/net/if_ethersubr.c b/cpukit/libnetworking/net/if_ethersubr.c
new file mode 100644
index 0000000000..a1c5815e69
--- /dev/null
+++ b/cpukit/libnetworking/net/if_ethersubr.c
@@ -0,0 +1,899 @@
+/*
+ * Copyright (c) 1982, 1989, 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.
+ * 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.
+ *
+ * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if_ethersubr.c,v 1.189 2005/03/06 22:59:40 sobomax Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#include "opt_atalk.h"
+#include "opt_inet.h"
+#include "opt_inet6.h"
+#include "opt_ipx.h"
+#include "opt_bdg.h"
+#include "opt_mac.h"
+#include "opt_netgraph.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/syslog.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/netisr.h>
+#include <net/route.h>
+#include <net/if_llc.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/ethernet.h>
+
+#if defined(INET) || defined(INET6)
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_fw.h>
+#ifndef __rtems__
+#include <netinet/ip_dummynet.h>
+#endif
+#endif
+#ifdef INET6
+#include <netinet6/nd6.h>
+#endif
+
+#ifdef DEV_CARP
+#include <netinet/ip_carp.h>
+#endif
+
+#ifdef IPX
+#include <netipx/ipx.h>
+#include <netipx/ipx_if.h>
+#endif
+
+#ifdef NETATALK
+#include <netatalk/at.h>
+#include <netatalk/at_var.h>
+#include <netatalk/at_extern.h>
+
+#define llc_snap_org_code llc_un.type_snap.org_code
+#define llc_snap_ether_type llc_un.type_snap.ether_type
+
+extern u_char at_org_code[3];
+extern u_char aarp_org_code[3];
+#endif /* NETATALK */
+
+u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+#define senderr(e) do { error = (e); goto bad;} while (0)
+
+/*
+ * Ethernet output routine.
+ * Encapsulate a packet of type family for the local net.
+ * Use trailer local net encapsulation if enough data in first
+ * packet leaves a multiple of 512 bytes of data in remainder.
+ * Assumes that ifp is actually pointer to arpcom structure.
+ */
+int
+ether_output(struct ifnet *ifp, struct mbuf *m,
+ struct sockaddr *dst, struct rtentry *rt0)
+{
+ short type;
+ int s, error = 0;
+ u_char edst[6];
+ register struct rtentry *rt;
+ struct mbuf *mcopy = (struct mbuf *)0;
+ register struct ether_header *eh;
+ int off, len = m->m_pkthdr.len;
+ struct arpcom *ac = (struct arpcom *)ifp;
+#ifdef NETATALK
+ struct at_ifaddr *aa;
+#endif /* NETATALK */
+ int hlen; /* link layer header length */
+
+ if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
+ senderr(ENETDOWN);
+ rt = rt0;
+ if (rt) {
+ if ((rt->rt_flags & RTF_UP) == 0) {
+ rt0 = rt = rtalloc1(dst, 1, 0UL);
+ if (rt0)
+ rt->rt_refcnt--;
+ else
+ senderr(EHOSTUNREACH);
+ }
+ if (rt->rt_flags & RTF_GATEWAY) {
+ if (rt->rt_gwroute == 0)
+ goto lookup;
+ if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
+ rtfree(rt); rt = rt0;
+ lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
+ 0UL);
+ if ((rt = rt->rt_gwroute) == 0)
+ senderr(EHOSTUNREACH);
+ }
+ }
+ if (rt->rt_flags & RTF_REJECT)
+ if (rt->rt_rmx.rmx_expire == 0 ||
+ rtems_bsdnet_seconds_since_boot() < rt->rt_rmx.rmx_expire)
+ senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
+ }
+ hlen = ETHER_HDR_LEN;
+ switch (dst->sa_family) {
+
+#ifdef INET
+ case AF_INET:
+ if (!arpresolve(ac, rt, m, dst, edst, rt0))
+ return (0); /* if not yet resolved */
+ /* If broadcasting on a simplex interface, loopback a copy */
+ if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
+ mcopy = m_copy(m, 0, (int)M_COPYALL);
+ off = m->m_pkthdr.len - m->m_len;
+ type = htons(ETHERTYPE_IP);
+ break;
+#endif
+#ifdef IPX
+ case AF_IPX:
+ {
+ struct ifaddr *ia;
+
+ type = htons(ETHERTYPE_IPX);
+ bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
+ (caddr_t)edst, sizeof (edst));
+ for (ia = ifp->if_addrlist; ia != NULL; ia = ia->ifa_next)
+ if(ia->ifa_addr->sa_family == AF_IPX &&
+ !bcmp((caddr_t)edst,
+ (caddr_t)&((struct ipx_ifaddr *)ia)->ia_addr.sipx_addr.x_host,
+ sizeof(edst)))
+ return (looutput(ifp, m, dst, rt));
+ /* If broadcasting on a simplex interface, loopback a copy */
+ if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
+ mcopy = m_copy(m, 0, (int)M_COPYALL);
+ break;
+ }
+#endif
+#ifdef NETATALK
+ case AF_APPLETALK:
+ {
+ struct sockaddr_at *sat = (struct sockaddr_at *)dst;
+
+ /*
+ * super hack..
+ * Most of this loopback code should move into the appletalk
+ * code, but it's here for now.. remember to move it! [JRE]
+ * This may not get the same interface we started with
+ * fix asap. XXX
+ */
+ aa = at_ifawithnet( sat );
+ if (aa == NULL) {
+ goto bad;
+ }
+ if( aa->aa_ifa.ifa_ifp != ifp ) {
+ (*aa->aa_ifa.ifa_ifp->if_output)(aa->aa_ifa.ifa_ifp,
+ m,dst,rt);
+ }
+ if (((sat->sat_addr.s_net == ATADDR_ANYNET)
+ && (sat->sat_addr.s_node == ATADDR_ANYNODE))
+ || ((sat->sat_addr.s_net == aa->aa_addr.sat_addr.s_net )
+ && (sat->sat_addr.s_node == aa->aa_addr.sat_addr.s_node))) {
+ (void) looutput(ifp, m, dst, rt);
+ return(0);
+ }
+
+ if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
+#ifdef NETATALKDEBUG
+ extern char *prsockaddr(struct sockaddr *);
+ printf("aarpresolv: failed for %s\n", prsockaddr(dst));
+#endif /* NETATALKDEBUG */
+ return (0);
+ }
+
+ /*
+ * If broadcasting on a simplex interface, loopback a copy
+ */
+ if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
+ mcopy = m_copy(m, 0, (int)M_COPYALL);
+ }
+ /*
+ * In the phase 2 case, we need to prepend an mbuf for the llc header.
+ * Since we must preserve the value of m, which is passed to us by
+ * value, we m_copy() the first mbuf, and use it for our llc header.
+ */
+ if ( aa->aa_flags & AFA_PHASE2 ) {
+ struct llc llc;
+
+ M_PREPEND(m, sizeof(struct llc), M_WAIT);
+ len += sizeof(struct llc);
+ llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
+ llc.llc_control = LLC_UI;
+ bcopy(at_org_code, llc.llc_snap_org_code, sizeof(at_org_code));
+ llc.llc_snap_ether_type = htons( ETHERTYPE_AT );
+ bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc));
+ type = htons(m->m_pkthdr.len);
+ } else {
+ type = htons(ETHERTYPE_AT);
+ }
+ break;
+#endif /* NETATALK */
+
+ case AF_UNSPEC:
+ eh = (struct ether_header *)dst->sa_data;
+ (void)memcpy(edst, eh->ether_dhost, sizeof (edst));
+ type = eh->ether_type;
+ break;
+
+ default:
+ printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
+ dst->sa_family);
+ senderr(EAFNOSUPPORT);
+ }
+
+
+ if (mcopy)
+ (void) looutput(ifp, mcopy, dst, rt);
+ /*
+ * Add local net header. If no space in first mbuf,
+ * allocate another.
+ */
+ M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
+ if (m == NULL)
+ senderr(ENOBUFS);
+ eh = mtod(m, struct ether_header *);
+ (void)memcpy(&eh->ether_type, &type,
+ sizeof(eh->ether_type));
+ (void)memcpy(eh->ether_dhost, edst, sizeof (edst));
+ (void)memcpy(eh->ether_shost, ac->ac_enaddr,
+ sizeof(eh->ether_shost));
+ s = splimp();
+ /*
+ * Queue message on interface, and start output if interface
+ * not yet active.
+ */
+ if (IF_QFULL(&ifp->if_snd)) {
+ IF_DROP(&ifp->if_snd);
+ splx(s);
+ senderr(ENOBUFS);
+ }
+ IF_ENQUEUE(&ifp->if_snd, m);
+ if ((ifp->if_flags & IFF_OACTIVE) == 0)
+ (*ifp->if_start)(ifp);
+ splx(s);
+ ifp->if_obytes += len + sizeof (struct ether_header);
+ if (m->m_flags & M_MCAST)
+ ifp->if_omcasts++;
+ return (error);
+
+bad:
+ if (m)
+ m_freem(m);
+ return (error);
+}
+
+/*
+ * Process a received Ethernet packet;
+ * the packet is in the mbuf chain m without
+ * the ether header, which is provided separately.
+ */
+void
+ether_input(ifp, eh, m)
+ struct ifnet *ifp;
+ register struct ether_header *eh;
+ struct mbuf *m;
+{
+ register struct ifqueue *inq;
+ u_short ether_type;
+ int s;
+#if defined(NETATALK)
+ struct llc *l;
+#endif
+
+ if ((ifp->if_flags & IFF_UP) == 0) {
+ m_freem(m);
+ return;
+ }
+ ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
+ if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
+ sizeof(etherbroadcastaddr)) == 0)
+ m->m_flags |= M_BCAST;
+ else if (eh->ether_dhost[0] & 1)
+ m->m_flags |= M_MCAST;
+ if (m->m_flags & (M_BCAST|M_MCAST))
+ ifp->if_imcasts++;
+
+ /*
+ * RTEMS addition -- allow application to `tap into'
+ * the incoming packet stream.
+ */
+ if (ifp->if_tap && (*ifp->if_tap)(ifp, eh, m)) {
+ m_freem(m);
+ return;
+ }
+
+ ether_type = ntohs(eh->ether_type);
+
+ switch (ether_type) {
+#ifdef INET
+ case ETHERTYPE_IP:
+ schednetisr(NETISR_IP);
+ inq = &ipintrq;
+ break;
+
+ case ETHERTYPE_ARP:
+ schednetisr(NETISR_ARP);
+ inq = &arpintrq;
+ break;
+#endif
+#ifdef IPX
+ case ETHERTYPE_IPX:
+ schednetisr(NETISR_IPX);
+ inq = &ipxintrq;
+ break;
+#endif
+#ifdef NETATALK
+ case ETHERTYPE_AT:
+ schednetisr(NETISR_ATALK);
+ inq = &atintrq1;
+ break;
+ case ETHERTYPE_AARP:
+ /* probably this should be done with a NETISR as well */
+ aarpinput((struct arpcom *)ifp, m); /* XXX */
+ return;
+#endif /* NETATALK */
+ default:
+#if defined (ISO) || defined (LLC) || defined(NETATALK)
+ if (ether_type > ETHERMTU)
+ goto dropanyway;
+ l = mtod(m, struct llc *);
+ switch (l->llc_dsap) {
+#ifdef NETATALK
+ case LLC_SNAP_LSAP:
+ switch (l->llc_control) {
+ case LLC_UI:
+ if (l->llc_ssap != LLC_SNAP_LSAP)
+ goto dropanyway;
+
+ if (Bcmp(&(l->llc_snap_org_code)[0], at_org_code,
+ sizeof(at_org_code)) == 0 &&
+ ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {
+ inq = &atintrq2;
+ m_adj( m, sizeof( struct llc ));
+ schednetisr(NETISR_ATALK);
+ break;
+ }
+
+ if (Bcmp(&(l->llc_snap_org_code)[0], aarp_org_code,
+ sizeof(aarp_org_code)) == 0 &&
+ ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {
+ m_adj( m, sizeof( struct llc ));
+ aarpinput((struct arpcom *)ifp, m); /* XXX */
+ return;
+ }
+
+ default:
+ goto dropanyway;
+ }
+ break;
+#endif /* NETATALK */
+#ifdef ISO
+ case LLC_ISO_LSAP:
+ switch (l->llc_control) {
+ case LLC_UI:
+ /* LLC_UI_P forbidden in class 1 service */
+ if ((l->llc_dsap == LLC_ISO_LSAP) &&
+ (l->llc_ssap == LLC_ISO_LSAP)) {
+ /* LSAP for ISO */
+ if (m->m_pkthdr.len > ether_type)
+ m_adj(m, ether_type - m->m_pkthdr.len);
+ m->m_data += 3; /* XXX */
+ m->m_len -= 3; /* XXX */
+ m->m_pkthdr.len -= 3; /* XXX */
+ M_PREPEND(m, sizeof *eh, M_DONTWAIT);
+ if (m == 0)
+ return;
+ *mtod(m, struct ether_header *) = *eh;
+ IFDEBUG(D_ETHER)
+ printf("clnp packet");
+ ENDDEBUG
+ schednetisr(NETISR_ISO);
+ inq = &clnlintrq;
+ break;
+ }
+ goto dropanyway;
+
+ case LLC_XID:
+ case LLC_XID_P:
+ if(m->m_len < 6)
+ goto dropanyway;
+ l->llc_window = 0;
+ l->llc_fid = 9;
+ l->llc_class = 1;
+ l->llc_dsap = l->llc_ssap = 0;
+ /* Fall through to */
+ case LLC_TEST:
+ case LLC_TEST_P:
+ {
+ struct sockaddr sa;
+ register struct ether_header *eh2;
+ int i;
+ u_char c = l->llc_dsap;
+
+ l->llc_dsap = l->llc_ssap;
+ l->llc_ssap = c;
+ if (m->m_flags & (M_BCAST | M_MCAST))
+ bcopy((caddr_t)ac->ac_enaddr,
+ (caddr_t)eh->ether_dhost, 6);
+ sa.sa_family = AF_UNSPEC;
+ sa.sa_len = sizeof(sa);
+ eh2 = (struct ether_header *)sa.sa_data;
+ for (i = 0; i < 6; i++) {
+ eh2->ether_shost[i] = c = eh->ether_dhost[i];
+ eh2->ether_dhost[i] =
+ eh->ether_dhost[i] = eh->ether_shost[i];
+ eh->ether_shost[i] = c;
+ }
+ ifp->if_output(ifp, m, &sa, NULL);
+ return;
+ }
+ default:
+ m_freem(m);
+ return;
+ }
+ break;
+#endif /* ISO */
+#ifdef LLC
+ case LLC_X25_LSAP:
+ {
+ if (m->m_pkthdr.len > ether_type)
+ m_adj(m, ether_type - m->m_pkthdr.len);
+ M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
+ if (m == 0)
+ return;
+ if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,
+ eh->ether_dhost, LLC_X25_LSAP, 6,
+ mtod(m, struct sdl_hdr *)))
+ panic("ETHER cons addr failure");
+ mtod(m, struct sdl_hdr *)->sdlhdr_len = ether_type;
+#ifdef LLC_DEBUG
+ printf("llc packet\n");
+#endif /* LLC_DEBUG */
+ schednetisr(NETISR_CCITT);
+ inq = &llcintrq;
+ break;
+ }
+#endif /* LLC */
+ dropanyway:
+ default:
+ m_freem(m);
+ return;
+ }
+#else /* ISO || LLC || NETATALK */
+ m_freem(m);
+ return;
+#endif /* ISO || LLC || NETATALK */
+ }
+
+ s = splimp();
+ if (IF_QFULL(inq)) {
+ IF_DROP(inq);
+ m_freem(m);
+ } else
+ IF_ENQUEUE(inq, m);
+ splx(s);
+}
+
+/*
+ * Convert Ethernet address to printable (loggable) representation.
+ * The static buffer isn't a really huge problem since this code
+ * is protected by the RTEMS network mutex.
+ */
+char *
+ether_sprintf(const u_char *ap)
+{
+ static char buf[32];
+ char *b = buf;
+ int i;
+
+ for (i = 0; i < ETHER_ADDR_LEN; i++, b+=3)
+ sprintf(b, "%02x:", *ap++);
+ *--b = '\0';
+ return buf;
+}
+
+/*
+ * Perform common duties while attaching to interface list
+ */
+void
+ether_ifattach(struct ifnet *ifp)
+{
+ struct ifaddr *ifa;
+ struct sockaddr_dl *sdl;
+
+ ifp->if_type = IFT_ETHER;
+ ifp->if_addrlen = ETHER_ADDR_LEN;
+ ifp->if_hdrlen = ETHER_HDR_LEN;
+ ifp->if_mtu = ETHERMTU;
+ if (ifp->if_baudrate == 0)
+ ifp->if_baudrate = 10000000;
+ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
+ if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
+ sdl->sdl_family == AF_LINK) {
+ sdl->sdl_type = IFT_ETHER;
+ sdl->sdl_alen = ifp->if_addrlen;
+ bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
+ LLADDR(sdl), ifp->if_addrlen);
+ break;
+ }
+}
+
+#if defined(__rtems__)
+u_char ether_ipmulticast_min[6] =
+ { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
+u_char ether_ipmulticast_max[6] =
+ { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
+#else
+static u_char ether_ipmulticast_min[6] =
+ { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
+static u_char ether_ipmulticast_max[6] =
+ { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
+#endif
+
+/*
+ * Add an Ethernet multicast address or range of addresses to the list for a
+ * given interface.
+ */
+int
+ether_addmulti(ifr, ac)
+ struct ifreq *ifr;
+ register struct arpcom *ac;
+{
+ register struct ether_multi *enm;
+ struct sockaddr_in *sin;
+ u_char addrlo[6];
+ u_char addrhi[6];
+ int set_allmulti = 0;
+ int s = splimp();
+
+ switch (ifr->ifr_addr.sa_family) {
+
+ case AF_UNSPEC:
+ bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
+ bcopy(addrlo, addrhi, 6);
+ break;
+
+#ifdef INET
+ case AF_INET:
+ sin = (struct sockaddr_in *)&(ifr->ifr_addr);
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
+ /*
+ * An IP address of INADDR_ANY means listen to all
+ * of the Ethernet multicast addresses used for IP.
+ * (This is for the sake of IP multicast routers.)
+ */
+ bcopy(ether_ipmulticast_min, addrlo, 6);
+ bcopy(ether_ipmulticast_max, addrhi, 6);
+ set_allmulti = 1;
+ }
+ else {
+ ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
+ bcopy(addrlo, addrhi, 6);
+ }
+ break;
+#endif
+
+ default:
+ splx(s);
+ return (EAFNOSUPPORT);
+ }
+
+ /*
+ * Verify that we have valid Ethernet multicast addresses.
+ */
+ if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
+ splx(s);
+ return (EINVAL);
+ }
+ /*
+ * See if the address range is already in the list.
+ */
+ ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
+ if (enm != NULL) {
+ /*
+ * Found it; just increment the reference count.
+ */
+ ++enm->enm_refcount;
+ splx(s);
+ return (0);
+ }
+ /*
+ * New address or range; malloc a new multicast record
+ * and link it into the interface's multicast list.
+ */
+ enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
+ if (enm == NULL) {
+ splx(s);
+ return (ENOBUFS);
+ }
+ bcopy(addrlo, enm->enm_addrlo, 6);
+ bcopy(addrhi, enm->enm_addrhi, 6);
+ enm->enm_ac = ac;
+ enm->enm_refcount = 1;
+ enm->enm_next = ac->ac_multiaddrs;
+ ac->ac_multiaddrs = enm;
+ ac->ac_multicnt++;
+ splx(s);
+ if (set_allmulti)
+ ac->ac_if.if_flags |= IFF_ALLMULTI;
+
+ /*
+ * Return ENETRESET to inform the driver that the list has changed
+ * and its reception filter should be adjusted accordingly.
+ */
+ return (ENETRESET);
+}
+
+/*
+ * Delete a multicast address record.
+ */
+int
+ether_delmulti(ifr, ac)
+ struct ifreq *ifr;
+ register struct arpcom *ac;
+{
+ register struct ether_multi *enm;
+ register struct ether_multi **p;
+ struct sockaddr_in *sin;
+ u_char addrlo[6];
+ u_char addrhi[6];
+ int unset_allmulti = 0;
+ int s = splimp();
+
+ switch (ifr->ifr_addr.sa_family) {
+
+ case AF_UNSPEC:
+ bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
+ bcopy(addrlo, addrhi, 6);
+ break;
+
+#ifdef INET
+ case AF_INET:
+ sin = (struct sockaddr_in *)&(ifr->ifr_addr);
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
+ /*
+ * An IP address of INADDR_ANY means stop listening
+ * to the range of Ethernet multicast addresses used
+ * for IP.
+ */
+ bcopy(ether_ipmulticast_min, addrlo, 6);
+ bcopy(ether_ipmulticast_max, addrhi, 6);
+ unset_allmulti = 1;
+ }
+ else {
+ ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
+ bcopy(addrlo, addrhi, 6);
+ }
+ break;
+#endif
+
+ default:
+ splx(s);
+ return (EAFNOSUPPORT);
+ }
+
+ /*
+ * Look up the address in our list.
+ */
+ ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
+ if (enm == NULL) {
+ splx(s);
+ return (ENXIO);
+ }
+ if (--enm->enm_refcount != 0) {
+ /*
+ * Still some claims to this record.
+ */
+ splx(s);
+ return (0);
+ }
+ /*
+ * No remaining claims to this record; unlink and free it.
+ */
+ for (p = &enm->enm_ac->ac_multiaddrs;
+ *p != enm;
+ p = &(*p)->enm_next)
+ continue;
+ *p = (*p)->enm_next;
+ free(enm, M_IFMADDR);
+ ac->ac_multicnt--;
+ splx(s);
+ if (unset_allmulti)
+ ac->ac_if.if_flags &= ~IFF_ALLMULTI;
+
+ /*
+ * Return ENETRESET to inform the driver that the list has changed
+ * and its reception filter should be adjusted accordingly.
+ */
+ return (ENETRESET);
+}
+
+SYSCTL_DECL(_net_link);
+SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
+
+#if 0
+/*
+ * This is for reference. We have a table-driven version
+ * of the little-endian crc32 generator, which is faster
+ * than the double-loop.
+ */
+uint32_t
+ether_crc32_le(const uint8_t *buf, size_t len)
+{
+ size_t i;
+ uint32_t crc;
+ int bit;
+ uint8_t data;
+
+ crc = 0xffffffff; /* initial value */
+
+ for (i = 0; i < len; i++) {
+ for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1)
+ carry = (crc ^ data) & 1;
+ crc >>= 1;
+ if (carry)
+ crc = (crc ^ ETHER_CRC_POLY_LE);
+ }
+
+ return (crc);
+}
+#else
+uint32_t
+ether_crc32_le(const uint8_t *buf, size_t len)
+{
+ static const uint32_t crctab[] = {
+ 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
+ 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
+ 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
+ 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
+ };
+ size_t i;
+ uint32_t crc;
+
+ crc = 0xffffffff; /* initial value */
+
+ for (i = 0; i < len; i++) {
+ crc ^= buf[i];
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ }
+
+ return (crc);
+}
+#endif
+
+uint32_t
+ether_crc32_be(const uint8_t *buf, size_t len)
+{
+ size_t i;
+ uint32_t crc, carry;
+ int bit;
+ uint8_t data;
+
+ crc = 0xffffffff; /* initial value */
+
+ for (i = 0; i < len; i++) {
+ for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1) {
+ carry = ((crc & 0x80000000) ? 1 : 0) ^ (data & 0x01);
+ crc <<= 1;
+ if (carry)
+ crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
+ }
+ }
+
+ return (crc);
+}
+
+int
+ether_ioctl(struct ifnet *ifp, int command, caddr_t data)
+{
+ struct ifaddr *ifa = (struct ifaddr *) data;
+ struct ifreq *ifr = (struct ifreq *) data;
+ int error = 0;
+
+ switch (command) {
+ case SIOCSIFADDR:
+ ifp->if_flags |= IFF_UP;
+
+ switch (ifa->ifa_addr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ ifp->if_init(ifp->if_softc); /* before arpwhohas */
+ arp_ifinit((struct arpcom *)ifp, ifa);
+ break;
+#endif
+#ifdef IPX
+ /*
+ * XXX - This code is probably wrong
+ */
+ case AF_IPX:
+ {
+ struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
+ struct arpcom *ac = (struct arpcom *) (ifp->if_softc);
+
+ if (ipx_nullhost(*ina))
+ ina->x_host =
+ *(union ipx_host *)
+ ac->ac_enaddr;
+ else {
+ bcopy((caddr_t) ina->x_host.c_host,
+ (caddr_t) ac->ac_enaddr,
+ sizeof(ac->ac_enaddr));
+ }
+
+ /*
+ * Set new address
+ */
+ ifp->if_init(ifp->if_softc);
+ break;
+ }
+#endif
+ default:
+ ifp->if_init(ifp->if_softc);
+ break;
+ }
+ break;
+
+ case SIOCGIFADDR:
+ {
+ struct sockaddr *sa;
+
+ sa = (struct sockaddr *) & ifr->ifr_data;
+ bcopy(((struct arpcom *)ifp->if_softc)->ac_enaddr,
+ (caddr_t) sa->sa_data, ETHER_ADDR_LEN);
+ }
+ break;
+
+ case SIOCSIFMTU:
+ /*
+ * Set the interface MTU.
+ */
+ if (ifr->ifr_mtu > ETHERMTU) {
+ error = EINVAL;
+ } else {
+ ifp->if_mtu = ifr->ifr_mtu;
+ }
+ break;
+ }
+ return (error);
+}
diff --git a/cpukit/libnetworking/net/if_llc.h b/cpukit/libnetworking/net/if_llc.h
new file mode 100644
index 0000000000..5923e3abfc
--- /dev/null
+++ b/cpukit/libnetworking/net/if_llc.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 1988, 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.
+ * 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.
+ *
+ * @(#)if_llc.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if_llc.h,v 1.11 2005/01/07 01:45:34 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NET_IF_LLC_H_
+#define _NET_IF_LLC_H_
+
+#ifndef __packed
+#if defined(__GNUC__)
+#define __packed __attribute__((packed))
+#else
+#define __packed
+#endif
+#endif
+
+/*
+ * IEEE 802.2 Link Level Control headers, for use in conjunction with
+ * 802.{3,4,5} media access control methods.
+ *
+ * Headers here do not use bit fields due to shortcomings in many
+ * compilers.
+ */
+
+struct llc {
+ u_int8_t llc_dsap;
+ u_int8_t llc_ssap;
+ union {
+ struct {
+ u_int8_t control;
+ u_int8_t format_id;
+ u_int8_t class;
+ u_int8_t window_x2;
+ } type_u __packed;
+ struct {
+ u_int8_t num_snd_x2;
+ u_int8_t num_rcv_x2;
+ } type_i __packed;
+ struct {
+ u_int8_t control;
+ u_int8_t num_rcv_x2;
+ } type_s __packed;
+ struct {
+ u_int8_t control;
+ /*
+ * We cannot put the following fields in a structure because
+ * the structure rounding might cause padding.
+ */
+ u_int8_t frmr_rej_pdu0;
+ u_int8_t frmr_rej_pdu1;
+ u_int8_t frmr_control;
+ u_int8_t frmr_control_ext;
+ u_int8_t frmr_cause;
+ } type_frmr __packed;
+ struct {
+ u_int8_t control;
+ u_int8_t org_code[3];
+ u_int16_t ether_type;
+ } type_snap __packed;
+ struct {
+ u_int8_t control;
+ u_int8_t control_ext;
+ } type_raw __packed;
+ } llc_un /* XXX __packed ??? */;
+} __packed;
+
+struct frmrinfo {
+ u_int8_t frmr_rej_pdu0;
+ u_int8_t frmr_rej_pdu1;
+ u_int8_t frmr_control;
+ u_int8_t frmr_control_ext;
+ u_int8_t frmr_cause;
+} __packed;
+
+#define llc_control llc_un.type_u.control
+#define llc_control_ext llc_un.type_raw.control_ext
+#define llc_fid llc_un.type_u.format_id
+#define llc_class llc_un.type_u.class
+#define llc_window llc_un.type_u.window_x2
+#define llc_frmrinfo llc_un.type_frmr.frmr_rej_pdu0
+#define llc_frmr_pdu0 llc_un.type_frmr.frmr_rej_pdu0
+#define llc_frmr_pdu1 llc_un.type_frmr.frmr_rej_pdu1
+#define llc_frmr_control llc_un.type_frmr.frmr_control
+#define llc_frmr_control_ext llc_un.type_frmr.frmr_control_ext
+#define llc_frmr_cause llc_un.type_frmr.frmr_cause
+#define llc_snap llc_un.type_snap
+
+/*
+ * Don't use sizeof(struct llc_un) for LLC header sizes
+ */
+#define LLC_ISFRAMELEN 4
+#define LLC_UFRAMELEN 3
+#define LLC_FRMRLEN 7
+#define LLC_SNAPFRAMELEN 8
+
+/*
+ * Unnumbered LLC format commands
+ */
+#define LLC_UI 0x3
+#define LLC_UI_P 0x13
+#define LLC_DISC 0x43
+#define LLC_DISC_P 0x53
+#define LLC_UA 0x63
+#define LLC_UA_P 0x73
+#define LLC_TEST 0xe3
+#define LLC_TEST_P 0xf3
+#define LLC_FRMR 0x87
+#define LLC_FRMR_P 0x97
+#define LLC_DM 0x0f
+#define LLC_DM_P 0x1f
+#define LLC_XID 0xaf
+#define LLC_XID_P 0xbf
+#define LLC_SABME 0x6f
+#define LLC_SABME_P 0x7f
+
+/*
+ * Supervisory LLC commands
+ */
+#define LLC_RR 0x01
+#define LLC_RNR 0x05
+#define LLC_REJ 0x09
+
+/*
+ * Info format - dummy only
+ */
+#define LLC_INFO 0x00
+
+/*
+ * ISO PDTR 10178 contains among others
+ */
+#define LLC_X25_LSAP 0x7e
+#define LLC_SNAP_LSAP 0xaa
+#define LLC_ISO_LSAP 0xfe
+
+#endif /* _NET_IF_LLC_H_ */
diff --git a/cpukit/libnetworking/net/if_loop.c b/cpukit/libnetworking/net/if_loop.c
new file mode 100644
index 0000000000..c84abd9ded
--- /dev/null
+++ b/cpukit/libnetworking/net/if_loop.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ * 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.
+ *
+ * @(#)if_loop.c 8.2 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/net/if_loop.c,v 1.104 2005/02/24 01:34:01 sam Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+/*
+ * Loopback interface driver for protocol testing and timing.
+ */
+#include "loop.h"
+#if NLOOP > 0
+
+#include "opt_atalk.h"
+#include "opt_inet.h"
+#include "opt_inet6.h"
+#include "opt_ipx.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/netisr.h>
+#include <net/route.h>
+#include <net/bpf.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#endif
+
+#ifdef IPX
+#include <netipx/ipx.h>
+#include <netipx/ipx_if.h>
+#endif
+
+#ifdef INET6
+#ifndef INET
+#include <netinet/in.h>
+#endif
+#include <netinet6/in6_var.h>
+#include <netinet/ip6.h>
+#endif
+
+#ifdef NETATALK
+#include <netatalk/at.h>
+#include <netatalk/at_var.h>
+#endif
+
+static int loioctl(struct ifnet *, u_long, caddr_t);
+static void lortrequest(int, struct rtentry *, struct sockaddr *);
+
+ void rtems_bsdnet_loopattach(void *);
+PSEUDO_SET(loopattach, if_loop);
+
+#ifdef TINY_LOMTU
+#define LOMTU (1024+512)
+#elif defined(LARGE_LOMTU)
+#define LOMTU 131072
+#else
+#define LOMTU 16384
+#endif
+
+struct ifnet loif[NLOOP];
+
+/* ARGSUSED */
+void
+rtems_bsdnet_loopattach(dummy)
+ void *dummy;
+{
+ register struct ifnet *ifp;
+ register int i = 0;
+
+ for (ifp = loif; i < NLOOP; ifp++) {
+ ifp->if_name = "lo";
+ ifp->if_next = NULL;
+ ifp->if_unit = i++;
+ ifp->if_mtu = LOMTU;
+ ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
+ ifp->if_ioctl = loioctl;
+ ifp->if_output = looutput;
+ ifp->if_type = IFT_LOOP;
+ ifp->if_hdrlen = 0;
+ ifp->if_addrlen = 0;
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ if_attach(ifp);
+#if NBPFILTER > 0
+ bpfattach(ifp, DLT_NULL, sizeof(u_int));
+#endif
+ }
+}
+
+int
+looutput(ifp, m, dst, rt)
+ struct ifnet *ifp;
+ register struct mbuf *m;
+ struct sockaddr *dst;
+ register struct rtentry *rt;
+{
+ int s, isr;
+ register struct ifqueue *ifq = 0;
+
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("looutput no HDR");
+#if NBPFILTER > 0
+ /* BPF write needs to be handled specially */
+ if (dst->sa_family == AF_UNSPEC) {
+ dst->sa_family = *(mtod(m, int *));
+ m->m_len -= sizeof(int);
+ m->m_pkthdr.len -= sizeof(int);
+ m->m_data += sizeof(int);
+ }
+
+ /* Let BPF see incoming packet */
+ if (ifp->if_bpf) {
+ /*
+ * We need to prepend the address family as
+ * a four byte field. Cons up a dummy header
+ * to pacify bpf. This is safe because bpf
+ * will only read from the mbuf (i.e., it won't
+ * try to free it or keep a pointer a to it).
+ */
+ struct mbuf m0;
+ u_int af = dst->sa_family;
+
+ m0.m_next = m;
+ m0.m_len = 4;
+ m0.m_data = (char *)&af;
+
+ bpf_mtap(ifp, &m0);
+ }
+#endif
+ m->m_pkthdr.rcvif = ifp;
+
+ if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
+ m_freem(m);
+ return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
+ rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+ }
+ ifp->if_opackets++;
+ ifp->if_obytes += m->m_pkthdr.len;
+ switch (dst->sa_family) {
+
+#ifdef INET
+ case AF_INET:
+ ifq = &ipintrq;
+ isr = NETISR_IP;
+ break;
+#endif
+#ifdef IPX
+ case AF_IPX:
+ ifq = &ipxintrq;
+ isr = NETISR_IPX;
+ break;
+#endif
+#ifdef NETATALK
+ case AF_APPLETALK:
+ ifq = &atintrq2;
+ isr = NETISR_ATALK;
+ break;
+#endif /* NETATALK */
+ default:
+ printf("lo%d: can't handle af%d\n", ifp->if_unit,
+ dst->sa_family);
+ m_freem(m);
+ return (EAFNOSUPPORT);
+ }
+ s = splimp();
+ if (IF_QFULL(ifq)) {
+ IF_DROP(ifq);
+ m_freem(m);
+ splx(s);
+ return (ENOBUFS);
+ }
+ IF_ENQUEUE(ifq, m);
+ schednetisr(isr);
+ ifp->if_ipackets++;
+ ifp->if_ibytes += m->m_pkthdr.len;
+ splx(s);
+ return (0);
+}
+
+/* ARGSUSED */
+static void
+lortrequest(cmd, rt, sa)
+ int cmd;
+ struct rtentry *rt;
+ struct sockaddr *sa;
+{
+ if (rt) {
+ rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; /* for ISO */
+ /*
+ * For optimal performance, the send and receive buffers
+ * should be at least twice the MTU plus a little more for
+ * overhead.
+ */
+ rt->rt_rmx.rmx_recvpipe =
+ rt->rt_rmx.rmx_sendpipe = 3 * LOMTU;
+ }
+}
+
+/*
+ * Process an ioctl request.
+ */
+/* ARGSUSED */
+static int
+loioctl(ifp, cmd, data)
+ register struct ifnet *ifp;
+ u_long cmd;
+ caddr_t data;
+{
+ register struct ifaddr *ifa;
+ register struct ifreq *ifr = (struct ifreq *)data;
+ register int error = 0;
+
+ switch (cmd) {
+
+ case SIOCSIFADDR:
+ ifp->if_flags |= IFF_UP | IFF_RUNNING;
+ ifa = (struct ifaddr *)data;
+ ifa->ifa_rtrequest = lortrequest;
+ /*
+ * Everything else is done at a higher level.
+ */
+ break;
+
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ if (ifr == 0) {
+ error = EAFNOSUPPORT; /* XXX */
+ break;
+ }
+ switch (ifr->ifr_addr.sa_family) {
+
+#ifdef INET
+ case AF_INET:
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ break;
+#endif
+
+ default:
+ error = EAFNOSUPPORT;
+ break;
+ }
+ break;
+
+ case SIOCSIFMTU:
+ ifp->if_mtu = ifr->ifr_mtu;
+ break;
+
+ case SIOCSIFFLAGS:
+ break;
+
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+#endif /* NLOOP > 0 */
diff --git a/cpukit/libnetworking/net/if_media.h b/cpukit/libnetworking/net/if_media.h
new file mode 100644
index 0000000000..e52c89c021
--- /dev/null
+++ b/cpukit/libnetworking/net/if_media.h
@@ -0,0 +1,527 @@
+/* $NetBSD: if_media.h,v 1.3 1997/03/26 01:19:27 thorpej Exp $ */
+/* $FreeBSD: src/sys/net/if_media.h,v 1.26 2004/01/26 11:52:32 harti Exp $ */
+
+/*
+ * Copyright (c) 1997
+ * Jonathan Stone and Jason R. Thorpe. All rights reserved.
+ *
+ * This software is derived from information provided by Matt Thomas.
+ *
+ * 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 Jonathan Stone
+ * and Jason R. Thorpe for the NetBSD Project.
+ * 4. The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHOR 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.
+ */
+
+#ifndef _NET_IF_MEDIA_H_
+#define _NET_IF_MEDIA_H_
+
+/*
+ * Prototypes and definitions for BSD/OS-compatible network interface
+ * media selection.
+ *
+ * Where it is safe to do so, this code strays slightly from the BSD/OS
+ * design. Software which uses the API (device drivers, basically)
+ * shouldn't notice any difference.
+ *
+ * Many thanks to Matt Thomas for providing the information necessary
+ * to implement this interface.
+ */
+
+#ifdef _KERNEL
+
+#include <sys/queue.h>
+
+/*
+ * Driver callbacks for media status and change requests.
+ */
+typedef int (*ifm_change_cb_t)(struct ifnet *ifp);
+typedef void (*ifm_stat_cb_t)(struct ifnet *ifp, struct ifmediareq *req);
+
+/*
+ * In-kernel representation of a single supported media type.
+ */
+struct ifmedia_entry {
+ LIST_ENTRY(ifmedia_entry) ifm_list;
+ int ifm_media; /* description of this media attachment */
+ int ifm_data; /* for driver-specific use */
+ void *ifm_aux; /* for driver-specific use */
+};
+
+/*
+ * One of these goes into a network interface's softc structure.
+ * It is used to keep general media state.
+ */
+struct ifmedia {
+ int ifm_mask; /* mask of changes we don't care about */
+ int ifm_media; /* current user-set media word */
+ struct ifmedia_entry *ifm_cur; /* currently selected media */
+ LIST_HEAD(, ifmedia_entry) ifm_list; /* list of all supported media */
+ ifm_change_cb_t ifm_change; /* media change driver callback */
+ ifm_stat_cb_t ifm_status; /* media status driver callback */
+};
+
+/* Initialize an interface's struct if_media field. */
+void ifmedia_init(struct ifmedia *ifm, int dontcare_mask,
+ ifm_change_cb_t change_callback, ifm_stat_cb_t status_callback);
+
+/* Remove all mediums from a struct ifmedia. */
+void ifmedia_removeall( struct ifmedia *ifm);
+
+/* Add one supported medium to a struct ifmedia. */
+void ifmedia_add(struct ifmedia *ifm, int mword, int data, void *aux);
+
+/* Add an array (of ifmedia_entry) media to a struct ifmedia. */
+void ifmedia_list_add(struct ifmedia *mp, struct ifmedia_entry *lp,
+ int count);
+
+/* Set default media type on initialization. */
+void ifmedia_set(struct ifmedia *ifm, int mword);
+
+/* Common ioctl function for getting/setting media, called by driver. */
+int ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr,
+ struct ifmedia *ifm, u_long cmd);
+
+#endif /*_KERNEL */
+
+/*
+ * if_media Options word:
+ * Bits Use
+ * ---- -------
+ * 0-4 Media variant
+ * 5-7 Media type
+ * 8-15 Type specific options
+ * 16-18 Mode (for multi-mode devices)
+ * 19 RFU
+ * 20-27 Shared (global) options
+ * 28-31 Instance
+ */
+
+/*
+ * Ethernet
+ */
+#define IFM_ETHER 0x00000020
+#define IFM_10_T 3 /* 10BaseT - RJ45 */
+#define IFM_10_2 4 /* 10Base2 - Thinnet */
+#define IFM_10_5 5 /* 10Base5 - AUI */
+#define IFM_100_TX 6 /* 100BaseTX - RJ45 */
+#define IFM_100_FX 7 /* 100BaseFX - Fiber */
+#define IFM_100_T4 8 /* 100BaseT4 - 4 pair cat 3 */
+#define IFM_100_VG 9 /* 100VG-AnyLAN */
+#define IFM_100_T2 10 /* 100BaseT2 */
+#define IFM_1000_SX 11 /* 1000BaseSX - multi-mode fiber */
+#define IFM_10_STP 12 /* 10BaseT over shielded TP */
+#define IFM_10_FL 13 /* 10BaseFL - Fiber */
+#define IFM_1000_LX 14 /* 1000baseLX - single-mode fiber */
+#define IFM_1000_CX 15 /* 1000baseCX - 150ohm STP */
+#define IFM_1000_T 16 /* 1000baseT - 4 pair cat 5 */
+#define IFM_HPNA_1 17 /* HomePNA 1.0 (1Mb/s) */
+/* note 31 is the max! */
+
+#define IFM_ETH_MASTER 0x00000100 /* master mode (1000baseT) */
+
+/*
+ * Token ring
+ */
+#define IFM_TOKEN 0x00000040
+#define IFM_TOK_STP4 3 /* Shielded twisted pair 4m - DB9 */
+#define IFM_TOK_STP16 4 /* Shielded twisted pair 16m - DB9 */
+#define IFM_TOK_UTP4 5 /* Unshielded twisted pair 4m - RJ45 */
+#define IFM_TOK_UTP16 6 /* Unshielded twisted pair 16m - RJ45 */
+#define IFM_TOK_STP100 7 /* Shielded twisted pair 100m - DB9 */
+#define IFM_TOK_UTP100 8 /* Unshielded twisted pair 100m - RJ45 */
+#define IFM_TOK_ETR 0x00000200 /* Early token release */
+#define IFM_TOK_SRCRT 0x00000400 /* Enable source routing features */
+#define IFM_TOK_ALLR 0x00000800 /* All routes / Single route bcast */
+#define IFM_TOK_DTR 0x00002000 /* Dedicated token ring */
+#define IFM_TOK_CLASSIC 0x00004000 /* Classic token ring */
+#define IFM_TOK_AUTO 0x00008000 /* Automatic Dedicate/Classic token ring */
+
+/*
+ * FDDI
+ */
+#define IFM_FDDI 0x00000060
+#define IFM_FDDI_SMF 3 /* Single-mode fiber */
+#define IFM_FDDI_MMF 4 /* Multi-mode fiber */
+#define IFM_FDDI_UTP 5 /* CDDI / UTP */
+#define IFM_FDDI_DA 0x00000100 /* Dual attach / single attach */
+
+/*
+ * IEEE 802.11 Wireless
+ */
+#define IFM_IEEE80211 0x00000080
+/* NB: 0,1,2 are auto, manual, none defined below */
+#define IFM_IEEE80211_FH1 3 /* Frequency Hopping 1Mbps */
+#define IFM_IEEE80211_FH2 4 /* Frequency Hopping 2Mbps */
+#define IFM_IEEE80211_DS1 5 /* Direct Sequence 1Mbps */
+#define IFM_IEEE80211_DS2 6 /* Direct Sequence 2Mbps */
+#define IFM_IEEE80211_DS5 7 /* Direct Sequence 5.5Mbps */
+#define IFM_IEEE80211_DS11 8 /* Direct Sequence 11Mbps */
+#define IFM_IEEE80211_DS22 9 /* Direct Sequence 22Mbps */
+#define IFM_IEEE80211_OFDM6 10 /* OFDM 6Mbps */
+#define IFM_IEEE80211_OFDM9 11 /* OFDM 9Mbps */
+#define IFM_IEEE80211_OFDM12 12 /* OFDM 12Mbps */
+#define IFM_IEEE80211_OFDM18 13 /* OFDM 18Mbps */
+#define IFM_IEEE80211_OFDM24 14 /* OFDM 24Mbps */
+#define IFM_IEEE80211_OFDM36 15 /* OFDM 36Mbps */
+#define IFM_IEEE80211_OFDM48 16 /* OFDM 48Mbps */
+#define IFM_IEEE80211_OFDM54 17 /* OFDM 54Mbps */
+#define IFM_IEEE80211_OFDM72 18 /* OFDM 72Mbps */
+
+#define IFM_IEEE80211_ADHOC 0x00000100 /* Operate in Adhoc mode */
+#define IFM_IEEE80211_HOSTAP 0x00000200 /* Operate in Host AP mode */
+#define IFM_IEEE80211_IBSS 0x00000400 /* Operate in IBSS mode */
+#define IFM_IEEE80211_IBSSMASTER 0x00000800 /* Operate as an IBSS master */
+#define IFM_IEEE80211_TURBO 0x00001000 /* Operate in turbo mode */
+#define IFM_IEEE80211_MONITOR 0x00002000 /* Operate in monitor mode */
+
+/* operating mode for multi-mode devices */
+#define IFM_IEEE80211_11A 0x00010000 /* 5Ghz, OFDM mode */
+#define IFM_IEEE80211_11B 0x00020000 /* Direct Sequence mode */
+#define IFM_IEEE80211_11G 0x00030000 /* 2Ghz, CCK mode */
+#define IFM_IEEE80211_FH 0x00040000 /* 2Ghz, GFSK mode */
+
+/*
+ * ATM
+ */
+#define IFM_ATM 0x000000a0
+#define IFM_ATM_UNKNOWN 3
+#define IFM_ATM_UTP_25 4
+#define IFM_ATM_TAXI_100 5
+#define IFM_ATM_TAXI_140 6
+#define IFM_ATM_MM_155 7
+#define IFM_ATM_SM_155 8
+#define IFM_ATM_UTP_155 9
+#define IFM_ATM_MM_622 10
+#define IFM_ATM_SM_622 11
+#define IFM_ATM_VIRTUAL 12
+#define IFM_ATM_SDH 0x00000100 /* SDH instead of SONET */
+#define IFM_ATM_NOSCRAMB 0x00000200 /* no scrambling */
+#define IFM_ATM_UNASSIGNED 0x00000400 /* unassigned cells */
+
+/*
+ * Shared media sub-types
+ */
+#define IFM_AUTO 0 /* Autoselect best media */
+#define IFM_MANUAL 1 /* Jumper/dipswitch selects media */
+#define IFM_NONE 2 /* Deselect all media */
+
+/*
+ * Shared options
+ */
+#define IFM_FDX 0x00100000 /* Force full duplex */
+#define IFM_HDX 0x00200000 /* Force half duplex */
+#define IFM_FLAG0 0x01000000 /* Driver defined flag */
+#define IFM_FLAG1 0x02000000 /* Driver defined flag */
+#define IFM_FLAG2 0x04000000 /* Driver defined flag */
+#define IFM_LOOP 0x08000000 /* Put hardware in loopback */
+
+/*
+ * Masks
+ */
+#define IFM_NMASK 0x000000e0 /* Network type */
+#define IFM_TMASK 0x0000001f /* Media sub-type */
+#define IFM_IMASK 0xf0000000 /* Instance */
+#define IFM_ISHIFT 28 /* Instance shift */
+#define IFM_OMASK 0x0000ff00 /* Type specific options */
+#define IFM_MMASK 0x00070000 /* Mode */
+#define IFM_MSHIFT 16 /* Mode shift */
+#define IFM_GMASK 0x0ff00000 /* Global options */
+
+/*
+ * Status bits
+ */
+#define IFM_AVALID 0x00000001 /* Active bit valid */
+#define IFM_ACTIVE 0x00000002 /* Interface attached to working net */
+
+/*
+ * Macros to extract various bits of information from the media word.
+ */
+#define IFM_TYPE(x) ((x) & IFM_NMASK)
+#define IFM_SUBTYPE(x) ((x) & IFM_TMASK)
+#define IFM_TYPE_OPTIONS(x) ((x) & IFM_OMASK)
+#define IFM_INST(x) (((x) & IFM_IMASK) >> IFM_ISHIFT)
+#define IFM_OPTIONS(x) ((x) & (IFM_OMASK|IFM_GMASK))
+#define IFM_MODE(x) ((x) & IFM_MMASK)
+
+#define IFM_INST_MAX IFM_INST(IFM_IMASK)
+
+/*
+ * Macro to create a media word.
+ */
+#define IFM_MAKEWORD(type, subtype, options, instance) \
+ ((type) | (subtype) | (options) | ((instance) << IFM_ISHIFT))
+#define IFM_MAKEMODE(mode) \
+ (((mode) << IFM_MSHIFT) & IFM_MMASK)
+
+/*
+ * NetBSD extension not defined in the BSDI API. This is used in various
+ * places to get the canonical description for a given type/subtype.
+ *
+ * NOTE: all but the top-level type descriptions must contain NO whitespace!
+ * Otherwise, parsing these in ifconfig(8) would be a nightmare.
+ */
+struct ifmedia_description {
+ int ifmt_word; /* word value; may be masked */
+ const char *ifmt_string; /* description */
+};
+
+#define IFM_TYPE_DESCRIPTIONS { \
+ { IFM_ETHER, "Ethernet" }, \
+ { IFM_TOKEN, "Token ring" }, \
+ { IFM_FDDI, "FDDI" }, \
+ { IFM_IEEE80211, "IEEE 802.11 Wireless Ethernet" }, \
+ { IFM_ATM, "ATM" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_ETHERNET_DESCRIPTIONS { \
+ { IFM_10_T, "10baseT/UTP" }, \
+ { IFM_10_2, "10base2/BNC" }, \
+ { IFM_10_5, "10base5/AUI" }, \
+ { IFM_100_TX, "100baseTX" }, \
+ { IFM_100_FX, "100baseFX" }, \
+ { IFM_100_T4, "100baseT4" }, \
+ { IFM_100_VG, "100baseVG" }, \
+ { IFM_100_T2, "100baseT2" }, \
+ { IFM_10_STP, "10baseSTP" }, \
+ { IFM_10_FL, "10baseFL" }, \
+ { IFM_1000_SX, "1000baseSX" }, \
+ { IFM_1000_LX, "1000baseLX" }, \
+ { IFM_1000_CX, "1000baseCX" }, \
+ { IFM_1000_T, "1000baseTX" }, \
+ { IFM_1000_T, "1000baseT" }, \
+ { IFM_HPNA_1, "homePNA" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_ETHERNET_ALIASES { \
+ { IFM_10_T, "UTP" }, \
+ { IFM_10_T, "10UTP" }, \
+ { IFM_10_2, "BNC" }, \
+ { IFM_10_2, "10BNC" }, \
+ { IFM_10_5, "AUI" }, \
+ { IFM_10_5, "10AUI" }, \
+ { IFM_100_TX, "100TX" }, \
+ { IFM_100_T4, "100T4" }, \
+ { IFM_100_VG, "100VG" }, \
+ { IFM_100_T2, "100T2" }, \
+ { IFM_10_STP, "10STP" }, \
+ { IFM_10_FL, "10FL" }, \
+ { IFM_1000_SX, "1000SX" }, \
+ { IFM_1000_LX, "1000LX" }, \
+ { IFM_1000_CX, "1000CX" }, \
+ { IFM_1000_T, "1000TX" }, \
+ { IFM_1000_T, "1000T" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS { \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_TOKENRING_DESCRIPTIONS { \
+ { IFM_TOK_STP4, "DB9/4Mbit" }, \
+ { IFM_TOK_STP16, "DB9/16Mbit" }, \
+ { IFM_TOK_UTP4, "UTP/4Mbit" }, \
+ { IFM_TOK_UTP16, "UTP/16Mbit" }, \
+ { IFM_TOK_STP100, "STP/100Mbit" }, \
+ { IFM_TOK_UTP100, "UTP/100Mbit" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_TOKENRING_ALIASES { \
+ { IFM_TOK_STP4, "4STP" }, \
+ { IFM_TOK_STP16, "16STP" }, \
+ { IFM_TOK_UTP4, "4UTP" }, \
+ { IFM_TOK_UTP16, "16UTP" }, \
+ { IFM_TOK_STP100, "100STP" }, \
+ { IFM_TOK_UTP100, "100UTP" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS { \
+ { IFM_TOK_ETR, "EarlyTokenRelease" }, \
+ { IFM_TOK_SRCRT, "SourceRouting" }, \
+ { IFM_TOK_ALLR, "AllRoutes" }, \
+ { IFM_TOK_DTR, "Dedicated" }, \
+ { IFM_TOK_CLASSIC,"Classic" }, \
+ { IFM_TOK_AUTO, " " }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_FDDI_DESCRIPTIONS { \
+ { IFM_FDDI_SMF, "Single-mode" }, \
+ { IFM_FDDI_MMF, "Multi-mode" }, \
+ { IFM_FDDI_UTP, "UTP" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_FDDI_ALIASES { \
+ { IFM_FDDI_SMF, "SMF" }, \
+ { IFM_FDDI_MMF, "MMF" }, \
+ { IFM_FDDI_UTP, "CDDI" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS { \
+ { IFM_FDDI_DA, "Dual-attach" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_IEEE80211_DESCRIPTIONS { \
+ { IFM_IEEE80211_FH1, "FH/1Mbps" }, \
+ { IFM_IEEE80211_FH2, "FH/2Mbps" }, \
+ { IFM_IEEE80211_DS1, "DS/1Mbps" }, \
+ { IFM_IEEE80211_DS2, "DS/2Mbps" }, \
+ { IFM_IEEE80211_DS5, "DS/5.5Mbps" }, \
+ { IFM_IEEE80211_DS11, "DS/11Mbps" }, \
+ { IFM_IEEE80211_DS22, "DS/22Mbps" }, \
+ { IFM_IEEE80211_OFDM6, "OFDM/6Mbps" }, \
+ { IFM_IEEE80211_OFDM9, "OFDM/9Mbps" }, \
+ { IFM_IEEE80211_OFDM12, "OFDM/12Mbps" }, \
+ { IFM_IEEE80211_OFDM18, "OFDM/18Mbps" }, \
+ { IFM_IEEE80211_OFDM24, "OFDM/24Mbps" }, \
+ { IFM_IEEE80211_OFDM36, "OFDM/36Mbps" }, \
+ { IFM_IEEE80211_OFDM48, "OFDM/48Mbps" }, \
+ { IFM_IEEE80211_OFDM54, "OFDM/54Mbps" }, \
+ { IFM_IEEE80211_OFDM72, "OFDM/72Mbps" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_IEEE80211_ALIASES { \
+ { IFM_IEEE80211_FH1, "FH1" }, \
+ { IFM_IEEE80211_FH2, "FH2" }, \
+ { IFM_IEEE80211_FH1, "FrequencyHopping/1Mbps" }, \
+ { IFM_IEEE80211_FH2, "FrequencyHopping/2Mbps" }, \
+ { IFM_IEEE80211_DS1, "DS1" }, \
+ { IFM_IEEE80211_DS2, "DS2" }, \
+ { IFM_IEEE80211_DS5, "DS5.5" }, \
+ { IFM_IEEE80211_DS11, "DS11" }, \
+ { IFM_IEEE80211_DS22, "DS22" }, \
+ { IFM_IEEE80211_DS1, "DirectSequence/1Mbps" }, \
+ { IFM_IEEE80211_DS2, "DirectSequence/2Mbps" }, \
+ { IFM_IEEE80211_DS5, "DirectSequence/5.5Mbps" }, \
+ { IFM_IEEE80211_DS11, "DirectSequence/11Mbps" }, \
+ { IFM_IEEE80211_DS22, "DirectSequence/22Mbps" }, \
+ { IFM_IEEE80211_OFDM6, "OFDM6" }, \
+ { IFM_IEEE80211_OFDM9, "OFDM9" }, \
+ { IFM_IEEE80211_OFDM12, "OFDM12" }, \
+ { IFM_IEEE80211_OFDM18, "OFDM18" }, \
+ { IFM_IEEE80211_OFDM24, "OFDM24" }, \
+ { IFM_IEEE80211_OFDM36, "OFDM36" }, \
+ { IFM_IEEE80211_OFDM48, "OFDM48" }, \
+ { IFM_IEEE80211_OFDM54, "OFDM54" }, \
+ { IFM_IEEE80211_OFDM72, "OFDM72" }, \
+ { IFM_IEEE80211_DS1, "CCK1" }, \
+ { IFM_IEEE80211_DS2, "CCK2" }, \
+ { IFM_IEEE80211_DS5, "CCK5.5" }, \
+ { IFM_IEEE80211_DS11, "CCK11" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS { \
+ { IFM_IEEE80211_ADHOC, "adhoc" }, \
+ { IFM_IEEE80211_HOSTAP, "hostap" }, \
+ { IFM_IEEE80211_IBSS, "ibss" }, \
+ { IFM_IEEE80211_IBSSMASTER, "ibss-master" }, \
+ { IFM_IEEE80211_TURBO, "turbo" }, \
+ { IFM_IEEE80211_MONITOR, "monitor" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS { \
+ { IFM_AUTO, "autoselect" }, \
+ { IFM_IEEE80211_11A, "11a" }, \
+ { IFM_IEEE80211_11B, "11b" }, \
+ { IFM_IEEE80211_11G, "11g" }, \
+ { IFM_IEEE80211_FH, "fh" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_IEEE80211_MODE_ALIASES { \
+ { IFM_AUTO, "auto" }, \
+ { 0, NULL }, \
+}
+
+# define IFM_SUBTYPE_ATM_DESCRIPTIONS { \
+ { IFM_ATM_UNKNOWN, "Unknown" }, \
+ { IFM_ATM_UTP_25, "UTP/25.6MBit" }, \
+ { IFM_ATM_TAXI_100, "Taxi/100MBit" }, \
+ { IFM_ATM_TAXI_140, "Taxi/140MBit" }, \
+ { IFM_ATM_MM_155, "Multi-mode/155MBit" }, \
+ { IFM_ATM_SM_155, "Single-mode/155MBit" }, \
+ { IFM_ATM_UTP_155, "UTP/155MBit" }, \
+ { IFM_ATM_MM_622, "Multi-mode/622MBit" }, \
+ { IFM_ATM_SM_622, "Single-mode/622MBit" }, \
+ { IFM_ATM_VIRTUAL, "Virtual" }, \
+ { 0, NULL }, \
+}
+
+# define IFM_SUBTYPE_ATM_ALIASES { \
+ { IFM_ATM_UNKNOWN, "UNKNOWN" }, \
+ { IFM_ATM_UTP_25, "UTP-25" }, \
+ { IFM_ATM_TAXI_100, "TAXI-100" }, \
+ { IFM_ATM_TAXI_140, "TAXI-140" }, \
+ { IFM_ATM_MM_155, "MM-155" }, \
+ { IFM_ATM_SM_155, "SM-155" }, \
+ { IFM_ATM_UTP_155, "UTP-155" }, \
+ { IFM_ATM_MM_622, "MM-622" }, \
+ { IFM_ATM_SM_622, "SM-622" }, \
+ { IFM_ATM_VIRTUAL, "VIRTUAL" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS { \
+ { IFM_ATM_SDH, "SDH" }, \
+ { IFM_ATM_NOSCRAMB, "Noscramb" }, \
+ { IFM_ATM_UNASSIGNED, "Unassigned" }, \
+ { 0, NULL }, \
+}
+
+
+#define IFM_SUBTYPE_SHARED_DESCRIPTIONS { \
+ { IFM_AUTO, "autoselect" }, \
+ { IFM_MANUAL, "manual" }, \
+ { IFM_NONE, "none" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SUBTYPE_SHARED_ALIASES { \
+ { IFM_AUTO, "auto" }, \
+ { 0, NULL }, \
+}
+
+#define IFM_SHARED_OPTION_DESCRIPTIONS { \
+ { IFM_FDX, "full-duplex" }, \
+ { IFM_HDX, "half-duplex" }, \
+ { IFM_FLAG0, "flag0" }, \
+ { IFM_FLAG1, "flag1" }, \
+ { IFM_FLAG2, "flag2" }, \
+ { IFM_LOOP, "hw-loopback" }, \
+ { 0, NULL }, \
+}
+
+#endif /* _NET_IF_MEDIA_H_ */
diff --git a/cpukit/libnetworking/net/if_ppp.c b/cpukit/libnetworking/net/if_ppp.c
new file mode 100644
index 0000000000..3c69511acb
--- /dev/null
+++ b/cpukit/libnetworking/net/if_ppp.c
@@ -0,0 +1,1771 @@
+/*
+ * if_ppp.c - Point-to-Point Protocol (PPP) Asynchronous driver.
+ */
+
+/*-
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ *
+ * Drew D. Perkins
+ * Carnegie Mellon University
+ * 4910 Forbes Ave.
+ * Pittsburgh, PA 15213
+ * (412) 268-8576
+ * ddp@andrew.cmu.edu
+ *
+ * Based on:
+ * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89
+ *
+ * Copyright (c) 1987 Regents of the University of California.
+ * 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 University of California, Berkeley. 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.
+ *
+ * Serial Line interface
+ *
+ * Rick Adams
+ * Center for Seismic Studies
+ * 1300 N 17th Street, Suite 1450
+ * Arlington, Virginia 22209
+ * (703)276-7900
+ * rick@seismo.ARPA
+ * seismo!rick
+ *
+ * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris).
+ * Converted to 4.3BSD Beta by Chris Torek.
+ * Other changes made at Berkeley, based in part on code by Kirk Smith.
+ *
+ * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com)
+ * Added VJ tcp header compression; more unified ioctls
+ *
+ * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au).
+ * Cleaned up a lot of the mbuf-related code to fix bugs that
+ * caused system crashes and packet corruption. Changed pppstart
+ * so that it doesn't just give up with a collision if the whole
+ * packet doesn't fit in the output ring buffer.
+ *
+ * Added priority queueing for interactive IP packets, following
+ * the model of if_sl.c, plus hooks for bpf.
+ * Paul Mackerras (paulus@cs.anu.edu.au).
+ */
+
+/* $FreeBSD: src/sys/net/if_ppp.c,v 1.109 2005/10/12 19:52:16 thompsa Exp $ */
+/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
+/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
+
+/* $Id$ */
+
+#include "opt_inet.h"
+#include "opt_ipx.h"
+#include "opt_mac.h"
+#include "opt_ppp.h"
+
+#if NPPP > 0
+
+#include <termios.h>
+#include <rtems/termiostypes.h>
+#include <rtems/rtems_bsdnet.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/kernel.h>
+#include <sys/time.h>
+#include <sys/malloc.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/netisr.h>
+#include <net/route.h>
+#ifdef PPP_FILTER
+#include <net/bpf.h>
+#endif
+
+#if INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#endif
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#ifdef VJC
+#include <net/pppcompress.h>
+#endif
+
+#include <net/ppp_defs.h>
+#include <net/if_ppp.h>
+#include <net/if_pppvar.h>
+#include <machine/cpu.h>
+
+#define splsoftnet splnet
+
+#ifdef PPP_COMPRESS
+#define PACKETPTR struct mbuf *
+#include <net/ppp-comp.h>
+#endif
+
+static int pppsioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
+static void ppp_requeue(struct ppp_softc *);
+#ifdef PPP_COMPRESS
+static void ppp_ccp(struct ppp_softc *, struct mbuf *m, int rcvd);
+static void ppp_ccp_closed(struct ppp_softc *);
+#endif
+static struct mbuf *ppp_inproc(struct ppp_softc *, struct mbuf *);
+static void pppdumpm(struct mbuf *m0);
+
+/*
+ * Some useful mbuf macros not in mbuf.h.
+ */
+#define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
+
+#define M_DATASTART(m) \
+ (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \
+ (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
+
+#define M_DATASIZE(m) \
+ (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \
+ (m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
+
+/*
+ * We steal two bits in the mbuf m_flags, to mark high-priority packets
+ * for output, and received packets following lost/corrupted packets.
+ */
+#define M_HIGHPRI 0x2000 /* output packet for sc_fastq */
+#define M_ERRMARK 0x4000 /* steal a bit in mbuf m_flags */
+
+
+#ifdef PPP_COMPRESS
+/*
+ * List of compressors we know about.
+ * We leave some space so maybe we can modload compressors.
+ */
+
+extern struct compressor ppp_bsd_compress;
+extern struct compressor ppp_deflate, ppp_deflate_draft;
+
+struct compressor *ppp_compressors[8] = {
+#if DO_BSD_COMPRESS
+ &ppp_bsd_compress,
+#endif
+#if DO_DEFLATE
+ &ppp_deflate,
+ &ppp_deflate_draft,
+#endif
+ NULL
+};
+#endif /* PPP_COMPRESS */
+
+extern struct ifqueue ipintrq;
+static struct timeval ppp_time;
+
+#ifndef __rtems__
+TEXT_SET(pseudo_set, ppp_rxdaemon);
+#endif
+
+static rtems_task ppp_rxdaemon(rtems_task_argument arg)
+{
+ rtems_event_set events;
+ rtems_interrupt_level level;
+ struct ppp_softc *sc = (struct ppp_softc *)arg;
+ struct mbuf *mp = (struct mbuf *)0;
+ struct mbuf *m;
+
+ /* enter processing loop */
+ while ( 1 ) {
+ /* wait for event */
+ rtems_event_receive(RX_PACKET|RX_MBUF|RX_EMPTY,RTEMS_WAIT|RTEMS_EVENT_ANY,RTEMS_NO_TIMEOUT,&events);
+ if ( events & RX_EMPTY ) {
+ printf("RX: QUEUE is EMPTY\n");
+ events &= ~RX_EMPTY;
+ }
+
+ if ( events ) {
+ /* get the network semaphore */
+ rtems_bsdnet_semaphore_obtain();
+
+ /* check to see if new packet was received */
+ if ( events & RX_PACKET ) {
+ /* get received packet mbuf chain */
+ rtems_interrupt_disable(level);
+ IF_DEQUEUE(&sc->sc_rawq, m);
+ rtems_interrupt_enable(level);
+
+ /* ensure packet was retrieved */
+ if ( m != (struct mbuf *)0 ) {
+ /* process the received packet */
+ mp = ppp_inproc(sc, m);
+ }
+ }
+
+ /* allocate a new mbuf to replace one */
+ if ( mp == NULL ) {
+ pppallocmbuf(sc, &mp);
+ }
+
+ /* place mbuf on freeq */
+ rtems_interrupt_disable(level);
+ IF_ENQUEUE(&sc->sc_freeq, mp);
+ rtems_interrupt_enable(level);
+ mp = (struct mbuf *)0;
+
+ /* release the network semaphore */
+ rtems_bsdnet_semaphore_release();
+
+ /* check to see if queue is empty */
+ if ( sc->sc_rawq.ifq_head ) {
+ /* queue is not empty - post another event */
+ rtems_event_send(sc->sc_rxtask, RX_PACKET);
+ }
+ }
+ }
+}
+
+static rtems_task ppp_txdaemon(rtems_task_argument arg)
+{
+ rtems_event_set events;
+ int iprocess = (int )0;
+ struct ppp_softc *sc = (struct ppp_softc *)arg;
+ struct mbuf *mp;
+ struct mbuf *mf;
+ struct mbuf *m;
+ struct rtems_termios_tty *tp;
+
+ int frag;
+
+ /* enter processing loop */
+ while ( 1 ) {
+ /* wait for event */
+ rtems_event_receive(TX_PACKET|TX_TRANSMIT,RTEMS_WAIT|RTEMS_EVENT_ANY,RTEMS_NO_TIMEOUT,&events);
+ if ( events & TX_TRANSMIT ) {
+ /* received event from interrupt handler - free current mbuf */
+ rtems_bsdnet_semaphore_obtain();
+
+ m_freem(sc->sc_outm);
+
+ rtems_bsdnet_semaphore_release();
+
+ /* chain is done - clear the values */
+ sc->sc_outm = (struct mbuf *)0;
+ sc->sc_outmc = (struct mbuf *)0;
+
+ /* now set flag to fake receive of TX_PACKET event */
+ /* this will check to see if we have any pending packets */
+ events |= TX_PACKET;
+ }
+
+ /* received event from pppasyncstart */
+ if ( events & TX_PACKET ) {
+ /* ensure we are not busy */
+ if ( sc->sc_outm == (struct mbuf *)0 ) {
+ /* try dequeuing a packet */
+ sc->sc_outm = ppp_dequeue(sc);
+ if ( sc->sc_outm == NULL ) {
+ /* clear output flags */
+ sc->sc_outflag = 0;
+ sc->sc_if.if_flags &= ~IFF_OACTIVE;
+ }
+ else {
+ /* set flag to start process */
+ iprocess = 1;
+ sc->sc_outflag = SC_TX_BUSY;
+ sc->sc_if.if_flags |= IFF_OACTIVE;
+ }
+ }
+ }
+
+ /* check to see if there is any processing required */
+ if ( iprocess ) {
+ /* clear process flag */
+ iprocess = (int)0;
+ frag=0;
+
+ /* initialize output values */
+ sc->sc_outfcs = PPP_INITFCS;
+ sc->sc_outbuf = (u_char *)0;
+ sc->sc_outlen = (short )0;
+ sc->sc_outoff = (short )0;
+ sc->sc_outfcslen = (short )0;
+
+/* printf("Start Transmit Packet..\n"); */
+
+ /* loop over all mbufs in chain */
+ mf = NULL;
+ mp = NULL;
+ m = sc->sc_outm;
+
+ sc->sc_outmc = m;
+ sc->sc_outlen = m->m_len;
+ sc->sc_outbuf = mtod(m, u_char *);
+
+ while (( m != (struct mbuf *)0 ) && ( m->m_len > 0 )) {
+ frag++;
+
+ /* update the FCS value and then check next packet length */
+ if(m->m_len){
+ sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
+ }
+
+ if(( m->m_next != NULL ) && ( m->m_next->m_len == 0 )) {
+ if(mf){
+ printf(" if_ppp.c : MBUF Error !!!!\n");
+ }
+ else{
+ mf = m->m_next;
+ m->m_next = NULL;
+ }
+ }
+
+#ifdef LALL_X
+ /* check next packet to see if it is empty */
+ while (( m->m_next != NULL ) && ( m->m_next->m_len == 0 )) {
+ /* next mbuf is zero length */
+ /* add empty mbuf to free chain */
+ if ( mp == NULL ) {
+ /* item is head of free list */
+ mf = m->m_next;
+ mp = mf;
+ }
+ else {
+ /* add item to end of the free list */
+ mp->m_next = m->m_next;
+ mp = m->m_next;
+ }
+
+ /* remove empty item from process chain */
+ m->m_next = m->m_next->m_next;
+ mp->m_next = NULL;
+ }
+#endif
+ /* move to next packet */
+ m = m->m_next;
+ }
+
+ /* ensure there is data to be sent out */
+ tp = (struct rtems_termios_tty *)sc->sc_devp;
+ if (( tp != NULL ) && ( sc->sc_outmc != (struct mbuf *)0 )) {
+ /* place FCS value into buffer */
+ sc->sc_outfcsbuf[sc->sc_outfcslen++] = ~sc->sc_outfcs & 0xff;
+ sc->sc_outfcsbuf[sc->sc_outfcslen++] = (~sc->sc_outfcs >> 8) & 0xff;
+ microtime(&sc->sc_if.if_lastchange);
+
+ /* write out frame byte to start the transmission */
+ sc->sc_outchar = (u_char)PPP_FLAG;
+ (*tp->device.write)(tp->minor, (char *)&sc->sc_outchar, 1);
+ }
+
+ /* check to see if we need to free some empty mbufs */
+ if ( mf != (struct mbuf *)0 ) {
+ /* free empty mbufs */
+ rtems_bsdnet_semaphore_obtain();
+ m_freem(mf);
+ rtems_bsdnet_semaphore_release();
+ }
+ }
+ }
+}
+
+static void ppp_init(struct ppp_softc *sc)
+{
+ rtems_status_code status;
+ uint32_t priority = 100;
+
+ /* determine priority value */
+ if ( rtems_bsdnet_config.network_task_priority ) {
+ priority = rtems_bsdnet_config.network_task_priority;
+ }
+
+ /* check to see if we need to start up daemons */
+ if ( sc->sc_rxtask == 0 ) {
+ /* start rx daemon task */
+ status = rtems_task_create(rtems_build_name('R','x','P','0'+sc->sc_if.if_unit), priority, 2048,
+ RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
+ &sc->sc_rxtask);
+ if (status != RTEMS_SUCCESSFUL) {
+ rtems_fatal_error_occurred(status);
+ }
+ else {
+ status = rtems_task_start(sc->sc_rxtask, ppp_rxdaemon, (rtems_task_argument)sc);
+ if (status != RTEMS_SUCCESSFUL) {
+ rtems_fatal_error_occurred(status);
+ }
+ }
+
+ /* start tx daemon task */
+ status = rtems_task_create(rtems_build_name('T','x','P','0'+sc->sc_if.if_unit), priority, 2048,
+ RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
+ &sc->sc_txtask);
+ if (status != RTEMS_SUCCESSFUL) {
+ rtems_fatal_error_occurred(status);
+ }
+ else {
+ status = rtems_task_start(sc->sc_txtask, ppp_txdaemon, (rtems_task_argument)sc);
+ if (status != RTEMS_SUCCESSFUL) {
+ rtems_fatal_error_occurred(status);
+ }
+ }
+ }
+
+ /* mark driver running and output inactive */
+ /* ilya: IFF_RUNNING flag will be marked after the IPCP goes up */
+/* sc->sc_if.if_flags |= IFF_RUNNING; */
+}
+
+/*
+ * Called from boot code to establish ppp interfaces.
+ */
+int rtems_ppp_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching)
+{
+/* int i = (int)0; */
+ struct ppp_softc *sc;
+ char *name;
+ int number;
+
+
+ number = rtems_bsdnet_parse_driver_name (config, &name);
+
+ if (!attaching || (number >= NPPP))
+ return 0;
+
+ sc = &ppp_softc[number];
+
+ if (sc->sc_if.if_name != NULL)
+ return 0; /* interface is already attached */
+
+/* for (sc = ppp_softc; i < NPPP; sc++) { */
+ sc->sc_if.if_name = name /*"ppp"*/;
+ sc->sc_if.if_unit = number /*i++*/;
+ sc->sc_if.if_mtu = PPP_MTU;
+ sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
+ sc->sc_if.if_type = IFT_PPP;
+ sc->sc_if.if_hdrlen = PPP_HDRLEN;
+ sc->sc_if.if_ioctl = pppsioctl;
+ sc->sc_if.if_output = pppoutput;
+ sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
+ sc->sc_inq.ifq_maxlen = IFQ_MAXLEN;
+ sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN;
+ sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN;
+ sc->sc_freeq.ifq_maxlen = NUM_MBUFQ;
+
+ /* initialize and attach */
+ ppp_init(sc);
+ if_attach(&sc->sc_if);
+#if NBPFILTER > 0
+ bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN);
+#endif
+/* } */
+
+ return ( 1 );
+}
+
+/*
+ * Allocate a ppp interface unit and initialize it.
+ */
+struct ppp_softc *
+pppalloc(pid)
+ pid_t pid;
+{
+ int nppp, i;
+ struct ppp_softc *sc;
+
+ for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++)
+ if (sc->sc_xfer == pid) {
+ sc->sc_xfer = 0;
+ return sc;
+ }
+ for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++)
+ if (sc->sc_devp == NULL)
+ break;
+ if (nppp >= NPPP)
+ return NULL;
+
+ sc->sc_flags = 0;
+ sc->sc_mru = PPP_MRU;
+ sc->sc_relinq = NULL;
+ bzero((char *)&sc->sc_stats, sizeof(sc->sc_stats));
+#ifdef VJC
+ MALLOC(sc->sc_comp, struct vjcompress *, sizeof(struct vjcompress),
+ M_DEVBUF, M_NOWAIT);
+ if (sc->sc_comp)
+ vj_compress_init(sc->sc_comp, -1);
+#endif
+#ifdef PPP_COMPRESS
+ sc->sc_xc_state = NULL;
+ sc->sc_rc_state = NULL;
+#endif /* PPP_COMPRESS */
+ for (i = 0; i < NUM_NP; ++i)
+ sc->sc_npmode[i] = NPMODE_ERROR;
+ sc->sc_npqueue = NULL;
+ sc->sc_npqtail = &sc->sc_npqueue;
+ microtime(&ppp_time);
+ sc->sc_last_sent = sc->sc_last_recv = ppp_time.tv_sec;
+
+ return sc;
+}
+
+/*
+ * Deallocate a ppp unit. Must be called at splsoftnet or higher.
+ */
+void
+pppdealloc(sc)
+ struct ppp_softc *sc;
+{
+ struct mbuf *m;
+ rtems_interrupt_level level;
+
+ if_down(&sc->sc_if);
+ sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
+ sc->sc_devp = NULL;
+ sc->sc_xfer = 0;
+
+ rtems_interrupt_disable(level);
+ if ( sc->sc_m != NULL ) {
+ m_freem(sc->sc_m);
+ sc->sc_m = (struct mbuf *)0;
+ }
+ if ( sc->sc_outm != NULL ) {
+ m_freem(sc->sc_outm);
+ sc->sc_outm = (struct mbuf *)0;
+ sc->sc_outmc = (struct mbuf *)0;
+ sc->sc_outflag = 0;
+ }
+ do {
+ IF_DEQUEUE(&sc->sc_freeq, m);
+ if (m != NULL) {
+ m_freem(m);
+ }
+ } while ( m != NULL );
+ do {
+ IF_DEQUEUE(&sc->sc_rawq, m);
+ if (m != NULL) {
+ m_freem(m);
+ }
+ } while ( m != NULL );
+ rtems_interrupt_enable(level);
+
+ for (;;) {
+ IF_DEQUEUE(&sc->sc_inq, m);
+ if (m == NULL)
+ break;
+ m_freem(m);
+ }
+ for (;;) {
+ IF_DEQUEUE(&sc->sc_fastq, m);
+ if (m == NULL)
+ break;
+ m_freem(m);
+ }
+ while ((m = sc->sc_npqueue) != NULL) {
+ sc->sc_npqueue = m->m_nextpkt;
+ m_freem(m);
+ }
+#ifdef PPP_COMPRESS
+ ppp_ccp_closed(sc);
+ sc->sc_xc_state = NULL;
+ sc->sc_rc_state = NULL;
+#endif /* PPP_COMPRESS */
+#ifdef PPP_FILTER
+ if (sc->sc_pass_filt.bf_insns != 0) {
+ FREE(sc->sc_pass_filt.bf_insns, M_DEVBUF);
+ sc->sc_pass_filt.bf_insns = 0;
+ sc->sc_pass_filt.bf_len = 0;
+ }
+ if (sc->sc_active_filt.bf_insns != 0) {
+ FREE(sc->sc_active_filt.bf_insns, M_DEVBUF);
+ sc->sc_active_filt.bf_insns = 0;
+ sc->sc_active_filt.bf_len = 0;
+ }
+#endif /* PPP_FILTER */
+#ifdef VJC
+ if (sc->sc_comp != 0) {
+ FREE(sc->sc_comp, M_DEVBUF);
+ sc->sc_comp = 0;
+ }
+#endif
+}
+
+/*
+ * Ioctl routine for generic ppp devices.
+ */
+int
+pppioctl(sc, cmd, data, flag, p)
+ struct ppp_softc *sc;
+ int cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ int s, flags, mru, npx, taskid;
+ struct npioctl *npi;
+ time_t t;
+#ifdef PPP_FILTER
+ int error;
+ struct bpf_program *bp, *nbp;
+ struct bpf_insn *newcode, *oldcode;
+ int newcodelen;
+#endif /* PPP_FILTER */
+#ifdef PPP_COMPRESS
+ int nb;
+ struct ppp_option_data *odp;
+ struct compressor **cp;
+ u_char ccp_option[CCP_MAX_OPTION_LENGTH];
+#endif
+
+ switch (cmd) {
+ case FIONREAD:
+ *(int *)data = sc->sc_inq.ifq_len;
+ break;
+
+ case PPPIOCSTASK:
+ taskid = *(int *)data;
+ sc->sc_pppdtask = taskid;
+ break;
+
+ case PPPIOCGUNIT:
+ *(int *)data = sc->sc_if.if_unit;
+ break;
+
+ case PPPIOCGFLAGS:
+ *(u_int *)data = sc->sc_flags;
+ break;
+
+ case PPPIOCSFLAGS:
+ flags = *(int *)data & SC_MASK;
+ s = splsoftnet();
+#ifdef PPP_COMPRESS
+ if (sc->sc_flags & SC_CCP_OPEN && !(flags & SC_CCP_OPEN))
+ ppp_ccp_closed(sc);
+#endif
+ s = splimp();
+ sc->sc_flags = (sc->sc_flags & ~SC_MASK) | flags;
+ splx(s);
+ break;
+
+ case PPPIOCSMRU:
+ mru = *(int *)data;
+ if ( mru >= MCLBYTES ) {
+ /* error - currently only handle 1 culster sized MRU */
+ /* if we want to handle up to PPP_MAXMRU then we */
+ /* need to reallocate all mbufs on the freeq */
+ /* this can only be done with iterrupts disabled */
+ return ( -1 );
+ }
+ else if ( mru >= PPP_MRU ) {
+ /* update the size */
+ sc->sc_mru = mru;
+ }
+ break;
+
+ case PPPIOCGMRU:
+ *(int *)data = sc->sc_mru;
+ break;
+
+#ifdef VJC
+ case PPPIOCSMAXCID:
+ if (sc->sc_comp) {
+ s = splsoftnet();
+ vj_compress_init(sc->sc_comp, *(int *)data);
+ splx(s);
+ }
+ break;
+#endif
+
+ case PPPIOCXFERUNIT:
+ sc->sc_xfer = 0; /* Always root p->p_pid;*/
+ break;
+
+#ifdef PPP_COMPRESS
+ case PPPIOCSCOMPRESS:
+ odp = (struct ppp_option_data *) data;
+ nb = odp->length;
+ if (nb > sizeof(ccp_option))
+ nb = sizeof(ccp_option);
+ if ((error = copyin(odp->ptr, ccp_option, nb)) != 0)
+ return (error);
+ if (ccp_option[1] < 2) /* preliminary check on the length byte */
+ return (EINVAL);
+ for (cp = ppp_compressors; *cp != NULL; ++cp)
+ if ((*cp)->compress_proto == ccp_option[0]) {
+ /*
+ * Found a handler for the protocol - try to allocate
+ * a compressor or decompressor.
+ */
+ error = 0;
+ if (odp->transmit) {
+ s = splsoftnet();
+ if (sc->sc_xc_state != NULL)
+ (*sc->sc_xcomp->comp_free)(sc->sc_xc_state);
+ sc->sc_xcomp = *cp;
+ sc->sc_xc_state = (*cp)->comp_alloc(ccp_option, nb);
+ if (sc->sc_xc_state == NULL) {
+ if (sc->sc_flags & SC_DEBUG)
+ printf("ppp%d: comp_alloc failed\n",
+ sc->sc_if.if_unit);
+ error = ENOBUFS;
+ }
+ splimp();
+ sc->sc_flags &= ~SC_COMP_RUN;
+ splx(s);
+ } else {
+ s = splsoftnet();
+ if (sc->sc_rc_state != NULL)
+ (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state);
+ sc->sc_rcomp = *cp;
+ sc->sc_rc_state = (*cp)->decomp_alloc(ccp_option, nb);
+ if (sc->sc_rc_state == NULL) {
+ if (sc->sc_flags & SC_DEBUG)
+ printf("ppp%d: decomp_alloc failed\n",
+ sc->sc_if.if_unit);
+ error = ENOBUFS;
+ }
+ splimp();
+ sc->sc_flags &= ~SC_DECOMP_RUN;
+ splx(s);
+ }
+ return (error);
+ }
+ if (sc->sc_flags & SC_DEBUG)
+ printf("ppp%d: no compressor for [%x %x %x], %x\n",
+ sc->sc_if.if_unit, ccp_option[0], ccp_option[1],
+ ccp_option[2], nb);
+ return (EINVAL); /* no handler found */
+#endif /* PPP_COMPRESS */
+
+ case PPPIOCGNPMODE:
+ case PPPIOCSNPMODE:
+ npi = (struct npioctl *) data;
+ switch (npi->protocol) {
+ case PPP_IP:
+ npx = NP_IP;
+ break;
+ default:
+ return EINVAL;
+ }
+ if (cmd == PPPIOCGNPMODE) {
+ npi->mode = sc->sc_npmode[npx];
+ } else {
+ if (npi->mode != sc->sc_npmode[npx]) {
+ s = splsoftnet();
+ sc->sc_npmode[npx] = npi->mode;
+ if (npi->mode != NPMODE_QUEUE) {
+ ppp_requeue(sc);
+ (*sc->sc_start)(sc);
+ }
+ splx(s);
+ }
+ }
+ break;
+
+ case PPPIOCGIDLE:
+ s = splsoftnet();
+ microtime(&ppp_time);
+ t = ppp_time.tv_sec;
+ ((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent;
+ ((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv;
+ splx(s);
+ break;
+
+#ifdef PPP_FILTER
+ case PPPIOCSPASS:
+ case PPPIOCSACTIVE:
+ nbp = (struct bpf_program *) data;
+ if ((unsigned) nbp->bf_len > BPF_MAXINSNS)
+ return EINVAL;
+ newcodelen = nbp->bf_len * sizeof(struct bpf_insn);
+ if (newcodelen != 0) {
+ MALLOC(newcode, struct bpf_insn *, newcodelen, M_DEVBUF, M_WAITOK);
+ if (newcode == 0) {
+ return EINVAL; /* or sumpin */
+ }
+ if ((error = copyin((caddr_t)nbp->bf_insns, (caddr_t)newcode,
+ newcodelen)) != 0) {
+ FREE(newcode, M_DEVBUF);
+ return error;
+ }
+ if (!bpf_validate(newcode, nbp->bf_len)) {
+ FREE(newcode, M_DEVBUF);
+ return EINVAL;
+ }
+ } else
+ newcode = 0;
+ bp = (cmd == PPPIOCSPASS)? &sc->sc_pass_filt: &sc->sc_active_filt;
+ oldcode = bp->bf_insns;
+ s = splimp();
+ bp->bf_len = nbp->bf_len;
+ bp->bf_insns = newcode;
+ splx(s);
+ if (oldcode != 0)
+ FREE(oldcode, M_DEVBUF);
+ break;
+#endif
+
+ default:
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * Process an ioctl request to the ppp network interface.
+ */
+static int
+pppsioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ /*struct proc *p = curproc;*/ /* XXX */
+ register struct ppp_softc *sc = &ppp_softc[ifp->if_unit];
+ register struct ifaddr *ifa = (struct ifaddr *)data;
+ register struct ifreq *ifr = (struct ifreq *)data;
+ struct ppp_stats *psp;
+#ifdef PPP_COMPRESS
+ struct ppp_comp_stats *pcp;
+#endif
+ int s = splimp(), error = 0;
+
+ switch (cmd) {
+ case SIOCSIFFLAGS:
+ if ((ifp->if_flags & IFF_RUNNING) == 0)
+ ifp->if_flags &= ~IFF_UP;
+ break;
+
+ case SIOCSIFADDR:
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ error = EAFNOSUPPORT;
+ break;
+
+ case SIOCSIFDSTADDR:
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ error = EAFNOSUPPORT;
+ break;
+
+ case SIOCSIFMTU:
+ sc->sc_if.if_mtu = ifr->ifr_mtu;
+ break;
+
+ case SIOCGIFMTU:
+ ifr->ifr_mtu = sc->sc_if.if_mtu;
+ break;
+
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ if (ifr == 0) {
+ error = EAFNOSUPPORT;
+ break;
+ }
+ switch(ifr->ifr_addr.sa_family) {
+#ifdef INET
+ case AF_INET:
+ break;
+#endif
+ default:
+ error = EAFNOSUPPORT;
+ break;
+ }
+ break;
+
+ case SIO_RTEMS_SHOW_STATS:
+ printf(" MRU:%-8u", sc->sc_mru);
+ printf(" Bytes received:%-8u", sc->sc_stats.ppp_ibytes);
+ printf(" Packets received:%-8u", sc->sc_stats.ppp_ipackets);
+ printf(" Receive errors:%-8u\n", sc->sc_stats.ppp_ierrors);
+ printf(" Bytes sent:%-8u", sc->sc_stats.ppp_obytes);
+ printf(" Packets sent:%-8u", sc->sc_stats.ppp_opackets);
+ printf(" Transmit errors:%-8u\n", sc->sc_stats.ppp_oerrors);
+ break;
+
+ case SIOCGPPPSTATS:
+ psp = &((struct ifpppstatsreq *) data)->stats;
+ bzero(psp, sizeof(*psp));
+ psp->p = sc->sc_stats;
+#if defined(VJC) && !defined(SL_NO_STATS)
+ if (sc->sc_comp) {
+ psp->vj.vjs_packets = sc->sc_comp->sls_packets;
+ psp->vj.vjs_compressed = sc->sc_comp->sls_compressed;
+ psp->vj.vjs_searches = sc->sc_comp->sls_searches;
+ psp->vj.vjs_misses = sc->sc_comp->sls_misses;
+ psp->vj.vjs_uncompressedin = sc->sc_comp->sls_uncompressedin;
+ psp->vj.vjs_compressedin = sc->sc_comp->sls_compressedin;
+ psp->vj.vjs_errorin = sc->sc_comp->sls_errorin;
+ psp->vj.vjs_tossed = sc->sc_comp->sls_tossed;
+ }
+#endif /* VJC */
+ break;
+
+#ifdef PPP_COMPRESS
+ case SIOCGPPPCSTATS:
+ pcp = &((struct ifpppcstatsreq *) data)->stats;
+ bzero(pcp, sizeof(*pcp));
+ if (sc->sc_xc_state != NULL)
+ (*sc->sc_xcomp->comp_stat)(sc->sc_xc_state, &pcp->c);
+ if (sc->sc_rc_state != NULL)
+ (*sc->sc_rcomp->decomp_stat)(sc->sc_rc_state, &pcp->d);
+ break;
+#endif /* PPP_COMPRESS */
+
+ default:
+ error = EINVAL;
+ }
+ splx(s);
+ return (error);
+}
+
+/*
+ * Queue a packet. Start transmission if not active.
+ * Packet is placed in Information field of PPP frame.
+ */
+int
+pppoutput(ifp, m0, dst, rtp)
+ struct ifnet *ifp;
+ struct mbuf *m0;
+ struct sockaddr *dst;
+ struct rtentry *rtp;
+{
+ register struct ppp_softc *sc = &ppp_softc[ifp->if_unit];
+ int protocol, address, control;
+ u_char *cp;
+ int s, error;
+ struct ip *ip;
+ struct ifqueue *ifq;
+ enum NPmode mode;
+ int len;
+ struct mbuf *m;
+
+ if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0
+ || ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) {
+ error = ENETDOWN; /* sort of */
+ goto bad;
+ }
+
+ /*
+ * Compute PPP header.
+ */
+ m0->m_flags &= ~M_HIGHPRI;
+ switch (dst->sa_family) {
+#ifdef INET
+ case AF_INET:
+ address = PPP_ALLSTATIONS;
+ control = PPP_UI;
+ protocol = PPP_IP;
+ mode = sc->sc_npmode[NP_IP];
+
+ /*
+ * If this packet has the "low delay" bit set in the IP header,
+ * put it on the fastq instead.
+ */
+ ip = mtod(m0, struct ip *);
+ if (ip->ip_tos & IPTOS_LOWDELAY)
+ m0->m_flags |= M_HIGHPRI;
+ break;
+#endif
+ case AF_UNSPEC:
+ address = PPP_ADDRESS(dst->sa_data);
+ control = PPP_CONTROL(dst->sa_data);
+ protocol = PPP_PROTOCOL(dst->sa_data);
+ mode = NPMODE_PASS;
+ break;
+ default:
+ printf("ppp%d: af%d not supported\n", ifp->if_unit, dst->sa_family);
+ error = EAFNOSUPPORT;
+ goto bad;
+ }
+
+ /*
+ * Drop this packet, or return an error, if necessary.
+ */
+ if (mode == NPMODE_ERROR) {
+ error = ENETDOWN;
+ goto bad;
+ }
+ if (mode == NPMODE_DROP) {
+ error = 0;
+ goto bad;
+ }
+
+ /*
+ * Add PPP header. If no space in first mbuf, allocate another.
+ * (This assumes M_LEADINGSPACE is always 0 for a cluster mbuf.)
+ */
+ if (M_LEADINGSPACE(m0) < PPP_HDRLEN) {
+ m0 = m_prepend(m0, PPP_HDRLEN, M_DONTWAIT);
+ if (m0 == 0) {
+ error = ENOBUFS;
+ goto bad;
+ }
+ m0->m_len = 0;
+ } else
+ m0->m_data -= PPP_HDRLEN;
+
+ cp = mtod(m0, u_char *);
+ *cp++ = address;
+ *cp++ = control;
+ *cp++ = protocol >> 8;
+ *cp++ = protocol & 0xff;
+ m0->m_len += PPP_HDRLEN;
+
+ len = 0;
+ for (m = m0; m != 0; m = m->m_next)
+ len += m->m_len;
+
+ if (sc->sc_flags & SC_LOG_OUTPKT) {
+ printf("ppp%d output: ", ifp->if_unit);
+ pppdumpm(m0);
+ }
+
+ if ((protocol & 0x8000) == 0) {
+#ifdef PPP_FILTER
+ /*
+ * Apply the pass and active filters to the packet,
+ * but only if it is a data packet.
+ */
+ *mtod(m0, u_char *) = 1; /* indicates outbound */
+ if (sc->sc_pass_filt.bf_insns != 0
+ && bpf_filter(sc->sc_pass_filt.bf_insns, (u_char *) m0,
+ len, 0) == 0) {
+ error = 0; /* drop this packet */
+ goto bad;
+ }
+
+ /*
+ * Update the time we sent the most recent packet.
+ */
+ if (sc->sc_active_filt.bf_insns == 0
+ || bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m0, len, 0))
+ sc->sc_last_sent = time.tv_sec;
+
+ *mtod(m0, u_char *) = address;
+#else
+ /*
+ * Update the time we sent the most recent data packet.
+ */
+ microtime(&ppp_time);
+ sc->sc_last_sent = ppp_time.tv_sec;
+#endif /* PPP_FILTER */
+ }
+
+#if NBPFILTER > 0
+ /*
+ * See if bpf wants to look at the packet.
+ */
+ if (sc->sc_bpf)
+ bpf_mtap(sc->sc_bpf, m0);
+#endif
+
+ /*
+ * Put the packet on the appropriate queue.
+ */
+ s = splsoftnet();
+ if (mode == NPMODE_QUEUE) {
+ /* XXX we should limit the number of packets on this queue */
+ *sc->sc_npqtail = m0;
+ m0->m_nextpkt = NULL;
+ sc->sc_npqtail = &m0->m_nextpkt;
+ } else {
+ ifq = (m0->m_flags & M_HIGHPRI)? &sc->sc_fastq: &ifp->if_snd;
+ if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) {
+ IF_DROP(ifq);
+ splx(s);
+ sc->sc_if.if_oerrors++;
+ sc->sc_stats.ppp_oerrors++;
+ error = ENOBUFS;
+ goto bad;
+ }
+ IF_ENQUEUE(ifq, m0);
+ (*sc->sc_start)(sc);
+ }
+ ifp->if_lastchange = ppp_time;
+ ifp->if_opackets++;
+ ifp->if_obytes += len;
+
+ splx(s);
+ return (0);
+
+bad:
+ m_freem(m0);
+ return (error);
+}
+
+/*
+ * After a change in the NPmode for some NP, move packets from the
+ * npqueue to the send queue or the fast queue as appropriate.
+ * Should be called at spl[soft]net.
+ */
+static void
+ppp_requeue(sc)
+ struct ppp_softc *sc;
+{
+ struct mbuf *m, **mpp;
+ struct ifqueue *ifq;
+ enum NPmode mode;
+
+ for (mpp = &sc->sc_npqueue; (m = *mpp) != NULL; ) {
+ switch (PPP_PROTOCOL(mtod(m, u_char *))) {
+ case PPP_IP:
+ mode = sc->sc_npmode[NP_IP];
+ break;
+ default:
+ mode = NPMODE_PASS;
+ }
+
+ switch (mode) {
+ case NPMODE_PASS:
+ /*
+ * This packet can now go on one of the queues to be sent.
+ */
+ *mpp = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ ifq = (m->m_flags & M_HIGHPRI)? &sc->sc_fastq: &sc->sc_if.if_snd;
+ if (IF_QFULL(ifq)) {
+ IF_DROP(ifq);
+ sc->sc_if.if_oerrors++;
+ sc->sc_stats.ppp_oerrors++;
+ } else
+ IF_ENQUEUE(ifq, m);
+ break;
+
+ case NPMODE_DROP:
+ case NPMODE_ERROR:
+ *mpp = m->m_nextpkt;
+ m_freem(m);
+ break;
+
+ case NPMODE_QUEUE:
+ mpp = &m->m_nextpkt;
+ break;
+ }
+ }
+ sc->sc_npqtail = mpp;
+}
+
+/*
+ * Get a packet to send. This procedure is intended to be called at
+ * splsoftnet, since it may involve time-consuming operations such as
+ * applying VJ compression, packet compression, address/control and/or
+ * protocol field compression to the packet.
+ */
+struct mbuf *
+ppp_dequeue(sc)
+ struct ppp_softc *sc;
+{
+#ifdef PPP_COMPRESS
+ struct mbuf *mp;
+#endif
+ struct mbuf *m;
+ u_char *cp;
+ int address, control, protocol;
+
+ /*
+ * Grab a packet to send: first try the fast queue, then the
+ * normal queue.
+ */
+ rtems_bsdnet_semaphore_obtain();
+ IF_DEQUEUE(&sc->sc_fastq, m);
+ if (m == NULL)
+ IF_DEQUEUE(&sc->sc_if.if_snd, m);
+ rtems_bsdnet_semaphore_release();
+
+ if (m == NULL)
+ return NULL;
+
+ ++sc->sc_stats.ppp_opackets;
+
+ /*
+ * Extract the ppp header of the new packet.
+ * The ppp header will be in one mbuf.
+ */
+ cp = mtod(m, u_char *);
+ address = PPP_ADDRESS(cp);
+ control = PPP_CONTROL(cp);
+ protocol = PPP_PROTOCOL(cp);
+
+ switch (protocol) {
+ case PPP_IP:
+#ifdef VJC
+ /*
+ * If the packet is a TCP/IP packet, see if we can compress it.
+ */
+ if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) {
+ struct ip *ip;
+ int type;
+
+ mp = m;
+ ip = (struct ip *) (cp + PPP_HDRLEN);
+ if (mp->m_len <= PPP_HDRLEN) {
+ mp = mp->m_next;
+ if (mp == NULL)
+ break;
+ ip = mtod(mp, struct ip *);
+ }
+ /* this code assumes the IP/TCP header is in one non-shared mbuf */
+ if (ip->ip_p == IPPROTO_TCP) {
+ type = vj_compress_tcp(mp, ip, sc->sc_comp,
+ !(sc->sc_flags & SC_NO_TCP_CCID));
+ switch (type) {
+ case TYPE_UNCOMPRESSED_TCP:
+ protocol = PPP_VJC_UNCOMP;
+ break;
+ case TYPE_COMPRESSED_TCP:
+ protocol = PPP_VJC_COMP;
+ cp = mtod(m, u_char *);
+ cp[0] = address; /* header has moved */
+ cp[1] = control;
+ cp[2] = 0;
+ break;
+ }
+ cp[3] = protocol; /* update protocol in PPP header */
+ }
+ }
+#endif /* VJC */
+ break;
+
+#ifdef PPP_COMPRESS
+ case PPP_CCP:
+ ppp_ccp(sc, m, 0);
+ break;
+#endif /* PPP_COMPRESS */
+ }
+
+#ifdef PPP_COMPRESS
+ if (protocol != PPP_LCP && protocol != PPP_CCP
+ && sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) {
+ struct mbuf *mcomp = NULL;
+ int slen, clen;
+
+ slen = 0;
+ for (mp = m; mp != NULL; mp = mp->m_next)
+ slen += mp->m_len;
+ clen = (*sc->sc_xcomp->compress)
+ (sc->sc_xc_state, &mcomp, m, slen, sc->sc_if.if_mtu + PPP_HDRLEN);
+ if (mcomp != NULL) {
+ if (sc->sc_flags & SC_CCP_UP) {
+ /* Send the compressed packet instead of the original. */
+ m_freem(m);
+ m = mcomp;
+ cp = mtod(m, u_char *);
+ protocol = cp[3];
+ } else {
+ /* Can't transmit compressed packets until CCP is up. */
+ m_freem(mcomp);
+ }
+ }
+ }
+#endif /* PPP_COMPRESS */
+
+ /*
+ * Compress the address/control and protocol, if possible.
+ */
+ if (sc->sc_flags & SC_COMP_AC && address == PPP_ALLSTATIONS &&
+ control == PPP_UI && protocol != PPP_ALLSTATIONS &&
+ protocol != PPP_LCP) {
+ /* can compress address/control */
+ m->m_data += 2;
+ m->m_len -= 2;
+ }
+ if (sc->sc_flags & SC_COMP_PROT && protocol < 0xFF) {
+ /* can compress protocol */
+ if (mtod(m, u_char *) == cp) {
+ cp[2] = cp[1]; /* move address/control up */
+ cp[1] = cp[0];
+ }
+ ++m->m_data;
+ --m->m_len;
+ }
+
+ return m;
+}
+
+/*
+ * Software interrupt routine, called at splsoftnet.
+ */
+void
+pppintr(void)
+{
+}
+
+#ifdef PPP_COMPRESS
+/*
+ * Handle a CCP packet. `rcvd' is 1 if the packet was received,
+ * 0 if it is about to be transmitted.
+ */
+static void
+ppp_ccp(sc, m, rcvd)
+ struct ppp_softc *sc;
+ struct mbuf *m;
+ int rcvd;
+{
+ u_char *dp, *ep;
+ struct mbuf *mp;
+ int slen, s;
+
+ /*
+ * Get a pointer to the data after the PPP header.
+ */
+ if (m->m_len <= PPP_HDRLEN) {
+ mp = m->m_next;
+ if (mp == NULL)
+ return;
+ dp = (mp != NULL)? mtod(mp, u_char *): NULL;
+ } else {
+ mp = m;
+ dp = mtod(mp, u_char *) + PPP_HDRLEN;
+ }
+
+ ep = mtod(mp, u_char *) + mp->m_len;
+ if (dp + CCP_HDRLEN > ep)
+ return;
+ slen = CCP_LENGTH(dp);
+ if (dp + slen > ep) {
+ if (sc->sc_flags & SC_DEBUG)
+ printf("if_ppp/ccp: not enough data in mbuf (%p+%x > %p+%x)\n",
+ dp, slen, mtod(mp, u_char *), mp->m_len);
+ return;
+ }
+
+ switch (CCP_CODE(dp)) {
+ case CCP_CONFREQ:
+ case CCP_TERMREQ:
+ case CCP_TERMACK:
+ /* CCP must be going down - disable compression */
+ if (sc->sc_flags & SC_CCP_UP) {
+ s = splimp();
+ sc->sc_flags &= ~(SC_CCP_UP | SC_COMP_RUN | SC_DECOMP_RUN);
+ splx(s);
+ }
+ break;
+
+ case CCP_CONFACK:
+ if (sc->sc_flags & SC_CCP_OPEN && !(sc->sc_flags & SC_CCP_UP)
+ && slen >= CCP_HDRLEN + CCP_OPT_MINLEN
+ && slen >= CCP_OPT_LENGTH(dp + CCP_HDRLEN) + CCP_HDRLEN) {
+ if (!rcvd) {
+ /* we're agreeing to send compressed packets. */
+ if (sc->sc_xc_state != NULL
+ && (*sc->sc_xcomp->comp_init)
+ (sc->sc_xc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
+ sc->sc_if.if_unit, 0, sc->sc_flags & SC_DEBUG)) {
+ s = splimp();
+ sc->sc_flags |= SC_COMP_RUN;
+ splx(s);
+ }
+ } else {
+ /* peer is agreeing to send compressed packets. */
+ if (sc->sc_rc_state != NULL
+ && (*sc->sc_rcomp->decomp_init)
+ (sc->sc_rc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
+ sc->sc_if.if_unit, 0, sc->sc_mru,
+ sc->sc_flags & SC_DEBUG)) {
+ s = splimp();
+ sc->sc_flags |= SC_DECOMP_RUN;
+ sc->sc_flags &= ~(SC_DC_ERROR | SC_DC_FERROR);
+ splx(s);
+ }
+ }
+ }
+ break;
+
+ case CCP_RESETACK:
+ if (sc->sc_flags & SC_CCP_UP) {
+ if (!rcvd) {
+ if (sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN))
+ (*sc->sc_xcomp->comp_reset)(sc->sc_xc_state);
+ } else {
+ if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) {
+ (*sc->sc_rcomp->decomp_reset)(sc->sc_rc_state);
+ s = splimp();
+ sc->sc_flags &= ~SC_DC_ERROR;
+ splx(s);
+ }
+ }
+ }
+ break;
+ }
+}
+
+/*
+ * CCP is down; free (de)compressor state if necessary.
+ */
+static void
+ppp_ccp_closed(sc)
+ struct ppp_softc *sc;
+{
+ if (sc->sc_xc_state) {
+ (*sc->sc_xcomp->comp_free)(sc->sc_xc_state);
+ sc->sc_xc_state = NULL;
+ }
+ if (sc->sc_rc_state) {
+ (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state);
+ sc->sc_rc_state = NULL;
+ }
+}
+#endif /* PPP_COMPRESS */
+
+/*
+ * Process a received PPP packet, doing decompression as necessary.
+ * Should be called at splsoftnet.
+ */
+#define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \
+ TYPE_UNCOMPRESSED_TCP)
+
+static struct mbuf *
+ppp_inproc(sc, m)
+ struct ppp_softc *sc;
+ struct mbuf *m;
+{
+ struct mbuf *mf = (struct mbuf *)0;
+ struct ifnet *ifp = &sc->sc_if;
+ struct ifqueue *inq;
+ int s, ilen, proto, rv;
+ u_char *cp, adrs, ctrl;
+ struct mbuf *mp;
+#ifdef PPP_COMPRESS
+ struct mbuf *dmp = NULL;
+#endif
+#ifdef VJC
+ u_char *iphdr;
+ u_int hlen;
+ int xlen;
+#endif
+
+ sc->sc_stats.ppp_ipackets++;
+
+ if (sc->sc_flags & SC_LOG_INPKT) {
+ ilen = 0;
+ for (mp = m; mp != NULL; mp = mp->m_next)
+ ilen += mp->m_len;
+ printf("ppp%d: got %d bytes\n", ifp->if_unit, ilen);
+ pppdumpm(m);
+ }
+
+ cp = mtod(m, u_char *);
+ adrs = PPP_ADDRESS(cp);
+ ctrl = PPP_CONTROL(cp);
+ proto = PPP_PROTOCOL(cp);
+
+ if (m->m_flags & M_ERRMARK) {
+ m->m_flags &= ~M_ERRMARK;
+ s = splimp();
+ sc->sc_flags |= SC_VJ_RESET;
+ splx(s);
+ }
+
+#ifdef PPP_COMPRESS
+ /*
+ * Decompress this packet if necessary, update the receiver's
+ * dictionary, or take appropriate action on a CCP packet.
+ */
+ if (proto == PPP_COMP && sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)
+ && !(sc->sc_flags & SC_DC_ERROR) && !(sc->sc_flags & SC_DC_FERROR)) {
+ /* decompress this packet */
+ rv = (*sc->sc_rcomp->decompress)(sc->sc_rc_state, m, &dmp);
+ if (rv == DECOMP_OK) {
+ m_freem(m);
+ if (dmp == NULL) {
+ /* no error, but no decompressed packet produced */
+ return mf;
+ }
+ m = dmp;
+ cp = mtod(m, u_char *);
+ proto = PPP_PROTOCOL(cp);
+
+ } else {
+ /*
+ * An error has occurred in decompression.
+ * Pass the compressed packet up to pppd, which may take
+ * CCP down or issue a Reset-Req.
+ */
+ if (sc->sc_flags & SC_DEBUG)
+ printf("ppp%d: decompress failed %d\n", ifp->if_unit, rv);
+ s = splimp();
+ sc->sc_flags |= SC_VJ_RESET;
+ if (rv == DECOMP_ERROR)
+ sc->sc_flags |= SC_DC_ERROR;
+ else
+ sc->sc_flags |= SC_DC_FERROR;
+ splx(s);
+ }
+
+ } else {
+ if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) {
+ (*sc->sc_rcomp->incomp)(sc->sc_rc_state, m);
+ }
+ if (proto == PPP_CCP) {
+ ppp_ccp(sc, m, 1);
+ }
+ }
+#endif
+
+ ilen = 0;
+ for (mp = m; mp != NULL; mp = mp->m_next)
+ ilen += mp->m_len;
+
+#ifdef VJC
+ if (sc->sc_flags & SC_VJ_RESET) {
+ /*
+ * If we've missed a packet, we must toss subsequent compressed
+ * packets which don't have an explicit connection ID.
+ */
+ if (sc->sc_comp)
+ vj_uncompress_tcp(NULL, 0, TYPE_ERROR, sc->sc_comp);
+ s = splimp();
+ sc->sc_flags &= ~SC_VJ_RESET;
+ splx(s);
+ }
+
+ /*
+ * See if we have a VJ-compressed packet to uncompress.
+ */
+ if (proto == PPP_VJC_COMP) {
+ if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0)
+ goto bad;
+
+ xlen = vj_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN,
+ ilen - PPP_HDRLEN, TYPE_COMPRESSED_TCP,
+ sc->sc_comp, &iphdr, &hlen);
+
+ if (xlen <= 0) {
+ if (sc->sc_flags & SC_DEBUG)
+ printf("ppp%d: VJ uncompress failed on type comp\n",
+ ifp->if_unit);
+ goto bad;
+ }
+
+ /* Copy the PPP and IP headers into a new mbuf. */
+ MGETHDR(mp, M_DONTWAIT, MT_DATA);
+ if (mp == NULL)
+ goto bad;
+ mp->m_len = 0;
+ mp->m_next = NULL;
+ if (hlen + PPP_HDRLEN > MHLEN) {
+ MCLGET(mp, M_DONTWAIT);
+ if (M_TRAILINGSPACE(mp) < hlen + PPP_HDRLEN) {
+ m_freem(mp);
+ goto bad; /* lose if big headers and no clusters */
+ }
+ }
+#ifdef MAC
+ mac_create_mbuf_from_mbuf(m, mp);
+#endif
+ cp = mtod(mp, u_char *);
+ cp[0] = adrs;
+ cp[1] = ctrl;
+ cp[2] = 0;
+ cp[3] = PPP_IP;
+ proto = PPP_IP;
+ bcopy(iphdr, cp + PPP_HDRLEN, hlen);
+ mp->m_len = hlen + PPP_HDRLEN;
+
+ /*
+ * Trim the PPP and VJ headers off the old mbuf
+ * and stick the new and old mbufs together.
+ */
+ m->m_data += PPP_HDRLEN + xlen;
+ m->m_len -= PPP_HDRLEN + xlen;
+ if (m->m_len <= M_TRAILINGSPACE(mp)) {
+ bcopy(mtod(m, u_char *), mtod(mp, u_char *) + mp->m_len, m->m_len);
+ mp->m_len += m->m_len;
+ MFREE(m, mp->m_next);
+ } else
+ mp->m_next = m;
+ m = mp;
+ ilen += hlen - xlen;
+
+ } else if (proto == PPP_VJC_UNCOMP) {
+ if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0)
+ goto bad;
+
+ xlen = vj_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN,
+ ilen - PPP_HDRLEN, TYPE_UNCOMPRESSED_TCP,
+ sc->sc_comp, &iphdr, &hlen);
+
+ if (xlen < 0) {
+ if (sc->sc_flags & SC_DEBUG)
+ printf("ppp%d: VJ uncompress failed on type uncomp\n",
+ ifp->if_unit);
+ goto bad;
+ }
+
+ proto = PPP_IP;
+ cp[3] = PPP_IP;
+ }
+#endif /* VJC */
+
+ /*
+ * If the packet will fit in a header mbuf, don't waste a
+ * whole cluster on it.
+ */
+ if (ilen <= MHLEN && M_IS_CLUSTER(m)) {
+ MGETHDR(mp, M_DONTWAIT, MT_DATA);
+ if (mp != NULL) {
+ m_copydata(m, 0, ilen, mtod(mp, caddr_t));
+ /* instead of freeing - return cluster mbuf so it can be reused */
+ /* m_freem(m); */
+ mf = m;
+ m = mp;
+ m->m_len = ilen;
+ }
+ }
+ m->m_pkthdr.len = ilen;
+ m->m_pkthdr.rcvif = ifp;
+
+ if ((proto & 0x8000) == 0) {
+#ifdef PPP_FILTER
+ /*
+ * See whether we want to pass this packet, and
+ * if it counts as link activity.
+ */
+ adrs = *mtod(m, u_char *); /* save address field */
+ *mtod(m, u_char *) = 0; /* indicate inbound */
+ if (sc->sc_pass_filt.bf_insns != 0
+ && bpf_filter(sc->sc_pass_filt.bf_insns, (u_char *) m,
+ ilen, 0) == 0) {
+ /* drop this packet */
+ m_freem(m);
+ return mf;
+ }
+ if (sc->sc_active_filt.bf_insns == 0
+ || bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m, ilen, 0))
+ sc->sc_last_recv = time.tv_sec;
+
+ *mtod(m, u_char *) = adrs;
+#else
+ /*
+ * Record the time that we received this packet.
+ */
+ microtime(&ppp_time);
+ sc->sc_last_recv = ppp_time.tv_sec;
+#endif /* PPP_FILTER */
+ }
+
+#if NBPFILTER > 0
+ /* See if bpf wants to look at the packet. */
+ if (sc->sc_bpf)
+ bpf_mtap(sc->sc_bpf, m);
+#endif
+
+ rv = 0;
+ switch (proto) {
+#ifdef INET
+ case PPP_IP:
+ /*
+ * IP packet - take off the ppp header and pass it up to IP.
+ */
+ if ((ifp->if_flags & IFF_UP) == 0
+ || sc->sc_npmode[NP_IP] != NPMODE_PASS) {
+ /* interface is down - drop the packet. */
+ m_freem(m);
+ return mf;
+ }
+ m->m_pkthdr.len -= PPP_HDRLEN;
+ m->m_data += PPP_HDRLEN;
+ m->m_len -= PPP_HDRLEN;
+ schednetisr(NETISR_IP);
+ inq = &ipintrq;
+ break;
+#endif
+
+ default:
+ /*
+ * Some other protocol - place on input queue for read().
+ */
+ inq = &sc->sc_inq;
+ rv = 1;
+ break;
+ }
+
+ /*
+ * Put the packet on the appropriate input queue.
+ */
+ s = splimp();
+ if (IF_QFULL(inq)) {
+ IF_DROP(inq);
+ splx(s);
+ if (sc->sc_flags & SC_DEBUG)
+ printf("ppp%d: input queue full\n", ifp->if_unit);
+ ifp->if_iqdrops++;
+ goto bad;
+ }
+ IF_ENQUEUE(inq, m);
+ splx(s);
+
+ ifp->if_ipackets++;
+ ifp->if_ibytes += ilen;
+ microtime(&ppp_time);
+ ifp->if_lastchange = ppp_time;
+
+ if (rv) {
+ (*sc->sc_ctlp)(sc);
+ }
+
+ return mf;
+
+ bad:
+ m_freem(m);
+ sc->sc_if.if_ierrors++;
+ sc->sc_stats.ppp_ierrors++;
+ return mf;
+}
+
+#define MAX_DUMP_BYTES 128
+
+static void
+pppdumpm(m0)
+ struct mbuf *m0;
+{
+ char buf[3*MAX_DUMP_BYTES+4];
+ char *bp = buf;
+ struct mbuf *m;
+ static char digits[] = "0123456789abcdef";
+
+ for (m = m0; m; m = m->m_next) {
+ int l = m->m_len;
+ u_char *rptr = (u_char *)m->m_data;
+
+ while (l--) {
+ if (bp > buf + sizeof(buf) - 4)
+ goto done;
+ *bp++ = digits[*rptr >> 4]; /* convert byte to ascii hex */
+ *bp++ = digits[*rptr++ & 0xf];
+ }
+
+ if (m->m_next) {
+ if (bp > buf + sizeof(buf) - 3)
+ goto done;
+ *bp++ = '|';
+ } else
+ *bp++ = ' ';
+ }
+done:
+ if (m)
+ *bp++ = '>';
+ *bp = 0;
+ printf("%s\n", buf);
+}
+
+#endif /* NPPP > 0 */
diff --git a/cpukit/libnetworking/net/if_ppp.h b/cpukit/libnetworking/net/if_ppp.h
new file mode 100644
index 0000000000..18b191c8e6
--- /dev/null
+++ b/cpukit/libnetworking/net/if_ppp.h
@@ -0,0 +1,134 @@
+/* $Id$ */
+
+/*
+ * if_ppp.h - Point-to-Point Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ */
+
+#ifndef _IF_PPP_H_
+#define _IF_PPP_H_
+
+/*
+ * Bit definitions for flags.
+ */
+#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */
+#define SC_COMP_AC 0x00000002 /* header compression (output) */
+#define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */
+#define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */
+#define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */
+#define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */
+#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */
+#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */
+#define SC_DEBUG 0x00010000 /* enable debug messages */
+#define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */
+#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */
+#define SC_LOG_RAWIN 0x00080000 /* log all chars received */
+#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */
+#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */
+#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */
+#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */
+#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */
+#define SC_SYNC 0x00200000 /* use synchronous HDLC framing */
+#define SC_MASK 0x0fff00ff /* bits that user can change */
+
+/*
+ * State bits in sc_flags, not changeable by user.
+ */
+#define SC_TIMEOUT 0x00000400 /* timeout is currently pending */
+#define SC_VJ_RESET 0x00000800 /* need to reset VJ decomp */
+#define SC_COMP_RUN 0x00001000 /* compressor has been inited */
+#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */
+#define SC_DC_ERROR 0x00004000 /* non-fatal decomp error detected */
+#define SC_DC_FERROR 0x00008000 /* fatal decomp error detected */
+#define SC_TBUSY 0x10000000 /* xmitter doesn't need a packet yet */
+#define SC_PKTLOST 0x20000000 /* have lost or dropped a packet */
+#define SC_FLUSH 0x40000000 /* flush input until next PPP_FLAG */
+#define SC_ESCAPED 0x80000000 /* saw a PPP_ESCAPE */
+
+/*
+ * Ioctl definitions.
+ */
+
+struct npioctl {
+ int protocol; /* PPP procotol, e.g. PPP_IP */
+ enum NPmode mode;
+};
+
+/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */
+struct ppp_option_data {
+ u_char *ptr;
+ u_int length;
+ int transmit;
+};
+
+struct ifpppstatsreq {
+ char ifr_name[IFNAMSIZ];
+ struct ppp_stats stats;
+};
+
+struct ifpppcstatsreq {
+ char ifr_name[IFNAMSIZ];
+ struct ppp_comp_stats stats;
+};
+
+/*
+ * Ioctl definitions.
+ */
+
+#define PPPIOCSTASK _IOW('t', 91, int) /* set pppd task id */
+#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */
+#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */
+#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */
+#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */
+#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */
+#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */
+#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */
+#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */
+#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */
+#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */
+#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */
+#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */
+#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */
+#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data)
+#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */
+#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */
+#define PPPIOCGIDLE _IOR('t', 74, struct ppp_idle) /* get idle time */
+#ifdef PPP_FILTER
+#define PPPIOCSPASS _IOW('t', 71, struct bpf_program) /* set pass filter */
+#define PPPIOCSACTIVE _IOW('t', 70, struct bpf_program) /* set active filt */
+#endif /* PPP_FILTER */
+
+/* PPPIOC[GS]MTU are alternatives to SIOC[GS]IFMTU, used under Ultrix */
+#define PPPIOCGMTU _IOR('t', 73, int) /* get interface MTU */
+#define PPPIOCSMTU _IOW('t', 72, int) /* set interface MTU */
+
+/*
+ * These two are interface ioctls so that pppstats can do them on
+ * a socket without having to open the serial device.
+ */
+#define SIOCGPPPSTATS _IOWR('i', 123, struct ifpppstatsreq)
+#define SIOCGPPPCSTATS _IOWR('i', 122, struct ifpppcstatsreq)
+
+#if !defined(ifr_mtu)
+#define ifr_mtu ifr_ifru.ifru_metric
+#endif
+
+#if (defined(_KERNEL) || defined(_KERNEL)) && !defined(NeXT)
+void pppattach __P((void));
+void pppintr __P((void));
+#endif
+#endif /* _IF_PPP_H_ */
diff --git a/cpukit/libnetworking/net/if_pppvar.h b/cpukit/libnetworking/net/if_pppvar.h
new file mode 100644
index 0000000000..aa109b855b
--- /dev/null
+++ b/cpukit/libnetworking/net/if_pppvar.h
@@ -0,0 +1,141 @@
+/* $Id$ */
+/*
+ * if_pppvar.h - private structures and declarations for PPP.
+ *
+ * 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.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ */
+
+/*
+ * Supported network protocols. These values are used for
+ * indexing sc_npmode.
+ */
+#define NP_IP 0 /* Internet Protocol */
+#define NUM_NP 1 /* Number of NPs. */
+#define NUM_MBUFQ 64
+
+
+/*
+ * Structure describing each ppp unit.
+ */
+struct ppp_softc {
+ struct ifnet sc_if; /* network-visible interface */
+ u_int sc_flags; /* control/status bits; see if_ppp.h */
+ void *sc_devp; /* pointer to device-dep structure */
+ void (*sc_start)(struct ppp_softc *); /* start output proc */
+ void (*sc_ctlp)(struct ppp_softc *); /* rcvd control pkt */
+ void (*sc_relinq)(struct ppp_softc *); /* relinquish ifunit */
+ short sc_mru; /* max receive unit */
+ pid_t sc_xfer; /* used in transferring unit */
+ struct ifqueue sc_rawq; /* received packets */
+ struct ifqueue sc_inq; /* queue of input packets for daemon */
+ struct ifqueue sc_fastq; /* interactive output packet q */
+ struct mbuf *sc_npqueue; /* output packets not to be sent yet */
+ struct mbuf **sc_npqtail; /* ptr to last next ptr in npqueue */
+ struct pppstat sc_stats; /* count of bytes/pkts sent/rcvd */
+ caddr_t sc_bpf; /* hook for BPF */
+ enum NPmode sc_npmode[NUM_NP]; /* what to do with each NP */
+ struct compressor *sc_xcomp; /* transmit compressor */
+ void *sc_xc_state; /* transmit compressor state */
+ struct compressor *sc_rcomp; /* receive decompressor */
+ void *sc_rc_state; /* receive decompressor state */
+ time_t sc_last_sent; /* time (secs) last NP pkt sent */
+ time_t sc_last_recv; /* time (secs) last NP pkt rcvd */
+#ifdef PPP_FILTER
+ struct bpf_program sc_pass_filt; /* filter for packets to pass */
+ struct bpf_program sc_active_filt; /* filter for "non-idle" packets */
+#endif /* PPP_FILTER */
+#ifdef VJC
+ struct vjcompress *sc_comp; /* vjc control buffer */
+#endif
+
+ /* Device-dependent part for async lines. */
+ ext_accm sc_asyncmap; /* async control character map */
+ u_long sc_rasyncmap; /* receive async control char map */
+ struct mbuf *sc_outm; /* mbuf chain currently being output */
+ struct mbuf *sc_outmc; /* mbuf currently being output */
+ struct mbuf *sc_m; /* pointer to input mbuf chain */
+ struct mbuf *sc_mc; /* pointer to current input mbuf */
+ char *sc_mp; /* ptr to next char in input mbuf */
+ short sc_ilen; /* length of input packet so far */
+ u_short sc_fcs; /* FCS so far (input) */
+ u_short sc_outfcs; /* FCS so far for output packet */
+ u_char sc_rawin[16]; /* chars as received */
+ int sc_rawin_count; /* # in sc_rawin */
+
+ struct ifqueue sc_freeq; /* free packets */
+ short sc_outoff; /* output packet byte offset */
+ short sc_outflag; /* output status flag */
+ short sc_outlen; /* length of output packet */
+ short sc_outfcslen; /* length of output fcs data */
+ u_char sc_outfcsbuf[8]; /* output packet fcs buffer */
+ u_char *sc_outbuf; /* pointer to output data */
+ u_char sc_outchar;
+
+ rtems_id sc_rxtask;
+ rtems_id sc_txtask;
+ rtems_id sc_pppdtask;
+};
+
+struct ppp_softc ppp_softc[NPPP];
+
+struct ppp_softc *pppalloc(pid_t pid);
+void pppdealloc(struct ppp_softc *sc);
+int pppoutput(struct ifnet *, struct mbuf *,
+ struct sockaddr *, struct rtentry *);
+int pppioctl(struct ppp_softc *sc, int cmd, caddr_t data,
+ int flag, struct proc *p);
+struct mbuf *ppp_dequeue(struct ppp_softc *sc);
+u_short pppfcs(u_short fcs, u_char *cp, int len);
+void pppallocmbuf(struct ppp_softc *sc, struct mbuf **mp);
+
+
+/* define event values */
+#define RX_PACKET RTEMS_EVENT_1
+#define RX_MBUF RTEMS_EVENT_2
+#define RX_EMPTY RTEMS_EVENT_3
+#define TX_PACKET RTEMS_EVENT_1
+#define TX_TRANSMIT RTEMS_EVENT_2
+#define PPPD_EVENT RTEMS_EVENT_31
+
+/* define out flag values */
+#define SC_TX_BUSY 0x0001
+#define SC_TX_FCS 0x0002
+#define SC_TX_ESCAPE 0x0004
+#define SC_TX_LASTCHAR 0x0008
+#define SC_TX_PENDING 0x0010
diff --git a/cpukit/libnetworking/net/if_types.h b/cpukit/libnetworking/net/if_types.h
new file mode 100644
index 0000000000..478c419761
--- /dev/null
+++ b/cpukit/libnetworking/net/if_types.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * 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.
+ * 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.
+ *
+ * @(#)if_types.h 8.3 (Berkeley) 4/28/95
+ * $FreeBSD: src/sys/net/if_types.h,v 1.18 2005/02/22 13:04:03 glebius Exp $
+ * $NetBSD: if_types.h,v 1.16 2000/04/19 06:30:53 itojun Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NET_IF_TYPES_H_
+#define _NET_IF_TYPES_H_
+
+/*
+ * Interface types for benefit of parsing media address headers.
+ * This list is derived from the SNMP list of ifTypes, originally
+ * documented in RFC1573, now maintained as:
+ *
+ * ftp.isi.edu/in-notes/iana/assignments/smi-numbers
+ */
+
+#define IFT_OTHER 0x1 /* none of the following */
+#define IFT_1822 0x2 /* old-style arpanet imp */
+#define IFT_HDH1822 0x3 /* HDH arpanet imp */
+#define IFT_X25DDN 0x4 /* x25 to imp */
+#define IFT_X25 0x5 /* PDN X25 interface (RFC877) */
+#define IFT_ETHER 0x6 /* Ethernet CSMA/CD */
+#define IFT_ISO88023 0x7 /* CMSA/CD */
+#define IFT_ISO88024 0x8 /* Token Bus */
+#define IFT_ISO88025 0x9 /* Token Ring */
+#define IFT_ISO88026 0xa /* MAN */
+#define IFT_STARLAN 0xb
+#define IFT_P10 0xc /* Proteon 10MBit ring */
+#define IFT_P80 0xd /* Proteon 80MBit ring */
+#define IFT_HY 0xe /* Hyperchannel */
+#define IFT_FDDI 0xf
+#define IFT_LAPB 0x10
+#define IFT_SDLC 0x11
+#define IFT_T1 0x12
+#define IFT_CEPT 0x13 /* E1 - european T1 */
+#define IFT_ISDNBASIC 0x14
+#define IFT_ISDNPRIMARY 0x15
+#define IFT_PTPSERIAL 0x16 /* Proprietary PTP serial */
+#define IFT_PPP 0x17 /* RFC 1331 */
+#define IFT_LOOP 0x18 /* loopback */
+#define IFT_EON 0x19 /* ISO over IP */
+#define IFT_XETHER 0x1a /* obsolete 3MB experimental ethernet */
+#define IFT_NSIP 0x1b /* XNS over IP */
+#define IFT_SLIP 0x1c /* IP over generic TTY */
+#define IFT_ULTRA 0x1d /* Ultra Technologies */
+#define IFT_DS3 0x1e /* Generic T3 */
+#define IFT_SIP 0x1f /* SMDS */
+#define IFT_FRELAY 0x20 /* Frame Relay DTE only */
+#define IFT_RS232 0x21
+#define IFT_PARA 0x22 /* parallel-port */
+#define IFT_ARCNET 0x23
+#define IFT_ARCNETPLUS 0x24
+#define IFT_ATM 0x25 /* ATM cells */
+#define IFT_MIOX25 0x26
+#define IFT_SONET 0x27 /* SONET or SDH */
+#define IFT_X25PLE 0x28
+#define IFT_ISO88022LLC 0x29
+#define IFT_LOCALTALK 0x2a
+#define IFT_SMDSDXI 0x2b
+#define IFT_FRELAYDCE 0x2c /* Frame Relay DCE */
+#define IFT_V35 0x2d
+#define IFT_HSSI 0x2e
+#define IFT_HIPPI 0x2f
+#define IFT_MODEM 0x30 /* Generic Modem */
+#define IFT_AAL5 0x31 /* AAL5 over ATM */
+#define IFT_SONETPATH 0x32
+#define IFT_SONETVT 0x33
+#define IFT_SMDSICIP 0x34 /* SMDS InterCarrier Interface */
+#define IFT_PROPVIRTUAL 0x35 /* Proprietary Virtual/internal */
+#define IFT_PROPMUX 0x36 /* Proprietary Multiplexing */
+#define IFT_IEEE80212 0x37 /* 100BaseVG */
+#define IFT_FIBRECHANNEL 0x38 /* Fibre Channel */
+#define IFT_HIPPIINTERFACE 0x39 /* HIPPI interfaces */
+#define IFT_FRAMERELAYINTERCONNECT 0x3a /* Obsolete, use either 0x20 or 0x2c */
+#define IFT_AFLANE8023 0x3b /* ATM Emulated LAN for 802.3 */
+#define IFT_AFLANE8025 0x3c /* ATM Emulated LAN for 802.5 */
+#define IFT_CCTEMUL 0x3d /* ATM Emulated circuit */
+#define IFT_FASTETHER 0x3e /* Fast Ethernet (100BaseT) */
+#define IFT_ISDN 0x3f /* ISDN and X.25 */
+#define IFT_V11 0x40 /* CCITT V.11/X.21 */
+#define IFT_V36 0x41 /* CCITT V.36 */
+#define IFT_G703AT64K 0x42 /* CCITT G703 at 64Kbps */
+#define IFT_G703AT2MB 0x43 /* Obsolete see DS1-MIB */
+#define IFT_QLLC 0x44 /* SNA QLLC */
+#define IFT_FASTETHERFX 0x45 /* Fast Ethernet (100BaseFX) */
+#define IFT_CHANNEL 0x46 /* channel */
+#define IFT_IEEE80211 0x47 /* radio spread spectrum */
+#define IFT_IBM370PARCHAN 0x48 /* IBM System 360/370 OEMI Channel */
+#define IFT_ESCON 0x49 /* IBM Enterprise Systems Connection */
+#define IFT_DLSW 0x4a /* Data Link Switching */
+#define IFT_ISDNS 0x4b /* ISDN S/T interface */
+#define IFT_ISDNU 0x4c /* ISDN U interface */
+#define IFT_LAPD 0x4d /* Link Access Protocol D */
+#define IFT_IPSWITCH 0x4e /* IP Switching Objects */
+#define IFT_RSRB 0x4f /* Remote Source Route Bridging */
+#define IFT_ATMLOGICAL 0x50 /* ATM Logical Port */
+#define IFT_DS0 0x51 /* Digital Signal Level 0 */
+#define IFT_DS0BUNDLE 0x52 /* group of ds0s on the same ds1 */
+#define IFT_BSC 0x53 /* Bisynchronous Protocol */
+#define IFT_ASYNC 0x54 /* Asynchronous Protocol */
+#define IFT_CNR 0x55 /* Combat Net Radio */
+#define IFT_ISO88025DTR 0x56 /* ISO 802.5r DTR */
+#define IFT_EPLRS 0x57 /* Ext Pos Loc Report Sys */
+#define IFT_ARAP 0x58 /* Appletalk Remote Access Protocol */
+#define IFT_PROPCNLS 0x59 /* Proprietary Connectionless Protocol*/
+#define IFT_HOSTPAD 0x5a /* CCITT-ITU X.29 PAD Protocol */
+#define IFT_TERMPAD 0x5b /* CCITT-ITU X.3 PAD Facility */
+#define IFT_FRAMERELAYMPI 0x5c /* Multiproto Interconnect over FR */
+#define IFT_X213 0x5d /* CCITT-ITU X213 */
+#define IFT_ADSL 0x5e /* Asymmetric Digital Subscriber Loop */
+#define IFT_RADSL 0x5f /* Rate-Adapt. Digital Subscriber Loop*/
+#define IFT_SDSL 0x60 /* Symmetric Digital Subscriber Loop */
+#define IFT_VDSL 0x61 /* Very H-Speed Digital Subscrib. Loop*/
+#define IFT_ISO88025CRFPINT 0x62 /* ISO 802.5 CRFP */
+#define IFT_MYRINET 0x63 /* Myricom Myrinet */
+#define IFT_VOICEEM 0x64 /* voice recEive and transMit */
+#define IFT_VOICEFXO 0x65 /* voice Foreign Exchange Office */
+#define IFT_VOICEFXS 0x66 /* voice Foreign Exchange Station */
+#define IFT_VOICEENCAP 0x67 /* voice encapsulation */
+#define IFT_VOICEOVERIP 0x68 /* voice over IP encapsulation */
+#define IFT_ATMDXI 0x69 /* ATM DXI */
+#define IFT_ATMFUNI 0x6a /* ATM FUNI */
+#define IFT_ATMIMA 0x6b /* ATM IMA */
+#define IFT_PPPMULTILINKBUNDLE 0x6c /* PPP Multilink Bundle */
+#define IFT_IPOVERCDLC 0x6d /* IBM ipOverCdlc */
+#define IFT_IPOVERCLAW 0x6e /* IBM Common Link Access to Workstn */
+#define IFT_STACKTOSTACK 0x6f /* IBM stackToStack */
+#define IFT_VIRTUALIPADDRESS 0x70 /* IBM VIPA */
+#define IFT_MPC 0x71 /* IBM multi-protocol channel support */
+#define IFT_IPOVERATM 0x72 /* IBM ipOverAtm */
+#define IFT_ISO88025FIBER 0x73 /* ISO 802.5j Fiber Token Ring */
+#define IFT_TDLC 0x74 /* IBM twinaxial data link control */
+#define IFT_GIGABITETHERNET 0x75 /* Gigabit Ethernet */
+#define IFT_HDLC 0x76 /* HDLC */
+#define IFT_LAPF 0x77 /* LAP F */
+#define IFT_V37 0x78 /* V.37 */
+#define IFT_X25MLP 0x79 /* Multi-Link Protocol */
+#define IFT_X25HUNTGROUP 0x7a /* X25 Hunt Group */
+#define IFT_TRANSPHDLC 0x7b /* Transp HDLC */
+#define IFT_INTERLEAVE 0x7c /* Interleave channel */
+#define IFT_FAST 0x7d /* Fast channel */
+#define IFT_IP 0x7e /* IP (for APPN HPR in IP networks) */
+#define IFT_DOCSCABLEMACLAYER 0x7f /* CATV Mac Layer */
+#define IFT_DOCSCABLEDOWNSTREAM 0x80 /* CATV Downstream interface */
+#define IFT_DOCSCABLEUPSTREAM 0x81 /* CATV Upstream interface */
+#define IFT_A12MPPSWITCH 0x82 /* Avalon Parallel Processor */
+#define IFT_TUNNEL 0x83 /* Encapsulation interface */
+#define IFT_COFFEE 0x84 /* coffee pot */
+#define IFT_CES 0x85 /* Circiut Emulation Service */
+#define IFT_ATMSUBINTERFACE 0x86 /* (x) ATM Sub Interface */
+#define IFT_L2VLAN 0x87 /* Layer 2 Virtual LAN using 802.1Q */
+#define IFT_L3IPVLAN 0x88 /* Layer 3 Virtual LAN - IP Protocol */
+#define IFT_L3IPXVLAN 0x89 /* Layer 3 Virtual LAN - IPX Prot. */
+#define IFT_DIGITALPOWERLINE 0x8a /* IP over Power Lines */
+#define IFT_MEDIAMAILOVERIP 0x8b /* (xxx) Multimedia Mail over IP */
+#define IFT_DTM 0x8c /* Dynamic synchronous Transfer Mode */
+#define IFT_DCN 0x8d /* Data Communications Network */
+#define IFT_IPFORWARD 0x8e /* IP Forwarding Interface */
+#define IFT_MSDSL 0x8f /* Multi-rate Symmetric DSL */
+#define IFT_IEEE1394 0x90 /* IEEE1394 High Performance SerialBus*/
+#define IFT_IFGSN 0x91 /* HIPPI-6400 */
+#define IFT_DVBRCCMACLAYER 0x92 /* DVB-RCC MAC Layer */
+#define IFT_DVBRCCDOWNSTREAM 0x93 /* DVB-RCC Downstream Channel */
+#define IFT_DVBRCCUPSTREAM 0x94 /* DVB-RCC Upstream Channel */
+#define IFT_ATMVIRTUAL 0x95 /* ATM Virtual Interface */
+#define IFT_MPLSTUNNEL 0x96 /* MPLS Tunnel Virtual Interface */
+#define IFT_SRP 0x97 /* Spatial Reuse Protocol */
+#define IFT_VOICEOVERATM 0x98 /* Voice over ATM */
+#define IFT_VOICEOVERFRAMERELAY 0x99 /* Voice Over Frame Relay */
+#define IFT_IDSL 0x9a /* Digital Subscriber Loop over ISDN */
+#define IFT_COMPOSITELINK 0x9b /* Avici Composite Link Interface */
+#define IFT_SS7SIGLINK 0x9c /* SS7 Signaling Link */
+#define IFT_PROPWIRELESSP2P 0x9d /* Prop. P2P wireless interface */
+#define IFT_FRFORWARD 0x9e /* Frame forward Interface */
+#define IFT_RFC1483 0x9f /* Multiprotocol over ATM AAL5 */
+#define IFT_USB 0xa0 /* USB Interface */
+#define IFT_IEEE8023ADLAG 0xa1 /* IEEE 802.3ad Link Aggregate*/
+#define IFT_BGPPOLICYACCOUNTING 0xa2 /* BGP Policy Accounting */
+#define IFT_FRF16MFRBUNDLE 0xa3 /* FRF.16 Multilik Frame Relay*/
+#define IFT_H323GATEKEEPER 0xa4 /* H323 Gatekeeper */
+#define IFT_H323PROXY 0xa5 /* H323 Voice and Video Proxy */
+#define IFT_MPLS 0xa6 /* MPLS */
+#define IFT_MFSIGLINK 0xa7 /* Multi-frequency signaling link */
+#define IFT_HDSL2 0xa8 /* High Bit-Rate DSL, 2nd gen. */
+#define IFT_SHDSL 0xa9 /* Multirate HDSL2 */
+#define IFT_DS1FDL 0xaa /* Facility Data Link (4Kbps) on a DS1*/
+#define IFT_POS 0xab /* Packet over SONET/SDH Interface */
+#define IFT_DVBASILN 0xac /* DVB-ASI Input */
+#define IFT_DVBASIOUT 0xad /* DVB-ASI Output */
+#define IFT_PLC 0xae /* Power Line Communications */
+#define IFT_NFAS 0xaf /* Non-Facility Associated Signaling */
+#define IFT_TR008 0xb0 /* TROO8 */
+#define IFT_GR303RDT 0xb1 /* Remote Digital Terminal */
+#define IFT_GR303IDT 0xb2 /* Integrated Digital Terminal */
+#define IFT_ISUP 0xb3 /* ISUP */
+#define IFT_PROPDOCSWIRELESSMACLAYER 0xb4 /* prop/Wireless MAC Layer */
+#define IFT_PROPDOCSWIRELESSDOWNSTREAM 0xb5 /* prop/Wireless Downstream */
+#define IFT_PROPDOCSWIRELESSUPSTREAM 0xb6 /* prop/Wireless Upstream */
+#define IFT_HIPERLAN2 0xb7 /* HIPERLAN Type 2 Radio Interface */
+#define IFT_PROPBWAP2MP 0xb8 /* PropBroadbandWirelessAccess P2MP*/
+#define IFT_SONETOVERHEADCHANNEL 0xb9 /* SONET Overhead Channel */
+#define IFT_DIGITALWRAPPEROVERHEADCHANNEL 0xba /* Digital Wrapper Overhead */
+#define IFT_AAL2 0xbb /* ATM adaptation layer 2 */
+#define IFT_RADIOMAC 0xbc /* MAC layer over radio links */
+#define IFT_ATMRADIO 0xbd /* ATM over radio links */
+#define IFT_IMT 0xbe /* Inter-Machine Trunks */
+#define IFT_MVL 0xbf /* Multiple Virtual Lines DSL */
+#define IFT_REACHDSL 0xc0 /* Long Reach DSL */
+#define IFT_FRDLCIENDPT 0xc1 /* Frame Relay DLCI End Point */
+#define IFT_ATMVCIENDPT 0xc2 /* ATM VCI End Point */
+#define IFT_OPTICALCHANNEL 0xc3 /* Optical Channel */
+#define IFT_OPTICALTRANSPORT 0xc4 /* Optical Transport */
+
+#define IFT_STF 0xd7 /* 6to4 interface */
+
+/* not based on IANA assignments */
+#define IFT_GIF 0xf0
+#define IFT_PVC 0xf1
+#define IFT_FAITH 0xf2
+#define IFT_PFLOG 0xf6
+#define IFT_PFSYNC 0xf7
+#define IFT_CARP 0xf8 /* Common Address Redundancy Protocol */
+#endif /* !_NET_IF_TYPES_H_ */
diff --git a/cpukit/libnetworking/net/if_var.h b/cpukit/libnetworking/net/if_var.h
new file mode 100644
index 0000000000..ad32cd11a6
--- /dev/null
+++ b/cpukit/libnetworking/net/if_var.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 1982, 1986, 1989, 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.
+ * 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.
+ *
+ * From: @(#)if.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if_var.h,v 1.107 2006/06/19 22:20:44 mlaier Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NET_IF_VAR_H_
+#define _NET_IF_VAR_H_
+
+/*
+ * Structures defining a network interface, providing a packet
+ * transport mechanism (ala level 0 of the PUP protocols).
+ *
+ * Each interface accepts output datagrams of a specified maximum
+ * length, and provides higher level routines with input datagrams
+ * received from its medium.
+ *
+ * Output occurs when the routine if_output is called, with three parameters:
+ * (*ifp->if_output)(ifp, m, dst, rt)
+ * Here m is the mbuf chain to be sent and dst is the destination address.
+ * The output routine encapsulates the supplied datagram if necessary,
+ * and then transmits it on its medium.
+ *
+ * On input, each interface unwraps the data received by it, and either
+ * places it on the input queue of an internetwork datagram routine
+ * and posts the associated software interrupt, or passes the datagram to a raw
+ * packet input routine.
+ *
+ * Routines exist for locating interfaces by their addresses
+ * or for locating an interface on a certain network, as well as more general
+ * routing and gateway routines maintaining information used to locate
+ * interfaces. These routines live in the files if.c and route.c
+ */
+
+/*
+ * Forward structure declarations for function prototypes [sic].
+ */
+struct mbuf;
+#ifndef __rtems__
+struct thread;
+#endif
+struct rtentry;
+struct rt_addrinfo;
+struct socket;
+struct ether_header;
+#ifndef __rtems__
+struct carp_if;
+#endif
+
+#include <sys/queue.h> /* get TAILQ macros */
+
+/*
+ * Structure defining a queue for a network interface.
+ */
+struct ifqueue {
+ struct mbuf *ifq_head;
+ struct mbuf *ifq_tail;
+ int ifq_len;
+ int ifq_maxlen;
+ int ifq_drops;
+};
+
+/*
+ * Structure defining a network interface.
+ *
+ * (Would like to call this struct ``if'', but C isn't PL/1.)
+ */
+struct ifnet {
+ void *if_softc; /* pointer to driver state */
+ char *if_name; /* name, e.g. ``en'' or ``lo'' */
+ struct ifnet *if_next; /* all struct ifnets are chained */
+ struct ifaddr *if_addrlist; /* linked list of addresses per if */
+ int if_pcount; /* number of promiscuous listeners */
+ struct bpf_if *if_bpf; /* packet filter structure */
+ u_short if_index; /* numeric abbreviation for this if */
+ short if_unit; /* sub-unit for lower level driver */
+ short if_timer; /* time 'til if_watchdog called */
+ int if_flags; /* up/down, broadcast, etc. */
+ void *if_linkmib; /* link-type-specific MIB data */
+ size_t if_linkmiblen; /* length of above data */
+ struct if_data if_data;
+/* procedure handles */
+ int (*if_output) /* output routine (enqueue) */
+ (struct ifnet *, struct mbuf *, struct sockaddr *,
+ struct rtentry *);
+ void (*if_start) /* initiate output routine */
+ (struct ifnet *);
+ int (*if_ioctl) /* ioctl routine */
+ (struct ifnet *, u_long, caddr_t);
+ void (*if_watchdog) /* timer routine */
+ (struct ifnet *);
+ int (*if_poll_recv) /* polled receive routine */
+ (struct ifnet *, int *);
+ int (*if_poll_xmit) /* polled transmit routine */
+ (struct ifnet *, int *);
+ void (*if_poll_intren) /* polled interrupt reenable routine */
+ (struct ifnet *);
+ void (*if_poll_slowinput) /* input routine for slow devices */
+ (struct ifnet *, struct mbuf *);
+ void (*if_init) /* Init routine */
+ (void *);
+ int (*if_tap) /* Packet filter routine */
+ (struct ifnet *, struct ether_header *, struct mbuf *);
+ struct ifqueue if_snd; /* output queue */
+ struct ifqueue *if_poll_slowq; /* input queue for slow devices */
+};
+
+typedef void if_init_f_t(void *);
+
+/*
+ * XXX These aliases are terribly dangerous because they could apply
+ * to anything.
+ */
+#define if_mtu if_data.ifi_mtu
+#define if_type if_data.ifi_type
+#define if_physical if_data.ifi_physical
+#define if_addrlen if_data.ifi_addrlen
+#define if_hdrlen if_data.ifi_hdrlen
+#define if_metric if_data.ifi_metric
+#define if_baudrate if_data.ifi_baudrate
+#define if_ipackets if_data.ifi_ipackets
+#define if_ierrors if_data.ifi_ierrors
+#define if_opackets if_data.ifi_opackets
+#define if_oerrors if_data.ifi_oerrors
+#define if_collisions if_data.ifi_collisions
+#define if_ibytes if_data.ifi_ibytes
+#define if_obytes if_data.ifi_obytes
+#define if_imcasts if_data.ifi_imcasts
+#define if_omcasts if_data.ifi_omcasts
+#define if_iqdrops if_data.ifi_iqdrops
+#define if_noproto if_data.ifi_noproto
+#define if_lastchange if_data.ifi_lastchange
+#define if_recvquota if_data.ifi_recvquota
+#define if_xmitquota if_data.ifi_xmitquota
+#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)NULL)
+
+/*
+ * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
+ * are queues of messages stored on ifqueue structures
+ * (defined above). Entries are added to and deleted from these structures
+ * by these macros, which should be called with ipl raised to splimp().
+ */
+#define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
+#define IF_DROP(ifq) ((ifq)->ifq_drops++)
+
+#define IF_ENQUEUE(ifq, m) do { \
+ (m)->m_nextpkt = NULL; \
+ if ((ifq)->ifq_tail == NULL) \
+ (ifq)->ifq_head = m; \
+ else \
+ (ifq)->ifq_tail->m_nextpkt = m; \
+ (ifq)->ifq_tail = m; \
+ (ifq)->ifq_len++; \
+} while (0)
+
+#define IF_PREPEND(ifq, m) do { \
+ (m)->m_nextpkt = (ifq)->ifq_head; \
+ if ((ifq)->ifq_tail == NULL) \
+ (ifq)->ifq_tail = (m); \
+ (ifq)->ifq_head = (m); \
+ (ifq)->ifq_len++; \
+} while (0)
+
+#define IF_DEQUEUE(ifq, m) do { \
+ (m) = (ifq)->ifq_head; \
+ if (m) { \
+ if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL) \
+ (ifq)->ifq_tail = NULL; \
+ (m)->m_nextpkt = NULL; \
+ (ifq)->ifq_len--; \
+ } \
+} while (0)
+
+/*
+ * The ifaddr structure contains information about one address
+ * of an interface. They are maintained by the different address families,
+ * are allocated and attached when an address is set, and are linked
+ * together so all addresses for an interface can be located.
+ */
+struct ifaddr {
+ struct sockaddr *ifa_addr; /* address of interface */
+ struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */
+#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
+ struct sockaddr *ifa_netmask; /* used to determine subnet */
+ struct ifnet *ifa_ifp; /* back-pointer to interface */
+ struct ifaddr *ifa_next; /* next address for interface */
+ void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */
+ (int, struct rtentry *, struct sockaddr *);
+ u_short ifa_flags; /* mostly rt_flags for cloning */
+ u_int ifa_refcnt; /* references to this structure */
+ int ifa_metric; /* cost of going out this interface */
+ int (*ifa_claim_addr) /* check if an addr goes to this if */
+ (struct ifaddr *, struct sockaddr *);
+
+};
+#define IFA_ROUTE RTF_UP /* route installed */
+
+#ifdef _KERNEL
+#define IFAFREE(ifa) \
+ if ((ifa)->ifa_refcnt <= 0) \
+ ifafree(ifa); \
+ else \
+ (ifa)->ifa_refcnt--;
+
+extern struct ifnet *ifnet;
+extern int ifqmaxlen;
+extern struct ifnet loif[];
+extern int if_index;
+extern struct ifaddr **ifnet_addrs;
+
+void if_attach(struct ifnet *);
+void if_down(struct ifnet *);
+void if_up(struct ifnet *);
+/*void ifinit(void);*/ /* declared in systm.h for main() */
+int ifioctl(struct socket *, u_long, caddr_t, struct proc *);
+int ifpromisc(struct ifnet *, int);
+
+struct ifaddr *ifa_ifwithaddr(struct sockaddr *);
+struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
+struct ifaddr *ifa_ifwithnet(struct sockaddr *);
+struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
+struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
+
+#endif /* _KERNEL */
+
+#endif /* !_NET_IF_VAR_H_ */
diff --git a/cpukit/libnetworking/net/netisr.h b/cpukit/libnetworking/net/netisr.h
new file mode 100644
index 0000000000..2500f3f46c
--- /dev/null
+++ b/cpukit/libnetworking/net/netisr.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1980, 1986, 1989, 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.
+ * 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.
+ *
+ * @(#)netisr.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/netisr.h,v 1.33 2005/01/07 01:45:35 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NET_NETISR_H_
+#define _NET_NETISR_H_
+
+/*
+ * The networking code runs off software interrupts.
+ *
+ * You can switch into the network by doing splnet() and return by splx().
+ * The software interrupt level for the network is higher than the software
+ * level for the clock (so you can enter the network in routines called
+ * at timeout time).
+ */
+
+/*
+ * Each ``pup-level-1'' input queue has a bit in a ``netisr'' status
+ * word which is used to de-multiplex a single software
+ * interrupt used for scheduling the network code to calls
+ * on the lowest level routine of each protocol.
+ */
+#define NETISR_RAW 0 /* same as AF_UNSPEC */
+#define NETISR_IP 2 /* same as AF_INET */
+#define NETISR_IMP 3 /* same as AF_IMPLINK */
+#define NETISR_ISO 7 /* same as AF_ISO */
+#define NETISR_CCITT 10 /* same as AF_CCITT */
+#define NETISR_ATALK 16 /* same as AF_APPLETALK */
+#define NETISR_ARP 18 /* same as AF_LINK */
+#define NETISR_IPX 23 /* same as AF_IPX */
+#define NETISR_ISDN 26 /* same as AF_E164 */
+#define NETISR_PPP 27 /* PPP soft interrupt */
+
+#define schednetisr(anisr) rtems_bsdnet_schednetisr(anisr)
+
+#ifndef LOCORE
+#ifdef _KERNEL
+extern volatile unsigned int netisr; /* scheduling bits for network */
+
+typedef void netisr_t(void);
+
+struct netisrtab {
+ int nit_num;
+ netisr_t *nit_isr;
+};
+
+#define NETISR_SET(num, isr)
+
+int register_netisr __P((int, netisr_t *));
+
+#endif
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/net/ppp-comp.h b/cpukit/libnetworking/net/ppp-comp.h
new file mode 100644
index 0000000000..aa2f99b6d1
--- /dev/null
+++ b/cpukit/libnetworking/net/ppp-comp.h
@@ -0,0 +1,165 @@
+/*
+ * ppp-comp.h - Definitions for doing PPP packet compression.
+ *
+ * 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$
+ */
+
+#ifndef _NET_PPP_COMP_H
+#define _NET_PPP_COMP_H
+
+/*
+ * The following symbols control whether we include code for
+ * various compression methods.
+ */
+#ifndef DO_BSD_COMPRESS
+#define DO_BSD_COMPRESS 0 /* by default, include BSD-Compress */
+#endif
+#ifndef DO_DEFLATE
+#define DO_DEFLATE 0 /* by default, include Deflate */
+#endif
+#define DO_PREDICTOR_1 0
+#define DO_PREDICTOR_2 0
+
+/*
+ * Structure giving methods for compression/decompression.
+ */
+#ifdef PACKETPTR
+struct compressor {
+ int compress_proto; /* CCP compression protocol number */
+
+ /* Allocate space for a compressor (transmit side) */
+ void *(*comp_alloc) __P((u_char *options, int opt_len));
+ /* Free space used by a compressor */
+ void (*comp_free) __P((void *state));
+ /* Initialize a compressor */
+ int (*comp_init) __P((void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int debug));
+ /* Reset a compressor */
+ void (*comp_reset) __P((void *state));
+ /* Compress a packet */
+ int (*compress) __P((void *state, PACKETPTR *mret,
+ PACKETPTR mp, int orig_len, int max_len));
+ /* Return compression statistics */
+ void (*comp_stat) __P((void *state, struct compstat *stats));
+
+ /* Allocate space for a decompressor (receive side) */
+ void *(*decomp_alloc) __P((u_char *options, int opt_len));
+ /* Free space used by a decompressor */
+ void (*decomp_free) __P((void *state));
+ /* Initialize a decompressor */
+ int (*decomp_init) __P((void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int mru, int debug));
+ /* Reset a decompressor */
+ void (*decomp_reset) __P((void *state));
+ /* Decompress a packet. */
+ int (*decompress) __P((void *state, PACKETPTR mp,
+ PACKETPTR *dmpp));
+ /* Update state for an incompressible packet received */
+ void (*incomp) __P((void *state, PACKETPTR mp));
+ /* Return decompression statistics */
+ void (*decomp_stat) __P((void *state, struct compstat *stats));
+};
+#endif /* PACKETPTR */
+
+/*
+ * Return values for decompress routine.
+ * We need to make these distinctions so that we can disable certain
+ * useful functionality, namely sending a CCP reset-request as a result
+ * of an error detected after decompression. This is to avoid infringing
+ * a patent held by Motorola.
+ * Don't you just lurve software patents.
+ */
+#define DECOMP_OK 0 /* everything went OK */
+#define DECOMP_ERROR 1 /* error detected before decomp. */
+#define DECOMP_FATALERROR 2 /* error detected after decomp. */
+
+/*
+ * CCP codes.
+ */
+#define CCP_CONFREQ 1
+#define CCP_CONFACK 2
+#define CCP_TERMREQ 5
+#define CCP_TERMACK 6
+#define CCP_RESETREQ 14
+#define CCP_RESETACK 15
+
+/*
+ * Max # bytes for a CCP option
+ */
+#define CCP_MAX_OPTION_LENGTH 32
+
+/*
+ * Parts of a CCP packet.
+ */
+#define CCP_CODE(dp) ((dp)[0])
+#define CCP_ID(dp) ((dp)[1])
+#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3])
+#define CCP_HDRLEN 4
+
+#define CCP_OPT_CODE(dp) ((dp)[0])
+#define CCP_OPT_LENGTH(dp) ((dp)[1])
+#define CCP_OPT_MINLEN 2
+
+/*
+ * Definitions for BSD-Compress.
+ */
+#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */
+#define CILEN_BSD_COMPRESS 3 /* length of config. option */
+
+/* Macros for handling the 3rd byte of the BSD-Compress config option. */
+#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */
+#define BSD_VERSION(x) ((x) >> 5) /* version of option format */
+#define BSD_CURRENT_VERSION 1 /* current version number */
+#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n))
+
+#define BSD_MIN_BITS 9 /* smallest code size supported */
+#define BSD_MAX_BITS 15 /* largest code size supported */
+
+/*
+ * Definitions for Deflate.
+ */
+#define CI_DEFLATE 26 /* config option for Deflate */
+#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */
+#define CILEN_DEFLATE 4 /* length of its config option */
+
+#define DEFLATE_MIN_SIZE 8
+#define DEFLATE_MAX_SIZE 15
+#define DEFLATE_METHOD_VAL 8
+#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE)
+#define DEFLATE_METHOD(x) ((x) & 0x0F)
+#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \
+ + DEFLATE_METHOD_VAL)
+#define DEFLATE_CHK_SEQUENCE 0
+
+/*
+ * Definitions for other, as yet unsupported, compression methods.
+ */
+#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */
+#define CILEN_PREDICTOR_1 2 /* length of its config option */
+#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */
+#define CILEN_PREDICTOR_2 2 /* length of its config option */
+
+#endif /* _NET_PPP_COMP_H */
diff --git a/cpukit/libnetworking/net/ppp-deflate.c b/cpukit/libnetworking/net/ppp-deflate.c
new file mode 100644
index 0000000000..2023735b8b
--- /dev/null
+++ b/cpukit/libnetworking/net/ppp-deflate.c
@@ -0,0 +1,683 @@
+/* $Id$ */
+
+/*
+ * ppp_deflate.c - interface the zlib procedures for Deflate compression
+ * and decompression (as used by gzip) to the PPP code.
+ * This version is for use with mbufs on BSD-derived systems.
+ *
+ * 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 HAS 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.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <net/ppp_defs.h>
+#include <net/zlib.h>
+
+#define PACKETPTR struct mbuf *
+#include <net/ppp-comp.h>
+
+#if DO_DEFLATE
+
+#define DEFLATE_DEBUG 1
+
+/*
+ * State for a Deflate (de)compressor.
+ */
+struct deflate_state {
+ int seqno;
+ int w_size;
+ int unit;
+ int hdrlen;
+ int mru;
+ int debug;
+ z_stream strm;
+ struct compstat stats;
+};
+
+#define DEFLATE_OVHD 2 /* Deflate overhead/packet */
+
+static void *zalloc __P((void *, u_int items, u_int size));
+static void zfree __P((void *, void *ptr));
+static void *z_comp_alloc __P((u_char *options, int opt_len));
+static void *z_decomp_alloc __P((u_char *options, int opt_len));
+static void z_comp_free __P((void *state));
+static void z_decomp_free __P((void *state));
+static int z_comp_init __P((void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int debug));
+static int z_decomp_init __P((void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int mru, int debug));
+static int z_compress __P((void *state, struct mbuf **mret,
+ struct mbuf *mp, int slen, int maxolen));
+static void z_incomp __P((void *state, struct mbuf *dmsg));
+static int z_decompress __P((void *state, struct mbuf *cmp,
+ struct mbuf **dmpp));
+static void z_comp_reset __P((void *state));
+static void z_decomp_reset __P((void *state));
+static void z_comp_stats __P((void *state, struct compstat *stats));
+
+/*
+ * Procedures exported to if_ppp.c.
+ */
+struct compressor ppp_deflate = {
+ CI_DEFLATE, /* compress_proto */
+ z_comp_alloc, /* comp_alloc */
+ z_comp_free, /* comp_free */
+ z_comp_init, /* comp_init */
+ z_comp_reset, /* comp_reset */
+ z_compress, /* compress */
+ z_comp_stats, /* comp_stat */
+ z_decomp_alloc, /* decomp_alloc */
+ z_decomp_free, /* decomp_free */
+ z_decomp_init, /* decomp_init */
+ z_decomp_reset, /* decomp_reset */
+ z_decompress, /* decompress */
+ z_incomp, /* incomp */
+ z_comp_stats, /* decomp_stat */
+};
+
+struct compressor ppp_deflate = {
+ CI_DEFLATE_DRAFT, /* compress_proto */
+ z_comp_alloc, /* comp_alloc */
+ z_comp_free, /* comp_free */
+ z_comp_init, /* comp_init */
+ z_comp_reset, /* comp_reset */
+ z_compress, /* compress */
+ z_comp_stats, /* comp_stat */
+ z_decomp_alloc, /* decomp_alloc */
+ z_decomp_free, /* decomp_free */
+ z_decomp_init, /* decomp_init */
+ z_decomp_reset, /* decomp_reset */
+ z_decompress, /* decompress */
+ z_incomp, /* incomp */
+ z_comp_stats, /* decomp_stat */
+};
+
+/*
+ * Space allocation and freeing routines for use by zlib routines.
+ */
+void *
+zalloc(notused, items, size)
+ void *notused;
+ u_int items, size;
+{
+ void *ptr;
+
+ MALLOC(ptr, void *, items * size, M_DEVBUF, M_NOWAIT);
+ return ptr;
+}
+
+void
+zfree(notused, ptr)
+ void *notused;
+ void *ptr;
+{
+ FREE(ptr, M_DEVBUF);
+}
+
+/*
+ * Allocate space for a compressor.
+ */
+static void *
+z_comp_alloc(options, opt_len)
+ u_char *options;
+ int opt_len;
+{
+ struct deflate_state *state;
+ int w_size;
+
+ if (opt_len != CILEN_DEFLATE
+ || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
+ || options[1] != CILEN_DEFLATE
+ || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
+ || options[3] != DEFLATE_CHK_SEQUENCE)
+ return NULL;
+ w_size = DEFLATE_SIZE(options[2]);
+ if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
+ return NULL;
+
+ MALLOC(state, struct deflate_state *, sizeof(struct deflate_state),
+ M_DEVBUF, M_NOWAIT);
+ if (state == NULL)
+ return NULL;
+
+ state->strm.next_in = NULL;
+ state->strm.zalloc = zalloc;
+ state->strm.zfree = zfree;
+ if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL,
+ -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
+ FREE(state, M_DEVBUF);
+ return NULL;
+ }
+
+ state->w_size = w_size;
+ bzero(&state->stats, sizeof(state->stats));
+ return (void *) state;
+}
+
+static void
+z_comp_free(arg)
+ void *arg;
+{
+ struct deflate_state *state = (struct deflate_state *) arg;
+
+ deflateEnd(&state->strm);
+ FREE(state, M_DEVBUF);
+}
+
+static int
+z_comp_init(arg, options, opt_len, unit, hdrlen, debug)
+ void *arg;
+ u_char *options;
+ int opt_len, unit, hdrlen, debug;
+{
+ struct deflate_state *state = (struct deflate_state *) arg;
+
+ if (opt_len < CILEN_DEFLATE
+ || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
+ || options[1] != CILEN_DEFLATE
+ || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
+ || DEFLATE_SIZE(options[2]) != state->w_size
+ || options[3] != DEFLATE_CHK_SEQUENCE)
+ return 0;
+
+ state->seqno = 0;
+ state->unit = unit;
+ state->hdrlen = hdrlen;
+ state->debug = debug;
+
+ deflateReset(&state->strm);
+
+ return 1;
+}
+
+static void
+z_comp_reset(arg)
+ void *arg;
+{
+ struct deflate_state *state = (struct deflate_state *) arg;
+
+ state->seqno = 0;
+ deflateReset(&state->strm);
+}
+
+int
+z_compress(arg, mret, mp, orig_len, maxolen)
+ void *arg;
+ struct mbuf **mret; /* compressed packet (out) */
+ struct mbuf *mp; /* uncompressed packet (in) */
+ int orig_len, maxolen;
+{
+ struct deflate_state *state = (struct deflate_state *) arg;
+ u_char *rptr, *wptr;
+ int proto, olen, wspace, r, flush;
+ struct mbuf *m;
+
+ /*
+ * Check that the protocol is in the range we handle.
+ */
+ rptr = mtod(mp, u_char *);
+ proto = PPP_PROTOCOL(rptr);
+ if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) {
+ *mret = NULL;
+ return orig_len;
+ }
+
+ /* Allocate one mbuf initially. */
+ if (maxolen > orig_len)
+ maxolen = orig_len;
+ MGET(m, M_DONTWAIT, MT_DATA);
+ *mret = m;
+ if (m != NULL) {
+ m->m_len = 0;
+ if (maxolen + state->hdrlen > MLEN)
+ MCLGET(m, M_DONTWAIT);
+ wspace = M_TRAILINGSPACE(m);
+ if (state->hdrlen + PPP_HDRLEN + 2 < wspace) {
+ m->m_data += state->hdrlen;
+ wspace -= state->hdrlen;
+ }
+ wptr = mtod(m, u_char *);
+
+ /*
+ * Copy over the PPP header and store the 2-byte sequence number.
+ */
+ wptr[0] = PPP_ADDRESS(rptr);
+ wptr[1] = PPP_CONTROL(rptr);
+ wptr[2] = PPP_COMP >> 8;
+ wptr[3] = PPP_COMP;
+ wptr += PPP_HDRLEN;
+ wptr[0] = state->seqno >> 8;
+ wptr[1] = state->seqno;
+ wptr += 2;
+ state->strm.next_out = wptr;
+ state->strm.avail_out = wspace - (PPP_HDRLEN + 2);
+ } else {
+ state->strm.next_out = NULL;
+ state->strm.avail_out = 1000000;
+ wptr = NULL;
+ wspace = 0;
+ }
+ ++state->seqno;
+
+ rptr += (proto > 0xff)? 2: 3; /* skip 1st proto byte if 0 */
+ state->strm.next_in = rptr;
+ state->strm.avail_in = mtod(mp, u_char *) + mp->m_len - rptr;
+ mp = mp->m_next;
+ flush = (mp == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
+ olen = 0;
+ for (;;) {
+ r = deflate(&state->strm, flush);
+ if (r != Z_OK) {
+ printf("z_compress: deflate returned %d (%s)\n",
+ r, (state->strm.msg? state->strm.msg: ""));
+ break;
+ }
+ if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
+ break; /* all done */
+ if (state->strm.avail_in == 0 && mp != NULL) {
+ state->strm.next_in = mtod(mp, u_char *);
+ state->strm.avail_in = mp->m_len;
+ mp = mp->m_next;
+ if (mp == NULL)
+ flush = Z_PACKET_FLUSH;
+ }
+ if (state->strm.avail_out == 0) {
+ if (m != NULL) {
+ m->m_len = wspace;
+ olen += wspace;
+ MGET(m->m_next, M_DONTWAIT, MT_DATA);
+ m = m->m_next;
+ if (m != NULL) {
+ m->m_len = 0;
+ if (maxolen - olen > MLEN)
+ MCLGET(m, M_DONTWAIT);
+ state->strm.next_out = mtod(m, u_char *);
+ state->strm.avail_out = wspace = M_TRAILINGSPACE(m);
+ }
+ }
+ if (m == NULL) {
+ state->strm.next_out = NULL;
+ state->strm.avail_out = 1000000;
+ }
+ }
+ }
+ if (m != NULL)
+ olen += (m->m_len = wspace - state->strm.avail_out);
+
+ /*
+ * See if we managed to reduce the size of the packet.
+ * If the compressor just gave us a single zero byte, it means
+ * the packet was incompressible.
+ */
+ if (m != NULL && olen < orig_len
+ && !(olen == PPP_HDRLEN + 3 && *wptr == 0)) {
+ state->stats.comp_bytes += olen;
+ state->stats.comp_packets++;
+ } else {
+ if (*mret != NULL) {
+ m_freem(*mret);
+ *mret = NULL;
+ }
+ state->stats.inc_bytes += orig_len;
+ state->stats.inc_packets++;
+ olen = orig_len;
+ }
+ state->stats.unc_bytes += orig_len;
+ state->stats.unc_packets++;
+
+ return olen;
+}
+
+static void
+z_comp_stats(arg, stats)
+ void *arg;
+ struct compstat *stats;
+{
+ struct deflate_state *state = (struct deflate_state *) arg;
+ u_int out;
+
+ *stats = state->stats;
+ stats->ratio = stats->unc_bytes;
+ out = stats->comp_bytes + stats->inc_bytes;
+ if (stats->ratio <= 0x7ffffff)
+ stats->ratio <<= 8;
+ else
+ out >>= 8;
+ if (out != 0)
+ stats->ratio /= out;
+}
+
+/*
+ * Allocate space for a decompressor.
+ */
+static void *
+z_decomp_alloc(options, opt_len)
+ u_char *options;
+ int opt_len;
+{
+ struct deflate_state *state;
+ int w_size;
+
+ if (opt_len != CILEN_DEFLATE
+ || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
+ || options[1] != CILEN_DEFLATE
+ || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
+ || options[3] != DEFLATE_CHK_SEQUENCE)
+ return NULL;
+ w_size = DEFLATE_SIZE(options[2]);
+ if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
+ return NULL;
+
+ MALLOC(state, struct deflate_state *, sizeof(struct deflate_state),
+ M_DEVBUF, M_NOWAIT);
+ if (state == NULL)
+ return NULL;
+
+ state->strm.next_out = NULL;
+ state->strm.zalloc = zalloc;
+ state->strm.zfree = zfree;
+ if (inflateInit2(&state->strm, -w_size) != Z_OK) {
+ FREE(state, M_DEVBUF);
+ return NULL;
+ }
+
+ state->w_size = w_size;
+ bzero(&state->stats, sizeof(state->stats));
+ return (void *) state;
+}
+
+static void
+z_decomp_free(arg)
+ void *arg;
+{
+ struct deflate_state *state = (struct deflate_state *) arg;
+
+ inflateEnd(&state->strm);
+ FREE(state, M_DEVBUF);
+}
+
+static int
+z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug)
+ void *arg;
+ u_char *options;
+ int opt_len, unit, hdrlen, mru, debug;
+{
+ struct deflate_state *state = (struct deflate_state *) arg;
+
+ if (opt_len < CILEN_DEFLATE
+ || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
+ || options[1] != CILEN_DEFLATE
+ || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
+ || DEFLATE_SIZE(options[2]) != state->w_size
+ || options[3] != DEFLATE_CHK_SEQUENCE)
+ return 0;
+
+ state->seqno = 0;
+ state->unit = unit;
+ state->hdrlen = hdrlen;
+ state->debug = debug;
+ state->mru = mru;
+
+ inflateReset(&state->strm);
+
+ return 1;
+}
+
+static void
+z_decomp_reset(arg)
+ void *arg;
+{
+ struct deflate_state *state = (struct deflate_state *) arg;
+
+ state->seqno = 0;
+ inflateReset(&state->strm);
+}
+
+/*
+ * Decompress a Deflate-compressed packet.
+ *
+ * Because of patent problems, we return DECOMP_ERROR for errors
+ * found by inspecting the input data and for system problems, but
+ * DECOMP_FATALERROR for any errors which could possibly be said to
+ * be being detected "after" decompression. For DECOMP_ERROR,
+ * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
+ * infringing a patent of Motorola's if we do, so we take CCP down
+ * instead.
+ *
+ * Given that the frame has the correct sequence number and a good FCS,
+ * errors such as invalid codes in the input most likely indicate a
+ * bug, so we return DECOMP_FATALERROR for them in order to turn off
+ * compression, even though they are detected by inspecting the input.
+ */
+int
+z_decompress(arg, mi, mop)
+ void *arg;
+ struct mbuf *mi, **mop;
+{
+ struct deflate_state *state = (struct deflate_state *) arg;
+ struct mbuf *mo, *mo_head;
+ u_char *rptr, *wptr;
+ int rlen, olen, ospace;
+ int seq, i, flush, r, decode_proto;
+ u_char hdr[PPP_HDRLEN + DEFLATE_OVHD];
+
+ *mop = NULL;
+ rptr = mtod(mi, u_char *);
+ rlen = mi->m_len;
+ for (i = 0; i < PPP_HDRLEN + DEFLATE_OVHD; ++i) {
+ while (rlen <= 0) {
+ mi = mi->m_next;
+ if (mi == NULL)
+ return DECOMP_ERROR;
+ rptr = mtod(mi, u_char *);
+ rlen = mi->m_len;
+ }
+ hdr[i] = *rptr++;
+ --rlen;
+ }
+
+ /* Check the sequence number. */
+ seq = (hdr[PPP_HDRLEN] << 8) + hdr[PPP_HDRLEN+1];
+ if (seq != state->seqno) {
+ if (state->debug)
+ printf("z_decompress%d: bad seq # %d, expected %d\n",
+ state->unit, seq, state->seqno);
+ return DECOMP_ERROR;
+ }
+ ++state->seqno;
+
+ /* Allocate an output mbuf. */
+ MGETHDR(mo, M_DONTWAIT, MT_DATA);
+ if (mo == NULL)
+ return DECOMP_ERROR;
+ mo_head = mo;
+ mo->m_len = 0;
+ mo->m_next = NULL;
+ MCLGET(mo, M_DONTWAIT);
+ ospace = M_TRAILINGSPACE(mo);
+ if (state->hdrlen + PPP_HDRLEN < ospace) {
+ mo->m_data += state->hdrlen;
+ ospace -= state->hdrlen;
+ }
+
+ /*
+ * Fill in the first part of the PPP header. The protocol field
+ * comes from the decompressed data.
+ */
+ wptr = mtod(mo, u_char *);
+ wptr[0] = PPP_ADDRESS(hdr);
+ wptr[1] = PPP_CONTROL(hdr);
+ wptr[2] = 0;
+
+ /*
+ * Set up to call inflate. We set avail_out to 1 initially so we can
+ * look at the first byte of the output and decide whether we have
+ * a 1-byte or 2-byte protocol field.
+ */
+ state->strm.next_in = rptr;
+ state->strm.avail_in = rlen;
+ mi = mi->m_next;
+ flush = (mi == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
+ rlen += PPP_HDRLEN + DEFLATE_OVHD;
+ state->strm.next_out = wptr + 3;
+ state->strm.avail_out = 1;
+ decode_proto = 1;
+ olen = PPP_HDRLEN;
+
+ /*
+ * Call inflate, supplying more input or output as needed.
+ */
+ for (;;) {
+ r = inflate(&state->strm, flush);
+ if (r != Z_OK) {
+#if !DEFLATE_DEBUG
+ if (state->debug)
+#endif
+ printf("z_decompress%d: inflate returned %d (%s)\n",
+ state->unit, r, (state->strm.msg? state->strm.msg: ""));
+ m_freem(mo_head);
+ return DECOMP_FATALERROR;
+ }
+ if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
+ break; /* all done */
+ if (state->strm.avail_in == 0 && mi != NULL) {
+ state->strm.next_in = mtod(mi, u_char *);
+ state->strm.avail_in = mi->m_len;
+ rlen += mi->m_len;
+ mi = mi->m_next;
+ if (mi == NULL)
+ flush = Z_PACKET_FLUSH;
+ }
+ if (state->strm.avail_out == 0) {
+ if (decode_proto) {
+ state->strm.avail_out = ospace - PPP_HDRLEN;
+ if ((wptr[3] & 1) == 0) {
+ /* 2-byte protocol field */
+ wptr[2] = wptr[3];
+ --state->strm.next_out;
+ ++state->strm.avail_out;
+ --olen;
+ }
+ decode_proto = 0;
+ } else {
+ mo->m_len = ospace;
+ olen += ospace;
+ MGET(mo->m_next, M_DONTWAIT, MT_DATA);
+ mo = mo->m_next;
+ if (mo == NULL) {
+ m_freem(mo_head);
+ return DECOMP_ERROR;
+ }
+ MCLGET(mo, M_DONTWAIT);
+ state->strm.next_out = mtod(mo, u_char *);
+ state->strm.avail_out = ospace = M_TRAILINGSPACE(mo);
+ }
+ }
+ }
+ if (decode_proto) {
+ m_freem(mo_head);
+ return DECOMP_ERROR;
+ }
+ olen += (mo->m_len = ospace - state->strm.avail_out);
+#if DEFLATE_DEBUG
+ if (olen > state->mru + PPP_HDRLEN)
+ printf("ppp_deflate%d: exceeded mru (%d > %d)\n",
+ state->unit, olen, state->mru + PPP_HDRLEN);
+#endif
+
+ state->stats.unc_bytes += olen;
+ state->stats.unc_packets++;
+ state->stats.comp_bytes += rlen;
+ state->stats.comp_packets++;
+
+ *mop = mo_head;
+ return DECOMP_OK;
+}
+
+/*
+ * Incompressible data has arrived - add it to the history.
+ */
+static void
+z_incomp(arg, mi)
+ void *arg;
+ struct mbuf *mi;
+{
+ struct deflate_state *state = (struct deflate_state *) arg;
+ u_char *rptr;
+ int rlen, proto, r;
+
+ /*
+ * Check that the protocol is one we handle.
+ */
+ rptr = mtod(mi, u_char *);
+ proto = PPP_PROTOCOL(rptr);
+ if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
+ return;
+
+ ++state->seqno;
+
+ /*
+ * Iterate through the mbufs, adding the characters in them
+ * to the decompressor's history. For the first mbuf, we start
+ * at the either the 1st or 2nd byte of the protocol field,
+ * depending on whether the protocol value is compressible.
+ */
+ rlen = mi->m_len;
+ state->strm.next_in = rptr + 3;
+ state->strm.avail_in = rlen - 3;
+ if (proto > 0xff) {
+ --state->strm.next_in;
+ ++state->strm.avail_in;
+ }
+ for (;;) {
+ r = inflateIncomp(&state->strm);
+ if (r != Z_OK) {
+ /* gak! */
+#if !DEFLATE_DEBUG
+ if (state->debug)
+#endif
+ printf("z_incomp%d: inflateIncomp returned %d (%s)\n",
+ state->unit, r, (state->strm.msg? state->strm.msg: ""));
+ return;
+ }
+ mi = mi->m_next;
+ if (mi == NULL)
+ break;
+ state->strm.next_in = mtod(mi, u_char *);
+ state->strm.avail_in = mi->m_len;
+ rlen += mi->m_len;
+ }
+
+ /*
+ * Update stats.
+ */
+ state->stats.inc_bytes += rlen;
+ state->stats.inc_packets++;
+ state->stats.unc_bytes += rlen;
+ state->stats.unc_packets++;
+}
+
+#endif /* DO_DEFLATE */
diff --git a/cpukit/libnetworking/net/ppp_defs.h b/cpukit/libnetworking/net/ppp_defs.h
new file mode 100644
index 0000000000..c8367c1998
--- /dev/null
+++ b/cpukit/libnetworking/net/ppp_defs.h
@@ -0,0 +1,184 @@
+/* $Id$ */
+
+/*
+ * ppp_defs.h - PPP definitions.
+ *
+ * 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.
+ */
+
+#ifndef _PPP_DEFS_H_
+#define _PPP_DEFS_H_
+
+/*
+ * The basic PPP frame.
+ */
+#define PPP_HDRLEN 4 /* octets for standard ppp header */
+#define PPP_FCSLEN 2 /* octets for FCS */
+
+/*
+ * Packet sizes
+ *
+ * Note - lcp shouldn't be allowed to negotiate stuff outside these
+ * limits. See lcp.h in the pppd directory.
+ * (XXX - these constants should simply be shared by lcp.c instead
+ * of living in lcp.h)
+ */
+#define PPP_MTU 1500 /* Default MTU (size of Info field) */
+#define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN)
+#define PPP_MINMTU 64
+#define PPP_MRU 1500 /* default MRU = max length of info field */
+#define PPP_MAXMRU 65000 /* Largest MRU we allow */
+#define PPP_MINMRU 128
+
+#define PPP_ADDRESS(p) (((u_char *)(p))[0])
+#define PPP_CONTROL(p) (((u_char *)(p))[1])
+#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])
+
+/*
+ * Significant octet values.
+ */
+#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */
+#define PPP_UI 0x03 /* Unnumbered Information */
+#define PPP_FLAG 0x7e /* Flag Sequence */
+#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */
+#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */
+
+/*
+ * Protocol field values.
+ */
+#define PPP_IP 0x21 /* Internet Protocol */
+#define PPP_AT 0x29 /* AppleTalk Protocol */
+#define PPP_IPX 0x2b /* IPX protocol */
+#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */
+#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */
+#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */
+#define PPP_COMP 0xfd /* compressed packet */
+#define PPP_IPCP 0x8021 /* IP Control Protocol */
+#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */
+#define PPP_IPXCP 0x802b /* IPX Control Protocol */
+#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
+#define PPP_CCP 0x80fd /* Compression Control Protocol */
+#define PPP_LCP 0xc021 /* Link Control Protocol */
+#define PPP_PAP 0xc023 /* Password Authentication Protocol */
+#define PPP_LQR 0xc025 /* Link Quality Report protocol */
+#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */
+#define PPP_CBCP 0xc029 /* Callback Control Protocol */
+
+/*
+ * Values for FCS calculations.
+ */
+#define PPP_INITFCS 0xffff /* Initial FCS value */
+#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */
+#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
+
+/*
+ * A 32-bit unsigned integral type.
+ */
+
+#if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) \
+ && !defined(__FreeBSD__) && (NS_TARGET < 40)
+#ifdef UINT32_T
+typedef UINT32_T u_int32_t;
+#else
+/*typedef unsigned int u_int32_t;*/
+/*typedef unsigned short u_int16_t;*/
+#endif
+#endif
+
+/*
+ * Extended asyncmap - allows any character to be escaped.
+ */
+typedef u_int32_t ext_accm[8];
+
+/*
+ * What to do with network protocol (NP) packets.
+ */
+enum NPmode {
+ NPMODE_PASS, /* pass the packet through */
+ NPMODE_DROP, /* silently drop the packet */
+ NPMODE_ERROR, /* return an error */
+ NPMODE_QUEUE /* save it up for later. */
+};
+
+/*
+ * Statistics.
+ */
+struct pppstat {
+ unsigned int ppp_ibytes; /* bytes received */
+ unsigned int ppp_ipackets; /* packets received */
+ unsigned int ppp_ierrors; /* receive errors */
+ unsigned int ppp_obytes; /* bytes sent */
+ unsigned int ppp_opackets; /* packets sent */
+ unsigned int ppp_oerrors; /* transmit errors */
+};
+
+struct vjstat {
+ unsigned int vjs_packets; /* outbound packets */
+ unsigned int vjs_compressed; /* outbound compressed packets */
+ unsigned int vjs_searches; /* searches for connection state */
+ unsigned int vjs_misses; /* times couldn't find conn. state */
+ unsigned int vjs_uncompressedin; /* inbound uncompressed packets */
+ unsigned int vjs_compressedin; /* inbound compressed packets */
+ unsigned int vjs_errorin; /* inbound unknown type packets */
+ unsigned int vjs_tossed; /* inbound packets tossed because of error */
+};
+
+struct ppp_stats {
+ struct pppstat p; /* basic PPP statistics */
+ struct vjstat vj; /* VJ header compression statistics */
+};
+
+struct compstat {
+ unsigned int unc_bytes; /* total uncompressed bytes */
+ unsigned int unc_packets; /* total uncompressed packets */
+ unsigned int comp_bytes; /* compressed bytes */
+ unsigned int comp_packets; /* compressed packets */
+ unsigned int inc_bytes; /* incompressible bytes */
+ unsigned int inc_packets; /* incompressible packets */
+ unsigned int ratio; /* recent compression ratio << 8 */
+};
+
+struct ppp_comp_stats {
+ struct compstat c; /* packet compression statistics */
+ struct compstat d; /* packet decompression statistics */
+};
+
+/*
+ * The following structure records the time in seconds since
+ * the last NP packet was sent or received.
+ */
+struct ppp_idle {
+ time_t xmit_idle; /* time since last NP packet sent */
+ time_t recv_idle; /* time since last NP packet received */
+};
+
+#ifndef __P
+#ifdef __STDC__
+#define __P(x) x
+#else
+#define __P(x) ()
+#endif
+#endif
+
+#endif /* _PPP_DEFS_H_ */
diff --git a/cpukit/libnetworking/net/ppp_tty.c b/cpukit/libnetworking/net/ppp_tty.c
new file mode 100644
index 0000000000..1ce5542bde
--- /dev/null
+++ b/cpukit/libnetworking/net/ppp_tty.c
@@ -0,0 +1,956 @@
+/*
+ * ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous
+ * tty devices.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ *
+ * Drew D. Perkins
+ * Carnegie Mellon University
+ * 4910 Forbes Ave.
+ * Pittsburgh, PA 15213
+ * (412) 268-8576
+ * ddp@andrew.cmu.edu
+ *
+ * Based on:
+ * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89
+ *
+ * Copyright (c) 1987 Regents of the University of California.
+ * 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 University of California, Berkeley. 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.
+ *
+ * Serial Line interface
+ *
+ * Rick Adams
+ * Center for Seismic Studies
+ * 1300 N 17th Street, Suite 1450
+ * Arlington, Virginia 22209
+ * (703)276-7900
+ * rick@seismo.ARPA
+ * seismo!rick
+ *
+ * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris).
+ * Converted to 4.3BSD Beta by Chris Torek.
+ * Other changes made at Berkeley, based in part on code by Kirk Smith.
+ *
+ * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com)
+ * Added VJ tcp header compression; more unified ioctls
+ *
+ * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au).
+ * Cleaned up a lot of the mbuf-related code to fix bugs that
+ * caused system crashes and packet corruption. Changed pppstart
+ * so that it doesn't just give up with a "collision" if the whole
+ * packet doesn't fit in the output ring buffer.
+ *
+ * Added priority queueing for interactive IP packets, following
+ * the model of if_sl.c, plus hooks for bpf.
+ * Paul Mackerras (paulus@cs.anu.edu.au).
+ */
+
+/* $FreeBSD: src/sys/net/ppp_tty.c,v 1.69 2005/10/16 20:44:18 phk Exp $ */
+/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
+/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
+
+/* $Id$ */
+
+#include "opt_ppp.h" /* XXX for ppp_defs.h */
+
+#if NPPP > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <sys/kernel.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+
+#ifdef VJC
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <net/pppcompress.h>
+#endif
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <sys/ttycom.h>
+#include <termios.h>
+#include <rtems/termiostypes.h>
+
+#ifdef PPP_FILTER
+#include <net/bpf.h>
+#endif
+#include <net/ppp_defs.h>
+#include <net/if_ppp.h>
+#include <net/if_pppvar.h>
+
+
+void pppasyncattach(void);
+int pppopen(struct rtems_termios_tty *tty);
+int pppclose(struct rtems_termios_tty *tty);
+int pppread(struct rtems_termios_tty *tty, rtems_libio_rw_args_t *rw_args);
+int pppwrite(struct rtems_termios_tty *tty, rtems_libio_rw_args_t *rw_args);
+int ppptioctl(struct rtems_termios_tty *tty, rtems_libio_ioctl_args_t *args);
+int pppinput(int c, struct rtems_termios_tty *tty);
+int pppstart(struct rtems_termios_tty *tp);
+u_short pppfcs(u_short fcs, u_char *cp, int len);
+void pppallocmbuf(struct ppp_softc *sc, struct mbuf **mp);
+
+static void pppasyncstart(struct ppp_softc *);
+static void pppasyncctlp(struct ppp_softc *);
+static void pppasyncrelinq(struct ppp_softc *);
+/*static void ppp_timeout __P((void *)); */
+/*static void pppdumpb __P((u_char *b, int l)); */
+/*static void ppplogchar __P((struct ppp_softc *, int)); */
+
+/*
+ * Some useful mbuf macros not in mbuf.h.
+ */
+#define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
+
+#define M_DATASTART(m) \
+ (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \
+ (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
+
+#define M_DATASIZE(m) \
+ (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \
+ (m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
+
+/*
+ * We steal two bits in the mbuf m_flags, to mark high-priority packets
+ * for output, and received packets following lost/corrupted packets.
+ */
+#define M_HIGHPRI 0x2000 /* output packet for sc_fastq */
+#define M_ERRMARK 0x4000 /* steal a bit in mbuf m_flags */
+
+/*
+ * Does c need to be escaped?
+ */
+#define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
+
+/*
+ * Procedures for using an async tty interface for PPP.
+ */
+
+/* This is a FreeBSD-2.0 kernel. */
+#define CCOUNT(rb) (((rb).Size+(rb).Head-(rb).Tail) % (rb).Size)
+#define FCOUNT(rb) ((rb).Size-CCOUNT(rb)-1)
+#define PPP_LOWAT 100 /* Process more output when < LOWAT on queue */
+#define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
+
+/*
+ * Define the PPP line discipline.
+ */
+
+static struct linesw pppdisc = {
+ pppopen, pppclose, pppread, pppwrite,
+ pppinput, pppstart, ppptioctl, NULL
+};
+
+void
+pppasyncattach()
+{
+ linesw[PPPDISC] = pppdisc;
+}
+
+TEXT_SET(pseudo_set, pppasyncattach);
+
+/*
+ * Line specific open routine for async tty devices.
+ * Attach the given tty to the first available ppp unit.
+ * Called from device open routine or ttioctl.
+ */
+/* ARGSUSED */
+int
+pppopen(struct rtems_termios_tty *tty)
+{
+ int i;
+ register struct ppp_softc *sc;
+ struct mbuf *m = (struct mbuf *)0;
+ extern int termios_baud_to_number(int);
+
+ if (tty->t_line == PPPDISC) {
+ sc = (struct ppp_softc *)tty->t_sc;
+ if (sc != NULL && sc->sc_devp == (void *)tty) {
+ return (0);
+ }
+ }
+
+ if ((sc = pppalloc(1)) == NULL) {
+ return ENXIO;
+ }
+
+ if (sc->sc_relinq)
+ (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
+
+ sc->sc_ilen = 0;
+ sc->sc_m = NULL;
+ bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
+ sc->sc_asyncmap[0] = 0xffffffff;
+ sc->sc_asyncmap[3] = 0x60000000;
+ sc->sc_rasyncmap = 0;
+ sc->sc_devp = tty;
+ sc->sc_start = pppasyncstart;
+ sc->sc_ctlp = pppasyncctlp;
+ sc->sc_relinq = pppasyncrelinq;
+ sc->sc_outm = NULL;
+ sc->sc_outmc = NULL;
+
+ /* preallocate mbufs for free queue */
+ rtems_bsdnet_semaphore_obtain();
+ for (i=0; i<NUM_MBUFQ; i++) {
+ pppallocmbuf(sc, &m);
+ if ( i == 0 ) {
+ /* use first mbuf for rx iterrupt handling */
+ sc->sc_m = m;
+ }
+ else {
+ /* enqueue mbuf for later use */
+ IF_ENQUEUE(&sc->sc_freeq, m);
+ }
+ m = (struct mbuf *)0;
+ }
+ rtems_bsdnet_semaphore_release();
+
+ /* initialize values */
+ sc->sc_if.if_flags |= IFF_RUNNING;
+ sc->sc_if.if_baudrate =
+ termios_baud_to_number(tty->termios.c_cflag & CBAUD);
+
+ tty->t_sc = (void *)sc;
+
+ return ( RTEMS_SUCCESSFUL );
+}
+
+/*
+ * Line specific close routine, called from device close routine
+ * and from ttioctl.
+ * Detach the tty from the ppp unit.
+ * Mimics part of ttyclose().
+ */
+int
+pppclose(struct rtems_termios_tty *tty)
+{
+ register struct ppp_softc *sc;
+
+ tty->t_line = 0;
+ sc = (struct ppp_softc *)tty->t_sc;
+ if (sc != NULL) {
+ tty->t_sc = NULL;
+ if (tty == (struct rtems_termios_tty *)sc->sc_devp) {
+ rtems_bsdnet_semaphore_obtain();
+ pppasyncrelinq(sc);
+ pppdealloc(sc);
+ rtems_bsdnet_semaphore_release();
+ }
+ }
+ return ( RTEMS_SUCCESSFUL );
+}
+
+/*
+ * Relinquish the interface unit to another device.
+ */
+static void
+pppasyncrelinq(sc)
+ struct ppp_softc *sc;
+{
+#ifdef XXX_XXX
+ if (sc->sc_outm) {
+ m_freem(sc->sc_outm);
+ sc->sc_outm = NULL;
+ }
+ if (sc->sc_m) {
+ m_freem(sc->sc_m);
+ sc->sc_m = NULL;
+ }
+ if (sc->sc_flags & SC_TIMEOUT) {
+ untimeout(ppp_timeout, (void *) sc);
+ sc->sc_flags &= ~SC_TIMEOUT;
+ }
+#endif
+}
+
+/*
+ * Line specific (tty) read routine.
+ */
+int
+pppread(struct rtems_termios_tty *tty, rtems_libio_rw_args_t *rw_args)
+{
+ rtems_status_code status = RTEMS_UNSATISFIED;
+ int count = 0;
+ int maximum = rw_args->count;
+ char *buffer = rw_args->buffer;
+ register struct ppp_softc *sc = (struct ppp_softc *)tty->t_sc;
+ struct mbuf *m;
+ struct mbuf *m0;
+ u_char *p;
+
+ if (sc == NULL)
+ return 0;
+
+ /*
+ * Loop waiting for input, checking that nothing disasterous
+ * happens in the meantime.
+ */
+ if (tty != (struct rtems_termios_tty *)sc->sc_devp || tty->t_line != PPPDISC) {
+ return ( status );
+ }
+ if (sc->sc_inq.ifq_head == NULL) {
+ return ( status );
+ }
+
+ /* Get the packet from the input queue */
+ rtems_bsdnet_semaphore_obtain();
+ IF_DEQUEUE(&sc->sc_inq, m0);
+
+ /* loop over mbuf chain */
+ m = m0;
+ while (( m != NULL ) && ( m->m_len > 0 ) && ( count+m->m_len < maximum )) {
+ /* copy data into buffer */
+ p = mtod(m, u_char *);
+ memcpy(buffer, p, m->m_len);
+ memset(p, 0, m->m_len);
+ count += m->m_len;
+ buffer += m->m_len;
+
+ /* increment loop index */
+ m = m->m_next;
+ }
+
+ /* free mbuf chain */
+ m_freem(m0);
+ rtems_bsdnet_semaphore_release();
+
+ /* update return values */
+ rw_args->bytes_moved = count;
+ if ( count >= 0 ) {
+ status = RTEMS_SUCCESSFUL;
+ }
+
+ /* check to see if queue is empty */
+ if (sc->sc_inq.ifq_head != NULL) {
+ /* queue is not empty - post another event to ourself */
+ rtems_event_send(sc->sc_pppdtask, PPPD_EVENT);
+ }
+
+ return ( status );
+}
+
+/*
+ * Line specific (tty) write routine.
+ */
+int
+pppwrite(struct rtems_termios_tty *tty, rtems_libio_rw_args_t *rw_args)
+{
+ struct sockaddr dst;
+ int n;
+ int len;
+ int maximum = rw_args->count;
+ char *out_buffer = rw_args->buffer;
+ register struct ppp_softc *sc = (struct ppp_softc *)tty->t_sc;
+ struct mbuf *m;
+ struct mbuf *m0;
+ struct mbuf **mp;
+
+ rtems_bsdnet_semaphore_obtain();
+ for (mp = &m0; maximum; mp = &m->m_next) {
+ MGET(m, M_WAIT, MT_DATA);
+ if ((*mp = m) == NULL) {
+ m_freem(m0);
+ return (ENOBUFS);
+ }
+ m->m_len = 0;
+ if (maximum >= MCLBYTES / 2) {
+ MCLGET(m, M_DONTWAIT);
+ }
+ len = M_TRAILINGSPACE(m);
+ if (len > maximum) {
+ memcpy(mtod(m, u_char *),out_buffer,maximum);
+ m->m_len = maximum;
+ maximum = 0;
+ }
+ else {
+ memcpy(mtod(m, u_char *),out_buffer,len);
+ m->m_len = len;
+ maximum -= len;
+ out_buffer += len;
+ }
+ }
+
+ dst.sa_family = AF_UNSPEC;
+ bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
+ m0->m_data += PPP_HDRLEN;
+ m0->m_len -= PPP_HDRLEN;
+
+ n = pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0);
+ rtems_bsdnet_semaphore_release();
+
+ return ( n );
+}
+
+/*
+ * Line specific (tty) ioctl routine.
+ * This discipline requires that tty device drivers call
+ * the line specific l_ioctl routine from their ioctl routines.
+ */
+/* ARGSUSED */
+int
+ppptioctl(struct rtems_termios_tty *tty, rtems_libio_ioctl_args_t *args)
+{
+/* int i; */
+ int error = RTEMS_SUCCESSFUL;
+ int cmd = args->command;
+ caddr_t data = args->buffer;
+ struct ppp_softc *sc = tty->t_sc;
+
+ switch (cmd) {
+ case RTEMS_IO_GET_ATTRIBUTES:
+ case RTEMS_IO_SET_ATTRIBUTES:
+ case RTEMS_IO_TCDRAIN:
+ case RTEMS_IO_SNDWAKEUP:
+ case RTEMS_IO_RCVWAKEUP:
+ case TIOCGETD:
+ case TIOCSETD:
+ error = rtems_termios_ioctl(args);
+ break;
+
+ case PPPIOCSASYNCMAP:
+ sc->sc_asyncmap[0] = *(u_int *)data;
+ break;
+
+ case PPPIOCGASYNCMAP:
+ *(u_int *)data = sc->sc_asyncmap[0];
+ break;
+
+ case PPPIOCSRASYNCMAP:
+ sc->sc_rasyncmap = *(u_int *)data;
+ break;
+
+ case PPPIOCGRASYNCMAP:
+ *(u_int *)data = sc->sc_rasyncmap;
+ break;
+
+ case PPPIOCSXASYNCMAP:
+ bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
+ sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
+ sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
+ sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
+ break;
+
+ case PPPIOCGXASYNCMAP:
+ bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
+ break;
+
+ default:
+ rtems_bsdnet_semaphore_obtain();
+ error = pppioctl(sc, cmd, data, 0, NULL);
+ rtems_bsdnet_semaphore_release();
+ }
+ return error;
+}
+
+/*
+ * FCS lookup table as calculated by genfcstab.
+ */
+static u_short fcstab[256] = {
+ 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+ 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+ 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+ 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+ 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+ 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+ 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+ 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+ 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+ 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+ 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+ 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+ 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+ 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+ 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+ 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+ 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+ 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+ 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+ 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+ 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+ 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+ 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+ 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+ 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+ 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+ 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+ 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+ 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+ 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+ 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+ 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+/*
+ * Calculate a new FCS given the current FCS and the new data.
+ */
+u_short
+pppfcs(u_short fcs, u_char *cp, int len)
+{
+ while (len--)
+ fcs = PPP_FCS(fcs, *cp++);
+ return (fcs);
+}
+
+/*
+ * This gets called at splsoftnet from if_ppp.c at various times
+ * when there is data ready to be sent.
+ */
+void pppasyncstart(struct ppp_softc *sc)
+{
+ /* check to see if output is not active */
+ if ( sc->sc_outflag == 0 ) {
+ /* mark active and post tx event to daemon */
+ sc->sc_outflag |= SC_TX_PENDING;
+ rtems_event_send(sc->sc_txtask, TX_PACKET);
+ }
+}
+
+/*
+ * This gets called when a received packet is placed on
+ * the inq, at splsoftnet.
+ */
+static void
+pppasyncctlp(sc)
+ struct ppp_softc *sc;
+{
+ /* check to see if task id was set */
+ if ( sc->sc_pppdtask != 0 ) {
+ /* post event to daemon */
+ rtems_event_send(sc->sc_pppdtask, PPPD_EVENT);
+ }
+}
+
+/*
+ * Start output on async tty interface. If the transmit queue
+ * has drained sufficiently, arrange for pppasyncstart to be
+ * called later at splsoftnet.
+ * Called at spltty or higher.
+ */
+int
+pppstart(struct rtems_termios_tty *tp)
+{
+ u_char *sendBegin;
+ u_long ioffset = (u_long )0;
+ struct mbuf *m = (struct mbuf *)0;
+ struct ppp_softc *sc = tp->t_sc;
+
+ /* ensure input is valid and we are busy */
+ if (( sc != NULL ) && ( sc->sc_outflag & SC_TX_BUSY )) {
+ /* check to see if we need to get the next buffer */
+
+ /* Ready with PPP_FLAG Character ? */
+ if(sc->sc_outflag & SC_TX_LASTCHAR){
+ sc->sc_outflag &= ~(SC_TX_BUSY | SC_TX_FCS | SC_TX_LASTCHAR);
+ rtems_event_send(sc->sc_txtask, TX_TRANSMIT); /* Ready for the next Packet */
+ return(0);
+ }
+
+ if ( sc->sc_outoff >= sc->sc_outlen ) {
+ /* loop to get next non-zero length buffer */
+ if ( sc->sc_outmc != NULL ) {
+ m = sc->sc_outmc->m_next;
+ }
+
+ /* check for next mbuf in chain */
+ if ( m != NULL ) {
+ /* update values to use this mbuf */
+ sc->sc_outmc = m;
+ sc->sc_outbuf = mtod(m, u_char *);
+ sc->sc_outlen = m->m_len;
+ sc->sc_outoff = (short)0;
+ }
+ else if ( (sc->sc_outflag & SC_TX_FCS) == 0 ) {
+ /* setup to use FCS buffer */
+ sc->sc_outflag |= SC_TX_FCS;
+ sc->sc_outbuf = sc->sc_outfcsbuf;
+ sc->sc_outlen = sc->sc_outfcslen;
+ sc->sc_outoff = (short)0;
+ }
+ else {
+ /* done with this packet */
+ sc->sc_outflag |= SC_TX_LASTCHAR;
+ sc->sc_outflag &=~(SC_TX_FCS);
+ sc->sc_outchar = (u_char)PPP_FLAG;
+ (*tp->device.write)(tp->minor, (char *)&sc->sc_outchar, 1);
+ return(0);
+ }
+ }
+
+ /* check to see if there is some data to write out */
+ if ( sc->sc_outoff < sc->sc_outlen ) {
+ /* check to see if character needs to be escaped */
+ sc->sc_outchar = sc->sc_outbuf[sc->sc_outoff];
+ if ( ESCAPE_P(sc->sc_outchar) ) {
+ if ( sc->sc_outflag & SC_TX_ESCAPE ) {
+ /* last sent character was the escape character */
+ sc->sc_outchar = sc->sc_outchar ^ PPP_TRANS;
+
+ /* clear the escape flag and increment the offset */
+ sc->sc_outflag &= ~SC_TX_ESCAPE;
+ ioffset++;
+ }
+ else {
+ /* need to send the escape character */
+ sc->sc_outchar = PPP_ESCAPE;
+
+ /* set the escape flag */
+ sc->sc_outflag |= SC_TX_ESCAPE;
+ }
+ sendBegin = &sc->sc_outchar;
+ }
+ else {
+ /* escape not needed - increment the offset as much as possible */
+ while ((!ESCAPE_P(sc->sc_outchar)) && ((sc->sc_outoff + ioffset) < sc->sc_outlen)) {
+ ioffset++;
+ sc->sc_outchar = sc->sc_outbuf[sc->sc_outoff + ioffset];
+ }
+ sendBegin = &sc->sc_outbuf[sc->sc_outoff];
+ }
+
+ /* write out the character(s) and update the stats */
+ (*tp->device.write)(tp->minor, (char *)sendBegin, (ioffset > 0) ? ioffset : 1);
+ sc->sc_stats.ppp_obytes += (ioffset > 0) ? ioffset : 1;
+ sc->sc_outoff += ioffset;
+ }
+ }
+
+ return ( 0 );
+}
+
+#ifdef XXX_XXX
+/*
+ * Timeout routine - try to start some more output.
+ */
+static void
+ppp_timeout(x)
+ void *x;
+{
+ struct rtems_termios_tty *tty = (struct rtems_termios_tty *)x;
+ struct ppp_softc *sc = tty->t_sc;
+/* struct rtems_termios_tty *tp = (struct rtems_termios_tty *)sc->sc_devp; */
+
+ sc->sc_flags &= ~SC_TIMEOUT;
+/* pppstart(tp); */
+}
+#endif
+
+/*
+ * Allocate enough mbuf to handle current MRU.
+ */
+#ifdef XXX_XXX
+static void
+pppgetm(sc)
+ register struct ppp_softc *sc;
+{
+ struct mbuf *m, **mp;
+ int len;
+
+ mp = &sc->sc_m;
+ for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
+ if ((m = *mp) == NULL) {
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL)
+ break;
+ *mp = m;
+ MCLGET(m, M_DONTWAIT);
+ }
+ len -= M_DATASIZE(m);
+ mp = &m->m_next;
+ }
+}
+#endif
+
+void
+pppallocmbuf(struct ppp_softc *sc, struct mbuf **mp)
+{
+ int ilen;
+ struct mbuf *m;
+
+ /* loop over length value */
+ ilen = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN;
+ while ( ilen > 0 ) {
+ /* see if this is end of the chain */
+ m = *mp;
+ if ( m == NULL ) {
+ /* get mbuf header */
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if ( m == NULL ) {
+ /* error - set condition to break out */
+ printf("pppallocmbuf: MGETHDR failed\n");
+ break;
+ }
+ MCLGET(m, M_DONTWAIT);
+ m->m_next = NULL;
+ *mp = m;
+ }
+
+ /* update loop variables */
+ mp = &m->m_next;
+ ilen -= M_DATASIZE(m);
+ }
+}
+
+/*
+ * tty interface receiver interrupt.
+ */
+static unsigned paritytab[8] = {
+ 0x96696996, 0x69969669, 0x69969669, 0x96696996,
+ 0x69969669, 0x96696996, 0x96696996, 0x69969669
+};
+
+int
+pppinput(int c, struct rtems_termios_tty *tp)
+{
+ register struct ppp_softc *sc = tp->t_sc;
+ struct mbuf *m;
+ int ilen;
+
+ if (sc == NULL || tp != (struct rtems_termios_tty *)sc->sc_devp)
+ return 0;
+ if (sc->sc_m == NULL) {
+ rtems_event_send(sc->sc_rxtask, RX_EMPTY);
+ IF_DEQUEUE(&sc->sc_freeq, sc->sc_m);
+ if ( sc->sc_m == NULL ) {
+ return 0;
+ }
+ }
+
+ ++sc->sc_stats.ppp_ibytes;
+
+ c &= 0xff;
+ if (c & 0x80)
+ sc->sc_flags |= SC_RCV_B7_1;
+ else
+ sc->sc_flags |= SC_RCV_B7_0;
+ if (paritytab[c >> 5] & (1 << (c & 0x1F)))
+ sc->sc_flags |= SC_RCV_ODDP;
+ else
+ sc->sc_flags |= SC_RCV_EVNP;
+
+ if (c == PPP_FLAG) {
+ ilen = sc->sc_ilen;
+ sc->sc_ilen = 0;
+
+ /*
+ * If SC_ESCAPED is set, then we've seen the packet
+ * abort sequence "}~".
+ */
+ if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
+ || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) {
+ sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
+ if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
+ /* bad fcs error */
+ sc->sc_if.if_ierrors++;
+ sc->sc_stats.ppp_ierrors++;
+ } else
+ sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
+ return 0;
+ }
+
+ if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
+ if (ilen) {
+ /* too short error */
+ sc->sc_if.if_ierrors++;
+ sc->sc_stats.ppp_ierrors++;
+ sc->sc_flags |= SC_PKTLOST;
+ }
+ return 0;
+ }
+
+ /* Remove FCS trailer. Somewhat painful... */
+ ilen -= 2;
+ if (--sc->sc_mc->m_len == 0) {
+ for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next);
+ sc->sc_mc = m;
+ }
+ sc->sc_mc->m_len--;
+
+ /* excise this mbuf chain - place on raw queue */
+ m = sc->sc_m;
+ if ( sc->sc_flags & SC_PKTLOST ) {
+ m->m_flags |= M_ERRMARK;
+ sc->sc_flags &= ~SC_PKTLOST;
+ }
+ IF_ENQUEUE(&sc->sc_rawq, m);
+
+ /* setup next mbuf chain */
+ IF_DEQUEUE(&sc->sc_freeq, sc->sc_m);
+
+ /* send rx packet event */
+ rtems_event_send(sc->sc_rxtask, RX_PACKET);
+ return 0;
+ }
+
+ if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
+ return 0;
+
+ if (sc->sc_flags & SC_ESCAPED) {
+ sc->sc_flags &= ~SC_ESCAPED;
+ c ^= PPP_TRANS;
+ } else if (c == PPP_ESCAPE) {
+ sc->sc_flags |= SC_ESCAPED;
+ return 0;
+ }
+
+ /*
+ * Initialize buffer on first octet received.
+ * First octet could be address or protocol (when compressing
+ * address/control).
+ * Second octet is control.
+ * Third octet is first or second (when compressing protocol)
+ * octet of protocol.
+ * Fourth octet is second octet of protocol.
+ */
+ if (sc->sc_ilen == 0) {
+ m = sc->sc_m;
+ m->m_len = 0;
+ m->m_data = M_DATASTART(sc->sc_m);
+ sc->sc_mc = m;
+ sc->sc_mp = mtod(m, char *);
+ sc->sc_fcs = PPP_INITFCS;
+ if (c != PPP_ALLSTATIONS) {
+ if (sc->sc_flags & SC_REJ_COMP_AC) {
+ /* garbage received error */
+ goto flush;
+ }
+ *sc->sc_mp++ = PPP_ALLSTATIONS;
+ *sc->sc_mp++ = PPP_UI;
+ sc->sc_ilen += 2;
+ m->m_len += 2;
+ }
+ }
+ if (sc->sc_ilen == 1 && c != PPP_UI) {
+ /* missing UI error */
+ goto flush;
+ }
+ if (sc->sc_ilen == 2 && (c & 1) == 1) {
+ /* a compressed protocol */
+ *sc->sc_mp++ = 0;
+ sc->sc_ilen++;
+ sc->sc_mc->m_len++;
+ }
+ if (sc->sc_ilen == 3 && (c & 1) == 0) {
+ /* bad protocol error */
+ goto flush;
+ }
+
+ /* packet beyond configured mru? */
+ if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
+ /* packet too big error */
+ goto flush;
+ }
+
+ /* is this mbuf full? */
+ m = sc->sc_mc;
+ if (M_TRAILINGSPACE(m) <= 0) {
+ if (m->m_next == NULL) {
+ /* get next available mbuf for the chain */
+ IF_DEQUEUE(&sc->sc_freeq, m->m_next);
+ if (m->m_next == NULL) {
+ /* too few mbufs */
+ goto flush;
+ }
+ else {
+ /* send rx mbuf event */
+ rtems_event_send(sc->sc_rxtask, RX_MBUF);
+ }
+ }
+ sc->sc_mc = m = m->m_next;
+ m->m_len = 0;
+ m->m_next = 0;
+ m->m_data = M_DATASTART(m);
+ sc->sc_mp = mtod(m, char *);
+ }
+
+ ++m->m_len;
+ *sc->sc_mp++ = c;
+ sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
+ return 0;
+
+ flush:
+ if (!(sc->sc_flags & SC_FLUSH)) {
+ sc->sc_if.if_ierrors++;
+ sc->sc_stats.ppp_ierrors++;
+ sc->sc_flags |= SC_FLUSH;
+ }
+ return 0;
+}
+
+#ifdef XXX_XXX
+#define MAX_DUMP_BYTES 128
+
+static void
+ppplogchar(sc, c)
+ struct ppp_softc *sc;
+ int c;
+{
+ if (c >= 0)
+ sc->sc_rawin[sc->sc_rawin_count++] = c;
+ if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
+ || (c < 0 && sc->sc_rawin_count > 0)) {
+ printf("ppp%d input: ", sc->sc_if.if_unit);
+ pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
+ sc->sc_rawin_count = 0;
+ }
+}
+
+static void
+pppdumpb(b, l)
+ u_char *b;
+ int l;
+{
+ char buf[3*MAX_DUMP_BYTES+4];
+ char *bp = buf;
+ static char digits[] = "0123456789abcdef";
+
+ while (l--) {
+ if (bp >= buf + sizeof(buf) - 3) {
+ *bp++ = '>';
+ break;
+ }
+ *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
+ *bp++ = digits[*b++ & 0xf];
+ *bp++ = ' ';
+ }
+
+ *bp = 0;
+ printf("%s\n", buf);
+}
+#endif
+
+#endif /* NPPP > 0 */
diff --git a/cpukit/libnetworking/net/pppcompress.c b/cpukit/libnetworking/net/pppcompress.c
new file mode 100644
index 0000000000..b87c662c18
--- /dev/null
+++ b/cpukit/libnetworking/net/pppcompress.c
@@ -0,0 +1,594 @@
+/*-
+ * Copyright (c) 1989 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.
+ *
+ * @(#)slcompress.c 7.7 (Berkeley) 5/7/91
+ */
+
+/*
+ * Routines to compress and uncompess tcp packets (for transmission
+ * over low speed serial lines.
+ *
+ * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
+ * - Initial distribution.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include <net/pppcompress.h>
+
+#ifndef SL_NO_STATS
+#define INCR(counter) ++comp->counter;
+#else
+#define INCR(counter)
+#endif
+
+#define BCMP(p1, p2, n) bcmp((char *)(p1), (char *)(p2), (int)(n))
+#define BCOPY(p1, p2, n) bcopy((char *)(p1), (char *)(p2), (int)(n))
+#ifndef _KERNEL
+#define ovbcopy bcopy
+#endif
+
+void
+vj_compress_init(comp, max_state)
+ struct vjcompress *comp;
+ int max_state;
+{
+ register u_int i;
+ register struct cstate *tstate = comp->tstate;
+
+ if ((unsigned) max_state > MAX_STATES - 1)
+ max_state = MAX_STATES - 1;
+ bzero((char *)comp, sizeof(*comp));
+ for (i = max_state; i > 0; --i) {
+ tstate[i].cs_id = i;
+ tstate[i].cs_next = &tstate[i - 1];
+ }
+ tstate[0].cs_next = &tstate[max_state];
+ tstate[0].cs_id = 0;
+ comp->last_cs = &tstate[0];
+ comp->last_recv = 255;
+ comp->last_xmit = 255;
+ comp->flags = SLF_TOSS;
+}
+
+
+/* ENCODE encodes a number that is known to be non-zero. ENCODEZ
+ * checks for zero (since zero has to be encoded in the long, 3 byte
+ * form).
+ */
+#define ENCODE(n) { \
+ if ((u_short)(n) >= 256) { \
+ *cp++ = 0; \
+ cp[1] = (n); \
+ cp[0] = (n) >> 8; \
+ cp += 2; \
+ } else { \
+ *cp++ = (n); \
+ } \
+}
+#define ENCODEZ(n) { \
+ if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
+ *cp++ = 0; \
+ cp[1] = (n); \
+ cp[0] = (n) >> 8; \
+ cp += 2; \
+ } else { \
+ *cp++ = (n); \
+ } \
+}
+
+#define DECODEL(f) { \
+ if (*cp == 0) {\
+ (f) = htonl(ntohl(f) + ((cp[1] << 8) | cp[2])); \
+ cp += 3; \
+ } else { \
+ (f) = htonl(ntohl(f) + (u_long)*cp++); \
+ } \
+}
+
+#define DECODES(f) { \
+ if (*cp == 0) {\
+ (f) = htons(ntohs(f) + ((cp[1] << 8) | cp[2])); \
+ cp += 3; \
+ } else { \
+ (f) = htons(ntohs(f) + (u_long)*cp++); \
+ } \
+}
+
+#define DECODEU(f) { \
+ if (*cp == 0) {\
+ (f) = htons((cp[1] << 8) | cp[2]); \
+ cp += 3; \
+ } else { \
+ (f) = htons((u_long)*cp++); \
+ } \
+}
+
+u_int
+vj_compress_tcp(m, ip, comp, compress_cid)
+ struct mbuf *m;
+ register struct ip *ip;
+ struct vjcompress *comp;
+ int compress_cid;
+{
+ register struct cstate *cs = comp->last_cs->cs_next;
+ register u_int hlen = ip->ip_hl;
+ register struct tcphdr *oth;
+ register struct tcphdr *th;
+ register u_int deltaS, deltaA;
+ register u_int changes = 0;
+ u_char new_seq[16];
+ register u_char *cp = new_seq;
+
+ /*
+ * Bail if this is an IP fragment or if the TCP packet isn't
+ * `compressible' (i.e., ACK isn't set or some other control bit is
+ * set). (We assume that the caller has already made sure the
+ * packet is IP proto TCP).
+ */
+ if ((ip->ip_off & htons(0x3fff)) || m->m_len < 40)
+ return (TYPE_IP);
+
+ th = (struct tcphdr *)&((int *)ip)[hlen];
+ if ((th->th_flags & (TH_SYN|TH_FIN|TH_RST|TH_ACK)) != TH_ACK)
+ return (TYPE_IP);
+ /*
+ * Packet is compressible -- we're going to send either a
+ * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need
+ * to locate (or create) the connection state. Special case the
+ * most recently used connection since it's most likely to be used
+ * again & we don't have to do any reordering if it's used.
+ */
+ INCR(sls_packets)
+ if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr ||
+ ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr ||
+ *(int *)th != ((int *)&cs->cs_ip)[cs->cs_ip.ip_hl]) {
+ /*
+ * Wasn't the first -- search for it.
+ *
+ * States are kept in a circularly linked list with
+ * last_cs pointing to the end of the list. The
+ * list is kept in lru order by moving a state to the
+ * head of the list whenever it is referenced. Since
+ * the list is short and, empirically, the connection
+ * we want is almost always near the front, we locate
+ * states via linear search. If we don't find a state
+ * for the datagram, the oldest state is (re-)used.
+ */
+ register struct cstate *lcs;
+ register struct cstate *lastcs = comp->last_cs;
+
+ do {
+ lcs = cs; cs = cs->cs_next;
+ INCR(sls_searches)
+ if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr
+ && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr
+ && *(int *)th == ((int *)&cs->cs_ip)[cs->cs_ip.ip_hl])
+ goto found;
+ } while (cs != lastcs);
+
+ /*
+ * Didn't find it -- re-use oldest cstate. Send an
+ * uncompressed packet that tells the other side what
+ * connection number we're using for this conversation.
+ * Note that since the state list is circular, the oldest
+ * state points to the newest and we only need to set
+ * last_cs to update the lru linkage.
+ */
+ INCR(sls_misses)
+ comp->last_cs = lcs;
+ hlen += th->th_off;
+ hlen <<= 2;
+ goto uncompressed;
+
+ found:
+ /*
+ * Found it -- move to the front on the connection list.
+ */
+ if (cs == lastcs)
+ comp->last_cs = lcs;
+ else {
+ lcs->cs_next = cs->cs_next;
+ cs->cs_next = lastcs->cs_next;
+ lastcs->cs_next = cs;
+ }
+ }
+
+ /*
+ * Make sure that only what we expect to change changed. The first
+ * line of the `if' checks the IP protocol version, header length &
+ * type of service. The 2nd line checks the "Don't fragment" bit.
+ * The 3rd line checks the time-to-live and protocol (the protocol
+ * check is unnecessary but costless). The 4th line checks the TCP
+ * header length. The 5th line checks IP options, if any. The 6th
+ * line checks TCP options, if any. If any of these things are
+ * different between the previous & current datagram, we send the
+ * current datagram `uncompressed'.
+ */
+ oth = (struct tcphdr *)&((int *)&cs->cs_ip)[hlen];
+ deltaS = hlen;
+ hlen += th->th_off;
+ hlen <<= 2;
+
+ if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] ||
+ ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] ||
+ ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] ||
+ th->th_off != oth->th_off ||
+ (deltaS > 5 &&
+ BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) ||
+ (th->th_off > 5 &&
+ BCMP(th + 1, oth + 1, (th->th_off - 5) << 2)))
+ goto uncompressed;
+
+ /*
+ * Figure out which of the changing fields changed. The
+ * receiver expects changes in the order: urgent, window,
+ * ack, seq (the order minimizes the number of temporaries
+ * needed in this section of code).
+ */
+ if (th->th_flags & TH_URG) {
+ deltaS = ntohs(th->th_urp);
+ ENCODEZ(deltaS);
+ changes |= NEW_U;
+ } else if (th->th_urp != oth->th_urp)
+ /* argh! URG not set but urp changed -- a sensible
+ * implementation should never do this but RFC793
+ * doesn't prohibit the change so we have to deal
+ * with it. */
+ goto uncompressed;
+
+ if ((deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win)))) {
+ ENCODE(deltaS);
+ changes |= NEW_W;
+ }
+
+ if ((deltaA = ntohl(th->th_ack) - ntohl(oth->th_ack))) {
+ if (deltaA > 0xffff)
+ goto uncompressed;
+ ENCODE(deltaA);
+ changes |= NEW_A;
+ }
+
+ if ((deltaS = ntohl(th->th_seq) - ntohl(oth->th_seq))) {
+ if (deltaS > 0xffff)
+ goto uncompressed;
+ ENCODE(deltaS);
+ changes |= NEW_S;
+ }
+
+ switch(changes) {
+
+ case 0:
+ /*
+ * Nothing changed. If this packet contains data and the
+ * last one didn't, this is probably a data packet following
+ * an ack (normal on an interactive connection) and we send
+ * it compressed. Otherwise it's probably a retransmit,
+ * retransmitted ack or window probe. Send it uncompressed
+ * in case the other side missed the compressed version.
+ */
+ if (ip->ip_len != cs->cs_ip.ip_len &&
+ ntohs(cs->cs_ip.ip_len) == hlen)
+ break;
+
+ /* (fall through) */
+
+ case SPECIAL_I:
+ case SPECIAL_D:
+ /*
+ * actual changes match one of our special case encodings --
+ * send packet uncompressed.
+ */
+ goto uncompressed;
+
+ case NEW_S|NEW_A:
+ if (deltaS == deltaA &&
+ deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
+ /* special case for echoed terminal traffic */
+ changes = SPECIAL_I;
+ cp = new_seq;
+ }
+ break;
+
+ case NEW_S:
+ if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
+ /* special case for data xfer */
+ changes = SPECIAL_D;
+ cp = new_seq;
+ }
+ break;
+ }
+
+ deltaS = ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id);
+ if (deltaS != 1) {
+ ENCODEZ(deltaS);
+ changes |= NEW_I;
+ }
+ if (th->th_flags & TH_PUSH)
+ changes |= TCP_PUSH_BIT;
+ /*
+ * Grab the cksum before we overwrite it below. Then update our
+ * state with this packet's header.
+ */
+ deltaA = ntohs(th->th_sum);
+ BCOPY(ip, &cs->cs_ip, hlen);
+
+ /*
+ * We want to use the original packet as our compressed packet.
+ * (cp - new_seq) is the number of bytes we need for compressed
+ * sequence numbers. In addition we need one byte for the change
+ * mask, one for the connection id and two for the tcp checksum.
+ * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how
+ * many bytes of the original packet to toss so subtract the two to
+ * get the new packet size.
+ */
+ deltaS = cp - new_seq;
+ cp = (u_char *)ip;
+ if (compress_cid == 0 || comp->last_xmit != cs->cs_id) {
+ comp->last_xmit = cs->cs_id;
+ hlen -= deltaS + 4;
+ cp += hlen;
+ *cp++ = changes | NEW_C;
+ *cp++ = cs->cs_id;
+ } else {
+ hlen -= deltaS + 3;
+ cp += hlen;
+ *cp++ = changes;
+ }
+ m->m_len -= hlen;
+ m->m_data += hlen;
+ *cp++ = deltaA >> 8;
+ *cp++ = deltaA;
+ BCOPY(new_seq, cp, deltaS);
+ INCR(sls_compressed)
+ return (TYPE_COMPRESSED_TCP);
+
+ /*
+ * Update connection state cs & send uncompressed packet ('uncompressed'
+ * means a regular ip/tcp packet but with the 'conversation id' we hope
+ * to use on future compressed packets in the protocol field).
+ */
+uncompressed:
+ BCOPY(ip, &cs->cs_ip, hlen);
+ ip->ip_p = cs->cs_id;
+ comp->last_xmit = cs->cs_id;
+ return (TYPE_UNCOMPRESSED_TCP);
+}
+
+
+int
+vj_uncompress_tcp(bufp, len, type, comp)
+ u_char **bufp;
+ int len;
+ u_int type;
+ struct vjcompress *comp;
+{
+ u_char *hdr, *cp;
+ u_int hlen;
+ int vjlen;
+
+ cp = bufp? *bufp: NULL;
+ vjlen = vj_uncompress_tcp_core(cp, len, len, type, comp, &hdr, &hlen);
+ if (vjlen < 0)
+ return (0); /* error */
+ if (vjlen == 0)
+ return (len); /* was uncompressed already */
+
+ cp += vjlen;
+ len -= vjlen;
+
+ /*
+ * At this point, cp points to the first byte of data in the
+ * packet. If we're not aligned on a 4-byte boundary, copy the
+ * data down so the ip & tcp headers will be aligned. Then back up
+ * cp by the tcp/ip header length to make room for the reconstructed
+ * header (we assume the packet we were handed has enough space to
+ * prepend 128 bytes of header).
+ */
+ if ((int)cp & 3) {
+ if (len > 0)
+ (void) ovbcopy(cp, (caddr_t)((int)cp &~ 3), len);
+ cp = (u_char *)((int)cp &~ 3);
+ }
+ cp -= hlen;
+ len += hlen;
+ BCOPY(hdr, cp, hlen);
+
+ *bufp = cp;
+ return (len);
+}
+
+/*
+ * Uncompress a packet of total length total_len. The first buflen
+ * bytes are at buf; this must include the entire (compressed or
+ * uncompressed) TCP/IP header. This procedure returns the length
+ * of the VJ header, with a pointer to the uncompressed IP header
+ * in *hdrp and its length in *hlenp.
+ */
+int
+vj_uncompress_tcp_core(buf, buflen, total_len, type, comp, hdrp, hlenp)
+ u_char *buf;
+ int buflen, total_len;
+ u_int type;
+ struct vjcompress *comp;
+ u_char **hdrp;
+ u_int *hlenp;
+{
+ register u_char *cp;
+ register u_int hlen, changes;
+ register struct tcphdr *th;
+ register struct cstate *cs;
+ register struct ip *ip;
+ register u_short *bp;
+ register u_int vjlen;
+
+ switch (type) {
+
+ case TYPE_UNCOMPRESSED_TCP:
+ ip = (struct ip *) buf;
+ if (ip->ip_p >= MAX_STATES)
+ goto bad;
+ cs = &comp->rstate[comp->last_recv = ip->ip_p];
+ comp->flags &=~ SLF_TOSS;
+ ip->ip_p = IPPROTO_TCP;
+ /*
+ * Calculate the size of the TCP/IP header and make sure that
+ * we don't overflow the space we have available for it.
+ */
+ hlen = ip->ip_hl << 2;
+ if (hlen + sizeof(struct tcphdr) > buflen)
+ goto bad;
+ hlen += ((struct tcphdr *)&((char *)ip)[hlen])->th_off << 2;
+ if (hlen > MAX_HDR || hlen > buflen)
+ goto bad;
+ BCOPY(ip, &cs->cs_ip, hlen);
+ cs->cs_hlen = hlen;
+ INCR(sls_uncompressedin)
+ *hdrp = (u_char *) &cs->cs_ip;
+ *hlenp = hlen;
+ return (0);
+
+ default:
+ goto bad;
+
+ case TYPE_COMPRESSED_TCP:
+ break;
+ }
+ /* We've got a compressed packet. */
+ INCR(sls_compressedin)
+ cp = buf;
+ changes = *cp++;
+ if (changes & NEW_C) {
+ /* Make sure the state index is in range, then grab the state.
+ * If we have a good state index, clear the 'discard' flag. */
+ if (*cp >= MAX_STATES)
+ goto bad;
+
+ comp->flags &=~ SLF_TOSS;
+ comp->last_recv = *cp++;
+ } else {
+ /* this packet has an implicit state index. If we've
+ * had a line error since the last time we got an
+ * explicit state index, we have to toss the packet. */
+ if (comp->flags & SLF_TOSS) {
+ INCR(sls_tossed)
+ return (-1);
+ }
+ }
+ cs = &comp->rstate[comp->last_recv];
+ hlen = cs->cs_ip.ip_hl << 2;
+ th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen];
+ th->th_sum = htons((*cp << 8) | cp[1]);
+ cp += 2;
+ if (changes & TCP_PUSH_BIT)
+ th->th_flags |= TH_PUSH;
+ else
+ th->th_flags &=~ TH_PUSH;
+
+ switch (changes & SPECIALS_MASK) {
+ case SPECIAL_I:
+ {
+ register u_int i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
+ th->th_ack = htonl(ntohl(th->th_ack) + i);
+ th->th_seq = htonl(ntohl(th->th_seq) + i);
+ }
+ break;
+
+ case SPECIAL_D:
+ th->th_seq = htonl(ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len)
+ - cs->cs_hlen);
+ break;
+
+ default:
+ if (changes & NEW_U) {
+ th->th_flags |= TH_URG;
+ DECODEU(th->th_urp)
+ } else
+ th->th_flags &=~ TH_URG;
+ if (changes & NEW_W)
+ DECODES(th->th_win)
+ if (changes & NEW_A)
+ DECODEL(th->th_ack)
+ if (changes & NEW_S)
+ DECODEL(th->th_seq)
+ break;
+ }
+ if (changes & NEW_I) {
+ DECODES(cs->cs_ip.ip_id)
+ } else
+ cs->cs_ip.ip_id = htons(ntohs(cs->cs_ip.ip_id) + 1);
+
+ /*
+ * At this point, cp points to the first byte of data in the
+ * packet. Fill in the IP total length and update the IP
+ * header checksum.
+ */
+ vjlen = cp - buf;
+ buflen -= vjlen;
+ if (buflen < 0)
+ /* we must have dropped some characters (crc should detect
+ * this but the old slip framing won't) */
+ goto bad;
+
+ total_len += cs->cs_hlen - vjlen;
+ cs->cs_ip.ip_len = htons(total_len);
+
+ /* recompute the ip header checksum */
+ bp = (u_short *) &cs->cs_ip;
+ cs->cs_ip.ip_sum = 0;
+ for (changes = 0; hlen > 0; hlen -= 2)
+ changes += *bp++;
+ changes = (changes & 0xffff) + (changes >> 16);
+ changes = (changes & 0xffff) + (changes >> 16);
+ cs->cs_ip.ip_sum = ~ changes;
+
+ *hdrp = (u_char *) &cs->cs_ip;
+ *hlenp = cs->cs_hlen;
+ return vjlen;
+
+bad:
+ comp->flags |= SLF_TOSS;
+ INCR(sls_errorin)
+ return (-1);
+}
diff --git a/cpukit/libnetworking/net/pppcompress.h b/cpukit/libnetworking/net/pppcompress.h
new file mode 100644
index 0000000000..3f7687e6bb
--- /dev/null
+++ b/cpukit/libnetworking/net/pppcompress.h
@@ -0,0 +1,164 @@
+/*
+ * Definitions for tcp compression routines.
+ *
+ * Copyright (c) 1989 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.
+ *
+ * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
+ * - Initial distribution.
+ *
+ * From: slcompress.h 7.4 90/06/28
+ * $Id$
+ */
+
+#ifndef _NET_PPPCOMPRESS_H_
+#define _NET_PPPCOMPRESS_H_
+
+#define MAX_STATES 16 /* must be > 2 and < 256 */
+#define MAX_HDR MLEN /* XXX 4bsd-ism: should really be 128 */
+
+/*
+ * Compressed packet format:
+ *
+ * The first octet contains the packet type (top 3 bits), TCP
+ * 'push' bit, and flags that indicate which of the 4 TCP sequence
+ * numbers have changed (bottom 5 bits). The next octet is a
+ * conversation number that associates a saved IP/TCP header with
+ * the compressed packet. The next two octets are the TCP checksum
+ * from the original datagram. The next 0 to 15 octets are
+ * sequence number changes, one change per bit set in the header
+ * (there may be no changes and there are two special cases where
+ * the receiver implicitly knows what changed -- see below).
+ *
+ * There are 5 numbers which can change (they are always inserted
+ * in the following order): TCP urgent pointer, window,
+ * acknowlegement, sequence number and IP ID. (The urgent pointer
+ * is different from the others in that its value is sent, not the
+ * change in value.) Since typical use of SLIP links is biased
+ * toward small packets (see comments on MTU/MSS below), changes
+ * use a variable length coding with one octet for numbers in the
+ * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
+ * range 256 - 65535 or 0. (If the change in sequence number or
+ * ack is more than 65535, an uncompressed packet is sent.)
+ */
+
+/*
+ * Packet types (must not conflict with IP protocol version)
+ *
+ * The top nibble of the first octet is the packet type. There are
+ * three possible types: IP (not proto TCP or tcp with one of the
+ * control flags set); uncompressed TCP (a normal IP/TCP packet but
+ * with the 8-bit protocol field replaced by an 8-bit connection id --
+ * this type of packet syncs the sender & receiver); and compressed
+ * TCP (described above).
+ *
+ * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
+ * is logically part of the 4-bit "changes" field that follows. Top
+ * three bits are actual packet type. For backward compatibility
+ * and in the interest of conserving bits, numbers are chosen so the
+ * IP protocol version number (4) which normally appears in this nibble
+ * means "IP packet".
+ */
+
+/* packet types */
+#define TYPE_IP 0x40
+#define TYPE_UNCOMPRESSED_TCP 0x70
+#define TYPE_COMPRESSED_TCP 0x80
+#define TYPE_ERROR 0x00
+
+/* Bits in first octet of compressed packet */
+#define NEW_C 0x40 /* flag bits for what changed in a packet */
+#define NEW_I 0x20
+#define NEW_S 0x08
+#define NEW_A 0x04
+#define NEW_W 0x02
+#define NEW_U 0x01
+
+/* reserved, special-case values of above */
+#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */
+#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */
+#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)
+
+#define TCP_PUSH_BIT 0x10
+
+
+/*
+ * "state" data for each active tcp conversation on the wire. This is
+ * basically a copy of the entire IP/TCP header from the last packet
+ * we saw from the conversation together with a small identifier
+ * the transmit & receive ends of the line use to locate saved header.
+ */
+struct cstate {
+ struct cstate *cs_next; /* next most recently used cstate (xmit only) */
+ u_short cs_hlen; /* size of hdr (receive only) */
+ u_char cs_id; /* connection # associated with this state */
+ u_char cs_filler;
+ union {
+ char csu_hdr[MAX_HDR];
+ struct ip csu_ip; /* ip/tcp hdr from most recent packet */
+ } slcs_u;
+};
+#define cs_ip slcs_u.csu_ip
+#define cs_hdr slcs_u.csu_hdr
+
+/*
+ * all the state data for one serial line (we need one of these
+ * per line).
+ */
+struct vjcompress {
+ struct cstate *last_cs; /* most recently used tstate */
+ u_char last_recv; /* last rcvd conn. id */
+ u_char last_xmit; /* last sent conn. id */
+ u_short flags;
+#ifndef SL_NO_STATS
+ int sls_packets; /* outbound packets */
+ int sls_compressed; /* outbound compressed packets */
+ int sls_searches; /* searches for connection state */
+ int sls_misses; /* times couldn't find conn. state */
+ int sls_uncompressedin; /* inbound uncompressed packets */
+ int sls_compressedin; /* inbound compressed packets */
+ int sls_errorin; /* inbound unknown type packets */
+ int sls_tossed; /* inbound packets tossed because of error */
+#endif
+ struct cstate tstate[MAX_STATES]; /* xmit connection states */
+ struct cstate rstate[MAX_STATES]; /* receive connection states */
+};
+/* flag values */
+#define SLF_TOSS 1 /* tossing rcvd frames because of input err */
+
+void vj_compress_init __P((struct vjcompress *, int));
+u_int vj_compress_tcp __P((struct mbuf *,
+ struct ip *, struct vjcompress *, int));
+int vj_uncompress_tcp __P((u_char **, int, u_int, struct vjcompress *));
+int vj_uncompress_tcp_core __P((u_char *, int, int, u_int,
+ struct vjcompress *, u_char **, u_int *));
+
+#endif /* _NET_PPPCOMPRESS_H_ */
diff --git a/cpukit/libnetworking/net/radix.c b/cpukit/libnetworking/net/radix.c
new file mode 100644
index 0000000000..8a98c42d1f
--- /dev/null
+++ b/cpukit/libnetworking/net/radix.c
@@ -0,0 +1,1074 @@
+/*
+ * Copyright (c) 1988, 1989, 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.
+ * 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.
+ *
+ * @(#)radix.c 8.5 (Berkeley) 5/19/95
+ * $FreeBSD: src/sys/net/radix.c,v 1.36 2004/04/21 15:27:36 luigi Exp $
+ */
+
+/*
+ * Routines to build and maintain radix trees for routing lookups.
+ */
+#ifndef _RADIX_H_
+#include <sys/param.h>
+#ifdef _KERNEL
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#define M_DONTWAIT M_NOWAIT
+#include <sys/domain.h>
+#else
+#include <stdlib.h>
+#endif
+#include <sys/syslog.h>
+#include <net/radix.h>
+#endif
+
+static int rn_walktree_from(struct radix_node_head *h, void *a, void *m,
+ walktree_f_t *f, void *w);
+static int rn_walktree(struct radix_node_head *, walktree_f_t *, void *);
+static struct radix_node
+ *rn_insert(void *, struct radix_node_head *, int *,
+ struct radix_node [2]),
+ *rn_newpair(void *, int, struct radix_node[2]),
+ *rn_search(void *, struct radix_node *),
+ *rn_search_m(void *, struct radix_node *, void *);
+
+static int max_keylen;
+static struct radix_mask *rn_mkfreelist;
+static struct radix_node_head *mask_rnhead;
+static char *addmask_key;
+static char normal_chars[] = {0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, -1};
+static char *rn_zeros, *rn_ones;
+
+#define rn_masktop (mask_rnhead->rnh_treetop)
+#undef Bcmp
+#define Bcmp(a, b, l) \
+ (l == 0 ? 0 : bcmp((caddr_t)(a), (caddr_t)(b), (u_long)l))
+
+static int rn_lexobetter(void *m_arg, void *n_arg);
+static struct radix_mask *
+ rn_new_radix_mask(struct radix_node *tt,
+ struct radix_mask *next);
+static int rn_satisfies_leaf(char *trial, struct radix_node *leaf,
+ int skip);
+
+/*
+ * The data structure for the keys is a radix tree with one way
+ * branching removed. The index rn_bit at an internal node n represents a bit
+ * position to be tested. The tree is arranged so that all descendants
+ * of a node n have keys whose bits all agree up to position rn_bit - 1.
+ * (We say the index of n is rn_bit.)
+ *
+ * There is at least one descendant which has a one bit at position rn_bit,
+ * and at least one with a zero there.
+ *
+ * A route is determined by a pair of key and mask. We require that the
+ * bit-wise logical and of the key and mask to be the key.
+ * We define the index of a route to associated with the mask to be
+ * the first bit number in the mask where 0 occurs (with bit number 0
+ * representing the highest order bit).
+ *
+ * We say a mask is normal if every bit is 0, past the index of the mask.
+ * If a node n has a descendant (k, m) with index(m) == index(n) == rn_bit,
+ * and m is a normal mask, then the route applies to every descendant of n.
+ * If the index(m) < rn_bit, this implies the trailing last few bits of k
+ * before bit b are all 0, (and hence consequently true of every descendant
+ * of n), so the route applies to all descendants of the node as well.
+ *
+ * Similar logic shows that a non-normal mask m such that
+ * index(m) <= index(n) could potentially apply to many children of n.
+ * Thus, for each non-host route, we attach its mask to a list at an internal
+ * node as high in the tree as we can go.
+ *
+ * The present version of the code makes use of normal routes in short-
+ * circuiting an explict mask and compare operation when testing whether
+ * a key satisfies a normal route, and also in remembering the unique leaf
+ * that governs a subtree.
+ */
+
+static struct radix_node *
+rn_search(v_arg, head)
+ void *v_arg;
+ struct radix_node *head;
+{
+ register struct radix_node *x;
+ register caddr_t v;
+
+ for (x = head, v = v_arg; x->rn_bit >= 0;) {
+ if (x->rn_bmask & v[x->rn_offset])
+ x = x->rn_right;
+ else
+ x = x->rn_left;
+ }
+ return (x);
+}
+
+static struct radix_node *
+rn_search_m(v_arg, head, m_arg)
+ struct radix_node *head;
+ void *v_arg, *m_arg;
+{
+ register struct radix_node *x;
+ register caddr_t v = v_arg, m = m_arg;
+
+ for (x = head; x->rn_bit >= 0;) {
+ if ((x->rn_bmask & m[x->rn_offset]) &&
+ (x->rn_bmask & v[x->rn_offset]))
+ x = x->rn_right;
+ else
+ x = x->rn_left;
+ }
+ return x;
+}
+
+int
+rn_refines(m_arg, n_arg)
+ void *m_arg, *n_arg;
+{
+ register caddr_t m = m_arg, n = n_arg;
+ register caddr_t lim, lim2 = lim = n + *(u_char *)n;
+ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
+ int masks_are_equal = 1;
+
+ if (longer > 0)
+ lim -= longer;
+ while (n < lim) {
+ if (*n & ~(*m))
+ return 0;
+ if (*n++ != *m++)
+ masks_are_equal = 0;
+ }
+ while (n < lim2)
+ if (*n++)
+ return 0;
+ if (masks_are_equal && (longer < 0))
+ for (lim2 = m - longer; m < lim2; )
+ if (*m++)
+ return 1;
+ return (!masks_are_equal);
+}
+
+struct radix_node *
+rn_lookup(v_arg, m_arg, head)
+ void *v_arg, *m_arg;
+ struct radix_node_head *head;
+{
+ register struct radix_node *x;
+ caddr_t netmask = 0;
+
+ if (m_arg) {
+ x = rn_addmask(m_arg, 1, head->rnh_treetop->rn_offset);
+ if (x == 0)
+ return (0);
+ netmask = x->rn_key;
+ }
+ x = rn_match(v_arg, head);
+ if (x && netmask) {
+ while (x && x->rn_mask != netmask)
+ x = x->rn_dupedkey;
+ }
+ return x;
+}
+
+static int
+rn_satisfies_leaf(trial, leaf, skip)
+ char *trial;
+ register struct radix_node *leaf;
+ int skip;
+{
+ register char *cp = trial, *cp2 = leaf->rn_key, *cp3 = leaf->rn_mask;
+ char *cplim;
+ int length = min(*(u_char *)cp, *(u_char *)cp2);
+
+ if (cp3 == 0)
+ cp3 = rn_ones;
+ else
+ length = min(length, *(u_char *)cp3);
+ cplim = cp + length; cp3 += skip; cp2 += skip;
+ for (cp += skip; cp < cplim; cp++, cp2++, cp3++)
+ if ((*cp ^ *cp2) & *cp3)
+ return 0;
+ return 1;
+}
+
+struct radix_node *
+rn_match(v_arg, head)
+ void *v_arg;
+ struct radix_node_head *head;
+{
+ caddr_t v = v_arg;
+ register struct radix_node *t = head->rnh_treetop, *x;
+ register caddr_t cp = v, cp2;
+ caddr_t cplim;
+ struct radix_node *saved_t, *top = t;
+ int off = t->rn_offset, vlen = *(u_char *)cp, matched_off;
+ register int test, b, rn_bit;
+
+ /*
+ * Open code rn_search(v, top) to avoid overhead of extra
+ * subroutine call.
+ */
+ for (; t->rn_bit >= 0; ) {
+ if (t->rn_bmask & cp[t->rn_offset])
+ t = t->rn_right;
+ else
+ t = t->rn_left;
+ }
+ /*
+ * See if we match exactly as a host destination
+ * or at least learn how many bits match, for normal mask finesse.
+ *
+ * It doesn't hurt us to limit how many bytes to check
+ * to the length of the mask, since if it matches we had a genuine
+ * match and the leaf we have is the most specific one anyway;
+ * if it didn't match with a shorter length it would fail
+ * with a long one. This wins big for class B&C netmasks which
+ * are probably the most common case...
+ */
+ if (t->rn_mask)
+ vlen = *(u_char *)t->rn_mask;
+ cp += off; cp2 = t->rn_key + off; cplim = v + vlen;
+ for (; cp < cplim; cp++, cp2++)
+ if (*cp != *cp2)
+ goto on1;
+ /*
+ * This extra grot is in case we are explicitly asked
+ * to look up the default. Ugh!
+ *
+ * Never return the root node itself, it seems to cause a
+ * lot of confusion.
+ */
+ if (t->rn_flags & RNF_ROOT)
+ t = t->rn_dupedkey;
+ return t;
+on1:
+ test = (*cp ^ *cp2) & 0xff; /* find first bit that differs */
+ for (b = 7; (test >>= 1) > 0;)
+ b--;
+ matched_off = cp - v;
+ b += matched_off << 3;
+ rn_bit = -1 - b;
+ /*
+ * If there is a host route in a duped-key chain, it will be first.
+ */
+ if ((saved_t = t)->rn_mask == 0)
+ t = t->rn_dupedkey;
+ for (; t; t = t->rn_dupedkey)
+ /*
+ * Even if we don't match exactly as a host,
+ * we may match if the leaf we wound up at is
+ * a route to a net.
+ */
+ if (t->rn_flags & RNF_NORMAL) {
+ if (rn_bit <= t->rn_bit)
+ return t;
+ } else if (rn_satisfies_leaf(v, t, matched_off))
+ return t;
+ t = saved_t;
+ /* start searching up the tree */
+ do {
+ register struct radix_mask *m;
+ t = t->rn_parent;
+ m = t->rn_mklist;
+ if (m) {
+ /*
+ * If non-contiguous masks ever become important
+ * we can restore the masking and open coding of
+ * the search and satisfaction test and put the
+ * calculation of "off" back before the "do".
+ */
+ do {
+ if (m->rm_flags & RNF_NORMAL) {
+ if (rn_bit <= m->rm_bit)
+ return (m->rm_leaf);
+ } else {
+ off = min(t->rn_offset, matched_off);
+ x = rn_search_m(v, t, m->rm_mask);
+ while (x && x->rn_mask != m->rm_mask)
+ x = x->rn_dupedkey;
+ if (x && rn_satisfies_leaf(v, x, off))
+ return x;
+ }
+ m = m->rm_mklist;
+ } while (m);
+ }
+ } while (t != top);
+ return 0;
+}
+
+#ifdef RN_DEBUG
+int rn_nodenum;
+struct radix_node *rn_clist;
+int rn_saveinfo;
+int rn_debug = 1;
+#endif
+
+static struct radix_node *
+rn_newpair(v, b, nodes)
+ void *v;
+ int b;
+ struct radix_node nodes[2];
+{
+ register struct radix_node *tt = nodes, *t = tt + 1;
+ t->rn_bit = b;
+ t->rn_bmask = 0x80 >> (b & 7);
+ t->rn_left = tt;
+ t->rn_offset = b >> 3;
+ tt->rn_bit = -1;
+ tt->rn_key = (caddr_t)v;
+ tt->rn_parent = t;
+ tt->rn_flags = t->rn_flags = RNF_ACTIVE;
+#ifdef RN_DEBUG
+ tt->rn_info = rn_nodenum++; t->rn_info = rn_nodenum++;
+ tt->rn_twin = t;
+ tt->rn_ybro = rn_clist;
+ rn_clist = tt;
+#endif
+ return t;
+}
+
+static struct radix_node *
+rn_insert(v_arg, head, dupentry, nodes)
+ void *v_arg;
+ struct radix_node_head *head;
+ int *dupentry;
+ struct radix_node nodes[2];
+{
+ caddr_t v = v_arg;
+ struct radix_node *top = head->rnh_treetop;
+ int head_off = top->rn_offset, vlen = (int)*((u_char *)v);
+ register struct radix_node *t = rn_search(v_arg, top);
+ register caddr_t cp = v + head_off;
+ register int b;
+ struct radix_node *tt;
+ /*
+ * Find first bit at which v and t->rn_key differ
+ */
+ {
+ register caddr_t cp2 = t->rn_key + head_off;
+ register int cmp_res;
+ caddr_t cplim = v + vlen;
+
+ while (cp < cplim)
+ if (*cp2++ != *cp++)
+ goto on1;
+ *dupentry = 1;
+ return t;
+on1:
+ *dupentry = 0;
+ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
+ for (b = (cp - v) << 3; cmp_res; b--)
+ cmp_res >>= 1;
+ }
+ {
+ register struct radix_node *p, *x = top;
+ cp = v;
+ do {
+ p = x;
+ if (cp[x->rn_offset] & x->rn_bmask)
+ x = x->rn_right;
+ else
+ x = x->rn_left;
+ } while (b > (unsigned) x->rn_bit);
+ /* x->rn_bit < b && x->rn_bit >= 0 */
+#ifdef RN_DEBUG
+ if (rn_debug)
+ log(LOG_DEBUG, "rn_insert: Going In:\n"), traverse(p);
+#endif
+ t = rn_newpair(v_arg, b, nodes);
+ tt = t->rn_left;
+ if ((cp[p->rn_offset] & p->rn_bmask) == 0)
+ p->rn_left = t;
+ else
+ p->rn_right = t;
+ x->rn_parent = t;
+ t->rn_parent = p; /* frees x, p as temp vars below */
+ if ((cp[t->rn_offset] & t->rn_bmask) == 0) {
+ t->rn_right = x;
+ } else {
+ t->rn_right = tt;
+ t->rn_left = x;
+ }
+#ifdef RN_DEBUG
+ if (rn_debug)
+ log(LOG_DEBUG, "rn_insert: Coming Out:\n"), traverse(p);
+#endif
+ }
+ return (tt);
+}
+
+struct radix_node *
+rn_addmask(n_arg, search, skip)
+ int search, skip;
+ void *n_arg;
+{
+ caddr_t netmask = (caddr_t)n_arg;
+ register struct radix_node *x;
+ register caddr_t cp, cplim;
+ register int b = 0, mlen, j;
+ int maskduplicated, m0, isnormal;
+ struct radix_node *saved_x;
+ static int last_zeroed = 0;
+
+ if ((mlen = *(u_char *)netmask) > max_keylen)
+ mlen = max_keylen;
+ if (skip == 0)
+ skip = 1;
+ if (mlen <= skip)
+ return (mask_rnhead->rnh_nodes);
+ if (skip > 1)
+ Bcopy(rn_ones + 1, addmask_key + 1, skip - 1);
+ if ((m0 = mlen) > skip)
+ Bcopy(netmask + skip, addmask_key + skip, mlen - skip);
+ /*
+ * Trim trailing zeroes.
+ */
+ for (cp = addmask_key + mlen; (cp > addmask_key) && cp[-1] == 0;)
+ cp--;
+ mlen = cp - addmask_key;
+ if (mlen <= skip) {
+ if (m0 >= last_zeroed)
+ last_zeroed = mlen;
+ return (mask_rnhead->rnh_nodes);
+ }
+ if (m0 < last_zeroed)
+ Bzero(addmask_key + m0, last_zeroed - m0);
+ *addmask_key = last_zeroed = mlen;
+ x = rn_search(addmask_key, rn_masktop);
+ if (Bcmp(addmask_key, x->rn_key, mlen) != 0)
+ x = 0;
+ if (x || search)
+ return (x);
+ R_Malloc(x, struct radix_node *, max_keylen + 2 * sizeof (*x));
+ if ((saved_x = x) == 0)
+ return (0);
+ Bzero(x, max_keylen + 2 * sizeof (*x));
+ netmask = cp = (caddr_t)(x + 2);
+ Bcopy(addmask_key, cp, mlen);
+ x = rn_insert(cp, mask_rnhead, &maskduplicated, x);
+ if (maskduplicated) {
+ log(LOG_ERR, "rn_addmask: mask impossibly already in tree");
+ Free(saved_x);
+ return (x);
+ }
+ /*
+ * Calculate index of mask, and check for normalcy.
+ */
+ cplim = netmask + mlen; isnormal = 1;
+ for (cp = netmask + skip; (cp < cplim) && *(u_char *)cp == 0xff;)
+ cp++;
+ if (cp != cplim) {
+ for (j = 0x80; (j & *cp) != 0; j >>= 1)
+ b++;
+ if (*cp != normal_chars[b] || cp != (cplim - 1))
+ isnormal = 0;
+ }
+ b += (cp - netmask) << 3;
+ x->rn_bit = -1 - b;
+ if (isnormal)
+ x->rn_flags |= RNF_NORMAL;
+ return (x);
+}
+
+static int /* XXX: arbitrary ordering for non-contiguous masks */
+rn_lexobetter(m_arg, n_arg)
+ void *m_arg, *n_arg;
+{
+ register u_char *mp = m_arg, *np = n_arg, *lim;
+
+ if (*mp > *np)
+ return 1; /* not really, but need to check longer one first */
+ if (*mp == *np)
+ for (lim = mp + *mp; mp < lim;)
+ if (*mp++ > *np++)
+ return 1;
+ return 0;
+}
+
+static struct radix_mask *
+rn_new_radix_mask(tt, next)
+ register struct radix_node *tt;
+ register struct radix_mask *next;
+{
+ register struct radix_mask *m;
+
+ MKGet(m);
+ if (m == 0) {
+ log(LOG_ERR, "Mask for route not entered\n");
+ return (0);
+ }
+ Bzero(m, sizeof *m);
+ m->rm_bit = tt->rn_bit;
+ m->rm_flags = tt->rn_flags;
+ if (tt->rn_flags & RNF_NORMAL)
+ m->rm_leaf = tt;
+ else
+ m->rm_mask = tt->rn_mask;
+ m->rm_mklist = next;
+ tt->rn_mklist = m;
+ return m;
+}
+
+struct radix_node *
+rn_addroute(v_arg, n_arg, head, treenodes)
+ void *v_arg, *n_arg;
+ struct radix_node_head *head;
+ struct radix_node treenodes[2];
+{
+ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
+ register struct radix_node *t, *x = 0, *tt;
+ struct radix_node *saved_tt, *top = head->rnh_treetop;
+ short b = 0, b_leaf = 0;
+ int keyduplicated;
+ caddr_t mmask;
+ struct radix_mask *m, **mp;
+
+ /*
+ * In dealing with non-contiguous masks, there may be
+ * many different routes which have the same mask.
+ * We will find it useful to have a unique pointer to
+ * the mask to speed avoiding duplicate references at
+ * nodes and possibly save time in calculating indices.
+ */
+ if (netmask) {
+ if ((x = rn_addmask(netmask, 0, top->rn_offset)) == 0)
+ return (0);
+ b_leaf = x->rn_bit;
+ b = -1 - x->rn_bit;
+ netmask = x->rn_key;
+ }
+ /*
+ * Deal with duplicated keys: attach node to previous instance
+ */
+ saved_tt = tt = rn_insert(v, head, &keyduplicated, treenodes);
+ if (keyduplicated) {
+ for (t = tt; tt; t = tt, tt = tt->rn_dupedkey) {
+ if (tt->rn_mask == netmask)
+ return (0);
+ if (netmask == 0 ||
+ (tt->rn_mask &&
+ ((b_leaf < tt->rn_bit) /* index(netmask) > node */
+ || rn_refines(netmask, tt->rn_mask)
+ || rn_lexobetter(netmask, tt->rn_mask))))
+ break;
+ }
+ /*
+ * If the mask is not duplicated, we wouldn't
+ * find it among possible duplicate key entries
+ * anyway, so the above test doesn't hurt.
+ *
+ * We sort the masks for a duplicated key the same way as
+ * in a masklist -- most specific to least specific.
+ * This may require the unfortunate nuisance of relocating
+ * the head of the list.
+ *
+ * We also reverse, or doubly link the list through the
+ * parent pointer.
+ */
+ if (tt == saved_tt) {
+ struct radix_node *xx = x;
+ /* link in at head of list */
+ (tt = treenodes)->rn_dupedkey = t;
+ tt->rn_flags = t->rn_flags;
+ tt->rn_parent = x = t->rn_parent;
+ t->rn_parent = tt; /* parent */
+ if (x->rn_left == t)
+ x->rn_left = tt;
+ else
+ x->rn_right = tt;
+ saved_tt = tt; x = xx;
+ } else {
+ (tt = treenodes)->rn_dupedkey = t->rn_dupedkey;
+ t->rn_dupedkey = tt;
+ tt->rn_parent = t; /* parent */
+ if (tt->rn_dupedkey) /* parent */
+ tt->rn_dupedkey->rn_parent = tt; /* parent */
+ }
+#ifdef RN_DEBUG
+ t=tt+1; tt->rn_info = rn_nodenum++; t->rn_info = rn_nodenum++;
+ tt->rn_twin = t; tt->rn_ybro = rn_clist; rn_clist = tt;
+#endif
+ tt->rn_key = (caddr_t) v;
+ tt->rn_bit = -1;
+ tt->rn_flags = RNF_ACTIVE;
+ }
+ /*
+ * Put mask in tree.
+ */
+ if (netmask) {
+ tt->rn_mask = netmask;
+ tt->rn_bit = x->rn_bit;
+ tt->rn_flags |= x->rn_flags & RNF_NORMAL;
+ }
+ t = saved_tt->rn_parent;
+ if (keyduplicated)
+ goto on2;
+ b_leaf = -1 - t->rn_bit;
+ if (t->rn_right == saved_tt)
+ x = t->rn_left;
+ else
+ x = t->rn_right;
+ /* Promote general routes from below */
+ if (x->rn_bit < 0) {
+ for (mp = &t->rn_mklist; x; x = x->rn_dupedkey)
+ if (x->rn_mask && (x->rn_bit >= b_leaf) && x->rn_mklist == 0) {
+ *mp = m = rn_new_radix_mask(x, 0);
+ if (m)
+ mp = &m->rm_mklist;
+ }
+ } else if (x->rn_mklist) {
+ /*
+ * Skip over masks whose index is > that of new node
+ */
+ for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist)
+ if (m->rm_bit >= b_leaf)
+ break;
+ t->rn_mklist = m; *mp = 0;
+ }
+on2:
+ /* Add new route to highest possible ancestor's list */
+ if ((netmask == 0) || (b > t->rn_bit ))
+ return tt; /* can't lift at all */
+ b_leaf = tt->rn_bit;
+ do {
+ x = t;
+ t = t->rn_parent;
+ } while (b <= t->rn_bit && x != top);
+ /*
+ * Search through routes associated with node to
+ * insert new route according to index.
+ * Need same criteria as when sorting dupedkeys to avoid
+ * double loop on deletion.
+ */
+ for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist) {
+ if (m->rm_bit < b_leaf)
+ continue;
+ if (m->rm_bit > b_leaf)
+ break;
+ if (m->rm_flags & RNF_NORMAL) {
+ mmask = m->rm_leaf->rn_mask;
+ if (tt->rn_flags & RNF_NORMAL) {
+ log(LOG_ERR,
+ "Non-unique normal route, mask not entered\n");
+ return tt;
+ }
+ } else
+ mmask = m->rm_mask;
+ if (mmask == netmask) {
+ m->rm_refs++;
+ tt->rn_mklist = m;
+ return tt;
+ }
+ if (rn_refines(netmask, mmask)
+ || rn_lexobetter(netmask, mmask))
+ break;
+ }
+ *mp = rn_new_radix_mask(tt, *mp);
+ return tt;
+}
+
+struct radix_node *
+rn_delete(v_arg, netmask_arg, head)
+ void *v_arg, *netmask_arg;
+ struct radix_node_head *head;
+{
+ register struct radix_node *t, *p, *x, *tt;
+ struct radix_mask *m, *saved_m, **mp;
+ struct radix_node *dupedkey, *saved_tt, *top;
+ caddr_t v, netmask;
+ int b, head_off, vlen;
+
+ v = v_arg;
+ netmask = netmask_arg;
+ x = head->rnh_treetop;
+ tt = rn_search(v, x);
+ head_off = x->rn_offset;
+ vlen = *(u_char *)v;
+ saved_tt = tt;
+ top = x;
+ if (tt == 0 ||
+ Bcmp(v + head_off, tt->rn_key + head_off, vlen - head_off))
+ return (0);
+ /*
+ * Delete our route from mask lists.
+ */
+ if (netmask) {
+ if ((x = rn_addmask(netmask, 1, head_off)) == 0)
+ return (0);
+ netmask = x->rn_key;
+ while (tt->rn_mask != netmask)
+ if ((tt = tt->rn_dupedkey) == 0)
+ return (0);
+ }
+ if (tt->rn_mask == 0 || (saved_m = m = tt->rn_mklist) == 0)
+ goto on1;
+ if (tt->rn_flags & RNF_NORMAL) {
+ if (m->rm_leaf != tt || m->rm_refs > 0) {
+ log(LOG_ERR, "rn_delete: inconsistent annotation\n");
+ return 0; /* dangling ref could cause disaster */
+ }
+ } else {
+ if (m->rm_mask != tt->rn_mask) {
+ log(LOG_ERR, "rn_delete: inconsistent annotation\n");
+ goto on1;
+ }
+ if (--m->rm_refs >= 0)
+ goto on1;
+ }
+ b = -1 - tt->rn_bit;
+ t = saved_tt->rn_parent;
+ if (b > t->rn_bit)
+ goto on1; /* Wasn't lifted at all */
+ do {
+ x = t;
+ t = t->rn_parent;
+ } while (b <= t->rn_bit && x != top);
+ for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist)
+ if (m == saved_m) {
+ *mp = m->rm_mklist;
+ MKFree(m);
+ break;
+ }
+ if (m == 0) {
+ log(LOG_ERR, "rn_delete: couldn't find our annotation\n");
+ if (tt->rn_flags & RNF_NORMAL)
+ return (0); /* Dangling ref to us */
+ }
+on1:
+ /*
+ * Eliminate us from tree
+ */
+ if (tt->rn_flags & RNF_ROOT)
+ return (0);
+#ifdef RN_DEBUG
+ /* Get us out of the creation list */
+ for (t = rn_clist; t && t->rn_ybro != tt; t = t->rn_ybro) {}
+ if (t) t->rn_ybro = tt->rn_ybro;
+#endif
+ t = tt->rn_parent;
+ dupedkey = saved_tt->rn_dupedkey;
+ if (dupedkey) {
+ /*
+ * Here, tt is the deletion target and
+ * saved_tt is the head of the dupekey chain.
+ */
+ if (tt == saved_tt) {
+ /* remove from head of chain */
+ x = dupedkey; x->rn_parent = t;
+ if (t->rn_left == tt)
+ t->rn_left = x;
+ else
+ t->rn_right = x;
+ } else {
+ /* find node in front of tt on the chain */
+ for (x = p = saved_tt; p && p->rn_dupedkey != tt;)
+ p = p->rn_dupedkey;
+ if (p) {
+ p->rn_dupedkey = tt->rn_dupedkey;
+ if (tt->rn_dupedkey) /* parent */
+ tt->rn_dupedkey->rn_parent = p;
+ /* parent */
+ } else log(LOG_ERR, "rn_delete: couldn't find us\n");
+ }
+ t = tt + 1;
+ if (t->rn_flags & RNF_ACTIVE) {
+#ifndef RN_DEBUG
+ *++x = *t;
+ p = t->rn_parent;
+#else
+ b = t->rn_info;
+ *++x = *t;
+ t->rn_info = b;
+ p = t->rn_parent;
+#endif
+ if (p->rn_left == t)
+ p->rn_left = x;
+ else
+ p->rn_right = x;
+ x->rn_left->rn_parent = x;
+ x->rn_right->rn_parent = x;
+ }
+ goto out;
+ }
+ if (t->rn_left == tt)
+ x = t->rn_right;
+ else
+ x = t->rn_left;
+ p = t->rn_parent;
+ if (p->rn_right == t)
+ p->rn_right = x;
+ else
+ p->rn_left = x;
+ x->rn_parent = p;
+ /*
+ * Demote routes attached to us.
+ */
+ if (t->rn_mklist) {
+ if (x->rn_bit >= 0) {
+ for (mp = &x->rn_mklist; (m = *mp);)
+ mp = &m->rm_mklist;
+ *mp = t->rn_mklist;
+ } else {
+ /* If there are any key,mask pairs in a sibling
+ duped-key chain, some subset will appear sorted
+ in the same order attached to our mklist */
+ for (m = t->rn_mklist; m && x; x = x->rn_dupedkey)
+ if (m == x->rn_mklist) {
+ struct radix_mask *mm = m->rm_mklist;
+ x->rn_mklist = 0;
+ if (--(m->rm_refs) < 0)
+ MKFree(m);
+ m = mm;
+ }
+ if (m)
+ log(LOG_ERR,
+ "rn_delete: Orphaned Mask %p at %p\n",
+ (void *)m, (void *)x);
+ }
+ }
+ /*
+ * We may be holding an active internal node in the tree.
+ */
+ x = tt + 1;
+ if (t != x) {
+#ifndef RN_DEBUG
+ *t = *x;
+#else
+ b = t->rn_info;
+ *t = *x;
+ t->rn_info = b;
+#endif
+ t->rn_left->rn_parent = t;
+ t->rn_right->rn_parent = t;
+ p = x->rn_parent;
+ if (p->rn_left == x)
+ p->rn_left = t;
+ else
+ p->rn_right = t;
+ }
+out:
+ tt->rn_flags &= ~RNF_ACTIVE;
+ tt[1].rn_flags &= ~RNF_ACTIVE;
+ return (tt);
+}
+
+/*
+ * This is the same as rn_walktree() except for the parameters and the
+ * exit.
+ */
+static int
+rn_walktree_from(h, a, m, f, w)
+ struct radix_node_head *h;
+ void *a, *m;
+ walktree_f_t *f;
+ void *w;
+{
+ int error;
+ struct radix_node *base, *next;
+ u_char *xa = (u_char *)a;
+ u_char *xm = (u_char *)m;
+ register struct radix_node *rn, *last = 0 /* shut up gcc */;
+ int stopping = 0;
+ int lastb;
+
+ /*
+ * rn_search_m is sort-of-open-coded here.
+ */
+ /* printf("about to search\n"); */
+ for (rn = h->rnh_treetop; rn->rn_bit >= 0; ) {
+ last = rn;
+ /* printf("rn_bit %d, rn_bmask %x, xm[rn_offset] %x\n",
+ rn->rn_bit, rn->rn_bmask, xm[rn->rn_offset]); */
+ if (!(rn->rn_bmask & xm[rn->rn_offset])) {
+ break;
+ }
+ if (rn->rn_bmask & xa[rn->rn_offset]) {
+ rn = rn->rn_right;
+ } else {
+ rn = rn->rn_left;
+ }
+ }
+ /* printf("done searching\n"); */
+
+ /*
+ * Two cases: either we stepped off the end of our mask,
+ * in which case last == rn, or we reached a leaf, in which
+ * case we want to start from the last node we looked at.
+ * Either way, last is the node we want to start from.
+ */
+ rn = last;
+ lastb = rn->rn_bit;
+
+ /* printf("rn %p, lastb %d\n", rn, lastb);*/
+
+ /*
+ * This gets complicated because we may delete the node
+ * while applying the function f to it, so we need to calculate
+ * the successor node in advance.
+ */
+ while (rn->rn_bit >= 0)
+ rn = rn->rn_left;
+
+ while (!stopping) {
+ /* printf("node %p (%d)\n", rn, rn->rn_bit); */
+ base = rn;
+ /* If at right child go back up, otherwise, go right */
+ while (rn->rn_parent->rn_right == rn
+ && !(rn->rn_flags & RNF_ROOT)) {
+ rn = rn->rn_parent;
+
+ /* if went up beyond last, stop */
+ if (rn->rn_bit < lastb) {
+ stopping = 1;
+ /* printf("up too far\n"); */
+ }
+ }
+
+ /* Find the next *leaf* since next node might vanish, too */
+ for (rn = rn->rn_parent->rn_right; rn->rn_bit >= 0;)
+ rn = rn->rn_left;
+ next = rn;
+ /* Process leaves */
+ while ((rn = base) != 0) {
+ base = rn->rn_dupedkey;
+ /* printf("leaf %p\n", rn); */
+ if (!(rn->rn_flags & RNF_ROOT)
+ && (error = (*f)(rn, w)))
+ return (error);
+ }
+ rn = next;
+
+ if (rn->rn_flags & RNF_ROOT) {
+ /* printf("root, stopping"); */
+ stopping = 1;
+ }
+
+ }
+ return 0;
+}
+
+static int
+rn_walktree(h, f, w)
+ struct radix_node_head *h;
+ walktree_f_t *f;
+ void *w;
+{
+ int error;
+ struct radix_node *base, *next;
+ register struct radix_node *rn = h->rnh_treetop;
+ /*
+ * This gets complicated because we may delete the node
+ * while applying the function f to it, so we need to calculate
+ * the successor node in advance.
+ */
+ /* First time through node, go left */
+ while (rn->rn_bit >= 0)
+ rn = rn->rn_left;
+ for (;;) {
+ base = rn;
+ /* If at right child go back up, otherwise, go right */
+ while (rn->rn_parent->rn_right == rn
+ && (rn->rn_flags & RNF_ROOT) == 0)
+ rn = rn->rn_parent;
+ /* Find the next *leaf* since next node might vanish, too */
+ for (rn = rn->rn_parent->rn_right; rn->rn_bit >= 0;)
+ rn = rn->rn_left;
+ next = rn;
+ /* Process leaves */
+ while ((rn = base)) {
+ base = rn->rn_dupedkey;
+ if (!(rn->rn_flags & RNF_ROOT)
+ && (error = (*f)(rn, w)))
+ return (error);
+ }
+ rn = next;
+ if (rn->rn_flags & RNF_ROOT)
+ return (0);
+ }
+ /* NOTREACHED */
+}
+
+int
+rn_inithead(head, off)
+ void **head;
+ int off;
+{
+ register struct radix_node_head *rnh;
+ register struct radix_node *t, *tt, *ttt;
+ if (*head)
+ return (1);
+ R_Malloc(rnh, struct radix_node_head *, sizeof (*rnh));
+ if (rnh == 0)
+ return (0);
+ Bzero(rnh, sizeof (*rnh));
+ *head = rnh;
+ t = rn_newpair(rn_zeros, off, rnh->rnh_nodes);
+ ttt = rnh->rnh_nodes + 2;
+ t->rn_right = ttt;
+ t->rn_parent = t;
+ tt = t->rn_left;
+ tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE;
+ tt->rn_bit = -1 - off;
+ *ttt = *tt;
+ ttt->rn_key = rn_ones;
+ rnh->rnh_addaddr = rn_addroute;
+ rnh->rnh_deladdr = rn_delete;
+ rnh->rnh_matchaddr = rn_match;
+ rnh->rnh_lookup = rn_lookup;
+ rnh->rnh_walktree = rn_walktree;
+ rnh->rnh_walktree_from = rn_walktree_from;
+ rnh->rnh_treetop = t;
+ return (1);
+}
+
+void
+rn_init()
+{
+ char *cp, *cplim;
+#ifdef _KERNEL
+ struct domain *dom;
+
+ for (dom = domains; dom; dom = dom->dom_next)
+ if (dom->dom_maxrtkey > max_keylen)
+ max_keylen = dom->dom_maxrtkey;
+#endif
+ if (max_keylen == 0) {
+ log(LOG_ERR,
+ "rn_init: radix functions require max_keylen be set\n");
+ return;
+ }
+ R_Malloc(rn_zeros, char *, 3 * max_keylen);
+ if (rn_zeros == NULL)
+ panic("rn_init");
+ Bzero(rn_zeros, 3 * max_keylen);
+ rn_ones = cp = rn_zeros + max_keylen;
+ addmask_key = cplim = rn_ones + max_keylen;
+ while (cp < cplim)
+ *cp++ = -1;
+ if (rn_inithead((void **)(void*)&mask_rnhead, 0) == 0)
+ panic("rn_init 2");
+}
diff --git a/cpukit/libnetworking/net/radix.h b/cpukit/libnetworking/net/radix.h
new file mode 100644
index 0000000000..cf132a4ab9
--- /dev/null
+++ b/cpukit/libnetworking/net/radix.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1988, 1989, 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.
+ * 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.
+ *
+ * @(#)radix.h 8.2 (Berkeley) 10/31/94
+ * $FreeBSD: src/sys/net/radix.h,v 1.25 2004/04/18 11:48:35 luigi Exp $
+ */
+
+#ifndef _RADIX_H_
+#define _RADIX_H_
+
+/*
+ * Radix search tree node layout.
+ */
+
+struct radix_node {
+ struct radix_mask *rn_mklist; /* list of masks contained in subtree */
+ struct radix_node *rn_parent; /* parent */
+ short rn_bit; /* bit offset; -1-index(netmask) */
+ char rn_bmask; /* node: mask for bit test*/
+ u_char rn_flags; /* enumerated next */
+#define RNF_NORMAL 1 /* leaf contains normal route */
+#define RNF_ROOT 2 /* leaf is root leaf for tree */
+#define RNF_ACTIVE 4 /* This node is alive (for rtfree) */
+ union {
+ struct { /* leaf only data: */
+ caddr_t rn_Key; /* object of search */
+ caddr_t rn_Mask; /* netmask, if present */
+ struct radix_node *rn_Dupedkey;
+ } rn_leaf;
+ struct { /* node only data: */
+ int rn_Off; /* where to start compare */
+ struct radix_node *rn_L;/* progeny */
+ struct radix_node *rn_R;/* progeny */
+ } rn_node;
+ } rn_u;
+#ifdef RN_DEBUG
+ int rn_info;
+ struct radix_node *rn_twin;
+ struct radix_node *rn_ybro;
+#endif
+};
+
+#define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey
+#define rn_key rn_u.rn_leaf.rn_Key
+#define rn_mask rn_u.rn_leaf.rn_Mask
+#define rn_offset rn_u.rn_node.rn_Off
+#define rn_left rn_u.rn_node.rn_L
+#define rn_right rn_u.rn_node.rn_R
+
+/*
+ * Annotations to tree concerning potential routes applying to subtrees.
+ */
+
+struct radix_mask {
+ short rm_bit; /* bit offset; -1-index(netmask) */
+ char rm_unused; /* cf. rn_bmask */
+ u_char rm_flags; /* cf. rn_flags */
+ struct radix_mask *rm_mklist; /* more masks to try */
+ union {
+ caddr_t rmu_mask; /* the mask */
+ struct radix_node *rmu_leaf; /* for normal routes */
+ } rm_rmu;
+ int rm_refs; /* # of references to this struct */
+};
+
+#define rm_mask rm_rmu.rmu_mask
+#define rm_leaf rm_rmu.rmu_leaf /* extra field would make 32 bytes */
+
+#define MKGet(m) {\
+ if (rn_mkfreelist) {\
+ m = rn_mkfreelist; \
+ rn_mkfreelist = (m)->rm_mklist; \
+ } else \
+ R_Malloc(m, struct radix_mask *, sizeof (*(m))); }\
+
+#define MKFree(m) { (m)->rm_mklist = rn_mkfreelist; rn_mkfreelist = (m);}
+
+typedef int walktree_f_t(struct radix_node *, void *);
+
+struct radix_node_head {
+ struct radix_node *rnh_treetop;
+ int rnh_addrsize; /* permit, but not require fixed keys */
+ int rnh_pktsize; /* permit, but not require fixed keys */
+ struct radix_node *(*rnh_addaddr) /* add based on sockaddr */
+ (void *v, void *mask,
+ struct radix_node_head *head, struct radix_node nodes[]);
+ struct radix_node *(*rnh_addpkt) /* add based on packet hdr */
+ (void *v, void *mask,
+ struct radix_node_head *head, struct radix_node nodes[]);
+ struct radix_node *(*rnh_deladdr) /* remove based on sockaddr */
+ (void *v, void *mask, struct radix_node_head *head);
+ struct radix_node *(*rnh_delpkt) /* remove based on packet hdr */
+ (void *v, void *mask, struct radix_node_head *head);
+ struct radix_node *(*rnh_matchaddr) /* locate based on sockaddr */
+ (void *v, struct radix_node_head *head);
+ struct radix_node *(*rnh_lookup) /* locate based on sockaddr */
+ (void *v, void *mask, struct radix_node_head *head);
+ struct radix_node *(*rnh_matchpkt) /* locate based on packet hdr */
+ (void *v, struct radix_node_head *head);
+ int (*rnh_walktree) /* traverse tree */
+ (struct radix_node_head *head, walktree_f_t *f, void *w);
+ int (*rnh_walktree_from) /* traverse tree below a */
+ (struct radix_node_head *head, void *a, void *m,
+ walktree_f_t *f, void *w);
+ void (*rnh_close) /* do something when the last ref drops */
+ (struct radix_node *rn, struct radix_node_head *head);
+ struct radix_node rnh_nodes[3]; /* empty tree for common case */
+};
+
+#ifndef _KERNEL
+#define Bcmp(a, b, n) bcmp(((char *)(a)), ((char *)(b)), (n))
+#define Bcopy(a, b, n) bcopy(((char *)(a)), ((char *)(b)), (unsigned)(n))
+#define Bzero(p, n) bzero((char *)(p), (int)(n));
+#define R_Malloc(p, t, n) (p = (t) malloc((unsigned int)(n)))
+#define R_Zalloc(p, t, n) (p = (t) calloc(1,(unsigned int)(n)))
+#define Free(p) free((char *)p);
+#else
+#define Bcmp(a, b, n) bcmp(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n))
+#define Bcopy(a, b, n) bcopy(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n))
+#define Bzero(p, n) bzero((caddr_t)(p), (unsigned)(n));
+#define R_Malloc(p, t, n) (p = (t) malloc((unsigned long)(n), M_RTABLE, M_DONTWAIT))
+#define Free(p) free((caddr_t)p, M_RTABLE);
+#endif /*_KERNEL*/
+
+void rn_init(void);
+int rn_inithead(void **, int);
+int rn_refines(void *, void *);
+struct radix_node
+ *rn_addmask(void *, int, int),
+ *rn_addroute (void *, void *, struct radix_node_head *,
+ struct radix_node [2]),
+ *rn_delete(void *, void *, struct radix_node_head *),
+ *rn_lookup (void *v_arg, void *m_arg,
+ struct radix_node_head *head),
+ *rn_match(void *, struct radix_node_head *);
+
+#endif /* _RADIX_H_ */
diff --git a/cpukit/libnetworking/net/raw_cb.c b/cpukit/libnetworking/net/raw_cb.c
new file mode 100644
index 0000000000..0676931cdc
--- /dev/null
+++ b/cpukit/libnetworking/net/raw_cb.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1980, 1986, 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.
+ *
+ * @(#)raw_cb.c 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/raw_cb.h>
+#include <netinet/in.h>
+
+/*
+ * Routines to manage the raw protocol control blocks.
+ *
+ * TODO:
+ * hash lookups by protocol family/protocol + address family
+ * take care of unique address problems per AF?
+ * redo address binding to allow wildcards
+ */
+
+struct rawcb rawcb;
+static u_long raw_sendspace = RAWSNDQ;
+static u_long raw_recvspace = RAWRCVQ;
+
+/*
+ * Allocate a control block and a nominal amount
+ * of buffer space for the socket.
+ */
+int
+raw_attach(so, proto)
+ register struct socket *so;
+ int proto;
+{
+ register struct rawcb *rp = sotorawcb(so);
+ int error;
+
+ /*
+ * It is assumed that raw_attach is called
+ * after space has been allocated for the
+ * rawcb.
+ */
+ if (rp == 0)
+ return (ENOBUFS);
+ error = soreserve(so, raw_sendspace, raw_recvspace);
+ if (error)
+ return (error);
+ rp->rcb_socket = so;
+ rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
+ rp->rcb_proto.sp_protocol = proto;
+ insque(rp, &rawcb);
+ return (0);
+}
+
+/*
+ * Detach the raw connection block and discard
+ * socket resources.
+ */
+void
+raw_detach(rp)
+ register struct rawcb *rp;
+{
+ struct socket *so = rp->rcb_socket;
+
+ so->so_pcb = 0;
+ sofree(so);
+ remque(rp);
+#ifdef notdef
+ if (rp->rcb_laddr)
+ m_freem(dtom(rp->rcb_laddr));
+ rp->rcb_laddr = 0;
+#endif
+ free((caddr_t)(rp), M_PCB);
+}
+
+/*
+ * Disconnect and possibly release resources.
+ */
+void
+raw_disconnect(rp)
+ struct rawcb *rp;
+{
+
+#ifdef notdef
+ if (rp->rcb_faddr)
+ m_freem(dtom(rp->rcb_faddr));
+ rp->rcb_faddr = 0;
+#endif
+ if (rp->rcb_socket->so_state & SS_NOFDREF)
+ raw_detach(rp);
+}
+
+#ifdef notdef
+int
+raw_bind(so, nam)
+ register struct socket *so;
+ struct mbuf *nam;
+{
+ struct sockaddr *addr = mtod(nam, struct sockaddr *);
+ register struct rawcb *rp;
+
+ if (ifnet == 0)
+ return (EADDRNOTAVAIL);
+ rp = sotorawcb(so);
+ nam = m_copym(nam, 0, M_COPYALL, M_WAITOK);
+ rp->rcb_laddr = mtod(nam, struct sockaddr *);
+ return (0);
+}
+#endif
diff --git a/cpukit/libnetworking/net/raw_cb.h b/cpukit/libnetworking/net/raw_cb.h
new file mode 100644
index 0000000000..ee8f14e822
--- /dev/null
+++ b/cpukit/libnetworking/net/raw_cb.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1980, 1986, 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.
+ *
+ * @(#)raw_cb.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NET_RAW_CB_H_
+#define _NET_RAW_CB_H_
+
+/*
+ * Raw protocol interface control block. Used
+ * to tie a socket to the generic raw interface.
+ */
+struct rawcb {
+ struct rawcb *rcb_next; /* doubly linked list */
+ struct rawcb *rcb_prev;
+ struct socket *rcb_socket; /* back pointer to socket */
+ struct sockaddr *rcb_faddr; /* destination address */
+ struct sockaddr *rcb_laddr; /* socket's address */
+ struct sockproto rcb_proto; /* protocol family, protocol */
+};
+
+#define sotorawcb(so) ((struct rawcb *)(so)->so_pcb)
+
+/*
+ * Nominal space allocated to a raw socket.
+ */
+#define RAWSNDQ 8192
+#define RAWRCVQ 8192
+
+#ifdef _KERNEL
+extern struct rawcb rawcb; /* head of list */
+
+int raw_attach __P((struct socket *, int));
+void raw_ctlinput __P((int, struct sockaddr *, void *));
+void raw_detach __P((struct rawcb *));
+void raw_disconnect __P((struct rawcb *));
+void raw_init __P((void));
+void raw_input __P((struct mbuf *,
+ struct sockproto *, struct sockaddr *, struct sockaddr *));
+int raw_usrreq __P((struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *));
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/net/raw_usrreq.c b/cpukit/libnetworking/net/raw_usrreq.c
new file mode 100644
index 0000000000..fb4faf4d6d
--- /dev/null
+++ b/cpukit/libnetworking/net/raw_usrreq.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 1980, 1986, 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.
+ *
+ * @(#)raw_usrreq.c 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/netisr.h>
+#include <net/raw_cb.h>
+
+/*
+ * Initialize raw connection block q.
+ */
+void
+raw_init()
+{
+
+ rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
+}
+
+
+/*
+ * Raw protocol input routine. Find the socket
+ * associated with the packet(s) and move them over. If
+ * nothing exists for this packet, drop it.
+ */
+/*
+ * Raw protocol interface.
+ */
+void
+raw_input(m0, proto, src, dst)
+ struct mbuf *m0;
+ register struct sockproto *proto;
+ struct sockaddr *src, *dst;
+{
+ register struct rawcb *rp;
+ register struct mbuf *m = m0;
+ register int sockets = 0;
+ struct socket *last;
+
+ last = 0;
+ for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
+ if (rp->rcb_proto.sp_family != proto->sp_family)
+ continue;
+ if (rp->rcb_proto.sp_protocol &&
+ rp->rcb_proto.sp_protocol != proto->sp_protocol)
+ continue;
+ /*
+ * We assume the lower level routines have
+ * placed the address in a canonical format
+ * suitable for a structure comparison.
+ *
+ * Note that if the lengths are not the same
+ * the comparison will fail at the first byte.
+ */
+#define equal(a1, a2) \
+ (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
+ if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
+ continue;
+ if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
+ continue;
+ if (last) {
+ struct mbuf *n;
+ n = m_copy(m, 0, (int)M_COPYALL);
+ if (n) {
+ if (sbappendaddr(&last->so_rcv, src,
+ n, (struct mbuf *)0) == 0)
+ /* should notify about lost packet */
+ m_freem(n);
+ else {
+ sorwakeup(last);
+ sockets++;
+ }
+ }
+ }
+ last = rp->rcb_socket;
+ }
+ if (last) {
+ if (sbappendaddr(&last->so_rcv, src,
+ m, (struct mbuf *)0) == 0)
+ m_freem(m);
+ else {
+ sorwakeup(last);
+ sockets++;
+ }
+ } else
+ m_freem(m);
+}
+
+/*ARGSUSED*/
+void
+raw_ctlinput(cmd, arg, dummy)
+ int cmd;
+ struct sockaddr *arg;
+ void *dummy;
+{
+
+ if (cmd < 0 || cmd > PRC_NCMDS)
+ return;
+ /* INCOMPLETE */
+}
+
+/*ARGSUSED*/
+int
+raw_usrreq(so, req, m, nam, control)
+ struct socket *so;
+ int req;
+ struct mbuf *m, *nam, *control;
+{
+ register struct rawcb *rp = sotorawcb(so);
+ register int error = 0;
+ int len;
+
+ if (req == PRU_CONTROL)
+ return (EOPNOTSUPP);
+ if (control && control->m_len) {
+ error = EOPNOTSUPP;
+ goto release;
+ }
+ if (rp == 0) {
+ error = EINVAL;
+ goto release;
+ }
+ switch (req) {
+
+ /*
+ * Allocate a raw control block and fill in the
+ * necessary info to allow packets to be routed to
+ * the appropriate raw interface routine.
+ */
+ case PRU_ATTACH:
+ if ((so->so_state & SS_PRIV) == 0) {
+ error = EACCES;
+ break;
+ }
+ error = raw_attach(so, (int)nam);
+ break;
+
+ /*
+ * Destroy state just before socket deallocation.
+ * Flush data or not depending on the options.
+ */
+ case PRU_DETACH:
+ if (rp == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ raw_detach(rp);
+ break;
+
+ /*
+ * If a socket isn't bound to a single address,
+ * the raw input routine will hand it anything
+ * within that protocol family (assuming there's
+ * nothing else around it should go to).
+ */
+ case PRU_CONNECT:
+ error = EINVAL;
+#if 0
+ if (rp->rcb_faddr) {
+ error = EISCONN;
+ break;
+ }
+ nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
+ rp->rcb_faddr = mtod(nam, struct sockaddr *);
+ soisconnected(so);
+#endif
+ break;
+
+ case PRU_BIND:
+ error = EINVAL;
+#if 0
+ if (rp->rcb_laddr) {
+ error = EINVAL; /* XXX */
+ break;
+ }
+ error = raw_bind(so, nam);
+#endif
+ break;
+
+ case PRU_CONNECT2:
+ error = EOPNOTSUPP;
+ goto release;
+
+ case PRU_DISCONNECT:
+ if (rp->rcb_faddr == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ raw_disconnect(rp);
+ soisdisconnected(so);
+ break;
+
+ /*
+ * Mark the connection as being incapable of further input.
+ */
+ case PRU_SHUTDOWN:
+ socantsendmore(so);
+ break;
+
+ /*
+ * Ship a packet out. The appropriate raw output
+ * routine handles any massaging necessary.
+ */
+ case PRU_SEND:
+ if (nam) {
+ if (rp->rcb_faddr) {
+ error = EISCONN;
+ break;
+ }
+ rp->rcb_faddr = mtod(nam, struct sockaddr *);
+ } else if (rp->rcb_faddr == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ error = (*so->so_proto->pr_output)(m, so);
+ m = NULL;
+ if (nam)
+ rp->rcb_faddr = 0;
+ break;
+
+ case PRU_ABORT:
+ raw_disconnect(rp);
+ sofree(so);
+ soisdisconnected(so);
+ break;
+
+ case PRU_SENSE:
+ /*
+ * stat: don't bother with a blocksize.
+ */
+ return (0);
+
+ /*
+ * Not supported.
+ */
+ case PRU_RCVOOB:
+ case PRU_RCVD:
+ return(EOPNOTSUPP);
+
+ case PRU_LISTEN:
+ case PRU_ACCEPT:
+ case PRU_SENDOOB:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_SOCKADDR:
+ if (rp->rcb_laddr == 0) {
+ error = EINVAL;
+ break;
+ }
+ len = rp->rcb_laddr->sa_len;
+ bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
+ nam->m_len = len;
+ break;
+
+ case PRU_PEERADDR:
+ if (rp->rcb_faddr == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ len = rp->rcb_faddr->sa_len;
+ bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
+ nam->m_len = len;
+ break;
+
+ default:
+ panic("raw_usrreq");
+ }
+release:
+ if (m != NULL)
+ m_freem(m);
+ return (error);
+}
diff --git a/cpukit/libnetworking/net/route.c b/cpukit/libnetworking/net/route.c
new file mode 100644
index 0000000000..e9a6eabe8d
--- /dev/null
+++ b/cpukit/libnetworking/net/route.c
@@ -0,0 +1,959 @@
+/*
+ * Copyright (c) 1980, 1986, 1991, 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.
+ *
+ * @(#)route.c 8.2 (Berkeley) 11/15/93
+ * $Id$
+ */
+
+#include "opt_mrouting.h"
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/raw_cb.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_mroute.h>
+
+#define SA(p) ((struct sockaddr *)(p))
+
+struct route_cb route_cb;
+static struct rtstat rtstat;
+struct radix_node_head *rt_tables[AF_MAX+1];
+
+static int rttrash; /* routes not in table but not freed */
+
+static void rt_maskedcopy __P((struct sockaddr *,
+ struct sockaddr *, struct sockaddr *));
+static void rtable_init __P((void **));
+
+static void
+rtable_init(table)
+ void **table;
+{
+ struct domain *dom;
+ for (dom = domains; dom; dom = dom->dom_next)
+ if (dom->dom_rtattach)
+ dom->dom_rtattach(&table[dom->dom_family],
+ dom->dom_rtoffset);
+}
+
+void
+route_init()
+{
+ rn_init(); /* initialize all zeroes, all ones, mask table */
+ rtable_init((void **)rt_tables);
+}
+
+/*
+ * Packet routing routines.
+ */
+void
+rtalloc(ro)
+ register struct route *ro;
+{
+ if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
+ return; /* XXX */
+ ro->ro_rt = rtalloc1(&ro->ro_dst, 1, 0UL);
+}
+
+void
+rtalloc_ign(ro, ignore)
+ register struct route *ro;
+ u_long ignore;
+{
+ if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
+ return; /* XXX */
+ ro->ro_rt = rtalloc1(&ro->ro_dst, 1, ignore);
+}
+
+/*
+ * Look up the route that matches the address given
+ * Or, at least try.. Create a cloned route if needed.
+ */
+struct rtentry *
+rtalloc1(dst, report, ignflags)
+ register struct sockaddr *dst;
+ int report;
+ u_long ignflags;
+{
+ register struct radix_node_head *rnh = rt_tables[dst->sa_family];
+ register struct rtentry *rt;
+ register struct radix_node *rn;
+ struct rtentry *newrt = 0;
+ struct rt_addrinfo info;
+ u_long nflags;
+ int s = splnet(), err = 0, msgtype = RTM_MISS;
+
+ /*
+ * Look up the address in the table for that Address Family
+ */
+ if (rnh && (rn = rnh->rnh_matchaddr((caddr_t)dst, rnh)) &&
+ ((rn->rn_flags & RNF_ROOT) == 0)) {
+ /*
+ * If we find it and it's not the root node, then
+ * get a refernce on the rtentry associated.
+ */
+ newrt = rt = (struct rtentry *)rn;
+ nflags = rt->rt_flags & ~ignflags;
+ if (report && (nflags & (RTF_CLONING | RTF_PRCLONING))) {
+ /*
+ * We are apparently adding (report = 0 in delete).
+ * If it requires that it be cloned, do so.
+ * (This implies it wasn't a HOST route.)
+ */
+ err = rtrequest(RTM_RESOLVE, dst, SA(0),
+ SA(0), 0, &newrt);
+ if (err) {
+ /*
+ * If the cloning didn't succeed, maybe
+ * what we have will do. Return that.
+ */
+ newrt = rt;
+ rt->rt_refcnt++;
+ goto miss;
+ }
+ if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) {
+ /*
+ * If the new route specifies it be
+ * externally resolved, then go do that.
+ */
+ msgtype = RTM_RESOLVE;
+ goto miss;
+ }
+ } else
+ rt->rt_refcnt++;
+ } else {
+ /*
+ * Either we hit the root or couldn't find any match,
+ * Which basically means
+ * "caint get there frm here"
+ */
+ rtstat.rts_unreach++;
+ miss: if (report) {
+ /*
+ * If required, report the failure to the supervising
+ * Authorities.
+ * For a delete, this is not an error. (report == 0)
+ */
+ bzero((caddr_t)&info, sizeof(info));
+ info.rti_info[RTAX_DST] = dst;
+ rt_missmsg(msgtype, &info, 0, err);
+ }
+ }
+ splx(s);
+ return (newrt);
+}
+
+void
+rtfree(rt)
+ register struct rtentry *rt;
+{
+ register struct radix_node_head *rnh =
+ rt_tables[rt_key(rt)->sa_family];
+ register struct ifaddr *ifa;
+
+ if (rt == 0 || rnh == 0)
+ panic("rtfree");
+ rt->rt_refcnt--;
+ if(rnh->rnh_close && rt->rt_refcnt == 0) {
+ rnh->rnh_close((struct radix_node *)rt, rnh);
+ }
+ if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_UP) == 0) {
+ if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT))
+ panic ("rtfree 2");
+ rttrash--;
+ if (rt->rt_refcnt < 0) {
+ printf("rtfree: %p not freed (neg refs)\n", rt);
+ return;
+ }
+ ifa = rt->rt_ifa;
+ IFAFREE(ifa);
+ if (rt->rt_parent) {
+ RTFREE(rt->rt_parent);
+ }
+ Free(rt_key(rt));
+ Free(rt);
+ }
+}
+
+void
+ifafree(ifa)
+ register struct ifaddr *ifa;
+{
+ if (ifa == NULL)
+ panic("ifafree");
+ if (ifa->ifa_refcnt == 0)
+ free(ifa, M_IFADDR);
+ else
+ ifa->ifa_refcnt--;
+}
+
+/*
+ * Force a routing table entry to the specified
+ * destination to go through the given gateway.
+ * Normally called as a result of a routing redirect
+ * message from the network layer.
+ *
+ * N.B.: must be called at splnet
+ *
+ */
+void
+rtredirect(dst, gateway, netmask, flags, src, rtp)
+ struct sockaddr *dst, *gateway, *netmask, *src;
+ int flags;
+ struct rtentry **rtp;
+{
+ register struct rtentry *rt;
+ int error = 0;
+ short *stat = 0;
+ struct rt_addrinfo info;
+ struct ifaddr *ifa;
+
+ /* verify the gateway is directly reachable */
+ if ((ifa = ifa_ifwithnet(gateway)) == 0) {
+ error = ENETUNREACH;
+ goto out;
+ }
+ rt = rtalloc1(dst, 0, 0UL);
+ /*
+ * If the redirect isn't from our current router for this dst,
+ * it's either old or wrong. If it redirects us to ourselves,
+ * we have a routing loop, perhaps as a result of an interface
+ * going down recently.
+ */
+#define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
+ if (!(flags & RTF_DONE) && rt &&
+ (!equal(src, rt->rt_gateway) || rt->rt_ifa != ifa))
+ error = EINVAL;
+ else if (ifa_ifwithaddr(gateway))
+ error = EHOSTUNREACH;
+ if (error)
+ goto done;
+ /*
+ * Create a new entry if we just got back a wildcard entry
+ * or the the lookup failed. This is necessary for hosts
+ * which use routing redirects generated by smart gateways
+ * to dynamically build the routing tables.
+ */
+ if ((rt == 0) || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
+ goto create;
+ /*
+ * Don't listen to the redirect if it's
+ * for a route to an interface.
+ */
+ if (rt->rt_flags & RTF_GATEWAY) {
+ if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
+ /*
+ * Changing from route to net => route to host.
+ * Create new route, rather than smashing route to net.
+ */
+ create:
+ flags |= RTF_GATEWAY | RTF_DYNAMIC;
+ error = rtrequest((int)RTM_ADD, dst, gateway,
+ netmask, flags,
+ (struct rtentry **)0);
+ stat = &rtstat.rts_dynamic;
+ } else {
+ /*
+ * Smash the current notion of the gateway to
+ * this destination. Should check about netmask!!!
+ */
+ rt->rt_flags |= RTF_MODIFIED;
+ flags |= RTF_MODIFIED;
+ stat = &rtstat.rts_newgateway;
+ rt_setgate(rt, rt_key(rt), gateway);
+ }
+ } else
+ error = EHOSTUNREACH;
+done:
+ if (rt) {
+ if (rtp && !error)
+ *rtp = rt;
+ else
+ rtfree(rt);
+ }
+out:
+ if (error)
+ rtstat.rts_badredirect++;
+ else if (stat != NULL)
+ (*stat)++;
+ bzero((caddr_t)&info, sizeof(info));
+ info.rti_info[RTAX_DST] = dst;
+ info.rti_info[RTAX_GATEWAY] = gateway;
+ info.rti_info[RTAX_NETMASK] = netmask;
+ info.rti_info[RTAX_AUTHOR] = src;
+ rt_missmsg(RTM_REDIRECT, &info, flags, error);
+}
+
+/*
+* Routing table ioctl interface.
+*/
+int
+rtioctl(req, data, p)
+ int req;
+ caddr_t data;
+ struct proc *p;
+{
+#ifdef INET
+ /* Multicast goop, grrr... */
+#ifdef MROUTING
+ return mrt_ioctl(req, data);
+#else
+ return mrt_ioctl(req, data, p);
+#endif
+#else /* INET */
+ return ENXIO;
+#endif /* INET */
+}
+
+struct ifaddr *
+ifa_ifwithroute(flags, dst, gateway)
+ int flags;
+ struct sockaddr *dst, *gateway;
+{
+ register struct ifaddr *ifa;
+ if ((flags & RTF_GATEWAY) == 0) {
+ /*
+ * If we are adding a route to an interface,
+ * and the interface is a pt to pt link
+ * we should search for the destination
+ * as our clue to the interface. Otherwise
+ * we can use the local address.
+ */
+ ifa = 0;
+ if (flags & RTF_HOST) {
+ ifa = ifa_ifwithdstaddr(dst);
+ }
+ if (ifa == 0)
+ ifa = ifa_ifwithaddr(gateway);
+ } else {
+ /*
+ * If we are adding a route to a remote net
+ * or host, the gateway may still be on the
+ * other end of a pt to pt link.
+ */
+ ifa = ifa_ifwithdstaddr(gateway);
+ }
+ if (ifa == 0)
+ ifa = ifa_ifwithnet(gateway);
+ if (ifa == 0) {
+ struct rtentry *rt = rtalloc1(dst, 0, 0UL);
+ if (rt == 0)
+ return (0);
+ rt->rt_refcnt--;
+ if ((ifa = rt->rt_ifa) == 0)
+ return (0);
+ }
+ if (ifa->ifa_addr->sa_family != dst->sa_family) {
+ struct ifaddr *oifa = ifa;
+ ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
+ if (ifa == 0)
+ ifa = oifa;
+ }
+ return (ifa);
+}
+
+#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+
+static int rt_fixdelete(struct radix_node *, void *);
+static int rt_fixchange(struct radix_node *, void *);
+
+struct rtfc_arg {
+ struct rtentry *rt0;
+ struct radix_node_head *rnh;
+};
+
+/*
+ * Do appropriate manipulations of a routing tree given
+ * all the bits of info needed
+ */
+int
+rtrequest(req, dst, gateway, netmask, flags, ret_nrt)
+ int req, flags;
+ struct sockaddr *dst, *gateway, *netmask;
+ struct rtentry **ret_nrt;
+{
+ int s = splnet(); int error = 0;
+ register struct rtentry *rt;
+ register struct radix_node *rn;
+ register struct radix_node_head *rnh;
+ struct ifaddr *ifa;
+ struct sockaddr *ndst;
+#define senderr(x) { error = x ; goto bad; }
+
+ /*
+ * Find the correct routing tree to use for this Address Family
+ */
+ if ((rnh = rt_tables[dst->sa_family]) == 0)
+ senderr(ESRCH);
+ /*
+ * If we are adding a host route then we don't want to put
+ * a netmask in the tree
+ */
+ if (flags & RTF_HOST)
+ netmask = 0;
+ switch (req) {
+ case RTM_DELETE:
+ /*
+ * Remove the item from the tree and return it.
+ * Complain if it is not there and do no more processing.
+ */
+ if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == 0)
+ senderr(ESRCH);
+ if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
+ panic ("rtrequest delete");
+ rt = (struct rtentry *)rn;
+
+ /*
+ * Now search what's left of the subtree for any cloned
+ * routes which might have been formed from this node.
+ */
+ if ((rt->rt_flags & RTF_PRCLONING) && netmask) {
+ rnh->rnh_walktree_from(rnh, dst, netmask,
+ rt_fixdelete, rt);
+ }
+
+ /*
+ * Remove any external references we may have.
+ * This might result in another rtentry being freed if
+ * we held it's last reference.
+ */
+ if (rt->rt_gwroute) {
+ rt = rt->rt_gwroute;
+ RTFREE(rt);
+ (rt = (struct rtentry *)rn)->rt_gwroute = 0;
+ }
+
+ /*
+ * NB: RTF_UP must be set during the search above,
+ * because we might delete the last ref, causing
+ * rt to get freed prematurely.
+ */
+ rt->rt_flags &= ~RTF_UP;
+
+ /*
+ * If there is llinfo or similar associated with the
+ * route, give the interface a chance to deal with it..
+ */
+ if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
+ ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0));
+ rttrash++;
+ /*
+ * If the caller wants it, then it can have it, but it's up to it
+ * to free the rtentry as we won't be doing it.
+ */
+ if (ret_nrt)
+ *ret_nrt = rt;
+ else if (rt->rt_refcnt <= 0) {
+ rt->rt_refcnt++; /* make a 1->0 transition */
+ rtfree(rt);
+ }
+ break;
+
+ case RTM_RESOLVE:
+ if (ret_nrt == 0 || (rt = *ret_nrt) == 0)
+ senderr(EINVAL);
+ ifa = rt->rt_ifa;
+ flags = rt->rt_flags &
+ ~(RTF_CLONING | RTF_PRCLONING | RTF_STATIC);
+ flags |= RTF_WASCLONED;
+ gateway = rt->rt_gateway;
+ if ((netmask = rt->rt_genmask) == 0)
+ flags |= RTF_HOST;
+ goto makeroute;
+
+ case RTM_ADD:
+ if ((flags & RTF_GATEWAY) && !gateway)
+ panic("rtrequest: GATEWAY but no gateway");
+
+ if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == 0)
+ senderr(ENETUNREACH);
+
+ makeroute:
+ R_Malloc(rt, struct rtentry *, sizeof(*rt));
+ if (rt == 0)
+ senderr(ENOBUFS);
+ Bzero(rt, sizeof(*rt));
+ rt->rt_flags = RTF_UP | flags;
+ if ((error = rt_setgate(rt, dst, gateway))) {
+ Free(rt);
+ senderr(error);
+ }
+ ndst = rt_key(rt);
+ if (netmask) {
+ rt_maskedcopy(dst, ndst, netmask);
+ } else
+ Bcopy(dst, ndst, dst->sa_len);
+
+ /*
+ * This moved from below so that rnh->rnh_addaddr() can
+ * examine the ifa and ifp if it so desires.
+ */
+ ifa->ifa_refcnt++;
+ rt->rt_ifa = ifa;
+ rt->rt_ifp = ifa->ifa_ifp;
+
+ rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask,
+ rnh, rt->rt_nodes);
+ if (rn == 0) {
+ struct rtentry *rt2;
+ /*
+ * Uh-oh, we already have one of these in the tree.
+ * We do a special hack: if the route that's already
+ * there was generated by the protocol-cloning
+ * mechanism, then we just blow it away and retry
+ * the insertion of the new one.
+ */
+ rt2 = rtalloc1(dst, 0, RTF_PRCLONING);
+ if (rt2 && rt2->rt_parent) {
+ rtrequest(RTM_DELETE,
+ (struct sockaddr *)rt_key(rt2),
+ rt2->rt_gateway,
+ rt_mask(rt2), rt2->rt_flags, 0);
+ RTFREE(rt2);
+ rn = rnh->rnh_addaddr((caddr_t)ndst,
+ (caddr_t)netmask,
+ rnh, rt->rt_nodes);
+ } else if (rt2) {
+ RTFREE(rt2);
+ }
+ }
+
+ if (rn == 0) {
+ if (rt->rt_gwroute)
+ rtfree(rt->rt_gwroute);
+ if (rt->rt_ifa) {
+ IFAFREE(rt->rt_ifa);
+ }
+ Free(rt_key(rt));
+ Free(rt);
+ senderr(EEXIST);
+ }
+ rt->rt_parent = 0;
+
+ if (req == RTM_RESOLVE) {
+ rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */
+ if ((*ret_nrt)->rt_flags & RTF_PRCLONING) {
+ rt->rt_parent = (*ret_nrt);
+ (*ret_nrt)->rt_refcnt++;
+ }
+ }
+ if (ifa->ifa_rtrequest)
+ ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0));
+ /*
+ * We repeat the same procedure from rt_setgate() here because
+ * it doesn't fire when we call it there because the node
+ * hasn't been added to the tree yet.
+ */
+ if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) {
+ struct rtfc_arg arg;
+ arg.rnh = rnh;
+ arg.rt0 = rt;
+ rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt),
+ rt_fixchange, &arg);
+ }
+
+ if (ret_nrt) {
+ *ret_nrt = rt;
+ rt->rt_refcnt++;
+ }
+ break;
+ }
+bad:
+ splx(s);
+ return (error);
+}
+
+/*
+ * Called from rtrequest(RTM_DELETE, ...) to fix up the route's ``family''
+ * (i.e., the routes related to it by the operation of cloning). This
+ * routine is iterated over all potential former-child-routes by way of
+ * rnh->rnh_walktree_from() above, and those that actually are children of
+ * the late parent (passed in as VP here) are themselves deleted.
+ */
+static int
+rt_fixdelete(struct radix_node *rn, void *vp)
+{
+ struct rtentry *rt = (struct rtentry *)rn;
+ struct rtentry *rt0 = vp;
+
+ if (rt->rt_parent == rt0 && !(rt->rt_flags & RTF_PINNED)) {
+ return rtrequest(RTM_DELETE, rt_key(rt),
+ (struct sockaddr *)0, rt_mask(rt),
+ rt->rt_flags, (struct rtentry **)0);
+ }
+ return 0;
+}
+
+/*
+ * This routine is called from rt_setgate() to do the analogous thing for
+ * adds and changes. There is the added complication in this case of a
+ * middle insert; i.e., insertion of a new network route between an older
+ * network route and (cloned) host routes. For this reason, a simple check
+ * of rt->rt_parent is insufficient; each candidate route must be tested
+ * against the (mask, value) of the new route (passed as before in vp)
+ * to see if the new route matches it. Unfortunately, this has the obnoxious
+ * property of also triggering for insertion /above/ a pre-existing network
+ * route and clones. Sigh. This may be fixed some day.
+ *
+ * XXX - it may be possible to do fixdelete() for changes and reserve this
+ * routine just for adds. I'm not sure why I thought it was necessary to do
+ * changes this way.
+ */
+#ifdef DEBUG
+int rtfcdebug = 0;
+#endif
+
+static int
+rt_fixchange(struct radix_node *rn, void *vp)
+{
+ struct rtentry *rt = (struct rtentry *)rn;
+ struct rtfc_arg *ap = vp;
+ struct rtentry *rt0 = ap->rt0;
+ struct radix_node_head *rnh = ap->rnh;
+ u_char *xk1, *xm1, *xk2;
+ int i, len;
+
+#ifdef DEBUG
+ if (rtfcdebug)
+ printf("rt_fixchange: rt %p, rt0 %p\n", rt, rt0);
+#endif
+
+ if (!rt->rt_parent || (rt->rt_flags & RTF_PINNED)) {
+#ifdef DEBUG
+ if(rtfcdebug) printf("no parent or pinned\n");
+#endif
+ return 0;
+ }
+
+ if (rt->rt_parent == rt0) {
+#ifdef DEBUG
+ if(rtfcdebug) printf("parent match\n");
+#endif
+ return rtrequest(RTM_DELETE, rt_key(rt),
+ (struct sockaddr *)0, rt_mask(rt),
+ rt->rt_flags, (struct rtentry **)0);
+ }
+
+ /*
+ * There probably is a function somewhere which does this...
+ * if not, there should be.
+ */
+ len = imin(((struct sockaddr *)rt_key(rt0))->sa_len,
+ ((struct sockaddr *)rt_key(rt))->sa_len);
+
+ xk1 = (u_char *)rt_key(rt0);
+ xm1 = (u_char *)rt_mask(rt0);
+ xk2 = (u_char *)rt_key(rt);
+
+ for (i = rnh->rnh_treetop->rn_offset; i < len; i++) {
+ if ((xk2[i] & xm1[i]) != xk1[i]) {
+#ifdef DEBUG
+ if(rtfcdebug) printf("no match\n");
+#endif
+ return 0;
+ }
+ }
+
+ /*
+ * OK, this node is a clone, and matches the node currently being
+ * changed/added under the node's mask. So, get rid of it.
+ */
+#ifdef DEBUG
+ if(rtfcdebug) printf("deleting\n");
+#endif
+ return rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0,
+ rt_mask(rt), rt->rt_flags, (struct rtentry **)0);
+}
+
+int
+rt_setgate(rt0, dst, gate)
+ struct rtentry *rt0;
+ struct sockaddr *dst, *gate;
+{
+ caddr_t new, old;
+ int dlen = ROUNDUP(dst->sa_len), glen = ROUNDUP(gate->sa_len);
+ register struct rtentry *rt = rt0;
+ struct radix_node_head *rnh = rt_tables[dst->sa_family];
+
+ /*
+ * A host route with the destination equal to the gateway
+ * will interfere with keeping LLINFO in the routing
+ * table, so disallow it.
+ */
+ if (((rt0->rt_flags & (RTF_HOST|RTF_GATEWAY|RTF_LLINFO)) ==
+ (RTF_HOST|RTF_GATEWAY)) &&
+ (dst->sa_len == gate->sa_len) &&
+ (bcmp(dst, gate, dst->sa_len) == 0)) {
+ /*
+ * The route might already exist if this is an RTM_CHANGE
+ * or a routing redirect, so try to delete it.
+ */
+ if (rt_key(rt0))
+ rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt0),
+ rt0->rt_gateway, rt_mask(rt0), rt0->rt_flags, 0);
+ return EADDRNOTAVAIL;
+ }
+
+ if (rt->rt_gateway == 0 || glen > ROUNDUP(rt->rt_gateway->sa_len)) {
+ old = (caddr_t)rt_key(rt);
+ R_Malloc(new, caddr_t, dlen + glen);
+ if (new == 0)
+ return ENOBUFS;
+ rt->rt_nodes->rn_key = new;
+ } else {
+ new = rt->rt_nodes->rn_key;
+ old = 0;
+ }
+ Bcopy(gate, (rt->rt_gateway = (struct sockaddr *)(new + dlen)), glen);
+ if (old) {
+ Bcopy(dst, new, dlen);
+ Free(old);
+ }
+ if (rt->rt_gwroute) {
+ rt = rt->rt_gwroute; RTFREE(rt);
+ rt = rt0; rt->rt_gwroute = 0;
+ }
+ /*
+ * Cloning loop avoidance:
+ * In the presence of protocol-cloning and bad configuration,
+ * it is possible to get stuck in bottomless mutual recursion
+ * (rtrequest rt_setgate rtalloc1). We avoid this by not allowing
+ * protocol-cloning to operate for gateways (which is probably the
+ * correct choice anyway), and avoid the resulting reference loops
+ * by disallowing any route to run through itself as a gateway.
+ * This is obviuosly mandatory when we get rt->rt_output().
+ */
+ if (rt->rt_flags & RTF_GATEWAY) {
+ rt->rt_gwroute = rtalloc1(gate, 1, RTF_PRCLONING);
+ if (rt->rt_gwroute == rt) {
+ RTFREE(rt->rt_gwroute);
+ rt->rt_gwroute = 0;
+ return EDQUOT; /* failure */
+ }
+ }
+
+ /*
+ * This isn't going to do anything useful for host routes, so
+ * don't bother. Also make sure we have a reasonable mask
+ * (we don't yet have one during adds).
+ */
+ if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) {
+ struct rtfc_arg arg;
+ arg.rnh = rnh;
+ arg.rt0 = rt;
+ rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt),
+ rt_fixchange, &arg);
+ }
+
+ return 0;
+}
+
+static void
+rt_maskedcopy(src, dst, netmask)
+ struct sockaddr *src, *dst, *netmask;
+{
+ register u_char *cp1 = (u_char *)src;
+ register u_char *cp2 = (u_char *)dst;
+ register u_char *cp3 = (u_char *)netmask;
+ u_char *cplim = cp2 + *cp3;
+ u_char *cplim2 = cp2 + *cp1;
+
+ *cp2++ = *cp1++; *cp2++ = *cp1++; /* copies sa_len & sa_family */
+ cp3 += 2;
+ if (cplim > cplim2)
+ cplim = cplim2;
+ while (cp2 < cplim)
+ *cp2++ = *cp1++ & *cp3++;
+ if (cp2 < cplim2)
+ bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2));
+}
+
+/*
+ * Set up a routing table entry, normally
+ * for an interface.
+ */
+int
+rtinit(ifa, cmd, flags)
+ register struct ifaddr *ifa;
+ int cmd, flags;
+{
+ register struct rtentry *rt;
+ register struct sockaddr *dst;
+ register struct sockaddr *deldst;
+ struct mbuf *m = 0;
+ struct rtentry *nrt = 0;
+ int error;
+
+ dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
+ /*
+ * If it's a delete, check that if it exists, it's on the correct
+ * interface or we might scrub a route to another ifa which would
+ * be confusing at best and possibly worse.
+ */
+ if (cmd == RTM_DELETE) {
+ /*
+ * It's a delete, so it should already exist..
+ * If it's a net, mask off the host bits
+ * (Assuming we have a mask)
+ */
+ if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
+ m = m_get(M_WAIT, MT_SONAME);
+ deldst = mtod(m, struct sockaddr *);
+ rt_maskedcopy(dst, deldst, ifa->ifa_netmask);
+ dst = deldst;
+ }
+ /*
+ * Get an rtentry that is in the routing tree and
+ * contains the correct info. (if this fails we can't get there).
+ * We set "report" to FALSE so that if it doesn't exist,
+ * it doesn't report an error or clone a route, etc. etc.
+ */
+ rt = rtalloc1(dst, 0, 0UL);
+ if (rt) {
+ /*
+ * Ok so we found the rtentry. it has an extra reference
+ * for us at this stage. we won't need that so
+ * lop that off now.
+ */
+ rt->rt_refcnt--;
+ if (rt->rt_ifa != ifa) {
+ /*
+ * If the interface in the rtentry doesn't match
+ * the interface we are using, then we don't
+ * want to delete it, so return an error.
+ * This seems to be the only point of
+ * this whole RTM_DELETE clause.
+ */
+ if (m)
+ (void) m_free(m);
+ return (flags & RTF_HOST ? EHOSTUNREACH
+ : ENETUNREACH);
+ }
+ }
+ /* XXX */
+#if 0
+ else {
+ /*
+ * One would think that as we are deleting, and we know
+ * it doesn't exist, we could just return at this point
+ * with an "ELSE" clause, but apparently not..
+ */
+ return (flags & RTF_HOST ? EHOSTUNREACH
+ : ENETUNREACH);
+ }
+#endif
+ }
+ /*
+ * Do the actual request
+ */
+ error = rtrequest(cmd, dst, ifa->ifa_addr, ifa->ifa_netmask,
+ flags | ifa->ifa_flags, &nrt);
+ if (m)
+ (void) m_free(m);
+ /*
+ * If we are deleting, and we found an entry, then
+ * it's been removed from the tree.. now throw it away.
+ */
+ if (cmd == RTM_DELETE && error == 0 && (rt = nrt)) {
+ /*
+ * notify any listenning routing agents of the change
+ */
+ rt_newaddrmsg(cmd, ifa, error, nrt);
+ if (rt->rt_refcnt <= 0) {
+ rt->rt_refcnt++; /* need a 1->0 transition to free */
+ rtfree(rt);
+ }
+ }
+
+ /*
+ * We are adding, and we have a returned routing entry.
+ * We need to sanity check the result.
+ */
+ if (cmd == RTM_ADD && error == 0 && (rt = nrt)) {
+ /*
+ * We just wanted to add it.. we don't actually need a reference
+ */
+ rt->rt_refcnt--;
+ /*
+ * If it came back with an unexpected interface, then it must
+ * have already existed or something. (XXX)
+ */
+ if (rt->rt_ifa != ifa) {
+ printf("rtinit: wrong ifa (%p) was (%p)\n", ifa,
+ rt->rt_ifa);
+ /*
+ * Ask that the route we got back be removed
+ * from the routing tables as we are trying
+ * to supersede it.
+ */
+ if (rt->rt_ifa->ifa_rtrequest)
+ rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0));
+ /*
+ * Remove the referenve to the it's ifaddr.
+ */
+ IFAFREE(rt->rt_ifa);
+ /*
+ * And substitute in references to the ifaddr
+ * we are adding.
+ */
+ rt->rt_ifa = ifa;
+ rt->rt_ifp = ifa->ifa_ifp;
+ ifa->ifa_refcnt++;
+ /*
+ * Now add it to the routing table
+ * XXX could we have just left it?
+ * as it might have been in the right place..
+ */
+ if (ifa->ifa_rtrequest)
+ ifa->ifa_rtrequest(RTM_ADD, rt, SA(0));
+ }
+ /*
+ * notify any listenning routing agents of the change
+ */
+ rt_newaddrmsg(cmd, ifa, error, nrt);
+ }
+ return (error);
+}
diff --git a/cpukit/libnetworking/net/route.h b/cpukit/libnetworking/net/route.h
new file mode 100644
index 0000000000..bb64d150c8
--- /dev/null
+++ b/cpukit/libnetworking/net/route.h
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 1980, 1986, 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.
+ * 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.
+ *
+ * @(#)route.h 8.4 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/net/route.h,v 1.62 2004/10/05 19:48:33 sam Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NET_ROUTE_H_
+#define _NET_ROUTE_H_
+
+/*
+ * Kernel resident routing tables.
+ *
+ * The routing tables are initialized when interface addresses
+ * are set by making entries for all directly connected interfaces.
+ */
+
+/*
+ * A route consists of a destination address and a reference
+ * to a routing entry. These are often held by protocols
+ * in their control blocks, e.g. inpcb.
+ */
+struct route {
+ struct rtentry *ro_rt;
+ struct sockaddr ro_dst;
+};
+
+/*
+ * These numbers are used by reliable protocols for determining
+ * retransmission behavior and are included in the routing structure.
+ */
+struct rt_metrics_lite {
+ u_long rmx_mtu; /* MTU for this path */
+ u_long rmx_expire; /* lifetime for route, e.g. redirect */
+ u_long rmx_pksent; /* packets sent using this route */
+};
+
+struct rt_metrics {
+ u_long rmx_locks; /* Kernel must leave these values alone */
+ u_long rmx_mtu; /* MTU for this path */
+ u_long rmx_hopcount; /* max hops expected */
+ u_long rmx_expire; /* lifetime for route, e.g. redirect */
+ u_long rmx_recvpipe; /* inbound delay-bandwidth product */
+ u_long rmx_sendpipe; /* outbound delay-bandwidth product */
+ u_long rmx_ssthresh; /* outbound gateway buffer limit */
+ u_long rmx_rtt; /* estimated round trip time */
+ u_long rmx_rttvar; /* estimated rtt variance */
+ u_long rmx_pksent; /* packets sent using this route */
+ u_long rmx_filler[4]; /* will be used for T/TCP later */
+};
+
+/*
+ * rmx_rtt and rmx_rttvar are stored as microseconds;
+ * RTTTOPRHZ(rtt) converts to a value suitable for use
+ * by a protocol slowtimo counter.
+ */
+#define RTM_RTTUNIT 1000000 /* units for rtt, rttvar, as units per sec */
+#define RTTTOPRHZ(r) ((r) / (RTM_RTTUNIT / PR_SLOWHZ))
+
+/*
+ * XXX kernel function pointer `rt_output' is visible to applications.
+ */
+struct mbuf;
+
+/*
+ * We distinguish between routes to hosts and routes to networks,
+ * preferring the former if available. For each route we infer
+ * the interface to use from the gateway address supplied when
+ * the route was entered. Routes that forward packets through
+ * gateways are marked so that the output routines know to address the
+ * gateway rather than the ultimate destination.
+ */
+#ifndef RNF_NORMAL
+#include <net/radix.h>
+#endif
+struct rtentry {
+ struct radix_node rt_nodes[2]; /* tree glue, and other values */
+#define rt_key(r) ((struct sockaddr *)((r)->rt_nodes->rn_key))
+#define rt_mask(r) ((struct sockaddr *)((r)->rt_nodes->rn_mask))
+ struct sockaddr *rt_gateway; /* value */
+ u_long rt_flags; /* up/down?, host/net */
+ struct ifnet *rt_ifp; /* the answer: interface to use */
+ struct ifaddr *rt_ifa; /* the answer: interface address to use */
+ struct rt_metrics rt_rmx; /* metrics used by rx'ing protocols */
+ long rt_refcnt; /* # held references */
+ struct sockaddr *rt_genmask; /* for generation of cloned routes */
+ caddr_t rt_llinfo; /* pointer to link level info cache */
+ struct rtentry *rt_gwroute; /* implied entry for gatewayed routes */
+ int (*rt_output) __P((struct ifnet *, struct mbuf *,
+ struct sockaddr *, struct rtentry *));
+ /* output routine for this (rt,if) */
+ struct rtentry *rt_parent; /* cloning parent of this route */
+};
+
+/*
+ * Following structure necessary for 4.3 compatibility;
+ * We should eventually move it to a compat file.
+ */
+struct ortentry {
+ u_long rt_hash; /* to speed lookups */
+ struct sockaddr rt_dst; /* key */
+ struct sockaddr rt_gateway; /* value */
+ short rt_flags; /* up/down?, host/net */
+ short rt_refcnt; /* # held references */
+ u_long rt_use; /* raw # packets forwarded */
+ struct ifnet *rt_ifp; /* the answer: interface to use */
+};
+
+#define rt_use rt_rmx.rmx_pksent
+
+#define RTF_UP 0x1 /* route usable */
+#define RTF_GATEWAY 0x2 /* destination is a gateway */
+#define RTF_HOST 0x4 /* host entry (net otherwise) */
+#define RTF_REJECT 0x8 /* host or net unreachable */
+#define RTF_DYNAMIC 0x10 /* created dynamically (by redirect) */
+#define RTF_MODIFIED 0x20 /* modified dynamically (by redirect) */
+#define RTF_DONE 0x40 /* message confirmed */
+/* 0x80 unused, was RTF_DELCLONE */
+#define RTF_CLONING 0x100 /* generate new routes on use */
+#define RTF_XRESOLVE 0x200 /* external daemon resolves name */
+#define RTF_LLINFO 0x400 /* generated by link layer (e.g. ARP) */
+#define RTF_STATIC 0x800 /* manually added */
+#define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */
+#define RTF_PROTO2 0x4000 /* protocol specific routing flag */
+#define RTF_PROTO1 0x8000 /* protocol specific routing flag */
+
+#define RTF_PRCLONING 0x10000 /* protocol requires cloning */
+#define RTF_WASCLONED 0x20000 /* route generated through cloning */
+#define RTF_PROTO3 0x40000 /* protocol specific routing flag */
+/* 0x80000 unused */
+#define RTF_PINNED 0x100000 /* future use */
+#define RTF_LOCAL 0x200000 /* route represents a local address */
+#define RTF_BROADCAST 0x400000 /* route represents a bcast address */
+#define RTF_MULTICAST 0x800000 /* route represents a mcast address */
+ /* 0x1000000 and up unassigned */
+
+/*
+ * Routing statistics.
+ */
+struct rtstat {
+ short rts_badredirect; /* bogus redirect calls */
+ short rts_dynamic; /* routes created by redirects */
+ short rts_newgateway; /* routes modified by redirects */
+ short rts_unreach; /* lookups which failed */
+ short rts_wildcard; /* lookups satisfied by a wildcard */
+};
+/*
+ * Structures for routing messages.
+ */
+struct rt_msghdr {
+ u_short rtm_msglen; /* to skip over non-understood messages */
+ u_char rtm_version; /* future binary compatibility */
+ u_char rtm_type; /* message type */
+ u_short rtm_index; /* index for associated ifp */
+ int rtm_flags; /* flags, incl. kern & message, e.g. DONE */
+ int rtm_addrs; /* bitmask identifying sockaddrs in msg */
+ pid_t rtm_pid; /* identify sender */
+ int rtm_seq; /* for sender to identify action */
+ int rtm_errno; /* why failed */
+ int rtm_use; /* from rtentry */
+ u_long rtm_inits; /* which metrics we are initializing */
+ struct rt_metrics rtm_rmx; /* metrics themselves */
+};
+
+#define RTM_VERSION 5 /* Up the ante and ignore older versions */
+
+/*
+ * Message types.
+ */
+#define RTM_ADD 0x1 /* Add Route */
+#define RTM_DELETE 0x2 /* Delete Route */
+#define RTM_CHANGE 0x3 /* Change Metrics or flags */
+#define RTM_GET 0x4 /* Report Metrics */
+#define RTM_LOSING 0x5 /* Kernel Suspects Partitioning */
+#define RTM_REDIRECT 0x6 /* Told to use different route */
+#define RTM_MISS 0x7 /* Lookup failed on this address */
+#define RTM_LOCK 0x8 /* fix specified metrics */
+#define RTM_OLDADD 0x9 /* caused by SIOCADDRT */
+#define RTM_OLDDEL 0xa /* caused by SIOCDELRT */
+#define RTM_RESOLVE 0xb /* req to resolve dst to LL addr */
+#define RTM_NEWADDR 0xc /* address being added to iface */
+#define RTM_DELADDR 0xd /* address being removed from iface */
+#define RTM_IFINFO 0xe /* iface going up/down etc. */
+#define RTM_NEWMADDR 0xf /* mcast group membership being added to if */
+#define RTM_DELMADDR 0x10 /* mcast group membership being deleted */
+#define RTM_IFANNOUNCE 0x11 /* iface arrival/departure */
+#define RTM_IEEE80211 0x12 /* IEEE80211 wireless event */
+
+/*
+ * Bitmask values for rtm_inits and rmx_locks.
+ */
+#define RTV_MTU 0x1 /* init or lock _mtu */
+#define RTV_HOPCOUNT 0x2 /* init or lock _hopcount */
+#define RTV_EXPIRE 0x4 /* init or lock _expire */
+#define RTV_RPIPE 0x8 /* init or lock _recvpipe */
+#define RTV_SPIPE 0x10 /* init or lock _sendpipe */
+#define RTV_SSTHRESH 0x20 /* init or lock _ssthresh */
+#define RTV_RTT 0x40 /* init or lock _rtt */
+#define RTV_RTTVAR 0x80 /* init or lock _rttvar */
+
+/*
+ * Bitmask values for rtm_addrs.
+ */
+#define RTA_DST 0x1 /* destination sockaddr present */
+#define RTA_GATEWAY 0x2 /* gateway sockaddr present */
+#define RTA_NETMASK 0x4 /* netmask sockaddr present */
+#define RTA_GENMASK 0x8 /* cloning mask sockaddr present */
+#define RTA_IFP 0x10 /* interface name sockaddr present */
+#define RTA_IFA 0x20 /* interface addr sockaddr present */
+#define RTA_AUTHOR 0x40 /* sockaddr for author of redirect */
+#define RTA_BRD 0x80 /* for NEWADDR, broadcast or p-p dest addr */
+
+/*
+ * Index offsets for sockaddr array for alternate internal encoding.
+ */
+#define RTAX_DST 0 /* destination sockaddr present */
+#define RTAX_GATEWAY 1 /* gateway sockaddr present */
+#define RTAX_NETMASK 2 /* netmask sockaddr present */
+#define RTAX_GENMASK 3 /* cloning mask sockaddr present */
+#define RTAX_IFP 4 /* interface name sockaddr present */
+#define RTAX_IFA 5 /* interface addr sockaddr present */
+#define RTAX_AUTHOR 6 /* sockaddr for author of redirect */
+#define RTAX_BRD 7 /* for NEWADDR, broadcast or p-p dest addr */
+#define RTAX_MAX 8 /* size of array to allocate */
+
+struct rt_addrinfo {
+ int rti_addrs;
+ struct sockaddr *rti_info[RTAX_MAX];
+};
+
+struct route_cb {
+ int ip_count;
+ int ipx_count;
+ int ns_count;
+ int iso_count;
+ int any_count;
+};
+
+#ifdef _KERNEL
+#define RTFREE(rt) \
+ do { \
+ if ((rt)->rt_refcnt <= 1) \
+ rtfree(rt); \
+ else \
+ (rt)->rt_refcnt--; \
+ } while (0)
+
+extern struct route_cb route_cb;
+extern struct radix_node_head *rt_tables[AF_MAX+1];
+
+void route_init __P((void));
+void rt_ifmsg(struct ifnet *);
+void rt_missmsg(int, struct rt_addrinfo *, int, int);
+void rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *);
+int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *);
+void rtalloc_ign __P((struct route *, unsigned long));
+void rtalloc(struct route *ro); /* XXX deprecated, use rtalloc_ign(ro, 0) */
+struct rtentry *
+ rtalloc1 __P((struct sockaddr *, int, unsigned long));
+void rtfree(struct rtentry *);
+int rtinit(struct ifaddr *, int, int);
+int rtioctl __P((int, caddr_t, struct proc *));
+void rtredirect(struct sockaddr *, struct sockaddr *,
+ struct sockaddr *, int, struct sockaddr *, struct rtentry **);
+int rtrequest(int, struct sockaddr *,
+ struct sockaddr *, struct sockaddr *, int, struct rtentry **);
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/net/rtsock.c b/cpukit/libnetworking/net/rtsock.c
new file mode 100644
index 0000000000..08b8bf5b1a
--- /dev/null
+++ b/cpukit/libnetworking/net/rtsock.c
@@ -0,0 +1,797 @@
+/*
+ * Copyright (c) 1988, 1991, 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.
+ * 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.
+ *
+ * @(#)rtsock.c 8.7 (Berkeley) 10/12/95
+ * $FreeBSD: src/sys/net/rtsock.c,v 1.122 2005/03/26 21:49:43 sam Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/raw_cb.h>
+
+static struct sockaddr route_dst = { 2, PF_ROUTE, };
+static struct sockaddr route_src = { 2, PF_ROUTE, };
+static struct sockaddr sa_zero = { sizeof(sa_zero), AF_INET, };
+static struct sockproto route_proto = { PF_ROUTE, };
+
+struct walkarg {
+ int w_tmemsize;
+ int w_op, w_arg;
+ caddr_t w_tmem;
+ struct sysctl_req *w_req;
+};
+
+static struct mbuf *rt_msg1(int type, struct rt_addrinfo *rtinfo);
+static int rt_msg2(int type, struct rt_addrinfo *rtinfo,
+ caddr_t cp, struct walkarg *w);
+static int rt_xaddrs(caddr_t cp, caddr_t cplim,
+ struct rt_addrinfo *rtinfo);
+static int sysctl_dumpentry(struct radix_node *rn, void *vw);
+static int sysctl_iflist(int af, struct walkarg *w);
+static int route_output(struct mbuf *m, struct socket *so);
+static int route_usrreq(struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *);
+static void rt_setmetrics(u_long which, const struct rt_metrics *in,
+ struct rt_metrics *out);
+
+/*ARGSUSED*/
+static int
+route_usrreq(so, req, m, nam, control)
+ struct socket *so;
+ int req;
+ struct mbuf *m, *nam, *control;
+{
+ int error = 0;
+ struct rawcb *rp = sotorawcb(so);
+ int s;
+
+ if (req == PRU_ATTACH) {
+ MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK);
+ so->so_pcb = (caddr_t)rp;
+ if (so->so_pcb)
+ bzero(so->so_pcb, sizeof(*rp));
+ }
+ if (req == PRU_DETACH && rp) {
+ int af = rp->rcb_proto.sp_protocol;
+ if (af == AF_INET)
+ route_cb.ip_count--;
+ else if (af == AF_IPX)
+ route_cb.ipx_count--;
+ else if (af == AF_ISO)
+ route_cb.iso_count--;
+ route_cb.any_count--;
+ }
+ s = splnet();
+ error = raw_usrreq(so, req, m, nam, control);
+ rp = sotorawcb(so);
+ if (req == PRU_ATTACH && rp) {
+ int af = rp->rcb_proto.sp_protocol;
+ if (error) {
+ free((caddr_t)rp, M_PCB);
+ splx(s);
+ return (error);
+ }
+ if (af == AF_INET)
+ route_cb.ip_count++;
+ else if (af == AF_IPX)
+ route_cb.ipx_count++;
+ else if (af == AF_ISO)
+ route_cb.iso_count++;
+ rp->rcb_faddr = &route_src;
+ route_cb.any_count++;
+ soisconnected(so);
+ so->so_options |= SO_USELOOPBACK;
+ }
+ splx(s);
+ return (error);
+}
+
+/*ARGSUSED*/
+static int
+route_output(struct mbuf *m, struct socket *so)
+{
+#define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0)
+ struct rt_msghdr *rtm = NULL;
+ struct rtentry *rt = NULL;
+ struct rtentry *saved_nrt = 0;
+ struct radix_node_head *rnh;
+ struct rt_addrinfo info;
+ int len, error = 0;
+ struct ifnet *ifp = NULL;
+ struct ifaddr *ifa = NULL;
+
+#define senderr(e) { error = e; goto flush;}
+ if (m == NULL || ((m->m_len < sizeof(long)) &&
+ (m = m_pullup(m, sizeof(long))) == NULL))
+ return (ENOBUFS);
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("route_output");
+ len = m->m_pkthdr.len;
+ if (len < sizeof(*rtm) ||
+ len != mtod(m, struct rt_msghdr *)->rtm_msglen) {
+ info.rti_info[RTAX_DST] = NULL;
+ senderr(EINVAL);
+ }
+ R_Malloc(rtm, struct rt_msghdr *, len);
+ if (rtm == NULL) {
+ info.rti_info[RTAX_DST] = NULL;
+ senderr(ENOBUFS);
+ }
+ m_copydata(m, 0, len, (caddr_t)rtm);
+ if (rtm->rtm_version != RTM_VERSION) {
+ info.rti_info[RTAX_DST] = NULL;
+ senderr(EPROTONOSUPPORT);
+ }
+ info.rti_addrs = rtm->rtm_addrs;
+ if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info)) {
+ info.rti_info[RTAX_DST] = NULL;
+ senderr(EINVAL);
+ }
+ if (info.rti_info[RTAX_DST] == NULL ||
+ info.rti_info[RTAX_DST]->sa_family >= AF_MAX ||
+ (info.rti_info[RTAX_GATEWAY] != NULL &&
+ info.rti_info[RTAX_GATEWAY]->sa_family >= AF_MAX))
+ senderr(EINVAL);
+ if (info.rti_info[RTAX_GENMASK]) {
+ struct radix_node *t;
+ t = rn_addmask((caddr_t) info.rti_info[RTAX_GENMASK], 0, 1);
+ if (t != NULL &&
+ Bcmp(info.rti_info[RTAX_GENMASK], t->rn_key, *(u_char *)info.rti_info[RTAX_GENMASK]) == 0)
+ info.rti_info[RTAX_GENMASK] =
+ (struct sockaddr *)t->rn_key;
+ else
+ senderr(ENOBUFS);
+ }
+ switch (rtm->rtm_type) {
+
+ case RTM_ADD:
+ if (info.rti_info[RTAX_GATEWAY] == NULL)
+ senderr(EINVAL);
+ error = rtrequest(RTM_ADD, info.rti_info[RTAX_DST], info.rti_info[RTAX_GATEWAY], info.rti_info[RTAX_NETMASK],
+ rtm->rtm_flags, &saved_nrt);
+ if (error == 0 && saved_nrt) {
+ rt_setmetrics(rtm->rtm_inits,
+ &rtm->rtm_rmx, &saved_nrt->rt_rmx);
+ saved_nrt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits);
+ saved_nrt->rt_rmx.rmx_locks |=
+ (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks);
+ saved_nrt->rt_refcnt--;
+ saved_nrt->rt_genmask = info.rti_info[RTAX_GENMASK];
+ }
+ break;
+
+ case RTM_DELETE:
+ error = rtrequest(RTM_DELETE, info.rti_info[RTAX_DST], info.rti_info[RTAX_GATEWAY], info.rti_info[RTAX_NETMASK],
+ rtm->rtm_flags, &saved_nrt);
+ if (error == 0) {
+ if ((rt = saved_nrt))
+ rt->rt_refcnt++;
+ goto report;
+ }
+ break;
+
+ case RTM_GET:
+ case RTM_CHANGE:
+ case RTM_LOCK:
+ rnh = rt_tables[info.rti_info[RTAX_DST]->sa_family];
+ if (rnh == NULL) {
+ senderr(EAFNOSUPPORT);
+ } else if ((rt = (struct rtentry *)
+ rnh->rnh_lookup(info.rti_info[RTAX_DST], info.rti_info[RTAX_NETMASK], rnh)))
+ rt->rt_refcnt++;
+ else
+ senderr(ESRCH);
+ switch(rtm->rtm_type) {
+
+ case RTM_GET:
+ report:
+ info.rti_info[RTAX_DST] = rt_key(rt);
+ info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+ info.rti_info[RTAX_NETMASK] = rt_mask(rt);
+ info.rti_info[RTAX_GENMASK] = rt->rt_genmask;
+ if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) {
+ ifp = rt->rt_ifp;
+ if (ifp) {
+ info.rti_info[RTAX_IFP] = ifp->if_addrlist->ifa_addr;
+ info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
+ rtm->rtm_index = ifp->if_index;
+ } else {
+ info.rti_info[RTAX_IFP] = NULL;
+ info.rti_info[RTAX_IFA] = NULL;
+ }
+ }
+ len = rt_msg2(rtm->rtm_type, &info, NULL, NULL);
+ if (len > rtm->rtm_msglen) {
+ struct rt_msghdr *new_rtm;
+ R_Malloc(new_rtm, struct rt_msghdr *, len);
+ if (new_rtm == NULL) {
+ senderr(ENOBUFS);
+ }
+ Bcopy(rtm, new_rtm, rtm->rtm_msglen);
+ Free(rtm); rtm = new_rtm;
+ }
+ (void)rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm, NULL);
+ rtm->rtm_flags = rt->rt_flags;
+ rtm->rtm_rmx = rt->rt_rmx;
+ rtm->rtm_addrs = info.rti_addrs;
+ break;
+
+ case RTM_CHANGE:
+ if (info.rti_info[RTAX_GATEWAY] && (error = rt_setgate(rt, rt_key(rt), info.rti_info[RTAX_GATEWAY])))
+ senderr(error);
+
+ /*
+ * If they tried to change things but didn't specify
+ * the required gateway, then just use the old one.
+ * This can happen if the user tries to change the
+ * flags on the default route without changing the
+ * default gateway. Changing flags still doesn't work.
+ */
+ if ((rt->rt_flags & RTF_GATEWAY) && !info.rti_info[RTAX_GATEWAY])
+ info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+
+ /* new gateway could require new ifaddr, ifp;
+ flags may also be different; ifp may be specified
+ by ll sockaddr when protocol address is ambiguous */
+ if (info.rti_info[RTAX_IFP] && (ifa = ifa_ifwithnet(info.rti_info[RTAX_IFP])) &&
+ (ifp = ifa->ifa_ifp) && (info.rti_info[RTAX_IFA] || info.rti_info[RTAX_GATEWAY]))
+ ifa = ifaof_ifpforaddr(info.rti_info[RTAX_IFA] ? info.rti_info[RTAX_IFA] : info.rti_info[RTAX_GATEWAY],
+ ifp);
+ else if ((info.rti_info[RTAX_IFA] && (ifa = ifa_ifwithaddr(info.rti_info[RTAX_IFA]))) ||
+ (info.rti_info[RTAX_GATEWAY] && (ifa = ifa_ifwithroute(rt->rt_flags,
+ rt_key(rt), info.rti_info[RTAX_GATEWAY]))))
+ ifp = ifa->ifa_ifp;
+ if (ifa) {
+ struct ifaddr *oifa = rt->rt_ifa;
+ if (oifa != ifa) {
+ if (oifa && oifa->ifa_rtrequest)
+ oifa->ifa_rtrequest(RTM_DELETE,
+ rt, info.rti_info[RTAX_GATEWAY]);
+ IFAFREE(rt->rt_ifa);
+ rt->rt_ifa = ifa;
+ ifa->ifa_refcnt++;
+ rt->rt_ifp = ifp;
+ }
+ }
+ rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx,
+ &rt->rt_rmx);
+ if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)
+ rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, info.rti_info[RTAX_GATEWAY]);
+ if (info.rti_info[RTAX_GENMASK])
+ rt->rt_genmask = info.rti_info[RTAX_GENMASK];
+ /* FALLTHROUGH */
+ case RTM_LOCK:
+ rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits);
+ rt->rt_rmx.rmx_locks |=
+ (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks);
+ break;
+ }
+ break;
+
+ default:
+ senderr(EOPNOTSUPP);
+ }
+
+flush:
+ if (rtm) {
+ if (error)
+ rtm->rtm_errno = error;
+ else
+ rtm->rtm_flags |= RTF_DONE;
+ }
+ if (rt) /* XXX can this be true? */
+ rtfree(rt);
+ {
+ struct rawcb *rp = NULL;
+ /*
+ * Check to see if we don't want our own messages.
+ */
+ if ((so->so_options & SO_USELOOPBACK) == 0) {
+ if (route_cb.any_count <= 1) {
+ if (rtm)
+ Free(rtm);
+ m_freem(m);
+ return (error);
+ }
+ /* There is another listener, so construct message */
+ rp = sotorawcb(so);
+ }
+ if (rtm) {
+ m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm);
+ Free(rtm);
+ }
+ if (rp)
+ rp->rcb_proto.sp_family = 0; /* Avoid us */
+ if (info.rti_info[RTAX_DST])
+ route_proto.sp_protocol = info.rti_info[RTAX_DST]->sa_family;
+ raw_input(m, &route_proto, &route_src, &route_dst);
+ if (rp)
+ rp->rcb_proto.sp_family = PF_ROUTE;
+ }
+ return (error);
+#undef sa_equal
+}
+
+static void
+rt_setmetrics(u_long which, const struct rt_metrics *in,
+ struct rt_metrics *out)
+{
+#define metric(f, e) if (which & (f)) out->e = in->e;
+ metric(RTV_RPIPE, rmx_recvpipe);
+ metric(RTV_SPIPE, rmx_sendpipe);
+ metric(RTV_SSTHRESH, rmx_ssthresh);
+ metric(RTV_RTT, rmx_rtt);
+ metric(RTV_RTTVAR, rmx_rttvar);
+ metric(RTV_HOPCOUNT, rmx_hopcount);
+ metric(RTV_MTU, rmx_mtu);
+ metric(RTV_EXPIRE, rmx_expire);
+#undef metric
+}
+
+#define ROUNDUP(a) \
+ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+
+
+/*
+ * Extract the addresses of the passed sockaddrs.
+ * Do a little sanity checking so as to avoid bad memory references.
+ * This data is derived straight from userland.
+ */
+static int
+rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
+{
+ struct sockaddr *sa;
+ int i;
+
+ bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info));
+ for (i = 0; i < RTAX_MAX && cp < cplim; i++) {
+ if ((rtinfo->rti_addrs & (1 << i)) == 0)
+ continue;
+ sa = (struct sockaddr *)cp;
+ /*
+ * It won't fit.
+ */
+ if (cp + sa->sa_len > cplim)
+ return (EINVAL);
+ /*
+ * there are no more.. quit now
+ * If there are more bits, they are in error.
+ * I've seen this. route(1) can evidently generate these.
+ * This causes kernel to core dump.
+ * for compatibility, If we see this, point to a safe address.
+ */
+ if (sa->sa_len == 0) {
+ rtinfo->rti_info[i] = &sa_zero;
+ return (0); /* should be EINVAL but for compat */
+ }
+ /* accept it */
+ rtinfo->rti_info[i] = sa;
+ ADVANCE(cp, sa);
+ }
+ return (0);
+}
+
+static struct mbuf *
+rt_msg1(int type, struct rt_addrinfo *rtinfo)
+{
+ struct rt_msghdr *rtm;
+ struct mbuf *m;
+ int i;
+ struct sockaddr *sa;
+ int len, dlen;
+
+ m = m_gethdr(M_DONTWAIT, MT_DATA);
+ if (m == 0)
+ return (m);
+ switch (type) {
+
+ case RTM_DELADDR:
+ case RTM_NEWADDR:
+ len = sizeof(struct ifa_msghdr);
+ break;
+
+ case RTM_IFINFO:
+ len = sizeof(struct if_msghdr);
+ break;
+
+ default:
+ len = sizeof(struct rt_msghdr);
+ }
+ if (len > MHLEN)
+ panic("rt_msg1");
+ m->m_pkthdr.len = m->m_len = len;
+ m->m_pkthdr.rcvif = NULL;
+ rtm = mtod(m, struct rt_msghdr *);
+ bzero((caddr_t)rtm, len);
+ for (i = 0; i < RTAX_MAX; i++) {
+ if ((sa = rtinfo->rti_info[i]) == NULL)
+ continue;
+ rtinfo->rti_addrs |= (1 << i);
+ dlen = ROUNDUP(sa->sa_len);
+ m_copyback(m, len, dlen, (caddr_t)sa);
+ len += dlen;
+ }
+ if (m->m_pkthdr.len != len) {
+ m_freem(m);
+ return (NULL);
+ }
+ rtm->rtm_msglen = len;
+ rtm->rtm_version = RTM_VERSION;
+ rtm->rtm_type = type;
+ return (m);
+}
+
+static int
+rt_msg2(int type, struct rt_addrinfo *rtinfo, caddr_t cp, struct walkarg *w)
+{
+ int i;
+ int len, dlen, second_time = 0;
+ caddr_t cp0;
+
+ rtinfo->rti_addrs = 0;
+again:
+ switch (type) {
+
+ case RTM_DELADDR:
+ case RTM_NEWADDR:
+ len = sizeof(struct ifa_msghdr);
+ break;
+
+ case RTM_IFINFO:
+ len = sizeof(struct if_msghdr);
+ break;
+
+ default:
+ len = sizeof(struct rt_msghdr);
+ }
+ cp0 = cp;
+ if (cp0)
+ cp += len;
+ for (i = 0; i < RTAX_MAX; i++) {
+ struct sockaddr *sa;
+
+ if ((sa = rtinfo->rti_info[i]) == NULL)
+ continue;
+ rtinfo->rti_addrs |= (1 << i);
+ dlen = ROUNDUP(sa->sa_len);
+ if (cp) {
+ bcopy((caddr_t)sa, cp, (unsigned)dlen);
+ cp += dlen;
+ }
+ len += dlen;
+ }
+ if (cp == NULL && w != NULL && !second_time) {
+ struct walkarg *rw = w;
+
+ if (rw->w_req) {
+ if (rw->w_tmemsize < len) {
+ if (rw->w_tmem)
+ free(rw->w_tmem, M_RTABLE);
+ rw->w_tmem = (caddr_t)
+ malloc(len, M_RTABLE, M_NOWAIT);
+ if (rw->w_tmem)
+ rw->w_tmemsize = len;
+ }
+ if (rw->w_tmem) {
+ cp = rw->w_tmem;
+ second_time = 1;
+ goto again;
+ }
+ }
+ }
+ if (cp) {
+ struct rt_msghdr *rtm = (struct rt_msghdr *)cp0;
+
+ rtm->rtm_version = RTM_VERSION;
+ rtm->rtm_type = type;
+ rtm->rtm_msglen = len;
+ }
+ return (len);
+}
+
+/*
+ * This routine is called to generate a message from the routing
+ * socket indicating that a redirect has occured, a routing lookup
+ * has failed, or that a protocol has detected timeouts to a particular
+ * destination.
+ */
+void
+rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
+{
+ struct rt_msghdr *rtm;
+ struct mbuf *m;
+ struct sockaddr *sa = rtinfo->rti_info[RTAX_DST];
+
+ if (route_cb.any_count == 0)
+ return;
+ m = rt_msg1(type, rtinfo);
+ if (m == NULL)
+ return;
+ rtm = mtod(m, struct rt_msghdr *);
+ rtm->rtm_flags = RTF_DONE | flags;
+ rtm->rtm_errno = error;
+ rtm->rtm_addrs = rtinfo->rti_addrs;
+ route_proto.sp_protocol = sa ? sa->sa_family : 0;
+ raw_input(m, &route_proto, &route_src, &route_dst);
+}
+
+/*
+ * This routine is called to generate a message from the routing
+ * socket indicating that the status of a network interface has changed.
+ */
+void
+rt_ifmsg(struct ifnet *ifp)
+{
+ struct if_msghdr *ifm;
+ struct mbuf *m;
+ struct rt_addrinfo info;
+
+ if (route_cb.any_count == 0)
+ return;
+ bzero((caddr_t)&info, sizeof(info));
+ m = rt_msg1(RTM_IFINFO, &info);
+ if (m == NULL)
+ return;
+ ifm = mtod(m, struct if_msghdr *);
+ ifm->ifm_index = ifp->if_index;
+ ifm->ifm_flags = ifp->if_flags;
+ ifm->ifm_data = ifp->if_data;
+ ifm->ifm_addrs = 0;
+ route_proto.sp_protocol = 0;
+ raw_input(m, &route_proto, &route_src, &route_dst);
+}
+
+/*
+ * This is called to generate messages from the routing socket
+ * indicating a network interface has had addresses associated with it.
+ * if we ever reverse the logic and replace messages TO the routing
+ * socket indicate a request to configure interfaces, then it will
+ * be unnecessary as the routing socket will automatically generate
+ * copies of it.
+ */
+void
+rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
+{
+ struct rt_addrinfo info;
+ struct sockaddr *sa = NULL;
+ int pass;
+ struct mbuf *m = NULL;
+ struct ifnet *ifp = ifa->ifa_ifp;
+
+ if (route_cb.any_count == 0)
+ return;
+ for (pass = 1; pass < 3; pass++) {
+ bzero((caddr_t)&info, sizeof(info));
+ if ((cmd == RTM_ADD && pass == 1) ||
+ (cmd == RTM_DELETE && pass == 2)) {
+ struct ifa_msghdr *ifam;
+ int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR;
+
+ info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr;
+ info.rti_info[RTAX_IFP] = ifp->if_addrlist->ifa_addr;
+ info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
+ info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
+ if ((m = rt_msg1(ncmd, &info)) == NULL)
+ continue;
+ ifam = mtod(m, struct ifa_msghdr *);
+ ifam->ifam_index = ifp->if_index;
+ ifam->ifam_metric = ifa->ifa_metric;
+ ifam->ifam_flags = ifa->ifa_flags;
+ ifam->ifam_addrs = info.rti_addrs;
+ }
+ if ((cmd == RTM_ADD && pass == 2) ||
+ (cmd == RTM_DELETE && pass == 1)) {
+ struct rt_msghdr *rtm;
+
+ if (rt == NULL)
+ continue;
+ info.rti_info[RTAX_NETMASK] = rt_mask(rt);
+ info.rti_info[RTAX_DST] = sa = rt_key(rt);
+ info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+ if ((m = rt_msg1(cmd, &info)) == NULL)
+ continue;
+ rtm = mtod(m, struct rt_msghdr *);
+ rtm->rtm_index = ifp->if_index;
+ rtm->rtm_flags |= rt->rt_flags;
+ rtm->rtm_errno = error;
+ rtm->rtm_addrs = info.rti_addrs;
+ }
+ route_proto.sp_protocol = sa ? sa->sa_family : 0;
+ raw_input(m, &route_proto, &route_src, &route_dst);
+ }
+}
+
+
+/*
+ * This is used in dumping the kernel table via sysctl().
+ */
+int
+sysctl_dumpentry(struct radix_node *rn, void *vw)
+{
+ struct walkarg *w = vw;
+ struct rtentry *rt = (struct rtentry *)rn;
+ int error = 0, size;
+ struct rt_addrinfo info;
+
+ if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))
+ return 0;
+ bzero((caddr_t)&info, sizeof(info));
+ info.rti_info[RTAX_DST] = rt_key(rt);
+ info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+ info.rti_info[RTAX_NETMASK] = rt_mask(rt);
+ info.rti_info[RTAX_GENMASK] = rt->rt_genmask;
+ size = rt_msg2(RTM_GET, &info, NULL, w);
+ if (w->w_req && w->w_tmem) {
+ struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;
+
+ rtm->rtm_flags = rt->rt_flags;
+ rtm->rtm_use = rt->rt_use;
+ rtm->rtm_rmx = rt->rt_rmx;
+ rtm->rtm_index = rt->rt_ifp->if_index;
+ rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0;
+ rtm->rtm_addrs = info.rti_addrs;
+ error = 0;
+ return (error);
+ }
+ return (error);
+}
+
+int
+sysctl_iflist(int af, struct walkarg *w)
+{
+ struct ifnet *ifp;
+ struct ifaddr *ifa;
+ struct rt_addrinfo info;
+ int len, error = 0;
+
+ bzero((caddr_t)&info, sizeof(info));
+ for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+ if (w->w_arg && w->w_arg != ifp->if_index)
+ continue;
+ ifa = ifp->if_addrlist;
+ info.rti_info[RTAX_IFP] = ifa->ifa_addr;
+ len = rt_msg2(RTM_IFINFO, &info, (caddr_t)0, w);
+ info.rti_info[RTAX_IFP] = 0;
+ if (w->w_req && w->w_tmem) {
+ struct if_msghdr *ifm;
+
+ ifm = (struct if_msghdr *)w->w_tmem;
+ ifm->ifm_index = ifp->if_index;
+ ifm->ifm_flags = ifp->if_flags;
+ ifm->ifm_data = ifp->if_data;
+ ifm->ifm_addrs = info.rti_addrs;
+ error = SYSCTL_OUT(w->w_req,(caddr_t)ifm, len);
+ if (error)
+ return (error);
+ }
+ while ((ifa = ifa->ifa_next) != 0) {
+ if (af && af != ifa->ifa_addr->sa_family)
+ continue;
+ info.rti_info[RTAX_IFA] = ifa->ifa_addr;
+ info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
+ info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
+ len = rt_msg2(RTM_NEWADDR, &info, NULL, w);
+ if (w->w_req && w->w_tmem) {
+ struct ifa_msghdr *ifam;
+
+ ifam = (struct ifa_msghdr *)w->w_tmem;
+ ifam->ifam_index = ifa->ifa_ifp->if_index;
+ ifam->ifam_flags = ifa->ifa_flags;
+ ifam->ifam_metric = ifa->ifa_metric;
+ ifam->ifam_addrs = info.rti_addrs;
+ error = SYSCTL_OUT(w->w_req, w->w_tmem, len);
+ if (error)
+ return (error);
+ }
+ }
+ info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] = info.rti_info[RTAX_BRD] = 0;
+ }
+ return (0);
+}
+
+static int
+sysctl_rtsock(SYSCTL_HANDLER_ARGS)
+{
+ int *name = (int *)arg1;
+ u_int namelen = arg2;
+ struct radix_node_head *rnh;
+ int i, s, error = EINVAL;
+ u_char af;
+ struct walkarg w;
+
+ name ++;
+ namelen--;
+ if (req->newptr)
+ return (EPERM);
+ if (namelen != 3)
+ return (EINVAL);
+ af = name[0];
+ Bzero(&w, sizeof(w));
+ w.w_op = name[1];
+ w.w_arg = name[2];
+ w.w_req = req;
+
+ s = splnet();
+ switch (w.w_op) {
+
+ case NET_RT_DUMP:
+ case NET_RT_FLAGS:
+ for (i = 1; i <= AF_MAX; i++)
+ if ((rnh = rt_tables[i]) && (af == 0 || af == i) &&
+ (error = rnh->rnh_walktree(rnh,
+ sysctl_dumpentry, &w)))
+ break;
+ break;
+
+ case NET_RT_IFLIST:
+ error = sysctl_iflist(af, &w);
+ }
+ splx(s);
+ if (w.w_tmem)
+ free(w.w_tmem, M_RTABLE);
+ return (error);
+}
+
+SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD, sysctl_rtsock,"");
+
+/*
+ * Definitions of protocols supported in the ROUTE domain.
+ */
+
+extern struct domain routedomain; /* or at least forward */
+
+static struct protosw routesw[] = {
+{ SOCK_RAW, &routedomain, 0, PR_ATOMIC|PR_ADDR,
+ 0, route_output, raw_ctlinput, 0,
+ route_usrreq,
+ raw_init
+}
+};
+
+struct domain routedomain =
+ { PF_ROUTE, "route", route_init, 0, 0,
+ routesw, &routesw[sizeof(routesw)/sizeof(routesw[0])] };
+
+DOMAIN_SET(route);
diff --git a/cpukit/libnetworking/net/slcompress.c b/cpukit/libnetworking/net/slcompress.c
new file mode 100644
index 0000000000..11b4678c0a
--- /dev/null
+++ b/cpukit/libnetworking/net/slcompress.c
@@ -0,0 +1,612 @@
+/*-
+ * Copyright (c) 1989, 1993, 1994
+ * 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.
+ * 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.
+ *
+ * @(#)slcompress.c 8.2 (Berkeley) 4/16/94
+ * $FreeBSD: src/sys/net/slcompress.c,v 1.19 2004/04/07 20:46:12 imp Exp $
+ */
+
+/*
+ * Routines to compress and uncompess tcp packets (for transmission
+ * over low speed serial lines.
+ *
+ * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
+ * - Initial distribution.
+ *
+ */
+
+#if defined(__rtems__)
+#include <stdint.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/systm.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include <net/slcompress.h>
+
+#ifndef SL_NO_STATS
+#define INCR(counter) ++comp->counter;
+#else
+#define INCR(counter)
+#endif
+
+#define BCMP(p1, p2, n) bcmp((void *)(p1), (void *)(p2), (int)(n))
+#define BCOPY(p1, p2, n) bcopy((void *)(p1), (void *)(p2), (int)(n))
+
+void
+sl_compress_init(comp, max_state)
+ struct slcompress *comp;
+ int max_state;
+{
+ register u_int i;
+ register struct cstate *tstate = comp->tstate;
+
+ if (max_state == -1) {
+ max_state = MAX_STATES - 1;
+ bzero((char *)comp, sizeof(*comp));
+ } else {
+ /* Don't reset statistics */
+ bzero((char *)comp->tstate, sizeof(comp->tstate));
+ bzero((char *)comp->rstate, sizeof(comp->rstate));
+ }
+ for (i = max_state; i > 0; --i) {
+ tstate[i].cs_id = i;
+ tstate[i].cs_next = &tstate[i - 1];
+ }
+ tstate[0].cs_next = &tstate[max_state];
+ tstate[0].cs_id = 0;
+ comp->last_cs = &tstate[0];
+ comp->last_recv = 255;
+ comp->last_xmit = 255;
+ comp->flags = SLF_TOSS;
+}
+
+
+/* ENCODE encodes a number that is known to be non-zero. ENCODEZ
+ * checks for zero (since zero has to be encoded in the long, 3 byte
+ * form).
+ */
+#define ENCODE(n) { \
+ if ((u_int16_t)(n) >= 256) { \
+ *cp++ = 0; \
+ cp[1] = (n); \
+ cp[0] = (n) >> 8; \
+ cp += 2; \
+ } else { \
+ *cp++ = (n); \
+ } \
+}
+#define ENCODEZ(n) { \
+ if ((u_int16_t)(n) >= 256 || (u_int16_t)(n) == 0) { \
+ *cp++ = 0; \
+ cp[1] = (n); \
+ cp[0] = (n) >> 8; \
+ cp += 2; \
+ } else { \
+ *cp++ = (n); \
+ } \
+}
+
+#define DECODEL(f) { \
+ if (*cp == 0) {\
+ (f) = htonl(ntohl(f) + ((cp[1] << 8) | cp[2])); \
+ cp += 3; \
+ } else { \
+ (f) = htonl(ntohl(f) + (u_int32_t)*cp++); \
+ } \
+}
+
+#define DECODES(f) { \
+ if (*cp == 0) {\
+ (f) = htons(ntohs(f) + ((cp[1] << 8) | cp[2])); \
+ cp += 3; \
+ } else { \
+ (f) = htons(ntohs(f) + (u_int32_t)*cp++); \
+ } \
+}
+
+#define DECODEU(f) { \
+ if (*cp == 0) {\
+ (f) = htons((cp[1] << 8) | cp[2]); \
+ cp += 3; \
+ } else { \
+ (f) = htons((u_int32_t)*cp++); \
+ } \
+}
+
+/*
+ * Attempt to compress an outgoing TCP packet and return the type of
+ * the result. The caller must have already verified that the protocol
+ * is TCP. The first mbuf must contain the complete IP and TCP headers,
+ * and "ip" must be == mtod(m, struct ip *). "comp" supplies the
+ * compression state, and "compress_cid" tells us whether it is OK
+ * to leave out the CID field when feasible.
+ *
+ * The caller is responsible for adjusting m->m_pkthdr.len upon return,
+ * if m is an M_PKTHDR mbuf.
+ */
+u_int
+sl_compress_tcp(m, ip, comp, compress_cid)
+ struct mbuf *m;
+ register struct ip *ip;
+ struct slcompress *comp;
+ int compress_cid;
+{
+ register struct cstate *cs = comp->last_cs->cs_next;
+ register u_int hlen = ip->ip_hl;
+ register struct tcphdr *oth;
+ register struct tcphdr *th;
+ register u_int deltaS, deltaA;
+ register u_int changes = 0;
+ u_char new_seq[16];
+ register u_char *cp = new_seq;
+
+ /*
+ * Bail if this is an IP fragment or if the TCP packet isn't
+ * `compressible' (i.e., ACK isn't set or some other control bit is
+ * set). (We assume that the caller has already made sure the
+ * packet is IP proto TCP).
+ */
+ if ((ip->ip_off & htons(0x3fff)) || m->m_len < 40)
+ return (TYPE_IP);
+
+ th = (struct tcphdr *)&((int32_t *)ip)[hlen];
+ if ((th->th_flags & (TH_SYN|TH_FIN|TH_RST|TH_ACK)) != TH_ACK)
+ return (TYPE_IP);
+ /*
+ * Packet is compressible -- we're going to send either a
+ * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need
+ * to locate (or create) the connection state. Special case the
+ * most recently used connection since it's most likely to be used
+ * again & we don't have to do any reordering if it's used.
+ */
+ INCR(sls_packets)
+ if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr ||
+ ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr ||
+ *(int32_t *)th != ((int32_t *)&cs->cs_ip)[cs->cs_ip.ip_hl]) {
+ /*
+ * Wasn't the first -- search for it.
+ *
+ * States are kept in a circularly linked list with
+ * last_cs pointing to the end of the list. The
+ * list is kept in lru order by moving a state to the
+ * head of the list whenever it is referenced. Since
+ * the list is short and, empirically, the connection
+ * we want is almost always near the front, we locate
+ * states via linear search. If we don't find a state
+ * for the datagram, the oldest state is (re-)used.
+ */
+ register struct cstate *lcs;
+ register struct cstate *lastcs = comp->last_cs;
+
+ do {
+ lcs = cs; cs = cs->cs_next;
+ INCR(sls_searches)
+ if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr
+ && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr
+ && *(int32_t *)th ==
+ ((int32_t *)&cs->cs_ip)[cs->cs_ip.ip_hl])
+ goto found;
+ } while (cs != lastcs);
+
+ /*
+ * Didn't find it -- re-use oldest cstate. Send an
+ * uncompressed packet that tells the other side what
+ * connection number we're using for this conversation.
+ * Note that since the state list is circular, the oldest
+ * state points to the newest and we only need to set
+ * last_cs to update the lru linkage.
+ */
+ INCR(sls_misses)
+ comp->last_cs = lcs;
+ hlen += th->th_off;
+ hlen <<= 2;
+ if (hlen > m->m_len)
+ return TYPE_IP;
+ goto uncompressed;
+
+ found:
+ /*
+ * Found it -- move to the front on the connection list.
+ */
+ if (cs == lastcs)
+ comp->last_cs = lcs;
+ else {
+ lcs->cs_next = cs->cs_next;
+ cs->cs_next = lastcs->cs_next;
+ lastcs->cs_next = cs;
+ }
+ }
+
+ /*
+ * Make sure that only what we expect to change changed. The first
+ * line of the `if' checks the IP protocol version, header length &
+ * type of service. The 2nd line checks the "Don't fragment" bit.
+ * The 3rd line checks the time-to-live and protocol (the protocol
+ * check is unnecessary but costless). The 4th line checks the TCP
+ * header length. The 5th line checks IP options, if any. The 6th
+ * line checks TCP options, if any. If any of these things are
+ * different between the previous & current datagram, we send the
+ * current datagram `uncompressed'.
+ */
+ oth = (struct tcphdr *)&((int32_t *)&cs->cs_ip)[hlen];
+ deltaS = hlen;
+ hlen += th->th_off;
+ hlen <<= 2;
+ if (hlen > m->m_len)
+ return TYPE_IP;
+
+ if (((u_int16_t *)ip)[0] != ((u_int16_t *)&cs->cs_ip)[0] ||
+ ((u_int16_t *)ip)[3] != ((u_int16_t *)&cs->cs_ip)[3] ||
+ ((u_int16_t *)ip)[4] != ((u_int16_t *)&cs->cs_ip)[4] ||
+ th->th_off != oth->th_off ||
+ (deltaS > 5 &&
+ BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) ||
+ (th->th_off > 5 &&
+ BCMP(th + 1, oth + 1, (th->th_off - 5) << 2)))
+ goto uncompressed;
+
+ /*
+ * Figure out which of the changing fields changed. The
+ * receiver expects changes in the order: urgent, window,
+ * ack, seq (the order minimizes the number of temporaries
+ * needed in this section of code).
+ */
+ if (th->th_flags & TH_URG) {
+ deltaS = ntohs(th->th_urp);
+ ENCODEZ(deltaS);
+ changes |= NEW_U;
+ } else if (th->th_urp != oth->th_urp)
+ /* argh! URG not set but urp changed -- a sensible
+ * implementation should never do this but RFC793
+ * doesn't prohibit the change so we have to deal
+ * with it. */
+ goto uncompressed;
+
+ deltaS = (u_int16_t)(ntohs(th->th_win) - ntohs(oth->th_win));
+ if (deltaS) {
+ ENCODE(deltaS);
+ changes |= NEW_W;
+ }
+
+ deltaA = ntohl(th->th_ack) - ntohl(oth->th_ack);
+ if (deltaA) {
+ if (deltaA > 0xffff)
+ goto uncompressed;
+ ENCODE(deltaA);
+ changes |= NEW_A;
+ }
+
+ deltaS = ntohl(th->th_seq) - ntohl(oth->th_seq);
+ if (deltaS) {
+ if (deltaS > 0xffff)
+ goto uncompressed;
+ ENCODE(deltaS);
+ changes |= NEW_S;
+ }
+
+ switch(changes) {
+
+ case 0:
+ /*
+ * Nothing changed. If this packet contains data and the
+ * last one didn't, this is probably a data packet following
+ * an ack (normal on an interactive connection) and we send
+ * it compressed. Otherwise it's probably a retransmit,
+ * retransmitted ack or window probe. Send it uncompressed
+ * in case the other side missed the compressed version.
+ */
+ if (ip->ip_len != cs->cs_ip.ip_len &&
+ ntohs(cs->cs_ip.ip_len) == hlen)
+ break;
+
+ /* FALLTHROUGH */
+
+ case SPECIAL_I:
+ case SPECIAL_D:
+ /*
+ * actual changes match one of our special case encodings --
+ * send packet uncompressed.
+ */
+ goto uncompressed;
+
+ case NEW_S|NEW_A:
+ if (deltaS == deltaA &&
+ deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
+ /* special case for echoed terminal traffic */
+ changes = SPECIAL_I;
+ cp = new_seq;
+ }
+ break;
+
+ case NEW_S:
+ if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
+ /* special case for data xfer */
+ changes = SPECIAL_D;
+ cp = new_seq;
+ }
+ break;
+ }
+
+ deltaS = ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id);
+ if (deltaS != 1) {
+ ENCODEZ(deltaS);
+ changes |= NEW_I;
+ }
+ if (th->th_flags & TH_PUSH)
+ changes |= TCP_PUSH_BIT;
+ /*
+ * Grab the cksum before we overwrite it below. Then update our
+ * state with this packet's header.
+ */
+ deltaA = ntohs(th->th_sum);
+ BCOPY(ip, &cs->cs_ip, hlen);
+
+ /*
+ * We want to use the original packet as our compressed packet.
+ * (cp - new_seq) is the number of bytes we need for compressed
+ * sequence numbers. In addition we need one byte for the change
+ * mask, one for the connection id and two for the tcp checksum.
+ * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how
+ * many bytes of the original packet to toss so subtract the two to
+ * get the new packet size.
+ */
+ deltaS = cp - new_seq;
+ cp = (u_char *)ip;
+ if (compress_cid == 0 || comp->last_xmit != cs->cs_id) {
+ comp->last_xmit = cs->cs_id;
+ hlen -= deltaS + 4;
+ cp += hlen;
+ *cp++ = changes | NEW_C;
+ *cp++ = cs->cs_id;
+ } else {
+ hlen -= deltaS + 3;
+ cp += hlen;
+ *cp++ = changes;
+ }
+ m->m_len -= hlen;
+ m->m_data += hlen;
+ *cp++ = deltaA >> 8;
+ *cp++ = deltaA;
+ BCOPY(new_seq, cp, deltaS);
+ INCR(sls_compressed)
+ return (TYPE_COMPRESSED_TCP);
+
+ /*
+ * Update connection state cs & send uncompressed packet ('uncompressed'
+ * means a regular ip/tcp packet but with the 'conversation id' we hope
+ * to use on future compressed packets in the protocol field).
+ */
+uncompressed:
+ BCOPY(ip, &cs->cs_ip, hlen);
+ ip->ip_p = cs->cs_id;
+ comp->last_xmit = cs->cs_id;
+ return (TYPE_UNCOMPRESSED_TCP);
+}
+
+
+int
+sl_uncompress_tcp(bufp, len, type, comp)
+ u_char **bufp;
+ int len;
+ u_int type;
+ struct slcompress *comp;
+{
+ u_char *hdr, *cp;
+ u_int hlen;
+ int vjlen;
+
+ cp = bufp? *bufp: NULL;
+ vjlen = sl_uncompress_tcp_core(cp, len, len, type, comp, &hdr, &hlen);
+ if (vjlen < 0)
+ return (0); /* error */
+ if (vjlen == 0)
+ return (len); /* was uncompressed already */
+
+ cp += vjlen;
+ len -= vjlen;
+
+ /*
+ * At this point, cp points to the first byte of data in the
+ * packet. If we're not aligned on a 4-byte boundary, copy the
+ * data down so the ip & tcp headers will be aligned. Then back up
+ * cp by the tcp/ip header length to make room for the reconstructed
+ * header (we assume the packet we were handed has enough space to
+ * prepend 128 bytes of header).
+ */
+ if ((intptr_t)cp & 3) {
+ if (len > 0)
+ BCOPY(cp, ((intptr_t)cp &~ 3), len);
+ cp = (u_char *)((intptr_t)cp &~ 3);
+ }
+ cp -= hlen;
+ len += hlen;
+ BCOPY(hdr, cp, hlen);
+
+ *bufp = cp;
+ return (len);
+}
+
+/*
+ * Uncompress a packet of total length total_len. The first buflen
+ * bytes are at buf; this must include the entire (compressed or
+ * uncompressed) TCP/IP header. This procedure returns the length
+ * of the VJ header, with a pointer to the uncompressed IP header
+ * in *hdrp and its length in *hlenp.
+ */
+int
+sl_uncompress_tcp_core(buf, buflen, total_len, type, comp, hdrp, hlenp)
+ u_char *buf;
+ int buflen, total_len;
+ u_int type;
+ struct slcompress *comp;
+ u_char **hdrp;
+ u_int *hlenp;
+{
+ register u_char *cp;
+ register u_int hlen, changes;
+ register struct tcphdr *th;
+ register struct cstate *cs;
+ register struct ip *ip;
+ register u_int16_t *bp;
+ register u_int vjlen;
+
+ switch (type) {
+
+ case TYPE_UNCOMPRESSED_TCP:
+ ip = (struct ip *) buf;
+ if (ip->ip_p >= MAX_STATES)
+ goto bad;
+ cs = &comp->rstate[comp->last_recv = ip->ip_p];
+ comp->flags &=~ SLF_TOSS;
+ ip->ip_p = IPPROTO_TCP;
+ /*
+ * Calculate the size of the TCP/IP header and make sure that
+ * we don't overflow the space we have available for it.
+ */
+ hlen = ip->ip_hl << 2;
+ if (hlen + sizeof(struct tcphdr) > buflen)
+ goto bad;
+ hlen += ((struct tcphdr *)&((char *)ip)[hlen])->th_off << 2;
+ if (hlen > MAX_HDR || hlen > buflen)
+ goto bad;
+ BCOPY(ip, &cs->cs_ip, hlen);
+ cs->cs_hlen = hlen;
+ INCR(sls_uncompressedin)
+ *hdrp = (u_char *) &cs->cs_ip;
+ *hlenp = hlen;
+ return (0);
+
+ default:
+ goto bad;
+
+ case TYPE_COMPRESSED_TCP:
+ break;
+ }
+ /* We've got a compressed packet. */
+ INCR(sls_compressedin)
+ cp = buf;
+ changes = *cp++;
+ if (changes & NEW_C) {
+ /* Make sure the state index is in range, then grab the state.
+ * If we have a good state index, clear the 'discard' flag. */
+ if (*cp >= MAX_STATES)
+ goto bad;
+
+ comp->flags &=~ SLF_TOSS;
+ comp->last_recv = *cp++;
+ } else {
+ /* this packet has an implicit state index. If we've
+ * had a line error since the last time we got an
+ * explicit state index, we have to toss the packet. */
+ if (comp->flags & SLF_TOSS) {
+ INCR(sls_tossed)
+ return (-1);
+ }
+ }
+ cs = &comp->rstate[comp->last_recv];
+ hlen = cs->cs_ip.ip_hl << 2;
+ th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen];
+ th->th_sum = htons((*cp << 8) | cp[1]);
+ cp += 2;
+ if (changes & TCP_PUSH_BIT)
+ th->th_flags |= TH_PUSH;
+ else
+ th->th_flags &=~ TH_PUSH;
+
+ switch (changes & SPECIALS_MASK) {
+ case SPECIAL_I:
+ {
+ register u_int i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
+ th->th_ack = htonl(ntohl(th->th_ack) + i);
+ th->th_seq = htonl(ntohl(th->th_seq) + i);
+ }
+ break;
+
+ case SPECIAL_D:
+ th->th_seq = htonl(ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len)
+ - cs->cs_hlen);
+ break;
+
+ default:
+ if (changes & NEW_U) {
+ th->th_flags |= TH_URG;
+ DECODEU(th->th_urp)
+ } else
+ th->th_flags &=~ TH_URG;
+ if (changes & NEW_W)
+ DECODES(th->th_win)
+ if (changes & NEW_A)
+ DECODEL(th->th_ack)
+ if (changes & NEW_S)
+ DECODEL(th->th_seq)
+ break;
+ }
+ if (changes & NEW_I) {
+ DECODES(cs->cs_ip.ip_id)
+ } else
+ cs->cs_ip.ip_id = htons(ntohs(cs->cs_ip.ip_id) + 1);
+
+ /*
+ * At this point, cp points to the first byte of data in the
+ * packet. Fill in the IP total length and update the IP
+ * header checksum.
+ */
+ vjlen = cp - buf;
+ buflen -= vjlen;
+ if (buflen < 0)
+ /* we must have dropped some characters (crc should detect
+ * this but the old slip framing won't) */
+ goto bad;
+
+ total_len += cs->cs_hlen - vjlen;
+ cs->cs_ip.ip_len = htons(total_len);
+
+ /* recompute the ip header checksum */
+ bp = (u_int16_t *) &cs->cs_ip;
+ cs->cs_ip.ip_sum = 0;
+ for (changes = 0; hlen > 0; hlen -= 2)
+ changes += *bp++;
+ changes = (changes & 0xffff) + (changes >> 16);
+ changes = (changes & 0xffff) + (changes >> 16);
+ cs->cs_ip.ip_sum = ~ changes;
+
+ *hdrp = (u_char *) &cs->cs_ip;
+ *hlenp = cs->cs_hlen;
+ return vjlen;
+
+bad:
+ comp->flags |= SLF_TOSS;
+ INCR(sls_errorin)
+ return (-1);
+}
diff --git a/cpukit/libnetworking/net/slcompress.h b/cpukit/libnetworking/net/slcompress.h
new file mode 100644
index 0000000000..99ee01be3a
--- /dev/null
+++ b/cpukit/libnetworking/net/slcompress.h
@@ -0,0 +1,157 @@
+/*
+ * Definitions for tcp compression routines.
+ *
+ * Copyright (c) 1989, 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.
+ * 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.
+ *
+ * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
+ * - Initial distribution.
+ * $FreeBSD: src/sys/net/slcompress.h,v 1.18 2004/04/07 20:46:12 imp Exp $
+ */
+
+#ifndef _NET_SLCOMPRESS_H_
+#define _NET_SLCOMPRESS_H_
+
+#define MAX_STATES 16 /* must be > 2 and < 256 */
+#define MAX_HDR 128
+
+/*
+ * Compressed packet format:
+ *
+ * The first octet contains the packet type (top 3 bits), TCP
+ * 'push' bit, and flags that indicate which of the 4 TCP sequence
+ * numbers have changed (bottom 5 bits). The next octet is a
+ * conversation number that associates a saved IP/TCP header with
+ * the compressed packet. The next two octets are the TCP checksum
+ * from the original datagram. The next 0 to 15 octets are
+ * sequence number changes, one change per bit set in the header
+ * (there may be no changes and there are two special cases where
+ * the receiver implicitly knows what changed -- see below).
+ *
+ * There are 5 numbers which can change (they are always inserted
+ * in the following order): TCP urgent pointer, window,
+ * acknowledgement, sequence number and IP ID. (The urgent pointer
+ * is different from the others in that its value is sent, not the
+ * change in value.) Since typical use of SLIP links is biased
+ * toward small packets (see comments on MTU/MSS below), changes
+ * use a variable length coding with one octet for numbers in the
+ * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
+ * range 256 - 65535 or 0. (If the change in sequence number or
+ * ack is more than 65535, an uncompressed packet is sent.)
+ */
+
+/*
+ * Packet types (must not conflict with IP protocol version)
+ *
+ * The top nibble of the first octet is the packet type. There are
+ * three possible types: IP (not proto TCP or tcp with one of the
+ * control flags set); uncompressed TCP (a normal IP/TCP packet but
+ * with the 8-bit protocol field replaced by an 8-bit connection id --
+ * this type of packet syncs the sender & receiver); and compressed
+ * TCP (described above).
+ *
+ * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
+ * is logically part of the 4-bit "changes" field that follows. Top
+ * three bits are actual packet type. For backward compatibility
+ * and in the interest of conserving bits, numbers are chosen so the
+ * IP protocol version number (4) which normally appears in this nibble
+ * means "IP packet".
+ */
+
+/* packet types */
+#define TYPE_IP 0x40
+#define TYPE_UNCOMPRESSED_TCP 0x70
+#define TYPE_COMPRESSED_TCP 0x80
+#define TYPE_ERROR 0x00
+
+/* Bits in first octet of compressed packet */
+#define NEW_C 0x40 /* flag bits for what changed in a packet */
+#define NEW_I 0x20
+#define NEW_S 0x08
+#define NEW_A 0x04
+#define NEW_W 0x02
+#define NEW_U 0x01
+
+/* reserved, special-case values of above */
+#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */
+#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */
+#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)
+
+#define TCP_PUSH_BIT 0x10
+
+
+/*
+ * "state" data for each active tcp conversation on the wire. This is
+ * basically a copy of the entire IP/TCP header from the last packet
+ * we saw from the conversation together with a small identifier
+ * the transmit & receive ends of the line use to locate saved header.
+ */
+struct cstate {
+ struct cstate *cs_next; /* next most recently used cstate (xmit only) */
+ u_int16_t cs_hlen; /* size of hdr (receive only) */
+ u_char cs_id; /* connection # associated with this state */
+ u_char cs_filler;
+ union {
+ char csu_hdr[MAX_HDR];
+ struct ip csu_ip; /* ip/tcp hdr from most recent packet */
+ } slcs_u;
+};
+#define cs_ip slcs_u.csu_ip
+#define cs_hdr slcs_u.csu_hdr
+
+/*
+ * all the state data for one serial line (we need one of these
+ * per line).
+ */
+struct slcompress {
+ struct cstate *last_cs; /* most recently used tstate */
+ u_char last_recv; /* last rcvd conn. id */
+ u_char last_xmit; /* last sent conn. id */
+ u_int16_t flags;
+#ifndef SL_NO_STATS
+ int sls_packets; /* outbound packets */
+ int sls_compressed; /* outbound compressed packets */
+ int sls_searches; /* searches for connection state */
+ int sls_misses; /* times couldn't find conn. state */
+ int sls_uncompressedin; /* inbound uncompressed packets */
+ int sls_compressedin; /* inbound compressed packets */
+ int sls_errorin; /* inbound unknown type packets */
+ int sls_tossed; /* inbound packets tossed because of error */
+#endif
+ struct cstate tstate[MAX_STATES]; /* xmit connection states */
+ struct cstate rstate[MAX_STATES]; /* receive connection states */
+};
+/* flag values */
+#define SLF_TOSS 1 /* tossing rcvd frames because of input err */
+
+void sl_compress_init(struct slcompress *, int);
+u_int sl_compress_tcp(struct mbuf *, struct ip *, struct slcompress *, int);
+int sl_uncompress_tcp(u_char **, int, u_int, struct slcompress *);
+int sl_uncompress_tcp_core(u_char *, int, int, u_int,
+ struct slcompress *, u_char **, u_int *);
+
+#endif /* !_NET_SLCOMPRESS_H_ */
diff --git a/cpukit/libnetworking/netdb.h b/cpukit/libnetworking/netdb.h
new file mode 100644
index 0000000000..29350e063b
--- /dev/null
+++ b/cpukit/libnetworking/netdb.h
@@ -0,0 +1,192 @@
+/*-
+ * Copyright (c) 1980, 1983, 1988, 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.
+ *
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*
+ * @(#)netdb.h 8.1 (Berkeley) 6/2/93
+ * From: Id: netdb.h,v 8.9 1996/11/19 08:39:29 vixie Exp $
+ * $FreeBSD: src/include/netdb.h,v 1.34 2005/02/14 11:33:11 phantom Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NETDB_H_
+#define _NETDB_H_
+
+#include <sys/cdefs.h>
+#include <rtems/bsdnet/_types.h>
+
+#ifndef _SOCKLEN_T_DECLARED
+typedef __socklen_t socklen_t;
+#define _SOCKLEN_T_DECLARED
+#endif
+
+#ifndef _PATH_HEQUIV
+# define _PATH_HEQUIV "/etc/hosts.equiv"
+#endif
+#define _PATH_HOSTS "/etc/hosts"
+#define _PATH_NETWORKS "/etc/networks"
+#define _PATH_PROTOCOLS "/etc/protocols"
+#define _PATH_SERVICES "/etc/services"
+
+extern int h_errno;
+
+/*
+ * Structures returned by network data base library. All addresses are
+ * supplied in host order, and returned in network order (suitable for
+ * use in system calls).
+ */
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+};
+
+/*
+ * Assumption here is that a network number
+ * fits in an unsigned long -- probably a poor one.
+ */
+struct netent {
+ char *n_name; /* official name of net */
+ char **n_aliases; /* alias list */
+ int n_addrtype; /* net address type */
+ unsigned long n_net; /* network # */
+};
+
+struct servent {
+ char *s_name; /* official service name */
+ char **s_aliases; /* alias list */
+ int s_port; /* port # */
+ char *s_proto; /* protocol to use */
+};
+
+struct protoent {
+ char *p_name; /* official protocol name */
+ char **p_aliases; /* alias list */
+ int p_proto; /* protocol # */
+};
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (left in extern int h_errno).
+ */
+
+#define NETDB_INTERNAL -1 /* see errno */
+#define NETDB_SUCCESS 0 /* no problem */
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */
+#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data record of requested type */
+#define NO_ADDRESS NO_DATA /* no address, look for MX record */
+
+__BEGIN_DECLS
+void endhostent(void);
+void endnetent(void);
+void endprotoent(void);
+void endservent(void);
+struct hostent *gethostbyaddr(const char *, int, int);
+struct hostent *gethostbyname(const char *);
+struct hostent *gethostbyname2(const char *, int);
+struct hostent *gethostent(void);
+struct netent *getnetbyaddr(unsigned long, int);
+struct netent *getnetbyname(const char *);
+struct netent *getnetent(void);
+struct protoent *getprotobyname(const char *);
+struct protoent *getprotobynumber(int);
+struct protoent *getprotoent(void);
+struct servent *getservbyname(const char *, const char *);
+struct servent *getservbyport(int, const char *);
+struct servent *getservent(void);
+void herror(const char *);
+__const char *hstrerror(int);
+void sethostent(int);
+/* void sethostfile(const char *); */
+void setnetent(int);
+void setprotoent(int);
+void setservent(int);
+
+/*
+ * PRIVATE functions specific to the FreeBSD implementation
+ */
+
+/* DO NOT USE THESE, THEY ARE SUBJECT TO CHANGE AND ARE NOT PORTABLE!!! */
+void _sethosthtent(int);
+void _endhosthtent(void);
+void _sethostdnsent(int);
+void _endhostdnsent(void);
+void _setnethtent(int);
+void _endnethtent(void);
+void _setnetdnsent(int);
+void _endnetdnsent(void);
+struct hostent * _gethostbyhtname(const char *, int);
+struct hostent * _gethostbydnsname(const char *, int);
+struct hostent * _gethostbynisname(const char *, int);
+struct hostent * _gethostbyhtaddr (const char *, int, int);
+struct hostent * _gethostbydnsaddr(const char *, int, int);
+struct hostent * _gethostbynisaddr(const char *, int, int);
+struct netent * _getnetbyhtname (const char *);
+struct netent * _getnetbydnsname(const char *);
+struct netent * _getnetbynisname(const char *);
+struct netent * _getnetbyhtaddr (unsigned long, int);
+struct netent * _getnetbydnsaddr(unsigned long, int);
+struct netent * _getnetbynisaddr(unsigned long, int);
+void _map_v4v6_address(const char *, char *);
+void _map_v4v6_hostent(struct hostent *, char **, int *len);
+__END_DECLS
+
+#endif /* !_NETDB_H_ */
diff --git a/cpukit/libnetworking/netinet/icmp_var.h b/cpukit/libnetworking/netinet/icmp_var.h
new file mode 100644
index 0000000000..da74e58f98
--- /dev/null
+++ b/cpukit/libnetworking/netinet/icmp_var.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ *
+ * @(#)icmp_var.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NETINET_ICMP_VAR_H_
+#define _NETINET_ICMP_VAR_H_
+
+/*
+ * Variables related to this implementation
+ * of the internet control message protocol.
+ */
+struct icmpstat {
+/* statistics related to icmp packets generated */
+ u_long icps_error; /* # of calls to icmp_error */
+ u_long icps_oldshort; /* no error 'cuz old ip too short */
+ u_long icps_oldicmp; /* no error 'cuz old was icmp */
+ u_long icps_outhist[ICMP_MAXTYPE + 1];
+/* statistics related to input messages processed */
+ u_long icps_badcode; /* icmp_code out of range */
+ u_long icps_tooshort; /* packet < ICMP_MINLEN */
+ u_long icps_checksum; /* bad checksum */
+ u_long icps_badlen; /* calculated bound mismatch */
+ u_long icps_reflect; /* number of responses */
+ u_long icps_inhist[ICMP_MAXTYPE + 1];
+ u_long icps_allecho; /* all echo requests dropped */
+ u_long icps_bmcastecho; /* b/mcast echo requests dropped */
+ u_long icps_bmcasttstamp; /* b/mcast tstamp requests dropped */
+};
+
+/*
+ * Names for ICMP sysctl objects
+ */
+#define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */
+#define ICMPCTL_STATS 2 /* statistics (read-only) */
+#define ICMPCTL_MAXID 3
+
+#define ICMPCTL_NAMES { \
+ { 0, 0 }, \
+ { "maskrepl", CTLTYPE_INT }, \
+ { "stats", CTLTYPE_STRUCT }, \
+}
+
+#ifdef _KERNEL
+SYSCTL_DECL(_net_inet_icmp);
+extern struct icmpstat icmpstat;
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/netinet/if_ether.c b/cpukit/libnetworking/netinet/if_ether.c
new file mode 100644
index 0000000000..56f6c6878a
--- /dev/null
+++ b/cpukit/libnetworking/netinet/if_ether.c
@@ -0,0 +1,651 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 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.
+ * 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.
+ *
+ * @(#)if_ether.c 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/if_ether.c,v 1.136 2005/03/13 11:23:22 glebius Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+/*
+ * Ethernet address resolution protocol.
+ * TODO:
+ * add "inuse/lock" bit (or ref. count) along with valid bit
+ */
+
+#include "opt_inet.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/queue.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/syslog.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/route.h>
+#include <net/netisr.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+
+#define SIN(s) ((struct sockaddr_in *)s)
+#define SDL(s) ((struct sockaddr_dl *)s)
+
+SYSCTL_DECL(_net_link_ether);
+SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, "");
+
+/* timer values */
+static int arpt_prune = (5*60*1); /* walk list every 5 minutes */
+static int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */
+static int arpt_down = 20; /* once declared down, don't send for 20 sec */
+
+SYSCTL_INT(_net_link_ether_inet, OID_AUTO, prune_intvl, CTLFLAG_RW,
+ &arpt_prune, 0, "");
+SYSCTL_INT(_net_link_ether_inet, OID_AUTO, max_age, CTLFLAG_RW,
+ &arpt_keep, 0, "");
+SYSCTL_INT(_net_link_ether_inet, OID_AUTO, host_down_time, CTLFLAG_RW,
+ &arpt_down, 0, "");
+
+#define rt_expire rt_rmx.rmx_expire
+
+struct llinfo_arp {
+ LIST_ENTRY(llinfo_arp) la_le;
+ struct rtentry *la_rt;
+ struct mbuf *la_hold; /* last packet until resolved/timeout */
+ long la_asked; /* last time we QUERIED for this addr */
+#define la_timer la_rt->rt_rmx.rmx_expire /* deletion time in seconds */
+};
+
+static LIST_HEAD(, llinfo_arp) llinfo_arp;
+
+struct ifqueue arpintrq = {0, 0, 0, 50};
+static int arp_inuse, arp_allocated;
+
+static int arp_maxtries = 5;
+static int useloopback = 1; /* use loopback interface for local traffic */
+static int arp_proxyall = 0;
+
+SYSCTL_INT(_net_link_ether_inet, OID_AUTO, maxtries, CTLFLAG_RW,
+ &arp_maxtries, 0, "");
+SYSCTL_INT(_net_link_ether_inet, OID_AUTO, useloopback, CTLFLAG_RW,
+ &useloopback, 0, "");
+SYSCTL_INT(_net_link_ether_inet, OID_AUTO, proxyall, CTLFLAG_RW,
+ &arp_proxyall, 0, "");
+
+static void arp_rtrequest __P((int, struct rtentry *, struct sockaddr *));
+static void arprequest __P((struct arpcom *, u_long *, u_long *, u_char *));
+void arpintr __P((void));
+static void arptfree(struct llinfo_arp *);
+static void arptimer(void *);
+static struct llinfo_arp
+ *arplookup(u_long, int, int);
+#ifdef INET
+static void in_arpinput(struct mbuf *);
+#endif
+
+/*
+ * Timeout routine. Age arp_tab entries periodically.
+ */
+/* ARGSUSED */
+static void
+arptimer(ignored_arg)
+ void *ignored_arg;
+{
+ int s = splnet();
+ struct llinfo_arp *la, *ola;
+
+ la = llinfo_arp.lh_first;
+ timeout(arptimer, (caddr_t)0, arpt_prune * hz);
+ while ((ola = la) != 0) {
+ register struct rtentry *rt = la->la_rt;
+ la = la->la_le.le_next;
+ if (rt->rt_expire && rt->rt_expire <= rtems_bsdnet_seconds_since_boot())
+ arptfree(ola); /* timer has expired, clear */
+ }
+ splx(s);
+}
+
+/*
+ * Parallel to llc_rtrequest.
+ */
+static void
+arp_rtrequest(req, rt, sa)
+ int req;
+ struct rtentry *rt;
+ struct sockaddr *sa;
+{
+ struct sockaddr *gate;
+ struct llinfo_arp *la;
+ static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
+ static int arpinit_done;
+
+ if (!arpinit_done) {
+ arpinit_done = 1;
+ LIST_INIT(&llinfo_arp);
+ timeout(arptimer, (caddr_t)0, hz);
+ }
+ if (rt->rt_flags & RTF_GATEWAY)
+ return;
+ gate = rt->rt_gateway;
+ la = (struct llinfo_arp *)rt->rt_llinfo;
+ switch (req) {
+
+ case RTM_ADD:
+ /*
+ * XXX: If this is a manually added route to interface
+ * such as older version of routed or gated might provide,
+ * restore cloning bit.
+ */
+ if ((rt->rt_flags & RTF_HOST) == 0 &&
+ rt_mask(rt) != NULL &&
+ SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
+ rt->rt_flags |= RTF_CLONING;
+ if (rt->rt_flags & RTF_CLONING) {
+ /*
+ * Case 1: This route should come from a route to iface.
+ */
+ rt_setgate(rt, rt_key(rt),
+ (struct sockaddr *)&null_sdl);
+ gate = rt->rt_gateway;
+ SDL(gate)->sdl_type = rt->rt_ifp->if_type;
+ SDL(gate)->sdl_index = rt->rt_ifp->if_index;
+ rt->rt_expire = rtems_bsdnet_seconds_since_boot();
+ break;
+ }
+ /* Announce a new entry if requested. */
+ if (rt->rt_flags & RTF_ANNOUNCE)
+ arprequest((struct arpcom *)rt->rt_ifp,
+ &SIN(rt_key(rt))->sin_addr.s_addr,
+ &SIN(rt_key(rt))->sin_addr.s_addr,
+ (u_char *)LLADDR(SDL(gate)));
+ /*FALLTHROUGH*/
+ case RTM_RESOLVE:
+ if (gate->sa_family != AF_LINK ||
+ gate->sa_len < sizeof(null_sdl)) {
+ log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
+ break;
+ }
+ SDL(gate)->sdl_type = rt->rt_ifp->if_type;
+ SDL(gate)->sdl_index = rt->rt_ifp->if_index;
+ if (la != 0)
+ break; /* This happens on a route change */
+ /*
+ * Case 2: This route may come from cloning, or a manual route
+ * add with a LL address.
+ */
+ R_Malloc(la, struct llinfo_arp *, sizeof(*la));
+ rt->rt_llinfo = (caddr_t)la;
+ if (la == 0) {
+ log(LOG_DEBUG, "arp_rtrequest: malloc failed\n");
+ break;
+ }
+ arp_inuse++;
+ arp_allocated++;
+ Bzero(la, sizeof(*la));
+ la->la_rt = rt;
+ rt->rt_flags |= RTF_LLINFO;
+ LIST_INSERT_HEAD(&llinfo_arp, la, la_le);
+
+ /*
+ * This keeps the multicast addresses from showing up
+ * in `arp -a' listings as unresolved. It's not actually
+ * functional. Then the same for broadcast.
+ */
+ if (IN_MULTICAST(ntohl(SIN(rt_key(rt))->sin_addr.s_addr))) {
+ ETHER_MAP_IP_MULTICAST(&SIN(rt_key(rt))->sin_addr,
+ LLADDR(SDL(gate)));
+ SDL(gate)->sdl_alen = 6;
+ rt->rt_expire = 0;
+ }
+ if (in_broadcast(SIN(rt_key(rt))->sin_addr, rt->rt_ifp)) {
+ memcpy(LLADDR(SDL(gate)), etherbroadcastaddr, 6);
+ SDL(gate)->sdl_alen = 6;
+ rt->rt_expire = 0;
+ }
+
+ if (SIN(rt_key(rt))->sin_addr.s_addr ==
+ (IA_SIN(rt->rt_ifa))->sin_addr.s_addr) {
+ /*
+ * This test used to be
+ * if (loif.if_flags & IFF_UP)
+ * It allowed local traffic to be forced
+ * through the hardware by configuring the loopback down.
+ * However, it causes problems during network configuration
+ * for boards that can't receive packets they send.
+ * It is now necessary to clear "useloopback" and remove
+ * the route to force traffic out to the hardware.
+ */
+ rt->rt_expire = 0;
+ Bcopy(((struct arpcom *)rt->rt_ifp)->ac_enaddr,
+ LLADDR(SDL(gate)), SDL(gate)->sdl_alen = 6);
+ if (useloopback)
+ rt->rt_ifp = loif;
+
+ }
+ break;
+
+ case RTM_DELETE:
+ if (la == 0)
+ break;
+ arp_inuse--;
+ LIST_REMOVE(la, la_le);
+ rt->rt_llinfo = 0;
+ rt->rt_flags &= ~RTF_LLINFO;
+ if (la->la_hold)
+ m_freem(la->la_hold);
+ Free((caddr_t)la);
+ }
+}
+
+/*
+ * Broadcast an ARP request. Caller specifies:
+ * - arp header source ip address
+ * - arp header target ip address
+ * - arp header source ethernet address
+ */
+static void
+arprequest(ac, sip, tip, enaddr)
+ struct arpcom *ac;
+ u_long *sip, *tip;
+ u_char *enaddr;
+{
+ struct mbuf *m;
+ struct ether_header *eh;
+ struct ether_arp *ea;
+ struct sockaddr sa;
+
+ if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
+ return;
+ m->m_len = sizeof(*ea);
+ m->m_pkthdr.len = sizeof(*ea);
+ MH_ALIGN(m, sizeof(*ea));
+ ea = mtod(m, struct ether_arp *);
+ eh = (struct ether_header *)sa.sa_data;
+ bzero((caddr_t)ea, sizeof (*ea));
+ (void)memcpy(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost));
+ eh->ether_type = htons(ETHERTYPE_ARP); /* if_output will not swap */
+ ea->arp_hrd = htons(ARPHRD_ETHER);
+ ea->arp_pro = htons(ETHERTYPE_IP);
+ ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */
+ ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */
+ ea->arp_op = htons(ARPOP_REQUEST);
+ (void)memcpy(ea->arp_sha, enaddr, sizeof(ea->arp_sha));
+ (void)memcpy(ea->arp_spa, sip, sizeof(ea->arp_spa));
+ (void)memcpy(ea->arp_tpa, tip, sizeof(ea->arp_tpa));
+ sa.sa_family = AF_UNSPEC;
+ sa.sa_len = sizeof(sa);
+ (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
+}
+
+/*
+ * Resolve an IP address into an ethernet address. If success,
+ * desten is filled in. If there is no entry in arptab,
+ * set one up and broadcast a request for the IP address.
+ * Hold onto this mbuf and resend it once the address
+ * is finally resolved. A return value of 1 indicates
+ * that desten has been filled in and the packet should be sent
+ * normally; a 0 return indicates that the packet has been
+ * taken over here, either now or for later transmission.
+ */
+int
+arpresolve(ac, rt, m, dst, desten, rt0)
+ struct arpcom *ac;
+ struct rtentry *rt;
+ struct mbuf *m;
+ struct sockaddr *dst;
+ u_char *desten;
+ struct rtentry *rt0;
+{
+ struct llinfo_arp *la = 0;
+ struct sockaddr_dl *sdl;
+
+ if (m->m_flags & M_BCAST) { /* broadcast */
+ (void)memcpy(desten, etherbroadcastaddr, sizeof(etherbroadcastaddr));
+ return (1);
+ }
+ if (m->m_flags & M_MCAST) { /* multicast */
+ ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
+ return(1);
+ }
+ if (rt)
+ la = (struct llinfo_arp *)rt->rt_llinfo;
+ else {
+ la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0);
+ if (la)
+ rt = la->la_rt;
+ }
+ if (la == 0 || rt == 0) {
+ log(LOG_DEBUG, "arpresolve: can't allocate llinfo for %s\n",
+ inet_ntoa(SIN(dst)->sin_addr));
+ m_freem(m);
+ return (0);
+ }
+ sdl = SDL(rt->rt_gateway);
+ /*
+ * Check the address family and length is valid, the address
+ * is resolved; otherwise, try to resolve.
+ */
+ if ((rt->rt_expire == 0 || rt->rt_expire > rtems_bsdnet_seconds_since_boot()) &&
+ sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
+ bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
+ return 1;
+ }
+ /*
+ * There is an arptab entry, but no ethernet address
+ * response yet. Replace the held mbuf with this
+ * latest one.
+ */
+ if (la->la_hold)
+ m_freem(la->la_hold);
+ la->la_hold = m;
+ if (rt->rt_expire) {
+ rt->rt_flags &= ~RTF_REJECT;
+ if (la->la_asked == 0 || rt->rt_expire != rtems_bsdnet_seconds_since_boot()) {
+ rt->rt_expire = rtems_bsdnet_seconds_since_boot();
+ if (la->la_asked++ < arp_maxtries)
+ arprequest(ac,
+ &(SIN(rt->rt_ifa->ifa_addr)->sin_addr.s_addr),
+ &(SIN(dst)->sin_addr.s_addr),
+ ac->ac_enaddr);
+ else {
+ rt->rt_flags |= RTF_REJECT;
+ rt->rt_expire += arpt_down;
+ la->la_asked = 0;
+ }
+
+ }
+ }
+ return (0);
+}
+
+/*
+ * Common length and type checks are done here,
+ * then the protocol-specific routine is called.
+ */
+void
+arpintr(void)
+{
+ struct mbuf *m;
+ struct arphdr *ar;
+ int s;
+
+ while (arpintrq.ifq_head) {
+ s = splimp();
+ IF_DEQUEUE(&arpintrq, m);
+ splx(s);
+ if (m == 0 || (m->m_flags & M_PKTHDR) == 0)
+ panic("arpintr");
+ if (m->m_len >= sizeof(struct arphdr) &&
+ (ar = mtod(m, struct arphdr *)) &&
+ ntohs(ar->ar_hrd) == ARPHRD_ETHER &&
+ m->m_len >=
+ sizeof(struct arphdr) + 2 * ar->ar_hln + 2 * ar->ar_pln)
+
+ switch (ntohs(ar->ar_pro)) {
+
+ case ETHERTYPE_IP:
+ in_arpinput(m);
+ continue;
+ }
+ m_freem(m);
+ }
+}
+
+NETISR_SET(NETISR_ARP, arpintr);
+
+/*
+ * ARP for Internet protocols on 10 Mb/s Ethernet.
+ * Algorithm is that given in RFC 826.
+ * In addition, a sanity check is performed on the sender
+ * protocol address, to catch impersonators.
+ * We no longer handle negotiations for use of trailer protocol:
+ * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent
+ * along with IP replies if we wanted trailers sent to us,
+ * and also sent them in response to IP replies.
+ * This allowed either end to announce the desire to receive
+ * trailer packets.
+ * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
+ * but formerly didn't normally send requests.
+ */
+static void
+in_arpinput(m)
+ struct mbuf *m;
+{
+ struct ether_arp *ea;
+ struct arpcom *ac = (struct arpcom *)m->m_pkthdr.rcvif;
+ struct ether_header *eh;
+ struct llinfo_arp *la = 0;
+ struct rtentry *rt;
+ struct in_ifaddr *ia;
+ struct in_ifaddr *maybe_ia = 0;
+ struct sockaddr_dl *sdl;
+ struct sockaddr sa;
+ struct in_addr isaddr, itaddr, myaddr;
+ int op;
+
+ ea = mtod(m, struct ether_arp *);
+ op = ntohs(ea->arp_op);
+ (void)memcpy(&isaddr, ea->arp_spa, sizeof (isaddr));
+ (void)memcpy(&itaddr, ea->arp_tpa, sizeof (itaddr));
+ for (ia = in_ifaddr; ia; ia = ia->ia_next)
+ if (ia->ia_ifp == &ac->ac_if) {
+ maybe_ia = ia;
+ if ((itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) ||
+ (isaddr.s_addr == ia->ia_addr.sin_addr.s_addr))
+ break;
+ }
+ if (maybe_ia == 0) {
+ m_freem(m);
+ return;
+ }
+ myaddr = ia ? ia->ia_addr.sin_addr : maybe_ia->ia_addr.sin_addr;
+ if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)ac->ac_enaddr,
+ sizeof (ea->arp_sha))) {
+ m_freem(m); /* it's from me, ignore it. */
+ return;
+ }
+ if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr,
+ sizeof (ea->arp_sha))) {
+ log(LOG_ERR,
+ "arp: ether address is broadcast for IP address %s!\n",
+ inet_ntoa(isaddr));
+ m_freem(m);
+ return;
+ }
+ if (isaddr.s_addr == myaddr.s_addr) {
+ log(LOG_ERR,
+ "arp: %6D is using my IP address %s!\n",
+ ea->arp_sha, ":", inet_ntoa(isaddr));
+ itaddr = myaddr;
+ goto reply;
+ }
+ la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);
+ if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
+ if (sdl->sdl_alen &&
+ bcmp((caddr_t)ea->arp_sha, LLADDR(sdl), sdl->sdl_alen))
+ log(LOG_INFO, "arp: %s moved from %6D to %6D\n",
+ inet_ntoa(isaddr), (u_char *)LLADDR(sdl), ":",
+ ea->arp_sha, ":");
+ (void)memcpy(LLADDR(sdl), ea->arp_sha, sizeof(ea->arp_sha));
+ sdl->sdl_alen = sizeof(ea->arp_sha);
+ if (rt->rt_expire)
+ rt->rt_expire = rtems_bsdnet_seconds_since_boot() + arpt_keep;
+ rt->rt_flags &= ~RTF_REJECT;
+ la->la_asked = 0;
+ if (la->la_hold) {
+ (*ac->ac_if.if_output)(&ac->ac_if, la->la_hold,
+ rt_key(rt), rt);
+ la->la_hold = 0;
+ }
+ }
+reply:
+ if (op != ARPOP_REQUEST) {
+ m_freem(m);
+ return;
+ }
+ if (itaddr.s_addr == myaddr.s_addr) {
+ /* I am the target */
+ (void)memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
+ (void)memcpy(ea->arp_sha, ac->ac_enaddr, sizeof(ea->arp_sha));
+ } else {
+ la = arplookup(itaddr.s_addr, 0, SIN_PROXY);
+ if (la == NULL) {
+ struct sockaddr_in sin;
+
+ if (!arp_proxyall) {
+ m_freem(m);
+ return;
+ }
+
+ bzero(&sin, sizeof sin);
+ sin.sin_family = AF_INET;
+ sin.sin_len = sizeof sin;
+ sin.sin_addr = itaddr;
+
+ rt = rtalloc1((struct sockaddr *)&sin, 0, 0UL);
+ if (!rt) {
+ m_freem(m);
+ return;
+ }
+ /*
+ * Don't send proxies for nodes on the same interface
+ * as this one came out of, or we'll get into a fight
+ * over who claims what Ether address.
+ */
+ if (rt->rt_ifp == &ac->ac_if) {
+ rtfree(rt);
+ m_freem(m);
+ return;
+ }
+ (void)memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
+ (void)memcpy(ea->arp_sha, ac->ac_enaddr, sizeof(ea->arp_sha));
+ rtfree(rt);
+#ifdef DEBUG_PROXY
+ printf("arp: proxying for %s\n",
+ inet_ntoa(itaddr));
+#endif
+ } else {
+ rt = la->la_rt;
+ (void)memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
+ sdl = SDL(rt->rt_gateway);
+ (void)memcpy(ea->arp_sha, LLADDR(sdl), sizeof(ea->arp_sha));
+ }
+ }
+
+ (void)memcpy(ea->arp_tpa, ea->arp_spa, sizeof(ea->arp_spa));
+ (void)memcpy(ea->arp_spa, &itaddr, sizeof(ea->arp_spa));
+ ea->arp_op = htons(ARPOP_REPLY);
+ ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
+ eh = (struct ether_header *)sa.sa_data;
+ (void)memcpy(eh->ether_dhost, ea->arp_tha, sizeof(eh->ether_dhost));
+ eh->ether_type = htons(ETHERTYPE_ARP);
+ sa.sa_family = AF_UNSPEC;
+ sa.sa_len = sizeof(sa);
+ (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
+ return;
+}
+
+/*
+ * Free an arp entry.
+ */
+static void
+arptfree(la)
+ struct llinfo_arp *la;
+{
+ struct rtentry *rt = la->la_rt;
+ struct sockaddr_dl *sdl;
+ if (rt == 0)
+ panic("arptfree");
+ if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&
+ sdl->sdl_family == AF_LINK) {
+ sdl->sdl_alen = 0;
+ la->la_asked = 0;
+ rt->rt_flags &= ~RTF_REJECT;
+ return;
+ }
+ rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt),
+ 0, (struct rtentry **)0);
+}
+/*
+ * Lookup or enter a new address in arptab.
+ */
+static struct llinfo_arp *
+arplookup(addr, create, proxy)
+ u_long addr;
+ int create, proxy;
+{
+ struct rtentry *rt;
+ static struct sockaddr_inarp sin = {sizeof(sin), AF_INET };
+ const char *why = 0;
+
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = addr;
+ sin.sin_other = proxy ? SIN_PROXY : 0;
+ rt = rtalloc1((struct sockaddr *)&sin, create, 0UL);
+ if (rt == 0)
+ return (0);
+ rt->rt_refcnt--;
+
+ if (rt->rt_flags & RTF_GATEWAY)
+ why = "host is not on local network";
+ else if ((rt->rt_flags & RTF_LLINFO) == 0)
+ why = "could not allocate llinfo";
+ else if (rt->rt_gateway->sa_family != AF_LINK)
+ why = "gateway route is not ours";
+
+ if (why && create) {
+ log(LOG_DEBUG, "arplookup %s failed: %s\n",
+ inet_ntoa(sin.sin_addr), why);
+ return 0;
+ } else if (why) {
+ return 0;
+ }
+ return ((struct llinfo_arp *)rt->rt_llinfo);
+}
+
+void
+arp_ifinit(ac, ifa)
+ struct arpcom *ac;
+ struct ifaddr *ifa;
+{
+ if (ntohl(IA_SIN(ifa)->sin_addr.s_addr) != INADDR_ANY)
+ arprequest(ac, &(IA_SIN(ifa)->sin_addr.s_addr),
+ &(IA_SIN(ifa)->sin_addr.s_addr), ac->ac_enaddr);
+ ifa->ifa_rtrequest = arp_rtrequest;
+ ifa->ifa_flags |= RTF_CLONING;
+}
diff --git a/cpukit/libnetworking/netinet/if_ether.h b/cpukit/libnetworking/netinet/if_ether.h
new file mode 100644
index 0000000000..191b08e452
--- /dev/null
+++ b/cpukit/libnetworking/netinet/if_ether.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ * 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.
+ *
+ * @(#)if_ether.h 8.3 (Berkeley) 5/2/95
+ * $FreeBSD: src/sys/netinet/if_ether.h,v 1.32 2005/02/22 13:04:03 glebius Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NETINET_IF_ETHER_H_
+#define _NETINET_IF_ETHER_H_
+
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+
+#ifdef _KERNEL
+/*
+ * Macro to map an IP multicast address to an Ethernet multicast address.
+ * The high-order 25 bits of the Ethernet address are statically assigned,
+ * and the low-order 23 bits are taken from the low end of the IP address.
+ */
+#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
+ /* struct in_addr *ipaddr; */ \
+ /* u_char enaddr[ETHER_ADDR_LEN]; */ \
+{ \
+ (enaddr)[0] = 0x01; \
+ (enaddr)[1] = 0x00; \
+ (enaddr)[2] = 0x5e; \
+ (enaddr)[3] = ((u_char *)ipaddr)[1] & 0x7f; \
+ (enaddr)[4] = ((u_char *)ipaddr)[2]; \
+ (enaddr)[5] = ((u_char *)ipaddr)[3]; \
+}
+#endif
+
+/*
+ * Ethernet Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description. Structure below is adapted
+ * to resolving internet addresses. Field names used correspond to
+ * RFC 826.
+ */
+struct ether_arp {
+ struct arphdr ea_hdr; /* fixed-size header */
+ u_char arp_sha[ETHER_ADDR_LEN]; /* sender hardware address */
+ u_char arp_spa[4]; /* sender protocol address */
+ u_char arp_tha[ETHER_ADDR_LEN]; /* target hardware address */
+ u_char arp_tpa[4]; /* target protocol address */
+};
+#define arp_hrd ea_hdr.ar_hrd
+#define arp_pro ea_hdr.ar_pro
+#define arp_hln ea_hdr.ar_hln
+#define arp_pln ea_hdr.ar_pln
+#define arp_op ea_hdr.ar_op
+
+struct sockaddr_inarp {
+ u_char sin_len;
+ u_char sin_family;
+ u_short sin_port;
+ struct in_addr sin_addr;
+ struct in_addr sin_srcaddr;
+ u_short sin_tos;
+ u_short sin_other;
+#define SIN_PROXY 1
+};
+/*
+ * IP and ethernet specific routing flags
+ */
+#define RTF_USETRAILERS RTF_PROTO1 /* use trailers */
+#define RTF_ANNOUNCE RTF_PROTO2 /* announce new arp entry */
+
+#ifdef _KERNEL
+extern u_char etherbroadcastaddr[ETHER_ADDR_LEN];
+extern u_char ether_ipmulticast_min[ETHER_ADDR_LEN];
+extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN];
+extern struct ifqueue arpintrq;
+
+int arpresolve __P((struct arpcom *, struct rtentry *, struct mbuf *,
+ struct sockaddr *, u_char *, struct rtentry *));
+void arp_ifinit __P((struct arpcom *, struct ifaddr *));
+int ether_addmulti __P((struct ifreq *, struct arpcom *));
+int ether_delmulti __P((struct ifreq *, struct arpcom *));
+
+/*
+ * Ethernet multicast address structure. There is one of these for each
+ * multicast address or range of multicast addresses that we are supposed
+ * to listen to on a particular interface. They are kept in a linked list,
+ * rooted in the interface's arpcom structure. (This really has nothing to
+ * do with ARP, or with the Internet address family, but this appears to be
+ * the minimally-disrupting place to put it.)
+ */
+struct ether_multi {
+ u_char enm_addrlo[ETHER_ADDR_LEN]; /* low or only address of range */
+ u_char enm_addrhi[ETHER_ADDR_LEN]; /* high or only address of range */
+ struct arpcom *enm_ac; /* back pointer to arpcom */
+ u_int enm_refcount; /* no. claims to this addr/range */
+ struct ether_multi *enm_next; /* ptr to next ether_multi */
+};
+
+/*
+ * Structure used by macros below to remember position when stepping through
+ * all of the ether_multi records.
+ */
+struct ether_multistep {
+ struct ether_multi *e_enm;
+};
+
+/*
+ * Macro for looking up the ether_multi record for a given range of Ethernet
+ * multicast addresses connected to a given arpcom structure. If no matching
+ * record is found, "enm" returns NULL.
+ */
+#define ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm) \
+ /* u_char addrlo[ETHER_ADDR_LEN]; */ \
+ /* u_char addrhi[ETHER_ADDR_LEN]; */ \
+ /* struct arpcom *ac; */ \
+ /* struct ether_multi *enm; */ \
+{ \
+ for ((enm) = (ac)->ac_multiaddrs; \
+ (enm) != NULL && \
+ (bcmp((enm)->enm_addrlo, (addrlo), ETHER_ADDR_LEN) != 0 || \
+ bcmp((enm)->enm_addrhi, (addrhi), ETHER_ADDR_LEN) != 0); \
+ (enm) = (enm)->enm_next); \
+}
+
+/*
+ * Macro to step through all of the ether_multi records, one at a time.
+ * The current position is remembered in "step", which the caller must
+ * provide. ETHER_FIRST_MULTI(), below, must be called to initialize "step"
+ * and get the first record. Both macros return a NULL "enm" when there
+ * are no remaining records.
+ */
+#define ETHER_NEXT_MULTI(step, enm) \
+ /* struct ether_multistep step; */ \
+ /* struct ether_multi *enm; */ \
+{ \
+ if (((enm) = (step).e_enm) != NULL) \
+ (step).e_enm = (enm)->enm_next; \
+}
+
+#define ETHER_FIRST_MULTI(step, ac, enm) \
+ /* struct ether_multistep step; */ \
+ /* struct arpcom *ac; */ \
+ /* struct ether_multi *enm; */ \
+{ \
+ (step).e_enm = (ac)->ac_multiaddrs; \
+ ETHER_NEXT_MULTI((step), (enm)); \
+}
+
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/netinet/igmp.c b/cpukit/libnetworking/netinet/igmp.c
new file mode 100644
index 0000000000..2af8b7038e
--- /dev/null
+++ b/cpukit/libnetworking/netinet/igmp.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 1988 Stephen Deering.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Stephen Deering of Stanford University.
+ *
+ * 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.
+ *
+ * @(#)igmp.c 8.1 (Berkeley) 7/19/93
+ * $Id$
+ */
+
+/*
+ * Internet Group Management Protocol (IGMP) routines.
+ *
+ * Written by Steve Deering, Stanford, May 1988.
+ * Modified by Rosen Sharma, Stanford, Aug 1994.
+ * Modified by Bill Fenner, Xerox PARC, Feb 1995.
+ * Modified to fully comply to IGMPv2 by Bill Fenner, Oct 1995.
+ *
+ * MULTICAST Revision: 3.5.1.4
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/igmp.h>
+#include <netinet/igmp_var.h>
+
+static struct router_info *
+ find_rti __P((struct ifnet *ifp));
+
+static struct igmpstat igmpstat;
+
+SYSCTL_STRUCT(_net_inet_igmp, IGMPCTL_STATS, stats, CTLFLAG_RD,
+ &igmpstat, igmpstat, "");
+
+static int igmp_timers_are_running;
+static u_long igmp_all_hosts_group;
+static u_long igmp_all_rtrs_group;
+static struct mbuf *router_alert;
+static struct router_info *Head;
+
+static void igmp_sendpkt(struct in_multi *, int, unsigned long);
+
+void
+igmp_init()
+{
+ struct ipoption *ra;
+
+ /*
+ * To avoid byte-swapping the same value over and over again.
+ */
+ igmp_all_hosts_group = htonl(INADDR_ALLHOSTS_GROUP);
+ igmp_all_rtrs_group = htonl(INADDR_ALLRTRS_GROUP);
+
+ igmp_timers_are_running = 0;
+
+ /*
+ * Construct a Router Alert option to use in outgoing packets
+ */
+ MGET(router_alert, M_DONTWAIT, MT_DATA);
+ ra = mtod(router_alert, struct ipoption *);
+ ra->ipopt_dst.s_addr = 0;
+ ra->ipopt_list[0] = IPOPT_RA; /* Router Alert Option */
+ ra->ipopt_list[1] = 0x04; /* 4 bytes long */
+ ra->ipopt_list[2] = 0x00;
+ ra->ipopt_list[3] = 0x00;
+ router_alert->m_len = sizeof(ra->ipopt_dst) + ra->ipopt_list[1];
+
+ Head = (struct router_info *) 0;
+}
+
+static struct router_info *
+find_rti(ifp)
+ struct ifnet *ifp;
+{
+ register struct router_info *rti = Head;
+
+#ifdef IGMP_DEBUG
+ printf("[igmp.c, _find_rti] --> entering \n");
+#endif
+ while (rti) {
+ if (rti->rti_ifp == ifp) {
+#ifdef IGMP_DEBUG
+ printf("[igmp.c, _find_rti] --> found old entry \n");
+#endif
+ return rti;
+ }
+ rti = rti->rti_next;
+ }
+ MALLOC(rti, struct router_info *, sizeof *rti, M_MRTABLE, M_NOWAIT);
+ rti->rti_ifp = ifp;
+ rti->rti_type = IGMP_V2_ROUTER;
+ rti->rti_time = 0;
+ rti->rti_next = Head;
+ Head = rti;
+#ifdef IGMP_DEBUG
+ printf("[igmp.c, _find_rti] --> created an entry \n");
+#endif
+ return rti;
+}
+
+void
+igmp_input(m, iphlen)
+ register struct mbuf *m;
+ register int iphlen;
+{
+ register struct igmp *igmp;
+ register struct ip *ip;
+ register int igmplen;
+ register struct ifnet *ifp = m->m_pkthdr.rcvif;
+ register int minlen;
+ register struct in_multi *inm;
+ register struct in_ifaddr *ia;
+ struct in_multistep step;
+ struct router_info *rti;
+
+ int timer; /** timer value in the igmp query header **/
+
+ ++igmpstat.igps_rcv_total;
+
+ ip = mtod(m, struct ip *);
+ igmplen = ip->ip_len;
+
+ /*
+ * Validate lengths
+ */
+ if (igmplen < IGMP_MINLEN) {
+ ++igmpstat.igps_rcv_tooshort;
+ m_freem(m);
+ return;
+ }
+ minlen = iphlen + IGMP_MINLEN;
+ if ((m->m_flags & M_EXT || m->m_len < minlen) &&
+ (m = m_pullup(m, minlen)) == 0) {
+ ++igmpstat.igps_rcv_tooshort;
+ return;
+ }
+
+ /*
+ * Validate checksum
+ */
+ m->m_data += iphlen;
+ m->m_len -= iphlen;
+ igmp = mtod(m, struct igmp *);
+ if (in_cksum(m, igmplen)) {
+ ++igmpstat.igps_rcv_badsum;
+ m_freem(m);
+ return;
+ }
+ m->m_data -= iphlen;
+ m->m_len += iphlen;
+
+ ip = mtod(m, struct ip *);
+ timer = igmp->igmp_code * PR_FASTHZ / IGMP_TIMER_SCALE;
+ rti = find_rti(ifp);
+
+ /*
+ * In the IGMPv2 specification, there are 3 states and a flag.
+ *
+ * In Non-Member state, we simply don't have a membership record.
+ * In Delaying Member state, our timer is running (inm->inm_timer)
+ * In Idle Member state, our timer is not running (inm->inm_timer==0)
+ *
+ * The flag is inm->inm_state, it is set to IGMP_OTHERMEMBER if
+ * we have heard a report from another member, or IGMP_IREPORTEDLAST
+ * if I sent the last report.
+ */
+ switch (igmp->igmp_type) {
+
+ case IGMP_MEMBERSHIP_QUERY:
+ ++igmpstat.igps_rcv_queries;
+
+ if (ifp->if_flags & IFF_LOOPBACK)
+ break;
+
+ if (igmp->igmp_code == 0) {
+ /*
+ * Old router. Remember that the querier on this
+ * interface is old, and set the timer to the
+ * value in RFC 1112.
+ */
+
+ rti->rti_type = IGMP_V1_ROUTER;
+ rti->rti_time = 0;
+
+ timer = IGMP_MAX_HOST_REPORT_DELAY * PR_FASTHZ;
+
+ if (ip->ip_dst.s_addr != igmp_all_hosts_group ||
+ igmp->igmp_group.s_addr != 0) {
+ ++igmpstat.igps_rcv_badqueries;
+ m_freem(m);
+ return;
+ }
+ } else {
+ /*
+ * New router. Simply do the new validity check.
+ */
+
+ if (igmp->igmp_group.s_addr != 0 &&
+ !IN_MULTICAST(ntohl(igmp->igmp_group.s_addr))) {
+ ++igmpstat.igps_rcv_badqueries;
+ m_freem(m);
+ return;
+ }
+ }
+
+ /*
+ * - Start the timers in all of our membership records
+ * that the query applies to for the interface on
+ * which the query arrived excl. those that belong
+ * to the "all-hosts" group (224.0.0.1).
+ * - Restart any timer that is already running but has
+ * a value longer than the requested timeout.
+ * - Use the value specified in the query message as
+ * the maximum timeout.
+ */
+ IN_FIRST_MULTI(step, inm);
+ while (inm != NULL) {
+ if (inm->inm_ifp == ifp &&
+ inm->inm_addr.s_addr != igmp_all_hosts_group &&
+ (igmp->igmp_group.s_addr == 0 ||
+ igmp->igmp_group.s_addr == inm->inm_addr.s_addr)) {
+ if (inm->inm_timer == 0 ||
+ inm->inm_timer > timer) {
+ inm->inm_timer =
+ IGMP_RANDOM_DELAY(timer);
+ igmp_timers_are_running = 1;
+ }
+ }
+ IN_NEXT_MULTI(step, inm);
+ }
+
+ break;
+
+ case IGMP_V1_MEMBERSHIP_REPORT:
+ case IGMP_V2_MEMBERSHIP_REPORT:
+ /*
+ * For fast leave to work, we have to know that we are the
+ * last person to send a report for this group. Reports
+ * can potentially get looped back if we are a multicast
+ * router, so discard reports sourced by me.
+ */
+ IFP_TO_IA(ifp, ia);
+ if (ia && ip->ip_src.s_addr == IA_SIN(ia)->sin_addr.s_addr)
+ break;
+
+ ++igmpstat.igps_rcv_reports;
+
+ if (ifp->if_flags & IFF_LOOPBACK)
+ break;
+
+ if (!IN_MULTICAST(ntohl(igmp->igmp_group.s_addr))) {
+ ++igmpstat.igps_rcv_badreports;
+ m_freem(m);
+ return;
+ }
+
+ /*
+ * KLUDGE: if the IP source address of the report has an
+ * unspecified (i.e., zero) subnet number, as is allowed for
+ * a booting host, replace it with the correct subnet number
+ * so that a process-level multicast routing demon can
+ * determine which subnet it arrived from. This is necessary
+ * to compensate for the lack of any way for a process to
+ * determine the arrival interface of an incoming packet.
+ */
+ if ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) == 0)
+ if (ia) ip->ip_src.s_addr = htonl(ia->ia_subnet);
+
+ /*
+ * If we belong to the group being reported, stop
+ * our timer for that group.
+ */
+ IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm);
+
+ if (inm != NULL) {
+ inm->inm_timer = 0;
+ ++igmpstat.igps_rcv_ourreports;
+
+ inm->inm_state = IGMP_OTHERMEMBER;
+ }
+
+ break;
+ }
+
+ /*
+ * Pass all valid IGMP packets up to any process(es) listening
+ * on a raw IGMP socket.
+ */
+ rip_input(m, iphlen);
+}
+
+void
+igmp_joingroup(inm)
+ struct in_multi *inm;
+{
+ int s = splnet();
+
+ if (inm->inm_addr.s_addr == igmp_all_hosts_group
+ || inm->inm_ifp->if_flags & IFF_LOOPBACK) {
+ inm->inm_timer = 0;
+ inm->inm_state = IGMP_OTHERMEMBER;
+ } else {
+ inm->inm_rti = find_rti(inm->inm_ifp);
+ igmp_sendpkt(inm, inm->inm_rti->rti_type, 0);
+ inm->inm_timer = IGMP_RANDOM_DELAY(
+ IGMP_MAX_HOST_REPORT_DELAY*PR_FASTHZ);
+ inm->inm_state = IGMP_IREPORTEDLAST;
+ igmp_timers_are_running = 1;
+ }
+ splx(s);
+}
+
+void
+igmp_leavegroup(inm)
+ struct in_multi *inm;
+{
+ if (inm->inm_state == IGMP_IREPORTEDLAST &&
+ inm->inm_addr.s_addr != igmp_all_hosts_group &&
+ !(inm->inm_ifp->if_flags & IFF_LOOPBACK) &&
+ inm->inm_rti->rti_type != IGMP_V1_ROUTER)
+ igmp_sendpkt(inm, IGMP_V2_LEAVE_GROUP, igmp_all_rtrs_group);
+}
+
+void
+igmp_fasttimo()
+{
+ register struct in_multi *inm;
+ struct in_multistep step;
+ int s;
+
+ /*
+ * Quick check to see if any work needs to be done, in order
+ * to minimize the overhead of fasttimo processing.
+ */
+
+ if (!igmp_timers_are_running)
+ return;
+
+ s = splnet();
+ igmp_timers_are_running = 0;
+ IN_FIRST_MULTI(step, inm);
+ while (inm != NULL) {
+ if (inm->inm_timer == 0) {
+ /* do nothing */
+ } else if (--inm->inm_timer == 0) {
+ igmp_sendpkt(inm, inm->inm_rti->rti_type, 0);
+ inm->inm_state = IGMP_IREPORTEDLAST;
+ } else {
+ igmp_timers_are_running = 1;
+ }
+ IN_NEXT_MULTI(step, inm);
+ }
+ splx(s);
+}
+
+void
+igmp_slowtimo()
+{
+ int s = splnet();
+ register struct router_info *rti = Head;
+
+#ifdef IGMP_DEBUG
+ printf("[igmp.c,_slowtimo] -- > entering \n");
+#endif
+ while (rti) {
+ if (rti->rti_type == IGMP_V1_ROUTER) {
+ rti->rti_time++;
+ if (rti->rti_time >= IGMP_AGE_THRESHOLD) {
+ rti->rti_type = IGMP_V2_ROUTER;
+ }
+ }
+ rti = rti->rti_next;
+ }
+#ifdef IGMP_DEBUG
+ printf("[igmp.c,_slowtimo] -- > exiting \n");
+#endif
+ splx(s);
+}
+
+static struct route igmprt;
+
+static void
+igmp_sendpkt(inm, type, addr)
+ struct in_multi *inm;
+ int type;
+ unsigned long addr;
+{
+ struct mbuf *m;
+ struct igmp *igmp;
+ struct ip *ip;
+ struct ip_moptions imo;
+
+ MGETHDR(m, M_DONTWAIT, MT_HEADER);
+ if (m == NULL)
+ return;
+
+ m->m_pkthdr.rcvif = loif;
+ m->m_pkthdr.len = sizeof(struct ip) + IGMP_MINLEN;
+ MH_ALIGN(m, IGMP_MINLEN + sizeof(struct ip));
+ m->m_data += sizeof(struct ip);
+ m->m_len = IGMP_MINLEN;
+ igmp = mtod(m, struct igmp *);
+ igmp->igmp_type = type;
+ igmp->igmp_code = 0;
+ igmp->igmp_group = inm->inm_addr;
+ igmp->igmp_cksum = 0;
+ igmp->igmp_cksum = in_cksum(m, IGMP_MINLEN);
+
+ m->m_data -= sizeof(struct ip);
+ m->m_len += sizeof(struct ip);
+ ip = mtod(m, struct ip *);
+ ip->ip_tos = 0;
+ ip->ip_len = sizeof(struct ip) + IGMP_MINLEN;
+ ip->ip_off = 0;
+ ip->ip_p = IPPROTO_IGMP;
+ ip->ip_src.s_addr = INADDR_ANY;
+ ip->ip_dst.s_addr = addr ? addr : igmp->igmp_group.s_addr;
+
+ imo.imo_multicast_ifp = inm->inm_ifp;
+ imo.imo_multicast_ttl = 1;
+ imo.imo_multicast_vif = -1;
+ /*
+ * Request loopback of the report if we are acting as a multicast
+ * router, so that the process-level routing demon can hear it.
+ */
+ imo.imo_multicast_loop = (ip_mrouter != NULL);
+
+ /*
+ * XXX
+ * Do we have to worry about reentrancy here? Don't think so.
+ */
+ ip_output(m, router_alert, &igmprt, 0, &imo);
+
+ ++igmpstat.igps_snd_reports;
+}
diff --git a/cpukit/libnetworking/netinet/igmp.h b/cpukit/libnetworking/netinet/igmp.h
new file mode 100644
index 0000000000..01d6d09179
--- /dev/null
+++ b/cpukit/libnetworking/netinet/igmp.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1988 Stephen Deering.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Stephen Deering of Stanford University.
+ *
+ * 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.
+ *
+ * @(#)igmp.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NETINET_IGMP_H_
+#define _NETINET_IGMP_H_
+
+/*
+ * Internet Group Management Protocol (IGMP) definitions.
+ *
+ * Written by Steve Deering, Stanford, May 1988.
+ *
+ * MULTICAST Revision: 3.5.1.2
+ */
+
+/*
+ * IGMP packet format.
+ */
+struct igmp {
+ u_char igmp_type; /* version & type of IGMP message */
+ u_char igmp_code; /* subtype for routing msgs */
+ u_short igmp_cksum; /* IP-style checksum */
+ struct in_addr igmp_group; /* group address being reported */
+}; /* (zero for queries) */
+
+#define IGMP_MINLEN 8
+
+/*
+ * Message types, including version number.
+ */
+#define IGMP_MEMBERSHIP_QUERY 0x11 /* membership query */
+#define IGMP_V1_MEMBERSHIP_REPORT 0x12 /* Ver. 1 membership report */
+#define IGMP_V2_MEMBERSHIP_REPORT 0x16 /* Ver. 2 membership report */
+#define IGMP_V2_LEAVE_GROUP 0x17 /* Leave-group message */
+
+#define IGMP_DVMRP 0x13 /* DVMRP routing message */
+#define IGMP_PIM 0x14 /* PIM routing message */
+
+#define IGMP_MTRACE_RESP 0x1e /* traceroute resp.(to sender)*/
+#define IGMP_MTRACE 0x1f /* mcast traceroute messages */
+
+#define IGMP_MAX_HOST_REPORT_DELAY 10 /* max delay for response to */
+ /* query (in seconds) according */
+ /* to RFC1112 */
+
+
+#define IGMP_TIMER_SCALE 10 /* denotes that the igmp code field */
+ /* specifies time in 10th of seconds*/
+
+/*
+ * The following four defininitions are for backwards compatibility.
+ * They should be removed as soon as all applications are updated to
+ * use the new constant names.
+ */
+#define IGMP_HOST_MEMBERSHIP_QUERY IGMP_MEMBERSHIP_QUERY
+#define IGMP_HOST_MEMBERSHIP_REPORT IGMP_V1_MEMBERSHIP_REPORT
+#define IGMP_HOST_NEW_MEMBERSHIP_REPORT IGMP_V2_MEMBERSHIP_REPORT
+#define IGMP_HOST_LEAVE_MESSAGE IGMP_V2_LEAVE_GROUP
+
+#endif /* _NETINET_IGMP_H_ */
diff --git a/cpukit/libnetworking/netinet/igmp_var.h b/cpukit/libnetworking/netinet/igmp_var.h
new file mode 100644
index 0000000000..d1454e0521
--- /dev/null
+++ b/cpukit/libnetworking/netinet/igmp_var.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1988 Stephen Deering.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Stephen Deering of Stanford University.
+ *
+ * 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.
+ * 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.
+ *
+ * from: @(#)igmp_var.h 8.1 (Berkeley) 7/19/93
+ * $FreeBSD: src/sys/netinet/igmp_var.h,v 1.20 2004/04/07 20:46:13 imp Exp $
+ */
+
+#ifndef _NETINET_IGMP_VAR_H_
+#define _NETINET_IGMP_VAR_H_
+
+/*
+ * Internet Group Management Protocol (IGMP),
+ * implementation-specific definitions.
+ *
+ * Written by Steve Deering, Stanford, May 1988.
+ *
+ * MULTICAST Revision: 3.5.1.3
+ */
+
+struct igmpstat {
+ u_int igps_rcv_total; /* total IGMP messages received */
+ u_int igps_rcv_tooshort; /* received with too few bytes */
+ u_int igps_rcv_badsum; /* received with bad checksum */
+ u_int igps_rcv_queries; /* received membership queries */
+ u_int igps_rcv_badqueries; /* received invalid queries */
+ u_int igps_rcv_reports; /* received membership reports */
+ u_int igps_rcv_badreports; /* received invalid reports */
+ u_int igps_rcv_ourreports; /* received reports for our groups */
+ u_int igps_snd_reports; /* sent membership reports */
+};
+
+#ifdef _KERNEL
+#define IGMP_RANDOM_DELAY(X) (random() % (X) + 1)
+
+/*
+ * States for IGMPv2's leave processing
+ */
+#define IGMP_OTHERMEMBER 0
+#define IGMP_IREPORTEDLAST 1
+
+/*
+ * We must remember what version the subnet's querier is.
+ * We conveniently use the IGMP message type for the proper
+ * membership report to keep this state.
+ */
+#define IGMP_V1_ROUTER IGMP_V1_MEMBERSHIP_REPORT
+#define IGMP_V2_ROUTER IGMP_V2_MEMBERSHIP_REPORT
+
+/*
+ * Revert to new router if we haven't heard from an old router in
+ * this amount of time.
+ */
+#define IGMP_AGE_THRESHOLD 540
+
+void igmp_init(void);
+void igmp_input(struct mbuf *, int);
+void igmp_joingroup(struct in_multi *);
+void igmp_leavegroup(struct in_multi *);
+void igmp_fasttimo(void);
+void igmp_slowtimo(void);
+
+SYSCTL_DECL(_net_inet_igmp);
+
+#endif
+
+/*
+ * Names for IGMP sysctl objects
+ */
+#define IGMPCTL_STATS 1 /* statistics (read-only) */
+#define IGMPCTL_MAXID 2
+
+#define IGMPCTL_NAMES { \
+ { 0, 0 }, \
+ { "stats", CTLTYPE_STRUCT }, \
+}
+#endif
diff --git a/cpukit/libnetworking/netinet/in.c b/cpukit/libnetworking/netinet/in.c
new file mode 100644
index 0000000000..3b246fd210
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in.c
@@ -0,0 +1,723 @@
+/*
+ * Copyright (c) 1982, 1986, 1991, 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.
+ * 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.c 8.4 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/netinet/in.c,v 1.75 2004/04/07 20:46:13 imp Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+
+#include <netinet/igmp_var.h>
+
+/*
+ * This structure is used to keep track of in_multi chains which belong to
+ * deleted interface addresses.
+ */
+static LIST_HEAD(, multi_kludge) in_mk; /* XXX BSS initialization */
+
+struct multi_kludge {
+ LIST_ENTRY(multi_kludge) mk_entry;
+ struct ifnet *mk_ifp;
+ struct in_multihead mk_head;
+};
+
+static void in_socktrim __P((struct sockaddr_in *));
+static int in_ifinit __P((struct ifnet *,
+ struct in_ifaddr *, struct sockaddr_in *, int));
+static void in_ifscrub __P((struct ifnet *, struct in_ifaddr *));
+
+static int subnetsarelocal = 0;
+SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW,
+ &subnetsarelocal, 0, "");
+/*
+ * Return 1 if an internet address is for a ``local'' host
+ * (one to which we have a connection). If subnetsarelocal
+ * is true, this includes other subnets of the local net.
+ * Otherwise, it includes only the directly-connected (sub)nets.
+ */
+int
+in_localaddr(in)
+ struct in_addr in;
+{
+ register u_long i = ntohl(in.s_addr);
+ register struct in_ifaddr *ia;
+
+ if (subnetsarelocal) {
+ for (ia = in_ifaddr; ia; ia = ia->ia_next)
+ if ((i & ia->ia_netmask) == ia->ia_net)
+ return (1);
+ } else {
+ for (ia = in_ifaddr; ia; ia = ia->ia_next)
+ if ((i & ia->ia_subnetmask) == ia->ia_subnet)
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * Determine whether an IP address is in a reserved set of addresses
+ * that may not be forwarded, or whether datagrams to that destination
+ * may be forwarded.
+ */
+int
+in_canforward(in)
+ struct in_addr in;
+{
+ register u_long i = ntohl(in.s_addr);
+ register u_long net;
+
+ if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i))
+ return (0);
+ if (IN_CLASSA(i)) {
+ net = i & IN_CLASSA_NET;
+ if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Trim a mask in a sockaddr
+ */
+static void
+in_socktrim(ap)
+struct sockaddr_in *ap;
+{
+ register char *cplim = (char *) &ap->sin_addr;
+ register char *cp = (char *) (&ap->sin_addr + 1);
+
+ ap->sin_len = 0;
+ while (--cp >= cplim)
+ if (*cp) {
+ (ap)->sin_len = cp - (char *) (ap) + 1;
+ break;
+ }
+}
+
+static int in_interfaces; /* number of external internet interfaces */
+
+/*
+ * Generic internet control operations (ioctl's).
+ * Ifp is 0 if not an interface-specific ioctl.
+ */
+/* ARGSUSED */
+int
+in_control(so, cmd, data, ifp)
+ struct socket *so;
+ u_long cmd;
+ caddr_t data;
+ register struct ifnet *ifp;
+{
+ register struct ifreq *ifr = (struct ifreq *)data;
+ register struct in_ifaddr *ia = 0, *iap;
+ register struct ifaddr *ifa;
+ struct in_ifaddr *oia;
+ struct in_aliasreq *ifra = (struct in_aliasreq *)data;
+ struct sockaddr_in oldaddr;
+ int error, hostIsNew, maskIsNew, s;
+ struct multi_kludge *mk;
+
+ /*
+ * Find address for this interface, if it exists.
+ *
+ * If an alias address was specified, find that one instead of
+ * the first one on the interface.
+ */
+ if (ifp)
+ for (iap = in_ifaddr; iap; iap = iap->ia_next)
+ if (iap->ia_ifp == ifp) {
+ if (((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr ==
+ iap->ia_addr.sin_addr.s_addr) {
+ ia = iap;
+ break;
+ } else if (ia == NULL) {
+ ia = iap;
+ if (ifr->ifr_addr.sa_family != AF_INET)
+ break;
+ }
+ }
+
+ switch (cmd) {
+
+ case SIOCAIFADDR:
+ case SIOCDIFADDR:
+ if (ifra->ifra_addr.sin_family == AF_INET) {
+ for (oia = ia; ia; ia = ia->ia_next) {
+ if (ia->ia_ifp == ifp &&
+ ia->ia_addr.sin_addr.s_addr ==
+ ifra->ifra_addr.sin_addr.s_addr)
+ break;
+ }
+ if ((ifp->if_flags & IFF_POINTOPOINT)
+ && (cmd == SIOCAIFADDR)
+ && (ifra->ifra_dstaddr.sin_addr.s_addr
+ == INADDR_ANY)) {
+ return EDESTADDRREQ;
+ }
+ }
+ if (cmd == SIOCDIFADDR && ia == 0)
+ return (EADDRNOTAVAIL);
+ /* FALLTHROUGH */
+ case SIOCSIFADDR:
+ case SIOCSIFNETMASK:
+ case SIOCSIFDSTADDR:
+ if ((so->so_state & SS_PRIV) == 0)
+ return (EPERM);
+
+ if (ifp == 0)
+ panic("in_control");
+ if (ia == (struct in_ifaddr *)0) {
+ oia = (struct in_ifaddr *)
+ malloc(sizeof *oia, M_IFADDR, M_WAITOK);
+ if (oia == (struct in_ifaddr *)NULL)
+ return (ENOBUFS);
+ bzero((caddr_t)oia, sizeof *oia);
+ ia = in_ifaddr;
+ /*
+ * Protect from ipintr() traversing address list
+ * while we're modifying it.
+ */
+ s = splnet();
+
+ if (ia) {
+ for ( ; ia->ia_next; ia = ia->ia_next)
+ continue;
+ ia->ia_next = oia;
+ } else
+ in_ifaddr = oia;
+ ia = oia;
+ ifa = ifp->if_addrlist;
+ if (ifa) {
+ for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
+ continue;
+ ifa->ifa_next = (struct ifaddr *) ia;
+ } else
+ ifp->if_addrlist = (struct ifaddr *) ia;
+ ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
+ ia->ia_ifa.ifa_dstaddr
+ = (struct sockaddr *)&ia->ia_dstaddr;
+ ia->ia_ifa.ifa_netmask
+ = (struct sockaddr *)&ia->ia_sockmask;
+ ia->ia_sockmask.sin_len = 8;
+ if (ifp->if_flags & IFF_BROADCAST) {
+ ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
+ ia->ia_broadaddr.sin_family = AF_INET;
+ }
+ ia->ia_ifp = ifp;
+ if (!(ifp->if_flags & IFF_LOOPBACK))
+ in_interfaces++;
+ splx(s);
+ }
+ break;
+
+ case SIOCSIFBRDADDR:
+ if ((so->so_state & SS_PRIV) == 0)
+ return (EPERM);
+ /* FALLTHROUGH */
+
+ case SIOCGIFADDR:
+ case SIOCGIFNETMASK:
+ case SIOCGIFDSTADDR:
+ case SIOCGIFBRDADDR:
+ if (ia == (struct in_ifaddr *)0)
+ return (EADDRNOTAVAIL);
+ break;
+ }
+ switch (cmd) {
+
+ case SIOCGIFADDR:
+ *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;
+ break;
+
+ case SIOCGIFBRDADDR:
+ if ((ifp->if_flags & IFF_BROADCAST) == 0)
+ return (EINVAL);
+ *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr;
+ break;
+
+ case SIOCGIFDSTADDR:
+ if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
+ return (EINVAL);
+ *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr;
+ break;
+
+ case SIOCGIFNETMASK:
+ *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
+ break;
+
+ case SIOCSIFDSTADDR:
+ if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
+ return (EINVAL);
+ oldaddr = ia->ia_dstaddr;
+ ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
+ if (ifp->if_ioctl && (error = (*ifp->if_ioctl)
+ (ifp, SIOCSIFDSTADDR, (caddr_t)ia))) {
+ ia->ia_dstaddr = oldaddr;
+ return (error);
+ }
+ if (ia->ia_flags & IFA_ROUTE) {
+ ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
+ rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
+ ia->ia_ifa.ifa_dstaddr =
+ (struct sockaddr *)&ia->ia_dstaddr;
+ rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
+ }
+ break;
+
+ case SIOCSIFBRDADDR:
+ if ((ifp->if_flags & IFF_BROADCAST) == 0)
+ return (EINVAL);
+ ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
+ break;
+
+ case SIOCSIFADDR:
+ return (in_ifinit(ifp, ia,
+ (struct sockaddr_in *) &ifr->ifr_addr, 1));
+
+ case SIOCSIFNETMASK:
+ ia->ia_sockmask.sin_addr = ifra->ifra_addr.sin_addr;
+ ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr);
+ break;
+
+ case SIOCAIFADDR:
+ maskIsNew = 0;
+ hostIsNew = 1;
+ error = 0;
+ if (ia->ia_addr.sin_family == AF_INET) {
+ if (ifra->ifra_addr.sin_len == 0) {
+ ifra->ifra_addr = ia->ia_addr;
+ hostIsNew = 0;
+ } else if (ifra->ifra_addr.sin_addr.s_addr ==
+ ia->ia_addr.sin_addr.s_addr)
+ hostIsNew = 0;
+ }
+ if (ifra->ifra_mask.sin_len) {
+ in_ifscrub(ifp, ia);
+ ia->ia_sockmask = ifra->ifra_mask;
+ ia->ia_subnetmask =
+ ntohl(ia->ia_sockmask.sin_addr.s_addr);
+ maskIsNew = 1;
+ }
+ if ((ifp->if_flags & IFF_POINTOPOINT) &&
+ (ifra->ifra_dstaddr.sin_family == AF_INET)) {
+ in_ifscrub(ifp, ia);
+ ia->ia_dstaddr = ifra->ifra_dstaddr;
+ maskIsNew = 1; /* We lie; but the effect's the same */
+ }
+ if (ifra->ifra_addr.sin_family == AF_INET &&
+ (hostIsNew || maskIsNew))
+ error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
+ if ((ifp->if_flags & IFF_BROADCAST) &&
+ (ifra->ifra_broadaddr.sin_family == AF_INET))
+ ia->ia_broadaddr = ifra->ifra_broadaddr;
+ return (error);
+
+ case SIOCDIFADDR:
+ mk = malloc(sizeof *mk, M_IPMADDR, M_WAITOK);
+ if (!mk)
+ return ENOBUFS;
+
+ in_ifscrub(ifp, ia);
+ /*
+ * Protect from ipintr() traversing address list
+ * while we're modifying it.
+ */
+ s = splnet();
+
+ if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
+ ifp->if_addrlist = ifa->ifa_next;
+ else {
+ while (ifa->ifa_next &&
+ (ifa->ifa_next != (struct ifaddr *)ia))
+ ifa = ifa->ifa_next;
+ if (ifa->ifa_next)
+ ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
+ else
+ printf("Couldn't unlink inifaddr from ifp\n");
+ }
+ oia = ia;
+ if (oia == (ia = in_ifaddr))
+ in_ifaddr = ia->ia_next;
+ else {
+ while (ia->ia_next && (ia->ia_next != oia))
+ ia = ia->ia_next;
+ if (ia->ia_next)
+ ia->ia_next = oia->ia_next;
+ else
+ printf("Didn't unlink inifadr from list\n");
+ }
+
+ if (!oia->ia_multiaddrs.lh_first) {
+ IFAFREE(&oia->ia_ifa);
+ FREE(mk, M_IPMADDR);
+ splx(s);
+ break;
+ }
+
+ /*
+ * Multicast address kludge:
+ * If there were any multicast addresses attached to this
+ * interface address, either move them to another address
+ * on this interface, or save them until such time as this
+ * interface is reconfigured for IP.
+ */
+ IFP_TO_IA(oia->ia_ifp, ia);
+ if (ia) { /* there is another address */
+ struct in_multi *inm;
+ for(inm = oia->ia_multiaddrs.lh_first; inm;
+ inm = inm->inm_entry.le_next) {
+ IFAFREE(&inm->inm_ia->ia_ifa);
+ ia->ia_ifa.ifa_refcnt++;
+ inm->inm_ia = ia;
+ LIST_INSERT_HEAD(&ia->ia_multiaddrs, inm,
+ inm_entry);
+ }
+ FREE(mk, M_IPMADDR);
+ } else { /* last address on this if deleted, save */
+ struct in_multi *inm;
+
+ LIST_INIT(&mk->mk_head);
+ mk->mk_ifp = ifp;
+
+ for(inm = oia->ia_multiaddrs.lh_first; inm;
+ inm = inm->inm_entry.le_next) {
+ LIST_INSERT_HEAD(&mk->mk_head, inm, inm_entry);
+ }
+
+ if (mk->mk_head.lh_first) {
+ LIST_INSERT_HEAD(&in_mk, mk, mk_entry);
+ } else {
+ FREE(mk, M_IPMADDR);
+ }
+ }
+
+ IFAFREE((&oia->ia_ifa));
+ splx(s);
+ break;
+
+ default:
+ if (ifp == 0 || ifp->if_ioctl == 0)
+ return (EOPNOTSUPP);
+ return ((*ifp->if_ioctl)(ifp, cmd, data));
+ }
+ return (0);
+}
+
+/*
+ * Delete any existing route for an interface.
+ */
+static void
+in_ifscrub(ifp, ia)
+ register struct ifnet *ifp;
+ register struct in_ifaddr *ia;
+{
+
+ if ((ia->ia_flags & IFA_ROUTE) == 0)
+ return;
+ if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
+ rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
+ else
+ rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
+ ia->ia_flags &= ~IFA_ROUTE;
+}
+
+/*
+ * Initialize an interface's internet address
+ * and routing table entry.
+ */
+static int
+in_ifinit(ifp, ia, sin, scrub)
+ register struct ifnet *ifp;
+ register struct in_ifaddr *ia;
+ struct sockaddr_in *sin;
+ int scrub;
+{
+ register u_long i = ntohl(sin->sin_addr.s_addr);
+ struct sockaddr_in oldaddr;
+ int s = splimp(), flags = RTF_UP, error;
+ struct multi_kludge *mk;
+
+ oldaddr = ia->ia_addr;
+ ia->ia_addr = *sin;
+ /*
+ * Give the interface a chance to initialize
+ * if this is its first address,
+ * and to validate the address if necessary.
+ */
+ if (ifp->if_ioctl &&
+ (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
+ splx(s);
+ ia->ia_addr = oldaddr;
+ return (error);
+ }
+ splx(s);
+ if (scrub) {
+ ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
+ in_ifscrub(ifp, ia);
+ ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
+ }
+ if (IN_CLASSA(i))
+ ia->ia_netmask = IN_CLASSA_NET;
+ else if (IN_CLASSB(i))
+ ia->ia_netmask = IN_CLASSB_NET;
+ else
+ ia->ia_netmask = IN_CLASSC_NET;
+ /*
+ * The subnet mask usually includes at least the standard network part,
+ * but may may be smaller in the case of supernetting.
+ * If it is set, we believe it.
+ */
+ if (ia->ia_subnetmask == 0) {
+ ia->ia_subnetmask = ia->ia_netmask;
+ ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
+ } else
+ ia->ia_netmask &= ia->ia_subnetmask;
+ ia->ia_net = i & ia->ia_netmask;
+ ia->ia_subnet = i & ia->ia_subnetmask;
+ in_socktrim(&ia->ia_sockmask);
+ /*
+ * Add route for the network.
+ */
+ ia->ia_ifa.ifa_metric = ifp->if_metric;
+ if (ifp->if_flags & IFF_BROADCAST) {
+ ia->ia_broadaddr.sin_addr.s_addr =
+ htonl(ia->ia_subnet | ~ia->ia_subnetmask);
+ ia->ia_netbroadcast.s_addr =
+ htonl(ia->ia_net | ~ ia->ia_netmask);
+ } else if (ifp->if_flags & IFF_LOOPBACK) {
+ ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
+ flags |= RTF_HOST;
+ } else if (ifp->if_flags & IFF_POINTOPOINT) {
+ if (ia->ia_dstaddr.sin_family != AF_INET)
+ return (0);
+ flags |= RTF_HOST;
+ }
+ if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
+ ia->ia_flags |= IFA_ROUTE;
+
+ LIST_INIT(&ia->ia_multiaddrs);
+ /*
+ * If the interface supports multicast, join the "all hosts"
+ * multicast group on that interface.
+ */
+ if (ifp->if_flags & IFF_MULTICAST) {
+ struct in_addr addr;
+
+ /*
+ * Continuation of multicast address hack:
+ * If there was a multicast group list previously saved
+ * for this interface, then we re-attach it to the first
+ * address configured on the i/f.
+ */
+ for(mk = in_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
+ if(mk->mk_ifp == ifp) {
+ struct in_multi *inm;
+
+ for(inm = mk->mk_head.lh_first; inm;
+ inm = inm->inm_entry.le_next) {
+ IFAFREE(&inm->inm_ia->ia_ifa);
+ ia->ia_ifa.ifa_refcnt++;
+ inm->inm_ia = ia;
+ LIST_INSERT_HEAD(&ia->ia_multiaddrs,
+ inm, inm_entry);
+ }
+ LIST_REMOVE(mk, mk_entry);
+ free(mk, M_IPMADDR);
+ break;
+ }
+ }
+
+ addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
+ in_addmulti(&addr, ifp);
+ }
+ return (error);
+}
+
+
+/*
+ * Return 1 if the address might be a local broadcast address.
+ */
+int
+in_broadcast(in, ifp)
+ struct in_addr in;
+ struct ifnet *ifp;
+{
+ register struct ifaddr *ifa;
+ u_long t;
+
+ if (in.s_addr == INADDR_BROADCAST ||
+ in.s_addr == INADDR_ANY)
+ return 1;
+ if ((ifp->if_flags & IFF_BROADCAST) == 0)
+ return 0;
+ t = ntohl(in.s_addr);
+ /*
+ * Look through the list of addresses for a match
+ * with a broadcast address.
+ */
+#define ia ((struct in_ifaddr *)ifa)
+ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
+ if (ifa->ifa_addr->sa_family == AF_INET &&
+ (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
+ in.s_addr == ia->ia_netbroadcast.s_addr ||
+ /*
+ * Check for old-style (host 0) broadcast.
+ */
+ t == ia->ia_subnet || t == ia->ia_net) &&
+ /*
+ * Check for an all one subnetmask. These
+ * only exist when an interface gets a secondary
+ * address.
+ */
+ ia->ia_subnetmask != (u_long)0xffffffff)
+ return 1;
+ return (0);
+#undef ia
+}
+/*
+ * Add an address to the list of IP multicast addresses for a given interface.
+ */
+struct in_multi *
+in_addmulti(ap, ifp)
+ register struct in_addr *ap;
+ register struct ifnet *ifp;
+{
+ register struct in_multi *inm;
+ struct ifreq ifr;
+ struct in_ifaddr *ia;
+ int s = splnet();
+
+ /*
+ * See if address already in list.
+ */
+ IN_LOOKUP_MULTI(*ap, ifp, inm);
+ if (inm != NULL) {
+ /*
+ * Found it; just increment the reference count.
+ */
+ ++inm->inm_refcount;
+ }
+ else {
+ /*
+ * New address; allocate a new multicast record
+ * and link it into the interface's multicast list.
+ */
+ inm = (struct in_multi *)malloc(sizeof(*inm),
+ M_IPMADDR, M_NOWAIT);
+ if (inm == NULL) {
+ splx(s);
+ return (NULL);
+ }
+ inm->inm_addr = *ap;
+ inm->inm_ifp = ifp;
+ inm->inm_refcount = 1;
+ IFP_TO_IA(ifp, ia);
+ if (ia == NULL) {
+ free(inm, M_IPMADDR);
+ splx(s);
+ return (NULL);
+ }
+ inm->inm_ia = ia;
+ ia->ia_ifa.ifa_refcnt++; /* gain a reference */
+ LIST_INSERT_HEAD(&ia->ia_multiaddrs, inm, inm_entry);
+
+ /*
+ * Ask the network driver to update its multicast reception
+ * filter appropriately for the new address.
+ */
+ ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
+ ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr = *ap;
+ if ((ifp->if_ioctl == NULL) ||
+ (*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
+ LIST_REMOVE(inm, inm_entry);
+ IFAFREE(&ia->ia_ifa); /* release reference */
+ free(inm, M_IPMADDR);
+ splx(s);
+ return (NULL);
+ }
+ /*
+ * Let IGMP know that we have joined a new IP multicast group.
+ */
+ igmp_joingroup(inm);
+ }
+ splx(s);
+ return (inm);
+}
+
+/*
+ * Delete a multicast address record.
+ */
+void
+in_delmulti(inm)
+ register struct in_multi *inm;
+{
+ struct ifreq ifr;
+ int s = splnet();
+
+ if (--inm->inm_refcount == 0) {
+ /*
+ * No remaining claims to this record; let IGMP know that
+ * we are leaving the multicast group.
+ */
+ igmp_leavegroup(inm);
+ /*
+ * Unlink from list.
+ */
+ LIST_REMOVE(inm, inm_entry);
+ IFAFREE(&inm->inm_ia->ia_ifa); /* release reference */
+
+ /*
+ * Notify the network driver to update its multicast reception
+ * filter.
+ */
+ ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
+ ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr =
+ inm->inm_addr;
+ (*inm->inm_ifp->if_ioctl)(inm->inm_ifp, SIOCDELMULTI,
+ (caddr_t)&ifr);
+ free(inm, M_IPMADDR);
+ }
+ splx(s);
+}
diff --git a/cpukit/libnetworking/netinet/in.h b/cpukit/libnetworking/netinet/in.h
new file mode 100644
index 0000000000..48e53e9496
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in.h
@@ -0,0 +1,468 @@
+/*
+ * Copyright (c) 1982, 1986, 1990, 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.
+ * 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.h 8.3 (Berkeley) 1/3/94
+ * $FreeBSD: src/sys/netinet/in.h,v 1.91 2005/08/22 16:13:07 andre Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NETINET_IN_H_
+#define _NETINET_IN_H_
+
+#include <rtems/bsdnet/_types.h>
+#include <machine/endian.h>
+
+/* Protocols common to RFC 1700, POSIX, and X/Open. */
+#define IPPROTO_IP 0 /* dummy for IP */
+#define IPPROTO_ICMP 1 /* control message protocol */
+#define IPPROTO_TCP 6 /* tcp */
+#define IPPROTO_UDP 17 /* user datagram protocol */
+
+#define INADDR_ANY (u_int32_t)0x00000000
+#define INADDR_BROADCAST (u_int32_t)0xffffffff /* must be masked */
+
+#ifndef _IN_PORT_T_DECLARED
+typedef uint16_t in_port_t;
+#define _IN_PORT_T_DECLARED
+#endif
+
+#ifndef _SA_FAMILY_T_DECLARED
+typedef __sa_family_t sa_family_t;
+#define _SA_FAMILY_T_DECLARED
+#endif
+
+/* Internet address (a structure for historical reasons). */
+#ifndef _STRUCT_IN_ADDR_DECLARED
+struct in_addr {
+ u_long s_addr;
+};
+#define _STRUCT_IN_ADDR_DECLARED
+#endif
+
+/* Socket address, internet style. */
+struct sockaddr_in {
+ uint8_t sin_len;
+ sa_family_t sin_family;
+ in_port_t sin_port;
+ struct in_addr sin_addr;
+ char sin_zero[8];
+};
+
+
+/*
+ * Constants and structures defined by the internet system,
+ * Per RFC 790, September 1981, and numerous additions.
+ */
+
+/*
+ * Protocols (RFC 1700)
+ */
+#define IPPROTO_HOPOPTS 0 /* IP6 hop-by-hop options */
+#define IPPROTO_IGMP 2 /* group mgmt protocol */
+#define IPPROTO_GGP 3 /* gateway^2 (deprecated) */
+#define IPPROTO_IPV4 4 /* IPv4 encapsulation */
+#define IPPROTO_IPIP IPPROTO_IPV4 /* for compatibility */
+#define IPPROTO_ST 7 /* Stream protocol II */
+#define IPPROTO_EGP 8 /* exterior gateway protocol */
+#define IPPROTO_PIGP 9 /* private interior gateway */
+#define IPPROTO_RCCMON 10 /* BBN RCC Monitoring */
+#define IPPROTO_NVPII 11 /* network voice protocol*/
+#define IPPROTO_PUP 12 /* pup */
+#define IPPROTO_ARGUS 13 /* Argus */
+#define IPPROTO_EMCON 14 /* EMCON */
+#define IPPROTO_XNET 15 /* Cross Net Debugger */
+#define IPPROTO_CHAOS 16 /* Chaos*/
+#define IPPROTO_MUX 18 /* Multiplexing */
+#define IPPROTO_MEAS 19 /* DCN Measurement Subsystems */
+#define IPPROTO_HMP 20 /* Host Monitoring */
+#define IPPROTO_PRM 21 /* Packet Radio Measurement */
+#define IPPROTO_IDP 22 /* xns idp */
+#define IPPROTO_TRUNK1 23 /* Trunk-1 */
+#define IPPROTO_TRUNK2 24 /* Trunk-2 */
+#define IPPROTO_LEAF1 25 /* Leaf-1 */
+#define IPPROTO_LEAF2 26 /* Leaf-2 */
+#define IPPROTO_RDP 27 /* Reliable Data */
+#define IPPROTO_IRTP 28 /* Reliable Transaction */
+#define IPPROTO_TP 29 /* tp-4 w/ class negotiation */
+#define IPPROTO_BLT 30 /* Bulk Data Transfer */
+#define IPPROTO_NSP 31 /* Network Services */
+#define IPPROTO_INP 32 /* Merit Internodal */
+#define IPPROTO_SEP 33 /* Sequential Exchange */
+#define IPPROTO_3PC 34 /* Third Party Connect */
+#define IPPROTO_IDPR 35 /* InterDomain Policy Routing */
+#define IPPROTO_XTP 36 /* XTP */
+#define IPPROTO_DDP 37 /* Datagram Delivery */
+#define IPPROTO_CMTP 38 /* Control Message Transport */
+#define IPPROTO_TPXX 39 /* TP++ Transport */
+#define IPPROTO_IL 40 /* IL transport protocol */
+#define IPPROTO_IPV6 41 /* IP6 header */
+#define IPPROTO_SDRP 42 /* Source Demand Routing */
+#define IPPROTO_ROUTING 43 /* IP6 routing header */
+#define IPPROTO_FRAGMENT 44 /* IP6 fragmentation header */
+#define IPPROTO_IDRP 45 /* InterDomain Routing*/
+#define IPPROTO_RSVP 46 /* resource reservation */
+#define IPPROTO_GRE 47 /* General Routing Encap. */
+#define IPPROTO_MHRP 48 /* Mobile Host Routing */
+#define IPPROTO_BHA 49 /* BHA */
+#define IPPROTO_ESP 50 /* IP6 Encap Sec. Payload */
+#define IPPROTO_AH 51 /* IP6 Auth Header */
+#define IPPROTO_INLSP 52 /* Integ. Net Layer Security */
+#define IPPROTO_SWIPE 53 /* IP with encryption */
+#define IPPROTO_NHRP 54 /* Next Hop Resolution */
+#define IPPROTO_MOBILE 55 /* IP Mobility */
+#define IPPROTO_TLSP 56 /* Transport Layer Security */
+#define IPPROTO_SKIP 57 /* SKIP */
+#define IPPROTO_ICMPV6 58 /* ICMP6 */
+#define IPPROTO_NONE 59 /* IP6 no next header */
+#define IPPROTO_DSTOPTS 60 /* IP6 destination option */
+#define IPPROTO_AHIP 61 /* any host internal protocol */
+#define IPPROTO_CFTP 62 /* CFTP */
+#define IPPROTO_HELLO 63 /* "hello" routing protocol */
+#define IPPROTO_SATEXPAK 64 /* SATNET/Backroom EXPAK */
+#define IPPROTO_KRYPTOLAN 65 /* Kryptolan */
+#define IPPROTO_RVD 66 /* Remote Virtual Disk */
+#define IPPROTO_IPPC 67 /* Pluribus Packet Core */
+#define IPPROTO_ADFS 68 /* Any distributed FS */
+#define IPPROTO_SATMON 69 /* Satnet Monitoring */
+#define IPPROTO_VISA 70 /* VISA Protocol */
+#define IPPROTO_IPCV 71 /* Packet Core Utility */
+#define IPPROTO_CPNX 72 /* Comp. Prot. Net. Executive */
+#define IPPROTO_CPHB 73 /* Comp. Prot. HeartBeat */
+#define IPPROTO_WSN 74 /* Wang Span Network */
+#define IPPROTO_PVP 75 /* Packet Video Protocol */
+#define IPPROTO_BRSATMON 76 /* BackRoom SATNET Monitoring */
+#define IPPROTO_ND 77 /* Sun net disk proto (temp.) */
+#define IPPROTO_WBMON 78 /* WIDEBAND Monitoring */
+#define IPPROTO_WBEXPAK 79 /* WIDEBAND EXPAK */
+#define IPPROTO_EON 80 /* ISO cnlp */
+#define IPPROTO_VMTP 81 /* VMTP */
+#define IPPROTO_SVMTP 82 /* Secure VMTP */
+#define IPPROTO_VINES 83 /* Banyon VINES */
+#define IPPROTO_TTP 84 /* TTP */
+#define IPPROTO_IGP 85 /* NSFNET-IGP */
+#define IPPROTO_DGP 86 /* dissimilar gateway prot. */
+#define IPPROTO_TCF 87 /* TCF */
+#define IPPROTO_IGRP 88 /* Cisco/GXS IGRP */
+#define IPPROTO_OSPFIGP 89 /* OSPFIGP */
+#define IPPROTO_SRPC 90 /* Strite RPC protocol */
+#define IPPROTO_LARP 91 /* Locus Address Resoloution */
+#define IPPROTO_MTP 92 /* Multicast Transport */
+#define IPPROTO_AX25 93 /* AX.25 Frames */
+#define IPPROTO_IPEIP 94 /* IP encapsulated in IP */
+#define IPPROTO_MICP 95 /* Mobile Int.ing control */
+#define IPPROTO_SCCSP 96 /* Semaphore Comm. security */
+#define IPPROTO_ETHERIP 97 /* Ethernet IP encapsulation */
+#define IPPROTO_ENCAP 98 /* encapsulation header */
+#define IPPROTO_APES 99 /* any private encr. scheme */
+#define IPPROTO_GMTP 100 /* GMTP*/
+#define IPPROTO_IPCOMP 108 /* payload compression (IPComp) */
+/* 101-254: Partly Unassigned */
+#define IPPROTO_PIM 103 /* Protocol Independent Mcast */
+#define IPPROTO_CARP 112 /* CARP */
+#define IPPROTO_PGM 113 /* PGM */
+#define IPPROTO_PFSYNC 240 /* PFSYNC */
+/* 255: Reserved */
+/* BSD Private, local use, namespace incursion */
+#define IPPROTO_DIVERT 254 /* divert pseudo-protocol */
+#define IPPROTO_RAW 255 /* raw IP packet */
+#define IPPROTO_MAX 256
+
+/*
+ * Merged from FreeBSD 1.78 of this file so Python compiles.
+ * This is a size value for functions such as inet_ntop().
+ */
+#define INET_ADDRSTRLEN 16
+
+/*
+ * Local port number conventions:
+ *
+ * When a user does a bind(2) or connect(2) with a port number of zero,
+ * a non-conflicting local port address is chosen.
+ * The default range is IPPORT_HIFIRSTAUTO through
+ * IPPORT_HILASTAUTO, although that is settable by sysctl.
+ *
+ * A user may set the IPPROTO_IP option IP_PORTRANGE to change this
+ * default assignment range.
+ *
+ * The value IP_PORTRANGE_DEFAULT causes the default behavior.
+ *
+ * The value IP_PORTRANGE_HIGH changes the range of candidate port numbers
+ * into the "high" range. These are reserved for client outbound connections
+ * which do not want to be filtered by any firewalls. Note that by default
+ * this is the same as IP_PORTRANGE_DEFAULT.
+ *
+ * The value IP_PORTRANGE_LOW changes the range to the "low" are
+ * that is (by convention) restricted to privileged processes. This
+ * convention is based on "vouchsafe" principles only. It is only secure
+ * if you trust the remote host to restrict these ports.
+ *
+ * The default range of ports and the high range can be changed by
+ * sysctl(3). (net.inet.ip.port{hi,low}{first,last}_auto)
+ *
+ * Changing those values has bad security implications if you are
+ * using a stateless firewall that is allowing packets outside of that
+ * range in order to allow transparent outgoing connections.
+ *
+ * Such a firewall configuration will generally depend on the use of these
+ * default values. If you change them, you may find your Security
+ * Administrator looking for you with a heavy object.
+ */
+
+/*
+ * Ports < IPPORT_RESERVED are reserved for
+ * privileged processes (e.g. root). (IP_PORTRANGE_LOW)
+ * Ports > IPPORT_USERRESERVED are reserved
+ * for servers, not necessarily privileged. (IP_PORTRANGE_DEFAULT)
+ */
+#define IPPORT_RESERVED 1024
+#define IPPORT_USERRESERVED 5000
+
+/*
+ * Default local port range to use by setting IP_PORTRANGE_HIGH
+ */
+#define IPPORT_HIFIRSTAUTO 40000
+#define IPPORT_HILASTAUTO 44999
+
+/*
+ * Scanning for a free reserved port return a value below IPPORT_RESERVED,
+ * but higher than IPPORT_RESERVEDSTART. Traditionally the start value was
+ * 512, but that conflicts with some well-known-services that firewalls may
+ * have a fit if we use.
+ */
+#define IPPORT_RESERVEDSTART 600
+/*
+ * Definitions of bits in internet address integers.
+ * On subnets, the decomposition of addresses to host and net parts
+ * is done according to subnet mask, not the masks here.
+ */
+#define IN_CLASSA(i) (((u_int32_t)(i) & 0x80000000) == 0)
+#define IN_CLASSA_NET 0xff000000
+#define IN_CLASSA_NSHIFT 24
+#define IN_CLASSA_HOST 0x00ffffff
+#define IN_CLASSA_MAX 128
+
+#define IN_CLASSB(i) (((u_int32_t)(i) & 0xc0000000) == 0x80000000)
+#define IN_CLASSB_NET 0xffff0000
+#define IN_CLASSB_NSHIFT 16
+#define IN_CLASSB_HOST 0x0000ffff
+#define IN_CLASSB_MAX 65536
+
+#define IN_CLASSC(i) (((u_int32_t)(i) & 0xe0000000) == 0xc0000000)
+#define IN_CLASSC_NET 0xffffff00
+#define IN_CLASSC_NSHIFT 8
+#define IN_CLASSC_HOST 0x000000ff
+
+#define IN_CLASSD(i) (((u_int32_t)(i) & 0xf0000000) == 0xe0000000)
+#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */
+#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */
+#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */
+#define IN_MULTICAST(i) IN_CLASSD(i)
+
+#define IN_EXPERIMENTAL(i) (((u_int32_t)(i) & 0xf0000000) == 0xf0000000)
+#define IN_BADCLASS(i) (((u_int32_t)(i) & 0xf0000000) == 0xf0000000)
+
+#define INADDR_LOOPBACK (u_int32_t)0x7f000001
+#ifndef _KERNEL
+#define INADDR_NONE 0xffffffff /* -1 return */
+#endif
+
+#define INADDR_UNSPEC_GROUP (u_int32_t)0xe0000000 /* 224.0.0.0 */
+#define INADDR_ALLHOSTS_GROUP (u_int32_t)0xe0000001 /* 224.0.0.1 */
+#define INADDR_ALLRTRS_GROUP (u_int32_t)0xe0000002 /* 224.0.0.2 */
+#define INADDR_MAX_LOCAL_GROUP (u_int32_t)0xe00000ff /* 224.0.0.255 */
+
+#define IN_LOOPBACKNET 127 /* official! */
+
+/*
+ * Structure used to describe IP options.
+ * Used to store options internally, to pass them to a process,
+ * or to restore options retrieved earlier.
+ * The ip_dst is used for the first-hop gateway when using a source route
+ * (this gets put into the header proper).
+ */
+struct ip_opts {
+ struct in_addr ip_dst; /* first hop, 0 w/o src rt */
+ char ip_opts[40]; /* actually variable in size */
+};
+
+/*
+ * Options for use with [gs]etsockopt at the IP level.
+ * First word of comment is data type; bool is stored in int.
+ */
+#define IP_OPTIONS 1 /* buf/ip_opts; set/get IP options */
+#define IP_HDRINCL 2 /* int; header is included with data */
+#define IP_TOS 3 /* int; IP type of service and preced. */
+#define IP_TTL 4 /* int; IP time to live */
+#define IP_RECVOPTS 5 /* bool; receive all IP opts w/dgram */
+#define IP_RECVRETOPTS 6 /* bool; receive IP opts for response */
+#define IP_RECVDSTADDR 7 /* bool; receive IP dst addr w/dgram */
+#define IP_SENDSRCADDR IP_RECVDSTADDR /* cmsg_type to set src addr */
+#define IP_RETOPTS 8 /* ip_opts; set/get IP options */
+#define IP_MULTICAST_IF 9 /* u_char; set/get IP multicast i/f */
+#define IP_MULTICAST_TTL 10 /* u_char; set/get IP multicast ttl */
+#define IP_MULTICAST_LOOP 11 /* u_char; set/get IP multicast loopback */
+#define IP_ADD_MEMBERSHIP 12 /* ip_mreq; add an IP group membership */
+#define IP_DROP_MEMBERSHIP 13 /* ip_mreq; drop an IP group membership */
+#define IP_MULTICAST_VIF 14 /* set/get IP mcast virt. iface */
+#define IP_RSVP_ON 15 /* enable RSVP in kernel */
+#define IP_RSVP_OFF 16 /* disable RSVP in kernel */
+#define IP_RSVP_VIF_ON 17 /* set RSVP per-vif socket */
+#define IP_RSVP_VIF_OFF 18 /* unset RSVP per-vif socket */
+#define IP_PORTRANGE 19 /* int; range to choose for unspec port */
+#define IP_RECVIF 20 /* bool; receive reception if w/dgram */
+
+#define IP_FW_ADD 50 /* add a firewall rule to chain */
+#define IP_FW_DEL 51 /* delete a firewall rule from chain */
+#define IP_FW_FLUSH 52 /* flush firewall rule chain */
+#define IP_FW_ZERO 53 /* clear single/all firewall counter(s) */
+#define IP_FW_GET 54 /* get entire firewall rule chain */
+#define IP_NAT 55 /* set/get NAT opts */
+
+/*
+ * Defaults and limits for options
+ */
+#define IP_DEFAULT_MULTICAST_TTL 1 /* normally limit m'casts to 1 hop */
+#define IP_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */
+#define IP_MAX_MEMBERSHIPS 20 /* per socket */
+
+/*
+ * Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP.
+ */
+struct ip_mreq {
+ struct in_addr imr_multiaddr; /* IP multicast address of group */
+ struct in_addr imr_interface; /* local IP address of interface */
+};
+
+/*
+ * Argument for IP_PORTRANGE:
+ * - which range to search when port is unspecified at bind() or connect()
+ */
+#define IP_PORTRANGE_DEFAULT 0 /* default range */
+#define IP_PORTRANGE_HIGH 1 /* "high" - request firewall bypass */
+#define IP_PORTRANGE_LOW 2 /* "low" - vouchsafe security */
+
+/*
+ * Definitions for inet sysctl operations.
+ *
+ * Third level is protocol number.
+ * Fourth level is desired variable within that protocol.
+ */
+#define IPPROTO_MAXID (IPPROTO_IDP + 1) /* don't list to IPPROTO_MAX */
+
+#define CTL_IPPROTO_NAMES { \
+ { "ip", CTLTYPE_NODE }, \
+ { "icmp", CTLTYPE_NODE }, \
+ { "igmp", CTLTYPE_NODE }, \
+ { "ggp", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "tcp", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { "egp", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "pup", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "udp", CTLTYPE_NODE }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "idp", CTLTYPE_NODE }, \
+}
+
+/*
+ * Names for IP sysctl objects
+ */
+#define IPCTL_FORWARDING 1 /* act as router */
+#define IPCTL_SENDREDIRECTS 2 /* may send redirects when forwarding */
+#define IPCTL_DEFTTL 3 /* default TTL */
+#ifdef notyet
+#define IPCTL_DEFMTU 4 /* default MTU */
+#endif
+#define IPCTL_RTEXPIRE 5 /* cloned route expiration time */
+#define IPCTL_RTMINEXPIRE 6 /* min value for expiration time */
+#define IPCTL_RTMAXCACHE 7 /* trigger level for dynamic expire */
+#define IPCTL_SOURCEROUTE 8 /* may perform source routes */
+#define IPCTL_DIRECTEDBROADCAST 9 /* may re-broadcast received packets */
+#define IPCTL_INTRQMAXLEN 10 /* max length of netisr queue */
+#define IPCTL_INTRQDROPS 11 /* number of netisr q drops */
+#define IPCTL_ACCEPTSOURCEROUTE 13 /* may accept source routed packets */
+#define IPCTL_MAXID 13
+
+#define IPCTL_NAMES { \
+ { 0, 0 }, \
+ { "forwarding", CTLTYPE_INT }, \
+ { "redirect", CTLTYPE_INT }, \
+ { "ttl", CTLTYPE_INT }, \
+ { "mtu", CTLTYPE_INT }, \
+ { "rtexpire", CTLTYPE_INT }, \
+ { "rtminexpire", CTLTYPE_INT }, \
+ { "rtmaxcache", CTLTYPE_INT }, \
+ { "sourceroute", CTLTYPE_INT }, \
+ { "directed-broadcast", CTLTYPE_INT }, \
+ { "intr-queue-maxlen", CTLTYPE_INT }, \
+ { "intr-queue-drops", CTLTYPE_INT }, \
+ { "accept_sourceroute", CTLTYPE_INT }, \
+}
+
+
+#ifdef _KERNEL
+struct ifnet; struct mbuf; /* forward declarations for Standard C */
+
+int in_broadcast(struct in_addr, struct ifnet *);
+int in_canforward(struct in_addr);
+int in_cksum(struct mbuf *, int);
+int in_localaddr(struct in_addr);
+char *inet_ntoa(struct in_addr); /* in libkern */
+
+/* Firewall hooks */
+struct ip;
+typedef int ip_fw_chk_t __P((struct ip**, int, struct ifnet*, int, struct mbuf**));
+typedef int ip_fw_ctl_t __P((int, struct mbuf**));
+extern ip_fw_chk_t *ip_fw_chk_ptr;
+extern ip_fw_ctl_t *ip_fw_ctl_ptr;
+
+/* IP NAT hooks */
+typedef int ip_nat_t __P((struct ip**, struct mbuf**, struct ifnet*, int));
+typedef int ip_nat_ctl_t __P((int, struct mbuf**));
+extern ip_nat_t *ip_nat_ptr;
+extern ip_nat_ctl_t *ip_nat_ctl_ptr;
+#define IP_NAT_IN 0x00000001
+#define IP_NAT_OUT 0x00000002
+
+#endif /* _KERNEL */
+
+#endif /* !_NETINET_IN_H_*/
diff --git a/cpukit/libnetworking/netinet/in_cksum.c b/cpukit/libnetworking/netinet/in_cksum.c
new file mode 100644
index 0000000000..a2728d04b0
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in_cksum.c
@@ -0,0 +1,176 @@
+/*
+ * 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>
+
+/*
+ * Try to use a CPU specific version, then punt to the portable C one.
+ */
+
+
+#if (defined(__GNUC__) && defined(__arm__))
+
+#include "in_cksum_arm.h"
+
+#elif (defined(__GNUC__) && defined(__i386__))
+
+#include "in_cksum_i386.h"
+
+#elif (defined(__GNUC__) && (defined(__mc68000__) || defined(__m68k__)))
+
+#include "in_cksum_m68k.h"
+#elif (defined(__GNUC__) && defined(__PPC__))
+
+#include "in_cksum_powerpc.h"
+
+#else
+
+#include <stdio.h> /* for puts */
+
+/*
+ * Checksum routine for Internet Protocol family headers (Portable Version).
+ *
+ * This routine is very heavily used in the network
+ * code and should be modified for each CPU to be as fast as possible.
+ */
+
+#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
+#define REDUCE \
+ {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
+
+int
+in_cksum(m, len)
+ register struct mbuf *m;
+ register int len;
+{
+ register u_short *w;
+ register int sum = 0;
+ register int mlen = 0;
+ int byte_swapped = 0;
+
+ union {
+ char c[2];
+ u_short s;
+ } s_util;
+ union {
+ u_short s[2];
+ long l;
+ } l_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 even boundary.
+ */
+ if ((1 & (int) w) && (mlen > 0)) {
+ REDUCE;
+ sum <<= 8;
+ s_util.c[0] = *(u_char *)w;
+ w = (u_short *)((char *)w + 1);
+ mlen--;
+ byte_swapped = 1;
+ }
+ /*
+ * Unroll the loop to make overhead from
+ * branches &c small.
+ */
+ while ((mlen -= 32) >= 0) {
+ sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
+ sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
+ sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
+ sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
+ w += 16;
+ }
+ mlen += 32;
+ while ((mlen -= 8) >= 0) {
+ sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
+ w += 4;
+ }
+ mlen += 8;
+ if (mlen == 0 && byte_swapped == 0)
+ continue;
+ REDUCE;
+ 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)
+ puts("cksum: out of data");
+ 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);
+}
+#endif
diff --git a/cpukit/libnetworking/netinet/in_cksum_arm.h b/cpukit/libnetworking/netinet/in_cksum_arm.h
new file mode 100644
index 0000000000..10d21ab2a6
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in_cksum_arm.h
@@ -0,0 +1,276 @@
+/* $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));
+}
diff --git a/cpukit/libnetworking/netinet/in_cksum_i386.h b/cpukit/libnetworking/netinet/in_cksum_i386.h
new file mode 100644
index 0000000000..a64bd57832
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in_cksum_i386.h
@@ -0,0 +1,204 @@
+/*
+ * 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);
+}
diff --git a/cpukit/libnetworking/netinet/in_cksum_m68k.h b/cpukit/libnetworking/netinet/in_cksum_m68k.h
new file mode 100644
index 0000000000..cce5d28570
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in_cksum_m68k.h
@@ -0,0 +1,223 @@
+/*
+ * 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@(2f-.-2:b,%3) | Jump into loop\n"
+ "1: | 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"
+ "2: | 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 1b | 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,1b | (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);
+}
diff --git a/cpukit/libnetworking/netinet/in_cksum_powerpc.h b/cpukit/libnetworking/netinet/in_cksum_powerpc.h
new file mode 100644
index 0000000000..fe2f04e246
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in_cksum_powerpc.h
@@ -0,0 +1,173 @@
+/*
+ * 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);
+}
diff --git a/cpukit/libnetworking/netinet/in_pcb.c b/cpukit/libnetworking/netinet/in_pcb.c
new file mode 100644
index 0000000000..0cdaedf52c
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in_pcb.c
@@ -0,0 +1,760 @@
+/*
+ * Copyright (c) 1982, 1986, 1991, 1993, 1995
+ * 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.
+ * 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_pcb.c 8.4 (Berkeley) 5/24/95
+ * $FreeBSD: src/sys/netinet/in_pcb.c,v 1.158 2005/01/07 01:45:44 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+
+struct in_addr zeroin_addr;
+
+static void in_pcbinshash __P((struct inpcb *));
+static void in_rtchange __P((struct inpcb *, int));
+
+/*
+ * These configure the range of local port addresses assigned to
+ * "unspecified" outgoing connections/packets/whatever.
+ */
+static int ipport_lowfirstauto = IPPORT_RESERVED - 1; /* 1023 */
+static int ipport_lowlastauto = IPPORT_RESERVEDSTART; /* 600 */
+static int ipport_firstauto = IPPORT_RESERVED; /* 1024 */
+static int ipport_lastauto = IPPORT_USERRESERVED; /* 5000 */
+static int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 40000 */
+static int ipport_hilastauto = IPPORT_HILASTAUTO; /* 44999 */
+
+#define RANGECHK(var, min, max) \
+ if ((var) < (min)) { (var) = (min); } \
+ else if ((var) > (max)) { (var) = (max); }
+
+static int
+sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS)
+{
+ int error = sysctl_handle_int(oidp,
+ oidp->oid_arg1, oidp->oid_arg2, req);
+ if (!error) {
+ RANGECHK(ipport_lowfirstauto, 1, IPPORT_RESERVED - 1);
+ RANGECHK(ipport_lowlastauto, 1, IPPORT_RESERVED - 1);
+ RANGECHK(ipport_firstauto, IPPORT_RESERVED, USHRT_MAX);
+ RANGECHK(ipport_lastauto, IPPORT_RESERVED, USHRT_MAX);
+ RANGECHK(ipport_hifirstauto, IPPORT_RESERVED, USHRT_MAX);
+ RANGECHK(ipport_hilastauto, IPPORT_RESERVED, USHRT_MAX);
+ }
+ return error;
+}
+
+#undef RANGECHK
+
+SYSCTL_NODE(_net_inet_ip, IPPROTO_IP, portrange, CTLFLAG_RW, 0, "IP Ports");
+
+SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowfirst, CTLTYPE_INT|CTLFLAG_RW,
+ &ipport_lowfirstauto, 0, &sysctl_net_ipport_check, "I", "");
+SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowlast, CTLTYPE_INT|CTLFLAG_RW,
+ &ipport_lowlastauto, 0, &sysctl_net_ipport_check, "I", "");
+SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, first, CTLTYPE_INT|CTLFLAG_RW,
+ &ipport_firstauto, 0, &sysctl_net_ipport_check, "I", "");
+SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, last, CTLTYPE_INT|CTLFLAG_RW,
+ &ipport_lastauto, 0, &sysctl_net_ipport_check, "I", "");
+SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hifirst, CTLTYPE_INT|CTLFLAG_RW,
+ &ipport_hifirstauto, 0, &sysctl_net_ipport_check, "I", "");
+SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hilast, CTLTYPE_INT|CTLFLAG_RW,
+ &ipport_hilastauto, 0, &sysctl_net_ipport_check, "I", "");
+
+int
+in_pcballoc(so, pcbinfo)
+ struct socket *so;
+ struct inpcbinfo *pcbinfo;
+{
+ register struct inpcb *inp;
+ int s;
+
+ MALLOC(inp, struct inpcb *, sizeof(*inp), M_PCB, M_NOWAIT);
+ if (inp == NULL)
+ return (ENOBUFS);
+ bzero((caddr_t)inp, sizeof(*inp));
+ inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
+ inp->inp_pcbinfo = pcbinfo;
+ inp->inp_socket = so;
+ s = splnet();
+ LIST_INSERT_HEAD(pcbinfo->listhead, inp, inp_list);
+ pcbinfo->ipi_count++;
+ in_pcbinshash(inp);
+ splx(s);
+ so->so_pcb = (caddr_t)inp;
+ return (0);
+}
+
+int
+in_pcbbind(inp, nam)
+ register struct inpcb *inp;
+ struct mbuf *nam;
+{
+ register struct socket *so = inp->inp_socket;
+ unsigned short *lastport;
+ struct sockaddr_in *sin;
+ u_short lport = 0;
+ int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
+ int error;
+
+ if (in_ifaddr == 0)
+ return (EADDRNOTAVAIL);
+ if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY)
+ return (EINVAL);
+ if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 &&
+ ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
+ (so->so_options & SO_ACCEPTCONN) == 0))
+ wild = 1;
+ if (nam) {
+ sin = mtod(nam, struct sockaddr_in *);
+ if (nam->m_len != sizeof (*sin))
+ return (EINVAL);
+#ifdef notdef
+ /*
+ * We should check the family, but old programs
+ * incorrectly fail to initialize it.
+ */
+ if (sin->sin_family != AF_INET)
+ return (EAFNOSUPPORT);
+#endif
+ lport = sin->sin_port;
+ if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
+ /*
+ * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
+ * allow complete duplication of binding if
+ * SO_REUSEPORT is set, or if SO_REUSEADDR is set
+ * and a multicast address is bound on both
+ * new and duplicated sockets.
+ */
+ if (so->so_options & SO_REUSEADDR)
+ reuseport = SO_REUSEADDR|SO_REUSEPORT;
+ } else if (sin->sin_addr.s_addr != INADDR_ANY) {
+ sin->sin_port = 0; /* yech... */
+ if (ifa_ifwithaddr((struct sockaddr *)sin) == 0)
+ return (EADDRNOTAVAIL);
+ }
+ if (lport) {
+ struct inpcb *t;
+
+ /* GROSS */
+ if (ntohs(lport) < IPPORT_RESERVED &&
+ (error = suser(p->p_ucred, &p->p_acflag)))
+ return (EACCES);
+ if (so->so_uid) {
+ t = in_pcblookup(inp->inp_pcbinfo, zeroin_addr,
+ 0, sin->sin_addr, lport,
+ INPLOOKUP_WILDCARD);
+ if (t && (so->so_uid != t->inp_socket->so_uid))
+ return (EADDRINUSE);
+ }
+ t = in_pcblookup(inp->inp_pcbinfo, zeroin_addr, 0,
+ sin->sin_addr, lport, wild);
+ if (t && (reuseport & t->inp_socket->so_options) == 0)
+ return (EADDRINUSE);
+ }
+ inp->inp_laddr = sin->sin_addr;
+ }
+ if (lport == 0) {
+ ushort first, last;
+ int count;
+
+ inp->inp_flags |= INP_ANONPORT;
+
+ if (inp->inp_flags & INP_HIGHPORT) {
+ first = ipport_hifirstauto; /* sysctl */
+ last = ipport_hilastauto;
+ lastport = &inp->inp_pcbinfo->lasthi;
+ } else if (inp->inp_flags & INP_LOWPORT) {
+ if ((error = suser(p->p_ucred, &p->p_acflag)))
+ return (EACCES);
+ first = ipport_lowfirstauto; /* 1023 */
+ last = ipport_lowlastauto; /* 600 */
+ lastport = &inp->inp_pcbinfo->lastlow;
+ } else {
+ first = ipport_firstauto; /* sysctl */
+ last = ipport_lastauto;
+ lastport = &inp->inp_pcbinfo->lastport;
+ }
+ /*
+ * Simple check to ensure all ports are not used up causing
+ * a deadlock here.
+ *
+ * We split the two cases (up and down) so that the direction
+ * is not being tested on each round of the loop.
+ */
+ if (first > last) {
+ /*
+ * counting down
+ */
+ count = first - last;
+
+ do {
+ if (count-- <= 0) /* completely used? */
+ return (EADDRNOTAVAIL);
+ --*lastport;
+ if (*lastport > first || *lastport < last)
+ *lastport = first;
+ lport = htons(*lastport);
+ } while (in_pcblookup(inp->inp_pcbinfo,
+ zeroin_addr, 0, inp->inp_laddr, lport, wild));
+ } else {
+ /*
+ * counting up
+ */
+ count = last - first;
+
+ do {
+ if (count-- <= 0) /* completely used? */
+ return (EADDRNOTAVAIL);
+ ++*lastport;
+ if (*lastport < first || *lastport > last)
+ *lastport = first;
+ lport = htons(*lastport);
+ } while (in_pcblookup(inp->inp_pcbinfo,
+ zeroin_addr, 0, inp->inp_laddr, lport, wild));
+ }
+ }
+ inp->inp_lport = lport;
+ in_pcbrehash(inp);
+ return (0);
+}
+
+/*
+ * Transform old in_pcbconnect() into an inner subroutine for new
+ * in_pcbconnect(): Do some validity-checking on the remote
+ * address (in mbuf 'nam') and then determine local host address
+ * (i.e., which interface) to use to access that remote host.
+ *
+ * This preserves definition of in_pcbconnect(), while supporting a
+ * slightly different version for T/TCP. (This is more than
+ * a bit of a kludge, but cleaning up the internal interfaces would
+ * have forced minor changes in every protocol).
+ */
+
+int
+in_pcbladdr(inp, nam, plocal_sin)
+ register struct inpcb *inp;
+ struct mbuf *nam;
+ struct sockaddr_in **plocal_sin;
+{
+ struct in_ifaddr *ia;
+ register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
+
+ if (nam->m_len != sizeof (*sin))
+ return (EINVAL);
+ if (sin->sin_family != AF_INET)
+ return (EAFNOSUPPORT);
+ if (sin->sin_port == 0)
+ return (EADDRNOTAVAIL);
+ if (in_ifaddr) {
+ /*
+ * If the destination address is INADDR_ANY,
+ * use the primary local address.
+ * If the supplied address is INADDR_BROADCAST,
+ * and the primary interface supports broadcast,
+ * choose the broadcast address for that interface.
+ */
+#define satosin(sa) ((struct sockaddr_in *)(sa))
+#define sintosa(sin) ((struct sockaddr *)(sin))
+#define ifatoia(ifa) ((struct in_ifaddr *)(ifa))
+ if (sin->sin_addr.s_addr == INADDR_ANY)
+ sin->sin_addr = IA_SIN(in_ifaddr)->sin_addr;
+ else if (sin->sin_addr.s_addr == (u_long)INADDR_BROADCAST &&
+ (in_ifaddr->ia_ifp->if_flags & IFF_BROADCAST))
+ sin->sin_addr = satosin(&in_ifaddr->ia_broadaddr)->sin_addr;
+ }
+ if (inp->inp_laddr.s_addr == INADDR_ANY) {
+ register struct route *ro;
+
+ ia = (struct in_ifaddr *)0;
+ /*
+ * If route is known or can be allocated now,
+ * our src addr is taken from the i/f, else punt.
+ */
+ ro = &inp->inp_route;
+ if (ro->ro_rt &&
+ (satosin(&ro->ro_dst)->sin_addr.s_addr !=
+ sin->sin_addr.s_addr ||
+ inp->inp_socket->so_options & SO_DONTROUTE)) {
+ RTFREE(ro->ro_rt);
+ ro->ro_rt = (struct rtentry *)0;
+ }
+ if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/
+ (ro->ro_rt == (struct rtentry *)0 ||
+ ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
+ /* No route yet, so try to acquire one */
+ ro->ro_dst.sa_family = AF_INET;
+ ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
+ ((struct sockaddr_in *) &ro->ro_dst)->sin_addr =
+ sin->sin_addr;
+ rtalloc(ro);
+ }
+ /*
+ * If we found a route, use the address
+ * corresponding to the outgoing interface
+ * unless it is the loopback (in case a route
+ * to our address on another net goes to loopback).
+ */
+ if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK))
+ ia = ifatoia(ro->ro_rt->rt_ifa);
+ if (ia == 0) {
+ u_short fport = sin->sin_port;
+
+ sin->sin_port = 0;
+ ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin)));
+ if (ia == 0)
+ ia = ifatoia(ifa_ifwithnet(sintosa(sin)));
+ sin->sin_port = fport;
+ if (ia == 0)
+ ia = in_ifaddr;
+ if (ia == 0)
+ return (EADDRNOTAVAIL);
+ }
+ /*
+ * If the destination address is multicast and an outgoing
+ * interface has been set as a multicast option, use the
+ * address of that interface as our source address.
+ */
+ if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) &&
+ inp->inp_moptions != NULL) {
+ struct ip_moptions *imo;
+ struct ifnet *ifp;
+
+ imo = inp->inp_moptions;
+ if (imo->imo_multicast_ifp != NULL) {
+ ifp = imo->imo_multicast_ifp;
+ for (ia = in_ifaddr; ia; ia = ia->ia_next)
+ if (ia->ia_ifp == ifp)
+ break;
+ if (ia == 0)
+ return (EADDRNOTAVAIL);
+ }
+ }
+ /*
+ * Don't do pcblookup call here; return interface in plocal_sin
+ * and exit to caller, that will do the lookup.
+ */
+ *plocal_sin = &ia->ia_addr;
+
+ }
+ return(0);
+}
+
+/*
+ * Outer subroutine:
+ * Connect from a socket to a specified address.
+ * Both address and port must be specified in argument sin.
+ * If don't have a local address for this socket yet,
+ * then pick one.
+ */
+int
+in_pcbconnect(inp, nam)
+ register struct inpcb *inp;
+ struct mbuf *nam;
+{
+ struct sockaddr_in *ifaddr;
+ register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
+ int error;
+
+ /*
+ * Call inner routine, to assign local interface address.
+ */
+ if ((error = in_pcbladdr(inp, nam, &ifaddr)))
+ return(error);
+
+ if (in_pcblookuphash(inp->inp_pcbinfo, sin->sin_addr, sin->sin_port,
+ inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr,
+ inp->inp_lport, 0) != NULL)
+ return (EADDRINUSE);
+ if (inp->inp_laddr.s_addr == INADDR_ANY) {
+ if (inp->inp_lport == 0)
+ (void)in_pcbbind(inp, (struct mbuf *)0);
+ inp->inp_laddr = ifaddr->sin_addr;
+ }
+ inp->inp_faddr = sin->sin_addr;
+ inp->inp_fport = sin->sin_port;
+ in_pcbrehash(inp);
+ return (0);
+}
+
+void
+in_pcbdisconnect(inp)
+ struct inpcb *inp;
+{
+
+ inp->inp_faddr.s_addr = INADDR_ANY;
+ inp->inp_fport = 0;
+ in_pcbrehash(inp);
+ if (inp->inp_socket->so_state & SS_NOFDREF)
+ in_pcbdetach(inp);
+}
+
+void
+in_pcbdetach(inp)
+ struct inpcb *inp;
+{
+ struct socket *so = inp->inp_socket;
+ struct inpcbinfo *ipi = inp->inp_pcbinfo;
+ int s;
+
+ inp->inp_gencnt = ++ipi->ipi_gencnt;
+ so->so_pcb = 0;
+ sofree(so);
+ if (inp->inp_options)
+ (void)m_free(inp->inp_options);
+ if (inp->inp_route.ro_rt)
+ rtfree(inp->inp_route.ro_rt);
+ ip_freemoptions(inp->inp_moptions);
+ s = splnet();
+ LIST_REMOVE(inp, inp_hash);
+ LIST_REMOVE(inp, inp_list);
+ splx(s);
+ FREE(inp, M_PCB);
+}
+
+void
+in_setsockaddr(inp, nam)
+ register struct inpcb *inp;
+ struct mbuf *nam;
+{
+ register struct sockaddr_in *sin;
+
+ nam->m_len = sizeof (*sin);
+ sin = mtod(nam, struct sockaddr_in *);
+ bzero((caddr_t)sin, sizeof (*sin));
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_port = inp->inp_lport;
+ sin->sin_addr = inp->inp_laddr;
+}
+
+void
+in_setpeeraddr(inp, nam)
+ struct inpcb *inp;
+ struct mbuf *nam;
+{
+ register struct sockaddr_in *sin;
+
+ nam->m_len = sizeof (*sin);
+ sin = mtod(nam, struct sockaddr_in *);
+ bzero((caddr_t)sin, sizeof (*sin));
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_port = inp->inp_fport;
+ sin->sin_addr = inp->inp_faddr;
+}
+
+/*
+ * Pass some notification to all connections of a protocol
+ * associated with address dst. The local address and/or port numbers
+ * may be specified to limit the search. The "usual action" will be
+ * taken, depending on the ctlinput cmd. The caller must filter any
+ * cmds that are uninteresting (e.g., no error in the map).
+ * Call the protocol specific routine (if any) to report
+ * any errors for each matching socket.
+ *
+ * Must be called at splnet.
+ */
+void
+in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify)
+ struct inpcbhead *head;
+ struct sockaddr *dst;
+ u_int fport_arg, lport_arg;
+ struct in_addr laddr;
+ int cmd;
+ void (*notify) __P((struct inpcb *, int));
+{
+ register struct inpcb *inp, *oinp;
+ struct in_addr faddr;
+ u_short fport = fport_arg, lport = lport_arg;
+ int errnum, s;
+
+ if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET)
+ return;
+ faddr = ((struct sockaddr_in *)dst)->sin_addr;
+ if (faddr.s_addr == INADDR_ANY)
+ return;
+
+ /*
+ * Redirects go to all references to the destination,
+ * and use in_rtchange to invalidate the route cache.
+ * Dead host indications: notify all references to the destination.
+ * Otherwise, if we have knowledge of the local port and address,
+ * deliver only to that socket.
+ */
+ if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) {
+ fport = 0;
+ lport = 0;
+ laddr.s_addr = 0;
+ if (cmd != PRC_HOSTDEAD)
+ notify = in_rtchange;
+ }
+ errnum = inetctlerrmap[cmd];
+ s = splnet();
+ for (inp = head->lh_first; inp != NULL;) {
+ if (inp->inp_faddr.s_addr != faddr.s_addr ||
+ inp->inp_socket == 0 ||
+ (lport && inp->inp_lport != lport) ||
+ (laddr.s_addr && inp->inp_laddr.s_addr != laddr.s_addr) ||
+ (fport && inp->inp_fport != fport)) {
+ inp = inp->inp_list.le_next;
+ continue;
+ }
+ oinp = inp;
+ inp = inp->inp_list.le_next;
+ if (notify)
+ (*notify)(oinp, errnum);
+ }
+ splx(s);
+}
+
+/*
+ * Check for alternatives when higher level complains
+ * about service problems. For now, invalidate cached
+ * routing information. If the route was created dynamically
+ * (by a redirect), time to try a default gateway again.
+ */
+void
+in_losing(inp)
+ struct inpcb *inp;
+{
+ register struct rtentry *rt;
+ struct rt_addrinfo info;
+
+ if ((rt = inp->inp_route.ro_rt)) {
+ inp->inp_route.ro_rt = 0;
+ bzero((caddr_t)&info, sizeof(info));
+ info.rti_info[RTAX_DST] =
+ (struct sockaddr *)&inp->inp_route.ro_dst;
+ info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+ info.rti_info[RTAX_NETMASK] = rt_mask(rt);
+ rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0);
+ if (rt->rt_flags & RTF_DYNAMIC)
+ (void) rtrequest(RTM_DELETE, rt_key(rt),
+ rt->rt_gateway, rt_mask(rt), rt->rt_flags,
+ (struct rtentry **)0);
+ else
+ /*
+ * A new route can be allocated
+ * the next time output is attempted.
+ */
+ rtfree(rt);
+ }
+}
+
+/*
+ * After a routing change, flush old routing
+ * and allocate a (hopefully) better one.
+ */
+static void
+in_rtchange(inp, errnum)
+ register struct inpcb *inp;
+ int errnum;
+{
+ if (inp->inp_route.ro_rt) {
+ rtfree(inp->inp_route.ro_rt);
+ inp->inp_route.ro_rt = 0;
+ /*
+ * A new route can be allocated the next time
+ * output is attempted.
+ */
+ }
+}
+
+struct inpcb *
+in_pcblookup(pcbinfo, faddr, fport_arg, laddr, lport_arg, wild_okay)
+ struct inpcbinfo *pcbinfo;
+ struct in_addr faddr, laddr;
+ u_int fport_arg, lport_arg;
+ int wild_okay;
+{
+ register struct inpcb *inp, *match = NULL;
+ int matchwild = 3, wildcard;
+ u_short fport = fport_arg, lport = lport_arg;
+ int s;
+
+ s = splnet();
+
+ for (inp = pcbinfo->listhead->lh_first; inp != NULL; inp = inp->inp_list.le_next) {
+ if (inp->inp_lport != lport)
+ continue;
+ wildcard = 0;
+ if (inp->inp_faddr.s_addr != INADDR_ANY) {
+ if (faddr.s_addr == INADDR_ANY)
+ wildcard++;
+ else if (inp->inp_faddr.s_addr != faddr.s_addr ||
+ inp->inp_fport != fport)
+ continue;
+ } else {
+ if (faddr.s_addr != INADDR_ANY)
+ wildcard++;
+ }
+ if (inp->inp_laddr.s_addr != INADDR_ANY) {
+ if (laddr.s_addr == INADDR_ANY)
+ wildcard++;
+ else if (inp->inp_laddr.s_addr != laddr.s_addr)
+ continue;
+ } else {
+ if (laddr.s_addr != INADDR_ANY)
+ wildcard++;
+ }
+ if (wildcard && wild_okay == 0)
+ continue;
+ if (wildcard < matchwild) {
+ match = inp;
+ matchwild = wildcard;
+ if (matchwild == 0) {
+ break;
+ }
+ }
+ }
+ splx(s);
+ return (match);
+}
+
+/*
+ * Lookup PCB in hash list.
+ */
+struct inpcb *
+in_pcblookuphash(pcbinfo, faddr, fport_arg, laddr, lport_arg, wildcard)
+ struct inpcbinfo *pcbinfo;
+ struct in_addr faddr, laddr;
+ u_int fport_arg, lport_arg;
+ int wildcard;
+{
+ struct inpcbhead *head;
+ register struct inpcb *inp;
+ u_short fport = fport_arg, lport = lport_arg;
+ int s;
+
+ s = splnet();
+ /*
+ * First look for an exact match.
+ */
+ head = &pcbinfo->hashbase[INP_PCBHASH(faddr.s_addr, lport, fport, pcbinfo->hashmask)];
+ for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) {
+ if (inp->inp_faddr.s_addr == faddr.s_addr &&
+ inp->inp_laddr.s_addr == laddr.s_addr &&
+ inp->inp_fport == fport &&
+ inp->inp_lport == lport)
+ goto found;
+ }
+ if (wildcard) {
+ struct inpcb *local_wild = NULL;
+
+ head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)];
+ for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) {
+ if (inp->inp_faddr.s_addr == INADDR_ANY &&
+ inp->inp_fport == 0 && inp->inp_lport == lport) {
+ if (inp->inp_laddr.s_addr == laddr.s_addr)
+ goto found;
+ else if (inp->inp_laddr.s_addr == INADDR_ANY)
+ local_wild = inp;
+ }
+ }
+ if (local_wild != NULL) {
+ inp = local_wild;
+ goto found;
+ }
+ }
+ splx(s);
+ return (NULL);
+
+found:
+ /*
+ * Move PCB to head of this hash chain so that it can be
+ * found more quickly in the future.
+ * XXX - this is a pessimization on machines with few
+ * concurrent connections.
+ */
+ if (inp != head->lh_first) {
+ LIST_REMOVE(inp, inp_hash);
+ LIST_INSERT_HEAD(head, inp, inp_hash);
+ }
+ splx(s);
+ return (inp);
+}
+
+/*
+ * Insert PCB into hash chain. Must be called at splnet.
+ */
+static void
+in_pcbinshash(inp)
+ struct inpcb *inp;
+{
+ struct inpcbhead *head;
+
+ head = &inp->inp_pcbinfo->hashbase[INP_PCBHASH(inp->inp_faddr.s_addr,
+ inp->inp_lport, inp->inp_fport, inp->inp_pcbinfo->hashmask)];
+
+ LIST_INSERT_HEAD(head, inp, inp_hash);
+}
+
+void
+in_pcbrehash(inp)
+ struct inpcb *inp;
+{
+ struct inpcbhead *head;
+ int s;
+
+ s = splnet();
+ LIST_REMOVE(inp, inp_hash);
+
+ head = &inp->inp_pcbinfo->hashbase[INP_PCBHASH(inp->inp_faddr.s_addr,
+ inp->inp_lport, inp->inp_fport, inp->inp_pcbinfo->hashmask)];
+
+ LIST_INSERT_HEAD(head, inp, inp_hash);
+ inp->inp_pcbinfo->ipi_count--;
+ splx(s);
+}
diff --git a/cpukit/libnetworking/netinet/in_pcb.h b/cpukit/libnetworking/netinet/in_pcb.h
new file mode 100644
index 0000000000..49a9c004bd
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in_pcb.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1982, 1986, 1990, 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_pcb.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NETINET_IN_PCB_H_
+#define _NETINET_IN_PCB_H_
+
+#include <sys/queue.h>
+
+/*
+ * Common structure pcb for internet protocol implementation.
+ * Here are stored pointers to local and foreign host table
+ * entries, local and foreign socket numbers, and pointers
+ * up (to a socket structure) and down (to a protocol-specific)
+ * control block.
+ */
+LIST_HEAD(inpcbhead, inpcb);
+
+typedef u_int64_t inp_gen_t;
+
+struct inpcb {
+ LIST_ENTRY(inpcb) inp_list; /* list for all PCBs of this proto */
+ LIST_ENTRY(inpcb) inp_hash; /* hash list */
+ struct inpcbinfo *inp_pcbinfo; /* PCB list info */
+ struct in_addr inp_faddr; /* foreign host table entry */
+ struct in_addr inp_laddr; /* local host table entry */
+ u_short inp_fport; /* foreign port */
+ u_short inp_lport; /* local port */
+ caddr_t inp_ppcb; /* pointer to per-protocol pcb */
+ struct socket *inp_socket; /* back pointer to socket */
+ struct mbuf *inp_options; /* IP options */
+ struct route inp_route; /* placeholder for routing entry */
+ int inp_flags; /* generic IP/datagram flags */
+ u_char inp_ip_tos; /* type of service proto */
+ u_char inp_ip_ttl; /* time to live proto */
+ u_char inp_ip_p; /* protocol proto */
+ u_char pad[1]; /* alignment */
+ struct ip_moptions *inp_moptions; /* IP multicast options */
+ inp_gen_t inp_gencnt; /* generation count of this instance */
+#if 0 /* Someday, perhaps... */
+ struct ip inp_ip; /* header prototype; should have more */
+#endif
+};
+
+/*
+ * Interface exported to userland by various protocols which use
+ * inpcbs. Hack alert -- only define if struct xsocket is in scope.
+ *
+ * ccj - 20 Nov 2002
+ * Double hack alert. This is taken from the pre 5.0 sources and
+ * merged into RTEMS. This allows the TCPCTL_PCBLIST code in
+ * net-snmp to work.
+ */
+#ifdef _SYS_SOCKETVAR_H_
+typedef u_int64_t so_gen_t; /* should be in sys/sockvar.h */
+
+struct xinpcb {
+ size_t xi_len; /* length of this structure */
+ struct inpcb xi_inp;
+/* struct xsocket xi_socket; ccj removed */
+ u_int64_t xi_alignment_hack;
+};
+
+
+struct xinpgen {
+ size_t xig_len; /* length of this structure */
+ u_int xig_count; /* number of PCBs at this time */
+ inp_gen_t xig_gen; /* generation count at this time */
+ so_gen_t xig_sogen; /* socket generation count at this time */
+};
+#endif /* _SYS_SOCKETVAR_H_ */
+
+struct inpcbinfo {
+ struct inpcbhead *listhead;
+ struct inpcbhead *hashbase;
+ unsigned long hashmask;
+ unsigned short lastport;
+ unsigned short lastlow;
+ unsigned short lasthi;
+ u_int ipi_count; /* number of pcbs in this list */
+ u_int64_t ipi_gencnt; /* current generation count */
+};
+
+#define INP_PCBHASH(faddr, lport, fport, mask) \
+ (((faddr) ^ ((faddr) >> 16) ^ (lport) ^ (fport)) & (mask))
+
+/* flags in inp_flags: */
+#define INP_RECVOPTS 0x01 /* receive incoming IP options */
+#define INP_RECVRETOPTS 0x02 /* receive IP options for reply */
+#define INP_RECVDSTADDR 0x04 /* receive IP dst address */
+#define INP_HDRINCL 0x08 /* user supplies entire IP header */
+#define INP_HIGHPORT 0x10 /* user wants "high" port binding */
+#define INP_LOWPORT 0x20 /* user wants "low" port binding */
+#define INP_ANONPORT 0x40 /* port chosen for user */
+#define INP_RECVIF 0x80 /* receive incoming interface */
+#define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
+ INP_RECVIF)
+
+#define INPLOOKUP_WILDCARD 1
+
+#define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb)
+
+#ifdef _KERNEL
+void in_losing __P((struct inpcb *));
+int in_pcballoc __P((struct socket *, struct inpcbinfo *));
+int in_pcbbind __P((struct inpcb *, struct mbuf *));
+int in_pcbconnect __P((struct inpcb *, struct mbuf *));
+void in_pcbdetach __P((struct inpcb *));
+void in_pcbdisconnect __P((struct inpcb *));
+int in_pcbladdr __P((struct inpcb *, struct mbuf *,
+ struct sockaddr_in **));
+struct inpcb *
+ in_pcblookup __P((struct inpcbinfo *,
+ struct in_addr, u_int, struct in_addr, u_int, int));
+struct inpcb *
+ in_pcblookuphash __P((struct inpcbinfo *,
+ struct in_addr, u_int, struct in_addr, u_int, int));
+void in_pcbnotify __P((struct inpcbhead *, struct sockaddr *,
+ u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int)));
+void in_pcbrehash __P((struct inpcb *));
+void in_setpeeraddr __P((struct inpcb *, struct mbuf *));
+void in_setsockaddr __P((struct inpcb *, struct mbuf *));
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/netinet/in_proto.c b/cpukit/libnetworking/netinet/in_proto.c
new file mode 100644
index 0000000000..b59b7be884
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in_proto.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 1982, 1986, 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_proto.c 8.2 (Berkeley) 2/9/95
+ * $Id$
+ */
+
+#include "opt_tcpdebug.h"
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/radix.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/in_pcb.h>
+#include <netinet/igmp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#ifdef TCPDEBUG
+#include <netinet/tcp_debug.h>
+#endif
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+/*
+ * TCP/IP protocol family: IP, ICMP, UDP, TCP.
+ */
+
+#ifdef IPXIP
+#include <netipx/ipx.h>
+#include <netipx/ipx_ip.h>
+#endif
+
+#ifdef NSIP
+#include <netns/ns.h>
+#include <netns/ns_if.h>
+#endif
+
+#ifdef TPIP
+void tpip_input(), tpip_ctlinput(), tp_init(), tp_slowtimo(), tp_drain();
+int tp_ctloutput(), tp_usrreq();
+#endif
+
+#ifdef EON
+void eoninput(), eonctlinput(), eonprotoinit();
+#endif /* EON */
+
+extern struct domain inetdomain;
+
+struct protosw inetsw[] = {
+{ 0, &inetdomain, 0, 0,
+ 0, 0, 0, 0,
+ 0,
+ ip_init, 0, ip_slowtimo, ip_drain
+},
+{ SOCK_DGRAM, &inetdomain, IPPROTO_UDP, PR_ATOMIC|PR_ADDR,
+ udp_input, 0, udp_ctlinput, ip_ctloutput,
+ udp_usrreq,
+ udp_init
+},
+{ SOCK_STREAM, &inetdomain, IPPROTO_TCP,
+ PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD,
+ tcp_input, 0, tcp_ctlinput, tcp_ctloutput,
+ 0,
+ tcp_init, tcp_fasttimo, tcp_slowtimo, tcp_drain,
+ &tcp_usrreqs
+},
+{ SOCK_RAW, &inetdomain, IPPROTO_RAW, PR_ATOMIC|PR_ADDR,
+ rip_input, 0, 0, rip_ctloutput,
+ rip_usrreq,
+ 0, 0, 0, 0,
+},
+{ SOCK_RAW, &inetdomain, IPPROTO_ICMP, PR_ATOMIC|PR_ADDR,
+ icmp_input, 0, 0, rip_ctloutput,
+ rip_usrreq
+},
+{ SOCK_RAW, &inetdomain, IPPROTO_IGMP, PR_ATOMIC|PR_ADDR,
+ igmp_input, 0, 0, rip_ctloutput,
+ rip_usrreq,
+ igmp_init, igmp_fasttimo, igmp_slowtimo
+},
+{ SOCK_RAW, &inetdomain, IPPROTO_RSVP, PR_ATOMIC|PR_ADDR,
+ rsvp_input, 0, 0, rip_ctloutput,
+ rip_usrreq,
+ 0, 0, 0, 0,
+},
+{ SOCK_RAW, &inetdomain, IPPROTO_IPIP, PR_ATOMIC|PR_ADDR,
+ ipip_input, 0, 0, rip_ctloutput,
+ rip_usrreq,
+ 0, 0, 0, 0,
+},
+#ifdef IPDIVERT
+{ SOCK_RAW, &inetdomain, IPPROTO_DIVERT, PR_ATOMIC|PR_ADDR,
+ div_input, 0, 0, ip_ctloutput,
+ div_usrreq,
+ div_init, 0, 0, 0,
+},
+#endif
+#ifdef TPIP
+{ SOCK_SEQPACKET,&inetdomain, IPPROTO_TP, PR_CONNREQUIRED|PR_WANTRCVD,
+ tpip_input, 0, tpip_ctlinput, tp_ctloutput,
+ tp_usrreq,
+ tp_init, 0, tp_slowtimo, tp_drain,
+},
+#endif
+/* EON (ISO CLNL over IP) */
+#ifdef EON
+{ SOCK_RAW, &inetdomain, IPPROTO_EON, 0,
+ eoninput, 0, eonctlinput, 0,
+ 0,
+ eonprotoinit, 0, 0, 0,
+},
+#endif
+#ifdef IPXIP
+{ SOCK_RAW, &inetdomain, IPPROTO_IDP, PR_ATOMIC|PR_ADDR,
+ ipxip_input, 0, ipxip_ctlinput, 0,
+ rip_usrreq,
+ 0, 0, 0, 0,
+},
+#endif
+#ifdef NSIP
+{ SOCK_RAW, &inetdomain, IPPROTO_IDP, PR_ATOMIC|PR_ADDR,
+ idpip_input, 0, nsip_ctlinput, 0,
+ rip_usrreq,
+ 0, 0, 0, 0,
+},
+#endif
+ /* raw wildcard */
+{ SOCK_RAW, &inetdomain, 0, PR_ATOMIC|PR_ADDR,
+ rip_input, 0, 0, rip_ctloutput,
+ rip_usrreq,
+ rip_init, 0, 0, 0,
+},
+};
+
+extern int in_inithead(void **, int);
+
+struct domain inetdomain =
+ { AF_INET, "internet", 0, 0, 0,
+ inetsw, &inetsw[sizeof(inetsw)/sizeof(inetsw[0])], 0,
+ in_inithead, 32, sizeof(struct sockaddr_in)
+ };
+
+DOMAIN_SET(inet);
+
+SYSCTL_NODE(_net, PF_INET, inet, CTLFLAG_RW, 0,
+ "Internet Family");
+
+SYSCTL_NODE(_net_inet, IPPROTO_IP, ip, CTLFLAG_RW, 0, "IP");
+SYSCTL_NODE(_net_inet, IPPROTO_ICMP, icmp, CTLFLAG_RW, 0, "ICMP");
+SYSCTL_NODE(_net_inet, IPPROTO_UDP, udp, CTLFLAG_RW, 0, "UDP");
+SYSCTL_NODE(_net_inet, IPPROTO_TCP, tcp, CTLFLAG_RW, 0, "TCP");
+SYSCTL_NODE(_net_inet, IPPROTO_IGMP, igmp, CTLFLAG_RW, 0, "IGMP");
+#ifdef IPDIVERT
+SYSCTL_NODE(_net_inet, IPPROTO_DIVERT, div, CTLFLAG_RW, 0, "DIVERT");
+#endif
diff --git a/cpukit/libnetworking/netinet/in_rmx.c b/cpukit/libnetworking/netinet/in_rmx.c
new file mode 100644
index 0000000000..bfdd1e1c8f
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in_rmx.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright 1994, 1995 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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.
+ *
+ * $Id$
+ */
+
+/*
+ * This code does two things necessary for the enhanced TCP metrics to
+ * function in a useful manner:
+ * 1) It marks all non-host routes as `cloning', thus ensuring that
+ * every actual reference to such a route actually gets turned
+ * into a reference to a host route to the specific destination
+ * requested.
+ * 2) When such routes lose all their references, it arranges for them
+ * to be deleted in some random collection of circumstances, so that
+ * a large quantity of stale routing data is not kept in kernel memory
+ * indefinitely. See in_rtqtimo() below for the exact mechanism.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/mbuf.h>
+#include <sys/syslog.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#include <netinet/tcp.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+
+extern int in_inithead __P((void **head, int off));
+
+#define RTPRF_OURS RTF_PROTO3 /* set on routes we manage */
+
+/*
+ * Do what we need to do when inserting a route.
+ */
+static struct radix_node *
+in_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
+ struct radix_node *treenodes)
+{
+ struct rtentry *rt = (struct rtentry *)treenodes;
+ struct sockaddr_in *sin = (struct sockaddr_in *)rt_key(rt);
+ struct radix_node *ret;
+
+ /*
+ * For IP, all unicast non-host routes are automatically cloning.
+ */
+ if(IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
+ rt->rt_flags |= RTF_MULTICAST;
+
+ if(!(rt->rt_flags & (RTF_HOST | RTF_CLONING | RTF_MULTICAST))) {
+ rt->rt_flags |= RTF_PRCLONING;
+ }
+
+ /*
+ * A little bit of help for both IP output and input:
+ * For host routes, we make sure that RTF_BROADCAST
+ * is set for anything that looks like a broadcast address.
+ * This way, we can avoid an expensive call to in_broadcast()
+ * in ip_output() most of the time (because the route passed
+ * to ip_output() is almost always a host route).
+ *
+ * We also do the same for local addresses, with the thought
+ * that this might one day be used to speed up ip_input().
+ *
+ * We also mark routes to multicast addresses as such, because
+ * it's easy to do and might be useful (but this is much more
+ * dubious since it's so easy to inspect the address). (This
+ * is done above.)
+ */
+ if (rt->rt_flags & RTF_HOST) {
+ if (in_broadcast(sin->sin_addr, rt->rt_ifp)) {
+ rt->rt_flags |= RTF_BROADCAST;
+ } else {
+#define satosin(sa) ((struct sockaddr_in *)sa)
+ if (satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr
+ == sin->sin_addr.s_addr)
+ rt->rt_flags |= RTF_LOCAL;
+#undef satosin
+ }
+ }
+
+ /*
+ * We also specify a send and receive pipe size for every
+ * route added, to help TCP a bit. TCP doesn't actually
+ * want a true pipe size, which would be prohibitive in memory
+ * costs and is hard to compute anyway; it simply uses these
+ * values to size its buffers. So, we fill them in with the
+ * same values that TCP would have used anyway, and allow the
+ * installing program or the link layer to override these values
+ * as it sees fit. This will hopefully allow TCP more
+ * opportunities to save its ssthresh value.
+ */
+ if (!rt->rt_rmx.rmx_sendpipe && !(rt->rt_rmx.rmx_locks & RTV_SPIPE))
+ rt->rt_rmx.rmx_sendpipe = tcp_sendspace;
+
+ if (!rt->rt_rmx.rmx_recvpipe && !(rt->rt_rmx.rmx_locks & RTV_RPIPE))
+ rt->rt_rmx.rmx_recvpipe = tcp_recvspace;
+
+ if (!rt->rt_rmx.rmx_mtu && !(rt->rt_rmx.rmx_locks & RTV_MTU)
+ && rt->rt_ifp)
+ rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
+
+ ret = rn_addroute(v_arg, n_arg, head, treenodes);
+ if (ret == NULL && rt->rt_flags & RTF_HOST) {
+ struct rtentry *rt2;
+ /*
+ * We are trying to add a host route, but can't.
+ * Find out if it is because of an
+ * ARP entry and delete it if so.
+ */
+ rt2 = rtalloc1((struct sockaddr *)sin, 0,
+ RTF_CLONING | RTF_PRCLONING);
+ if (rt2) {
+ if (rt2->rt_flags & RTF_LLINFO &&
+ rt2->rt_flags & RTF_HOST &&
+ rt2->rt_gateway &&
+ rt2->rt_gateway->sa_family == AF_LINK) {
+ rtrequest(RTM_DELETE,
+ (struct sockaddr *)rt_key(rt2),
+ rt2->rt_gateway,
+ rt_mask(rt2), rt2->rt_flags, 0);
+ ret = rn_addroute(v_arg, n_arg, head,
+ treenodes);
+ }
+ RTFREE(rt2);
+ }
+ }
+ return ret;
+}
+
+/*
+ * This code is the inverse of in_clsroute: on first reference, if we
+ * were managing the route, stop doing so and set the expiration timer
+ * back off again.
+ */
+static struct radix_node *
+in_matroute(void *v_arg, struct radix_node_head *head)
+{
+ struct radix_node *rn = rn_match(v_arg, head);
+ struct rtentry *rt = (struct rtentry *)rn;
+
+ if(rt && rt->rt_refcnt == 0) { /* this is first reference */
+ if(rt->rt_flags & RTPRF_OURS) {
+ rt->rt_flags &= ~RTPRF_OURS;
+ rt->rt_rmx.rmx_expire = 0;
+ }
+ }
+ return rn;
+}
+
+static int rtq_reallyold = 60*60;
+ /* one hour is ``really old'' */
+SYSCTL_INT(_net_inet_ip, IPCTL_RTEXPIRE, rtexpire,
+ CTLFLAG_RW, &rtq_reallyold , 0, "");
+
+static int rtq_minreallyold = 10;
+ /* never automatically crank down to less */
+SYSCTL_INT(_net_inet_ip, IPCTL_RTMINEXPIRE, rtminexpire,
+ CTLFLAG_RW, &rtq_minreallyold , 0, "");
+
+static int rtq_toomany = 128;
+ /* 128 cached routes is ``too many'' */
+SYSCTL_INT(_net_inet_ip, IPCTL_RTMAXCACHE, rtmaxcache,
+ CTLFLAG_RW, &rtq_toomany , 0, "");
+
+
+/*
+ * On last reference drop, mark the route as belong to us so that it can be
+ * timed out.
+ */
+static void
+in_clsroute(struct radix_node *rn, struct radix_node_head *head)
+{
+ struct rtentry *rt = (struct rtentry *)rn;
+
+ if(!(rt->rt_flags & RTF_UP))
+ return; /* prophylactic measures */
+
+ if((rt->rt_flags & (RTF_LLINFO | RTF_HOST)) != RTF_HOST)
+ return;
+
+ if((rt->rt_flags & (RTF_WASCLONED | RTPRF_OURS))
+ != RTF_WASCLONED)
+ return;
+
+ /*
+ * As requested by David Greenman:
+ * If rtq_reallyold is 0, just delete the route without
+ * waiting for a timeout cycle to kill it.
+ */
+ if(rtq_reallyold != 0) {
+ rt->rt_flags |= RTPRF_OURS;
+ rt->rt_rmx.rmx_expire = rtems_bsdnet_seconds_since_boot() + rtq_reallyold;
+ } else {
+ rtrequest(RTM_DELETE,
+ (struct sockaddr *)rt_key(rt),
+ rt->rt_gateway, rt_mask(rt),
+ rt->rt_flags, 0);
+ }
+}
+
+struct rtqk_arg {
+ struct radix_node_head *rnh;
+ int draining;
+ int killed;
+ int found;
+ int updating;
+ time_t nextstop;
+};
+
+/*
+ * Get rid of old routes. When draining, this deletes everything, even when
+ * the timeout is not expired yet. When updating, this makes sure that
+ * nothing has a timeout longer than the current value of rtq_reallyold.
+ */
+static int
+in_rtqkill(struct radix_node *rn, void *rock)
+{
+ struct rtqk_arg *ap = rock;
+ struct rtentry *rt = (struct rtentry *)rn;
+ int err;
+
+ if(rt->rt_flags & RTPRF_OURS) {
+ ap->found++;
+
+ if(ap->draining || rt->rt_rmx.rmx_expire <= rtems_bsdnet_seconds_since_boot()) {
+ if(rt->rt_refcnt > 0)
+ panic("rtqkill route really not free");
+
+ err = rtrequest(RTM_DELETE,
+ (struct sockaddr *)rt_key(rt),
+ rt->rt_gateway, rt_mask(rt),
+ rt->rt_flags, 0);
+ if(err) {
+ log(LOG_WARNING, "in_rtqkill: error %d\n", err);
+ } else {
+ ap->killed++;
+ }
+ } else {
+ if(ap->updating
+ && (rt->rt_rmx.rmx_expire - rtems_bsdnet_seconds_since_boot()
+ > rtq_reallyold)) {
+ rt->rt_rmx.rmx_expire = rtems_bsdnet_seconds_since_boot()
+ + rtq_reallyold;
+ }
+ ap->nextstop = lmin(ap->nextstop,
+ rt->rt_rmx.rmx_expire);
+ }
+ }
+
+ return 0;
+}
+
+#define RTQ_TIMEOUT 60*10 /* run no less than once every ten minutes */
+static int rtq_timeout = RTQ_TIMEOUT;
+
+static void
+in_rtqtimo(void *rock)
+{
+ struct radix_node_head *rnh = rock;
+ struct rtqk_arg arg;
+ struct timeval atv;
+ static time_t last_adjusted_timeout = 0;
+ int s;
+
+ arg.found = arg.killed = 0;
+ arg.rnh = rnh;
+ arg.nextstop = rtems_bsdnet_seconds_since_boot() + rtq_timeout;
+ arg.draining = arg.updating = 0;
+ s = splnet();
+ rnh->rnh_walktree(rnh, in_rtqkill, &arg);
+ splx(s);
+
+ /*
+ * Attempt to be somewhat dynamic about this:
+ * If there are ``too many'' routes sitting around taking up space,
+ * then crank down the timeout, and see if we can't make some more
+ * go away. However, we make sure that we will never adjust more
+ * than once in rtq_timeout seconds, to keep from cranking down too
+ * hard.
+ */
+ if((arg.found - arg.killed > rtq_toomany)
+ && (rtems_bsdnet_seconds_since_boot() - last_adjusted_timeout >= rtq_timeout)
+ && rtq_reallyold > rtq_minreallyold) {
+ rtq_reallyold = 2*rtq_reallyold / 3;
+ if(rtq_reallyold < rtq_minreallyold) {
+ rtq_reallyold = rtq_minreallyold;
+ }
+
+ last_adjusted_timeout = rtems_bsdnet_seconds_since_boot();
+#ifdef DIAGNOSTIC
+ log(LOG_DEBUG, "in_rtqtimo: adjusted rtq_reallyold to %d\n",
+ rtq_reallyold);
+#endif
+ arg.found = arg.killed = 0;
+ arg.updating = 1;
+ s = splnet();
+ rnh->rnh_walktree(rnh, in_rtqkill, &arg);
+ splx(s);
+ }
+
+ atv.tv_usec = 0;
+ atv.tv_sec = arg.nextstop;
+ timeout(in_rtqtimo, rock, hzto(&atv));
+}
+
+void
+in_rtqdrain(void)
+{
+ struct radix_node_head *rnh = rt_tables[AF_INET];
+ struct rtqk_arg arg;
+ int s;
+ arg.found = arg.killed = 0;
+ arg.rnh = rnh;
+ arg.nextstop = 0;
+ arg.draining = 1;
+ arg.updating = 0;
+ s = splnet();
+ rnh->rnh_walktree(rnh, in_rtqkill, &arg);
+ splx(s);
+}
+
+/*
+ * Initialize our routing tree.
+ */
+int
+in_inithead(void **head, int off)
+{
+ struct radix_node_head *rnh;
+
+ if(!rn_inithead(head, off))
+ return 0;
+
+ if(head != (void **)&rt_tables[AF_INET]) /* BOGUS! */
+ return 1; /* only do this for the real routing table */
+
+ rnh = *head;
+ rnh->rnh_addaddr = in_addroute;
+ rnh->rnh_matchaddr = in_matroute;
+ rnh->rnh_close = in_clsroute;
+ in_rtqtimo(rnh); /* kick off timeout first time */
+ return 1;
+}
diff --git a/cpukit/libnetworking/netinet/in_systm.h b/cpukit/libnetworking/netinet/in_systm.h
new file mode 100644
index 0000000000..6178a7bf5e
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in_systm.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1982, 1986, 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_systm.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NETINET_IN_SYSTM_H_
+#define _NETINET_IN_SYSTM_H_
+
+/*
+ * Miscellaneous internetwork
+ * definitions for kernel.
+ */
+
+/*
+ * Network types.
+ *
+ * Internally the system keeps counters in the headers with the bytes
+ * swapped so that VAX instructions will work on them. It reverses
+ * the bytes before transmission at each protocol level. The n_ types
+ * represent the types with the bytes in ``high-ender'' order.
+ */
+typedef u_short n_short; /* short as received from the net */
+typedef u_long n_long; /* long as received from the net */
+
+typedef u_long n_time; /* ms since 00:00 GMT, byte rev */
+
+#ifdef _KERNEL
+n_time iptime __P((void));
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/netinet/in_var.h b/cpukit/libnetworking/netinet/in_var.h
new file mode 100644
index 0000000000..505d99e6a2
--- /dev/null
+++ b/cpukit/libnetworking/netinet/in_var.h
@@ -0,0 +1,238 @@
+/* $Id */
+/*
+ * Copyright (c) 1985, 1986, 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.
+ * 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_var.h 8.2 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/netinet/in_var.h,v 1.52 2004/10/19 21:06:14 andre Exp $
+ */
+
+#ifndef _NETINET_IN_VAR_H_
+#define _NETINET_IN_VAR_H_
+
+#include <sys/queue.h>
+#if !defined(__rtems__)
+#include <sys/fnv_hash.h>
+#endif
+
+/*
+ * Interface address, Internet version. One of these structures
+ * is allocated for each Internet address on an interface.
+ * The ifaddr structure contains the protocol-independent part
+ * of the structure and is assumed to be first.
+ */
+struct in_ifaddr {
+ struct ifaddr ia_ifa; /* protocol-independent info */
+#define ia_ifp ia_ifa.ifa_ifp
+#define ia_flags ia_ifa.ifa_flags
+ /* ia_{,sub}net{,mask} in host order */
+ u_long ia_net; /* network number of interface */
+ u_long ia_netmask; /* mask of net part */
+ u_long ia_subnet; /* subnet number, including net */
+ u_long ia_subnetmask; /* mask of subnet part */
+ struct in_addr ia_netbroadcast; /* to recognize net broadcasts */
+ struct in_ifaddr *ia_next; /* next in list of internet addresses */
+ struct sockaddr_in ia_addr; /* reserve space for interface name */
+ struct sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
+#define ia_broadaddr ia_dstaddr
+ struct sockaddr_in ia_sockmask; /* reserve space for general netmask */
+ LIST_HEAD(in_multihead, in_multi) ia_multiaddrs;
+ /* list of multicast addresses */
+};
+
+struct in_aliasreq {
+ char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ struct sockaddr_in ifra_addr;
+ struct sockaddr_in ifra_broadaddr;
+#define ifra_dstaddr ifra_broadaddr
+ struct sockaddr_in ifra_mask;
+};
+/*
+ * Given a pointer to an in_ifaddr (ifaddr),
+ * return a pointer to the addr as a sockaddr_in.
+ */
+#define IA_SIN(ia) (&(((struct in_ifaddr *)(ia))->ia_addr))
+#define IA_DSTSIN(ia) (&(((struct in_ifaddr *)(ia))->ia_dstaddr))
+
+#define IN_LNAOF(in, ifa) \
+ ((ntohl((in).s_addr) & ~((struct in_ifaddr *)(ifa)->ia_subnetmask))
+
+
+#ifdef _KERNEL
+extern struct in_ifaddr *in_ifaddr;
+extern struct ifqueue ipintrq; /* ip packet input queue */
+extern struct in_addr zeroin_addr;
+extern u_char inetctlerrmap[];
+
+/*
+ * Macro for finding the interface (ifnet structure) corresponding to one
+ * of our IP addresses.
+ */
+#define INADDR_TO_IFP(addr, ifp) \
+ /* struct in_addr addr; */ \
+ /* struct ifnet *ifp; */ \
+{ \
+ register struct in_ifaddr *ia; \
+\
+ for (ia = in_ifaddr; \
+ ia != NULL && ((ia->ia_ifp->if_flags & IFF_POINTOPOINT)? \
+ IA_DSTSIN(ia):IA_SIN(ia))->sin_addr.s_addr != (addr).s_addr; \
+ ia = ia->ia_next) \
+ continue; \
+ if (ia == NULL) \
+ for (ia = in_ifaddr; \
+ ia != NULL; \
+ ia = ia->ia_next) \
+ if (ia->ia_ifp->if_flags & IFF_POINTOPOINT && \
+ IA_SIN(ia)->sin_addr.s_addr == (addr).s_addr) \
+ break; \
+ (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
+}
+
+/*
+ * Macro for finding the internet address structure (in_ifaddr) corresponding
+ * to a given interface (ifnet structure).
+ */
+#define IFP_TO_IA(ifp, ia) \
+ /* struct ifnet *ifp; */ \
+ /* struct in_ifaddr *ia; */ \
+{ \
+ for ((ia) = in_ifaddr; \
+ (ia) != NULL && (ia)->ia_ifp != (ifp); \
+ (ia) = (ia)->ia_next) \
+ continue; \
+}
+#endif
+
+/*
+ * This information should be part of the ifnet structure but we don't wish
+ * to change that - as it might break a number of things
+ */
+
+struct router_info {
+ struct ifnet *rti_ifp;
+ int rti_type; /* type of router which is querier on this interface */
+ int rti_time; /* # of slow timeouts since last old query */
+ struct router_info *rti_next;
+};
+
+/*
+ * Internet multicast address structure. There is one of these for each IP
+ * multicast group to which this host belongs on a given network interface.
+ * They are kept in a linked list, rooted in the interface's in_ifaddr
+ * structure.
+ */
+struct in_multi {
+ LIST_ENTRY(in_multi) inm_entry; /* list glue */
+ struct in_addr inm_addr; /* IP multicast address */
+ struct ifnet *inm_ifp; /* back pointer to ifnet */
+ struct in_ifaddr *inm_ia; /* back pointer to in_ifaddr */
+ u_int inm_refcount; /* no. membership claims by sockets */
+ u_int inm_timer; /* IGMP membership report timer */
+ u_int inm_state; /* state of the membership */
+ struct router_info *inm_rti; /* router info*/
+};
+
+#ifdef _KERNEL
+
+#ifdef SYSCTL_DECL
+SYSCTL_DECL(_net_inet_ip);
+SYSCTL_DECL(_net_inet_raw);
+#endif
+
+/*
+ * Structure used by macros below to remember position when stepping through
+ * all of the in_multi records.
+ */
+struct in_multistep {
+ struct in_ifaddr *i_ia;
+ struct in_multi *i_inm;
+};
+
+/*
+ * Macro for looking up the in_multi record for a given IP multicast address
+ * on a given interface. If no matching record is found, "inm" returns NULL.
+ */
+#define IN_LOOKUP_MULTI(addr, ifp, inm) \
+ /* struct in_addr addr; */ \
+ /* struct ifnet *ifp; */ \
+ /* struct in_multi *inm; */ \
+{ \
+ register struct in_ifaddr *ia; \
+\
+ IFP_TO_IA((ifp), ia); \
+ if (ia == NULL) \
+ (inm) = NULL; \
+ else \
+ for ((inm) = ia->ia_multiaddrs.lh_first; \
+ (inm) != NULL && (inm)->inm_addr.s_addr != (addr).s_addr; \
+ (inm) = inm->inm_entry.le_next) \
+ continue; \
+}
+
+/*
+ * Macro to step through all of the in_multi records, one at a time.
+ * The current position is remembered in "step", which the caller must
+ * provide. IN_FIRST_MULTI(), below, must be called to initialize "step"
+ * and get the first record. Both macros return a NULL "inm" when there
+ * are no remaining records.
+ */
+#define IN_NEXT_MULTI(step, inm) \
+ /* struct in_multistep step; */ \
+ /* struct in_multi *inm; */ \
+{ \
+ if (((inm) = (step).i_inm) != NULL) \
+ (step).i_inm = (inm)->inm_entry.le_next; \
+ else \
+ while ((step).i_ia != NULL) { \
+ (inm) = (step).i_ia->ia_multiaddrs.lh_first; \
+ (step).i_ia = (step).i_ia->ia_next; \
+ if ((inm) != NULL) { \
+ (step).i_inm = (inm)->inm_entry.le_next; \
+ break; \
+ } \
+ } \
+}
+
+#define IN_FIRST_MULTI(step, inm) \
+ /* struct in_multistep step; */ \
+ /* struct in_multi *inm; */ \
+{ \
+ (step).i_ia = in_ifaddr; \
+ (step).i_inm = NULL; \
+ IN_NEXT_MULTI((step), (inm)); \
+}
+
+struct in_multi *in_addmulti __P((struct in_addr *, struct ifnet *));
+void in_delmulti __P((struct in_multi *));
+int in_control __P((struct socket *, u_long, caddr_t, struct ifnet *));
+void in_rtqdrain __P((void));
+void ip_input __P((struct mbuf *));
+
+#endif /* _KERNEL */
+
+#endif /* _NETINET_IN_VAR_H_ */
diff --git a/cpukit/libnetworking/netinet/ip.h b/cpukit/libnetworking/netinet/ip.h
new file mode 100644
index 0000000000..e8e540a37d
--- /dev/null
+++ b/cpukit/libnetworking/netinet/ip.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ * 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.
+ *
+ * @(#)ip.h 8.2 (Berkeley) 6/1/94
+ * $FreeBSD: src/sys/netinet/ip.h,v 1.29 2005/01/07 01:45:44 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NETINET_IP_H_
+#define _NETINET_IP_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * Definitions for internet protocol version 4.
+ * Per RFC 791, September 1981.
+ */
+#define IPVERSION 4
+
+#ifndef __packed
+#if defined(__GNUC__)
+#define __packed __attribute__((packed))
+#else
+#define __packed
+#endif
+#endif
+
+/*
+ * Structure of an internet header, naked of options.
+ */
+struct ip {
+#ifdef _IP_VHL
+ u_char ip_vhl; /* version << 4 | header length >> 2 */
+#else
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int ip_hl:4, /* header length */
+ ip_v:4; /* version */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int ip_v:4, /* version */
+ ip_hl:4; /* header length */
+#endif
+#endif /* not _IP_VHL */
+ u_char ip_tos; /* type of service */
+ u_short ip_len; /* total length */
+ u_short ip_id; /* identification */
+ u_short ip_off; /* fragment offset field */
+#define IP_RF 0x8000 /* reserved fragment flag */
+#define IP_DF 0x4000 /* dont fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ u_char ip_ttl; /* time to live */
+ u_char ip_p; /* protocol */
+ u_short ip_sum; /* checksum */
+ struct in_addr ip_src,ip_dst; /* source and dest address */
+} __packed;
+
+#ifdef _IP_VHL
+#define IP_MAKE_VHL(v, hl) ((v) << 4 | (hl))
+#define IP_VHL_HL(vhl) ((vhl) & 0x0f)
+#define IP_VHL_V(vhl) ((vhl) >> 4)
+#define IP_VHL_BORING 0x45
+#endif
+
+#ifdef CTASSERT
+CTASSERT(sizeof (struct ip) == 20);
+#endif
+
+#define IP_MAXPACKET 65535 /* maximum packet size */
+
+/*
+ * Definitions for IP type of service (ip_tos)
+ */
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+#define IPTOS_MINCOST 0x02
+#if 1
+/* ECN RFC3168 obsoletes RFC2481, and these will be deprecated soon. */
+#define IPTOS_CE 0x01
+#define IPTOS_ECT 0x02
+#endif
+
+/*
+ * Definitions for IP precedence (also in ip_tos) (hopefully unused)
+ */
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_ROUTINE 0x00
+
+/*
+ * ECN (Explicit Congestion Notification) codepoints in RFC3168
+ * mapped to the lower 2 bits of the TOS field.
+ */
+#define IPTOS_ECN_NOTECT 0x00 /* not-ECT */
+#define IPTOS_ECN_ECT1 0x01 /* ECN-capable transport (1) */
+#define IPTOS_ECN_ECT0 0x02 /* ECN-capable transport (0) */
+#define IPTOS_ECN_CE 0x03 /* congestion experienced */
+#define IPTOS_ECN_MASK 0x03 /* ECN field mask */
+
+/*
+ * Definitions for options.
+ */
+#define IPOPT_COPIED(o) ((o)&0x80)
+#define IPOPT_CLASS(o) ((o)&0x60)
+#define IPOPT_NUMBER(o) ((o)&0x1f)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_DEBMEAS 0x40
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_EOL 0 /* end of option list */
+#define IPOPT_NOP 1 /* no operation */
+
+#define IPOPT_RR 7 /* record packet route */
+#define IPOPT_TS 68 /* timestamp */
+#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
+#define IPOPT_LSRR 131 /* loose source route */
+#define IPOPT_ESO 133 /* extended security */
+#define IPOPT_CIPSO 134 /* commerical security */
+#define IPOPT_SATID 136 /* satnet id */
+#define IPOPT_SSRR 137 /* strict source route */
+#define IPOPT_RA 148 /* router alert */
+
+/*
+ * Offsets to fields in options other than EOL and NOP.
+ */
+#define IPOPT_OPTVAL 0 /* option ID */
+#define IPOPT_OLEN 1 /* option length */
+#define IPOPT_OFFSET 2 /* offset within option */
+#define IPOPT_MINOFF 4 /* min value of above */
+
+/*
+ * Time stamp option structure.
+ */
+struct ip_timestamp {
+ u_char ipt_code; /* IPOPT_TS */
+ u_char ipt_len; /* size of structure (variable) */
+ u_char ipt_ptr; /* index of current entry */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int ipt_flg:4, /* flags, see below */
+ ipt_oflw:4; /* overflow counter */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int ipt_oflw:4, /* overflow counter */
+ ipt_flg:4; /* flags, see below */
+#endif
+ union ipt_timestamp {
+ n_long ipt_time[1];
+ struct ipt_ta {
+ struct in_addr ipt_addr;
+ n_long ipt_time;
+ } ipt_ta[1];
+ } ipt_timestamp;
+};
+
+#include <machine/in_cksum.h>
+
+/* flag bits for ipt_flg */
+#define IPOPT_TS_TSONLY 0 /* timestamps only */
+#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
+#define IPOPT_TS_PRESPEC 3 /* specified modules only */
+
+/* bits for security (not byte swapped) */
+#define IPOPT_SECUR_UNCLASS 0x0000
+#define IPOPT_SECUR_CONFID 0xf135
+#define IPOPT_SECUR_EFTO 0x789a
+#define IPOPT_SECUR_MMMM 0xbc4d
+#define IPOPT_SECUR_RESTR 0xaf13
+#define IPOPT_SECUR_SECRET 0xd788
+#define IPOPT_SECUR_TOPSECRET 0x6bc5
+
+/*
+ * Internet implementation parameters.
+ */
+#define MAXTTL 255 /* maximum time to live (seconds) */
+#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
+#define IPFRAGTTL 60 /* time to live for frags, slowhz */
+#define IPTTLDEC 1 /* subtracted when forwarding */
+
+#define IP_MSS 576 /* default maximum segment size */
+
+/*
+ * This is the real IPv4 pseudo header, used for computing the TCP and UDP
+ * checksums. For the Internet checksum, struct ipovly can be used instead.
+ * For stronger checksums, the real thing must be used.
+ */
+struct ippseudo {
+ struct in_addr ippseudo_src; /* source internet address */
+ struct in_addr ippseudo_dst; /* destination internet address */
+ u_char ippseudo_pad; /* pad, must be zero */
+ u_char ippseudo_p; /* protocol */
+ u_short ippseudo_len; /* protocol length */
+};
+#endif
diff --git a/cpukit/libnetworking/netinet/ip_divert.c b/cpukit/libnetworking/netinet/ip_divert.c
new file mode 100644
index 0000000000..c681f8dc10
--- /dev/null
+++ b/cpukit/libnetworking/netinet/ip_divert.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 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.
+ * 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.
+ *
+ * $FreeBSD: src/sys/netinet/ip_divert.c,v 1.113 2005/05/13 11:44:37 glebius Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+#include <sys/systm.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+
+/*
+ * Divert sockets
+ */
+
+/*
+ * Allocate enough space to hold a full IP packet
+ */
+#define DIVSNDQ (65536 + 100)
+#define DIVRCVQ (65536 + 100)
+
+/* Global variables */
+
+/*
+ * ip_input() and ip_output() set this secret value before calling us to
+ * let us know which divert port to divert a packet to; this is done so
+ * we can use the existing prototype for struct protosw's pr_input().
+ * This is stored in host order.
+ */
+u_short ip_divert_port;
+
+/*
+ * We set this value to a non-zero port number when we want the call to
+ * ip_fw_chk() in ip_input() or ip_output() to ignore ``divert <port>''
+ * chain entries. This is stored in host order.
+ */
+u_short ip_divert_ignore;
+
+/* Internal variables. */
+static struct inpcbhead divcb;
+static struct inpcbinfo divcbinfo;
+
+static u_long div_sendspace = DIVSNDQ; /* XXX sysctl ? */
+static u_long div_recvspace = DIVRCVQ; /* XXX sysctl ? */
+
+/* Optimization: have this preinitialized */
+static struct sockaddr_in divsrc = { sizeof(divsrc), AF_INET };
+
+/* Internal functions */
+
+static int div_output(struct socket *so,
+ struct mbuf *m, struct mbuf *addr, struct mbuf *control);
+
+/*
+ * Initialize divert connection block queue.
+ */
+void
+div_init(void)
+{
+ LIST_INIT(&divcb);
+ divcbinfo.listhead = &divcb;
+ /*
+ * XXX We don't use the hash list for divert IP, but it's easier
+ * to allocate a one entry hash list than it is to check all
+ * over the place for hashbase == NULL.
+ */
+ divcbinfo.hashbase = hashinit(1, M_PCB, &divcbinfo.hashmask);
+}
+
+/*
+ * Setup generic address and protocol structures
+ * for div_input routine, then pass them along with
+ * mbuf chain. ip->ip_len is assumed to have had
+ * the header length (hlen) subtracted out already.
+ * We tell whether the packet was incoming or outgoing
+ * by seeing if hlen == 0, which is a hack.
+ */
+void
+div_input(struct mbuf *m, int hlen)
+{
+ struct ip *ip;
+ struct inpcb *inp;
+ struct socket *sa;
+
+ /* Sanity check */
+ if (ip_divert_port == 0)
+ panic("div_input: port is 0");
+
+ /* Assure header */
+ if (m->m_len < sizeof(struct ip) &&
+ (m = m_pullup(m, sizeof(struct ip))) == 0) {
+ return;
+ }
+ ip = mtod(m, struct ip *);
+
+ /* Record divert port */
+ divsrc.sin_port = htons(ip_divert_port);
+
+ /* Restore packet header fields */
+ ip->ip_len += hlen;
+ HTONS(ip->ip_len);
+ HTONS(ip->ip_off);
+
+ /* Record receive interface address, if any */
+ divsrc.sin_addr.s_addr = 0;
+ if (hlen) {
+ struct ifaddr *ifa;
+
+#ifdef DIAGNOSTIC
+ /* Sanity check */
+ if (!(m->m_flags & M_PKTHDR))
+ panic("div_input: no pkt hdr");
+#endif
+
+ /* More fields affected by ip_input() */
+ HTONS(ip->ip_id);
+
+ /* Find IP address for recieve interface */
+ for (ifa = m->m_pkthdr.rcvif->if_addrlist;
+ ifa != NULL; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr == NULL)
+ continue;
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+ divsrc.sin_addr =
+ ((struct sockaddr_in *) ifa->ifa_addr)->sin_addr;
+ break;
+ }
+ }
+
+ /* Put packet on socket queue, if any */
+ sa = NULL;
+ for (inp = divcb.lh_first; inp != NULL; inp = inp->inp_list.le_next) {
+ if (inp->inp_lport == htons(ip_divert_port))
+ sa = inp->inp_socket;
+ }
+ if (sa) {
+ if (sbappendaddr(&sa->so_rcv, (struct sockaddr *)&divsrc,
+ m, (struct mbuf *)0) == 0)
+ m_freem(m);
+ else
+ sorwakeup(sa);
+ } else {
+ m_freem(m);
+ ipstat.ips_noproto++;
+ ipstat.ips_delivered--;
+ }
+}
+
+/*
+ * Deliver packet back into the IP processing machinery.
+ *
+ * If no address specified, or address is 0.0.0.0, send to ip_output();
+ * otherwise, send to ip_input() and mark as having been received on
+ * the interface with that address.
+ *
+ * If no address specified, or dest port is 0, allow packet to divert
+ * back to this socket; otherwise, don't.
+ */
+static int
+div_output(struct socket *so, struct mbuf *m,
+ struct mbuf *addr, struct mbuf *control)
+{
+ register struct inpcb *const inp = sotoinpcb(so);
+ register struct ip *const ip = mtod(m, struct ip *);
+ struct sockaddr_in *sin = NULL;
+ int error = 0;
+
+ if (control)
+ m_freem(control); /* XXX */
+ if (addr)
+ sin = mtod(addr, struct sockaddr_in *);
+
+ /* Loopback avoidance option */
+ ip_divert_ignore = ntohs(inp->inp_lport);
+
+ /* Reinject packet into the system as incoming or outgoing */
+ if (!sin || sin->sin_addr.s_addr == 0) {
+ /* Don't allow both user specified and setsockopt options,
+ and don't allow packet length sizes that will crash */
+ if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options) ||
+ ((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) {
+ error = EINVAL;
+ goto cantsend;
+ }
+
+ /* Convert fields to host order for ip_output() */
+ NTOHS(ip->ip_len);
+ NTOHS(ip->ip_off);
+
+ /* Send packet to output processing */
+ ipstat.ips_rawout++; /* XXX */
+ error = ip_output(m, inp->inp_options, &inp->inp_route,
+ (so->so_options & SO_DONTROUTE) |
+ IP_ALLOWBROADCAST | IP_RAWOUTPUT, inp->inp_moptions);
+ } else {
+ struct ifaddr *ifa;
+
+ /* Find receive interface with the given IP address */
+ sin->sin_port = 0;
+ if ((ifa = ifa_ifwithaddr((struct sockaddr *) sin)) == 0) {
+ error = EADDRNOTAVAIL;
+ goto cantsend;
+ }
+ m->m_pkthdr.rcvif = ifa->ifa_ifp;
+
+ /* Send packet to input processing */
+ ip_input(m);
+ }
+
+ /* Reset for next time (and other packets) */
+ ip_divert_ignore = 0;
+ return error;
+
+cantsend:
+ ip_divert_ignore = 0;
+ m_freem(m);
+ return error;
+}
+
+/*ARGSUSED*/
+int
+div_usrreq(so, req, m, nam, control)
+ register struct socket *so;
+ int req;
+ struct mbuf *m, *nam, *control;
+{
+ register int error = 0;
+ register struct inpcb *inp = sotoinpcb(so);
+ int s;
+
+ if (inp == NULL && req != PRU_ATTACH) {
+ error = EINVAL;
+ goto release;
+ }
+ switch (req) {
+
+ case PRU_ATTACH:
+ if (inp)
+ panic("div_attach");
+ if ((so->so_state & SS_PRIV) == 0) {
+ error = EACCES;
+ break;
+ }
+ s = splnet();
+ error = in_pcballoc(so, &divcbinfo);
+ splx(s);
+ if (error)
+ break;
+ error = soreserve(so, div_sendspace, div_recvspace);
+ if (error)
+ break;
+ inp = (struct inpcb *)so->so_pcb;
+ inp->inp_ip_p = (int)nam; /* XXX */
+ inp->inp_flags |= INP_HDRINCL;
+ /* The socket is always "connected" because
+ we always know "where" to send the packet */
+ so->so_state |= SS_ISCONNECTED;
+ break;
+
+ case PRU_DISCONNECT:
+ if ((so->so_state & SS_ISCONNECTED) == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ /* FALLTHROUGH */
+ case PRU_ABORT:
+ soisdisconnected(so);
+ /* FALLTHROUGH */
+ case PRU_DETACH:
+ if (inp == 0)
+ panic("div_detach");
+ in_pcbdetach(inp);
+ break;
+
+ case PRU_BIND:
+ s = splnet();
+ error = in_pcbbind(inp, nam);
+ splx(s);
+ break;
+
+ /*
+ * Mark the connection as being incapable of further input.
+ */
+ case PRU_SHUTDOWN:
+ socantsendmore(so);
+ break;
+
+ case PRU_SEND:
+ /* Packet must have a header (but that's about it) */
+ if (m->m_len < sizeof (struct ip) ||
+ (m = m_pullup(m, sizeof (struct ip))) == 0) {
+ ipstat.ips_toosmall++;
+ error = EINVAL;
+ break;
+ }
+
+ /* Send packet */
+ error = div_output(so, m, nam, control);
+ m = NULL;
+ break;
+
+ case PRU_SOCKADDR:
+ in_setsockaddr(inp, nam);
+ break;
+
+ case PRU_SENSE:
+ /*
+ * stat: don't bother with a blocksize.
+ */
+ return (0);
+
+ /*
+ * Not supported.
+ */
+ case PRU_CONNECT:
+ case PRU_CONNECT2:
+ case PRU_CONTROL:
+ case PRU_RCVOOB:
+ case PRU_RCVD:
+ case PRU_LISTEN:
+ case PRU_ACCEPT:
+ case PRU_SENDOOB:
+ case PRU_PEERADDR:
+ error = EOPNOTSUPP;
+ break;
+
+ default:
+ panic("div_usrreq");
+ }
+release:
+ if (m)
+ m_freem(m);
+ return (error);
+}
diff --git a/cpukit/libnetworking/netinet/ip_fw.c b/cpukit/libnetworking/netinet/ip_fw.c
new file mode 100644
index 0000000000..4bad293e7d
--- /dev/null
+++ b/cpukit/libnetworking/netinet/ip_fw.c
@@ -0,0 +1,1074 @@
+/*
+ * Copyright (c) 1996 Alex Nash
+ * Copyright (c) 1993 Daniel Boulet
+ * Copyright (c) 1994 Ugen J.S.Antsilevich
+ *
+ * Redistribution and use in source forms, with and without modification,
+ * are permitted provided that this entire comment appears intact.
+ *
+ * Redistribution in binary form may occur without any restrictions.
+ * Obviously, it would be nice if you gave credit where credit is due
+ * but requiring it would be too onerous.
+ *
+ * This software is provided ``AS IS'' without any warranties of any kind.
+ *
+ * $Id$
+ */
+
+/*
+ * Implement IP packet firewall
+ */
+
+#ifndef IPFIREWALL_MODULE
+#include "opt_ipfw.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/queue.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/sysctl.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_fw.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#include <netinet/udp.h>
+
+static int fw_debug = 1;
+#ifdef IPFIREWALL_VERBOSE
+static int fw_verbose = 1;
+#else
+static int fw_verbose = 0;
+#endif
+#ifdef IPFIREWALL_VERBOSE_LIMIT
+static int fw_verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
+#else
+static int fw_verbose_limit = 0;
+#endif
+
+LIST_HEAD (ip_fw_head, ip_fw_chain) ip_fw_chain;
+
+/*
+ * ccj - No current need for firewall so have provided the MIB.
+ */
+#if 0
+#ifdef SYSCTL_NODE
+SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
+SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, debug, CTLFLAG_RW, &fw_debug, 0, "");
+SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose, CTLFLAG_RW, &fw_verbose, 0, "");
+SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, CTLFLAG_RW, &fw_verbose_limit, 0, "");
+#endif
+#endif
+
+#define dprintf(a) if (!fw_debug); else printf a
+
+#define print_ip(a) printf("%ld.%ld.%ld.%ld",(ntohl(a.s_addr)>>24)&0xFF,\
+ (ntohl(a.s_addr)>>16)&0xFF,\
+ (ntohl(a.s_addr)>>8)&0xFF,\
+ (ntohl(a.s_addr))&0xFF);
+
+#define dprint_ip(a) if (!fw_debug); else print_ip(a)
+
+static int add_entry __P((struct ip_fw_head *chainptr, struct ip_fw *frwl));
+static int del_entry __P((struct ip_fw_head *chainptr, u_short number));
+static int zero_entry __P((struct mbuf *m));
+static struct ip_fw *check_ipfw_struct __P((struct ip_fw *m));
+static struct ip_fw *check_ipfw_mbuf __P((struct mbuf *fw));
+static int ipopts_match __P((struct ip *ip, struct ip_fw *f));
+static int port_match __P((u_short *portptr, int nports, u_short port,
+ int range_flag));
+static int tcpflg_match __P((struct tcphdr *tcp, struct ip_fw *f));
+static int icmptype_match __P((struct icmp * icmp, struct ip_fw * f));
+static void ipfw_report __P((struct ip_fw *f, struct ip *ip,
+ struct ifnet *rif, struct ifnet *oif));
+
+#ifdef IPFIREWALL_MODULE
+static ip_fw_chk_t *old_chk_ptr;
+static ip_fw_ctl_t *old_ctl_ptr;
+#endif
+
+static int ip_fw_chk __P((struct ip **pip, int hlen,
+ struct ifnet *oif, int ignport, struct mbuf **m));
+static int ip_fw_ctl __P((int stage, struct mbuf **mm));
+
+static char err_prefix[] = "ip_fw_ctl:";
+
+/*
+ * Returns 1 if the port is matched by the vector, 0 otherwise
+ */
+static inline int
+port_match(u_short *portptr, int nports, u_short port, int range_flag)
+{
+ if (!nports)
+ return 1;
+ if (range_flag) {
+ if (portptr[0] <= port && port <= portptr[1]) {
+ return 1;
+ }
+ nports -= 2;
+ portptr += 2;
+ }
+ while (nports-- > 0) {
+ if (*portptr++ == port) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int
+tcpflg_match(struct tcphdr *tcp, struct ip_fw *f)
+{
+ u_char flg_set, flg_clr;
+
+ if ((f->fw_tcpf & IP_FW_TCPF_ESTAB) &&
+ (tcp->th_flags & (IP_FW_TCPF_RST | IP_FW_TCPF_ACK)))
+ return 1;
+
+ flg_set = tcp->th_flags & f->fw_tcpf;
+ flg_clr = tcp->th_flags & f->fw_tcpnf;
+
+ if (flg_set != f->fw_tcpf)
+ return 0;
+ if (flg_clr)
+ return 0;
+
+ return 1;
+}
+
+static int
+icmptype_match(struct icmp *icmp, struct ip_fw *f)
+{
+ int type;
+
+ if (!(f->fw_flg & IP_FW_F_ICMPBIT))
+ return(1);
+
+ type = icmp->icmp_type;
+
+ /* check for matching type in the bitmap */
+ if (type < IP_FW_ICMPTYPES_DIM * sizeof(unsigned) * 8 &&
+ (f->fw_icmptypes[type / (sizeof(unsigned) * 8)] &
+ (1U << (type % (8 * sizeof(unsigned))))))
+ return(1);
+
+ return(0); /* no match */
+}
+
+static int
+ipopts_match(struct ip *ip, struct ip_fw *f)
+{
+ register u_char *cp;
+ int opt, optlen, cnt;
+ u_char opts, nopts, nopts_sve;
+
+ cp = (u_char *)(ip + 1);
+ cnt = (ip->ip_hl << 2) - sizeof (struct ip);
+ opts = f->fw_ipopt;
+ nopts = nopts_sve = f->fw_ipnopt;
+
+ for (; cnt > 0; cnt -= optlen, cp += optlen) {
+ opt = cp[IPOPT_OPTVAL];
+ if (opt == IPOPT_EOL)
+ break;
+ if (opt == IPOPT_NOP)
+ optlen = 1;
+ else {
+ optlen = cp[IPOPT_OLEN];
+ if (optlen <= 0 || optlen > cnt) {
+ return 0; /*XXX*/
+ }
+ }
+ switch (opt) {
+
+ default:
+ break;
+
+ case IPOPT_LSRR:
+ opts &= ~IP_FW_IPOPT_LSRR;
+ nopts &= ~IP_FW_IPOPT_LSRR;
+ break;
+
+ case IPOPT_SSRR:
+ opts &= ~IP_FW_IPOPT_SSRR;
+ nopts &= ~IP_FW_IPOPT_SSRR;
+ break;
+
+ case IPOPT_RR:
+ opts &= ~IP_FW_IPOPT_RR;
+ nopts &= ~IP_FW_IPOPT_RR;
+ break;
+ case IPOPT_TS:
+ opts &= ~IP_FW_IPOPT_TS;
+ nopts &= ~IP_FW_IPOPT_TS;
+ break;
+ }
+ if (opts == nopts)
+ break;
+ }
+ if (opts == 0 && nopts == nopts_sve)
+ return 1;
+ else
+ return 0;
+}
+
+static inline int
+iface_match(struct ifnet *ifp, union ip_fw_if *ifu, int byname)
+{
+ /* Check by name or by IP address */
+ if (byname) {
+ /* Check unit number (-1 is wildcard) */
+ if (ifu->fu_via_if.unit != -1
+ && ifp->if_unit != ifu->fu_via_if.unit)
+ return(0);
+ /* Check name */
+ if (strncmp(ifp->if_name, ifu->fu_via_if.name, FW_IFNLEN))
+ return(0);
+ return(1);
+ } else if (ifu->fu_via_ip.s_addr != 0) { /* Zero == wildcard */
+ struct ifaddr *ia;
+
+ for (ia = ifp->if_addrlist; ia; ia = ia->ifa_next) {
+ if (ia->ifa_addr == NULL)
+ continue;
+ if (ia->ifa_addr->sa_family != AF_INET)
+ continue;
+ if (ifu->fu_via_ip.s_addr != ((struct sockaddr_in *)
+ (ia->ifa_addr))->sin_addr.s_addr)
+ continue;
+ return(1);
+ }
+ return(0);
+ }
+ return(1);
+}
+
+static void
+ipfw_report(struct ip_fw *f, struct ip *ip,
+ struct ifnet *rif, struct ifnet *oif)
+{
+ static int counter;
+ struct tcphdr *const tcp = (struct tcphdr *) ((u_long *) ip+ ip->ip_hl);
+ struct udphdr *const udp = (struct udphdr *) ((u_long *) ip+ ip->ip_hl);
+ struct icmp *const icmp = (struct icmp *) ((u_long *) ip + ip->ip_hl);
+ int count;
+
+ count = f ? f->fw_pcnt : ++counter;
+ if (fw_verbose_limit != 0 && count > fw_verbose_limit)
+ return;
+
+ /* Print command name */
+ printf("ipfw: %d ", f ? f->fw_number : -1);
+ if (!f)
+ printf("Refuse");
+ else
+ switch (f->fw_flg & IP_FW_F_COMMAND) {
+ case IP_FW_F_DENY:
+ printf("Deny");
+ break;
+ case IP_FW_F_REJECT:
+ if (f->fw_reject_code == IP_FW_REJECT_RST)
+ printf("Reset");
+ else
+ printf("Unreach");
+ break;
+ case IP_FW_F_ACCEPT:
+ printf("Accept");
+ break;
+ case IP_FW_F_COUNT:
+ printf("Count");
+ break;
+ case IP_FW_F_DIVERT:
+ printf("Divert %d", f->fw_divert_port);
+ break;
+ case IP_FW_F_TEE:
+ printf("Tee %d", f->fw_divert_port);
+ break;
+ case IP_FW_F_SKIPTO:
+ printf("SkipTo %d", f->fw_skipto_rule);
+ break;
+ default:
+ printf("UNKNOWN");
+ break;
+ }
+ printf(" ");
+
+ switch (ip->ip_p) {
+ case IPPROTO_TCP:
+ printf("TCP ");
+ print_ip(ip->ip_src);
+ if ((ip->ip_off & IP_OFFMASK) == 0)
+ printf(":%d ", ntohs(tcp->th_sport));
+ else
+ printf(" ");
+ print_ip(ip->ip_dst);
+ if ((ip->ip_off & IP_OFFMASK) == 0)
+ printf(":%d", ntohs(tcp->th_dport));
+ break;
+ case IPPROTO_UDP:
+ printf("UDP ");
+ print_ip(ip->ip_src);
+ if ((ip->ip_off & IP_OFFMASK) == 0)
+ printf(":%d ", ntohs(udp->uh_sport));
+ else
+ printf(" ");
+ print_ip(ip->ip_dst);
+ if ((ip->ip_off & IP_OFFMASK) == 0)
+ printf(":%d", ntohs(udp->uh_dport));
+ break;
+ case IPPROTO_ICMP:
+ printf("ICMP:%u.%u ", icmp->icmp_type, icmp->icmp_code);
+ print_ip(ip->ip_src);
+ printf(" ");
+ print_ip(ip->ip_dst);
+ break;
+ default:
+ printf("P:%d ", ip->ip_p);
+ print_ip(ip->ip_src);
+ printf(" ");
+ print_ip(ip->ip_dst);
+ break;
+ }
+ if (oif)
+ printf(" out via %s%d", oif->if_name, oif->if_unit);
+ else if (rif)
+ printf(" in via %s%d", rif->if_name, rif->if_unit);
+ if ((ip->ip_off & IP_OFFMASK))
+ printf(" Fragment = %d",ip->ip_off & IP_OFFMASK);
+ printf("\n");
+ if (fw_verbose_limit != 0 && count == fw_verbose_limit)
+ printf("ipfw: limit reached on rule #%d\n",
+ f ? f->fw_number : -1);
+}
+
+/*
+ * Parameters:
+ *
+ * ip Pointer to packet header (struct ip *)
+ * hlen Packet header length
+ * oif Outgoing interface, or NULL if packet is incoming
+ * ignport Ignore all divert/tee rules to this port (if non-zero)
+ * *m The packet; we set to NULL when/if we nuke it.
+ *
+ * Return value:
+ *
+ * 0 The packet is to be accepted and routed normally OR
+ * the packet was denied/rejected and has been dropped;
+ * in the latter case, *m is equal to NULL upon return.
+ * port Divert the packet to port.
+ */
+
+static int
+ip_fw_chk(struct ip **pip, int hlen,
+ struct ifnet *oif, int ignport, struct mbuf **m)
+{
+ struct ip_fw_chain *chain;
+ struct ip_fw *rule = NULL;
+ struct ip *ip = *pip;
+ struct ifnet *const rif = (*m)->m_pkthdr.rcvif;
+ u_short offset = (ip->ip_off & IP_OFFMASK);
+ u_short src_port, dst_port;
+
+ /*
+ * Go down the chain, looking for enlightment
+ */
+ for (chain=ip_fw_chain.lh_first; chain; chain = chain->chain.le_next) {
+ register struct ip_fw *const f = chain->rule;
+
+ /* Check direction inbound */
+ if (!oif && !(f->fw_flg & IP_FW_F_IN))
+ continue;
+
+ /* Check direction outbound */
+ if (oif && !(f->fw_flg & IP_FW_F_OUT))
+ continue;
+
+ /* Fragments */
+ if ((f->fw_flg & IP_FW_F_FRAG) && !(ip->ip_off & IP_OFFMASK))
+ continue;
+
+ /* If src-addr doesn't match, not this rule. */
+ if (((f->fw_flg & IP_FW_F_INVSRC) != 0) ^ ((ip->ip_src.s_addr
+ & f->fw_smsk.s_addr) != f->fw_src.s_addr))
+ continue;
+
+ /* If dest-addr doesn't match, not this rule. */
+ if (((f->fw_flg & IP_FW_F_INVDST) != 0) ^ ((ip->ip_dst.s_addr
+ & f->fw_dmsk.s_addr) != f->fw_dst.s_addr))
+ continue;
+
+ /* Interface check */
+ if ((f->fw_flg & IF_FW_F_VIAHACK) == IF_FW_F_VIAHACK) {
+ struct ifnet *const iface = oif ? oif : rif;
+
+ /* Backwards compatibility hack for "via" */
+ if (!iface || !iface_match(iface,
+ &f->fw_in_if, f->fw_flg & IP_FW_F_OIFNAME))
+ continue;
+ } else {
+ /* Check receive interface */
+ if ((f->fw_flg & IP_FW_F_IIFACE)
+ && (!rif || !iface_match(rif,
+ &f->fw_in_if, f->fw_flg & IP_FW_F_IIFNAME)))
+ continue;
+ /* Check outgoing interface */
+ if ((f->fw_flg & IP_FW_F_OIFACE)
+ && (!oif || !iface_match(oif,
+ &f->fw_out_if, f->fw_flg & IP_FW_F_OIFNAME)))
+ continue;
+ }
+
+ /* Check IP options */
+ if (f->fw_ipopt != f->fw_ipnopt && !ipopts_match(ip, f))
+ continue;
+
+ /* Check protocol; if wildcard, match */
+ if (f->fw_prot == IPPROTO_IP)
+ goto got_match;
+
+ /* If different, don't match */
+ if (ip->ip_p != f->fw_prot)
+ continue;
+
+#define PULLUP_TO(len) do { \
+ if ((*m)->m_len < (len) \
+ && (*m = m_pullup(*m, (len))) == 0) { \
+ goto bogusfrag; \
+ } \
+ *pip = ip = mtod(*m, struct ip *); \
+ offset = (ip->ip_off & IP_OFFMASK); \
+ } while (0)
+
+ /* Protocol specific checks */
+ switch (ip->ip_p) {
+ case IPPROTO_TCP:
+ {
+ struct tcphdr *tcp;
+
+ if (offset == 1) /* cf. RFC 1858 */
+ goto bogusfrag;
+ if (offset != 0) {
+ /*
+ * TCP flags and ports aren't available in this
+ * packet -- if this rule specified either one,
+ * we consider the rule a non-match.
+ */
+ if (f->fw_nports != 0 ||
+ f->fw_tcpf != f->fw_tcpnf)
+ continue;
+
+ break;
+ }
+ PULLUP_TO(hlen + 14);
+ tcp = (struct tcphdr *) ((u_long *)ip + ip->ip_hl);
+ if (f->fw_tcpf != f->fw_tcpnf && !tcpflg_match(tcp, f))
+ continue;
+ src_port = ntohs(tcp->th_sport);
+ dst_port = ntohs(tcp->th_dport);
+ goto check_ports;
+ }
+
+ case IPPROTO_UDP:
+ {
+ struct udphdr *udp;
+
+ if (offset != 0) {
+ /*
+ * Port specification is unavailable -- if this
+ * rule specifies a port, we consider the rule
+ * a non-match.
+ */
+ if (f->fw_nports != 0)
+ continue;
+
+ break;
+ }
+ PULLUP_TO(hlen + 4);
+ udp = (struct udphdr *) ((u_long *)ip + ip->ip_hl);
+ src_port = ntohs(udp->uh_sport);
+ dst_port = ntohs(udp->uh_dport);
+check_ports:
+ if (!port_match(&f->fw_pts[0],
+ IP_FW_GETNSRCP(f), src_port,
+ f->fw_flg & IP_FW_F_SRNG))
+ continue;
+ if (!port_match(&f->fw_pts[IP_FW_GETNSRCP(f)],
+ IP_FW_GETNDSTP(f), dst_port,
+ f->fw_flg & IP_FW_F_DRNG))
+ continue;
+ break;
+ }
+
+ case IPPROTO_ICMP:
+ {
+ struct icmp *icmp;
+
+ if (offset != 0) /* Type isn't valid */
+ break;
+ PULLUP_TO(hlen + 2);
+ icmp = (struct icmp *) ((u_long *)ip + ip->ip_hl);
+ if (!icmptype_match(icmp, f))
+ continue;
+ break;
+ }
+#undef PULLUP_TO
+
+bogusfrag:
+ if (fw_verbose)
+ ipfw_report(NULL, ip, rif, oif);
+ goto dropit;
+ }
+
+got_match:
+ /* Ignore divert/tee rule if socket port is "ignport" */
+ switch (f->fw_flg & IP_FW_F_COMMAND) {
+ case IP_FW_F_DIVERT:
+ case IP_FW_F_TEE:
+ if (f->fw_divert_port == ignport)
+ continue; /* ignore this rule */
+ break;
+ }
+
+ /* Update statistics */
+ f->fw_pcnt += 1;
+ f->fw_bcnt += ip->ip_len;
+ f->timestamp = rtems_bsdnet_seconds_since_boot();
+
+ /* Log to console if desired */
+ if ((f->fw_flg & IP_FW_F_PRN) && fw_verbose)
+ ipfw_report(f, ip, rif, oif);
+
+ /* Take appropriate action */
+ switch (f->fw_flg & IP_FW_F_COMMAND) {
+ case IP_FW_F_ACCEPT:
+ return(0);
+ case IP_FW_F_COUNT:
+ continue;
+ case IP_FW_F_DIVERT:
+ return(f->fw_divert_port);
+ case IP_FW_F_TEE:
+ /*
+ * XXX someday tee packet here, but beware that you
+ * can't use m_copym() or m_copypacket() because
+ * the divert input routine modifies the mbuf
+ * (and these routines only increment reference
+ * counts in the case of mbuf clusters), so need
+ * to write custom routine.
+ */
+ continue;
+ case IP_FW_F_SKIPTO:
+#ifdef DIAGNOSTIC
+ while (chain->chain.le_next
+ && chain->chain.le_next->rule->fw_number
+ < f->fw_skipto_rule)
+#else
+ while (chain->chain.le_next->rule->fw_number
+ < f->fw_skipto_rule)
+#endif
+ chain = chain->chain.le_next;
+ continue;
+ }
+
+ /* Deny/reject this packet using this rule */
+ rule = f;
+ break;
+ }
+
+#ifdef DIAGNOSTIC
+ /* Rule 65535 should always be there and should always match */
+ if (!chain)
+ panic("ip_fw: chain");
+#endif
+
+ /*
+ * At this point, we're going to drop the packet.
+ * Send a reject notice if all of the following are true:
+ *
+ * - The packet matched a reject rule
+ * - The packet is not an ICMP packet
+ * - The packet is not a multicast or broadcast packet
+ */
+ if ((rule->fw_flg & IP_FW_F_COMMAND) == IP_FW_F_REJECT
+ && ip->ip_p != IPPROTO_ICMP
+ && !((*m)->m_flags & (M_BCAST|M_MCAST))
+ && !IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
+ switch (rule->fw_reject_code) {
+ case IP_FW_REJECT_RST:
+ {
+ struct tcphdr *const tcp =
+ (struct tcphdr *) ((u_long *)ip + ip->ip_hl);
+ struct tcpiphdr ti, *const tip = (struct tcpiphdr *) ip;
+
+ if (offset != 0 || (tcp->th_flags & TH_RST))
+ break;
+ ti.ti_i = *((struct ipovly *) ip);
+ ti.ti_t = *tcp;
+ bcopy(&ti, ip, sizeof(ti));
+ NTOHL(tip->ti_seq);
+ NTOHL(tip->ti_ack);
+ tip->ti_len = ip->ip_len - hlen - (tip->ti_off << 2);
+ if (tcp->th_flags & TH_ACK) {
+ tcp_respond(NULL, tip, *m,
+ (tcp_seq)0, ntohl(tcp->th_ack), TH_RST);
+ } else {
+ if (tcp->th_flags & TH_SYN)
+ tip->ti_len++;
+ tcp_respond(NULL, tip, *m, tip->ti_seq
+ + tip->ti_len, (tcp_seq)0, TH_RST|TH_ACK);
+ }
+ *m = NULL;
+ break;
+ }
+ default: /* Send an ICMP unreachable using code */
+ icmp_error(*m, ICMP_UNREACH,
+ rule->fw_reject_code, 0L, 0);
+ *m = NULL;
+ break;
+ }
+ }
+
+dropit:
+ /*
+ * Finally, drop the packet.
+ */
+ if (*m) {
+ m_freem(*m);
+ *m = NULL;
+ }
+ return(0);
+}
+
+static int
+add_entry(struct ip_fw_head *chainptr, struct ip_fw *frwl)
+{
+ struct ip_fw *ftmp = 0;
+ struct ip_fw_chain *fwc = 0, *fcp, *fcpl = 0;
+ u_short nbr = 0;
+ int s;
+
+ fwc = malloc(sizeof *fwc, M_IPFW, M_DONTWAIT);
+ ftmp = malloc(sizeof *ftmp, M_IPFW, M_DONTWAIT);
+ if (!fwc || !ftmp) {
+ dprintf(("%s malloc said no\n", err_prefix));
+ if (fwc) free(fwc, M_IPFW);
+ if (ftmp) free(ftmp, M_IPFW);
+ return (ENOSPC);
+ }
+
+ bcopy(frwl, ftmp, sizeof(struct ip_fw));
+ ftmp->fw_in_if.fu_via_if.name[FW_IFNLEN - 1] = '\0';
+ ftmp->fw_pcnt = 0L;
+ ftmp->fw_bcnt = 0L;
+ fwc->rule = ftmp;
+
+ s = splnet();
+
+ if (!chainptr->lh_first) {
+ LIST_INSERT_HEAD(chainptr, fwc, chain);
+ splx(s);
+ return(0);
+ } else if (ftmp->fw_number == (u_short)-1) {
+ if (fwc) free(fwc, M_IPFW);
+ if (ftmp) free(ftmp, M_IPFW);
+ splx(s);
+ dprintf(("%s bad rule number\n", err_prefix));
+ return (EINVAL);
+ }
+
+ /* If entry number is 0, find highest numbered rule and add 100 */
+ if (ftmp->fw_number == 0) {
+ for (fcp = chainptr->lh_first; fcp; fcp = fcp->chain.le_next) {
+ if (fcp->rule->fw_number != (u_short)-1)
+ nbr = fcp->rule->fw_number;
+ else
+ break;
+ }
+ if (nbr < (u_short)-1 - 100)
+ nbr += 100;
+ ftmp->fw_number = nbr;
+ }
+
+ /* Got a valid number; now insert it, keeping the list ordered */
+ for (fcp = chainptr->lh_first; fcp; fcp = fcp->chain.le_next) {
+ if (fcp->rule->fw_number > ftmp->fw_number) {
+ if (fcpl) {
+ LIST_INSERT_AFTER(fcpl, fwc, chain);
+ } else {
+ LIST_INSERT_HEAD(chainptr, fwc, chain);
+ }
+ break;
+ } else {
+ fcpl = fcp;
+ }
+ }
+
+ splx(s);
+ return (0);
+}
+
+static int
+del_entry(struct ip_fw_head *chainptr, u_short number)
+{
+ struct ip_fw_chain *fcp;
+ int s;
+
+ s = splnet();
+
+ fcp = chainptr->lh_first;
+ if (number != (u_short)-1) {
+ for (; fcp; fcp = fcp->chain.le_next) {
+ if (fcp->rule->fw_number == number) {
+ LIST_REMOVE(fcp, chain);
+ splx(s);
+ free(fcp->rule, M_IPFW);
+ free(fcp, M_IPFW);
+ return 0;
+ }
+ }
+ }
+
+ splx(s);
+ return (EINVAL);
+}
+
+static int
+zero_entry(struct mbuf *m)
+{
+ struct ip_fw *frwl;
+ struct ip_fw_chain *fcp;
+ int s;
+
+ if (m) {
+ if (m->m_len != sizeof(struct ip_fw))
+ return(EINVAL);
+ frwl = mtod(m, struct ip_fw *);
+ }
+ else
+ frwl = NULL;
+
+ /*
+ * It's possible to insert multiple chain entries with the
+ * same number, so we don't stop after finding the first
+ * match if zeroing a specific entry.
+ */
+ s = splnet();
+ for (fcp = ip_fw_chain.lh_first; fcp; fcp = fcp->chain.le_next)
+ if (!frwl || frwl->fw_number == fcp->rule->fw_number) {
+ fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;
+ fcp->rule->timestamp = 0;
+ }
+ splx(s);
+
+ if (fw_verbose) {
+ if (frwl)
+ printf("ipfw: Entry %d cleared.\n", frwl->fw_number);
+ else
+ printf("ipfw: Accounting cleared.\n");
+ }
+
+ return(0);
+}
+
+static struct ip_fw *
+check_ipfw_mbuf(struct mbuf *m)
+{
+ /* Check length */
+ if (m->m_len != sizeof(struct ip_fw)) {
+ dprintf(("%s len=%d, want %d\n", err_prefix, m->m_len,
+ (int)sizeof(struct ip_fw)));
+ return (NULL);
+ }
+ return(check_ipfw_struct(mtod(m, struct ip_fw *)));
+}
+
+static struct ip_fw *
+check_ipfw_struct(struct ip_fw *frwl)
+{
+ /* Check for invalid flag bits */
+ if ((frwl->fw_flg & ~IP_FW_F_MASK) != 0) {
+ dprintf(("%s undefined flag bits set (flags=%x)\n",
+ err_prefix, frwl->fw_flg));
+ return (NULL);
+ }
+ /* Must apply to incoming or outgoing (or both) */
+ if (!(frwl->fw_flg & (IP_FW_F_IN | IP_FW_F_OUT))) {
+ dprintf(("%s neither in nor out\n", err_prefix));
+ return (NULL);
+ }
+ /* Empty interface name is no good */
+ if (((frwl->fw_flg & IP_FW_F_IIFNAME)
+ && !*frwl->fw_in_if.fu_via_if.name)
+ || ((frwl->fw_flg & IP_FW_F_OIFNAME)
+ && !*frwl->fw_out_if.fu_via_if.name)) {
+ dprintf(("%s empty interface name\n", err_prefix));
+ return (NULL);
+ }
+ /* Sanity check interface matching */
+ if ((frwl->fw_flg & IF_FW_F_VIAHACK) == IF_FW_F_VIAHACK) {
+ ; /* allow "via" backwards compatibility */
+ } else if ((frwl->fw_flg & IP_FW_F_IN)
+ && (frwl->fw_flg & IP_FW_F_OIFACE)) {
+ dprintf(("%s outgoing interface check on incoming\n",
+ err_prefix));
+ return (NULL);
+ }
+ /* Sanity check port ranges */
+ if ((frwl->fw_flg & IP_FW_F_SRNG) && IP_FW_GETNSRCP(frwl) < 2) {
+ dprintf(("%s src range set but n_src_p=%d\n",
+ err_prefix, IP_FW_GETNSRCP(frwl)));
+ return (NULL);
+ }
+ if ((frwl->fw_flg & IP_FW_F_DRNG) && IP_FW_GETNDSTP(frwl) < 2) {
+ dprintf(("%s dst range set but n_dst_p=%d\n",
+ err_prefix, IP_FW_GETNDSTP(frwl)));
+ return (NULL);
+ }
+ if (IP_FW_GETNSRCP(frwl) + IP_FW_GETNDSTP(frwl) > IP_FW_MAX_PORTS) {
+ dprintf(("%s too many ports (%d+%d)\n",
+ err_prefix, IP_FW_GETNSRCP(frwl), IP_FW_GETNDSTP(frwl)));
+ return (NULL);
+ }
+ /*
+ * Protocols other than TCP/UDP don't use port range
+ */
+ if ((frwl->fw_prot != IPPROTO_TCP) &&
+ (frwl->fw_prot != IPPROTO_UDP) &&
+ (IP_FW_GETNSRCP(frwl) || IP_FW_GETNDSTP(frwl))) {
+ dprintf(("%s port(s) specified for non TCP/UDP rule\n",
+ err_prefix));
+ return(NULL);
+ }
+
+ /*
+ * Rather than modify the entry to make such entries work,
+ * we reject this rule and require user level utilities
+ * to enforce whatever policy they deem appropriate.
+ */
+ if ((frwl->fw_src.s_addr & (~frwl->fw_smsk.s_addr)) ||
+ (frwl->fw_dst.s_addr & (~frwl->fw_dmsk.s_addr))) {
+ dprintf(("%s rule never matches\n", err_prefix));
+ return(NULL);
+ }
+
+ if ((frwl->fw_flg & IP_FW_F_FRAG) &&
+ (frwl->fw_prot == IPPROTO_UDP || frwl->fw_prot == IPPROTO_TCP)) {
+ if (frwl->fw_nports) {
+ dprintf(("%s cannot mix 'frag' and ports\n", err_prefix));
+ return(NULL);
+ }
+ if (frwl->fw_prot == IPPROTO_TCP &&
+ frwl->fw_tcpf != frwl->fw_tcpnf) {
+ dprintf(("%s cannot mix 'frag' with TCP flags\n", err_prefix));
+ return(NULL);
+ }
+ }
+
+ /* Check command specific stuff */
+ switch (frwl->fw_flg & IP_FW_F_COMMAND)
+ {
+ case IP_FW_F_REJECT:
+ if (frwl->fw_reject_code >= 0x100
+ && !(frwl->fw_prot == IPPROTO_TCP
+ && frwl->fw_reject_code == IP_FW_REJECT_RST)) {
+ dprintf(("%s unknown reject code\n", err_prefix));
+ return(NULL);
+ }
+ break;
+ case IP_FW_F_DIVERT: /* Diverting to port zero is invalid */
+ case IP_FW_F_TEE:
+ if (frwl->fw_divert_port == 0) {
+ dprintf(("%s can't divert to port 0\n", err_prefix));
+ return (NULL);
+ }
+ break;
+ case IP_FW_F_DENY:
+ case IP_FW_F_ACCEPT:
+ case IP_FW_F_COUNT:
+ case IP_FW_F_SKIPTO:
+ break;
+ default:
+ dprintf(("%s invalid command\n", err_prefix));
+ return(NULL);
+ }
+
+ return frwl;
+}
+
+static int
+ip_fw_ctl(int stage, struct mbuf **mm)
+{
+ int error;
+ struct mbuf *m;
+
+ if (stage == IP_FW_GET) {
+ struct ip_fw_chain *fcp = ip_fw_chain.lh_first;
+ *mm = m = m_get(M_WAIT, MT_SOOPTS);
+ for (; fcp; fcp = fcp->chain.le_next) {
+ memcpy(m->m_data, fcp->rule, sizeof *(fcp->rule));
+ m->m_len = sizeof *(fcp->rule);
+ m->m_next = m_get(M_WAIT, MT_SOOPTS);
+ m = m->m_next;
+ m->m_len = 0;
+ }
+ return (0);
+ }
+ m = *mm;
+ /* only allow get calls if secure mode > 2 */
+ if (securelevel > 2) {
+ if (m) (void)m_free(m);
+ return(EPERM);
+ }
+ if (stage == IP_FW_FLUSH) {
+ while (ip_fw_chain.lh_first != NULL &&
+ ip_fw_chain.lh_first->rule->fw_number != (u_short)-1) {
+ struct ip_fw_chain *fcp = ip_fw_chain.lh_first;
+ int s = splnet();
+ LIST_REMOVE(ip_fw_chain.lh_first, chain);
+ splx(s);
+ free(fcp->rule, M_IPFW);
+ free(fcp, M_IPFW);
+ }
+ if (m) (void)m_free(m);
+ return (0);
+ }
+ if (stage == IP_FW_ZERO) {
+ error = zero_entry(m);
+ if (m) (void)m_free(m);
+ return (error);
+ }
+ if (m == NULL) {
+ printf("%s NULL mbuf ptr\n", err_prefix);
+ return (EINVAL);
+ }
+
+ if (stage == IP_FW_ADD) {
+ struct ip_fw *frwl = check_ipfw_mbuf(m);
+
+ if (!frwl)
+ error = EINVAL;
+ else
+ error = add_entry(&ip_fw_chain, frwl);
+ if (m) (void)m_free(m);
+ return error;
+ }
+ if (stage == IP_FW_DEL) {
+ if (m->m_len != sizeof(struct ip_fw)) {
+ dprintf(("%s len=%d, want %d\n", err_prefix, m->m_len,
+ (int)sizeof(struct ip_fw)));
+ error = EINVAL;
+ } else if (mtod(m, struct ip_fw *)->fw_number == (u_short)-1) {
+ dprintf(("%s can't delete rule 65535\n", err_prefix));
+ error = EINVAL;
+ } else
+ error = del_entry(&ip_fw_chain,
+ mtod(m, struct ip_fw *)->fw_number);
+ if (m) (void)m_free(m);
+ return error;
+ }
+
+ dprintf(("%s unknown request %d\n", err_prefix, stage));
+ if (m) (void)m_free(m);
+ return (EINVAL);
+}
+
+void
+ip_fw_init(void)
+{
+ struct ip_fw default_rule;
+
+ ip_fw_chk_ptr = ip_fw_chk;
+ ip_fw_ctl_ptr = ip_fw_ctl;
+ LIST_INIT(&ip_fw_chain);
+
+ bzero(&default_rule, sizeof default_rule);
+ default_rule.fw_prot = IPPROTO_IP;
+ default_rule.fw_number = (u_short)-1;
+#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
+ default_rule.fw_flg |= IP_FW_F_ACCEPT;
+#else
+ default_rule.fw_flg |= IP_FW_F_DENY;
+#endif
+ default_rule.fw_flg |= IP_FW_F_IN | IP_FW_F_OUT;
+ if (check_ipfw_struct(&default_rule) == NULL ||
+ add_entry(&ip_fw_chain, &default_rule))
+ panic(__FUNCTION__);
+
+ printf("IP packet filtering initialized, "
+#ifdef IPDIVERT
+ "divert enabled, ");
+#else
+ "divert disabled, ");
+#endif
+#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
+ printf("default to accept, ");
+#endif
+#ifndef IPFIREWALL_VERBOSE
+ printf("logging disabled\n");
+#else
+ if (fw_verbose_limit == 0)
+ printf("unlimited logging\n");
+ else
+ printf("logging limited to %d packets/entry\n",
+ fw_verbose_limit);
+#endif
+}
+
+#ifdef IPFIREWALL_MODULE
+
+#include <sys/exec.h>
+#include <sys/sysent.h>
+#include <sys/lkm.h>
+
+MOD_MISC(ipfw);
+
+static int
+ipfw_load(struct lkm_table *lkmtp, int cmd)
+{
+ int s=splnet();
+
+ old_chk_ptr = ip_fw_chk_ptr;
+ old_ctl_ptr = ip_fw_ctl_ptr;
+
+ ip_fw_init();
+ splx(s);
+ return 0;
+}
+
+static int
+ipfw_unload(struct lkm_table *lkmtp, int cmd)
+{
+ int s=splnet();
+
+ ip_fw_chk_ptr = old_chk_ptr;
+ ip_fw_ctl_ptr = old_ctl_ptr;
+
+ while (ip_fw_chain.lh_first != NULL) {
+ struct ip_fw_chain *fcp = ip_fw_chain.lh_first;
+ LIST_REMOVE(ip_fw_chain.lh_first, chain);
+ free(fcp->rule, M_IPFW);
+ free(fcp, M_IPFW);
+ }
+
+ splx(s);
+ printf("IP firewall unloaded\n");
+ return 0;
+}
+
+int
+ipfw_mod(struct lkm_table *lkmtp, int cmd, int ver)
+{
+ DISPATCH(lkmtp, cmd, ver, ipfw_load, ipfw_unload, lkm_nullcmd);
+}
+#endif
diff --git a/cpukit/libnetworking/netinet/ip_fw.h b/cpukit/libnetworking/netinet/ip_fw.h
new file mode 100644
index 0000000000..f90deb96c2
--- /dev/null
+++ b/cpukit/libnetworking/netinet/ip_fw.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 1993 Daniel Boulet
+ * Copyright (c) 1994 Ugen J.S.Antsilevich
+ *
+ * Redistribution and use in source forms, with and without modification,
+ * are permitted provided that this entire comment appears intact.
+ *
+ * Redistribution in binary form may occur without any restrictions.
+ * Obviously, it would be nice if you gave credit where credit is due
+ * but requiring it would be too onerous.
+ *
+ * This software is provided ``AS IS'' without any warranties of any kind.
+ *
+ * $Id$
+ */
+
+#ifndef _IP_FW_H
+#define _IP_FW_H
+
+#include <net/if.h>
+
+/*
+ * This union structure identifies an interface, either explicitly
+ * by name or implicitly by IP address. The flags IP_FW_F_IIFNAME
+ * and IP_FW_F_OIFNAME say how to interpret this structure. An
+ * interface unit number of -1 matches any unit number, while an
+ * IP address of 0.0.0.0 indicates matches any interface.
+ *
+ * The receive and transmit interfaces are only compared against the
+ * the packet if the corresponding bit (IP_FW_F_IIFACE or IP_FW_F_OIFACE)
+ * is set. Note some packets lack a receive or transmit interface
+ * (in which case the missing "interface" never matches).
+ */
+
+union ip_fw_if {
+ struct in_addr fu_via_ip; /* Specified by IP address */
+ struct { /* Specified by interface name */
+#define FW_IFNLEN IFNAMSIZ
+ char name[FW_IFNLEN];
+ short unit; /* -1 means match any unit */
+ } fu_via_if;
+};
+
+/*
+ * Format of an IP firewall descriptor
+ *
+ * fw_src, fw_dst, fw_smsk, fw_dmsk are always stored in network byte order.
+ * fw_flg and fw_n*p are stored in host byte order (of course).
+ * Port numbers are stored in HOST byte order.
+ * Warning: setsockopt() will fail if sizeof(struct ip_fw) > MLEN (108)
+ */
+
+struct ip_fw {
+ u_long fw_pcnt,fw_bcnt; /* Packet and byte counters */
+ struct in_addr fw_src, fw_dst; /* Source and destination IP addr */
+ struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */
+ u_short fw_number; /* Rule number */
+ u_short fw_flg; /* Flags word */
+#define IP_FW_MAX_PORTS 10 /* A reasonable maximum */
+ u_short fw_pts[IP_FW_MAX_PORTS]; /* Array of port numbers to match */
+ u_char fw_ipopt,fw_ipnopt; /* IP options set/unset */
+ u_char fw_tcpf,fw_tcpnf; /* TCP flags set/unset */
+#define IP_FW_ICMPTYPES_DIM (32 / (sizeof(unsigned) * 8))
+ unsigned fw_icmptypes[IP_FW_ICMPTYPES_DIM]; /* ICMP types bitmap */
+ long timestamp; /* timestamp (tv_sec) of last match */
+ union ip_fw_if fw_in_if, fw_out_if; /* Incoming and outgoing interfaces */
+ union {
+ u_short fu_divert_port; /* Divert/tee port (options IPDIVERT) */
+ u_short fu_skipto_rule; /* SKIPTO command rule number */
+ u_short fu_reject_code; /* REJECT response code */
+ } fw_un;
+ u_char fw_prot; /* IP protocol */
+ u_char fw_nports; /* N'of src ports and # of dst ports */
+ /* in ports array (dst ports follow */
+ /* src ports; max of 10 ports in all; */
+ /* count of 0 means match all ports) */
+};
+
+#define IP_FW_GETNSRCP(rule) ((rule)->fw_nports & 0x0f)
+#define IP_FW_SETNSRCP(rule, n) do { \
+ (rule)->fw_nports &= ~0x0f; \
+ (rule)->fw_nports |= (n); \
+ } while (0)
+#define IP_FW_GETNDSTP(rule) ((rule)->fw_nports >> 4)
+#define IP_FW_SETNDSTP(rule, n) do { \
+ (rule)->fw_nports &= ~0xf0; \
+ (rule)->fw_nports |= (n) << 4;\
+ } while (0)
+
+#define fw_divert_port fw_un.fu_divert_port
+#define fw_skipto_rule fw_un.fu_skipto_rule
+#define fw_reject_code fw_un.fu_reject_code
+
+struct ip_fw_chain {
+ LIST_ENTRY(ip_fw_chain) chain;
+ struct ip_fw *rule;
+};
+
+/*
+ * Values for "flags" field .
+ */
+#define IP_FW_F_IN 0x0001 /* Check inbound packets */
+#define IP_FW_F_OUT 0x0002 /* Check outbound packets */
+#define IP_FW_F_IIFACE 0x0004 /* Apply inbound interface test */
+#define IP_FW_F_OIFACE 0x0008 /* Apply outbound interface test */
+
+#define IP_FW_F_COMMAND 0x0070 /* Mask for type of chain entry: */
+#define IP_FW_F_DENY 0x0000 /* This is a deny rule */
+#define IP_FW_F_REJECT 0x0010 /* Deny and send a response packet */
+#define IP_FW_F_ACCEPT 0x0020 /* This is an accept rule */
+#define IP_FW_F_COUNT 0x0030 /* This is a count rule */
+#define IP_FW_F_DIVERT 0x0040 /* This is a divert rule */
+#define IP_FW_F_TEE 0x0050 /* This is a tee rule */
+#define IP_FW_F_SKIPTO 0x0060 /* This is a skipto rule */
+
+#define IP_FW_F_PRN 0x0080 /* Print if this rule matches */
+
+#define IP_FW_F_SRNG 0x0100 /* The first two src ports are a min *
+ * and max range (stored in host byte *
+ * order). */
+
+#define IP_FW_F_DRNG 0x0200 /* The first two dst ports are a min *
+ * and max range (stored in host byte *
+ * order). */
+
+#define IP_FW_F_IIFNAME 0x0400 /* In interface by name/unit (not IP) */
+#define IP_FW_F_OIFNAME 0x0800 /* Out interface by name/unit (not IP) */
+
+#define IP_FW_F_INVSRC 0x1000 /* Invert sense of src check */
+#define IP_FW_F_INVDST 0x2000 /* Invert sense of dst check */
+
+#define IP_FW_F_FRAG 0x4000 /* Fragment */
+
+#define IP_FW_F_ICMPBIT 0x8000 /* ICMP type bitmap is valid */
+
+#define IP_FW_F_MASK 0xFFFF /* All possible flag bits mask */
+
+/*
+ * For backwards compatibility with rules specifying "via iface" but
+ * not restricted to only "in" or "out" packets, we define this combination
+ * of bits to represent this configuration.
+ */
+
+#define IF_FW_F_VIAHACK (IP_FW_F_IN|IP_FW_F_OUT|IP_FW_F_IIFACE|IP_FW_F_OIFACE)
+
+/*
+ * Definitions for REJECT response codes.
+ * Values less than 256 correspond to ICMP unreachable codes.
+ */
+#define IP_FW_REJECT_RST 0x0100 /* TCP packets: send RST */
+
+/*
+ * Definitions for IP option names.
+ */
+#define IP_FW_IPOPT_LSRR 0x01
+#define IP_FW_IPOPT_SSRR 0x02
+#define IP_FW_IPOPT_RR 0x04
+#define IP_FW_IPOPT_TS 0x08
+
+/*
+ * Definitions for TCP flags.
+ */
+#define IP_FW_TCPF_FIN TH_FIN
+#define IP_FW_TCPF_SYN TH_SYN
+#define IP_FW_TCPF_RST TH_RST
+#define IP_FW_TCPF_PSH TH_PUSH
+#define IP_FW_TCPF_ACK TH_ACK
+#define IP_FW_TCPF_URG TH_URG
+#define IP_FW_TCPF_ESTAB 0x40
+
+/*
+ * Main firewall chains definitions and global var's definitions.
+ */
+#ifdef _KERNEL
+
+/*
+ * Function definitions.
+ */
+void ip_fw_init(void);
+
+#endif /* _KERNEL */
+
+#endif /* _IP_FW_H */
diff --git a/cpukit/libnetworking/netinet/ip_icmp.c b/cpukit/libnetworking/netinet/ip_icmp.c
new file mode 100644
index 0000000000..26d9b8b491
--- /dev/null
+++ b/cpukit/libnetworking/netinet/ip_icmp.c
@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 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.
+ * 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.
+ *
+ * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94
+ * $FreeBSD: src/sys/netinet/ip_icmp.c,v 1.101 2005/05/04 13:23:54 andre Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#define _IP_VHL
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_var.h>
+#include <netinet/icmp_var.h>
+
+#ifdef IPSEC
+#include <netinet6/ipsec.h>
+#include <netkey/key.h>
+#endif
+
+#ifdef FAST_IPSEC
+#include <netipsec/ipsec.h>
+#include <netipsec/key.h>
+#define IPSEC
+#endif
+
+#include <machine/in_cksum.h>
+
+/*
+ * ICMP routines: error generation, receive packet processing, and
+ * routines to turnaround packets back to the originator, and
+ * host table maintenance routines.
+ */
+
+ struct icmpstat icmpstat;
+SYSCTL_STRUCT(_net_inet_icmp, ICMPCTL_STATS, stats, CTLFLAG_RD,
+ &icmpstat, icmpstat, "");
+
+static int icmpmaskrepl = 0;
+SYSCTL_INT(_net_inet_icmp, ICMPCTL_MASKREPL, maskrepl, CTLFLAG_RW,
+ &icmpmaskrepl, 0, "");
+
+static int icmpbmcastecho = 1;
+SYSCTL_INT(_net_inet_icmp, OID_AUTO, bmcastecho, CTLFLAG_RW, &icmpbmcastecho,
+ 0, "");
+
+static int icmpallecho = 1;
+SYSCTL_INT(_net_inet_icmp, OID_AUTO, allecho, CTLFLAG_RW, &icmpallecho,
+ 0, "");
+
+/* #define ICMPPRINTFS 1 */
+#ifdef ICMPPRINTFS
+int icmpprintfs = 0;
+#endif
+
+static void icmp_reflect(struct mbuf *);
+static void icmp_send(struct mbuf *, struct mbuf *);
+
+extern struct protosw inetsw[];
+unsigned int icmplenPanicAvoided;
+
+/*
+ * Generate an error packet of type error
+ * in response to bad packet ip.
+ */
+void
+icmp_error(n, type, code, dest, destifp)
+ struct mbuf *n;
+ int type, code;
+ n_long dest;
+ struct ifnet *destifp;
+{
+ register struct ip *oip = mtod(n, struct ip *), *nip;
+ register unsigned oiplen = IP_VHL_HL(oip->ip_vhl) << 2;
+ register struct icmp *icp;
+ register struct mbuf *m;
+ unsigned icmplen;
+
+#ifdef ICMPPRINTFS
+ if (icmpprintfs)
+ printf("icmp_error(%p, %x, %d)\n", oip, type, code);
+#endif
+ if (type != ICMP_REDIRECT)
+ icmpstat.icps_error++;
+ /*
+ * Don't send error if not the first fragment of message.
+ * Don't error if the old packet protocol was ICMP
+ * error message, only known informational types.
+ */
+ if (oip->ip_off &~ (IP_MF|IP_DF))
+ goto freeit;
+ if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT &&
+ n->m_len >= oiplen + ICMP_MINLEN &&
+ !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiplen))->icmp_type)) {
+ icmpstat.icps_oldicmp++;
+ goto freeit;
+ }
+ /* Don't send error in response to a multicast or broadcast packet */
+ if (n->m_flags & (M_BCAST|M_MCAST))
+ goto freeit;
+ /* Don't send error in response to malicious packet */
+ icmplen = min(oiplen + 8, oip->ip_len);
+ if (icmplen < sizeof(struct ip)) {
+ icmplenPanicAvoided++;
+ goto freeit;
+ }
+
+ /*
+ * First, formulate icmp message
+ */
+ m = m_gethdr(M_DONTWAIT, MT_HEADER);
+ if (m == NULL)
+ goto freeit;
+#ifdef MAC
+ mac_create_mbuf_netlayer(n, m);
+#endif
+ m->m_len = icmplen + ICMP_MINLEN;
+ MH_ALIGN(m, m->m_len);
+ icp = mtod(m, struct icmp *);
+ if ((u_int)type > ICMP_MAXTYPE)
+ panic("icmp_error");
+ icmpstat.icps_outhist[type]++;
+ icp->icmp_type = type;
+ if (type == ICMP_REDIRECT)
+ icp->icmp_gwaddr.s_addr = dest;
+ else {
+ icp->icmp_void = 0;
+ /*
+ * The following assignments assume an overlay with the
+ * zeroed icmp_void field.
+ */
+ if (type == ICMP_PARAMPROB) {
+ icp->icmp_pptr = code;
+ code = 0;
+ } else if (type == ICMP_UNREACH &&
+ code == ICMP_UNREACH_NEEDFRAG && destifp) {
+ icp->icmp_nextmtu = htons(destifp->if_mtu);
+ }
+ }
+
+ icp->icmp_code = code;
+ bcopy((caddr_t)oip, (caddr_t)&icp->icmp_ip, icmplen);
+ nip = &icp->icmp_ip;
+ nip->ip_len = htons((u_short)(nip->ip_len + oiplen));
+
+ /*
+ * Now, copy old ip header (without options)
+ * in front of icmp message.
+ */
+ if (m->m_data - sizeof(struct ip) < m->m_pktdat)
+ panic("icmp len");
+ m->m_data -= sizeof(struct ip);
+ m->m_len += sizeof(struct ip);
+ m->m_pkthdr.len = m->m_len;
+ m->m_pkthdr.rcvif = n->m_pkthdr.rcvif;
+ nip = mtod(m, struct ip *);
+ bcopy((caddr_t)oip, (caddr_t)nip, sizeof(struct ip));
+ nip->ip_len = m->m_len;
+ nip->ip_vhl = IP_VHL_BORING;
+ nip->ip_p = IPPROTO_ICMP;
+ nip->ip_tos = 0;
+ icmp_reflect(m);
+
+freeit:
+ m_freem(n);
+}
+
+static struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET };
+static struct sockaddr_in icmpdst = { sizeof (struct sockaddr_in), AF_INET };
+static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET };
+
+/*
+ * Process a received ICMP message.
+ */
+void
+icmp_input(m, off)
+ struct mbuf *m;
+ int off;
+{
+ struct icmp *icp;
+ struct in_ifaddr *ia;
+ struct ip *ip = mtod(m, struct ip *);
+ int hlen = off;
+ int icmplen = ip->ip_len;
+ int i, code;
+ void (*ctlfunc)(int, struct sockaddr *, void *);
+
+ /*
+ * Locate icmp structure in mbuf, and check
+ * that not corrupted and of at least minimum length.
+ */
+#ifdef ICMPPRINTFS
+ if (icmpprintfs) {
+ char buf[4 * sizeof "123"];
+ strcpy(buf, inet_ntoa(ip->ip_src));
+ printf("icmp_input from %s to %s, len %d\n",
+ buf, inet_ntoa(ip->ip_dst), icmplen);
+ }
+#endif
+ if (icmplen < ICMP_MINLEN) {
+ icmpstat.icps_tooshort++;
+ goto freeit;
+ }
+ i = hlen + min(icmplen, ICMP_ADVLENMIN);
+ if (m->m_len < i && (m = m_pullup(m, i)) == 0) {
+ icmpstat.icps_tooshort++;
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ m->m_len -= hlen;
+ m->m_data += hlen;
+ icp = mtod(m, struct icmp *);
+ if (in_cksum(m, icmplen)) {
+ icmpstat.icps_checksum++;
+ goto freeit;
+ }
+ m->m_len += hlen;
+ m->m_data -= hlen;
+
+#ifdef ICMPPRINTFS
+ if (icmpprintfs)
+ printf("icmp_input, type %d code %d\n", icp->icmp_type,
+ icp->icmp_code);
+#endif
+
+ /*
+ * Message type specific processing.
+ */
+ if (icp->icmp_type > ICMP_MAXTYPE)
+ goto raw;
+ icmpstat.icps_inhist[icp->icmp_type]++;
+ code = icp->icmp_code;
+ switch (icp->icmp_type) {
+
+ case ICMP_UNREACH:
+ switch (code) {
+ case ICMP_UNREACH_NET:
+ case ICMP_UNREACH_HOST:
+ case ICMP_UNREACH_PROTOCOL:
+ case ICMP_UNREACH_PORT:
+ case ICMP_UNREACH_SRCFAIL:
+ code = PRC_UNREACH_NET;
+ break;
+
+ case ICMP_UNREACH_NEEDFRAG:
+ code = PRC_MSGSIZE;
+ break;
+
+ case ICMP_UNREACH_NET_UNKNOWN:
+ case ICMP_UNREACH_NET_PROHIB:
+ case ICMP_UNREACH_TOSNET:
+ code = PRC_UNREACH_NET;
+ break;
+
+ case ICMP_UNREACH_HOST_UNKNOWN:
+ case ICMP_UNREACH_ISOLATED:
+ case ICMP_UNREACH_HOST_PROHIB:
+ case ICMP_UNREACH_TOSHOST:
+ code = PRC_UNREACH_HOST;
+ break;
+
+ case ICMP_UNREACH_FILTER_PROHIB:
+ case ICMP_UNREACH_HOST_PRECEDENCE:
+ case ICMP_UNREACH_PRECEDENCE_CUTOFF:
+ code = PRC_UNREACH_PORT;
+ break;
+
+ default:
+ goto badcode;
+ }
+ goto deliver;
+
+ case ICMP_TIMXCEED:
+ if (code > 1)
+ goto badcode;
+ code += PRC_TIMXCEED_INTRANS;
+ goto deliver;
+
+ case ICMP_PARAMPROB:
+ if (code > 1)
+ goto badcode;
+ code = PRC_PARAMPROB;
+ goto deliver;
+
+ case ICMP_SOURCEQUENCH:
+ if (code)
+ goto badcode;
+ code = PRC_QUENCH;
+ deliver:
+ /*
+ * Problem with datagram; advise higher level routines.
+ */
+ if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
+ IP_VHL_HL(icp->icmp_ip.ip_vhl) < (sizeof(struct ip) >> 2)) {
+ icmpstat.icps_badlen++;
+ goto freeit;
+ }
+ NTOHS(icp->icmp_ip.ip_len);
+ /* Discard ICMP's in response to multicast packets */
+ if (IN_MULTICAST(ntohl(icp->icmp_ip.ip_dst.s_addr)))
+ goto badcode;
+#ifdef ICMPPRINTFS
+ if (icmpprintfs)
+ printf("deliver to protocol %d\n", icp->icmp_ip.ip_p);
+#endif
+ icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
+#if 1
+ /*
+ * MTU discovery:
+ * If we got a needfrag and there is a host route to the
+ * original destination, and the MTU is not locked, then
+ * set the MTU in the route to the suggested new value
+ * (if given) and then notify as usual. The ULPs will
+ * notice that the MTU has changed and adapt accordingly.
+ * If no new MTU was suggested, then we guess a new one
+ * less than the current value. If the new MTU is
+ * unreasonably small (arbitrarily set at 296), then
+ * we reset the MTU to the interface value and enable the
+ * lock bit, indicating that we are no longer doing MTU
+ * discovery.
+ */
+ if (code == PRC_MSGSIZE) {
+ struct rtentry *rt;
+ int mtu;
+
+ rt = rtalloc1((struct sockaddr *)&icmpsrc, 0,
+ RTF_CLONING | RTF_PRCLONING);
+ if (rt && (rt->rt_flags & RTF_HOST)
+ && !(rt->rt_rmx.rmx_locks & RTV_MTU)) {
+ mtu = ntohs(icp->icmp_nextmtu);
+ if (!mtu)
+ mtu = ip_next_mtu(rt->rt_rmx.rmx_mtu,
+ 1);
+#ifdef DEBUG_MTUDISC
+ printf("MTU for %s reduced to %d\n",
+ inet_ntoa(icmpsrc.sin_addr), mtu);
+#endif
+ if (mtu < 296) {
+ /* rt->rt_rmx.rmx_mtu =
+ rt->rt_ifp->if_mtu; */
+ rt->rt_rmx.rmx_locks |= RTV_MTU;
+ } else if (rt->rt_rmx.rmx_mtu > mtu) {
+ rt->rt_rmx.rmx_mtu = mtu;
+ }
+ }
+ if (rt)
+ RTFREE(rt);
+ }
+
+#endif
+ ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
+ if (ctlfunc)
+ (*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
+ (void *)&icp->icmp_ip);
+ break;
+
+ badcode:
+ icmpstat.icps_badcode++;
+ break;
+
+ case ICMP_ECHO:
+ if (!icmpallecho) {
+ icmpstat.icps_allecho++;
+ break;
+ }
+ if (!icmpbmcastecho
+ && (m->m_flags & (M_MCAST | M_BCAST)) != 0
+ && IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
+ icmpstat.icps_bmcastecho++;
+ break;
+ }
+ icp->icmp_type = ICMP_ECHOREPLY;
+ goto reflect;
+
+ case ICMP_TSTAMP:
+ if (!icmpbmcastecho
+ && (m->m_flags & (M_MCAST | M_BCAST)) != 0
+ && IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
+ icmpstat.icps_bmcasttstamp++;
+ break;
+ }
+ if (icmplen < ICMP_TSLEN) {
+ icmpstat.icps_badlen++;
+ break;
+ }
+ icp->icmp_type = ICMP_TSTAMPREPLY;
+ icp->icmp_rtime = iptime();
+ icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */
+ goto reflect;
+
+ case ICMP_MASKREQ:
+#define satosin(sa) ((struct sockaddr_in *)(sa))
+ if (icmpmaskrepl == 0)
+ break;
+ /*
+ * We are not able to respond with all ones broadcast
+ * unless we receive it over a point-to-point interface.
+ */
+ if (icmplen < ICMP_MASKLEN)
+ break;
+ switch (ip->ip_dst.s_addr) {
+
+ case INADDR_BROADCAST:
+ case INADDR_ANY:
+ icmpdst.sin_addr = ip->ip_src;
+ break;
+
+ default:
+ icmpdst.sin_addr = ip->ip_dst;
+ }
+ ia = (struct in_ifaddr *)ifaof_ifpforaddr(
+ (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif);
+ if (ia == 0)
+ break;
+ if (ia->ia_ifp == 0)
+ break;
+ icp->icmp_type = ICMP_MASKREPLY;
+ icp->icmp_mask = ia->ia_sockmask.sin_addr.s_addr;
+ if (ip->ip_src.s_addr == 0) {
+ if (ia->ia_ifp->if_flags & IFF_BROADCAST)
+ ip->ip_src = satosin(&ia->ia_broadaddr)->sin_addr;
+ else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT)
+ ip->ip_src = satosin(&ia->ia_dstaddr)->sin_addr;
+ }
+reflect:
+ ip->ip_len += hlen; /* since ip_input deducts this */
+ icmpstat.icps_reflect++;
+ icmpstat.icps_outhist[icp->icmp_type]++;
+ icmp_reflect(m);
+ return;
+
+ case ICMP_REDIRECT:
+ if (code > 3)
+ goto badcode;
+ if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
+ IP_VHL_HL(icp->icmp_ip.ip_vhl) < (sizeof(struct ip) >> 2)) {
+ icmpstat.icps_badlen++;
+ break;
+ }
+ /*
+ * Short circuit routing redirects to force
+ * immediate change in the kernel's routing
+ * tables. The message is also handed to anyone
+ * listening on a raw socket (e.g. the routing
+ * daemon for use in updating its tables).
+ */
+ icmpgw.sin_addr = ip->ip_src;
+ icmpdst.sin_addr = icp->icmp_gwaddr;
+#ifdef ICMPPRINTFS
+ if (icmpprintfs) {
+ char buf[4 * sizeof "123"];
+ strcpy(buf, inet_ntoa(icp->icmp_ip.ip_dst));
+
+ printf("redirect dst %s to %s\n",
+ buf, inet_ntoa(icp->icmp_gwaddr));
+ }
+#endif
+ icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
+ rtredirect((struct sockaddr *)&icmpsrc,
+ (struct sockaddr *)&icmpdst,
+ (struct sockaddr *)0, RTF_GATEWAY | RTF_HOST,
+ (struct sockaddr *)&icmpgw, (struct rtentry **)0);
+ pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc);
+ break;
+
+ /*
+ * No kernel processing for the following;
+ * just fall through to send to raw listener.
+ */
+ case ICMP_ECHOREPLY:
+ case ICMP_ROUTERADVERT:
+ case ICMP_ROUTERSOLICIT:
+ case ICMP_TSTAMPREPLY:
+ case ICMP_IREQREPLY:
+ case ICMP_MASKREPLY:
+ default:
+ break;
+ }
+
+raw:
+ rip_input(m, hlen);
+ return;
+
+freeit:
+ m_freem(m);
+}
+
+/*
+ * Reflect the ip packet back to the source
+ */
+static void
+icmp_reflect(m)
+ struct mbuf *m;
+{
+ struct ip *ip = mtod(m, struct ip *);
+ struct in_ifaddr *ia;
+ struct in_addr t;
+ struct mbuf *opts = 0;
+ int optlen = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof(struct ip);
+
+ if (!in_canforward(ip->ip_src) &&
+ ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) !=
+ (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) {
+ m_freem(m); /* Bad return address */
+ goto done; /* Ip_output() will check for broadcast */
+ }
+ t = ip->ip_dst;
+ ip->ip_dst = ip->ip_src;
+ /*
+ * If the incoming packet was addressed directly to us,
+ * use dst as the src for the reply. Otherwise (broadcast
+ * or anonymous), use the address which corresponds
+ * to the incoming interface.
+ */
+ for (ia = in_ifaddr; ia; ia = ia->ia_next) {
+ if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr)
+ break;
+ if (ia->ia_ifp && (ia->ia_ifp->if_flags & IFF_BROADCAST) &&
+ t.s_addr == satosin(&ia->ia_broadaddr)->sin_addr.s_addr)
+ break;
+ }
+ icmpdst.sin_addr = t;
+ if ((ia == (struct in_ifaddr *)0) && m->m_pkthdr.rcvif)
+ ia = (struct in_ifaddr *)ifaof_ifpforaddr(
+ (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif);
+ /*
+ * The following happens if the packet was not addressed to us,
+ * and was received on an interface with no IP address.
+ */
+ if (ia == (struct in_ifaddr *)0)
+ ia = in_ifaddr;
+ t = IA_SIN(ia)->sin_addr;
+ ip->ip_src = t;
+ ip->ip_ttl = MAXTTL;
+
+ if (optlen > 0) {
+ register u_char *cp;
+ int opt, cnt;
+ u_int len;
+
+ /*
+ * Retrieve any source routing from the incoming packet;
+ * add on any record-route or timestamp options.
+ */
+ cp = (u_char *) (ip + 1);
+ if ((opts = ip_srcroute()) == 0 &&
+ (opts = m_gethdr(M_DONTWAIT, MT_HEADER))) {
+ opts->m_len = sizeof(struct in_addr);
+ mtod(opts, struct in_addr *)->s_addr = 0;
+ }
+ if (opts) {
+#ifdef ICMPPRINTFS
+ if (icmpprintfs)
+ printf("icmp_reflect optlen %d rt %d => ",
+ optlen, opts->m_len);
+#endif
+ for (cnt = optlen; cnt > 0; cnt -= len, cp += len) {
+ opt = cp[IPOPT_OPTVAL];
+ if (opt == IPOPT_EOL)
+ break;
+ if (opt == IPOPT_NOP)
+ len = 1;
+ else {
+ if (cnt < IPOPT_OLEN + sizeof(*cp))
+ break;
+ len = cp[IPOPT_OLEN];
+ if (len < IPOPT_OLEN + sizeof(*cp) ||
+ len > cnt)
+ break;
+ }
+ /*
+ * Should check for overflow, but it "can't happen"
+ */
+ if (opt == IPOPT_RR || opt == IPOPT_TS ||
+ opt == IPOPT_SECURITY) {
+ bcopy((caddr_t)cp,
+ mtod(opts, caddr_t) + opts->m_len, len);
+ opts->m_len += len;
+ }
+ }
+ /* Terminate & pad, if necessary */
+ cnt = opts->m_len % 4;
+ if (cnt) {
+ for (; cnt < 4; cnt++) {
+ *(mtod(opts, caddr_t) + opts->m_len) =
+ IPOPT_EOL;
+ opts->m_len++;
+ }
+ }
+#ifdef ICMPPRINTFS
+ if (icmpprintfs)
+ printf("%d\n", opts->m_len);
+#endif
+ }
+ /*
+ * Now strip out original options by copying rest of first
+ * mbuf's data back, and adjust the IP length.
+ */
+ ip->ip_len -= optlen;
+ ip->ip_vhl = IP_VHL_BORING;
+ m->m_len -= optlen;
+ if (m->m_flags & M_PKTHDR)
+ m->m_pkthdr.len -= optlen;
+ optlen += sizeof(struct ip);
+ bcopy((caddr_t)ip + optlen, (caddr_t)(ip + 1),
+ (unsigned)(m->m_len - sizeof(struct ip)));
+ }
+ m->m_flags &= ~(M_BCAST|M_MCAST);
+ icmp_send(m, opts);
+done:
+ if (opts)
+ (void)m_free(opts);
+}
+
+/*
+ * Send an icmp packet back to the ip level,
+ * after supplying a checksum.
+ */
+static void
+icmp_send(m, opts)
+ register struct mbuf *m;
+ struct mbuf *opts;
+{
+ register struct ip *ip = mtod(m, struct ip *);
+ register int hlen;
+ register struct icmp *icp;
+ struct route ro;
+
+ hlen = IP_VHL_HL(ip->ip_vhl) << 2;
+ m->m_data += hlen;
+ m->m_len -= hlen;
+ icp = mtod(m, struct icmp *);
+ icp->icmp_cksum = 0;
+ icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen);
+ m->m_data -= hlen;
+ m->m_len += hlen;
+#ifdef ICMPPRINTFS
+ if (icmpprintfs) {
+ char buf[4 * sizeof "123"];
+ strcpy(buf, inet_ntoa(ip->ip_dst));
+ printf("icmp_send dst %s src %s\n",
+ buf, inet_ntoa(ip->ip_src));
+ }
+#endif
+ bzero(&ro, sizeof ro);
+ (void) ip_output(m, opts, &ro, 0, NULL);
+ if (ro.ro_rt)
+ RTFREE(ro.ro_rt);
+}
+
+n_time
+iptime()
+{
+ struct timeval atv;
+ u_long t;
+
+ microtime(&atv);
+ t = (atv.tv_sec % (24*60*60)) * 1000 + atv.tv_usec / 1000;
+ return (htonl(t));
+}
+
+/*
+ * Return the next larger or smaller MTU plateau (table from RFC 1191)
+ * given current value MTU. If DIR is less than zero, a larger plateau
+ * is returned; otherwise, a smaller value is returned.
+ */
+int
+ip_next_mtu(mtu, dir)
+ int mtu;
+ int dir;
+{
+ static int mtutab[] = {
+ 65535, 32000, 17914, 8166, 4352, 2002, 1492, 1280, 1006, 508,
+ 296, 68, 0
+ };
+ int i;
+
+ for (i = 0; i < (sizeof mtutab) / (sizeof mtutab[0]); i++) {
+ if (mtu >= mtutab[i])
+ break;
+ }
+
+ if (dir < 0) {
+ if (i == 0) {
+ return 0;
+ } else {
+ return mtutab[i - 1];
+ }
+ } else {
+ if (mtutab[i] == 0) {
+ return 0;
+ } else if(mtu > mtutab[i]) {
+ return mtutab[i];
+ } else {
+ return mtutab[i + 1];
+ }
+ }
+}
diff --git a/cpukit/libnetworking/netinet/ip_icmp.h b/cpukit/libnetworking/netinet/ip_icmp.h
new file mode 100644
index 0000000000..1a763de365
--- /dev/null
+++ b/cpukit/libnetworking/netinet/ip_icmp.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ * 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.
+ *
+ * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/ip_icmp.h,v 1.26 2005/05/04 13:09:19 andre Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NETINET_IP_ICMP_H_
+#define _NETINET_IP_ICMP_H_
+
+/*
+ * Interface Control Message Protocol Definitions.
+ * Per RFC 792, September 1981.
+ */
+
+/*
+ * Internal of an ICMP Router Advertisement
+ */
+struct icmp_ra_addr {
+ u_int32_t ira_addr;
+ u_int32_t ira_preference;
+};
+
+/*
+ * Structure of an icmp header.
+ */
+struct icmp {
+ u_char icmp_type; /* type of message, see below */
+ u_char icmp_code; /* type sub code */
+ u_short icmp_cksum; /* ones complement cksum of struct */
+ union {
+ u_char ih_pptr; /* ICMP_PARAMPROB */
+ struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
+ struct ih_idseq {
+ n_short icd_id;
+ n_short icd_seq;
+ } ih_idseq;
+ int ih_void;
+
+ /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
+ struct ih_pmtu {
+ n_short ipm_void;
+ n_short ipm_nextmtu;
+ } ih_pmtu;
+
+ struct ih_rtradv {
+ u_char irt_num_addrs;
+ u_char irt_wpa;
+ u_int16_t irt_lifetime;
+ } ih_rtradv;
+ } icmp_hun;
+#define icmp_pptr icmp_hun.ih_pptr
+#define icmp_gwaddr icmp_hun.ih_gwaddr
+#define icmp_id icmp_hun.ih_idseq.icd_id
+#define icmp_seq icmp_hun.ih_idseq.icd_seq
+#define icmp_void icmp_hun.ih_void
+#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
+#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
+#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
+#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
+#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
+ union {
+ struct id_ts { /* ICMP Timestamp */
+ n_time its_otime; /* Originate */
+ n_time its_rtime; /* Receive */
+ n_time its_ttime; /* Transmit */
+ } id_ts;
+ struct id_ip {
+ struct ip idi_ip;
+ /* options and then 64 bits of data */
+ } id_ip;
+ struct icmp_ra_addr id_radv;
+ u_int32_t id_mask;
+ char id_data[1];
+ } icmp_dun;
+#define icmp_otime icmp_dun.id_ts.its_otime
+#define icmp_rtime icmp_dun.id_ts.its_rtime
+#define icmp_ttime icmp_dun.id_ts.its_ttime
+#define icmp_ip icmp_dun.id_ip.idi_ip
+#define icmp_radv icmp_dun.id_radv
+#define icmp_mask icmp_dun.id_mask
+#define icmp_data icmp_dun.id_data
+};
+
+/*
+ * Lower bounds on packet lengths for various types.
+ * For the error advice packets must first insure that the
+ * packet is large enough to contain the returned ip header.
+ * Only then can we do the check to see if 64 bits of packet
+ * data have been returned, since we need to check the returned
+ * ip header length.
+ */
+#define ICMP_MINLEN 8 /* abs minimum */
+#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */
+#define ICMP_MASKLEN 12 /* address mask */
+#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
+#ifndef _IP_VHL
+#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
+ /* N.B.: must separately check that ip_hl >= 5 */
+#else
+#define ICMP_ADVLEN(p) (8 + (IP_VHL_HL((p)->icmp_ip.ip_vhl) << 2) + 8)
+ /* N.B.: must separately check that header length >= 5 */
+#endif
+
+/*
+ * Definition of type and code field values.
+ */
+#define ICMP_ECHOREPLY 0 /* echo reply */
+#define ICMP_UNREACH 3 /* dest unreachable, codes: */
+#define ICMP_UNREACH_NET 0 /* bad net */
+#define ICMP_UNREACH_HOST 1 /* bad host */
+#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */
+#define ICMP_UNREACH_PORT 3 /* bad port */
+#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
+#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
+#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */
+#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */
+#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */
+#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */
+#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */
+#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */
+#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */
+#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohib */
+#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host prec vio. */
+#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* prec cutoff */
+#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */
+#define ICMP_REDIRECT 5 /* shorter route, codes: */
+#define ICMP_REDIRECT_NET 0 /* for network */
+#define ICMP_REDIRECT_HOST 1 /* for host */
+#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
+#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
+#define ICMP_ALTHOSTADDR 6 /* alternate host address */
+#define ICMP_ECHO 8 /* echo service */
+#define ICMP_ROUTERADVERT 9 /* router advertisement */
+#define ICMP_ROUTERADVERT_NORMAL 0 /* normal advertisement */
+#define ICMP_ROUTERADVERT_NOROUTE_COMMON 16 /* selective routing */
+#define ICMP_ROUTERSOLICIT 10 /* router solicitation */
+#define ICMP_TIMXCEED 11 /* time exceeded, code: */
+#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
+#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */
+#define ICMP_PARAMPROB 12 /* ip header bad */
+#define ICMP_PARAMPROB_ERRATPTR 0 /* error at param ptr */
+#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */
+#define ICMP_PARAMPROB_LENGTH 2 /* bad length */
+#define ICMP_TSTAMP 13 /* timestamp request */
+#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
+#define ICMP_IREQ 15 /* information request */
+#define ICMP_IREQREPLY 16 /* information reply */
+#define ICMP_MASKREQ 17 /* address mask request */
+#define ICMP_MASKREPLY 18 /* address mask reply */
+#define ICMP_TRACEROUTE 30 /* traceroute */
+#define ICMP_DATACONVERR 31 /* data conversion error */
+#define ICMP_MOBILE_REDIRECT 32 /* mobile host redirect */
+#define ICMP_IPV6_WHEREAREYOU 33 /* IPv6 where-are-you */
+#define ICMP_IPV6_IAMHERE 34 /* IPv6 i-am-here */
+#define ICMP_MOBILE_REGREQUEST 35 /* mobile registration req */
+#define ICMP_MOBILE_REGREPLY 36 /* mobile registration reply */
+#define ICMP_SKIP 39 /* SKIP */
+#define ICMP_PHOTURIS 40 /* Photuris */
+#define ICMP_PHOTURIS_UNKNOWN_INDEX 1 /* unknown sec index */
+#define ICMP_PHOTURIS_AUTH_FAILED 2 /* auth failed */
+#define ICMP_PHOTURIS_DECRYPT_FAILED 3 /* decrypt failed */
+
+#define ICMP_MAXTYPE 40
+
+#define ICMP_INFOTYPE(type) \
+ ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
+ (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
+ (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
+ (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
+ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
+
+#ifdef _KERNEL
+void icmp_error(struct mbuf *, int, int, n_long, struct ifnet *);
+void icmp_input(struct mbuf *, int);
+int ip_next_mtu(int, int);
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/netinet/ip_input.c b/cpukit/libnetworking/netinet/ip_input.c
new file mode 100644
index 0000000000..f915fb7106
--- /dev/null
+++ b/cpukit/libnetworking/netinet/ip_input.c
@@ -0,0 +1,1488 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 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.
+ *
+ * @(#)ip_input.c 8.2 (Berkeley) 1/4/94
+ * $Id$
+ * $ANA: ip_input.c,v 1.5 1996/09/18 14:34:59 wollman Exp $
+ */
+
+#define _IP_VHL
+
+#include "opt_ipfw.h"
+
+#include <stddef.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#include <sys/syslog.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+#include <net/netisr.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <machine/in_cksum.h>
+
+#include <sys/socketvar.h>
+
+#ifdef IPFIREWALL
+#include <netinet/ip_fw.h>
+#endif
+
+int rsvp_on = 0;
+static int ip_rsvp_on;
+struct socket *ip_rsvpd;
+
+int ipforwarding = 0;
+SYSCTL_INT(_net_inet_ip, IPCTL_FORWARDING, forwarding, CTLFLAG_RW,
+ &ipforwarding, 0, "");
+
+static int ipsendredirects = 1; /* XXX */
+SYSCTL_INT(_net_inet_ip, IPCTL_SENDREDIRECTS, redirect, CTLFLAG_RW,
+ &ipsendredirects, 0, "");
+
+int ip_defttl = IPDEFTTL;
+SYSCTL_INT(_net_inet_ip, IPCTL_DEFTTL, ttl, CTLFLAG_RW,
+ &ip_defttl, 0, "");
+
+static int ip_dosourceroute = 0;
+SYSCTL_INT(_net_inet_ip, IPCTL_SOURCEROUTE, sourceroute, CTLFLAG_RW,
+ &ip_dosourceroute, 0, "");
+
+static int ip_acceptsourceroute = 0;
+SYSCTL_INT(_net_inet_ip, IPCTL_ACCEPTSOURCEROUTE, accept_sourceroute,
+ CTLFLAG_RW, &ip_acceptsourceroute, 0, "");
+#ifdef DIAGNOSTIC
+static int ipprintfs = 0;
+#endif
+
+extern struct domain inetdomain;
+extern struct protosw inetsw[];
+u_char ip_protox[IPPROTO_MAX];
+static int ipqmaxlen = IFQ_MAXLEN;
+struct in_ifaddr *in_ifaddr; /* first inet address */
+struct ifqueue ipintrq;
+SYSCTL_INT(_net_inet_ip, IPCTL_INTRQMAXLEN, intr_queue_maxlen, CTLFLAG_RD,
+ &ipintrq.ifq_maxlen, 0, "");
+SYSCTL_INT(_net_inet_ip, IPCTL_INTRQDROPS, intr_queue_drops, CTLFLAG_RD,
+ &ipintrq.ifq_drops, 0, "");
+
+struct ipstat ipstat;
+
+/* Packet reassembly stuff */
+#define IPREASS_NHASH_LOG2 6
+#define IPREASS_NHASH (1 << IPREASS_NHASH_LOG2)
+#define IPREASS_HMASK (IPREASS_NHASH - 1)
+#define IPREASS_HASH(x,y) \
+ (((((x) & 0xF) | ((((x) >> 8) & 0xF) << 4)) ^ (y)) & IPREASS_HMASK)
+
+static struct ipq ipq[IPREASS_NHASH];
+static int nipq = 0; /* total # of reass queues */
+static int maxnipq;
+
+#ifdef IPCTL_DEFMTU
+SYSCTL_INT(_net_inet_ip, IPCTL_DEFMTU, mtu, CTLFLAG_RW,
+ &ip_mtu, 0, "");
+#endif
+
+#if !defined(COMPAT_IPFW) || COMPAT_IPFW == 1
+#undef COMPAT_IPFW
+#define COMPAT_IPFW 1
+#else
+#undef COMPAT_IPFW
+#endif
+
+#ifdef COMPAT_IPFW
+/* Firewall hooks */
+ip_fw_chk_t *ip_fw_chk_ptr;
+ip_fw_ctl_t *ip_fw_ctl_ptr;
+
+/* IP Network Address Translation (NAT) hooks */
+ip_nat_t *ip_nat_ptr;
+ip_nat_ctl_t *ip_nat_ctl_ptr;
+#endif
+
+/*
+ * We need to save the IP options in case a protocol wants to respond
+ * to an incoming packet over the same route if the packet got here
+ * using IP source routing. This allows connection establishment and
+ * maintenance when the remote end is on a network that is not known
+ * to us.
+ */
+static int ip_nhops = 0;
+static struct ip_srcrt {
+ struct in_addr dst; /* final destination */
+ char nop; /* one NOP to align */
+ char srcopt[IPOPT_OFFSET + 1]; /* OPTVAL, OLEN and OFFSET */
+ struct in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)];
+} ip_srcrt;
+
+#ifdef IPDIVERT
+/*
+ * Shared variable between ip_input() and ip_reass() to communicate
+ * about which packets, once assembled from fragments, get diverted,
+ * and to which port.
+ */
+static u_short frag_divert_port;
+#endif
+
+static void save_rte __P((u_char *, struct in_addr));
+static void ip_deq __P((struct ipasfrag *));
+static int ip_dooptions __P((struct mbuf *));
+static void ip_enq __P((struct ipasfrag *, struct ipasfrag *));
+static void ip_forward __P((struct mbuf *, int));
+static void ip_freef __P((struct ipq *));
+static struct ip *
+ ip_reass __P((struct ipasfrag *, struct ipq *, struct ipq *));
+static struct in_ifaddr *
+ ip_rtaddr __P((struct in_addr));
+void ipintr __P((void));
+/*
+ * IP initialization: fill in IP protocol switch table.
+ * All protocols not implemented in kernel go to raw IP protocol handler.
+ */
+void
+ip_init()
+{
+ register struct protosw *pr;
+ register int i;
+
+ pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
+ if (pr == 0)
+ panic("ip_init");
+ for (i = 0; i < IPPROTO_MAX; i++)
+ ip_protox[i] = pr - inetsw;
+ for (pr = inetdomain.dom_protosw;
+ pr < inetdomain.dom_protoswNPROTOSW; pr++)
+ if (pr->pr_domain->dom_family == PF_INET &&
+ pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
+ ip_protox[pr->pr_protocol] = pr - inetsw;
+
+ for (i = 0; i < IPREASS_NHASH; i++)
+ ipq[i].next = ipq[i].prev = &ipq[i];
+
+ maxnipq = nmbclusters/4;
+
+ ip_id = rtems_bsdnet_seconds_since_boot() & 0xffff;
+ ipintrq.ifq_maxlen = ipqmaxlen;
+#ifdef IPFIREWALL
+ ip_fw_init();
+#endif
+#ifdef IPNAT
+ ip_nat_init();
+#endif
+
+}
+
+static struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
+static struct route ipforward_rt;
+
+/*
+ * Ip input routine. Checksum and byte swap header. If fragmented
+ * try to reassemble. Process options. Pass to next level.
+ */
+void
+ip_input(struct mbuf *m)
+{
+ struct ip *ip;
+ struct ipq *fp;
+ struct in_ifaddr *ia;
+ int i, hlen;
+ u_short sum;
+
+#ifdef DIAGNOSTIC
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("ip_input no HDR");
+#endif
+ /*
+ * If no IP addresses have been set yet but the interfaces
+ * are receiving, can't do anything with incoming packets yet.
+ */
+ if (in_ifaddr == NULL)
+ goto bad;
+ ipstat.ips_total++;
+
+ if (m->m_pkthdr.len < sizeof(struct ip))
+ goto tooshort;
+
+#if defined(DIAGNOSTIC) && defined(ORIGINAL_FREEBSD_CODE)
+ if (m->m_len < sizeof(struct ip))
+ panic("ipintr mbuf too short");
+#endif
+
+ if (m->m_len < sizeof (struct ip) &&
+ (m = m_pullup(m, sizeof (struct ip))) == 0) {
+ ipstat.ips_toosmall++;
+ return;
+ }
+ ip = mtod(m, struct ip *);
+
+ if (IP_VHL_V(ip->ip_vhl) != IPVERSION) {
+ ipstat.ips_badvers++;
+ goto bad;
+ }
+
+ hlen = IP_VHL_HL(ip->ip_vhl) << 2;
+ if (hlen < sizeof(struct ip)) { /* minimum header length */
+ ipstat.ips_badhlen++;
+ goto bad;
+ }
+ if (hlen > m->m_len) {
+ if ((m = m_pullup(m, hlen)) == 0) {
+ ipstat.ips_badhlen++;
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ }
+ if (hlen == sizeof(struct ip)) {
+ sum = in_cksum_hdr(ip);
+ } else {
+ sum = in_cksum(m, hlen);
+ }
+ if (sum) {
+ ipstat.ips_badsum++;
+ goto bad;
+ }
+
+ /*
+ * Convert fields to host representation.
+ */
+ NTOHS(ip->ip_len);
+ if (ip->ip_len < hlen) {
+ ipstat.ips_badlen++;
+ goto bad;
+ }
+ NTOHS(ip->ip_id);
+ NTOHS(ip->ip_off);
+
+ /*
+ * Check that the amount of data in the buffers
+ * is as at least much as the IP header would have us expect.
+ * Trim mbufs if longer than we expect.
+ * Drop packet if shorter than we expect.
+ */
+ if (m->m_pkthdr.len < ip->ip_len) {
+tooshort:
+ ipstat.ips_tooshort++;
+ goto bad;
+ }
+ if (m->m_pkthdr.len > ip->ip_len) {
+ if (m->m_len == m->m_pkthdr.len) {
+ m->m_len = ip->ip_len;
+ m->m_pkthdr.len = ip->ip_len;
+ } else
+ m_adj(m, ip->ip_len - m->m_pkthdr.len);
+ }
+ /*
+ * IpHack's section.
+ * Right now when no processing on packet has done
+ * and it is still fresh out of network we do our black
+ * deals with it.
+ * - Firewall: deny/allow/divert
+ * - Xlate: translate packet's addr/port (NAT).
+ * - Wrap: fake packet's addr/port <unimpl.>
+ * - Encapsulate: put it in another IP and send out. <unimp.>
+ */
+
+#ifdef COMPAT_IPFW
+ if (ip_fw_chk_ptr) {
+#ifdef IPDIVERT
+ u_short port;
+
+ port = (*ip_fw_chk_ptr)(&ip, hlen, NULL, ip_divert_ignore, &m);
+ ip_divert_ignore = 0;
+ if (port) { /* Divert packet */
+ frag_divert_port = port;
+ goto ours;
+ }
+#else
+ /* If ipfw says divert, we have to just drop packet */
+ if ((*ip_fw_chk_ptr)(&ip, hlen, NULL, 0, &m)) {
+ m_freem(m);
+ m = NULL;
+ }
+#endif
+ if (!m)
+ return;
+ }
+
+ if (ip_nat_ptr && !(*ip_nat_ptr)(&ip, &m, m->m_pkthdr.rcvif, IP_NAT_IN))
+ return;
+#endif
+
+ /*
+ * Process options and, if not destined for us,
+ * ship it on. ip_dooptions returns 1 when an
+ * error was detected (causing an icmp message
+ * to be sent and the original packet to be freed).
+ */
+ ip_nhops = 0; /* for source routed packets */
+ if (hlen > sizeof (struct ip) && ip_dooptions(m))
+ return;
+
+ /* greedy RSVP, snatches any PATH packet of the RSVP protocol and no
+ * matter if it is destined to another node, or whether it is
+ * a multicast one, RSVP wants it! and prevents it from being forwarded
+ * anywhere else. Also checks if the rsvp daemon is running before
+ * grabbing the packet.
+ */
+ if (rsvp_on && ip->ip_p==IPPROTO_RSVP)
+ goto ours;
+
+ /*
+ * Check our list of addresses, to see if the packet is for us.
+ */
+ for (ia = in_ifaddr; ia; ia = ia->ia_next) {
+#define satosin(sa) ((struct sockaddr_in *)(sa))
+
+ if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr)
+ goto ours;
+#ifdef BOOTP_COMPAT
+ if (IA_SIN(ia)->sin_addr.s_addr == INADDR_ANY)
+ goto ours;
+#endif
+ if (ia->ia_ifp && ia->ia_ifp->if_flags & IFF_BROADCAST) {
+ if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr ==
+ ip->ip_dst.s_addr)
+ goto ours;
+ if (ip->ip_dst.s_addr == ia->ia_netbroadcast.s_addr)
+ goto ours;
+ }
+ }
+ if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
+ struct in_multi *inm;
+ if (ip_mrouter) {
+ /*
+ * If we are acting as a multicast router, all
+ * incoming multicast packets are passed to the
+ * kernel-level multicast forwarding function.
+ * The packet is returned (relatively) intact; if
+ * ip_mforward() returns a non-zero value, the packet
+ * must be discarded, else it may be accepted below.
+ *
+ * (The IP ident field is put in the same byte order
+ * as expected when ip_mforward() is called from
+ * ip_output().)
+ */
+ ip->ip_id = htons(ip->ip_id);
+ if (ip_mforward(ip, m->m_pkthdr.rcvif, m, 0) != 0) {
+ ipstat.ips_cantforward++;
+ m_freem(m);
+ return;
+ }
+ ip->ip_id = ntohs(ip->ip_id);
+
+ /*
+ * The process-level routing demon needs to receive
+ * all multicast IGMP packets, whether or not this
+ * host belongs to their destination groups.
+ */
+ if (ip->ip_p == IPPROTO_IGMP)
+ goto ours;
+ ipstat.ips_forward++;
+ }
+ /*
+ * See if we belong to the destination multicast group on the
+ * arrival interface.
+ */
+ IN_LOOKUP_MULTI(ip->ip_dst, m->m_pkthdr.rcvif, inm);
+ if (inm == NULL) {
+ ipstat.ips_cantforward++;
+ m_freem(m);
+ return;
+ }
+ goto ours;
+ }
+ if (ip->ip_dst.s_addr == (u_long)INADDR_BROADCAST)
+ goto ours;
+ if (ip->ip_dst.s_addr == INADDR_ANY)
+ goto ours;
+
+ /*
+ * Not for us; forward if possible and desirable.
+ */
+ if (ipforwarding == 0) {
+ ipstat.ips_cantforward++;
+ m_freem(m);
+ } else
+ ip_forward(m, 0);
+ return;
+
+ours:
+
+ /*
+ * If offset or IP_MF are set, must reassemble.
+ * Otherwise, nothing need be done.
+ * (We could look in the reassembly queue to see
+ * if the packet was previously fragmented,
+ * but it's not worth the time; just let them time out.)
+ */
+ if (ip->ip_off &~ (IP_DF | IP_RF)) {
+ if (m->m_flags & M_EXT) { /* XXX */
+ if ((m = m_pullup(m, sizeof (struct ip))) == 0) {
+ ipstat.ips_toosmall++;
+#ifdef IPDIVERT
+ frag_divert_port = 0;
+#endif
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ }
+ sum = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
+ /*
+ * Look for queue of fragments
+ * of this datagram.
+ */
+ for (fp = ipq[sum].next; fp != &ipq[sum]; fp = fp->next)
+ if (ip->ip_id == fp->ipq_id &&
+ ip->ip_src.s_addr == fp->ipq_src.s_addr &&
+ ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
+ ip->ip_p == fp->ipq_p)
+ goto found;
+
+ fp = 0;
+
+ /* check if there's a place for the new queue */
+ if (nipq > maxnipq) {
+ /*
+ * drop something from the tail of the current queue
+ * before proceeding further
+ */
+ if (ipq[sum].prev == &ipq[sum]) { /* gak */
+ for (i = 0; i < IPREASS_NHASH; i++) {
+ if (ipq[i].prev != &ipq[i]) {
+ ip_freef(ipq[i].prev);
+ break;
+ }
+ }
+ } else
+ ip_freef(ipq[sum].prev);
+ }
+found:
+ /*
+ * Adjust ip_len to not reflect header,
+ * set ip_mff if more fragments are expected,
+ * convert offset of this to bytes.
+ */
+ ip->ip_len -= hlen;
+ ((struct ipasfrag *)ip)->ipf_mff &= ~1;
+ if (ip->ip_off & IP_MF)
+ ((struct ipasfrag *)ip)->ipf_mff |= 1;
+ ip->ip_off <<= 3;
+
+ /*
+ * If datagram marked as having more fragments
+ * or if this is not the first fragment,
+ * attempt reassembly; if it succeeds, proceed.
+ */
+ if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) {
+ ipstat.ips_fragments++;
+ ip = ip_reass((struct ipasfrag *)ip, fp, &ipq[sum]);
+ if (ip == 0)
+ return;
+ ipstat.ips_reassembled++;
+ m = dtom(ip);
+#ifdef IPDIVERT
+ if (frag_divert_port) {
+ ip->ip_len += hlen;
+ HTONS(ip->ip_len);
+ HTONS(ip->ip_off);
+ HTONS(ip->ip_id);
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum_hdr(ip);
+ NTOHS(ip->ip_id);
+ NTOHS(ip->ip_off);
+ NTOHS(ip->ip_len);
+ ip->ip_len -= hlen;
+ }
+#endif
+ } else
+ if (fp)
+ ip_freef(fp);
+ } else
+ ip->ip_len -= hlen;
+
+#ifdef IPDIVERT
+ /*
+ * Divert reassembled packets to the divert protocol if required
+ */
+ if (frag_divert_port) {
+ ipstat.ips_delivered++;
+ ip_divert_port = frag_divert_port;
+ frag_divert_port = 0;
+ (*inetsw[ip_protox[IPPROTO_DIVERT]].pr_input)(m, hlen);
+ return;
+ }
+
+ /* Don't let packets divert themselves */
+ if (ip->ip_p == IPPROTO_DIVERT) {
+ ipstat.ips_noproto++;
+ goto bad;
+ }
+#endif
+
+ /*
+ * Switch out to protocol's input routine.
+ */
+ ipstat.ips_delivered++;
+ (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen);
+ return;
+bad:
+ m_freem(m);
+}
+
+/*
+ * IP software interrupt routine - to go away sometime soon
+ */
+void
+ipintr(void)
+{
+ int s;
+ struct mbuf *m;
+
+ while(1) {
+ s = splimp();
+ IF_DEQUEUE(&ipintrq, m);
+ splx(s);
+ if (m == 0)
+ return;
+ ip_input(m);
+ }
+}
+
+NETISR_SET(NETISR_IP, ipintr);
+
+/*
+ * Take incoming datagram fragment and try to
+ * reassemble it into whole datagram. If a chain for
+ * reassembly of this datagram already exists, then it
+ * is given as fp; otherwise have to make a chain.
+ */
+static struct ip *
+ip_reass(ip, fp, where)
+ register struct ipasfrag *ip;
+ register struct ipq *fp;
+ struct ipq *where;
+{
+ register struct mbuf *m = dtom(ip);
+ register struct ipasfrag *q;
+ struct mbuf *t;
+ int hlen = ip->ip_hl << 2;
+ int i, next;
+
+ /*
+ * Presence of header sizes in mbufs
+ * would confuse code below.
+ */
+ m->m_data += hlen;
+ m->m_len -= hlen;
+
+ /*
+ * If first fragment to arrive, create a reassembly queue.
+ */
+ if (fp == 0) {
+ if ((t = m_get(M_DONTWAIT, MT_FTABLE)) == NULL)
+ goto dropfrag;
+ fp = mtod(t, struct ipq *);
+ insque(fp, where);
+ nipq++;
+ fp->ipq_ttl = IPFRAGTTL;
+ fp->ipq_p = ip->ip_p;
+ fp->ipq_id = ip->ip_id;
+ fp->ipq_next = fp->ipq_prev = (struct ipasfrag *)fp;
+ fp->ipq_src = ((struct ip *)ip)->ip_src;
+ fp->ipq_dst = ((struct ip *)ip)->ip_dst;
+#ifdef IPDIVERT
+ fp->ipq_divert = 0;
+#endif
+ q = (struct ipasfrag *)fp;
+ goto insert;
+ }
+
+ /*
+ * Find a segment which begins after this one does.
+ */
+ for (q = fp->ipq_next; q != (struct ipasfrag *)fp; q = q->ipf_next)
+ if (q->ip_off > ip->ip_off)
+ break;
+
+ /*
+ * If there is a preceding segment, it may provide some of
+ * our data already. If so, drop the data from the incoming
+ * segment. If it provides all of our data, drop us.
+ */
+ if (q->ipf_prev != (struct ipasfrag *)fp) {
+ i = q->ipf_prev->ip_off + q->ipf_prev->ip_len - ip->ip_off;
+ if (i > 0) {
+ if (i >= ip->ip_len)
+ goto dropfrag;
+ m_adj(dtom(ip), i);
+ ip->ip_off += i;
+ ip->ip_len -= i;
+ }
+ }
+
+ /*
+ * While we overlap succeeding segments trim them or,
+ * if they are completely covered, dequeue them.
+ */
+ while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) {
+ struct mbuf *m0;
+
+ i = (ip->ip_off + ip->ip_len) - q->ip_off;
+ if (i < q->ip_len) {
+ q->ip_len -= i;
+ q->ip_off += i;
+ m_adj(dtom(q), i);
+ break;
+ }
+ m0 = dtom(q);
+ q = q->ipf_next;
+ ip_deq(q->ipf_prev);
+ m_freem(m0);
+ }
+
+insert:
+
+#ifdef IPDIVERT
+ /*
+ * Any fragment diverting causes the whole packet to divert
+ */
+ if (frag_divert_port != 0)
+ fp->ipq_divert = frag_divert_port;
+ frag_divert_port = 0;
+#endif
+
+ /*
+ * Stick new segment in its place;
+ * check for complete reassembly.
+ */
+ ip_enq(ip, q->ipf_prev);
+ next = 0;
+ for (q = fp->ipq_next; q != (struct ipasfrag *)fp; q = q->ipf_next) {
+ if (q->ip_off != next)
+ return (0);
+ next += q->ip_len;
+ }
+ if (q->ipf_prev->ipf_mff & 1)
+ return (0);
+
+ /*
+ * Reassembly is complete. Make sure the packet is a sane size.
+ */
+ if (next + (IP_VHL_HL(((struct ip *)fp->ipq_next)->ip_vhl) << 2)
+ > IP_MAXPACKET) {
+ ipstat.ips_toolong++;
+ ip_freef(fp);
+ return (0);
+ }
+
+ /*
+ * Concatenate fragments.
+ */
+ q = fp->ipq_next;
+ m = dtom(q);
+ t = m->m_next;
+ m->m_next = 0;
+ m_cat(m, t);
+ q = q->ipf_next;
+ while (q != (struct ipasfrag *)fp) {
+ t = dtom(q);
+ q = q->ipf_next;
+ m_cat(m, t);
+ }
+
+#ifdef IPDIVERT
+ /*
+ * Record divert port for packet, if any
+ */
+ frag_divert_port = fp->ipq_divert;
+#endif
+
+ /*
+ * Create header for new ip packet by
+ * modifying header of first packet;
+ * dequeue and discard fragment reassembly header.
+ * Make header visible.
+ */
+ ip = fp->ipq_next;
+ ip->ip_len = next;
+ ip->ipf_mff &= ~1;
+ ((struct ip *)ip)->ip_src = fp->ipq_src;
+ ((struct ip *)ip)->ip_dst = fp->ipq_dst;
+ remque(fp);
+ nipq--;
+ (void) m_free(dtom(fp));
+ m = dtom(ip);
+ m->m_len += (ip->ip_hl << 2);
+ m->m_data -= (ip->ip_hl << 2);
+ /* some debugging cruft by sklower, below, will go away soon */
+ if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */
+ register int plen = 0;
+ for (t = m; m; m = m->m_next)
+ plen += m->m_len;
+ t->m_pkthdr.len = plen;
+ }
+ return ((struct ip *)ip);
+
+dropfrag:
+ ipstat.ips_fragdropped++;
+ m_freem(m);
+ return (0);
+}
+
+/*
+ * Free a fragment reassembly header and all
+ * associated datagrams.
+ */
+static void
+ip_freef(fp)
+ struct ipq *fp;
+{
+ register struct ipasfrag *q, *p;
+
+ for (q = fp->ipq_next; q != (struct ipasfrag *)fp; q = p) {
+ p = q->ipf_next;
+ ip_deq(q);
+ m_freem(dtom(q));
+ }
+ remque(fp);
+ (void) m_free(dtom(fp));
+ nipq--;
+}
+
+/*
+ * Put an ip fragment on a reassembly chain.
+ * Like insque, but pointers in middle of structure.
+ */
+static void
+ip_enq(p, prev)
+ register struct ipasfrag *p, *prev;
+{
+
+ p->ipf_prev = prev;
+ p->ipf_next = prev->ipf_next;
+ prev->ipf_next->ipf_prev = p;
+ prev->ipf_next = p;
+}
+
+/*
+ * To ip_enq as remque is to insque.
+ */
+static void
+ip_deq(p)
+ register struct ipasfrag *p;
+{
+
+ p->ipf_prev->ipf_next = p->ipf_next;
+ p->ipf_next->ipf_prev = p->ipf_prev;
+}
+
+/*
+ * IP timer processing;
+ * if a timer expires on a reassembly
+ * queue, discard it.
+ */
+void
+ip_slowtimo()
+{
+ register struct ipq *fp;
+ int s = splnet();
+ int i;
+
+ for (i = 0; i < IPREASS_NHASH; i++) {
+ fp = ipq[i].next;
+ if (fp == 0)
+ continue;
+ while (fp != &ipq[i]) {
+ --fp->ipq_ttl;
+ fp = fp->next;
+ if (fp->prev->ipq_ttl == 0) {
+ ipstat.ips_fragtimeout++;
+ ip_freef(fp->prev);
+ }
+ }
+ }
+ splx(s);
+}
+
+/*
+ * Drain off all datagram fragments.
+ */
+void
+ip_drain()
+{
+ int i;
+
+ for (i = 0; i < IPREASS_NHASH; i++) {
+ while (ipq[i].next != &ipq[i]) {
+ ipstat.ips_fragdropped++;
+ ip_freef(ipq[i].next);
+ }
+ }
+ in_rtqdrain();
+}
+
+/*
+ * Do option processing on a datagram,
+ * possibly discarding it if bad options are encountered,
+ * or forwarding it if source-routed.
+ * Returns 1 if packet has been forwarded/freed,
+ * 0 if the packet should be processed further.
+ */
+static int
+ip_dooptions(m)
+ struct mbuf *m;
+{
+ register struct ip *ip = mtod(m, struct ip *);
+ register u_char *cp;
+ register struct ip_timestamp *ipt;
+ register struct in_ifaddr *ia;
+ int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0;
+ struct in_addr *sin, dst;
+ n_time ntime;
+
+ dst = ip->ip_dst;
+ cp = (u_char *)(ip + 1);
+ cnt = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof (struct ip);
+ for (; cnt > 0; cnt -= optlen, cp += optlen) {
+ opt = cp[IPOPT_OPTVAL];
+ if (opt == IPOPT_EOL)
+ break;
+ if (opt == IPOPT_NOP)
+ optlen = 1;
+ else {
+ optlen = cp[IPOPT_OLEN];
+ if (optlen <= 0 || optlen > cnt) {
+ code = &cp[IPOPT_OLEN] - (u_char *)ip;
+ goto bad;
+ }
+ }
+ switch (opt) {
+
+ default:
+ break;
+
+ /*
+ * Source routing with record.
+ * Find interface with current destination address.
+ * If none on this machine then drop if strictly routed,
+ * or do nothing if loosely routed.
+ * Record interface address and bring up next address
+ * component. If strictly routed make sure next
+ * address is on directly accessible net.
+ */
+ case IPOPT_LSRR:
+ case IPOPT_SSRR:
+ if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
+ code = &cp[IPOPT_OFFSET] - (u_char *)ip;
+ goto bad;
+ }
+ ipaddr.sin_addr = ip->ip_dst;
+ ia = (struct in_ifaddr *)
+ ifa_ifwithaddr((struct sockaddr *)&ipaddr);
+ if (ia == 0) {
+ if (opt == IPOPT_SSRR) {
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_SRCFAIL;
+ goto bad;
+ }
+ if (!ip_dosourceroute)
+ goto nosourcerouting;
+ /*
+ * Loose routing, and not at next destination
+ * yet; nothing to do except forward.
+ */
+ break;
+ }
+ off--; /* 0 origin */
+ if (off > optlen - sizeof(struct in_addr)) {
+ /*
+ * End of source route. Should be for us.
+ */
+ if (!ip_acceptsourceroute)
+ goto nosourcerouting;
+ save_rte(cp, ip->ip_src);
+ break;
+ }
+
+ if (!ip_dosourceroute) {
+ char buf[4*sizeof "123"];
+
+nosourcerouting:
+ strcpy(buf, inet_ntoa(ip->ip_dst));
+ log(LOG_WARNING,
+ "attempted source route from %s to %s\n",
+ inet_ntoa(ip->ip_src), buf);
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_SRCFAIL;
+ goto bad;
+ }
+
+ /*
+ * locate outgoing interface
+ */
+ (void)memcpy(&ipaddr.sin_addr, cp + off,
+ sizeof(ipaddr.sin_addr));
+
+ if (opt == IPOPT_SSRR) {
+#define INA struct in_ifaddr *
+#define SA struct sockaddr *
+ if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0)
+ ia = (INA)ifa_ifwithnet((SA)&ipaddr);
+ } else
+ ia = ip_rtaddr(ipaddr.sin_addr);
+ if (ia == 0) {
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_SRCFAIL;
+ goto bad;
+ }
+ ip->ip_dst = ipaddr.sin_addr;
+ (void)memcpy(cp + off, &(IA_SIN(ia)->sin_addr),
+ sizeof(struct in_addr));
+ cp[IPOPT_OFFSET] += sizeof(struct in_addr);
+ /*
+ * Let ip_intr's mcast routing check handle mcast pkts
+ */
+ forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr));
+ break;
+
+ case IPOPT_RR:
+ if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
+ code = &cp[IPOPT_OFFSET] - (u_char *)ip;
+ goto bad;
+ }
+ /*
+ * If no space remains, ignore.
+ */
+ off--; /* 0 origin */
+ if (off > optlen - sizeof(struct in_addr))
+ break;
+ (void)memcpy(&ipaddr.sin_addr, &ip->ip_dst,
+ sizeof(ipaddr.sin_addr));
+ /*
+ * locate outgoing interface; if we're the destination,
+ * use the incoming interface (should be same).
+ */
+ if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 &&
+ (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_HOST;
+ goto bad;
+ }
+ (void)memcpy(cp + off, &(IA_SIN(ia)->sin_addr),
+ sizeof(struct in_addr));
+ cp[IPOPT_OFFSET] += sizeof(struct in_addr);
+ break;
+
+ case IPOPT_TS:
+ code = cp - (u_char *)ip;
+ ipt = (struct ip_timestamp *)cp;
+ if (ipt->ipt_len < 5)
+ goto bad;
+ if (ipt->ipt_ptr > ipt->ipt_len - sizeof (long)) {
+ if (++ipt->ipt_oflw == 0)
+ goto bad;
+ break;
+ }
+ sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1);
+ switch (ipt->ipt_flg) {
+
+ case IPOPT_TS_TSONLY:
+ break;
+
+ case IPOPT_TS_TSANDADDR:
+ if (ipt->ipt_ptr + sizeof(n_time) +
+ sizeof(struct in_addr) > ipt->ipt_len)
+ goto bad;
+ ipaddr.sin_addr = dst;
+ ia = (INA)ifaof_ifpforaddr((SA)&ipaddr,
+ m->m_pkthdr.rcvif);
+ if (ia == 0)
+ continue;
+ (void)memcpy(sin, &IA_SIN(ia)->sin_addr,
+ sizeof(struct in_addr));
+ ipt->ipt_ptr += sizeof(struct in_addr);
+ break;
+
+ case IPOPT_TS_PRESPEC:
+ if (ipt->ipt_ptr + sizeof(n_time) +
+ sizeof(struct in_addr) > ipt->ipt_len)
+ goto bad;
+ (void)memcpy(&ipaddr.sin_addr, sin,
+ sizeof(struct in_addr));
+ if (ifa_ifwithaddr((SA)&ipaddr) == 0)
+ continue;
+ ipt->ipt_ptr += sizeof(struct in_addr);
+ break;
+
+ default:
+ goto bad;
+ }
+ ntime = iptime();
+ (void)memcpy(cp + ipt->ipt_ptr - 1, &ntime,
+ sizeof(n_time));
+ ipt->ipt_ptr += sizeof(n_time);
+ }
+ }
+ if (forward && ipforwarding) {
+ ip_forward(m, 1);
+ return (1);
+ }
+ return (0);
+bad:
+ ip->ip_len -= IP_VHL_HL(ip->ip_vhl) << 2; /* XXX icmp_error adds in hdr length */
+ icmp_error(m, type, code, 0, 0);
+ ipstat.ips_badoptions++;
+ return (1);
+}
+
+/*
+ * Given address of next destination (final or next hop),
+ * return internet address info of interface to be used to get there.
+ */
+static struct in_ifaddr *
+ip_rtaddr(dst)
+ struct in_addr dst;
+{
+ register struct sockaddr_in *sin;
+
+ sin = (struct sockaddr_in *) &ipforward_rt.ro_dst;
+
+ if (ipforward_rt.ro_rt == 0 || dst.s_addr != sin->sin_addr.s_addr) {
+ if (ipforward_rt.ro_rt) {
+ RTFREE(ipforward_rt.ro_rt);
+ ipforward_rt.ro_rt = 0;
+ }
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_addr = dst;
+
+ rtalloc_ign(&ipforward_rt, RTF_PRCLONING);
+ }
+ if (ipforward_rt.ro_rt == 0)
+ return ((struct in_ifaddr *)0);
+ return ((struct in_ifaddr *) ipforward_rt.ro_rt->rt_ifa);
+}
+
+/*
+ * Save incoming source route for use in replies,
+ * to be picked up later by ip_srcroute if the receiver is interested.
+ */
+void
+save_rte(option, dst)
+ u_char *option;
+ struct in_addr dst;
+{
+ unsigned olen;
+
+ olen = option[IPOPT_OLEN];
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf("save_rte: olen %d\n", olen);
+#endif
+ if (olen > sizeof(ip_srcrt) - (1 + sizeof(dst)))
+ return;
+ bcopy(option, ip_srcrt.srcopt, olen);
+ ip_nhops = (olen - IPOPT_OFFSET - 1) / sizeof(struct in_addr);
+ ip_srcrt.dst = dst;
+}
+
+/*
+ * Retrieve incoming source route for use in replies,
+ * in the same form used by setsockopt.
+ * The first hop is placed before the options, will be removed later.
+ */
+struct mbuf *
+ip_srcroute()
+{
+ register struct in_addr *p, *q;
+ register struct mbuf *m;
+
+ if (ip_nhops == 0)
+ return ((struct mbuf *)0);
+ m = m_get(M_DONTWAIT, MT_SOOPTS);
+ if (m == 0)
+ return ((struct mbuf *)0);
+
+#define OPTSIZ (sizeof(ip_srcrt.nop) + sizeof(ip_srcrt.srcopt))
+
+ /* length is (nhops+1)*sizeof(addr) + sizeof(nop + srcrt header) */
+ m->m_len = ip_nhops * sizeof(struct in_addr) + sizeof(struct in_addr) +
+ OPTSIZ;
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf("ip_srcroute: nhops %d mlen %d", ip_nhops, m->m_len);
+#endif
+
+ /*
+ * First save first hop for return route
+ */
+ p = &ip_srcrt.route[ip_nhops - 1];
+ *(mtod(m, struct in_addr *)) = *p--;
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf(" hops %lx", ntohl(mtod(m, struct in_addr *)->s_addr));
+#endif
+
+ /*
+ * Copy option fields and padding (nop) to mbuf.
+ */
+ ip_srcrt.nop = IPOPT_NOP;
+ ip_srcrt.srcopt[IPOPT_OFFSET] = IPOPT_MINOFF;
+ (void)memcpy(mtod(m, caddr_t) + sizeof(struct in_addr),
+ &ip_srcrt.nop, OPTSIZ);
+ q = (struct in_addr *)(mtod(m, caddr_t) +
+ sizeof(struct in_addr) + OPTSIZ);
+#undef OPTSIZ
+ /*
+ * Record return path as an IP source route,
+ * reversing the path (pointers are now aligned).
+ */
+ while (p >= ip_srcrt.route) {
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf(" %lx", ntohl(q->s_addr));
+#endif
+ *q++ = *p--;
+ }
+ /*
+ * Last hop goes to final destination.
+ */
+ *q = ip_srcrt.dst;
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf(" %lx\n", ntohl(q->s_addr));
+#endif
+ return (m);
+}
+
+/*
+ * Strip out IP options, at higher
+ * level protocol in the kernel.
+ * Second argument is buffer to which options
+ * will be moved, and return value is their length.
+ * XXX should be deleted; last arg currently ignored.
+ */
+void
+ip_stripoptions(m, mopt)
+ register struct mbuf *m;
+ struct mbuf *mopt;
+{
+ register int i;
+ struct ip *ip = mtod(m, struct ip *);
+ register caddr_t opts;
+ int olen;
+
+ olen = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof (struct ip);
+ opts = (caddr_t)(ip + 1);
+ i = m->m_len - (sizeof (struct ip) + olen);
+ bcopy(opts + olen, opts, (unsigned)i);
+ m->m_len -= olen;
+ if (m->m_flags & M_PKTHDR)
+ m->m_pkthdr.len -= olen;
+ ip->ip_vhl = IP_MAKE_VHL(IPVERSION, sizeof(struct ip) >> 2);
+}
+
+u_char inetctlerrmap[PRC_NCMDS] = {
+ 0, 0, 0, 0,
+ 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH,
+ EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED,
+ EMSGSIZE, EHOSTUNREACH, 0, 0,
+ 0, 0, 0, 0,
+ ENOPROTOOPT
+};
+
+/*
+ * Forward a packet. If some error occurs return the sender
+ * an icmp packet. Note we can't always generate a meaningful
+ * icmp message because icmp doesn't have a large enough repertoire
+ * of codes and types.
+ *
+ * If not forwarding, just drop the packet. This could be confusing
+ * if ipforwarding was zero but some routing protocol was advancing
+ * us as a gateway to somewhere. However, we must let the routing
+ * protocol deal with that.
+ *
+ * The srcrt parameter indicates whether the packet is being forwarded
+ * via a source route.
+ */
+static void
+ip_forward(m, srcrt)
+ struct mbuf *m;
+ int srcrt;
+{
+ register struct ip *ip = mtod(m, struct ip *);
+ register struct sockaddr_in *sin;
+ register struct rtentry *rt;
+ int error, type = 0, code = 0;
+ struct mbuf *mcopy;
+ n_long dest;
+ struct ifnet *destifp;
+
+ dest = 0;
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf("forward: src %lx dst %lx ttl %x\n",
+ ip->ip_src.s_addr, ip->ip_dst.s_addr, ip->ip_ttl);
+#endif
+
+
+ if (m->m_flags & M_BCAST || in_canforward(ip->ip_dst) == 0) {
+ ipstat.ips_cantforward++;
+ m_freem(m);
+ return;
+ }
+ HTONS(ip->ip_id);
+ if (ip->ip_ttl <= IPTTLDEC) {
+ icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0);
+ return;
+ }
+ ip->ip_ttl -= IPTTLDEC;
+
+ sin = (struct sockaddr_in *)&ipforward_rt.ro_dst;
+ if ((rt = ipforward_rt.ro_rt) == 0 ||
+ ip->ip_dst.s_addr != sin->sin_addr.s_addr) {
+ if (ipforward_rt.ro_rt) {
+ RTFREE(ipforward_rt.ro_rt);
+ ipforward_rt.ro_rt = 0;
+ }
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_addr = ip->ip_dst;
+
+ rtalloc_ign(&ipforward_rt, RTF_PRCLONING);
+ if (ipforward_rt.ro_rt == 0) {
+ icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
+ return;
+ }
+ rt = ipforward_rt.ro_rt;
+ }
+
+ /*
+ * Save at most 64 bytes of the packet in case
+ * we need to generate an ICMP message to the src.
+ */
+ mcopy = m_copy(m, 0, imin((int)ip->ip_len, 64));
+
+ /*
+ * If forwarding packet using same interface that it came in on,
+ * perhaps should send a redirect to sender to shortcut a hop.
+ * Only send redirect if source is sending directly to us,
+ * and if packet was not source routed (or has any options).
+ * Also, don't send redirect if forwarding using a default route
+ * or a route modified by a redirect.
+ */
+#define satosin(sa) ((struct sockaddr_in *)(sa))
+ if (rt->rt_ifp == m->m_pkthdr.rcvif &&
+ (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
+ satosin(rt_key(rt))->sin_addr.s_addr != 0 &&
+ ipsendredirects && !srcrt) {
+#define RTA(rt) ((struct in_ifaddr *)(rt->rt_ifa))
+ u_long src = ntohl(ip->ip_src.s_addr);
+
+ if (RTA(rt) &&
+ (src & RTA(rt)->ia_subnetmask) == RTA(rt)->ia_subnet) {
+ if (rt->rt_flags & RTF_GATEWAY)
+ dest = satosin(rt->rt_gateway)->sin_addr.s_addr;
+ else
+ dest = ip->ip_dst.s_addr;
+ /* Router requirements says to only send host redirects */
+ type = ICMP_REDIRECT;
+ code = ICMP_REDIRECT_HOST;
+#ifdef DIAGNOSTIC
+ if (ipprintfs)
+ printf("redirect (%d) to %lx\n", code, (u_long)dest);
+#endif
+ }
+ }
+
+ error = ip_output(m, (struct mbuf *)0, &ipforward_rt,
+ IP_FORWARDING, 0);
+ if (error)
+ ipstat.ips_cantforward++;
+ else {
+ ipstat.ips_forward++;
+ if (type)
+ ipstat.ips_redirectsent++;
+ else {
+ if (mcopy)
+ m_freem(mcopy);
+ return;
+ }
+ }
+ if (mcopy == NULL)
+ return;
+ destifp = NULL;
+
+ switch (error) {
+
+ case 0: /* forwarded, but need redirect */
+ /* type, code set above */
+ break;
+
+ case ENETUNREACH: /* shouldn't happen, checked above */
+ case EHOSTUNREACH:
+ case ENETDOWN:
+ case EHOSTDOWN:
+ default:
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_HOST;
+ break;
+
+ case EMSGSIZE:
+ type = ICMP_UNREACH;
+ code = ICMP_UNREACH_NEEDFRAG;
+ if (ipforward_rt.ro_rt)
+ destifp = ipforward_rt.ro_rt->rt_ifp;
+ ipstat.ips_cantfrag++;
+ break;
+
+ case ENOBUFS:
+ type = ICMP_SOURCEQUENCH;
+ code = 0;
+ break;
+ }
+ icmp_error(mcopy, type, code, dest, destifp);
+}
+
+void
+ip_savecontrol(inp, mp, ip, m)
+ register struct inpcb *inp;
+ register struct mbuf **mp;
+ register struct ip *ip;
+ register struct mbuf *m;
+{
+ if (inp->inp_socket->so_options & SO_TIMESTAMP) {
+ struct timeval tv;
+
+ microtime(&tv);
+ *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
+ SCM_TIMESTAMP, SOL_SOCKET);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ }
+ if (inp->inp_flags & INP_RECVDSTADDR) {
+ *mp = sbcreatecontrol((caddr_t) &ip->ip_dst,
+ sizeof(struct in_addr), IP_RECVDSTADDR, IPPROTO_IP);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ }
+#ifdef notyet
+ /* XXX
+ * Moving these out of udp_input() made them even more broken
+ * than they already were.
+ */
+ /* options were tossed already */
+ if (inp->inp_flags & INP_RECVOPTS) {
+ *mp = sbcreatecontrol((caddr_t) opts_deleted_above,
+ sizeof(struct in_addr), IP_RECVOPTS, IPPROTO_IP);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ }
+ /* ip_srcroute doesn't do what we want here, need to fix */
+ if (inp->inp_flags & INP_RECVRETOPTS) {
+ *mp = sbcreatecontrol((caddr_t) ip_srcroute(),
+ sizeof(struct in_addr), IP_RECVRETOPTS, IPPROTO_IP);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ }
+#endif
+ if (inp->inp_flags & INP_RECVIF) {
+ struct sockaddr_dl sdl;
+
+ sdl.sdl_len = offsetof(struct sockaddr_dl, sdl_data[0]);
+ sdl.sdl_family = AF_LINK;
+ sdl.sdl_index = m->m_pkthdr.rcvif ?
+ m->m_pkthdr.rcvif->if_index : 0;
+ sdl.sdl_nlen = sdl.sdl_alen = sdl.sdl_slen = 0;
+ *mp = sbcreatecontrol((caddr_t) &sdl, sdl.sdl_len,
+ IP_RECVIF, IPPROTO_IP);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ }
+}
+
+int
+ip_rsvp_init(struct socket *so)
+{
+ if (so->so_type != SOCK_RAW ||
+ so->so_proto->pr_protocol != IPPROTO_RSVP)
+ return EOPNOTSUPP;
+
+ if (ip_rsvpd != NULL)
+ return EADDRINUSE;
+
+ ip_rsvpd = so;
+ /*
+ * This may seem silly, but we need to be sure we don't over-increment
+ * the RSVP counter, in case something slips up.
+ */
+ if (!ip_rsvp_on) {
+ ip_rsvp_on = 1;
+ rsvp_on++;
+ }
+
+ return 0;
+}
+
+int
+ip_rsvp_done(void)
+{
+ ip_rsvpd = NULL;
+ /*
+ * This may seem silly, but we need to be sure we don't over-decrement
+ * the RSVP counter, in case something slips up.
+ */
+ if (ip_rsvp_on) {
+ ip_rsvp_on = 0;
+ rsvp_on--;
+ }
+ return 0;
+}
diff --git a/cpukit/libnetworking/netinet/ip_mroute.c b/cpukit/libnetworking/netinet/ip_mroute.c
new file mode 100644
index 0000000000..a0fff67646
--- /dev/null
+++ b/cpukit/libnetworking/netinet/ip_mroute.c
@@ -0,0 +1,2303 @@
+/*
+ * IP multicast forwarding procedures
+ *
+ * Written by David Waitzman, BBN Labs, August 1988.
+ * Modified by Steve Deering, Stanford, February 1989.
+ * Modified by Mark J. Steiglitz, Stanford, May, 1991
+ * Modified by Van Jacobson, LBL, January 1993
+ * Modified by Ajit Thyagarajan, PARC, August 1993
+ * Modified by Bill Fenner, PARC, April 1995
+ *
+ * MROUTING Revision: 3.5
+ * $Id$
+ */
+
+#include "opt_mrouting.h"
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#include <sys/ioctl.h>
+#include <sys/syslog.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/igmp.h>
+#include <netinet/igmp_var.h>
+#include <netinet/ip_mroute.h>
+#include <netinet/udp.h>
+
+#ifndef NTOHL
+#if BYTE_ORDER != BIG_ENDIAN
+#define NTOHL(d) ((d) = ntohl((d)))
+#define NTOHS(d) ((d) = ntohs((u_short)(d)))
+#define HTONL(d) ((d) = htonl((d)))
+#define HTONS(d) ((d) = htons((u_short)(d)))
+#else
+#define NTOHL(d)
+#define NTOHS(d)
+#define HTONL(d)
+#define HTONS(d)
+#endif
+#endif
+
+#ifndef MROUTING
+extern u_long _ip_mcast_src __P((int vifi));
+extern int _ip_mforward __P((struct ip *ip, struct ifnet *ifp,
+ struct mbuf *m, struct ip_moptions *imo));
+extern int _ip_mrouter_done __P((void));
+extern int _ip_mrouter_get __P((int cmd, struct socket *so,
+ struct mbuf **m));
+extern int _ip_mrouter_set __P((int cmd, struct socket *so,
+ struct mbuf *m));
+extern int _mrt_ioctl __P((int req, caddr_t data, struct proc *p));
+
+/*
+ * Dummy routines and globals used when multicast routing is not compiled in.
+ */
+
+struct socket *ip_mrouter = NULL;
+/* static u_int ip_mrtproto = 0; */
+/* static struct mrtstat mrtstat; */
+u_int rsvpdebug = 0;
+
+int
+_ip_mrouter_set(cmd, so, m)
+ int cmd;
+ struct socket *so;
+ struct mbuf *m;
+{
+ return(EOPNOTSUPP);
+}
+
+int (*ip_mrouter_set)(int, struct socket *, struct mbuf *) = _ip_mrouter_set;
+
+
+int
+_ip_mrouter_get(cmd, so, m)
+ int cmd;
+ struct socket *so;
+ struct mbuf **m;
+{
+ return(EOPNOTSUPP);
+}
+
+int (*ip_mrouter_get)(int, struct socket *, struct mbuf **) = _ip_mrouter_get;
+
+int
+_ip_mrouter_done()
+{
+ return(0);
+}
+
+int (*ip_mrouter_done)(void) = _ip_mrouter_done;
+
+int
+_ip_mforward(ip, ifp, m, imo)
+ struct ip *ip;
+ struct ifnet *ifp;
+ struct mbuf *m;
+ struct ip_moptions *imo;
+{
+ return(0);
+}
+
+int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
+ struct ip_moptions *) = _ip_mforward;
+
+int
+_mrt_ioctl(int req, caddr_t data, struct proc *p)
+{
+ return EOPNOTSUPP;
+}
+
+int (*mrt_ioctl)(int, caddr_t, struct proc *) = _mrt_ioctl;
+
+void
+rsvp_input(m, iphlen) /* XXX must fixup manually */
+ struct mbuf *m;
+ int iphlen;
+{
+ /* Can still get packets with rsvp_on = 0 if there is a local member
+ * of the group to which the RSVP packet is addressed. But in this
+ * case we want to throw the packet away.
+ */
+ if (!rsvp_on) {
+ m_freem(m);
+ return;
+ }
+
+ if (ip_rsvpd != NULL) {
+ if (rsvpdebug)
+ printf("rsvp_input: Sending packet up old-style socket\n");
+ rip_input(m, iphlen);
+ return;
+ }
+ /* Drop the packet */
+ m_freem(m);
+}
+
+void ipip_input(struct mbuf *m, int iphlen) { /* XXX must fixup manually */
+ rip_input(m, iphlen);
+}
+
+int (*legal_vif_num)(int) = 0;
+
+/*
+ * This should never be called, since IP_MULTICAST_VIF should fail, but
+ * just in case it does get called, the code a little lower in ip_output
+ * will assign the packet a local address.
+ */
+u_long
+_ip_mcast_src(int vifi) { return INADDR_ANY; }
+u_long (*ip_mcast_src)(int) = _ip_mcast_src;
+
+int
+ip_rsvp_vif_init(so, m)
+ struct socket *so;
+ struct mbuf *m;
+{
+ return(EINVAL);
+}
+
+int
+ip_rsvp_vif_done(so, m)
+ struct socket *so;
+ struct mbuf *m;
+{
+ return(EINVAL);
+}
+
+void
+ip_rsvp_force_done(so)
+ struct socket *so;
+{
+ return;
+}
+
+#else /* MROUTING */
+
+#define M_HASCL(m) ((m)->m_flags & M_EXT)
+
+#define INSIZ sizeof(struct in_addr)
+#define same(a1, a2) \
+ (bcmp((caddr_t)(a1), (caddr_t)(a2), INSIZ) == 0)
+
+#define MT_MRTABLE MT_RTABLE /* since nothing else uses it */
+
+/*
+ * Globals. All but ip_mrouter and ip_mrtproto could be static,
+ * except for netstat or debugging purposes.
+ */
+#ifndef MROUTE_LKM
+struct socket *ip_mrouter = NULL;
+struct mrtstat mrtstat;
+
+int ip_mrtproto = IGMP_DVMRP; /* for netstat only */
+#else /* MROUTE_LKM */
+extern void X_ipip_input __P((struct mbuf *m, int iphlen));
+extern struct mrtstat mrtstat;
+static int ip_mrtproto;
+#endif
+
+#define NO_RTE_FOUND 0x1
+#define RTE_FOUND 0x2
+
+static struct mbuf *mfctable[MFCTBLSIZ];
+static u_char nexpire[MFCTBLSIZ];
+static struct vif viftable[MAXVIFS];
+static u_int mrtdebug = 0; /* debug level */
+#define DEBUG_MFC 0x02
+#define DEBUG_FORWARD 0x04
+#define DEBUG_EXPIRE 0x08
+#define DEBUG_XMIT 0x10
+static u_int tbfdebug = 0; /* tbf debug level */
+static u_int rsvpdebug = 0; /* rsvp debug level */
+
+#define EXPIRE_TIMEOUT (hz / 4) /* 4x / second */
+#define UPCALL_EXPIRE 6 /* number of timeouts */
+
+/*
+ * Define the token bucket filter structures
+ * tbftable -> each vif has one of these for storing info
+ */
+
+static struct tbf tbftable[MAXVIFS];
+#define TBF_REPROCESS (hz / 100) /* 100x / second */
+
+/*
+ * 'Interfaces' associated with decapsulator (so we can tell
+ * packets that went through it from ones that get reflected
+ * by a broken gateway). These interfaces are never linked into
+ * the system ifnet list & no routes point to them. I.e., packets
+ * can't be sent this way. They only exist as a placeholder for
+ * multicast source verification.
+ */
+static struct ifnet multicast_decap_if[MAXVIFS];
+
+#define ENCAP_TTL 64
+#define ENCAP_PROTO IPPROTO_IPIP /* 4 */
+
+/* prototype IP hdr for encapsulated packets */
+static struct ip multicast_encap_iphdr = {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ sizeof(struct ip) >> 2, IPVERSION,
+#else
+ IPVERSION, sizeof(struct ip) >> 2,
+#endif
+ 0, /* tos */
+ sizeof(struct ip), /* total length */
+ 0, /* id */
+ 0, /* frag offset */
+ ENCAP_TTL, ENCAP_PROTO,
+ 0, /* checksum */
+};
+
+/*
+ * Private variables.
+ */
+static vifi_t numvifs = 0;
+static int have_encap_tunnel = 0;
+
+/*
+ * one-back cache used by ipip_input to locate a tunnel's vif
+ * given a datagram's src ip address.
+ */
+static u_long last_encap_src;
+static struct vif *last_encap_vif;
+
+static u_long X_ip_mcast_src __P((int vifi));
+static int X_ip_mforward __P((struct ip *ip, struct ifnet *ifp, struct mbuf *m, struct ip_moptions *imo));
+static int X_ip_mrouter_done __P((void));
+static int X_ip_mrouter_get __P((int cmd, struct socket *so, struct mbuf **m));
+static int X_ip_mrouter_set __P((int cmd, struct socket *so, struct mbuf *m));
+static int X_legal_vif_num __P((int vif));
+static int X_mrt_ioctl __P((int cmd, caddr_t data));
+
+static int get_sg_cnt(struct sioc_sg_req *);
+static int get_vif_cnt(struct sioc_vif_req *);
+static int ip_mrouter_init(struct socket *, struct mbuf *);
+static int add_vif(struct vifctl *);
+static int del_vif(vifi_t *);
+static int add_mfc(struct mfcctl *);
+static int del_mfc(struct mfcctl *);
+static int socket_send(struct socket *, struct mbuf *, struct sockaddr_in *);
+static int get_version(struct mbuf *);
+static int get_assert(struct mbuf *);
+static int set_assert(int *);
+static void expire_upcalls(void *);
+static int ip_mdq(struct mbuf *, struct ifnet *, struct mfc *,
+ vifi_t);
+static void phyint_send(struct ip *, struct vif *, struct mbuf *);
+static void encap_send(struct ip *, struct vif *, struct mbuf *);
+static void tbf_control(struct vif *, struct mbuf *, struct ip *, u_long);
+static void tbf_queue(struct vif *, struct mbuf *);
+static void tbf_process_q(struct vif *);
+static void tbf_reprocess_q(void *);
+static int tbf_dq_sel(struct vif *, struct ip *);
+static void tbf_send_packet(struct vif *, struct mbuf *);
+static void tbf_update_tokens(struct vif *);
+static int priority(struct vif *, struct ip *);
+void multiencap_decap(struct mbuf *);
+
+/*
+ * whether or not special PIM assert processing is enabled.
+ */
+static int pim_assert;
+/*
+ * Rate limit for assert notification messages, in usec
+ */
+#define ASSERT_MSG_TIME 3000000
+
+/*
+ * Hash function for a source, group entry
+ */
+#define MFCHASH(a, g) MFCHASHMOD(((a) >> 20) ^ ((a) >> 10) ^ (a) ^ \
+ ((g) >> 20) ^ ((g) >> 10) ^ (g))
+
+/*
+ * Find a route for a given origin IP address and Multicast group address
+ * Type of service parameter to be added in the future!!!
+ */
+
+#define MFCFIND(o, g, rt) { \
+ register struct mbuf *_mb_rt = mfctable[MFCHASH(o,g)]; \
+ register struct mfc *_rt = NULL; \
+ rt = NULL; \
+ ++mrtstat.mrts_mfc_lookups; \
+ while (_mb_rt) { \
+ _rt = mtod(_mb_rt, struct mfc *); \
+ if ((_rt->mfc_origin.s_addr == o) && \
+ (_rt->mfc_mcastgrp.s_addr == g) && \
+ (_mb_rt->m_act == NULL)) { \
+ rt = _rt; \
+ break; \
+ } \
+ _mb_rt = _mb_rt->m_next; \
+ } \
+ if (rt == NULL) { \
+ ++mrtstat.mrts_mfc_misses; \
+ } \
+}
+
+
+/*
+ * Macros to compute elapsed time efficiently
+ * Borrowed from Van Jacobson's scheduling code
+ */
+#define TV_DELTA(a, b, delta) { \
+ register int xxs; \
+ \
+ delta = (a).tv_usec - (b).tv_usec; \
+ if ((xxs = (a).tv_sec - (b).tv_sec)) { \
+ switch (xxs) { \
+ case 2: \
+ delta += 1000000; \
+ /* fall through */ \
+ case 1: \
+ delta += 1000000; \
+ break; \
+ default: \
+ delta += (1000000 * xxs); \
+ } \
+ } \
+}
+
+#define TV_LT(a, b) (((a).tv_usec < (b).tv_usec && \
+ (a).tv_sec <= (b).tv_sec) || (a).tv_sec < (b).tv_sec)
+
+#ifdef UPCALL_TIMING
+u_long upcall_data[51];
+static void collate(struct timeval *);
+#endif /* UPCALL_TIMING */
+
+
+/*
+ * Handle MRT setsockopt commands to modify the multicast routing tables.
+ */
+static int
+X_ip_mrouter_set(cmd, so, m)
+ int cmd;
+ struct socket *so;
+ struct mbuf *m;
+{
+ if (cmd != MRT_INIT && so != ip_mrouter) return EACCES;
+
+ switch (cmd) {
+ case MRT_INIT: return ip_mrouter_init(so, m);
+ case MRT_DONE: return ip_mrouter_done();
+ case MRT_ADD_VIF: return add_vif (mtod(m, struct vifctl *));
+ case MRT_DEL_VIF: return del_vif (mtod(m, vifi_t *));
+ case MRT_ADD_MFC: return add_mfc (mtod(m, struct mfcctl *));
+ case MRT_DEL_MFC: return del_mfc (mtod(m, struct mfcctl *));
+ case MRT_ASSERT: return set_assert(mtod(m, int *));
+ default: return EOPNOTSUPP;
+ }
+}
+
+#ifndef MROUTE_LKM
+int (*ip_mrouter_set)(int, struct socket *, struct mbuf *) = X_ip_mrouter_set;
+#endif
+
+/*
+ * Handle MRT getsockopt commands
+ */
+static int
+X_ip_mrouter_get(cmd, so, m)
+ int cmd;
+ struct socket *so;
+ struct mbuf **m;
+{
+ struct mbuf *mb;
+
+ if (so != ip_mrouter) return EACCES;
+
+ *m = mb = m_get(M_WAIT, MT_SOOPTS);
+
+ switch (cmd) {
+ case MRT_VERSION: return get_version(mb);
+ case MRT_ASSERT: return get_assert(mb);
+ default: return EOPNOTSUPP;
+ }
+}
+
+#ifndef MROUTE_LKM
+int (*ip_mrouter_get)(int, struct socket *, struct mbuf **) = X_ip_mrouter_get;
+#endif
+
+/*
+ * Handle ioctl commands to obtain information from the cache
+ */
+static int
+X_mrt_ioctl(cmd, data)
+ int cmd;
+ caddr_t data;
+{
+ int error = 0;
+
+ switch (cmd) {
+ case (SIOCGETVIFCNT):
+ return (get_vif_cnt((struct sioc_vif_req *)data));
+ break;
+ case (SIOCGETSGCNT):
+ return (get_sg_cnt((struct sioc_sg_req *)data));
+ break;
+ default:
+ return (EINVAL);
+ break;
+ }
+ return error;
+}
+
+#ifndef MROUTE_LKM
+int (*mrt_ioctl)(int, caddr_t) = X_mrt_ioctl;
+#endif
+
+/*
+ * returns the packet, byte, rpf-failure count for the source group provided
+ */
+static int
+get_sg_cnt(req)
+ register struct sioc_sg_req *req;
+{
+ register struct mfc *rt;
+ int s;
+
+ s = splnet();
+ MFCFIND(req->src.s_addr, req->grp.s_addr, rt);
+ splx(s);
+ if (rt != NULL) {
+ req->pktcnt = rt->mfc_pkt_cnt;
+ req->bytecnt = rt->mfc_byte_cnt;
+ req->wrong_if = rt->mfc_wrong_if;
+ } else
+ req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff;
+
+ return 0;
+}
+
+/*
+ * returns the input and output packet and byte counts on the vif provided
+ */
+static int
+get_vif_cnt(req)
+ register struct sioc_vif_req *req;
+{
+ register vifi_t vifi = req->vifi;
+
+ if (vifi >= numvifs) return EINVAL;
+
+ req->icount = viftable[vifi].v_pkt_in;
+ req->ocount = viftable[vifi].v_pkt_out;
+ req->ibytes = viftable[vifi].v_bytes_in;
+ req->obytes = viftable[vifi].v_bytes_out;
+
+ return 0;
+}
+
+/*
+ * Enable multicast routing
+ */
+static int
+ip_mrouter_init(so, m)
+ struct socket *so;
+ struct mbuf *m;
+{
+ int *v;
+
+ if (mrtdebug)
+ log(LOG_DEBUG,"ip_mrouter_init: so_type = %d, pr_protocol = %d\n",
+ so->so_type, so->so_proto->pr_protocol);
+
+ if (so->so_type != SOCK_RAW ||
+ so->so_proto->pr_protocol != IPPROTO_IGMP) return EOPNOTSUPP;
+
+ if (!m || (m->m_len != sizeof(int *)))
+ return ENOPROTOOPT;
+
+ v = mtod(m, int *);
+ if (*v != 1)
+ return ENOPROTOOPT;
+
+ if (ip_mrouter != NULL) return EADDRINUSE;
+
+ ip_mrouter = so;
+
+ bzero((caddr_t)mfctable, sizeof(mfctable));
+ bzero((caddr_t)nexpire, sizeof(nexpire));
+
+ pim_assert = 0;
+
+ timeout(expire_upcalls, (caddr_t)NULL, EXPIRE_TIMEOUT);
+
+ if (mrtdebug)
+ log(LOG_DEBUG, "ip_mrouter_init\n");
+
+ return 0;
+}
+
+/*
+ * Disable multicast routing
+ */
+static int
+X_ip_mrouter_done()
+{
+ vifi_t vifi;
+ int i;
+ struct ifnet *ifp;
+ struct ifreq ifr;
+ struct mbuf *mb_rt;
+ struct mbuf *m;
+ struct rtdetq *rte;
+ int s;
+
+ s = splnet();
+
+ /*
+ * For each phyint in use, disable promiscuous reception of all IP
+ * multicasts.
+ */
+ for (vifi = 0; vifi < numvifs; vifi++) {
+ if (viftable[vifi].v_lcl_addr.s_addr != 0 &&
+ !(viftable[vifi].v_flags & VIFF_TUNNEL)) {
+ ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
+ ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr
+ = INADDR_ANY;
+ ifp = viftable[vifi].v_ifp;
+ (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr);
+ }
+ }
+ bzero((caddr_t)tbftable, sizeof(tbftable));
+ bzero((caddr_t)viftable, sizeof(viftable));
+ numvifs = 0;
+ pim_assert = 0;
+
+ untimeout(expire_upcalls, (caddr_t)NULL);
+
+ /*
+ * Free all multicast forwarding cache entries.
+ */
+ for (i = 0; i < MFCTBLSIZ; i++) {
+ mb_rt = mfctable[i];
+ while (mb_rt) {
+ if (mb_rt->m_act != NULL) {
+ while (mb_rt->m_act) {
+ m = mb_rt->m_act;
+ mb_rt->m_act = m->m_act;
+ rte = mtod(m, struct rtdetq *);
+ m_freem(rte->m);
+ m_free(m);
+ }
+ }
+ mb_rt = m_free(mb_rt);
+ }
+ }
+
+ bzero((caddr_t)mfctable, sizeof(mfctable));
+
+ /*
+ * Reset de-encapsulation cache
+ */
+ last_encap_src = 0;
+ last_encap_vif = NULL;
+ have_encap_tunnel = 0;
+
+ ip_mrouter = NULL;
+
+ splx(s);
+
+ if (mrtdebug)
+ log(LOG_DEBUG, "ip_mrouter_done\n");
+
+ return 0;
+}
+
+#ifndef MROUTE_LKM
+int (*ip_mrouter_done)(void) = X_ip_mrouter_done;
+#endif
+
+static int
+get_version(mb)
+ struct mbuf *mb;
+{
+ int *v;
+
+ v = mtod(mb, int *);
+
+ *v = 0x0305; /* XXX !!!! */
+ mb->m_len = sizeof(int);
+
+ return 0;
+}
+
+/*
+ * Set PIM assert processing global
+ */
+static int
+set_assert(i)
+ int *i;
+{
+ if ((*i != 1) && (*i != 0))
+ return EINVAL;
+
+ pim_assert = *i;
+
+ return 0;
+}
+
+/*
+ * Get PIM assert processing global
+ */
+static int
+get_assert(m)
+ struct mbuf *m;
+{
+ int *i;
+
+ i = mtod(m, int *);
+
+ *i = pim_assert;
+
+ return 0;
+}
+
+/*
+ * Add a vif to the vif table
+ */
+static int
+add_vif(vifcp)
+ register struct vifctl *vifcp;
+{
+ register struct vif *vifp = viftable + vifcp->vifc_vifi;
+ static struct sockaddr_in sin = {sizeof sin, AF_INET};
+ struct ifaddr *ifa;
+ struct ifnet *ifp;
+ struct ifreq ifr;
+ int error, s;
+ struct tbf *v_tbf = tbftable + vifcp->vifc_vifi;
+
+ if (vifcp->vifc_vifi >= MAXVIFS) return EINVAL;
+ if (vifp->v_lcl_addr.s_addr != 0) return EADDRINUSE;
+
+ /* Find the interface with an address in AF_INET family */
+ sin.sin_addr = vifcp->vifc_lcl_addr;
+ ifa = ifa_ifwithaddr((struct sockaddr *)&sin);
+ if (ifa == 0) return EADDRNOTAVAIL;
+ ifp = ifa->ifa_ifp;
+
+ if (vifcp->vifc_flags & VIFF_TUNNEL) {
+ if ((vifcp->vifc_flags & VIFF_SRCRT) == 0) {
+ /*
+ * An encapsulating tunnel is wanted. Tell ipip_input() to
+ * start paying attention to encapsulated packets.
+ */
+ if (have_encap_tunnel == 0) {
+ have_encap_tunnel = 1;
+ for (s = 0; s < MAXVIFS; ++s) {
+ multicast_decap_if[s].if_name = "mdecap";
+ multicast_decap_if[s].if_unit = s;
+ }
+ }
+ /*
+ * Set interface to fake encapsulator interface
+ */
+ ifp = &multicast_decap_if[vifcp->vifc_vifi];
+ /*
+ * Prepare cached route entry
+ */
+ bzero(&vifp->v_route, sizeof(vifp->v_route));
+ } else {
+ log(LOG_ERR, "source routed tunnels not supported\n");
+ return EOPNOTSUPP;
+ }
+ } else {
+ /* Make sure the interface supports multicast */
+ if ((ifp->if_flags & IFF_MULTICAST) == 0)
+ return EOPNOTSUPP;
+
+ /* Enable promiscuous reception of all IP multicasts from the if */
+ ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
+ ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr = INADDR_ANY;
+ s = splnet();
+ error = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, (caddr_t)&ifr);
+ splx(s);
+ if (error)
+ return error;
+ }
+
+ s = splnet();
+ /* define parameters for the tbf structure */
+ vifp->v_tbf = v_tbf;
+ GET_TIME(vifp->v_tbf->tbf_last_pkt_t);
+ vifp->v_tbf->tbf_n_tok = 0;
+ vifp->v_tbf->tbf_q_len = 0;
+ vifp->v_tbf->tbf_max_q_len = MAXQSIZE;
+ vifp->v_tbf->tbf_q = vifp->v_tbf->tbf_t = NULL;
+
+ vifp->v_flags = vifcp->vifc_flags;
+ vifp->v_threshold = vifcp->vifc_threshold;
+ vifp->v_lcl_addr = vifcp->vifc_lcl_addr;
+ vifp->v_rmt_addr = vifcp->vifc_rmt_addr;
+ vifp->v_ifp = ifp;
+ /* scaling up here allows division by 1024 in critical code */
+ vifp->v_rate_limit= vifcp->vifc_rate_limit * 1024 / 1000;
+ vifp->v_rsvp_on = 0;
+ vifp->v_rsvpd = NULL;
+ /* initialize per vif pkt counters */
+ vifp->v_pkt_in = 0;
+ vifp->v_pkt_out = 0;
+ vifp->v_bytes_in = 0;
+ vifp->v_bytes_out = 0;
+ splx(s);
+
+ /* Adjust numvifs up if the vifi is higher than numvifs */
+ if (numvifs <= vifcp->vifc_vifi) numvifs = vifcp->vifc_vifi + 1;
+
+ if (mrtdebug)
+ log(LOG_DEBUG, "add_vif #%d, lcladdr %x, %s %x, thresh %x, rate %d\n",
+ vifcp->vifc_vifi,
+ ntohl(vifcp->vifc_lcl_addr.s_addr),
+ (vifcp->vifc_flags & VIFF_TUNNEL) ? "rmtaddr" : "mask",
+ ntohl(vifcp->vifc_rmt_addr.s_addr),
+ vifcp->vifc_threshold,
+ vifcp->vifc_rate_limit);
+
+ return 0;
+}
+
+/*
+ * Delete a vif from the vif table
+ */
+static int
+del_vif(vifip)
+ vifi_t *vifip;
+{
+ register struct vif *vifp = viftable + *vifip;
+ register vifi_t vifi;
+ register struct mbuf *m;
+ struct ifnet *ifp;
+ struct ifreq ifr;
+ int s;
+
+ if (*vifip >= numvifs) return EINVAL;
+ if (vifp->v_lcl_addr.s_addr == 0) return EADDRNOTAVAIL;
+
+ s = splnet();
+
+ if (!(vifp->v_flags & VIFF_TUNNEL)) {
+ ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
+ ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr = INADDR_ANY;
+ ifp = vifp->v_ifp;
+ (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr);
+ }
+
+ if (vifp == last_encap_vif) {
+ last_encap_vif = 0;
+ last_encap_src = 0;
+ }
+
+ /*
+ * Free packets queued at the interface
+ */
+ while (vifp->v_tbf->tbf_q) {
+ m = vifp->v_tbf->tbf_q;
+ vifp->v_tbf->tbf_q = m->m_act;
+ m_freem(m);
+ }
+
+ bzero((caddr_t)vifp->v_tbf, sizeof(*(vifp->v_tbf)));
+ bzero((caddr_t)vifp, sizeof (*vifp));
+
+ /* Adjust numvifs down */
+ for (vifi = numvifs; vifi > 0; vifi--)
+ if (viftable[vifi-1].v_lcl_addr.s_addr != 0) break;
+ numvifs = vifi;
+
+ splx(s);
+
+ if (mrtdebug)
+ log(LOG_DEBUG, "del_vif %d, numvifs %d\n", *vifip, numvifs);
+
+ return 0;
+}
+
+/*
+ * Add an mfc entry
+ */
+static int
+add_mfc(mfccp)
+ struct mfcctl *mfccp;
+{
+ struct mfc *rt;
+ register struct mbuf *mb_rt;
+ u_long hash;
+ struct mbuf *mb_ntry;
+ struct rtdetq *rte;
+ register u_short nstl;
+ int s;
+ int i;
+
+ MFCFIND(mfccp->mfcc_origin.s_addr, mfccp->mfcc_mcastgrp.s_addr, rt);
+
+ /* If an entry already exists, just update the fields */
+ if (rt) {
+ if (mrtdebug & DEBUG_MFC)
+ log(LOG_DEBUG,"add_mfc update o %x g %x p %x\n",
+ ntohl(mfccp->mfcc_origin.s_addr),
+ ntohl(mfccp->mfcc_mcastgrp.s_addr),
+ mfccp->mfcc_parent);
+
+ s = splnet();
+ rt->mfc_parent = mfccp->mfcc_parent;
+ for (i = 0; i < numvifs; i++)
+ rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
+ splx(s);
+ return 0;
+ }
+
+ /*
+ * Find the entry for which the upcall was made and update
+ */
+ s = splnet();
+ hash = MFCHASH(mfccp->mfcc_origin.s_addr, mfccp->mfcc_mcastgrp.s_addr);
+ for (mb_rt = mfctable[hash], nstl = 0; mb_rt; mb_rt = mb_rt->m_next) {
+
+ rt = mtod(mb_rt, struct mfc *);
+ if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) &&
+ (rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr) &&
+ (mb_rt->m_act != NULL)) {
+
+ if (nstl++)
+ log(LOG_ERR, "add_mfc %s o %x g %x p %x dbx %x\n",
+ "multiple kernel entries",
+ ntohl(mfccp->mfcc_origin.s_addr),
+ ntohl(mfccp->mfcc_mcastgrp.s_addr),
+ mfccp->mfcc_parent, mb_rt->m_act);
+
+ if (mrtdebug & DEBUG_MFC)
+ log(LOG_DEBUG,"add_mfc o %x g %x p %x dbg %x\n",
+ ntohl(mfccp->mfcc_origin.s_addr),
+ ntohl(mfccp->mfcc_mcastgrp.s_addr),
+ mfccp->mfcc_parent, mb_rt->m_act);
+
+ rt->mfc_origin = mfccp->mfcc_origin;
+ rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
+ rt->mfc_parent = mfccp->mfcc_parent;
+ for (i = 0; i < numvifs; i++)
+ rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
+ /* initialize pkt counters per src-grp */
+ rt->mfc_pkt_cnt = 0;
+ rt->mfc_byte_cnt = 0;
+ rt->mfc_wrong_if = 0;
+ rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0;
+
+ rt->mfc_expire = 0; /* Don't clean this guy up */
+ nexpire[hash]--;
+
+ /* free packets Qed at the end of this entry */
+ while (mb_rt->m_act) {
+ mb_ntry = mb_rt->m_act;
+ rte = mtod(mb_ntry, struct rtdetq *);
+/* #ifdef RSVP_ISI */
+ ip_mdq(rte->m, rte->ifp, rt, -1);
+/* #endif */
+ mb_rt->m_act = mb_ntry->m_act;
+ m_freem(rte->m);
+#ifdef UPCALL_TIMING
+ collate(&(rte->t));
+#endif /* UPCALL_TIMING */
+ m_free(mb_ntry);
+ }
+ }
+ }
+
+ /*
+ * It is possible that an entry is being inserted without an upcall
+ */
+ if (nstl == 0) {
+ if (mrtdebug & DEBUG_MFC)
+ log(LOG_DEBUG,"add_mfc no upcall h %d o %x g %x p %x\n",
+ hash, ntohl(mfccp->mfcc_origin.s_addr),
+ ntohl(mfccp->mfcc_mcastgrp.s_addr),
+ mfccp->mfcc_parent);
+
+ for (mb_rt = mfctable[hash]; mb_rt; mb_rt = mb_rt->m_next) {
+
+ rt = mtod(mb_rt, struct mfc *);
+ if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) &&
+ (rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr)) {
+
+ rt->mfc_origin = mfccp->mfcc_origin;
+ rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
+ rt->mfc_parent = mfccp->mfcc_parent;
+ for (i = 0; i < numvifs; i++)
+ rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
+ /* initialize pkt counters per src-grp */
+ rt->mfc_pkt_cnt = 0;
+ rt->mfc_byte_cnt = 0;
+ rt->mfc_wrong_if = 0;
+ rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0;
+ if (rt->mfc_expire)
+ nexpire[hash]--;
+ rt->mfc_expire = 0;
+ }
+ }
+ if (mb_rt == NULL) {
+ /* no upcall, so make a new entry */
+ MGET(mb_rt, M_DONTWAIT, MT_MRTABLE);
+ if (mb_rt == NULL) {
+ splx(s);
+ return ENOBUFS;
+ }
+
+ rt = mtod(mb_rt, struct mfc *);
+
+ /* insert new entry at head of hash chain */
+ rt->mfc_origin = mfccp->mfcc_origin;
+ rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
+ rt->mfc_parent = mfccp->mfcc_parent;
+ for (i = 0; i < numvifs; i++)
+ rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
+ /* initialize pkt counters per src-grp */
+ rt->mfc_pkt_cnt = 0;
+ rt->mfc_byte_cnt = 0;
+ rt->mfc_wrong_if = 0;
+ rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0;
+ rt->mfc_expire = 0;
+
+ /* link into table */
+ mb_rt->m_next = mfctable[hash];
+ mfctable[hash] = mb_rt;
+ mb_rt->m_act = NULL;
+ }
+ }
+ splx(s);
+ return 0;
+}
+
+#ifdef UPCALL_TIMING
+/*
+ * collect delay statistics on the upcalls
+ */
+static void collate(t)
+register struct timeval *t;
+{
+ register u_long d;
+ register struct timeval tp;
+ register u_long delta;
+
+ GET_TIME(tp);
+
+ if (TV_LT(*t, tp))
+ {
+ TV_DELTA(tp, *t, delta);
+
+ d = delta >> 10;
+ if (d > 50)
+ d = 50;
+
+ ++upcall_data[d];
+ }
+}
+#endif /* UPCALL_TIMING */
+
+/*
+ * Delete an mfc entry
+ */
+static int
+del_mfc(mfccp)
+ struct mfcctl *mfccp;
+{
+ struct in_addr origin;
+ struct in_addr mcastgrp;
+ struct mfc *rt;
+ struct mbuf *mb_rt;
+ struct mbuf **nptr;
+ u_long hash;
+ int s;
+
+ origin = mfccp->mfcc_origin;
+ mcastgrp = mfccp->mfcc_mcastgrp;
+ hash = MFCHASH(origin.s_addr, mcastgrp.s_addr);
+
+ if (mrtdebug & DEBUG_MFC)
+ log(LOG_DEBUG,"del_mfc orig %x mcastgrp %x\n",
+ ntohl(origin.s_addr), ntohl(mcastgrp.s_addr));
+
+ s = splnet();
+
+ nptr = &mfctable[hash];
+ while ((mb_rt = *nptr) != NULL) {
+ rt = mtod(mb_rt, struct mfc *);
+ if (origin.s_addr == rt->mfc_origin.s_addr &&
+ mcastgrp.s_addr == rt->mfc_mcastgrp.s_addr &&
+ mb_rt->m_act == NULL)
+ break;
+
+ nptr = &mb_rt->m_next;
+ }
+ if (mb_rt == NULL) {
+ splx(s);
+ return EADDRNOTAVAIL;
+ }
+
+ MFREE(mb_rt, *nptr);
+
+ splx(s);
+
+ return 0;
+}
+
+/*
+ * Send a message to mrouted on the multicast routing socket
+ */
+static int
+socket_send(s, mm, src)
+ struct socket *s;
+ struct mbuf *mm;
+ struct sockaddr_in *src;
+{
+ if (s) {
+ if (sbappendaddr(&s->so_rcv,
+ (struct sockaddr *)src,
+ mm, (struct mbuf *)0) != 0) {
+ sorwakeup(s);
+ return 0;
+ }
+ }
+ m_freem(mm);
+ return -1;
+}
+
+/*
+ * IP multicast forwarding function. This function assumes that the packet
+ * pointed to by "ip" has arrived on (or is about to be sent to) the interface
+ * pointed to by "ifp", and the packet is to be relayed to other networks
+ * that have members of the packet's destination IP multicast group.
+ *
+ * The packet is returned unscathed to the caller, unless it is
+ * erroneous, in which case a non-zero return value tells the caller to
+ * discard it.
+ */
+
+#define IP_HDR_LEN 20 /* # bytes of fixed IP header (excluding options) */
+#define TUNNEL_LEN 12 /* # bytes of IP option for tunnel encapsulation */
+
+static int
+X_ip_mforward(ip, ifp, m, imo)
+ register struct ip *ip;
+ struct ifnet *ifp;
+ struct mbuf *m;
+ struct ip_moptions *imo;
+{
+ register struct mfc *rt;
+ register u_char *ipoptions;
+ static struct sockaddr_in k_igmpsrc = { sizeof k_igmpsrc, AF_INET };
+ static int srctun = 0;
+ register struct mbuf *mm;
+ int s;
+ vifi_t vifi;
+ struct vif *vifp;
+
+ if (mrtdebug & DEBUG_FORWARD)
+ log(LOG_DEBUG, "ip_mforward: src %x, dst %x, ifp %x\n",
+ ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr), ifp);
+
+ if (ip->ip_hl < (IP_HDR_LEN + TUNNEL_LEN) >> 2 ||
+ (ipoptions = (u_char *)(ip + 1))[1] != IPOPT_LSRR ) {
+ /*
+ * Packet arrived via a physical interface or
+ * an encapsulated tunnel.
+ */
+ } else {
+ /*
+ * Packet arrived through a source-route tunnel.
+ * Source-route tunnels are no longer supported.
+ */
+ if ((srctun++ % 1000) == 0)
+ log(LOG_ERR, "ip_mforward: received source-routed packet from %x\n",
+ ntohl(ip->ip_src.s_addr));
+
+ return 1;
+ }
+
+ if ((imo) && ((vifi = imo->imo_multicast_vif) < numvifs)) {
+ if (ip->ip_ttl < 255)
+ ip->ip_ttl++; /* compensate for -1 in *_send routines */
+ if (rsvpdebug && ip->ip_p == IPPROTO_RSVP) {
+ vifp = viftable + vifi;
+ printf("Sending IPPROTO_RSVP from %lx to %lx on vif %d (%s%s%d)\n",
+ ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr), vifi,
+ (vifp->v_flags & VIFF_TUNNEL) ? "tunnel on " : "",
+ vifp->v_ifp->if_name, vifp->v_ifp->if_unit);
+ }
+ return (ip_mdq(m, ifp, NULL, vifi));
+ }
+ if (rsvpdebug && ip->ip_p == IPPROTO_RSVP) {
+ printf("Warning: IPPROTO_RSVP from %lx to %lx without vif option\n",
+ ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr));
+ if(!imo)
+ printf("In fact, no options were specified at all\n");
+ }
+
+ /*
+ * Don't forward a packet with time-to-live of zero or one,
+ * or a packet destined to a local-only group.
+ */
+ if (ip->ip_ttl <= 1 ||
+ ntohl(ip->ip_dst.s_addr) <= INADDR_MAX_LOCAL_GROUP)
+ return 0;
+
+ /*
+ * Determine forwarding vifs from the forwarding cache table
+ */
+ s = splnet();
+ MFCFIND(ip->ip_src.s_addr, ip->ip_dst.s_addr, rt);
+
+ /* Entry exists, so forward if necessary */
+ if (rt != NULL) {
+ splx(s);
+ return (ip_mdq(m, ifp, rt, -1));
+ } else {
+ /*
+ * If we don't have a route for packet's origin,
+ * Make a copy of the packet &
+ * send message to routing daemon
+ */
+
+ register struct mbuf *mb_rt;
+ register struct mbuf *mb_ntry;
+ register struct mbuf *mb0;
+ register struct rtdetq *rte;
+ register struct mbuf *rte_m;
+ register u_long hash;
+ register int npkts;
+ int hlen = ip->ip_hl << 2;
+#ifdef UPCALL_TIMING
+ struct timeval tp;
+
+ GET_TIME(tp);
+#endif
+
+ mrtstat.mrts_no_route++;
+ if (mrtdebug & (DEBUG_FORWARD | DEBUG_MFC))
+ log(LOG_DEBUG, "ip_mforward: no rte s %x g %x\n",
+ ntohl(ip->ip_src.s_addr),
+ ntohl(ip->ip_dst.s_addr));
+
+ /*
+ * Allocate mbufs early so that we don't do extra work if we are
+ * just going to fail anyway. Make sure to pullup the header so
+ * that other people can't step on it.
+ */
+ MGET(mb_ntry, M_DONTWAIT, MT_DATA);
+ if (mb_ntry == NULL) {
+ splx(s);
+ return ENOBUFS;
+ }
+ mb0 = m_copy(m, 0, M_COPYALL);
+ if (mb0 && (M_HASCL(mb0) || mb0->m_len < hlen))
+ mb0 = m_pullup(mb0, hlen);
+ if (mb0 == NULL) {
+ m_free(mb_ntry);
+ splx(s);
+ return ENOBUFS;
+ }
+
+ /* is there an upcall waiting for this packet? */
+ hash = MFCHASH(ip->ip_src.s_addr, ip->ip_dst.s_addr);
+ for (mb_rt = mfctable[hash]; mb_rt; mb_rt = mb_rt->m_next) {
+ rt = mtod(mb_rt, struct mfc *);
+ if ((ip->ip_src.s_addr == rt->mfc_origin.s_addr) &&
+ (ip->ip_dst.s_addr == rt->mfc_mcastgrp.s_addr) &&
+ (mb_rt->m_act != NULL))
+ break;
+ }
+
+ if (mb_rt == NULL) {
+ int i;
+ struct igmpmsg *im;
+
+ /* no upcall, so make a new entry */
+ MGET(mb_rt, M_DONTWAIT, MT_MRTABLE);
+ if (mb_rt == NULL) {
+ m_free(mb_ntry);
+ m_freem(mb0);
+ splx(s);
+ return ENOBUFS;
+ }
+ /* Make a copy of the header to send to the user level process */
+ mm = m_copy(mb0, 0, hlen);
+ if (mm == NULL) {
+ m_free(mb_ntry);
+ m_freem(mb0);
+ m_free(mb_rt);
+ splx(s);
+ return ENOBUFS;
+ }
+
+ /*
+ * Send message to routing daemon to install
+ * a route into the kernel table
+ */
+ k_igmpsrc.sin_addr = ip->ip_src;
+
+ im = mtod(mm, struct igmpmsg *);
+ im->im_msgtype = IGMPMSG_NOCACHE;
+ im->im_mbz = 0;
+
+ mrtstat.mrts_upcalls++;
+
+ if (socket_send(ip_mrouter, mm, &k_igmpsrc) < 0) {
+ log(LOG_WARNING, "ip_mforward: ip_mrouter socket queue full\n");
+ ++mrtstat.mrts_upq_sockfull;
+ m_free(mb_ntry);
+ m_freem(mb0);
+ m_free(mb_rt);
+ splx(s);
+ return ENOBUFS;
+ }
+
+ rt = mtod(mb_rt, struct mfc *);
+
+ /* insert new entry at head of hash chain */
+ rt->mfc_origin.s_addr = ip->ip_src.s_addr;
+ rt->mfc_mcastgrp.s_addr = ip->ip_dst.s_addr;
+ rt->mfc_expire = UPCALL_EXPIRE;
+ nexpire[hash]++;
+ for (i = 0; i < numvifs; i++)
+ rt->mfc_ttls[i] = 0;
+ rt->mfc_parent = -1;
+
+ /* link into table */
+ mb_rt->m_next = mfctable[hash];
+ mfctable[hash] = mb_rt;
+ mb_rt->m_act = NULL;
+
+ rte_m = mb_rt;
+ } else {
+ /* determine if q has overflowed */
+ for (rte_m = mb_rt, npkts = 0; rte_m->m_act; rte_m = rte_m->m_act)
+ npkts++;
+
+ if (npkts > MAX_UPQ) {
+ mrtstat.mrts_upq_ovflw++;
+ m_free(mb_ntry);
+ m_freem(mb0);
+ splx(s);
+ return 0;
+ }
+ }
+
+ mb_ntry->m_act = NULL;
+ rte = mtod(mb_ntry, struct rtdetq *);
+
+ rte->m = mb0;
+ rte->ifp = ifp;
+#ifdef UPCALL_TIMING
+ rte->t = tp;
+#endif
+
+ /* Add this entry to the end of the queue */
+ rte_m->m_act = mb_ntry;
+
+ splx(s);
+
+ return 0;
+ }
+}
+
+#ifndef MROUTE_LKM
+int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
+ struct ip_moptions *) = X_ip_mforward;
+#endif
+
+/*
+ * Clean up the cache entry if upcall is not serviced
+ */
+static void
+expire_upcalls(void *unused)
+{
+ struct mbuf *mb_rt, *m, **nptr;
+ struct rtdetq *rte;
+ struct mfc *mfc;
+ int i;
+ int s;
+
+ s = splnet();
+ for (i = 0; i < MFCTBLSIZ; i++) {
+ if (nexpire[i] == 0)
+ continue;
+ nptr = &mfctable[i];
+ for (mb_rt = *nptr; mb_rt != NULL; mb_rt = *nptr) {
+ mfc = mtod(mb_rt, struct mfc *);
+
+ /*
+ * Skip real cache entries
+ * Make sure it wasn't marked to not expire (shouldn't happen)
+ * If it expires now
+ */
+ if (mb_rt->m_act != NULL &&
+ mfc->mfc_expire != 0 &&
+ --mfc->mfc_expire == 0) {
+ if (mrtdebug & DEBUG_EXPIRE)
+ log(LOG_DEBUG, "expire_upcalls: expiring (%x %x)\n",
+ ntohl(mfc->mfc_origin.s_addr),
+ ntohl(mfc->mfc_mcastgrp.s_addr));
+ /*
+ * drop all the packets
+ * free the mbuf with the pkt, if, timing info
+ */
+ while (mb_rt->m_act) {
+ m = mb_rt->m_act;
+ mb_rt->m_act = m->m_act;
+
+ rte = mtod(m, struct rtdetq *);
+ m_freem(rte->m);
+ m_free(m);
+ }
+ ++mrtstat.mrts_cache_cleanups;
+ nexpire[i]--;
+
+ MFREE(mb_rt, *nptr);
+ } else {
+ nptr = &mb_rt->m_next;
+ }
+ }
+ }
+ splx(s);
+ timeout(expire_upcalls, (caddr_t)NULL, EXPIRE_TIMEOUT);
+}
+
+/*
+ * Packet forwarding routine once entry in the cache is made
+ */
+static int
+ip_mdq(m, ifp, rt, xmt_vif)
+ register struct mbuf *m;
+ register struct ifnet *ifp;
+ register struct mfc *rt;
+ register vifi_t xmt_vif;
+{
+ register struct ip *ip = mtod(m, struct ip *);
+ register vifi_t vifi;
+ register struct vif *vifp;
+ register int plen = ntohs(ip->ip_len);
+
+/*
+ * Macro to send packet on vif. Since RSVP packets don't get counted on
+ * input, they shouldn't get counted on output, so statistics keeping is
+ * seperate.
+ */
+#define MC_SEND(ip,vifp,m) { \
+ if ((vifp)->v_flags & VIFF_TUNNEL) \
+ encap_send((ip), (vifp), (m)); \
+ else \
+ phyint_send((ip), (vifp), (m)); \
+}
+
+ /*
+ * If xmt_vif is not -1, send on only the requested vif.
+ *
+ * (since vifi_t is u_short, -1 becomes MAXUSHORT, which > numvifs.)
+ */
+ if (xmt_vif < numvifs) {
+ MC_SEND(ip, viftable + xmt_vif, m);
+ return 1;
+ }
+
+ /*
+ * Don't forward if it didn't arrive from the parent vif for its origin.
+ */
+ vifi = rt->mfc_parent;
+ if ((vifi >= numvifs) || (viftable[vifi].v_ifp != ifp)) {
+ /* came in the wrong interface */
+ if (mrtdebug & DEBUG_FORWARD)
+ log(LOG_DEBUG, "wrong if: ifp %x vifi %d vififp %x\n",
+ ifp, vifi, viftable[vifi].v_ifp);
+ ++mrtstat.mrts_wrong_if;
+ ++rt->mfc_wrong_if;
+ /*
+ * If we are doing PIM assert processing, and we are forwarding
+ * packets on this interface, and it is a broadcast medium
+ * interface (and not a tunnel), send a message to the routing daemon.
+ */
+ if (pim_assert && rt->mfc_ttls[vifi] &&
+ (ifp->if_flags & IFF_BROADCAST) &&
+ !(viftable[vifi].v_flags & VIFF_TUNNEL)) {
+ struct sockaddr_in k_igmpsrc;
+ struct mbuf *mm;
+ struct igmpmsg *im;
+ int hlen = ip->ip_hl << 2;
+ struct timeval now;
+ register u_long delta;
+
+ GET_TIME(now);
+
+ TV_DELTA(rt->mfc_last_assert, now, delta);
+
+ if (delta > ASSERT_MSG_TIME) {
+ mm = m_copy(m, 0, hlen);
+ if (mm && (M_HASCL(mm) || mm->m_len < hlen))
+ mm = m_pullup(mm, hlen);
+ if (mm == NULL) {
+ return ENOBUFS;
+ }
+
+ rt->mfc_last_assert = now;
+
+ im = mtod(mm, struct igmpmsg *);
+ im->im_msgtype = IGMPMSG_WRONGVIF;
+ im->im_mbz = 0;
+ im->im_vif = vifi;
+
+ k_igmpsrc.sin_addr = im->im_src;
+
+ socket_send(ip_mrouter, mm, &k_igmpsrc);
+ }
+ }
+ return 0;
+ }
+
+ /* If I sourced this packet, it counts as output, else it was input. */
+ if (ip->ip_src.s_addr == viftable[vifi].v_lcl_addr.s_addr) {
+ viftable[vifi].v_pkt_out++;
+ viftable[vifi].v_bytes_out += plen;
+ } else {
+ viftable[vifi].v_pkt_in++;
+ viftable[vifi].v_bytes_in += plen;
+ }
+ rt->mfc_pkt_cnt++;
+ rt->mfc_byte_cnt += plen;
+
+ /*
+ * For each vif, decide if a copy of the packet should be forwarded.
+ * Forward if:
+ * - the ttl exceeds the vif's threshold
+ * - there are group members downstream on interface
+ */
+ for (vifp = viftable, vifi = 0; vifi < numvifs; vifp++, vifi++)
+ if ((rt->mfc_ttls[vifi] > 0) &&
+ (ip->ip_ttl > rt->mfc_ttls[vifi])) {
+ vifp->v_pkt_out++;
+ vifp->v_bytes_out += plen;
+ MC_SEND(ip, vifp, m);
+ }
+
+ return 0;
+}
+
+/*
+ * check if a vif number is legal/ok. This is used by ip_output, to export
+ * numvifs there,
+ */
+static int
+X_legal_vif_num(vif)
+ int vif;
+{
+ if (vif >= 0 && vif < numvifs)
+ return(1);
+ else
+ return(0);
+}
+
+#ifndef MROUTE_LKM
+int (*legal_vif_num)(int) = X_legal_vif_num;
+#endif
+
+/*
+ * Return the local address used by this vif
+ */
+static u_long
+X_ip_mcast_src(vifi)
+ int vifi;
+{
+ if (vifi >= 0 && vifi < numvifs)
+ return viftable[vifi].v_lcl_addr.s_addr;
+ else
+ return INADDR_ANY;
+}
+
+#ifndef MROUTE_LKM
+u_long (*ip_mcast_src)(int) = X_ip_mcast_src;
+#endif
+
+static void
+phyint_send(ip, vifp, m)
+ struct ip *ip;
+ struct vif *vifp;
+ struct mbuf *m;
+{
+ register struct mbuf *mb_copy;
+ register int hlen = ip->ip_hl << 2;
+
+ /*
+ * Make a new reference to the packet; make sure that
+ * the IP header is actually copied, not just referenced,
+ * so that ip_output() only scribbles on the copy.
+ */
+ mb_copy = m_copy(m, 0, M_COPYALL);
+ if (mb_copy && (M_HASCL(mb_copy) || mb_copy->m_len < hlen))
+ mb_copy = m_pullup(mb_copy, hlen);
+ if (mb_copy == NULL)
+ return;
+
+ if (vifp->v_rate_limit <= 0)
+ tbf_send_packet(vifp, mb_copy);
+ else
+ tbf_control(vifp, mb_copy, mtod(mb_copy, struct ip *), ip->ip_len);
+}
+
+static void
+encap_send(ip, vifp, m)
+ register struct ip *ip;
+ register struct vif *vifp;
+ register struct mbuf *m;
+{
+ register struct mbuf *mb_copy;
+ register struct ip *ip_copy;
+ register int i, len = ip->ip_len;
+
+ /*
+ * copy the old packet & pullup it's IP header into the
+ * new mbuf so we can modify it. Try to fill the new
+ * mbuf since if we don't the ethernet driver will.
+ */
+ MGETHDR(mb_copy, M_DONTWAIT, MT_HEADER);
+ if (mb_copy == NULL)
+ return;
+ mb_copy->m_data += max_linkhdr;
+ mb_copy->m_len = sizeof(multicast_encap_iphdr);
+
+ if ((mb_copy->m_next = m_copy(m, 0, M_COPYALL)) == NULL) {
+ m_freem(mb_copy);
+ return;
+ }
+ i = MHLEN - M_LEADINGSPACE(mb_copy);
+ if (i > len)
+ i = len;
+ mb_copy = m_pullup(mb_copy, i);
+ if (mb_copy == NULL)
+ return;
+ mb_copy->m_pkthdr.len = len + sizeof(multicast_encap_iphdr);
+
+ /*
+ * fill in the encapsulating IP header.
+ */
+ ip_copy = mtod(mb_copy, struct ip *);
+ *ip_copy = multicast_encap_iphdr;
+ ip_copy->ip_id = htons(ip_id++);
+ ip_copy->ip_len += len;
+ ip_copy->ip_src = vifp->v_lcl_addr;
+ ip_copy->ip_dst = vifp->v_rmt_addr;
+
+ /*
+ * turn the encapsulated IP header back into a valid one.
+ */
+ ip = (struct ip *)((caddr_t)ip_copy + sizeof(multicast_encap_iphdr));
+ --ip->ip_ttl;
+ HTONS(ip->ip_len);
+ HTONS(ip->ip_off);
+ ip->ip_sum = 0;
+ mb_copy->m_data += sizeof(multicast_encap_iphdr);
+ ip->ip_sum = in_cksum(mb_copy, ip->ip_hl << 2);
+ mb_copy->m_data -= sizeof(multicast_encap_iphdr);
+
+ if (vifp->v_rate_limit <= 0)
+ tbf_send_packet(vifp, mb_copy);
+ else
+ tbf_control(vifp, mb_copy, ip, ip_copy->ip_len);
+}
+
+/*
+ * De-encapsulate a packet and feed it back through ip input (this
+ * routine is called whenever IP gets a packet with proto type
+ * ENCAP_PROTO and a local destination address).
+ */
+void
+#ifdef MROUTE_LKM
+X_ipip_input(m, iphlen)
+#else
+ipip_input(m, iphlen)
+#endif
+ register struct mbuf *m;
+ int iphlen;
+{
+ struct ifnet *ifp = m->m_pkthdr.rcvif;
+ register struct ip *ip = mtod(m, struct ip *);
+ register int hlen = ip->ip_hl << 2;
+ register int s;
+ register struct ifqueue *ifq;
+ register struct vif *vifp;
+
+ if (!have_encap_tunnel) {
+ rip_input(m, iphlen);
+ return;
+ }
+ /*
+ * dump the packet if it's not to a multicast destination or if
+ * we don't have an encapsulating tunnel with the source.
+ * Note: This code assumes that the remote site IP address
+ * uniquely identifies the tunnel (i.e., that this site has
+ * at most one tunnel with the remote site).
+ */
+ if (! IN_MULTICAST(ntohl(((struct ip *)((char *)ip + hlen))->ip_dst.s_addr))) {
+ ++mrtstat.mrts_bad_tunnel;
+ m_freem(m);
+ return;
+ }
+ if (ip->ip_src.s_addr != last_encap_src) {
+ register struct vif *vife;
+
+ vifp = viftable;
+ vife = vifp + numvifs;
+ last_encap_src = ip->ip_src.s_addr;
+ last_encap_vif = 0;
+ for ( ; vifp < vife; ++vifp)
+ if (vifp->v_rmt_addr.s_addr == ip->ip_src.s_addr) {
+ if ((vifp->v_flags & (VIFF_TUNNEL|VIFF_SRCRT))
+ == VIFF_TUNNEL)
+ last_encap_vif = vifp;
+ break;
+ }
+ }
+ if ((vifp = last_encap_vif) == 0) {
+ last_encap_src = 0;
+ mrtstat.mrts_cant_tunnel++; /*XXX*/
+ m_freem(m);
+ if (mrtdebug)
+ log(LOG_DEBUG, "ip_mforward: no tunnel with %x\n",
+ ntohl(ip->ip_src.s_addr));
+ return;
+ }
+ ifp = vifp->v_ifp;
+
+ if (hlen > IP_HDR_LEN)
+ ip_stripoptions(m, (struct mbuf *) 0);
+ m->m_data += IP_HDR_LEN;
+ m->m_len -= IP_HDR_LEN;
+ m->m_pkthdr.len -= IP_HDR_LEN;
+ m->m_pkthdr.rcvif = ifp;
+
+ ifq = &ipintrq;
+ s = splimp();
+ if (IF_QFULL(ifq)) {
+ IF_DROP(ifq);
+ m_freem(m);
+ } else {
+ IF_ENQUEUE(ifq, m);
+ /*
+ * normally we would need a "schednetisr(NETISR_IP)"
+ * here but we were called by ip_input and it is going
+ * to loop back & try to dequeue the packet we just
+ * queued as soon as we return so we avoid the
+ * unnecessary software interrrupt.
+ */
+ }
+ splx(s);
+}
+
+/*
+ * Token bucket filter module
+ */
+
+static void
+tbf_control(vifp, m, ip, p_len)
+ register struct vif *vifp;
+ register struct mbuf *m;
+ register struct ip *ip;
+ register u_long p_len;
+{
+ register struct tbf *t = vifp->v_tbf;
+
+ if (p_len > MAX_BKT_SIZE) {
+ /* drop if packet is too large */
+ mrtstat.mrts_pkt2large++;
+ m_freem(m);
+ return;
+ }
+
+ tbf_update_tokens(vifp);
+
+ /* if there are enough tokens,
+ * and the queue is empty,
+ * send this packet out
+ */
+
+ if (t->tbf_q_len == 0) {
+ /* queue empty, send packet if enough tokens */
+ if (p_len <= t->tbf_n_tok) {
+ t->tbf_n_tok -= p_len;
+ tbf_send_packet(vifp, m);
+ } else {
+ /* queue packet and timeout till later */
+ tbf_queue(vifp, m);
+ timeout(tbf_reprocess_q, (caddr_t)vifp, TBF_REPROCESS);
+ }
+ } else if (t->tbf_q_len < t->tbf_max_q_len) {
+ /* finite queue length, so queue pkts and process queue */
+ tbf_queue(vifp, m);
+ tbf_process_q(vifp);
+ } else {
+ /* queue length too much, try to dq and queue and process */
+ if (!tbf_dq_sel(vifp, ip)) {
+ mrtstat.mrts_q_overflow++;
+ m_freem(m);
+ return;
+ } else {
+ tbf_queue(vifp, m);
+ tbf_process_q(vifp);
+ }
+ }
+ return;
+}
+
+/*
+ * adds a packet to the queue at the interface
+ */
+static void
+tbf_queue(vifp, m)
+ register struct vif *vifp;
+ register struct mbuf *m;
+{
+ register int s = splnet();
+ register struct tbf *t = vifp->v_tbf;
+
+ if (t->tbf_t == NULL) {
+ /* Queue was empty */
+ t->tbf_q = m;
+ } else {
+ /* Insert at tail */
+ t->tbf_t->m_act = m;
+ }
+
+ /* Set new tail pointer */
+ t->tbf_t = m;
+
+#ifdef DIAGNOSTIC
+ /* Make sure we didn't get fed a bogus mbuf */
+ if (m->m_act)
+ panic("tbf_queue: m_act");
+#endif
+ m->m_act = NULL;
+
+ t->tbf_q_len++;
+
+ splx(s);
+}
+
+
+/*
+ * processes the queue at the interface
+ */
+static void
+tbf_process_q(vifp)
+ register struct vif *vifp;
+{
+ register struct mbuf *m;
+ register int len;
+ register int s = splnet();
+ register struct tbf *t = vifp->v_tbf;
+
+ /* loop through the queue at the interface and send as many packets
+ * as possible
+ */
+ while (t->tbf_q_len > 0) {
+ m = t->tbf_q;
+
+ len = mtod(m, struct ip *)->ip_len;
+
+ /* determine if the packet can be sent */
+ if (len <= t->tbf_n_tok) {
+ /* if so,
+ * reduce no of tokens, dequeue the packet,
+ * send the packet.
+ */
+ t->tbf_n_tok -= len;
+
+ t->tbf_q = m->m_act;
+ if (--t->tbf_q_len == 0)
+ t->tbf_t = NULL;
+
+ m->m_act = NULL;
+ tbf_send_packet(vifp, m);
+
+ } else break;
+ }
+ splx(s);
+}
+
+static void
+tbf_reprocess_q(xvifp)
+ void *xvifp;
+{
+ register struct vif *vifp = xvifp;
+ if (ip_mrouter == NULL)
+ return;
+
+ tbf_update_tokens(vifp);
+
+ tbf_process_q(vifp);
+
+ if (vifp->v_tbf->tbf_q_len)
+ timeout(tbf_reprocess_q, (caddr_t)vifp, TBF_REPROCESS);
+}
+
+/* function that will selectively discard a member of the queue
+ * based on the precedence value and the priority
+ */
+static int
+tbf_dq_sel(vifp, ip)
+ register struct vif *vifp;
+ register struct ip *ip;
+{
+ register int s = splnet();
+ register u_int p;
+ register struct mbuf *m, *last;
+ register struct mbuf **np;
+ register struct tbf *t = vifp->v_tbf;
+
+ p = priority(vifp, ip);
+
+ np = &t->tbf_q;
+ last = NULL;
+ while ((m = *np) != NULL) {
+ if (p > priority(vifp, mtod(m, struct ip *))) {
+ *np = m->m_act;
+ /* If we're removing the last packet, fix the tail pointer */
+ if (m == t->tbf_t)
+ t->tbf_t = last;
+ m_freem(m);
+ /* it's impossible for the queue to be empty, but
+ * we check anyway. */
+ if (--t->tbf_q_len == 0)
+ t->tbf_t = NULL;
+ splx(s);
+ mrtstat.mrts_drop_sel++;
+ return(1);
+ }
+ np = &m->m_act;
+ last = m;
+ }
+ splx(s);
+ return(0);
+}
+
+static void
+tbf_send_packet(vifp, m)
+ register struct vif *vifp;
+ register struct mbuf *m;
+{
+ struct ip_moptions imo;
+ int error;
+ static struct route ro;
+ int s = splnet();
+
+ if (vifp->v_flags & VIFF_TUNNEL) {
+ /* If tunnel options */
+ ip_output(m, (struct mbuf *)0, &vifp->v_route,
+ IP_FORWARDING, (struct ip_moptions *)0);
+ } else {
+ imo.imo_multicast_ifp = vifp->v_ifp;
+ imo.imo_multicast_ttl = mtod(m, struct ip *)->ip_ttl - 1;
+ imo.imo_multicast_loop = 1;
+ imo.imo_multicast_vif = -1;
+
+ /*
+ * Re-entrancy should not be a problem here, because
+ * the packets that we send out and are looped back at us
+ * should get rejected because they appear to come from
+ * the loopback interface, thus preventing looping.
+ */
+ error = ip_output(m, (struct mbuf *)0, &ro,
+ IP_FORWARDING, &imo);
+
+ if (mrtdebug & DEBUG_XMIT)
+ log(LOG_DEBUG, "phyint_send on vif %d err %d\n",
+ vifp - viftable, error);
+ }
+ splx(s);
+}
+
+/* determine the current time and then
+ * the elapsed time (between the last time and time now)
+ * in milliseconds & update the no. of tokens in the bucket
+ */
+static void
+tbf_update_tokens(vifp)
+ register struct vif *vifp;
+{
+ struct timeval tp;
+ register u_long tm;
+ register int s = splnet();
+ register struct tbf *t = vifp->v_tbf;
+
+ GET_TIME(tp);
+
+ TV_DELTA(tp, t->tbf_last_pkt_t, tm);
+
+ /*
+ * This formula is actually
+ * "time in seconds" * "bytes/second".
+ *
+ * (tm / 1000000) * (v_rate_limit * 1000 * (1000/1024) / 8)
+ *
+ * The (1000/1024) was introduced in add_vif to optimize
+ * this divide into a shift.
+ */
+ t->tbf_n_tok += tm * vifp->v_rate_limit / 1024 / 8;
+ t->tbf_last_pkt_t = tp;
+
+ if (t->tbf_n_tok > MAX_BKT_SIZE)
+ t->tbf_n_tok = MAX_BKT_SIZE;
+
+ splx(s);
+}
+
+static int
+priority(vifp, ip)
+ register struct vif *vifp;
+ register struct ip *ip;
+{
+ register int prio;
+
+ /* temporary hack; may add general packet classifier some day */
+
+ /*
+ * The UDP port space is divided up into four priority ranges:
+ * [0, 16384) : unclassified - lowest priority
+ * [16384, 32768) : audio - highest priority
+ * [32768, 49152) : whiteboard - medium priority
+ * [49152, 65536) : video - low priority
+ */
+ if (ip->ip_p == IPPROTO_UDP) {
+ struct udphdr *udp = (struct udphdr *)(((char *)ip) + (ip->ip_hl << 2));
+ switch (ntohs(udp->uh_dport) & 0xc000) {
+ case 0x4000:
+ prio = 70;
+ break;
+ case 0x8000:
+ prio = 60;
+ break;
+ case 0xc000:
+ prio = 55;
+ break;
+ default:
+ prio = 50;
+ break;
+ }
+ if (tbfdebug > 1)
+ log(LOG_DEBUG, "port %x prio%d\n", ntohs(udp->uh_dport), prio);
+ } else {
+ prio = 50;
+ }
+ return prio;
+}
+
+/*
+ * End of token bucket filter modifications
+ */
+
+int
+ip_rsvp_vif_init(so, m)
+ struct socket *so;
+ struct mbuf *m;
+{
+ int i;
+ register int s;
+
+ if (rsvpdebug)
+ printf("ip_rsvp_vif_init: so_type = %d, pr_protocol = %d\n",
+ so->so_type, so->so_proto->pr_protocol);
+
+ if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP)
+ return EOPNOTSUPP;
+
+ /* Check mbuf. */
+ if (m == NULL || m->m_len != sizeof(int)) {
+ return EINVAL;
+ }
+ i = *(mtod(m, int *));
+
+ if (rsvpdebug)
+ printf("ip_rsvp_vif_init: vif = %d rsvp_on = %d\n",i,rsvp_on);
+
+ s = splnet();
+
+ /* Check vif. */
+ if (!legal_vif_num(i)) {
+ splx(s);
+ return EADDRNOTAVAIL;
+ }
+
+ /* Check if socket is available. */
+ if (viftable[i].v_rsvpd != NULL) {
+ splx(s);
+ return EADDRINUSE;
+ }
+
+ viftable[i].v_rsvpd = so;
+ /* This may seem silly, but we need to be sure we don't over-increment
+ * the RSVP counter, in case something slips up.
+ */
+ if (!viftable[i].v_rsvp_on) {
+ viftable[i].v_rsvp_on = 1;
+ rsvp_on++;
+ }
+
+ splx(s);
+ return 0;
+}
+
+int
+ip_rsvp_vif_done(so, m)
+ struct socket *so;
+ struct mbuf *m;
+{
+ int i;
+ register int s;
+
+ if (rsvpdebug)
+ printf("ip_rsvp_vif_done: so_type = %d, pr_protocol = %d\n",
+ so->so_type, so->so_proto->pr_protocol);
+
+ if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP)
+ return EOPNOTSUPP;
+
+ /* Check mbuf. */
+ if (m == NULL || m->m_len != sizeof(int)) {
+ return EINVAL;
+ }
+ i = *(mtod(m, int *));
+
+ s = splnet();
+
+ /* Check vif. */
+ if (!legal_vif_num(i)) {
+ splx(s);
+ return EADDRNOTAVAIL;
+ }
+
+ if (rsvpdebug)
+ printf("ip_rsvp_vif_done: v_rsvpd = %p so = %p\n",
+ viftable[i].v_rsvpd, so);
+
+ viftable[i].v_rsvpd = NULL;
+ /* This may seem silly, but we need to be sure we don't over-decrement
+ * the RSVP counter, in case something slips up.
+ */
+ if (viftable[i].v_rsvp_on) {
+ viftable[i].v_rsvp_on = 0;
+ rsvp_on--;
+ }
+
+ splx(s);
+ return 0;
+}
+
+void
+ip_rsvp_force_done(so)
+ struct socket *so;
+{
+ int vifi;
+ register int s;
+
+ /* Don't bother if it is not the right type of socket. */
+ if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP)
+ return;
+
+ s = splnet();
+
+ /* The socket may be attached to more than one vif...this
+ * is perfectly legal.
+ */
+ for (vifi = 0; vifi < numvifs; vifi++) {
+ if (viftable[vifi].v_rsvpd == so) {
+ viftable[vifi].v_rsvpd = NULL;
+ /* This may seem silly, but we need to be sure we don't
+ * over-decrement the RSVP counter, in case something slips up.
+ */
+ if (viftable[vifi].v_rsvp_on) {
+ viftable[vifi].v_rsvp_on = 0;
+ rsvp_on--;
+ }
+ }
+ }
+
+ splx(s);
+ return;
+}
+
+void
+rsvp_input(m, iphlen)
+ struct mbuf *m;
+ int iphlen;
+{
+ int vifi;
+ register struct ip *ip = mtod(m, struct ip *);
+ static struct sockaddr_in rsvp_src = { sizeof rsvp_src, AF_INET };
+ register int s;
+ struct ifnet *ifp;
+
+ if (rsvpdebug)
+ printf("rsvp_input: rsvp_on %d\n",rsvp_on);
+
+ /* Can still get packets with rsvp_on = 0 if there is a local member
+ * of the group to which the RSVP packet is addressed. But in this
+ * case we want to throw the packet away.
+ */
+ if (!rsvp_on) {
+ m_freem(m);
+ return;
+ }
+
+ /* If the old-style non-vif-associated socket is set, then use
+ * it and ignore the new ones.
+ */
+ if (ip_rsvpd != NULL) {
+ if (rsvpdebug)
+ printf("rsvp_input: Sending packet up old-style socket\n");
+ rip_input(m, iphlen);
+ return;
+ }
+
+ s = splnet();
+
+ if (rsvpdebug)
+ printf("rsvp_input: check vifs\n");
+
+#ifdef DIAGNOSTIC
+ if (!(m->m_flags & M_PKTHDR))
+ panic("rsvp_input no hdr");
+#endif
+
+ ifp = m->m_pkthdr.rcvif;
+ /* Find which vif the packet arrived on. */
+ for (vifi = 0; vifi < numvifs; vifi++) {
+ if (viftable[vifi].v_ifp == ifp)
+ break;
+ }
+
+ if (vifi == numvifs) {
+ /* Can't find vif packet arrived on. Drop packet. */
+ if (rsvpdebug)
+ printf("rsvp_input: Can't find vif for packet...dropping it.\n");
+ m_freem(m);
+ splx(s);
+ return;
+ }
+
+ if (rsvpdebug)
+ printf("rsvp_input: check socket\n");
+
+ if (viftable[vifi].v_rsvpd == NULL) {
+ /* drop packet, since there is no specific socket for this
+ * interface */
+ if (rsvpdebug)
+ printf("rsvp_input: No socket defined for vif %d\n",vifi);
+ m_freem(m);
+ splx(s);
+ return;
+ }
+ rsvp_src.sin_addr = ip->ip_src;
+
+ if (rsvpdebug && m)
+ printf("rsvp_input: m->m_len = %d, sbspace() = %ld\n",
+ m->m_len,sbspace(&(viftable[vifi].v_rsvpd->so_rcv)));
+
+ if (socket_send(viftable[vifi].v_rsvpd, m, &rsvp_src) < 0)
+ if (rsvpdebug)
+ printf("rsvp_input: Failed to append to socket\n");
+ else
+ if (rsvpdebug)
+ printf("rsvp_input: send packet up\n");
+
+ splx(s);
+}
+
+#ifdef MROUTE_LKM
+#include <sys/conf.h>
+#include <sys/exec.h>
+#include <sys/sysent.h>
+#include <sys/lkm.h>
+
+MOD_MISC("ip_mroute_mod")
+
+static int
+ip_mroute_mod_handle(struct lkm_table *lkmtp, int cmd)
+{
+ int i;
+ struct lkm_misc *args = lkmtp->private.lkm_misc;
+ int err = 0;
+
+ switch(cmd) {
+ static int (*old_ip_mrouter_cmd)();
+ static int (*old_ip_mrouter_done)();
+ static int (*old_ip_mforward)();
+ static int (*old_mrt_ioctl)();
+ static void (*old_proto4_input)();
+ static int (*old_legal_vif_num)();
+ extern struct protosw inetsw[];
+
+ case LKM_E_LOAD:
+ if(lkmexists(lkmtp) || ip_mrtproto)
+ return(EEXIST);
+ old_ip_mrouter_cmd = ip_mrouter_cmd;
+ ip_mrouter_cmd = X_ip_mrouter_cmd;
+ old_ip_mrouter_done = ip_mrouter_done;
+ ip_mrouter_done = X_ip_mrouter_done;
+ old_ip_mforward = ip_mforward;
+ ip_mforward = X_ip_mforward;
+ old_mrt_ioctl = mrt_ioctl;
+ mrt_ioctl = X_mrt_ioctl;
+ old_proto4_input = inetsw[ip_protox[ENCAP_PROTO]].pr_input;
+ inetsw[ip_protox[ENCAP_PROTO]].pr_input = X_ipip_input;
+ old_legal_vif_num = legal_vif_num;
+ legal_vif_num = X_legal_vif_num;
+ ip_mrtproto = IGMP_DVMRP;
+
+ printf("\nIP multicast routing loaded\n");
+ break;
+
+ case LKM_E_UNLOAD:
+ if (ip_mrouter)
+ return EINVAL;
+
+ ip_mrouter_cmd = old_ip_mrouter_cmd;
+ ip_mrouter_done = old_ip_mrouter_done;
+ ip_mforward = old_ip_mforward;
+ mrt_ioctl = old_mrt_ioctl;
+ inetsw[ip_protox[ENCAP_PROTO]].pr_input = old_proto4_input;
+ legal_vif_num = old_legal_vif_num;
+ ip_mrtproto = 0;
+ break;
+
+ default:
+ err = EINVAL;
+ break;
+ }
+
+ return(err);
+}
+
+int
+ip_mroute_mod(struct lkm_table *lkmtp, int cmd, int ver) {
+ DISPATCH(lkmtp, cmd, ver, ip_mroute_mod_handle, ip_mroute_mod_handle,
+ nosys);
+}
+
+#endif /* MROUTE_LKM */
+#endif /* MROUTING */
diff --git a/cpukit/libnetworking/netinet/ip_mroute.h b/cpukit/libnetworking/netinet/ip_mroute.h
new file mode 100644
index 0000000000..35d2437089
--- /dev/null
+++ b/cpukit/libnetworking/netinet/ip_mroute.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 1989 Stephen Deering.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Stephen Deering of Stanford University.
+ *
+ * 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.
+ *
+ * @(#)ip_mroute.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NETINET_IP_MROUTE_H_
+#define _NETINET_IP_MROUTE_H_
+
+/*
+ * Definitions for IP multicast forwarding.
+ *
+ * Written by David Waitzman, BBN Labs, August 1988.
+ * Modified by Steve Deering, Stanford, February 1989.
+ * Modified by Ajit Thyagarajan, PARC, August 1993.
+ * Modified by Ajit Thyagarajan, PARC, August 1994.
+ *
+ * MROUTING Revision: 3.3.1.3
+ */
+
+
+/*
+ * Multicast Routing set/getsockopt commands.
+ */
+#define MRT_INIT 100 /* initialize forwarder */
+#define MRT_DONE 101 /* shut down forwarder */
+#define MRT_ADD_VIF 102 /* create virtual interface */
+#define MRT_DEL_VIF 103 /* delete virtual interface */
+#define MRT_ADD_MFC 104 /* insert forwarding cache entry */
+#define MRT_DEL_MFC 105 /* delete forwarding cache entry */
+#define MRT_VERSION 106 /* get kernel version number */
+#define MRT_ASSERT 107 /* enable PIM assert processing */
+
+
+#define GET_TIME(t) microtime(&t)
+
+/*
+ * Types and macros for handling bitmaps with one bit per virtual interface.
+ */
+#define MAXVIFS 32
+typedef u_long vifbitmap_t;
+typedef u_short vifi_t; /* type of a vif index */
+#define ALL_VIFS (vifi_t)-1
+
+#define VIFM_SET(n, m) ((m) |= (1 << (n)))
+#define VIFM_CLR(n, m) ((m) &= ~(1 << (n)))
+#define VIFM_ISSET(n, m) ((m) & (1 << (n)))
+#define VIFM_CLRALL(m) ((m) = 0x00000000)
+#define VIFM_COPY(mfrom, mto) ((mto) = (mfrom))
+#define VIFM_SAME(m1, m2) ((m1) == (m2))
+
+
+/*
+ * Argument structure for MRT_ADD_VIF.
+ * (MRT_DEL_VIF takes a single vifi_t argument.)
+ */
+struct vifctl {
+ vifi_t vifc_vifi; /* the index of the vif to be added */
+ u_char vifc_flags; /* VIFF_ flags defined below */
+ u_char vifc_threshold; /* min ttl required to forward on vif */
+ u_int vifc_rate_limit; /* max rate */
+ struct in_addr vifc_lcl_addr; /* local interface address */
+ struct in_addr vifc_rmt_addr; /* remote address (tunnels only) */
+};
+
+#define VIFF_TUNNEL 0x1 /* vif represents a tunnel end-point */
+#define VIFF_SRCRT 0x2 /* tunnel uses IP source routing */
+
+/*
+ * Argument structure for MRT_ADD_MFC and MRT_DEL_MFC
+ * (mfcc_tos to be added at a future point)
+ */
+struct mfcctl {
+ struct in_addr mfcc_origin; /* ip origin of mcasts */
+ struct in_addr mfcc_mcastgrp; /* multicast group associated*/
+ vifi_t mfcc_parent; /* incoming vif */
+ u_char mfcc_ttls[MAXVIFS]; /* forwarding ttls on vifs */
+};
+
+/*
+ * The kernel's multicast routing statistics.
+ */
+struct mrtstat {
+ u_long mrts_mfc_lookups; /* # forw. cache hash table hits */
+ u_long mrts_mfc_misses; /* # forw. cache hash table misses */
+ u_long mrts_upcalls; /* # calls to mrouted */
+ u_long mrts_no_route; /* no route for packet's origin */
+ u_long mrts_bad_tunnel; /* malformed tunnel options */
+ u_long mrts_cant_tunnel; /* no room for tunnel options */
+ u_long mrts_wrong_if; /* arrived on wrong interface */
+ u_long mrts_upq_ovflw; /* upcall Q overflow */
+ u_long mrts_cache_cleanups; /* # entries with no upcalls */
+ u_long mrts_drop_sel; /* pkts dropped selectively */
+ u_long mrts_q_overflow; /* pkts dropped - Q overflow */
+ u_long mrts_pkt2large; /* pkts dropped - size > BKT SIZE */
+ u_long mrts_upq_sockfull; /* upcalls dropped - socket full */
+};
+
+/*
+ * Argument structure used by mrouted to get src-grp pkt counts
+ */
+struct sioc_sg_req {
+ struct in_addr src;
+ struct in_addr grp;
+ u_long pktcnt;
+ u_long bytecnt;
+ u_long wrong_if;
+};
+
+/*
+ * Argument structure used by mrouted to get vif pkt counts
+ */
+struct sioc_vif_req {
+ vifi_t vifi; /* vif number */
+ u_long icount; /* Input packet count on vif */
+ u_long ocount; /* Output packet count on vif */
+ u_long ibytes; /* Input byte count on vif */
+ u_long obytes; /* Output byte count on vif */
+};
+
+
+/*
+ * The kernel's virtual-interface structure.
+ */
+struct vif {
+ u_char v_flags; /* VIFF_ flags defined above */
+ u_char v_threshold; /* min ttl required to forward on vif*/
+ u_int v_rate_limit; /* max rate */
+ struct tbf *v_tbf; /* token bucket structure at intf. */
+ struct in_addr v_lcl_addr; /* local interface address */
+ struct in_addr v_rmt_addr; /* remote address (tunnels only) */
+ struct ifnet *v_ifp; /* pointer to interface */
+ u_long v_pkt_in; /* # pkts in on interface */
+ u_long v_pkt_out; /* # pkts out on interface */
+ u_long v_bytes_in; /* # bytes in on interface */
+ u_long v_bytes_out; /* # bytes out on interface */
+ struct route v_route; /* cached route if this is a tunnel */
+ u_int v_rsvp_on; /* RSVP listening on this vif */
+ struct socket *v_rsvpd; /* RSVP daemon socket */
+};
+
+/*
+ * The kernel's multicast forwarding cache entry structure
+ * (A field for the type of service (mfc_tos) is to be added
+ * at a future point)
+ */
+struct mfc {
+ struct in_addr mfc_origin; /* IP origin of mcasts */
+ struct in_addr mfc_mcastgrp; /* multicast group associated*/
+ vifi_t mfc_parent; /* incoming vif */
+ u_char mfc_ttls[MAXVIFS]; /* forwarding ttls on vifs */
+ u_long mfc_pkt_cnt; /* pkt count for src-grp */
+ u_long mfc_byte_cnt; /* byte count for src-grp */
+ u_long mfc_wrong_if; /* wrong if for src-grp */
+ int mfc_expire; /* time to clean entry up */
+ struct timeval mfc_last_assert; /* last time I sent an assert*/
+};
+
+/*
+ * Struct used to communicate from kernel to multicast router
+ * note the convenient similarity to an IP packet
+ */
+struct igmpmsg {
+ u_long unused1;
+ u_long unused2;
+ u_char im_msgtype; /* what type of message */
+#define IGMPMSG_NOCACHE 1
+#define IGMPMSG_WRONGVIF 2
+ u_char im_mbz; /* must be zero */
+ u_char im_vif; /* vif rec'd on */
+ u_char unused3;
+ struct in_addr im_src, im_dst;
+};
+
+/*
+ * Argument structure used for pkt info. while upcall is made
+ */
+struct rtdetq {
+ struct mbuf *m; /* A copy of the packet */
+ struct ifnet *ifp; /* Interface pkt came in on */
+ vifi_t xmt_vif; /* Saved copy of imo_multicast_vif */
+#ifdef UPCALL_TIMING
+ struct timeval t; /* Timestamp */
+#endif /* UPCALL_TIMING */
+};
+
+#define MFCTBLSIZ 256
+#if (MFCTBLSIZ & (MFCTBLSIZ - 1)) == 0 /* from sys:route.h */
+#define MFCHASHMOD(h) ((h) & (MFCTBLSIZ - 1))
+#else
+#define MFCHASHMOD(h) ((h) % MFCTBLSIZ)
+#endif
+
+#define MAX_UPQ 4 /* max. no of pkts in upcall Q */
+
+/*
+ * Token Bucket filter code
+ */
+#define MAX_BKT_SIZE 10000 /* 10K bytes size */
+#define MAXQSIZE 10 /* max # of pkts in queue */
+
+/*
+ * the token bucket filter at each vif
+ */
+struct tbf
+{
+ struct timeval tbf_last_pkt_t; /* arr. time of last pkt */
+ u_long tbf_n_tok; /* no of tokens in bucket */
+ u_long tbf_q_len; /* length of queue at this vif */
+ u_long tbf_max_q_len; /* max. queue length */
+ struct mbuf *tbf_q; /* Packet queue */
+ struct mbuf *tbf_t; /* tail-insertion pointer */
+};
+
+#ifdef _KERNEL
+
+extern int (*ip_mrouter_set) __P((int, struct socket *, struct mbuf *));
+extern int (*ip_mrouter_get) __P((int, struct socket *, struct mbuf **));
+extern int (*ip_mrouter_done) __P((void));
+#ifdef MROUTING
+extern int (*mrt_ioctl) __P((int, caddr_t));
+#else
+extern int (*mrt_ioctl) __P((int, caddr_t, struct proc *));
+#endif
+
+#endif /* _KERNEL */
+
+#endif /* _NETINET_IP_MROUTE_H_ */
diff --git a/cpukit/libnetworking/netinet/ip_output.c b/cpukit/libnetworking/netinet/ip_output.c
new file mode 100644
index 0000000000..8d4a2e8a7f
--- /dev/null
+++ b/cpukit/libnetworking/netinet/ip_output.c
@@ -0,0 +1,1307 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 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.
+ *
+ * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
+ * $Id$
+ */
+
+#define _IP_VHL
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/errno.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+
+#ifdef vax
+#include <machine/mtpr.h>
+#endif
+#include <machine/in_cksum.h>
+
+#if !defined(COMPAT_IPFW) || COMPAT_IPFW == 1
+#undef COMPAT_IPFW
+#define COMPAT_IPFW 1
+#else
+#undef COMPAT_IPFW
+#endif
+
+u_short ip_id;
+
+static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *));
+static void ip_mloopback
+ __P((struct ifnet *, struct mbuf *, struct sockaddr_in *, int));
+static int ip_getmoptions
+ __P((int, struct ip_moptions *, struct mbuf **));
+static int ip_optcopy __P((struct ip *, struct ip *));
+static int ip_pcbopts __P((struct mbuf **, struct mbuf *));
+static int ip_setmoptions
+ __P((int, struct ip_moptions **, struct mbuf *));
+
+extern struct protosw inetsw[];
+
+/*
+ * IP output. The packet in mbuf chain m contains a skeletal IP
+ * header (with len, off, ttl, proto, tos, src, dst).
+ * The mbuf chain containing the packet will be freed.
+ * The mbuf opt, if present, will not be freed.
+ */
+int
+ip_output(m0, opt, ro, flags, imo)
+ struct mbuf *m0;
+ struct mbuf *opt;
+ struct route *ro;
+ int flags;
+ struct ip_moptions *imo;
+{
+ struct ip *ip, *mhip;
+ struct ifnet *ifp;
+ struct mbuf *m = m0;
+ int hlen = sizeof (struct ip);
+ int len = 0, off, error = 0;
+ struct sockaddr_in *dst;
+ struct in_ifaddr *ia;
+ int isbroadcast;
+
+#ifdef DIAGNOSTIC
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("ip_output no HDR");
+ if (!ro)
+ panic("ip_output no route, proto = %d",
+ mtod(m, struct ip *)->ip_p);
+#endif
+ if (opt) {
+ m = ip_insertoptions(m, opt, &len);
+ hlen = len;
+ }
+ ip = mtod(m, struct ip *);
+ /*
+ * Fill in IP header.
+ */
+ if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
+ ip->ip_vhl = IP_MAKE_VHL(IPVERSION, hlen >> 2);
+ ip->ip_off &= IP_DF;
+ ip->ip_id = htons(ip_id++);
+ ipstat.ips_localout++;
+ } else {
+ hlen = IP_VHL_HL(ip->ip_vhl) << 2;
+ }
+
+ dst = (struct sockaddr_in *)&ro->ro_dst;
+ /*
+ * If there is a cached route,
+ * check that it is to the same destination
+ * and is still up. If not, free it and try again.
+ */
+ if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
+ dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
+ RTFREE(ro->ro_rt);
+ ro->ro_rt = (struct rtentry *)0;
+ }
+ if (ro->ro_rt == 0) {
+ dst->sin_family = AF_INET;
+ dst->sin_len = sizeof(*dst);
+ dst->sin_addr = ip->ip_dst;
+ }
+ /*
+ * If routing to interface only,
+ * short circuit routing lookup.
+ */
+#define ifatoia(ifa) ((struct in_ifaddr *)(ifa))
+#define sintosa(sin) ((struct sockaddr *)(sin))
+ if (flags & IP_ROUTETOIF) {
+ if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 &&
+ (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) {
+ ipstat.ips_noroute++;
+ error = ENETUNREACH;
+ goto bad;
+ }
+ ifp = ia->ia_ifp;
+ ip->ip_ttl = 1;
+ isbroadcast = in_broadcast(dst->sin_addr, ifp);
+ } else {
+ /*
+ * If this is the case, we probably don't want to allocate
+ * a protocol-cloned route since we didn't get one from the
+ * ULP. This lets TCP do its thing, while not burdening
+ * forwarding or ICMP with the overhead of cloning a route.
+ * Of course, we still want to do any cloning requested by
+ * the link layer, as this is probably required in all cases
+ * for correct operation (as it is for ARP).
+ */
+ if (ro->ro_rt == 0)
+ rtalloc_ign(ro, RTF_PRCLONING);
+ if (ro->ro_rt == 0) {
+ ipstat.ips_noroute++;
+ error = EHOSTUNREACH;
+ goto bad;
+ }
+ ia = ifatoia(ro->ro_rt->rt_ifa);
+ ifp = ro->ro_rt->rt_ifp;
+ ro->ro_rt->rt_use++;
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY)
+ dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
+ if (ro->ro_rt->rt_flags & RTF_HOST)
+ isbroadcast = (ro->ro_rt->rt_flags & RTF_BROADCAST);
+ else
+ isbroadcast = in_broadcast(dst->sin_addr, ifp);
+ }
+ if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
+ struct in_multi *inm;
+
+ m->m_flags |= M_MCAST;
+ /*
+ * IP destination address is multicast. Make sure "dst"
+ * still points to the address in "ro". (It may have been
+ * changed to point to a gateway address, above.)
+ */
+ dst = (struct sockaddr_in *)&ro->ro_dst;
+ /*
+ * See if the caller provided any multicast options
+ */
+ if (imo != NULL) {
+ ip->ip_ttl = imo->imo_multicast_ttl;
+ if (imo->imo_multicast_ifp != NULL)
+ ifp = imo->imo_multicast_ifp;
+ if (imo->imo_multicast_vif != -1)
+ ip->ip_src.s_addr =
+ ip_mcast_src(imo->imo_multicast_vif);
+ } else
+ ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL;
+ /*
+ * Confirm that the outgoing interface supports multicast.
+ */
+ if ((imo == NULL) || (imo->imo_multicast_vif == -1)) {
+ if ((ifp->if_flags & IFF_MULTICAST) == 0) {
+ ipstat.ips_noroute++;
+ error = ENETUNREACH;
+ goto bad;
+ }
+ }
+ /*
+ * If source address not specified yet, use address
+ * of outgoing interface.
+ */
+ if (ip->ip_src.s_addr == INADDR_ANY) {
+ register struct in_ifaddr *ia;
+
+ for (ia = in_ifaddr; ia; ia = ia->ia_next)
+ if (ia->ia_ifp == ifp) {
+ ip->ip_src = IA_SIN(ia)->sin_addr;
+ break;
+ }
+ }
+
+ IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm);
+ if (inm != NULL &&
+ (imo == NULL || imo->imo_multicast_loop)) {
+ /*
+ * If we belong to the destination multicast group
+ * on the outgoing interface, and the caller did not
+ * forbid loopback, loop back a copy.
+ */
+ ip_mloopback(ifp, m, dst, hlen);
+ }
+ else {
+ /*
+ * If we are acting as a multicast router, perform
+ * multicast forwarding as if the packet had just
+ * arrived on the interface to which we are about
+ * to send. The multicast forwarding function
+ * recursively calls this function, using the
+ * IP_FORWARDING flag to prevent infinite recursion.
+ *
+ * Multicasts that are looped back by ip_mloopback(),
+ * above, will be forwarded by the ip_input() routine,
+ * if necessary.
+ */
+ if (ip_mrouter && (flags & IP_FORWARDING) == 0) {
+ /*
+ * Check if rsvp daemon is running. If not, don't
+ * set ip_moptions. This ensures that the packet
+ * is multicast and not just sent down one link
+ * as prescribed by rsvpd.
+ */
+ if (!rsvp_on)
+ imo = NULL;
+ if (ip_mforward(ip, ifp, m, imo) != 0) {
+ m_freem(m);
+ goto done;
+ }
+ }
+ }
+
+ /*
+ * Multicasts with a time-to-live of zero may be looped-
+ * back, above, but must not be transmitted on a network.
+ * Also, multicasts addressed to the loopback interface
+ * are not sent -- the above call to ip_mloopback() will
+ * loop back a copy if this host actually belongs to the
+ * destination group on the loopback interface.
+ */
+ if (ip->ip_ttl == 0 || ifp->if_flags & IFF_LOOPBACK) {
+ m_freem(m);
+ goto done;
+ }
+
+ goto sendit;
+ }
+#ifndef notdef
+ /*
+ * If source address not specified yet, use address
+ * of outgoing interface.
+ */
+ if (ip->ip_src.s_addr == INADDR_ANY)
+ ip->ip_src = IA_SIN(ia)->sin_addr;
+#endif
+ /*
+ * Verify that we have any chance at all of being able to queue
+ * the packet or packet fragments
+ */
+ if ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >=
+ ifp->if_snd.ifq_maxlen) {
+ error = ENOBUFS;
+ goto bad;
+ }
+
+ /*
+ * Look for broadcast address and
+ * and verify user is allowed to send
+ * such a packet.
+ */
+ if (isbroadcast) {
+ if ((ifp->if_flags & IFF_BROADCAST) == 0) {
+ error = EADDRNOTAVAIL;
+ goto bad;
+ }
+ if ((flags & IP_ALLOWBROADCAST) == 0) {
+ error = EACCES;
+ goto bad;
+ }
+ /* don't allow broadcast messages to be fragmented */
+ if ((u_short)ip->ip_len > ifp->if_mtu) {
+ error = EMSGSIZE;
+ goto bad;
+ }
+ m->m_flags |= M_BCAST;
+ } else {
+ m->m_flags &= ~M_BCAST;
+ }
+
+sendit:
+ /*
+ * IpHack's section.
+ * - Xlate: translate packet's addr/port (NAT).
+ * - Firewall: deny/allow/etc.
+ * - Wrap: fake packet's addr/port <unimpl.>
+ * - Encapsulate: put it in another IP and send out. <unimp.>
+ */
+
+#ifdef COMPAT_IPFW
+ if (ip_nat_ptr && !(*ip_nat_ptr)(&ip, &m, ifp, IP_NAT_OUT)) {
+ error = EACCES;
+ goto done;
+ }
+
+ /*
+ * Check with the firewall...
+ */
+ if (ip_fw_chk_ptr) {
+#ifdef IPDIVERT
+ ip_divert_port = (*ip_fw_chk_ptr)(&ip,
+ hlen, ifp, ip_divert_ignore, &m);
+ ip_divert_ignore = 0;
+ if (ip_divert_port) { /* Divert packet */
+ (*inetsw[ip_protox[IPPROTO_DIVERT]].pr_input)(m, 0);
+ goto done;
+ }
+#else
+ /* If ipfw says divert, we have to just drop packet */
+ if ((*ip_fw_chk_ptr)(&ip, hlen, ifp, 0, &m)) {
+ m_freem(m);
+ goto done;
+ }
+#endif
+ if (!m) {
+ error = EACCES;
+ goto done;
+ }
+ }
+#endif /* COMPAT_IPFW */
+
+ /*
+ * If small enough for interface, can just send directly.
+ */
+ if ((u_short)ip->ip_len <= ifp->if_mtu) {
+ ip->ip_len = htons((u_short)ip->ip_len);
+ ip->ip_off = htons((u_short)ip->ip_off);
+ ip->ip_sum = 0;
+ if (ip->ip_vhl == IP_VHL_BORING) {
+ ip->ip_sum = in_cksum_hdr(ip);
+ } else {
+ ip->ip_sum = in_cksum(m, hlen);
+ }
+ error = (*ifp->if_output)(ifp, m,
+ (struct sockaddr *)dst, ro->ro_rt);
+ goto done;
+ }
+ /*
+ * Too large for interface; fragment if possible.
+ * Must be able to put at least 8 bytes per fragment.
+ */
+ if (ip->ip_off & IP_DF) {
+ error = EMSGSIZE;
+ /*
+ * This case can happen if the user changed the MTU
+ * of an interface after enabling IP on it. Because
+ * most netifs don't keep track of routes pointing to
+ * them, there is no way for one to update all its
+ * routes when the MTU is changed.
+ */
+ if ((ro->ro_rt->rt_flags & (RTF_UP | RTF_HOST))
+ && !(ro->ro_rt->rt_rmx.rmx_locks & RTV_MTU)
+ && (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)) {
+ ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu;
+ }
+ ipstat.ips_cantfrag++;
+ goto bad;
+ }
+ len = (ifp->if_mtu - hlen) &~ 7;
+ if (len < 8) {
+ error = EMSGSIZE;
+ goto bad;
+ }
+
+ {
+ int mhlen, firstlen = len;
+ struct mbuf **mnext = &m->m_nextpkt;
+
+ /*
+ * Loop through length of segment after first fragment,
+ * make new header and copy data of each part and link onto chain.
+ */
+ m0 = m;
+ mhlen = sizeof (struct ip);
+ for (off = hlen + len; off < (u_short)ip->ip_len; off += len) {
+ MGETHDR(m, M_DONTWAIT, MT_HEADER);
+ if (m == 0) {
+ error = ENOBUFS;
+ ipstat.ips_odropped++;
+ goto sendorfree;
+ }
+ m->m_data += max_linkhdr;
+ mhip = mtod(m, struct ip *);
+ *mhip = *ip;
+ if (hlen > sizeof (struct ip)) {
+ mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
+ mhip->ip_vhl = IP_MAKE_VHL(IPVERSION, mhlen >> 2);
+ }
+ m->m_len = mhlen;
+ mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
+ if (ip->ip_off & IP_MF)
+ mhip->ip_off |= IP_MF;
+ if (off + len >= (u_short)ip->ip_len)
+ len = (u_short)ip->ip_len - off;
+ else
+ mhip->ip_off |= IP_MF;
+ mhip->ip_len = htons((u_short)(len + mhlen));
+ m->m_next = m_copy(m0, off, len);
+ if (m->m_next == 0) {
+ (void) m_free(m);
+ error = ENOBUFS; /* ??? */
+ ipstat.ips_odropped++;
+ goto sendorfree;
+ }
+ m->m_pkthdr.len = mhlen + len;
+ m->m_pkthdr.rcvif = (struct ifnet *)0;
+ mhip->ip_off = htons((u_short)mhip->ip_off);
+ mhip->ip_sum = 0;
+ if (mhip->ip_vhl == IP_VHL_BORING) {
+ mhip->ip_sum = in_cksum_hdr(mhip);
+ } else {
+ mhip->ip_sum = in_cksum(m, mhlen);
+ }
+ *mnext = m;
+ mnext = &m->m_nextpkt;
+ ipstat.ips_ofragments++;
+ }
+ /*
+ * Update first fragment by trimming what's been copied out
+ * and updating header, then send each fragment (in order).
+ */
+ m = m0;
+ m_adj(m, hlen + firstlen - (u_short)ip->ip_len);
+ m->m_pkthdr.len = hlen + firstlen;
+ ip->ip_len = htons((u_short)m->m_pkthdr.len);
+ ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
+ ip->ip_sum = 0;
+ if (ip->ip_vhl == IP_VHL_BORING) {
+ ip->ip_sum = in_cksum_hdr(ip);
+ } else {
+ ip->ip_sum = in_cksum(m, hlen);
+ }
+sendorfree:
+ for (m = m0; m; m = m0) {
+ m0 = m->m_nextpkt;
+ m->m_nextpkt = 0;
+ if (error == 0)
+ error = (*ifp->if_output)(ifp, m,
+ (struct sockaddr *)dst, ro->ro_rt);
+ else
+ m_freem(m);
+ }
+
+ if (error == 0)
+ ipstat.ips_fragmented++;
+ }
+done:
+ return (error);
+bad:
+ m_freem(m0);
+ goto done;
+}
+
+/*
+ * Insert IP options into preformed packet.
+ * Adjust IP destination as required for IP source routing,
+ * as indicated by a non-zero in_addr at the start of the options.
+ *
+ * XXX This routine assumes that the packet has no options in place.
+ */
+static struct mbuf *
+ip_insertoptions(m, opt, phlen)
+ register struct mbuf *m;
+ struct mbuf *opt;
+ int *phlen;
+{
+ register struct ipoption *p = mtod(opt, struct ipoption *);
+ struct mbuf *n;
+ register struct ip *ip = mtod(m, struct ip *);
+ unsigned optlen;
+
+ optlen = opt->m_len - sizeof(p->ipopt_dst);
+ if (optlen + (u_short)ip->ip_len > IP_MAXPACKET)
+ return (m); /* XXX should fail */
+ if (p->ipopt_dst.s_addr)
+ ip->ip_dst = p->ipopt_dst;
+ if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) {
+ MGETHDR(n, M_DONTWAIT, MT_HEADER);
+ if (n == 0)
+ return (m);
+ n->m_pkthdr.len = m->m_pkthdr.len + optlen;
+ m->m_len -= sizeof(struct ip);
+ m->m_data += sizeof(struct ip);
+ n->m_next = m;
+ m = n;
+ m->m_len = optlen + sizeof(struct ip);
+ m->m_data += max_linkhdr;
+ (void)memcpy(mtod(m, void *), ip, sizeof(struct ip));
+ } else {
+ m->m_data -= optlen;
+ m->m_len += optlen;
+ m->m_pkthdr.len += optlen;
+ ovbcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip));
+ }
+ ip = mtod(m, struct ip *);
+ bcopy(p->ipopt_list, ip + 1, optlen);
+ *phlen = sizeof(struct ip) + optlen;
+ ip->ip_vhl = IP_MAKE_VHL(IPVERSION, *phlen >> 2);
+ ip->ip_len += optlen;
+ return (m);
+}
+
+/*
+ * Copy options from ip to jp,
+ * omitting those not copied during fragmentation.
+ */
+static int
+ip_optcopy(ip, jp)
+ struct ip *ip, *jp;
+{
+ register u_char *cp, *dp;
+ int opt, optlen, cnt;
+
+ cp = (u_char *)(ip + 1);
+ dp = (u_char *)(jp + 1);
+ cnt = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof (struct ip);
+ for (; cnt > 0; cnt -= optlen, cp += optlen) {
+ opt = cp[0];
+ if (opt == IPOPT_EOL)
+ break;
+ if (opt == IPOPT_NOP) {
+ /* Preserve for IP mcast tunnel's LSRR alignment. */
+ *dp++ = IPOPT_NOP;
+ optlen = 1;
+ continue;
+ } else
+ optlen = cp[IPOPT_OLEN];
+ /* bogus lengths should have been caught by ip_dooptions */
+ if (optlen > cnt)
+ optlen = cnt;
+ if (IPOPT_COPIED(opt)) {
+ bcopy(cp, dp, optlen);
+ dp += optlen;
+ }
+ }
+ for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++)
+ *dp++ = IPOPT_EOL;
+ return (optlen);
+}
+
+/*
+ * IP socket option processing.
+ */
+int
+ip_ctloutput(op, so, level, optname, mp)
+ int op;
+ struct socket *so;
+ int level, optname;
+ struct mbuf **mp;
+{
+ register struct inpcb *inp = sotoinpcb(so);
+ register struct mbuf *m = *mp;
+ register int optval = 0;
+ int error = 0;
+
+ if (level != IPPROTO_IP) {
+ error = EINVAL;
+ if (op == PRCO_SETOPT && *mp)
+ (void) m_free(*mp);
+ } else switch (op) {
+
+ case PRCO_SETOPT:
+ switch (optname) {
+ case IP_OPTIONS:
+#ifdef notyet
+ case IP_RETOPTS:
+ return (ip_pcbopts(optname, &inp->inp_options, m));
+#else
+ return (ip_pcbopts(&inp->inp_options, m));
+#endif
+
+ case IP_TOS:
+ case IP_TTL:
+ case IP_RECVOPTS:
+ case IP_RECVRETOPTS:
+ case IP_RECVDSTADDR:
+ case IP_RECVIF:
+ if (m == 0 || m->m_len != sizeof(int))
+ error = EINVAL;
+ else {
+ optval = *mtod(m, int *);
+ switch (optname) {
+
+ case IP_TOS:
+ inp->inp_ip_tos = optval;
+ break;
+
+ case IP_TTL:
+ inp->inp_ip_ttl = optval;
+ break;
+#define OPTSET(bit) \
+ if (optval) \
+ inp->inp_flags |= bit; \
+ else \
+ inp->inp_flags &= ~bit;
+
+ case IP_RECVOPTS:
+ OPTSET(INP_RECVOPTS);
+ break;
+
+ case IP_RECVRETOPTS:
+ OPTSET(INP_RECVRETOPTS);
+ break;
+
+ case IP_RECVDSTADDR:
+ OPTSET(INP_RECVDSTADDR);
+ break;
+
+ case IP_RECVIF:
+ OPTSET(INP_RECVIF);
+ break;
+ }
+ }
+ break;
+#undef OPTSET
+
+ case IP_MULTICAST_IF:
+ case IP_MULTICAST_VIF:
+ case IP_MULTICAST_TTL:
+ case IP_MULTICAST_LOOP:
+ case IP_ADD_MEMBERSHIP:
+ case IP_DROP_MEMBERSHIP:
+ error = ip_setmoptions(optname, &inp->inp_moptions, m);
+ break;
+
+ case IP_PORTRANGE:
+ if (m == 0 || m->m_len != sizeof(int))
+ error = EINVAL;
+ else {
+ optval = *mtod(m, int *);
+
+ switch (optval) {
+
+ case IP_PORTRANGE_DEFAULT:
+ inp->inp_flags &= ~(INP_LOWPORT);
+ inp->inp_flags &= ~(INP_HIGHPORT);
+ break;
+
+ case IP_PORTRANGE_HIGH:
+ inp->inp_flags &= ~(INP_LOWPORT);
+ inp->inp_flags |= INP_HIGHPORT;
+ break;
+
+ case IP_PORTRANGE_LOW:
+ inp->inp_flags &= ~(INP_HIGHPORT);
+ inp->inp_flags |= INP_LOWPORT;
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+ }
+ break;
+
+ default:
+ error = ENOPROTOOPT;
+ break;
+ }
+ if (m)
+ (void)m_free(m);
+ break;
+
+ case PRCO_GETOPT:
+ switch (optname) {
+ case IP_OPTIONS:
+ case IP_RETOPTS:
+ *mp = m = m_get(M_WAIT, MT_SOOPTS);
+ if (inp->inp_options) {
+ m->m_len = inp->inp_options->m_len;
+ bcopy(mtod(inp->inp_options, void *),
+ mtod(m, void *), m->m_len);
+ } else
+ m->m_len = 0;
+ break;
+
+ case IP_TOS:
+ case IP_TTL:
+ case IP_RECVOPTS:
+ case IP_RECVRETOPTS:
+ case IP_RECVDSTADDR:
+ case IP_RECVIF:
+ *mp = m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof(int);
+ switch (optname) {
+
+ case IP_TOS:
+ optval = inp->inp_ip_tos;
+ break;
+
+ case IP_TTL:
+ optval = inp->inp_ip_ttl;
+ break;
+
+#define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0)
+
+ case IP_RECVOPTS:
+ optval = OPTBIT(INP_RECVOPTS);
+ break;
+
+ case IP_RECVRETOPTS:
+ optval = OPTBIT(INP_RECVRETOPTS);
+ break;
+
+ case IP_RECVDSTADDR:
+ optval = OPTBIT(INP_RECVDSTADDR);
+ break;
+
+ case IP_RECVIF:
+ optval = OPTBIT(INP_RECVIF);
+ break;
+ }
+ *mtod(m, int *) = optval;
+ break;
+
+ case IP_MULTICAST_IF:
+ case IP_MULTICAST_VIF:
+ case IP_MULTICAST_TTL:
+ case IP_MULTICAST_LOOP:
+ case IP_ADD_MEMBERSHIP:
+ case IP_DROP_MEMBERSHIP:
+ error = ip_getmoptions(optname, inp->inp_moptions, mp);
+ break;
+
+ case IP_PORTRANGE:
+ *mp = m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof(int);
+
+ if (inp->inp_flags & INP_HIGHPORT)
+ optval = IP_PORTRANGE_HIGH;
+ else if (inp->inp_flags & INP_LOWPORT)
+ optval = IP_PORTRANGE_LOW;
+ else
+ optval = 0;
+
+ *mtod(m, int *) = optval;
+ break;
+
+ default:
+ error = ENOPROTOOPT;
+ break;
+ }
+ break;
+ }
+ return (error);
+}
+
+/*
+ * Set up IP options in pcb for insertion in output packets.
+ * Store in mbuf with pointer in pcbopt, adding pseudo-option
+ * with destination address if source routed.
+ */
+static int
+#ifdef notyet
+ip_pcbopts(optname, pcbopt, m)
+ int optname;
+#else
+ip_pcbopts(pcbopt, m)
+#endif
+ struct mbuf **pcbopt;
+ register struct mbuf *m;
+{
+ register int cnt, optlen;
+ register u_char *cp;
+ u_char opt;
+
+ /* turn off any old options */
+ if (*pcbopt)
+ (void)m_free(*pcbopt);
+ *pcbopt = 0;
+ if (m == (struct mbuf *)0 || m->m_len == 0) {
+ /*
+ * Only turning off any previous options.
+ */
+ if (m)
+ (void)m_free(m);
+ return (0);
+ }
+
+#ifndef vax
+ if (m->m_len % sizeof(long))
+ goto bad;
+#endif
+ /*
+ * IP first-hop destination address will be stored before
+ * actual options; move other options back
+ * and clear it when none present.
+ */
+ if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN])
+ goto bad;
+ cnt = m->m_len;
+ m->m_len += sizeof(struct in_addr);
+ cp = mtod(m, u_char *) + sizeof(struct in_addr);
+ ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt);
+ bzero(mtod(m, caddr_t), sizeof(struct in_addr));
+
+ for (; cnt > 0; cnt -= optlen, cp += optlen) {
+ opt = cp[IPOPT_OPTVAL];
+ if (opt == IPOPT_EOL)
+ break;
+ if (opt == IPOPT_NOP)
+ optlen = 1;
+ else {
+ optlen = cp[IPOPT_OLEN];
+ if (optlen <= IPOPT_OLEN || optlen > cnt)
+ goto bad;
+ }
+ switch (opt) {
+
+ default:
+ break;
+
+ case IPOPT_LSRR:
+ case IPOPT_SSRR:
+ /*
+ * user process specifies route as:
+ * ->A->B->C->D
+ * D must be our final destination (but we can't
+ * check that since we may not have connected yet).
+ * A is first hop destination, which doesn't appear in
+ * actual IP option, but is stored before the options.
+ */
+ if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr))
+ goto bad;
+ m->m_len -= sizeof(struct in_addr);
+ cnt -= sizeof(struct in_addr);
+ optlen -= sizeof(struct in_addr);
+ cp[IPOPT_OLEN] = optlen;
+ /*
+ * Move first hop before start of options.
+ */
+ bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t),
+ sizeof(struct in_addr));
+ /*
+ * Then copy rest of options back
+ * to close up the deleted entry.
+ */
+ ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] +
+ sizeof(struct in_addr)),
+ (caddr_t)&cp[IPOPT_OFFSET+1],
+ (unsigned)cnt + sizeof(struct in_addr));
+ break;
+ }
+ }
+ if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr))
+ goto bad;
+ *pcbopt = m;
+ return (0);
+
+bad:
+ (void)m_free(m);
+ return (EINVAL);
+}
+
+/*
+ * Set the IP multicast options in response to user setsockopt().
+ */
+static int
+ip_setmoptions(optname, imop, m)
+ int optname;
+ struct ip_moptions **imop;
+ struct mbuf *m;
+{
+ register int error = 0;
+ u_char loop;
+ register int i;
+ struct in_addr addr;
+ register struct ip_mreq *mreq;
+ register struct ifnet *ifp;
+ register struct ip_moptions *imo = *imop;
+ struct route ro;
+ register struct sockaddr_in *dst;
+ int s;
+
+ if (imo == NULL) {
+ /*
+ * No multicast option buffer attached to the pcb;
+ * allocate one and initialize to default values.
+ */
+ imo = (struct ip_moptions*)malloc(sizeof(*imo), M_IPMOPTS,
+ M_WAITOK);
+
+ if (imo == NULL)
+ return (ENOBUFS);
+ *imop = imo;
+ imo->imo_multicast_ifp = NULL;
+ imo->imo_multicast_vif = -1;
+ imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
+ imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
+ imo->imo_num_memberships = 0;
+ }
+
+ switch (optname) {
+ /* store an index number for the vif you wanna use in the send */
+ case IP_MULTICAST_VIF:
+ if (!legal_vif_num) {
+ error = EOPNOTSUPP;
+ break;
+ }
+ if (m == NULL || m->m_len != sizeof(int)) {
+ error = EINVAL;
+ break;
+ }
+ i = *(mtod(m, int *));
+ if (!legal_vif_num(i) && (i != -1)) {
+ error = EINVAL;
+ break;
+ }
+ imo->imo_multicast_vif = i;
+ break;
+
+ case IP_MULTICAST_IF:
+ /*
+ * Select the interface for outgoing multicast packets.
+ */
+ if (m == NULL || m->m_len != sizeof(struct in_addr)) {
+ error = EINVAL;
+ break;
+ }
+ addr = *(mtod(m, struct in_addr *));
+ /*
+ * INADDR_ANY is used to remove a previous selection.
+ * When no interface is selected, a default one is
+ * chosen every time a multicast packet is sent.
+ */
+ if (addr.s_addr == INADDR_ANY) {
+ imo->imo_multicast_ifp = NULL;
+ break;
+ }
+ /*
+ * The selected interface is identified by its local
+ * IP address. Find the interface and confirm that
+ * it supports multicasting.
+ */
+ s = splimp();
+ INADDR_TO_IFP(addr, ifp);
+ if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
+ splx(s);
+ error = EADDRNOTAVAIL;
+ break;
+ }
+ imo->imo_multicast_ifp = ifp;
+ splx(s);
+ break;
+
+ case IP_MULTICAST_TTL:
+ /*
+ * Set the IP time-to-live for outgoing multicast packets.
+ */
+ if (m == NULL || m->m_len != 1) {
+ error = EINVAL;
+ break;
+ }
+ imo->imo_multicast_ttl = *(mtod(m, u_char *));
+ break;
+
+ case IP_MULTICAST_LOOP:
+ /*
+ * Set the loopback flag for outgoing multicast packets.
+ * Must be zero or one.
+ */
+ if (m == NULL || m->m_len != 1 ||
+ (loop = *(mtod(m, u_char *))) > 1) {
+ error = EINVAL;
+ break;
+ }
+ imo->imo_multicast_loop = loop;
+ break;
+
+ case IP_ADD_MEMBERSHIP:
+ /*
+ * Add a multicast group membership.
+ * Group must be a valid IP multicast address.
+ */
+ if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {
+ error = EINVAL;
+ break;
+ }
+ mreq = mtod(m, struct ip_mreq *);
+ if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) {
+ error = EINVAL;
+ break;
+ }
+ s = splimp();
+ /*
+ * If no interface address was provided, use the interface of
+ * the route to the given multicast address.
+ */
+ if (mreq->imr_interface.s_addr == INADDR_ANY) {
+ bzero((caddr_t)&ro, sizeof(ro));
+ dst = (struct sockaddr_in *)&ro.ro_dst;
+ dst->sin_len = sizeof(*dst);
+ dst->sin_family = AF_INET;
+ dst->sin_addr = mreq->imr_multiaddr;
+ rtalloc(&ro);
+ if (ro.ro_rt == NULL) {
+ error = EADDRNOTAVAIL;
+ splx(s);
+ break;
+ }
+ ifp = ro.ro_rt->rt_ifp;
+ rtfree(ro.ro_rt);
+ }
+ else {
+ INADDR_TO_IFP(mreq->imr_interface, ifp);
+ }
+
+ /*
+ * See if we found an interface, and confirm that it
+ * supports multicast.
+ */
+ if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
+ error = EADDRNOTAVAIL;
+ splx(s);
+ break;
+ }
+ /*
+ * See if the membership already exists or if all the
+ * membership slots are full.
+ */
+ for (i = 0; i < imo->imo_num_memberships; ++i) {
+ if (imo->imo_membership[i]->inm_ifp == ifp &&
+ imo->imo_membership[i]->inm_addr.s_addr
+ == mreq->imr_multiaddr.s_addr)
+ break;
+ }
+ if (i < imo->imo_num_memberships) {
+ error = EADDRINUSE;
+ splx(s);
+ break;
+ }
+ if (i == IP_MAX_MEMBERSHIPS) {
+ error = ETOOMANYREFS;
+ splx(s);
+ break;
+ }
+ /*
+ * Everything looks good; add a new record to the multicast
+ * address list for the given interface.
+ */
+ if ((imo->imo_membership[i] =
+ in_addmulti(&mreq->imr_multiaddr, ifp)) == NULL) {
+ error = ENOBUFS;
+ splx(s);
+ break;
+ }
+ ++imo->imo_num_memberships;
+ splx(s);
+ break;
+
+ case IP_DROP_MEMBERSHIP:
+ /*
+ * Drop a multicast group membership.
+ * Group must be a valid IP multicast address.
+ */
+ if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {
+ error = EINVAL;
+ break;
+ }
+ mreq = mtod(m, struct ip_mreq *);
+ if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) {
+ error = EINVAL;
+ break;
+ }
+
+ s = splimp();
+ /*
+ * If an interface address was specified, get a pointer
+ * to its ifnet structure.
+ */
+ if (mreq->imr_interface.s_addr == INADDR_ANY)
+ ifp = NULL;
+ else {
+ INADDR_TO_IFP(mreq->imr_interface, ifp);
+ if (ifp == NULL) {
+ error = EADDRNOTAVAIL;
+ splx(s);
+ break;
+ }
+ }
+ /*
+ * Find the membership in the membership array.
+ */
+ for (i = 0; i < imo->imo_num_memberships; ++i) {
+ if ((ifp == NULL ||
+ imo->imo_membership[i]->inm_ifp == ifp) &&
+ imo->imo_membership[i]->inm_addr.s_addr ==
+ mreq->imr_multiaddr.s_addr)
+ break;
+ }
+ if (i == imo->imo_num_memberships) {
+ error = EADDRNOTAVAIL;
+ splx(s);
+ break;
+ }
+ /*
+ * Give up the multicast address record to which the
+ * membership points.
+ */
+ in_delmulti(imo->imo_membership[i]);
+ /*
+ * Remove the gap in the membership array.
+ */
+ for (++i; i < imo->imo_num_memberships; ++i)
+ imo->imo_membership[i-1] = imo->imo_membership[i];
+ --imo->imo_num_memberships;
+ splx(s);
+ break;
+
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+
+ /*
+ * If all options have default values, no need to keep the mbuf.
+ */
+ if (imo->imo_multicast_ifp == NULL &&
+ imo->imo_multicast_vif == -1 &&
+ imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL &&
+ imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP &&
+ imo->imo_num_memberships == 0) {
+ free(*imop, M_IPMOPTS);
+ *imop = NULL;
+ }
+
+ return (error);
+}
+
+/*
+ * Return the IP multicast options in response to user getsockopt().
+ */
+static int
+ip_getmoptions(optname, imo, mp)
+ int optname;
+ register struct ip_moptions *imo;
+ register struct mbuf **mp;
+{
+ u_char *ttl;
+ u_char *loop;
+ struct in_addr *addr;
+ struct in_ifaddr *ia;
+
+ *mp = m_get(M_WAIT, MT_SOOPTS);
+
+ switch (optname) {
+
+ case IP_MULTICAST_VIF:
+ if (imo != NULL)
+ *(mtod(*mp, int *)) = imo->imo_multicast_vif;
+ else
+ *(mtod(*mp, int *)) = -1;
+ (*mp)->m_len = sizeof(int);
+ return(0);
+
+ case IP_MULTICAST_IF:
+ addr = mtod(*mp, struct in_addr *);
+ (*mp)->m_len = sizeof(struct in_addr);
+ if (imo == NULL || imo->imo_multicast_ifp == NULL)
+ addr->s_addr = INADDR_ANY;
+ else {
+ IFP_TO_IA(imo->imo_multicast_ifp, ia);
+ addr->s_addr = (ia == NULL) ? INADDR_ANY
+ : IA_SIN(ia)->sin_addr.s_addr;
+ }
+ return (0);
+
+ case IP_MULTICAST_TTL:
+ ttl = mtod(*mp, u_char *);
+ (*mp)->m_len = 1;
+ *ttl = (imo == NULL) ? IP_DEFAULT_MULTICAST_TTL
+ : imo->imo_multicast_ttl;
+ return (0);
+
+ case IP_MULTICAST_LOOP:
+ loop = mtod(*mp, u_char *);
+ (*mp)->m_len = 1;
+ *loop = (imo == NULL) ? IP_DEFAULT_MULTICAST_LOOP
+ : imo->imo_multicast_loop;
+ return (0);
+
+ default:
+ return (EOPNOTSUPP);
+ }
+}
+
+/*
+ * Discard the IP multicast options.
+ */
+void
+ip_freemoptions(imo)
+ register struct ip_moptions *imo;
+{
+ register int i;
+
+ if (imo != NULL) {
+ for (i = 0; i < imo->imo_num_memberships; ++i)
+ in_delmulti(imo->imo_membership[i]);
+ free(imo, M_IPMOPTS);
+ }
+}
+
+/*
+ * Routine called from ip_output() to loop back a copy of an IP multicast
+ * packet to the input queue of a specified interface. Note that this
+ * calls the output routine of the loopback "driver", but with an interface
+ * pointer that might NOT be a loopback interface -- evil, but easier than
+ * replicating that code here.
+ */
+static void
+ip_mloopback(ifp, m, dst, hlen)
+ struct ifnet *ifp;
+ register struct mbuf *m;
+ register struct sockaddr_in *dst;
+ int hlen;
+{
+ register struct ip *ip;
+ struct mbuf *copym;
+
+ copym = m_copy(m, 0, M_COPYALL);
+ if (copym != NULL && (copym->m_flags & M_EXT || copym->m_len < hlen))
+ copym = m_pullup(copym, hlen);
+ if (copym != NULL) {
+ /*
+ * We don't bother to fragment if the IP length is greater
+ * than the interface's MTU. Can this possibly matter?
+ */
+ ip = mtod(copym, struct ip *);
+ ip->ip_len = htons((u_short)ip->ip_len);
+ ip->ip_off = htons((u_short)ip->ip_off);
+ ip->ip_sum = 0;
+ if (ip->ip_vhl == IP_VHL_BORING) {
+ ip->ip_sum = in_cksum_hdr(ip);
+ } else {
+ ip->ip_sum = in_cksum(copym, hlen);
+ }
+ /*
+ * NB:
+ * It's not clear whether there are any lingering
+ * reentrancy problems in other areas which might
+ * be exposed by using ip_input directly (in
+ * particular, everything which modifies the packet
+ * in-place). Yet another option is using the
+ * protosw directly to deliver the looped back
+ * packet. For the moment, we'll err on the side
+ * of safety by continuing to abuse looutput().
+ */
+#ifdef notdef
+ copym->m_pkthdr.rcvif = ifp;
+ ip_input(copym)
+#else
+ (void) looutput(ifp, copym, (struct sockaddr *)dst, NULL);
+#endif
+ }
+}
diff --git a/cpukit/libnetworking/netinet/ip_var.h b/cpukit/libnetworking/netinet/ip_var.h
new file mode 100644
index 0000000000..b5d4a95251
--- /dev/null
+++ b/cpukit/libnetworking/netinet/ip_var.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ * 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.
+ *
+ * @(#)ip_var.h 8.2 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/netinet/ip_var.h,v 1.94 2005/01/07 01:45:44 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NETINET_IP_VAR_H_
+#define _NETINET_IP_VAR_H_
+
+/*
+ * Overlay for ip header used by other protocols (tcp, udp).
+ */
+struct ipovly {
+ caddr_t ih_next;
+ caddr_t ih_prev; /* for protocol sequence q's */
+ u_char ih_x1; /* (unused) */
+ u_char ih_pr; /* protocol */
+ u_short ih_len; /* protocol length */
+ struct in_addr ih_src; /* source internet address */
+ struct in_addr ih_dst; /* destination internet address */
+};
+
+/*
+ * Ip reassembly queue structure. Each fragment
+ * being reassembled is attached to one of these structures.
+ * They are timed out after ipq_ttl drops to 0, and may also
+ * be reclaimed if memory becomes tight.
+ */
+struct ipq {
+ struct ipq *next,*prev; /* to other reass headers */
+ u_char ipq_ttl; /* time for reass q to live */
+ u_char ipq_p; /* protocol of this fragment */
+ u_short ipq_id; /* sequence id for reassembly */
+ struct ipasfrag *ipq_next,*ipq_prev;
+ /* to ip headers of fragments */
+ struct in_addr ipq_src,ipq_dst;
+#ifdef IPDIVERT
+ u_short ipq_divert; /* divert protocol port */
+#endif
+};
+
+/*
+ * Ip header, when holding a fragment.
+ *
+ * Note: ipf_next must be at same offset as ipq_next above
+ */
+struct ipasfrag {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_char ip_hl:4,
+ ip_v:4;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_char ip_v:4,
+ ip_hl:4;
+#endif
+ u_char ipf_mff; /* XXX overlays ip_tos: use low bit
+ * to avoid destroying tos;
+ * copied from (ip_off&IP_MF) */
+ u_short ip_len;
+ u_short ip_id;
+ u_short ip_off;
+ u_char ip_ttl;
+ u_char ip_p;
+ u_short ip_sum;
+ struct ipasfrag *ipf_next; /* next fragment */
+ struct ipasfrag *ipf_prev; /* previous fragment */
+};
+
+/*
+ * Structure stored in mbuf in inpcb.ip_options
+ * and passed to ip_output when ip options are in use.
+ * The actual length of the options (including ipopt_dst)
+ * is in m_len.
+ */
+#define MAX_IPOPTLEN 40
+
+struct ipoption {
+ struct in_addr ipopt_dst; /* first-hop dst if source routed */
+ char ipopt_list[MAX_IPOPTLEN]; /* options proper */
+};
+
+/*
+ * Structure attached to inpcb.ip_moptions and
+ * passed to ip_output when IP multicast options are in use.
+ */
+struct ip_moptions {
+ struct ifnet *imo_multicast_ifp; /* ifp for outgoing multicasts */
+ u_char imo_multicast_ttl; /* TTL for outgoing multicasts */
+ u_char imo_multicast_loop; /* 1 => hear sends if a member */
+ u_short imo_num_memberships; /* no. memberships this socket */
+ struct in_multi *imo_membership[IP_MAX_MEMBERSHIPS];
+ u_long imo_multicast_vif; /* vif num outgoing multicasts */
+};
+
+struct ipstat {
+ u_long ips_total; /* total packets received */
+ u_long ips_badsum; /* checksum bad */
+ u_long ips_tooshort; /* packet too short */
+ u_long ips_toosmall; /* not enough data */
+ u_long ips_badhlen; /* ip header length < data size */
+ u_long ips_badlen; /* ip length < ip header length */
+ u_long ips_fragments; /* fragments received */
+ u_long ips_fragdropped; /* frags dropped (dups, out of space) */
+ u_long ips_fragtimeout; /* fragments timed out */
+ u_long ips_forward; /* packets forwarded */
+ u_long ips_cantforward; /* packets rcvd for unreachable dest */
+ u_long ips_redirectsent; /* packets forwarded on same net */
+ u_long ips_noproto; /* unknown or unsupported protocol */
+ u_long ips_delivered; /* datagrams delivered to upper level*/
+ u_long ips_localout; /* total ip packets generated here */
+ u_long ips_odropped; /* lost packets due to nobufs, etc. */
+ u_long ips_reassembled; /* total packets reassembled ok */
+ u_long ips_fragmented; /* datagrams successfully fragmented */
+ u_long ips_ofragments; /* output fragments created */
+ u_long ips_cantfrag; /* don't fragment flag was set, etc. */
+ u_long ips_badoptions; /* error in option processing */
+ u_long ips_noroute; /* packets discarded due to no route */
+ u_long ips_badvers; /* ip version != 4 */
+ u_long ips_rawout; /* total raw ip packets generated */
+ u_long ips_toolong; /* ip length > max ip packet size */
+};
+
+#ifdef _KERNEL
+/* flags passed to ip_output as last parameter */
+#define IP_FORWARDING 0x1 /* most of ip header exists */
+#define IP_RAWOUTPUT 0x2 /* raw ip header exists */
+#define IP_SENDONES 0x4 /* send all-ones broadcast */
+#define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */
+#define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */
+
+struct ip;
+struct inpcb;
+struct route;
+struct sockopt;
+struct mbuf;
+
+extern struct ipstat ipstat;
+extern u_short ip_id; /* ip packet ctr, for ids */
+extern int ip_defttl; /* default IP ttl */
+extern u_char ip_protox[];
+extern struct socket *ip_rsvpd; /* reservation protocol daemon */
+extern struct socket *ip_mrouter; /* multicast routing daemon */
+extern int (*legal_vif_num)(int);
+extern u_long (*ip_mcast_src)(int);
+extern int rsvp_on;
+
+int ip_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
+void ip_drain(void);
+void ip_freemoptions(struct ip_moptions *);
+void ip_init(void);
+extern int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
+ struct ip_moptions *);
+int ip_output __P((struct mbuf *,
+ struct mbuf *, struct route *, int, struct ip_moptions *));
+void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
+ struct mbuf *);
+void ip_slowtimo(void);
+struct mbuf *
+ ip_srcroute __P((void));
+void ip_stripoptions(struct mbuf *, struct mbuf *);
+int rip_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
+void rip_init(void);
+void rip_input(struct mbuf *, int);
+int rip_output(struct mbuf *, struct socket *, u_long);
+int rip_usrreq __P((struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *));
+void ipip_input(struct mbuf *, int);
+void rsvp_input(struct mbuf *, int);
+int ip_rsvp_init(struct socket *);
+int ip_rsvp_done(void);
+int ip_rsvp_vif_init __P((struct socket *, struct mbuf *));
+int ip_rsvp_vif_done __P((struct socket *, struct mbuf *));
+void ip_rsvp_force_done __P((struct socket *));
+
+#ifdef IPDIVERT
+void div_init __P((void));
+void div_input __P((struct mbuf *, int));
+int div_usrreq __P((struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *));
+extern u_short ip_divert_port;
+extern u_short ip_divert_ignore;
+#endif /* IPDIVERT */
+
+#endif /* _KERNEL */
+
+#endif /* !_NETINET_IP_VAR_H_ */
diff --git a/cpukit/libnetworking/netinet/raw_ip.c b/cpukit/libnetworking/netinet/raw_ip.c
new file mode 100644
index 0000000000..48ddf1d952
--- /dev/null
+++ b/cpukit/libnetworking/netinet/raw_ip.c
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 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.
+ * 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.
+ *
+ * @(#)raw_ip.c 8.7 (Berkeley) 5/15/95
+ * $FreeBSD: src/sys/netinet/raw_ip.c,v 1.147 2005/01/07 01:45:45 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#include "opt_inet6.h"
+#include "opt_ipsec.h"
+#include "opt_mac.h"
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+#include <sys/systm.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#define _IP_VHL
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_mroute.h>
+
+#include <netinet/ip_fw.h>
+
+#if !defined(COMPAT_IPFW) || COMPAT_IPFW == 1
+#undef COMPAT_IPFW
+#define COMPAT_IPFW 1
+#else
+#undef COMPAT_IPFW
+#endif
+
+static struct inpcbhead ripcb;
+static struct inpcbinfo ripcbinfo;
+
+/*
+ * Nominal space allocated to a raw ip socket.
+ */
+#define RIPSNDQ 8192
+#define RIPRCVQ 8192
+
+/*
+ * Raw interface to IP protocol.
+ */
+
+/*
+ * Initialize raw connection block q.
+ */
+void
+rip_init()
+{
+ LIST_INIT(&ripcb);
+ ripcbinfo.listhead = &ripcb;
+ /*
+ * XXX We don't use the hash list for raw IP, but it's easier
+ * to allocate a one entry hash list than it is to check all
+ * over the place for hashbase == NULL.
+ */
+ ripcbinfo.hashbase = hashinit(1, M_PCB, &ripcbinfo.hashmask);
+}
+
+static struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };
+/*
+ * Setup generic address and protocol structures
+ * for raw_input routine, then pass them along with
+ * mbuf chain.
+ */
+void
+rip_input(struct mbuf *m, int iphlen)
+{
+ struct ip *ip = mtod(m, struct ip *);
+ register struct inpcb *inp;
+ struct inpcb *last = 0;
+ struct mbuf *opts = 0;
+
+ ripsrc.sin_addr = ip->ip_src;
+ for (inp = ripcb.lh_first; inp != NULL; inp = inp->inp_list.le_next) {
+ if (inp->inp_ip_p && inp->inp_ip_p != ip->ip_p)
+ continue;
+ if (inp->inp_laddr.s_addr &&
+ inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
+ continue;
+ if (inp->inp_faddr.s_addr &&
+ inp->inp_faddr.s_addr != ip->ip_src.s_addr)
+ continue;
+ if (last) {
+ struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
+ if (n) {
+ if (last->inp_flags & INP_CONTROLOPTS ||
+ last->inp_socket->so_options & SO_TIMESTAMP)
+ ip_savecontrol(last, &opts, ip, n);
+ if (sbappendaddr(&last->inp_socket->so_rcv,
+ (struct sockaddr *)&ripsrc, n,
+ opts) == 0) {
+ /* should notify about lost packet */
+ m_freem(n);
+ if (opts)
+ m_freem(opts);
+ } else
+ sorwakeup(last->inp_socket);
+ opts = 0;
+ }
+ }
+ last = inp;
+ }
+ if (last) {
+ if (last->inp_flags & INP_CONTROLOPTS ||
+ last->inp_socket->so_options & SO_TIMESTAMP)
+ ip_savecontrol(last, &opts, ip, m);
+ if (sbappendaddr(&last->inp_socket->so_rcv,
+ (struct sockaddr *)&ripsrc, m, opts) == 0) {
+ m_freem(m);
+ if (opts)
+ m_freem(opts);
+ } else
+ sorwakeup(last->inp_socket);
+ } else {
+ m_freem(m);
+ ipstat.ips_noproto++;
+ ipstat.ips_delivered--;
+ }
+}
+
+/*
+ * Generate IP header and pass packet to ip_output.
+ * Tack on options user may have setup with control call.
+ */
+int
+rip_output(struct mbuf *m, struct socket *so, u_long dst)
+{
+ struct ip *ip;
+ struct inpcb *inp = sotoinpcb(so);
+ int flags = ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0) |
+ IP_ALLOWBROADCAST;
+
+ /*
+ * If the user handed us a complete IP packet, use it.
+ * Otherwise, allocate an mbuf for a header and fill it in.
+ */
+ if ((inp->inp_flags & INP_HDRINCL) == 0) {
+ if (m->m_pkthdr.len + sizeof(struct ip) > IP_MAXPACKET) {
+ m_freem(m);
+ return(EMSGSIZE);
+ }
+ M_PREPEND(m, sizeof(struct ip), M_WAIT);
+ ip = mtod(m, struct ip *);
+ ip->ip_tos = 0;
+ ip->ip_off = 0;
+ ip->ip_p = inp->inp_ip_p;
+ ip->ip_len = m->m_pkthdr.len;
+ ip->ip_src = inp->inp_laddr;
+ ip->ip_dst.s_addr = dst;
+ ip->ip_ttl = MAXTTL;
+ } else {
+ if (m->m_pkthdr.len > IP_MAXPACKET) {
+ m_freem(m);
+ return(EMSGSIZE);
+ }
+ ip = mtod(m, struct ip *);
+ /* don't allow both user specified and setsockopt options,
+ and don't allow packet length sizes that will crash */
+ if (((IP_VHL_HL(ip->ip_vhl) != (sizeof (*ip) >> 2))
+ && inp->inp_options)
+ || (ip->ip_len > m->m_pkthdr.len)
+ || (ip->ip_len < (IP_VHL_HL(ip->ip_vhl) << 2))) {
+ m_freem(m);
+ return EINVAL;
+ }
+ if (ip->ip_id == 0)
+ ip->ip_id = htons(ip_id++);
+ /* XXX prevent ip_output from overwriting header fields */
+ flags |= IP_RAWOUTPUT;
+ ipstat.ips_rawout++;
+ }
+ return (ip_output(m, inp->inp_options, &inp->inp_route, flags,
+ inp->inp_moptions));
+}
+
+/*
+ * Raw IP socket option processing.
+ */
+int
+rip_ctloutput(op, so, level, optname, m)
+ int op;
+ struct socket *so;
+ int level, optname;
+ struct mbuf **m;
+{
+ struct inpcb *inp = sotoinpcb(so);
+ int error;
+
+ if (level != IPPROTO_IP) {
+ if (op == PRCO_SETOPT && *m)
+ (void)m_free(*m);
+ return (EINVAL);
+ }
+
+ switch (optname) {
+
+ case IP_HDRINCL:
+ error = 0;
+ if (op == PRCO_SETOPT) {
+ if (m == 0 || *m == 0 || (*m)->m_len < sizeof (int))
+ error = EINVAL;
+ else if (*mtod(*m, int *))
+ inp->inp_flags |= INP_HDRINCL;
+ else
+ inp->inp_flags &= ~INP_HDRINCL;
+ if (*m)
+ (void)m_free(*m);
+ } else {
+ *m = m_get(M_WAIT, MT_SOOPTS);
+ (*m)->m_len = sizeof (int);
+ *mtod(*m, int *) = inp->inp_flags & INP_HDRINCL;
+ }
+ return (error);
+
+#ifdef COMPAT_IPFW
+ case IP_FW_GET:
+ if (ip_fw_ctl_ptr == NULL || op == PRCO_SETOPT) {
+ if (*m) (void)m_free(*m);
+ return(EINVAL);
+ }
+ return (*ip_fw_ctl_ptr)(optname, m);
+
+ case IP_FW_ADD:
+ case IP_FW_DEL:
+ case IP_FW_FLUSH:
+ case IP_FW_ZERO:
+ if (ip_fw_ctl_ptr == NULL || op != PRCO_SETOPT) {
+ if (*m) (void)m_free(*m);
+ return(EINVAL);
+ }
+ return (*ip_fw_ctl_ptr)(optname, m);
+
+ case IP_NAT:
+ if (ip_nat_ctl_ptr == NULL) {
+ if (*m) (void)m_free(*m);
+ return(EINVAL);
+ }
+ return (*ip_nat_ctl_ptr)(op, m);
+
+#endif
+ case IP_RSVP_ON:
+ return ip_rsvp_init(so);
+ break;
+
+ case IP_RSVP_OFF:
+ return ip_rsvp_done();
+ break;
+
+ case IP_RSVP_VIF_ON:
+ return ip_rsvp_vif_init(so, *m);
+
+ case IP_RSVP_VIF_OFF:
+ return ip_rsvp_vif_done(so, *m);
+
+ case MRT_INIT:
+ case MRT_DONE:
+ case MRT_ADD_VIF:
+ case MRT_DEL_VIF:
+ case MRT_ADD_MFC:
+ case MRT_DEL_MFC:
+ case MRT_VERSION:
+ case MRT_ASSERT:
+ if (op == PRCO_SETOPT) {
+ error = ip_mrouter_set(optname, so, *m);
+ if (*m)
+ (void)m_free(*m);
+ } else if (op == PRCO_GETOPT) {
+ error = ip_mrouter_get(optname, so, m);
+ } else
+ error = EINVAL;
+ return (error);
+ }
+ return (ip_ctloutput(op, so, level, optname, m));
+}
+
+static u_long rip_sendspace = RIPSNDQ; /* XXX sysctl ? */
+static u_long rip_recvspace = RIPRCVQ; /* XXX sysctl ? */
+
+/*ARGSUSED*/
+int
+rip_usrreq(so, req, m, nam, control)
+ register struct socket *so;
+ int req;
+ struct mbuf *m, *nam, *control;
+{
+ register int error = 0;
+ register struct inpcb *inp = sotoinpcb(so);
+ int s;
+
+ if (req == PRU_CONTROL)
+ return (in_control(so, (u_long)m, (caddr_t)nam,
+ (struct ifnet *)control));
+
+ switch (req) {
+
+ case PRU_ATTACH:
+ if (inp)
+ panic("rip_attach");
+ if ((so->so_state & SS_PRIV) == 0) {
+ error = EACCES;
+ break;
+ }
+ s = splnet();
+ error = in_pcballoc(so, &ripcbinfo);
+ splx(s);
+ if (error)
+ break;
+ error = soreserve(so, rip_sendspace, rip_recvspace);
+ if (error)
+ break;
+ inp = (struct inpcb *)so->so_pcb;
+ inp->inp_ip_p = (int)nam;
+ break;
+
+ case PRU_DISCONNECT:
+ if ((so->so_state & SS_ISCONNECTED) == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ /* FALLTHROUGH */
+ case PRU_ABORT:
+ soisdisconnected(so);
+ /* FALLTHROUGH */
+ case PRU_DETACH:
+ if (inp == 0)
+ panic("rip_detach");
+ if (so == ip_mrouter)
+ ip_mrouter_done();
+ ip_rsvp_force_done(so);
+ if (so == ip_rsvpd)
+ ip_rsvp_done();
+ in_pcbdetach(inp);
+ break;
+
+ case PRU_BIND:
+ {
+ struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
+
+ if (nam->m_len != sizeof(*addr)) {
+ error = EINVAL;
+ break;
+ }
+ if ((ifnet == 0) ||
+ ((addr->sin_family != AF_INET) &&
+ (addr->sin_family != AF_IMPLINK)) ||
+ (addr->sin_addr.s_addr &&
+ ifa_ifwithaddr((struct sockaddr *)addr) == 0)) {
+ error = EADDRNOTAVAIL;
+ break;
+ }
+ inp->inp_laddr = addr->sin_addr;
+ break;
+ }
+ case PRU_CONNECT:
+ {
+ struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
+
+ if (nam->m_len != sizeof(*addr)) {
+ error = EINVAL;
+ break;
+ }
+ if (ifnet == 0) {
+ error = EADDRNOTAVAIL;
+ break;
+ }
+ if ((addr->sin_family != AF_INET) &&
+ (addr->sin_family != AF_IMPLINK)) {
+ error = EAFNOSUPPORT;
+ break;
+ }
+ inp->inp_faddr = addr->sin_addr;
+ soisconnected(so);
+ break;
+ }
+
+ case PRU_CONNECT2:
+ error = EOPNOTSUPP;
+ break;
+
+ /*
+ * Mark the connection as being incapable of further input.
+ */
+ case PRU_SHUTDOWN:
+ socantsendmore(so);
+ break;
+
+ /*
+ * Ship a packet out. The appropriate raw output
+ * routine handles any massaging necessary.
+ */
+ case PRU_SEND:
+ {
+ register u_long dst;
+
+ if (so->so_state & SS_ISCONNECTED) {
+ if (nam) {
+ error = EISCONN;
+ break;
+ }
+ dst = inp->inp_faddr.s_addr;
+ } else {
+ if (nam == NULL) {
+ error = ENOTCONN;
+ break;
+ }
+ dst = mtod(nam, struct sockaddr_in *)->sin_addr.s_addr;
+ }
+ error = rip_output(m, so, dst);
+ m = NULL;
+ break;
+ }
+
+ case PRU_SENSE:
+ /*
+ * stat: don't bother with a blocksize.
+ */
+ return (0);
+
+ /*
+ * Not supported.
+ */
+ case PRU_RCVOOB:
+ case PRU_RCVD:
+ case PRU_LISTEN:
+ case PRU_ACCEPT:
+ case PRU_SENDOOB:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_SOCKADDR:
+ in_setsockaddr(inp, nam);
+ break;
+
+ case PRU_PEERADDR:
+ in_setpeeraddr(inp, nam);
+ break;
+
+ default:
+ panic("rip_usrreq");
+ }
+ if (m != NULL)
+ m_freem(m);
+ return (error);
+}
diff --git a/cpukit/libnetworking/netinet/tcp.h b/cpukit/libnetworking/netinet/tcp.h
new file mode 100644
index 0000000000..a8c24f572b
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ * 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.
+ *
+ * @(#)tcp.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/tcp.h,v 1.30 2005/01/07 01:45:45 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NETINET_TCP_H_
+#define _NETINET_TCP_H_
+
+#include <sys/cdefs.h>
+
+#if __BSD_VISIBLE
+
+typedef u_int32_t tcp_seq;
+
+#define tcp6_seq tcp_seq /* for KAME src sync over BSD*'s */
+#define tcp6hdr tcphdr /* for KAME src sync over BSD*'s */
+
+typedef u_long tcp_cc; /* connection count per rfc1644 */
+
+/*
+ * TCP header.
+ * Per RFC 793, September, 1981.
+ */
+struct tcphdr {
+ u_short th_sport; /* source port */
+ u_short th_dport; /* destination port */
+ tcp_seq th_seq; /* sequence number */
+ tcp_seq th_ack; /* acknowledgement number */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int th_x2:4, /* (unused) */
+ th_off:4; /* data offset */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int th_off:4, /* data offset */
+ th_x2:4; /* (unused) */
+#endif
+ u_char th_flags;
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+#define TH_ECE 0x40
+#define TH_CWR 0x80
+#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
+
+ u_short th_win; /* window */
+ u_short th_sum; /* checksum */
+ u_short th_urp; /* urgent pointer */
+};
+
+#define TCPOPT_EOL 0
+#define TCPOPT_NOP 1
+#define TCPOPT_MAXSEG 2
+#define TCPOLEN_MAXSEG 4
+#define TCPOPT_WINDOW 3
+#define TCPOLEN_WINDOW 3
+#define TCPOPT_SACK_PERMITTED 4 /* Experimental */
+#define TCPOLEN_SACK_PERMITTED 2
+#define TCPOPT_SACK 5 /* Experimental */
+#define TCPOPT_TIMESTAMP 8
+#define TCPOLEN_TIMESTAMP 10
+#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
+#define TCPOPT_TSTAMP_HDR \
+ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
+
+#define TCPOPT_CC 11 /* CC options: RFC-1644 */
+#define TCPOPT_CCNEW 12
+#define TCPOPT_CCECHO 13
+#define TCPOLEN_CC 6
+#define TCPOLEN_CC_APPA (TCPOLEN_CC+2)
+#define TCPOPT_CC_HDR(ccopt) \
+ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|(ccopt)<<8|TCPOLEN_CC)
+
+/*
+ * Default maximum segment size for TCP.
+ * With an IP MTU of 576, this is 536,
+ * but 512 is probably more convenient.
+ * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
+ */
+#define TCP_MSS 512
+
+#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */
+#define TTCP_CLIENT_SND_WND 4096 /* dflt send window for T/TCP client */
+
+#define TCP_MAX_WINSHIFT 14 /* maximum window shift */
+
+#define TCP_MAXHLEN (0xf<<2) /* max length of header in bytes */
+#define TCP_MAXOLEN (TCP_MAXHLEN - sizeof(struct tcphdr))
+ /* max space left for options */
+#endif /* __BSD_VISIBLE */
+
+/*
+ * User-settable options (used with setsockopt).
+ */
+#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
+#if __BSD_VISIBLE
+#define TCP_MAXSEG 0x02 /* set maximum segment size */
+#define TCP_NOPUSH 0x04 /* don't push last block of write */
+#define TCP_NOOPT 0x08 /* don't use TCP options */
+#define TCP_MD5SIG 0x10 /* use MD5 digests (RFC2385) */
+#define TCP_INFO 0x20 /* retrieve tcp_info structure */
+#endif
+
+#endif /* !_NETINET_TCP_H_ */
diff --git a/cpukit/libnetworking/netinet/tcp_debug.c b/cpukit/libnetworking/netinet/tcp_debug.c
new file mode 100644
index 0000000000..2f88ae658e
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp_debug.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ *
+ * @(#)tcp_debug.c 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#include "opt_tcpdebug.h"
+
+#ifdef TCPDEBUG
+/* load symbolic names */
+#define PRUREQUESTS
+#define TCPSTATES
+#define TCPTIMERS
+#define TANAMES
+#endif
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+
+#include <net/route.h>
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#include <netinet/tcp_debug.h>
+
+#ifdef TCPDEBUG
+static int tcpconsdebug = 0; /* set to 1 to enable prints */
+#endif
+
+static struct tcp_debug tcp_debug[TCP_NDEBUG];
+static int tcp_debx;
+
+/*
+ * Tcp debug routines
+ */
+void
+tcp_trace(act, ostate, tp, ti, req)
+ short act, ostate;
+ struct tcpcb *tp;
+ struct tcpiphdr *ti;
+ int req;
+{
+#ifdef TCPDEBUG
+ tcp_seq seq, ack;
+ int len, flags;
+#endif
+ struct tcp_debug *td = &tcp_debug[tcp_debx++];
+
+ if (tcp_debx == TCP_NDEBUG)
+ tcp_debx = 0;
+ td->td_time = iptime();
+ td->td_act = act;
+ td->td_ostate = ostate;
+ td->td_tcb = (caddr_t)tp;
+ if (tp)
+ td->td_cb = *tp;
+ else
+ bzero((caddr_t)&td->td_cb, sizeof (*tp));
+ if (ti)
+ td->td_ti = *ti;
+ else
+ bzero((caddr_t)&td->td_ti, sizeof (*ti));
+ td->td_req = req;
+#ifdef TCPDEBUG
+ if (tcpconsdebug == 0)
+ return;
+ if (tp)
+ printf("%p %s:", tp, tcpstates[ostate]);
+ else
+ printf("???????? ");
+ printf("%s ", tanames[act]);
+ switch (act) {
+
+ case TA_INPUT:
+ case TA_OUTPUT:
+ case TA_DROP:
+ if (ti == 0)
+ break;
+ seq = ti->ti_seq;
+ ack = ti->ti_ack;
+ len = ti->ti_len;
+ if (act == TA_OUTPUT) {
+ seq = ntohl(seq);
+ ack = ntohl(ack);
+ len = ntohs((u_short)len);
+ }
+ if (act == TA_OUTPUT)
+ len -= sizeof (struct tcphdr);
+ if (len)
+ printf("[%x..%x)", seq, seq+len);
+ else
+ printf("%x", seq);
+ printf("@%x, urp=%x", ack, ti->ti_urp);
+ flags = ti->ti_flags;
+ if (flags) {
+ char *cp = "<";
+#define pf(f) { \
+ if (ti->ti_flags & TH_##f) { \
+ printf("%s%s", cp, #f); \
+ cp = ","; \
+ } \
+}
+ pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG);
+ printf(">");
+ }
+ break;
+
+ case TA_USER:
+ printf("%s", prurequests[req&0xff]);
+ if ((req & 0xff) == PRU_SLOWTIMO)
+ printf("<%s>", tcptimers[req>>8]);
+ break;
+ }
+ if (tp)
+ printf(" -> %s", tcpstates[tp->t_state]);
+ /* print out internal state of tp !?! */
+ printf("\n");
+ if (tp == 0)
+ return;
+ printf("\trcv_(nxt,wnd,up) (%x,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n",
+ tp->rcv_nxt, tp->rcv_wnd, tp->rcv_up, tp->snd_una, tp->snd_nxt,
+ tp->snd_max);
+ printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n",
+ tp->snd_wl1, tp->snd_wl2, tp->snd_wnd);
+#endif /* TCPDEBUG */
+}
diff --git a/cpukit/libnetworking/netinet/tcp_debug.h b/cpukit/libnetworking/netinet/tcp_debug.h
new file mode 100644
index 0000000000..4bff757e2a
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp_debug.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ *
+ * @(#)tcp_debug.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NETINET_TCP_DEBUG_H_
+#define _NETINET_TCP_DEBUG_H_
+
+struct tcp_debug {
+ n_time td_time;
+ short td_act;
+ short td_ostate;
+ caddr_t td_tcb;
+ struct tcpiphdr td_ti;
+ short td_req;
+ struct tcpcb td_cb;
+};
+
+#define TA_INPUT 0
+#define TA_OUTPUT 1
+#define TA_USER 2
+#define TA_RESPOND 3
+#define TA_DROP 4
+
+#ifdef TANAMES
+static char *tanames[] =
+ { "input", "output", "user", "respond", "drop" };
+#endif
+
+#define TCP_NDEBUG 100
+
+#ifndef _KERNEL
+/* XXX common variables for broken applications. */
+struct tcp_debug tcp_debug[TCP_NDEBUG];
+int tcp_debx;
+#endif
+
+#endif /* !_NETINET_TCP_DEBUG_H_ */
diff --git a/cpukit/libnetworking/netinet/tcp_fsm.h b/cpukit/libnetworking/netinet/tcp_fsm.h
new file mode 100644
index 0000000000..3f2c12f54f
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp_fsm.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ *
+ * @(#)tcp_fsm.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NETINET_TCP_FSM_H_
+#define _NETINET_TCP_FSM_H_
+
+/*
+ * TCP FSM state definitions.
+ * Per RFC793, September, 1981.
+ */
+
+#define TCP_NSTATES 11
+
+#define TCPS_CLOSED 0 /* closed */
+#define TCPS_LISTEN 1 /* listening for connection */
+#define TCPS_SYN_SENT 2 /* active, have sent syn */
+#define TCPS_SYN_RECEIVED 3 /* have send and received syn */
+/* states < TCPS_ESTABLISHED are those where connections not established */
+#define TCPS_ESTABLISHED 4 /* established */
+#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */
+/* states > TCPS_CLOSE_WAIT are those where user has closed */
+#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */
+#define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */
+#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */
+/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
+#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */
+#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */
+
+#define TCPS_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED)
+#define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED)
+#define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT)
+
+#ifdef TCPOUTFLAGS
+/*
+ * Flags used when sending segments in tcp_output.
+ * Basic flags (TH_RST,TH_ACK,TH_SYN,TH_FIN) are totally
+ * determined by state, with the proviso that TH_FIN is sent only
+ * if all data queued for output is included in the segment.
+ */
+static u_char tcp_outflags[TCP_NSTATES] = {
+ TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
+ TH_ACK, TH_ACK,
+ TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_ACK, TH_ACK,
+};
+#endif
+
+#ifdef KPROF
+int tcp_acounts[TCP_NSTATES][PRU_NREQ];
+#endif
+
+#ifdef TCPSTATES
+char *tcpstates[] = {
+ "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD",
+ "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING",
+ "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT",
+};
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/netinet/tcp_input.c b/cpukit/libnetworking/netinet/tcp_input.c
new file mode 100644
index 0000000000..6cde8daf5e
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp_input.c
@@ -0,0 +1,2165 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
+ * 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 acknowledgment:
+ * 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.
+ *
+ * @(#)tcp_input.c 8.12 (Berkeley) 5/24/95
+ * $Id$
+ */
+
+#include "opt_tcpdebug.h"
+
+#ifndef TUBA_INCLUDE
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+#include <sys/syslog.h>
+
+#include <machine/cpu.h> /* before tcp_seq.h, for tcp_random18() */
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#ifdef TCPDEBUG
+#include <netinet/tcp_debug.h>
+static struct tcpiphdr tcp_saveti;
+#endif
+
+static int tcprexmtthresh = 3;
+tcp_seq tcp_iss;
+tcp_cc tcp_ccgen;
+
+struct tcpstat tcpstat;
+SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats,
+ CTLFLAG_RD, &tcpstat , tcpstat, "");
+
+static int log_in_vain = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_RW,
+ &log_in_vain, 0, "");
+
+u_long tcp_now;
+struct inpcbhead tcb;
+struct inpcbinfo tcbinfo;
+
+static void tcp_dooptions __P((struct tcpcb *,
+ u_char *, int, struct tcpiphdr *, struct tcpopt *));
+static void tcp_pulloutofband __P((struct socket *,
+ struct tcpiphdr *, struct mbuf *));
+static int tcp_reass __P((struct tcpcb *, struct tcpiphdr *, struct mbuf *));
+static void tcp_xmit_timer __P((struct tcpcb *, int));
+
+#endif /* TUBA_INCLUDE */
+
+/*
+ * Insert segment ti into reassembly queue of tcp with
+ * control block tp. Return TH_FIN if reassembly now includes
+ * a segment with FIN. The macro form does the common case inline
+ * (segment is the next to be received on an established connection,
+ * and the queue is empty), avoiding linkage into and removal
+ * from the queue and repetition of various conversions.
+ * Set DELACK for segments received in order, but ack immediately
+ * when segments are out of order (so fast retransmit can work).
+ */
+#ifdef TCP_ACK_HACK
+#define TCP_REASS(tp, ti, m, so, flags) { \
+ if ((ti)->ti_seq == (tp)->rcv_nxt && \
+ (tp)->seg_next == (struct tcpiphdr *)(tp) && \
+ (tp)->t_state == TCPS_ESTABLISHED) { \
+ if (ti->ti_flags & TH_PUSH) \
+ tp->t_flags |= TF_ACKNOW; \
+ else \
+ tp->t_flags |= TF_DELACK; \
+ (tp)->rcv_nxt += (ti)->ti_len; \
+ flags = (ti)->ti_flags & TH_FIN; \
+ tcpstat.tcps_rcvpack++;\
+ tcpstat.tcps_rcvbyte += (ti)->ti_len;\
+ sbappend(&(so)->so_rcv, (m)); \
+ sorwakeup(so); \
+ } else { \
+ (flags) = tcp_reass((tp), (ti), (m)); \
+ tp->t_flags |= TF_ACKNOW; \
+ } \
+}
+#else
+#define TCP_REASS(tp, ti, m, so, flags) { \
+ if ((ti)->ti_seq == (tp)->rcv_nxt && \
+ (tp)->seg_next == (struct tcpiphdr *)(tp) && \
+ (tp)->t_state == TCPS_ESTABLISHED) { \
+ tp->t_flags |= TF_DELACK; \
+ (tp)->rcv_nxt += (ti)->ti_len; \
+ flags = (ti)->ti_flags & TH_FIN; \
+ tcpstat.tcps_rcvpack++;\
+ tcpstat.tcps_rcvbyte += (ti)->ti_len;\
+ sbappend(&(so)->so_rcv, (m)); \
+ sorwakeup(so); \
+ } else { \
+ (flags) = tcp_reass((tp), (ti), (m)); \
+ tp->t_flags |= TF_ACKNOW; \
+ } \
+}
+#endif
+#ifndef TUBA_INCLUDE
+
+static int
+tcp_reass(tp, ti, m)
+ register struct tcpcb *tp;
+ register struct tcpiphdr *ti;
+ struct mbuf *m;
+{
+ register struct tcpiphdr *q;
+ struct socket *so = tp->t_inpcb->inp_socket;
+ int flags;
+ /*
+ * Call with ti==0 after become established to
+ * force pre-ESTABLISHED data up to user socket.
+ */
+ if (ti == 0)
+ goto present;
+
+ /*
+ * Find a segment which begins after this one does.
+ */
+ for (q = tp->seg_next; q != (struct tcpiphdr *)tp;
+ q = (struct tcpiphdr *)q->ti_next)
+ if (SEQ_GT(q->ti_seq, ti->ti_seq))
+ break;
+
+ /*
+ * If there is a preceding segment, it may provide some of
+ * our data already. If so, drop the data from the incoming
+ * segment. If it provides all of our data, drop us.
+ */
+ if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) {
+ register int i;
+ q = (struct tcpiphdr *)q->ti_prev;
+ /* conversion to int (in i) handles seq wraparound */
+ i = q->ti_seq + q->ti_len - ti->ti_seq;
+ if (i > 0) {
+ if (i >= ti->ti_len) {
+ tcpstat.tcps_rcvduppack++;
+ tcpstat.tcps_rcvdupbyte += ti->ti_len;
+ m_freem(m);
+ /*
+ * Try to present any queued data
+ * at the left window edge to the user.
+ * This is needed after the 3-WHS
+ * completes.
+ */
+ goto present; /* ??? */
+ }
+ m_adj(m, i);
+ ti->ti_len -= i;
+ ti->ti_seq += i;
+ }
+ q = (struct tcpiphdr *)(q->ti_next);
+ }
+ tcpstat.tcps_rcvoopack++;
+ tcpstat.tcps_rcvoobyte += ti->ti_len;
+#if (defined(__GNUC__) && (defined(__arm__) || defined(__mips__)))
+ STR32_UNALGN(ti,m);
+#else
+ REASS_MBUF(ti) = m; /* XXX */
+#endif
+ /*
+ * While we overlap succeeding segments trim them or,
+ * if they are completely covered, dequeue them.
+ */
+ while (q != (struct tcpiphdr *)tp) {
+ register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
+ if (i <= 0)
+ break;
+ if (i < q->ti_len) {
+ q->ti_seq += i;
+ q->ti_len -= i;
+#if (defined(__GNUC__) && (defined(__arm__) || defined(__mips__)))
+ LD32_UNALGN(q,m);
+ m_adj(m, i);
+#else
+ m_adj(REASS_MBUF(q), i);
+#endif
+ break;
+ }
+ q = (struct tcpiphdr *)q->ti_next;
+#if (defined(__GNUC__) && (defined(__arm__) || defined(__mips__)))
+ LD32_UNALGN((struct tcpiphdr *)q->ti_prev,m);
+#else
+ m = REASS_MBUF((struct tcpiphdr *)q->ti_prev);
+#endif
+ remque(q->ti_prev);
+ m_freem(m);
+ }
+
+ /*
+ * Stick new segment in its place.
+ */
+ insque(ti, q->ti_prev);
+
+present:
+ /*
+ * Present data to user, advancing rcv_nxt through
+ * completed sequence space.
+ */
+ if (!TCPS_HAVEESTABLISHED(tp->t_state))
+ return (0);
+ ti = tp->seg_next;
+ if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt)
+ return (0);
+ do {
+ tp->rcv_nxt += ti->ti_len;
+ flags = ti->ti_flags & TH_FIN;
+ remque(ti);
+#if (defined(__GNUC__) && (defined(__arm__) || defined(__mips__)))
+ LD32_UNALGN(ti,m);
+#else
+ m = REASS_MBUF(ti);
+#endif
+ ti = (struct tcpiphdr *)ti->ti_next;
+ if (so->so_state & SS_CANTRCVMORE)
+ m_freem(m);
+ else
+ sbappend(&so->so_rcv, m);
+ } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt);
+ sorwakeup(so);
+ return (flags);
+}
+
+/*
+ * TCP input routine, follows pages 65-76 of the
+ * protocol specification dated September, 1981 very closely.
+ */
+void
+tcp_input(m, iphlen)
+ register struct mbuf *m;
+ int iphlen;
+{
+ register struct tcpiphdr *ti;
+ register struct inpcb *inp;
+ u_char *optp = NULL;
+ int optlen = 0;
+ int len, tlen, off;
+ register struct tcpcb *tp = 0;
+ register int tiflags;
+ struct socket *so = 0;
+ int todrop, acked, ourfinisacked, needoutput = 0;
+ struct in_addr laddr;
+ int dropsocket = 0;
+ int iss = 0;
+ u_long tiwin;
+ struct tcpopt to; /* options in this segment */
+ struct rmxp_tao *taop; /* pointer to our TAO cache entry */
+ struct rmxp_tao tao_noncached; /* in case there's no cached entry */
+#ifdef TCPDEBUG
+ short ostate = 0;
+#endif
+
+ bzero((char *)&to, sizeof(to));
+
+ tcpstat.tcps_rcvtotal++;
+ /*
+ * Get IP and TCP header together in first mbuf.
+ * Note: IP leaves IP header in first mbuf.
+ */
+ ti = mtod(m, struct tcpiphdr *);
+ if (iphlen > sizeof (struct ip))
+ ip_stripoptions(m, (struct mbuf *)0);
+ if (m->m_len < sizeof (struct tcpiphdr)) {
+ if ((m = m_pullup(m, sizeof (struct tcpiphdr))) == 0) {
+ tcpstat.tcps_rcvshort++;
+ return;
+ }
+ ti = mtod(m, struct tcpiphdr *);
+ }
+
+ /*
+ * Checksum extended TCP header and data.
+ */
+ tlen = ((struct ip *)ti)->ip_len;
+ len = sizeof (struct ip) + tlen;
+ ti->ti_next = ti->ti_prev = 0;
+ ti->ti_x1 = 0;
+ ti->ti_len = (u_short)tlen;
+ HTONS(ti->ti_len);
+ ti->ti_sum = in_cksum(m, len);
+ if (ti->ti_sum) {
+ tcpstat.tcps_rcvbadsum++;
+ goto drop;
+ }
+#endif /* TUBA_INCLUDE */
+
+ /*
+ * Check that TCP offset makes sense,
+ * pull out TCP options and adjust length. XXX
+ */
+ off = ti->ti_off << 2;
+ if (off < sizeof (struct tcphdr) || off > tlen) {
+ tcpstat.tcps_rcvbadoff++;
+ goto drop;
+ }
+ tlen -= off;
+ ti->ti_len = tlen;
+ if (off > sizeof (struct tcphdr)) {
+ if (m->m_len < sizeof(struct ip) + off) {
+ if ((m = m_pullup(m, sizeof (struct ip) + off)) == 0) {
+ tcpstat.tcps_rcvshort++;
+ return;
+ }
+ ti = mtod(m, struct tcpiphdr *);
+ }
+ optlen = off - sizeof (struct tcphdr);
+ optp = mtod(m, u_char *) + sizeof (struct tcpiphdr);
+ }
+ tiflags = ti->ti_flags;
+
+ /*
+ * Convert TCP protocol specific fields to host format.
+ */
+ NTOHL(ti->ti_seq);
+ NTOHL(ti->ti_ack);
+ NTOHS(ti->ti_win);
+ NTOHS(ti->ti_urp);
+
+ /*
+ * Drop TCP, IP headers and TCP options.
+ */
+ m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
+ m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
+
+ /*
+ * Locate pcb for segment.
+ */
+findpcb:
+ inp = in_pcblookuphash(&tcbinfo, ti->ti_src, ti->ti_sport,
+ ti->ti_dst, ti->ti_dport, 1);
+
+ /*
+ * If the state is CLOSED (i.e., TCB does not exist) then
+ * all data in the incoming segment is discarded.
+ * If the TCB exists but is in CLOSED state, it is embryonic,
+ * but should either do a listen or a connect soon.
+ */
+ if (inp == NULL) {
+ if (log_in_vain && tiflags & TH_SYN) {
+ char buf[4*sizeof "123"];
+
+ strcpy(buf, inet_ntoa(ti->ti_dst));
+ log(LOG_INFO, "Connection attempt to TCP %s:%d"
+ " from %s:%d\n",
+ buf, ntohs(ti->ti_dport),
+ inet_ntoa(ti->ti_src), ntohs(ti->ti_sport));
+ }
+ goto dropwithreset;
+ }
+ tp = intotcpcb(inp);
+ if (tp == 0)
+ goto dropwithreset;
+ if (tp->t_state == TCPS_CLOSED)
+ goto drop;
+
+ /* Unscale the window into a 32-bit value. */
+ if ((tiflags & TH_SYN) == 0)
+ tiwin = ti->ti_win << tp->snd_scale;
+ else
+ tiwin = ti->ti_win;
+
+ so = inp->inp_socket;
+ if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) {
+#ifdef TCPDEBUG
+ if (so->so_options & SO_DEBUG) {
+ ostate = tp->t_state;
+ tcp_saveti = *ti;
+ }
+#endif
+ if (so->so_options & SO_ACCEPTCONN) {
+ register struct tcpcb *tp0 = tp;
+ struct socket *so2;
+ if ((tiflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) {
+ /*
+ * Note: dropwithreset makes sure we don't
+ * send a RST in response to a RST.
+ */
+ if (tiflags & TH_ACK) {
+ tcpstat.tcps_badsyn++;
+ goto dropwithreset;
+ }
+ goto drop;
+ }
+ so2 = sonewconn(so, 0);
+ if (so2 == 0) {
+ tcpstat.tcps_listendrop++;
+ so2 = sodropablereq(so);
+ if (so2) {
+ tcp_drop(sototcpcb(so2), ETIMEDOUT);
+ so2 = sonewconn(so, 0);
+ }
+ if (!so2)
+ goto drop;
+ }
+ so = so2;
+ /*
+ * This is ugly, but ....
+ *
+ * Mark socket as temporary until we're
+ * committed to keeping it. The code at
+ * ``drop'' and ``dropwithreset'' check the
+ * flag dropsocket to see if the temporary
+ * socket created here should be discarded.
+ * We mark the socket as discardable until
+ * we're committed to it below in TCPS_LISTEN.
+ */
+ dropsocket++;
+ inp = (struct inpcb *)so->so_pcb;
+ inp->inp_laddr = ti->ti_dst;
+ inp->inp_lport = ti->ti_dport;
+ in_pcbrehash(inp);
+#if BSD>=43
+ inp->inp_options = ip_srcroute();
+#endif
+ tp = intotcpcb(inp);
+ tp->t_state = TCPS_LISTEN;
+ tp->t_flags |= tp0->t_flags & (TF_NOPUSH|TF_NOOPT);
+
+ /* Compute proper scaling value from buffer space */
+ while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
+ TCP_MAXWIN << tp->request_r_scale < so->so_rcv.sb_hiwat)
+ tp->request_r_scale++;
+ }
+ }
+
+ /*
+ * Segment received on connection.
+ * Reset idle time and keep-alive timer.
+ */
+ tp->t_idle = 0;
+ if (TCPS_HAVEESTABLISHED(tp->t_state))
+ tp->t_timer[TCPT_KEEP] = tcp_keepidle;
+
+ /*
+ * Process options if not in LISTEN state,
+ * else do it below (after getting remote address).
+ */
+ if (tp->t_state != TCPS_LISTEN)
+ tcp_dooptions(tp, optp, optlen, ti, &to);
+
+ /*
+ * Header prediction: check for the two common cases
+ * of a uni-directional data xfer. If the packet has
+ * no control flags, is in-sequence, the window didn't
+ * change and we're not retransmitting, it's a
+ * candidate. If the length is zero and the ack moved
+ * forward, we're the sender side of the xfer. Just
+ * free the data acked & wake any higher level process
+ * that was blocked waiting for space. If the length
+ * is non-zero and the ack didn't move, we're the
+ * receiver side. If we're getting packets in-order
+ * (the reassembly queue is empty), add the data to
+ * the socket buffer and note that we need a delayed ack.
+ * Make sure that the hidden state-flags are also off.
+ * Since we check for TCPS_ESTABLISHED above, it can only
+ * be TH_NEEDSYN.
+ */
+ if (tp->t_state == TCPS_ESTABLISHED &&
+ (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK &&
+ ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) &&
+ ((to.to_flags & TOF_TS) == 0 ||
+ TSTMP_GEQ(to.to_tsval, tp->ts_recent)) &&
+ /*
+ * Using the CC option is compulsory if once started:
+ * the segment is OK if no T/TCP was negotiated or
+ * if the segment has a CC option equal to CCrecv
+ */
+ ((tp->t_flags & (TF_REQ_CC|TF_RCVD_CC)) != (TF_REQ_CC|TF_RCVD_CC) ||
+ ((to.to_flags & TOF_CC) != 0 && to.to_cc == tp->cc_recv)) &&
+ ti->ti_seq == tp->rcv_nxt &&
+ tiwin && tiwin == tp->snd_wnd &&
+ tp->snd_nxt == tp->snd_max) {
+
+ /*
+ * If last ACK falls within this segment's sequence numbers,
+ * record the timestamp.
+ * NOTE that the test is modified according to the latest
+ * proposal of the tcplw@cray.com list (Braden 1993/04/26).
+ */
+ if ((to.to_flags & TOF_TS) != 0 &&
+ SEQ_LEQ(ti->ti_seq, tp->last_ack_sent)) {
+ tp->ts_recent_age = tcp_now;
+ tp->ts_recent = to.to_tsval;
+ }
+
+ if (ti->ti_len == 0) {
+ if (SEQ_GT(ti->ti_ack, tp->snd_una) &&
+ SEQ_LEQ(ti->ti_ack, tp->snd_max) &&
+ tp->snd_cwnd >= tp->snd_wnd &&
+ tp->t_dupacks < tcprexmtthresh) {
+ /*
+ * this is a pure ack for outstanding data.
+ */
+ ++tcpstat.tcps_predack;
+ if ((to.to_flags & TOF_TS) != 0)
+ tcp_xmit_timer(tp,
+ tcp_now - to.to_tsecr + 1);
+ else if (tp->t_rtt &&
+ SEQ_GT(ti->ti_ack, tp->t_rtseq))
+ tcp_xmit_timer(tp, tp->t_rtt);
+ acked = ti->ti_ack - tp->snd_una;
+ tcpstat.tcps_rcvackpack++;
+ tcpstat.tcps_rcvackbyte += acked;
+ sbdrop(&so->so_snd, acked);
+ tp->snd_una = ti->ti_ack;
+ m_freem(m);
+
+ /*
+ * If all outstanding data are acked, stop
+ * retransmit timer, otherwise restart timer
+ * using current (possibly backed-off) value.
+ * If process is waiting for space,
+ * wakeup/selwakeup/signal. If data
+ * are ready to send, let tcp_output
+ * decide between more output or persist.
+ */
+ if (tp->snd_una == tp->snd_max)
+ tp->t_timer[TCPT_REXMT] = 0;
+ else if (tp->t_timer[TCPT_PERSIST] == 0)
+ tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
+
+ if (so->so_snd.sb_flags & SB_NOTIFY)
+ sowwakeup(so);
+ if (so->so_snd.sb_cc)
+ (void) tcp_output(tp);
+ return;
+ }
+ } else if (ti->ti_ack == tp->snd_una &&
+ tp->seg_next == (struct tcpiphdr *)tp &&
+ ti->ti_len <= sbspace(&so->so_rcv)) {
+ /*
+ * this is a pure, in-sequence data packet
+ * with nothing on the reassembly queue and
+ * we have enough buffer space to take it.
+ */
+ ++tcpstat.tcps_preddat;
+ tp->rcv_nxt += ti->ti_len;
+ tcpstat.tcps_rcvpack++;
+ tcpstat.tcps_rcvbyte += ti->ti_len;
+ /*
+ * Add data to socket buffer.
+ */
+ sbappend(&so->so_rcv, m);
+ sorwakeup(so);
+#ifdef TCP_ACK_HACK
+ /*
+ * If this is a short packet, then ACK now - with Nagel
+ * congestion avoidance sender won't send more until
+ * he gets an ACK.
+ */
+ if (tiflags & TH_PUSH) {
+ tp->t_flags |= TF_ACKNOW;
+ tcp_output(tp);
+ } else {
+ tp->t_flags |= TF_DELACK;
+ }
+#else
+ tp->t_flags |= TF_DELACK;
+#endif
+ return;
+ }
+ }
+
+ /*
+ * Calculate amount of space in receive window,
+ * and then do TCP input processing.
+ * Receive window is amount of space in rcv queue,
+ * but not less than advertised window.
+ */
+ { int win;
+
+ win = sbspace(&so->so_rcv);
+ if (win < 0)
+ win = 0;
+ tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt));
+ }
+
+ switch (tp->t_state) {
+
+ /*
+ * If the state is LISTEN then ignore segment if it contains an RST.
+ * If the segment contains an ACK then it is bad and send a RST.
+ * If it does not contain a SYN then it is not interesting; drop it.
+ * If it is from this socket, drop it, it must be forged.
+ * Don't bother responding if the destination was a broadcast.
+ * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
+ * tp->iss, and send a segment:
+ * <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK>
+ * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss.
+ * Fill in remote peer address fields if not previously specified.
+ * Enter SYN_RECEIVED state, and process any other fields of this
+ * segment in this state.
+ */
+ case TCPS_LISTEN: {
+ struct mbuf *am;
+ register struct sockaddr_in *sin;
+
+ if (tiflags & TH_RST)
+ goto drop;
+ if (tiflags & TH_ACK)
+ goto dropwithreset;
+ if ((tiflags & TH_SYN) == 0)
+ goto drop;
+ if ((ti->ti_dport == ti->ti_sport) &&
+ (ti->ti_dst.s_addr == ti->ti_src.s_addr))
+ goto drop;
+ /*
+ * RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
+ * in_broadcast() should never return true on a received
+ * packet with M_BCAST not set.
+ */
+ if (m->m_flags & (M_BCAST|M_MCAST) ||
+ IN_MULTICAST(ntohl(ti->ti_dst.s_addr)))
+ goto drop;
+ am = m_get(M_DONTWAIT, MT_SONAME); /* XXX */
+ if (am == NULL)
+ goto drop;
+ am->m_len = sizeof (struct sockaddr_in);
+ sin = mtod(am, struct sockaddr_in *);
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_addr = ti->ti_src;
+ sin->sin_port = ti->ti_sport;
+ bzero((caddr_t)sin->sin_zero, sizeof(sin->sin_zero));
+ laddr = inp->inp_laddr;
+ if (inp->inp_laddr.s_addr == INADDR_ANY)
+ inp->inp_laddr = ti->ti_dst;
+ if (in_pcbconnect(inp, am)) {
+ inp->inp_laddr = laddr;
+ (void) m_free(am);
+ goto drop;
+ }
+ (void) m_free(am);
+ tp->t_template = tcp_template(tp);
+ if (tp->t_template == 0) {
+ tp = tcp_drop(tp, ENOBUFS);
+ dropsocket = 0; /* socket is already gone */
+ goto drop;
+ }
+ if ((taop = tcp_gettaocache(inp)) == NULL) {
+ taop = &tao_noncached;
+ bzero(taop, sizeof(*taop));
+ }
+ tcp_dooptions(tp, optp, optlen, ti, &to);
+ if (iss)
+ tp->iss = iss;
+ else
+ tp->iss = tcp_iss;
+ tcp_iss += TCP_ISSINCR/4;
+ tp->irs = ti->ti_seq;
+ tcp_sendseqinit(tp);
+ tcp_rcvseqinit(tp);
+ /*
+ * Initialization of the tcpcb for transaction;
+ * set SND.WND = SEG.WND,
+ * initialize CCsend and CCrecv.
+ */
+ tp->snd_wnd = tiwin; /* initial send-window */
+ tp->cc_send = CC_INC(tcp_ccgen);
+ tp->cc_recv = to.to_cc;
+ /*
+ * Perform TAO test on incoming CC (SEG.CC) option, if any.
+ * - compare SEG.CC against cached CC from the same host,
+ * if any.
+ * - if SEG.CC > chached value, SYN must be new and is accepted
+ * immediately: save new CC in the cache, mark the socket
+ * connected, enter ESTABLISHED state, turn on flag to
+ * send a SYN in the next segment.
+ * A virtual advertised window is set in rcv_adv to
+ * initialize SWS prevention. Then enter normal segment
+ * processing: drop SYN, process data and FIN.
+ * - otherwise do a normal 3-way handshake.
+ */
+ if ((to.to_flags & TOF_CC) != 0) {
+ if (taop->tao_cc != 0 && CC_GT(to.to_cc, taop->tao_cc)) {
+ taop->tao_cc = to.to_cc;
+ tp->t_state = TCPS_ESTABLISHED;
+
+ /*
+ * If there is a FIN, or if there is data and the
+ * connection is local, then delay SYN,ACK(SYN) in
+ * the hope of piggy-backing it on a response
+ * segment. Otherwise must send ACK now in case
+ * the other side is slow starting.
+ */
+ if ((tiflags & TH_FIN) || (ti->ti_len != 0 &&
+ in_localaddr(inp->inp_faddr)))
+ tp->t_flags |= (TF_DELACK | TF_NEEDSYN);
+ else
+ tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN);
+
+ /*
+ * Limit the `virtual advertised window' to TCP_MAXWIN
+ * here. Even if we requested window scaling, it will
+ * become effective only later when our SYN is acked.
+ */
+ tp->rcv_adv += min(tp->rcv_wnd, TCP_MAXWIN);
+ tcpstat.tcps_connects++;
+ soisconnected(so);
+ tp->t_timer[TCPT_KEEP] = tcp_keepinit;
+ dropsocket = 0; /* committed to socket */
+ tcpstat.tcps_accepts++;
+ goto trimthenstep6;
+ }
+ /* else do standard 3-way handshake */
+ } else {
+ /*
+ * No CC option, but maybe CC.NEW:
+ * invalidate cached value.
+ */
+ taop->tao_cc = 0;
+ }
+ /*
+ * TAO test failed or there was no CC option,
+ * do a standard 3-way handshake.
+ */
+ tp->t_flags |= TF_ACKNOW;
+ tp->t_state = TCPS_SYN_RECEIVED;
+ tp->t_timer[TCPT_KEEP] = tcp_keepinit;
+ dropsocket = 0; /* committed to socket */
+ tcpstat.tcps_accepts++;
+ goto trimthenstep6;
+ }
+
+ /*
+ * If the state is SYN_RECEIVED:
+ * if seg contains SYN/ACK, send a RST.
+ * if seg contains an ACK, but not for our SYN/ACK, send a RST.
+ */
+ case TCPS_SYN_RECEIVED:
+ if (tiflags & TH_ACK) {
+ if (tiflags & TH_SYN) {
+ tcpstat.tcps_badsyn++;
+ goto dropwithreset;
+ }
+ if (SEQ_LEQ(ti->ti_ack, tp->snd_una) ||
+ SEQ_GT(ti->ti_ack, tp->snd_max))
+ goto dropwithreset;
+ }
+ break;
+
+ /*
+ * If the state is SYN_SENT:
+ * if seg contains an ACK, but not for our SYN, drop the input.
+ * if seg contains a RST, then drop the connection.
+ * if seg does not contain SYN, then drop it.
+ * Otherwise this is an acceptable SYN segment
+ * initialize tp->rcv_nxt and tp->irs
+ * if seg contains ack then advance tp->snd_una
+ * if SYN has been acked change to ESTABLISHED else SYN_RCVD state
+ * arrange for segment to be acked (eventually)
+ * continue processing rest of data/controls, beginning with URG
+ */
+ case TCPS_SYN_SENT:
+ if ((taop = tcp_gettaocache(inp)) == NULL) {
+ taop = &tao_noncached;
+ bzero(taop, sizeof(*taop));
+ }
+
+ if ((tiflags & TH_ACK) &&
+ (SEQ_LEQ(ti->ti_ack, tp->iss) ||
+ SEQ_GT(ti->ti_ack, tp->snd_max))) {
+ /*
+ * If we have a cached CCsent for the remote host,
+ * hence we haven't just crashed and restarted,
+ * do not send a RST. This may be a retransmission
+ * from the other side after our earlier ACK was lost.
+ * Our new SYN, when it arrives, will serve as the
+ * needed ACK.
+ */
+ if (taop->tao_ccsent != 0)
+ goto drop;
+ else
+ goto dropwithreset;
+ }
+ if (tiflags & TH_RST) {
+ if (tiflags & TH_ACK)
+ tp = tcp_drop(tp, ECONNREFUSED);
+ goto drop;
+ }
+ if ((tiflags & TH_SYN) == 0)
+ goto drop;
+ tp->snd_wnd = ti->ti_win; /* initial send window */
+ tp->cc_recv = to.to_cc; /* foreign CC */
+
+ tp->irs = ti->ti_seq;
+ tcp_rcvseqinit(tp);
+ if (tiflags & TH_ACK) {
+ /*
+ * Our SYN was acked. If segment contains CC.ECHO
+ * option, check it to make sure this segment really
+ * matches our SYN. If not, just drop it as old
+ * duplicate, but send an RST if we're still playing
+ * by the old rules. If no CC.ECHO option, make sure
+ * we don't get fooled into using T/TCP.
+ */
+ if (to.to_flags & TOF_CCECHO) {
+ if (tp->cc_send != to.to_ccecho) {
+ if (taop->tao_ccsent != 0)
+ goto drop;
+ else
+ goto dropwithreset;
+ }
+ } else
+ tp->t_flags &= ~TF_RCVD_CC;
+ tcpstat.tcps_connects++;
+ soisconnected(so);
+ /* Do window scaling on this connection? */
+ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
+ (TF_RCVD_SCALE|TF_REQ_SCALE)) {
+ tp->snd_scale = tp->requested_s_scale;
+ tp->rcv_scale = tp->request_r_scale;
+ }
+ /* Segment is acceptable, update cache if undefined. */
+ if (taop->tao_ccsent == 0)
+ taop->tao_ccsent = to.to_ccecho;
+
+ tp->rcv_adv += tp->rcv_wnd;
+ tp->snd_una++; /* SYN is acked */
+ /*
+ * If there's data, delay ACK; if there's also a FIN
+ * ACKNOW will be turned on later.
+ */
+ if (ti->ti_len != 0)
+ tp->t_flags |= TF_DELACK;
+ else
+ tp->t_flags |= TF_ACKNOW;
+ /*
+ * Received <SYN,ACK> in SYN_SENT[*] state.
+ * Transitions:
+ * SYN_SENT --> ESTABLISHED
+ * SYN_SENT* --> FIN_WAIT_1
+ */
+ if (tp->t_flags & TF_NEEDFIN) {
+ tp->t_state = TCPS_FIN_WAIT_1;
+ tp->t_flags &= ~TF_NEEDFIN;
+ tiflags &= ~TH_SYN;
+ } else {
+ tp->t_state = TCPS_ESTABLISHED;
+ tp->t_timer[TCPT_KEEP] = tcp_keepidle;
+ }
+ } else {
+ /*
+ * Received initial SYN in SYN-SENT[*] state => simul-
+ * taneous open. If segment contains CC option and there is
+ * a cached CC, apply TAO test; if it succeeds, connection is
+ * half-synchronized. Otherwise, do 3-way handshake:
+ * SYN-SENT -> SYN-RECEIVED
+ * SYN-SENT* -> SYN-RECEIVED*
+ * If there was no CC option, clear cached CC value.
+ */
+ tp->t_flags |= TF_ACKNOW;
+ tp->t_timer[TCPT_REXMT] = 0;
+ if (to.to_flags & TOF_CC) {
+ if (taop->tao_cc != 0 &&
+ CC_GT(to.to_cc, taop->tao_cc)) {
+ /*
+ * update cache and make transition:
+ * SYN-SENT -> ESTABLISHED*
+ * SYN-SENT* -> FIN-WAIT-1*
+ */
+ taop->tao_cc = to.to_cc;
+ if (tp->t_flags & TF_NEEDFIN) {
+ tp->t_state = TCPS_FIN_WAIT_1;
+ tp->t_flags &= ~TF_NEEDFIN;
+ } else {
+ tp->t_state = TCPS_ESTABLISHED;
+ tp->t_timer[TCPT_KEEP] = tcp_keepidle;
+ }
+ tp->t_flags |= TF_NEEDSYN;
+ } else
+ tp->t_state = TCPS_SYN_RECEIVED;
+ } else {
+ /* CC.NEW or no option => invalidate cache */
+ taop->tao_cc = 0;
+ tp->t_state = TCPS_SYN_RECEIVED;
+ }
+ }
+
+trimthenstep6:
+ /*
+ * Advance ti->ti_seq to correspond to first data byte.
+ * If data, trim to stay within window,
+ * dropping FIN if necessary.
+ */
+ ti->ti_seq++;
+ if (ti->ti_len > tp->rcv_wnd) {
+ todrop = ti->ti_len - tp->rcv_wnd;
+ m_adj(m, -todrop);
+ ti->ti_len = tp->rcv_wnd;
+ tiflags &= ~TH_FIN;
+ tcpstat.tcps_rcvpackafterwin++;
+ tcpstat.tcps_rcvbyteafterwin += todrop;
+ }
+ tp->snd_wl1 = ti->ti_seq - 1;
+ tp->rcv_up = ti->ti_seq;
+ /*
+ * Client side of transaction: already sent SYN and data.
+ * If the remote host used T/TCP to validate the SYN,
+ * our data will be ACK'd; if so, enter normal data segment
+ * processing in the middle of step 5, ack processing.
+ * Otherwise, goto step 6.
+ */
+ if (tiflags & TH_ACK)
+ goto process_ACK;
+ goto step6;
+ /*
+ * If the state is LAST_ACK or CLOSING or TIME_WAIT:
+ * if segment contains a SYN and CC [not CC.NEW] option:
+ * if state == TIME_WAIT and connection duration > MSL,
+ * drop packet and send RST;
+ *
+ * if SEG.CC > CCrecv then is new SYN, and can implicitly
+ * ack the FIN (and data) in retransmission queue.
+ * Complete close and delete TCPCB. Then reprocess
+ * segment, hoping to find new TCPCB in LISTEN state;
+ *
+ * else must be old SYN; drop it.
+ * else do normal processing.
+ */
+ case TCPS_LAST_ACK:
+ case TCPS_CLOSING:
+ case TCPS_TIME_WAIT:
+ if ((tiflags & TH_SYN) &&
+ (to.to_flags & TOF_CC) && tp->cc_recv != 0) {
+ if (tp->t_state == TCPS_TIME_WAIT &&
+ tp->t_duration > TCPTV_MSL)
+ goto dropwithreset;
+ if (CC_GT(to.to_cc, tp->cc_recv)) {
+ tp = tcp_close(tp);
+ goto findpcb;
+ }
+ else
+ goto drop;
+ }
+ break; /* continue normal processing */
+ }
+
+ /*
+ * States other than LISTEN or SYN_SENT.
+ * First check timestamp, if present.
+ * Then check the connection count, if present.
+ * Then check that at least some bytes of segment are within
+ * receive window. If segment begins before rcv_nxt,
+ * drop leading data (and SYN); if nothing left, just ack.
+ *
+ * RFC 1323 PAWS: If we have a timestamp reply on this segment
+ * and it's less than ts_recent, drop it.
+ */
+ if ((to.to_flags & TOF_TS) != 0 && (tiflags & TH_RST) == 0 &&
+ tp->ts_recent && TSTMP_LT(to.to_tsval, tp->ts_recent)) {
+
+ /* Check to see if ts_recent is over 24 days old. */
+ if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) {
+ /*
+ * Invalidate ts_recent. If this segment updates
+ * ts_recent, the age will be reset later and ts_recent
+ * will get a valid value. If it does not, setting
+ * ts_recent to zero will at least satisfy the
+ * requirement that zero be placed in the timestamp
+ * echo reply when ts_recent isn't valid. The
+ * age isn't reset until we get a valid ts_recent
+ * because we don't want out-of-order segments to be
+ * dropped when ts_recent is old.
+ */
+ tp->ts_recent = 0;
+ } else {
+ tcpstat.tcps_rcvduppack++;
+ tcpstat.tcps_rcvdupbyte += ti->ti_len;
+ tcpstat.tcps_pawsdrop++;
+ goto dropafterack;
+ }
+ }
+
+ /*
+ * T/TCP mechanism
+ * If T/TCP was negotiated and the segment doesn't have CC,
+ * or if it's CC is wrong then drop the segment.
+ * RST segments do not have to comply with this.
+ */
+ if ((tp->t_flags & (TF_REQ_CC|TF_RCVD_CC)) == (TF_REQ_CC|TF_RCVD_CC) &&
+ ((to.to_flags & TOF_CC) == 0 || tp->cc_recv != to.to_cc) &&
+ (tiflags & TH_RST) == 0)
+ goto dropafterack;
+
+ todrop = tp->rcv_nxt - ti->ti_seq;
+ if (todrop > 0) {
+ if (tiflags & TH_SYN) {
+ tiflags &= ~TH_SYN;
+ ti->ti_seq++;
+ if (ti->ti_urp > 1)
+ ti->ti_urp--;
+ else
+ tiflags &= ~TH_URG;
+ todrop--;
+ }
+ /*
+ * Following if statement from Stevens, vol. 2, p. 960.
+ */
+ if (todrop > ti->ti_len
+ || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) {
+ /*
+ * Any valid FIN must be to the left of the window.
+ * At this point the FIN must be a duplicate or out
+ * of sequence; drop it.
+ */
+ tiflags &= ~TH_FIN;
+
+ /*
+ * Send an ACK to resynchronize and drop any data.
+ * But keep on processing for RST or ACK.
+ */
+ tp->t_flags |= TF_ACKNOW;
+ todrop = ti->ti_len;
+ tcpstat.tcps_rcvduppack++;
+ tcpstat.tcps_rcvdupbyte += todrop;
+ } else {
+ tcpstat.tcps_rcvpartduppack++;
+ tcpstat.tcps_rcvpartdupbyte += todrop;
+ }
+ m_adj(m, todrop);
+ ti->ti_seq += todrop;
+ ti->ti_len -= todrop;
+ if (ti->ti_urp > todrop)
+ ti->ti_urp -= todrop;
+ else {
+ tiflags &= ~TH_URG;
+ ti->ti_urp = 0;
+ }
+ }
+
+ /*
+ * If new data are received on a connection after the
+ * user processes are gone, then RST the other end.
+ */
+ if ((so->so_state & SS_NOFDREF) &&
+ tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) {
+ tp = tcp_close(tp);
+ tcpstat.tcps_rcvafterclose++;
+ goto dropwithreset;
+ }
+
+ /*
+ * If segment ends after window, drop trailing data
+ * (and PUSH and FIN); if nothing left, just ACK.
+ */
+ todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd);
+ if (todrop > 0) {
+ tcpstat.tcps_rcvpackafterwin++;
+ if (todrop >= ti->ti_len) {
+ tcpstat.tcps_rcvbyteafterwin += ti->ti_len;
+ /*
+ * If a new connection request is received
+ * while in TIME_WAIT, drop the old connection
+ * and start over if the sequence numbers
+ * are above the previous ones.
+ */
+ if (tiflags & TH_SYN &&
+ tp->t_state == TCPS_TIME_WAIT &&
+ SEQ_GT(ti->ti_seq, tp->rcv_nxt)) {
+ iss = tp->rcv_nxt + TCP_ISSINCR;
+ tp = tcp_close(tp);
+ goto findpcb;
+ }
+ /*
+ * If window is closed can only take segments at
+ * window edge, and have to drop data and PUSH from
+ * incoming segments. Continue processing, but
+ * remember to ack. Otherwise, drop segment
+ * and ack.
+ */
+ if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) {
+ tp->t_flags |= TF_ACKNOW;
+ tcpstat.tcps_rcvwinprobe++;
+ } else
+ goto dropafterack;
+ } else
+ tcpstat.tcps_rcvbyteafterwin += todrop;
+ m_adj(m, -todrop);
+ ti->ti_len -= todrop;
+ tiflags &= ~(TH_PUSH|TH_FIN);
+ }
+
+ /*
+ * If last ACK falls within this segment's sequence numbers,
+ * record its timestamp.
+ * NOTE that the test is modified according to the latest
+ * proposal of the tcplw@cray.com list (Braden 1993/04/26).
+ */
+ if ((to.to_flags & TOF_TS) != 0 &&
+ SEQ_LEQ(ti->ti_seq, tp->last_ack_sent)) {
+ tp->ts_recent_age = tcp_now;
+ tp->ts_recent = to.to_tsval;
+ }
+
+ /*
+ * If the RST bit is set examine the state:
+ * SYN_RECEIVED STATE:
+ * If passive open, return to LISTEN state.
+ * If active open, inform user that connection was refused.
+ * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
+ * Inform user that connection was reset, and close tcb.
+ * CLOSING, LAST_ACK, TIME_WAIT STATES
+ * Close the tcb.
+ */
+ if (tiflags&TH_RST) switch (tp->t_state) {
+
+ case TCPS_SYN_RECEIVED:
+ so->so_error = ECONNREFUSED;
+ goto close;
+
+ case TCPS_ESTABLISHED:
+ case TCPS_FIN_WAIT_1:
+ case TCPS_FIN_WAIT_2:
+ case TCPS_CLOSE_WAIT:
+ so->so_error = ECONNRESET;
+ close:
+ tp->t_state = TCPS_CLOSED;
+ tcpstat.tcps_drops++;
+ tp = tcp_close(tp);
+ goto drop;
+
+ case TCPS_CLOSING:
+ case TCPS_LAST_ACK:
+ case TCPS_TIME_WAIT:
+ tp = tcp_close(tp);
+ goto drop;
+ }
+
+ /*
+ * If a SYN is in the window, then this is an
+ * error and we send an RST and drop the connection.
+ */
+ if (tiflags & TH_SYN) {
+ tp = tcp_drop(tp, ECONNRESET);
+ goto dropwithreset;
+ }
+
+ /*
+ * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN
+ * flag is on (half-synchronized state), then queue data for
+ * later processing; else drop segment and return.
+ */
+ if ((tiflags & TH_ACK) == 0) {
+ if (tp->t_state == TCPS_SYN_RECEIVED ||
+ (tp->t_flags & TF_NEEDSYN))
+ goto step6;
+ else
+ goto drop;
+ }
+
+ /*
+ * Ack processing.
+ */
+ switch (tp->t_state) {
+
+ /*
+ * In SYN_RECEIVED state, the ack ACKs our SYN, so enter
+ * ESTABLISHED state and continue processing.
+ * The ACK was checked above.
+ */
+ case TCPS_SYN_RECEIVED:
+
+ tcpstat.tcps_connects++;
+ soisconnected(so);
+ /* Do window scaling? */
+ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
+ (TF_RCVD_SCALE|TF_REQ_SCALE)) {
+ tp->snd_scale = tp->requested_s_scale;
+ tp->rcv_scale = tp->request_r_scale;
+ }
+ /*
+ * Upon successful completion of 3-way handshake,
+ * update cache.CC if it was undefined, pass any queued
+ * data to the user, and advance state appropriately.
+ */
+ if ((taop = tcp_gettaocache(inp)) != NULL &&
+ taop->tao_cc == 0)
+ taop->tao_cc = tp->cc_recv;
+
+ /*
+ * Make transitions:
+ * SYN-RECEIVED -> ESTABLISHED
+ * SYN-RECEIVED* -> FIN-WAIT-1
+ */
+ if (tp->t_flags & TF_NEEDFIN) {
+ tp->t_state = TCPS_FIN_WAIT_1;
+ tp->t_flags &= ~TF_NEEDFIN;
+ } else {
+ tp->t_state = TCPS_ESTABLISHED;
+ tp->t_timer[TCPT_KEEP] = tcp_keepidle;
+ }
+ /*
+ * If segment contains data or ACK, will call tcp_reass()
+ * later; if not, do so now to pass queued data to user.
+ */
+ if (ti->ti_len == 0 && (tiflags & TH_FIN) == 0)
+ (void) tcp_reass(tp, (struct tcpiphdr *)0,
+ (struct mbuf *)0);
+ tp->snd_wl1 = ti->ti_seq - 1;
+ /* fall into ... */
+
+ /*
+ * In ESTABLISHED state: drop duplicate ACKs; ACK out of range
+ * ACKs. If the ack is in the range
+ * tp->snd_una < ti->ti_ack <= tp->snd_max
+ * then advance tp->snd_una to ti->ti_ack and drop
+ * data from the retransmission queue. If this ACK reflects
+ * more up to date window information we update our window information.
+ */
+ case TCPS_ESTABLISHED:
+ case TCPS_FIN_WAIT_1:
+ case TCPS_FIN_WAIT_2:
+ case TCPS_CLOSE_WAIT:
+ case TCPS_CLOSING:
+ case TCPS_LAST_ACK:
+ case TCPS_TIME_WAIT:
+
+ if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) {
+ if (ti->ti_len == 0 && tiwin == tp->snd_wnd) {
+ tcpstat.tcps_rcvdupack++;
+ /*
+ * If we have outstanding data (other than
+ * a window probe), this is a completely
+ * duplicate ack (ie, window info didn't
+ * change), the ack is the biggest we've
+ * seen and we've seen exactly our rexmt
+ * threshhold of them, assume a packet
+ * has been dropped and retransmit it.
+ * Kludge snd_nxt & the congestion
+ * window so we send only this one
+ * packet.
+ *
+ * We know we're losing at the current
+ * window size so do congestion avoidance
+ * (set ssthresh to half the current window
+ * and pull our congestion window back to
+ * the new ssthresh).
+ *
+ * Dup acks mean that packets have left the
+ * network (they're now cached at the receiver)
+ * so bump cwnd by the amount in the receiver
+ * to keep a constant cwnd packets in the
+ * network.
+ */
+ if (tp->t_timer[TCPT_REXMT] == 0 ||
+ ti->ti_ack != tp->snd_una)
+ tp->t_dupacks = 0;
+ else if (++tp->t_dupacks == tcprexmtthresh) {
+ tcp_seq onxt = tp->snd_nxt;
+ u_int win =
+ min(tp->snd_wnd, tp->snd_cwnd) / 2 /
+ tp->t_maxseg;
+
+ if (win < 2)
+ win = 2;
+ tp->snd_ssthresh = win * tp->t_maxseg;
+ tp->t_timer[TCPT_REXMT] = 0;
+ tp->t_rtt = 0;
+ tp->snd_nxt = ti->ti_ack;
+ tp->snd_cwnd = tp->t_maxseg;
+ (void) tcp_output(tp);
+ tp->snd_cwnd = tp->snd_ssthresh +
+ tp->t_maxseg * tp->t_dupacks;
+ if (SEQ_GT(onxt, tp->snd_nxt))
+ tp->snd_nxt = onxt;
+ goto drop;
+ } else if (tp->t_dupacks > tcprexmtthresh) {
+ tp->snd_cwnd += tp->t_maxseg;
+ (void) tcp_output(tp);
+ goto drop;
+ }
+ } else
+ tp->t_dupacks = 0;
+ break;
+ }
+ /*
+ * If the congestion window was inflated to account
+ * for the other side's cached packets, retract it.
+ */
+ if (tp->t_dupacks >= tcprexmtthresh &&
+ tp->snd_cwnd > tp->snd_ssthresh)
+ tp->snd_cwnd = tp->snd_ssthresh;
+ tp->t_dupacks = 0;
+ if (SEQ_GT(ti->ti_ack, tp->snd_max)) {
+ tcpstat.tcps_rcvacktoomuch++;
+ goto dropafterack;
+ }
+ /*
+ * If we reach this point, ACK is not a duplicate,
+ * i.e., it ACKs something we sent.
+ */
+ if (tp->t_flags & TF_NEEDSYN) {
+ /*
+ * T/TCP: Connection was half-synchronized, and our
+ * SYN has been ACK'd (so connection is now fully
+ * synchronized). Go to non-starred state,
+ * increment snd_una for ACK of SYN, and check if
+ * we can do window scaling.
+ */
+ tp->t_flags &= ~TF_NEEDSYN;
+ tp->snd_una++;
+ /* Do window scaling? */
+ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
+ (TF_RCVD_SCALE|TF_REQ_SCALE)) {
+ tp->snd_scale = tp->requested_s_scale;
+ tp->rcv_scale = tp->request_r_scale;
+ }
+ }
+
+process_ACK:
+ acked = ti->ti_ack - tp->snd_una;
+ tcpstat.tcps_rcvackpack++;
+ tcpstat.tcps_rcvackbyte += acked;
+
+ /*
+ * If we have a timestamp reply, update smoothed
+ * round trip time. If no timestamp is present but
+ * transmit timer is running and timed sequence
+ * number was acked, update smoothed round trip time.
+ * Since we now have an rtt measurement, cancel the
+ * timer backoff (cf., Phil Karn's retransmit alg.).
+ * Recompute the initial retransmit timer.
+ */
+ if (to.to_flags & TOF_TS)
+ tcp_xmit_timer(tp, tcp_now - to.to_tsecr + 1);
+ else if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq))
+ tcp_xmit_timer(tp,tp->t_rtt);
+
+ /*
+ * If all outstanding data is acked, stop retransmit
+ * timer and remember to restart (more output or persist).
+ * If there is more data to be acked, restart retransmit
+ * timer, using current (possibly backed-off) value.
+ */
+ if (ti->ti_ack == tp->snd_max) {
+ tp->t_timer[TCPT_REXMT] = 0;
+ needoutput = 1;
+ } else if (tp->t_timer[TCPT_PERSIST] == 0)
+ tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
+
+ /*
+ * If no data (only SYN) was ACK'd,
+ * skip rest of ACK processing.
+ */
+ if (acked == 0)
+ goto step6;
+
+ /*
+ * When new data is acked, open the congestion window.
+ * If the window gives us less than ssthresh packets
+ * in flight, open exponentially (maxseg per packet).
+ * Otherwise open linearly: maxseg per window
+ * (maxseg^2 / cwnd per packet).
+ */
+ {
+ register u_int cw = tp->snd_cwnd;
+ register u_int incr = tp->t_maxseg;
+
+ if (cw > tp->snd_ssthresh)
+ incr = incr * incr / cw;
+ tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<<tp->snd_scale);
+ }
+ if (acked > so->so_snd.sb_cc) {
+ tp->snd_wnd -= so->so_snd.sb_cc;
+ sbdrop(&so->so_snd, (int)so->so_snd.sb_cc);
+ ourfinisacked = 1;
+ } else {
+ sbdrop(&so->so_snd, acked);
+ tp->snd_wnd -= acked;
+ ourfinisacked = 0;
+ }
+ if (so->so_snd.sb_flags & SB_NOTIFY)
+ sowwakeup(so);
+ tp->snd_una = ti->ti_ack;
+ if (SEQ_LT(tp->snd_nxt, tp->snd_una))
+ tp->snd_nxt = tp->snd_una;
+
+ switch (tp->t_state) {
+
+ /*
+ * In FIN_WAIT_1 STATE in addition to the processing
+ * for the ESTABLISHED state if our FIN is now acknowledged
+ * then enter FIN_WAIT_2.
+ */
+ case TCPS_FIN_WAIT_1:
+ if (ourfinisacked) {
+ /*
+ * If we can't receive any more
+ * data, then closing user can proceed.
+ * Starting the timer is contrary to the
+ * specification, but if we don't get a FIN
+ * we'll hang forever.
+ */
+ if (so->so_state & SS_CANTRCVMORE) {
+ soisdisconnected(so);
+ tp->t_timer[TCPT_2MSL] = tcp_maxidle;
+ }
+ tp->t_state = TCPS_FIN_WAIT_2;
+ }
+ break;
+
+ /*
+ * In CLOSING STATE in addition to the processing for
+ * the ESTABLISHED state if the ACK acknowledges our FIN
+ * then enter the TIME-WAIT state, otherwise ignore
+ * the segment.
+ */
+ case TCPS_CLOSING:
+ if (ourfinisacked) {
+ tp->t_state = TCPS_TIME_WAIT;
+ tcp_canceltimers(tp);
+ /* Shorten TIME_WAIT [RFC-1644, p.28] */
+ if (tp->cc_recv != 0 &&
+ tp->t_duration < TCPTV_MSL)
+ tp->t_timer[TCPT_2MSL] =
+ tp->t_rxtcur * TCPTV_TWTRUNC;
+ else
+ tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
+ soisdisconnected(so);
+ }
+ break;
+
+ /*
+ * In LAST_ACK, we may still be waiting for data to drain
+ * and/or to be acked, as well as for the ack of our FIN.
+ * If our FIN is now acknowledged, delete the TCB,
+ * enter the closed state and return.
+ */
+ case TCPS_LAST_ACK:
+ if (ourfinisacked) {
+ tp = tcp_close(tp);
+ goto drop;
+ }
+ break;
+
+ /*
+ * In TIME_WAIT state the only thing that should arrive
+ * is a retransmission of the remote FIN. Acknowledge
+ * it and restart the finack timer.
+ */
+ case TCPS_TIME_WAIT:
+ tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
+ goto dropafterack;
+ }
+ }
+
+step6:
+ /*
+ * Update window information.
+ * Don't look at window if no ACK: TAC's send garbage on first SYN.
+ */
+ if ((tiflags & TH_ACK) &&
+ (SEQ_LT(tp->snd_wl1, ti->ti_seq) ||
+ (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) ||
+ (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) {
+ /* keep track of pure window updates */
+ if (ti->ti_len == 0 &&
+ tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd)
+ tcpstat.tcps_rcvwinupd++;
+ tp->snd_wnd = tiwin;
+ tp->snd_wl1 = ti->ti_seq;
+ tp->snd_wl2 = ti->ti_ack;
+ if (tp->snd_wnd > tp->max_sndwnd)
+ tp->max_sndwnd = tp->snd_wnd;
+ needoutput = 1;
+ }
+
+ /*
+ * Process segments with URG.
+ */
+ if ((tiflags & TH_URG) && ti->ti_urp &&
+ TCPS_HAVERCVDFIN(tp->t_state) == 0) {
+ /*
+ * This is a kludge, but if we receive and accept
+ * random urgent pointers, we'll crash in
+ * soreceive. It's hard to imagine someone
+ * actually wanting to send this much urgent data.
+ */
+ if (ti->ti_urp + so->so_rcv.sb_cc > sb_max) {
+ ti->ti_urp = 0; /* XXX */
+ tiflags &= ~TH_URG; /* XXX */
+ goto dodata; /* XXX */
+ }
+ /*
+ * If this segment advances the known urgent pointer,
+ * then mark the data stream. This should not happen
+ * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since
+ * a FIN has been received from the remote side.
+ * In these states we ignore the URG.
+ *
+ * According to RFC961 (Assigned Protocols),
+ * the urgent pointer points to the last octet
+ * of urgent data. We continue, however,
+ * to consider it to indicate the first octet
+ * of data past the urgent section as the original
+ * spec states (in one of two places).
+ */
+ if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) {
+ tp->rcv_up = ti->ti_seq + ti->ti_urp;
+ so->so_oobmark = so->so_rcv.sb_cc +
+ (tp->rcv_up - tp->rcv_nxt) - 1;
+ if (so->so_oobmark == 0)
+ so->so_state |= SS_RCVATMARK;
+ sohasoutofband(so);
+ tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA);
+ }
+ /*
+ * Remove out of band data so doesn't get presented to user.
+ * This can happen independent of advancing the URG pointer,
+ * but if two URG's are pending at once, some out-of-band
+ * data may creep in... ick.
+ */
+ if (ti->ti_urp <= (u_long)ti->ti_len
+#ifdef SO_OOBINLINE
+ && (so->so_options & SO_OOBINLINE) == 0
+#endif
+ )
+ tcp_pulloutofband(so, ti, m);
+ } else
+ /*
+ * If no out of band data is expected,
+ * pull receive urgent pointer along
+ * with the receive window.
+ */
+ if (SEQ_GT(tp->rcv_nxt, tp->rcv_up))
+ tp->rcv_up = tp->rcv_nxt;
+dodata: /* XXX */
+
+ /*
+ * Process the segment text, merging it into the TCP sequencing queue,
+ * and arranging for acknowledgment of receipt if necessary.
+ * This process logically involves adjusting tp->rcv_wnd as data
+ * is presented to the user (this happens in tcp_usrreq.c,
+ * case PRU_RCVD). If a FIN has already been received on this
+ * connection then we just ignore the text.
+ */
+ if ((ti->ti_len || (tiflags&TH_FIN)) &&
+ TCPS_HAVERCVDFIN(tp->t_state) == 0) {
+ TCP_REASS(tp, ti, m, so, tiflags);
+ /*
+ * Note the amount of data that peer has sent into
+ * our window, in order to estimate the sender's
+ * buffer size.
+ */
+ len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt);
+ } else {
+ m_freem(m);
+ tiflags &= ~TH_FIN;
+ }
+
+ /*
+ * If FIN is received ACK the FIN and let the user know
+ * that the connection is closing.
+ */
+ if (tiflags & TH_FIN) {
+ if (TCPS_HAVERCVDFIN(tp->t_state) == 0) {
+ socantrcvmore(so);
+ /*
+ * If connection is half-synchronized
+ * (ie NEEDSYN flag on) then delay ACK,
+ * so it may be piggybacked when SYN is sent.
+ * Otherwise, since we received a FIN then no
+ * more input can be expected, send ACK now.
+ */
+ if (tp->t_flags & TF_NEEDSYN)
+ tp->t_flags |= TF_DELACK;
+ else
+ tp->t_flags |= TF_ACKNOW;
+ tp->rcv_nxt++;
+ }
+ switch (tp->t_state) {
+
+ /*
+ * In SYN_RECEIVED and ESTABLISHED STATES
+ * enter the CLOSE_WAIT state.
+ */
+ case TCPS_SYN_RECEIVED:
+ case TCPS_ESTABLISHED:
+ tp->t_state = TCPS_CLOSE_WAIT;
+ break;
+
+ /*
+ * If still in FIN_WAIT_1 STATE FIN has not been acked so
+ * enter the CLOSING state.
+ */
+ case TCPS_FIN_WAIT_1:
+ tp->t_state = TCPS_CLOSING;
+ break;
+
+ /*
+ * In FIN_WAIT_2 state enter the TIME_WAIT state,
+ * starting the time-wait timer, turning off the other
+ * standard timers.
+ */
+ case TCPS_FIN_WAIT_2:
+ tp->t_state = TCPS_TIME_WAIT;
+ tcp_canceltimers(tp);
+ /* Shorten TIME_WAIT [RFC-1644, p.28] */
+ if (tp->cc_recv != 0 &&
+ tp->t_duration < TCPTV_MSL) {
+ tp->t_timer[TCPT_2MSL] =
+ tp->t_rxtcur * TCPTV_TWTRUNC;
+ /* For transaction client, force ACK now. */
+ tp->t_flags |= TF_ACKNOW;
+ }
+ else
+ tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
+ soisdisconnected(so);
+ break;
+
+ /*
+ * In TIME_WAIT state restart the 2 MSL time_wait timer.
+ */
+ case TCPS_TIME_WAIT:
+ tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
+ break;
+ }
+ }
+#ifdef TCPDEBUG
+ if (so->so_options & SO_DEBUG)
+ tcp_trace(TA_INPUT, ostate, tp, &tcp_saveti, 0);
+#endif
+
+ /*
+ * Return any desired output.
+ */
+ if (needoutput || (tp->t_flags & TF_ACKNOW))
+ (void) tcp_output(tp);
+ return;
+
+dropafterack:
+ /*
+ * Generate an ACK dropping incoming segment if it occupies
+ * sequence space, where the ACK reflects our state.
+ */
+ if (tiflags & TH_RST)
+ goto drop;
+#ifdef TCPDEBUG
+ if (so->so_options & SO_DEBUG)
+ tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0);
+#endif
+ m_freem(m);
+ tp->t_flags |= TF_ACKNOW;
+ (void) tcp_output(tp);
+ return;
+
+dropwithreset:
+ /*
+ * Generate a RST, dropping incoming segment.
+ * Make ACK acceptable to originator of segment.
+ * Don't bother to respond if destination was broadcast/multicast.
+ */
+ if ((tiflags & TH_RST) || m->m_flags & (M_BCAST|M_MCAST) ||
+ IN_MULTICAST(ntohl(ti->ti_dst.s_addr)))
+ goto drop;
+#ifdef TCPDEBUG
+ if (tp == 0 || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
+ tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0);
+#endif
+ if (tiflags & TH_ACK)
+ tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST);
+ else {
+ if (tiflags & TH_SYN)
+ ti->ti_len++;
+ tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0,
+ TH_RST|TH_ACK);
+ }
+ /* destroy temporarily created socket */
+ if (dropsocket)
+ (void) soabort(so);
+ return;
+
+drop:
+ /*
+ * Drop space held by incoming segment and return.
+ */
+#ifdef TCPDEBUG
+ if (tp == 0 || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
+ tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0);
+#endif
+ m_freem(m);
+ /* destroy temporarily created socket */
+ if (dropsocket)
+ (void) soabort(so);
+ return;
+#ifndef TUBA_INCLUDE
+}
+
+static void
+tcp_dooptions(tp, cp, cnt, ti, to)
+ struct tcpcb *tp;
+ u_char *cp;
+ int cnt;
+ struct tcpiphdr *ti;
+ struct tcpopt *to;
+{
+ u_short mss = 0;
+ int opt, optlen;
+
+ for (; cnt > 0; cnt -= optlen, cp += optlen) {
+ opt = cp[0];
+ if (opt == TCPOPT_EOL)
+ break;
+ if (opt == TCPOPT_NOP)
+ optlen = 1;
+ else {
+ optlen = cp[1];
+ if (optlen <= 0)
+ break;
+ }
+ switch (opt) {
+
+ default:
+ continue;
+
+ case TCPOPT_MAXSEG:
+ if (optlen != TCPOLEN_MAXSEG)
+ continue;
+ if (!(ti->ti_flags & TH_SYN))
+ continue;
+ bcopy((char *) cp + 2, (char *) &mss, sizeof(mss));
+ NTOHS(mss);
+ break;
+
+ case TCPOPT_WINDOW:
+ if (optlen != TCPOLEN_WINDOW)
+ continue;
+ if (!(ti->ti_flags & TH_SYN))
+ continue;
+ tp->t_flags |= TF_RCVD_SCALE;
+ tp->requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT);
+ break;
+
+ case TCPOPT_TIMESTAMP:
+ if (optlen != TCPOLEN_TIMESTAMP)
+ continue;
+ to->to_flags |= TOF_TS;
+ bcopy((char *)cp + 2,
+ (char *)&to->to_tsval, sizeof(to->to_tsval));
+ NTOHL(to->to_tsval);
+ bcopy((char *)cp + 6,
+ (char *)&to->to_tsecr, sizeof(to->to_tsecr));
+ NTOHL(to->to_tsecr);
+
+ /*
+ * A timestamp received in a SYN makes
+ * it ok to send timestamp requests and replies.
+ */
+ if (ti->ti_flags & TH_SYN) {
+ tp->t_flags |= TF_RCVD_TSTMP;
+ tp->ts_recent = to->to_tsval;
+ tp->ts_recent_age = tcp_now;
+ }
+ break;
+ case TCPOPT_CC:
+ if (optlen != TCPOLEN_CC)
+ continue;
+ to->to_flags |= TOF_CC;
+ bcopy((char *)cp + 2,
+ (char *)&to->to_cc, sizeof(to->to_cc));
+ NTOHL(to->to_cc);
+ /*
+ * A CC or CC.new option received in a SYN makes
+ * it ok to send CC in subsequent segments.
+ */
+ if (ti->ti_flags & TH_SYN)
+ tp->t_flags |= TF_RCVD_CC;
+ break;
+ case TCPOPT_CCNEW:
+ if (optlen != TCPOLEN_CC)
+ continue;
+ if (!(ti->ti_flags & TH_SYN))
+ continue;
+ to->to_flags |= TOF_CCNEW;
+ bcopy((char *)cp + 2,
+ (char *)&to->to_cc, sizeof(to->to_cc));
+ NTOHL(to->to_cc);
+ /*
+ * A CC or CC.new option received in a SYN makes
+ * it ok to send CC in subsequent segments.
+ */
+ tp->t_flags |= TF_RCVD_CC;
+ break;
+ case TCPOPT_CCECHO:
+ if (optlen != TCPOLEN_CC)
+ continue;
+ if (!(ti->ti_flags & TH_SYN))
+ continue;
+ to->to_flags |= TOF_CCECHO;
+ bcopy((char *)cp + 2,
+ (char *)&to->to_ccecho, sizeof(to->to_ccecho));
+ NTOHL(to->to_ccecho);
+ break;
+ }
+ }
+ if (ti->ti_flags & TH_SYN)
+ tcp_mss(tp, mss); /* sets t_maxseg */
+}
+
+/*
+ * Pull out of band byte out of a segment so
+ * it doesn't appear in the user's data queue.
+ * It is still reflected in the segment length for
+ * sequencing purposes.
+ */
+static void
+tcp_pulloutofband(so, ti, m)
+ struct socket *so;
+ struct tcpiphdr *ti;
+ register struct mbuf *m;
+{
+ int cnt = ti->ti_urp - 1;
+
+ while (cnt >= 0) {
+ if (m->m_len > cnt) {
+ char *cp = mtod(m, caddr_t) + cnt;
+ struct tcpcb *tp = sototcpcb(so);
+
+ tp->t_iobc = *cp;
+ tp->t_oobflags |= TCPOOB_HAVEDATA;
+ bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1));
+ m->m_len--;
+ return;
+ }
+ cnt -= m->m_len;
+ m = m->m_next;
+ if (m == 0)
+ break;
+ }
+ panic("tcp_pulloutofband");
+}
+
+/*
+ * Collect new round-trip time estimate
+ * and update averages and current timeout.
+ */
+static void
+tcp_xmit_timer(tp, rtt)
+ register struct tcpcb *tp;
+ short rtt;
+{
+ register int delta;
+
+ tcpstat.tcps_rttupdated++;
+ tp->t_rttupdated++;
+ if (tp->t_srtt != 0) {
+ /*
+ * srtt is stored as fixed point with 5 bits after the
+ * binary point (i.e., scaled by 8). The following magic
+ * is equivalent to the smoothing algorithm in rfc793 with
+ * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed
+ * point). Adjust rtt to origin 0.
+ */
+ delta = ((rtt - 1) << TCP_DELTA_SHIFT)
+ - (tp->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT));
+
+ if ((tp->t_srtt += delta) <= 0)
+ tp->t_srtt = 1;
+
+ /*
+ * We accumulate a smoothed rtt variance (actually, a
+ * smoothed mean difference), then set the retransmit
+ * timer to smoothed rtt + 4 times the smoothed variance.
+ * rttvar is stored as fixed point with 4 bits after the
+ * binary point (scaled by 16). The following is
+ * equivalent to rfc793 smoothing with an alpha of .75
+ * (rttvar = rttvar*3/4 + |delta| / 4). This replaces
+ * rfc793's wired-in beta.
+ */
+ if (delta < 0)
+ delta = -delta;
+ delta -= tp->t_rttvar >> (TCP_RTTVAR_SHIFT - TCP_DELTA_SHIFT);
+ if ((tp->t_rttvar += delta) <= 0)
+ tp->t_rttvar = 1;
+ } else {
+ /*
+ * No rtt measurement yet - use the unsmoothed rtt.
+ * Set the variance to half the rtt (so our first
+ * retransmit happens at 3*rtt).
+ */
+ tp->t_srtt = rtt << TCP_RTT_SHIFT;
+ tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1);
+ }
+ tp->t_rtt = 0;
+ tp->t_rxtshift = 0;
+
+ /*
+ * the retransmit should happen at rtt + 4 * rttvar.
+ * Because of the way we do the smoothing, srtt and rttvar
+ * will each average +1/2 tick of bias. When we compute
+ * the retransmit timer, we want 1/2 tick of rounding and
+ * 1 extra tick because of +-1/2 tick uncertainty in the
+ * firing of the timer. The bias will give us exactly the
+ * 1.5 tick we need. But, because the bias is
+ * statistical, we have to test that we don't drop below
+ * the minimum feasible timer (which is 2 ticks).
+ */
+ TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp),
+ max(tp->t_rttmin, rtt + 2), TCPTV_REXMTMAX);
+
+ /*
+ * We received an ack for a packet that wasn't retransmitted;
+ * it is probably safe to discard any error indications we've
+ * received recently. This isn't quite right, but close enough
+ * for now (a route might have failed after we sent a segment,
+ * and the return path might not be symmetrical).
+ */
+ tp->t_softerror = 0;
+}
+
+/*
+ * Determine a reasonable value for maxseg size.
+ * If the route is known, check route for mtu.
+ * If none, use an mss that can be handled on the outgoing
+ * interface without forcing IP to fragment; if bigger than
+ * an mbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES
+ * to utilize large mbufs. If no route is found, route has no mtu,
+ * or the destination isn't local, use a default, hopefully conservative
+ * size (usually 512 or the default IP max size, but no more than the mtu
+ * of the interface), as we can't discover anything about intervening
+ * gateways or networks. We also initialize the congestion/slow start
+ * window to be a single segment if the destination isn't local.
+ * While looking at the routing entry, we also initialize other path-dependent
+ * parameters from pre-set or cached values in the routing entry.
+ *
+ * Also take into account the space needed for options that we
+ * send regularly. Make maxseg shorter by that amount to assure
+ * that we can send maxseg amount of data even when the options
+ * are present. Store the upper limit of the length of options plus
+ * data in maxopd.
+ *
+ * NOTE that this routine is only called when we process an incoming
+ * segment, for outgoing segments only tcp_mssopt is called.
+ *
+ * In case of T/TCP, we call this routine during implicit connection
+ * setup as well (offer = -1), to initialize maxseg from the cached
+ * MSS of our peer.
+ */
+void
+tcp_mss(tp, offer)
+ struct tcpcb *tp;
+ int offer;
+{
+ register struct rtentry *rt;
+ struct ifnet *ifp;
+ register int rtt, mss;
+ u_long bufsize;
+ struct inpcb *inp;
+ struct socket *so;
+ struct rmxp_tao *taop;
+ int origoffer = offer;
+
+ inp = tp->t_inpcb;
+ if ((rt = tcp_rtlookup(inp)) == NULL) {
+ tp->t_maxopd = tp->t_maxseg = tcp_mssdflt;
+ return;
+ }
+ ifp = rt->rt_ifp;
+ so = inp->inp_socket;
+
+ taop = rmx_taop(rt->rt_rmx);
+ /*
+ * Offer == -1 means that we didn't receive SYN yet,
+ * use cached value in that case;
+ */
+ if (offer == -1)
+ offer = taop->tao_mssopt;
+ /*
+ * Offer == 0 means that there was no MSS on the SYN segment,
+ * in this case we use tcp_mssdflt.
+ */
+ if (offer == 0)
+ offer = tcp_mssdflt;
+ else
+ /*
+ * Sanity check: make sure that maxopd will be large
+ * enough to allow some data on segments even is the
+ * all the option space is used (40bytes). Otherwise
+ * funny things may happen in tcp_output.
+ */
+ offer = max(offer, 64);
+ taop->tao_mssopt = offer;
+
+ /*
+ * While we're here, check if there's an initial rtt
+ * or rttvar. Convert from the route-table units
+ * to scaled multiples of the slow timeout timer.
+ */
+ if (tp->t_srtt == 0 && (rtt = rt->rt_rmx.rmx_rtt)) {
+ /*
+ * XXX the lock bit for RTT indicates that the value
+ * is also a minimum value; this is subject to time.
+ */
+ if (rt->rt_rmx.rmx_locks & RTV_RTT)
+ tp->t_rttmin = rtt / (RTM_RTTUNIT / PR_SLOWHZ);
+ tp->t_srtt = rtt / (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTT_SCALE));
+ tcpstat.tcps_usedrtt++;
+ if (rt->rt_rmx.rmx_rttvar) {
+ tp->t_rttvar = rt->rt_rmx.rmx_rttvar /
+ (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTTVAR_SCALE));
+ tcpstat.tcps_usedrttvar++;
+ } else {
+ /* default variation is +- 1 rtt */
+ tp->t_rttvar =
+ tp->t_srtt * TCP_RTTVAR_SCALE / TCP_RTT_SCALE;
+ }
+ TCPT_RANGESET(tp->t_rxtcur,
+ ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1,
+ tp->t_rttmin, TCPTV_REXMTMAX);
+ }
+ /*
+ * if there's an mtu associated with the route, use it
+ */
+ if (rt->rt_rmx.rmx_mtu)
+ mss = rt->rt_rmx.rmx_mtu - sizeof(struct tcpiphdr);
+ else
+ {
+ mss = ifp->if_mtu - sizeof(struct tcpiphdr);
+ if (!in_localaddr(inp->inp_faddr))
+ mss = min(mss, tcp_mssdflt);
+ }
+ mss = min(mss, offer);
+ /*
+ * maxopd stores the maximum length of data AND options
+ * in a segment; maxseg is the amount of data in a normal
+ * segment. We need to store this value (maxopd) apart
+ * from maxseg, because now every segment carries options
+ * and thus we normally have somewhat less data in segments.
+ */
+ tp->t_maxopd = mss;
+
+ /*
+ * In case of T/TCP, origoffer==-1 indicates, that no segments
+ * were received yet. In this case we just guess, otherwise
+ * we do the same as before T/TCP.
+ */
+ if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
+ (origoffer == -1 ||
+ (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP))
+ mss -= TCPOLEN_TSTAMP_APPA;
+ if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
+ (origoffer == -1 ||
+ (tp->t_flags & TF_RCVD_CC) == TF_RCVD_CC))
+ mss -= TCPOLEN_CC_APPA;
+
+#if (MCLBYTES & (MCLBYTES - 1)) == 0
+ if (mss > MCLBYTES)
+ mss &= ~(MCLBYTES-1);
+#else
+ if (mss > MCLBYTES)
+ mss = mss / MCLBYTES * MCLBYTES;
+#endif
+ /*
+ * If there's a pipesize, change the socket buffer
+ * to that size. Make the socket buffers an integral
+ * number of mss units; if the mss is larger than
+ * the socket buffer, decrease the mss.
+ */
+#ifdef RTV_SPIPE
+ if ((bufsize = rt->rt_rmx.rmx_sendpipe) == 0)
+#endif
+ bufsize = so->so_snd.sb_hiwat;
+ if (bufsize < mss)
+ mss = bufsize;
+ else {
+ bufsize = roundup(bufsize, mss);
+ if (bufsize > sb_max)
+ bufsize = sb_max;
+ (void)sbreserve(&so->so_snd, bufsize);
+ }
+ tp->t_maxseg = mss;
+
+#ifdef RTV_RPIPE
+ if ((bufsize = rt->rt_rmx.rmx_recvpipe) == 0)
+#endif
+ bufsize = so->so_rcv.sb_hiwat;
+ if (bufsize > mss) {
+ bufsize = roundup(bufsize, mss);
+ if (bufsize > sb_max)
+ bufsize = sb_max;
+ (void)sbreserve(&so->so_rcv, bufsize);
+ }
+ /*
+ * Don't force slow-start on local network.
+ */
+ if (!in_localaddr(inp->inp_faddr))
+ tp->snd_cwnd = mss;
+
+ if (rt->rt_rmx.rmx_ssthresh) {
+ /*
+ * There's some sort of gateway or interface
+ * buffer limit on the path. Use this to set
+ * the slow start threshhold, but set the
+ * threshold to no less than 2*mss.
+ */
+ tp->snd_ssthresh = max(2 * mss, rt->rt_rmx.rmx_ssthresh);
+ tcpstat.tcps_usedssthresh++;
+ }
+}
+
+/*
+ * Determine the MSS option to send on an outgoing SYN.
+ */
+int
+tcp_mssopt(tp)
+ struct tcpcb *tp;
+{
+ struct rtentry *rt;
+
+ rt = tcp_rtlookup(tp->t_inpcb);
+ if (rt == NULL)
+ return tcp_mssdflt;
+
+ return rt->rt_ifp->if_mtu - sizeof(struct tcpiphdr);
+}
+#endif /* TUBA_INCLUDE */
diff --git a/cpukit/libnetworking/netinet/tcp_output.c b/cpukit/libnetworking/netinet/tcp_output.c
new file mode 100644
index 0000000000..cbb5218dce
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp_output.c
@@ -0,0 +1,755 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ * 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.
+ *
+ * @(#)tcp_output.c 8.4 (Berkeley) 5/24/95
+ * $Id$
+ */
+
+#include "opt_tcpdebug.h"
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#define TCPOUTFLAGS
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#ifdef TCPDEBUG
+#include <netinet/tcp_debug.h>
+#endif
+
+#ifdef notyet
+extern struct mbuf *m_copypack();
+#endif
+
+
+/*
+ * Tcp output routine: figure out what should be sent and send it.
+ */
+int
+tcp_output(tp)
+ register struct tcpcb *tp;
+{
+ register struct socket *so = tp->t_inpcb->inp_socket;
+ register long len, win;
+ int off, flags, error;
+ register struct mbuf *m;
+ register struct tcpiphdr *ti;
+ u_char opt[TCP_MAXOLEN];
+ unsigned optlen, hdrlen;
+ int idle, sendalot;
+ struct rmxp_tao *taop;
+ struct rmxp_tao tao_noncached;
+
+ /*
+ * Determine length of data that should be transmitted,
+ * and flags that will be used.
+ * If there is some data or critical controls (SYN, RST)
+ * to send, then transmit; otherwise, investigate further.
+ */
+ idle = (tp->snd_max == tp->snd_una);
+ if (idle && tp->t_idle >= tp->t_rxtcur)
+ /*
+ * We have been idle for "a while" and no acks are
+ * expected to clock out any data we send --
+ * slow start to get ack "clock" running again.
+ */
+ tp->snd_cwnd = tp->t_maxseg;
+again:
+ sendalot = 0;
+ off = tp->snd_nxt - tp->snd_una;
+ win = min(tp->snd_wnd, tp->snd_cwnd);
+
+ flags = tcp_outflags[tp->t_state];
+ /*
+ * Get standard flags, and add SYN or FIN if requested by 'hidden'
+ * state flags.
+ */
+ if (tp->t_flags & TF_NEEDFIN)
+ flags |= TH_FIN;
+ if (tp->t_flags & TF_NEEDSYN)
+ flags |= TH_SYN;
+
+ /*
+ * If in persist timeout with window of 0, send 1 byte.
+ * Otherwise, if window is small but nonzero
+ * and timer expired, we will send what we can
+ * and go to transmit state.
+ */
+ if (tp->t_force) {
+ if (win == 0) {
+ /*
+ * If we still have some data to send, then
+ * clear the FIN bit. Usually this would
+ * happen below when it realizes that we
+ * aren't sending all the data. However,
+ * if we have exactly 1 byte of unset data,
+ * then it won't clear the FIN bit below,
+ * and if we are in persist state, we wind
+ * up sending the packet without recording
+ * that we sent the FIN bit.
+ *
+ * We can't just blindly clear the FIN bit,
+ * because if we don't have any more data
+ * to send then the probe will be the FIN
+ * itself.
+ */
+ if (off < so->so_snd.sb_cc)
+ flags &= ~TH_FIN;
+ win = 1;
+ } else {
+ tp->t_timer[TCPT_PERSIST] = 0;
+ tp->t_rxtshift = 0;
+ }
+ }
+
+ len = min(so->so_snd.sb_cc, win) - off;
+
+ if ((taop = tcp_gettaocache(tp->t_inpcb)) == NULL) {
+ taop = &tao_noncached;
+ bzero(taop, sizeof(*taop));
+ }
+
+ /*
+ * Lop off SYN bit if it has already been sent. However, if this
+ * is SYN-SENT state and if segment contains data and if we don't
+ * know that foreign host supports TAO, suppress sending segment.
+ */
+ if ((flags & TH_SYN) && SEQ_GT(tp->snd_nxt, tp->snd_una)) {
+ flags &= ~TH_SYN;
+ off--, len++;
+ if (len > 0 && tp->t_state == TCPS_SYN_SENT &&
+ taop->tao_ccsent == 0)
+ return 0;
+ }
+
+ /*
+ * Be careful not to send data and/or FIN on SYN segments
+ * in cases when no CC option will be sent.
+ * This measure is needed to prevent interoperability problems
+ * with not fully conformant TCP implementations.
+ */
+ if ((flags & TH_SYN) &&
+ ((tp->t_flags & TF_NOOPT) || !(tp->t_flags & TF_REQ_CC) ||
+ ((flags & TH_ACK) && !(tp->t_flags & TF_RCVD_CC)))) {
+ len = 0;
+ flags &= ~TH_FIN;
+ }
+
+ if (len < 0) {
+ /*
+ * If FIN has been sent but not acked,
+ * but we haven't been called to retransmit,
+ * len will be -1. Otherwise, window shrank
+ * after we sent into it. If window shrank to 0,
+ * cancel pending retransmit, pull snd_nxt back
+ * to (closed) window, and set the persist timer
+ * if it isn't already going. If the window didn't
+ * close completely, just wait for an ACK.
+ */
+ len = 0;
+ if (win == 0) {
+ tp->t_timer[TCPT_REXMT] = 0;
+ tp->t_rxtshift = 0;
+ tp->snd_nxt = tp->snd_una;
+ if (tp->t_timer[TCPT_PERSIST] == 0)
+ tcp_setpersist(tp);
+ }
+ }
+ if (len > tp->t_maxseg) {
+ len = tp->t_maxseg;
+ sendalot = 1;
+ }
+ if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
+ flags &= ~TH_FIN;
+
+ win = sbspace(&so->so_rcv);
+
+ /*
+ * Sender silly window avoidance. If connection is idle
+ * and can send all data, a maximum segment,
+ * at least a maximum default-size segment do it,
+ * or are forced, do it; otherwise don't bother.
+ * If peer's buffer is tiny, then send
+ * when window is at least half open.
+ * If retransmitting (possibly after persist timer forced us
+ * to send into a small window), then must resend.
+ */
+ if (len) {
+ if (len == tp->t_maxseg)
+ goto send;
+ if ((idle || tp->t_flags & TF_NODELAY) &&
+ (tp->t_flags & TF_NOPUSH) == 0 &&
+ len + off >= so->so_snd.sb_cc)
+ goto send;
+ if (tp->t_force)
+ goto send;
+ if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0)
+ goto send;
+ if (SEQ_LT(tp->snd_nxt, tp->snd_max))
+ goto send;
+ }
+
+ /*
+ * Compare available window to amount of window
+ * known to peer (as advertised window less
+ * next expected input). If the difference is at least two
+ * max size segments, or at least 50% of the maximum possible
+ * window, then want to send a window update to peer.
+ */
+ if (win > 0) {
+ /*
+ * "adv" is the amount we can increase the window,
+ * taking into account that we are limited by
+ * TCP_MAXWIN << tp->rcv_scale.
+ */
+ long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) -
+ (tp->rcv_adv - tp->rcv_nxt);
+
+ if (adv >= (long) (2 * tp->t_maxseg))
+ goto send;
+ if (2 * adv >= (long) so->so_rcv.sb_hiwat)
+ goto send;
+ }
+
+ /*
+ * Send if we owe peer an ACK.
+ */
+ if (tp->t_flags & TF_ACKNOW)
+ goto send;
+ if ((flags & TH_RST) ||
+ ((flags & TH_SYN) && (tp->t_flags & TF_NEEDSYN) == 0))
+ goto send;
+ if (SEQ_GT(tp->snd_up, tp->snd_una))
+ goto send;
+ /*
+ * If our state indicates that FIN should be sent
+ * and we have not yet done so, or we're retransmitting the FIN,
+ * then we need to send.
+ */
+ if (flags & TH_FIN &&
+ ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))
+ goto send;
+
+ /*
+ * TCP window updates are not reliable, rather a polling protocol
+ * using ``persist'' packets is used to insure receipt of window
+ * updates. The three ``states'' for the output side are:
+ * idle not doing retransmits or persists
+ * persisting to move a small or zero window
+ * (re)transmitting and thereby not persisting
+ *
+ * tp->t_timer[TCPT_PERSIST]
+ * is set when we are in persist state.
+ * tp->t_force
+ * is set when we are called to send a persist packet.
+ * tp->t_timer[TCPT_REXMT]
+ * is set when we are retransmitting
+ * The output side is idle when both timers are zero.
+ *
+ * If send window is too small, there is data to transmit, and no
+ * retransmit or persist is pending, then go to persist state.
+ * If nothing happens soon, send when timer expires:
+ * if window is nonzero, transmit what we can,
+ * otherwise force out a byte.
+ */
+ if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 &&
+ tp->t_timer[TCPT_PERSIST] == 0) {
+ tp->t_rxtshift = 0;
+ tcp_setpersist(tp);
+ }
+
+ /*
+ * No reason to send a segment, just return.
+ */
+ return (0);
+
+send:
+ /*
+ * Before ESTABLISHED, force sending of initial options
+ * unless TCP set not to do any options.
+ * NOTE: we assume that the IP/TCP header plus TCP options
+ * always fit in a single mbuf, leaving room for a maximum
+ * link header, i.e.
+ * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN
+ */
+ optlen = 0;
+ hdrlen = sizeof (struct tcpiphdr);
+ if (flags & TH_SYN) {
+ tp->snd_nxt = tp->iss;
+ if ((tp->t_flags & TF_NOOPT) == 0) {
+ u_short mss;
+
+ opt[0] = TCPOPT_MAXSEG;
+ opt[1] = TCPOLEN_MAXSEG;
+ mss = htons((u_short) tcp_mssopt(tp));
+ (void)memcpy(opt + 2, &mss, sizeof(mss));
+ optlen = TCPOLEN_MAXSEG;
+
+ if ((tp->t_flags & TF_REQ_SCALE) &&
+ ((flags & TH_ACK) == 0 ||
+ (tp->t_flags & TF_RCVD_SCALE))) {
+ *((u_long *) (opt + optlen)) = htonl(
+ TCPOPT_NOP << 24 |
+ TCPOPT_WINDOW << 16 |
+ TCPOLEN_WINDOW << 8 |
+ tp->request_r_scale);
+ optlen += 4;
+ }
+ }
+ }
+
+ /*
+ * Send a timestamp and echo-reply if this is a SYN and our side
+ * wants to use timestamps (TF_REQ_TSTMP is set) or both our side
+ * and our peer have sent timestamps in our SYN's.
+ */
+ if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
+ (flags & TH_RST) == 0 &&
+ ((flags & TH_ACK) == 0 ||
+ (tp->t_flags & TF_RCVD_TSTMP))) {
+ u_long *lp = (u_long *)(opt + optlen);
+
+ /* Form timestamp option as shown in appendix A of RFC 1323. */
+ *lp++ = htonl(TCPOPT_TSTAMP_HDR);
+ *lp++ = htonl(tcp_now);
+ *lp = htonl(tp->ts_recent);
+ optlen += TCPOLEN_TSTAMP_APPA;
+ }
+
+ /*
+ * Send `CC-family' options if our side wants to use them (TF_REQ_CC),
+ * options are allowed (!TF_NOOPT) and it's not a RST.
+ */
+ if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
+ (flags & TH_RST) == 0) {
+ switch (flags & (TH_SYN|TH_ACK)) {
+ /*
+ * This is a normal ACK, send CC if we received CC before
+ * from our peer.
+ */
+ case TH_ACK:
+ if (!(tp->t_flags & TF_RCVD_CC))
+ break;
+ /*FALLTHROUGH*/
+
+ /*
+ * We can only get here in T/TCP's SYN_SENT* state, when
+ * we're a sending a non-SYN segment without waiting for
+ * the ACK of our SYN. A check above assures that we only
+ * do this if our peer understands T/TCP.
+ */
+ case 0:
+ opt[optlen++] = TCPOPT_NOP;
+ opt[optlen++] = TCPOPT_NOP;
+ opt[optlen++] = TCPOPT_CC;
+ opt[optlen++] = TCPOLEN_CC;
+ *(u_int32_t *)&opt[optlen] = htonl(tp->cc_send);
+
+ optlen += 4;
+ break;
+
+ /*
+ * This is our initial SYN, check whether we have to use
+ * CC or CC.new.
+ */
+ case TH_SYN:
+ opt[optlen++] = TCPOPT_NOP;
+ opt[optlen++] = TCPOPT_NOP;
+ opt[optlen++] = tp->t_flags & TF_SENDCCNEW ?
+ TCPOPT_CCNEW : TCPOPT_CC;
+ opt[optlen++] = TCPOLEN_CC;
+ *(u_int32_t *)&opt[optlen] = htonl(tp->cc_send);
+ optlen += 4;
+ break;
+
+ /*
+ * This is a SYN,ACK; send CC and CC.echo if we received
+ * CC from our peer.
+ */
+ case (TH_SYN|TH_ACK):
+ if (tp->t_flags & TF_RCVD_CC) {
+ opt[optlen++] = TCPOPT_NOP;
+ opt[optlen++] = TCPOPT_NOP;
+ opt[optlen++] = TCPOPT_CC;
+ opt[optlen++] = TCPOLEN_CC;
+ *(u_int32_t *)&opt[optlen] =
+ htonl(tp->cc_send);
+ optlen += 4;
+ opt[optlen++] = TCPOPT_NOP;
+ opt[optlen++] = TCPOPT_NOP;
+ opt[optlen++] = TCPOPT_CCECHO;
+ opt[optlen++] = TCPOLEN_CC;
+ *(u_int32_t *)&opt[optlen] =
+ htonl(tp->cc_recv);
+ optlen += 4;
+ }
+ break;
+ }
+ }
+
+ hdrlen += optlen;
+
+ /*
+ * Adjust data length if insertion of options will
+ * bump the packet length beyond the t_maxopd length.
+ * Clear the FIN bit because we cut off the tail of
+ * the segment.
+ */
+ if (len + optlen > tp->t_maxopd) {
+ /*
+ * If there is still more to send, don't close the connection.
+ */
+ flags &= ~TH_FIN;
+ len = tp->t_maxopd - optlen;
+ sendalot = 1;
+ }
+
+/*#ifdef DIAGNOSTIC*/
+ if (max_linkhdr + hdrlen > MHLEN)
+ panic("tcphdr too big");
+/*#endif*/
+
+ /*
+ * Grab a header mbuf, attaching a copy of data to
+ * be transmitted, and initialize the header from
+ * the template for sends on this connection.
+ */
+ if (len) {
+ if (tp->t_force && len == 1)
+ tcpstat.tcps_sndprobe++;
+ else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
+ tcpstat.tcps_sndrexmitpack++;
+ tcpstat.tcps_sndrexmitbyte += len;
+ } else {
+ tcpstat.tcps_sndpack++;
+ tcpstat.tcps_sndbyte += len;
+ }
+#ifdef notyet
+ if ((m = m_copypack(so->so_snd.sb_mb, off,
+ (int)len, max_linkhdr + hdrlen)) == 0) {
+ error = ENOBUFS;
+ goto out;
+ }
+ /*
+ * m_copypack left space for our hdr; use it.
+ */
+ m->m_len += hdrlen;
+ m->m_data -= hdrlen;
+#else
+ MGETHDR(m, M_DONTWAIT, MT_HEADER);
+ if (m == NULL) {
+ error = ENOBUFS;
+ goto out;
+ }
+ m->m_data += max_linkhdr;
+ m->m_len = hdrlen;
+ if (len <= MHLEN - hdrlen - max_linkhdr) {
+ m_copydata(so->so_snd.sb_mb, off, (int) len,
+ mtod(m, caddr_t) + hdrlen);
+ m->m_len += len;
+ } else {
+ m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len);
+ if (m->m_next == 0) {
+ (void) m_free(m);
+ error = ENOBUFS;
+ goto out;
+ }
+ }
+#endif
+ /*
+ * If we're sending everything we've got, set PUSH.
+ * (This will keep happy those implementations which only
+ * give data to the user when a buffer fills or
+ * a PUSH comes in.)
+ */
+ if (off + len == so->so_snd.sb_cc)
+ flags |= TH_PUSH;
+ } else {
+ if (tp->t_flags & TF_ACKNOW)
+ tcpstat.tcps_sndacks++;
+ else if (flags & (TH_SYN|TH_FIN|TH_RST))
+ tcpstat.tcps_sndctrl++;
+ else if (SEQ_GT(tp->snd_up, tp->snd_una))
+ tcpstat.tcps_sndurg++;
+ else
+ tcpstat.tcps_sndwinup++;
+
+ MGETHDR(m, M_DONTWAIT, MT_HEADER);
+ if (m == NULL) {
+ error = ENOBUFS;
+ goto out;
+ }
+ m->m_data += max_linkhdr;
+ m->m_len = hdrlen;
+ }
+ m->m_pkthdr.rcvif = (struct ifnet *)0;
+ ti = mtod(m, struct tcpiphdr *);
+ if (tp->t_template == 0)
+ panic("tcp_output");
+ (void)memcpy(ti, tp->t_template, sizeof (struct tcpiphdr));
+
+ /*
+ * Fill in fields, remembering maximum advertised
+ * window for use in delaying messages about window sizes.
+ * If resending a FIN, be sure not to use a new sequence number.
+ */
+ if (flags & TH_FIN && tp->t_flags & TF_SENTFIN &&
+ tp->snd_nxt == tp->snd_max)
+ tp->snd_nxt--;
+ /*
+ * If we are doing retransmissions, then snd_nxt will
+ * not reflect the first unsent octet. For ACK only
+ * packets, we do not want the sequence number of the
+ * retransmitted packet, we want the sequence number
+ * of the next unsent octet. So, if there is no data
+ * (and no SYN or FIN), use snd_max instead of snd_nxt
+ * when filling in ti_seq. But if we are in persist
+ * state, snd_max might reflect one byte beyond the
+ * right edge of the window, so use snd_nxt in that
+ * case, since we know we aren't doing a retransmission.
+ * (retransmit and persist are mutually exclusive...)
+ */
+ if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST])
+ ti->ti_seq = htonl(tp->snd_nxt);
+ else
+ ti->ti_seq = htonl(tp->snd_max);
+ ti->ti_ack = htonl(tp->rcv_nxt);
+ if (optlen) {
+ bcopy(opt, ti + 1, optlen);
+ ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2;
+ }
+ ti->ti_flags = flags;
+ /*
+ * Calculate receive window. Don't shrink window,
+ * but avoid silly window syndrome.
+ */
+ if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)tp->t_maxseg)
+ win = 0;
+ if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
+ win = (long)(tp->rcv_adv - tp->rcv_nxt);
+ if (win > (long)TCP_MAXWIN << tp->rcv_scale)
+ win = (long)TCP_MAXWIN << tp->rcv_scale;
+ ti->ti_win = htons((u_short) (win>>tp->rcv_scale));
+ if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
+ ti->ti_urp = htons((u_short)(tp->snd_up - tp->snd_nxt));
+ ti->ti_flags |= TH_URG;
+ } else
+ /*
+ * If no urgent pointer to send, then we pull
+ * the urgent pointer to the left edge of the send window
+ * so that it doesn't drift into the send window on sequence
+ * number wraparound.
+ */
+ tp->snd_up = tp->snd_una; /* drag it along */
+
+ /*
+ * Put TCP length in extended header, and then
+ * checksum extended header and data.
+ */
+ if (len + optlen)
+ ti->ti_len = htons((u_short)(sizeof (struct tcphdr) +
+ optlen + len));
+ ti->ti_sum = in_cksum(m, (int)(hdrlen + len));
+
+ /*
+ * In transmit state, time the transmission and arrange for
+ * the retransmit. In persist state, just set snd_max.
+ */
+ if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) {
+ tcp_seq startseq = tp->snd_nxt;
+
+ /*
+ * Advance snd_nxt over sequence space of this segment.
+ */
+ if (flags & (TH_SYN|TH_FIN)) {
+ if (flags & TH_SYN)
+ tp->snd_nxt++;
+ if (flags & TH_FIN) {
+ tp->snd_nxt++;
+ tp->t_flags |= TF_SENTFIN;
+ }
+ }
+ tp->snd_nxt += len;
+ if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
+ tp->snd_max = tp->snd_nxt;
+ /*
+ * Time this transmission if not a retransmission and
+ * not currently timing anything.
+ */
+ if (tp->t_rtt == 0) {
+ tp->t_rtt = 1;
+ tp->t_rtseq = startseq;
+ tcpstat.tcps_segstimed++;
+ }
+ }
+
+ /*
+ * Set retransmit timer if not currently set,
+ * and not doing an ack or a keep-alive probe.
+ * Initial value for retransmit timer is smoothed
+ * round-trip time + 2 * round-trip time variance.
+ * Initialize shift counter which is used for backoff
+ * of retransmit time.
+ */
+ if (tp->t_timer[TCPT_REXMT] == 0 &&
+ tp->snd_nxt != tp->snd_una) {
+ tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
+ if (tp->t_timer[TCPT_PERSIST]) {
+ tp->t_timer[TCPT_PERSIST] = 0;
+ tp->t_rxtshift = 0;
+ }
+ }
+ } else
+ if (SEQ_GT(tp->snd_nxt + len, tp->snd_max))
+ tp->snd_max = tp->snd_nxt + len;
+
+#ifdef TCPDEBUG
+ /*
+ * Trace.
+ */
+ if (so->so_options & SO_DEBUG)
+ tcp_trace(TA_OUTPUT, tp->t_state, tp, ti, 0);
+#endif
+
+ /*
+ * Fill in IP length and desired time to live and
+ * send to IP level. There should be a better way
+ * to handle ttl and tos; we could keep them in
+ * the template, but need a way to checksum without them.
+ */
+ m->m_pkthdr.len = hdrlen + len;
+#ifdef TUBA
+ if (tp->t_tuba_pcb)
+ error = tuba_output(m, tp);
+ else
+#endif
+ {
+#if 1
+ struct rtentry *rt;
+#endif
+ ((struct ip *)ti)->ip_len = m->m_pkthdr.len;
+ ((struct ip *)ti)->ip_ttl = tp->t_inpcb->inp_ip_ttl; /* XXX */
+ ((struct ip *)ti)->ip_tos = tp->t_inpcb->inp_ip_tos; /* XXX */
+#if 1
+ /*
+ * See if we should do MTU discovery. We do it only if the following
+ * are true:
+ * 1) we have a valid route to the destination
+ * 2) the MTU is not locked (if it is, then discovery has been
+ * disabled)
+ */
+ if ((rt = tp->t_inpcb->inp_route.ro_rt)
+ && rt->rt_flags & RTF_UP
+ && !(rt->rt_rmx.rmx_locks & RTV_MTU)) {
+ ((struct ip *)ti)->ip_off |= IP_DF;
+ }
+#endif
+ error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
+ so->so_options & SO_DONTROUTE, 0);
+ }
+ if (error) {
+out:
+ if (error == ENOBUFS) {
+ tcp_quench(tp->t_inpcb, 0);
+ return (0);
+ }
+#if 1
+ if (error == EMSGSIZE) {
+ /*
+ * ip_output() will have already fixed the route
+ * for us. tcp_mtudisc() will, as its last action,
+ * initiate retransmission, so it is important to
+ * not do so here.
+ */
+ tcp_mtudisc(tp->t_inpcb, 0);
+ return 0;
+ }
+#endif
+ if ((error == EHOSTUNREACH || error == ENETDOWN)
+ && TCPS_HAVERCVDSYN(tp->t_state)) {
+ tp->t_softerror = error;
+ return (0);
+ }
+ return (error);
+ }
+ tcpstat.tcps_sndtotal++;
+
+ /*
+ * Data sent (as far as we can tell).
+ * If this advertises a larger window than any other segment,
+ * then remember the size of the advertised window.
+ * Any pending ACK has now been sent.
+ */
+ if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv))
+ tp->rcv_adv = tp->rcv_nxt + win;
+ tp->last_ack_sent = tp->rcv_nxt;
+ tp->t_flags &= ~(TF_ACKNOW|TF_DELACK);
+ if (sendalot)
+ goto again;
+ return (0);
+}
+
+void
+tcp_setpersist(tp)
+ register struct tcpcb *tp;
+{
+ register int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
+
+ if (tp->t_timer[TCPT_REXMT])
+ panic("tcp_output REXMT");
+ /*
+ * Start/restart persistance timer.
+ */
+ TCPT_RANGESET(tp->t_timer[TCPT_PERSIST],
+ t * tcp_backoff[tp->t_rxtshift],
+ TCPTV_PERSMIN, TCPTV_PERSMAX);
+ if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
+ tp->t_rxtshift++;
+}
diff --git a/cpukit/libnetworking/netinet/tcp_seq.h b/cpukit/libnetworking/netinet/tcp_seq.h
new file mode 100644
index 0000000000..ffc64c50af
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp_seq.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1982, 1986, 1993, 1995
+ * 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.
+ *
+ * @(#)tcp_seq.h 8.3 (Berkeley) 6/21/95
+ * $Id$
+ */
+
+#ifndef _NETINET_TCP_SEQ_H_
+#define _NETINET_TCP_SEQ_H_
+/*
+ * TCP sequence numbers are 32 bit integers operated
+ * on with modular arithmetic. These macros can be
+ * used to compare such integers.
+ */
+#define SEQ_LT(a,b) ((int)((a)-(b)) < 0)
+#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
+#define SEQ_GT(a,b) ((int)((a)-(b)) > 0)
+#define SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0)
+
+/* for modulo comparisons of timestamps */
+#define TSTMP_LT(a,b) ((int)((a)-(b)) < 0)
+#define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0)
+
+/*
+ * TCP connection counts are 32 bit integers operated
+ * on with modular arithmetic. These macros can be
+ * used to compare such integers.
+ */
+#define CC_LT(a,b) ((int)((a)-(b)) < 0)
+#define CC_LEQ(a,b) ((int)((a)-(b)) <= 0)
+#define CC_GT(a,b) ((int)((a)-(b)) > 0)
+#define CC_GEQ(a,b) ((int)((a)-(b)) >= 0)
+
+/* Macro to increment a CC: skip 0 which has a special meaning */
+#define CC_INC(c) (++(c) == 0 ? ++(c) : (c))
+
+/*
+ * Macros to initialize tcp sequence numbers for
+ * send and receive from initial send and receive
+ * sequence numbers.
+ */
+#define tcp_rcvseqinit(tp) \
+ (tp)->rcv_adv = (tp)->rcv_nxt = (tp)->irs + 1
+
+#define tcp_sendseqinit(tp) \
+ (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = \
+ (tp)->iss
+
+#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ)
+ /* timestamp wrap-around time */
+
+#ifdef _KERNEL
+extern tcp_cc tcp_ccgen; /* global connection count */
+
+/*
+ * Increment for tcp_iss each second.
+ * This is designed to increment at the standard 250 KB/s,
+ * but with a random component averaging 128 KB.
+ * We also increment tcp_iss by a quarter of this amount
+ * each time we use the value for a new connection.
+ * If defined, the tcp_random18() macro should produce a
+ * number in the range [0-0x3ffff] that is hard to predict.
+ */
+#ifndef tcp_random18
+#define tcp_random18() ((random() >> 14) & 0x3ffff)
+#endif
+#define TCP_ISSINCR (122*1024 + tcp_random18())
+
+extern tcp_seq tcp_iss; /* tcp initial send seq # */
+#else
+#define TCP_ISSINCR (250*1024) /* increment for tcp_iss each second */
+#endif /* _KERNEL */
+#endif /* _NETINET_TCP_SEQ_H_ */
diff --git a/cpukit/libnetworking/netinet/tcp_subr.c b/cpukit/libnetworking/netinet/tcp_subr.c
new file mode 100644
index 0000000000..fd9b160fdf
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp_subr.c
@@ -0,0 +1,740 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ * 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.
+ * 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.
+ *
+ * @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95
+ * $FreeBSD: src/sys/netinet/tcp_subr.c,v 1.226 2005/05/07 00:41:36 cperciva Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#include "opt_tcpdebug.h"
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+
+#include <net/route.h>
+#include <net/if.h>
+
+#define _IP_VHL
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#ifdef TCPDEBUG
+#include <netinet/tcp_debug.h>
+#endif
+
+int tcp_mssdflt = TCP_MSS;
+SYSCTL_INT(_net_inet_tcp, TCPCTL_MSSDFLT, mssdflt, CTLFLAG_RW,
+ &tcp_mssdflt , 0, "Default TCP Maximum Segment Size");
+
+static int tcp_do_rfc1323 = 1;
+#if !defined(__rtems__)
+static int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
+SYSCTL_INT(_net_inet_tcp, TCPCTL_RTTDFLT, rttdflt,
+ CTLFLAG_RW, &tcp_rttdflt , 0, "");
+
+SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1323, rfc1323,
+ CTLFLAG_RW, &tcp_do_rfc1323 , 0, "");
+#endif
+
+static void tcp_notify __P((struct inpcb *, int));
+
+/*
+ * Target size of TCP PCB hash table. Will be rounded down to a prime
+ * number.
+ */
+#ifndef TCBHASHSIZE
+#define TCBHASHSIZE 128
+#endif
+
+/*
+ * Tcp initialization
+ */
+void
+tcp_init()
+{
+
+ tcp_iss = random(); /* wrong, but better than a constant */
+ tcp_ccgen = 1;
+ LIST_INIT(&tcb);
+ tcbinfo.listhead = &tcb;
+ tcbinfo.hashbase = hashinit(TCBHASHSIZE, M_PCB, &tcbinfo.hashmask);
+ if (max_protohdr < sizeof(struct tcpiphdr))
+ max_protohdr = sizeof(struct tcpiphdr);
+ if (max_linkhdr + sizeof(struct tcpiphdr) > MHLEN)
+ panic("tcp_init");
+}
+
+/*
+ * Create template to be used to send tcp packets on a connection.
+ * Call after host entry created, allocates an mbuf and fills
+ * in a skeletal tcp/ip header, minimizing the amount of work
+ * necessary when the connection is used.
+ */
+struct tcpiphdr *
+tcp_template(tp)
+ struct tcpcb *tp;
+{
+ register struct inpcb *inp = tp->t_inpcb;
+ register struct mbuf *m;
+ register struct tcpiphdr *n;
+
+ if ((n = tp->t_template) == 0) {
+ m = m_get(M_DONTWAIT, MT_HEADER);
+ if (m == NULL)
+ return (0);
+ m->m_len = sizeof (struct tcpiphdr);
+ n = mtod(m, struct tcpiphdr *);
+ }
+ n->ti_next = n->ti_prev = 0;
+ n->ti_x1 = 0;
+ n->ti_pr = IPPROTO_TCP;
+ n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
+ n->ti_src = inp->inp_laddr;
+ n->ti_dst = inp->inp_faddr;
+ n->ti_sport = inp->inp_lport;
+ n->ti_dport = inp->inp_fport;
+ n->ti_seq = 0;
+ n->ti_ack = 0;
+ n->ti_x2 = 0;
+ n->ti_off = 5;
+ n->ti_flags = 0;
+ n->ti_win = 0;
+ n->ti_sum = 0;
+ n->ti_urp = 0;
+ return (n);
+}
+
+/*
+ * Send a single message to the TCP at address specified by
+ * the given TCP/IP header. If m == 0, then we make a copy
+ * of the tcpiphdr at ti and send directly to the addressed host.
+ * This is used to force keep alive messages out using the TCP
+ * template for a connection tp->t_template. If flags are given
+ * then we send a message back to the TCP which originated the
+ * segment ti, and discard the mbuf containing it and any other
+ * attached mbufs.
+ *
+ * In any case the ack and sequence number of the transmitted
+ * segment are as specified by the parameters.
+ *
+ * NOTE: If m != NULL, then ti must point to *inside* the mbuf.
+ */
+void
+tcp_respond(tp, ti, m, ack, seq, flags)
+ struct tcpcb *tp;
+ register struct tcpiphdr *ti;
+ register struct mbuf *m;
+ tcp_seq ack, seq;
+ int flags;
+{
+ register int tlen;
+ int win = 0;
+ struct route *ro = 0;
+ struct route sro;
+
+ if (tp) {
+ win = sbspace(&tp->t_inpcb->inp_socket->so_rcv);
+ ro = &tp->t_inpcb->inp_route;
+ } else {
+ ro = &sro;
+ bzero(ro, sizeof *ro);
+ }
+ if (m == NULL) {
+ m = m_gethdr(M_DONTWAIT, MT_HEADER);
+ if (m == NULL)
+ return;
+#ifdef TCP_COMPAT_42
+ tlen = 1;
+#else
+ tlen = 0;
+#endif
+ m->m_data += max_linkhdr;
+ *mtod(m, struct tcpiphdr *) = *ti;
+ ti = mtod(m, struct tcpiphdr *);
+ flags = TH_ACK;
+ } else {
+ m_freem(m->m_next);
+ m->m_next = NULL;
+ m->m_data = (caddr_t)ti;
+ m->m_len = sizeof (struct tcpiphdr);
+ tlen = 0;
+#define xchg(a,b,type) { type t; t=a; a=b; b=t; }
+ xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_long);
+ xchg(ti->ti_dport, ti->ti_sport, u_short);
+#undef xchg
+ }
+ ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
+ tlen += sizeof (struct tcpiphdr);
+ m->m_len = tlen;
+ m->m_pkthdr.len = tlen;
+ m->m_pkthdr.rcvif = (struct ifnet *) 0;
+ ti->ti_next = ti->ti_prev = 0;
+ ti->ti_x1 = 0;
+ ti->ti_seq = htonl(seq);
+ ti->ti_ack = htonl(ack);
+ ti->ti_x2 = 0;
+ ti->ti_off = sizeof (struct tcphdr) >> 2;
+ ti->ti_flags = flags;
+ if (tp)
+ ti->ti_win = htons((u_short) (win >> tp->rcv_scale));
+ else
+ ti->ti_win = htons((u_short)win);
+ ti->ti_urp = 0;
+ ti->ti_sum = 0;
+ ti->ti_sum = in_cksum(m, tlen);
+ ((struct ip *)ti)->ip_len = tlen;
+ ((struct ip *)ti)->ip_ttl = ip_defttl;
+#ifdef TCPDEBUG
+ if (tp == NULL || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
+ tcp_trace(TA_OUTPUT, 0, tp, ti, 0);
+#endif
+ (void) ip_output(m, NULL, ro, 0, NULL);
+ if (ro == &sro && ro->ro_rt) {
+ RTFREE(ro->ro_rt);
+ }
+}
+
+/*
+ * Create a new TCP control block, making an
+ * empty reassembly queue and hooking it to the argument
+ * protocol control block.
+ */
+struct tcpcb *
+tcp_newtcpcb(inp)
+ struct inpcb *inp;
+{
+ struct tcpcb *tp;
+
+ tp = malloc(sizeof(*tp), M_PCB, M_NOWAIT);
+ if (tp == NULL)
+ return ((struct tcpcb *)0);
+ bzero((char *) tp, sizeof(struct tcpcb));
+ tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp;
+ tp->t_maxseg = tp->t_maxopd = tcp_mssdflt;
+
+ if (tcp_do_rfc1323)
+ tp->t_flags = (TF_REQ_SCALE|TF_REQ_TSTMP);
+ tp->t_inpcb = inp;
+ /*
+ * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no
+ * rtt estimate. Set rttvar so that srtt + 4 * rttvar gives
+ * reasonable initial retransmit time.
+ */
+ tp->t_srtt = TCPTV_SRTTBASE;
+ tp->t_rttvar = ((TCPTV_RTOBASE - TCPTV_SRTTBASE) << TCP_RTTVAR_SHIFT) / 4;
+ tp->t_rttmin = TCPTV_MIN;
+ tp->t_rxtcur = TCPTV_RTOBASE;
+ tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
+ tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
+ inp->inp_ip_ttl = ip_defttl;
+ inp->inp_ppcb = (caddr_t)tp;
+ return (tp);
+}
+
+/*
+ * Drop a TCP connection, reporting
+ * the specified error. If connection is synchronized,
+ * then send a RST to peer.
+ */
+struct tcpcb *
+tcp_drop(tp, errnum)
+ register struct tcpcb *tp;
+ int errnum;
+{
+ struct socket *so = tp->t_inpcb->inp_socket;
+
+ if (TCPS_HAVERCVDSYN(tp->t_state)) {
+ tp->t_state = TCPS_CLOSED;
+ (void) tcp_output(tp);
+ tcpstat.tcps_drops++;
+ } else
+ tcpstat.tcps_conndrops++;
+ if (errnum == ETIMEDOUT && tp->t_softerror)
+ errnum = tp->t_softerror;
+ so->so_error = errnum;
+ return (tcp_close(tp));
+}
+
+/*
+ * Close a TCP control block:
+ * discard all space held by the tcp
+ * discard internet protocol block
+ * wake up any sleepers
+ */
+struct tcpcb *
+tcp_close(tp)
+ struct tcpcb *tp;
+{
+ register struct tcpiphdr *t;
+ struct inpcb *inp = tp->t_inpcb;
+ struct socket *so = inp->inp_socket;
+ register struct mbuf *m;
+ register struct rtentry *rt;
+
+ /*
+ * If we got enough samples through the srtt filter,
+ * save the rtt and rttvar in the routing entry.
+ * 'Enough' is arbitrarily defined as the 16 samples.
+ * 16 samples is enough for the srtt filter to converge
+ * to within 5% of the correct value; fewer samples and
+ * we could save a very bogus rtt.
+ *
+ * Don't update the default route's characteristics and don't
+ * update anything that the user "locked".
+ */
+ if (tp->t_rttupdated >= 16 &&
+ (rt = inp->inp_route.ro_rt) &&
+ ((struct sockaddr_in *)rt_key(rt))->sin_addr.s_addr != INADDR_ANY) {
+ register u_long i = 0;
+
+ if ((rt->rt_rmx.rmx_locks & RTV_RTT) == 0) {
+ i = tp->t_srtt *
+ (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTT_SCALE));
+ if (rt->rt_rmx.rmx_rtt && i)
+ /*
+ * filter this update to half the old & half
+ * the new values, converting scale.
+ * See route.h and tcp_var.h for a
+ * description of the scaling constants.
+ */
+ rt->rt_rmx.rmx_rtt =
+ (rt->rt_rmx.rmx_rtt + i) / 2;
+ else
+ rt->rt_rmx.rmx_rtt = i;
+ tcpstat.tcps_cachedrtt++;
+ }
+ if ((rt->rt_rmx.rmx_locks & RTV_RTTVAR) == 0) {
+ i = tp->t_rttvar *
+ (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTTVAR_SCALE));
+ if (rt->rt_rmx.rmx_rttvar && i)
+ rt->rt_rmx.rmx_rttvar =
+ (rt->rt_rmx.rmx_rttvar + i) / 2;
+ else
+ rt->rt_rmx.rmx_rttvar = i;
+ tcpstat.tcps_cachedrttvar++;
+ }
+ /*
+ * update the pipelimit (ssthresh) if it has been updated
+ * already or if a pipesize was specified & the threshhold
+ * got below half the pipesize. I.e., wait for bad news
+ * before we start updating, then update on both good
+ * and bad news.
+ */
+ if (((rt->rt_rmx.rmx_locks & RTV_SSTHRESH) == 0 &&
+ ((i = tp->snd_ssthresh) != 0) && rt->rt_rmx.rmx_ssthresh) ||
+ i < (rt->rt_rmx.rmx_sendpipe / 2)) {
+ /*
+ * convert the limit from user data bytes to
+ * packets then to packet data bytes.
+ */
+ i = (i + tp->t_maxseg / 2) / tp->t_maxseg;
+ if (i < 2)
+ i = 2;
+ i *= (u_long)(tp->t_maxseg + sizeof (struct tcpiphdr));
+ if (rt->rt_rmx.rmx_ssthresh)
+ rt->rt_rmx.rmx_ssthresh =
+ (rt->rt_rmx.rmx_ssthresh + i) / 2;
+ else
+ rt->rt_rmx.rmx_ssthresh = i;
+ tcpstat.tcps_cachedssthresh++;
+ }
+ }
+ /* free the reassembly queue, if any */
+ t = tp->seg_next;
+ while (t != (struct tcpiphdr *)tp) {
+ t = (struct tcpiphdr *)t->ti_next;
+#if (defined(__GNUC__) && (defined(__arm__) || defined(__mips__)))
+ LD32_UNALGN((struct tcpiphdr *)t->ti_prev,m);
+#else
+ m = REASS_MBUF((struct tcpiphdr *)t->ti_prev);
+#endif
+ remque(t->ti_prev);
+ m_freem(m);
+ }
+ if (tp->t_template)
+ (void) m_free(dtom(tp->t_template));
+ free(tp, M_PCB);
+ inp->inp_ppcb = 0;
+ soisdisconnected(so);
+ in_pcbdetach(inp);
+ tcpstat.tcps_closed++;
+ return ((struct tcpcb *)0);
+}
+
+void
+tcp_drain()
+{
+
+}
+
+/*
+ * Notify a tcp user of an asynchronous error;
+ * store error as soft error, but wake up user
+ * (for now, won't do anything until can select for soft error).
+ */
+static void
+tcp_notify(inp, error)
+ struct inpcb *inp;
+ int error;
+{
+ struct tcpcb *tp = (struct tcpcb *)inp->inp_ppcb;
+ struct socket *so = inp->inp_socket;
+
+ /*
+ * Ignore some errors if we are hooked up.
+ * If connection hasn't completed, has retransmitted several times,
+ * and receives a second error, give up now. This is better
+ * than waiting a long time to establish a connection that
+ * can never complete.
+ */
+ if (tp->t_state == TCPS_ESTABLISHED &&
+ (error == EHOSTUNREACH || error == ENETUNREACH ||
+ error == EHOSTDOWN)) {
+ return;
+ } else if (tp->t_state < TCPS_ESTABLISHED && tp->t_rxtshift > 3 &&
+ tp->t_softerror)
+ so->so_error = error;
+ else
+ tp->t_softerror = error;
+ soconnwakeup (so);
+ sorwakeup(so);
+ sowwakeup(so);
+}
+
+#ifdef __rtems__
+#define INP_INFO_RLOCK(a)
+#define INP_INFO_RUNLOCK(a)
+#define INP_LOCK(a)
+#define INP_UNLOCK(a)
+#endif
+
+static int
+tcp_pcblist(SYSCTL_HANDLER_ARGS)
+{
+ int error, i, n, s;
+ struct inpcb *inp, **inp_list;
+ inp_gen_t gencnt;
+ struct xinpgen xig;
+
+ /*
+ * The process of preparing the TCB list is too time-consuming and
+ * resource-intensive to repeat twice on every request.
+ */
+ if (req->oldptr == NULL) {
+ n = tcbinfo.ipi_count;
+ req->oldidx = 2 * (sizeof xig)
+ + (n + n/8) * sizeof(struct xtcpcb);
+ return (0);
+ }
+
+ if (req->newptr != NULL)
+ return (EPERM);
+
+ /*
+ * OK, now we're committed to doing something.
+ */
+ s = splnet();
+ INP_INFO_RLOCK(&tcbinfo);
+ gencnt = tcbinfo.ipi_gencnt;
+ n = tcbinfo.ipi_count;
+ INP_INFO_RUNLOCK(&tcbinfo);
+ splx(s);
+
+ sysctl_wire_old_buffer(req, 2 * (sizeof xig)
+ + n * sizeof(struct xtcpcb));
+
+ xig.xig_len = sizeof xig;
+ xig.xig_count = n;
+ xig.xig_gen = gencnt;
+/* xig.xig_sogen = so_gencnt; remove by ccj */
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ if (error)
+ return error;
+
+ /* ccj add exit if the count is 0 */
+ if (!n)
+ return error;
+
+ inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
+ if (inp_list == 0)
+ return ENOMEM;
+
+ s = splnet();
+ INP_INFO_RLOCK(&tcbinfo);
+ for (inp = LIST_FIRST(tcbinfo.listhead), i = 0; inp && i < n;
+ inp = LIST_NEXT(inp, inp_list)) {
+ INP_LOCK(inp);
+ if (inp->inp_gencnt <= gencnt)
+#if 0
+ &&
+ cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0)
+#endif
+ inp_list[i++] = inp;
+ INP_UNLOCK(inp);
+ }
+ INP_INFO_RUNLOCK(&tcbinfo);
+ splx(s);
+ n = i;
+
+ error = 0;
+ for (i = 0; i < n; i++) {
+ inp = inp_list[i];
+ INP_LOCK(inp);
+ if (inp->inp_gencnt <= gencnt) {
+ struct xtcpcb xt;
+ caddr_t inp_ppcb;
+ xt.xt_len = sizeof xt;
+ /* XXX should avoid extra copy */
+ bcopy(inp, &xt.xt_inp, sizeof *inp);
+ inp_ppcb = inp->inp_ppcb;
+ if (inp_ppcb != NULL)
+ bcopy(inp_ppcb, &xt.xt_tp, sizeof xt.xt_tp);
+ else
+ bzero((char *) &xt.xt_tp, sizeof xt.xt_tp);
+#if 0
+ if (inp->inp_socket)
+ sotoxsocket(inp->inp_socket, &xt.xt_socket);
+#endif
+ error = SYSCTL_OUT(req, &xt, sizeof xt);
+ }
+ INP_UNLOCK(inp);
+ }
+ if (!error) {
+ /*
+ * Give the user an updated idea of our state.
+ * If the generation differs from what we told
+ * her before, she knows that something happened
+ * while we were processing this request, and it
+ * might be necessary to retry.
+ */
+ s = splnet();
+ INP_INFO_RLOCK(&tcbinfo);
+ xig.xig_gen = tcbinfo.ipi_gencnt;
+#if 0
+ xig.xig_sogen = so_gencnt;
+#endif
+ xig.xig_count = tcbinfo.ipi_count;
+ INP_INFO_RUNLOCK(&tcbinfo);
+ splx(s);
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ }
+ free(inp_list, M_TEMP);
+ return error;
+}
+
+SYSCTL_PROC(_net_inet_tcp, TCPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0,
+ tcp_pcblist, "S,xtcpcb", "List of active TCP connections");
+
+void
+tcp_ctlinput(cmd, sa, vip)
+ int cmd;
+ struct sockaddr *sa;
+ void *vip;
+{
+ struct ip *ip = vip;
+ struct tcphdr *th;
+ void (*notify) __P((struct inpcb *, int)) = tcp_notify;
+
+ if (cmd == PRC_QUENCH)
+ notify = tcp_quench;
+#if 1
+ else if (cmd == PRC_MSGSIZE)
+ notify = tcp_mtudisc;
+#endif
+ else if (!PRC_IS_REDIRECT(cmd) &&
+ ((unsigned)cmd > PRC_NCMDS || inetctlerrmap[cmd] == 0))
+ return;
+ if (ip) {
+ th = (struct tcphdr *)((caddr_t)ip
+ + (IP_VHL_HL(ip->ip_vhl) << 2));
+ in_pcbnotify(&tcb, sa, th->th_dport, ip->ip_src, th->th_sport,
+ cmd, notify);
+ } else
+ in_pcbnotify(&tcb, sa, 0, zeroin_addr, 0, cmd, notify);
+}
+
+/*
+ * When a source quench is received, close congestion window
+ * to one segment. We will gradually open it again as we proceed.
+ */
+void
+tcp_quench(inp, errnum)
+ struct inpcb *inp;
+ int errnum;
+{
+ struct tcpcb *tp = intotcpcb(inp);
+
+ if (tp)
+ tp->snd_cwnd = tp->t_maxseg;
+}
+
+/*
+ * When `need fragmentation' ICMP is received, update our idea of the MSS
+ * based on the new value in the route. Also nudge TCP to send something,
+ * since we know the packet we just sent was dropped.
+ * This duplicates some code in the tcp_mss() function in tcp_input.c.
+ */
+void
+tcp_mtudisc(inp, errnum)
+ struct inpcb *inp;
+ int errnum;
+{
+ struct tcpcb *tp = intotcpcb(inp);
+ struct rtentry *rt;
+ struct rmxp_tao *taop;
+ struct socket *so = inp->inp_socket;
+ int offered;
+ int mss;
+
+ if (tp) {
+ rt = tcp_rtlookup(inp);
+ if (!rt || !rt->rt_rmx.rmx_mtu) {
+ tp->t_maxopd = tp->t_maxseg = tcp_mssdflt;
+ return;
+ }
+ taop = rmx_taop(rt->rt_rmx);
+ offered = taop->tao_mssopt;
+ mss = rt->rt_rmx.rmx_mtu - sizeof(struct tcpiphdr);
+ if (offered)
+ mss = min(mss, offered);
+ /*
+ * XXX - The above conditional probably violates the TCP
+ * spec. The problem is that, since we don't know the
+ * other end's MSS, we are supposed to use a conservative
+ * default. But, if we do that, then MTU discovery will
+ * never actually take place, because the conservative
+ * default is much less than the MTUs typically seen
+ * on the Internet today. For the moment, we'll sweep
+ * this under the carpet.
+ *
+ * The conservative default might not actually be a problem
+ * if the only case this occurs is when sending an initial
+ * SYN with options and data to a host we've never talked
+ * to before. Then, they will reply with an MSS value which
+ * will get recorded and the new parameters should get
+ * recomputed. For Further Study.
+ */
+ if (tp->t_maxopd <= mss)
+ return;
+ tp->t_maxopd = mss;
+
+ if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
+ (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)
+ mss -= TCPOLEN_TSTAMP_APPA;
+ if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
+ (tp->t_flags & TF_RCVD_CC) == TF_RCVD_CC)
+ mss -= TCPOLEN_CC_APPA;
+#if (MCLBYTES & (MCLBYTES - 1)) == 0
+ if (mss > MCLBYTES)
+ mss &= ~(MCLBYTES-1);
+#else
+ if (mss > MCLBYTES)
+ mss = mss / MCLBYTES * MCLBYTES;
+#endif
+ if (so->so_snd.sb_hiwat < mss)
+ mss = so->so_snd.sb_hiwat;
+
+ tp->t_maxseg = mss;
+
+ tcpstat.tcps_mturesent++;
+ tp->t_rtt = 0;
+ tp->snd_nxt = tp->snd_una;
+ tcp_output(tp);
+ }
+}
+
+/*
+ * Look-up the routing entry to the peer of this inpcb. If no route
+ * is found and it cannot be allocated, then return NULL. This routine
+ * is called by TCP routines that access the rmx structure and by tcp_mss
+ * to get the interface MTU.
+ */
+struct rtentry *
+tcp_rtlookup(inp)
+ struct inpcb *inp;
+{
+ struct route *ro;
+ struct rtentry *rt;
+
+ ro = &inp->inp_route;
+ rt = ro->ro_rt;
+ if (rt == NULL || !(rt->rt_flags & RTF_UP)) {
+ /* No route yet, so try to acquire one */
+ if (inp->inp_faddr.s_addr != INADDR_ANY) {
+ ro->ro_dst.sa_family = AF_INET;
+ ro->ro_dst.sa_len = sizeof(ro->ro_dst);
+ ((struct sockaddr_in *) &ro->ro_dst)->sin_addr =
+ inp->inp_faddr;
+ rtalloc(ro);
+ rt = ro->ro_rt;
+ }
+ }
+ return rt;
+}
+
+/*
+ * Return a pointer to the cached information about the remote host.
+ * The cached information is stored in the protocol specific part of
+ * the route metrics.
+ */
+struct rmxp_tao *
+tcp_gettaocache(inp)
+ struct inpcb *inp;
+{
+ struct rtentry *rt = tcp_rtlookup(inp);
+
+ /* Make sure this is a host route and is up. */
+ if (rt == NULL ||
+ (rt->rt_flags & (RTF_UP|RTF_HOST)) != (RTF_UP|RTF_HOST))
+ return NULL;
+
+ return rmx_taop(rt->rt_rmx);
+}
diff --git a/cpukit/libnetworking/netinet/tcp_timer.c b/cpukit/libnetworking/netinet/tcp_timer.c
new file mode 100644
index 0000000000..04d3d604e2
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp_timer.c
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ * 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.
+ *
+ * @(#)tcp_timer.c 8.2 (Berkeley) 5/24/95
+ * $Id$
+ */
+
+#include "opt_tcpdebug.h"
+
+#ifndef TUBA_INCLUDE
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+
+#include <machine/cpu.h> /* before tcp_seq.h, for tcp_random18() */
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#ifdef TCPDEBUG
+#include <netinet/tcp_debug.h>
+#endif
+
+int tcp_keepinit = TCPTV_KEEP_INIT;
+SYSCTL_INT(_net_inet_tcp, TCPCTL_KEEPINIT, keepinit,
+ CTLFLAG_RW, &tcp_keepinit , 0, "");
+
+int tcp_keepidle = TCPTV_KEEP_IDLE;
+SYSCTL_INT(_net_inet_tcp, TCPCTL_KEEPIDLE, keepidle,
+ CTLFLAG_RW, &tcp_keepidle , 0, "");
+
+static int tcp_keepintvl = TCPTV_KEEPINTVL;
+SYSCTL_INT(_net_inet_tcp, TCPCTL_KEEPINTVL, keepintvl,
+ CTLFLAG_RW, &tcp_keepintvl , 0, "");
+
+static int always_keepalive = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, always_keepalive,
+ CTLFLAG_RW, &always_keepalive , 0, "");
+
+static int tcp_keepcnt = TCPTV_KEEPCNT;
+ /* max idle probes */
+static int tcp_maxpersistidle = TCPTV_KEEP_IDLE;
+ /* max idle time in persist */
+int tcp_maxidle;
+#else /* TUBA_INCLUDE */
+
+static int tcp_maxpersistidle;
+#endif /* TUBA_INCLUDE */
+
+/*
+ * Fast timeout routine for processing delayed acks
+ */
+void
+tcp_fasttimo()
+{
+ register struct inpcb *inp;
+ register struct tcpcb *tp;
+ int s;
+
+ s = splnet();
+
+ for (inp = tcb.lh_first; inp != NULL; inp = inp->inp_list.le_next) {
+ if ((tp = (struct tcpcb *)inp->inp_ppcb) &&
+ (tp->t_flags & TF_DELACK)) {
+ tp->t_flags &= ~TF_DELACK;
+ tp->t_flags |= TF_ACKNOW;
+ tcpstat.tcps_delack++;
+ (void) tcp_output(tp);
+ }
+ }
+ splx(s);
+}
+
+/*
+ * Tcp protocol timeout routine called every 500 ms.
+ * Updates the timers in all active tcb's and
+ * causes finite state machine actions if timers expire.
+ */
+void
+tcp_slowtimo()
+{
+ register struct inpcb *ip, *ipnxt;
+ register struct tcpcb *tp;
+ register int i;
+ int s;
+#ifdef TCPDEBUG
+ int ostate;
+#endif
+
+ s = splnet();
+
+ tcp_maxidle = tcp_keepcnt * tcp_keepintvl;
+
+ ip = tcb.lh_first;
+ if (ip == NULL) {
+ splx(s);
+ return;
+ }
+ /*
+ * Search through tcb's and update active timers.
+ */
+ for (; ip != NULL; ip = ipnxt) {
+ ipnxt = ip->inp_list.le_next;
+ tp = intotcpcb(ip);
+ if (tp == 0 || tp->t_state == TCPS_LISTEN)
+ continue;
+ for (i = 0; i < TCPT_NTIMERS; i++) {
+ if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
+#ifdef TCPDEBUG
+ ostate = tp->t_state;
+#endif
+ tp = tcp_timers(tp, i);
+ if (tp == NULL)
+ goto tpgone;
+#ifdef TCPDEBUG
+ if (tp->t_inpcb->inp_socket->so_options
+ & SO_DEBUG)
+ tcp_trace(TA_USER, ostate, tp,
+ (struct tcpiphdr *)0,
+ PRU_SLOWTIMO);
+#endif
+ }
+ }
+ tp->t_idle++;
+ tp->t_duration++;
+ if (tp->t_rtt)
+ tp->t_rtt++;
+tpgone:
+ ;
+ }
+ tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */
+#ifdef TCP_COMPAT_42
+ if ((int)tcp_iss < 0)
+ tcp_iss = TCP_ISSINCR; /* XXX */
+#endif
+ tcp_now++; /* for timestamps */
+ splx(s);
+}
+#ifndef TUBA_INCLUDE
+
+/*
+ * Cancel all timers for TCP tp.
+ */
+void
+tcp_canceltimers(tp)
+ struct tcpcb *tp;
+{
+ register int i;
+
+ for (i = 0; i < TCPT_NTIMERS; i++)
+ tp->t_timer[i] = 0;
+}
+
+int tcp_backoff[TCP_MAXRXTSHIFT + 1] =
+ { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
+
+static int tcp_totbackoff = 511; /* sum of tcp_backoff[] */
+
+/*
+ * TCP timer processing.
+ */
+struct tcpcb *
+tcp_timers(tp, timer)
+ register struct tcpcb *tp;
+ int timer;
+{
+ register int rexmt;
+
+ switch (timer) {
+
+ /*
+ * 2 MSL timeout in shutdown went off. If we're closed but
+ * still waiting for peer to close and connection has been idle
+ * too long, or if 2MSL time is up from TIME_WAIT, delete connection
+ * control block. Otherwise, check again in a bit.
+ */
+ case TCPT_2MSL:
+ if (tp->t_state != TCPS_TIME_WAIT &&
+ tp->t_idle <= tcp_maxidle)
+ tp->t_timer[TCPT_2MSL] = tcp_keepintvl;
+ else
+ tp = tcp_close(tp);
+ break;
+
+ /*
+ * Retransmission timer went off. Message has not
+ * been acked within retransmit interval. Back off
+ * to a longer retransmit interval and retransmit one segment.
+ */
+ case TCPT_REXMT:
+ if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
+ tp->t_rxtshift = TCP_MAXRXTSHIFT;
+ tcpstat.tcps_timeoutdrop++;
+ tp = tcp_drop(tp, tp->t_softerror ?
+ tp->t_softerror : ETIMEDOUT);
+ break;
+ }
+ tcpstat.tcps_rexmttimeo++;
+ rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
+ TCPT_RANGESET(tp->t_rxtcur, rexmt,
+ tp->t_rttmin, TCPTV_REXMTMAX);
+ tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
+ /*
+ * If losing, let the lower level know and try for
+ * a better route. Also, if we backed off this far,
+ * our srtt estimate is probably bogus. Clobber it
+ * so we'll take the next rtt measurement as our srtt;
+ * move the current srtt into rttvar to keep the current
+ * retransmit times until then.
+ */
+ if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) {
+ in_losing(tp->t_inpcb);
+ tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT);
+ tp->t_srtt = 0;
+ }
+ tp->snd_nxt = tp->snd_una;
+ /*
+ * Force a segment to be sent.
+ */
+ tp->t_flags |= TF_ACKNOW;
+ /*
+ * If timing a segment in this window, stop the timer.
+ */
+ tp->t_rtt = 0;
+ /*
+ * Close the congestion window down to one segment
+ * (we'll open it by one segment for each ack we get).
+ * Since we probably have a window's worth of unacked
+ * data accumulated, this "slow start" keeps us from
+ * dumping all that data as back-to-back packets (which
+ * might overwhelm an intermediate gateway).
+ *
+ * There are two phases to the opening: Initially we
+ * open by one mss on each ack. This makes the window
+ * size increase exponentially with time. If the
+ * window is larger than the path can handle, this
+ * exponential growth results in dropped packet(s)
+ * almost immediately. To get more time between
+ * drops but still "push" the network to take advantage
+ * of improving conditions, we switch from exponential
+ * to linear window opening at some threshhold size.
+ * For a threshhold, we use half the current window
+ * size, truncated to a multiple of the mss.
+ *
+ * (the minimum cwnd that will give us exponential
+ * growth is 2 mss. We don't allow the threshhold
+ * to go below this.)
+ */
+ {
+ u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;
+ if (win < 2)
+ win = 2;
+ tp->snd_cwnd = tp->t_maxseg;
+ tp->snd_ssthresh = win * tp->t_maxseg;
+ tp->t_dupacks = 0;
+ }
+ (void) tcp_output(tp);
+ break;
+
+ /*
+ * Persistance timer into zero window.
+ * Force a byte to be output, if possible.
+ */
+ case TCPT_PERSIST:
+ tcpstat.tcps_persisttimeo++;
+ /*
+ * Hack: if the peer is dead/unreachable, we do not
+ * time out if the window is closed. After a full
+ * backoff, drop the connection if the idle time
+ * (no responses to probes) reaches the maximum
+ * backoff that we would use if retransmitting.
+ */
+ if (tp->t_rxtshift == TCP_MAXRXTSHIFT) {
+ u_long maxidle = TCP_REXMTVAL(tp);
+ if (maxidle < tp->t_rttmin)
+ maxidle = tp->t_rttmin;
+ maxidle *= tcp_totbackoff;
+ if (tp->t_idle >= tcp_maxpersistidle ||
+ tp->t_idle >= maxidle) {
+ tcpstat.tcps_persistdrop++;
+ tp = tcp_drop(tp, ETIMEDOUT);
+ break;
+ }
+ }
+ tcp_setpersist(tp);
+ tp->t_force = 1;
+ (void) tcp_output(tp);
+ tp->t_force = 0;
+ break;
+
+ /*
+ * Keep-alive timer went off; send something
+ * or drop connection if idle for too long.
+ */
+ case TCPT_KEEP:
+ tcpstat.tcps_keeptimeo++;
+ if (tp->t_state < TCPS_ESTABLISHED)
+ goto dropit;
+ if ((always_keepalive ||
+ tp->t_inpcb->inp_socket->so_options & SO_KEEPALIVE) &&
+ tp->t_state <= TCPS_CLOSING) {
+ if (tp->t_idle >= tcp_keepidle + tcp_maxidle)
+ goto dropit;
+ /*
+ * Send a packet designed to force a response
+ * if the peer is up and reachable:
+ * either an ACK if the connection is still alive,
+ * or an RST if the peer has closed the connection
+ * due to timeout or reboot.
+ * Using sequence number tp->snd_una-1
+ * causes the transmitted zero-length segment
+ * to lie outside the receive window;
+ * by the protocol spec, this requires the
+ * correspondent TCP to respond.
+ */
+ tcpstat.tcps_keepprobe++;
+#ifdef TCP_COMPAT_42
+ /*
+ * The keepalive packet must have nonzero length
+ * to get a 4.2 host to respond.
+ */
+ tcp_respond(tp, tp->t_template, (struct mbuf *)NULL,
+ tp->rcv_nxt - 1, tp->snd_una - 1, 0);
+#else
+ tcp_respond(tp, tp->t_template, (struct mbuf *)NULL,
+ tp->rcv_nxt, tp->snd_una - 1, 0);
+#endif
+ tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
+ } else
+ tp->t_timer[TCPT_KEEP] = tcp_keepidle;
+ break;
+ dropit:
+ tcpstat.tcps_keepdrops++;
+ tp = tcp_drop(tp, ETIMEDOUT);
+ break;
+ }
+ return (tp);
+}
+#endif /* TUBA_INCLUDE */
diff --git a/cpukit/libnetworking/netinet/tcp_timer.h b/cpukit/libnetworking/netinet/tcp_timer.h
new file mode 100644
index 0000000000..4bbbb712b6
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp_timer.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ * 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.
+ *
+ * @(#)tcp_timer.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/tcp_timer.h,v 1.26 2004/08/16 18:32:07 rwatson Exp $
+ */
+
+#ifndef _NETINET_TCP_TIMER_H_
+#define _NETINET_TCP_TIMER_H_
+
+/*
+ * Definitions of the TCP timers. These timers are counted
+ * down PR_SLOWHZ times a second.
+ */
+#define TCPT_NTIMERS 4
+
+#define TCPT_REXMT 0 /* retransmit */
+#define TCPT_PERSIST 1 /* retransmit persistence */
+#define TCPT_KEEP 2 /* keep alive */
+#define TCPT_2MSL 3 /* 2*msl quiet time timer */
+
+/*
+ * The TCPT_REXMT timer is used to force retransmissions.
+ * The TCP has the TCPT_REXMT timer set whenever segments
+ * have been sent for which ACKs are expected but not yet
+ * received. If an ACK is received which advances tp->snd_una,
+ * then the retransmit timer is cleared (if there are no more
+ * outstanding segments) or reset to the base value (if there
+ * are more ACKs expected). Whenever the retransmit timer goes off,
+ * we retransmit one unacknowledged segment, and do a backoff
+ * on the retransmit timer.
+ *
+ * The TCPT_PERSIST timer is used to keep window size information
+ * flowing even if the window goes shut. If all previous transmissions
+ * have been acknowledged (so that there are no retransmissions in progress),
+ * and the window is too small to bother sending anything, then we start
+ * the TCPT_PERSIST timer. When it expires, if the window is nonzero,
+ * we go to transmit state. Otherwise, at intervals send a single byte
+ * into the peer's window to force him to update our window information.
+ * We do this at most as often as TCPT_PERSMIN time intervals,
+ * but no more frequently than the current estimate of round-trip
+ * packet time. The TCPT_PERSIST timer is cleared whenever we receive
+ * a window update from the peer.
+ *
+ * The TCPT_KEEP timer is used to keep connections alive. If an
+ * connection is idle (no segments received) for TCPTV_KEEP_INIT amount of time,
+ * but not yet established, then we drop the connection. Once the connection
+ * is established, if the connection is idle for TCPTV_KEEP_IDLE time
+ * (and keepalives have been enabled on the socket), we begin to probe
+ * the connection. We force the peer to send us a segment by sending:
+ * <SEQ=SND.UNA-1><ACK=RCV.NXT><CTL=ACK>
+ * This segment is (deliberately) outside the window, and should elicit
+ * an ack segment in response from the peer. If, despite the TCPT_KEEP
+ * initiated segments we cannot elicit a response from a peer in TCPT_MAXIDLE
+ * amount of time probing, then we drop the connection.
+ */
+
+/*
+ * Time constants.
+ */
+#define TCPTV_MSL ( 30*PR_SLOWHZ) /* max seg lifetime (hah!) */
+#define TCPTV_SRTTBASE 0 /* base roundtrip time;
+ if 0, no idea yet */
+#define TCPTV_RTOBASE ( 3*PR_SLOWHZ) /* assumed RTO if no info */
+#define TCPTV_SRTTDFLT ( 3*PR_SLOWHZ) /* assumed RTT if no info */
+
+#define TCPTV_PERSMIN ( 5*PR_SLOWHZ) /* retransmit persistence */
+#define TCPTV_PERSMAX ( 60*PR_SLOWHZ) /* maximum persist interval */
+
+#define TCPTV_KEEP_INIT ( 75*PR_SLOWHZ) /* initial connect keep alive */
+#define TCPTV_KEEP_IDLE (120*60*PR_SLOWHZ) /* dflt time before probing */
+#define TCPTV_KEEPINTVL ( 75*PR_SLOWHZ) /* default probe interval */
+#define TCPTV_KEEPCNT 8 /* max probes before drop */
+
+#define TCPTV_MIN ( 1*PR_SLOWHZ) /* minimum allowable value */
+#define TCPTV_REXMTMAX ( 64*PR_SLOWHZ) /* max allowable REXMT value */
+
+#define TCPTV_TWTRUNC 8 /* RTO factor to truncate TW */
+
+#define TCP_LINGERTIME 120 /* linger at most 2 minutes */
+
+#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */
+
+#ifdef TCPTIMERS
+static char *tcptimers[] =
+ { "REXMT", "PERSIST", "KEEP", "2MSL" };
+#endif
+
+/*
+ * Force a time value to be in a certain range.
+ */
+#define TCPT_RANGESET(tv, value, tvmin, tvmax) { \
+ (tv) = (value); \
+ if ((u_long)(tv) < (u_long)(tvmin)) \
+ (tv) = (tvmin); \
+ else if ((u_long)(tv) > (u_long)(tvmax)) \
+ (tv) = (tvmax); \
+}
+
+#ifdef _KERNEL
+extern int tcp_keepinit; /* time to establish connection */
+extern int tcp_keepidle; /* time before keepalive probes begin */
+extern int tcp_maxidle; /* time to drop after starting probes */
+extern int tcp_ttl; /* time to live for TCP segs */
+extern int tcp_backoff[];
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/netinet/tcp_usrreq.c b/cpukit/libnetworking/netinet/tcp_usrreq.c
new file mode 100644
index 0000000000..e1f615562d
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp_usrreq.c
@@ -0,0 +1,839 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 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.
+ * 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.
+ *
+ * From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94
+ * $FreeBSD: src/sys/netinet/tcp_usrreq.c,v 1.120 2005/05/01 14:01:38 rwatson Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#include "opt_tcpdebug.h"
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+#include <sys/stat.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+#ifdef TCPDEBUG
+#include <netinet/tcp_debug.h>
+#endif
+
+/*
+ * TCP protocol interface to socket abstraction.
+ */
+extern char *tcpstates[];
+
+static int tcp_attach(struct socket *);
+static int tcp_connect __P((struct tcpcb *, struct mbuf *));
+static struct tcpcb *
+ tcp_disconnect(struct tcpcb *);
+static struct tcpcb *
+ tcp_usrclosed __P((struct tcpcb *));
+
+#ifdef TCPDEBUG
+#define TCPDEBUG0 int ostate
+#define TCPDEBUG1() ostate = tp ? tp->t_state : 0
+#define TCPDEBUG2(req) if (tp && (so->so_options & SO_DEBUG)) \
+ tcp_trace(TA_USER, ostate, tp, 0, req)
+#else
+#define TCPDEBUG0
+#define TCPDEBUG1()
+#define TCPDEBUG2(req)
+#endif
+
+/*
+ * TCP attaches to socket via pru_attach(), reserving space,
+ * and an internet control block.
+ */
+static int
+tcp_usr_attach(struct socket *so, int proto)
+{
+ int s = splnet();
+ int error;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = 0;
+ TCPDEBUG0;
+
+ TCPDEBUG1();
+ if (inp) {
+ error = EISCONN;
+ goto out;
+ }
+
+ error = tcp_attach(so);
+ if (error)
+ goto out;
+
+ if ((so->so_options & SO_LINGER) && so->so_linger == 0)
+ so->so_linger = TCP_LINGERTIME * hz;
+ tp = sototcpcb(so);
+out:
+ TCPDEBUG2(PRU_ATTACH);
+ splx(s);
+ return error;
+}
+
+/*
+ * pru_detach() detaches the TCP protocol from the socket.
+ * If the protocol state is non-embryonic, then can't
+ * do this directly: have to initiate a pru_disconnect(),
+ * which may finish later; embryonic TCB's can just
+ * be discarded here.
+ */
+static int
+tcp_usr_detach(struct socket *so)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+ TCPDEBUG0;
+
+ if (inp == 0) {
+ splx(s);
+ return EINVAL; /* XXX */
+ }
+ tp = intotcpcb(inp);
+ TCPDEBUG1();
+ if (tp->t_state > TCPS_LISTEN)
+ tp = tcp_disconnect(tp);
+ else
+ tp = tcp_close(tp);
+
+ TCPDEBUG2(PRU_DETACH);
+ splx(s);
+ return error;
+}
+
+#define COMMON_START() TCPDEBUG0; \
+ do { \
+ if (inp == 0) { \
+ splx(s); \
+ return EINVAL; \
+ } \
+ tp = intotcpcb(inp); \
+ TCPDEBUG1(); \
+ } while(0)
+
+#define COMMON_END(req) out: TCPDEBUG2(req); splx(s); return error; goto out
+
+
+/*
+ * Give the socket an address.
+ */
+static int
+tcp_usr_bind(struct socket *so, struct mbuf *nam)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+ struct sockaddr_in *sinp;
+
+ COMMON_START();
+
+ /*
+ * Must check for multicast addresses and disallow binding
+ * to them.
+ */
+ sinp = mtod(nam, struct sockaddr_in *);
+ if (sinp->sin_family == AF_INET &&
+ IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
+ error = EAFNOSUPPORT;
+ goto out;
+ }
+ error = in_pcbbind(inp, nam);
+ if (error)
+ goto out;
+ COMMON_END(PRU_BIND);
+
+}
+
+/*
+ * Prepare to accept connections.
+ */
+static int
+tcp_usr_listen(struct socket *so)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+
+ COMMON_START();
+ if (inp->inp_lport == 0)
+ error = in_pcbbind(inp, NULL);
+ if (error == 0)
+ tp->t_state = TCPS_LISTEN;
+ COMMON_END(PRU_LISTEN);
+}
+
+/*
+ * Initiate connection to peer.
+ * Create a template for use in transmissions on this connection.
+ * Enter SYN_SENT state, and mark socket as connecting.
+ * Start keep-alive timer, and seed output sequence space.
+ * Send initial segment on connection.
+ */
+static int
+tcp_usr_connect(struct socket *so, struct mbuf *nam)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+ struct sockaddr_in *sinp;
+
+ COMMON_START();
+
+ /*
+ * Must disallow TCP ``connections'' to multicast addresses.
+ */
+ sinp = mtod(nam, struct sockaddr_in *);
+ if (sinp->sin_family == AF_INET
+ && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
+ error = EAFNOSUPPORT;
+ goto out;
+ }
+
+ if ((error = tcp_connect(tp, nam)) != 0)
+ goto out;
+ error = tcp_output(tp);
+ COMMON_END(PRU_CONNECT);
+}
+
+/*
+ * Initiate disconnect from peer.
+ * If connection never passed embryonic stage, just drop;
+ * else if don't need to let data drain, then can just drop anyways,
+ * else have to begin TCP shutdown process: mark socket disconnecting,
+ * drain unread data, state switch to reflect user close, and
+ * send segment (e.g. FIN) to peer. Socket will be really disconnected
+ * when peer sends FIN and acks ours.
+ *
+ * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
+ */
+static int
+tcp_usr_disconnect(struct socket *so)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+
+ COMMON_START();
+ tp = tcp_disconnect(tp);
+ COMMON_END(PRU_DISCONNECT);
+}
+
+/*
+ * Accept a connection. Essentially all the work is
+ * done at higher levels; just return the address
+ * of the peer, storing through addr.
+ */
+static int
+tcp_usr_accept(struct socket *so, struct mbuf *nam)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+
+ COMMON_START();
+ in_setpeeraddr(inp, nam);
+ COMMON_END(PRU_ACCEPT);
+}
+
+/*
+ * Mark the connection as being incapable of further output.
+ */
+static int
+tcp_usr_shutdown(struct socket *so)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+
+ COMMON_START();
+ socantsendmore(so);
+ tp = tcp_usrclosed(tp);
+ if (tp)
+ error = tcp_output(tp);
+ COMMON_END(PRU_SHUTDOWN);
+}
+
+/*
+ * After a receive, possibly send window update to peer.
+ */
+static int
+tcp_usr_rcvd(struct socket *so, int flags)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+
+ COMMON_START();
+ tcp_output(tp);
+ COMMON_END(PRU_RCVD);
+}
+
+/*
+ * Do a send by putting data in output queue and updating urgent
+ * marker if URG set. Possibly send more data.
+ */
+static int
+tcp_usr_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+
+ COMMON_START();
+ if (control && control->m_len) {
+ m_freem(control); /* XXX shouldn't caller do this??? */
+ if (m)
+ m_freem(m);
+ error = EINVAL;
+ goto out;
+ }
+
+ if(!(flags & PRUS_OOB)) {
+ sbappend(&so->so_snd, m);
+ if (nam && tp->t_state < TCPS_SYN_SENT) {
+ /*
+ * Do implied connect if not yet connected,
+ * initialize window to default value, and
+ * initialize maxseg/maxopd using peer's cached
+ * MSS.
+ */
+ error = tcp_connect(tp, nam);
+ if (error)
+ goto out;
+ tp->snd_wnd = TTCP_CLIENT_SND_WND;
+ tcp_mss(tp, -1);
+ }
+
+ if (flags & PRUS_EOF) {
+ /*
+ * Close the send side of the connection after
+ * the data is sent.
+ */
+ socantsendmore(so);
+ tp = tcp_usrclosed(tp);
+ }
+ if (tp != NULL)
+ error = tcp_output(tp);
+ } else {
+ if (sbspace(&so->so_snd) < -512) {
+ m_freem(m);
+ error = ENOBUFS;
+ goto out;
+ }
+ /*
+ * According to RFC961 (Assigned Protocols),
+ * the urgent pointer points to the last octet
+ * of urgent data. We continue, however,
+ * to consider it to indicate the first octet
+ * of data past the urgent section.
+ * Otherwise, snd_up should be one lower.
+ */
+ sbappend(&so->so_snd, m);
+ if (nam && tp->t_state < TCPS_SYN_SENT) {
+ /*
+ * Do implied connect if not yet connected,
+ * initialize window to default value, and
+ * initialize maxseg/maxopd using peer's cached
+ * MSS.
+ */
+ error = tcp_connect(tp, nam);
+ if (error)
+ goto out;
+ tp->snd_wnd = TTCP_CLIENT_SND_WND;
+ tcp_mss(tp, -1);
+ }
+ tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
+ tp->t_force = 1;
+ error = tcp_output(tp);
+ tp->t_force = 0;
+ }
+ COMMON_END((flags & PRUS_OOB) ? PRU_SENDOOB :
+ ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND));
+}
+
+/*
+ * Abort the TCP.
+ */
+static int
+tcp_usr_abort(struct socket *so)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+
+ COMMON_START();
+ tp = tcp_drop(tp, ECONNABORTED);
+ COMMON_END(PRU_ABORT);
+}
+
+/*
+ * Fill in st_bklsize for fstat() operations on a socket.
+ */
+static int
+tcp_usr_sense(struct socket *so, struct stat *sb)
+{
+ int s = splnet();
+
+ sb->st_blksize = so->so_snd.sb_hiwat;
+ splx(s);
+ return 0;
+}
+
+/*
+ * Receive out-of-band data.
+ */
+static int
+tcp_usr_rcvoob(struct socket *so, struct mbuf *m, int flags)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+
+ COMMON_START();
+ if ((so->so_oobmark == 0 &&
+ (so->so_state & SS_RCVATMARK) == 0) ||
+ so->so_options & SO_OOBINLINE ||
+ tp->t_oobflags & TCPOOB_HADDATA) {
+ error = EINVAL;
+ goto out;
+ }
+ if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
+ error = EWOULDBLOCK;
+ goto out;
+ }
+ m->m_len = 1;
+ *mtod(m, caddr_t) = tp->t_iobc;
+ if ((flags & MSG_PEEK) == 0)
+ tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA);
+ COMMON_END(PRU_RCVOOB);
+}
+
+static int
+tcp_usr_sockaddr(struct socket *so, struct mbuf *nam)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+
+ COMMON_START();
+ in_setsockaddr(inp, nam);
+ COMMON_END(PRU_SOCKADDR);
+}
+
+static int
+tcp_usr_peeraddr(struct socket *so, struct mbuf *nam)
+{
+ int s = splnet();
+ int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp;
+
+ COMMON_START();
+ in_setpeeraddr(inp, nam);
+ COMMON_END(PRU_PEERADDR);
+}
+
+/*
+ * XXX - this should just be a call to in_control, but we need to get
+ * the types worked out.
+ */
+static int
+tcp_usr_control(struct socket *so, int cmd, caddr_t arg, struct ifnet *ifp)
+{
+ return in_control(so, cmd, arg, ifp);
+}
+
+/* xxx - should be const */
+struct pr_usrreqs tcp_usrreqs = {
+ tcp_usr_abort, tcp_usr_accept, tcp_usr_attach, tcp_usr_bind,
+ tcp_usr_connect, pru_connect2_notsupp, tcp_usr_control, tcp_usr_detach,
+ tcp_usr_disconnect, tcp_usr_listen, tcp_usr_peeraddr, tcp_usr_rcvd,
+ tcp_usr_rcvoob, tcp_usr_send, tcp_usr_sense, tcp_usr_shutdown,
+ tcp_usr_sockaddr
+};
+
+/*
+ * Common subroutine to open a TCP connection to remote host specified
+ * by struct sockaddr_in in mbuf *nam. Call in_pcbbind to assign a local
+ * port number if needed. Call in_pcbladdr to do the routing and to choose
+ * a local host address (interface). If there is an existing incarnation
+ * of the same connection in TIME-WAIT state and if the remote host was
+ * sending CC options and if the connection duration was < MSL, then
+ * truncate the previous TIME-WAIT state and proceed.
+ * Initialize connection parameters and enter SYN-SENT state.
+ */
+static int
+tcp_connect(tp, nam)
+ register struct tcpcb *tp;
+ struct mbuf *nam;
+{
+ struct inpcb *inp = tp->t_inpcb, *oinp;
+ struct socket *so = inp->inp_socket;
+ struct tcpcb *otp;
+ struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
+ struct sockaddr_in *ifaddr;
+ int error;
+ struct rmxp_tao *taop;
+ struct rmxp_tao tao_noncached;
+
+ if (inp->inp_lport == 0) {
+ error = in_pcbbind(inp, NULL);
+ if (error)
+ return error;
+ }
+
+ /*
+ * Cannot simply call in_pcbconnect, because there might be an
+ * earlier incarnation of this same connection still in
+ * TIME_WAIT state, creating an ADDRINUSE error.
+ */
+ error = in_pcbladdr(inp, nam, &ifaddr);
+ if (error)
+ return error;
+ oinp = in_pcblookuphash(inp->inp_pcbinfo,
+ sin->sin_addr, sin->sin_port,
+ inp->inp_laddr.s_addr != INADDR_ANY ? inp->inp_laddr
+ : ifaddr->sin_addr,
+ inp->inp_lport, 0);
+ if (oinp) {
+ if (oinp != inp && (otp = intotcpcb(oinp)) != NULL &&
+ otp->t_state == TCPS_TIME_WAIT &&
+ otp->t_duration < TCPTV_MSL &&
+ (otp->t_flags & TF_RCVD_CC))
+ otp = tcp_close(otp);
+ else
+ return EADDRINUSE;
+ }
+ if (inp->inp_laddr.s_addr == INADDR_ANY)
+ inp->inp_laddr = ifaddr->sin_addr;
+ inp->inp_faddr = sin->sin_addr;
+ inp->inp_fport = sin->sin_port;
+ in_pcbrehash(inp);
+
+ tp->t_template = tcp_template(tp);
+ if (tp->t_template == 0) {
+ in_pcbdisconnect(inp);
+ return ENOBUFS;
+ }
+
+ /* Compute window scaling to request. */
+ while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
+ (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
+ tp->request_r_scale++;
+
+ soisconnecting(so);
+ tcpstat.tcps_connattempt++;
+ tp->t_state = TCPS_SYN_SENT;
+ tp->t_timer[TCPT_KEEP] = tcp_keepinit;
+ tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2;
+ tcp_sendseqinit(tp);
+
+ /*
+ * Generate a CC value for this connection and
+ * check whether CC or CCnew should be used.
+ */
+ if ((taop = tcp_gettaocache(tp->t_inpcb)) == NULL) {
+ taop = &tao_noncached;
+ bzero(taop, sizeof(*taop));
+ }
+
+ tp->cc_send = CC_INC(tcp_ccgen);
+ if (taop->tao_ccsent != 0 &&
+ CC_GEQ(tp->cc_send, taop->tao_ccsent)) {
+ taop->tao_ccsent = tp->cc_send;
+ } else {
+ taop->tao_ccsent = 0;
+ tp->t_flags |= TF_SENDCCNEW;
+ }
+
+ return 0;
+}
+
+int
+tcp_ctloutput(op, so, level, optname, mp)
+ int op;
+ struct socket *so;
+ int level, optname;
+ struct mbuf **mp;
+{
+ int error = 0, s;
+ struct inpcb *inp;
+ register struct tcpcb *tp;
+ register struct mbuf *m;
+ register int i;
+
+ s = splnet();
+ inp = sotoinpcb(so);
+ if (inp == NULL) {
+ splx(s);
+ if (op == PRCO_SETOPT && *mp)
+ (void) m_free(*mp);
+ return (ECONNRESET);
+ }
+ if (level != IPPROTO_TCP) {
+ error = ip_ctloutput(op, so, level, optname, mp);
+ splx(s);
+ return (error);
+ }
+ tp = intotcpcb(inp);
+
+ switch (op) {
+
+ case PRCO_SETOPT:
+ m = *mp;
+ switch (optname) {
+
+ case TCP_NODELAY:
+ if (m == NULL || m->m_len < sizeof (int))
+ error = EINVAL;
+ else if (*mtod(m, int *))
+ tp->t_flags |= TF_NODELAY;
+ else
+ tp->t_flags &= ~TF_NODELAY;
+ break;
+
+ case TCP_MAXSEG:
+ if (m && (i = *mtod(m, int *)) > 0 && i <= tp->t_maxseg)
+ tp->t_maxseg = i;
+ else
+ error = EINVAL;
+ break;
+
+ case TCP_NOOPT:
+ if (m == NULL || m->m_len < sizeof (int))
+ error = EINVAL;
+ else if (*mtod(m, int *))
+ tp->t_flags |= TF_NOOPT;
+ else
+ tp->t_flags &= ~TF_NOOPT;
+ break;
+
+ case TCP_NOPUSH:
+ if (m == NULL || m->m_len < sizeof (int))
+ error = EINVAL;
+ else if (*mtod(m, int *))
+ tp->t_flags |= TF_NOPUSH;
+ else
+ tp->t_flags &= ~TF_NOPUSH;
+ break;
+
+ default:
+ error = ENOPROTOOPT;
+ break;
+ }
+ if (m)
+ (void) m_free(m);
+ break;
+
+ case PRCO_GETOPT:
+ *mp = m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof(int);
+
+ switch (optname) {
+ case TCP_NODELAY:
+ *mtod(m, int *) = tp->t_flags & TF_NODELAY;
+ break;
+ case TCP_MAXSEG:
+ *mtod(m, int *) = tp->t_maxseg;
+ break;
+ case TCP_NOOPT:
+ *mtod(m, int *) = tp->t_flags & TF_NOOPT;
+ break;
+ case TCP_NOPUSH:
+ *mtod(m, int *) = tp->t_flags & TF_NOPUSH;
+ break;
+ default:
+ error = ENOPROTOOPT;
+ break;
+ }
+ break;
+ }
+ splx(s);
+ return (error);
+}
+
+/*
+ * tcp_sendspace and tcp_recvspace are the default send and receive window
+ * sizes, respectively. These are obsolescent (this information should
+ * be set by the route).
+ */
+u_long tcp_sendspace = 1024*16;
+SYSCTL_INT(_net_inet_tcp, TCPCTL_SENDSPACE, sendspace,
+ CTLFLAG_RW, &tcp_sendspace , 0, "");
+u_long tcp_recvspace = 1024*16;
+SYSCTL_INT(_net_inet_tcp, TCPCTL_RECVSPACE, recvspace,
+ CTLFLAG_RW, &tcp_recvspace , 0, "");
+
+/*
+ * Attach TCP protocol to socket, allocating
+ * internet protocol control block, tcp control block,
+ * bufer space, and entering LISTEN state if to accept connections.
+ */
+static int
+tcp_attach(so)
+ struct socket *so;
+{
+ register struct tcpcb *tp;
+ struct inpcb *inp;
+ int error;
+
+ if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
+ error = soreserve(so, tcp_sendspace, tcp_recvspace);
+ if (error)
+ return (error);
+ }
+ error = in_pcballoc(so, &tcbinfo);
+ if (error)
+ return (error);
+ inp = sotoinpcb(so);
+ tp = tcp_newtcpcb(inp);
+ if (tp == 0) {
+ int nofd = so->so_state & SS_NOFDREF; /* XXX */
+
+ so->so_state &= ~SS_NOFDREF; /* don't free the socket yet */
+ in_pcbdetach(inp);
+ so->so_state |= nofd;
+ return (ENOBUFS);
+ }
+ tp->t_state = TCPS_CLOSED;
+ return (0);
+}
+
+/*
+ * Initiate (or continue) disconnect.
+ * If embryonic state, just send reset (once).
+ * If in ``let data drain'' option and linger null, just drop.
+ * Otherwise (hard), mark socket disconnecting and drop
+ * current input data; switch states based on user close, and
+ * send segment to peer (with FIN).
+ */
+static struct tcpcb *
+tcp_disconnect(tp)
+ register struct tcpcb *tp;
+{
+ struct socket *so = tp->t_inpcb->inp_socket;
+
+ if (tp->t_state < TCPS_ESTABLISHED)
+ tp = tcp_close(tp);
+ else if ((so->so_options & SO_LINGER) && so->so_linger == 0)
+ tp = tcp_drop(tp, 0);
+ else {
+ soisdisconnecting(so);
+ sbflush(&so->so_rcv);
+ tp = tcp_usrclosed(tp);
+ if (tp)
+ (void) tcp_output(tp);
+ }
+ return (tp);
+}
+
+/*
+ * User issued close, and wish to trail through shutdown states:
+ * if never received SYN, just forget it. If got a SYN from peer,
+ * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
+ * If already got a FIN from peer, then almost done; go to LAST_ACK
+ * state. In all other cases, have already sent FIN to peer (e.g.
+ * after PRU_SHUTDOWN), and just have to play tedious game waiting
+ * for peer to send FIN or not respond to keep-alives, etc.
+ * We can let the user exit from the close as soon as the FIN is acked.
+ */
+static struct tcpcb *
+tcp_usrclosed(tp)
+ register struct tcpcb *tp;
+{
+
+ switch (tp->t_state) {
+
+ case TCPS_CLOSED:
+ case TCPS_LISTEN:
+ tp->t_state = TCPS_CLOSED;
+ tp = tcp_close(tp);
+ break;
+
+ case TCPS_SYN_SENT:
+ case TCPS_SYN_RECEIVED:
+ tp->t_flags |= TF_NEEDFIN;
+ break;
+
+ case TCPS_ESTABLISHED:
+ tp->t_state = TCPS_FIN_WAIT_1;
+ break;
+
+ case TCPS_CLOSE_WAIT:
+ tp->t_state = TCPS_LAST_ACK;
+ break;
+ }
+ if (tp && tp->t_state >= TCPS_FIN_WAIT_2) {
+ soisdisconnected(tp->t_inpcb->inp_socket);
+ /* To prevent the connection hanging in FIN_WAIT_2 forever. */
+ if (tp->t_state == TCPS_FIN_WAIT_2)
+ tp->t_timer[TCPT_2MSL] = tcp_maxidle;
+ }
+ return (tp);
+}
diff --git a/cpukit/libnetworking/netinet/tcp_var.h b/cpukit/libnetworking/netinet/tcp_var.h
new file mode 100644
index 0000000000..4d5d9e6eaf
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcp_var.h
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 1982, 1986, 1993, 1994, 1995
+ * 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.
+ * 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.
+ *
+ * @(#)tcp_var.h 8.4 (Berkeley) 5/24/95
+ * $FreeBSD: src/sys/netinet/tcp_var.h,v 1.121 2005/04/21 20:11:01 ps Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NETINET_TCP_VAR_H_
+#define _NETINET_TCP_VAR_H_
+
+#include <netinet/tcp.h>
+
+/*
+ * Kernel variables for tcp.
+ */
+
+#ifdef __BSD_VISIBLE
+/*
+ * Tcp control block, one per tcp; fields:
+ */
+struct tcpcb {
+ struct tcpiphdr *seg_next; /* sequencing queue */
+ struct tcpiphdr *seg_prev;
+ int t_state; /* state of this connection */
+ u_int t_flags;
+#define TF_ACKNOW 0x000001 /* ack peer immediately */
+#define TF_DELACK 0x000002 /* ack, but try to delay it */
+#define TF_NODELAY 0x000004 /* don't delay packets to coalesce */
+#define TF_NOOPT 0x000008 /* don't use tcp options */
+#define TF_SENTFIN 0x000010 /* have sent FIN */
+#define TF_REQ_SCALE 0x000020 /* have/will request window scaling */
+#define TF_RCVD_SCALE 0x000040 /* other side has requested scaling */
+#define TF_REQ_TSTMP 0x000080 /* have/will request timestamps */
+#define TF_RCVD_TSTMP 0x000100 /* a timestamp was received in SYN */
+#define TF_SACK_PERMIT 0x000200 /* other side said I could SACK */
+#define TF_NEEDSYN 0x000400 /* send SYN (implicit state) */
+#define TF_NEEDFIN 0x000800 /* send FIN (implicit state) */
+#define TF_NOPUSH 0x001000 /* don't push */
+#define TF_REQ_CC 0x002000 /* have/will request CC */
+#define TF_RCVD_CC 0x004000 /* a CC was received in SYN */
+#define TF_SENDCCNEW 0x008000 /* send CCnew instead of CC in SYN */
+#define TF_MORETOCOME 0x010000 /* More data to be appended to sock */
+#define TF_LQ_OVERFLOW 0x020000 /* listen queue overflow */
+#define TF_LASTIDLE 0x040000 /* connection was previously idle */
+#define TF_RXWIN0SENT 0x080000 /* sent a receiver win 0 in response */
+#define TF_FASTRECOVERY 0x100000 /* in NewReno Fast Recovery */
+#define TF_WASFRECOVERY 0x200000 /* was in NewReno Fast Recovery */
+#define TF_SIGNATURE 0x400000 /* require MD5 digests (RFC2385) */
+ int t_force; /* 1 if forcing out a byte */
+ int t_timer[TCPT_NTIMERS]; /* tcp timers */
+ int t_rxtshift; /* log(2) of rexmt exp. backoff */
+ int t_rxtcur; /* current retransmit value */
+ int t_dupacks; /* consecutive dup acks recd */
+ u_int t_maxseg; /* maximum segment size */
+ u_int t_maxopd; /* mss plus options */
+ struct tcpiphdr *t_template; /* skeletal packet for transmit */
+ struct inpcb *t_inpcb; /* back pointer to internet pcb */
+/*
+ * The following fields are used as in the protocol specification.
+ * See RFC783, Dec. 1981, page 21.
+ */
+/* send sequence variables */
+ tcp_seq snd_una; /* send unacknowledged */
+ tcp_seq snd_max; /* highest sequence number sent;
+ * used to recognize retransmits
+ */
+ tcp_seq snd_nxt; /* send next */
+ tcp_seq snd_up; /* send urgent pointer */
+
+ tcp_seq snd_wl1; /* window update seg seq number */
+ tcp_seq snd_wl2; /* window update seg ack number */
+ tcp_seq iss; /* initial send sequence number */
+ tcp_seq irs; /* initial receive sequence number */
+
+ tcp_seq rcv_nxt; /* receive next */
+ tcp_seq rcv_adv; /* advertised window */
+ u_long rcv_wnd; /* receive window */
+ tcp_seq rcv_up; /* receive urgent pointer */
+
+ u_long snd_wnd; /* send window */
+/*
+ * Additional variables for this implementation.
+ */
+/* congestion control (for slow start, source quench, retransmit after loss) */
+ u_long snd_cwnd; /* congestion-controlled window */
+ u_long snd_ssthresh; /* snd_cwnd size threshold for
+ * for slow start exponential to
+ * linear switch
+ */
+/*
+ * transmit timing stuff. See below for scale of srtt and rttvar.
+ * "Variance" is actually smoothed difference.
+ */
+ u_int t_idle; /* inactivity time */
+ int t_rtt; /* round trip time */
+ tcp_seq t_rtseq; /* sequence number being timed */
+ int t_srtt; /* smoothed round-trip time */
+ int t_rttvar; /* variance in round-trip time */
+ u_int t_rttmin; /* minimum rtt allowed */
+ u_long max_sndwnd; /* largest window peer has offered */
+
+ int t_softerror; /* possible error not yet reported */
+/* out-of-band data */
+ char t_oobflags; /* have some */
+ char t_iobc; /* input character */
+#define TCPOOB_HAVEDATA 0x01
+#define TCPOOB_HADDATA 0x02
+/* RFC 1323 variables */
+ u_char snd_scale; /* window scaling for send window */
+ u_char rcv_scale; /* window scaling for recv window */
+ u_char request_r_scale; /* pending window scaling */
+ u_char requested_s_scale;
+ u_long ts_recent; /* timestamp echo data */
+
+ u_long ts_recent_age; /* when last updated */
+ tcp_seq last_ack_sent;
+/* RFC 1644 variables */
+ tcp_cc cc_send; /* send connection count */
+ tcp_cc cc_recv; /* receive connection count */
+ u_long t_duration; /* connection duration */
+
+/* TUBA stuff */
+ caddr_t t_tuba_pcb; /* next level down pcb for TCP over z */
+/* More RTT stuff */
+ u_long t_rttupdated; /* number of times rtt sampled */
+};
+
+/*
+ * Structure to hold TCP options that are only used during segment
+ * processing (in tcp_input), but not held in the tcpcb.
+ * It's basically used to reduce the number of parameters
+ * to tcp_dooptions.
+ */
+struct tcpopt {
+ u_long to_flags; /* which options are present */
+#define TOF_TS 0x0001 /* timestamp */
+#define TOF_CC 0x0002 /* CC and CCnew are exclusive */
+#define TOF_CCNEW 0x0004
+#define TOF_CCECHO 0x0008
+#define TOF_MSS 0x0010
+#define TOF_SCALE 0x0020
+#define TOF_SIGNATURE 0x0040 /* signature option present */
+#define TOF_SIGLEN 0x0080 /* signature length valid (RFC2385) */
+#define TOF_SACK 0x0100 /* Peer sent SACK option */
+ u_int32_t to_tsval;
+ u_int32_t to_tsecr;
+ tcp_cc to_cc; /* holds CC or CCnew */
+ tcp_cc to_ccecho;
+};
+
+/*
+ * The TAO cache entry which is stored in the protocol family specific
+ * portion of the route metrics.
+ */
+struct rmxp_tao {
+ tcp_cc tao_cc; /* latest CC in valid SYN */
+ tcp_cc tao_ccsent; /* latest CC sent to peer */
+ u_short tao_mssopt; /* peer's cached MSS */
+#ifdef notyet
+ u_short tao_flags; /* cache status flags */
+#define TAOF_DONT 0x0001 /* peer doesn't understand rfc1644 */
+#define TAOF_OK 0x0002 /* peer does understand rfc1644 */
+#define TAOF_UNDEF 0 /* we don't know yet */
+#endif /* notyet */
+};
+#define rmx_taop(r) ((struct rmxp_tao *)(r).rmx_filler)
+
+#define intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb)
+#define intotw(ip) ((struct tcptw *)(ip)->inp_ppcb)
+#define sototcpcb(so) (intotcpcb(sotoinpcb(so)))
+#endif /* __BSD_VISIBLE */
+
+/*
+ * The smoothed round-trip time and estimated variance
+ * are stored as fixed point numbers scaled by the values below.
+ * For convenience, these scales are also used in smoothing the average
+ * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed).
+ * With these scales, srtt has 3 bits to the right of the binary point,
+ * and thus an "ALPHA" of 0.875. rttvar has 2 bits to the right of the
+ * binary point, and is smoothed with an ALPHA of 0.75.
+ */
+#define TCP_RTT_SCALE 32 /* multiplier for srtt; 3 bits frac. */
+#define TCP_RTT_SHIFT 5 /* shift for srtt; 3 bits frac. */
+#define TCP_RTTVAR_SCALE 16 /* multiplier for rttvar; 2 bits */
+#define TCP_RTTVAR_SHIFT 4 /* shift for rttvar; 2 bits */
+#define TCP_DELTA_SHIFT 2 /* see tcp_input.c */
+
+/*
+ * The initial retransmission should happen at rtt + 4 * rttvar.
+ * Because of the way we do the smoothing, srtt and rttvar
+ * will each average +1/2 tick of bias. When we compute
+ * the retransmit timer, we want 1/2 tick of rounding and
+ * 1 extra tick because of +-1/2 tick uncertainty in the
+ * firing of the timer. The bias will give us exactly the
+ * 1.5 tick we need. But, because the bias is
+ * statistical, we have to test that we don't drop below
+ * the minimum feasible timer (which is 2 ticks).
+ * This version of the macro adapted from a paper by Lawrence
+ * Brakmo and Larry Peterson which outlines a problem caused
+ * by insufficient precision in the original implementation,
+ * which results in inappropriately large RTO values for very
+ * fast networks.
+ */
+#define TCP_REXMTVAL(tp) \
+ ((((tp)->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT)) \
+ + (tp)->t_rttvar) >> TCP_DELTA_SHIFT)
+
+/* XXX
+ * We want to avoid doing m_pullup on incoming packets but that
+ * means avoiding dtom on the tcp reassembly code. That in turn means
+ * keeping an mbuf pointer in the reassembly queue (since we might
+ * have a cluster). As a quick hack, the source & destination
+ * port numbers (which are no longer needed once we've located the
+ * tcpcb) are overlayed with an mbuf pointer.
+ */
+#if (defined(__GNUC__) && (defined(__arm__) || defined(__mips__)))
+#define STR32_UNALGN(ti,m) \
+ (ti)->ti_sport = (unsigned short)(((unsigned int) m & 0xffff0000) >> 16); \
+ (ti)->ti_dport = (unsigned short) ((unsigned int) m & 0x0000ffff);
+#define LD32_UNALGN(ti,m) \
+ m = (struct mbuf *)((((unsigned int) (ti)->ti_sport) << 16) | ( (unsigned int)(ti)->ti_dport));
+
+#else
+#define REASS_MBUF(ti) (*(struct mbuf **)&((ti)->ti_t))
+#endif
+
+/*
+ * TCP statistics.
+ * Many of these should be kept per connection,
+ * but that's inconvenient at the moment.
+ */
+struct tcpstat {
+ u_long tcps_connattempt; /* connections initiated */
+ u_long tcps_accepts; /* connections accepted */
+ u_long tcps_connects; /* connections established */
+ u_long tcps_drops; /* connections dropped */
+ u_long tcps_conndrops; /* embryonic connections dropped */
+ u_long tcps_closed; /* conn. closed (includes drops) */
+ u_long tcps_segstimed; /* segs where we tried to get rtt */
+ u_long tcps_rttupdated; /* times we succeeded */
+ u_long tcps_delack; /* delayed acks sent */
+ u_long tcps_timeoutdrop; /* conn. dropped in rxmt timeout */
+ u_long tcps_rexmttimeo; /* retransmit timeouts */
+ u_long tcps_persisttimeo; /* persist timeouts */
+ u_long tcps_keeptimeo; /* keepalive timeouts */
+ u_long tcps_keepprobe; /* keepalive probes sent */
+ u_long tcps_keepdrops; /* connections dropped in keepalive */
+
+ u_long tcps_sndtotal; /* total packets sent */
+ u_long tcps_sndpack; /* data packets sent */
+ u_long tcps_sndbyte; /* data bytes sent */
+ u_long tcps_sndrexmitpack; /* data packets retransmitted */
+ u_long tcps_sndrexmitbyte; /* data bytes retransmitted */
+ u_long tcps_sndacks; /* ack-only packets sent */
+ u_long tcps_sndprobe; /* window probes sent */
+ u_long tcps_sndurg; /* packets sent with URG only */
+ u_long tcps_sndwinup; /* window update-only packets sent */
+ u_long tcps_sndctrl; /* control (SYN|FIN|RST) packets sent */
+
+ u_long tcps_rcvtotal; /* total packets received */
+ u_long tcps_rcvpack; /* packets received in sequence */
+ u_long tcps_rcvbyte; /* bytes received in sequence */
+ u_long tcps_rcvbadsum; /* packets received with ccksum errs */
+ u_long tcps_rcvbadoff; /* packets received with bad offset */
+ u_long tcps_rcvshort; /* packets received too short */
+ u_long tcps_rcvduppack; /* duplicate-only packets received */
+ u_long tcps_rcvdupbyte; /* duplicate-only bytes received */
+ u_long tcps_rcvpartduppack; /* packets with some duplicate data */
+ u_long tcps_rcvpartdupbyte; /* dup. bytes in part-dup. packets */
+ u_long tcps_rcvoopack; /* out-of-order packets received */
+ u_long tcps_rcvoobyte; /* out-of-order bytes received */
+ u_long tcps_rcvpackafterwin; /* packets with data after window */
+ u_long tcps_rcvbyteafterwin; /* bytes rcvd after window */
+ u_long tcps_rcvafterclose; /* packets rcvd after "close" */
+ u_long tcps_rcvwinprobe; /* rcvd window probe packets */
+ u_long tcps_rcvdupack; /* rcvd duplicate acks */
+ u_long tcps_rcvacktoomuch; /* rcvd acks for unsent data */
+ u_long tcps_rcvackpack; /* rcvd ack packets */
+ u_long tcps_rcvackbyte; /* bytes acked by rcvd acks */
+ u_long tcps_rcvwinupd; /* rcvd window update packets */
+ u_long tcps_pawsdrop; /* segments dropped due to PAWS */
+ u_long tcps_predack; /* times hdr predict ok for acks */
+ u_long tcps_preddat; /* times hdr predict ok for data pkts */
+ u_long tcps_pcbcachemiss;
+ u_long tcps_cachedrtt; /* times cached RTT in route updated */
+ u_long tcps_cachedrttvar; /* times cached rttvar updated */
+ u_long tcps_cachedssthresh; /* times cached ssthresh updated */
+ u_long tcps_usedrtt; /* times RTT initialized from route */
+ u_long tcps_usedrttvar; /* times RTTVAR initialized from rt */
+ u_long tcps_usedssthresh; /* times ssthresh initialized from rt*/
+ u_long tcps_persistdrop; /* timeout in persist state */
+ u_long tcps_badsyn; /* bogus SYN, e.g. premature ACK */
+ u_long tcps_mturesent; /* resends due to MTU discovery */
+ u_long tcps_listendrop; /* listen queue overflows */
+};
+
+/*
+ * TCB structure exported to user-land via sysctl(3).
+ * Evil hack: declare only if in_pcb.h and sys/socketvar.h have been
+ * included. Not all of our clients do.
+ */
+#if defined(_NETINET_IN_PCB_H_) && defined(_SYS_SOCKETVAR_H_)
+struct xtcpcb {
+ size_t xt_len;
+ struct inpcb xt_inp;
+ struct tcpcb xt_tp;
+#if 0
+ struct xsocket xt_socket;
+ u_quad_t xt_alignment_hack;
+#endif
+};
+#endif
+
+/*
+ * Names for TCP sysctl objects
+ */
+#define TCPCTL_DO_RFC1323 1 /* use RFC-1323 extensions */
+#define TCPCTL_DO_RFC1644 2 /* use RFC-1644 extensions */
+#define TCPCTL_MSSDFLT 3 /* MSS default */
+#define TCPCTL_STATS 4 /* statistics (read-only) */
+#define TCPCTL_RTTDFLT 5 /* default RTT estimate */
+#define TCPCTL_KEEPIDLE 6 /* keepalive idle timer */
+#define TCPCTL_KEEPINTVL 7 /* interval to send keepalives */
+#define TCPCTL_SENDSPACE 8 /* send buffer space */
+#define TCPCTL_RECVSPACE 9 /* receive buffer space */
+#define TCPCTL_KEEPINIT 10 /* timeout for establishing syn */
+#define TCPCTL_PCBLIST 11 /* list of all outstanding PCBs */
+#define TCPCTL_MAXID 12
+
+#define TCPCTL_NAMES { \
+ { 0, 0 }, \
+ { "rfc1323", CTLTYPE_INT }, \
+ { "rfc1644", CTLTYPE_INT }, \
+ { "mssdflt", CTLTYPE_INT }, \
+ { "stats", CTLTYPE_STRUCT }, \
+ { "rttdflt", CTLTYPE_INT }, \
+ { "keepidle", CTLTYPE_INT }, \
+ { "keepintvl", CTLTYPE_INT }, \
+ { "sendspace", CTLTYPE_INT }, \
+ { "recvspace", CTLTYPE_INT }, \
+ { "keepinit", CTLTYPE_INT }, \
+}
+
+#ifdef _KERNEL
+#ifdef SYSCTL_DECL
+SYSCTL_DECL(_net_inet_tcp);
+#endif
+
+extern struct inpcbhead tcb; /* head of queue of active tcpcb's */
+extern struct inpcbinfo tcbinfo;
+extern struct tcpstat tcpstat; /* tcp statistics */
+extern int tcp_mssdflt; /* XXX */
+extern u_long tcp_now; /* for RFC 1323 timestamps */
+
+void tcp_canceltimers __P((struct tcpcb *));
+struct tcpcb *
+ tcp_close(struct tcpcb *);
+void tcp_ctlinput(int, struct sockaddr *, void *);
+int tcp_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
+struct tcpcb *
+ tcp_drop(struct tcpcb *, int);
+void tcp_drain(void);
+void tcp_fasttimo(void);
+struct rmxp_tao *
+ tcp_gettaocache __P((struct inpcb *));
+void tcp_init(void);
+void tcp_input(struct mbuf *, int);
+void tcp_mss(struct tcpcb *, int);
+int tcp_mssopt __P((struct tcpcb *));
+void tcp_mtudisc(struct inpcb *, int);
+struct tcpcb *
+ tcp_newtcpcb(struct inpcb *);
+int tcp_output(struct tcpcb *);
+void tcp_quench(struct inpcb *, int);
+void tcp_respond(struct tcpcb *,
+ struct tcpiphdr *, struct mbuf *, tcp_seq, tcp_seq, int);
+struct rtentry *
+ tcp_rtlookup __P((struct inpcb *));
+void tcp_setpersist(struct tcpcb *);
+void tcp_slowtimo(void);
+struct tcpiphdr *
+ tcp_template __P((struct tcpcb *));
+struct tcpcb *
+ tcp_timers(struct tcpcb *, int);
+void tcp_trace(int, int, struct tcpcb *, struct tcpiphdr *, int);
+
+extern struct pr_usrreqs tcp_usrreqs;
+extern u_long tcp_sendspace;
+extern u_long tcp_recvspace;
+
+#endif /* _KERNEL */
+
+#endif /* _NETINET_TCP_VAR_H_ */
diff --git a/cpukit/libnetworking/netinet/tcpip.h b/cpukit/libnetworking/netinet/tcpip.h
new file mode 100644
index 0000000000..b8634bfd15
--- /dev/null
+++ b/cpukit/libnetworking/netinet/tcpip.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ *
+ * @(#)tcpip.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NETINET_TCPIP_H_
+#define _NETINET_TCPIP_H_
+
+/*
+ * Tcp+ip header, after ip options removed.
+ */
+struct tcpiphdr {
+ struct ipovly ti_i; /* overlaid ip structure */
+ struct tcphdr ti_t; /* tcp header */
+};
+#ifdef notyet
+/*
+ * Tcp+ip header, after ip options removed but including TCP options.
+ */
+struct full_tcpiphdr {
+ struct ipovly ti_i; /* overlaid ip structure */
+ struct tcphdr ti_t; /* tcp header */
+ char ti_o[TCP_MAXOLEN]; /* space for tcp options */
+};
+#endif /* notyet */
+#define ti_next ti_i.ih_next
+#define ti_prev ti_i.ih_prev
+#define ti_x1 ti_i.ih_x1
+#define ti_pr ti_i.ih_pr
+#define ti_len ti_i.ih_len
+#define ti_src ti_i.ih_src
+#define ti_dst ti_i.ih_dst
+#define ti_sport ti_t.th_sport
+#define ti_dport ti_t.th_dport
+#define ti_seq ti_t.th_seq
+#define ti_ack ti_t.th_ack
+#define ti_x2 ti_t.th_x2
+#define ti_off ti_t.th_off
+#define ti_flags ti_t.th_flags
+#define ti_win ti_t.th_win
+#define ti_sum ti_t.th_sum
+#define ti_urp ti_t.th_urp
+
+#endif
diff --git a/cpukit/libnetworking/netinet/udp.h b/cpukit/libnetworking/netinet/udp.h
new file mode 100644
index 0000000000..e73e1f4ddb
--- /dev/null
+++ b/cpukit/libnetworking/netinet/udp.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ *
+ * @(#)udp.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NETINET_UDP_H_
+#define _NETINET_UDP_H_
+
+/*
+ * Udp protocol header.
+ * Per RFC 768, September, 1981.
+ */
+struct udphdr {
+ u_short uh_sport; /* source port */
+ u_short uh_dport; /* destination port */
+ u_short uh_ulen; /* udp length */
+ u_short uh_sum; /* udp checksum */
+};
+
+#endif
diff --git a/cpukit/libnetworking/netinet/udp_usrreq.c b/cpukit/libnetworking/netinet/udp_usrreq.c
new file mode 100644
index 0000000000..767565a6ea
--- /dev/null
+++ b/cpukit/libnetworking/netinet/udp_usrreq.c
@@ -0,0 +1,728 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ * 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.
+ * 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.
+ *
+ * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95
+ * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.170 2004/11/08 14:44:53 phk Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+#include <sys/stat.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/syslog.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+/*
+ * UDP protocol implementation.
+ * Per RFC 768, August, 1980.
+ */
+#ifndef COMPAT_42
+static int udpcksum = 1;
+#else
+static int udpcksum = 0; /* XXX */
+#endif
+SYSCTL_INT(_net_inet_udp, UDPCTL_CHECKSUM, checksum, CTLFLAG_RW,
+ &udpcksum, 0, "");
+
+static int log_in_vain = 0;
+SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_RW,
+ &log_in_vain, 0, "");
+
+struct inpcbhead udb; /* from udp_var.h */
+struct inpcbinfo udbinfo;
+
+#ifndef UDBHASHSIZE
+#define UDBHASHSIZE 64
+#endif
+
+ struct udpstat udpstat; /* from udp_var.h */
+SYSCTL_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RD,
+ &udpstat, udpstat, "");
+
+static struct sockaddr_in udp_in = { sizeof(udp_in), AF_INET };
+
+static void udp_detach __P((struct inpcb *));
+static int udp_output __P((struct inpcb *, struct mbuf *, struct mbuf *,
+ struct mbuf *));
+static void udp_notify __P((struct inpcb *, int));
+
+void
+udp_init()
+{
+ LIST_INIT(&udb);
+ udbinfo.listhead = &udb;
+ udbinfo.hashbase = hashinit(UDBHASHSIZE, M_PCB, &udbinfo.hashmask);
+}
+
+void
+udp_input(m, iphlen)
+ register struct mbuf *m;
+ int iphlen;
+{
+ register struct ip *ip;
+ register struct udphdr *uh;
+ register struct inpcb *inp;
+ struct mbuf *opts = 0;
+ int len;
+ struct ip save_ip;
+
+ udpstat.udps_ipackets++;
+
+ /*
+ * Strip IP options, if any; should skip this,
+ * make available to user, and use on returned packets,
+ * but we don't yet have a way to check the checksum
+ * with options still present.
+ */
+ if (iphlen > sizeof (struct ip)) {
+ ip_stripoptions(m, (struct mbuf *)0);
+ iphlen = sizeof(struct ip);
+ }
+
+ /*
+ * Get IP and UDP header together in first mbuf.
+ */
+ ip = mtod(m, struct ip *);
+ if (m->m_len < iphlen + sizeof(struct udphdr)) {
+ if ((m = m_pullup(m, iphlen + sizeof(struct udphdr))) == 0) {
+ udpstat.udps_hdrops++;
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ }
+ uh = (struct udphdr *)((caddr_t)ip + iphlen);
+
+ /*
+ * Make mbuf data length reflect UDP length.
+ * If not enough data to reflect UDP length, drop.
+ */
+ len = ntohs((u_short)uh->uh_ulen);
+ if (ip->ip_len != len) {
+ if (len > ip->ip_len || len < sizeof(struct udphdr)) {
+ udpstat.udps_badlen++;
+ goto bad;
+ }
+ m_adj(m, len - ip->ip_len);
+ /* ip->ip_len = len; */
+ }
+ /*
+ * Save a copy of the IP header in case we want restore it
+ * for sending an ICMP error message in response.
+ */
+ save_ip = *ip;
+
+ /*
+ * Checksum extended UDP header and data.
+ */
+ if (uh->uh_sum) {
+ ((struct ipovly *)ip)->ih_next = 0;
+ ((struct ipovly *)ip)->ih_prev = 0;
+ ((struct ipovly *)ip)->ih_x1 = 0;
+ ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
+ uh->uh_sum = in_cksum(m, len + sizeof (struct ip));
+ if (uh->uh_sum) {
+ udpstat.udps_badsum++;
+ m_freem(m);
+ return;
+ }
+ }
+
+ if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
+ in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {
+ struct inpcb *last;
+ /*
+ * Deliver a multicast or broadcast datagram to *all* sockets
+ * for which the local and remote addresses and ports match
+ * those of the incoming datagram. This allows more than
+ * one process to receive multi/broadcasts on the same port.
+ * (This really ought to be done for unicast datagrams as
+ * well, but that would cause problems with existing
+ * applications that open both address-specific sockets and
+ * a wildcard socket listening to the same port -- they would
+ * end up receiving duplicates of every unicast datagram.
+ * Those applications open the multiple sockets to overcome an
+ * inadequacy of the UDP socket interface, but for backwards
+ * compatibility we avoid the problem here rather than
+ * fixing the interface. Maybe 4.5BSD will remedy this?)
+ */
+
+ /*
+ * Construct sockaddr format source address.
+ */
+ udp_in.sin_port = uh->uh_sport;
+ udp_in.sin_addr = ip->ip_src;
+ m->m_len -= sizeof (struct udpiphdr);
+ m->m_data += sizeof (struct udpiphdr);
+ /*
+ * Locate pcb(s) for datagram.
+ * (Algorithm copied from raw_intr().)
+ */
+ last = NULL;
+ for (inp = udb.lh_first; inp != NULL; inp = inp->inp_list.le_next) {
+ if (inp->inp_lport != uh->uh_dport)
+ continue;
+ if (inp->inp_laddr.s_addr != INADDR_ANY) {
+ if (inp->inp_laddr.s_addr !=
+ ip->ip_dst.s_addr)
+ continue;
+ }
+ if (inp->inp_faddr.s_addr != INADDR_ANY) {
+ if (inp->inp_faddr.s_addr !=
+ ip->ip_src.s_addr ||
+ inp->inp_fport != uh->uh_sport)
+ continue;
+ }
+
+ if (last != NULL) {
+ struct mbuf *n;
+
+ if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
+ if (last->inp_flags & INP_CONTROLOPTS
+ || last->inp_socket->so_options & SO_TIMESTAMP)
+ ip_savecontrol(last, &opts, ip, n);
+ if (sbappendaddr(&last->inp_socket->so_rcv,
+ (struct sockaddr *)&udp_in,
+ n, opts) == 0) {
+ m_freem(n);
+ if (opts)
+ m_freem(opts);
+ udpstat.udps_fullsock++;
+ } else
+ sorwakeup(last->inp_socket);
+ opts = 0;
+ }
+ }
+ last = inp;
+ /*
+ * Don't look for additional matches if this one does
+ * not have either the SO_REUSEPORT or SO_REUSEADDR
+ * socket options set. This heuristic avoids searching
+ * through all pcbs in the common case of a non-shared
+ * port. It * assumes that an application will never
+ * clear these options after setting them.
+ */
+ if (((last->inp_socket->so_options&(SO_REUSEPORT|SO_REUSEADDR)) == 0))
+ break;
+ }
+
+ if (last == NULL) {
+ /*
+ * No matching pcb found; discard datagram.
+ * (No need to send an ICMP Port Unreachable
+ * for a broadcast or multicast datgram.)
+ */
+ udpstat.udps_noportbcast++;
+ goto bad;
+ }
+ if (last->inp_flags & INP_CONTROLOPTS
+ || last->inp_socket->so_options & SO_TIMESTAMP)
+ ip_savecontrol(last, &opts, ip, m);
+ if (sbappendaddr(&last->inp_socket->so_rcv,
+ (struct sockaddr *)&udp_in,
+ m, opts) == 0) {
+ udpstat.udps_fullsock++;
+ goto bad;
+ }
+ sorwakeup(last->inp_socket);
+ return;
+ }
+ /*
+ * Locate pcb for datagram.
+ */
+ inp = in_pcblookuphash(&udbinfo, ip->ip_src, uh->uh_sport,
+ ip->ip_dst, uh->uh_dport, 1);
+ if (inp == NULL) {
+ if (log_in_vain) {
+ char buf[4*sizeof "123"];
+
+ strcpy(buf, inet_ntoa(ip->ip_dst));
+ log(LOG_INFO, "Connection attempt to UDP %s:%d"
+ " from %s:%d\n",
+ buf, ntohs(uh->uh_dport),
+ inet_ntoa(ip->ip_src), ntohs(uh->uh_sport));
+ }
+ udpstat.udps_noport++;
+ if (m->m_flags & (M_BCAST | M_MCAST)) {
+ udpstat.udps_noportbcast++;
+ goto bad;
+ }
+ *ip = save_ip;
+ icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
+ return;
+ }
+
+ /*
+ * Construct sockaddr format source address.
+ * Stuff source address and datagram in user buffer.
+ */
+ udp_in.sin_port = uh->uh_sport;
+ udp_in.sin_addr = ip->ip_src;
+ if (inp->inp_flags & INP_CONTROLOPTS
+ || inp->inp_socket->so_options & SO_TIMESTAMP)
+ ip_savecontrol(inp, &opts, ip, m);
+ iphlen += sizeof(struct udphdr);
+ m->m_len -= iphlen;
+ m->m_pkthdr.len -= iphlen;
+ m->m_data += iphlen;
+ if (sbappendaddr(&inp->inp_socket->so_rcv, (struct sockaddr *)&udp_in,
+ m, opts) == 0) {
+ udpstat.udps_fullsock++;
+ goto bad;
+ }
+ sorwakeup(inp->inp_socket);
+ return;
+bad:
+ m_freem(m);
+ if (opts)
+ m_freem(opts);
+}
+
+/*
+ * Notify a udp user of an asynchronous error;
+ * just wake up so that he can collect error status.
+ */
+static void
+udp_notify(inp, errnum)
+ register struct inpcb *inp;
+ int errnum;
+{
+ inp->inp_socket->so_error = errnum;
+ sorwakeup(inp->inp_socket);
+ sowwakeup(inp->inp_socket);
+}
+
+void
+udp_ctlinput(cmd, sa, vip)
+ int cmd;
+ struct sockaddr *sa;
+ void *vip;
+{
+ register struct ip *ip = vip;
+ register struct udphdr *uh;
+
+ if (!PRC_IS_REDIRECT(cmd) &&
+ ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0))
+ return;
+ if (ip) {
+ uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+ in_pcbnotify(&udb, sa, uh->uh_dport, ip->ip_src, uh->uh_sport,
+ cmd, udp_notify);
+ } else
+ in_pcbnotify(&udb, sa, 0, zeroin_addr, 0, cmd, udp_notify);
+}
+
+static int
+udp_output(inp, m, addr, control)
+ register struct inpcb *inp;
+ register struct mbuf *m;
+ struct mbuf *addr, *control;
+{
+ register struct udpiphdr *ui;
+ register int len = m->m_pkthdr.len;
+ struct in_addr laddr;
+ int s = 0, error = 0;
+
+ laddr.s_addr = 0;
+ if (control)
+ m_freem(control); /* XXX */
+
+ if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) {
+ error = EMSGSIZE;
+ goto release;
+ }
+
+ if (addr) {
+ laddr = inp->inp_laddr;
+ if (inp->inp_faddr.s_addr != INADDR_ANY) {
+ error = EISCONN;
+ goto release;
+ }
+ /*
+ * Must block input while temporarily connected.
+ */
+ s = splnet();
+ error = in_pcbconnect(inp, addr);
+ if (error) {
+ splx(s);
+ goto release;
+ }
+ } else {
+ if (inp->inp_faddr.s_addr == INADDR_ANY) {
+ error = ENOTCONN;
+ goto release;
+ }
+ }
+ /*
+ * Calculate data length and get a mbuf
+ * for UDP and IP headers.
+ */
+ M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
+ if (m == 0) {
+ error = ENOBUFS;
+ if (addr)
+ splx(s);
+ goto release;
+ }
+
+ /*
+ * Fill in mbuf with extended UDP header
+ * and addresses and length put into network format.
+ */
+ ui = mtod(m, struct udpiphdr *);
+ ui->ui_next = ui->ui_prev = 0;
+ ui->ui_x1 = 0;
+ ui->ui_pr = IPPROTO_UDP;
+ ui->ui_len = htons((u_short)len + sizeof (struct udphdr));
+ ui->ui_src = inp->inp_laddr;
+ ui->ui_dst = inp->inp_faddr;
+ ui->ui_sport = inp->inp_lport;
+ ui->ui_dport = inp->inp_fport;
+ ui->ui_ulen = ui->ui_len;
+
+ /*
+ * Stuff checksum and output datagram.
+ */
+ ui->ui_sum = 0;
+ if (udpcksum) {
+ if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len)) == 0)
+ ui->ui_sum = 0xffff;
+ }
+ ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
+ ((struct ip *)ui)->ip_ttl = inp->inp_ip_ttl; /* XXX */
+ ((struct ip *)ui)->ip_tos = inp->inp_ip_tos; /* XXX */
+ udpstat.udps_opackets++;
+ error = ip_output(m, inp->inp_options, &inp->inp_route,
+ inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST),
+ inp->inp_moptions);
+
+ if (addr) {
+ in_pcbdisconnect(inp);
+ inp->inp_laddr = laddr;
+ splx(s);
+ }
+ return (error);
+
+release:
+ m_freem(m);
+ return (error);
+}
+
+#ifdef __rtems__
+#define INP_INFO_RLOCK(a)
+#define INP_INFO_RUNLOCK(a)
+#define INP_LOCK(a)
+#define INP_UNLOCK(a)
+#endif
+
+static int
+udp_pcblist(SYSCTL_HANDLER_ARGS)
+{
+ int error, i, n, s;
+ struct inpcb *inp, **inp_list;
+ inp_gen_t gencnt;
+ struct xinpgen xig;
+
+ /*
+ * The process of preparing the TCB list is too time-consuming and
+ * resource-intensive to repeat twice on every request.
+ */
+ if (req->oldptr == 0) {
+ n = udbinfo.ipi_count;
+ req->oldidx = 2 * (sizeof xig)
+ + (n + n/8) * sizeof(struct xinpcb);
+ return 0;
+ }
+
+ if (req->newptr != 0)
+ return EPERM;
+
+ /*
+ * OK, now we're committed to doing something.
+ */
+ s = splnet();
+ gencnt = udbinfo.ipi_gencnt;
+ n = udbinfo.ipi_count;
+ splx(s);
+
+ sysctl_wire_old_buffer(req, 2 * (sizeof xig)
+ + n * sizeof(struct xinpcb));
+
+ xig.xig_len = sizeof xig;
+ xig.xig_count = n;
+ xig.xig_gen = gencnt;
+#if 0
+ xig.xig_sogen = so_gencnt;
+#endif
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ if (error)
+ return error;
+
+ /* ccj add the exit if count is 0 */
+ if (!n)
+ return error;
+
+ inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
+ if (inp_list == 0)
+ return ENOMEM;
+
+ s = splnet();
+ INP_INFO_RLOCK(&udbinfo);
+ for (inp = LIST_FIRST(udbinfo.listhead), i = 0; inp && i < n;
+ inp = LIST_NEXT(inp, inp_list)) {
+ INP_LOCK(inp);
+ if (inp->inp_gencnt <= gencnt)
+#if 0
+ &&
+ cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0)
+#endif
+ inp_list[i++] = inp;
+ INP_UNLOCK(inp);
+ }
+ INP_INFO_RUNLOCK(&udbinfo);
+ splx(s);
+ n = i;
+
+ error = 0;
+ for (i = 0; i < n; i++) {
+ inp = inp_list[i];
+ INP_LOCK(inp);
+ if (inp->inp_gencnt <= gencnt) {
+ struct xinpcb xi;
+ xi.xi_len = sizeof xi;
+ /* XXX should avoid extra copy */
+ bcopy(inp, &xi.xi_inp, sizeof *inp);
+#if 0
+ if (inp->inp_socket)
+ sotoxsocket(inp->inp_socket, &xi.xi_socket);
+#endif
+ error = SYSCTL_OUT(req, &xi, sizeof xi);
+ }
+ INP_UNLOCK(inp);
+ }
+ if (!error) {
+ /*
+ * Give the user an updated idea of our state.
+ * If the generation differs from what we told
+ * her before, she knows that something happened
+ * while we were processing this request, and it
+ * might be necessary to retry.
+ */
+ s = splnet();
+ INP_INFO_RLOCK(&udbinfo);
+ xig.xig_gen = udbinfo.ipi_gencnt;
+#if 0
+ xig.xig_sogen = so_gencnt;
+#endif
+ xig.xig_count = udbinfo.ipi_count;
+ INP_INFO_RUNLOCK(&udbinfo);
+ splx(s);
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ }
+ free(inp_list, M_TEMP);
+ return error;
+}
+
+SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0,
+ udp_pcblist, "S,xinpcb", "List of active UDP sockets");
+
+static u_long udp_sendspace = 9216; /* really max datagram size */
+ /* 40 1K datagrams */
+SYSCTL_INT(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW,
+ &udp_sendspace, 0, "");
+
+static u_long udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
+SYSCTL_INT(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW,
+ &udp_recvspace, 0, "");
+
+/*ARGSUSED*/
+int
+udp_usrreq(so, req, m, addr, control)
+ struct socket *so;
+ int req;
+ struct mbuf *m, *addr, *control;
+{
+ struct inpcb *inp = sotoinpcb(so);
+ int error = 0;
+ int s;
+
+ if (req == PRU_CONTROL)
+ return (in_control(so, (u_long)m, (caddr_t)addr,
+ (struct ifnet *)control));
+ if (inp == NULL && req != PRU_ATTACH) {
+ error = EINVAL;
+ goto release;
+ }
+ /*
+ * Note: need to block udp_input while changing
+ * the udp pcb queue and/or pcb addresses.
+ */
+ switch (req) {
+
+ case PRU_ATTACH:
+ if (inp != NULL) {
+ error = EINVAL;
+ break;
+ }
+ s = splnet();
+ error = in_pcballoc(so, &udbinfo);
+ splx(s);
+ if (error)
+ break;
+ error = soreserve(so, udp_sendspace, udp_recvspace);
+ if (error)
+ break;
+ ((struct inpcb *) so->so_pcb)->inp_ip_ttl = ip_defttl;
+ break;
+
+ case PRU_DETACH:
+ udp_detach(inp);
+ break;
+
+ case PRU_BIND:
+ s = splnet();
+ error = in_pcbbind(inp, addr);
+ splx(s);
+ break;
+
+ case PRU_LISTEN:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_CONNECT:
+ if (inp->inp_faddr.s_addr != INADDR_ANY) {
+ error = EISCONN;
+ break;
+ }
+ s = splnet();
+ error = in_pcbconnect(inp, addr);
+ splx(s);
+ if (error == 0)
+ soisconnected(so);
+ break;
+
+ case PRU_CONNECT2:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_ACCEPT:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_DISCONNECT:
+ if (inp->inp_faddr.s_addr == INADDR_ANY) {
+ error = ENOTCONN;
+ break;
+ }
+ s = splnet();
+ in_pcbdisconnect(inp);
+ inp->inp_laddr.s_addr = INADDR_ANY;
+ splx(s);
+ so->so_state &= ~SS_ISCONNECTED; /* XXX */
+ break;
+
+ case PRU_SHUTDOWN:
+ socantsendmore(so);
+ break;
+
+ case PRU_SEND:
+ return (udp_output(inp, m, addr, control));
+
+ case PRU_ABORT:
+ soisdisconnected(so);
+ udp_detach(inp);
+ break;
+
+ case PRU_SOCKADDR:
+ in_setsockaddr(inp, addr);
+ break;
+
+ case PRU_PEERADDR:
+ in_setpeeraddr(inp, addr);
+ break;
+
+ case PRU_SENSE:
+ /*
+ * stat: don't bother with a blocksize.
+ */
+ return (0);
+
+ case PRU_SENDOOB:
+ case PRU_FASTTIMO:
+ case PRU_SLOWTIMO:
+ case PRU_PROTORCV:
+ case PRU_PROTOSEND:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_RCVD:
+ case PRU_RCVOOB:
+ return (EOPNOTSUPP); /* do not free mbuf's */
+
+ default:
+ panic("udp_usrreq");
+ }
+
+release:
+ if (control) {
+ printf("udp control data unexpectedly retained\n");
+ m_freem(control);
+ }
+ if (m)
+ m_freem(m);
+ return (error);
+}
+
+static void
+udp_detach(inp)
+ struct inpcb *inp;
+{
+ int s = splnet();
+
+ in_pcbdetach(inp);
+ splx(s);
+}
diff --git a/cpukit/libnetworking/netinet/udp_var.h b/cpukit/libnetworking/netinet/udp_var.h
new file mode 100644
index 0000000000..6842dad8d5
--- /dev/null
+++ b/cpukit/libnetworking/netinet/udp_var.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1982, 1986, 1989, 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.
+ * 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.
+ *
+ * @(#)udp_var.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/udp_var.h,v 1.28 2004/08/16 18:32:07 rwatson Exp $
+ */
+
+#ifndef _NETINET_UDP_VAR_H_
+#define _NETINET_UDP_VAR_H_
+
+/*
+ * UDP kernel structures and variables.
+ */
+struct udpiphdr {
+ struct ipovly ui_i; /* overlaid ip structure */
+ struct udphdr ui_u; /* udp header */
+};
+#define ui_next ui_i.ih_next
+#define ui_prev ui_i.ih_prev
+#define ui_x1 ui_i.ih_x1
+#define ui_pr ui_i.ih_pr
+#define ui_len ui_i.ih_len
+#define ui_src ui_i.ih_src
+#define ui_dst ui_i.ih_dst
+#define ui_sport ui_u.uh_sport
+#define ui_dport ui_u.uh_dport
+#define ui_ulen ui_u.uh_ulen
+#define ui_sum ui_u.uh_sum
+
+struct udpstat {
+ /* input statistics: */
+ u_long udps_ipackets; /* total input packets */
+ u_long udps_hdrops; /* packet shorter than header */
+ u_long udps_badsum; /* checksum error */
+ u_long udps_badlen; /* data length larger than packet */
+ u_long udps_noport; /* no socket on port */
+ u_long udps_noportbcast; /* of above, arrived as broadcast */
+ u_long udps_fullsock; /* not delivered, input socket full */
+ u_long udpps_pcbcachemiss; /* input packets missing pcb cache */
+ u_long udpps_pcbhashmiss; /* input packets not for hashed pcb */
+ /* output statistics: */
+ u_long udps_opackets; /* total output packets */
+};
+
+/*
+ * Names for UDP sysctl objects
+ */
+#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */
+#define UDPCTL_STATS 2 /* statistics (read-only) */
+#define UDPCTL_MAXDGRAM 3 /* max datagram size */
+#define UDPCTL_RECVSPACE 4 /* default receive buffer space */
+#define UDPCTL_PCBLIST 5 /* list of PCBs for UDP sockets */
+#define UDPCTL_MAXID 6
+
+#define UDPCTL_NAMES { \
+ { 0, 0 }, \
+ { "checksum", CTLTYPE_INT }, \
+ { "stats", CTLTYPE_STRUCT }, \
+ { "maxdgram", CTLTYPE_INT }, \
+ { "recvspace", CTLTYPE_INT }, \
+}
+
+#ifdef _KERNEL
+SYSCTL_DECL(_net_inet_udp);
+
+extern struct inpcbhead udb;
+extern struct inpcbinfo udbinfo;
+extern struct udpstat udpstat;
+
+void udp_ctlinput __P((int, struct sockaddr *, void *));
+void udp_init __P((void));
+void udp_input __P((struct mbuf *, int));
+int udp_usrreq __P((struct socket *,
+ int, struct mbuf *, struct mbuf *, struct mbuf *));
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/nfs/bootp_subr.c b/cpukit/libnetworking/nfs/bootp_subr.c
new file mode 100644
index 0000000000..3ad2a38ac1
--- /dev/null
+++ b/cpukit/libnetworking/nfs/bootp_subr.c
@@ -0,0 +1,1159 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 1995 Gordon Ross, Adam Glass
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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, Lawrence Berkeley Laboratory 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.
+ *
+ * based on:
+ * nfs/krpc_subr.c
+ * $NetBSD: krpc_subr.c,v 1.10 1995/08/08 20:43:43 gwr Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/sockio.h>
+#include <sys/mount.h>
+#include <sys/mbuf.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <net/if_types.h>
+#include <net/if_dl.h>
+#include <netinet/if_ether.h>
+
+#include <nfs/nfsproto.h>
+#include <nfsclient/nfsargs.h>
+#include <nfsclient/nfsdiskless.h>
+#include <nfs/xdr_subs.h>
+
+#include <fcntl.h>
+#include <rtems/mkrootfs.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/bsdnet/servers.h>
+
+#define BOOTP_MIN_LEN 300 /* Minimum size of bootp udp packet */
+
+/*
+ * What is the longest we will wait before re-sending a request?
+ * Note this is also the frequency of "RPC timeout" messages.
+ * The re-send loop count sup linearly to this maximum, so the
+ * first complaint will happen after (1+2+3+4+5)=15 seconds.
+ */
+#define MAX_RESEND_DELAY 5 /* seconds */
+
+/* Definitions from RFC951 */
+struct bootp_packet {
+ u_int8_t op;
+ u_int8_t htype;
+ u_int8_t hlen;
+ u_int8_t hops;
+ u_int32_t xid;
+ u_int16_t secs;
+ u_int16_t flags;
+ struct in_addr ciaddr;
+ struct in_addr yiaddr;
+ struct in_addr siaddr;
+ struct in_addr giaddr;
+ unsigned char chaddr[16];
+ char sname[64];
+ char file[128];
+ unsigned char vend[256];
+};
+
+#define IPPORT_BOOTPC 68
+#define IPPORT_BOOTPS 67
+
+extern int nfs_diskless_valid;
+extern struct nfsv3_diskless nfsv3_diskless;
+
+/* mountd RPC */
+#if !defined(__rtems__)
+static int md_mount __P((struct sockaddr_in *mdsin, char *path,
+ u_char *fhp, int *fhsizep, struct nfs_args *args,struct proc *procp));
+static int md_lookup_swap __P((struct sockaddr_in *mdsin,char *path,
+ u_char *fhp, int *fhsizep,
+ struct nfs_args *args,
+ struct proc *procp));
+static int setfs __P((struct sockaddr_in *addr, char *path, char *p));
+static int getdec __P((char **ptr));
+#endif
+#if !defined(__rtems__)
+static char *substr __P((char *a,char *b));
+static void mountopts __P((struct nfs_args *args, char *p));
+static int xdr_opaque_decode __P((struct mbuf **ptr,u_char *buf,
+ int len));
+static int xdr_int_decode __P((struct mbuf **ptr,int *iptr));
+#endif
+static void printip __P((char *prefix,struct in_addr addr));
+
+#ifdef BOOTP_DEBUG
+void bootpboot_p_sa(struct sockaddr *sa,struct sockaddr *ma);
+void bootpboot_p_ma(struct sockaddr *ma);
+void bootpboot_p_rtentry(struct rtentry *rt);
+void bootpboot_p_tree(struct radix_node *rn);
+void bootpboot_p_rtlist(void);
+void bootpboot_p_iflist(void);
+#endif
+
+int bootpc_call(struct bootp_packet *call,
+ struct bootp_packet *reply,
+ struct proc *procp);
+
+int bootpc_fakeup_interface(struct ifreq *ireq,struct socket *so,
+ struct proc *procp);
+
+int
+bootpc_adjust_interface(struct ifreq *ireq,struct socket *so,
+ struct sockaddr_in *myaddr,
+ struct sockaddr_in *netmask,
+ struct sockaddr_in *gw,
+ struct proc *procp);
+
+void bootpc_init(int update_files);
+
+#ifdef BOOTP_DEBUG
+void bootpboot_p_sa(sa,ma)
+ struct sockaddr *sa;
+ struct sockaddr *ma;
+{
+ if (!sa) {
+ printf("(sockaddr *) <null>");
+ return;
+ }
+ switch (sa->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+ printf("inet %x",ntohl(sin->sin_addr.s_addr));
+ if (ma) {
+ struct sockaddr_in *sin = (struct sockaddr_in *) ma;
+ printf(" mask %x",ntohl(sin->sin_addr.s_addr));
+ }
+ }
+ break;
+ case AF_LINK:
+ {
+ struct sockaddr_dl *sli = (struct sockaddr_dl *) sa;
+ int i;
+ printf("link %.*s ",sli->sdl_nlen,sli->sdl_data);
+ for (i=0;i<sli->sdl_alen;i++) {
+ if (i>0)
+ printf(":");
+ printf("%x",(unsigned char) sli->sdl_data[i+sli->sdl_nlen]);
+ }
+ }
+ break;
+ default:
+ printf("af%d",sa->sa_family);
+ }
+}
+
+void bootpboot_p_ma(ma)
+ struct sockaddr *ma;
+{
+ if (!ma) {
+ printf("<null>");
+ return;
+ }
+ printf("%x",*(int*)ma);
+}
+
+void bootpboot_p_rtentry(rt)
+ struct rtentry *rt;
+{
+ bootpboot_p_sa(rt_key(rt),rt_mask(rt));
+ printf(" ");
+ bootpboot_p_ma(rt->rt_genmask);
+ printf(" ");
+ bootpboot_p_sa(rt->rt_gateway,NULL);
+ printf(" ");
+ printf("flags %x",(unsigned short) rt->rt_flags);
+ printf(" %d",rt->rt_rmx.rmx_expire);
+ printf(" %s%d\n",rt->rt_ifp->if_name,rt->rt_ifp->if_unit);
+}
+void bootpboot_p_tree(rn)
+ struct radix_node *rn;
+{
+ while (rn) {
+ if (rn->rn_b < 0) {
+ if (rn->rn_flags & RNF_ROOT) {
+ } else {
+ bootpboot_p_rtentry((struct rtentry *) rn);
+ }
+ rn = rn->rn_dupedkey;
+ } else {
+ bootpboot_p_tree(rn->rn_l);
+ bootpboot_p_tree(rn->rn_r);
+ return;
+ }
+
+ }
+}
+
+void bootpboot_p_rtlist(void)
+{
+ printf("Routing table:\n");
+ bootpboot_p_tree(rt_tables[AF_INET]->rnh_treetop);
+}
+
+void bootpboot_p_iflist(void)
+{
+ struct ifnet *ifp;
+ struct ifaddr *ifa;
+ printf("Interface list:\n");
+ for (ifp = TAILQ_FIRST(&ifnet); ifp != 0; ifp = TAILQ_NEXT(ifp,if_link))
+ {
+ for (ifa = TAILQ_FIRST(&ifp->if_addrhead) ;ifa;
+ ifa=TAILQ_NEXT(ifa,ifa_link))
+ if (ifa->ifa_addr->sa_family == AF_INET ) {
+ printf("%s%d flags %x, addr %x, bcast %x, net %x\n",
+ ifp->if_name,ifp->if_unit,
+ (unsigned short) ifp->if_flags,
+ ntohl(((struct sockaddr_in *) ifa->ifa_addr)->sin_addr.s_addr),
+ ntohl(((struct sockaddr_in *) ifa->ifa_dstaddr)->sin_addr.s_addr),
+ ntohl(((struct sockaddr_in *) ifa->ifa_netmask)->sin_addr.s_addr)
+ );
+ }
+ }
+}
+#endif
+
+/*
+ * - determine space needed to store src string
+ * - allocate or reallocate dst, so that string fits in
+ * - copy string from src to dest
+ */
+void *bootp_strdup_realloc(char *dst,const char *src)
+{
+ size_t len;
+ void *realloc(void * __r, size_t __size);
+
+ if (dst == NULL) {
+ /* first allocation, simply use strdup */
+ if (src)
+ dst = strdup(src);
+ }
+ else {
+ /* already allocated, so use realloc/strcpy */
+ len = src ? strlen(src) + 1 : 0;
+ /* src == NULL tells us to effectively free dst */
+ dst = realloc(dst,len);
+ if (dst != NULL) {
+ strcpy(dst,src);
+ }
+ }
+ return dst;
+}
+
+int
+bootpc_call(call,reply,procp)
+ struct bootp_packet *call;
+ struct bootp_packet *reply; /* output */
+ struct proc *procp;
+{
+ struct socket *so;
+ struct sockaddr_in *sin;
+ struct mbuf *m, *nam;
+ struct uio auio;
+ struct iovec aio;
+ int error, rcvflg, timo, secs, len;
+
+ /* Free at end if not null. */
+ nam = NULL;
+
+ /*
+ * Create socket and set its recieve timeout.
+ */
+ if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)))
+ goto out;
+
+ m = m_get(M_WAIT, MT_SOOPTS);
+ if (m == NULL) {
+ error = ENOBUFS;
+ goto out;
+ } else {
+ struct timeval *tv;
+ tv = mtod(m, struct timeval *);
+ m->m_len = sizeof(*tv);
+ tv->tv_sec = 1;
+ tv->tv_usec = 0;
+ if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m)))
+ goto out;
+ }
+
+ /*
+ * Enable broadcast.
+ */
+ {
+ int *on;
+ m = m_get(M_WAIT, MT_SOOPTS);
+ if (m == NULL) {
+ error = ENOBUFS;
+ goto out;
+ }
+ on = mtod(m, int *);
+ m->m_len = sizeof(*on);
+ *on = 1;
+ if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m)))
+ goto out;
+ }
+
+ /*
+ * Bind the local endpoint to a bootp client port.
+ */
+ m = m_getclr(M_WAIT, MT_SONAME);
+ sin = mtod(m, struct sockaddr_in *);
+ sin->sin_len = m->m_len = sizeof(*sin);
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = INADDR_ANY;
+ sin->sin_port = htons(IPPORT_BOOTPC);
+ error = sobind(so, m);
+ m_freem(m);
+ if (error) {
+ printf("bind failed\n");
+ goto out;
+ }
+
+ /*
+ * Setup socket address for the server.
+ */
+ nam = m_get(M_WAIT, MT_SONAME);
+ if (nam == NULL) {
+ error = ENOBUFS;
+ goto out;
+ }
+ sin = mtod(nam, struct sockaddr_in *);
+ sin-> sin_len = sizeof(*sin);
+ sin-> sin_family = AF_INET;
+ sin->sin_addr.s_addr = INADDR_BROADCAST;
+ sin->sin_port = htons(IPPORT_BOOTPS);
+
+ nam->m_len = sizeof(*sin);
+
+ /*
+ * Send it, repeatedly, until a reply is received,
+ * but delay each re-send by an increasing amount.
+ * If the delay hits the maximum, start complaining.
+ */
+ timo = 0;
+ for (;;) {
+ /* Send BOOTP request (or re-send). */
+
+ aio.iov_base = (caddr_t) call;
+ aio.iov_len = sizeof(*call);
+
+ auio.uio_iov = &aio;
+ auio.uio_iovcnt = 1;
+ auio.uio_segflg = UIO_SYSSPACE;
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_offset = 0;
+ auio.uio_resid = sizeof(*call);
+ auio.uio_procp = procp;
+
+ error = sosend(so, nam, &auio, NULL, NULL, 0);
+ if (error) {
+ printf("bootpc_call: sosend: %d\n", error);
+ goto out;
+ }
+
+ /* Determine new timeout. */
+ if (timo < MAX_RESEND_DELAY)
+ timo++;
+ else
+ printf("BOOTP timeout for server 0x%x\n",
+ (int)ntohl(sin->sin_addr.s_addr));
+
+ /*
+ * Wait for up to timo seconds for a reply.
+ * The socket receive timeout was set to 1 second.
+ */
+ secs = timo;
+ while (secs > 0) {
+ aio.iov_base = (caddr_t) reply;
+ aio.iov_len = sizeof(*reply);
+
+ auio.uio_iov = &aio;
+ auio.uio_iovcnt = 1;
+ auio.uio_segflg = UIO_SYSSPACE;
+ auio.uio_rw = UIO_READ;
+ auio.uio_offset = 0;
+ auio.uio_resid = sizeof(*reply);
+ auio.uio_procp = procp;
+
+ rcvflg = 0;
+ error = soreceive(so, NULL, &auio, NULL, NULL, &rcvflg);
+ if (error == EWOULDBLOCK) {
+ secs--;
+ call->secs=htons(ntohs(call->secs)+1);
+ continue;
+ }
+ if (error)
+ goto out;
+ len = sizeof(*reply) - auio.uio_resid;
+
+ /* Do we have the required number of bytes ? */
+ if (len < BOOTP_MIN_LEN)
+ continue;
+
+ /* Is it the right reply? */
+ if (reply->op != 2)
+ continue;
+
+ if (reply->xid != call->xid)
+ continue;
+
+ if (reply->hlen != call->hlen)
+ continue;
+
+ if (bcmp(reply->chaddr,call->chaddr,call->hlen))
+ continue;
+
+ goto gotreply; /* break two levels */
+
+ } /* while secs */
+ } /* forever send/receive */
+
+ error = ETIMEDOUT;
+ goto out;
+
+ gotreply:
+ out:
+ if (nam) m_freem(nam);
+ soclose(so);
+ return error;
+}
+
+int
+bootpc_fakeup_interface(struct ifreq *ireq,struct socket *so,
+ struct proc *procp)
+{
+ struct sockaddr_in *sin;
+ int error;
+ struct sockaddr_in dst;
+ struct sockaddr_in gw;
+ struct sockaddr_in mask;
+
+ /*
+ * Bring up the interface.
+ *
+ * Get the old interface flags and or IFF_UP into them; if
+ * IFF_UP set blindly, interface selection can be clobbered.
+ */
+ error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)ireq, procp);
+ if (error)
+ panic("bootpc_fakeup_interface: GIFFLAGS, error=%d", error);
+ ireq->ifr_flags |= IFF_UP;
+ error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)ireq, procp);
+ if (error)
+ panic("bootpc_fakeup_interface: SIFFLAGS, error=%d", error);
+
+ /*
+ * Do enough of ifconfig(8) so that the chosen interface
+ * can talk to the servers. (just set the address)
+ */
+
+ /* addr is 0.0.0.0 */
+
+ sin = (struct sockaddr_in *)&ireq->ifr_addr;
+ bzero((caddr_t)sin, sizeof(*sin));
+ sin->sin_len = sizeof(*sin);
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = INADDR_ANY;
+ error = ifioctl(so, SIOCSIFADDR, (caddr_t)ireq, procp);
+ if (error)
+ panic("bootpc_fakeup_interface: set if addr, error=%d", error);
+
+ /* netmask is 0.0.0.0 */
+
+ sin = (struct sockaddr_in *)&ireq->ifr_addr;
+ bzero((caddr_t)sin, sizeof(*sin));
+ sin->sin_len = sizeof(*sin);
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = INADDR_ANY;
+ error = ifioctl(so, SIOCSIFNETMASK, (caddr_t)ireq, procp);
+ if (error)
+ panic("bootpc_fakeup_interface: set if net addr, error=%d", error);
+
+ /* Broadcast is 255.255.255.255 */
+
+ sin = (struct sockaddr_in *)&ireq->ifr_addr;
+ bzero((caddr_t)sin, sizeof(*sin));
+ sin->sin_len = sizeof(*sin);
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = INADDR_BROADCAST;
+ error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t)ireq, procp);
+ if (error)
+ panic("bootpc_fakeup_interface: set if broadcast addr, error=%d", error);
+
+ /* Add default route to 0.0.0.0 so we can send data */
+
+ bzero((caddr_t) &dst, sizeof(dst));
+ dst.sin_len=sizeof(dst);
+ dst.sin_family=AF_INET;
+ dst.sin_addr.s_addr = htonl(0);
+
+ bzero((caddr_t) &gw, sizeof(gw));
+ gw.sin_len=sizeof(gw);
+ gw.sin_family=AF_INET;
+ gw.sin_addr.s_addr = htonl(0x0);
+
+ bzero((caddr_t) &mask, sizeof(mask));
+ mask.sin_len=sizeof(mask);
+ mask.sin_family=AF_INET;
+ mask.sin_addr.s_addr = htonl(0);
+
+ error = rtrequest(RTM_ADD,
+ (struct sockaddr *) &dst,
+ (struct sockaddr *) &gw,
+ (struct sockaddr *) &mask,
+ RTF_UP | RTF_STATIC
+ , NULL);
+ if (error)
+ printf("bootpc_fakeup_interface: add default route, error=%d\n", error);
+ return error;
+}
+
+int
+bootpc_adjust_interface(struct ifreq *ireq,struct socket *so,
+ struct sockaddr_in *myaddr,
+ struct sockaddr_in *netmask,
+ struct sockaddr_in *gw,
+ struct proc *procp)
+{
+ int error;
+ struct sockaddr_in oldgw;
+ struct sockaddr_in olddst;
+ struct sockaddr_in oldmask;
+ struct sockaddr_in *sin;
+
+ /* Remove old default route to 0.0.0.0 */
+
+ bzero((caddr_t) &olddst, sizeof(olddst));
+ olddst.sin_len=sizeof(olddst);
+ olddst.sin_family=AF_INET;
+ olddst.sin_addr.s_addr = INADDR_ANY;
+
+ bzero((caddr_t) &oldgw, sizeof(oldgw));
+ oldgw.sin_len=sizeof(oldgw);
+ oldgw.sin_family=AF_INET;
+ oldgw.sin_addr.s_addr = INADDR_ANY;
+
+ bzero((caddr_t) &oldmask, sizeof(oldmask));
+ oldmask.sin_len=sizeof(oldmask);
+ oldmask.sin_family=AF_INET;
+ oldmask.sin_addr.s_addr = INADDR_ANY;
+
+ error = rtrequest(RTM_DELETE,
+ (struct sockaddr *) &olddst,
+ (struct sockaddr *) &oldgw,
+ (struct sockaddr *) &oldmask,
+ (RTF_UP | RTF_STATIC), NULL);
+ if (error) {
+ printf("nfs_boot: del default route, error=%d\n", error);
+ return error;
+ }
+
+ /*
+ * Do enough of ifconfig(8) so that the chosen interface
+ * can talk to the servers. (just set the address)
+ */
+ bcopy(netmask,&ireq->ifr_addr,sizeof(*netmask));
+ error = ifioctl(so, SIOCSIFNETMASK, (caddr_t)ireq, procp);
+ if (error)
+ panic("nfs_boot: set if netmask, error=%d", error);
+
+ /* Broadcast is with host part of IP address all 1's */
+
+ sin = (struct sockaddr_in *)&ireq->ifr_addr;
+ bzero((caddr_t)sin, sizeof(*sin));
+ sin->sin_len = sizeof(*sin);
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = myaddr->sin_addr.s_addr | ~ netmask->sin_addr.s_addr;
+ error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t)ireq, procp);
+ if (error)
+ panic("bootpc_call: set if broadcast addr, error=%d", error);
+
+ bcopy(myaddr,&ireq->ifr_addr,sizeof(*myaddr));
+ error = ifioctl(so, SIOCSIFADDR, (caddr_t)ireq, procp);
+ if (error)
+ panic("nfs_boot: set if addr, error=%d", error);
+
+ /* Add new default route */
+
+ error = rtrequest(RTM_ADD,
+ (struct sockaddr *) &olddst,
+ (struct sockaddr *) gw,
+ (struct sockaddr *) &oldmask,
+ (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL);
+ if (error) {
+ printf("nfs_boot: add net route, error=%d\n", error);
+ return error;
+ }
+
+ return 0;
+}
+
+#if !defined(__rtems__)
+static int
+setfs(struct sockaddr_in *addr, char *path, char *p)
+{
+ unsigned ip = 0;
+ int val;
+
+ if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
+ ip = val << 24;
+ if (*p != '.') return(0);
+ p++;
+ if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
+ ip |= (val << 16);
+ if (*p != '.') return(0);
+ p++;
+ if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
+ ip |= (val << 8);
+ if (*p != '.') return(0);
+ p++;
+ if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
+ ip |= val;
+ if (*p != ':') return(0);
+ p++;
+
+ addr->sin_addr.s_addr = htonl(ip);
+ addr->sin_len = sizeof(struct sockaddr_in);
+ addr->sin_family = AF_INET;
+
+ strncpy(path,p,MNAMELEN-1);
+ return(1);
+}
+#endif
+
+#if !defined(__rtems__)
+static int
+getdec(char **ptr)
+{
+ char *p = *ptr;
+ int ret=0;
+ if ((*p < '0') || (*p > '9')) return(-1);
+ while ((*p >= '0') && (*p <= '9')) {
+ ret = ret*10 + (*p - '0');
+ p++;
+ }
+ *ptr = p;
+ return(ret);
+}
+#endif
+
+#if !defined(__rtems__)
+static char *
+substr(char *a, char *b)
+{
+ char *loc1;
+ char *loc2;
+
+ while (*a != '\0') {
+ loc1 = a;
+ loc2 = b;
+ while (*loc1 == *loc2++) {
+ if (*loc1 == '\0') return (0);
+ loc1++;
+ if (*loc2 == '\0') return (loc1);
+ }
+ a++;
+ }
+ return (0);
+}
+#endif
+
+static void printip(char *prefix,struct in_addr addr)
+{
+ unsigned int ip;
+
+ ip = ntohl(addr.s_addr);
+
+ printf("%s is %d.%d.%d.%d\n",prefix,
+ ip >> 24, (ip >> 16) & 255 ,(ip >> 8) & 255 ,ip & 255 );
+}
+
+static int dhcpOptionOverload = 0;
+static char dhcp_gotgw = 0;
+static char dhcp_gotnetmask = 0;
+static char dhcp_gotserver = 0;
+static char dhcp_gotlogserver = 0;
+static struct sockaddr_in dhcp_netmask;
+static struct sockaddr_in dhcp_gw;
+static char *dhcp_hostname = NULL;
+
+static void
+processOptions (unsigned char *optbuf, int optbufSize)
+{
+ int j = 0;
+ int len;
+ int code, ncode;
+ unsigned char *p;
+
+ ncode = optbuf[0];
+ while (j < optbufSize) {
+ code = optbuf[j] = ncode;
+ if (code == 255)
+ return;
+ if (code == 0) {
+ j++;
+ continue;
+ }
+ len = optbuf[j+1];
+ j += 2;
+ if ((len + j) >= optbufSize) {
+ printf ("Truncated field for code %d", code);
+ return;
+ }
+ ncode = optbuf[j+len];
+ optbuf[j+len] = '\0';
+ p = &optbuf[j];
+ j += len;
+
+ /*
+ * Process the option
+ */
+ switch (code) {
+ case 1:
+ /* Subnet mask */
+ if (len!=4)
+ panic("bootpc: subnet mask len is %d",len);
+ bcopy (p, &dhcp_netmask.sin_addr, 4);
+ dhcp_gotnetmask = 1;
+ break;
+
+ case 2:
+ /* Time offset */
+ if (len!=4)
+ panic("bootpc: time offset len is %d",len);
+ bcopy (p, &rtems_bsdnet_timeoffset, 4);
+ rtems_bsdnet_timeoffset = ntohl (rtems_bsdnet_timeoffset);
+ break;
+
+ case 3:
+ /* Routers */
+ if (len % 4)
+ panic ("bootpc: Router Len is %d", len);
+ if (len > 0) {
+ bcopy(p, &dhcp_gw.sin_addr, 4);
+ dhcp_gotgw = 1;
+ }
+ break;
+
+ case 42:
+ /* NTP servers */
+ if (len % 4)
+ panic ("bootpc: time server Len is %d", len);
+ {
+ int tlen = 0;
+ while ((tlen < len) &&
+ (rtems_bsdnet_ntpserver_count < sizeof rtems_bsdnet_config.ntp_server /
+ sizeof rtems_bsdnet_config.ntp_server[0])) {
+ bcopy (p+tlen,
+ &rtems_bsdnet_ntpserver[rtems_bsdnet_ntpserver_count],
+ 4);
+ printip("Time Server",
+ rtems_bsdnet_ntpserver[rtems_bsdnet_ntpserver_count]);
+ rtems_bsdnet_ntpserver_count++;
+ tlen += 4;
+ }
+ }
+ break;
+
+ case 6:
+ /* Domain Name servers */
+ if (len % 4)
+ panic ("bootpc: DNS Len is %d", len);
+ {
+ int dlen = 0;
+ while ((dlen < len) &&
+ (rtems_bsdnet_nameserver_count < sizeof rtems_bsdnet_config.name_server /
+ sizeof rtems_bsdnet_config.name_server[0])) {
+ bcopy (p+dlen,
+ &rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count],
+ 4);
+ printip("Domain Name Server",
+ rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count]);
+ rtems_bsdnet_nameserver_count++;
+ dlen += 4;
+ }
+ }
+ break;
+
+ case 12:
+ /* Host name */
+ if (len>=MAXHOSTNAMELEN)
+ panic ("bootpc: hostname >=%d bytes", MAXHOSTNAMELEN);
+ if (sethostname ((char *)p, len) < 0)
+ panic("Can't set host name");
+ printf("Hostname is %s\n", p);
+ dhcp_hostname = bootp_strdup_realloc(dhcp_hostname,(char *)p);
+ break;
+
+ case 7:
+ /* Log servers */
+ if (len % 4)
+ panic ("bootpc: Log server Len is %d", len);
+ if (len > 0) {
+ bcopy(p, &rtems_bsdnet_log_host_address, 4);
+ dhcp_gotlogserver = 1;
+ }
+ break;
+
+ case 15:
+ /* Domain name */
+ if (p[0]) {
+ rtems_bsdnet_domain_name =
+ bootp_strdup_realloc(rtems_bsdnet_domain_name,(char *)p);
+ printf("Domain name is %s\n", rtems_bsdnet_domain_name);
+ }
+ break;
+
+ case 16: /* Swap server IP address. unused */
+ break;
+
+ case 52:
+ /* DHCP option override */
+ if (len != 1)
+ panic ("bootpc: DHCP option overload len is %d", len);
+ dhcpOptionOverload = p[0];
+ break;
+
+ case 128: /* Site-specific option for DHCP servers that
+ * a) don't supply tag 54
+ * and
+ * b) don't supply the server address in siaddr
+ * For example, on Solaris 2.6 in.dhcpd, include in the dhcptab:
+ * Bootsrv s Site,128,IP,1,1
+ * and use that symbol in the macro that defines the client:
+ * Bootsrv=<tftp-server-ip-address>
+ */
+ case 54:
+ /* DHCP server */
+ if (len != 4)
+ panic ("bootpc: DHCP server len is %d", len);
+ bcopy(p, &rtems_bsdnet_bootp_server_address, 4);
+ dhcp_gotserver = 1;
+ break;
+
+ case 66:
+ /* DHCP server name option */
+ if (p[0])
+ rtems_bsdnet_bootp_server_name =
+ bootp_strdup_realloc(rtems_bsdnet_bootp_server_name,(char *)p);
+ break;
+
+ case 67:
+ /* DHCP bootfile option */
+ if (p[0])
+ rtems_bsdnet_bootp_boot_file_name =
+ bootp_strdup_realloc(rtems_bsdnet_bootp_boot_file_name,(char *)p);
+ break;
+
+ case 129:
+ /* Site specific option; we use this to get
+ * a 'command line string'
+ */
+ if (p[0])
+ rtems_bsdnet_bootp_cmdline = strdup((char *)p);
+ break;
+
+ default:
+ printf ("Ignoring BOOTP/DHCP option code %d\n", code);
+ break;
+ }
+ }
+}
+
+#define EALEN 6
+
+void
+bootpc_init(int update_files)
+{
+ struct bootp_packet call;
+ struct bootp_packet reply;
+ static u_int32_t xid = ~0xFF;
+
+ struct ifreq ireq;
+ struct ifnet *ifp;
+ struct socket *so;
+ int j;
+ int error;
+ struct sockaddr_in myaddr;
+ struct ifaddr *ifa;
+ struct sockaddr_dl *sdl = NULL;
+ char *delim;
+ struct proc *procp = NULL;
+
+ /*
+ * If already filled in, don't touch it here
+ */
+ if (nfs_diskless_valid)
+ return;
+
+ /*
+ * If we are to update the files create the root
+ * file structure.
+ */
+ if (update_files)
+ if (rtems_create_root_fs () < 0) {
+ printf("Error creating the root filesystem.\nFile not created.\n");
+ update_files = 0;
+ }
+
+ if (dhcp_hostname != NULL) {
+ /* free it */
+ dhcp_hostname=bootp_strdup_realloc(dhcp_hostname,0);
+ }
+
+ /*
+ * Find a network interface.
+ */
+ for (ifp = ifnet; ifp != 0; ifp = ifp->if_next)
+ if ((ifp->if_flags &
+ (IFF_LOOPBACK|IFF_POINTOPOINT)) == 0)
+ break;
+ if (ifp == NULL)
+ panic("bootpc_init: no suitable interface");
+ bzero(&ireq,sizeof(ireq));
+ sprintf(ireq.ifr_name, "%s%d", ifp->if_name,ifp->if_unit);
+ printf("bootpc_init: using network interface '%s'\n",
+ ireq.ifr_name);
+
+ if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)) != 0)
+ panic("nfs_boot: socreate, error=%d", error);
+
+ bootpc_fakeup_interface(&ireq,so,procp);
+
+ printf("Bootpc testing starting\n");
+
+ /* Get HW address */
+
+ for (ifa = ifp->if_addrlist;ifa; ifa = ifa->ifa_next)
+ if (ifa->ifa_addr->sa_family == AF_LINK &&
+ (sdl = ((struct sockaddr_dl *) ifa->ifa_addr)) &&
+ sdl->sdl_type == IFT_ETHER)
+ break;
+
+ if (!sdl)
+ panic("bootpc: Unable to find HW address");
+ if (sdl->sdl_alen != EALEN )
+ panic("bootpc: HW address len is %d, expected value is %d",
+ sdl->sdl_alen,EALEN);
+
+ printf("bootpc hw address is ");
+ delim="";
+ for (j=0;j<sdl->sdl_alen;j++) {
+ printf("%s%x",delim,((unsigned char *)LLADDR(sdl))[j]);
+ delim=":";
+ }
+ printf("\n");
+
+#if 0
+ bootpboot_p_iflist();
+ bootpboot_p_rtlist();
+#endif
+
+ bzero((caddr_t) &call, sizeof(call));
+
+ /* bootpc part */
+ call.op = 1; /* BOOTREQUEST */
+ call.htype= 1; /* 10mb ethernet */
+ call.hlen=sdl->sdl_alen; /* Hardware address length */
+ call.hops=0;
+ xid++;
+ call.xid = txdr_unsigned(xid);
+ bcopy(LLADDR(sdl),&call.chaddr,sdl->sdl_alen);
+
+ call.vend[0]=99;
+ call.vend[1]=130;
+ call.vend[2]=83;
+ call.vend[3]=99;
+ call.vend[4]=255;
+
+ call.secs = 0;
+ call.flags = htons(0x8000); /* We need an broadcast answer */
+
+ error = bootpc_call(&call,&reply,procp);
+
+ if (error)
+ panic("BOOTP call failed -- error %d", error);
+
+ /*
+ * Initialize network address structures
+ */
+ bzero(&myaddr,sizeof(myaddr));
+ bzero(&dhcp_netmask,sizeof(dhcp_netmask));
+ bzero(&dhcp_gw,sizeof(dhcp_gw));
+ myaddr.sin_len = sizeof(myaddr);
+ myaddr.sin_family = AF_INET;
+ dhcp_netmask.sin_len = sizeof(dhcp_netmask);
+ dhcp_netmask.sin_family = AF_INET;
+ dhcp_gw.sin_len = sizeof(dhcp_gw);
+ dhcp_gw.sin_family= AF_INET;
+
+ /*
+ * Set our address
+ */
+ myaddr.sin_addr = reply.yiaddr;
+ printip("My ip address",myaddr.sin_addr);
+
+ /*
+ * Process BOOTP/DHCP options
+ */
+ if (reply.vend[0]==99 && reply.vend[1]==130 &&
+ reply.vend[2]==83 && reply.vend[3]==99) {
+ processOptions (&reply.vend[4], sizeof(reply.vend) - 4);
+ }
+ if (dhcpOptionOverload & 1) {
+ processOptions ((unsigned char *)reply.file, sizeof reply.file);
+ }
+ else {
+ if (reply.file[0])
+ rtems_bsdnet_bootp_boot_file_name =
+ bootp_strdup_realloc(rtems_bsdnet_bootp_boot_file_name,reply.file);
+ }
+ if (dhcpOptionOverload & 2) {
+ processOptions ((unsigned char *)reply.sname, sizeof reply.sname);
+ }
+ else {
+ if (reply.sname[0])
+ rtems_bsdnet_bootp_server_name =
+ bootp_strdup_realloc(rtems_bsdnet_bootp_server_name,reply.sname);
+ }
+ if (rtems_bsdnet_bootp_server_name)
+ printf ("Server name is %s\n", rtems_bsdnet_bootp_server_name);
+ if (rtems_bsdnet_bootp_boot_file_name)
+ printf ("Boot file is %s\n", rtems_bsdnet_bootp_boot_file_name);
+ if (rtems_bsdnet_bootp_cmdline)
+ printf ("Command line is %s\n", rtems_bsdnet_bootp_cmdline);
+
+ /*
+ * Use defaults if values were not supplied by BOOTP/DHCP options
+ */
+ if (!dhcp_gotnetmask) {
+ if (IN_CLASSA(ntohl(myaddr.sin_addr.s_addr)))
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);
+ else if (IN_CLASSB(ntohl(myaddr.sin_addr.s_addr)))
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);
+ else
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
+ }
+ printip ("Subnet mask", dhcp_netmask.sin_addr);
+ if (!dhcp_gotserver)
+ rtems_bsdnet_bootp_server_address = reply.siaddr;
+ printip ("Server ip address" ,rtems_bsdnet_bootp_server_address);
+ if (!dhcp_gotgw)
+ dhcp_gw.sin_addr = reply.giaddr;
+ printip ("Gateway ip address", dhcp_gw.sin_addr);
+ if (!dhcp_gotlogserver)
+ rtems_bsdnet_log_host_address = rtems_bsdnet_bootp_server_address;
+ printip ("Log server ip address", rtems_bsdnet_log_host_address);
+
+ /*
+ * Update the files if we are asked too.
+ */
+ if (update_files) {
+ char *dn = rtems_bsdnet_domain_name;
+ char *hn = dhcp_hostname;
+ if (!dn)
+ dn = "mydomain";
+ if (!hn)
+ hn = "me";
+ rtems_rootfs_append_host_rec(*((unsigned long*) &myaddr.sin_addr), hn, dn);
+
+ /*
+ * Should the given domainname be used here ?
+ */
+ if (dhcp_gotserver) {
+ if (rtems_bsdnet_bootp_server_name)
+ hn = rtems_bsdnet_bootp_server_name;
+ else
+ hn = "bootps";
+ rtems_rootfs_append_host_rec(*((unsigned long *) &rtems_bsdnet_bootp_server_address),
+ hn, dn);
+ }
+
+ if (dhcp_gotlogserver) {
+ rtems_rootfs_append_host_rec(*((unsigned long *) &rtems_bsdnet_log_host_address),
+ "logs", dn);
+ }
+
+ /*
+ * Setup the DNS configuration file /etc/resolv.conf.
+ */
+ if (rtems_bsdnet_nameserver_count) {
+ int i;
+ char buf[64];
+ const char *bufl[1];
+
+ bufl[0] = buf;
+
+#define MKFILE_MODE (S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH)
+
+ if (rtems_bsdnet_domain_name &&
+ (strlen(rtems_bsdnet_domain_name) < (sizeof(buf) - 1))) {
+ strcpy(buf, "search ");
+ strcat(buf, rtems_bsdnet_domain_name);
+ strcat(buf, "\n");
+ rtems_rootfs_file_append ("/etc/resolv.conf", MKFILE_MODE, 1, bufl);
+ }
+
+ for (i = 0; i < rtems_bsdnet_nameserver_count; i++) {
+ strcpy(buf, "nameserver ");
+ strcat(buf, inet_ntoa(rtems_bsdnet_nameserver[i]));
+ strcat(buf, "\n");
+ if (rtems_rootfs_file_append ("/etc/resolv.conf", MKFILE_MODE, 1, bufl))
+ break;
+ }
+ }
+ }
+
+ /*
+ * Configure the interface with the new settings
+ */
+ error = bootpc_adjust_interface(&ireq,so,
+ &myaddr,&dhcp_netmask,&dhcp_gw,procp);
+ soclose(so);
+}
diff --git a/cpukit/libnetworking/nfs/krpc.h b/cpukit/libnetworking/nfs/krpc.h
new file mode 100644
index 0000000000..8a21392657
--- /dev/null
+++ b/cpukit/libnetworking/nfs/krpc.h
@@ -0,0 +1,26 @@
+/* $NetBSD: krpc.h,v 1.4 1995/12/19 23:07:11 cgd Exp $ */
+/* $Id$ */
+
+#include <sys/cdefs.h>
+
+int krpc_call __P((struct sockaddr_in *sin,
+ u_int prog, u_int vers, u_int func,
+ struct mbuf **data, struct mbuf **from, struct proc *procp));
+
+int krpc_portmap __P((struct sockaddr_in *sin,
+ u_int prog, u_int vers, u_int16_t *portp, struct proc *procp));
+
+struct mbuf *xdr_string_encode __P((char *str, int len));
+
+/*
+ * RPC definitions for the portmapper
+ */
+#define PMAPPORT 111
+#define PMAPPROG 100000
+#define PMAPVERS 2
+#define PMAPPROC_NULL 0
+#define PMAPPROC_SET 1
+#define PMAPPROC_UNSET 2
+#define PMAPPROC_GETPORT 3
+#define PMAPPROC_DUMP 4
+#define PMAPPROC_CALLIT 5
diff --git a/cpukit/libnetworking/nfs/nfs.h b/cpukit/libnetworking/nfs/nfs.h
new file mode 100644
index 0000000000..afa7593278
--- /dev/null
+++ b/cpukit/libnetworking/nfs/nfs.h
@@ -0,0 +1,620 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * 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.
+ *
+ * @(#)nfs.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NFS_NFS_H_
+#define _NFS_NFS_H_
+
+#include <nfs/rpcv2.h>
+
+/*
+ * Tunable constants for nfs
+ */
+
+#define NFS_MAXIOVEC 34
+#define NFS_TICKINTVL 5 /* Desired time for a tick (msec) */
+#define NFS_HZ (hz / nfs_ticks) /* Ticks/sec */
+#define NFS_TIMEO (1 * NFS_HZ) /* Default timeout = 1 second */
+#define NFS_MINTIMEO (1 * NFS_HZ) /* Min timeout to use */
+#define NFS_MAXTIMEO (60 * NFS_HZ) /* Max timeout to backoff to */
+#define NFS_MINIDEMTIMEO (5 * NFS_HZ) /* Min timeout for non-idempotent ops*/
+#define NFS_MAXREXMIT 100 /* Stop counting after this many */
+#define NFS_MAXWINDOW 1024 /* Max number of outstanding requests */
+#define NFS_RETRANS 10 /* Num of retrans for soft mounts */
+#define NFS_MAXGRPS 16 /* Max. size of groups list */
+#ifndef NFS_MINATTRTIMO
+#define NFS_MINATTRTIMO 5 /* Attribute cache timeout in sec */
+#endif
+#ifndef NFS_MAXATTRTIMO
+#define NFS_MAXATTRTIMO 60
+#endif
+#define NFS_WSIZE 8192 /* Def. write data size <= 8192 */
+#define NFS_RSIZE 8192 /* Def. read data size <= 8192 */
+#define NFS_READDIRSIZE 8192 /* Def. readdir size */
+#define NFS_DEFRAHEAD 1 /* Def. read ahead # blocks */
+#define NFS_MAXRAHEAD 4 /* Max. read ahead # blocks */
+#define NFS_MAXUIDHASH 64 /* Max. # of hashed uid entries/mp */
+#define NFS_MAXASYNCDAEMON 20 /* Max. number async_daemons runnable */
+#define NFS_MAXGATHERDELAY 100 /* Max. write gather delay (msec) */
+#ifndef NFS_GATHERDELAY
+#define NFS_GATHERDELAY 10 /* Default write gather delay (msec) */
+#endif
+#define NFS_DIRBLKSIZ 4096 /* Must be a multiple of DIRBLKSIZ */
+
+/*
+ * Oddballs
+ */
+#define NMOD(a) ((a) % nfs_asyncdaemons)
+#define NFS_CMPFH(n, f, s) \
+ ((n)->n_fhsize == (s) && !bcmp((caddr_t)(n)->n_fhp, (caddr_t)(f), (s)))
+#define NFS_ISV3(v) (VFSTONFS((v)->v_mount)->nm_flag & NFSMNT_NFSV3)
+#define NFS_SRVMAXDATA(n) \
+ (((n)->nd_flag & ND_NFSV3) ? (((n)->nd_nam2) ? \
+ NFS_MAXDGRAMDATA : NFS_MAXDATA) : NFS_V2MAXDATA)
+
+/*
+ * XXX
+ * sys/buf.h should be edited to change B_APPENDWRITE --> B_NEEDCOMMIT, but
+ * until then...
+ * Same goes for sys/malloc.h, which needs M_NFSDIROFF,
+ * M_NFSRVDESC and M_NFSBIGFH added.
+ * The VA_EXCLUSIVE flag should be added for va_vaflags and set for an
+ * exclusive create.
+ * The B_INVAFTERWRITE flag should be set to whatever is required by the
+ * buffer cache code to say "Invalidate the block after it is written back".
+ */
+#ifndef B_NEEDCOMMIT
+#define B_NEEDCOMMIT B_APPENDWRITE
+#endif
+#ifndef M_NFSRVDESC
+#define M_NFSRVDESC M_TEMP
+#endif
+#ifndef M_NFSDIROFF
+#define M_NFSDIROFF M_TEMP
+#endif
+#ifndef M_NFSBIGFH
+#define M_NFSBIGFH M_TEMP
+#endif
+#ifndef VA_EXCLUSIVE
+#define VA_EXCLUSIVE 0
+#endif
+#ifdef __FreeBSD__
+#define B_INVAFTERWRITE B_NOCACHE
+#else
+#define B_INVAFTERWRITE B_INVAL
+#endif
+
+/*
+ * These ifdefs try to handle the differences between the various 4.4BSD-Lite
+ * based vfs interfaces.
+ * btw: NetBSD-current does have a VOP_LEASDE(), but I don't know how to
+ * differentiate between NetBSD-1.0 and NetBSD-current, so..
+ * I also don't know about BSDi's 2.0 release.
+ */
+#if !defined(HAS_VOPLEASE) && !defined(__FreeBSD__) && !defined(__NetBSD__)
+#define HAS_VOPLEASE 1
+#endif
+#if !defined(HAS_VOPREVOKE) && !defined(__FreeBSD__) && !defined(__NetBSD__)
+#define HAS_VOPREVOKE 1
+#endif
+
+/*
+ * The IO_METASYNC flag should be implemented for local file systems.
+ * (Until then, it is nothin at all.)
+ */
+#ifndef IO_METASYNC
+#define IO_METASYNC 0
+#endif
+
+/*
+ * Set the attribute timeout based on how recently the file has been modified.
+ */
+#define NFS_ATTRTIMEO(np) \
+ ((((np)->n_flag & NMODIFIED) || \
+ (time.tv_sec - (np)->n_mtime) / 10 < NFS_MINATTRTIMO) ? NFS_MINATTRTIMO : \
+ ((time.tv_sec - (np)->n_mtime) / 10 > NFS_MAXATTRTIMO ? NFS_MAXATTRTIMO : \
+ (time.tv_sec - (np)->n_mtime) / 10))
+
+/*
+ * Expected allocation sizes for major data structures. If the actual size
+ * of the structure exceeds these sizes, then malloc() will be allocating
+ * almost twice the memory required. This is used in nfs_init() to warn
+ * the sysadmin that the size of a structure should be reduced.
+ * (These sizes are always a power of 2. If the kernel malloc() changes
+ * to one that does not allocate space in powers of 2 size, then this all
+ * becomes bunk!)
+ */
+#define NFS_NODEALLOC 256
+#define NFS_MNTALLOC 512
+#define NFS_SVCALLOC 256
+#define NFS_UIDALLOC 128
+
+/*
+ * Structures for the nfssvc(2) syscall. Not that anyone but nfsd and mount_nfs
+ * should ever try and use it.
+ */
+struct nfsd_args {
+ int sock; /* Socket to serve */
+ caddr_t name; /* Client address for connection based sockets */
+ int namelen; /* Length of name */
+};
+
+struct nfsd_srvargs {
+ struct nfsd *nsd_nfsd; /* Pointer to in kernel nfsd struct */
+ uid_t nsd_uid; /* Effective uid mapped to cred */
+ u_long nsd_haddr; /* Ip address of client */
+ struct ucred nsd_cr; /* Cred. uid maps to */
+ int nsd_authlen; /* Length of auth string (ret) */
+ u_char *nsd_authstr; /* Auth string (ret) */
+ int nsd_verflen; /* and the verfier */
+ u_char *nsd_verfstr;
+ struct timeval nsd_timestamp; /* timestamp from verifier */
+ u_long nsd_ttl; /* credential ttl (sec) */
+ NFSKERBKEY_T nsd_key; /* Session key */
+};
+
+struct nfsd_cargs {
+ char *ncd_dirp; /* Mount dir path */
+ uid_t ncd_authuid; /* Effective uid */
+ int ncd_authtype; /* Type of authenticator */
+ int ncd_authlen; /* Length of authenticator string */
+ u_char *ncd_authstr; /* Authenticator string */
+ int ncd_verflen; /* and the verifier */
+ u_char *ncd_verfstr;
+ NFSKERBKEY_T ncd_key; /* Session key */
+};
+
+/*
+ * Stats structure
+ */
+struct nfsstats {
+ int attrcache_hits;
+ int attrcache_misses;
+ int lookupcache_hits;
+ int lookupcache_misses;
+ int direofcache_hits;
+ int direofcache_misses;
+ int biocache_reads;
+ int read_bios;
+ int read_physios;
+ int biocache_writes;
+ int write_bios;
+ int write_physios;
+ int biocache_readlinks;
+ int readlink_bios;
+ int biocache_readdirs;
+ int readdir_bios;
+ int rpccnt[NFS_NPROCS];
+ int rpcretries;
+ int srvrpccnt[NFS_NPROCS];
+ int srvrpc_errs;
+ int srv_errs;
+ int rpcrequests;
+ int rpctimeouts;
+ int rpcunexpected;
+ int rpcinvalid;
+ int srvcache_inproghits;
+ int srvcache_idemdonehits;
+ int srvcache_nonidemdonehits;
+ int srvcache_misses;
+ int srvnqnfs_leases;
+ int srvnqnfs_maxleases;
+ int srvnqnfs_getleases;
+ int srvvop_writes;
+};
+
+/*
+ * Flags for nfssvc() system call.
+ */
+#define NFSSVC_BIOD 0x002
+#define NFSSVC_NFSD 0x004
+#define NFSSVC_ADDSOCK 0x008
+#define NFSSVC_AUTHIN 0x010
+#define NFSSVC_GOTAUTH 0x040
+#define NFSSVC_AUTHINFAIL 0x080
+#define NFSSVC_MNTD 0x100
+
+/*
+ * fs.nfs sysctl(3) identifiers
+ */
+#define NFS_NFSSTATS 1 /* struct: struct nfsstats */
+#define NFS_NFSPRIVPORT 2 /* int: prohibit nfs to resvports */
+
+#define FS_NFS_NAMES { \
+ { 0, 0 }, \
+ { "nfsstats", CTLTYPE_STRUCT }, \
+ { "nfsprivport", CTLTYPE_INT }, \
+}
+
+/*
+ * The set of signals the interrupt an I/O in progress for NFSMNT_INT mounts.
+ * What should be in this set is open to debate, but I believe that since
+ * I/O system calls on ufs are never interrupted by signals the set should
+ * be minimal. My reasoning is that many current programs that use signals
+ * such as SIGALRM will not expect file I/O system calls to be interrupted
+ * by them and break.
+ */
+#if defined(_KERNEL) || defined(_KERNEL)
+
+struct uio; struct buf; struct vattr; struct nameidata; /* XXX */
+
+#define NFSINT_SIGMASK (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGKILL)| \
+ sigmask(SIGHUP)|sigmask(SIGQUIT))
+
+/*
+ * Socket errors ignored for connectionless sockets??
+ * For now, ignore them all
+ */
+#define NFSIGNORE_SOERROR(s, e) \
+ ((e) != EINTR && (e) != ERESTART && (e) != EWOULDBLOCK && \
+ ((s) & PR_CONNREQUIRED) == 0)
+
+/*
+ * Nfs outstanding request list element
+ */
+struct nfsreq {
+ TAILQ_ENTRY(nfsreq) r_chain;
+ struct mbuf *r_mreq;
+ struct mbuf *r_mrep;
+ struct mbuf *r_md;
+ caddr_t r_dpos;
+ struct nfsmount *r_nmp;
+ struct vnode *r_vp;
+ u_long r_xid;
+ int r_flags; /* flags on request, see below */
+ int r_retry; /* max retransmission count */
+ int r_rexmit; /* current retrans count */
+ int r_timer; /* tick counter on reply */
+ int r_procnum; /* NFS procedure number */
+ int r_rtt; /* RTT for rpc */
+ struct proc *r_procp; /* Proc that did I/O system call */
+};
+
+/*
+ * Queue head for nfsreq's
+ */
+extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq;
+
+/* Flag values for r_flags */
+#define R_TIMING 0x01 /* timing request (in mntp) */
+#define R_SENT 0x02 /* request has been sent */
+#define R_SOFTTERM 0x04 /* soft mnt, too many retries */
+#define R_INTR 0x08 /* intr mnt, signal pending */
+#define R_SOCKERR 0x10 /* Fatal error on socket */
+#define R_TPRINTFMSG 0x20 /* Did a tprintf msg. */
+#define R_MUSTRESEND 0x40 /* Must resend request */
+#define R_GETONEREP 0x80 /* Probe for one reply only */
+
+/*
+ * A list of nfssvc_sock structures is maintained with all the sockets
+ * that require service by the nfsd.
+ * The nfsuid structs hang off of the nfssvc_sock structs in both lru
+ * and uid hash lists.
+ */
+#ifndef NFS_UIDHASHSIZ
+#define NFS_UIDHASHSIZ 29 /* Tune the size of nfssvc_sock with this */
+#endif
+#define NUIDHASH(sock, uid) \
+ (&(sock)->ns_uidhashtbl[(uid) % NFS_UIDHASHSIZ])
+#ifndef NFS_WDELAYHASHSIZ
+#define NFS_WDELAYHASHSIZ 16 /* and with this */
+#endif
+#define NWDELAYHASH(sock, f) \
+ (&(sock)->ns_wdelayhashtbl[(*((u_long *)(f))) % NFS_WDELAYHASHSIZ])
+#ifndef NFS_MUIDHASHSIZ
+#define NFS_MUIDHASHSIZ 63 /* Tune the size of nfsmount with this */
+#endif
+#define NMUIDHASH(nmp, uid) \
+ (&(nmp)->nm_uidhashtbl[(uid) % NFS_MUIDHASHSIZ])
+#define NFSNOHASH(fhsum) \
+ (&nfsnodehashtbl[(fhsum) & nfsnodehash])
+
+/*
+ * Network address hash list element
+ */
+union nethostaddr {
+ u_long had_inetaddr;
+ struct mbuf *had_nam;
+};
+
+struct nfsuid {
+ TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */
+ LIST_ENTRY(nfsuid) nu_hash; /* Hash list */
+ int nu_flag; /* Flags */
+ union nethostaddr nu_haddr; /* Host addr. for dgram sockets */
+ struct ucred nu_cr; /* Cred uid mapped to */
+ int nu_expire; /* Expiry time (sec) */
+ struct timeval nu_timestamp; /* Kerb. timestamp */
+ u_long nu_nickname; /* Nickname on server */
+ NFSKERBKEY_T nu_key; /* and session key */
+};
+
+#define nu_inetaddr nu_haddr.had_inetaddr
+#define nu_nam nu_haddr.had_nam
+/* Bits for nu_flag */
+#define NU_INETADDR 0x1
+#define NU_NAM 0x2
+#define NU_NETFAM(u) (((u)->nu_flag & NU_INETADDR) ? AF_INET : AF_ISO)
+
+struct nfssvc_sock {
+ TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */
+ TAILQ_HEAD(, nfsuid) ns_uidlruhead;
+ struct file *ns_fp;
+ struct socket *ns_so;
+ struct mbuf *ns_nam;
+ struct mbuf *ns_raw;
+ struct mbuf *ns_rawend;
+ struct mbuf *ns_rec;
+ struct mbuf *ns_recend;
+ struct mbuf *ns_frag;
+ int ns_flag;
+ int ns_solock;
+ int ns_cc;
+ int ns_reclen;
+ int ns_numuids;
+ u_long ns_sref;
+ LIST_HEAD(, nfsrv_descript) ns_tq; /* Write gather lists */
+ LIST_HEAD(, nfsuid) ns_uidhashtbl[NFS_UIDHASHSIZ];
+ LIST_HEAD(nfsrvw_delayhash, nfsrv_descript) ns_wdelayhashtbl[NFS_WDELAYHASHSIZ];
+};
+
+/* Bits for "ns_flag" */
+#define SLP_VALID 0x01
+#define SLP_DOREC 0x02
+#define SLP_NEEDQ 0x04
+#define SLP_DISCONN 0x08
+#define SLP_GETSTREAM 0x10
+#define SLP_LASTFRAG 0x20
+#define SLP_ALLFLAGS 0xff
+
+extern TAILQ_HEAD(nfssvc_sockhead, nfssvc_sock) nfssvc_sockhead;
+extern int nfssvc_sockhead_flag;
+#define SLP_INIT 0x01
+#define SLP_WANTINIT 0x02
+
+/*
+ * One of these structures is allocated for each nfsd.
+ */
+struct nfsd {
+ TAILQ_ENTRY(nfsd) nfsd_chain; /* List of all nfsd's */
+ int nfsd_flag; /* NFSD_ flags */
+ struct nfssvc_sock *nfsd_slp; /* Current socket */
+ int nfsd_authlen; /* Authenticator len */
+ u_char nfsd_authstr[RPCAUTH_MAXSIZ]; /* Authenticator data */
+ int nfsd_verflen; /* and the Verifier */
+ u_char nfsd_verfstr[RPCVERF_MAXSIZ];
+ struct proc *nfsd_procp; /* Proc ptr */
+ struct nfsrv_descript *nfsd_nd; /* Associated nfsrv_descript */
+};
+
+/* Bits for "nfsd_flag" */
+#define NFSD_WAITING 0x01
+#define NFSD_REQINPROG 0x02
+#define NFSD_NEEDAUTH 0x04
+#define NFSD_AUTHFAIL 0x08
+
+/*
+ * This structure is used by the server for describing each request.
+ * Some fields are used only when write request gathering is performed.
+ */
+struct nfsrv_descript {
+ u_quad_t nd_time; /* Write deadline (usec) */
+ off_t nd_off; /* Start byte offset */
+ off_t nd_eoff; /* and end byte offset */
+ LIST_ENTRY(nfsrv_descript) nd_hash; /* Hash list */
+ LIST_ENTRY(nfsrv_descript) nd_tq; /* and timer list */
+ LIST_HEAD(,nfsrv_descript) nd_coalesce; /* coalesced writes */
+ struct mbuf *nd_mrep; /* Request mbuf list */
+ struct mbuf *nd_md; /* Current dissect mbuf */
+ struct mbuf *nd_mreq; /* Reply mbuf list */
+ struct mbuf *nd_nam; /* and socket addr */
+ struct mbuf *nd_nam2; /* return socket addr */
+ caddr_t nd_dpos; /* Current dissect pos */
+ int nd_procnum; /* RPC # */
+ int nd_stable; /* storage type */
+ int nd_flag; /* nd_flag */
+ int nd_len; /* Length of this write */
+ int nd_repstat; /* Reply status */
+ u_long nd_retxid; /* Reply xid */
+ u_long nd_duration; /* Lease duration */
+ struct timeval nd_starttime; /* Time RPC initiated */
+ fhandle_t nd_fh; /* File handle */
+ struct ucred nd_cr; /* Credentials */
+};
+
+/* Bits for "nd_flag" */
+#define ND_READ LEASE_READ
+#define ND_WRITE LEASE_WRITE
+#define ND_CHECK 0x04
+#define ND_LEASE (ND_READ | ND_WRITE | ND_CHECK)
+#define ND_NFSV3 0x08
+#define ND_NQNFS 0x10
+#define ND_KERBNICK 0x20
+#define ND_KERBFULL 0x40
+#define ND_KERBAUTH (ND_KERBNICK | ND_KERBFULL)
+
+extern TAILQ_HEAD(nfsd_head, nfsd) nfsd_head;
+extern int nfsd_head_flag;
+#define NFSD_CHECKSLP 0x01
+
+/*
+ * These macros compare nfsrv_descript structures.
+ */
+#define NFSW_CONTIG(o, n) \
+ ((o)->nd_eoff >= (n)->nd_off && \
+ !bcmp((caddr_t)&(o)->nd_fh, (caddr_t)&(n)->nd_fh, NFSX_V3FH))
+
+#define NFSW_SAMECRED(o, n) \
+ (((o)->nd_flag & ND_KERBAUTH) == ((n)->nd_flag & ND_KERBAUTH) && \
+ !bcmp((caddr_t)&(o)->nd_cr, (caddr_t)&(n)->nd_cr, \
+ sizeof (struct ucred)))
+
+int nfs_reply __P((struct nfsreq *));
+int nfs_getreq __P((struct nfsrv_descript *,struct nfsd *,int));
+int nfs_send __P((struct socket *,struct mbuf *,struct mbuf *,struct nfsreq *));
+int nfs_rephead __P((int,struct nfsrv_descript *,struct nfssvc_sock *,int,int,u_quad_t *,struct mbuf **,struct mbuf **,caddr_t *));
+int nfs_sndlock __P((int *,struct nfsreq *));
+void nfs_sndunlock __P((int *flagp));
+int nfs_disct __P((struct mbuf **,caddr_t *,int,int,caddr_t *));
+int nfs_vinvalbuf __P((struct vnode *,int,struct ucred *,struct proc *,int));
+int nfs_readrpc __P((struct vnode *,struct uio *,struct ucred *));
+int nfs_writerpc __P((struct vnode *,struct uio *,struct ucred *,int *,int *));
+int nfs_readdirrpc __P((register struct vnode *,struct uio *,struct ucred *));
+int nfs_asyncio __P((struct buf *,struct ucred *));
+int nfs_doio __P((struct buf *,struct ucred *,struct proc *));
+int nfs_readlinkrpc __P((struct vnode *,struct uio *,struct ucred *));
+int nfs_sigintr __P((struct nfsmount *,struct nfsreq *r,struct proc *));
+int nfs_readdirplusrpc __P((struct vnode *,register struct uio *,struct ucred *));
+int nfsm_disct __P((struct mbuf **,caddr_t *,int,int,caddr_t *));
+void nfsm_srvfattr __P((struct nfsrv_descript *,struct vattr *,struct nfs_fattr *));
+void nfsm_srvwcc __P((struct nfsrv_descript *,int,struct vattr *,int,struct vattr *,struct mbuf **,char **));
+void nfsm_srvpostopattr __P((struct nfsrv_descript *,int,struct vattr *,struct mbuf **,char **));
+int netaddr_match __P((int,union nethostaddr *,struct mbuf *));
+int nfs_request __P((struct vnode *,struct mbuf *,int,struct proc *,struct ucred *,struct mbuf **,struct mbuf **,caddr_t *));
+int nfs_loadattrcache __P((struct vnode **,struct mbuf **,caddr_t *,struct vattr *));
+int nfs_namei __P((struct nameidata *,fhandle_t *,int,struct nfssvc_sock *,struct mbuf *,struct mbuf **,caddr_t *,struct vnode **,struct proc *,int));
+void nfsm_adj __P((struct mbuf *,int,int));
+int nfsm_mbuftouio __P((struct mbuf **,struct uio *,int,caddr_t *));
+void nfsrv_initcache __P((void));
+int nfs_getauth __P((struct nfsmount *,struct nfsreq *,struct ucred *,char **,int *,char *,int *,NFSKERBKEY_T));
+int nfs_getnickauth __P((struct nfsmount *,struct ucred *,char **,int *,char *,int));
+int nfs_savenickauth __P((struct nfsmount *,struct ucred *,int,NFSKERBKEY_T,struct mbuf **,char **,struct mbuf *));
+int nfs_adv __P((struct mbuf **,caddr_t *,int,int));
+void nfs_nhinit __P((void));
+void nfs_timer __P((void*));
+u_long nfs_hash __P((nfsfh_t *,int));
+void nfsrv_slpderef __P((struct nfssvc_sock *slp));
+int nfsrv_dorec __P((struct nfssvc_sock *,struct nfsd *,struct nfsrv_descript **));
+void nfsrv_cleancache __P((void));
+int nfsrv_getcache __P((struct nfsrv_descript *,struct nfssvc_sock *,struct mbuf **));
+int nfs_init __P((void));
+void nfsrv_updatecache __P((struct nfsrv_descript *,int,struct mbuf *));
+int nfs_connect __P((struct nfsmount *,struct nfsreq *));
+void nfs_disconnect __P((struct nfsmount *nmp));
+int nfs_getattrcache __P((struct vnode *,struct vattr *));
+int nfsm_strtmbuf __P((struct mbuf **,char **,char *,long));
+int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *, int getpages));
+int nfsm_uiotombuf __P((struct uio *,struct mbuf **,int,caddr_t *));
+void nfsrv_init __P((int));
+void nfs_clearcommit __P((struct mount *));
+int nfsrv_errmap __P((struct nfsrv_descript *, int));
+void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
+void nfsrvw_sort __P((gid_t [],int));
+void nfsrv_setcred __P((struct ucred *,struct ucred *));
+int nfs_writebp __P((struct buf *,int));
+int nfsrv_object_create __P(( struct vnode * ));
+void nfsrv_wakenfsd __P((struct nfssvc_sock *slp));
+int nfsrv_writegather __P((struct nfsrv_descript **, struct nfssvc_sock *,
+ struct proc *, struct mbuf **));
+int nfs_fsinfo __P((struct nfsmount *, struct vnode *, struct ucred *,
+ struct proc *p));
+
+int nfsrv3_access __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_commit __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_create __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_fhtovp __P((fhandle_t *,int,struct vnode **,
+ struct ucred *,struct nfssvc_sock *,struct mbuf *,
+ int *,int));
+int nfsrv_fsinfo __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_getattr __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_link __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_lookup __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_mkdir __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_mknod __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_noop __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_null __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_pathconf __P((struct nfsrv_descript *nfsd,
+ struct nfssvc_sock *slp, struct proc *procp,
+ struct mbuf **mrq));
+int nfsrv_read __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_readdir __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_readdirplus __P((struct nfsrv_descript *nfsd,
+ struct nfssvc_sock *slp, struct proc *procp,
+ struct mbuf **mrq));
+int nfsrv_readlink __P((struct nfsrv_descript *nfsd,
+ struct nfssvc_sock *slp, struct proc *procp,
+ struct mbuf **mrq));
+int nfsrv_remove __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_rename __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_rmdir __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_setattr __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_statfs __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_symlink __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
+ struct proc *procp, struct mbuf **mrq));
+
+#ifdef NFS_DEBUG
+
+extern int nfs_debug;
+#define NFS_DEBUG_ASYNCIO 1 /* asynchronous i/o */
+#define NFS_DEBUG_WG 2 /* server write gathering */
+#define NFS_DEBUG_RC 4 /* server request caching */
+
+#define NFS_DPF(cat, args) \
+ do { \
+ if (nfs_debug & NFS_DEBUG_##cat) printf args; \
+ } while (0)
+
+#else
+
+#define NFS_DPF(cat, args)
+
+#endif
+
+#endif /* _KERNEL */
+
+#endif
diff --git a/cpukit/libnetworking/nfs/nfsproto.h b/cpukit/libnetworking/nfs/nfsproto.h
new file mode 100644
index 0000000000..9c937068a2
--- /dev/null
+++ b/cpukit/libnetworking/nfs/nfsproto.h
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)nfsproto.h 8.2 (Berkeley) 3/30/95
+ * $FreeBSD: src/sys/nfs/nfsproto.h,v 1.11 2005/01/07 01:45:50 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NFS_NFSPROTO_H_
+#define _NFS_NFSPROTO_H_
+
+/*
+ * nfs definitions as per the Version 2 and 3 specs
+ */
+
+/*
+ * Constants as defined in the Sun NFS Version 2 and 3 specs.
+ * "NFS: Network File System Protocol Specification" RFC1094
+ * and in the "NFS: Network File System Version 3 Protocol
+ * Specification"
+ */
+
+#define NFS_PORT 2049
+#define NFS_PROG 100003
+#define NFS_VER2 2
+#define NFS_VER3 3
+#define NFS_V2MAXDATA 8192
+#define NFS_MAXDGRAMDATA 16384
+#define NFS_MAXDATA 32768
+#define NFS_MAXPATHLEN 1024
+#define NFS_MAXNAMLEN 255
+#define NFS_MAXPKTHDR 404
+#define NFS_MAXPACKET (NFS_MAXPKTHDR + NFS_MAXDATA)
+#define NFS_MINPACKET 20
+#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */
+
+/* Stat numbers for rpc returns (version 2 and 3) */
+#define NFS_OK 0
+#define NFSERR_PERM 1
+#define NFSERR_NOENT 2
+#define NFSERR_IO 5
+#define NFSERR_NXIO 6
+#define NFSERR_ACCES 13
+#define NFSERR_EXIST 17
+#define NFSERR_XDEV 18 /* Version 3 only */
+#define NFSERR_NODEV 19
+#define NFSERR_NOTDIR 20
+#define NFSERR_ISDIR 21
+#define NFSERR_INVAL 22 /* Version 3 only */
+#define NFSERR_FBIG 27
+#define NFSERR_NOSPC 28
+#define NFSERR_ROFS 30
+#define NFSERR_MLINK 31 /* Version 3 only */
+#define NFSERR_NAMETOL 63
+#define NFSERR_NOTEMPTY 66
+#define NFSERR_DQUOT 69
+#define NFSERR_STALE 70
+#define NFSERR_REMOTE 71 /* Version 3 only */
+#define NFSERR_WFLUSH 99 /* Version 2 only */
+#define NFSERR_BADHANDLE 10001 /* The rest Version 3, 4 only */
+#define NFSERR_NOT_SYNC 10002
+#define NFSERR_BAD_COOKIE 10003
+#define NFSERR_NOTSUPP 10004
+#define NFSERR_TOOSMALL 10005
+#define NFSERR_SERVERFAULT 10006
+#define NFSERR_BADTYPE 10007
+#define NFSERR_JUKEBOX 10008
+#define NFSERR_TRYLATER NFSERR_JUKEBOX
+#define NFSERR_STALEWRITEVERF 30001 /* Fake return for nfs_commit() */
+
+
+
+#define NFSERR_RETVOID 0x20000000 /* Return void, not error */
+#define NFSERR_AUTHERR 0x40000000 /* Mark an authentication error */
+#define NFSERR_RETERR 0x80000000 /* Mark an error return for V3 */
+
+/* Sizes in bytes of various nfs rpc components */
+#define NFSX_UNSIGNED 4
+
+/* specific to NFS Version 2 */
+#define NFSX_V2FH 32
+#define NFSX_V2FATTR 68
+#define NFSX_V2SATTR 32
+#define NFSX_V2COOKIE 4
+#define NFSX_V2STATFS 20
+
+/* specific to NFS Version 3 */
+#define NFSX_V3FH (sizeof (fhandle_t)) /* size this server uses */
+#define NFSX_V3FHMAX 64 /* max. allowed by protocol */
+#define NFSX_V3FATTR 84
+#define NFSX_V3SATTR 60 /* max. all fields filled in */
+#define NFSX_V3SRVSATTR (sizeof (struct nfsv3_sattr))
+#define NFSX_V3POSTOPATTR (NFSX_V3FATTR + NFSX_UNSIGNED)
+#define NFSX_V3WCCDATA (NFSX_V3POSTOPATTR + 8 * NFSX_UNSIGNED)
+#define NFSX_V3COOKIEVERF 8
+#define NFSX_V3WRITEVERF 8
+#define NFSX_V3CREATEVERF 8
+#define NFSX_V3STATFS 52
+#define NFSX_V3FSINFO 48
+#define NFSX_V3PATHCONF 24
+
+/* variants for both versions */
+#define NFSX_FH(v3) ((v3) ? (NFSX_V3FHMAX + NFSX_UNSIGNED) : \
+ NFSX_V2FH)
+#define NFSX_SRVFH(v3) ((v3) ? NFSX_V3FH : NFSX_V2FH)
+#define NFSX_FATTR(v3) ((v3) ? NFSX_V3FATTR : NFSX_V2FATTR)
+#define NFSX_PREOPATTR(v3) ((v3) ? (7 * NFSX_UNSIGNED) : 0)
+#define NFSX_POSTOPATTR(v3) ((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : 0)
+#define NFSX_POSTOPORFATTR(v3) ((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : \
+ NFSX_V2FATTR)
+#define NFSX_WCCDATA(v3) ((v3) ? NFSX_V3WCCDATA : 0)
+#define NFSX_WCCORFATTR(v3) ((v3) ? NFSX_V3WCCDATA : NFSX_V2FATTR)
+#define NFSX_SATTR(v3) ((v3) ? NFSX_V3SATTR : NFSX_V2SATTR)
+#define NFSX_COOKIEVERF(v3) ((v3) ? NFSX_V3COOKIEVERF : 0)
+#define NFSX_WRITEVERF(v3) ((v3) ? NFSX_V3WRITEVERF : 0)
+#define NFSX_READDIR(v3) ((v3) ? (5 * NFSX_UNSIGNED) : \
+ (2 * NFSX_UNSIGNED))
+#define NFSX_STATFS(v3) ((v3) ? NFSX_V3STATFS : NFSX_V2STATFS)
+
+/* nfs rpc procedure numbers (before version mapping) */
+#define NFSPROC_NULL 0
+#define NFSPROC_GETATTR 1
+#define NFSPROC_SETATTR 2
+#define NFSPROC_LOOKUP 3
+#define NFSPROC_ACCESS 4
+#define NFSPROC_READLINK 5
+#define NFSPROC_READ 6
+#define NFSPROC_WRITE 7
+#define NFSPROC_CREATE 8
+#define NFSPROC_MKDIR 9
+#define NFSPROC_SYMLINK 10
+#define NFSPROC_MKNOD 11
+#define NFSPROC_REMOVE 12
+#define NFSPROC_RMDIR 13
+#define NFSPROC_RENAME 14
+#define NFSPROC_LINK 15
+#define NFSPROC_READDIR 16
+#define NFSPROC_READDIRPLUS 17
+#define NFSPROC_FSSTAT 18
+#define NFSPROC_FSINFO 19
+#define NFSPROC_PATHCONF 20
+#define NFSPROC_COMMIT 21
+#define NFSPROC_NOOP 22
+#define NFS_NPROCS 23
+
+/* Actual Version 2 procedure numbers */
+#define NFSV2PROC_NULL 0
+#define NFSV2PROC_GETATTR 1
+#define NFSV2PROC_SETATTR 2
+#define NFSV2PROC_NOOP 3
+#define NFSV2PROC_ROOT NFSV2PROC_NOOP /* Obsolete */
+#define NFSV2PROC_LOOKUP 4
+#define NFSV2PROC_READLINK 5
+#define NFSV2PROC_READ 6
+#define NFSV2PROC_WRITECACHE NFSV2PROC_NOOP /* Obsolete */
+#define NFSV2PROC_WRITE 8
+#define NFSV2PROC_CREATE 9
+#define NFSV2PROC_REMOVE 10
+#define NFSV2PROC_RENAME 11
+#define NFSV2PROC_LINK 12
+#define NFSV2PROC_SYMLINK 13
+#define NFSV2PROC_MKDIR 14
+#define NFSV2PROC_RMDIR 15
+#define NFSV2PROC_READDIR 16
+#define NFSV2PROC_STATFS 17
+
+/*
+ * Constants used by the Version 3 protocol for various RPCs
+ */
+#define NFSV3SATTRTIME_DONTCHANGE 0
+#define NFSV3SATTRTIME_TOSERVER 1
+#define NFSV3SATTRTIME_TOCLIENT 2
+
+#define NFSV3ACCESS_READ 0x01
+#define NFSV3ACCESS_LOOKUP 0x02
+#define NFSV3ACCESS_MODIFY 0x04
+#define NFSV3ACCESS_EXTEND 0x08
+#define NFSV3ACCESS_DELETE 0x10
+#define NFSV3ACCESS_EXECUTE 0x20
+
+#define NFSV3WRITE_UNSTABLE 0
+#define NFSV3WRITE_DATASYNC 1
+#define NFSV3WRITE_FILESYNC 2
+
+#define NFSV3CREATE_UNCHECKED 0
+#define NFSV3CREATE_GUARDED 1
+#define NFSV3CREATE_EXCLUSIVE 2
+
+#define NFSV3FSINFO_LINK 0x01
+#define NFSV3FSINFO_SYMLINK 0x02
+#define NFSV3FSINFO_HOMOGENEOUS 0x08
+#define NFSV3FSINFO_CANSETTIME 0x10
+
+/* File types */
+typedef enum { NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5,
+ NFSOCK=6, NFFIFO=7 } nfstype;
+
+/* Structs for common parts of the rpc's */
+/*
+ * File Handle (32 bytes for version 2), variable up to 64 for version 3.
+ * File Handles of up to NFS_SMALLFH in size are stored directly in the
+ * nfs node, whereas larger ones are malloc'd. (This never happens when
+ * NFS_SMALLFH is set to 64.)
+ * NFS_SMALLFH should be in the range of 32 to 64 and be divisible by 4.
+ */
+#ifndef NFS_SMALLFH
+#define NFS_SMALLFH 64
+#endif
+union nfsfh {
+ fhandle_t fh_generic;
+ u_char fh_bytes[NFS_SMALLFH];
+};
+typedef union nfsfh nfsfh_t;
+
+struct nfsv2_time {
+ u_int32_t nfsv2_sec;
+ u_int32_t nfsv2_usec;
+};
+typedef struct nfsv2_time nfstime2;
+
+struct nfsv3_time {
+ u_int32_t nfsv3_sec;
+ u_int32_t nfsv3_nsec;
+};
+typedef struct nfsv3_time nfstime3;
+
+/*
+ * Quads are defined as arrays of 2 longs to ensure dense packing for the
+ * protocol and to facilitate xdr conversion.
+ */
+struct nfs_uquad {
+ u_int32_t nfsuquad[2];
+};
+typedef struct nfs_uquad nfsuint64;
+
+/*
+ * Used to convert between two u_longs and a u_quad_t.
+ */
+union nfs_quadconvert {
+ u_int32_t lval[2];
+ u_quad_t qval;
+};
+typedef union nfs_quadconvert nfsquad_t;
+
+/*
+ * NFS Version 3 special file number.
+ */
+struct nfsv3_spec {
+ u_int32_t specdata1;
+ u_int32_t specdata2;
+};
+typedef struct nfsv3_spec nfsv3spec;
+
+/*
+ * File attributes and setable attributes. These structures cover both
+ * NFS version 2 and the version 3 protocol. Note that the union is only
+ * used so that one pointer can refer to both variants. These structures
+ * go out on the wire and must be densely packed, so no quad data types
+ * are used. (all fields are longs or u_longs or structures of same)
+ * NB: You can't do sizeof(struct nfs_fattr), you must use the
+ * NFSX_FATTR(v3) macro.
+ */
+struct nfs_fattr {
+ u_int32_t fa_type;
+ u_int32_t fa_mode;
+ u_int32_t fa_nlink;
+ u_int32_t fa_uid;
+ u_int32_t fa_gid;
+ union {
+ struct {
+ u_int32_t nfsv2fa_size;
+ u_int32_t nfsv2fa_blocksize;
+ u_int32_t nfsv2fa_rdev;
+ u_int32_t nfsv2fa_blocks;
+ u_int32_t nfsv2fa_fsid;
+ u_int32_t nfsv2fa_fileid;
+ nfstime2 nfsv2fa_atime;
+ nfstime2 nfsv2fa_mtime;
+ nfstime2 nfsv2fa_ctime;
+ } fa_nfsv2;
+ struct {
+ nfsuint64 nfsv3fa_size;
+ nfsuint64 nfsv3fa_used;
+ nfsv3spec nfsv3fa_rdev;
+ nfsuint64 nfsv3fa_fsid;
+ nfsuint64 nfsv3fa_fileid;
+ nfstime3 nfsv3fa_atime;
+ nfstime3 nfsv3fa_mtime;
+ nfstime3 nfsv3fa_ctime;
+ } fa_nfsv3;
+ } fa_un;
+};
+
+/* and some ugly defines for accessing union components */
+#define fa2_size fa_un.fa_nfsv2.nfsv2fa_size
+#define fa2_blocksize fa_un.fa_nfsv2.nfsv2fa_blocksize
+#define fa2_rdev fa_un.fa_nfsv2.nfsv2fa_rdev
+#define fa2_blocks fa_un.fa_nfsv2.nfsv2fa_blocks
+#define fa2_fsid fa_un.fa_nfsv2.nfsv2fa_fsid
+#define fa2_fileid fa_un.fa_nfsv2.nfsv2fa_fileid
+#define fa2_atime fa_un.fa_nfsv2.nfsv2fa_atime
+#define fa2_mtime fa_un.fa_nfsv2.nfsv2fa_mtime
+#define fa2_ctime fa_un.fa_nfsv2.nfsv2fa_ctime
+#define fa3_size fa_un.fa_nfsv3.nfsv3fa_size
+#define fa3_used fa_un.fa_nfsv3.nfsv3fa_used
+#define fa3_rdev fa_un.fa_nfsv3.nfsv3fa_rdev
+#define fa3_fsid fa_un.fa_nfsv3.nfsv3fa_fsid
+#define fa3_fileid fa_un.fa_nfsv3.nfsv3fa_fileid
+#define fa3_atime fa_un.fa_nfsv3.nfsv3fa_atime
+#define fa3_mtime fa_un.fa_nfsv3.nfsv3fa_mtime
+#define fa3_ctime fa_un.fa_nfsv3.nfsv3fa_ctime
+
+struct nfsv2_sattr {
+ u_int32_t sa_mode;
+ u_int32_t sa_uid;
+ u_int32_t sa_gid;
+ u_int32_t sa_size;
+ nfstime2 sa_atime;
+ nfstime2 sa_mtime;
+};
+
+/*
+ * NFS Version 3 sattr structure for the new node creation case.
+ */
+struct nfsv3_sattr {
+ u_int32_t sa_modetrue;
+ u_int32_t sa_mode;
+ u_int32_t sa_uidfalse;
+ u_int32_t sa_gidfalse;
+ u_int32_t sa_sizefalse;
+ u_int32_t sa_atimetype;
+ nfstime3 sa_atime;
+ u_int32_t sa_mtimetype;
+ nfstime3 sa_mtime;
+};
+
+struct nfs_statfs {
+ union {
+ struct {
+ u_int32_t nfsv2sf_tsize;
+ u_int32_t nfsv2sf_bsize;
+ u_int32_t nfsv2sf_blocks;
+ u_int32_t nfsv2sf_bfree;
+ u_int32_t nfsv2sf_bavail;
+ } sf_nfsv2;
+ struct {
+ nfsuint64 nfsv3sf_tbytes;
+ nfsuint64 nfsv3sf_fbytes;
+ nfsuint64 nfsv3sf_abytes;
+ nfsuint64 nfsv3sf_tfiles;
+ nfsuint64 nfsv3sf_ffiles;
+ nfsuint64 nfsv3sf_afiles;
+ u_int32_t nfsv3sf_invarsec;
+ } sf_nfsv3;
+ } sf_un;
+};
+
+#define sf_tsize sf_un.sf_nfsv2.nfsv2sf_tsize
+#define sf_bsize sf_un.sf_nfsv2.nfsv2sf_bsize
+#define sf_blocks sf_un.sf_nfsv2.nfsv2sf_blocks
+#define sf_bfree sf_un.sf_nfsv2.nfsv2sf_bfree
+#define sf_bavail sf_un.sf_nfsv2.nfsv2sf_bavail
+#define sf_tbytes sf_un.sf_nfsv3.nfsv3sf_tbytes
+#define sf_fbytes sf_un.sf_nfsv3.nfsv3sf_fbytes
+#define sf_abytes sf_un.sf_nfsv3.nfsv3sf_abytes
+#define sf_tfiles sf_un.sf_nfsv3.nfsv3sf_tfiles
+#define sf_ffiles sf_un.sf_nfsv3.nfsv3sf_ffiles
+#define sf_afiles sf_un.sf_nfsv3.nfsv3sf_afiles
+#define sf_invarsec sf_un.sf_nfsv3.nfsv3sf_invarsec
+
+struct nfsv3_fsinfo {
+ u_int32_t fs_rtmax;
+ u_int32_t fs_rtpref;
+ u_int32_t fs_rtmult;
+ u_int32_t fs_wtmax;
+ u_int32_t fs_wtpref;
+ u_int32_t fs_wtmult;
+ u_int32_t fs_dtpref;
+ nfsuint64 fs_maxfilesize;
+ nfstime3 fs_timedelta;
+ u_int32_t fs_properties;
+};
+
+struct nfsv3_pathconf {
+ u_int32_t pc_linkmax;
+ u_int32_t pc_namemax;
+ u_int32_t pc_notrunc;
+ u_int32_t pc_chownrestricted;
+ u_int32_t pc_caseinsensitive;
+ u_int32_t pc_casepreserving;
+};
+
+#endif
diff --git a/cpukit/libnetworking/nfs/rpcv2.h b/cpukit/libnetworking/nfs/rpcv2.h
new file mode 100644
index 0000000000..c8a41698e7
--- /dev/null
+++ b/cpukit/libnetworking/nfs/rpcv2.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)rpcv2.h 8.2 (Berkeley) 3/30/95
+ * $FreeBSD: src/sys/nfs/rpcv2.h,v 1.14 2005/01/07 01:45:50 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NFS_RPCV2_H_
+#define _NFS_RPCV2_H_
+
+/*
+ * Definitions for Sun RPC Version 2, from
+ * "RPC: Remote Procedure Call Protocol Specification" RFC1057
+ */
+
+/* Version # */
+#define RPC_VER2 2
+
+/* Authentication */
+#define RPCAUTH_NULL 0
+#define RPCAUTH_UNIX 1
+#define RPCAUTH_SHORT 2
+#define RPCAUTH_KERB4 4
+#define RPCAUTH_MAXSIZ 400
+#define RPCVERF_MAXSIZ 12 /* For Kerb, can actually be 400 */
+#define RPCAUTH_UNIXGIDS 16
+
+/*
+ * Constants associated with authentication flavours.
+ */
+#define RPCAKN_FULLNAME 0
+#define RPCAKN_NICKNAME 1
+
+/* msg type */
+#define RPC_CALL 0
+#define RPC_REPLY 1
+
+/* reply status */
+#define RPC_MSGACCEPTED 0
+#define RPC_MSGDENIED 1
+
+/* accepted status */
+#define RPC_SUCCESS 0
+#define RPC_PROGUNAVAIL 1
+#define RPC_PROGMISMATCH 2
+#define RPC_PROCUNAVAIL 3
+#define RPC_GARBAGE 4 /* I like this one */
+#define RPC_SYSTEMERR 5
+
+/* rejected status */
+#define RPC_MISMATCH 0
+#define RPC_AUTHERR 1
+
+/* Authentication failures */
+#define AUTH_OK 0
+#define AUTH_BADCRED 1
+#define AUTH_REJECTCRED 2
+#define AUTH_BADVERF 3
+#define AUTH_REJECTVERF 4
+#define AUTH_TOOWEAK 5 /* Give em wheaties */
+
+/* Sizes of rpc header parts */
+#define RPC_SIZ 24
+#define RPC_REPLYSIZ 28
+
+/* RPC Prog definitions */
+#define RPCPROG_MNT 100005
+#define RPCMNT_VER1 1
+#define RPCMNT_VER3 3
+#define RPCMNT_MOUNT 1
+#define RPCMNT_DUMP 2
+#define RPCMNT_UMOUNT 3
+#define RPCMNT_UMNTALL 4
+#define RPCMNT_EXPORT 5
+#define RPCMNT_NAMELEN 255
+#define RPCMNT_PATHLEN 1024
+#define RPCPROG_NFS 100003
+
+#endif
diff --git a/cpukit/libnetworking/nfs/xdr_subs.h b/cpukit/libnetworking/nfs/xdr_subs.h
new file mode 100644
index 0000000000..62358a57ea
--- /dev/null
+++ b/cpukit/libnetworking/nfs/xdr_subs.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)xdr_subs.h 8.3 (Berkeley) 3/30/95
+ * $FreeBSD: src/sys/nfs/xdr_subs.h,v 1.15 2005/01/07 01:45:50 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NFS_XDR_SUBS_H_
+#define _NFS_XDR_SUBS_H_
+
+/*
+ * Macros used for conversion to/from xdr representation by nfs...
+ * These use the MACHINE DEPENDENT routines ntohl, htonl
+ * As defined by "XDR: External Data Representation Standard" RFC1014
+ *
+ * To simplify the implementation, we use ntohl/htonl even on big-endian
+ * machines, and count on them being `#define'd away. Some of these
+ * might be slightly more efficient as quad_t copies on a big-endian,
+ * but we cannot count on their alignment anyway.
+ */
+
+#define fxdr_unsigned(t, v) ((t)ntohl((int32_t)(v)))
+#define txdr_unsigned(v) (htonl((int32_t)(v)))
+
+#define fxdr_nfsv2time(f, t) { \
+ (t)->tv_sec = ntohl(((struct nfsv2_time *)(f))->nfsv2_sec); \
+ if (((struct nfsv2_time *)(f))->nfsv2_usec != 0xffffffff) \
+ (t)->tv_nsec = 1000 * ntohl(((struct nfsv2_time *)(f))->nfsv2_usec); \
+ else \
+ (t)->tv_nsec = 0; \
+}
+#define txdr_nfsv2time(f, t) { \
+ ((struct nfsv2_time *)(t))->nfsv2_sec = htonl((f)->tv_sec); \
+ if ((f)->tv_nsec != -1) \
+ ((struct nfsv2_time *)(t))->nfsv2_usec = htonl((f)->tv_nsec / 1000); \
+ else \
+ ((struct nfsv2_time *)(t))->nfsv2_usec = 0xffffffff; \
+}
+
+#define fxdr_nfsv3time(f, t) { \
+ (t)->tv_sec = ntohl(((struct nfsv3_time *)(f))->nfsv3_sec); \
+ (t)->tv_nsec = ntohl(((struct nfsv3_time *)(f))->nfsv3_nsec); \
+}
+#define txdr_nfsv3time(f, t) { \
+ ((struct nfsv3_time *)(t))->nfsv3_sec = htonl((f)->tv_sec); \
+ ((struct nfsv3_time *)(t))->nfsv3_nsec = htonl((f)->tv_nsec); \
+}
+
+#define fxdr_hyper(f) \
+ ((((u_quad_t)ntohl(((u_int32_t *)(f))[0])) << 32) | \
+ (u_quad_t)(ntohl(((u_int32_t *)(f))[1])))
+#define txdr_hyper(f, t) \
+do { \
+ ((u_int32_t *)(t))[0] = htonl((u_int32_t)((f) >> 32)); \
+ ((u_int32_t *)(t))[1] = htonl((u_int32_t)((f) & 0xffffffff)); \
+} while (0)
+
+#endif
diff --git a/cpukit/libnetworking/nfsclient/nfsargs.h b/cpukit/libnetworking/nfsclient/nfsargs.h
new file mode 100644
index 0000000000..697ee0c59d
--- /dev/null
+++ b/cpukit/libnetworking/nfsclient/nfsargs.h
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 1989, 1993, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)nfs.h 8.4 (Berkeley) 5/1/95
+ * $FreeBSD: src/sys/nfsclient/nfsargs.h,v 1.67 2005/01/07 01:45:51 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _NFSCLIENT_NFSARGS_H_
+#define _NFSCLIENT_NFSARGS_H_
+
+/*
+ * Arguments to mount NFS
+ */
+struct nfs_args {
+ struct sockaddr *addr; /* file server address */
+ int addrlen; /* length of address */
+ int sotype; /* Socket type */
+ int proto; /* and Protocol */
+ u_char *fh; /* File handle to be mounted */
+ int fhsize; /* Size, in bytes, of fh */
+ int flags; /* flags */
+ int wsize; /* write size in bytes */
+ int rsize; /* read size in bytes */
+ int readdirsize; /* readdir size in bytes */
+ int timeo; /* initial timeout in .1 secs */
+ int retrans; /* times to retry send */
+ int maxgrouplist; /* Max. size of group list */
+ int readahead; /* # of blocks to readahead */
+ int leaseterm; /* Term (sec) of lease */
+ int deadthresh; /* Retrans threshold */
+ char *hostname; /* server's name */
+};
+
+/*
+ * NFS mount option flags
+ */
+#define NFSMNT_SOFT 0x00000001 /* soft mount (hard is default) */
+#define NFSMNT_WSIZE 0x00000002 /* set write size */
+#define NFSMNT_RSIZE 0x00000004 /* set read size */
+#define NFSMNT_TIMEO 0x00000008 /* set initial timeout */
+#define NFSMNT_RETRANS 0x00000010 /* set number of request retries */
+#define NFSMNT_MAXGRPS 0x00000020 /* set maximum grouplist size */
+#define NFSMNT_INT 0x00000040 /* allow interrupts on hard mount */
+#define NFSMNT_NOCONN 0x00000080 /* Don't Connect the socket */
+/* 0x100 free, was NFSMNT_NQNFS */
+#define NFSMNT_NFSV3 0x00000200 /* Use NFS Version 3 protocol */
+/* 0x400 free, was NFSMNT_KERB */
+#define NFSMNT_DUMBTIMR 0x00000800 /* Don't estimate rtt dynamically */
+/* 0x1000 free, was NFSMNT_LEASETERM */
+#define NFSMNT_READAHEAD 0x00002000 /* set read ahead */
+#define NFSMNT_DEADTHRESH 0x00004000 /* set dead server retry thresh */
+#define NFSMNT_RESVPORT 0x00008000 /* Allocate a reserved port */
+#define NFSMNT_RDIRPLUS 0x00010000 /* Use Readdirplus for V3 */
+#define NFSMNT_READDIRSIZE 0x00020000 /* Set readdir size */
+#define NFSMNT_ACREGMIN 0x00040000
+#define NFSMNT_ACREGMAX 0x00080000
+#define NFSMNT_ACDIRMIN 0x00100000
+#define NFSMNT_ACDIRMAX 0x00200000
+#define NFSMNT_NOLOCKD 0x00400000 /* Locks are local */
+#define NFSMNT_NFSV4 0x00800000 /* Use NFS Version 4 protocol */
+#define NFSMNT_HASWRITEVERF 0x01000000 /* NFSv4 Write verifier */
+
+#endif
diff --git a/cpukit/libnetworking/nfsclient/nfsdiskless.h b/cpukit/libnetworking/nfsclient/nfsdiskless.h
new file mode 100644
index 0000000000..0ed5c8f6f7
--- /dev/null
+++ b/cpukit/libnetworking/nfsclient/nfsdiskless.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * 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.
+ *
+ * @(#)nfsdiskless.h 8.1 (Berkeley) 6/10/93
+ * $Id$
+ */
+
+#ifndef _NFS_NFSDISKLESS_H_
+#define _NFS_NFSDISKLESS_H_
+
+/*
+ * Structure that must be initialized for a diskless nfs client.
+ * This structure is used by nfs_mountroot() to set up the root and swap
+ * vnodes plus do a partial ifconfig(8) and route(8) so that the critical net
+ * interface can communicate with the server.
+ * The primary bootstrap is expected to fill in the appropriate fields before
+ * starting the kernel. Whether or not the swap area is nfs mounted is determined
+ * by the value in swdevt[0]. (equal to NODEV --> swap over nfs)
+ * Currently only works for AF_INET protocols.
+ * NB: All fields are stored in net byte order to avoid hassles with
+ * client/server byte ordering differences.
+ */
+
+/*
+ * I have defined a new structure that can handle an NFS Version 3 file handle
+ * but the kernel still expects the old Version 2 one to be provided. The
+ * changes required in nfs_vfsops.c for using the new are documented there in
+ * comments. (I felt that breaking network booting code by changing this
+ * structure would not be prudent at this time, since almost all servers are
+ * still Version 2 anyhow.)
+ */
+struct nfsv3_diskless {
+ struct ifaliasreq myif; /* Default interface */
+ struct sockaddr_in mygateway; /* Default gateway */
+ struct nfs_args swap_args; /* Mount args for swap file */
+ int swap_fhsize; /* Size of file handle */
+ u_char swap_fh[NFSX_V3FHMAX]; /* Swap file's file handle */
+ struct sockaddr_in swap_saddr; /* Address of swap server */
+ char swap_hostnam[MNAMELEN]; /* Host name for mount pt */
+ int swap_nblks; /* Size of server swap file */
+ struct ucred swap_ucred; /* Swap credentials */
+ struct nfs_args root_args; /* Mount args for root fs */
+ int root_fhsize; /* Size of root file handle */
+ u_char root_fh[NFSX_V3FHMAX]; /* File handle of root dir */
+ struct sockaddr_in root_saddr; /* Address of root server */
+ char root_hostnam[MNAMELEN]; /* Host name for mount pt */
+ long root_time; /* Timestamp of root fs */
+ char my_hostnam[MAXHOSTNAMELEN]; /* Client host name */
+};
+
+struct nfs_diskless {
+ struct ifaliasreq myif; /* Default interface */
+ struct sockaddr_in mygateway; /* Default gateway */
+ struct nfs_args swap_args; /* Mount args for swap file */
+ u_char swap_fh[NFSX_V2FH]; /* Swap file's file handle */
+ struct sockaddr_in swap_saddr; /* Address of swap server */
+ char swap_hostnam[MNAMELEN]; /* Host name for mount pt */
+ int swap_nblks; /* Size of server swap file */
+ struct ucred swap_ucred; /* Swap credentials */
+ struct nfs_args root_args; /* Mount args for root fs */
+ u_char root_fh[NFSX_V2FH]; /* File handle of root dir */
+ struct sockaddr_in root_saddr; /* Address of root server */
+ char root_hostnam[MNAMELEN]; /* Host name for mount pt */
+ long root_time; /* Timestamp of root fs */
+ char my_hostnam[MAXHOSTNAMELEN]; /* Client host name */
+};
+
+#endif
diff --git a/cpukit/libnetworking/opt_atalk.h b/cpukit/libnetworking/opt_atalk.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/opt_atalk.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/opt_bdg.h b/cpukit/libnetworking/opt_bdg.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/opt_bdg.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/opt_compat.h b/cpukit/libnetworking/opt_compat.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/opt_compat.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/opt_inet.h b/cpukit/libnetworking/opt_inet.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/opt_inet.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/opt_inet6.h b/cpukit/libnetworking/opt_inet6.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/opt_inet6.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/opt_ipfw.h b/cpukit/libnetworking/opt_ipfw.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/opt_ipfw.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/opt_ipsec.h b/cpukit/libnetworking/opt_ipsec.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/opt_ipsec.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/opt_ipx.h b/cpukit/libnetworking/opt_ipx.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/opt_ipx.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/opt_mac.h b/cpukit/libnetworking/opt_mac.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/opt_mac.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/opt_mrouting.h b/cpukit/libnetworking/opt_mrouting.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/opt_mrouting.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/opt_netgraph.h b/cpukit/libnetworking/opt_netgraph.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/opt_netgraph.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/opt_ppp.h b/cpukit/libnetworking/opt_ppp.h
new file mode 100644
index 0000000000..d318f6a5f9
--- /dev/null
+++ b/cpukit/libnetworking/opt_ppp.h
@@ -0,0 +1,11 @@
+
+#ifndef _PPP_H_
+#define _PPP_H_
+
+#define NPPP 1
+#define NBPFILTER 0
+#undef VJC
+#undef PPP_FILTER
+#undef PPP_COMPRESS
+
+#endif
diff --git a/cpukit/libnetworking/opt_tcpdebug.h b/cpukit/libnetworking/opt_tcpdebug.h
new file mode 100644
index 0000000000..4c10d1bac2
--- /dev/null
+++ b/cpukit/libnetworking/opt_tcpdebug.h
@@ -0,0 +1,16 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
+
+/*
+ * Uncomment the following line to turn on debug code. When you define
+ * this symbol, tcp_trace() is called. If you want tcp_trace() to
+ * print, then you need to edit netinet/tcp_debug to set the variable
+ * "tcpconsdebug" to 1.
+ */
+
+/*
+#define TCPDEBUG
+*/
diff --git a/cpukit/libnetworking/poll.h b/cpukit/libnetworking/poll.h
new file mode 100644
index 0000000000..0287495599
--- /dev/null
+++ b/cpukit/libnetworking/poll.h
@@ -0,0 +1,6 @@
+#ifndef _POLL_H_
+#define _POLL_H_
+
+#include <sys/poll.h>
+
+#endif /* !_POLL_H_ */
diff --git a/cpukit/libnetworking/preinstall.am b/cpukit/libnetworking/preinstall.am
new file mode 100644
index 0000000000..0f26230449
--- /dev/null
+++ b/cpukit/libnetworking/preinstall.am
@@ -0,0 +1,471 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)
+ @: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
+
+if HAS_NETWORKING
+$(PROJECT_INCLUDE)/netdb.h: netdb.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netdb.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netdb.h
+
+$(PROJECT_INCLUDE)/resolv.h: resolv.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/resolv.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/resolv.h
+
+$(PROJECT_INCLUDE)/syslog.h: syslog.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/syslog.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/syslog.h
+
+$(PROJECT_INCLUDE)/arpa/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/arpa
+ @: > $(PROJECT_INCLUDE)/arpa/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/arpa/$(dirstamp)
+
+$(PROJECT_INCLUDE)/arpa/ftp.h: arpa/ftp.h $(PROJECT_INCLUDE)/arpa/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/arpa/ftp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/arpa/ftp.h
+
+$(PROJECT_INCLUDE)/arpa/inet.h: arpa/inet.h $(PROJECT_INCLUDE)/arpa/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/arpa/inet.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/arpa/inet.h
+
+$(PROJECT_INCLUDE)/arpa/nameser.h: arpa/nameser.h $(PROJECT_INCLUDE)/arpa/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/arpa/nameser.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/arpa/nameser.h
+
+$(PROJECT_INCLUDE)/arpa/nameser_compat.h: arpa/nameser_compat.h $(PROJECT_INCLUDE)/arpa/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/arpa/nameser_compat.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/arpa/nameser_compat.h
+
+$(PROJECT_INCLUDE)/machine/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/machine
+ @: > $(PROJECT_INCLUDE)/machine/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/machine/$(dirstamp)
+
+$(PROJECT_INCLUDE)/machine/conf.h: machine/conf.h $(PROJECT_INCLUDE)/machine/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/machine/conf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/machine/conf.h
+
+$(PROJECT_INCLUDE)/machine/cpu.h: machine/cpu.h $(PROJECT_INCLUDE)/machine/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/machine/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/machine/cpu.h
+
+$(PROJECT_INCLUDE)/machine/cpufunc.h: machine/cpufunc.h $(PROJECT_INCLUDE)/machine/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/machine/cpufunc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/machine/cpufunc.h
+
+$(PROJECT_INCLUDE)/machine/endian.h: machine/endian.h $(PROJECT_INCLUDE)/machine/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/machine/endian.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/machine/endian.h
+
+$(PROJECT_INCLUDE)/machine/in_cksum.h: machine/in_cksum.h $(PROJECT_INCLUDE)/machine/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/machine/in_cksum.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/machine/in_cksum.h
+
+$(PROJECT_INCLUDE)/machine/vmparam.h: machine/vmparam.h $(PROJECT_INCLUDE)/machine/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/machine/vmparam.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/machine/vmparam.h
+
+$(PROJECT_INCLUDE)/net/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/net
+ @: > $(PROJECT_INCLUDE)/net/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/net/$(dirstamp)
+
+$(PROJECT_INCLUDE)/net/bpf.h: net/bpf.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/bpf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/bpf.h
+
+$(PROJECT_INCLUDE)/net/ethernet.h: net/ethernet.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/ethernet.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/ethernet.h
+
+$(PROJECT_INCLUDE)/net/if.h: net/if.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/if.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/if.h
+
+$(PROJECT_INCLUDE)/net/if_arp.h: net/if_arp.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/if_arp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/if_arp.h
+
+$(PROJECT_INCLUDE)/net/if_dl.h: net/if_dl.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/if_dl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/if_dl.h
+
+$(PROJECT_INCLUDE)/net/if_llc.h: net/if_llc.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/if_llc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/if_llc.h
+
+$(PROJECT_INCLUDE)/net/if_ppp.h: net/if_ppp.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/if_ppp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/if_ppp.h
+
+$(PROJECT_INCLUDE)/net/if_types.h: net/if_types.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/if_types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/if_types.h
+
+$(PROJECT_INCLUDE)/net/if_var.h: net/if_var.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/if_var.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/if_var.h
+
+$(PROJECT_INCLUDE)/net/netisr.h: net/netisr.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/netisr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/netisr.h
+
+$(PROJECT_INCLUDE)/net/ppp-comp.h: net/ppp-comp.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/ppp-comp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/ppp-comp.h
+
+$(PROJECT_INCLUDE)/net/ppp_defs.h: net/ppp_defs.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/ppp_defs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/ppp_defs.h
+
+$(PROJECT_INCLUDE)/net/radix.h: net/radix.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/radix.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/radix.h
+
+$(PROJECT_INCLUDE)/net/raw_cb.h: net/raw_cb.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/raw_cb.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/raw_cb.h
+
+$(PROJECT_INCLUDE)/net/route.h: net/route.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/route.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/route.h
+
+$(PROJECT_INCLUDE)/net/if_pppvar.h: net/if_pppvar.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/if_pppvar.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/if_pppvar.h
+
+$(PROJECT_INCLUDE)/net/pppcompress.h: net/pppcompress.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/pppcompress.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/pppcompress.h
+
+$(PROJECT_INCLUDE)/net/slcompress.h: net/slcompress.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/slcompress.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/slcompress.h
+
+$(PROJECT_INCLUDE)/net/if_media.h: net/if_media.h $(PROJECT_INCLUDE)/net/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/net/if_media.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/net/if_media.h
+
+$(PROJECT_INCLUDE)/netinet/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/netinet
+ @: > $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+
+$(PROJECT_INCLUDE)/netinet/icmp_var.h: netinet/icmp_var.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/icmp_var.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/icmp_var.h
+
+$(PROJECT_INCLUDE)/netinet/if_ether.h: netinet/if_ether.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/if_ether.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/if_ether.h
+
+$(PROJECT_INCLUDE)/netinet/igmp.h: netinet/igmp.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/igmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/igmp.h
+
+$(PROJECT_INCLUDE)/netinet/igmp_var.h: netinet/igmp_var.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/igmp_var.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/igmp_var.h
+
+$(PROJECT_INCLUDE)/netinet/in.h: netinet/in.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/in.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/in.h
+
+$(PROJECT_INCLUDE)/netinet/in_pcb.h: netinet/in_pcb.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/in_pcb.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/in_pcb.h
+
+$(PROJECT_INCLUDE)/netinet/in_systm.h: netinet/in_systm.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/in_systm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/in_systm.h
+
+$(PROJECT_INCLUDE)/netinet/in_var.h: netinet/in_var.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/in_var.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/in_var.h
+
+$(PROJECT_INCLUDE)/netinet/ip.h: netinet/ip.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/ip.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/ip.h
+
+$(PROJECT_INCLUDE)/netinet/ip_fw.h: netinet/ip_fw.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/ip_fw.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/ip_fw.h
+
+$(PROJECT_INCLUDE)/netinet/ip_icmp.h: netinet/ip_icmp.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/ip_icmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/ip_icmp.h
+
+$(PROJECT_INCLUDE)/netinet/ip_mroute.h: netinet/ip_mroute.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/ip_mroute.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/ip_mroute.h
+
+$(PROJECT_INCLUDE)/netinet/ip_var.h: netinet/ip_var.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/ip_var.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/ip_var.h
+
+$(PROJECT_INCLUDE)/netinet/tcp.h: netinet/tcp.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/tcp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/tcp.h
+
+$(PROJECT_INCLUDE)/netinet/tcp_debug.h: netinet/tcp_debug.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/tcp_debug.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/tcp_debug.h
+
+$(PROJECT_INCLUDE)/netinet/tcp_fsm.h: netinet/tcp_fsm.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/tcp_fsm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/tcp_fsm.h
+
+$(PROJECT_INCLUDE)/netinet/tcp_seq.h: netinet/tcp_seq.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/tcp_seq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/tcp_seq.h
+
+$(PROJECT_INCLUDE)/netinet/tcp_timer.h: netinet/tcp_timer.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/tcp_timer.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/tcp_timer.h
+
+$(PROJECT_INCLUDE)/netinet/tcp_var.h: netinet/tcp_var.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/tcp_var.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/tcp_var.h
+
+$(PROJECT_INCLUDE)/netinet/tcpip.h: netinet/tcpip.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/tcpip.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/tcpip.h
+
+$(PROJECT_INCLUDE)/netinet/udp.h: netinet/udp.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/udp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/udp.h
+
+$(PROJECT_INCLUDE)/netinet/udp_var.h: netinet/udp_var.h $(PROJECT_INCLUDE)/netinet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/netinet/udp_var.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/netinet/udp_var.h
+
+$(PROJECT_INCLUDE)/nfs/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/nfs
+ @: > $(PROJECT_INCLUDE)/nfs/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/nfs/$(dirstamp)
+
+$(PROJECT_INCLUDE)/nfs/krpc.h: nfs/krpc.h $(PROJECT_INCLUDE)/nfs/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/nfs/krpc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/nfs/krpc.h
+
+$(PROJECT_INCLUDE)/nfs/nfs.h: nfs/nfs.h $(PROJECT_INCLUDE)/nfs/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/nfs/nfs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/nfs/nfs.h
+
+$(PROJECT_INCLUDE)/nfs/nfsproto.h: nfs/nfsproto.h $(PROJECT_INCLUDE)/nfs/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/nfs/nfsproto.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/nfs/nfsproto.h
+
+$(PROJECT_INCLUDE)/nfs/rpcv2.h: nfs/rpcv2.h $(PROJECT_INCLUDE)/nfs/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/nfs/rpcv2.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/nfs/rpcv2.h
+
+$(PROJECT_INCLUDE)/nfs/xdr_subs.h: nfs/xdr_subs.h $(PROJECT_INCLUDE)/nfs/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/nfs/xdr_subs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/nfs/xdr_subs.h
+
+$(PROJECT_INCLUDE)/nfsclient/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/nfsclient
+ @: > $(PROJECT_INCLUDE)/nfsclient/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/nfsclient/$(dirstamp)
+
+$(PROJECT_INCLUDE)/nfsclient/nfsargs.h: nfsclient/nfsargs.h $(PROJECT_INCLUDE)/nfsclient/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/nfsclient/nfsargs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/nfsclient/nfsargs.h
+
+$(PROJECT_INCLUDE)/nfsclient/nfsdiskless.h: nfsclient/nfsdiskless.h $(PROJECT_INCLUDE)/nfsclient/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/nfsclient/nfsdiskless.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/nfsclient/nfsdiskless.h
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/rtems_bsdnet.h: rtems/rtems_bsdnet.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems_bsdnet.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems_bsdnet.h
+
+$(PROJECT_INCLUDE)/rtems/rtems_bsdnet_internal.h: rtems/rtems_bsdnet_internal.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems_bsdnet_internal.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems_bsdnet_internal.h
+
+$(PROJECT_INCLUDE)/rtems/dhcp.h: rtems/dhcp.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/dhcp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/dhcp.h
+
+$(PROJECT_INCLUDE)/rtems/tftp.h: rtems/tftp.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/tftp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/tftp.h
+
+$(PROJECT_INCLUDE)/rtems/ftpfs.h: rtems/ftpfs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/ftpfs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/ftpfs.h
+
+$(PROJECT_INCLUDE)/rtems/mkrootfs.h: rtems/mkrootfs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/mkrootfs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/mkrootfs.h
+
+$(PROJECT_INCLUDE)/rtems/rtems_mii_ioctl.h: rtems/rtems_mii_ioctl.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems_mii_ioctl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems_mii_ioctl.h
+
+$(PROJECT_INCLUDE)/sys/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/sys
+ @: > $(PROJECT_INCLUDE)/sys/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/sys/$(dirstamp)
+
+$(PROJECT_INCLUDE)/sys/buf.h: sys/buf.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/buf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/buf.h
+
+$(PROJECT_INCLUDE)/sys/callout.h: sys/callout.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/callout.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/callout.h
+
+$(PROJECT_INCLUDE)/sys/conf.h: sys/conf.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/conf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/conf.h
+
+$(PROJECT_INCLUDE)/sys/domain.h: sys/domain.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/domain.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/domain.h
+
+$(PROJECT_INCLUDE)/sys/kernel.h: sys/kernel.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/kernel.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/kernel.h
+
+$(PROJECT_INCLUDE)/sys/libkern.h: sys/libkern.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/libkern.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/libkern.h
+
+$(PROJECT_INCLUDE)/sys/linker_set.h: sys/linker_set.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/linker_set.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/linker_set.h
+
+$(PROJECT_INCLUDE)/sys/malloc.h: sys/malloc.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/malloc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/malloc.h
+
+$(PROJECT_INCLUDE)/sys/mbuf.h: sys/mbuf.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/mbuf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/mbuf.h
+
+$(PROJECT_INCLUDE)/sys/mount.h: sys/mount.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/mount.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/mount.h
+
+$(PROJECT_INCLUDE)/sys/proc.h: sys/proc.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/proc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/proc.h
+
+$(PROJECT_INCLUDE)/sys/protosw.h: sys/protosw.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/protosw.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/protosw.h
+
+$(PROJECT_INCLUDE)/sys/queue.h: sys/queue.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/queue.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/queue.h
+
+$(PROJECT_INCLUDE)/sys/reboot.h: sys/reboot.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/reboot.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/reboot.h
+
+$(PROJECT_INCLUDE)/sys/resourcevar.h: sys/resourcevar.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/resourcevar.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/resourcevar.h
+
+$(PROJECT_INCLUDE)/sys/rtprio.h: sys/rtprio.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/rtprio.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/rtprio.h
+
+$(PROJECT_INCLUDE)/sys/select.h: sys/select.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/select.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/select.h
+
+$(PROJECT_INCLUDE)/sys/signalvar.h: sys/signalvar.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/signalvar.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/signalvar.h
+
+$(PROJECT_INCLUDE)/sys/socket.h: sys/socket.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/socket.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/socket.h
+
+$(PROJECT_INCLUDE)/sys/socketvar.h: sys/socketvar.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/socketvar.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/socketvar.h
+
+$(PROJECT_INCLUDE)/sys/sysctl.h: sys/sysctl.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/sysctl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/sysctl.h
+
+$(PROJECT_INCLUDE)/sys/syslog.h: sys/syslog.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/syslog.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/syslog.h
+
+$(PROJECT_INCLUDE)/sys/systm.h: sys/systm.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/systm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/systm.h
+
+$(PROJECT_INCLUDE)/sys/ttydefaults.h: sys/ttydefaults.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/ttydefaults.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/ttydefaults.h
+
+$(PROJECT_INCLUDE)/sys/ucred.h: sys/ucred.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/ucred.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/ucred.h
+
+$(PROJECT_INCLUDE)/sys/uio.h: sys/uio.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/uio.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/uio.h
+
+$(PROJECT_INCLUDE)/sys/un.h: sys/un.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/un.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/un.h
+
+$(PROJECT_INCLUDE)/vm/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/vm
+ @: > $(PROJECT_INCLUDE)/vm/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/vm/$(dirstamp)
+
+$(PROJECT_INCLUDE)/vm/vm.h: vm/vm.h $(PROJECT_INCLUDE)/vm/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/vm/vm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/vm/vm.h
+
+$(PROJECT_INCLUDE)/vm/vm_extern.h: vm/vm_extern.h $(PROJECT_INCLUDE)/vm/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/vm/vm_extern.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/vm/vm_extern.h
+
+$(PROJECT_INCLUDE)/vm/vm_kern.h: vm/vm_kern.h $(PROJECT_INCLUDE)/vm/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/vm/vm_kern.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/vm/vm_kern.h
+
+$(PROJECT_INCLUDE)/vm/vm_param.h: vm/vm_param.h $(PROJECT_INCLUDE)/vm/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/vm/vm_param.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/vm/vm_param.h
+
+$(PROJECT_INCLUDE)/dev/mii/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/dev/mii
+ @: > $(PROJECT_INCLUDE)/dev/mii/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/dev/mii/$(dirstamp)
+
+$(PROJECT_INCLUDE)/dev/mii/mii.h: dev/mii/mii.h $(PROJECT_INCLUDE)/dev/mii/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/dev/mii/mii.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/dev/mii/mii.h
+endif
diff --git a/cpukit/libnetworking/resolv.h b/cpukit/libnetworking/resolv.h
new file mode 100644
index 0000000000..614f204706
--- /dev/null
+++ b/cpukit/libnetworking/resolv.h
@@ -0,0 +1,306 @@
+/*-
+ * Copyright (c) 1983, 1987, 1989, 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.
+ */
+
+/*
+ * Portions Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * @(#)resolv.h 8.1 (Berkeley) 6/2/93
+ * From Id: resolv.h,v 8.12 1998/04/28 19:36:46 halley Exp $
+ * $Id$
+ */
+
+#ifndef _RESOLV_H_
+#define _RESOLV_H_
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <stdio.h>
+
+/*
+ * Revision information. This is the release date in YYYYMMDD format.
+ * It can change every day so the right thing to do with it is use it
+ * in preprocessor commands such as "#if (__RES > 19931104)". Do not
+ * compare for equality; rather, use it to determine whether your resolver
+ * is new enough to contain a certain feature.
+ */
+
+#define __RES 19960801
+
+/*
+ * This used to be defined in res_query.c, now it's in herror.c. It was
+ * never extern'd by any *.h file before it was placed here. herror.c is
+ * part of libresolv.a even though it might make more sense in libnetdb.a
+ * or even libnet.a.
+ */
+
+extern int h_errno;
+
+/*
+ * Resolver configuration file.
+ * Normally not present, but may contain the address of the
+ * inital name server(s) to query and the domain search list.
+ */
+
+#ifndef _PATH_RESCONF
+#define _PATH_RESCONF "/etc/resolv.conf"
+#endif
+
+/*
+ * Global defines and variables for resolver stub.
+ */
+#define MAXNS 3 /* max # name servers we'll track */
+#define MAXDFLSRCH 3 /* # default domain levels to try */
+#define MAXDNSRCH 6 /* max # domains in search path */
+#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
+
+#define RES_TIMEOUT 5 /* min. seconds between retries */
+#define MAXRESOLVSORT 10 /* number of net to sort on */
+#define RES_MAXNDOTS 15 /* should reflect bit field size */
+
+struct __res_state {
+ int retrans; /* retransmition time interval */
+ int retry; /* number of times to retransmit */
+ u_long options; /* option flags - see below. */
+ int nscount; /* number of name servers */
+ struct sockaddr_in
+ nsaddr_list[MAXNS]; /* address of name server */
+#define nsaddr nsaddr_list[0] /* for backward compatibility */
+ u_short id; /* current message id */
+ char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
+ char defdname[256]; /* default domain (deprecated) */
+ u_long pfcode; /* RES_PRF_ flags - see below. */
+ unsigned ndots:4; /* threshold for initial abs. query */
+ unsigned nsort:4; /* number of elements in sort_list[] */
+ char unused[3];
+ struct {
+ struct in_addr addr;
+ u_int32_t mask;
+ } sort_list[MAXRESOLVSORT];
+ char pad[72]; /* on an i386 this means 512b total */
+};
+
+/*
+ * Resolver options (keep these in synch with res_debug.c, please)
+ */
+#define RES_INIT 0x00000001 /* address initialized */
+#define RES_DEBUG 0x00000002 /* print debug messages */
+#define RES_AAONLY 0x00000004 /* authoritative answers only (!IMPL)*/
+#define RES_USEVC 0x00000008 /* use virtual circuit */
+#define RES_PRIMARY 0x00000010 /* query primary server only (!IMPL) */
+#define RES_IGNTC 0x00000020 /* ignore truncation errors */
+#define RES_RECURSE 0x00000040 /* recursion desired */
+#define RES_DEFNAMES 0x00000080 /* use default domain name */
+#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */
+#define RES_DNSRCH 0x00000200 /* search up local domain tree */
+#define RES_INSECURE1 0x00000400 /* type 1 security disabled */
+#define RES_INSECURE2 0x00000800 /* type 2 security disabled */
+#define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */
+#define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */
+#define RES_NOTLDQUERY 0x00004000 /* Don't query TLD names */
+
+#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
+
+/*
+ * Resolver "pfcode" values. Used by dig.
+ */
+#define RES_PRF_STATS 0x00000001
+#define RES_PRF_UPDATE 0x00000002
+#define RES_PRF_CLASS 0x00000004
+#define RES_PRF_CMD 0x00000008
+#define RES_PRF_QUES 0x00000010
+#define RES_PRF_ANS 0x00000020
+#define RES_PRF_AUTH 0x00000040
+#define RES_PRF_ADD 0x00000080
+#define RES_PRF_HEAD1 0x00000100
+#define RES_PRF_HEAD2 0x00000200
+#define RES_PRF_TTLID 0x00000400
+#define RES_PRF_HEADX 0x00000800
+#define RES_PRF_QUERY 0x00001000
+#define RES_PRF_REPLY 0x00002000
+#define RES_PRF_INIT 0x00004000
+/* 0x00008000 */
+
+typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
+ res_sendhookact;
+
+typedef res_sendhookact (*res_send_qhook)__P((struct sockaddr_in * const *ns,
+ const u_char **query,
+ int *querylen,
+ u_char *ans,
+ int anssiz,
+ int *resplen));
+
+typedef res_sendhookact (*res_send_rhook)__P((const struct sockaddr_in *ns,
+ const u_char *query,
+ int querylen,
+ u_char *ans,
+ int anssiz,
+ int *resplen));
+
+struct res_sym {
+ int number; /* Identifying number, like T_MX */
+ char * name; /* Its symbolic name, like "MX" */
+ char * humanname; /* Its fun name, like "mail exchanger" */
+};
+
+extern struct __res_state _res;
+extern const struct res_sym __p_class_syms[];
+extern const struct res_sym __p_type_syms[];
+
+/* Private routines shared between libc/net, named, nslookup and others. */
+#define res_hnok __res_hnok
+#define res_ownok __res_ownok
+#define res_mailok __res_mailok
+#define res_dnok __res_dnok
+#define sym_ston __sym_ston
+#define sym_ntos __sym_ntos
+#define sym_ntop __sym_ntop
+#define b64_ntop __b64_ntop
+#define b64_pton __b64_pton
+#define loc_ntoa __loc_ntoa
+#define loc_aton __loc_aton
+#define fp_resstat __fp_resstat
+#define p_query __p_query
+#define dn_skipname __dn_skipname
+#define fp_resstat __fp_resstat
+#define fp_query __fp_query
+#define fp_nquery __fp_nquery
+#define hostalias __hostalias
+#define putlong __putlong
+#define putshort __putshort
+#define p_class __p_class
+#define p_time __p_time
+#define p_type __p_type
+#define p_query __p_query
+#define p_cdnname __p_cdnname
+#define p_section __p_section
+#define p_cdname __p_cdname
+#define p_fqnname __p_fqnname
+#define p_fqname __p_fqname
+#define p_option __p_option
+#define p_secstodate __p_secstodate
+#define dn_count_labels __dn_count_labels
+#define dn_comp __dn_comp
+#define dn_expand __dn_expand
+#define res_init __res_init
+#define res_randomid __res_randomid
+#define res_query __res_query
+#define res_search __res_search
+#define res_querydomain __res_querydomain
+#define res_mkquery __res_mkquery
+#define res_send __res_send
+#define res_isourserver __res_isourserver
+#define res_nameinquery __res_nameinquery
+#define res_queriesmatch __res_queriesmatch
+#define res_close __res_close
+#define res_mkupdate __res_mkupdate
+#define res_mkupdrec __res_mkupdrec
+#define res_freeupdrec __res_freeupdrec
+
+__BEGIN_DECLS
+int res_hnok __P((const char *));
+int res_ownok __P((const char *));
+int res_mailok __P((const char *));
+int res_dnok __P((const char *));
+int sym_ston __P((const struct res_sym *, const char *, int *));
+const char * sym_ntos __P((const struct res_sym *, int, int *));
+const char * sym_ntop __P((const struct res_sym *, int, int *));
+int b64_ntop __P((u_char const *, size_t, char *, size_t));
+int b64_pton __P((char const *, u_char *, size_t));
+int loc_aton __P((const char *, u_char *));
+const char * loc_ntoa __P((const u_char *, char *));
+int dn_skipname __P((const u_char *, const u_char *));
+void fp_resstat __P((struct __res_state *, FILE *));
+void fp_query __P((const u_char *, FILE *));
+void fp_nquery __P((const u_char *, int, FILE *));
+const char * hostalias __P((const char *));
+void putlong __P((u_int32_t, u_char *));
+void putshort __P((u_int16_t, u_char *));
+const char * p_class __P((int));
+const char * p_time __P((u_int32_t));
+const char * p_type __P((int));
+void p_query __P((const u_char *));
+const u_char * p_cdnname __P((const u_char *, const u_char *, int, FILE *));
+const u_char * p_cdname __P((const u_char *, const u_char *, FILE *));
+const u_char * p_fqnname __P((const u_char *, const u_char *,
+ int, char *, int));
+const u_char * p_fqname __P((const u_char *, const u_char *, FILE *));
+const char * p_option __P((u_long));
+char * p_secstodate __P((u_long));
+int dn_count_labels __P((const char *));
+int dn_comp __P((const char *, u_char *, int,
+ u_char **, u_char **));
+int dn_expand __P((const u_char *, const u_char *, const u_char *,
+ char *, int));
+int res_init __P((void));
+u_int res_randomid __P((void));
+int res_query __P((const char *, int, int, u_char *, int));
+int res_search __P((const char *, int, int, u_char *, int));
+int res_querydomain __P((const char *, const char *, int, int,
+ u_char *, int));
+int res_mkquery __P((int, const char *, int, int, const u_char *,
+ int, const u_char *, u_char *, int));
+int res_send __P((const u_char *, int, u_char *, int));
+int res_isourserver __P((const struct sockaddr_in *));
+int res_nameinquery __P((const char *, int, int,
+ const u_char *, const u_char *));
+int res_queriesmatch __P((const u_char *, const u_char *,
+ const u_char *, const u_char *));
+void res_close __P((void));
+const char * p_section __P((int, int));
+/* XXX The following depend on the ns_updrec typedef in arpa/nameser.h */
+#ifdef _ARPA_NAMESER_H_
+int res_update __P((ns_updrec *));
+int res_mkupdate __P((ns_updrec *, u_char *, int));
+ns_updrec * res_mkupdrec __P((int, const char *, u_int, u_int, u_long));
+void res_freeupdrec __P((ns_updrec *));
+#endif
+__END_DECLS
+
+#endif /* !_RESOLV_H_ */
diff --git a/cpukit/libnetworking/rtems/bsdnet/_types.h b/cpukit/libnetworking/rtems/bsdnet/_types.h
new file mode 100644
index 0000000000..fb75f46d86
--- /dev/null
+++ b/cpukit/libnetworking/rtems/bsdnet/_types.h
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/sys/sys/_types.h,v 1.21 2005/03/22 01:19:17 das Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RTEMS_BSDNET__TYPES_H_
+#define _RTEMS_BSDNET__TYPES_H_
+
+#include <rtems/stdint.h>
+
+/*
+ * Standard type definitions.
+ */
+typedef uint8_t __sa_family_t;
+typedef uint32_t __socklen_t;
+
+#endif /* !_RTEMS_BSDNET_TYPES_H_ */
diff --git a/cpukit/libnetworking/rtems/bsdnet/servers.h b/cpukit/libnetworking/rtems/bsdnet/servers.h
new file mode 100644
index 0000000000..8e017d237d
--- /dev/null
+++ b/cpukit/libnetworking/rtems/bsdnet/servers.h
@@ -0,0 +1,21 @@
+/**
+ * @file rtems/rtems_bsdnet.h
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RTEMS_BSDNET_SERVERS_H
+#define _RTEMS_BSDNET_SERVERS_H
+
+extern struct in_addr *rtems_bsdnet_ntpserver;
+extern int rtems_bsdnet_ntpserver_count;
+
+/*
+ * Network configuration
+ */
+extern struct in_addr *rtems_bsdnet_nameserver;
+extern int rtems_bsdnet_nameserver_count;
+
+#endif /* _RTEMS_BSDNET_SERVERS_H */
diff --git a/cpukit/libnetworking/rtems/dhcp.h b/cpukit/libnetworking/rtems/dhcp.h
new file mode 100644
index 0000000000..f8cde76a41
--- /dev/null
+++ b/cpukit/libnetworking/rtems/dhcp.h
@@ -0,0 +1,47 @@
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Cybertec Pty Ltd, 2005
+ All rights reserved Cybertec Pty Ltd, 2005
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+ */
+
+/**
+ @file
+
+ DHCP Server interface.
+*/
+
+#if !defined (__RTEMS_DHCP_H__)
+#define __RTEMS_DHCP_H__
+
+#if __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ * Perform DHCP.
+ */
+void rtems_bsdnet_do_dhcp (void);
+
+/*
+ * Maintain a DHCP offer that has already been accepted.
+ */
+void rtems_bsdnet_do_dhcp_refresh_only (unsigned long xid,
+ unsigned long lease_time,
+ unsigned long elapsed_time,
+ unsigned long ip_address,
+ unsigned long srv_address,
+ const char *hostname);
+
+#if __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/rtems/ftpfs.h b/cpukit/libnetworking/rtems/ftpfs.h
new file mode 100644
index 0000000000..bc928a33f5
--- /dev/null
+++ b/cpukit/libnetworking/rtems/ftpfs.h
@@ -0,0 +1,37 @@
+/**
+ * @file rtems/ftpfs.h
+ *
+ * File Transfer Protocol client declarations
+ *
+ * Transfer file to/from remote host
+ */
+
+/*
+ * (c) Copyright 2002
+ * Thomas Doerfler
+ * IMD Ingenieurbuero fuer Microcomputertechnik
+ * Herbststr. 8
+ * 82178 Puchheim, Germany
+ * <Thomas.Doerfler@imd-systems.de>
+ *
+ * This code has been created after closly inspecting
+ * "tftpdriver.c" from Eric Norum.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_FTPFS_H
+#define _RTEMS_FTPFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* create mount point and mount ftp file system */
+ int rtems_bsdnet_initialize_ftp_filesystem () ;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/rtems/issetugid.c b/cpukit/libnetworking/rtems/issetugid.c
new file mode 100644
index 0000000000..09deaaf019
--- /dev/null
+++ b/cpukit/libnetworking/rtems/issetugid.c
@@ -0,0 +1,15 @@
+/*
+ * Dummy version of BSD routine
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+int
+issetugid (void)
+{
+ return 0;
+}
diff --git a/cpukit/libnetworking/rtems/mkrootfs.c b/cpukit/libnetworking/rtems/mkrootfs.c
new file mode 100644
index 0000000000..a65f249930
--- /dev/null
+++ b/cpukit/libnetworking/rtems/mkrootfs.c
@@ -0,0 +1,335 @@
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Cybertec Pty Ltd, 2000
+ All rights reserved Cybertec Pty Ltd, 2000
+
+ COPYRIGHT (c) 1989-1998.
+ 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.rtems.com/license/LICENSE.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ Set of helpers when creating a root file system. The root filesystem
+ in RTEMS is the In Memory Filesystem (IMFS). We could copy an exiting
+ filesystem to here, how-ever a number of files can have target
+ specific initialisation info which we need to write.
+
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <rtems/mkrootfs.h>
+
+/*
+ * A table a list of names and their modes.
+ */
+
+typedef struct rtems_rootfs_dir_table
+{
+ const char *name;
+ int mode;
+} rtems_rootfs_dir_table;
+
+/*
+ * Table of directorys to make.
+ */
+
+static const rtems_rootfs_dir_table default_directories[] =
+{
+ { "/bin", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/etc", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/dev", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/usr/bin", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH }
+};
+
+#define MKFILE_MODE (S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH)
+#define MKDIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
+
+/*
+ * Build a path. Taken from the BSD `mkdir' command.
+ */
+
+int
+rtems_rootfs_mkdir (const char *path_orig, mode_t omode)
+{
+ struct stat sb;
+ mode_t numask, oumask;
+ int first, last, retval;
+ char path[128];
+ char *p = path;
+
+ if (strlen (path_orig) >= sizeof path)
+ {
+ printf ("root fs: mkdir path too long `%s'\n", path);
+ return -1;
+ }
+
+ strcpy (path, path_orig);
+ oumask = 0;
+ retval = 0;
+ if (p[0] == '/') /* Skip leading '/'. */
+ ++p;
+ for (first = 1, last = 0; !last ; ++p)
+ {
+ if (p[0] == '\0')
+ last = 1;
+ else if (p[0] != '/')
+ continue;
+ *p = '\0';
+ if (p[1] == '\0')
+ last = 1;
+ if (first)
+ {
+ /*
+ * POSIX 1003.2:
+ * For each dir operand that does not name an existing
+ * directory, effects equivalent to those cased by the
+ * following command shall occcur:
+ *
+ * mkdir -p -m $(umask -S),u+wx $(dirname dir) &&
+ * mkdir [-m mode] dir
+ *
+ * We change the user's umask and then restore it,
+ * instead of doing chmod's.
+ */
+ oumask = umask(0);
+ numask = oumask & ~(S_IWUSR | S_IXUSR);
+ umask(numask);
+ first = 0;
+ }
+ if (last)
+ umask(oumask);
+ if (stat(path, &sb))
+ {
+ if (errno != ENOENT)
+ {
+ printf ("root fs: error stat'ing path `%s', %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0)
+ {
+ printf ("root fs: error building path `%s', %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ }
+ else if ((sb.st_mode & S_IFMT) != S_IFDIR)
+ {
+ if (last)
+ errno = EEXIST;
+ else
+ errno = ENOTDIR;
+ printf ("root fs: path `%s' contains a file, %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ if (!last)
+ *p = '/';
+ }
+ if (!first && !last)
+ umask(oumask);
+ return retval;
+}
+
+/*
+ * Create enough files to support the networking stack.
+ * Points to a table of strings.
+ */
+
+int
+rtems_rootfs_file_append (const char *file,
+ mode_t omode,
+ const int line_cnt,
+ const char **lines)
+{
+ struct stat sb;
+ int fd;
+ int i;
+
+ /*
+ * See is a file exists. If it does not, create the
+ * file and the path to the file.
+ */
+
+ fd = -1;
+
+ if (stat(file, &sb))
+ {
+ if (errno == ENOENT)
+ {
+ /*
+ * Get the path to the file if one exists and create the
+ * path. If it exists nothing happens.
+ */
+
+ int i = strlen (file);
+
+ while (i)
+ {
+ if (file[i] == '/')
+ {
+ char path[128];
+
+ if (i >= sizeof path)
+ {
+ printf ("root fs, path too long `%s'\n", file);
+ return -1;
+ }
+
+ strncpy (path, file, i);
+ path[i] = '\0';
+
+ if (rtems_rootfs_mkdir (path, MKDIR_MODE))
+ return -1;
+ break;
+ }
+ i--;
+ }
+
+ if ((fd = open (file, O_CREAT | O_APPEND | O_WRONLY, omode)) < 0)
+ {
+ printf ("root fs, cannot create file `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+ }
+
+ if (fd < 0)
+ {
+ if ((fd = open (file, O_APPEND | O_WRONLY)) < 0)
+ {
+ printf ("root fs, cannot open file `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+
+ for (i = 0; i < line_cnt; i++)
+ {
+ int len = strlen (lines[i]);
+
+ if (len)
+ {
+ if (write (fd, lines[i], strlen (lines[i])) < 0)
+ {
+ close (fd);
+ printf ("root fs, cannot write to `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+ }
+
+ return close (fd);
+}
+
+/*
+ * Write hosts record.
+ */
+
+int
+rtems_rootfs_append_host_rec (unsigned long cip,
+ const char *cname,
+ const char *dname)
+{
+ char buf[128];
+ char *bufp = buf;
+ const char *bufl[1];
+ struct in_addr ip;
+
+ ip.s_addr = cip;
+
+ if (cname && strlen (cname))
+ {
+ snprintf (bufp, sizeof (buf), "%s\t\t%s", inet_ntoa (ip), cname);
+ bufp += strlen (buf);
+
+ if (dname && strlen (dname))
+ {
+ snprintf (bufp, sizeof (buf), "\t\t%s.%s", cname, dname);
+ bufp += strlen (buf);
+ }
+
+ strcat (buf, "\n");
+
+ bufl[0] = buf;
+
+ if (rtems_rootfs_file_append ("/etc/hosts", MKFILE_MODE, 1, bufl) < 0)
+ return -1;
+ }
+ else
+ {
+ printf ("rootfs hosts rec append, no cname supplied\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Create a root file system.
+ */
+
+int
+rtems_create_root_fs ()
+{
+ const char *lines[1];
+ int i;
+
+ /*
+ * Create the directories.
+ */
+
+ for (i = 0;
+ i < (sizeof (default_directories) / sizeof (rtems_rootfs_dir_table));
+ i++)
+ if (rtems_rootfs_mkdir (default_directories[i].name,
+ default_directories[i].mode))
+ return -1;
+
+ /*
+ * The TCP/IP stack likes this one. If DNS does not work
+ * use the host file.
+ */
+
+ lines[0] = "hosts,bind\n";
+
+ if (rtems_rootfs_file_append ("/etc/host.conf", MKFILE_MODE, 1, lines))
+ return -1;
+
+ /*
+ * Create a `/etc/hosts' file.
+ */
+
+ if (rtems_rootfs_append_host_rec (0x7f000001, "localhost", "localdomain"))
+ return -1;
+
+ return 0;
+}
diff --git a/cpukit/libnetworking/rtems/mkrootfs.h b/cpukit/libnetworking/rtems/mkrootfs.h
new file mode 100644
index 0000000000..a0e9cbb0fc
--- /dev/null
+++ b/cpukit/libnetworking/rtems/mkrootfs.h
@@ -0,0 +1,65 @@
+/**
+ * @file rtems/mkrootfs.h
+ *
+ * RTEMS Root FS creation support.
+ */
+
+/*
+ Copyright Cybertec Pty Ltd, 2000
+ All rights reserved Cybertec Pty Ltd, 2000
+
+ COPYRIGHT (c) 1989-1998.
+ 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.rtems.com/license/LICENSE.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ $Id$
+*/
+
+#ifndef _RTEMS_MKROOTFS_H
+#define _RTEMS_MKROOTFS_H
+
+#include <rtems.h>
+
+/*
+ * Builds the complete path, like "mkdir -p".
+ */
+
+int
+rtems_rootfs_mkdir (const char *path, mode_t omode);
+
+/*
+ * Appends the lines to the a file. Create the file
+ * and builds the path if it does not exist.
+ */
+
+int
+rtems_rootfs_file_append (const char *file,
+ mode_t omode,
+ const int line_cnt,
+ const char **lines);
+
+/*
+ * Helper for bulding an /etc/hosts file.
+ */
+
+int
+rtems_rootfs_append_host_rec (unsigned long cip,
+ const char *cname,
+ const char *dname);
+
+/*
+ * Create a few common directories, plus a :
+ * /etc/passwd, /etc/group, /etc/host.conf, and
+ * /etc/hosts file.
+ */
+
+int
+rtems_create_root_fs ();
+
+#endif
diff --git a/cpukit/libnetworking/rtems/rtems_bootp.c b/cpukit/libnetworking/rtems/rtems_bootp.c
new file mode 100644
index 0000000000..23c6801757
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_bootp.c
@@ -0,0 +1,36 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/error.h>
+#include <sys/types.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/rtems_bsdnet_internal.h>
+
+/*
+ * Perform a BOOTP request
+ */
+void
+rtems_bsdnet_do_bootp (void)
+{
+ rtems_bsdnet_semaphore_obtain ();
+ bootpc_init (FALSE);
+ rtems_bsdnet_semaphore_release ();
+}
+
+/*
+ * Perform a BOOTP request and update "standard" files in /etc
+ * with the results.
+ */
+void
+rtems_bsdnet_do_bootp_and_rootfs (void)
+{
+ rtems_bsdnet_semaphore_obtain ();
+ bootpc_init (TRUE);
+ rtems_bsdnet_semaphore_release ();
+}
diff --git a/cpukit/libnetworking/rtems/rtems_bsdnet.h b/cpukit/libnetworking/rtems/rtems_bsdnet.h
new file mode 100644
index 0000000000..3112779078
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_bsdnet.h
@@ -0,0 +1,279 @@
+/**
+ * @file rtems/rtems_bsdnet.h
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RTEMS_BSDNET_H
+#define _RTEMS_BSDNET_H
+
+#include <rtems.h>
+
+/*
+ * If this file is included from inside the Network Stack proper or
+ * a device driver, then __INSIDE_RTEMS_BSD_TCPIP_STACK__ should be
+ * defined. This triggers a number of internally used definitions.
+ */
+
+#if defined(__INSIDE_RTEMS_BSD_TCPIP_STACK__)
+#undef _COMPILING_BSD_KERNEL_
+#undef _KERNEL
+#undef INET
+#undef NFS
+#undef DIAGNOSTIC
+#undef BOOTP_COMPAT
+#undef __BSD_VISIBLE
+
+#define _COMPILING_BSD_KERNEL_
+#define _KERNEL
+#define INET
+#define NFS
+#define DIAGNOSTIC
+#define BOOTP_COMPAT
+#define __BSD_VISIBLE 1
+#endif
+
+/*
+ * Values that may be obtained by BOOTP
+ */
+extern struct in_addr rtems_bsdnet_bootp_server_address;
+extern char *rtems_bsdnet_bootp_server_name;
+extern char *rtems_bsdnet_bootp_boot_file_name;
+extern char *rtems_bsdnet_bootp_cmdline;
+extern long rtems_bsdnet_timeoffset;
+
+/*
+ * Manipulate routing tables
+ */
+struct sockaddr;
+struct rtentry;
+int rtems_bsdnet_rtrequest (
+ int req,
+ struct sockaddr *dst,
+ struct sockaddr *gateway,
+ struct sockaddr *netmask,
+ int flags,
+ struct rtentry **net_nrt);
+
+/*
+ * Diagnostics
+ */
+void rtems_bsdnet_show_inet_routes (void);
+void rtems_bsdnet_show_mbuf_stats (void);
+void rtems_bsdnet_show_if_stats (void);
+void rtems_bsdnet_show_ip_stats (void);
+void rtems_bsdnet_show_icmp_stats (void);
+void rtems_bsdnet_show_udp_stats (void);
+void rtems_bsdnet_show_tcp_stats (void);
+
+/*
+ * Network configuration
+ */
+struct rtems_bsdnet_ifconfig {
+ /*
+ * These three entries must be supplied for each interface.
+ */
+ char *name;
+
+ /*
+ * This function now handles attaching and detaching an interface.
+ * The parameter attaching indicates the operation being invoked.
+ * For older attach functions which do not have the extra parameter
+ * it will be ignored.
+ */
+ int (*attach)(struct rtems_bsdnet_ifconfig *conf, int attaching);
+
+ /*
+ * Link to next interface
+ */
+ struct rtems_bsdnet_ifconfig *next;
+
+ /*
+ * The following entries may be obtained
+ * from BOOTP or explicitily supplied.
+ */
+ char *ip_address;
+ char *ip_netmask;
+ void *hardware_address;
+
+ /*
+ * The driver assigns defaults values to the following
+ * entries if they are not explicitly supplied.
+ */
+ int ignore_broadcast;
+ int mtu;
+ int rbuf_count;
+ int xbuf_count;
+
+ /*
+ * For external ethernet controller board the following
+ * parameters are needed
+ */
+ unsigned int port; /* port of the board */
+ unsigned int irno; /* irq of the board */
+ unsigned int bpar; /* memory of the board */
+
+ /*
+ * Driver control block pointer. Typcially this points to the driver's
+ * controlling structure. You set this when you have the structure allocated
+ * externally to the driver.
+ */
+ void *drv_ctrl;
+
+};
+
+struct rtems_bsdnet_config {
+ /*
+ * This entry points to the head of the ifconfig chain.
+ */
+ struct rtems_bsdnet_ifconfig *ifconfig;
+
+ /*
+ * This entry should be rtems_bsdnet_do_bootp if BOOTP
+ * is being used to configure the network, and NULL
+ * if BOOTP is not being used.
+ */
+ void (*bootp)(void);
+
+ /*
+ * The remaining items can be initialized to 0, in
+ * which case the default value will be used.
+ */
+ rtems_task_priority network_task_priority; /* 100 */
+ unsigned long mbuf_bytecount; /* 64 kbytes */
+ unsigned long mbuf_cluster_bytecount; /* 128 kbytes */
+ char *hostname; /* BOOTP */
+ char *domainname; /* BOOTP */
+ char *gateway; /* BOOTP */
+ char *log_host; /* BOOTP */
+ char *name_server[3]; /* BOOTP */
+ char *ntp_server[3]; /* BOOTP */
+};
+
+/*
+ * Default global device configuration structure. This is scanned
+ * by the initialize network function. Check the network demo's for
+ * an example of the structure. Like the RTEMS configuration tables,
+ * they are not part of RTEMS but part of your application or bsp
+ * code.
+ */
+extern struct rtems_bsdnet_config rtems_bsdnet_config;
+
+/*
+ * Initialise the BSD stack, attach and `up' interfaces
+ * in the `rtems_bsdnet_config'. RTEMS must already be initialised.
+ */
+int rtems_bsdnet_initialize_network (void);
+
+/*
+ * Dynamic interface control. Drivers must free any resources such as
+ * memory, interrupts, io regions claimed during the `attach' and/or
+ * `up' operations when asked to `detach'.
+ * You must configure the interface after attaching it.
+ */
+void rtems_bsdnet_attach (struct rtems_bsdnet_ifconfig *ifconfig);
+void rtems_bsdnet_detach (struct rtems_bsdnet_ifconfig *ifconfig);
+
+/*
+ * Interface configuration. The commands are listed in `sys/sockio.h'.
+ */
+int rtems_bsdnet_ifconfig (const char *ifname, uint32_t cmd, void *param);
+
+void rtems_bsdnet_do_bootp (void);
+void rtems_bsdnet_do_bootp_and_rootfs (void);
+
+/* NTP tuning parameters */
+extern int rtems_bsdnet_ntp_retry_count;
+extern int rtems_bsdnet_ntp_timeout_secs;
+extern int rtems_bsdnet_ntp_bcast_timeout_secs;
+
+
+struct timestamp {
+ uint32_t integer;
+ uint32_t fraction;
+};
+
+/* Data is passed in network byte order */
+struct ntpPacketSmall {
+ uint8_t li_vn_mode;
+ uint8_t stratum;
+ int8_t poll_interval;
+ int8_t precision;
+ int32_t root_delay;
+ int32_t root_dispersion;
+ char reference_identifier[4];
+ struct timestamp reference_timestamp;
+ struct timestamp originate_timestamp;
+ struct timestamp receive_timestamp;
+ struct timestamp transmit_timestamp;
+};
+
+/* NOTE: packet data is *only* accessible from the callback
+ *
+ * 'callback' is invoked twice, once prior to sending a request
+ * to the server and one more time after receiving a valid reply.
+ * This allows for the user to measure round-trip times.
+ *
+ * Semantics of the 'state' parameter:
+ *
+ * state == 1: 1st call, just prior to sending request. The
+ * packet has been set up already but may be
+ * modified by the callback (e.g. to set the originate
+ * timestamp).
+ * state == -1: 1st call - no request will be sent but we'll
+ * wait for a reply from a broadcast server. The
+ * packet has not been set up.
+ * state == 0: 2nd call. The user is responsible for keeping track
+ * of the 'state' during the first call in order to
+ * know if it makes sense to calculate 'round-trip' times.
+ *
+ * RETURN VALUE: the callback should return 0 if processing the packet was
+ * successful and -1 on error in which case rtems_bsdnet_get_ntp()
+ * may try another server.
+ */
+typedef int (*rtems_bsdnet_ntp_callback_t)(
+ struct ntpPacketSmall *packet,
+ int state,
+ void *usr_data);
+
+/* Obtain time from a NTP server and call user callback to process data;
+ * socket parameter may be -1 to request the routine to open and close its own socket.
+ * Networking parameters as configured are used...
+ *
+ * It is legal to pass a NULL callback pointer. In this case, a default callback
+ * is used which determines the current time by contacting an NTP server. The current
+ * time is converted to a 'struct timespec' (seconds/nanoseconds) and passed into *usr_data.
+ * The caller is responsible for providing a memory area >= sizeof(struct timespec).
+ *
+ * RETURNS: 0 on success, -1 on failure.
+ */
+int rtems_bsdnet_get_ntp(int socket, rtems_bsdnet_ntp_callback_t callback, void *usr_data);
+
+int rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority);
+
+/*
+ * Callback to report BSD malloc starvation.
+ * The default implementation just prints a message but an application
+ * can provide its own version.
+ */
+void rtems_bsdnet_malloc_starvation(void);
+
+/*
+ * mbuf malloc interface to enable custom allocation of mbuf's
+ *
+ * May be declared in user code. If not, then the default is to
+ * malloc.
+ */
+void* rtems_bsdnet_malloc_mbuf(size_t size, int type);
+
+/*
+ * Possible values of the type parameter to rtems_bsdnet_malloc_mbuf to assist
+ * in allocation of the structure.
+ */
+#define MBUF_MALLOC_NMBCLUSTERS (0)
+#define MBUF_MALLOC_MCLREFCNT (1)
+#define MBUF_MALLOC_MBUF (2)
+
+#endif /* _RTEMS_BSDNET_H */
diff --git a/cpukit/libnetworking/rtems/rtems_bsdnet_internal.h b/cpukit/libnetworking/rtems/rtems_bsdnet_internal.h
new file mode 100644
index 0000000000..11395edb49
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_bsdnet_internal.h
@@ -0,0 +1,193 @@
+/*
+ * Declarations to fit FreeBSD to RTEMS.
+ *
+ *******************************************************************
+ * WARNING *
+ * This file should *never* be included by any application program *
+ *******************************************************************
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_BSDNET_INTERNAL_H
+#define _RTEMS_RTEMS_BSDNET_INTERNAL_H
+
+#include <rtems.h>
+
+typedef unsigned int vm_offset_t;
+typedef long long vm_ooffset_t;
+typedef unsigned int vm_pindex_t;
+typedef unsigned int vm_size_t;
+
+#define _BSD_OFF_T_ int32_t
+#define _BSD_PID_T_ rtems_id
+#define _BSD_VA_LIST_ char *
+
+/* make sure we get the network versions of these */
+#include <machine/types.h>
+#include <machine/param.h>
+#include <rtems/cdefs.h>
+
+#include <sys/time.h>
+
+struct mdproc {
+ int md_flags;
+ int *md_regs;
+};
+
+/*
+ * Other RTEMS/BSD glue
+ */
+struct socket;
+extern int soconnsleep (struct socket *so);
+extern void soconnwakeup (struct socket *so);
+#define splnet() 0
+#define splimp() 0
+#define splx(_s) do { (_s) = 0; } while(0)
+
+/* to avoid warnings */
+void *memcpy(void *dest, const void *src, size_t n);
+void *memset(void *s, int c, size_t n);
+
+#define ovbcopy(f,t,n) bcopy(f,t,n)
+#define copyout(f,t,n) (memcpy(t,f,n),0)
+#define copyin(f,t,n) (memcpy(t,f,n),0)
+
+#define random() rtems_bsdnet_random()
+#define panic rtems_panic
+#define suser(a,b) 0
+
+void microtime (struct timeval *tv);
+#define hz rtems_bsdnet_ticks_per_second
+#define tick rtems_bsdnet_microseconds_per_tick
+
+#define log rtems_bsdnet_log
+
+/*
+ * Since we can't have two sys/types.h files, we'll hack around
+ * and copy the contents of the BSD sys/types.h to here....
+ */
+#include <sys/cdefs.h>
+
+typedef u_int64_t u_quad_t; /* quads */
+typedef int64_t quad_t;
+typedef quad_t * qaddr_t;
+
+typedef void __sighandler_t __P((int));
+typedef __sighandler_t *sig_t; /* type of pointer to a signal function */
+#define NSIG 32
+struct sigaltstack {
+ char *ss_sp; /* signal stack base */
+ int ss_size; /* signal stack length */
+ int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */
+};
+
+#ifdef _KERNEL
+typedef int boolean_t;
+typedef struct vm_page *vm_page_t;
+#endif
+
+#ifndef _POSIX_SOURCE
+/*
+ * minor() gives a cookie instead of an index since we don't want to
+ * change the meanings of bits 0-15 or waste time and space shifting
+ * bits 16-31 for devices that don't use them.
+ */
+#define major(x) ((int)(((u_int)(x) >> 8)&0xff)) /* major number */
+#define minor(x) ((int)((x)&0xffff00ff)) /* minor number */
+#define makedev(x,y) ((dev_t)(((x) << 8) | (y))) /* create dev_t */
+#endif
+
+#include <machine/endian.h>
+
+typedef quad_t rlim_t; /* resource limit */
+typedef u_int32_t fixpt_t; /* fixed point number */
+
+/*
+ * Forward structure declarations for function prototypes. We include the
+ * common structures that cross subsystem boundaries here; others are mostly
+ * used in the same place that the structure is defined.
+ */
+struct proc;
+struct pgrp;
+struct ucred;
+struct rusage;
+struct file;
+struct buf;
+struct tty;
+struct uio;
+struct rtems_bsdnet_ifconfig;
+
+/*
+ * Redo kernel memory allocation
+ */
+#define malloc rtems_bsdnet_malloc
+#define free rtems_bsdnet_free
+
+#define M_NOWAIT 0x0001
+void *rtems_bsdnet_malloc (unsigned long size, int type, int flags);
+void rtems_bsdnet_free (void *addr, int type);
+
+void rtems_bsdnet_semaphore_obtain (void);
+void rtems_bsdnet_semaphore_release (void);
+void rtems_bsdnet_schednetisr (int n);
+int rtems_bsdnet_parse_driver_name (const struct rtems_bsdnet_ifconfig *config, char **namep);
+
+unsigned long rtems_bsdnet_seconds_since_boot (void);
+unsigned long rtems_bsdnet_random (void);
+
+rtems_id rtems_bsdnet_newproc (
+ char *name,
+ int stacksize,
+ void (*entry)(void *),
+ void *arg
+);
+
+rtems_status_code rtems_bsdnet_event_receive (
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out
+);
+
+/*
+ * Network configuration
+ */
+extern int rtems_bsdnet_ticks_per_second;
+extern int rtems_bsdnet_microseconds_per_tick;
+extern struct in_addr rtems_bsdnet_log_host_address;
+extern char *rtems_bsdnet_domain_name;
+
+/*
+ * Internal IOCTL command
+ */
+#define SIO_RTEMS_SHOW_STATS _IO('i', 250)
+
+/*
+ * Some extra prototypes
+ */
+int sethostname (char *name, size_t namelen);
+void domaininit (void *);
+void ifinit (void *);
+void ipintr (void);
+void arpintr (void);
+void bootpc_init(int );
+int socket (int, int, int);
+int ioctl (int, int, ...);
+
+/*
+ * Events used by networking routines.
+ * Everything will break if the application
+ * tries to use these events or if the `sleep'
+ * events are equal to any of the NETISR * events.
+ */
+#define SBWAIT_EVENT RTEMS_EVENT_24
+#define SOSLEEP_EVENT RTEMS_EVENT_25
+#define NETISR_IP_EVENT (1 << NETISR_IP)
+#define NETISR_ARP_EVENT (1 << NETISR_ARP)
+#define NETISR_EVENTS (NETISR_IP_EVENT|NETISR_ARP_EVENT)
+#if (SBWAIT_EVENT & SOSLEEP_EVENT & NETISR_EVENTS)
+# error "Network event conflict"
+#endif
+
+#endif /* _RTEMS_RTEMS_BSDNET_INTERNAL_H */
diff --git a/cpukit/libnetworking/rtems/rtems_bsdnet_malloc_starvation.c b/cpukit/libnetworking/rtems/rtems_bsdnet_malloc_starvation.c
new file mode 100644
index 0000000000..5e7d45d713
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_bsdnet_malloc_starvation.c
@@ -0,0 +1,19 @@
+/*
+ * Routine called when malloc() is not succeeding. This can be overridden
+ * by a BSP.
+ *
+ * $Id*
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <rtems/rtems_bsdnet.h>
+
+void
+rtems_bsdnet_malloc_starvation(void)
+{
+ printf ("rtems_bsdnet_malloc still waiting.\n");
+}
diff --git a/cpukit/libnetworking/rtems/rtems_dhcp.c b/cpukit/libnetworking/rtems/rtems_dhcp.c
new file mode 100644
index 0000000000..db5783269b
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_dhcp.c
@@ -0,0 +1,1133 @@
+/*
+ * DCHP client for RTEMS
+ * Andrew Bythell, <abythell@nortelnetworks.com>
+ * based on and uses subroutines from c/src/libnetworking/nfs/bootp_subr.c
+ */
+
+/*
+ * DHCP task added.
+ * Brendan Gannon, <bgannon@cybertec.com.au>
+ */
+
+/*
+ * Copyright (c) 1995 Gordon Ross, Adam Glass
+ * Copyright (c) 1992 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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, Lawrence Berkeley Laboratory 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.
+ *
+ */
+
+/*
+ * WARNING:
+ * This file should be moved into c/src/libnetworking/nfs
+ * and the following two #ifndef...#endif blocks and the #undefs at
+ * the end of the file should be removed
+ */
+
+#ifndef _COMPILING_BSD_KERNEL_
+#define _COMPILING_BSD_KERNEL_
+#endif
+
+#ifndef KERNEL
+#define KERNEL
+#endif
+
+#ifndef __INSIDE_RTEMS_BSD_TCPIP_STACK__
+#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
+#endif
+
+#ifndef __BSD_VISIBLE
+#define __BSD_VISIBLE 1
+#endif
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/bsdnet/servers.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <sys/ioctl.h>
+#include <sys/param.h> /* for MAXHOSTNAMELEN */
+#include <sys/systm.h>
+#include <sys/socketvar.h> /* for socreat() soclose() */
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <netinet/in.h> /* for NBO-HBO conversions */
+#include <net/if_types.h> /* for IFT_ETHER */
+#include <net/if_dl.h> /* for LLADDR */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <rtems/mkrootfs.h>
+
+#include "rtems/dhcp.h"
+
+#ifndef EALEN
+#define EALEN 6
+#endif
+
+/*
+ *DHCP flags
+ */
+#define DHCP_BROADCAST 0x8000
+#define DHCP_UNICAST 0x0000
+
+/*
+ * DHCP Op Codes
+ */
+#define DHCP_BOOTREQUEST 1
+#define DHCP_BOOTREPLY 2
+
+/*
+ * DHCP Messages
+ */
+#define DHCP_DISCOVER 1
+#define DHCP_OFFER 2
+#define DHCP_REQUEST 3
+#define DHCP_DECLINE 4
+#define DHCP_ACK 5
+#define DHCP_NACK 6
+#define DHCP_RELEASE 7
+
+/*
+ * DHCP Options
+ */
+#define DHCP_OPTION_PAD 0
+#define DHCP_SUBNET 1
+#define DHCP_GATEWAY 3
+#define DHCP_DNS 6
+#define DHCP_HOST 12
+#define DHCP_DOMAIN_NAME 15
+#define DHCP_NETMASK 28
+#define DHCP_REQUESTED_IP 50
+#define DHCP_LEASE 51
+#define DHCP_MESSAGE 53
+#define DHCP_SERVER 54
+#define DHCP_PARAMETERS 55
+#define DHCP_OPTION_END 255
+
+/*
+ * Definitions from RFC
+ */
+struct dhcp_packet
+{
+ u_int8_t op;
+ u_int8_t htype;
+ u_int8_t hlen;
+ u_int8_t hops;
+ u_int32_t xid;
+ u_int16_t secs;
+ u_int16_t flags;
+ struct in_addr ciaddr;
+ struct in_addr yiaddr;
+ struct in_addr siaddr;
+ struct in_addr giaddr;
+ unsigned char chaddr[16];
+ char sname[64];
+ char file[128];
+ unsigned char vend[312];
+};
+
+/*
+ * External Declarations for Functions found in
+ * rtems/c/src/libnetworking/nfs/
+ */
+extern int bootpc_call (struct dhcp_packet *call,
+ struct dhcp_packet *reply,
+ struct proc *procp);
+extern int bootpc_fakeup_interface (struct ifreq *ireq,
+ struct socket *so,
+ struct proc *procp);
+extern int bootpc_adjust_interface (struct ifreq *ireq,
+ struct socket *so,
+ struct sockaddr_in *myaddr,
+ struct sockaddr_in *netmask,
+ struct sockaddr_in *gw,
+ struct proc *procp);
+extern void *bootp_strdup_realloc (char *dst,
+ const char *src);
+extern int nfs_diskless_valid;
+
+/*
+ * Variables
+ */
+static int dhcp_option_overload = 0;
+static char dhcp_gotgw = 0;
+static char dhcp_gotnetmask = 0;
+static char dhcp_gotserver = 0;
+static char dhcp_gotlogserver = 0;
+static struct sockaddr_in dhcp_netmask;
+static struct sockaddr_in dhcp_gw;
+static char *dhcp_hostname;
+static int dhcp_message_type = 0;
+static unsigned long dhcp_lease_time;
+static unsigned long dhcp_elapsed_time = 0;
+static const char dhcp_magic_cookie[4] = { 99, 130, 83, 99 };
+static const char dhcp_request_parameters[5] = { DHCP_SUBNET,
+ DHCP_GATEWAY,
+ DHCP_DNS,
+ DHCP_HOST,
+ DHCP_DOMAIN_NAME };
+
+/*
+ * Format an IP address in dotted decimal.
+ */
+void
+format_ip (unsigned long ip, char* buffer)
+{
+ sprintf (buffer,
+ "%lu.%lu.%lu.%lu",
+ (ip >> 24),
+ (ip >> 16) & 0xff,
+ (ip >> 8) & 0xff,
+ (ip & 0xff));
+
+ return;
+}
+
+/*
+ * Print the IP setup
+ */
+static void
+printsetup (const char *iface,
+ struct in_addr ip_addr,
+ struct in_addr mask_addr,
+ struct in_addr srv_addr,
+ struct in_addr gw_addr)
+{
+ unsigned long ip;
+ char ip_str[15];
+
+ printf ("dhcpc: %s: ", iface);
+
+ ip = ntohl (ip_addr.s_addr);
+ format_ip (ip, ip_str);
+ printf ("inet: %-15s ", ip_str);
+
+ ip = ntohl (mask_addr.s_addr);
+ format_ip (ip, ip_str);
+ printf ("mask: %-15s\n", ip_str);
+
+ ip = ntohl (srv_addr.s_addr);
+ format_ip (ip, ip_str);
+ printf (" srv: %-15s ", ip_str);
+
+ ip = ntohl (gw_addr.s_addr);
+ format_ip (ip, ip_str);
+ printf (" gw: %-15s\n", ip_str);
+
+ return;
+}
+
+/*
+ * Process options from the DHCP packet.
+ * Based on BOOTP routine.
+ */
+static void
+process_options (unsigned char *optbuf, int optbufSize)
+{
+ int j = 0;
+ int len;
+ int code, ncode;
+ char *p;
+
+ ncode = optbuf[0];
+ while (j < optbufSize)
+ {
+ code = optbuf[j] = ncode;
+ if (code == 255)
+ return;
+ if (code == 0)
+ {
+ j++;
+ continue;
+ }
+ len = optbuf[j + 1];
+ j += 2;
+
+ if ((len + j) >= optbufSize)
+ {
+ printf ("Truncated field for code %d", code);
+ return;
+ }
+
+ ncode = optbuf[j + len];
+ optbuf[j + len] = '\0';
+ p = (char*) &optbuf[j];
+ j += len;
+
+ /*
+ * Process the option
+ */
+ switch (code)
+ {
+ case 1:
+ /* Subnet mask */
+ if (len != 4)
+ panic ("dhcpc: subnet mask len is %d", len);
+ memcpy (&dhcp_netmask.sin_addr, p, 4);
+ dhcp_gotnetmask = 1;
+ break;
+
+ case 2:
+ /* Time offset */
+ if (len != 4)
+ panic ("dhcpc: time offset len is %d", len);
+ memcpy (&rtems_bsdnet_timeoffset, p, 4);
+ rtems_bsdnet_timeoffset = ntohl (rtems_bsdnet_timeoffset);
+ break;
+
+ case 3:
+ /* Routers */
+ if (len % 4)
+ panic ("dhcpc: Router Len is %d", len);
+ if (len > 0)
+ {
+ memcpy (&dhcp_gw.sin_addr, p, 4);
+ dhcp_gotgw = 1;
+ }
+ break;
+
+ case 42:
+ /* NTP servers */
+ if (len % 4)
+ panic ("dhcpc: time server Len is %d", len);
+ {
+ int tlen = 0;
+ while ((tlen < len) &&
+ (rtems_bsdnet_ntpserver_count <
+ sizeof rtems_bsdnet_config.ntp_server /
+ sizeof rtems_bsdnet_config.ntp_server[0]))
+ {
+ memcpy (&rtems_bsdnet_ntpserver[rtems_bsdnet_ntpserver_count],
+ p + tlen, 4);
+ rtems_bsdnet_ntpserver_count++;
+ tlen += 4;
+ }
+ }
+ break;
+
+ case 6:
+ /* Domain Name servers */
+ if (len % 4)
+ panic ("dhcpc: DNS Len is %d", len);
+ {
+ int dlen = 0;
+ while ((dlen < len) &&
+ (rtems_bsdnet_nameserver_count <
+ sizeof rtems_bsdnet_config.name_server /
+ sizeof rtems_bsdnet_config.name_server[0]))
+ {
+ memcpy (&rtems_bsdnet_nameserver
+ [rtems_bsdnet_nameserver_count], p + dlen, 4);
+ rtems_bsdnet_nameserver_count++;
+ dlen += 4;
+ }
+ }
+ break;
+
+ case 12:
+ /* Host name */
+ if (len >= MAXHOSTNAMELEN)
+ panic ("dhcpc: hostname >= %d bytes", MAXHOSTNAMELEN);
+ if (sethostname (p, len) < 0)
+ panic ("dhcpc: can't set host name");
+ if (dhcp_hostname != NULL)
+ {
+ dhcp_hostname = realloc (dhcp_hostname, len);
+ strncpy (dhcp_hostname, p, len);
+ }
+ else
+ dhcp_hostname = strndup (p, len);
+ break;
+
+ case 7:
+ /* Log servers */
+ if (len % 4)
+ panic ("dhcpc: Log server Len is %d", len);
+ if (len > 0)
+ {
+ memcpy (&rtems_bsdnet_log_host_address, p, 4);
+ dhcp_gotlogserver = 1;
+ }
+ break;
+
+ case 15:
+ /* Domain name */
+ if (p[0])
+ {
+ rtems_bsdnet_domain_name = strdup (p);
+ }
+ break;
+
+ case 16: /* Swap server IP address. unused */
+ break;
+
+ case 50:
+ /* DHCP Requested IP Address */
+ if (len != 4)
+ panic ("dhcpc: DHCP option requested IP len is %d", len);
+ /*
+ * although nothing happens here, this case keeps the client
+ * from complaining about unknown options. The Requested IP
+ * is necessary to return to the server for a DHCP REQUEST
+ */
+ break;
+
+ case 51:
+ /* DHCP Lease Length */
+ if (len != 4)
+ panic ("dhcpc: DHCP option lease-length len is %d", len);
+ memcpy (&dhcp_lease_time, &p[0], 4);
+ dhcp_lease_time = ntohl (dhcp_lease_time);
+ break;
+
+ case 52:
+ /* DHCP option override */
+ if (len != 1)
+ panic ("dhcpc: DHCP option overload len is %d", len);
+ dhcp_option_overload = p[0];
+ break;
+
+ case 53:
+ /* DHCP message */
+ if (len != 1)
+ panic ("dhcpc: DHCP message len is %d", len);
+ dhcp_message_type = p[0];
+ break;
+
+ case 128: /* Site-specific option for DHCP servers that
+ * a) don't supply tag 54
+ * and
+ * b) don't supply the server address in siaddr
+ * For example, on Solaris 2.6 in.dhcpd, include in the dhcptab:
+ * Bootsrv s Site,128,IP,1,1
+ * and use that symbol in the macro that defines the client:
+ * Bootsrv=<tftp-server-ip-address>
+ */
+ case 54:
+ /* DHCP server */
+ if (len != 4)
+ panic ("dhcpc: DHCP server len is %d", len);
+ memcpy (&rtems_bsdnet_bootp_server_address, p, 4);
+ dhcp_gotserver = 1;
+ break;
+
+ case 66:
+ /* DHCP server name option */
+ if (p[0])
+ rtems_bsdnet_bootp_server_name = strdup (p);
+ break;
+
+ case 67:
+ /* DHCP bootfile option */
+ if (p[0])
+ rtems_bsdnet_bootp_boot_file_name = strdup (p);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/*
+ * Generate the packet for a DHCP DISCOVER.
+ */
+static int
+dhcp_discover_req (struct dhcp_packet* call,
+ struct sockaddr_dl *sdl,
+ unsigned long *xid)
+{
+ int len = 0;
+
+ memset (call, 0, sizeof (struct dhcp_packet));
+
+ /*
+ * Send a DHCP DISCOVER Message
+ */
+ call->op = DHCP_BOOTREQUEST;
+ call->htype = 1; /* 10mb ethernet */
+ call->hlen = sdl->sdl_alen; /* Hardware address length */
+ call->hops = 0;
+ (*xid)++;
+ call->xid = htonl (*xid);
+ call->flags = htons (DHCP_BROADCAST);
+
+ memcpy (&call->chaddr, LLADDR (sdl), sdl->sdl_alen);
+
+ /*
+ * Magic cookie.
+ */
+ memcpy (&call->vend[len], dhcp_magic_cookie, sizeof (dhcp_magic_cookie));
+ len += sizeof (dhcp_magic_cookie);
+
+ /*
+ * DHCP Message type.
+ */
+ call->vend[len++] = DHCP_MESSAGE;
+ call->vend[len++] = 1;
+ call->vend[len++] = DHCP_DISCOVER;
+
+ /*
+ * DHCP Parameter request list
+ */
+ call->vend[len++] = DHCP_PARAMETERS;
+ call->vend[len++] = sizeof (dhcp_request_parameters);
+ memcpy (&call->vend[len], &dhcp_request_parameters, sizeof (dhcp_request_parameters));
+ len += sizeof (dhcp_request_parameters);
+
+ /*
+ * Lease time.
+ */
+ call->vend[len++] = DHCP_LEASE;
+ call->vend[len++] = 4;
+ memset (&call->vend[len], 0xFF, 4); /* request infinite lease time */
+ len += 4;
+
+ /*
+ * End.
+ */
+ call->vend[len++] = DHCP_OPTION_END;
+ call->secs = 0;
+
+ return len;
+}
+
+/*
+ * Generate the packet for a DHCP REQUEST.
+ */
+static int
+dhcp_request_req (struct dhcp_packet* call,
+ struct dhcp_packet* reply,
+ struct sockaddr_dl *sdl,
+ int broadcast)
+{
+ int len = 0;
+ unsigned long temp;
+ char *hostname;
+
+ memset (call, 0, sizeof (struct dhcp_packet));
+
+ /*
+ * Send a DHCP REQUEST Message
+ */
+ call->op = DHCP_BOOTREQUEST;
+ call->htype = 1; /* 10mb ethernet */
+ call->hlen = sdl->sdl_alen; /* Hardware address length */
+ call->hops = 0;
+ call->xid = reply->xid;
+ if (broadcast)
+ call->flags = htons (DHCP_BROADCAST);
+ else
+ {
+ call->flags = htons (DHCP_UNICAST);
+ call->ciaddr = reply->yiaddr;
+ }
+ memcpy (&call->chaddr, LLADDR (sdl), sdl->sdl_alen);
+
+ /*
+ * Magic cookie.
+ */
+ memcpy (&call->vend[len], dhcp_magic_cookie, sizeof (dhcp_magic_cookie));
+ len += sizeof (dhcp_magic_cookie);
+
+ /*
+ * DHCP Message type.
+ */
+ call->vend[len++] = DHCP_MESSAGE;
+ call->vend[len++] = 1;
+ call->vend[len++] = DHCP_REQUEST;
+
+ /*
+ * DHCP server
+ */
+ if (broadcast)
+ {
+ call->vend[len++] = DHCP_SERVER;
+ call->vend[len++] = sizeof (rtems_bsdnet_bootp_server_address);
+ memcpy (&call->vend[len], &rtems_bsdnet_bootp_server_address,
+ sizeof (rtems_bsdnet_bootp_server_address));
+ len += sizeof (rtems_bsdnet_bootp_server_address);
+ }
+
+ /*
+ * Requested IP
+ */
+ call->vend[len++] = DHCP_REQUESTED_IP;
+ call->vend[len++] = sizeof (reply->yiaddr);
+ memcpy (&call->vend[len], &reply->yiaddr, sizeof (reply->yiaddr));
+ len += sizeof (reply->yiaddr);
+
+ /*
+ * DHCP Parameter request list
+ */
+ call->vend[len++] = DHCP_PARAMETERS;
+ call->vend[len++] = sizeof (dhcp_request_parameters);
+ memcpy (&call->vend[len], &dhcp_request_parameters, sizeof (dhcp_request_parameters));
+ len += sizeof (dhcp_request_parameters);
+
+ /*
+ * Lease time.
+ * For the REQUEST, return the lease time the server offered.
+ */
+ call->vend[len++] = DHCP_LEASE;
+ call->vend[len++] = 4;
+ temp = htonl (dhcp_lease_time);
+ memcpy (&call->vend[len], &temp, sizeof (unsigned long));
+ len += 4;
+
+ /*
+ * Host name.
+ */
+ hostname = malloc (MAXHOSTNAMELEN, 0, M_NOWAIT);
+ if (hostname != NULL)
+ {
+ if (gethostname (hostname, MAXHOSTNAMELEN) == 0)
+ {
+ call->vend[len++] = DHCP_HOST;
+ call->vend[len++] = strlen (hostname);
+ strcpy ((char*) &call->vend[len], hostname);
+ len += strlen (hostname);
+ }
+ free (hostname, 0);
+ }
+
+ /*
+ * End.
+ */
+ call->vend[len++] = DHCP_OPTION_END;
+ call->secs = 0;
+
+ return len;
+}
+
+/*
+ * Variables for the DHCP task.
+ */
+static struct dhcp_packet dhcp_req;
+static rtems_id dhcp_task_id;
+
+/*
+ * The DHCP task counts until half the lease time has expired.
+ * When this period is up, it sends a DHCP REQUEST packet to the
+ * server again to renew the lease.
+ * If the lease is renewed, the task starts counting again.
+ * If the lease is not renewed, the task retries until it is.
+ *
+ * The task will not rebind if the lease is not renewed.
+ */
+static void
+dhcp_task (rtems_task_argument _sdl)
+{
+ unsigned long count;
+ struct dhcp_packet call;
+ struct sockaddr_dl *sdl;
+ rtems_event_set event_out;
+ unsigned int timeout = 0;
+ int error;
+ struct proc *procp = NULL;
+
+ sdl = (struct sockaddr_dl *) _sdl;
+
+ count = dhcp_elapsed_time;
+
+ while (TRUE)
+ {
+ if (count >= (dhcp_lease_time / 2))
+ {
+ rtems_bsdnet_semaphore_obtain ();
+
+ dhcp_request_req (&call, &dhcp_req, sdl, TRUE);
+
+ /*
+ * Send the Request.
+ */
+ error = bootpc_call (&call, &dhcp_req, procp);
+
+ if (error)
+ panic ("DHCP call failed -- error %d", error);
+
+ /*
+ * Check for DHCP ACK/NACK
+ */
+ if (memcmp (&dhcp_req.vend[0],
+ dhcp_magic_cookie,
+ sizeof (dhcp_magic_cookie)) != 0)
+ {
+ rtems_bsdnet_semaphore_release ();
+ panic ("DHCP server did not send Magic Cookie.\n");
+ }
+
+ process_options (&dhcp_req.vend[4], sizeof (dhcp_req.vend) - 4);
+
+ if (dhcp_message_type != DHCP_ACK)
+ {
+ rtems_bsdnet_semaphore_release ();
+ panic ("DHCP server did not accept the DHCP request");
+ }
+
+ rtems_bsdnet_semaphore_release ();
+
+ count = 0;
+ }
+
+ /*
+ * Sleep until the next poll
+ */
+ timeout = TOD_MILLISECONDS_TO_TICKS (1000);
+ rtems_event_receive (RTEMS_EVENT_0,
+ RTEMS_WAIT | RTEMS_EVENT_ANY,
+ timeout, &event_out);
+ count++;
+ }
+}
+
+/*
+ * Start the DHCP task.
+ */
+static rtems_status_code
+dhcp_start_task (struct sockaddr_dl *sdl,
+ struct dhcp_packet *reply,
+ int priority)
+{
+ rtems_status_code sc;
+
+ memcpy (&dhcp_req, reply, sizeof (struct dhcp_packet));
+
+ sc = rtems_task_create (rtems_build_name ('d','h','c','p'),
+ priority,
+ 2048,
+ RTEMS_PREEMPT |
+ RTEMS_NO_TIMESLICE |
+ RTEMS_NO_ASR |
+ RTEMS_INTERRUPT_LEVEL (0),
+ RTEMS_LOCAL,
+ &dhcp_task_id);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ return sc;
+
+ sc = rtems_task_start (dhcp_task_id,
+ dhcp_task,
+ (rtems_task_argument) sdl);
+
+ if (sc != RTEMS_SUCCESSFUL)
+ return sc;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Check if the chosen interface already has an IP.
+ */
+static int
+dhcp_interface_has_ip (struct ifreq *ireq, struct socket *so, struct proc *procp)
+{
+ struct sockaddr_in* sin;
+ int error;
+
+ /*
+ * Check if the interface is already up.
+ */
+ error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)ireq, procp);
+ if (error)
+ return 0;
+
+ if ((ireq->ifr_flags & IFF_UP) == 0)
+ return 0;
+
+ sin = (struct sockaddr_in *)&ireq->ifr_addr;
+ bzero ((caddr_t)sin, sizeof (struct sockaddr_in));
+ sin->sin_len = sizeof (struct sockaddr_in);
+ sin->sin_family = AF_INET;
+ error = ifioctl (so, SIOCGIFADDR, (caddr_t)ireq, procp);
+ if (error)
+ return 0;
+
+ if (sin->sin_addr.s_addr != 0)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * DCHP Client Routine
+ * - The first DHCP offer is always accepted
+ * - No DHCP DECLINE message is sent if ARPing fails
+ */
+void
+dhcp_init (int update_files)
+{
+ struct dhcp_packet call;
+ struct dhcp_packet reply;
+ static unsigned long xid = ~0xFF;
+ struct ifreq ireq;
+ struct ifnet *ifp;
+ struct socket *so;
+ int len;
+ int error;
+ struct sockaddr_in myaddr;
+ struct ifaddr *ifa;
+ struct sockaddr_dl *sdl = NULL;
+ struct proc *procp = NULL;
+
+ /*
+ * If already filled in, don't touch it here
+ */
+ if (nfs_diskless_valid)
+ return;
+
+ /*
+ * If we are to update the files create the root
+ * file structure.
+ */
+ if (update_files)
+ if (rtems_create_root_fs () < 0) {
+ printf("Error creating the root filesystem.\nFile not created.\n");
+ update_files = 0;
+ }
+
+ /*
+ * Find a network interface.
+ */
+ for (ifp = ifnet; ifp != 0; ifp = ifp->if_next)
+ if ((ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) == 0)
+ break;
+ if (ifp == NULL)
+ panic ("dhcpc_init: no suitable interface");
+ memset (&ireq, 0, sizeof (ireq));
+ sprintf (ireq.ifr_name, "%s%d", ifp->if_name, ifp->if_unit);
+
+ if ((error = socreate (AF_INET, &so, SOCK_DGRAM, 0, procp)) != 0)
+ panic ("nfs_boot: socreate, error=%d", error);
+
+ if (!dhcp_interface_has_ip (&ireq, so, procp))
+ bootpc_fakeup_interface (&ireq, so, procp);
+
+ /*
+ * Get HW address
+ */
+ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
+ if (ifa->ifa_addr->sa_family == AF_LINK &&
+ (sdl = ((struct sockaddr_dl *) ifa->ifa_addr)) &&
+ sdl->sdl_type == IFT_ETHER)
+ break;
+
+ if (!sdl)
+ panic ("dhcpc: Unable to find HW address");
+ if (sdl->sdl_alen != EALEN)
+ panic ("dhcpc: HW address len is %d, expected value is %d",
+ sdl->sdl_alen, EALEN);
+
+ /*
+ * Build the DHCP Discover
+ */
+ len = dhcp_discover_req (&call, sdl, &xid);
+
+ /*
+ * Send the Discover.
+ */
+ error = bootpc_call (&call, &reply, procp);
+ if (error)
+ panic ("BOOTP call failed -- error %d", error);
+
+ /*
+ * Check for DHCP OFFER
+ */
+ if (memcmp (&reply.vend[0], dhcp_magic_cookie, sizeof (dhcp_magic_cookie)) != 0)
+ panic ("DHCP server did not send Magic Cookie.\n");
+
+ process_options (&reply.vend[4], sizeof (reply.vend) - 4);
+
+ if (dhcp_message_type != DHCP_OFFER)
+ panic ("DHCP server did not send a DHCP Offer.\n");
+
+ /*
+ * Send a DHCP REQUEST
+ */
+ dhcp_request_req (&call, &reply, sdl, TRUE);
+
+ error = bootpc_call (&call, &reply, procp);
+ if (error)
+ panic ("BOOTP call failed -- error %d", error);
+
+ /*
+ * Check for DHCP ACK/NACK
+ */
+ if (memcmp (&reply.vend[0], dhcp_magic_cookie, sizeof (dhcp_magic_cookie)) != 0)
+ panic ("DHCP server did not send Magic Cookie.\n");
+
+ process_options (&reply.vend[4], sizeof (reply.vend) - 4);
+
+ if (dhcp_message_type != DHCP_ACK)
+ panic ("DHCP server did not accept the DHCP request");
+
+ /*
+ * Initialize network address structures
+ */
+ memset (&myaddr, 0, sizeof (myaddr));
+ memset (&dhcp_netmask, 0, sizeof (dhcp_netmask));
+ memset (&dhcp_gw, 0, sizeof (dhcp_gw));
+ myaddr.sin_len = sizeof (myaddr);
+ myaddr.sin_family = AF_INET;
+ dhcp_netmask.sin_len = sizeof (dhcp_netmask);
+ dhcp_netmask.sin_family = AF_INET;
+ dhcp_gw.sin_len = sizeof (dhcp_gw);
+ dhcp_gw.sin_family = AF_INET;
+
+ /*
+ * Set our address
+ */
+ myaddr.sin_addr = reply.yiaddr;
+
+ /*
+ * Process BOOTP/DHCP options
+ */
+ if (memcmp (&reply.vend[0], dhcp_magic_cookie, sizeof (dhcp_magic_cookie)) == 0)
+ process_options (&reply.vend[4], sizeof (reply.vend) - 4);
+
+ if (dhcp_option_overload & 1)
+ process_options ((unsigned char*) reply.file, sizeof reply.file);
+ else
+ if (reply.file[0])
+ rtems_bsdnet_bootp_boot_file_name = strdup (reply.file);
+
+ if (dhcp_option_overload & 2)
+ process_options ((unsigned char*) reply.sname, sizeof reply.sname);
+ else
+ if (reply.sname[0])
+ rtems_bsdnet_bootp_server_name = strdup (reply.sname);
+
+ /*
+ * Use defaults if values were not supplied by BOOTP/DHCP options
+ */
+ if (!dhcp_gotnetmask)
+ {
+ if (IN_CLASSA (ntohl (myaddr.sin_addr.s_addr)))
+ dhcp_netmask.sin_addr.s_addr = htonl (IN_CLASSA_NET);
+ else if (IN_CLASSB (ntohl (myaddr.sin_addr.s_addr)))
+ dhcp_netmask.sin_addr.s_addr = htonl (IN_CLASSB_NET);
+ else
+ dhcp_netmask.sin_addr.s_addr = htonl (IN_CLASSC_NET);
+ }
+
+ if (!dhcp_gotserver)
+ rtems_bsdnet_bootp_server_address = reply.siaddr;
+
+ if (!dhcp_gotgw)
+ dhcp_gw.sin_addr = reply.giaddr;
+
+ if (!dhcp_gotlogserver)
+ rtems_bsdnet_log_host_address = rtems_bsdnet_bootp_server_address;
+
+ printsetup (ifp->if_name, myaddr.sin_addr, dhcp_netmask.sin_addr,
+ rtems_bsdnet_bootp_server_address, dhcp_gw.sin_addr);
+
+ /*
+ * Update the files if we are asked too.
+ */
+ if (update_files) {
+ char *dn = rtems_bsdnet_domain_name;
+ char *hn = dhcp_hostname;
+ if (!dn)
+ dn = "mydomain";
+ if (!hn)
+ {
+ hn = "me";
+ sethostname (hn, strlen (hn));
+ }
+ rtems_rootfs_append_host_rec(*((unsigned long*) &myaddr.sin_addr), hn, dn);
+
+ /*
+ * Should the given domainname be used here ?
+ */
+ if (dhcp_gotserver) {
+ if (rtems_bsdnet_bootp_server_name)
+ hn = rtems_bsdnet_bootp_server_name;
+ else
+ hn = "bootps";
+ rtems_rootfs_append_host_rec(*((unsigned long *) &rtems_bsdnet_bootp_server_address),
+ hn, dn);
+ }
+
+ if (dhcp_gotlogserver) {
+ rtems_rootfs_append_host_rec(*((unsigned long *) &rtems_bsdnet_log_host_address),
+ "logs", dn);
+ }
+
+ /*
+ * Setup the DNS configuration file /etc/resolv.conf.
+ */
+ if (rtems_bsdnet_nameserver_count) {
+ int i;
+ char buf[64];
+ const char *bufl[1];
+
+ bufl[0] = buf;
+
+#define MKFILE_MODE (S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH)
+
+ if (rtems_bsdnet_domain_name &&
+ (strlen(rtems_bsdnet_domain_name) < (sizeof(buf) - 1))) {
+ strcpy(buf, "search ");
+ strcat(buf, rtems_bsdnet_domain_name);
+ strcat(buf, "\n");
+ rtems_rootfs_file_append ("/etc/resolv.conf", MKFILE_MODE, 1, bufl);
+ }
+
+ for (i = 0; i < rtems_bsdnet_nameserver_count; i++) {
+ strcpy(buf, "nameserver ");
+ strcat(buf, inet_ntoa(rtems_bsdnet_ntpserver[i]));
+ strcat(buf, "\n");
+ if (rtems_rootfs_file_append ("/etc/resolv.conf", MKFILE_MODE, 1, bufl))
+ break;
+ }
+ }
+ }
+
+ /*
+ * Configure the interface with the new settings
+ */
+ error = bootpc_adjust_interface (&ireq, so,
+ &myaddr, &dhcp_netmask, &dhcp_gw, procp);
+
+ /*
+ * Start the DHCP task if the lease isn't infinite.
+ */
+ if (dhcp_lease_time != 0xffffffff)
+ dhcp_start_task (sdl, &reply, 150);
+
+ soclose (so);
+}
+
+/*
+ *
+ * RTEMS Entry point to DHCP client
+ *
+ */
+void rtems_bsdnet_do_dhcp (void)
+{
+ rtems_bsdnet_semaphore_obtain ();
+ dhcp_init (TRUE);
+ rtems_bsdnet_semaphore_release ();
+}
+
+void
+rtems_bsdnet_do_dhcp_refresh_only (unsigned long xid,
+ unsigned long lease_time,
+ unsigned long elapsed_time,
+ unsigned long ip_address,
+ unsigned long srv_address,
+ const char* hostname)
+{
+ struct dhcp_packet reply;
+ struct ifnet *ifp = NULL;
+ struct ifaddr *ifa = NULL;
+ struct sockaddr_dl *sdl = NULL;
+ struct sockaddr_in *sin = NULL;
+ int match = 0;
+ struct ifnet *mtif = NULL;
+
+ /*
+ * If an infinite lease has been granted, no task is needed.
+ */
+ if (lease_time == 0xffffffff)
+ return;
+
+ /*
+ * Find a network interface.
+ */
+ for (ifp = ifnet; (ifp != NULL) && !match; ifp = ifp->if_next)
+ if ((ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) == 0)
+ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
+ if (ifa->ifa_addr->sa_family == AF_INET)
+ {
+ sin = (struct sockaddr_in *) ifa->ifa_addr;
+ if (sin->sin_addr.s_addr == htonl (ip_address))
+ {
+ mtif = ifp;
+ match = 1;
+ break;
+ }
+ }
+
+ if (!match)
+ panic ("dhcpc: no matching interface");
+
+ for (ifa = mtif->if_addrlist; ifa != NULL; ifa = ifa->ifa_next)
+ if (ifa->ifa_addr->sa_family == AF_LINK &&
+ (sdl = ((struct sockaddr_dl *) ifa->ifa_addr)) &&
+ sdl->sdl_type == IFT_ETHER)
+ break;
+
+ if (!match)
+ panic ("dhcpc: no matching interface");
+
+ /*
+ * Set up given values in a simulated DHCP reply.
+ */
+ memset (&reply, 0x00, sizeof (reply));
+ reply.xid = htonl (xid);
+ reply.yiaddr.s_addr = htonl (ip_address);
+ reply.siaddr.s_addr = htonl (srv_address);
+ if (reply.siaddr.s_addr != rtems_bsdnet_bootp_server_address.s_addr)
+ {
+ memcpy (&rtems_bsdnet_bootp_server_address, &reply.siaddr,
+ sizeof (reply.siaddr));
+ }
+
+ dhcp_lease_time = lease_time;
+ dhcp_elapsed_time = elapsed_time;
+
+ if (hostname)
+ {
+ sethostname ((char *) hostname, strlen (hostname));
+ dhcp_hostname = bootp_strdup_realloc (dhcp_hostname, hostname);
+ }
+
+ dhcp_start_task (sdl, &reply, 150);
+}
+
+#undef D_COMPILING_BSD_KERNEL
+#undef KERNEL
diff --git a/cpukit/libnetworking/rtems/rtems_glue.c b/cpukit/libnetworking/rtems/rtems_glue.c
new file mode 100644
index 0000000000..657a2f862e
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_glue.c
@@ -0,0 +1,1233 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define RTEMS_FAST_MUTEX
+
+#ifdef RTEMS_FAST_MUTEX
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
+#endif
+
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/domain.h>
+#include <sys/mbuf.h>
+#include <sys/socketvar.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/callout.h>
+#include <sys/proc.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <vm/vm.h>
+#include <arpa/inet.h>
+
+#include <net/netisr.h>
+#include <net/route.h>
+
+/*
+ * Sysctl init all.
+ */
+void sysctl_register_all(void *arg);
+
+/*
+ * Memory allocation
+ */
+static int nmbuf = (64 * 1024) / MSIZE;
+ int nmbclusters = (128 * 1024) / MCLBYTES;
+
+/*
+ * Network task synchronization
+ */
+static rtems_id networkSemaphore;
+#ifdef RTEMS_FAST_MUTEX
+Semaphore_Control *the_networkSemaphore;
+#endif
+static rtems_id networkDaemonTid;
+static uint32_t networkDaemonPriority;
+static void networkDaemon (void *task_argument);
+
+/*
+ * Network timing
+ */
+int rtems_bsdnet_ticks_per_second;
+int rtems_bsdnet_microseconds_per_tick;
+
+/*
+ * Callout processing
+ */
+static rtems_interval ticksWhenCalloutsLastChecked;
+struct callout *callfree = NULL;
+struct callout calltodo;
+
+/*
+ * FreeBSD variables
+ */
+int nfs_diskless_valid;
+
+/*
+ * BOOTP values
+ */
+struct in_addr rtems_bsdnet_log_host_address = {0};
+struct in_addr rtems_bsdnet_bootp_server_address = {0};
+char *rtems_bsdnet_bootp_boot_file_name = 0;
+char *rtems_bsdnet_bootp_server_name = 0;
+char *rtems_bsdnet_domain_name = 0;
+char *rtems_bsdnet_bootp_cmdline = 0;
+static struct in_addr _rtems_bsdnet_nameserver[sizeof rtems_bsdnet_config.name_server /
+ sizeof rtems_bsdnet_config.name_server[0]];
+struct in_addr *rtems_bsdnet_nameserver = _rtems_bsdnet_nameserver;
+int rtems_bsdnet_nameserver_count = 0;
+static struct in_addr _rtems_bsdnet_ntpserver[sizeof rtems_bsdnet_config.ntp_server /
+ sizeof rtems_bsdnet_config.ntp_server[0]];
+struct in_addr *rtems_bsdnet_ntpserver = _rtems_bsdnet_ntpserver;
+int rtems_bsdnet_ntpserver_count = 0;
+long rtems_bsdnet_timeoffset = 0;
+
+/*
+ * Perform FreeBSD memory allocation.
+ * FIXME: This should be modified to keep memory allocation statistics.
+ */
+#undef malloc
+#undef free
+extern void *malloc (size_t);
+extern void free (void *);
+void *
+rtems_bsdnet_malloc (unsigned long size, int type, int flags)
+{
+ void *p;
+ int try = 0;
+
+ for (;;) {
+ p = malloc (size);
+ if (p || (flags & M_NOWAIT))
+ return p;
+ rtems_bsdnet_semaphore_release ();
+ if (++try >= 30) {
+ rtems_bsdnet_malloc_starvation();
+ try = 0;
+ }
+ rtems_task_wake_after (rtems_bsdnet_ticks_per_second);
+ rtems_bsdnet_semaphore_obtain ();
+ }
+}
+
+/*
+ * Free FreeBSD memory
+ * FIXME: This should be modified to keep memory allocation statistics.
+ */
+void
+rtems_bsdnet_free (void *addr, int type)
+{
+ free (addr);
+}
+
+/*
+ * Do the initializations required by the BSD code
+ */
+static int
+bsd_init (void)
+{
+ int i;
+ char *p;
+
+ /*
+ * Set up mbuf cluster data strutures
+ */
+ p = rtems_bsdnet_malloc_mbuf ((nmbclusters*MCLBYTES)+MCLBYTES-1, MBUF_MALLOC_NMBCLUSTERS);
+ if (p == NULL) {
+ printf ("Can't get network cluster memory.\n");
+ return -1;
+ }
+ p = (char *)(((unsigned long)p + (MCLBYTES-1)) & ~(MCLBYTES-1));
+ mbutl = (struct mbuf *)p;
+ for (i = 0; i < nmbclusters; i++) {
+ ((union mcluster *)p)->mcl_next = mclfree;
+ mclfree = (union mcluster *)p;
+ p += MCLBYTES;
+ mbstat.m_clfree++;
+ }
+ mbstat.m_clusters = nmbclusters;
+ mclrefcnt = rtems_bsdnet_malloc_mbuf (nmbclusters, MBUF_MALLOC_MCLREFCNT);
+ if (mclrefcnt == NULL) {
+ printf ("Can't get mbuf cluster reference counts memory.\n");
+ return -1;
+ }
+ memset (mclrefcnt, '\0', nmbclusters);
+
+ /*
+ * Set up mbuf data structures
+ */
+
+ p = rtems_bsdnet_malloc_mbuf(nmbuf * MSIZE + MSIZE - 1,MBUF_MALLOC_MBUF);
+ p = (char *)(((unsigned int)p + MSIZE - 1) & ~(MSIZE - 1));
+ if (p == NULL) {
+ printf ("Can't get network memory.\n");
+ return -1;
+ }
+ for (i = 0; i < nmbuf; i++) {
+ ((struct mbuf *)p)->m_next = mmbfree;
+ mmbfree = (struct mbuf *)p;
+ p += MSIZE;
+ }
+ mbstat.m_mbufs = nmbuf;
+ mbstat.m_mtypes[MT_FREE] = nmbuf;
+
+ /*
+ * Set up domains
+ */
+ {
+ extern struct domain routedomain;
+ extern struct domain inetdomain;
+
+ routedomain.dom_next = domains;
+ domains = &routedomain;
+ inetdomain.dom_next = domains;
+ domains = &inetdomain;
+ domaininit (NULL);
+ }
+
+ /*
+ * Setup the sysctl, normally done by a SYSINIT call.
+ */
+ sysctl_register_all(0);
+
+ /*
+ * Set up interfaces
+ */
+ ifinit (NULL);
+ return 0;
+}
+
+/*
+ * Initialize and start network operations
+ */
+static int
+rtems_bsdnet_initialize (void)
+{
+ rtems_status_code sc;
+
+ /*
+ * Set the priority of all network tasks
+ */
+ if (rtems_bsdnet_config.network_task_priority == 0)
+ networkDaemonPriority = 100;
+ else
+ networkDaemonPriority = rtems_bsdnet_config.network_task_priority;
+
+ /*
+ * Set the memory allocation limits
+ */
+ if (rtems_bsdnet_config.mbuf_bytecount)
+ nmbuf = rtems_bsdnet_config.mbuf_bytecount / MSIZE;
+ if (rtems_bsdnet_config.mbuf_cluster_bytecount)
+ nmbclusters = rtems_bsdnet_config.mbuf_cluster_bytecount / MCLBYTES;
+
+ /*
+ * Create the task-synchronization semaphore
+ */
+ sc = rtems_semaphore_create (rtems_build_name('B', 'S', 'D', 'n'),
+ 0,
+ RTEMS_PRIORITY |
+ RTEMS_BINARY_SEMAPHORE |
+ RTEMS_INHERIT_PRIORITY |
+ RTEMS_NO_PRIORITY_CEILING |
+ RTEMS_LOCAL,
+ 0,
+ &networkSemaphore);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("Can't create network seamphore: `%s'\n", rtems_status_text (sc));
+ return -1;
+ }
+#ifdef RTEMS_FAST_MUTEX
+ {
+ Objects_Locations location;
+ the_networkSemaphore = _Semaphore_Get( networkSemaphore, &location );
+ _Thread_Enable_dispatch();
+ }
+#endif
+
+ /*
+ * Compute clock tick conversion factors
+ */
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &rtems_bsdnet_ticks_per_second);
+ if (rtems_bsdnet_ticks_per_second <= 0)
+ rtems_bsdnet_ticks_per_second = 1;
+ rtems_bsdnet_microseconds_per_tick = 1000000 / rtems_bsdnet_ticks_per_second;
+
+ /*
+ * Ensure that `seconds' is greater than 0
+ */
+ while (rtems_bsdnet_seconds_since_boot() == 0)
+ rtems_task_wake_after(1);
+
+ /*
+ * Set up BSD-style sockets
+ */
+ if (bsd_init () < 0)
+ return -1;
+
+ /*
+ * Start network daemon
+ */
+ networkDaemonTid = rtems_bsdnet_newproc ("ntwk", 4096, networkDaemon, NULL);
+
+ /*
+ * Let other network tasks begin
+ */
+ rtems_bsdnet_semaphore_release ();
+ return 0;
+}
+
+/*
+ * Obtain network mutex
+ */
+void
+rtems_bsdnet_semaphore_obtain (void)
+{
+#ifdef RTEMS_FAST_MUTEX
+ ISR_Level level;
+ _ISR_Disable (level);
+ _CORE_mutex_Seize (
+ &the_networkSemaphore->Core_control.mutex,
+ networkSemaphore,
+ 1, /* wait */
+ 0, /* forever */
+ level
+ );
+ if (_Thread_Executing->Wait.return_code)
+ rtems_panic ("Can't obtain network semaphore\n");
+#else
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain (networkSemaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_panic ("Can't obtain network semaphore: `%s'\n", rtems_status_text (sc));
+#endif
+}
+
+/*
+ * Release network mutex
+ */
+void
+rtems_bsdnet_semaphore_release (void)
+{
+#ifdef RTEMS_FAST_MUTEX
+ int i;
+
+ _Thread_Disable_dispatch();
+ i = _CORE_mutex_Surrender (
+ &the_networkSemaphore->Core_control.mutex,
+ networkSemaphore,
+ NULL
+ );
+ _Thread_Enable_dispatch();
+ if (i)
+ rtems_panic ("Can't release network semaphore\n");
+#else
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_release (networkSemaphore);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_panic ("Can't release network semaphore: `%s'\n", rtems_status_text (sc));
+#endif
+}
+
+/*
+ * Wait for something to happen to a socket buffer
+ */
+int
+sbwait(sb)
+ struct sockbuf *sb;
+{
+ rtems_event_set events;
+ rtems_id tid;
+ rtems_status_code sc;
+
+ /*
+ * Soak up any pending events.
+ * The sleep/wakeup synchronization in the FreeBSD
+ * kernel has no memory.
+ */
+ rtems_event_receive (SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT, &events);
+
+ /*
+ * Set this task as the target of the wakeup operation.
+ */
+ rtems_task_ident (RTEMS_SELF, 0, &tid);
+ sb->sb_sel.si_pid = tid;
+
+ /*
+ * Show that socket is waiting
+ */
+ sb->sb_flags |= SB_WAIT;
+
+ /*
+ * Release the network semaphore.
+ */
+ rtems_bsdnet_semaphore_release ();
+
+ /*
+ * Wait for the wakeup event.
+ */
+ sc = rtems_event_receive (SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, sb->sb_timeo, &events);
+
+ /*
+ * Reobtain the network semaphore.
+ */
+ rtems_bsdnet_semaphore_obtain ();
+
+ /*
+ * Return the status of the wait.
+ */
+ switch (sc) {
+ case RTEMS_SUCCESSFUL: return 0;
+ case RTEMS_TIMEOUT: return EWOULDBLOCK;
+ default: return ENXIO;
+ }
+}
+
+
+/*
+ * Wake up the task waiting on a socket buffer.
+ */
+void
+sowakeup(so, sb)
+ register struct socket *so;
+ register struct sockbuf *sb;
+{
+ if (sb->sb_flags & SB_WAIT) {
+ sb->sb_flags &= ~SB_WAIT;
+ rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT);
+ }
+ if (sb->sb_wakeup) {
+ (*sb->sb_wakeup) (so, sb->sb_wakeuparg);
+ }
+}
+
+/*
+ * For now, a socket can be used by only one task at a time.
+ */
+int
+sb_lock(sb)
+ register struct sockbuf *sb;
+{
+ rtems_panic ("Socket buffer is already in use.");
+ return 0;
+}
+void
+wakeup (void *p)
+{
+ rtems_panic ("Wakeup called");
+}
+
+/*
+ * Wait for a connection/disconnection event.
+ */
+int
+soconnsleep (struct socket *so)
+{
+ rtems_event_set events;
+ rtems_id tid;
+ rtems_status_code sc;
+
+ /*
+ * Soak up any pending events.
+ * The sleep/wakeup synchronization in the FreeBSD
+ * kernel has no memory.
+ */
+ rtems_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT, &events);
+
+ /*
+ * Set this task as the target of the wakeup operation.
+ */
+ if (so->so_pgid)
+ rtems_panic ("Another task is already sleeping on that socket");
+ rtems_task_ident (RTEMS_SELF, 0, &tid);
+ so->so_pgid = tid;
+
+ /*
+ * Wait for the wakeup event.
+ */
+ sc = rtems_bsdnet_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, so->so_rcv.sb_timeo, &events);
+
+ /*
+ * Relinquish ownership of the socket.
+ */
+ so->so_pgid = 0;
+
+ switch (sc) {
+ case RTEMS_SUCCESSFUL: return 0;
+ case RTEMS_TIMEOUT: return EWOULDBLOCK;
+ default: return ENXIO;
+ }
+}
+
+/*
+ * Wake up a task waiting for a connection/disconnection to complete.
+ */
+void
+soconnwakeup (struct socket *so)
+{
+ if (so->so_pgid)
+ rtems_event_send (so->so_pgid, SOSLEEP_EVENT);
+}
+
+/*
+ * Send an event to the network daemon.
+ * This corresponds to sending a software interrupt in the BSD kernel.
+ */
+void
+rtems_bsdnet_schednetisr (int n)
+{
+ rtems_event_send (networkDaemonTid, 1 << n);
+}
+
+/*
+ * The network daemon
+ * This provides a context to run BSD software interrupts
+ */
+static void
+networkDaemon (void *task_argument)
+{
+ rtems_status_code sc;
+ rtems_event_set events;
+ rtems_interval now;
+ int ticksPassed;
+ uint32_t timeout;
+ struct callout *c;
+
+ for (;;) {
+ c = calltodo.c_next;
+ if (c)
+ timeout = c->c_time;
+ else
+ timeout = RTEMS_NO_TIMEOUT;
+
+ sc = rtems_bsdnet_event_receive (NETISR_EVENTS,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ timeout,
+ &events);
+ if ( sc == RTEMS_SUCCESSFUL ) {
+ if (events & NETISR_IP_EVENT)
+ ipintr ();
+ if (events & NETISR_ARP_EVENT)
+ arpintr ();
+ }
+
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ ticksPassed = now - ticksWhenCalloutsLastChecked;
+ if (ticksPassed != 0) {
+ ticksWhenCalloutsLastChecked = now;
+
+ c = calltodo.c_next;
+ if (c) {
+ c->c_time -= ticksPassed;
+ while ((c = calltodo.c_next) != NULL && c->c_time <= 0) {
+ void *arg;
+ void (*func) (void *);
+
+ func = c->c_func;
+ arg = c->c_arg;
+ calltodo.c_next = c->c_next;
+ c->c_next = callfree;
+ callfree = c;
+ (*func)(arg);
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Structure passed to task-start stub
+ */
+struct newtask {
+ void (*entry)(void *);
+ void *arg;
+};
+
+/*
+ * Task-start stub
+ */
+static void
+taskEntry (rtems_task_argument arg)
+{
+ struct newtask t;
+
+ /*
+ * Pick up task information and free
+ * the memory allocated to pass the
+ * information to this task.
+ */
+ t = *(struct newtask *)arg;
+ free ((struct newtask *)arg);
+
+ /*
+ * Enter the competition for the network semaphore
+ */
+ rtems_bsdnet_semaphore_obtain ();
+
+ /*
+ * Enter the task
+ */
+ (*t.entry)(t.arg);
+ rtems_panic ("Network task returned!\n");
+}
+
+/*
+ * Start a network task
+ */
+rtems_id
+rtems_bsdnet_newproc (char *name, int stacksize, void(*entry)(void *), void *arg)
+{
+ struct newtask *t;
+ char nm[4];
+ rtems_id tid;
+ rtems_status_code sc;
+
+ strncpy (nm, name, 4);
+ sc = rtems_task_create (rtems_build_name(nm[0], nm[1], nm[2], nm[3]),
+ networkDaemonPriority,
+ stacksize,
+ RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
+ &tid);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_panic ("Can't create network daemon `%s': `%s'\n", name, rtems_status_text (sc));
+
+ /*
+ * Set up task arguments
+ */
+ t = malloc (sizeof *t);
+ t->entry = entry;
+ t->arg = arg;
+
+ /*
+ * Start the task
+ */
+ sc = rtems_task_start (tid, taskEntry, (rtems_task_argument)t);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_panic ("Can't start network daemon `%s': `%s'\n", name, rtems_status_text (sc));
+
+ /*
+ * Let our caller know the i.d. of the new task
+ */
+ return tid;
+}
+
+rtems_status_code rtems_bsdnet_event_receive (
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out)
+{
+ rtems_status_code sc;
+
+ rtems_bsdnet_semaphore_release ();
+ sc = rtems_event_receive (event_in, option_set, ticks, event_out);
+ rtems_bsdnet_semaphore_obtain ();
+ return sc;
+}
+
+/*
+ * Return time since startup
+ */
+void
+microtime (struct timeval *t)
+{
+ rtems_interval now;
+
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ t->tv_sec = now / rtems_bsdnet_ticks_per_second;
+ t->tv_usec = (now % rtems_bsdnet_ticks_per_second) * rtems_bsdnet_microseconds_per_tick;
+}
+
+unsigned long
+rtems_bsdnet_seconds_since_boot (void)
+{
+ rtems_interval now;
+
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ return now / rtems_bsdnet_ticks_per_second;
+}
+
+/*
+ * Fake random number generator
+ */
+unsigned long
+rtems_bsdnet_random (void)
+{
+ rtems_interval now;
+
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ return (now * 99991);
+}
+
+/*
+ * Callout list processing
+ */
+void
+timeout(void (*ftn)(void *), void *arg, int ticks)
+{
+ register struct callout *new, *p, *t;
+
+ if (ticks <= 0)
+ ticks = 1;
+
+ /* Fill in the next free callout structure. */
+ if (callfree == NULL) {
+ callfree = malloc (sizeof *callfree);
+ if (callfree == NULL)
+ rtems_panic ("No memory for timeout table entry");
+ callfree->c_next = NULL;
+ }
+
+ new = callfree;
+ callfree = new->c_next;
+ new->c_arg = arg;
+ new->c_func = ftn;
+
+ /*
+ * The time for each event is stored as a difference from the time
+ * of the previous event on the queue. Walk the queue, correcting
+ * the ticks argument for queue entries passed. Correct the ticks
+ * value for the queue entry immediately after the insertion point
+ * as well. Watch out for negative c_time values; these represent
+ * overdue events.
+ */
+ for (p = &calltodo;
+ (t = p->c_next) != NULL && ticks > t->c_time; p = t)
+ if (t->c_time > 0)
+ ticks -= t->c_time;
+ new->c_time = ticks;
+ if (t != NULL)
+ t->c_time -= ticks;
+
+ /* Insert the new entry into the queue. */
+ p->c_next = new;
+ new->c_next = t;
+}
+
+/*
+ * Ticks till specified time
+ * XXX: This version worries only about seconds, but that's good
+ * enough for the way the network code uses this routine.
+ */
+int
+hzto(struct timeval *tv)
+{
+ long diff = tv->tv_sec - rtems_bsdnet_seconds_since_boot();
+
+ if (diff <= 0)
+ return 1;
+ return diff * rtems_bsdnet_ticks_per_second;
+}
+
+/*
+ * Kernel debugging
+ */
+int rtems_bsdnet_log_priority;
+void
+rtems_bsdnet_log (int priority, const char *fmt, ...)
+{
+ va_list args;
+
+ if (priority & rtems_bsdnet_log_priority) {
+ va_start (args, fmt);
+ vprintf (fmt, args);
+ va_end (args);
+ }
+}
+
+/*
+ * IP header checksum routine for processors which don't have an inline version
+ */
+u_int
+in_cksum_hdr (const void *ip)
+{
+ uint32_t sum;
+ const uint16_t *sp;
+ int i;
+
+ sum = 0;
+ sp = (uint16_t *)ip;
+ for (i = 0 ; i < 10 ; i++)
+ sum += *sp++;
+ while (sum > 0xFFFF)
+ sum = (sum & 0xffff) + (sum >> 16);
+ return ~sum & 0xFFFF;
+}
+
+/*
+ * Manipulate routing tables
+ */
+int rtems_bsdnet_rtrequest (
+ int req,
+ struct sockaddr *dst,
+ struct sockaddr *gateway,
+ struct sockaddr *netmask,
+ int flags,
+ struct rtentry **net_nrt)
+{
+ int error;
+
+ rtems_bsdnet_semaphore_obtain ();
+ error = rtrequest (req, dst, gateway, netmask, flags, net_nrt);
+ rtems_bsdnet_semaphore_release ();
+ if (error) {
+ errno = error;
+ return -1;
+ }
+ return 0;
+}
+
+static int
+rtems_bsdnet_setup (void)
+{
+ struct rtems_bsdnet_ifconfig *ifp;
+ short flags;
+ struct sockaddr_in address;
+ struct sockaddr_in netmask;
+ struct sockaddr_in broadcast;
+ struct sockaddr_in gateway;
+ int i;
+ extern char *strdup (const char *cp);
+
+ /*
+ * Set local parameters
+ */
+ if (rtems_bsdnet_config.hostname)
+ sethostname (rtems_bsdnet_config.hostname,
+ strlen (rtems_bsdnet_config.hostname));
+ if (rtems_bsdnet_config.domainname)
+ rtems_bsdnet_domain_name =
+ strdup (rtems_bsdnet_config.domainname);
+ if (rtems_bsdnet_config.log_host)
+ rtems_bsdnet_log_host_address.s_addr =
+ inet_addr (rtems_bsdnet_config.log_host);
+ for (i = 0 ; i < sizeof rtems_bsdnet_config.name_server /
+ sizeof rtems_bsdnet_config.name_server[0] ; i++) {
+ if (!rtems_bsdnet_config.name_server[i])
+ break;
+ rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count++].s_addr
+ = inet_addr (rtems_bsdnet_config.name_server[i]);
+ }
+ for (i = 0 ; i < sizeof rtems_bsdnet_config.ntp_server /
+ sizeof rtems_bsdnet_config.ntp_server[0] ; i++) {
+ if (!rtems_bsdnet_config.ntp_server[i])
+ break;
+ rtems_bsdnet_ntpserver[rtems_bsdnet_ntpserver_count++].s_addr
+ = inet_addr (rtems_bsdnet_config.ntp_server[i]);
+ }
+
+ /*
+ * Configure interfaces
+ */
+ for (ifp = rtems_bsdnet_config.ifconfig ; ifp ; ifp = ifp->next) {
+ if (ifp->ip_address == NULL)
+ continue;
+
+ /*
+ * Bring interface up
+ */
+ flags = IFF_UP;
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFFLAGS, &flags) < 0) {
+ printf ("Can't bring %s up: %s\n", ifp->name, strerror (errno));
+ continue;
+ }
+
+ /*
+ * Set interface netmask
+ */
+ memset (&netmask, '\0', sizeof netmask);
+ netmask.sin_len = sizeof netmask;
+ netmask.sin_family = AF_INET;
+ netmask.sin_addr.s_addr = inet_addr (ifp->ip_netmask);
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFNETMASK, &netmask) < 0) {
+ printf ("Can't set %s netmask: %s\n", ifp->name, strerror (errno));
+ continue;
+ }
+
+ /*
+ * Set interface address
+ */
+ memset (&address, '\0', sizeof address);
+ address.sin_len = sizeof address;
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = inet_addr (ifp->ip_address);
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFADDR, &address) < 0) {
+ printf ("Can't set %s address: %s\n", ifp->name, strerror (errno));
+ continue;
+ }
+
+ /*
+ * Set interface broadcast address if the interface has the
+ * broadcast flag set.
+ */
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCGIFFLAGS, &flags) < 0) {
+ printf ("Can't read %s flags: %s\n", ifp->name, strerror (errno));
+ continue;
+ }
+ if (flags & IFF_BROADCAST) {
+ memset (&broadcast, '\0', sizeof broadcast);
+ broadcast.sin_len = sizeof broadcast;
+ broadcast.sin_family = AF_INET;
+ broadcast.sin_addr.s_addr =
+ address.sin_addr.s_addr | ~netmask.sin_addr.s_addr;
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFBRDADDR, &broadcast) < 0) {
+ struct in_addr in_addr;
+ char buf[20];
+ in_addr.s_addr = broadcast.sin_addr.s_addr;
+ if (!inet_ntop(AF_INET, &in_addr, buf, sizeof(buf)))
+ strcpy(buf,"?.?.?.?");
+ printf ("Can't set %s broadcast address %s: %s\n",
+ ifp->name, buf, strerror (errno));
+ }
+ }
+ }
+
+ /*
+ * Set default route
+ */
+ if (rtems_bsdnet_config.gateway) {
+ address.sin_addr.s_addr = INADDR_ANY;
+ netmask.sin_addr.s_addr = INADDR_ANY;
+ memset (&gateway, '\0', sizeof gateway);
+ gateway.sin_len = sizeof gateway;
+ gateway.sin_family = AF_INET;
+ gateway.sin_addr.s_addr = inet_addr (rtems_bsdnet_config.gateway);
+ if (rtems_bsdnet_rtrequest (
+ RTM_ADD,
+ (struct sockaddr *)&address,
+ (struct sockaddr *)&gateway,
+ (struct sockaddr *)&netmask,
+ (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL) < 0) {
+ printf ("Can't set default route: %s\n", strerror (errno));
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Initialize the network
+ */
+int
+rtems_bsdnet_initialize_network (void)
+{
+ struct rtems_bsdnet_ifconfig *ifp;
+
+ /*
+ * Start network tasks.
+ * Initialize BSD network data structures.
+ */
+ if (rtems_bsdnet_initialize () < 0)
+ return -1;
+
+ /*
+ * Attach interfaces
+ */
+ for (ifp = rtems_bsdnet_config.ifconfig ; ifp ; ifp = ifp->next) {
+ rtems_bsdnet_attach (ifp);
+ }
+
+ /*
+ * Bring up the network
+ */
+ if (rtems_bsdnet_setup () < 0)
+ return -1;
+ if (rtems_bsdnet_config.bootp)
+ (*rtems_bsdnet_config.bootp)();
+ return 0;
+}
+
+/*
+ * Attach a network interface.
+ */
+void rtems_bsdnet_attach (struct rtems_bsdnet_ifconfig *ifp)
+{
+ if (ifp) {
+ rtems_bsdnet_semaphore_obtain ();
+ (ifp->attach)(ifp, 1);
+ rtems_bsdnet_semaphore_release ();
+ }
+}
+
+/*
+ * Detach a network interface.
+ */
+void rtems_bsdnet_detach (struct rtems_bsdnet_ifconfig *ifp)
+{
+ if (ifp) {
+ rtems_bsdnet_semaphore_obtain ();
+ (ifp->attach)(ifp, 0);
+ rtems_bsdnet_semaphore_release ();
+ }
+}
+
+/*
+ * Interface Configuration.
+ */
+int rtems_bsdnet_ifconfig (const char *ifname, uint32_t cmd, void *param)
+{
+ int s, r = 0;
+ struct ifreq ifreq;
+
+ /*
+ * Configure interfaces
+ */
+ s = socket (AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ return -1;
+
+ strncpy (ifreq.ifr_name, ifname, IFNAMSIZ);
+
+ rtems_bsdnet_semaphore_obtain ();
+
+ switch (cmd) {
+ case SIOCSIFADDR:
+ case SIOCSIFNETMASK:
+ memcpy (&ifreq.ifr_addr, param, sizeof (struct sockaddr));
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case OSIOCGIFADDR:
+ case SIOCGIFADDR:
+ case OSIOCGIFNETMASK:
+ case SIOCGIFNETMASK:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ memcpy (param, &ifreq.ifr_addr, sizeof (struct sockaddr));
+ break;
+
+ case SIOCGIFFLAGS:
+ case SIOCSIFFLAGS:
+ if ((r = ioctl (s, SIOCGIFFLAGS, &ifreq)) < 0)
+ break;
+ if (cmd == SIOCGIFFLAGS) {
+ *((short*) param) = ifreq.ifr_flags;
+ break;
+ }
+ ifreq.ifr_flags |= *((short*) param);
+ if ( (*((short*) param) & IFF_UP ) == 0 ) {
+ /* set the interface down */
+ ifreq.ifr_flags &= ~(IFF_UP);
+ }
+ r = ioctl (s, SIOCSIFFLAGS, &ifreq);
+ break;
+
+ case SIOCSIFDSTADDR:
+ memcpy (&ifreq.ifr_dstaddr, param, sizeof (struct sockaddr));
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case OSIOCGIFDSTADDR:
+ case SIOCGIFDSTADDR:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ memcpy (param, &ifreq.ifr_dstaddr, sizeof (struct sockaddr));
+ break;
+
+ case SIOCSIFBRDADDR:
+ memcpy (&ifreq.ifr_broadaddr, param, sizeof (struct sockaddr));
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case OSIOCGIFBRDADDR:
+ case SIOCGIFBRDADDR:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ memcpy (param, &ifreq.ifr_broadaddr, sizeof (struct sockaddr));
+ break;
+
+ case SIOCSIFMETRIC:
+ ifreq.ifr_metric = *((int*) param);
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case SIOCGIFMETRIC:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ *((int*) param) = ifreq.ifr_metric;
+ break;
+
+ case SIOCSIFMTU:
+ ifreq.ifr_mtu = *((int*) param);
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case SIOCGIFMTU:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ *((int*) param) = ifreq.ifr_mtu;
+ break;
+
+ case SIOCSIFPHYS:
+ ifreq.ifr_phys = *((int*) param);
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case SIOCGIFPHYS:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ *((int*) param) = ifreq.ifr_phys;
+ break;
+
+ case SIOCSIFMEDIA:
+ ifreq.ifr_media = *((int*) param);
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case SIOCGIFMEDIA:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ *((int*) param) = ifreq.ifr_media;
+ break;
+
+ case SIOCAIFADDR:
+ case SIOCDIFADDR:
+ r = ioctl(s, cmd, (struct freq *) param);
+ break;
+
+ default:
+ errno = EOPNOTSUPP;
+ r = -1;
+ break;
+ }
+
+ rtems_bsdnet_semaphore_release ();
+
+ close (s);
+ return r;
+}
+
+/*
+ * Parse a network driver name into a name and a unit number
+ */
+int
+rtems_bsdnet_parse_driver_name (const struct rtems_bsdnet_ifconfig *config, char **namep)
+{
+ const char *cp = config->name;
+ char c;
+ int unitNumber = 0;
+
+ if (cp == NULL) {
+ printf ("No network driver name.\n");
+ return -1;
+ }
+ while ((c = *cp++) != '\0') {
+ if ((c >= '0') && (c <= '9')) {
+ int len = cp - config->name;
+ if ((len < 2) || (len > 50))
+ break;
+ for (;;) {
+ unitNumber = (unitNumber * 10) + (c - '0');
+ c = *cp++;
+ if (c == '\0') {
+ char *unitName = malloc (len);
+ if (unitName == NULL) {
+ printf ("No memory.\n");
+ return -1;
+ }
+ strncpy (unitName, config->name, len - 1);
+ unitName[len-1] = '\0';
+ *namep = unitName;
+ return unitNumber;
+ }
+ if ((c < '0') || (c > '9'))
+ break;
+ }
+ break;
+ }
+ }
+ printf ("Bad network driver name `%s'.\n", config->name);
+ return -1;
+}
+
+/*
+ * Handle requests for more network memory
+ * XXX: Another possibility would be to use a semaphore here with
+ * a release in the mbuf free macro. I have chosen this `polling'
+ * approach because:
+ * 1) It is simpler.
+ * 2) It adds no complexity to the free macro.
+ * 3) Running out of mbufs should be a rare
+ * condition -- predeployment testing of
+ * an application should indicate the
+ * required mbuf pool size.
+ * XXX: Should there be a panic if a task is stuck in the loop for
+ * more than a minute or so?
+ */
+int
+m_mballoc (int nmb, int nowait)
+{
+ if (nowait)
+ return 0;
+ m_reclaim ();
+ if (mmbfree == NULL) {
+ int try = 0;
+ int print_limit = 30 * rtems_bsdnet_ticks_per_second;
+
+ mbstat.m_wait++;
+ for (;;) {
+ rtems_bsdnet_semaphore_release ();
+ rtems_task_wake_after (1);
+ rtems_bsdnet_semaphore_obtain ();
+ if (mmbfree)
+ break;
+ if (++try >= print_limit) {
+ printf ("Still waiting for mbuf.\n");
+ try = 0;
+ }
+ }
+ }
+ else {
+ mbstat.m_drops++;
+ }
+ return 1;
+}
+
+int
+m_clalloc(ncl, nowait)
+{
+ if (nowait)
+ return 0;
+ m_reclaim ();
+ if (mclfree == NULL) {
+ int try = 0;
+ int print_limit = 30 * rtems_bsdnet_ticks_per_second;
+
+ mbstat.m_wait++;
+ for (;;) {
+ rtems_bsdnet_semaphore_release ();
+ rtems_task_wake_after (1);
+ rtems_bsdnet_semaphore_obtain ();
+ if (mclfree)
+ break;
+ if (++try >= print_limit) {
+ printf ("Still waiting for mbuf cluster.\n");
+ try = 0;
+ }
+ }
+ }
+ else {
+ mbstat.m_drops++;
+ }
+ return 1;
+}
diff --git a/cpukit/libnetworking/rtems/rtems_malloc_mbuf.c b/cpukit/libnetworking/rtems/rtems_malloc_mbuf.c
new file mode 100644
index 0000000000..d5654c8297
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_malloc_mbuf.c
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define RTEMS_FAST_MUTEX
+
+#ifdef RTEMS_FAST_MUTEX
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
+#endif
+
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+
+/*
+ * Default allocator for mbuf data. Over-ride in user code to change
+ * the way mbuf's are allocated.
+ */
+
+void* rtems_bsdnet_malloc_mbuf(size_t size, int type)
+{
+ return malloc(size);
+}
+
+
diff --git a/cpukit/libnetworking/rtems/rtems_mii_ioctl.c b/cpukit/libnetworking/rtems/rtems_mii_ioctl.c
new file mode 100644
index 0000000000..5ee8186f05
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_mii_ioctl.c
@@ -0,0 +1,129 @@
+/* $Id$ */
+
+/* Simple (default) implementation for SIOCGIFMEDIA/SIOCSIFMEDIA
+ * to be used by ethernet drivers [from their ioctl].
+ *
+ * USERSPACE UTILITIES
+ *
+ * NOTE: This much simpler than the BSD ifmedia API
+ */
+
+/* Author: Till Straumann, <straumanatslacdotstandorddotedu>, 2005 */
+
+#include <rtems.h>
+
+#undef _KERNEL
+#undef KERNEL
+
+#include <rtems/rtems_mii_ioctl.h>
+
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+static struct ifmedia_description shared_media_strings[] =
+ IFM_SUBTYPE_SHARED_DESCRIPTIONS;
+static struct ifmedia_description ethern_media_strings[] =
+ IFM_SUBTYPE_ETHERNET_DESCRIPTIONS;
+static struct ifmedia_description eth_al_media_strings[] =
+ IFM_SUBTYPE_ETHERNET_ALIASES;
+
+static const char *
+find_desc (int tag, struct ifmedia_description *list)
+{
+ while (list->ifmt_string && tag != list->ifmt_word)
+ list++;
+ return list->ifmt_string;
+}
+
+#define WHATPRINT(buf,sz,fmt...) \
+ ( (sz) > 0 ? snprintf((buf),(sz),fmt) : fprintf((buf) ? (FILE*)(buf) : stdout, fmt) )
+
+int
+rtems_ifmedia2str (int media, char *buf, int bufsz)
+{
+ const char *mdesc;
+ const char *dupdesc = 0;
+
+ /* only ethernet supported, so far */
+ if (IFM_ETHER != IFM_TYPE (media))
+ return -1;
+
+ if (!(mdesc = find_desc (IFM_SUBTYPE (media), shared_media_strings)))
+ mdesc = find_desc (IFM_SUBTYPE (media), ethern_media_strings);
+
+ if (!mdesc)
+ return -1;
+
+ if (IFM_NONE != IFM_SUBTYPE (media))
+ dupdesc = IFM_FDX & media ? " full-duplex" : " half-duplex";
+
+ return WHATPRINT (buf, bufsz,
+ "Ethernet [phy instance: %i]: (link %s, autoneg %s) -- media: %s%s",
+ IFM_INST (media),
+ IFM_LINK_OK & media ? "ok" : "down",
+ IFM_ANEG_DIS & media ? "off" : "on",
+ mdesc, dupdesc ? dupdesc : "");
+}
+
+static int
+find_tag (const char *desc, struct ifmedia_description *list)
+{
+ while (list->ifmt_string) {
+ if (strstr (desc, list->ifmt_string))
+ return list->ifmt_word;
+ list++;
+ }
+ return -1;
+}
+
+
+/* convert a string to a media word
+ * RETURNS: 0 on failure; valid results have always at least IFM_ETHER set
+ */
+int
+rtems_str2ifmedia (const char *str, int phy)
+{
+ int sub, opt = 0;
+ char *chpt;
+
+ if (!strncmp (str, "auto", 4)) {
+ sub = IFM_AUTO;
+ } else if ((sub = find_tag (str, ethern_media_strings)) < 0) {
+ if ((sub = find_tag (str, eth_al_media_strings)) < 0) {
+ /* allow more */
+
+ /* if no number, 0 is returned which will not pass the test */
+ switch (strtol (str, &chpt, 10)) {
+ case 10:
+ sub = IFM_10_T;
+ break;
+ case 100:
+ sub = IFM_100_TX;
+ break;
+ case 1000:
+ sub = IFM_1000_T;
+ break;
+ default:
+ return 0;
+ }
+
+ /* need 'b' or 'base' */
+ if ('b' != *chpt++)
+ return 0;
+ if (!strncmp (chpt, "ase", 3))
+ chpt += 3;
+ if (toupper (*chpt++) != 'T')
+ return 0;
+ if (IFM_100_TX == sub && toupper (*chpt++) != 'X')
+ return 0;
+ }
+ }
+
+ if (strstr (str, "full") || strstr (str, "FDX") || strstr (str, "fdx"))
+ opt |= IFM_FDX;
+
+ return IFM_MAKEWORD (IFM_ETHER, sub, opt, phy);
+}
diff --git a/cpukit/libnetworking/rtems/rtems_mii_ioctl.h b/cpukit/libnetworking/rtems/rtems_mii_ioctl.h
new file mode 100644
index 0000000000..2e82a5706c
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_mii_ioctl.h
@@ -0,0 +1,99 @@
+/* Simple (default) implementation for SIOCGIFMEDIA/SIOCSIFMEDIA
+ * to be used by ethernet drivers [from their ioctl].
+ *
+ * NOTE: This much simpler than the BSD ifmedia API
+ *
+ * Author: Till Straumann, <strauman@slac.stanford.edu>, 2005
+ *
+ * $Id$
+ */
+
+#ifndef RTEMS_MII_IOCTL_H
+#define RTEMS_MII_IOCTL_H
+
+#include <dev/mii/mii.h> /* MII register definitions */
+#include <net/if_media.h> /* media word definitions; rest of API (ifmedia) unused! */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(_KERNEL) || defined(KERNEL) || \
+ defined(__KERNEL) || defined(__KERNEL__)
+/* mdio routines to be provided by driver */
+
+/* read mii register 'reg' at 'phy' (-1 meaning any/currently active)
+ * RETURNS 0 on success, -1 otherwise (e.g., illegal phy)
+ */
+typedef int (*rtems_mdio_read_func) (int phy, void *uarg, unsigned reg,
+ uint32_t * pval);
+
+/* write mii register 'reg' at 'phy' (-1 meaning any/currently active)
+ * RETURNS 0 on success, -1 otherwise (e.g., illegal phy)
+ */
+typedef int (*rtems_mdio_write_func) (int phy, void *uarg, unsigned reg,
+ uint32_t val);
+
+/* Values to this must be provided by the driver */
+struct rtems_mdio_info {
+ rtems_mdio_read_func mdio_r;
+ rtems_mdio_write_func mdio_w;
+ unsigned has_gmii:1; /* supports gigabit */
+};
+
+/* Implement SIOCSIFMEDIA/SIOCGIFMEDIA; get/set the current media word. Note
+ * that this does NOT implement the full BSD 'ifmedia' API; also, it only
+ * implements IFM_ETHER...
+ *
+ * INPUT:
+ * SIOCGIFMEDIA: the media word must set the phy instance (-1 for 'any')
+ *
+ */
+int
+rtems_mii_ioctl (struct rtems_mdio_info *info, void *uarg, int cmd,
+ int *media);
+
+#endif
+
+/* The driver flags have the following meaning (SIOCGIFMEDIA only):
+ */
+#define IFM_LINK_OK IFM_FLAG0
+#define IFM_ANEG_DIS IFM_FLAG1 /* autoneg. disabled; media forced */
+
+/* convert a media word to a string;
+ *
+ * RETURNS: number of characters written to 'buf'
+ *
+ * INPUT: if 'bufsz' is set to IFMEDIA2STR_PRINT_TO_FILE, 'buf' can be a FILE
+ * pointer where the info is printed insted. This can be NULL in which
+ * case 'stdout' is used.
+ */
+
+#define IFMEDIA2STR_PRINT_TO_FILE 0
+
+int rtems_ifmedia2str (int media, char *buf, int bufsz);
+
+/* convert a string to a media word
+ * RETURNS: 0 on failure (unrecognized or invalid mode);
+ * valid results have always at least IFM_ETHER set.
+ *
+ * In addition to IFM_SUBTYPE_ETHERNET_DESCRIPTIONS and
+ * IFM_SUBTYPE_ETHERNET_ALIASES, the strings
+ *
+ * '10' [ '0' [ '0' ]] 'b' [ 'ase' ] ( 't' | 'T' )
+ * (* if 100bT [ 'x' | 'X' ] is required here *)
+ *
+ * are recognized (e.g., 10bT, 100bTX)
+ *
+ * if any of the strings 'full' or 'FDX' or 'fdx' is present, a full-duplex mode
+ * is selected (half-duplex otherwise).
+ * e.g., '100bTx-full'
+ */
+
+int rtems_str2ifmedia (const char *str, int phy);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/rtems/rtems_mii_ioctl_kern.c b/cpukit/libnetworking/rtems/rtems_mii_ioctl_kern.c
new file mode 100644
index 0000000000..a6cc622df0
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_mii_ioctl_kern.c
@@ -0,0 +1,204 @@
+/* $Id$ */
+
+/* Simple (default) implementation for SIOCGIFMEDIA/SIOCSIFMEDIA
+ * to be used by ethernet drivers [from their ioctl].
+ *
+ * KERNEL PART (support for drivers)
+ *
+ * NOTE: This much simpler than the BSD ifmedia API
+ */
+
+/* Author: Till Straumann, <straumanatslacdotstandorddotedu>, 2005 */
+
+/* include first to avoid 'malloc' clash with rtems_bsdnet_malloc() hack */
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+
+#include <rtems/rtems_mii_ioctl.h>
+
+#include <sys/errno.h>
+
+
+#define DEBUG
+
+
+#ifndef MII_1000TCR
+#define MII_1000TCR MII_100T2CR
+#endif
+
+#ifndef MII_1000TSR
+#define MII_1000TSR MII_100T2SR
+#endif
+
+int
+rtems_mii_ioctl (struct rtems_mdio_info *info, void *uarg, int cmd,
+ int *media)
+{
+ uint32_t bmcr, bmsr, aner, bmcr2 = 0, bmsr2 = 0, anar, lpar;
+ int phy = IFM_INST (*media);
+ unsigned tmp;
+ int subtype = 0, options = 0;
+
+ switch (cmd) {
+ default:
+ return EINVAL;
+
+#ifdef DEBUG
+ case 0:
+#endif
+ case SIOCGIFMEDIA:
+ if (info->mdio_r (phy, uarg, MII_BMCR, &bmcr))
+ return EINVAL;
+ if (info->mdio_r (phy, uarg, MII_BMSR, &bmsr))
+ return EINVAL;
+ if (info->mdio_r (phy, uarg, MII_ANER, &aner))
+ return EINVAL;
+ if (info->has_gmii) {
+ if (info->mdio_r (phy, uarg, MII_1000TCR, &bmcr2))
+ return EINVAL;
+ if (info->mdio_r (phy, uarg, MII_1000TSR, &bmsr2))
+ return EINVAL;
+ }
+
+ /* link status */
+ if (BMSR_LINK & bmsr)
+ options |= IFM_LINK_OK;
+
+ /* do we have autonegotiation disabled ? */
+ if (!(BMCR_AUTOEN & bmcr)) {
+ options |= IFM_ANEG_DIS;
+
+ /* duplex is enforced */
+ options |= BMCR_FDX & bmcr ? IFM_FDX : IFM_HDX;
+
+ /* determine speed */
+ switch (BMCR_SPEED (bmcr)) {
+ case BMCR_S10:
+ subtype = IFM_10_T;
+ break;
+ case BMCR_S100:
+ subtype = IFM_100_TX;
+ break;
+ case BMCR_S1000:
+ subtype = IFM_1000_T;
+ break;
+ default:
+ return ENOTSUP; /* ?? */
+ }
+ } else if (!(BMSR_LINK & bmsr) || !(BMSR_ACOMP & bmsr)) {
+ subtype = IFM_NONE;
+ } else {
+ /* everything ok on our side */
+
+ if ( ! (ANER_LPAN & aner) ) {
+ /* Link partner doesn't autonegotiate --> our settings are the
+ * result of 'parallel detect' (in particular: duplex status is HALF
+ * according to the standard!).
+ * Let them know that something's fishy...
+ */
+ options |= IFM_ANEG_DIS;
+ }
+
+ tmp = ((bmcr2 << 2) & bmsr2) & (GTSR_LP_1000THDX | GTSR_LP_1000TFDX);
+ if (tmp) {
+ if (GTSR_LP_1000TFDX & tmp)
+ options |= IFM_FDX;
+ subtype = IFM_1000_T;
+ } else {
+ if (info->mdio_r (phy, uarg, MII_ANAR, &anar))
+ return EINVAL;
+ if (info->mdio_r (phy, uarg, MII_ANLPAR, &lpar))
+ return EINVAL;
+ if (ANLPAR_ACK & lpar) {
+ /* this is a negotiated link; otherwise we merely detect the partner's ability */
+ }
+ tmp = anar & lpar;
+ if (ANLPAR_TX_FD & tmp) {
+ options |= IFM_FDX;
+ subtype = IFM_100_TX;
+ } else if (ANLPAR_T4 & tmp) {
+ subtype = IFM_100_T4;
+ } else if (ANLPAR_TX & tmp) {
+ subtype = IFM_100_TX;
+ } else if (ANLPAR_10_FD & tmp) {
+ options |= IFM_FDX;
+ subtype = IFM_10_T;
+ } else {
+ subtype = IFM_10_T;
+ }
+ }
+ }
+
+ *media = IFM_MAKEWORD (IFM_ETHER, subtype, options, phy);
+
+ break;
+
+#ifdef DEBUG
+ case 1:
+#endif
+ case SIOCSIFMEDIA:
+ if (IFM_ETHER != IFM_TYPE (*media))
+ return EINVAL;
+
+ if (info->mdio_r (phy, uarg, MII_BMSR, &bmsr))
+ return EINVAL;
+
+ tmp = (IFM_FDX & *media);
+
+ switch (IFM_SUBTYPE (*media)) {
+ default:
+ return ENOTSUP;
+
+ case IFM_AUTO:
+ bmcr = BMCR_AUTOEN | BMCR_STARTNEG;
+ tmp = 0;
+ break;
+
+ case IFM_1000_T:
+ if (!info->has_gmii)
+ return ENOTSUP;
+
+ if (info->mdio_r (phy, uarg, MII_EXTSR, &bmsr2))
+ return EINVAL;
+
+ if (!(bmsr2 & (tmp ? EXTSR_1000TFDX : EXTSR_1000THDX)))
+ return EOPNOTSUPP;
+ bmcr = BMCR_S1000;
+ break;
+
+ case IFM_100_TX:
+ if (!(bmsr & (tmp ? BMSR_100TXFDX : BMSR_100TXHDX)))
+ return EOPNOTSUPP;
+ bmcr = BMCR_S100;
+ break;
+
+ case IFM_10_T:
+ if (!(bmsr & (tmp ? BMSR_10TFDX : BMSR_10THDX)))
+ return EOPNOTSUPP;
+ bmcr = BMCR_S10;
+ break;
+ }
+
+ if (tmp)
+ bmcr |= BMCR_FDX;
+
+ if (info->mdio_w (phy, uarg, MII_BMCR, bmcr))
+ return EINVAL;
+
+ /* TODO: should we adapt advertised capabilites ? */
+
+ break;
+ }
+
+ return 0;
+}
diff --git a/cpukit/libnetworking/rtems/rtems_select.c b/cpukit/libnetworking/rtems/rtems_select.c
new file mode 100644
index 0000000000..9504981147
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_select.c
@@ -0,0 +1,178 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdarg.h>
+/* #include <stdlib.h> */
+#include <stdio.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/proc.h>
+#include <sys/filio.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+/*
+ *********************************************************************
+ * RTEMS implementation of select() system call *
+ *********************************************************************
+ */
+
+/*
+ * This implementation is quite restricted:
+ * Works on sockets only -- no support for other devices!
+ * A given socket can be in a read-select or a read/recv* by only
+ * one task at a time.
+ * A given socket can be in a write-select or a write/send* by only
+ * one task at a time.
+ *
+ * NOTE - select() is a very expensive system call. It should be avoided
+ * if at all possible. In many cases, rewriting the application
+ * to use multiple tasks (one per socket) is a better solution.
+ */
+
+static __inline int imin(int a, int b) { return (a < b ? a : b); }
+struct socket *rtems_bsdnet_fdToSocket(int fd);
+
+static int
+socket_select (struct socket *so, int which, rtems_id tid)
+{
+ switch (which) {
+
+ case FREAD:
+ if (soreadable(so))
+ return (1);
+ so->so_rcv.sb_flags |= SB_WAIT;
+ so->so_rcv.sb_sel.si_pid = tid;
+ break;
+
+ case FWRITE:
+ if (sowriteable(so))
+ return (1);
+ so->so_snd.sb_flags |= SB_WAIT;
+ so->so_snd.sb_sel.si_pid = tid;
+ break;
+
+ case 0:
+ if (so->so_oobmark || (so->so_state & SS_RCVATMARK))
+ return (1);
+ so->so_rcv.sb_sel.si_pid = tid;
+ break;
+ }
+ return (0);
+}
+
+static int
+selscan (rtems_id tid, fd_mask **ibits, fd_mask **obits, int nfd, int *retval)
+{
+ struct socket *so;
+ int msk, i, fd;
+ fd_mask bits, bit;
+ int n = 0;
+ static int flag[3] = { FREAD, FWRITE, 0 };
+
+ for (msk = 0; msk < 3; msk++) {
+ if (ibits[msk] == NULL)
+ continue;
+ for (i = 0; i < nfd; i += NFDBITS) {
+ bits = ibits[msk][i/NFDBITS];
+ for (fd = i, bit = 1 ; bits && (fd < nfd) ; fd++, bit <<= 1) {
+ if ((bits & bit) == 0)
+ continue;
+ bits &= ~bit;
+ so = rtems_bsdnet_fdToSocket (fd);
+ if (so == NULL)
+ return (EBADF);
+ if (socket_select (so, flag[msk], tid)) {
+ obits[msk][fd/NFDBITS] |=
+ (1 << (fd % NFDBITS));
+ n++;
+ }
+ }
+ }
+ }
+ *retval = n;
+ return (0);
+}
+
+int
+select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *tv)
+{
+ fd_mask *ibits[3], *obits[3];
+ fd_set ob[3];
+ int error, timo;
+ int retval = 0;
+ rtems_id tid;
+ rtems_interval then, now;
+ rtems_event_set events;
+
+ if (nfds < 0)
+ return (EINVAL);
+ if (tv) {
+ timo = tv->tv_sec * hz + tv->tv_usec / tick;
+ if (timo == 0)
+ timo = 1;
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
+ }
+ else {
+ timo = 0;
+ }
+
+#define getbits(name,i) if (name) { \
+ ibits[i] = &name->fds_bits[0]; \
+ obits[i] = &ob[i].fds_bits[0]; \
+ FD_ZERO(&ob[i]); \
+ } \
+ else ibits[i] = NULL
+ getbits (readfds, 0);
+ getbits (writefds, 1);
+ getbits (exceptfds, 2);
+#undef getbits
+
+ rtems_task_ident (RTEMS_SELF, 0, &tid);
+ rtems_event_receive (SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT, &events);
+ for (;;) {
+ rtems_bsdnet_semaphore_obtain ();
+ error = selscan(tid, ibits, obits, nfds, &retval);
+ rtems_bsdnet_semaphore_release ();
+ if (error || retval)
+ break;
+ if (timo) {
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ timo -= now - then;
+ if (timo <= 0)
+ break;
+ then = now;
+ }
+ rtems_event_receive (SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, timo, &events);
+ }
+
+#define putbits(name,i) if (name) *name = ob[i]
+ putbits (readfds, 0);
+ putbits (writefds, 1);
+ putbits (exceptfds, 2);
+#undef putbits
+ if (error) {
+ errno = error;
+ retval = -1;
+ }
+ return (retval);
+}
diff --git a/cpukit/libnetworking/rtems/rtems_showicmpstat.c b/cpukit/libnetworking/rtems/rtems_showicmpstat.c
new file mode 100644
index 0000000000..0071c95947
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_showicmpstat.c
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/icmp_var.h>
+
+/*
+ * Display ICMP statistics
+ * Don't lock the rest of the network tasks out while printing.
+ * It's no big deal if the values change while being printed.
+ */
+static void
+showicmpstat (const char *name, unsigned long n)
+{
+ if (n)
+ printf ("%35s%12lu\n", name, n);
+}
+
+void
+rtems_bsdnet_show_icmp_stats (void)
+{
+ int i;
+ char cbuf[20];
+ extern unsigned int icmplenPanicAvoided;
+
+ printf ("************ ICMP Statistics ************\n");
+ showicmpstat ("Calls to icmp_error()", icmpstat.icps_error);
+ showicmpstat ("Errors not sent -- old was icmp", icmpstat.icps_oldicmp);
+ for (i = 0 ; i <= ICMP_MAXTYPE ; i++) {
+ if (icmpstat.icps_outhist[i]) {
+ sprintf (cbuf, "Type %d sent", i);
+ showicmpstat (cbuf, icmpstat.icps_outhist[i]);
+ }
+ }
+ showicmpstat ("icmp_code out of range", icmpstat.icps_badcode);
+ showicmpstat ("packet < ICMP_MINLEN", icmpstat.icps_tooshort);
+ showicmpstat ("bad checksum", icmpstat.icps_checksum);
+ showicmpstat ("calculated bound mismatch", icmpstat.icps_badlen);
+ showicmpstat ("number of responses", icmpstat.icps_reflect);
+ showicmpstat ("all echo requests dropped", icmpstat.icps_allecho);
+ showicmpstat ("b/mcast echo requests dropped", icmpstat.icps_bmcastecho);
+ showicmpstat ("b/mcast tstamp requests dropped", icmpstat.icps_bmcasttstamp);
+ for (i = 0 ; i <= ICMP_MAXTYPE ; i++) {
+ if (icmpstat.icps_inhist[i]) {
+ sprintf (cbuf, "Type %d received", i);
+ showicmpstat (cbuf, icmpstat.icps_inhist[i]);
+ }
+ }
+ showicmpstat ("ICMP panic avoided", icmplenPanicAvoided);
+ printf ("\n");
+}
diff --git a/cpukit/libnetworking/rtems/rtems_showifstat.c b/cpukit/libnetworking/rtems/rtems_showifstat.c
new file mode 100644
index 0000000000..17722093fb
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_showifstat.c
@@ -0,0 +1,157 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mbuf.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * Display an address
+ */
+static int
+showaddress (char *name, struct sockaddr *a)
+{
+ struct sockaddr_in *sa;
+ char buf[17];
+
+ if (!a)
+ return 0;
+ printf ("%s:", name);
+ sa = (struct sockaddr_in *)a;
+ printf ("%-16s", inet_ntop (AF_INET, &sa->sin_addr, buf, sizeof(buf)));
+ return 1;
+}
+
+/*
+ * Display interface statistics
+ */
+void
+rtems_bsdnet_show_if_stats (void)
+{
+ struct ifnet *ifp;
+ struct ifaddr *ifa;
+ unsigned short bit, flags;
+
+ printf ("************ INTERFACE STATISTICS ************\n");
+ for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+ printf ("***** %s%d *****\n", ifp->if_name, ifp->if_unit);
+ for (ifa = ifp->if_addrlist ; ifa ; ifa = ifa->ifa_next) {
+
+ if ( !ifa->ifa_addr )
+ continue;
+
+ switch ( ifa->ifa_addr->sa_family ) {
+ case AF_LINK:
+ {
+ struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+ unsigned char *cp = (unsigned char *)LLADDR(sdl);
+ int i;
+
+ switch ( sdl->sdl_type ) {
+ case IFT_ETHER:
+ if ( (i=sdl->sdl_alen) > 0 ) {
+ printf("Ethernet Address: ");
+ do {
+ i--;
+ printf("%02X%c", *cp++, i ? ':' : '\n');
+ } while ( i>0 );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case AF_INET:
+ {
+ int printed;
+ printed = showaddress ("Address", ifa->ifa_addr);
+ if (ifp->if_flags & IFF_BROADCAST)
+ printed |= showaddress ("Broadcast Address", ifa->ifa_broadaddr);
+ if (ifp->if_flags & IFF_POINTOPOINT)
+ printed |= showaddress ("Destination Address", ifa->ifa_dstaddr);
+ printed |= showaddress ("Net mask", ifa->ifa_netmask);
+ if (printed)
+ printf ("\n");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ printf ("Flags:");
+ for (bit = 1, flags = ifp->if_flags ; flags ; bit <<= 1) {
+ char *cp;
+ char xbuf[20];
+ switch (flags & bit) {
+ case 0: cp = NULL; break;
+ case IFF_UP: cp = "Up"; break;
+ case IFF_BROADCAST: cp = "Broadcast"; break;
+ case IFF_DEBUG: cp = "Debug"; break;
+ case IFF_LOOPBACK: cp = "Loopback"; break;
+ case IFF_POINTOPOINT: cp = "Point-to-point"; break;
+ case IFF_RUNNING: cp = "Running"; break;
+ case IFF_NOARP: cp = "No-ARP"; break;
+ case IFF_PROMISC: cp = "Promiscuous"; break;
+ case IFF_ALLMULTI: cp = "All-multicast"; break;
+ case IFF_OACTIVE: cp = "Active"; break;
+ case IFF_SIMPLEX: cp = "Simplex"; break;
+ case IFF_LINK0: cp = "Link0"; break;
+ case IFF_LINK1: cp = "Link1"; break;
+ case IFF_LINK2: cp = "Link2"; break;
+ case IFF_MULTICAST: cp = "Multicast"; break;
+ default: sprintf (xbuf, "%#x", bit); cp = xbuf; break;
+ }
+ if (cp) {
+ flags &= ~bit;
+ printf (" %s", cp);
+ }
+ }
+ printf ("\n");
+
+ printf ("Send queue limit:%-4d length:%-4d Dropped:%-8d\n",
+ ifp->if_snd.ifq_maxlen,
+ ifp->if_snd.ifq_len,
+ ifp->if_snd.ifq_drops);
+
+ /*
+ * FIXME: Could print if_data statistics here,
+ * but right now the drivers maintain their
+ * own statistics.
+ */
+
+ /*
+ * Grab the network semaphore.
+ * In most cases this is not necessary, but it's
+ * easier to always call the driver ioctl function
+ * while holding the semaphore than to try
+ * and explain why some ioctl commands are invoked
+ * while holding the semaphore and others are
+ * invoked while not holding the semaphore.
+ */
+ rtems_bsdnet_semaphore_obtain ();
+ (*ifp->if_ioctl)(ifp, SIO_RTEMS_SHOW_STATS, NULL);
+ rtems_bsdnet_semaphore_release ();
+ }
+ printf ("\n");
+}
diff --git a/cpukit/libnetworking/rtems/rtems_showipstat.c b/cpukit/libnetworking/rtems/rtems_showipstat.c
new file mode 100644
index 0000000000..75eabca2c1
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_showipstat.c
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+/*
+ * Display IP statistics
+ * Don't lock the rest of the network tasks out while printing.
+ * It's no big deal if the values change while being printed.
+ */
+static void
+showipstat (const char *name, unsigned long n)
+{
+ if (n)
+ printf ("%35s%12lu\n", name, n);
+}
+
+void
+rtems_bsdnet_show_ip_stats (void)
+{
+ printf ("************ IP Statistics ************\n");
+ showipstat ("total packets received", ipstat.ips_total);
+ showipstat ("checksum bad", ipstat.ips_badsum);
+ showipstat ("packet too short", ipstat.ips_tooshort);
+ showipstat ("not enough data", ipstat.ips_toosmall);
+ showipstat ("ip header length < data size", ipstat.ips_badhlen);
+ showipstat ("ip length < ip header length", ipstat.ips_badlen);
+ showipstat ("fragments received", ipstat.ips_fragments);
+ showipstat ("frags dropped (dups, out of space)", ipstat.ips_fragdropped);
+ showipstat ("fragments timed out", ipstat.ips_fragtimeout);
+ showipstat ("packets forwarded", ipstat.ips_forward);
+ showipstat ("packets rcvd for unreachable dest", ipstat.ips_cantforward);
+ showipstat ("packets forwarded on same net", ipstat.ips_redirectsent);
+ showipstat ("unknown or unsupported protocol", ipstat.ips_noproto);
+ showipstat ("datagrams delivered to upper level", ipstat.ips_delivered);
+ showipstat ("total ip packets generated here", ipstat.ips_localout);
+ showipstat ("lost packets due to nobufs, etc.", ipstat.ips_odropped);
+ showipstat ("total packets reassembled ok", ipstat.ips_reassembled);
+ showipstat ("datagrams successfully fragmented", ipstat.ips_fragmented);
+ showipstat ("output fragments created", ipstat.ips_ofragments);
+ showipstat ("don't fragment flag was set, etc.", ipstat.ips_cantfrag);
+ showipstat ("error in option processing", ipstat.ips_badoptions);
+ showipstat ("packets discarded due to no route", ipstat.ips_noroute);
+ showipstat ("ip version != 4", ipstat.ips_badvers);
+ showipstat ("total raw ip packets generated", ipstat.ips_rawout);
+ showipstat ("ip length > max ip packet size", ipstat.ips_toolong);
+ printf ("\n");
+}
diff --git a/cpukit/libnetworking/rtems/rtems_showmbuf.c b/cpukit/libnetworking/rtems/rtems_showmbuf.c
new file mode 100644
index 0000000000..a4404a5a6c
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_showmbuf.c
@@ -0,0 +1,69 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+
+/*
+ * Display MBUF statistics
+ * Don't lock the rest of the network tasks out while printing.
+ * It's no big deal if the values change while being printed.
+ */
+void
+rtems_bsdnet_show_mbuf_stats (void)
+{
+ int i;
+ int printed = 0;
+ char *cp;
+
+ printf ("************ MBUF STATISTICS ************\n");
+ printf ("mbufs:%4lu clusters:%4lu free:%4lu\n",
+ mbstat.m_mbufs, mbstat.m_clusters, mbstat.m_clfree);
+ printf ("drops:%4lu waits:%4lu drains:%4lu\n",
+ mbstat.m_drops, mbstat.m_wait, mbstat.m_drain);
+ for (i = 0 ; i < 20 ; i++) {
+ switch (i) {
+ case MT_FREE: cp = "free"; break;
+ case MT_DATA: cp = "data"; break;
+ case MT_HEADER: cp = "header"; break;
+ case MT_SOCKET: cp = "socket"; break;
+ case MT_PCB: cp = "pcb"; break;
+ case MT_RTABLE: cp = "rtable"; break;
+ case MT_HTABLE: cp = "htable"; break;
+ case MT_ATABLE: cp = "atable"; break;
+ case MT_SONAME: cp = "soname"; break;
+ case MT_SOOPTS: cp = "soopts"; break;
+ case MT_FTABLE: cp = "ftable"; break;
+ case MT_RIGHTS: cp = "rights"; break;
+ case MT_IFADDR: cp = "ifaddr"; break;
+ case MT_CONTROL: cp = "control"; break;
+ case MT_OOBDATA: cp = "oobdata"; break;
+ default: cp = NULL; break;
+ }
+ if ((cp != NULL) || (mbstat.m_mtypes[i] != 0)) {
+ char cbuf[16];
+ if (cp == NULL) {
+ sprintf (cbuf, "Type %d", i);
+ cp = cbuf;
+ }
+ printf ("%10s:%-8u", cp, mbstat.m_mtypes[i]);
+ if (++printed == 4) {
+ printf ("\n");
+ printed = 0;
+ }
+ }
+ }
+ if (printed)
+ printf ("\n");
+ printf ("\n");
+}
diff --git a/cpukit/libnetworking/rtems/rtems_showroute.c b/cpukit/libnetworking/rtems/rtems_showroute.c
new file mode 100644
index 0000000000..871b8263eb
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_showroute.c
@@ -0,0 +1,240 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+/*
+ * We'll use the application versions of realloc and free.
+ */
+#undef free
+#undef malloc
+#include <stdlib.h>
+
+/*
+ * Information per route
+ */
+struct rinfo {
+ struct sockaddr dst;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_dl sdl;
+ } un;
+ unsigned long pksent;
+ unsigned long expire;
+ int flags;
+ char ifname[16];
+ short ifunit;
+ short refcnt;
+};
+
+/*
+ * Information per display
+ */
+struct dinfo {
+ int capacity;
+ int count;
+ struct rinfo *routes;
+};
+
+/*
+ * Copy address
+ */
+static void
+copyAddress (void *to, void *from, int tolen)
+{
+ int ncopy;
+ struct sockaddr dummy;
+
+ if (from == NULL) {
+ /*
+ * Create a fake address of unspecified type
+ */
+ from = &dummy;
+ dummy.sa_len = 4;
+ dummy.sa_family = AF_UNSPEC;
+ }
+ ncopy = ((struct sockaddr *)from)->sa_len;
+ if (ncopy > tolen)
+ ncopy = tolen;
+ memcpy (to, from, ncopy);
+}
+
+/*
+ * Package everything up before printing it.
+ * We don't want to block all network operations till
+ * the printing completes!
+ */
+static int
+show_inet_route (rn, vw)
+ struct radix_node *rn;
+ void *vw;
+{
+ struct rtentry *rt = (struct rtentry *)rn;
+ struct ifnet *ifp;
+ struct dinfo *dp = (struct dinfo *)vw;
+ struct rinfo *r;
+
+ /*
+ * Get a pointer to a new route info structure
+ */
+ if (dp->count >= dp->capacity) {
+ r = realloc (dp->routes, (sizeof *r) * (dp->capacity + 20));
+ if (r == 0)
+ return ENOMEM;
+ dp->capacity += 20;
+ dp->routes = r;
+ }
+ r = dp->routes + dp->count++;
+
+ /*
+ * Fill in the route info structure
+ */
+ copyAddress (&r->dst, rt_key(rt), sizeof r->dst);
+ if (rt->rt_flags & (RTF_GATEWAY | RTF_HOST)) {
+ copyAddress (&r->un, rt->rt_gateway, sizeof r->un);
+ }
+ else {
+ /*
+ * Create a fake address to hold the mask
+ */
+ struct sockaddr_in dummy;
+
+ dummy.sin_family = AF_INET;
+ dummy.sin_len = sizeof dummy;
+ dummy.sin_addr = ((struct sockaddr_in *)rt_mask(rt))->sin_addr;
+ copyAddress (&r->un, &dummy, sizeof r->un);
+ }
+ r->flags = rt->rt_flags;
+ r->refcnt = rt->rt_refcnt;
+ r->pksent = rt->rt_rmx.rmx_pksent;
+ r->expire = rt->rt_rmx.rmx_expire;
+ ifp = rt->rt_ifp;
+ strncpy (r->ifname, (ifp->if_name ? ifp->if_name : ""), sizeof r->ifname);
+ r->ifunit = ifp->if_unit;
+ return 0;
+}
+
+/*
+ * Convert link address to ASCII
+ */
+static char *
+link_ascii (struct sockaddr_dl *sdl, char *buf, int bufsize)
+{
+ char *cp;
+ int i;
+ int first = 1;
+ int nleft = sdl->sdl_alen;
+ char *ap = LLADDR (sdl);
+ static const char hextab[16] = "0123456789ABCDEF";
+
+ cp = buf;
+ while (nleft && (bufsize > 4)) {
+ if (first) {
+ first = 0;
+ }
+ else {
+ *cp++ = ':';
+ bufsize--;
+ }
+ i = *ap++;
+ *cp++ = hextab[(i >> 4) & 0xf];
+ *cp++ = hextab[i & 0xf];
+ nleft--;
+ bufsize -= 2;
+ }
+ *cp = '\0';
+ return buf;
+}
+
+void
+rtems_bsdnet_show_inet_routes (void)
+{
+ struct radix_node_head *rnh;
+ struct dinfo d;
+ struct rinfo *r;
+ int i, error;
+
+ /*
+ * For now we'll handle only AF_INET
+ */
+ rnh = rt_tables[AF_INET];
+ if (!rnh)
+ return;
+ d.count = d.capacity = 0;
+ d.routes = NULL;
+ rtems_bsdnet_semaphore_obtain ();
+ error = rnh->rnh_walktree(rnh, show_inet_route, &d);
+ rtems_bsdnet_semaphore_release ();
+ if (error) {
+ printf ("Can't get route info: %s\n", strerror (error));
+ return;
+ }
+ if (d.count == 0) {
+ printf ("No routes!\n");
+ return;
+ }
+ printf ("Destination Gateway/Mask/Hw Flags Refs Use Expire Interface\n");
+ for (i = 0, r = d.routes ; i < d.count ; i++, r++) {
+ char buf[30];
+ char *cp, *fc, flagbuf[10];
+ const char *addr;
+ unsigned long flagbit;
+ struct sockaddr_in *sin;
+
+ sin = (struct sockaddr_in *)&r->dst;
+ if (sin->sin_addr.s_addr == INADDR_ANY)
+ addr = "default";
+ else
+ addr = inet_ntop (AF_INET, &sin->sin_addr, buf, sizeof buf);
+ printf ("%-16s", addr);
+ switch (r->un.sa.sa_family) {
+ case AF_INET:
+ addr = inet_ntop (AF_INET, &r->un.sin.sin_addr, buf, sizeof buf);
+ break;
+
+ case AF_LINK:
+ addr = link_ascii (&r->un.sdl, buf, sizeof buf);
+ break;
+
+ default:
+ addr = "";
+ break;
+ }
+ printf ("%-19s", addr);
+ fc = "UGHRDM XLS";
+ for (flagbit = 0x1, cp = flagbuf ; *fc ; flagbit <<= 1, fc++) {
+ if ((r->flags & flagbit) && (*fc != ' '))
+ *cp++ = *fc;
+ }
+ *cp = '\0';
+ printf ("%-10s%3d%9ld%7ld %.*s%d\n", flagbuf,
+ r->refcnt, r->pksent,
+ r->expire,
+ (int)sizeof r->ifname, r->ifname,
+ r->ifunit);
+ }
+ free (d.routes);
+}
diff --git a/cpukit/libnetworking/rtems/rtems_showtcpstat.c b/cpukit/libnetworking/rtems/rtems_showtcpstat.c
new file mode 100644
index 0000000000..15612878ef
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_showtcpstat.c
@@ -0,0 +1,106 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_var.h>
+
+/*
+ * Display TCP statistics
+ * Don't lock the rest of the network tasks out while printing.
+ * It's no big deal if the values change while being printed.
+ */
+static void
+showtcpstat (const char *name, unsigned long n)
+{
+ if (n)
+ printf ("%35s%12lu\n", name, n);
+}
+
+void
+rtems_bsdnet_show_tcp_stats (void)
+{
+ printf ("************ TCP Statistics ************\n");
+ showtcpstat ("connections initiated", tcpstat.tcps_connattempt);
+ showtcpstat ("connections accepted", tcpstat.tcps_accepts);
+ showtcpstat ("connections established", tcpstat.tcps_connects);
+ showtcpstat ("connections dropped", tcpstat.tcps_drops);
+ showtcpstat ("embryonic connections dropped", tcpstat.tcps_conndrops);
+ showtcpstat ("conn. closed (includes drops)", tcpstat.tcps_closed);
+ showtcpstat ("segs where we tried to get rtt", tcpstat.tcps_segstimed);
+ showtcpstat ("times we succeeded", tcpstat.tcps_rttupdated);
+ showtcpstat ("delayed acks sent", tcpstat.tcps_delack);
+ showtcpstat ("conn. dropped in rxmt timeout", tcpstat.tcps_timeoutdrop);
+ showtcpstat ("retransmit timeouts", tcpstat.tcps_rexmttimeo);
+ showtcpstat ("persist timeouts", tcpstat.tcps_persisttimeo);
+ showtcpstat ("keepalive timeouts", tcpstat.tcps_keeptimeo);
+ showtcpstat ("keepalive probes sent", tcpstat.tcps_keepprobe);
+ showtcpstat ("connections dropped in keepalive", tcpstat.tcps_keepdrops);
+
+ showtcpstat ("total packets sent", tcpstat.tcps_sndtotal);
+ showtcpstat ("data packets sent", tcpstat.tcps_sndpack);
+ showtcpstat ("data bytes sent", tcpstat.tcps_sndbyte);
+ showtcpstat ("data packets retransmitted", tcpstat.tcps_sndrexmitpack);
+ showtcpstat ("data bytes retransmitted", tcpstat.tcps_sndrexmitbyte);
+ showtcpstat ("ack-only packets sent", tcpstat.tcps_sndacks);
+ showtcpstat ("window probes sent", tcpstat.tcps_sndprobe);
+ showtcpstat ("packets sent with URG only", tcpstat.tcps_sndurg);
+ showtcpstat ("window update-only packets sent", tcpstat.tcps_sndwinup);
+ showtcpstat ("control (SYN|FIN|RST) packets sent", tcpstat.tcps_sndctrl);
+
+ showtcpstat ("total packets received", tcpstat.tcps_rcvtotal);
+ showtcpstat ("packets received in sequence", tcpstat.tcps_rcvpack);
+ showtcpstat ("bytes received in sequence", tcpstat.tcps_rcvbyte);
+ showtcpstat ("packets received with ccksum errs", tcpstat.tcps_rcvbadsum);
+ showtcpstat ("packets received with bad offset", tcpstat.tcps_rcvbadoff);
+ showtcpstat ("packets received too short", tcpstat.tcps_rcvshort);
+ showtcpstat ("duplicate-only packets received", tcpstat.tcps_rcvduppack);
+ showtcpstat ("duplicate-only bytes received", tcpstat.tcps_rcvdupbyte);
+ showtcpstat ("packets with some duplicate data", tcpstat.tcps_rcvpartduppack);
+ showtcpstat ("dup. bytes in part-dup. packets", tcpstat.tcps_rcvpartdupbyte);
+ showtcpstat ("out-of-order packets received", tcpstat.tcps_rcvoopack);
+ showtcpstat ("out-of-order bytes received", tcpstat.tcps_rcvoobyte);
+ showtcpstat ("packets with data after window", tcpstat.tcps_rcvpackafterwin);
+ showtcpstat ("bytes rcvd after window", tcpstat.tcps_rcvbyteafterwin);
+ showtcpstat ("packets rcvd after \"close\"", tcpstat.tcps_rcvafterclose);
+ showtcpstat ("rcvd window probe packets", tcpstat.tcps_rcvwinprobe);
+ showtcpstat ("rcvd duplicate acks", tcpstat.tcps_rcvdupack);
+ showtcpstat ("rcvd acks for unsent data", tcpstat.tcps_rcvacktoomuch);
+ showtcpstat ("rcvd ack packets", tcpstat.tcps_rcvackpack);
+ showtcpstat ("bytes acked by rcvd acks", tcpstat.tcps_rcvackbyte);
+ showtcpstat ("rcvd window update packets", tcpstat.tcps_rcvwinupd);
+ showtcpstat ("segments dropped due to PAWS", tcpstat.tcps_pawsdrop);
+ showtcpstat ("times hdr predict ok for acks", tcpstat.tcps_predack);
+ showtcpstat ("times hdr predict ok for data pkts", tcpstat.tcps_preddat);
+ showtcpstat ("pcb cache misses", tcpstat.tcps_pcbcachemiss);
+ showtcpstat ("times cached RTT in route updated", tcpstat.tcps_cachedrtt);
+ showtcpstat ("times cached rttvar updated", tcpstat.tcps_cachedrttvar);
+ showtcpstat ("times cached ssthresh updated", tcpstat.tcps_cachedssthresh);
+ showtcpstat ("times RTT initialized from route", tcpstat.tcps_usedrtt);
+ showtcpstat ("times RTTVAR initialized from rt", tcpstat.tcps_usedrttvar);
+ showtcpstat ("times ssthresh initialized from rt", tcpstat.tcps_usedssthresh);
+ showtcpstat ("timeout in persist state", tcpstat.tcps_persistdrop);
+ showtcpstat ("bogus SYN, e.g. premature ACK", tcpstat.tcps_badsyn);
+ showtcpstat ("resends due to MTU discovery", tcpstat.tcps_mturesent);
+ showtcpstat ("listen queue overflows", tcpstat.tcps_listendrop);
+ printf ("\n");
+}
diff --git a/cpukit/libnetworking/rtems/rtems_showudpstat.c b/cpukit/libnetworking/rtems/rtems_showudpstat.c
new file mode 100644
index 0000000000..d47534d964
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_showudpstat.c
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+/*
+ * Display UDP statistics
+ * Don't lock the rest of the network tasks out while printing.
+ * It's no big deal if the values change while being printed.
+ */
+static void
+showudpstat (const char *name, unsigned long n)
+{
+ if (n)
+ printf ("%35s%12lu\n", name, n);
+}
+
+void
+rtems_bsdnet_show_udp_stats (void)
+{
+ printf ("************ UDP Statistics ************\n");
+ showudpstat ("total input packets", udpstat.udps_ipackets);
+ showudpstat ("packet shorter than header", udpstat.udps_hdrops);
+ showudpstat ("checksum error", udpstat.udps_badsum);
+ showudpstat ("data length larger than packet", udpstat.udps_badlen);
+ showudpstat ("no socket on port", udpstat.udps_noport);
+ showudpstat ("of above, arrived as broadcast", udpstat.udps_noportbcast);
+ showudpstat ("not delivered, input socket full", udpstat.udps_fullsock);
+ showudpstat ("input packets missing pcb cache", udpstat.udpps_pcbcachemiss);
+ showudpstat ("input packets not for hashed pcb", udpstat.udpps_pcbhashmiss);
+ showudpstat ("total output packets", udpstat.udps_opackets);
+ printf ("\n");
+}
diff --git a/cpukit/libnetworking/rtems/rtems_syscall.c b/cpukit/libnetworking/rtems/rtems_syscall.c
new file mode 100644
index 0000000000..30de3ca3da
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_syscall.c
@@ -0,0 +1,792 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdarg.h>
+/* #include <stdlib.h> */
+#include <stdio.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/proc.h>
+#include <sys/fcntl.h>
+#include <sys/filio.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+/*
+ * Hooks to RTEMS I/O system
+ */
+static const rtems_filesystem_file_handlers_r socket_handlers;
+int rtems_bsdnet_makeFdForSocket(void *so, const rtems_filesystem_file_handlers_r *h);
+struct socket *rtems_bsdnet_fdToSocket(int fd);
+
+/*
+ * Package system call argument into mbuf.
+ */
+static int
+sockargstombuf (struct mbuf **mp, const void *buf, int buflen, int type)
+{
+ struct mbuf *m;
+
+ if ((u_int)buflen > MLEN)
+ return (EINVAL);
+ m = m_get(M_WAIT, type);
+ if (m == NULL)
+ return (ENOBUFS);
+ m->m_len = buflen;
+ memcpy (mtod(m, caddr_t), buf, buflen);
+ *mp = m;
+ if (type == MT_SONAME) {
+ struct sockaddr *sa;
+ sa = mtod(m, struct sockaddr *);
+ sa->sa_len = buflen;
+ }
+ return 0;
+}
+
+/*
+ *********************************************************************
+ * BSD-style entry points *
+ *********************************************************************
+ */
+int
+socket (int domain, int type, int protocol)
+{
+ int fd;
+ int error;
+ struct socket *so;
+
+ rtems_bsdnet_semaphore_obtain ();
+ error = socreate(domain, &so, type, protocol, NULL);
+ if (error == 0) {
+ fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
+ if (fd < 0)
+ soclose (so);
+ }
+ else {
+ errno = error;
+ fd = -1;
+ }
+ rtems_bsdnet_semaphore_release ();
+ return fd;
+}
+
+int
+bind (int s, struct sockaddr *name, int namelen)
+{
+ int error;
+ int ret = -1;
+ struct socket *so;
+ struct mbuf *nam;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) {
+ error = sockargstombuf (&nam, name, namelen, MT_SONAME);
+ if (error == 0) {
+ error = sobind (so, nam);
+ if (error == 0)
+ ret = 0;
+ else
+ errno = error;
+ m_freem (nam);
+ }
+ else {
+ errno = error;
+ }
+ }
+ rtems_bsdnet_semaphore_release ();
+ return ret;
+}
+
+int
+connect (int s, struct sockaddr *name, int namelen)
+{
+ int error;
+ int ret = -1;
+ struct socket *so;
+ struct mbuf *nam;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
+ errno = EALREADY;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ error = sockargstombuf (&nam, name, namelen, MT_SONAME);
+ if (error) {
+ errno = error;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ error = soconnect (so, nam);
+ if (error)
+ goto bad;
+ if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
+ m_freem(nam);
+ errno = EINPROGRESS;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
+ error = soconnsleep (so);
+ if (error)
+ break;
+ }
+ if (error == 0) {
+ error = so->so_error;
+ so->so_error = 0;
+ }
+ bad:
+ so->so_state &= ~SS_ISCONNECTING;
+ m_freem (nam);
+ if (error)
+ errno = error;
+ else
+ ret = 0;
+ rtems_bsdnet_semaphore_release ();
+ return ret;
+}
+
+int
+listen (int s, int backlog)
+{
+ int error;
+ int ret = -1;
+ struct socket *so;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) {
+ error = solisten (so, backlog);
+ if (error == 0)
+ ret = 0;
+ else
+ errno = error;
+ }
+ rtems_bsdnet_semaphore_release ();
+ return ret;
+}
+
+int
+accept (int s, struct sockaddr *name, int *namelen)
+{
+ int fd;
+ struct socket *head, *so;
+ struct mbuf *nam;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((head = rtems_bsdnet_fdToSocket (s)) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ if ((head->so_options & SO_ACCEPTCONN) == 0) {
+ errno = EINVAL;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ if ((head->so_state & SS_NBIO) && head->so_comp.tqh_first == NULL) {
+ errno = EWOULDBLOCK;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ while (head->so_comp.tqh_first == NULL && head->so_error == 0) {
+ if (head->so_state & SS_CANTRCVMORE) {
+ head->so_error = ECONNABORTED;
+ break;
+ }
+ head->so_error = soconnsleep (head);
+ }
+ if (head->so_error) {
+ errno = head->so_error;
+ head->so_error = 0;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+
+ so = head->so_comp.tqh_first;
+ TAILQ_REMOVE(&head->so_comp, so, so_list);
+ head->so_qlen--;
+
+ fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
+ if (fd < 0) {
+ TAILQ_INSERT_HEAD(&head->so_comp, so, so_list);
+ head->so_qlen++;
+ soconnwakeup (head);
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ so->so_state &= ~SS_COMP;
+ so->so_head = NULL;
+
+ nam = m_get(M_WAIT, MT_SONAME);
+ (void) soaccept(so, nam);
+ if (name) {
+ /* check length before it is destroyed */
+ if (*namelen > nam->m_len)
+ *namelen = nam->m_len;
+ memcpy (name, mtod(nam, caddr_t), *namelen);
+ }
+ m_freem(nam);
+ rtems_bsdnet_semaphore_release ();
+ return (fd);
+
+}
+
+/*
+ * Shutdown routine
+ */
+
+int
+shutdown (int s, int how)
+{
+ struct socket *so;
+ int error;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ error = soshutdown(so, how);
+ rtems_bsdnet_semaphore_release ();
+ if (error) {
+ errno = error;
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * All `transmit' operations end up calling this routine.
+ */
+ssize_t
+sendmsg (int s, const struct msghdr *mp, int flags)
+{
+ int ret = -1;
+ int error;
+ struct uio auio;
+ struct iovec *iov;
+ struct socket *so;
+ struct mbuf *to;
+ struct mbuf *control = NULL;
+ int i;
+ int len;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ auio.uio_iov = mp->msg_iov;
+ auio.uio_iovcnt = mp->msg_iovlen;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_offset = 0;
+ auio.uio_resid = 0;
+ iov = mp->msg_iov;
+ for (i = 0; i < mp->msg_iovlen; i++, iov++) {
+ if ((auio.uio_resid += iov->iov_len) < 0) {
+ errno = EINVAL;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ }
+ if (mp->msg_name) {
+ error = sockargstombuf (&to, mp->msg_name, mp->msg_namelen, MT_SONAME);
+ if (error) {
+ errno = error;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ }
+ else {
+ to = NULL;
+ }
+ if (mp->msg_control) {
+ if (mp->msg_controllen < sizeof (struct cmsghdr)) {
+ errno = EINVAL;
+ if (to)
+ m_freem(to);
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ sockargstombuf (&control, mp->msg_control, mp->msg_controllen, MT_CONTROL);
+ }
+ else {
+ control = NULL;
+ }
+ len = auio.uio_resid;
+ error = sosend (so, to, &auio, (struct mbuf *)0, control, flags);
+ if (error) {
+ if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+ }
+ if (error)
+ errno = error;
+ else
+ ret = len - auio.uio_resid;
+ if (to)
+ m_freem(to);
+ rtems_bsdnet_semaphore_release ();
+ return (ret);
+}
+
+/*
+ * Send a message to a host
+ */
+ssize_t
+sendto (int s, const void *buf, size_t buflen, int flags, const struct sockaddr *to, int tolen)
+{
+ struct msghdr msg;
+ struct iovec iov;
+
+ iov.iov_base = (void *)buf;
+ iov.iov_len = buflen;
+ msg.msg_name = (caddr_t)to;
+ msg.msg_namelen = tolen;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ return sendmsg (s, &msg, flags);
+}
+
+/*
+ * Send a message to a connected host
+ */
+ssize_t
+send (int s, const void *buf, size_t buflen, int flags)
+{
+ return sendto (s, buf, buflen, flags, NULL, 0);
+}
+
+/*
+ * All `receive' operations end up calling this routine.
+ */
+ssize_t
+recvmsg (int s, struct msghdr *mp, int flags)
+{
+ int ret = -1;
+ int error;
+ struct uio auio;
+ struct iovec *iov;
+ struct socket *so;
+ struct mbuf *from = NULL, *control = NULL;
+ int i;
+ int len;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ auio.uio_iov = mp->msg_iov;
+ auio.uio_iovcnt = mp->msg_iovlen;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_rw = UIO_READ;
+ auio.uio_offset = 0;
+ auio.uio_resid = 0;
+ iov = mp->msg_iov;
+ for (i = 0; i < mp->msg_iovlen; i++, iov++) {
+ if ((auio.uio_resid += iov->iov_len) < 0) {
+ errno = EINVAL;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ }
+ len = auio.uio_resid;
+ mp->msg_flags = flags;
+ error = soreceive (so, &from, &auio, (struct mbuf **)NULL,
+ mp->msg_control ? &control : (struct mbuf **)NULL,
+ &mp->msg_flags);
+ if (error) {
+ if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+ }
+ if (error) {
+ errno = error;
+ }
+ else {
+ ret = len - auio.uio_resid;
+ if (mp->msg_name) {
+ len = mp->msg_namelen;
+ if ((len <= 0) || (from == NULL)) {
+ len = 0;
+ }
+ else {
+ if (len > from->m_len)
+ len = from->m_len;
+ memcpy (mp->msg_name, mtod(from, caddr_t), len);
+ }
+ mp->msg_namelen = len;
+ }
+ if (mp->msg_control) {
+ struct mbuf *m;
+ void *ctlbuf;
+
+ len = mp->msg_controllen;
+ m = control;
+ mp->msg_controllen = 0;
+ ctlbuf = mp->msg_control;
+
+ while (m && (len > 0)) {
+ unsigned int tocopy;
+
+ if (len >= m->m_len)
+ tocopy = m->m_len;
+ else {
+ mp->msg_flags |= MSG_CTRUNC;
+ tocopy = len;
+ }
+ memcpy(ctlbuf, mtod(m, caddr_t), tocopy);
+ ctlbuf += tocopy;
+ len -= tocopy;
+ m = m->m_next;
+ }
+ mp->msg_controllen = ctlbuf - mp->msg_control;
+ }
+ }
+ if (from)
+ m_freem (from);
+ if (control)
+ m_freem (control);
+ rtems_bsdnet_semaphore_release ();
+ return (ret);
+}
+
+/*
+ * Receive a message from a host
+ */
+ssize_t
+recvfrom (int s, void *buf, size_t buflen, int flags, const struct sockaddr *from, int *fromlen)
+{
+ struct msghdr msg;
+ struct iovec iov;
+ int ret;
+
+ iov.iov_base = buf;
+ iov.iov_len = buflen;
+ msg.msg_name = (caddr_t)from;
+ if (fromlen)
+ msg.msg_namelen = *fromlen;
+ else
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ ret = recvmsg (s, &msg, flags);
+ if ((from != NULL) && (fromlen != NULL) && (ret >= 0))
+ *fromlen = msg.msg_namelen;
+ return ret;
+}
+
+/*
+ * Receive a message from a connected host
+ */
+ssize_t
+recv (int s, void *buf, size_t buflen, int flags)
+{
+ return recvfrom (s, buf, buflen, flags, NULL, NULL);
+}
+
+int
+setsockopt (int s, int level, int name, const void *val, int len)
+{
+ struct socket *so;
+ struct mbuf *m = NULL;
+ int error;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ if (len > MLEN) {
+ errno = EINVAL;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ if (val) {
+ error = sockargstombuf (&m, val, len, MT_SOOPTS);
+ if (error) {
+ errno = error;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ }
+ error = sosetopt(so, level, name, m);
+ if (error) {
+ errno = error;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ rtems_bsdnet_semaphore_release ();
+ return 0;
+}
+
+int
+getsockopt (int s, int level, int name, void *aval, int *avalsize)
+{
+ struct socket *so;
+ struct mbuf *m = NULL, *m0;
+ char *val = aval;
+ int i, op, valsize;
+ int error;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ if (val)
+ valsize = *avalsize;
+ else
+ valsize = 0;
+ if (((error = sogetopt(so, level, name, &m)) == 0) && val && valsize && m) {
+ op = 0;
+ while (m && op < valsize) {
+ i = valsize - op;
+ if (i > m->m_len)
+ i = m->m_len;
+ memcpy (val, mtod(m, caddr_t), i);
+ op += i;
+ val += i;
+ m0 = m;
+ MFREE (m0, m);
+ }
+ *avalsize = op;
+ }
+ if (m != NULL)
+ (void) m_free(m);
+ if (error) {
+ errno = error;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ rtems_bsdnet_semaphore_release ();
+ return 0;
+}
+
+static int
+getpeersockname (int s, struct sockaddr *name, int *namelen, int pflag)
+{
+ struct socket *so;
+ struct mbuf *m;
+ int len = *namelen;
+ int error;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ m = m_getclr(M_WAIT, MT_SONAME);
+ if (m == NULL) {
+ errno = ENOBUFS;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ if (pflag)
+ error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, m);
+ else
+ error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, m);
+ if (error) {
+ m_freem(m);
+ errno = error;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ if (len > m->m_len) {
+ len = m->m_len;
+ *namelen = len;
+ }
+ memcpy (name, mtod(m, caddr_t), len);
+ m_freem (m);
+ rtems_bsdnet_semaphore_release ();
+ return 0;
+}
+
+int
+getpeername (int s, struct sockaddr *name, int *namelen)
+{
+ return getpeersockname (s, name, namelen, 1);
+}
+int
+getsockname (int s, struct sockaddr *name, int *namelen)
+{
+ return getpeersockname (s, name, namelen, 0);
+}
+
+int
+sysctl(int *name, u_int namelen, void *oldp,
+ size_t *oldlenp, void *newp, size_t newlen)
+{
+ int error;
+ size_t j;
+
+ rtems_bsdnet_semaphore_obtain ();
+ error = userland_sysctl (0, name, namelen, oldp, oldlenp, 1, newp, newlen, &j);
+ rtems_bsdnet_semaphore_release ();
+
+ if (oldlenp)
+ *oldlenp = j;
+
+ if (error)
+ {
+ errno = error;
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ ************************************************************************
+ * RTEMS I/O HANDLER ROUTINES *
+ ************************************************************************
+ */
+static int
+rtems_bsdnet_close (rtems_libio_t *iop)
+{
+ struct socket *so;
+ int error;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = iop->data1) == NULL) {
+ errno = EBADF;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ error = soclose (so);
+ rtems_bsdnet_semaphore_release ();
+ if (error) {
+ errno = error;
+ return -1;
+ }
+ return 0;
+}
+
+static ssize_t
+rtems_bsdnet_read (rtems_libio_t *iop, void *buffer, uint32_t count)
+{
+ return recv (iop->data0, buffer, count, 0);
+}
+
+static ssize_t
+rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, uint32_t count)
+{
+ return send (iop->data0, buffer, count, 0);
+}
+
+static int
+so_ioctl (rtems_libio_t *iop, struct socket *so, uint32_t command, void *buffer)
+{
+ switch (command) {
+ case FIONBIO:
+ if (*(int *)buffer) {
+ iop->flags |= O_NONBLOCK;
+ so->so_state |= SS_NBIO;
+ }
+ else {
+ iop->flags &= ~O_NONBLOCK;
+ so->so_state &= ~SS_NBIO;
+ }
+ return 0;
+
+ case FIONREAD:
+ *(int *)buffer = so->so_rcv.sb_cc;
+ return 0;
+ }
+
+ if (IOCGROUP(command) == 'i')
+ return ifioctl (so, command, buffer, NULL);
+ if (IOCGROUP(command) == 'r')
+ return rtioctl (command, buffer, NULL);
+ return (*so->so_proto->pr_usrreqs->pru_control)(so, command, buffer, 0);
+}
+
+static int
+rtems_bsdnet_ioctl (rtems_libio_t *iop, uint32_t command, void *buffer)
+{
+ struct socket *so;
+ int error;
+
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = iop->data1) == NULL) {
+ errno = EBADF;
+ rtems_bsdnet_semaphore_release ();
+ return -1;
+ }
+ error = so_ioctl (iop, so, command, buffer);
+ rtems_bsdnet_semaphore_release ();
+ if (error) {
+ errno = error;
+ return -1;
+ }
+ return 0;
+}
+
+static int
+rtems_bsdnet_fcntl (int cmd, rtems_libio_t *iop)
+{
+ struct socket *so;
+
+ if (cmd == F_SETFL) {
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = iop->data1) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return EBADF;
+ }
+ if (iop->flags & LIBIO_FLAGS_NO_DELAY)
+ so->so_state |= SS_NBIO;
+ else
+ so->so_state &= ~SS_NBIO;
+ rtems_bsdnet_semaphore_release ();
+ }
+ return 0;
+}
+
+static int
+rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
+{
+ sp->st_mode = S_IFSOCK;
+ return 0;
+}
+
+static const rtems_filesystem_file_handlers_r socket_handlers = {
+ NULL, /* open */
+ rtems_bsdnet_close, /* close */
+ rtems_bsdnet_read, /* read */
+ rtems_bsdnet_write, /* write */
+ rtems_bsdnet_ioctl, /* ioctl */
+ NULL, /* lseek */
+ rtems_bsdnet_fstat, /* fstat */
+ NULL, /* fchmod */
+ NULL, /* ftruncate */
+ NULL, /* fpathconf */
+ NULL, /* fsync */
+ NULL, /* fdatasync */
+ rtems_bsdnet_fcntl, /* fcntl */
+};
diff --git a/cpukit/libnetworking/rtems/sghostname.c b/cpukit/libnetworking/rtems/sghostname.c
new file mode 100644
index 0000000000..0303813e12
--- /dev/null
+++ b/cpukit/libnetworking/rtems/sghostname.c
@@ -0,0 +1,53 @@
+/*
+ * RTEMS versions of hostname functions
+ * FIXME: Not thread-safe
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <errno.h>
+#include <rtems/rtems_bsdnet.h>
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+
+static char *rtems_hostname;
+
+int
+gethostname (char *name, size_t namelen)
+{
+ char *cp = rtems_hostname;
+
+ if (cp == NULL)
+ cp = "";
+ strncpy (name, cp, namelen);
+ return 0;
+}
+
+int
+sethostname (char *name, size_t namelen)
+{
+ char *old, *new;
+
+ if (namelen >= MAXHOSTNAMELEN) {
+ errno = EINVAL;
+ return -1;
+ }
+ new = malloc (namelen + 1, M_HTABLE, M_NOWAIT);
+ if (new == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ strncpy (new, name, namelen);
+ new[namelen] = '\0';
+ old = rtems_hostname;
+ rtems_hostname = new;
+ if (old)
+ free (old, M_HTABLE);
+ return 0;
+}
diff --git a/cpukit/libnetworking/rtems/tftp.h b/cpukit/libnetworking/rtems/tftp.h
new file mode 100644
index 0000000000..0813d80431
--- /dev/null
+++ b/cpukit/libnetworking/rtems/tftp.h
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ */
+
+/*
+ * Trivial File Transfer Protocol (TFTP)
+ *
+ * Transfer file to/from remote host
+ *
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ */
+
+/*
+ * Usage:
+ *
+ * To open `/bootfiles/image' on `hostname' for reading:
+ * fd = open ("/TFTP/hostname/bootfiles/image", O_RDONLY);
+ *
+ * The `hostname' must be four dot-separated decimal values.
+ */
+
+#ifndef _RTEMS_TFTP_H
+#define _RTEMS_TFTP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Filesystem initialization routine
+ */
+
+int rtems_bsdnet_initialize_tftp_filesystem( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/sys/buf.h b/cpukit/libnetworking/sys/buf.h
new file mode 100644
index 0000000000..8fbf734cbe
--- /dev/null
+++ b/cpukit/libnetworking/sys/buf.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)buf.h 8.9 (Berkeley) 3/30/95
+ * $FreeBSD: src/sys/sys/buf.h,v 1.181 2004/11/18 08:44:09 jeff Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _SYS_BUF_H_
+#define _SYS_BUF_H_
+
+#include <sys/queue.h>
+
+#define NOLIST ((struct buf *)0x87654321)
+
+struct buf;
+
+struct iodone_chain {
+ long ic_prev_flags;
+ void (*ic_prev_iodone) __P((struct buf *));
+ void *ic_prev_iodone_chain;
+ struct {
+ long ia_long;
+ void *ia_ptr;
+ } ic_args[5];
+};
+
+typedef TAILQ_HEAD(buf_queue_head, buf) buf_queue_head, *buf_queue_head_t;
+
+/*
+ * The buffer header describes an I/O operation in the kernel.
+ */
+struct buf {
+ LIST_ENTRY(buf) b_hash; /* Hash chain. */
+ LIST_ENTRY(buf) b_vnbufs; /* Buffer's associated vnode. */
+ TAILQ_ENTRY(buf) b_freelist; /* Free list position if not active. */
+ TAILQ_ENTRY(buf) b_act; /* Device driver queue when active. *new* */
+ struct proc *b_proc; /* Associated proc; NULL if kernel. */
+ long b_flags; /* B_* flags. */
+ unsigned short b_qindex; /* buffer queue index */
+ unsigned char b_usecount; /* buffer use count */
+ int b_error; /* Errno value. */
+ long b_bufsize; /* Allocated buffer size. */
+ long b_bcount; /* Valid bytes in buffer. */
+ long b_resid; /* Remaining I/O. */
+ dev_t b_dev; /* Device associated with buffer. */
+ struct {
+ caddr_t b_addr; /* Memory, superblocks, indirect etc. */
+ } b_un;
+ caddr_t b_kvabase; /* base kva for buffer */
+ int b_kvasize; /* size of kva for buffer */
+ void *b_saveaddr; /* Original b_addr for physio. */
+ daddr_t b_lblkno; /* Logical block number. */
+ daddr_t b_blkno; /* Underlying physical block number. */
+ /* Function to call upon completion. */
+ void (*b_iodone) __P((struct buf *));
+ /* For nested b_iodone's. */
+ struct iodone_chain *b_iodone_chain;
+ struct vnode *b_vp; /* Device vnode. */
+ int b_dirtyoff; /* Offset in buffer of dirty region. */
+ int b_dirtyend; /* Offset of end of dirty region. */
+ struct ucred *b_rcred; /* Read credentials reference. */
+ struct ucred *b_wcred; /* Write credentials reference. */
+ int b_validoff; /* Offset in buffer of valid region. */
+ int b_validend; /* Offset of end of valid region. */
+ daddr_t b_pblkno; /* physical block number */
+ caddr_t b_savekva; /* saved kva for transfer while bouncing */
+ void *b_driver1; /* for private use by the driver */
+ void *b_driver2; /* for private use by the driver */
+ void *b_spc;
+ union cluster_info {
+ TAILQ_HEAD(cluster_list_head, buf) cluster_head;
+ TAILQ_ENTRY(buf) cluster_entry;
+ } b_cluster;
+ struct vm_page *b_pages[btoc(MAXPHYS)];
+ int b_npages;
+};
+
+/* Device driver compatibility definitions. */
+#define b_data b_un.b_addr /* b_un.b_addr is not changeable. */
+
+/*
+ * These flags are kept in b_flags.
+ */
+#define B_AGE 0x00000001 /* Move to age queue when I/O done. */
+#define B_NEEDCOMMIT 0x00000002 /* Append-write in progress. */
+#define B_ASYNC 0x00000004 /* Start I/O, do not wait. */
+#define B_BAD 0x00000008 /* Bad block revectoring in progress. */
+#define B_BUSY 0x00000010 /* I/O in progress. */
+#define B_CACHE 0x00000020 /* Bread found us in the cache. */
+#define B_CALL 0x00000040 /* Call b_iodone from biodone. */
+#define B_DELWRI 0x00000080 /* Delay I/O until buffer reused. */
+#define B_DIRTY 0x00000100 /* Dirty page to be pushed out async. */
+#define B_DONE 0x00000200 /* I/O completed. */
+#define B_EINTR 0x00000400 /* I/O was interrupted */
+#define B_ERROR 0x00000800 /* I/O error occurred. */
+#define B_GATHERED 0x00001000 /* LFS: already in a segment. */
+#define B_INVAL 0x00002000 /* Does not contain valid info. */
+#define B_LOCKED 0x00004000 /* Locked in core (not reusable). */
+#define B_NOCACHE 0x00008000 /* Do not cache block after use. */
+#define B_MALLOC 0x00010000 /* malloced b_data */
+#define B_CLUSTEROK 0x00020000 /* Pagein op, so swap() can count it. */
+#define B_PHYS 0x00040000 /* I/O to user memory. */
+#define B_RAW 0x00080000 /* Set by physio for raw transfers. */
+#define B_READ 0x00100000 /* Read buffer. */
+#define B_TAPE 0x00200000 /* Magnetic tape I/O. */
+#define B_RELBUF 0x00400000 /* Release VMIO buffer. */
+#define B_WANTED 0x00800000 /* Process wants this buffer. */
+#define B_WRITE 0x00000000 /* Write buffer (pseudo flag). */
+#define B_WRITEINPROG 0x01000000 /* Write in progress. */
+#define B_XXX 0x02000000 /* Debugging flag. */
+#define B_PAGING 0x04000000 /* volatile paging I/O -- bypass VMIO */
+#define B_ORDERED 0x08000000 /* Must guarantee I/O ordering */
+#define B_VMIO 0x20000000 /* VMIO flag */
+#define B_CLUSTER 0x40000000 /* pagein op, so swap() can count it */
+#define B_BOUNCE 0x80000000 /* bounce buffer flag */
+
+/*
+ * number of buffer hash entries
+ */
+#define BUFHSZ 512
+
+/*
+ * buffer hash table calculation, originally by David Greenman
+ */
+#define BUFHASH(vnp, bn) \
+ (&bufhashtbl[(((unsigned long)(vnp) >> 7)+(int)(bn)) % BUFHSZ])
+
+/*
+ * Definitions for the buffer free lists.
+ */
+#define BUFFER_QUEUES 6 /* number of free buffer queues */
+
+extern LIST_HEAD(bufhashhdr, buf) bufhashtbl[BUFHSZ], invalhash;
+extern TAILQ_HEAD(bqueues, buf) bufqueues[BUFFER_QUEUES];
+
+#define QUEUE_NONE 0 /* on no queue */
+#define QUEUE_LOCKED 1 /* locked buffers */
+#define QUEUE_LRU 2 /* useful buffers */
+#define QUEUE_VMIO 3 /* VMIO buffers */
+#define QUEUE_AGE 4 /* not-useful buffers */
+#define QUEUE_EMPTY 5 /* empty buffer headers*/
+
+/*
+ * Zero out the buffer's data area.
+ */
+#define clrbuf(bp) { \
+ bzero((bp)->b_data, (u_int)(bp)->b_bcount); \
+ (bp)->b_resid = 0; \
+}
+
+/* Flags to low-level allocation routines. */
+#define B_CLRBUF 0x01 /* Request allocated buffer be cleared. */
+#define B_SYNC 0x02 /* Do all allocations synchronously. */
+
+#ifdef _KERNEL
+extern int nbuf; /* The number of buffer headers */
+extern struct buf *buf; /* The buffer headers. */
+extern char *buffers; /* The buffer contents. */
+extern int bufpages; /* Number of memory pages in the buffer pool. */
+extern struct buf *swbuf; /* Swap I/O buffer headers. */
+extern int nswbuf; /* Number of swap I/O buffer headers. */
+extern TAILQ_HEAD(swqueue, buf) bswlist;
+
+void bufinit __P((void));
+void bremfree __P((struct buf *));
+int bread __P((struct vnode *, daddr_t, int,
+ struct ucred *, struct buf **));
+int breadn __P((struct vnode *, daddr_t, int, daddr_t *, int *, int,
+ struct ucred *, struct buf **));
+int bwrite __P((struct buf *));
+void bdwrite __P((struct buf *));
+void bawrite __P((struct buf *));
+int bowrite __P((struct buf *));
+void brelse __P((struct buf *));
+void bqrelse __P((struct buf *));
+int vfs_bio_awrite __P((struct buf *));
+struct buf * getpbuf __P((void));
+struct buf *incore __P((struct vnode *, daddr_t));
+struct buf *gbincore __P((struct vnode *, daddr_t));
+int inmem __P((struct vnode *, daddr_t));
+struct buf *getblk __P((struct vnode *, daddr_t, int, int, int));
+struct buf *geteblk __P((int));
+int allocbuf __P((struct buf *, int));
+int biowait __P((struct buf *));
+void biodone __P((struct buf *));
+
+void cluster_callback __P((struct buf *));
+int cluster_read __P((struct vnode *, u_quad_t, daddr_t, long,
+ struct ucred *, struct buf **));
+int cluster_wbuild __P((struct vnode *, long, daddr_t, int));
+void cluster_write __P((struct buf *, u_quad_t));
+int physio __P((void (*)(struct buf *), struct buf *, dev_t,
+ int, u_int (*)(struct buf *), struct uio *));
+u_int minphys __P((struct buf *));
+void vfs_bio_clrbuf __P((struct buf *));
+void vfs_busy_pages __P((struct buf *, int clear_modify));
+void vfs_unbusy_pages(struct buf *);
+void vwakeup __P((struct buf *));
+void vmapbuf __P((struct buf *));
+void vunmapbuf __P((struct buf *));
+void relpbuf __P((struct buf *));
+void brelvp __P((struct buf *));
+void bgetvp __P((struct vnode *, struct buf *));
+void pbgetvp __P((struct vnode *, struct buf *));
+void pbrelvp __P((struct buf *));
+void reassignbuf __P((struct buf *, struct vnode *));
+struct buf *trypbuf __P((void));
+void vm_bounce_alloc __P((struct buf *));
+void vm_bounce_free __P((struct buf *));
+vm_offset_t vm_bounce_kva_alloc __P((int));
+void vm_bounce_kva_alloc_free __P((vm_offset_t, int));
+#endif /* _KERNEL */
+
+#endif /* !_SYS_BUF_H_ */
diff --git a/cpukit/libnetworking/sys/callout.h b/cpukit/libnetworking/sys/callout.h
new file mode 100644
index 0000000000..132dc3e92c
--- /dev/null
+++ b/cpukit/libnetworking/sys/callout.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)callout.h 8.2 (Berkeley) 1/21/94
+ * $FreeBSD: src/sys/sys/callout.h,v 1.27 2004/04/20 15:49:31 cperciva Exp $
+ */
+
+#ifndef _SYS_CALLOUT_H_
+#define _SYS_CALLOUT_H_
+
+struct callout {
+ struct callout *c_next; /* next callout in queue */
+ void *c_arg; /* function argument */
+ void (*c_func) __P((void *)); /* function to call */
+ int c_time; /* ticks to the event */
+};
+
+#ifdef _KERNEL
+extern struct callout *callfree, *callout, calltodo;
+extern int ncallout;
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/sys/conf.h b/cpukit/libnetworking/sys/conf.h
new file mode 100644
index 0000000000..207acfe33d
--- /dev/null
+++ b/cpukit/libnetworking/sys/conf.h
@@ -0,0 +1,228 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ *
+ * @(#)conf.h 8.5 (Berkeley) 1/9/95
+ * $Id$
+ */
+
+#ifndef _SYS_CONF_H_
+#define _SYS_CONF_H_
+
+/*
+ * Definitions of device driver entry switches
+ */
+
+struct buf;
+struct proc;
+struct tty;
+struct uio;
+struct vnode;
+
+typedef int d_open_t __P((dev_t dev, int oflags, int devtype, struct proc *p));
+typedef int d_close_t __P((dev_t dev, int fflag, int devtype, struct proc *p));
+typedef void d_strategy_t __P((struct buf *bp));
+typedef int d_ioctl_t __P((dev_t dev, int cmd, caddr_t data,
+ int fflag, struct proc *p));
+typedef int d_dump_t __P((dev_t dev));
+typedef int d_psize_t __P((dev_t dev));
+
+typedef int d_read_t __P((dev_t dev, struct uio *uio, int ioflag));
+typedef int d_write_t __P((dev_t dev, struct uio *uio, int ioflag));
+typedef void d_stop_t __P((struct tty *tp, int rw));
+typedef int d_reset_t __P((dev_t dev));
+typedef struct tty *d_devtotty_t __P((dev_t dev));
+typedef int d_select_t __P((dev_t dev, int which, struct proc *p));
+typedef int d_mmap_t __P((dev_t dev, int offset, int nprot));
+
+typedef int l_open_t __P((dev_t dev, struct tty *tp));
+typedef int l_close_t __P((struct tty *tp, int flag));
+typedef int l_read_t __P((struct tty *tp, struct uio *uio, int flag));
+typedef int l_write_t __P((struct tty *tp, struct uio *uio, int flag));
+typedef int l_ioctl_t __P((struct tty *tp, int cmd, caddr_t data,
+ int flag, struct proc *p));
+typedef int l_rint_t __P((int c, struct tty *tp));
+typedef int l_start_t __P((struct tty *tp));
+typedef int l_modem_t __P((struct tty *tp, int flag));
+
+/*
+ * Block device switch table
+ */
+struct bdevsw {
+ d_open_t *d_open;
+ d_close_t *d_close;
+ d_strategy_t *d_strategy;
+ d_ioctl_t *d_ioctl;
+ d_dump_t *d_dump;
+ d_psize_t *d_psize;
+ int d_flags;
+ char *d_name; /* name of the driver e.g. audio */
+ struct cdevsw *d_cdev; /* cross pointer to the cdev */
+ int d_maj; /* the major number we were assigned */
+};
+
+#ifdef _KERNEL
+extern struct bdevsw *bdevsw[];
+#endif
+
+/*
+ * Character device switch table
+ */
+struct cdevsw {
+ d_open_t *d_open;
+ d_close_t *d_close;
+ d_read_t *d_read;
+ d_write_t *d_write;
+ d_ioctl_t *d_ioctl;
+ d_stop_t *d_stop;
+ d_reset_t *d_reset; /* XXX not used */
+ d_devtotty_t *d_devtotty;
+ d_select_t *d_select;
+ d_mmap_t *d_mmap;
+ d_strategy_t *d_strategy;
+ char *d_name; /* see above */
+ struct bdevsw *d_bdev;
+ int d_maj;
+};
+
+#ifdef _KERNEL
+extern struct cdevsw *cdevsw[];
+#endif
+
+/*
+ * Line discipline switch table
+ */
+struct linesw {
+ l_open_t *l_open;
+ l_close_t *l_close;
+ l_read_t *l_read;
+ l_write_t *l_write;
+ l_ioctl_t *l_ioctl;
+ l_rint_t *l_rint;
+ l_start_t *l_start;
+ l_modem_t *l_modem;
+};
+
+#ifdef _KERNEL
+extern struct linesw linesw[];
+extern int nlinesw;
+
+int ldisc_register __P((int , struct linesw *));
+void ldisc_deregister __P((int));
+#define LDISC_LOAD -1 /* Loadable line discipline */
+#endif
+
+/*
+ * Swap device table
+ */
+struct swdevt {
+ dev_t sw_dev;
+ int sw_flags;
+ int sw_nblks;
+ struct vnode *sw_vp;
+};
+#define SW_FREED 0x01
+#define SW_SEQUENTIAL 0x02
+#define sw_freed sw_flags /* XXX compat */
+
+#ifdef _KERNEL
+d_open_t noopen;
+d_close_t noclose;
+d_read_t noread;
+d_write_t nowrite;
+d_ioctl_t noioctl;
+d_stop_t nostop;
+d_reset_t noreset;
+d_devtotty_t nodevtotty;
+d_select_t noselect;
+d_mmap_t nommap;
+
+/* Bogus defines for compatibility. */
+#define noioc noioctl
+#define nostrat nostrategy
+#define zerosize nopsize
+/*
+ * XXX d_strategy seems to be unused for cdevs that aren't associated with
+ * bdevs and called without checking for it being non-NULL for bdevs.
+ */
+#define nostrategy ((d_strategy_t *)NULL)
+
+d_dump_t nodump;
+
+/*
+ * nopsize is little used, so not worth having dummy functions for.
+ */
+#define nopsize ((d_psize_t *)NULL)
+
+d_open_t nullopen;
+d_close_t nullclose;
+#define nullstop nostop /* one void return is as good as another */
+#define nullreset noreset /* one unused function is as good as another */
+
+d_open_t nxopen;
+d_close_t nxclose;
+d_read_t nxread;
+d_write_t nxwrite;
+d_ioctl_t nxioctl;
+#define nxstop nostop /* one void return is as good as another */
+#define nxreset noreset /* one unused function is as good as another */
+#define nxdevtotty nodevtotty /* one NULL return is as good as another */
+d_select_t nxselect;
+#define nxmmap nommap /* one -1 return is as good as another */
+#define nxstrategy nostrategy /* one NULL value is as good as another */
+d_dump_t nxdump;
+#define nxpsize nopsize /* one NULL value is as good as another */
+
+d_read_t rawread;
+d_write_t rawwrite;
+
+l_read_t l_noread;
+l_write_t l_nowrite;
+
+int bdevsw_add __P((dev_t *descrip,struct bdevsw *new,struct bdevsw **old));
+int cdevsw_add __P((dev_t *descrip,struct cdevsw *new,struct cdevsw **old));
+void cdevsw_make __P((struct bdevsw *from));
+void bdevsw_add_generic __P((int bdev, int cdev, struct bdevsw *bdevsw));
+dev_t chrtoblk __P((dev_t dev));
+int isdisk __P((dev_t dev, int type));
+int iskmemdev __P((dev_t dev));
+int iszerodev __P((dev_t dev));
+void setconf __P((void));
+#endif /* _KERNEL */
+
+#include <machine/conf.h>
+
+#endif /* !_SYS_CONF_H_ */
diff --git a/cpukit/libnetworking/sys/domain.h b/cpukit/libnetworking/sys/domain.h
new file mode 100644
index 0000000000..54622018b2
--- /dev/null
+++ b/cpukit/libnetworking/sys/domain.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ *
+ * @(#)domain.h 8.1 (Berkeley) 6/2/93
+ * $Id$
+ */
+
+#ifndef _SYS_DOMAIN_H_
+#define _SYS_DOMAIN_H_
+
+/*
+ * Structure per communications domain.
+ */
+
+/*
+ * Forward structure declarations for function prototypes [sic].
+ */
+struct mbuf;
+
+struct domain {
+ int dom_family; /* AF_xxx */
+ char *dom_name;
+ void (*dom_init) /* initialize domain data structures */
+ __P((void));
+ int (*dom_externalize) /* externalize access rights */
+ __P((struct mbuf *));
+ void (*dom_dispose) /* dispose of internalized rights */
+ __P((struct mbuf *));
+ struct protosw *dom_protosw, *dom_protoswNPROTOSW;
+ struct domain *dom_next;
+ int (*dom_rtattach) /* initialize routing table */
+ __P((void **, int));
+ int dom_rtoffset; /* an arg to rtattach, in bits */
+ int dom_maxrtkey; /* for routing layer */
+};
+
+#ifdef _KERNEL
+extern struct domain *domains;
+extern struct domain localdomain;
+
+#define DOMAIN_SET(name) \
+ DATA_SET(domain_set, name ## domain);
+
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/sys/kernel.h b/cpukit/libnetworking/sys/kernel.h
new file mode 100644
index 0000000000..25e483809a
--- /dev/null
+++ b/cpukit/libnetworking/sys/kernel.h
@@ -0,0 +1,264 @@
+/*-
+ * Copyright (c) 1995 Terrence R. Lambert
+ * All rights reserved.
+ *
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ *
+ * @(#)kernel.h 8.3 (Berkeley) 1/21/94
+ * $Id$
+ */
+
+#ifndef _SYS_KERNEL_H_
+#define _SYS_KERNEL_H_
+
+/* Global variables for the kernel. */
+
+/* 1.1 */
+extern long hostid;
+extern char hostname[MAXHOSTNAMELEN];
+extern int hostnamelen;
+extern char domainname[MAXHOSTNAMELEN];
+extern int domainnamelen;
+extern char kernelname[MAXPATHLEN];
+
+/* 1.2 */
+extern volatile struct timeval mono_time;
+extern struct timeval boottime;
+extern struct timeval runtime;
+/* extern volatile struct timeval time; */
+extern struct timezone tz; /* XXX */
+
+extern int tick; /* usec per tick (1000000 / hz) */
+extern int hz; /* system clock's frequency */
+extern int psratio; /* ratio: prof / stat */
+extern int stathz; /* statistics clock's frequency */
+extern int profhz; /* profiling clock's frequency */
+extern int ticks;
+extern int lbolt; /* once a second sleep address */
+extern int tickdelta;
+extern long timedelta;
+
+#if FREEBSD_RELENG_2_2_2_BASE
+/*
+ * The following macros are used to declare global sets of objects, which
+ * are collected by the linker into a `struct linker_set' as defined below.
+ *
+ * NB: the constants defined below must match those defined in
+ * ld/ld.h. Since their calculation requires arithmetic, we
+ * can't name them symbolically (e.g., 23 is N_SETT | N_EXT).
+ */
+#define MAKE_SET(set, sym, type)
+#define TEXT_SET(set, sym) MAKE_SET(set, sym, 23)
+#define DATA_SET(set, sym) MAKE_SET(set, sym, 25)
+#define BSS_SET(set, sym) MAKE_SET(set, sym, 27)
+#define ABS_SET(set, sym) MAKE_SET(set, sym, 21)
+
+#else
+
+/*
+ * RTEMS specific port using the updated sys/linker_set.h
+ * from the lastest FreeBSD (2002-Nov-15). This is a better
+ * way.
+ *
+ * Chris Johns (ccj@acm.org> 18 Nov 2002.
+ */
+#include <sys/linker_set.h>
+
+#endif
+
+/*
+ * Enumerated types for known system startup interfaces.
+ *
+ * Startup occurs in ascending numeric order; the list entries are
+ * sorted prior to attempting startup to guarantee order. Items
+ * of the same level are arbitrated for order based on the 'order'
+ * element.
+ *
+ * These numbers are arbitrary and are chosen ONLY for ordering; the
+ * enumeration values are explicit rather than implicit to provide
+ * for binary compatibility with inserted elements.
+ *
+ * The SI_SUB_RUN_SCHEDULER value must have the highest lexical value.
+ *
+ * The SI_SUB_CONSOLE and SI_SUB_SWAP values represent values used by
+ * the BSD 4.4Lite but not by FreeBSD; they are maintained in dependent
+ * order to support porting.
+ *
+ * The SI_SUB_PROTO_BEGIN and SI_SUB_PROTO_END bracket a range of
+ * initializations to take place at splimp(). This is a historical
+ * wart that should be removed -- probably running everything at
+ * splimp() until the first init that doesn't want it is the correct
+ * fix. They are currently present to ensure historical behavior.
+ */
+enum sysinit_sub_id {
+ SI_SUB_DUMMY = 0x00000000, /* not executed; for linker*/
+ SI_SUB_CONSOLE = 0x08000000, /* console*/
+ SI_SUB_COPYRIGHT = 0x08000001, /* first use of console*/
+ SI_SUB_VM = 0x10000000, /* virtual memory system init*/
+ SI_SUB_KMEM = 0x18000000, /* kernel memory*/
+ SI_SUB_CPU = 0x20000000, /* CPU resource(s)*/
+ SI_SUB_DEVFS = 0x22000000, /* get DEVFS ready */
+ SI_SUB_DRIVERS = 0x23000000, /* Let Drivers initialize */
+ SI_SUB_CONFIGURE = 0x24000000, /* Configure devices */
+ SI_SUB_INTRINSIC = 0x28000000, /* proc 0*/
+ SI_SUB_RUN_QUEUE = 0x30000000, /* the run queue*/
+ SI_SUB_VM_CONF = 0x38000000, /* config VM, set limits*/
+ SI_SUB_VFS = 0x40000000, /* virtual file system*/
+ SI_SUB_CLOCKS = 0x48000000, /* real time and stat clocks*/
+ SI_SUB_MBUF = 0x50000000, /* mbufs*/
+ SI_SUB_CLIST = 0x58000000, /* clists*/
+ SI_SUB_SYSV_SHM = 0x64000000, /* System V shared memory*/
+ SI_SUB_SYSV_SEM = 0x68000000, /* System V semaphores*/
+ SI_SUB_SYSV_MSG = 0x6C000000, /* System V message queues*/
+ SI_SUB_PSEUDO = 0x70000000, /* pseudo devices*/
+ SI_SUB_PROTO_BEGIN = 0x80000000, /* XXX: set splimp (kludge)*/
+ SI_SUB_PROTO_IF = 0x84000000, /* interfaces*/
+ SI_SUB_PROTO_DOMAIN = 0x88000000, /* domains (address families?)*/
+ SI_SUB_PROTO_END = 0x8fffffff, /* XXX: set splx (kludge)*/
+ SI_SUB_KPROF = 0x90000000, /* kernel profiling*/
+ SI_SUB_KICK_SCHEDULER = 0xa0000000, /* start the timeout events*/
+ SI_SUB_ROOT = 0xb0000000, /* root mount*/
+ SI_SUB_ROOT_FDTAB = 0xb8000000, /* root vnode in fd table...*/
+ SI_SUB_SWAP = 0xc0000000, /* swap*/
+ SI_SUB_INTRINSIC_POST = 0xd0000000, /* proc 0 cleanup*/
+ SI_SUB_KTHREAD_INIT = 0xe0000000, /* init process*/
+ SI_SUB_KTHREAD_PAGE = 0xe4000000, /* pageout daemon*/
+ SI_SUB_KTHREAD_VM = 0xe8000000, /* vm daemon*/
+ SI_SUB_KTHREAD_UPDATE = 0xec000000, /* update daemon*/
+ SI_SUB_RUN_SCHEDULER = 0xffffffff /* scheduler: no return*/
+};
+
+
+/*
+ * Some enumerated orders; "ANY" sorts last.
+ */
+enum sysinit_elem_order {
+ SI_ORDER_FIRST = 0x00000000, /* first*/
+ SI_ORDER_SECOND = 0x00000001, /* second*/
+ SI_ORDER_THIRD = 0x00000002, /* third*/
+ SI_ORDER_MIDDLE = 0x10000000, /* somewhere in the middle */
+ SI_ORDER_ANY = 0xffffffff /* last*/
+};
+
+
+/*
+ * System initialization call types; currently two are supported... one
+ * to do a simple function call and one to cause a process to be started
+ * by the kernel on the callers behalf.
+ */
+typedef enum sysinit_elem_type {
+ SI_TYPE_DEFAULT = 0x00000000, /* No special processing*/
+ SI_TYPE_KTHREAD = 0x00000001 /* start kernel thread*/
+} si_elem_t;
+
+
+/*
+ * A system initialization call instance
+ *
+ * The subsystem
+ */
+struct sysinit {
+ unsigned int subsystem; /* subsystem identifier*/
+ unsigned int order; /* init order within subsystem*/
+ void (*func) __P((void *)); /* init function*/
+ void *udata; /* multiplexer/argument */
+ si_elem_t type; /* sysinit_elem_type*/
+};
+
+
+/*
+ * Default: no special processing
+ */
+#define SYSINIT(uniquifier, subsystem, order, func, ident)
+
+/*
+ * Call 'fork()' before calling '(*func)(ident)';
+ * for making a kernel 'thread' (or builtin process.)
+ */
+#define SYSINIT_KT(uniquifier, subsystem, order, func, ident)
+
+
+/*
+ * A kernel process descriptor; used to start "internal" daemons
+ *
+ * Note: global_procpp may be NULL for no global save area
+ */
+struct kproc_desc {
+ char *arg0; /* arg 0 (for 'ps' listing)*/
+ void (*func) __P((void)); /* "main" for kernel process*/
+ struct proc **global_procpp; /* ptr to proc ptr save area*/
+};
+
+void kproc_start __P((void *udata));
+
+#ifdef PSEUDO_LKM
+#include <sys/conf.h>
+#include <sys/exec.h>
+#include <sys/sysent.h>
+#include <sys/lkm.h>
+
+#define PSEUDO_SET(init, name) \
+ extern struct linker_set MODVNOPS; \
+ MOD_MISC(name); \
+ static int \
+ name ## _load(struct lkm_table *lkmtp, int cmd) \
+ { init((void *)NULL /* XXX unused (?) */); return 0; } \
+ static int \
+ name ## _unload(struct lkm_table *lkmtp, int cmd) \
+ { return EINVAL; } \
+ int \
+ name ## _mod(struct lkm_table *lkmtp, int cmd, int ver) { \
+ DISPATCH(lkmtp, cmd, ver, name ## _load, name ## _unload, \
+ lkm_nullcmd); }
+#else /* PSEUDO_LKM */
+
+/*
+ * Compatibility. To be deprecated after LKM is updated.
+ */
+#define PSEUDO_SET(sym, name) SYSINIT(ps, SI_SUB_PSEUDO, SI_ORDER_ANY, sym, 0)
+
+#endif /* PSEUDO_LKM */
+
+struct linker_set {
+ int ls_length;
+ const void *ls_items[1]; /* really ls_length of them,
+ * trailing NULL */
+};
+
+extern struct linker_set execsw_set;
+
+#endif /* !_SYS_KERNEL_H_*/
diff --git a/cpukit/libnetworking/sys/libkern.h b/cpukit/libnetworking/sys/libkern.h
new file mode 100644
index 0000000000..fd09ced07f
--- /dev/null
+++ b/cpukit/libnetworking/sys/libkern.h
@@ -0,0 +1,94 @@
+/*-
+ * 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.
+ * 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.
+ *
+ * @(#)libkern.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/sys/libkern.h,v 1.48 2005/02/10 20:39:39 glebius Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _SYS_LIBKERN_H_
+#define _SYS_LIBKERN_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/* BCD conversions. */
+extern u_char const bcd2bin_data[];
+extern u_char const bin2bcd_data[];
+extern char const hex2ascii_data[];
+
+#define bcd2bin(bcd) (bcd2bin_data[bcd])
+#define bin2bcd(bin) (bin2bcd_data[bin])
+#define hex2ascii(hex) (hex2ascii_data[hex])
+
+static __inline int imax(int a, int b) { return (a > b ? a : b); }
+static __inline int imin(int a, int b) { return (a < b ? a : b); }
+static __inline long lmax(long a, long b) { return (a > b ? a : b); }
+static __inline long lmin(long a, long b) { return (a < b ? a : b); }
+static __inline u_int max(u_int a, u_int b) { return (a > b ? a : b); }
+static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); }
+static __inline quad_t qmax(quad_t a, quad_t b) { return (a > b ? a : b); }
+static __inline quad_t qmin(quad_t a, quad_t b) { return (a < b ? a : b); }
+static __inline u_long ulmax(u_long a, u_long b) { return (a > b ? a : b); }
+static __inline u_long ulmin(u_long a, u_long b) { return (a < b ? a : b); }
+
+/* Prototypes for non-quad routines. */
+int bcmp(const void *, const void *, size_t);
+#ifndef HAVE_INLINE_FFS
+int ffs(int);
+#endif
+#ifndef HAVE_INLINE_FLS
+int fls(int);
+#endif
+int locc(int, char *, u_int);
+void qsort(void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *));
+#if defined(__rtems__)
+u_long rtems_bsdnet_random(void);
+#define random() rtems_bsdnet_random()
+#else
+u_long random(void);
+#endif
+char *index(const char *, int);
+char *rindex(const char *, int);
+int scanc(u_int, const u_char *, const u_char *, int);
+int skpc(int, int, char *);
+void srandom(u_long);
+char *strcat(char * __restrict, const char * __restrict);
+int strcmp(const char *, const char *);
+char *strdup(const char *s);
+char *strcpy(char * __restrict, const char * __restrict);
+size_t strlen(const char *);
+int strncmp(const char *, const char *, size_t);
+char *strncpy(char * __restrict, const char * __restrict, size_t);
+char *strerror(int errnum);
+
+#endif /* !_SYS_LIBKERN_H_ */
diff --git a/cpukit/libnetworking/sys/linker_set.h b/cpukit/libnetworking/sys/linker_set.h
new file mode 100644
index 0000000000..a2354ed397
--- /dev/null
+++ b/cpukit/libnetworking/sys/linker_set.h
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 1999 John D. Polstra
+ * Copyright (c) 1999,2001 Peter Wemm <peter@FreeBSD.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/sys/sys/linker_set.h,v 1.13 2002/09/23 06:11:29 peter Exp $
+ */
+
+#ifndef _SYS_LINKER_SET_H_
+#define _SYS_LINKER_SET_H_
+
+/*
+ * The following macros are used to declare global sets of objects, which
+ * are collected by the linker into a `linker_set' as defined below.
+ * For ELF, this is done by constructing a separate segment for each set.
+ */
+
+/*
+ * Private macros, not to be used outside this header file.
+ */
+#ifdef __GNUC__
+#define __MAKE_SET(set, sym) \
+ static void const * const __set_##set##_sym_##sym \
+ __attribute((section("set_" #set))) __used = &sym
+#else /* !__GNUC__ */
+#ifndef lint
+#error "This file needs to be compiled by GCC or lint"
+#endif /* lint */
+#define __MAKE_SET(set, sym) extern void const * const (__set_##set##_sym_##sym)
+#endif /* __GNUC__ */
+
+/*
+ * Public macros.
+ */
+#define TEXT_SET(set, sym) __MAKE_SET(set, sym)
+#define DATA_SET(set, sym) __MAKE_SET(set, sym)
+#define BSS_SET(set, sym) __MAKE_SET(set, sym)
+#define ABS_SET(set, sym) __MAKE_SET(set, sym)
+#define SET_ENTRY(set, sym) __MAKE_SET(set, sym)
+
+/*
+ * Initialize before referring to a give linker set
+ */
+#define SET_DECLARE(set, ptype) \
+ extern ptype *__CONCAT(__start_set_,set)[]; \
+ extern ptype *__CONCAT(__stop_set_,set)[]
+
+#define SET_BEGIN(set) \
+ (__CONCAT(__start_set_,set))
+#define SET_LIMIT(set) \
+ (__CONCAT(__stop_set_,set))
+
+/*
+ * Iterate over all the elements of a set.
+ *
+ * Sets always contain addresses of things, and "pvar" points to words
+ * containing those addresses. Thus is must be declared as "type **pvar",
+ * and the address of each set item is obtained inside the loop by "*pvar".
+ */
+#define SET_FOREACH(pvar, set) \
+ for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++)
+
+#define SET_ITEM(set, i) \
+ ((SET_BEGIN(set))[i])
+
+/*
+ * Provide a count of the items in a set.
+ */
+#define SET_COUNT(set) \
+ (SET_LIMIT(set) - SET_BEGIN(set))
+
+#endif /* _SYS_LINKER_SET_H_ */
diff --git a/cpukit/libnetworking/sys/malloc.h b/cpukit/libnetworking/sys/malloc.h
new file mode 100644
index 0000000000..4574213ee8
--- /dev/null
+++ b/cpukit/libnetworking/sys/malloc.h
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 1987, 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.
+ *
+ * @(#)malloc.h 8.5 (Berkeley) 5/3/95
+ * $Id$
+ */
+
+#ifndef _SYS_MALLOC_H_
+#define _SYS_MALLOC_H_
+
+#include <rtems/rtems_bsdnet_internal.h> /* Ensure we get RTEMS malloc hooks */
+#define KMEMSTATS
+
+/*
+ * flags to malloc
+ */
+#define M_WAITOK 0x0000
+#define M_NOWAIT 0x0001
+#define M_KERNEL 0x0002
+
+/*
+ * Types of memory to be allocated
+ */
+#define M_FREE 0 /* should be on free list */
+#define M_MBUF 1 /* mbuf */
+#define M_DEVBUF 2 /* device driver memory */
+#define M_SOCKET 3 /* socket structure */
+#define M_PCB 4 /* protocol control block */
+#define M_RTABLE 5 /* routing tables */
+#define M_HTABLE 6 /* IMP host tables */
+#define M_FTABLE 7 /* fragment reassembly header */
+#define M_ZOMBIE 8 /* zombie proc status */
+#define M_IFADDR 9 /* interface address */
+#define M_SOOPTS 10 /* socket options */
+#define M_SONAME 11 /* socket name */
+#define M_NAMEI 12 /* namei path name buffer */
+#define M_GPROF 13 /* kernel profiling buffer */
+#define M_IOCTLOPS 14 /* ioctl data buffer */
+#define M_MAPMEM 15 /* mapped memory descriptors */
+#define M_CRED 16 /* credentials */
+#define M_PGRP 17 /* process group header */
+#define M_SESSION 18 /* session header */
+#define M_IOV 19 /* large iov's */
+#define M_MOUNT 20 /* vfs mount struct */
+#define M_FHANDLE 21 /* network file handle */
+#define M_NFSREQ 22 /* NFS request header */
+#define M_NFSMNT 23 /* NFS mount structure */
+#define M_NFSNODE 24 /* NFS vnode private part */
+#define M_VNODE 25 /* Dynamically allocated vnodes */
+#define M_CACHE 26 /* Dynamically allocated cache entries */
+#define M_DQUOT 27 /* UFS quota entries */
+#define M_UFSMNT 28 /* UFS mount structure */
+#define M_SHM 29 /* SVID compatible shared memory segments */
+#define M_VMMAP 30 /* VM map structures */
+#define M_VMMAPENT 31 /* VM map entry structures */
+#define M_VMOBJ 32 /* VM object structure */
+#define M_VMOBJHASH 33 /* VM object hash structure */
+#define M_VMPMAP 34 /* VM pmap */
+#define M_VMPVENT 35 /* VM phys-virt mapping entry */
+#define M_VMPAGER 36 /* XXX: VM pager struct */
+#define M_VMPGDATA 37 /* XXX: VM pager private data */
+#define M_FILE 38 /* Open file structure */
+#define M_FILEDESC 39 /* Open file descriptor table */
+#define M_LOCKF 40 /* Byte-range locking structures */
+#define M_PROC 41 /* Proc structures */
+#define M_SUBPROC 42 /* Proc sub-structures */
+#define M_SEGMENT 43 /* Segment for LFS */
+#define M_LFSNODE 44 /* LFS vnode private part */
+#define M_FFSNODE 45 /* FFS vnode private part */
+#define M_MFSNODE 46 /* MFS vnode private part */
+#define M_NQLEASE 47 /* Nqnfs lease */
+#define M_NQMHOST 48 /* Nqnfs host address table */
+#define M_NETADDR 49 /* Export host address structure */
+#define M_NFSSVC 50 /* Nfs server structure */
+#define M_NFSUID 51 /* Nfs uid mapping structure */
+#define M_NFSD 52 /* Nfs server daemon structure */
+#define M_IPMOPTS 53 /* internet multicast options */
+#define M_IPMADDR 54 /* internet multicast address */
+#define M_IFMADDR 55 /* link-level multicast address */
+#define M_MRTABLE 56 /* multicast routing tables */
+#define M_ISOFSMNT 57 /* ISOFS mount structure */
+#define M_ISOFSNODE 58 /* ISOFS vnode private part */
+#define M_NFSRVDESC 59 /* NFS server socket descriptor */
+#define M_NFSDIROFF 60 /* NFS directory offset data */
+#define M_NFSBIGFH 61 /* NFS version 3 file handle */
+#define M_MSDOSFSMNT 67 /* MSDOSFS mount structure */
+#define M_MSDOSFSNODE 68 /* MSDOSFS vnode private part */
+#define M_MSDOSFSFAT 69 /* MSDOSFS file allocation table */
+#define M_DEVFSMNT 70 /* DEVFS mount structure */
+#define M_DEVFSBACK 71 /* DEVFS Back node */
+#define M_DEVFSFRONT 72 /* DEVFS Front node */
+#define M_DEVFSNODE 73 /* DEVFS node */
+#define M_TEMP 74 /* misc temporary data buffers */
+#define M_TTYS 75 /* tty data structures */
+#define M_GZIP 76 /* Gzip trees */
+#define M_IPFW 77 /* IpFw/IpAcct chain's */
+#define M_DEVL 78 /* isa_device lists in userconfig() */
+#define M_PKTCLASS 79 /* structures used in packet classifier */
+#define M_SYSCTL 80 /* sysctl internal magic */
+#define M_SECA 81 /* security associations, key management */
+#define M_BIOBUF 82 /* BIO buffer */
+#define M_KTRACE 83 /* KTRACE */
+#define M_SELECT 84 /* select() buffer */
+#define M_CFS 85 /* Coda */
+#define M_LAST 86 /* Must be last type + 1 */
+
+#define INITKMEMNAMES { \
+ "free", /* 0 M_FREE */ \
+ "mbuf", /* 1 M_MBUF */ \
+ "devbuf", /* 2 M_DEVBUF */ \
+ "socket", /* 3 M_SOCKET */ \
+ "pcb", /* 4 M_PCB */ \
+ "routetbl", /* 5 M_RTABLE */ \
+ "hosttbl", /* 6 M_HTABLE */ \
+ "fragtbl", /* 7 M_FTABLE */ \
+ "zombie", /* 8 M_ZOMBIE */ \
+ "ifaddr", /* 9 M_IFADDR */ \
+ "soopts", /* 10 M_SOOPTS */ \
+ "soname", /* 11 M_SONAME */ \
+ "namei", /* 12 M_NAMEI */ \
+ "gprof", /* 13 M_GPROF */ \
+ "ioctlops", /* 14 M_IOCTLOPS */ \
+ "mapmem", /* 15 M_MAPMEM */ \
+ "cred", /* 16 M_CRED */ \
+ "pgrp", /* 17 M_PGRP */ \
+ "session", /* 18 M_SESSION */ \
+ "iov", /* 19 M_IOV */ \
+ "mount", /* 20 M_MOUNT */ \
+ "fhandle", /* 21 M_FHANDLE */ \
+ "NFS req", /* 22 M_NFSREQ */ \
+ "NFS mount", /* 23 M_NFSMNT */ \
+ "NFS node", /* 24 M_NFSNODE */ \
+ "vnodes", /* 25 M_VNODE */ \
+ "namecache", /* 26 M_CACHE */ \
+ "UFS quota", /* 27 M_DQUOT */ \
+ "UFS mount", /* 28 M_UFSMNT */ \
+ "shm", /* 29 M_SHM */ \
+ "VM map", /* 30 M_VMMAP */ \
+ "VM mapent", /* 31 M_VMMAPENT */ \
+ "VM object", /* 32 M_VMOBJ */ \
+ "VM objhash", /* 33 M_VMOBJHASH */ \
+ "VM pmap", /* 34 M_VMPMAP */ \
+ "VM pvmap", /* 35 M_VMPVENT */ \
+ "VM pager", /* 36 M_VMPAGER */ \
+ "VM pgdata", /* 37 M_VMPGDATA */ \
+ "file", /* 38 M_FILE */ \
+ "file desc", /* 39 M_FILEDESC */ \
+ "lockf", /* 40 M_LOCKF */ \
+ "proc", /* 41 M_PROC */ \
+ "subproc", /* 42 M_SUBPROC */ \
+ "LFS segment", /* 43 M_SEGMENT */ \
+ "LFS node", /* 44 M_LFSNODE */ \
+ "FFS node", /* 45 M_FFSNODE */ \
+ "MFS node", /* 46 M_MFSNODE */ \
+ "NQNFS Lease", /* 47 M_NQLEASE */ \
+ "NQNFS Host", /* 48 M_NQMHOST */ \
+ "Export Host", /* 49 M_NETADDR */ \
+ "NFS srvsock", /* 50 M_NFSSVC */ \
+ "NFS uid", /* 51 M_NFSUID */ \
+ "NFS daemon", /* 52 M_NFSD */ \
+ "ip_moptions", /* 53 M_IPMOPTS */ \
+ "in_multi", /* 54 M_IPMADDR */ \
+ "ether_multi", /* 55 M_IFMADDR */ \
+ "mrt", /* 56 M_MRTABLE */ \
+ "ISOFS mount", /* 57 M_ISOFSMNT */ \
+ "ISOFS node", /* 58 M_ISOFSNODE */ \
+ "NFSV3 srvdesc",/* 59 M_NFSRVDESC */ \
+ "NFSV3 diroff", /* 60 M_NFSDIROFF */ \
+ "NFSV3 bigfh", /* 61 M_NFSBIGFH */ \
+ NULL, \
+ NULL, NULL, NULL, NULL, \
+ "MSDOSFS mount",/* 67 M_MSDOSFSMNT */ \
+ "MSDOSFS node", /* 68 M_MSDOSFSNODE */ \
+ "MSDOSFS FAT", /* 69 M_MSDOSFSFAR */ \
+ "DEVFS mount", /* 70 M_DEVFSMNT */ \
+ "DEVFS back", /* 71 M_DEVFSBACK */ \
+ "DEVFS front", /* 72 M_DEVFSFRONT */ \
+ "DEVFS node", /* 73 M_DEVFSNODE */ \
+ "temp", /* 74 M_TEMP */ \
+ "ttys", /* 75 M_TTYS */ \
+ "Gzip trees", /* 76 M_GZIP */ \
+ "IpFw/IpAcct", /* 77 M_IPFW */ \
+ "isa_devlist", /* 78 M_DEVL */ \
+ "PktClass", /* 79 M_PKTCLASS */ \
+ "sysctl", /* 80 M_SYSCTL */ \
+ "key mgmt", /* 81 M_SECA */ \
+ "BIO buffer", /* 82 M_BIOBUF */ \
+ "KTRACE", /* 83 M_KTRACE */ \
+ "select", /* 84 M_SELECT */ \
+ "Coda", /* 85 M_CFS */ \
+}
+
+struct kmemstats {
+ long ks_inuse; /* # of packets of this type currently in use */
+ long ks_calls; /* total packets of this type ever allocated */
+ long ks_memuse; /* total memory held in bytes */
+ u_short ks_limblocks; /* number of times blocked for hitting limit */
+ u_short ks_mapblocks; /* number of times blocked for kernel map */
+ long ks_maxused; /* maximum number ever used */
+ long ks_limit; /* most that are allowed to exist */
+ long ks_size; /* sizes of this thing that are allocated */
+ long ks_spare;
+};
+
+/*
+ * Array of descriptors that describe the contents of each page
+ */
+struct kmemusage {
+ short ku_indx; /* bucket index */
+ union {
+ u_short freecnt;/* for small allocations, free pieces in page */
+ u_short pagecnt;/* for large allocations, pages alloced */
+ } ku_un;
+};
+#define ku_freecnt ku_un.freecnt
+#define ku_pagecnt ku_un.pagecnt
+
+/*
+ * Set of buckets for each size of memory block that is retained
+ */
+struct kmembuckets {
+ caddr_t kb_next; /* list of free blocks */
+ caddr_t kb_last; /* last free block */
+ long kb_calls; /* total calls to allocate this size */
+ long kb_total; /* total number of blocks allocated */
+ long kb_totalfree; /* # of free elements in this bucket */
+ long kb_elmpercl; /* # of elements in this sized allocation */
+ long kb_highwat; /* high water mark */
+ long kb_couldfree; /* over high water mark and could free */
+};
+
+#ifdef _KERNEL
+#define MINALLOCSIZE (1 << MINBUCKET)
+#define BUCKETINDX(size) \
+ ((size) <= (MINALLOCSIZE * 128) \
+ ? (size) <= (MINALLOCSIZE * 8) \
+ ? (size) <= (MINALLOCSIZE * 2) \
+ ? (size) <= (MINALLOCSIZE * 1) \
+ ? (MINBUCKET + 0) \
+ : (MINBUCKET + 1) \
+ : (size) <= (MINALLOCSIZE * 4) \
+ ? (MINBUCKET + 2) \
+ : (MINBUCKET + 3) \
+ : (size) <= (MINALLOCSIZE* 32) \
+ ? (size) <= (MINALLOCSIZE * 16) \
+ ? (MINBUCKET + 4) \
+ : (MINBUCKET + 5) \
+ : (size) <= (MINALLOCSIZE * 64) \
+ ? (MINBUCKET + 6) \
+ : (MINBUCKET + 7) \
+ : (size) <= (MINALLOCSIZE * 2048) \
+ ? (size) <= (MINALLOCSIZE * 512) \
+ ? (size) <= (MINALLOCSIZE * 256) \
+ ? (MINBUCKET + 8) \
+ : (MINBUCKET + 9) \
+ : (size) <= (MINALLOCSIZE * 1024) \
+ ? (MINBUCKET + 10) \
+ : (MINBUCKET + 11) \
+ : (size) <= (MINALLOCSIZE * 8192) \
+ ? (size) <= (MINALLOCSIZE * 4096) \
+ ? (MINBUCKET + 12) \
+ : (MINBUCKET + 13) \
+ : (size) <= (MINALLOCSIZE * 16384) \
+ ? (MINBUCKET + 14) \
+ : (MINBUCKET + 15))
+
+/*
+ * Turn virtual addresses into kmem map indices
+ */
+#define kmemxtob(alloc) (kmembase + (alloc) * PAGE_SIZE)
+#define btokmemx(addr) (((caddr_t)(addr) - kmembase) / PAGE_SIZE)
+#define btokup(addr) (&kmemusage[(caddr_t)(addr) - kmembase >> PAGE_SHIFT])
+
+/*
+ * Macro versions for the usual cases of malloc/free
+ */
+#if defined(KMEMSTATS) || defined(DIAGNOSTIC)
+#define MALLOC(space, cast, size, type, flags) \
+ (space) = (cast)malloc((u_long)(size), type, flags)
+#define FREE(addr, type) free((addr), type)
+
+#else /* do not collect statistics */
+#define MALLOC(space, cast, size, type, flags) { \
+ register struct kmembuckets *kbp = &bucket[BUCKETINDX(size)]; \
+ long s = splimp(); \
+ if (kbp->kb_next == NULL) { \
+ (space) = (cast)malloc((u_long)(size), type, flags); \
+ } else { \
+ (space) = (cast)kbp->kb_next; \
+ kbp->kb_next = *(caddr_t *)(space); \
+ } \
+ splx(s); \
+}
+
+#define FREE(addr, type) { \
+ register struct kmembuckets *kbp; \
+ register struct kmemusage *kup = btokup(addr); \
+ long s = splimp(); \
+ if (1 << kup->ku_indx > MAXALLOCSAVE) { \
+ free((addr), type); \
+ } else { \
+ kbp = &bucket[kup->ku_indx]; \
+ if (kbp->kb_next == NULL) \
+ kbp->kb_next = (caddr_t)(addr); \
+ else \
+ *(caddr_t *)(kbp->kb_last) = (caddr_t)(addr); \
+ *(caddr_t *)(addr) = NULL; \
+ kbp->kb_last = (caddr_t)(addr); \
+ } \
+ splx(s); \
+}
+#endif /* do not collect statistics */
+
+extern struct kmemstats kmemstats[];
+extern struct kmemusage *kmemusage;
+extern char *kmembase;
+extern struct kmembuckets bucket[];
+
+void *contigmalloc __P((unsigned long size, int type, int flags,
+ unsigned long low, unsigned long high,
+ unsigned long alignment, unsigned long boundary));
+void free __P((void *addr, int type));
+void *malloc __P((unsigned long size, int type, int flags));
+#endif /* _KERNEL */
+
+#endif /* !_SYS_MALLOC_H_ */
diff --git a/cpukit/libnetworking/sys/mbuf.h b/cpukit/libnetworking/sys/mbuf.h
new file mode 100644
index 0000000000..e88aed3628
--- /dev/null
+++ b/cpukit/libnetworking/sys/mbuf.h
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 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. 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.
+ *
+ * @(#)mbuf.h 8.5 (Berkeley) 2/19/95
+ * $FreeBSD: src/sys/sys/mbuf.h,v 1.169 2005/03/17 19:34:57 jmg Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _SYS_MBUF_H_
+#define _SYS_MBUF_H_
+
+#ifndef M_WAITOK
+#include <sys/malloc.h>
+#endif
+
+/*
+ * Mbufs are of a single size, MSIZE (machine/machparam.h), which
+ * includes overhead. An mbuf may add a single "mbuf cluster" of size
+ * MCLBYTES (also in machine/machparam.h), which has no additional overhead
+ * and is used instead of the internal data area; this is done when
+ * at least MINCLSIZE of data must be stored.
+ */
+
+#define MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */
+#define MHLEN (MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */
+#define MINCLSIZE (MHLEN + MLEN) /* smallest amount to put in cluster */
+#define M_MAXCOMPRESS (MHLEN / 2) /* max amount to copy for compression */
+
+/*-
+ * Macros for type conversion:
+ * mtod(m, t) -- Convert mbuf pointer to data pointer of correct type.
+ * dtom(x) -- Convert data pointer within mbuf to mbuf pointer (XXX).
+ * mtocl(x) -- Convert pointer within cluster to cluster index #
+ * cltom(x) -- Convert cluster # to ptr to beginning of cluster
+ */
+#define mtod(m, t) ((t)((m)->m_data))
+#define dtom(x) ((struct mbuf *)((intptr_t)(x) & ~(MSIZE-1)))
+#define mtocl(x) (((u_long)(x) - (u_long)mbutl) >> MCLSHIFT)
+#define cltom(x) ((caddr_t)((u_long)mbutl + ((u_long)(x) << MCLSHIFT)))
+
+/*
+ * Header present at the beginning of every mbuf.
+ */
+struct m_hdr {
+ struct mbuf *mh_next; /* next buffer in chain */
+ struct mbuf *mh_nextpkt; /* next chain in queue/record */
+ caddr_t mh_data; /* location of data */
+ int mh_len; /* amount of data in this mbuf */
+ int mh_flags; /* flags; see below */
+ short mh_type; /* type of data in this mbuf */
+};
+
+/*
+ * Record/packet header in first mbuf of chain; valid only if M_PKTHDR is set.
+ */
+struct pkthdr {
+ struct ifnet *rcvif; /* rcv interface */
+ int len; /* total packet length */
+};
+
+/*
+ * Description of external storage mapped into mbuf; valid only if M_EXT is set.
+ */
+struct m_ext {
+ caddr_t ext_buf; /* start of buffer */
+ void (*ext_free) /* free routine if not the usual */
+ __P((caddr_t, u_int));
+ u_int ext_size; /* size of buffer, for ext_free */
+ void (*ext_ref) /* add a reference to the ext object */
+ __P((caddr_t, u_int));
+};
+
+/*
+ * The core of the mbuf object along with some shortcut defines for
+ * practical purposes.
+ */
+struct mbuf {
+ struct m_hdr m_hdr;
+ union {
+ struct {
+ struct pkthdr MH_pkthdr; /* M_PKTHDR set */
+ union {
+ struct m_ext MH_ext; /* M_EXT set */
+ char MH_databuf[MHLEN];
+ } MH_dat;
+ } MH;
+ char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */
+ } M_dat;
+};
+#define m_next m_hdr.mh_next
+#define m_len m_hdr.mh_len
+#define m_data m_hdr.mh_data
+#define m_type m_hdr.mh_type
+#define m_flags m_hdr.mh_flags
+#define m_nextpkt m_hdr.mh_nextpkt
+#define m_act m_nextpkt
+#define m_pkthdr M_dat.MH.MH_pkthdr
+#define m_ext M_dat.MH.MH_dat.MH_ext
+#define m_pktdat M_dat.MH.MH_dat.MH_databuf
+#define m_dat M_dat.M_databuf
+
+/*
+ * mbuf flags.
+ */
+#define M_EXT 0x0001 /* has associated external storage */
+#define M_PKTHDR 0x0002 /* start of record */
+#define M_EOR 0x0004 /* end of record */
+#define M_PROTO1 0x0008 /* protocol-specific */
+
+/*
+ * mbuf pkthdr flags (also stored in m_flags).
+ */
+#define M_BCAST 0x0100 /* send/received as link-level broadcast */
+#define M_MCAST 0x0200 /* send/received as link-level multicast */
+
+/*
+ * Flags copied when copying m_pkthdr.
+ */
+#define M_COPYFLAGS (M_PKTHDR|M_EOR|M_PROTO1|M_BCAST|M_MCAST)
+
+/*
+ * mbuf types.
+ */
+#define MT_FREE 0 /* should be on free list */
+#define MT_DATA 1 /* dynamic (data) allocation */
+#define MT_HEADER 2 /* packet header */
+#define MT_SOCKET 3 /* socket structure */
+#define MT_PCB 4 /* protocol control block */
+#define MT_RTABLE 5 /* routing tables */
+#define MT_HTABLE 6 /* IMP host tables */
+#define MT_ATABLE 7 /* address resolution tables */
+#define MT_SONAME 8 /* socket name */
+#define MT_SOOPTS 10 /* socket options */
+#define MT_FTABLE 11 /* fragment reassembly header */
+#define MT_RIGHTS 12 /* access rights */
+#define MT_IFADDR 13 /* interface address */
+#define MT_CONTROL 14 /* extra-data protocol message */
+#define MT_OOBDATA 15 /* expedited data */
+
+/*
+ * General mbuf allocator statistics structure.
+ */
+struct mbstat {
+ u_long m_mbufs; /* mbufs obtained from page pool */
+ u_long m_clusters; /* clusters obtained from page pool */
+ u_long m_spare; /* spare field */
+ u_long m_clfree; /* free clusters */
+ u_long m_drops; /* times failed to find space */
+ u_long m_wait; /* times waited for space */
+ u_long m_drain; /* times drained protocols for space */
+ u_short m_mtypes[256]; /* type specific mbuf allocations */
+};
+
+
+/* flags to m_get/MGET */
+#define M_DONTWAIT M_NOWAIT
+#define M_WAIT M_WAITOK
+
+/* Freelists:
+ *
+ * Normal mbuf clusters are normally treated as character arrays
+ * after allocation, but use the first word of the buffer as a free list
+ * pointer while on the free list.
+ */
+union mcluster {
+ union mcluster *mcl_next;
+ char mcl_buf[MCLBYTES];
+};
+
+/*
+ * mbuf utility macros:
+ *
+ * MBUFLOCK(code)
+ * prevents a section of code from from being interrupted by network
+ * drivers.
+ */
+#define MBUFLOCK(code) \
+ { int ms = splimp(); \
+ { code } \
+ splx(ms); \
+ }
+
+/*
+ * mbuf allocation/deallocation macros:
+ *
+ * MGET(struct mbuf *m, int how, int type)
+ * allocates an mbuf and initializes it to contain internal data.
+ *
+ * MGETHDR(struct mbuf *m, int how, int type)
+ * allocates an mbuf and initializes it to contain a packet header
+ * and internal data.
+ */
+#define MGET(m, how, type) { \
+ int _ms = splimp(); \
+ if (mmbfree == 0) \
+ (void)m_mballoc(1, (how)); \
+ if (((m) = mmbfree) != 0) { \
+ mmbfree = (m)->m_next; \
+ mbstat.m_mtypes[MT_FREE]--; \
+ (m)->m_type = (type); \
+ mbstat.m_mtypes[type]++; \
+ (m)->m_next = (struct mbuf *)NULL; \
+ (m)->m_nextpkt = (struct mbuf *)NULL; \
+ (m)->m_data = (m)->m_dat; \
+ (m)->m_flags = 0; \
+ splx(_ms); \
+ } else { \
+ splx(_ms); \
+ (m) = m_retry((how), (type)); \
+ } \
+}
+
+#define MGETHDR(m, how, type) { \
+ int _ms = splimp(); \
+ if (mmbfree == 0) \
+ (void)m_mballoc(1, (how)); \
+ if (((m) = mmbfree) != 0) { \
+ mmbfree = (m)->m_next; \
+ mbstat.m_mtypes[MT_FREE]--; \
+ (m)->m_type = (type); \
+ mbstat.m_mtypes[type]++; \
+ (m)->m_next = (struct mbuf *)NULL; \
+ (m)->m_nextpkt = (struct mbuf *)NULL; \
+ (m)->m_data = (m)->m_pktdat; \
+ (m)->m_flags = M_PKTHDR; \
+ splx(_ms); \
+ } else { \
+ splx(_ms); \
+ (m) = m_retryhdr((how), (type)); \
+ } \
+}
+
+/*
+ * Mbuf cluster macros.
+ * MCLALLOC(caddr_t p, int how) allocates an mbuf cluster.
+ * MCLGET adds such clusters to a normal mbuf;
+ * the flag M_EXT is set upon success.
+ * MCLFREE releases a reference to a cluster allocated by MCLALLOC,
+ * freeing the cluster if the reference count has reached 0.
+ */
+#define MCLALLOC(p, how) \
+ MBUFLOCK( \
+ if (mclfree == 0) \
+ (void)m_clalloc(1, (how)); \
+ if (((p) = (caddr_t)mclfree) != 0) { \
+ ++mclrefcnt[mtocl(p)]; \
+ mbstat.m_clfree--; \
+ mclfree = ((union mcluster *)(p))->mcl_next; \
+ } \
+ )
+
+#define MCLGET(m, how) \
+ { MCLALLOC((m)->m_ext.ext_buf, (how)); \
+ if ((m)->m_ext.ext_buf != NULL) { \
+ (m)->m_data = (m)->m_ext.ext_buf; \
+ (m)->m_flags |= M_EXT; \
+ (m)->m_ext.ext_free = NULL; \
+ (m)->m_ext.ext_ref = NULL; \
+ (m)->m_ext.ext_size = MCLBYTES; \
+ } \
+ }
+
+#define MCLFREE(p) \
+ MBUFLOCK ( \
+ if (--mclrefcnt[mtocl(p)] == 0) { \
+ ((union mcluster *)(p))->mcl_next = mclfree; \
+ mclfree = (union mcluster *)(p); \
+ mbstat.m_clfree++; \
+ } \
+ )
+
+/*
+ * MFREE(struct mbuf *m, struct mbuf *n)
+ * Free a single mbuf and associated external storage.
+ * Place the successor, if any, in n.
+ */
+#define MFREE(m, n) \
+ MBUFLOCK( \
+ mbstat.m_mtypes[(m)->m_type]--; \
+ if ((m)->m_flags & M_EXT) { \
+ if ((m)->m_ext.ext_free) \
+ (*((m)->m_ext.ext_free))((m)->m_ext.ext_buf, \
+ (m)->m_ext.ext_size); \
+ else { \
+ char *p = (m)->m_ext.ext_buf; \
+ if (--mclrefcnt[mtocl(p)] == 0) { \
+ ((union mcluster *)(p))->mcl_next = mclfree; \
+ mclfree = (union mcluster *)(p); \
+ mbstat.m_clfree++; \
+ } \
+ } \
+ } \
+ (n) = (m)->m_next; \
+ (m)->m_type = MT_FREE; \
+ mbstat.m_mtypes[MT_FREE]++; \
+ (m)->m_next = mmbfree; \
+ mmbfree = (m); \
+ )
+
+/*
+ * Copy mbuf pkthdr from from to to.
+ * from must have M_PKTHDR set, and to must be empty.
+ */
+#define M_COPY_PKTHDR(to, from) { \
+ (to)->m_pkthdr = (from)->m_pkthdr; \
+ (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
+ (to)->m_data = (to)->m_pktdat; \
+}
+
+/*
+ * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
+ * an object of the specified size at the end of the mbuf, longword aligned.
+ */
+#define M_ALIGN(m, len) do { \
+ (m)->m_data += (MLEN - (len)) & ~(sizeof(long) - 1); \
+} while (0)
+
+/*
+ * As above, for mbufs allocated with m_gethdr/MGETHDR
+ * or initialized by M_COPY_PKTHDR.
+ */
+#define MH_ALIGN(m, len) do { \
+ (m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1); \
+} while (0)
+
+/*
+ * Compute the amount of space available
+ * before the current start of data in an mbuf.
+ */
+#define M_LEADINGSPACE(m) \
+ ((m)->m_flags & M_EXT ? /* (m)->m_data - (m)->m_ext.ext_buf */ 0 : \
+ (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
+ (m)->m_data - (m)->m_dat)
+
+/*
+ * Compute the amount of space available
+ * after the end of data in an mbuf.
+ */
+#define M_TRAILINGSPACE(m) \
+ ((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size - \
+ ((m)->m_data + (m)->m_len) : \
+ &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
+
+/*
+ * Arrange to prepend space of size plen to mbuf m.
+ * If a new mbuf must be allocated, how specifies whether to wait.
+ * If how is M_DONTWAIT and allocation fails, the original mbuf chain
+ * is freed and m is set to NULL.
+ */
+#define M_PREPEND(m, plen, how) { \
+ if (M_LEADINGSPACE(m) >= (plen)) { \
+ (m)->m_data -= (plen); \
+ (m)->m_len += (plen); \
+ } else \
+ (m) = m_prepend((m), (plen), (how)); \
+ if ((m) && (m)->m_flags & M_PKTHDR) \
+ (m)->m_pkthdr.len += (plen); \
+}
+
+/*
+ * Change mbuf to new type.
+ * This is a relatively expensive operation and should be avoided.
+ */
+#define MCHTYPE(m, t) { \
+ MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;) \
+ (m)->m_type = t;\
+}
+
+/* Length to m_copy to copy all. */
+#define M_COPYALL 1000000000
+
+/* Compatibility with 4.3. */
+#define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT)
+
+#ifdef _KERNEL
+extern struct mbuf *mbutl; /* virtual address of mclusters */
+extern char *mclrefcnt; /* cluster reference counts */
+extern struct mbstat mbstat;
+extern int nmbclusters;
+extern int nmbufs;
+extern struct mbuf *mmbfree;
+extern union mcluster *mclfree;
+extern int max_linkhdr; /* largest link-level header */
+extern int max_protohdr; /* largest protocol header */
+extern int max_hdr; /* largest link+protocol header */
+extern int max_datalen; /* MHLEN - max_hdr */
+
+struct mbuf *m_copym(struct mbuf *, int, int, int);
+struct mbuf *m_copypacket(struct mbuf *, int);
+struct mbuf *m_devget(char *, int, int, struct ifnet *,
+ void (*copy)(char *, caddr_t, u_int));
+struct mbuf *m_free(struct mbuf *);
+struct mbuf *m_get(int, int);
+struct mbuf *m_getclr(int, int);
+struct mbuf *m_gethdr(int, int);
+struct mbuf *m_prepend(struct mbuf *,int,int);
+struct mbuf *m_pullup(struct mbuf *, int);
+struct mbuf *m_retry(int, int);
+struct mbuf *m_retryhdr(int, int);
+struct mbuf *m_split(struct mbuf *,int,int);
+void m_adj(struct mbuf *, int);
+void m_cat(struct mbuf *,struct mbuf *);
+int m_mballoc(int, int);
+int m_clalloc(int, int);
+int m_copyback(struct mbuf *, int, int, caddr_t);
+int m_copydata(const struct mbuf *, int, int, caddr_t);
+void m_freem(struct mbuf *);
+void m_reclaim(void);
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_MBUF_H_ */
diff --git a/cpukit/libnetworking/sys/mount.h b/cpukit/libnetworking/sys/mount.h
new file mode 100644
index 0000000000..c055677258
--- /dev/null
+++ b/cpukit/libnetworking/sys/mount.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1989, 1991, 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.
+ * 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.
+ *
+ * @(#)mount.h 8.21 (Berkeley) 5/20/95
+ * $FreeBSD: src/sys/sys/mount.h,v 1.198 2005/08/06 01:42:04 ssouhlal Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _SYS_MOUNT_H_
+#define _SYS_MOUNT_H_
+
+#ifndef _KERNEL
+#include <sys/ucred.h>
+#endif
+#include <sys/queue.h>
+
+typedef struct fsid { int32_t val[2]; } fsid_t; /* filesystem id type */
+
+/*
+ * File identifier.
+ * These are unique per filesystem on a single machine.
+ */
+#define MAXFIDSZ 16
+
+struct fid {
+ u_short fid_len; /* length of data in bytes */
+ u_short fid_reserved; /* force longword alignment */
+ char fid_data[MAXFIDSZ]; /* data (variable length) */
+};
+
+/*
+ * filesystem statistics
+ */
+#define MFSNAMELEN 16 /* length of type name including null */
+#define MNAMELEN 88 /* size of on/from name bufs */
+
+/*
+ * User specifiable flags.
+ */
+#define MNT_RDONLY 0x00000001 /* read only filesystem */
+#define MNT_SYNCHRONOUS 0x00000002 /* filesystem written synchronously */
+#define MNT_NOEXEC 0x00000004 /* can't exec from filesystem */
+#define MNT_NOSUID 0x00000008 /* don't honor setuid bits on fs */
+#define MNT_NODEV 0x00000010 /* don't interpret special files */
+#define MNT_UNION 0x00000020 /* union with underlying filesystem */
+#define MNT_ASYNC 0x00000040 /* filesystem written asynchronously */
+#define MNT_NOATIME 0x10000000 /* disable update of file access time */
+
+/*
+ * NFS export related mount flags.
+ */
+#define MNT_EXRDONLY 0x00000080 /* exported read only */
+#define MNT_EXPORTED 0x00000100 /* filesystem is exported */
+#define MNT_DEFEXPORTED 0x00000200 /* exported to the world */
+#define MNT_EXPORTANON 0x00000400 /* use anon uid mapping for everyone */
+#define MNT_EXKERB 0x00000800 /* exported with Kerberos uid mapping */
+#define MNT_EXPUBLIC 0x20000000 /* public export (WebNFS) */
+
+/*
+ * Flags set by internal operations,
+ * but visible to the user.
+ */
+#define MNT_LOCAL 0x00001000 /* filesystem is stored locally */
+#define MNT_QUOTA 0x00002000 /* quotas are enabled on filesystem */
+#define MNT_ROOTFS 0x00004000 /* identifies the root filesystem */
+#define MNT_USER 0x00008000 /* mounted by a user */
+#define MNT_IGNORE 0x00800000 /* do not show entry in df */
+
+/*
+ * External filesystem command modifier flags.
+ * Unmount can use the MNT_FORCE flag.
+ */
+#define MNT_UPDATE 0x00010000 /* not a real mount, just an update */
+#define MNT_DELEXPORT 0x00020000 /* delete export host lists */
+#define MNT_RELOAD 0x00040000 /* reload filesystem data */
+#define MNT_FORCE 0x00080000 /* force unmount or readonly change */
+
+/*
+ * Generic file handle
+ */
+struct fhandle {
+ fsid_t fh_fsid; /* Filesystem id of mount point */
+ struct fid fh_fid; /* Filesys specific id */
+};
+typedef struct fhandle fhandle_t;
+
+#ifdef _KERNEL
+
+#else /* !_KERNEL */
+
+#include <sys/cdefs.h>
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_MOUNT_H_ */
diff --git a/cpukit/libnetworking/sys/poll.h b/cpukit/libnetworking/sys/poll.h
new file mode 100644
index 0000000000..9ea42b9ddf
--- /dev/null
+++ b/cpukit/libnetworking/sys/poll.h
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 1997 Peter Wemm <peter@freebsd.org>
+ * 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. 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 BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/sys/sys/poll.h,v 1.13 2002/07/10 04:47:25 mike Exp $
+ */
+
+#ifndef _SYS_POLL_H_
+#define _SYS_POLL_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * This file is intended to be compatible with the traditional poll.h.
+ */
+
+typedef unsigned int nfds_t;
+
+/*
+ * This structure is passed as an array to poll(2).
+ */
+struct pollfd {
+ int fd; /* which file descriptor to poll */
+ short events; /* events we are interested in */
+ short revents; /* events found on return */
+};
+
+/*
+ * Requestable events. If poll(2) finds any of these set, they are
+ * copied to revents on return.
+ * XXX Note that FreeBSD doesn't make much distinction between POLLPRI
+ * and POLLRDBAND since none of the file types have distinct priority
+ * bands - and only some have an urgent "mode".
+ * XXX Note POLLIN isn't really supported in true SVSV terms. Under SYSV
+ * POLLIN includes all of normal, band and urgent data. Most poll handlers
+ * on FreeBSD only treat it as "normal" data.
+ */
+#define POLLIN 0x0001 /* any readable data available */
+#define POLLPRI 0x0002 /* OOB/Urgent readable data */
+#define POLLOUT 0x0004 /* file descriptor is writeable */
+#define POLLRDNORM 0x0040 /* non-OOB/URG data available */
+#define POLLWRNORM POLLOUT /* no write type differentiation */
+#define POLLRDBAND 0x0080 /* OOB/Urgent readable data */
+#define POLLWRBAND 0x0100 /* OOB/Urgent data can be written */
+
+#if __BSD_VISIBLE
+/* General FreeBSD extension (currently only supported for sockets): */
+#define POLLINIGNEOF 0x2000 /* like POLLIN, except ignore EOF */
+#endif
+
+/*
+ * These events are set if they occur regardless of whether they were
+ * requested.
+ */
+#define POLLERR 0x0008 /* some poll error occurred */
+#define POLLHUP 0x0010 /* file descriptor was "hung up" */
+#define POLLNVAL 0x0020 /* requested events "invalid" */
+
+#if __BSD_VISIBLE
+
+#define POLLSTANDARD (POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLRDBAND|\
+ POLLWRBAND|POLLERR|POLLHUP|POLLNVAL)
+
+/*
+ * Request that poll() wait forever.
+ * XXX in SYSV, this is defined in stropts.h, which is not included
+ * by poll.h.
+ */
+#define INFTIM (-1)
+
+#endif
+
+#ifndef _KERNEL
+
+__BEGIN_DECLS
+int poll(struct pollfd _pfd[], nfds_t _nfds, int _timeout);
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif /* !_SYS_POLL_H_ */
diff --git a/cpukit/libnetworking/sys/proc.h b/cpukit/libnetworking/sys/proc.h
new file mode 100644
index 0000000000..2189a33b11
--- /dev/null
+++ b/cpukit/libnetworking/sys/proc.h
@@ -0,0 +1,8 @@
+/*
+ * Dummy structure
+ *
+ * $Id$
+ */
+struct proc {
+ int this_should_never_be_referenced;
+};
diff --git a/cpukit/libnetworking/sys/protosw.h b/cpukit/libnetworking/sys/protosw.h
new file mode 100644
index 0000000000..13bbc26cee
--- /dev/null
+++ b/cpukit/libnetworking/sys/protosw.h
@@ -0,0 +1,300 @@
+/*-
+ * Copyright (c) 1982, 1986, 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.
+ * 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.
+ *
+ * @(#)protosw.h 8.1 (Berkeley) 6/2/93
+ * $FreeBSD: src/sys/sys/protosw.h,v 1.43 2004/04/07 04:19:49 imp Exp $
+ */
+
+#ifndef _SYS_PROTOSW_H_
+#define _SYS_PROTOSW_H_
+
+/* Forward declare these structures referenced from prototypes below. */
+struct mbuf;
+struct sockaddr;
+struct socket;
+struct sockproto;
+struct stat;
+
+/*
+ * Protocol switch table.
+ *
+ * Each protocol has a handle initializing one of these structures,
+ * which is used for protocol-protocol and system-protocol communication.
+ *
+ * A protocol is called through the pr_init entry before any other.
+ * Thereafter it is called every 200ms through the pr_fasttimo entry and
+ * every 500ms through the pr_slowtimo for timer based actions.
+ * The system will call the pr_drain entry if it is low on space and
+ * this should throw away any non-critical data.
+ *
+ * Protocols pass data between themselves as chains of mbufs using
+ * the pr_input and pr_output hooks. Pr_input passes data up (towards
+ * UNIX) and pr_output passes it down (towards the imps); control
+ * information passes up and down on pr_ctlinput and pr_ctloutput.
+ * The protocol is responsible for the space occupied by any the
+ * arguments to these entries and must dispose it.
+ *
+ * The userreq routine interfaces protocols to the system and is
+ * described below.
+ */
+struct protosw {
+ short pr_type; /* socket type used for */
+ struct domain *pr_domain; /* domain protocol a member of */
+ short pr_protocol; /* protocol number */
+ short pr_flags; /* see below */
+/* protocol-protocol hooks */
+ void (*pr_input) __P((struct mbuf *, int len));
+ /* input to protocol (from below) */
+ int (*pr_output) __P((struct mbuf *m, struct socket *so));
+ /* output to protocol (from above) */
+ void (*pr_ctlinput)__P((int, struct sockaddr *, void *));
+ /* control input (from below) */
+ int (*pr_ctloutput)__P((int, struct socket *, int, int,
+ struct mbuf **));
+ /* control output (from above) */
+/* user-protocol hook */
+ int (*pr_ousrreq) __P((struct socket *, int, struct mbuf *,
+ struct mbuf *, struct mbuf *));
+ /* user request: see list below */
+/* utility hooks */
+ void (*pr_init) __P((void)); /* initialization hook */
+ void (*pr_fasttimo) __P((void));
+ /* fast timeout (200ms) */
+ void (*pr_slowtimo) __P((void));
+ /* slow timeout (500ms) */
+ void (*pr_drain) __P((void));
+ /* flush any excess space possible */
+ struct pr_usrreqs *pr_usrreqs; /* supersedes pr_usrreq() */
+};
+
+#define PR_SLOWHZ 2 /* 2 slow timeouts per second */
+#define PR_FASTHZ 5 /* 5 fast timeouts per second */
+
+/*
+ * Values for pr_flags.
+ * PR_ADDR requires PR_ATOMIC;
+ * PR_ADDR and PR_CONNREQUIRED are mutually exclusive.
+ * PR_IMPLOPCL means that the protocol allows sendto without prior connect,
+ * and the protocol understands the MSG_EOF flag. The first property is
+ * is only relevant if PR_CONNREQUIRED is set (otherwise sendto is allowed
+ * anyhow).
+ */
+#define PR_ATOMIC 0x01 /* exchange atomic messages only */
+#define PR_ADDR 0x02 /* addresses given with messages */
+#define PR_CONNREQUIRED 0x04 /* connection required by protocol */
+#define PR_WANTRCVD 0x08 /* want PRU_RCVD calls */
+#define PR_RIGHTS 0x10 /* passes capabilities */
+#define PR_IMPLOPCL 0x20 /* implied open/close */
+#define PR_LASTHDR 0x40 /* enforce ipsec policy; last header */
+
+/*
+ * The arguments to usrreq are:
+ * (*protosw[].pr_usrreq)(up, req, m, nam, opt);
+ * where up is a (struct socket *), req is one of these requests,
+ * m is an optional mbuf chain containing a message,
+ * nam is an optional mbuf chain containing an address,
+ * and opt is a pointer to a socketopt structure or nil.
+ * The protocol is responsible for disposal of the mbuf chain m,
+ * the caller is responsible for any space held by nam and opt.
+ * A non-zero return from usrreq gives an
+ * UNIX error number which should be passed to higher level software.
+ */
+#define PRU_ATTACH 0 /* attach protocol to up */
+#define PRU_DETACH 1 /* detach protocol from up */
+#define PRU_BIND 2 /* bind socket to address */
+#define PRU_LISTEN 3 /* listen for connection */
+#define PRU_CONNECT 4 /* establish connection to peer */
+#define PRU_ACCEPT 5 /* accept connection from peer */
+#define PRU_DISCONNECT 6 /* disconnect from peer */
+#define PRU_SHUTDOWN 7 /* won't send any more data */
+#define PRU_RCVD 8 /* have taken data; more room now */
+#define PRU_SEND 9 /* send this data */
+#define PRU_ABORT 10 /* abort (fast DISCONNECT, DETATCH) */
+#define PRU_CONTROL 11 /* control operations on protocol */
+#define PRU_SENSE 12 /* return status into m */
+#define PRU_RCVOOB 13 /* retrieve out of band data */
+#define PRU_SENDOOB 14 /* send out of band data */
+#define PRU_SOCKADDR 15 /* fetch socket's address */
+#define PRU_PEERADDR 16 /* fetch peer's address */
+#define PRU_CONNECT2 17 /* connect two sockets */
+/* begin for protocols internal use */
+#define PRU_FASTTIMO 18 /* 200ms timeout */
+#define PRU_SLOWTIMO 19 /* 500ms timeout */
+#define PRU_PROTORCV 20 /* receive from below */
+#define PRU_PROTOSEND 21 /* send to below */
+/* end for protocol's internal use */
+#define PRU_SEND_EOF 22 /* send and close */
+#define PRU_NREQ 22
+
+#ifdef PRUREQUESTS
+const char *prurequests[] = {
+ "ATTACH", "DETACH", "BIND", "LISTEN",
+ "CONNECT", "ACCEPT", "DISCONNECT", "SHUTDOWN",
+ "RCVD", "SEND", "ABORT", "CONTROL",
+ "SENSE", "RCVOOB", "SENDOOB", "SOCKADDR",
+ "PEERADDR", "CONNECT2", "FASTTIMO", "SLOWTIMO",
+ "PROTORCV", "PROTOSEND",
+ "SEND_EOF",
+};
+#endif
+
+#ifdef _KERNEL /* users shouldn't see this decl */
+struct stat;
+struct ifnet;
+
+/*
+ * If the ordering here looks odd, that's because it's alphabetical.
+ */
+struct pr_usrreqs {
+ int (*pru_abort) __P((struct socket *so));
+ int (*pru_accept) __P((struct socket *so, struct mbuf *nam));
+ int (*pru_attach) __P((struct socket *so, int proto));
+ int (*pru_bind) __P((struct socket *so, struct mbuf *nam));
+ int (*pru_connect) __P((struct socket *so, struct mbuf *nam));
+ int (*pru_connect2) __P((struct socket *so1, struct socket *so2));
+ int (*pru_control) __P((struct socket *so, int cmd, caddr_t data,
+ struct ifnet *ifp));
+ int (*pru_detach) __P((struct socket *so));
+ int (*pru_disconnect) __P((struct socket *so));
+ int (*pru_listen) __P((struct socket *so));
+ int (*pru_peeraddr) __P((struct socket *so, struct mbuf *nam));
+ int (*pru_rcvd) __P((struct socket *so, int flags));
+ int (*pru_rcvoob) __P((struct socket *so, struct mbuf *m,
+ int flags));
+ /*
+ * The `m' parameter here is almost certainly going to become a
+ * `struct uio' at some point in the future. Similar changes
+ * will probably happen for the receive entry points.
+ */
+ int (*pru_send) __P((struct socket *so, int flags, struct mbuf *m,
+ struct mbuf *addr, struct mbuf *control));
+#define PRUS_OOB 0x1
+#define PRUS_EOF 0x2
+ int (*pru_sense) __P((struct socket *so, struct stat *sb));
+ int (*pru_shutdown) __P((struct socket *so));
+ int (*pru_sockaddr) __P((struct socket *so, struct mbuf *nam));
+};
+
+int pru_accept_notsupp(struct socket *so, struct mbuf *nam);
+int pru_connect2_notsupp(struct socket *so1, struct socket *so2);
+int pru_control_notsupp(struct socket *so, int cmd, caddr_t data,
+ struct ifnet *ifp);
+int pru_listen_notsupp(struct socket *so);
+int pru_rcvd_notsupp(struct socket *so, int flags);
+int pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags);
+int pru_sense_null(struct socket *so, struct stat *sb);
+
+#define PRU_OLDSTYLE
+
+#ifdef PRU_OLDSTYLE
+/*
+ * Protocols which don't yet implement pr_usrreqs can point it to this
+ * structure, which will call the old pr_usrreq() entry point with the
+ * appropriate arguments.
+ */
+extern struct pr_usrreqs pru_oldstyle;
+#endif /* PRU_OLDSTYLE */
+
+#endif /* _KERNEL */
+
+/*
+ * The arguments to the ctlinput routine are
+ * (*protosw[].pr_ctlinput)(cmd, sa, arg);
+ * where cmd is one of the commands below, sa is a pointer to a sockaddr,
+ * and arg is a `void *' argument used within a protocol family.
+ */
+#define PRC_IFDOWN 0 /* interface transition */
+#define PRC_ROUTEDEAD 1 /* select new route if possible ??? */
+#define PRC_IFUP 2 /* interface has come back up */
+#define PRC_QUENCH2 3 /* DEC congestion bit says slow down */
+#define PRC_QUENCH 4 /* some one said to slow down */
+#define PRC_MSGSIZE 5 /* message size forced drop */
+#define PRC_HOSTDEAD 6 /* host appears to be down */
+#define PRC_HOSTUNREACH 7 /* deprecated (use PRC_UNREACH_HOST) */
+#define PRC_UNREACH_NET 8 /* no route to network */
+#define PRC_UNREACH_HOST 9 /* no route to host */
+#define PRC_UNREACH_PROTOCOL 10 /* dst says bad protocol */
+#define PRC_UNREACH_PORT 11 /* bad port # */
+/* was PRC_UNREACH_NEEDFRAG 12 (use PRC_MSGSIZE) */
+#define PRC_UNREACH_SRCFAIL 13 /* source route failed */
+#define PRC_REDIRECT_NET 14 /* net routing redirect */
+#define PRC_REDIRECT_HOST 15 /* host routing redirect */
+#define PRC_REDIRECT_TOSNET 16 /* redirect for type of service & net */
+#define PRC_REDIRECT_TOSHOST 17 /* redirect for tos & host */
+#define PRC_TIMXCEED_INTRANS 18 /* packet lifetime expired in transit */
+#define PRC_TIMXCEED_REASS 19 /* lifetime expired on reass q */
+#define PRC_PARAMPROB 20 /* header incorrect */
+#define PRC_UNREACH_ADMIN_PROHIB 21 /* packet administrativly prohibited */
+
+#define PRC_NCMDS 22
+
+#define PRC_IS_REDIRECT(cmd) \
+ ((cmd) >= PRC_REDIRECT_NET && (cmd) <= PRC_REDIRECT_TOSHOST)
+
+#ifdef PRCREQUESTS
+char *prcrequests[] = {
+ "IFDOWN", "ROUTEDEAD", "IFUP", "DEC-BIT-QUENCH2",
+ "QUENCH", "MSGSIZE", "HOSTDEAD", "#7",
+ "NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH",
+ "#12", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT",
+ "TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS",
+ "PARAMPROB", "ADMIN-UNREACH"
+};
+#endif
+
+/*
+ * The arguments to ctloutput are:
+ * (*protosw[].pr_ctloutput)(req, so, level, optname, optval);
+ * req is one of the actions listed below, so is a (struct socket *),
+ * level is an indication of which protocol layer the option is intended.
+ * optname is a protocol dependent socket option request,
+ * optval is a pointer to a mbuf-chain pointer, for value-return results.
+ * The protocol is responsible for disposal of the mbuf chain *optval
+ * if supplied,
+ * the caller is responsible for any space held by *optval, when returned.
+ * A non-zero return from usrreq gives an
+ * UNIX error number which should be passed to higher level software.
+ */
+#define PRCO_GETOPT 0
+#define PRCO_SETOPT 1
+
+#define PRCO_NCMDS 2
+
+#ifdef PRCOREQUESTS
+char *prcorequests[] = {
+ "GETOPT", "SETOPT",
+};
+#endif
+
+#ifdef _KERNEL
+void pfctlinput(int, struct sockaddr *);
+struct protosw *pffindproto(int family, int protocol, int type);
+struct protosw *pffindtype(int family, int type);
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/sys/queue.h b/cpukit/libnetworking/sys/queue.h
new file mode 100644
index 0000000000..7fef7bdf41
--- /dev/null
+++ b/cpukit/libnetworking/sys/queue.h
@@ -0,0 +1,602 @@
+/*
+ * Copyright (c) 1991, 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.
+ * 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.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ * $FreeBSD: src/sys/sys/queue.h,v 1.60 2005/03/02 21:33:29 joerg Exp $
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define _SYS_QUEUE_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * This file defines four types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction. Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ * SLIST LIST STAILQ TAILQ
+ * _HEAD + + + +
+ * _HEAD_INITIALIZER + + + +
+ * _ENTRY + + + +
+ * _INIT + + + +
+ * _EMPTY + + + +
+ * _FIRST + + + +
+ * _NEXT + + + +
+ * _PREV - - - +
+ * _LAST - - + +
+ * _FOREACH + + + +
+ * _FOREACH_REVERSE - - - +
+ * _INSERT_HEAD + + + +
+ * _INSERT_BEFORE - + - +
+ * _INSERT_AFTER + + + +
+ * _INSERT_TAIL - - + +
+ * _CONCAT - - + +
+ * _REMOVE_HEAD + - + -
+ * _REMOVE + + + +
+ *
+ */
+#define QUEUE_MACRO_DEBUG 0
+#if QUEUE_MACRO_DEBUG
+/* Store the last 2 places the queue element or head was altered */
+struct qm_trace {
+ char * lastfile;
+ int lastline;
+ char * prevfile;
+ int prevline;
+};
+
+#define TRACEBUF struct qm_trace trace;
+#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
+
+#define QMD_TRACE_HEAD(head) do { \
+ (head)->trace.prevline = (head)->trace.lastline; \
+ (head)->trace.prevfile = (head)->trace.lastfile; \
+ (head)->trace.lastline = __LINE__; \
+ (head)->trace.lastfile = __FILE__; \
+} while (0)
+
+#define QMD_TRACE_ELEM(elem) do { \
+ (elem)->trace.prevline = (elem)->trace.lastline; \
+ (elem)->trace.prevfile = (elem)->trace.lastfile; \
+ (elem)->trace.lastline = __LINE__; \
+ (elem)->trace.lastfile = __FILE__; \
+} while (0)
+
+#else
+#define QMD_TRACE_ELEM(elem)
+#define QMD_TRACE_HEAD(head)
+#define TRACEBUF
+#define TRASHIT(x)
+#endif /* QUEUE_MACRO_DEBUG */
+
+/*
+ * Singly-linked List declarations.
+ */
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
+
+#define SLIST_FIRST(head) ((head)->slh_first)
+
+#define SLIST_FOREACH(var, head, field) \
+ for ((var) = SLIST_FIRST((head)); \
+ (var); \
+ (var) = SLIST_NEXT((var), field))
+
+#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
+ for ((varp) = &SLIST_FIRST((head)); \
+ ((var) = *(varp)) != NULL; \
+ (varp) = &SLIST_NEXT((var), field))
+
+#define SLIST_INIT(head) do { \
+ SLIST_FIRST((head)) = NULL; \
+} while (0)
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
+ SLIST_NEXT((slistelm), field) = (elm); \
+} while (0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
+ SLIST_FIRST((head)) = (elm); \
+} while (0)
+
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#define SLIST_REMOVE(head, elm, type, field) do { \
+ if (SLIST_FIRST((head)) == (elm)) { \
+ SLIST_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = SLIST_FIRST((head)); \
+ while (SLIST_NEXT(curelm, field) != (elm)) \
+ curelm = SLIST_NEXT(curelm, field); \
+ SLIST_NEXT(curelm, field) = \
+ SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
+ } \
+} while (0)
+
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define STAILQ_HEAD(name, type) \
+struct name { \
+ struct type *stqh_first;/* first element */ \
+ struct type **stqh_last;/* addr of last next element */ \
+}
+
+#define STAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).stqh_first }
+
+#define STAILQ_ENTRY(type) \
+struct { \
+ struct type *stqe_next; /* next element */ \
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define STAILQ_CONCAT(head1, head2) do { \
+ if (!STAILQ_EMPTY((head2))) { \
+ *(head1)->stqh_last = (head2)->stqh_first; \
+ (head1)->stqh_last = (head2)->stqh_last; \
+ STAILQ_INIT((head2)); \
+ } \
+} while (0)
+
+#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
+
+#define STAILQ_FIRST(head) ((head)->stqh_first)
+
+#define STAILQ_FOREACH(var, head, field) \
+ for((var) = STAILQ_FIRST((head)); \
+ (var); \
+ (var) = STAILQ_NEXT((var), field))
+
+#define STAILQ_INIT(head) do { \
+ STAILQ_FIRST((head)) = NULL; \
+ (head)->stqh_last = &STAILQ_FIRST((head)); \
+} while (0)
+
+#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
+ if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
+ STAILQ_NEXT((tqelm), field) = (elm); \
+} while (0)
+
+#define STAILQ_INSERT_HEAD(head, elm, field) do { \
+ if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
+ STAILQ_FIRST((head)) = (elm); \
+} while (0)
+
+#define STAILQ_INSERT_TAIL(head, elm, field) do { \
+ STAILQ_NEXT((elm), field) = NULL; \
+ *(head)->stqh_last = (elm); \
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
+} while (0)
+
+#define STAILQ_LAST(head, type, field) \
+ (STAILQ_EMPTY((head)) ? \
+ NULL : \
+ ((struct type *) \
+ ((char *)((head)->stqh_last) - __offsetof(struct type, field))))
+
+#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
+
+#define STAILQ_REMOVE(head, elm, type, field) do { \
+ if (STAILQ_FIRST((head)) == (elm)) { \
+ STAILQ_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = STAILQ_FIRST((head)); \
+ while (STAILQ_NEXT(curelm, field) != (elm)) \
+ curelm = STAILQ_NEXT(curelm, field); \
+ if ((STAILQ_NEXT(curelm, field) = \
+ STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
+ (head)->stqh_last = &STAILQ_NEXT((curelm), field);\
+ } \
+} while (0)
+
+#define STAILQ_REMOVE_HEAD(head, field) do { \
+ if ((STAILQ_FIRST((head)) = \
+ STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
+ (head)->stqh_last = &STAILQ_FIRST((head)); \
+} while (0)
+
+#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
+ if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
+ (head)->stqh_last = &STAILQ_FIRST((head)); \
+} while (0)
+
+/*
+ * List declarations.
+ */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List functions.
+ */
+
+#define LIST_EMPTY(head) ((head)->lh_first == NULL)
+
+#define LIST_FIRST(head) ((head)->lh_first)
+
+#define LIST_FOREACH(var, head, field) \
+ for ((var) = LIST_FIRST((head)); \
+ (var); \
+ (var) = LIST_NEXT((var), field))
+
+#define LIST_INIT(head) do { \
+ LIST_FIRST((head)) = NULL; \
+} while (0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
+ LIST_NEXT((listelm), field)->field.le_prev = \
+ &LIST_NEXT((elm), field); \
+ LIST_NEXT((listelm), field) = (elm); \
+ (elm)->field.le_prev = &LIST_NEXT((listelm), field); \
+} while (0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ LIST_NEXT((elm), field) = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
+} while (0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
+ LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
+ LIST_FIRST((head)) = (elm); \
+ (elm)->field.le_prev = &LIST_FIRST((head)); \
+} while (0)
+
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+#define LIST_REMOVE(elm, field) do { \
+ if (LIST_NEXT((elm), field) != NULL) \
+ LIST_NEXT((elm), field)->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = LIST_NEXT((elm), field); \
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#define TAILQ_HEAD(name, type) \
+struct name { \
+ struct type *tqh_first; /* first element */ \
+ struct type **tqh_last; /* addr of last next element */ \
+ TRACEBUF \
+}
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first }
+
+#define TAILQ_ENTRY(type) \
+struct { \
+ struct type *tqe_next; /* next element */ \
+ struct type **tqe_prev; /* address of previous next element */ \
+ TRACEBUF \
+}
+
+/*
+ * Tail queue functions.
+ */
+#define TAILQ_CONCAT(head1, head2, field) do { \
+ if (!TAILQ_EMPTY(head2)) { \
+ *(head1)->tqh_last = (head2)->tqh_first; \
+ (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
+ (head1)->tqh_last = (head2)->tqh_last; \
+ TAILQ_INIT((head2)); \
+ QMD_TRACE_HEAD(head); \
+ QMD_TRACE_HEAD(head2); \
+ } \
+} while (0)
+
+#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
+
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+
+#define TAILQ_FOREACH(var, head, field) \
+ for ((var) = TAILQ_FIRST((head)); \
+ (var); \
+ (var) = TAILQ_NEXT((var), field))
+
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = TAILQ_LAST((head), headname); \
+ (var); \
+ (var) = TAILQ_PREV((var), headname, field))
+
+#define TAILQ_INIT(head) do { \
+ TAILQ_FIRST((head)) = NULL; \
+ (head)->tqh_last = &TAILQ_FIRST((head)); \
+ QMD_TRACE_HEAD(head); \
+} while (0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
+ TAILQ_NEXT((elm), field)->field.tqe_prev = \
+ &TAILQ_NEXT((elm), field); \
+ else { \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_HEAD(head); \
+ } \
+ TAILQ_NEXT((listelm), field) = (elm); \
+ (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+ QMD_TRACE_ELEM(&listelm->field); \
+} while (0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ TAILQ_NEXT((elm), field) = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+ QMD_TRACE_ELEM(&listelm->field); \
+} while (0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
+ TAILQ_FIRST((head))->field.tqe_prev = \
+ &TAILQ_NEXT((elm), field); \
+ else \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ TAILQ_FIRST((head)) = (elm); \
+ (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
+ QMD_TRACE_HEAD(head); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ TAILQ_NEXT((elm), field) = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_HEAD(head); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ if ((TAILQ_NEXT((elm), field)) != NULL) \
+ TAILQ_NEXT((elm), field)->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else { \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ QMD_TRACE_HEAD(head); \
+ } \
+ *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
+ TRASHIT((elm)->field.tqe_next); \
+ TRASHIT((elm)->field.tqe_prev); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+
+/*
+ * Circular queue definitions.
+ */
+#define CIRCLEQ_HEAD(name, type) \
+struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+}
+
+#define CIRCLEQ_ENTRY(type) \
+struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+}
+
+/*
+ * Circular queue functions.
+ */
+#define CIRCLEQ_INIT(head) { \
+ (head)->cqh_first = (void *)(head); \
+ (head)->cqh_last = (void *)(head); \
+}
+
+#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) { \
+ (elm)->field.cqe_next = (listelm)->field.cqe_next; \
+ (elm)->field.cqe_prev = (listelm); \
+ if ((listelm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (listelm)->field.cqe_next->field.cqe_prev = (elm); \
+ (listelm)->field.cqe_next = (elm); \
+}
+
+#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) { \
+ (elm)->field.cqe_next = (listelm); \
+ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
+ if ((listelm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (listelm)->field.cqe_prev->field.cqe_next = (elm); \
+ (listelm)->field.cqe_prev = (elm); \
+}
+
+#define CIRCLEQ_INSERT_HEAD(head, elm, field) { \
+ (elm)->field.cqe_next = (head)->cqh_first; \
+ (elm)->field.cqe_prev = (void *)(head); \
+ if ((head)->cqh_last == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (head)->cqh_first->field.cqe_prev = (elm); \
+ (head)->cqh_first = (elm); \
+}
+
+#define CIRCLEQ_INSERT_TAIL(head, elm, field) { \
+ (elm)->field.cqe_next = (void *)(head); \
+ (elm)->field.cqe_prev = (head)->cqh_last; \
+ if ((head)->cqh_first == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (head)->cqh_last->field.cqe_next = (elm); \
+ (head)->cqh_last = (elm); \
+}
+
+#define CIRCLEQ_REMOVE(head, elm, field) { \
+ if ((elm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm)->field.cqe_prev; \
+ else \
+ (elm)->field.cqe_next->field.cqe_prev = \
+ (elm)->field.cqe_prev; \
+ if ((elm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm)->field.cqe_next; \
+ else \
+ (elm)->field.cqe_prev->field.cqe_next = \
+ (elm)->field.cqe_next; \
+}
+
+#ifdef _KERNEL
+
+/*
+ * XXX insque() and remque() are an old way of handling certain queues.
+ * They bogusly assumes that all queue heads look alike.
+ */
+
+
+#ifdef __GNUC__
+
+struct quehead {
+ struct quehead *qh_link;
+ struct quehead *qh_rlink;
+};
+
+static __inline void
+insque(void *a, void *b)
+{
+ struct quehead *element = (struct quehead *)a,
+ *head = (struct quehead *)b;
+
+ element->qh_link = head->qh_link;
+ element->qh_rlink = head;
+ head->qh_link = element;
+ element->qh_link->qh_rlink = element;
+}
+
+static __inline void
+remque(void *a)
+{
+ struct quehead *element = (struct quehead *)a;
+
+ element->qh_link->qh_rlink = element->qh_rlink;
+ element->qh_rlink->qh_link = element->qh_link;
+ element->qh_rlink = 0;
+}
+
+#else /* !__GNUC__ */
+
+void insque(void *a, void *b);
+void remque(void *a);
+
+#endif /* __GNUC__ */
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_QUEUE_H_ */
diff --git a/cpukit/libnetworking/sys/reboot.h b/cpukit/libnetworking/sys/reboot.h
new file mode 100644
index 0000000000..48a7f0f782
--- /dev/null
+++ b/cpukit/libnetworking/sys/reboot.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993, 1994
+ * 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.
+ *
+ * @(#)reboot.h 8.3 (Berkeley) 12/13/94
+ * $Id$
+ */
+
+#ifndef _SYS_REBOOT_H_
+#define _SYS_REBOOT_H_
+
+/*
+ * Arguments to reboot system call. These are passed to
+ * the boot program and on to init.
+ */
+#define RB_AUTOBOOT 0 /* flags for system auto-booting itself */
+
+#define RB_ASKNAME 0x001 /* ask for file name to reboot from */
+#define RB_SINGLE 0x002 /* reboot to single user only */
+#define RB_NOSYNC 0x004 /* dont sync before reboot */
+#define RB_HALT 0x008 /* don't reboot, just halt */
+#define RB_INITNAME 0x010 /* name given for /etc/init (unused) */
+#define RB_DFLTROOT 0x020 /* use compiled-in rootdev */
+#define RB_KDB 0x040 /* give control to kernel debugger */
+#define RB_RDONLY 0x080 /* mount root fs read-only */
+#define RB_DUMP 0x100 /* dump kernel memory before reboot */
+#define RB_MINIROOT 0x200 /* mini-root present in memory at boot time */
+#define RB_CONFIG 0x400 /* invoke user configuration routing */
+#define RB_VERBOSE 0x800 /* print all potentially useful info */
+#define RB_SERIAL 0x1000 /* user serial port as console */
+#define RB_CDROM 0x2000 /* use cdrom as root */
+#define RB_POWEROFF 0x4000 /* if you can, turn the power off */
+#define RB_GDB 0x8000 /* use GDB remote debugger instead of DDB */
+#define RB_MUTE 0x10000 /* Come up with the console muted */
+#define RB_SELFTEST 0x20000 /* don't boot to normal operation, do selftest */
+
+#define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */
+
+/*
+ * Constants for converting boot-style device number to type,
+ * adaptor (uba, mba, etc), unit number and partition number.
+ * Type (== major device number) is in the low byte
+ * for backward compatibility. Except for that of the "magic
+ * number", each mask applies to the shifted value.
+ * Format:
+ * (4) (4) (4) (4) (8) (8)
+ * --------------------------------
+ * |MA | AD| CT| UN| PART | TYPE |
+ * --------------------------------
+ */
+#define B_ADAPTORSHIFT 24
+#define B_ADAPTORMASK 0x0f
+#define B_ADAPTOR(val) (((val) >> B_ADAPTORSHIFT) & B_ADAPTORMASK)
+#define B_CONTROLLERSHIFT 20
+#define B_CONTROLLERMASK 0xf
+#define B_CONTROLLER(val) (((val)>>B_CONTROLLERSHIFT) & B_CONTROLLERMASK)
+#define B_SLICESHIFT 20
+#define B_SLICEMASK 0xff
+#define B_SLICE(val) (((val)>>B_SLICESHIFT) & B_SLICEMASK)
+#define B_UNITSHIFT 16
+#define B_UNITMASK 0xf
+#define B_UNIT(val) (((val) >> B_UNITSHIFT) & B_UNITMASK)
+#define B_PARTITIONSHIFT 8
+#define B_PARTITIONMASK 0xff
+#define B_PARTITION(val) (((val) >> B_PARTITIONSHIFT) & B_PARTITIONMASK)
+#define B_TYPESHIFT 0
+#define B_TYPEMASK 0xff
+#define B_TYPE(val) (((val) >> B_TYPESHIFT) & B_TYPEMASK)
+
+#define B_MAGICMASK 0xf0000000
+#define B_DEVMAGIC 0xa0000000
+
+#define MAKEBOOTDEV(type, adaptor, controller, unit, partition) \
+ (((type) << B_TYPESHIFT) | ((adaptor) << B_ADAPTORSHIFT) | \
+ ((controller) << B_CONTROLLERSHIFT) | ((unit) << B_UNITSHIFT) | \
+ ((partition) << B_PARTITIONSHIFT) | B_DEVMAGIC)
+
+#endif
diff --git a/cpukit/libnetworking/sys/resourcevar.h b/cpukit/libnetworking/sys/resourcevar.h
new file mode 100644
index 0000000000..2b4c47e48f
--- /dev/null
+++ b/cpukit/libnetworking/sys/resourcevar.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+/* intentionally empty file */
diff --git a/cpukit/libnetworking/sys/rtprio.h b/cpukit/libnetworking/sys/rtprio.h
new file mode 100644
index 0000000000..843cf8cd1f
--- /dev/null
+++ b/cpukit/libnetworking/sys/rtprio.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1994, Henrik Vestergaard Draboel
+ * 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 (name).
+ * 4. 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 BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+#ifndef _SYS_RTPRIO_H_
+#define _SYS_RTPRIO_H_
+
+/*
+ * Process realtime-priority specifications to rtprio.
+ */
+
+/* priority types */
+#define RTP_PRIO_REALTIME 0
+#define RTP_PRIO_NORMAL 1
+#define RTP_PRIO_IDLE 2
+
+/* priority range */
+#define RTP_PRIO_MIN 0 /* Highest priority */
+#define RTP_PRIO_MAX 31 /* Lowest priority */
+
+/*
+ * rtprio() syscall functions
+ */
+#define RTP_LOOKUP 0
+#define RTP_SET 1
+
+#ifndef LOCORE
+struct rtprio {
+ u_short type;
+ u_short prio;
+};
+#endif
+
+#ifndef _KERNEL
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int rtprio __P((int, pid_t, struct rtprio *));
+__END_DECLS
+#endif /* !_KERNEL */
+#endif /* !_SYS_RTPRIO_H_ */
diff --git a/cpukit/libnetworking/sys/select.h b/cpukit/libnetworking/sys/select.h
new file mode 100644
index 0000000000..c03a1abe2c
--- /dev/null
+++ b/cpukit/libnetworking/sys/select.h
@@ -0,0 +1,75 @@
+/*-
+ * 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.
+ *
+ * @(#)select.h 8.2 (Berkeley) 1/4/94
+ * $Id$
+ */
+
+#ifndef _SYS_SELECT_H_
+#define _SYS_SELECT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Used to maintain information about processes that wish to be
+ * notified when I/O becomes possible.
+ */
+struct selinfo {
+ pid_t si_pid; /* process to be notified */
+ short si_flags; /* see below */
+};
+#define SI_COLL 0x0001 /* collision occurred */
+
+#ifdef _KERNEL
+struct proc;
+
+void selrecord __P((struct proc *selector, struct selinfo *));
+void selwakeup __P((struct selinfo *));
+#endif
+
+/* Check the first NFDS descriptors each in READFDS (if not NULL) for read
+ readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
+ (if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out
+ after waiting the interval specified therein. Returns the number of ready
+ descriptors, or -1 for errors. */
+extern int select (int __nfds, fd_set *__readfds,
+ fd_set *__writefds,
+ fd_set *__exceptfds,
+ struct timeval *__timeout);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_SYS_SELECT_H_ */
diff --git a/cpukit/libnetworking/sys/signalvar.h b/cpukit/libnetworking/sys/signalvar.h
new file mode 100644
index 0000000000..151f2c6d8e
--- /dev/null
+++ b/cpukit/libnetworking/sys/signalvar.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 1991, 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.
+ *
+ * @(#)signalvar.h 8.6 (Berkeley) 2/19/95
+ * $Id$
+ */
+
+#ifndef _SYS_SIGNALVAR_H_ /* tmp for user.h */
+#define _SYS_SIGNALVAR_H_
+
+/*
+ * Kernel signal definitions and data structures,
+ * not exported to user programs.
+ */
+
+/*
+ * Process signal actions and state, needed only within the process
+ * (not necessarily resident).
+ */
+struct sigacts {
+ sig_t ps_sigact[NSIG]; /* disposition of signals */
+ sigset_t ps_catchmask[NSIG]; /* signals to be blocked */
+ sigset_t ps_sigonstack; /* signals to take on sigstack */
+ sigset_t ps_sigintr; /* signals that interrupt syscalls */
+ sigset_t ps_sigreset; /* signals that reset when caught */
+ sigset_t ps_signodefer; /* signals not masked while handled */
+ sigset_t ps_oldmask; /* saved mask from before sigpause */
+ int ps_flags; /* signal flags, below */
+ struct sigaltstack ps_sigstk; /* sp & on stack state variable */
+ int ps_sig; /* for core dump/debugger XXX */
+ u_long ps_code; /* for core dump/debugger XXX */
+ sigset_t ps_usertramp; /* SunOS compat; libc sigtramp XXX */
+};
+
+/* signal flags */
+#define SAS_OLDMASK 0x01 /* need to restore mask before pause */
+#define SAS_ALTSTACK 0x02 /* have alternate signal stack */
+
+/* additional signal action values, used only temporarily/internally */
+#define SIG_CATCH ((__sighandler_t *)2)
+#define SIG_HOLD ((__sighandler_t *)3)
+
+/*
+ * get signal action for process and signal; currently only for current process
+ */
+#define SIGACTION(p, sig) (p->p_sigacts->ps_sigact[(sig)])
+
+/*
+ * Determine signal that should be delivered to process p, the current
+ * process, 0 if none. If there is a pending stop signal with default
+ * action, the process stops in issignal().
+ */
+#define CURSIG(p) \
+ (((p)->p_siglist == 0 || \
+ (((p)->p_flag & P_TRACED) == 0 && \
+ ((p)->p_siglist & ~(p)->p_sigmask) == 0)) ? \
+ 0 : issignal(p))
+
+/*
+ * Clear a pending signal from a process.
+ */
+#define CLRSIG(p, sig) { (p)->p_siglist &= ~sigmask(sig); }
+
+/*
+ * Signal properties and actions.
+ * The array below categorizes the signals and their default actions
+ * according to the following properties:
+ */
+#define SA_KILL 0x01 /* terminates process by default */
+#define SA_CORE 0x02 /* ditto and coredumps */
+#define SA_STOP 0x04 /* suspend process */
+#define SA_TTYSTOP 0x08 /* ditto, from tty */
+#define SA_IGNORE 0x10 /* ignore by default */
+#define SA_CONT 0x20 /* continue if suspended */
+#define SA_CANTMASK 0x40 /* non-maskable, catchable */
+
+#ifdef SIGPROP
+static int sigprop[NSIG + 1] = {
+ 0, /* unused */
+ SA_KILL, /* SIGHUP */
+ SA_KILL, /* SIGINT */
+ SA_KILL|SA_CORE, /* SIGQUIT */
+ SA_KILL|SA_CORE, /* SIGILL */
+ SA_KILL|SA_CORE, /* SIGTRAP */
+ SA_KILL|SA_CORE, /* SIGABRT */
+ SA_KILL|SA_CORE, /* SIGEMT */
+ SA_KILL|SA_CORE, /* SIGFPE */
+ SA_KILL, /* SIGKILL */
+ SA_KILL|SA_CORE, /* SIGBUS */
+ SA_KILL|SA_CORE, /* SIGSEGV */
+ SA_KILL|SA_CORE, /* SIGSYS */
+ SA_KILL, /* SIGPIPE */
+ SA_KILL, /* SIGALRM */
+ SA_KILL, /* SIGTERM */
+ SA_IGNORE, /* SIGURG */
+ SA_STOP, /* SIGSTOP */
+ SA_STOP|SA_TTYSTOP, /* SIGTSTP */
+ SA_IGNORE|SA_CONT, /* SIGCONT */
+ SA_IGNORE, /* SIGCHLD */
+ SA_STOP|SA_TTYSTOP, /* SIGTTIN */
+ SA_STOP|SA_TTYSTOP, /* SIGTTOU */
+ SA_IGNORE, /* SIGIO */
+ SA_KILL, /* SIGXCPU */
+ SA_KILL, /* SIGXFSZ */
+ SA_KILL, /* SIGVTALRM */
+ SA_KILL, /* SIGPROF */
+ SA_IGNORE, /* SIGWINCH */
+ SA_IGNORE, /* SIGINFO */
+ SA_KILL, /* SIGUSR1 */
+ SA_KILL, /* SIGUSR2 */
+};
+
+#define contsigmask (sigmask(SIGCONT))
+#define stopsigmask (sigmask(SIGSTOP) | sigmask(SIGTSTP) | \
+ sigmask(SIGTTIN) | sigmask(SIGTTOU))
+
+#endif /* SIGPROP */
+
+#define sigcantmask (sigmask(SIGKILL) | sigmask(SIGSTOP))
+
+#ifdef _KERNEL
+/*
+ * Machine-independent functions:
+ */
+void execsigs __P((struct proc *p));
+void gsignal __P((int pgid, int sig));
+int issignal __P((struct proc *p));
+void killproc __P((struct proc *p, char *why));
+void pgsignal __P((struct pgrp *pgrp, int sig, int checkctty));
+void postsig __P((int sig));
+void psignal __P((struct proc *p, int sig));
+void setsigvec __P((struct proc *p, int signum, struct sigaction *sa));
+void sigexit __P((struct proc *p, int signum));
+void siginit __P((struct proc *p));
+void trapsignal __P((struct proc *p, int sig, u_long code));
+
+/*
+ * Machine-dependent functions:
+ */
+void sendsig __P((sig_t action, int sig, int returnmask, u_long code));
+#endif /* _KERNEL */
+#endif /* !_SYS_SIGNALVAR_H_ */
diff --git a/cpukit/libnetworking/sys/socket.h b/cpukit/libnetworking/sys/socket.h
new file mode 100644
index 0000000000..10894425cc
--- /dev/null
+++ b/cpukit/libnetworking/sys/socket.h
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994
+ * 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.
+ * 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.
+ *
+ * @(#)socket.h 8.4 (Berkeley) 2/21/94
+ * $FreeBSD: src/sys/sys/socket.h,v 1.88 2005/04/13 00:01:46 mdodd Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _SYS_SOCKET_H_
+#define _SYS_SOCKET_H_
+
+#include <sys/cdefs.h>
+#include <rtems/bsdnet/_types.h>
+
+/*
+ * Definitions related to sockets: types, address families, options.
+ */
+
+/*
+ * Data types.
+ */
+
+#ifndef _SA_FAMILY_T_DECLARED
+typedef __sa_family_t sa_family_t;
+#define _SA_FAMILY_T_DECLARED
+#endif
+
+#ifndef _SOCKLEN_T_DECLARED
+typedef __socklen_t socklen_t;
+#define _SOCKLEN_T_DECLARED
+#endif
+
+/*
+ * Types
+ */
+#define SOCK_STREAM 1 /* stream socket */
+#define SOCK_DGRAM 2 /* datagram socket */
+#define SOCK_RAW 3 /* raw-protocol interface */
+#if __BSD_VISIBLE
+#define SOCK_RDM 4 /* reliably-delivered message */
+#endif
+#define SOCK_SEQPACKET 5 /* sequenced packet stream */
+
+/*
+ * Option flags per-socket.
+ */
+#define SO_DEBUG 0x0001 /* turn on debugging info recording */
+#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
+#define SO_REUSEADDR 0x0004 /* allow local address reuse */
+#define SO_KEEPALIVE 0x0008 /* keep connections alive */
+#define SO_DONTROUTE 0x0010 /* just use interface addresses */
+#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
+#if __BSD_VISIBLE
+#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
+#endif
+#define SO_LINGER 0x0080 /* linger on close if data present */
+#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
+#if __BSD_VISIBLE
+#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
+#define SO_TIMESTAMP 0x0400 /* timestamp received dgram traffic */
+#define SO_NOSIGPIPE 0x0800 /* no SIGPIPE from EPIPE */
+#define SO_ACCEPTFILTER 0x1000 /* there is an accept filter */
+#define SO_BINTIME 0x2000 /* timestamp received dgram traffic */
+#endif
+
+/*
+ * Additional options, not kept in so_options.
+ */
+#define SO_SNDBUF 0x1001 /* send buffer size */
+#define SO_RCVBUF 0x1002 /* receive buffer size */
+#define SO_SNDLOWAT 0x1003 /* send low-water mark */
+#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
+#define SO_SNDTIMEO 0x1005 /* send timeout */
+#define SO_RCVTIMEO 0x1006 /* receive timeout */
+#define SO_ERROR 0x1007 /* get error status and clear */
+#define SO_TYPE 0x1008 /* get socket type */
+#define SO_PRIVSTATE 0x1009 /* get/deny privileged state */
+
+/*
+ * RTEMS addition: get and set wakeup functions.
+ */
+#define SO_SNDWAKEUP 0x1020 /* wakeup when ready to send */
+#define SO_RCVWAKEUP 0x1021 /* wakeup when ready to receive */
+
+/*
+ * Structure used for manipulating linger option.
+ */
+struct linger {
+ int l_onoff; /* option on/off */
+ int l_linger; /* linger time */
+};
+
+/*
+ * RTEMS addition: structure used to get and set wakeup function.
+ */
+struct socket;
+struct sockwakeup {
+ void (*sw_pfn) __P((struct socket *, caddr_t));
+ caddr_t sw_arg;
+};
+
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define SOL_SOCKET 0xffff /* options for socket level */
+
+/*
+ * Address families.
+ */
+#define AF_UNSPEC 0 /* unspecified */
+#if __BSD_VISIBLE
+#define AF_LOCAL AF_UNIX /* local to host (pipes, portals) */
+#endif
+#define AF_UNIX 1 /* standardized name for AF_LOCAL */
+#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
+#if __BSD_VISIBLE
+#define AF_IMPLINK 3 /* arpanet imp addresses */
+#define AF_PUP 4 /* pup protocols: e.g. BSP */
+#define AF_CHAOS 5 /* mit CHAOS protocols */
+#define AF_NETBIOS 6 /* SMB protocols */
+#define AF_ISO 7 /* ISO protocols */
+#define AF_OSI AF_ISO
+#define AF_ECMA 8 /* European computer manufacturers */
+#define AF_DATAKIT 9 /* datakit protocols */
+#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
+#define AF_SNA 11 /* IBM SNA */
+#define AF_DECnet 12 /* DECnet */
+#define AF_DLI 13 /* DEC Direct data link interface */
+#define AF_LAT 14 /* LAT */
+#define AF_HYLINK 15 /* NSC Hyperchannel */
+#define AF_APPLETALK 16 /* Apple Talk */
+#define AF_ROUTE 17 /* Internal Routing Protocol */
+#define AF_LINK 18 /* Link layer interface */
+#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
+#define AF_COIP 20 /* connection-oriented IP, aka ST II */
+#define AF_CNT 21 /* Computer Network Technology */
+#define pseudo_AF_RTIP 22 /* Help Identify RTIP packets */
+#define AF_IPX 23 /* Novell Internet Protocol */
+#define AF_SIP 24 /* Simple Internet Protocol */
+#define pseudo_AF_PIP 25 /* Help Identify PIP packets */
+#define AF_ISDN 26 /* Integrated Services Digital Network*/
+#define AF_E164 AF_ISDN /* CCITT E.164 recommendation */
+#define pseudo_AF_KEY 27 /* Internal key-management function */
+#endif
+#define AF_INET6 28 /* IPv6 */
+
+#define AF_MAX 29
+
+/*
+ * Structure used by kernel to store most
+ * addresses.
+ */
+struct sockaddr {
+ unsigned char sa_len; /* total length */
+ sa_family_t sa_family; /* address family */
+ char sa_data[14]; /* actually longer; address value */
+};
+
+/*
+ * Structure used by kernel to pass protocol
+ * information in raw sockets.
+ */
+struct sockproto {
+ unsigned short sp_family; /* address family */
+ unsigned short sp_protocol; /* protocol */
+};
+
+/*
+ * Protocol families, same as address families for now.
+ */
+#define PF_UNSPEC AF_UNSPEC
+#define PF_LOCAL AF_LOCAL
+#define PF_UNIX PF_LOCAL /* backward compatibility */
+#define PF_INET AF_INET
+#define PF_IMPLINK AF_IMPLINK
+#define PF_PUP AF_PUP
+#define PF_CHAOS AF_CHAOS
+#define PF_NETBIOS AF_NETBIOS
+#define PF_ISO AF_ISO
+#define PF_OSI AF_ISO
+#define PF_ECMA AF_ECMA
+#define PF_DATAKIT AF_DATAKIT
+#define PF_CCITT AF_CCITT
+#define PF_SNA AF_SNA
+#define PF_DECnet AF_DECnet
+#define PF_DLI AF_DLI
+#define PF_LAT AF_LAT
+#define PF_HYLINK AF_HYLINK
+#define PF_APPLETALK AF_APPLETALK
+#define PF_ROUTE AF_ROUTE
+#define PF_LINK AF_LINK
+#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
+#define PF_COIP AF_COIP
+#define PF_CNT AF_CNT
+#define PF_SIP AF_SIP
+#define PF_IPX AF_IPX
+#define PF_RTIP pseudo_AF_RTIP /* same format as AF_INET */
+#define PF_PIP pseudo_AF_PIP
+#define PF_ISDN AF_ISDN
+#define PF_KEY pseudo_AF_KEY
+#define PF_INET6 AF_INET6
+
+#define PF_MAX AF_MAX
+
+/*
+ * Definitions for network related sysctl, CTL_NET.
+ *
+ * Second level is protocol family.
+ * Third level is protocol number.
+ *
+ * Further levels are defined by the individual families below.
+ */
+#define NET_MAXID AF_MAX
+
+#define CTL_NET_NAMES { \
+ { 0, 0 }, \
+ { "unix", CTLTYPE_NODE }, \
+ { "inet", CTLTYPE_NODE }, \
+ { "implink", CTLTYPE_NODE }, \
+ { "pup", CTLTYPE_NODE }, \
+ { "chaos", CTLTYPE_NODE }, \
+ { "xerox_ns", CTLTYPE_NODE }, \
+ { "iso", CTLTYPE_NODE }, \
+ { "emca", CTLTYPE_NODE }, \
+ { "datakit", CTLTYPE_NODE }, \
+ { "ccitt", CTLTYPE_NODE }, \
+ { "ibm_sna", CTLTYPE_NODE }, \
+ { "decnet", CTLTYPE_NODE }, \
+ { "dec_dli", CTLTYPE_NODE }, \
+ { "lat", CTLTYPE_NODE }, \
+ { "hylink", CTLTYPE_NODE }, \
+ { "appletalk", CTLTYPE_NODE }, \
+ { "route", CTLTYPE_NODE }, \
+ { "link_layer", CTLTYPE_NODE }, \
+ { "xtp", CTLTYPE_NODE }, \
+ { "coip", CTLTYPE_NODE }, \
+ { "cnt", CTLTYPE_NODE }, \
+ { "rtip", CTLTYPE_NODE }, \
+ { "ipx", CTLTYPE_NODE }, \
+ { "sip", CTLTYPE_NODE }, \
+ { "pip", CTLTYPE_NODE }, \
+ { "isdn", CTLTYPE_NODE }, \
+ { "key", CTLTYPE_NODE }, \
+}
+
+/*
+ * PF_ROUTE - Routing table
+ *
+ * Three additional levels are defined:
+ * Fourth: address family, 0 is wildcard
+ * Fifth: type of info, defined below
+ * Sixth: flag(s) to mask with for NET_RT_FLAGS
+ */
+#define NET_RT_DUMP 1 /* dump; may limit to a.f. */
+#define NET_RT_FLAGS 2 /* by flags, e.g. RESOLVING */
+#define NET_RT_IFLIST 3 /* survey interface list */
+#define NET_RT_MAXID 4
+
+#define CTL_NET_RT_NAMES { \
+ { 0, 0 }, \
+ { "dump", CTLTYPE_STRUCT }, \
+ { "flags", CTLTYPE_STRUCT }, \
+ { "iflist", CTLTYPE_STRUCT }, \
+}
+
+/*
+ * Maximum queue length specifiable by listen.
+ */
+#define SOMAXCONN 128
+
+/*
+ * Message header for recvmsg and sendmsg calls.
+ * Used value-result for recvmsg, value only for sendmsg.
+ */
+struct msghdr {
+ void *msg_name; /* optional address */
+ socklen_t msg_namelen; /* size of address */
+ struct iovec *msg_iov; /* scatter/gather array */
+ int msg_iovlen; /* # elements in msg_iov */
+ void *msg_control; /* ancillary data, see below */
+ socklen_t msg_controllen; /* ancillary data buffer len */
+ int msg_flags; /* flags on received message */
+};
+
+#define MSG_OOB 0x1 /* process out-of-band data */
+#define MSG_PEEK 0x2 /* peek at incoming message */
+#define MSG_DONTROUTE 0x4 /* send without using routing tables */
+#define MSG_EOR 0x8 /* data completes record */
+#define MSG_TRUNC 0x10 /* data discarded before delivery */
+#define MSG_CTRUNC 0x20 /* control data lost before delivery */
+#define MSG_WAITALL 0x40 /* wait for full request or error */
+#if __BSD_VISIBLE
+#define MSG_DONTWAIT 0x80 /* this message should be nonblocking */
+#define MSG_EOF 0x100 /* data completes connection */
+#define MSG_COMPAT 0x8000 /* used in sendit() */
+#endif
+
+/*
+ * Header for ancillary data objects in msg_control buffer.
+ * Used for additional information with/about a datagram
+ * not expressible by flags. The format is a sequence
+ * of message elements headed by cmsghdr structures.
+ */
+struct cmsghdr {
+ socklen_t cmsg_len; /* data byte count, including hdr */
+ int cmsg_level; /* originating protocol */
+ int cmsg_type; /* protocol-specific type */
+/* followed by u_char cmsg_data[]; */
+};
+
+/* given pointer to struct cmsghdr, return pointer to data */
+#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
+
+/* given pointer to struct cmsghdr, return pointer to next cmsghdr */
+#define CMSG_NXTHDR(mhdr, cmsg) \
+ (((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
+ (mhdr)->msg_control + (mhdr)->msg_controllen) ? \
+ (struct cmsghdr *)NULL : \
+ (struct cmsghdr *)((caddr_t)(cmsg) + ALIGN((cmsg)->cmsg_len)))
+
+#define CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
+
+/* "Socket"-level control message types: */
+#define SCM_RIGHTS 0x01 /* access rights (array of int) */
+#define SCM_TIMESTAMP 0x02 /* timestamp (struct timeval) */
+
+/*
+ * 4.3 compat sockaddr, move to compat file later
+ */
+struct osockaddr {
+ unsigned short sa_family; /* address family */
+ char sa_data[14]; /* up to 14 bytes of direct address */
+};
+
+/*
+ * 4.3-compat message header (move to compat file later).
+ */
+struct omsghdr {
+ char *msg_name; /* optional address */
+ int msg_namelen; /* size of address */
+ struct iovec *msg_iov; /* scatter/gather array */
+ int msg_iovlen; /* # elements in msg_iov */
+ char *msg_accrights; /* access rights sent/received */
+ int msg_accrightslen;
+};
+
+/*
+ * howto arguments for shutdown(2), specified by Posix.1g.
+ */
+#define SHUT_RD 0 /* shut down the reading side */
+#define SHUT_WR 1 /* shut down the writing side */
+#define SHUT_RDWR 2 /* shut down both sides */
+
+#ifndef _KERNEL
+
+__BEGIN_DECLS
+int accept(int, struct sockaddr * __restrict, socklen_t * __restrict);
+int bind(int, const struct sockaddr *, socklen_t);
+int connect(int, const struct sockaddr *, socklen_t);
+int getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict);
+int getsockname(int, struct sockaddr * __restrict, socklen_t * __restrict);
+int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict);
+int listen(int, int);
+ssize_t recv(int, void *, size_t, int);
+ssize_t recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict);
+ssize_t recvmsg(int, struct msghdr *, int);
+ssize_t send(int, const void *, size_t, int);
+ssize_t sendto(int, const void *,
+ size_t, int, const struct sockaddr *, socklen_t);
+ssize_t sendmsg(int, const struct msghdr *, int);
+int setsockopt(int, int, int, const void *, socklen_t);
+int shutdown(int, int);
+int socket(int, int, int);
+int socketpair(int, int, int, int *);
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif /* !_SYS_SOCKET_H_ */
diff --git a/cpukit/libnetworking/sys/socketvar.h b/cpukit/libnetworking/sys/socketvar.h
new file mode 100644
index 0000000000..1fd0abdace
--- /dev/null
+++ b/cpukit/libnetworking/sys/socketvar.h
@@ -0,0 +1,280 @@
+/* $Id$ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1990, 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.
+ * 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.
+ *
+ * @(#)socketvar.h 8.3 (Berkeley) 2/19/95
+ * $FreeBSD: src/sys/sys/socketvar.h,v 1.135 2004/10/18 22:19:43 rwatson Exp $
+ */
+
+#ifndef _SYS_SOCKETVAR_H_
+#define _SYS_SOCKETVAR_H_
+
+#include <sys/queue.h> /* for TAILQ macros */
+#include <sys/select.h> /* for struct selinfo */
+
+/*
+ * Kernel structure per socket.
+ * Contains send and receive buffer queues,
+ * handle on protocol and pointer to protocol
+ * private data and error information.
+ */
+struct socket {
+ short so_type; /* generic type, see socket.h */
+ short so_options; /* from socket call, see socket.h */
+ short so_linger; /* time to linger while closing */
+ short so_state; /* internal state flags SS_*, below */
+ void *so_pcb; /* protocol control block */
+ struct protosw *so_proto; /* protocol handle */
+/*
+ * Variables for connection queuing.
+ * Socket where accepts occur is so_head in all subsidiary sockets.
+ * If so_head is 0, socket is not related to an accept.
+ * For head socket so_q0 queues partially completed connections,
+ * while so_q is a queue of connections ready to be accepted.
+ * If a connection is aborted and it has so_head set, then
+ * it has to be pulled out of either so_q0 or so_q.
+ * We allow connections to queue up based on current queue lengths
+ * and limit on number of queued connections for this socket.
+ */
+ struct socket *so_head; /* back pointer to accept socket */
+ TAILQ_HEAD(, socket) so_incomp; /* queue of partial unaccepted connections */
+ TAILQ_HEAD(, socket) so_comp; /* queue of complete unaccepted connections */
+ TAILQ_ENTRY(socket) so_list; /* list of unaccepted connections */
+ short so_qlen; /* number of unaccepted connections */
+ short so_incqlen; /* number of unaccepted incomplete
+ connections */
+ short so_qlimit; /* max number queued connections */
+ short so_timeo; /* connection timeout */
+ u_short so_error; /* error affecting connection */
+ pid_t so_pgid; /* pgid for signals */
+ u_long so_oobmark; /* chars to oob mark */
+/*
+ * Variables for socket buffering.
+ */
+ struct sockbuf {
+ u_int sb_cc; /* actual chars in buffer */
+ u_int sb_hiwat; /* max actual char count */
+ u_int sb_mbcnt; /* chars of mbufs used */
+ u_int sb_mbmax; /* max chars of mbufs to use */
+ int sb_lowat; /* low water mark */
+ struct mbuf *sb_mb; /* the mbuf chain */
+ struct selinfo sb_sel; /* process selecting read/write */
+ short sb_flags; /* flags, see below */
+ int sb_timeo; /* timeout for read/write */
+ void (*sb_wakeup) __P((struct socket *, caddr_t));
+ caddr_t sb_wakeuparg; /* arg for above */
+ } so_rcv, so_snd;
+#define SB_MAX (256*1024) /* default for max chars in sockbuf */
+#define SB_LOCK 0x01 /* lock on data queue */
+#define SB_WANT 0x02 /* someone is waiting to lock */
+#define SB_WAIT 0x04 /* someone is waiting for data/space */
+#define SB_SEL 0x08 /* someone is selecting */
+#define SB_ASYNC 0x10 /* ASYNC I/O, need signals */
+#define SB_NOTIFY (SB_WAIT|SB_SEL|SB_ASYNC)
+#define SB_NOINTR 0x40 /* operations not interruptible */
+
+ caddr_t so_tpcb; /* Wisc. protocol control block XXX */
+ void (*so_upcall)(struct socket *, void *arg, int);
+ void *so_upcallarg; /* Arg for above */
+ uid_t so_uid; /* who opened the socket */
+};
+
+/*
+ * Socket state bits.
+ */
+#define SS_NOFDREF 0x0001 /* no file table ref any more */
+#define SS_ISCONNECTED 0x0002 /* socket connected to a peer */
+#define SS_ISCONNECTING 0x0004 /* in process of connecting to peer */
+#define SS_ISDISCONNECTING 0x0008 /* in process of disconnecting */
+#define SS_CANTSENDMORE 0x0010 /* can't send more data to peer */
+#define SS_CANTRCVMORE 0x0020 /* can't receive more data from peer */
+#define SS_RCVATMARK 0x0040 /* at mark on input */
+
+#define SS_PRIV 0x0080 /* privileged for broadcast, raw... */
+#define SS_NBIO 0x0100 /* non-blocking ops */
+#define SS_ASYNC 0x0200 /* async i/o notify */
+#define SS_ISCONFIRMING 0x0400 /* deciding to accept connection req */
+
+#define SS_INCOMP 0x0800 /* unaccepted, incomplete connection */
+#define SS_COMP 0x1000 /* unaccepted, complete connection */
+
+
+/*
+ * Macros for sockets and socket buffering.
+ */
+
+/*
+ * How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
+ * This is problematical if the fields are unsigned, as the space might
+ * still be negative (cc > hiwat or mbcnt > mbmax). Should detect
+ * overflow and return 0. Should use "lmin" but it doesn't exist now.
+ */
+#define sbspace(sb) \
+ ((long) imin((int)((sb)->sb_hiwat - (sb)->sb_cc), \
+ (int)((sb)->sb_mbmax - (sb)->sb_mbcnt)))
+
+/* do we have to send all at once on a socket? */
+#define sosendallatonce(so) \
+ ((so)->so_proto->pr_flags & PR_ATOMIC)
+
+/* can we read something from so? */
+#define soreadable(so) \
+ ((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \
+ ((so)->so_state & SS_CANTRCVMORE) || \
+ (so)->so_comp.tqh_first || (so)->so_error)
+
+/* can we write something to so? */
+#define sowriteable(so) \
+ ((sbspace(&(so)->so_snd) >= (so)->so_snd.sb_lowat && \
+ (((so)->so_state&SS_ISCONNECTED) || \
+ ((so)->so_proto->pr_flags&PR_CONNREQUIRED)==0)) || \
+ ((so)->so_state & SS_CANTSENDMORE) || \
+ (so)->so_error)
+
+/* adjust counters in sb reflecting allocation of m */
+#define sballoc(sb, m) { \
+ (sb)->sb_cc += (m)->m_len; \
+ (sb)->sb_mbcnt += MSIZE; \
+ if ((m)->m_flags & M_EXT) \
+ (sb)->sb_mbcnt += (m)->m_ext.ext_size; \
+}
+
+/* adjust counters in sb reflecting freeing of m */
+#define sbfree(sb, m) { \
+ (sb)->sb_cc -= (m)->m_len; \
+ (sb)->sb_mbcnt -= MSIZE; \
+ if ((m)->m_flags & M_EXT) \
+ (sb)->sb_mbcnt -= (m)->m_ext.ext_size; \
+}
+
+/*
+ * Set lock on sockbuf sb; sleep if lock is already held.
+ * Unless SB_NOINTR is set on sockbuf, sleep is interruptible.
+ * Returns error without lock if sleep is interrupted.
+ */
+#define sblock(sb, wf) ((sb)->sb_flags & SB_LOCK ? \
+ (((wf) == M_WAITOK) ? sb_lock(sb) : EWOULDBLOCK) : \
+ ((sb)->sb_flags |= SB_LOCK), 0)
+
+/* release lock on sockbuf sb */
+#define sbunlock(sb) { \
+ (sb)->sb_flags &= ~SB_LOCK; \
+ if ((sb)->sb_flags & SB_WANT) { \
+ (sb)->sb_flags &= ~SB_WANT; \
+ wakeup((caddr_t)&(sb)->sb_flags); \
+ } \
+}
+
+#define sorwakeup(so) { sowakeup((so), &(so)->so_rcv); \
+ if ((so)->so_upcall) \
+ (*((so)->so_upcall))((so), (so)->so_upcallarg, M_DONTWAIT); \
+ }
+
+#define sowwakeup(so) sowakeup((so), &(so)->so_snd)
+
+#ifdef _KERNEL
+extern u_long sb_max;
+
+/* to catch callers missing new second argument to sonewconn: */
+#define sonewconn(head, connstatus) sonewconn1((head), (connstatus))
+
+struct filedesc;
+struct mbuf;
+struct sockaddr;
+struct stat;
+struct file;
+
+/*
+ * File operations on sockets.
+ */
+int soo_ioctl(struct file *fp, int cmd, caddr_t data,
+ struct proc *p);
+int soo_select(struct file *fp, int which, struct proc *p);
+int soo_stat(struct socket *so, struct stat *ub);
+
+/*
+ * From uipc_socket and friends
+ */
+int getsock(struct filedesc *fdp, int fdes, struct file **fpp);
+int sockargs(struct mbuf **mp, caddr_t buf, int buflen, int type);
+void sbappend(struct sockbuf *sb, struct mbuf *m);
+int sbappendaddr(struct sockbuf *sb, struct sockaddr *asa,
+ struct mbuf *m0, struct mbuf *control);
+int sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
+ struct mbuf *control);
+void sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
+void sbcheck(struct sockbuf *sb);
+void sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n);
+struct mbuf *
+ sbcreatecontrol(caddr_t p, int size, int type, int level);
+void sbdrop(struct sockbuf *sb, int len);
+void sbdroprecord(struct sockbuf *sb);
+void sbflush(struct sockbuf *sb);
+void sbinsertoob(struct sockbuf *sb, struct mbuf *m0);
+void sbrelease(struct sockbuf *sb);
+int sbreserve(struct sockbuf *sb, u_long cc);
+int sbwait(struct sockbuf *sb);
+int sb_lock(struct sockbuf *sb);
+int soabort(struct socket *so);
+int soaccept(struct socket *so, struct mbuf *nam);
+int sobind(struct socket *so, struct mbuf *nam);
+void socantrcvmore(struct socket *so);
+void socantsendmore(struct socket *so);
+int soclose(struct socket *so);
+int soconnect(struct socket *so, struct mbuf *nam);
+int soconnect2(struct socket *so1, struct socket *so2);
+int socreate(int dom, struct socket **aso, int type, int proto,
+ struct proc *p);
+int sodisconnect(struct socket *so);
+void sofree(struct socket *so);
+int sogetopt(struct socket *so, int level, int optname,
+ struct mbuf **mp);
+void sohasoutofband(struct socket *so);
+void soisconnected(struct socket *so);
+void soisconnecting(struct socket *so);
+void soisdisconnected(struct socket *so);
+void soisdisconnecting(struct socket *so);
+int solisten(struct socket *so, int backlog);
+struct socket *
+ sodropablereq(struct socket *head);
+struct socket *
+ sonewconn1(struct socket *head, int connstatus);
+int soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
+ struct mbuf **mp0, struct mbuf **controlp, int *flagsp);
+int soreserve(struct socket *so, u_long sndcc, u_long rcvcc);
+void sorflush(struct socket *so);
+int sosend(struct socket *so, struct mbuf *addr, struct uio *uio,
+ struct mbuf *top, struct mbuf *control, int flags);
+int sosetopt(struct socket *so, int level, int optname,
+ struct mbuf *m0);
+int soshutdown(struct socket *so, int how);
+void sowakeup(struct socket *so, struct sockbuf *sb);
+#endif /* _KERNEL */
+
+#endif /* !_SYS_SOCKETVAR_H_ */
diff --git a/cpukit/libnetworking/sys/sysctl.h b/cpukit/libnetworking/sys/sysctl.h
new file mode 100644
index 0000000000..5aade0fcad
--- /dev/null
+++ b/cpukit/libnetworking/sys/sysctl.h
@@ -0,0 +1,642 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Karels at Berkeley Software Design, Inc.
+ *
+ * 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.
+ * 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.
+ *
+ * @(#)sysctl.h 8.1 (Berkeley) 6/2/93
+ * $FreeBSD: src/sys/sys/sysctl.h,v 1.133 2004/10/11 22:04:16 peter Exp $
+ */
+
+#ifndef _SYS_SYSCTL_H_
+#define _SYS_SYSCTL_H_
+
+#include <rtems/stdint.h>
+#include <sys/queue.h>
+
+struct thread;
+/*
+ * Definitions for sysctl call. The sysctl call uses a hierarchical name
+ * for objects that can be examined or modified. The name is expressed as
+ * a sequence of integers. Like a file path name, the meaning of each
+ * component depends on its place in the hierarchy. The top-level and kern
+ * identifiers are defined here, and other identifiers are defined in the
+ * respective subsystem header files.
+ */
+
+#define CTL_MAXNAME 24 /* largest number of components supported */
+
+/*
+ * Each subsystem defined by sysctl defines a list of variables
+ * for that subsystem. Each name is either a node with further
+ * levels defined below it, or it is a leaf of some particular
+ * type given below. Each sysctl level defines a set of name/type
+ * pairs to be used by sysctl(8) in manipulating the subsystem.
+ */
+struct ctlname {
+ char *ctl_name; /* subsystem name */
+ int ctl_type; /* type of name */
+};
+
+#define CTLTYPE 0xf /* Mask for the type */
+#define CTLTYPE_NODE 1 /* name is a node */
+#define CTLTYPE_INT 2 /* name describes an integer */
+#define CTLTYPE_STRING 3 /* name describes a string */
+#define CTLTYPE_QUAD 4 /* name describes a 64-bit number */
+#define CTLTYPE_OPAQUE 5 /* name describes a structure */
+#define CTLTYPE_STRUCT CTLTYPE_OPAQUE /* name describes a structure */
+#define CTLTYPE_UINT 6 /* name describes an unsigned integer */
+#define CTLTYPE_LONG 7 /* name describes a long */
+#define CTLTYPE_ULONG 8 /* name describes an unsigned long */
+
+#define CTLFLAG_RD 0x80000000 /* Allow reads of variable */
+#define CTLFLAG_WR 0x40000000 /* Allow writes to the variable */
+#define CTLFLAG_RW (CTLFLAG_RD|CTLFLAG_WR)
+#define CTLFLAG_NOLOCK 0x20000000 /* XXX Don't Lock */
+#define CTLFLAG_ANYBODY 0x10000000 /* All users can set this var */
+#define CTLFLAG_SECURE 0x08000000 /* Permit set only if securelevel<=0 */
+#define CTLFLAG_PRISON 0x04000000 /* Prisoned roots can fiddle */
+#define CTLFLAG_DYN 0x02000000 /* Dynamic oid - can be freed */
+#define CTLFLAG_SKIP 0x01000000 /* Skip this sysctl when listing */
+#define CTLMASK_SECURE 0x00F00000 /* Secure level */
+#define CTLFLAG_TUN 0x00080000 /* Tunable variable */
+#define CTLFLAG_RDTUN (CTLFLAG_RD|CTLFLAG_TUN)
+
+/*
+ * Secure level. Note that CTLFLAG_SECURE == CTLFLAG_SECURE1.
+ *
+ * Secure when the securelevel is raised to at least N.
+ */
+#define CTLSHIFT_SECURE 20
+#define CTLFLAG_SECURE1 (CTLFLAG_SECURE | (0 << CTLSHIFT_SECURE))
+#define CTLFLAG_SECURE2 (CTLFLAG_SECURE | (1 << CTLSHIFT_SECURE))
+#define CTLFLAG_SECURE3 (CTLFLAG_SECURE | (2 << CTLSHIFT_SECURE))
+
+/*
+ * USE THIS instead of a hardwired number from the categories below
+ * to get dynamically assigned sysctl entries using the linker-set
+ * technology. This is the way nearly all new sysctl variables should
+ * be implemented.
+ * e.g. SYSCTL_INT(_parent, OID_AUTO, name, CTLFLAG_RW, &variable, 0, "");
+ */
+#define OID_AUTO (-1)
+
+/*
+ * The starting number for dynamically-assigned entries. WARNING!
+ * ALL static sysctl entries should have numbers LESS than this!
+ */
+#define CTL_AUTO_START 0x100
+
+#ifdef _KERNEL
+#define SYSCTL_HANDLER_ARGS struct sysctl_oid *oidp, void *arg1, int arg2, \
+ struct sysctl_req *req
+
+/* definitions for sysctl_req 'lock' member */
+#define REQ_UNLOCKED 0 /* not locked and not wired */
+#define REQ_LOCKED 1 /* locked and not wired */
+#define REQ_WIRED 2 /* locked and wired */
+
+/*
+ * This describes the access space for a sysctl request. This is needed
+ * so that we can use the interface from the kernel or from user-space.
+ */
+struct sysctl_req {
+ struct thread *td; /* used for access checking */
+ int lock; /* locking/wiring state */
+ void *oldptr;
+ size_t oldlen;
+ size_t oldidx;
+ int (*oldfunc)(struct sysctl_req *, const void *, size_t);
+ void *newptr;
+ size_t newlen;
+ size_t newidx;
+ int (*newfunc)(struct sysctl_req *, void *, size_t);
+ size_t validlen;
+};
+
+SLIST_HEAD(sysctl_oid_list, sysctl_oid);
+
+/*
+ * This describes one "oid" in the MIB tree. Potentially more nodes can
+ * be hidden behind it, expanded by the handler.
+ */
+struct sysctl_oid {
+ struct sysctl_oid_list *oid_parent;
+ SLIST_ENTRY(sysctl_oid) oid_link;
+ int oid_number;
+ uint32_t oid_kind;
+ void *oid_arg1;
+ int oid_arg2;
+ const char *oid_name;
+ int (*oid_handler)(SYSCTL_HANDLER_ARGS);
+ const char *oid_fmt;
+ int oid_refcnt;
+ const char *descr;
+};
+
+#define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l)
+#define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l)
+
+int sysctl_handle_int(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_long(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_intptr(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_string(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_opaque(SYSCTL_HANDLER_ARGS);
+
+/*
+ * These functions are used to add/remove an oid from the mib.
+ */
+void sysctl_register_oid(struct sysctl_oid *oidp);
+void sysctl_unregister_oid(struct sysctl_oid *oidp);
+
+/* Declare a static oid to allow child oids to be added to it. */
+#define SYSCTL_DECL(name) \
+ extern struct sysctl_oid_list sysctl_##name##_children
+
+/* Hide these in macros */
+#define SYSCTL_CHILDREN(oid_ptr) (struct sysctl_oid_list *) \
+ (oid_ptr)->oid_arg1
+#define SYSCTL_CHILDREN_SET(oid_ptr, val) \
+ (oid_ptr)->oid_arg1 = (val);
+#define SYSCTL_STATIC_CHILDREN(oid_name) \
+ (&sysctl_##oid_name##_children)
+
+/* === Structs and macros related to context handling === */
+
+/* All dynamically created sysctls can be tracked in a context list. */
+struct sysctl_ctx_entry {
+ struct sysctl_oid *entry;
+ TAILQ_ENTRY(sysctl_ctx_entry) link;
+};
+
+TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
+
+#define SYSCTL_NODE_CHILDREN(parent, name) \
+ sysctl_##parent##_##name##_children
+
+/* This constructs a "raw" MIB oid. */
+#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
+ static struct sysctl_oid sysctl__##parent##_##name = { \
+ &sysctl_##parent##_children, { 0 }, \
+ nbr, kind, a1, a2, #name, handler, fmt, 0, descr }; \
+ DATA_SET(sysctl_set, sysctl__##parent##_##name)
+
+#define SYSCTL_ADD_OID(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
+ sysctl_add_oid(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, descr)
+
+/* This constructs a node from which other oids can hang. */
+#define SYSCTL_NODE(parent, nbr, name, access, handler, descr) \
+ struct sysctl_oid_list SYSCTL_NODE_CHILDREN(parent, name); \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_NODE|(access), \
+ (void*)&SYSCTL_NODE_CHILDREN(parent, name), 0, handler, \
+ "N", descr)
+
+#define SYSCTL_ADD_NODE(ctx, parent, nbr, name, access, handler, descr) \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_NODE|(access), \
+ 0, 0, handler, "N", descr)
+
+/* Oid for a string. len can be 0 to indicate '\0' termination. */
+#define SYSCTL_STRING(parent, nbr, name, access, arg, len, descr) \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_STRING|(access), \
+ arg, len, sysctl_handle_string, "A", descr)
+
+#define SYSCTL_ADD_STRING(ctx, parent, nbr, name, access, arg, len, descr) \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_STRING|(access), \
+ arg, len, sysctl_handle_string, "A", descr)
+
+/* Oid for an int. If ptr is NULL, val is returned. */
+#define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|(access), \
+ ptr, val, sysctl_handle_int, "I", descr)
+
+#define SYSCTL_ADD_INT(ctx, parent, nbr, name, access, ptr, val, descr) \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_INT|(access), \
+ ptr, val, sysctl_handle_int, "I", descr)
+
+/* Oid for an unsigned int. If ptr is NULL, val is returned. */
+#define SYSCTL_UINT(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|(access), \
+ ptr, val, sysctl_handle_int, "IU", descr)
+
+#define SYSCTL_ADD_UINT(ctx, parent, nbr, name, access, ptr, val, descr) \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|(access), \
+ ptr, val, sysctl_handle_int, "IU", descr)
+
+/* Oid for a long. The pointer must be non NULL. */
+#define SYSCTL_LONG(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_LONG|(access), \
+ ptr, val, sysctl_handle_long, "L", descr)
+
+#define SYSCTL_ADD_LONG(ctx, parent, nbr, name, access, ptr, descr) \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_LONG|(access), \
+ ptr, 0, sysctl_handle_long, "L", descr)
+
+/* Oid for an unsigned long. The pointer must be non NULL. */
+#define SYSCTL_ULONG(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_ULONG|(access), \
+ ptr, val, sysctl_handle_long, "LU", descr)
+
+#define SYSCTL_ADD_ULONG(ctx, parent, nbr, name, access, ptr, descr) \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_ULONG|(access), \
+ ptr, 0, sysctl_handle_long, "LU", descr)
+
+/* Oid for an opaque object. Specified by a pointer and a length. */
+#define SYSCTL_OPAQUE(parent, nbr, name, access, ptr, len, fmt, descr) \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), \
+ ptr, len, sysctl_handle_opaque, fmt, descr)
+
+#define SYSCTL_ADD_OPAQUE(ctx, parent, nbr, name, access, ptr, len, fmt, descr)\
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \
+ ptr, len, sysctl_handle_opaque, fmt, descr)
+
+/* Oid for a struct. Specified by a pointer and a type. */
+#define SYSCTL_STRUCT(parent, nbr, name, access, ptr, type, descr) \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), \
+ ptr, sizeof(struct type), sysctl_handle_opaque, \
+ "S," #type, descr)
+
+#define SYSCTL_ADD_STRUCT(ctx, parent, nbr, name, access, ptr, type, descr) \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \
+ ptr, sizeof(struct type), sysctl_handle_opaque, "S," #type, descr)
+
+/* Oid for a procedure. Specified by a pointer and an arg. */
+#define SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr) \
+ SYSCTL_OID(parent, nbr, name, (access), \
+ ptr, arg, handler, fmt, descr)
+
+#define SYSCTL_ADD_PROC(ctx, parent, nbr, name, access, ptr, arg, handler, fmt, descr) \
+ sysctl_add_oid(ctx, parent, nbr, name, (access), \
+ ptr, arg, handler, fmt, descr)
+
+#endif /* _KERNEL */
+
+/*
+ * Top-level identifiers
+ */
+#define CTL_UNSPEC 0 /* unused */
+#define CTL_KERN 1 /* "high kernel": proc, limits */
+#define CTL_VM 2 /* virtual memory */
+#define CTL_VFS 3 /* filesystem, mount type is next */
+#define CTL_NET 4 /* network, see socket.h */
+#define CTL_DEBUG 5 /* debugging parameters */
+#define CTL_HW 6 /* generic cpu/io */
+#define CTL_MACHDEP 7 /* machine dependent */
+#define CTL_USER 8 /* user-level */
+#define CTL_P1003_1B 9 /* POSIX 1003.1B */
+#define CTL_MAXID 10 /* number of valid top-level ids */
+
+#define CTL_NAMES { \
+ { 0, 0 }, \
+ { "kern", CTLTYPE_NODE }, \
+ { "vm", CTLTYPE_NODE }, \
+ { "vfs", CTLTYPE_NODE }, \
+ { "net", CTLTYPE_NODE }, \
+ { "debug", CTLTYPE_NODE }, \
+ { "hw", CTLTYPE_NODE }, \
+ { "machdep", CTLTYPE_NODE }, \
+ { "user", CTLTYPE_NODE }, \
+ { "p1003_1b", CTLTYPE_NODE }, \
+}
+
+/*
+ * CTL_KERN identifiers
+ */
+#define KERN_OSTYPE 1 /* string: system version */
+#define KERN_OSRELEASE 2 /* string: system release */
+#define KERN_OSREV 3 /* int: system revision */
+#define KERN_VERSION 4 /* string: compile time info */
+#define KERN_MAXVNODES 5 /* int: max vnodes */
+#define KERN_MAXPROC 6 /* int: max processes */
+#define KERN_MAXFILES 7 /* int: max open files */
+#define KERN_ARGMAX 8 /* int: max arguments to exec */
+#define KERN_SECURELVL 9 /* int: system security level */
+#define KERN_HOSTNAME 10 /* string: hostname */
+#define KERN_HOSTID 11 /* int: host identifier */
+#define KERN_CLOCKRATE 12 /* struct: struct clockrate */
+#define KERN_VNODE 13 /* struct: vnode structures */
+#define KERN_PROC 14 /* struct: process entries */
+#define KERN_FILE 15 /* struct: file entries */
+#define KERN_PROF 16 /* node: kernel profiling info */
+#define KERN_POSIX1 17 /* int: POSIX.1 version */
+#define KERN_NGROUPS 18 /* int: # of supplemental group ids */
+#define KERN_JOB_CONTROL 19 /* int: is job control available */
+#define KERN_SAVED_IDS 20 /* int: saved set-user/group-ID */
+#define KERN_BOOTTIME 21 /* struct: time kernel was booted */
+#define KERN_NISDOMAINNAME 22 /* string: YP domain name */
+#define KERN_UPDATEINTERVAL 23 /* int: update process sleep time */
+#define KERN_OSRELDATE 24 /* int: kernel release date */
+#define KERN_NTP_PLL 25 /* node: NTP PLL control */
+#define KERN_BOOTFILE 26 /* string: name of booted kernel */
+#define KERN_MAXFILESPERPROC 27 /* int: max open files per proc */
+#define KERN_MAXPROCPERUID 28 /* int: max processes per uid */
+#define KERN_DUMPDEV 29 /* struct cdev *: device to dump on */
+#define KERN_IPC 30 /* node: anything related to IPC */
+#define KERN_DUMMY 31 /* unused */
+#define KERN_PS_STRINGS 32 /* int: address of PS_STRINGS */
+#define KERN_USRSTACK 33 /* int: address of USRSTACK */
+#define KERN_LOGSIGEXIT 34 /* int: do we log sigexit procs? */
+#define KERN_IOV_MAX 35 /* int: value of UIO_MAXIOV */
+#define KERN_MAXID 36 /* number of valid kern ids */
+
+#define CTL_KERN_NAMES { \
+ { 0, 0 }, \
+ { "ostype", CTLTYPE_STRING }, \
+ { "osrelease", CTLTYPE_STRING }, \
+ { "osrevision", CTLTYPE_INT }, \
+ { "version", CTLTYPE_STRING }, \
+ { "maxvnodes", CTLTYPE_INT }, \
+ { "maxproc", CTLTYPE_INT }, \
+ { "maxfiles", CTLTYPE_INT }, \
+ { "argmax", CTLTYPE_INT }, \
+ { "securelevel", CTLTYPE_INT }, \
+ { "hostname", CTLTYPE_STRING }, \
+ { "hostid", CTLTYPE_UINT }, \
+ { "clockrate", CTLTYPE_STRUCT }, \
+ { "vnode", CTLTYPE_STRUCT }, \
+ { "proc", CTLTYPE_STRUCT }, \
+ { "file", CTLTYPE_STRUCT }, \
+ { "profiling", CTLTYPE_NODE }, \
+ { "posix1version", CTLTYPE_INT }, \
+ { "ngroups", CTLTYPE_INT }, \
+ { "job_control", CTLTYPE_INT }, \
+ { "saved_ids", CTLTYPE_INT }, \
+ { "boottime", CTLTYPE_STRUCT }, \
+ { "nisdomainname", CTLTYPE_STRING }, \
+ { "update", CTLTYPE_INT }, \
+ { "osreldate", CTLTYPE_INT }, \
+ { "ntp_pll", CTLTYPE_NODE }, \
+ { "bootfile", CTLTYPE_STRING }, \
+ { "maxfilesperproc", CTLTYPE_INT }, \
+ { "maxprocperuid", CTLTYPE_INT }, \
+ { "ipc", CTLTYPE_NODE }, \
+ { "dummy", CTLTYPE_INT }, \
+ { "ps_strings", CTLTYPE_INT }, \
+ { "usrstack", CTLTYPE_INT }, \
+ { "logsigexit", CTLTYPE_INT }, \
+ { "iov_max", CTLTYPE_INT }, \
+}
+
+/*
+ * CTL_VFS identifiers
+ */
+#define CTL_VFS_NAMES { \
+ { "vfsconf", CTLTYPE_STRUCT }, \
+}
+
+/*
+ * KERN_PROC subtypes
+ */
+#define KERN_PROC_ALL 0 /* everything */
+#define KERN_PROC_PID 1 /* by process id */
+#define KERN_PROC_PGRP 2 /* by process group id */
+#define KERN_PROC_SESSION 3 /* by session of pid */
+#define KERN_PROC_TTY 4 /* by controlling tty */
+#define KERN_PROC_UID 5 /* by effective uid */
+#define KERN_PROC_RUID 6 /* by real uid */
+#define KERN_PROC_ARGS 7 /* get/set arguments/proctitle */
+#define KERN_PROC_PROC 8 /* only return procs */
+#define KERN_PROC_SV_NAME 9 /* get syscall vector name */
+#define KERN_PROC_RGID 10 /* by real group id */
+#define KERN_PROC_GID 11 /* by effective group id */
+#define KERN_PROC_INC_THREAD 0x10 /*
+ * modifier for pid, pgrp, tty,
+ * uid, ruid, gid, rgid and proc
+ */
+
+/*
+ * KERN_IPC identifiers
+ */
+#define KIPC_MAXSOCKBUF 1 /* int: max size of a socket buffer */
+#define KIPC_SOCKBUF_WASTE 2 /* int: wastage factor in sockbuf */
+#define KIPC_SOMAXCONN 3 /* int: max length of connection q */
+#define KIPC_MAX_LINKHDR 4 /* int: max length of link header */
+#define KIPC_MAX_PROTOHDR 5 /* int: max length of network header */
+#define KIPC_MAX_HDR 6 /* int: max total length of headers */
+#define KIPC_MAX_DATALEN 7 /* int: max length of data? */
+
+/*
+ * CTL_HW identifiers
+ */
+#define HW_MACHINE 1 /* string: machine class */
+#define HW_MODEL 2 /* string: specific machine model */
+#define HW_NCPU 3 /* int: number of cpus */
+#define HW_BYTEORDER 4 /* int: machine byte order */
+#define HW_PHYSMEM 5 /* int: total memory */
+#define HW_USERMEM 6 /* int: non-kernel memory */
+#define HW_PAGESIZE 7 /* int: software page size */
+#define HW_DISKNAMES 8 /* strings: disk drive names */
+#define HW_DISKSTATS 9 /* struct: diskstats[] */
+#define HW_FLOATINGPT 10 /* int: has HW floating point? */
+#define HW_MACHINE_ARCH 11 /* string: machine architecture */
+#define HW_MAXID 12 /* number of valid hw ids */
+
+#define CTL_HW_NAMES { \
+ { 0, 0 }, \
+ { "machine", CTLTYPE_STRING }, \
+ { "model", CTLTYPE_STRING }, \
+ { "ncpu", CTLTYPE_INT }, \
+ { "byteorder", CTLTYPE_INT }, \
+ { "physmem", CTLTYPE_ULONG }, \
+ { "usermem", CTLTYPE_ULONG }, \
+ { "pagesize", CTLTYPE_INT }, \
+ { "disknames", CTLTYPE_STRUCT }, \
+ { "diskstats", CTLTYPE_STRUCT }, \
+ { "floatingpoint", CTLTYPE_INT }, \
+}
+
+/*
+ * CTL_USER definitions
+ */
+#define USER_CS_PATH 1 /* string: _CS_PATH */
+#define USER_BC_BASE_MAX 2 /* int: BC_BASE_MAX */
+#define USER_BC_DIM_MAX 3 /* int: BC_DIM_MAX */
+#define USER_BC_SCALE_MAX 4 /* int: BC_SCALE_MAX */
+#define USER_BC_STRING_MAX 5 /* int: BC_STRING_MAX */
+#define USER_COLL_WEIGHTS_MAX 6 /* int: COLL_WEIGHTS_MAX */
+#define USER_EXPR_NEST_MAX 7 /* int: EXPR_NEST_MAX */
+#define USER_LINE_MAX 8 /* int: LINE_MAX */
+#define USER_RE_DUP_MAX 9 /* int: RE_DUP_MAX */
+#define USER_POSIX2_VERSION 10 /* int: POSIX2_VERSION */
+#define USER_POSIX2_C_BIND 11 /* int: POSIX2_C_BIND */
+#define USER_POSIX2_C_DEV 12 /* int: POSIX2_C_DEV */
+#define USER_POSIX2_CHAR_TERM 13 /* int: POSIX2_CHAR_TERM */
+#define USER_POSIX2_FORT_DEV 14 /* int: POSIX2_FORT_DEV */
+#define USER_POSIX2_FORT_RUN 15 /* int: POSIX2_FORT_RUN */
+#define USER_POSIX2_LOCALEDEF 16 /* int: POSIX2_LOCALEDEF */
+#define USER_POSIX2_SW_DEV 17 /* int: POSIX2_SW_DEV */
+#define USER_POSIX2_UPE 18 /* int: POSIX2_UPE */
+#define USER_STREAM_MAX 19 /* int: POSIX2_STREAM_MAX */
+#define USER_TZNAME_MAX 20 /* int: POSIX2_TZNAME_MAX */
+#define USER_MAXID 21 /* number of valid user ids */
+
+#define CTL_USER_NAMES { \
+ { 0, 0 }, \
+ { "cs_path", CTLTYPE_STRING }, \
+ { "bc_base_max", CTLTYPE_INT }, \
+ { "bc_dim_max", CTLTYPE_INT }, \
+ { "bc_scale_max", CTLTYPE_INT }, \
+ { "bc_string_max", CTLTYPE_INT }, \
+ { "coll_weights_max", CTLTYPE_INT }, \
+ { "expr_nest_max", CTLTYPE_INT }, \
+ { "line_max", CTLTYPE_INT }, \
+ { "re_dup_max", CTLTYPE_INT }, \
+ { "posix2_version", CTLTYPE_INT }, \
+ { "posix2_c_bind", CTLTYPE_INT }, \
+ { "posix2_c_dev", CTLTYPE_INT }, \
+ { "posix2_char_term", CTLTYPE_INT }, \
+ { "posix2_fort_dev", CTLTYPE_INT }, \
+ { "posix2_fort_run", CTLTYPE_INT }, \
+ { "posix2_localedef", CTLTYPE_INT }, \
+ { "posix2_sw_dev", CTLTYPE_INT }, \
+ { "posix2_upe", CTLTYPE_INT }, \
+ { "stream_max", CTLTYPE_INT }, \
+ { "tzname_max", CTLTYPE_INT }, \
+}
+
+#define CTL_P1003_1B_ASYNCHRONOUS_IO 1 /* boolean */
+#define CTL_P1003_1B_MAPPED_FILES 2 /* boolean */
+#define CTL_P1003_1B_MEMLOCK 3 /* boolean */
+#define CTL_P1003_1B_MEMLOCK_RANGE 4 /* boolean */
+#define CTL_P1003_1B_MEMORY_PROTECTION 5 /* boolean */
+#define CTL_P1003_1B_MESSAGE_PASSING 6 /* boolean */
+#define CTL_P1003_1B_PRIORITIZED_IO 7 /* boolean */
+#define CTL_P1003_1B_PRIORITY_SCHEDULING 8 /* boolean */
+#define CTL_P1003_1B_REALTIME_SIGNALS 9 /* boolean */
+#define CTL_P1003_1B_SEMAPHORES 10 /* boolean */
+#define CTL_P1003_1B_FSYNC 11 /* boolean */
+#define CTL_P1003_1B_SHARED_MEMORY_OBJECTS 12 /* boolean */
+#define CTL_P1003_1B_SYNCHRONIZED_IO 13 /* boolean */
+#define CTL_P1003_1B_TIMERS 14 /* boolean */
+#define CTL_P1003_1B_AIO_LISTIO_MAX 15 /* int */
+#define CTL_P1003_1B_AIO_MAX 16 /* int */
+#define CTL_P1003_1B_AIO_PRIO_DELTA_MAX 17 /* int */
+#define CTL_P1003_1B_DELAYTIMER_MAX 18 /* int */
+#define CTL_P1003_1B_MQ_OPEN_MAX 19 /* int */
+#define CTL_P1003_1B_PAGESIZE 20 /* int */
+#define CTL_P1003_1B_RTSIG_MAX 21 /* int */
+#define CTL_P1003_1B_SEM_NSEMS_MAX 22 /* int */
+#define CTL_P1003_1B_SEM_VALUE_MAX 23 /* int */
+#define CTL_P1003_1B_SIGQUEUE_MAX 24 /* int */
+#define CTL_P1003_1B_TIMER_MAX 25 /* int */
+
+#define CTL_P1003_1B_MAXID 26
+
+#define CTL_P1003_1B_NAMES { \
+ { 0, 0 }, \
+ { "asynchronous_io", CTLTYPE_INT }, \
+ { "mapped_files", CTLTYPE_INT }, \
+ { "memlock", CTLTYPE_INT }, \
+ { "memlock_range", CTLTYPE_INT }, \
+ { "memory_protection", CTLTYPE_INT }, \
+ { "message_passing", CTLTYPE_INT }, \
+ { "prioritized_io", CTLTYPE_INT }, \
+ { "priority_scheduling", CTLTYPE_INT }, \
+ { "realtime_signals", CTLTYPE_INT }, \
+ { "semaphores", CTLTYPE_INT }, \
+ { "fsync", CTLTYPE_INT }, \
+ { "shared_memory_objects", CTLTYPE_INT }, \
+ { "synchronized_io", CTLTYPE_INT }, \
+ { "timers", CTLTYPE_INT }, \
+ { "aio_listio_max", CTLTYPE_INT }, \
+ { "aio_max", CTLTYPE_INT }, \
+ { "aio_prio_delta_max", CTLTYPE_INT }, \
+ { "delaytimer_max", CTLTYPE_INT }, \
+ { "mq_open_max", CTLTYPE_INT }, \
+ { "pagesize", CTLTYPE_INT }, \
+ { "rtsig_max", CTLTYPE_INT }, \
+ { "nsems_max", CTLTYPE_INT }, \
+ { "sem_value_max", CTLTYPE_INT }, \
+ { "sigqueue_max", CTLTYPE_INT }, \
+ { "timer_max", CTLTYPE_INT }, \
+}
+
+#ifdef _KERNEL
+
+/*
+ * Declare some common oids.
+ */
+extern struct sysctl_oid_list sysctl__children;
+SYSCTL_DECL(_kern);
+SYSCTL_DECL(_sysctl);
+SYSCTL_DECL(_vm);
+SYSCTL_DECL(_vfs);
+SYSCTL_DECL(_net);
+SYSCTL_DECL(_debug);
+SYSCTL_DECL(_debug_sizeof);
+SYSCTL_DECL(_hw);
+SYSCTL_DECL(_machdep);
+SYSCTL_DECL(_user);
+SYSCTL_DECL(_compat);
+
+extern char machine[];
+extern char osrelease[];
+extern char ostype[];
+extern char kern_ident[];
+
+/* Dynamic oid handling */
+struct sysctl_oid *sysctl_add_oid(struct sysctl_ctx_list *clist,
+ struct sysctl_oid_list *parent, int nbr, const char *name,
+ int kind, void *arg1, int arg2,
+ int (*handler) (SYSCTL_HANDLER_ARGS),
+ const char *fmt, const char *descr);
+int sysctl_move_oid(struct sysctl_oid *oidp,
+ struct sysctl_oid_list *parent);
+int sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse);
+int sysctl_ctx_init(struct sysctl_ctx_list *clist);
+int sysctl_ctx_free(struct sysctl_ctx_list *clist);
+struct sysctl_ctx_entry *sysctl_ctx_entry_add(struct sysctl_ctx_list *clist,
+ struct sysctl_oid *oidp);
+struct sysctl_ctx_entry *sysctl_ctx_entry_find(struct sysctl_ctx_list *clist,
+ struct sysctl_oid *oidp);
+int sysctl_ctx_entry_del(struct sysctl_ctx_list *clist,
+ struct sysctl_oid *oidp);
+
+int kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
+ size_t *oldlenp, void *new, size_t newlen,
+ size_t *retval);
+int kernel_sysctlbyname(struct thread *td, char *name,
+ void *old, size_t *oldlenp, void *new, size_t newlen,
+ size_t *retval);
+int userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
+ size_t *oldlenp, int inkernel, void *new, size_t newlen,
+ size_t *retval);
+int sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
+ int *nindx, struct sysctl_req *req);
+int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len);
+
+#else /* !_KERNEL */
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int sysctl(int *, u_int, void *, size_t *, void *, size_t);
+int sysctlbyname(const char *, void *, size_t *, void *, size_t);
+int sysctlnametomib(const char *, int *, size_t *);
+__END_DECLS
+#endif /* _KERNEL */
+
+#endif /* !_SYS_SYSCTL_H_ */
diff --git a/cpukit/libnetworking/sys/syslog.h b/cpukit/libnetworking/sys/syslog.h
new file mode 100644
index 0000000000..affce6887e
--- /dev/null
+++ b/cpukit/libnetworking/sys/syslog.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 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.
+ * 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.
+ *
+ * @(#)syslog.h 8.1 (Berkeley) 6/2/93
+ * $FreeBSD: src/sys/sys/syslog.h,v 1.26 2005/01/07 02:29:24 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _SYS_SYSLOG_H_
+#define _SYS_SYSLOG_H_
+
+#define _PATH_LOG "/var/run/log"
+#define _PATH_OLDLOG "/dev/log" /* backward compatibility */
+
+/*
+ * priorities/facilities are encoded into a single 32-bit quantity, where the
+ * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
+ * (0-big number). Both the priorities and the facilities map roughly
+ * one-to-one to strings in the syslogd(8) source code. This mapping is
+ * included in this file.
+ *
+ * priorities (these are ordered)
+ */
+#define LOG_EMERG 0 /* system is unusable */
+#define LOG_ALERT 1 /* action must be taken immediately */
+#define LOG_CRIT 2 /* critical conditions */
+#define LOG_ERR 3 /* error conditions */
+#define LOG_WARNING 4 /* warning conditions */
+#define LOG_NOTICE 5 /* normal but significant condition */
+#define LOG_INFO 6 /* informational */
+#define LOG_DEBUG 7 /* debug-level messages */
+
+#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */
+ /* extract priority */
+#define LOG_PRI(p) ((p) & LOG_PRIMASK)
+#define LOG_MAKEPRI(fac, pri) ((fac) | (pri))
+
+#ifdef SYSLOG_NAMES
+#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */
+ /* mark "facility" */
+#define INTERNAL_MARK LOG_MAKEPRI((LOG_NFACILITIES<<3), 0)
+typedef struct _code {
+ const char *c_name;
+ int c_val;
+} CODE;
+
+CODE prioritynames[] = {
+ { "alert", LOG_ALERT, },
+ { "crit", LOG_CRIT, },
+ { "debug", LOG_DEBUG, },
+ { "emerg", LOG_EMERG, },
+ { "err", LOG_ERR, },
+ { "error", LOG_ERR, }, /* DEPRECATED */
+ { "info", LOG_INFO, },
+ { "none", INTERNAL_NOPRI, }, /* INTERNAL */
+ { "notice", LOG_NOTICE, },
+ { "panic", LOG_EMERG, }, /* DEPRECATED */
+ { "warn", LOG_WARNING, }, /* DEPRECATED */
+ { "warning", LOG_WARNING, },
+ { NULL, -1, }
+};
+#endif
+
+/* facility codes */
+#define LOG_KERN (0<<3) /* kernel messages */
+#define LOG_USER (1<<3) /* random user-level messages */
+#define LOG_MAIL (2<<3) /* mail system */
+#define LOG_DAEMON (3<<3) /* system daemons */
+#define LOG_AUTH (4<<3) /* authorization messages */
+#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
+#define LOG_LPR (6<<3) /* line printer subsystem */
+#define LOG_NEWS (7<<3) /* network news subsystem */
+#define LOG_UUCP (8<<3) /* UUCP subsystem */
+#define LOG_CRON (9<<3) /* clock daemon */
+#define LOG_AUTHPRIV (10<<3) /* authorization messages (private) */
+ /* Facility #10 clashes in DEC UNIX, where */
+ /* it's defined as LOG_MEGASAFE for AdvFS */
+ /* event logging. */
+#define LOG_FTP (11<<3) /* ftp daemon */
+#define LOG_NTP (12<<3) /* NTP subsystem */
+
+ /* other codes through 15 reserved for system use */
+#define LOG_LOCAL0 (16<<3) /* reserved for local use */
+#define LOG_LOCAL1 (17<<3) /* reserved for local use */
+#define LOG_LOCAL2 (18<<3) /* reserved for local use */
+#define LOG_LOCAL3 (19<<3) /* reserved for local use */
+#define LOG_LOCAL4 (20<<3) /* reserved for local use */
+#define LOG_LOCAL5 (21<<3) /* reserved for local use */
+#define LOG_LOCAL6 (22<<3) /* reserved for local use */
+#define LOG_LOCAL7 (23<<3) /* reserved for local use */
+
+#define LOG_NFACILITIES 24 /* current number of facilities */
+#define LOG_FACMASK 0x03f8 /* mask to extract facility part */
+ /* facility of pri */
+#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
+
+#ifdef SYSLOG_NAMES
+CODE facilitynames[] = {
+ { "auth", LOG_AUTH, },
+ { "authpriv", LOG_AUTHPRIV, },
+ { "cron", LOG_CRON, },
+ { "daemon", LOG_DAEMON, },
+ { "ftp", LOG_FTP, },
+ { "kern", LOG_KERN, },
+ { "lpr", LOG_LPR, },
+ { "mail", LOG_MAIL, },
+ { "mark", INTERNAL_MARK, }, /* INTERNAL */
+ { "news", LOG_NEWS, },
+ { "ntp", LOG_NTP, },
+ { "security", LOG_AUTH, }, /* DEPRECATED */
+ { "syslog", LOG_SYSLOG, },
+ { "user", LOG_USER, },
+ { "uucp", LOG_UUCP, },
+ { "local0", LOG_LOCAL0, },
+ { "local1", LOG_LOCAL1, },
+ { "local2", LOG_LOCAL2, },
+ { "local3", LOG_LOCAL3, },
+ { "local4", LOG_LOCAL4, },
+ { "local5", LOG_LOCAL5, },
+ { "local6", LOG_LOCAL6, },
+ { "local7", LOG_LOCAL7, },
+ { NULL, -1, }
+};
+#endif
+
+#ifdef _KERNEL
+#define LOG_PRINTF -1 /* pseudo-priority to indicate use of printf */
+#endif
+
+/*
+ * arguments to setlogmask.
+ */
+#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */
+#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */
+
+/*
+ * Option flags for openlog.
+ *
+ * LOG_ODELAY no longer does anything.
+ * LOG_NDELAY is the inverse of what it used to be.
+ */
+#define LOG_PID 0x01 /* log the pid with each message */
+#define LOG_CONS 0x02 /* log on the console if errors in sending */
+#define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */
+#define LOG_NDELAY 0x08 /* don't delay open */
+#define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */
+#define LOG_PERROR 0x20 /* log to stderr as well */
+
+#ifdef _KERNEL
+
+#else /* not _KERNEL */
+
+#include <sys/cdefs.h>
+#include <stdarg.h>
+
+__BEGIN_DECLS
+void closelog(void);
+void openlog(const char *, int, int);
+int setlogmask(int);
+void syslog(int, const char *, ...);
+void vsyslog(int, const char *, va_list);
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif
diff --git a/cpukit/libnetworking/sys/systm.h b/cpukit/libnetworking/sys/systm.h
new file mode 100644
index 0000000000..3363140dbe
--- /dev/null
+++ b/cpukit/libnetworking/sys/systm.h
@@ -0,0 +1,199 @@
+/*-
+ * Copyright (c) 1982, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ *
+ * @(#)systm.h 8.7 (Berkeley) 3/29/95
+ * $Id$
+ */
+
+#ifndef _SYS_SYSTM_H_
+#define _SYS_SYSTM_H_
+
+#include <rtems/rtems_bsdnet_internal.h> /* for __BSD_VA_LIST__ */
+#include <machine/cpufunc.h>
+
+extern int securelevel; /* system security level (see init(8)) */
+
+extern int cold; /* nonzero if we are doing a cold boot */
+extern const char *panicstr; /* panic message */
+extern char version[]; /* system version */
+extern char copyright[]; /* system copyright */
+
+extern int nblkdev; /* number of entries in bdevsw */
+extern int nchrdev; /* number of entries in cdevsw */
+extern struct swdevt *swdevt; /* swap-device information */
+extern int nswdev; /* number of swap devices */
+extern int nswap; /* size of swap space */
+
+extern int selwait; /* select timeout address */
+
+extern u_char curpriority; /* priority of current process */
+
+extern int physmem; /* physical memory */
+
+extern dev_t dumpdev; /* dump device */
+extern long dumplo; /* offset into dumpdev */
+
+extern dev_t rootdev; /* root device */
+extern struct vnode *rootvp; /* vnode equivalent to above */
+
+extern dev_t swapdev; /* swapping device */
+extern struct vnode *swapdev_vp;/* vnode equivalent to above */
+
+extern int boothowto; /* reboot flags, from console subsystem */
+extern int bootverbose; /* nonzero to print verbose messages */
+
+/*
+ * General function declarations.
+ */
+void Debugger __P((const char *msg));
+int nullop __P((void));
+int eopnotsupp __P((void));
+int einval __P((void));
+int seltrue __P((dev_t dev, int which, struct proc *p));
+int ureadc __P((int, struct uio *));
+void *hashinit __P((int count, int type, u_long *hashmask));
+void *phashinit __P((int count, int type, u_long *nentries));
+
+void panic __P((const char *, ...)) __dead2;
+void boot __P((int)) __dead2;
+void cpu_boot __P((int));
+void tablefull __P((const char *));
+int addlog __P((const char *, ...));
+int kvprintf __P((char const *, void (*)(int, void*), void *, int,
+ _BSD_VA_LIST_));
+void log __P((int, const char *, ...));
+int printf __P((const char *, ...));
+int sprintf __P((char *buf, const char *, ...));
+void uprintf __P((const char *, ...));
+void ttyprintf __P((struct tty *, const char *, ...));
+
+#define bcopy(f,t,n) memcpy((t),(f),(n))
+#define bzero(p,n) memset((p),(0),(n))
+
+int copystr __P((const void *kfaddr, void *kdaddr, size_t len,
+ size_t *lencopied));
+int copyinstr __P((const void *udaddr, void *kaddr, size_t len,
+ size_t *lencopied));
+int copyin __P((const void *udaddr, void *kaddr, size_t len));
+int copyout __P((const void *kaddr, void *udaddr, size_t len));
+
+int fubyte __P((const void *base));
+int fuibyte __P((const void *base));
+int subyte __P((void *base, int byte));
+int suibyte __P((void *base, int byte));
+int fuword __P((const void *base));
+int suword __P((void *base, int word));
+int susword __P((void *base, int word));
+
+int hzto __P((struct timeval *tv));
+void realitexpire __P((void *));
+
+struct clockframe;
+void hardclock __P((struct clockframe *frame));
+void softclock __P((void));
+void statclock __P((struct clockframe *frame));
+
+void startprofclock __P((struct proc *));
+void stopprofclock __P((struct proc *));
+void setstatclockrate __P((int hzrate));
+
+void hardupdate __P((long));
+void hardpps __P((struct timeval *tvp, long usec));
+
+#include <sys/libkern.h>
+
+/* Initialize the world */
+extern void consinit(void);
+extern void usrinfoinit(void);
+extern void cpu_initclocks(void);
+extern void vntblinit(void);
+extern void nchinit(void);
+
+/* Finalize the world. */
+void shutdown_nice __P((void));
+
+/*
+ * Kernel to clock driver interface.
+ */
+void inittodr __P((time_t base));
+void resettodr __P((void));
+void startrtclock __P((void));
+
+/* Timeouts */
+typedef void (timeout_t)(void *); /* actual timeout function type */
+typedef timeout_t *timeout_func_t; /* a pointer to this type */
+
+void timeout(timeout_func_t, void *, int);
+void untimeout(timeout_func_t, void *);
+void logwakeup __P((void));
+
+/* Various other callout lists that modules might want to know about */
+/* shutdown callout list definitions */
+typedef void (*bootlist_fn)(int,void *);
+int at_shutdown(bootlist_fn function, void *arg, int);
+int rm_at_shutdown(bootlist_fn function, void *arg);
+#define SHUTDOWN_PRE_SYNC 0
+#define SHUTDOWN_POST_SYNC 1
+
+/* forking */ /* XXX not yet */
+typedef void (*forklist_fn)(struct proc *parent,struct proc *child,int flags);
+int at_fork(forklist_fn function);
+int rm_at_fork(forklist_fn function);
+
+/* exiting */
+typedef void (*exitlist_fn)(struct proc *procp);
+int at_exit(exitlist_fn function);
+int rm_at_exit(exitlist_fn function);
+
+/* Not exactly a callout LIST, but a callout entry.. */
+/* Allow an external module to define a hardware watchdog tickler */
+/* Normally a process would do this, but there are times when the */
+/* kernel needs to be able to hold off the watchdog, when the process */
+/* is not active, e.g. when dumping core. Costs us a whole 4 bytes to */
+/* make this generic. the variable is in kern_shutdown.c */
+typedef void (*watchdog_tickle_fn)(void);
+extern watchdog_tickle_fn wdog_tickler;
+
+
+/*
+ * Common `proc' functions are declared here so that proc.h can be included
+ * less often.
+ */
+int tsleep __P((void *chan, int pri, char *wmesg, int timo));
+void wakeup __P((void *chan));
+
+#endif /* !_SYS_SYSTM_H_ */
diff --git a/cpukit/libnetworking/sys/ttydefaults.h b/cpukit/libnetworking/sys/ttydefaults.h
new file mode 100644
index 0000000000..68f0ddbe77
--- /dev/null
+++ b/cpukit/libnetworking/sys/ttydefaults.h
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ *
+ * @(#)ttydefaults.h 8.4 (Berkeley) 1/21/94
+ * $Id$
+ */
+
+/*
+ * System wide defaults for terminal state.
+ */
+#ifndef _SYS_TTYDEFAULTS_H_
+#define _SYS_TTYDEFAULTS_H_
+
+/*
+ * Defaults on "first" open.
+ */
+#define TTYDEF_IFLAG (BRKINT | ICRNL | IMAXBEL | IXON | IXANY)
+#define TTYDEF_OFLAG (OPOST | ONLCR)
+#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)
+#define TTYDEF_CFLAG (CREAD | CS8 | HUPCL)
+#define TTYDEF_SPEED (B9600)
+
+/*
+ * Control Character Defaults
+ */
+#define CTRL(x) (x&037)
+#define CEOF CTRL('d')
+#define CEOL 0xff /* XXX avoid _POSIX_VDISABLE */
+#define CERASE 0177
+#define CINTR CTRL('c')
+#define CSTATUS CTRL('t')
+#define CKILL CTRL('u')
+#define CMIN 1
+#define CQUIT 034 /* FS, ^\ */
+#define CSUSP CTRL('z')
+#define CTIME 0
+#define CDSUSP CTRL('y')
+#define CSTART CTRL('q')
+#define CSTOP CTRL('s')
+#define CLNEXT CTRL('v')
+#define CDISCARD CTRL('o')
+#define CWERASE CTRL('w')
+#define CREPRINT CTRL('r')
+#define CEOT CEOF
+/* compat */
+#define CBRK CEOL
+#define CRPRNT CREPRINT
+#define CFLUSH CDISCARD
+
+/* PROTECTED INCLUSION ENDS HERE */
+#endif /* !_SYS_TTYDEFAULTS_H_ */
+
+/*
+ * #define TTYDEFCHARS to include an array of default control characters.
+ */
+#ifdef TTYDEFCHARS
+static cc_t ttydefchars[NCCS] = {
+ CEOF, CEOL, CEOL, CERASE, CWERASE, CKILL, CREPRINT,
+ _POSIX_VDISABLE, CINTR, CQUIT, CSUSP, CDSUSP, CSTART, CSTOP, CLNEXT,
+ CDISCARD, CMIN, CTIME, CSTATUS, _POSIX_VDISABLE
+};
+#undef TTYDEFCHARS
+#endif
diff --git a/cpukit/libnetworking/sys/ucred.h b/cpukit/libnetworking/sys/ucred.h
new file mode 100644
index 0000000000..5da8b344d0
--- /dev/null
+++ b/cpukit/libnetworking/sys/ucred.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1989, 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.
+ *
+ * @(#)ucred.h 8.4 (Berkeley) 1/9/95
+ * $Id$
+ */
+
+#ifndef _SYS_UCRED_H_
+#define _SYS_UCRED_H_
+
+/*
+ * Credentials.
+ */
+struct ucred {
+ u_short cr_ref; /* reference count */
+ uid_t cr_uid; /* effective user id */
+ short cr_ngroups; /* number of groups */
+ gid_t cr_groups[NGROUPS]; /* groups */
+};
+#define cr_gid cr_groups[0]
+#define NOCRED ((struct ucred *)0) /* no credential available */
+#define FSCRED ((struct ucred *)-1) /* filesystem credential */
+
+#ifdef _KERNEL
+#define crhold(cr) (cr)->cr_ref++
+
+struct ucred *crcopy __P((struct ucred *cr));
+struct ucred *crdup __P((struct ucred *cr));
+void crfree __P((struct ucred *cr));
+struct ucred *crget __P((void));
+int suser __P((struct ucred *cred, u_short *acflag));
+int groupmember __P((gid_t gid, struct ucred *cred));
+#endif /* _KERNEL */
+
+#endif /* !_SYS_UCRED_H_ */
diff --git a/cpukit/libnetworking/sys/uio.h b/cpukit/libnetworking/sys/uio.h
new file mode 100644
index 0000000000..50047c58f4
--- /dev/null
+++ b/cpukit/libnetworking/sys/uio.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1982, 1986, 1993, 1994
+ * 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.
+ * 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.
+ *
+ * @(#)uio.h 8.5 (Berkeley) 2/22/94
+ * $FreeBSD: src/sys/sys/uio.h,v 1.38 2005/01/07 02:29:24 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _SYS_UIO_H_
+#define _SYS_UIO_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * XXX
+ * iov_base should be a void *.
+ */
+struct iovec {
+ char *iov_base; /* Base address. */
+ size_t iov_len; /* Length. */
+};
+
+#if __BSD_VISIBLE
+enum uio_rw { UIO_READ, UIO_WRITE };
+
+/* Segment flag values. */
+enum uio_seg {
+ UIO_USERSPACE, /* from user data space */
+ UIO_SYSSPACE, /* from system space */
+ UIO_USERISPACE, /* from user I space */
+ UIO_NOCOPY /* don't copy, already in object */
+};
+#endif
+
+#ifdef _KERNEL
+
+struct uio {
+ struct iovec *uio_iov;
+ int uio_iovcnt;
+ off_t uio_offset;
+ int uio_resid;
+ enum uio_seg uio_segflg;
+ enum uio_rw uio_rw;
+ struct proc *uio_procp;
+};
+
+/*
+ * Limits
+ *
+ * N.B.: UIO_MAXIOV must be no less than IOV_MAX from <sys/syslimits.h>
+ * which in turn must be no less than _XOPEN_IOV_MAX from <limits.h>. If
+ * we ever make this tunable (probably pointless), then IOV_MAX should be
+ * removed from <sys/syslimits.h> and applications would be expected to use
+ * sysconf(3) to find out the correct value, or else assume the worst
+ * (_XOPEN_IOV_MAX). Perhaps UIO_MAXIOV should be simply defined as
+ * IOV_MAX.
+ */
+#define UIO_MAXIOV 1024 /* max 1K of iov's */
+
+int uiomove(void *cp, int n, struct uio *uio);
+
+#else /* !_KERNEL */
+
+__BEGIN_DECLS
+ssize_t readv(int, const struct iovec *, int);
+ssize_t writev(int, const struct iovec *, int);
+__END_DECLS
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_UIO_H_ */
diff --git a/cpukit/libnetworking/sys/un.h b/cpukit/libnetworking/sys/un.h
new file mode 100644
index 0000000000..35425ad1eb
--- /dev/null
+++ b/cpukit/libnetworking/sys/un.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1982, 1986, 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.
+ * 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.
+ *
+ * @(#)un.h 8.3 (Berkeley) 2/19/95
+ * $FreeBSD: src/sys/sys/un.h,v 1.29 2005/04/13 00:01:46 mdodd Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _SYS_UN_H_
+#define _SYS_UN_H_
+
+#include <sys/cdefs.h>
+#include <rtems/bsdnet/_types.h>
+
+#ifndef _SA_FAMILY_T_DECLARED
+typedef __sa_family_t sa_family_t;
+#define _SA_FAMILY_T_DECLARED
+#endif
+
+/*
+ * Definitions for UNIX IPC domain.
+ */
+struct sockaddr_un {
+ unsigned char sun_len; /* sockaddr len including null */
+ sa_family_t sun_family; /* AF_UNIX */
+ char sun_path[104]; /* path name (gag) */
+};
+
+#if __BSD_VISIBLE
+
+/* Socket options. */
+#define LOCAL_PEERCRED 0x001 /* retrieve peer credentials */
+#define LOCAL_CREDS 0x002 /* pass credentials to receiver */
+#define LOCAL_CONNWAIT 0x004 /* connects block until accepted */
+
+#ifdef _KERNEL
+struct mbuf;
+struct socket;
+struct sockopt;
+
+#else /* !_KERNEL */
+
+/* actual length of an initialized sockaddr_un */
+#define SUN_LEN(su) \
+ (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
+
+#endif /* _KERNEL */
+
+#endif /* __BSD_VISIBLE */
+
+#endif /* !_SYS_UN_H_ */
diff --git a/cpukit/libnetworking/syslog.h b/cpukit/libnetworking/syslog.h
new file mode 100644
index 0000000000..6d223d00b7
--- /dev/null
+++ b/cpukit/libnetworking/syslog.h
@@ -0,0 +1,5 @@
+/*
+ * $Id$
+ */
+
+#include <sys/syslog.h>
diff --git a/cpukit/libnetworking/vm/vm.h b/cpukit/libnetworking/vm/vm.h
new file mode 100644
index 0000000000..7debe74a82
--- /dev/null
+++ b/cpukit/libnetworking/vm/vm.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1991, 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.
+ *
+ * @(#)vm.h 8.2 (Berkeley) 12/13/93
+ * $Id$
+ */
+
+#ifndef VM_H
+#define VM_H
+
+typedef char vm_inherit_t; /* XXX: inheritance codes */
+typedef u_char vm_prot_t; /* protection codes */
+
+union vm_map_object;
+typedef union vm_map_object vm_map_object_t;
+
+struct vm_map_entry;
+typedef struct vm_map_entry *vm_map_entry_t;
+
+struct vm_map;
+typedef struct vm_map *vm_map_t;
+
+struct vm_object;
+typedef struct vm_object *vm_object_t;
+
+#ifndef _KERNEL
+/*
+ * This is defined in <sys/types.h> for the kernel so that non-vm kernel
+ * sources (mainly Mach-derived ones such as ddb) don't have to include
+ * vm stuff. Defining it there for applications might break things.
+ * Define it here for "applications" that include vm headers (e.g.,
+ * genassym).
+ */
+typedef int boolean_t;
+
+/*
+ * This is defined in <sys/types.h> for the kernel so that vnode_if.h
+ * doesn't have to include <vm/vm.h>.
+ */
+struct vm_page;
+typedef struct vm_page *vm_page_t;
+#endif
+
+#endif /* VM_H */
diff --git a/cpukit/libnetworking/vm/vm_extern.h b/cpukit/libnetworking/vm/vm_extern.h
new file mode 100644
index 0000000000..0edb3ebb44
--- /dev/null
+++ b/cpukit/libnetworking/vm/vm_extern.h
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ * 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.
+ *
+ * @(#)vm_extern.h 8.2 (Berkeley) 1/12/94
+ * $FreeBSD: src/sys/vm/vm_extern.h,v 1.75 2004/11/20 02:29:00 das Exp $
+ */
+
+/*
+ * $Id$
+ */
+#ifndef _VM_EXTERN_H_
+#define _VM_EXTERN_H_
+
+struct buf;
+struct proc;
+struct vmspace;
+struct vmtotal;
+struct mount;
+struct vnode;
+
+#ifdef _KERNEL
+
+#ifdef TYPEDEF_FOR_UAP
+int getpagesize __P((struct proc * p, void *, int *));
+int madvise __P((struct proc *, void *, int *));
+int mincore __P((struct proc *, void *, int *));
+int mprotect __P((struct proc *, void *, int *));
+int msync __P((struct proc *, void *, int *));
+int munmap __P((struct proc *, void *, int *));
+int obreak __P((struct proc *, void *, int *));
+int sbrk __P((struct proc *, void *, int *));
+int smmap __P((struct proc *, void *, int *));
+int sstk __P((struct proc *, void *, int *));
+int swapon __P((struct proc *, void *, int *));
+#endif
+
+void faultin __P((struct proc *p));
+int grow __P((struct proc *, u_int));
+int kernacc __P((caddr_t, int, int));
+vm_offset_t kmem_alloc __P((vm_map_t, vm_size_t));
+vm_offset_t kmem_alloc_pageable __P((vm_map_t, vm_size_t));
+vm_offset_t kmem_alloc_wait __P((vm_map_t, vm_size_t));
+void kmem_free __P((vm_map_t, vm_offset_t, vm_size_t));
+void kmem_free_wakeup __P((vm_map_t, vm_offset_t, vm_size_t));
+void kmem_init __P((vm_offset_t, vm_offset_t));
+vm_offset_t kmem_malloc __P((vm_map_t, vm_size_t, boolean_t));
+vm_map_t kmem_suballoc __P((vm_map_t, vm_offset_t *, vm_offset_t *, vm_size_t, boolean_t));
+void munmapfd __P((struct proc *, int));
+int pager_cache __P((vm_object_t, boolean_t));
+int swaponvp __P((struct proc *, struct vnode *, dev_t , u_long));
+void swapout_procs __P((void));
+int useracc __P((caddr_t, int, int));
+int vm_fault __P((vm_map_t, vm_offset_t, vm_prot_t, boolean_t));
+void vm_fault_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t));
+void vm_fault_unwire __P((vm_map_t, vm_offset_t, vm_offset_t));
+int vm_fault_wire __P((vm_map_t, vm_offset_t, vm_offset_t));
+int vm_fault_user_wire __P((vm_map_t, vm_offset_t, vm_offset_t));
+int vm_fork __P((struct proc *, struct proc *));
+int vm_mmap __P((vm_map_t, vm_offset_t *, vm_size_t, vm_prot_t, vm_prot_t, int, caddr_t, vm_ooffset_t));
+vm_offset_t vm_page_alloc_contig __P((vm_offset_t, vm_offset_t, vm_offset_t, vm_offset_t));
+void vm_set_page_size __P((void));
+void vmmeter __P((void));
+struct vmspace *vmspace_alloc __P((vm_offset_t, vm_offset_t, int));
+struct vmspace *vmspace_fork __P((struct vmspace *));
+void vmspace_free __P((struct vmspace *));
+void vnode_pager_setsize __P((struct vnode *, vm_ooffset_t));
+void vnode_pager_umount __P((struct mount *));
+void vnode_pager_uncache __P((struct vnode *));
+void vslock __P((caddr_t, u_int));
+void vsunlock __P((caddr_t, u_int, int));
+void vm_object_print __P((/* db_expr_t */ int, boolean_t, /* db_expr_t */ int,
+ char *));
+void vm_fault_quick __P((caddr_t v, int prot));
+
+#endif /* _KERNEL */
+
+#endif /* !_VM_EXTERN_H_ */
diff --git a/cpukit/libnetworking/vm/vm_kern.h b/cpukit/libnetworking/vm/vm_kern.h
new file mode 100644
index 0000000000..309f503f44
--- /dev/null
+++ b/cpukit/libnetworking/vm/vm_kern.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 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.
+ *
+ * from: @(#)vm_kern.h 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1987, 1990 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Authors: Avadis Tevanian, Jr., Michael Wayne Young
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ *
+ * $FreeBSD: src/sys/vm/vm_kern.h,v 1.28 2005/01/07 02:29:27 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _VM_VM_KERN_H_
+#define _VM_VM_KERN_H_ 1
+
+/* Kernel memory management definitions. */
+extern vm_map_t buffer_map;
+extern vm_map_t kernel_map;
+extern vm_map_t kmem_map;
+extern vm_map_t clean_map;
+extern vm_map_t exec_map;
+extern vm_map_t pipe_map;
+extern u_int vm_kmem_size;
+
+#endif /* _VM_VM_KERN_H_ */
diff --git a/cpukit/libnetworking/vm/vm_param.h b/cpukit/libnetworking/vm/vm_param.h
new file mode 100644
index 0000000000..e7eac938ee
--- /dev/null
+++ b/cpukit/libnetworking/vm/vm_param.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * The Mach Operating System project at Carnegie-Mellon University.
+ *
+ * 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.
+ * 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.
+ *
+ * from: @(#)vm_param.h 8.1 (Berkeley) 6/11/93
+ *
+ *
+ * Copyright (c) 1987, 1990 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Authors: Avadis Tevanian, Jr., Michael Wayne Young
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ *
+ * $FreeBSD: src/sys/vm/vm_param.h,v 1.21 2005/01/07 02:29:27 imp Exp $
+ */
+
+/*
+ * $Id$
+ */
+
+/*
+ * Machine independent virtual memory parameters.
+ */
+
+#ifndef _VM_PARAM_
+#define _VM_PARAM_
+
+#include <machine/vmparam.h>
+
+/*
+ * CTL_VM identifiers
+ */
+#define VM_TOTAL 1 /* struct vmtotal */
+#define VM_METER VM_TOTAL/* deprecated, use VM_TOTAL */
+#define VM_LOADAVG 2 /* struct loadavg */
+#define VM_V_FREE_MIN 3 /* cnt.v_free_min */
+#define VM_V_FREE_TARGET 4 /* cnt.v_free_target */
+#define VM_V_FREE_RESERVED 5 /* cnt.v_free_reserved */
+#define VM_V_INACTIVE_TARGET 6 /* cnt.v_inactive_target */
+#define VM_V_CACHE_MIN 7 /* cnt.v_cache_max */
+#define VM_V_CACHE_MAX 8 /* cnt.v_cache_min */
+#define VM_V_PAGEOUT_FREE_MIN 9 /* cnt.v_pageout_free_min */
+#define VM_PAGEOUT_ALGORITHM 10 /* pageout algorithm */
+#define VM_SWAPPING_ENABLED 11 /* swapping enabled */
+#define VM_MAXID 12 /* number of valid vm ids */
+
+#define CTL_VM_NAMES { \
+ { 0, 0 }, \
+ { "vmtotal", CTLTYPE_STRUCT }, \
+ { "loadavg", CTLTYPE_STRUCT }, \
+ { "v_free_min", CTLTYPE_INT }, \
+ { "v_free_target", CTLTYPE_INT }, \
+ { "v_free_reserved", CTLTYPE_INT }, \
+ { "v_inactive_target", CTLTYPE_INT }, \
+ { "v_cache_min", CTLTYPE_INT }, \
+ { "v_cache_max", CTLTYPE_INT }, \
+ { "v_pageout_free_min", CTLTYPE_INT}, \
+ { "pageout_algorithm", CTLTYPE_INT}, \
+ { "swapping_enabled", CTLTYPE_INT},\
+}
+
+/*
+ * Return values from the VM routines.
+ */
+#define KERN_SUCCESS 0
+#define KERN_INVALID_ADDRESS 1
+#define KERN_PROTECTION_FAILURE 2
+#define KERN_NO_SPACE 3
+#define KERN_INVALID_ARGUMENT 4
+#define KERN_FAILURE 5
+#define KERN_RESOURCE_SHORTAGE 6
+#define KERN_NOT_RECEIVER 7
+#define KERN_NO_ACCESS 8
+
+#ifndef ASSEMBLER
+#ifdef _KERNEL
+#define num_pages(x) \
+ ((vm_offset_t)((((vm_offset_t)(x)) + PAGE_MASK) >> PAGE_SHIFT))
+extern unsigned long maxtsiz;
+extern unsigned long dfldsiz;
+extern unsigned long maxdsiz;
+extern unsigned long dflssiz;
+extern unsigned long maxssiz;
+extern unsigned long sgrowsiz;
+#endif /* _KERNEL */
+#endif /* ASSEMBLER */
+#endif /* _VM_PARAM_ */
diff --git a/cpukit/librpc/.cvsignore b/cpukit/librpc/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/librpc/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/librpc/Makefile.am b/cpukit/librpc/Makefile.am
new file mode 100644
index 0000000000..98663f8e3f
--- /dev/null
+++ b/cpukit/librpc/Makefile.am
@@ -0,0 +1,91 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+EXTRA_DIST =
+
+if LIBRPC
+include_rpcdir = $(includedir)/rpc
+
+include_rpc_HEADERS = include/rpc/auth.h include/rpc/auth_unix.h
+include_rpc_HEADERS += include/rpc/clnt.h include/rpc/clnt_stat.h \
+ include/rpc/clnt_soc.h
+include_rpc_HEADERS += include/rpc/svc.h include/rpc/svc_auth.h \
+ include/rpc/svc_soc.h
+include_rpc_HEADERS += include/rpc/pmap_clnt.h include/rpc/pmap_prot.h \
+ include/rpc/pmap_rmt.h
+include_rpc_HEADERS += include/rpc/rpc.h include/rpc/types.h \
+ include/rpc/xdr.h include/rpc/rpc_com.h include/rpc/rpc_msg.h \
+ include/rpc/rpcent.h
+
+man_MANS =
+
+noinst_LIBRARIES = libxdr.a
+libxdr_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+libxdr_a_SOURCES = src/xdr/xdr.c src/xdr/xdr_array.c src/xdr/xdr_float.c \
+ src/xdr/xdr_mem.c src/xdr/xdr_rec.c src/xdr/xdr_reference.c \
+ src/xdr/xdr_sizeof.c src/xdr/xdr_stdio.c
+endif
+
+libxdr_mans = src/xdr/xdr.3
+EXTRA_DIST += $(libxdr_mans)
+
+if LIBRPC
+man_MANS += $(libxdr_mans)
+
+noinst_LIBRARIES += librpc.a
+librpc_a_CPPFLAGS = $(AM_CPPFLAGS) $(librpc_CPPFLAGS)
+
+librpc_a_SOURCES = src/rpc/auth_none.c src/rpc/auth_unix.c \
+ src/rpc/authunix_prot.c src/rpc/bindresvport.c src/rpc/clnt_generic.c \
+ src/rpc/clnt_perror.c src/rpc/clnt_raw.c src/rpc/clnt_simple.c \
+ src/rpc/clnt_tcp.c src/rpc/clnt_udp.c src/rpc/get_myaddress.c \
+ src/rpc/getrpcent.c src/rpc/getrpcport.c src/rpc/netname.c \
+ src/rpc/netnamer.c src/rpc/pmap_clnt.c src/rpc/pmap_getmaps.c \
+ src/rpc/pmap_getport.c src/rpc/pmap_prot.c src/rpc/pmap_prot2.c \
+ src/rpc/pmap_rmt.c src/rpc/rpc_callmsg.c src/rpc/rpc_commondata.c \
+ src/rpc/rpc_dtablesize.c src/rpc/rpc_prot.c src/rpc/rpcdname.c \
+ src/rpc/rtime.c src/rpc/svc.c src/rpc/svc_auth.c src/rpc/svc_auth_unix.c \
+ src/rpc/svc_raw.c src/rpc/svc_run.c src/rpc/svc_simple.c \
+ src/rpc/svc_tcp.c src/rpc/svc_udp.c src/rpc/rtems_portmapper.c \
+ src/rpc/rtems_rpc.c
+
+librpc_CPPFLAGS = -D_RPC_read=read -D_RPC_write=write -D_RPC_close=close \
+ -D_RTEMS_RPC_INTERNAL_
+endif
+
+librpc_mans = src/rpc/bindresvport.3 src/rpc/getrpcent.3 src/rpc/publickey.3 \
+ src/rpc/rpc.3 src/rpc/rpc_secure.3 src/rpc/rstat_svc.8 \
+ src/rpc/des_crypt.3 src/rpc/getrpcport.3 src/rpc/publickey.5 \
+ src/rpc/rpc.5 src/rpc/rstat.1 src/rpc/rtime.3
+EXTRA_DIST += $(librpc_mans)
+
+if LIBRPC
+man_MANS += $(librpc_mans)
+endif
+
+EXTRA_DIST += src/rpc/DISCLAIMER src/rpc/README
+
+EXTRA_DIST += README_RTEMS
+
+## FIXME: Unused
+EXTRA_DIST += include/rpcsvc/bootparam_prot.x include/rpcsvc/crypt.x \
+ include/rpcsvc/key_prot.x include/rpcsvc/klm_prot.x \
+ include/rpcsvc/mount.x include/rpcsvc/nfs_prot.x \
+ include/rpcsvc/nis_cache.x include/rpcsvc/nis_callback.x \
+ include/rpcsvc/nis_db.h include/rpcsvc/nislib.h \
+ include/rpcsvc/nis_object.x include/rpcsvc/nis_tags.h \
+ include/rpcsvc/nis.x include/rpcsvc/nlm_prot.x \
+ include/rpcsvc/pmap_prot.x include/rpcsvc/rex.x include/rpcsvc/rnusers.x \
+ include/rpcsvc/rquota.x include/rpcsvc/rstat.x include/rpcsvc/rwall.x \
+ include/rpcsvc/sm_inter.x include/rpcsvc/spray.x include/rpcsvc/ypclnt.h \
+ include/rpcsvc/yppasswd.x include/rpcsvc/yp_prot.h \
+ include/rpcsvc/ypupdate_prot.x include/rpcsvc/yp.x \
+ include/rpcsvc/ypxfrd.x
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/librpc/README_RTEMS b/cpukit/librpc/README_RTEMS
new file mode 100644
index 0000000000..e60f8799aa
--- /dev/null
+++ b/cpukit/librpc/README_RTEMS
@@ -0,0 +1,64 @@
+USING RPC/XDR ON RTEMS
+======================
+For the most part, programmers using RPC/XDR routines on RTEMS
+can proceed as if they were to be using a POSIX/UNIX system.
+The only significant changes are those to start the portmapper
+and to allow use of RPC/XDR by multiple threads.
+
+Starting the portmapper
+=======================
+The SUN portmapper program has been modified to run as an RTEMS
+task. Applications which need the portmapper can start this
+task by calling:
+ int rtems_rpc_start_portmapper (int priority);
+The return value is an RTEMS status code.
+
+Multi-threaded operation
+========================
+The RPC/XDR package has been modified to allow for multiple RTEMS
+tasks to use RPC/XDR routines. If more than one task is to call
+an RPC/XDR routine, the additional tasks must call:
+ int rtems_rpc_task_init(void);
+before calling any RPC/XDR routines. For example, the portmapper
+calls this routine since the portmapper uses RPC/XDR routines in
+a separate thread.
+The return value is an RTEMS status code.
+
+
+Porting Notes
+=============
+Most of the FreeBSD rpc library ports to RTEMS with little
+or no modification beyond that required to provide for operation
+in a multitasking environment. Multitasking operation was
+provided by moving all `static persistence' variables into
+a single structure and using an RTEMS task variable to point
+to that structure.
+
+Some of the library, however, has not made it into the RTEMS
+implementation. FreeBSD source files which have been left out include:
+- Files which provide RPC to the AF_UNIX address family:
+ clnt_unix.c
+ svc_unix.c
+ An `ifndef __rtems__' was added to clnt_generic.c because clnt_unix.c
+ was omitted.
+- Files which need NIS:
+ auth_time.c
+- Files which provide DES authentication:
+ auth_des.c
+ authdes_prot.c
+ crypt_client.c
+ des_crypt.c
+ des_soft.c
+ getpublickey.c
+ key_call.c
+ key_prot_xdr.c
+ svc_auth_des.c
+
+The FreeBSD xdr source compiles and runs on RTEMS without modification.
+
+The original source was obtained from:
+ ftp://ftp.FreeBSD.org/pub/FreeBSD/
+ branches/4.0-stable/src/lib/libc/rpc
+ branches/4.0-stable/src/lib/libc/xdr
+ branches/4.0-stable/src/include/rpc
+ branches/4.0-stable/src/include/rpcsvc
diff --git a/cpukit/librpc/include/rpc/auth.h b/cpukit/librpc/include/rpc/auth.h
new file mode 100644
index 0000000000..036089938c
--- /dev/null
+++ b/cpukit/librpc/include/rpc/auth.h
@@ -0,0 +1,260 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)auth.h 1.17 88/02/08 SMI
+ * from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC
+ * $FreeBSD: src/include/rpc/auth.h,v 1.15 1999/08/27 23:45:02 peter Exp $
+ */
+
+/*
+ * auth.h, Authentication interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The data structures are completely opaque to the client. The client
+ * is required to pass a AUTH * to routines that create rpc
+ * "sessions".
+ */
+
+#ifndef _RPC_AUTH_H
+#define _RPC_AUTH_H
+#include <sys/cdefs.h>
+#include <sys/socket.h>
+
+#define MAX_AUTH_BYTES 400
+#define MAXNETNAMELEN 255 /* maximum length of network user's name */
+
+/*
+ * Status returned from authentication check
+ */
+enum auth_stat {
+ AUTH_OK=0,
+ /*
+ * failed at remote end
+ */
+ AUTH_BADCRED=1, /* bogus credentials (seal broken) */
+ AUTH_REJECTEDCRED=2, /* client should begin new session */
+ AUTH_BADVERF=3, /* bogus verifier (seal broken) */
+ AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */
+ AUTH_TOOWEAK=5, /* rejected due to security reasons */
+ /*
+ * failed locally
+ */
+ AUTH_INVALIDRESP=6, /* bogus response verifier */
+ AUTH_FAILED=7 /* some unknown reason */
+};
+
+union des_block {
+ struct {
+ u_int32_t high;
+ u_int32_t low;
+ } key;
+ char c[8];
+};
+typedef union des_block des_block;
+__BEGIN_DECLS
+extern bool_t xdr_des_block (XDR *, des_block *);
+__END_DECLS
+
+/*
+ * Authentication info. Opaque to client.
+ */
+struct opaque_auth {
+ enum_t oa_flavor; /* flavor of auth */
+ caddr_t oa_base; /* address of more auth stuff */
+ u_int oa_length; /* not to exceed MAX_AUTH_BYTES */
+};
+__BEGIN_DECLS
+bool_t xdr_opaque_auth (XDR *xdrs, struct opaque_auth *ap);
+__END_DECLS
+
+
+/*
+ * Auth handle, interface to client side authenticators.
+ */
+typedef struct __rpc_auth {
+ struct opaque_auth ah_cred;
+ struct opaque_auth ah_verf;
+ union des_block ah_key;
+ struct auth_ops {
+ void (*ah_nextverf) (struct __rpc_auth *);
+ /* nextverf & serialize */
+ int (*ah_marshal) (struct __rpc_auth *, XDR *);
+ /* validate verifier */
+ int (*ah_validate) (struct __rpc_auth *,
+ struct opaque_auth *);
+ /* refresh credentials */
+ int (*ah_refresh) (struct __rpc_auth *);
+ /* destroy this structure */
+ void (*ah_destroy) (struct __rpc_auth *);
+ } *ah_ops;
+ caddr_t ah_private;
+} AUTH;
+
+
+/*
+ * Authentication ops.
+ * The ops and the auth handle provide the interface to the authenticators.
+ *
+ * AUTH *auth;
+ * XDR *xdrs;
+ * struct opaque_auth verf;
+ */
+#define AUTH_NEXTVERF(auth) \
+ ((*((auth)->ah_ops->ah_nextverf))(auth))
+#define auth_nextverf(auth) \
+ ((*((auth)->ah_ops->ah_nextverf))(auth))
+
+#define AUTH_MARSHALL(auth, xdrs) \
+ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+#define auth_marshall(auth, xdrs) \
+ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+
+#define AUTH_VALIDATE(auth, verfp) \
+ ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+#define auth_validate(auth, verfp) \
+ ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+
+#define AUTH_REFRESH(auth) \
+ ((*((auth)->ah_ops->ah_refresh))(auth))
+#define auth_refresh(auth) \
+ ((*((auth)->ah_ops->ah_refresh))(auth))
+
+#define AUTH_DESTROY(auth) \
+ ((*((auth)->ah_ops->ah_destroy))(auth))
+#define auth_destroy(auth) \
+ ((*((auth)->ah_ops->ah_destroy))(auth))
+
+
+extern struct opaque_auth _null_auth;
+
+/*
+ * These are the various implementations of client side authenticators.
+ */
+
+/*
+ * Unix style authentication
+ * AUTH *authunix_create(machname, uid, gid, len, aup_gids)
+ * char *machname;
+ * int uid;
+ * int gid;
+ * int len;
+ * int *aup_gids;
+ */
+__BEGIN_DECLS
+struct sockaddr_in;
+extern AUTH *authunix_create (char *, int, int, int, int *);
+extern AUTH *authunix_create_default (void);
+extern AUTH *authnone_create (void);
+__END_DECLS
+
+/* Forward compatibility with TI-RPC */
+#define authsys_create authunix_create
+#define authsys_create_default authunix_create_default
+
+/*
+ * DES style authentication
+ * AUTH *authdes_create(servername, window, timehost, ckey)
+ * char *servername; - network name of server
+ * u_int window; - time to live
+ * struct sockaddr *timehost; - optional hostname to sync with
+ * des_block *ckey; - optional conversation key to use
+ */
+__BEGIN_DECLS
+extern AUTH *authdes_create ( char *, u_int, struct sockaddr *, des_block * );
+#ifdef NOTYET
+/*
+ * TI-RPC supports this call, but it requires the inclusion of
+ * NIS+-specific headers which would require the inclusion of other
+ * headers which would result in a tangled mess. For now, the NIS+
+ * code prototypes this routine internally.
+ */
+extern AUTH *authdes_pk_create ( char *, netobj *, u_int,
+ struct sockaddr *, des_block *,
+ nis_server * );
+#endif
+__END_DECLS
+
+/*
+ * Netname manipulation routines.
+ */
+__BEGIN_DECLS
+extern int netname2user ( char *, uid_t *, gid_t *, int *, gid_t *);
+extern int netname2host ( char *, char *, int );
+extern int getnetname ( char * );
+extern int user2netname ( char *, uid_t, char * );
+extern int host2netname ( char *, char *, char * );
+extern void passwd2des ( char *, char * );
+__END_DECLS
+
+/*
+ * Keyserv interface routines.
+ * XXX Should not be here.
+ */
+#ifndef HEXKEYBYTES
+#define HEXKEYBYTES 48
+#endif
+typedef char kbuf[HEXKEYBYTES];
+typedef char *namestr;
+
+struct netstarg {
+ kbuf st_priv_key;
+ kbuf st_pub_key;
+ namestr st_netname;
+};
+
+__BEGIN_DECLS
+extern int key_decryptsession ( const char *, des_block * );
+extern int key_decryptsession_pk ( char *, netobj *, des_block * );
+extern int key_encryptsession ( const char *, des_block * );
+extern int key_encryptsession_pk ( char *, netobj *, des_block * );
+extern int key_gendes ( des_block * );
+extern int key_setsecret ( const char * );
+extern int key_secretkey_is_set ( void );
+extern int key_setnet ( struct netstarg * );
+extern int key_get_conv ( char *, des_block * );
+__END_DECLS
+
+/*
+ * Publickey routines.
+ */
+__BEGIN_DECLS
+extern int getpublickey ( char *, char * );
+extern int getpublicandprivatekey ( char *, char * );
+extern int getsecretkey ( char *, char *, char * );
+__END_DECLS
+
+
+#define AUTH_NONE 0 /* no authentication */
+#define AUTH_NULL 0 /* backward compatibility */
+#define AUTH_UNIX 1 /* unix style (uid, gids) */
+#define AUTH_SYS 1 /* forward compatibility */
+#define AUTH_SHORT 2 /* short hand unix style */
+#define AUTH_DES 3 /* des style (encrypted timestamps) */
+
+#endif /* !_RPC_AUTH_H */
diff --git a/cpukit/librpc/include/rpc/auth_unix.h b/cpukit/librpc/include/rpc/auth_unix.h
new file mode 100644
index 0000000000..4b015b67ab
--- /dev/null
+++ b/cpukit/librpc/include/rpc/auth_unix.h
@@ -0,0 +1,84 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)auth_unix.h 1.8 88/02/08 SMI
+ * from: @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC
+ * $FreeBSD: src/include/rpc/auth_unix.h,v 1.10 1999/08/27 23:45:03 peter Exp $
+ */
+
+/*
+ * auth_unix.h, Protocol for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * The system is very weak. The client uses no encryption for it
+ * credentials and only sends null verifiers. The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ */
+
+#ifndef _RPC_AUTH_UNIX_H
+#define _RPC_AUTH_UNIX_H
+#include <sys/cdefs.h>
+
+/* The machine name is part of a credential; it may not exceed 255 bytes */
+#define MAX_MACHINE_NAME 255
+
+/* gids compose part of a credential; there may not be more than 16 of them */
+#define NGRPS 16
+
+/*
+ * Unix style credentials.
+ */
+struct authunix_parms {
+ u_long aup_time;
+ char *aup_machname;
+ int aup_uid;
+ int aup_gid;
+ u_int aup_len;
+ int *aup_gids;
+};
+
+#define authsys_parms authunix_parms
+
+__BEGIN_DECLS
+extern bool_t xdr_authunix_parms __P((XDR *, struct authunix_parms *));
+__END_DECLS
+
+/*
+ * If a response verifier has flavor AUTH_SHORT,
+ * then the body of the response verifier encapsulates the following structure;
+ * again it is serialized in the obvious fashion.
+ */
+struct short_hand_verf {
+ struct opaque_auth new_cred;
+};
+
+#endif /* !_RPC_AUTH_UNIX_H */
diff --git a/cpukit/librpc/include/rpc/clnt.h b/cpukit/librpc/include/rpc/clnt.h
new file mode 100644
index 0000000000..85e31d931e
--- /dev/null
+++ b/cpukit/librpc/include/rpc/clnt.h
@@ -0,0 +1,317 @@
+/* $NetBSD: clnt.h,v 1.14 2000/06/02 22:57:55 fvdl Exp $ */
+
+/*
+ * The contents of this file are subject to the Sun Standards
+ * License Version 1.0 the (the "License";) You may not use
+ * this file except in compliance with the License. You may
+ * obtain a copy of the License at lib/libc/rpc/LICENSE
+ *
+ * Software distributed under the License is distributed on
+ * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is Copyright 1998 by Sun Microsystems, Inc
+ *
+ * The Initial Developer of the Original Code is: Sun
+ * Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)clnt.h 1.31 94/04/29 SMI
+ * from: @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC
+ * $FreeBSD: src/include/rpc/clnt.h,v 1.21 2003/01/24 01:47:55 fjoe Exp $
+ */
+
+/*
+ * clnt.h - Client side remote procedure call interface.
+ *
+ * Copyright (c) 1986-1991,1994-1999 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RPC_CLNT_H_
+#define _RPC_CLNT_H_
+#include <rpc/clnt_stat.h>
+#include <sys/cdefs.h>
+#include <sys/un.h>
+
+/*
+ * Error info.
+ */
+struct rpc_err {
+ enum clnt_stat re_status;
+ union {
+ int RE_errno; /* related system error */
+ enum auth_stat RE_why; /* why the auth error occurred */
+ struct {
+ rpcvers_t low; /* lowest version supported */
+ rpcvers_t high; /* highest version supported */
+ } RE_vers;
+ struct { /* maybe meaningful if RPC_FAILED */
+ int32_t s1;
+ int32_t s2;
+ } RE_lb; /* life boot & debugging only */
+ } ru;
+#define re_errno ru.RE_errno
+#define re_why ru.RE_why
+#define re_vers ru.RE_vers
+#define re_lb ru.RE_lb
+};
+
+
+/*
+ * Client rpc handle.
+ * Created by individual implementations
+ * Client is responsible for initializing auth, see e.g. auth_none.c.
+ */
+typedef struct __rpc_client {
+ AUTH *cl_auth; /* authenticator */
+ struct clnt_ops {
+ /* call remote procedure */
+ enum clnt_stat (*cl_call)(struct __rpc_client *,
+ rpcproc_t, xdrproc_t, void *, xdrproc_t,
+ void *, struct timeval);
+ /* abort a call */
+ void (*cl_abort)(struct __rpc_client *);
+ /* get specific error code */
+ void (*cl_geterr)(struct __rpc_client *,
+ struct rpc_err *);
+ /* frees results */
+ bool_t (*cl_freeres)(struct __rpc_client *,
+ xdrproc_t, void *);
+ /* destroy this structure */
+ void (*cl_destroy)(struct __rpc_client *);
+ /* the ioctl() of rpc */
+ bool_t (*cl_control)(struct __rpc_client *, u_int,
+ void *);
+ } *cl_ops;
+ void *cl_private; /* private stuff */
+} CLIENT;
+
+#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */
+
+/*
+ * client side rpc interface ops
+ *
+ * Parameter types are:
+ *
+ */
+
+/*
+ * enum clnt_stat
+ * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
+ * CLIENT *rh;
+ * u_long proc;
+ * xdrproc_t xargs;
+ * caddr_t argsp;
+ * xdrproc_t xres;
+ * caddr_t resp;
+ * struct timeval timeout;
+ */
+#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \
+ ((*(rh)->cl_ops->cl_call)(rh, proc, (xdrproc_t)xargs, (caddr_t)argsp, \
+ (xdrproc_t) xres, (caddr_t)resp, secs))
+#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \
+ ((*(rh)->cl_ops->cl_call)(rh, proc, (xdrproc_t) xargs, (caddr_t)argsp, \
+ (xdrproc_t) xres, (caddr_t)resp, secs))
+
+/*
+ * void
+ * CLNT_ABORT(rh);
+ * CLIENT *rh;
+ */
+#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh))
+#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh))
+
+/*
+ * struct rpc_err
+ * CLNT_GETERR(rh);
+ * CLIENT *rh;
+ */
+#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+
+
+/*
+ * bool_t
+ * CLNT_FREERES(rh, xres, resp);
+ * CLIENT *rh;
+ * xdrproc_t xres;
+ * caddr_t resp;
+ */
+#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,(xdrproc_t)xres,resp))
+#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,(xdrproc_t)xres,resp))
+
+/*
+ * bool_t
+ * CLNT_CONTROL(cl, request, info)
+ * CLIENT *cl;
+ * u_int request;
+ * char *info;
+ */
+#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+
+/*
+ * control operations that apply to udp, tcp and unix transports
+ *
+ * Note: options marked XXX are no-ops in this implementation of RPC.
+ * The are present in TI-RPC but can't be implemented here since they
+ * depend on the presence of STREAMS/TLI, which we don't have.
+ *
+ */
+#define CLSET_TIMEOUT 1 /* set timeout (timeval) */
+#define CLGET_TIMEOUT 2 /* get timeout (timeval) */
+#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */
+#define CLGET_FD 6 /* get connections file descriptor */
+#define CLGET_SVC_ADDR 7 /* get server's address (netbuf) */
+#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */
+#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy */
+#define CLGET_XID 10 /* Get xid */
+#define CLSET_XID 11 /* Set xid */
+#define CLGET_VERS 12 /* Get version number */
+#define CLSET_VERS 13 /* Set version number */
+#define CLGET_PROG 14 /* Get program number */
+#define CLSET_PROG 15 /* Set program number */
+#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) XXX */
+#define CLSET_PUSH_TIMOD 17 /* push timod if not already present XXX */
+#define CLSET_POP_TIMOD 18 /* pop timod XXX */
+
+/*
+ * Connectionless only control operations
+ */
+#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */
+#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */
+
+/*
+ * Operations which GSSAPI needs. (Bletch.)
+ */
+#define CLGET_LOCAL_ADDR 19 /* get local addr (sockaddr) */
+
+
+/*
+ * void
+ * CLNT_DESTROY(rh);
+ * CLIENT *rh;
+ */
+#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh))
+#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh))
+
+
+/*
+ * RPCTEST is a test program which is accessible on every rpc
+ * transport/port. It is used for testing, performance evaluation,
+ * and network administration.
+ */
+
+#define RPCTEST_PROGRAM ((rpcprog_t)1)
+#define RPCTEST_VERSION ((rpcvers_t)1)
+#define RPCTEST_NULL_PROC ((rpcproc_t)2)
+#define RPCTEST_NULL_BATCH_PROC ((rpcproc_t)3)
+
+/*
+ * By convention, procedure 0 takes null arguments and returns them
+ */
+
+#define NULLPROC ((rpcproc_t)0)
+
+/*
+ * Below are the client handle creation routines for the various
+ * implementations of client side rpc. They can return NULL if a
+ * creation failure occurs.
+ */
+
+/*
+ * Generic client creation routine. Supported protocols are "udp", "tcp"
+ * and "unix".
+ * CLIENT *
+ * clnt_create(host, prog, vers, prot);
+ * char *host; -- hostname
+ * u_long prog; -- program number
+ * u_long vers; -- version number
+ * char *prot; -- protocol
+ */
+__BEGIN_DECLS
+extern CLIENT *clnt_create(char *, u_long, u_long, char *);
+__END_DECLS
+
+
+/*
+ * Added for compatibility to old rpc 4.0. Obsoleted by clnt_vc_create().
+ */
+extern CLIENT *clntunix_create(struct sockaddr_un *,
+ u_long, u_long, int *, u_int, u_int);
+__END_DECLS
+
+
+/*
+ * Print why creation failed
+ */
+__BEGIN_DECLS
+extern void clnt_pcreateerror(const char *); /* stderr */
+extern char *clnt_spcreateerror(const char *); /* string */
+__END_DECLS
+
+/*
+ * Like clnt_perror(), but is more verbose in its output
+ */
+__BEGIN_DECLS
+extern void clnt_perrno(enum clnt_stat); /* stderr */
+extern char *clnt_sperrno(enum clnt_stat); /* string */
+__END_DECLS
+
+/*
+ * Print an English error message, given the client error code
+ */
+__BEGIN_DECLS
+extern void clnt_perror(CLIENT *, const char *); /* stderr */
+extern char *clnt_sperror(CLIENT *, const char *); /* string */
+__END_DECLS
+
+
+/*
+ * If a creation fails, the following allows the user to figure out why.
+ */
+struct rpc_createerr {
+ enum clnt_stat cf_stat;
+ struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
+};
+
+extern struct rpc_createerr rpc_createerr;
+
+/* For backward compatibility */
+#include <rpc/clnt_soc.h>
+
+#endif /* !_RPC_CLNT_H_ */
diff --git a/cpukit/librpc/include/rpc/clnt_soc.h b/cpukit/librpc/include/rpc/clnt_soc.h
new file mode 100644
index 0000000000..f98c1b9b78
--- /dev/null
+++ b/cpukit/librpc/include/rpc/clnt_soc.h
@@ -0,0 +1,106 @@
+/* $NetBSD: clnt_soc.h,v 1.1 2000/06/02 22:57:55 fvdl Exp $ */
+/* $FreeBSD: src/include/rpc/clnt_soc.h,v 1.2 2002/03/23 17:24:55 imp Exp $ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1984 - 1991 by Sun Microsystems, Inc.
+ */
+
+/*
+ * clnt.h - Client side remote procedure call interface.
+ */
+
+#ifndef _RPC_CLNT_SOC_H
+#define _RPC_CLNT_SOC_H
+
+/* derived from clnt_soc.h 1.3 88/12/17 SMI */
+
+/*
+ * All the following declarations are only for backward compatibility
+ * with TS-RPC.
+ */
+
+#include <sys/cdefs.h>
+
+#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */
+
+/*
+ * TCP based rpc
+ * CLIENT *
+ * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ * struct sockaddr_in *raddr;
+ * u_long prog;
+ * u_long version;
+ * register int *sockp;
+ * u_int sendsz;
+ * u_int recvsz;
+ */
+__BEGIN_DECLS
+extern CLIENT *clnttcp_create(struct sockaddr_in *, u_long, u_long, int *,
+ u_int, u_int);
+__END_DECLS
+
+/*
+ * Raw (memory) rpc.
+ */
+__BEGIN_DECLS
+extern CLIENT *clntraw_create(u_long, u_long);
+__END_DECLS
+
+
+/*
+ * UDP based rpc.
+ * CLIENT *
+ * clntudp_create(raddr, program, version, wait, sockp)
+ * struct sockaddr_in *raddr;
+ * u_long program;
+ * u_long version;
+ * struct timeval wait;
+ * int *sockp;
+ *
+ * Same as above, but you specify max packet sizes.
+ * CLIENT *
+ * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+ * struct sockaddr_in *raddr;
+ * u_long program;
+ * u_long version;
+ * struct timeval wait;
+ * int *sockp;
+ * u_int sendsz;
+ * u_int recvsz;
+ */
+__BEGIN_DECLS
+extern CLIENT *clntudp_create(struct sockaddr_in *, u_long, u_long,
+ struct timeval, int *);
+extern CLIENT *clntudp_bufcreate(struct sockaddr_in *, u_long, u_long,
+ struct timeval, int *, u_int, u_int);
+__END_DECLS
+
+#endif /* _RPC_CLNT_SOC_H */
diff --git a/cpukit/librpc/include/rpc/clnt_stat.h b/cpukit/librpc/include/rpc/clnt_stat.h
new file mode 100644
index 0000000000..397bdbc596
--- /dev/null
+++ b/cpukit/librpc/include/rpc/clnt_stat.h
@@ -0,0 +1,83 @@
+/* $FreeBSD: src/include/rpc/clnt_stat.h,v 1.2 2001/03/20 08:20:50 alfred Exp $ */
+/*
+ * Copyright (c) 1986 - 1991, 1994, 1996, 1997 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+/*
+ * clnt_stat.h - Client side remote procedure call enum
+ *
+ */
+
+#ifndef _RPC_CLNT_STAT_H
+#define _RPC_CLNT_STAT_H
+
+/* #pragma ident "@(#)clnt_stat.h 1.2 97/04/28 SMI" */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum clnt_stat {
+ RPC_SUCCESS = 0, /* call succeeded */
+ /*
+ * local errors
+ */
+ RPC_CANTENCODEARGS = 1, /* can't encode arguments */
+ RPC_CANTDECODERES = 2, /* can't decode results */
+ RPC_CANTSEND = 3, /* failure in sending call */
+ RPC_CANTRECV = 4,
+ /* failure in receiving result */
+ RPC_TIMEDOUT = 5, /* call timed out */
+ RPC_INTR = 18, /* call interrupted */
+ RPC_UDERROR = 23, /* recv got uderr indication */
+ /*
+ * remote errors
+ */
+ RPC_VERSMISMATCH = 6, /* rpc versions not compatible */
+ RPC_AUTHERROR = 7, /* authentication error */
+ RPC_PROGUNAVAIL = 8, /* program not available */
+ RPC_PROGVERSMISMATCH = 9, /* program version mismatched */
+ RPC_PROCUNAVAIL = 10, /* procedure unavailable */
+ RPC_CANTDECODEARGS = 11, /* decode arguments error */
+ RPC_SYSTEMERROR = 12, /* generic "other problem" */
+
+ /*
+ * rpc_call & clnt_create errors
+ */
+ RPC_UNKNOWNHOST = 13, /* unknown host name */
+ RPC_UNKNOWNPROTO = 17, /* unknown protocol */
+ RPC_UNKNOWNADDR = 19, /* Remote address unknown */
+ RPC_NOBROADCAST = 21, /* Broadcasting not supported */
+
+ /*
+ * rpcbind errors
+ */
+ RPC_RPCBFAILURE = 14, /* the pmapper failed in its call */
+#define RPC_PMAPFAILURE RPC_RPCBFAILURE
+ RPC_PROGNOTREGISTERED = 15, /* remote program is not registered */
+ RPC_N2AXLATEFAILURE = 22,
+ /* Name to address translation failed */
+ /*
+ * Misc error in the TLI library
+ */
+ RPC_TLIERROR = 20,
+ /*
+ * unspecified error
+ */
+ RPC_FAILED = 16,
+ /*
+ * asynchronous errors
+ */
+ RPC_INPROGRESS = 24,
+ RPC_STALERACHANDLE = 25,
+ RPC_CANTCONNECT = 26, /* couldn't make connection (cots) */
+ RPC_XPRTFAILED = 27, /* received discon from remote (cots) */
+ RPC_CANTCREATESTREAM = 28 /* can't push rpc module (cots) */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_RPC_CLNT_STAT_H */
diff --git a/cpukit/librpc/include/rpc/pmap_clnt.h b/cpukit/librpc/include/rpc/pmap_clnt.h
new file mode 100644
index 0000000000..2f4a2780dd
--- /dev/null
+++ b/cpukit/librpc/include/rpc/pmap_clnt.h
@@ -0,0 +1,85 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)pmap_clnt.h 1.11 88/02/08 SMI
+ * from: @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC
+ * $FreeBSD: src/include/rpc/pmap_clnt.h,v 1.11 1999/08/27 23:45:04 peter Exp $
+ */
+
+/*
+ * pmap_clnt.h
+ * Supplies C routines to get to portmap services.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * Usage:
+ * success = pmap_set(program, version, protocol, port);
+ * success = pmap_unset(program, version);
+ * port = pmap_getport(address, program, version, protocol);
+ * head = pmap_getmaps(address);
+ * clnt_stat = pmap_rmtcall(address, program, version, procedure,
+ * xdrargs, argsp, xdrres, resp, tout, port_ptr)
+ * (works for udp only.)
+ * clnt_stat = clnt_broadcast(program, version, procedure,
+ * xdrargs, argsp, xdrres, resp, eachresult)
+ * (like pmap_rmtcall, except the call is broadcasted to all
+ * locally connected nets. For each valid response received,
+ * the procedure eachresult is called. Its form is:
+ * done = eachresult(resp, raddr)
+ * bool_t done;
+ * caddr_t resp;
+ * struct sockaddr_in raddr;
+ * where resp points to the results of the call and raddr is the
+ * address if the responder to the broadcast.
+ */
+
+#ifndef _RPC_PMAPCLNT_H
+#define _RPC_PMAPCLNT_H
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern bool_t pmap_set __P((u_long, u_long, int, int));
+extern bool_t pmap_unset __P((u_long, u_long));
+extern struct pmaplist *pmap_getmaps __P((struct sockaddr_in *));
+extern enum clnt_stat pmap_rmtcall __P((struct sockaddr_in *,
+ u_long, u_long, u_long,
+ xdrproc_t, caddr_t,
+ xdrproc_t, caddr_t,
+ struct timeval, u_long *));
+extern enum clnt_stat clnt_broadcast __P((u_long, u_long, u_long,
+ xdrproc_t, char *,
+ xdrproc_t, char *,
+ bool_t (*) __P((caddr_t,
+ struct sockaddr_in *))));
+extern u_short pmap_getport __P((struct sockaddr_in *,
+ u_long, u_long, u_int));
+__END_DECLS
+
+#endif /* !_RPC_PMAPCLNT_H */
diff --git a/cpukit/librpc/include/rpc/pmap_prot.h b/cpukit/librpc/include/rpc/pmap_prot.h
new file mode 100644
index 0000000000..14f0837bfe
--- /dev/null
+++ b/cpukit/librpc/include/rpc/pmap_prot.h
@@ -0,0 +1,104 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)pmap_prot.h 1.14 88/02/08 SMI
+ * from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC
+ * $FreeBSD: src/include/rpc/pmap_prot.h,v 1.10 1999/08/27 23:45:04 peter Exp $
+ */
+
+/*
+ * pmap_prot.h
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The following procedures are supported by the protocol:
+ *
+ * PMAPPROC_NULL() returns ()
+ * takes nothing, returns nothing
+ *
+ * PMAPPROC_SET(struct pmap) returns (bool_t)
+ * TRUE is success, FALSE is failure. Registers the tuple
+ * [prog, vers, prot, port].
+ *
+ * PMAPPROC_UNSET(struct pmap) returns (bool_t)
+ * TRUE is success, FALSE is failure. Un-registers pair
+ * [prog, vers]. prot and port are ignored.
+ *
+ * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
+ * 0 is failure. Otherwise returns the port number where the pair
+ * [prog, vers] is registered. It may lie!
+ *
+ * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
+ *
+ * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
+ * RETURNS (port, string<>);
+ * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
+ * Calls the procedure on the local machine. If it is not registered,
+ * this procedure is quite; ie it does not return error information!!!
+ * This procedure only is supported on rpc/udp and calls via
+ * rpc/udp. This routine only passes null authentication parameters.
+ * This file has no interface to xdr routines for PMAPPROC_CALLIT.
+ *
+ * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
+ */
+
+#ifndef _RPC_PMAPPROT_H
+#define _RPC_PMAPPROT_H
+#include <sys/cdefs.h>
+
+#define PMAPPORT ((u_short)111)
+#define PMAPPROG ((u_long)100000)
+#define PMAPVERS ((u_long)2)
+#define PMAPVERS_PROTO ((u_long)2)
+#define PMAPVERS_ORIG ((u_long)1)
+#define PMAPPROC_NULL ((u_long)0)
+#define PMAPPROC_SET ((u_long)1)
+#define PMAPPROC_UNSET ((u_long)2)
+#define PMAPPROC_GETPORT ((u_long)3)
+#define PMAPPROC_DUMP ((u_long)4)
+#define PMAPPROC_CALLIT ((u_long)5)
+
+struct pmap {
+ long unsigned pm_prog;
+ long unsigned pm_vers;
+ long unsigned pm_prot;
+ long unsigned pm_port;
+};
+
+struct pmaplist {
+ struct pmap pml_map;
+ struct pmaplist *pml_next;
+};
+
+__BEGIN_DECLS
+extern bool_t xdr_pmap __P((XDR *, struct pmap *));
+extern bool_t xdr_pmaplist __P((XDR *, struct pmaplist **));
+__END_DECLS
+
+#endif /* !_RPC_PMAPPROT_H */
diff --git a/cpukit/librpc/include/rpc/pmap_rmt.h b/cpukit/librpc/include/rpc/pmap_rmt.h
new file mode 100644
index 0000000000..e632f8deca
--- /dev/null
+++ b/cpukit/librpc/include/rpc/pmap_rmt.h
@@ -0,0 +1,63 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)pmap_rmt.h 1.2 88/02/08 SMI
+ * from: @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC
+ * $FreeBSD: src/include/rpc/pmap_rmt.h,v 1.10 1999/08/27 23:45:05 peter Exp $
+ */
+
+/*
+ * Structures and XDR routines for parameters to and replies from
+ * the portmapper remote-call-service.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_PMAPRMT_H
+#define _RPC_PMAPRMT_H
+#include <sys/cdefs.h>
+
+struct rmtcallargs {
+ u_long prog, vers, proc, arglen;
+ caddr_t args_ptr;
+ xdrproc_t xdr_args;
+};
+
+struct rmtcallres {
+ u_long *port_ptr;
+ u_long resultslen;
+ caddr_t results_ptr;
+ xdrproc_t xdr_results;
+};
+
+__BEGIN_DECLS
+extern bool_t xdr_rmtcall_args __P((XDR *, struct rmtcallargs *));
+extern bool_t xdr_rmtcallres __P((XDR *, struct rmtcallres *));
+__END_DECLS
+
+#endif /* !_RPC_PMAPRMT_H */
diff --git a/cpukit/librpc/include/rpc/rpc.h b/cpukit/librpc/include/rpc/rpc.h
new file mode 100644
index 0000000000..95df085926
--- /dev/null
+++ b/cpukit/librpc/include/rpc/rpc.h
@@ -0,0 +1,116 @@
+/* $NetBSD: rpc.h,v 1.13 2000/06/02 22:57:56 fvdl Exp $ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)rpc.h 1.9 88/02/08 SMI
+ * from: @(#)rpc.h 2.4 89/07/11 4.0 RPCSRC
+ * $FreeBSD: src/include/rpc/rpc.h,v 1.17 2002/03/23 17:24:55 imp Exp $
+ */
+
+/*
+ * rpc.h, Just includes the billions of rpc header files necessary to
+ * do remote procedure calling.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+#ifndef _RPC_RPC_H
+#define _RPC_RPC_H
+
+#include <rpc/types.h> /* some typedefs */
+#include <netinet/in.h>
+
+/* external data representation interfaces */
+#include <rpc/xdr.h> /* generic (de)serializer */
+
+/* Client side only authentication */
+#include <rpc/auth.h> /* generic authenticator (client side) */
+
+/* Client side (mostly) remote procedure call */
+#include <rpc/clnt.h> /* generic rpc stuff */
+
+/* semi-private protocol headers */
+#include <rpc/rpc_msg.h> /* protocol for rpc messages */
+#include <rpc/auth_unix.h> /* protocol for unix style cred */
+
+/* Server side only remote procedure callee */
+#include <rpc/svc.h> /* service manager and multiplexer */
+#include <rpc/svc_auth.h> /* service side authenticator */
+
+#include <rpc/rpcent.h>
+
+__BEGIN_DECLS
+extern int get_myaddress(struct sockaddr_in *);
+extern int bindresvport(int, struct sockaddr_in *);
+extern int bindresvport_sa(int, struct sockaddr *);
+__END_DECLS
+
+int rtems_rpc_task_init (void);
+int rtems_rpc_start_portmapper (int priority);
+
+#ifdef _RTEMS_RPC_INTERNAL_
+/*
+ * Multi-threaded support
+ * Group all global and static variables into a single spot.
+ * This area will be allocated on a per-task basis
+ */
+struct _rtems_rpc_task_variables {
+ int svc_svc_maxfd;
+ fd_set svc_svc_fdset;
+ SVCXPRT ** svc_xports;
+ int svc_xportssize;
+ int svc__svc_fdsetsize;
+ fd_set *svc__svc_fdset;
+ struct svc_callout *svc_svc_head;
+
+ char *clnt_perror_buf;
+
+ struct clnt_raw_private *clnt_raw_private;
+
+ void *call_rpc_private;
+
+ struct call_rpc_private *svc_raw_private;
+
+ struct prog_lst *svc_simple_proglst;
+ struct prog_lst *svc_simple_pl;
+ SVCXPRT *svc_simple_transp;
+
+ char *rpcdname_default_domain;
+
+ struct authsvc *svc_auths_Auths;
+};
+extern struct _rtems_rpc_task_variables *rtems_rpc_task_variables;
+
+#define svc_maxfd (rtems_rpc_task_variables->svc_svc_maxfd)
+#define svc_fdset (rtems_rpc_task_variables->svc_svc_fdset)
+#define __svc_fdsetsize (rtems_rpc_task_variables->svc__svc_fdsetsize)
+#define __svc_fdset (rtems_rpc_task_variables->svc__svc_fdset)
+
+#endif /* _RTEMS_RPC_INTERNAL_ */
+
+#endif /* !_RPC_RPC_H */
diff --git a/cpukit/librpc/include/rpc/rpc_com.h b/cpukit/librpc/include/rpc/rpc_com.h
new file mode 100644
index 0000000000..7697b9a44c
--- /dev/null
+++ b/cpukit/librpc/include/rpc/rpc_com.h
@@ -0,0 +1,68 @@
+/* $NetBSD: rpc_com.h,v 1.3 2000/12/10 04:10:08 christos Exp $ */
+/* $FreeBSD: src/include/rpc/rpc_com.h,v 1.6 2003/01/16 07:13:51 mbr Exp $ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
+ */
+
+/*
+ * $Id$
+ */
+
+/*
+ * rpc_com.h, Common definitions for both the server and client side.
+ * All for the topmost layer of rpc
+ *
+ */
+
+#ifndef _RPC_RPCCOM_H
+#define _RPC_RPCCOM_H
+
+#include <sys/cdefs.h>
+
+/* #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */
+
+/*
+ * The max size of the transport, if the size cannot be determined
+ * by other means.
+ */
+#define RPC_MAXDATASIZE 9000
+#define RPC_MAXADDRSIZE 1024
+
+__BEGIN_DECLS
+extern u_int __rpc_get_a_size(int);
+extern u_int __rpc_get_t_size(int, long);
+extern int __rpc_dtbsize(void);
+extern int _rpc_dtablesize(void);
+extern int _rpc_get_default_domain(char **);
+__END_DECLS
+
+#endif /* _RPC_RPCCOM_H */
diff --git a/cpukit/librpc/include/rpc/rpc_msg.h b/cpukit/librpc/include/rpc/rpc_msg.h
new file mode 100644
index 0000000000..733a5e2892
--- /dev/null
+++ b/cpukit/librpc/include/rpc/rpc_msg.h
@@ -0,0 +1,199 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)rpc_msg.h 1.7 86/07/16 SMI
+ * from: @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC
+ * $FreeBSD: src/include/rpc/rpc_msg.h,v 1.15 2003/01/01 18:48:42 schweikh Exp $
+ */
+
+/*
+ * rpc_msg.h
+ * rpc message definition
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RPC_RPC_MSG_H
+#define _RPC_RPC_MSG_H
+
+#define RPC_MSG_VERSION ((u_int32_t) 2)
+#define RPC_SERVICE_PORT ((u_short) 2048)
+
+/*
+ * Bottom up definition of an rpc message.
+ * NOTE: call and reply use the same overall stuct but
+ * different parts of unions within it.
+ */
+
+enum msg_type {
+ CALL=0,
+ REPLY=1
+};
+
+enum reply_stat {
+ MSG_ACCEPTED=0,
+ MSG_DENIED=1
+};
+
+enum accept_stat {
+ SUCCESS=0,
+ PROG_UNAVAIL=1,
+ PROG_MISMATCH=2,
+ PROC_UNAVAIL=3,
+ GARBAGE_ARGS=4,
+ SYSTEM_ERR=5
+};
+
+enum reject_stat {
+ RPC_MISMATCH=0,
+ AUTH_ERROR=1
+};
+
+/*
+ * Reply part of an rpc exchange
+ */
+
+/*
+ * Reply to an rpc request that was accepted by the server.
+ * Note: there could be an error even though the request was
+ * accepted.
+ */
+struct accepted_reply {
+ struct opaque_auth ar_verf;
+ enum accept_stat ar_stat;
+ union {
+ struct {
+ u_int32_t low;
+ u_int32_t high;
+ } AR_versions;
+ struct {
+ caddr_t where;
+ xdrproc_t proc;
+ } AR_results;
+ /* and many other null cases */
+ } ru;
+#define ar_results ru.AR_results
+#define ar_vers ru.AR_versions
+};
+
+/*
+ * Reply to an rpc request that was rejected by the server.
+ */
+struct rejected_reply {
+ enum reject_stat rj_stat;
+ union {
+ struct {
+ u_int32_t low;
+ u_int32_t high;
+ } RJ_versions;
+ enum auth_stat RJ_why; /* why authentication did not work */
+ } ru;
+#define rj_vers ru.RJ_versions
+#define rj_why ru.RJ_why
+};
+
+/*
+ * Body of a reply to an rpc request.
+ */
+struct reply_body {
+ enum reply_stat rp_stat;
+ union {
+ struct accepted_reply RP_ar;
+ struct rejected_reply RP_dr;
+ } ru;
+#define rp_acpt ru.RP_ar
+#define rp_rjct ru.RP_dr
+};
+
+/*
+ * Body of an rpc request call.
+ */
+struct call_body {
+ u_int32_t cb_rpcvers; /* must be equal to two */
+ u_int32_t cb_prog;
+ u_int32_t cb_vers;
+ u_int32_t cb_proc;
+ struct opaque_auth cb_cred;
+ struct opaque_auth cb_verf; /* protocol specific - provided by client */
+};
+
+/*
+ * The rpc message
+ */
+struct rpc_msg {
+ u_int32_t rm_xid;
+ enum msg_type rm_direction;
+ union {
+ struct call_body RM_cmb;
+ struct reply_body RM_rmb;
+ } ru;
+#define rm_call ru.RM_cmb
+#define rm_reply ru.RM_rmb
+};
+#define acpted_rply ru.RM_rmb.ru.RP_ar
+#define rjcted_rply ru.RM_rmb.ru.RP_dr
+
+__BEGIN_DECLS
+/*
+ * XDR routine to handle a rpc message.
+ * xdr_callmsg(xdrs, cmsg)
+ * XDR *xdrs;
+ * struct rpc_msg *cmsg;
+ */
+extern bool_t xdr_callmsg(XDR *, struct rpc_msg *);
+
+/*
+ * XDR routine to pre-serialize the static part of a rpc message.
+ * xdr_callhdr(xdrs, cmsg)
+ * XDR *xdrs;
+ * struct rpc_msg *cmsg;
+ */
+extern bool_t xdr_callhdr(XDR *, struct rpc_msg *);
+
+/*
+ * XDR routine to handle a rpc reply.
+ * xdr_replymsg(xdrs, rmsg)
+ * XDR *xdrs;
+ * struct rpc_msg *rmsg;
+ */
+extern bool_t xdr_replymsg __P((XDR *, struct rpc_msg *));
+
+/*
+ * Fills in the error part of a reply message.
+ * _seterr_reply(msg, error)
+ * struct rpc_msg *msg;
+ * struct rpc_err *error;
+ */
+extern void _seterr_reply(struct rpc_msg *, struct rpc_err *);
+__END_DECLS
+
+#endif /* !_RPC_RPC_MSG_H */
diff --git a/cpukit/librpc/include/rpc/rpcent.h b/cpukit/librpc/include/rpc/rpcent.h
new file mode 100644
index 0000000000..dbc8b0e5f9
--- /dev/null
+++ b/cpukit/librpc/include/rpc/rpcent.h
@@ -0,0 +1,69 @@
+/* $NetBSD: rpcent.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */
+/* $FreeBSD: src/include/rpc/rpcent.h,v 1.2 2002/03/23 17:24:55 imp Exp $ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
+ */
+
+/*
+ * rpcent.h,
+ * For converting rpc program numbers to names etc.
+ *
+ */
+
+#ifndef _RPC_RPCENT_H
+#define _RPC_RPCENT_H
+
+/* #pragma ident "@(#)rpcent.h 1.13 94/04/25 SMI" */
+/* @(#)rpcent.h 1.1 88/12/06 SMI */
+
+
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ int r_number; /* rpc program number */
+};
+
+__BEGIN_DECLS
+extern struct rpcent *getrpcbyname_r(const char *, struct rpcent *,
+ char *, int);
+extern struct rpcent *getrpcbynumber_r(int, struct rpcent *, char *, int);
+extern struct rpcent *getrpcent_r(struct rpcent *, char *, int);
+
+/* Old interfaces that return a pointer to a static area; MT-unsafe */
+extern struct rpcent *getrpcbyname(char *);
+extern struct rpcent *getrpcbynumber(int);
+extern struct rpcent *getrpcent(void);
+extern void setrpcent(int);
+extern void endrpcent(void);
+__END_DECLS
+
+#endif /* !_RPC_CENT_H */
diff --git a/cpukit/librpc/include/rpc/svc.h b/cpukit/librpc/include/rpc/svc.h
new file mode 100644
index 0000000000..4ba04a5894
--- /dev/null
+++ b/cpukit/librpc/include/rpc/svc.h
@@ -0,0 +1,289 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)svc.h 1.35 88/12/17 SMI
+ * from: @(#)svc.h 1.27 94/04/25 SMI
+ * $FreeBSD: src/include/rpc/svc.h,v 1.24 2003/06/15 10:32:01 mbr Exp $
+ */
+
+/*
+ * svc.h, Server-side remote procedure call interface.
+ *
+ * Copyright (C) 1986-1993 by Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_SVC_H
+#define _RPC_SVC_H
+#include <sys/cdefs.h>
+
+/*
+ * This interface must manage two items concerning remote procedure calling:
+ *
+ * 1) An arbitrary number of transport connections upon which rpc requests
+ * are received. The two most notable transports are TCP and UDP; they are
+ * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
+ * they in turn call xprt_register and xprt_unregister.
+ *
+ * 2) An arbitrary number of locally registered services. Services are
+ * described by the following four data: program number, version number,
+ * "service dispatch" function, a transport handle, and a boolean that
+ * indicates whether or not the exported program should be registered with a
+ * local binder service; if true the program's number and version and the
+ * port number from the transport handle are registered with the binder.
+ * These data are registered with the rpc svc system via svc_register.
+ *
+ * A service's dispatch function is called whenever an rpc request comes in
+ * on a transport. The request's program and version numbers must match
+ * those of the registered service. The dispatch function is passed two
+ * parameters, struct svc_req * and SVCXPRT *, defined below.
+ */
+
+enum xprt_stat {
+ XPRT_DIED,
+ XPRT_MOREREQS,
+ XPRT_IDLE
+};
+
+struct rpc_msg;
+
+/*
+ * Server side transport handle
+ */
+typedef struct __rpc_svcxprt {
+ int xp_sock;
+ u_short xp_port; /* associated port number */
+ struct xp_ops {
+ /* receive incoming requests */
+ bool_t (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *);
+ /* get transport status */
+ enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *);
+ /* get arguments */
+ bool_t (*xp_getargs)(struct __rpc_svcxprt *, xdrproc_t,
+ void *);
+ /* send reply */
+ bool_t (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *);
+ /* free mem allocated for args */
+ bool_t (*xp_freeargs)(struct __rpc_svcxprt *, xdrproc_t,
+ void *);
+ /* destroy this struct */
+ void (*xp_destroy)(struct __rpc_svcxprt *);
+ } *xp_ops;
+ socklen_t xp_addrlen; /* length of remote address */
+ struct sockaddr_in xp_raddr; /* remote addr. (backward ABI compat) */
+ struct opaque_auth xp_verf; /* raw response verifier */
+ void *xp_p1; /* private: for use by svc ops */
+ void *xp_p2; /* private: for use by svc ops */
+} SVCXPRT;
+
+/*
+ * Service request
+ */
+struct svc_req {
+ u_int32_t rq_prog; /* service program number */
+ u_int32_t rq_vers; /* service protocol version */
+ u_int32_t rq_proc; /* the desired procedure */
+ struct opaque_auth rq_cred; /* raw creds from the wire */
+ caddr_t rq_clntcred; /* read only cooked cred */
+ SVCXPRT *rq_xprt; /* associated transport */
+};
+
+
+/*
+ * Operations defined on an SVCXPRT handle
+ *
+ * SVCXPRT *xprt;
+ * struct rpc_msg *msg;
+ * xdrproc_t xargs;
+ * caddr_t argsp;
+ */
+#define SVC_RECV(xprt, msg) \
+ (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+#define svc_recv(xprt, msg) \
+ (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+
+#define SVC_STAT(xprt) \
+ (*(xprt)->xp_ops->xp_stat)(xprt)
+#define svc_stat(xprt) \
+ (*(xprt)->xp_ops->xp_stat)(xprt)
+
+#define SVC_GETARGS(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+#define svc_getargs(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+
+#define SVC_REPLY(xprt, msg) \
+ (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+#define svc_reply(xprt, msg) \
+ (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+
+#define SVC_FREEARGS(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+#define svc_freeargs(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+
+#define SVC_DESTROY(xprt) \
+ (*(xprt)->xp_ops->xp_destroy)(xprt)
+#define svc_destroy(xprt) \
+ (*(xprt)->xp_ops->xp_destroy)(xprt)
+
+/*
+ * Transport registration.
+ *
+ * xprt_register(xprt)
+ * SVCXPRT *xprt;
+ */
+__BEGIN_DECLS
+extern void xprt_register(SVCXPRT *);
+__END_DECLS
+
+/*
+ * Transport un-register
+ *
+ * xprt_unregister(xprt)
+ * SVCXPRT *xprt;
+ */
+__BEGIN_DECLS
+extern void xprt_unregister(SVCXPRT *);
+__END_DECLS
+
+
+/*
+ * When the service routine is called, it must first check to see if it
+ * knows about the procedure; if not, it should call svcerr_noproc
+ * and return. If so, it should deserialize its arguments via
+ * SVC_GETARGS (defined above). If the deserialization does not work,
+ * svcerr_decode should be called followed by a return. Successful
+ * decoding of the arguments should be followed the execution of the
+ * procedure's code and a call to svc_sendreply.
+ *
+ * Also, if the service refuses to execute the procedure due to too-
+ * weak authentication parameters, svcerr_weakauth should be called.
+ * Note: do not confuse access-control failure with weak authentication!
+ *
+ * NB: In pure implementations of rpc, the caller always waits for a reply
+ * msg. This message is sent when svc_sendreply is called.
+ * Therefore pure service implementations should always call
+ * svc_sendreply even if the function logically returns void; use
+ * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows
+ * for the abuse of pure rpc via batched calling or pipelining. In the
+ * case of a batched call, svc_sendreply should NOT be called since
+ * this would send a return message, which is what batching tries to avoid.
+ * It is the service/protocol writer's responsibility to know which calls are
+ * batched and which are not. Warning: responding to batch calls may
+ * deadlock the caller and server processes!
+ */
+
+__BEGIN_DECLS
+extern bool_t svc_sendreply(SVCXPRT *, xdrproc_t, void *);
+extern void svcerr_decode(SVCXPRT *);
+extern void svcerr_weakauth(SVCXPRT *);
+extern void svcerr_noproc(SVCXPRT *);
+extern void svcerr_progvers(SVCXPRT *, rpcvers_t, rpcvers_t);
+extern void svcerr_auth(SVCXPRT *, enum auth_stat);
+extern void svcerr_noprog(SVCXPRT *);
+extern void svcerr_systemerr(SVCXPRT *);
+__END_DECLS
+
+/*
+ * Lowest level dispatching -OR- who owns this process anyway.
+ * Somebody has to wait for incoming requests and then call the correct
+ * service routine. The routine svc_run does infinite waiting; i.e.,
+ * svc_run never returns.
+ * Since another (co-existant) package may wish to selectively wait for
+ * incoming calls or other events outside of the rpc architecture, the
+ * routine svc_getreq is provided. It must be passed readfds, the
+ * "in-place" results of a select system call (see select, section 2).
+ */
+
+/*
+ * Global keeper of rpc service descriptors in use
+ * dynamic; must be inspected before each call to select
+ */
+extern int svc_maxfd;
+extern fd_set svc_fdset;
+#define svc_fds svc_fdset.fds_bits[0] /* compatibility */
+
+#ifndef _KERNEL
+/*
+ * a small program implemented by the svc_rpc implementation itself;
+ * also see clnt.h for protocol numbers.
+ */
+__BEGIN_DECLS
+extern void rpctest_service(void);
+__END_DECLS
+#endif
+
+__BEGIN_DECLS
+extern void svc_getreq(int);
+extern void svc_getreqset(fd_set *);
+extern void svc_getreqset2(fd_set *, int); /* XXX: nonstd, undoc */
+extern void svc_run(void);
+__END_DECLS
+
+/*
+ * Socket to use on svcxxx_create call to get default socket
+ */
+#define RPC_ANYSOCK -1
+#define RPC_ANYFD RPC_ANYSOCK
+
+/*
+ * These are the existing service side transport implementations
+ */
+
+__BEGIN_DECLS
+/*
+ * Transport independent svc_create routine.
+ */
+
+/*
+ * Connectionless and connectionful create routines
+ */
+
+extern SVCXPRT *svc_vc_create(const int, const u_int, const u_int);
+/*
+ * const int fd; -- open connection end point
+ * const u_int sendsize; -- max send size
+ * const u_int recvsize; -- max recv size
+ */
+
+/*
+ * Added for compatibility to old rpc 4.0. Obsoleted by svc_vc_create().
+ */
+extern SVCXPRT *svcunix_create(int, u_int, u_int, char *);
+
+/*
+ * Added for compatibility to old rpc 4.0. Obsoleted by svc_fd_create().
+ */
+extern SVCXPRT *svcunixfd_create(int, u_int, u_int);
+__END_DECLS
+
+
+/* for backward compatibility */
+#include <rpc/svc_soc.h>
+
+#endif /* !_RPC_SVC_H */
diff --git a/cpukit/librpc/include/rpc/svc_auth.h b/cpukit/librpc/include/rpc/svc_auth.h
new file mode 100644
index 0000000000..a203d8cbeb
--- /dev/null
+++ b/cpukit/librpc/include/rpc/svc_auth.h
@@ -0,0 +1,56 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)svc_auth.h 1.6 86/07/16 SMI
+ * from: @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC
+ * $FreeBSD: src/include/rpc/svc_auth.h,v 1.12 1999/08/27 23:45:05 peter Exp $
+ */
+
+/*
+ * svc_auth.h, Service side of rpc authentication.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_SVCAUTH_H
+#define _RPC_SVCAUTH_H
+
+struct rpc_msg;
+struct svc_req;
+
+/*
+ * Server side authenticator
+ */
+__BEGIN_DECLS
+extern enum auth_stat _authenticate __P((struct svc_req *, struct rpc_msg *));
+extern int svc_auth_reg __P((int, enum auth_stat (*)(struct svc_req *,
+ struct rpc_msg *)));
+extern enum auth_stat _svcauth_des __P((struct svc_req *, struct rpc_msg *));
+__END_DECLS
+
+#endif /* !_RPC_SVCAUTH_H */
diff --git a/cpukit/librpc/include/rpc/svc_soc.h b/cpukit/librpc/include/rpc/svc_soc.h
new file mode 100644
index 0000000000..359d11e8ba
--- /dev/null
+++ b/cpukit/librpc/include/rpc/svc_soc.h
@@ -0,0 +1,123 @@
+/* $NetBSD: svc_soc.h,v 1.1 2000/06/02 22:57:57 fvdl Exp $ */
+/* $FreeBSD: src/include/rpc/svc_soc.h,v 1.2 2002/03/23 17:24:55 imp Exp $ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
+ */
+
+/*
+ * svc.h, Server-side remote procedure call interface.
+ */
+
+#ifndef _RPC_SVC_SOC_H
+#define _RPC_SVC_SOC_H
+#include <sys/cdefs.h>
+
+/* #pragma ident "@(#)svc_soc.h 1.11 94/04/25 SMI" */
+/* svc_soc.h 1.8 89/05/01 SMI */
+
+/*
+ * All the following declarations are only for backward compatibility
+ * with TS-RPC
+ */
+
+/*
+ * Approved way of getting address of caller
+ */
+#define svc_getcaller(x) (&(x)->xp_raddr)
+
+/*
+ * Service registration
+ *
+ * svc_register(xprt, prog, vers, dispatch, protocol)
+ * SVCXPRT *xprt;
+ * u_long prog;
+ * u_long vers;
+ * void (*dispatch)();
+ * int protocol; like TCP or UDP, zero means do not register
+ */
+__BEGIN_DECLS
+extern bool_t svc_register(SVCXPRT *, u_long, u_long,
+ void (*)(struct svc_req *, SVCXPRT *), int);
+__END_DECLS
+
+/*
+ * Service un-registration
+ *
+ * svc_unregister(prog, vers)
+ * u_long prog;
+ * u_long vers;
+ */
+__BEGIN_DECLS
+extern void svc_unregister(u_long, u_long);
+__END_DECLS
+
+
+/*
+ * Memory based rpc for testing and timing.
+ */
+__BEGIN_DECLS
+extern SVCXPRT *svcraw_create(void);
+__END_DECLS
+
+
+/*
+ * Udp based rpc.
+ */
+__BEGIN_DECLS
+extern SVCXPRT *svcudp_create(int);
+extern SVCXPRT *svcudp_bufcreate(int, u_int, u_int);
+__END_DECLS
+
+
+/*
+ * Tcp based rpc.
+ */
+__BEGIN_DECLS
+extern SVCXPRT *svctcp_create(int, u_int, u_int);
+__END_DECLS
+
+/*
+ * Fd based rpc.
+ */
+__BEGIN_DECLS
+extern SVCXPRT *svcfd_create(int, u_int, u_int);
+__END_DECLS
+
+/*
+ * AF_UNIX socket based rpc.
+ */
+__BEGIN_DECLS
+extern SVCXPRT *svcunix_create (int, u_int, u_int, char *);
+extern SVCXPRT *svcunixfd_create (int, u_int, u_int);
+__END_DECLS
+
+#endif /* !_RPC_SVC_SOC_H */
diff --git a/cpukit/librpc/include/rpc/types.h b/cpukit/librpc/include/rpc/types.h
new file mode 100644
index 0000000000..997a31defd
--- /dev/null
+++ b/cpukit/librpc/include/rpc/types.h
@@ -0,0 +1,68 @@
+/* $NetBSD: types.h,v 1.13 2000/06/13 01:02:44 thorpej Exp $ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)types.h 1.18 87/07/24 SMI
+ * from: @(#)types.h 2.3 88/08/15 4.0 RPCSRC
+ * $FreeBSD: src/include/rpc/types.h,v 1.11 2003/12/07 21:10:06 marcel Exp $
+ */
+
+/*
+ * Rpc additions to <sys/types.h>
+ */
+#ifndef _RPC_TYPES_H
+#define _RPC_TYPES_H
+
+#include <rtems/stdint.h>
+
+typedef int32_t bool_t;
+typedef int32_t enum_t;
+
+typedef uint32_t rpcprog_t;
+typedef uint32_t rpcvers_t;
+typedef uint32_t rpcproc_t;
+typedef uint32_t rpcprot_t;
+typedef uint32_t rpcport_t;
+typedef int32_t rpc_inline_t;
+
+#define __dontcare__ -1
+
+#ifndef FALSE
+# define FALSE (0)
+#endif
+#ifndef TRUE
+# define TRUE (1)
+#endif
+
+#define mem_alloc(bsize) malloc(bsize)
+#define mem_free(ptr, bsize) free(ptr)
+
+#include <sys/time.h>
+
+#endif /* !_RPC_TYPES_H */
diff --git a/cpukit/librpc/include/rpc/xdr.h b/cpukit/librpc/include/rpc/xdr.h
new file mode 100644
index 0000000000..13867875a7
--- /dev/null
+++ b/cpukit/librpc/include/rpc/xdr.h
@@ -0,0 +1,309 @@
+/* $NetBSD: xdr.h,v 1.19 2000/07/17 05:00:45 matt Exp $ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)xdr.h 1.19 87/04/22 SMI
+ * from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC
+ * $FreeBSD: src/include/rpc/xdr.h,v 1.23 2003/03/07 13:19:40 nectar Exp $
+ */
+
+/*
+ * xdr.h, External Data Representation Serialization Routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_XDR_H
+#define _RPC_XDR_H
+#include <sys/cdefs.h>
+
+/*
+ * XDR provides a conventional way for converting between C data
+ * types and an external bit-string representation. Library supplied
+ * routines provide for the conversion on built-in C data types. These
+ * routines and utility routines defined here are used to help implement
+ * a type encode/decode routine for each user-defined type.
+ *
+ * Each data type provides a single procedure which takes two arguments:
+ *
+ * bool_t
+ * xdrproc(xdrs, argresp)
+ * XDR *xdrs;
+ * <type> *argresp;
+ *
+ * xdrs is an instance of a XDR handle, to which or from which the data
+ * type is to be converted. argresp is a pointer to the structure to be
+ * converted. The XDR handle contains an operation field which indicates
+ * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
+ *
+ * XDR_DECODE may allocate space if the pointer argresp is null. This
+ * data can be freed with the XDR_FREE operation.
+ *
+ * We write only one procedure per data type to make it easy
+ * to keep the encode and decode procedures for a data type consistent.
+ * In many cases the same code performs all operations on a user defined type,
+ * because all the hard work is done in the component type routines.
+ * decode as a series of calls on the nested data types.
+ */
+
+/*
+ * Xdr operations. XDR_ENCODE causes the type to be encoded into the
+ * stream. XDR_DECODE causes the type to be extracted from the stream.
+ * XDR_FREE can be used to release the space allocated by an XDR_DECODE
+ * request.
+ */
+enum xdr_op {
+ XDR_ENCODE=0,
+ XDR_DECODE=1,
+ XDR_FREE=2
+};
+
+/*
+ * This is the number of bytes per unit of external data.
+ */
+#define BYTES_PER_XDR_UNIT (4)
+#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
+ * BYTES_PER_XDR_UNIT)
+
+/*
+ * The XDR handle.
+ * Contains operation which is being applied to the stream,
+ * an operations vector for the particular implementation (e.g. see xdr_mem.c),
+ * and two private fields for the use of the particular implementation.
+ */
+typedef struct __rpc_xdr {
+ enum xdr_op x_op; /* operation; fast additional param */
+ struct xdr_ops {
+ /* get a long from underlying stream */
+ bool_t (*x_getlong)(struct __rpc_xdr *, long *);
+ /* put a long to underlying stream */
+ bool_t (*x_putlong)(struct __rpc_xdr *, const long *);
+ /* get some bytes from underlying stream */
+ bool_t (*x_getbytes)(struct __rpc_xdr *, char *, u_int);
+ /* put some bytes to underlying stream */
+ bool_t (*x_putbytes)(struct __rpc_xdr *, const char *, u_int);
+ /* returns bytes off from beginning */
+ u_int (*x_getpostn)(struct __rpc_xdr *);
+ /* lets you reposition the stream */
+ bool_t (*x_setpostn)(struct __rpc_xdr *, u_int);
+ /* buf quick ptr to buffered data */
+ int32_t *(*x_inline)(struct __rpc_xdr *, u_int);
+ /* free privates of this xdr_stream */
+ void (*x_destroy)(struct __rpc_xdr *);
+ } *x_ops;
+ char * x_public; /* users' data */
+ void * x_private; /* pointer to private data */
+ char * x_base; /* private used for position info */
+ u_int x_handy; /* extra private word */
+} XDR;
+
+/*
+ * A xdrproc_t exists for each data type which is to be encoded or decoded.
+ *
+ * The second argument to the xdrproc_t is a pointer to an opaque pointer.
+ * The opaque pointer generally points to a structure of the data type
+ * to be decoded. If this pointer is 0, then the type routines should
+ * allocate dynamic storage of the appropriate size and return it.
+ */
+typedef bool_t (*xdrproc_t) (XDR *, void *, ...);
+
+/*
+ * Operations defined on a XDR handle
+ *
+ * XDR *xdrs;
+ * long *longp;
+ * caddr_t addr;
+ * u_int len;
+ * u_int pos;
+ */
+#define XDR_GETLONG(xdrs, longp) \
+ (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+#define xdr_getlong(xdrs, longp) \
+ (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+
+#define XDR_PUTLONG(xdrs, longp) \
+ (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+#define xdr_putlong(xdrs, longp) \
+ (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+
+#define XDR_GETBYTES(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+#define xdr_getbytes(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+
+#define XDR_PUTBYTES(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+#define xdr_putbytes(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+
+#define XDR_GETPOS(xdrs) \
+ (*(xdrs)->x_ops->x_getpostn)(xdrs)
+#define xdr_getpos(xdrs) \
+ (*(xdrs)->x_ops->x_getpostn)(xdrs)
+
+#define XDR_SETPOS(xdrs, pos) \
+ (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+#define xdr_setpos(xdrs, pos) \
+ (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+
+#define XDR_INLINE(xdrs, len) \
+ (*(xdrs)->x_ops->x_inline)(xdrs, len)
+#define xdr_inline(xdrs, len) \
+ (*(xdrs)->x_ops->x_inline)(xdrs, len)
+
+#define XDR_DESTROY(xdrs) \
+ if ((xdrs)->x_ops->x_destroy) \
+ (*(xdrs)->x_ops->x_destroy)(xdrs)
+#define xdr_destroy(xdrs) \
+ if ((xdrs)->x_ops->x_destroy) \
+ (*(xdrs)->x_ops->x_destroy)(xdrs)
+
+/*
+ * Support struct for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * an entry with a null procedure pointer. The xdr_union routine gets
+ * the discriminant value and then searches the array of structures
+ * for a matching value. If a match is found the associated xdr routine
+ * is called to handle that part of the union. If there is
+ * no match, then a default routine may be called.
+ * If there is no match and no default routine it is an error.
+ */
+#define NULL_xdrproc_t ((xdrproc_t)0)
+struct xdr_discrim {
+ int value;
+ xdrproc_t proc;
+};
+
+/*
+ * In-line routines for fast encode/decode of primitive data types.
+ * Caveat emptor: these use single memory cycles to get the
+ * data from the underlying buffer, and will fail to operate
+ * properly if the data is not aligned. The standard way to use these
+ * is to say:
+ * if ((buf = XDR_INLINE(xdrs, count)) == NULL)
+ * return (FALSE);
+ * <<< macro calls >>>
+ * where ``count'' is the number of bytes of data occupied
+ * by the primitive data types.
+ *
+ * N.B. and frozen for all time: each data type here uses 4 bytes
+ * of external representation.
+ */
+#define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++))
+#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v))
+
+#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf))
+#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf))
+#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf))
+
+#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+
+/*
+ * These are the "generic" xdr routines.
+ */
+__BEGIN_DECLS
+extern bool_t xdr_void(void);
+extern bool_t xdr_int(XDR *, int *);
+extern bool_t xdr_u_int(XDR *, u_int *);
+extern bool_t xdr_long(XDR *, long *);
+extern bool_t xdr_u_long(XDR *, u_long *);
+extern bool_t xdr_short(XDR *, short *);
+extern bool_t xdr_u_short(XDR *, u_short *);
+extern bool_t xdr_int16_t(XDR *, int16_t *);
+extern bool_t xdr_u_int16_t(XDR *, u_int16_t *);
+extern bool_t xdr_int32_t(XDR *, int32_t *);
+extern bool_t xdr_u_int32_t(XDR *, u_int32_t *);
+extern bool_t xdr_int64_t(XDR *, int64_t *);
+extern bool_t xdr_u_int64_t(XDR *, u_int64_t *);
+extern bool_t xdr_bool(XDR *, bool_t *);
+extern bool_t xdr_enum(XDR *, enum_t *);
+extern bool_t xdr_array(XDR *, char **, u_int *, u_int, u_int, xdrproc_t);
+extern bool_t xdr_bytes(XDR *, char **, u_int *, u_int);
+extern bool_t xdr_opaque(XDR *, caddr_t, u_int);
+extern bool_t xdr_string(XDR *, char **, u_int);
+extern bool_t xdr_union(XDR *, enum_t *, char *, const struct xdr_discrim *, xdrproc_t);
+extern unsigned long xdr_sizeof (xdrproc_t, void *);
+extern bool_t xdr_char(XDR *, char *);
+extern bool_t xdr_u_char(XDR *, u_char *);
+extern bool_t xdr_vector(XDR *, char *, u_int, u_int, xdrproc_t);
+extern bool_t xdr_float(XDR *, float *);
+extern bool_t xdr_double(XDR *, double *);
+extern bool_t xdr_reference(XDR *, caddr_t *, u_int, xdrproc_t);
+extern bool_t xdr_pointer(XDR *, caddr_t *, u_int, xdrproc_t);
+extern bool_t xdr_wrapstring(XDR *, char **);
+extern void xdr_free(xdrproc_t, char *);
+__END_DECLS
+
+/*
+ * Common opaque bytes objects used by many rpc protocols;
+ * declared here due to commonality.
+ */
+#define MAX_NETOBJ_SZ 1024
+struct netobj {
+ u_int n_len;
+ char *n_bytes;
+};
+typedef struct netobj netobj;
+extern bool_t xdr_netobj(XDR *, struct netobj *);
+
+/*
+ * These are the public routines for the various implementations of
+ * xdr streams.
+ */
+__BEGIN_DECLS
+/* XDR using memory buffers */
+extern void xdrmem_create(XDR *, char *, u_int, enum xdr_op);
+
+/* XDR using stdio library */
+#ifdef _STDIO_H_
+extern void xdrstdio_create(XDR *, FILE *, enum xdr_op);
+#endif
+
+/* XDR pseudo records for tcp */
+extern void xdrrec_create(XDR *, u_int, u_int, char *,
+ int (*) (caddr_t, caddr_t, int),
+ int (*) (caddr_t, caddr_t, int));
+
+/* make end of xdr record */
+extern bool_t xdrrec_endofrecord(XDR *, bool_t);
+
+/* move to beginning of next record */
+extern bool_t xdrrec_skiprecord(XDR *);
+
+/* true if no more input */
+extern bool_t xdrrec_eof(XDR *);
+__END_DECLS
+
+#endif /* !_RPC_XDR_H */
diff --git a/cpukit/librpc/include/rpcsvc/bootparam_prot.x b/cpukit/librpc/include/rpcsvc/bootparam_prot.x
new file mode 100644
index 0000000000..0f74c8f8ad
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/bootparam_prot.x
@@ -0,0 +1,103 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * RPC for bootparms service.
+ * There are two procedures:
+ * WHOAMI takes a net address and returns a client name and also a
+ * likely net address for routing
+ * GETFILE takes a client name and file identifier and returns the
+ * server name, server net address and pathname for the file.
+ * file identifiers typically include root, swap, pub and dump
+ */
+
+#ifdef RPC_HDR
+%#include <rpc/types.h>
+%#include <sys/time.h>
+%#include <sys/errno.h>
+%#include <sys/param.h>
+%#include <sys/syslimits.h>
+%#include <sys/ucred.h>
+#else
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)bootparam_prot.x 1.2 87/06/24 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)bootparam_prot.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/bootparam_prot.x,v 1.5 1999/08/27 23:45:07 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const MAX_MACHINE_NAME = 255;
+const MAX_PATH_LEN = 1024;
+const MAX_FILEID = 32;
+const IP_ADDR_TYPE = 1;
+
+typedef string bp_machine_name_t<MAX_MACHINE_NAME>;
+typedef string bp_path_t<MAX_PATH_LEN>;
+typedef string bp_fileid_t<MAX_FILEID>;
+
+struct ip_addr_t {
+ char net;
+ char host;
+ char lh;
+ char impno;
+};
+
+union bp_address switch (int address_type) {
+ case IP_ADDR_TYPE:
+ ip_addr_t ip_addr;
+};
+
+struct bp_whoami_arg {
+ bp_address client_address;
+};
+
+struct bp_whoami_res {
+ bp_machine_name_t client_name;
+ bp_machine_name_t domain_name;
+ bp_address router_address;
+};
+
+struct bp_getfile_arg {
+ bp_machine_name_t client_name;
+ bp_fileid_t file_id;
+};
+
+struct bp_getfile_res {
+ bp_machine_name_t server_name;
+ bp_address server_address;
+ bp_path_t server_path;
+};
+
+program BOOTPARAMPROG {
+ version BOOTPARAMVERS {
+ bp_whoami_res BOOTPARAMPROC_WHOAMI(bp_whoami_arg) = 1;
+ bp_getfile_res BOOTPARAMPROC_GETFILE(bp_getfile_arg) = 2;
+ } = 1;
+} = 100026;
diff --git a/cpukit/librpc/include/rpcsvc/crypt.x b/cpukit/librpc/include/rpcsvc/crypt.x
new file mode 100644
index 0000000000..8df1654440
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/crypt.x
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1996
+ * Bill Paul <wpaul@ctr.columbia.edu>. 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 Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul 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.
+ *
+ * $FreeBSD: src/include/rpcsvc/crypt.x,v 1.3 1999/08/27 23:45:08 peter Exp $
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/crypt.x,v 1.3 1999/08/27 23:45:08 peter Exp $";
+%#endif
+#endif
+
+/*
+ * This protocol definition exists because of the U.S. government and
+ * its stupid export laws. We can't export DES code from the United
+ * States to other countries (even though the code already exists
+ * outside the U.S. -- go figure that one out) but we need to make
+ * Secure RPC work. The normal way around this is to break the DES
+ * code out into a shared library; we can then provide a dummy lib
+ * in the base OS and provide the real lib in the secure dist, which
+ * the user can install later. But we need Secure RPC for NIS+, and
+ * there are several system programs that use NIS+ which are statically
+ * linked. We would have to provide replacements for these programs
+ * in the secure dist, but there are a lot, and this is a pain. The
+ * shared lib trick won't work for these programs, and we can't change
+ * them once they're compiled.
+ *
+ * One solution for this problem is to do the DES encryption as a system
+ * call; no programs need to be changed and we can even supply the DES
+ * support as an LKM. But this bloats the kernel. Maybe if we have
+ * Secure NFS one day this will be worth it, but for now we should keep
+ * this mess in user space.
+ *
+ * So we have this second solution: we provide a server that does the
+ * DES encryption for us. In this case, the server is keyserv (we need
+ * it to make Secure RPC work anyway) and we use this protocol to ship
+ * the data back and forth between keyserv and the application.
+ */
+
+enum des_dir { ENCRYPT_DES, DECRYPT_DES };
+enum des_mode { CBC_DES, ECB_DES };
+
+struct desargs {
+ u_char des_key[8]; /* key (with low bit parity) */
+ des_dir des_dir; /* direction */
+ des_mode des_mode; /* mode */
+ u_char des_ivec[8]; /* input vector */
+ opaque desbuf<>;
+};
+
+struct desresp {
+ opaque desbuf<>;
+ u_char des_ivec[8];
+ int stat;
+};
+
+program CRYPT_PROG {
+ version CRYPT_VERS {
+ desresp
+ DES_CRYPT(desargs) = 1;
+ } = 1;
+} = 600100029;
diff --git a/cpukit/librpc/include/rpcsvc/key_prot.x b/cpukit/librpc/include/rpcsvc/key_prot.x
new file mode 100644
index 0000000000..f545569e01
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/key_prot.x
@@ -0,0 +1,282 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+/*
+ * Key server protocol definition
+ * Copyright (C) 1990, 1991 Sun Microsystems, Inc.
+ *
+ * The keyserver is a public key storage/encryption/decryption service
+ * The encryption method used is based on the Diffie-Hellman exponential
+ * key exchange technology.
+ *
+ * The key server is local to each machine, akin to the portmapper.
+ * Under TI-RPC, communication with the keyserver is through the
+ * loopback transport.
+ *
+ * NOTE: This .x file generates the USER level headers for the keyserver.
+ * the KERNEL level headers are created by hand as they kernel has special
+ * requirements.
+ */
+
+%/* From: #pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI" */
+%
+%/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */
+%
+%/*
+% * Compiled from key_prot.x using rpcgen.
+% * DO NOT EDIT THIS FILE!
+% * This is NOT source code!
+% */
+
+/*
+ * PROOT and MODULUS define the way the Diffie-Hellman key is generated.
+ *
+ * MODULUS should be chosen as a prime of the form: MODULUS == 2*p + 1,
+ * where p is also prime.
+ *
+ * PROOT satisfies the following two conditions:
+ * (1) (PROOT ** 2) % MODULUS != 1
+ * (2) (PROOT ** p) % MODULUS != 1
+ *
+ */
+
+const PROOT = 3;
+const HEXMODULUS = "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b";
+
+const HEXKEYBYTES = 48; /* HEXKEYBYTES == strlen(HEXMODULUS) */
+const KEYSIZE = 192; /* KEYSIZE == bit length of key */
+const KEYBYTES = 24; /* byte length of key */
+
+/*
+ * The first 16 hex digits of the encrypted secret key are used as
+ * a checksum in the database.
+ */
+const KEYCHECKSUMSIZE = 16;
+
+/*
+ * status of operation
+ */
+enum keystatus {
+ KEY_SUCCESS, /* no problems */
+ KEY_NOSECRET, /* no secret key stored */
+ KEY_UNKNOWN, /* unknown netname */
+ KEY_SYSTEMERR /* system error (out of memory, encryption failure) */
+};
+
+typedef opaque keybuf[HEXKEYBYTES]; /* store key in hex */
+
+typedef string netnamestr<MAXNETNAMELEN>;
+
+/*
+ * Argument to ENCRYPT or DECRYPT
+ */
+struct cryptkeyarg {
+ netnamestr remotename;
+ des_block deskey;
+};
+
+/*
+ * Argument to ENCRYPT_PK or DECRYPT_PK
+ */
+struct cryptkeyarg2 {
+ netnamestr remotename;
+ netobj remotekey; /* Contains a length up to 1024 bytes */
+ des_block deskey;
+};
+
+
+/*
+ * Result of ENCRYPT, DECRYPT, ENCRYPT_PK, and DECRYPT_PK
+ */
+union cryptkeyres switch (keystatus status) {
+case KEY_SUCCESS:
+ des_block deskey;
+default:
+ void;
+};
+
+const MAXGIDS = 16; /* max number of gids in gid list */
+
+/*
+ * Unix credential
+ */
+struct unixcred {
+ u_int uid;
+ u_int gid;
+ u_int gids<MAXGIDS>;
+};
+
+/*
+ * Result returned from GETCRED
+ */
+union getcredres switch (keystatus status) {
+case KEY_SUCCESS:
+ unixcred cred;
+default:
+ void;
+};
+/*
+ * key_netstarg;
+ */
+
+struct key_netstarg {
+ keybuf st_priv_key;
+ keybuf st_pub_key;
+ netnamestr st_netname;
+};
+
+union key_netstres switch (keystatus status){
+case KEY_SUCCESS:
+ key_netstarg knet;
+default:
+ void;
+};
+
+#ifdef RPC_HDR
+%
+%#ifndef opaque
+%#define opaque char
+%#endif
+%
+#endif
+program KEY_PROG {
+ version KEY_VERS {
+
+ /*
+ * This is my secret key.
+ * Store it for me.
+ */
+ keystatus
+ KEY_SET(keybuf) = 1;
+
+ /*
+ * I want to talk to X.
+ * Encrypt a conversation key for me.
+ */
+ cryptkeyres
+ KEY_ENCRYPT(cryptkeyarg) = 2;
+
+ /*
+ * X just sent me a message.
+ * Decrypt the conversation key for me.
+ */
+ cryptkeyres
+ KEY_DECRYPT(cryptkeyarg) = 3;
+
+ /*
+ * Generate a secure conversation key for me
+ */
+ des_block
+ KEY_GEN(void) = 4;
+
+ /*
+ * Get me the uid, gid and group-access-list associated
+ * with this netname (for kernel which cannot use NIS)
+ */
+ getcredres
+ KEY_GETCRED(netnamestr) = 5;
+ } = 1;
+ version KEY_VERS2 {
+
+ /*
+ * #######
+ * Procedures 1-5 are identical to version 1
+ * #######
+ */
+
+ /*
+ * This is my secret key.
+ * Store it for me.
+ */
+ keystatus
+ KEY_SET(keybuf) = 1;
+
+ /*
+ * I want to talk to X.
+ * Encrypt a conversation key for me.
+ */
+ cryptkeyres
+ KEY_ENCRYPT(cryptkeyarg) = 2;
+
+ /*
+ * X just sent me a message.
+ * Decrypt the conversation key for me.
+ */
+ cryptkeyres
+ KEY_DECRYPT(cryptkeyarg) = 3;
+
+ /*
+ * Generate a secure conversation key for me
+ */
+ des_block
+ KEY_GEN(void) = 4;
+
+ /*
+ * Get me the uid, gid and group-access-list associated
+ * with this netname (for kernel which cannot use NIS)
+ */
+ getcredres
+ KEY_GETCRED(netnamestr) = 5;
+
+ /*
+ * I want to talk to X. and I know X's public key
+ * Encrypt a conversation key for me.
+ */
+ cryptkeyres
+ KEY_ENCRYPT_PK(cryptkeyarg2) = 6;
+
+ /*
+ * X just sent me a message. and I know X's public key
+ * Decrypt the conversation key for me.
+ */
+ cryptkeyres
+ KEY_DECRYPT_PK(cryptkeyarg2) = 7;
+
+ /*
+ * Store my public key, netname and private key.
+ */
+ keystatus
+ KEY_NET_PUT(key_netstarg) = 8;
+
+ /*
+ * Retrieve my public key, netname and private key.
+ */
+ key_netstres
+ KEY_NET_GET(void) = 9;
+
+ /*
+ * Return me the conversation key that is constructed
+ * from my secret key and this publickey.
+ */
+
+ cryptkeyres
+ KEY_GET_CONV(keybuf) = 10;
+
+
+ } = 2;
+} = 100029;
diff --git a/cpukit/librpc/include/rpcsvc/klm_prot.x b/cpukit/librpc/include/rpcsvc/klm_prot.x
new file mode 100644
index 0000000000..c4cfe36d42
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/klm_prot.x
@@ -0,0 +1,139 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Kernel/lock manager protocol definition
+ * Copyright (C) 1986 Sun Microsystems, Inc.
+ *
+ * protocol used between the UNIX kernel (the "client") and the
+ * local lock manager. The local lock manager is a deamon running
+ * above the kernel.
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)klm_prot.x 1.7 87/07/08 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)klm_prot.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/klm_prot.x,v 1.6 1999/08/27 23:45:08 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const LM_MAXSTRLEN = 1024;
+
+/*
+ * lock manager status returns
+ */
+enum klm_stats {
+ klm_granted = 0, /* lock is granted */
+ klm_denied = 1, /* lock is denied */
+ klm_denied_nolocks = 2, /* no lock entry available */
+ klm_working = 3 /* lock is being processed */
+};
+
+/*
+ * lock manager lock identifier
+ */
+struct klm_lock {
+ string server_name<LM_MAXSTRLEN>;
+ netobj fh; /* a counted file handle */
+ int pid; /* holder of the lock */
+ unsigned l_offset; /* beginning offset of the lock */
+ unsigned l_len; /* byte length of the lock;
+ * zero means through end of file */
+};
+
+/*
+ * lock holder identifier
+ */
+struct klm_holder {
+ bool exclusive; /* FALSE if shared lock */
+ int svid; /* holder of the lock (pid) */
+ unsigned l_offset; /* beginning offset of the lock */
+ unsigned l_len; /* byte length of the lock;
+ * zero means through end of file */
+};
+
+/*
+ * reply to KLM_LOCK / KLM_UNLOCK / KLM_CANCEL
+ */
+struct klm_stat {
+ klm_stats stat;
+};
+
+/*
+ * reply to a KLM_TEST call
+ */
+union klm_testrply switch (klm_stats stat) {
+ case klm_denied:
+ struct klm_holder holder;
+ default: /* All other cases return no arguments */
+ void;
+};
+
+
+/*
+ * arguments to KLM_LOCK
+ */
+struct klm_lockargs {
+ bool block;
+ bool exclusive;
+ struct klm_lock alock;
+};
+
+/*
+ * arguments to KLM_TEST
+ */
+struct klm_testargs {
+ bool exclusive;
+ struct klm_lock alock;
+};
+
+/*
+ * arguments to KLM_UNLOCK
+ */
+struct klm_unlockargs {
+ struct klm_lock alock;
+};
+
+program KLM_PROG {
+ version KLM_VERS {
+
+ klm_testrply KLM_TEST (struct klm_testargs) = 1;
+
+ klm_stat KLM_LOCK (struct klm_lockargs) = 2;
+
+ klm_stat KLM_CANCEL (struct klm_lockargs) = 3;
+ /* klm_granted=> the cancel request fails due to lock is already granted */
+ /* klm_denied=> the cancel request successfully aborts
+lock request */
+
+ klm_stat KLM_UNLOCK (struct klm_unlockargs) = 4;
+ } = 1;
+} = 100020;
diff --git a/cpukit/librpc/include/rpcsvc/mount.x b/cpukit/librpc/include/rpcsvc/mount.x
new file mode 100644
index 0000000000..f68a06fe9b
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/mount.x
@@ -0,0 +1,257 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Protocol description for the mount program
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)mount.x 1.2 87/09/18 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)mount.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/mount.x,v 1.6 1999/08/27 23:45:08 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */
+const MNTNAMLEN = 255; /* maximum bytes in a name argument */
+const FHSIZE = 32; /* size in bytes of a file handle */
+#ifdef WANT_NFS3
+const FHSIZE3 = 64; /* size in bytes of a file handle (v3) */
+#endif
+
+/*
+ * The fhandle is the file handle that the server passes to the client.
+ * All file operations are done using the file handles to refer to a file
+ * or a directory. The file handle can contain whatever information the
+ * server needs to distinguish an individual file.
+ */
+typedef opaque fhandle[FHSIZE];
+#ifdef WANT_NFS3
+typedef opaque fhandle3<FHSIZE3>;
+#endif
+
+/*
+ * If a status of zero is returned, the call completed successfully, and
+ * a file handle for the directory follows. A non-zero status indicates
+ * some sort of error. The status corresponds with UNIX error numbers.
+ */
+union fhstatus switch (unsigned fhs_status) {
+case 0:
+ fhandle fhs_fhandle;
+default:
+ void;
+};
+
+#ifdef WANT_NFS3
+/*
+ * Status codes returned by the version 3 mount call.
+ */
+enum mountstat3 {
+ MNT3_OK = 0, /* no error */
+ MNT3ERR_PERM = 1, /* Not owner */
+ MNT3ERR_NOENT = 2, /* No such file or directory */
+ MNT3ERR_IO = 5, /* I/O error */
+ MNT3ERR_ACCES = 13, /* Permission denied */
+ MNT3ERR_NOTDIR = 20, /* Not a directory */
+ MNT3ERR_INVAL = 22, /* Invalid argument */
+ MNT3ERR_NAMETOOLONG = 63, /* Filename too long */
+ MNT3ERR_NOTSUPP = 10004, /* Operation not supported */
+ MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */
+};
+
+struct mountres3_ok {
+ fhandle3 fhandle;
+ int auth_flavors<>;
+};
+
+union mountres3 switch (mountstat3 fhs_status) {
+case 0:
+ mountres3_ok mountinfo;
+default:
+ void;
+};
+#endif
+
+/*
+ * The type dirpath is the pathname of a directory
+ */
+typedef string dirpath<MNTPATHLEN>;
+
+/*
+ * The type name is used for arbitrary names (hostnames, groupnames)
+ */
+typedef string name<MNTNAMLEN>;
+
+/*
+ * A list of who has what mounted
+ */
+typedef struct mountbody *mountlist;
+struct mountbody {
+ name ml_hostname;
+ dirpath ml_directory;
+ mountlist ml_next;
+};
+
+/*
+ * A list of netgroups
+ */
+typedef struct groupnode *groups;
+struct groupnode {
+ name gr_name;
+ groups gr_next;
+};
+
+/*
+ * A list of what is exported and to whom
+ */
+typedef struct exportnode *exports;
+struct exportnode {
+ dirpath ex_dir;
+ groups ex_groups;
+ exports ex_next;
+};
+
+program MOUNTPROG {
+ /*
+ * Version one of the mount protocol communicates with version two
+ * of the NFS protocol. Version three communicates with
+ * version three of the NFS protocol. The only connecting
+ * point is the fhandle structure, which is the same for both
+ * protocols.
+ */
+ version MOUNTVERS {
+ /*
+ * Does no work. It is made available in all RPC services
+ * to allow server reponse testing and timing
+ */
+ void
+ MOUNTPROC_NULL(void) = 0;
+
+ /*
+ * If fhs_status is 0, then fhs_fhandle contains the
+ * file handle for the directory. This file handle may
+ * be used in the NFS protocol. This procedure also adds
+ * a new entry to the mount list for this client mounting
+ * the directory.
+ * Unix authentication required.
+ */
+ fhstatus
+ MOUNTPROC_MNT(dirpath) = 1;
+
+ /*
+ * Returns the list of remotely mounted filesystems. The
+ * mountlist contains one entry for each hostname and
+ * directory pair.
+ */
+ mountlist
+ MOUNTPROC_DUMP(void) = 2;
+
+ /*
+ * Removes the mount list entry for the directory
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNT(dirpath) = 3;
+
+ /*
+ * Removes all of the mount list entries for this client
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNTALL(void) = 4;
+
+ /*
+ * Returns a list of all the exported filesystems, and which
+ * machines are allowed to import it.
+ */
+ exports
+ MOUNTPROC_EXPORT(void) = 5;
+
+ /*
+ * Identical to MOUNTPROC_EXPORT above
+ */
+ exports
+ MOUNTPROC_EXPORTALL(void) = 6;
+ } = 1;
+#ifdef WANT_NFS3
+ version MOUNTVERS3 {
+ /*
+ * Does no work. It is made available in all RPC services
+ * to allow server reponse testing and timing
+ */
+ void
+ MOUNTPROC_NULL(void) = 0;
+
+ /*
+ * If mountres3.fhs_status is MNT3_OK, then
+ * mountres3.mountinfo contains the file handle for
+ * the directory and a list of acceptable
+ * authentication flavors. This file handle may only
+ * be used in the NFS version 3 protocol. This
+ * procedure also results in the server adding a new
+ * entry to its mount list recording that this client
+ * has mounted the directory. AUTH_UNIX authentication
+ * or better is required.
+ */
+ mountres3
+ MOUNTPROC_MNT(dirpath) = 1;
+
+ /*
+ * Returns the list of remotely mounted filesystems. The
+ * mountlist contains one entry for each hostname and
+ * directory pair.
+ */
+ mountlist
+ MOUNTPROC_DUMP(void) = 2;
+
+ /*
+ * Removes the mount list entry for the directory
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNT(dirpath) = 3;
+
+ /*
+ * Removes all of the mount list entries for this client
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNTALL(void) = 4;
+
+ /*
+ * Returns a list of all the exported filesystems, and which
+ * machines are allowed to import it.
+ */
+ exports
+ MOUNTPROC_EXPORT(void) = 5;
+ } = 3;
+#endif
+} = 100005;
diff --git a/cpukit/librpc/include/rpcsvc/nfs_prot.x b/cpukit/librpc/include/rpcsvc/nfs_prot.x
new file mode 100644
index 0000000000..c1e592c1a1
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/nfs_prot.x
@@ -0,0 +1,1265 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)nfs_prot.x 1.2 87/10/12 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)nfs_prot.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/nfs_prot.x,v 1.7 1999/08/27 23:45:08 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const NFS_PORT = 2049;
+const NFS_MAXDATA = 8192;
+const NFS_MAXPATHLEN = 1024;
+const NFS_MAXNAMLEN = 255;
+const NFS_FHSIZE = 32;
+const NFS_COOKIESIZE = 4;
+const NFS_FIFO_DEV = -1; /* size kludge for named pipes */
+
+/*
+ * File types
+ */
+const NFSMODE_FMT = 0170000; /* type of file */
+const NFSMODE_DIR = 0040000; /* directory */
+const NFSMODE_CHR = 0020000; /* character special */
+const NFSMODE_BLK = 0060000; /* block special */
+const NFSMODE_REG = 0100000; /* regular */
+const NFSMODE_LNK = 0120000; /* symbolic link */
+const NFSMODE_SOCK = 0140000; /* socket */
+const NFSMODE_FIFO = 0010000; /* fifo */
+
+/*
+ * Error status
+ */
+enum nfsstat {
+ NFS_OK= 0, /* no error */
+ NFSERR_PERM=1, /* Not owner */
+ NFSERR_NOENT=2, /* No such file or directory */
+ NFSERR_IO=5, /* I/O error */
+ NFSERR_NXIO=6, /* No such device or address */
+ NFSERR_ACCES=13, /* Permission denied */
+ NFSERR_EXIST=17, /* File exists */
+ NFSERR_NODEV=19, /* No such device */
+ NFSERR_NOTDIR=20, /* Not a directory*/
+ NFSERR_ISDIR=21, /* Is a directory */
+ NFSERR_FBIG=27, /* File too large */
+ NFSERR_NOSPC=28, /* No space left on device */
+ NFSERR_ROFS=30, /* Read-only file system */
+ NFSERR_NAMETOOLONG=63, /* File name too long */
+ NFSERR_NOTEMPTY=66, /* Directory not empty */
+ NFSERR_DQUOT=69, /* Disc quota exceeded */
+ NFSERR_STALE=70, /* Stale NFS file handle */
+ NFSERR_WFLUSH=99 /* write cache flushed */
+};
+
+/*
+ * File types
+ */
+enum ftype {
+ NFNON = 0, /* non-file */
+ NFREG = 1, /* regular file */
+ NFDIR = 2, /* directory */
+ NFBLK = 3, /* block special */
+ NFCHR = 4, /* character special */
+ NFLNK = 5, /* symbolic link */
+ NFSOCK = 6, /* unix domain sockets */
+ NFBAD = 7, /* unused */
+ NFFIFO = 8 /* named pipe */
+};
+
+/*
+ * File access handle
+ */
+struct nfs_fh {
+ opaque data[NFS_FHSIZE];
+};
+
+/*
+ * Timeval
+ */
+struct nfstime {
+ unsigned seconds;
+ unsigned useconds;
+};
+
+
+/*
+ * File attributes
+ */
+struct fattr {
+ ftype type; /* file type */
+ unsigned mode; /* protection mode bits */
+ unsigned nlink; /* # hard links */
+ unsigned uid; /* owner user id */
+ unsigned gid; /* owner group id */
+ unsigned size; /* file size in bytes */
+ unsigned blocksize; /* prefered block size */
+ unsigned rdev; /* special device # */
+ unsigned blocks; /* Kb of disk used by file */
+ unsigned fsid; /* device # */
+ unsigned fileid; /* inode # */
+ nfstime atime; /* time of last access */
+ nfstime mtime; /* time of last modification */
+ nfstime ctime; /* time of last change */
+};
+
+/*
+ * File attributes which can be set
+ */
+struct sattr {
+ unsigned mode; /* protection mode bits */
+ unsigned uid; /* owner user id */
+ unsigned gid; /* owner group id */
+ unsigned size; /* file size in bytes */
+ nfstime atime; /* time of last access */
+ nfstime mtime; /* time of last modification */
+};
+
+
+typedef string filename<NFS_MAXNAMLEN>;
+typedef string nfspath<NFS_MAXPATHLEN>;
+
+/*
+ * Reply status with file attributes
+ */
+union attrstat switch (nfsstat status) {
+case NFS_OK:
+ fattr attributes;
+default:
+ void;
+};
+
+struct sattrargs {
+ nfs_fh file;
+ sattr attributes;
+};
+
+/*
+ * Arguments for directory operations
+ */
+struct diropargs {
+ nfs_fh dir; /* directory file handle */
+ filename name; /* name (up to NFS_MAXNAMLEN bytes) */
+};
+
+struct diropokres {
+ nfs_fh file;
+ fattr attributes;
+};
+
+/*
+ * Results from directory operation
+ */
+union diropres switch (nfsstat status) {
+case NFS_OK:
+ diropokres diropres;
+default:
+ void;
+};
+
+union readlinkres switch (nfsstat status) {
+case NFS_OK:
+ nfspath data;
+default:
+ void;
+};
+
+/*
+ * Arguments to remote read
+ */
+struct readargs {
+ nfs_fh file; /* handle for file */
+ unsigned offset; /* byte offset in file */
+ unsigned count; /* immediate read count */
+ unsigned totalcount; /* total read count (from this offset)*/
+};
+
+/*
+ * Status OK portion of remote read reply
+ */
+struct readokres {
+ fattr attributes; /* attributes, need for pagin*/
+ opaque data<NFS_MAXDATA>;
+};
+
+union readres switch (nfsstat status) {
+case NFS_OK:
+ readokres reply;
+default:
+ void;
+};
+
+/*
+ * Arguments to remote write
+ */
+struct writeargs {
+ nfs_fh file; /* handle for file */
+ unsigned beginoffset; /* beginning byte offset in file */
+ unsigned offset; /* current byte offset in file */
+ unsigned totalcount; /* total write count (to this offset)*/
+ opaque data<NFS_MAXDATA>;
+};
+
+struct createargs {
+ diropargs where;
+ sattr attributes;
+};
+
+struct renameargs {
+ diropargs from;
+ diropargs to;
+};
+
+struct linkargs {
+ nfs_fh from;
+ diropargs to;
+};
+
+struct symlinkargs {
+ diropargs from;
+ nfspath to;
+ sattr attributes;
+};
+
+
+typedef opaque nfscookie[NFS_COOKIESIZE];
+
+/*
+ * Arguments to readdir
+ */
+struct readdirargs {
+ nfs_fh dir; /* directory handle */
+ nfscookie cookie;
+ unsigned count; /* number of directory bytes to read */
+};
+
+struct entry {
+ unsigned fileid;
+ filename name;
+ nfscookie cookie;
+ entry *nextentry;
+};
+
+struct dirlist {
+ entry *entries;
+ bool eof;
+};
+
+union readdirres switch (nfsstat status) {
+case NFS_OK:
+ dirlist reply;
+default:
+ void;
+};
+
+struct statfsokres {
+ unsigned tsize; /* preferred transfer size in bytes */
+ unsigned bsize; /* fundamental file system block size */
+ unsigned blocks; /* total blocks in file system */
+ unsigned bfree; /* free blocks in fs */
+ unsigned bavail; /* free blocks avail to non-superuser */
+};
+
+union statfsres switch (nfsstat status) {
+case NFS_OK:
+ statfsokres reply;
+default:
+ void;
+};
+
+#ifdef WANT_NFS3
+
+/*
+ * NFSv3 constants and types
+ */
+const NFS3_FHSIZE = 64; /* maximum size in bytes of a file handle */
+const NFS3_COOKIEVERFSIZE = 8; /* size of a cookie verifier for READDIR */
+const NFS3_CREATEVERFSIZE = 8; /* size of the verifier used for CREATE */
+const NFS3_WRITEVERFSIZE = 8; /* size of the verifier used for WRITE */
+
+typedef unsigned hyper uint64;
+typedef hyper int64;
+typedef unsigned long uint32;
+typedef long int32;
+typedef string filename3<>;
+typedef string nfspath3<>;
+typedef uint64 fileid3;
+typedef uint64 cookie3;
+typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
+typedef opaque createverf3[NFS3_CREATEVERFSIZE];
+typedef opaque writeverf3[NFS3_WRITEVERFSIZE];
+typedef uint32 uid3;
+typedef uint32 gid3;
+typedef uint64 size3;
+typedef uint64 offset3;
+typedef uint32 mode3;
+typedef uint32 count3;
+
+/*
+ * Error status (v3)
+ */
+enum nfsstat3 {
+ NFS3_OK = 0,
+ NFS3ERR_PERM = 1,
+ NFS3ERR_NOENT = 2,
+ NFS3ERR_IO = 5,
+ NFS3ERR_NXIO = 6,
+ NFS3ERR_ACCES = 13,
+ NFS3ERR_EXIST = 17,
+ NFS3ERR_XDEV = 18,
+ NFS3ERR_NODEV = 19,
+ NFS3ERR_NOTDIR = 20,
+ NFS3ERR_ISDIR = 21,
+ NFS3ERR_INVAL = 22,
+ NFS3ERR_FBIG = 27,
+ NFS3ERR_NOSPC = 28,
+ NFS3ERR_ROFS = 30,
+ NFS3ERR_MLINK = 31,
+ NFS3ERR_NAMETOOLONG = 63,
+ NFS3ERR_NOTEMPTY = 66,
+ NFS3ERR_DQUOT = 69,
+ NFS3ERR_STALE = 70,
+ NFS3ERR_REMOTE = 71,
+ NFS3ERR_BADHANDLE = 10001,
+ NFS3ERR_NOT_SYNC = 10002,
+ NFS3ERR_BAD_COOKIE = 10003,
+ NFS3ERR_NOTSUPP = 10004,
+ NFS3ERR_TOOSMALL = 10005,
+ NFS3ERR_SERVERFAULT = 10006,
+ NFS3ERR_BADTYPE = 10007,
+ NFS3ERR_JUKEBOX = 10008
+};
+
+/*
+ * File types (v3)
+ */
+enum ftype3 {
+ NF3REG = 1, /* regular file */
+ NF3DIR = 2, /* directory */
+ NF3BLK = 3, /* block special */
+ NF3CHR = 4, /* character special */
+ NF3LNK = 5, /* symbolic link */
+ NF3SOCK = 6, /* unix domain sockets */
+ NF3FIFO = 7 /* named pipe */
+};
+
+struct specdata3 {
+ uint32 specdata1;
+ uint32 specdata2;
+};
+
+/*
+ * File access handle (v3)
+ */
+struct nfs_fh3 {
+ opaque data<NFS3_FHSIZE>;
+};
+
+/*
+ * Timeval (v3)
+ */
+struct nfstime3 {
+ uint32 seconds;
+ uint32 nseconds;
+};
+
+
+/*
+ * File attributes (v3)
+ */
+struct fattr3 {
+ ftype3 type; /* file type */
+ mode3 mode; /* protection mode bits */
+ uint32 nlink; /* # hard links */
+ uid3 uid; /* owner user id */
+ gid3 gid; /* owner group id */
+ size3 size; /* file size in bytes */
+ size3 used; /* prefered block size */
+ specdata3 rdev; /* special device # */
+ uint64 fsid; /* device # */
+ fileid3 fileid; /* inode # */
+ nfstime3 atime; /* time of last access */
+ nfstime3 mtime; /* time of last modification */
+ nfstime3 ctime; /* time of last change */
+};
+
+union post_op_attr switch (bool attributes_follow) {
+case TRUE:
+ fattr3 attributes;
+case FALSE:
+ void;
+};
+
+struct wcc_attr {
+ size3 size;
+ nfstime3 mtime;
+ nfstime3 ctime;
+};
+
+union pre_op_attr switch (bool attributes_follow) {
+case TRUE:
+ wcc_attr attributes;
+case FALSE:
+ void;
+};
+
+struct wcc_data {
+ pre_op_attr before;
+ post_op_attr after;
+};
+
+union post_op_fh3 switch (bool handle_follows) {
+case TRUE:
+ nfs_fh3 handle;
+case FALSE:
+ void;
+};
+
+/*
+ * File attributes which can be set (v3)
+ */
+enum time_how {
+ DONT_CHANGE = 0,
+ SET_TO_SERVER_TIME = 1,
+ SET_TO_CLIENT_TIME = 2
+};
+
+union set_mode3 switch (bool set_it) {
+case TRUE:
+ mode3 mode;
+default:
+ void;
+};
+
+union set_uid3 switch (bool set_it) {
+case TRUE:
+ uid3 uid;
+default:
+ void;
+};
+
+union set_gid3 switch (bool set_it) {
+case TRUE:
+ gid3 gid;
+default:
+ void;
+};
+
+union set_size3 switch (bool set_it) {
+case TRUE:
+ size3 size;
+default:
+ void;
+};
+
+union set_atime switch (time_how set_it) {
+case SET_TO_CLIENT_TIME:
+ nfstime3 atime;
+default:
+ void;
+};
+
+union set_mtime switch (time_how set_it) {
+case SET_TO_CLIENT_TIME:
+ nfstime3 mtime;
+default:
+ void;
+};
+
+struct sattr3 {
+ set_mode3 mode;
+ set_uid3 uid;
+ set_gid3 gid;
+ set_size3 size;
+ set_atime atime;
+ set_mtime mtime;
+};
+
+/*
+ * Arguments for directory operations (v3)
+ */
+struct diropargs3 {
+ nfs_fh3 dir; /* directory file handle */
+ filename3 name; /* name (up to NFS_MAXNAMLEN bytes) */
+};
+
+/*
+ * Arguments to getattr (v3).
+ */
+struct GETATTR3args {
+ nfs_fh3 object;
+};
+
+struct GETATTR3resok {
+ fattr3 obj_attributes;
+};
+
+union GETATTR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ GETATTR3resok resok;
+default:
+ void;
+};
+
+/*
+ * Arguments to setattr (v3).
+ */
+union sattrguard3 switch (bool check) {
+case TRUE:
+ nfstime3 obj_ctime;
+case FALSE:
+ void;
+};
+
+struct SETATTR3args {
+ nfs_fh3 object;
+ sattr3 new_attributes;
+ sattrguard3 guard;
+};
+
+struct SETATTR3resok {
+ wcc_data obj_wcc;
+};
+
+struct SETATTR3resfail {
+ wcc_data obj_wcc;
+};
+
+union SETATTR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ SETATTR3resok resok;
+default:
+ SETATTR3resfail resfail;
+};
+
+/*
+ * Arguments to lookup (v3).
+ */
+struct LOOKUP3args {
+ diropargs3 what;
+};
+
+struct LOOKUP3resok {
+ nfs_fh3 object;
+ post_op_attr obj_attributes;
+ post_op_attr dir_attributes;
+};
+
+struct LOOKUP3resfail {
+ post_op_attr dir_attributes;
+};
+
+union LOOKUP3res switch (nfsstat3 status) {
+case NFS3_OK:
+ LOOKUP3resok resok;
+default:
+ LOOKUP3resfail resfail;
+};
+
+/*
+ * Arguments to access (v3).
+ */
+const ACCESS3_READ = 0x0001;
+const ACCESS3_LOOKUP = 0x0002;
+const ACCESS3_MODIFY = 0x0004;
+const ACCESS3_EXTEND = 0x0008;
+const ACCESS3_DELETE = 0x0010;
+const ACCESS3_EXECUTE = 0x0020;
+
+struct ACCESS3args {
+ nfs_fh3 object;
+ uint32 access;
+};
+
+struct ACCESS3resok {
+ post_op_attr obj_attributes;
+ uint32 access;
+};
+
+struct ACCESS3resfail {
+ post_op_attr obj_attributes;
+};
+
+union ACCESS3res switch (nfsstat3 status) {
+case NFS3_OK:
+ ACCESS3resok resok;
+default:
+ ACCESS3resfail resfail;
+};
+
+/*
+ * Arguments to readlink (v3).
+ */
+struct READLINK3args {
+ nfs_fh3 symlink;
+};
+
+struct READLINK3resok {
+ post_op_attr symlink_attributes;
+ nfspath3 data;
+};
+
+struct READLINK3resfail {
+ post_op_attr symlink_attributes;
+};
+
+union READLINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READLINK3resok resok;
+default:
+ READLINK3resfail resfail;
+};
+
+/*
+ * Arguments to read (v3).
+ */
+struct READ3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+};
+
+struct READ3resok {
+ post_op_attr file_attributes;
+ count3 count;
+ bool eof;
+ opaque data<>;
+};
+
+struct READ3resfail {
+ post_op_attr file_attributes;
+};
+
+/* XXX: solaris 2.6 uses ``nfsstat'' here */
+union READ3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READ3resok resok;
+default:
+ READ3resfail resfail;
+};
+
+/*
+ * Arguments to write (v3).
+ */
+enum stable_how {
+ UNSTABLE = 0,
+ DATA_SYNC = 1,
+ FILE_SYNC = 2
+};
+
+struct WRITE3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+ stable_how stable;
+ opaque data<>;
+};
+
+struct WRITE3resok {
+ wcc_data file_wcc;
+ count3 count;
+ stable_how committed;
+ writeverf3 verf;
+};
+
+struct WRITE3resfail {
+ wcc_data file_wcc;
+};
+
+union WRITE3res switch (nfsstat3 status) {
+case NFS3_OK:
+ WRITE3resok resok;
+default:
+ WRITE3resfail resfail;
+};
+
+/*
+ * Arguments to create (v3).
+ */
+enum createmode3 {
+ UNCHECKED = 0,
+ GUARDED = 1,
+ EXCLUSIVE = 2
+};
+
+union createhow3 switch (createmode3 mode) {
+case UNCHECKED:
+case GUARDED:
+ sattr3 obj_attributes;
+case EXCLUSIVE:
+ createverf3 verf;
+};
+
+struct CREATE3args {
+ diropargs3 where;
+ createhow3 how;
+};
+
+struct CREATE3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct CREATE3resfail {
+ wcc_data dir_wcc;
+};
+
+union CREATE3res switch (nfsstat3 status) {
+case NFS3_OK:
+ CREATE3resok resok;
+default:
+ CREATE3resfail resfail;
+};
+
+/*
+ * Arguments to mkdir (v3).
+ */
+struct MKDIR3args {
+ diropargs3 where;
+ sattr3 attributes;
+};
+
+struct MKDIR3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct MKDIR3resfail {
+ wcc_data dir_wcc;
+};
+
+union MKDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ MKDIR3resok resok;
+default:
+ MKDIR3resfail resfail;
+};
+
+/*
+ * Arguments to symlink (v3).
+ */
+struct symlinkdata3 {
+ sattr3 symlink_attributes;
+ nfspath3 symlink_data;
+};
+
+struct SYMLINK3args {
+ diropargs3 where;
+ symlinkdata3 symlink;
+};
+
+struct SYMLINK3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct SYMLINK3resfail {
+ wcc_data dir_wcc;
+};
+
+union SYMLINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+ SYMLINK3resok resok;
+default:
+ SYMLINK3resfail resfail;
+};
+
+/*
+ * Arguments to mknod (v3).
+ */
+struct devicedata3 {
+ sattr3 dev_attributes;
+ specdata3 spec;
+};
+
+union mknoddata3 switch (ftype3 type) {
+case NF3CHR:
+case NF3BLK:
+ devicedata3 device;
+case NF3SOCK:
+case NF3FIFO:
+ sattr3 pipe_attributes;
+default:
+ void;
+};
+
+struct MKNOD3args {
+ diropargs3 where;
+ mknoddata3 what;
+};
+
+struct MKNOD3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct MKNOD3resfail {
+ wcc_data dir_wcc;
+};
+
+union MKNOD3res switch (nfsstat3 status) {
+case NFS3_OK:
+ MKNOD3resok resok;
+default:
+ MKNOD3resfail resfail;
+};
+
+/*
+ * Arguments to remove (v3).
+ */
+struct REMOVE3args {
+ diropargs3 object;
+};
+
+struct REMOVE3resok {
+ wcc_data dir_wcc;
+};
+
+struct REMOVE3resfail {
+ wcc_data dir_wcc;
+};
+
+union REMOVE3res switch (nfsstat3 status) {
+case NFS3_OK:
+ REMOVE3resok resok;
+default:
+ REMOVE3resfail resfail;
+};
+
+/*
+ * Arguments to rmdir (v3).
+ */
+struct RMDIR3args {
+ diropargs3 object;
+};
+
+struct RMDIR3resok {
+ wcc_data dir_wcc;
+};
+
+struct RMDIR3resfail {
+ wcc_data dir_wcc;
+};
+
+union RMDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ RMDIR3resok resok;
+default:
+ RMDIR3resfail resfail;
+};
+
+/*
+ * Arguments to rename (v3).
+ */
+struct RENAME3args {
+ diropargs3 from;
+ diropargs3 to;
+};
+
+struct RENAME3resok {
+ wcc_data fromdir_wcc;
+ wcc_data todir_wcc;
+};
+
+struct RENAME3resfail {
+ wcc_data fromdir_wcc;
+ wcc_data todir_wcc;
+};
+
+union RENAME3res switch (nfsstat3 status) {
+case NFS3_OK:
+ RENAME3resok resok;
+default:
+ RENAME3resfail resfail;
+};
+
+/*
+ * Arguments to link (v3).
+ */
+struct LINK3args {
+ nfs_fh3 file;
+ diropargs3 link;
+};
+
+struct LINK3resok {
+ post_op_attr file_attributes;
+ wcc_data linkdir_wcc;
+};
+
+struct LINK3resfail {
+ post_op_attr file_attributes;
+ wcc_data linkdir_wcc;
+};
+
+union LINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+ LINK3resok resok;
+default:
+ LINK3resfail resfail;
+};
+
+/*
+ * Arguments to readdir (v3).
+ */
+struct READDIR3args {
+ nfs_fh3 dir;
+ cookie3 cookie;
+ cookieverf3 cookieverf;
+ count3 count;
+};
+
+struct entry3 {
+ fileid3 fileid;
+ filename3 name;
+ cookie3 cookie;
+ entry3 *nextentry;
+};
+
+struct dirlist3 {
+ entry3 *entries;
+ bool eof;
+};
+
+struct READDIR3resok {
+ post_op_attr dir_attributes;
+ cookieverf3 cookieverf;
+ dirlist3 reply;
+};
+
+struct READDIR3resfail {
+ post_op_attr dir_attributes;
+};
+
+union READDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READDIR3resok resok;
+default:
+ READDIR3resfail resfail;
+};
+
+/*
+ * Arguments to readdirplus (v3).
+ */
+struct READDIRPLUS3args {
+ nfs_fh3 dir;
+ cookie3 cookie;
+ cookieverf3 cookieverf;
+ count3 dircount;
+ count3 maxcount;
+};
+
+struct entryplus3 {
+ fileid3 fileid;
+ filename3 name;
+ cookie3 cookie;
+ post_op_attr name_attributes;
+ post_op_fh3 name_handle;
+ entryplus3 *nextentry;
+};
+
+struct dirlistplus3 {
+ entryplus3 *entries;
+ bool eof;
+};
+
+struct READDIRPLUS3resok {
+ post_op_attr dir_attributes;
+ cookieverf3 cookieverf;
+ dirlistplus3 reply;
+};
+
+struct READDIRPLUS3resfail {
+ post_op_attr dir_attributes;
+};
+
+union READDIRPLUS3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READDIRPLUS3resok resok;
+default:
+ READDIRPLUS3resfail resfail;
+};
+
+/*
+ * Arguments to fsstat (v3).
+ */
+struct FSSTAT3args {
+ nfs_fh3 fsroot;
+};
+
+struct FSSTAT3resok {
+ post_op_attr obj_attributes;
+ size3 tbytes;
+ size3 fbytes;
+ size3 abytes;
+ size3 tfiles;
+ size3 ffiles;
+ size3 afiles;
+ uint32 invarsec;
+};
+
+struct FSSTAT3resfail {
+ post_op_attr obj_attributes;
+};
+
+union FSSTAT3res switch (nfsstat3 status) {
+case NFS3_OK:
+ FSSTAT3resok resok;
+default:
+ FSSTAT3resfail resfail;
+};
+
+/*
+ * Arguments to fsinfo (v3).
+ */
+const FSF3_LINK = 0x0001;
+const FSF3_SYMLINK = 0x0002;
+const FSF3_HOMOGENEOUS = 0x0008;
+const FSF3_CANSETTIME = 0x0010;
+
+struct FSINFO3args {
+ nfs_fh3 fsroot;
+};
+
+struct FSINFO3resok {
+ post_op_attr obj_attributes;
+ uint32 rtmax;
+ uint32 rtpref;
+ uint32 rtmult;
+ uint32 wtmax;
+ uint32 wtpref;
+ uint32 wtmult;
+ uint32 dtpref;
+ size3 maxfilesize;
+ nfstime3 time_delta;
+ uint32 properties;
+};
+
+struct FSINFO3resfail {
+ post_op_attr obj_attributes;
+};
+
+union FSINFO3res switch (nfsstat3 status) {
+case NFS3_OK:
+ FSINFO3resok resok;
+default:
+ FSINFO3resfail resfail;
+};
+
+/*
+ * Arguments to pathconf (v3).
+ */
+struct PATHCONF3args {
+ nfs_fh3 object;
+};
+
+struct PATHCONF3resok {
+ post_op_attr obj_attributes;
+ uint32 linkmax;
+ uint32 name_max;
+ bool no_trunc;
+ bool chown_restricted;
+ bool case_insensitive;
+ bool case_preserving;
+};
+
+struct PATHCONF3resfail {
+ post_op_attr obj_attributes;
+};
+
+union PATHCONF3res switch (nfsstat3 status) {
+case NFS3_OK:
+ PATHCONF3resok resok;
+default:
+ PATHCONF3resfail resfail;
+};
+
+/*
+ * Arguments to commit (v3).
+ */
+struct COMMIT3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+};
+
+struct COMMIT3resok {
+ wcc_data file_wcc;
+ writeverf3 verf;
+};
+
+struct COMMIT3resfail {
+ wcc_data file_wcc;
+};
+
+union COMMIT3res switch (nfsstat3 status) {
+case NFS3_OK:
+ COMMIT3resok resok;
+default:
+ COMMIT3resfail resfail;
+};
+
+#endif /* WANT_NFS3 */
+
+/*
+ * Remote file service routines
+ */
+program NFS_PROGRAM {
+ version NFS_VERSION {
+ void
+ NFSPROC_NULL(void) = 0;
+
+ attrstat
+ NFSPROC_GETATTR(nfs_fh) = 1;
+
+ attrstat
+ NFSPROC_SETATTR(sattrargs) = 2;
+
+ void
+ NFSPROC_ROOT(void) = 3;
+
+ diropres
+ NFSPROC_LOOKUP(diropargs) = 4;
+
+ readlinkres
+ NFSPROC_READLINK(nfs_fh) = 5;
+
+ readres
+ NFSPROC_READ(readargs) = 6;
+
+ void
+ NFSPROC_WRITECACHE(void) = 7;
+
+ attrstat
+ NFSPROC_WRITE(writeargs) = 8;
+
+ diropres
+ NFSPROC_CREATE(createargs) = 9;
+
+ nfsstat
+ NFSPROC_REMOVE(diropargs) = 10;
+
+ nfsstat
+ NFSPROC_RENAME(renameargs) = 11;
+
+ nfsstat
+ NFSPROC_LINK(linkargs) = 12;
+
+ nfsstat
+ NFSPROC_SYMLINK(symlinkargs) = 13;
+
+ diropres
+ NFSPROC_MKDIR(createargs) = 14;
+
+ nfsstat
+ NFSPROC_RMDIR(diropargs) = 15;
+
+ readdirres
+ NFSPROC_READDIR(readdirargs) = 16;
+
+ statfsres
+ NFSPROC_STATFS(nfs_fh) = 17;
+ } = 2;
+} = 100003;
+#ifdef WANT_NFS3
+program NFS3_PROGRAM {
+ version NFS_V3 {
+ void
+ NFSPROC3_NULL(void) = 0;
+
+ GETATTR3res
+ NFSPROC3_GETATTR(GETATTR3args) = 1;
+
+ SETATTR3res
+ NFSPROC3_SETATTR(SETATTR3args) = 2;
+
+ LOOKUP3res
+ NFSPROC3_LOOKUP(LOOKUP3args) = 3;
+
+ ACCESS3res
+ NFSPROC3_ACCESS(ACCESS3args) = 4;
+
+ READLINK3res
+ NFSPROC3_READLINK(READLINK3args) = 5;
+
+ READ3res
+ NFSPROC3_READ(READ3args) = 6;
+
+ WRITE3res
+ NFSPROC3_WRITE(WRITE3args) = 7;
+
+ CREATE3res
+ NFSPROC3_CREATE(CREATE3args) = 8;
+
+ MKDIR3res
+ NFSPROC3_MKDIR(MKDIR3args) = 9;
+
+ SYMLINK3res
+ NFSPROC3_SYMLINK(SYMLINK3args) = 10;
+
+ MKNOD3res
+ NFSPROC3_MKNOD(MKNOD3args) = 11;
+
+ REMOVE3res
+ NFSPROC3_REMOVE(REMOVE3args) = 12;
+
+ RMDIR3res
+ NFSPROC3_RMDIR(RMDIR3args) = 13;
+
+ RENAME3res
+ NFSPROC3_RENAME(RENAME3args) = 14;
+
+ LINK3res
+ NFSPROC3_LINK(LINK3args) = 15;
+
+ READDIR3res
+ NFSPROC3_READDIR(READDIR3args) = 16;
+
+ READDIRPLUS3res
+ NFSPROC3_READDIRPLUS(READDIRPLUS3args) = 17;
+
+ FSSTAT3res
+ NFSPROC3_FSSTAT(FSSTAT3args) = 18;
+
+ FSINFO3res
+ NFSPROC3_FSINFO(FSINFO3args) = 19;
+
+ PATHCONF3res
+ NFSPROC3_PATHCONF(PATHCONF3args) = 20;
+
+ COMMIT3res
+ NFSPROC3_COMMIT(COMMIT3args) = 21;
+ } = 3;
+} = 100003;
+#endif
diff --git a/cpukit/librpc/include/rpcsvc/nis.x b/cpukit/librpc/include/rpcsvc/nis.x
new file mode 100644
index 0000000000..ba6c6d1576
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/nis.x
@@ -0,0 +1,466 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/nis.x,v 1.3 1999/08/27 23:45:09 peter Exp $";
+%#endif /* not lint */
+#endif
+
+/*
+ * From 4.1 : @(#)nis.x 1.61 Copyright 1989 Sun Microsystems
+ *
+ * RPC Language Protocol description file for NIS Plus
+ * This version : 1.61
+ * Last Modified : 3/19/91
+ */
+#ifdef RPC_HDR
+%/*
+% * nis.h
+% *
+% * This file is the main include file for NIS clients. It contains
+% * both the client library function defines and the various data
+% * structures used by the NIS service. It includes the file nis_tags.h
+% * which defines the tag values. This allows the tags to change without
+% * having to change the nis.x file.
+% *
+% * NOTE : DO NOT EDIT THIS FILE! It is automatically generated when
+% * rpcgen is run on the nis.x file. Note that there is a
+% * simple sed script to remove some unneeded lines. (See the
+% * Makefile target nis.h)
+% *
+% */
+%#include <rpcsvc/nis_tags.h>
+#endif
+
+/* This gets stuffed into the source files. */
+#if RPC_HDR
+%#include <rpc/xdr.h>
+#endif
+/*
+ * This is just pointless.
+ */
+#ifdef SUN_STUPIDITY
+#if RPC_SVC
+%#include "nis_svc.h"
+#endif
+#endif
+
+/* Include the RPC Language description of NIS objects */
+#include "nis_object.x"
+
+/* Errors that can be returned by the service */
+enum nis_error {
+ NIS_SUCCESS = 0, /* A-ok, let's rock n roll */
+ NIS_S_SUCCESS = 1, /* Name found (maybe) */
+ NIS_NOTFOUND = 2, /* Name definitely not found */
+ NIS_S_NOTFOUND = 3, /* Name maybe not found */
+ NIS_CACHEEXPIRED = 4, /* Name exists but cache out of date */
+ NIS_NAMEUNREACHABLE = 5, /* Can't get there from here */
+ NIS_UNKNOWNOBJ = 6, /* Object type is bogus */
+ NIS_TRYAGAIN = 7, /* I'm busy, call back */
+ NIS_SYSTEMERROR = 8, /* Out of band failure */
+ NIS_CHAINBROKEN = 9, /* First/Next warning */
+ NIS_PERMISSION = 10, /* Not enough permission to access */
+ NIS_NOTOWNER = 11, /* You don't own it, sorry */
+ NIS_NOT_ME = 12, /* I don't serve this name */
+ NIS_NOMEMORY = 13, /* Outta VM! Help! */
+ NIS_NAMEEXISTS = 14, /* Can't create over another name */
+ NIS_NOTMASTER = 15, /* I'm justa secondaray, don't ask me */
+ NIS_INVALIDOBJ = 16, /* Object is broken somehow */
+ NIS_BADNAME = 17, /* Unparsable name */
+ NIS_NOCALLBACK = 18, /* Couldn't talk to call back proc */
+ NIS_CBRESULTS = 19, /* Results being called back to you */
+ NIS_NOSUCHNAME = 20, /* Name unknown */
+ NIS_NOTUNIQUE = 21, /* Value is not uniques (entry) */
+ NIS_IBMODERROR = 22, /* Inf. Base. Modify error. */
+ NIS_NOSUCHTABLE = 23, /* Name for table was wrong */
+ NIS_TYPEMISMATCH = 24, /* Entry and table type mismatch */
+ NIS_LINKNAMEERROR = 25, /* Link points to bogus name */
+ NIS_PARTIAL = 26, /* Partial success, found table */
+ NIS_TOOMANYATTRS = 27, /* Too many attributes */
+ NIS_RPCERROR = 28, /* RPC error encountered */
+ NIS_BADATTRIBUTE = 29, /* Bad or invalid attribute */
+ NIS_NOTSEARCHABLE = 30, /* Non-searchable object searched */
+ NIS_CBERROR = 31, /* Error during callback (svc crash) */
+ NIS_FOREIGNNS = 32, /* Foreign Namespace */
+ NIS_BADOBJECT = 33, /* Malformed object structure */
+ NIS_NOTSAMEOBJ = 34, /* Object swapped during deletion */
+ NIS_MODFAIL = 35, /* Failure during a Modify. */
+ NIS_BADREQUEST = 36, /* Illegal query for table */
+ NIS_NOTEMPTY = 37, /* Attempt to remove a non-empty tbl */
+ NIS_COLDSTART_ERR = 38, /* Error accesing the cold start file */
+ NIS_RESYNC = 39, /* Transaction log too far out of date */
+ NIS_FAIL = 40, /* NIS operation failed. */
+ NIS_UNAVAIL = 41, /* NIS+ service is unavailable (client) */
+ NIS_RES2BIG = 42, /* NIS+ result too big for datagram */
+ NIS_SRVAUTH = 43, /* NIS+ server wasn't authenticated. */
+ NIS_CLNTAUTH = 44, /* NIS+ Client wasn't authenticated. */
+ NIS_NOFILESPACE = 45, /* NIS+ server ran out of disk space */
+ NIS_NOPROC = 46, /* NIS+ server couldn't create new proc */
+ NIS_DUMPLATER = 47 /* NIS+ server already has dump child */
+};
+
+
+/*
+ * Structure definitions for the parameters and results of the actual
+ * NIS RPC calls.
+ *
+ * This is the standard result (in the protocol) of most of the nis
+ * requests.
+ */
+
+struct nis_result {
+ nis_error status; /* Status of the response */
+ nis_object objects<>; /* objects found */
+ netobj cookie; /* Cookie Data */
+ u_long zticks; /* server ticks */
+ u_long dticks; /* DBM ticks. */
+ u_long aticks; /* Cache (accel) ticks */
+ u_long cticks; /* Client ticks */
+};
+
+/*
+ * A Name Service request
+ * This request is used to access the name space, ns_name is the name
+ * of the object within the namespace and the object is it's value, for
+ * add/modify, a copy of the original for remove.
+ */
+
+struct ns_request {
+ nis_name ns_name; /* Name in the NIS name space */
+ nis_object ns_object<1>; /* Optional Object (add/remove) */
+};
+
+/*
+ * An information base request
+ * This request includes the NIS name of the table we wish to search, the
+ * search criteria in the form of attribute/value pairs and an optional
+ * callback program number. If the callback program number is provided
+ * the server will send back objects one at a time, otherwise it will
+ * return them all in the response.
+ */
+
+struct ib_request {
+ nis_name ibr_name; /* The name of the Table */
+ nis_attr ibr_srch<>; /* The search critereia */
+ u_long ibr_flags; /* Optional flags */
+ nis_object ibr_obj<1>; /* optional object (add/modify) */
+ nis_server ibr_cbhost<1>; /* Optional callback info */
+ u_long ibr_bufsize; /* Optional first/next bufsize */
+ netobj ibr_cookie; /* The first/next cookie */
+};
+
+/*
+ * This argument to the PING call notifies the replicas that something in
+ * a directory has changed and this is it's timestamp. The replica will use
+ * the timestamp to determine if its resync operation was successful.
+ */
+struct ping_args {
+ nis_name dir; /* Directory that had the change */
+ u_long stamp; /* timestamp of the transaction */
+};
+
+/*
+ * These are the type of entries that are stored in the transaction log,
+ * note that modifications will appear as two entries, for names, they have
+ * a "OLD" entry followed by a "NEW" entry. For entries in tables, there
+ * is a remove followed by an add. It is done this way so that we can read
+ * the log backwards to back out transactions and forwards to propogate
+ * updated.
+ */
+enum log_entry_t {
+ LOG_NOP = 0,
+ ADD_NAME = 1, /* Name Added to name space */
+ REM_NAME = 2, /* Name removed from name space */
+ MOD_NAME_OLD = 3, /* Name was modified in the name space */
+ MOD_NAME_NEW = 4, /* Name was modified in the name space */
+ ADD_IBASE = 5, /* Entry added to information base */
+ REM_IBASE = 6, /* Entry removed from information base */
+ MOD_IBASE = 7, /* Entry was modified in information base */
+ UPD_STAMP = 8 /* Update timestamp (used as fenceposts) */
+};
+
+/*
+ * This result is returned from the name service when it is requested to
+ * dump logged entries from its transaction log. Information base updates
+ * will have the name of the information base in the le_name field and
+ * a canonical set of attribute/value pairs to fully specify the entry's
+ * 'name'.
+ */
+struct log_entry {
+ u_long le_time; /* Time in seconds */
+ log_entry_t le_type; /* Type of log entry */
+ nis_name le_princp; /* Principal making the change */
+ nis_name le_name; /* Name of table/dir involved */
+ nis_attr le_attrs<>; /* List of AV pairs. */
+ nis_object le_object; /* Actual object value */
+};
+
+struct log_result {
+ nis_error lr_status; /* The status itself */
+ netobj lr_cookie; /* Used by the dump callback */
+ log_entry lr_entries<>; /* zero or more entries */
+};
+
+struct cp_result {
+ nis_error cp_status; /* Status of the checkpoint */
+ u_long cp_zticks; /* Service 'ticks' */
+ u_long cp_dticks; /* Database 'ticks' */
+};
+
+/*
+ * This structure defines a generic NIS tag list. The taglist contains
+ * zero or tags, each of which is a type and a value. (u_long).
+ * These are used to report statistics (see tag definitions below)
+ * and to set or reset state variables.
+ */
+struct nis_tag {
+ u_long tag_type; /* Statistic tag (may vary) */
+ string tag_val<1024>; /* Statistic value may also vary */
+};
+
+struct nis_taglist {
+ nis_tag tags<>; /* List of tags */
+};
+
+struct dump_args {
+ nis_name da_dir; /* Directory to dump */
+ u_long da_time; /* From this timestamp */
+ nis_server da_cbhost<1>; /* Callback to use. */
+};
+
+struct fd_args {
+ nis_name dir_name; /* The directory we're looking for */
+ nis_name requester; /* Host principal name for signature */
+};
+
+struct fd_result {
+ nis_error status; /* Status returned by function */
+ nis_name source; /* Source of this answer */
+ opaque dir_data<>; /* Directory Data (XDR'ed) */
+ opaque signature<>; /* Signature of the source */
+};
+
+
+/*
+ * What's going on here? Well, it's like this. When the service
+ * is being compiled it wants to have the service definition specific
+ * info included, and when the client is being compiled it wants that
+ * info. This includes the appropriate file which was generated by
+ * make in the protocols directory (probably /usr/include/rpcsvc).
+ *
+ * Uhm... guys? With RPC, you aren't supposed to have seperate
+ * server-specific and client-specific header files. You have one header
+ * file that's suitable for both. If your code doesn't work using just
+ * the one header file, I submit to you that it's broken.
+ * -Bill
+ */
+#ifdef SUN_STUPIDITY
+#ifdef RPC_SVC
+%#include "nis_svc.h"
+#endif
+#ifdef RPC_CLNT
+%#include "nis_clnt.h"
+#endif
+#endif
+
+program NIS_PROG {
+
+ /* RPC Language description of the NIS+ protocol */
+ version NIS_VERSION {
+ /* The name service functions */
+ nis_result NIS_LOOKUP(ns_request) = 1;
+ nis_result NIS_ADD(ns_request) = 2;
+ nis_result NIS_MODIFY(ns_request) = 3;
+ nis_result NIS_REMOVE(ns_request) = 4;
+
+ /* The information base functions */
+ nis_result NIS_IBLIST(ib_request) = 5;
+ nis_result NIS_IBADD(ib_request) = 6;
+ nis_result NIS_IBMODIFY(ib_request) = 7;
+ nis_result NIS_IBREMOVE(ib_request) = 8;
+ nis_result NIS_IBFIRST(ib_request) = 9;
+ nis_result NIS_IBNEXT(ib_request) = 10;
+
+ /* NIS Administrative functions */
+ fd_result NIS_FINDDIRECTORY(fd_args) = 12;
+
+ /* If fetch and optionally reset statistics */
+ nis_taglist NIS_STATUS(nis_taglist) = 14;
+
+ /* Dump changes to directory since time in da_time */
+ log_result NIS_DUMPLOG(dump_args) = 15;
+
+ /* Dump contents of directory named */
+ log_result NIS_DUMP(dump_args) = 16;
+
+ /* Check status of callback thread */
+ bool NIS_CALLBACK(netobj) = 17;
+
+ /* Return last update time for named dir */
+ u_long NIS_CPTIME(nis_name) = 18;
+
+ /* Checkpoint directory or table named */
+ cp_result NIS_CHECKPOINT(nis_name) = 19;
+
+ /* Send 'status changed' ping to replicates */
+ void NIS_PING(ping_args) = 20;
+
+ /* Modify server behaviour (such as debugging) */
+ nis_taglist NIS_SERVSTATE(nis_taglist) = 21;
+
+ /* Create a Directory */
+ nis_error NIS_MKDIR(nis_name) = 22;
+
+ /* Remove a Directory */
+ nis_error NIS_RMDIR(nis_name) = 23;
+
+ /* Update public keys of a directory object */
+ nis_error NIS_UPDKEYS(nis_name) = 24;
+ } = 3;
+} = 100300;
+
+/*
+ * Included below are the defines that become part of nis.h,
+ * they are technically not part of the protocol, but do define
+ * key aspects of the implementation and are therefore useful
+ * in building a conforming server or client.
+ */
+#if RPC_HDR
+%/*
+% * Generic "hash" datastructures, used by all types of hashed data.
+% */
+%struct nis_hash_data {
+% nis_name name; /* NIS name of hashed item */
+% int keychain; /* It's hash key (for pop) */
+% struct nis_hash_data *next; /* Hash collision pointer */
+% struct nis_hash_data *prv_item; /* A serial, doubly linked list */
+% struct nis_hash_data *nxt_item; /* of items in the hash table */
+%};
+%typedef struct nis_hash_data NIS_HASH_ITEM;
+%
+%struct nis_hash_table {
+% NIS_HASH_ITEM *keys[64]; /* A hash table of items */
+% NIS_HASH_ITEM *first; /* The first "item" in serial list */
+%};
+%typedef struct nis_hash_table NIS_HASH_TABLE;
+%
+%/* Structure for storing dynamically allocated static data */
+%struct nis_sdata {
+% void *buf; /* Memory allocation pointer */
+% u_long size; /* Buffer size */
+%};
+%
+%/* Generic client creating flags */
+%#define ZMH_VC 1
+%#define ZMH_DG 2
+%#define ZMH_AUTH 4
+%
+%/* Testing Access rights for objects */
+%
+%#define NIS_READ_ACC 1
+%#define NIS_MODIFY_ACC 2
+%#define NIS_CREATE_ACC 4
+%#define NIS_DESTROY_ACC 8
+%/* Test macros. a == access rights, m == desired rights. */
+%#define WORLD(a, m) (((a) & (m)) != 0)
+%#define GROUP(a, m) (((a) & ((m) << 8)) != 0)
+%#define OWNER(a, m) (((a) & ((m) << 16)) != 0)
+%#define NOBODY(a, m) (((a) & ((m) << 24)) != 0)
+%
+%#define OATYPE(d, n) (((d)->do_armask.do_armask_val+n)->oa_otype)
+%#define OARIGHTS(d, n) (((d)->do_armask.do_armask_val+n)->oa_rights)
+%#define WORLD_DEFAULT (NIS_READ_ACC)
+%#define GROUP_DEFAULT (NIS_READ_ACC << 8)
+%#define OWNER_DEFAULT ((NIS_READ_ACC +\
+ NIS_MODIFY_ACC +\
+ NIS_CREATE_ACC +\
+ NIS_DESTROY_ACC) << 16)
+%#define DEFAULT_RIGHTS (WORLD_DEFAULT | GROUP_DEFAULT | OWNER_DEFAULT)
+%
+%/* Result manipulation defines ... */
+%#define NIS_RES_NUMOBJ(x) ((x)->objects.objects_len)
+%#define NIS_RES_OBJECT(x) ((x)->objects.objects_val)
+%#define NIS_RES_COOKIE(x) ((x)->cookie)
+%#define NIS_RES_STATUS(x) ((x)->status)
+%
+%/* These defines make getting at the variant part of the object easier. */
+%#define TA_data zo_data.objdata_u.ta_data
+%#define EN_data zo_data.objdata_u.en_data
+%#define DI_data zo_data.objdata_u.di_data
+%#define LI_data zo_data.objdata_u.li_data
+%#define GR_data zo_data.objdata_u.gr_data
+%
+%#define __type_of(o) ((o)->zo_data.zo_type)
+%
+%/* Declarations for the internal subroutines in nislib.c */
+%enum name_pos {SAME_NAME, HIGHER_NAME, LOWER_NAME, NOT_SEQUENTIAL, BAD_NAME};
+%typedef enum name_pos name_pos;
+%
+%/*
+% * Defines for getting at column data in entry objects. Because RPCGEN
+% * generates some rather wordy structures, we create some defines that
+% * collapse the needed keystrokes to access a particular value using
+% * these definitions they take an nis_object *, and an int and return
+% * a u_char * for Value, and an int for length.
+% */
+%#define ENTRY_VAL(obj, col) \
+ (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val
+%#define ENTRY_LEN(obj, col) \
+ (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len
+%
+%#ifdef __cplusplus
+%}
+%#endif
+%
+%/* Prototypes, and extern declarations for the NIS library functions. */
+%#include <rpcsvc/nislib.h>
+%#endif /* __NIS_RPCGEN_H */
+%/* EDIT_START */
+%
+%/*
+% * nis_3.h
+% *
+% * This file contains definitions that are only of interest to the actual
+% * service daemon and client stubs. Normal users of NIS will not include
+% * this file.
+% *
+% * NOTE : This include file is automatically created by a combination
+% * of rpcgen and sed. DO NOT EDIT IT, change the nis.x file instead
+% * and then remake this file.
+% */
+%#ifndef __nis_3_h
+%#define __nis_3_h
+%#ifdef __cplusplus
+%extern "C" {
+%#endif
+#endif
diff --git a/cpukit/librpc/include/rpcsvc/nis_cache.x b/cpukit/librpc/include/rpcsvc/nis_cache.x
new file mode 100644
index 0000000000..8343cfd050
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/nis_cache.x
@@ -0,0 +1,87 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+/*
+ * nis_cache.x
+ *
+ * Copyright (c) 1988-1992 Sun Microsystems Inc
+ * All Rights Reserved.
+ */
+
+/* From: %#pragma ident "@(#)nis_cache.x 1.11 94/05/03 SMI" */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/nis_cache.x,v 1.3 1999/08/27 23:45:09 peter Exp $";
+%#endif /* not lint */
+#endif
+
+#ifdef RPC_HDR
+%#include <rpc/types.h>
+%#include <rpcsvc/nis.h>
+%
+%/* default cache file */
+%#define CACHEFILE "/var/nis/NIS_SHARED_DIRCACHE"
+%
+%/* clients have to read-lock the cache file, and SVR4 locking requires that */
+%/* the file be writable, but we don't want a world-writable cache file. */
+%/* So... everyone agrees to use a different, world-writable file for the */
+%/* locking operations, but the data is in CACHEFILE. */
+%#define CACHELOCK "/usr/tmp/.NIS_DIR_CACHELOCK"
+%
+%/* the file containing one trusted XDR'ed directory object.
+% * This has to be present for the system to work.
+% */
+%#define COLD_START_FILE "/var/nis/NIS_COLD_START"
+%
+%enum pc_status {HIT, MISS, NEAR_MISS};
+%
+%extern int __nis_debuglevel;
+%
+%
+#endif
+
+#ifdef RPC_CLNT
+#ifdef SOLARIS
+%#include "../gen/nis_clnt.h"
+#else
+%#include "nis.h"
+#endif
+#endif
+
+program CACHEPROG {
+ version CACHE_VER_1 {
+ void NIS_CACHE_ADD_ENTRY(fd_result) = 1;
+ void NIS_CACHE_REMOVE_ENTRY(directory_obj) = 2;
+ void NIS_CACHE_READ_COLDSTART(void) = 3;
+ void NIS_CACHE_REFRESH_ENTRY(string<>) = 4;
+ } = 1;
+} = 100301;
diff --git a/cpukit/librpc/include/rpcsvc/nis_callback.x b/cpukit/librpc/include/rpcsvc/nis_callback.x
new file mode 100644
index 0000000000..4e74aa0a2e
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/nis_callback.x
@@ -0,0 +1,76 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+/*
+ * nis_callback.x
+ *
+ * Copyright (c) 1988-1992 Sun Microsystems Inc
+ * All Rights Reserved.
+ */
+
+/* From: %#pragma ident "@(#)nis_callback.x 1.7 94/05/03 SMI" */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/nis_callback.x,v 1.3 1999/08/27 23:45:09 peter Exp $";
+%#endif /* not lint */
+#endif
+
+/*
+ * "@(#)zns_cback.x 1.2 90/09/10 Copyr 1990 Sun Micro"
+ *
+ * RPCL description of the Callback Service.
+ */
+
+#ifdef RPC_HDR
+%#include <rpcsvc/nis.h>
+#endif
+#ifdef RPC_XDR
+#ifdef SOLARIS
+%#include "nis_clnt.h"
+#else
+%#include "nis.h"
+#endif
+#endif
+
+typedef nis_object *obj_p;
+
+struct cback_data {
+ obj_p entries<>; /* List of objects */
+};
+
+program CB_PROG {
+ version CB_VERS {
+ bool CBPROC_RECEIVE(cback_data) = 1;
+ void CBPROC_FINISH(void) = 2;
+ void CBPROC_ERROR(nis_error) = 3;
+ } = 1;
+} = 100302;
diff --git a/cpukit/librpc/include/rpcsvc/nis_db.h b/cpukit/librpc/include/rpcsvc/nis_db.h
new file mode 100644
index 0000000000..dbdee5aac8
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/nis_db.h
@@ -0,0 +1,162 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * $FreeBSD: src/include/rpcsvc/nis_db.h,v 1.5 1999/08/27 23:45:09 peter Exp $
+ */
+
+/*
+ * Copyright (c) 1991, by Sun Microsystems Inc.
+ */
+
+/*
+ * This header file defines the interface to the NIS database. All
+ * implementations of the database must export at least these routines.
+ * They must also follow the conventions set herein. See the implementors
+ * guide for specific semantics that are required.
+ */
+
+#ifndef _RPCSVC_NIS_DB_H
+#define _RPCSVC_NIS_DB_H
+
+
+/* From: #pragma ident "@(#)nis_db.h 1.8 94/05/03 SMI" */
+
+/*
+ * Note: although the version of <rpcsvc/nis_db.h> shipped with Solaris
+ * 2.5/2.5.x is actually older than this one (according to the ident
+ * string), it contains changes and a few added functions. Those changes
+ * have been hand merged into this file to bring it up to date.
+ */
+
+#include <rpc/rpc.h>
+#include <rpcsvc/nis.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum db_status {
+ DB_SUCCESS = 0,
+ DB_NOTFOUND = 1,
+ DB_NOTUNIQUE = 2,
+ DB_BADTABLE = 3,
+ DB_BADQUERY = 4,
+ DB_BADOBJECT = 5,
+ DB_MEMORY_LIMIT = 6,
+ DB_STORAGE_LIMIT = 7,
+ DB_INTERNAL_ERROR = 8
+};
+typedef enum db_status db_status;
+
+enum db_action {
+ DB_LOOKUP = 0,
+ DB_REMOVE = 1,
+ DB_ADD = 2,
+ DB_FIRST = 3,
+ DB_NEXT = 4,
+ DB_ALL = 5,
+ DB_RESET_NEXT = 6
+};
+typedef enum db_action db_action;
+
+typedef entry_obj *entry_object_p;
+
+typedef struct {
+ u_int db_next_desc_len;
+ char *db_next_desc_val;
+} db_next_desc;
+
+struct db_result {
+ db_status status;
+ db_next_desc nextinfo;
+ struct {
+ u_int objects_len;
+ entry_object_p *objects_val;
+ } objects;
+ long ticks;
+};
+typedef struct db_result db_result;
+
+/*
+ * Prototypes for the database functions.
+ */
+
+#if (__STDC__)
+
+extern bool_t db_initialize(char *);
+#ifdef ORIGINAL_DECLS
+extern bool_t db_create_table(char *, table_obj *);
+extern bool_t db_destroy_table(char *);
+#else
+extern db_status db_create_table(char *, table_obj *);
+extern db_status db_destroy_table(char *);
+#endif
+extern db_result *db_first_entry(char *, int, nis_attr *);
+extern db_result *db_next_entry(char *, db_next_desc *);
+extern db_result *db_reset_next_entry(char *, db_next_desc *);
+extern db_result *db_list_entries(char *, int, nis_attr *);
+extern db_result *db_add_entry(char *, int, nis_attr *, entry_obj *);
+extern db_result *db_remove_entry(char *, int, nis_attr *);
+extern db_status db_checkpoint(char *);
+extern db_status db_standby(char *);
+#ifndef ORIGINAL_DECLS
+extern db_status db_table_exists(char *);
+extern db_status db_unload_table(char *);
+extern void db_free_result(db_result *);
+#endif
+
+#else /* Non-prototype definitions */
+
+extern bool_t db_initialize();
+#ifdef ORIGINAL_DECLS
+extern bool_t db_create_table();
+extern bool_t db_destroy_table();
+#else
+extern db_status db_create_table();
+extern db_status db_destroy_table();
+#endif
+extern db_result *db_first_entry();
+extern db_result *db_next_entry();
+extern db_result *db_reset_next_entry();
+extern db_result *db_list_entries();
+extern db_result *db_add_entry();
+extern db_result *db_remove_entry();
+extern db_status db_checkpoint();
+extern db_status db_standby();
+#ifndef ORIGINAL_DECLS
+extern db_status db_table_exists();
+extern db_status db_unload_table();
+extern void db_free_result();
+#endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RPCSVC_NIS_DB_H */
diff --git a/cpukit/librpc/include/rpcsvc/nis_object.x b/cpukit/librpc/include/rpcsvc/nis_object.x
new file mode 100644
index 0000000000..3156724f1b
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/nis_object.x
@@ -0,0 +1,317 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+/*
+ * nis_object.x
+ *
+ * Copyright (c) 1988-1992 Sun Microsystems Inc
+ * All Rights Reserved.
+ */
+
+/* From: %#pragma ident "@(#)nis_object.x 1.10 94/05/03 SMI" */
+
+#if RPC_HDR
+%
+%#ifndef __nis_object_h
+%#define __nis_object_h
+%
+#endif
+/*
+ * This file defines the format for a NIS object in RPC language.
+ * It is included by the main .x file and the database access protocol
+ * file. It is common because both of them need to deal with the same
+ * type of object. Generating the actual code though is a bit messy because
+ * the nis.x file and the nis_dba.x file will generate xdr routines to
+ * encode/decode objects when only one set is needed. Such is life when
+ * one is using rpcgen.
+ *
+ * Note, the protocol doesn't specify any limits on such things as
+ * maximum name length, number of attributes, etc. These are enforced
+ * by the database backend. When you hit them you will no. Also see
+ * the db_getlimits() function for fetching the limit values.
+ *
+ */
+
+/* Some manifest constants, chosen to maximize flexibility without
+ * plugging the wire full of data.
+ */
+const NIS_MAXSTRINGLEN = 255;
+const NIS_MAXNAMELEN = 1024;
+const NIS_MAXATTRNAME = 32;
+const NIS_MAXATTRVAL = 2048;
+const NIS_MAXCOLUMNS = 64;
+const NIS_MAXATTR = 16;
+const NIS_MAXPATH = 1024;
+const NIS_MAXREPLICAS = 128;
+const NIS_MAXLINKS = 16;
+
+const NIS_PK_NONE = 0; /* no public key (unix/sys auth) */
+const NIS_PK_DH = 1; /* Public key is Diffie-Hellman type */
+const NIS_PK_RSA = 2; /* Public key if RSA type */
+const NIS_PK_KERB = 3; /* Use kerberos style authentication */
+
+/*
+ * The fundamental name type of NIS. The name may consist of two parts,
+ * the first being the fully qualified name, and the second being an
+ * optional set of attribute/value pairs.
+ */
+struct nis_attr {
+ string zattr_ndx<>; /* name of the index */
+ opaque zattr_val<>; /* Value for the attribute. */
+};
+
+typedef string nis_name<>; /* The NIS name itself. */
+
+/* NIS object types are defined by the following enumeration. The numbers
+ * they use are based on the following scheme :
+ * 0 - 1023 are reserved for Sun,
+ * 1024 - 2047 are defined to be private to a particular tree.
+ * 2048 - 4095 are defined to be user defined.
+ * 4096 - ... are reserved for future use.
+ */
+
+enum zotypes {
+ BOGUS_OBJ = 0, /* Uninitialized object structure */
+ NO_OBJ = 1, /* NULL object (no data) */
+ DIRECTORY_OBJ = 2, /* Directory object describing domain */
+ GROUP_OBJ = 3, /* Group object (a list of names) */
+ TABLE_OBJ = 4, /* Table object (a database schema) */
+ ENTRY_OBJ = 5, /* Entry object (a database record) */
+ LINK_OBJ = 6, /* A name link. */
+ PRIVATE_OBJ = 7 /* Private object (all opaque data) */
+};
+
+/*
+ * The types of Name services NIS knows about. They are enumerated
+ * here. The Binder code will use this type to determine if it has
+ * a set of library routines that will access the indicated name service.
+ */
+enum nstype {
+ UNKNOWN = 0,
+ NIS = 1, /* Nis Plus Service */
+ SUNYP = 2, /* Old NIS Service */
+ IVY = 3, /* Nis Plus Plus Service */
+ DNS = 4, /* Domain Name Service */
+ X500 = 5, /* ISO/CCCIT X.500 Service */
+ DNANS = 6, /* Digital DECNet Name Service */
+ XCHS = 7, /* Xerox ClearingHouse Service */
+ CDS= 8
+};
+
+/*
+ * DIRECTORY - The name service object. These objects identify other name
+ * servers that are serving some portion of the name space. Each has a
+ * type associated with it. The resolver library will note whether or not
+ * is has the needed routines to access that type of service.
+ * The oarmask structure defines an access rights mask on a per object
+ * type basis for the name spaces. The only bits currently used are
+ * create and destroy. By enabling or disabling these access rights for
+ * a specific object type for a one of the accessor entities (owner,
+ * group, world) the administrator can control what types of objects
+ * may be freely added to the name space and which require the
+ * administrator's approval.
+ */
+struct oar_mask {
+ u_long oa_rights; /* Access rights mask */
+ zotypes oa_otype; /* Object type */
+};
+
+struct endpoint {
+ string uaddr<>;
+ string family<>; /* Transport family (INET, OSI, etc) */
+ string proto<>; /* Protocol (TCP, UDP, CLNP, etc) */
+};
+
+/*
+ * Note: pkey is a netobj which is limited to 1024 bytes which limits the
+ * keysize to 8192 bits. This is consider to be a reasonable limit for
+ * the expected lifetime of this service.
+ */
+struct nis_server {
+ nis_name name; /* Principal name of the server */
+ endpoint ep<>; /* Universal addr(s) for server */
+ u_long key_type; /* Public key type */
+ netobj pkey; /* server's public key */
+};
+
+struct directory_obj {
+ nis_name do_name; /* Name of the directory being served */
+ nstype do_type; /* one of NIS, DNS, IVY, YP, or X.500 */
+ nis_server do_servers<>; /* <0> == Primary name server */
+ u_long do_ttl; /* Time To Live (for caches) */
+ oar_mask do_armask<>; /* Create/Destroy rights by object type */
+};
+
+/*
+ * ENTRY - This is one row of data from an information base.
+ * The type value is used by the client library to convert the entry to
+ * it's internal structure representation. The Table name is a back pointer
+ * to the table where the entry is stored. This allows the client library
+ * to determine where to send a request if the client wishes to change this
+ * entry but got to it through a LINK rather than directly.
+ * If the entry is a "standalone" entry then this field is void.
+ */
+const EN_BINARY = 1; /* Indicates value is binary data */
+const EN_CRYPT = 2; /* Indicates the value is encrypted */
+const EN_XDR = 4; /* Indicates the value is XDR encoded */
+const EN_MODIFIED = 8; /* Indicates entry is modified. */
+const EN_ASN1 = 64; /* Means contents use ASN.1 encoding */
+
+struct entry_col {
+ u_long ec_flags; /* Flags for this value */
+ opaque ec_value<>; /* It's textual value */
+};
+
+struct entry_obj {
+ string en_type<>; /* Type of entry such as "passwd" */
+ entry_col en_cols<>; /* Value for the entry */
+};
+
+/*
+ * GROUP - The group object contains a list of NIS principal names. Groups
+ * are used to authorize principals. Each object has a set of access rights
+ * for members of its group. Principal names in groups are in the form
+ * name.directory and recursive groups are expressed as @groupname.directory
+ */
+struct group_obj {
+ u_long gr_flags; /* Flags controlling group */
+ nis_name gr_members<>; /* List of names in group */
+};
+
+/*
+ * LINK - This is the LINK object. It is quite similar to a symbolic link
+ * in the UNIX filesystem. The attributes in the main object structure are
+ * relative to the LINK data and not what it points to (like the file system)
+ * "modify" privleges here indicate the right to modify what the link points
+ * at and not to modify that actual object pointed to by the link.
+ */
+struct link_obj {
+ zotypes li_rtype; /* Real type of the object */
+ nis_attr li_attrs<>; /* Attribute/Values for tables */
+ nis_name li_name; /* The object's real NIS name */
+};
+
+/*
+ * TABLE - This is the table object. It implements a simple
+ * data base that applications and use for configuration or
+ * administration purposes. The role of the table is to group together
+ * a set of related entries. Tables are the simple database component
+ * of NIS. Like many databases, tables are logically divided into columns
+ * and rows. The columns are labeled with indexes and each ENTRY makes
+ * up a row. Rows may be addressed within the table by selecting one
+ * or more indexes, and values for those indexes. Each row which has
+ * a value for the given index that matches the desired value is returned.
+ * Within the definition of each column there is a flags variable, this
+ * variable contains flags which determine whether or not the column is
+ * searchable, contains binary data, and access rights for the entry objects
+ * column value.
+ */
+
+const TA_BINARY = 1; /* Means table data is binary */
+const TA_CRYPT = 2; /* Means value should be encrypted */
+const TA_XDR = 4; /* Means value is XDR encoded */
+const TA_SEARCHABLE = 8; /* Means this column is searchable */
+const TA_CASE = 16; /* Means this column is Case Sensitive */
+const TA_MODIFIED = 32; /* Means this columns attrs are modified*/
+const TA_ASN1 = 64; /* Means contents use ASN.1 encoding */
+
+struct table_col {
+ string tc_name<64>; /* Column Name */
+ u_long tc_flags; /* control flags */
+ u_long tc_rights; /* Access rights mask */
+};
+
+struct table_obj {
+ string ta_type<64>; /* Table type such as "passwd" */
+ int ta_maxcol; /* Total number of columns */
+ u_char ta_sep; /* Separator character */
+ table_col ta_cols<>; /* The number of table indexes */
+ string ta_path<>; /* A search path for this table */
+};
+
+/*
+ * This union joins together all of the currently known objects.
+ */
+union objdata switch (zotypes zo_type) {
+ case DIRECTORY_OBJ :
+ struct directory_obj di_data;
+ case GROUP_OBJ :
+ struct group_obj gr_data;
+ case TABLE_OBJ :
+ struct table_obj ta_data;
+ case ENTRY_OBJ:
+ struct entry_obj en_data;
+ case LINK_OBJ :
+ struct link_obj li_data;
+ case PRIVATE_OBJ :
+ opaque po_data<>;
+ case NO_OBJ :
+ void;
+ case BOGUS_OBJ :
+ void;
+ default :
+ void;
+};
+
+/*
+ * This is the basic NIS object data type. It consists of a generic part
+ * which all objects contain, and a specialized part which varies depending
+ * on the type of the object. All of the specialized sections have been
+ * described above. You might have wondered why they all start with an
+ * integer size, followed by the useful data. The answer is, when the
+ * server doesn't recognize the type returned it treats it as opaque data.
+ * And the definition for opaque data is {int size; char *data;}. In this
+ * way, servers and utility routines that do not understand a given type
+ * may still pass it around. One has to be careful in setting
+ * this variable accurately, it must take into account such things as
+ * XDR padding of structures etc. The best way to set it is to note one's
+ * position in the XDR encoding stream, encode the structure, look at the
+ * new position and calculate the size.
+ */
+struct nis_oid {
+ u_long ctime; /* Time of objects creation */
+ u_long mtime; /* Time of objects modification */
+};
+
+struct nis_object {
+ nis_oid zo_oid; /* object identity verifier. */
+ nis_name zo_name; /* The NIS name for this object */
+ nis_name zo_owner; /* NIS name of object owner. */
+ nis_name zo_group; /* NIS name of access group. */
+ nis_name zo_domain; /* The administrator for the object */
+ u_long zo_access; /* Access rights (owner, group, world) */
+ u_long zo_ttl; /* Object's time to live in seconds. */
+ objdata zo_data; /* Data structure for this type */
+};
+#if RPC_HDR
+%
+%#endif /* if __nis_object_h */
+%
+#endif
diff --git a/cpukit/librpc/include/rpcsvc/nis_tags.h b/cpukit/librpc/include/rpcsvc/nis_tags.h
new file mode 100644
index 0000000000..0eaee6d442
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/nis_tags.h
@@ -0,0 +1,137 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Copyright (c) 1991, Sun Microsystems Inc.
+ */
+
+/*
+ * nis_tags.h
+ *
+ * This file contains the tags and statistics definitions. It is
+ * automatically included by nis.h
+ */
+
+#ifndef _RPCSVC_NIS_TAGS_H
+#define _RPCSVC_NIS_TAGS_H
+
+/* From: #pragma ident "@(#)nis_tags.h 1.10 94/05/03 SMI" */
+/* from file: zns_tags.h 1.7 Copyright (c) 1990 Sun Microsystems */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ORIGINAL_DECLS
+#define NIS_DIR "data"
+#endif
+
+/* Lookup and List function flags */
+#define FOLLOW_LINKS (1<<0) /* Follow link objects */
+#define FOLLOW_PATH (1<<1) /* Follow the path in a table */
+#define HARD_LOOKUP (1<<2) /* Block until successful */
+#define ALL_RESULTS (1<<3) /* Retrieve all results */
+#define NO_CACHE (1<<4) /* Do not return 'cached' results */
+#define MASTER_ONLY (1<<5) /* Get value only from master server */
+#define EXPAND_NAME (1<<6) /* Expand partitially qualified names */
+
+/* Semantic modification for table operations flags */
+#define RETURN_RESULT (1<<7) /* Return resulting object to client */
+#define ADD_OVERWRITE (1<<8) /* Allow overwrites on ADD */
+#define REM_MULTIPLE (1<<9) /* Allow wildcard deletes */
+#define MOD_SAMEOBJ (1<<10) /* Check modified object before write */
+#define ADD_RESERVED (1<<11) /* Spare ADD semantic */
+#define REM_RESERVED (1<<12) /* Spare REM semantic */
+#ifdef ORIGINAL_DECLS
+#define MOD_RESERVED (1<<13) /* Spare MOD semantic */
+#else
+#define MOD_EXCLUSIVE (1<<13) /* Modify no overwrite on modified keys */
+#endif
+
+/* Transport specific modifications to the operation */
+#define USE_DGRAM (1<<16) /* Use a datagram transport */
+#define NO_AUTHINFO (1<<17) /* Don't bother attaching auth info */
+
+/*
+ * Declarations for "standard" NIS+ tags
+ * State variable tags have values 0 - 2047
+ * Statistic tags have values 2048 - 65535
+ * User Tags have values >2^16
+ */
+#define TAG_DEBUG 1 /* set debug level */
+#define TAG_STATS 2 /* Enable/disable statistics */
+#define TAG_GCACHE 3 /* Flush the Group Cache */
+#ifndef ORIGINAL_DECLS
+#define TAG_GCACHE_ALL TAG_GCACHE
+#endif
+#define TAG_DCACHE 4 /* Flush the directory cache */
+#ifndef ORIGINAL_DECLS
+#define TAG_DCACHE_ONE TAG_DCACHE
+#endif
+#define TAG_OCACHE 5 /* Flush the Object Cache */
+#define TAG_SECURE 6 /* Set the security level */
+#ifndef ORIGINAL_DECLS
+#define TAG_TCACHE_ONE 7 /* Flush the table cache */
+#define TAG_DCACHE_ALL 8 /* Flush entire directory cache */
+#define TAG_TCACHE_ALL 9 /* Flush entire table cache */
+#define TAG_GCACHE_ONE 10 /* Flush one group object */
+#define TAG_DCACHE_ONE_REFRESH 11 /* Flush and refresh one DO */
+#endif
+
+#define TAG_OPSTATS 2048 /* NIS+ operations statistics */
+#define TAG_THREADS 2049 /* Child process/thread status */
+#define TAG_HEAP 2050 /* Heap usage statistics */
+#define TAG_UPDATES 2051 /* Updates to this service */
+#define TAG_VISIBLE 2052 /* First update that isn't replicated */
+#define TAG_S_DCACHE 2053 /* Directory cache statistics */
+#define TAG_S_OCACHE 2054 /* Object cache statistics */
+#define TAG_S_GCACHE 2055 /* Group cache statistics */
+#define TAG_S_STORAGE 2056 /* Group cache statistics */
+#define TAG_UPTIME 2057 /* Time that server has been up */
+#ifndef ORIGINAL_DECLS
+#define TAG_DIRLIST 2058 /* Dir served by this server */
+#define TAG_NISCOMPAT 2059 /* Whether supports NIS compat mode */
+#define TAG_DNSFORWARDING 2060 /* Whether DNS forwarding supported*/
+#define TAG_SECURITY_LEVEL 2061 /* Security level of the server */
+#define TAG_ROOTSERVER 2062 /* Whether root server */
+#endif
+
+/*
+ * Declarations for the Group object flags. Currently
+ * there are only 3.
+ */
+#define IMPMEM_GROUPS 1 /* Implicit Membership allowed */
+#define RECURS_GROUPS 2 /* Recursive Groups allowed */
+#define NEGMEM_GROUPS 4 /* Negative Groups allowed */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RPCSVC_NIS_TAGS_H */
diff --git a/cpukit/librpc/include/rpcsvc/nislib.h b/cpukit/librpc/include/rpcsvc/nislib.h
new file mode 100644
index 0000000000..9f874d270e
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/nislib.h
@@ -0,0 +1,317 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Copyright (c) 1991, Sun Microsystems Inc.
+ */
+
+/*
+ * This file contains the interfaces that are visible in the SunOS 5.x
+ * implementation of NIS Plus. When using C++ the defined __cplusplus and
+ * __STDC__ should both be true.
+ */
+
+#ifndef _RPCSVC_NISLIB_H
+#define _RPCSVC_NISLIB_H
+
+/* From: #pragma ident "@(#)nislib.h 1.16 94/05/03 SMI" */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct signature {
+ int signature_len;
+ char *signature_val;
+};
+
+#ifdef __STDC__
+extern void nis_freeresult(nis_result *);
+extern nis_result * nis_lookup(nis_name, u_long);
+extern nis_result * nis_list(nis_name, u_long,
+ int (*)(nis_name, nis_object *, void *), void *);
+extern nis_result * nis_add(nis_name, nis_object *);
+extern nis_result * nis_remove(nis_name, nis_object *);
+extern nis_result * nis_modify(nis_name, nis_object *);
+
+extern nis_result * nis_add_entry(nis_name, nis_object *, u_long);
+extern nis_result * nis_remove_entry(nis_name, nis_object *, u_long);
+extern nis_result * nis_modify_entry(nis_name, nis_object *, u_long);
+extern nis_result * nis_first_entry(nis_name);
+extern nis_result * nis_next_entry(nis_name, netobj *);
+
+extern nis_error nis_mkdir(nis_name, nis_server *);
+extern nis_error nis_rmdir(nis_name, nis_server *);
+extern name_pos nis_dir_cmp(nis_name, nis_name);
+
+extern nis_name * nis_getnames(nis_name);
+extern void nis_freenames(nis_name *);
+extern nis_name nis_domain_of(nis_name);
+extern nis_name nis_leaf_of(nis_name);
+extern nis_name nis_leaf_of_r(const nis_name, char *, size_t);
+extern nis_name nis_name_of(nis_name);
+extern nis_name nis_local_group(void);
+extern nis_name nis_local_directory(void);
+extern nis_name nis_local_principal(void);
+extern nis_name nis_local_host(void);
+
+extern void nis_destroy_object(nis_object *);
+extern nis_object * nis_clone_object(nis_object *, nis_object *);
+extern void nis_print_object(nis_object *);
+
+extern char * nis_sperrno(nis_error);
+extern void nis_perror(nis_error, char *);
+extern char * nis_sperror(nis_error, char *);
+extern void nis_lerror(nis_error, char *);
+
+extern void nis_print_group_entry(nis_name);
+extern bool_t nis_ismember(nis_name, nis_name);
+extern nis_error nis_creategroup(nis_name, u_long);
+extern nis_error nis_destroygroup(nis_name);
+extern nis_error nis_addmember(nis_name, nis_name);
+extern nis_error nis_removemember(nis_name, nis_name);
+extern nis_error nis_verifygroup(nis_name);
+
+extern void nis_freeservlist(nis_server **);
+extern nis_server ** nis_getservlist(nis_name);
+extern nis_error nis_stats(nis_server *, nis_tag *, int, nis_tag **);
+extern nis_error nis_servstate(nis_server *, nis_tag *, int, nis_tag **);
+extern void nis_freetags(nis_tag *, int);
+
+extern nis_result * nis_checkpoint(nis_name);
+extern void nis_ping(nis_name, u_long, nis_object *);
+
+/*
+ * XXX: PLEASE NOTE THAT THE FOLLOWING FUNCTIONS ARE INTERNAL
+ * TO NIS+ AND SHOULD NOT BE USED BY ANY APPLICATION PROGRAM.
+ * THEIR SEMANTICS AND/OR SIGNATURE CAN CHANGE WITHOUT NOTICE.
+ * SO, PLEASE DO NOT USE THEM. YOU ARE WARNED!!!!
+ */
+
+extern char ** __break_name(nis_name, int *);
+extern int __name_distance(char **, char **);
+extern nis_result * nis_make_error(nis_error, u_long, u_long, u_long, u_long);
+extern nis_attr * __cvt2attr(int *, char **);
+extern void nis_free_request(ib_request *);
+extern nis_error nis_get_request(nis_name, nis_object *, netobj*, ib_request*);
+extern nis_object * nis_read_obj(char *);
+extern int nis_write_obj(char *, nis_object *);
+extern int nis_in_table(nis_name, NIS_HASH_TABLE *, int *);
+extern int nis_insert_item(NIS_HASH_ITEM *, NIS_HASH_TABLE *);
+extern NIS_HASH_ITEM * nis_find_item(nis_name, NIS_HASH_TABLE *);
+extern NIS_HASH_ITEM * nis_remove_item(nis_name, NIS_HASH_TABLE *);
+extern void nis_insert_name(nis_name, NIS_HASH_TABLE *);
+extern void nis_remove_name(nis_name, NIS_HASH_TABLE *);
+extern CLIENT * nis_make_rpchandle(nis_server *, int, u_long, u_long, u_long,
+ int, int);
+extern void * nis_get_static_storage(struct nis_sdata *, u_long, u_long);
+extern char * nis_data(char *);
+extern void nis_print_rights(u_long);
+extern void nis_print_directory(directory_obj *);
+extern void nis_print_group(group_obj *);
+extern void nis_print_table(table_obj *);
+extern void nis_print_link(link_obj *);
+extern void nis_print_entry(entry_obj *);
+extern nis_object * nis_get_object(char *, char *, char *, u_long, u_long,
+ zotypes);
+extern nis_server * __nis_init_callback(CLIENT *,
+ int (*)(nis_name, nis_object *, void *), void *);
+extern int nis_getdtblsize(void);
+extern int __nis_run_callback(netobj *, u_long, struct timeval *, CLIENT *);
+
+extern log_result *nis_dumplog(nis_server *, nis_name, u_long);
+extern log_result *nis_dump(nis_server *, nis_name,
+ int (*)(nis_name, nis_object *, void *));
+
+extern bool_t __do_ismember(nis_name, nis_name,
+ nis_result *(*)(nis_name, u_long));
+extern nis_name __nis_map_group(nis_name);
+extern nis_name __nis_map_group_r(nis_name, char*, size_t);
+
+extern nis_error __nis_CacheBind(char *, directory_obj *);
+extern nis_error __nis_CacheSearch(char *, directory_obj *);
+extern bool_t __nis_CacheRemoveEntry(directory_obj *);
+extern void __nis_CacheRestart(void);
+extern void __nis_CachePrint(void);
+extern void __nis_CacheDumpStatistics(void);
+extern bool_t writeColdStartFile(directory_obj *);
+
+extern CLIENT * __get_ti_clnt(char *, CLIENT *, char **, pid_t *);
+extern int __strcmp_case_insens(char *, char *);
+extern int __strncmp_case_insens(char *, char *);
+
+extern fd_result * nis_finddirectory(directory_obj *, nis_name);
+extern int __start_clock(int);
+extern u_long __stop_clock(int);
+
+/*
+ * This particular function is part of the FreeBSD NIS+ implementation
+ * only. Ideally it should be somewhere else, but it is used by both
+ * rpc.nisd and nis_cachemgr, and there aren't that many headers common
+ * to both programs.
+ */
+
+extern struct signature *__nis_calculate_encrypted_cksum(unsigned char *, unsigned int, char *, int);
+
+#else
+
+/* Non-prototype definitions (old fashioned C) */
+
+extern void nis_freeresult();
+extern nis_result * nis_lookup();
+extern nis_result * nis_list();
+extern nis_result * nis_add();
+extern nis_result * nis_remove();
+extern nis_result * nis_modify();
+
+extern nis_result * nis_add_entry();
+extern nis_result * nis_remove_entry();
+extern nis_result * nis_modify_entry();
+extern nis_result * nis_first_entry();
+extern nis_result * nis_next_entry();
+
+extern nis_error nis_mkdir();
+extern nis_error nis_rmdir();
+extern name_pos nis_dir_cmp();
+
+extern nis_name *nis_getnames();
+extern void nis_freenames();
+extern nis_name nis_domain_of();
+extern nis_name nis_leaf_of();
+extern nis_name nis_leaf_of_r();
+extern nis_name nis_name_of();
+extern nis_name nis_local_group();
+extern nis_name nis_local_directory();
+extern nis_name nis_local_principal();
+extern nis_name nis_local_host();
+
+extern void nis_destroy_object();
+extern nis_object * nis_clone_object();
+extern void nis_print_object();
+
+extern char * nis_sperrno();
+extern void nis_perror();
+extern char * nis_sperror();
+extern void nis_lerror();
+
+extern void nis_print_group_entry();
+extern bool_t nis_ismember();
+extern nis_error nis_creategroup();
+extern nis_error nis_destroygroup();
+extern nis_error nis_addmember();
+extern nis_error nis_removemember();
+extern nis_error nis_verifygroup();
+
+extern void nis_freeservlist();
+extern nis_server ** nis_getservlist();
+extern nis_error nis_stats();
+extern nis_error nis_servstate();
+extern void nis_freetags();
+
+extern nis_result * nis_checkpoint();
+extern void nis_ping();
+
+/*
+ * XXX: PLEASE NOTE THAT THE FOLLOWING FUNCTIONS ARE INTERNAL
+ * TO NIS+ AND SHOULD NOT BE USED BY ANY APPLICATION PROGRAM.
+ * THEIR SEMANTICS AND/OR SIGNATURE CAN CHANGE WITHOUT NOTICE.
+ * SO, PLEASE DO NOT USE THEM. YOU ARE WARNED!!!!
+ */
+extern char ** __break_name();
+extern int __name_distance();
+extern nis_result * nis_make_error();
+extern nis_attr * __cvt2attr();
+extern void nis_free_request();
+extern nis_error nis_get_request();
+extern nis_object * nis_read_obj();
+extern int nis_write_obj();
+extern int nis_in_table();
+extern int nis_insert_item();
+extern NIS_HASH_ITEM * nis_find_item();
+extern NIS_HASH_ITEM * nis_remove_item();
+extern void nis_insert_name();
+extern void nis_remove_name();
+extern CLIENT * nis_make_rpchandle();
+extern void * nis_get_static_storage();
+extern char * nis_data();
+
+extern void nis_print_rights();
+extern void nis_print_directory();
+extern void nis_print_group();
+extern void nis_print_table();
+extern void nis_print_link();
+extern void nis_print_entry();
+extern nis_object * nis_get_object();
+
+extern nis_server * __nis_init_callback();
+extern int nis_getdtblsize();
+extern int __nis_run_callback();
+
+extern log_result * nis_dump();
+extern log_result * nis_dumplog();
+
+extern bool_t __do_ismember();
+extern nis_name __nis_map_group();
+extern nis_name __nis_map_group_r();
+
+
+extern nis_error __nis_CacheBind();
+extern directory_obj * __nis_CacheSearch();
+extern bool_t __nis_CacheRemoveEntry();
+extern void __nis_CacheRestart();
+extern void __nis_CachePrint();
+extern void __nis_CacheDumpStatistics();
+extern bool_t writeColdStartFile();
+
+extern CLIENT * __get_ti_clnt();
+extern int __strcmp_case_insens();
+extern int __strncmp_case_insens();
+
+extern fd_result * nis_finddirectory();
+extern int __start_clock();
+extern u_long __stop_clock();
+
+/*
+ * This particular function is part of the FreeBSD NIS+ implementation
+ * only. Ideally it should be somewhere else, but it is used by both
+ * rpc.nisd and nis_cachemgr, and there aren't that many headers common
+ * to both programs.
+ */
+
+extern struct signature *__nis_calculate_encrypted_cksum();
+
+#endif
+
+#define NUL '\0'
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RPCSVC_NISLIB_H */
diff --git a/cpukit/librpc/include/rpcsvc/nlm_prot.x b/cpukit/librpc/include/rpcsvc/nlm_prot.x
new file mode 100644
index 0000000000..fdc6d6ea96
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/nlm_prot.x
@@ -0,0 +1,183 @@
+/* @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC */
+/* @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro */
+
+/*
+ * Network lock manager protocol definition
+ * Copyright (C) 1986 Sun Microsystems, Inc.
+ *
+ * protocol used between local lock manager and remote lock manager
+ */
+
+#ifdef RPC_HDR
+%#define LM_MAXSTRLEN 1024
+%#define MAXNAMELEN LM_MAXSTRLEN+1
+#else
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/nlm_prot.x,v 1.8 1999/08/27 23:45:10 peter Exp $";
+%#endif /* not lint */
+#endif
+
+/*
+ * status of a call to the lock manager
+ */
+enum nlm_stats {
+ nlm_granted = 0,
+ nlm_denied = 1,
+ nlm_denied_nolocks = 2,
+ nlm_blocked = 3,
+ nlm_denied_grace_period = 4
+};
+
+struct nlm_holder {
+ bool exclusive;
+ int svid;
+ netobj oh;
+ unsigned l_offset;
+ unsigned l_len;
+};
+
+union nlm_testrply switch (nlm_stats stat) {
+ case nlm_denied:
+ struct nlm_holder holder;
+ default:
+ void;
+};
+
+struct nlm_stat {
+ nlm_stats stat;
+};
+
+struct nlm_res {
+ netobj cookie;
+ nlm_stat stat;
+};
+
+struct nlm_testres {
+ netobj cookie;
+ nlm_testrply stat;
+};
+
+struct nlm_lock {
+ string caller_name<LM_MAXSTRLEN>;
+ netobj fh; /* identify a file */
+ netobj oh; /* identify owner of a lock */
+ int svid; /* generated from pid for svid */
+ unsigned l_offset;
+ unsigned l_len;
+};
+
+struct nlm_lockargs {
+ netobj cookie;
+ bool block;
+ bool exclusive;
+ struct nlm_lock alock;
+ bool reclaim; /* used for recovering locks */
+ int state; /* specify local status monitor state */
+};
+
+struct nlm_cancargs {
+ netobj cookie;
+ bool block;
+ bool exclusive;
+ struct nlm_lock alock;
+};
+
+struct nlm_testargs {
+ netobj cookie;
+ bool exclusive;
+ struct nlm_lock alock;
+};
+
+struct nlm_unlockargs {
+ netobj cookie;
+ struct nlm_lock alock;
+};
+
+
+#ifdef RPC_HDR
+%/*
+% * The following enums are actually bit encoded for efficient
+% * boolean algebra.... DON'T change them.....
+% */
+#endif
+enum fsh_mode {
+ fsm_DN = 0, /* deny none */
+ fsm_DR = 1, /* deny read */
+ fsm_DW = 2, /* deny write */
+ fsm_DRW = 3 /* deny read/write */
+};
+
+enum fsh_access {
+ fsa_NONE = 0, /* for completeness */
+ fsa_R = 1, /* read only */
+ fsa_W = 2, /* write only */
+ fsa_RW = 3 /* read/write */
+};
+
+struct nlm_share {
+ string caller_name<LM_MAXSTRLEN>;
+ netobj fh;
+ netobj oh;
+ fsh_mode mode;
+ fsh_access access;
+};
+
+struct nlm_shareargs {
+ netobj cookie;
+ nlm_share share;
+ bool reclaim;
+};
+
+struct nlm_shareres {
+ netobj cookie;
+ nlm_stats stat;
+ int sequence;
+};
+
+struct nlm_notify {
+ string name<MAXNAMELEN>;
+ long state;
+};
+
+/*
+ * Over-the-wire protocol used between the network lock managers
+ */
+
+program NLM_PROG {
+ version NLM_VERS {
+
+ nlm_testres NLM_TEST(struct nlm_testargs) = 1;
+
+ nlm_res NLM_LOCK(struct nlm_lockargs) = 2;
+
+ nlm_res NLM_CANCEL(struct nlm_cancargs) = 3;
+ nlm_res NLM_UNLOCK(struct nlm_unlockargs) = 4;
+
+ /*
+ * remote lock manager call-back to grant lock
+ */
+ nlm_res NLM_GRANTED(struct nlm_testargs)= 5;
+ /*
+ * message passing style of requesting lock
+ */
+ void NLM_TEST_MSG(struct nlm_testargs) = 6;
+ void NLM_LOCK_MSG(struct nlm_lockargs) = 7;
+ void NLM_CANCEL_MSG(struct nlm_cancargs) =8;
+ void NLM_UNLOCK_MSG(struct nlm_unlockargs) = 9;
+ void NLM_GRANTED_MSG(struct nlm_testargs) = 10;
+ void NLM_TEST_RES(nlm_testres) = 11;
+ void NLM_LOCK_RES(nlm_res) = 12;
+ void NLM_CANCEL_RES(nlm_res) = 13;
+ void NLM_UNLOCK_RES(nlm_res) = 14;
+ void NLM_GRANTED_RES(nlm_res) = 15;
+ } = 1;
+
+ version NLM_VERSX {
+ nlm_shareres NLM_SHARE(nlm_shareargs) = 20;
+ nlm_shareres NLM_UNSHARE(nlm_shareargs) = 21;
+ nlm_res NLM_NM_LOCK(nlm_lockargs) = 22;
+ void NLM_FREE_ALL(nlm_notify) = 23;
+ } = 3;
+
+} = 100021;
diff --git a/cpukit/librpc/include/rpcsvc/pmap_prot.x b/cpukit/librpc/include/rpcsvc/pmap_prot.x
new file mode 100644
index 0000000000..2e9c089484
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/pmap_prot.x
@@ -0,0 +1,284 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+%/*
+% * Copyright (c) 1984,1989 by Sun Microsystems, Inc.
+% */
+
+%/* from pmap_prot.x */
+
+#ifdef RPC_HDR
+%
+%#pragma ident "@(#)pmap_prot.x 1.6 94/04/29 SMI"
+%
+%#ifndef _KERNEL
+%
+#endif
+
+/*
+ * Port Mapper Protocol Specification (in RPC Language)
+ * derived from RFC 1057
+ */
+
+%/*
+% * Protocol for the local binder service, or pmap.
+% *
+% * Copyright (C) 1984, Sun Microsystems, Inc.
+% *
+% * The following procedures are supported by the protocol:
+% *
+% * PMAPPROC_NULL() returns ()
+% * takes nothing, returns nothing
+% *
+% * PMAPPROC_SET(struct pmap) returns (bool_t)
+% * TRUE is success, FALSE is failure. Registers the tuple
+% * [prog, vers, prot, port].
+% *
+% * PMAPPROC_UNSET(struct pmap) returns (bool_t)
+% * TRUE is success, FALSE is failure. Un-registers pair
+% * [prog, vers]. prot and port are ignored.
+% *
+% * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
+% * 0 is failure. Otherwise returns the port number where the pair
+% * [prog, vers] is registered. It may lie!
+% *
+% * PMAPPROC_DUMP() RETURNS (struct pmaplist_ptr)
+% *
+% * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
+% * RETURNS (port, string<>);
+% * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc,
+% * encapsulatedargs);
+% * Calls the procedure on the local machine. If it is not registered,
+% * this procedure is quite; ie it does not return error information!!!
+% * This procedure only is supported on rpc/udp and calls via
+% * rpc/udp. This routine only passes null authentication parameters.
+% * This file has no interface to xdr routines for PMAPPROC_CALLIT.
+% *
+% * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
+% */
+%
+const PMAPPORT = 111; /* portmapper port number */
+%
+%
+%/*
+% * A mapping of (program, version, protocol) to port number
+% */
+
+struct pmap {
+ unsigned long pm_prog;
+ unsigned long pm_vers;
+ unsigned long pm_prot;
+ unsigned long pm_port;
+};
+#ifdef RPC_HDR
+%
+%typedef pmap PMAP;
+%
+#endif
+%
+%/*
+% * Supported values for the "prot" field
+% */
+%
+const PMAP_IPPROTO_TCP = 6; /* protocol number for TCP/IP */
+const PMAP_IPPROTO_UDP = 17; /* protocol number for UDP/IP */
+%
+%
+%/*
+% * A list of mappings
+% *
+% * Below are two definitions for the pmaplist structure. This is done because
+% * xdr_pmaplist() is specified to take a struct pmaplist **, rather than a
+% * struct pmaplist * that rpcgen would produce. One version of the pmaplist
+% * structure (actually called pm__list) is used with rpcgen, and the other is
+% * defined only in the header file for compatibility with the specified
+% * interface.
+% */
+
+struct pm__list {
+ pmap pml_map;
+ struct pm__list *pml_next;
+};
+
+typedef pm__list *pmaplist_ptr; /* results of PMAPPROC_DUMP */
+
+#ifdef RPC_HDR
+%
+%typedef struct pm__list pmaplist;
+%typedef struct pm__list PMAPLIST;
+%
+%#ifndef __cplusplus
+%struct pmaplist {
+% PMAP pml_map;
+% struct pmaplist *pml_next;
+%};
+%#endif
+%
+%#ifdef __cplusplus
+%extern "C" {
+%#endif
+%#ifdef __STDC__
+%extern bool_t xdr_pmaplist(XDR *, pmaplist**);
+%#else /* K&R C */
+%bool_t xdr_pmaplist();
+%#endif
+%#ifdef __cplusplus
+%}
+%#endif
+%
+#endif
+
+%
+%/*
+% * Arguments to callit
+% */
+
+struct rmtcallargs {
+ unsigned long prog;
+ unsigned long vers;
+ unsigned long proc;
+ opaque args<>;
+};
+#ifdef RPC_HDR
+%
+%/*
+% * Client-side only representation of rmtcallargs structure.
+% *
+% * The routine that XDRs the rmtcallargs structure must deal with the
+% * opaque arguments in the "args" structure. xdr_rmtcall_args() needs to be
+% * passed the XDR routine that knows the args' structure. This routine
+% * doesn't need to go over-the-wire (and it wouldn't make sense anyway) since
+% * the application being called knows the args structure already. So we use a
+% * different "XDR" structure on the client side, p_rmtcallargs, which includes
+% * the args' XDR routine.
+% */
+%struct p_rmtcallargs {
+% u_long prog;
+% u_long vers;
+% u_long proc;
+% struct {
+% u_int args_len;
+% char *args_val;
+% } args;
+% xdrproc_t xdr_args; /* encodes args */
+%};
+%
+#endif /* def RPC_HDR */
+%
+%
+%/*
+% * Results of callit
+% */
+
+struct rmtcallres {
+ unsigned long port;
+ opaque res<>;
+};
+#ifdef RPC_HDR
+%
+%/*
+% * Client-side only representation of rmtcallres structure.
+% */
+%struct p_rmtcallres {
+% u_long port;
+% struct {
+% u_int res_len;
+% char *res_val;
+% } res;
+% xdrproc_t xdr_res; /* decodes res */
+%};
+%
+#endif /* def RPC_HDR */
+
+/*
+ * Port mapper procedures
+ */
+
+program PMAPPROG {
+ version PMAPVERS {
+ void
+ PMAPPROC_NULL(void) = 0;
+
+ bool
+ PMAPPROC_SET(pmap) = 1;
+
+ bool
+ PMAPPROC_UNSET(pmap) = 2;
+
+ unsigned long
+ PMAPPROC_GETPORT(pmap) = 3;
+
+ pmaplist_ptr
+ PMAPPROC_DUMP(void) = 4;
+
+ rmtcallres
+ PMAPPROC_CALLIT(rmtcallargs) = 5;
+ } = 2;
+} = 100000;
+%
+#ifdef RPC_HDR
+%#define PMAPVERS_PROTO ((u_long)2)
+%#define PMAPVERS_ORIG ((u_long)1)
+%
+%#else /* ndef _KERNEL */
+%
+%#include <rpc/pmap_rmt.h>
+%
+%#ifdef __cplusplus
+%extern "C" {
+%#endif
+%
+%#define PMAPPORT 111
+%
+%struct pmap {
+% long unsigned pm_prog;
+% long unsigned pm_vers;
+% long unsigned pm_prot;
+% long unsigned pm_port;
+%};
+%typedef struct pmap PMAP;
+%#ifdef __STDC__
+%extern bool_t xdr_pmap (XDR *, struct pmap *);
+%#else
+%extern bool_t xdr_pmap ();
+%#endif
+%
+%struct pmaplist {
+% struct pmap pml_map;
+% struct pmaplist *pml_next;
+%};
+%typedef struct pmaplist PMAPLIST;
+%typedef struct pmaplist *pmaplist_ptr;
+%
+%
+%#ifdef __cplusplus
+%}
+%#endif
+%
+%#endif /* ndef _KERNEL */
+#endif
diff --git a/cpukit/librpc/include/rpcsvc/rex.x b/cpukit/librpc/include/rpcsvc/rex.x
new file mode 100644
index 0000000000..928efa21e7
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/rex.x
@@ -0,0 +1,235 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Remote execution (rex) protocol specification
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)rex.x 1.3 87/09/18 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)rex.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/rex.x,v 1.6 1999/08/27 23:45:10 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const STRINGSIZE = 1024;
+typedef string rexstring<1024>;
+
+/*
+ * values to pass to REXPROC_SIGNAL
+ */
+const SIGINT = 2; /* interrupt */
+
+/*
+ * Values for rst_flags, below
+ */
+const REX_INTERACTIVE = 1; /* interactive mode */
+
+struct rex_start {
+ rexstring rst_cmd<>; /* list of command and args */
+ rexstring rst_host; /* working directory host name */
+ rexstring rst_fsname; /* working directory file system name */
+ rexstring rst_dirwithin;/* working directory within file system */
+ rexstring rst_env<>; /* list of environment */
+ unsigned int rst_port0; /* port for stdin */
+ unsigned int rst_port1; /* port for stdout */
+ unsigned int rst_port2; /* port for stderr */
+ unsigned int rst_flags; /* options - see const above */
+};
+
+struct rex_result {
+ int rlt_stat; /* integer status code */
+ rexstring rlt_message; /* string message for human consumption */
+};
+
+
+struct sgttyb {
+ unsigned four; /* always equals 4 */
+ opaque chars[4];
+ /* chars[0] == input speed */
+ /* chars[1] == output speed */
+ /* chars[2] == kill character */
+ /* chars[3] == erase character */
+ unsigned flags;
+};
+/* values for speeds above (baud rates) */
+const B0 = 0;
+const B50 = 1;
+const B75 = 2;
+const B110 = 3;
+const B134 = 4;
+const B150 = 5;
+const B200 = 6;
+const B300 = 7;
+const B600 = 8;
+const B1200 = 9;
+const B1800 = 10;
+const B2400 = 11;
+const B4800 = 12;
+const B9600 = 13;
+const B19200 = 14;
+const B38400 = 15;
+
+/* values for flags above */
+const TANDEM = 0x00000001; /* send stopc on out q full */
+const CBREAK = 0x00000002; /* half-cooked mode */
+const LCASE = 0x00000004; /* simulate lower case */
+const ECHO = 0x00000008; /* echo input */
+const CRMOD = 0x00000010; /* map \r to \r\n on output */
+const RAW = 0x00000020; /* no i/o processing */
+const ODDP = 0x00000040; /* get/send odd parity */
+const EVENP = 0x00000080; /* get/send even parity */
+const ANYP = 0x000000c0; /* get any parity/send none */
+const NLDELAY = 0x00000300; /* \n delay */
+const NL0 = 0x00000000;
+const NL1 = 0x00000100; /* tty 37 */
+const NL2 = 0x00000200; /* vt05 */
+const NL3 = 0x00000300;
+const TBDELAY = 0x00000c00; /* horizontal tab delay */
+const TAB0 = 0x00000000;
+const TAB1 = 0x00000400; /* tty 37 */
+const TAB2 = 0x00000800;
+const XTABS = 0x00000c00; /* expand tabs on output */
+const CRDELAY = 0x00003000; /* \r delay */
+const CR0 = 0x00000000;
+const CR1 = 0x00001000; /* tn 300 */
+const CR2 = 0x00002000; /* tty 37 */
+const CR3 = 0x00003000; /* concept 100 */
+const VTDELAY = 0x00004000; /* vertical tab delay */
+const FF0 = 0x00000000;
+const FF1 = 0x00004000; /* tty 37 */
+const BSDELAY = 0x00008000; /* \b delay */
+const BS0 = 0x00000000;
+const BS1 = 0x00008000;
+const CRTBS = 0x00010000; /* do backspacing for crt */
+const PRTERA = 0x00020000; /* \ ... / erase */
+const CRTERA = 0x00040000; /* " \b " to wipe out char */
+const TILDE = 0x00080000; /* hazeltine tilde kludge */
+const MDMBUF = 0x00100000; /* start/stop output on carrier intr */
+const LITOUT = 0x00200000; /* literal output */
+const TOSTOP = 0x00400000; /* SIGTTOU on background output */
+const FLUSHO = 0x00800000; /* flush output to terminal */
+const NOHANG = 0x01000000; /* no SIGHUP on carrier drop */
+const L001000 = 0x02000000;
+const CRTKIL = 0x04000000; /* kill line with " \b " */
+const PASS8 = 0x08000000;
+const CTLECH = 0x10000000; /* echo control chars as ^X */
+const PENDIN = 0x20000000; /* tp->t_rawq needs reread */
+const DECCTQ = 0x40000000; /* only ^Q starts after ^S */
+const NOFLSH = 0x80000000; /* no output flush on signal */
+
+struct tchars {
+ unsigned six; /* always equals 6 */
+ opaque chars[6];
+ /* chars[0] == interrupt char */
+ /* chars[1] == quit char */
+ /* chars[2] == start output char */
+ /* chars[3] == stop output char */
+ /* chars[4] == end-of-file char */
+ /* chars[5] == input delimeter (like nl) */
+};
+
+struct ltchars {
+ unsigned six; /* always equals 6 */
+ opaque chars[6];
+ /* chars[0] == stop process signal */
+ /* chars[1] == delayed stop process signal */
+ /* chars[2] == reprint line */
+ /* chars[3] == flush output */
+ /* chars[4] == word erase */
+ /* chars[5] == literal next character */
+ unsigned mode;
+};
+
+struct rex_ttysize {
+ int ts_lines;
+ int ts_cols;
+};
+
+struct rex_ttymode {
+ sgttyb basic; /* standard unix tty flags */
+ tchars more; /* interrupt, kill characters, etc. */
+ ltchars yetmore; /* special Berkeley characters */
+ unsigned andmore; /* and Berkeley modes */
+};
+
+/* values for andmore above */
+const LCRTBS = 0x0001; /* do backspacing for crt */
+const LPRTERA = 0x0002; /* \ ... / erase */
+const LCRTERA = 0x0004; /* " \b " to wipe out char */
+const LTILDE = 0x0008; /* hazeltine tilde kludge */
+const LMDMBUF = 0x0010; /* start/stop output on carrier intr */
+const LLITOUT = 0x0020; /* literal output */
+const LTOSTOP = 0x0040; /* SIGTTOU on background output */
+const LFLUSHO = 0x0080; /* flush output to terminal */
+const LNOHANG = 0x0100; /* no SIGHUP on carrier drop */
+const LL001000 = 0x0200;
+const LCRTKIL = 0x0400; /* kill line with " \b " */
+const LPASS8 = 0x0800;
+const LCTLECH = 0x1000; /* echo control chars as ^X */
+const LPENDIN = 0x2000; /* needs reread */
+const LDECCTQ = 0x4000; /* only ^Q starts after ^S */
+const LNOFLSH = 0x8000; /* no output flush on signal */
+
+program REXPROG {
+ version REXVERS {
+
+ /*
+ * Start remote execution
+ */
+ rex_result
+ REXPROC_START(rex_start) = 1;
+
+ /*
+ * Wait for remote execution to terminate
+ */
+ rex_result
+ REXPROC_WAIT(void) = 2;
+
+ /*
+ * Send tty modes
+ */
+ void
+ REXPROC_MODES(rex_ttymode) = 3;
+
+ /*
+ * Send window size change
+ */
+ void
+ REXPROC_WINCH(rex_ttysize) = 4;
+
+ /*
+ * Send other signal
+ */
+ void
+ REXPROC_SIGNAL(int) = 5;
+ } = 1;
+} = 100017;
diff --git a/cpukit/librpc/include/rpcsvc/rnusers.x b/cpukit/librpc/include/rpcsvc/rnusers.x
new file mode 100644
index 0000000000..393eaf4eac
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/rnusers.x
@@ -0,0 +1,122 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Find out about remote users
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)rnusers.x 1.2 87/09/20 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)rnusers.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/rnusers.x,v 1.6 1999/08/27 23:45:10 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const MAXUSERS = 100;
+const MAXUTLEN = 256;
+
+struct utmp {
+ string ut_line<MAXUTLEN>;
+ string ut_name<MAXUTLEN>;
+ string ut_host<MAXUTLEN>;
+ int ut_time;
+};
+
+
+struct utmpidle {
+ utmp ui_utmp;
+ unsigned int ui_idle;
+};
+
+typedef utmp utmparr<MAXUSERS>;
+
+typedef utmpidle utmpidlearr<MAXUSERS>;
+
+const RUSERS_MAXUSERLEN = 32;
+const RUSERS_MAXLINELEN = 32;
+const RUSERS_MAXHOSTLEN = 257;
+
+struct rusers_utmp {
+ string ut_user<RUSERS_MAXUSERLEN>; /* aka ut_name */
+ string ut_line<RUSERS_MAXLINELEN>; /* device */
+ string ut_host<RUSERS_MAXHOSTLEN>; /* host user logged on from */
+ int ut_type; /* type of entry */
+ int ut_time; /* time entry was made */
+ unsigned int ut_idle; /* minutes idle */
+};
+
+typedef rusers_utmp utmp_array<>;
+
+program RUSERSPROG {
+ /*
+ * Old version does not include idle information
+ */
+ version RUSERSVERS_ORIG {
+ int
+ RUSERSPROC_NUM(void) = 1;
+
+ utmparr
+ RUSERSPROC_NAMES(void) = 2;
+
+ utmparr
+ RUSERSPROC_ALLNAMES(void) = 3;
+ } = 1;
+
+ /*
+ * Includes idle information
+ */
+ version RUSERSVERS_IDLE {
+ int
+ RUSERSPROC_NUM(void) = 1;
+
+ utmpidlearr
+ RUSERSPROC_NAMES(void) = 2;
+
+ utmpidlearr
+ RUSERSPROC_ALLNAMES(void) = 3;
+ } = 2;
+
+ /*
+ * Version 3 rusers procedures (from Solaris).
+ * (Thanks a lot Sun.)
+ */
+ version RUSERSVERS_3 {
+ int
+ RUSERSPROC_NUM(void) = 1;
+
+ utmp_array
+ RUSERSPROC_NAMES(void) = 2;
+
+ utmp_array
+ RUSERSPROC_ALLNAMES(void) = 3;
+ } = 3;
+
+} = 100002;
diff --git a/cpukit/librpc/include/rpcsvc/rquota.x b/cpukit/librpc/include/rpcsvc/rquota.x
new file mode 100644
index 0000000000..72864d1c69
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/rquota.x
@@ -0,0 +1,67 @@
+/*
+ * Remote quota protocol
+ * Requires unix authentication
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)rquota.x 1.2 87/09/20 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)rquota.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/rquota.x,v 1.6 1999/08/27 23:45:10 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const RQ_PATHLEN = 1024;
+
+struct getquota_args {
+ string gqa_pathp<RQ_PATHLEN>; /* path to filesystem of interest */
+ int gqa_uid; /* inquire about quota for uid */
+};
+
+/*
+ * remote quota structure
+ */
+struct rquota {
+ int rq_bsize; /* block size for block counts */
+ bool rq_active; /* indicates whether quota is active */
+ unsigned int rq_bhardlimit; /* absolute limit on disk blks alloc */
+ unsigned int rq_bsoftlimit; /* preferred limit on disk blks */
+ unsigned int rq_curblocks; /* current block count */
+ unsigned int rq_fhardlimit; /* absolute limit on allocated files */
+ unsigned int rq_fsoftlimit; /* preferred file limit */
+ unsigned int rq_curfiles; /* current # allocated files */
+ unsigned int rq_btimeleft; /* time left for excessive disk use */
+ unsigned int rq_ftimeleft; /* time left for excessive files */
+};
+
+enum gqr_status {
+ Q_OK = 1, /* quota returned */
+ Q_NOQUOTA = 2, /* noquota for uid */
+ Q_EPERM = 3 /* no permission to access quota */
+};
+
+union getquota_rslt switch (gqr_status status) {
+case Q_OK:
+ rquota gqr_rquota; /* valid if status == Q_OK */
+case Q_NOQUOTA:
+ void;
+case Q_EPERM:
+ void;
+};
+
+program RQUOTAPROG {
+ version RQUOTAVERS {
+ /*
+ * Get all quotas
+ */
+ getquota_rslt
+ RQUOTAPROC_GETQUOTA(getquota_args) = 1;
+
+ /*
+ * Get active quotas only
+ */
+ getquota_rslt
+ RQUOTAPROC_GETACTIVEQUOTA(getquota_args) = 2;
+ } = 1;
+} = 100011;
diff --git a/cpukit/librpc/include/rpcsvc/rstat.x b/cpukit/librpc/include/rpcsvc/rstat.x
new file mode 100644
index 0000000000..fee9d52032
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/rstat.x
@@ -0,0 +1,151 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Gather statistics on remote machines
+ */
+
+#ifdef RPC_HDR
+
+%#ifndef FSCALE
+%/*
+% * Scale factor for scaled integers used to count load averages.
+% */
+%#define FSHIFT 8 /* bits to right of fixed binary point */
+%#define FSCALE (1<<FSHIFT)
+%
+%#endif /* ndef FSCALE */
+
+#else
+
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)rstat.x 1.2 87/09/18 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)rstat.x 2.2 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/rstat.x,v 1.6 1999/08/27 23:45:11 peter Exp $";
+%#endif /* not lint */
+
+#endif /* def RPC_HDR */
+
+const RSTAT_CPUSTATES = 4;
+const RSTAT_DK_NDRIVE = 4;
+
+/*
+ * GMT since 0:00, January 1, 1970
+ */
+struct rstat_timeval {
+ unsigned int tv_sec; /* seconds */
+ unsigned int tv_usec; /* and microseconds */
+};
+
+struct statstime { /* RSTATVERS_TIME */
+ int cp_time[RSTAT_CPUSTATES];
+ int dk_xfer[RSTAT_DK_NDRIVE];
+ unsigned int v_pgpgin; /* these are cumulative sum */
+ unsigned int v_pgpgout;
+ unsigned int v_pswpin;
+ unsigned int v_pswpout;
+ unsigned int v_intr;
+ int if_ipackets;
+ int if_ierrors;
+ int if_oerrors;
+ int if_collisions;
+ unsigned int v_swtch;
+ int avenrun[3]; /* scaled by FSCALE */
+ rstat_timeval boottime;
+ rstat_timeval curtime;
+ int if_opackets;
+};
+
+struct statsswtch { /* RSTATVERS_SWTCH */
+ int cp_time[RSTAT_CPUSTATES];
+ int dk_xfer[RSTAT_DK_NDRIVE];
+ unsigned int v_pgpgin; /* these are cumulative sum */
+ unsigned int v_pgpgout;
+ unsigned int v_pswpin;
+ unsigned int v_pswpout;
+ unsigned int v_intr;
+ int if_ipackets;
+ int if_ierrors;
+ int if_oerrors;
+ int if_collisions;
+ unsigned int v_swtch;
+ unsigned int avenrun[3];/* scaled by FSCALE */
+ rstat_timeval boottime;
+ int if_opackets;
+};
+
+struct stats { /* RSTATVERS_ORIG */
+ int cp_time[RSTAT_CPUSTATES];
+ int dk_xfer[RSTAT_DK_NDRIVE];
+ unsigned int v_pgpgin; /* these are cumulative sum */
+ unsigned int v_pgpgout;
+ unsigned int v_pswpin;
+ unsigned int v_pswpout;
+ unsigned int v_intr;
+ int if_ipackets;
+ int if_ierrors;
+ int if_oerrors;
+ int if_collisions;
+ int if_opackets;
+};
+
+
+program RSTATPROG {
+ /*
+ * Newest version includes current time and context switching info
+ */
+ version RSTATVERS_TIME {
+ statstime
+ RSTATPROC_STATS(void) = 1;
+
+ unsigned int
+ RSTATPROC_HAVEDISK(void) = 2;
+ } = 3;
+ /*
+ * Does not have current time
+ */
+ version RSTATVERS_SWTCH {
+ statsswtch
+ RSTATPROC_STATS(void) = 1;
+
+ unsigned int
+ RSTATPROC_HAVEDISK(void) = 2;
+ } = 2;
+ /*
+ * Old version has no info about current time or context switching
+ */
+ version RSTATVERS_ORIG {
+ stats
+ RSTATPROC_STATS(void) = 1;
+
+ unsigned int
+ RSTATPROC_HAVEDISK(void) = 2;
+ } = 1;
+} = 100001;
diff --git a/cpukit/librpc/include/rpcsvc/rwall.x b/cpukit/librpc/include/rpcsvc/rwall.x
new file mode 100644
index 0000000000..6c26c1f18f
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/rwall.x
@@ -0,0 +1,57 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+%/*
+% * Copyright (c) 1984, 1990 by Sun Microsystems, Inc.
+% */
+%
+%/* from @(#)rwall.x 1.6 91/03/11 TIRPC 1.0 */
+
+#ifdef RPC_HDR
+%
+%#ifndef _rpcsvc_rwall_h
+%#define _rpcsvc_rwall_h
+%
+%typedef char *wrapstring;
+%
+#endif
+
+program WALLPROG {
+ version WALLVERS {
+ void
+ WALLPROC_WALL(wrapstring) = 2;
+
+ } = 1;
+} = 100008;
+
+#ifdef RPC_HDR
+%
+%#endif /* ! _rpcsvc_rwall_h */
+#endif
diff --git a/cpukit/librpc/include/rpcsvc/sm_inter.x b/cpukit/librpc/include/rpcsvc/sm_inter.x
new file mode 100644
index 0000000000..2071516a7f
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/sm_inter.x
@@ -0,0 +1,122 @@
+/* @(#)sm_inter.x 2.2 88/08/01 4.0 RPCSRC */
+/* @(#)sm_inter.x 1.7 87/06/24 Copyr 1987 Sun Micro */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Status monitor protocol specification
+ * Copyright (C) 1986 Sun Microsystems, Inc.
+ *
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/sm_inter.x,v 1.8 1999/08/27 23:45:11 peter Exp $";
+%#endif /* not lint */
+#endif
+
+program SM_PROG {
+ version SM_VERS {
+ /* res_stat = stat_succ if status monitor agrees to monitor */
+ /* res_stat = stat_fail if status monitor cannot monitor */
+ /* if res_stat == stat_succ, state = state number of site sm_name */
+ struct sm_stat_res SM_STAT(struct sm_name) = 1;
+
+ /* res_stat = stat_succ if status monitor agrees to monitor */
+ /* res_stat = stat_fail if status monitor cannot monitor */
+ /* stat consists of state number of local site */
+ struct sm_stat_res SM_MON(struct mon) = 2;
+
+ /* stat consists of state number of local site */
+ struct sm_stat SM_UNMON(struct mon_id) = 3;
+
+ /* stat consists of state number of local site */
+ struct sm_stat SM_UNMON_ALL(struct my_id) = 4;
+
+ void SM_SIMU_CRASH(void) = 5;
+
+ } = 1;
+} = 100024;
+
+const SM_MAXSTRLEN = 1024;
+
+struct sm_name {
+ string mon_name<SM_MAXSTRLEN>;
+};
+
+struct my_id {
+ string my_name<SM_MAXSTRLEN>; /* name of the site iniates the monitoring request*/
+ int my_prog; /* rpc program # of the requesting process */
+ int my_vers; /* rpc version # of the requesting process */
+ int my_proc; /* rpc procedure # of the requesting process */
+};
+
+struct mon_id {
+ string mon_name<SM_MAXSTRLEN>; /* name of the site to be monitored */
+ struct my_id my_id;
+};
+
+
+struct mon{
+ struct mon_id mon_id;
+ opaque priv[16]; /* private information to store at monitor for requesting process */
+};
+
+
+/*
+ * state # of status monitor monitonically increases each time
+ * status of the site changes:
+ * an even number (>= 0) indicates the site is down and
+ * an odd number (> 0) indicates the site is up;
+ */
+struct sm_stat {
+ int state; /* state # of status monitor */
+};
+
+enum res {
+ stat_succ = 0, /* status monitor agrees to monitor */
+ stat_fail = 1 /* status monitor cannot monitor */
+};
+
+struct sm_stat_res {
+ res res_stat;
+ int state;
+};
+
+/*
+ * structure of the status message sent back by the status monitor
+ * when monitor site status changes
+ */
+struct status {
+ string mon_name<SM_MAXSTRLEN>;
+ int state;
+ opaque priv[16]; /* stored private information */
+};
diff --git a/cpukit/librpc/include/rpcsvc/spray.x b/cpukit/librpc/include/rpcsvc/spray.x
new file mode 100644
index 0000000000..a4d086af48
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/spray.x
@@ -0,0 +1,90 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Spray a server with packets
+ * Useful for testing flakiness of network interfaces
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)spray.x 1.2 87/09/18 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)spray.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/spray.x,v 1.6 1999/08/27 23:45:11 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const SPRAYMAX = 8845; /* max amount can spray */
+
+/*
+ * GMT since 0:00, 1 January 1970
+ */
+struct spraytimeval {
+ unsigned int sec;
+ unsigned int usec;
+};
+
+/*
+ * spray statistics
+ */
+struct spraycumul {
+ unsigned int counter;
+ spraytimeval clock;
+};
+
+/*
+ * spray data
+ */
+typedef opaque sprayarr<SPRAYMAX>;
+
+program SPRAYPROG {
+ version SPRAYVERS {
+ /*
+ * Just throw away the data and increment the counter
+ * This call never returns, so the client should always
+ * time it out.
+ */
+ void
+ SPRAYPROC_SPRAY(sprayarr) = 1;
+
+ /*
+ * Get the value of the counter and elapsed time since
+ * last CLEAR.
+ */
+ spraycumul
+ SPRAYPROC_GET(void) = 2;
+
+ /*
+ * Clear the counter and reset the elapsed time
+ */
+ void
+ SPRAYPROC_CLEAR(void) = 3;
+ } = 1;
+} = 100012;
diff --git a/cpukit/librpc/include/rpcsvc/yp.x b/cpukit/librpc/include/rpcsvc/yp.x
new file mode 100644
index 0000000000..aa872653ff
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/yp.x
@@ -0,0 +1,379 @@
+/* @(#)yp.x 2.1 88/08/01 4.0 RPCSRC */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Protocol description file for the Yellow Pages Service
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/yp.x,v 1.12 1999/08/27 23:45:12 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const YPMAXRECORD = 1024;
+const YPMAXDOMAIN = 64;
+const YPMAXMAP = 64;
+const YPMAXPEER = 64;
+
+
+enum ypstat {
+ YP_TRUE = 1,
+ YP_NOMORE = 2,
+ YP_FALSE = 0,
+ YP_NOMAP = -1,
+ YP_NODOM = -2,
+ YP_NOKEY = -3,
+ YP_BADOP = -4,
+ YP_BADDB = -5,
+ YP_YPERR = -6,
+ YP_BADARGS = -7,
+ YP_VERS = -8
+};
+
+
+enum ypxfrstat {
+ YPXFR_SUCC = 1,
+ YPXFR_AGE = 2,
+ YPXFR_NOMAP = -1,
+ YPXFR_NODOM = -2,
+ YPXFR_RSRC = -3,
+ YPXFR_RPC = -4,
+ YPXFR_MADDR = -5,
+ YPXFR_YPERR = -6,
+ YPXFR_BADARGS = -7,
+ YPXFR_DBM = -8,
+ YPXFR_FILE = -9,
+ YPXFR_SKEW = -10,
+ YPXFR_CLEAR = -11,
+ YPXFR_FORCE = -12,
+ YPXFR_XFRERR = -13,
+ YPXFR_REFUSED = -14
+};
+
+
+typedef string domainname<YPMAXDOMAIN>;
+typedef string mapname<YPMAXMAP>;
+typedef string peername<YPMAXPEER>;
+typedef opaque keydat<YPMAXRECORD>;
+typedef opaque valdat<YPMAXRECORD>;
+
+
+struct ypmap_parms {
+ domainname domain;
+ mapname map;
+ unsigned int ordernum;
+ peername peer;
+};
+
+struct ypreq_key {
+ domainname domain;
+ mapname map;
+ keydat key;
+};
+
+struct ypreq_nokey {
+ domainname domain;
+ mapname map;
+};
+
+struct ypreq_xfr {
+ ypmap_parms map_parms;
+ unsigned int transid;
+ unsigned int prog;
+ unsigned int port;
+};
+
+
+struct ypresp_val {
+ ypstat stat;
+ valdat val;
+};
+
+struct ypresp_key_val {
+ ypstat stat;
+#ifdef STUPID_SUN_BUG /* These are backwards */
+ keydat key;
+ valdat val;
+#else
+ valdat val;
+ keydat key;
+#endif
+};
+
+
+struct ypresp_master {
+ ypstat stat;
+ peername peer;
+};
+
+struct ypresp_order {
+ ypstat stat;
+ unsigned int ordernum;
+};
+
+union ypresp_all switch (bool more) {
+case TRUE:
+ ypresp_key_val val;
+case FALSE:
+ void;
+};
+
+struct ypresp_xfr {
+ unsigned int transid;
+ ypxfrstat xfrstat;
+};
+
+struct ypmaplist {
+ mapname map;
+ ypmaplist *next;
+};
+
+struct ypresp_maplist {
+ ypstat stat;
+ ypmaplist *maps;
+};
+
+enum yppush_status {
+ YPPUSH_SUCC = 1, /* Success */
+ YPPUSH_AGE = 2, /* Master's version not newer */
+ YPPUSH_NOMAP = -1, /* Can't find server for map */
+ YPPUSH_NODOM = -2, /* Domain not supported */
+ YPPUSH_RSRC = -3, /* Local resource alloc failure */
+ YPPUSH_RPC = -4, /* RPC failure talking to server */
+ YPPUSH_MADDR = -5, /* Can't get master address */
+ YPPUSH_YPERR = -6, /* YP server/map db error */
+ YPPUSH_BADARGS = -7, /* Request arguments bad */
+ YPPUSH_DBM = -8, /* Local dbm operation failed */
+ YPPUSH_FILE = -9, /* Local file I/O operation failed */
+ YPPUSH_SKEW = -10, /* Map version skew during transfer */
+ YPPUSH_CLEAR = -11, /* Can't send "Clear" req to local ypserv */
+ YPPUSH_FORCE = -12, /* No local order number in map use -f flag. */
+ YPPUSH_XFRERR = -13, /* ypxfr error */
+ YPPUSH_REFUSED = -14 /* Transfer request refused by ypserv */
+};
+
+struct yppushresp_xfr {
+ unsigned transid;
+ yppush_status status;
+};
+
+/*
+ * Response structure and overall result status codes. Success and failure
+ * represent two separate response message types.
+ */
+
+enum ypbind_resptype {
+ YPBIND_SUCC_VAL = 1,
+ YPBIND_FAIL_VAL = 2
+};
+
+struct ypbind_binding {
+ opaque ypbind_binding_addr[4]; /* In network order */
+ opaque ypbind_binding_port[2]; /* In network order */
+};
+
+union ypbind_resp switch (ypbind_resptype ypbind_status) {
+case YPBIND_FAIL_VAL:
+ unsigned ypbind_error;
+case YPBIND_SUCC_VAL:
+ ypbind_binding ypbind_bindinfo;
+};
+
+/* Detailed failure reason codes for response field ypbind_error*/
+
+const YPBIND_ERR_ERR = 1; /* Internal error */
+const YPBIND_ERR_NOSERV = 2; /* No bound server for passed domain */
+const YPBIND_ERR_RESC = 3; /* System resource allocation failure */
+
+
+/*
+ * Request data structure for ypbind "Set domain" procedure.
+ */
+struct ypbind_setdom {
+ domainname ypsetdom_domain;
+ ypbind_binding ypsetdom_binding;
+ unsigned ypsetdom_vers;
+};
+
+
+/*
+ * NIS v1 support for backwards compatibility
+ */
+enum ypreqtype {
+ YPREQ_KEY = 1,
+ YPREQ_NOKEY = 2,
+ YPREQ_MAP_PARMS = 3
+};
+
+enum ypresptype {
+ YPRESP_VAL = 1,
+ YPRESP_KEY_VAL = 2,
+ YPRESP_MAP_PARMS = 3
+};
+
+union yprequest switch (ypreqtype yp_reqtype) {
+case YPREQ_KEY:
+ ypreq_key yp_req_keytype;
+case YPREQ_NOKEY:
+ ypreq_nokey yp_req_nokeytype;
+case YPREQ_MAP_PARMS:
+ ypmap_parms yp_req_map_parmstype;
+};
+
+union ypresponse switch (ypresptype yp_resptype) {
+case YPRESP_VAL:
+ ypresp_val yp_resp_valtype;
+case YPRESP_KEY_VAL:
+ ypresp_key_val yp_resp_key_valtype;
+case YPRESP_MAP_PARMS:
+ ypmap_parms yp_resp_map_parmstype;
+};
+
+#if !defined(YPBIND_ONLY) && !defined(YPPUSH_ONLY)
+/*
+ * YP access protocol
+ */
+program YPPROG {
+/*
+ * NIS v1 support for backwards compatibility
+ */
+ version YPOLDVERS {
+ void
+ YPOLDPROC_NULL(void) = 0;
+
+ bool
+ YPOLDPROC_DOMAIN(domainname) = 1;
+
+ bool
+ YPOLDPROC_DOMAIN_NONACK(domainname) = 2;
+
+ ypresponse
+ YPOLDPROC_MATCH(yprequest) = 3;
+
+ ypresponse
+ YPOLDPROC_FIRST(yprequest) = 4;
+
+ ypresponse
+ YPOLDPROC_NEXT(yprequest) = 5;
+
+ ypresponse
+ YPOLDPROC_POLL(yprequest) = 6;
+
+ ypresponse
+ YPOLDPROC_PUSH(yprequest) = 7;
+
+ ypresponse
+ YPOLDPROC_PULL(yprequest) = 8;
+
+ ypresponse
+ YPOLDPROC_GET(yprequest) = 9;
+ } = 1;
+
+ version YPVERS {
+ void
+ YPPROC_NULL(void) = 0;
+
+ bool
+ YPPROC_DOMAIN(domainname) = 1;
+
+ bool
+ YPPROC_DOMAIN_NONACK(domainname) = 2;
+
+ ypresp_val
+ YPPROC_MATCH(ypreq_key) = 3;
+
+ ypresp_key_val
+#ifdef STUPID_SUN_BUG /* should be ypreq_nokey */
+ YPPROC_FIRST(ypreq_key) = 4;
+#else
+ YPPROC_FIRST(ypreq_nokey) = 4;
+#endif
+ ypresp_key_val
+ YPPROC_NEXT(ypreq_key) = 5;
+
+ ypresp_xfr
+ YPPROC_XFR(ypreq_xfr) = 6;
+
+ void
+ YPPROC_CLEAR(void) = 7;
+
+ ypresp_all
+ YPPROC_ALL(ypreq_nokey) = 8;
+
+ ypresp_master
+ YPPROC_MASTER(ypreq_nokey) = 9;
+
+ ypresp_order
+ YPPROC_ORDER(ypreq_nokey) = 10;
+
+ ypresp_maplist
+ YPPROC_MAPLIST(domainname) = 11;
+ } = 2;
+} = 100004;
+#endif
+#if !defined(YPSERV_ONLY) && !defined(YPBIND_ONLY)
+/*
+ * YPPUSHPROC_XFRRESP is the callback routine for result of YPPROC_XFR
+ */
+program YPPUSH_XFRRESPPROG {
+ version YPPUSH_XFRRESPVERS {
+ void
+ YPPUSHPROC_NULL(void) = 0;
+#ifdef STUPID_SUN_BUG /* argument and return value are backwards */
+ yppushresp_xfr
+ YPPUSHPROC_XFRRESP(void) = 1;
+#else
+ void
+ YPPUSHPROC_XFRRESP(yppushresp_xfr) = 1;
+#endif
+ } = 1;
+} = 0x40000000; /* transient: could be anything up to 0x5fffffff */
+#endif
+#if !defined(YPSERV_ONLY) && !defined(YPPUSH_ONLY)
+/*
+ * YP binding protocol
+ */
+program YPBINDPROG {
+ version YPBINDVERS {
+ void
+ YPBINDPROC_NULL(void) = 0;
+
+ ypbind_resp
+ YPBINDPROC_DOMAIN(domainname) = 1;
+
+ void
+ YPBINDPROC_SETDOM(ypbind_setdom) = 2;
+ } = 2;
+} = 100007;
+
+#endif
diff --git a/cpukit/librpc/include/rpcsvc/yp_prot.h b/cpukit/librpc/include/rpcsvc/yp_prot.h
new file mode 100644
index 0000000000..92de593611
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/yp_prot.h
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
+ * 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. 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 BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD: src/include/rpcsvc/yp_prot.h,v 1.10 1999/08/27 23:45:12 peter Exp $
+ */
+
+#ifndef _RPCSVC_YP_PROT_H_
+#define _RPCSVC_YP_PROT_H_
+
+/*
+ * YPSERV PROTOCOL:
+ *
+ * ypserv supports the following procedures:
+ *
+ * YPPROC_NULL takes (void), returns (void).
+ * called to check if server is alive.
+ * YPPROC_DOMAIN takes (char *), returns (bool_t).
+ * true if ypserv serves the named domain.
+ * YPPROC_DOMAIN_NOACK takes (char *), returns (bool_t).
+ * true if ypserv serves the named domain.
+ * used for broadcasts, does not ack if ypserv
+ * doesn't handle named domain.
+ * YPPROC_MATCH takes (struct ypreq_key), returns (struct ypresp_val)
+ * does a lookup.
+ * YPPROC_FIRST takes (struct ypreq_nokey) returns (ypresp_key_val).
+ * gets the first key/datum from the map.
+ * YPPROC_NEXT takes (struct ypreq_key) returns (ypresp_key_val).
+ * gets the next key/datum from the map.
+ * YPPROC_XFR takes (struct ypreq_xfr), returns (void).
+ * tells ypserv to check if there is a new version of
+ * the map.
+ * YPPROC_CLEAR takes (void), returns (void).
+ * tells ypserv to flush it's file cache, so that
+ * newly transferred files will get read.
+ * YPPROC_ALL takes (struct ypreq_nokey), returns (bool_t and
+ * struct ypresp_key_val).
+ * returns an array of data, with the bool_t being
+ * false on the last datum. read the source, it's
+ * convoluted.
+ * YPPROC_MASTER takes (struct ypreq_nokey), returns (ypresp_master).
+ * YPPROC_ORDER takes (struct ypreq_nokey), returns (ypresp_order).
+ * YPPROC_MAPLIST takes (char *), returns (struct ypmaplist *).
+ */
+
+#ifndef BOOL_DEFINED
+typedef u_int bool;
+#define BOOL_DEFINED
+#endif
+
+/* Program and version symbols, magic numbers */
+
+#define YPPROG ((u_long)100004)
+#define YPVERS ((u_long)2)
+#define YPVERS_ORIG ((u_long)1)
+#define YPMAXRECORD ((u_long)1024)
+#define YPMAXDOMAIN ((u_long)64)
+#define YPMAXMAP ((u_long)64)
+#define YPMAXPEER ((u_long)256)
+
+/*
+ * I don't know if anything of sun's depends on this, or if they
+ * simply defined it so that their own code wouldn't try to send
+ * packets over the ethernet MTU. This YP code doesn't use it.
+ */
+#define YPMSGSZ 1600
+
+#ifndef DATUM
+typedef struct {
+ char *dptr;
+ int dsize;
+} datum;
+#define DATUM
+#endif
+
+struct ypmap_parms {
+ char *domain;
+ char *map;
+ u_long ordernum;
+ char *owner;
+};
+
+struct ypreq_key {
+ char *domain;
+ char *map;
+ datum keydat;
+};
+
+struct ypreq_nokey {
+ char *domain;
+ char *map;
+};
+
+struct ypreq_xfr {
+ struct ypmap_parms map_parms;
+ u_long transid;
+ u_long proto;
+ u_short port;
+};
+#define ypxfr_domain map_parms.domain
+#define ypxfr_map map_parms.map
+#define ypxfr_ordernum map_parms.ordernum
+#define ypxfr_owner map_parms.owner
+
+struct ypresp_val {
+ u_long status;
+ datum valdat;
+};
+
+struct ypresp_key_val {
+ u_long status;
+ datum keydat;
+ datum valdat;
+};
+
+struct ypresp_master {
+ u_long status;
+ char *master;
+};
+
+struct ypresp_order {
+ u_long status;
+ u_long ordernum;
+};
+
+struct ypmaplist {
+ char ypml_name[YPMAXMAP + 1];
+ struct ypmaplist *ypml_next;
+};
+
+struct ypresp_maplist {
+ u_long status;
+ struct ypmaplist *list;
+};
+
+/* ypserv procedure numbers */
+#define YPPROC_NULL ((u_long)0)
+#define YPPROC_DOMAIN ((u_long)1)
+#define YPPROC_DOMAIN_NONACK ((u_long)2)
+#define YPPROC_MATCH ((u_long)3)
+#define YPPROC_FIRST ((u_long)4)
+#define YPPROC_NEXT ((u_long)5)
+#define YPPROC_XFR ((u_long)6)
+#define YPPROC_CLEAR ((u_long)7)
+#define YPPROC_ALL ((u_long)8)
+#define YPPROC_MASTER ((u_long)9)
+#define YPPROC_ORDER ((u_long)10)
+#define YPPROC_MAPLIST ((u_long)11)
+
+/* ypserv procedure return status values */
+#define YP_TRUE ((long)1) /* general purpose success code */
+#define YP_NOMORE ((long)2) /* no more entries in map */
+#define YP_FALSE ((long)0) /* general purpose failure code */
+#define YP_NOMAP ((long)-1) /* no such map in domain */
+#define YP_NODOM ((long)-2) /* domain not supported */
+#define YP_NOKEY ((long)-3) /* no such key in map */
+#define YP_BADOP ((long)-4) /* invalid operation */
+#define YP_BADDB ((long)-5) /* server data base is bad */
+#define YP_YPERR ((long)-6) /* YP server error */
+#define YP_BADARGS ((long)-7) /* request arguments bad */
+#define YP_VERS ((long)-8) /* YP server version mismatch */
+
+/*
+ * Sun's header file says:
+ * "Domain binding data structure, used by ypclnt package and ypserv modules.
+ * Users of the ypclnt package (or of this protocol) don't HAVE to know about
+ * it, but it must be available to users because _yp_dobind is a public
+ * interface."
+ *
+ * This is totally bogus! Nowhere else does Sun state that _yp_dobind() is
+ * a public interface, and I don't know any reason anyone would want to call
+ * it. But, just in case anyone does actually expect it to be available..
+ * we provide this.. exactly as Sun wants it.
+ */
+struct dom_binding {
+ struct dom_binding *dom_pnext;
+ char dom_domain[YPMAXDOMAIN + 1];
+ struct sockaddr_in dom_server_addr;
+ u_short dom_server_port;
+ int dom_socket;
+ CLIENT *dom_client;
+ u_short dom_local_port;
+ long dom_vers;
+};
+
+/*
+ * YPBIND PROTOCOL:
+ *
+ * ypbind supports the following procedures:
+ *
+ * YPBINDPROC_NULL takes (void), returns (void).
+ * to check if ypbind is running.
+ * YPBINDPROC_DOMAIN takes (char *), returns (struct ypbind_resp).
+ * requests that ypbind start to serve the
+ * named domain (if it doesn't already)
+ * YPBINDPROC_SETDOM takes (struct ypbind_setdom), returns (void).
+ * used by ypset.
+ */
+
+#define YPBINDPROG ((u_long)100007)
+#define YPBINDVERS ((u_long)2)
+#define YPBINDVERS_ORIG ((u_long)1)
+
+/* ypbind procedure numbers */
+#define YPBINDPROC_NULL ((u_long)0)
+#define YPBINDPROC_DOMAIN ((u_long)1)
+#define YPBINDPROC_SETDOM ((u_long)2)
+
+/* error code in ypbind_resp.ypbind_status */
+enum ypbind_resptype {
+ YPBIND_SUCC_VAL = 1,
+ YPBIND_FAIL_VAL = 2
+};
+
+/* network order, of course */
+struct ypbind_binding {
+ struct in_addr ypbind_binding_addr;
+ u_short ypbind_binding_port;
+};
+
+struct ypbind_resp {
+ enum ypbind_resptype ypbind_status;
+ union {
+ u_long ypbind_error;
+ struct ypbind_binding ypbind_bindinfo;
+ } ypbind_respbody;
+};
+
+/* error code in ypbind_resp.ypbind_respbody.ypbind_error */
+#define YPBIND_ERR_ERR 1 /* internal error */
+#define YPBIND_ERR_NOSERV 2 /* no bound server for passed domain */
+#define YPBIND_ERR_RESC 3 /* system resource allocation failure */
+
+/*
+ * Request data structure for ypbind "Set domain" procedure.
+ */
+struct ypbind_setdom {
+ char ypsetdom_domain[YPMAXDOMAIN + 1];
+ struct ypbind_binding ypsetdom_binding;
+ u_short ypsetdom_vers;
+};
+#define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr
+#define ypsetdom_port ypsetdom_binding.ypbind_binding_port
+
+/*
+ * YPPUSH PROTOCOL:
+ *
+ * Sun says:
+ * "Protocol between clients (ypxfr, only) and yppush
+ * yppush speaks a protocol in the transient range, which
+ * is supplied to ypxfr as a command-line parameter when it
+ * is activated by ypserv."
+ *
+ * This protocol is not implemented, naturally, because this YP
+ * implementation only does the client side.
+ */
+#define YPPUSHVERS ((u_long)1)
+#define YPPUSHVERS_ORIG ((u_long)1)
+
+/* yppush procedure numbers */
+#define YPPUSHPROC_NULL ((u_long)0)
+#define YPPUSHPROC_XFRRESP ((u_long)1)
+
+struct yppushresp_xfr {
+ u_long transid;
+ u_long status;
+};
+
+/* yppush status value in yppushresp_xfr.status */
+#define YPPUSH_SUCC ((long)1) /* Success */
+#define YPPUSH_AGE ((long)2) /* Master's version not newer */
+#define YPPUSH_NOMAP ((long)-1) /* Can't find server for map */
+#define YPPUSH_NODOM ((long)-2) /* Domain not supported */
+#define YPPUSH_RSRC ((long)-3) /* Local resource alloc failure */
+#define YPPUSH_RPC ((long)-4) /* RPC failure talking to server */
+#define YPPUSH_MADDR ((long)-5) /* Can't get master address */
+#define YPPUSH_YPERR ((long)-6) /* YP server/map db error */
+#define YPPUSH_BADARGS ((long)-7) /* Request arguments bad */
+#define YPPUSH_DBM ((long)-8) /* Local dbm operation failed */
+#define YPPUSH_FILE ((long)-9) /* Local file I/O operation failed */
+#define YPPUSH_SKEW ((long)-10) /* Map version skew during transfer */
+#define YPPUSH_CLEAR ((long)-11) /* Can't send "Clear" req to local ypserv */
+#define YPPUSH_FORCE ((long)-12) /* No local order number in map - use -f */
+#define YPPUSH_XFRERR ((long)-13) /* ypxfr error */
+#define YPPUSH_REFUSED ((long)-14) /* Transfer request refused by ypserv */
+
+struct inaddr;
+__BEGIN_DECLS
+bool_t xdr_datum __P((XDR *, datum *));
+bool_t xdr_ypreq_key __P((XDR *, struct ypreq_key *));
+bool_t xdr_ypreq_nokey __P((XDR *, struct ypreq_nokey *));
+bool_t xdr_ypreq_xfr __P((XDR *, struct ypreq_xfr *));
+bool_t xdr_ypresp_val __P((XDR *, struct ypresp_val *));
+bool_t xdr_ypresp_key_val __P((XDR *, struct ypresp_key_val *));
+bool_t xdr_ypbind_resp __P((XDR *, struct ypbind_resp *));
+bool_t xdr_ypbind_setdom __P((XDR *, struct ypbind_setdom *));
+bool_t xdr_yp_inaddr __P((XDR *, struct inaddr *));
+bool_t xdr_ypmap_parms __P((XDR *, struct ypmap_parms *));
+bool_t xdr_yppushresp_xfr __P((XDR *, struct yppushresp_xfr *));
+bool_t xdr_ypresp_order __P((XDR *, struct ypresp_order *));
+bool_t xdr_ypresp_master __P((XDR *, struct ypresp_master *));
+bool_t xdr_ypresp_maplist __P((XDR *, struct ypresp_maplist *));
+__END_DECLS
+
+#endif /* _RPCSVC_YP_PROT_H_ */
diff --git a/cpukit/librpc/include/rpcsvc/ypclnt.h b/cpukit/librpc/include/rpcsvc/ypclnt.h
new file mode 100644
index 0000000000..0c73147998
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/ypclnt.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
+ * 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. 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 BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD: src/include/rpcsvc/ypclnt.h,v 1.11 1999/08/27 23:45:12 peter Exp $
+ */
+
+#ifndef _RPCSVC_YPCLNT_H_
+#define _RPCSVC_YPCLNT_H_
+
+#include <sys/cdefs.h>
+
+#define YPERR_BADARGS 1 /* args to function are bad */
+#define YPERR_RPC 2 /* RPC failure */
+#define YPERR_DOMAIN 3 /* can't bind to a server for domain */
+#define YPERR_MAP 4 /* no such map in server's domain */
+#define YPERR_KEY 5 /* no such key in map */
+#define YPERR_YPERR 6 /* some internal YP server or client error */
+#define YPERR_RESRC 7 /* local resource allocation failure */
+#define YPERR_NOMORE 8 /* no more records in map database */
+#define YPERR_PMAP 9 /* can't communicate with portmapper */
+#define YPERR_YPBIND 10 /* can't communicate with ypbind */
+#define YPERR_YPSERV 11 /* can't communicate with ypserv */
+#define YPERR_NODOM 12 /* local domain name not set */
+#define YPERR_BADDB 13 /* YP data base is bad */
+#define YPERR_VERS 14 /* YP version mismatch */
+#define YPERR_ACCESS 15 /* access violation */
+#define YPERR_BUSY 16 /* database is busy */
+
+/*
+ * Types of update operations
+ */
+#define YPOP_CHANGE 1 /* change, do not add */
+#define YPOP_INSERT 2 /* add, do not change */
+#define YPOP_DELETE 3 /* delete this entry */
+#define YPOP_STORE 4 /* add, or change */
+
+struct ypall_callback {
+ /* return non-0 to stop getting called */
+ int (*foreach) __P((unsigned long, char *, int, char *, int, void *));
+ char *data; /* opaque pointer for use of callback fn */
+};
+
+struct dom_binding;
+
+__BEGIN_DECLS
+int yp_bind __P((char *dom));
+int _yp_dobind __P((char *dom, struct dom_binding **ypdb));
+void yp_unbind __P((char *dom));
+int yp_get_default_domain __P((char **domp));
+int yp_match __P((char *indomain, char *inmap,
+ const char *inkey, int inkeylen, char **outval,
+ int *outvallen));
+int yp_first __P((char *indomain, char *inmap,
+ char **outkey, int *outkeylen, char **outval,
+ int *outvallen));
+int yp_next __P((char *indomain, char *inmap,
+ char *inkey, int inkeylen, char **outkey,
+ int *outkeylen, char **outval, int *outvallen));
+int yp_master __P((char *indomain, char *inmap, char **outname));
+int yp_order __P((char *indomain, char *inmap, int *outorder));
+int yp_all __P((char *indomain, char *inmap,
+ struct ypall_callback *incallback));
+char * yperr_string __P((int incode));
+char * ypbinderr_string __P((int incode));
+int ypprot_err __P((unsigned int incode));
+__END_DECLS
+
+#endif /* _RPCSVC_YPCLNT_H_ */
diff --git a/cpukit/librpc/include/rpcsvc/yppasswd.x b/cpukit/librpc/include/rpcsvc/yppasswd.x
new file mode 100644
index 0000000000..bcc83a1346
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/yppasswd.x
@@ -0,0 +1,75 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * YP password update protocol
+ * Requires unix authentication
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)yppasswd.x 1.1 87/04/13 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)yppasswd.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/yppasswd.x,v 1.6 1999/08/27 23:45:12 peter Exp $";
+%#endif /* not lint */
+#endif
+
+program YPPASSWDPROG {
+ version YPPASSWDVERS {
+ /*
+ * Update my passwd entry
+ */
+ int
+ YPPASSWDPROC_UPDATE(yppasswd) = 1;
+ } = 1;
+} = 100009;
+
+
+struct x_passwd {
+ string pw_name<>; /* username */
+ string pw_passwd<>; /* encrypted password */
+ int pw_uid; /* user id */
+ int pw_gid; /* group id */
+ string pw_gecos<>; /* in real life name */
+ string pw_dir<>; /* home directory */
+ string pw_shell<>; /* default shell */
+};
+
+struct yppasswd {
+ string oldpass<>; /* unencrypted old password */
+ x_passwd newpw; /* new passwd entry */
+};
+
+
+#ifdef RPC_HDR
+%#include <sys/cdefs.h>
+%extern int _yppasswd __P(( char * , struct x_passwd * ));
+%#define yppasswd(x,y) _yppasswd(x,y)
+#endif
diff --git a/cpukit/librpc/include/rpcsvc/ypupdate_prot.x b/cpukit/librpc/include/rpcsvc/ypupdate_prot.x
new file mode 100644
index 0000000000..f16d5ee45e
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/ypupdate_prot.x
@@ -0,0 +1,88 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+%/*
+% * Copyright (c) 1986, 1990 by Sun Microsystems, Inc.
+% */
+%
+%/* from @(#)ypupdate_prot.x 1.3 91/03/11 TIRPC 1.0 */
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/ypupdate_prot.x,v 1.3 1999/08/27 23:45:13 peter Exp $";
+%#endif
+#endif
+%
+%/*
+% * Compiled from ypupdate_prot.x using rpcgen
+% * This is NOT source code!
+% * DO NOT EDIT THIS FILE!
+% */
+
+/*
+ * YP update service protocol
+ */
+#ifdef RPC_HDR
+%
+%#ifndef _rpcsvc_ypupdate_prot_h
+%#define _rpcsvc_ypupdate_prot_h
+%
+#endif
+
+const MAXMAPNAMELEN = 255;
+const MAXYPDATALEN = 1023;
+const MAXERRMSGLEN = 255;
+
+program YPU_PROG {
+ version YPU_VERS {
+ u_int YPU_CHANGE(ypupdate_args) = 1;
+ u_int YPU_INSERT(ypupdate_args) = 2;
+ u_int YPU_DELETE(ypdelete_args) = 3;
+ u_int YPU_STORE(ypupdate_args) = 4;
+ } = 1;
+} = 100028;
+
+typedef opaque yp_buf<MAXYPDATALEN>;
+
+struct ypupdate_args {
+ string mapname<MAXMAPNAMELEN>;
+ yp_buf key;
+ yp_buf datum;
+};
+
+struct ypdelete_args {
+ string mapname<MAXMAPNAMELEN>;
+ yp_buf key;
+};
+
+#ifdef RPC_HDR
+%
+%#endif /* !_rpcsvc_ypupdate_prot_h */
+#endif
diff --git a/cpukit/librpc/include/rpcsvc/ypxfrd.x b/cpukit/librpc/include/rpcsvc/ypxfrd.x
new file mode 100644
index 0000000000..1845a4f43b
--- /dev/null
+++ b/cpukit/librpc/include/rpcsvc/ypxfrd.x
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 1995, 1996
+ * Bill Paul <wpaul@ctr.columbia.edu>. 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 Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul 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.
+ *
+ * $FreeBSD: src/include/rpcsvc/ypxfrd.x,v 1.7 1999/08/27 23:45:13 peter Exp $
+ */
+
+/*
+ * This protocol definition file describes a file transfer
+ * system used to very quickly move NIS maps from one host to
+ * another. This is similar to what Sun does with their ypxfrd
+ * protocol, but it must be stressed that this protocol is _NOT_
+ * compatible with Sun's. There are a couple of reasons for this:
+ *
+ * 1) Sun's protocol is proprietary. The protocol definition is
+ * not freely available in any of the SunRPC source distributions,
+ * even though the NIS v2 protocol is.
+ *
+ * 2) The idea here is to transfer entire raw files rather than
+ * sending just the records. Sun uses ndbm for its NIS map files,
+ * while FreeBSD uses Berkeley DB. Both are hash databases, but the
+ * formats are incompatible, making it impossible for them to
+ * use each others' files. Even if FreeBSD adopted ndbm for its
+ * database format, FreeBSD/i386 is a little-endian OS and
+ * SunOS/SPARC is big-endian; ndbm is byte-order sensitive and
+ * not very smart about it, which means an attempt to read a
+ * database on a little-endian box that was created on a big-endian
+ * box (or vice-versa) can cause the ndbm code to eat itself.
+ * Luckily, Berkeley DB is able to deal with this situation in
+ * a more graceful manner.
+ *
+ * While the protocol is incompatible, the idea is the same: we just open
+ * up a TCP pipe to the client and transfer the raw map database
+ * from the master server to the slave. This is many times faster than
+ * the standard yppush/ypxfr transfer method since it saves us from
+ * having to recreate the map databases via the DB library each time.
+ * For example: creating a passwd database with 30,000 entries with yp_mkdb
+ * can take a couple of minutes, but to just copy the file takes only a few
+ * seconds.
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/ypxfrd.x,v 1.7 1999/08/27 23:45:13 peter Exp $";
+%#endif /* not lint */
+#endif
+
+/* XXX cribbed from yp.x */
+const _YPMAXRECORD = 1024;
+const _YPMAXDOMAIN = 64;
+const _YPMAXMAP = 64;
+const _YPMAXPEER = 64;
+
+/* Suggested default -- not necesarrily the one used. */
+const YPXFRBLOCK = 32767;
+
+/*
+ * Possible return codes from the remote server.
+ */
+enum xfrstat {
+ XFR_REQUEST_OK = 1, /* Transfer request granted */
+ XFR_DENIED = 2, /* Transfer request denied */
+ XFR_NOFILE = 3, /* Requested map file doesn't exist */
+ XFR_ACCESS = 4, /* File exists, but I couldn't access it */
+ XFR_BADDB = 5, /* File is not a hash database */
+ XFR_READ_OK = 6, /* Block read successfully */
+ XFR_READ_ERR = 7, /* Read error during transfer */
+ XFR_DONE = 8, /* Transfer completed */
+ XFR_DB_ENDIAN_MISMATCH = 9, /* Database byte order mismatch */
+ XFR_DB_TYPE_MISMATCH = 10 /* Database type mismatch */
+};
+
+/*
+ * Database type specifications. The client can use this to ask
+ * the server for a particular type of database or just take whatever
+ * the server has to offer.
+ */
+enum xfr_db_type {
+ XFR_DB_ASCII = 1, /* Flat ASCII text */
+ XFR_DB_BSD_HASH = 2, /* Berkeley DB, hash method */
+ XFR_DB_BSD_BTREE = 3, /* Berkeley DB, btree method */
+ XFR_DB_BSD_RECNO = 4, /* Berkeley DB, recno method */
+ XFR_DB_BSD_MPOOL = 5, /* Berkeley DB, mpool method */
+ XFR_DB_BSD_NDBM = 6, /* Berkeley DB, hash, ndbm compat */
+ XFR_DB_GNU_GDBM = 7, /* GNU GDBM */
+ XFR_DB_DBM = 8, /* Old, deprecated dbm format */
+ XFR_DB_NDBM = 9, /* ndbm format (used by Sun's NISv2) */
+ XFR_DB_OPAQUE = 10, /* Mystery format -- just pass along */
+ XFR_DB_ANY = 11, /* I'll take any format you've got */
+ XFR_DB_UNKNOWN = 12 /* Unknown format */
+};
+
+/*
+ * Machine byte order specification. This allows the client to check
+ * that it's copying a map database from a machine of similar byte sex.
+ * This is necessary for handling database libraries that are fatally
+ * byte order sensitive.
+ *
+ * The XFR_ENDIAN_ANY type is for use with the Berkeley DB database
+ * formats; Berkeley DB is smart enough to make up for byte order
+ * differences, so byte sex isn't important.
+ */
+enum xfr_byte_order {
+ XFR_ENDIAN_BIG = 1, /* We want big endian */
+ XFR_ENDIAN_LITTLE = 2, /* We want little endian */
+ XFR_ENDIAN_ANY = 3 /* We'll take whatever you got */
+};
+
+typedef string xfrdomain<_YPMAXDOMAIN>;
+typedef string xfrmap<_YPMAXMAP>;
+typedef string xfrmap_filename<_YPMAXMAP>; /* actual name of map file */
+
+/*
+ * Ask the remote ypxfrd for a map using this structure.
+ * Note: we supply both a map name and a map file name. These are not
+ * the same thing. In the case of ndbm, maps are stored in two files:
+ * map.bykey.pag and may.bykey.dir. We may also have to deal with
+ * file extensions (on the off chance that the remote server is supporting
+ * multiple DB formats). To handle this, we tell the remote server both
+ * what map we want and, in the case of ndbm, whether we want the .dir
+ * or the .pag part. This name should not be a fully qualified path:
+ * it's up to the remote server to decide which directories to look in.
+ */
+struct ypxfr_mapname {
+ xfrmap xfrmap;
+ xfrdomain xfrdomain;
+ xfrmap_filename xfrmap_filename;
+ xfr_db_type xfr_db_type;
+ xfr_byte_order xfr_byte_order;
+};
+
+/* Read response using this structure. */
+union xfr switch (bool ok) {
+case TRUE:
+ opaque xfrblock_buf<>;
+case FALSE:
+ xfrstat xfrstat;
+};
+
+program YPXFRD_FREEBSD_PROG {
+ version YPXFRD_FREEBSD_VERS {
+ union xfr
+ YPXFRD_GETMAP(ypxfr_mapname) = 1;
+ } = 1;
+} = 600100069; /* 100069 + 60000000 -- 100069 is the Sun ypxfrd prog number */
diff --git a/cpukit/librpc/preinstall.am b/cpukit/librpc/preinstall.am
new file mode 100644
index 0000000000..144db9a51c
--- /dev/null
+++ b/cpukit/librpc/preinstall.am
@@ -0,0 +1,89 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+if LIBRPC
+$(PROJECT_INCLUDE)/rpc/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rpc
+ @: > $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rpc/auth.h: include/rpc/auth.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/auth.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/auth.h
+
+$(PROJECT_INCLUDE)/rpc/auth_unix.h: include/rpc/auth_unix.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/auth_unix.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/auth_unix.h
+
+$(PROJECT_INCLUDE)/rpc/clnt.h: include/rpc/clnt.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/clnt.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/clnt.h
+
+$(PROJECT_INCLUDE)/rpc/clnt_stat.h: include/rpc/clnt_stat.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/clnt_stat.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/clnt_stat.h
+
+$(PROJECT_INCLUDE)/rpc/clnt_soc.h: include/rpc/clnt_soc.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/clnt_soc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/clnt_soc.h
+
+$(PROJECT_INCLUDE)/rpc/svc.h: include/rpc/svc.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/svc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/svc.h
+
+$(PROJECT_INCLUDE)/rpc/svc_auth.h: include/rpc/svc_auth.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/svc_auth.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/svc_auth.h
+
+$(PROJECT_INCLUDE)/rpc/svc_soc.h: include/rpc/svc_soc.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/svc_soc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/svc_soc.h
+
+$(PROJECT_INCLUDE)/rpc/pmap_clnt.h: include/rpc/pmap_clnt.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/pmap_clnt.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/pmap_clnt.h
+
+$(PROJECT_INCLUDE)/rpc/pmap_prot.h: include/rpc/pmap_prot.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/pmap_prot.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/pmap_prot.h
+
+$(PROJECT_INCLUDE)/rpc/pmap_rmt.h: include/rpc/pmap_rmt.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/pmap_rmt.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/pmap_rmt.h
+
+$(PROJECT_INCLUDE)/rpc/rpc.h: include/rpc/rpc.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/rpc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/rpc.h
+
+$(PROJECT_INCLUDE)/rpc/types.h: include/rpc/types.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/types.h
+
+$(PROJECT_INCLUDE)/rpc/xdr.h: include/rpc/xdr.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/xdr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/xdr.h
+
+$(PROJECT_INCLUDE)/rpc/rpc_com.h: include/rpc/rpc_com.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/rpc_com.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/rpc_com.h
+
+$(PROJECT_INCLUDE)/rpc/rpc_msg.h: include/rpc/rpc_msg.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/rpc_msg.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/rpc_msg.h
+
+$(PROJECT_INCLUDE)/rpc/rpcent.h: include/rpc/rpcent.h $(PROJECT_INCLUDE)/rpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rpc/rpcent.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc/rpcent.h
+endif
diff --git a/cpukit/librpc/src/rpc/DISCLAIMER b/cpukit/librpc/src/rpc/DISCLAIMER
new file mode 100644
index 0000000000..1a66d5f4c9
--- /dev/null
+++ b/cpukit/librpc/src/rpc/DISCLAIMER
@@ -0,0 +1,28 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
diff --git a/cpukit/librpc/src/rpc/README b/cpukit/librpc/src/rpc/README
new file mode 100644
index 0000000000..ad9d70f990
--- /dev/null
+++ b/cpukit/librpc/src/rpc/README
@@ -0,0 +1,233 @@
+RPCSRC 4.0 7/11/89
+
+This distribution contains Sun Microsystem's implementation of the
+RPC and XDR protocols and is compatible with 4.2BSD and 4.3BSD. Also
+included is complete documentation, utilities, RPC service
+specification files, and demonstration services in the format used by
+the RPC protocol compiler (rpcgen). See WHAT'S NEW below for
+details.
+
+NOTE ABOUT SECURE RPC:
+
+This release of RPCSRC contains most of the code needed to implement
+Secure RPC (see "DES Authentication" in the RPC Protocol Specification,
+doc/rpc.rfc.ms). Due to legal considerations, we are unable to
+distribute an implementation of DES, the Data Encryption Standard, which
+Secure RPC requires. For this reason, all of the files, documentation, and
+programs associated with Secure RPC have been placed into a separate
+directory, secure_rpc. The RPC library contained in the main body of this
+release *DOES NOT* support Secure RPC. See secure_rpc/README for more
+details. (A DES library was posted in Volume 18 of comp.sources.unix.)
+
+If you wish to report bugs found in this release, send mail to:
+
+Portable ONC/NFS
+Sun Microsystems, Inc
+MS 12-33
+2550 Garcia Avenue
+Mountain View, CA 94043
+
+or send Email to nfsnet@sun.com (the Internet) or sun!nfsnet (Usenet).
+
+ROADMAP
+
+The directory hierarchy is as follows:
+
+ demo/ Various demonstration services
+ demo/dir Remote directory lister
+ demo/msg Remote console message delivery service
+ demo/sort Remote sort service
+
+ doc/ Documentation for RPC, XDR and NFS in "-ms" format.
+
+ etc/ Utilities (rpcinfo and portmap). portmap must be
+ started by root before any other RPC network services are
+ used. SEE BELOW FOR BUGFIX TO 4.3BSD COMPILER.
+
+ man/ Manual pages for RPC library, rpcgen, and utilities.
+
+ rpc/ The RPC and XDR library. SEE BELOW
+ FOR BUGFIX TO 4.2BSD COMPILER.
+
+ rpcgen/ The RPC Language compiler (for .x files)
+
+ rpcsvc/ Service definition files for various services and the
+ server and client code for the Remote Status service.
+
+ secure_rpc/ The files in this directory are used to build a version of
+ the RPC library with DES Authentication. See the README
+ file in that directory for more details.
+
+BUILD INSTRUCTIONS
+
+Makefiles can be found in all directories except for man. The
+Makefile in the top directory will cause these others to be invoked
+(except for in the doc, man and demo directories), in turn building the
+entire release.
+
+WARNING! THE DEFAULT INSTALLATION PROCEDURES WILL INSTALL FILES
+IN /usr/include, /usr/lib, /usr/bin and /etc.
+
+The master RPC include file, rpc/rpc.h, is used by all programs and
+routines that use RPC. It includes other RPC and system include files
+needed by the RPC system. PLEASE NOTE: If your system has NFS, it
+may have been based on Sun's NFS Source. The include files installed
+by this package may duplicate include files you will find on your NFS
+system. The RPCSRC 4.0 include files are upwardly compatible to all
+NFS Source include files as of the date of this distribution (not
+including any new definitions or declarations added by your system
+vendor). HOWEVER: Please read the comments towards the end of
+rpc/rpc.h regarding rpc/netdb.h. You may need to uncomment the
+inclusion of that file if the structures it defines are already
+defined by your system's include files.
+
+After making any compiler fixes that are needed (see below), at
+the top directory, type:
+
+ make install
+
+For all installations, the Makefile macro DESTDIR is prepended to the
+installation path. It is defined to be null in the Makefiles, so
+installations are relative to root. (You will probably need root
+privileges for installing the files under the default path.) To
+install the files under some other tree (e.g., /usr/local), use the
+command:
+
+ make install DESTDIR=/usr/local
+
+This will place the include files in /usr/local/usr/include, the RPC
+library in /usr/local/usr/lib, rpcgen in /usr/local/usr/bin, and the
+utilities in /usr/local/etc. You'll have to edit the Makefiles or
+install the files by hand if you want to do anything other than this
+kind of relocation of the installation tree.
+
+The RPC library will be built and installed first. By default it is
+installed in /usr/lib as "librpclib.a". The directory
+/usr/include/rpc will also be created, and several header files will
+be installed there. ALL RPC SERVICES INCLUDE THESE HEADER FILES.
+
+The programs in etc/ link in routines from librpclib.a. If you change
+where it is installed, be sure to edit etc/'s Makefile to reflect this.
+These programs are installed in /etc. PORTMAP MUST BE RUNNING ON
+YOUR SYSTEM BEFORE YOU START ANY OTHER RPC SERVICE.
+
+rpcgen is installed in /usr/bin. This program is required to build
+the demonstration services in demo and the rstat client and server in
+rpcsvc/.
+
+The rpcsvc/ directory will install its files in the directory
+/usr/include/rpcsvc. The Remote Status service (rstat_svc) will be
+compiled and installed in /etc. If you wish to make this service
+available, you should either start this service when needed or have
+it started at boot time by invoking it in your /etc/rc.local script.
+(Be sure that portmap is started first!) Sun has modified its
+version of inetd to automatically start RPC services. (Use "make
+LIB=" when building rstat on a Sun Workstation.) The Remote Status
+client (rstat) will be installed in /usr/bin. This program queries
+the rstat_svc on a remote host and prints a system status summary
+similar to the one printed by "uptime".
+
+The documentation is not built during the "make install" command.
+Typing "make" in the doc directory will cause all of the manuals to
+be formatted using nroff into a single file. We have had a report
+that certain "troff" equivalents have trouble processing the full
+manual. If you have trouble, try building the manuals individually
+(see the Makefile).
+
+The demonstration services in the demo directory are not built by the
+top-level "make install" command. To build these, cd to the demo
+directory and enter "make". The three services will be built.
+RPCGEN MUST BE INSTALLED in a path that make can find. To run the
+services, start the portmap program as root and invoke the service
+(you probably will want to put it in the background). rpcinfo can be
+used to check that the service succeeded in getting registered with
+portmap, and to ping the service (see rpcinfo's man page). You can
+then use the corresponding client program to exercise the service.
+To build these services on a Sun workstation, you must prevent the
+Makefile from trying to link the RPC library (as these routines are
+already a part of Sun's libc). Use: "make LIB=".
+
+BUGFIX FOR 4.3BSD COMPILER
+
+The use of a 'void *' declaration for one of the arguments in
+the reply_proc() procedure in etc/rpcinfo.c will trigger a bug
+in the 4.3BSD compiler. The bug is fixed by the following change to
+the compiler file mip/manifest.h:
+
+*** manifest.h.r1.1 Thu Apr 30 13:52:25 1987
+--- manifest.h.r1.2 Mon Nov 23 18:58:17 1987
+***************
+*** 21,27 ****
+ /*
+ * Bogus type values
+ */
+! #define TNULL PTR /* pointer to UNDEF */
+ #define TVOID FTN /* function returning UNDEF (for void) */
+
+ /*
+--- 21,27 ----
+ /*
+ * Bogus type values
+ */
+! #define TNULL INCREF(MOETY) /* pointer to MOETY -- impossible type */
+ #define TVOID FTN /* function returning UNDEF (for void) */
+
+ /*
+
+If you cannot fix your compiler, change the declaration in reply_proc()
+from 'void *' to 'char *'.
+
+BUGFIX FOR 4.2BSD COMPILER
+
+Unpatched 4.2BSD compilers complain about valid C. You can make old
+compilers happy by changing some voids to ints. However, the fix to
+the 4.2 VAX compiler is as follows (to mip/trees.c):
+
+*** trees.c.r1.1 Mon May 11 13:47:58 1987
+--- trees.c.r1.2 Wed Jul 2 18:28:52 1986
+***************
+*** 1247,1253 ****
+ if(o==CAST && mt1==0)return(TYPL+TYMATCH);
+ if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
+ else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );
+! else if( mt12 == 0 ) break;
+ else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );
+ else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
+ break;
+--- 1261,1269 ----
+ if(o==CAST && mt1==0)return(TYPL+TYMATCH);
+ if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
+ else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );
+! /* if right is TVOID and looks like a CALL, is not ok */
+! else if (mt2 == 0 && (p->in.right->in.op == CALL || p->in.right->in.op == UNARY CALL))
+! break;
+ else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );
+ else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
+ break;
+
+WHAT'S NEW IN THIS RELEASE: RPCSRC 4.0
+
+The previous release was RPCSRC 3.9. As with all previous releases,
+this release is based directly on files from Sun Microsystem's
+implementation.
+
+Upgrade from RPCSRC 3.9
+
+1) RPCSRC 4.0 upgrades RPCSRC 3.9. Improvements from SunOS 4.0 have
+ been integrated into this release.
+
+Secure RPC (in the secure_rpc/ directory)
+
+2) DES Authentication routines and programs are provided.
+3) A new manual, "Secure NFS" is provided, which describes Secure RPC
+ and Secure NFS.
+4) Skeleton routines and manual pages are provided which describe the
+ DES encryption procedures required by Secure RPC. HOWEVER, NO DES
+ ROUTINE IS PROVIDED.
+
+New Functionality
+
+5) rpcinfo can now be used to de-register services from the portmapper
+ which may have terminated abnormally.
+6) A new client, rstat, is provided which queries the rstat_svc and
+ prints a status line similar to the one displayed by "uptime".
diff --git a/cpukit/librpc/src/rpc/auth_none.c b/cpukit/librpc/src/rpc/auth_none.c
new file mode 100644
index 0000000000..3dc05e81c3
--- /dev/null
+++ b/cpukit/librpc/src/rpc/auth_none.c
@@ -0,0 +1,134 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/auth_none.c,v 1.9 1999/08/28 00:00:32 peter Exp $";
+#endif
+
+/*
+ * auth_none.c
+ * Creates a client authentication handle for passing "null"
+ * credentials and verifiers to remote systems.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdlib.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#define MAX_MARSHAL_SIZE 20
+
+/*
+ * Authenticator operations routines
+ */
+static void authnone_verf(AUTH*);
+static void authnone_destroy(AUTH*);
+static bool_t authnone_marshal(AUTH*, XDR*);
+static bool_t authnone_validate(AUTH*, struct opaque_auth *);
+static bool_t authnone_refresh(AUTH*);
+
+static struct auth_ops ops = {
+ authnone_verf,
+ authnone_marshal,
+ authnone_validate,
+ authnone_refresh,
+ authnone_destroy
+};
+
+static struct authnone_private {
+ AUTH no_client;
+ char marshalled_client[MAX_MARSHAL_SIZE];
+ u_int mcnt;
+} *authnone_private;
+
+AUTH *
+authnone_create()
+{
+ struct authnone_private *ap = authnone_private;
+ XDR xdr_stream;
+ XDR *xdrs;
+
+ if (ap == 0) {
+ ap = (struct authnone_private *)calloc(1, sizeof (*ap));
+ if (ap == 0)
+ return (0);
+ authnone_private = ap;
+ }
+ if (!ap->mcnt) {
+ ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
+ ap->no_client.ah_ops = &ops;
+ xdrs = &xdr_stream;
+ xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHAL_SIZE,
+ XDR_ENCODE);
+ (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
+ (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
+ ap->mcnt = XDR_GETPOS(xdrs);
+ XDR_DESTROY(xdrs);
+ }
+ return (&ap->no_client);
+}
+
+/*ARGSUSED*/
+static bool_t
+authnone_marshal(AUTH *client, XDR *xdrs)
+{
+ struct authnone_private *ap = authnone_private;
+
+ if (ap == 0)
+ return (0);
+ return ((*xdrs->x_ops->x_putbytes)(xdrs,
+ ap->marshalled_client, ap->mcnt));
+}
+
+static void
+authnone_verf(AUTH *client)
+{
+}
+
+static bool_t
+authnone_validate(AUTH *client, struct opaque_auth *opaque)
+{
+
+ return (TRUE);
+}
+
+static bool_t
+authnone_refresh(AUTH *client)
+{
+
+ return (FALSE);
+}
+
+static void
+authnone_destroy(AUTH *client)
+{
+}
diff --git a/cpukit/librpc/src/rpc/auth_unix.c b/cpukit/librpc/src/rpc/auth_unix.c
new file mode 100644
index 0000000000..279822942a
--- /dev/null
+++ b/cpukit/librpc/src/rpc/auth_unix.c
@@ -0,0 +1,341 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/auth_unix.c,v 1.12 1999/12/29 05:04:16 peter Exp $";
+#endif
+
+/*
+ * auth_unix.c, Implements UNIX style authentication parameters.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The system is very weak. The client uses no encryption for it's
+ * credentials and only sends null verifiers. The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * Unix authenticator operations vector
+ */
+static void authunix_nextverf(AUTH*);
+static bool_t authunix_marshal(AUTH*, XDR*);
+static bool_t authunix_validate(AUTH*, struct opaque_auth *);
+static bool_t authunix_refresh(AUTH*);
+static void authunix_destroy(AUTH*);
+
+static struct auth_ops auth_unix_ops = {
+ authunix_nextverf,
+ authunix_marshal,
+ authunix_validate,
+ authunix_refresh,
+ authunix_destroy
+};
+
+/*
+ * This struct is pointed to by the ah_private field of an auth_handle.
+ */
+struct audata {
+ struct opaque_auth au_origcred; /* original credentials */
+ struct opaque_auth au_shcred; /* short hand cred */
+ u_long au_shfaults; /* short hand cache faults */
+ char au_marshed[MAX_AUTH_BYTES];
+ u_int au_mpos; /* xdr pos at end of marshed */
+};
+#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
+
+static void marshal_new_auth();
+
+/*
+ * This goop is here because some servers refuse to accept a
+ * credential with more than some number (usually 8) supplementary
+ * groups. Blargh!
+ */
+static int authunix_maxgrouplist = 0;
+
+void
+set_rpc_maxgrouplist(int num)
+{
+ authunix_maxgrouplist = num;
+}
+
+/*
+ * Create a unix style authenticator.
+ * Returns an auth handle with the given stuff in it.
+ */
+AUTH *
+authunix_create(machname, uid, gid, len, aup_gids)
+ char *machname;
+ int uid;
+ int gid;
+ int len;
+ int *aup_gids;
+{
+ struct authunix_parms aup;
+ char mymem[MAX_AUTH_BYTES];
+ struct timeval now;
+ XDR xdrs;
+ register AUTH *auth;
+ register struct audata *au;
+
+ /*
+ * Allocate and set up auth handle
+ */
+ auth = (AUTH *)mem_alloc(sizeof(*auth));
+#ifndef _KERNEL
+ if (auth == NULL) {
+ (void)fprintf(stderr, "authunix_create: out of memory\n");
+ return (NULL);
+ }
+#endif
+ au = (struct audata *)mem_alloc(sizeof(*au));
+#ifndef _KERNEL
+ if (au == NULL) {
+ (void)fprintf(stderr, "authunix_create: out of memory\n");
+ return (NULL);
+ }
+#endif
+ auth->ah_ops = &auth_unix_ops;
+ auth->ah_private = (caddr_t)au;
+ auth->ah_verf = au->au_shcred = _null_auth;
+ au->au_shfaults = 0;
+
+ /*
+ * fill in param struct from the given params
+ */
+ (void)gettimeofday(&now, (struct timezone *)0);
+ aup.aup_time = now.tv_sec;
+ aup.aup_machname = machname;
+ aup.aup_uid = uid;
+ aup.aup_gid = gid;
+ /* GW: continuation of max group list hack */
+ if(authunix_maxgrouplist != 0) {
+ aup.aup_len = ((len < authunix_maxgrouplist) ? len
+ : authunix_maxgrouplist);
+ } else {
+ aup.aup_len = (u_int)len;
+ }
+ aup.aup_gids = aup_gids;
+
+ /*
+ * Serialize the parameters into origcred
+ */
+ xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
+ if (! xdr_authunix_parms(&xdrs, &aup))
+ abort();
+ au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
+ au->au_origcred.oa_flavor = AUTH_UNIX;
+#ifdef _KERNEL
+ au->au_origcred.oa_base = mem_alloc((u_int) len);
+#else
+ if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
+ (void)fprintf(stderr, "authunix_create: out of memory\n");
+ return (NULL);
+ }
+#endif
+ memcpy(au->au_origcred.oa_base, mymem, (u_int)len);
+
+ /*
+ * set auth handle to reflect new cred.
+ */
+ auth->ah_cred = au->au_origcred;
+ marshal_new_auth(auth);
+ return (auth);
+}
+
+/*
+ * Returns an auth handle with parameters determined by doing lots of
+ * syscalls.
+ */
+AUTH *
+authunix_create_default()
+{
+ register int len;
+ char machname[MAX_MACHINE_NAME + 1];
+ register int uid;
+ register int gid;
+ int gids[NGRPS];
+ int i;
+ gid_t real_gids[NGROUPS];
+
+ if (gethostname(machname, MAX_MACHINE_NAME) == -1)
+ abort();
+ machname[MAX_MACHINE_NAME] = 0;
+ uid = (int)geteuid();
+ gid = (int)getegid();
+ if ((len = getgroups(NGROUPS, real_gids)) < 0)
+ abort();
+ if(len > NGRPS) len = NGRPS; /* GW: turn `gid_t's into `int's */
+ for(i = 0; i < len; i++) {
+ gids[i] = (int)real_gids[i];
+ }
+ return (authunix_create(machname, uid, gid, len, gids));
+}
+
+/*
+ * authunix operations
+ */
+
+static void
+authunix_nextverf(AUTH *auth)
+{
+ /* no action necessary */
+}
+
+static bool_t
+authunix_marshal(AUTH *auth, XDR *xdrs)
+{
+ struct audata *au = AUTH_PRIVATE(auth);
+
+ return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
+}
+
+static bool_t
+authunix_validate( AUTH *auth, struct opaque_auth *verf )
+{
+ register struct audata *au;
+ XDR xdrs;
+
+ if (verf->oa_flavor == AUTH_SHORT) {
+ au = AUTH_PRIVATE(auth);
+ xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, XDR_DECODE);
+
+ if (au->au_shcred.oa_base != NULL) {
+ mem_free(au->au_shcred.oa_base,
+ au->au_shcred.oa_length);
+ au->au_shcred.oa_base = NULL;
+ }
+ if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
+ auth->ah_cred = au->au_shcred;
+ } else {
+ xdrs.x_op = XDR_FREE;
+ (void)xdr_opaque_auth(&xdrs, &au->au_shcred);
+ au->au_shcred.oa_base = NULL;
+ auth->ah_cred = au->au_origcred;
+ }
+ marshal_new_auth(auth);
+ }
+ return (TRUE);
+}
+
+static bool_t
+authunix_refresh(AUTH *auth)
+{
+ struct audata *au = AUTH_PRIVATE(auth);
+ struct authunix_parms aup;
+ struct timeval now;
+ XDR xdrs;
+ int stat;
+
+ if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
+ /* there is no hope. Punt */
+ return (FALSE);
+ }
+ au->au_shfaults ++;
+
+ /* first deserialize the creds back into a struct authunix_parms */
+ aup.aup_machname = NULL;
+ aup.aup_gids = (int *)NULL;
+ xdrmem_create(&xdrs, au->au_origcred.oa_base,
+ au->au_origcred.oa_length, XDR_DECODE);
+ stat = xdr_authunix_parms(&xdrs, &aup);
+ if (! stat)
+ goto done;
+
+ /* update the time and serialize in place */
+ (void)gettimeofday(&now, (struct timezone *)0);
+ aup.aup_time = now.tv_sec;
+ xdrs.x_op = XDR_ENCODE;
+ XDR_SETPOS(&xdrs, 0);
+ stat = xdr_authunix_parms(&xdrs, &aup);
+ if (! stat)
+ goto done;
+ auth->ah_cred = au->au_origcred;
+ marshal_new_auth(auth);
+done:
+ /* free the struct authunix_parms created by deserializing */
+ xdrs.x_op = XDR_FREE;
+ (void)xdr_authunix_parms(&xdrs, &aup);
+ XDR_DESTROY(&xdrs);
+ return (stat);
+}
+
+static void
+authunix_destroy(AUTH *auth)
+{
+ struct audata *au = AUTH_PRIVATE(auth);
+
+ mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
+
+ if (au->au_shcred.oa_base != NULL)
+ mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
+
+ mem_free(auth->ah_private, sizeof(struct audata));
+
+ if (auth->ah_verf.oa_base != NULL)
+ mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
+
+ mem_free((caddr_t)auth, sizeof(*auth));
+}
+
+/*
+ * Marshals (pre-serializes) an auth struct.
+ * sets private data, au_marshed and au_mpos
+ */
+static void
+marshal_new_auth(AUTH *auth)
+{
+ XDR xdr_stream;
+ XDR *xdrs = &xdr_stream;
+ struct audata *au = AUTH_PRIVATE(auth);
+
+ xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
+ if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
+ (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
+ perror("auth_none.c - Fatal marshalling problem");
+ } else {
+ au->au_mpos = XDR_GETPOS(xdrs);
+ }
+ XDR_DESTROY(xdrs);
+}
diff --git a/cpukit/librpc/src/rpc/authunix_prot.c b/cpukit/librpc/src/rpc/authunix_prot.c
new file mode 100644
index 0000000000..e6e91f5396
--- /dev/null
+++ b/cpukit/librpc/src/rpc/authunix_prot.c
@@ -0,0 +1,67 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/authunix_prot.c,v 1.6 1999/08/28 00:00:33 peter Exp $";
+#endif
+
+/*
+ * authunix_prot.c
+ * XDR for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * XDR for unix authentication parameters.
+ */
+bool_t
+xdr_authunix_parms(xdrs, p)
+ register XDR *xdrs;
+ register struct authunix_parms *p;
+{
+
+ if (xdr_u_long(xdrs, &(p->aup_time))
+ && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
+ && xdr_int(xdrs, &(p->aup_uid))
+ && xdr_int(xdrs, &(p->aup_gid))
+ && xdr_array(xdrs, (caddr_t *)&(p->aup_gids),
+ &(p->aup_len), NGRPS, sizeof(int), (xdrproc_t) xdr_int) ) {
+ return (TRUE);
+ }
+ return (FALSE);
+}
diff --git a/cpukit/librpc/src/rpc/bindresvport.3 b/cpukit/librpc/src/rpc/bindresvport.3
new file mode 100644
index 0000000000..02a079decc
--- /dev/null
+++ b/cpukit/librpc/src/rpc/bindresvport.3
@@ -0,0 +1,106 @@
+.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI
+.\" $FreeBSD: src/lib/libc/rpc/bindresvport.3,v 1.10 2000/01/27 02:55:01 bde Exp $
+.\"
+.Dd January 27, 2000
+.Dt BINDRESVPORT 3
+.Os
+.Sh NAME
+.Nm bindresvport ,
+.Nm bindresvport_sa
+.Ndbind a socket to a privileged IP port
+.Sh SYNOPSIS
+.Fd #include <rpc/rpc.h>
+.Ft int
+.Fn bindresvport "int sd" "struct sockaddr_in *sin"
+.Ft int
+.Fn bindresvport_sa "int sd" "struct sockaddr *sa"
+.Sh DESCRIPTION
+.Fn bindresvport
+and
+.Fn bindresvport_sa
+are used to bind a socket descriptor to a privileged
+.Tn IP
+port, that is, a
+port number in the range 0-1023.
+.Pp
+Only root can bind to a privileged port; this call will fail for any
+other users.
+.Pp
+When
+.Va sin
+is not null,
+.Va sin->sin_family
+must be initialized to the address family of the socket, passed by
+.Va sd .
+If the value of sin->sin_port is non-zero
+.Fn bindresvport
+will attempt to use that specific port. If it fails, it chooses another
+privileged port automatically.
+.Pp
+It is legal to pass null pointer to
+.Va sin .
+In this case, the caller cannot get the port number
+.Fn bindresvport
+has picked.
+.Pp
+Function prototype of
+.Fn bindresvport
+is biased to
+.Dv AF_INET
+socket.
+.Fn bindresvport_sa
+acts exactly the same, with more neutral function prototype.
+Note that both functions behave exactly the same, and
+both support
+.Dv AF_INET6
+sockets as well as
+.Dv AF_INET
+sockets.
+.Sh RETURN VALUES
+.Fn bindresvport
+and
+.Fn bindresvport_sa
+return 0 if they are successful, otherwise \-1 is returned and
+.Va errno
+set to reflect the cause of the error.
+.Sh ERRORS
+The
+.Fn bindresvport
+and
+.Fn bindresvport_sa
+functions fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa sd
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+.Fa sd
+is not a socket.
+.It Bq Er EADDRNOTAVAIL
+The specified address is not available from the local machine.
+.It Bq Er EADDRINUSE
+The specified address is already in use.
+.It Bq Er EINVAL
+The socket is already bound to an address,
+or the socket family and the family of specified address mismatch.
+.It Bq Er EACCES
+The requested address is protected, and the current user
+has inadequate permission to access it.
+.It Bq Er EFAULT
+The
+.Fa name
+parameter is not in a valid part of the user
+address space.
+.It Bq Er ENOBUFS
+Insufficient resources were available in the system
+to perform the operation.
+.It Bq Er EPFNOSUPPORT
+The protocol family has not been configured into the
+system, no implementation for it exists,
+or address family did not match between arguments.
+.El
+.Sh "SEE ALSO"
+.Xr bind 2 ,
+.Xr socket 2 ,
+.Xr rresvport 3 ,
+.Xr rresvport_af 3
diff --git a/cpukit/librpc/src/rpc/bindresvport.c b/cpukit/librpc/src/rpc/bindresvport.c
new file mode 100644
index 0000000000..e987d77f7b
--- /dev/null
+++ b/cpukit/librpc/src/rpc/bindresvport.c
@@ -0,0 +1,156 @@
+/* $NetBSD: bindresvport.c,v 1.19 2000/07/06 03:03:59 christos Exp $ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)bindresvport.c 1.8 88/02/08 SMI";*/
+/*static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";*/
+/*from: OpenBSD: bindresvport.c,v 1.7 1996/07/30 16:25:47 downsj Exp */
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/bindresvport.c,v 1.12 2000/01/26 09:02:42 shin Exp $";
+#endif
+
+/*
+ * Copyright (c) 1987 by Sun Microsystems, Inc.
+ *
+ * Portions Copyright(C) 1996, Jason Downs. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rpc/rpc.h>
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+int
+bindresvport(sd, sin)
+ int sd;
+ struct sockaddr_in *sin;
+{
+ return bindresvport_sa(sd, (struct sockaddr *)sin);
+}
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+int
+bindresvport_sa(sd, sa)
+ int sd;
+ struct sockaddr *sa;
+{
+ int old, error, af;
+ struct sockaddr myaddr;
+ struct sockaddr_in *sin;
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+#endif
+ int proto, portrange, portlow;
+ u_int16_t port;
+ socklen_t salen;
+
+ if (sa == NULL) {
+ salen = sizeof(myaddr);
+ sa = (struct sockaddr *)&myaddr;
+
+ if (getsockname(sd, sa, &salen) == -1)
+ return -1; /* errno is correctly set */
+
+ af = sa->sa_family;
+ memset(&myaddr, 0, salen);
+ } else
+ af = sa->sa_family;
+
+ switch (af) {
+ case AF_INET:
+ proto = IPPROTO_IP;
+ portrange = IP_PORTRANGE;
+ portlow = IP_PORTRANGE_LOW;
+ sin = (struct sockaddr_in *)sa;
+ salen = sizeof(struct sockaddr_in);
+ port = sin->sin_port;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ proto = IPPROTO_IPV6;
+ portrange = IPV6_PORTRANGE;
+ portlow = IPV6_PORTRANGE_LOW;
+ sin6 = (struct sockaddr_in6 *)sa;
+ salen = sizeof(struct sockaddr_in6);
+ port = sin6->sin6_port;
+ break;
+#endif
+ default:
+ errno = EPFNOSUPPORT;
+ return (-1);
+ }
+ sa->sa_family = af;
+ sa->sa_len = salen;
+
+ if (port == 0) {
+ socklen_t oldlen = sizeof(old);
+
+ error = getsockopt(sd, proto, portrange, &old, &oldlen);
+ if (error < 0)
+ return (error);
+
+ error = setsockopt(sd, proto, portrange, &portlow,
+ sizeof(portlow));
+ if (error < 0)
+ return (error);
+ }
+
+ error = bind(sd, sa, salen);
+
+ if (port == 0) {
+ int saved_errno = errno;
+
+ if (error) {
+ if (setsockopt(sd, proto, portrange, &old,
+ sizeof(old)) < 0)
+ errno = saved_errno;
+ return (error);
+ }
+
+ if (sa != (struct sockaddr *)&myaddr) {
+ /* Hmm, what did the kernel assign? */
+ if (getsockname(sd, sa, &salen) < 0)
+ errno = saved_errno;
+ return (error);
+ }
+ }
+ return (error);
+}
diff --git a/cpukit/librpc/src/rpc/clnt_generic.c b/cpukit/librpc/src/rpc/clnt_generic.c
new file mode 100644
index 0000000000..d387fae4c0
--- /dev/null
+++ b/cpukit/librpc/src/rpc/clnt_generic.c
@@ -0,0 +1,141 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";*/
+/*static char *sccsid = "from: @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_generic.c,v 1.9 1999/08/28 00:00:35 peter Exp $";
+#endif
+
+/*
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netdb.h>
+#include <string.h>
+
+/*
+ * Generic client creation: takes (hostname, program-number, protocol) and
+ * returns client handle. Default options are set, which the user can
+ * change using the rpc equivalent of ioctl()'s.
+ */
+CLIENT *
+clnt_create(hostname, prog, vers, proto)
+ char *hostname;
+ u_long prog;
+ u_long vers;
+ char *proto;
+{
+ struct hostent *h;
+ struct protoent *p;
+ struct sockaddr_in sin;
+#ifndef __rtems__
+ struct sockaddr_un sun;
+#endif
+ int sock;
+ struct timeval tv;
+ CLIENT *client;
+
+#ifndef __rtems__
+ if (!strcmp(proto, "unix")) {
+ bzero((char *)&sun, sizeof(sun));
+ sun.sun_family = AF_UNIX;
+ strcpy(sun.sun_path, hostname);
+ sun.sun_len = sizeof(sun.sun_len) + sizeof(sun.sun_family) +
+ strlen(sun.sun_path) + 1;
+ sock = RPC_ANYSOCK;
+ client = clntunix_create(&sun, prog, vers, &sock, 0, 0);
+ if (client == NULL)
+ return(NULL);
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control(client, CLSET_TIMEOUT, &tv);
+ return(client);
+ }
+#endif
+
+ h = gethostbyname(hostname);
+ if (h == NULL) {
+ rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
+ return (NULL);
+ }
+ if (h->h_addrtype != AF_INET) {
+ /*
+ * Only support INET for now
+ */
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(struct sockaddr_in);
+ sin.sin_family = h->h_addrtype;
+ sin.sin_port = 0;
+ memcpy((char*)&sin.sin_addr, h->h_addr, h->h_length);
+ p = getprotobyname(proto);
+ if (p == NULL) {
+ rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
+ rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
+ return (NULL);
+ }
+ sock = RPC_ANYSOCK;
+ switch (p->p_proto) {
+ case IPPROTO_UDP:
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+ client = clntudp_create(&sin, prog, vers, tv, &sock);
+ if (client == NULL) {
+ return (NULL);
+ }
+#if 0 /* XXX do we need this? */
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control(client, CLSET_TIMEOUT, &tv);
+#endif
+ break;
+ case IPPROTO_TCP:
+ client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
+ if (client == NULL) {
+ return (NULL);
+ }
+#if 0 /* XXX do we need this? */
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control(client, CLSET_TIMEOUT, &tv);
+#endif
+ break;
+ default:
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
+ return (NULL);
+ }
+ return (client);
+}
diff --git a/cpukit/librpc/src/rpc/clnt_perror.c b/cpukit/librpc/src/rpc/clnt_perror.c
new file mode 100644
index 0000000000..967f8d1d7c
--- /dev/null
+++ b/cpukit/librpc/src/rpc/clnt_perror.c
@@ -0,0 +1,254 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_perror.c,v 1.11 1999/08/28 00:00:35 peter Exp $";
+#endif
+
+/*
+ * clnt_perror.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/clnt.h>
+
+static char *auth_errmsg();
+#define CLNT_PERROR_BUFLEN 256
+
+#define buf (rtems_rpc_task_variables->clnt_perror_buf)
+
+static char *
+_buf()
+{
+
+ if (buf == 0)
+ buf = (char *)malloc(CLNT_PERROR_BUFLEN);
+ return (buf);
+}
+
+/*
+ * Print reply error info
+ */
+char *
+clnt_sperror(rpch, s)
+ CLIENT *rpch;
+ const char *s;
+{
+ struct rpc_err e;
+ char *err;
+ char *str = _buf();
+ char *strstart = str;
+
+ if (str == 0)
+ return (0);
+ CLNT_GETERR(rpch, &e);
+
+ (void) sprintf(str, "%s: %s", s, clnt_sperrno(e.re_status));
+ str += strlen(str);
+
+ switch (e.re_status) {
+ case RPC_SUCCESS:
+ case RPC_CANTENCODEARGS:
+ case RPC_CANTDECODERES:
+ case RPC_TIMEDOUT:
+ case RPC_PROGUNAVAIL:
+ case RPC_PROCUNAVAIL:
+ case RPC_CANTDECODEARGS:
+ case RPC_SYSTEMERROR:
+ case RPC_UNKNOWNHOST:
+ case RPC_UNKNOWNPROTO:
+ case RPC_PMAPFAILURE:
+ case RPC_PROGNOTREGISTERED:
+ case RPC_FAILED:
+ break;
+
+ case RPC_CANTSEND:
+ case RPC_CANTRECV:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN - (str - strstart),
+ "; errno = %s\n", strerror(e.re_errno));
+ break;
+
+ case RPC_VERSMISMATCH:
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu\n",
+ (u_long)e.re_vers.low, (u_long)e.re_vers.high);
+ break;
+
+ case RPC_AUTHERROR:
+ err = auth_errmsg(e.re_why);
+ (void) sprintf(str,"; why = ");
+ str += strlen(str);
+ if (err != NULL) {
+ (void) sprintf(str, "%s\n",err);
+ } else {
+ (void) sprintf(str,
+ "(unknown authentication error - %d)\n",
+ (int) e.re_why);
+ }
+ break;
+
+ case RPC_PROGVERSMISMATCH:
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu\n",
+ (u_long)e.re_vers.low, (u_long)e.re_vers.high);
+ break;
+
+ default: /* unknown */
+ (void) sprintf(str,
+ "; s1 = %lu, s2 = %lu\n",
+ (long)e.re_lb.s1, (long)e.re_lb.s2);
+ break;
+ }
+ strstart[CLNT_PERROR_BUFLEN-2] = '\n';
+ strstart[CLNT_PERROR_BUFLEN-1] = '\0';
+ return(strstart) ;
+}
+
+void
+clnt_perror(rpch, s)
+ CLIENT *rpch;
+ const char *s;
+{
+ (void) fprintf(stderr,"%s\n",clnt_sperror(rpch,s));
+}
+
+
+static const char *const rpc_errlist[] = {
+ "RPC: Success", /* 0 - RPC_SUCCESS */
+ "RPC: Can't encode arguments", /* 1 - RPC_CANTENCODEARGS */
+ "RPC: Can't decode result", /* 2 - RPC_CANTDECODERES */
+ "RPC: Unable to send", /* 3 - RPC_CANTSEND */
+ "RPC: Unable to receive", /* 4 - RPC_CANTRECV */
+ "RPC: Timed out", /* 5 - RPC_TIMEDOUT */
+ "RPC: Incompatible versions of RPC", /* 6 - RPC_VERSMISMATCH */
+ "RPC: Authentication error", /* 7 - RPC_AUTHERROR */
+ "RPC: Program unavailable", /* 8 - RPC_PROGUNAVAIL */
+ "RPC: Program/version mismatch", /* 9 - RPC_PROGVERSMISMATCH */
+ "RPC: Procedure unavailable", /* 10 - RPC_PROCUNAVAIL */
+ "RPC: Server can't decode arguments", /* 11 - RPC_CANTDECODEARGS */
+ "RPC: Remote system error", /* 12 - RPC_SYSTEMERROR */
+ "RPC: Unknown host", /* 13 - RPC_UNKNOWNHOST */
+ "RPC: Port mapper failure", /* 14 - RPC_PMAPFAILURE */
+ "RPC: Program not registered", /* 15 - RPC_PROGNOTREGISTERED */
+ "RPC: Failed (unspecified error)", /* 16 - RPC_FAILED */
+ "RPC: Unknown protocol" /* 17 - RPC_UNKNOWNPROTO */
+};
+
+
+/*
+ * This interface for use by clntrpc
+ */
+char *
+clnt_sperrno(stat)
+ enum clnt_stat stat;
+{
+ unsigned int errnum = stat;
+
+ if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0])))
+ return (char *)rpc_errlist[errnum];
+
+ return ("RPC: (unknown error code)");
+}
+
+void
+clnt_perrno(num)
+ enum clnt_stat num;
+{
+ (void) fprintf(stderr,"%s\n",clnt_sperrno(num));
+}
+
+
+char *
+clnt_spcreateerror(s)
+ const char *s;
+{
+ char *str = _buf();
+
+ if (str == 0)
+ return(0);
+ switch (rpc_createerr.cf_stat) {
+ case RPC_PMAPFAILURE:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
+ clnt_sperrno(rpc_createerr.cf_stat),
+ clnt_sperrno(rpc_createerr.cf_error.re_status));
+ break;
+
+ case RPC_SYSTEMERROR:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
+ clnt_sperrno(rpc_createerr.cf_stat),
+ strerror(rpc_createerr.cf_error.re_errno));
+ break;
+ default:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s\n", s,
+ clnt_sperrno(rpc_createerr.cf_stat));
+ break;
+ }
+ str[CLNT_PERROR_BUFLEN-2] = '\n';
+ str[CLNT_PERROR_BUFLEN-1] = '\0';
+ return (str);
+}
+
+void
+clnt_pcreateerror(s)
+ const char *s;
+{
+ (void) fprintf(stderr,"%s\n",clnt_spcreateerror(s));
+}
+
+static const char *const auth_errlist[] = {
+ "Authentication OK", /* 0 - AUTH_OK */
+ "Invalid client credential", /* 1 - AUTH_BADCRED */
+ "Server rejected credential", /* 2 - AUTH_REJECTEDCRED */
+ "Invalid client verifier", /* 3 - AUTH_BADVERF */
+ "Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
+ "Client credential too weak", /* 5 - AUTH_TOOWEAK */
+ "Invalid server verifier", /* 6 - AUTH_INVALIDRESP */
+ "Failed (unspecified error)" /* 7 - AUTH_FAILED */
+};
+
+static char *
+auth_errmsg(stat)
+ enum auth_stat stat;
+{
+ unsigned int errnum = stat;
+
+ if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0])))
+ return (char *)auth_errlist[errnum];
+
+ return(NULL);
+}
diff --git a/cpukit/librpc/src/rpc/clnt_raw.c b/cpukit/librpc/src/rpc/clnt_raw.c
new file mode 100644
index 0000000000..9195e55887
--- /dev/null
+++ b/cpukit/librpc/src/rpc/clnt_raw.c
@@ -0,0 +1,243 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_raw.c,v 1.10 1999/08/28 00:00:36 peter Exp $";
+#endif
+
+/*
+ * clnt_raw.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Memory based rpc for simple testing and timing.
+ * Interface to create an rpc client and server in the same process.
+ * This lets us similate rpc and get round trip overhead, without
+ * any interference from the kernal.
+ */
+
+#include <rpc/rpc.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define MCALL_MSG_SIZE 24
+
+/*
+ * This is the "network" we will be moving stuff over.
+ */
+struct clnt_raw_private {
+ CLIENT client_object;
+ XDR xdr_stream;
+ char _raw_buf[UDPMSGSIZE];
+ char mashl_callmsg[MCALL_MSG_SIZE];
+ u_int mcnt;
+};
+#define clntraw_private (rtems_rpc_task_variables->clnt_raw_private)
+
+static enum clnt_stat clntraw_call();
+static void clntraw_abort();
+static void clntraw_geterr();
+static bool_t clntraw_freeres();
+static bool_t clntraw_control();
+static void clntraw_destroy();
+
+static struct clnt_ops client_ops = {
+ clntraw_call,
+ clntraw_abort,
+ clntraw_geterr,
+ clntraw_freeres,
+ clntraw_destroy,
+ clntraw_control
+};
+
+void svc_getreq();
+
+/*
+ * Create a client handle for memory based rpc.
+ */
+CLIENT *
+clntraw_create(
+ u_long prog,
+ u_long vers )
+{
+ register struct clnt_raw_private *clp = clntraw_private;
+ struct rpc_msg call_msg;
+ XDR *xdrs = &clp->xdr_stream;
+ CLIENT *client = &clp->client_object;
+
+ if (clp == 0) {
+ clp = (struct clnt_raw_private *)calloc(1, sizeof (*clp));
+ if (clp == 0)
+ return (0);
+ clntraw_private = clp;
+ }
+ /*
+ * pre-serialize the static part of the call msg and stash it away
+ */
+ call_msg.rm_direction = CALL;
+ call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ call_msg.rm_call.cb_prog = prog;
+ call_msg.rm_call.cb_vers = vers;
+ xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
+ if (! xdr_callhdr(xdrs, &call_msg)) {
+ perror("clnt_raw.c - Fatal header serialization error.");
+ }
+ clp->mcnt = XDR_GETPOS(xdrs);
+ XDR_DESTROY(xdrs);
+
+ /*
+ * Set xdrmem for client/server shared buffer
+ */
+ xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+
+ /*
+ * create client handle
+ */
+ client->cl_ops = &client_ops;
+ client->cl_auth = authnone_create();
+ return (client);
+}
+
+static enum clnt_stat
+clntraw_call(
+ CLIENT *h,
+ u_long proc,
+ xdrproc_t xargs,
+ caddr_t argsp,
+ xdrproc_t xresults,
+ caddr_t resultsp,
+ struct timeval timeout )
+{
+ register struct clnt_raw_private *clp = clntraw_private;
+ register XDR *xdrs = &clp->xdr_stream;
+ struct rpc_msg msg;
+ enum clnt_stat status;
+ struct rpc_err error;
+
+ if (clp == 0)
+ return (RPC_FAILED);
+call_again:
+ /*
+ * send request
+ */
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, 0);
+ ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ;
+ if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
+ (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+ (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+ (! (*xargs)(xdrs, argsp))) {
+ return (RPC_CANTENCODEARGS);
+ }
+ (void)XDR_GETPOS(xdrs); /* called just to cause overhead */
+
+ /*
+ * We have to call server input routine here because this is
+ * all going on in one process. Yuk.
+ */
+ svc_getreq(1);
+
+ /*
+ * get results
+ */
+ xdrs->x_op = XDR_DECODE;
+ XDR_SETPOS(xdrs, 0);
+ msg.acpted_rply.ar_verf = _null_auth;
+ msg.acpted_rply.ar_results.where = resultsp;
+ msg.acpted_rply.ar_results.proc = xresults;
+ if (! xdr_replymsg(xdrs, &msg))
+ return (RPC_CANTDECODERES);
+ _seterr_reply(&msg, &error);
+ status = error.re_status;
+
+ if (status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+ status = RPC_AUTHERROR;
+ }
+ } /* end successful completion */
+ else {
+ if (AUTH_REFRESH(h->cl_auth))
+ goto call_again;
+ } /* end of unsuccessful completion */
+
+ if (status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+ status = RPC_AUTHERROR;
+ }
+ if (msg.acpted_rply.ar_verf.oa_base != NULL) {
+ xdrs->x_op = XDR_FREE;
+ (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
+ }
+ }
+
+ return (status);
+}
+
+static void
+clntraw_geterr()
+{
+}
+
+
+static bool_t
+clntraw_freeres(
+ CLIENT *cl,
+ xdrproc_t xdr_res,
+ caddr_t res_ptr )
+{
+ register struct clnt_raw_private *clp = clntraw_private;
+ register XDR *xdrs = &clp->xdr_stream;
+ bool_t rval;
+
+ if (clp == 0)
+ {
+ rval = (bool_t) RPC_FAILED;
+ return (rval);
+ }
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clntraw_abort()
+{
+}
+
+static bool_t
+clntraw_control()
+{
+ return (FALSE);
+}
+
+static void
+clntraw_destroy()
+{
+}
diff --git a/cpukit/librpc/src/rpc/clnt_simple.c b/cpukit/librpc/src/rpc/clnt_simple.c
new file mode 100644
index 0000000000..3a772203d3
--- /dev/null
+++ b/cpukit/librpc/src/rpc/clnt_simple.c
@@ -0,0 +1,123 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_simple.c,v 1.12 2000/01/27 23:06:35 jasone Exp $";
+#endif
+
+/*
+ * clnt_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+struct call_rpc_private {
+ CLIENT *client;
+ int socket;
+ int oldprognum, oldversnum, valid;
+ char *oldhost;
+};
+#define callrpc_private (rtems_rpc_task_variables->call_rpc_private)
+
+int
+callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
+ char *host;
+ int prognum, versnum, procnum;
+ xdrproc_t inproc, outproc;
+ char *in, *out;
+{
+ register struct call_rpc_private *crp = callrpc_private;
+ struct sockaddr_in server_addr;
+ enum clnt_stat clnt_stat;
+ struct hostent *hp;
+ struct timeval timeout, tottimeout;
+
+ if (crp == 0) {
+ crp = (struct call_rpc_private *)calloc(1, sizeof (*crp));
+ if (crp == 0)
+ return (0);
+ callrpc_private = crp;
+ }
+ if (crp->oldhost == NULL) {
+ crp->oldhost = malloc(MAXHOSTNAMELEN);
+ crp->oldhost[0] = 0;
+ crp->socket = RPC_ANYSOCK;
+ }
+ if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
+ && strcmp(crp->oldhost, host) == 0) {
+ /* reuse old client */
+ } else {
+ crp->valid = 0;
+ if (crp->socket != -1)
+ (void)_RPC_close(crp->socket);
+ crp->socket = RPC_ANYSOCK;
+ if (crp->client) {
+ clnt_destroy(crp->client);
+ crp->client = NULL;
+ }
+ if ((hp = gethostbyname(host)) == NULL)
+ return ((int) RPC_UNKNOWNHOST);
+ timeout.tv_usec = 0;
+ timeout.tv_sec = 5;
+ memset(&server_addr, 0, sizeof(server_addr));
+ memcpy((char *)&server_addr.sin_addr, hp->h_addr, hp->h_length);
+ server_addr.sin_len = sizeof(struct sockaddr_in);
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_port = 0;
+ if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
+ (u_long)versnum, timeout, &crp->socket)) == NULL)
+ return ((int) rpc_createerr.cf_stat);
+ crp->valid = 1;
+ crp->oldprognum = prognum;
+ crp->oldversnum = versnum;
+ (void) strcpy(crp->oldhost, host);
+ }
+ tottimeout.tv_sec = 25;
+ tottimeout.tv_usec = 0;
+ clnt_stat = clnt_call(crp->client, procnum, inproc, in,
+ outproc, out, tottimeout);
+ /*
+ * if call failed, empty cache
+ */
+ if (clnt_stat != RPC_SUCCESS)
+ crp->valid = 0;
+ return ((int) clnt_stat);
+}
diff --git a/cpukit/librpc/src/rpc/clnt_tcp.c b/cpukit/librpc/src/rpc/clnt_tcp.c
new file mode 100644
index 0000000000..a6e80eda8b
--- /dev/null
+++ b/cpukit/librpc/src/rpc/clnt_tcp.c
@@ -0,0 +1,581 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_tcp.c,v 1.14 2000/01/27 23:06:36 jasone Exp $";
+#endif
+
+/*
+ * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * TCP based RPC supports 'batched calls'.
+ * A sequence of calls may be batched-up in a send buffer. The rpc call
+ * return immediately to the client even though the call was not necessarily
+ * sent. The batching occurs if the results' xdr routine is NULL (0) AND
+ * the rpc timeout value is zero (see clnt.h, rpc).
+ *
+ * Clients should NOT casually batch calls that in fact return results; that is,
+ * the server side should be aware that a call is batched and not produce any
+ * return message. Batched calls that produce many result messages can
+ * deadlock (netlock) the client and the server....
+ *
+ * Now go hang yourself.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/select.h>
+
+#define MCALL_MSG_SIZE 24
+
+static int readtcp();
+static int writetcp();
+
+static enum clnt_stat clnttcp_call();
+static void clnttcp_abort();
+static void clnttcp_geterr();
+static bool_t clnttcp_freeres();
+static bool_t clnttcp_control();
+static void clnttcp_destroy();
+
+static struct clnt_ops tcp_ops = {
+ clnttcp_call,
+ clnttcp_abort,
+ clnttcp_geterr,
+ clnttcp_freeres,
+ clnttcp_destroy,
+ clnttcp_control
+};
+
+struct ct_data {
+ int ct_sock;
+ bool_t ct_closeit;
+ struct timeval ct_wait;
+ bool_t ct_waitset; /* wait set by clnt_control? */
+ struct sockaddr_in ct_addr;
+ struct rpc_err ct_error;
+ char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
+ u_int ct_mpos; /* pos after marshal */
+ XDR ct_xdrs;
+};
+
+/*
+ * Create a client handle for a tcp/ip connection.
+ * If *sockp<0, *sockp is set to a newly created TCP socket and it is
+ * connected to raddr. If *sockp non-negative then
+ * raddr is ignored. The rpc/tcp package does buffering
+ * similar to stdio, so the client must pick send and receive buffer sizes,];
+ * 0 => use the default.
+ * If raddr->sin_port is 0, then a binder on the remote machine is
+ * consulted for the right port number.
+ * NB: *sockp is copied into a private area.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this
+ * something more useful.
+ */
+CLIENT *
+clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ struct sockaddr_in *raddr;
+ u_long prog;
+ u_long vers;
+ register int *sockp;
+ u_int sendsz;
+ u_int recvsz;
+{
+ CLIENT *h;
+ register struct ct_data *ct = NULL;
+ struct timeval now;
+ struct rpc_msg call_msg;
+ static u_int32_t disrupt;
+
+ if (disrupt == 0)
+ disrupt = (u_int32_t)(long)raddr;
+
+ h = (CLIENT *)mem_alloc(sizeof(*h));
+ if (h == NULL) {
+ (void)fprintf(stderr, "clnttcp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ ct = (struct ct_data *)mem_alloc(sizeof(*ct));
+ if (ct == NULL) {
+ (void)fprintf(stderr, "clnttcp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+
+ /*
+ * If no port number given ask the pmap for one
+ */
+ if (raddr->sin_port == 0) {
+ u_short port;
+ if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) {
+ mem_free((caddr_t)ct, sizeof(struct ct_data));
+ mem_free((caddr_t)h, sizeof(CLIENT));
+ return ((CLIENT *)NULL);
+ }
+ raddr->sin_port = htons(port);
+ }
+
+ /*
+ * If no socket given, open one
+ */
+ if (*sockp < 0) {
+ *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ (void)bindresvport(*sockp, (struct sockaddr_in *)0);
+ if ((*sockp < 0)
+ || (connect(*sockp, (struct sockaddr *)raddr,
+ sizeof(*raddr)) < 0)) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ if (*sockp != -1)
+ (void)_RPC_close(*sockp);
+ goto fooy;
+ }
+ ct->ct_closeit = TRUE;
+ } else {
+ ct->ct_closeit = FALSE;
+ }
+
+ /*
+ * Set up private data struct
+ */
+ ct->ct_sock = *sockp;
+ ct->ct_wait.tv_usec = 0;
+ ct->ct_waitset = FALSE;
+ ct->ct_addr = *raddr;
+
+ /*
+ * Initialize call message
+ */
+ (void)gettimeofday(&now, (struct timezone *)0);
+ call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
+ call_msg.rm_direction = CALL;
+ call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ call_msg.rm_call.cb_prog = prog;
+ call_msg.rm_call.cb_vers = vers;
+
+ /*
+ * pre-serialize the static part of the call msg and stash it away
+ */
+ xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
+ XDR_ENCODE);
+ if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
+ if (ct->ct_closeit) {
+ (void)_RPC_close(*sockp);
+ }
+ goto fooy;
+ }
+ ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
+ XDR_DESTROY(&(ct->ct_xdrs));
+
+ /*
+ * Create a client handle which uses xdrrec for serialization
+ * and authnone for authentication.
+ */
+ xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
+ (caddr_t)ct, readtcp, writetcp);
+ h->cl_ops = &tcp_ops;
+ h->cl_private = (caddr_t) ct;
+ h->cl_auth = authnone_create();
+ return (h);
+
+fooy:
+ /*
+ * Something goofed, free stuff and barf
+ */
+ if (ct)
+ mem_free((caddr_t)ct, sizeof(struct ct_data));
+ if (h)
+ mem_free((caddr_t)h, sizeof(CLIENT));
+ return ((CLIENT *)NULL);
+}
+
+static enum clnt_stat
+clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
+ register CLIENT *h;
+ u_long proc;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+ xdrproc_t xdr_results;
+ caddr_t results_ptr;
+ struct timeval timeout;
+{
+ register struct ct_data *ct = (struct ct_data *) h->cl_private;
+ register XDR *xdrs = &(ct->ct_xdrs);
+ struct rpc_msg reply_msg;
+ u_long x_id;
+ u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */
+ register bool_t shipnow;
+ int refreshes = 2;
+
+ if (!ct->ct_waitset) {
+ ct->ct_wait = timeout;
+ }
+
+ shipnow =
+ (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
+ && timeout.tv_usec == 0) ? FALSE : TRUE;
+
+call_again:
+ xdrs->x_op = XDR_ENCODE;
+ ct->ct_error.re_status = RPC_SUCCESS;
+ x_id = ntohl(--(*msg_x_id));
+ if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
+ (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+ (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+ (! (*xdr_args)(xdrs, args_ptr))) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ ct->ct_error.re_status = RPC_CANTENCODEARGS;
+ (void)xdrrec_endofrecord(xdrs, TRUE);
+ return (ct->ct_error.re_status);
+ }
+ if (! xdrrec_endofrecord(xdrs, shipnow))
+ return (ct->ct_error.re_status = RPC_CANTSEND);
+ if (! shipnow)
+ return (RPC_SUCCESS);
+ /*
+ * Hack to provide rpc-based message passing
+ */
+ if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+ return(ct->ct_error.re_status = RPC_TIMEDOUT);
+ }
+
+
+ /*
+ * Keep receiving until we get a valid transaction id
+ */
+ xdrs->x_op = XDR_DECODE;
+ while (TRUE) {
+ reply_msg.acpted_rply.ar_verf = _null_auth;
+ reply_msg.acpted_rply.ar_results.where = NULL;
+ reply_msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
+ if (! xdrrec_skiprecord(xdrs))
+ return (ct->ct_error.re_status);
+ /* now decode and validate the response header */
+ if (! xdr_replymsg(xdrs, &reply_msg)) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ continue;
+ return (ct->ct_error.re_status);
+ }
+ if (reply_msg.rm_xid == x_id)
+ break;
+ }
+
+ /*
+ * process header
+ */
+ _seterr_reply(&reply_msg, &(ct->ct_error));
+ if (ct->ct_error.re_status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
+ ct->ct_error.re_status = RPC_AUTHERROR;
+ ct->ct_error.re_why = AUTH_INVALIDRESP;
+ } else if (! (*xdr_results)(xdrs, results_ptr)) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ ct->ct_error.re_status = RPC_CANTDECODERES;
+ }
+ /* free verifier ... */
+ if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+ xdrs->x_op = XDR_FREE;
+ (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
+ }
+ } /* end successful completion */
+ else {
+ /* maybe our credentials need to be refreshed ... */
+ if (refreshes-- && AUTH_REFRESH(h->cl_auth))
+ goto call_again;
+ } /* end of unsuccessful completion */
+ return (ct->ct_error.re_status);
+}
+
+static void
+clnttcp_geterr(h, errp)
+ CLIENT *h;
+ struct rpc_err *errp;
+{
+ register struct ct_data *ct =
+ (struct ct_data *) h->cl_private;
+
+ *errp = ct->ct_error;
+}
+
+static bool_t
+clnttcp_freeres(cl, xdr_res, res_ptr)
+ CLIENT *cl;
+ xdrproc_t xdr_res;
+ caddr_t res_ptr;
+{
+ register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+ register XDR *xdrs = &(ct->ct_xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clnttcp_abort()
+{
+}
+
+
+static bool_t
+clnttcp_control(cl, request, info)
+ CLIENT *cl;
+ int request;
+ char *info;
+{
+ register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+ register struct timeval *tv;
+ socklen_t len;
+
+ switch (request) {
+ case CLSET_FD_CLOSE:
+ ct->ct_closeit = TRUE;
+ break;
+ case CLSET_FD_NCLOSE:
+ ct->ct_closeit = FALSE;
+ break;
+ case CLSET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ tv = (struct timeval *)info;
+ ct->ct_wait.tv_sec = tv->tv_sec;
+ ct->ct_wait.tv_usec = tv->tv_usec;
+ ct->ct_waitset = TRUE;
+ break;
+ case CLGET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ *(struct timeval *)info = ct->ct_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ if (info == NULL)
+ return(FALSE);
+ *(struct sockaddr_in *)info = ct->ct_addr;
+ break;
+ case CLGET_FD:
+ if (info == NULL)
+ return(FALSE);
+ *(int *)info = ct->ct_sock;
+ break;
+ case CLGET_XID:
+ /*
+ * use the knowledge that xid is the
+ * first element in the call structure *.
+ * This will get the xid of the PREVIOUS call
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)ct->ct_mcall);
+ break;
+ case CLSET_XID:
+ /* This will set the xid of the NEXT call */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1);
+ /* decrement by 1 as clnttcp_call() increments once */
+ case CLGET_VERS:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the version number field is the fifth field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
+ 4 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_VERS:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_PROG:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the program number field is the field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
+ 3 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_PROG:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_LOCAL_ADDR:
+ len = sizeof(struct sockaddr);
+ if (getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0)
+ return(FALSE);
+ break;
+ case CLGET_RETRY_TIMEOUT:
+ case CLSET_RETRY_TIMEOUT:
+ case CLGET_SVC_ADDR:
+ case CLSET_SVC_ADDR:
+ case CLSET_PUSH_TIMOD:
+ case CLSET_POP_TIMOD:
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+static void
+clnttcp_destroy(h)
+ CLIENT *h;
+{
+ register struct ct_data *ct =
+ (struct ct_data *) h->cl_private;
+
+ if (ct->ct_closeit) {
+ (void)_RPC_close(ct->ct_sock);
+ }
+ XDR_DESTROY(&(ct->ct_xdrs));
+ mem_free((caddr_t)ct, sizeof(struct ct_data));
+ mem_free((caddr_t)h, sizeof(CLIENT));
+}
+
+/*
+ * Interface between xdr serializer and tcp connection.
+ * Behaves like the system calls, read & write, but keeps some error state
+ * around for the rpc level.
+ */
+static int
+readtcp(ct, buf, len)
+ register struct ct_data *ct;
+ caddr_t buf;
+ register int len;
+{
+ fd_set *fds, readfds;
+ struct timeval start, after, duration, delta, tmp, tv;
+ int r, save_errno;
+
+ if (len == 0)
+ return (0);
+
+ if (ct->ct_sock + 1 > FD_SETSIZE) {
+ int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL)
+ return (-1);
+ memset(fds, 0, bytes);
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ gettimeofday(&start, NULL);
+ delta = ct->ct_wait;
+ while (TRUE) {
+ /* XXX we know the other bits are still clear */
+ FD_SET(ct->ct_sock, fds);
+ tv = delta; /* in case select writes back */
+ r = select(ct->ct_sock+1, fds, NULL, NULL, &tv);
+ save_errno = errno;
+
+ gettimeofday(&after, NULL);
+ timersub(&start, &after, &duration);
+ timersub(&ct->ct_wait, &duration, &tmp);
+ delta = tmp;
+ if (delta.tv_sec < 0 || !timerisset(&delta))
+ r = 0;
+
+ switch (r) {
+ case 0:
+ if (fds != &readfds)
+ free(fds);
+ ct->ct_error.re_status = RPC_TIMEDOUT;
+ return (-1);
+
+ case -1:
+ if (errno == EINTR)
+ continue;
+ if (fds != &readfds)
+ free(fds);
+ ct->ct_error.re_status = RPC_CANTRECV;
+ ct->ct_error.re_errno = save_errno;
+ return (-1);
+ }
+ break;
+ }
+ switch (len = _RPC_read(ct->ct_sock, buf, len)) {
+
+ case 0:
+ /* premature eof */
+ ct->ct_error.re_errno = ECONNRESET;
+ ct->ct_error.re_status = RPC_CANTRECV;
+ len = -1; /* it's really an error */
+ break;
+
+ case -1:
+ ct->ct_error.re_errno = errno;
+ ct->ct_error.re_status = RPC_CANTRECV;
+ break;
+ }
+ return (len);
+}
+
+static int
+writetcp(ct, buf, len)
+ struct ct_data *ct;
+ caddr_t buf;
+ int len;
+{
+ register int i, cnt;
+
+ for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+ if ((i = _RPC_write(ct->ct_sock, buf, cnt)) == -1) {
+ ct->ct_error.re_errno = errno;
+ ct->ct_error.re_status = RPC_CANTSEND;
+ return (-1);
+ }
+ }
+ return (len);
+}
diff --git a/cpukit/librpc/src/rpc/clnt_udp.c b/cpukit/librpc/src/rpc/clnt_udp.c
new file mode 100644
index 0000000000..a83014aca2
--- /dev/null
+++ b/cpukit/librpc/src/rpc/clnt_udp.c
@@ -0,0 +1,568 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_udp.c,v 1.15 2000/01/27 23:06:36 jasone Exp $";
+#endif
+
+/*
+ * clnt_udp.c, Implements a UDP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/select.h>
+
+/*
+ * UDP bases client side rpc operations
+ */
+static enum clnt_stat clntudp_call();
+static void clntudp_abort();
+static void clntudp_geterr();
+static bool_t clntudp_freeres();
+static bool_t clntudp_control();
+static void clntudp_destroy();
+
+static struct clnt_ops udp_ops = {
+ clntudp_call,
+ clntudp_abort,
+ clntudp_geterr,
+ clntudp_freeres,
+ clntudp_destroy,
+ clntudp_control
+};
+
+/*
+ * Private data kept per client handle
+ */
+struct cu_data {
+ int cu_sock;
+ bool_t cu_closeit;
+ struct sockaddr_in cu_raddr;
+ int cu_rlen;
+ struct timeval cu_wait;
+ struct timeval cu_total;
+ struct rpc_err cu_error;
+ XDR cu_outxdrs;
+ u_int cu_xdrpos;
+ u_int cu_sendsz;
+ char *cu_outbuf;
+ u_int cu_recvsz;
+ char cu_inbuf[1];
+};
+
+/*
+ * Create a UDP based client handle.
+ * If *sockp<0, *sockp is set to a newly created UPD socket.
+ * If raddr->sin_port is 0 a binder on the remote machine
+ * is consulted for the correct port number.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is initialized to null authentication.
+ * Caller may wish to set this something more useful.
+ *
+ * wait is the amount of time used between retransmitting a call if
+ * no response has been heard; retransmition occurs until the actual
+ * rpc call times out.
+ *
+ * sendsz and recvsz are the maximum allowable packet sizes that can be
+ * sent and received.
+ */
+CLIENT *
+clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+ struct sockaddr_in *raddr;
+ u_long program;
+ u_long version;
+ struct timeval wait;
+ register int *sockp;
+ u_int sendsz;
+ u_int recvsz;
+{
+ CLIENT *cl;
+ register struct cu_data *cu = NULL;
+ struct timeval now;
+ struct rpc_msg call_msg;
+ static u_int32_t disrupt;
+
+ if (disrupt == 0)
+ disrupt = (u_int32_t)(long)raddr;
+
+ cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
+ if (cl == NULL) {
+ (void) fprintf(stderr, "clntudp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ sendsz = ((sendsz + 3) / 4) * 4;
+ recvsz = ((recvsz + 3) / 4) * 4;
+ cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz);
+ if (cu == NULL) {
+ (void) fprintf(stderr, "clntudp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ cu->cu_outbuf = &cu->cu_inbuf[recvsz];
+
+ (void)gettimeofday(&now, (struct timezone *)0);
+ if (raddr->sin_port == 0) {
+ u_short port;
+ if ((port =
+ pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
+ goto fooy;
+ }
+ raddr->sin_port = htons(port);
+ }
+ cl->cl_ops = &udp_ops;
+ cl->cl_private = (caddr_t)cu;
+ cu->cu_raddr = *raddr;
+ cu->cu_rlen = sizeof (cu->cu_raddr);
+ cu->cu_wait = wait;
+ cu->cu_total.tv_sec = -1;
+ cu->cu_total.tv_usec = -1;
+ cu->cu_sendsz = sendsz;
+ cu->cu_recvsz = recvsz;
+ call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
+ call_msg.rm_direction = CALL;
+ call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ call_msg.rm_call.cb_prog = program;
+ call_msg.rm_call.cb_vers = version;
+ xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,
+ sendsz, XDR_ENCODE);
+ if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
+ goto fooy;
+ }
+ cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
+ if (*sockp < 0) {
+ int dontblock = 1;
+
+ *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (*sockp < 0) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ /* attempt to bind to priv port */
+ (void)bindresvport(*sockp, (struct sockaddr_in *)0);
+ /* the sockets rpc controls are non-blocking */
+ (void)ioctl(*sockp, FIONBIO, (char *) &dontblock);
+ cu->cu_closeit = TRUE;
+ } else {
+ cu->cu_closeit = FALSE;
+ }
+ cu->cu_sock = *sockp;
+ cl->cl_auth = authnone_create();
+ return (cl);
+fooy:
+ if (cu)
+ mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);
+ if (cl)
+ mem_free((caddr_t)cl, sizeof(CLIENT));
+ return ((CLIENT *)NULL);
+}
+
+CLIENT *
+clntudp_create(raddr, program, version, wait, sockp)
+ struct sockaddr_in *raddr;
+ u_long program;
+ u_long version;
+ struct timeval wait;
+ register int *sockp;
+{
+
+ return(clntudp_bufcreate(raddr, program, version, wait, sockp,
+ UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum clnt_stat
+clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
+ register CLIENT *cl; /* client handle */
+ u_long proc; /* procedure number */
+ xdrproc_t xargs; /* xdr routine for args */
+ caddr_t argsp; /* pointer to args */
+ xdrproc_t xresults; /* xdr routine for results */
+ caddr_t resultsp; /* pointer to results */
+ struct timeval utimeout; /* seconds to wait before giving up */
+{
+ register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+ register XDR *xdrs;
+ register int outlen;
+ register int inlen;
+ socklen_t fromlen;
+ fd_set *fds, readfds;
+ struct sockaddr_in from;
+ struct rpc_msg reply_msg;
+ XDR reply_xdrs;
+ struct timeval time_waited, start, after, tmp1, tmp2, tv;
+ bool_t ok;
+ int nrefreshes = 2; /* number of times to refresh cred */
+ struct timeval timeout;
+
+ if (cu->cu_total.tv_usec == -1)
+ timeout = utimeout; /* use supplied timeout */
+ else
+ timeout = cu->cu_total; /* use default timeout */
+
+ if (cu->cu_sock + 1 > FD_SETSIZE) {
+ int bytes = howmany(cu->cu_sock + 1, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL)
+ return (cu->cu_error.re_status = RPC_CANTSEND);
+ memset(fds, 0, bytes);
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ timerclear(&time_waited);
+
+call_again:
+ xdrs = &(cu->cu_outxdrs);
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, cu->cu_xdrpos);
+ /*
+ * the transaction is the first thing in the out buffer
+ */
+ (*(u_short *)(cu->cu_outbuf))++;
+ if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+ (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
+ (! (*xargs)(xdrs, argsp))) {
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
+ }
+ outlen = (int)XDR_GETPOS(xdrs);
+
+send_again:
+ if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
+ (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) != outlen) {
+ cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTSEND);
+ }
+
+ /*
+ * Hack to provide rpc-based message passing
+ */
+ if (!timerisset(&timeout)) {
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+ }
+ /*
+ * sub-optimal code appears here because we have
+ * some clock time to spare while the packets are in flight.
+ * (We assume that this is actually only executed once.)
+ */
+ reply_msg.acpted_rply.ar_verf = _null_auth;
+ reply_msg.acpted_rply.ar_results.where = resultsp;
+ reply_msg.acpted_rply.ar_results.proc = xresults;
+
+ gettimeofday(&start, NULL);
+ for (;;) {
+ /* XXX we know the other bits are still clear */
+ FD_SET(cu->cu_sock, fds);
+ tv = cu->cu_wait;
+ switch (select(cu->cu_sock+1, fds, NULL, NULL, &tv)) {
+
+ case 0:
+ timeradd(&time_waited, &cu->cu_wait, &tmp1);
+ time_waited = tmp1;
+ if (timercmp(&time_waited, &timeout, <))
+ goto send_again;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+
+ case -1:
+ if (errno == EINTR) {
+ gettimeofday(&after, NULL);
+ timersub(&after, &start, &tmp1);
+ timeradd(&time_waited, &tmp1, &tmp2);
+ time_waited = tmp2;
+ if (timercmp(&time_waited, &timeout, <))
+ continue;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+ }
+ cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+
+ do {
+ fromlen = sizeof(struct sockaddr);
+ inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
+ (int) cu->cu_recvsz, 0,
+ (struct sockaddr *)&from, &fromlen);
+ } while (inlen < 0 && errno == EINTR);
+ if (inlen < 0) {
+ if (errno == EWOULDBLOCK)
+ continue;
+ cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+ if (inlen < sizeof(u_int32_t))
+ continue;
+ /* see if reply transaction id matches sent id */
+ if (*((u_int32_t *)(cu->cu_inbuf)) != *((u_int32_t *)(cu->cu_outbuf)))
+ continue;
+ /* we now assume we have the proper reply */
+ break;
+ }
+
+ /*
+ * now decode and validate the response
+ */
+ xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE);
+ ok = xdr_replymsg(&reply_xdrs, &reply_msg);
+ /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */
+ if (ok) {
+ _seterr_reply(&reply_msg, &(cu->cu_error));
+ if (cu->cu_error.re_status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(cl->cl_auth,
+ &reply_msg.acpted_rply.ar_verf)) {
+ cu->cu_error.re_status = RPC_AUTHERROR;
+ cu->cu_error.re_why = AUTH_INVALIDRESP;
+ }
+ if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+ xdrs->x_op = XDR_FREE;
+ (void)xdr_opaque_auth(xdrs,
+ &(reply_msg.acpted_rply.ar_verf));
+ }
+ } /* end successful completion */
+ else {
+ /* maybe our credentials need to be refreshed ... */
+ if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) {
+ nrefreshes--;
+ goto call_again;
+ }
+ } /* end of unsuccessful completion */
+ } /* end of valid reply message */
+ else {
+ /*
+ * It's possible for xdr_replymsg() to fail partway
+ * through its attempt to decode the result from the
+ * server. If this happens, it will leave the reply
+ * structure partially populated with dynamically
+ * allocated memory. (This can happen if someone uses
+ * clntudp_bufcreate() to create a CLIENT handle and
+ * specifies a receive buffer size that is too small.)
+ * This memory must be free()ed to avoid a leak.
+ */
+ int op = reply_xdrs.x_op;
+ reply_xdrs.x_op = XDR_FREE;
+ xdr_replymsg(&reply_xdrs, &reply_msg);
+ reply_xdrs.x_op = op;
+ cu->cu_error.re_status = RPC_CANTDECODERES;
+ }
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status);
+}
+
+static void
+clntudp_geterr(cl, errp)
+ CLIENT *cl;
+ struct rpc_err *errp;
+{
+ register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+ *errp = cu->cu_error;
+}
+
+
+static bool_t
+clntudp_freeres(cl, xdr_res, res_ptr)
+ CLIENT *cl;
+ xdrproc_t xdr_res;
+ caddr_t res_ptr;
+{
+ register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+ register XDR *xdrs = &(cu->cu_outxdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clntudp_abort(/*h*/)
+ /*CLIENT *h;*/
+{
+}
+
+
+static bool_t
+clntudp_control(cl, request, info)
+ CLIENT *cl;
+ int request;
+ char *info;
+{
+ register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+ register struct timeval *tv;
+ socklen_t len;
+
+ switch (request) {
+ case CLSET_FD_CLOSE:
+ cu->cu_closeit = TRUE;
+ break;
+ case CLSET_FD_NCLOSE:
+ cu->cu_closeit = FALSE;
+ break;
+ case CLSET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ tv = (struct timeval *)info;
+ cu->cu_total.tv_sec = tv->tv_sec;
+ cu->cu_total.tv_usec = tv->tv_usec;
+ break;
+ case CLGET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ *(struct timeval *)info = cu->cu_total;
+ break;
+ case CLSET_RETRY_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ tv = (struct timeval *)info;
+ cu->cu_wait.tv_sec = tv->tv_sec;
+ cu->cu_wait.tv_usec = tv->tv_usec;
+ break;
+ case CLGET_RETRY_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ *(struct timeval *)info = cu->cu_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ if (info == NULL)
+ return(FALSE);
+ *(struct sockaddr_in *)info = cu->cu_raddr;
+ break;
+ case CLGET_FD:
+ if (info == NULL)
+ return(FALSE);
+ *(int *)info = cu->cu_sock;
+ break;
+ case CLGET_XID:
+ /*
+ * use the knowledge that xid is the
+ * first element in the call structure *.
+ * This will get the xid of the PREVIOUS call
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)cu->cu_outbuf);
+ break;
+ case CLSET_XID:
+ /* This will set the xid of the NEXT call */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)cu->cu_outbuf = htonl(*(u_long *)info - 1);
+ /* decrement by 1 as clntudp_call() increments once */
+ case CLGET_VERS:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the version number field is the fifth field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
+ 4 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_VERS:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_PROG:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the program number field is the field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
+ 3 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_PROG:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_LOCAL_ADDR:
+ len = sizeof(struct sockaddr);
+ if (getsockname(cu->cu_sock, (struct sockaddr *)info, &len) <0)
+ return(FALSE);
+ break;
+ case CLGET_SVC_ADDR:
+ case CLSET_SVC_ADDR:
+ case CLSET_PUSH_TIMOD:
+ case CLSET_POP_TIMOD:
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+static void
+clntudp_destroy(cl)
+ CLIENT *cl;
+{
+ register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+ if (cu->cu_closeit) {
+ (void)_RPC_close(cu->cu_sock);
+ }
+ XDR_DESTROY(&(cu->cu_outxdrs));
+ mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz));
+ mem_free((caddr_t)cl, sizeof(CLIENT));
+}
diff --git a/cpukit/librpc/src/rpc/des_crypt.3 b/cpukit/librpc/src/rpc/des_crypt.3
new file mode 100644
index 0000000000..a92f577a56
--- /dev/null
+++ b/cpukit/librpc/src/rpc/des_crypt.3
@@ -0,0 +1,130 @@
+.\" @(#)des_crypt.3 2.1 88/08/11 4.0 RPCSRC; from 1.16 88/03/02 SMI;
+.\" $FreeBSD: src/lib/libc/rpc/des_crypt.3,v 1.4 2000/03/02 09:13:45 sheldonh Exp $
+.\"
+.TH DES_CRYPT 3 "6 October 1987"
+.SH NAME
+des_crypt, ecb_crypt, cbc_crypt, des_setparity \- fast DES encryption
+.SH SYNOPSIS
+.nf
+.B #include <des_crypt.h>
+.LP
+.B int ecb_crypt(key, data, datalen, mode)
+.B char *key;
+.B char *data;
+.B unsigned datalen;
+.B unsigned mode;
+.LP
+.B int cbc_crypt(key, data, datalen, mode, ivec)
+.B char *key;
+.B char *data;
+.B unsigned datalen;
+.B unsigned mode;
+.B char *ivec;
+.LP
+.B void des_setparity(key)
+.B char *key;
+.fi
+.SH DESCRIPTION
+.IX encryption cbc_crypt "" \fLcbc_crypt\fP
+.IX "des encryption" cbc_crypt "DES encryption" \fLcbc_crypt\fP
+.IX encryption des_setparity "" \fLdes_setparity\fP
+.IX "des encryption" des_setparity "DES encryption" \fLdes_setparity\fP
+.B ecb_crypt(\|)
+and
+.B cbc_crypt(\|)
+implement the
+.SM NBS
+.SM DES
+(Data Encryption Standard).
+These routines are faster and more general purpose than
+.BR crypt (3).
+They also are able to utilize
+.SM DES
+hardware if it is available.
+.B ecb_crypt(\|)
+encrypts in
+.SM ECB
+(Electronic Code Book)
+mode, which encrypts blocks of data independently.
+.B cbc_crypt(\|)
+encrypts in
+.SM CBC
+(Cipher Block Chaining)
+mode, which chains together
+successive blocks.
+.SM CBC
+mode protects against insertions, deletions and
+substitutions of blocks.
+Also, regularities in the clear text will
+not appear in the cipher text.
+.LP
+Here is how to use these routines. The first parameter,
+.IR key ,
+is the 8-byte encryption key with parity.
+To set the key's parity, which for
+.SM DES
+is in the low bit of each byte, use
+.IR des_setparity .
+The second parameter,
+.IR data ,
+contains the data to be encrypted or decrypted.
+The
+third parameter,
+.IR datalen ,
+is the length in bytes of
+.IR data ,
+which must be a multiple of 8. The fourth parameter,
+.IR mode ,
+is formed by
+.SM OR\s0'ing
+together some things. For the encryption direction 'or' in either
+.SM DES_ENCRYPT
+or
+.SM DES_DECRYPT\s0.
+For software versus hardware
+encryption, 'or' in either
+.SM DES_HW
+or
+.SM DES_SW\s0.
+If
+.SM DES_HW
+is specified, and there is no hardware, then the encryption is performed
+in software and the routine returns
+.SM DESERR_NOHWDEVICE\s0.
+For
+.IR cbc_crypt ,
+the parameter
+.I ivec
+is the the 8-byte initialization
+vector for the chaining. It is updated to the next initialization
+vector upon return.
+.LP
+.SH "SEE ALSO"
+.BR des (1),
+.BR crypt (3)
+.SH DIAGNOSTICS
+.PD 0
+.TP 20
+.SM DESERR_NONE
+No error.
+.TP
+.SM DESERR_NOHWDEVICE
+Encryption succeeded, but done in software instead of the requested hardware.
+.TP
+.SM DESERR_HWERR
+An error occurred in the hardware or driver.
+.TP
+.SM DESERR_BADPARAM
+Bad parameter to routine.
+.PD
+.LP
+Given a result status
+.IR stat ,
+the macro
+.SM DES_FAILED\c
+.BR ( stat )
+is false only for the first two statuses.
+.SH RESTRICTIONS
+These routines are not available in RPCSRC 4.0.
+This information is provided to describe the DES interface expected by
+Secure RPC.
diff --git a/cpukit/librpc/src/rpc/get_myaddress.c b/cpukit/librpc/src/rpc/get_myaddress.c
new file mode 100644
index 0000000000..869bd51be4
--- /dev/null
+++ b/cpukit/librpc/src/rpc/get_myaddress.c
@@ -0,0 +1,113 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/get_myaddress.c,v 1.17 2000/01/27 23:06:37 jasone Exp $";
+#endif
+
+/*
+ * get_myaddress.c
+ *
+ * Get client's IP address via ioctl. This avoids using the yellowpages.
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mbuf.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * don't use gethostbyname, which would invoke yellow pages
+ *
+ * Avoid loopback interfaces. We return information from a loopback
+ * interface only if there are no other possible interfaces.
+ */
+int
+get_myaddress(addr)
+ struct sockaddr_in *addr;
+{
+ int s;
+ char buf[BUFSIZ];
+ struct ifconf ifc;
+ struct ifreq ifreq, *ifr, *end;
+ int loopback = 0, gotit = 0;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ return(-1);
+ }
+ ifc.ifc_len = sizeof (buf);
+ ifc.ifc_buf = buf;
+ if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+ _RPC_close(s);
+ return(-1);
+ }
+again:
+ ifr = ifc.ifc_req;
+ end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
+
+ while (ifr < end) {
+ ifreq = *ifr;
+ if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+ _RPC_close(s);
+ return(-1);
+ }
+ if (((ifreq.ifr_flags & IFF_UP) &&
+ ifr->ifr_addr.sa_family == AF_INET &&
+ !(ifreq.ifr_flags & IFF_LOOPBACK)) ||
+ (loopback == 1 && (ifreq.ifr_flags & IFF_LOOPBACK)
+ && (ifr->ifr_addr.sa_family == AF_INET)
+ && (ifreq.ifr_flags & IFF_UP))) {
+ *addr = *((struct sockaddr_in *)&ifr->ifr_addr);
+ addr->sin_port = htons(PMAPPORT);
+ gotit = 1;
+ break;
+ }
+ if (ifr->ifr_addr.sa_len)
+ ifr = (struct ifreq *) ((caddr_t) ifr +
+ ifr->ifr_addr.sa_len -
+ sizeof(struct sockaddr));
+ ifr++;
+ }
+ if (gotit == 0 && loopback == 0) {
+ loopback = 1;
+ goto again;
+ }
+ (void)_RPC_close(s);
+ return (gotit ? 0 : -1);
+}
diff --git a/cpukit/librpc/src/rpc/getrpcent.3 b/cpukit/librpc/src/rpc/getrpcent.3
new file mode 100644
index 0000000000..1e92e9d03d
--- /dev/null
+++ b/cpukit/librpc/src/rpc/getrpcent.3
@@ -0,0 +1,98 @@
+.\" @(#)getrpcent.3n 2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI
+.\" $FreeBSD: src/lib/libc/rpc/getrpcent.3,v 1.11 1999/08/28 00:00:39 peter Exp $
+.\"
+.Dd December 14, 1987
+.Dt GETRPCENT 3
+.Os
+.Sh NAME
+.Nm getrpcent ,
+.Nm getrpcbyname ,
+.Nm getrpcbynumber ,
+.Nm endrpcent ,
+.Nm setrpcent
+.Nd get RPC entry
+.Sh SYNOPSIS
+.Fd #include <rpc/rpc.h>
+.Ft struct rpcent *
+.Fn getrpcent void
+.Ft struct rpcent *
+.Fn getrpcbyname "char *name"
+.Ft struct rpcent *
+.Fn getrpcbynumber "int number"
+.Ft void
+.Fn setrpcent "int stayopen"
+.Ft void
+.Fn endrpcent void
+.Sh DESCRIPTION
+The
+.Fn getrpcent ,
+.Fn getrpcbyname ,
+and
+.Fn getrpcbynumber
+functions each return a pointer to an object with the
+following structure
+containing the broken-out
+fields of a line in the rpc program number data base,
+.Pa /etc/rpc .
+.Bd -literal
+
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ long r_number; /* rpc program number */
+};
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width r_aliasesxxx
+.It Fa r_name
+The name of the server for this rpc program.
+.It Fa r_aliases
+A zero terminated list of alternate names for the rpc program.
+.It Fa r_number
+The rpc program number for this service.
+.El
+.Pp
+The
+.Fn getrpcent
+function reads the next line of the file, opening the file if necessary.
+The
+.Nm getrpcent
+function opens and rewinds the file. If the
+.Fa stayopen
+flag is non-zero,
+the net data base will not be closed after each call to
+.Fn getrpcent
+(either directly, or indirectly through one of
+the other
+.Fn getrpcent
+function family.
+.Pp
+.Fn endrpcent
+closes the file.
+.Pp
+.Fn getrpcbyname
+and
+.Fn getrpcbynumber
+sequentially search from the beginning
+of the file until a matching rpc program name or
+program number is found, or until end-of-file is encountered.
+.Sh FILES
+.Bl -tag -width /etc/rpc -compact
+.It Pa /etc/rpc
+.El
+.Sh "SEE ALSO"
+.Xr rpc 5 ,
+.Xr rpcinfo 8 ,
+.Xr ypserv 8
+.Sh DIAGNOSTICS
+A
+.Dv NULL
+pointer is returned on
+.Dv EOF
+or error.
+.Sh BUGS
+All information
+is contained in a static area
+so it must be copied if it is
+to be saved.
diff --git a/cpukit/librpc/src/rpc/getrpcent.c b/cpukit/librpc/src/rpc/getrpcent.c
new file mode 100644
index 0000000000..e2d2e164d5
--- /dev/null
+++ b/cpukit/librpc/src/rpc/getrpcent.c
@@ -0,0 +1,302 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/getrpcent.c,v 1.10 1999/08/28 00:00:39 peter Exp $";
+#endif
+
+/*
+ * Copyright (c) 1984 by Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#ifdef YP
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+
+/*
+ * Internet version.
+ */
+struct rpcdata {
+ FILE *rpcf;
+ int stayopen;
+#define MAXALIASES 35
+ char *rpc_aliases[MAXALIASES];
+ struct rpcent rpc;
+ char line[BUFSIZ+1];
+#ifdef YP
+ char *domain;
+ char *current;
+ int currentlen;
+#endif
+} *rpcdata;
+
+#ifdef YP
+static int __yp_nomap = 0;
+extern int _yp_check(char **);
+#endif /* YP */
+
+static struct rpcent *interpret();
+struct hostent *gethostent();
+char *inet_ntoa();
+
+static char RPCDB[] = "/etc/rpc";
+
+static struct rpcdata *
+_rpcdata()
+{
+ register struct rpcdata *d = rpcdata;
+
+ if (d == 0) {
+ d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
+ rpcdata = d;
+ }
+ return (d);
+}
+
+struct rpcent *
+getrpcbynumber(number)
+ register int number;
+{
+ register struct rpcdata *d = _rpcdata();
+ register struct rpcent *p;
+#ifdef YP
+ int reason;
+ char adrstr[16];
+#endif
+
+ if (d == 0)
+ return (0);
+#ifdef YP
+ if (!__yp_nomap && _yp_check(&d->domain)) {
+ sprintf(adrstr, "%d", number);
+ reason = yp_match(d->domain, "rpc.bynumber", adrstr, strlen(adrstr),
+ &d->current, &d->currentlen);
+ switch(reason) {
+ case 0:
+ break;
+ case YPERR_MAP:
+ __yp_nomap = 1;
+ goto no_yp;
+ break;
+ default:
+ return(0);
+ break;
+ }
+ d->current[d->currentlen] = '\0';
+ p = interpret(d->current, d->currentlen);
+ (void) free(d->current);
+ return p;
+ }
+no_yp:
+#endif /* YP */
+ setrpcent(0);
+ while ((p = getrpcent())) {
+ if (p->r_number == number)
+ break;
+ }
+ endrpcent();
+ return (p);
+}
+
+struct rpcent *
+getrpcbyname(name)
+ char *name;
+{
+ struct rpcent *rpc = NULL;
+ char **rp;
+
+ setrpcent(0);
+ while ((rpc = getrpcent())) {
+ if (strcmp(rpc->r_name, name) == 0)
+ goto done;
+ for (rp = rpc->r_aliases; *rp != NULL; rp++) {
+ if (strcmp(*rp, name) == 0)
+ goto done;
+ }
+ }
+done:
+ endrpcent();
+ return (rpc);
+}
+
+void
+setrpcent(f)
+ int f;
+{
+ register struct rpcdata *d = _rpcdata();
+
+ if (d == 0)
+ return;
+#ifdef YP
+ if (!__yp_nomap && _yp_check(NULL)) {
+ if (d->current)
+ free(d->current);
+ d->current = NULL;
+ d->currentlen = 0;
+ return;
+ }
+ __yp_nomap = 0;
+#endif /* YP */
+ if (d->rpcf == NULL)
+ d->rpcf = fopen(RPCDB, "r");
+ else
+ rewind(d->rpcf);
+ d->stayopen |= f;
+}
+
+void
+endrpcent()
+{
+ register struct rpcdata *d = _rpcdata();
+
+ if (d == 0)
+ return;
+#ifdef YP
+ if (!__yp_nomap && _yp_check(NULL)) {
+ if (d->current && !d->stayopen)
+ free(d->current);
+ d->current = NULL;
+ d->currentlen = 0;
+ return;
+ }
+ __yp_nomap = 0;
+#endif /* YP */
+ if (d->rpcf && !d->stayopen) {
+ fclose(d->rpcf);
+ d->rpcf = NULL;
+ }
+}
+
+struct rpcent *
+getrpcent()
+{
+ register struct rpcdata *d = _rpcdata();
+#ifdef YP
+ struct rpcent *hp;
+ int reason;
+ char *val = NULL;
+ int vallen;
+#endif
+
+ if (d == 0)
+ return(NULL);
+#ifdef YP
+ if (!__yp_nomap && _yp_check(&d->domain)) {
+ if (d->current == NULL && d->currentlen == 0) {
+ reason = yp_first(d->domain, "rpc.bynumber",
+ &d->current, &d->currentlen,
+ &val, &vallen);
+ } else {
+ reason = yp_next(d->domain, "rpc.bynumber",
+ d->current, d->currentlen,
+ &d->current, &d->currentlen,
+ &val, &vallen);
+ }
+ switch(reason) {
+ case 0:
+ break;
+ case YPERR_MAP:
+ __yp_nomap = 1;
+ goto no_yp;
+ break;
+ default:
+ return(0);
+ break;
+ }
+ val[vallen] = '\0';
+ hp = interpret(val, vallen);
+ (void) free(val);
+ return hp;
+ }
+no_yp:
+#endif /* YP */
+ if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
+ return (NULL);
+ /* -1 so there is room to append a \n below */
+ if (fgets(d->line, BUFSIZ - 1, d->rpcf) == NULL)
+ return (NULL);
+ return (interpret(d->line, strlen(d->line)));
+}
+
+static struct rpcent *
+interpret(val, len)
+ char *val;
+ int len;
+{
+ register struct rpcdata *d = _rpcdata();
+ char *p;
+ register char *cp, **q;
+
+ if (d == 0)
+ return (0);
+ (void) strncpy(d->line, val, BUFSIZ);
+ d->line[BUFSIZ] = '\0';
+ p = d->line;
+ p[len] = '\n';
+ if (*p == '#')
+ return (getrpcent());
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ return (getrpcent());
+ *cp = '\0';
+ cp = strpbrk(p, " \t");
+ if (cp == NULL)
+ return (getrpcent());
+ *cp++ = '\0';
+ /* THIS STUFF IS INTERNET SPECIFIC */
+ d->rpc.r_name = d->line;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ d->rpc.r_number = atoi(cp);
+ q = d->rpc.r_aliases = d->rpc_aliases;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &(d->rpc_aliases[MAXALIASES - 1]))
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return (&d->rpc);
+}
diff --git a/cpukit/librpc/src/rpc/getrpcport.3 b/cpukit/librpc/src/rpc/getrpcport.3
new file mode 100644
index 0000000000..0e9175ec12
--- /dev/null
+++ b/cpukit/librpc/src/rpc/getrpcport.3
@@ -0,0 +1,31 @@
+.\" @(#)getrpcport.3r 2.2 88/08/02 4.0 RPCSRC; from 1.12 88/02/26 SMI
+.\" $FreeBSD: src/lib/libc/rpc/getrpcport.3,v 1.6 1999/08/28 00:00:40 peter Exp $
+.\"
+.Dd October 6, 1987
+.Dt GETRPCPORT 3
+.Os
+.Sh NAME
+.Nm getrpcport
+.Nd get RPC port number
+.Sh SYNOPSIS
+.Ft int
+.Fn getrpcport "char *host" "int prognum" "int versnum" "int proto"
+.Sh DESCRIPTION
+.Fn getrpcport
+returns the port number for version
+.Fa versnum
+of the RPC program
+.Fa prognum
+running on
+.Fa host
+and using protocol
+.Fa proto .
+It returns 0 if it cannot contact the portmapper, or if
+.Fa prognum
+is not registered. If
+.Fa prognum
+is registered but not with version
+.Fa versnum ,
+it will still return a port number (for some version of the program)
+indicating that the program is indeed registered.
+The version mismatch will be detected upon the first call to the service.
diff --git a/cpukit/librpc/src/rpc/getrpcport.c b/cpukit/librpc/src/rpc/getrpcport.c
new file mode 100644
index 0000000000..8d17615c66
--- /dev/null
+++ b/cpukit/librpc/src/rpc/getrpcport.c
@@ -0,0 +1,63 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getrpcport.c 1.3 87/08/11 SMI";*/
+/*static char *sccsid = "from: @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/getrpcport.c,v 1.10 1999/08/28 00:00:40 peter Exp $";
+#endif
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+int
+getrpcport(host, prognum, versnum, proto)
+ char *host;
+ int prognum, versnum, proto;
+{
+ struct sockaddr_in addr;
+ struct hostent *hp;
+
+ if ((hp = gethostbyname(host)) == NULL)
+ return (0);
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_len = sizeof(struct sockaddr_in);
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ memcpy((char *)&addr.sin_addr, hp->h_addr, hp->h_length);
+ return (pmap_getport(&addr, prognum, versnum, proto));
+}
diff --git a/cpukit/librpc/src/rpc/netname.c b/cpukit/librpc/src/rpc/netname.c
new file mode 100644
index 0000000000..22167bee86
--- /dev/null
+++ b/cpukit/librpc/src/rpc/netname.c
@@ -0,0 +1,136 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)netname.c 1.8 91/03/11 Copyr 1986 Sun Micro";
+#endif
+
+/*
+ * netname utility routines
+ * convert from unix names to network names and vice-versa
+ * This module is operating system dependent!
+ * What we define here will work with any unix system that has adopted
+ * the sun NIS domain architecture.
+ */
+
+#include <sys/param.h>
+#include <rpc/rpc.h>
+#include <rpc/rpc_com.h>
+#ifdef YP
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+#ifndef NGROUPS
+#define NGROUPS 16
+#endif
+
+static char *OPSYS = "unix";
+
+/*
+ * Figure out my fully qualified network name
+ */
+int
+getnetname(name)
+ char name[MAXNETNAMELEN+1];
+{
+ uid_t uid;
+
+ uid = geteuid();
+ if (uid == 0) {
+ return (host2netname(name, (char *) NULL, (char *) NULL));
+ } else {
+ return (user2netname(name, uid, (char *) NULL));
+ }
+}
+
+
+/*
+ * Convert unix cred to network-name
+ */
+int
+user2netname(netname, uid, domain)
+ char netname[MAXNETNAMELEN + 1];
+ uid_t uid;
+ char *domain;
+{
+ char *dfltdom;
+
+#define MAXIPRINT (11) /* max length of printed integer */
+
+ if (domain == NULL) {
+ if (_rpc_get_default_domain(&dfltdom) != 0) {
+ return (0);
+ }
+ domain = dfltdom;
+ }
+ if (strlen(domain) + 1 + MAXIPRINT > MAXNETNAMELEN) {
+ return (0);
+ }
+ (void) sprintf(netname, "%s.%ld@%s", OPSYS, (u_long)uid, domain);
+ return (1);
+}
+
+
+/*
+ * Convert host to network-name
+ */
+int
+host2netname(netname, host, domain)
+ char netname[MAXNETNAMELEN + 1];
+ char *host;
+ char *domain;
+{
+ char *dfltdom;
+ char hostname[MAXHOSTNAMELEN+1];
+
+ if (domain == NULL) {
+ if (_rpc_get_default_domain(&dfltdom) != 0) {
+ return (0);
+ }
+ domain = dfltdom;
+ }
+ if (host == NULL) {
+ (void) gethostname(hostname, sizeof(hostname));
+ host = hostname;
+ }
+ if (strlen(domain) + 1 + strlen(host) > MAXNETNAMELEN) {
+ return (0);
+ }
+ (void) sprintf(netname, "%s.%s@%s", OPSYS, host, domain);
+ return (1);
+}
diff --git a/cpukit/librpc/src/rpc/netnamer.c b/cpukit/librpc/src/rpc/netnamer.c
new file mode 100644
index 0000000000..eac9913119
--- /dev/null
+++ b/cpukit/librpc/src/rpc/netnamer.c
@@ -0,0 +1,326 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
+#endif
+/*
+ * netname utility routines convert from unix names to network names and
+ * vice-versa This module is operating system dependent! What we define here
+ * will work with any unix system that has adopted the sun NIS domain
+ * architecture.
+ */
+#include <sys/param.h>
+#include <rpc/rpc.h>
+#include <rpc/rpc_com.h>
+#ifdef YP
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+#include <ctype.h>
+#include <stdio.h>
+#include <grp.h>
+#include <pwd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static char *OPSYS = "unix";
+#ifdef YP
+static char *NETID = "netid.byname";
+#endif
+static char *NETIDFILE = "/etc/netid";
+
+static int getnetid __P(( char *, char * ));
+static int _getgroups __P(( char *, gid_t * ));
+
+#ifndef NGROUPS
+#define NGROUPS 16
+#endif
+
+/*
+ * Convert network-name into unix credential
+ */
+int
+netname2user(netname, uidp, gidp, gidlenp, gidlist)
+ char netname[MAXNETNAMELEN + 1];
+ uid_t *uidp;
+ gid_t *gidp;
+ int *gidlenp;
+ gid_t *gidlist;
+{
+ char *p;
+ int gidlen;
+ uid_t uid;
+ long luid;
+ struct passwd *pwd;
+ char val[1024];
+ char *val1, *val2;
+ char *domain;
+ int vallen;
+ int err;
+
+ if (getnetid(netname, val)) {
+ p = strtok(val, ":");
+ if (p == NULL)
+ return (0);
+ *uidp = (uid_t) atol(val);
+ p = strtok(NULL, "\n,");
+ *gidp = (gid_t) atol(p);
+ if (p == NULL) {
+ return (0);
+ }
+ gidlen = 0;
+ for (gidlen = 0; gidlen < NGROUPS; gidlen++) {
+ p = strtok(NULL, "\n,");
+ if (p == NULL)
+ break;
+ gidlist[gidlen] = (gid_t) atol(p);
+ }
+ *gidlenp = gidlen;
+
+ return (1);
+ }
+ val1 = strchr(netname, '.');
+ if (val1 == NULL)
+ return (0);
+ if (strncmp(netname, OPSYS, (val1-netname)))
+ return (0);
+ val1++;
+ val2 = strchr(val1, '@');
+ if (val2 == NULL)
+ return (0);
+ vallen = val2 - val1;
+ if (vallen > (1024 - 1))
+ vallen = 1024 - 1;
+ (void) strncpy(val, val1, 1024);
+ val[vallen] = 0;
+
+ err = _rpc_get_default_domain(&domain); /* change to rpc */
+ if (err)
+ return (0);
+
+ if (strcmp(val2 + 1, domain))
+ return (0); /* wrong domain */
+
+ if (sscanf(val, "%ld", &luid) != 1)
+ return (0);
+ uid = luid;
+
+ /* use initgroups method */
+ pwd = getpwuid(uid);
+ if (pwd == NULL)
+ return (0);
+ *uidp = pwd->pw_uid;
+ *gidp = pwd->pw_gid;
+ *gidlenp = _getgroups(pwd->pw_name, gidlist);
+ return (1);
+}
+
+/*
+ * initgroups
+ */
+
+static int
+_getgroups(uname, groups)
+ char *uname;
+ gid_t groups[NGROUPS];
+{
+ gid_t ngroups = 0;
+ register struct group *grp;
+ register int i;
+ register int j;
+ int filter;
+
+ setgrent();
+ while ((grp = getgrent())) {
+ for (i = 0; grp->gr_mem[i]; i++)
+ if (!strcmp(grp->gr_mem[i], uname)) {
+ if (ngroups == NGROUPS) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "initgroups: %s is in too many groups\n", uname);
+#endif
+ goto toomany;
+ }
+ /* filter out duplicate group entries */
+ filter = 0;
+ for (j = 0; j < ngroups; j++)
+ if (groups[j] == grp->gr_gid) {
+ filter++;
+ break;
+ }
+ if (!filter)
+ groups[ngroups++] = grp->gr_gid;
+ }
+ }
+toomany:
+ endgrent();
+ return (ngroups);
+}
+
+/*
+ * Convert network-name to hostname
+ */
+int
+netname2host(netname, hostname, hostlen)
+ char netname[MAXNETNAMELEN + 1];
+ char *hostname;
+ int hostlen;
+{
+ int err;
+ char valbuf[1024];
+ char *val;
+ char *val2;
+ int vallen;
+ char *domain;
+
+ if (getnetid(netname, valbuf)) {
+ val = valbuf;
+ if ((*val == '0') && (val[1] == ':')) {
+ (void) strncpy(hostname, val + 2, hostlen);
+ return (1);
+ }
+ }
+ val = strchr(netname, '.');
+ if (val == NULL)
+ return (0);
+ if (strncmp(netname, OPSYS, (val - netname)))
+ return (0);
+ val++;
+ val2 = strchr(val, '@');
+ if (val2 == NULL)
+ return (0);
+ vallen = val2 - val;
+ if (vallen > (hostlen - 1))
+ vallen = hostlen - 1;
+ (void) strncpy(hostname, val, vallen);
+ hostname[vallen] = 0;
+
+ err = _rpc_get_default_domain(&domain); /* change to rpc */
+ if (err)
+ return (0);
+
+ if (strcmp(val2 + 1, domain))
+ return (0); /* wrong domain */
+ else
+ return (1);
+}
+
+/*
+ * reads the file /etc/netid looking for a + to optionally go to the
+ * network information service.
+ */
+int
+getnetid(key, ret)
+ char *key, *ret;
+{
+ char buf[1024]; /* big enough */
+ char *res;
+ char *mkey;
+ char *mval;
+ FILE *fd;
+#ifdef YP
+ char *domain;
+ int err;
+ char *lookup;
+ int len;
+#endif
+
+ fd = fopen(NETIDFILE, "r");
+ if (fd == (FILE *) 0) {
+#ifdef YP
+ res = "+";
+ goto getnetidyp;
+#else
+ return (0);
+#endif
+ }
+ for (;;) {
+ if (fd == (FILE *) 0)
+ return (0); /* getnetidyp brings us here */
+ res = fgets(buf, 1024, fd);
+ if (res == 0) {
+ fclose(fd);
+ return (0);
+ }
+ if (res[0] == '#')
+ continue;
+ else if (res[0] == '+') {
+#ifdef YP
+ getnetidyp:
+ err = yp_get_default_domain(&domain);
+ if (err) {
+ continue;
+ }
+ lookup = NULL;
+ err = yp_match(domain, NETID, key,
+ strlen(key), &lookup, &len);
+ if (err) {
+#ifdef DEBUG
+ fprintf(stderr, "match failed error %d\n", err);
+#endif
+ continue;
+ }
+ lookup[len] = 0;
+ strcpy(ret, lookup);
+ free(lookup);
+ if (fd != NULL)
+ fclose(fd);
+ return (2);
+#else /* YP */
+#ifdef DEBUG
+ fprintf(stderr,
+"Bad record in %s '+' -- NIS not supported in this library copy\n",
+ NETIDFILE);
+#endif
+ continue;
+#endif /* YP */
+ } else {
+ mkey = strtok(buf, "\t ");
+ if (mkey == NULL) {
+ fprintf(stderr,
+ "Bad record in %s -- %s", NETIDFILE, buf);
+ continue;
+ }
+ mval = strtok(NULL, " \t#\n");
+ if (mval == NULL) {
+ fprintf(stderr,
+ "Bad record in %s val problem - %s", NETIDFILE, buf);
+ continue;
+ }
+ if (strcmp(mkey, key) == 0) {
+ strcpy(ret, mval);
+ fclose(fd);
+ return (1);
+
+ }
+ }
+ }
+}
diff --git a/cpukit/librpc/src/rpc/pmap_clnt.c b/cpukit/librpc/src/rpc/pmap_clnt.c
new file mode 100644
index 0000000000..b9f3550b0b
--- /dev/null
+++ b/cpukit/librpc/src/rpc/pmap_clnt.c
@@ -0,0 +1,149 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_clnt.c,v 1.11 2000/01/27 23:06:39 jasone Exp $";
+#endif
+
+/*
+ * pmap_clnt.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <netinet/in.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+void clnt_perror();
+
+#ifndef PORTMAPSOCK
+#define PORTMAPSOCK "/var/run/portmapsock"
+#endif
+
+/*
+ * Set a mapping between program,version and port.
+ * Calls the pmap service remotely to do the mapping.
+ */
+bool_t
+pmap_set(program, version, protocol, port)
+ u_long program;
+ u_long version;
+ int protocol;
+ int port; /* was u_short but changed to match prototype */
+{
+ struct sockaddr_in myaddress;
+ int socket = -1;
+ register CLIENT *client;
+ struct pmap parms;
+ bool_t rslt;
+ struct stat st;
+
+ /*
+ * Temporary hack for backwards compatibility. Eventually
+ * this test will go away and we'll use only the "unix" transport.
+ */
+ if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
+ client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
+ else {
+ if (get_myaddress(&myaddress) != 0)
+ return (FALSE);
+ myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+ timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ }
+
+ if (client == (CLIENT *)NULL)
+ return (FALSE);
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_prot = protocol;
+ parms.pm_port = port;
+ if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt,
+ tottimeout) != RPC_SUCCESS) {
+ clnt_perror(client, "Cannot register service");
+ return (FALSE);
+ }
+ CLNT_DESTROY(client);
+ if (socket != -1)
+ (void)_RPC_close(socket);
+ return (rslt);
+}
+
+/*
+ * Remove the mapping between program,version and port.
+ * Calls the pmap service remotely to do the un-mapping.
+ */
+bool_t
+pmap_unset(program, version)
+ u_long program;
+ u_long version;
+{
+ struct sockaddr_in myaddress;
+ int socket = -1;
+ register CLIENT *client;
+ struct pmap parms;
+ bool_t rslt;
+ struct stat st;
+
+ /*
+ * Temporary hack for backwards compatibility. Eventually
+ * this test will go away and we'll use only the "unix" transport.
+ */
+ if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
+ client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
+ else {
+ if (get_myaddress(&myaddress) != 0)
+ return (FALSE);
+ myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+ timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ }
+ if (client == (CLIENT *)NULL)
+ return (FALSE);
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_port = parms.pm_prot = 0;
+ CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
+ tottimeout);
+ CLNT_DESTROY(client);
+ if (socket != -1)
+ (void)_RPC_close(socket);
+ return (rslt);
+}
diff --git a/cpukit/librpc/src/rpc/pmap_getmaps.c b/cpukit/librpc/src/rpc/pmap_getmaps.c
new file mode 100644
index 0000000000..7585d683cd
--- /dev/null
+++ b/cpukit/librpc/src/rpc/pmap_getmaps.c
@@ -0,0 +1,87 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_getmaps.c,v 1.11 2000/01/27 23:06:39 jasone Exp $";
+#endif
+
+/*
+ * pmap_getmap.c
+ * Client interface to pmap rpc service.
+ * contains pmap_getmaps, which is only tcp service involved
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mbuf.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#define NAMELEN 255
+#define MAX_BROADCAST_SIZE 1400
+
+/*
+ * Get a copy of the current port maps.
+ * Calls the pmap service remotely to do get the maps.
+ */
+struct pmaplist *
+pmap_getmaps(address)
+ struct sockaddr_in *address;
+{
+ struct pmaplist *head = (struct pmaplist *)NULL;
+ int socket = -1;
+ struct timeval minutetimeout;
+ register CLIENT *client;
+
+ minutetimeout.tv_sec = 60;
+ minutetimeout.tv_usec = 0;
+ address->sin_port = htons(PMAPPORT);
+ client = clnttcp_create(address, PMAPPROG,
+ PMAPVERS, &socket, 50, 500);
+ if (client != (CLIENT *)NULL) {
+ if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist,
+ &head, minutetimeout) != RPC_SUCCESS) {
+ clnt_perror(client, "pmap_getmaps rpc problem");
+ }
+ CLNT_DESTROY(client);
+ }
+ if (socket != -1)
+ (void)_RPC_close(socket);
+ address->sin_port = 0;
+ return (head);
+}
diff --git a/cpukit/librpc/src/rpc/pmap_getport.c b/cpukit/librpc/src/rpc/pmap_getport.c
new file mode 100644
index 0000000000..31fa7689b9
--- /dev/null
+++ b/cpukit/librpc/src/rpc/pmap_getport.c
@@ -0,0 +1,92 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_getport.c,v 1.10 2000/01/27 23:06:40 jasone Exp $";
+#endif
+
+/*
+ * pmap_getport.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <sys/mbuf.h>
+#include <net/if.h>
+#include <unistd.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+/*
+ * Find the mapped port for program,version.
+ * Calls the pmap service remotely to do the lookup.
+ * Returns 0 if no map exists.
+ */
+u_short
+pmap_getport(address, program, version, protocol)
+ struct sockaddr_in *address;
+ u_long program;
+ u_long version;
+ u_int protocol;
+{
+ u_short port = 0;
+ int socket = -1;
+ register CLIENT *client;
+ struct pmap parms;
+
+ address->sin_port = htons(PMAPPORT);
+ client = clntudp_bufcreate(address, PMAPPROG,
+ PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ if (client != (CLIENT *)NULL) {
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_prot = protocol;
+ parms.pm_port = 0; /* not needed or used */
+ if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
+ xdr_u_short, &port, tottimeout) != RPC_SUCCESS){
+ rpc_createerr.cf_stat = RPC_PMAPFAILURE;
+ clnt_geterr(client, &rpc_createerr.cf_error);
+ } else if (port == 0) {
+ rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
+ }
+ CLNT_DESTROY(client);
+ }
+ if (socket != -1)
+ (void)_RPC_close(socket);
+ address->sin_port = 0;
+ return (port);
+}
diff --git a/cpukit/librpc/src/rpc/pmap_prot.c b/cpukit/librpc/src/rpc/pmap_prot.c
new file mode 100644
index 0000000000..ec7ab30812
--- /dev/null
+++ b/cpukit/librpc/src/rpc/pmap_prot.c
@@ -0,0 +1,59 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_prot.c,v 1.6 1999/08/28 00:00:42 peter Exp $";
+#endif
+
+/*
+ * pmap_prot.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+bool_t
+xdr_pmap(xdrs, regs)
+ XDR *xdrs;
+ struct pmap *regs;
+{
+
+ if (xdr_u_long(xdrs, &regs->pm_prog) &&
+ xdr_u_long(xdrs, &regs->pm_vers) &&
+ xdr_u_long(xdrs, &regs->pm_prot))
+ return (xdr_u_long(xdrs, &regs->pm_port));
+ return (FALSE);
+}
diff --git a/cpukit/librpc/src/rpc/pmap_prot2.c b/cpukit/librpc/src/rpc/pmap_prot2.c
new file mode 100644
index 0000000000..65ede28c37
--- /dev/null
+++ b/cpukit/librpc/src/rpc/pmap_prot2.c
@@ -0,0 +1,118 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_prot2.c,v 1.7 1999/08/28 00:00:42 peter Exp $";
+#endif
+
+/*
+ * pmap_prot2.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+/*
+ * What is going on with linked lists? (!)
+ * First recall the link list declaration from pmap_prot.h:
+ *
+ * struct pmaplist {
+ * struct pmap pml_map;
+ * struct pmaplist *pml_map;
+ * };
+ *
+ * Compare that declaration with a corresponding xdr declaration that
+ * is (a) pointer-less, and (b) recursive:
+ *
+ * typedef union switch (bool_t) {
+ *
+ * case TRUE: struct {
+ * struct pmap;
+ * pmaplist_t foo;
+ * };
+ *
+ * case FALSE: struct {};
+ * } pmaplist_t;
+ *
+ * Notice that the xdr declaration has no nxt pointer while
+ * the C declaration has no bool_t variable. The bool_t can be
+ * interpreted as ``more data follows me''; if FALSE then nothing
+ * follows this bool_t; if TRUE then the bool_t is followed by
+ * an actual struct pmap, and then (recursively) by the
+ * xdr union, pamplist_t.
+ *
+ * This could be implemented via the xdr_union primitive, though this
+ * would cause a one recursive call per element in the list. Rather than do
+ * that we can ``unwind'' the recursion
+ * into a while loop and do the union arms in-place.
+ *
+ * The head of the list is what the C programmer wishes to past around
+ * the net, yet is the data that the pointer points to which is interesting;
+ * this sounds like a job for xdr_reference!
+ */
+bool_t
+xdr_pmaplist(xdrs, rp)
+ register XDR *xdrs;
+ register struct pmaplist **rp;
+{
+ /*
+ * more_elements is pre-computed in case the direction is
+ * XDR_ENCODE or XDR_FREE. more_elements is overwritten by
+ * xdr_bool when the direction is XDR_DECODE.
+ */
+ bool_t more_elements;
+ register int freeing = (xdrs->x_op == XDR_FREE);
+ register struct pmaplist **next = NULL;
+
+ while (TRUE) {
+ more_elements = (bool_t)(*rp != NULL);
+ if (! xdr_bool(xdrs, &more_elements))
+ return (FALSE);
+ if (! more_elements)
+ return (TRUE); /* we are done */
+ /*
+ * the unfortunate side effect of non-recursion is that in
+ * the case of freeing we must remember the next object
+ * before we free the current object ...
+ */
+ if (freeing)
+ next = &((*rp)->pml_next);
+ if (! xdr_reference(xdrs, (caddr_t *)rp,
+ (u_int)sizeof(struct pmaplist), (xdrproc_t) xdr_pmap))
+ return (FALSE);
+ rp = (freeing) ? next : &((*rp)->pml_next);
+ }
+}
diff --git a/cpukit/librpc/src/rpc/pmap_rmt.c b/cpukit/librpc/src/rpc/pmap_rmt.c
new file mode 100644
index 0000000000..ec737a93a1
--- /dev/null
+++ b/cpukit/librpc/src/rpc/pmap_rmt.c
@@ -0,0 +1,434 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_rmt.c,v 1.15 2000/01/27 23:06:40 jasone Exp $";
+#endif
+
+/*
+ * pmap_rmt.c
+ * Client interface to pmap rpc service.
+ * remote call and broadcast service
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <rpc/pmap_rmt.h>
+
+#include <stdlib.h>
+#include <sys/select.h>
+
+#define MAX_BROADCAST_SIZE 1400
+
+static const struct timeval timeout = { 3, 0 };
+
+/*
+ * pmapper remote-call-service interface.
+ * This routine is used to call the pmapper remote call service
+ * which will look up a service program in the port maps, and then
+ * remotely call that routine with the given parameters. This allows
+ * programs to do a lookup and call in one step.
+*/
+enum clnt_stat
+pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout,
+ port_ptr)
+ struct sockaddr_in *addr;
+ u_long prog, vers, proc;
+ xdrproc_t xdrargs, xdrres;
+ caddr_t argsp, resp;
+ struct timeval tout;
+ u_long *port_ptr;
+{
+ int sock = -1;
+ CLIENT *client;
+ struct rmtcallargs a;
+ struct rmtcallres r;
+ enum clnt_stat stat;
+
+ assert(addr != NULL);
+ assert(port_ptr != NULL);
+
+ addr->sin_port = htons(PMAPPORT);
+ client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &sock);
+ if (client != NULL) {
+ a.prog = prog;
+ a.vers = vers;
+ a.proc = proc;
+ a.args_ptr = argsp;
+ a.xdr_args = xdrargs;
+ r.port_ptr = port_ptr;
+ r.results_ptr = resp;
+ r.xdr_results = xdrres;
+ stat = CLNT_CALL(client, (rpcproc_t)PMAPPROC_CALLIT,
+ (xdrproc_t)xdr_rmtcall_args, &a, (xdrproc_t)xdr_rmtcallres,
+ &r, tout);
+ CLNT_DESTROY(client);
+ } else {
+ stat = RPC_FAILED;
+ }
+ if (sock != -1)
+ (void)_RPC_close(sock);
+ addr->sin_port = 0;
+ return (stat);
+}
+
+
+/*
+ * XDR remote call arguments
+ * written for XDR_ENCODE direction only
+ */
+bool_t
+xdr_rmtcall_args(xdrs, cap)
+ XDR *xdrs;
+ struct rmtcallargs *cap;
+{
+ u_int lenposition, argposition, position;
+
+ assert(xdrs != NULL);
+ assert(cap != NULL);
+
+ if (xdr_u_long(xdrs, &(cap->prog)) &&
+ xdr_u_long(xdrs, &(cap->vers)) &&
+ xdr_u_long(xdrs, &(cap->proc))) {
+ lenposition = XDR_GETPOS(xdrs);
+ if (! xdr_u_long(xdrs, &(cap->arglen)))
+ return (FALSE);
+ argposition = XDR_GETPOS(xdrs);
+ if (! (*(cap->xdr_args))(xdrs, cap->args_ptr))
+ return (FALSE);
+ position = XDR_GETPOS(xdrs);
+ cap->arglen = (u_long)position - (u_long)argposition;
+ XDR_SETPOS(xdrs, lenposition);
+ if (! xdr_u_long(xdrs, &(cap->arglen)))
+ return (FALSE);
+ XDR_SETPOS(xdrs, position);
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR remote call results
+ * written for XDR_DECODE direction only
+ */
+bool_t
+xdr_rmtcallres(xdrs, crp)
+ XDR *xdrs;
+ struct rmtcallres *crp;
+{
+ caddr_t port_ptr;
+
+ assert(xdrs != NULL);
+ assert(crp != NULL);
+
+ port_ptr = (caddr_t)(void *)crp->port_ptr;
+ if (xdr_reference(xdrs, &port_ptr, sizeof (u_long),
+ (xdrproc_t)xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) {
+ crp->port_ptr = (u_long *)(void *)port_ptr;
+ return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
+ }
+ return (FALSE);
+}
+
+
+/*
+ * The following is kludged-up support for simple rpc broadcasts.
+ * Someday a large, complicated system will replace these trivial
+ * routines which only support udp/ip .
+ */
+
+static int
+getbroadcastnets(addrs, sock, buf)
+ struct in_addr *addrs;
+ int sock; /* any valid socket will do */
+ char *buf; /* why allocxate more when we can use existing... */
+{
+ struct ifconf ifc;
+ struct ifreq ifreq, *ifr;
+ struct sockaddr_in *sin;
+ struct in_addr addr;
+ char *cp, *cplim;
+ int n, i = 0;
+
+ ifc.ifc_len = UDPMSGSIZE;
+ ifc.ifc_buf = buf;
+ if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+ perror("broadcast: ioctl (get interface configuration)");
+ return (0);
+ }
+#define max(a, b) (a > b ? a : b)
+#define size(p) max((p).sa_len, sizeof(p))
+ cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
+ for (cp = buf; cp < cplim;
+ cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
+ ifr = (struct ifreq *)cp;
+ if (ifr->ifr_addr.sa_family != AF_INET)
+ continue;
+ ifreq = *ifr;
+ if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+ perror("broadcast: ioctl (get interface flags)");
+ continue;
+ }
+ if ((ifreq.ifr_flags & IFF_BROADCAST) &&
+ (ifreq.ifr_flags & IFF_UP)) {
+ sin = (struct sockaddr_in *)&ifr->ifr_addr;
+#ifdef SIOCGIFBRDADDR /* 4.3BSD */
+ if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
+ addr =
+ inet_makeaddr(inet_netof(sin->sin_addr),
+ INADDR_ANY);
+ } else {
+ addr = ((struct sockaddr_in*)
+ &ifreq.ifr_addr)->sin_addr;
+ }
+#else /* 4.2 BSD */
+ addr = inet_makeaddr(inet_netof(sin->sin_addr),
+ INADDR_ANY);
+#endif
+ for (n=i-1; n>=0; n--) {
+ if (addr.s_addr == addrs[n].s_addr)
+ break;
+ }
+ if (n<0) {
+ addrs[i++] = addr;
+ }
+ }
+ }
+ return (i);
+}
+
+typedef bool_t (*resultproc_t)();
+
+enum clnt_stat
+clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
+ u_long prog; /* program number */
+ u_long vers; /* version number */
+ u_long proc; /* procedure number */
+ xdrproc_t xargs; /* xdr routine for args */
+ caddr_t argsp; /* pointer to args */
+ xdrproc_t xresults; /* xdr routine for results */
+ caddr_t resultsp; /* pointer to results */
+ resultproc_t eachresult; /* call with each result obtained */
+{
+ enum clnt_stat stat = RPC_SUCCESS; /* to avoid warning */
+ AUTH *unix_auth = authunix_create_default();
+ XDR xdr_stream;
+ register XDR *xdrs = &xdr_stream;
+ int outlen, inlen, nets;
+ socklen_t fromlen;
+ register int sock;
+ int on = 1;
+ fd_set *fds = 0, readfds; /* initialized to avoid warning */
+ register int i;
+ bool_t done = FALSE;
+ register u_long xid;
+ u_long port;
+ struct in_addr addrs[20];
+ struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
+ struct rmtcallargs a;
+ struct rmtcallres r;
+ struct rpc_msg msg;
+ struct timeval t, tv;
+ char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
+ static u_int32_t disrupt;
+
+ if (disrupt == 0)
+ disrupt = (u_int32_t)(long)resultsp;
+
+ /*
+ * initialization: create a socket, a broadcast address, and
+ * preserialize the arguments into a send buffer.
+ */
+ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ perror("Cannot create socket for broadcast rpc");
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+#ifdef SO_BROADCAST
+ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
+ perror("Cannot set socket option SO_BROADCAST");
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+#endif /* def SO_BROADCAST */
+ if (sock + 1 > FD_SETSIZE) {
+ int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL) {
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+ memset(fds, 0, bytes);
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ nets = getbroadcastnets(addrs, sock, inbuf);
+ memset(&baddr, 0, sizeof (baddr));
+ baddr.sin_len = sizeof(struct sockaddr_in);
+ baddr.sin_family = AF_INET;
+ baddr.sin_port = htons(PMAPPORT);
+ baddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ (void)gettimeofday(&t, (struct timezone *)0);
+ msg.rm_xid = xid = (++disrupt) ^ getpid() ^ t.tv_sec ^ t.tv_usec;
+ t.tv_usec = 0;
+ msg.rm_direction = CALL;
+ msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ msg.rm_call.cb_prog = PMAPPROG;
+ msg.rm_call.cb_vers = PMAPVERS;
+ msg.rm_call.cb_proc = PMAPPROC_CALLIT;
+ msg.rm_call.cb_cred = unix_auth->ah_cred;
+ msg.rm_call.cb_verf = unix_auth->ah_verf;
+ a.prog = prog;
+ a.vers = vers;
+ a.proc = proc;
+ a.xdr_args = xargs;
+ a.args_ptr = argsp;
+ r.port_ptr = &port;
+ r.xdr_results = xresults;
+ r.results_ptr = resultsp;
+ xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE);
+ if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) {
+ stat = RPC_CANTENCODEARGS;
+ goto done_broad;
+ }
+ outlen = (int)xdr_getpos(xdrs);
+ xdr_destroy(xdrs);
+ /*
+ * Basic loop: broadcast a packet and wait a while for response(s).
+ * The response timeout grows larger per iteration.
+ *
+ * XXX This will loop about 5 times the stop. If there are
+ * lots of signals being received by the process it will quit
+ * send them all in one quick burst, not paying attention to
+ * the intended function of sending them slowly over half a
+ * minute or so
+ */
+ for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) {
+ for (i = 0; i < nets; i++) {
+ baddr.sin_addr = addrs[i];
+ if (sendto(sock, outbuf, outlen, 0,
+ (struct sockaddr *)&baddr,
+ sizeof (struct sockaddr)) != outlen) {
+ perror("Cannot send broadcast packet");
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+ }
+ if (eachresult == NULL) {
+ stat = RPC_SUCCESS;
+ goto done_broad;
+ }
+ recv_again:
+ msg.acpted_rply.ar_verf = _null_auth;
+ msg.acpted_rply.ar_results.where = (caddr_t)&r;
+ msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_rmtcallres;
+ /* XXX we know the other bits are still clear */
+ FD_SET(sock, fds);
+ tv = t; /* for select() that copies back */
+ switch (select(sock + 1, fds, NULL, NULL, &tv)) {
+
+ case 0: /* timed out */
+ stat = RPC_TIMEDOUT;
+ continue;
+
+ case -1: /* some kind of error */
+ if (errno == EINTR)
+ goto recv_again;
+ perror("Broadcast select problem");
+ stat = RPC_CANTRECV;
+ goto done_broad;
+
+ } /* end of select results switch */
+ try_again:
+ fromlen = sizeof(struct sockaddr);
+ inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0,
+ (struct sockaddr *)&raddr, &fromlen);
+ if (inlen < 0) {
+ if (errno == EINTR)
+ goto try_again;
+ perror("Cannot receive reply to broadcast");
+ stat = RPC_CANTRECV;
+ goto done_broad;
+ }
+ if (inlen < sizeof(u_int32_t))
+ goto recv_again;
+ /*
+ * see if reply transaction id matches sent id.
+ * If so, decode the results.
+ */
+ xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
+ if (xdr_replymsg(xdrs, &msg)) {
+ if ((msg.rm_xid == xid) &&
+ (msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
+ (msg.acpted_rply.ar_stat == SUCCESS)) {
+ raddr.sin_port = htons((u_short)port);
+ done = (*eachresult)(resultsp, &raddr);
+ }
+ /* otherwise, we just ignore the errors ... */
+ }
+ xdrs->x_op = XDR_FREE;
+ msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
+ (void)xdr_replymsg(xdrs, &msg);
+ (void)(*xresults)(xdrs, resultsp);
+ xdr_destroy(xdrs);
+ if (done) {
+ stat = RPC_SUCCESS;
+ goto done_broad;
+ } else {
+ goto recv_again;
+ }
+ }
+done_broad:
+ if (fds != &readfds)
+ free(fds);
+ if (sock >= 0)
+ (void)_RPC_close(sock);
+ AUTH_DESTROY(unix_auth);
+ return (stat);
+}
diff --git a/cpukit/librpc/src/rpc/publickey.3 b/cpukit/librpc/src/rpc/publickey.3
new file mode 100644
index 0000000000..29094f98b2
--- /dev/null
+++ b/cpukit/librpc/src/rpc/publickey.3
@@ -0,0 +1,47 @@
+.\" @(#)publickey.3r 2.1 88/08/07 4.0 RPCSRC
+.\" $FreeBSD: src/lib/libc/rpc/publickey.3,v 1.4 2000/03/02 09:13:46 sheldonh Exp $
+.\"
+.TH PUBLICKEY 3R "6 October 1987"
+.SH NAME
+publickey, getpublickey, getsecretkey \- get public or secret key
+.SH SYNOPSIS
+.nf
+.B #include <rpc/rpc.h>
+.B #include <rpc/key_prot.h>
+.LP
+.B getpublickey(netname, publickey)
+.B char netname[\s-1MAXNETNAMELEN\s0+1];
+.B char publickey[\s-1HEXKEYBYTES\s0+1];
+.LP
+.B getsecretkey(netname, secretkey, passwd)
+.B char netname[\s-1MAXNETNAMELEN\s0+1];
+.B char secretkey[\s-1HEXKEYBYTES\s0+1];
+.B char *passwd;
+.fi
+.SH DESCRIPTION
+.IX "getpublickey function" "" "\fLgetpublickey()\fP function"
+.IX "getsecretkey function" "" "\fLgetsecretkey()\fP function"
+These routines are used to get public and secret keys from the
+.SM YP
+database.
+.B getsecretkey(\|)
+has an extra argument,
+.IR passwd ,
+which is used to decrypt the encrypted secret key stored in the database.
+Both routines return 1 if they are successful in finding the key, 0 otherwise.
+The keys are returned as
+.SM NULL\s0-terminated,
+hexadecimal strings.
+If the password supplied to
+.B getsecretkey(\|)
+fails to decrypt the secret key, the routine will return 1 but the
+.I secretkey
+argument will be a
+.SM NULL
+string (``'').
+.SH "SEE ALSO"
+.BR publickey (5)
+.LP
+.I \s-1RPC\s0 Programmer's Manual
+in
+.TX NETP
diff --git a/cpukit/librpc/src/rpc/publickey.5 b/cpukit/librpc/src/rpc/publickey.5
new file mode 100644
index 0000000000..9f7a325488
--- /dev/null
+++ b/cpukit/librpc/src/rpc/publickey.5
@@ -0,0 +1,38 @@
+.\" $FreeBSD: src/lib/libc/rpc/publickey.5,v 1.5 2000/03/02 09:13:46 sheldonh Exp $
+.\" @(#)publickey.5 2.1 88/08/07 4.0 RPCSRC; from 1.6 88/02/29 SMI;
+.TH PUBLICKEY 5 "19 October 1987"
+.SH NAME
+publickey \- public key database
+.SH SYNOPSIS
+.B /etc/publickey
+.SH DESCRIPTION
+.LP
+.B /etc/publickey
+is the public key database used for secure
+networking.
+Each entry in
+the database consists of a network user
+name (which may either refer to
+a user or a hostname), followed by the user's
+public key (in hex
+notation), a colon, and then the user's
+secret key encrypted with
+its login password (also in hex notation).
+.LP
+This file is altered either by the user through the
+.BR chkey (1)
+command or by the system administrator through the
+.BR newkey (8)
+command.
+The file
+.B /etc/publickey
+should only contain data on the NIS master machine, where it
+is converted into the
+.SM NIS
+database
+.BR publickey.byname .
+.SH SEE ALSO
+.BR chkey (1),
+.BR publickey (3R),
+.BR newkey (8),
+.BR ypupdated (8C)
diff --git a/cpukit/librpc/src/rpc/rpc.3 b/cpukit/librpc/src/rpc/rpc.3
new file mode 100644
index 0000000000..f40b643827
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rpc.3
@@ -0,0 +1,1767 @@
+.\" @(#)rpc.3n 2.4 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI
+.\" $FreeBSD: src/lib/libc/rpc/rpc.3,v 1.11 2000/03/02 09:13:47 sheldonh Exp $
+.\"
+.TH RPC 3 "16 February 1988"
+.SH NAME
+rpc \- library routines for remote procedure calls
+.SH SYNOPSIS AND DESCRIPTION
+These routines allow C programs to make procedure
+calls on other machines across the network.
+First, the client calls a procedure to send a
+data packet to the server.
+Upon receipt of the packet, the server calls a dispatch routine
+to perform the requested service, and then sends back a
+reply.
+Finally, the procedure call returns to the client.
+.LP
+Routines that are used for Secure RPC (DES authentication) are described in
+.BR rpc_secure (3).
+Secure RPC can be used only if DES encryption is available.
+.LP
+.ft B
+.nf
+.sp .5
+#include <rpc/rpc.h>
+.fi
+.ft R
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+auth_destroy(auth)
+\s-1AUTH\s0 *auth;
+.fi
+.ft R
+.IP
+A macro that destroys the authentication information associated with
+.IR auth .
+Destruction usually involves deallocation of private data
+structures.
+The use of
+.I auth
+is undefined after calling
+.BR auth_destroy(\|) .
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authnone_create(\|)
+.fi
+.ft R
+.IP
+Create and returns an
+.SM RPC
+authentication handle that passes nonusable authentication
+information with each remote procedure call.
+This is the
+default authentication used by
+.SM RPC.
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authunix_create(host, uid, gid, len, aup_gids)
+char *host;
+int uid, gid, len, *aup.gids;
+.fi
+.ft R
+.IP
+Create and return an
+.SM RPC
+authentication handle that contains
+.UX
+authentication information.
+The parameter
+.I host
+is the name of the machine on which the information was
+created;
+.I uid
+is the user's user
+.SM ID ;
+.I gid
+is the user's current group
+.SM ID ;
+.I len
+and
+.I aup_gids
+refer to a counted array of groups to which the user belongs.
+It is easy to impersonate a user.
+.br
+.if t .ne 5
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authunix_create_default(\|)
+.fi
+.ft R
+.IP
+Calls
+.B authunix_create(\|)
+with the appropriate parameters.
+.br
+.if t .ne 13
+.LP
+.ft B
+.nf
+.sp .5
+callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
+char *host;
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+.fi
+.ft R
+.IP
+Call the remote procedure associated with
+.IR prognum ,
+.IR versnum ,
+and
+.I procnum
+on the machine,
+.IR host .
+The parameter
+.I in
+is the address of the procedure's argument(s), and
+.I out
+is the address of where to place the result(s);
+.I inproc
+is used to encode the procedure's parameters, and
+.I outproc
+is used to decode the procedure's results.
+This routine returns zero if it succeeds, or the value of
+.B "enum clnt_stat"
+cast to an integer if it fails.
+The routine
+.B clnt_perrno(\|)
+is handy for translating failure statuses into messages.
+.IP
+Warning: calling remote procedures with this routine
+uses
+.SM UDP/IP
+as a transport; see
+.B clntudp_create(\|)
+for restrictions.
+You do not have control of timeouts or authentication using
+this routine.
+.br
+.if t .ne 16
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+clnt_broadcast(prognum, versnum, procnum, inproc, in, outproc, out, eachresult)
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+resultproc_t eachresult;
+.fi
+.ft R
+.IP
+Like
+.BR callrpc(\|) ,
+except the call message is broadcast to all locally
+connected broadcast nets.
+Each time it receives a
+response, this routine calls
+.BR eachresult(\|) ,
+whose form is:
+.IP
+.RS 1i
+.ft B
+.nf
+eachresult(out, addr)
+char *out;
+struct sockaddr_in *addr;
+.ft R
+.fi
+.RE
+.IP
+where
+.I out
+is the same as
+.I out
+passed to
+.BR clnt_broadcast(\|) ,
+except that the remote procedure's output is decoded there;
+.I addr
+points to the address of the machine that sent the results.
+If
+.B eachresult(\|)
+returns zero,
+.B clnt_broadcast(\|)
+waits for more replies; otherwise it returns with appropriate
+status.
+.IP
+Warning: broadcast sockets are limited in size to the
+maximum transfer unit of the data link.
+For ethernet,
+this value is 1500 bytes.
+.br
+.if t .ne 13
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+clnt_call(clnt, procnum, inproc, in, outproc, out, tout)
+\s-1CLIENT\s0 *clnt;
+u_long
+procnum;
+xdrproc_t inproc, outproc;
+char *in, *out;
+struct timeval tout;
+.fi
+.ft R
+.IP
+A macro that calls the remote procedure
+.I procnum
+associated with the client handle,
+.IR clnt ,
+which is obtained with an
+.SM RPC
+client creation routine such as
+.BR clnt_create(\|) .
+The parameter
+.I in
+is the address of the procedure's argument(s), and
+.I out
+is the address of where to place the result(s);
+.I inproc
+is used to encode the procedure's parameters, and
+.I outproc
+is used to decode the procedure's results;
+.I tout
+is the time allowed for results to come back.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+clnt_destroy(clnt)
+\s-1CLIENT\s0 *clnt;
+.fi
+.ft R
+.IP
+A macro that destroys the client's
+.SM RPC
+handle.
+Destruction usually involves deallocation
+of private data structures, including
+.I clnt
+itself. Use of
+.I clnt
+is undefined after calling
+.BR clnt_destroy(\|) .
+If the
+.SM RPC
+library opened the associated socket, it will close it also.
+Otherwise, the socket remains open.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clnt_create(host, prog, vers, proto)
+char *host;
+u_long prog, vers;
+char *proto;
+.fi
+.ft R
+.IP
+Generic client creation routine.
+.I host
+identifies the name of the remote host where the server
+is located.
+.I proto
+indicates which kind of transport protocol to use.
+The
+currently supported values for this field are \(lqudp\(rq
+and \(lqtcp\(rq.
+Default timeouts are set, but can be modified using
+.BR clnt_control(\|) .
+.IP
+Warning: Using
+.SM UDP
+has its shortcomings. Since
+.SM UDP\s0-based
+.SM RPC
+messages can only hold up to 8 Kbytes of encoded data,
+this transport cannot be used for procedures that take
+large arguments or return huge results.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+bool_t
+clnt_control(cl, req, info)
+\s-1CLIENT\s0 *cl;
+u_int req;
+char *info;
+.fi
+.ft R
+.IP
+A macro used to change or retrieve various information
+about a client object.
+.I req
+indicates the type of operation, and
+.I info
+is a pointer to the information.
+For both
+.SM UDP
+and
+.SM TCP\s0,
+the supported values of
+.I req
+and their argument types and what they do are:
+.IP
+.nf
+.ta +2.0i +2.0i +2.0i
+.SM CLSET_TIMEOUT\s0 struct timeval set total timeout
+.SM CLGET_TIMEOUT\s0 struct timeval get total timeout
+.fi
+.IP
+Note: if you set the timeout using
+.BR clnt_control(\|) ,
+the timeout parameter passed to
+.B clnt_call(\|)
+will be ignored in all future calls.
+.IP
+.nf
+.SM CLGET_SERVER_ADDR\s0 struct sockaddr_in get server's address
+.fi
+.br
+.IP
+The following operations are valid for
+.SM UDP
+only:
+.IP
+.nf
+.ta +2.0i ; +2.0i ; +2.0i
+.SM CLSET_RETRY_TIMEOUT\s0 struct timeval set the retry timeout
+.SM CLGET_RETRY_TIMEOUT\s0 struct timeval get the retry timeout
+.fi
+.br
+.IP
+The retry timeout is the time that
+.SM "UDP RPC"
+waits for the server to reply before
+retransmitting the request.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+clnt_freeres(clnt, outproc, out)
+\s-1CLIENT\s0 *clnt;
+xdrproc_t outproc;
+char *out;
+.fi
+.ft R
+.IP
+A macro that frees any data allocated by the
+.SM RPC/XDR
+system when it decoded the results of an
+.SM RPC
+call. The
+parameter
+.I out
+is the address of the results, and
+.I outproc
+is the
+.SM XDR
+routine describing the results.
+This routine returns one if the results were successfully
+freed,
+and zero otherwise.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_geterr(clnt, errp)
+\s-1CLIENT\s0 *clnt;
+struct rpc_err *errp;
+.fi
+.ft R
+.IP
+A macro that copies the error structure out of the client
+handle
+to the structure at address
+.IR errp .
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_pcreateerror(s)
+char *s;
+.fi
+.ft R
+.IP
+Print a message to standard error indicating
+why a client
+.SM RPC
+handle could not be created.
+The message is prepended with string
+.I s
+and a colon.
+Used when a
+.BR clnt_create(\|) ,
+.BR clntraw_create(\|) ,
+.BR clnttcp_create(\|) ,
+or
+.B clntudp_create(\|)
+call fails.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_perrno(stat)
+enum clnt_stat stat;
+.fi
+.ft R
+.IP
+Print a message to standard error corresponding
+to the condition indicated by
+.IR stat .
+Used after
+.BR callrpc(\|) .
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+clnt_perror(clnt, s)
+\s-1CLIENT\s0 *clnt;
+char *s;
+.fi
+.ft R
+.IP
+Print a message to standard error indicating why an
+.SM RPC
+call failed;
+.I clnt
+is the handle used to do the call.
+The message is prepended with string
+.I s
+and a colon.
+Used after
+.BR clnt_call(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_spcreateerror
+char *s;
+.fi
+.ft R
+.IP
+Like
+.BR clnt_pcreateerror(\|) ,
+except that it returns a string
+instead of printing to the standard error.
+.IP
+Bugs: returns pointer to static data that is overwritten
+on each call.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_sperrno(stat)
+enum clnt_stat stat;
+.fi
+.ft R
+.IP
+Take the same arguments as
+.BR clnt_perrno(\|) ,
+but instead of sending a message to the standard error
+indicating why an
+.SM RPC
+call failed, return a pointer to a string which contains
+the message. The string ends with a
+.SM NEWLINE\s0.
+.IP
+.B clnt_sperrno(\|)
+is used instead of
+.B clnt_perrno(\|)
+if the program does not have a standard error (as a program
+running as a server quite likely does not), or if the
+programmer
+does not want the message to be output with
+.BR printf ,
+or if a message format different from that supported by
+.B clnt_perrno(\|)
+is to be used.
+Note: unlike
+.B clnt_sperror(\|)
+and
+.BR clnt_spcreaterror(\|) ,
+.B clnt_sperrno(\|)
+returns pointer to static data, but the
+result will not get overwritten on each call.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_sperror(rpch, s)
+\s-1CLIENT\s0 *rpch;
+char *s;
+.fi
+.ft R
+.IP
+Like
+.BR clnt_perror(\|) ,
+except that (like
+.BR clnt_sperrno(\|) )
+it returns a string instead of printing to standard error.
+.IP
+Bugs: returns pointer to static data that is overwritten
+on each call.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntraw_create(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+This routine creates a toy
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum .
+The transport used to pass messages to the service is
+actually a buffer within the process's address space, so the
+corresponding
+.SM RPC
+server should live in the same address space; see
+.BR svcraw_create(\|) .
+This allows simulation of
+.SM RPC
+and acquisition of
+.SM RPC
+overheads, such as round trip times, without any
+kernel interference.
+This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clnttcp_create(addr, prognum, versnum, sockp, sendsz, recvsz)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+int *sockp;
+u_int sendsz, recvsz;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum ;
+the client uses
+.SM TCP/IP
+as a transport.
+The remote program is located at Internet
+address
+.IR *addr .
+If
+.\"The following in-line font conversion is necessary for the hyphen indicator
+\fB\%addr\->sin_port\fR
+is zero, then it is set to the actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.IR sockp .
+Since
+.SM TCP\s0-based
+.SM RPC
+uses buffered
+.SM I/O ,
+the user may specify the size of the send and receive buffers
+with the parameters
+.I sendsz
+and
+.IR recvsz ;
+values of zero choose suitable defaults.
+This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntudp_create(addr, prognum, versnum, wait, sockp)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+struct timeval wait;
+int *sockp;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum ;
+the client uses
+.SM UDP/IP
+as a transport.
+The remote program is located at Internet
+address
+.IR addr .
+If
+\fB\%addr\->sin_port\fR
+is zero, then it is set to actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.IR sockp .
+The
+.SM UDP
+transport resends the call message in intervals of
+.B wait
+time until a response is received or until the call times
+out.
+The total time for the call to time out is specified by
+.BR clnt_call(\|) .
+.IP
+Warning: since
+.SM UDP\s0-based
+.SM RPC
+messages can only hold up to 8 Kbytes
+of encoded data, this transport cannot be used for procedures
+that take large arguments or return huge results.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntudp_bufcreate(addr, prognum, versnum, wait, sockp, sendsize, recosize)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+struct timeval wait;
+int *sockp;
+unsigned int sendsize;
+unsigned int recosize;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+on
+.IR versnum ;
+the client uses
+.SM UDP/IP
+as a transport.
+The remote program is located at Internet
+address
+.IR addr .
+If
+\fB\%addr\->sin_port\fR
+is zero, then it is set to actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.BR sockp .
+The
+.SM UDP
+transport resends the call message in intervals of
+.B wait
+time until a response is received or until the call times
+out.
+The total time for the call to time out is specified by
+.BR clnt_call(\|) .
+.IP
+This allows the user to specify the maximum packet size for sending and receiving
+.SM UDP\s0-based
+.SM RPC
+messages.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+int
+get_myaddress(addr)
+struct sockaddr_in *addr;
+.fi
+.ft R
+.IP
+Stuff the machine's
+.SM IP
+address into
+.IR *addr ,
+without consulting the library routines that deal with
+.BR /etc/hosts .
+The port number is always set to
+.BR htons(\s-1PMAPPORT\s0) .
+Returns zero on success, non-zero on failure.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+struct pmaplist *
+pmap_getmaps(addr)
+struct sockaddr_in *addr;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which returns a list of the current
+.SM RPC
+program-to-port mappings
+on the host located at
+.SM IP
+address
+.IR *addr .
+This routine can return
+.SM NULL .
+The command
+.RB ` "rpcinfo \-p" '
+uses this routine.
+.br
+.if t .ne 12
+.LP
+.ft B
+.nf
+.sp .5
+u_short
+pmap_getport(addr, prognum, versnum, protocol)
+struct sockaddr_in *addr;
+u_long prognum, versnum, protocol;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which returns the port number
+on which waits a service that supports program number
+.IR prognum ,
+version
+.IR versnum ,
+and speaks the transport protocol associated with
+.IR protocol .
+The value of
+.I protocol
+is most likely
+.B
+.SM IPPROTO_UDP
+or
+.BR \s-1IPPROTO_TCP\s0 .
+A return value of zero means that the mapping does not exist
+or that
+the
+.SM RPC
+system failed to contact the remote
+.B portmap
+service. In the latter case, the global variable
+.B rpc_createerr(\|)
+contains the
+.SM RPC
+status.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+pmap_rmtcall(addr, prognum, versnum, procnum, inproc, in, outproc, out, tout, portp)
+struct sockaddr_in *addr;
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+struct timeval tout;
+u_long *portp;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which instructs
+.B portmap
+on the host at
+.SM IP
+address
+.I *addr
+to make an
+.SM RPC
+call on your behalf to a procedure on that host.
+The parameter
+.I *portp
+will be modified to the program's port number if the
+procedure
+succeeds.
+The definitions of other parameters are discussed
+in
+.B callrpc(\|)
+and
+.BR clnt_call(\|) .
+This procedure should be used for a \(lqping\(rq and nothing
+else.
+See also
+.BR clnt_broadcast(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+pmap_set(prognum, versnum, protocol, port)
+u_long prognum, versnum, protocol;
+u_short port;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which establishes a mapping between the triple
+.RI [ prognum , versnum , protocol\fR]
+and
+.I port
+on the machine's
+.B portmap
+service.
+The value of
+.I protocol
+is most likely
+.B
+.SM IPPROTO_UDP
+or
+.BR \s-1IPPROTO_TCP\s0 .
+This routine returns one if it succeeds, zero otherwise.
+Automatically done by
+.BR svc_register(\|) .
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+pmap_unset(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which destroys all mapping between the triple
+.RI [ prognum , versnum , *\fR]
+and
+.B ports
+on the machine's
+.B portmap
+service.
+This routine returns one if it succeeds, zero
+otherwise.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+registerrpc(prognum, versnum, procnum, procname, inproc, outproc)
+u_long prognum, versnum, procnum;
+char *(*procname) (\|) ;
+xdrproc_t inproc, outproc;
+.fi
+.ft R
+.IP
+Register procedure
+.I procname
+with the
+.SM RPC
+service package. If a request arrives for program
+.IR prognum ,
+version
+.IR versnum ,
+and procedure
+.IR procnum ,
+.I procname
+is called with a pointer to its parameter(s);
+.I progname
+should return a pointer to its static result(s);
+.I inproc
+is used to decode the parameters while
+.I outproc
+is used to encode the results.
+This routine returns zero if the registration succeeded, \-1
+otherwise.
+.IP
+Warning: remote procedures registered in this form
+are accessed using the
+.SM UDP/IP
+transport; see
+.B svcudp_create(\|)
+for restrictions.
+.br
+.if t .ne 5
+.LP
+.ft B
+.nf
+.sp .5
+struct rpc_createerr rpc_createerr;
+.fi
+.ft R
+.IP
+A global variable whose value is set by any
+.SM RPC
+client creation routine
+that does not succeed. Use the routine
+.B clnt_pcreateerror(\|)
+to print the reason why.
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+svc_destroy(xprt)
+\s-1SVCXPRT\s0 *
+xprt;
+.fi
+.ft R
+.IP
+A macro that destroys the
+.SM RPC
+service transport handle,
+.IR xprt .
+Destruction usually involves deallocation
+of private data structures, including
+.I xprt
+itself. Use of
+.I xprt
+is undefined after calling this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+fd_set svc_fdset;
+.fi
+.ft R
+.IP
+A global variable reflecting the
+.SM RPC
+service side's
+read file descriptor bit mask; it is suitable as a template parameter
+to the
+.B select
+system call.
+This is only of interest
+if a service implementor does not call
+.BR svc_run(\|) ,
+but rather does his own asynchronous event processing.
+This variable is read-only (do not pass its address to
+.BR select !),
+yet it may change after calls to
+.B svc_getreqset(\|)
+or any creation routines.
+.br
+As well, note that if the process has descriptor limits
+which are extended beyond
+.BR FD_SETSIZE ,
+this variable will only be usable for the first
+.BR FD_SETSIZE
+descriptors.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+int svc_fds;
+.fi
+.ft R
+.IP
+Similar to
+.BR svc_fedset(\|) ,
+but limited to 32 descriptors.
+This
+interface is obsoleted by
+.BR svc_fdset(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_freeargs(xprt, inproc, in)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t inproc;
+char *in;
+.fi
+.ft R
+.IP
+A macro that frees any data allocated by the
+.SM RPC/XDR
+system when it decoded the arguments to a service procedure
+using
+.BR svc_getargs(\|) .
+This routine returns 1 if the results were successfully
+freed,
+and zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+svc_getargs(xprt, inproc, in)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t inproc;
+char *in;
+.fi
+.ft R
+.IP
+A macro that decodes the arguments of an
+.SM RPC
+request
+associated with the
+.SM RPC
+service transport handle,
+.IR xprt .
+The parameter
+.I in
+is the address where the arguments will be placed;
+.I inproc
+is the
+.SM XDR
+routine used to decode the arguments.
+This routine returns one if decoding succeeds, and zero
+otherwise.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+struct sockaddr_in *
+svc_getcaller(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+The approved way of getting the network address of the caller
+of a procedure associated with the
+.SM RPC
+service transport handle,
+.IR xprt .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_getreqset(rdfds)
+fd_set *rdfds;
+.fi
+.ft R
+.IP
+This routine is only of interest if a service implementor
+does not call
+.BR svc_run(\|) ,
+but instead implements custom asynchronous event processing.
+It is called when the
+.B select
+system call has determined that an
+.SM RPC
+request has arrived on some
+.SM RPC
+.B socket(s) ;
+.I rdfds
+is the resultant read file descriptor bit mask.
+The routine returns when all sockets associated with the
+value of
+.I rdfds
+have been serviced.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+svc_getreq(rdfds)
+int rdfds;
+.fi
+.ft R
+.IP
+Similar to
+.BR svc_getreqset(\|) ,
+but limited to 32 descriptors.
+This interface is obsoleted by
+.BR svc_getreqset(\|) .
+.br
+.if t .ne 17
+.LP
+.ft B
+.nf
+.sp .5
+svc_register(xprt, prognum, versnum, dispatch, protocol)
+\s-1SVCXPRT\s0 *xprt;
+u_long prognum, versnum;
+void (*dispatch) (\|);
+u_long protocol;
+.fi
+.ft R
+.IP
+Associates
+.I prognum
+and
+.I versnum
+with the service dispatch procedure,
+.IR dispatch .
+If
+.I protocol
+is zero, the service is not registered with the
+.B portmap
+service. If
+.I protocol
+is non-zero, then a mapping of the triple
+.RI [ prognum , versnum , protocol\fR]
+to
+\fB\%xprt\->xp_port\fR
+is established with the local
+.B portmap
+service (generally
+.I protocol
+is zero,
+.B
+.SM IPPROTO_UDP
+or
+.B
+.SM IPPROTO_TCP
+).
+The procedure
+.I dispatch
+has the following form:
+.RS 1i
+.ft B
+.nf
+dispatch(request, xprt)
+struct svc_req *request;
+\s-1SVCXPRT\s0 *xprt;
+.ft R
+.fi
+.RE
+.IP
+The
+.B svc_register(\|)
+routine returns one if it succeeds, and zero otherwise.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+svc_run(\|)
+.fi
+.ft R
+.IP
+This routine never returns.
+It waits for
+.SM RPC
+requests to arrive, and calls the appropriate service
+procedure using
+.B svc_getreq(\|)
+when one arrives.
+This procedure is usually waiting for a
+.B select(\|)
+system call to return.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_sendreply(xprt, outproc, out)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t outproc;
+char *out;
+.fi
+.ft R
+.IP
+Called by an
+.SM RPC
+service's dispatch routine to send the results of a
+remote procedure call. The parameter
+.I xprt
+is the request's associated transport handle;
+.I outproc
+is the
+.SM XDR
+routine which is used to encode the results; and
+.I out
+is the address of the results.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svc_unregister(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+Remove all mapping of the double
+.RI [ prognum , versnum ]
+to dispatch routines, and of the triple
+.RI [ prognum , versnum , *\fR]
+to port number.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_auth(xprt, why)
+\s-1SVCXPRT\s0 *xprt;
+enum auth_stat why;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that refuses to perform
+a remote procedure call due to an authentication error.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_decode(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that cannot successfully
+decode its parameters.
+See also
+.BR svc_getargs(\|) .
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_noproc(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that does not implement
+the procedure number that the caller requests.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_noprog(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called when the desired program is not registered with the
+.SM RPC
+package.
+Service implementors usually do not need this routine.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_progvers(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called when the desired version of a program is not registered
+with the
+.SM RPC
+package.
+Service implementors usually do not need this routine.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_systemerr(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine when it detects a system
+error
+not covered by any particular protocol.
+For example, if a service can no longer allocate storage,
+it may call this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_weakauth(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that refuses to perform
+a remote procedure call due to insufficient
+authentication parameters. The routine calls
+.BR "svcerr_auth(xprt, \s-1AUTH_TOOWEAK\s0)" .
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcraw_create(\|)
+.fi
+.ft R
+.IP
+This routine creates a toy
+.SM RPC
+service transport, to which it returns a pointer. The
+transport
+is really a buffer within the process's address space,
+so the corresponding
+.SM RPC
+client should live in the same
+address space;
+see
+.BR clntraw_create(\|) .
+This routine allows simulation of
+.SM RPC
+and acquisition of
+.SM RPC
+overheads (such as round trip times), without any kernel
+interference.
+This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svctcp_create(sock, send_buf_size, recv_buf_size)
+int sock;
+u_int send_buf_size, recv_buf_size;
+.fi
+.ft R
+.IP
+This routine creates a
+.SM TCP/IP\s0-based
+.SM RPC
+service transport, to which it returns a pointer.
+The transport is associated with the socket
+.IR sock ,
+which may be
+.BR \s-1RPC_ANYSOCK\s0 ,
+in which case a new socket is created.
+If the socket is not bound to a local
+.SM TCP
+port, then this routine binds it to an arbitrary port. Upon
+completion,
+\fB\%xprt\->xp_sock\fR
+is the transport's socket descriptor, and
+\fB\%xprt\->xp_port\fR
+is the transport's port number.
+This routine returns
+.SM NULL
+if it fails.
+Since
+.SM TCP\s0-based
+.SM RPC
+uses buffered
+.SM I/O ,
+users may specify the size of buffers; values of zero
+choose suitable defaults.
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcfd_create(fd, sendsize, recvsize)
+int fd;
+u_int sendsize;
+u_int recvsize;
+.fi
+.ft R
+.IP
+Create a service on top of any open descriptor.
+Typically,
+this
+descriptor is a connected socket for a stream protocol such
+as
+.SM TCP\s0.
+.I sendsize
+and
+.I recvsize
+indicate sizes for the send and receive buffers. If they are
+zero, a reasonable default is chosen.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcudp_bufcreate(sock, sendsize, recosize)
+int sock;
+.fi
+.ft R
+.IP
+This routine creates a
+.SM UDP/IP\s0-based
+.SM RPC
+service transport, to which it returns a pointer.
+The transport is associated with the socket
+.IR sock ,
+which may be
+.B \s-1RPC_ANYSOCK\s0 ,
+in which case a new socket is created.
+If the socket is not bound to a local
+.SM UDP
+port, then this routine binds it to an arbitrary port.
+Upon
+completion,
+\fB\%xprt\->xp_sock\fR
+is the transport's socket descriptor, and
+\fB\%xprt\->xp_port\fR
+is the transport's port number.
+This routine returns
+.SM NULL
+if it fails.
+.IP
+This allows the user to specify the maximum packet size for sending and
+receiving
+.SM UDP\s0-based
+.SM RPC messages.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_accepted_reply(xdrs, ar)
+\s-1XDR\s0 *xdrs;
+struct accepted_reply *ar;
+.fi
+.ft R
+.IP
+Used for encoding
+.SM RPC
+reply messages.
+This routine is useful for users who
+wish to generate
+\s-1RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_authunix_parms(xdrs, aupp)
+\s-1XDR\s0 *xdrs;
+struct authunix_parms *aupp;
+.fi
+.ft R
+.IP
+Used for describing
+.SM UNIX
+credentials.
+This routine is useful for users
+who wish to generate these credentials without using the
+.SM RPC
+authentication package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdr_callhdr(xdrs, chdr)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *chdr;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+call header messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_callmsg(xdrs, cmsg)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *cmsg;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+call messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_opaque_auth(xdrs, ap)
+\s-1XDR\s0 *xdrs;
+struct opaque_auth *ap;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+authentication information messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_pmap(xdrs, regs)
+\s-1XDR\s0 *xdrs;
+struct pmap *regs;
+.fi
+.ft R
+.IP
+Used for describing parameters to various
+.B portmap
+procedures, externally.
+This routine is useful for users who wish to generate
+these parameters without using the
+.B pmap
+interface.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_pmaplist(xdrs, rp)
+\s-1XDR\s0 *xdrs;
+struct pmaplist **rp;
+.fi
+.ft R
+.IP
+Used for describing a list of port mappings, externally.
+This routine is useful for users who wish to generate
+these parameters without using the
+.B pmap
+interface.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_rejected_reply(xdrs, rr)
+\s-1XDR\s0 *xdrs;
+struct rejected_reply *rr;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+reply messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_replymsg(xdrs, rmsg)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *rmsg;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+reply messages.
+This routine is useful for users who wish to generate
+.SM RPC
+style messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+xprt_register(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+After
+.SM RPC
+service transport handles are created,
+they should register themselves with the
+.SM RPC
+service package.
+This routine modifies the global variable
+.BR svc_fds(\|) .
+Service implementors usually do not need this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+xprt_unregister(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Before an
+.SM RPC
+service transport handle is destroyed,
+it should unregister itself with the
+.SM RPC
+service package.
+This routine modifies the global variable
+.BR svc_fds(\|) .
+Service implementors usually do not need this routine.
+.SH SEE ALSO
+.BR rpc_secure (3),
+.BR xdr (3)
+.br
+The following manuals:
+.RS
+.ft I
+Remote Procedure Calls: Protocol Specification
+.br
+Remote Procedure Call Programming Guide
+.br
+rpcgen Programming Guide
+.br
+.ft R
+.RE
+.IR "\s-1RPC\s0: Remote Procedure Call Protocol Specification" ,
+.SM RFC1050, Sun Microsystems, Inc.,
+.SM USC-ISI\s0.
+
diff --git a/cpukit/librpc/src/rpc/rpc.5 b/cpukit/librpc/src/rpc/rpc.5
new file mode 100644
index 0000000000..36f895dbf2
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rpc.5
@@ -0,0 +1,35 @@
+.\" $FreeBSD: src/lib/libc/rpc/rpc.5,v 1.6 1999/08/28 00:00:44 peter Exp $
+.\" @(#)rpc.5 2.2 88/08/03 4.0 RPCSRC; from 1.4 87/11/27 SMI;
+.Dd September 26, 1985
+.Dt RPC 5
+.Sh NAME
+.Nm rpc
+.Nd rpc program number data base
+.Sh SYNOPSIS
+/etc/rpc
+.Sh DESCRIPTION
+The
+.Pa /etc/rpc
+file contains user readable names that
+can be used in place of rpc program numbers.
+Each line has the following information:
+.Pp
+.Bl -bullet -compact
+.It
+name of server for the rpc program
+.It
+rpc program number
+.It
+aliases
+.El
+.Pp
+Items are separated by any number of blanks and/or
+tab characters.
+A ``#'' indicates the beginning of a comment; characters up to the end of
+the line are not interpreted by routines which search the file.
+.Sh FILES
+.Bl -tag -compact -width /etc/rpc
+.Pa /etc/rpc
+.El
+.Sh "SEE ALSO"
+.Xr getrpcent 3
diff --git a/cpukit/librpc/src/rpc/rpc_callmsg.c b/cpukit/librpc/src/rpc/rpc_callmsg.c
new file mode 100644
index 0000000000..495ddca819
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rpc_callmsg.c
@@ -0,0 +1,192 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_callmsg.c,v 1.9 1999/08/28 00:00:45 peter Exp $";
+#endif
+
+/*
+ * rpc_callmsg.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+
+#include <sys/param.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+/*
+ * XDR a call message
+ */
+bool_t
+xdr_callmsg(xdrs, cmsg)
+ register XDR *xdrs;
+ register struct rpc_msg *cmsg;
+{
+ register int32_t *buf;
+ register struct opaque_auth *oa;
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT
+ + RNDUP(cmsg->rm_call.cb_cred.oa_length)
+ + 2 * BYTES_PER_XDR_UNIT
+ + RNDUP(cmsg->rm_call.cb_verf.oa_length));
+ if (buf != NULL) {
+ IXDR_PUT_LONG(buf, cmsg->rm_xid);
+ IXDR_PUT_ENUM(buf, cmsg->rm_direction);
+ if (cmsg->rm_direction != CALL) {
+ return (FALSE);
+ }
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers);
+ if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+ return (FALSE);
+ }
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog);
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers);
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc);
+ oa = &cmsg->rm_call.cb_cred;
+ IXDR_PUT_ENUM(buf, oa->oa_flavor);
+ IXDR_PUT_LONG(buf, oa->oa_length);
+ if (oa->oa_length) {
+ memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
+ buf += RNDUP(oa->oa_length) / sizeof (int32_t);
+ }
+ oa = &cmsg->rm_call.cb_verf;
+ IXDR_PUT_ENUM(buf, oa->oa_flavor);
+ IXDR_PUT_LONG(buf, oa->oa_length);
+ if (oa->oa_length) {
+ memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
+ /* no real need....
+ buf += RNDUP(oa->oa_length) / sizeof (int32_t);
+ */
+ }
+ return (TRUE);
+ }
+ }
+ if (xdrs->x_op == XDR_DECODE) {
+ buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
+ if (buf != NULL) {
+ cmsg->rm_xid = IXDR_GET_LONG(buf);
+ cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
+ if (cmsg->rm_direction != CALL) {
+ return (FALSE);
+ }
+ cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
+ if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+ return (FALSE);
+ }
+ cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
+ cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
+ cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
+ oa = &cmsg->rm_call.cb_cred;
+ oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+ oa->oa_length = IXDR_GET_LONG(buf);
+ if (oa->oa_length) {
+ if (oa->oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ if (oa->oa_base == NULL) {
+ oa->oa_base = (caddr_t)
+ mem_alloc(oa->oa_length);
+ }
+ buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+ if (buf == NULL) {
+ if (xdr_opaque(xdrs, oa->oa_base,
+ oa->oa_length) == FALSE) {
+ return (FALSE);
+ }
+ } else {
+ memcpy(oa->oa_base, (caddr_t)buf,
+ oa->oa_length);
+ /* no real need....
+ buf += RNDUP(oa->oa_length) /
+ sizeof (int32_t);
+ */
+ }
+ }
+ oa = &cmsg->rm_call.cb_verf;
+ buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
+ xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
+ return (FALSE);
+ }
+ } else {
+ oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+ oa->oa_length = IXDR_GET_LONG(buf);
+ }
+ if (oa->oa_length) {
+ if (oa->oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ if (oa->oa_base == NULL) {
+ oa->oa_base = (caddr_t)
+ mem_alloc(oa->oa_length);
+ }
+ buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+ if (buf == NULL) {
+ if (xdr_opaque(xdrs, oa->oa_base,
+ oa->oa_length) == FALSE) {
+ return (FALSE);
+ }
+ } else {
+ memcpy(oa->oa_base, (caddr_t)buf,
+ oa->oa_length);
+ /* no real need...
+ buf += RNDUP(oa->oa_length) /
+ sizeof (int32_t);
+ */
+ }
+ }
+ return (TRUE);
+ }
+ }
+ if (
+ xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) &&
+ xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+ (cmsg->rm_direction == CALL) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+ (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_proc)) &&
+ xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
+ return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
+ return (FALSE);
+}
diff --git a/cpukit/librpc/src/rpc/rpc_commondata.c b/cpukit/librpc/src/rpc/rpc_commondata.c
new file mode 100644
index 0000000000..bbe6003337
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rpc_commondata.c
@@ -0,0 +1,41 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_commondata.c,v 1.7 1999/08/28 00:00:45 peter Exp $";
+#endif
+
+#include <rpc/rpc.h>
+/*
+ * This file should only contain common data (global data) that is exported
+ * by public interfaces
+ */
+struct opaque_auth _null_auth;
+struct rpc_createerr rpc_createerr;
diff --git a/cpukit/librpc/src/rpc/rpc_dtablesize.c b/cpukit/librpc/src/rpc/rpc_dtablesize.c
new file mode 100644
index 0000000000..e07c0b6568
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rpc_dtablesize.c
@@ -0,0 +1,61 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";*/
+/*static char *sccsid = "from: @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_dtablesize.c,v 1.10 1999/08/28 00:00:45 peter Exp $";
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+
+/*
+ * Cache the result of getdtablesize(), so we don't have to do an
+ * expensive system call every time.
+ */
+/*
+ * XXX In FreeBSD 2.x, you can have the maximum number of open file
+ * descriptors be greater than FD_SETSIZE (which us 256 by default).
+ *
+ * Since old programs tend to use this call to determine the first arg
+ * for select(), having this return > FD_SETSIZE is a Bad Idea(TM)!
+ */
+int
+_rpc_dtablesize(void)
+{
+ static int size;
+
+ if (size == 0) {
+ size = getdtablesize();
+ if (size > FD_SETSIZE)
+ size = FD_SETSIZE;
+ }
+ return (size);
+}
diff --git a/cpukit/librpc/src/rpc/rpc_prot.c b/cpukit/librpc/src/rpc/rpc_prot.c
new file mode 100644
index 0000000000..11a1ad2dcd
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rpc_prot.c
@@ -0,0 +1,321 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_prot.c,v 1.8 1999/08/28 00:00:46 peter Exp $";
+#endif
+
+/*
+ * rpc_prot.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements the rpc message definition,
+ * its serializer and some common rpc utility routines.
+ * The routines are meant for various implementations of rpc -
+ * they are NOT for the rpc client or rpc service implementations!
+ * Because authentication stuff is easy and is part of rpc, the opaque
+ * routines are also in this program.
+ */
+
+#include <sys/param.h>
+
+#include <rpc/rpc.h>
+
+static void accepted(enum accept_stat, struct rpc_err *);
+static void rejected(enum reject_stat, struct rpc_err *);
+
+/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
+
+extern struct opaque_auth _null_auth;
+
+/*
+ * XDR an opaque authentication struct
+ * (see auth.h)
+ */
+bool_t
+xdr_opaque_auth(xdrs, ap)
+ XDR *xdrs;
+ struct opaque_auth *ap;
+{
+
+ if (xdr_enum(xdrs, &(ap->oa_flavor)))
+ return (xdr_bytes(xdrs, &ap->oa_base,
+ &ap->oa_length, MAX_AUTH_BYTES));
+ return (FALSE);
+}
+
+/*
+ * XDR a DES block
+ */
+bool_t
+xdr_des_block(xdrs, blkp)
+ XDR *xdrs;
+ des_block *blkp;
+{
+ return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
+}
+
+/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
+
+/*
+ * XDR the MSG_ACCEPTED part of a reply message union
+ */
+bool_t
+xdr_accepted_reply(xdrs, ar)
+ XDR *xdrs;
+ struct accepted_reply *ar;
+{
+
+ /* personalized union, rather than calling xdr_union */
+ if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
+ return (FALSE);
+ if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
+ return (FALSE);
+ switch (ar->ar_stat) {
+
+ case SUCCESS:
+ return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
+
+ case PROG_MISMATCH:
+ if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low)))
+ return (FALSE);
+ return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high)));
+
+ case GARBAGE_ARGS:
+ case SYSTEM_ERR:
+ case PROC_UNAVAIL:
+ case PROG_UNAVAIL:
+/* default: */
+ break;
+ }
+ return (TRUE); /* TRUE => open ended set of problems */
+}
+
+/*
+ * XDR the MSG_DENIED part of a reply message union
+ */
+bool_t
+xdr_rejected_reply(xdrs, rr)
+ XDR *xdrs;
+ struct rejected_reply *rr;
+{
+
+ /* personalized union, rather than calling xdr_union */
+ if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
+ return (FALSE);
+ switch (rr->rj_stat) {
+
+ case RPC_MISMATCH:
+ if (! xdr_u_int32_t(xdrs, &(rr->rj_vers.low)))
+ return (FALSE);
+ return (xdr_u_int32_t(xdrs, &(rr->rj_vers.high)));
+
+ case AUTH_ERROR:
+ return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
+ }
+ return (FALSE);
+}
+
+static const struct xdr_discrim reply_dscrm[3] = {
+ { (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply },
+ { (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply },
+ { __dontcare__, NULL_xdrproc_t } };
+
+/*
+ * XDR a reply message
+ */
+bool_t
+xdr_replymsg(xdrs, rmsg)
+ XDR *xdrs;
+ struct rpc_msg *rmsg;
+{
+ if (
+ xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
+ xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
+ (rmsg->rm_direction == REPLY) )
+ return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
+ (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
+ return (FALSE);
+}
+
+
+/*
+ * Serializes the "static part" of a call message header.
+ * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
+ * The rm_xid is not really static, but the user can easily munge on the fly.
+ */
+bool_t
+xdr_callhdr(xdrs, cmsg)
+ XDR *xdrs;
+ struct rpc_msg *cmsg;
+{
+
+ cmsg->rm_direction = CALL;
+ cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ if (
+ (xdrs->x_op == XDR_ENCODE) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) &&
+ xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) )
+ return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)));
+ return (FALSE);
+}
+
+/* ************************** Client utility routine ************* */
+
+static void
+accepted(acpt_stat, error)
+ enum accept_stat acpt_stat;
+ struct rpc_err *error;
+{
+
+ switch (acpt_stat) {
+
+ case PROG_UNAVAIL:
+ error->re_status = RPC_PROGUNAVAIL;
+ return;
+
+ case PROG_MISMATCH:
+ error->re_status = RPC_PROGVERSMISMATCH;
+ return;
+
+ case PROC_UNAVAIL:
+ error->re_status = RPC_PROCUNAVAIL;
+ return;
+
+ case GARBAGE_ARGS:
+ error->re_status = RPC_CANTDECODEARGS;
+ return;
+
+ case SYSTEM_ERR:
+ error->re_status = RPC_SYSTEMERROR;
+ return;
+
+ case SUCCESS:
+ error->re_status = RPC_SUCCESS;
+ return;
+ }
+ /* something's wrong, but we don't know what ... */
+ error->re_status = RPC_FAILED;
+ error->re_lb.s1 = (long)MSG_ACCEPTED;
+ error->re_lb.s2 = (long)acpt_stat;
+}
+
+static void
+rejected(rjct_stat, error)
+ enum reject_stat rjct_stat;
+ struct rpc_err *error;
+{
+
+ switch (rjct_stat) {
+
+ case RPC_VERSMISMATCH:
+ error->re_status = RPC_VERSMISMATCH;
+ return;
+
+ case AUTH_ERROR:
+ error->re_status = RPC_AUTHERROR;
+ return;
+ default:
+ break;
+ }
+ /* something's wrong, but we don't know what ... */
+ error->re_status = RPC_FAILED;
+ error->re_lb.s1 = (long)MSG_DENIED;
+ error->re_lb.s2 = (long)rjct_stat;
+}
+
+/*
+ * given a reply message, fills in the error
+ */
+void
+_seterr_reply(msg, error)
+ struct rpc_msg *msg;
+ struct rpc_err *error;
+{
+
+ /* optimized for normal, SUCCESSful case */
+ switch (msg->rm_reply.rp_stat) {
+
+ case MSG_ACCEPTED:
+ if (msg->acpted_rply.ar_stat == SUCCESS) {
+ error->re_status = RPC_SUCCESS;
+ return;
+ }
+ accepted(msg->acpted_rply.ar_stat, error);
+ break;
+
+ case MSG_DENIED:
+ rejected(msg->rjcted_rply.rj_stat, error);
+ break;
+
+ default:
+ error->re_status = RPC_FAILED;
+ error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
+ break;
+ }
+ switch (error->re_status) {
+
+ case RPC_VERSMISMATCH:
+ error->re_vers.low = msg->rjcted_rply.rj_vers.low;
+ error->re_vers.high = msg->rjcted_rply.rj_vers.high;
+ break;
+
+ case RPC_AUTHERROR:
+ error->re_why = msg->rjcted_rply.rj_why;
+ break;
+
+ case RPC_PROGVERSMISMATCH:
+ error->re_vers.low = msg->acpted_rply.ar_vers.low;
+ error->re_vers.high = msg->acpted_rply.ar_vers.high;
+ break;
+
+ case RPC_FAILED:
+ case RPC_SUCCESS:
+ case RPC_PROGNOTREGISTERED:
+ case RPC_PMAPFAILURE:
+ case RPC_UNKNOWNPROTO:
+ case RPC_UNKNOWNHOST:
+ case RPC_SYSTEMERROR:
+ case RPC_CANTDECODEARGS:
+ case RPC_PROCUNAVAIL:
+ case RPC_PROGUNAVAIL:
+ case RPC_TIMEDOUT:
+ case RPC_CANTRECV:
+ case RPC_CANTSEND:
+ case RPC_CANTDECODERES:
+ case RPC_CANTENCODEARGS:
+ default:
+ break;
+ }
+}
diff --git a/cpukit/librpc/src/rpc/rpc_secure.3 b/cpukit/librpc/src/rpc/rpc_secure.3
new file mode 100644
index 0000000000..4efd9b8614
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rpc_secure.3
@@ -0,0 +1,254 @@
+.\" @(#)rpc_secure.3n 2.1 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI
+.\" $FreeBSD: src/lib/libc/rpc/rpc_secure.3,v 1.6 2000/03/02 09:13:48 sheldonh Exp $
+.\"
+.Dd February 16, 1988
+.Dt RPC 3
+.Sh NAME
+.Nm rpc_secure
+.Nd library routines for secure remote procedure calls
+.Sh SYNOPSIS
+.Fd #include <rpc/rpc.h>
+.Ft AUTH *
+.Fo authdes_create
+.Fa "char *name"
+.Fa "unsigned window"
+.Fa "struct sockaddr *addr"
+.Fa "des_block *ckey"
+.Fc
+.Ft int
+.Fn authdes_getucred "struct authdes_cred *adc" "uid_t *uid" "gid_t *gid" "int *grouplen" "gid_t *groups"
+.Ft int
+.Fn getnetname "char *name"
+.Ft int
+.Fn host2netname "char *name" "char *host" "char *domain"
+.Ft int
+.Fn key_decryptsession "const char *remotename" "des_block *deskey"
+.Ft int
+.Fn key_encryptsession "const char *remotename" "des_block *deskey"
+.Ft int
+.Fn key_gendes "des_block *deskey"
+.Ft int
+.Fn key_setsecret "const char *key"
+.Ft int
+.Fn netname2host "char *name" "char *host" "int hostlen"
+.Ft int
+.Fn netname2user "char *name" "uid_t *uidp" "gid_t *gidp" "int *gidlenp" "gid_t *gidlist"
+.Ft int
+.Fn user2netname "char *name" "uid_t uid" "char *domain"
+.Sh DESCRIPTION
+These routines are part of the
+.Tn RPC
+library. They implement
+.Tn DES
+Authentication. See
+.Xr rpc 3
+for further details about
+.Tn RPC .
+.Pp
+The
+.Fn authdes_create
+is the first of two routines which interface to the
+.Tn RPC
+secure authentication system, known as
+.Tn DES
+authentication.
+The second is
+.Fn authdes_getucred ,
+below.
+.Pp
+Note: the keyserver daemon
+.Xr keyserv 8
+must be running for the
+.Tn DES
+authentication system to work.
+.Pp
+.Fn Authdes_create ,
+used on the client side, returns an authentication handle that
+will enable the use of the secure authentication system.
+The first parameter
+.Fa name
+is the network name, or
+.Fa netname ,
+of the owner of the server process.
+This field usually
+represents a
+.Fa hostname
+derived from the utility routine
+.Fn host2netname ,
+but could also represent a user name using
+.Fn user2netname .
+The second field is window on the validity of
+the client credential, given in seconds. A small
+window is more secure than a large one, but choosing
+too small of a window will increase the frequency of
+resynchronizations because of clock drift.
+The third
+parameter
+.Fa addr
+is optional. If it is
+.Dv NULL ,
+then the authentication system will assume
+that the local clock is always in sync with the server's
+clock, and will not attempt resynchronizations.
+If an address
+is supplied, however, then the system will use the address
+for consulting the remote time service whenever
+resynchronization
+is required.
+This parameter is usually the
+address of the
+.Tn RPC
+server itself.
+The final parameter
+.Fa ckey
+is also optional. If it is
+.Dv NULL ,
+then the authentication system will
+generate a random
+.Tn DES
+key to be used for the encryption of credentials.
+If it is supplied, however, then it will be used instead.
+.Pp
+.Fn Authdes_getucred ,
+the second of the two
+.Tn DES
+authentication routines,
+is used on the server side for converting a
+.Tn DES
+credential, which is
+operating system independent, into a
+.Ux
+credential.
+This routine differs from utility routine
+.Fn netname2user
+in that
+.Fn authdes_getucred
+pulls its information from a cache, and does not have to do a
+Yellow Pages lookup every time it is called to get its information.
+.Pp
+.Fn Getnetname
+installs the unique, operating-system independent netname of
+the
+caller in the fixed-length array
+.Fa name .
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails.
+.Pp
+.Fn Host2netname
+converts from a domain-specific hostname to an
+operating-system independent netname.
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails.
+Inverse of
+.Fn netname2host .
+.Pp
+.Fn Key_decryptsession
+is an interface to the keyserver daemon, which is associated
+with
+.Tn RPC Ns 's
+secure authentication system (
+.Tn DES
+authentication).
+User programs rarely need to call it, or its associated routines
+.Fn key_encryptsession ,
+.Fn key_gendes
+and
+.Fn key_setsecret .
+System commands such as
+.Xr login 1
+and the
+.Tn RPC
+library are the main clients of these four routines.
+.Pp
+.Fn Key_decryptsession
+takes a server netname and a
+.Tn DES
+key, and decrypts the key by
+using the the public key of the the server and the secret key
+associated with the effective uid of the calling process. It
+is the inverse of
+.Fn key_encryptsession .
+.Pp
+.Fn Key_encryptsession
+is a keyserver interface routine.
+It
+takes a server netname and a des key, and encrypts
+it using the public key of the the server and the secret key
+associated with the effective uid of the calling process. It
+is the inverse of
+.Fn key_decryptsession .
+.Pp
+.Fn Key_gendes
+is a keyserver interface routine.
+It
+is used to ask the keyserver for a secure conversation key.
+Choosing one
+.Qq random
+is usually not good enough,
+because
+the common ways of choosing random numbers, such as using the
+current time, are very easy to guess.
+.Pp
+.Fn Key_setsecret
+is a keyserver interface routine.
+It is used to set the key for
+the effective
+.Fa uid
+of the calling process.
+.Pp
+.Fn Netname2host
+converts from an operating-system independent netname to a
+domain-specific hostname.
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails. Inverse of
+.Fn host2netname .
+.Pp
+.Fn Netname2user
+converts from an operating-system independent netname to a
+domain-specific user ID.
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails.
+Inverse of
+.Fn user2netname .
+.Pp
+.Fn User2netname
+converts from a domain-specific username to an operating-system
+independent netname.
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails.
+Inverse of
+.Fn netname2user .
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr xdr 3 ,
+.Xr keyserv 8
+.Pp
+The following manuals:
+.Rs
+.%B Remote Procedure Calls: Protocol Specification
+.Re
+.Rs
+.%B Remote Procedure Call Programming Guide
+.Re
+.Rs
+.%B Rpcgen Programming Guide
+.Re
+.Rs
+.%B RPC: Remote Procedure Call Protocol Specification
+.%O RFC1050, Sun Microsystems Inc., USC-ISI
+.Re
diff --git a/cpukit/librpc/src/rpc/rpcdname.c b/cpukit/librpc/src/rpc/rpcdname.c
new file mode 100644
index 0000000000..10886d2226
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rpcdname.c
@@ -0,0 +1,80 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpcdname.c 1.7 91/03/11 Copyr 1989 Sun Micro";
+#endif
+
+/*
+ * rpcdname.c
+ * Gets the default domain name
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+int getdomainname(char *, size_t);
+
+#define default_domain (rtems_rpc_task_variables->rpcdname_default_domain)
+
+static char *
+get_default_domain()
+{
+ char temp[256];
+
+ if (default_domain)
+ return (default_domain);
+ if (getdomainname(temp, sizeof(temp)) < 0)
+ return (0);
+ if (strlen(temp) > 0) {
+ default_domain = (char *)malloc((strlen(temp)+(size_t)1));
+ if (default_domain == 0)
+ return (0);
+ (void) strcpy(default_domain, temp);
+ return (default_domain);
+ }
+ return (0);
+}
+
+/*
+ * This is a wrapper for the system call getdomainname which returns a
+ * ypclnt.h error code in the failure case. It also checks to see that
+ * the domain name is non-null, knowing that the null string is going to
+ * get rejected elsewhere in the NIS client package.
+ */
+int
+_rpc_get_default_domain(
+ char **domain )
+{
+ if ((*domain = get_default_domain()) != 0)
+ return (0);
+ return (-1);
+}
diff --git a/cpukit/librpc/src/rpc/rstat.1 b/cpukit/librpc/src/rpc/rstat.1
new file mode 100644
index 0000000000..6cc47c26c8
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rstat.1
@@ -0,0 +1,58 @@
+.\" $FreeBSD: src/lib/libc/rpc/rstat.1,v 1.5 1999/08/28 00:00:46 peter Exp $
+.\" @(#)rstat.1 2.1 88/08/03 4.0 RPCSRC
+.TH RSTAT 1 "3 August 1988"
+.SH NAME
+rstat \- remote status display
+.SH SYNOPSIS
+.B rstat
+.B host
+.SH DESCRIPTION
+.LP
+.B rstat
+displays a summary of the current system status of a particular
+.BR host .
+The output shows the current time of day, how long the system has
+been up,
+and the load averages.
+The load average numbers give the number of jobs in the run queue
+averaged over 1, 5 and 15 minutes.
+.PP
+The
+.B rstat_svc(8)
+daemon must be running on the remote host for this command to
+work.
+.B rstat
+uses an RPC protocol defined in /usr/include/rpcsvc/rstat.x.
+.SH EXAMPLE
+.RS
+.ft B
+.nf
+example% rstat otherhost
+7:36am up 6 days, 16:45, load average: 0.20, 0.23, 0.18
+example%
+.ft R
+.fi
+.RE
+.SH DIAGNOSTICS
+.LP
+rstat: RPC: Program not registered
+.IP
+The
+.B rstat_svc
+daemon has not been started on the remote host.
+.LP
+rstat: RPC: Timed out
+.IP
+A communication error occurred. Either the network is
+excessively congested, or the
+.B rstat_svc
+daemon has terminated on the remote host.
+.LP
+rstat: RPC: Port mapper failure - RPC: Timed out
+.IP
+The remote host is not running the portmapper (see
+.BR portmap(8) ),
+and cannot accommodate any RPC-based services. The host may be down.
+.SH "SEE ALSO"
+.BR portmap (8),
+.BR rstat_svc (8)
diff --git a/cpukit/librpc/src/rpc/rstat_svc.8 b/cpukit/librpc/src/rpc/rstat_svc.8
new file mode 100644
index 0000000000..e2eae8be3d
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rstat_svc.8
@@ -0,0 +1,22 @@
+.\" $FreeBSD: src/lib/libc/rpc/rstat_svc.8,v 1.5 1999/08/28 00:00:47 peter Exp $
+.\" @(#)rstat_svc.8c 2.2 88/08/03 4.0 RPCSRC; from 1.10 87/09/09 SMI
+.TH RSTAT_SVC 8 "24 November 1987"
+.SH NAME
+rstat_svc \- kernel statistics server
+.SH SYNOPSIS
+.B /etc/rstat_svc
+.SH DESCRIPTION
+.LP
+.B rstat_svc
+is a server which returns performance statistics
+obtained from the kernel.
+These statistics are graphically displayed by the Sun Microsystems program,
+.BR perfmeter (1).
+The
+.B rstat_svc
+daemon is normally invoked at boot time through /etc/rc.local.
+.PP
+.B rstat_svc
+uses an RPC protocol defined in /usr/include/rpcsvc/rstat.x.
+.\" .SH "SEE ALSO"
+.\" .BR rstat (1),
diff --git a/cpukit/librpc/src/rpc/rtems_portmapper.c b/cpukit/librpc/src/rpc/rtems_portmapper.c
new file mode 100644
index 0000000000..41e0e3a724
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rtems_portmapper.c
@@ -0,0 +1,491 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <sys/signal.h>
+
+static void reg_service();
+static void callit();
+static struct pmaplist *pmaplist;
+static int debugging = 0;
+
+#include <rtems.h>
+#define fork() (-1)
+
+
+static rtems_task rtems_portmapper (rtems_task_argument unused)
+{
+ SVCXPRT *xprt;
+ int sock;
+ struct sockaddr_in addr;
+ int len = sizeof(struct sockaddr_in);
+ register struct pmaplist *pml;
+
+ rtems_rpc_task_init ();
+ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ perror("portmap cannot create socket");
+ rtems_task_delete (RTEMS_SELF);
+ }
+
+ addr.sin_addr.s_addr = 0;
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(PMAPPORT);
+ if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
+ perror("portmap cannot bind");
+ close (sock);
+ rtems_task_delete (RTEMS_SELF);
+ }
+
+ if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) {
+ fprintf(stderr, "couldn't do udp_create\n");
+ close (sock);
+ rtems_task_delete (RTEMS_SELF);
+ }
+ /* make an entry for ourself */
+ pml = (struct pmaplist *)malloc(sizeof(struct pmaplist));
+ pml->pml_next = 0;
+ pml->pml_map.pm_prog = PMAPPROG;
+ pml->pml_map.pm_vers = PMAPVERS;
+ pml->pml_map.pm_prot = IPPROTO_UDP;
+ pml->pml_map.pm_port = PMAPPORT;
+ pmaplist = pml;
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ perror("portmap cannot create socket");
+ close (sock);
+ rtems_task_delete (RTEMS_SELF);
+ }
+ if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
+ perror("portmap cannot bind");
+ close (sock);
+ rtems_task_delete (RTEMS_SELF);
+ }
+ if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE))
+ == (SVCXPRT *)NULL) {
+ fprintf(stderr, "couldn't do tcp_create\n");
+ close (sock);
+ rtems_task_delete (RTEMS_SELF);
+ }
+ /* make an entry for ourself */
+ pml = (struct pmaplist *)malloc(sizeof(struct pmaplist));
+ pml->pml_map.pm_prog = PMAPPROG;
+ pml->pml_map.pm_vers = PMAPVERS;
+ pml->pml_map.pm_prot = IPPROTO_TCP;
+ pml->pml_map.pm_port = PMAPPORT;
+ pml->pml_next = pmaplist;
+ pmaplist = pml;
+
+ (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE);
+
+ svc_run();
+ fprintf(stderr, "run_svc returned unexpectedly\n");
+ close (sock);
+ rtems_task_delete (RTEMS_SELF);
+}
+
+static struct pmaplist *
+find_service(
+ u_long prog,
+ u_long vers,
+ int prot )
+{
+ register struct pmaplist *hit = NULL;
+ register struct pmaplist *pml;
+
+ for (pml = pmaplist; pml != NULL; pml = pml->pml_next) {
+ if ((pml->pml_map.pm_prog != prog) ||
+ (pml->pml_map.pm_prot != prot))
+ continue;
+ hit = pml;
+ if (pml->pml_map.pm_vers == vers)
+ break;
+ }
+ return (hit);
+}
+
+/*
+ * 1 OK, 0 not
+ */
+static void reg_service(
+ struct svc_req *rqstp,
+ SVCXPRT *xprt )
+{
+ struct pmap reg;
+ struct pmaplist *pml, *prevpml, *fnd;
+ int ans, port;
+ caddr_t t;
+
+#ifdef DEBUG
+ fprintf(stderr, "server: about do a switch\n");
+#endif
+ switch (rqstp->rq_proc) {
+
+ case PMAPPROC_NULL:
+ /*
+ * Null proc call
+ */
+ if ((!svc_sendreply(xprt, (xdrproc_t) xdr_void, NULL)) &&
+ debugging) {
+ abort();
+ }
+ break;
+
+ case PMAPPROC_SET:
+ /*
+ * Set a program,version to port mapping
+ */
+ if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (caddr_t)&reg))
+ svcerr_decode(xprt);
+ else {
+ /*
+ * check to see if already used
+ * find_service returns a hit even if
+ * the versions don't match, so check for it
+ */
+ fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
+ if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {
+ if (fnd->pml_map.pm_port == reg.pm_port) {
+ ans = 1;
+ goto done;
+ }
+ else {
+ ans = 0;
+ goto done;
+ }
+ } else {
+ /*
+ * add to END of list
+ */
+ pml = (struct pmaplist *)
+ malloc(sizeof(struct pmaplist));
+ pml->pml_map = reg;
+ pml->pml_next = 0;
+ if (pmaplist == 0) {
+ pmaplist = pml;
+ } else {
+ for (fnd= pmaplist; fnd->pml_next != 0;
+ fnd = fnd->pml_next);
+ fnd->pml_next = pml;
+ }
+ ans = 1;
+ }
+ done:
+ if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t)&ans)) &&
+ debugging) {
+ fprintf(stderr, "svc_sendreply\n");
+ abort();
+ }
+ }
+ break;
+
+ case PMAPPROC_UNSET:
+ /*
+ * Remove a program,version to port mapping.
+ */
+ if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (caddr_t)&reg))
+ svcerr_decode(xprt);
+ else {
+ ans = 0;
+ for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {
+ if ((pml->pml_map.pm_prog != reg.pm_prog) ||
+ (pml->pml_map.pm_vers != reg.pm_vers)) {
+ /* both pml & prevpml move forwards */
+ prevpml = pml;
+ pml = pml->pml_next;
+ continue;
+ }
+ /* found it; pml moves forward, prevpml stays */
+ ans = 1;
+ t = (caddr_t)pml;
+ pml = pml->pml_next;
+ if (prevpml == NULL)
+ pmaplist = pml;
+ else
+ prevpml->pml_next = pml;
+ free(t);
+ }
+ if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t)&ans)) &&
+ debugging) {
+ fprintf(stderr, "svc_sendreply\n");
+ abort();
+ }
+ }
+ break;
+
+ case PMAPPROC_GETPORT:
+ /*
+ * Lookup the mapping for a program,version and return its port
+ */
+ if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (caddr_t)&reg))
+ svcerr_decode(xprt);
+ else {
+ fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
+ if (fnd)
+ port = fnd->pml_map.pm_port;
+ else
+ port = 0;
+ if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t)&port)) &&
+ debugging) {
+ fprintf(stderr, "svc_sendreply\n");
+ abort();
+ }
+ }
+ break;
+
+ case PMAPPROC_DUMP:
+ /*
+ * Return the current set of mapped program,version
+ */
+ if (!svc_getargs(xprt, (xdrproc_t) xdr_void, NULL))
+ svcerr_decode(xprt);
+ else {
+ if ((!svc_sendreply(xprt, (xdrproc_t) xdr_pmaplist,
+ (caddr_t)&pmaplist)) && debugging) {
+ fprintf(stderr, "svc_sendreply\n");
+ abort();
+ }
+ }
+ break;
+
+ case PMAPPROC_CALLIT:
+ /*
+ * Calls a procedure on the local machine. If the requested
+ * procedure is not registered this procedure does not return
+ * error information!!
+ * This procedure is only supported on rpc/udp and calls via
+ * rpc/udp. It passes null authentication parameters.
+ */
+ callit(rqstp, xprt);
+ break;
+
+ default:
+ svcerr_noproc(xprt);
+ break;
+ }
+}
+
+
+/*
+ * Stuff for the rmtcall service
+ */
+#define ARGSIZE 9000
+
+struct encap_parms {
+ u_long arglen;
+ char *args;
+};
+
+static bool_t
+xdr_encap_parms(
+ XDR *xdrs,
+ struct encap_parms *epp )
+{
+
+ return (xdr_bytes(xdrs, &(epp->args), (u_int*)&(epp->arglen), ARGSIZE));
+}
+
+struct rmtcallargs {
+ u_long rmt_prog;
+ u_long rmt_vers;
+ u_long rmt_port;
+ u_long rmt_proc;
+ struct encap_parms rmt_args;
+};
+
+static bool_t
+xdr_rmtcall_args(
+ register XDR *xdrs,
+ register struct rmtcallargs *cap )
+{
+
+ /* does not get a port number */
+ if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&
+ xdr_u_long(xdrs, &(cap->rmt_vers)) &&
+ xdr_u_long(xdrs, &(cap->rmt_proc))) {
+ return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
+ }
+ return (FALSE);
+}
+
+static bool_t
+xdr_rmtcall_result(
+ register XDR *xdrs,
+ register struct rmtcallargs *cap )
+{
+ if (xdr_u_long(xdrs, &(cap->rmt_port)))
+ return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
+ return (FALSE);
+}
+
+/*
+ * only worries about the struct encap_parms part of struct rmtcallargs.
+ * The arglen must already be set!!
+ */
+static bool_t
+xdr_opaque_parms(
+ XDR *xdrs,
+ struct rmtcallargs *cap )
+{
+
+ return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));
+}
+
+/*
+ * This routine finds and sets the length of incoming opaque paraters
+ * and then calls xdr_opaque_parms.
+ */
+static bool_t
+xdr_len_opaque_parms(
+ register XDR *xdrs,
+ struct rmtcallargs *cap )
+{
+ register u_int beginpos, lowpos, highpos, currpos, pos;
+
+ beginpos = lowpos = pos = xdr_getpos(xdrs);
+ highpos = lowpos + ARGSIZE;
+ while ((int)(highpos - lowpos) >= 0) {
+ currpos = (lowpos + highpos) / 2;
+ if (xdr_setpos(xdrs, currpos)) {
+ pos = currpos;
+ lowpos = currpos + 1;
+ } else {
+ highpos = currpos - 1;
+ }
+ }
+ xdr_setpos(xdrs, beginpos);
+ cap->rmt_args.arglen = pos - beginpos;
+ return (xdr_opaque_parms(xdrs, cap));
+}
+
+/*
+ * Call a remote procedure service
+ * This procedure is very quiet when things go wrong.
+ * The proc is written to support broadcast rpc. In the broadcast case,
+ * a machine should shut-up instead of complain, less the requestor be
+ * overrun with complaints at the expense of not hearing a valid reply ...
+ *
+ * This now forks so that the program & process that it calls can call
+ * back to the portmapper.
+ */
+static void
+callit(
+ struct svc_req *rqstp,
+ SVCXPRT *xprt )
+{
+ struct rmtcallargs a;
+ struct pmaplist *pml;
+ u_short port;
+ struct sockaddr_in me;
+ int pid, socket = -1;
+ CLIENT *client;
+ struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;
+ struct timeval timeout;
+ char buf[ARGSIZE];
+
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
+ a.rmt_args.args = buf;
+ if (!svc_getargs(xprt, (xdrproc_t) xdr_rmtcall_args, (caddr_t)&a))
+ return;
+ if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL)
+ return;
+ /*
+ * fork a child to do the work. Parent immediately returns.
+ * Child exits upon completion.
+ */
+ if ((pid = fork()) != 0) {
+ if (debugging && (pid < 0)) {
+ fprintf(stderr, "portmap CALLIT: cannot fork.\n");
+ }
+ return;
+ }
+ port = pml->pml_map.pm_port;
+ get_myaddress(&me);
+ me.sin_port = htons(port);
+ client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket);
+ if (client != (CLIENT *)NULL) {
+ if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
+ client->cl_auth = authunix_create(au->aup_machname,
+ au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids);
+ }
+ a.rmt_port = (u_long)port;
+ if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a,
+ xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) {
+ svc_sendreply(xprt, (xdrproc_t) xdr_rmtcall_result, (caddr_t)&a);
+ }
+ AUTH_DESTROY(client->cl_auth);
+ clnt_destroy(client);
+ }
+ (void)close(socket);
+ exit(0);
+}
+
+/*
+ * Start the RPC portmapper
+ */
+int rtems_rpc_start_portmapper (int priority)
+{
+ rtems_mode mode;
+ rtems_status_code sc;
+ rtems_id tid;
+ static int started;
+
+ rtems_task_mode (RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &mode);
+ if (started) {
+ rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode);
+ return RTEMS_SUCCESSFUL;
+ }
+ sc = rtems_task_create (rtems_build_name('P', 'M', 'A', 'P'),
+ priority,
+ ARGSIZE + 8000,
+ RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
+ &tid);
+ if (sc != RTEMS_SUCCESSFUL) {
+ rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode);
+ return sc;
+ }
+ sc = rtems_task_start (tid, rtems_portmapper, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode);
+ return sc;
+ }
+ started = 1;
+ rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode);
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/librpc/src/rpc/rtems_rpc.c b/cpukit/librpc/src/rpc/rtems_rpc.c
new file mode 100644
index 0000000000..301ba2138b
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rtems_rpc.c
@@ -0,0 +1,59 @@
+/*
+ * RTEMS multi-tasking support
+ *
+ * $Id$
+ */
+
+#include <rpc/rpc.h>
+#include <rtems.h>
+#include <stdlib.h>
+
+/*
+ * RPC variables for single-thread
+ */
+static struct _rtems_rpc_task_variables rpc_default = {
+ -1, /* svc_maxfd */
+};
+
+/*
+ * RPC values for initializing a new per-task set of variables
+ */
+static const struct _rtems_rpc_task_variables rpc_init = {
+ -1, /* svc_maxfd */
+};
+
+/*
+ * Per-task pointer to RPC data
+ */
+struct _rtems_rpc_task_variables *rtems_rpc_task_variables = &rpc_default;
+
+/*
+ * Set up per-task RPC variables
+ */
+int rtems_rpc_task_init (void)
+{
+ rtems_status_code sc;
+ struct _rtems_rpc_task_variables *tvp;
+
+ if (rtems_rpc_task_variables == &rpc_default) {
+ tvp = malloc (sizeof *tvp);
+ if (tvp == NULL)
+ return RTEMS_NO_MEMORY;
+ /*
+ * FIXME: Should have destructor which cleans up
+ * all RPC stuff:
+ * - Close all files
+ * - Go through and free linked list elements
+ * - Free other allocated memory (e.g. clnt_perror_buf)
+ */
+ sc = rtems_task_variable_add (
+ RTEMS_SELF, (void *)&rtems_rpc_task_variables, NULL);
+ if (sc != RTEMS_SUCCESSFUL) {
+ free (tvp);
+ return sc;
+ }
+ *tvp = rpc_init;
+ rtems_rpc_task_variables = tvp;
+ }
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/librpc/src/rpc/rtime.3 b/cpukit/librpc/src/rpc/rtime.3
new file mode 100644
index 0000000000..ad3e538c43
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rtime.3
@@ -0,0 +1,47 @@
+.\" @(#)rtime.3n 2.1 88/08/08 4.0 RPCSRC; from 1.5 88/02/08 SMI
+.\" $FreeBSD: src/lib/libc/rpc/rtime.3,v 1.4 2000/03/02 09:13:48 sheldonh Exp $
+.\"
+.TH RTIME 3 "22 November 1987"
+.SH NAME
+rtime \- get remote time
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/time.h>
+.B #include <netinet/in.h>
+.LP
+.B int rtime(addrp, timep, timeout)
+.B struct sockaddr_in \(**addrp;
+.B struct timeval \(**timep;
+.B struct timeval \(**timeout;
+.fi
+.SH DESCRIPTION
+.B rtime(\|)
+consults the Internet Time Server at the address pointed to by
+.I addrp
+and returns the remote time in the
+.B timeval
+struct pointed to by
+.IR timep .
+Normally, the
+.SM UDP
+protocol is used when consulting the Time Server.
+The
+.I timeout
+parameter specifies how long the
+routine should wait before giving
+up when waiting for a reply. If
+.I timeout
+is specified as
+.SM NULL\s0,
+however, the routine will instead use
+.SM TCP
+and block until a reply is received from the time server.
+.LP
+The routine returns 0 if it is successful.
+Otherwise,
+it returns \-1 and
+.B errno
+is set to reflect the cause of the error.
+.SH "SEE ALSO"
+.BR timed (8c)
diff --git a/cpukit/librpc/src/rpc/rtime.c b/cpukit/librpc/src/rpc/rtime.c
new file mode 100644
index 0000000000..a724350c48
--- /dev/null
+++ b/cpukit/librpc/src/rpc/rtime.c
@@ -0,0 +1,158 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+
+ */
+
+/*
+ * rtime - get time from remote machine
+ *
+ * gets time, obtaining value from host
+ * on the udp/time socket. Since timeserver returns
+ * with time of day in seconds since Jan 1, 1900, must
+ * subtract seconds before Jan 1, 1970 to get
+ * what unix uses.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/select.h>
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/* from: static char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI"; */
+static const char rcsid[] = "$FreeBSD: src/lib/libc/rpc/rtime.c,v 1.5 2000/01/27 23:06:41 jasone Exp $";
+#endif
+
+extern int _rpc_dtablesize __P(( void ));
+
+#define NYEARS (unsigned long)(1970 - 1900)
+#define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4)))
+
+static void do_close __P(( int ));
+
+int
+rtime(addrp, timep, timeout)
+ struct sockaddr_in *addrp;
+ struct timeval *timep;
+ struct timeval *timeout;
+{
+ int s;
+ fd_set readfds;
+ int res;
+ unsigned long thetime;
+ struct sockaddr_in from;
+ socklen_t fromlen;
+ int type;
+ struct servent *serv;
+
+ if (timeout == NULL) {
+ type = SOCK_STREAM;
+ } else {
+ type = SOCK_DGRAM;
+ }
+ s = socket(AF_INET, type, 0);
+ if (s < 0) {
+ return(-1);
+ }
+ addrp->sin_family = AF_INET;
+
+ /* TCP and UDP port are the same in this case */
+ if ((serv = getservbyname("time", "tcp")) == NULL) {
+ return(-1);
+ }
+
+ addrp->sin_port = serv->s_port;
+
+ if (type == SOCK_DGRAM) {
+ res = sendto(s, (char *)&thetime, sizeof(thetime), 0,
+ (struct sockaddr *)addrp, sizeof(*addrp));
+ if (res < 0) {
+ do_close(s);
+ return(-1);
+ }
+ do {
+ FD_ZERO(&readfds);
+ FD_SET(s, &readfds);
+ res = select(_rpc_dtablesize(), &readfds,
+ (fd_set *)NULL, (fd_set *)NULL, timeout);
+ } while (res < 0 && errno == EINTR);
+ if (res <= 0) {
+ if (res == 0) {
+ errno = ETIMEDOUT;
+ }
+ do_close(s);
+ return(-1);
+ }
+ fromlen = sizeof(from);
+ res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
+ (struct sockaddr *)&from, &fromlen);
+ do_close(s);
+ if (res < 0) {
+ return(-1);
+ }
+ } else {
+ if (connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) {
+ do_close(s);
+ return(-1);
+ }
+ res = _RPC_read(s, (char *)&thetime, sizeof(thetime));
+ do_close(s);
+ if (res < 0) {
+ return(-1);
+ }
+ }
+ if (res != sizeof(thetime)) {
+ errno = EIO;
+ return(-1);
+ }
+ thetime = ntohl(thetime);
+ timep->tv_sec = thetime - TOFFSET;
+ timep->tv_usec = 0;
+ return(0);
+}
+
+static void
+do_close(s)
+ int s;
+{
+ int save;
+
+ save = errno;
+ (void)_RPC_close(s);
+ errno = save;
+}
diff --git a/cpukit/librpc/src/rpc/svc.c b/cpukit/librpc/src/rpc/svc.c
new file mode 100644
index 0000000000..bf305bce80
--- /dev/null
+++ b/cpukit/librpc/src/rpc/svc.c
@@ -0,0 +1,491 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc.c 2.4 88/08/11 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc.c,v 1.14 1999/08/28 00:00:48 peter Exp $";
+#endif
+
+/*
+ * svc.c, Server-side remote procedure call interface.
+ *
+ * There are two sets of procedures here. The xprt routines are
+ * for handling transport handles. The svc routines handle the
+ * list of service routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/errno.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+
+#define xports (rtems_rpc_task_variables->svc_xports)
+#define xportssize (rtems_rpc_task_variables->svc_xportssize)
+
+#define NULL_SVC ((struct svc_callout *)0)
+#define RQCRED_SIZE 400 /* this size is excessive */
+
+#define max(a, b) (a > b ? a : b)
+
+/*
+ * The services list
+ * Each entry represents a set of procedures (an rpc program).
+ * The dispatch routine takes request structs and runs the
+ * apropriate procedure.
+ */
+struct svc_callout {
+ struct svc_callout *sc_next;
+ u_long sc_prog;
+ u_long sc_vers;
+ void (*sc_dispatch)();
+};
+#define svc_head (rtems_rpc_task_variables->svc_svc_head)
+
+static struct svc_callout *svc_find();
+
+/* *************** SVCXPRT related stuff **************** */
+
+/*
+ * Activate a transport handle.
+ */
+void
+xprt_register(
+ SVCXPRT *xprt )
+{
+ register int sock = xprt->xp_sock;
+
+ if (sock + 1 > __svc_fdsetsize) {
+ int bytes = sizeof (fd_set);
+ fd_set *fds;
+
+ fds = (fd_set *)malloc(bytes);
+ memset(fds, 0, bytes);
+ if (__svc_fdset) {
+ memcpy(fds, __svc_fdset, bytes);
+ free(__svc_fdset);
+ }
+ __svc_fdset = fds;
+ __svc_fdsetsize = bytes * NBBY;
+ }
+
+ if (sock < FD_SETSIZE)
+ FD_SET(sock, &svc_fdset);
+ FD_SET(sock, __svc_fdset);
+
+ if (xports == NULL || sock + 1 > xportssize) {
+ SVCXPRT **xp;
+ int size = FD_SETSIZE;
+
+ if (sock + 1 > size)
+ size = sock + 1;
+ xp = (SVCXPRT **)mem_alloc(size * sizeof(SVCXPRT *));
+ memset(xp, 0, size * sizeof(SVCXPRT *));
+ if (xports) {
+ memcpy(xp, xports, xportssize * sizeof(SVCXPRT *));
+ free(xports);
+ }
+ xportssize = size;
+ xports = xp;
+ }
+ xports[sock] = xprt;
+ svc_maxfd = max(svc_maxfd, sock);
+}
+
+/*
+ * De-activate a transport handle.
+ */
+void
+xprt_unregister(
+ SVCXPRT *xprt )
+{
+ register int sock = xprt->xp_sock;
+
+ if (xports[sock] == xprt) {
+ xports[sock] = (SVCXPRT *)0;
+ if (sock < FD_SETSIZE)
+ FD_CLR(sock, &svc_fdset);
+ FD_CLR(sock, __svc_fdset);
+ if (sock == svc_maxfd) {
+ for (svc_maxfd--; svc_maxfd >= 0; svc_maxfd--)
+ if (xports[svc_maxfd])
+ break;
+ }
+ /*
+ * XXX could use svc_maxfd as a hint to
+ * decrease the size of __svc_fdset
+ */
+ }
+}
+
+
+/* ********************** CALLOUT list related stuff ************* */
+
+/*
+ * Add a service program to the callout list.
+ * The dispatch routine will be called when a rpc request for this
+ * program number comes in.
+ */
+bool_t
+svc_register(
+ SVCXPRT *xprt,
+ u_long prog,
+ u_long vers,
+ void (*dispatch)(),
+ int protocol )
+{
+ struct svc_callout *prev;
+ register struct svc_callout *s;
+
+ if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) {
+ if (s->sc_dispatch == dispatch)
+ goto pmap_it; /* he is registering another xptr */
+ return (FALSE);
+ }
+ s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout));
+ if (s == (struct svc_callout *)0) {
+ return (FALSE);
+ }
+ s->sc_prog = prog;
+ s->sc_vers = vers;
+ s->sc_dispatch = dispatch;
+ s->sc_next = svc_head;
+ svc_head = s;
+pmap_it:
+ /* now register the information with the local binder service */
+ if (protocol) {
+ return (pmap_set(prog, vers, protocol, xprt->xp_port));
+ }
+ return (TRUE);
+}
+
+/*
+ * Remove a service program from the callout list.
+ */
+void
+svc_unregister(
+ u_long prog,
+ u_long vers )
+{
+ struct svc_callout *prev;
+ register struct svc_callout *s;
+
+ if ((s = svc_find(prog, vers, &prev)) == NULL_SVC)
+ return;
+ if (prev == NULL_SVC) {
+ svc_head = s->sc_next;
+ } else {
+ prev->sc_next = s->sc_next;
+ }
+ s->sc_next = NULL_SVC;
+ mem_free((char *) s, (u_int) sizeof(struct svc_callout));
+ /* now unregister the information with the local binder service */
+ (void)pmap_unset(prog, vers);
+}
+
+/*
+ * Search the callout list for a program number, return the callout
+ * struct.
+ */
+static struct svc_callout *
+svc_find(
+ u_long prog,
+ u_long vers,
+ struct svc_callout **prev )
+{
+ register struct svc_callout *s, *p;
+
+ p = NULL_SVC;
+ for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+ if ((s->sc_prog == prog) && (s->sc_vers == vers))
+ goto done;
+ p = s;
+ }
+done:
+ *prev = p;
+ return (s);
+}
+
+/* ******************* REPLY GENERATION ROUTINES ************ */
+
+/*
+ * Send a reply to an rpc request
+ */
+bool_t
+svc_sendreply(
+ register SVCXPRT *xprt,
+ xdrproc_t xdr_results,
+ void *xdr_location )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = SUCCESS;
+ rply.acpted_rply.ar_results.where = xdr_location;
+ rply.acpted_rply.ar_results.proc = xdr_results;
+ return (SVC_REPLY(xprt, &rply));
+}
+
+/*
+ * No procedure error reply
+ */
+void
+svcerr_noproc(
+ register SVCXPRT *xprt )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = PROC_UNAVAIL;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Can't decode args error reply
+ */
+void
+svcerr_decode(
+ register SVCXPRT *xprt )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = GARBAGE_ARGS;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Some system error
+ */
+void
+svcerr_systemerr(
+ register SVCXPRT *xprt )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = SYSTEM_ERR;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Authentication error reply
+ */
+void
+svcerr_auth(
+ SVCXPRT *xprt,
+ enum auth_stat why )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_DENIED;
+ rply.rjcted_rply.rj_stat = AUTH_ERROR;
+ rply.rjcted_rply.rj_why = why;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Auth too weak error reply
+ */
+void
+svcerr_weakauth(
+ SVCXPRT *xprt )
+{
+
+ svcerr_auth(xprt, AUTH_TOOWEAK);
+}
+
+/*
+ * Program unavailable error reply
+ */
+void
+svcerr_noprog(
+ register SVCXPRT *xprt )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = PROG_UNAVAIL;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Program version mismatch error reply
+ */
+void
+svcerr_progvers(
+ register SVCXPRT *xprt,
+ rpcvers_t low_vers,
+ rpcvers_t high_vers )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = PROG_MISMATCH;
+ rply.acpted_rply.ar_vers.low = low_vers;
+ rply.acpted_rply.ar_vers.high = high_vers;
+ SVC_REPLY(xprt, &rply);
+}
+
+/* ******************* SERVER INPUT STUFF ******************* */
+
+/*
+ * Get server side input from some transport.
+ *
+ * Statement of authentication parameters management:
+ * This function owns and manages all authentication parameters, specifically
+ * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and
+ * the "cooked" credentials (rqst->rq_clntcred).
+ * However, this function does not know the structure of the cooked
+ * credentials, so it make the following assumptions:
+ * a) the structure is contiguous (no pointers), and
+ * b) the cred structure size does not exceed RQCRED_SIZE bytes.
+ * In all events, all three parameters are freed upon exit from this routine.
+ * The storage is trivially management on the call stack in user land, but
+ * is mallocated in kernel land.
+ */
+
+void
+svc_getreq(
+ int rdfds )
+{
+ fd_set readfds;
+
+ FD_ZERO(&readfds);
+ readfds.fds_bits[0] = rdfds;
+ svc_getreqset(&readfds);
+}
+
+void
+svc_getreqset(
+ fd_set *readfds )
+{
+ svc_getreqset2(readfds, FD_SETSIZE);
+}
+
+void
+svc_getreqset2(
+ fd_set *readfds,
+ int width )
+{
+ enum xprt_stat stat;
+ struct rpc_msg msg;
+ int prog_found;
+ u_long low_vers;
+ u_long high_vers;
+ struct svc_req r;
+ register SVCXPRT *xprt;
+ register int bit;
+ register int sock;
+ register fd_mask mask, *maskp;
+ char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];
+ msg.rm_call.cb_cred.oa_base = cred_area;
+ msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
+ r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);
+
+
+ maskp = readfds->fds_bits;
+ for (sock = 0; sock < width; sock += NFDBITS) {
+ for (mask = *maskp++; (bit = ffs(mask)); mask ^= (1 << (bit - 1))) {
+ /* sock has input waiting */
+ xprt = xports[sock + bit - 1];
+ if (xprt == NULL)
+ /* But do we control sock? */
+ continue;
+ /* now receive msgs from xprtprt (support batch calls) */
+ do {
+ if (SVC_RECV(xprt, &msg)) {
+
+ /* now find the exported program and call it */
+ register struct svc_callout *s;
+ enum auth_stat why;
+
+ r.rq_xprt = xprt;
+ r.rq_prog = msg.rm_call.cb_prog;
+ r.rq_vers = msg.rm_call.cb_vers;
+ r.rq_proc = msg.rm_call.cb_proc;
+ r.rq_cred = msg.rm_call.cb_cred;
+ /* first authenticate the message */
+ if ((why= _authenticate(&r, &msg)) != AUTH_OK) {
+ svcerr_auth(xprt, why);
+ goto call_done;
+ }
+ /* now match message with a registered service*/
+ prog_found = FALSE;
+ low_vers = (u_long) - 1;
+ high_vers = 0;
+ for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+ if (s->sc_prog == r.rq_prog) {
+ if (s->sc_vers == r.rq_vers) {
+ (*s->sc_dispatch)(&r, xprt);
+ goto call_done;
+ } /* found correct version */
+ prog_found = TRUE;
+ if (s->sc_vers < low_vers)
+ low_vers = s->sc_vers;
+ if (s->sc_vers > high_vers)
+ high_vers = s->sc_vers;
+ } /* found correct program */
+ }
+ /*
+ * if we got here, the program or version
+ * is not served ...
+ */
+ if (prog_found)
+ svcerr_progvers(xprt,
+ low_vers, high_vers);
+ else
+ svcerr_noprog(xprt);
+ /* Fall through to ... */
+ }
+ call_done:
+ if ((stat = SVC_STAT(xprt)) == XPRT_DIED){
+ SVC_DESTROY(xprt);
+ break;
+ }
+ } while (stat == XPRT_MOREREQS);
+ }
+ }
+}
diff --git a/cpukit/librpc/src/rpc/svc_auth.c b/cpukit/librpc/src/rpc/svc_auth.c
new file mode 100644
index 0000000000..c1095932a7
--- /dev/null
+++ b/cpukit/librpc/src/rpc/svc_auth.c
@@ -0,0 +1,216 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1986-1991 by Sun Microsystems Inc.
+ */
+
+/* #ident "@(#)svc_auth.c 1.16 94/04/24 SMI" */
+
+#if !defined(lint) && defined(SCCSIDS)
+#if 0
+static char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
+#else
+static const char rcsid[] =
+ "$FreeBSD: src/lib/libc/rpc/svc_auth.c,v 1.7 1999/12/29 05:04:16 peter Exp $";
+#endif
+#endif
+
+/*
+ * svc_auth.c, Server-side rpc authenticator interface.
+ *
+ */
+
+#ifdef _KERNEL
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/clnt.h>
+#include <rpc/rpc_msg.h>
+#include <rpc/svc.h>
+#include <rpc/svc_auth.h>
+#else
+#include <stdlib.h>
+#include <rpc/rpc.h>
+#endif
+#include <sys/types.h>
+
+/*
+ * svcauthsw is the bdevsw of server side authentication.
+ *
+ * Server side authenticators are called from authenticate by
+ * using the client auth struct flavor field to index into svcauthsw.
+ * The server auth flavors must implement a routine that looks
+ * like:
+ *
+ * enum auth_stat
+ * flavorx_auth(rqst, msg)
+ * register struct svc_req *rqst;
+ * register struct rpc_msg *msg;
+ *
+ */
+
+enum auth_stat _svcauth_null(); /* no authentication */
+enum auth_stat _svcauth_unix(); /* (system) unix style (uid, gids) */
+enum auth_stat _svcauth_short(); /* short hand unix style */
+enum auth_stat _svcauth_des(); /* des style */
+
+/* declarations to allow servers to specify new authentication flavors */
+struct authsvc {
+ int flavor;
+ enum auth_stat (*handler)();
+ struct authsvc *next;
+};
+#define Auths (rtems_rpc_task_variables->svc_auths_Auths)
+
+/*
+ * The call rpc message, msg has been obtained from the wire. The msg contains
+ * the raw form of credentials and verifiers. authenticate returns AUTH_OK
+ * if the msg is successfully authenticated. If AUTH_OK then the routine also
+ * does the following things:
+ * set rqst->rq_xprt->verf to the appropriate response verifier;
+ * sets rqst->rq_client_cred to the "cooked" form of the credentials.
+ *
+ * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
+ * its length is set appropriately.
+ *
+ * The caller still owns and is responsible for msg->u.cmb.cred and
+ * msg->u.cmb.verf. The authentication system retains ownership of
+ * rqst->rq_client_cred, the cooked credentials.
+ *
+ * There is an assumption that any flavour less than AUTH_NULL is
+ * invalid.
+ */
+enum auth_stat
+_authenticate(rqst, msg)
+ register struct svc_req *rqst;
+ struct rpc_msg *msg;
+{
+ register int cred_flavor;
+ register struct authsvc *asp;
+
+ rqst->rq_cred = msg->rm_call.cb_cred;
+ rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
+ rqst->rq_xprt->xp_verf.oa_length = 0;
+ cred_flavor = rqst->rq_cred.oa_flavor;
+ switch (cred_flavor) {
+ case AUTH_NULL:
+ return(_svcauth_null(rqst, msg));
+ case AUTH_UNIX:
+ return(_svcauth_unix(rqst, msg));
+ case AUTH_SHORT:
+ return(_svcauth_short(rqst, msg));
+ /*
+ * We leave AUTH_DES turned off by default because svcauth_des()
+ * needs getpublickey(), which is in librpcsvc, not libc. If we
+ * included AUTH_DES as a built-in flavor, programs that don't
+ * have -lrpcsvc in their Makefiles wouldn't link correctly, even
+ * though they don't use AUTH_DES. And I'm too lazy to go through
+ * the tree looking for all of them.
+ */
+#ifdef DES_BUILTIN
+ case AUTH_DES:
+ return(_svcauth_des(rqst, msg));
+#endif
+ }
+
+ /* flavor doesn't match any of the builtin types, so try new ones */
+ for (asp = Auths; asp; asp = asp->next) {
+ if (asp->flavor == cred_flavor) {
+ enum auth_stat as;
+
+ as = (*asp->handler)(rqst, msg);
+ return (as);
+ }
+ }
+
+ return (AUTH_REJECTEDCRED);
+}
+
+/*ARGSUSED*/
+enum auth_stat
+_svcauth_null(rqst, msg)
+ struct svc_req *rqst;
+ struct rpc_msg *msg;
+{
+ return (AUTH_OK);
+}
+
+/*
+ * Allow the rpc service to register new authentication types that it is
+ * prepared to handle. When an authentication flavor is registered,
+ * the flavor is checked against already registered values. If not
+ * registered, then a new Auths entry is added on the list.
+ *
+ * There is no provision to delete a registration once registered.
+ *
+ * This routine returns:
+ * 0 if registration successful
+ * 1 if flavor already registered
+ * -1 if can't register (errno set)
+ */
+
+int
+svc_auth_reg(cred_flavor, handler)
+ register int cred_flavor;
+ enum auth_stat (*handler)();
+{
+ register struct authsvc *asp;
+
+ switch (cred_flavor) {
+ case AUTH_NULL:
+ case AUTH_UNIX:
+ case AUTH_SHORT:
+#ifdef DES_BUILTIN
+ case AUTH_DES:
+#endif
+ /* already registered */
+ return (1);
+
+ default:
+ for (asp = Auths; asp; asp = asp->next) {
+ if (asp->flavor == cred_flavor) {
+ /* already registered */
+ return (1);
+ }
+ }
+
+ /* this is a new one, so go ahead and register it */
+ asp = (struct authsvc *)mem_alloc(sizeof (*asp));
+ if (asp == NULL) {
+ return (-1);
+ }
+ asp->flavor = cred_flavor;
+ asp->handler = handler;
+ asp->next = Auths;
+ Auths = asp;
+ break;
+ }
+ return (0);
+}
diff --git a/cpukit/librpc/src/rpc/svc_auth_unix.c b/cpukit/librpc/src/rpc/svc_auth_unix.c
new file mode 100644
index 0000000000..8b4e257a2c
--- /dev/null
+++ b/cpukit/librpc/src/rpc/svc_auth_unix.c
@@ -0,0 +1,148 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_auth_unix.c,v 1.8 1999/08/28 00:00:49 peter Exp $";
+#endif
+
+/*
+ * svc_auth_unix.c
+ * Handles UNIX flavor authentication parameters on the service side of rpc.
+ * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT.
+ * _svcauth_unix does full blown unix style uid,gid+gids auth,
+ * _svcauth_short uses a shorthand auth to index into a cache of longhand auths.
+ * Note: the shorthand has been gutted for efficiency.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+/*
+ * Unix longhand authenticator
+ */
+enum auth_stat
+_svcauth_unix(rqst, msg)
+ register struct svc_req *rqst;
+ register struct rpc_msg *msg;
+{
+ register enum auth_stat stat;
+ XDR xdrs;
+ register struct authunix_parms *aup;
+ register int32_t *buf;
+ struct area {
+ struct authunix_parms area_aup;
+ char area_machname[MAX_MACHINE_NAME+1];
+ int area_gids[NGRPS];
+ } *area;
+ u_int auth_len;
+ int str_len, gid_len;
+ register int i;
+
+ area = (struct area *) rqst->rq_clntcred;
+ aup = &area->area_aup;
+ aup->aup_machname = area->area_machname;
+ aup->aup_gids = area->area_gids;
+ auth_len = (u_int)msg->rm_call.cb_cred.oa_length;
+ xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE);
+ buf = XDR_INLINE(&xdrs, auth_len);
+ if (buf != NULL) {
+ aup->aup_time = IXDR_GET_LONG(buf);
+ str_len = IXDR_GET_U_LONG(buf);
+ if (str_len > MAX_MACHINE_NAME) {
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+ memcpy(aup->aup_machname, (caddr_t)buf, (u_int)str_len);
+ aup->aup_machname[str_len] = 0;
+ str_len = RNDUP(str_len);
+ buf += str_len / sizeof (int32_t);
+ aup->aup_uid = IXDR_GET_LONG(buf);
+ aup->aup_gid = IXDR_GET_LONG(buf);
+ gid_len = IXDR_GET_U_LONG(buf);
+ if (gid_len > NGRPS) {
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+ aup->aup_len = gid_len;
+ for (i = 0; i < gid_len; i++) {
+ aup->aup_gids[i] = IXDR_GET_LONG(buf);
+ }
+ /*
+ * five is the smallest unix credentials structure -
+ * timestamp, hostname len (0), uid, gid, and gids len (0).
+ */
+ if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
+ (void) printf("bad auth_len gid %d str %d auth %d\n",
+ gid_len, str_len, auth_len);
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+ } else if (! xdr_authunix_parms(&xdrs, aup)) {
+ xdrs.x_op = XDR_FREE;
+ (void)xdr_authunix_parms(&xdrs, aup);
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+
+ /* get the verifier */
+ if ((u_int)msg->rm_call.cb_verf.oa_length) {
+ rqst->rq_xprt->xp_verf.oa_flavor =
+ msg->rm_call.cb_verf.oa_flavor;
+ rqst->rq_xprt->xp_verf.oa_base =
+ msg->rm_call.cb_verf.oa_base;
+ rqst->rq_xprt->xp_verf.oa_length =
+ msg->rm_call.cb_verf.oa_length;
+ } else {
+ rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
+ rqst->rq_xprt->xp_verf.oa_length = 0;
+ }
+ stat = AUTH_OK;
+done:
+ XDR_DESTROY(&xdrs);
+ return (stat);
+}
+
+
+/*
+ * Shorthand unix authenticator
+ * Looks up longhand in a cache.
+ */
+/*ARGSUSED*/
+enum auth_stat
+_svcauth_short(rqst, msg)
+ struct svc_req *rqst;
+ struct rpc_msg *msg;
+{
+ return (AUTH_REJECTEDCRED);
+}
diff --git a/cpukit/librpc/src/rpc/svc_raw.c b/cpukit/librpc/src/rpc/svc_raw.c
new file mode 100644
index 0000000000..108b18a309
--- /dev/null
+++ b/cpukit/librpc/src/rpc/svc_raw.c
@@ -0,0 +1,169 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_raw.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_raw.c,v 1.7 1999/08/28 00:00:49 peter Exp $";
+#endif
+
+/*
+ * svc_raw.c, This a toy for simple testing and timing.
+ * Interface to create an rpc client and server in the same UNIX process.
+ * This lets us similate rpc and get rpc (round trip) overhead, without
+ * any interference from the kernal.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <stdlib.h>
+
+/*
+ * This is the "network" that we will be moving data over
+ */
+struct svc_raw_private {
+ char _raw_buf[UDPMSGSIZE];
+ SVCXPRT server;
+ XDR xdr_stream;
+ char verf_body[MAX_AUTH_BYTES];
+};
+#define svcraw_private ((struct svc_raw_private *)(rtems_rpc_task_variables)->svc_raw_private)
+
+static bool_t svcraw_recv();
+static enum xprt_stat svcraw_stat();
+static bool_t svcraw_getargs();
+static bool_t svcraw_reply();
+static bool_t svcraw_freeargs();
+static void svcraw_destroy();
+
+static struct xp_ops server_ops = {
+ svcraw_recv,
+ svcraw_stat,
+ svcraw_getargs,
+ svcraw_reply,
+ svcraw_freeargs,
+ svcraw_destroy
+};
+
+SVCXPRT *
+svcraw_create()
+{
+ register struct svc_raw_private *srp = svcraw_private;
+
+ if (srp == 0) {
+ srp = (struct svc_raw_private *)calloc(1, sizeof (*srp));
+ if (srp == 0)
+ return (0);
+ }
+ srp->server.xp_sock = 0;
+ srp->server.xp_port = 0;
+ srp->server.xp_ops = &server_ops;
+ srp->server.xp_verf.oa_base = srp->verf_body;
+ xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+ return (&srp->server);
+}
+
+static enum xprt_stat
+svcraw_stat()
+{
+
+ return (XPRT_IDLE);
+}
+
+static bool_t
+svcraw_recv(xprt, msg)
+ SVCXPRT *xprt;
+ struct rpc_msg *msg;
+{
+ register struct svc_raw_private *srp = svcraw_private;
+ register XDR *xdrs;
+
+ if (srp == 0)
+ return (0);
+ xdrs = &srp->xdr_stream;
+ xdrs->x_op = XDR_DECODE;
+ XDR_SETPOS(xdrs, 0);
+ if (! xdr_callmsg(xdrs, msg))
+ return (FALSE);
+ return (TRUE);
+}
+
+static bool_t
+svcraw_reply(xprt, msg)
+ SVCXPRT *xprt;
+ struct rpc_msg *msg;
+{
+ register struct svc_raw_private *srp = svcraw_private;
+ register XDR *xdrs;
+
+ if (srp == 0)
+ return (FALSE);
+ xdrs = &srp->xdr_stream;
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, 0);
+ if (! xdr_replymsg(xdrs, msg))
+ return (FALSE);
+ (void)XDR_GETPOS(xdrs); /* called just for overhead */
+ return (TRUE);
+}
+
+static bool_t
+svcraw_getargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+ register struct svc_raw_private *srp = svcraw_private;
+
+ if (srp == 0)
+ return (FALSE);
+ return ((*xdr_args)(&srp->xdr_stream, args_ptr));
+}
+
+static bool_t
+svcraw_freeargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+ register struct svc_raw_private *srp = svcraw_private;
+ register XDR *xdrs;
+
+ if (srp == 0)
+ return (FALSE);
+ xdrs = &srp->xdr_stream;
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static void
+svcraw_destroy()
+{
+}
diff --git a/cpukit/librpc/src/rpc/svc_run.c b/cpukit/librpc/src/rpc/svc_run.c
new file mode 100644
index 0000000000..b1b6dded2f
--- /dev/null
+++ b/cpukit/librpc/src/rpc/svc_run.c
@@ -0,0 +1,84 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_run.c,v 1.10 1999/08/28 00:00:49 peter Exp $";
+#endif
+
+/*
+ * This is the rpc server side idle loop
+ * Wait for input, call server program.
+ */
+#include <rpc/rpc.h>
+#include <stdio.h>
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/select.h>
+
+void
+svc_run()
+{
+ fd_set *fds;
+
+ for (;;) {
+ if (__svc_fdset) {
+ int bytes = sizeof (fd_set);
+ fds = (fd_set *)malloc(bytes);
+ memcpy(fds, __svc_fdset, bytes);
+ } else
+ fds = NULL;
+ switch (select(svc_maxfd + 1, fds, NULL, NULL,
+ (struct timeval *)0)) {
+ case -1:
+ if (errno == EINTR) {
+ if (fds)
+ free(fds);
+ continue;
+ }
+ perror("svc_run: - select failed");
+ if (fds)
+ free(fds);
+ return;
+ case 0:
+ if (fds)
+ free(fds);
+ continue;
+ default:
+ /* if fds == NULL, select() can't return a result */
+ svc_getreqset2(fds, svc_maxfd + 1);
+ free(fds);
+ }
+ }
+}
diff --git a/cpukit/librpc/src/rpc/svc_simple.c b/cpukit/librpc/src/rpc/svc_simple.c
new file mode 100644
index 0000000000..1ad846981a
--- /dev/null
+++ b/cpukit/librpc/src/rpc/svc_simple.c
@@ -0,0 +1,155 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_simple.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_simple.c,v 1.9 1999/08/28 00:00:50 peter Exp $";
+#endif
+
+/*
+ * svc_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+struct prog_lst {
+ char *(*p_progname)();
+ rpcprog_t p_prognum;
+ rpcproc_t p_procnum;
+ xdrproc_t p_inproc, p_outproc;
+ struct prog_lst *p_nxt;
+};
+static void universal();
+#define proglst (rtems_rpc_task_variables->svc_simple_proglst)
+#define pl (rtems_rpc_task_variables->svc_simple_pl)
+#define transp (rtems_rpc_task_variables->svc_simple_transp)
+
+int
+registerrpc(
+ int prognum,
+ int versnum,
+ int procnum,
+ char *(*progname)(),
+ xdrproc_t inproc,
+ xdrproc_t outproc )
+{
+
+ if (procnum == NULLPROC) {
+ (void) fprintf(stderr,
+ "can't reassign procedure number %" PRIu32 "\n", NULLPROC);
+ return (-1);
+ }
+ if (transp == 0) {
+ transp = svcudp_create(RPC_ANYSOCK);
+ if (transp == NULL) {
+ (void) fprintf(stderr, "couldn't create an rpc server\n");
+ return (-1);
+ }
+ }
+ (void) pmap_unset((u_long)prognum, (u_long)versnum);
+ if (!svc_register(transp, (u_long)prognum, (u_long)versnum,
+ universal, IPPROTO_UDP)) {
+ (void) fprintf(stderr, "couldn't register prog %d vers %d\n",
+ prognum, versnum);
+ return (-1);
+ }
+ pl = (struct prog_lst *)malloc(sizeof(struct prog_lst));
+ if (pl == NULL) {
+ (void) fprintf(stderr, "registerrpc: out of memory\n");
+ return (-1);
+ }
+ pl->p_progname = progname;
+ pl->p_prognum = prognum;
+ pl->p_procnum = procnum;
+ pl->p_inproc = inproc;
+ pl->p_outproc = outproc;
+ pl->p_nxt = proglst;
+ proglst = pl;
+ return (0);
+}
+
+static void
+universal(
+ struct svc_req *rqstp,
+ SVCXPRT *atransp )
+{
+ int prog, proc;
+ char *outdata;
+ char xdrbuf[UDPMSGSIZE];
+ struct prog_lst *lpl;
+
+ /*
+ * enforce "procnum 0 is echo" convention
+ */
+ if (rqstp->rq_proc == NULLPROC) {
+ if (svc_sendreply(atransp, (xdrproc_t) xdr_void, NULL) == FALSE) {
+ (void) fprintf(stderr, "xxx\n");
+ exit(1);
+ }
+ return;
+ }
+ prog = rqstp->rq_prog;
+ proc = rqstp->rq_proc;
+ for (lpl = proglst; lpl != NULL; lpl = lpl->p_nxt)
+ if (lpl->p_prognum == prog && lpl->p_procnum == proc) {
+ /* decode arguments into a CLEAN buffer */
+ memset(xdrbuf, 0, sizeof(xdrbuf)); /* required ! */
+ if (!svc_getargs(atransp, lpl->p_inproc, xdrbuf)) {
+ svcerr_decode(atransp);
+ return;
+ }
+ outdata = (*(lpl->p_progname))(xdrbuf);
+ if (outdata == NULL &&
+ lpl->p_outproc != (xdrproc_t) xdr_void)
+ /* there was an error */
+ return;
+ if (!svc_sendreply(atransp, lpl->p_outproc, outdata)) {
+ (void) fprintf(stderr,
+ "trouble replying to prog %d\n",
+ lpl->p_prognum);
+ exit(1);
+ }
+ /* free the decoded arguments */
+ (void)svc_freeargs(atransp, lpl->p_inproc, xdrbuf);
+ return;
+ }
+ (void) fprintf(stderr, "never registered prog %d\n", prog);
+ exit(1);
+}
diff --git a/cpukit/librpc/src/rpc/svc_tcp.c b/cpukit/librpc/src/rpc/svc_tcp.c
new file mode 100644
index 0000000000..413c9893a7
--- /dev/null
+++ b/cpukit/librpc/src/rpc/svc_tcp.c
@@ -0,0 +1,482 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_tcp.c,v 1.18 2000/01/27 23:06:41 jasone Exp $";
+#endif
+
+/*
+ * svc_tcp.c, Server side for TCP/IP based RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Actually implements two flavors of transporter -
+ * a tcp rendezvouser (a listner and connection establisher)
+ * and a record/tcp stream.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <sys/select.h>
+
+/*
+ * Ops vector for TCP/IP based rpc service handle
+ */
+static bool_t svctcp_recv();
+static enum xprt_stat svctcp_stat();
+static bool_t svctcp_getargs();
+static bool_t svctcp_reply();
+static bool_t svctcp_freeargs();
+static void svctcp_destroy();
+
+static struct xp_ops svctcp_op = {
+ svctcp_recv,
+ svctcp_stat,
+ svctcp_getargs,
+ svctcp_reply,
+ svctcp_freeargs,
+ svctcp_destroy
+};
+
+/*
+ * Ops vector for TCP/IP rendezvous handler
+ */
+static bool_t rendezvous_request();
+static enum xprt_stat rendezvous_stat();
+
+static struct xp_ops svctcp_rendezvous_op = {
+ rendezvous_request,
+ rendezvous_stat,
+ (bool_t (*)())abort,
+ (bool_t (*)())abort,
+ (bool_t (*)())abort,
+ svctcp_destroy
+};
+
+static int readtcp(), writetcp();
+static SVCXPRT *makefd_xprt();
+
+struct tcp_rendezvous { /* kept in xprt->xp_p1 */
+ u_int sendsize;
+ u_int recvsize;
+};
+
+struct tcp_conn { /* kept in xprt->xp_p1 */
+ enum xprt_stat strm_stat;
+ u_long x_id;
+ XDR xdrs;
+ char verf_body[MAX_AUTH_BYTES];
+};
+
+/*
+ * Usage:
+ * xprt = svctcp_create(sock, send_buf_size, recv_buf_size);
+ *
+ * Creates, registers, and returns a (rpc) tcp based transporter.
+ * Once *xprt is initialized, it is registered as a transporter
+ * see (svc.h, xprt_register). This routine returns
+ * a NULL if a problem occurred.
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svctcp_create
+ * binds it to an arbitrary port. The routine then starts a tcp
+ * listener on the socket's associated port. In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ *
+ * Since tcp streams do buffered io similar to stdio, the caller can specify
+ * how big the send and receive buffers are via the second and third parms;
+ * 0 => use the system default.
+ */
+SVCXPRT *
+svctcp_create(sock, sendsize, recvsize)
+ register int sock;
+ u_int sendsize;
+ u_int recvsize;
+{
+ bool_t madesock = FALSE;
+ register SVCXPRT *xprt;
+ register struct tcp_rendezvous *r;
+ struct sockaddr_in addr;
+ socklen_t len = sizeof(struct sockaddr_in);
+ int on;
+
+ if (sock == RPC_ANYSOCK) {
+ if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ perror("svctcp_.c - udp socket creation problem");
+ return ((SVCXPRT *)NULL);
+ }
+ madesock = TRUE;
+ }
+ on = 1;
+ if (ioctl(sock, FIONBIO, &on) < 0) {
+ perror("svc_tcp.c - cannot turn on non-blocking mode");
+ if (madesock)
+ (void)_RPC_close(sock);
+ return ((SVCXPRT *)NULL);
+ }
+ memset(&addr, 0, sizeof (addr));
+ addr.sin_len = sizeof(struct sockaddr_in);
+ addr.sin_family = AF_INET;
+ if (bindresvport(sock, &addr)) {
+ addr.sin_port = 0;
+ (void)bind(sock, (struct sockaddr *)&addr, len);
+ }
+ if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0) ||
+ (listen(sock, 2) != 0)) {
+ perror("svctcp_.c - cannot getsockname or listen");
+ if (madesock)
+ (void)_RPC_close(sock);
+ return ((SVCXPRT *)NULL);
+ }
+ r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r));
+ if (r == NULL) {
+ (void) fprintf(stderr, "svctcp_create: out of memory\n");
+ return (NULL);
+ }
+ r->sendsize = sendsize;
+ r->recvsize = recvsize;
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == NULL) {
+ (void) fprintf(stderr, "svctcp_create: out of memory\n");
+ return (NULL);
+ }
+ xprt->xp_p2 = NULL;
+ xprt->xp_p1 = (caddr_t)r;
+ xprt->xp_verf = _null_auth;
+ xprt->xp_ops = &svctcp_rendezvous_op;
+ xprt->xp_port = ntohs(addr.sin_port);
+ xprt->xp_sock = sock;
+ xprt_register(xprt);
+ return (xprt);
+}
+
+/*
+ * Like svtcp_create(), except the routine takes any *open* UNIX file
+ * descriptor as its first input.
+ */
+SVCXPRT *
+svcfd_create(fd, sendsize, recvsize)
+ int fd;
+ u_int sendsize;
+ u_int recvsize;
+{
+
+ return (makefd_xprt(fd, sendsize, recvsize));
+}
+
+static SVCXPRT *
+makefd_xprt(fd, sendsize, recvsize)
+ int fd;
+ u_int sendsize;
+ u_int recvsize;
+{
+ register SVCXPRT *xprt;
+ register struct tcp_conn *cd;
+
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == (SVCXPRT *)NULL) {
+ (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+ goto done;
+ }
+ cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn));
+ if (cd == (struct tcp_conn *)NULL) {
+ (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+ mem_free((char *) xprt, sizeof(SVCXPRT));
+ xprt = (SVCXPRT *)NULL;
+ goto done;
+ }
+ cd->strm_stat = XPRT_IDLE;
+ xdrrec_create(&(cd->xdrs), sendsize, recvsize,
+ (caddr_t)xprt, readtcp, writetcp);
+ xprt->xp_p2 = NULL;
+ xprt->xp_p1 = (caddr_t)cd;
+ xprt->xp_verf.oa_base = cd->verf_body;
+ xprt->xp_addrlen = 0;
+ xprt->xp_ops = &svctcp_op; /* truely deals with calls */
+ xprt->xp_port = 0; /* this is a connection, not a rendezvouser */
+ xprt->xp_sock = fd;
+ xprt_register(xprt);
+ done:
+ return (xprt);
+}
+
+static bool_t
+rendezvous_request(xprt)
+ register SVCXPRT *xprt;
+{
+ int sock;
+ struct tcp_rendezvous *r;
+ struct sockaddr_in addr;
+ socklen_t len;
+ int off;
+
+ r = (struct tcp_rendezvous *)xprt->xp_p1;
+ again:
+ len = sizeof(struct sockaddr_in);
+ if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr,
+ &len)) < 0) {
+ if (errno == EINTR)
+ goto again;
+ return (FALSE);
+ }
+ /*
+ * Guard against FTP bounce attacks.
+ */
+ if (addr.sin_port == htons(20)) {
+ _RPC_close(sock);
+ return (FALSE);
+ }
+ /*
+ * The listening socket is in FIONBIO mode and we inherit it.
+ */
+ off = 0;
+ if (ioctl(sock, FIONBIO, &off) < 0) {
+ _RPC_close(sock);
+ return (FALSE);
+ }
+ /*
+ * make a new transporter (re-uses xprt)
+ */
+ xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
+ xprt->xp_raddr = addr;
+ xprt->xp_addrlen = len;
+ return (FALSE); /* there is never an rpc msg to be processed */
+}
+
+static enum xprt_stat
+rendezvous_stat()
+{
+
+ return (XPRT_IDLE);
+}
+
+static void
+svctcp_destroy(xprt)
+ register SVCXPRT *xprt;
+{
+ register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1;
+
+ xprt_unregister(xprt);
+ (void)_RPC_close(xprt->xp_sock);
+ if (xprt->xp_port != 0) {
+ /* a rendezvouser socket */
+ xprt->xp_port = 0;
+ } else {
+ /* an actual connection socket */
+ XDR_DESTROY(&(cd->xdrs));
+ }
+ mem_free((caddr_t)cd, sizeof(struct tcp_conn));
+ mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+/*
+ * All read operations timeout after 35 seconds.
+ * A timeout is fatal for the connection.
+ */
+static struct timeval wait_per_try = { 35, 0 };
+
+/*
+ * reads data from the tcp conection.
+ * any error is fatal and the connection is closed.
+ * (And a read of zero bytes is a half closed stream => error.)
+ *
+ * Note: we have to be careful here not to allow ourselves to become
+ * blocked too long in this routine. While we're waiting for data from one
+ * client, another client may be trying to connect. To avoid this situation,
+ * some code from svc_run() is transplanted here: the select() loop checks
+ * all RPC descriptors including the one we want and calls svc_getreqset2()
+ * to handle new requests if any are detected.
+ */
+static int
+readtcp(xprt, buf, len)
+ register SVCXPRT *xprt;
+ caddr_t buf;
+ register int len;
+{
+ register int sock = xprt->xp_sock;
+ struct timeval start, delta, tv;
+ struct timeval tmp1, tmp2;
+ fd_set *fds;
+
+ delta = wait_per_try;
+ fds = NULL;
+ gettimeofday(&start, NULL);
+ do {
+ int bytes = sizeof (fd_set);
+ if (fds != NULL)
+ free(fds);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL)
+ goto fatal_err;
+ memcpy(fds, __svc_fdset, bytes);
+
+ /* XXX we know the other bits are still clear */
+ FD_SET(sock, fds);
+ tv = delta; /* in case select() implements writeback */
+ switch (select(svc_maxfd + 1, fds, NULL, NULL, &tv)) {
+ case -1:
+ if (errno != EINTR)
+ goto fatal_err;
+ gettimeofday(&tmp1, NULL);
+ timersub(&tmp1, &start, &tmp2);
+ timersub(&wait_per_try, &tmp2, &tmp1);
+ if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
+ goto fatal_err;
+ delta = tmp1;
+ continue;
+ case 0:
+ goto fatal_err;
+ default:
+ if (!FD_ISSET(sock, fds)) {
+ svc_getreqset2(fds, svc_maxfd + 1);
+ gettimeofday(&tmp1, NULL);
+ timersub(&tmp1, &start, &tmp2);
+ timersub(&wait_per_try, &tmp2, &tmp1);
+ if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
+ goto fatal_err;
+ delta = tmp1;
+ continue;
+ }
+ }
+ } while (!FD_ISSET(sock, fds));
+ if ((len = _RPC_read(sock, buf, len)) > 0) {
+ if (fds != NULL)
+ free(fds);
+ return (len);
+ }
+fatal_err:
+ ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
+ if (fds != NULL)
+ free(fds);
+ return (-1);
+}
+
+/*
+ * writes data to the tcp connection.
+ * Any error is fatal and the connection is closed.
+ */
+static int
+writetcp(xprt, buf, len)
+ register SVCXPRT *xprt;
+ caddr_t buf;
+ int len;
+{
+ register int i, cnt;
+
+ for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+ if ((i = _RPC_write(xprt->xp_sock, buf, cnt)) < 0) {
+ ((struct tcp_conn *)(xprt->xp_p1))->strm_stat =
+ XPRT_DIED;
+ return (-1);
+ }
+ }
+ return (len);
+}
+
+static enum xprt_stat
+svctcp_stat(xprt)
+ SVCXPRT *xprt;
+{
+ register struct tcp_conn *cd =
+ (struct tcp_conn *)(xprt->xp_p1);
+
+ if (cd->strm_stat == XPRT_DIED)
+ return (XPRT_DIED);
+ if (! xdrrec_eof(&(cd->xdrs)))
+ return (XPRT_MOREREQS);
+ return (XPRT_IDLE);
+}
+
+static bool_t
+svctcp_recv(xprt, msg)
+ SVCXPRT *xprt;
+ register struct rpc_msg *msg;
+{
+ register struct tcp_conn *cd =
+ (struct tcp_conn *)(xprt->xp_p1);
+ register XDR *xdrs = &(cd->xdrs);
+
+ xdrs->x_op = XDR_DECODE;
+ (void)xdrrec_skiprecord(xdrs);
+ if (xdr_callmsg(xdrs, msg)) {
+ cd->x_id = msg->rm_xid;
+ return (TRUE);
+ }
+ cd->strm_stat = XPRT_DIED; /* XXXX */
+ return (FALSE);
+}
+
+static bool_t
+svctcp_getargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+
+ return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr));
+}
+
+static bool_t
+svctcp_freeargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+ register XDR *xdrs =
+ &(((struct tcp_conn *)(xprt->xp_p1))->xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static bool_t
+svctcp_reply(xprt, msg)
+ SVCXPRT *xprt;
+ register struct rpc_msg *msg;
+{
+ register struct tcp_conn *cd =
+ (struct tcp_conn *)(xprt->xp_p1);
+ register XDR *xdrs = &(cd->xdrs);
+ register bool_t stat;
+
+ xdrs->x_op = XDR_ENCODE;
+ msg->rm_xid = cd->x_id;
+ stat = xdr_replymsg(xdrs, msg);
+ (void)xdrrec_endofrecord(xdrs, TRUE);
+ return (stat);
+}
diff --git a/cpukit/librpc/src/rpc/svc_udp.c b/cpukit/librpc/src/rpc/svc_udp.c
new file mode 100644
index 0000000000..c25095bf33
--- /dev/null
+++ b/cpukit/librpc/src/rpc/svc_udp.c
@@ -0,0 +1,479 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_udp.c,v 1.13 2000/01/27 23:06:41 jasone Exp $";
+#endif
+
+/*
+ * svc_udp.c,
+ * Server side for UDP/IP based RPC. (Does some caching in the hopes of
+ * achieving execute-at-most-once semantics.)
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+#define rpc_buffer(xprt) ((xprt)->xp_p1)
+#define MAX(a, b) ((a > b) ? a : b)
+
+static bool_t svcudp_recv();
+static bool_t svcudp_reply();
+static enum xprt_stat svcudp_stat();
+static bool_t svcudp_getargs();
+static bool_t svcudp_freeargs();
+static void svcudp_destroy();
+static void cache_set __P((SVCXPRT *, u_long));
+static int cache_get __P((SVCXPRT *, struct rpc_msg *, char **, u_long *));
+
+static struct xp_ops svcudp_op = {
+ svcudp_recv,
+ svcudp_stat,
+ svcudp_getargs,
+ svcudp_reply,
+ svcudp_freeargs,
+ svcudp_destroy
+};
+
+/*
+ * kept in xprt->xp_p2
+ */
+struct svcudp_data {
+ u_int su_iosz; /* byte size of send.recv buffer */
+ u_long su_xid; /* transaction id */
+ XDR su_xdrs; /* XDR handle */
+ char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */
+ char * su_cache; /* cached data, NULL if no cache */
+};
+#define su_data(xprt) ((struct svcudp_data *)(xprt->xp_p2))
+
+/*
+ * Usage:
+ * xprt = svcudp_create(sock);
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svcudp_create
+ * binds it to an arbitrary port. In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ * Once *xprt is initialized, it is registered as a transporter;
+ * see (svc.h, xprt_register).
+ * The routines returns NULL if a problem occurred.
+ */
+SVCXPRT *
+svcudp_bufcreate(sock, sendsz, recvsz)
+ register int sock;
+ u_int sendsz, recvsz;
+{
+ bool_t madesock = FALSE;
+ register SVCXPRT *xprt;
+ register struct svcudp_data *su;
+ struct sockaddr_in addr;
+ socklen_t len = sizeof(struct sockaddr_in);
+
+ if (sock == RPC_ANYSOCK) {
+ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ perror("svcudp_create: socket creation problem");
+ return ((SVCXPRT *)NULL);
+ }
+ madesock = TRUE;
+ }
+ memset((char *)&addr, 0, sizeof (addr));
+ addr.sin_len = sizeof(struct sockaddr_in);
+ addr.sin_family = AF_INET;
+ if (bindresvport(sock, &addr)) {
+ addr.sin_port = 0;
+ (void)bind(sock, (struct sockaddr *)&addr, len);
+ }
+ if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) {
+ perror("svcudp_create - cannot getsockname");
+ if (madesock)
+ (void)_RPC_close(sock);
+ return ((SVCXPRT *)NULL);
+ }
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == NULL) {
+ (void)fprintf(stderr, "svcudp_create: out of memory\n");
+ return (NULL);
+ }
+ su = (struct svcudp_data *)mem_alloc(sizeof(*su));
+ if (su == NULL) {
+ (void)fprintf(stderr, "svcudp_create: out of memory\n");
+ return (NULL);
+ }
+ su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
+ if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) {
+ (void)fprintf(stderr, "svcudp_create: out of memory\n");
+ return (NULL);
+ }
+ xdrmem_create(
+ &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE);
+ su->su_cache = NULL;
+ xprt->xp_p2 = (caddr_t)su;
+ xprt->xp_verf.oa_base = su->su_verfbody;
+ xprt->xp_ops = &svcudp_op;
+ xprt->xp_port = ntohs(addr.sin_port);
+ xprt->xp_sock = sock;
+ xprt_register(xprt);
+ return (xprt);
+}
+
+SVCXPRT *
+svcudp_create(sock)
+ int sock;
+{
+
+ return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum xprt_stat
+svcudp_stat(xprt)
+ SVCXPRT *xprt;
+{
+
+ return (XPRT_IDLE);
+}
+
+static bool_t
+svcudp_recv(xprt, msg)
+ register SVCXPRT *xprt;
+ struct rpc_msg *msg;
+{
+ register struct svcudp_data *su = su_data(xprt);
+ register XDR *xdrs = &(su->su_xdrs);
+ register int rlen;
+ char *reply;
+ u_long replylen;
+
+ again:
+ xprt->xp_addrlen = sizeof(struct sockaddr_in);
+ rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz,
+ 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen));
+ if (rlen == -1 && errno == EINTR)
+ goto again;
+ if (rlen == -1 || rlen < 4*sizeof(u_int32_t))
+ return (FALSE);
+ xdrs->x_op = XDR_DECODE;
+ XDR_SETPOS(xdrs, 0);
+ if (! xdr_callmsg(xdrs, msg))
+ return (FALSE);
+ su->su_xid = msg->rm_xid;
+ if (su->su_cache != NULL) {
+ if (cache_get(xprt, msg, &reply, &replylen)) {
+ (void) sendto(xprt->xp_sock, reply, (int) replylen, 0,
+ (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen);
+ return (TRUE);
+ }
+ }
+ return (TRUE);
+}
+
+static bool_t
+svcudp_reply(xprt, msg)
+ register SVCXPRT *xprt;
+ struct rpc_msg *msg;
+{
+ register struct svcudp_data *su = su_data(xprt);
+ register XDR *xdrs = &(su->su_xdrs);
+ register int slen;
+ register bool_t stat = FALSE;
+
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, 0);
+ msg->rm_xid = su->su_xid;
+ if (xdr_replymsg(xdrs, msg)) {
+ slen = (int)XDR_GETPOS(xdrs);
+ if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
+ (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
+ == slen) {
+ stat = TRUE;
+ if (su->su_cache && slen >= 0) {
+ cache_set(xprt, (u_long) slen);
+ }
+ }
+ }
+ return (stat);
+}
+
+static bool_t
+svcudp_getargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+
+ return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr));
+}
+
+static bool_t
+svcudp_freeargs(xprt, xdr_args, args_ptr)
+ SVCXPRT *xprt;
+ xdrproc_t xdr_args;
+ caddr_t args_ptr;
+{
+ register XDR *xdrs = &(su_data(xprt)->su_xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static void
+svcudp_destroy(xprt)
+ register SVCXPRT *xprt;
+{
+ register struct svcudp_data *su = su_data(xprt);
+
+ xprt_unregister(xprt);
+ (void)_RPC_close(xprt->xp_sock);
+ XDR_DESTROY(&(su->su_xdrs));
+ mem_free(rpc_buffer(xprt), su->su_iosz);
+ mem_free((caddr_t)su, sizeof(struct svcudp_data));
+ mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+
+/***********this could be a separate file*********************/
+
+/*
+ * Fifo cache for udp server
+ * Copies pointers to reply buffers into fifo cache
+ * Buffers are sent again if retransmissions are detected.
+ */
+
+#define SPARSENESS 4 /* 75% sparse */
+
+#define CACHE_PERROR(msg) \
+ (void) fprintf(stderr,"%s\n", msg)
+
+#define ALLOC(type, size) \
+ (type *) mem_alloc((unsigned) (sizeof(type) * (size)))
+
+#define BZERO(addr, type, size) \
+ memset((char *) addr, 0, sizeof(type) * (int) (size))
+
+/*
+ * An entry in the cache
+ */
+typedef struct cache_node *cache_ptr;
+struct cache_node {
+ /*
+ * Index into cache is xid, proc, vers, prog and address
+ */
+ u_long cache_xid;
+ u_long cache_proc;
+ u_long cache_vers;
+ u_long cache_prog;
+ struct sockaddr_in cache_addr;
+ /*
+ * The cached reply and length
+ */
+ char * cache_reply;
+ u_long cache_replylen;
+ /*
+ * Next node on the list, if there is a collision
+ */
+ cache_ptr cache_next;
+};
+
+
+
+/*
+ * The entire cache
+ */
+struct udp_cache {
+ u_long uc_size; /* size of cache */
+ cache_ptr *uc_entries; /* hash table of entries in cache */
+ cache_ptr *uc_fifo; /* fifo list of entries in cache */
+ u_long uc_nextvictim; /* points to next victim in fifo list */
+ u_long uc_prog; /* saved program number */
+ u_long uc_vers; /* saved version number */
+ u_long uc_proc; /* saved procedure number */
+ struct sockaddr_in uc_addr; /* saved caller's address */
+};
+
+
+/*
+ * the hashing function
+ */
+#define CACHE_LOC(transp, xid) \
+ (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size))
+
+
+/*
+ * Enable use of the cache.
+ * Note: there is no disable.
+ */
+int svcudp_enablecache(transp, size)
+ SVCXPRT *transp;
+ u_long size;
+{
+ struct svcudp_data *su = su_data(transp);
+ struct udp_cache *uc;
+
+ if (su->su_cache != NULL) {
+ CACHE_PERROR("enablecache: cache already enabled");
+ return(0);
+ }
+ uc = ALLOC(struct udp_cache, 1);
+ if (uc == NULL) {
+ CACHE_PERROR("enablecache: could not allocate cache");
+ return(0);
+ }
+ uc->uc_size = size;
+ uc->uc_nextvictim = 0;
+ uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS);
+ if (uc->uc_entries == NULL) {
+ CACHE_PERROR("enablecache: could not allocate cache data");
+ return(0);
+ }
+ BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS);
+ uc->uc_fifo = ALLOC(cache_ptr, size);
+ if (uc->uc_fifo == NULL) {
+ CACHE_PERROR("enablecache: could not allocate cache fifo");
+ return(0);
+ }
+ BZERO(uc->uc_fifo, cache_ptr, size);
+ su->su_cache = (char *) uc;
+ return(1);
+}
+
+
+/*
+ * Set an entry in the cache
+ */
+static void
+cache_set(xprt, replylen)
+ SVCXPRT *xprt;
+ u_long replylen;
+{
+ register cache_ptr victim;
+ register cache_ptr *vicp;
+ register struct svcudp_data *su = su_data(xprt);
+ struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+ u_int loc;
+ char *newbuf;
+
+ /*
+ * Find space for the new entry, either by
+ * reusing an old entry, or by mallocing a new one
+ */
+ victim = uc->uc_fifo[uc->uc_nextvictim];
+ if (victim != NULL) {
+ loc = CACHE_LOC(xprt, victim->cache_xid);
+ for (vicp = &uc->uc_entries[loc];
+ *vicp != NULL && *vicp != victim;
+ vicp = &(*vicp)->cache_next)
+ ;
+ if (*vicp == NULL) {
+ CACHE_PERROR("cache_set: victim not found");
+ return;
+ }
+ *vicp = victim->cache_next; /* remote from cache */
+ newbuf = victim->cache_reply;
+ } else {
+ victim = ALLOC(struct cache_node, 1);
+ if (victim == NULL) {
+ CACHE_PERROR("cache_set: victim alloc failed");
+ return;
+ }
+ newbuf = mem_alloc(su->su_iosz);
+ if (newbuf == NULL) {
+ CACHE_PERROR("cache_set: could not allocate new rpc_buffer");
+ return;
+ }
+ }
+
+ /*
+ * Store it away
+ */
+ victim->cache_replylen = replylen;
+ victim->cache_reply = rpc_buffer(xprt);
+ rpc_buffer(xprt) = newbuf;
+ xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE);
+ victim->cache_xid = su->su_xid;
+ victim->cache_proc = uc->uc_proc;
+ victim->cache_vers = uc->uc_vers;
+ victim->cache_prog = uc->uc_prog;
+ victim->cache_addr = uc->uc_addr;
+ loc = CACHE_LOC(xprt, victim->cache_xid);
+ victim->cache_next = uc->uc_entries[loc];
+ uc->uc_entries[loc] = victim;
+ uc->uc_fifo[uc->uc_nextvictim++] = victim;
+ uc->uc_nextvictim %= uc->uc_size;
+}
+
+/*
+ * Try to get an entry from the cache
+ * return 1 if found, 0 if not found
+ */
+static int
+cache_get(xprt, msg, replyp, replylenp)
+ SVCXPRT *xprt;
+ struct rpc_msg *msg;
+ char **replyp;
+ u_long *replylenp;
+{
+ u_int loc;
+ register cache_ptr ent;
+ register struct svcudp_data *su = su_data(xprt);
+ register struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+
+# define EQADDR(a1, a2) (memcmp(&a1, &a2, sizeof(a1)) == 0)
+
+ loc = CACHE_LOC(xprt, su->su_xid);
+ for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) {
+ if (ent->cache_xid == su->su_xid &&
+ ent->cache_proc == uc->uc_proc &&
+ ent->cache_vers == uc->uc_vers &&
+ ent->cache_prog == uc->uc_prog &&
+ EQADDR(ent->cache_addr, uc->uc_addr)) {
+ *replyp = ent->cache_reply;
+ *replylenp = ent->cache_replylen;
+ return(1);
+ }
+ }
+ /*
+ * Failed to find entry
+ * Remember a few things so we can do a set later
+ */
+ uc->uc_proc = msg->rm_call.cb_proc;
+ uc->uc_vers = msg->rm_call.cb_vers;
+ uc->uc_prog = msg->rm_call.cb_prog;
+ uc->uc_addr = xprt->xp_raddr;
+ return(0);
+}
diff --git a/cpukit/librpc/src/xdr/xdr.3 b/cpukit/librpc/src/xdr/xdr.3
new file mode 100644
index 0000000000..c1cdb11015
--- /dev/null
+++ b/cpukit/librpc/src/xdr/xdr.3
@@ -0,0 +1,837 @@
+.\" @(#)xdr.3n 2.2 88/08/03 4.0 RPCSRC; from 1.16 88/03/14 SMI
+.\" $FreeBSD: src/lib/libc/xdr/xdr.3,v 1.8 2000/03/02 09:14:05 sheldonh Exp $
+.\"
+.TH XDR 3 "16 February 1988"
+.SH NAME
+xdr \- library routines for external data representation
+.SH SYNOPSIS AND DESCRIPTION
+.LP
+These routines allow C programmers to describe
+arbitrary data structures in a machine-independent fashion.
+Data for remote procedure calls are transmitted using these
+routines.
+.LP
+.ft B
+.nf
+.sp .5
+xdr_array(xdrs, arrp, sizep, maxsize, elsize, elproc)
+\s-1XDR\s0 *xdrs;
+char **arrp;
+u_int *sizep, maxsize, elsize;
+xdrproc_t elproc;
+.fi
+.ft R
+.IP
+A filter primitive that translates between variable-length
+arrays
+and their corresponding external representations.
+The
+parameter
+.I arrp
+is the address of the pointer to the array, while
+.I sizep
+is the address of the element count of the array;
+this element count cannot exceed
+.IR maxsize .
+The parameter
+.I elsize
+is the
+.I sizeof
+each of the array's elements, and
+.I elproc
+is an
+.SM XDR
+filter that translates between
+the array elements' C form, and their external
+representation.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_bool(xdrs, bp)
+\s-1XDR\s0 *xdrs;
+bool_t *bp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between booleans (C
+integers)
+and their external representations.
+When encoding data, this
+filter produces values of either one or zero.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_bytes(xdrs, sp, sizep, maxsize)
+\s-1XDR\s0 *xdrs;
+char **sp;
+u_int *sizep, maxsize;
+.fi
+.ft R
+.IP
+A filter primitive that translates between counted byte
+strings and their external representations.
+The parameter
+.I sp
+is the address of the string pointer.
+The length of the
+string is located at address
+.IR sizep ;
+strings cannot be longer than
+.IR maxsize .
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_char(xdrs, cp)
+\s-1XDR\s0 *xdrs;
+char *cp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C characters
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+Note: encoded characters are not packed, and occupy 4 bytes
+each.
+For arrays of characters, it is worthwhile to
+consider
+.BR xdr_bytes(\|) ,
+.B xdr_opaque(\|)
+or
+.BR xdr_string(\|) .
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdr_destroy(xdrs)
+\s-1XDR\s0 *xdrs;
+.fi
+.ft R
+.IP
+A macro that invokes the destroy routine associated with the
+.SM XDR
+stream,
+.IR xdrs .
+Destruction usually involves freeing private data structures
+associated with the stream. Using
+.I xdrs
+after invoking
+.B xdr_destroy(\|)
+is undefined.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_double(xdrs, dp)
+\s-1XDR\s0 *xdrs;
+double *dp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B double
+precision numbers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_enum(xdrs, ep)
+\s-1XDR\s0 *xdrs;
+enum_t *ep;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.BR enum s
+(actually integers) and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_float(xdrs, fp)
+\s-1XDR\s0 *xdrs;
+float *fp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.BR float s
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdr_free(proc, objp)
+xdrproc_t proc;
+char *objp;
+.fi
+.ft R
+.IP
+Generic freeing routine.
+The first argument is the
+.SM XDR
+routine for the object being freed.
+The second argument
+is a pointer to the object itself.
+Note: the pointer passed
+to this routine is
+.I not
+freed, but what it points to
+.I is
+freed (recursively).
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+u_int
+xdr_getpos(xdrs)
+\s-1XDR\s0 *xdrs;
+.fi
+.ft R
+.IP
+A macro that invokes the get-position routine
+associated with the
+.SM XDR
+stream,
+.IR xdrs .
+The routine returns an unsigned integer,
+which indicates the position of the
+.SM XDR
+byte stream.
+A desirable feature of
+.SM XDR
+streams is that simple arithmetic works with this number,
+although the
+.SM XDR
+stream instances need not guarantee this.
+.br
+.if t .ne 4
+.LP
+.ft B
+.nf
+.sp .5
+.br
+long *
+xdr_inline(xdrs, len)
+\s-1XDR\s0 *xdrs;
+int len;
+.fi
+.ft R
+.IP
+A macro that invokes the in-line routine associated with the
+.SM XDR
+stream,
+.IR xdrs .
+The routine returns a pointer
+to a contiguous piece of the stream's buffer;
+.I len
+is the byte length of the desired buffer.
+Note: pointer is cast to
+.BR "long *" .
+.IP
+Warning:
+.B xdr_inline(\|)
+may return
+.SM NULL
+(0)
+if it cannot allocate a contiguous piece of a buffer.
+Therefore the behavior may vary among stream instances;
+it exists for the sake of efficiency.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_int(xdrs, ip)
+\s-1XDR\s0 *xdrs;
+int *ip;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C integers
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_long(xdrs, lp)
+\s-1XDR\s0 *xdrs;
+long *lp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B long
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 12
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdrmem_create(xdrs, addr, size, op)
+\s-1XDR\s0 *xdrs;
+char *addr;
+u_int size;
+enum xdr_op op;
+.fi
+.ft R
+.IP
+This routine initializes the
+.SM XDR
+stream object pointed to by
+.IR xdrs .
+The stream's data is written to, or read from,
+a chunk of memory at location
+.I addr
+whose length is no more than
+.I size
+bytes long. The
+.I op
+determines the direction of the
+.SM XDR
+stream
+(either
+.BR \s-1XDR_ENCODE\s0 ,
+.BR \s-1XDR_DECODE\s0 ,
+or
+.BR \s-1XDR_FREE\s0 ).
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_opaque(xdrs, cp, cnt)
+\s-1XDR\s0 *xdrs;
+char *cp;
+u_int cnt;
+.fi
+.ft R
+.IP
+A filter primitive that translates between fixed size opaque
+data
+and its external representation.
+The parameter
+.I cp
+is the address of the opaque object, and
+.I cnt
+is its size in bytes.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_pointer(xdrs, objpp, objsize, xdrobj)
+\s-1XDR\s0 *xdrs;
+char **objpp;
+u_int objsize;
+xdrproc_t xdrobj;
+.fi
+.ft R
+.IP
+Like
+.B xdr_reference(\|)
+execpt that it serializes
+.SM NULL
+pointers, whereas
+.B xdr_reference(\|)
+does not. Thus,
+.B xdr_pointer(\|)
+can represent
+recursive data structures, such as binary trees or
+linked lists.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdrrec_create(xdrs, sendsize, recvsize, handle, readit, writeit)
+\s-1XDR\s0 *xdrs;
+u_int sendsize, recvsize;
+char *handle;
+int (*readit) (\|), (*writeit) (\|);
+.fi
+.ft R
+.IP
+This routine initializes the
+.SM XDR
+stream object pointed to by
+.IR xdrs .
+The stream's data is written to a buffer of size
+.IR sendsize ;
+a value of zero indicates the system should use a suitable
+default.
+The stream's data is read from a buffer of size
+.IR recvsize ;
+it too can be set to a suitable default by passing a zero
+value.
+When a stream's output buffer is full,
+.I writeit
+is called. Similarly, when a stream's input buffer is empty,
+.I readit
+is called. The behavior of these two routines is similar to
+the
+system calls
+.B read
+and
+.BR write ,
+except that
+.I handle
+is passed to the former routines as the first parameter.
+Note: the
+.SM XDR
+stream's
+.I op
+field must be set by the caller.
+.IP
+Warning: this
+.SM XDR
+stream implements an intermediate record stream.
+Therefore there are additional bytes in the stream
+to provide record boundary information.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+xdrrec_endofrecord(xdrs, sendnow)
+\s-1XDR\s0 *xdrs;
+int sendnow;
+.fi
+.ft R
+.IP
+This routine can be invoked only on
+streams created by
+.BR xdrrec_create(\|) .
+The data in the output buffer is marked as a completed
+record,
+and the output buffer is optionally written out if
+.I sendnow
+is non-zero.
+This routine returns one if it succeeds, zero
+otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdrrec_eof(xdrs)
+\s-1XDR\s0 *xdrs;
+int empty;
+.fi
+.ft R
+.IP
+This routine can be invoked only on
+streams created by
+.BR xdrrec_create(\|) .
+After consuming the rest of the current record in the stream,
+this routine returns one if the stream has no more input,
+zero otherwise.
+.br
+.if t .ne 3
+.LP
+.ft B
+.nf
+.sp .5
+xdrrec_skiprecord(xdrs)
+\s-1XDR\s0 *xdrs;
+.fi
+.ft R
+.IP
+This routine can be invoked only on
+streams created by
+.BR xdrrec_create(\|) .
+It tells the
+.SM XDR
+implementation that the rest of the current record
+in the stream's input buffer should be discarded.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+xdr_reference(xdrs, pp, size, proc)
+\s-1XDR\s0 *xdrs;
+char **pp;
+u_int size;
+xdrproc_t proc;
+.fi
+.ft R
+.IP
+A primitive that provides pointer chasing within structures.
+The parameter
+.I pp
+is the address of the pointer;
+.I size
+is the
+.I sizeof
+the structure that
+.I *pp
+points to; and
+.I proc
+is an
+.SM XDR
+procedure that filters the structure
+between its C form and its external representation.
+This routine returns one if it succeeds, zero otherwise.
+.IP
+Warning: this routine does not understand
+.SM NULL
+pointers.
+Use
+.B xdr_pointer(\|)
+instead.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_setpos(xdrs, pos)
+\s-1XDR\s0 *xdrs;
+u_int pos;
+.fi
+.ft R
+.IP
+A macro that invokes the set position routine associated with
+the
+.SM XDR
+stream
+.IR xdrs .
+The parameter
+.I pos
+is a position value obtained from
+.BR xdr_getpos(\|) .
+This routine returns one if the
+.SM XDR
+stream could be repositioned,
+and zero otherwise.
+.IP
+Warning: it is difficult to reposition some types of
+.SM XDR
+streams, so this routine may fail with one
+type of stream and succeed with another.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_short(xdrs, sp)
+\s-1XDR\s0 *xdrs;
+short *sp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B short
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdrstdio_create(xdrs, file, op)
+\s-1XDR\s0 *xdrs;
+\s-1FILE\s0 *file;
+enum xdr_op op;
+.fi
+.ft R
+.IP
+This routine initializes the
+.SM XDR
+stream object pointed to by
+.IR xdrs .
+The
+.SM XDR
+stream data is written to, or read from, the Standard
+.B I/O
+stream
+.IR file .
+The parameter
+.I op
+determines the direction of the
+.SM XDR
+stream (either
+.BR \s-1XDR_ENCODE\s0 ,
+.BR \s-1XDR_DECODE\s0 ,
+or
+.BR \s-1XDR_FREE\s0 ).
+.IP
+Warning: the destroy routine associated with such
+.SM XDR
+streams calls
+.B fflush(\|)
+on the
+.I file
+stream, but never
+.BR fclose(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+xdr_string(xdrs, sp, maxsize)
+\s-1XDR\s0
+*xdrs;
+char **sp;
+u_int maxsize;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C strings and
+their
+corresponding external representations.
+Strings cannot be longer than
+.IR maxsize .
+Note:
+.I sp
+is the address of the string's pointer.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_char(xdrs, ucp)
+\s-1XDR\s0 *xdrs;
+unsigned char *ucp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between
+.B unsigned
+C characters and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_int(xdrs, up)
+\s-1XDR\s0 *xdrs;
+unsigned *up;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B unsigned
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_long(xdrs, ulp)
+\s-1XDR\s0 *xdrs;
+unsigned long *ulp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B "unsigned long"
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_short(xdrs, usp)
+\s-1XDR\s0 *xdrs;
+unsigned short *usp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B "unsigned short"
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 16
+.LP
+.ft B
+.nf
+.sp .5
+xdr_union(xdrs, dscmp, unp, choices, dfault)
+\s-1XDR\s0 *xdrs;
+int *dscmp;
+char *unp;
+struct xdr_discrim *choices;
+bool_t (*defaultarm) (\|); /* may equal \s-1NULL\s0 */
+.fi
+.ft R
+.IP
+A filter primitive that translates between a discriminated C
+.B union
+and its corresponding external representation.
+It first
+translates the discriminant of the union located at
+.IR dscmp .
+This discriminant is always an
+.BR enum_t .
+Next the union located at
+.I unp
+is translated. The parameter
+.I choices
+is a pointer to an array of
+.B xdr_discrim(\|)
+structures.
+Each structure contains an ordered pair of
+.RI [ value , proc ].
+If the union's discriminant is equal to the associated
+.IR value ,
+then the
+.I proc
+is called to translate the union. The end of the
+.B xdr_discrim(\|)
+structure array is denoted by a routine of value
+.SM NULL\s0.
+If the discriminant is not found in the
+.I choices
+array, then the
+.I defaultarm
+procedure is called (if it is not
+.SM NULL\s0).
+Returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+xdr_vector(xdrs, arrp, size, elsize, elproc)
+\s-1XDR\s0 *xdrs;
+char *arrp;
+u_int size, elsize;
+xdrproc_t elproc;
+.fi
+.ft R
+.IP
+A filter primitive that translates between fixed-length
+arrays
+and their corresponding external representations. The
+parameter
+.I arrp
+is the address of the pointer to the array, while
+.I size
+is the element count of the array. The parameter
+.I elsize
+is the
+.I sizeof
+each of the array's elements, and
+.I elproc
+is an
+.SM XDR
+filter that translates between
+the array elements' C form, and their external
+representation.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 5
+.LP
+.ft B
+.nf
+.sp .5
+xdr_void(\|)
+.fi
+.ft R
+.IP
+This routine always returns one.
+It may be passed to
+.SM RPC
+routines that require a function parameter,
+where nothing is to be done.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_wrapstring(xdrs, sp)
+\s-1XDR\s0 *xdrs;
+char **sp;
+.fi
+.ft R
+.IP
+A primitive that calls
+.B "xdr_string(xdrs, sp,\s-1MAXUN.UNSIGNED\s0 );"
+where
+.B
+.SM MAXUN.UNSIGNED
+is the maximum value of an unsigned integer.
+.B xdr_wrapstring(\|)
+is handy because the
+.SM RPC
+package passes a maximum of two
+.SM XDR
+routines as parameters, and
+.BR xdr_string(\|) ,
+one of the most frequently used primitives, requires three.
+Returns one if it succeeds, zero otherwise.
+.SH SEE ALSO
+.BR rpc (3)
+.LP
+The following manuals:
+.RS
+.ft I
+eXternal Data Representation Standard: Protocol Specification
+.br
+eXternal Data Representation: Sun Technical Notes
+.ft R
+.br
+.IR "\s-1XDR\s0: External Data Representation Standard" ,
+.SM RFC1014, Sun Microsystems, Inc.,
+.SM USC-ISI\s0.
diff --git a/cpukit/librpc/src/xdr/xdr.c b/cpukit/librpc/src/xdr/xdr.c
new file mode 100644
index 0000000000..898c1f24ff
--- /dev/null
+++ b/cpukit/librpc/src/xdr/xdr.c
@@ -0,0 +1,858 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr.c 1.35 87/08/12";*/
+/*static char *sccsid = "from: @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr.c,v 1.9 1999/08/28 00:02:55 peter Exp $";
+#endif
+
+/*
+ * xdr.c, Generic XDR routines implementation.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ *
+ * These are the "generic" xdr routines used to serialize and de-serialize
+ * most common data items. See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#if defined(__rtems__)
+#define warnx(msg) fprintf(stderr, msg "\n");
+#endif
+
+/*
+ * constants specific to the xdr "protocol"
+ */
+#define XDR_FALSE ((long) 0)
+#define XDR_TRUE ((long) 1)
+#define LASTUNSIGNED ((u_int) 0-1)
+
+/*
+ * for unit alignment
+ */
+static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
+
+/*
+ * Free a data structure using XDR
+ * Not a filter, but a convenient utility nonetheless
+ */
+void
+xdr_free(proc, objp)
+ xdrproc_t proc;
+ char *objp;
+{
+ XDR x;
+
+ x.x_op = XDR_FREE;
+ (*proc)(&x, objp);
+}
+
+/*
+ * XDR nothing
+ */
+bool_t
+xdr_void(/* xdrs, addr */)
+ /* XDR *xdrs; */
+ /* caddr_t addr; */
+{
+
+ return (TRUE);
+}
+
+
+/*
+ * XDR integers
+ */
+bool_t
+xdr_int(xdrs, ip)
+ XDR *xdrs;
+ int *ip;
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *ip;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *ip = (int) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned integers
+ */
+bool_t
+xdr_u_int(xdrs, up)
+ XDR *xdrs;
+ u_int *up;
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *up;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *up = (u_int) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+
+/*
+ * XDR long integers
+ * same as xdr_u_long - open coded to save a proc call!
+ */
+bool_t
+xdr_long(xdrs, lp)
+ XDR *xdrs;
+ long *lp;
+{
+ switch (xdrs->x_op) {
+ case XDR_ENCODE:
+ return (XDR_PUTLONG(xdrs, lp));
+ case XDR_DECODE:
+ return (XDR_GETLONG(xdrs, lp));
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned long integers
+ * same as xdr_long - open coded to save a proc call!
+ */
+bool_t
+xdr_u_long(xdrs, ulp)
+ XDR *xdrs;
+ u_long *ulp;
+{
+ switch (xdrs->x_op) {
+ case XDR_ENCODE:
+ return (XDR_PUTLONG(xdrs, (long *)ulp));
+ case XDR_DECODE:
+ return (XDR_GETLONG(xdrs, (long *)ulp));
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+
+/*
+ * XDR 32-bit integers
+ * same as xdr_u_int32_t - open coded to save a proc call!
+ */
+bool_t
+xdr_int32_t(xdrs, int32_p)
+ XDR *xdrs;
+ int32_t *int32_p;
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *int32_p;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *int32_p = (int32_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned 32-bit integers
+ * same as xdr_int32_t - open coded to save a proc call!
+ */
+bool_t
+xdr_u_int32_t(xdrs, u_int32_p)
+ XDR *xdrs;
+ u_int32_t *u_int32_p;
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *u_int32_p;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *u_int32_p = (u_int32_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR short integers
+ */
+bool_t
+xdr_short(xdrs, sp)
+ XDR *xdrs;
+ short *sp;
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *sp;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *sp = (short) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned short integers
+ */
+bool_t
+xdr_u_short(xdrs, usp)
+ XDR *xdrs;
+ u_short *usp;
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *usp;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *usp = (u_short) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+
+/*
+ * XDR 16-bit integers
+ */
+bool_t
+xdr_int16_t(xdrs, int16_p)
+ XDR *xdrs;
+ int16_t *int16_p;
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *int16_p;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *int16_p = (int16_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned 16-bit integers
+ */
+bool_t
+xdr_u_int16_t(xdrs, u_int16_p)
+ XDR *xdrs;
+ u_int16_t *u_int16_p;
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *u_int16_p;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *u_int16_p = (u_int16_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+
+/*
+ * XDR a char
+ */
+bool_t
+xdr_char(xdrs, cp)
+ XDR *xdrs;
+ char *cp;
+{
+ int i;
+
+ i = (*cp);
+ if (!xdr_int(xdrs, &i)) {
+ return (FALSE);
+ }
+ *cp = i;
+ return (TRUE);
+}
+
+/*
+ * XDR an unsigned char
+ */
+bool_t
+xdr_u_char(xdrs, cp)
+ XDR *xdrs;
+ u_char *cp;
+{
+ u_int u;
+
+ u = (*cp);
+ if (!xdr_u_int(xdrs, &u)) {
+ return (FALSE);
+ }
+ *cp = u;
+ return (TRUE);
+}
+
+/*
+ * XDR booleans
+ */
+bool_t
+xdr_bool(xdrs, bp)
+ XDR *xdrs;
+ bool_t *bp;
+{
+ long lb;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ lb = *bp ? XDR_TRUE : XDR_FALSE;
+ return (XDR_PUTLONG(xdrs, &lb));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &lb)) {
+ return (FALSE);
+ }
+ *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR enumerations
+ */
+bool_t
+xdr_enum(xdrs, ep)
+ XDR *xdrs;
+ enum_t *ep;
+{
+#ifndef lint
+ enum sizecheck { SIZEVAL }; /* used to find the size of an enum */
+
+ /*
+ * enums are treated as ints
+ */
+ if (sizeof (enum sizecheck) == sizeof (long)) {
+ return (xdr_long(xdrs, (long *)ep));
+ } else if (sizeof (enum sizecheck) == sizeof (int)) {
+ return (xdr_int(xdrs, (int *)ep));
+ } else if (sizeof (enum sizecheck) == sizeof (short)) {
+ return (xdr_short(xdrs, (short *)ep));
+ } else {
+ return (FALSE);
+ }
+#else
+ (void) (xdr_short(xdrs, (short *)ep));
+ (void) (xdr_int(xdrs, (int *)ep));
+ return (xdr_long(xdrs, (long *)ep));
+#endif
+}
+
+/*
+ * XDR opaque data
+ * Allows the specification of a fixed size sequence of opaque bytes.
+ * cp points to the opaque object and cnt gives the byte length.
+ */
+bool_t
+xdr_opaque(xdrs, cp, cnt)
+ XDR *xdrs;
+ caddr_t cp;
+ u_int cnt;
+{
+ u_int rndup;
+ static int crud[BYTES_PER_XDR_UNIT];
+
+ /*
+ * if no data we are done
+ */
+ if (cnt == 0)
+ return (TRUE);
+
+ /*
+ * round byte count to full xdr units
+ */
+ rndup = cnt % BYTES_PER_XDR_UNIT;
+ if (rndup > 0)
+ rndup = BYTES_PER_XDR_UNIT - rndup;
+
+ if (xdrs->x_op == XDR_DECODE) {
+ if (!XDR_GETBYTES(xdrs, cp, cnt)) {
+ return (FALSE);
+ }
+ if (rndup == 0)
+ return (TRUE);
+ return (XDR_GETBYTES(xdrs, (caddr_t)crud, rndup));
+ }
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
+ return (FALSE);
+ }
+ if (rndup == 0)
+ return (TRUE);
+ return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
+ }
+
+ if (xdrs->x_op == XDR_FREE) {
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+/*
+ * XDR counted bytes
+ * *cpp is a pointer to the bytes, *sizep is the count.
+ * If *cpp is NULL maxsize bytes are allocated
+ */
+bool_t
+xdr_bytes(xdrs, cpp, sizep, maxsize)
+ XDR *xdrs;
+ char **cpp;
+ u_int *sizep;
+ u_int maxsize;
+{
+ char *sp = *cpp; /* sp is the actual string pointer */
+ u_int nodesize;
+
+ /*
+ * first deal with the length since xdr bytes are counted
+ */
+ if (! xdr_u_int(xdrs, sizep)) {
+ return (FALSE);
+ }
+ nodesize = *sizep;
+ if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
+ return (FALSE);
+ }
+
+ /*
+ * now deal with the actual bytes
+ */
+ switch (xdrs->x_op) {
+
+ case XDR_DECODE:
+ if (nodesize == 0) {
+ return (TRUE);
+ }
+ if (sp == NULL) {
+ *cpp = sp = mem_alloc(nodesize);
+ }
+ if (sp == NULL) {
+ warnx("xdr_bytes: out of memory");
+ return (FALSE);
+ }
+ /* FALLTHROUGH */
+
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, sp, nodesize));
+
+ case XDR_FREE:
+ if (sp != NULL) {
+ mem_free(sp, nodesize);
+ *cpp = NULL;
+ }
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * Implemented here due to commonality of the object.
+ */
+bool_t
+xdr_netobj(xdrs, np)
+ XDR *xdrs;
+ struct netobj *np;
+{
+
+ return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
+}
+
+/*
+ * XDR a descriminated union
+ * Support routine for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * an entry with a null procedure pointer. The routine gets
+ * the discriminant value and then searches the array of xdrdiscrims
+ * looking for that value. It calls the procedure given in the xdrdiscrim
+ * to handle the discriminant. If there is no specific routine a default
+ * routine may be called.
+ * If there is no specific or default routine an error is returned.
+ */
+bool_t
+xdr_union(xdrs, dscmp, unp, choices, dfault)
+ XDR *xdrs;
+ enum_t *dscmp; /* enum to decide which arm to work on */
+ char *unp; /* the union itself */
+ const struct xdr_discrim *choices; /* [value, xdr proc] for each arm */
+ xdrproc_t dfault; /* default xdr routine */
+{
+ enum_t dscm;
+
+ /*
+ * we deal with the discriminator; it's an enum
+ */
+ if (! xdr_enum(xdrs, dscmp)) {
+ return (FALSE);
+ }
+ dscm = *dscmp;
+
+ /*
+ * search choices for a value that matches the discriminator.
+ * if we find one, execute the xdr routine for that value.
+ */
+ for (; choices->proc != NULL_xdrproc_t; choices++) {
+ if (choices->value == dscm)
+ return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
+ }
+
+ /*
+ * no match - execute the default xdr routine if there is one
+ */
+ return ((dfault == NULL_xdrproc_t) ? FALSE :
+ (*dfault)(xdrs, unp, LASTUNSIGNED));
+}
+
+
+/*
+ * Non-portable xdr primitives.
+ * Care should be taken when moving these routines to new architectures.
+ */
+
+
+/*
+ * XDR null terminated ASCII strings
+ * xdr_string deals with "C strings" - arrays of bytes that are
+ * terminated by a NULL character. The parameter cpp references a
+ * pointer to storage; If the pointer is null, then the necessary
+ * storage is allocated. The last parameter is the max allowed length
+ * of the string as specified by a protocol.
+ */
+bool_t
+xdr_string(xdrs, cpp, maxsize)
+ XDR *xdrs;
+ char **cpp;
+ u_int maxsize;
+{
+ char *sp = *cpp; /* sp is the actual string pointer */
+ u_int size = 0;
+ u_int nodesize;
+
+ /*
+ * first deal with the length since xdr strings are counted-strings
+ */
+ switch (xdrs->x_op) {
+ case XDR_FREE:
+ if (sp == NULL) {
+ return(TRUE); /* already free */
+ }
+ /* FALLTHROUGH */
+ case XDR_ENCODE:
+ size = strlen(sp);
+ break;
+ case XDR_DECODE:
+ break;
+ }
+ if (! xdr_u_int(xdrs, &size)) {
+ return (FALSE);
+ }
+ if (size > maxsize) {
+ return (FALSE);
+ }
+ nodesize = size + 1;
+
+ /*
+ * now deal with the actual bytes
+ */
+ switch (xdrs->x_op) {
+
+ case XDR_DECODE:
+ if (nodesize == 0) {
+ return (TRUE);
+ }
+ if (sp == NULL)
+ *cpp = sp = mem_alloc(nodesize);
+ if (sp == NULL) {
+ warnx("xdr_string: out of memory");
+ return (FALSE);
+ }
+ sp[size] = 0;
+ /* FALLTHROUGH */
+
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, sp, size));
+
+ case XDR_FREE:
+ mem_free(sp, nodesize);
+ *cpp = NULL;
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * Wrapper for xdr_string that can be called directly from
+ * routines like clnt_call
+ */
+bool_t
+xdr_wrapstring(xdrs, cpp)
+ XDR *xdrs;
+ char **cpp;
+{
+ return xdr_string(xdrs, cpp, LASTUNSIGNED);
+}
+
+/*
+ * XDR 64-bit integers
+ */
+bool_t
+xdr_int64_t(xdrs, int64_p)
+ XDR *xdrs;
+ int64_t *int64_p;
+{
+ int64_t x;
+
+ switch (xdrs->x_op) {
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, (caddr_t)int64_p, sizeof(int64_t)));
+ case XDR_DECODE:
+ if (!xdr_opaque(xdrs, (caddr_t)&x, sizeof x)) {
+ return (FALSE);
+ }
+ *int64_p = x;
+ return (TRUE);
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+
+/*
+ * XDR unsigned 64-bit integers
+ */
+bool_t
+xdr_u_int64_t(xdrs, uint64_p)
+ XDR *xdrs;
+ u_int64_t *uint64_p;
+{
+ u_int64_t x;
+
+ switch (xdrs->x_op) {
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, (caddr_t)uint64_p, sizeof(u_int64_t)));
+ case XDR_DECODE:
+ if (!xdr_opaque(xdrs, (caddr_t)&x, sizeof x)) {
+ return (FALSE);
+ }
+ *uint64_p = x;
+ return (TRUE);
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/* FIXME: RTEMS does not support u_longlong_t and longlong_t, yet */
+#if !defined(__rtems__)
+/*
+ * XDR hypers
+ */
+bool_t
+xdr_hyper(xdrs, llp)
+ XDR *xdrs;
+ longlong_t *llp;
+{
+
+ /*
+ * Don't bother open-coding this; it's a fair amount of code. Just
+ * call xdr_int64_t().
+ */
+ return (xdr_int64_t(xdrs, (int64_t *)llp));
+}
+
+
+/*
+ * XDR unsigned hypers
+ */
+bool_t
+xdr_u_hyper(xdrs, ullp)
+ XDR *xdrs;
+ u_longlong_t *ullp;
+{
+
+ /*
+ * Don't bother open-coding this; it's a fair amount of code. Just
+ * call xdr_u_int64_t().
+ */
+ return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
+}
+
+
+/*
+ * XDR longlong_t's
+ */
+bool_t
+xdr_longlong_t(xdrs, llp)
+ XDR *xdrs;
+ longlong_t *llp;
+{
+
+ /*
+ * Don't bother open-coding this; it's a fair amount of code. Just
+ * call xdr_int64_t().
+ */
+ return (xdr_int64_t(xdrs, (int64_t *)llp));
+}
+
+
+/*
+ * XDR u_longlong_t's
+ */
+bool_t
+xdr_u_longlong_t(xdrs, ullp)
+ XDR *xdrs;
+ u_longlong_t *ullp;
+{
+
+ /*
+ * Don't bother open-coding this; it's a fair amount of code. Just
+ * call xdr_u_int64_t().
+ */
+ return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
+}
+#endif
diff --git a/cpukit/librpc/src/xdr/xdr_array.c b/cpukit/librpc/src/xdr/xdr_array.c
new file mode 100644
index 0000000000..53ced17096
--- /dev/null
+++ b/cpukit/librpc/src/xdr/xdr_array.c
@@ -0,0 +1,156 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_array.c,v 1.8 1999/08/28 00:02:55 peter Exp $";
+#endif
+
+/*
+ * xdr_array.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * arrays. See xdr.h for more info on the interface to xdr.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED ((u_int) 0-1)
+
+/*
+ * XDR an array of arbitrary elements
+ * *addrp is a pointer to the array, *sizep is the number of elements.
+ * If addrp is NULL (*sizep * elsize) bytes are allocated.
+ * elsize is the size (in bytes) of each element, and elproc is the
+ * xdr procedure to call to handle each element of the array.
+ */
+bool_t
+xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc)
+ register XDR *xdrs;
+ caddr_t *addrp; /* array pointer */
+ u_int *sizep; /* number of elements */
+ u_int maxsize; /* max numberof elements */
+ u_int elsize; /* size in bytes of each element */
+ xdrproc_t elproc; /* xdr routine to handle each element */
+{
+ register u_int i;
+ register caddr_t target = *addrp;
+ register u_int c; /* the actual element count */
+ register bool_t stat = TRUE;
+ register u_int nodesize;
+
+ /* like strings, arrays are really counted arrays */
+ if (! xdr_u_int(xdrs, sizep)) {
+ return (FALSE);
+ }
+ c = *sizep;
+ if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
+ return (FALSE);
+ }
+ nodesize = c * elsize;
+
+ /*
+ * if we are deserializing, we may need to allocate an array.
+ * We also save time by checking for a null array if we are freeing.
+ */
+ if (target == NULL)
+ switch (xdrs->x_op) {
+ case XDR_DECODE:
+ if (c == 0)
+ return (TRUE);
+ *addrp = target = mem_alloc(nodesize);
+ if (target == NULL) {
+ (void) fprintf(stderr,
+ "xdr_array: out of memory\n");
+ return (FALSE);
+ }
+ memset(target, 0, nodesize);
+ break;
+
+ case XDR_FREE:
+ return (TRUE);
+ case XDR_ENCODE: /* to avoid warning */
+ break;
+ }
+
+ /*
+ * now we xdr each element of array
+ */
+ for (i = 0; (i < c) && stat; i++) {
+ stat = (*elproc)(xdrs, target, LASTUNSIGNED);
+ target += elsize;
+ }
+
+ /*
+ * the array may need freeing
+ */
+ if (xdrs->x_op == XDR_FREE) {
+ mem_free(*addrp, nodesize);
+ *addrp = NULL;
+ }
+ return (stat);
+}
+
+/*
+ * xdr_vector():
+ *
+ * XDR a fixed length array. Unlike variable-length arrays,
+ * the storage of fixed length arrays is static and unfreeable.
+ * > basep: base of the array
+ * > size: size of the array
+ * > elemsize: size of each element
+ * > xdr_elem: routine to XDR each element
+ */
+bool_t
+xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem)
+ register XDR *xdrs;
+ register char *basep;
+ register u_int nelem;
+ register u_int elemsize;
+ register xdrproc_t xdr_elem;
+{
+ register u_int i;
+ register char *elptr;
+
+ elptr = basep;
+ for (i = 0; i < nelem; i++) {
+ if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) {
+ return(FALSE);
+ }
+ elptr += elemsize;
+ }
+ return(TRUE);
+}
diff --git a/cpukit/librpc/src/xdr/xdr_float.c b/cpukit/librpc/src/xdr/xdr_float.c
new file mode 100644
index 0000000000..3e8922a220
--- /dev/null
+++ b/cpukit/librpc/src/xdr/xdr_float.c
@@ -0,0 +1,334 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_float.c,v 1.7 1999/08/28 00:02:55 peter Exp $";
+#endif
+
+/*
+ * xdr_float.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "floating point" xdr routines used to (de)serialize
+ * most common data items. See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+/*
+ * NB: Not portable.
+ * This routine works on machines with IEEE754 FP and Vaxen.
+ */
+
+#if defined(__alpha__) || \
+ defined(_AM29K) || \
+ defined(__arm__) || \
+ defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || \
+ defined(__hppa__) || \
+ defined(__i386__) || \
+ defined(__m68k__) || defined(__mc68000__) || \
+ defined(__mips__) || \
+ defined(__nios2__) || \
+ defined(__ns32k__) || \
+ defined(__sparc__) || \
+ defined(__ppc__) || defined(__PPC__) || \
+ defined(__sh__) || \
+ defined(__AVR__)
+
+#include <machine/endian.h>
+#if !defined(IEEEFP)
+#define IEEEFP
+#endif
+
+#elif defined(_TMS320C3x) || defined(_TMS320C4x)
+#error "Texas Instruments C3x/C4x Not supported."
+
+#elif defined(vax)
+
+/* What IEEE single precision floating point looks like on a Vax */
+struct ieee_single {
+ unsigned int mantissa: 23;
+ unsigned int exp : 8;
+ unsigned int sign : 1;
+};
+
+/* Vax single precision floating point */
+struct vax_single {
+ unsigned int mantissa1 : 7;
+ unsigned int exp : 8;
+ unsigned int sign : 1;
+ unsigned int mantissa2 : 16;
+};
+
+#define VAX_SNG_BIAS 0x81
+#define IEEE_SNG_BIAS 0x7f
+
+static struct sgl_limits {
+ struct vax_single s;
+ struct ieee_single ieee;
+} sgl_limits[2] = {
+ {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */
+ { 0x0, 0xff, 0x0 }}, /* Max IEEE */
+ {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
+ { 0x0, 0x0, 0x0 }} /* Min IEEE */
+};
+/* end of vax */
+#else
+#error "xdr_float.c: unknown CPU"
+#endif
+
+
+bool_t
+xdr_float(xdrs, fp)
+ register XDR *xdrs;
+ register float *fp;
+{
+#ifdef IEEEFP
+ bool_t rv;
+ long tmpl;
+#else
+ struct ieee_single is;
+ struct vax_single vs, *vsp;
+ struct sgl_limits *lim;
+ int i;
+#endif
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+#ifdef IEEEFP
+ tmpl = *(int32_t *)fp;
+ return (XDR_PUTLONG(xdrs, &tmpl));
+#else
+ vs = *((struct vax_single *)fp);
+ for (i = 0, lim = sgl_limits;
+ i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
+ i++, lim++) {
+ if ((vs.mantissa2 == lim->s.mantissa2) &&
+ (vs.exp == lim->s.exp) &&
+ (vs.mantissa1 == lim->s.mantissa1)) {
+ is = lim->ieee;
+ goto shipit;
+ }
+ }
+ is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
+ is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
+ shipit:
+ is.sign = vs.sign;
+ return (XDR_PUTLONG(xdrs, (long *)&is));
+#endif
+
+ case XDR_DECODE:
+#ifdef IEEEFP
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *(int32_t *)fp = tmpl;
+ return (rv);
+#else
+ vsp = (struct vax_single *)fp;
+ if (!XDR_GETLONG(xdrs, (long *)&is))
+ return (FALSE);
+ for (i = 0, lim = sgl_limits;
+ i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
+ i++, lim++) {
+ if ((is.exp == lim->ieee.exp) &&
+ (is.mantissa == lim->ieee.mantissa)) {
+ *vsp = lim->s;
+ goto doneit;
+ }
+ }
+ vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
+ vsp->mantissa2 = is.mantissa;
+ vsp->mantissa1 = (is.mantissa >> 16);
+ doneit:
+ vsp->sign = is.sign;
+ return (TRUE);
+#endif
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+#ifdef vax
+/* What IEEE double precision floating point looks like on a Vax */
+struct ieee_double {
+ unsigned int mantissa1 : 20;
+ unsigned int exp : 11;
+ unsigned int sign : 1;
+ unsigned int mantissa2 : 32;
+};
+
+/* Vax double precision floating point */
+struct vax_double {
+ unsigned int mantissa1 : 7;
+ unsigned int exp : 8;
+ unsigned int sign : 1;
+ unsigned int mantissa2 : 16;
+ unsigned int mantissa3 : 16;
+ unsigned int mantissa4 : 16;
+};
+
+#define VAX_DBL_BIAS 0x81
+#define IEEE_DBL_BIAS 0x3ff
+#define MASK(nbits) ((1 << nbits) - 1)
+
+static struct dbl_limits {
+ struct vax_double d;
+ struct ieee_double ieee;
+} dbl_limits[2] = {
+ {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
+ { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */
+ {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
+ { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
+};
+
+#endif /* vax */
+
+
+bool_t
+xdr_double(xdrs, dp)
+ register XDR *xdrs;
+ double *dp;
+{
+#ifdef IEEEFP
+ register int32_t *i32p;
+ bool_t rv;
+ long tmpl;
+#else
+ register long *lp;
+ struct ieee_double id;
+ struct vax_double vd;
+ register struct dbl_limits *lim;
+ int i;
+#endif
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+#ifdef IEEEFP
+ i32p = (int32_t *)dp;
+#if BYTE_ORDER == BIG_ENDIAN
+ tmpl = *i32p++;
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+ if (!rv)
+ return (rv);
+ tmpl = *i32p;
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+#else
+ tmpl = *(i32p+1);
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+ if (!rv)
+ return (rv);
+ tmpl = *i32p;
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+#endif
+ return (rv);
+#else
+ vd = *((struct vax_double *)dp);
+ for (i = 0, lim = dbl_limits;
+ i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
+ i++, lim++) {
+ if ((vd.mantissa4 == lim->d.mantissa4) &&
+ (vd.mantissa3 == lim->d.mantissa3) &&
+ (vd.mantissa2 == lim->d.mantissa2) &&
+ (vd.mantissa1 == lim->d.mantissa1) &&
+ (vd.exp == lim->d.exp)) {
+ id = lim->ieee;
+ goto shipit;
+ }
+ }
+ id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
+ id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
+ id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
+ (vd.mantissa3 << 13) |
+ ((vd.mantissa4 >> 3) & MASK(13));
+ shipit:
+ id.sign = vd.sign;
+ lp = (long *)&id;
+ return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
+#endif
+
+ case XDR_DECODE:
+#ifdef IEEEFP
+ i32p = (int32_t *)dp;
+#if BYTE_ORDER == BIG_ENDIAN
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *i32p++ = tmpl;
+ if (!rv)
+ return (rv);
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *i32p = tmpl;
+#else
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *(i32p+1) = tmpl;
+ if (!rv)
+ return (rv);
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *i32p = tmpl;
+#endif
+ return (rv);
+#else
+ lp = (long *)&id;
+ if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
+ return (FALSE);
+ for (i = 0, lim = dbl_limits;
+ i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
+ i++, lim++) {
+ if ((id.mantissa2 == lim->ieee.mantissa2) &&
+ (id.mantissa1 == lim->ieee.mantissa1) &&
+ (id.exp == lim->ieee.exp)) {
+ vd = lim->d;
+ goto doneit;
+ }
+ }
+ vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
+ vd.mantissa1 = (id.mantissa1 >> 13);
+ vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
+ (id.mantissa2 >> 29);
+ vd.mantissa3 = (id.mantissa2 >> 13);
+ vd.mantissa4 = (id.mantissa2 << 3);
+ doneit:
+ vd.sign = id.sign;
+ *dp = *((double *)&vd);
+ return (TRUE);
+#endif
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
diff --git a/cpukit/librpc/src/xdr/xdr_mem.c b/cpukit/librpc/src/xdr/xdr_mem.c
new file mode 100644
index 0000000000..0b17afa115
--- /dev/null
+++ b/cpukit/librpc/src/xdr/xdr_mem.c
@@ -0,0 +1,242 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_mem.c,v 1.8 1999/08/28 00:02:56 peter Exp $";
+#endif
+
+/*
+ * xdr_mem.h, XDR implementation using memory buffers.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * If you have some data to be interpreted as external data representation
+ * or to be converted to external data representation in a memory buffer,
+ * then this is the package for you.
+ *
+ */
+
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+static bool_t xdrmem_getlong_aligned();
+static bool_t xdrmem_putlong_aligned();
+static bool_t xdrmem_getlong_unaligned();
+static bool_t xdrmem_putlong_unaligned();
+static bool_t xdrmem_getbytes();
+static bool_t xdrmem_putbytes();
+static u_int xdrmem_getpos(); /* XXX w/64-bit pointers, u_int not enough! */
+static bool_t xdrmem_setpos();
+static int32_t *xdrmem_inline_aligned();
+static int32_t *xdrmem_inline_unaligned();
+static void xdrmem_destroy();
+
+static struct xdr_ops xdrmem_ops_aligned = {
+ xdrmem_getlong_aligned,
+ xdrmem_putlong_aligned,
+ xdrmem_getbytes,
+ xdrmem_putbytes,
+ xdrmem_getpos,
+ xdrmem_setpos,
+ xdrmem_inline_aligned,
+ xdrmem_destroy
+};
+
+static struct xdr_ops xdrmem_ops_unaligned = {
+ xdrmem_getlong_unaligned,
+ xdrmem_putlong_unaligned,
+ xdrmem_getbytes,
+ xdrmem_putbytes,
+ xdrmem_getpos,
+ xdrmem_setpos,
+ xdrmem_inline_unaligned,
+ xdrmem_destroy
+};
+
+/*
+ * The procedure xdrmem_create initializes a stream descriptor for a
+ * memory buffer.
+ */
+void
+xdrmem_create(xdrs, addr, size, op)
+ register XDR *xdrs;
+ caddr_t addr;
+ u_int size;
+ enum xdr_op op;
+{
+
+ xdrs->x_op = op;
+ xdrs->x_ops = ((size_t)addr & (sizeof(int32_t) - 1))
+ ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
+ xdrs->x_private = xdrs->x_base = addr;
+ xdrs->x_handy = size;
+}
+
+static void
+xdrmem_destroy(/*xdrs*/)
+ /*XDR *xdrs;*/
+{
+
+}
+
+static bool_t
+xdrmem_getlong_aligned(xdrs, lp)
+ register XDR *xdrs;
+ long *lp;
+{
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ *lp = ntohl(*(int32_t *)(xdrs->x_private));
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong_aligned(xdrs, lp)
+ register XDR *xdrs;
+ long *lp;
+{
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ *(int32_t *)xdrs->x_private = htonl(*lp);
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_getlong_unaligned(xdrs, lp)
+ register XDR *xdrs;
+ long *lp;
+{
+ int32_t l;
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ memcpy(&l, xdrs->x_private, sizeof(int32_t));
+ *lp = ntohl(l);
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong_unaligned(xdrs, lp)
+ register XDR *xdrs;
+ long *lp;
+{
+ int32_t l;
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ l = htonl(*lp);
+ memcpy(xdrs->x_private, &l, sizeof(int32_t));
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_getbytes(xdrs, addr, len)
+ register XDR *xdrs;
+ caddr_t addr;
+ register u_int len;
+{
+
+ if ((xdrs->x_handy -= len) < 0)
+ return (FALSE);
+ memcpy(addr, xdrs->x_private, len);
+ xdrs->x_private += len;
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_putbytes(xdrs, addr, len)
+ register XDR *xdrs;
+ caddr_t addr;
+ register u_int len;
+{
+
+ if ((xdrs->x_handy -= len) < 0)
+ return (FALSE);
+ memcpy(xdrs->x_private, addr, len);
+ xdrs->x_private += len;
+ return (TRUE);
+}
+
+static u_int
+xdrmem_getpos(xdrs)
+ register XDR *xdrs;
+{
+
+ /* XXX w/64-bit pointers, u_int not enough! */
+ return ((u_long)xdrs->x_private - (u_long)xdrs->x_base);
+}
+
+static bool_t
+xdrmem_setpos(xdrs, pos)
+ register XDR *xdrs;
+ u_int pos;
+{
+ register caddr_t newaddr = xdrs->x_base + pos;
+ register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
+
+ if ((long)newaddr > (long)lastaddr)
+ return (FALSE);
+ xdrs->x_private = newaddr;
+ xdrs->x_handy = (long)lastaddr - (long)newaddr;
+ return (TRUE);
+}
+
+static int32_t *
+xdrmem_inline_aligned(xdrs, len)
+ register XDR *xdrs;
+ int len;
+{
+ int32_t *buf = 0;
+
+ if (xdrs->x_handy >= len) {
+ xdrs->x_handy -= len;
+ buf = (int32_t *) xdrs->x_private;
+ xdrs->x_private += len;
+ }
+ return (buf);
+}
+
+static int32_t *
+xdrmem_inline_unaligned(xdrs, len)
+ register XDR *xdrs;
+ int len;
+{
+
+ return (0);
+}
diff --git a/cpukit/librpc/src/xdr/xdr_rec.c b/cpukit/librpc/src/xdr/xdr_rec.c
new file mode 100644
index 0000000000..d87b413ee6
--- /dev/null
+++ b/cpukit/librpc/src/xdr/xdr_rec.c
@@ -0,0 +1,601 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_rec.c,v 1.12 2000/01/19 06:12:32 wpaul Exp $";
+#endif
+
+/*
+ * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
+ * layer above tcp (for rpc's use).
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These routines interface XDRSTREAMS to a tcp/ip connection.
+ * There is a record marking layer between the xdr stream
+ * and the tcp transport level. A record is composed on one or more
+ * record fragments. A record fragment is a thirty-two bit header followed
+ * by n bytes of data, where n is contained in the header. The header
+ * is represented as a htonl(u_long). Thegh order bit encodes
+ * whether or not the fragment is the last fragment of the record
+ * (1 => fragment is last, 0 => more fragments to follow.
+ * The other 31 bits encode the byte length of the fragment.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+#include <unistd.h> /* for lseek() */
+
+static u_int fix_buf_size();
+static bool_t flush_out();
+static bool_t get_input_bytes();
+static bool_t set_input_fragment();
+static bool_t skip_input_bytes();
+
+static bool_t xdrrec_getlong();
+static bool_t xdrrec_putlong();
+static bool_t xdrrec_getbytes();
+static bool_t xdrrec_putbytes();
+static u_int xdrrec_getpos();
+static bool_t xdrrec_setpos();
+static int32_t *xdrrec_inline();
+static void xdrrec_destroy();
+
+static struct xdr_ops xdrrec_ops = {
+ xdrrec_getlong,
+ xdrrec_putlong,
+ xdrrec_getbytes,
+ xdrrec_putbytes,
+ xdrrec_getpos,
+ xdrrec_setpos,
+ xdrrec_inline,
+ xdrrec_destroy
+};
+
+/*
+ * A record is composed of one or more record fragments.
+ * A record fragment is a two-byte header followed by zero to
+ * 2**32-1 bytes. The header is treated as a long unsigned and is
+ * encode/decoded to the network via htonl/ntohl. The low order 31 bits
+ * are a byte count of the fragment. The highest order bit is a boolean:
+ * 1 => this fragment is the last fragment of the record,
+ * 0 => this fragment is followed by more fragment(s).
+ *
+ * The fragment/record machinery is not general; it is constructed to
+ * meet the needs of xdr and rpc based on tcp.
+ */
+
+#define LAST_FRAG ((u_int32_t)(1 << 31))
+
+typedef struct rec_strm {
+ caddr_t tcp_handle;
+ caddr_t the_buffer;
+ /*
+ * out-goung bits
+ */
+ int (*writeit) __P((caddr_t, caddr_t, int));
+ caddr_t out_base; /* output buffer (points to frag header) */
+ caddr_t out_finger; /* next output position */
+ caddr_t out_boundry; /* data cannot up to this address */
+ u_int32_t *frag_header; /* beginning of current fragment */
+ bool_t frag_sent; /* true if buffer sent in middle of record */
+ /*
+ * in-coming bits
+ */
+ int (*readit) __P((caddr_t, caddr_t, int));
+ u_long in_size; /* fixed size of the input buffer */
+ caddr_t in_base;
+ caddr_t in_finger; /* location of next byte to be had */
+ caddr_t in_boundry; /* can read up to this location */
+ long fbtbc; /* fragment bytes to be consumed */
+ bool_t last_frag;
+ u_int sendsize;
+ u_int recvsize;
+} RECSTREAM;
+
+
+/*
+ * Create an xdr handle for xdrrec
+ * xdrrec_create fills in xdrs. Sendsize and recvsize are
+ * send and recv buffer sizes (0 => use default).
+ * tcp_handle is an opaque handle that is passed as the first parameter to
+ * the procedures readit and writeit. Readit and writeit are read and
+ * write respectively. They are like the system
+ * calls expect that they take an opaque handle rather than an fd.
+ */
+void
+xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
+ register XDR *xdrs;
+ register u_int sendsize;
+ register u_int recvsize;
+ caddr_t tcp_handle;
+ int (*readit)(); /* like read, but pass it a tcp_handle, not sock */
+ int (*writeit)(); /* like write, but pass it a tcp_handle, not sock */
+{
+ register RECSTREAM *rstrm =
+ (RECSTREAM *)mem_alloc(sizeof(RECSTREAM));
+
+ if (rstrm == NULL) {
+ (void)fprintf(stderr, "xdrrec_create: out of memory\n");
+ /*
+ * This is bad. Should rework xdrrec_create to
+ * return a handle, and in this case return NULL
+ */
+ return;
+ }
+ /*
+ * adjust sizes and allocate buffer quad byte aligned
+ */
+ rstrm->sendsize = sendsize = fix_buf_size(sendsize);
+ rstrm->recvsize = recvsize = fix_buf_size(recvsize);
+ rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT);
+ if (rstrm->the_buffer == NULL) {
+ (void)fprintf(stderr, "xdrrec_create: out of memory\n");
+ return;
+ }
+ for (rstrm->out_base = rstrm->the_buffer;
+ (u_long)rstrm->out_base % BYTES_PER_XDR_UNIT != 0;
+ rstrm->out_base++);
+ rstrm->in_base = rstrm->out_base + sendsize;
+ /*
+ * now the rest ...
+ */
+ xdrs->x_ops = &xdrrec_ops;
+ xdrs->x_private = (caddr_t)rstrm;
+ rstrm->tcp_handle = tcp_handle;
+ rstrm->readit = readit;
+ rstrm->writeit = writeit;
+ rstrm->out_finger = rstrm->out_boundry = rstrm->out_base;
+ rstrm->frag_header = (u_int32_t *)rstrm->out_base;
+ rstrm->out_finger += sizeof(u_int32_t);
+ rstrm->out_boundry += sendsize;
+ rstrm->frag_sent = FALSE;
+ rstrm->in_size = recvsize;
+ rstrm->in_boundry = rstrm->in_base;
+ rstrm->in_finger = (rstrm->in_boundry += recvsize);
+ rstrm->fbtbc = 0;
+ rstrm->last_frag = TRUE;
+}
+
+
+/*
+ * The reoutines defined below are the xdr ops which will go into the
+ * xdr handle filled in by xdrrec_create.
+ */
+
+static bool_t
+xdrrec_getlong(xdrs, lp)
+ XDR *xdrs;
+ long *lp;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ register int32_t *buflp = (int32_t *)(rstrm->in_finger);
+ int32_t mylong;
+
+ /* first try the inline, fast case */
+ if ((rstrm->fbtbc >= sizeof(int32_t)) &&
+ (((long)rstrm->in_boundry - (long)buflp) >= sizeof(int32_t))) {
+ *lp = (long)ntohl((u_int32_t)(*buflp));
+ rstrm->fbtbc -= sizeof(int32_t);
+ rstrm->in_finger += sizeof(int32_t);
+ } else {
+ if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(int32_t)))
+ return (FALSE);
+ *lp = (long)ntohl((u_int32_t)mylong);
+ }
+ return (TRUE);
+}
+
+static bool_t
+xdrrec_putlong(xdrs, lp)
+ XDR *xdrs;
+ long *lp;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ register int32_t *dest_lp = ((int32_t *)(rstrm->out_finger));
+
+ if ((rstrm->out_finger += sizeof(int32_t)) > rstrm->out_boundry) {
+ /*
+ * this case should almost never happen so the code is
+ * inefficient
+ */
+ rstrm->out_finger -= sizeof(int32_t);
+ rstrm->frag_sent = TRUE;
+ if (! flush_out(rstrm, FALSE))
+ return (FALSE);
+ dest_lp = ((int32_t *)(rstrm->out_finger));
+ rstrm->out_finger += sizeof(int32_t);
+ }
+ *dest_lp = (int32_t)htonl((u_int32_t)(*lp));
+ return (TRUE);
+}
+
+static bool_t /* must manage buffers, fragments, and records */
+xdrrec_getbytes(xdrs, addr, len)
+ XDR *xdrs;
+ register caddr_t addr;
+ register u_int len;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ register int current;
+
+ while (len > 0) {
+ current = rstrm->fbtbc;
+ if (current == 0) {
+ if (rstrm->last_frag)
+ return (FALSE);
+ if (! set_input_fragment(rstrm))
+ return (FALSE);
+ continue;
+ }
+ current = (len < current) ? len : current;
+ if (! get_input_bytes(rstrm, addr, current))
+ return (FALSE);
+ addr += current;
+ rstrm->fbtbc -= current;
+ len -= current;
+ }
+ return (TRUE);
+}
+
+static bool_t
+xdrrec_putbytes(xdrs, addr, len)
+ XDR *xdrs;
+ register caddr_t addr;
+ register u_int len;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ register long current;
+
+ while (len > 0) {
+ current = (u_long)rstrm->out_boundry -
+ (u_long)rstrm->out_finger;
+ current = (len < current) ? len : current;
+ memcpy(rstrm->out_finger, addr, current);
+ rstrm->out_finger += current;
+ addr += current;
+ len -= current;
+ if (rstrm->out_finger == rstrm->out_boundry) {
+ rstrm->frag_sent = TRUE;
+ if (! flush_out(rstrm, FALSE))
+ return (FALSE);
+ }
+ }
+ return (TRUE);
+}
+
+static u_int
+xdrrec_getpos(xdrs)
+ register XDR *xdrs;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+ register long pos;
+
+ pos = lseek((int)(long)rstrm->tcp_handle, (off_t) 0, 1);
+ if (pos != -1)
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ pos += rstrm->out_finger - rstrm->out_base;
+ break;
+
+ case XDR_DECODE:
+ pos -= rstrm->in_boundry - rstrm->in_finger;
+ break;
+
+ default:
+ pos = -1;
+ break;
+ }
+ return ((u_int) pos);
+}
+
+static bool_t
+xdrrec_setpos(xdrs, pos)
+ register XDR *xdrs;
+ u_int pos;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+ u_int currpos = xdrrec_getpos(xdrs);
+ int delta = currpos - pos;
+ caddr_t newpos;
+
+ if ((int)currpos != -1)
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ newpos = rstrm->out_finger - delta;
+ if ((newpos > (caddr_t)(rstrm->frag_header)) &&
+ (newpos < rstrm->out_boundry)) {
+ rstrm->out_finger = newpos;
+ return (TRUE);
+ }
+ break;
+
+ case XDR_DECODE:
+ newpos = rstrm->in_finger - delta;
+ if ((delta < (int)(rstrm->fbtbc)) &&
+ (newpos <= rstrm->in_boundry) &&
+ (newpos >= rstrm->in_base)) {
+ rstrm->in_finger = newpos;
+ rstrm->fbtbc -= delta;
+ return (TRUE);
+ }
+ break;
+ case XDR_FREE: /* to avoid warning */
+ break;
+ }
+ return (FALSE);
+}
+
+static int32_t *
+xdrrec_inline(xdrs, len)
+ register XDR *xdrs;
+ int len;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+ int32_t * buf = NULL;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
+ buf = (int32_t *) rstrm->out_finger;
+ rstrm->out_finger += len;
+ }
+ break;
+
+ case XDR_DECODE:
+ if ((len <= rstrm->fbtbc) &&
+ ((rstrm->in_finger + len) <= rstrm->in_boundry)) {
+ buf = (int32_t *) rstrm->in_finger;
+ rstrm->fbtbc -= len;
+ rstrm->in_finger += len;
+ }
+ break;
+ case XDR_FREE: /* to avoid warning */
+ break;
+ }
+ return (buf);
+}
+
+static void
+xdrrec_destroy(xdrs)
+ register XDR *xdrs;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+
+ mem_free(rstrm->the_buffer,
+ rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT);
+ mem_free((caddr_t)rstrm, sizeof(RECSTREAM));
+}
+
+
+/*
+ * Exported routines to manage xdr records
+ */
+
+/*
+ * Before reading (deserializing from the stream, one should always call
+ * this procedure to guarantee proper record alignment.
+ */
+bool_t
+xdrrec_skiprecord(xdrs)
+ XDR *xdrs;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+ while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+ if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+ return (FALSE);
+ rstrm->fbtbc = 0;
+ if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+ return (FALSE);
+ }
+ rstrm->last_frag = FALSE;
+ return (TRUE);
+}
+
+/*
+ * Look ahead fuction.
+ * Returns TRUE iff there is no more input in the buffer
+ * after consuming the rest of the current record.
+ */
+bool_t
+xdrrec_eof(xdrs)
+ XDR *xdrs;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+ while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+ if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+ return (TRUE);
+ rstrm->fbtbc = 0;
+ if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+ return (TRUE);
+ }
+ if (rstrm->in_finger == rstrm->in_boundry)
+ return (TRUE);
+ return (FALSE);
+}
+
+/*
+ * The client must tell the package when an end-of-record has occurred.
+ * The second paraemters tells whether the record should be flushed to the
+ * (output) tcp stream. (This let's the package support batched or
+ * pipelined procedure calls.) TRUE => immmediate flush to tcp connection.
+ */
+bool_t
+xdrrec_endofrecord(xdrs, sendnow)
+ XDR *xdrs;
+ bool_t sendnow;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ register u_long len; /* fragment length */
+
+ if (sendnow || rstrm->frag_sent ||
+ ((u_long)rstrm->out_finger + sizeof(u_int32_t) >=
+ (u_long)rstrm->out_boundry)) {
+ rstrm->frag_sent = FALSE;
+ return (flush_out(rstrm, TRUE));
+ }
+ len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) -
+ sizeof(u_int32_t);
+ *(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG);
+ rstrm->frag_header = (u_int32_t *)rstrm->out_finger;
+ rstrm->out_finger += sizeof(u_int32_t);
+ return (TRUE);
+}
+
+
+/*
+ * Internal useful routines
+ */
+static bool_t
+flush_out(rstrm, eor)
+ register RECSTREAM *rstrm;
+ bool_t eor;
+{
+ register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0;
+ register u_int32_t len = (u_long)(rstrm->out_finger) -
+ (u_long)(rstrm->frag_header) - sizeof(u_int32_t);
+
+ *(rstrm->frag_header) = htonl(len | eormask);
+ len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base);
+ if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
+ != (int)len)
+ return (FALSE);
+ rstrm->frag_header = (u_int32_t *)rstrm->out_base;
+ rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_int32_t);
+ return (TRUE);
+}
+
+static bool_t /* knows nothing about records! Only about input buffers */
+fill_input_buf(rstrm)
+ register RECSTREAM *rstrm;
+{
+ register caddr_t where;
+ u_long i;
+ register long len;
+
+ where = rstrm->in_base;
+ i = (u_long)rstrm->in_boundry % BYTES_PER_XDR_UNIT;
+ where += i;
+ len = rstrm->in_size - i;
+ if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
+ return (FALSE);
+ rstrm->in_finger = where;
+ where += len;
+ rstrm->in_boundry = where;
+ return (TRUE);
+}
+
+static bool_t /* knows nothing about records! Only about input buffers */
+get_input_bytes(rstrm, addr, len)
+ register RECSTREAM *rstrm;
+ register caddr_t addr;
+ register int len;
+{
+ register long current;
+
+ while (len > 0) {
+ current = (long)rstrm->in_boundry - (long)rstrm->in_finger;
+ if (current == 0) {
+ if (! fill_input_buf(rstrm))
+ return (FALSE);
+ continue;
+ }
+ current = (len < current) ? len : current;
+ memcpy(addr, rstrm->in_finger, current);
+ rstrm->in_finger += current;
+ addr += current;
+ len -= current;
+ }
+ return (TRUE);
+}
+
+static bool_t /* next two bytes of the input stream are treated as a header */
+set_input_fragment(rstrm)
+ register RECSTREAM *rstrm;
+{
+ u_int32_t header;
+
+ if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header)))
+ return (FALSE);
+ header = (long)ntohl(header);
+ rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
+ /*
+ * Sanity check. Try not to accept wildly incorrect
+ * record sizes. Unfortunately, the only record size
+ * we can positively identify as being 'wildly incorrect'
+ * is zero. Ridiculously large record sizes may look wrong,
+ * but we don't have any way to be certain that they aren't
+ * what the client actually intended to send us.
+ */
+ if (header == 0)
+ return(FALSE);
+ rstrm->fbtbc = header & (~LAST_FRAG);
+ return (TRUE);
+}
+
+static bool_t /* consumes input bytes; knows nothing about records! */
+skip_input_bytes(rstrm, cnt)
+ register RECSTREAM *rstrm;
+ long cnt;
+{
+ register long current;
+
+ while (cnt > 0) {
+ current = (long)rstrm->in_boundry - (long)rstrm->in_finger;
+ if (current == 0) {
+ if (! fill_input_buf(rstrm))
+ return (FALSE);
+ continue;
+ }
+ current = (cnt < current) ? cnt : current;
+ rstrm->in_finger += current;
+ cnt -= current;
+ }
+ return (TRUE);
+}
+
+static u_int
+fix_buf_size(s)
+ register u_int s;
+{
+
+ if (s < 100)
+ s = 4000;
+ return (RNDUP(s));
+}
diff --git a/cpukit/librpc/src/xdr/xdr_reference.c b/cpukit/librpc/src/xdr/xdr_reference.c
new file mode 100644
index 0000000000..41ac34b220
--- /dev/null
+++ b/cpukit/librpc/src/xdr/xdr_reference.c
@@ -0,0 +1,138 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_reference.c 1.11 87/08/11 SMI";*/
+/*static char *sccsid = "from: @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_reference.c,v 1.8 1999/08/28 00:02:56 peter Exp $";
+#endif
+
+/*
+ * xdr_reference.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * "pointers". See xdr.h for more info on the interface to xdr.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED ((u_int) 0-1)
+
+/*
+ * XDR an indirect pointer
+ * xdr_reference is for recursively translating a structure that is
+ * referenced by a pointer inside the structure that is currently being
+ * translated. pp references a pointer to storage. If *pp is null
+ * the necessary storage is allocated.
+ * size is the sizeof the referneced structure.
+ * proc is the routine to handle the referenced structure.
+ */
+bool_t
+xdr_reference(xdrs, pp, size, proc)
+ register XDR *xdrs;
+ caddr_t *pp; /* the pointer to work on */
+ u_int size; /* size of the object pointed to */
+ xdrproc_t proc; /* xdr routine to handle the object */
+{
+ register caddr_t loc = *pp;
+ register bool_t stat;
+
+ if (loc == NULL)
+ switch (xdrs->x_op) {
+ case XDR_FREE:
+ return (TRUE);
+
+ case XDR_DECODE:
+ *pp = loc = (caddr_t) mem_alloc(size);
+ if (loc == NULL) {
+ (void) fprintf(stderr,
+ "xdr_reference: out of memory\n");
+ return (FALSE);
+ }
+ memset(loc, 0, (int)size);
+ break;
+ case XDR_ENCODE: /* to avoid warning */
+ break;
+ }
+
+ stat = (*proc)(xdrs, loc, LASTUNSIGNED);
+
+ if (xdrs->x_op == XDR_FREE) {
+ mem_free(loc, size);
+ *pp = NULL;
+ }
+ return (stat);
+}
+
+
+/*
+ * xdr_pointer():
+ *
+ * XDR a pointer to a possibly recursive data structure. This
+ * differs with xdr_reference in that it can serialize/deserialiaze
+ * trees correctly.
+ *
+ * What's sent is actually a union:
+ *
+ * union object_pointer switch (boolean b) {
+ * case TRUE: object_data data;
+ * case FALSE: void nothing;
+ * }
+ *
+ * > objpp: Pointer to the pointer to the object.
+ * > obj_size: size of the object.
+ * > xdr_obj: routine to XDR an object.
+ *
+ */
+bool_t
+xdr_pointer(xdrs,objpp,obj_size,xdr_obj)
+ register XDR *xdrs;
+ char **objpp;
+ u_int obj_size;
+ xdrproc_t xdr_obj;
+{
+
+ bool_t more_data;
+
+ more_data = (*objpp != NULL);
+ if (! xdr_bool(xdrs,&more_data)) {
+ return (FALSE);
+ }
+ if (! more_data) {
+ *objpp = NULL;
+ return (TRUE);
+ }
+ return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
+}
diff --git a/cpukit/librpc/src/xdr/xdr_sizeof.c b/cpukit/librpc/src/xdr/xdr_sizeof.c
new file mode 100644
index 0000000000..5a4c1a78dc
--- /dev/null
+++ b/cpukit/librpc/src/xdr/xdr_sizeof.c
@@ -0,0 +1,163 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * xdr_sizeof.c
+ *
+ * Copyright 1990 Sun Microsystems, Inc.
+ *
+ * General purpose routine to see how much space something will use
+ * when serialized using XDR.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+/* ARGSUSED */
+static bool_t
+x_putlong(xdrs, longp)
+ XDR *xdrs;
+ long *longp;
+{
+ xdrs->x_handy += BYTES_PER_XDR_UNIT;
+ return (TRUE);
+}
+
+/* ARGSUSED */
+static bool_t
+x_putbytes(xdrs, bp, len)
+ XDR *xdrs;
+ char *bp;
+ int len;
+{
+ xdrs->x_handy += len;
+ return (TRUE);
+}
+
+static u_int
+x_getpostn(xdrs)
+ XDR *xdrs;
+{
+ return (xdrs->x_handy);
+}
+
+/* ARGSUSED */
+static bool_t
+x_setpostn(xdrs, pos)
+ XDR *xdrs;
+ u_int pos;
+{
+ /* This is not allowed */
+ return (FALSE);
+}
+
+static int32_t *
+x_inline(xdrs, len)
+ XDR *xdrs;
+ long len;
+{
+ if (len == 0) {
+ return (NULL);
+ }
+ if (xdrs->x_op != XDR_ENCODE) {
+ return (NULL);
+ }
+ if (len < (long) xdrs->x_base) {
+ /* x_private was already allocated */
+ xdrs->x_handy += len;
+ return ((int32_t *) xdrs->x_private);
+ } else {
+ /* Free the earlier space and allocate new area */
+ if (xdrs->x_private)
+ free(xdrs->x_private);
+ if ((xdrs->x_private = (caddr_t) malloc(len)) == NULL) {
+ xdrs->x_base = 0;
+ return (NULL);
+ }
+ xdrs->x_base = (caddr_t) len;
+ xdrs->x_handy += len;
+ return ((int32_t *) xdrs->x_private);
+ }
+}
+
+static int
+harmless()
+{
+ /* Always return FALSE/NULL, as the case may be */
+ return (0);
+}
+
+static void
+x_destroy(xdrs)
+ XDR *xdrs;
+{
+ xdrs->x_handy = 0;
+ xdrs->x_base = 0;
+ if (xdrs->x_private) {
+ free(xdrs->x_private);
+ xdrs->x_private = NULL;
+ }
+ return;
+}
+
+unsigned long
+xdr_sizeof(func, data)
+ xdrproc_t func;
+ void *data;
+{
+ XDR x;
+ struct xdr_ops ops;
+ bool_t stat;
+ /* to stop ANSI-C compiler from complaining */
+ typedef bool_t (* dummyfunc1)(XDR *, long *);
+ typedef bool_t (* dummyfunc2)(XDR *, caddr_t, u_int);
+
+ ops.x_putlong = x_putlong;
+ ops.x_putbytes = x_putbytes;
+ ops.x_inline = x_inline;
+ ops.x_getpostn = x_getpostn;
+ ops.x_setpostn = x_setpostn;
+ ops.x_destroy = x_destroy;
+
+ /* the other harmless ones */
+ ops.x_getlong = (dummyfunc1) harmless;
+ ops.x_getbytes = (dummyfunc2) harmless;
+
+ x.x_op = XDR_ENCODE;
+ x.x_ops = &ops;
+ x.x_handy = 0;
+ x.x_private = (caddr_t) NULL;
+ x.x_base = (caddr_t) 0;
+
+ stat = func(&x, data);
+ if (x.x_private)
+ free(x.x_private);
+ return (stat == TRUE ? (unsigned) x.x_handy: 0);
+}
diff --git a/cpukit/librpc/src/xdr/xdr_stdio.c b/cpukit/librpc/src/xdr/xdr_stdio.c
new file mode 100644
index 0000000000..f19395f9ba
--- /dev/null
+++ b/cpukit/librpc/src/xdr/xdr_stdio.c
@@ -0,0 +1,190 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_stdio.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_stdio.c,v 1.7 1999/08/28 00:02:56 peter Exp $";
+#endif
+
+/*
+ * xdr_stdio.c, XDR implementation on standard i/o file.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements a XDR on a stdio stream.
+ * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
+ * from the stream.
+ */
+
+#include <rpc/types.h>
+#include <stdio.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+static bool_t xdrstdio_getlong();
+static bool_t xdrstdio_putlong();
+static bool_t xdrstdio_getbytes();
+static bool_t xdrstdio_putbytes();
+static u_int xdrstdio_getpos();
+static bool_t xdrstdio_setpos();
+static int32_t *xdrstdio_inline();
+static void xdrstdio_destroy();
+
+/*
+ * Ops vector for stdio type XDR
+ */
+static struct xdr_ops xdrstdio_ops = {
+ xdrstdio_getlong, /* deseraialize a long int */
+ xdrstdio_putlong, /* seraialize a long int */
+ xdrstdio_getbytes, /* deserialize counted bytes */
+ xdrstdio_putbytes, /* serialize counted bytes */
+ xdrstdio_getpos, /* get offset in the stream */
+ xdrstdio_setpos, /* set offset in the stream */
+ xdrstdio_inline, /* prime stream for inline macros */
+ xdrstdio_destroy /* destroy stream */
+};
+
+/*
+ * Initialize a stdio xdr stream.
+ * Sets the xdr stream handle xdrs for use on the stream file.
+ * Operation flag is set to op.
+ */
+void
+xdrstdio_create(xdrs, file, op)
+ register XDR *xdrs;
+ FILE *file;
+ enum xdr_op op;
+{
+
+ xdrs->x_op = op;
+ xdrs->x_ops = &xdrstdio_ops;
+ xdrs->x_private = (caddr_t)file;
+ xdrs->x_handy = 0;
+ xdrs->x_base = 0;
+}
+
+/*
+ * Destroy a stdio xdr stream.
+ * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
+ */
+static void
+xdrstdio_destroy(xdrs)
+ register XDR *xdrs;
+{
+ (void)fflush((FILE *)xdrs->x_private);
+ /* xx should we close the file ?? */
+}
+
+static bool_t
+xdrstdio_getlong(xdrs, lp)
+ XDR *xdrs;
+ register long *lp;
+{
+
+ if (fread((caddr_t)lp, sizeof(int32_t), 1,
+ (FILE *)xdrs->x_private) != 1)
+ return (FALSE);
+ *lp = (long)ntohl((int32_t)*lp);
+ return (TRUE);
+}
+
+static bool_t
+xdrstdio_putlong(xdrs, lp)
+ XDR *xdrs;
+ long *lp;
+{
+
+ long mycopy = (long)htonl((int32_t)*lp);
+
+ if (fwrite((caddr_t)&mycopy, sizeof(int32_t), 1,
+ (FILE *)xdrs->x_private) != 1)
+ return (FALSE);
+ return (TRUE);
+}
+
+static bool_t
+xdrstdio_getbytes(xdrs, addr, len)
+ XDR *xdrs;
+ caddr_t addr;
+ u_int len;
+{
+
+ if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+ return (FALSE);
+ return (TRUE);
+}
+
+static bool_t
+xdrstdio_putbytes(xdrs, addr, len)
+ XDR *xdrs;
+ caddr_t addr;
+ u_int len;
+{
+
+ if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+ return (FALSE);
+ return (TRUE);
+}
+
+static u_int
+xdrstdio_getpos(xdrs)
+ XDR *xdrs;
+{
+
+ return ((u_int) ftell((FILE *)xdrs->x_private));
+}
+
+static bool_t
+xdrstdio_setpos(xdrs, pos)
+ XDR *xdrs;
+ u_int pos;
+{
+
+ return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
+ FALSE : TRUE);
+}
+
+static int32_t *
+xdrstdio_inline(xdrs, len)
+ XDR *xdrs;
+ u_int len;
+{
+
+ /*
+ * Must do some work to implement this: must insure
+ * enough data in the underlying stdio buffer,
+ * that the buffer is aligned so that we can indirect through a
+ * long *, and stuff this pointer in xdrs->x_buf. Doing
+ * a fread or fwrite to a scratch buffer would defeat
+ * most of the gains to be had here and require storage
+ * management on this buffer, so we don't do this.
+ */
+ return (NULL);
+}
diff --git a/cpukit/posix/.cvsignore b/cpukit/posix/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/posix/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/posix/Makefile.am b/cpukit/posix/Makefile.am
new file mode 100644
index 0000000000..46ba563029
--- /dev/null
+++ b/cpukit/posix/Makefile.am
@@ -0,0 +1,157 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+EXTRA_DIST =
+
+if HAS_POSIX
+
+# include
+
+include_HEADERS = include/sched.h include/aio.h include/mqueue.h \
+ include/semaphore.h include/devctl.h
+
+# include/rtems/posix
+
+include_rtems_posixdir = $(includedir)/rtems/posix
+
+include_rtems_posix_HEADERS = include/rtems/posix/cancel.h \
+ include/rtems/posix/cond.h include/rtems/posix/config.h \
+ include/rtems/posix/key.h include/rtems/posix/mqueue.h \
+ include/rtems/posix/mutex.h include/rtems/posix/posixapi.h \
+ include/rtems/posix/priority.h include/rtems/posix/psignal.h \
+ include/rtems/posix/pthread.h include/rtems/posix/semaphore.h \
+ include/rtems/posix/threadsup.h include/rtems/posix/time.h \
+ include/rtems/posix/timer.h
+
+if HAS_MP
+include_rtems_posix_HEADERS += include/rtems/posix/condmp.h \
+ include/rtems/posix/mqueuemp.h include/rtems/posix/mutexmp.h \
+ include/rtems/posix/pthreadmp.h include/rtems/posix/semaphoremp.h
+endif
+
+if INLINE
+include_rtems_posix_HEADERS += inline/rtems/posix/cond.inl \
+ inline/rtems/posix/key.inl inline/rtems/posix/mqueue.inl \
+ inline/rtems/posix/mutex.inl inline/rtems/posix/pthread.inl \
+ inline/rtems/posix/priority.inl inline/rtems/posix/semaphore.inl \
+ inline/rtems/posix/timer.inl
+else
+include_rtems_posix_HEADERS += macros/rtems/posix/cond.inl \
+ macros/rtems/posix/key.inl macros/rtems/posix/mqueue.inl \
+ macros/rtems/posix/mutex.inl macros/rtems/posix/pthread.inl \
+ macros/rtems/posix/priority.inl macros/rtems/posix/semaphore.inl \
+ macros/rtems/posix/timer.inl
+endif
+
+## src
+
+# These are really in the stand but not really functional
+## BUILD_FOR_NOW_C_FILES
+libposix_a_SOURCES = src/aio.c src/devctl.c
+
+## ENOSYS_C_FILES
+libposix_a_SOURCES += src/execl.c src/execle.c src/execlp.c src/execv.c \
+ src/execve.c src/execvp.c src/fork.c src/pthreadatfork.c src/wait.c \
+ src/waitpid.c
+
+## CANCEL_C_FILES
+libposix_a_SOURCES += src/cancel.c src/cancelrun.c src/cleanuppop.c \
+ src/cleanuppush.c src/setcancelstate.c src/setcanceltype.c \
+ src/testcancel.c
+
+## CONDITION_VARIABLE_C_FILES
+libposix_a_SOURCES += src/cond.c src/condattrdestroy.c \
+ src/condattrgetpshared.c src/condattrinit.c src/condattrsetpshared.c \
+ src/condbroadcast.c src/conddefaultattributes.c src/conddestroy.c \
+ src/condinit.c src/condmp.c src/condsignal.c src/condsignalsupp.c \
+ src/condtimedwait.c src/condwait.c src/condwaitsupp.c
+
+## KEY_C_FILES
+libposix_a_SOURCES += src/key.c src/keycreate.c src/keydelete.c \
+ src/keygetspecific.c \
+ src/keyrundestructors.c src/keysetspecific.c
+
+## MEMORY_C_FILES
+libposix_a_SOURCES += src/getpagesize.c src/mprotect.c
+
+## MESSAGE_QUEUE_C_FILES
+libposix_a_SOURCES += src/mqueue.c src/mqueueclose.c \
+ src/mqueuecreatesupp.c src/mqueuedeletesupp.c src/mqueuegetattr.c \
+ src/mqueuenametoid.c src/mqueuenotify.c src/mqueueopen.c \
+ src/mqueuereceive.c src/mqueuerecvsupp.c src/mqueuesend.c \
+ src/mqueuesendsupp.c src/mqueuesetattr.c src/mqueuetimedreceive.c \
+ src/mqueuetimedsend.c src/mqueuetranslatereturncode.c \
+ src/mqueueunlink.c
+
+## MUTEX_C_FILES
+libposix_a_SOURCES += src/mutex.c src/mutexattrdestroy.c \
+ src/mutexattrgetprioceiling.c src/mutexattrgetprotocol.c \
+ src/mutexattrgetpshared.c src/mutexattrinit.c \
+ src/mutexattrsetprioceiling.c src/mutexattrsetprotocol.c \
+ src/mutexattrsetpshared.c src/mutexdefaultattributes.c \
+ src/mutexdestroy.c src/mutexfromcorestatus.c src/mutexgetprioceiling.c \
+ src/mutexinit.c src/mutexlock.c src/mutexlocksupp.c src/mutexmp.c \
+ src/mutexsetprioceiling.c src/mutextimedlock.c src/mutextrylock.c \
+ src/mutexunlock.c
+
+## PTHREAD_C_FILES
+libposix_a_SOURCES += src/pthread.c src/pthreadsetcputime.c \
+ src/pthreadgetcputime.c src/pthreadgetcpuclockid.c src/pthreadonce.c \
+ src/pthreadequal.c src/pthreadself.c src/pthreadexit.c \
+ src/pthreaddetach.c src/pthreadjoin.c src/pthreadcreate.c \
+ src/pthreadattrsetdetachstate.c src/pthreadattrgetdetachstate.c \
+ src/pthreadattrgetstackaddr.c src/pthreadattrsetstackaddr.c \
+ src/pthreadattrgetstacksize.c src/pthreadattrsetstacksize.c \
+ src/pthreadattrinit.c src/pthreadattrdestroy.c \
+ src/pthreadsetschedparam.c src/pthreadgetschedparam.c \
+ src/pthreadattrsetschedparam.c src/pthreadattrgetschedparam.c \
+ src/pthreadattrgetschedpolicy.c src/pthreadattrsetschedpolicy.c \
+ src/pthreadattrgetinheritsched.c src/pthreadattrsetinheritsched.c \
+ src/pthreadattrgetscope.c src/pthreadattrsetscope.c
+
+## PSIGNAL_C_FILES
+libposix_a_SOURCES += src/psignal.c src/alarm.c src/kill.c src/killinfo.c \
+ src/pause.c src/psignalclearprocesssignals.c \
+ src/psignalsetprocesssignals.c src/psignalchecksignal.c \
+ src/psignalclearsignals.c src/psignalunblockthread.c src/pthreadkill.c \
+ src/pthreadsigmask.c src/sigaction.c src/sigaddset.c src/sigdelset.c \
+ src/sigemptyset.c src/sigfillset.c src/sigismember.c src/sigpending.c \
+ src/sigprocmask.c src/sigqueue.c src/sigsuspend.c src/sigtimedwait.c \
+ src/sigwait.c src/sigwaitinfo.c src/signal_2.c src/ualarm.c
+
+## SEMAPHORE_C_FILES
+libposix_a_SOURCES += src/semaphore.c src/semaphorecreatesupp.c \
+ src/semaphoredeletesupp.c src/semaphoremp.c src/semaphorenametoid.c \
+ src/semaphorewaitsupp.c src/semclose.c src/semdestroy.c \
+ src/semgetvalue.c src/seminit.c src/semopen.c src/sempost.c \
+ src/semtimedwait.c src/semtrywait.c src/semunlink.c src/semwait.c
+
+## TIME_C_FILES
+libposix_a_SOURCES += src/adjtime.c src/time.c src/posixtimespecsubtract.c \
+ src/posixtimespectointerval.c src/posixintervaltotimespec.c \
+ src/clockgetcpuclockid.c src/clockgetenableattr.c src/clockgetres.c \
+ src/clockgettime.c src/clocksetenableattr.c src/clocksettime.c \
+ src/nanosleep.c src/sleep.c src/usleep.c
+
+# the timer manager needs to be split further but only after its
+# dependence on the Classic API Timer Manager is removed.
+## TIMER_C_FILES
+libposix_a_SOURCES += src/ptimer.c src/ptimer1.c
+
+EXTRA_DIST += src/README.mqueue
+
+libposix_a_SOURCES += src/adasupp.c src/sched.c \
+ src/sysconf.c src/types.c
+
+AM_CPPFLAGS += -D__RTEMS_INSIDE__
+
+noinst_LIBRARIES = libposix.a
+libposix_a_CPPFLAGS = $(AM_CPPFLAGS)
+endif
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/posix/include/aio.h b/cpukit/posix/include/aio.h
new file mode 100644
index 0000000000..48c955a555
--- /dev/null
+++ b/cpukit/posix/include/aio.h
@@ -0,0 +1,148 @@
+/**
+ * @file aio.h
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _AIO_H
+#define _AIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <unistd.h>
+
+#if defined(_POSIX_ASYNCHRONOUS_IO)
+
+/*
+ * 6.7.1 Data Definitions for Asynchronous Input and Output,
+ * P1003.1b-1993, p. 151
+ */
+
+#include <sys/types.h>
+#include <signal.h>
+#include <time.h>
+#include <fcntl.h>
+
+/*
+ * 6.7.1.2 Manifest Constants, P1003.1b-1993, p. 153
+ */
+
+#define AIO_CANCELED 0 /* all requested operations have been canceled */
+#define AIO_NOTCANCELED 1 /* some of the operations could not be canceled */
+ /* since they are in progress */
+#define AIO_ALLDONE 2 /* none of the requested operations could be */
+ /* canceled since they are already complete */
+
+/* lio_listio() options */
+
+#define LIO_WAIT 0 /* calling process is to suspend until the */
+ /* operation is complete */
+#define LIO_NOWAIT 1 /* calling process is to continue execution while */
+ /* the operation is performed and no notification */
+ /* shall be given when the operation is completed */
+#define LIO_READ 2 /* request a read() */
+#define LIO_WRITE 3 /* request a write() */
+#define LIO_NOP 4 /* no transfer is requested */
+
+/*
+ * 6.7.1.1 Asynchronous I/O Control Block, P1003.1b-1993, p. 151
+ */
+
+struct aiocb {
+ int aio_fildes; /* File descriptor */
+ off_t aio_offset; /* File offset */
+ volatile void *aio_buf; /* Location of buffer */
+ size_t aio_nbytes; /* Length of transfer */
+ int aio_reqprio; /* Request priority offset */
+ struct sigevent aio_sigevent; /* Signal number and value */
+ int aoi_lio_opcode; /* Operation to be performed */
+};
+
+/*
+ * 6.7.2 Asynchronous Read, P1003.1b-1993, p. 154
+ */
+
+int aio_read(
+ struct aiocb *aiocbp
+);
+
+/*
+ * 6.7.3 Asynchronous Write, P1003.1b-1993, p. 155
+ */
+
+int aio_write(
+ struct aiocb *aiocbp
+);
+
+/*
+ * 6.7.4 List Directed I/O, P1003.1b-1993, p. 158
+ */
+
+int lio_listio(
+ int mode,
+ struct aiocb * const list[],
+ int nent,
+ struct sigevent *sig
+);
+
+/*
+ * 6.7.5 Retrieve Error of Asynchronous I/O Operation, P1003.1b-1993, p. 161
+ */
+
+int aio_error(
+ const struct aiocb *aiocbp
+);
+
+/*
+ * 6.7.6 Retrieve Return Status of Asynchronous I/O Operation,
+ * P1003.1b-1993, p. 162
+ */
+
+int aio_return(
+ const struct aiocb *aiocbp
+);
+
+/*
+ * 6.7.7 Cancel Asynchronous I/O Operation, P1003.1b-1993, p. 163
+ */
+
+int aio_cancel(
+ int filedes,
+ struct aiocb *aiocbp
+);
+
+/*
+ * 6.7.7 Wait for Asynchronous I/O Request, P1003.1b-1993, p. 164
+ */
+
+int aio_suspend(
+ struct aiocb * const list[],
+ int nent,
+ const struct timespec *timeout
+);
+
+#if defined(_POSIX_SYNCHRONIZED_IO)
+
+/*
+ * 6.7.9 Asynchronous File Synchronization, P1003.1b-1993, p. 166
+ */
+
+int aio_fsync(
+ int op,
+ struct aiocb *aiocbp
+);
+
+#endif /* _POSIX_SYNCHRONIZED_IO */
+
+#endif /* _POSIX_ASYNCHRONOUS_IO */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/devctl.h b/cpukit/posix/include/devctl.h
new file mode 100644
index 0000000000..0e735ec068
--- /dev/null
+++ b/cpukit/posix/include/devctl.h
@@ -0,0 +1,41 @@
+/**
+ * @file devctl.h
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _DEVCTL_H
+#define _DEVCTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <unistd.h>
+
+#if defined(_POSIX_DEVICE_CONTROL)
+
+#include <sys/types.h>
+#include <unistd.h>
+
+/*
+ * 21.2.1 Control a Device, P1003.4b/D8, p. 65
+ */
+
+int devctl(
+ int filedes,
+ void *dev_data_ptr,
+ size_t nbyte,
+ int *dev_info_ptr
+);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/mqueue.h b/cpukit/posix/include/mqueue.h
new file mode 100644
index 0000000000..0c2a513345
--- /dev/null
+++ b/cpukit/posix/include/mqueue.h
@@ -0,0 +1,156 @@
+/**
+ * @file mqueue.h
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _MQUEUE_H
+#define _MQUEUE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <unistd.h>
+
+#if defined(_POSIX_MESSAGE_PASSING)
+
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+
+/*
+ * 15.1.1 Data Structures, P1003.1b-1993, p. 271
+ */
+
+typedef Objects_Id mqd_t;
+
+struct mq_attr {
+ long mq_flags; /* Message queue flags */
+ long mq_maxmsg; /* Maximum number of messages */
+ long mq_msgsize; /* Maximum message size */
+ long mq_curmsgs; /* Number of messages currently queued */
+};
+
+/*
+ * 15.2.2 Open a Message Queue, P1003.1b-1993, p. 272
+ */
+
+mqd_t mq_open(
+ const char *name,
+ int oflag,
+ ...
+);
+
+/*
+ * 15.2.2 Close a Message Queue, P1003.1b-1993, p. 275
+ */
+
+int mq_close(
+ mqd_t mqdes
+);
+
+/*
+ * 15.2.2 Remove a Message Queue, P1003.1b-1993, p. 276
+ */
+
+int mq_unlink(
+ const char *name
+);
+
+/*
+ * 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
+ *
+ * NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
+ */
+
+int mq_send(
+ mqd_t mqdes,
+ const char *msg_ptr,
+ size_t msg_len,
+ unsigned int msg_prio
+);
+
+#if defined(_POSIX_TIMEOUTS)
+
+#include <time.h>
+
+int mq_timedsend(
+ mqd_t mqdes,
+ const char *msg_ptr,
+ size_t msg_len,
+ unsigned int msg_prio,
+ const struct timespec *timeout
+);
+
+#endif /* _POSIX_TIMEOUTS */
+
+/*
+ * 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
+ *
+ * NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
+ */
+
+ssize_t mq_receive(
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio
+);
+
+#if defined(_POSIX_TIMEOUTS)
+
+ssize_t mq_timedreceive(
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio,
+ const struct timespec *timeout
+);
+
+#endif /* _POSIX_TIMEOUTS */
+
+#if defined(_POSIX_REALTIME_SIGNALS)
+
+/*
+ * 15.2.6 Notify Process that a Message is Available on a Queue,
+ * P1003.1b-1993, p. 280
+ */
+
+int mq_notify(
+ mqd_t mqdes,
+ const struct sigevent *notification
+);
+
+#endif /* _POSIX_REALTIME_SIGNALS */
+
+/*
+ * 15.2.7 Set Message Queue Attributes, P1003.1b-1993, p. 281
+ */
+
+int mq_setattr(
+ mqd_t mqdes,
+ const struct mq_attr *mqstat,
+ struct mq_attr *omqstat
+);
+
+/*
+ * 15.2.8 Get Message Queue Attributes, P1003.1b-1993, p. 283
+ */
+
+int mq_getattr(
+ mqd_t mqdes,
+ struct mq_attr *mqstat
+);
+
+#endif /* _POSIX_MESSAGE_PASSING */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/cancel.h b/cpukit/posix/include/rtems/posix/cancel.h
new file mode 100644
index 0000000000..61fabdb463
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/cancel.h
@@ -0,0 +1,33 @@
+/**
+ * @file rtems/posix/cancel.h
+ */
+
+/* rtems/posix/cancel.h
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_CANCEL_H
+#define _RTEMS_POSIX_CANCEL_H
+
+typedef struct {
+ Chain_Node Node;
+ void (*routine)( void * );
+ void *arg;
+} POSIX_Cancel_Handler_control;
+
+/*
+ * _POSIX_Threads_cancel_run
+ *
+ * DESCRIPTION:
+ *
+ * This support routine runs through the chain of cancel handlers that
+ * have been registered and executes them.
+ */
+
+void _POSIX_Threads_cancel_run(
+ Thread_Control *the_thread
+);
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/cond.h b/cpukit/posix/include/rtems/posix/cond.h
new file mode 100644
index 0000000000..23b00d9dba
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/cond.h
@@ -0,0 +1,171 @@
+/**
+ * @file rtems/posix/cond.h
+ */
+
+/*
+ * This include file contains all the private support information for
+ * POSIX condition variables.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_COND_H
+#define _RTEMS_POSIX_COND_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+#include <rtems/score/threadq.h>
+
+/*
+ * Constant to indicate condition variable does not currently have
+ * a mutex assigned to it.
+ */
+
+#define POSIX_CONDITION_VARIABLES_NO_MUTEX 0
+
+/*
+ * Data Structure used to manage a POSIX condition variable
+ */
+
+typedef struct {
+ Objects_Control Object;
+ int process_shared;
+ pthread_mutex_t Mutex;
+ Thread_queue_Control Wait_queue;
+} POSIX_Condition_variables_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+POSIX_EXTERN Objects_Information _POSIX_Condition_variables_Information;
+
+/*
+ * The default condition variable attributes structure.
+ */
+
+extern const pthread_condattr_t _POSIX_Condition_variables_Default_attributes;
+
+/*
+ * _POSIX_Condition_variables_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _POSIX_Condition_variables_Manager_initialization(
+ uint32_t maximum_condition_variables
+);
+
+/*
+ * _POSIX_Condition_variables_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a condition variable control block from
+ * the inactive chain of free condition variable control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Condition_variables_Control *
+ _POSIX_Condition_variables_Allocate( void );
+
+/*
+ * _POSIX_Condition_variables_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a condition variable control block to the
+ * inactive chain of free condition variable control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Condition_variables_Free (
+ POSIX_Condition_variables_Control *the_condition_variable
+);
+
+/*
+ * _POSIX_Condition_variables_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps condition variable IDs to condition variable control
+ * blocks. If ID corresponds to a local condition variable, then it returns
+ * the_condition variable control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the condition variable ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_condition variable is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_condition variable is undefined.
+ */
+
+#if 0
+RTEMS_INLINE_ROUTINE POSIX_Condition_variables_Control *_POSIX_Condition_variables_Get (
+ Objects_Id *id,
+ Objects_Locations *location
+);
+#endif
+
+/*
+ * _POSIX_Condition_variables_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_condition variable is NULL
+ * and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Condition_variables_Is_null (
+ POSIX_Condition_variables_Control *the_condition_variable
+);
+
+/*
+ * _POSIX_Condition_variables_Signal_support
+ *
+ * DESCRIPTION:
+ *
+ * A support routine which implements guts of the broadcast and single task
+ * wake up version of the "signal" operation.
+ */
+
+int _POSIX_Condition_variables_Signal_support(
+ pthread_cond_t *cond,
+ boolean is_broadcast
+);
+
+/*
+ * _POSIX_Condition_variables_Wait_support
+ *
+ * DESCRIPTION:
+ *
+ * A support routine which implements guts of the blocking, non-blocking, and
+ * timed wait version of condition variable wait routines.
+ */
+
+int _POSIX_Condition_variables_Wait_support(
+ pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ Watchdog_Interval timeout,
+ boolean already_timedout
+);
+
+#include <rtems/posix/cond.inl>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/posix/condmp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/condmp.h b/cpukit/posix/include/rtems/posix/condmp.h
new file mode 100644
index 0000000000..a6da27170d
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/condmp.h
@@ -0,0 +1,165 @@
+/**
+ * @file rtems/posix/condmp.h
+ */
+
+/* condmp.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the POSIX Condition Variable Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_CONDMP_H
+#define _RTEMS_POSIX_CONDMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote condition variable operations.
+ */
+
+typedef enum {
+ POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_CREATE = 0,
+ POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_DELETE = 1,
+ POSIX_CONDITION_VARIABLES_MP_EXTRACT_PROXY = 2,
+ POSIX_CONDITION_VARIABLES_MP_OBTAIN_REQUEST = 3,
+ POSIX_CONDITION_VARIABLES_MP_OBTAIN_RESPONSE = 4,
+ POSIX_CONDITION_VARIABLES_MP_RELEASE_REQUEST = 5,
+ POSIX_CONDITION_VARIABLES_MP_RELEASE_RESPONSE = 6,
+} POSIX_Condition_variables_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote condition variable operations.
+ */
+
+typedef struct {
+ MP_packet_Prefix Prefix;
+ POSIX_Condition_variables_MP_Remote_operations operation;
+ Objects_Name name;
+ boolean wait; /* XXX options */
+ Objects_Id proxy_id;
+} POSIX_Condition_variables_MP_Packet;
+
+/*
+ * _POSIX_Condition_variables_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+
+void _POSIX_Condition_variables_MP_Send_process_packet (
+ POSIX_Condition_variables_MP_Remote_operations operation,
+ Objects_Id condition_variables_id,
+ Objects_Name name,
+ Objects_Id proxy_id
+);
+
+/*
+ * _POSIX_Condition_variables_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+int _POSIX_Condition_variables_MP_Send_request_packet (
+ POSIX_Condition_variables_MP_Remote_operations operation,
+ Objects_Id condition_variables_id,
+ boolean wait, /* XXX options */
+ Watchdog_Interval timeout
+);
+
+/*
+ * _POSIX_Condition_variables_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _POSIX_Condition_variables_MP_Send_response_packet (
+ POSIX_Condition_variables_MP_Remote_operations operation,
+ Objects_Id condition_variables_id,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _POSIX_Condition_variables_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _POSIX_Condition_variables_MP_Process_packet (
+ MP_packet_Prefix *the_packet_prefix
+);
+
+/*
+ * _POSIX_Condition_variables_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Condition_variables_MP_Send_object_was_deleted (
+ Thread_Control *the_proxy
+);
+
+/*
+ * _POSIX_Condition_variables_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Condition_variables_MP_Send_extract_proxy (
+ Thread_Control *the_thread
+);
+
+/*
+ * _POSIX_Condition_variables_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a condition variable mp packet.
+ */
+
+POSIX_Condition_variables_MP_Packet
+ *_POSIX_Condition_variables_MP_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/posix/include/rtems/posix/config.h b/cpukit/posix/include/rtems/posix/config.h
new file mode 100644
index 0000000000..6364003825
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/config.h
@@ -0,0 +1,66 @@
+/**
+ * @file rtems/posix/config.h
+ */
+
+/* config.h
+ *
+ * This include file contains the table of user defined configuration
+ * parameters specific for the POSIX API.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_CONFIG_H
+#define _RTEMS_POSIX_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * XXX
+ *
+ * The following records define the Configuration Table. The
+ * information contained in this table is required in all
+ * RTEMS systems, whether single or multiprocessor. This
+ * table primarily defines the following:
+ *
+ * + required number of each object type
+ */
+
+/*
+ * For now, we are only allowing the user to specify the entry point
+ * and stack size for POSIX initialization threads.
+ */
+
+typedef struct {
+ void *(*thread_entry)(void *);
+ int stack_size;
+} posix_initialization_threads_table;
+
+typedef struct {
+ int maximum_threads;
+ int maximum_mutexes;
+ int maximum_condition_variables;
+ int maximum_keys;
+ int maximum_timers;
+ int maximum_queued_signals;
+ int maximum_message_queues;
+ int maximum_semaphores;
+ int number_of_initialization_threads;
+ posix_initialization_threads_table *User_initialization_threads_table;
+} posix_api_configuration_table;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/key.h b/cpukit/posix/include/rtems/posix/key.h
new file mode 100644
index 0000000000..a3bc0f7375
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/key.h
@@ -0,0 +1,138 @@
+/**
+ * @file rtems/posix/key.h
+ */
+
+/* rtems/posix/key.h
+ *
+ * This include file contains all the private support information for
+ * POSIX key.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_KEY_H
+#define _RTEMS_POSIX_KEY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Data Structure used to manage a POSIX key
+ *
+ * NOTE: The Values is a table indexed by the index portion of the
+ * ID of the currently executing thread.
+ */
+
+typedef struct {
+ Objects_Control Object;
+ boolean is_active;
+ void (*destructor)( void * );
+ void **Values[ OBJECTS_APIS_LAST + 1 ];
+} POSIX_Keys_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+POSIX_EXTERN Objects_Information _POSIX_Keys_Information;
+
+/*
+ * _POSIX_Keys_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _POSIX_Key_Manager_initialization(
+ uint32_t maximum_keys
+);
+
+/*
+ * _POSIX_Keys_Run_destructors
+ *
+ * DESCRIPTION:
+ *
+ * This function executes all the destructors associated with the thread's
+ * keys. This function will execute until all values have been set to NULL.
+ *
+ * NOTE: This is the routine executed when a thread exits to
+ * run through all the keys and do the destructor action.
+ */
+
+void _POSIX_Keys_Run_destructors(
+ Thread_Control *thread
+);
+
+/*
+ * _POSIX_Keys_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a keys control block from
+ * the inactive chain of free keys control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Keys_Control *_POSIX_Keys_Allocate( void );
+
+/*
+ * _POSIX_Keys_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a keys control block to the
+ * inactive chain of free keys control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Keys_Free (
+ POSIX_Keys_Control *the_key
+);
+
+/*
+ * _POSIX_Keys_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps key IDs to key control blocks.
+ * If ID corresponds to a local keys, then it returns
+ * the_key control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the keys ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_key is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_key is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Keys_Control *_POSIX_Keys_Get (
+ Objects_Id id,
+ Objects_Locations *location
+);
+
+/*
+ * _POSIX_Keys_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_key is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Keys_Is_null (
+ POSIX_Keys_Control *the_key
+);
+
+#include <rtems/posix/key.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/mqueue.h b/cpukit/posix/include/rtems/posix/mqueue.h
new file mode 100644
index 0000000000..f1222c08e9
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/mqueue.h
@@ -0,0 +1,251 @@
+/**
+ * @file rtems/posix/mqueue.h
+ *
+ * This include file contains all the private support information for
+ * POSIX Message Queues.
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_MQUEUE_H
+#define _RTEMS_POSIX_MQUEUE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <signal.h>
+
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+
+/*
+ * Data Structure used to manage a POSIX message queue
+ */
+
+typedef struct {
+ Objects_Control Object;
+ int process_shared;
+ boolean named;
+ boolean linked;
+ uint32_t open_count;
+ CORE_message_queue_Control Message_queue;
+ struct sigevent notification;
+} POSIX_Message_queue_Control;
+
+typedef struct {
+ Objects_Control Object;
+ POSIX_Message_queue_Control *Queue;
+ int oflag;
+} POSIX_Message_queue_Control_fd;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects. The second item is used to manage the set
+ * of "file descriptors" associated with the message queues.
+ */
+
+POSIX_EXTERN Objects_Information _POSIX_Message_queue_Information;
+POSIX_EXTERN Objects_Information _POSIX_Message_queue_Information_fds;
+
+/*
+ * _POSIX_Message_queue_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _POSIX_Message_queue_Manager_initialization(
+ uint32_t maximum_message_queues
+);
+
+/*
+ *
+ * _POSIX_Message_queue_Create_support
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the creation of a message queue utilizing the
+ * core message queue.
+ */
+
+int _POSIX_Message_queue_Create_support(
+ const char *name,
+ int pshared,
+ struct mq_attr *attr,
+ POSIX_Message_queue_Control **message_queue
+);
+
+/*
+ * _POSIX_Message_queue_Delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine supports the mq_unlink and mq_close routines by
+ * doing most of the work involved with removing a message queue.
+ */
+
+void _POSIX_Message_queue_Delete(
+ POSIX_Message_queue_Control *the_mq
+);
+
+/*
+ * _POSIX_Message_queue_Receive_support
+ *
+ * DESCRIPTION:
+ *
+ * This routine supports the various flavors of receiving a message.
+ */
+
+ssize_t _POSIX_Message_queue_Receive_support(
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio,
+ Watchdog_Interval timeout
+);
+
+/*
+ * _POSIX_Message_queue_Send_support
+ *
+ * DESCRIPTION:
+ *
+ * This routine posts a message to a specified message queue.
+ */
+
+int _POSIX_Message_queue_Send_support(
+ mqd_t mqdes,
+ const char *msg_ptr,
+ uint32_t msg_len,
+ uint32_t msg_prio,
+ Watchdog_Interval timeout
+);
+
+/*
+ * _POSIX_Message_queue_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a message queue control block from
+ * the inactive chain of free message queue control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control *_POSIX_Message_queue_Allocate( void );
+
+/*
+ * _POSIX_Message_queue_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a message queue control block to the
+ * inactive chain of free message queue control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Free (
+ POSIX_Message_queue_Control *the_mq
+);
+
+/*
+ * _POSIX_Message_queue_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps message queue IDs to message queue control blocks.
+ * If ID corresponds to a local message queue, then it returns
+ * the_mq control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the message queue ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_message queue is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_mq is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control *_POSIX_Message_queue_Get (
+ Objects_Id id,
+ Objects_Locations *location
+);
+
+/*
+ * _POSIX_Message_queue_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_message_queue is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Message_queue_Is_null (
+ POSIX_Message_queue_Control *the_mq
+);
+
+/*
+ * _POSIX_Message_queue_Name_to_id
+ *
+ * DESCRIPTION:
+ *
+ * This routine looks up the specified name for a message queue and returns the
+ * id of the message queue associated with it.
+ */
+
+int _POSIX_Message_queue_Name_to_id(
+ const char *name,
+ Objects_Id *id
+);
+
+/*
+ * _POSIX_Message_queue_Priority_to_core
+ *
+ * DESCRIPTION:
+ *
+ * XXX
+ */
+
+RTEMS_INLINE_ROUTINE CORE_message_queue_Submit_types _POSIX_Message_queue_Priority_to_core(
+ unsigned int priority
+);
+
+/*
+ * _POSIX_Message_queue_Priority_from_core
+ *
+ * DESCRIPTION:
+ *
+ * XXX
+ */
+
+RTEMS_INLINE_ROUTINE unsigned int _POSIX_Message_queue_Priority_from_core(
+ CORE_message_queue_Submit_types priority
+);
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Translate_core_message_queue_return_code
+ *
+ * DESCRIPTION:
+ *
+ * XXX
+ */
+
+int _POSIX_Message_queue_Translate_core_message_queue_return_code(
+ uint32_t the_message_queue_status
+);
+
+
+#include <rtems/posix/mqueue.inl>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/posix/mqueuemp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/mqueuemp.h b/cpukit/posix/include/rtems/posix/mqueuemp.h
new file mode 100644
index 0000000000..636c3407ee
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/mqueuemp.h
@@ -0,0 +1,164 @@
+/**
+ * @file rtems/posix/mqueuemp.h
+ */
+
+/* mqueuemp.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the POSIX Message Queue Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_MQUEUEMP_H
+#define _RTEMS_POSIX_MQUEUEMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote message queue operations.
+ */
+
+typedef enum {
+ POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_CREATE = 0,
+ POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_DELETE = 1,
+ POSIX_MESSAGE_QUEUE_MP_EXTRACT_PROXY = 2,
+ POSIX_MESSAGE_QUEUE_MP_OBTAIN_REQUEST = 3,
+ POSIX_MESSAGE_QUEUE_MP_OBTAIN_RESPONSE = 4,
+ POSIX_MESSAGE_QUEUE_MP_RELEASE_REQUEST = 5,
+ POSIX_MESSAGE_QUEUE_MP_RELEASE_RESPONSE = 6,
+} POSIX_Message_queue_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote message queue operations.
+ */
+
+typedef struct {
+ MP_packet_Prefix Prefix;
+ POSIX_Message_queue_MP_Remote_operations operation;
+ Objects_Name name;
+ boolean wait; /* XXX options */
+ Objects_Id proxy_id;
+} POSIX_Message_queue_MP_Packet;
+
+/*
+ * _POSIX_Message_queue_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+
+void _POSIX_Message_queue_MP_Send_process_packet (
+ POSIX_Message_queue_MP_Remote_operations operation,
+ Objects_Id mq_id,
+ Objects_Name name,
+ Objects_Id proxy_id
+);
+
+/*
+ * _POSIX_Message_queue_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+int _POSIX_Message_queue_MP_Send_request_packet (
+ POSIX_Message_queue_MP_Remote_operations operation,
+ Objects_Id mq_id,
+ boolean wait, /* XXX options */
+ Watchdog_Interval timeout
+);
+
+/*
+ * _POSIX_Message_queue_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _POSIX_Message_queue_MP_Send_response_packet (
+ POSIX_Message_queue_MP_Remote_operations operation,
+ Objects_Id mq_id,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _POSIX_Message_queue_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _POSIX_Message_queue_MP_Process_packet (
+ MP_packet_Prefix *the_packet_prefix
+);
+
+/*
+ * _POSIX_Message_queue_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Message_queue_MP_Send_object_was_deleted (
+ Thread_Control *the_proxy
+);
+
+/*
+ * _POSIX_Message_queue_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Message_queue_MP_Send_extract_proxy (
+ Thread_Control *the_thread
+);
+
+/*
+ * _POSIX_Message_queue_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a message queue mp packet.
+ */
+
+POSIX_Message_queue_MP_Packet *_POSIX_Message_queue_MP_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/posix/include/rtems/posix/mutex.h b/cpukit/posix/include/rtems/posix/mutex.h
new file mode 100644
index 0000000000..a81406f45b
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/mutex.h
@@ -0,0 +1,160 @@
+/**
+ * @file rtems/posix/mutex.h
+ */
+
+/*
+ * This include file contains all the private support information for
+ * POSIX mutex's.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_MUTEX_H
+#define _RTEMS_POSIX_MUTEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/coremutex.h>
+#include <pthread.h>
+
+/*
+ * Data Structure used to manage a POSIX mutex
+ */
+
+typedef struct {
+ Objects_Control Object;
+ int process_shared;
+ CORE_mutex_Control Mutex;
+} POSIX_Mutex_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+POSIX_EXTERN Objects_Information _POSIX_Mutex_Information;
+
+/*
+ * The default mutex attributes structure.
+ */
+
+extern const pthread_mutexattr_t _POSIX_Mutex_Default_attributes;
+
+/*
+ * _POSIX_Mutex_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _POSIX_Mutex_Manager_initialization(
+ uint32_t maximum_mutexes
+);
+
+/*
+ * _POSIX_Mutex_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a mutexes control block from
+ * the inactive chain of free mutexes control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Mutex_Control *_POSIX_Mutex_Allocate( void );
+
+/*
+ * _POSIX_Mutex_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a mutexes control block to the
+ * inactive chain of free mutexes control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Free (
+ POSIX_Mutex_Control *the_mutex
+);
+
+#if 0
+/*
+ * _POSIX_Mutex_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps mutexes IDs to mutexes control blocks.
+ * If ID corresponds to a local mutexes, then it returns
+ * the_mutex control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the mutexes ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_mutex is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_mutex is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Mutex_Control *_POSIX_Mutex_Get (
+ Objects_Id *id,
+ Objects_Locations *location
+);
+
+/*
+ * _POSIX_Mutex_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_mutex is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Mutex_Is_null (
+ POSIX_Mutex_Control *the_mutex
+);
+#endif
+
+/*
+ * _POSIX_Mutex_Lock_support
+ *
+ * DESCRIPTION:
+ *
+ * A support routine which implements guts of the blocking, non-blocking, and
+ * timed wait version of mutex lock.
+ */
+
+int _POSIX_Mutex_Lock_support(
+ pthread_mutex_t *mutex,
+ boolean blocking,
+ Watchdog_Interval timeout
+);
+
+/*
+ * _POSIX_Mutex_From_core_mutex_status
+ *
+ * DESCRIPTION:
+ *
+ * A support routine which converts core mutex status codes into the
+ * appropriate POSIX status values.
+ */
+
+int _POSIX_Mutex_From_core_mutex_status(
+ CORE_mutex_Status status
+);
+
+
+#include <rtems/posix/mutex.inl>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/posix/mutexmp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/mutexmp.h b/cpukit/posix/include/rtems/posix/mutexmp.h
new file mode 100644
index 0000000000..561bc42337
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/mutexmp.h
@@ -0,0 +1,177 @@
+/**
+ * @file rtems/posix/mutexmp.h
+ */
+
+/* mutexmp.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the POSIX Mutex Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_MUTEXMP_H
+#define _RTEMS_POSIX_MUTEXMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote mutex operations.
+ */
+
+typedef enum {
+ POSIX_MUTEX_MP_ANNOUNCE_CREATE = 0,
+ POSIX_MUTEX_MP_ANNOUNCE_DELETE = 1,
+ POSIX_MUTEX_MP_EXTRACT_PROXY = 2,
+ POSIX_MUTEX_MP_OBTAIN_REQUEST = 3,
+ POSIX_MUTEX_MP_OBTAIN_RESPONSE = 4,
+ POSIX_MUTEX_MP_RELEASE_REQUEST = 5,
+ POSIX_MUTEX_MP_RELEASE_RESPONSE = 6,
+} POSIX_Mutex_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote mutex operations.
+ */
+
+typedef struct {
+ MP_packet_Prefix Prefix;
+ POSIX_Mutex_MP_Remote_operations operation;
+ Objects_Name name;
+ boolean wait; /* XXX options */
+ Objects_Id proxy_id;
+} POSIX_Mutex_MP_Packet;
+
+/*
+ * _POSIX_Mutex_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+
+void _POSIX_Mutex_MP_Send_process_packet (
+ POSIX_Mutex_MP_Remote_operations operation,
+ Objects_Id mutex_id,
+ Objects_Name name,
+ Objects_Id proxy_id
+);
+
+/*
+ * _POSIX_Mutex_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+int _POSIX_Mutex_MP_Send_request_packet (
+ POSIX_Mutex_MP_Remote_operations operation,
+ Objects_Id mutex_id,
+ boolean wait, /* XXX options */
+ Watchdog_Interval timeout
+);
+
+/*
+ * _POSIX_Mutex_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _POSIX_Mutex_MP_Send_response_packet (
+ POSIX_Mutex_MP_Remote_operations operation,
+ Objects_Id mutex_id,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _POSIX_Mutex_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _POSIX_Mutex_MP_Process_packet (
+ MP_packet_Prefix *the_packet_prefix
+);
+
+/*
+ * _POSIX_Mutex_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Mutex_MP_Send_object_was_deleted (
+ Thread_Control *the_proxy
+);
+
+/*
+ * _POSIX_Mutex_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Mutex_MP_Send_extract_proxy (
+ Thread_Control *the_thread
+);
+
+/*
+ * _POSIX_Threads_mutex_MP_support
+ *
+ * DESCRIPTION:
+ *
+ * This routine XXX
+ */
+
+void _POSIX_Threads_mutex_MP_support(
+ Thread_Control *the_thread,
+ Objects_Id id
+);
+
+/*
+ * _POSIX_Mutex_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a mutex mp packet.
+ */
+
+POSIX_Mutex_MP_Packet *_POSIX_Mutex_MP_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/posix/include/rtems/posix/posixapi.h b/cpukit/posix/include/rtems/posix/posixapi.h
new file mode 100644
index 0000000000..af19c4fd07
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/posixapi.h
@@ -0,0 +1,37 @@
+/**
+ * @file rtems/posix/posixapi.h
+ */
+
+/*
+ * POSIX API Support
+ *
+ * NOTE:
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_POSIXAPI_H
+#define _RTEMS_POSIX_POSIXAPI_H
+
+#include <rtems/config.h>
+
+/*PAGE
+ *
+ * _POSIX_API_Initialize
+ *
+ * XXX
+ */
+
+void _POSIX_API_Initialize(
+ rtems_configuration_table *configuration_table
+);
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/priority.h b/cpukit/posix/include/rtems/posix/priority.h
new file mode 100644
index 0000000000..36cecc903d
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/priority.h
@@ -0,0 +1,48 @@
+/**
+ * @file rtems/posix/priority.h
+ */
+
+/*
+ *
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_PRIORITY_H
+#define _RTEMS_POSIX_PRIORITY_H
+
+#include <rtems/score/priority.h>
+
+/*
+ * 1003.1b-1993,2.2.2.80 definition of priority, p. 19
+ *
+ * "Numericallly higher values represent higher priorities."
+ *
+ * Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API.
+ *
+ * There are only 254 posix priority levels since a task at priority level
+ * 255 would never run because of the RTEMS idle task. This is necessary
+ * because GNAT maps the lowest Ada task priority to the lowest thread
+ * priority. The lowest priority Ada task should get to run, so there is
+ * a fundamental conflict with having 255 priorities.
+ */
+
+#define POSIX_SCHEDULER_MAXIMUM_PRIORITY (254)
+
+#define POSIX_SCHEDULER_MINIMUM_PRIORITY (1)
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Priority_Is_valid(
+ int priority
+);
+
+RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Priority_To_core(
+ int priority
+);
+
+RTEMS_INLINE_ROUTINE int _POSIX_Priority_From_core(
+ Priority_Control priority
+);
+
+#include <rtems/posix/priority.inl>
+
+#endif
diff --git a/cpukit/posix/include/rtems/posix/psignal.h b/cpukit/posix/include/rtems/posix/psignal.h
new file mode 100644
index 0000000000..8e4b0a3fa5
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/psignal.h
@@ -0,0 +1,125 @@
+/**
+ * @file rtems/posix/psignal.h
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_PSIGNAL_H
+#define _RTEMS_POSIX_PSIGNAL_H
+
+#include <rtems/posix/pthread.h>
+
+/*
+ * Currently 32 signals numbered 1-32 are defined
+ */
+
+#define SIGNAL_EMPTY_MASK 0x00000000
+#define SIGNAL_ALL_MASK 0xffffffff
+
+#define signo_to_mask( _sig ) (1 << ((_sig) - 1))
+
+#define is_valid_signo( _sig ) \
+ ((_sig) >= 1 && (_sig) <= 32 )
+
+#define _States_Is_interruptible_signal( _states ) \
+ ( ((_states) & \
+ (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \
+ (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL))
+
+#define SIGACTION_TERMINATE \
+ { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abnormal_termination_handler} }
+#define SIGACTION_IGNORE \
+ { 0, SIGNAL_ALL_MASK, {SIG_IGN} }
+#define SIGACTION_STOP \
+ { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} }
+#define SIGACTION_CONTINUE \
+ { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} }
+
+#define SIG_ARRAY_MAX (SIGRTMAX + 1)
+
+/*
+ * Variables
+ */
+
+extern sigset_t _POSIX_signals_Pending;
+
+extern struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ];
+
+extern struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ];
+
+extern Watchdog_Control _POSIX_signals_Alarm_timer;
+
+extern Thread_queue_Control _POSIX_signals_Wait_queue;
+
+extern Chain_Control _POSIX_signals_Inactive_siginfo;
+
+extern Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
+
+/*
+ * POSIX internal siginfo structure
+ */
+
+typedef struct {
+ Chain_Node Node;
+ siginfo_t Info;
+} POSIX_signals_Siginfo_node;
+
+/*
+ * Internal routines
+ */
+
+void _POSIX_signals_Manager_Initialization(
+ int maximum_queued_signals
+);
+
+void _POSIX_signals_Post_switch_extension(
+ Thread_Control *the_thread
+);
+
+boolean _POSIX_signals_Unblock_thread(
+ Thread_Control *the_thread,
+ int signo,
+ siginfo_t *info
+);
+
+boolean _POSIX_signals_Check_signal(
+ POSIX_API_Control *api,
+ int signo,
+ boolean is_global
+);
+
+boolean _POSIX_signals_Clear_signals(
+ POSIX_API_Control *api,
+ int signo,
+ siginfo_t *info,
+ boolean is_global,
+ boolean check_blocked
+);
+
+int killinfo(
+ pid_t pid,
+ int sig,
+ const union sigval *value
+);
+
+void _POSIX_signals_Set_process_signals(
+ sigset_t mask
+);
+
+void _POSIX_signals_Clear_process_signals(
+ sigset_t mask
+);
+
+/*
+ * Default signal handlers
+ */
+
+#define _POSIX_signals_Stop_handler NULL
+#define _POSIX_signals_Continue_handler NULL
+
+void _POSIX_signals_Abnormal_termination_handler( int signo );
+
+#endif
+/* end of file */
diff --git a/cpukit/posix/include/rtems/posix/pthread.h b/cpukit/posix/include/rtems/posix/pthread.h
new file mode 100644
index 0000000000..1598abc56d
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/pthread.h
@@ -0,0 +1,153 @@
+/**
+ * @file rtems/posix/pthread.h
+ */
+
+/* rtems/posix/pthread.h
+ *
+ * This include file contains all the private support information for
+ * POSIX threads.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_PTHREAD_H
+#define _RTEMS_POSIX_PTHREAD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/posix/config.h>
+#include <rtems/posix/threadsup.h>
+
+#define PTHREAD_MINIMUM_STACK_SIZE (STACK_MINIMUM_SIZE * 2)
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+POSIX_EXTERN Objects_Information _POSIX_Threads_Information;
+
+/*
+ * These are used to manage the user initialization threads.
+ */
+
+POSIX_EXTERN posix_initialization_threads_table
+ *_POSIX_Threads_User_initialization_threads;
+POSIX_EXTERN uint32_t _POSIX_Threads_Number_of_initialization_threads;
+
+extern const pthread_attr_t _POSIX_Threads_Default_attributes;
+
+/*
+ * _POSIX_Threads_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _POSIX_Threads_Manager_initialization(
+ uint32_t maximum_pthreads,
+ uint32_t number_of_initialization_threads,
+ posix_initialization_threads_table *user_threads
+);
+
+/*
+ * _POSIX_Threads_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a pthread control block from
+ * the inactive chain of free pthread control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate( void );
+
+/*
+ * _POSIX_Threads_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a pthread control block to the
+ * inactive chain of free pthread control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Free(
+ Thread_Control *the_pthread
+);
+
+/*
+ * _POSIX_Threads_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps pthread IDs to pthread control blocks.
+ * If ID corresponds to a local pthread, then it returns
+ * the_pthread control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the pthread ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_pthread is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_pthread is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Get(
+ pthread_t id,
+ Objects_Locations *location
+);
+
+/*
+ * _POSIX_Threads_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_pthread is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Threads_Is_null(
+ Thread_Control *the_pthread
+);
+
+/*
+ * _POSIX_Threads_Sporadic_budget_callout
+ *
+ * DESCRIPTION:
+ *
+ * This routine handles the sporadic scheduling algorithm.
+ */
+
+void _POSIX_Threads_Sporadic_budget_callout(
+ Thread_Control *the_thread
+);
+
+/*
+ * _POSIX_Threads_Sporadic_budget_TSR
+ *
+ * DESCRIPTION:
+ *
+ * This routine supports the sporadic scheduling algorithm.
+ */
+
+void _POSIX_Threads_Sporadic_budget_TSR(
+ Objects_Id id,
+ void *argument
+);
+
+#include <rtems/posix/pthread.inl>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/posix/pthreadmp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/pthreadmp.h b/cpukit/posix/include/rtems/posix/pthreadmp.h
new file mode 100644
index 0000000000..78e210bbe6
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/pthreadmp.h
@@ -0,0 +1,164 @@
+/**
+ * @file rtems/posix/pthreadmp.h
+ */
+
+/* pthreadmp.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the POSIX Threads Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_PTHREADMP_H
+#define _RTEMS_POSIX_PTHREADMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote pthread operations.
+ */
+
+typedef enum {
+ POSIX_THREADS_MP_ANNOUNCE_CREATE = 0,
+ POSIX_THREADS_MP_ANNOUNCE_DELETE = 1,
+ POSIX_THREADS_MP_EXTRACT_PROXY = 2,
+ POSIX_THREADS_MP_OBTAIN_REQUEST = 3,
+ POSIX_THREADS_MP_OBTAIN_RESPONSE = 4,
+ POSIX_THREADS_MP_RELEASE_REQUEST = 5,
+ POSIX_THREADS_MP_RELEASE_RESPONSE = 6
+} POSIX_Threads_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote pthread operations.
+ */
+
+typedef struct {
+ MP_packet_Prefix Prefix;
+ POSIX_Threads_MP_Remote_operations operation;
+ Objects_Name name;
+ boolean wait;
+ Objects_Id proxy_id;
+} POSIX_Threads_MP_Packet;
+
+/*
+ * _POSIX_Threads_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+
+void _POSIX_Threads_MP_Send_process_packet (
+ POSIX_Threads_MP_Remote_operations operation,
+ Objects_Id pthread_id,
+ Objects_Name name,
+ Objects_Id proxy_id
+);
+
+/*
+ * _POSIX_Threads_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+int _POSIX_Threads_MP_Send_request_packet (
+ POSIX_Threads_MP_Remote_operations operation,
+ Objects_Id pthread_id,
+ boolean wait,
+ Watchdog_Interval timeout
+);
+
+/*
+ * _POSIX_Threads_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _POSIX_Threads_MP_Send_response_packet (
+ POSIX_Threads_MP_Remote_operations operation,
+ Objects_Id pthread_id,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _POSIX_Threads_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _POSIX_Threads_MP_Process_packet (
+ MP_packet_Prefix *the_packet_prefix
+);
+
+/*
+ * _POSIX_Threads_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Threads_MP_Send_object_was_deleted (
+ Thread_Control *the_proxy
+);
+
+/*
+ * _POSIX_Threads_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Threads_MP_Send_extract_proxy (
+ Thread_Control *the_thread
+);
+
+/*
+ * _POSIX_Threads_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a pthread mp packet.
+ */
+
+POSIX_Threads_MP_Packet *_POSIX_Threads_MP_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/posix/include/rtems/posix/ptimer.h b/cpukit/posix/include/rtems/posix/ptimer.h
new file mode 100644
index 0000000000..befa4e1606
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/ptimer.h
@@ -0,0 +1,94 @@
+/**
+ * @file rtems/posix/ptimer.h
+ */
+
+/* rtems/posix/ptimer.h
+ *
+ * This include file contains all the private support information for
+ * POSIX timers.
+ *
+ * COPYRIGHT (c) 1998.
+ * Alfonso Escalera Piña
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * ptimer.h,v 1.0 1998/03/31 16:21:16
+ */
+
+#ifndef _RTEMS_POSIX_PTIMER_H
+#define _RTEMS_POSIX_PTIMER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/posix/config.h>
+
+/*
+ * _POSIX_Timers_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _POSIX_Timer_Manager_initialization ( int max_timers );
+
+/*
+ * 14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264
+ *
+ * timer_create
+ */
+
+int timer_create(
+ clockid_t clock_id,
+ struct sigevent *evp,
+ timer_t *timerid
+);
+
+/*
+ * 14.2.3 Delete a Per_process Timer, P1003.1b-1993, p. 266
+ */
+
+int timer_delete(
+ timer_t timerid
+);
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ *
+ * timer_settime
+ */
+
+int timer_settime(
+ timer_t timerid,
+ int flags,
+ const struct itimerspec *value,
+ struct itimerspec *ovalue
+);
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ *
+ * timer_gettime
+ */
+
+int timer_gettime(
+ timer_t timerid,
+ struct itimerspec *value
+);
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ *
+ * timer_getoverrun
+ *
+ */
+
+int timer_getoverrun(
+ timer_t timerid
+);
+
+#endif
diff --git a/cpukit/posix/include/rtems/posix/semaphore.h b/cpukit/posix/include/rtems/posix/semaphore.h
new file mode 100644
index 0000000000..5fd0f5f171
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/semaphore.h
@@ -0,0 +1,184 @@
+/**
+ * @file rtems/posix/semaphore.h
+ */
+
+/* rtems/posix/semaphore.h
+ *
+ * This include file contains all the private support information for
+ * POSIX Semaphores.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_SEMAPHORE_H
+#define _RTEMS_POSIX_SEMAPHORE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <semaphore.h>
+#include <rtems/score/coresem.h>
+
+#define SEM_FAILED (sem_t *) -1
+
+/*
+ * Data Structure used to manage a POSIX semaphore
+ */
+
+typedef struct {
+ Objects_Control Object;
+ int process_shared;
+ boolean named;
+ boolean linked;
+ uint32_t open_count;
+ CORE_semaphore_Control Semaphore;
+} POSIX_Semaphore_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+POSIX_EXTERN Objects_Information _POSIX_Semaphore_Information;
+
+/*
+ * _POSIX_Semaphore_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _POSIX_Semaphore_Manager_initialization(
+ uint32_t maximum_semaphorees
+);
+
+/*
+ * _POSIX_Semaphore_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a semaphore control block from
+ * the inactive chain of free semaphore control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Allocate( void );
+
+/*
+ * _POSIX_Semaphore_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a semaphore control block to the
+ * inactive chain of free semaphore control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free (
+ POSIX_Semaphore_Control *the_semaphore
+);
+
+/*
+ * _POSIX_Semaphore_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps semaphore IDs to semaphore control blocks.
+ * If ID corresponds to a local semaphore, then it returns
+ * the_semaphore control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the semaphore ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_semaphore is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_semaphore is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get (
+ sem_t *id,
+ Objects_Locations *location
+);
+
+/*
+ * _POSIX_Semaphore_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_semaphore is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Semaphore_Is_null (
+ POSIX_Semaphore_Control *the_semaphore
+);
+
+/*
+ * _POSIX_Semaphore_Create_support
+ *
+ * DESCRIPTION:
+ *
+ * This routine supports the sem_init and sem_open routines.
+ */
+
+int _POSIX_Semaphore_Create_support(
+ const char *name,
+ int pshared,
+ unsigned int value,
+ POSIX_Semaphore_Control **the_sem
+);
+
+/*
+ * _POSIX_Semaphore_Delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine supports the sem_close and sem_unlink routines.
+ */
+
+void _POSIX_Semaphore_Delete(
+ POSIX_Semaphore_Control *the_semaphore
+);
+
+/*
+ * _POSIX_Semaphore_Wait_support
+ *
+ * DESCRIPTION:
+ *
+ * This routine supports the sem_wait, sem_trywait, and sem_timedwait
+ * services.
+ */
+
+int _POSIX_Semaphore_Wait_support(
+ sem_t *sem,
+ boolean blocking,
+ Watchdog_Interval timeout
+);
+
+/*
+ * _POSIX_Semaphore_Name_to_id
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs name to id translation.
+ */
+
+int _POSIX_Semaphore_Name_to_id(
+ const char *name,
+ sem_t *id
+);
+
+#include <rtems/posix/semaphore.inl>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/posix/semaphoremp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/semaphoremp.h b/cpukit/posix/include/rtems/posix/semaphoremp.h
new file mode 100644
index 0000000000..3ae97433cf
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/semaphoremp.h
@@ -0,0 +1,164 @@
+/**
+ * @file rtems/posix/semaphoremp.h
+ */
+
+/* semaphoremp.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the POSIX Semaphore Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_SEMAPHOREMP_H
+#define _RTEMS_POSIX_SEMAPHOREMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote semaphore operations.
+ */
+
+typedef enum {
+ POSIX_SEMAPHORE_MP_ANNOUNCE_CREATE = 0,
+ POSIX_SEMAPHORE_MP_ANNOUNCE_DELETE = 1,
+ POSIX_SEMAPHORE_MP_EXTRACT_PROXY = 2,
+ POSIX_SEMAPHORE_MP_OBTAIN_REQUEST = 3,
+ POSIX_SEMAPHORE_MP_OBTAIN_RESPONSE = 4,
+ POSIX_SEMAPHORE_MP_RELEASE_REQUEST = 5,
+ POSIX_SEMAPHORE_MP_RELEASE_RESPONSE = 6,
+} POSIX_Semaphore_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote semaphore operations.
+ */
+
+typedef struct {
+ MP_packet_Prefix Prefix;
+ POSIX_Semaphore_MP_Remote_operations operation;
+ Objects_Name name;
+ boolean wait; /* XXX options */
+ Objects_Id proxy_id;
+} POSIX_Semaphore_MP_Packet;
+
+/*
+ * _POSIX_Semaphore_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+
+void _POSIX_Semaphore_MP_Send_process_packet(
+ POSIX_Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ Objects_Name name,
+ Objects_Id proxy_id
+);
+
+/*
+ * _POSIX_Semaphore_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+int _POSIX_Semaphore_MP_Send_request_packet(
+ POSIX_Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ boolean wait, /* XXX options */
+ Watchdog_Interval timeout
+);
+
+/*
+ * _POSIX_Semaphore_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _POSIX_Semaphore_MP_Send_response_packet(
+ POSIX_Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _POSIX_Semaphore_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _POSIX_Semaphore_MP_Process_packet(
+ MP_packet_Prefix *the_packet_prefix
+);
+
+/*
+ * _POSIX_Semaphore_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Semaphore_MP_Send_object_was_deleted(
+ Thread_Control *the_proxy
+);
+
+/*
+ * _POSIX_Semaphore_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Semaphore_MP_Send_extract_proxy(
+ Thread_Control *the_thread
+);
+
+/*
+ * _POSIX_Semaphore_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a semaphore mp packet.
+ */
+
+POSIX_Semaphore_MP_Packet *_POSIX_Semaphore_MP_Get_packet( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/posix/include/rtems/posix/threadsup.h b/cpukit/posix/include/rtems/posix/threadsup.h
new file mode 100644
index 0000000000..6f295160b7
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/threadsup.h
@@ -0,0 +1,40 @@
+/**
+ * @file rtems/posix/threadsup.h
+ */
+
+/* threadsup.h
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_THREADSUP_H
+#define _RTEMS_POSIX_THREADSUP_H
+
+#include <sys/signal.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/tqdata.h>
+
+typedef struct {
+ pthread_attr_t Attributes;
+ int detachstate;
+ Thread_queue_Control Join_List;
+ int schedpolicy;
+ struct sched_param schedparam;
+ int ss_high_priority;
+ Watchdog_Control Sporadic_timer;
+
+ sigset_t signals_blocked;
+ sigset_t signals_pending;
+
+ /*
+ * POSIX Cancelability
+ */
+ int cancelability_state;
+ int cancelability_type;
+ int cancelation_requested;
+ Chain_Control Cancellation_Handlers;
+
+} POSIX_API_Control;
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/time.h b/cpukit/posix/include/rtems/posix/time.h
new file mode 100644
index 0000000000..13418cf473
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/time.h
@@ -0,0 +1,54 @@
+/**
+ * @file rtems/posix/time.h
+ */
+
+/*
+ *
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_TIME_H
+#define _RTEMS_POSIX_TIME_H
+
+#include <rtems/score/tod.h>
+
+/*
+ * Seconds from January 1, 1970 to January 1, 1988. Used to account for
+ * differences between POSIX API and RTEMS core.
+ */
+
+#define POSIX_TIME_SECONDS_1970_THROUGH_1988 \
+ (((1987 - 1970 + 1) * TOD_SECONDS_PER_NON_LEAP_YEAR) + \
+ (4 * TOD_SECONDS_PER_DAY))
+
+/*PAGE
+ *
+ * _POSIX_Timespec_subtract
+ */
+
+void _POSIX_Timespec_subtract(
+ const struct timespec *the_start,
+ const struct timespec *end,
+ struct timespec *result
+);
+
+/*
+ * _POSIX_Timespec_to_interval
+ */
+
+Watchdog_Interval _POSIX_Timespec_to_interval(
+ const struct timespec *time
+);
+
+/*PAGE
+ *
+ * _POSIX_Interval_to_timespec
+ */
+
+void _POSIX_Interval_to_timespec(
+ Watchdog_Interval ticks,
+ struct timespec *time
+);
+
+#endif
diff --git a/cpukit/posix/include/rtems/posix/timer.h b/cpukit/posix/include/rtems/posix/timer.h
new file mode 100644
index 0000000000..20c80f273d
--- /dev/null
+++ b/cpukit/posix/include/rtems/posix/timer.h
@@ -0,0 +1,75 @@
+/**
+ * @file rtems/posix/timer.h
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_TIMER_H
+#define _RTEMS_POSIX_TIMER_H
+
+#include <rtems/posix/config.h>
+/*
+ * Constants
+ */
+
+#define STATE_FREE_C 0x01 /* Free position of the table of timers */
+#define STATE_CREATE_NEW_C 0x02 /* Created timer but not running */
+#define STATE_CREATE_RUN_C 0x03 /* Created timer and running */
+#define STATE_CREATE_STOP_C 0x04 /* Created, ran and stopped timer */
+/* Maximum number of nsec allowed */
+#define MAX_NSEC_C (uint32_t )1000000000
+#define MIN_NSEC_C 0 /* Minimum number of nsec allowew */
+#define TIMER_RELATIVE_C 0 /* Indicates that the fire time is
+ * relative to the current one */
+#define SEC_TO_TICKS_C _TOD_Ticks_per_second /* Number of ticks in a second*/
+/* Nanoseconds in a second */
+#define NSEC_PER_SEC_C (uint32_t )1000000000
+
+#define SECONDS_PER_YEAR_C (uint32_t )(360 * 24) * (uint32_t )(60 * 60)
+#define SECONDS_PER_MONTH_C (uint32_t )( 30 * 24) * (uint32_t )(60 * 60)
+#define SECONDS_PER_DAY_C (uint32_t )( 24 * 60) * (uint32_t )(60)
+#define SECONDS_PER_HOUR_C (uint32_t )( 60 * 60 )
+#define SECONDS_PER_MINUTE_C (uint32_t )( 60 )
+
+
+/*
+ * Data for a timer
+ */
+
+typedef struct {
+ Objects_Control Object;
+ Watchdog_Control Timer; /* Internal Timer */
+ pthread_t thread_id; /* Thread identifier */
+ char state; /* State of the timer */
+ struct sigevent inf; /* Information associated to the timer */
+ struct itimerspec timer_data; /* Timing data of the timer */
+ uint32_t ticks; /* Number of ticks of the initialization */
+ uint32_t overrun; /* Number of expirations of the timer */
+ TOD_Control time; /* Time in which the timer was started */
+} POSIX_Timer_Control;
+
+/*
+ * _POSIX_Timers_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _POSIX_Timer_Manager_initialization ( int max_timers );
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+POSIX_EXTERN Objects_Information _POSIX_Timer_Information;
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/posix/timer.inl>
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/sched.h b/cpukit/posix/include/sched.h
new file mode 100644
index 0000000000..4f80fe41eb
--- /dev/null
+++ b/cpukit/posix/include/sched.h
@@ -0,0 +1,98 @@
+/**
+ * @file sched.h
+ */
+
+/*
+ * $Id$
+ */
+
+
+#ifndef _SCHED_H
+#define _SCHED_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <unistd.h>
+
+#if defined(_POSIX_PRIORITY_SCHEDULING)
+
+#include <sys/types.h>
+#include <time.h>
+#include <sys/sched.h>
+#include <pthread.h>
+
+/*
+ * 13.3.1 Set Scheduling Parameters, P1003.1b-1993, p. 252
+ *
+ */
+
+int sched_setparam(
+ pid_t pid,
+ const struct sched_param *param
+);
+
+/*
+ * 13.3.2 Set Scheduling Parameters, P1003.1b-1993, p. 253
+ */
+
+int sched_getparam(
+ pid_t pid,
+ const struct sched_param *param
+);
+
+/*
+ * 13.3.3 Set Scheduling Policy and Scheduling Parameters,
+ * P1003.1b-1993, p. 254
+ */
+
+int sched_setscheduler(
+ pid_t pid,
+ int policy,
+ const struct sched_param *param
+);
+
+/*
+ * 13.3.4 Get Scheduling Policy, P1003.1b-1993, p. 256
+ */
+
+int sched_getscheduler(
+ pid_t pid
+);
+
+/*
+ * 13.3.6 Get Scheduling Parameter Limits, P1003.1b-1993, p. 258
+ */
+
+int sched_get_priority_max(
+ int policy
+);
+
+int sched_get_priority_min(
+ int policy
+);
+
+int sched_rr_get_interval(
+ pid_t pid,
+ struct timespec *interval
+);
+
+#endif /* _POSIX_PRIORITY_SCHEDULING */
+
+#if defined(_POSIX_THREADS) || defined(_POSIX_PRIORITY_SCHEDULING)
+
+/*
+ * 13.3.5 Yield Processor, P1003.1b-1993, p. 257
+ */
+
+int sched_yield( void );
+
+#endif /* _POSIX_THREADS or _POSIX_PRIORITY_SCHEDULING */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/include/semaphore.h b/cpukit/posix/include/semaphore.h
new file mode 100644
index 0000000000..c2334dcad8
--- /dev/null
+++ b/cpukit/posix/include/semaphore.h
@@ -0,0 +1,119 @@
+/**
+ * @file semaphore.h
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _SEMAPHORE_H
+#define _SEMAPHORE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <unistd.h>
+
+#if defined(_POSIX_SEMAPHORES)
+
+#include <sys/time.h>
+
+/*
+ * 11.1 Semaphore Characteristics, P1003.1b-1993, p.219
+ */
+
+typedef int sem_t;
+
+/*
+ * 11.2.1 Initialize an Unnamed Semaphore, P1003.1b-1993, p.219
+ */
+
+int sem_init(
+ sem_t *sem,
+ int pshared,
+ unsigned int value
+);
+
+/*
+ * 11.2.2 Destroy an Unnamed Semaphore, P1003.1b-1993, p.220
+ */
+
+int sem_destroy(
+ sem_t *sem
+);
+
+/*
+ * 11.2.3 Initialize/Open a Named Semaphore, P1003.1b-1993, p.221
+ *
+ * NOTE: Follows open() calling conventions.
+ */
+
+sem_t *sem_open(
+ const char *name,
+ int oflag,
+ ...
+);
+
+/*
+ * 11.2.4 Close a Named Semaphore, P1003.1b-1993, p.224
+ */
+
+int sem_close(
+ sem_t *sem
+);
+
+/*
+ * 11.2.5 Remove a Named Semaphore, P1003.1b-1993, p.225
+ */
+
+int sem_unlink(
+ const char *name
+);
+
+/*
+ * 11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
+ *
+ * NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
+ */
+
+int sem_wait(
+ sem_t *sem
+);
+
+int sem_trywait(
+ sem_t *sem
+);
+
+#if defined(_POSIX_TIMEOUTS)
+int sem_timedwait(
+ sem_t *sem,
+ const struct timespec *timeout
+);
+#endif
+
+/*
+ * 11.2.7 Unlock a Semaphore, P1003.1b-1993, p.227
+ */
+
+int sem_post(
+ sem_t *sem
+);
+
+/*
+ * 11.2.8 Get the Value of a Semaphore, P1003.1b-1993, p.229
+ */
+
+int sem_getvalue(
+ sem_t *sem,
+ int *sval
+);
+
+#endif /* _POSIX_SEMAPHORES */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/inline/rtems/posix/cond.inl b/cpukit/posix/inline/rtems/posix/cond.inl
new file mode 100644
index 0000000000..7d112cdf12
--- /dev/null
+++ b/cpukit/posix/inline/rtems/posix/cond.inl
@@ -0,0 +1,105 @@
+/**
+ * @file rtems/posix/cond.inl
+ */
+
+/* rtems/posix/cond.inl
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX condition variables.
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_COND_INL
+#define _RTEMS_POSIX_COND_INL
+
+#include <pthread.h>
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Allocate
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Condition_variables_Control
+ *_POSIX_Condition_variables_Allocate( void )
+{
+ return (POSIX_Condition_variables_Control *)
+ _Objects_Allocate( &_POSIX_Condition_variables_Information );
+}
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Free
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Condition_variables_Free (
+ POSIX_Condition_variables_Control *the_condition_variable
+)
+{
+ _Objects_Free(
+ &_POSIX_Condition_variables_Information,
+ &the_condition_variable->Object
+ );
+}
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Get
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Condition_variables_Control
+*_POSIX_Condition_variables_Get (
+ pthread_cond_t *cond,
+ Objects_Locations *location
+)
+{
+ Objects_Id *id = (Objects_Id *)cond;
+ int status;
+
+ if ( !id ) {
+ *location = OBJECTS_ERROR;
+ return (POSIX_Condition_variables_Control *) 0;
+ }
+
+ if ( *id == PTHREAD_COND_INITIALIZER ) {
+ /*
+ * Do an "auto-create" here.
+ */
+
+ status = pthread_cond_init( (pthread_cond_t *)id, 0 );
+ if ( status ) {
+ *location = OBJECTS_ERROR;
+ return (POSIX_Condition_variables_Control *) 0;
+ }
+ }
+
+ /*
+ * Now call Objects_Get()
+ */
+
+ return (POSIX_Condition_variables_Control *)
+ _Objects_Get( &_POSIX_Condition_variables_Information, *id, location );
+}
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Is_null
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Condition_variables_Is_null (
+ POSIX_Condition_variables_Control *the_condition_variable
+)
+{
+ return !the_condition_variable;
+}
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/posix/inline/rtems/posix/key.inl b/cpukit/posix/inline/rtems/posix/key.inl
new file mode 100644
index 0000000000..b6a60207bb
--- /dev/null
+++ b/cpukit/posix/inline/rtems/posix/key.inl
@@ -0,0 +1,73 @@
+/**
+ * @file rtems/posix/key.inl
+ */
+
+/* rtems/posix/key.inl
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX key's.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_KEY_INL
+#define _RTEMS_POSIX_KEY_INL
+
+/*PAGE
+ *
+ * _POSIX_Keys_Allocate
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Keys_Control *_POSIX_Keys_Allocate( void )
+{
+ return (POSIX_Keys_Control *) _Objects_Allocate( &_POSIX_Keys_Information );
+}
+
+/*PAGE
+ *
+ * _POSIX_Keys_Free
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Keys_Free (
+ POSIX_Keys_Control *the_key
+)
+{
+ _Objects_Free( &_POSIX_Keys_Information, &the_key->Object );
+}
+
+/*PAGE
+ *
+ * _POSIX_Keys_Get
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Keys_Control *_POSIX_Keys_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (POSIX_Keys_Control *)
+ _Objects_Get( &_POSIX_Keys_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _POSIX_Keys_Is_null
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Keys_Is_null (
+ POSIX_Keys_Control *the_key
+)
+{
+ return !the_key;
+}
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/posix/inline/rtems/posix/mqueue.inl b/cpukit/posix/inline/rtems/posix/mqueue.inl
new file mode 100644
index 0000000000..7bc0f4dbf6
--- /dev/null
+++ b/cpukit/posix/inline/rtems/posix/mqueue.inl
@@ -0,0 +1,154 @@
+/**
+ * @file rtems/posix/mqueue.inl
+ */
+
+/* rtems/posix/mqueue.inl
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX Message 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_MQUEUE_INL
+#define _RTEMS_POSIX_MQUEUE_INL
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Allocate
+ */
+
+RTEMS_INLINE_ROUTINE
+ POSIX_Message_queue_Control *_POSIX_Message_queue_Allocate( void )
+{
+ return (POSIX_Message_queue_Control *)
+ _Objects_Allocate( &_POSIX_Message_queue_Information );
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Allocate_fd
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control_fd *
+ _POSIX_Message_queue_Allocate_fd( void )
+{
+ return (POSIX_Message_queue_Control_fd *)
+ _Objects_Allocate( &_POSIX_Message_queue_Information_fds );
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Free
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Free (
+ POSIX_Message_queue_Control *the_mq
+)
+{
+ _Objects_Free( &_POSIX_Message_queue_Information, &the_mq->Object );
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Free_fd
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Free_fd (
+ POSIX_Message_queue_Control_fd *the_mq_fd
+)
+{
+ _Objects_Free( &_POSIX_Message_queue_Information_fds, &the_mq_fd->Object );
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Namespace_remove
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Namespace_remove (
+ POSIX_Message_queue_Control *the_mq
+)
+{
+ _Objects_Namespace_remove(
+ &_POSIX_Message_queue_Information, &the_mq->Object );
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Get
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control *_POSIX_Message_queue_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (POSIX_Message_queue_Control *)
+ _Objects_Get( &_POSIX_Message_queue_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Get_fd
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control_fd *_POSIX_Message_queue_Get_fd (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (POSIX_Message_queue_Control_fd *)
+ _Objects_Get( &_POSIX_Message_queue_Information_fds, id, location );
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Is_null
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Message_queue_Is_null (
+ POSIX_Message_queue_Control *the_mq
+)
+{
+ return !the_mq;
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Priority_to_core
+ */
+
+RTEMS_INLINE_ROUTINE CORE_message_queue_Submit_types _POSIX_Message_queue_Priority_to_core(
+ unsigned int priority
+)
+{
+ return priority * -1;
+}
+
+/*
+ * _POSIX_Message_queue_Priority_from_core
+ *
+ * DESCRIPTION:
+ *
+ * XXX
+ */
+
+RTEMS_INLINE_ROUTINE unsigned int _POSIX_Message_queue_Priority_from_core(
+ CORE_message_queue_Submit_types priority
+)
+{
+ /* absolute value without a library dependency */
+ return ((priority >= 0) ? priority : -priority);
+}
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/posix/inline/rtems/posix/mutex.inl b/cpukit/posix/inline/rtems/posix/mutex.inl
new file mode 100644
index 0000000000..cfe9df4b2f
--- /dev/null
+++ b/cpukit/posix/inline/rtems/posix/mutex.inl
@@ -0,0 +1,118 @@
+/**
+ * @file rtems/posix/mutex.inl
+ */
+
+/* rtems/posix/mutex.inl
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX mutex's.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_MUTEX_INL
+#define _RTEMS_POSIX_MUTEX_INL
+
+/*PAGE
+ *
+ * _POSIX_Mutex_Allocate
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Mutex_Control *_POSIX_Mutex_Allocate( void )
+{
+ return (POSIX_Mutex_Control *) _Objects_Allocate( &_POSIX_Mutex_Information );
+}
+
+/*PAGE
+ *
+ * _POSIX_Mutex_Free
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Free (
+ POSIX_Mutex_Control *the_mutex
+)
+{
+ _Objects_Free( &_POSIX_Mutex_Information, &the_mutex->Object );
+}
+
+/*PAGE
+ *
+ * _POSIX_Mutex_Get_support
+ *
+ * NOTE: The support macro makes it possible for both to use exactly
+ * the same code to check for NULL id pointer and
+ * PTHREAD_MUTEX_INITIALIZER without adding overhead.
+ */
+
+#define ___POSIX_Mutex_Get_support( _id, _location ) \
+ do { \
+ int _status; \
+ \
+ if ( !_id ) { \
+ *_location = OBJECTS_ERROR; \
+ return (POSIX_Mutex_Control *) 0; \
+ } \
+ \
+ if ( *_id == PTHREAD_MUTEX_INITIALIZER ) { \
+ /* \
+ * Do an "auto-create" here. \
+ */ \
+ \
+ _status = pthread_mutex_init( (pthread_mutex_t *)_id, 0 ); \
+ if ( _status ) { \
+ *_location = OBJECTS_ERROR; \
+ return (POSIX_Mutex_Control *) 0; \
+ } \
+ } \
+ } while (0)
+
+RTEMS_INLINE_ROUTINE POSIX_Mutex_Control *_POSIX_Mutex_Get (
+ pthread_mutex_t *mutex,
+ Objects_Locations *location
+)
+{
+ Objects_Id *id = (Objects_Id *)mutex;
+
+ ___POSIX_Mutex_Get_support( id, location );
+
+ return (POSIX_Mutex_Control *)
+ _Objects_Get( &_POSIX_Mutex_Information, *id, location );
+}
+
+RTEMS_INLINE_ROUTINE POSIX_Mutex_Control *_POSIX_Mutex_Get_interrupt_disable (
+ pthread_mutex_t *mutex,
+ Objects_Locations *location,
+ ISR_Level *level
+)
+{
+ Objects_Id *id = (Objects_Id *)mutex;
+
+ ___POSIX_Mutex_Get_support( id, location );
+
+ return (POSIX_Mutex_Control *)
+ _Objects_Get_isr_disable( &_POSIX_Mutex_Information, *id, location, level );
+}
+
+
+/*PAGE
+ *
+ * _POSIX_Mutex_Is_null
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Mutex_Is_null (
+ POSIX_Mutex_Control *the_mutex
+)
+{
+ return !the_mutex;
+}
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/posix/inline/rtems/posix/priority.inl b/cpukit/posix/inline/rtems/posix/priority.inl
new file mode 100644
index 0000000000..3e4f798676
--- /dev/null
+++ b/cpukit/posix/inline/rtems/posix/priority.inl
@@ -0,0 +1,41 @@
+/**
+ * @file rtems/posix/priority.inl
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_PRIORITY_INL
+#define _RTEMS_POSIX_PRIORITY_INL
+
+/*
+ * 1003.1b-1993,2.2.2.80 definition of priority, p. 19
+ *
+ * "Numericallly higher values represent higher priorities."
+ *
+ * Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Priority_Is_valid(
+ int priority
+)
+{
+ return (boolean) (priority >= 1 && priority <= 254);
+}
+
+RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Priority_To_core(
+ int priority
+)
+{
+ return (Priority_Control) (255 - priority);
+}
+
+RTEMS_INLINE_ROUTINE int _POSIX_Priority_From_core(
+ Priority_Control priority
+)
+{
+ return 255 - priority;
+}
+
+#endif
diff --git a/cpukit/posix/inline/rtems/posix/pthread.inl b/cpukit/posix/inline/rtems/posix/pthread.inl
new file mode 100644
index 0000000000..4c7edaba42
--- /dev/null
+++ b/cpukit/posix/inline/rtems/posix/pthread.inl
@@ -0,0 +1,73 @@
+/**
+ * @file rtems/posix/pthread.inl
+ */
+
+/* rtems/posix/pthread.inl
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX threads.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_PTHREAD_INL
+#define _RTEMS_POSIX_PTHREAD_INL
+
+/*PAGE
+ *
+ * _POSIX_Threads_Allocate
+ */
+
+RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate( void )
+{
+ return (Thread_Control *) _Objects_Allocate( &_POSIX_Threads_Information );
+}
+
+/*PAGE
+ *
+ * _POSIX_Threads_Free
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Free (
+ Thread_Control *the_pthread
+)
+{
+ _Objects_Free( &_POSIX_Threads_Information, &the_pthread->Object );
+}
+
+/*PAGE
+ *
+ * _POSIX_Threads_Get
+ */
+
+RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Get (
+ pthread_t id,
+ Objects_Locations *location
+)
+{
+ return (Thread_Control *)
+ _Objects_Get( &_POSIX_Threads_Information, (Objects_Id)id, location );
+}
+
+/*PAGE
+ *
+ * _POSIX_Threads_Is_null
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Threads_Is_null (
+ Thread_Control *the_pthread
+)
+{
+ return !the_pthread;
+}
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/posix/inline/rtems/posix/semaphore.inl b/cpukit/posix/inline/rtems/posix/semaphore.inl
new file mode 100644
index 0000000000..6369d6f09c
--- /dev/null
+++ b/cpukit/posix/inline/rtems/posix/semaphore.inl
@@ -0,0 +1,89 @@
+/**
+ * @file rtems/posix/semaphore.inl
+ */
+
+/* rtems/posix/semaphore.inl
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX Semaphores.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_SEMAPHORE_INL
+#define _RTEMS_POSIX_SEMAPHORE_INL
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Allocate
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Allocate( void )
+{
+ return (POSIX_Semaphore_Control *)
+ _Objects_Allocate( &_POSIX_Semaphore_Information );
+}
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Free
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free (
+ POSIX_Semaphore_Control *the_semaphore
+)
+{
+ _Objects_Free( &_POSIX_Semaphore_Information, &the_semaphore->Object );
+}
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Namespace_remove
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Namespace_remove (
+ POSIX_Semaphore_Control *the_semaphore
+)
+{
+ _Objects_Namespace_remove(
+ &_POSIX_Semaphore_Information, &the_semaphore->Object );
+}
+
+
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Get
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get (
+ sem_t *id,
+ Objects_Locations *location
+)
+{
+ return (POSIX_Semaphore_Control *)
+ _Objects_Get( &_POSIX_Semaphore_Information, *id, location );
+}
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Is_null
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Semaphore_Is_null (
+ POSIX_Semaphore_Control *the_semaphore
+)
+{
+ return !the_semaphore;
+}
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/posix/inline/rtems/posix/timer.inl b/cpukit/posix/inline/rtems/posix/timer.inl
new file mode 100644
index 0000000000..3b07bdad27
--- /dev/null
+++ b/cpukit/posix/inline/rtems/posix/timer.inl
@@ -0,0 +1,94 @@
+/**
+ * @file rtems/posix/timer.inl
+ */
+
+/* timer.inl
+ *
+ * This file contains the static inline implementation of the inlined routines
+ * from the POSIX Timer Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_TIMER_INL
+#define _RTEMS_POSIX_TIMER_INL
+
+/*PAGE
+ *
+ * _POSIX_Timer_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a timer control block from
+ * the inactive chain of free timer control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Timer_Control *_POSIX_Timer_Allocate( void )
+{
+ return (POSIX_Timer_Control *) _Objects_Allocate( &_POSIX_Timer_Information );
+}
+
+/*PAGE
+ *
+ * _POSIX_Timer_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a timer control block to the
+ * inactive chain of free timer control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Timer_Free (
+ POSIX_Timer_Control *the_timer
+)
+{
+ _Objects_Free( &_POSIX_Timer_Information, &the_timer->Object );
+}
+
+/*PAGE
+ *
+ * _POSIX_Timer_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps timer IDs to timer control blocks.
+ * If ID corresponds to a local timer, then it returns
+ * the timer control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. Otherwise, location is set
+ * to OBJECTS_ERROR and the returned value is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Timer_Control *_POSIX_Timer_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (POSIX_Timer_Control *)
+ _Objects_Get( &_POSIX_Timer_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _POSIX_Timer_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_timer is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _POSIX_Timer_Is_null (
+ POSIX_Timer_Control *the_timer
+)
+{
+ return (the_timer == NULL);
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/macros/rtems/posix/cond.inl b/cpukit/posix/macros/rtems/posix/cond.inl
new file mode 100644
index 0000000000..bb694976ab
--- /dev/null
+++ b/cpukit/posix/macros/rtems/posix/cond.inl
@@ -0,0 +1,104 @@
+/**
+ * @file rtems/posix/cond.inl
+ */
+
+/* rtems/posix/cond.inl
+ *
+ * This include file contains the macro implementation of the private
+ * inlined routines for POSIX condition variables.
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_COND_INL
+#define _RTEMS_POSIX_COND_INL
+
+#include <pthread.h>
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Allocate
+ */
+
+#define _POSIX_Condition_variables_Allocate() \
+ (POSIX_Condition_variables_Control *) \
+ _Objects_Allocate( &_POSIX_Condition_variables_Information )
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Free
+ *
+ * NOTE: The support macro makes it possible for both to use exactly
+ * the same code to check for NULL id pointer and
+ * PTHREAD_COND_INITIALIZER without adding overhead.
+ */
+
+#define _POSIX_Condition_variables_Free( _the_condition_variable ) \
+ _Objects_Free( &_POSIX_Condition_variables_Information, \
+ &(_the_condition_variable)->Object)
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Get
+ *
+ * NOTE: The support macro makes it possible for both to use exactly
+ * the same code to check for NULL id pointer and
+ * PTHREAD_COND_INITIALIZER without adding overhead.
+ */
+
+#define ___POSIX_Condition_variables_Get_support( _cond, _location ) \
+ do { \
+ Objects_Id *_id = (Objects_Id *)_cond; \
+ int _status; \
+ \
+ if ( !_id ) { \
+ *_location = OBJECTS_ERROR; \
+ return (POSIX_Condition_variables_Control *) 0; \
+ } \
+ \
+ if ( *_id == PTHREAD_COND_INITIALIZER ) { \
+ /* \
+ * Do an "auto-create" here. \
+ */ \
+ \
+ _status = pthread_cond_init( (pthread_cond_t *)_id, 0 ); \
+ if ( _status ) { \
+ *_location = OBJECTS_ERROR; \
+ return (POSIX_Condition_variables_Control *) 0; \
+ } \
+ } \
+ } while (0)
+
+
+/* If we find a compiler that doesn't accept static inline functions,
+ * then this will have to move to a .c file. Until then, we will use this.
+ */
+static inline POSIX_Condition_variables_Control *_POSIX_Condition_variables_Get (
+ pthread_cond_t *cond,
+ Objects_Locations *location
+)
+{
+ Objects_Id *id = (Objects_Id *)cond;
+ ___POSIX_Condition_variables_Get_support( id, location );
+
+ return (POSIX_Condition_variables_Control *)
+ _Objects_Get( &_POSIX_Condition_variables_Information, *id, location );
+}
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Is_null
+ */
+
+#define _POSIX_Condition_variables_Is_null( _the_condition_variable ) \
+ (!(_the_condition_variable))
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/macros/rtems/posix/key.inl b/cpukit/posix/macros/rtems/posix/key.inl
new file mode 100644
index 0000000000..2c41e4b9d9
--- /dev/null
+++ b/cpukit/posix/macros/rtems/posix/key.inl
@@ -0,0 +1,58 @@
+/**
+ * @file rtems/posix/key.inl
+ */
+
+/* rtems/posix/key.inl
+ *
+ * This include file contains the macro implementation of the private
+ * inlined routines for POSIX key's.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_KEY_INL
+#define _RTEMS_POSIX_KEY_INL
+
+/*PAGE
+ *
+ * _POSIX_Keys_Allocate
+ */
+
+#define _POSIX_Keys_Allocate() \
+ (POSIX_Keys_Control *) _Objects_Allocate( &_POSIX_Keys_Information )
+
+/*PAGE
+ *
+ * _POSIX_Keys_Free
+ */
+
+#define _POSIX_Keys_Free( _the_key ) \
+ _Objects_Free( &_POSIX_Keys_Information, &(_the_key)->Object );
+
+/*PAGE
+ *
+ * _POSIX_Keys_Get
+ */
+
+#define _POSIX_Keys_Get( _id, _location ) \
+ (POSIX_Keys_Control *) \
+ _Objects_Get( &_POSIX_Keys_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _POSIX_Keys_Is_null
+ */
+
+#define _POSIX_Keys_Is_null( _the_key ) \
+ (!(_the_key))
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/posix/macros/rtems/posix/mqueue.inl b/cpukit/posix/macros/rtems/posix/mqueue.inl
new file mode 100644
index 0000000000..f996688541
--- /dev/null
+++ b/cpukit/posix/macros/rtems/posix/mqueue.inl
@@ -0,0 +1,105 @@
+/**
+ * @file rtems/posix/mqueue.inl
+ */
+
+/* rtems/posix/mqueue.inl
+ *
+ * This include file contains the macro implementation of the private
+ * inlined routines for POSIX Message 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_MQUEUE_INL
+#define _RTEMS_POSIX_MQUEUE_INL
+
+/*
+ * _POSIX_Message_queue_Allocate
+ */
+
+#define _POSIX_Message_queue_Allocate() \
+ (POSIX_Message_queue_Control *) \
+ _Objects_Allocate( &_POSIX_Message_queue_Information )
+
+/*
+ * _POSIX_Message_queue_Allocate_fd
+ */
+
+#define _POSIX_Message_queue_Allocate_fd() \
+ (POSIX_Message_queue_Control_fd *) \
+ _Objects_Allocate( &_POSIX_Message_queue_Information_fds )
+
+/*
+ * _POSIX_Message_queue_Free
+ */
+
+#define _POSIX_Message_queue_Free( _the_mq ) \
+ _Objects_Free( &_POSIX_Message_queue_Information, &(_the_mq)->Object )
+
+/*
+ * _POSIX_Message_queue_Free_fd
+ */
+
+#define _POSIX_Message_queue_Free_fd( _the_mq_fd ) \
+ _Objects_Free( &_POSIX_Message_queue_Information_fds, &(_the_mq_fd)->Object )
+
+/*
+ * _POSIX_Message_queue_Namespace_remove
+ */
+
+#define _POSIX_Message_queue_Namespace_remove( _the_mq ) \
+ _Objects_Namespace_remove( \
+ &_POSIX_Message_queue_Information, &(_the_mq)->Object )
+
+/*
+ * _POSIX_Message_queue_Get
+ */
+
+#define _POSIX_Message_queue_Get( _id, _location ) \
+ (POSIX_Message_queue_Control *) \
+ _Objects_Get( &_POSIX_Message_queue_Information, (_id), (_location) )
+
+/*
+ * _POSIX_Message_queue_Get_fd
+ */
+
+#define _POSIX_Message_queue_Get_fd( _id, _location ) \
+ (POSIX_Message_queue_Control_fd *) \
+ _Objects_Get( &_POSIX_Message_queue_Information_fds, (_id), (_location) )
+
+/*
+ *
+ * _POSIX_Message_queue_Is_null
+ */
+
+#define _POSIX_Message_queue_Is_null( _the_mq ) \
+ (!(_the_mq))
+
+/*
+ *
+ * _POSIX_Message_queue_Priority_to_core
+ */
+
+#define _POSIX_Message_queue_Priority_to_core( _priority ) \
+ ((_priority) * -1)
+
+/*
+ * _POSIX_Message_queue_Priority_from_core
+ */
+
+/* absolute value without a library dependency */
+#define _POSIX_Message_queue_Priority_from_core( _priority ) \
+ ((((CORE_message_queue_Submit_types)(_priority)) >= 0) ? \
+ (_priority) : \
+ -((CORE_message_queue_Submit_types)(_priority)))
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/posix/macros/rtems/posix/mutex.inl b/cpukit/posix/macros/rtems/posix/mutex.inl
new file mode 100644
index 0000000000..5d8968f4b2
--- /dev/null
+++ b/cpukit/posix/macros/rtems/posix/mutex.inl
@@ -0,0 +1,111 @@
+/**
+ * @file rtems/posix/mutex.inl
+ */
+
+/* rtems/posix/mutex.inl
+ *
+ * This include file contains the macro implementation of the private
+ * inlined routines for POSIX mutex's.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_MUTEX_INL
+#define _RTEMS_POSIX_MUTEX_INL
+
+/*PAGE
+ *
+ * _POSIX_Mutex_Allocate
+ */
+
+#define _POSIX_Mutex_Allocate() \
+ (POSIX_Mutex_Control *) _Objects_Allocate( &_POSIX_Mutex_Information )
+
+/*PAGE
+ *
+ * _POSIX_Mutex_Free
+ */
+
+#define _POSIX_Mutex_Free( _the_mutex ) \
+ _Objects_Free( &_POSIX_Mutex_Information, &(_the_mutex)->Object )
+
+/*PAGE
+ *
+ * _POSIX_Mutex_Get
+ *
+ * NOTE: The support macro makes it possible for both to use exactly
+ * the same code to check for NULL id pointer and
+ * PTHREAD_MUTEX_INITIALIZER without adding overhead.
+ */
+
+#define ___POSIX_Mutex_Get_support( _mutex, _location ) \
+ do { \
+ int _status; \
+ Objects_Id *_id = (Objects_Id *) _mutex; \
+ \
+ if ( !_id ) { \
+ *_location = OBJECTS_ERROR; \
+ return (POSIX_Mutex_Control *) 0; \
+ } \
+ \
+ if ( *_id == PTHREAD_MUTEX_INITIALIZER ) { \
+ /* \
+ * Do an "auto-create" here. \
+ */ \
+ \
+ _status = pthread_mutex_init( (pthread_mutex_t *)_id, 0 ); \
+ if ( _status ) { \
+ *_location = OBJECTS_ERROR; \
+ return (POSIX_Mutex_Control *) 0; \
+ } \
+ } \
+ } while (0)
+
+/* If we find a compiler that doesn't accept static inline functions,
+ * then this will have to move to a .c file. Until then, we will use this.
+ */
+static inline POSIX_Mutex_Control * _POSIX_Mutex_Get(
+ pthread_mutex_t *id,
+ Objects_Locations *location
+)
+{
+ ___POSIX_Mutex_Get_support( id, location );
+
+ return (POSIX_Mutex_Control *)
+ _Objects_Get( &_POSIX_Mutex_Information, *id, location );
+}
+
+/* If we find a compiler that doesn't accept static inline functions,
+ * then this will have to move to a .c file. Until then, we will use this.
+ */
+static inline POSIX_Mutex_Control *_POSIX_Mutex_Get_interrupt_disable(
+ pthread_mutex_t *id,
+ Objects_Locations *location,
+ ISR_Level *level
+)
+{
+ ___POSIX_Mutex_Get_support( id, location );
+
+ return (POSIX_Mutex_Control *)
+ _Objects_Get_isr_disable( &_POSIX_Mutex_Information, *id, location, level );
+}
+
+
+/*PAGE
+ *
+ * _POSIX_Mutex_Is_null
+ */
+
+#define _POSIX_Mutex_Is_null( _the_mutex ) \
+ (!(_the_mutex))
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/posix/macros/rtems/posix/priority.inl b/cpukit/posix/macros/rtems/posix/priority.inl
new file mode 100644
index 0000000000..350db8b00e
--- /dev/null
+++ b/cpukit/posix/macros/rtems/posix/priority.inl
@@ -0,0 +1,29 @@
+/**
+ * @file rtems/posix/priority.inl
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_PRIORITY_INL
+#define _RTEMS_POSIX_PRIORITY_INL
+
+/*
+ * 1003.1b-1993,2.2.2.80 definition of priority, p. 19
+ *
+ * "Numericallly higher values represent higher priorities."
+ *
+ * Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API.
+ */
+
+#define _POSIX_Priority_Is_valid( _priority ) \
+ ((boolean) ((_priority) >= 1 && (_priority) <= 254))
+
+#define _POSIX_Priority_To_core( _priority ) \
+ ((Priority_Control) (255 - (_priority)))
+
+#define _POSIX_Priority_From_core( _priority ) \
+ (255 - (_priority))
+
+#endif
diff --git a/cpukit/posix/macros/rtems/posix/pthread.inl b/cpukit/posix/macros/rtems/posix/pthread.inl
new file mode 100644
index 0000000000..f260c3d19a
--- /dev/null
+++ b/cpukit/posix/macros/rtems/posix/pthread.inl
@@ -0,0 +1,58 @@
+/**
+ * @file rtems/posix/pthread.inl
+ */
+
+/* rtems/posix/pthread.inl
+ *
+ * This include file contains the macro implementation of the private
+ * inlined routines for POSIX threads.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_PTHREAD_INL
+#define _RTEMS_POSIX_PTHREAD_INL
+
+/*PAGE
+ *
+ * _POSIX_Threads_Allocate
+ */
+
+#define _POSIX_Threads_Allocate() \
+ (Thread_Control *) _Objects_Allocate( &_POSIX_Threads_Information )
+
+/*PAGE
+ *
+ * _POSIX_Threads_Free
+ */
+
+#define _POSIX_Threads_Free( _the_pthread ) \
+ _Objects_Free( &_POSIX_Threads_Information, &(_the_pthread)->Object )
+
+/*PAGE
+ *
+ * _POSIX_Threads_Get
+ */
+
+#define _POSIX_Threads_Get( _id, _location ) \
+ (Thread_Control *) \
+ _Objects_Get( &_POSIX_Threads_Information, (Objects_Id)(_id), (_location) )
+
+/*PAGE
+ *
+ * _POSIX_Threads_Is_null
+ */
+
+#define _POSIX_Threads_Is_null( _the_pthread ) \
+ (!(_the_pthread))
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/posix/macros/rtems/posix/semaphore.inl b/cpukit/posix/macros/rtems/posix/semaphore.inl
new file mode 100644
index 0000000000..757816263a
--- /dev/null
+++ b/cpukit/posix/macros/rtems/posix/semaphore.inl
@@ -0,0 +1,68 @@
+/**
+ * @file rtems/posix/semaphore.inl
+ */
+
+/* rtems/posix/semaphore.inl
+ *
+ * This include file contains the macro implementation of the private
+ * inlined routines for POSIX Semaphores.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_SEMAPHORE_INL
+#define _RTEMS_POSIX_SEMAPHORE_INL
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Allocate
+ */
+
+#define _POSIX_Semaphore_Allocate() \
+ (POSIX_Semaphore_Control *) \
+ _Objects_Allocate( &_POSIX_Semaphore_Information );
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Free
+ */
+
+#define _POSIX_Semaphore_Free( _the_semaphore ) \
+ _Objects_Free( &_POSIX_Semaphore_Information, &(_the_semaphore)->Object )
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Namespace_remove
+ */
+
+#define _POSIX_Semaphore_Namespace_remove( _the_semaphore ) \
+ _Objects_Namespace_remove( \
+ &_POSIX_Semaphore_Information, &(_the_semaphore)->Object )
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Get
+ */
+
+#define _POSIX_Semaphore_Get( _id, _location ) \
+ (POSIX_Semaphore_Control *) \
+ _Objects_Get( &_POSIX_Semaphore_Information, *(_id), (_location) )
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Is_null
+ */
+
+#define _POSIX_Semaphore_Is_null( _the_semaphore ) \
+ (!(_the_semaphore))
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/posix/macros/rtems/posix/timer.inl b/cpukit/posix/macros/rtems/posix/timer.inl
new file mode 100644
index 0000000000..7e7ad76c00
--- /dev/null
+++ b/cpukit/posix/macros/rtems/posix/timer.inl
@@ -0,0 +1,57 @@
+/**
+ * @file rtems/posix/timer.inl
+ */
+
+/* timer.inl
+ *
+ * This file contains the macro implementation of the inlined routines
+ * from the POSIX Timer Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POSIX_TIMER_INL
+#define _RTEMS_POSIX_TIMER_INL
+
+/*PAGE
+ *
+ * _POSIX_Timer_Allocate
+ */
+
+#define _POSIX_Timer_Allocate() \
+ (POSIX_Timer_Control *) _Objects_Allocate( &_POSIX_Timer_Information )
+
+/*PAGE
+ *
+ * _POSIX_Timer_Free
+ */
+
+#define _POSIX_Timer_Free( _the_timer ) \
+ _Objects_Free( &_POSIX_Timer_Information, &(_the_timer)->Object );
+
+/*PAGE
+ *
+ * _POSIX_Timer_Get
+ */
+
+#define _POSIX_Timer_Get( _id, _location ) \
+ (POSIX_Timer_Control *) \
+ _Objects_Get( &_POSIX_Timer_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _POSIX_Timer_Is_null
+ */
+
+#define _POSIX_Timer_Is_null( _the_timer ) \
+ (!(_the_timer))
+
+#endif
+/* end of include file */
diff --git a/cpukit/posix/preinstall.am b/cpukit/posix/preinstall.am
new file mode 100644
index 0000000000..b636f38a3f
--- /dev/null
+++ b/cpukit/posix/preinstall.am
@@ -0,0 +1,190 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)
+ @: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
+
+if HAS_POSIX
+$(PROJECT_INCLUDE)/sched.h: include/sched.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sched.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sched.h
+
+$(PROJECT_INCLUDE)/aio.h: include/aio.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/aio.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/aio.h
+
+$(PROJECT_INCLUDE)/mqueue.h: include/mqueue.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mqueue.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/mqueue.h
+
+$(PROJECT_INCLUDE)/semaphore.h: include/semaphore.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/semaphore.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/semaphore.h
+
+$(PROJECT_INCLUDE)/devctl.h: include/devctl.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/devctl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/devctl.h
+
+$(PROJECT_INCLUDE)/rtems/posix/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/posix
+ @: > $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/posix/cancel.h: include/rtems/posix/cancel.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cancel.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cancel.h
+
+$(PROJECT_INCLUDE)/rtems/posix/cond.h: include/rtems/posix/cond.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cond.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cond.h
+
+$(PROJECT_INCLUDE)/rtems/posix/config.h: include/rtems/posix/config.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/config.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/config.h
+
+$(PROJECT_INCLUDE)/rtems/posix/key.h: include/rtems/posix/key.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/key.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/key.h
+
+$(PROJECT_INCLUDE)/rtems/posix/mqueue.h: include/rtems/posix/mqueue.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mqueue.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mqueue.h
+
+$(PROJECT_INCLUDE)/rtems/posix/mutex.h: include/rtems/posix/mutex.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mutex.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mutex.h
+
+$(PROJECT_INCLUDE)/rtems/posix/posixapi.h: include/rtems/posix/posixapi.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/posixapi.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/posixapi.h
+
+$(PROJECT_INCLUDE)/rtems/posix/priority.h: include/rtems/posix/priority.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/priority.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/priority.h
+
+$(PROJECT_INCLUDE)/rtems/posix/psignal.h: include/rtems/posix/psignal.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/psignal.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/psignal.h
+
+$(PROJECT_INCLUDE)/rtems/posix/pthread.h: include/rtems/posix/pthread.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/pthread.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/pthread.h
+
+$(PROJECT_INCLUDE)/rtems/posix/semaphore.h: include/rtems/posix/semaphore.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
+
+$(PROJECT_INCLUDE)/rtems/posix/threadsup.h: include/rtems/posix/threadsup.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/threadsup.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/threadsup.h
+
+$(PROJECT_INCLUDE)/rtems/posix/time.h: include/rtems/posix/time.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/time.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/time.h
+
+$(PROJECT_INCLUDE)/rtems/posix/timer.h: include/rtems/posix/timer.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/timer.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/timer.h
+
+if HAS_MP
+$(PROJECT_INCLUDE)/rtems/posix/condmp.h: include/rtems/posix/condmp.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/condmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/condmp.h
+
+$(PROJECT_INCLUDE)/rtems/posix/mqueuemp.h: include/rtems/posix/mqueuemp.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mqueuemp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mqueuemp.h
+
+$(PROJECT_INCLUDE)/rtems/posix/mutexmp.h: include/rtems/posix/mutexmp.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mutexmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mutexmp.h
+
+$(PROJECT_INCLUDE)/rtems/posix/pthreadmp.h: include/rtems/posix/pthreadmp.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/pthreadmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/pthreadmp.h
+
+$(PROJECT_INCLUDE)/rtems/posix/semaphoremp.h: include/rtems/posix/semaphoremp.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphoremp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphoremp.h
+endif
+if INLINE
+$(PROJECT_INCLUDE)/rtems/posix/cond.inl: inline/rtems/posix/cond.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cond.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cond.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/key.inl: inline/rtems/posix/key.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/key.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/key.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/mqueue.inl: inline/rtems/posix/mqueue.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mqueue.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mqueue.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/mutex.inl: inline/rtems/posix/mutex.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mutex.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mutex.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/pthread.inl: inline/rtems/posix/pthread.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/pthread.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/pthread.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/priority.inl: inline/rtems/posix/priority.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/priority.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/priority.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/semaphore.inl: inline/rtems/posix/semaphore.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphore.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphore.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/timer.inl: inline/rtems/posix/timer.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/timer.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/timer.inl
+
+else
+$(PROJECT_INCLUDE)/rtems/posix/cond.inl: macros/rtems/posix/cond.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cond.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cond.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/key.inl: macros/rtems/posix/key.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/key.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/key.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/mqueue.inl: macros/rtems/posix/mqueue.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mqueue.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mqueue.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/mutex.inl: macros/rtems/posix/mutex.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mutex.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mutex.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/pthread.inl: macros/rtems/posix/pthread.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/pthread.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/pthread.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/priority.inl: macros/rtems/posix/priority.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/priority.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/priority.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/semaphore.inl: macros/rtems/posix/semaphore.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphore.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphore.inl
+
+$(PROJECT_INCLUDE)/rtems/posix/timer.inl: macros/rtems/posix/timer.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/timer.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/timer.inl
+endif
+endif
diff --git a/cpukit/posix/src/.cvsignore b/cpukit/posix/src/.cvsignore
new file mode 100644
index 0000000000..000074c626
--- /dev/null
+++ b/cpukit/posix/src/.cvsignore
@@ -0,0 +1,4 @@
+stamp-h
+stamp-h.in
+config.h
+config.h.in
diff --git a/cpukit/posix/src/README.mqueue b/cpukit/posix/src/README.mqueue
new file mode 100644
index 0000000000..12c8afc03e
--- /dev/null
+++ b/cpukit/posix/src/README.mqueue
@@ -0,0 +1,38 @@
+#
+# $Id$
+#
+
+This program should print out the default attribute settings for a
+POSIX message queue.
+
+#include <mqueue.h>
+#include <stdio.h>
+
+main()
+{
+ mqd_t mqfd;
+ struct mq_attr mqstat;
+ int status;
+
+ /* this should create it */
+ mqfd = mq_open("myipc",O_WRONLY|O_CREAT,NULL);
+ if ( (int)mqfd == -1 ) {
+ perror( "Unable to open message queue" );
+ exit( 1 );
+ }
+
+ status = mq_getattr(mqfd, &mqstat);
+ if ( !status ) {
+ printf( "mq_maxmsg: %d\n", mqstat.mq_maxmsg );
+ printf( "mq_msgsize: %d\n", mqstat.mq_msgsize );
+ printf( "mq_curmsgs: %d\n", mqstat.mq_curmsgs );
+ } else {
+ perror( "Unable to get attributes on message queue" );
+ exit( 1 );
+ }
+
+ /* this should delete it */
+ (void) mq_close( mqfd );
+ exit( 0 );
+}
+
diff --git a/cpukit/posix/src/adasupp.c b/cpukit/posix/src/adasupp.c
new file mode 100644
index 0000000000..535ff669c2
--- /dev/null
+++ b/cpukit/posix/src/adasupp.c
@@ -0,0 +1,32 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+
+/*PAGE
+ *
+ * _ada_pthread_minimum_stack_size
+ *
+ * This routine returns the minimum stack size so the GNAT RTS can
+ * allocate enough stack for Ada tasks.
+ */
+
+size_t _ada_pthread_minimum_stack_size( void )
+{
+ /*
+ * Eventually this may need to include a per cpu family calculation
+ * but for now, this will do.
+ */
+
+ return PTHREAD_MINIMUM_STACK_SIZE * 2;
+}
diff --git a/cpukit/posix/src/adjtime.c b/cpukit/posix/src/adjtime.c
new file mode 100644
index 0000000000..1e06dab608
--- /dev/null
+++ b/cpukit/posix/src/adjtime.c
@@ -0,0 +1,60 @@
+/*
+ * adjustime() function - required by NTP
+ *
+ * I am unaware of the history behind the definition of this service
+ * and don't know if its behavior is covered by any standard. --joel
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <time.h>
+#include <sys/time.h>
+
+#include <rtems/system.h>
+#include <rtems/score/tod.h>
+#include <rtems/posix/time.h>
+
+static long __adjustment = 0;
+
+int adjtime ( struct timeval *delta, struct timeval *olddelta )
+{
+ struct timespec ts;
+
+ if ( olddelta ) {
+ olddelta->tv_sec = __adjustment / TOD_MICROSECONDS_PER_SECOND;
+ olddelta->tv_usec = __adjustment / TOD_MICROSECONDS_PER_SECOND;
+ }
+
+ if ( !delta )
+ return -1;
+
+ __adjustment = (delta->tv_sec * TOD_MICROSECONDS_PER_SECOND) + delta->tv_usec;
+ /* too small to account for */
+ if ( __adjustment < _TOD_Microseconds_per_tick )
+ return 0;
+
+ clock_gettime( CLOCK_REALTIME, &ts );
+
+ ts.tv_sec += (__adjustment / TOD_MICROSECONDS_PER_SECOND);
+ ts.tv_nsec += (__adjustment % TOD_MICROSECONDS_PER_SECOND) *
+ TOD_NANOSECONDS_PER_MICROSECOND;
+
+ /* if adjustment is too much positive */
+ while ( ts.tv_nsec >= TOD_NANOSECONDS_PER_SECOND ) {
+ ts.tv_nsec -= TOD_NANOSECONDS_PER_SECOND;
+ ts.tv_sec++;
+ }
+
+ /* if adjustment is too much negative */
+ while ( ts.tv_nsec <= (-1 * TOD_NANOSECONDS_PER_SECOND) ) {
+ ts.tv_nsec += TOD_NANOSECONDS_PER_SECOND;
+ ts.tv_sec--;
+ }
+
+ clock_settime( CLOCK_REALTIME, &ts );
+ return 0;
+}
diff --git a/cpukit/posix/src/aio.c b/cpukit/posix/src/aio.c
new file mode 100644
index 0000000000..f993a5f2d5
--- /dev/null
+++ b/cpukit/posix/src/aio.c
@@ -0,0 +1,118 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <aio.h>
+
+#include <rtems/system.h>
+#include <rtems/seterr.h>
+
+int POSIX_NOT_IMPLEMENTED();
+
+/*PAGE
+ *
+ * 6.7.2 Asynchronous Read, P1003.1b-1993, p. 154
+ */
+
+int aio_read(
+ struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.3 Asynchronous Write, P1003.1b-1993, p. 155
+ */
+
+int aio_write(
+ struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.4 List Directed I/O, P1003.1b-1993, p. 158
+ */
+
+int lio_listio(
+ int mode,
+ struct aiocb * const list[],
+ int nent,
+ struct sigevent *sig
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.5 Retrieve Error of Asynchronous I/O Operation, P1003.1b-1993, p. 161
+ */
+
+int aio_error(
+ const struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.6 Retrieve Return Status of Asynchronous I/O Operation,
+ * P1003.1b-1993, p. 162
+ */
+
+int aio_return(
+ const struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.7 Cancel Asynchronous I/O Operation, P1003.1b-1993, p. 163
+ */
+
+int aio_cancel(
+ int filedes,
+ struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.7 Wait for Asynchronous I/O Request, P1003.1b-1993, p. 164
+ */
+
+int aio_suspend(
+ struct aiocb * const list[],
+ int nent,
+ const struct timespec *timeout
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.9 Asynchronous File Synchronization, P1003.1b-1993, p. 166
+ */
+
+int aio_fsync(
+ int op,
+ struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
diff --git a/cpukit/posix/src/alarm.c b/cpukit/posix/src/alarm.c
new file mode 100644
index 0000000000..c061b97e48
--- /dev/null
+++ b/cpukit/posix/src/alarm.c
@@ -0,0 +1,82 @@
+/*
+ * 3.4.1 Schedule Alarm, P1003.1b-1993, p. 79
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+/* #include <errno.h> */
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+
+Watchdog_Control _POSIX_signals_Alarm_timer;
+
+/*PAGE
+ *
+ * _POSIX_signals_Alarm_TSR
+ */
+
+void _POSIX_signals_Alarm_TSR(
+ Objects_Id id,
+ void *argument
+)
+{
+ int status;
+
+ status = kill( getpid(), SIGALRM );
+ /* XXX can't print from an ISR, should this be fatal? */
+}
+
+unsigned int alarm(
+ unsigned int seconds
+)
+{
+ unsigned int remaining = 0;
+ Watchdog_Control *the_timer;
+
+ the_timer = &_POSIX_signals_Alarm_timer;
+
+ /*
+ * Initialize the timer used to implement alarm().
+ */
+
+ if ( !the_timer->routine ) {
+ _Watchdog_Initialize( the_timer, _POSIX_signals_Alarm_TSR, 0, NULL );
+ } else {
+ switch ( _Watchdog_Remove( the_timer ) ) {
+ case WATCHDOG_INACTIVE:
+ case WATCHDOG_BEING_INSERTED:
+ break;
+
+ case WATCHDOG_ACTIVE:
+ case WATCHDOG_REMOVE_IT:
+ /*
+ * The stop_time and start_time fields are snapshots of ticks since
+ * boot. Since alarm() is dealing in seconds, we must account for
+ * this.
+ */
+
+ remaining = the_timer->initial -
+ ((the_timer->stop_time - the_timer->start_time) /
+ _TOD_Ticks_per_second);
+ break;
+ }
+ }
+
+ _Watchdog_Insert_seconds( the_timer, seconds );
+
+ return remaining;
+}
diff --git a/cpukit/posix/src/cancel.c b/cpukit/posix/src/cancel.c
new file mode 100644
index 0000000000..2b72be4aef
--- /dev/null
+++ b/cpukit/posix/src/cancel.c
@@ -0,0 +1,62 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/cancel.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/threadsup.h>
+
+/*PAGE
+ *
+ * 18.2.1 Canceling Execution of a Thread, P1003.1c/Draft 10, p. 181
+ */
+
+int pthread_cancel(
+ pthread_t thread
+)
+{
+ Thread_Control *the_thread;
+ POSIX_API_Control *thread_support;
+ Objects_Locations location;
+
+ /*
+ * Don't even think about deleting a resource from an ISR.
+ */
+
+ if ( _ISR_Is_in_progress() )
+ return EPROTO;
+
+ the_thread = _POSIX_Threads_Get( thread, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ return POSIX_MP_NOT_IMPLEMENTED();
+ case OBJECTS_LOCAL:
+ thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ thread_support->cancelation_requested = 1;
+
+ if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
+ thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS ) {
+ _POSIX_Threads_cancel_run( the_thread );
+ }
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/cancelrun.c b/cpukit/posix/src/cancelrun.c
new file mode 100644
index 0000000000..17fa55bdc6
--- /dev/null
+++ b/cpukit/posix/src/cancelrun.c
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/cancel.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/threadsup.h>
+
+/*PAGE
+ *
+ * _POSIX_Threads_cancel_run
+ *
+ */
+
+void _POSIX_Threads_cancel_run(
+ Thread_Control *the_thread
+)
+{
+ POSIX_Cancel_Handler_control *handler;
+ Chain_Control *handler_stack;
+ POSIX_API_Control *thread_support;
+ ISR_Level level;
+
+ thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ handler_stack = &thread_support->Cancellation_Handlers;
+
+ thread_support->cancelability_state = PTHREAD_CANCEL_DISABLE;
+
+ while ( !_Chain_Is_empty( handler_stack ) ) {
+ _ISR_Disable( level );
+ handler = (POSIX_Cancel_Handler_control *)
+ _Chain_Tail( handler_stack )->previous;
+ _Chain_Extract_unprotected( &handler->Node );
+ _ISR_Enable( level );
+
+ (*handler->routine)( handler->arg );
+
+ _Workspace_Free( handler );
+ }
+
+ /* Now we can delete the thread */
+
+ the_thread->Wait.return_argument = PTHREAD_CANCELED;
+ _Thread_Close(
+ _Objects_Get_information( the_thread->Object.id ),
+ the_thread
+ );
+ _POSIX_Threads_Free( the_thread );
+
+}
diff --git a/cpukit/posix/src/cleanuppop.c b/cpukit/posix/src/cleanuppop.c
new file mode 100644
index 0000000000..49c35dff41
--- /dev/null
+++ b/cpukit/posix/src/cleanuppop.c
@@ -0,0 +1,60 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/cancel.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/threadsup.h>
+
+/*PAGE
+ *
+ * 18.2.3.1 Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184
+ */
+
+void pthread_cleanup_pop(
+ int execute
+)
+{
+ POSIX_Cancel_Handler_control *handler;
+ POSIX_Cancel_Handler_control tmp_handler;
+ Chain_Control *handler_stack;
+ POSIX_API_Control *thread_support;
+ ISR_Level level;
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ handler_stack = &thread_support->Cancellation_Handlers;
+
+ _ISR_Disable( level );
+ if ( _Chain_Is_empty( handler_stack ) ) {
+ _ISR_Enable( level );
+ return;
+ }
+
+ handler = (POSIX_Cancel_Handler_control *)
+ _Chain_Tail( handler_stack )->previous;
+ _Chain_Extract_unprotected( &handler->Node );
+
+ _ISR_Enable( level );
+
+ tmp_handler = *handler;
+
+ _Thread_Disable_dispatch();
+ _Workspace_Free( handler );
+ _Thread_Enable_dispatch();
+
+ if ( execute )
+ (*tmp_handler.routine)( tmp_handler.arg );
+}
diff --git a/cpukit/posix/src/cleanuppush.c b/cpukit/posix/src/cleanuppush.c
new file mode 100644
index 0000000000..6efc7f9c45
--- /dev/null
+++ b/cpukit/posix/src/cleanuppush.c
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/cancel.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/threadsup.h>
+
+/*PAGE
+ *
+ * 18.2.3.1 Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184
+ */
+
+void pthread_cleanup_push(
+ void (*routine)( void * ),
+ void *arg
+)
+{
+ POSIX_Cancel_Handler_control *handler;
+ Chain_Control *handler_stack;
+ POSIX_API_Control *thread_support;
+
+ if ( !routine )
+ return; /* XXX what to do really? */
+
+ _Thread_Disable_dispatch();
+ handler = _Workspace_Allocate( sizeof( POSIX_Cancel_Handler_control ) );
+
+ if ( !handler ) {
+ _Thread_Enable_dispatch();
+ return; /* XXX what to do really? */
+ }
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ handler_stack = &thread_support->Cancellation_Handlers;
+
+ handler->routine = routine;
+ handler->arg = arg;
+
+ _Chain_Append( handler_stack, &handler->Node );
+
+ _Thread_Enable_dispatch();
+}
diff --git a/cpukit/posix/src/clockgetcpuclockid.c b/cpukit/posix/src/clockgetcpuclockid.c
new file mode 100644
index 0000000000..96e554c1f5
--- /dev/null
+++ b/cpukit/posix/src/clockgetcpuclockid.c
@@ -0,0 +1,32 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 20.1.3 Accessing a Process CPU-time CLock, P1003.4b/D8, p. 55
+ */
+
+int clock_getcpuclockid(
+ pid_t pid,
+ clockid_t *clock_id
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
diff --git a/cpukit/posix/src/clockgetenableattr.c b/cpukit/posix/src/clockgetenableattr.c
new file mode 100644
index 0000000000..0d3fbebfb4
--- /dev/null
+++ b/cpukit/posix/src/clockgetenableattr.c
@@ -0,0 +1,32 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58
+ */
+
+int clock_getenable_attr(
+ clockid_t clock_id,
+ int *attr
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
diff --git a/cpukit/posix/src/clockgetres.c b/cpukit/posix/src/clockgetres.c
new file mode 100644
index 0000000000..423759c8d8
--- /dev/null
+++ b/cpukit/posix/src/clockgetres.c
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 14.2.1 Clocks, P1003.1b-1993, p. 263
+ */
+
+int clock_getres(
+ clockid_t clock_id,
+ struct timespec *res
+)
+{
+ if ( !res )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ switch ( clock_id ) {
+
+ /*
+ * All time in rtems is based on the same clock tick.
+ */
+
+ case CLOCK_REALTIME:
+ case CLOCK_PROCESS_CPUTIME:
+ case CLOCK_THREAD_CPUTIME:
+ if ( res ) {
+ res->tv_sec = _TOD_Microseconds_per_tick / 1000000;
+ res->tv_nsec = _TOD_Microseconds_per_tick * 1000;
+ /* _POSIX_Interval_to_timespec( _TOD_Microseconds_per_tick, res ); */
+ }
+ break;
+
+ default:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ }
+ return 0;
+}
diff --git a/cpukit/posix/src/clockgettime.c b/cpukit/posix/src/clockgettime.c
new file mode 100644
index 0000000000..97a6f607e5
--- /dev/null
+++ b/cpukit/posix/src/clockgettime.c
@@ -0,0 +1,69 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 14.2.1 Clocks, P1003.1b-1993, p. 263
+ */
+
+int clock_gettime(
+ clockid_t clock_id,
+ struct timespec *tp
+)
+{
+ ISR_Level level;
+ time_t seconds;
+ long ticks;
+
+ if ( !tp )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ switch ( clock_id ) {
+
+ case CLOCK_REALTIME:
+
+ _ISR_Disable( level );
+ seconds = _TOD_Seconds_since_epoch;
+ ticks = _TOD_Current.ticks;
+ _ISR_Enable( level );
+
+ tp->tv_sec = seconds + POSIX_TIME_SECONDS_1970_THROUGH_1988;
+ tp->tv_nsec = ticks * _TOD_Microseconds_per_tick *
+ TOD_NANOSECONDS_PER_MICROSECOND;
+ break;
+
+#ifdef _POSIX_CPUTIME
+ case CLOCK_PROCESS_CPUTIME:
+ /* don't base this on _Watchdog_Ticks_since_boot--duration is too short*/
+ return POSIX_NOT_IMPLEMENTED();
+ break;
+#endif
+
+#ifdef _POSIX_THREAD_CPUTIME
+ case CLOCK_THREAD_CPUTIME:
+ return POSIX_NOT_IMPLEMENTED();
+ break;
+#endif
+ default:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ }
+ return 0;
+}
diff --git a/cpukit/posix/src/clocksetenableattr.c b/cpukit/posix/src/clocksetenableattr.c
new file mode 100644
index 0000000000..f5a29920d1
--- /dev/null
+++ b/cpukit/posix/src/clocksetenableattr.c
@@ -0,0 +1,32 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58
+ */
+
+int clock_setenable_attr(
+ clockid_t clock_id,
+ int attr
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
diff --git a/cpukit/posix/src/clocksettime.c b/cpukit/posix/src/clocksettime.c
new file mode 100644
index 0000000000..c85e90de61
--- /dev/null
+++ b/cpukit/posix/src/clocksettime.c
@@ -0,0 +1,88 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 14.2.1 Clocks, P1003.1b-1993, p. 263
+ */
+
+int clock_settime(
+ clockid_t clock_id,
+ const struct timespec *tp
+)
+{
+ struct tm split_time;
+ TOD_Control tod;
+ Watchdog_Interval seconds;
+
+ assert( tp );
+
+ switch ( clock_id ) {
+
+ case CLOCK_REALTIME:
+ (void) gmtime_r( &tp->tv_sec, &split_time );
+
+ /*
+ * Convert the tm structure format to that used by the TOD Handler
+ *
+ * NOTE: TOD Handler does not honor leap seconds.
+ */
+
+ tod.year = split_time.tm_year + 1900; /* RHS is years since 1900 */
+ tod.month = split_time.tm_mon + 1; /* RHS uses 0-11 */
+ tod.day = split_time.tm_mday;
+ tod.hour = split_time.tm_hour;
+ tod.minute = split_time.tm_min;
+ tod.second = split_time.tm_sec; /* RHS allows 0-61 for leap seconds */
+
+ tod.ticks = (tp->tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND) /
+ _TOD_Microseconds_per_tick;
+
+ if ( !_TOD_Validate( &tod ) )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ /*
+ * We can't use the tp->tv_sec field because it is based on
+ * a different EPOCH.
+ */
+
+ seconds = _TOD_To_seconds( &tod );
+ _Thread_Disable_dispatch();
+ _TOD_Set( &tod, seconds );
+ _Thread_Enable_dispatch();
+ break;
+
+#ifdef _POSIX_CPUTIME
+ case CLOCK_PROCESS_CPUTIME:
+ return POSIX_NOT_IMPLEMENTED();
+ break;
+#endif
+
+#ifdef _POSIX_THREAD_CPUTIME
+ case CLOCK_THREAD_CPUTIME:
+ return POSIX_NOT_IMPLEMENTED();
+ break;
+#endif
+ default:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ }
+ return 0;
+}
diff --git a/cpukit/posix/src/cond.c b/cpukit/posix/src/cond.c
new file mode 100644
index 0000000000..b2d0fcd8d1
--- /dev/null
+++ b/cpukit/posix/src/cond.c
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Manager_initialization
+ *
+ * This routine initializes all condition variable manager related data
+ * structures.
+ *
+ * Input parameters:
+ * maximum_condition_variables - maximum configured condition_variables
+ *
+ * Output parameters: NONE
+ */
+
+void _POSIX_Condition_variables_Manager_initialization(
+ uint32_t maximum_condition_variables
+)
+{
+ _Objects_Initialize_information(
+ &_POSIX_Condition_variables_Information, /* object information table */
+ OBJECTS_POSIX_API, /* object API */
+ OBJECTS_POSIX_CONDITION_VARIABLES, /* object class */
+ maximum_condition_variables, /* maximum objects of this class */
+ sizeof( POSIX_Condition_variables_Control ),
+ /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ 0 /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+}
diff --git a/cpukit/posix/src/condattrdestroy.c b/cpukit/posix/src/condattrdestroy.c
new file mode 100644
index 0000000000..3d818e9fef
--- /dev/null
+++ b/cpukit/posix/src/condattrdestroy.c
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * 11.4.1 Condition Variable Initialization Attributes,
+ * P1003.1c/Draft 10, p. 96
+ */
+
+int pthread_condattr_destroy(
+ pthread_condattr_t *attr
+)
+{
+ if ( !attr || attr->is_initialized == FALSE )
+ return EINVAL;
+
+ attr->is_initialized = FALSE;
+ return 0;
+}
diff --git a/cpukit/posix/src/condattrgetpshared.c b/cpukit/posix/src/condattrgetpshared.c
new file mode 100644
index 0000000000..479fb61cfb
--- /dev/null
+++ b/cpukit/posix/src/condattrgetpshared.c
@@ -0,0 +1,36 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * 11.4.1 Condition Variable Initialization Attributes,
+ * P1003.1c/Draft 10, p. 96
+ */
+
+int pthread_condattr_getpshared(
+ const pthread_condattr_t *attr,
+ int *pshared
+)
+{
+ if ( !attr )
+ return EINVAL;
+
+ *pshared = attr->process_shared;
+ return 0;
+}
diff --git a/cpukit/posix/src/condattrinit.c b/cpukit/posix/src/condattrinit.c
new file mode 100644
index 0000000000..3cd620a312
--- /dev/null
+++ b/cpukit/posix/src/condattrinit.c
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * 11.4.1 Condition Variable Initialization Attributes,
+ * P1003.1c/Draft 10, p. 96
+ */
+
+int pthread_condattr_init(
+ pthread_condattr_t *attr
+)
+{
+ if ( !attr )
+ return EINVAL;
+
+ *attr = _POSIX_Condition_variables_Default_attributes;
+ return 0;
+}
diff --git a/cpukit/posix/src/condattrsetpshared.c b/cpukit/posix/src/condattrsetpshared.c
new file mode 100644
index 0000000000..05539b2866
--- /dev/null
+++ b/cpukit/posix/src/condattrsetpshared.c
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * 11.4.1 Condition Variable Initialization Attributes,
+ * P1003.1c/Draft 10, p. 96
+ */
+
+int pthread_condattr_setpshared(
+ pthread_condattr_t *attr,
+ int pshared
+)
+{
+ if ( !attr )
+ return EINVAL;
+
+ switch ( pshared ) {
+ case PTHREAD_PROCESS_SHARED:
+ case PTHREAD_PROCESS_PRIVATE:
+ attr->process_shared = pshared;
+ return 0;
+
+ default:
+ return EINVAL;
+ }
+}
diff --git a/cpukit/posix/src/condbroadcast.c b/cpukit/posix/src/condbroadcast.c
new file mode 100644
index 0000000000..b1efbceb96
--- /dev/null
+++ b/cpukit/posix/src/condbroadcast.c
@@ -0,0 +1,30 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * 11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
+ */
+
+int pthread_cond_broadcast(
+ pthread_cond_t *cond
+)
+{
+ return _POSIX_Condition_variables_Signal_support( cond, TRUE );
+}
diff --git a/cpukit/posix/src/conddefaultattributes.c b/cpukit/posix/src/conddefaultattributes.c
new file mode 100644
index 0000000000..b8b0ae824c
--- /dev/null
+++ b/cpukit/posix/src/conddefaultattributes.c
@@ -0,0 +1,28 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * The default condition variable attributes structure.
+ */
+
+const pthread_condattr_t _POSIX_Condition_variables_Default_attributes = {
+ TRUE, /* is_initialized */
+ PTHREAD_PROCESS_PRIVATE /* process_shared */
+};
diff --git a/cpukit/posix/src/conddestroy.c b/cpukit/posix/src/conddestroy.c
new file mode 100644
index 0000000000..43f7045de6
--- /dev/null
+++ b/cpukit/posix/src/conddestroy.c
@@ -0,0 +1,80 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * 11.4.2 Initializing and Destroying a Condition Variable,
+ * P1003.1c/Draft 10, p. 87
+ */
+
+int pthread_cond_destroy(
+ pthread_cond_t *cond
+)
+{
+ POSIX_Condition_variables_Control *the_cond;
+ Objects_Locations location;
+
+ the_cond = _POSIX_Condition_variables_Get( cond, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ return EINVAL;
+#endif
+
+ case OBJECTS_ERROR:
+ return EINVAL;
+
+
+ case OBJECTS_LOCAL:
+
+ if ( _Thread_queue_First( &the_cond->Wait_queue ) ) {
+ _Thread_Enable_dispatch();
+ return EBUSY;
+ }
+
+ _Objects_Close(
+ &_POSIX_Condition_variables_Information,
+ &the_cond->Object
+ );
+
+ _POSIX_Condition_variables_Free( the_cond );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_cond->process_shared == PTHREAD_PROCESS_SHARED ) {
+
+ _Objects_MP_Close(
+ &_POSIX_Condition_variables_Information,
+ the_cond->Object.id
+ );
+
+ _POSIX_Condition_variables_MP_Send_process_packet(
+ POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_DELETE,
+ the_cond->Object.id,
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+ }
+#endif
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/condinit.c b/cpukit/posix/src/condinit.c
new file mode 100644
index 0000000000..319cd4383a
--- /dev/null
+++ b/cpukit/posix/src/condinit.c
@@ -0,0 +1,99 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * 11.4.2 Initializing and Destroying a Condition Variable,
+ * P1003.1c/Draft 10, p. 87
+ */
+
+int pthread_cond_init(
+ pthread_cond_t *cond,
+ const pthread_condattr_t *attr
+)
+{
+ POSIX_Condition_variables_Control *the_cond;
+ const pthread_condattr_t *the_attr;
+
+ if ( attr ) the_attr = attr;
+ else the_attr = &_POSIX_Condition_variables_Default_attributes;
+
+ /*
+ * XXX: Be careful about attributes when global!!!
+ */
+
+ if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
+ return POSIX_MP_NOT_IMPLEMENTED();
+
+ if ( !the_attr->is_initialized )
+ return EINVAL;
+
+ _Thread_Disable_dispatch();
+
+ the_cond = _POSIX_Condition_variables_Allocate();
+
+ if ( !the_cond ) {
+ _Thread_Enable_dispatch();
+ return ENOMEM;
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&
+ !( _Objects_MP_Allocate_and_open( &_POSIX_Condition_variables_Information,
+ 0, the_cond->Object.id, FALSE ) ) ) {
+ _POSIX_Condition_variables_Free( the_cond );
+ _Thread_Enable_dispatch();
+ return EAGAIN;
+ }
+#endif
+
+ the_cond->process_shared = the_attr->process_shared;
+
+ the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
+
+/* XXX some more initialization might need to go here */
+ _Thread_queue_Initialize(
+ &the_cond->Wait_queue,
+ THREAD_QUEUE_DISCIPLINE_FIFO,
+ STATES_WAITING_FOR_CONDITION_VARIABLE,
+ ETIMEDOUT
+ );
+
+ _Objects_Open(
+ &_POSIX_Condition_variables_Information,
+ &the_cond->Object,
+ 0
+ );
+
+ *cond = the_cond->Object.id;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
+ _POSIX_Condition_variables_MP_Send_process_packet(
+ POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_CREATE,
+ the_cond->Object.id,
+ 0, /* Name not used */
+ 0 /* Not used */
+ );
+#endif
+
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
diff --git a/cpukit/posix/src/condmp.c b/cpukit/posix/src/condmp.c
new file mode 100644
index 0000000000..8b5054d264
--- /dev/null
+++ b/cpukit/posix/src/condmp.c
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*
+ * TEMPORARY
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+void _POSIX_Condition_variables_MP_Send_process_packet (
+ POSIX_Condition_variables_MP_Remote_operations operation,
+ Objects_Id condition_variables_id,
+ Objects_Name name,
+ Objects_Id proxy_id
+)
+{
+ (void) POSIX_MP_NOT_IMPLEMENTED();
+}
+
+void _POSIX_Condition_variables_MP_Send_extract_proxy(
+ Thread_Control *the_thread
+)
+{
+ (void) POSIX_MP_NOT_IMPLEMENTED();
+}
+#endif
+
+/*
+ * END OF TEMPORARY
+ */
diff --git a/cpukit/posix/src/condsignal.c b/cpukit/posix/src/condsignal.c
new file mode 100644
index 0000000000..bd9d4b3b07
--- /dev/null
+++ b/cpukit/posix/src/condsignal.c
@@ -0,0 +1,30 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * 11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
+ */
+
+int pthread_cond_signal(
+ pthread_cond_t *cond
+)
+{
+ return _POSIX_Condition_variables_Signal_support( cond, FALSE );
+}
diff --git a/cpukit/posix/src/condsignalsupp.c b/cpukit/posix/src/condsignalsupp.c
new file mode 100644
index 0000000000..5fad8e0ead
--- /dev/null
+++ b/cpukit/posix/src/condsignalsupp.c
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Signal_support
+ *
+ * A support routine which implements guts of the broadcast and single task
+ * wake up version of the "signal" operation.
+ */
+
+int _POSIX_Condition_variables_Signal_support(
+ pthread_cond_t *cond,
+ boolean is_broadcast
+)
+{
+ register POSIX_Condition_variables_Control *the_cond;
+ Objects_Locations location;
+ Thread_Control *the_thread;
+
+ the_cond = _POSIX_Condition_variables_Get( cond, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ return EINVAL;
+#endif
+
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_LOCAL:
+
+ do {
+ the_thread = _Thread_queue_Dequeue( &the_cond->Wait_queue );
+ if ( !the_thread )
+ the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
+ } while ( is_broadcast && the_thread );
+
+ _Thread_Enable_dispatch();
+
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/condtimedwait.c b/cpukit/posix/src/condtimedwait.c
new file mode 100644
index 0000000000..32ce1d4a05
--- /dev/null
+++ b/cpukit/posix/src/condtimedwait.c
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * 11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
+ */
+
+int pthread_cond_timedwait(
+ pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ const struct timespec *abstime
+)
+{
+ Watchdog_Interval timeout;
+ struct timespec current_time;
+ struct timespec difference;
+ boolean already_timedout = FALSE;
+
+ if ( !abstime )
+ return EINVAL;
+
+ /*
+ * The abstime is a walltime. We turn it into an interval.
+ */
+
+ (void) clock_gettime( CLOCK_REALTIME, &current_time );
+
+ /* XXX probably some error checking should go here */
+
+ _POSIX_Timespec_subtract( &current_time, abstime, &difference );
+
+ if ( ( difference.tv_sec < 0 ) || ( ( difference.tv_sec == 0 ) &&
+ ( difference.tv_nsec < 0 ) ) )
+ already_timedout = TRUE;
+
+ timeout = _POSIX_Timespec_to_interval( &difference );
+
+ return _POSIX_Condition_variables_Wait_support(
+ cond,
+ mutex,
+ timeout,
+ already_timedout
+ );
+}
diff --git a/cpukit/posix/src/condwait.c b/cpukit/posix/src/condwait.c
new file mode 100644
index 0000000000..cde020fe93
--- /dev/null
+++ b/cpukit/posix/src/condwait.c
@@ -0,0 +1,36 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * 11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
+ */
+
+int pthread_cond_wait(
+ pthread_cond_t *cond,
+ pthread_mutex_t *mutex
+)
+{
+ return _POSIX_Condition_variables_Wait_support(
+ cond,
+ mutex,
+ THREAD_QUEUE_WAIT_FOREVER,
+ FALSE
+ );
+}
diff --git a/cpukit/posix/src/condwaitsupp.c b/cpukit/posix/src/condwaitsupp.c
new file mode 100644
index 0000000000..02780779bf
--- /dev/null
+++ b/cpukit/posix/src/condwaitsupp.c
@@ -0,0 +1,108 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/mutex.h>
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Wait_support
+ *
+ * A support routine which implements guts of the blocking, non-blocking, and
+ * timed wait version of condition variable wait routines.
+ */
+
+int _POSIX_Condition_variables_Wait_support(
+ pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ Watchdog_Interval timeout,
+ boolean already_timedout
+)
+{
+ register POSIX_Condition_variables_Control *the_cond;
+ Objects_Locations location;
+ int status;
+ int mutex_status;
+
+ if ( !_POSIX_Mutex_Get( mutex, &location ) ) {
+ return EINVAL;
+ }
+
+ _Thread_Unnest_dispatch();
+
+ the_cond = _POSIX_Condition_variables_Get( cond, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ return EINVAL;
+#endif
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_LOCAL:
+
+ if ( the_cond->Mutex && ( the_cond->Mutex != *mutex ) ) {
+ _Thread_Enable_dispatch();
+ return EINVAL;
+ }
+
+ (void) pthread_mutex_unlock( mutex );
+/* XXX ignore this for now since behavior is undefined
+ if ( mutex_status ) {
+ _Thread_Enable_dispatch();
+ return EINVAL;
+ }
+*/
+
+ if ( !already_timedout ) {
+ the_cond->Mutex = *mutex;
+
+ _Thread_queue_Enter_critical_section( &the_cond->Wait_queue );
+ _Thread_Executing->Wait.return_code = 0;
+ _Thread_Executing->Wait.queue = &the_cond->Wait_queue;
+ _Thread_Executing->Wait.id = *cond;
+
+ _Thread_queue_Enqueue( &the_cond->Wait_queue, timeout );
+
+ _Thread_Enable_dispatch();
+
+ /*
+ * Switch ourself out because we blocked as a result of the
+ * _Thread_queue_Enqueue.
+ */
+
+ status = _Thread_Executing->Wait.return_code;
+ if ( status && status != ETIMEDOUT )
+ return status;
+
+ } else {
+ _Thread_Enable_dispatch();
+ status = ETIMEDOUT;
+ }
+
+ /*
+ * When we get here the dispatch disable level is 0.
+ */
+
+ mutex_status = pthread_mutex_lock( mutex );
+ if ( mutex_status )
+ return EINVAL;
+
+ return status;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/devctl.c b/cpukit/posix/src/devctl.c
new file mode 100644
index 0000000000..9800a109eb
--- /dev/null
+++ b/cpukit/posix/src/devctl.c
@@ -0,0 +1,26 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <devctl.h>
+
+#include <rtems/system.h>
+
+/*PAGE
+ *
+ * 21.2.1 Control a Device, P1003.4b/D8, p. 65
+ */
+
+int devctl(
+ int filedes,
+ void *dev_data_ptr,
+ size_t nbyte,
+ int *dev_info_ptr
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
diff --git a/cpukit/posix/src/execl.c b/cpukit/posix/src/execl.c
new file mode 100644
index 0000000000..fa820a268f
--- /dev/null
+++ b/cpukit/posix/src/execl.c
@@ -0,0 +1,21 @@
+/*
+ * execl() - POSIX 1003.1b 3.1.2
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+int execl(
+ const char *path,
+ const char *arg,
+ ...
+)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/posix/src/execle.c b/cpukit/posix/src/execle.c
new file mode 100644
index 0000000000..83bd05882c
--- /dev/null
+++ b/cpukit/posix/src/execle.c
@@ -0,0 +1,21 @@
+/*
+ * execle() - POSIX 1003.1b 3.1.2
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+int execle(
+ const char *path,
+ char const *arg,
+ ...
+)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/posix/src/execlp.c b/cpukit/posix/src/execlp.c
new file mode 100644
index 0000000000..2bc1303527
--- /dev/null
+++ b/cpukit/posix/src/execlp.c
@@ -0,0 +1,21 @@
+/*
+ * execlp() - POSIX 1003.1b 3.1.2
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+int execlp(
+ const char *file,
+ const char *arg,
+ ...
+)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/posix/src/execv.c b/cpukit/posix/src/execv.c
new file mode 100644
index 0000000000..c30d4939b6
--- /dev/null
+++ b/cpukit/posix/src/execv.c
@@ -0,0 +1,20 @@
+/*
+ * execv() - POSIX 1003.1b 3.1.2
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+int execv(
+ const char *file,
+ char *const argv[]
+)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/posix/src/execve.c b/cpukit/posix/src/execve.c
new file mode 100644
index 0000000000..43ec3004e6
--- /dev/null
+++ b/cpukit/posix/src/execve.c
@@ -0,0 +1,21 @@
+/*
+ * execve() - POSIX 1003.1b 3.1.2
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+int execve(
+ const char *path,
+ char *const argv[],
+ char *const envp[]
+)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/posix/src/execvp.c b/cpukit/posix/src/execvp.c
new file mode 100644
index 0000000000..a82db0ed32
--- /dev/null
+++ b/cpukit/posix/src/execvp.c
@@ -0,0 +1,20 @@
+/*
+ * execvp() - POSIX 1003.1b 3.1.2
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+
+int execvp(
+ const char *path,
+ char *const argv[]
+)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/posix/src/fork.c b/cpukit/posix/src/fork.c
new file mode 100644
index 0000000000..b06b1c9dbf
--- /dev/null
+++ b/cpukit/posix/src/fork.c
@@ -0,0 +1,18 @@
+/*
+ * fork() - POSIX 1003.1b 3.1.1
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <errno.h>
+
+int fork( void )
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/posix/src/getpagesize.c b/cpukit/posix/src/getpagesize.c
new file mode 100644
index 0000000000..806c500a9b
--- /dev/null
+++ b/cpukit/posix/src/getpagesize.c
@@ -0,0 +1,23 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+
+/*PAGE
+ *
+ * Get System Page Size (from SVR4 and 4.2+ BSD)
+ *
+ * This is not a functional version but the SPARC backend for at least
+ * gcc 2.8.1 plus gnat 3.13p and gcc 3.0.1 require it to be there and
+ * return a reasonable value.
+ */
+
+size_t getpagesize(void)
+{
+ return 4096;
+}
diff --git a/cpukit/posix/src/key.c b/cpukit/posix/src/key.c
new file mode 100644
index 0000000000..8723cb67a0
--- /dev/null
+++ b/cpukit/posix/src/key.c
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <string.h>
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/key.h>
+
+/*
+ * _POSIX_Key_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _POSIX_Key_Manager_initialization(
+ uint32_t maximum_keys
+)
+{
+ _Objects_Initialize_information(
+ &_POSIX_Keys_Information, /* object information table */
+ OBJECTS_POSIX_API, /* object API */
+ OBJECTS_POSIX_KEYS, /* object class */
+ maximum_keys, /* maximum objects of this class */
+ sizeof( POSIX_Keys_Control ),
+ /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ 0 /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+}
diff --git a/cpukit/posix/src/keycreate.c b/cpukit/posix/src/keycreate.c
new file mode 100644
index 0000000000..d8ae746992
--- /dev/null
+++ b/cpukit/posix/src/keycreate.c
@@ -0,0 +1,90 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <string.h>
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/key.h>
+
+/*PAGE
+ *
+ * 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
+ */
+
+int pthread_key_create(
+ pthread_key_t *key,
+ void (*destructor)( void * )
+)
+{
+ POSIX_Keys_Control *the_key;
+ void *table;
+ uint32_t the_api;
+ uint32_t bytes_to_allocate;
+
+
+ _Thread_Disable_dispatch();
+
+ the_key = _POSIX_Keys_Allocate();
+
+ if ( !the_key ) {
+ _Thread_Enable_dispatch();
+ return EAGAIN;
+ }
+
+ the_key->destructor = destructor;
+
+ /*
+ * This is a bit more complex than one might initially expect because
+ * APIs are optional. Thus there may be no ITRON tasks to have keys
+ * for. [NOTE: Currently RTEMS Classic API tasks are not always enabled.]
+ */
+
+ for ( the_api = 1;
+ the_api <= OBJECTS_APIS_LAST;
+ the_api++ ) {
+
+ if ( _Objects_Information_table[ the_api ] &&
+ _Objects_Information_table[ the_api ][ 1 ] ) {
+ bytes_to_allocate = sizeof( void * ) *
+ (_Objects_Information_table[ the_api ][ 1 ]->maximum + 1);
+ table = _Workspace_Allocate( bytes_to_allocate );
+ if ( !table ) {
+ for ( --the_api;
+ the_api >= 1;
+ the_api-- )
+ _Workspace_Free( the_key->Values[ the_api ] );
+
+ _POSIX_Keys_Free( the_key );
+ _Thread_Enable_dispatch();
+ return ENOMEM;
+ }
+
+ the_key->Values[ the_api ] = table;
+ memset( table, '\0', bytes_to_allocate );
+ } else {
+ the_key->Values[ the_api ] = NULL;
+ }
+
+
+ }
+
+ the_key->is_active = TRUE;
+
+ _Objects_Open( &_POSIX_Keys_Information, &the_key->Object, 0 );
+
+ *key = the_key->Object.id;
+
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
diff --git a/cpukit/posix/src/keydelete.c b/cpukit/posix/src/keydelete.c
new file mode 100644
index 0000000000..364108046b
--- /dev/null
+++ b/cpukit/posix/src/keydelete.c
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <string.h>
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/key.h>
+
+/*PAGE
+ *
+ * 17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167
+ */
+
+int pthread_key_delete(
+ pthread_key_t key
+)
+{
+ register POSIX_Keys_Control *the_key;
+ Objects_Locations location;
+ uint32_t the_api;
+
+ the_key = _POSIX_Keys_Get( key, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE: /* should never happen */
+ return EINVAL;
+ case OBJECTS_LOCAL:
+ _Objects_Close( &_POSIX_Keys_Information, &the_key->Object );
+
+ the_key->is_active = FALSE;
+
+ for ( the_api = 1;
+ the_api <= OBJECTS_APIS_LAST;
+ the_api++ )
+ if ( the_key->Values[ the_api ] )
+ _Workspace_Free( the_key->Values[ the_api ] );
+
+ /*
+ * NOTE: The destructor is not called and it is the responsibility
+ * of the application to free the memory.
+ */
+
+ _POSIX_Keys_Free( the_key );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/keygetspecific.c b/cpukit/posix/src/keygetspecific.c
new file mode 100644
index 0000000000..ee6912022c
--- /dev/null
+++ b/cpukit/posix/src/keygetspecific.c
@@ -0,0 +1,48 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <string.h>
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/key.h>
+
+/*PAGE
+ *
+ * 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
+ */
+
+void *pthread_getspecific(
+ pthread_key_t key
+)
+{
+ register POSIX_Keys_Control *the_key;
+ uint32_t index;
+ uint32_t class;
+ Objects_Locations location;
+ void *key_data;
+
+ the_key = _POSIX_Keys_Get( key, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE: /* should never happen */
+ return NULL;
+ case OBJECTS_LOCAL:
+ index = _Objects_Get_index( _Thread_Executing->Object.id );
+ class = _Objects_Get_class( _Thread_Executing->Object.id );
+ key_data = (void *) the_key->Values[ class ][ index ];
+ _Thread_Enable_dispatch();
+ return key_data;
+ }
+ (void) POSIX_BOTTOM_REACHED();
+ return (void *)NULL;
+}
diff --git a/cpukit/posix/src/keyrundestructors.c b/cpukit/posix/src/keyrundestructors.c
new file mode 100644
index 0000000000..f2c3b8e380
--- /dev/null
+++ b/cpukit/posix/src/keyrundestructors.c
@@ -0,0 +1,80 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <string.h>
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/key.h>
+
+/*PAGE
+ *
+ * _POSIX_Keys_Run_destructors
+ *
+ * 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
+ *
+ * NOTE: This is the routine executed when a thread exits to
+ * run through all the keys and do the destructor action.
+ */
+
+void _POSIX_Keys_Run_destructors(
+ Thread_Control *thread
+)
+{
+ uint32_t index;
+ uint32_t pthread_index;
+ uint32_t pthread_class;
+ uint32_t iterations;
+ boolean are_all_null;
+ POSIX_Keys_Control *the_key;
+ void *value;
+
+ pthread_index = _Objects_Get_index( thread->Object.id );
+ pthread_class = _Objects_Get_class( thread->Object.id );
+
+ iterations = 0;
+
+ for ( ; ; ) {
+
+ are_all_null = TRUE;
+
+ for ( index=1 ; index <= _POSIX_Keys_Information.maximum ; index++ ) {
+
+ the_key = (POSIX_Keys_Control *)
+ _POSIX_Keys_Information.local_table[ index ];
+
+ if ( the_key && the_key->is_active && the_key->destructor ) {
+ value = the_key->Values[ pthread_class ][ pthread_index ];
+ if ( value ) {
+ (*the_key->destructor)( value );
+ if ( the_key->Values[ pthread_class ][ pthread_index ] )
+ are_all_null = FALSE;
+ }
+ }
+ }
+
+ if ( are_all_null == TRUE )
+ return;
+
+ iterations++;
+
+ /*
+ * The standard allows one to not do this and thus go into an infinite
+ * loop. It seems rude to unnecessarily lock up a system.
+ *
+ * Reference: 17.1.1.2 P1003.1c/Draft 10, p. 163, line 99.
+ */
+
+ if ( iterations >= PTHREAD_DESTRUCTOR_ITERATIONS )
+ return;
+ }
+}
diff --git a/cpukit/posix/src/keysetspecific.c b/cpukit/posix/src/keysetspecific.c
new file mode 100644
index 0000000000..30f10a06b4
--- /dev/null
+++ b/cpukit/posix/src/keysetspecific.c
@@ -0,0 +1,47 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <string.h>
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/key.h>
+
+/*PAGE
+ *
+ * 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
+ */
+
+int pthread_setspecific(
+ pthread_key_t key,
+ const void *value
+)
+{
+ register POSIX_Keys_Control *the_key;
+ uint32_t index;
+ uint32_t class;
+ Objects_Locations location;
+
+ the_key = _POSIX_Keys_Get( key, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE: /* should never happen */
+ return EINVAL;
+ case OBJECTS_LOCAL:
+ index = _Objects_Get_index( _Thread_Executing->Object.id );
+ class = _Objects_Get_class( _Thread_Executing->Object.id );
+ the_key->Values[ class ][ index ] = (void *) value;
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/kill.c b/cpukit/posix/src/kill.c
new file mode 100644
index 0000000000..b601ee1d01
--- /dev/null
+++ b/cpukit/posix/src/kill.c
@@ -0,0 +1,51 @@
+/*
+ * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+
+int kill(
+ pid_t pid,
+ int sig
+)
+{
+ return killinfo( pid, sig, NULL );
+}
+
+/*
+ * _kill_r
+ *
+ * This is the Newlib dependent reentrant version of kill().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _kill_r(
+ struct _reent *ptr,
+ pid_t pid,
+ int sig
+)
+{
+ return kill( pid, sig );
+}
+#endif
diff --git a/cpukit/posix/src/killinfo.c b/cpukit/posix/src/killinfo.c
new file mode 100644
index 0000000000..b275a0b764
--- /dev/null
+++ b/cpukit/posix/src/killinfo.c
@@ -0,0 +1,338 @@
+/*
+ * kill() support routine
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/seterr.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68
+ *
+ * NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS.
+ */
+
+#define _POSIX_signals_Is_interested( _api, _mask ) \
+ ( ~(_api)->signals_blocked & (_mask) )
+
+int killinfo(
+ pid_t pid,
+ int sig,
+ const union sigval *value
+)
+{
+ sigset_t mask;
+ POSIX_API_Control *api;
+ uint32_t the_api;
+ uint32_t index;
+ uint32_t maximum;
+ Objects_Information *the_info;
+ Objects_Control **object_table;
+ Thread_Control *the_thread;
+ Thread_Control *interested_thread;
+ Priority_Control interested_priority;
+ Chain_Control *the_chain;
+ Chain_Node *the_node;
+ siginfo_t siginfo_struct;
+ siginfo_t *siginfo;
+ POSIX_signals_Siginfo_node *psiginfo;
+
+ /*
+ * Only supported for the "calling process" (i.e. this node).
+ */
+
+ if ( pid != getpid() )
+ rtems_set_errno_and_return_minus_one( ESRCH );
+
+ /*
+ * Validate the signal passed.
+ */
+
+ if ( !sig )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( !is_valid_signo(sig) )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ /*
+ * If the signal is being ignored, then we are out of here.
+ */
+
+ if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) {
+ return 0;
+ }
+
+ /*
+ * P1003.1c/Draft 10, p. 33 says that certain signals should always
+ * be directed to the executing thread such as those caused by hardware
+ * faults.
+ */
+
+ switch ( sig ) {
+ case SIGFPE:
+ case SIGILL:
+ case SIGSEGV:
+ return pthread_kill( pthread_self(), sig );
+ default:
+ break;
+ }
+
+ mask = signo_to_mask( sig );
+
+ /*
+ * Build up a siginfo structure
+ */
+
+ siginfo = &siginfo_struct;
+ siginfo->si_signo = sig;
+ siginfo->si_code = SI_USER;
+ if ( !value ) {
+ siginfo->si_value.sival_int = 0;
+ } else {
+ siginfo->si_value = *value;
+ }
+
+ _Thread_Disable_dispatch();
+
+ /*
+ * Is the currently executing thread interested? If so then it will
+ * get it an execute it as soon as the dispatcher executes.
+ */
+
+ the_thread = _Thread_Executing;
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+ if ( _POSIX_signals_Is_interested( api, mask ) ) {
+ goto process_it;
+ }
+
+ /*
+ * Is an interested thread waiting for this signal (sigwait())?
+ */
+
+ /* XXX violation of visibility -- need to define thread queue support */
+
+ for( index=0 ;
+ index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
+ index++ ) {
+
+ the_chain = &_POSIX_signals_Wait_queue.Queues.Priority[ index ];
+
+ for ( the_node = the_chain->first ;
+ !_Chain_Is_tail( the_chain, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_thread = (Thread_Control *)the_node;
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ if ((the_thread->Wait.option & mask) || (~api->signals_blocked & mask)) {
+ goto process_it;
+ }
+
+ }
+ }
+
+ /*
+ * Is any other thread interested? The highest priority interested
+ * thread is selected. In the event of a tie, then the following
+ * additional criteria is used:
+ *
+ * + ready thread over blocked
+ * + blocked on call interruptible by signal (can return EINTR)
+ * + blocked on call not interruptible by signal
+ *
+ * This looks at every thread in the system regardless of the creating API.
+ *
+ * NOTES:
+ *
+ * + rtems internal threads do not receive signals.
+ */
+
+ interested_thread = NULL;
+ interested_priority = PRIORITY_MAXIMUM + 1;
+
+ for ( the_api = 2;
+ the_api <= OBJECTS_APIS_LAST;
+ the_api++ ) {
+
+ if ( the_api == OBJECTS_INTERNAL_THREADS )
+ continue;
+
+ if ( !_Objects_Information_table[ the_api ] ) /* API not installed */
+ continue;
+
+ the_info = _Objects_Information_table[ the_api ][ 1 ];
+
+ if ( !the_info ) /* manager not installed */
+ continue;
+
+ maximum = the_info->maximum;
+ object_table = the_info->local_table;
+
+ assert( object_table ); /* always at least 1 entry */
+
+ for ( index = 1 ; index <= maximum ; index++ ) {
+ the_thread = (Thread_Control *) object_table[ index ];
+
+ if ( !the_thread )
+ continue;
+
+ /*
+ * If this thread is of lower priority than the interested thread,
+ * go on to the next thread.
+ */
+
+ if ( the_thread->current_priority > interested_priority )
+ continue;
+
+ /*
+ * If this thread is not interested, then go on to the next thread.
+ */
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ if ( !api || !_POSIX_signals_Is_interested( api, mask ) )
+ continue;
+
+ /*
+ * Now we know the thread under connsideration is interested.
+ * If the thread under consideration is of higher priority, then
+ * it becomes the interested thread.
+ */
+
+ if ( the_thread->current_priority < interested_priority ) {
+ interested_thread = the_thread;
+ interested_priority = the_thread->current_priority;
+ continue;
+ }
+
+ /*
+ * Now the thread and the interested thread have the same priority.
+ * If the interested thread is ready, then we don't need to send it
+ * to a blocked thread.
+ */
+
+ if ( _States_Is_ready( interested_thread->current_state ) )
+ continue;
+
+ /*
+ * Now the interested thread is blocked.
+ * If the thread we are considering is not, the it becomes the
+ * interested thread.
+ */
+
+ if ( _States_Is_ready( the_thread->current_state ) ) {
+ interested_thread = the_thread;
+ interested_priority = the_thread->current_priority;
+ continue;
+ }
+
+ /*
+ * Now we know both threads are blocked.
+ * If the interested thread is interruptible, then just use it.
+ */
+
+ /* XXX need a new states macro */
+ if ( interested_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL )
+ continue;
+
+ /*
+ * Now both threads are blocked and the interested thread is not
+ * interruptible.
+ * If the thread under consideration is interruptible by a signal,
+ * then it becomes the interested thread.
+ */
+
+ /* XXX need a new states macro */
+ if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {
+ interested_thread = the_thread;
+ interested_priority = the_thread->current_priority;
+ }
+ }
+ }
+
+ if ( interested_thread ) {
+ the_thread = interested_thread;
+ goto process_it;
+ }
+
+ /*
+ * OK so no threads were interested right now. It will be left on the
+ * global pending until a thread receives it. The global set of threads
+ * can change interest in this signal in one of the following ways:
+ *
+ * + a thread is created with the signal unblocked,
+ * + pthread_sigmask() unblocks the signal,
+ * + sigprocmask() unblocks the signal, OR
+ * + sigaction() which changes the handler to SIG_IGN.
+ */
+
+ the_thread = NULL;
+ goto post_process_signal;
+
+ /*
+ * We found a thread which was interested, so now we mark that this
+ * thread needs to do the post context switch extension so it can
+ * evaluate the signals pending.
+ */
+
+process_it:
+
+ the_thread->do_post_task_switch_extension = TRUE;
+
+ /*
+ * Returns TRUE if the signal was synchronously given to a thread
+ * blocked waiting for the signal.
+ */
+
+ if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) {
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+
+post_process_signal:
+
+ /*
+ * We may have woken up a thread but we definitely need to post the
+ * signal to the process wide information set.
+ */
+
+ _POSIX_signals_Set_process_signals( mask );
+
+ if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) {
+
+ psiginfo = (POSIX_signals_Siginfo_node *)
+ _Chain_Get( &_POSIX_signals_Inactive_siginfo );
+ if ( !psiginfo ) {
+ rtems_set_errno_and_return_minus_one( EAGAIN );
+ }
+
+ psiginfo->Info = *siginfo;
+
+ _Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node );
+ }
+
+ _Thread_Enable_dispatch();
+ return 0;
+}
diff --git a/cpukit/posix/src/mprotect.c b/cpukit/posix/src/mprotect.c
new file mode 100644
index 0000000000..60740615b5
--- /dev/null
+++ b/cpukit/posix/src/mprotect.c
@@ -0,0 +1,23 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+
+/*PAGE
+ *
+ * 12.2.3 Change Memory Protection, P1003.1b-1996, p. 277.
+ *
+ * This is not a functional version but the SPARC backend for at least
+ * gcc 2.8.1 plus gnat 3.13p and gcc 3.0.1 require it to be there and
+ * return 0.
+ */
+
+int mprotect(const void *addr, size_t len, int prot)
+{
+ return 0;
+}
diff --git a/cpukit/posix/src/mqueue.c b/cpukit/posix/src/mqueue.c
new file mode 100644
index 0000000000..3caef06194
--- /dev/null
+++ b/cpukit/posix/src/mqueue.c
@@ -0,0 +1,81 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Manager_initialization
+ *
+ * This routine initializes all message_queue manager related data structures.
+ *
+ * Input parameters:
+ * maximum_message_queues - maximum configured message_queues
+ *
+ * Output parameters: NONE
+ */
+
+void _POSIX_Message_queue_Manager_initialization(
+ uint32_t maximum_message_queues
+)
+{
+ _Objects_Initialize_information(
+ &_POSIX_Message_queue_Information, /* object information table */
+ OBJECTS_POSIX_API, /* object API */
+ OBJECTS_POSIX_MESSAGE_QUEUES, /* object class */
+ maximum_message_queues, /* maximum objects of this class */
+ sizeof( POSIX_Message_queue_Control ),
+ /* size of this object's control block */
+ TRUE, /* TRUE if names for this object are strings */
+ _POSIX_PATH_MAX /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+ _Objects_Initialize_information(
+ &_POSIX_Message_queue_Information_fds,
+ OBJECTS_POSIX_API,
+ OBJECTS_POSIX_MESSAGE_QUEUE_FDS,
+ maximum_message_queues,
+ sizeof( POSIX_Message_queue_Control_fd ),
+ /* size of this object's control block */
+ TRUE, /* TRUE if names for this object are strings */
+ NAME_MAX /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+}
diff --git a/cpukit/posix/src/mqueueclose.c b/cpukit/posix/src/mqueueclose.c
new file mode 100644
index 0000000000..9254bbf25b
--- /dev/null
+++ b/cpukit/posix/src/mqueueclose.c
@@ -0,0 +1,79 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*
+ *
+ * 15.2.2 Close a Message Queue, P1003.1b-1993, p. 275
+ */
+
+int mq_close(
+ mqd_t mqdes
+)
+{
+ POSIX_Message_queue_Control *the_mq;
+ POSIX_Message_queue_Control_fd *the_mq_fd;
+ Objects_Locations location;
+
+ the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EBADF );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_LOCAL:
+ /*
+ * First update the actual message queue to reflect this descriptor
+ * being disassociated. This may result in the queue being really
+ * deleted.
+ */
+
+ the_mq = the_mq_fd->Queue;
+ the_mq->open_count -= 1;
+ _POSIX_Message_queue_Delete( the_mq );
+
+ /*
+ * Now close this file descriptor.
+ */
+
+ _Objects_Close(
+ &_POSIX_Message_queue_Information_fds, &the_mq_fd->Object );
+ _POSIX_Message_queue_Free_fd( the_mq_fd );
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/mqueuecreatesupp.c b/cpukit/posix/src/mqueuecreatesupp.c
new file mode 100644
index 0000000000..1259701124
--- /dev/null
+++ b/cpukit/posix/src/mqueuecreatesupp.c
@@ -0,0 +1,173 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/* pure ANSI mode does not have this prototype */
+size_t strnlen(const char *, size_t);
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Create_support
+ *
+ * This routine does the actual creation and initialization of
+ * a poxix message queue.
+ */
+
+int _POSIX_Message_queue_Create_support(
+ const char *name_arg,
+ int pshared,
+ struct mq_attr *attr_ptr,
+ POSIX_Message_queue_Control **message_queue
+)
+{
+ POSIX_Message_queue_Control *the_mq;
+ CORE_message_queue_Attributes *the_mq_attr;
+ struct mq_attr attr;
+ char *name;
+ size_t n;
+
+ n = strnlen( name_arg, NAME_MAX );
+ if ( n > NAME_MAX )
+ return ENAMETOOLONG;
+
+ _Thread_Disable_dispatch();
+
+ /*
+ * There is no real basis for the default values. They will work
+ * but were not compared against any existing implementation for
+ * compatibility. See README.mqueue for an example program we
+ * think will print out the defaults. Report anything you find with it.
+ */
+
+ if ( attr_ptr == NULL ) {
+ attr.mq_maxmsg = 10;
+ attr.mq_msgsize = 16;
+ } else {
+ if ( attr_ptr->mq_maxmsg <= 0 ){
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ if ( attr_ptr->mq_msgsize <= 0 ){
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ attr = *attr_ptr;
+ }
+
+#if 0 && defined(RTEMS_MULTIPROCESSING)
+ if ( pshared == PTHREAD_PROCESS_SHARED &&
+ !( _Objects_MP_Allocate_and_open( &_POSIX_Message_queue_Information, 0,
+ the_mq->Object.id, FALSE ) ) ) {
+ _POSIX_Message_queue_Free( the_mq );
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( ENFILE );
+ }
+#endif
+
+ the_mq = _POSIX_Message_queue_Allocate();
+ if ( !the_mq ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( ENFILE );
+ }
+
+ the_mq->process_shared = pshared;
+ the_mq->named = TRUE;
+ the_mq->open_count = 1;
+ the_mq->linked = TRUE;
+
+ /*
+ * Make a copy of the user's string for name just in case it was
+ * dynamically constructed.
+ */
+
+ name = _Workspace_Allocate(n);
+ if (!name) {
+ _POSIX_Message_queue_Free( the_mq );
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( ENOMEM );
+ }
+ strcpy( name, name_arg );
+
+ /* XXX
+ *
+ * Note that thread blocking discipline should be based on the
+ * current scheduling policy.
+ */
+
+ the_mq_attr = &the_mq->Message_queue.Attributes;
+ the_mq_attr->discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
+
+ if ( ! _CORE_message_queue_Initialize(
+ &the_mq->Message_queue,
+ the_mq_attr,
+ attr.mq_maxmsg,
+ attr.mq_msgsize
+ ) ) {
+
+#if 0 && defined(RTEMS_MULTIPROCESSING)
+ if ( pshared == PTHREAD_PROCESS_SHARED )
+ _Objects_MP_Close( &_POSIX_Message_queue_Information, the_mq->Object.id );
+#endif
+
+ _POSIX_Message_queue_Free( the_mq );
+ _Workspace_Free(name);
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( ENOSPC );
+ }
+
+ _Objects_Open(
+ &_POSIX_Message_queue_Information,
+ &the_mq->Object,
+ (char *) name
+ );
+
+ *message_queue = the_mq;
+
+#if 0 && defined(RTEMS_MULTIPROCESSING)
+ if ( pshared == PTHREAD_PROCESS_SHARED )
+ _POSIX_Message_queue_MP_Send_process_packet(
+ POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
+ the_mq->Object.id,
+ (char *) name,
+ 0 /* Not used */
+ );
+#endif
+
+ _Thread_Enable_dispatch();
+ return 0;
+}
diff --git a/cpukit/posix/src/mqueuedeletesupp.c b/cpukit/posix/src/mqueuedeletesupp.c
new file mode 100644
index 0000000000..bf2e52fd64
--- /dev/null
+++ b/cpukit/posix/src/mqueuedeletesupp.c
@@ -0,0 +1,78 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Delete
+ */
+
+void _POSIX_Message_queue_Delete(
+ POSIX_Message_queue_Control *the_mq
+)
+{
+ if ( !the_mq->linked && !the_mq->open_count ) {
+ /* the name memory may have been freed by unlink. */
+ if ( the_mq->Object.name )
+ _Workspace_Free( the_mq->Object.name );
+
+ _Objects_Close( &_POSIX_Message_queue_Information, &the_mq->Object );
+
+ _CORE_message_queue_Close(
+ &the_mq->Message_queue,
+ NULL, /* no MP support */
+ CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED
+ );
+
+ _POSIX_Message_queue_Free( the_mq );
+
+#if 0 && defined(RTEMS_MULTIPROCESSING)
+ if ( the_mq->process_shared == PTHREAD_PROCESS_SHARED ) {
+
+ _Objects_MP_Close(
+ &_POSIX_Message_queue_Information,
+ the_mq->Object.id
+ );
+
+ _POSIX_Message_queue_MP_Send_process_packet(
+ POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_DELETE,
+ the_mq->Object.id,
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+ }
+#endif
+
+ }
+}
diff --git a/cpukit/posix/src/mqueuegetattr.c b/cpukit/posix/src/mqueuegetattr.c
new file mode 100644
index 0000000000..d5cb7ababb
--- /dev/null
+++ b/cpukit/posix/src/mqueuegetattr.c
@@ -0,0 +1,79 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 15.2.8 Get Message Queue Attributes, P1003.1b-1993, p. 283
+ */
+
+int mq_getattr(
+ mqd_t mqdes,
+ struct mq_attr *mqstat
+)
+{
+ POSIX_Message_queue_Control *the_mq;
+ POSIX_Message_queue_Control_fd *the_mq_fd;
+ Objects_Locations location;
+ CORE_message_queue_Attributes *the_mq_attr;
+
+ if ( !mqstat )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EBADF );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_LOCAL:
+ the_mq = the_mq_fd->Queue;
+
+ /*
+ * Return the old values.
+ */
+
+ the_mq_attr = &the_mq->Message_queue.Attributes;
+
+ mqstat->mq_flags = the_mq_fd->oflag;
+ mqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
+ mqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages;
+ mqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/mqueuenametoid.c b/cpukit/posix/src/mqueuenametoid.c
new file mode 100644
index 0000000000..91dd9357fd
--- /dev/null
+++ b/cpukit/posix/src/mqueuenametoid.c
@@ -0,0 +1,66 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Name_to_id
+ *
+ * Look up the specified name and attempt to locate the id
+ * for the associated message queue.
+ */
+
+int _POSIX_Message_queue_Name_to_id(
+ const char *name,
+ Objects_Id *id
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ if ( !name )
+ return EINVAL;
+
+ if ( !name[0] )
+ return EINVAL;
+
+ if( strlen(name) > PATH_MAX )
+ return ENAMETOOLONG;
+
+ status = _Objects_Name_to_id(
+ &_POSIX_Message_queue_Information, (char *)name, 0, id );
+
+ if ( status == OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL )
+ return 0;
+
+ return ENOENT;
+}
diff --git a/cpukit/posix/src/mqueuenotify.c b/cpukit/posix/src/mqueuenotify.c
new file mode 100644
index 0000000000..5733346e16
--- /dev/null
+++ b/cpukit/posix/src/mqueuenotify.c
@@ -0,0 +1,107 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Notify_handler
+ *
+ */
+
+void _POSIX_Message_queue_Notify_handler(
+ void *user_data
+)
+{
+ POSIX_Message_queue_Control *the_mq;
+
+ the_mq = user_data;
+
+ kill( getpid(), the_mq->notification.sigev_signo );
+
+ _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
+}
+
+/*PAGE
+ *
+ * 15.2.6 Notify Process that a Message is Available on a Queue,
+ * P1003.1b-1993, p. 280
+ */
+
+int mq_notify(
+ mqd_t mqdes,
+ const struct sigevent *notification
+)
+{
+ POSIX_Message_queue_Control *the_mq;
+ POSIX_Message_queue_Control_fd *the_mq_fd;
+ Objects_Locations location;
+
+ the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EBADF );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_LOCAL:
+ the_mq = the_mq_fd->Queue;
+
+ if ( notification ) {
+ if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( EBUSY );
+ }
+
+ _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
+
+ the_mq->notification = *notification;
+
+ _CORE_message_queue_Set_notify(
+ &the_mq->Message_queue,
+ _POSIX_Message_queue_Notify_handler,
+ the_mq
+ );
+ } else {
+
+ _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
+
+ }
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/mqueueopen.c b/cpukit/posix/src/mqueueopen.c
new file mode 100644
index 0000000000..8195e9d2af
--- /dev/null
+++ b/cpukit/posix/src/mqueueopen.c
@@ -0,0 +1,158 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 15.2.2 Open a Message Queue, P1003.1b-1993, p. 272
+ */
+
+mqd_t mq_open(
+ const char *name,
+ int oflag,
+ ...
+ /* mode_t mode, */
+ /* struct mq_attr attr */
+)
+{
+ va_list arg;
+ mode_t mode;
+ struct mq_attr *attr = NULL;
+ int status;
+ Objects_Id the_mq_id;
+ POSIX_Message_queue_Control *the_mq;
+ POSIX_Message_queue_Control_fd *the_mq_fd;
+ Objects_Locations location;
+
+ _Thread_Disable_dispatch();
+
+ if ( oflag & O_CREAT ) {
+ va_start(arg, oflag);
+ mode = (mode_t) va_arg( arg, unsigned int );
+ attr = (struct mq_attr *) va_arg( arg, struct mq_attr * );
+ va_end(arg);
+ }
+
+ the_mq_fd = _POSIX_Message_queue_Allocate_fd();
+ if ( !the_mq_fd ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( ENFILE );
+ }
+ the_mq_fd->oflag = oflag;
+
+ status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
+
+ /*
+ * If the name to id translation worked, then the message queue exists
+ * and we can just return a pointer to the id. Otherwise we may
+ * need to check to see if this is a "message queue does not exist"
+ * or some other miscellaneous error on the name.
+ */
+
+ if ( status ) {
+
+ /*
+ * Unless provided a valid name that did not already exist
+ * and we are willing to create then it is an error.
+ */
+
+ if ( !( status == ENOENT && (oflag & O_CREAT) ) ) {
+ _POSIX_Message_queue_Free_fd( the_mq_fd );
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one_cast( status, mqd_t );
+ }
+
+ } else { /* name -> ID translation succeeded */
+
+ /*
+ * Check for existence with creation.
+ */
+
+ if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
+ _POSIX_Message_queue_Free_fd( the_mq_fd );
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one_cast( EEXIST, mqd_t );
+ }
+
+ /*
+ * In this case we need to do an ID->pointer conversion to
+ * check the mode.
+ */
+
+ the_mq = _POSIX_Message_queue_Get( the_mq_id, &location );
+ the_mq->open_count += 1;
+ the_mq_fd->Queue = the_mq;
+ _Objects_Open(
+ &_POSIX_Message_queue_Information_fds,
+ &the_mq_fd->Object,
+ NULL
+ );
+ _Thread_Enable_dispatch();
+ _Thread_Enable_dispatch();
+ return (mqd_t)the_mq_fd->Object.id;
+
+ }
+
+ /*
+ * At this point, the message queue does not exist and everything has been
+ * checked. We should go ahead and create a message queue.
+ */
+
+ status = _POSIX_Message_queue_Create_support(
+ name,
+ TRUE, /* shared across processes */
+ attr,
+ &the_mq
+ );
+
+ /*
+ * errno was set by Create_support, so don't set it again.
+ */
+
+ if ( status == -1 ) {
+ _Thread_Enable_dispatch();
+ _POSIX_Message_queue_Free_fd( the_mq_fd );
+ return (mqd_t) -1;
+ }
+
+ the_mq_fd->Queue = the_mq;
+ _Objects_Open(
+ &_POSIX_Message_queue_Information_fds,
+ &the_mq_fd->Object,
+ NULL
+ );
+
+ _Thread_Enable_dispatch();
+
+ return (mqd_t) the_mq_fd->Object.id;
+}
diff --git a/cpukit/posix/src/mqueuereceive.c b/cpukit/posix/src/mqueuereceive.c
new file mode 100644
index 0000000000..e87d5fa8e9
--- /dev/null
+++ b/cpukit/posix/src/mqueuereceive.c
@@ -0,0 +1,56 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
+ *
+ * NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
+ */
+
+ssize_t mq_receive(
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio
+)
+{
+ return _POSIX_Message_queue_Receive_support(
+ mqdes,
+ msg_ptr,
+ msg_len,
+ msg_prio,
+ THREAD_QUEUE_WAIT_FOREVER
+ );
+}
diff --git a/cpukit/posix/src/mqueuerecvsupp.c b/cpukit/posix/src/mqueuerecvsupp.c
new file mode 100644
index 0000000000..6c2ca9e605
--- /dev/null
+++ b/cpukit/posix/src/mqueuerecvsupp.c
@@ -0,0 +1,107 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Receive_support
+ *
+ * NOTE: XXX Document how size, priority, length, and the buffer go
+ * through the layers.
+ */
+
+ssize_t _POSIX_Message_queue_Receive_support(
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio,
+ Watchdog_Interval timeout
+)
+{
+ POSIX_Message_queue_Control *the_mq;
+ POSIX_Message_queue_Control_fd *the_mq_fd;
+ Objects_Locations location;
+ uint32_t length_out;
+
+ the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EBADF );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_LOCAL:
+ if ( (the_mq_fd->oflag & O_ACCMODE) == O_WRONLY ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( EBADF );
+ }
+
+ the_mq = the_mq_fd->Queue;
+
+ if ( msg_len < the_mq->Message_queue.maximum_message_size ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( EMSGSIZE );
+ }
+
+ /*
+ * Now if something goes wrong, we return a "length" of -1
+ * to indicate an error.
+ */
+
+ length_out = -1;
+
+ _CORE_message_queue_Seize(
+ &the_mq->Message_queue,
+ mqdes,
+ msg_ptr,
+ &length_out,
+ (the_mq_fd->oflag & O_NONBLOCK) ? FALSE : TRUE,
+ timeout
+ );
+
+ _Thread_Enable_dispatch();
+ *msg_prio =
+ _POSIX_Message_queue_Priority_from_core(_Thread_Executing->Wait.count);
+
+ if ( !_Thread_Executing->Wait.return_code )
+ return length_out;
+
+ rtems_set_errno_and_return_minus_one(
+ _POSIX_Message_queue_Translate_core_message_queue_return_code(
+ _Thread_Executing->Wait.return_code
+ )
+ );
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/mqueuesend.c b/cpukit/posix/src/mqueuesend.c
new file mode 100644
index 0000000000..484fe72183
--- /dev/null
+++ b/cpukit/posix/src/mqueuesend.c
@@ -0,0 +1,56 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
+ *
+ * NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
+ */
+
+int mq_send(
+ mqd_t mqdes,
+ const char *msg_ptr,
+ size_t msg_len,
+ unsigned int msg_prio
+)
+{
+ return _POSIX_Message_queue_Send_support(
+ mqdes,
+ msg_ptr,
+ msg_len,
+ msg_prio,
+ THREAD_QUEUE_WAIT_FOREVER
+ );
+}
diff --git a/cpukit/posix/src/mqueuesendsupp.c b/cpukit/posix/src/mqueuesendsupp.c
new file mode 100644
index 0000000000..33109465e6
--- /dev/null
+++ b/cpukit/posix/src/mqueuesendsupp.c
@@ -0,0 +1,117 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Send_support
+ */
+
+int _POSIX_Message_queue_Send_support(
+ mqd_t mqdes,
+ const char *msg_ptr,
+ uint32_t msg_len,
+ uint32_t msg_prio,
+ Watchdog_Interval timeout
+)
+{
+ POSIX_Message_queue_Control *the_mq;
+ POSIX_Message_queue_Control_fd *the_mq_fd;
+ Objects_Locations location;
+ CORE_message_queue_Status msg_status;
+
+ /*
+ * Validate the priority.
+ * XXX - Do not validate msg_prio is not less than 0.
+ */
+
+ if ( msg_prio > MQ_PRIO_MAX )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EBADF );
+
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ case OBJECTS_LOCAL:
+ if ( (the_mq_fd->oflag & O_ACCMODE) == O_RDONLY ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( EBADF );
+ }
+
+ the_mq = the_mq_fd->Queue;
+
+ msg_status = _CORE_message_queue_Submit(
+ &the_mq->Message_queue,
+ (void *) msg_ptr,
+ msg_len,
+ mqdes, /* mqd_t is an object id */
+#if defined(RTEMS_MULTIPROCESSING)
+ NULL, /* XXX _POSIX_Message_queue_Core_message_queue_mp_support*/
+#else
+ NULL,
+#endif
+ _POSIX_Message_queue_Priority_to_core( msg_prio ),
+ (the_mq_fd->oflag & O_NONBLOCK) ? FALSE : TRUE,
+ timeout /* no timeout */
+ );
+
+ _Thread_Enable_dispatch();
+
+ /*
+ * If we had to block, then this is where the task returns
+ * after it wakes up. The returned status is correct for
+ * non-blocking operations but if we blocked, then we need
+ * to look at the status in our TCB.
+ */
+
+ if ( msg_status == CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT )
+ msg_status = _Thread_Executing->Wait.return_code;
+
+ if ( !msg_status )
+ return msg_status;
+
+ rtems_set_errno_and_return_minus_one(
+ _POSIX_Message_queue_Translate_core_message_queue_return_code(
+ msg_status
+ )
+ );
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/mqueuesetattr.c b/cpukit/posix/src/mqueuesetattr.c
new file mode 100644
index 0000000000..6d3b132ade
--- /dev/null
+++ b/cpukit/posix/src/mqueuesetattr.c
@@ -0,0 +1,81 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 15.2.7 Set Message Queue Attributes, P1003.1b-1993, p. 281
+ */
+
+int mq_setattr(
+ mqd_t mqdes,
+ const struct mq_attr *mqstat,
+ struct mq_attr *omqstat
+)
+{
+ POSIX_Message_queue_Control_fd *the_mq_fd;
+ CORE_message_queue_Control *the_core_mq;
+ Objects_Locations location;
+
+ if ( !mqstat )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EBADF );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_LOCAL:
+
+ the_core_mq = &the_mq_fd->Queue->Message_queue;
+
+ /*
+ * Return the old values.
+ */
+
+ if ( omqstat ) {
+ omqstat->mq_flags = the_mq_fd->oflag;
+ omqstat->mq_msgsize = the_core_mq->maximum_message_size;
+ omqstat->mq_maxmsg = the_core_mq->maximum_pending_messages;
+ omqstat->mq_curmsgs = the_core_mq->number_of_pending_messages;
+ }
+
+ the_mq_fd->oflag = mqstat->mq_flags;
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/mqueuetimedreceive.c b/cpukit/posix/src/mqueuetimedreceive.c
new file mode 100644
index 0000000000..2ad5f4c6d6
--- /dev/null
+++ b/cpukit/posix/src/mqueuetimedreceive.c
@@ -0,0 +1,57 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
+ *
+ * NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
+ */
+
+ssize_t mq_timedreceive(
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio,
+ const struct timespec *timeout
+)
+{
+ return _POSIX_Message_queue_Receive_support(
+ mqdes,
+ msg_ptr,
+ msg_len,
+ msg_prio,
+ _POSIX_Timespec_to_interval( timeout )
+ );
+}
diff --git a/cpukit/posix/src/mqueuetimedsend.c b/cpukit/posix/src/mqueuetimedsend.c
new file mode 100644
index 0000000000..89569368be
--- /dev/null
+++ b/cpukit/posix/src/mqueuetimedsend.c
@@ -0,0 +1,57 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
+ *
+ * NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
+ */
+
+int mq_timedsend(
+ mqd_t mqdes,
+ const char *msg_ptr,
+ size_t msg_len,
+ unsigned int msg_prio,
+ const struct timespec *timeout
+)
+{
+ return _POSIX_Message_queue_Send_support(
+ mqdes,
+ msg_ptr,
+ msg_len,
+ msg_prio,
+ _POSIX_Timespec_to_interval( timeout )
+ );
+}
diff --git a/cpukit/posix/src/mqueuetranslatereturncode.c b/cpukit/posix/src/mqueuetranslatereturncode.c
new file mode 100644
index 0000000000..74e67d0cf7
--- /dev/null
+++ b/cpukit/posix/src/mqueuetranslatereturncode.c
@@ -0,0 +1,101 @@
+/*
+ * POSIX Message Queue Error Translation
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+#include <rtems/score/interr.h>
+
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Translate_core_message_queue_return_code
+ *
+ * Input parameters:
+ * the_message_queue_status - message_queue status code to translate
+ *
+ * Output parameters:
+ * rtems status code - translated POSIX status code
+ *
+ */
+
+int _POSIX_Message_queue_Translate_core_message_queue_return_code(
+ uint32_t the_message_queue_status
+)
+{
+ switch ( the_message_queue_status ) {
+ case CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL:
+ return 0;
+
+ /*
+ * Bad message size
+ */
+ case CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE:
+ return EMSGSIZE;
+
+ /*
+ * Queue is full of pending messages.
+ */
+ case CORE_MESSAGE_QUEUE_STATUS_TOO_MANY:
+ return EAGAIN;
+
+ /*
+ * Out of message buffers to queue pending message
+ */
+ case CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED:
+ return ENOMEM;
+
+ /*
+ * No message available on receive poll
+ */
+ case CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT:
+ return EAGAIN;
+
+ /*
+ * Queue was deleted while thread blocked on it.
+ */
+ case CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED:
+ return EBADF;
+
+ /*
+ * POSIX Real-Time Extensions add timeouts to send and receive.
+ */
+ case CORE_MESSAGE_QUEUE_STATUS_TIMEOUT:
+ return ETIMEDOUT;
+
+ /*
+ * RTEMS POSIX API implementation does not support multiprocessing.
+ */
+ case THREAD_STATUS_PROXY_BLOCKING:
+ return ENOSYS;
+ }
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_POSIX_API,
+ TRUE,
+ the_message_queue_status
+ );
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/mqueueunlink.c b/cpukit/posix/src/mqueueunlink.c
new file mode 100644
index 0000000000..9f27cb6b61
--- /dev/null
+++ b/cpukit/posix/src/mqueueunlink.c
@@ -0,0 +1,87 @@
+/*
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 15.2.2 Remove a Message Queue, P1003.1b-1993, p. 276
+ */
+
+int mq_unlink(
+ const char *name
+)
+{
+ int status;
+ register POSIX_Message_queue_Control *the_mq;
+ Objects_Id the_mq_id;
+
+ _Thread_Disable_dispatch();
+
+ status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
+ if ( status != 0 ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( status );
+ }
+
+ /*
+ * Don't support unlinking a remote message queue.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id(the_mq_id) ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( ENOSYS );
+ }
+#endif
+
+ the_mq = (POSIX_Message_queue_Control *) _Objects_Get_local_object(
+ &_POSIX_Message_queue_Information,
+ _Objects_Get_index( the_mq_id )
+ );
+
+#if 0 && defined(RTEMS_MULTIPROCESSING)
+ if ( the_mq->process_shared == PTHREAD_PROCESS_SHARED ) {
+ _Objects_MP_Close( &_POSIX_Message_queue_Information, the_mq_id );
+ }
+#endif
+
+
+ the_mq->linked = FALSE;
+ _Workspace_Free( the_mq->Object.name );
+ _POSIX_Message_queue_Namespace_remove( the_mq );
+ _POSIX_Message_queue_Delete( the_mq );
+
+ _Thread_Enable_dispatch();
+ return 0;
+}
diff --git a/cpukit/posix/src/mutex.c b/cpukit/posix/src/mutex.c
new file mode 100644
index 0000000000..b7bde39167
--- /dev/null
+++ b/cpukit/posix/src/mutex.c
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Mutex_Manager_initialization
+ *
+ * This routine initializes all mutex manager related data structures.
+ *
+ * Input parameters:
+ * maximum_mutexes - maximum configured mutexes
+ *
+ * Output parameters: NONE
+ */
+
+void _POSIX_Mutex_Manager_initialization(
+ uint32_t maximum_mutexes
+)
+{
+ _Objects_Initialize_information(
+ &_POSIX_Mutex_Information, /* object information table */
+ OBJECTS_POSIX_API, /* object API */
+ OBJECTS_POSIX_MUTEXES, /* object class */
+ maximum_mutexes, /* maximum objects of this class */
+ sizeof( POSIX_Mutex_Control ),
+ /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ 0 /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+}
diff --git a/cpukit/posix/src/mutexattrdestroy.c b/cpukit/posix/src/mutexattrdestroy.c
new file mode 100644
index 0000000000..429dbeaee2
--- /dev/null
+++ b/cpukit/posix/src/mutexattrdestroy.c
@@ -0,0 +1,37 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
+ */
+
+int pthread_mutexattr_destroy(
+ pthread_mutexattr_t *attr
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->is_initialized = FALSE;
+ return 0;
+}
diff --git a/cpukit/posix/src/mutexattrgetprioceiling.c b/cpukit/posix/src/mutexattrgetprioceiling.c
new file mode 100644
index 0000000000..f0ef90b61f
--- /dev/null
+++ b/cpukit/posix/src/mutexattrgetprioceiling.c
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
+ */
+
+int pthread_mutexattr_getprioceiling(
+ const pthread_mutexattr_t *attr,
+ int *prioceiling
+)
+{
+ if ( !attr || !attr->is_initialized || !prioceiling )
+ return EINVAL;
+
+ *prioceiling = attr->prio_ceiling;
+ return 0;
+}
diff --git a/cpukit/posix/src/mutexattrgetprotocol.c b/cpukit/posix/src/mutexattrgetprotocol.c
new file mode 100644
index 0000000000..2537ba00bf
--- /dev/null
+++ b/cpukit/posix/src/mutexattrgetprotocol.c
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
+ */
+
+int pthread_mutexattr_getprotocol(
+ const pthread_mutexattr_t *attr,
+ int *protocol
+)
+{
+ if ( !attr || !attr->is_initialized || !protocol )
+ return EINVAL;
+
+ *protocol = attr->protocol;
+ return 0;
+}
diff --git a/cpukit/posix/src/mutexattrgetpshared.c b/cpukit/posix/src/mutexattrgetpshared.c
new file mode 100644
index 0000000000..3374b250ba
--- /dev/null
+++ b/cpukit/posix/src/mutexattrgetpshared.c
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
+ */
+
+int pthread_mutexattr_getpshared(
+ const pthread_mutexattr_t *attr,
+ int *pshared
+)
+{
+ if ( !attr || !attr->is_initialized || !pshared )
+ return EINVAL;
+
+ *pshared = attr->process_shared;
+ return 0;
+}
diff --git a/cpukit/posix/src/mutexattrinit.c b/cpukit/posix/src/mutexattrinit.c
new file mode 100644
index 0000000000..0cd6783ce8
--- /dev/null
+++ b/cpukit/posix/src/mutexattrinit.c
@@ -0,0 +1,37 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
+ */
+
+int pthread_mutexattr_init(
+ pthread_mutexattr_t *attr
+)
+{
+ if ( !attr )
+ return EINVAL;
+
+ *attr = _POSIX_Mutex_Default_attributes;
+ return 0;
+}
diff --git a/cpukit/posix/src/mutexattrsetprioceiling.c b/cpukit/posix/src/mutexattrsetprioceiling.c
new file mode 100644
index 0000000000..da34a2fbb3
--- /dev/null
+++ b/cpukit/posix/src/mutexattrsetprioceiling.c
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
+ */
+
+int pthread_mutexattr_setprioceiling(
+ pthread_mutexattr_t *attr,
+ int prioceiling
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ if ( !_POSIX_Priority_Is_valid( prioceiling ) )
+ return EINVAL;
+
+ attr->prio_ceiling = prioceiling;
+ return 0;
+}
diff --git a/cpukit/posix/src/mutexattrsetprotocol.c b/cpukit/posix/src/mutexattrsetprotocol.c
new file mode 100644
index 0000000000..2f74abf3d2
--- /dev/null
+++ b/cpukit/posix/src/mutexattrsetprotocol.c
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
+ */
+
+int pthread_mutexattr_setprotocol(
+ pthread_mutexattr_t *attr,
+ int protocol
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ switch ( protocol ) {
+ case PTHREAD_PRIO_NONE:
+ case PTHREAD_PRIO_INHERIT:
+ case PTHREAD_PRIO_PROTECT:
+ attr->protocol = protocol;
+ return 0;
+
+ default:
+ return EINVAL;
+ }
+}
diff --git a/cpukit/posix/src/mutexattrsetpshared.c b/cpukit/posix/src/mutexattrsetpshared.c
new file mode 100644
index 0000000000..10d7a80647
--- /dev/null
+++ b/cpukit/posix/src/mutexattrsetpshared.c
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
+ */
+
+int pthread_mutexattr_setpshared(
+ pthread_mutexattr_t *attr,
+ int pshared
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ switch ( pshared ) {
+ case PTHREAD_PROCESS_SHARED:
+ case PTHREAD_PROCESS_PRIVATE:
+ attr->process_shared = pshared;
+ return 0;
+
+ default:
+ return EINVAL;
+ }
+}
diff --git a/cpukit/posix/src/mutexdefaultattributes.c b/cpukit/posix/src/mutexdefaultattributes.c
new file mode 100644
index 0000000000..bdca71a43b
--- /dev/null
+++ b/cpukit/posix/src/mutexdefaultattributes.c
@@ -0,0 +1,34 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * The default mutex attributes structure.
+ */
+
+const pthread_mutexattr_t _POSIX_Mutex_Default_attributes = {
+ TRUE, /* is_initialized */
+ PTHREAD_PROCESS_PRIVATE, /* process_shared */
+ POSIX_SCHEDULER_MAXIMUM_PRIORITY, /* prio_ceiling */
+ PTHREAD_PRIO_NONE, /* protocol */
+ FALSE /* recursive */
+};
diff --git a/cpukit/posix/src/mutexdestroy.c b/cpukit/posix/src/mutexdestroy.c
new file mode 100644
index 0000000000..f4210148cd
--- /dev/null
+++ b/cpukit/posix/src/mutexdestroy.c
@@ -0,0 +1,87 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
+ */
+
+int pthread_mutex_destroy(
+ pthread_mutex_t *mutex
+)
+{
+ register POSIX_Mutex_Control *the_mutex;
+ Objects_Locations location;
+
+ the_mutex = _POSIX_Mutex_Get( mutex, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ return EINVAL;
+#endif
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_LOCAL:
+ /*
+ * XXX: There is an error for the mutex being locked
+ * or being in use by a condition variable.
+ */
+
+ if ( _CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
+ _Thread_Enable_dispatch();
+ return EBUSY;
+ }
+
+ _Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
+
+ _CORE_mutex_Flush(
+ &the_mutex->Mutex,
+#if defined(RTEMS_MULTIPROCESSING)
+ _POSIX_Mutex_MP_Send_object_was_deleted,
+#else
+ NULL,
+#endif
+ EINVAL
+ );
+
+ _POSIX_Mutex_Free( the_mutex );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_mutex->process_shared == PTHREAD_PROCESS_SHARED ) {
+
+ _Objects_MP_Close( &_POSIX_Mutex_Information, the_mutex->Object.id );
+
+ _POSIX_Mutex_MP_Send_process_packet(
+ POSIX_MUTEX_MP_ANNOUNCE_DELETE,
+ the_mutex->Object.id,
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+ }
+#endif
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/mutexfromcorestatus.c b/cpukit/posix/src/mutexfromcorestatus.c
new file mode 100644
index 0000000000..3c6f617861
--- /dev/null
+++ b/cpukit/posix/src/mutexfromcorestatus.c
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Mutex_From_core_mutex_status
+ */
+
+int _POSIX_Mutex_From_core_mutex_status(
+ CORE_mutex_Status status
+)
+{
+ switch ( status ) {
+ case CORE_MUTEX_STATUS_SUCCESSFUL:
+ return 0;
+ case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
+ return EBUSY;
+ case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
+ return EDEADLK;
+ case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
+ return EPERM;
+ case CORE_MUTEX_WAS_DELETED:
+ return EINVAL;
+ case CORE_MUTEX_TIMEOUT:
+ return EAGAIN;
+ case CORE_MUTEX_STATUS_CEILING_VIOLATED:
+ return EINVAL;
+ default:
+ break;
+ }
+ assert( 0 );
+ return 0;
+}
diff --git a/cpukit/posix/src/mutexgetprioceiling.c b/cpukit/posix/src/mutexgetprioceiling.c
new file mode 100644
index 0000000000..4e43325560
--- /dev/null
+++ b/cpukit/posix/src/mutexgetprioceiling.c
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
+ */
+
+int pthread_mutex_getprioceiling(
+ pthread_mutex_t *mutex,
+ int *prioceiling
+)
+{
+ register POSIX_Mutex_Control *the_mutex;
+ Objects_Locations location;
+
+ if ( !prioceiling )
+ return EINVAL;
+
+ the_mutex = _POSIX_Mutex_Get( mutex, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return POSIX_MP_NOT_IMPLEMENTED(); /* XXX feels questionable */
+#endif
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_LOCAL:
+ *prioceiling = _POSIX_Priority_From_core(
+ the_mutex->Mutex.Attributes.priority_ceiling
+ );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/mutexinit.c b/cpukit/posix/src/mutexinit.c
new file mode 100644
index 0000000000..3af8c1d621
--- /dev/null
+++ b/cpukit/posix/src/mutexinit.c
@@ -0,0 +1,186 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
+ *
+ * NOTE: XXX Could be optimized so all the attribute error checking
+ * is not performed when attr is NULL.
+ */
+
+int pthread_mutex_init(
+ pthread_mutex_t *mutex,
+ const pthread_mutexattr_t *attr
+)
+{
+ POSIX_Mutex_Control *the_mutex;
+ CORE_mutex_Attributes *the_mutex_attr;
+ const pthread_mutexattr_t *the_attr;
+ CORE_mutex_Disciplines the_discipline;
+#if 0
+ register POSIX_Mutex_Control *mutex_in_use;
+ Objects_Locations location;
+#endif
+
+ if ( attr ) the_attr = attr;
+ else the_attr = &_POSIX_Mutex_Default_attributes;
+
+ /* Check for NULL mutex */
+
+ if ( !mutex )
+ return EINVAL;
+
+ /*
+ * This code should eventually be removed.
+ *
+ * Although the POSIX specification says:
+ *
+ * "Attempting to initialize an already initialized mutex results
+ * in undefined behavior."
+ *
+ * Trying to keep the caller from doing the create when *mutex
+ * is actually a valid ID causes grief. All it takes is the wrong
+ * value in an uninitialized variable to make this fail. As best
+ * I can tell, RTEMS was the only pthread implementation to choose
+ * this option for "undefined behavior" and doing so has created
+ * portability problems. In particular, Rosimildo DaSilva
+ * <rdasilva@connecttel.com> saw seemingly random failures in the
+ * RTEMS port of omniORB2 when this code was enabled.
+ *
+ * Joel Sherrill <joel@OARcorp.com> 14 May 1999
+ */
+
+
+#if 0
+ /* avoid infinite recursion on call to this routine in _POSIX_Mutex_Get */
+
+ if ( *mutex != PTHREAD_MUTEX_INITIALIZER ) {
+
+ /* EBUSY if *mutex is a valid id */
+
+ mutex_in_use = _POSIX_Mutex_Get( mutex, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ case OBJECTS_ERROR:
+ break;
+ case OBJECTS_LOCAL:
+ _Thread_Enable_dispatch();
+ return EBUSY;
+ }
+ }
+#endif
+
+ if ( !the_attr->is_initialized )
+ return EINVAL;
+
+ /*
+ * XXX: Be careful about attributes when global!!!
+ */
+
+ assert( the_attr->process_shared == PTHREAD_PROCESS_PRIVATE );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
+ return POSIX_MP_NOT_IMPLEMENTED();
+#endif
+
+ /*
+ * Determine the discipline of the mutex
+ */
+
+ switch ( the_attr->protocol ) {
+ case PTHREAD_PRIO_NONE:
+ the_discipline = CORE_MUTEX_DISCIPLINES_FIFO;
+ break;
+ case PTHREAD_PRIO_INHERIT:
+ the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
+ break;
+ case PTHREAD_PRIO_PROTECT:
+ the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ if ( !_POSIX_Priority_Is_valid( the_attr->prio_ceiling ) )
+ return EINVAL;
+
+ _Thread_Disable_dispatch();
+
+ the_mutex = _POSIX_Mutex_Allocate();
+
+ if ( !the_mutex ) {
+ _Thread_Enable_dispatch();
+ return EAGAIN;
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&
+ !( _Objects_MP_Allocate_and_open( &_POSIX_Mutex_Information, 0,
+ the_mutex->Object.id, FALSE ) ) ) {
+ _POSIX_Mutex_Free( the_mutex );
+ _Thread_Enable_dispatch();
+ return EAGAIN;
+ }
+#endif
+
+ the_mutex->process_shared = the_attr->process_shared;
+
+ the_mutex_attr = &the_mutex->Mutex.Attributes;
+
+ if ( the_attr->recursive )
+ the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
+ else
+ the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
+ the_mutex_attr->only_owner_release = TRUE;
+ the_mutex_attr->priority_ceiling =
+ _POSIX_Priority_To_core( the_attr->prio_ceiling );
+ the_mutex_attr->discipline = the_discipline;
+
+ /*
+ * Must be initialized to unlocked.
+ */
+
+ _CORE_mutex_Initialize(
+ &the_mutex->Mutex,
+ the_mutex_attr,
+ CORE_MUTEX_UNLOCKED
+ );
+
+ _Objects_Open( &_POSIX_Mutex_Information, &the_mutex->Object, 0 );
+
+ *mutex = the_mutex->Object.id;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
+ _POSIX_Mutex_MP_Send_process_packet(
+ POSIX_MUTEX_MP_ANNOUNCE_CREATE,
+ the_mutex->Object.id,
+ 0, /* Name not used */
+ 0 /* Not used */
+ );
+#endif
+
+ _Thread_Enable_dispatch();
+ return 0;
+}
diff --git a/cpukit/posix/src/mutexlock.c b/cpukit/posix/src/mutexlock.c
new file mode 100644
index 0000000000..b040dc08d4
--- /dev/null
+++ b/cpukit/posix/src/mutexlock.c
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
+ *
+ * NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
+ */
+
+int pthread_mutex_lock(
+ pthread_mutex_t *mutex
+)
+{
+ return _POSIX_Mutex_Lock_support( mutex, TRUE, THREAD_QUEUE_WAIT_FOREVER );
+}
diff --git a/cpukit/posix/src/mutexlocksupp.c b/cpukit/posix/src/mutexlocksupp.c
new file mode 100644
index 0000000000..9e8ee10172
--- /dev/null
+++ b/cpukit/posix/src/mutexlocksupp.c
@@ -0,0 +1,67 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Mutex_Lock_support
+ *
+ * A support routine which implements guts of the blocking, non-blocking, and
+ * timed wait version of mutex lock.
+ */
+
+int _POSIX_Mutex_Lock_support(
+ pthread_mutex_t *mutex,
+ boolean blocking,
+ Watchdog_Interval timeout
+)
+{
+ register POSIX_Mutex_Control *the_mutex;
+ Objects_Locations location;
+ ISR_Level level;
+
+ the_mutex = _POSIX_Mutex_Get_interrupt_disable( mutex, &location, &level );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return _POSIX_Mutex_MP_Send_request_packet(
+ POSIX_MUTEX_MP_OBTAIN_REQUEST,
+ *mutex,
+ 0, /* must define the option set */
+ WATCHDOG_NO_TIMEOUT
+ );
+#endif
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_LOCAL:
+ _CORE_mutex_Seize(
+ &the_mutex->Mutex,
+ the_mutex->Object.id,
+ blocking,
+ timeout,
+ level
+ );
+ return _POSIX_Mutex_From_core_mutex_status(
+ (CORE_mutex_Status) _Thread_Executing->Wait.return_code
+ );
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/mutexmp.c b/cpukit/posix/src/mutexmp.c
new file mode 100644
index 0000000000..75db779ce4
--- /dev/null
+++ b/cpukit/posix/src/mutexmp.c
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*
+ * TEMPORARY
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+void _POSIX_Mutex_MP_Send_process_packet (
+ POSIX_Mutex_MP_Remote_operations operation,
+ Objects_Id mutex_id,
+ Objects_Name name,
+ Objects_Id proxy_id
+)
+{
+ (void) POSIX_MP_NOT_IMPLEMENTED();
+}
+
+void _POSIX_Mutex_MP_Send_object_was_deleted (
+ Thread_Control *the_proxy
+)
+{
+ (void) POSIX_MP_NOT_IMPLEMENTED();
+}
+
+int _POSIX_Mutex_MP_Send_request_packet (
+ POSIX_Mutex_MP_Remote_operations operation,
+ Objects_Id mutex_id,
+ boolean wait, /* XXX options */
+ Watchdog_Interval timeout
+)
+{
+ return POSIX_MP_NOT_IMPLEMENTED();
+}
+
+void _POSIX_Threads_mutex_MP_support(
+ Thread_Control *the_thread,
+ Objects_Id id
+)
+{
+ (void) POSIX_MP_NOT_IMPLEMENTED(); /* XXX: should never get here */
+}
+#endif
+
+/*
+ * END OF TEMPORARY
+ */
diff --git a/cpukit/posix/src/mutexsetprioceiling.c b/cpukit/posix/src/mutexsetprioceiling.c
new file mode 100644
index 0000000000..60c82a4f19
--- /dev/null
+++ b/cpukit/posix/src/mutexsetprioceiling.c
@@ -0,0 +1,82 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
+ */
+
+int pthread_mutex_setprioceiling(
+ pthread_mutex_t *mutex,
+ int prioceiling,
+ int *old_ceiling
+)
+{
+ register POSIX_Mutex_Control *the_mutex;
+ Objects_Locations location;
+ Priority_Control the_priority;
+ int status;
+
+ if ( !old_ceiling )
+ return EINVAL;
+
+ if ( !_POSIX_Priority_Is_valid( prioceiling ) )
+ return EINVAL;
+
+ the_priority = _POSIX_Priority_To_core( prioceiling );
+
+ /*
+ * Must acquire the mutex before we can change it's ceiling
+ */
+
+ status = pthread_mutex_lock( mutex );
+ if ( status )
+ return status;
+
+ the_mutex = _POSIX_Mutex_Get( mutex, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ /* XXX It feels questionable to set the ceiling on a remote mutex. */
+ return EINVAL;
+#endif
+ case OBJECTS_ERROR:
+ return EINVAL; /* impossible to get here */
+ case OBJECTS_LOCAL:
+ *old_ceiling = _POSIX_Priority_From_core(
+ the_mutex->Mutex.Attributes.priority_ceiling
+ );
+ the_mutex->Mutex.Attributes.priority_ceiling = the_priority;
+ _CORE_mutex_Surrender(
+ &the_mutex->Mutex,
+ the_mutex->Object.id,
+#if defined(RTEMS_MULTIPROCESSING)
+ _POSIX_Threads_mutex_MP_support
+#else
+ NULL
+#endif
+ );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/mutextimedlock.c b/cpukit/posix/src/mutextimedlock.c
new file mode 100644
index 0000000000..6555f5a4d2
--- /dev/null
+++ b/cpukit/posix/src/mutextimedlock.c
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
+ *
+ * NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
+ */
+
+int pthread_mutex_timedlock(
+ pthread_mutex_t *mutex,
+ const struct timespec *timeout
+)
+{
+ return _POSIX_Mutex_Lock_support(
+ mutex,
+ TRUE,
+ _POSIX_Timespec_to_interval( timeout )
+ );
+}
diff --git a/cpukit/posix/src/mutextrylock.c b/cpukit/posix/src/mutextrylock.c
new file mode 100644
index 0000000000..68df754b0a
--- /dev/null
+++ b/cpukit/posix/src/mutextrylock.c
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
+ *
+ * NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
+ */
+
+int pthread_mutex_trylock(
+ pthread_mutex_t *mutex
+)
+{
+ return _POSIX_Mutex_Lock_support( mutex, FALSE, THREAD_QUEUE_WAIT_FOREVER );
+}
diff --git a/cpukit/posix/src/mutexunlock.c b/cpukit/posix/src/mutexunlock.c
new file mode 100644
index 0000000000..b88ae4c269
--- /dev/null
+++ b/cpukit/posix/src/mutexunlock.c
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
+ *
+ * NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
+ */
+
+int pthread_mutex_unlock(
+ pthread_mutex_t *mutex
+)
+{
+ register POSIX_Mutex_Control *the_mutex;
+ Objects_Locations location;
+ CORE_mutex_Status status;
+
+ the_mutex = _POSIX_Mutex_Get( mutex, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return _POSIX_Mutex_MP_Send_request_packet(
+ POSIX_MUTEX_MP_RELEASE_REQUEST,
+ *mutex,
+ 0, /* Not used */
+ MPCI_DEFAULT_TIMEOUT
+ );
+#endif
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_LOCAL:
+ status = _CORE_mutex_Surrender(
+ &the_mutex->Mutex,
+ the_mutex->Object.id,
+#if defined(RTEMS_MULTIPROCESSING)
+ _POSIX_Threads_mutex_MP_support
+#else
+ NULL
+#endif
+ );
+ _Thread_Enable_dispatch();
+ return _POSIX_Mutex_From_core_mutex_status( status );
+ break;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c
new file mode 100644
index 0000000000..06fc1bc5cb
--- /dev/null
+++ b/cpukit/posix/src/nanosleep.c
@@ -0,0 +1,104 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
+ */
+
+int nanosleep(
+ const struct timespec *rqtp,
+ struct timespec *rmtp
+)
+{
+ Watchdog_Interval ticks;
+ struct timespec *the_rqtp;
+
+ if ( !rqtp )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ the_rqtp = (struct timespec *)rqtp;
+
+ /*
+ * Return EAGAIN if the delay interval is negative.
+ *
+ * NOTE: This behavior is beyond the POSIX specification.
+ * FSU pthreads shares this behavior.
+ */
+
+ if ( the_rqtp->tv_sec < 0 )
+ the_rqtp->tv_sec = 0;
+
+ if ( /* the_rqtp->tv_sec < 0 || */ the_rqtp->tv_nsec < 0 )
+ rtems_set_errno_and_return_minus_one( EAGAIN );
+
+ if ( the_rqtp->tv_nsec >= TOD_NANOSECONDS_PER_SECOND )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ ticks = _POSIX_Timespec_to_interval( the_rqtp );
+
+ /*
+ * This behavior is also beyond the POSIX specification but is
+ * consistent with the RTEMS api and yields desirable behavior.
+ */
+
+ if ( !ticks ) {
+ _Thread_Disable_dispatch();
+ _Thread_Yield_processor();
+ _Thread_Enable_dispatch();
+ if ( rmtp ) {
+ rmtp->tv_sec = 0;
+ rmtp->tv_nsec = 0;
+ }
+ return 0;
+ }
+
+ _Thread_Disable_dispatch();
+ _Thread_Set_state(
+ _Thread_Executing,
+ STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL
+ );
+ _Watchdog_Initialize(
+ &_Thread_Executing->Timer,
+ _Thread_Delay_ended,
+ _Thread_Executing->Object.id,
+ NULL
+ );
+ _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks );
+ _Thread_Enable_dispatch();
+
+ /* calculate time remaining */
+
+ if ( rmtp ) {
+ ticks -=
+ _Thread_Executing->Timer.stop_time - _Thread_Executing->Timer.start_time;
+
+ _POSIX_Interval_to_timespec( ticks, rmtp );
+
+ /*
+ * If there is time remaining, then we were interrupted by a signal.
+ */
+
+ if ( ticks )
+ rtems_set_errno_and_return_minus_one( EINTR );
+ }
+
+ return 0;
+}
diff --git a/cpukit/posix/src/pause.c b/cpukit/posix/src/pause.c
new file mode 100644
index 0000000000..e4a8782bc4
--- /dev/null
+++ b/cpukit/posix/src/pause.c
@@ -0,0 +1,40 @@
+/*
+ * 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 81
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+
+/*
+ * 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 81
+ */
+
+int pause( void )
+{
+ sigset_t all_signals;
+ int status;
+
+ (void) sigfillset( &all_signals );
+
+ status = sigtimedwait( &all_signals, NULL, NULL );
+
+ return status;
+}
diff --git a/cpukit/posix/src/posixintervaltotimespec.c b/cpukit/posix/src/posixintervaltotimespec.c
new file mode 100644
index 0000000000..916b890d8a
--- /dev/null
+++ b/cpukit/posix/src/posixintervaltotimespec.c
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Interval_to_timespec
+ */
+
+void _POSIX_Interval_to_timespec(
+ Watchdog_Interval ticks,
+ struct timespec *time
+)
+{
+ uint32_t usecs;
+
+ usecs = ticks * _TOD_Microseconds_per_tick;
+
+ time->tv_sec = usecs / TOD_MICROSECONDS_PER_SECOND;
+ time->tv_nsec = (usecs % TOD_MICROSECONDS_PER_SECOND) *
+ TOD_NANOSECONDS_PER_MICROSECOND;
+}
diff --git a/cpukit/posix/src/posixtimespecsubtract.c b/cpukit/posix/src/posixtimespecsubtract.c
new file mode 100644
index 0000000000..0fa611b6ea
--- /dev/null
+++ b/cpukit/posix/src/posixtimespecsubtract.c
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Timespec_subtract
+ */
+
+void _POSIX_Timespec_subtract(
+ const struct timespec *the_start,
+ const struct timespec *end,
+ struct timespec *result
+)
+{
+ struct timespec start_struct = *the_start;
+ struct timespec *start = &start_struct;
+ uint32_t nsecs_per_sec = TOD_NANOSECONDS_PER_SECOND;
+
+ if (end->tv_nsec < start->tv_nsec) {
+ int seconds = (start->tv_nsec - end->tv_nsec) / nsecs_per_sec + 1;
+ start->tv_nsec -= nsecs_per_sec * seconds;
+ start->tv_sec += seconds;
+ }
+
+ if (end->tv_nsec - start->tv_nsec > nsecs_per_sec) {
+ int seconds = (start->tv_nsec - end->tv_nsec) / nsecs_per_sec;
+ start->tv_nsec += nsecs_per_sec * seconds;
+ start->tv_sec -= seconds;
+ }
+
+ result->tv_sec = end->tv_sec - start->tv_sec;
+ result->tv_nsec = end->tv_nsec - start->tv_nsec;
+}
diff --git a/cpukit/posix/src/posixtimespectointerval.c b/cpukit/posix/src/posixtimespectointerval.c
new file mode 100644
index 0000000000..3e4d5cf130
--- /dev/null
+++ b/cpukit/posix/src/posixtimespectointerval.c
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Timespec_to_interval
+ */
+
+Watchdog_Interval _POSIX_Timespec_to_interval(
+ const struct timespec *time
+)
+{
+ Watchdog_Interval ticks;
+
+ ticks = (time->tv_sec * TOD_MICROSECONDS_PER_SECOND) /
+ _TOD_Microseconds_per_tick;
+
+ ticks += (time->tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND) /
+ _TOD_Microseconds_per_tick;
+
+ if (ticks)
+ return ticks;
+
+ return 1;
+}
diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c
new file mode 100644
index 0000000000..be8a7dadf4
--- /dev/null
+++ b/cpukit/posix/src/psignal.c
@@ -0,0 +1,206 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h> /* memcpy */
+#include <stdlib.h> /* exit */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tqdata.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/threadsup.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/time.h>
+#include <stdio.h>
+
+/*** PROCESS WIDE STUFF ****/
+
+sigset_t _POSIX_signals_Pending;
+
+void _POSIX_signals_Abnormal_termination_handler( int signo )
+{
+ exit( 1 );
+}
+
+#define SIG_ARRAY_MAX (SIGRTMAX + 1)
+struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = {
+ /* NO SIGNAL 0 */ SIGACTION_IGNORE,
+ /* SIGHUP 1 */ SIGACTION_TERMINATE,
+ /* SIGINT 2 */ SIGACTION_TERMINATE,
+ /* SIGQUIT 3 */ SIGACTION_TERMINATE,
+ /* SIGILL 4 */ SIGACTION_TERMINATE,
+ /* SIGTRAP 5 */ SIGACTION_TERMINATE,
+ /* SIGIOT 6 */ SIGACTION_TERMINATE,
+ /* SIGABRT 6 SIGACTION_TERMINATE, -- alias for SIGIOT */
+ /* SIGEMT 7 */ SIGACTION_TERMINATE,
+ /* SIGFPE 8 */ SIGACTION_TERMINATE,
+ /* SIGKILL 9 */ SIGACTION_TERMINATE,
+ /* SIGBUS 10 */ SIGACTION_TERMINATE,
+ /* SIGSEGV 11 */ SIGACTION_TERMINATE,
+ /* SIGSYS 12 */ SIGACTION_TERMINATE,
+ /* SIGPIPE 13 */ SIGACTION_TERMINATE,
+ /* SIGALRM 14 */ SIGACTION_TERMINATE,
+ /* SIGTERM 15 */ SIGACTION_TERMINATE,
+ /* SIGURG 16 */ SIGACTION_TERMINATE,
+ /* SIGSTOP 17 */ SIGACTION_TERMINATE,
+ /* SIGTSTP 18 */ SIGACTION_TERMINATE,
+ /* SIGCONT 19 */ SIGACTION_TERMINATE,
+ /* SIGCHLD 20 */ SIGACTION_TERMINATE,
+ /* SIGTTIN 21 */ SIGACTION_TERMINATE,
+ /* SIGTTOU 22 */ SIGACTION_TERMINATE,
+ /* SIGIO 23 */ SIGACTION_TERMINATE,
+ /* SIGWINCH 24 */ SIGACTION_TERMINATE,
+ /* SIGUSR1 25 */ SIGACTION_TERMINATE,
+ /* SIGUSR2 26 */ SIGACTION_TERMINATE,
+ /* SIGRT 27 */ SIGACTION_TERMINATE,
+ /* SIGRT 28 */ SIGACTION_TERMINATE,
+ /* SIGRT 29 */ SIGACTION_TERMINATE,
+ /* SIGRT 30 */ SIGACTION_TERMINATE,
+ /* SIGRTMAX 31 */ SIGACTION_TERMINATE
+};
+
+struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ];
+
+Thread_queue_Control _POSIX_signals_Wait_queue;
+
+Chain_Control _POSIX_signals_Inactive_siginfo;
+Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
+
+/*PAGE
+ *
+ * XXX - move these
+ */
+
+#define _States_Is_interruptible_signal( _states ) \
+ ( ((_states) & \
+ (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \
+ (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL))
+
+/*
+ * _POSIX_signals_Post_switch_extension
+ */
+
+void _POSIX_signals_Post_switch_extension(
+ Thread_Control *the_thread
+)
+{
+ POSIX_API_Control *api;
+ int signo;
+ ISR_Level level;
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ /*
+ * If we invoke any user code, there is the possibility that
+ * a new signal has been posted that we should process so we
+ * restart the loop if a signal handler was invoked.
+ *
+ * The first thing done is to check there are any signals to be
+ * processed at all. No point in doing this loop otherwise.
+ */
+
+restart:
+ _ISR_Disable( level );
+ if ( !(~api->signals_blocked &
+ (api->signals_pending | _POSIX_signals_Pending)) ) {
+ _ISR_Enable( level );
+ return;
+ }
+ _ISR_Enable( level );
+
+ for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
+
+ if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
+ goto restart;
+
+ if ( _POSIX_signals_Check_signal( api, signo, TRUE ) )
+ goto restart;
+
+ }
+
+/* XXX - add __SIGFIRSTNOTRT or something like that to newlib signal .h */
+
+ for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) {
+
+ if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
+ goto restart;
+
+ if ( _POSIX_signals_Check_signal( api, signo, TRUE ) )
+ goto restart;
+
+ }
+
+}
+
+/*PAGE
+ *
+ * _POSIX_signals_Manager_Initialization
+ */
+
+void _POSIX_signals_Manager_Initialization(
+ int maximum_queued_signals
+)
+{
+ uint32_t signo;
+
+ /*
+ * Ensure we have the same number of vectors and default vector entries
+ */
+
+ assert(
+ sizeof(_POSIX_signals_Vectors) == sizeof(_POSIX_signals_Default_vectors)
+ );
+
+ memcpy(
+ _POSIX_signals_Vectors,
+ _POSIX_signals_Default_vectors,
+ sizeof( _POSIX_signals_Vectors )
+ );
+
+ /*
+ * Initialize the set of pending signals for the entire process
+ */
+
+ sigemptyset( &_POSIX_signals_Pending );
+
+ /*
+ * Initialize the queue we use to block for signals
+ */
+
+ _Thread_queue_Initialize(
+ &_POSIX_signals_Wait_queue,
+ THREAD_QUEUE_DISCIPLINE_PRIORITY,
+ STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL,
+ EAGAIN
+ );
+
+ /* XXX status codes */
+
+ /*
+ * Allocate the siginfo pools.
+ */
+
+ for ( signo=1 ; signo<= SIGRTMAX ; signo++ )
+ _Chain_Initialize_empty( &_POSIX_signals_Siginfo[ signo ] );
+
+ _Chain_Initialize(
+ &_POSIX_signals_Inactive_siginfo,
+ _Workspace_Allocate_or_fatal_error(
+ maximum_queued_signals * sizeof( POSIX_signals_Siginfo_node )
+ ),
+ maximum_queued_signals,
+ sizeof( POSIX_signals_Siginfo_node )
+ );
+}
diff --git a/cpukit/posix/src/psignalchecksignal.c b/cpukit/posix/src/psignalchecksignal.c
new file mode 100644
index 0000000000..0da7887afd
--- /dev/null
+++ b/cpukit/posix/src/psignalchecksignal.c
@@ -0,0 +1,93 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tqdata.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/threadsup.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/time.h>
+#include <stdio.h>
+
+
+/*PAGE
+ *
+ * _POSIX_signals_Check_signal
+ */
+
+boolean _POSIX_signals_Check_signal(
+ POSIX_API_Control *api,
+ int signo,
+ boolean is_global
+)
+{
+ siginfo_t siginfo_struct;
+ sigset_t saved_signals_blocked;
+
+ if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct,
+ is_global, TRUE ) )
+ return FALSE;
+
+ /*
+ * Since we made a union of these, only one test is necessary but this is
+ * safer.
+ */
+
+ assert( _POSIX_signals_Vectors[ signo ].sa_handler ||
+ _POSIX_signals_Vectors[ signo ].sa_sigaction );
+
+ /*
+ * Just to prevent sending a signal which is currently being ignored.
+ */
+
+ if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN )
+ return FALSE;
+
+ /*
+ * Block the signals requested in sa_mask
+ */
+
+ saved_signals_blocked = api->signals_blocked;
+ api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask;
+
+ /* Here, the signal handler function executes */
+
+ switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
+ case SA_SIGINFO:
+/*
+ *
+ * assert( is_global );
+ */
+ (*_POSIX_signals_Vectors[ signo ].sa_sigaction)(
+ signo,
+ &siginfo_struct,
+ NULL /* context is undefined per 1003.1b-1993, p. 66 */
+ );
+ break;
+ default:
+ (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo );
+ break;
+ }
+
+ /*
+ * Restore the previous set of blocked signals
+ */
+
+ api->signals_blocked = saved_signals_blocked;
+
+ return TRUE;
+}
diff --git a/cpukit/posix/src/psignalclearprocesssignals.c b/cpukit/posix/src/psignalclearprocesssignals.c
new file mode 100644
index 0000000000..1ff39534d3
--- /dev/null
+++ b/cpukit/posix/src/psignalclearprocesssignals.c
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tqdata.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/threadsup.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/time.h>
+#include <stdio.h>
+
+/*PAGE
+ *
+ * _POSIX_signals_Clear_process_signals
+ */
+
+void _POSIX_signals_Clear_process_signals(
+ sigset_t mask
+)
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+ _POSIX_signals_Pending &= ~mask;
+ if ( !_POSIX_signals_Pending )
+ _Thread_Do_post_task_switch_extension--;
+ _ISR_Enable( level );
+}
diff --git a/cpukit/posix/src/psignalclearsignals.c b/cpukit/posix/src/psignalclearsignals.c
new file mode 100644
index 0000000000..a1e397c695
--- /dev/null
+++ b/cpukit/posix/src/psignalclearsignals.c
@@ -0,0 +1,89 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tqdata.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/threadsup.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/time.h>
+#include <stdio.h>
+
+/*PAGE
+ *
+ * _POSIX_signals_Clear_signals
+ */
+
+boolean _POSIX_signals_Clear_signals(
+ POSIX_API_Control *api,
+ int signo,
+ siginfo_t *info,
+ boolean is_global,
+ boolean check_blocked
+)
+{
+ sigset_t mask;
+ sigset_t signals_blocked;
+ ISR_Level level;
+ boolean do_callout;
+ POSIX_signals_Siginfo_node *psiginfo;
+
+ mask = signo_to_mask( signo );
+
+ do_callout = FALSE;
+
+ /* set blocked signals based on if checking for them, SIGNAL_ALL_MASK
+ * insures that no signals are blocked and all are checked.
+ */
+
+ if ( check_blocked )
+ signals_blocked = ~api->signals_blocked;
+ else
+ signals_blocked = SIGNAL_ALL_MASK;
+
+ /* XXX this is not right for siginfo type signals yet */
+ /* XXX since they can't be cleared the same way */
+
+ _ISR_Disable( level );
+ if ( is_global ) {
+ if ( mask & (_POSIX_signals_Pending & signals_blocked) ) {
+ if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) {
+ psiginfo = (POSIX_signals_Siginfo_node *)
+ _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] );
+ if ( _Chain_Is_empty( &_POSIX_signals_Siginfo[ signo ] ) )
+ _POSIX_signals_Clear_process_signals( mask );
+ if ( psiginfo ) {
+ *info = psiginfo->Info;
+ _Chain_Append_unprotected(
+ &_POSIX_signals_Inactive_siginfo,
+ &psiginfo->Node
+ );
+ } else
+ do_callout = FALSE;
+ } else
+ _POSIX_signals_Clear_process_signals( mask );
+ do_callout = TRUE;
+ }
+ } else {
+ if ( mask & (api->signals_pending & signals_blocked) ) {
+ api->signals_pending &= ~mask;
+ do_callout = TRUE;
+ }
+ }
+ _ISR_Enable( level );
+ return do_callout;
+}
diff --git a/cpukit/posix/src/psignalsetprocesssignals.c b/cpukit/posix/src/psignalsetprocesssignals.c
new file mode 100644
index 0000000000..65cb51664e
--- /dev/null
+++ b/cpukit/posix/src/psignalsetprocesssignals.c
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tqdata.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/threadsup.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/time.h>
+#include <stdio.h>
+
+/*PAGE
+ *
+ * _POSIX_signals_Set_process_signals
+ */
+
+void _POSIX_signals_Set_process_signals(
+ sigset_t mask
+)
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+ if ( !_POSIX_signals_Pending )
+ _Thread_Do_post_task_switch_extension++;
+ _POSIX_signals_Pending |= mask;
+ _ISR_Enable( level );
+}
diff --git a/cpukit/posix/src/psignalunblockthread.c b/cpukit/posix/src/psignalunblockthread.c
new file mode 100644
index 0000000000..249d16392a
--- /dev/null
+++ b/cpukit/posix/src/psignalunblockthread.c
@@ -0,0 +1,93 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tqdata.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/threadsup.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/time.h>
+#include <stdio.h>
+
+
+/*PAGE
+ *
+ * _POSIX_signals_Unblock_thread
+ */
+
+/* XXX this routine could probably be cleaned up */
+boolean _POSIX_signals_Unblock_thread(
+ Thread_Control *the_thread,
+ int signo,
+ siginfo_t *info
+)
+{
+ POSIX_API_Control *api;
+ sigset_t mask;
+ siginfo_t *the_info = NULL;
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ mask = signo_to_mask( signo );
+
+ /*
+ * Is the thread is specifically waiting for a signal?
+ */
+
+ if ( _States_Is_interruptible_signal( the_thread->current_state ) ) {
+
+ if ( (the_thread->Wait.option & mask) || (~api->signals_blocked & mask) ) {
+ the_thread->Wait.return_code = EINTR;
+
+ the_info = (siginfo_t *) the_thread->Wait.return_argument;
+
+ if ( !info ) {
+ the_info->si_signo = signo;
+ the_info->si_code = SI_USER;
+ the_info->si_value.sival_int = 0;
+ } else {
+ *the_info = *info;
+ }
+
+ _Thread_queue_Extract_with_proxy( the_thread );
+ return TRUE;
+ }
+
+ /*
+ * This should only be reached via pthread_kill().
+ */
+
+ return FALSE;
+ }
+
+ if ( ~api->signals_blocked & mask ) {
+ the_thread->do_post_task_switch_extension = TRUE;
+
+ if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {
+ the_thread->Wait.return_code = EINTR;
+ if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) )
+ _Thread_queue_Extract_with_proxy( the_thread );
+ else if ( _States_Is_delaying(the_thread->current_state)){
+ if ( _Watchdog_Is_active( &the_thread->Timer ) )
+ (void) _Watchdog_Remove( &the_thread->Timer );
+ _Thread_Unblock( the_thread );
+ }
+ }
+ }
+ return FALSE;
+
+}
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
new file mode 100644
index 0000000000..bbd7a73a9e
--- /dev/null
+++ b/cpukit/posix/src/pthread.c
@@ -0,0 +1,392 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/cancel.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/config.h>
+#include <rtems/posix/key.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * The default pthreads attributes structure.
+ *
+ * NOTE: Be careful .. if the default attribute set changes,
+ * _POSIX_Threads_Initialize_user_threads will need to be examined.
+ *
+ */
+
+const pthread_attr_t _POSIX_Threads_Default_attributes = {
+ TRUE, /* is_initialized */
+ NULL, /* stackaddr */
+ PTHREAD_MINIMUM_STACK_SIZE, /* stacksize */
+ PTHREAD_SCOPE_PROCESS, /* contentionscope */
+ PTHREAD_INHERIT_SCHED, /* inheritsched */
+ SCHED_FIFO, /* schedpolicy */
+ { /* schedparam */
+ 2, /* sched_priority */
+ 0, /* ss_low_priority */
+ { 0L, 0 }, /* ss_replenish_period */
+ { 0L, 0 } /* ss_initial_budget */
+ },
+ PTHREAD_CREATE_JOINABLE, /* detachstate */
+ 1 /* cputime_clock_allowed */
+};
+
+/*PAGE
+ *
+ * _POSIX_Threads_Sporadic_budget_TSR
+ */
+
+void _POSIX_Threads_Sporadic_budget_TSR(
+ Objects_Id id,
+ void *argument
+)
+{
+ uint32_t ticks;
+ uint32_t new_priority;
+ Thread_Control *the_thread;
+ POSIX_API_Control *api;
+
+ the_thread = argument;
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ ticks = _POSIX_Timespec_to_interval( &api->schedparam.ss_initial_budget );
+
+ if ( !ticks )
+ ticks = 1;
+
+ the_thread->cpu_time_budget = ticks;
+
+ new_priority = _POSIX_Priority_To_core( api->ss_high_priority );
+ the_thread->real_priority = new_priority;
+
+ if ( the_thread->resource_count == 0 ||
+ the_thread->current_priority > new_priority )
+ _Thread_Change_priority( the_thread, new_priority, TRUE );
+
+ ticks = _POSIX_Timespec_to_interval( &api->schedparam.ss_replenish_period );
+
+ if ( !ticks )
+ ticks = 1;
+
+ _Watchdog_Insert_ticks( &api->Sporadic_timer, ticks );
+}
+
+/*PAGE
+ *
+ * _POSIX_Threads_Sporadic_budget_callout
+ */
+
+void _POSIX_Threads_Sporadic_budget_callout(
+ Thread_Control *the_thread
+)
+{
+ POSIX_API_Control *api;
+ uint32_t new_priority;
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ /*
+ * This will prevent the thread from consuming its entire "budget"
+ * while at low priority.
+ */
+
+
+ the_thread->cpu_time_budget = 0xFFFFFFFF; /* XXX should be based on MAX_U32 */
+
+ new_priority = _POSIX_Priority_To_core( api->schedparam.ss_low_priority );
+ the_thread->real_priority = new_priority;
+
+ if ( the_thread->resource_count == 0 ||
+ the_thread->current_priority > new_priority )
+ _Thread_Change_priority( the_thread, new_priority, TRUE );
+}
+
+/*PAGE
+ *
+ * _POSIX_Threads_Create_extension
+ *
+ * XXX
+ */
+
+boolean _POSIX_Threads_Create_extension(
+ Thread_Control *executing,
+ Thread_Control *created
+)
+{
+ POSIX_API_Control *api;
+ POSIX_API_Control *executing_api;
+
+ api = _Workspace_Allocate( sizeof( POSIX_API_Control ) );
+
+ if ( !api )
+ return FALSE;
+
+ created->API_Extensions[ THREAD_API_POSIX ] = api;
+
+ /* XXX check all fields are touched */
+ api->Attributes = _POSIX_Threads_Default_attributes;
+ api->detachstate = _POSIX_Threads_Default_attributes.detachstate;
+ api->schedpolicy = _POSIX_Threads_Default_attributes.schedpolicy;
+ api->schedparam = _POSIX_Threads_Default_attributes.schedparam;
+ api->schedparam.sched_priority =
+ _POSIX_Priority_From_core( created->current_priority );
+
+ /*
+ * POSIX 1003.1 1996, 18.2.2.2
+ */
+ api->cancelation_requested = 0;
+ api->cancelability_state = PTHREAD_CANCEL_ENABLE;
+ api->cancelability_type = PTHREAD_CANCEL_DEFERRED;
+ _Chain_Initialize_empty (&api->Cancellation_Handlers);
+
+ /*
+ * If the thread is not a posix thread, then all posix signals are blocked
+ * by default.
+ */
+
+ /* XXX use signal constants */
+ api->signals_pending = 0;
+ if ( _Objects_Get_API( created->Object.id ) == OBJECTS_POSIX_API &&
+ _Objects_Get_class( created->Object.id ) == 1 ) {
+ executing_api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+ api->signals_blocked = api->signals_blocked;
+ } else
+ api->signals_blocked = 0xffffffff;
+
+ _Thread_queue_Initialize(
+ &api->Join_List,
+ THREAD_QUEUE_DISCIPLINE_FIFO,
+ STATES_WAITING_FOR_JOIN_AT_EXIT,
+ 0
+ );
+
+ _Watchdog_Initialize(
+ &api->Sporadic_timer,
+ _POSIX_Threads_Sporadic_budget_TSR,
+ created->Object.id,
+ created
+ );
+
+ return TRUE;
+}
+
+/*PAGE
+ *
+ * _POSIX_Threads_Delete_extension
+ */
+
+User_extensions_routine _POSIX_Threads_Delete_extension(
+ Thread_Control *executing,
+ Thread_Control *deleted
+)
+{
+ Thread_Control *the_thread;
+ POSIX_API_Control *api;
+ void **value_ptr;
+
+ api = deleted->API_Extensions[ THREAD_API_POSIX ];
+
+ /*
+ * Run the POSIX cancellation handlers
+ */
+
+ _POSIX_Keys_Run_destructors( deleted );
+
+ /*
+ * Wakeup all the tasks which joined with this one
+ */
+
+ value_ptr = (void **) deleted->Wait.return_argument;
+
+ while ( (the_thread = _Thread_queue_Dequeue( &api->Join_List )) )
+ *(void **)the_thread->Wait.return_argument = value_ptr;
+
+ if ( api->schedpolicy == SCHED_SPORADIC )
+ (void) _Watchdog_Remove( &api->Sporadic_timer );
+
+ deleted->API_Extensions[ THREAD_API_POSIX ] = NULL;
+
+ (void) _Workspace_Free( api );
+}
+
+/*
+ *
+ * _POSIX_Threads_Exitted_extension
+ */
+
+User_extensions_routine _POSIX_Threads_Exitted_extension(
+ Thread_Control *executing
+)
+{
+ /*
+ * If the executing thread was not created with the POSIX API, then this
+ * API do not get to define its exit behavior.
+ */
+ if ( _Objects_Get_API( executing->Object.id ) == OBJECTS_POSIX_API )
+ pthread_exit( executing->Wait.return_argument );
+}
+
+/*PAGE
+ *
+ * _POSIX_Threads_Initialize_user_threads
+ *
+ * This routine creates and starts all configured user
+ * initialzation threads.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _POSIX_Threads_Initialize_user_threads( void )
+{
+ int status;
+ uint32_t index;
+ uint32_t maximum;
+ posix_initialization_threads_table *user_threads;
+ pthread_t thread_id;
+ pthread_attr_t attr;
+
+ user_threads = _POSIX_Threads_User_initialization_threads;
+ maximum = _POSIX_Threads_Number_of_initialization_threads;
+
+ if ( !user_threads || maximum == 0 )
+ return;
+
+ /*
+ * Be careful .. if the default attribute set changes, this may need to.
+ *
+ * Setting the attributes explicitly is critical, since we don't want
+ * to inherit the idle tasks attributes.
+ */
+
+ for ( index=0 ; index < maximum ; index++ ) {
+ status = pthread_attr_init( &attr );
+ assert( !status );
+
+ status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
+ assert( !status );
+
+ status = pthread_attr_setstacksize( &attr, user_threads[ index ].stack_size);
+ assert( !status );
+
+ status = pthread_create(
+ &thread_id,
+ &attr,
+ user_threads[ index ].thread_entry,
+ NULL
+ );
+ assert( !status );
+ }
+}
+
+/*PAGE
+ *
+ * API Extension control structures
+ */
+
+API_extensions_Control _POSIX_Threads_API_extensions = {
+ { NULL, NULL },
+ NULL, /* predriver */
+ _POSIX_Threads_Initialize_user_threads, /* postdriver */
+ _POSIX_signals_Post_switch_extension, /* post switch */
+};
+
+User_extensions_Control _POSIX_Threads_User_extensions = {
+ { NULL, NULL },
+ { { NULL, NULL }, NULL },
+ { _POSIX_Threads_Create_extension, /* create */
+ NULL, /* start */
+ NULL, /* restart */
+ _POSIX_Threads_Delete_extension, /* delete */
+ NULL, /* switch */
+ NULL, /* begin */
+ _POSIX_Threads_Exitted_extension, /* exitted */
+ NULL /* fatal */
+ }
+};
+
+/*PAGE
+ *
+ * _POSIX_Threads_Manager_initialization
+ *
+ * This routine initializes all threads manager related data structures.
+ *
+ * Input parameters:
+ * maximum_pthreads - maximum configured pthreads
+ *
+ * Output parameters: NONE
+ */
+
+void _POSIX_Threads_Manager_initialization(
+ uint32_t maximum_pthreads,
+ uint32_t number_of_initialization_threads,
+ posix_initialization_threads_table *user_threads
+
+)
+{
+ _POSIX_Threads_Number_of_initialization_threads =
+ number_of_initialization_threads;
+ _POSIX_Threads_User_initialization_threads = user_threads;
+
+ /*
+ * There may not be any POSIX initialization threads configured.
+ */
+
+#if 0
+ if ( user_threads == NULL || number_of_initialization_threads == 0 )
+ _Internal_error_Occurred( INTERNAL_ERROR_POSIX_API, TRUE, EINVAL );
+#endif
+
+ _Objects_Initialize_information(
+ &_POSIX_Threads_Information, /* object information table */
+ OBJECTS_POSIX_API, /* object API */
+ OBJECTS_POSIX_THREADS, /* object class */
+ maximum_pthreads, /* maximum objects of this class */
+ sizeof( Thread_Control ),
+ /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ 0 /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Add all the extensions for this API
+ */
+
+ _User_extensions_Add_API_set( &_POSIX_Threads_User_extensions );
+
+ _API_extensions_Add( &_POSIX_Threads_API_extensions );
+
+
+ /*
+ * If we supported MP, then here we would ...
+ * Register the MP Process Packet routine.
+ */
+
+}
diff --git a/cpukit/posix/src/pthreadatfork.c b/cpukit/posix/src/pthreadatfork.c
new file mode 100644
index 0000000000..7bc398ed85
--- /dev/null
+++ b/cpukit/posix/src/pthreadatfork.c
@@ -0,0 +1,31 @@
+/*
+ * pthread_atfork() - POSIX 1003.1b 3.1.3
+ *
+ * 3.1.3 Register Fork Handlers, P1003.1c/Draft 10, P1003.1c/Draft 10, p. 27
+ *
+ * RTEMS does not support processes, so we fall under this and do not
+ * provide this routine:
+ *
+ * "Either the implementation shall support the pthread_atfork() function
+ * as described above or the pthread_atfork() funciton shall not be
+ * provided."
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <errno.h>
+
+int pthread_atfork(
+ void (*prepare)(void),
+ void (*parent)(void),
+ void (*child)(void)
+)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/posix/src/pthreadattrdestroy.c b/cpukit/posix/src/pthreadattrdestroy.c
new file mode 100644
index 0000000000..9b5858ff60
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrdestroy.c
@@ -0,0 +1,32 @@
+/*
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+
+int pthread_attr_destroy(
+ pthread_attr_t *attr
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->is_initialized = FALSE;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadattrgetdetachstate.c b/cpukit/posix/src/pthreadattrgetdetachstate.c
new file mode 100644
index 0000000000..bd8b9a02ae
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrgetdetachstate.c
@@ -0,0 +1,31 @@
+/*
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_getdetachstate(
+ const pthread_attr_t *attr,
+ int *detachstate
+)
+{
+ if ( !attr || !attr->is_initialized || !detachstate )
+ return EINVAL;
+
+ *detachstate = attr->detachstate;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadattrgetinheritsched.c b/cpukit/posix/src/pthreadattrgetinheritsched.c
new file mode 100644
index 0000000000..e924f2d26c
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrgetinheritsched.c
@@ -0,0 +1,31 @@
+/*
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_getinheritsched(
+ const pthread_attr_t *attr,
+ int *inheritsched
+)
+{
+ if ( !attr || !attr->is_initialized || !inheritsched )
+ return EINVAL;
+
+ *inheritsched = attr->inheritsched;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadattrgetschedparam.c b/cpukit/posix/src/pthreadattrgetschedparam.c
new file mode 100644
index 0000000000..2ec95d729e
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrgetschedparam.c
@@ -0,0 +1,31 @@
+/*
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_getschedparam(
+ const pthread_attr_t *attr,
+ struct sched_param *param
+)
+{
+ if ( !attr || !attr->is_initialized || !param )
+ return EINVAL;
+
+ *param = attr->schedparam;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadattrgetschedpolicy.c b/cpukit/posix/src/pthreadattrgetschedpolicy.c
new file mode 100644
index 0000000000..571430e953
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrgetschedpolicy.c
@@ -0,0 +1,31 @@
+/*
+ * 13.5.1 Thread Creation Scheduling Parameters, P1003.1c/Draft 10, p. 120
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_getschedpolicy(
+ const pthread_attr_t *attr,
+ int *policy
+)
+{
+ if ( !attr || !attr->is_initialized || !policy )
+ return EINVAL;
+
+ *policy = attr->schedpolicy;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadattrgetscope.c b/cpukit/posix/src/pthreadattrgetscope.c
new file mode 100644
index 0000000000..2d74dc30ba
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrgetscope.c
@@ -0,0 +1,31 @@
+/*
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_getscope(
+ const pthread_attr_t *attr,
+ int *contentionscope
+)
+{
+ if ( !attr || !attr->is_initialized || !contentionscope )
+ return EINVAL;
+
+ *contentionscope = attr->contentionscope;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadattrgetstackaddr.c b/cpukit/posix/src/pthreadattrgetstackaddr.c
new file mode 100644
index 0000000000..3ca66112aa
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrgetstackaddr.c
@@ -0,0 +1,31 @@
+/*
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_getstackaddr(
+ const pthread_attr_t *attr,
+ void **stackaddr
+)
+{
+ if ( !attr || !attr->is_initialized || !stackaddr )
+ return EINVAL;
+
+ *stackaddr = attr->stackaddr;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadattrgetstacksize.c b/cpukit/posix/src/pthreadattrgetstacksize.c
new file mode 100644
index 0000000000..f7f23c6dd6
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrgetstacksize.c
@@ -0,0 +1,31 @@
+/*
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_getstacksize(
+ const pthread_attr_t *attr,
+ size_t *stacksize
+)
+{
+ if ( !attr || !attr->is_initialized || !stacksize )
+ return EINVAL;
+
+ *stacksize = attr->stacksize;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadattrinit.c b/cpukit/posix/src/pthreadattrinit.c
new file mode 100644
index 0000000000..1862623e3e
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrinit.c
@@ -0,0 +1,33 @@
+/*
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+
+int pthread_attr_init(
+ pthread_attr_t *attr
+)
+{
+ if ( !attr )
+ return EINVAL;
+
+ *attr = _POSIX_Threads_Default_attributes;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadattrsetdetachstate.c b/cpukit/posix/src/pthreadattrsetdetachstate.c
new file mode 100644
index 0000000000..cb29f44d3a
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrsetdetachstate.c
@@ -0,0 +1,38 @@
+/*
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_setdetachstate(
+ pthread_attr_t *attr,
+ int detachstate
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ switch ( detachstate ) {
+ case PTHREAD_CREATE_DETACHED:
+ case PTHREAD_CREATE_JOINABLE:
+ attr->detachstate = detachstate;
+ return 0;
+
+ default:
+ return EINVAL;
+ }
+}
diff --git a/cpukit/posix/src/pthreadattrsetinheritsched.c b/cpukit/posix/src/pthreadattrsetinheritsched.c
new file mode 100644
index 0000000000..0819eb48b7
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrsetinheritsched.c
@@ -0,0 +1,41 @@
+/*
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+
+int pthread_attr_setinheritsched(
+ pthread_attr_t *attr,
+ int inheritsched
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ switch ( inheritsched ) {
+ case PTHREAD_INHERIT_SCHED:
+ case PTHREAD_EXPLICIT_SCHED:
+ attr->inheritsched = inheritsched;
+ return 0;
+
+ default:
+ return ENOTSUP;
+ }
+}
diff --git a/cpukit/posix/src/pthreadattrsetschedparam.c b/cpukit/posix/src/pthreadattrsetschedparam.c
new file mode 100644
index 0000000000..cb310a9893
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrsetschedparam.c
@@ -0,0 +1,31 @@
+/*
+ * 13.5.1 Thread Creation Scheduling Parameters, P1003.1c/Draft 10, p. 120
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_setschedparam(
+ pthread_attr_t *attr,
+ const struct sched_param *param
+)
+{
+ if ( !attr || !attr->is_initialized || !param )
+ return EINVAL;
+
+ attr->schedparam = *param;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadattrsetschedpolicy.c b/cpukit/posix/src/pthreadattrsetschedpolicy.c
new file mode 100644
index 0000000000..ab61e000ed
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrsetschedpolicy.c
@@ -0,0 +1,43 @@
+/*
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+
+int pthread_attr_setschedpolicy(
+ pthread_attr_t *attr,
+ int policy
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ switch ( policy ) {
+ case SCHED_OTHER:
+ case SCHED_FIFO:
+ case SCHED_RR:
+ case SCHED_SPORADIC:
+ attr->schedpolicy = policy;
+ return 0;
+
+ default:
+ return ENOTSUP;
+ }
+}
diff --git a/cpukit/posix/src/pthreadattrsetscope.c b/cpukit/posix/src/pthreadattrsetscope.c
new file mode 100644
index 0000000000..8c6d1c3f9c
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrsetscope.c
@@ -0,0 +1,43 @@
+/*
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+
+int pthread_attr_setscope(
+ pthread_attr_t *attr,
+ int contentionscope
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ switch ( contentionscope ) {
+ case PTHREAD_SCOPE_PROCESS:
+ attr->contentionscope = contentionscope;
+ return 0;
+
+ case PTHREAD_SCOPE_SYSTEM:
+ return ENOTSUP;
+
+ default:
+ return EINVAL;
+ }
+}
diff --git a/cpukit/posix/src/pthreadattrsetstackaddr.c b/cpukit/posix/src/pthreadattrsetstackaddr.c
new file mode 100644
index 0000000000..b7ed212546
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrsetstackaddr.c
@@ -0,0 +1,31 @@
+/*
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_setstackaddr(
+ pthread_attr_t *attr,
+ void *stackaddr
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->stackaddr = stackaddr;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadattrsetstacksize.c b/cpukit/posix/src/pthreadattrsetstacksize.c
new file mode 100644
index 0000000000..9598a8a7d7
--- /dev/null
+++ b/cpukit/posix/src/pthreadattrsetstacksize.c
@@ -0,0 +1,37 @@
+/*
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+
+int pthread_attr_setstacksize(
+ pthread_attr_t *attr,
+ size_t stacksize
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ if (stacksize < PTHREAD_MINIMUM_STACK_SIZE)
+ attr->stacksize = PTHREAD_MINIMUM_STACK_SIZE;
+ else
+ attr->stacksize = stacksize;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
new file mode 100644
index 0000000000..61a59c01f8
--- /dev/null
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -0,0 +1,256 @@
+/*
+ * 16.1.2 Thread Creation, P1003.1c/Draft 10, p. 144
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+int pthread_create(
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)( void * ),
+ void *arg
+)
+{
+ const pthread_attr_t *the_attr;
+ Priority_Control core_priority;
+ Thread_CPU_budget_algorithms budget_algorithm;
+ Thread_CPU_budget_algorithm_callout budget_callout;
+ boolean is_fp;
+ boolean status;
+ Thread_Control *the_thread;
+ POSIX_API_Control *api;
+ int schedpolicy = SCHED_RR;
+ struct sched_param schedparam;
+
+ the_attr = (attr) ? attr : &_POSIX_Threads_Default_attributes;
+
+ if ( !the_attr->is_initialized )
+ return EINVAL;
+
+ /*
+ * Core Thread Initialize insures we get the minimum amount of
+ * stack space if it is allowed to allocate it itself.
+ */
+
+ if ( the_attr->stackaddr && !_Stack_Is_enough( the_attr->stacksize ) )
+ return EINVAL;
+
+#if 0
+ int cputime_clock_allowed; /* see time.h */
+ POSIX_NOT_IMPLEMENTED();
+#endif
+
+ /*
+ * P1003.1c/Draft 10, p. 121.
+ *
+ * If inheritsched is set to PTHREAD_INHERIT_SCHED, then this thread
+ * inherits scheduling attributes from the creating thread. If it is
+ * PTHREAD_EXPLICIT_SCHED, then scheduling parameters come from the
+ * attributes structure.
+ */
+
+ switch ( the_attr->inheritsched ) {
+ case PTHREAD_INHERIT_SCHED:
+ api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+ schedpolicy = api->schedpolicy;
+ schedparam = api->schedparam;
+ break;
+
+ case PTHREAD_EXPLICIT_SCHED:
+ schedpolicy = the_attr->schedpolicy;
+ schedparam = the_attr->schedparam;
+ break;
+
+ default:
+ return EINVAL;
+ }
+
+ /*
+ * Check the contentionscope since rtems only supports PROCESS wide
+ * contention (i.e. no system wide contention).
+ */
+
+ if ( the_attr->contentionscope != PTHREAD_SCOPE_PROCESS )
+ return ENOTSUP;
+
+ /*
+ * Interpret the scheduling parameters.
+ */
+
+ if ( !_POSIX_Priority_Is_valid( schedparam.sched_priority ) )
+ return EINVAL;
+
+ core_priority = _POSIX_Priority_To_core( schedparam.sched_priority );
+
+ /*
+ * Set the core scheduling policy information.
+ */
+
+ budget_callout = NULL;
+ budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
+
+ switch ( schedpolicy ) {
+ case SCHED_OTHER:
+ budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
+ break;
+
+ case SCHED_FIFO:
+ budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
+ break;
+
+ case SCHED_RR:
+ budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE;
+ break;
+
+ case SCHED_SPORADIC:
+ budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
+ budget_callout = _POSIX_Threads_Sporadic_budget_callout;
+
+ if ( _POSIX_Timespec_to_interval( &schedparam.ss_replenish_period ) <
+ _POSIX_Timespec_to_interval( &schedparam.ss_initial_budget ) )
+ return EINVAL;
+
+ if ( !_POSIX_Priority_Is_valid( schedparam.ss_low_priority ) )
+ return EINVAL;
+
+ break;
+
+ default:
+ return EINVAL;
+ }
+
+ /*
+ * Currently all POSIX threads are floating point if the hardware
+ * supports it.
+ */
+
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ is_fp = TRUE;
+#else
+ is_fp = FALSE;
+#endif
+
+ /*
+ * Disable dispatch for protection
+ */
+
+ _Thread_Disable_dispatch();
+
+ /*
+ * Allocate the thread control block.
+ *
+ * NOTE: Global threads are not currently supported.
+ */
+
+ the_thread = _POSIX_Threads_Allocate();
+
+ if ( !the_thread ) {
+ _Thread_Enable_dispatch();
+ return EAGAIN;
+ }
+
+ /*
+ * Initialize the core thread for this task.
+ */
+
+ status = _Thread_Initialize(
+ &_POSIX_Threads_Information,
+ the_thread,
+ the_attr->stackaddr,
+ the_attr->stacksize,
+ is_fp,
+ core_priority,
+ TRUE, /* preemptible */
+ budget_algorithm,
+ budget_callout,
+ 0, /* isr level */
+ NULL /* posix threads don't have a name */
+ );
+
+ if ( !status ) {
+ _POSIX_Threads_Free( the_thread );
+ _Thread_Enable_dispatch();
+ return EAGAIN;
+ }
+
+ /*
+ * finish initializing the per API structure
+ */
+
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ api->Attributes = *the_attr;
+ api->detachstate = the_attr->detachstate;
+ api->schedpolicy = schedpolicy;
+ api->schedparam = schedparam;
+
+ /*
+ * This insures we evaluate the process-wide signals pending when we
+ * first run.
+ *
+ * NOTE: Since the thread starts with all unblocked, this is necessary.
+ */
+
+ the_thread->do_post_task_switch_extension = TRUE;
+
+ /*
+ * POSIX threads are allocated and started in one operation.
+ */
+
+ status = _Thread_Start(
+ the_thread,
+ THREAD_START_POINTER,
+ start_routine,
+ arg,
+ 0 /* unused */
+ );
+
+ if ( schedpolicy == SCHED_SPORADIC ) {
+ _Watchdog_Insert_ticks(
+ &api->Sporadic_timer,
+ _POSIX_Timespec_to_interval( &api->schedparam.ss_replenish_period )
+ );
+ }
+
+ /*
+ * _Thread_Start only fails if the thread was in the incorrect state
+ */
+
+ if ( !status ) {
+ _POSIX_Threads_Free( the_thread );
+ _Thread_Enable_dispatch();
+ return EINVAL;
+ }
+
+ /*
+ * Return the id and indicate we successfully created the thread
+ */
+
+ *thread = the_thread->Object.id;
+
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreaddetach.c b/cpukit/posix/src/pthreaddetach.c
new file mode 100644
index 0000000000..7d7629f18a
--- /dev/null
+++ b/cpukit/posix/src/pthreaddetach.c
@@ -0,0 +1,47 @@
+/*
+ * 16.1.4 Detaching a Thread, P1003.1c/Draft 10, p. 149
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+#include <rtems/posix/pthread.h>
+
+int pthread_detach(
+ pthread_t thread
+)
+{
+ register Thread_Control *the_thread;
+ POSIX_API_Control *api;
+ Objects_Locations location;
+
+ the_thread = _POSIX_Threads_Get( thread, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE:
+ return ESRCH;
+ case OBJECTS_LOCAL:
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+ api->detachstate = PTHREAD_CREATE_DETACHED;
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/pthreadequal.c b/cpukit/posix/src/pthreadequal.c
new file mode 100644
index 0000000000..39136cc388
--- /dev/null
+++ b/cpukit/posix/src/pthreadequal.c
@@ -0,0 +1,82 @@
+/*
+ * 16.1.7 Compare Thread IDs, p1003.1c/Draft 10, p. 153
+ *
+ * NOTE: POSIX does not define the behavior when either thread id is invalid.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/score/thread.h>
+
+int pthread_equal(
+ pthread_t t1,
+ pthread_t t2
+)
+{
+ /*
+ * If the system is configured for debug, then we will do everything we
+ * can to insure that both ids are valid. Otherwise, we will do the
+ * cheapest possible thing to determine if they are equal.
+ */
+
+#ifndef RTEMS_DEBUG
+ return _Objects_Are_ids_equal( t1, t2 );
+#else
+ int status;
+ Objects_Locations location;
+
+ /*
+ * By default this is not a match.
+ */
+
+ status = 0;
+
+ /*
+ * Validate the first id and return 0 if it is not valid
+ */
+
+ (void) _POSIX_Threads_Get( t1, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE:
+ break;
+
+ case OBJECTS_LOCAL:
+
+ /*
+ * Validate the second id and return 0 if it is not valid
+ */
+
+ (void) _POSIX_Threads_Get( t2, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE:
+ break;
+ case OBJECTS_LOCAL:
+ status = _Objects_Are_ids_equal( t1, t2 );
+ break;
+ }
+ _Thread_Unnest_dispatch();
+ break;
+ }
+
+ _Thread_Enable_dispatch();
+ return status;
+#endif
+}
diff --git a/cpukit/posix/src/pthreadexit.c b/cpukit/posix/src/pthreadexit.c
new file mode 100644
index 0000000000..8346f139b8
--- /dev/null
+++ b/cpukit/posix/src/pthreadexit.c
@@ -0,0 +1,48 @@
+/*
+ * 16.1.5.1 Thread Termination, p1003.1c/Draft 10, p. 150
+ *
+ * NOTE: Key destructors are executed in the POSIX api delete extension.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+#include <rtems/posix/pthread.h>
+
+void pthread_exit(
+ void *value_ptr
+)
+{
+ Objects_Information *the_information;
+
+ the_information = _Objects_Get_information( _Thread_Executing->Object.id );
+
+ /* This should never happen if _Thread_Get() works right */
+ assert( the_information );
+
+ _Thread_Disable_dispatch();
+
+ _Thread_Executing->Wait.return_argument = value_ptr;
+
+ _Thread_Close( the_information, _Thread_Executing );
+
+ _POSIX_Threads_Free( _Thread_Executing );
+
+ _Thread_Enable_dispatch();
+}
diff --git a/cpukit/posix/src/pthreadgetcpuclockid.c b/cpukit/posix/src/pthreadgetcpuclockid.c
new file mode 100644
index 0000000000..7769e4b7c6
--- /dev/null
+++ b/cpukit/posix/src/pthreadgetcpuclockid.c
@@ -0,0 +1,29 @@
+/*
+ * 20.1.6 Accessing a Thread CPU-time Clock, P1003.4b/Draft 8, p. 58
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+
+int pthread_getcpuclockid(
+ pthread_t pid,
+ clockid_t *clock_id
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
diff --git a/cpukit/posix/src/pthreadgetcputime.c b/cpukit/posix/src/pthreadgetcputime.c
new file mode 100644
index 0000000000..7c9bb46c7b
--- /dev/null
+++ b/cpukit/posix/src/pthreadgetcputime.c
@@ -0,0 +1,31 @@
+/*
+ * 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/Draft 8, p. 59
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_getcputime(
+ pthread_attr_t *attr,
+ int *clock_allowed
+)
+{
+ if ( !attr || !attr->is_initialized || !clock_allowed )
+ return EINVAL;
+
+ *clock_allowed = attr->cputime_clock_allowed;
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadgetschedparam.c b/cpukit/posix/src/pthreadgetschedparam.c
new file mode 100644
index 0000000000..8b399b75ba
--- /dev/null
+++ b/cpukit/posix/src/pthreadgetschedparam.c
@@ -0,0 +1,59 @@
+/*
+ * 13.5.2 Dynamic Thread Scheduling Parameters Access,
+ * P1003.1c/Draft 10, p. 124
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/priority.h>
+
+int pthread_getschedparam(
+ pthread_t thread,
+ int *policy,
+ struct sched_param *param
+)
+{
+ Objects_Locations location;
+ POSIX_API_Control *api;
+ register Thread_Control *the_thread;
+
+ if ( !policy || !param )
+ return EINVAL;
+
+ the_thread = _POSIX_Threads_Get( thread, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE:
+ return ESRCH;
+ case OBJECTS_LOCAL:
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+ if ( policy )
+ *policy = api->schedpolicy;
+ if ( param ) {
+ *param = api->schedparam;
+ param->sched_priority =
+ _POSIX_Priority_From_core( the_thread->current_priority );
+ }
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+
+ return POSIX_BOTTOM_REACHED();
+
+}
diff --git a/cpukit/posix/src/pthreadjoin.c b/cpukit/posix/src/pthreadjoin.c
new file mode 100644
index 0000000000..669028335c
--- /dev/null
+++ b/cpukit/posix/src/pthreadjoin.c
@@ -0,0 +1,71 @@
+/*
+ * 16.1.3 Wait for Thread Termination, P1003.1c/Draft 10, p. 147
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+#include <rtems/posix/pthread.h>
+
+int pthread_join(
+ pthread_t thread,
+ void **value_ptr
+)
+{
+ register Thread_Control *the_thread;
+ POSIX_API_Control *api;
+ Objects_Locations location;
+ void *return_pointer;
+
+ the_thread = _POSIX_Threads_Get( thread, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE:
+ return ESRCH;
+ case OBJECTS_LOCAL:
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ if ( api->detachstate == PTHREAD_CREATE_DETACHED ) {
+ _Thread_Enable_dispatch();
+ return EINVAL;
+ }
+
+ if ( _Thread_Is_executing( the_thread ) ) {
+ _Thread_Enable_dispatch();
+ return EDEADLK;
+ }
+
+ /*
+ * Put ourself on the threads join list
+ */
+
+ _Thread_Executing->Wait.return_argument = &return_pointer;
+
+ _Thread_queue_Enter_critical_section( &api->Join_List );
+
+ _Thread_queue_Enqueue( &api->Join_List, WATCHDOG_NO_TIMEOUT );
+
+ _Thread_Enable_dispatch();
+
+ if ( value_ptr )
+ *value_ptr = return_pointer;
+ return 0;
+ }
+
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/pthreadkill.c b/cpukit/posix/src/pthreadkill.c
new file mode 100644
index 0000000000..c6624eb8be
--- /dev/null
+++ b/cpukit/posix/src/pthreadkill.c
@@ -0,0 +1,83 @@
+/*
+ * 3.3.10 Send a Signal to a Thread, P1003.1c/D10, p. 43
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/score/isr.h>
+#include <rtems/seterr.h>
+
+int pthread_kill(
+ pthread_t thread,
+ int sig
+)
+{
+ POSIX_API_Control *api;
+ Thread_Control *the_thread;
+ Objects_Locations location;
+
+ if ( !sig )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( !is_valid_signo(sig) )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+/* commented out when posix timers added
+ if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO )
+ rtems_set_errno_and_return_minus_one( ENOSYS );
+*/
+
+ the_thread = _POSIX_Threads_Get( thread, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE:
+ rtems_set_errno_and_return_minus_one( ESRCH );
+ case OBJECTS_LOCAL:
+ /*
+ * If sig == 0 then just validate arguments
+ */
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ if ( sig ) {
+
+ if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) {
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+
+ /* XXX critical section */
+
+ api->signals_pending |= signo_to_mask( sig );
+
+ (void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL );
+
+ the_thread->do_post_task_switch_extension = TRUE;
+
+ if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
+ _ISR_Signals_to_thread_executing = TRUE;
+ }
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/pthreadonce.c b/cpukit/posix/src/pthreadonce.c
new file mode 100644
index 0000000000..b1371c8def
--- /dev/null
+++ b/cpukit/posix/src/pthreadonce.c
@@ -0,0 +1,44 @@
+/*
+ * 16.1.8 Dynamic Package Initialization, P1003.1c/Draft 10, p. 154
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+
+int pthread_once(
+ pthread_once_t *once_control,
+ void (*init_routine)(void)
+)
+{
+ if ( !once_control || !init_routine )
+ return EINVAL;
+
+ if ( !once_control->init_executed ) {
+ rtems_mode saveMode;
+ rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &saveMode);
+ if ( !once_control->init_executed ) {
+ once_control->is_initialized = TRUE;
+ once_control->init_executed = TRUE;
+ (*init_routine)();
+ }
+ rtems_task_mode(saveMode, RTEMS_PREEMPT_MASK, &saveMode);
+ }
+ return 0;
+}
diff --git a/cpukit/posix/src/pthreadself.c b/cpukit/posix/src/pthreadself.c
new file mode 100644
index 0000000000..c1baf85177
--- /dev/null
+++ b/cpukit/posix/src/pthreadself.c
@@ -0,0 +1,27 @@
+/*
+ * 16.1.6 Get Calling Thread's ID, p1003.1c/Draft 10, p. 152
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+
+pthread_t pthread_self( void )
+{
+ return _Thread_Executing->Object.id;
+}
diff --git a/cpukit/posix/src/pthreadsetcputime.c b/cpukit/posix/src/pthreadsetcputime.c
new file mode 100644
index 0000000000..70b9594ab9
--- /dev/null
+++ b/cpukit/posix/src/pthreadsetcputime.c
@@ -0,0 +1,38 @@
+/*
+ * 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/Draft 8, p. 59
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_attr_setcputime(
+ pthread_attr_t *attr,
+ int clock_allowed
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ switch ( clock_allowed ) {
+ case CLOCK_ENABLED:
+ case CLOCK_DISABLED:
+ attr->cputime_clock_allowed = clock_allowed;
+ return 0;
+
+ default:
+ return EINVAL;
+ }
+}
diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c
new file mode 100644
index 0000000000..3413dbfc74
--- /dev/null
+++ b/cpukit/posix/src/pthreadsetschedparam.c
@@ -0,0 +1,129 @@
+/*
+ * 13.5.2 Dynamic Thread Scheduling Parameters Access,
+ * P1003.1c/Draft 10, p. 124
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+int pthread_setschedparam(
+ pthread_t thread,
+ int policy,
+ struct sched_param *param
+)
+{
+ register Thread_Control *the_thread;
+ POSIX_API_Control *api;
+ Thread_CPU_budget_algorithms budget_algorithm;
+ Thread_CPU_budget_algorithm_callout budget_callout;
+ Objects_Locations location;
+
+ /*
+ * Check all the parameters
+ */
+
+ if ( !param )
+ return EINVAL;
+
+ if ( !_POSIX_Priority_Is_valid( param->sched_priority ) )
+ return EINVAL;
+
+ budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
+ budget_callout = NULL;
+
+ switch ( policy ) {
+ case SCHED_OTHER:
+ budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
+ break;
+
+ case SCHED_FIFO:
+ budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
+ break;
+
+ case SCHED_RR:
+ budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE;
+ break;
+
+ case SCHED_SPORADIC:
+ budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
+ budget_callout = _POSIX_Threads_Sporadic_budget_callout;
+
+ if ( _POSIX_Timespec_to_interval( &param->ss_replenish_period ) <
+ _POSIX_Timespec_to_interval( &param->ss_initial_budget ) )
+ return EINVAL;
+
+ if ( !_POSIX_Priority_Is_valid( param->ss_low_priority ) )
+ return EINVAL;
+
+ break;
+
+ default:
+ return EINVAL;
+ }
+
+ /*
+ * Actually change the scheduling policy and parameters
+ */
+
+ the_thread = _POSIX_Threads_Get( thread, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE:
+ return ESRCH;
+ case OBJECTS_LOCAL:
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ if ( api->schedpolicy == SCHED_SPORADIC )
+ (void) _Watchdog_Remove( &api->Sporadic_timer );
+
+ api->schedpolicy = policy;
+ api->schedparam = *param;
+ the_thread->budget_algorithm = budget_algorithm;
+ the_thread->budget_callout = budget_callout;
+
+ switch ( api->schedpolicy ) {
+ case SCHED_OTHER:
+ case SCHED_FIFO:
+ case SCHED_RR:
+ the_thread->cpu_time_budget = _Thread_Ticks_per_timeslice;
+
+ the_thread->real_priority =
+ _POSIX_Priority_To_core( api->schedparam.sched_priority );
+
+ _Thread_Change_priority(
+ the_thread,
+ the_thread->real_priority,
+ TRUE
+ );
+ break;
+
+ case SCHED_SPORADIC:
+ api->ss_high_priority = api->schedparam.sched_priority;
+ _Watchdog_Remove( &api->Sporadic_timer );
+ _POSIX_Threads_Sporadic_budget_TSR( 0, the_thread );
+ break;
+ }
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/pthreadsigmask.c b/cpukit/posix/src/pthreadsigmask.c
new file mode 100644
index 0000000000..59bc688fcd
--- /dev/null
+++ b/cpukit/posix/src/pthreadsigmask.c
@@ -0,0 +1,73 @@
+/*
+ * 3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
+ *
+ * NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/seterr.h>
+
+int pthread_sigmask(
+ int how,
+ const sigset_t *set,
+ sigset_t *oset
+)
+{
+ POSIX_API_Control *api;
+
+ if ( !set && !oset )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ if ( oset )
+ *oset = api->signals_blocked;
+
+ if ( !set )
+ return 0;
+
+ switch ( how ) {
+ case SIG_BLOCK:
+ api->signals_blocked |= *set;
+ break;
+ case SIG_UNBLOCK:
+ api->signals_blocked &= ~*set;
+ break;
+ case SIG_SETMASK:
+ api->signals_blocked = *set;
+ break;
+ default:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ /* XXX are there critical section problems here? */
+
+ /* XXX evaluate the new set */
+
+ if ( ~api->signals_blocked &
+ (api->signals_pending | _POSIX_signals_Pending) ) {
+ _Thread_Executing->do_post_task_switch_extension = TRUE;
+ _Thread_Dispatch();
+ }
+
+ return 0;
+}
diff --git a/cpukit/posix/src/ptimer.c b/cpukit/posix/src/ptimer.c
new file mode 100644
index 0000000000..2f0a5d5559
--- /dev/null
+++ b/cpukit/posix/src/ptimer.c
@@ -0,0 +1,62 @@
+/*
+ * ptimer.c,v 1.1 1996/06/03 16:29:58 joel Exp
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+#include <limits.h> /* _POSIX_PATH_MAX */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/posix/time.h>
+
+/************************************/
+/* These includes are now necessary */
+/************************************/
+
+#include <unistd.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/rtems/clock.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/score/wkspace.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <signal.h>
+
+#include <rtems/posix/timer.h>
+
+/*
+ * _POSIX_Timer_Manager_initialization
+ *
+ * Description: Initialize the internal structure in which the data of all
+ * the timers are stored
+ */
+
+void _POSIX_Timer_Manager_initialization ( int maximum_timers )
+{
+ _Objects_Initialize_information(
+ &_POSIX_Timer_Information, /* object information table */
+ OBJECTS_POSIX_API, /* object API */
+ OBJECTS_POSIX_TIMERS, /* object class */
+ maximum_timers, /* maximum objects of this class */
+ sizeof( POSIX_Timer_Control ),
+ /* size of this object's control block */
+ FALSE, /* TRUE if names for this object are strings */
+ _POSIX_PATH_MAX /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+}
diff --git a/cpukit/posix/src/ptimer1.c b/cpukit/posix/src/ptimer1.c
new file mode 100644
index 0000000000..87a17f22d2
--- /dev/null
+++ b/cpukit/posix/src/ptimer1.c
@@ -0,0 +1,568 @@
+/*
+ * ptimer.c,v 1.1 1996/06/03 16:29:58 joel Exp
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/posix/time.h>
+
+/************************************/
+/* These includes are now necessary */
+/************************************/
+
+#include <unistd.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/rtems/clock.h>
+#include <rtems/posix/psignal.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <signal.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/timer.h>
+
+boolean _Watchdog_Insert_ticks_helper(
+ Watchdog_Control *timer,
+ Watchdog_Interval ticks,
+ Objects_Id id,
+ Watchdog_Service_routine_entry TSR,
+ void *arg
+)
+{
+ ISR_Level level;
+
+ (void) _Watchdog_Remove( timer );
+ _ISR_Disable( level );
+
+ /*
+ * Check to see if the watchdog has just been inserted by a
+ * higher priority interrupt. If so, abandon this insert.
+ */
+ if ( timer->state != WATCHDOG_INACTIVE ) {
+ _ISR_Enable( level );
+ return FALSE;
+ }
+
+ /*
+ * OK. Now we now the timer was not rescheduled by an interrupt
+ * so we can atomically initialize it as in use.
+ */
+ _Watchdog_Initialize( timer, TSR, id, arg );
+ _Watchdog_Insert_ticks( timer, ticks );
+ _ISR_Enable( level );
+ return TRUE;
+}
+
+/* #define DEBUG_MESSAGES */
+
+/*
+ * ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S
+ *
+ * Description: This function converts the data of a structure itimerspec
+ * into structure rtems_time_of_day
+ */
+
+void ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S(
+ const struct itimerspec *itimer,
+ rtems_time_of_day *rtems_time
+)
+{
+ unsigned long int seconds;
+
+ /* The leap years and the months with 28, 29 or 31 days have not been
+ * considered. It will be made in the future */
+
+ seconds = itimer->it_value.tv_sec;
+
+ rtems_time->year = seconds / SECONDS_PER_YEAR_C;
+ seconds = seconds % SECONDS_PER_YEAR_C;
+
+ rtems_time->month = seconds / SECONDS_PER_MONTH_C;
+ seconds = seconds % SECONDS_PER_MONTH_C;
+
+ rtems_time->day = seconds / SECONDS_PER_DAY_C;
+ seconds = seconds % SECONDS_PER_DAY_C;
+
+ rtems_time->hour = seconds / SECONDS_PER_HOUR_C;
+ seconds = seconds % SECONDS_PER_HOUR_C;
+
+ rtems_time->minute = seconds / SECONDS_PER_MINUTE_C;
+ seconds = seconds % SECONDS_PER_MINUTE_C;
+
+ rtems_time->second = seconds;
+
+ rtems_time->ticks = itimer->it_value.tv_nsec/
+ (NSEC_PER_SEC_C / SEC_TO_TICKS_C);
+
+}
+
+
+/* ***************************************************************************
+ * _POSIX_Timer_TSR
+ *
+ * Description: This is the operation that is ran when a timer expires
+ * ***************************************************************************/
+
+
+void _POSIX_Timer_TSR(Objects_Id timer, void *data)
+{
+ POSIX_Timer_Control *ptimer;
+ boolean activated;
+
+ ptimer = (POSIX_Timer_Control *)data;
+
+ /* Increment the number of expirations. */
+ ptimer->overrun = ptimer->overrun + 1;
+ /* The timer must be reprogrammed */
+ if ( ( ptimer->timer_data.it_interval.tv_sec != 0 ) ||
+ ( ptimer->timer_data.it_interval.tv_nsec != 0 ) ) {
+#if 0
+ status = rtems_timer_fire_after(
+ ptimer->timer_id, ptimer->ticks, _POSIX_Timer_TSR, ptimer );
+#endif
+ activated = _Watchdog_Insert_ticks_helper(
+ &ptimer->Timer,
+ ptimer->ticks,
+ ptimer->Object.id,
+ _POSIX_Timer_TSR,
+ ptimer
+ );
+ if ( !activated )
+ return;
+
+ /* Store the time when the timer was started again */
+ ptimer->time = _TOD_Current;
+
+ /* The state really did not change but just to be safe */
+ ptimer->state = STATE_CREATE_RUN_C;
+ } else {
+ /* Indicates that the timer is stopped */
+ ptimer->state = STATE_CREATE_STOP_C;
+ }
+
+ /*
+ * The sending of the signal to the process running the handling function
+ * specified for that signal is simulated
+ */
+
+ if ( pthread_kill ( ptimer->thread_id, ptimer->inf.sigev_signo ) ) {
+ /* XXX error handling */
+ }
+
+ /* After the signal handler returns, the count of expirations of the
+ * timer must be set to 0.
+ */
+ ptimer->overrun = 0;
+}
+
+/* *********************************************************************
+ * 14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264
+ * ********************************************************************/
+
+/* **************
+ * timer_create
+ * **************/
+
+int timer_create(
+ clockid_t clock_id,
+ struct sigevent *evp,
+ timer_t *timerid
+)
+{
+ POSIX_Timer_Control *ptimer;
+
+ if ( clock_id != CLOCK_REALTIME )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ /*
+ * The data of the structure evp are checked in order to verify if they
+ * are coherent.
+ */
+
+ if (evp != NULL) {
+ /* The structure has data */
+ if ( ( evp->sigev_notify != SIGEV_NONE ) &&
+ ( evp->sigev_notify != SIGEV_SIGNAL ) ) {
+ /* The value of the field sigev_notify is not valid */
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ if ( !evp->sigev_signo )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( !is_valid_signo(evp->sigev_signo) )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ _Thread_Disable_dispatch(); /* to prevent deletion */
+
+ /*
+ * Allocate a timer
+ */
+ ptimer = _POSIX_Timer_Allocate();
+ if ( !ptimer ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( EAGAIN );
+ }
+
+ /* The data of the created timer are stored to use them later */
+
+ ptimer->state = STATE_CREATE_NEW_C;
+ ptimer->thread_id = _Thread_Executing->Object.id;
+
+ if ( evp != NULL ) {
+ ptimer->inf.sigev_notify = evp->sigev_notify;
+ ptimer->inf.sigev_signo = evp->sigev_signo;
+ ptimer->inf.sigev_value = evp->sigev_value;
+ }
+
+ ptimer->overrun = 0;
+ ptimer->timer_data.it_value.tv_sec = 0;
+ ptimer->timer_data.it_value.tv_nsec = 0;
+ ptimer->timer_data.it_interval.tv_sec = 0;
+ ptimer->timer_data.it_interval.tv_nsec = 0;
+
+ _Watchdog_Initialize( &ptimer->Timer, NULL, 0, NULL );
+ _Objects_Open(&_POSIX_Timer_Information, &ptimer->Object, (Objects_Name) 0);
+
+ *timerid = ptimer->Object.id;
+ _Thread_Enable_dispatch();
+ return 0;
+}
+
+/*
+ * 14.2.3 Delete a Per_process Timer, P1003.1b-1993, p. 266
+ */
+
+int timer_delete(
+ timer_t timerid
+)
+{
+ /*
+ * IDEA: This function must probably stop the timer first and then delete it
+ *
+ * It will have to do a call to rtems_timer_cancel and then another
+ * call to rtems_timer_delete.
+ * The call to rtems_timer_delete will be probably unnecessary,
+ * because rtems_timer_delete stops the timer before deleting it.
+ */
+ POSIX_Timer_Control *ptimer;
+ Objects_Locations location;
+
+ ptimer = _POSIX_Timer_Get( timerid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+#endif
+
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ case OBJECTS_LOCAL:
+ _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object );
+ ptimer->state = STATE_FREE_C;
+ (void) _Watchdog_Remove( &ptimer->Timer );
+ _POSIX_Timer_Free( ptimer );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return -1; /* unreached - only to remove warnings */
+}
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ */
+
+/* **************
+ * timer_settime
+ * **************/
+
+
+int timer_settime(
+ timer_t timerid,
+ int flags,
+ const struct itimerspec *value,
+ struct itimerspec *ovalue
+)
+{
+ POSIX_Timer_Control *ptimer;
+ Objects_Locations location;
+ boolean activated;
+
+ if ( value == NULL ) {
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ /* First, it verifies if the structure "value" is correct */
+ if ( ( value->it_value.tv_nsec > MAX_NSEC_C ) ||
+ ( value->it_value.tv_nsec < MIN_NSEC_C ) ) {
+ /* The number of nanoseconds is not correct */
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ /* XXX check for seconds in the past */
+
+ if ( flags != TIMER_ABSTIME && flags != TIMER_RELATIVE_C ) {
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ /* If the function reaches this point, then it will be necessary to do
+ * something with the structure of times of the timer: to stop, start
+ * or start it again
+ */
+
+ ptimer = _POSIX_Timer_Get( timerid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return -1;
+ rtems_set_errno_and_return_minus_one( EINVAL );
+#endif
+
+ case OBJECTS_ERROR:
+ return -1;
+
+ case OBJECTS_LOCAL:
+ /* First, it verifies if the timer must be stopped */
+ if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) {
+ /* Stop the timer */
+ (void) _Watchdog_Remove( &ptimer->Timer );
+ /* The old data of the timer are returned */
+ if ( ovalue )
+ *ovalue = ptimer->timer_data;
+ /* The new data are set */
+ ptimer->timer_data = *value;
+ /* Indicates that the timer is created and stopped */
+ ptimer->state = STATE_CREATE_STOP_C;
+ /* Returns with success */
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+
+ /* absolute or relative? */
+ switch (flags) {
+ case TIMER_ABSTIME:
+
+ /* The fire time is absolute: use "rtems_time_fire_when" */
+ /* First, it converts from struct itimerspec to rtems_time_of_day */
+
+#if 0
+ ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S( value, &tod );
+ status = rtems_timer_fire_when(
+ ptimer->timer_id, &tod, _POSIX_Timer_TSR, ptimer);
+#endif
+ _Watchdog_Initialize(
+ &ptimer->Timer, _POSIX_Timer_TSR, ptimer->Object.id, ptimer );
+
+ _Watchdog_Insert_seconds(
+ &ptimer->Timer,
+ value->it_value.tv_sec - _TOD_Seconds_since_epoch
+ );
+
+ /* Returns the old ones in "ovalue" */
+ if ( ovalue )
+ *ovalue = ptimer->timer_data;
+ ptimer->timer_data = *value;
+
+ /* Indicate that the time is running */
+ ptimer->state = STATE_CREATE_RUN_C;
+
+ /* Stores the time in which the timer was started again */
+ ptimer->time = _TOD_Current;
+ _Thread_Enable_dispatch();
+ return 0;
+ break;
+
+ /* The fire time is relative: use "rtems_time_fire_after" */
+ case TIMER_RELATIVE_C:
+ /* First, convert from seconds and nanoseconds to ticks */
+ ptimer->ticks = ( SEC_TO_TICKS_C * value->it_value.tv_sec ) +
+ ( value->it_value.tv_nsec / (NSEC_PER_SEC_C / SEC_TO_TICKS_C));
+
+#if 0
+ status = rtems_timer_fire_after(
+ ptimer->timer_id, ptimer->ticks, _POSIX_Timer_TSR, ptimer );
+#endif
+ activated = _Watchdog_Insert_ticks_helper(
+ &ptimer->Timer,
+ ptimer->ticks,
+ ptimer->Object.id,
+ _POSIX_Timer_TSR,
+ ptimer
+ );
+ if ( !activated )
+ return 0;
+
+ /* The timer has been started and is running */
+ /* return the old ones in "ovalue" */
+ if ( ovalue )
+ *ovalue = ptimer->timer_data;
+ ptimer->timer_data = *value;
+
+ /* Indicate that the time is running */
+ ptimer->state = STATE_CREATE_RUN_C;
+ ptimer->time = _TOD_Current;
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+ return -1; /* unreached - only to remove warnings */
+}
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ */
+
+/* **************
+ * timer_gettime
+ * **************/
+
+int timer_gettime(
+ timer_t timerid,
+ struct itimerspec *value
+)
+{
+
+ /*
+ * IDEA: This function does not use functions of RTEMS to the handle
+ * of timers. It uses some functions for managing the time.
+ *
+ * A possible form to do this is the following:
+ *
+ * - When a timer is initialized, the value of the time in
+ * that moment is stored.
+ * - When this function is called, it returns the difference
+ * between the current time and the initialization time.
+ */
+
+ POSIX_Timer_Control *ptimer;
+ Objects_Locations location;
+ rtems_time_of_day current_time;
+ uint32_t hours;
+ uint32_t minutes;
+ uint32_t seconds;
+ uint32_t ticks;
+ uint32_t nanosec;
+
+ /* Reads the current time */
+ current_time = _TOD_Current;
+
+ ptimer = _POSIX_Timer_Get( timerid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+#endif
+
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ case OBJECTS_LOCAL:
+ /* Calculates the difference between the start time of the timer and
+ * the current one */
+
+ hours = current_time.hour - ptimer->time.hour;
+
+ if ( current_time.minute < ptimer->time.minute ) {
+ minutes = 60 - ptimer->time.minute + current_time.minute;
+ hours--;
+ } else {
+ minutes = current_time.minute - ptimer->time.minute;
+ }
+
+ if ( current_time.second < ptimer->time.second ) {
+ seconds = 60 - ptimer->time.second + current_time.second;
+ minutes--;
+ } else {
+ seconds = current_time.second - ptimer->time.second;
+ }
+
+ if ( current_time.ticks < ptimer->time.ticks ) {
+ ticks = 100 - ptimer->time.ticks + current_time.ticks;
+ seconds--;
+ } else {
+ ticks = current_time.ticks - ptimer->time.ticks;
+ }
+
+ /* The time that the timer is running is calculated */
+ seconds = hours * 60 * 60 +
+ minutes * 60 +
+ seconds;
+
+ nanosec = ticks * 10 * /* msec */
+ 1000 * /* microsec */
+ 1000; /* nanosec */
+
+
+ /* Calculates the time left before the timer finishes */
+
+ value->it_value.tv_sec = ptimer->timer_data.it_value.tv_sec - seconds;
+ value->it_value.tv_nsec = ptimer->timer_data.it_value.tv_nsec - nanosec;
+
+ value->it_interval.tv_sec = ptimer->timer_data.it_interval.tv_sec;
+ value->it_interval.tv_nsec = ptimer->timer_data.it_interval.tv_nsec;
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return -1; /* unreached - only to remove warnings */
+}
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ */
+
+/*
+ * timer_getoverrun
+ *
+ * The expiration of a timer must increase by one a counter.
+ * After the signal handler associated to the timer finishes
+ * its execution, _POSIX_Timer_TSR will have to set this counter to 0.
+ */
+
+int timer_getoverrun(
+ timer_t timerid
+)
+{
+ int overrun;
+ POSIX_Timer_Control *ptimer;
+ Objects_Locations location;
+
+ ptimer = _POSIX_Timer_Get( timerid, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+#endif
+
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ case OBJECTS_LOCAL:
+ overrun = ptimer->overrun;
+ ptimer->overrun = 0;
+ _Thread_Enable_dispatch();
+ return overrun;
+ }
+ return -1; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/posix/src/sched.c b/cpukit/posix/src/sched.c
new file mode 100644
index 0000000000..13b8db2a71
--- /dev/null
+++ b/cpukit/posix/src/sched.c
@@ -0,0 +1,157 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <sched.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/thread.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 13.3.1 Set Scheduling Parameters, P1003.1b-1993, p. 252
+ *
+ */
+
+int sched_setparam(
+ pid_t pid,
+ const struct sched_param *param
+)
+{
+ rtems_set_errno_and_return_minus_one( ENOSYS );
+}
+
+/*PAGE
+ *
+ * 13.3.2 Set Scheduling Parameters, P1003.1b-1993, p. 253
+ */
+
+int sched_getparam(
+ pid_t pid,
+ const struct sched_param *param
+)
+{
+ rtems_set_errno_and_return_minus_one( ENOSYS );
+}
+
+/*PAGE
+ *
+ * 13.3.3 Set Scheduling Policy and Scheduling Parameters,
+ * P1003.1b-1993, p. 254
+ */
+
+int sched_setscheduler(
+ pid_t pid,
+ int policy,
+ const struct sched_param *param
+)
+{
+ rtems_set_errno_and_return_minus_one( ENOSYS );
+}
+
+/*PAGE
+ *
+ * 13.3.4 Get Scheduling Policy, P1003.1b-1993, p. 256
+ */
+
+int sched_getscheduler(
+ pid_t pid
+)
+{
+ rtems_set_errno_and_return_minus_one( ENOSYS );
+}
+
+/*PAGE
+ *
+ * 13.3.6 Get Scheduling Parameter Limits, P1003.1b-1993, p. 258
+ */
+
+int sched_get_priority_max(
+ int policy
+)
+{
+ switch ( policy ) {
+ case SCHED_OTHER:
+ case SCHED_FIFO:
+ case SCHED_RR:
+ case SCHED_SPORADIC:
+ break;
+
+ default:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ return POSIX_SCHEDULER_MAXIMUM_PRIORITY;
+}
+
+/*PAGE
+ *
+ * 13.3.6 Get Scheduling Parameter Limits, P1003.1b-1993, p. 258
+ */
+
+int sched_get_priority_min(
+ int policy
+)
+{
+ switch ( policy ) {
+ case SCHED_OTHER:
+ case SCHED_FIFO:
+ case SCHED_RR:
+ case SCHED_SPORADIC:
+ break;
+
+ default:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ return POSIX_SCHEDULER_MINIMUM_PRIORITY;
+}
+
+/*PAGE
+ *
+ * 13.3.6 Get Scheduling Parameter Limits, P1003.1b-1993, p. 258
+ */
+
+int sched_rr_get_interval(
+ pid_t pid,
+ struct timespec *interval
+)
+{
+ /* XXX do we need to support different time quantums per thread */
+
+ /*
+ * Only supported for the "calling process" (i.e. this node).
+ */
+
+ if ( pid && pid != getpid() )
+ rtems_set_errno_and_return_minus_one( ESRCH );
+
+ if ( !interval )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ _POSIX_Interval_to_timespec( _Thread_Ticks_per_timeslice, interval );
+ return 0;
+}
+
+/*PAGE
+ *
+ * 13.3.5 Yield Processor, P1003.1b-1993, p. 257
+ */
+
+int sched_yield( void )
+{
+ _Thread_Disable_dispatch();
+ _Thread_Yield_processor();
+ _Thread_Enable_dispatch();
+ return 0;
+}
diff --git a/cpukit/posix/src/semaphore.c b/cpukit/posix/src/semaphore.c
new file mode 100644
index 0000000000..3ec96d8366
--- /dev/null
+++ b/cpukit/posix/src/semaphore.c
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Manager_initialization
+ *
+ * This routine initializes all semaphore manager related data structures.
+ *
+ * Input parameters:
+ * maximum_semaphores - maximum configured semaphores
+ *
+ * Output parameters: NONE
+ */
+
+void _POSIX_Semaphore_Manager_initialization(
+ uint32_t maximum_semaphores
+)
+{
+ _Objects_Initialize_information(
+ &_POSIX_Semaphore_Information, /* object information table */
+ OBJECTS_POSIX_API, /* object API */
+ OBJECTS_POSIX_SEMAPHORES, /* object class */
+ maximum_semaphores /* maximum objects of this class */,
+ sizeof( POSIX_Semaphore_Control ),
+ /* size of this object's control block */
+ TRUE, /* TRUE if names for this object are strings */
+ _POSIX_PATH_MAX /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+}
diff --git a/cpukit/posix/src/semaphorecreatesupp.c b/cpukit/posix/src/semaphorecreatesupp.c
new file mode 100644
index 0000000000..64d8f435b0
--- /dev/null
+++ b/cpukit/posix/src/semaphorecreatesupp.c
@@ -0,0 +1,129 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+#include <string.h> /* strlen */
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Create_support
+ *
+ * This routine does the actual creation and initialization of
+ * a poxix semaphore. It is a support routine for sem_init and
+ * sem_open.
+ */
+
+int _POSIX_Semaphore_Create_support(
+ const char *name,
+ int pshared,
+ unsigned int value,
+ POSIX_Semaphore_Control **the_sem
+)
+{
+ POSIX_Semaphore_Control *the_semaphore;
+ CORE_semaphore_Attributes *the_sem_attr;
+
+ _Thread_Disable_dispatch();
+
+ /* Sharing semaphores among processes is not currently supported */
+ if (pshared != 0) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( ENOSYS );
+ }
+
+ if ( name ) {
+ if( strlen(name) > PATH_MAX ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( ENAMETOOLONG );
+ }
+ }
+
+ the_semaphore = _POSIX_Semaphore_Allocate();
+
+ if ( !the_semaphore ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( ENOSPC );
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( pshared == PTHREAD_PROCESS_SHARED &&
+ !( _Objects_MP_Allocate_and_open( &_POSIX_Semaphore_Information, 0,
+ the_semaphore->Object.id, FALSE ) ) ) {
+ _POSIX_Semaphore_Free( the_semaphore );
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( EAGAIN );
+ }
+#endif
+
+ the_semaphore->process_shared = pshared;
+
+ if ( name ) {
+ the_semaphore->named = TRUE;
+ the_semaphore->open_count = 1;
+ the_semaphore->linked = TRUE;
+ }
+ else
+ the_semaphore->named = FALSE;
+
+ the_sem_attr = &the_semaphore->Semaphore.Attributes;
+
+ /*
+ * POSIX does not appear to specify what the discipline for
+ * blocking tasks on this semaphore should be. It could somehow
+ * be derived from the current scheduling policy. One
+ * thing is certain, no matter what we decide, it won't be
+ * the same as all other POSIX implementations. :)
+ */
+
+ the_sem_attr->discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
+
+ /*
+ * This effectively disables limit checking.
+ */
+
+ the_sem_attr->maximum_count = 0xFFFFFFFF;
+
+ _CORE_semaphore_Initialize( &the_semaphore->Semaphore, the_sem_attr, value );
+
+ /*
+ * Make the semaphore available for use.
+ */
+
+ _Objects_Open(
+ &_POSIX_Semaphore_Information,
+ &the_semaphore->Object,
+ (char *) name
+ );
+
+ *the_sem = the_semaphore;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( pshared == PTHREAD_PROCESS_SHARED )
+ _POSIX_Semaphore_MP_Send_process_packet(
+ POSIX_SEMAPHORE_MP_ANNOUNCE_CREATE,
+ the_semaphore->Object.id,
+ (char *) name,
+ 0 /* proxy id - Not used */
+ );
+#endif
+
+ _Thread_Enable_dispatch();
+ return 0;
+}
diff --git a/cpukit/posix/src/semaphoredeletesupp.c b/cpukit/posix/src/semaphoredeletesupp.c
new file mode 100644
index 0000000000..44b00fcd67
--- /dev/null
+++ b/cpukit/posix/src/semaphoredeletesupp.c
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Delete
+ */
+
+void _POSIX_Semaphore_Delete(
+ POSIX_Semaphore_Control *the_semaphore
+)
+{
+ if ( !the_semaphore->linked && !the_semaphore->open_count ) {
+ _Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );
+
+ _CORE_semaphore_Flush(
+ &the_semaphore->Semaphore,
+#if defined(RTEMS_MULTIPROCESSING)
+ _POSIX_Semaphore_MP_Send_object_was_deleted,
+#else
+ NULL,
+#endif
+ -1 /* XXX should also seterrno -> EINVAL */
+ );
+
+ _POSIX_Semaphore_Free( the_semaphore );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
+
+ _Objects_MP_Close(
+ &_POSIX_Semaphore_Information,
+ the_semaphore->Object.id
+ );
+
+ _POSIX_Semaphore_MP_Send_process_packet(
+ POSIX_SEMAPHORE_MP_ANNOUNCE_DELETE,
+ the_semaphore->Object.id,
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+ }
+#endif
+
+ }
+}
diff --git a/cpukit/posix/src/semaphoremp.c b/cpukit/posix/src/semaphoremp.c
new file mode 100644
index 0000000000..d5a4cf9f1e
--- /dev/null
+++ b/cpukit/posix/src/semaphoremp.c
@@ -0,0 +1,146 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+#if defined(RTEMS_MULTIPROCESSING)
+/*
+ * _POSIX_Semaphore_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+
+void _POSIX_Semaphore_MP_Send_process_packet(
+ POSIX_Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ Objects_Name name,
+ Objects_Id proxy_id
+)
+{
+ POSIX_MP_NOT_IMPLEMENTED();
+}
+
+/*
+ * _POSIX_Semaphore_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+int _POSIX_Semaphore_MP_Send_request_packet(
+ POSIX_Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ boolean wait, /* XXX options */
+ Watchdog_Interval timeout
+)
+{
+ POSIX_MP_NOT_IMPLEMENTED();
+ return 0;
+}
+
+/*
+ * _POSIX_Semaphore_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _POSIX_Semaphore_MP_Send_response_packet(
+ POSIX_Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ Thread_Control *the_thread
+)
+{
+ POSIX_MP_NOT_IMPLEMENTED();
+}
+
+/*
+ *
+ * _POSIX_Semaphore_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _POSIX_Semaphore_MP_Process_packet(
+ MP_packet_Prefix *the_packet_prefix
+)
+{
+ POSIX_MP_NOT_IMPLEMENTED();
+}
+
+/*
+ * _POSIX_Semaphore_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Semaphore_MP_Send_object_was_deleted(
+ Thread_Control *the_proxy
+)
+{
+ POSIX_MP_NOT_IMPLEMENTED();
+}
+
+/*
+ * _POSIX_Semaphore_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _POSIX_Semaphore_MP_Send_extract_proxy(
+ Thread_Control *the_thread
+)
+{
+ POSIX_MP_NOT_IMPLEMENTED();
+}
+
+/*
+ * _POSIX_Semaphore_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a semaphore mp packet.
+ */
+
+POSIX_Semaphore_MP_Packet *_POSIX_Semaphore_MP_Get_packet( void )
+{
+ POSIX_MP_NOT_IMPLEMENTED();
+ return NULL;
+}
+
+#endif /* endif RTEMS_MULTIPROCESSING */
diff --git a/cpukit/posix/src/semaphorenametoid.c b/cpukit/posix/src/semaphorenametoid.c
new file mode 100644
index 0000000000..eb1a4686cf
--- /dev/null
+++ b/cpukit/posix/src/semaphorenametoid.c
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Name_to_id
+ *
+ * Look up the specified name and attempt to locate the id
+ * for the associated semaphore.
+ */
+
+int _POSIX_Semaphore_Name_to_id(
+ const char *name,
+ sem_t *id
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ if ( !name )
+ return EINVAL;
+
+ if ( !name[0] )
+ return EINVAL;
+
+ status = _Objects_Name_to_id(
+ &_POSIX_Semaphore_Information, (char *)name, 0, (Objects_Id*)id );
+
+ if ( status == OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL )
+ return 0;
+
+ return ENOENT;
+}
diff --git a/cpukit/posix/src/semaphorewaitsupp.c b/cpukit/posix/src/semaphorewaitsupp.c
new file mode 100644
index 0000000000..7c76ff87bd
--- /dev/null
+++ b/cpukit/posix/src/semaphorewaitsupp.c
@@ -0,0 +1,71 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Wait_support
+ */
+
+int _POSIX_Semaphore_Wait_support(
+ sem_t *sem,
+ boolean blocking,
+ Watchdog_Interval timeout
+)
+{
+ register POSIX_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _POSIX_Semaphore_Get( sem, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_LOCAL:
+ _CORE_semaphore_Seize(
+ &the_semaphore->Semaphore,
+ the_semaphore->Object.id,
+ blocking,
+ timeout
+ );
+ _Thread_Enable_dispatch();
+ switch ( _Thread_Executing->Wait.return_code ) {
+ case CORE_SEMAPHORE_STATUS_SUCCESSFUL:
+ break;
+ case CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT:
+ rtems_set_errno_and_return_minus_one( EAGAIN );
+ case CORE_SEMAPHORE_WAS_DELETED:
+ rtems_set_errno_and_return_minus_one( EAGAIN );
+ case CORE_SEMAPHORE_TIMEOUT:
+ rtems_set_errno_and_return_minus_one( ETIMEDOUT );
+ break;
+ case CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED:
+ /*
+ * This error can not occur since we set the maximum
+ * count to the largest value the count can hold.
+ */
+ break;
+ }
+ }
+ return 0;
+}
diff --git a/cpukit/posix/src/semclose.c b/cpukit/posix/src/semclose.c
new file mode 100644
index 0000000000..83b72f36e0
--- /dev/null
+++ b/cpukit/posix/src/semclose.c
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+
+/*PAGE
+ *
+ * sem_close
+ *
+ * Routine to close a semaphore that has been opened or initialized.
+ *
+ * 11.2.4 Close a Named Semaphore, P1003.1b-1993, p.224
+ */
+
+int sem_close(
+ sem_t *sem
+)
+{
+ register POSIX_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _POSIX_Semaphore_Get( sem, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_LOCAL:
+ the_semaphore->open_count -= 1;
+ _POSIX_Semaphore_Delete( the_semaphore );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/semdestroy.c b/cpukit/posix/src/semdestroy.c
new file mode 100644
index 0000000000..2daccce17c
--- /dev/null
+++ b/cpukit/posix/src/semdestroy.c
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 11.2.2 Destroy an Unnamed Semaphore, P1003.1b-1993, p.220
+ */
+
+int sem_destroy(
+ sem_t *sem
+)
+{
+ register POSIX_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _POSIX_Semaphore_Get( sem, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_LOCAL:
+ /*
+ * Undefined operation on a named semaphore.
+ */
+
+ if ( the_semaphore->named == TRUE ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ _POSIX_Semaphore_Delete( the_semaphore );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/semgetvalue.c b/cpukit/posix/src/semgetvalue.c
new file mode 100644
index 0000000000..e2bf9f83b2
--- /dev/null
+++ b/cpukit/posix/src/semgetvalue.c
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 11.2.8 Get the Value of a Semaphore, P1003.1b-1993, p.229
+ */
+
+int sem_getvalue(
+ sem_t *sem,
+ int *sval
+)
+{
+ register POSIX_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _POSIX_Semaphore_Get( sem, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_LOCAL:
+ *sval = _CORE_semaphore_Get_count( &the_semaphore->Semaphore );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/seminit.c b/cpukit/posix/src/seminit.c
new file mode 100644
index 0000000000..449f2c1c01
--- /dev/null
+++ b/cpukit/posix/src/seminit.c
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 11.2.1 Initialize an Unnamed Semaphore, P1003.1b-1993, p.219
+ */
+
+int sem_init(
+ sem_t *sem,
+ int pshared,
+ unsigned int value
+)
+{
+ int status;
+ POSIX_Semaphore_Control *the_semaphore;
+
+ if ( !sem )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ status = _POSIX_Semaphore_Create_support(
+ NULL,
+ pshared,
+ value,
+ &the_semaphore
+ );
+
+ if ( status != -1 )
+ *sem = the_semaphore->Object.id;
+
+ return status;
+}
diff --git a/cpukit/posix/src/semopen.c b/cpukit/posix/src/semopen.c
new file mode 100644
index 0000000000..1e31451932
--- /dev/null
+++ b/cpukit/posix/src/semopen.c
@@ -0,0 +1,125 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * sem_open
+ *
+ * Opens a named semaphore. Used in conjunction with the sem_close
+ * and sem_unlink commands.
+ *
+ * 11.2.3 Initialize/Open a Named Semaphore, P1003.1b-1993, p.221
+ *
+ * NOTE: When oflag is O_CREAT, then optional third and fourth
+ * parameters must be present.
+ */
+
+sem_t *sem_open(
+ const char *name,
+ int oflag,
+ ...
+ /* mode_t mode, */
+ /* unsigned int value */
+)
+{
+ va_list arg;
+ mode_t mode;
+ unsigned int value = 0;
+ int status;
+ sem_t the_semaphore_id;
+ Objects_Id *id;
+ POSIX_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ _Thread_Disable_dispatch();
+
+ if ( oflag & O_CREAT ) {
+ va_start(arg, oflag);
+ mode = (mode_t) va_arg( arg, unsigned int );
+ value = va_arg( arg, unsigned int );
+ va_end(arg);
+ }
+
+ status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id );
+
+ /*
+ * If the name to id translation worked, then the semaphore exists
+ * and we can just return a pointer to the id. Otherwise we may
+ * need to check to see if this is a "semaphore does not exist"
+ * or some other miscellaneous error on the name.
+ */
+
+ if ( status ) {
+
+ /*
+ * Unless provided a valid name that did not already exist
+ * and we are willing to create then it is an error.
+ */
+
+ if ( !( status == ENOENT && (oflag & O_CREAT) ) ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one_cast( status, sem_t * );
+ }
+ } else {
+
+ /*
+ * Check for existence with creation.
+ */
+
+ if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one_cast( EEXIST, sem_t * );
+ }
+
+ the_semaphore = _POSIX_Semaphore_Get( &the_semaphore_id, &location );
+ the_semaphore->open_count += 1;
+ _Thread_Enable_dispatch();
+ _Thread_Enable_dispatch();
+ id = &the_semaphore->Object.id;
+ return (sem_t *)id;
+
+ }
+
+ /*
+ * At this point, the semaphore does not exist and everything has been
+ * checked. We should go ahead and create a semaphore.
+ */
+
+ status =_POSIX_Semaphore_Create_support(
+ name,
+ FALSE, /* not shared across processes */
+ value,
+ &the_semaphore
+ );
+
+ /*
+ * errno was set by Create_support, so don't set it again.
+ */
+
+ _Thread_Enable_dispatch();
+
+ if ( status == -1 )
+ return SEM_FAILED;
+
+ id = &the_semaphore->Object.id;
+ return (sem_t *)id;
+}
diff --git a/cpukit/posix/src/sempost.c b/cpukit/posix/src/sempost.c
new file mode 100644
index 0000000000..a4d7a36876
--- /dev/null
+++ b/cpukit/posix/src/sempost.c
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 11.2.7 Unlock a Semaphore, P1003.1b-1993, p.227
+ */
+
+int sem_post(
+ sem_t *sem
+)
+{
+ register POSIX_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _POSIX_Semaphore_Get( sem, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ case OBJECTS_LOCAL:
+ _CORE_semaphore_Surrender(
+ &the_semaphore->Semaphore,
+ the_semaphore->Object.id,
+#if defined(RTEMS_MULTIPROCESSING)
+ NULL /* XXX need to define a routine to handle this case */
+#else
+ NULL
+#endif
+ );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/cpukit/posix/src/semtimedwait.c b/cpukit/posix/src/semtimedwait.c
new file mode 100644
index 0000000000..6acb704f7c
--- /dev/null
+++ b/cpukit/posix/src/semtimedwait.c
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
+ *
+ * NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
+ */
+
+int sem_timedwait(
+ sem_t *sem,
+ const struct timespec *abstime
+)
+{
+ /*
+ * The abstime is a walltime. We turn it into an interval.
+ */
+ Watchdog_Interval ticks;
+ struct timespec current_time;
+ struct timespec difference;
+
+ /*
+ * Error check the absolute time to timeout
+ */
+ if ( /* abstime->tv_sec < 0 || */ abstime->tv_nsec ) /* tv_sec is unsigned */
+ return EINVAL;
+
+ if ( abstime->tv_nsec >= TOD_NANOSECONDS_PER_SECOND )
+ return EINVAL;
+
+ (void) clock_gettime( CLOCK_REALTIME, &current_time );
+
+ /*
+ * Make sure the abstime is in the future
+ */
+ if ( abstime->tv_sec < current_time.tv_sec )
+ return EINVAL;
+ if ( (abstime->tv_sec == current_time.tv_sec) &&
+ (abstime->tv_nsec <= current_time.tv_nsec) )
+ return EINVAL;
+
+ _POSIX_Timespec_subtract( &current_time, abstime, &difference );
+
+ ticks = _POSIX_Timespec_to_interval( &difference );
+
+ return _POSIX_Semaphore_Wait_support( sem, TRUE, ticks );
+}
+
diff --git a/cpukit/posix/src/semtrywait.c b/cpukit/posix/src/semtrywait.c
new file mode 100644
index 0000000000..2aecde9425
--- /dev/null
+++ b/cpukit/posix/src/semtrywait.c
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
+ *
+ * NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
+ */
+
+int sem_trywait(
+ sem_t *sem
+)
+{
+ return _POSIX_Semaphore_Wait_support( sem, FALSE, THREAD_QUEUE_WAIT_FOREVER );
+}
diff --git a/cpukit/posix/src/semunlink.c b/cpukit/posix/src/semunlink.c
new file mode 100644
index 0000000000..53475f1527
--- /dev/null
+++ b/cpukit/posix/src/semunlink.c
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * sem_unlink
+ *
+ * Unlinks a named semaphore, sem_close must also be called to remove
+ * the semaphore.
+ *
+ * 11.2.5 Remove a Named Semaphore, P1003.1b-1993, p.225
+ */
+
+int sem_unlink(
+ const char *name
+)
+{
+ int status;
+ register POSIX_Semaphore_Control *the_semaphore;
+ sem_t the_semaphore_id;
+
+ _Thread_Disable_dispatch();
+
+ status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id );
+ if ( status != 0 ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( status );
+ }
+
+ /*
+ * Don't support unlinking a remote semaphore.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id((Objects_Id)the_semaphore_id) ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( ENOSYS );
+ }
+#endif
+
+ the_semaphore = (POSIX_Semaphore_Control *) _Objects_Get_local_object(
+ &_POSIX_Semaphore_Information,
+ _Objects_Get_index( the_semaphore_id )
+ );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
+ _Objects_MP_Close( &_POSIX_Semaphore_Information, the_semaphore_id );
+ }
+#endif
+
+ the_semaphore->linked = FALSE;
+ _POSIX_Semaphore_Namespace_remove( the_semaphore );
+ _POSIX_Semaphore_Delete( the_semaphore );
+
+ _Thread_Enable_dispatch();
+ return 0;
+}
diff --git a/cpukit/posix/src/semwait.c b/cpukit/posix/src/semwait.c
new file mode 100644
index 0000000000..9ef787c727
--- /dev/null
+++ b/cpukit/posix/src/semwait.c
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+#include <rtems/seterr.h>
+
+/*PAGE
+ *
+ * 11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
+ *
+ * NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
+ */
+
+int sem_wait(
+ sem_t *sem
+)
+{
+ return _POSIX_Semaphore_Wait_support( sem, TRUE, THREAD_QUEUE_WAIT_FOREVER );
+}
diff --git a/cpukit/posix/src/setcancelstate.c b/cpukit/posix/src/setcancelstate.c
new file mode 100644
index 0000000000..94050bfc91
--- /dev/null
+++ b/cpukit/posix/src/setcancelstate.c
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/cancel.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/threadsup.h>
+
+/*PAGE
+ *
+ * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
+ */
+
+int pthread_setcancelstate(
+ int state,
+ int *oldstate
+)
+{
+ POSIX_API_Control *thread_support;
+
+ /*
+ * Don't even think about deleting a resource from an ISR.
+ * Besides this request is supposed to be for _Thread_Executing
+ * and the ISR context is not a thread.
+ */
+
+ if ( _ISR_Is_in_progress() )
+ return EPROTO;
+
+ if ( !oldstate )
+ return EINVAL;
+
+ if ( state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE )
+ return EINVAL;
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ _Thread_Disable_dispatch();
+ *oldstate = thread_support->cancelability_state;
+ thread_support->cancelability_state = state;
+
+ if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
+ thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS &&
+ thread_support->cancelation_requested )
+ _POSIX_Threads_cancel_run( _Thread_Executing );
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
diff --git a/cpukit/posix/src/setcanceltype.c b/cpukit/posix/src/setcanceltype.c
new file mode 100644
index 0000000000..a7b7655f1d
--- /dev/null
+++ b/cpukit/posix/src/setcanceltype.c
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/cancel.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/threadsup.h>
+
+/*PAGE
+ *
+ * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
+ */
+
+int pthread_setcanceltype(
+ int type,
+ int *oldtype
+)
+{
+ POSIX_API_Control *thread_support;
+
+ /*
+ * Don't even think about deleting a resource from an ISR.
+ * Besides this request is supposed to be for _Thread_Executing
+ * and the ISR context is not a thread.
+ */
+
+ if ( _ISR_Is_in_progress() )
+ return EPROTO;
+
+ if ( !oldtype )
+ return EINVAL;
+
+ if ( type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS )
+ return EINVAL;
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ _Thread_Disable_dispatch();
+ *oldtype = thread_support->cancelability_type;
+ thread_support->cancelability_type = type;
+
+ if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
+ thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS &&
+ thread_support->cancelation_requested )
+ _POSIX_Threads_cancel_run( _Thread_Executing );
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
diff --git a/cpukit/posix/src/sigaction.c b/cpukit/posix/src/sigaction.c
new file mode 100644
index 0000000000..a8d48f9f3b
--- /dev/null
+++ b/cpukit/posix/src/sigaction.c
@@ -0,0 +1,93 @@
+/*
+ * 3.3.4 Examine and Change Signal Action, P1003.1b-1993, p. 70
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/seterr.h>
+#include <rtems/score/isr.h>
+
+/*
+ * PARAMETERS_PASSING_S is defined in ptimer.c
+ */
+
+extern void PARAMETERS_PASSING_S (int num_signal, const struct sigaction inf);
+
+int sigaction(
+ int sig,
+ const struct sigaction *act,
+ struct sigaction *oact
+)
+{
+ ISR_Level level;
+
+ if ( oact )
+ *oact = _POSIX_signals_Vectors[ sig ];
+
+ if ( !sig )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( !is_valid_signo(sig) )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ /*
+ * Some signals cannot be ignored (P1003.1b-1993, pp. 70-72 and references.
+ *
+ * NOTE: Solaris documentation claims to "silently enforce" this which
+ * contradicts the POSIX specification.
+ */
+
+ if ( sig == SIGKILL )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ /*
+ * Evaluate the new action structure and set the global signal vector
+ * appropriately.
+ */
+
+ if ( act ) {
+
+ /*
+ * Unless the user is installing the default signal actions, then
+ * we can just copy the provided sigaction structure into the vectors.
+ */
+
+ _ISR_Disable( level );
+ if ( act->sa_handler == SIG_DFL ) {
+ _POSIX_signals_Vectors[ sig ] = _POSIX_signals_Default_vectors[ sig ];
+ } else {
+ _POSIX_signals_Clear_process_signals( signo_to_mask(sig) );
+ _POSIX_signals_Vectors[ sig ] = *act;
+ }
+ _ISR_Enable( level );
+ }
+
+ /*
+ * No need to evaluate or dispatch because:
+ *
+ * + If we were ignoring the signal before, none could be pending
+ * now (signals not posted when SIG_IGN).
+ * + If we are now ignoring a signal that was previously pending,
+ * we clear the pending signal indicator.
+ */
+
+ return 0;
+}
diff --git a/cpukit/posix/src/sigaddset.c b/cpukit/posix/src/sigaddset.c
new file mode 100644
index 0000000000..5ac0fe0f17
--- /dev/null
+++ b/cpukit/posix/src/sigaddset.c
@@ -0,0 +1,42 @@
+/*
+ * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/seterr.h>
+
+int sigaddset(
+ sigset_t *set,
+ int signo
+)
+{
+ if ( !set )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( !signo )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( !is_valid_signo(signo) )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ *set |= signo_to_mask(signo);
+ return 0;
+}
diff --git a/cpukit/posix/src/sigdelset.c b/cpukit/posix/src/sigdelset.c
new file mode 100644
index 0000000000..be0135a7b5
--- /dev/null
+++ b/cpukit/posix/src/sigdelset.c
@@ -0,0 +1,46 @@
+/*
+ * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/seterr.h>
+
+/*
+ * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
+ */
+
+int sigdelset(
+ sigset_t *set,
+ int signo
+)
+{
+ if ( !set )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( !signo )
+ return 0;
+
+ if ( !is_valid_signo(signo) )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ *set &= ~signo_to_mask(signo);
+ return 0;
+}
diff --git a/cpukit/posix/src/sigemptyset.c b/cpukit/posix/src/sigemptyset.c
new file mode 100644
index 0000000000..a216ad7a8c
--- /dev/null
+++ b/cpukit/posix/src/sigemptyset.c
@@ -0,0 +1,35 @@
+/*
+ * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/seterr.h>
+
+int sigemptyset(
+ sigset_t *set
+)
+{
+ if ( !set )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ *set = 0;
+ return 0;
+}
diff --git a/cpukit/posix/src/sigfillset.c b/cpukit/posix/src/sigfillset.c
new file mode 100644
index 0000000000..dd8aa82c69
--- /dev/null
+++ b/cpukit/posix/src/sigfillset.c
@@ -0,0 +1,35 @@
+/*
+ * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/seterr.h>
+
+int sigfillset(
+ sigset_t *set
+)
+{
+ if ( !set )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ *set = SIGNAL_ALL_MASK;
+ return 0;
+}
diff --git a/cpukit/posix/src/sigismember.c b/cpukit/posix/src/sigismember.c
new file mode 100644
index 0000000000..3bdd32b729
--- /dev/null
+++ b/cpukit/posix/src/sigismember.c
@@ -0,0 +1,44 @@
+/*
+ * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/seterr.h>
+
+int sigismember(
+ const sigset_t *set,
+ int signo
+)
+{
+ if ( !set )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( !signo )
+ return 0;
+
+ if ( !is_valid_signo(signo) )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( *set & signo_to_mask(signo) )
+ return 1;
+
+ return 0;
+}
diff --git a/cpukit/posix/src/signal_2.c b/cpukit/posix/src/signal_2.c
new file mode 100644
index 0000000000..8d9c483803
--- /dev/null
+++ b/cpukit/posix/src/signal_2.c
@@ -0,0 +1,52 @@
+/*
+ * signal(2) - Install signal handler
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <signal.h>
+#include <errno.h>
+
+typedef void (*sighandler_t)(int);
+
+sighandler_t signal(
+ int signum,
+ sighandler_t handler
+)
+{
+ struct sigaction s;
+ struct sigaction old;
+
+ s.sa_handler = handler ;
+ sigemptyset(&s.sa_mask);
+
+ /*
+ * Depending on which system we want to behave like, one of
+ * the following versions should be chosen.
+ */
+
+/* #define signal_like_linux */
+
+#if defined(signal_like_linux)
+ s.sa_flags = SA_RESTART | SA_INTERRUPT | SA_NOMASK;
+ s.sa_restorer= NULL ;
+#elif defined(signal_like_SVR4)
+ s.sa_flags = SA_RESTART;
+#else
+ s.sa_flags = 0;
+#endif
+
+ sigaction( signum, &s, &old );
+ return (sighandler_t) old.sa_handler;
+}
diff --git a/cpukit/posix/src/sigpending.c b/cpukit/posix/src/sigpending.c
new file mode 100644
index 0000000000..9f22760a58
--- /dev/null
+++ b/cpukit/posix/src/sigpending.c
@@ -0,0 +1,40 @@
+/*
+ * 3.3.6 Examine Pending Signals, P1003.1b-1993, p. 75
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <signal.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/seterr.h>
+
+int sigpending(
+ sigset_t *set
+)
+{
+ POSIX_API_Control *api;
+
+ if ( !set )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ *set = api->signals_pending | _POSIX_signals_Pending;
+
+ return 0;
+}
diff --git a/cpukit/posix/src/sigprocmask.c b/cpukit/posix/src/sigprocmask.c
new file mode 100644
index 0000000000..c149a39065
--- /dev/null
+++ b/cpukit/posix/src/sigprocmask.c
@@ -0,0 +1,39 @@
+/*
+ * 3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
+ *
+ * NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+
+int sigprocmask(
+ int how,
+ const sigset_t *set,
+ sigset_t *oset
+)
+{
+ /*
+ * P1003.1c/Draft 10, p. 38 maps sigprocmask to pthread_sigmask.
+ */
+
+ return pthread_sigmask( how, set, oset );
+}
diff --git a/cpukit/posix/src/sigqueue.c b/cpukit/posix/src/sigqueue.c
new file mode 100644
index 0000000000..727f2c6b42
--- /dev/null
+++ b/cpukit/posix/src/sigqueue.c
@@ -0,0 +1,32 @@
+/*
+ * 3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+
+int sigqueue(
+ pid_t pid,
+ int signo,
+ const union sigval value
+)
+{
+ return killinfo( pid, signo, &value );
+}
diff --git a/cpukit/posix/src/sigsuspend.c b/cpukit/posix/src/sigsuspend.c
new file mode 100644
index 0000000000..aa330bc71c
--- /dev/null
+++ b/cpukit/posix/src/sigsuspend.c
@@ -0,0 +1,53 @@
+/*
+ * 3.3.7 Wait for a Signal, P1003.1b-1993, p. 75
+ *
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <signal.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/seterr.h>
+
+int sigsuspend(
+ const sigset_t *sigmask
+)
+{
+ sigset_t saved_signals_blocked;
+ sigset_t all_signals;
+ int status;
+ POSIX_API_Control *api;
+
+ api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ status = sigprocmask( SIG_BLOCK, sigmask, &saved_signals_blocked );
+
+ (void) sigfillset( &all_signals );
+
+ status = sigtimedwait( &all_signals, NULL, NULL );
+
+ (void) sigprocmask( SIG_SETMASK, &saved_signals_blocked, NULL );
+
+ /*
+ * sigtimedwait() returns the signal number while sigsuspend()
+ * is supposed to return -1 and EINTR when a signal is caught.
+ */
+ if ( status != -1 )
+ rtems_set_errno_and_return_minus_one( EINTR );
+
+ return status;
+}
diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c
new file mode 100644
index 0000000000..1486be3054
--- /dev/null
+++ b/cpukit/posix/src/sigtimedwait.c
@@ -0,0 +1,140 @@
+/*
+ * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+#include <rtems/score/isr.h>
+
+int _POSIX_signals_Get_highest(
+ sigset_t set
+)
+{
+ int signo;
+
+ for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
+ if ( set & signo_to_mask( signo ) )
+ return signo;
+ }
+
+/* XXX - add __SIGFIRSTNOTRT or something like that to newlib signal .h */
+
+ for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) {
+ if ( set & signo_to_mask( signo ) )
+ return signo;
+ }
+
+ return 0;
+}
+
+int sigtimedwait(
+ const sigset_t *set,
+ siginfo_t *info,
+ const struct timespec *timeout
+)
+{
+ Thread_Control *the_thread;
+ POSIX_API_Control *api;
+ Watchdog_Interval interval;
+ siginfo_t signal_information;
+ siginfo_t *the_info;
+ int signo;
+ ISR_Level level;
+
+ /*
+ * Error check parameters before disabling interrupts.
+ */
+
+ interval = 0;
+ if ( timeout ) {
+
+ if ( timeout->tv_nsec < 0 ||
+ timeout->tv_nsec >= TOD_NANOSECONDS_PER_SECOND) {
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ interval = _POSIX_Timespec_to_interval( timeout );
+ }
+
+ /*
+ * Initialize local variables.
+ */
+
+ the_info = ( info ) ? info : &signal_information;
+
+ the_thread = _Thread_Executing;
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ /*
+ * What if they are already pending?
+ */
+
+ /* API signals pending? */
+
+ _ISR_Disable( level );
+ if ( *set & api->signals_pending ) {
+ /* XXX real info later */
+ the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending );
+ _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, FALSE, FALSE );
+ _ISR_Enable( level );
+
+ the_info->si_code = SI_USER;
+ the_info->si_value.sival_int = 0;
+ return the_info->si_signo;
+ }
+
+ /* Process pending signals? */
+
+ if ( *set & _POSIX_signals_Pending ) {
+ signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending );
+ _POSIX_signals_Clear_signals( api, signo, the_info, TRUE, FALSE );
+ _ISR_Enable( level );
+
+ the_info->si_signo = signo;
+ the_info->si_code = SI_USER;
+ the_info->si_value.sival_int = 0;
+ return signo;
+ }
+
+ the_info->si_signo = -1;
+
+ _Thread_Disable_dispatch();
+ the_thread->Wait.queue = &_POSIX_signals_Wait_queue;
+ the_thread->Wait.return_code = EINTR;
+ the_thread->Wait.option = *set;
+ the_thread->Wait.return_argument = the_info;
+ _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
+ _ISR_Enable( level );
+ _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval );
+ _Thread_Enable_dispatch();
+
+ /*
+ * When the thread is set free by a signal, it is need to eliminate
+ * the signal.
+ */
+
+ _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, FALSE, FALSE );
+ errno = _Thread_Executing->Wait.return_code;
+ return the_info->si_signo;
+}
diff --git a/cpukit/posix/src/sigwait.c b/cpukit/posix/src/sigwait.c
new file mode 100644
index 0000000000..1c34b5ee5b
--- /dev/null
+++ b/cpukit/posix/src/sigwait.c
@@ -0,0 +1,44 @@
+/*
+ * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
+ *
+ * NOTE: P1003.1c/D10, p. 39 adds sigwait().
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+
+int sigwait(
+ const sigset_t *set,
+ int *sig
+)
+{
+ int status;
+
+ status = sigtimedwait( set, NULL, NULL );
+
+ if ( status != -1 ) {
+ if ( sig )
+ *sig = status;
+ return 0;
+ }
+
+ return errno;
+}
diff --git a/cpukit/posix/src/sigwaitinfo.c b/cpukit/posix/src/sigwaitinfo.c
new file mode 100644
index 0000000000..2c61e2a8fc
--- /dev/null
+++ b/cpukit/posix/src/sigwaitinfo.c
@@ -0,0 +1,33 @@
+/*
+ * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
+ *
+ * NOTE: P1003.1c/D10, p. 39 adds sigwait().
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <signal.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+
+int sigwaitinfo(
+ const sigset_t *set,
+ siginfo_t *info
+)
+{
+ return sigtimedwait( set, info, NULL );
+}
diff --git a/cpukit/posix/src/sleep.c b/cpukit/posix/src/sleep.c
new file mode 100644
index 0000000000..501fe5770f
--- /dev/null
+++ b/cpukit/posix/src/sleep.c
@@ -0,0 +1,31 @@
+/*
+ * 3.4.3 Delay Process Execution, P1003.1b-1993, p. 81
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <time.h>
+#include <unistd.h>
+
+#include <rtems/system.h>
+
+
+unsigned int sleep(
+ unsigned int seconds
+)
+{
+ /* XXX can we get away with this implementation? */
+ struct timespec tp;
+ struct timespec tm;
+
+ tp.tv_sec = seconds;
+ tp.tv_nsec = 0;
+
+ nanosleep( &tp, &tm );
+
+ return tm.tv_sec; /* seconds remaining */
+}
diff --git a/cpukit/posix/src/sysconf.c b/cpukit/posix/src/sysconf.c
new file mode 100644
index 0000000000..4a8add9e35
--- /dev/null
+++ b/cpukit/posix/src/sysconf.c
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/tod.h>
+
+/*PAGE
+ *
+ * 4.8.1 Get Configurable System Variables, P1003.1b-1993, p. 95
+ */
+
+long sysconf(
+ int name
+)
+{
+
+ switch (name) {
+ case _SC_CLK_TCK:
+ return _TOD_Ticks_per_second;
+
+ case _SC_OPEN_MAX: {
+ extern uint32_t rtems_libio_number_iops;
+ return rtems_libio_number_iops;
+ }
+
+ case _SC_GETPW_R_SIZE_MAX:
+ return 1024;
+
+#if defined(__sparc__)
+ case 515: /* Solaris _SC_STACK_PROT */
+ return 0;
+#endif
+
+ default:
+ break;
+ }
+
+ errno = EINVAL;
+ return -1;
+}
diff --git a/cpukit/posix/src/testcancel.c b/cpukit/posix/src/testcancel.c
new file mode 100644
index 0000000000..8d80794e2d
--- /dev/null
+++ b/cpukit/posix/src/testcancel.c
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/cancel.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/threadsup.h>
+
+/*PAGE
+ *
+ * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
+ */
+
+void pthread_testcancel( void )
+{
+ POSIX_API_Control *thread_support;
+
+ /*
+ * Don't even think about deleting a resource from an ISR.
+ * Besides this request is supposed to be for _Thread_Executing
+ * and the ISR context is not a thread.
+ */
+
+ if ( _ISR_Is_in_progress() )
+ return;
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ _Thread_Disable_dispatch();
+ if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
+ thread_support->cancelation_requested )
+ _POSIX_Threads_cancel_run( _Thread_Executing );
+ _Thread_Enable_dispatch();
+}
diff --git a/cpukit/posix/src/time.c b/cpukit/posix/src/time.c
new file mode 100644
index 0000000000..69592b7318
--- /dev/null
+++ b/cpukit/posix/src/time.c
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/seterr.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * 4.5.1 Get System Time, P1003.1b-1993, p. 91
+ */
+
+/* Using the implementation in newlib */
+#if 0
+time_t time(
+ time_t *tloc
+)
+{
+ time_t seconds_since_epoch;
+
+ /*
+ * No error is the time of day is not set. For RTEMS the system time
+ * starts out at the rtems epoch.
+ */
+
+ /*
+ * Internally the RTEMS epoch is 1988. This must be taken into account.
+ */
+
+ seconds_since_epoch = _TOD_Seconds_since_epoch;
+
+ seconds_since_epoch += POSIX_TIME_SECONDS_1970_THROUGH_1988;
+
+ if ( tloc )
+ *tloc = seconds_since_epoch;
+
+ return seconds_since_epoch;
+}
+#endif
diff --git a/cpukit/posix/src/types.c b/cpukit/posix/src/types.c
new file mode 100644
index 0000000000..d9befea289
--- /dev/null
+++ b/cpukit/posix/src/types.c
@@ -0,0 +1,46 @@
+/*
+ * This file is the shell of what it initially was and is now misnamed.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/seterr.h>
+
+/*
+ * TEMPORARY
+ */
+
+#include <assert.h>
+
+int POSIX_MP_NOT_IMPLEMENTED()
+{
+ assert( 0 );
+ return 0;
+}
+
+int POSIX_BOTTOM_REACHED()
+{
+ assert( 0 );
+ return 0;
+}
+
+int POSIX_NOT_IMPLEMENTED()
+{
+ assert( 0 );
+ return 0;
+}
+
+/*
+ * END OF TEMPORARY
+ */
diff --git a/cpukit/posix/src/ualarm.c b/cpukit/posix/src/ualarm.c
new file mode 100644
index 0000000000..ab268d105c
--- /dev/null
+++ b/cpukit/posix/src/ualarm.c
@@ -0,0 +1,94 @@
+/*
+ * XXX 3.4.1 Schedule Alarm, P1003.1b-1993, p. 79
+ *
+ * COPYRIGHT (c) 1989-2003.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+/* #include <errno.h> */
+
+#include <rtems/system.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/time.h>
+
+Watchdog_Control _POSIX_signals_Ualarm_timer;
+
+/*PAGE
+ *
+ * _POSIX_signals_Ualarm_TSR
+ */
+
+void _POSIX_signals_Ualarm_TSR(
+ Objects_Id id,
+ void *argument
+)
+{
+ int status;
+
+ status = kill( getpid(), SIGALRM );
+ /* XXX can't print from an ISR, should this be fatal? */
+}
+
+useconds_t ualarm(
+ useconds_t useconds,
+ useconds_t interval
+)
+{
+ useconds_t remaining = 0;
+ Watchdog_Control *the_timer;
+ Watchdog_Interval ticks;
+ struct timespec tp;
+
+ the_timer = &_POSIX_signals_Ualarm_timer;
+
+ /*
+ * Initialize the timer used to implement alarm().
+ */
+
+ if ( !the_timer->routine ) {
+ _Watchdog_Initialize( the_timer, _POSIX_signals_Ualarm_TSR, 0, NULL );
+ } else {
+ switch ( _Watchdog_Remove( the_timer ) ) {
+ case WATCHDOG_INACTIVE:
+ case WATCHDOG_BEING_INSERTED:
+ break;
+
+ case WATCHDOG_ACTIVE:
+ case WATCHDOG_REMOVE_IT:
+ /*
+ * The stop_time and start_time fields are snapshots of ticks since
+ * boot. Since alarm() is dealing in seconds, we must account for
+ * this.
+ */
+
+
+ ticks = the_timer->initial -
+ ((the_timer->stop_time - the_timer->start_time) /
+ _TOD_Ticks_per_second);
+
+ _POSIX_Interval_to_timespec( ticks, &tp );
+ remaining = tp.tv_sec * TOD_MICROSECONDS_PER_SECOND;
+ remaining += tp.tv_nsec / 1000;
+ break;
+ }
+ }
+
+ tp.tv_sec = useconds / TOD_MICROSECONDS_PER_SECOND;
+ tp.tv_nsec = (useconds % TOD_MICROSECONDS_PER_SECOND) * 1000;
+ ticks = _POSIX_Timespec_to_interval( &tp );
+ _Watchdog_Insert_ticks( the_timer, ticks );
+
+ return remaining;
+}
diff --git a/cpukit/posix/src/usleep.c b/cpukit/posix/src/usleep.c
new file mode 100644
index 0000000000..6753cfe713
--- /dev/null
+++ b/cpukit/posix/src/usleep.c
@@ -0,0 +1,34 @@
+/*
+ * XXX 3.4.3 Delay Process Execution, P1003.1b-1993, p. 81
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <time.h>
+#include <unistd.h>
+
+#include <rtems/system.h>
+#include <rtems/score/tod.h>
+
+
+unsigned usleep(
+ unsigned int useconds
+)
+{
+ struct timespec tp;
+ struct timespec tm;
+ unsigned remaining;
+
+ tp.tv_sec = useconds / TOD_MICROSECONDS_PER_SECOND;
+ tp.tv_nsec = (useconds % TOD_MICROSECONDS_PER_SECOND) * 1000;
+
+ nanosleep( &tp, &tm );
+
+ remaining = tm.tv_sec * TOD_MICROSECONDS_PER_SECOND;
+ remaining += tm.tv_nsec / 1000;
+ return remaining; /* seconds remaining */
+}
diff --git a/cpukit/posix/src/wait.c b/cpukit/posix/src/wait.c
new file mode 100644
index 0000000000..5bfa8ce943
--- /dev/null
+++ b/cpukit/posix/src/wait.c
@@ -0,0 +1,21 @@
+/*
+ * waitpid() - POSIX 1003.1b 3.2.1
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+int wait(
+ int *stat_loc
+)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/posix/src/waitpid.c b/cpukit/posix/src/waitpid.c
new file mode 100644
index 0000000000..5201f56a05
--- /dev/null
+++ b/cpukit/posix/src/waitpid.c
@@ -0,0 +1,23 @@
+/*
+ * waitpid() - POSIX 1003.1 3.2.1
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+int waitpid(
+ pid_t pid,
+ int *stat_loc,
+ int options
+)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/pppd/.cvsignore b/cpukit/pppd/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/pppd/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/pppd/Makefile.am b/cpukit/pppd/Makefile.am
new file mode 100644
index 0000000000..bca0c59e3f
--- /dev/null
+++ b/cpukit/pppd/Makefile.am
@@ -0,0 +1,21 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+if HAS_NETWORKING
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtemspppd.h rtemsdialer.h
+
+project_lib_LIBRARIES = libpppd.a
+libpppd_a_SOURCES = 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 lcp.c lcp.h magic.c magic.h \
+ options.c upap.c upap.h md4.c md4.h md5.c md5.h utils.c sys-rtems.c \
+ rtemsmain.c rtemspppd.c rtemspppd.h pppd.h patchlevel.h pathnames.h \
+ rtemsdialer.h
+libpppd_a_CPPFLAGS = $(AM_CPPFLAGS) -D__BSD_VISIBLE
+endif
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/pppd/README b/cpukit/pppd/README
new file mode 100644
index 0000000000..28c9f7ef5d
--- /dev/null
+++ b/cpukit/pppd/README
@@ -0,0 +1,29 @@
+#
+# $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>.
+=================================================================
+
diff --git a/cpukit/pppd/STATUS b/cpukit/pppd/STATUS
new file mode 100644
index 0000000000..4c0d35d423
--- /dev/null
+++ b/cpukit/pppd/STATUS
@@ -0,0 +1,27 @@
+#
+# $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
diff --git a/cpukit/pppd/auth.c b/cpukit/pppd/auth.c
new file mode 100644
index 0000000000..b315a1f723
--- /dev/null
+++ b/cpukit/pppd/auth.c
@@ -0,0 +1,1121 @@
+/*
+ * auth.c - PPP authentication and phase control.
+ *
+ * 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) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ */
+
+#define RCSID "$Id$"
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#if defined(_PATH_LASTLOG) && defined(_linux_)
+#include <lastlog.h>
+#endif
+
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifdef USE_PAM
+#include <security/pam_appl.h>
+#endif
+
+#ifdef HAS_SHADOW
+#include <shadow.h>
+#ifndef PW_PPP
+#define PW_PPP PW_LOGIN
+#endif
+#endif
+
+#include "pppd.h"
+#include "fsm.h"
+#include "lcp.h"
+#include "ipcp.h"
+#include "upap.h"
+#include "chap.h"
+#ifdef CBCP_SUPPORT
+#include "cbcp.h"
+#endif
+#include "pathnames.h"
+
+static const char rcsid[] = RCSID;
+
+/* The name by which the peer authenticated itself to us. */
+char peer_authname[MAXNAMELEN];
+
+/* Records which authentication operations haven't completed yet. */
+static int auth_pending[NUM_PPP];
+
+/* List of addresses which the peer may use. */
+static struct permitted_ip *addresses[NUM_PPP];
+
+/* Wordlist giving addresses which the peer may use
+ without authenticating itself. */
+static struct wordlist *noauth_addrs;
+
+/* Extra options to apply, from the secrets file entry for the peer. */
+static struct wordlist *extra_options;
+
+/* Number of network protocols which we have opened. */
+static int num_np_open;
+
+/* Number of network protocols which have come up. */
+static int num_np_up;
+
+/* Set if we got the contents of passwd[] from the pap-secrets file. */
+static int passwd_from_file;
+
+/* Set if we require authentication only because we have a default route. */
+static bool default_auth;
+
+/* Hook for a link status */
+void (*auth_linkup_hook)__P((void)) = NULL;
+void (*auth_linkdown_hook)__P((void)) = NULL;
+
+/* Hook to enable a plugin to control the idle time limit */
+int (*idle_time_hook) __P((struct ppp_idle *)) = NULL;
+
+/* Hook for a plugin to say whether we can possibly authenticate any peer */
+int (*pap_check_hook) __P((void)) = NULL;
+
+/* Hook for a plugin to check the PAP user and password */
+int (*pap_auth_hook) __P((char *user, char *passwd/*, char **msgp,
+ struct wordlist **paddrs,
+ struct wordlist **popts*/)) = NULL;
+
+/* Hook for a plugin to know about the PAP user logout */
+void (*pap_logout_hook) __P((void)) = NULL;
+
+/* Hook for a plugin to get the PAP password for authenticating us */
+int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL;
+
+/*
+ * This is used to ensure that we don't start an auth-up/down
+ * script while one is already running.
+ */
+enum script_state {
+ s_down,
+ s_up
+};
+
+static enum script_state auth_state = s_down;
+static enum script_state auth_script_state = s_down;
+
+/*
+ * Option variables.
+ */
+bool uselogin = 0; /* Use /etc/passwd for checking PAP */
+bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */
+bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */
+bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */
+bool usehostname = 0; /* Use hostname for our_name */
+bool auth_required = 0; /* Always require authentication from peer */
+bool allow_any_ip = 0; /* Allow peer to use any IP address */
+bool explicit_remote = 0; /* User specified explicit remote name */
+char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
+
+/* Bits in auth_pending[] */
+#define PAP_WITHPEER 1
+#define PAP_PEER 2
+#define CHAP_WITHPEER 4
+#define CHAP_PEER 8
+
+extern char *crypt __P((const char *, const char *));
+
+/* Prototypes for procedures local to this file. */
+
+static void network_phase __P((int));
+static void check_idle __P((void *));
+static void connect_time_expired __P((void *));
+static int null_login __P((int));
+static int get_pap_passwd __P((char *));
+static int have_pap_secret __P((int *));
+static int have_chap_secret __P((char *, char *, int, int *));
+#if 0
+static int ip_addr_check __P((u_int32_t, struct permitted_ip *));
+#endif
+static void free_wordlist __P((struct wordlist *));
+static void auth_script __P((enum script_state s));
+static void set_allowed_addrs __P((int, struct wordlist *, struct wordlist *));
+
+
+/*
+ * Authentication-related options.
+ */
+option_t auth_options[] = {
+ { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap,
+ "Require PAP authentication from peer", 1, &auth_required },
+ { "+pap", o_bool, &lcp_wantoptions[0].neg_upap,
+ "Require PAP authentication from peer", 1, &auth_required },
+ { "refuse-pap", o_bool, &refuse_pap,
+ "Don't agree to auth to peer with PAP", 1 },
+ { "-pap", o_bool, &refuse_pap,
+ "Don't allow PAP authentication with peer", 1 },
+ { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap,
+ "Require CHAP authentication from peer", 1, &auth_required },
+ { "+chap", o_bool, &lcp_wantoptions[0].neg_chap,
+ "Require CHAP authentication from peer", 1, &auth_required },
+ { "refuse-chap", o_bool, &refuse_chap,
+ "Don't agree to auth to peer with CHAP", 1 },
+ { "-chap", o_bool, &refuse_chap,
+ "Don't allow CHAP authentication with peer", 1 },
+ { "name", o_string, our_name,
+ "Set local name for authentication",
+ OPT_PRIV|OPT_STATIC, NULL, MAXNAMELEN },
+ { "user", o_string, user,
+ "Set name for auth with peer", OPT_STATIC, NULL, MAXNAMELEN },
+ { "usehostname", o_bool, &usehostname,
+ "Must use hostname for authentication", 1 },
+ { "remotename", o_string, remote_name,
+ "Set remote name for authentication", OPT_STATIC,
+ &explicit_remote, MAXNAMELEN },
+ { "auth", o_bool, &auth_required,
+ "Require authentication from peer", 1 },
+ { "noauth", o_bool, &auth_required,
+ "Don't require peer to authenticate", OPT_PRIV, &allow_any_ip },
+ { "login", o_bool, &uselogin,
+ "Use system password database for PAP", 1 },
+ { "papcrypt", o_bool, &cryptpap,
+ "PAP passwords are encrypted", 1 },
+/* Removed for RTEMS PORT
+ { "+ua", o_special, setupapfile,
+ "Get PAP user and password from file" },
+*/
+ { "password", o_string, passwd,
+ "Password for authenticating us to the peer", OPT_STATIC,
+ NULL, MAXSECRETLEN },
+/* Removed for RTEMS_PORT
+ { "privgroup", o_special, privgroup,
+ "Allow group members to use privileged options", OPT_PRIV },
+ { "allow-ip", o_special, set_noauth_addr,
+ "Set IP address(es) which can be used without authentication",
+ OPT_PRIV },
+*/
+ { NULL }
+};
+
+/*
+ * An Open on LCP has requested a change from Dead to Establish phase.
+ * Do what's necessary to bring the physical layer up.
+ */
+void
+link_required(unit)
+ int unit;
+{
+}
+
+/*
+ * LCP has terminated the link; go to the Dead phase and take the
+ * physical layer down.
+ */
+void
+link_terminated(unit)
+ int unit;
+{
+ if (pppd_phase == PHASE_DEAD)
+ return;
+ if (pap_logout_hook) {
+ pap_logout_hook();
+ }
+ new_phase(PHASE_DEAD);
+ notice("Connection terminated.");
+}
+
+/*
+ * LCP has gone down; it will either die or try to re-establish.
+ */
+void
+link_down(unit)
+ int unit;
+{
+ int i;
+ struct protent *protp;
+
+ auth_state = s_down;
+ if (auth_script_state == s_up) {
+ update_link_stats(unit);
+ auth_script(s_down);
+ }
+ for (i = 0; (protp = protocols[i]) != NULL; ++i) {
+ if (!protp->enabled_flag)
+ continue;
+ if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)
+ (*protp->lowerdown)(unit);
+ if (protp->protocol < 0xC000 && protp->close != NULL)
+ (*protp->close)(unit, "LCP down");
+ }
+ num_np_open = 0;
+ num_np_up = 0;
+ if (pppd_phase != PHASE_DEAD)
+ new_phase(PHASE_TERMINATE);
+}
+
+/*
+ * The link is established.
+ * Proceed to the Dead, Authenticate or Network phase as appropriate.
+ */
+void
+link_established(unit)
+ int unit;
+{
+ int auth;
+ lcp_options *wo = &lcp_wantoptions[unit];
+ lcp_options *go = &lcp_gotoptions[unit];
+ lcp_options *ho = &lcp_hisoptions[unit];
+ int i;
+ struct protent *protp;
+
+ /*
+ * Tell higher-level protocols that LCP is up.
+ */
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (protp->protocol != PPP_LCP && protp->enabled_flag
+ && protp->lowerup != NULL)
+ (*protp->lowerup)(unit);
+
+ if (auth_required && !(go->neg_chap || go->neg_upap)) {
+ /*
+ * We wanted the peer to authenticate itself, and it refused:
+ * if we have some address(es) it can use without auth, fine,
+ * otherwise treat it as though it authenticated with PAP using
+ * a username * of "" and a password of "". If that's not OK,
+ * boot it out.
+ */
+ if (noauth_addrs != NULL) {
+ set_allowed_addrs(unit, noauth_addrs, NULL);
+ } else if (!wo->neg_upap || !null_login(unit)) {
+ warn("peer refused to authenticate: terminating link");
+ lcp_close(unit, "peer refused to authenticate");
+ pppd_status = EXIT_PEER_AUTH_FAILED;
+ return;
+ }
+ }
+
+ new_phase(PHASE_AUTHENTICATE);
+ auth = 0;
+ if (go->neg_chap) {
+ ChapAuthPeer(unit, our_name, go->chap_mdtype);
+ auth |= CHAP_PEER;
+ } else if (go->neg_upap) {
+ upap_authpeer(unit);
+ auth |= PAP_PEER;
+ }
+ if (ho->neg_chap) {
+ ChapAuthWithPeer(unit, user, ho->chap_mdtype);
+ auth |= CHAP_WITHPEER;
+ } else if (ho->neg_upap) {
+ if (passwd[0] == 0) {
+ passwd_from_file = 1;
+ if (!get_pap_passwd(passwd))
+ error("No secret found for PAP login");
+ }
+ upap_authwithpeer(unit, user, passwd);
+ auth |= PAP_WITHPEER;
+ }
+ auth_pending[unit] = auth;
+
+ if (!auth)
+ network_phase(unit);
+}
+
+/*
+ * Proceed to the network phase.
+ */
+static void
+network_phase(unit)
+ int unit;
+{
+#ifdef CBCP_SUPPORT
+ lcp_options *go = &lcp_gotoptions[unit];
+#endif
+
+ /* always run the auth-up script */
+ auth_state = s_up;
+ if (auth_script_state == s_down) {
+ auth_script(s_up);
+ }
+
+#ifdef CBCP_SUPPORT
+ /*
+ * If we negotiated callback, do it now.
+ */
+ if (go->neg_cbcp) {
+ new_phase(PHASE_CALLBACK);
+ (*cbcp_protent.open)(unit);
+ return;
+ }
+#endif
+
+ /*
+ * Process extra options from the secrets file
+ */
+ if (extra_options) {
+ options_from_list(extra_options, 1);
+ free_wordlist(extra_options);
+ extra_options = 0;
+ }
+ start_networks();
+}
+
+void
+start_networks()
+{
+ int i;
+ struct protent *protp;
+
+ new_phase(PHASE_NETWORK);
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (protp->protocol < 0xC000 && protp->enabled_flag
+ && protp->open != NULL) {
+ (*protp->open)(0);
+ if (protp->protocol != PPP_CCP)
+ ++num_np_open;
+ }
+
+ if (num_np_open == 0)
+ /* nothing to do */
+ lcp_close(0, "No network protocols running");
+}
+
+/*
+ * The peer has failed to authenticate himself using `protocol'.
+ */
+void
+auth_peer_fail(unit, protocol)
+ int unit, protocol;
+{
+ /*
+ * Authentication failure: take the link down
+ */
+ lcp_close(unit, "Authentication failed");
+ pppd_status = EXIT_PEER_AUTH_FAILED;
+}
+
+/*
+ * The peer has been successfully authenticated using `protocol'.
+ */
+void
+auth_peer_success(unit, protocol, name, namelen)
+ int unit, protocol;
+ char *name;
+ int namelen;
+{
+ int bit;
+
+ switch (protocol) {
+ case PPP_CHAP:
+ bit = CHAP_PEER;
+ break;
+ case PPP_PAP:
+ bit = PAP_PEER;
+ break;
+ default:
+ warn("auth_peer_success: unknown protocol %x", protocol);
+ return;
+ }
+
+ /*
+ * Save the authenticated name of the peer for later.
+ */
+ if (namelen > sizeof(peer_authname) - 1)
+ namelen = sizeof(peer_authname) - 1;
+ BCOPY(name, peer_authname, namelen);
+ peer_authname[namelen] = 0;
+
+ /*
+ * If there is no more authentication still to be done,
+ * proceed to the network (or callback) phase.
+ */
+ if ((auth_pending[unit] &= ~bit) == 0)
+ network_phase(unit);
+}
+
+/*
+ * We have failed to authenticate ourselves to the peer using `protocol'.
+ */
+void
+auth_withpeer_fail(unit, protocol)
+ int unit, protocol;
+{
+ if (passwd_from_file)
+ BZERO(passwd, MAXSECRETLEN);
+ /*
+ * We've failed to authenticate ourselves to our peer.
+ * Some servers keep sending CHAP challenges, but there
+ * is no point in persisting without any way to get updated
+ * authentication secrets.
+ */
+ lcp_close(unit, "Failed to authenticate ourselves to peer");
+ pppd_status = EXIT_AUTH_TOPEER_FAILED;
+}
+
+/*
+ * We have successfully authenticated ourselves with the peer using `protocol'.
+ */
+void
+auth_withpeer_success(unit, protocol)
+ int unit, protocol;
+{
+ int bit;
+
+ switch (protocol) {
+ case PPP_CHAP:
+ bit = CHAP_WITHPEER;
+ break;
+ case PPP_PAP:
+ if (passwd_from_file)
+ BZERO(passwd, MAXSECRETLEN);
+ bit = PAP_WITHPEER;
+ break;
+ default:
+ warn("auth_withpeer_success: unknown protocol %x", protocol);
+ bit = 0;
+ }
+
+ /*
+ * If there is no more authentication still being done,
+ * proceed to the network (or callback) phase.
+ */
+ if ((auth_pending[unit] &= ~bit) == 0)
+ network_phase(unit);
+}
+
+
+/*
+ * np_up - a network protocol has come up.
+ */
+void
+np_up(unit, proto)
+ int unit, proto;
+{
+ int tlim;
+
+ if (num_np_up == 0) {
+ /*
+ * At this point we consider that the link has come up successfully.
+ */
+ pppd_status = EXIT_OK;
+ unsuccess = 0;
+ new_phase(PHASE_RUNNING);
+
+ if (idle_time_hook != 0)
+ tlim = (*idle_time_hook)(NULL);
+ else
+ tlim = idle_time_limit;
+ if (tlim > 0)
+ TIMEOUT(check_idle, NULL, tlim);
+
+ /*
+ * Set a timeout to close the connection once the maximum
+ * connect time has expired.
+ */
+ if (maxconnect > 0)
+ TIMEOUT(connect_time_expired, 0, maxconnect);
+ }
+ ++num_np_up;
+}
+
+/*
+ * np_down - a network protocol has gone down.
+ */
+void
+np_down(unit, proto)
+ int unit, proto;
+{
+ if (--num_np_up == 0) {
+ UNTIMEOUT(check_idle, NULL);
+ new_phase(PHASE_NETWORK);
+ }
+}
+
+/*
+ * np_finished - a network protocol has finished using the link.
+ */
+void
+np_finished(unit, proto)
+ int unit, proto;
+{
+ if (--num_np_open <= 0) {
+ /* no further use for the link: shut up shop. */
+ lcp_close(0, "No network protocols running");
+ }
+}
+
+/*
+ * check_idle - check whether the link has been idle for long
+ * enough that we can shut it down.
+ */
+static void
+check_idle(arg)
+ void *arg;
+{
+ struct ppp_idle idle;
+ time_t itime;
+ int tlim;
+
+ if (!get_idle_time(0, &idle))
+ return;
+ if (idle_time_hook != 0) {
+ tlim = idle_time_hook(&idle);
+ } else {
+ itime = MIN(idle.xmit_idle, idle.recv_idle);
+ tlim = idle_time_limit - itime;
+ }
+ if (tlim <= 0) {
+ /* link is idle: shut it down. */
+ notice("Terminating connection due to lack of activity.");
+ lcp_close(0, "Link inactive");
+ need_holdoff = 0;
+ pppd_status = EXIT_IDLE_TIMEOUT;
+ } else {
+ TIMEOUT(check_idle, NULL, tlim);
+ }
+}
+
+/*
+ * connect_time_expired - log a message and close the connection.
+ */
+static void
+connect_time_expired(arg)
+ void *arg;
+{
+ info("Connect time expired");
+ lcp_close(0, "Connect time expired"); /* Close connection */
+ pppd_status = EXIT_CONNECT_TIME;
+}
+
+/*
+ * auth_check_options - called to check authentication options.
+ */
+int
+auth_check_options()
+{
+ lcp_options *wo = &lcp_wantoptions[0];
+ int status = 1;
+ int can_auth;
+ int lacks_ip;
+
+ /* Default our_name to hostname, and user to our_name */
+ if (our_name[0] == 0 || usehostname)
+ strlcpy(our_name, hostname, sizeof(our_name));
+ if (user[0] == 0)
+ strlcpy(user, our_name, sizeof(user));
+
+ /*
+ * If we have a default route, require the peer to authenticate
+ * unless the noauth option was given or the real user is root.
+ */
+ if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) {
+ printf("auth_check_options: turning on\n");
+ auth_required = 1;
+ default_auth = 1;
+ }
+
+ /* If authentication is required, ask peer for CHAP or PAP. */
+ if (auth_required) {
+ if (!wo->neg_chap && !wo->neg_upap) {
+ wo->neg_chap = 1;
+ wo->neg_upap = 1;
+ }
+ } else {
+ wo->neg_chap = 0;
+ wo->neg_upap = 0;
+ }
+
+ /*
+ * Check whether we have appropriate secrets to use
+ * to authenticate the peer.
+ */
+ lacks_ip = 0;
+ can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip));
+ if (!can_auth && wo->neg_chap) {
+ can_auth = have_chap_secret((explicit_remote? remote_name: NULL),
+ our_name, 1, &lacks_ip);
+ }
+
+ if (auth_required && !can_auth && noauth_addrs == NULL) {
+ if (default_auth) {
+ option_error(
+"By default the remote system is required to authenticate itself");
+ option_error(
+"(because this system has a default route to the internet)");
+ } else if (explicit_remote)
+ option_error(
+"The remote system (%s) is required to authenticate itself",
+ remote_name);
+ else
+ option_error(
+"The remote system is required to authenticate itself");
+ option_error(
+"but I couldn't find any suitable secret (password) for it to use to do so.");
+ if (lacks_ip)
+ option_error(
+"(None of the available passwords would let it use an IP address.)");
+
+ status = 0;
+ }
+ return ( status );
+}
+
+/*
+ * auth_reset - called when LCP is starting negotiations to recheck
+ * authentication options, i.e. whether we have appropriate secrets
+ * to use for authenticating ourselves and/or the peer.
+ */
+void
+auth_reset(unit)
+ int unit;
+{
+ lcp_options *go = &lcp_gotoptions[unit];
+ lcp_options *ao = &lcp_allowoptions[0];
+
+ ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));
+ ao->neg_chap = !refuse_chap
+ && (passwd[0] != 0
+ || have_chap_secret(user, (explicit_remote? remote_name: NULL),
+ 0, NULL));
+
+ if (go->neg_upap && !uselogin && !have_pap_secret(NULL))
+ go->neg_upap = 0;
+ if (go->neg_chap) {
+ if (!have_chap_secret((explicit_remote? remote_name: NULL),
+ our_name, 1, NULL))
+ go->neg_chap = 0;
+ }
+}
+
+
+/*
+ * check_passwd - Check the user name and passwd against the PAP secrets
+ * file. If requested, also check against the system password database,
+ * and login the user if OK.
+ *
+ * returns:
+ * UPAP_AUTHNAK: Authentication failed.
+ * UPAP_AUTHACK: Authentication succeeded.
+ * In either case, msg points to an appropriate message.
+ */
+int
+check_passwd(unit, auser, userlen, apasswd, passwdlen, msg)
+ int unit;
+ char *auser;
+ int userlen;
+ char *apasswd;
+ int passwdlen;
+ char **msg;
+{
+ char passwd[64], user[64];
+
+ if (pap_auth_hook)
+ {
+ slprintf(passwd, sizeof(passwd), "%.*v", passwdlen, apasswd);
+ slprintf(user, sizeof(user), "%.*v", userlen, auser);
+
+ return (*pap_auth_hook)(user, passwd/*, NULL, NULL, NULL*/) ?
+ UPAP_AUTHACK : UPAP_AUTHNAK;
+ }
+
+ return UPAP_AUTHACK;
+
+#if 0
+ int ret = (int)UPAP_AUTHNAK;
+
+ if (( userlen == 0 ) && ( passwdlen == 0 )) {
+ ret = (int)UPAP_AUTHACK;
+ }
+ printf("check_passwd: %d\n", ret);
+
+ return ret;
+#endif
+}
+
+/*
+ * null_login - Check if a username of "" and a password of "" are
+ * acceptable, and iff so, set the list of acceptable IP addresses
+ * and return 1.
+ */
+static int
+null_login(unit)
+ int unit;
+{
+ return 0;
+}
+
+
+/*
+ * get_pap_passwd - get a password for authenticating ourselves with
+ * our peer using PAP. Returns 1 on success, 0 if no suitable password
+ * could be found.
+ * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null).
+ */
+static int
+get_pap_passwd(passwd)
+ char *passwd;
+{
+ int ret = (int)0;
+
+ /*
+ * Check whether a plugin wants to supply this.
+ */
+ if (pap_passwd_hook) {
+ ret = (*pap_passwd_hook)(user, passwd);
+ }
+
+ return ( ret );
+}
+
+
+/*
+ * have_pap_secret - check whether we have a PAP file with any
+ * secrets that we could possibly use for authenticating the peer.
+ */
+static int
+have_pap_secret(lacks_ipp)
+ int *lacks_ipp;
+{
+ return 1;
+
+#if 0
+ int ret = (int)0;
+
+ /* let the plugin decide, if there is one */
+ printf("have_pap_secret:\n");
+ if (pap_check_hook) {
+ ret = (*pap_check_hook)();
+ }
+
+ return ( ret );
+#endif
+}
+
+
+/*
+ * have_chap_secret - check whether we have a CHAP file with a
+ * secret that we could possibly use for authenticating `client'
+ * on `server'. Either can be the null string, meaning we don't
+ * know the identity yet.
+ */
+static int
+have_chap_secret(client, server, need_ip, lacks_ipp)
+ char *client;
+ char *server;
+ int need_ip;
+ int *lacks_ipp;
+{
+ return 0;
+}
+
+
+/*
+ * get_secret - open the CHAP secret file and return the secret
+ * for authenticating the given client on the given server.
+ * (We could be either client or server).
+ */
+int
+get_secret(unit, client, server, secret, secret_len, am_server)
+ int unit;
+ char *client;
+ char *server;
+ unsigned char *secret;
+ int *secret_len;
+ int am_server;
+{
+ int len;
+ char secbuf[MAXWORDLEN];
+
+ if (!am_server && passwd[0] != 0) {
+ strlcpy(secbuf, passwd, sizeof(secbuf));
+ } else {
+ return 0;
+ }
+
+ len = strlen(secbuf);
+ if (len > MAXSECRETLEN) {
+ error("Secret for %s on %s is too long", client, server);
+ len = MAXSECRETLEN;
+ }
+ BCOPY(secbuf, secret, len);
+ BZERO(secbuf, sizeof(secbuf));
+ *secret_len = len;
+
+ return 1;
+}
+
+/*
+ * set_allowed_addrs() - set the list of allowed addresses.
+ * Also looks for `--' indicating options to apply for this peer
+ * and leaves the following words in extra_options.
+ */
+static void
+set_allowed_addrs(unit, addrs, opts)
+ int unit;
+ struct wordlist *addrs;
+ struct wordlist *opts;
+{
+ int n;
+ struct wordlist *ap, **pap;
+ struct permitted_ip *ip;
+ char *ptr_word, *ptr_mask;
+ struct hostent *hp;
+ struct netent *np;
+ u_int32_t a, mask, ah, offset;
+ struct ipcp_options *wo = &ipcp_wantoptions[unit];
+ u_int32_t suggested_ip = 0;
+
+ if (addresses[unit] != NULL)
+ free(addresses[unit]);
+ addresses[unit] = NULL;
+ if (extra_options != NULL)
+ free_wordlist(extra_options);
+ extra_options = opts;
+
+ /*
+ * Count the number of IP addresses given.
+ */
+ for (n = 0, pap = &addrs; (ap = *pap) != NULL; pap = &ap->next)
+ ++n;
+ if (n == 0)
+ return;
+ ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip));
+ if (ip == 0)
+ return;
+
+ n = 0;
+ for (ap = addrs; ap != NULL; ap = ap->next) {
+ /* "-" means no addresses authorized, "*" means any address allowed */
+ ptr_word = ap->word;
+ if (strcmp(ptr_word, "-") == 0)
+ break;
+ if (strcmp(ptr_word, "*") == 0) {
+ ip[n].permit = 1;
+ ip[n].base = ip[n].mask = 0;
+ ++n;
+ break;
+ }
+
+ ip[n].permit = 1;
+ if (*ptr_word == '!') {
+ ip[n].permit = 0;
+ ++ptr_word;
+ }
+
+ mask = ~ (u_int32_t) 0;
+ offset = 0;
+ ptr_mask = strchr (ptr_word, '/');
+ if (ptr_mask != NULL) {
+ int bit_count;
+ char *endp;
+
+ bit_count = (int) strtol (ptr_mask+1, &endp, 10);
+ if (bit_count <= 0 || bit_count > 32) {
+ warn("invalid address length %v in auth. address list",
+ ptr_mask+1);
+ continue;
+ }
+ bit_count = 32 - bit_count; /* # bits in host part */
+ if (*endp == '+') {
+ offset = pppifunit + 1;
+ ++endp;
+ }
+ if (*endp != 0) {
+ warn("invalid address length syntax: %v", ptr_mask+1);
+ continue;
+ }
+ *ptr_mask = '\0';
+ mask <<= bit_count;
+ }
+
+ hp = gethostbyname(ptr_word);
+ if (hp != NULL && hp->h_addrtype == AF_INET) {
+ a = *(u_int32_t *)hp->h_addr;
+ } else {
+ np = getnetbyname (ptr_word);
+ if (np != NULL && np->n_addrtype == AF_INET) {
+ a = htonl (*(u_int32_t *)np->n_net);
+ if (ptr_mask == NULL) {
+ /* calculate appropriate mask for net */
+ ah = ntohl(a);
+ if (IN_CLASSA(ah))
+ mask = IN_CLASSA_NET;
+ else if (IN_CLASSB(ah))
+ mask = IN_CLASSB_NET;
+ else if (IN_CLASSC(ah))
+ mask = IN_CLASSC_NET;
+ }
+ } else {
+ a = inet_addr (ptr_word);
+ }
+ }
+
+ if (ptr_mask != NULL)
+ *ptr_mask = '/';
+
+ if (a == (u_int32_t)-1L) {
+ warn("unknown host %s in auth. address list", ap->word);
+ continue;
+ }
+ if (offset != 0) {
+ if (offset >= ~mask) {
+ warn("interface unit %d too large for subnet %v",
+ pppifunit, ptr_word);
+ continue;
+ }
+ a = htonl((ntohl(a) & mask) + offset);
+ mask = ~(u_int32_t)0;
+ }
+ ip[n].mask = htonl(mask);
+ ip[n].base = a & ip[n].mask;
+ ++n;
+ if (~mask == 0 && suggested_ip == 0)
+ suggested_ip = a;
+ }
+
+ ip[n].permit = 0; /* make the last entry forbid all addresses */
+ ip[n].base = 0; /* to terminate the list */
+ ip[n].mask = 0;
+
+ addresses[unit] = ip;
+
+ /*
+ * If the address given for the peer isn't authorized, or if
+ * the user hasn't given one, AND there is an authorized address
+ * which is a single host, then use that if we find one.
+ */
+ if (suggested_ip != 0
+ && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr)))
+ wo->hisaddr = suggested_ip;
+}
+
+/*
+ * auth_ip_addr - check whether the peer is authorized to use
+ * a given IP address. Returns 1 if authorized, 0 otherwise.
+ */
+int
+auth_ip_addr(unit, addr)
+ int unit;
+ u_int32_t addr;
+{
+#if 0
+ int ok;
+#endif
+
+ /* don't allow loopback or multicast address */
+ if (bad_ip_adrs(addr))
+ return 0;
+
+ return 1;
+
+#if 0
+ if (addresses[unit] != NULL) {
+ ok = ip_addr_check(addr, addresses[unit]);
+ if (ok >= 0)
+ return ok;
+ }
+ if (auth_required)
+ return 0; /* no addresses authorized */
+ return allow_any_ip || !have_route_to(addr);
+#endif
+}
+
+#if 0
+static int
+ip_addr_check(addr, addrs)
+ u_int32_t addr;
+ struct permitted_ip *addrs;
+{
+ for (; ; ++addrs)
+ if ((addr & addrs->mask) == addrs->base)
+ return addrs->permit;
+}
+#endif
+
+/*
+ * bad_ip_adrs - return 1 if the IP address is one we don't want
+ * to use, such as an address in the loopback net or a multicast address.
+ * addr is in network byte order.
+ */
+int
+bad_ip_adrs(addr)
+ u_int32_t addr;
+{
+ addr = ntohl(addr);
+ return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
+ || IN_MULTICAST(addr) || IN_BADCLASS(addr);
+}
+
+/*
+ * free_wordlist - release memory allocated for a wordlist.
+ */
+static void
+free_wordlist(wp)
+ struct wordlist *wp;
+{
+ struct wordlist *next;
+
+ while (wp != NULL) {
+ next = wp->next;
+ free(wp);
+ wp = next;
+ }
+}
+
+/*
+ * auth_script - execute a script with arguments
+ * interface-name peer-name real-user tty speed
+ */
+static void
+auth_script(s)
+ enum script_state s;
+{
+ switch (s) {
+ case s_up:
+ auth_script_state = s_up;
+ if ( auth_linkup_hook ) {
+ (*auth_linkup_hook)();
+ }
+ break;
+ case s_down:
+ auth_script_state = s_down;
+ if ( auth_linkdown_hook ) {
+ (*auth_linkdown_hook)();
+ }
+ break;
+ }
+}
diff --git a/cpukit/pppd/cbcp.c b/cpukit/pppd/cbcp.c
new file mode 100644
index 0000000000..eb60a8e249
--- /dev/null
+++ b/cpukit/pppd/cbcp.c
@@ -0,0 +1,456 @@
+/*
+ * 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;
+}
diff --git a/cpukit/pppd/cbcp.h b/cpukit/pppd/cbcp.h
new file mode 100644
index 0000000000..c2ab3f6899
--- /dev/null
+++ b/cpukit/pppd/cbcp.h
@@ -0,0 +1,26 @@
+#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
diff --git a/cpukit/pppd/ccp.c b/cpukit/pppd/ccp.c
new file mode 100644
index 0000000000..615950b901
--- /dev/null
+++ b/cpukit/pppd/ccp.c
@@ -0,0 +1,1226 @@
+/*
+ * ccp.c - 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.
+ */
+
+#define RCSID "$Id$"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "pppd.h"
+#include "fsm.h"
+#include "ccp.h"
+#include <net/ppp-comp.h>
+
+static const char rcsid[] = RCSID;
+
+/*
+ * Command-line options.
+ */
+static int setbsdcomp __P((char **));
+static int setdeflate __P((char **));
+
+static option_t ccp_option_list[] = {
+ { "noccp", o_bool, &ccp_protent.enabled_flag,
+ "Disable CCP negotiation" },
+ { "-ccp", o_bool, &ccp_protent.enabled_flag,
+ "Disable CCP negotiation" },
+ { "bsdcomp", o_special, setbsdcomp,
+ "Request BSD-Compress packet compression" },
+ { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,
+ "don't allow BSD-Compress", OPT_A2COPY,
+ &ccp_allowoptions[0].bsd_compress },
+ { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,
+ "don't allow BSD-Compress", OPT_A2COPY,
+ &ccp_allowoptions[0].bsd_compress },
+ { "deflate", 1, setdeflate,
+ "request Deflate compression" },
+ { "nodeflate", o_bool, &ccp_wantoptions[0].deflate,
+ "don't allow Deflate compression", OPT_A2COPY,
+ &ccp_allowoptions[0].deflate },
+ { "-deflate", o_bool, &ccp_wantoptions[0].deflate,
+ "don't allow Deflate compression", OPT_A2COPY,
+ &ccp_allowoptions[0].deflate },
+ { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft,
+ "don't use draft deflate #", OPT_A2COPY,
+ &ccp_allowoptions[0].deflate_draft },
+ { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
+ "request Predictor-1", 1, &ccp_allowoptions[0].predictor_1 },
+ { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1,
+ "don't allow Predictor-1", OPT_A2COPY,
+ &ccp_allowoptions[0].predictor_1 },
+ { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
+ "don't allow Predictor-1", OPT_A2COPY,
+ &ccp_allowoptions[0].predictor_1 },
+
+ { NULL }
+};
+
+/*
+ * Protocol entry points from main code.
+ */
+static void ccp_init __P((int unit));
+static void ccp_open __P((int unit));
+static void ccp_close __P((int unit, char *));
+static void ccp_lowerup __P((int unit));
+static void ccp_lowerdown __P((int));
+static void ccp_input __P((int unit, u_char *pkt, int len));
+static void ccp_protrej __P((int unit));
+static int ccp_printpkt __P((u_char *pkt, int len,
+ void (*printer) __P((void *, char *, ...)),
+ void *arg));
+static void ccp_datainput __P((int unit, u_char *pkt, int len));
+
+struct protent ccp_protent = {
+ PPP_CCP,
+ ccp_init,
+ ccp_input,
+ ccp_protrej,
+ ccp_lowerup,
+ ccp_lowerdown,
+ ccp_open,
+ ccp_close,
+ ccp_printpkt,
+ ccp_datainput,
+ 1,
+ "CCP",
+ "Compressed",
+ ccp_option_list,
+ NULL,
+ NULL,
+ NULL
+};
+
+fsm ccp_fsm[NUM_PPP];
+ccp_options ccp_wantoptions[NUM_PPP]; /* what to request the peer to use */
+ccp_options ccp_gotoptions[NUM_PPP]; /* what the peer agreed to do */
+ccp_options ccp_allowoptions[NUM_PPP]; /* what we'll agree to do */
+ccp_options ccp_hisoptions[NUM_PPP]; /* what we agreed to do */
+
+/*
+ * Callbacks for fsm code.
+ */
+static void ccp_resetci __P((fsm *));
+static int ccp_cilen __P((fsm *));
+static void ccp_addci __P((fsm *, u_char *, int *));
+static int ccp_ackci __P((fsm *, u_char *, int));
+static int ccp_nakci __P((fsm *, u_char *, int));
+static int ccp_rejci __P((fsm *, u_char *, int));
+static int ccp_reqci __P((fsm *, u_char *, int *, int));
+static void ccp_up __P((fsm *));
+static void ccp_down __P((fsm *));
+static int ccp_extcode __P((fsm *, int, int, u_char *, int));
+static void ccp_rack_timeout __P((void *));
+static char *method_name __P((ccp_options *, ccp_options *));
+
+static fsm_callbacks ccp_callbacks = {
+ ccp_resetci,
+ ccp_cilen,
+ ccp_addci,
+ ccp_ackci,
+ ccp_nakci,
+ ccp_rejci,
+ ccp_reqci,
+ ccp_up,
+ ccp_down,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ ccp_extcode,
+ "CCP"
+};
+
+/*
+ * Do we want / did we get any compression?
+ */
+#define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \
+ || (opt).predictor_1 || (opt).predictor_2)
+
+/*
+ * Local state (mainly for handling reset-reqs and reset-acks).
+ */
+static int ccp_localstate[NUM_PPP];
+#define RACK_PENDING 1 /* waiting for reset-ack */
+#define RREQ_REPEAT 2 /* send another reset-req if no reset-ack */
+
+#define RACKTIMEOUT 1 /* second */
+
+static int all_rejected[NUM_PPP]; /* we rejected all peer's options */
+
+/*
+ * Option parsing.
+ */
+static int
+setbsdcomp(argv)
+ char **argv;
+{
+ int rbits, abits;
+ char *str, *endp;
+
+ str = *argv;
+ abits = rbits = strtol(str, &endp, 0);
+ if (endp != str && *endp == ',') {
+ str = endp + 1;
+ abits = strtol(str, &endp, 0);
+ }
+ if (*endp != 0 || endp == str) {
+ option_error("invalid parameter '%s' for bsdcomp option", *argv);
+ return 0;
+ }
+ if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS))
+ || (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) {
+ option_error("bsdcomp option values must be 0 or %d .. %d",
+ BSD_MIN_BITS, BSD_MAX_BITS);
+ return 0;
+ }
+ if (rbits > 0) {
+ ccp_wantoptions[0].bsd_compress = 1;
+ ccp_wantoptions[0].bsd_bits = rbits;
+ } else
+ ccp_wantoptions[0].bsd_compress = 0;
+ if (abits > 0) {
+ ccp_allowoptions[0].bsd_compress = 1;
+ ccp_allowoptions[0].bsd_bits = abits;
+ } else
+ ccp_allowoptions[0].bsd_compress = 0;
+ return 1;
+}
+
+static int
+setdeflate(argv)
+ char **argv;
+{
+ int rbits, abits;
+ char *str, *endp;
+
+ str = *argv;
+ abits = rbits = strtol(str, &endp, 0);
+ if (endp != str && *endp == ',') {
+ str = endp + 1;
+ abits = strtol(str, &endp, 0);
+ }
+ if (*endp != 0 || endp == str) {
+ option_error("invalid parameter '%s' for deflate option", *argv);
+ return 0;
+ }
+ if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE))
+ || (abits != 0 && (abits < DEFLATE_MIN_SIZE
+ || abits > DEFLATE_MAX_SIZE))) {
+ option_error("deflate option values must be 0 or %d .. %d",
+ DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
+ return 0;
+ }
+ if (rbits > 0) {
+ ccp_wantoptions[0].deflate = 1;
+ ccp_wantoptions[0].deflate_size = rbits;
+ } else
+ ccp_wantoptions[0].deflate = 0;
+ if (abits > 0) {
+ ccp_allowoptions[0].deflate = 1;
+ ccp_allowoptions[0].deflate_size = abits;
+ } else
+ ccp_allowoptions[0].deflate = 0;
+ return 1;
+}
+
+
+/*
+ * ccp_init - initialize CCP.
+ */
+static void
+ccp_init(unit)
+ int unit;
+{
+ fsm *f = &ccp_fsm[unit];
+
+ f->unit = unit;
+ f->protocol = PPP_CCP;
+ f->callbacks = &ccp_callbacks;
+ fsm_init(f);
+
+ memset(&ccp_wantoptions[unit], 0, sizeof(ccp_options));
+ memset(&ccp_gotoptions[unit], 0, sizeof(ccp_options));
+ memset(&ccp_allowoptions[unit], 0, sizeof(ccp_options));
+ memset(&ccp_hisoptions[unit], 0, sizeof(ccp_options));
+
+ ccp_wantoptions[0].deflate = 1;
+ ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE;
+ ccp_wantoptions[0].deflate_correct = 1;
+ ccp_wantoptions[0].deflate_draft = 1;
+ ccp_allowoptions[0].deflate = 1;
+ ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE;
+ ccp_allowoptions[0].deflate_correct = 1;
+ ccp_allowoptions[0].deflate_draft = 1;
+
+ ccp_wantoptions[0].bsd_compress = 1;
+ ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS;
+ ccp_allowoptions[0].bsd_compress = 1;
+ ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;
+
+ ccp_allowoptions[0].predictor_1 = 1;
+}
+
+/*
+ * ccp_open - CCP is allowed to come up.
+ */
+static void
+ccp_open(unit)
+ int unit;
+{
+ fsm *f = &ccp_fsm[unit];
+
+ if (f->state != OPENED)
+ ccp_flags_set(unit, 1, 0);
+
+ /*
+ * Find out which compressors the kernel supports before
+ * deciding whether to open in silent mode.
+ */
+ ccp_resetci(f);
+ if (!ANY_COMPRESS(ccp_gotoptions[unit]))
+ f->flags |= OPT_SILENT;
+
+ fsm_open(f);
+}
+
+/*
+ * ccp_close - Terminate CCP.
+ */
+static void
+ccp_close(unit, reason)
+ int unit;
+ char *reason;
+{
+ ccp_flags_set(unit, 0, 0);
+ fsm_close(&ccp_fsm[unit], reason);
+}
+
+/*
+ * ccp_lowerup - we may now transmit CCP packets.
+ */
+static void
+ccp_lowerup(unit)
+ int unit;
+{
+ fsm_lowerup(&ccp_fsm[unit]);
+}
+
+/*
+ * ccp_lowerdown - we may not transmit CCP packets.
+ */
+static void
+ccp_lowerdown(unit)
+ int unit;
+{
+ fsm_lowerdown(&ccp_fsm[unit]);
+}
+
+/*
+ * ccp_input - process a received CCP packet.
+ */
+static void
+ccp_input(unit, p, len)
+ int unit;
+ u_char *p;
+ int len;
+{
+ fsm *f = &ccp_fsm[unit];
+ int oldstate;
+
+ /*
+ * Check for a terminate-request so we can print a message.
+ */
+ oldstate = f->state;
+ fsm_input(f, p, len);
+ if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED)
+ notice("Compression disabled by peer.");
+
+ /*
+ * If we get a terminate-ack and we're not asking for compression,
+ * close CCP.
+ */
+ if (oldstate == REQSENT && p[0] == TERMACK
+ && !ANY_COMPRESS(ccp_gotoptions[unit]))
+ ccp_close(unit, "No compression negotiated");
+}
+
+/*
+ * Handle a CCP-specific code.
+ */
+static int
+ccp_extcode(f, code, id, p, len)
+ fsm *f;
+ int code, id;
+ u_char *p;
+ int len;
+{
+ switch (code) {
+ case CCP_RESETREQ:
+ if (f->state != OPENED)
+ break;
+ /* send a reset-ack, which the transmitter will see and
+ reset its compression state. */
+ fsm_sdata(f, CCP_RESETACK, id, NULL, 0);
+ break;
+
+ case CCP_RESETACK:
+ if (ccp_localstate[f->unit] & RACK_PENDING && id == f->reqid) {
+ ccp_localstate[f->unit] &= ~(RACK_PENDING | RREQ_REPEAT);
+ UNTIMEOUT(ccp_rack_timeout, f);
+ }
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * ccp_protrej - peer doesn't talk CCP.
+ */
+static void
+ccp_protrej(unit)
+ int unit;
+{
+ ccp_flags_set(unit, 0, 0);
+ fsm_lowerdown(&ccp_fsm[unit]);
+}
+
+/*
+ * ccp_resetci - initialize at start of negotiation.
+ */
+static void
+ccp_resetci(f)
+ fsm *f;
+{
+ ccp_options *go = &ccp_gotoptions[f->unit];
+ u_char opt_buf[16];
+
+ *go = ccp_wantoptions[f->unit];
+ all_rejected[f->unit] = 0;
+
+ /*
+ * Check whether the kernel knows about the various
+ * compression methods we might request.
+ */
+ if (go->bsd_compress) {
+ opt_buf[0] = CI_BSD_COMPRESS;
+ opt_buf[1] = CILEN_BSD_COMPRESS;
+ opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, BSD_MIN_BITS);
+ if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0)
+ go->bsd_compress = 0;
+ }
+ if (go->deflate) {
+ if (go->deflate_correct) {
+ opt_buf[0] = CI_DEFLATE;
+ opt_buf[1] = CILEN_DEFLATE;
+ opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE);
+ opt_buf[3] = DEFLATE_CHK_SEQUENCE;
+ if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
+ go->deflate_correct = 0;
+ }
+ if (go->deflate_draft) {
+ opt_buf[0] = CI_DEFLATE_DRAFT;
+ opt_buf[1] = CILEN_DEFLATE;
+ opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE);
+ opt_buf[3] = DEFLATE_CHK_SEQUENCE;
+ if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
+ go->deflate_draft = 0;
+ }
+ if (!go->deflate_correct && !go->deflate_draft)
+ go->deflate = 0;
+ }
+ if (go->predictor_1) {
+ opt_buf[0] = CI_PREDICTOR_1;
+ opt_buf[1] = CILEN_PREDICTOR_1;
+ if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_1, 0) <= 0)
+ go->predictor_1 = 0;
+ }
+ if (go->predictor_2) {
+ opt_buf[0] = CI_PREDICTOR_2;
+ opt_buf[1] = CILEN_PREDICTOR_2;
+ if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_2, 0) <= 0)
+ go->predictor_2 = 0;
+ }
+}
+
+/*
+ * ccp_cilen - Return total length of our configuration info.
+ */
+static int
+ccp_cilen(f)
+ fsm *f;
+{
+ ccp_options *go = &ccp_gotoptions[f->unit];
+
+ return (go->bsd_compress? CILEN_BSD_COMPRESS: 0)
+ + (go->deflate? CILEN_DEFLATE: 0)
+ + (go->predictor_1? CILEN_PREDICTOR_1: 0)
+ + (go->predictor_2? CILEN_PREDICTOR_2: 0);
+}
+
+/*
+ * ccp_addci - put our requests in a packet.
+ */
+static void
+ccp_addci(f, p, lenp)
+ fsm *f;
+ u_char *p;
+ int *lenp;
+{
+ int res;
+ ccp_options *go = &ccp_gotoptions[f->unit];
+ u_char *p0 = p;
+
+ /*
+ * Add the compression types that we can receive, in decreasing
+ * preference order. Get the kernel to allocate the first one
+ * in case it gets Acked.
+ */
+ if (go->deflate) {
+ p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT;
+ p[1] = CILEN_DEFLATE;
+ p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
+ p[3] = DEFLATE_CHK_SEQUENCE;
+ for (;;) {
+ res = ccp_test(f->unit, p, CILEN_DEFLATE, 0);
+ if (res > 0) {
+ p += CILEN_DEFLATE;
+ break;
+ }
+ if (res < 0 || go->deflate_size <= DEFLATE_MIN_SIZE) {
+ go->deflate = 0;
+ break;
+ }
+ --go->deflate_size;
+ p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
+ }
+ if (p != p0 && go->deflate_correct && go->deflate_draft) {
+ p[0] = CI_DEFLATE_DRAFT;
+ p[1] = CILEN_DEFLATE;
+ p[2] = p[2 - CILEN_DEFLATE];
+ p[3] = DEFLATE_CHK_SEQUENCE;
+ p += CILEN_DEFLATE;
+ }
+ }
+ if (go->bsd_compress) {
+ p[0] = CI_BSD_COMPRESS;
+ p[1] = CILEN_BSD_COMPRESS;
+ p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
+ if (p != p0) {
+ p += CILEN_BSD_COMPRESS; /* not the first option */
+ } else {
+ for (;;) {
+ res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0);
+ if (res > 0) {
+ p += CILEN_BSD_COMPRESS;
+ break;
+ }
+ if (res < 0 || go->bsd_bits <= BSD_MIN_BITS) {
+ go->bsd_compress = 0;
+ break;
+ }
+ --go->bsd_bits;
+ p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
+ }
+ }
+ }
+ /* XXX Should Predictor 2 be preferable to Predictor 1? */
+ if (go->predictor_1) {
+ p[0] = CI_PREDICTOR_1;
+ p[1] = CILEN_PREDICTOR_1;
+ if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 0) <= 0) {
+ go->predictor_1 = 0;
+ } else {
+ p += CILEN_PREDICTOR_1;
+ }
+ }
+ if (go->predictor_2) {
+ p[0] = CI_PREDICTOR_2;
+ p[1] = CILEN_PREDICTOR_2;
+ if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 0) <= 0) {
+ go->predictor_2 = 0;
+ } else {
+ p += CILEN_PREDICTOR_2;
+ }
+ }
+
+ go->method = (p > p0)? p0[0]: -1;
+
+ *lenp = p - p0;
+}
+
+/*
+ * ccp_ackci - process a received configure-ack, and return
+ * 1 iff the packet was OK.
+ */
+static int
+ccp_ackci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ ccp_options *go = &ccp_gotoptions[f->unit];
+ u_char *p0 = p;
+
+ if (go->deflate) {
+ if (len < CILEN_DEFLATE
+ || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+ || p[1] != CILEN_DEFLATE
+ || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+ || p[3] != DEFLATE_CHK_SEQUENCE)
+ return 0;
+ p += CILEN_DEFLATE;
+ len -= CILEN_DEFLATE;
+ /* XXX Cope with first/fast ack */
+ if (len == 0)
+ return 1;
+ if (go->deflate_correct && go->deflate_draft) {
+ if (len < CILEN_DEFLATE
+ || p[0] != CI_DEFLATE_DRAFT
+ || p[1] != CILEN_DEFLATE
+ || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+ || p[3] != DEFLATE_CHK_SEQUENCE)
+ return 0;
+ p += CILEN_DEFLATE;
+ len -= CILEN_DEFLATE;
+ }
+ }
+ if (go->bsd_compress) {
+ if (len < CILEN_BSD_COMPRESS
+ || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS
+ || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
+ return 0;
+ p += CILEN_BSD_COMPRESS;
+ len -= CILEN_BSD_COMPRESS;
+ /* XXX Cope with first/fast ack */
+ if (p == p0 && len == 0)
+ return 1;
+ }
+ if (go->predictor_1) {
+ if (len < CILEN_PREDICTOR_1
+ || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1)
+ return 0;
+ p += CILEN_PREDICTOR_1;
+ len -= CILEN_PREDICTOR_1;
+ /* XXX Cope with first/fast ack */
+ if (p == p0 && len == 0)
+ return 1;
+ }
+ if (go->predictor_2) {
+ if (len < CILEN_PREDICTOR_2
+ || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2)
+ return 0;
+ p += CILEN_PREDICTOR_2;
+ len -= CILEN_PREDICTOR_2;
+ /* XXX Cope with first/fast ack */
+ if (p == p0 && len == 0)
+ return 1;
+ }
+
+ if (len != 0)
+ return 0;
+ return 1;
+}
+
+/*
+ * ccp_nakci - process received configure-nak.
+ * Returns 1 iff the nak was OK.
+ */
+static int
+ccp_nakci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ ccp_options *go = &ccp_gotoptions[f->unit];
+ ccp_options no; /* options we've seen already */
+ ccp_options try; /* options to ask for next time */
+
+ memset(&no, 0, sizeof(no));
+ try = *go;
+
+ if (go->deflate && len >= CILEN_DEFLATE
+ && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+ && p[1] == CILEN_DEFLATE) {
+ no.deflate = 1;
+ /*
+ * Peer wants us to use a different code size or something.
+ * Stop asking for Deflate if we don't understand his suggestion.
+ */
+ if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
+ || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_SIZE
+ || p[3] != DEFLATE_CHK_SEQUENCE)
+ try.deflate = 0;
+ else if (DEFLATE_SIZE(p[2]) < go->deflate_size)
+ try.deflate_size = DEFLATE_SIZE(p[2]);
+ p += CILEN_DEFLATE;
+ len -= CILEN_DEFLATE;
+ if (go->deflate_correct && go->deflate_draft
+ && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT
+ && p[1] == CILEN_DEFLATE) {
+ p += CILEN_DEFLATE;
+ len -= CILEN_DEFLATE;
+ }
+ }
+
+ if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
+ && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
+ no.bsd_compress = 1;
+ /*
+ * Peer wants us to use a different number of bits
+ * or a different version.
+ */
+ if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION)
+ try.bsd_compress = 0;
+ else if (BSD_NBITS(p[2]) < go->bsd_bits)
+ try.bsd_bits = BSD_NBITS(p[2]);
+ p += CILEN_BSD_COMPRESS;
+ len -= CILEN_BSD_COMPRESS;
+ }
+
+ /*
+ * Predictor-1 and 2 have no options, so they can't be Naked.
+ *
+ * There may be remaining options but we ignore them.
+ */
+
+ if (f->state != OPENED)
+ *go = try;
+ return 1;
+}
+
+/*
+ * ccp_rejci - reject some of our suggested compression methods.
+ */
+static int
+ccp_rejci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ ccp_options *go = &ccp_gotoptions[f->unit];
+ ccp_options try; /* options to request next time */
+
+ try = *go;
+
+ /*
+ * Cope with empty configure-rejects by ceasing to send
+ * configure-requests.
+ */
+ if (len == 0 && all_rejected[f->unit])
+ return -1;
+
+ if (go->deflate && len >= CILEN_DEFLATE
+ && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+ && p[1] == CILEN_DEFLATE) {
+ if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+ || p[3] != DEFLATE_CHK_SEQUENCE)
+ return 0; /* Rej is bad */
+ if (go->deflate_correct)
+ try.deflate_correct = 0;
+ else
+ try.deflate_draft = 0;
+ p += CILEN_DEFLATE;
+ len -= CILEN_DEFLATE;
+ if (go->deflate_correct && go->deflate_draft
+ && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT
+ && p[1] == CILEN_DEFLATE) {
+ if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+ || p[3] != DEFLATE_CHK_SEQUENCE)
+ return 0; /* Rej is bad */
+ try.deflate_draft = 0;
+ p += CILEN_DEFLATE;
+ len -= CILEN_DEFLATE;
+ }
+ if (!try.deflate_correct && !try.deflate_draft)
+ try.deflate = 0;
+ }
+ if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
+ && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
+ if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
+ return 0;
+ try.bsd_compress = 0;
+ p += CILEN_BSD_COMPRESS;
+ len -= CILEN_BSD_COMPRESS;
+ }
+ if (go->predictor_1 && len >= CILEN_PREDICTOR_1
+ && p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) {
+ try.predictor_1 = 0;
+ p += CILEN_PREDICTOR_1;
+ len -= CILEN_PREDICTOR_1;
+ }
+ if (go->predictor_2 && len >= CILEN_PREDICTOR_2
+ && p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) {
+ try.predictor_2 = 0;
+ p += CILEN_PREDICTOR_2;
+ len -= CILEN_PREDICTOR_2;
+ }
+
+ if (len != 0)
+ return 0;
+
+ if (f->state != OPENED)
+ *go = try;
+
+ return 1;
+}
+
+/*
+ * ccp_reqci - processed a received configure-request.
+ * Returns CONFACK, CONFNAK or CONFREJ and the packet modified
+ * appropriately.
+ */
+static int
+ccp_reqci(f, p, lenp, dont_nak)
+ fsm *f;
+ u_char *p;
+ int *lenp;
+ int dont_nak;
+{
+ int ret, newret, res;
+ u_char *p0, *retp;
+ int len, clen, type, nb;
+ ccp_options *ho = &ccp_hisoptions[f->unit];
+ ccp_options *ao = &ccp_allowoptions[f->unit];
+
+ ret = CONFACK;
+ retp = p0 = p;
+ len = *lenp;
+
+ memset(ho, 0, sizeof(ccp_options));
+ ho->method = (len > 0)? p[0]: -1;
+
+ while (len > 0) {
+ newret = CONFACK;
+ if (len < 2 || p[1] < 2 || p[1] > len) {
+ /* length is bad */
+ clen = len;
+ newret = CONFREJ;
+
+ } else {
+ type = p[0];
+ clen = p[1];
+
+ switch (type) {
+ case CI_DEFLATE:
+ case CI_DEFLATE_DRAFT:
+ if (!ao->deflate || clen != CILEN_DEFLATE
+ || (!ao->deflate_correct && type == CI_DEFLATE)
+ || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) {
+ newret = CONFREJ;
+ break;
+ }
+
+ ho->deflate = 1;
+ ho->deflate_size = nb = DEFLATE_SIZE(p[2]);
+ if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
+ || p[3] != DEFLATE_CHK_SEQUENCE
+ || nb > ao->deflate_size || nb < DEFLATE_MIN_SIZE) {
+ newret = CONFNAK;
+ if (!dont_nak) {
+ p[2] = DEFLATE_MAKE_OPT(ao->deflate_size);
+ p[3] = DEFLATE_CHK_SEQUENCE;
+ /* fall through to test this #bits below */
+ } else
+ break;
+ }
+
+ /*
+ * Check whether we can do Deflate with the window
+ * size they want. If the window is too big, reduce
+ * it until the kernel can cope and nak with that.
+ * We only check this for the first option.
+ */
+ if (p == p0) {
+ for (;;) {
+ res = ccp_test(f->unit, p, CILEN_DEFLATE, 1);
+ if (res > 0)
+ break; /* it's OK now */
+ if (res < 0 || nb == DEFLATE_MIN_SIZE || dont_nak) {
+ newret = CONFREJ;
+ p[2] = DEFLATE_MAKE_OPT(ho->deflate_size);
+ break;
+ }
+ newret = CONFNAK;
+ --nb;
+ p[2] = DEFLATE_MAKE_OPT(nb);
+ }
+ }
+ break;
+
+ case CI_BSD_COMPRESS:
+ if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) {
+ newret = CONFREJ;
+ break;
+ }
+
+ ho->bsd_compress = 1;
+ ho->bsd_bits = nb = BSD_NBITS(p[2]);
+ if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION
+ || nb > ao->bsd_bits || nb < BSD_MIN_BITS) {
+ newret = CONFNAK;
+ if (!dont_nak) {
+ p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits);
+ /* fall through to test this #bits below */
+ } else
+ break;
+ }
+
+ /*
+ * Check whether we can do BSD-Compress with the code
+ * size they want. If the code size is too big, reduce
+ * it until the kernel can cope and nak with that.
+ * We only check this for the first option.
+ */
+ if (p == p0) {
+ for (;;) {
+ res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 1);
+ if (res > 0)
+ break;
+ if (res < 0 || nb == BSD_MIN_BITS || dont_nak) {
+ newret = CONFREJ;
+ p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION,
+ ho->bsd_bits);
+ break;
+ }
+ newret = CONFNAK;
+ --nb;
+ p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb);
+ }
+ }
+ break;
+
+ case CI_PREDICTOR_1:
+ if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) {
+ newret = CONFREJ;
+ break;
+ }
+
+ ho->predictor_1 = 1;
+ if (p == p0
+ && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 1) <= 0) {
+ newret = CONFREJ;
+ }
+ break;
+
+ case CI_PREDICTOR_2:
+ if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) {
+ newret = CONFREJ;
+ break;
+ }
+
+ ho->predictor_2 = 1;
+ if (p == p0
+ && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) {
+ newret = CONFREJ;
+ }
+ break;
+
+ default:
+ newret = CONFREJ;
+ }
+ }
+
+ if (newret == CONFNAK && dont_nak)
+ newret = CONFREJ;
+ if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) {
+ /* we're returning this option */
+ if (newret == CONFREJ && ret == CONFNAK)
+ retp = p0;
+ ret = newret;
+ if (p != retp)
+ BCOPY(p, retp, clen);
+ retp += clen;
+ }
+
+ p += clen;
+ len -= clen;
+ }
+
+ if (ret != CONFACK) {
+ if (ret == CONFREJ && *lenp == retp - p0)
+ all_rejected[f->unit] = 1;
+ else
+ *lenp = retp - p0;
+ }
+ return ret;
+}
+
+/*
+ * Make a string name for a compression method (or 2).
+ */
+static char *
+method_name(opt, opt2)
+ ccp_options *opt, *opt2;
+{
+ static char result[64];
+
+ if (!ANY_COMPRESS(*opt))
+ return "(none)";
+ switch (opt->method) {
+ case CI_DEFLATE:
+ case CI_DEFLATE_DRAFT:
+ if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
+ slprintf(result, sizeof(result), "Deflate%s (%d/%d)",
+ (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
+ opt->deflate_size, opt2->deflate_size);
+ else
+ slprintf(result, sizeof(result), "Deflate%s (%d)",
+ (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
+ opt->deflate_size);
+ break;
+ case CI_BSD_COMPRESS:
+ if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)
+ slprintf(result, sizeof(result), "BSD-Compress (%d/%d)",
+ opt->bsd_bits, opt2->bsd_bits);
+ else
+ slprintf(result, sizeof(result), "BSD-Compress (%d)",
+ opt->bsd_bits);
+ break;
+ case CI_PREDICTOR_1:
+ return "Predictor 1";
+ case CI_PREDICTOR_2:
+ return "Predictor 2";
+ default:
+ slprintf(result, sizeof(result), "Method %d", opt->method);
+ }
+ return result;
+}
+
+/*
+ * CCP has come up - inform the kernel driver and log a message.
+ */
+static void
+ccp_up(f)
+ fsm *f;
+{
+ ccp_options *go = &ccp_gotoptions[f->unit];
+ ccp_options *ho = &ccp_hisoptions[f->unit];
+ char method1[64];
+
+ ccp_flags_set(f->unit, 1, 1);
+ if (ANY_COMPRESS(*go)) {
+ if (ANY_COMPRESS(*ho)) {
+ if (go->method == ho->method) {
+ notice("%s compression enabled", method_name(go, ho));
+ } else {
+ strlcpy(method1, method_name(go, NULL), sizeof(method1));
+ notice("%s / %s compression enabled",
+ method1, method_name(ho, NULL));
+ }
+ } else
+ notice("%s receive compression enabled", method_name(go, NULL));
+ } else if (ANY_COMPRESS(*ho))
+ notice("%s transmit compression enabled", method_name(ho, NULL));
+}
+
+/*
+ * CCP has gone down - inform the kernel driver.
+ */
+static void
+ccp_down(f)
+ fsm *f;
+{
+ if (ccp_localstate[f->unit] & RACK_PENDING)
+ UNTIMEOUT(ccp_rack_timeout, f);
+ ccp_localstate[f->unit] = 0;
+ ccp_flags_set(f->unit, 1, 0);
+}
+
+/*
+ * Print the contents of a CCP packet.
+ */
+static char *ccp_codenames[] = {
+ "ConfReq", "ConfAck", "ConfNak", "ConfRej",
+ "TermReq", "TermAck", "CodeRej",
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ "ResetReq", "ResetAck",
+};
+
+static int
+ccp_printpkt(p, plen, printer, arg)
+ u_char *p;
+ int plen;
+ void (*printer) __P((void *, char *, ...));
+ void *arg;
+{
+ u_char *p0, *optend;
+ int code, id, len;
+ int optlen;
+
+ p0 = p;
+ if (plen < HEADERLEN)
+ return 0;
+ code = p[0];
+ id = p[1];
+ len = (p[2] << 8) + p[3];
+ if (len < HEADERLEN || len > plen)
+ return 0;
+
+ if (code >= 1 && code <= sizeof(ccp_codenames) / sizeof(char *)
+ && ccp_codenames[code-1] != NULL)
+ printer(arg, " %s", ccp_codenames[code-1]);
+ else
+ printer(arg, " code=0x%x", code);
+ printer(arg, " id=0x%x", id);
+ len -= HEADERLEN;
+ p += HEADERLEN;
+
+ switch (code) {
+ case CONFREQ:
+ case CONFACK:
+ case CONFNAK:
+ case CONFREJ:
+ /* print list of possible compression methods */
+ while (len >= 2) {
+ code = p[0];
+ optlen = p[1];
+ if (optlen < 2 || optlen > len)
+ break;
+ printer(arg, " <");
+ len -= optlen;
+ optend = p + optlen;
+ switch (code) {
+ case CI_DEFLATE:
+ case CI_DEFLATE_DRAFT:
+ if (optlen >= CILEN_DEFLATE) {
+ printer(arg, "deflate%s %d",
+ (code == CI_DEFLATE_DRAFT? "(old#)": ""),
+ DEFLATE_SIZE(p[2]));
+ if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL)
+ printer(arg, " method %d", DEFLATE_METHOD(p[2]));
+ if (p[3] != DEFLATE_CHK_SEQUENCE)
+ printer(arg, " check %d", p[3]);
+ p += CILEN_DEFLATE;
+ }
+ break;
+ case CI_BSD_COMPRESS:
+ if (optlen >= CILEN_BSD_COMPRESS) {
+ printer(arg, "bsd v%d %d", BSD_VERSION(p[2]),
+ BSD_NBITS(p[2]));
+ p += CILEN_BSD_COMPRESS;
+ }
+ break;
+ case CI_PREDICTOR_1:
+ if (optlen >= CILEN_PREDICTOR_1) {
+ printer(arg, "predictor 1");
+ p += CILEN_PREDICTOR_1;
+ }
+ break;
+ case CI_PREDICTOR_2:
+ if (optlen >= CILEN_PREDICTOR_2) {
+ printer(arg, "predictor 2");
+ p += CILEN_PREDICTOR_2;
+ }
+ break;
+ }
+ while (p < optend)
+ printer(arg, " %.2x", *p++);
+ printer(arg, ">");
+ }
+ break;
+
+ case TERMACK:
+ case TERMREQ:
+ if (len > 0 && *p >= ' ' && *p < 0x7f) {
+ print_string(p, len, printer, arg);
+ p += len;
+ len = 0;
+ }
+ break;
+ }
+
+ /* dump out the rest of the packet in hex */
+ while (--len >= 0)
+ printer(arg, " %.2x", *p++);
+
+ return p - p0;
+}
+
+/*
+ * We have received a packet that the decompressor failed to
+ * decompress. Here we would expect to issue a reset-request, but
+ * Motorola has a patent on resetting the compressor as a result of
+ * detecting an error in the decompressed data after decompression.
+ * (See US patent 5,130,993; international patent publication number
+ * WO 91/10289; Australian patent 73296/91.)
+ *
+ * So we ask the kernel whether the error was detected after
+ * decompression; if it was, we take CCP down, thus disabling
+ * compression :-(, otherwise we issue the reset-request.
+ */
+static void
+ccp_datainput(unit, pkt, len)
+ int unit;
+ u_char *pkt;
+ int len;
+{
+ fsm *f;
+
+ f = &ccp_fsm[unit];
+ if (f->state == OPENED) {
+ if (ccp_fatal_error(unit)) {
+ /*
+ * Disable compression by taking CCP down.
+ */
+ error("Lost compression sync: disabling compression");
+ ccp_close(unit, "Lost compression sync");
+ } else {
+ /*
+ * Send a reset-request to reset the peer's compressor.
+ * We don't do that if we are still waiting for an
+ * acknowledgement to a previous reset-request.
+ */
+ if (!(ccp_localstate[f->unit] & RACK_PENDING)) {
+ fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
+ TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);
+ ccp_localstate[f->unit] |= RACK_PENDING;
+ } else
+ ccp_localstate[f->unit] |= RREQ_REPEAT;
+ }
+ }
+}
+
+/*
+ * Timeout waiting for reset-ack.
+ */
+static void
+ccp_rack_timeout(arg)
+ void *arg;
+{
+ fsm *f = arg;
+
+ if (f->state == OPENED && ccp_localstate[f->unit] & RREQ_REPEAT) {
+ fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0);
+ TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);
+ ccp_localstate[f->unit] &= ~RREQ_REPEAT;
+ } else
+ ccp_localstate[f->unit] &= ~RACK_PENDING;
+}
diff --git a/cpukit/pppd/ccp.h b/cpukit/pppd/ccp.h
new file mode 100644
index 0000000000..609d858c5e
--- /dev/null
+++ b/cpukit/pppd/ccp.h
@@ -0,0 +1,48 @@
+/*
+ * 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;
diff --git a/cpukit/pppd/chap.c b/cpukit/pppd/chap.c
new file mode 100644
index 0000000000..4f396c3681
--- /dev/null
+++ b/cpukit/pppd/chap.c
@@ -0,0 +1,858 @@
+/*
+ * 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 <stdlib.h> /* drand48, srand48 */
+#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 *));
+
+/*
+ * 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;
+ unsigned 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;
+ unsigned 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;
+}
diff --git a/cpukit/pppd/chap.h b/cpukit/pppd/chap.h
new file mode 100644
index 0000000000..9f0361b1ae
--- /dev/null
+++ b/cpukit/pppd/chap.h
@@ -0,0 +1,124 @@
+/*
+ * 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__ */
diff --git a/cpukit/pppd/chap_ms.c b/cpukit/pppd/chap_ms.c
new file mode 100644
index 0000000000..81a57bb5aa
--- /dev/null
+++ b/cpukit/pppd/chap_ms.c
@@ -0,0 +1,338 @@
+/*
+ * 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 */
diff --git a/cpukit/pppd/chap_ms.h b/cpukit/pppd/chap_ms.h
new file mode 100644
index 0000000000..fad2755c86
--- /dev/null
+++ b/cpukit/pppd/chap_ms.h
@@ -0,0 +1,33 @@
+/*
+ * 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__ */
diff --git a/cpukit/pppd/chat.c b/cpukit/pppd/chat.c
new file mode 100644
index 0000000000..4c1378be63
--- /dev/null
+++ b/cpukit/pppd/chat.c
@@ -0,0 +1,857 @@
+/*
+ * 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
+ *
+ */
+
+/* $Id$ */
+
+/*
+ Fixes and some Changes by Wilfried Busalski Lancier-Monitoring GmbH Germany
+ wilfried.busalski@muenster.de
+
+ Fixes: put_string() Free memory allocated by clean()
+ get_string() Free memory allocated by clean()
+ chat_main() Will Distroy's no more the chat-script
+ getnextcommand() sepatator changed to '@'
+*/
+
+#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() *********************************************/
+
+#define MAX_ABORTS 16
+#define MAX_REPORTS 16
+#define DEFAULT_CHAT_TIMEOUT 45
+#define MAX_TIMEOUTS 10
+
+static int echo = 0;
+static int quiet = 0;
+static int use_env = 0;
+static int exit_code = 0;
+static char *phone_num = (char *) 0;
+static 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 *buff)
+{
+ char *token;
+ int len;
+
+ token=strchr(string,'@');
+ if (token==NULL){
+ return NULL;
+ }
+ len=token-string;
+ if(len > 78 ){
+ len=78;
+ }
+ memcpy(buff,string,len);
+ buff[len]=0;
+ return(token+1);
+}
+
+int chatmain(int fd, int mode, char *pScript)
+{
+ char arg[80];
+ char *script;
+
+ /* initialize exit code */
+ exit_code = 0;
+ ttyfd = fd;
+
+ script=pScript;
+
+ if ( debug ) {
+ dbglog("chat_main: %s\n", script);
+ }
+
+ /* get first expect string */
+ script = getnextcommand(script,arg);
+ while (( script != NULL ) && ( exit_code == 0 )) {
+ /* process the expect string */
+ chat_expect(arg);
+ if ( exit_code == 0 ) {
+ /* get the next send string */
+ script = getnextcommand(script,arg);
+ if ( script != NULL ) {
+ /* process the send string */
+ chat_send(arg);
+
+ /* get the next expect string */
+ script = getnextcommand(script,arg);
+ }
+ }
+ }
+ 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);
+ }
+}
+
+#if 0
+/*
+ * 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);
+}
+#endif
+
+/*
+ * 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) {
+ abort_next = 0;
+ if ( n_aborts < MAX_ABORTS ) {
+ char *s1;
+ s1 = clean(s, 0);
+ if (( strlen(s1) <= strlen(s) ) && ( strlen(s1) < sizeof(fail_buffer)))
+ abort_string[n_aborts++] = s1;
+ else
+ free(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;
+
+ return(write(ttyfd, &ch, 1));
+}
+
+static int write_char (c)
+int c;
+{
+ if (put_char(c) < 1) {
+ return (0);
+ }
+ return (1);
+}
+
+static int put_string (s)
+register char *s;
+{
+ char *out,*free_ptr=0;
+
+ quiet = 0;
+ out = free_ptr = clean(s, 1);
+ while (*out) {
+ register char c = *out++;
+
+ if (c != '\\') {
+ if (!write_char (c)){
+ free(free_ptr);
+ return 0;
+ }
+ continue;
+ }
+
+ c = *out++;
+
+ 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)){
+ free(free_ptr);
+ return 0;
+ }
+ break;
+ }
+ }
+ free(free_ptr);
+
+ return (1);
+}
+
+/*
+ * 'Wait for' this string to appear on this file descriptor.
+ */
+static int get_string(in_string)
+register char *in_string;
+{
+ int c, len, minlen;
+ register char *s = temp2, *end = s + STR_LEN;
+ char *logged = temp2;
+ char *string=0;
+ 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(in_string, 0);
+ len = strlen(string);
+ minlen = (len > sizeof(fail_buffer)? len: sizeof(fail_buffer)) - 1;
+
+ if (len > STR_LEN) {
+ exit_code = 1;
+ free(string);
+ return 0;
+ }
+
+ if (len == 0) {
+ free(string);
+ return (1);
+ }
+
+ while ( (c = get_char()) >= 0) {
+ int n, abort_len;
+
+ if(c == '\n' || c == '\r'){
+ s = temp2;
+ *s=0;
+ }
+ else{
+ *s++ = c;
+ *s=0;
+ }
+
+ if (s - temp2 >= len &&
+ c == string[len - 1] &&
+ strncmp(s - len, string, len) == 0) {
+ free(string);
+ 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]);
+ free(string);
+ 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;
+ free(string);
+ return (0);
+}
diff --git a/cpukit/pppd/demand.c b/cpukit/pppd/demand.c
new file mode 100644
index 0000000000..1165355ff3
--- /dev/null
+++ b/cpukit/pppd/demand.c
@@ -0,0 +1,347 @@
+/*
+ * demand.c - Support routines for demand-dialling.
+ *
+ * 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.
+ */
+
+#define RCSID "$Id$";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#ifdef PPP_FILTER
+#include <net/if.h>
+#include <net/bpf.h>
+#include <pcap.h>
+#endif
+
+#include "pppd.h"
+#include "fsm.h"
+#include "ipcp.h"
+#include "lcp.h"
+
+static const char rcsid[] = RCSID;
+
+static unsigned char *frame;
+static int framelen;
+static int framemax;
+static int escape_flag;
+static int flush_flag;
+static int fcs;
+
+struct packet {
+ int length;
+ struct packet *next;
+ unsigned char data[1];
+};
+
+struct packet *pend_q;
+struct packet *pend_qtail;
+
+static int active_packet __P((unsigned char *, int));
+
+/*
+ * demand_conf - configure the interface for doing dial-on-demand.
+ */
+void
+demand_conf()
+{
+ int i;
+ struct protent *protp;
+
+/* framemax = lcp_allowoptions[0].mru;
+ if (framemax < PPP_MRU) */
+ framemax = PPP_MRU;
+ framemax += PPP_HDRLEN + PPP_FCSLEN;
+ frame = malloc(framemax);
+ if (frame == NULL)
+ novm("demand frame");
+ framelen = 0;
+ pend_q = NULL;
+ escape_flag = 0;
+ flush_flag = 0;
+ fcs = PPP_INITFCS;
+
+ ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
+ ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
+
+#ifdef PPP_FILTER
+ set_filters(&pass_filter, &active_filter);
+#endif
+
+ /*
+ * Call the demand_conf procedure for each protocol that's got one.
+ */
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (protp->enabled_flag && protp->demand_conf != NULL)
+ if (!((*protp->demand_conf)(0)))
+ die(1);
+}
+
+
+/*
+ * demand_block - set each network protocol to block further packets.
+ */
+void
+demand_block()
+{
+ int i;
+ struct protent *protp;
+
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (protp->enabled_flag && protp->demand_conf != NULL)
+ sifnpmode(0, protp->protocol & ~0x8000, NPMODE_QUEUE);
+ get_loop_output();
+}
+
+/*
+ * demand_discard - set each network protocol to discard packets
+ * with an error.
+ */
+void
+demand_discard()
+{
+ struct packet *pkt, *nextpkt;
+ int i;
+ struct protent *protp;
+
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (protp->enabled_flag && protp->demand_conf != NULL)
+ sifnpmode(0, protp->protocol & ~0x8000, NPMODE_ERROR);
+ get_loop_output();
+
+ /* discard all saved packets */
+ for (pkt = pend_q; pkt != NULL; pkt = nextpkt) {
+ nextpkt = pkt->next;
+ free(pkt);
+ }
+ pend_q = NULL;
+ framelen = 0;
+ flush_flag = 0;
+ escape_flag = 0;
+ fcs = PPP_INITFCS;
+}
+
+/*
+ * demand_unblock - set each enabled network protocol to pass packets.
+ */
+void
+demand_unblock()
+{
+ int i;
+ struct protent *protp;
+
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (protp->enabled_flag && protp->demand_conf != NULL)
+ sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS);
+}
+
+/*
+ * FCS lookup table as calculated by genfcstab.
+ */
+static u_short fcstab[256] = {
+ 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+ 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+ 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+ 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+ 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+ 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+ 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+ 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+ 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+ 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+ 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+ 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+ 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+ 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+ 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+ 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+ 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+ 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+ 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+ 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+ 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+ 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+ 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+ 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+ 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+ 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+ 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+ 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+ 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+ 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+ 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+ 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+/*
+ * loop_chars - process characters received from the loopback.
+ * Calls loop_frame when a complete frame has been accumulated.
+ * Return value is 1 if we need to bring up the link, 0 otherwise.
+ */
+int
+loop_chars(p, n)
+ unsigned char *p;
+ int n;
+{
+ int c, rv;
+
+ rv = 0;
+ for (; n > 0; --n) {
+ c = *p++;
+ if (c == PPP_FLAG) {
+ if (!escape_flag && !flush_flag
+ && framelen > 2 && fcs == PPP_GOODFCS) {
+ framelen -= 2;
+ if (loop_frame(frame, framelen))
+ rv = 1;
+ }
+ framelen = 0;
+ flush_flag = 0;
+ escape_flag = 0;
+ fcs = PPP_INITFCS;
+ continue;
+ }
+ if (flush_flag)
+ continue;
+ if (escape_flag) {
+ c ^= PPP_TRANS;
+ escape_flag = 0;
+ } else if (c == PPP_ESCAPE) {
+ escape_flag = 1;
+ continue;
+ }
+ if (framelen >= framemax) {
+ flush_flag = 1;
+ continue;
+ }
+ frame[framelen++] = c;
+ fcs = PPP_FCS(fcs, c);
+ }
+ return rv;
+}
+
+/*
+ * loop_frame - given a frame obtained from the loopback,
+ * decide whether to bring up the link or not, and, if we want
+ * to transmit this frame later, put it on the pending queue.
+ * Return value is 1 if we need to bring up the link, 0 otherwise.
+ * We assume that the kernel driver has already applied the
+ * pass_filter, so we won't get packets it rejected.
+ * We apply the active_filter to see if we want this packet to
+ * bring up the link.
+ */
+int
+loop_frame(frame, len)
+ unsigned char *frame;
+ int len;
+{
+ struct packet *pkt;
+
+ /* dbglog("from loop: %P", frame, len); */
+ if (len < PPP_HDRLEN)
+ return 0;
+ if ((PPP_PROTOCOL(frame) & 0x8000) != 0)
+ return 0; /* shouldn't get any of these anyway */
+ if (!active_packet(frame, len))
+ return 0;
+
+ pkt = (struct packet *) malloc(sizeof(struct packet) + len);
+ if (pkt != NULL) {
+ pkt->length = len;
+ pkt->next = NULL;
+ memcpy(pkt->data, frame, len);
+ if (pend_q == NULL)
+ pend_q = pkt;
+ else
+ pend_qtail->next = pkt;
+ pend_qtail = pkt;
+ }
+ return 1;
+}
+
+/*
+ * demand_rexmit - Resend all those frames which we got via the
+ * loopback, now that the real serial link is up.
+ */
+void
+demand_rexmit(proto)
+ int proto;
+{
+ struct packet *pkt, *prev, *nextpkt;
+
+ prev = NULL;
+ pkt = pend_q;
+ pend_q = NULL;
+ for (; pkt != NULL; pkt = nextpkt) {
+ nextpkt = pkt->next;
+ if (PPP_PROTOCOL(pkt->data) == proto) {
+ output(0, pkt->data, pkt->length);
+ free(pkt);
+ } else {
+ if (prev == NULL)
+ pend_q = pkt;
+ else
+ prev->next = pkt;
+ prev = pkt;
+ }
+ }
+ pend_qtail = prev;
+ if (prev != NULL)
+ prev->next = NULL;
+}
+
+/*
+ * Scan a packet to decide whether it is an "active" packet,
+ * that is, whether it is worth bringing up the link for.
+ */
+static int
+active_packet(p, len)
+ unsigned char *p;
+ int len;
+{
+ int proto, i;
+ struct protent *protp;
+
+ if (len < PPP_HDRLEN)
+ return 0;
+ proto = PPP_PROTOCOL(p);
+#ifdef PPP_FILTER
+ if (active_filter.bf_len != 0
+ && bpf_filter(active_filter.bf_insns, frame, len, len) == 0)
+ return 0;
+#endif
+ for (i = 0; (protp = protocols[i]) != NULL; ++i) {
+ if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) {
+ if (!protp->enabled_flag)
+ return 0;
+ if (protp->active_pkt == NULL)
+ return 1;
+ return (*protp->active_pkt)(p, len);
+ }
+ }
+ return 0; /* not a supported protocol !!?? */
+}
diff --git a/cpukit/pppd/example/Makefile-user b/cpukit/pppd/example/Makefile-user
new file mode 100644
index 0000000000..69cc8aab50
--- /dev/null
+++ b/cpukit/pppd/example/Makefile-user
@@ -0,0 +1,45 @@
+#
+# Makefile
+#
+
+#
+# RTEMS_MAKEFILE_PATH is typically set in an environment variable
+#
+
+EXEC=ppptest.exe
+PGM=${ARCH}/$(EXEC)
+
+# optional managers required
+MANAGERS=io event semaphore
+
+# C source names
+CSRCS = init.c pppdapp.c
+
+COBJS_ = $(CSRCS:.c=.o)
+COBJS = $(COBJS_:%=${ARCH}/%)
+
+# C++ source names
+CXXSRCS =
+CXXOBJS_ = $(CXXSRCS:.cc=.o)
+CXXOBJS = $(CXXOBJS_:%=${ARCH}/%)
+
+# AS source names
+ASSRCS =
+ASOBJS_ = $(ASSRCS:.s=.o)
+ASOBJS = $(ASOBJS_:%=${ARCH}/%)
+
+# Libraries
+LIBS = -lrtemsall -lc
+
+include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS)
+
+all: ${ARCH} $(PGM)
+
+$(PGM): $(OBJS)
+ $(make-exe)
+
diff --git a/cpukit/pppd/example/README b/cpukit/pppd/example/README
new file mode 100644
index 0000000000..677e00af33
--- /dev/null
+++ b/cpukit/pppd/example/README
@@ -0,0 +1,15 @@
+#
+# $Id$
+#
+
+This is an example user application using pppd. It is built using
+the RTEMS application Makefiles. The file Makefile-user should
+be renamed to Makefile or the -f option given to make. The file
+is renamed to avoid bootstrap -c removing it.
+
+The files ppp.conf and pppd.options are sample configuration files
+that have successfully used to make ppp connections over a null
+modem serial cable to a UNIX box. Please review the man pages
+for either the ppp or pppd applications to ensure they are configured
+correctly.
+
diff --git a/cpukit/pppd/example/init.c b/cpukit/pppd/example/init.c
new file mode 100644
index 0000000000..f35d195bf2
--- /dev/null
+++ b/cpukit/pppd/example/init.c
@@ -0,0 +1,24 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtemspppd.h>
+
+#define CONFIGURE_INIT
+#include "system.h"
+#include "netconfig.h"
+
+
+extern int pppdapp_initialize(void);
+
+
+rtems_task Init(rtems_task_argument argument)
+{
+ /* initialize network */
+ rtems_bsdnet_initialize_network();
+ rtems_pppd_initialize();
+ pppdapp_initialize();
+
+ rtems_task_delete(RTEMS_SELF);
+}
diff --git a/cpukit/pppd/example/netconfig.h b/cpukit/pppd/example/netconfig.h
new file mode 100644
index 0000000000..3428288cd2
--- /dev/null
+++ b/cpukit/pppd/example/netconfig.h
@@ -0,0 +1,36 @@
+
+#ifndef NETCONFIG_H_
+#define NETCONFIG_H_
+
+#include <bsp.h>
+
+/* external function prototypes */
+extern int rtems_ppp_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching);
+
+/* Default network interface */
+static struct rtems_bsdnet_ifconfig netdriver_config = {
+ "ppp0", /* name */
+ rtems_ppp_driver_attach, /* attach function */
+ NULL, /* No more interfaces */
+ NULL, /* IP address */
+ NULL, /* IP net mask */
+ NULL, /* Driver supplies hardware address */
+ 0 /* Use default driver parameters */
+};
+
+/* Network configuration */
+struct rtems_bsdnet_config rtems_bsdnet_config = {
+ &netdriver_config,
+ NULL,
+ 30, /* Default network task priority */
+ (256*1024), /* Default mbuf capacity */
+ (512*1024), /* Default mbuf cluster capacity */
+ 0, /* Host name */
+ 0, /* Domain name */
+ 0, /* Gateway */
+ 0, /* Log host */
+ { 0 }, /* Name server(s) */
+ { 0 }, /* NTP server(s) */
+};
+
+#endif
diff --git a/cpukit/pppd/example/ppp.conf b/cpukit/pppd/example/ppp.conf
new file mode 100644
index 0000000000..094b1946a8
--- /dev/null
+++ b/cpukit/pppd/example/ppp.conf
@@ -0,0 +1,27 @@
+
+#
+# Example configuration file for setting up a ppp server
+# using a null-modem serial cable:
+#
+# Tested using ppp on OpenBSD 2.9
+# - just follow instructions in man page for accepting
+# ppp connections over the serial port
+# - if pap and/or chap is enabled, you must have a ppp.secret
+# file which will be used for user authentication
+# - found useful to turn on syslog for ppp
+#
+
+default:
+ set log Phase Chat LQM LCP IPCP CCP command
+ set device /dev/cua00
+ set speed 57600
+ set ctsrts on
+ set dial ""
+
+openbsd-server:
+ set timeout 0
+ set ifaddr 192.168.2.100 192.168.2.123
+ enable dns
+ allow users
+ enable chap
+ enable pap
diff --git a/cpukit/pppd/example/pppd.options b/cpukit/pppd/example/pppd.options
new file mode 100644
index 0000000000..c0706e6ec5
--- /dev/null
+++ b/cpukit/pppd/example/pppd.options
@@ -0,0 +1,9 @@
+/dev/tty00
+57600
+crtscts
+passive
+local
+noauth
+debug
+persist
+192.168.2.222:192.168.2.111
diff --git a/cpukit/pppd/example/pppdapp.c b/cpukit/pppd/example/pppdapp.c
new file mode 100644
index 0000000000..59e5029088
--- /dev/null
+++ b/cpukit/pppd/example/pppdapp.c
@@ -0,0 +1,146 @@
+
+#include <stdio.h>
+#include <rtemspppd.h>
+#include "system.h"
+
+
+/* define global variables */
+static unsigned int pppdapp_linkcount = 0;
+static rtems_id pppdapp_taskid;
+
+
+static void pppdapp_linkup_hook(void)
+{
+ pppdapp_linkcount++;
+ printf("PPP LINK UP [%d]\n", pppdapp_linkcount);
+}
+
+static void pppdapp_linkdown_hook(void)
+{
+ printf("PPP LINK DOWN [%d]\n", pppdapp_linkcount);
+}
+
+static void pppdapp_ipup_hook(void)
+{
+ /* send ipup signal to pppdapp task */
+ rtems_event_send(pppdapp_taskid, RTEMS_EVENT_10);
+}
+
+static void pppdapp_ipdown_hook(void)
+{
+ /* send ip down signal to pppdapp task */
+ rtems_event_send(pppdapp_taskid, RTEMS_EVENT_11);
+}
+
+static void pppdapp_setup(void)
+{
+ const char *pUser = "oscar";
+ const char *pPassword = "goldman";
+
+#undef USE_MODEM
+#ifdef USE_MODEM
+ const char *pTelephone = "5551234";
+ const char *pInitScript = "TIMEOUT@5@@AT@@OK@";
+ const char *pConnectScript = "TIMEOUT@90@@ATDT%s@CONNECT@@name:@%s@word:@%s@";
+ const char *pDisconnectScript = "TIMEOUT@5@@ATH0@@OK@";
+ char pConnect[128];
+
+ /* set the connect string */
+ sprintf(pConnect, pConnectScript, pTelephone, pUser, pPassword);
+
+ /* set pppd options for modem */
+ rtems_pppd_set_option("/dev/ttyS2", NULL);
+ rtems_pppd_set_option("57600", NULL);
+ rtems_pppd_set_option("crtscts", NULL);
+ rtems_pppd_set_option("modem", NULL);
+ rtems_pppd_set_option("noauth", NULL);
+ rtems_pppd_set_option("debug", NULL);
+ rtems_pppd_set_option("init", pInitScript);
+ rtems_pppd_set_option("connect", pConnect);
+ rtems_pppd_set_option("disconnect", pDisconnectScript);
+#else
+ /* set pppd options for null modem direct link serial cable */
+ rtems_pppd_set_option("/dev/ttyS1", NULL);
+ rtems_pppd_set_option("57600", NULL);
+ rtems_pppd_set_option("crtscts", NULL);
+ rtems_pppd_set_option("local", NULL);
+ rtems_pppd_set_option("noauth", NULL);
+ rtems_pppd_set_option("debug", NULL);
+ rtems_pppd_set_option("user", pUser);
+ rtems_pppd_set_option("password", pPassword);
+#endif
+
+ /* set up pppd hooks */
+ rtems_pppd_set_hook(RTEMS_PPPD_LINKUP_HOOK, pppdapp_linkup_hook);
+ rtems_pppd_set_hook(RTEMS_PPPD_LINKDOWN_HOOK, pppdapp_linkdown_hook);
+ rtems_pppd_set_hook(RTEMS_PPPD_IPUP_HOOK, pppdapp_ipup_hook);
+ rtems_pppd_set_hook(RTEMS_PPPD_IPDOWN_HOOK, pppdapp_ipdown_hook);
+}
+
+static rtems_task pppdapp(rtems_task_argument arg)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ rtems_interval tickspersecond = 0;
+ rtems_option options;
+ rtems_event_set in;
+ rtems_event_set out;
+
+ /* initialize ticks per second */
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &tickspersecond);
+ if ( tickspersecond == 0 ) {
+ /* ensure value is greater than zero */
+ tickspersecond = 100;
+ }
+
+ /* initiate connection */
+ pppdapp_setup();
+ rtems_pppd_connect();
+
+ /* enter processing loop */
+ in = (RTEMS_EVENT_10 | RTEMS_EVENT_11);
+ options = (RTEMS_EVENT_ANY | RTEMS_WAIT);
+ while ( sc == RTEMS_SUCCESSFUL ) {
+ /* wait for the next event */
+ sc = rtems_event_receive(in, options, RTEMS_NO_TIMEOUT, &out);
+ if ( sc == RTEMS_SUCCESSFUL ) {
+ /* determine which event was sent */
+ if ( out & RTEMS_EVENT_10 ) {
+ /* ip up recived */
+ /* call disconnect function */
+ rtems_pppd_disconnect();
+ }
+ if ( out & RTEMS_EVENT_11 ) {
+ /* ip down recived */
+ /* sleep 10 seconds and call connect function */
+ rtems_task_wake_after(10*tickspersecond);
+ rtems_pppd_connect();
+ }
+ }
+ }
+
+ /* terminate myself */
+ rtems_task_delete(RTEMS_SELF);
+}
+
+int pppdapp_initialize(void)
+{
+ int iReturn = (int)-1;
+ rtems_status_code status;
+ rtems_name taskName;
+
+ taskName = rtems_build_name( 'p', 'a', 'p', 'p' );
+ status = rtems_task_create(taskName,
+ CONFIGURE_INIT_TASK_PRIORITY,
+ CONFIGURE_INIT_TASK_STACK_SIZE,
+ CONFIGURE_INIT_TASK_INITIAL_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &pppdapp_taskid);
+ if ( status == RTEMS_SUCCESSFUL ) {
+ status = rtems_task_start(pppdapp_taskid, pppdapp, 0);
+ if ( status == RTEMS_SUCCESSFUL ) {
+ iReturn = (int)0;
+ }
+ }
+
+ return ( iReturn );
+}
diff --git a/cpukit/pppd/example/system.h b/cpukit/pppd/example/system.h
new file mode 100644
index 0000000000..87678da1b6
--- /dev/null
+++ b/cpukit/pppd/example/system.h
@@ -0,0 +1,42 @@
+
+#ifndef SYSTEM_H
+#define SYSTEM_H
+
+#include <rtems.h>
+#include <tty_drv.h>
+
+/* functions */
+extern rtems_task Init(rtems_task_argument argument);
+
+#include <bsp.h>
+
+#define CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE
+#ifdef CONFIGURE_INIT
+rtems_driver_address_table Device_drivers[5] = {
+ CONSOLE_DRIVER_TABLE_ENTRY,
+ CLOCK_DRIVER_TABLE_ENTRY,
+ TTY1_DRIVER_TABLE_ENTRY,
+ TTY2_DRIVER_TABLE_ENTRY,
+ {NULL, NULL, NULL, NULL, NULL, NULL}
+};
+#endif
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 8
+
+#define CONFIGURE_EXECUTIVE_RAM_SIZE (512*1024)
+#define CONFIGURE_MAXIMUM_SEMAPHORES 20
+#define CONFIGURE_MAXIMUM_TASKS 20
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 10000
+
+#define CONFIGURE_INIT_TASK_STACK_SIZE (10*1024)
+#define CONFIGURE_INIT_TASK_PRIORITY 120
+#define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \
+ RTEMS_NO_TIMESLICE | \
+ RTEMS_NO_ASR | \
+ RTEMS_INTERRUPT_LEVEL(0))
+
+#include <confdefs.h>
+
+#endif
diff --git a/cpukit/pppd/fsm.c b/cpukit/pppd/fsm.c
new file mode 100644
index 0000000000..53401a9129
--- /dev/null
+++ b/cpukit/pppd/fsm.c
@@ -0,0 +1,764 @@
+/*
+ * fsm.c - {Link, IP} Control Protocol Finite State Machine.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ */
+
+#define RCSID "$Id$"
+
+/*
+ * TODO:
+ * Randomize fsm id on link/init.
+ * Deal with variable outgoing MTU.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "pppd.h"
+#include "fsm.h"
+
+static const char rcsid[] = RCSID;
+
+static void fsm_timeout __P((void *));
+static void fsm_rconfreq __P((fsm *, u_char, u_char *, int));
+static void fsm_rconfack __P((fsm *, int, u_char *, int));
+static void fsm_rconfnakrej __P((fsm *, int, int, u_char *, int));
+static void fsm_rtermreq __P((fsm *, int, u_char *, int));
+static void fsm_rtermack __P((fsm *));
+static void fsm_rcoderej __P((fsm *, u_char *, int));
+static void fsm_sconfreq __P((fsm *, int));
+
+#define PROTO_NAME(f) ((f)->callbacks->proto_name)
+
+int peer_mru[NUM_PPP];
+
+
+/*
+ * fsm_init - Initialize fsm.
+ *
+ * Initialize fsm state.
+ */
+void
+fsm_init(f)
+ fsm *f;
+{
+ f->state = INITIAL;
+ f->flags = 0;
+ f->id = 100; /* XXX Start with random id? */
+ f->timeouttime = DEFTIMEOUT;
+ f->maxconfreqtransmits = DEFMAXCONFREQS;
+ f->maxtermtransmits = DEFMAXTERMREQS;
+ f->maxnakloops = DEFMAXNAKLOOPS;
+ f->term_reason_len = 0;
+}
+
+
+/*
+ * fsm_lowerup - The lower layer is up.
+ */
+void
+fsm_lowerup(f)
+ fsm *f;
+{
+ switch( f->state ){
+ case INITIAL:
+ f->state = CLOSED;
+ break;
+
+ case STARTING:
+ if( f->flags & OPT_SILENT )
+ f->state = STOPPED;
+ else {
+ /* Send an initial configure-request */
+ fsm_sconfreq(f, 0);
+ f->state = REQSENT;
+ }
+ break;
+
+ default:
+ FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state));
+ }
+}
+
+
+/*
+ * fsm_lowerdown - The lower layer is down.
+ *
+ * Cancel all timeouts and inform upper layers.
+ */
+void
+fsm_lowerdown(f)
+ fsm *f;
+{
+ switch( f->state ){
+ case CLOSED:
+ f->state = INITIAL;
+ break;
+
+ case STOPPED:
+ f->state = STARTING;
+ if( f->callbacks->starting )
+ (*f->callbacks->starting)(f);
+ break;
+
+ case CLOSING:
+ f->state = INITIAL;
+ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
+ break;
+
+ case STOPPING:
+ case REQSENT:
+ case ACKRCVD:
+ case ACKSENT:
+ f->state = STARTING;
+ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
+ break;
+
+ case OPENED:
+ if( f->callbacks->down )
+ (*f->callbacks->down)(f);
+ f->state = STARTING;
+ break;
+
+ default:
+ FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state));
+ }
+}
+
+
+/*
+ * fsm_open - Link is allowed to come up.
+ */
+void
+fsm_open(f)
+ fsm *f;
+{
+ switch( f->state ){
+ case INITIAL:
+ f->state = STARTING;
+ if( f->callbacks->starting )
+ (*f->callbacks->starting)(f);
+ break;
+
+ case CLOSED:
+ if( f->flags & OPT_SILENT )
+ f->state = STOPPED;
+ else {
+ /* Send an initial configure-request */
+ fsm_sconfreq(f, 0);
+ f->state = REQSENT;
+ }
+ break;
+
+ case CLOSING:
+ f->state = STOPPING;
+ /* fall through */
+ case STOPPED:
+ case OPENED:
+ if( f->flags & OPT_RESTART ){
+ fsm_lowerdown(f);
+ fsm_lowerup(f);
+ }
+ break;
+ }
+}
+
+
+/*
+ * fsm_close - Start closing connection.
+ *
+ * Cancel timeouts and either initiate close or possibly go directly to
+ * the CLOSED state.
+ */
+void
+fsm_close(f, reason)
+ fsm *f;
+ char *reason;
+{
+ f->term_reason = reason;
+ f->term_reason_len = (reason == NULL? 0: strlen(reason));
+ switch( f->state ){
+ case STARTING:
+ f->state = INITIAL;
+ break;
+ case STOPPED:
+ f->state = CLOSED;
+ break;
+ case STOPPING:
+ f->state = CLOSING;
+ break;
+
+ case REQSENT:
+ case ACKRCVD:
+ case ACKSENT:
+ case OPENED:
+ if( f->state != OPENED )
+ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
+ else if( f->callbacks->down )
+ (*f->callbacks->down)(f); /* Inform upper layers we're down */
+
+ /* Init restart counter, send Terminate-Request */
+ f->retransmits = f->maxtermtransmits;
+ fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
+ (u_char *) f->term_reason, f->term_reason_len);
+ TIMEOUT(fsm_timeout, f, f->timeouttime);
+ --f->retransmits;
+
+ f->state = CLOSING;
+ break;
+ }
+}
+
+
+/*
+ * fsm_timeout - Timeout expired.
+ */
+static void
+fsm_timeout(arg)
+ void *arg;
+{
+ fsm *f = (fsm *) arg;
+
+ switch (f->state) {
+ case CLOSING:
+ case STOPPING:
+ if( f->retransmits <= 0 ){
+ /*
+ * We've waited for an ack long enough. Peer probably heard us.
+ */
+ f->state = (f->state == CLOSING)? CLOSED: STOPPED;
+ if( f->callbacks->finished )
+ (*f->callbacks->finished)(f);
+ } else {
+ /* Send Terminate-Request */
+ fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
+ (u_char *) f->term_reason, f->term_reason_len);
+ TIMEOUT(fsm_timeout, f, f->timeouttime);
+ --f->retransmits;
+ }
+ break;
+
+ case REQSENT:
+ case ACKRCVD:
+ case ACKSENT:
+ if (f->retransmits <= 0) {
+ warn("%s: timeout sending Config-Requests\n", PROTO_NAME(f));
+ f->state = STOPPED;
+ if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )
+ (*f->callbacks->finished)(f);
+
+ } else {
+ /* Retransmit the configure-request */
+ if (f->callbacks->retransmit)
+ (*f->callbacks->retransmit)(f);
+ fsm_sconfreq(f, 1); /* Re-send Configure-Request */
+ if( f->state == ACKRCVD )
+ f->state = REQSENT;
+ }
+ break;
+
+ default:
+ FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state));
+ }
+}
+
+
+/*
+ * fsm_input - Input packet.
+ */
+void
+fsm_input(f, inpacket, l)
+ fsm *f;
+ u_char *inpacket;
+ int l;
+{
+ u_char *inp;
+ u_char code, id;
+ int len;
+
+ /*
+ * Parse header (code, id and length).
+ * If packet too short, drop it.
+ */
+ inp = inpacket;
+ if (l < HEADERLEN) {
+ FSMDEBUG(("fsm_input(%x): Rcvd short header.", f->protocol));
+ return;
+ }
+ GETCHAR(code, inp);
+ GETCHAR(id, inp);
+ GETSHORT(len, inp);
+ if (len < HEADERLEN) {
+ FSMDEBUG(("fsm_input(%x): Rcvd illegal length.", f->protocol));
+ return;
+ }
+ if (len > l) {
+ FSMDEBUG(("fsm_input(%x): Rcvd short packet.", f->protocol));
+ return;
+ }
+ len -= HEADERLEN; /* subtract header length */
+
+ if( f->state == INITIAL || f->state == STARTING ){
+ FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.",
+ f->protocol, f->state));
+ return;
+ }
+
+ /*
+ * Action depends on code.
+ */
+ switch (code) {
+ case CONFREQ:
+ fsm_rconfreq(f, id, inp, len);
+ break;
+
+ case CONFACK:
+ fsm_rconfack(f, id, inp, len);
+ break;
+
+ case CONFNAK:
+ case CONFREJ:
+ fsm_rconfnakrej(f, code, id, inp, len);
+ break;
+
+ case TERMREQ:
+ fsm_rtermreq(f, id, inp, len);
+ break;
+
+ case TERMACK:
+ fsm_rtermack(f);
+ break;
+
+ case CODEREJ:
+ fsm_rcoderej(f, inp, len);
+ break;
+
+ default:
+ if( !f->callbacks->extcode
+ || !(*f->callbacks->extcode)(f, code, id, inp, len) )
+ fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
+ break;
+ }
+}
+
+
+/*
+ * fsm_rconfreq - Receive Configure-Request.
+ */
+static void
+fsm_rconfreq(f, id, inp, len)
+ fsm *f;
+ u_char id;
+ u_char *inp;
+ int len;
+{
+ int code, reject_if_disagree;
+
+ switch( f->state ){
+ case CLOSED:
+ /* Go away, we're closed */
+ fsm_sdata(f, TERMACK, id, NULL, 0);
+ return;
+ case CLOSING:
+ case STOPPING:
+ return;
+
+ case OPENED:
+ /* Go down and restart negotiation */
+ if( f->callbacks->down )
+ (*f->callbacks->down)(f); /* Inform upper layers */
+ fsm_sconfreq(f, 0); /* Send initial Configure-Request */
+ break;
+
+ case STOPPED:
+ /* Negotiation started by our peer */
+ fsm_sconfreq(f, 0); /* Send initial Configure-Request */
+ f->state = REQSENT;
+ break;
+ }
+
+ /*
+ * Pass the requested configuration options
+ * to protocol-specific code for checking.
+ */
+ if (f->callbacks->reqci){ /* Check CI */
+ reject_if_disagree = (f->nakloops >= f->maxnakloops);
+ code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
+ } else if (len)
+ code = CONFREJ; /* Reject all CI */
+ else
+ code = CONFACK;
+
+ /* send the Ack, Nak or Rej to the peer */
+ fsm_sdata(f, code, id, inp, len);
+
+ if (code == CONFACK) {
+ if (f->state == ACKRCVD) {
+ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
+ f->state = OPENED;
+ if (f->callbacks->up)
+ (*f->callbacks->up)(f); /* Inform upper layers */
+ } else {
+ f->state = ACKSENT;
+ ppp_delay();
+ }
+ f->nakloops = 0;
+
+ } else {
+ /* we sent CONFACK or CONFREJ */
+ if (f->state != ACKRCVD)
+ f->state = REQSENT;
+ if( code == CONFNAK )
+ ++f->nakloops;
+ }
+}
+
+
+/*
+ * fsm_rconfack - Receive Configure-Ack.
+ */
+static void
+fsm_rconfack(f, id, inp, len)
+ fsm *f;
+ int id;
+ u_char *inp;
+ int len;
+{
+ if (id != f->reqid || f->seen_ack) /* Expected id? */
+ return; /* Nope, toss... */
+ if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
+ (len == 0)) ){
+ /* Ack is bad - ignore it */
+ error("Received bad configure-ack: %P", inp, len);
+ return;
+ }
+ f->seen_ack = 1;
+
+ switch (f->state) {
+ case CLOSED:
+ case STOPPED:
+ fsm_sdata(f, TERMACK, id, NULL, 0);
+ break;
+
+ case REQSENT:
+ f->state = ACKRCVD;
+ f->retransmits = f->maxconfreqtransmits;
+ break;
+
+ case ACKRCVD:
+ /* Huh? an extra valid Ack? oh well... */
+ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
+ fsm_sconfreq(f, 0);
+ f->state = REQSENT;
+ break;
+
+ case ACKSENT:
+ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
+ f->state = OPENED;
+ f->retransmits = f->maxconfreqtransmits;
+ if (f->callbacks->up)
+ (*f->callbacks->up)(f); /* Inform upper layers */
+ break;
+
+ case OPENED:
+ /* Go down and restart negotiation */
+ if (f->callbacks->down)
+ (*f->callbacks->down)(f); /* Inform upper layers */
+ fsm_sconfreq(f, 0); /* Send initial Configure-Request */
+ f->state = REQSENT;
+ break;
+ }
+}
+
+
+/*
+ * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
+ */
+static void
+fsm_rconfnakrej(f, code, id, inp, len)
+ fsm *f;
+ int code, id;
+ u_char *inp;
+ int len;
+{
+ int (*proc) __P((fsm *, u_char *, int));
+ int ret;
+
+ if (id != f->reqid || f->seen_ack) /* Expected id? */
+ return; /* Nope, toss... */
+ proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
+ if (!proc || !(ret = proc(f, inp, len))) {
+ /* Nak/reject is bad - ignore it */
+ error("Received bad configure-nak/rej: %P", inp, len);
+ return;
+ }
+ f->seen_ack = 1;
+
+ switch (f->state) {
+ case CLOSED:
+ case STOPPED:
+ fsm_sdata(f, TERMACK, id, NULL, 0);
+ break;
+
+ case REQSENT:
+ case ACKSENT:
+ /* They didn't agree to what we wanted - try another request */
+ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
+ if (ret < 0)
+ f->state = STOPPED; /* kludge for stopping CCP */
+ else
+ fsm_sconfreq(f, 0); /* Send Configure-Request */
+ break;
+
+ case ACKRCVD:
+ /* Got a Nak/reject when we had already had an Ack?? oh well... */
+ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
+ fsm_sconfreq(f, 0);
+ f->state = REQSENT;
+ break;
+
+ case OPENED:
+ /* Go down and restart negotiation */
+ if (f->callbacks->down)
+ (*f->callbacks->down)(f); /* Inform upper layers */
+ fsm_sconfreq(f, 0); /* Send initial Configure-Request */
+ f->state = REQSENT;
+ break;
+ }
+}
+
+
+/*
+ * fsm_rtermreq - Receive Terminate-Req.
+ */
+static void
+fsm_rtermreq(f, id, p, len)
+ fsm *f;
+ int id;
+ u_char *p;
+ int len;
+{
+ switch (f->state) {
+ case ACKRCVD:
+ case ACKSENT:
+ f->state = REQSENT; /* Start over but keep trying */
+ break;
+
+ case OPENED:
+ if (len > 0) {
+ info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p);
+ } else
+ info("%s terminated by peer", PROTO_NAME(f));
+ if (f->callbacks->down)
+ (*f->callbacks->down)(f); /* Inform upper layers */
+ f->retransmits = 0;
+ f->state = STOPPING;
+ TIMEOUT(fsm_timeout, f, f->timeouttime);
+ break;
+ }
+
+ fsm_sdata(f, TERMACK, id, NULL, 0);
+}
+
+
+/*
+ * fsm_rtermack - Receive Terminate-Ack.
+ */
+static void
+fsm_rtermack(f)
+ fsm *f;
+{
+ switch (f->state) {
+ case CLOSING:
+ UNTIMEOUT(fsm_timeout, f);
+ f->state = CLOSED;
+ if( f->callbacks->finished )
+ (*f->callbacks->finished)(f);
+ break;
+ case STOPPING:
+ UNTIMEOUT(fsm_timeout, f);
+ f->state = STOPPED;
+ if( f->callbacks->finished )
+ (*f->callbacks->finished)(f);
+ break;
+
+ case ACKRCVD:
+ f->state = REQSENT;
+ break;
+
+ case OPENED:
+ if (f->callbacks->down)
+ (*f->callbacks->down)(f); /* Inform upper layers */
+ fsm_sconfreq(f, 0);
+ break;
+ }
+}
+
+
+/*
+ * fsm_rcoderej - Receive an Code-Reject.
+ */
+static void
+fsm_rcoderej(f, inp, len)
+ fsm *f;
+ u_char *inp;
+ int len;
+{
+ u_char code, id;
+
+ if (len < HEADERLEN) {
+ FSMDEBUG(("fsm_rcoderej: Rcvd short Code-Reject packet!"));
+ return;
+ }
+ GETCHAR(code, inp);
+ GETCHAR(id, inp);
+ warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id);
+
+ if( f->state == ACKRCVD )
+ f->state = REQSENT;
+}
+
+
+/*
+ * fsm_protreject - Peer doesn't speak this protocol.
+ *
+ * Treat this as a catastrophic error (RXJ-).
+ */
+void
+fsm_protreject(f)
+ fsm *f;
+{
+ switch( f->state ){
+ case CLOSING:
+ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
+ /* fall through */
+ case CLOSED:
+ f->state = CLOSED;
+ if( f->callbacks->finished )
+ (*f->callbacks->finished)(f);
+ break;
+
+ case STOPPING:
+ case REQSENT:
+ case ACKRCVD:
+ case ACKSENT:
+ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
+ /* fall through */
+ case STOPPED:
+ f->state = STOPPED;
+ if( f->callbacks->finished )
+ (*f->callbacks->finished)(f);
+ break;
+
+ case OPENED:
+ if( f->callbacks->down )
+ (*f->callbacks->down)(f);
+
+ /* Init restart counter, send Terminate-Request */
+ f->retransmits = f->maxtermtransmits;
+ fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
+ (u_char *) f->term_reason, f->term_reason_len);
+ TIMEOUT(fsm_timeout, f, f->timeouttime);
+ --f->retransmits;
+
+ f->state = STOPPING;
+ break;
+
+ default:
+ FSMDEBUG(("%s: Protocol-reject event in state %d!",
+ PROTO_NAME(f), f->state));
+ }
+}
+
+
+/*
+ * fsm_sconfreq - Send a Configure-Request.
+ */
+static void
+fsm_sconfreq(f, retransmit)
+ fsm *f;
+ int retransmit;
+{
+ u_char *outp;
+ int cilen;
+
+ if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){
+ /* Not currently negotiating - reset options */
+ if( f->callbacks->resetci )
+ (*f->callbacks->resetci)(f);
+ f->nakloops = 0;
+ }
+
+ if( !retransmit ){
+ /* New request - reset retransmission counter, use new ID */
+ f->retransmits = f->maxconfreqtransmits;
+ f->reqid = ++f->id;
+ }
+
+ f->seen_ack = 0;
+
+ /*
+ * Make up the request packet
+ */
+ outp = outpacket_buf + PPP_HDRLEN + HEADERLEN;
+ if( f->callbacks->cilen && f->callbacks->addci ){
+ cilen = (*f->callbacks->cilen)(f);
+ if( cilen > peer_mru[f->unit] - HEADERLEN )
+ cilen = peer_mru[f->unit] - HEADERLEN;
+ if (f->callbacks->addci)
+ (*f->callbacks->addci)(f, outp, &cilen);
+ } else
+ cilen = 0;
+
+ /* send the request to our peer */
+ fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);
+
+ /* start the retransmit timer */
+ --f->retransmits;
+ TIMEOUT(fsm_timeout, f, f->timeouttime);
+}
+
+
+/*
+ * fsm_sdata - Send some data.
+ *
+ * Used for all packets sent to our peer by this module.
+ */
+void
+fsm_sdata(f, code, id, data, datalen)
+ fsm *f;
+ u_char code, id;
+ u_char *data;
+ int datalen;
+{
+ u_char *outp;
+ int outlen;
+
+ /* Adjust length to be smaller than MTU */
+ outp = outpacket_buf;
+ if (datalen > peer_mru[f->unit] - HEADERLEN)
+ datalen = peer_mru[f->unit] - HEADERLEN;
+ if (datalen && data != outp + PPP_HDRLEN + HEADERLEN)
+ BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
+ outlen = datalen + HEADERLEN;
+ MAKEHEADER(outp, f->protocol);
+ PUTCHAR(code, outp);
+ PUTCHAR(id, outp);
+ PUTSHORT(outlen, outp);
+ output(f->unit, outpacket_buf, outlen + PPP_HDRLEN);
+}
diff --git a/cpukit/pppd/fsm.h b/cpukit/pppd/fsm.h
new file mode 100644
index 0000000000..d1e623467c
--- /dev/null
+++ b/cpukit/pppd/fsm.h
@@ -0,0 +1,144 @@
+/*
+ * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ *
+ * $Id$
+ */
+
+/*
+ * Packet header = Code, id, length.
+ */
+#define HEADERLEN 4
+
+
+/*
+ * CP (LCP, IPCP, etc.) codes.
+ */
+#define CONFREQ 1 /* Configuration Request */
+#define CONFACK 2 /* Configuration Ack */
+#define CONFNAK 3 /* Configuration Nak */
+#define CONFREJ 4 /* Configuration Reject */
+#define TERMREQ 5 /* Termination Request */
+#define TERMACK 6 /* Termination Ack */
+#define CODEREJ 7 /* Code Reject */
+
+
+/*
+ * Each FSM is described by an fsm structure and fsm callbacks.
+ */
+typedef struct fsm {
+ int unit; /* Interface unit number */
+ int protocol; /* Data Link Layer Protocol field value */
+ int state; /* State */
+ int flags; /* Contains option bits */
+ u_char id; /* Current id */
+ u_char reqid; /* Current request id */
+ u_char seen_ack; /* Have received valid Ack/Nak/Rej to Req */
+ int timeouttime; /* Timeout time in milliseconds */
+ int maxconfreqtransmits; /* Maximum Configure-Request transmissions */
+ int retransmits; /* Number of retransmissions left */
+ int maxtermtransmits; /* Maximum Terminate-Request transmissions */
+ int nakloops; /* Number of nak loops since last ack */
+ int maxnakloops; /* Maximum number of nak loops tolerated */
+ struct fsm_callbacks *callbacks; /* Callback routines */
+ char *term_reason; /* Reason for closing protocol */
+ int term_reason_len; /* Length of term_reason */
+} fsm;
+
+
+typedef struct fsm_callbacks {
+ void (*resetci) /* Reset our Configuration Information */
+ __P((fsm *));
+ int (*cilen) /* Length of our Configuration Information */
+ __P((fsm *));
+ void (*addci) /* Add our Configuration Information */
+ __P((fsm *, u_char *, int *));
+ int (*ackci) /* ACK our Configuration Information */
+ __P((fsm *, u_char *, int));
+ int (*nakci) /* NAK our Configuration Information */
+ __P((fsm *, u_char *, int));
+ int (*rejci) /* Reject our Configuration Information */
+ __P((fsm *, u_char *, int));
+ int (*reqci) /* Request peer's Configuration Information */
+ __P((fsm *, u_char *, int *, int));
+ void (*up) /* Called when fsm reaches OPENED state */
+ __P((fsm *));
+ void (*down) /* Called when fsm leaves OPENED state */
+ __P((fsm *));
+ void (*starting) /* Called when we want the lower layer */
+ __P((fsm *));
+ void (*finished) /* Called when we don't want the lower layer */
+ __P((fsm *));
+ void (*protreject) /* Called when Protocol-Reject received */
+ __P((int));
+ void (*retransmit) /* Retransmission is necessary */
+ __P((fsm *));
+ int (*extcode) /* Called when unknown code received */
+ __P((fsm *, int, int, u_char *, int));
+ char *proto_name; /* String name for protocol (for messages) */
+} fsm_callbacks;
+
+
+/*
+ * Link states.
+ */
+#define INITIAL 0 /* Down, hasn't been opened */
+#define STARTING 1 /* Down, been opened */
+#define CLOSED 2 /* Up, hasn't been opened */
+#define STOPPED 3 /* Open, waiting for down event */
+#define CLOSING 4 /* Terminating the connection, not open */
+#define STOPPING 5 /* Terminating, but open */
+#define REQSENT 6 /* We've sent a Config Request */
+#define ACKRCVD 7 /* We've received a Config Ack */
+#define ACKSENT 8 /* We've sent a Config Ack */
+#define OPENED 9 /* Connection available */
+
+
+/*
+ * Flags - indicate options controlling FSM operation
+ */
+#define OPT_PASSIVE 1 /* Don't die if we don't get a response */
+#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */
+#define OPT_SILENT 4 /* Wait for peer to speak first */
+
+
+/*
+ * Timeouts.
+ */
+#define DEFTIMEOUT 5 /* Timeout time in seconds */
+#define DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */
+#define DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */
+#define DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */
+
+
+/*
+ * Prototypes
+ */
+void fsm_init __P((fsm *));
+void fsm_lowerup __P((fsm *));
+void fsm_lowerdown __P((fsm *));
+void fsm_open __P((fsm *));
+void fsm_close __P((fsm *, char *));
+void fsm_input __P((fsm *, u_char *, int));
+void fsm_protreject __P((fsm *));
+void fsm_sdata __P((fsm *, u_char, u_char, u_char *, int));
+
+
+/*
+ * Variables
+ */
+extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */
diff --git a/cpukit/pppd/ipcp.c b/cpukit/pppd/ipcp.c
new file mode 100644
index 0000000000..6b6a93a09e
--- /dev/null
+++ b/cpukit/pppd/ipcp.c
@@ -0,0 +1,1768 @@
+/*
+ * ipcp.c - PPP IP Control Protocol.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ */
+
+#define RCSID "$Id$"
+
+/*
+ * TODO:
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+
+#include "pppd.h"
+#include "fsm.h"
+#include "ipcp.h"
+#include "pathnames.h"
+
+#include <rtems/bsdnet/servers.h>
+
+static const char rcsid[] = RCSID;
+
+/* global vars */
+ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
+ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
+ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
+ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
+
+bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */
+
+/* Hook for a plugin to know when IP protocol has come up */
+void (*ip_up_hook) __P((void)) = NULL;
+
+/* Hook for a plugin to know when IP protocol has come down */
+void (*ip_down_hook) __P((void)) = NULL;
+
+/* local vars */
+static int default_route_set[NUM_PPP]; /* Have set up a default route */
+static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */
+static bool usepeerdns; /* Ask peer for DNS addrs */
+static int ipcp_is_up; /* have called np_up() */
+
+/*
+ * Callbacks for fsm code. (CI = Configuration Information)
+ */
+static void ipcp_resetci __P((fsm *)); /* Reset our CI */
+static int ipcp_cilen __P((fsm *)); /* Return length of our CI */
+static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
+static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
+static int ipcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */
+static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
+static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
+static void ipcp_up __P((fsm *)); /* We're UP */
+static void ipcp_down __P((fsm *)); /* We're DOWN */
+static void ipcp_finished __P((fsm *)); /* Don't need lower layer */
+
+fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
+
+static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
+ ipcp_resetci, /* Reset our Configuration Information */
+ ipcp_cilen, /* Length of our Configuration Information */
+ ipcp_addci, /* Add our Configuration Information */
+ ipcp_ackci, /* ACK our Configuration Information */
+ ipcp_nakci, /* NAK our Configuration Information */
+ ipcp_rejci, /* Reject our Configuration Information */
+ ipcp_reqci, /* Request peer's Configuration Information */
+ ipcp_up, /* Called when fsm reaches OPENED state */
+ ipcp_down, /* Called when fsm leaves OPENED state */
+ NULL, /* Called when we want the lower layer up */
+ ipcp_finished, /* Called when we want the lower layer down */
+ NULL, /* Called when Protocol-Reject received */
+ NULL, /* Retransmission is necessary */
+ NULL, /* Called to handle protocol-specific codes */
+ "IPCP" /* String name of protocol */
+};
+
+/*
+ * Command-line options.
+ */
+static int setvjslots __P((char **));
+static int setdnsaddr __P((char **));
+static int setwinsaddr __P((char **));
+
+static option_t ipcp_option_list[] = {
+ { "noip", o_bool, &ipcp_protent.enabled_flag,
+ "Disable IP and IPCP" },
+ { "-ip", o_bool, &ipcp_protent.enabled_flag,
+ "Disable IP and IPCP" },
+ { "novj", o_bool, &ipcp_wantoptions[0].neg_vj,
+ "Disable VJ compression", OPT_A2COPY, &ipcp_allowoptions[0].neg_vj },
+ { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj,
+ "Disable VJ compression", OPT_A2COPY, &ipcp_allowoptions[0].neg_vj },
+ { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag,
+ "Disable VJ connection-ID compression", OPT_A2COPY,
+ &ipcp_allowoptions[0].cflag },
+ { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag,
+ "Disable VJ connection-ID compression", OPT_A2COPY,
+ &ipcp_allowoptions[0].cflag },
+ { "vj-max-slots", 1, setvjslots,
+ "Set maximum VJ header slots" },
+ { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local,
+ "Accept peer's address for us", 1 },
+ { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote,
+ "Accept peer's address for it", 1 },
+ { "ipparam", o_string, &ipparam,
+ "Set ip script parameter" },
+ { "noipdefault", o_bool, &disable_defaultip,
+ "Don't use name for default IP adrs", 1 },
+ { "ms-dns", 1, setdnsaddr,
+ "DNS address for the peer's use" },
+ { "ms-wins", 1, setwinsaddr,
+ "Nameserver for SMB over TCP/IP for peer" },
+ { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime,
+ "Set timeout for IPCP" },
+ { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits,
+ "Set max #xmits for term-reqs" },
+ { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits,
+ "Set max #xmits for conf-reqs" },
+ { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops,
+ "Set max #conf-naks for IPCP" },
+ { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route,
+ "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route },
+ { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route,
+ "disable defaultroute option", OPT_A2COPY,
+ &ipcp_wantoptions[0].default_route },
+ { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route,
+ "disable defaultroute option", OPT_A2COPY,
+ &ipcp_wantoptions[0].default_route },
+ { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
+ "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
+ { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
+ "disable proxyarp option", OPT_A2COPY,
+ &ipcp_wantoptions[0].proxy_arp },
+ { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
+ "disable proxyarp option", OPT_A2COPY,
+ &ipcp_wantoptions[0].proxy_arp },
+ { "usepeerdns", o_bool, &usepeerdns,
+ "Ask peer for DNS address(es)", 1 },
+ { NULL }
+};
+
+/*
+ * Protocol entry points from main code.
+ */
+static void ipcp_init __P((int));
+static void ipcp_open __P((int));
+static void ipcp_close __P((int, char *));
+static void ipcp_lowerup __P((int));
+static void ipcp_lowerdown __P((int));
+static void ipcp_input __P((int, u_char *, int));
+static void ipcp_protrej __P((int));
+static int ipcp_printpkt __P((u_char *, int,
+ void (*) __P((void *, char *, ...)), void *));
+static void ip_check_options __P((void));
+static int ip_demand_conf __P((int));
+static int ip_active_pkt __P((u_char *, int));
+static void create_resolv __P((u_int32_t, u_int32_t));
+
+struct protent ipcp_protent = {
+ PPP_IPCP,
+ ipcp_init,
+ ipcp_input,
+ ipcp_protrej,
+ ipcp_lowerup,
+ ipcp_lowerdown,
+ ipcp_open,
+ ipcp_close,
+ ipcp_printpkt,
+ NULL,
+ 1,
+ "IPCP",
+ "IP",
+ ipcp_option_list,
+ ip_check_options,
+ ip_demand_conf,
+ ip_active_pkt
+};
+
+static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
+
+/*
+ * Lengths of configuration options.
+ */
+#define CILEN_VOID 2
+#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */
+#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */
+#define CILEN_ADDR 6 /* new-style single address option */
+#define CILEN_ADDRS 10 /* old-style dual address option */
+
+
+#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
+ (x) == CONFNAK ? "NAK" : "REJ")
+
+/*
+ * Make a string representation of a network IP address.
+ */
+char *
+ip_ntoa(ipaddr)
+u_int32_t ipaddr;
+{
+ static char b[64];
+
+ slprintf(b, sizeof(b), "%I", ipaddr);
+ return b;
+}
+
+/*
+ * Option parsing.
+ */
+
+/*
+ * setvjslots - set maximum number of connection slots for VJ compression
+ */
+static int
+setvjslots(argv)
+ char **argv;
+{
+ int value;
+
+ if (!int_option(*argv, &value))
+ return 0;
+ if (value < 2 || value > 16) {
+ option_error("vj-max-slots value must be between 2 and 16");
+ return 0;
+ }
+ ipcp_wantoptions [0].maxslotindex =
+ ipcp_allowoptions[0].maxslotindex = value - 1;
+ return 1;
+}
+
+/*
+ * setdnsaddr - set the dns address(es)
+ */
+static int
+setdnsaddr(argv)
+ char **argv;
+{
+ u_int32_t dns;
+ struct hostent *hp;
+
+ dns = inet_addr(*argv);
+ if (dns == (u_int32_t) -1) {
+ if ((hp = gethostbyname(*argv)) == NULL) {
+ option_error("invalid address parameter '%s' for ms-dns option",
+ *argv);
+ return 0;
+ }
+ dns = *(u_int32_t *)hp->h_addr;
+ }
+
+ /* if there is no primary then update it. */
+ if (ipcp_allowoptions[0].dnsaddr[0] == 0)
+ ipcp_allowoptions[0].dnsaddr[0] = dns;
+
+ /* always set the secondary address value to the same value. */
+ ipcp_allowoptions[0].dnsaddr[1] = dns;
+
+ return (1);
+}
+
+/*
+ * setwinsaddr - set the wins address(es)
+ * This is primrarly used with the Samba package under UNIX or for pointing
+ * the caller to the existing WINS server on a Windows NT platform.
+ */
+static int
+setwinsaddr(argv)
+ char **argv;
+{
+ u_int32_t wins;
+ struct hostent *hp;
+
+ wins = inet_addr(*argv);
+ if (wins == (u_int32_t) -1) {
+ if ((hp = gethostbyname(*argv)) == NULL) {
+ option_error("invalid address parameter '%s' for ms-wins option",
+ *argv);
+ return 0;
+ }
+ wins = *(u_int32_t *)hp->h_addr;
+ }
+
+ /* if there is no primary then update it. */
+ if (ipcp_allowoptions[0].winsaddr[0] == 0)
+ ipcp_allowoptions[0].winsaddr[0] = wins;
+
+ /* always set the secondary address value to the same value. */
+ ipcp_allowoptions[0].winsaddr[1] = wins;
+
+ return (1);
+}
+
+
+/*
+ * ipcp_init - Initialize IPCP.
+ */
+static void
+ipcp_init(unit)
+ int unit;
+{
+ fsm *f = &ipcp_fsm[unit];
+ ipcp_options *wo = &ipcp_wantoptions[unit];
+ ipcp_options *ao = &ipcp_allowoptions[unit];
+
+ f->unit = unit;
+ f->protocol = PPP_IPCP;
+ f->callbacks = &ipcp_callbacks;
+ fsm_init(&ipcp_fsm[unit]);
+
+ memset(wo, 0, sizeof(*wo));
+ memset(ao, 0, sizeof(*ao));
+
+ wo->neg_addr = 1;
+ wo->neg_vj = 1;
+ wo->vj_protocol = IPCP_VJ_COMP;
+ wo->maxslotindex = MAX_STATES - 1; /* really max index */
+ wo->cflag = 1;
+
+ /* max slots and slot-id compression are currently hardwired in */
+ /* ppp_if.c to 16 and 1, this needs to be changed (among other */
+ /* things) gmc */
+
+ ao->neg_addr = 1;
+ ao->neg_vj = 1;
+ ao->maxslotindex = MAX_STATES - 1;
+ ao->cflag = 1;
+
+ /*
+ * XXX These control whether the user may use the proxyarp
+ * and defaultroute options.
+ */
+ ao->proxy_arp = 1;
+ ao->default_route = 1;
+}
+
+
+/*
+ * ipcp_open - IPCP is allowed to come up.
+ */
+static void
+ipcp_open(unit)
+ int unit;
+{
+ fsm_open(&ipcp_fsm[unit]);
+}
+
+
+/*
+ * ipcp_close - Take IPCP down.
+ */
+static void
+ipcp_close(unit, reason)
+ int unit;
+ char *reason;
+{
+ fsm_close(&ipcp_fsm[unit], reason);
+}
+
+
+/*
+ * ipcp_lowerup - The lower layer is up.
+ */
+static void
+ipcp_lowerup(unit)
+ int unit;
+{
+ fsm_lowerup(&ipcp_fsm[unit]);
+}
+
+
+/*
+ * ipcp_lowerdown - The lower layer is down.
+ */
+static void
+ipcp_lowerdown(unit)
+ int unit;
+{
+ fsm_lowerdown(&ipcp_fsm[unit]);
+}
+
+
+/*
+ * ipcp_input - Input IPCP packet.
+ */
+static void
+ipcp_input(unit, p, len)
+ int unit;
+ u_char *p;
+ int len;
+{
+ fsm_input(&ipcp_fsm[unit], p, len);
+}
+
+
+/*
+ * ipcp_protrej - A Protocol-Reject was received for IPCP.
+ *
+ * Pretend the lower layer went down, so we shut up.
+ */
+static void
+ipcp_protrej(unit)
+ int unit;
+{
+ fsm_lowerdown(&ipcp_fsm[unit]);
+}
+
+
+/*
+ * ipcp_resetci - Reset our CI.
+ * Called by fsm_sconfreq, Send Configure Request.
+ */
+static void
+ipcp_resetci(f)
+ fsm *f;
+{
+ ipcp_options *wo = &ipcp_wantoptions[f->unit];
+ ipcp_options *go = &ipcp_gotoptions[f->unit];
+
+ wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;
+ if (wo->ouraddr == 0 || disable_defaultip)
+ wo->accept_local = 1;
+ if (wo->hisaddr == 0)
+ wo->accept_remote = 1;
+ wo->req_dns1 = usepeerdns; /* Request DNS addresses from the peer */
+ wo->req_dns2 = usepeerdns;
+ *go = *wo;
+ if (disable_defaultip)
+ go->ouraddr = 0;
+}
+
+
+/*
+ * ipcp_cilen - Return length of our CI.
+ * Called by fsm_sconfreq, Send Configure Request.
+ */
+static int
+ipcp_cilen(f)
+ fsm *f;
+{
+ ipcp_options *go = &ipcp_gotoptions[f->unit];
+ ipcp_options *wo = &ipcp_wantoptions[f->unit];
+ ipcp_options *ho = &ipcp_hisoptions[f->unit];
+
+#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
+#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)
+#define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0)
+
+ /*
+ * First see if we want to change our options to the old
+ * forms because we have received old forms from the peer.
+ */
+ if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {
+ /* use the old style of address negotiation */
+ go->neg_addr = 1;
+ go->old_addrs = 1;
+ }
+ if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
+ /* try an older style of VJ negotiation */
+ /* use the old style only if the peer did */
+ if (ho->neg_vj && ho->old_vj) {
+ go->neg_vj = 1;
+ go->old_vj = 1;
+ go->vj_protocol = ho->vj_protocol;
+ }
+ }
+
+ return (LENCIADDR(go->neg_addr, go->old_addrs) +
+ LENCIVJ(go->neg_vj, go->old_vj) +
+ LENCIDNS(go->req_dns1) +
+ LENCIDNS(go->req_dns2)) ;
+}
+
+
+/*
+ * ipcp_addci - Add our desired CIs to a packet.
+ * Called by fsm_sconfreq, Send Configure Request.
+ */
+static void
+ipcp_addci(f, ucp, lenp)
+ fsm *f;
+ u_char *ucp;
+ int *lenp;
+{
+ ipcp_options *go = &ipcp_gotoptions[f->unit];
+ int len = *lenp;
+
+#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
+ if (neg) { \
+ int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
+ if (len >= vjlen) { \
+ PUTCHAR(opt, ucp); \
+ PUTCHAR(vjlen, ucp); \
+ PUTSHORT(val, ucp); \
+ if (!old) { \
+ PUTCHAR(maxslotindex, ucp); \
+ PUTCHAR(cflag, ucp); \
+ } \
+ len -= vjlen; \
+ } else \
+ neg = 0; \
+ }
+
+#define ADDCIADDR(opt, neg, old, val1, val2) \
+ if (neg) { \
+ int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
+ if (len >= addrlen) { \
+ u_int32_t l; \
+ PUTCHAR(opt, ucp); \
+ PUTCHAR(addrlen, ucp); \
+ l = ntohl(val1); \
+ PUTLONG(l, ucp); \
+ if (old) { \
+ l = ntohl(val2); \
+ PUTLONG(l, ucp); \
+ } \
+ len -= addrlen; \
+ } else \
+ neg = 0; \
+ }
+
+#define ADDCIDNS(opt, neg, addr) \
+ if (neg) { \
+ if (len >= CILEN_ADDR) { \
+ u_int32_t l; \
+ PUTCHAR(opt, ucp); \
+ PUTCHAR(CILEN_ADDR, ucp); \
+ l = ntohl(addr); \
+ PUTLONG(l, ucp); \
+ len -= CILEN_ADDR; \
+ } else \
+ neg = 0; \
+ }
+
+ ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
+ go->old_addrs, go->ouraddr, go->hisaddr);
+
+ ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
+ go->maxslotindex, go->cflag);
+
+ ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
+
+ ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
+
+ *lenp -= len;
+}
+
+
+/*
+ * ipcp_ackci - Ack our CIs.
+ * Called by fsm_rconfack, Receive Configure ACK.
+ *
+ * Returns:
+ * 0 - Ack was bad.
+ * 1 - Ack was good.
+ */
+static int
+ipcp_ackci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ ipcp_options *go = &ipcp_gotoptions[f->unit];
+ u_short cilen, citype, cishort;
+ u_int32_t cilong;
+ u_char cimaxslotindex, cicflag;
+
+ /*
+ * CIs must be in exactly the same order that we sent...
+ * Check packet length and CI length at each step.
+ * If we find any deviations, then this packet is bad.
+ */
+
+#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
+ if (neg) { \
+ int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
+ if ((len -= vjlen) < 0) \
+ goto bad; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != vjlen || \
+ citype != opt) \
+ goto bad; \
+ GETSHORT(cishort, p); \
+ if (cishort != val) \
+ goto bad; \
+ if (!old) { \
+ GETCHAR(cimaxslotindex, p); \
+ if (cimaxslotindex != maxslotindex) \
+ goto bad; \
+ GETCHAR(cicflag, p); \
+ if (cicflag != cflag) \
+ goto bad; \
+ } \
+ }
+
+#define ACKCIADDR(opt, neg, old, val1, val2) \
+ if (neg) { \
+ int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
+ u_int32_t l; \
+ if ((len -= addrlen) < 0) \
+ goto bad; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != addrlen || \
+ citype != opt) \
+ goto bad; \
+ GETLONG(l, p); \
+ cilong = htonl(l); \
+ if (val1 != cilong) \
+ goto bad; \
+ if (old) { \
+ GETLONG(l, p); \
+ cilong = htonl(l); \
+ if (val2 != cilong) \
+ goto bad; \
+ } \
+ }
+
+#define ACKCIDNS(opt, neg, addr) \
+ if (neg) { \
+ u_int32_t l; \
+ if ((len -= CILEN_ADDR) < 0) \
+ goto bad; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_ADDR || citype != opt) \
+ goto bad; \
+ GETLONG(l, p); \
+ cilong = htonl(l); \
+ if (addr != cilong) \
+ goto bad; \
+ }
+
+ ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
+ go->old_addrs, go->ouraddr, go->hisaddr);
+
+ ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
+ go->maxslotindex, go->cflag);
+
+ ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
+
+ ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
+
+ /*
+ * If there are any remaining CIs, then this packet is bad.
+ */
+ if (len != 0)
+ goto bad;
+ return (1);
+
+bad:
+ IPCPDEBUG(("ipcp_ackci: received bad Ack!"));
+ return (0);
+}
+
+/*
+ * ipcp_nakci - Peer has sent a NAK for some of our CIs.
+ * This should not modify any state if the Nak is bad
+ * or if IPCP is in the OPENED state.
+ * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
+ *
+ * Returns:
+ * 0 - Nak was bad.
+ * 1 - Nak was good.
+ */
+static int
+ipcp_nakci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ ipcp_options *go = &ipcp_gotoptions[f->unit];
+ u_char cimaxslotindex, cicflag;
+ u_char citype, cilen, *next;
+ u_short cishort;
+ u_int32_t ciaddr1, ciaddr2, l, cidnsaddr;
+ ipcp_options no; /* options we've seen Naks for */
+ ipcp_options try; /* options to request next time */
+
+ BZERO(&no, sizeof(no));
+ try = *go;
+
+ /*
+ * Any Nak'd CIs must be in exactly the same order that we sent.
+ * Check packet length and CI length at each step.
+ * If we find any deviations, then this packet is bad.
+ */
+#define NAKCIADDR(opt, neg, old, code) \
+ if (go->neg && \
+ len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \
+ p[1] == cilen && \
+ p[0] == opt) { \
+ len -= cilen; \
+ INCPTR(2, p); \
+ GETLONG(l, p); \
+ ciaddr1 = htonl(l); \
+ if (old) { \
+ GETLONG(l, p); \
+ ciaddr2 = htonl(l); \
+ no.old_addrs = 1; \
+ } else \
+ ciaddr2 = 0; \
+ no.neg = 1; \
+ code \
+ }
+
+#define NAKCIVJ(opt, neg, code) \
+ if (go->neg && \
+ ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
+ len >= cilen && \
+ p[0] == opt) { \
+ len -= cilen; \
+ INCPTR(2, p); \
+ GETSHORT(cishort, p); \
+ no.neg = 1; \
+ code \
+ }
+
+#define NAKCIDNS(opt, neg, code) \
+ if (go->neg && \
+ ((cilen = p[1]) == CILEN_ADDR) && \
+ len >= cilen && \
+ p[0] == opt) { \
+ len -= cilen; \
+ INCPTR(2, p); \
+ GETLONG(l, p); \
+ cidnsaddr = htonl(l); \
+ no.neg = 1; \
+ code \
+ }
+
+ /*
+ * Accept the peer's idea of {our,his} address, if different
+ * from our idea, only if the accept_{local,remote} flag is set.
+ */
+ NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
+ if (go->accept_local && ciaddr1) { /* Do we know our address? */
+ try.ouraddr = ciaddr1;
+ }
+ if (go->accept_remote && ciaddr2) { /* Does he know his? */
+ try.hisaddr = ciaddr2;
+ }
+ );
+
+ /*
+ * Accept the peer's value of maxslotindex provided that it
+ * is less than what we asked for. Turn off slot-ID compression
+ * if the peer wants. Send old-style compress-type option if
+ * the peer wants.
+ */
+ NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
+ if (cilen == CILEN_VJ) {
+ GETCHAR(cimaxslotindex, p);
+ GETCHAR(cicflag, p);
+ if (cishort == IPCP_VJ_COMP) {
+ try.old_vj = 0;
+ if (cimaxslotindex < go->maxslotindex)
+ try.maxslotindex = cimaxslotindex;
+ if (!cicflag)
+ try.cflag = 0;
+ } else {
+ try.neg_vj = 0;
+ }
+ } else {
+ if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
+ try.old_vj = 1;
+ try.vj_protocol = cishort;
+ } else {
+ try.neg_vj = 0;
+ }
+ }
+ );
+
+ NAKCIDNS(CI_MS_DNS1, req_dns1,
+ try.dnsaddr[0] = cidnsaddr;
+ );
+
+ NAKCIDNS(CI_MS_DNS2, req_dns2,
+ try.dnsaddr[1] = cidnsaddr;
+ );
+
+ /*
+ * There may be remaining CIs, if the peer is requesting negotiation
+ * on an option that we didn't include in our request packet.
+ * If they want to negotiate about IP addresses, we comply.
+ * If they want us to ask for compression, we refuse.
+ */
+ while (len > CILEN_VOID) {
+ GETCHAR(citype, p);
+ GETCHAR(cilen, p);
+ if( (len -= cilen) < 0 )
+ goto bad;
+ next = p + cilen - 2;
+
+ switch (citype) {
+ case CI_COMPRESSTYPE:
+ if (go->neg_vj || no.neg_vj ||
+ (cilen != CILEN_VJ && cilen != CILEN_COMPRESS))
+ goto bad;
+ no.neg_vj = 1;
+ break;
+ case CI_ADDRS:
+ if ((go->neg_addr && go->old_addrs) || no.old_addrs
+ || cilen != CILEN_ADDRS)
+ goto bad;
+ try.neg_addr = 1;
+ try.old_addrs = 1;
+ GETLONG(l, p);
+ ciaddr1 = htonl(l);
+ if (ciaddr1 && go->accept_local)
+ try.ouraddr = ciaddr1;
+ GETLONG(l, p);
+ ciaddr2 = htonl(l);
+ if (ciaddr2 && go->accept_remote)
+ try.hisaddr = ciaddr2;
+ no.old_addrs = 1;
+ break;
+ case CI_ADDR:
+ if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)
+ goto bad;
+ try.old_addrs = 0;
+ GETLONG(l, p);
+ ciaddr1 = htonl(l);
+ if (ciaddr1 && go->accept_local)
+ try.ouraddr = ciaddr1;
+ if (try.ouraddr != 0)
+ try.neg_addr = 1;
+ no.neg_addr = 1;
+ break;
+ }
+ p = next;
+ }
+
+ /*
+ * OK, the Nak is good. Now we can update state.
+ * If there are any remaining options, we ignore them.
+ */
+ if (f->state != OPENED)
+ *go = try;
+
+ return 1;
+
+bad:
+ IPCPDEBUG(("ipcp_nakci: received bad Nak!"));
+ return 0;
+}
+
+
+/*
+ * ipcp_rejci - Reject some of our CIs.
+ * Callback from fsm_rconfnakrej.
+ */
+static int
+ipcp_rejci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ ipcp_options *go = &ipcp_gotoptions[f->unit];
+ u_char cimaxslotindex, ciflag, cilen;
+ u_short cishort;
+ u_int32_t cilong;
+ ipcp_options try; /* options to request next time */
+
+ try = *go;
+ /*
+ * Any Rejected CIs must be in exactly the same order that we sent.
+ * Check packet length and CI length at each step.
+ * If we find any deviations, then this packet is bad.
+ */
+#define REJCIADDR(opt, neg, old, val1, val2) \
+ if (go->neg && \
+ len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \
+ p[1] == cilen && \
+ p[0] == opt) { \
+ u_int32_t l; \
+ len -= cilen; \
+ INCPTR(2, p); \
+ GETLONG(l, p); \
+ cilong = htonl(l); \
+ /* Check rejected value. */ \
+ if (cilong != val1) \
+ goto bad; \
+ if (old) { \
+ GETLONG(l, p); \
+ cilong = htonl(l); \
+ /* Check rejected value. */ \
+ if (cilong != val2) \
+ goto bad; \
+ } \
+ try.neg = 0; \
+ }
+
+#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
+ if (go->neg && \
+ p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
+ len >= p[1] && \
+ p[0] == opt) { \
+ len -= p[1]; \
+ INCPTR(2, p); \
+ GETSHORT(cishort, p); \
+ /* Check rejected value. */ \
+ if (cishort != val) \
+ goto bad; \
+ if (!old) { \
+ GETCHAR(cimaxslotindex, p); \
+ if (cimaxslotindex != maxslot) \
+ goto bad; \
+ GETCHAR(ciflag, p); \
+ if (ciflag != cflag) \
+ goto bad; \
+ } \
+ try.neg = 0; \
+ }
+
+#define REJCIDNS(opt, neg, dnsaddr) \
+ if (go->neg && \
+ ((cilen = p[1]) == CILEN_ADDR) && \
+ len >= cilen && \
+ p[0] == opt) { \
+ u_int32_t l; \
+ len -= cilen; \
+ INCPTR(2, p); \
+ GETLONG(l, p); \
+ cilong = htonl(l); \
+ /* Check rejected value. */ \
+ if (cilong != dnsaddr) \
+ goto bad; \
+ try.neg = 0; \
+ }
+
+
+ REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,
+ go->old_addrs, go->ouraddr, go->hisaddr);
+
+ REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
+ go->maxslotindex, go->cflag);
+
+ REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
+
+ REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
+
+ /*
+ * If there are any remaining CIs, then this packet is bad.
+ */
+ if (len != 0)
+ goto bad;
+ /*
+ * Now we can update state.
+ */
+ if (f->state != OPENED)
+ *go = try;
+ return 1;
+
+bad:
+ IPCPDEBUG(("ipcp_rejci: received bad Reject!"));
+ return 0;
+}
+
+
+/*
+ * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
+ * Callback from fsm_rconfreq, Receive Configure Request
+ *
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
+ * appropriately. If reject_if_disagree is non-zero, doesn't return
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.
+ */
+static int
+ipcp_reqci(f, inp, len, reject_if_disagree)
+ fsm *f;
+ u_char *inp; /* Requested CIs */
+ int *len; /* Length of requested CIs */
+ int reject_if_disagree;
+{
+ ipcp_options *wo = &ipcp_wantoptions[f->unit];
+ ipcp_options *ho = &ipcp_hisoptions[f->unit];
+ ipcp_options *ao = &ipcp_allowoptions[f->unit];
+ ipcp_options *go = &ipcp_gotoptions[f->unit];
+ u_char *cip, *next; /* Pointer to current and next CIs */
+ u_short cilen, citype; /* Parsed len, type */
+ u_short cishort; /* Parsed short value */
+ u_int32_t tl, ciaddr1, ciaddr2;/* Parsed address values */
+ int rc = CONFACK; /* Final packet return code */
+ int orc; /* Individual option return code */
+ u_char *p; /* Pointer to next char to parse */
+ u_char *ucp = inp; /* Pointer to current output char */
+ int l = *len; /* Length left */
+ u_char maxslotindex, cflag;
+ int d;
+
+ /*
+ * Reset all his options.
+ */
+ BZERO(ho, sizeof(*ho));
+
+ /*
+ * Process all his options.
+ */
+ next = inp;
+ while (l) {
+ orc = CONFACK; /* Assume success */
+ cip = p = next; /* Remember begining of CI */
+ if (l < 2 || /* Not enough data for CI header or */
+ p[1] < 2 || /* CI length too small or */
+ p[1] > l) { /* CI length too big? */
+ IPCPDEBUG(("ipcp_reqci: bad CI length!"));
+ orc = CONFREJ; /* Reject bad CI */
+ cilen = l; /* Reject till end of packet */
+ l = 0; /* Don't loop again */
+ goto endswitch;
+ }
+ GETCHAR(citype, p); /* Parse CI type */
+ GETCHAR(cilen, p); /* Parse CI length */
+ l -= cilen; /* Adjust remaining length */
+ next += cilen; /* Step to next CI */
+
+ switch (citype) { /* Check CI type */
+ case CI_ADDRS:
+ if (!ao->neg_addr ||
+ cilen != CILEN_ADDRS) { /* Check CI length */
+ orc = CONFREJ; /* Reject CI */
+ break;
+ }
+
+ /*
+ * If he has no address, or if we both have his address but
+ * disagree about it, then NAK it with our idea.
+ * In particular, if we don't know his address, but he does,
+ * then accept it.
+ */
+ GETLONG(tl, p); /* Parse source address (his) */
+ ciaddr1 = htonl(tl);
+ if (ciaddr1 != wo->hisaddr
+ && (ciaddr1 == 0 || !wo->accept_remote)) {
+ orc = CONFNAK;
+ if (!reject_if_disagree) {
+ DECPTR(sizeof(u_int32_t), p);
+ tl = ntohl(wo->hisaddr);
+ PUTLONG(tl, p);
+ }
+ } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
+ /*
+ * If neither we nor he knows his address, reject the option.
+ */
+ orc = CONFREJ;
+ wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
+ break;
+ }
+
+ /*
+ * If he doesn't know our address, or if we both have our address
+ * but disagree about it, then NAK it with our idea.
+ */
+ GETLONG(tl, p); /* Parse desination address (ours) */
+ ciaddr2 = htonl(tl);
+ if (ciaddr2 != wo->ouraddr) {
+ if (ciaddr2 == 0 || !wo->accept_local) {
+ orc = CONFNAK;
+ if (!reject_if_disagree) {
+ DECPTR(sizeof(u_int32_t), p);
+ tl = ntohl(wo->ouraddr);
+ PUTLONG(tl, p);
+ }
+ } else {
+ go->ouraddr = ciaddr2; /* accept peer's idea */
+ }
+ }
+
+ ho->neg_addr = 1;
+ ho->old_addrs = 1;
+ ho->hisaddr = ciaddr1;
+ ho->ouraddr = ciaddr2;
+ break;
+
+ case CI_ADDR:
+ if (!ao->neg_addr ||
+ cilen != CILEN_ADDR) { /* Check CI length */
+ orc = CONFREJ; /* Reject CI */
+ break;
+ }
+
+ /*
+ * If he has no address, or if we both have his address but
+ * disagree about it, then NAK it with our idea.
+ * In particular, if we don't know his address, but he does,
+ * then accept it.
+ */
+ GETLONG(tl, p); /* Parse source address (his) */
+ ciaddr1 = htonl(tl);
+ if (ciaddr1 != wo->hisaddr
+ && (ciaddr1 == 0 || !wo->accept_remote)) {
+ orc = CONFNAK;
+ if (!reject_if_disagree) {
+ DECPTR(sizeof(u_int32_t), p);
+ tl = ntohl(wo->hisaddr);
+ PUTLONG(tl, p);
+ }
+ } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
+ /*
+ * Don't ACK an address of 0.0.0.0 - reject it instead.
+ */
+ orc = CONFREJ;
+ wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
+ break;
+ }
+
+ ho->neg_addr = 1;
+ ho->hisaddr = ciaddr1;
+ break;
+
+ case CI_MS_DNS1:
+ case CI_MS_DNS2:
+ /* Microsoft primary or secondary DNS request */
+ d = citype == CI_MS_DNS2;
+
+ /* If we do not have a DNS address then we cannot send it */
+ if (ao->dnsaddr[d] == 0 ||
+ cilen != CILEN_ADDR) { /* Check CI length */
+ orc = CONFREJ; /* Reject CI */
+ break;
+ }
+ GETLONG(tl, p);
+ if (htonl(tl) != ao->dnsaddr[d]) {
+ DECPTR(sizeof(u_int32_t), p);
+ tl = ntohl(ao->dnsaddr[d]);
+ PUTLONG(tl, p);
+ orc = CONFNAK;
+ }
+ break;
+
+ case CI_MS_WINS1:
+ case CI_MS_WINS2:
+ /* Microsoft primary or secondary WINS request */
+ d = citype == CI_MS_WINS2;
+
+ /* If we do not have a DNS address then we cannot send it */
+ if (ao->winsaddr[d] == 0 ||
+ cilen != CILEN_ADDR) { /* Check CI length */
+ orc = CONFREJ; /* Reject CI */
+ break;
+ }
+ GETLONG(tl, p);
+ if (htonl(tl) != ao->winsaddr[d]) {
+ DECPTR(sizeof(u_int32_t), p);
+ tl = ntohl(ao->winsaddr[d]);
+ PUTLONG(tl, p);
+ orc = CONFNAK;
+ }
+ break;
+
+ case CI_COMPRESSTYPE:
+ if (!ao->neg_vj ||
+ (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {
+ orc = CONFREJ;
+ break;
+ }
+ GETSHORT(cishort, p);
+
+ if (!(cishort == IPCP_VJ_COMP ||
+ (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
+ orc = CONFREJ;
+ break;
+ }
+
+ ho->neg_vj = 1;
+ ho->vj_protocol = cishort;
+ if (cilen == CILEN_VJ) {
+ GETCHAR(maxslotindex, p);
+ if (maxslotindex > ao->maxslotindex) {
+ orc = CONFNAK;
+ if (!reject_if_disagree){
+ DECPTR(1, p);
+ PUTCHAR(ao->maxslotindex, p);
+ }
+ }
+ GETCHAR(cflag, p);
+ if (cflag && !ao->cflag) {
+ orc = CONFNAK;
+ if (!reject_if_disagree){
+ DECPTR(1, p);
+ PUTCHAR(wo->cflag, p);
+ }
+ }
+ ho->maxslotindex = maxslotindex;
+ ho->cflag = cflag;
+ } else {
+ ho->old_vj = 1;
+ ho->maxslotindex = MAX_STATES - 1;
+ ho->cflag = 1;
+ }
+ break;
+
+ default:
+ orc = CONFREJ;
+ break;
+ }
+endswitch:
+ if (orc == CONFACK && /* Good CI */
+ rc != CONFACK) /* but prior CI wasnt? */
+ continue; /* Don't send this one */
+
+ if (orc == CONFNAK) { /* Nak this CI? */
+ if (reject_if_disagree) /* Getting fed up with sending NAKs? */
+ orc = CONFREJ; /* Get tough if so */
+ else {
+ if (rc == CONFREJ) /* Rejecting prior CI? */
+ continue; /* Don't send this one */
+ if (rc == CONFACK) { /* Ack'd all prior CIs? */
+ rc = CONFNAK; /* Not anymore... */
+ ucp = inp; /* Backup */
+ }
+ }
+ }
+
+ if (orc == CONFREJ && /* Reject this CI */
+ rc != CONFREJ) { /* but no prior ones? */
+ rc = CONFREJ;
+ ucp = inp; /* Backup */
+ }
+
+ /* Need to move CI? */
+ if (ucp != cip)
+ BCOPY(cip, ucp, cilen); /* Move it */
+
+ /* Update output pointer */
+ INCPTR(cilen, ucp);
+ }
+
+ /*
+ * If we aren't rejecting this packet, and we want to negotiate
+ * their address, and they didn't send their address, then we
+ * send a NAK with a CI_ADDR option appended. We assume the
+ * input buffer is long enough that we can append the extra
+ * option safely.
+ */
+ if (rc != CONFREJ && !ho->neg_addr &&
+ wo->req_addr && !reject_if_disagree) {
+ if (rc == CONFACK) {
+ rc = CONFNAK;
+ ucp = inp; /* reset pointer */
+ wo->req_addr = 0; /* don't ask again */
+ }
+ PUTCHAR(CI_ADDR, ucp);
+ PUTCHAR(CILEN_ADDR, ucp);
+ tl = ntohl(wo->hisaddr);
+ PUTLONG(tl, ucp);
+ }
+
+ *len = ucp - inp; /* Compute output length */
+ IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc)));
+ return (rc); /* Return final code */
+}
+
+
+/*
+ * ip_check_options - check that any IP-related options are OK,
+ * and assign appropriate defaults.
+ */
+static void
+ip_check_options()
+{
+ struct hostent *hp;
+ u_int32_t local;
+ ipcp_options *wo = &ipcp_wantoptions[0];
+
+ /*
+ * Default our local IP address based on our hostname.
+ * If local IP address already given, don't bother.
+ */
+ if (wo->ouraddr == 0) {
+ /*
+ * Look up our hostname (possibly with domain name appended)
+ * and take the first IP address as our local IP address.
+ * If there isn't an IP address for our hostname, too bad.
+ */
+ wo->accept_local = 1; /* don't insist on this default value */
+ if ((hp = gethostbyname(hostname)) != NULL) {
+ local = *(u_int32_t *)hp->h_addr;
+ if (local != 0 && !bad_ip_adrs(local))
+ wo->ouraddr = local;
+ }
+ }
+}
+
+
+/*
+ * ip_demand_conf - configure the interface as though
+ * IPCP were up, for use with dial-on-demand.
+ */
+static int
+ip_demand_conf(u)
+ int u;
+{
+ ipcp_options *wo = &ipcp_wantoptions[u];
+
+ if (wo->hisaddr == 0) {
+ /* make up an arbitrary address for the peer */
+ wo->hisaddr = htonl(0x0a707070 + pppifunit);
+ wo->accept_remote = 1;
+ }
+ if (wo->ouraddr == 0) {
+ /* make up an arbitrary address for us */
+ wo->ouraddr = htonl(0x0a404040 + pppifunit);
+ wo->accept_local = 1;
+ disable_defaultip = 1; /* don't tell the peer this address */
+ }
+ if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr)))
+ return 0;
+ if (!sifup(u))
+ return 0;
+ if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
+ return 0;
+ if (wo->default_route)
+ if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
+ default_route_set[u] = 1;
+ if (wo->proxy_arp)
+ if (sifproxyarp(u, wo->hisaddr))
+ proxy_arp_set[u] = 1;
+
+ notice("local IP address %I", wo->ouraddr);
+ notice("remote IP address %I", wo->hisaddr);
+
+ return 1;
+}
+
+
+/*
+ * ipcp_up - IPCP has come UP.
+ *
+ * Configure the IP network interface appropriately and bring it up.
+ */
+static void
+ipcp_up(f)
+ fsm *f;
+{
+ u_int32_t mask;
+ ipcp_options *ho = &ipcp_hisoptions[f->unit];
+ ipcp_options *go = &ipcp_gotoptions[f->unit];
+ ipcp_options *wo = &ipcp_wantoptions[f->unit];
+
+ IPCPDEBUG(("ipcp: up"));
+
+ /*
+ * We must have a non-zero IP address for both ends of the link.
+ */
+ if (!ho->neg_addr)
+ ho->hisaddr = wo->hisaddr;
+
+ if (ho->hisaddr == 0) {
+ error("Could not determine remote IP address");
+ ipcp_close(f->unit, "Could not determine remote IP address");
+ return;
+ }
+ if (go->ouraddr == 0) {
+ error("Could not determine local IP address");
+ ipcp_close(f->unit, "Could not determine local IP address");
+ return;
+ }
+
+ if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
+ create_resolv(go->dnsaddr[0], go->dnsaddr[1]);
+ }
+
+ /*
+ * Check that the peer is allowed to use the IP address it wants.
+ */
+ if (!auth_ip_addr(f->unit, ho->hisaddr)) {
+ error("Peer is not authorized to use remote address %I", ho->hisaddr);
+ ipcp_close(f->unit, "Unauthorized remote IP address");
+ return;
+ }
+
+ /* set tcp compression */
+ sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);
+
+ /*
+ * If we are doing dial-on-demand, the interface is already
+ * configured, so we put out any saved-up packets, then set the
+ * interface to pass IP packets.
+ */
+ if (demand) {
+ if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
+ ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
+ if (go->ouraddr != wo->ouraddr) {
+ warn("Local IP address changed to %I", go->ouraddr);
+ wo->ouraddr = go->ouraddr;
+ }
+ if (ho->hisaddr != wo->hisaddr) {
+ warn("Remote IP address changed to %I", ho->hisaddr);
+ wo->hisaddr = ho->hisaddr;
+ }
+
+ /* Set the interface to the new addresses */
+ mask = GetMask(go->ouraddr);
+ if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
+ if (debug)
+ warn("Interface configuration failed");
+ ipcp_close(f->unit, "Interface configuration failed");
+ return;
+ }
+
+ /* assign a default route through the interface if required */
+ if (ipcp_wantoptions[f->unit].default_route)
+ if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
+ default_route_set[f->unit] = 1;
+
+ /* Make a proxy ARP entry if requested. */
+ if (ipcp_wantoptions[f->unit].proxy_arp)
+ if (sifproxyarp(f->unit, ho->hisaddr))
+ proxy_arp_set[f->unit] = 1;
+
+ }
+ demand_rexmit(PPP_IP);
+ sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
+
+ } else {
+ /*
+ * Set IP addresses and (if specified) netmask.
+ */
+ mask = GetMask(go->ouraddr);
+
+#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__)))
+ if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
+ if (debug)
+ warn("Interface configuration failed");
+ ipcp_close(f->unit, "Interface configuration failed");
+ return;
+ }
+#endif
+
+ /* bring the interface up for IP */
+ if (!sifup(f->unit)) {
+ if (debug)
+ warn("Interface failed to come up");
+ ipcp_close(f->unit, "Interface configuration failed");
+ return;
+ }
+
+#if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
+ if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
+ if (debug)
+ warn("Interface configuration failed");
+ ipcp_close(f->unit, "Interface configuration failed");
+ return;
+ }
+#endif
+ sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
+
+ /* assign a default route through the interface if required */
+ if (ipcp_wantoptions[f->unit].default_route)
+ if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
+ default_route_set[f->unit] = 1;
+
+ /* Make a proxy ARP entry if requested. */
+ if (ipcp_wantoptions[f->unit].proxy_arp)
+ if (sifproxyarp(f->unit, ho->hisaddr))
+ proxy_arp_set[f->unit] = 1;
+
+ ipcp_wantoptions[0].ouraddr = go->ouraddr;
+
+ notice("local IP address %I", go->ouraddr);
+ notice("remote IP address %I", ho->hisaddr);
+ if (go->dnsaddr[0])
+ notice("primary DNS address %I", go->dnsaddr[0]);
+ if (go->dnsaddr[1])
+ notice("secondary DNS address %I", go->dnsaddr[1]);
+ }
+
+ np_up(f->unit, PPP_IP);
+ ipcp_is_up = 1;
+
+ if (ip_up_hook)
+ ip_up_hook();
+}
+
+
+/*
+ * ipcp_down - IPCP has gone DOWN.
+ *
+ * Take the IP network interface down, clear its addresses
+ * and delete routes through it.
+ */
+static void
+ipcp_down(f)
+ fsm *f;
+{
+ IPCPDEBUG(("ipcp: down"));
+ /* XXX a bit IPv4-centric here, we only need to get the stats
+ * before the interface is marked down. */
+ update_link_stats(f->unit);
+ if (ip_down_hook)
+ ip_down_hook();
+ if (ipcp_is_up) {
+ ipcp_is_up = 0;
+ np_down(f->unit, PPP_IP);
+ }
+ sifvjcomp(f->unit, 0, 0, 0);
+
+ /*
+ * If we are doing dial-on-demand, set the interface
+ * to queue up outgoing packets (for now).
+ */
+ if (demand) {
+ sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE);
+ } else {
+ sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
+ sifdown(f->unit);
+ ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
+ ipcp_hisoptions[f->unit].hisaddr);
+ }
+}
+
+
+/*
+ * ipcp_clear_addrs() - clear the interface addresses, routes,
+ * proxy arp entries, etc.
+ */
+static void
+ipcp_clear_addrs(unit, ouraddr, hisaddr)
+ int unit;
+ u_int32_t ouraddr; /* local address */
+ u_int32_t hisaddr; /* remote address */
+{
+ if (proxy_arp_set[unit]) {
+ cifproxyarp(unit, hisaddr);
+ proxy_arp_set[unit] = 0;
+ }
+ if (default_route_set[unit]) {
+ cifdefaultroute(unit, ouraddr, hisaddr);
+ default_route_set[unit] = 0;
+ }
+ cifaddr(unit, ouraddr, hisaddr);
+}
+
+
+/*
+ * ipcp_finished - possibly shut down the lower layers.
+ */
+static void
+ipcp_finished(f)
+ fsm *f;
+{
+ np_finished(f->unit, PPP_IP);
+}
+
+/*
+ * create_resolv - create the replacement resolv.conf file
+ */
+static void
+create_resolv(peerdns1, peerdns2)
+ u_int32_t peerdns1, peerdns2;
+{
+ /* initialize values */
+ rtems_bsdnet_nameserver_count = 0;
+
+ /* check to see if primary was specified */
+ if ( peerdns1 ) {
+ rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count].s_addr = peerdns1;
+ rtems_bsdnet_nameserver_count++;
+ }
+
+ /* check to see if secondary was specified */
+ if ( peerdns2 ) {
+ rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count].s_addr = peerdns2;
+ rtems_bsdnet_nameserver_count++;
+ }
+
+ /* initialize resolver */
+ __res_init();
+}
+
+/*
+ * ipcp_printpkt - print the contents of an IPCP packet.
+ */
+static char *ipcp_codenames[] = {
+ "ConfReq", "ConfAck", "ConfNak", "ConfRej",
+ "TermReq", "TermAck", "CodeRej"
+};
+
+static int
+ipcp_printpkt(p, plen, printer, arg)
+ u_char *p;
+ int plen;
+ void (*printer) __P((void *, char *, ...));
+ void *arg;
+{
+ int code, id, len, olen;
+ u_char *pstart, *optend;
+ u_short cishort;
+ u_int32_t cilong;
+
+ 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(ipcp_codenames) / sizeof(char *))
+ printer(arg, " %s", ipcp_codenames[code-1]);
+ else
+ printer(arg, " code=0x%x", code);
+ printer(arg, " id=0x%x", id);
+ len -= HEADERLEN;
+ switch (code) {
+ case CONFREQ:
+ case CONFACK:
+ case CONFNAK:
+ case CONFREJ:
+ /* print option list */
+ while (len >= 2) {
+ GETCHAR(code, p);
+ GETCHAR(olen, p);
+ p -= 2;
+ if (olen < 2 || olen > len) {
+ break;
+ }
+ printer(arg, " <");
+ len -= olen;
+ optend = p + olen;
+ switch (code) {
+ case CI_ADDRS:
+ if (olen == CILEN_ADDRS) {
+ p += 2;
+ GETLONG(cilong, p);
+ printer(arg, "addrs %I", htonl(cilong));
+ GETLONG(cilong, p);
+ printer(arg, " %I", htonl(cilong));
+ }
+ break;
+ case CI_COMPRESSTYPE:
+ if (olen >= CILEN_COMPRESS) {
+ p += 2;
+ GETSHORT(cishort, p);
+ printer(arg, "compress ");
+ switch (cishort) {
+ case IPCP_VJ_COMP:
+ printer(arg, "VJ");
+ break;
+ case IPCP_VJ_COMP_OLD:
+ printer(arg, "old-VJ");
+ break;
+ default:
+ printer(arg, "0x%x", cishort);
+ }
+ }
+ break;
+ case CI_ADDR:
+ if (olen == CILEN_ADDR) {
+ p += 2;
+ GETLONG(cilong, p);
+ printer(arg, "addr %I", htonl(cilong));
+ }
+ break;
+ case CI_MS_DNS1:
+ case CI_MS_DNS2:
+ p += 2;
+ GETLONG(cilong, p);
+ printer(arg, "ms-dns%d %I", code - CI_MS_DNS1 + 1,
+ htonl(cilong));
+ break;
+ case CI_MS_WINS1:
+ case CI_MS_WINS2:
+ p += 2;
+ GETLONG(cilong, p);
+ printer(arg, "ms-wins %I", htonl(cilong));
+ break;
+ }
+ while (p < optend) {
+ GETCHAR(code, p);
+ printer(arg, " %.2x", code);
+ }
+ printer(arg, ">");
+ }
+ break;
+
+ case TERMACK:
+ case TERMREQ:
+ if (len > 0 && *p >= ' ' && *p < 0x7f) {
+ printer(arg, " ");
+ print_string(p, len, printer, arg);
+ p += len;
+ len = 0;
+ }
+ break;
+ }
+
+ /* print the rest of the bytes in the packet */
+ for (; len > 0; --len) {
+ GETCHAR(code, p);
+ printer(arg, " %.2x", code);
+ }
+
+ return p - pstart;
+}
+
+/*
+ * ip_active_pkt - see if this IP packet is worth bringing the link up for.
+ * We don't bring the link up for IP fragments or for TCP FIN packets
+ * with no data.
+ */
+#define IP_HDRLEN 20 /* bytes */
+#define IP_OFFMASK 0x1fff
+#define IPPROTO_TCP 6
+#define TCP_HDRLEN 20
+#define TH_FIN 0x01
+
+/*
+ * We use these macros because the IP header may be at an odd address,
+ * and some compilers might use word loads to get th_off or ip_hl.
+ */
+
+#define net_short(x) (((x)[0] << 8) + (x)[1])
+#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF)
+#define get_ipoff(x) net_short((unsigned char *)(x) + 6)
+#define get_ipproto(x) (((unsigned char *)(x))[9])
+#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4)
+#define get_tcpflags(x) (((unsigned char *)(x))[13])
+
+static int
+ip_active_pkt(pkt, len)
+ u_char *pkt;
+ int len;
+{
+ u_char *tcp;
+ int hlen;
+
+ len -= PPP_HDRLEN;
+ pkt += PPP_HDRLEN;
+ if (len < IP_HDRLEN)
+ return 0;
+ if ((get_ipoff(pkt) & IP_OFFMASK) != 0)
+ return 0;
+ if (get_ipproto(pkt) != IPPROTO_TCP)
+ return 1;
+ hlen = get_iphl(pkt) * 4;
+ if (len < hlen + TCP_HDRLEN)
+ return 0;
+ tcp = pkt + hlen;
+ if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)
+ return 0;
+ return 1;
+}
diff --git a/cpukit/pppd/ipcp.h b/cpukit/pppd/ipcp.h
new file mode 100644
index 0000000000..8c5aca861d
--- /dev/null
+++ b/cpukit/pppd/ipcp.h
@@ -0,0 +1,73 @@
+/*
+ * ipcp.h - IP Control Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ *
+ * $Id$
+ */
+
+/*
+ * Options.
+ */
+#define CI_ADDRS 1 /* IP Addresses */
+#define CI_COMPRESSTYPE 2 /* Compression Type */
+#define CI_ADDR 3
+
+#define CI_MS_DNS1 129 /* Primary DNS value */
+#define CI_MS_WINS1 130 /* Primary WINS value */
+#define CI_MS_DNS2 131 /* Secondary DNS value */
+#define CI_MS_WINS2 132 /* Secondary WINS value */
+
+#define MAX_STATES 16 /* from slcompress.h */
+
+#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */
+#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */
+#define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */
+ /* maxslot and slot number compression) */
+
+#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option*/
+#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */
+ /* compression option*/
+
+typedef struct ipcp_options {
+ bool neg_addr; /* Negotiate IP Address? */
+ bool old_addrs; /* Use old (IP-Addresses) option? */
+ bool req_addr; /* Ask peer to send IP address? */
+ bool default_route; /* Assign default route through interface? */
+ bool proxy_arp; /* Make proxy ARP entry for peer? */
+ bool neg_vj; /* Van Jacobson Compression? */
+ bool old_vj; /* use old (short) form of VJ option? */
+ bool accept_local; /* accept peer's value for ouraddr */
+ bool accept_remote; /* accept peer's value for hisaddr */
+ bool req_dns1; /* Ask peer to send primary DNS address? */
+ bool req_dns2; /* Ask peer to send secondary DNS address? */
+ int vj_protocol; /* protocol value to use in VJ option */
+ int maxslotindex; /* values for RFC1332 VJ compression neg. */
+ bool cflag;
+ u_int32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */
+ u_int32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */
+ u_int32_t winsaddr[2]; /* Primary and secondary MS WINS entries */
+} ipcp_options;
+
+extern fsm ipcp_fsm[];
+extern ipcp_options ipcp_wantoptions[];
+extern ipcp_options ipcp_gotoptions[];
+extern ipcp_options ipcp_allowoptions[];
+extern ipcp_options ipcp_hisoptions[];
+
+char *ip_ntoa __P((u_int32_t));
+
+extern struct protent ipcp_protent;
diff --git a/cpukit/pppd/lcp.c b/cpukit/pppd/lcp.c
new file mode 100644
index 0000000000..4308c86026
--- /dev/null
+++ b/cpukit/pppd/lcp.c
@@ -0,0 +1,1953 @@
+/*
+ * lcp.c - PPP Link Control Protocol.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ */
+
+#define RCSID "$Id$";
+
+/*
+ * TODO:
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "pppd.h"
+#include "fsm.h"
+#include "lcp.h"
+#include "chap.h"
+#include "magic.h"
+
+static const char rcsid[] = RCSID;
+
+/*
+ * LCP-related command-line options.
+ */
+static int lcp_echo_interval = 0; /* Interval between LCP echo-requests */
+static int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */
+static bool lax_recv = 0; /* accept control chars in asyncmap */
+
+static int setescape __P((char **));
+
+static option_t lcp_option_list[] = {
+ /* LCP options */
+ { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression,
+ "Disable address/control compression",
+ OPT_A2COPY, &lcp_allowoptions[0].neg_accompression },
+ { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression,
+ "Disable address/control compression",
+ OPT_A2COPY, &lcp_allowoptions[0].neg_accompression },
+ { "default-asyncmap", o_bool, &lcp_wantoptions[0].neg_asyncmap,
+ "Disable asyncmap negotiation",
+ OPT_A2COPY, &lcp_allowoptions[0].neg_asyncmap },
+ { "-am", o_bool, &lcp_wantoptions[0].neg_asyncmap,
+ "Disable asyncmap negotiation",
+ OPT_A2COPY, &lcp_allowoptions[0].neg_asyncmap },
+ { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
+ "Set asyncmap (for received packets)",
+ OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
+ { "-as", o_uint32, &lcp_wantoptions[0].asyncmap,
+ "Set asyncmap (for received packets)",
+ OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
+ { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber,
+ "Disable magic number negotiation (looped-back line detection)",
+ OPT_A2COPY, &lcp_allowoptions[0].neg_magicnumber },
+ { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber,
+ "Disable magic number negotiation (looped-back line detection)",
+ OPT_A2COPY, &lcp_allowoptions[0].neg_magicnumber },
+ { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru,
+ "Disable MRU negotiation (use default 1500)",
+ OPT_A2COPY, &lcp_allowoptions[0].neg_mru },
+ { "-mru", o_bool, &lcp_wantoptions[0].neg_mru,
+ "Disable MRU negotiation (use default 1500)",
+ OPT_A2COPY, &lcp_allowoptions[0].neg_mru },
+ { "mru", o_int, &lcp_wantoptions[0].mru,
+ "Set MRU (maximum received packet size) for negotiation",
+ 0, &lcp_wantoptions[0].neg_mru },
+ { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression,
+ "Disable protocol field compression",
+ OPT_A2COPY, &lcp_allowoptions[0].neg_pcompression },
+ { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression,
+ "Disable protocol field compression",
+ OPT_A2COPY, &lcp_allowoptions[0].neg_pcompression },
+ { "-p", o_bool, &lcp_wantoptions[0].passive,
+ "Set passive mode", 1 },
+ { "passive", o_bool, &lcp_wantoptions[0].passive,
+ "Set passive mode", 1 },
+ { "silent", o_bool, &lcp_wantoptions[0].silent,
+ "Set silent mode", 1 },
+ { "escape", o_special, setescape,
+ "List of character codes to escape on transmission" },
+ { "lcp-echo-failure", o_int, &lcp_echo_fails,
+ "Set number of consecutive echo failures to indicate link failure" },
+ { "lcp-echo-interval", o_int, &lcp_echo_interval,
+ "Set time in seconds between LCP echo requests" },
+ { "lcp-restart", o_int, &lcp_fsm[0].timeouttime,
+ "Set time in seconds between LCP retransmissions" },
+ { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,
+ "Set maximum number of LCP terminate-request transmissions" },
+ { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits,
+ "Set maximum number of LCP configure-request transmissions" },
+ { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops,
+ "Set limit on number of LCP configure-naks" },
+ { "receive-all", o_bool, &lax_recv,
+ "Accept all received control characters", 1 },
+ {NULL}
+};
+
+/* global vars */
+fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/
+lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */
+lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
+lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
+lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
+u_int32_t xmit_accm[NUM_PPP][8]; /* extended transmit ACCM */
+
+static int lcp_echos_pending = 0; /* Number of outstanding echo msgs */
+static int lcp_echo_number = 0; /* ID number of next echo frame */
+static int lcp_echo_timer_running = 0; /* set if a timer is running */
+
+static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */
+
+/*
+ * Callbacks for fsm code. (CI = Configuration Information)
+ */
+static void lcp_resetci __P((fsm *)); /* Reset our CI */
+static int lcp_cilen __P((fsm *)); /* Return length of our CI */
+static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */
+static int lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
+static int lcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */
+static int lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
+static int lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */
+static void lcp_up __P((fsm *)); /* We're UP */
+static void lcp_down __P((fsm *)); /* We're DOWN */
+static void lcp_starting __P((fsm *)); /* We need lower layer up */
+static void lcp_finished __P((fsm *)); /* We need lower layer down */
+static int lcp_extcode __P((fsm *, int, int, u_char *, int));
+static void lcp_rprotrej __P((fsm *, u_char *, int));
+
+/*
+ * routines to send LCP echos to peer
+ */
+
+static void lcp_echo_lowerup __P((int));
+static void lcp_echo_lowerdown __P((int));
+static void LcpEchoTimeout __P((void *));
+static void lcp_received_echo_reply __P((fsm *, int, u_char *, int));
+static void LcpSendEchoRequest __P((fsm *));
+static void LcpLinkFailure __P((fsm *));
+static void LcpEchoCheck __P((fsm *));
+
+static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
+ lcp_resetci, /* Reset our Configuration Information */
+ lcp_cilen, /* Length of our Configuration Information */
+ lcp_addci, /* Add our Configuration Information */
+ lcp_ackci, /* ACK our Configuration Information */
+ lcp_nakci, /* NAK our Configuration Information */
+ lcp_rejci, /* Reject our Configuration Information */
+ lcp_reqci, /* Request peer's Configuration Information */
+ lcp_up, /* Called when fsm reaches OPENED state */
+ lcp_down, /* Called when fsm leaves OPENED state */
+ lcp_starting, /* Called when we want the lower layer up */
+ lcp_finished, /* Called when we want the lower layer down */
+ NULL, /* Called when Protocol-Reject received */
+ NULL, /* Retransmission is necessary */
+ lcp_extcode, /* Called to handle LCP-specific codes */
+ "LCP" /* String name of protocol */
+};
+
+/*
+ * Protocol entry points.
+ * Some of these are called directly.
+ */
+
+static void lcp_init __P((int));
+static void lcp_input __P((int, u_char *, int));
+static void lcp_protrej __P((int));
+static int lcp_printpkt __P((u_char *, int,
+ void (*) __P((void *, char *, ...)), void *));
+
+struct protent lcp_protent = {
+ PPP_LCP,
+ lcp_init,
+ lcp_input,
+ lcp_protrej,
+ lcp_lowerup,
+ lcp_lowerdown,
+ lcp_open,
+ lcp_close,
+ lcp_printpkt,
+ NULL,
+ 1,
+ "LCP",
+ NULL,
+ lcp_option_list,
+ NULL,
+ NULL,
+ NULL
+};
+
+int lcp_loopbackfail = DEFLOOPBACKFAIL;
+
+/*
+ * Length of each type of configuration option (in octets)
+ */
+#define CILEN_VOID 2
+#define CILEN_CHAR 3
+#define CILEN_SHORT 4 /* CILEN_VOID + 2 */
+#define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */
+#define CILEN_LONG 6 /* CILEN_VOID + 4 */
+#define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */
+#define CILEN_CBCP 3
+
+#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
+ (x) == CONFNAK ? "NAK" : "REJ")
+
+
+/*
+ * setescape - add chars to the set we escape on transmission.
+ */
+static int
+setescape(argv)
+ char **argv;
+{
+ int n, ret;
+ char *p, *endp;
+
+ p = *argv;
+ ret = 1;
+ while (*p) {
+ n = strtol(p, &endp, 16);
+ if (p == endp) {
+ option_error("escape parameter contains invalid hex number '%s'",
+ p);
+ return 0;
+ }
+ p = endp;
+ if (n < 0 || n == 0x5E || n > 0xFF) {
+ option_error("can't escape character 0x%x", n);
+ ret = 0;
+ } else
+ xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
+ while (*p == ',' || *p == ' ')
+ ++p;
+ }
+ return ret;
+}
+
+/*
+ * lcp_init - Initialize LCP.
+ */
+static void
+lcp_init(unit)
+ int unit;
+{
+ fsm *f = &lcp_fsm[unit];
+ lcp_options *wo = &lcp_wantoptions[unit];
+ lcp_options *ao = &lcp_allowoptions[unit];
+
+ f->unit = unit;
+ f->protocol = PPP_LCP;
+ f->callbacks = &lcp_callbacks;
+
+ fsm_init(f);
+
+ wo->passive = 0;
+ wo->silent = 0;
+ wo->restart = 0; /* Set to 1 in kernels or multi-line
+ implementations */
+ wo->neg_mru = 1;
+ wo->mru = DEFMRU;
+ wo->neg_asyncmap = 1;
+ wo->asyncmap = 0;
+ wo->neg_chap = 0; /* Set to 1 on server */
+ wo->neg_upap = 0; /* Set to 1 on server */
+ wo->chap_mdtype = CHAP_DIGEST_MD5;
+ wo->neg_magicnumber = 1;
+ wo->neg_pcompression = 1;
+ wo->neg_accompression = 1;
+ wo->neg_lqr = 0; /* no LQR implementation yet */
+ wo->neg_cbcp = 0;
+
+ ao->neg_mru = 1;
+ ao->mru = MAXMRU;
+ ao->neg_asyncmap = 1;
+ ao->asyncmap = 0;
+ ao->neg_chap = 1;
+ ao->chap_mdtype = CHAP_DIGEST_MD5;
+ ao->neg_upap = 1;
+ ao->neg_magicnumber = 1;
+ ao->neg_pcompression = 1;
+ ao->neg_accompression = 1;
+ ao->neg_lqr = 0; /* no LQR implementation yet */
+#ifdef CBCP_SUPPORT
+ ao->neg_cbcp = 1;
+#else
+ ao->neg_cbcp = 0;
+#endif
+
+ memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));
+ xmit_accm[unit][3] = 0x60000000;
+}
+
+
+/*
+ * lcp_open - LCP is allowed to come up.
+ */
+void
+lcp_open(unit)
+ int unit;
+{
+ fsm *f = &lcp_fsm[unit];
+ lcp_options *wo = &lcp_wantoptions[unit];
+
+ f->flags = 0;
+ if (wo->passive)
+ f->flags |= OPT_PASSIVE;
+ if (wo->silent)
+ f->flags |= OPT_SILENT;
+ fsm_open(f);
+}
+
+
+/*
+ * lcp_close - Take LCP down.
+ */
+void
+lcp_close(unit, reason)
+ int unit;
+ char *reason;
+{
+ fsm *f = &lcp_fsm[unit];
+
+ if (pppd_phase != PHASE_DEAD)
+ new_phase(PHASE_TERMINATE);
+ if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
+ /*
+ * This action is not strictly according to the FSM in RFC1548,
+ * but it does mean that the program terminates if you do a
+ * lcp_close() in passive/silent mode when a connection hasn't
+ * been established.
+ */
+ f->state = CLOSED;
+ lcp_finished(f);
+
+ } else
+ fsm_close(&lcp_fsm[unit], reason);
+}
+
+
+/*
+ * lcp_lowerup - The lower layer is up.
+ */
+void
+lcp_lowerup(unit)
+ int unit;
+{
+ lcp_options *wo = &lcp_wantoptions[unit];
+
+ /*
+ * Don't use A/C or protocol compression on transmission,
+ * but accept A/C and protocol compressed packets
+ * if we are going to ask for A/C and protocol compression.
+ */
+ ppp_set_xaccm(unit, xmit_accm[unit]);
+ ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0);
+ ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
+ wo->neg_pcompression, wo->neg_accompression);
+ peer_mru[unit] = PPP_MRU;
+ lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0];
+
+ fsm_lowerup(&lcp_fsm[unit]);
+}
+
+
+/*
+ * lcp_lowerdown - The lower layer is down.
+ */
+void
+lcp_lowerdown(unit)
+ int unit;
+{
+ fsm_lowerdown(&lcp_fsm[unit]);
+}
+
+
+/*
+ * lcp_input - Input LCP packet.
+ */
+static void
+lcp_input(unit, p, len)
+ int unit;
+ u_char *p;
+ int len;
+{
+ fsm *f = &lcp_fsm[unit];
+
+ fsm_input(f, p, len);
+}
+
+
+/*
+ * lcp_extcode - Handle a LCP-specific code.
+ */
+static int
+lcp_extcode(f, code, id, inp, len)
+ fsm *f;
+ int code, id;
+ u_char *inp;
+ int len;
+{
+ u_char *magp;
+
+ switch( code ){
+ case PROTREJ:
+ lcp_rprotrej(f, inp, len);
+ break;
+
+ case ECHOREQ:
+ if (f->state != OPENED)
+ break;
+ magp = inp;
+ PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
+ fsm_sdata(f, ECHOREP, id, inp, len);
+ break;
+
+ case ECHOREP:
+ lcp_received_echo_reply(f, id, inp, len);
+ break;
+
+ case DISCREQ:
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+
+/*
+ * lcp_rprotrej - Receive an Protocol-Reject.
+ *
+ * Figure out which protocol is rejected and inform it.
+ */
+static void
+lcp_rprotrej(f, inp, len)
+ fsm *f;
+ u_char *inp;
+ int len;
+{
+ int i;
+ struct protent *protp;
+ u_short prot;
+
+ if (len < 2) {
+ LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
+ return;
+ }
+
+ GETSHORT(prot, inp);
+
+ /*
+ * Protocol-Reject packets received in any state other than the LCP
+ * OPENED state SHOULD be silently discarded.
+ */
+ if( f->state != OPENED ){
+ LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state));
+ return;
+ }
+
+ /*
+ * Upcall the proper Protocol-Reject routine.
+ */
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (protp->protocol == prot && protp->enabled_flag) {
+ (*protp->protrej)(f->unit);
+ return;
+ }
+
+ warn("Protocol-Reject for unsupported protocol 0x%x", prot);
+}
+
+
+/*
+ * lcp_protrej - A Protocol-Reject was received.
+ */
+/*ARGSUSED*/
+static void
+lcp_protrej(unit)
+ int unit;
+{
+ /*
+ * Can't reject LCP!
+ */
+ error("Received Protocol-Reject for LCP!");
+ fsm_protreject(&lcp_fsm[unit]);
+}
+
+
+/*
+ * lcp_sprotrej - Send a Protocol-Reject for some protocol.
+ */
+void
+lcp_sprotrej(unit, p, len)
+ int unit;
+ u_char *p;
+ int len;
+{
+ /*
+ * Send back the protocol and the information field of the
+ * rejected packet. We only get here if LCP is in the OPENED state.
+ */
+ p += 2;
+ len -= 2;
+
+ fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
+ p, len);
+}
+
+
+/*
+ * lcp_resetci - Reset our CI.
+ */
+static void
+lcp_resetci(f)
+ fsm *f;
+{
+ lcp_wantoptions[f->unit].magicnumber = magic();
+ lcp_wantoptions[f->unit].numloops = 0;
+ lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
+ peer_mru[f->unit] = PPP_MRU;
+ auth_reset(f->unit);
+}
+
+
+/*
+ * lcp_cilen - Return length of our CI.
+ */
+static int
+lcp_cilen(f)
+ fsm *f;
+{
+ lcp_options *go = &lcp_gotoptions[f->unit];
+
+#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0)
+#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0)
+#define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0)
+#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0)
+#define LENCILQR(neg) ((neg) ? CILEN_LQR: 0)
+#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0)
+ /*
+ * NB: we only ask for one of CHAP and UPAP, even if we will
+ * accept either.
+ */
+ return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) +
+ LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
+ LENCICHAP(go->neg_chap) +
+ LENCISHORT(!go->neg_chap && go->neg_upap) +
+ LENCILQR(go->neg_lqr) +
+ LENCICBCP(go->neg_cbcp) +
+ LENCILONG(go->neg_magicnumber) +
+ LENCIVOID(go->neg_pcompression) +
+ LENCIVOID(go->neg_accompression));
+}
+
+
+/*
+ * lcp_addci - Add our desired CIs to a packet.
+ */
+static void
+lcp_addci(f, ucp, lenp)
+ fsm *f;
+ u_char *ucp;
+ int *lenp;
+{
+ lcp_options *go = &lcp_gotoptions[f->unit];
+ u_char *start_ucp = ucp;
+
+#define ADDCIVOID(opt, neg) \
+ if (neg) { \
+ PUTCHAR(opt, ucp); \
+ PUTCHAR(CILEN_VOID, ucp); \
+ }
+#define ADDCISHORT(opt, neg, val) \
+ if (neg) { \
+ PUTCHAR(opt, ucp); \
+ PUTCHAR(CILEN_SHORT, ucp); \
+ PUTSHORT(val, ucp); \
+ }
+#define ADDCICHAP(opt, neg, val, digest) \
+ if (neg) { \
+ PUTCHAR(opt, ucp); \
+ PUTCHAR(CILEN_CHAP, ucp); \
+ PUTSHORT(val, ucp); \
+ PUTCHAR(digest, ucp); \
+ }
+#define ADDCILONG(opt, neg, val) \
+ if (neg) { \
+ PUTCHAR(opt, ucp); \
+ PUTCHAR(CILEN_LONG, ucp); \
+ PUTLONG(val, ucp); \
+ }
+#define ADDCILQR(opt, neg, val) \
+ if (neg) { \
+ PUTCHAR(opt, ucp); \
+ PUTCHAR(CILEN_LQR, ucp); \
+ PUTSHORT(PPP_LQR, ucp); \
+ PUTLONG(val, ucp); \
+ }
+#define ADDCICHAR(opt, neg, val) \
+ if (neg) { \
+ PUTCHAR(opt, ucp); \
+ PUTCHAR(CILEN_CHAR, ucp); \
+ PUTCHAR(val, ucp); \
+ }
+
+ ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
+ ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
+ go->asyncmap);
+ ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
+ ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
+ ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
+ ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
+ ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
+ ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
+ ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
+
+ if (ucp - start_ucp != *lenp) {
+ /* this should never happen, because peer_mtu should be 1500 */
+ error("Bug in lcp_addci: wrong length");
+ }
+}
+
+
+/*
+ * lcp_ackci - Ack our CIs.
+ * This should not modify any state if the Ack is bad.
+ *
+ * Returns:
+ * 0 - Ack was bad.
+ * 1 - Ack was good.
+ */
+static int
+lcp_ackci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ lcp_options *go = &lcp_gotoptions[f->unit];
+ u_char cilen, citype, cichar;
+ u_short cishort;
+ u_int32_t cilong;
+
+ /*
+ * CIs must be in exactly the same order that we sent.
+ * Check packet length and CI length at each step.
+ * If we find any deviations, then this packet is bad.
+ */
+#define ACKCIVOID(opt, neg) \
+ if (neg) { \
+ if ((len -= CILEN_VOID) < 0) \
+ goto bad; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_VOID || \
+ citype != opt) \
+ goto bad; \
+ }
+#define ACKCISHORT(opt, neg, val) \
+ if (neg) { \
+ if ((len -= CILEN_SHORT) < 0) \
+ goto bad; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_SHORT || \
+ citype != opt) \
+ goto bad; \
+ GETSHORT(cishort, p); \
+ if (cishort != val) \
+ goto bad; \
+ }
+#define ACKCICHAR(opt, neg, val) \
+ if (neg) { \
+ if ((len -= CILEN_CHAR) < 0) \
+ goto bad; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_CHAR || \
+ citype != opt) \
+ goto bad; \
+ GETCHAR(cichar, p); \
+ if (cichar != val) \
+ goto bad; \
+ }
+#define ACKCICHAP(opt, neg, val, digest) \
+ if (neg) { \
+ if ((len -= CILEN_CHAP) < 0) \
+ goto bad; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_CHAP || \
+ citype != opt) \
+ goto bad; \
+ GETSHORT(cishort, p); \
+ if (cishort != val) \
+ goto bad; \
+ GETCHAR(cichar, p); \
+ if (cichar != digest) \
+ goto bad; \
+ }
+#define ACKCILONG(opt, neg, val) \
+ if (neg) { \
+ if ((len -= CILEN_LONG) < 0) \
+ goto bad; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_LONG || \
+ citype != opt) \
+ goto bad; \
+ GETLONG(cilong, p); \
+ if (cilong != val) \
+ goto bad; \
+ }
+#define ACKCILQR(opt, neg, val) \
+ if (neg) { \
+ if ((len -= CILEN_LQR) < 0) \
+ goto bad; \
+ GETCHAR(citype, p); \
+ GETCHAR(cilen, p); \
+ if (cilen != CILEN_LQR || \
+ citype != opt) \
+ goto bad; \
+ GETSHORT(cishort, p); \
+ if (cishort != PPP_LQR) \
+ goto bad; \
+ GETLONG(cilong, p); \
+ if (cilong != val) \
+ goto bad; \
+ }
+
+ ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
+ ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
+ go->asyncmap);
+ ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
+ ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
+ ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
+ ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
+ ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
+ ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
+ ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
+
+ /*
+ * If there are any remaining CIs, then this packet is bad.
+ */
+ if (len != 0)
+ goto bad;
+ return (1);
+bad:
+ LCPDEBUG(("lcp_acki: received bad Ack!"));
+ return (0);
+}
+
+
+/*
+ * lcp_nakci - Peer has sent a NAK for some of our CIs.
+ * This should not modify any state if the Nak is bad
+ * or if LCP is in the OPENED state.
+ *
+ * Returns:
+ * 0 - Nak was bad.
+ * 1 - Nak was good.
+ */
+static int
+lcp_nakci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ lcp_options *go = &lcp_gotoptions[f->unit];
+ lcp_options *wo = &lcp_wantoptions[f->unit];
+ u_char citype, cichar, *next;
+ u_short cishort;
+ u_int32_t cilong;
+ lcp_options no; /* options we've seen Naks for */
+ lcp_options try; /* options to request next time */
+ int looped_back = 0;
+ int cilen;
+
+ BZERO(&no, sizeof(no));
+ try = *go;
+
+ /*
+ * Any Nak'd CIs must be in exactly the same order that we sent.
+ * Check packet length and CI length at each step.
+ * If we find any deviations, then this packet is bad.
+ */
+#define NAKCIVOID(opt, neg, code) \
+ if (go->neg && \
+ len >= CILEN_VOID && \
+ p[1] == CILEN_VOID && \
+ p[0] == opt) { \
+ len -= CILEN_VOID; \
+ INCPTR(CILEN_VOID, p); \
+ no.neg = 1; \
+ code \
+ }
+#define NAKCICHAP(opt, neg, code) \
+ if (go->neg && \
+ len >= CILEN_CHAP && \
+ p[1] == CILEN_CHAP && \
+ p[0] == opt) { \
+ len -= CILEN_CHAP; \
+ INCPTR(2, p); \
+ GETSHORT(cishort, p); \
+ GETCHAR(cichar, p); \
+ no.neg = 1; \
+ code \
+ }
+#define NAKCICHAR(opt, neg, code) \
+ if (go->neg && \
+ len >= CILEN_CHAR && \
+ p[1] == CILEN_CHAR && \
+ p[0] == opt) { \
+ len -= CILEN_CHAR; \
+ INCPTR(2, p); \
+ GETCHAR(cichar, p); \
+ no.neg = 1; \
+ code \
+ }
+#define NAKCISHORT(opt, neg, code) \
+ if (go->neg && \
+ len >= CILEN_SHORT && \
+ p[1] == CILEN_SHORT && \
+ p[0] == opt) { \
+ len -= CILEN_SHORT; \
+ INCPTR(2, p); \
+ GETSHORT(cishort, p); \
+ no.neg = 1; \
+ code \
+ }
+#define NAKCILONG(opt, neg, code) \
+ if (go->neg && \
+ len >= CILEN_LONG && \
+ p[1] == CILEN_LONG && \
+ p[0] == opt) { \
+ len -= CILEN_LONG; \
+ INCPTR(2, p); \
+ GETLONG(cilong, p); \
+ no.neg = 1; \
+ code \
+ }
+#define NAKCILQR(opt, neg, code) \
+ if (go->neg && \
+ len >= CILEN_LQR && \
+ p[1] == CILEN_LQR && \
+ p[0] == opt) { \
+ len -= CILEN_LQR; \
+ INCPTR(2, p); \
+ GETSHORT(cishort, p); \
+ GETLONG(cilong, p); \
+ no.neg = 1; \
+ code \
+ }
+
+ /*
+ * We don't care if they want to send us smaller packets than
+ * we want. Therefore, accept any MRU less than what we asked for,
+ * but then ignore the new value when setting the MRU in the kernel.
+ * If they send us a bigger MRU than what we asked, accept it, up to
+ * the limit of the default MRU we'd get if we didn't negotiate.
+ */
+ if (go->neg_mru && go->mru != DEFMRU) {
+ NAKCISHORT(CI_MRU, neg_mru,
+ if (cishort <= wo->mru || cishort <= DEFMRU)
+ try.mru = cishort;
+ );
+ }
+
+ /*
+ * Add any characters they want to our (receive-side) asyncmap.
+ */
+ if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) {
+ NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
+ try.asyncmap = go->asyncmap | cilong;
+ );
+ }
+
+ /*
+ * If they've nak'd our authentication-protocol, check whether
+ * they are proposing a different protocol, or a different
+ * hash algorithm for CHAP.
+ */
+ if ((go->neg_chap || go->neg_upap)
+ && len >= CILEN_SHORT
+ && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
+ cilen = p[1];
+ len -= cilen;
+ no.neg_chap = go->neg_chap;
+ no.neg_upap = go->neg_upap;
+ INCPTR(2, p);
+ GETSHORT(cishort, p);
+ if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
+ /*
+ * If we were asking for CHAP, they obviously don't want to do it.
+ * If we weren't asking for CHAP, then we were asking for PAP,
+ * in which case this Nak is bad.
+ */
+ if (!go->neg_chap)
+ goto bad;
+ try.neg_chap = 0;
+
+ } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
+ GETCHAR(cichar, p);
+ if (go->neg_chap) {
+ /*
+ * We were asking for CHAP/MD5; they must want a different
+ * algorithm. If they can't do MD5, we can ask for M$-CHAP
+ * if we support it, otherwise we'll have to stop
+ * asking for CHAP.
+ */
+ if (cichar != go->chap_mdtype) {
+#ifdef CHAPMS
+ if (cichar == CHAP_MICROSOFT)
+ go->chap_mdtype = CHAP_MICROSOFT;
+ else
+#endif /* CHAPMS */
+ try.neg_chap = 0;
+ }
+ } else {
+ /*
+ * Stop asking for PAP if we were asking for it.
+ */
+ try.neg_upap = 0;
+ }
+
+ } else {
+ /*
+ * We don't recognize what they're suggesting.
+ * Stop asking for what we were asking for.
+ */
+ if (go->neg_chap)
+ try.neg_chap = 0;
+ else
+ try.neg_upap = 0;
+ p += cilen - CILEN_SHORT;
+ }
+ }
+
+ /*
+ * If they can't cope with our link quality protocol, we'll have
+ * to stop asking for LQR. We haven't got any other protocol.
+ * If they Nak the reporting period, take their value XXX ?
+ */
+ NAKCILQR(CI_QUALITY, neg_lqr,
+ if (cishort != PPP_LQR)
+ try.neg_lqr = 0;
+ else
+ try.lqr_period = cilong;
+ );
+
+ /*
+ * Only implementing CBCP...not the rest of the callback options
+ */
+ NAKCICHAR(CI_CALLBACK, neg_cbcp,
+ try.neg_cbcp = 0;
+ );
+
+ /*
+ * Check for a looped-back line.
+ */
+ NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
+ try.magicnumber = magic();
+ looped_back = 1;
+ );
+
+ /*
+ * Peer shouldn't send Nak for protocol compression or
+ * address/control compression requests; they should send
+ * a Reject instead. If they send a Nak, treat it as a Reject.
+ */
+ NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,
+ try.neg_pcompression = 0;
+ );
+ NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,
+ try.neg_accompression = 0;
+ );
+
+ /*
+ * There may be remaining CIs, if the peer is requesting negotiation
+ * on an option that we didn't include in our request packet.
+ * If we see an option that we requested, or one we've already seen
+ * in this packet, then this packet is bad.
+ * If we wanted to respond by starting to negotiate on the requested
+ * option(s), we could, but we don't, because except for the
+ * authentication type and quality protocol, if we are not negotiating
+ * an option, it is because we were told not to.
+ * For the authentication type, the Nak from the peer means
+ * `let me authenticate myself with you' which is a bit pointless.
+ * For the quality protocol, the Nak means `ask me to send you quality
+ * reports', but if we didn't ask for them, we don't want them.
+ * An option we don't recognize represents the peer asking to
+ * negotiate some option we don't support, so ignore it.
+ */
+ while (len > CILEN_VOID) {
+ GETCHAR(citype, p);
+ GETCHAR(cilen, p);
+ if (cilen < CILEN_VOID || (len -= cilen) < 0)
+ goto bad;
+ next = p + cilen - 2;
+
+ switch (citype) {
+ case CI_MRU:
+ if ((go->neg_mru && go->mru != DEFMRU)
+ || no.neg_mru || cilen != CILEN_SHORT)
+ goto bad;
+ GETSHORT(cishort, p);
+ if (cishort < DEFMRU)
+ try.mru = cishort;
+ break;
+ case CI_ASYNCMAP:
+ if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF)
+ || no.neg_asyncmap || cilen != CILEN_LONG)
+ goto bad;
+ break;
+ case CI_AUTHTYPE:
+ if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap)
+ goto bad;
+ break;
+ case CI_MAGICNUMBER:
+ if (go->neg_magicnumber || no.neg_magicnumber ||
+ cilen != CILEN_LONG)
+ goto bad;
+ break;
+ case CI_PCOMPRESSION:
+ if (go->neg_pcompression || no.neg_pcompression
+ || cilen != CILEN_VOID)
+ goto bad;
+ break;
+ case CI_ACCOMPRESSION:
+ if (go->neg_accompression || no.neg_accompression
+ || cilen != CILEN_VOID)
+ goto bad;
+ break;
+ case CI_QUALITY:
+ if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
+ goto bad;
+ break;
+ }
+ p = next;
+ }
+
+ /*
+ * OK, the Nak is good. Now we can update state.
+ * If there are any options left we ignore them.
+ */
+ if (f->state != OPENED) {
+ if (looped_back) {
+ if (++try.numloops >= lcp_loopbackfail) {
+ notice("Serial line is looped back.");
+ lcp_close(f->unit, "Loopback detected");
+ pppd_status = EXIT_LOOPBACK;
+ }
+ } else
+ try.numloops = 0;
+ *go = try;
+ }
+
+ return 1;
+
+bad:
+ LCPDEBUG(("lcp_nakci: received bad Nak!"));
+ return 0;
+}
+
+
+/*
+ * lcp_rejci - Peer has Rejected some of our CIs.
+ * This should not modify any state if the Reject is bad
+ * or if LCP is in the OPENED state.
+ *
+ * Returns:
+ * 0 - Reject was bad.
+ * 1 - Reject was good.
+ */
+static int
+lcp_rejci(f, p, len)
+ fsm *f;
+ u_char *p;
+ int len;
+{
+ lcp_options *go = &lcp_gotoptions[f->unit];
+ u_char cichar;
+ u_short cishort;
+ u_int32_t cilong;
+ lcp_options try; /* options to request next time */
+
+ try = *go;
+
+ /*
+ * Any Rejected CIs must be in exactly the same order that we sent.
+ * Check packet length and CI length at each step.
+ * If we find any deviations, then this packet is bad.
+ */
+#define REJCIVOID(opt, neg) \
+ if (go->neg && \
+ len >= CILEN_VOID && \
+ p[1] == CILEN_VOID && \
+ p[0] == opt) { \
+ len -= CILEN_VOID; \
+ INCPTR(CILEN_VOID, p); \
+ try.neg = 0; \
+ }
+#define REJCISHORT(opt, neg, val) \
+ if (go->neg && \
+ len >= CILEN_SHORT && \
+ p[1] == CILEN_SHORT && \
+ p[0] == opt) { \
+ len -= CILEN_SHORT; \
+ INCPTR(2, p); \
+ GETSHORT(cishort, p); \
+ /* Check rejected value. */ \
+ if (cishort != val) \
+ goto bad; \
+ try.neg = 0; \
+ }
+#define REJCICHAP(opt, neg, val, digest) \
+ if (go->neg && \
+ len >= CILEN_CHAP && \
+ p[1] == CILEN_CHAP && \
+ p[0] == opt) { \
+ len -= CILEN_CHAP; \
+ INCPTR(2, p); \
+ GETSHORT(cishort, p); \
+ GETCHAR(cichar, p); \
+ /* Check rejected value. */ \
+ if (cishort != val || cichar != digest) \
+ goto bad; \
+ try.neg = 0; \
+ try.neg_upap = 0; \
+ }
+#define REJCILONG(opt, neg, val) \
+ if (go->neg && \
+ len >= CILEN_LONG && \
+ p[1] == CILEN_LONG && \
+ p[0] == opt) { \
+ len -= CILEN_LONG; \
+ INCPTR(2, p); \
+ GETLONG(cilong, p); \
+ /* Check rejected value. */ \
+ if (cilong != val) \
+ goto bad; \
+ try.neg = 0; \
+ }
+#define REJCILQR(opt, neg, val) \
+ if (go->neg && \
+ len >= CILEN_LQR && \
+ p[1] == CILEN_LQR && \
+ p[0] == opt) { \
+ len -= CILEN_LQR; \
+ INCPTR(2, p); \
+ GETSHORT(cishort, p); \
+ GETLONG(cilong, p); \
+ /* Check rejected value. */ \
+ if (cishort != PPP_LQR || cilong != val) \
+ goto bad; \
+ try.neg = 0; \
+ }
+#define REJCICBCP(opt, neg, val) \
+ if (go->neg && \
+ len >= CILEN_CBCP && \
+ p[1] == CILEN_CBCP && \
+ p[0] == opt) { \
+ len -= CILEN_CBCP; \
+ INCPTR(2, p); \
+ GETCHAR(cichar, p); \
+ /* Check rejected value. */ \
+ if (cichar != val) \
+ goto bad; \
+ try.neg = 0; \
+ }
+
+ REJCISHORT(CI_MRU, neg_mru, go->mru);
+ REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
+ REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);
+ if (!go->neg_chap) {
+ REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
+ }
+ REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
+ REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
+ REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
+ REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
+ REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
+
+ /*
+ * If there are any remaining CIs, then this packet is bad.
+ */
+ if (len != 0)
+ goto bad;
+ /*
+ * Now we can update state.
+ */
+ if (f->state != OPENED)
+ *go = try;
+ return 1;
+
+bad:
+ LCPDEBUG(("lcp_rejci: received bad Reject!"));
+ return 0;
+}
+
+
+/*
+ * lcp_reqci - Check the peer's requested CIs and send appropriate response.
+ *
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
+ * appropriately. If reject_if_disagree is non-zero, doesn't return
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.
+ */
+static int
+lcp_reqci(f, inp, lenp, reject_if_disagree)
+ fsm *f;
+ u_char *inp; /* Requested CIs */
+ int *lenp; /* Length of requested CIs */
+ int reject_if_disagree;
+{
+ lcp_options *go = &lcp_gotoptions[f->unit];
+ lcp_options *ho = &lcp_hisoptions[f->unit];
+ lcp_options *ao = &lcp_allowoptions[f->unit];
+ u_char *cip, *next; /* Pointer to current and next CIs */
+ int cilen, citype, cichar; /* Parsed len, type, char value */
+ u_short cishort; /* Parsed short value */
+ u_int32_t cilong; /* Parse long value */
+ int rc = CONFACK; /* Final packet return code */
+ int orc; /* Individual option return code */
+ u_char *p; /* Pointer to next char to parse */
+ u_char *rejp; /* Pointer to next char in reject frame */
+ u_char *nakp; /* Pointer to next char in Nak frame */
+ int l = *lenp; /* Length left */
+
+ /*
+ * Reset all his options.
+ */
+ BZERO(ho, sizeof(*ho));
+
+ /*
+ * Process all his options.
+ */
+ next = inp;
+ nakp = nak_buffer;
+ rejp = inp;
+ while (l) {
+ orc = CONFACK; /* Assume success */
+ cip = p = next; /* Remember begining of CI */
+ if (l < 2 || /* Not enough data for CI header or */
+ p[1] < 2 || /* CI length too small or */
+ p[1] > l) { /* CI length too big? */
+ LCPDEBUG(("lcp_reqci: bad CI length!"));
+ orc = CONFREJ; /* Reject bad CI */
+ cilen = l; /* Reject till end of packet */
+ l = 0; /* Don't loop again */
+ citype = 0;
+ goto endswitch;
+ }
+ GETCHAR(citype, p); /* Parse CI type */
+ GETCHAR(cilen, p); /* Parse CI length */
+ l -= cilen; /* Adjust remaining length */
+ next += cilen; /* Step to next CI */
+
+ switch (citype) { /* Check CI type */
+ case CI_MRU:
+ if (!ao->neg_mru || /* Allow option? */
+ cilen != CILEN_SHORT) { /* Check CI length */
+ orc = CONFREJ; /* Reject CI */
+ break;
+ }
+ GETSHORT(cishort, p); /* Parse MRU */
+
+ /*
+ * He must be able to receive at least our minimum.
+ * No need to check a maximum. If he sends a large number,
+ * we'll just ignore it.
+ */
+ if (cishort < MINMRU) {
+ orc = CONFNAK; /* Nak CI */
+ PUTCHAR(CI_MRU, nakp);
+ PUTCHAR(CILEN_SHORT, nakp);
+ PUTSHORT(MINMRU, nakp); /* Give him a hint */
+ break;
+ }
+ ho->neg_mru = 1; /* Remember he sent MRU */
+ ho->mru = cishort; /* And remember value */
+ break;
+
+ case CI_ASYNCMAP:
+ if (!ao->neg_asyncmap ||
+ cilen != CILEN_LONG) {
+ orc = CONFREJ;
+ break;
+ }
+ GETLONG(cilong, p);
+
+ /*
+ * Asyncmap must have set at least the bits
+ * which are set in lcp_allowoptions[unit].asyncmap.
+ */
+ if ((ao->asyncmap & ~cilong) != 0) {
+ orc = CONFNAK;
+ PUTCHAR(CI_ASYNCMAP, nakp);
+ PUTCHAR(CILEN_LONG, nakp);
+ PUTLONG(ao->asyncmap | cilong, nakp);
+ break;
+ }
+ ho->neg_asyncmap = 1;
+ ho->asyncmap = cilong;
+ break;
+
+ case CI_AUTHTYPE:
+ if (cilen < CILEN_SHORT ||
+ !(ao->neg_upap || ao->neg_chap)) {
+ /*
+ * Reject the option if we're not willing to authenticate.
+ */
+ orc = CONFREJ;
+ break;
+ }
+ GETSHORT(cishort, p);
+
+ /*
+ * Authtype must be PAP or CHAP.
+ *
+ * Note: if both ao->neg_upap and ao->neg_chap are set,
+ * and the peer sends a Configure-Request with two
+ * authenticate-protocol requests, one for CHAP and one
+ * for UPAP, then we will reject the second request.
+ * Whether we end up doing CHAP or UPAP depends then on
+ * the ordering of the CIs in the peer's Configure-Request.
+ */
+
+ if (cishort == PPP_PAP) {
+ if (ho->neg_chap || /* we've already accepted CHAP */
+ cilen != CILEN_SHORT) {
+ LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
+ orc = CONFREJ;
+ break;
+ }
+ if (!ao->neg_upap) { /* we don't want to do PAP */
+ orc = CONFNAK; /* NAK it and suggest CHAP */
+ PUTCHAR(CI_AUTHTYPE, nakp);
+ PUTCHAR(CILEN_CHAP, nakp);
+ PUTSHORT(PPP_CHAP, nakp);
+ PUTCHAR(ao->chap_mdtype, nakp);
+ /* XXX if we can do CHAP_MICROSOFT as well, we should
+ probably put in another option saying so */
+ break;
+ }
+ ho->neg_upap = 1;
+ break;
+ }
+ if (cishort == PPP_CHAP) {
+ if (ho->neg_upap || /* we've already accepted PAP */
+ cilen != CILEN_CHAP) {
+ LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
+ orc = CONFREJ;
+ break;
+ }
+ if (!ao->neg_chap) { /* we don't want to do CHAP */
+ orc = CONFNAK; /* NAK it and suggest PAP */
+ PUTCHAR(CI_AUTHTYPE, nakp);
+ PUTCHAR(CILEN_SHORT, nakp);
+ PUTSHORT(PPP_PAP, nakp);
+ break;
+ }
+ GETCHAR(cichar, p); /* get digest type*/
+ if (cichar != CHAP_DIGEST_MD5
+#ifdef CHAPMS
+ && cichar != CHAP_MICROSOFT
+#endif
+ ) {
+ orc = CONFNAK;
+ PUTCHAR(CI_AUTHTYPE, nakp);
+ PUTCHAR(CILEN_CHAP, nakp);
+ PUTSHORT(PPP_CHAP, nakp);
+ PUTCHAR(ao->chap_mdtype, nakp);
+ break;
+ }
+ ho->chap_mdtype = cichar; /* save md type */
+ ho->neg_chap = 1;
+ break;
+ }
+
+ /*
+ * We don't recognize the protocol they're asking for.
+ * Nak it with something we're willing to do.
+ * (At this point we know ao->neg_upap || ao->neg_chap.)
+ */
+ orc = CONFNAK;
+ PUTCHAR(CI_AUTHTYPE, nakp);
+ if (ao->neg_chap) {
+ PUTCHAR(CILEN_CHAP, nakp);
+ PUTSHORT(PPP_CHAP, nakp);
+ PUTCHAR(ao->chap_mdtype, nakp);
+ } else {
+ PUTCHAR(CILEN_SHORT, nakp);
+ PUTSHORT(PPP_PAP, nakp);
+ }
+ break;
+
+ case CI_QUALITY:
+ if (!ao->neg_lqr ||
+ cilen != CILEN_LQR) {
+ orc = CONFREJ;
+ break;
+ }
+
+ GETSHORT(cishort, p);
+ GETLONG(cilong, p);
+
+ /*
+ * Check the protocol and the reporting period.
+ * XXX When should we Nak this, and what with?
+ */
+ if (cishort != PPP_LQR) {
+ orc = CONFNAK;
+ PUTCHAR(CI_QUALITY, nakp);
+ PUTCHAR(CILEN_LQR, nakp);
+ PUTSHORT(PPP_LQR, nakp);
+ PUTLONG(ao->lqr_period, nakp);
+ break;
+ }
+ break;
+
+ case CI_MAGICNUMBER:
+ if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
+ cilen != CILEN_LONG) {
+ orc = CONFREJ;
+ break;
+ }
+ GETLONG(cilong, p);
+
+ /*
+ * He must have a different magic number.
+ */
+ if (go->neg_magicnumber &&
+ cilong == go->magicnumber) {
+ cilong = magic(); /* Don't put magic() inside macro! */
+ orc = CONFNAK;
+ PUTCHAR(CI_MAGICNUMBER, nakp);
+ PUTCHAR(CILEN_LONG, nakp);
+ PUTLONG(cilong, nakp);
+ break;
+ }
+ ho->neg_magicnumber = 1;
+ ho->magicnumber = cilong;
+ break;
+
+
+ case CI_PCOMPRESSION:
+ if (!ao->neg_pcompression ||
+ cilen != CILEN_VOID) {
+ orc = CONFREJ;
+ break;
+ }
+ ho->neg_pcompression = 1;
+ break;
+
+ case CI_ACCOMPRESSION:
+ if (!ao->neg_accompression ||
+ cilen != CILEN_VOID) {
+ orc = CONFREJ;
+ break;
+ }
+ ho->neg_accompression = 1;
+ break;
+
+ default:
+ LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype));
+ orc = CONFREJ;
+ break;
+ }
+
+endswitch:
+ if (orc == CONFACK && /* Good CI */
+ rc != CONFACK) /* but prior CI wasnt? */
+ continue; /* Don't send this one */
+
+ if (orc == CONFNAK) { /* Nak this CI? */
+ if (reject_if_disagree /* Getting fed up with sending NAKs? */
+ && citype != CI_MAGICNUMBER) {
+ orc = CONFREJ; /* Get tough if so */
+ } else {
+ if (rc == CONFREJ) /* Rejecting prior CI? */
+ continue; /* Don't send this one */
+ rc = CONFNAK;
+ }
+ }
+ if (orc == CONFREJ) { /* Reject this CI */
+ rc = CONFREJ;
+ if (cip != rejp) /* Need to move rejected CI? */
+ BCOPY(cip, rejp, cilen); /* Move it */
+ INCPTR(cilen, rejp); /* Update output pointer */
+ }
+ }
+
+ /*
+ * If we wanted to send additional NAKs (for unsent CIs), the
+ * code would go here. The extra NAKs would go at *nakp.
+ * At present there are no cases where we want to ask the
+ * peer to negotiate an option.
+ */
+
+ switch (rc) {
+ case CONFACK:
+ *lenp = next - inp;
+ break;
+ case CONFNAK:
+ /*
+ * Copy the Nak'd options from the nak_buffer to the caller's buffer.
+ */
+ *lenp = nakp - nak_buffer;
+ BCOPY(nak_buffer, inp, *lenp);
+ break;
+ case CONFREJ:
+ *lenp = rejp - inp;
+ break;
+ }
+
+ LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc)));
+ return (rc); /* Return final code */
+}
+
+
+/*
+ * lcp_up - LCP has come UP.
+ */
+static void
+lcp_up(f)
+ fsm *f;
+{
+ lcp_options *wo = &lcp_wantoptions[f->unit];
+ lcp_options *ho = &lcp_hisoptions[f->unit];
+ lcp_options *go = &lcp_gotoptions[f->unit];
+ lcp_options *ao = &lcp_allowoptions[f->unit];
+
+ if (!go->neg_magicnumber)
+ go->magicnumber = 0;
+ if (!ho->neg_magicnumber)
+ ho->magicnumber = 0;
+
+ /*
+ * Set our MTU to the smaller of the MTU we wanted and
+ * the MRU our peer wanted. If we negotiated an MRU,
+ * set our MRU to the larger of value we wanted and
+ * the value we got in the negotiation.
+ */
+ ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
+ (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
+ ho->neg_pcompression, ho->neg_accompression);
+ ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU),
+ (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff),
+ go->neg_pcompression, go->neg_accompression);
+
+ if (ho->neg_mru)
+ peer_mru[f->unit] = ho->mru;
+
+ lcp_echo_lowerup(f->unit); /* Enable echo messages */
+
+ link_established(f->unit);
+}
+
+
+/*
+ * lcp_down - LCP has gone DOWN.
+ *
+ * Alert other protocols.
+ */
+static void
+lcp_down(f)
+ fsm *f;
+{
+ lcp_options *go = &lcp_gotoptions[f->unit];
+
+ lcp_echo_lowerdown(f->unit);
+
+ link_down(f->unit);
+
+ ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0);
+ ppp_recv_config(f->unit, PPP_MRU,
+ (go->neg_asyncmap? go->asyncmap: 0xffffffff),
+ go->neg_pcompression, go->neg_accompression);
+ peer_mru[f->unit] = PPP_MRU;
+}
+
+
+/*
+ * lcp_starting - LCP needs the lower layer up.
+ */
+static void
+lcp_starting(f)
+ fsm *f;
+{
+ link_required(f->unit);
+}
+
+
+/*
+ * lcp_finished - LCP has finished with the lower layer.
+ */
+static void
+lcp_finished(f)
+ fsm *f;
+{
+ link_terminated(f->unit);
+}
+
+
+/*
+ * lcp_printpkt - print the contents of an LCP packet.
+ */
+static char *lcp_codenames[] = {
+ "ConfReq", "ConfAck", "ConfNak", "ConfRej",
+ "TermReq", "TermAck", "CodeRej", "ProtRej",
+ "EchoReq", "EchoRep", "DiscReq"
+};
+
+static int
+lcp_printpkt(p, plen, printer, arg)
+ u_char *p;
+ int plen;
+ void (*printer) __P((void *, char *, ...));
+ void *arg;
+{
+ int code, id, len, olen;
+ u_char *pstart, *optend;
+ u_short cishort;
+ u_int32_t cilong;
+
+ 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(lcp_codenames) / sizeof(char *))
+ printer(arg, " %s", lcp_codenames[code-1]);
+ else
+ printer(arg, " code=0x%x", code);
+ printer(arg, " id=0x%x", id);
+ len -= HEADERLEN;
+ switch (code) {
+ case CONFREQ:
+ case CONFACK:
+ case CONFNAK:
+ case CONFREJ:
+ /* print option list */
+ while (len >= 2) {
+ GETCHAR(code, p);
+ GETCHAR(olen, p);
+ p -= 2;
+ if (olen < 2 || olen > len) {
+ break;
+ }
+ printer(arg, " <");
+ len -= olen;
+ optend = p + olen;
+ switch (code) {
+ case CI_MRU:
+ if (olen == CILEN_SHORT) {
+ p += 2;
+ GETSHORT(cishort, p);
+ printer(arg, "mru %d", cishort);
+ }
+ break;
+ case CI_ASYNCMAP:
+ if (olen == CILEN_LONG) {
+ p += 2;
+ GETLONG(cilong, p);
+ printer(arg, "asyncmap 0x%x", cilong);
+ }
+ break;
+ case CI_AUTHTYPE:
+ if (olen >= CILEN_SHORT) {
+ p += 2;
+ printer(arg, "auth ");
+ GETSHORT(cishort, p);
+ switch (cishort) {
+ case PPP_PAP:
+ printer(arg, "pap");
+ break;
+ case PPP_CHAP:
+ printer(arg, "chap");
+ if (p < optend) {
+ switch (*p) {
+ case CHAP_DIGEST_MD5:
+ printer(arg, " MD5");
+ ++p;
+ break;
+#ifdef CHAPMS
+ case CHAP_MICROSOFT:
+ printer(arg, " m$oft");
+ ++p;
+ break;
+#endif
+ }
+ }
+ break;
+ default:
+ printer(arg, "0x%x", cishort);
+ }
+ }
+ break;
+ case CI_QUALITY:
+ if (olen >= CILEN_SHORT) {
+ p += 2;
+ printer(arg, "quality ");
+ GETSHORT(cishort, p);
+ switch (cishort) {
+ case PPP_LQR:
+ printer(arg, "lqr");
+ break;
+ default:
+ printer(arg, "0x%x", cishort);
+ }
+ }
+ break;
+ case CI_CALLBACK:
+ if (olen >= CILEN_CHAR) {
+ p += 2;
+ printer(arg, "callback ");
+ GETCHAR(cishort, p);
+ switch (cishort) {
+ case CBCP_OPT:
+ printer(arg, "CBCP");
+ break;
+ default:
+ printer(arg, "0x%x", cishort);
+ }
+ }
+ break;
+ case CI_MAGICNUMBER:
+ if (olen == CILEN_LONG) {
+ p += 2;
+ GETLONG(cilong, p);
+ printer(arg, "magic 0x%x", cilong);
+ }
+ break;
+ case CI_PCOMPRESSION:
+ if (olen == CILEN_VOID) {
+ p += 2;
+ printer(arg, "pcomp");
+ }
+ break;
+ case CI_ACCOMPRESSION:
+ if (olen == CILEN_VOID) {
+ p += 2;
+ printer(arg, "accomp");
+ }
+ break;
+ }
+ while (p < optend) {
+ GETCHAR(code, p);
+ printer(arg, " %.2x", code);
+ }
+ printer(arg, ">");
+ }
+ break;
+
+ case TERMACK:
+ case TERMREQ:
+ if (len > 0 && *p >= ' ' && *p < 0x7f) {
+ printer(arg, " ");
+ print_string(p, len, printer, arg);
+ p += len;
+ len = 0;
+ }
+ break;
+
+ case ECHOREQ:
+ case ECHOREP:
+ case DISCREQ:
+ if (len >= 4) {
+ GETLONG(cilong, p);
+ printer(arg, " magic=0x%x", cilong);
+ p += 4;
+ len -= 4;
+ }
+ break;
+ }
+
+ /* print the rest of the bytes in the packet */
+ for (; len > 0; --len) {
+ GETCHAR(code, p);
+ printer(arg, " %.2x", code);
+ }
+
+ return p - pstart;
+}
+
+/*
+ * Time to shut down the link because there is nothing out there.
+ */
+
+static
+void LcpLinkFailure (f)
+ fsm *f;
+{
+ if (f->state == OPENED) {
+ info("No response to %d echo-requests", lcp_echos_pending);
+ notice("Serial link appears to be disconnected.");
+ lcp_close(f->unit, "Peer not responding");
+ pppd_status = EXIT_PEER_DEAD;
+ }
+}
+
+/*
+ * Timer expired for the LCP echo requests from this process.
+ */
+
+static void
+LcpEchoCheck (f)
+ fsm *f;
+{
+ LcpSendEchoRequest (f);
+ if (f->state != OPENED)
+ return;
+
+ /*
+ * Start the timer for the next interval.
+ */
+ if (lcp_echo_timer_running)
+ warn("assertion lcp_echo_timer_running==0 failed");
+ TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
+ lcp_echo_timer_running = 1;
+}
+
+/*
+ * LcpEchoTimeout - Timer expired on the LCP echo
+ */
+
+static void
+LcpEchoTimeout (arg)
+ void *arg;
+{
+ if (lcp_echo_timer_running != 0) {
+ lcp_echo_timer_running = 0;
+ LcpEchoCheck ((fsm *) arg);
+ }
+}
+
+/*
+ * LcpEchoReply - LCP has received a reply to the echo
+ */
+
+static void
+lcp_received_echo_reply (f, id, inp, len)
+ fsm *f;
+ int id;
+ u_char *inp;
+ int len;
+{
+ u_int32_t magic;
+
+ /* Check the magic number - don't count replies from ourselves. */
+ if (len < 4) {
+ dbglog("lcp: received short Echo-Reply, length %d", len);
+ return;
+ }
+ GETLONG(magic, inp);
+ if (lcp_gotoptions[f->unit].neg_magicnumber
+ && magic == lcp_gotoptions[f->unit].magicnumber) {
+ warn("appear to have received our own echo-reply!");
+ return;
+ }
+
+ /* Reset the number of outstanding echo frames */
+ lcp_echos_pending = 0;
+}
+
+/*
+ * LcpSendEchoRequest - Send an echo request frame to the peer
+ */
+
+static void
+LcpSendEchoRequest (f)
+ fsm *f;
+{
+ u_int32_t lcp_magic;
+ u_char pkt[4], *pktp;
+
+ /*
+ * Detect the failure of the peer at this point.
+ */
+ if (lcp_echo_fails != 0) {
+ if (lcp_echos_pending >= lcp_echo_fails) {
+ LcpLinkFailure(f);
+ lcp_echos_pending = 0;
+ }
+ }
+
+ /*
+ * Make and send the echo request frame.
+ */
+ if (f->state == OPENED) {
+ lcp_magic = lcp_gotoptions[f->unit].magicnumber;
+ pktp = pkt;
+ PUTLONG(lcp_magic, pktp);
+ fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt);
+ ++lcp_echos_pending;
+ }
+}
+
+/*
+ * lcp_echo_lowerup - Start the timer for the LCP frame
+ */
+
+static void
+lcp_echo_lowerup (unit)
+ int unit;
+{
+ fsm *f = &lcp_fsm[unit];
+
+ /* Clear the parameters for generating echo frames */
+ lcp_echos_pending = 0;
+ lcp_echo_number = 0;
+ lcp_echo_timer_running = 0;
+
+ /* If a timeout interval is specified then start the timer */
+ if (lcp_echo_interval != 0)
+ LcpEchoCheck (f);
+}
+
+/*
+ * lcp_echo_lowerdown - Stop the timer for the LCP frame
+ */
+
+static void
+lcp_echo_lowerdown (unit)
+ int unit;
+{
+ fsm *f = &lcp_fsm[unit];
+
+ if (lcp_echo_timer_running != 0) {
+ UNTIMEOUT (LcpEchoTimeout, f);
+ lcp_echo_timer_running = 0;
+ }
+}
diff --git a/cpukit/pppd/lcp.h b/cpukit/pppd/lcp.h
new file mode 100644
index 0000000000..16ba4cc44b
--- /dev/null
+++ b/cpukit/pppd/lcp.h
@@ -0,0 +1,88 @@
+/*
+ * lcp.h - Link Control Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ *
+ * $Id$
+ */
+
+/*
+ * Options.
+ */
+#define CI_MRU 1 /* Maximum Receive Unit */
+#define CI_ASYNCMAP 2 /* Async Control Character Map */
+#define CI_AUTHTYPE 3 /* Authentication Type */
+#define CI_QUALITY 4 /* Quality Protocol */
+#define CI_MAGICNUMBER 5 /* Magic Number */
+#define CI_PCOMPRESSION 7 /* Protocol Field Compression */
+#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */
+#define CI_CALLBACK 13 /* callback */
+
+/*
+ * LCP-specific packet types.
+ */
+#define PROTREJ 8 /* Protocol Reject */
+#define ECHOREQ 9 /* Echo Request */
+#define ECHOREP 10 /* Echo Reply */
+#define DISCREQ 11 /* Discard Request */
+#define CBCP_OPT 6 /* Use callback control protocol */
+
+/*
+ * The state of options is described by an lcp_options structure.
+ */
+typedef struct lcp_options {
+ bool passive; /* Don't die if we don't get a response */
+ bool silent; /* Wait for the other end to start first */
+ bool restart; /* Restart vs. exit after close */
+ bool neg_mru; /* Negotiate the MRU? */
+ bool neg_asyncmap; /* Negotiate the async map? */
+ bool neg_upap; /* Ask for UPAP authentication? */
+ bool neg_chap; /* Ask for CHAP authentication? */
+ bool neg_magicnumber; /* Ask for magic number? */
+ bool neg_pcompression; /* HDLC Protocol Field Compression? */
+ bool neg_accompression; /* HDLC Address/Control Field Compression? */
+ bool neg_lqr; /* Negotiate use of Link Quality Reports */
+ bool neg_cbcp; /* Negotiate use of CBCP */
+ int mru; /* Value of MRU */
+ u_char chap_mdtype; /* which MD type (hashing algorithm) */
+ u_int32_t asyncmap; /* Value of async map */
+ u_int32_t magicnumber;
+ int numloops; /* Number of loops during magic number neg. */
+ u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */
+} lcp_options;
+
+extern fsm lcp_fsm[];
+extern lcp_options lcp_wantoptions[];
+extern lcp_options lcp_gotoptions[];
+extern lcp_options lcp_allowoptions[];
+extern lcp_options lcp_hisoptions[];
+extern u_int32_t xmit_accm[][8];
+
+#define DEFMRU 1500 /* Try for this */
+#define MINMRU 128 /* No MRUs below this */
+#define MAXMRU 16384 /* Normally limit MRU to this */
+
+void lcp_open __P((int));
+void lcp_close __P((int, char *));
+void lcp_lowerup __P((int));
+void lcp_lowerdown __P((int));
+void lcp_sprotrej __P((int, u_char *, int)); /* send protocol reject */
+
+extern struct protent lcp_protent;
+
+/* Default number of times we receive our magic number from the peer
+ before deciding the link is looped-back. */
+#define DEFLOOPBACKFAIL 10
diff --git a/cpukit/pppd/magic.c b/cpukit/pppd/magic.c
new file mode 100644
index 0000000000..3013e08f07
--- /dev/null
+++ b/cpukit/pppd/magic.c
@@ -0,0 +1,58 @@
+/*
+ * magic.c - PPP Magic Number routines.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ */
+
+#define RCSID "$Id$"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include "pppd.h"
+#include "magic.h"
+
+static const char rcsid[] = RCSID;
+
+/*
+ * magic_init - Initialize the magic number generator.
+ *
+ * Attempts to compute a random number seed which will not repeat.
+ * The current method uses the current hostid, current process ID
+ * and current time, currently.
+ */
+void
+magic_init()
+{
+ long seed;
+ struct timeval t;
+
+ gettimeofday(&t, NULL);
+ seed = get_host_seed() ^ t.tv_sec ^ t.tv_usec ^ getpid();
+ srand48(seed);
+}
+
+/*
+ * magic - Returns the next magic number.
+ */
+u_int32_t
+magic()
+{
+ return (u_int32_t) mrand48();
+}
diff --git a/cpukit/pppd/magic.h b/cpukit/pppd/magic.h
new file mode 100644
index 0000000000..1344626a38
--- /dev/null
+++ b/cpukit/pppd/magic.h
@@ -0,0 +1,23 @@
+/*
+ * magic.h - PPP Magic Number definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ *
+ * $Id$
+ */
+
+void magic_init __P((void)); /* Initialize the magic number generator */
+u_int32_t magic __P((void)); /* Returns the next magic number */
diff --git a/cpukit/pppd/md4.c b/cpukit/pppd/md4.c
new file mode 100644
index 0000000000..cda9f943d0
--- /dev/null
+++ b/cpukit/pppd/md4.c
@@ -0,0 +1,298 @@
+/*
+** ********************************************************************
+** md4.c -- Implementation of MD4 Message Digest Algorithm **
+** Updated: 2/16/90 by Ronald L. Rivest **
+** (C) 1990 RSA Data Security, Inc. **
+** ********************************************************************
+*/
+
+/*
+** To use MD4:
+** -- Include md4.h in your program
+** -- Declare an MDstruct MD to hold the state of the digest
+** computation.
+** -- Initialize MD using MDbegin(&MD)
+** -- For each full block (64 bytes) X you wish to process, call
+** MD4Update(&MD,X,512)
+** (512 is the number of bits in a full block.)
+** -- For the last block (less than 64 bytes) you wish to process,
+** MD4Update(&MD,X,n)
+** where n is the number of bits in the partial block. A partial
+** block terminates the computation, so every MD computation
+** should terminate by processing a partial block, even if it
+** has n = 0.
+** -- The message digest is available in MD.buffer[0] ...
+** MD.buffer[3]. (Least-significant byte of each word
+** should be output first.)
+** -- You can print out the digest using MDprint(&MD)
+*/
+
+/* Implementation notes:
+** This implementation assumes that ints are 32-bit quantities.
+*/
+
+#define TRUE 1
+#define FALSE 0
+
+/* Compile-time includes
+*/
+#include <stdio.h>
+#include "md4.h"
+#include "pppd.h"
+
+/* Compile-time declarations of MD4 "magic constants".
+*/
+#define I0 0x67452301 /* Initial values for MD buffer */
+#define I1 0xefcdab89
+#define I2 0x98badcfe
+#define I3 0x10325476
+#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
+#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
+/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
+** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
+** Table 2, page 660.
+*/
+
+#define fs1 3 /* round 1 shift amounts */
+#define fs2 7
+#define fs3 11
+#define fs4 19
+#define gs1 3 /* round 2 shift amounts */
+#define gs2 5
+#define gs3 9
+#define gs4 13
+#define hs1 3 /* round 3 shift amounts */
+#define hs2 9
+#define hs3 11
+#define hs4 15
+
+/* Compile-time macro declarations for MD4.
+** Note: The "rot" operator uses the variable "tmp".
+** It assumes tmp is declared as unsigned int, so that the >>
+** operator will shift in zeros rather than extending the sign bit.
+*/
+#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
+#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
+#define h(X,Y,Z) (X^Y^Z)
+#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
+#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
+#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
+#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
+
+/* MD4print(MDp)
+** Print message digest buffer MDp as 32 hexadecimal digits.
+** Order is from low-order byte of buffer[0] to high-order byte of
+** buffer[3].
+** Each byte is printed with high-order hexadecimal digit first.
+** This is a user-callable routine.
+*/
+void
+MD4Print(MDp)
+MD4_CTX *MDp;
+{
+ int i,j;
+ for (i=0;i<4;i++)
+ for (j=0;j<32;j=j+8)
+ printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
+}
+
+/* MD4Init(MDp)
+** Initialize message digest buffer MDp.
+** This is a user-callable routine.
+*/
+void
+MD4Init(MDp)
+MD4_CTX *MDp;
+{
+ int i;
+ MDp->buffer[0] = I0;
+ MDp->buffer[1] = I1;
+ MDp->buffer[2] = I2;
+ MDp->buffer[3] = I3;
+ for (i=0;i<8;i++) MDp->count[i] = 0;
+ MDp->done = 0;
+}
+
+/* MDblock(MDp,X)
+** Update message digest buffer MDp->buffer using 16-word data block X.
+** Assumes all 16 words of X are full of data.
+** Does not update MDp->count.
+** This routine is not user-callable.
+*/
+static void
+MDblock(MDp,Xb)
+MD4_CTX *MDp;
+unsigned char *Xb;
+{
+ register unsigned int tmp, A, B, C, D;
+ unsigned int X[16];
+ int i;
+
+ for (i = 0; i < 16; ++i) {
+ X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24);
+ Xb += 4;
+ }
+
+ A = MDp->buffer[0];
+ B = MDp->buffer[1];
+ C = MDp->buffer[2];
+ D = MDp->buffer[3];
+ /* Update the message digest buffer */
+ ff(A , B , C , D , 0 , fs1); /* Round 1 */
+ ff(D , A , B , C , 1 , fs2);
+ ff(C , D , A , B , 2 , fs3);
+ ff(B , C , D , A , 3 , fs4);
+ ff(A , B , C , D , 4 , fs1);
+ ff(D , A , B , C , 5 , fs2);
+ ff(C , D , A , B , 6 , fs3);
+ ff(B , C , D , A , 7 , fs4);
+ ff(A , B , C , D , 8 , fs1);
+ ff(D , A , B , C , 9 , fs2);
+ ff(C , D , A , B , 10 , fs3);
+ ff(B , C , D , A , 11 , fs4);
+ ff(A , B , C , D , 12 , fs1);
+ ff(D , A , B , C , 13 , fs2);
+ ff(C , D , A , B , 14 , fs3);
+ ff(B , C , D , A , 15 , fs4);
+ gg(A , B , C , D , 0 , gs1); /* Round 2 */
+ gg(D , A , B , C , 4 , gs2);
+ gg(C , D , A , B , 8 , gs3);
+ gg(B , C , D , A , 12 , gs4);
+ gg(A , B , C , D , 1 , gs1);
+ gg(D , A , B , C , 5 , gs2);
+ gg(C , D , A , B , 9 , gs3);
+ gg(B , C , D , A , 13 , gs4);
+ gg(A , B , C , D , 2 , gs1);
+ gg(D , A , B , C , 6 , gs2);
+ gg(C , D , A , B , 10 , gs3);
+ gg(B , C , D , A , 14 , gs4);
+ gg(A , B , C , D , 3 , gs1);
+ gg(D , A , B , C , 7 , gs2);
+ gg(C , D , A , B , 11 , gs3);
+ gg(B , C , D , A , 15 , gs4);
+ hh(A , B , C , D , 0 , hs1); /* Round 3 */
+ hh(D , A , B , C , 8 , hs2);
+ hh(C , D , A , B , 4 , hs3);
+ hh(B , C , D , A , 12 , hs4);
+ hh(A , B , C , D , 2 , hs1);
+ hh(D , A , B , C , 10 , hs2);
+ hh(C , D , A , B , 6 , hs3);
+ hh(B , C , D , A , 14 , hs4);
+ hh(A , B , C , D , 1 , hs1);
+ hh(D , A , B , C , 9 , hs2);
+ hh(C , D , A , B , 5 , hs3);
+ hh(B , C , D , A , 13 , hs4);
+ hh(A , B , C , D , 3 , hs1);
+ hh(D , A , B , C , 11 , hs2);
+ hh(C , D , A , B , 7 , hs3);
+ hh(B , C , D , A , 15 , hs4);
+ MDp->buffer[0] += A;
+ MDp->buffer[1] += B;
+ MDp->buffer[2] += C;
+ MDp->buffer[3] += D;
+}
+
+/* MD4Update(MDp,X,count)
+** Input: X -- a pointer to an array of unsigned characters.
+** count -- the number of bits of X to use.
+** (if not a multiple of 8, uses high bits of last byte.)
+** Update MDp using the number of bits of X given by count.
+** This is the basic input routine for an MD4 user.
+** The routine completes the MD computation when count < 512, so
+** every MD computation should end with one call to MD4Update with a
+** count less than 512. A call with count 0 will be ignored if the
+** MD has already been terminated (done != 0), so an extra call with
+** count 0 can be given as a "courtesy close" to force termination
+** if desired.
+*/
+void
+MD4Update(MDp,X,count)
+MD4_CTX *MDp;
+unsigned char *X;
+unsigned int count;
+{
+ unsigned int i, tmp, bit, byte, mask;
+ unsigned char XX[64];
+ unsigned char *p;
+
+ /* return with no error if this is a courtesy close with count
+ ** zero and MDp->done is true.
+ */
+ if (count == 0 && MDp->done) return;
+ /* check to see if MD is already done and report error */
+ if (MDp->done)
+ { printf("\nError: MD4Update MD already done."); return; }
+
+ /* Add count to MDp->count */
+ tmp = count;
+ p = MDp->count;
+ while (tmp)
+ { tmp += *p;
+ *p++ = tmp;
+ tmp = tmp >> 8;
+ }
+
+ /* Process data */
+ if (count == 512)
+ { /* Full block of data to handle */
+ MDblock(MDp,X);
+ }
+ else if (count > 512) /* Check for count too large */
+ {
+ printf("\nError: MD4Update called with illegal count value %d.",
+ count);
+ return;
+ }
+ else /* partial block -- must be last block so finish up */
+ {
+ /* Find out how many bytes and residual bits there are */
+ byte = count >> 3;
+ bit = count & 7;
+ /* Copy X into XX since we need to modify it */
+ for (i=0;i<=byte;i++) XX[i] = X[i];
+ for (i=byte+1;i<64;i++) XX[i] = 0;
+ /* Add padding '1' bit and low-order zeros in last byte */
+ mask = 1 << (7 - bit);
+ XX[byte] = (XX[byte] | mask) & ~( mask - 1);
+ /* If room for bit count, finish up with this block */
+ if (byte <= 55)
+ {
+ for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
+ MDblock(MDp,XX);
+ }
+ else /* need to do two blocks to finish up */
+ {
+ MDblock(MDp,XX);
+ for (i=0;i<56;i++) XX[i] = 0;
+ for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
+ MDblock(MDp,XX);
+ }
+ /* Set flag saying we're done with MD computation */
+ MDp->done = 1;
+ }
+}
+
+/*
+** Finish up MD4 computation and return message digest.
+*/
+void
+MD4Final(buf, MD)
+unsigned char *buf;
+MD4_CTX *MD;
+{
+ int i, j;
+ unsigned int w;
+
+ MD4Update(MD, NULL, 0);
+ for (i = 0; i < 4; ++i) {
+ w = MD->buffer[i];
+ for (j = 0; j < 4; ++j) {
+ *buf++ = w;
+ w >>= 8;
+ }
+ }
+}
+
+/*
+** End of md4.c
+****************************(cut)***********************************/
diff --git a/cpukit/pppd/md4.h b/cpukit/pppd/md4.h
new file mode 100644
index 0000000000..80e8f9a2ac
--- /dev/null
+++ b/cpukit/pppd/md4.h
@@ -0,0 +1,64 @@
+
+/*
+** ********************************************************************
+** md4.h -- Header file for implementation of **
+** MD4 Message Digest Algorithm **
+** Updated: 2/13/90 by Ronald L. Rivest **
+** (C) 1990 RSA Data Security, Inc. **
+** ********************************************************************
+*/
+
+#ifndef __P
+# if defined(__STDC__) || defined(__GNUC__)
+# define __P(x) x
+# else
+# define __P(x) ()
+# endif
+#endif
+
+
+/* MDstruct is the data structure for a message digest computation.
+*/
+typedef struct {
+ unsigned int buffer[4]; /* Holds 4-word result of MD computation */
+ unsigned char count[8]; /* Number of bits processed so far */
+ unsigned int done; /* Nonzero means MD computation finished */
+} MD4_CTX;
+
+/* MD4Init(MD4_CTX *)
+** Initialize the MD4_CTX prepatory to doing a message digest
+** computation.
+*/
+extern void MD4Init __P((MD4_CTX *MD));
+
+/* MD4Update(MD,X,count)
+** Input: X -- a pointer to an array of unsigned characters.
+** count -- the number of bits of X to use (an unsigned int).
+** Updates MD using the first "count" bits of X.
+** The array pointed to by X is not modified.
+** If count is not a multiple of 8, MD4Update uses high bits of
+** last byte.
+** This is the basic input routine for a user.
+** The routine terminates the MD computation when count < 512, so
+** every MD computation should end with one call to MD4Update with a
+** count less than 512. Zero is OK for a count.
+*/
+extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count));
+
+/* MD4Print(MD)
+** Prints message digest buffer MD as 32 hexadecimal digits.
+** Order is from low-order byte of buffer[0] to high-order byte
+** of buffer[3].
+** Each byte is printed with high-order hexadecimal digit first.
+*/
+extern void MD4Print __P((MD4_CTX *));
+
+/* MD4Final(buf, MD)
+** Returns message digest from MD and terminates the message
+** digest computation.
+*/
+extern void MD4Final __P((unsigned char *, MD4_CTX *));
+
+/*
+** End of md4.h
+****************************(cut)***********************************/
diff --git a/cpukit/pppd/md5.c b/cpukit/pppd/md5.c
new file mode 100644
index 0000000000..afabb6028e
--- /dev/null
+++ b/cpukit/pppd/md5.c
@@ -0,0 +1,308 @@
+
+
+/*
+ ***********************************************************************
+ ** md5.c -- the source code for MD5 routines **
+ ** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
+ ** Created: 2/17/90 RLR **
+ ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
+ ***********************************************************************
+ */
+
+/*
+ ***********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. 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 <string.h> /* memcpy */
+
+#include "md5.h"
+
+/*
+ ***********************************************************************
+ ** Message-digest routines: **
+ ** To form the message digest for a message M **
+ ** (1) Initialize a context buffer mdContext using MD5Init **
+ ** (2) Call MD5Update on mdContext and M **
+ ** (3) Call MD5Final on mdContext **
+ ** The message digest is now in mdContext->digest[0...15] **
+ ***********************************************************************
+ */
+
+/* forward declaration */
+static void Transform ();
+
+static unsigned char PADDING[64] = {
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* 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); \
+ }
+
+#ifdef __STDC__
+#define UL(x) x##U
+#else
+#define UL(x) x
+#endif
+
+/* The routine MD5Init initializes the message-digest context
+ mdContext. All fields are set to zero.
+ */
+void MD5Init (mdContext)
+MD5_CTX *mdContext;
+{
+ mdContext->i[0] = mdContext->i[1] = (UINT4)0;
+
+ /* Load magic initialization constants.
+ */
+ mdContext->buf[0] = (UINT4)0x67452301;
+ mdContext->buf[1] = (UINT4)0xefcdab89;
+ mdContext->buf[2] = (UINT4)0x98badcfe;
+ mdContext->buf[3] = (UINT4)0x10325476;
+}
+
+/* The routine MD5Update updates the message-digest context to
+ account for the presence of each of the characters inBuf[0..inLen-1]
+ in the message whose digest is being computed.
+ */
+void MD5Update (mdContext, inBuf, inLen)
+MD5_CTX *mdContext;
+const unsigned char *inBuf;
+unsigned int inLen;
+{
+ UINT4 in[16];
+ int mdi;
+ unsigned int i, ii;
+
+ /* compute number of bytes mod 64 */
+ mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+ /* update number of bits */
+ if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
+ mdContext->i[1]++;
+ mdContext->i[0] += ((UINT4)inLen << 3);
+ mdContext->i[1] += ((UINT4)inLen >> 29);
+
+ while (inLen--) {
+ /* add new character to buffer, increment mdi */
+ mdContext->in[mdi++] = *inBuf++;
+
+ /* transform if necessary */
+ if (mdi == 0x40) {
+ for (i = 0, ii = 0; i < 16; i++, ii += 4)
+ in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+ (((UINT4)mdContext->in[ii+2]) << 16) |
+ (((UINT4)mdContext->in[ii+1]) << 8) |
+ ((UINT4)mdContext->in[ii]);
+ Transform (mdContext->buf, in);
+ mdi = 0;
+ }
+ }
+}
+
+/* The routine MD5Final terminates the message-digest computation and
+ ends with the desired message digest in mdContext->digest[0...15].
+ */
+void MD5Final (hash, mdContext)
+unsigned char hash[];
+MD5_CTX *mdContext;
+{
+ UINT4 in[16];
+ int mdi;
+ unsigned int i, ii;
+ unsigned int padLen;
+
+ /* save number of bits */
+ in[14] = mdContext->i[0];
+ in[15] = mdContext->i[1];
+
+ /* compute number of bytes mod 64 */
+ mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+ /* pad out to 56 mod 64 */
+ padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
+ MD5Update (mdContext, PADDING, padLen);
+
+ /* append length in bits and transform */
+ for (i = 0, ii = 0; i < 14; i++, ii += 4)
+ in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+ (((UINT4)mdContext->in[ii+2]) << 16) |
+ (((UINT4)mdContext->in[ii+1]) << 8) |
+ ((UINT4)mdContext->in[ii]);
+ Transform (mdContext->buf, in);
+
+ /* store buffer in digest */
+ for (i = 0, ii = 0; i < 4; i++, ii += 4) {
+ mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
+ mdContext->digest[ii+1] =
+ (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
+ mdContext->digest[ii+2] =
+ (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
+ mdContext->digest[ii+3] =
+ (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
+ }
+ memcpy(hash, mdContext->digest, 16);
+}
+
+/* Basic MD5 step. Transforms buf based on in.
+ */
+static void Transform (buf, in)
+UINT4 *buf;
+UINT4 *in;
+{
+ UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+
+ /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+ FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
+ FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
+ FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
+ FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
+ FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
+ FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
+ FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
+ FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
+ FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
+ FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
+ FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
+ FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
+ FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
+ FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
+ FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
+ FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
+
+ /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+ GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
+ GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
+ GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
+ GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
+ GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
+ GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */
+ GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
+ GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
+ GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
+ GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
+ GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
+ GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
+ GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
+ GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
+ GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
+ GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
+
+ /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+ HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
+ HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
+ HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
+ HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
+ HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
+ HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
+ HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
+ HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
+ HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
+ HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
+ HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
+ HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */
+ HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
+ HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
+ HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
+ HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
+
+ /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+ II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
+ II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
+ II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
+ II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
+ II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
+ II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
+ II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
+ II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
+ II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
+ II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
+ II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
+ II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
+ II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
+ II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
+ II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
+ II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+/*
+ ***********************************************************************
+ ** End of md5.c **
+ ******************************** (cut) ********************************
+ */
diff --git a/cpukit/pppd/md5.h b/cpukit/pppd/md5.h
new file mode 100644
index 0000000000..1756a31228
--- /dev/null
+++ b/cpukit/pppd/md5.h
@@ -0,0 +1,60 @@
+/*
+ ***********************************************************************
+ ** md5.h -- header file for implementation of MD5 **
+ ** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
+ ** Created: 2/17/90 RLR **
+ ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
+ ** Revised (for MD5): RLR 4/27/91 **
+ ** -- G modified to have y&~z instead of y&z **
+ ** -- FF, GG, HH modified to add in last register done **
+ ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
+ ** -- distinct additive constant for each step **
+ ** -- round 4 added, working mod 7 **
+ ***********************************************************************
+ */
+
+/*
+ ***********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. 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 __MD5_INCLUDE__
+
+#include <stdint.h>
+
+/* typedef a 32-bit type */
+typedef uint32_t UINT4;
+
+/* Data structure for MD5 (Message-Digest) computation */
+typedef struct {
+ UINT4 i[2]; /* number of _bits_ handled mod 2^64 */
+ UINT4 buf[4]; /* scratch buffer */
+ unsigned char in[64]; /* input buffer */
+ unsigned char digest[16]; /* actual digest after MD5Final call */
+} MD5_CTX;
+
+void MD5Init (MD5_CTX *);
+void MD5Update (MD5_CTX *, const unsigned char *, unsigned int);
+void MD5Final (unsigned char [16], MD5_CTX *);
+
+#define __MD5_INCLUDE__
+#endif /* __MD5_INCLUDE__ */
diff --git a/cpukit/pppd/options.c b/cpukit/pppd/options.c
new file mode 100644
index 0000000000..fb686d94a6
--- /dev/null
+++ b/cpukit/pppd/options.c
@@ -0,0 +1,1525 @@
+/*
+ * options.c - handles option processing for PPP.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ */
+
+#define RCSID "$Id$"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <string.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#ifdef PLUGIN
+#include <dlfcn.h>
+#endif
+#ifdef PPP_FILTER
+#include <pcap.h>
+#include <pcap-int.h> /* XXX: To get struct pcap */
+#endif
+
+#include "pppd.h"
+#include "pathnames.h"
+#include "patchlevel.h"
+#include "fsm.h"
+#include "lcp.h"
+#include "ipcp.h"
+#include "upap.h"
+#include "chap.h"
+#include "ccp.h"
+
+#include <net/ppp-comp.h>
+
+#if defined(ultrix) || defined(NeXT)
+char *strdup __P((char *));
+#endif
+
+static const char rcsid[] = RCSID;
+
+/*
+ * Option variables and default values.
+ */
+#ifdef PPP_FILTER
+int dflag = 0; /* Tell libpcap we want debugging */
+#endif
+int debug = 0; /* Debug flag */
+int kdebugflag = 0; /* Tell kernel to print debug messages */
+int default_device = 1; /* Using /dev/tty or equivalent */
+char devnam[MAXPATHLEN]; /* Device name */
+int crtscts = 0; /* Use hardware flow control */
+bool modem = 1; /* Use modem control lines */
+int inspeed = 0; /* Input/Output speed requested */
+u_int32_t netmask = 0; /* IP netmask to set on interface */
+bool lockflag = 0; /* Create lock file to lock the serial dev */
+bool nodetach = 0; /* Don't detach from controlling tty */
+bool updetach = 0; /* Detach once link is up */
+char *initializer = NULL; /* Script to initialize physical link */
+char *connect_script = NULL; /* Script to establish physical link */
+char *disconnect_script = NULL; /* Script to disestablish physical link */
+char *welcomer = NULL; /* Script to run after phys link estab. */
+char *ptycommand = NULL; /* Command to run on other side of pty */
+int maxconnect = 0; /* Maximum connect time */
+char user[MAXNAMELEN]; /* Username for PAP */
+char passwd[MAXSECRETLEN]; /* Password for PAP */
+bool persist = 0; /* Reopen link after it goes down */
+char our_name[MAXNAMELEN]; /* Our name for authentication purposes */
+bool demand = 0; /* do dial-on-demand */
+char *ipparam = NULL; /* Extra parameter for ip up/down scripts */
+int idle_time_limit = 0; /* Disconnect if idle for this many seconds */
+int holdoff = 30; /* # seconds to pause before reconnecting */
+bool holdoff_specified; /* true if a holdoff value has been given */
+bool notty = 0; /* Stdin/out is not a tty */
+char *record_file = NULL; /* File to record chars sent/received */
+int using_pty = 0;
+bool sync_serial = 0; /* Device is synchronous serial device */
+int log_to_fd = 1; /* send log messages to this fd too */
+int maxfail = 10; /* max # of unsuccessful connection attempts */
+char linkname[MAXPATHLEN]; /* logical name for link */
+bool tune_kernel; /* may alter kernel settings */
+int connect_delay = 1000; /* wait this many ms after connect script */
+
+extern option_t auth_options[];
+extern struct stat devstat;
+extern int prepass; /* Doing pre-pass to find device name */
+
+struct option_info initializer_info;
+struct option_info connect_script_info;
+struct option_info disconnect_script_info;
+struct option_info welcomer_info;
+struct option_info devnam_info;
+struct option_info ptycommand_info;
+
+#ifdef PPP_FILTER
+struct bpf_program pass_filter;/* Filter program for packets to pass */
+struct bpf_program active_filter; /* Filter program for link-active pkts */
+pcap_t pc; /* Fake struct pcap so we can compile expr */
+#endif
+
+char *current_option; /* the name of the option being parsed */
+int privileged_option; /* set iff the current option came from root */
+char *option_source; /* string saying where the option came from */
+bool log_to_file; /* log_to_fd is a file opened by us */
+
+/*
+ * Prototypes
+ */
+static int setdevname __P((char *));
+static int setipaddr __P((char *));
+static int setspeed __P((char *));
+static int noopt __P((char **));
+static int setdomain __P((char **));
+static int setnetmask __P((char **));
+static int setxonxoff __P((char **));
+static int readfile __P((char **));
+static int callfile __P((char **));
+static void usage __P((void));
+static int setlogfile __P((char **));
+#ifdef PLUGIN
+static int loadplugin __P((char **));
+#endif
+
+#ifdef PPP_FILTER
+static int setpassfilter __P((char **));
+static int setactivefilter __P((char **));
+#endif
+
+static option_t *find_option __P((char *name));
+static int process_option __P((option_t *, char **));
+static int n_arguments __P((option_t *));
+static int number_option __P((char *, u_int32_t *, int));
+
+/*
+ * Structure to store extra lists of options.
+ */
+struct option_list {
+ option_t *options;
+ struct option_list *next;
+};
+
+static struct option_list *extra_options = NULL;
+
+/*
+ * Valid arguments.
+ */
+option_t general_options[] = {
+ { "debug", o_int, &debug,
+ "Increase debugging level", OPT_INC|OPT_NOARG|1 },
+ { "-d", o_int, &debug,
+ "Increase debugging level", OPT_INC|OPT_NOARG|1 },
+ { "kdebug", o_int, &kdebugflag,
+ "Set kernel driver debug level" },
+ { "nodetach", o_bool, &nodetach,
+ "Don't detach from controlling tty", 1 },
+ { "-detach", o_bool, &nodetach,
+ "Don't detach from controlling tty", 1 },
+ { "updetach", o_bool, &updetach,
+ "Detach from controlling tty once link is up", 1 },
+ { "holdoff", o_int, &holdoff,
+ "Set time in seconds before retrying connection" },
+ { "idle", o_int, &idle_time_limit,
+ "Set time in seconds before disconnecting idle link" },
+ { "lock", o_bool, &lockflag,
+ "Lock serial device with UUCP-style lock file", 1 },
+ { "-all", o_special_noarg, noopt,
+ "Don't request/allow any LCP or IPCP options (useless)" },
+ { "init", o_string, &initializer,
+ "A program to initialize the device",
+ OPT_A2INFO | OPT_PRIVFIX, &initializer_info },
+ { "connect", o_string, &connect_script,
+ "A program to set up a connection",
+ OPT_A2INFO | OPT_PRIVFIX, &connect_script_info },
+ { "disconnect", o_string, &disconnect_script,
+ "Program to disconnect serial device",
+ OPT_A2INFO | OPT_PRIVFIX, &disconnect_script_info },
+ { "welcome", o_string, &welcomer,
+ "Script to welcome client",
+ OPT_A2INFO | OPT_PRIVFIX, &welcomer_info },
+ { "pty", o_string, &ptycommand,
+ "Script to run on pseudo-tty master side",
+ OPT_A2INFO | OPT_PRIVFIX | OPT_DEVNAM, &ptycommand_info },
+ { "notty", o_bool, &notty,
+ "Input/output is not a tty", OPT_DEVNAM | 1 },
+ { "record", o_string, &record_file,
+ "Record characters sent/received to file" },
+ { "maxconnect", o_int, &maxconnect,
+ "Set connection time limit", OPT_LLIMIT|OPT_NOINCR|OPT_ZEROINF },
+ { "crtscts", o_int, &crtscts,
+ "Set hardware (RTS/CTS) flow control", OPT_NOARG|OPT_VAL(1) },
+ { "nocrtscts", o_int, &crtscts,
+ "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1) },
+ { "-crtscts", o_int, &crtscts,
+ "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1) },
+ { "cdtrcts", o_int, &crtscts,
+ "Set alternate hardware (DTR/CTS) flow control", OPT_NOARG|OPT_VAL(2) },
+ { "nocdtrcts", o_int, &crtscts,
+ "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1) },
+ { "xonxoff", o_special_noarg, setxonxoff,
+ "Set software (XON/XOFF) flow control" },
+ { "domain", o_special, setdomain,
+ "Add given domain name to hostname" },
+ { "mtu", o_int, &lcp_allowoptions[0].mru,
+ "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU },
+ { "netmask", o_special, setnetmask,
+ "set netmask" },
+ { "modem", o_bool, &modem,
+ "Use modem control lines", 1 },
+ { "local", o_bool, &modem,
+ "Don't use modem control lines" },
+ { "file", o_special, readfile,
+ "Take options from a file", OPT_PREPASS },
+ { "call", o_special, callfile,
+ "Take options from a privileged file", OPT_PREPASS },
+ { "persist", o_bool, &persist,
+ "Keep on reopening connection after close", 1 },
+ { "nopersist", o_bool, &persist,
+ "Turn off persist option" },
+ { "demand", o_bool, &demand,
+ "Dial on demand", OPT_INITONLY | 1, &persist },
+ { "sync", o_bool, &sync_serial,
+ "Use synchronous HDLC serial encoding", 1 },
+ { "logfd", o_int, &log_to_fd,
+ "Send log messages to this file descriptor" },
+ { "logfile", o_special, setlogfile,
+ "Append log messages to this file" },
+ { "nolog", o_int, &log_to_fd,
+ "Don't send log messages to any file",
+ OPT_NOARG | OPT_VAL(-1) },
+ { "nologfd", o_int, &log_to_fd,
+ "Don't send log messages to any file descriptor",
+ OPT_NOARG | OPT_VAL(-1) },
+ { "linkname", o_string, linkname,
+ "Set logical name for link",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+ { "maxfail", o_int, &maxfail,
+ "Maximum number of unsuccessful connection attempts to allow" },
+ { "ktune", o_bool, &tune_kernel,
+ "Alter kernel settings as necessary", 1 },
+ { "noktune", o_bool, &tune_kernel,
+ "Don't alter kernel settings", 0 },
+ { "connect-delay", o_int, &connect_delay,
+ "Maximum time (in ms) to wait after connect script finishes" },
+#ifdef PLUGIN
+ { "plugin", o_special, loadplugin,
+ "Load a plug-in module into pppd", OPT_PRIV },
+#endif
+
+#ifdef PPP_FILTER
+ { "pdebug", o_int, &dflag,
+ "libpcap debugging" },
+ { "pass-filter", 1, setpassfilter,
+ "set filter for packets to pass" },
+ { "active-filter", 1, setactivefilter,
+ "set filter for active pkts" },
+#endif
+
+ { NULL }
+};
+
+#ifndef IMPLEMENTATION
+#define IMPLEMENTATION ""
+#endif
+
+static char *usage_string = "\
+pppd version %s.%d%s\n\
+Usage: %s [ options ], where options are:\n\
+ <device> Communicate over the named device\n\
+ <speed> Set the baud rate to <speed>\n\
+ <loc>:<rem> Set the local and/or remote interface IP\n\
+ addresses. Either one may be omitted.\n\
+ asyncmap <n> Set the desired async map to hex <n>\n\
+ auth Require authentication from peer\n\
+ connect <p> Invoke shell command <p> to set up the serial line\n\
+ crtscts Use hardware RTS/CTS flow control\n\
+ defaultroute Add default route through interface\n\
+ file <f> Take options from file <f>\n\
+ modem Use modem control lines\n\
+ mru <n> Set MRU value to <n> for negotiation\n\
+See pppd(8) for more options.\n\
+";
+
+/*
+ * parse_args - parse a string of arguments from the command line.
+ * If prepass is true, we are scanning for the device name and only
+ * processing a few options, so error messages are suppressed.
+ */
+int
+parse_args(argc, argv)
+ int argc;
+ char **argv;
+{
+ char *arg;
+ option_t *opt;
+ int ret;
+
+ privileged_option = privileged;
+ option_source = "command line";
+ while (argc > 0) {
+ arg = *argv++;
+ --argc;
+
+ /*
+ * First see if it's an option in the new option list.
+ */
+ opt = find_option(arg);
+ if (opt != NULL) {
+ int n = n_arguments(opt);
+ if (argc < n) {
+ option_error("too few parameters for option %s", arg);
+ return 0;
+ }
+ current_option = arg;
+ if (!process_option(opt, argv))
+ return 0;
+ argc -= n;
+ argv += n;
+ continue;
+ }
+
+ /*
+ * Maybe a tty name, speed or IP address?
+ */
+ if ((ret = setdevname(arg)) == 0
+ && (ret = setspeed(arg)) == 0
+ && (ret = setipaddr(arg)) == 0
+ && !prepass) {
+ option_error("unrecognized option '%s'", arg);
+ usage();
+ return 0;
+ }
+ if (ret < 0) /* error */
+ return 0;
+ }
+ return 1;
+}
+
+#if 0
+/*
+ * scan_args - scan the command line arguments to get the tty name,
+ * if specified. Also checks whether the notty or pty option was given.
+ */
+void
+scan_args(argc, argv)
+ int argc;
+ char **argv;
+{
+ char *arg;
+ option_t *opt;
+
+ privileged_option = privileged;
+ while (argc > 0) {
+ arg = *argv++;
+ --argc;
+
+ if (strcmp(arg, "notty") == 0 || strcmp(arg, "pty") == 0)
+ using_pty = 1;
+
+ /* Skip options and their arguments */
+ opt = find_option(arg);
+ if (opt != NULL) {
+ int n = n_arguments(opt);
+ argc -= n;
+ argv += n;
+ continue;
+ }
+
+ /* Check if it's a tty name and copy it if so */
+ (void) setdevname(arg, 1);
+ }
+}
+#endif
+
+/*
+ * options_from_file - Read a string of options from a file,
+ * and interpret them.
+ */
+int
+options_from_file(filename, must_exist, check_prot, priv)
+ char *filename;
+ int must_exist;
+ int check_prot;
+ int priv;
+{
+ FILE *f;
+ int i, newline, ret, err;
+ option_t *opt;
+ int oldpriv;
+ char *oldsource;
+ char *argv[MAXARGS];
+ char args[MAXARGS][MAXWORDLEN];
+ char cmd[MAXWORDLEN];
+
+ f = fopen(filename, "r");
+ err = errno;
+ if (f == NULL) {
+ if (!must_exist && err == ENOENT)
+ return 1;
+ errno = err;
+ option_error("Can't open options file %s: %m", filename);
+ return 0;
+ }
+
+ oldpriv = privileged_option;
+ privileged_option = priv;
+ oldsource = option_source;
+ option_source = strdup(filename);
+ if (option_source == NULL)
+ option_source = "file";
+ ret = 0;
+ while (getword(f, cmd, &newline, filename)) {
+ /*
+ * First see if it's a command.
+ */
+ opt = find_option(cmd);
+ if (opt != NULL) {
+ int n = n_arguments(opt);
+ for (i = 0; i < n; ++i) {
+ if (!getword(f, args[i], &newline, filename)) {
+ option_error(
+ "In file %s: too few parameters for option '%s'",
+ filename, cmd);
+ goto err;
+ }
+ argv[i] = args[i];
+ }
+ current_option = cmd;
+ if ((opt->flags & OPT_DEVEQUIV) && devnam_fixed) {
+ option_error("the %s option may not be used in the %s file",
+ cmd, filename);
+ goto err;
+ }
+ if (!process_option(opt, argv))
+ goto err;
+ continue;
+ }
+
+ /*
+ * Maybe a tty name, speed or IP address?
+ */
+ if ((i = setdevname(cmd)) == 0
+ && (i = setspeed(cmd)) == 0
+ && (i = setipaddr(cmd)) == 0) {
+ option_error("In file %s: unrecognized option '%s'",
+ filename, cmd);
+ goto err;
+ }
+ if (i < 0) /* error */
+ goto err;
+ }
+ ret = 1;
+
+err:
+ fclose(f);
+ privileged_option = oldpriv;
+ option_source = oldsource;
+ return ret;
+}
+
+/*
+ * options_from_user - See if the use has a ~/.ppprc file,
+ * and if so, interpret options from it.
+ */
+int
+options_from_user()
+{
+ return 0;
+}
+
+/*
+ * options_for_tty - See if an options file exists for the serial
+ * device, and if so, interpret options from it.
+ */
+int
+options_for_tty()
+{
+ char *dev, *path, *p;
+ int ret;
+ size_t pl;
+
+ dev = devnam;
+ if (strncmp(dev, "/dev/", 5) == 0)
+ dev += 5;
+ if (dev[0] == 0 || strcmp(dev, "tty") == 0)
+ return 1; /* don't look for /etc/ppp/options.tty */
+ pl = strlen(_PATH_TTYOPT) + strlen(dev) + 1;
+ path = malloc(pl);
+ if (path == NULL)
+ novm("tty init file name");
+ slprintf(path, pl, "%s%s", _PATH_TTYOPT, dev);
+ /* Turn slashes into dots, for Solaris case (e.g. /dev/term/a) */
+ for (p = path + strlen(_PATH_TTYOPT); *p != 0; ++p)
+ if (*p == '/')
+ *p = '.';
+ ret = options_from_file(path, 0, 0, 1);
+ free(path);
+ return ret;
+}
+
+/*
+ * options_from_list - process a string of options in a wordlist.
+ */
+int
+options_from_list(w, priv)
+ struct wordlist *w;
+ int priv;
+{
+ char *argv[MAXARGS];
+ option_t *opt;
+ int i, ret = 0;
+
+ privileged_option = priv;
+ option_source = "secrets file";
+
+ while (w != NULL) {
+ /*
+ * First see if it's a command.
+ */
+ opt = find_option(w->word);
+ if (opt != NULL) {
+ int n = n_arguments(opt);
+ struct wordlist *w0 = w;
+ for (i = 0; i < n; ++i) {
+ w = w->next;
+ if (w == NULL) {
+ option_error(
+ "In secrets file: too few parameters for option '%s'",
+ w0->word);
+ goto err;
+ }
+ argv[i] = w->word;
+ }
+ current_option = w0->word;
+ if (!process_option(opt, argv))
+ goto err;
+ w = w->next;
+ continue;
+ }
+
+ /*
+ * Maybe a tty name, speed or IP address?
+ */
+ if ((i = setdevname(w->word)) == 0
+ && (i = setspeed(w->word)) == 0
+ && (i = setipaddr(w->word)) == 0) {
+ option_error("In secrets file: unrecognized option '%s'",
+ w->word);
+ goto err;
+ }
+ if (i < 0) /* error */
+ goto err;
+ w = w->next;
+ }
+ ret = 1;
+
+err:
+ return ret;
+}
+
+/*
+ * find_option - scan the option lists for the various protocols
+ * looking for an entry with the given name.
+ * This could be optimized by using a hash table.
+ */
+static option_t *
+find_option(name)
+ char *name;
+{
+ option_t *opt;
+ struct option_list *list;
+ int i;
+
+ for (list = extra_options; list != NULL; list = list->next)
+ for (opt = list->options; opt->name != NULL; ++opt)
+ if (strcmp(name, opt->name) == 0)
+ return opt;
+ for (opt = general_options; opt->name != NULL; ++opt)
+ if (strcmp(name, opt->name) == 0)
+ return opt;
+ for (opt = auth_options; opt->name != NULL; ++opt)
+ if (strcmp(name, opt->name) == 0)
+ return opt;
+ for (i = 0; protocols[i] != NULL; ++i)
+ if ((opt = protocols[i]->options) != NULL)
+ for (; opt->name != NULL; ++opt)
+ if (strcmp(name, opt->name) == 0)
+ return opt;
+ return NULL;
+}
+
+/*
+ * process_option - process one new-style option.
+ */
+static int
+process_option(opt, argv)
+ option_t *opt;
+ char **argv;
+{
+ u_int32_t v;
+ int iv, a;
+ char *sv;
+ int (*parser) __P((char **));
+
+ if ((opt->flags & OPT_PREPASS) == 0 && prepass)
+ return 1;
+ if ((opt->flags & OPT_INITONLY) && pppd_phase != PHASE_INITIALIZE) {
+ option_error("it's too late to use the %s option", opt->name);
+ return 0;
+ }
+ if ((opt->flags & OPT_PRIV) && !privileged_option) {
+ option_error("using the %s option requires root privilege", opt->name);
+ return 0;
+ }
+ if ((opt->flags & OPT_ENABLE) && *(bool *)(opt->addr2) == 0) {
+ option_error("%s option is disabled", opt->name);
+ return 0;
+ }
+ if ((opt->flags & OPT_PRIVFIX) && !privileged_option) {
+ struct option_info *ip = (struct option_info *) opt->addr2;
+ if (ip && ip->priv) {
+ option_error("%s option cannot be overridden", opt->name);
+ return 0;
+ }
+ }
+
+ switch (opt->type) {
+ case o_bool:
+ v = opt->flags & OPT_VALUE;
+ *(bool *)(opt->addr) = v;
+ if (opt->addr2 && (opt->flags & OPT_A2COPY))
+ *(bool *)(opt->addr2) = v;
+ break;
+
+ case o_int:
+ iv = 0;
+ if ((opt->flags & OPT_NOARG) == 0) {
+ if (!int_option(*argv, &iv))
+ return 0;
+ if ((((opt->flags & OPT_LLIMIT) && iv < opt->lower_limit)
+ || ((opt->flags & OPT_ULIMIT) && iv > opt->upper_limit))
+ && !((opt->flags & OPT_ZEROOK && iv == 0))) {
+ char *zok = (opt->flags & OPT_ZEROOK)? " zero or": "";
+ switch (opt->flags & OPT_LIMITS) {
+ case OPT_LLIMIT:
+ option_error("%s value must be%s >= %d",
+ opt->name, zok, opt->lower_limit);
+ break;
+ case OPT_ULIMIT:
+ option_error("%s value must be%s <= %d",
+ opt->name, zok, opt->upper_limit);
+ break;
+ case OPT_LIMITS:
+ option_error("%s value must be%s between %d and %d",
+ opt->name, opt->lower_limit, opt->upper_limit);
+ break;
+ }
+ return 0;
+ }
+ }
+ a = opt->flags & OPT_VALUE;
+ if (a >= 128)
+ a -= 256; /* sign extend */
+ iv += a;
+ if (opt->flags & OPT_INC)
+ iv += *(int *)(opt->addr);
+ if ((opt->flags & OPT_NOINCR) && !privileged_option) {
+ int oldv = *(int *)(opt->addr);
+ if ((opt->flags & OPT_ZEROINF) ?
+ (oldv != 0 && (iv == 0 || iv > oldv)) : (iv > oldv)) {
+ option_error("%s value cannot be increased", opt->name);
+ return 0;
+ }
+ }
+ *(int *)(opt->addr) = iv;
+ if (opt->addr2 && (opt->flags & OPT_A2COPY))
+ *(int *)(opt->addr2) = iv;
+ break;
+
+ case o_uint32:
+ if (opt->flags & OPT_NOARG) {
+ v = opt->flags & OPT_VALUE;
+ } else if (!number_option(*argv, &v, 16))
+ return 0;
+ if (opt->flags & OPT_OR)
+ v |= *(u_int32_t *)(opt->addr);
+ *(u_int32_t *)(opt->addr) = v;
+ if (opt->addr2 && (opt->flags & OPT_A2COPY))
+ *(u_int32_t *)(opt->addr2) = v;
+ break;
+
+ case o_string:
+ if (opt->flags & OPT_STATIC) {
+ strlcpy((char *)(opt->addr), *argv, opt->upper_limit);
+ } else {
+ sv = strdup(*argv);
+ if (sv == NULL)
+ novm("option argument");
+ if ( *(char **)(opt->addr) != NULL ) {
+ free((void *)*(char **)(opt->addr));
+ *(char **)(opt->addr) = NULL;
+ }
+ *(char **)(opt->addr) = sv;
+ }
+ break;
+
+ case o_special_noarg:
+ case o_special:
+ parser = (int (*) __P((char **))) opt->addr;
+ if (!(*parser)(argv))
+ return 0;
+ break;
+ }
+
+ if (opt->addr2) {
+ if (opt->flags & OPT_A2INFO) {
+ struct option_info *ip = (struct option_info *) opt->addr2;
+ ip->priv = privileged_option;
+ ip->source = option_source;
+ } else if ((opt->flags & (OPT_A2COPY|OPT_ENABLE)) == 0)
+ *(bool *)(opt->addr2) = 1;
+ }
+
+ return 1;
+}
+
+/*
+ * n_arguments - tell how many arguments an option takes
+ */
+static int
+n_arguments(opt)
+ option_t *opt;
+{
+ return (opt->type == o_bool || opt->type == o_special_noarg
+ || (opt->flags & OPT_NOARG))? 0: 1;
+}
+
+/*
+ * add_options - add a list of options to the set we grok.
+ */
+void
+add_options(opt)
+ option_t *opt;
+{
+ struct option_list *list;
+
+ list = malloc(sizeof(*list));
+ if (list == 0)
+ novm("option list entry");
+ list->options = opt;
+ list->next = extra_options;
+ extra_options = list;
+}
+
+/*
+ * usage - print out a message telling how to use the program.
+ */
+static void
+usage()
+{
+ if (pppd_phase == PHASE_INITIALIZE)
+ fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION,
+ "rtems_pppd");
+}
+
+/*
+ * option_error - print a message about an error in an option.
+ * The message is logged, and also sent to
+ * stderr if pppd_phase == PHASE_INITIALIZE.
+ */
+void
+option_error __V((char *fmt, ...))
+{
+ va_list args;
+ char buf[256];
+
+#if defined(__STDC__)
+ va_start(args, fmt);
+#else
+ char *fmt;
+ va_start(args);
+ fmt = va_arg(args, char *);
+#endif
+ if (prepass) {
+ va_end(args);
+ return;
+ }
+ vslprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ fprintf(stderr, "pppd: %s\n", buf);
+}
+
+/*
+ * Read a word from a file.
+ * Words are delimited by white-space or by quotes (" or ').
+ * Quotes, white-space and \ may be escaped with \.
+ * \<newline> is ignored.
+ */
+int
+getword(f, word, newlinep, filename)
+ FILE *f;
+ char *word;
+ int *newlinep;
+ char *filename;
+{
+ int c, len, escape;
+ int quoted, comment;
+ int value, digit, got, n;
+
+#define isoctal(c) ((c) >= '0' && (c) < '8')
+
+ *newlinep = 0;
+ len = 0;
+ escape = 0;
+ comment = 0;
+
+ /*
+ * First skip white-space and comments.
+ */
+ for (;;) {
+ c = getc(f);
+ if (c == EOF)
+ break;
+
+ /*
+ * A newline means the end of a comment; backslash-newline
+ * is ignored. Note that we cannot have escape && comment.
+ */
+ if (c == '\n') {
+ if (!escape) {
+ *newlinep = 1;
+ comment = 0;
+ } else
+ escape = 0;
+ continue;
+ }
+
+ /*
+ * Ignore characters other than newline in a comment.
+ */
+ if (comment)
+ continue;
+
+ /*
+ * If this character is escaped, we have a word start.
+ */
+ if (escape)
+ break;
+
+ /*
+ * If this is the escape character, look at the next character.
+ */
+ if (c == '\\') {
+ escape = 1;
+ continue;
+ }
+
+ /*
+ * If this is the start of a comment, ignore the rest of the line.
+ */
+ if (c == '#') {
+ comment = 1;
+ continue;
+ }
+
+ /*
+ * A non-whitespace character is the start of a word.
+ */
+ if (!isspace(c))
+ break;
+ }
+
+ /*
+ * Save the delimiter for quoted strings.
+ */
+ if (!escape && (c == '"' || c == '\'')) {
+ quoted = c;
+ c = getc(f);
+ } else
+ quoted = 0;
+
+ /*
+ * Process characters until the end of the word.
+ */
+ while (c != EOF) {
+ if (escape) {
+ /*
+ * This character is escaped: backslash-newline is ignored,
+ * various other characters indicate particular values
+ * as for C backslash-escapes.
+ */
+ escape = 0;
+ if (c == '\n') {
+ c = getc(f);
+ continue;
+ }
+
+ got = 0;
+ switch (c) {
+ case 'a':
+ value = '\a';
+ break;
+ case 'b':
+ value = '\b';
+ break;
+ case 'f':
+ value = '\f';
+ break;
+ case 'n':
+ value = '\n';
+ break;
+ case 'r':
+ value = '\r';
+ break;
+ case 's':
+ value = ' ';
+ break;
+ case 't':
+ value = '\t';
+ break;
+
+ default:
+ if (isoctal(c)) {
+ /*
+ * \ddd octal sequence
+ */
+ value = 0;
+ for (n = 0; n < 3 && isoctal(c); ++n) {
+ value = (value << 3) + (c & 07);
+ c = getc(f);
+ }
+ got = 1;
+ break;
+ }
+
+ if (c == 'x') {
+ /*
+ * \x<hex_string> sequence
+ */
+ value = 0;
+ c = getc(f);
+ for (n = 0; n < 2 && isxdigit(c); ++n) {
+ digit = toupper(c) - '0';
+ if (digit > 10)
+ digit += '0' + 10 - 'A';
+ value = (value << 4) + digit;
+ c = getc (f);
+ }
+ got = 1;
+ break;
+ }
+
+ /*
+ * Otherwise the character stands for itself.
+ */
+ value = c;
+ break;
+ }
+
+ /*
+ * Store the resulting character for the escape sequence.
+ */
+ if (len < MAXWORDLEN-1)
+ word[len] = value;
+ ++len;
+
+ if (!got)
+ c = getc(f);
+ continue;
+
+ }
+
+ /*
+ * Not escaped: see if we've reached the end of the word.
+ */
+ if (quoted) {
+ if (c == quoted)
+ break;
+ } else {
+ if (isspace(c) || c == '#') {
+ ungetc (c, f);
+ break;
+ }
+ }
+
+ /*
+ * Backslash starts an escape sequence.
+ */
+ if (c == '\\') {
+ escape = 1;
+ c = getc(f);
+ continue;
+ }
+
+ /*
+ * An ordinary character: store it in the word and get another.
+ */
+ if (len < MAXWORDLEN-1)
+ word[len] = c;
+ ++len;
+
+ c = getc(f);
+ }
+
+ /*
+ * End of the word: check for errors.
+ */
+ if (c == EOF) {
+ if (ferror(f)) {
+ if (errno == 0)
+ errno = EIO;
+ option_error("Error reading %s: %m", filename);
+ die(1);
+ }
+ /*
+ * If len is zero, then we didn't find a word before the
+ * end of the file.
+ */
+ if (len == 0)
+ return 0;
+ }
+
+ /*
+ * Warn if the word was too long, and append a terminating null.
+ */
+ if (len >= MAXWORDLEN) {
+ option_error("warning: word in file %s too long (%.20s...)",
+ filename, word);
+ len = MAXWORDLEN - 1;
+ }
+ word[len] = 0;
+
+ return 1;
+
+#undef isoctal
+
+}
+
+/*
+ * number_option - parse an unsigned numeric parameter for an option.
+ */
+static int
+number_option(str, valp, base)
+ char *str;
+ u_int32_t *valp;
+ int base;
+{
+ char *ptr;
+
+ *valp = strtoul(str, &ptr, base);
+ if (ptr == str) {
+ option_error("invalid numeric parameter '%s' for %s option",
+ str, current_option);
+ return 0;
+ }
+ return 1;
+}
+
+
+/*
+ * int_option - like number_option, but valp is int *,
+ * the base is assumed to be 0, and *valp is not changed
+ * if there is an error.
+ */
+int
+int_option(str, valp)
+ char *str;
+ int *valp;
+{
+ u_int32_t v;
+
+ if (!number_option(str, &v, 0))
+ return 0;
+ *valp = (int) v;
+ return 1;
+}
+
+
+/*
+ * The following procedures parse options.
+ */
+
+/*
+ * readfile - take commands from a file.
+ */
+static int
+readfile(argv)
+ char **argv;
+{
+ return options_from_file(*argv, 1, 1, privileged_option);
+}
+
+/*
+ * callfile - take commands from /etc/ppp/peers/<name>.
+ * Name may not contain /../, start with / or ../, or end in /..
+ */
+static int
+callfile(argv)
+ char **argv;
+{
+ char *fname, *arg, *p;
+ int l, ok;
+
+ arg = *argv;
+ ok = 1;
+ if (arg[0] == '/' || arg[0] == 0)
+ ok = 0;
+ else {
+ for (p = arg; *p != 0; ) {
+ if (p[0] == '.' && p[1] == '.' && (p[2] == '/' || p[2] == 0)) {
+ ok = 0;
+ break;
+ }
+ while (*p != '/' && *p != 0)
+ ++p;
+ if (*p == '/')
+ ++p;
+ }
+ }
+ if (!ok) {
+ option_error("call option value may not contain .. or start with /");
+ return 0;
+ }
+
+ l = strlen(arg) + strlen(_PATH_PEERFILES) + 1;
+ if ((fname = (char *) malloc(l)) == NULL)
+ novm("call file name");
+ slprintf(fname, l, "%s%s", _PATH_PEERFILES, arg);
+
+ ok = options_from_file(fname, 1, 1, 1);
+
+ free(fname);
+ return ok;
+}
+
+#ifdef PPP_FILTER
+/*
+ * setpdebug - Set libpcap debugging level.
+ */
+static int
+setpdebug(argv)
+ char **argv;
+{
+ return int_option(*argv, &dflag);
+}
+
+/*
+ * setpassfilter - Set the pass filter for packets
+ */
+static int
+setpassfilter(argv)
+ char **argv;
+{
+ pc.linktype = DLT_PPP;
+ pc.snapshot = PPP_HDRLEN;
+
+ if (pcap_compile(&pc, &pass_filter, *argv, 1, netmask) == 0)
+ return 1;
+ option_error("error in pass-filter expression: %s\n", pcap_geterr(&pc));
+ return 0;
+}
+
+/*
+ * setactivefilter - Set the active filter for packets
+ */
+static int
+setactivefilter(argv)
+ char **argv;
+{
+ pc.linktype = DLT_PPP;
+ pc.snapshot = PPP_HDRLEN;
+
+ if (pcap_compile(&pc, &active_filter, *argv, 1, netmask) == 0)
+ return 1;
+ option_error("error in active-filter expression: %s\n", pcap_geterr(&pc));
+ return 0;
+}
+#endif
+
+/*
+ * noopt - Disable all options.
+ */
+static int
+noopt(argv)
+ char **argv;
+{
+ BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
+ BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
+ BZERO((char *) &ipcp_wantoptions[0], sizeof (struct ipcp_options));
+ BZERO((char *) &ipcp_allowoptions[0], sizeof (struct ipcp_options));
+
+ return (1);
+}
+
+/*
+ * setdomain - Set domain name to append to hostname
+ */
+static int
+setdomain(argv)
+ char **argv;
+{
+ if (!privileged_option) {
+ option_error("using the domain option requires root privilege");
+ return 0;
+ }
+ gethostname(hostname, MAXNAMELEN);
+ if (**argv != 0) {
+ if (**argv != '.')
+ strncat(hostname, ".", MAXNAMELEN - strlen(hostname));
+ strncat(hostname, *argv, MAXNAMELEN - strlen(hostname));
+ }
+ hostname[MAXNAMELEN-1] = 0;
+ return (1);
+}
+
+
+/*
+ * setspeed - Set the speed.
+ */
+static int
+setspeed(arg)
+ char *arg;
+{
+ int spd;
+ int ret = (int )1;
+ speed_t spdValue = (speed_t)0;
+ char *ptr;
+
+ if ( !prepass ) {
+ spd = strtol(arg, &ptr, 0);
+ if (ptr == arg || *ptr != 0 || spd == 0) {
+ ret = (int)0;
+ }
+ else {
+ switch ( spd ) {
+ case 2400:
+ spdValue = B2400;
+ break;
+ case 4800:
+ spdValue = B4800;
+ break;
+ case 9600:
+ spdValue = B9600;
+ break;
+ case 19200:
+ spdValue = B19200;
+ break;
+ case 38400:
+ spdValue = B38400;
+ break;
+ case 57600:
+ spdValue = B57600;
+ break;
+ case 115200:
+ spdValue = B115200;
+ break;
+ default:
+ ret = (int)0;
+ break;
+ }
+
+ if ( spdValue ) {
+ inspeed = spdValue;
+ }
+ }
+ }
+
+ return ( ret );
+}
+
+
+/*
+ * setdevname - Set the device name.
+ */
+static int
+setdevname(cp)
+ char *cp;
+{
+ struct stat statbuf;
+ char dev[MAXPATHLEN];
+
+ if (*cp == 0)
+ return 0;
+
+ if (strncmp("/dev/", cp, 5) != 0) {
+ strlcpy(dev, "/dev/", sizeof(dev));
+ strlcat(dev, cp, sizeof(dev));
+ cp = dev;
+ }
+
+ /*
+ * Check if there is a character device by this name.
+ */
+ if (stat(cp, &statbuf) < 0) {
+ if (errno == ENOENT)
+ return 0;
+ option_error("Couldn't stat %s: %m", cp);
+ return -1;
+ }
+ if (!S_ISCHR(statbuf.st_mode)) {
+ option_error("%s is not a character device", cp);
+ return -1;
+ }
+
+ if (pppd_phase != PHASE_INITIALIZE) {
+ option_error("device name cannot be changed after initialization");
+ return -1;
+ } else if (devnam_fixed) {
+ option_error("per-tty options file may not specify device name");
+ return -1;
+ }
+
+ if (devnam_info.priv && !privileged_option) {
+ option_error("device name cannot be overridden");
+ return -1;
+ }
+
+ strlcpy(devnam, cp, sizeof(devnam));
+ devstat = statbuf;
+ default_device = 0;
+ devnam_info.priv = privileged_option;
+ devnam_info.source = option_source;
+
+ return 1;
+}
+
+
+/*
+ * setipaddr - Set the IP address
+ */
+static int
+setipaddr(arg)
+ char *arg;
+{
+ struct hostent *hp;
+ char *colon;
+ u_int32_t local, remote;
+ ipcp_options *wo = &ipcp_wantoptions[0];
+
+ /*
+ * IP address pair separated by ":".
+ */
+ if ((colon = strchr(arg, ':')) == NULL)
+ return 0;
+ if (prepass)
+ return 1;
+
+ /*
+ * If colon first character, then no local addr.
+ */
+ if (colon != arg) {
+ *colon = '\0';
+ if ((local = inet_addr(arg)) == (u_int32_t) -1) {
+ if ((hp = gethostbyname(arg)) == NULL) {
+ option_error("unknown host: %s", arg);
+ return -1;
+ } else {
+ local = *(u_int32_t *)hp->h_addr;
+ }
+ }
+ if (bad_ip_adrs(local)) {
+ option_error("bad local IP address %s", ip_ntoa(local));
+ return -1;
+ }
+ if (local != 0)
+ wo->ouraddr = local;
+ *colon = ':';
+ }
+
+ /*
+ * If colon last character, then no remote addr.
+ */
+ if (*++colon != '\0') {
+ if ((remote = inet_addr(colon)) == (u_int32_t) -1) {
+ if ((hp = gethostbyname(colon)) == NULL) {
+ option_error("unknown host: %s", colon);
+ return -1;
+ } else {
+ remote = *(u_int32_t *)hp->h_addr;
+ if (remote_name[0] == 0)
+ strlcpy(remote_name, colon, sizeof(remote_name));
+ }
+ }
+ if (bad_ip_adrs(remote)) {
+ option_error("bad remote IP address %s", ip_ntoa(remote));
+ return -1;
+ }
+ if (remote != 0)
+ wo->hisaddr = remote;
+ }
+
+ return 1;
+}
+
+
+/*
+ * setnetmask - set the netmask to be used on the interface.
+ */
+static int
+setnetmask(argv)
+ char **argv;
+{
+ u_int32_t mask, b;
+ int n, ok;
+ char *p, *endp;
+
+ /*
+ * Unfortunately, if we use inet_addr, we can't tell whether
+ * a result of all 1s is an error or a valid 255.255.255.255.
+ */
+ p = *argv;
+ ok = 0;
+ mask = 0;
+ for (n = 3;; --n) {
+ b = strtoul(p, &endp, 0);
+ if (endp == p)
+ break;
+ if (b > 255) {
+ if (n == 3) {
+ /* accept e.g. 0xffffff00 */
+ p = endp;
+ mask = b;
+ }
+ break;
+ }
+ mask |= b << (n * 8);
+ p = endp;
+ if (*p != '.' || n == 0)
+ break;
+ ++p;
+ }
+
+ mask = htonl(mask);
+
+ if (*p != 0 || (netmask & ~mask) != 0) {
+ option_error("invalid netmask value '%s'", *argv);
+ return 0;
+ }
+
+ netmask = mask;
+ return (1);
+}
+
+static int
+setxonxoff(argv)
+ char **argv;
+{
+ lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */
+ lcp_wantoptions[0].neg_asyncmap = 1;
+
+ crtscts = -2;
+ return (1);
+}
+
+static int
+setlogfile(argv)
+ char **argv;
+{
+ int fd, err;
+
+ fd = open(*argv, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0644);
+ if (fd < 0 && errno == EEXIST)
+ fd = open(*argv, O_WRONLY | O_APPEND);
+ err = errno;
+ if (fd < 0) {
+ errno = err;
+ option_error("Can't open log file %s: %m", *argv);
+ return 0;
+ }
+ if (log_to_file && log_to_fd >= 0)
+ close(log_to_fd);
+ log_to_fd = fd;
+ log_to_file = 1;
+ return 1;
+}
+
+#ifdef PLUGIN
+static int
+loadplugin(argv)
+ char **argv;
+{
+ char *arg = *argv;
+ void *handle;
+ const char *err;
+ void (*init) __P((void));
+
+ handle = dlopen(arg, RTLD_GLOBAL | RTLD_NOW);
+ if (handle == 0) {
+ err = dlerror();
+ if (err != 0)
+ option_error("%s", err);
+ option_error("Couldn't load plugin %s", arg);
+ return 0;
+ }
+ init = dlsym(handle, "plugin_init");
+ if (init == 0) {
+ option_error("%s has no initialization entry point", arg);
+ dlclose(handle);
+ return 0;
+ }
+ info("Plugin %s loaded.", arg);
+ (*init)();
+ return 1;
+}
+#endif /* PLUGIN */
diff --git a/cpukit/pppd/patchlevel.h b/cpukit/pppd/patchlevel.h
new file mode 100644
index 0000000000..54d88b8a66
--- /dev/null
+++ b/cpukit/pppd/patchlevel.h
@@ -0,0 +1,6 @@
+/* $Id$ */
+#define PATCHLEVEL 11
+
+#define VERSION "2.3"
+#define IMPLEMENTATION ""
+#define DATE "23 December 1999"
diff --git a/cpukit/pppd/pathnames.h b/cpukit/pppd/pathnames.h
new file mode 100644
index 0000000000..0a4f6e69f2
--- /dev/null
+++ b/cpukit/pppd/pathnames.h
@@ -0,0 +1,43 @@
+/*
+ * define path names
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+
+#else
+#ifndef _PATH_VARRUN
+#define _PATH_VARRUN "/etc/ppp/"
+#endif
+#define _PATH_DEVNULL "/dev/null"
+#endif
+
+#ifndef _ROOT_PATH
+#define _ROOT_PATH
+#endif
+
+#define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets"
+#define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets"
+#define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options"
+#define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up"
+#define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down"
+#define _PATH_AUTHUP _ROOT_PATH "/etc/ppp/auth-up"
+#define _PATH_AUTHDOWN _ROOT_PATH "/etc/ppp/auth-down"
+#define _PATH_TTYOPT _ROOT_PATH "/etc/ppp/options."
+#define _PATH_CONNERRS _ROOT_PATH "/etc/ppp/connect-errors"
+#define _PATH_PEERFILES _ROOT_PATH "/etc/ppp/peers/"
+#define _PATH_RESOLV _ROOT_PATH "/etc/ppp/resolv.conf"
+
+#define _PATH_USEROPT ".ppprc"
+
+#ifdef INET6
+#define _PATH_IPV6UP _ROOT_PATH "/etc/ppp/ipv6-up"
+#define _PATH_IPV6DOWN _ROOT_PATH "/etc/ppp/ipv6-down"
+#endif
+
+#ifdef IPX_CHANGE
+#define _PATH_IPXUP _ROOT_PATH "/etc/ppp/ipx-up"
+#define _PATH_IPXDOWN _ROOT_PATH "/etc/ppp/ipx-down"
+#endif /* IPX_CHANGE */
diff --git a/cpukit/pppd/pppd.8 b/cpukit/pppd/pppd.8
new file mode 100644
index 0000000000..227345ff5f
--- /dev/null
+++ b/cpukit/pppd/pppd.8
@@ -0,0 +1,1480 @@
+.\" manual page [] for pppd 2.3
+.\" $Id$
+.\" SH section heading
+.\" SS subsection heading
+.\" LP paragraph
+.\" IP indented paragraph
+.\" TP hanging label
+.TH PPPD 8
+.SH NAME
+pppd \- Point to Point Protocol daemon
+.SH SYNOPSIS
+.B pppd
+[
+.I tty_name
+] [
+.I speed
+] [
+.I options
+]
+.SH DESCRIPTION
+.LP
+The Point-to-Point Protocol (PPP) provides a method for transmitting
+datagrams over serial point-to-point links. PPP
+is composed of three parts: a method for encapsulating datagrams over
+serial links, an extensible Link Control Protocol (LCP), and
+a family of Network Control Protocols (NCP) for establishing
+and configuring different network-layer protocols.
+.LP
+The encapsulation scheme is provided by driver code in the kernel.
+Pppd provides the basic LCP, authentication support, and an NCP for
+establishing and configuring the Internet Protocol (IP) (called the IP
+Control Protocol, IPCP).
+.SH FREQUENTLY USED OPTIONS
+.TP
+.I <tty_name>
+Communicate over the named device. The string "/dev/" is prepended if
+necessary. If no device name is given, or if the name of the terminal
+connected to the standard input is given, pppd will use that terminal,
+and will not fork to put itself in the background. A value for this
+option from a privileged source cannot be overridden by a
+non-privileged user.
+.TP
+.I <speed>
+Set the baud rate to <speed> (a decimal number). On systems such as
+4.4BSD and NetBSD, any speed can be specified. Other systems
+(e.g. SunOS) allow only a limited set of speeds.
+.TP
+.B asyncmap \fI<map>
+Set the async character map to <map>. This map describes which
+control characters cannot be successfully received over the serial
+line. Pppd will ask the peer to send these characters as a 2-byte
+escape sequence. The argument is a 32 bit hex number with each bit
+representing a character to escape. Bit 0 (00000001) represents the
+character 0x00; bit 31 (80000000) represents the character 0x1f or ^_.
+If multiple \fIasyncmap\fR options are given, the values are ORed
+together. If no \fIasyncmap\fR option is given, no async character
+map will be negotiated for the receive direction; the peer should then
+escape \fIall\fR control characters. To escape transmitted
+characters, use the \fIescape\fR option.
+.TP
+.B auth
+Require the peer to authenticate itself before allowing network
+packets to be sent or received. This option is the default if the
+system has a default route. If neither this option nor the
+\fInoauth\fR option is specified, pppd will only allow the peer to use
+IP addresses to which the system does not already have a route.
+.TP
+.B call \fIname
+Read options from the file /etc/ppp/peers/\fIname\fR. This file may
+contain privileged options, such as \fInoauth\fR, even if pppd
+is not being run by root. The \fIname\fR string may not begin with /
+or include .. as a pathname component. The format of the options file
+is described below.
+.TP
+.B connect \fIscript
+Use the executable or shell command specified by \fIscript\fR to set
+up the serial line. This script would typically use the chat(8)
+program to dial the modem and start the remote ppp session. A value
+for this option from a privileged source cannot be overridden by a
+non-privileged user.
+.TP
+.B crtscts
+Use hardware flow control (i.e. RTS/CTS) to control the flow of
+data on the serial port. If neither the \fIcrtscts\fR, the
+\fInocrtscts\fR, the \fIcdtrcts\fR nor the \fInocdtrcts\fR option
+is given, the hardware flow control setting for the serial port is
+left unchanged.
+Some serial ports (such as Macintosh serial ports) lack a true
+RTS output. Such serial ports use this mode to implement
+unidirectional flow control. The serial port will
+suspend transmission when requested by the modem (via CTS)
+but will be unable to request the modem stop sending to the
+computer. This mode retains the ability to use DTR as
+a modem control line.
+.TP
+.B defaultroute
+Add a default route to the system routing tables, using the peer as
+the gateway, when IPCP negotiation is successfully completed.
+This entry is removed when the PPP connection is broken. This option
+is privileged if the \fInodefaultroute\fR option has been specified.
+.TP
+.B disconnect \fIscript
+Run the executable or shell command specified by \fIscript\fR after
+pppd has terminated the link. This script could, for example, issue
+commands to the modem to cause it to hang up if hardware modem control
+signals were not available. The disconnect script is not run if the
+modem has already hung up. A value for this option from a privileged
+source cannot be overridden by a non-privileged user.
+.TP
+.B escape \fIxx,yy,...
+Specifies that certain characters should be escaped on transmission
+(regardless of whether the peer requests them to be escaped with its
+async control character map). The characters to be escaped are
+specified as a list of hex numbers separated by commas. Note that
+almost any character can be specified for the \fIescape\fR option,
+unlike the \fIasyncmap\fR option which only allows control characters
+to be specified. The characters which may not be escaped are those
+with hex values 0x20 - 0x3f or 0x5e.
+.TP
+.B file \fIname
+Read options from file \fIname\fR (the format is described below).
+The file must be readable by the user who has invoked pppd.
+.TP
+.B init \fIscript
+Run the executable or shell command specified by \fIscript\fR to
+initialize the serial line. This script would typically use the
+chat(8) program to configure the modem to enable auto answer. A value
+for this option from a privileged source cannot be overridden by a
+non-privileged user.
+.TP
+.B lock
+Specifies that pppd should create a UUCP-style lock file for the
+serial device to ensure exclusive access to the device.
+.TP
+.B mru \fIn
+Set the MRU [Maximum Receive Unit] value to \fIn\fR. Pppd
+will ask the peer to send packets of no more than \fIn\fR bytes. The
+minimum MRU value is 128. The default MRU value is 1500. A value of
+296 is recommended for slow links (40 bytes for TCP/IP header + 256
+bytes of data). (Note that for IPv6 MRU must be at least 1280)
+.TP
+.B mtu \fIn
+Set the MTU [Maximum Transmit Unit] value to \fIn\fR. Unless the
+peer requests a smaller value via MRU negotiation, pppd will
+request that the kernel networking code send data packets of no more
+than \fIn\fR bytes through the PPP network interface. (Note that for
+IPv6 MTU must be at least 1280)
+.TP
+.B passive
+Enables the "passive" option in the LCP. With this option, pppd will
+attempt to initiate a connection; if no reply is received from the
+peer, pppd will then just wait passively for a valid LCP packet from
+the peer, instead of exiting, as it would without this option.
+.SH OPTIONS
+.TP
+.I <local_IP_address>\fB:\fI<remote_IP_address>
+Set the local and/or remote interface IP addresses. Either one may be
+omitted. The IP addresses can be specified with a host name or in
+decimal dot notation (e.g. 150.234.56.78). The default local
+address is the (first) IP address of the system (unless the
+\fInoipdefault\fR
+option is given). The remote address will be obtained from the peer
+if not specified in any option. Thus, in simple cases, this option is
+not required. If a local and/or remote IP address is specified with
+this option, pppd
+will not accept a different value from the peer in the IPCP
+negotiation, unless the \fIipcp-accept-local\fR and/or
+\fIipcp-accept-remote\fR options are given, respectively.
+.TP
+.B ipv6 \fI<local_interface_identifier>\fR,\fI<remote_interface_identifier>
+Set the local and/or remote 64-bit interface identifier. Either one may be
+omitted. The identifier must be specified in standard ascii notation of
+IPv6 addresses (e.g. ::dead:beef). If the
+\fIipv6cp-use-ipaddr\fR
+option is given, the local identifier is the local IPv4 address (see above).
+On systems which supports a unique persistent id, such as EUI-48 derived
+from the Ethernet MAC address, \fIipv6cp-use-persistent\fR option can be
+used to replace the \fIipv6 <local>,<remote>\fR option. Otherwise the
+identifier is randomized.
+.TP
+.B active-filter \fIfilter-expression
+Specifies a packet filter to be applied to data packets to determine
+which packets are to be regarded as link activity, and therefore reset
+the idle timer, or cause the link to be brought up in demand-dialling
+mode. This option is useful in conjunction with the
+\fBidle\fR option if there are packets being sent or received
+regularly over the link (for example, routing information packets)
+which would otherwise prevent the link from ever appearing to be idle.
+The \fIfilter-expression\fR syntax is as described for tcpdump(1),
+except that qualifiers which are inappropriate for a PPP link, such as
+\fBether\fR and \fBarp\fR, are not permitted. Generally the filter
+expression should be enclosed in single-quotes to prevent whitespace
+in the expression from being interpreted by the shell. This option
+is currently only available under NetBSD, and then only
+if both the kernel and pppd were compiled with PPP_FILTER defined.
+.TP
+.B allow-ip \fIaddress(es)
+Allow peers to use the given IP address or subnet without
+authenticating themselves. The parameter is parsed as for each
+element of the list of allowed IP addresses in the secrets files (see
+the AUTHENTICATION section below).
+.TP
+.B bsdcomp \fInr,nt
+Request that the peer compress packets that it sends, using the
+BSD-Compress scheme, with a maximum code size of \fInr\fR bits, and
+agree to compress packets sent to the peer with a maximum code size of
+\fInt\fR bits. If \fInt\fR is not specified, it defaults to the value
+given for \fInr\fR. Values in the range 9 to 15 may be used for
+\fInr\fR and \fInt\fR; larger values give better compression but
+consume more kernel memory for compression dictionaries.
+Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables
+compression in the corresponding direction. Use \fInobsdcomp\fR or
+\fIbsdcomp 0\fR to disable BSD-Compress compression entirely.
+.TP
+.B cdtrcts
+Use a non-standard hardware flow control (i.e. DTR/CTS) to control
+the flow of data on the serial port. If neither the \fIcrtscts\fR,
+the \fInocrtscts\fR, the \fIcdtrcts\fR nor the \fInocdtrcts\fR
+option is given, the hardware flow control setting for the serial
+port is left unchanged.
+Some serial ports (such as Macintosh serial ports) lack a true
+RTS output. Such serial ports use this mode to implement true
+bi-directional flow control. The sacrifice is that this flow
+control mode does not permit using DTR as a modem control line.
+.TP
+.B chap-interval \fIn
+If this option is given, pppd will rechallenge the peer every \fIn\fR
+seconds.
+.TP
+.B chap-max-challenge \fIn
+Set the maximum number of CHAP challenge transmissions to \fIn\fR
+(default 10).
+.TP
+.B chap-restart \fIn
+Set the CHAP restart interval (retransmission timeout for challenges)
+to \fIn\fR seconds (default 3).
+.TP
+.B connect-delay \fIn
+Wait for up \fIn\fR milliseconds after the connect script finishes for
+a valid PPP packet from the peer. At the end of this time, or when a
+valid PPP packet is received from the peer, pppd will commence
+negotiation by sending its first LCP packet. The default value is
+1000 (1 second). This wait period only applies if the \fBconnect\fR
+or \fBpty\fR option is used.
+.TP
+.B debug
+Enables connection debugging facilities.
+If this option is given, pppd will log the contents of all
+control packets sent or received in a readable form. The packets are
+logged through syslog with facility \fIdaemon\fR and level
+\fIdebug\fR. This information can be directed to a file by setting up
+/etc/syslog.conf appropriately (see syslog.conf(5)).
+.TP
+.B default-asyncmap
+Disable asyncmap negotiation, forcing all control characters to be
+escaped for both the transmit and the receive direction.
+.TP
+.B default-mru
+Disable MRU [Maximum Receive Unit] negotiation. With this option,
+pppd will use the default MRU value of 1500 bytes for both the
+transmit and receive direction.
+.TP
+.B deflate \fInr,nt
+Request that the peer compress packets that it sends, using the
+Deflate scheme, with a maximum window size of \fI2**nr\fR bytes, and
+agree to compress packets sent to the peer with a maximum window size
+of \fI2**nt\fR bytes. If \fInt\fR is not specified, it defaults to
+the value given for \fInr\fR. Values in the range 8 to 15 may be used
+for \fInr\fR and \fInt\fR; larger values give better compression but
+consume more kernel memory for compression dictionaries.
+Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables
+compression in the corresponding direction. Use \fInodeflate\fR or
+\fIdeflate 0\fR to disable Deflate compression entirely. (Note: pppd
+requests Deflate compression in preference to BSD-Compress if the peer
+can do either.)
+.TP
+.B demand
+Initiate the link only on demand, i.e. when data traffic is present.
+With this option, the remote IP address must be specified by the user
+on the command line or in an options file. Pppd will initially
+configure the interface and enable it for IP traffic without
+connecting to the peer. When traffic is available, pppd will
+connect to the peer and perform negotiation, authentication, etc.
+When this is completed, pppd will commence passing data packets
+(i.e., IP packets) across the link.
+
+The \fIdemand\fR option implies the \fIpersist\fR option. If this
+behaviour is not desired, use the \fInopersist\fR option after the
+\fIdemand\fR option. The \fIidle\fR and \fIholdoff\fR
+options are also useful in conjuction with the \fIdemand\fR option.
+.TP
+.B domain \fId
+Append the domain name \fId\fR to the local host name for authentication
+purposes. For example, if gethostname() returns the name porsche, but
+the fully qualified domain name is porsche.Quotron.COM, you could
+specify \fIdomain Quotron.COM\fR. Pppd would then use the name
+\fIporsche.Quotron.COM\fR for looking up secrets in the secrets file,
+and as the default name to send to the peer when authenticating itself
+to the peer. This option is privileged.
+.TP
+.B hide-password
+When logging the contents of PAP packets, this option causes pppd to
+exclude the password string from the log. This is the default.
+.TP
+.B holdoff \fIn
+Specifies how many seconds to wait before re-initiating the link after
+it terminates. This option only has any effect if the \fIpersist\fR
+or \fIdemand\fR option is used. The holdoff period is not applied if
+the link was terminated because it was idle.
+.TP
+.B idle \fIn
+Specifies that pppd should disconnect if the link is idle for \fIn\fR
+seconds. The link is idle when no data packets (i.e. IP packets) are
+being sent or received. Note: it is not advisable to use this option
+with the \fIpersist\fR option without the \fIdemand\fR option.
+If the \fBactive-filter\fR
+option is given, data packets which are rejected by the specified
+activity filter also count as the link being idle.
+.TP
+.B ipcp-accept-local
+With this option, pppd will accept the peer's idea of our local IP
+address, even if the local IP address was specified in an option.
+.TP
+.B ipcp-accept-remote
+With this option, pppd will accept the peer's idea of its (remote) IP
+address, even if the remote IP address was specified in an option.
+.TP
+.B ipcp-max-configure \fIn
+Set the maximum number of IPCP configure-request transmissions to
+\fIn\fR (default 10).
+.TP
+.B ipcp-max-failure \fIn
+Set the maximum number of IPCP configure-NAKs returned before starting
+to send configure-Rejects instead to \fIn\fR (default 10).
+.TP
+.B ipcp-max-terminate \fIn
+Set the maximum number of IPCP terminate-request transmissions to
+\fIn\fR (default 3).
+.TP
+.B ipcp-restart \fIn
+Set the IPCP restart interval (retransmission timeout) to \fIn\fR
+seconds (default 3).
+.TP
+.B ipparam \fIstring
+Provides an extra parameter to the ip-up and ip-down scripts. If this
+option is given, the \fIstring\fR supplied is given as the 6th
+parameter to those scripts.
+.TP
+.B ipv6cp-max-configure \fIn
+Set the maximum number of IPv6CP configure-request transmissions to
+\fIn\fR (default 10).
+.TP
+.B ipv6cp-max-failure \fIn
+Set the maximum number of IPv6CP configure-NAKs returned before starting
+to send configure-Rejects instead to \fIn\fR (default 10).
+.TP
+.B ipv6cp-max-terminate \fIn
+Set the maximum number of IPv6CP terminate-request transmissions to
+\fIn\fR (default 3).
+.TP
+.B ipv6cp-restart \fIn
+Set the IPv6CP restart interval (retransmission timeout) to \fIn\fR
+seconds (default 3).
+.TP
+.B ipx
+Enable the IPXCP and IPX protocols. This option is presently only
+supported under Linux, and only if your kernel has been configured to
+include IPX support.
+.TP
+.B ipx-network \fIn
+Set the IPX network number in the IPXCP configure request frame to
+\fIn\fR, a hexadecimal number (without a leading 0x). There is no
+valid default. If this option is not specified, the network number is
+obtained from the peer. If the peer does not have the network number,
+the IPX protocol will not be started.
+.TP
+.B ipx-node \fIn\fB:\fIm
+Set the IPX node numbers. The two node numbers are separated from each
+other with a colon character. The first number \fIn\fR is the local
+node number. The second number \fIm\fR is the peer's node number. Each
+node number is a hexadecimal number, at most 10 digits long. The node
+numbers on the ipx-network must be unique. There is no valid
+default. If this option is not specified then the node numbers are
+obtained from the peer.
+.TP
+.B ipx-router-name \fI<string>
+Set the name of the router. This is a string and is sent to the peer
+as information data.
+.TP
+.B ipx-routing \fIn
+Set the routing protocol to be received by this option. More than one
+instance of \fIipx-routing\fR may be specified. The '\fInone\fR'
+option (0) may be specified as the only instance of ipx-routing. The
+values may be \fI0\fR for \fINONE\fR, \fI2\fR for \fIRIP/SAP\fR, and
+\fI4\fR for \fINLSP\fR.
+.TP
+.B ipxcp-accept-local
+Accept the peer's NAK for the node number specified in the ipx-node
+option. If a node number was specified, and non-zero, the default is
+to insist that the value be used. If you include this option then you
+will permit the peer to override the entry of the node number.
+.TP
+.B ipxcp-accept-network
+Accept the peer's NAK for the network number specified in the
+ipx-network option. If a network number was specified, and non-zero, the
+default is to insist that the value be used. If you include this
+option then you will permit the peer to override the entry of the node
+number.
+.TP
+.B ipxcp-accept-remote
+Use the peer's network number specified in the configure request
+frame. If a node number was specified for the peer and this option was
+not specified, the peer will be forced to use the value which you have
+specified.
+.TP
+.B ipxcp-max-configure \fIn
+Set the maximum number of IPXCP configure request frames which the
+system will send to \fIn\fR. The default is 10.
+.TP
+.B ipxcp-max-failure \fIn
+Set the maximum number of IPXCP NAK frames which the local system will
+send before it rejects the options. The default value is 3.
+.TP
+.B ipxcp-max-terminate \fIn
+Set the maximum nuber of IPXCP terminate request frames before the
+local system considers that the peer is not listening to them. The
+default value is 3.
+.TP
+.B kdebug \fIn
+Enable debugging code in the kernel-level PPP driver. The argument
+\fIn\fR is a number which is the sum of the following values: 1 to
+enable general debug messages, 2 to request that the contents of
+received packets be printed, and 4 to request that the contents of
+transmitted packets be printed. On most systems, messages printed by
+the kernel are logged by syslog(1) to a file as directed in the
+/etc/syslog.conf configuration file.
+.TP
+.B ktune
+Enables pppd to alter kernel settings as appropriate. Under Linux,
+pppd will enable IP forwarding (i.e. set /proc/sys/net/ipv4/ip_forward
+to 1) if the \fIproxyarp\fR option is used, and will enable the
+dynamic IP address option (i.e. set /proc/sys/net/ipv4/ip_dynaddr to
+1) in demand mode if the local address changes.
+.TP
+.B lcp-echo-failure \fIn
+If this option is given, pppd will presume the peer to be dead
+if \fIn\fR LCP echo-requests are sent without receiving a valid LCP
+echo-reply. If this happens, pppd will terminate the
+connection. Use of this option requires a non-zero value for the
+\fIlcp-echo-interval\fR parameter. This option can be used to enable
+pppd to terminate after the physical connection has been broken
+(e.g., the modem has hung up) in situations where no hardware modem
+control lines are available.
+.TP
+.B lcp-echo-interval \fIn
+If this option is given, pppd will send an LCP echo-request frame to
+the peer every \fIn\fR seconds. Normally the peer should respond to
+the echo-request by sending an echo-reply. This option can be used
+with the \fIlcp-echo-failure\fR option to detect that the peer is no
+longer connected.
+.TP
+.B lcp-max-configure \fIn
+Set the maximum number of LCP configure-request transmissions to
+\fIn\fR (default 10).
+.TP
+.B lcp-max-failure \fIn
+Set the maximum number of LCP configure-NAKs returned before starting
+to send configure-Rejects instead to \fIn\fR (default 10).
+.TP
+.B lcp-max-terminate \fIn
+Set the maximum number of LCP terminate-request transmissions to
+\fIn\fR (default 3).
+.TP
+.B lcp-restart \fIn
+Set the LCP restart interval (retransmission timeout) to \fIn\fR
+seconds (default 3).
+.TP
+.B linkname \fIname\fR
+Sets the logical name of the link to \fIname\fR. Pppd will create a
+file named \fBppp-\fIname\fB.pid\fR in /var/run (or /etc/ppp on some
+systems) containing its process ID. This can be useful in determining
+which instance of pppd is responsible for the link to a given peer
+system. This is a privileged option.
+.TP
+.B local
+Don't use the modem control lines. With this option, pppd will ignore
+the state of the CD (Carrier Detect) signal from the modem and will
+not change the state of the DTR (Data Terminal Ready) signal.
+.TP
+.B logfd \fIn
+Send log messages to file descriptor \fIn\fR. Pppd will send log
+messages to at most one file or file descriptor (as well as sending
+the log messages to syslog), so this option and the \fBlogfile\fR
+option are mutually exclusive. The default is for pppd to send log
+messages to stdout (file descriptor 1), unless the serial port is
+already open on stdout.
+.TP
+.B logfile \fIfilename
+Append log messages to the file \fIfilename\fR (as well as sending the
+log messages to syslog). The file is opened with the privileges of
+the user who invoked pppd, in append mode.
+.TP
+.B login
+Use the system password database for authenticating the peer using
+PAP, and record the user in the system wtmp file. Note that the peer
+must have an entry in the /etc/ppp/pap-secrets file as well as the
+system password database to be allowed access.
+.TP
+.B maxconnect \fIn
+Terminate the connection when it has been available for network
+traffic for \fIn\fR seconds (i.e. \fIn\fR seconds after the first
+network control protocol comes up).
+.TP
+.B maxfail \fIn
+Terminate after \fIn\fR consecutive failed connection attempts. A
+value of 0 means no limit. The default value is 10.
+.TP
+.B modem
+Use the modem control lines. This option is the default. With this
+option, pppd will wait for the CD (Carrier Detect) signal from the
+modem to be asserted when opening the serial device (unless a connect
+script is specified), and it will drop the DTR (Data Terminal Ready)
+signal briefly when the connection is terminated and before executing
+the connect script. On Ultrix, this option implies hardware flow
+control, as for the \fIcrtscts\fR option.
+.TP
+.B ms-dns \fI<addr>
+If pppd is acting as a server for Microsoft Windows clients, this
+option allows pppd to supply one or two DNS (Domain Name Server)
+addresses to the clients. The first instance of this option specifies
+the primary DNS address; the second instance (if given) specifies the
+secondary DNS address. (This option was present in some older
+versions of pppd under the name \fBdns-addr\fR.)
+.TP
+.B ms-wins \fI<addr>
+If pppd is acting as a server for Microsoft Windows or "Samba"
+clients, this option allows pppd to supply one or two WINS (Windows
+Internet Name Services) server addresses to the clients. The first
+instance of this option specifies the primary WINS address; the second
+instance (if given) specifies the secondary WINS address.
+.TP
+.B name \fIname
+Set the name of the local system for authentication purposes to
+\fIname\fR. This is a privileged option. With this option, pppd will
+use lines in the secrets files which have \fIname\fR as the second
+field when looking for a secret to use in authenticating the peer. In
+addition, unless overridden with the \fIuser\fR option, \fIname\fR
+will be used as the name to send to the peer when authenticating the
+local system to the peer. (Note that pppd does not append the domain
+name to \fIname\fR.)
+.TP
+.B netmask \fIn
+Set the interface netmask to \fIn\fR, a 32 bit netmask in "decimal dot"
+notation (e.g. 255.255.255.0). If this option is given, the value
+specified is ORed with the default netmask. The default netmask is
+chosen based on the negotiated remote IP address; it is the
+appropriate network mask for the class of the remote IP address, ORed
+with the netmasks for any non point-to-point network interfaces in the
+system which are on the same network. (Note: on some platforms, pppd
+will always use 255.255.255.255 for the netmask, if that is the only
+appropriate value for a point-to-point interface.)
+.TP
+.B noaccomp
+Disable Address/Control compression in both directions (send and
+receive).
+.TP
+.B noauth
+Do not require the peer to authenticate itself. This option is
+privileged.
+.TP
+.B nobsdcomp
+Disables BSD-Compress compression; \fBpppd\fR will not request or
+agree to compress packets using the BSD-Compress scheme.
+.TP
+.B noccp
+Disable CCP (Compression Control Protocol) negotiation. This option
+should only be required if the peer is buggy and gets confused by
+requests from pppd for CCP negotiation.
+.TP
+.B nocrtscts
+Disable hardware flow control (i.e. RTS/CTS) on the serial port.
+If neither the \fIcrtscts\fR nor the \fInocrtscts\fR nor the
+\fIcdtrcts\fR nor the \fInodtrcts\fR option is given, the hardware
+flow control setting for the serial port is left unchanged.
+.TP
+.B nodtrcts
+This option is a synonym for \fInocrtscts\fR. Either of these options will
+disable both forms of hardware flow control.
+.TP
+.B nodefaultroute
+Disable the \fIdefaultroute\fR option. The system administrator who
+wishes to prevent users from creating default routes with pppd
+can do so by placing this option in the /etc/ppp/options file.
+.TP
+.B nodeflate
+Disables Deflate compression; pppd will not request or agree to
+compress packets using the Deflate scheme.
+.TP
+.B nodetach
+Don't detach from the controlling terminal. Without this option, if a
+serial device other than the terminal on the standard input is
+specified, pppd will fork to become a background process.
+.TP
+.B noip
+Disable IPCP negotiation and IP communication. This option should
+only be required if the peer is buggy and gets confused by requests
+from pppd for IPCP negotiation.
+.TP
+.B noipv6
+Disable IPv6CP negotiation and IPv6 communication. This option should
+only be required if the peer is buggy and gets confused by requests
+from pppd for IPv6CP negotiation.
+.TP
+.B noipdefault
+Disables the default behaviour when no local IP address is specified,
+which is to determine (if possible) the local IP address from the
+hostname. With this option, the peer will have to supply the local IP
+address during IPCP negotiation (unless it specified explicitly on the
+command line or in an options file).
+.TP
+.B noipx
+Disable the IPXCP and IPX protocols. This option should only be
+required if the peer is buggy and gets confused by requests from pppd
+for IPXCP negotiation.
+.TP
+.B noktune
+Opposite of the \fIktune\fR option; disables pppd from changing system
+settings.
+.TP
+.B nolog
+Do not send log messages to a file or file descriptor. This option
+cancels the \fBlogfd\fR and \fBlogfile\fR options.
+.B nomagic
+Disable magic number negotiation. With this option, pppd cannot
+detect a looped-back line. This option should only be needed if the
+peer is buggy.
+.TP
+.B nopcomp
+Disable protocol field compression negotiation in both the receive and
+the transmit direction.
+.TP
+.B nopersist
+Exit once a connection has been made and terminated. This is the
+default unless the \fIpersist\fR or \fIdemand\fR option has been
+specified.
+.TP
+.B nopredictor1
+Do not accept or agree to Predictor-1 compression.
+.TP
+.B noproxyarp
+Disable the \fIproxyarp\fR option. The system administrator who
+wishes to prevent users from creating proxy ARP entries with pppd can
+do so by placing this option in the /etc/ppp/options file.
+.TP
+.B notty
+Normally, pppd requires a terminal device. With this option, pppd
+will allocate itself a pseudo-tty master/slave pair and use the slave
+as its terminal device. Pppd will create a child process to act as a
+`character shunt' to transfer characters between the pseudo-tty master
+and its standard input and output. Thus pppd will transmit characters
+on its standard output and receive characters on its standard input
+even if they are not terminal devices. This option increases the
+latency and CPU overhead of transferring data over the ppp interface
+as all of the characters sent and received must flow through the
+character shunt process. An explicit device name may not be given if
+this option is used.
+.TP
+.B novj
+Disable Van Jacobson style TCP/IP header compression in both the
+transmit and the receive direction.
+.TP
+.B novjccomp
+Disable the connection-ID compression option in Van Jacobson style
+TCP/IP header compression. With this option, pppd will not omit the
+connection-ID byte from Van Jacobson compressed TCP/IP headers, nor
+ask the peer to do so.
+.TP
+.B papcrypt
+Indicates that all secrets in the /etc/ppp/pap-secrets file which are
+used for checking the identity of the peer are encrypted, and thus
+pppd should not accept a password which, before encryption, is
+identical to the secret from the /etc/ppp/pap-secrets file.
+.TP
+.B pap-max-authreq \fIn
+Set the maximum number of PAP authenticate-request transmissions to
+\fIn\fR (default 10).
+.TP
+.B pap-restart \fIn
+Set the PAP restart interval (retransmission timeout) to \fIn\fR
+seconds (default 3).
+.TP
+.B pap-timeout \fIn
+Set the maximum time that pppd will wait for the peer to authenticate
+itself with PAP to \fIn\fR seconds (0 means no limit).
+.TP
+.B pass-filter \fIfilter-expression
+Specifies a packet filter to applied to data packets being sent or
+received to determine which packets should be allowed to pass.
+Packets which are rejected by the filter are silently discarded. This
+option can be used to prevent specific network daemons (such as
+routed) using up link bandwidth, or to provide a basic firewall
+capability.
+The \fIfilter-expression\fR syntax is as described for tcpdump(1),
+except that qualifiers which are inappropriate for a PPP link, such as
+\fBether\fR and \fBarp\fR, are not permitted. Generally the filter
+expression should be enclosed in single-quotes to prevent whitespace
+in the expression from being interpreted by the shell. Note that it
+is possible to apply different constraints to incoming and outgoing
+packets using the \fBinbound\fR and \fBoutbound\fR qualifiers. This
+option is currently only available under NetBSD, and then only if both
+the kernel and pppd were compiled with PPP_FILTER defined.
+.TP
+.B persist
+Do not exit after a connection is terminated; instead try to reopen
+the connection.
+.TP
+.B plugin \fIfilename
+Load the shared library object file \fIfilename\fR as a plugin. This
+is a privileged option.
+.TP
+.B predictor1
+Request that the peer compress frames that it sends using Predictor-1
+compression, and agree to compress transmitted frames with Predictor-1
+if requested. This option has no effect unless the kernel driver
+supports Predictor-1 compression.
+.TP
+.B privgroup \fIgroup-name
+Allows members of group \fIgroup-name\fR to use privileged options.
+This is a privileged option. Use of this option requires care as
+there is no guarantee that members of \fIgroup-name\fR cannot use pppd
+to become root themselves. Consider it equivalent to putting the
+members of \fIgroup-name\fR in the kmem or disk group.
+.TP
+.B proxyarp
+Add an entry to this system's ARP [Address Resolution Protocol] table
+with the IP address of the peer and the Ethernet address of this
+system. This will have the effect of making the peer appear to other
+systems to be on the local ethernet.
+.TP
+.B pty \fIscript
+Specifies that the command \fIscript\fR is to be used to communicate
+rather than a specific terminal device. Pppd will allocate itself a
+pseudo-tty master/slave pair and use the slave as its terminal
+device. The \fIscript\fR will be run in a child process with the
+pseudo-tty master as its standard input and output. An explicit
+device name may not be given if this option is used. (Note: if the
+\fIrecord\fR option is used in conjuction with the \fIpty\fR option,
+the child process will have pipes on its standard input and output.)
+.TP
+.B receive-all
+With this option, pppd will accept all control characters from the
+peer, including those marked in the receive asyncmap. Without this
+option, pppd will discard those characters as specified in RFC1662.
+This option should only be needed if the peer is buggy.
+.TP
+.B record \fIfilename
+Specifies that pppd should record all characters sent and received to
+a file named \fIfilename\fR. This file is opened in append mode,
+using the user's user-ID and permissions. This option is implemented
+using a pseudo-tty and a process to transfer characters between the
+pseudo-tty and the real serial device, so it will increase the latency
+and CPU overhead of transferring data over the ppp interface. The
+characters are stored in a tagged format with timestamps, which can be
+displayed in readable form using the pppdump(8) program.
+.TP
+.B remotename \fIname
+Set the assumed name of the remote system for authentication purposes
+to \fIname\fR.
+.TP
+.B refuse-chap
+With this option, pppd will not agree to authenticate itself to the
+peer using CHAP.
+.TP
+.B refuse-pap
+With this option, pppd will not agree to authenticate itself to the
+peer using PAP.
+.TP
+.B require-chap
+Require the peer to authenticate itself using CHAP [Challenge
+Handshake Authentication Protocol] authentication.
+.TP
+.B require-pap
+Require the peer to authenticate itself using PAP [Password
+Authentication Protocol] authentication.
+.TP
+.B show-password
+When logging the contents of PAP packets, this option causes pppd to
+show the password string in the log message.
+.TP
+.B silent
+With this option, pppd will not transmit LCP packets to initiate a
+connection until a valid LCP packet is received from the peer (as for
+the `passive' option with ancient versions of pppd).
+.TP
+.B sync
+Use synchronous HDLC serial encoding instead of asynchronous.
+The device used by pppd with this option must have sync support.
+Currently supports Microgate SyncLink adapters
+under Linux and FreeBSD 2.2.8 and later.
+.TP
+.B updetach
+With this option, pppd will detach from its controlling terminal once
+it has successfully established the ppp connection (to the point where
+the first network control protocol, usually the IP control protocol,
+has come up).
+.TP
+.B usehostname
+Enforce the use of the hostname (with domain name appended, if given)
+as the name of the local system for authentication purposes (overrides
+the \fIname\fR option). This option is not normally needed since the
+\fIname\fR option is privileged.
+.TP
+.B usepeerdns
+Ask the peer for up to 2 DNS server addresses. The addresses supplied
+by the peer (if any) are passed to the /etc/ppp/ip-up script in the
+environment variables DNS1 and DNS2. In addition, pppd will create an
+/etc/ppp/resolv.conf file containing one or two nameserver lines with
+the address(es) supplied by the peer.
+.TP
+.B user \fIname
+Sets the name used for authenticating the local system to the peer to
+\fIname\fR.
+.TP
+.B vj-max-slots \fIn
+Sets the number of connection slots to be used by the Van Jacobson
+TCP/IP header compression and decompression code to \fIn\fR, which
+must be between 2 and 16 (inclusive).
+.TP
+.B welcome \fIscript
+Run the executable or shell command specified by \fIscript\fR before
+initiating PPP negotiation, after the connect script (if any) has
+completed. A value for this option from a privileged source cannot be
+overridden by a non-privileged user.
+.TP
+.B xonxoff
+Use software flow control (i.e. XON/XOFF) to control the flow of data on
+the serial port.
+.SH OPTIONS FILES
+Options can be taken from files as well as the command line. Pppd
+reads options from the files /etc/ppp/options, ~/.ppprc and
+/etc/ppp/options.\fIttyname\fR (in that order) before processing the
+options on the command line. (In fact, the command-line options are
+scanned to find the terminal name before the options.\fIttyname\fR
+file is read.) In forming the name of the options.\fIttyname\fR file,
+the initial /dev/ is removed from the terminal name, and any remaining
+/ characters are replaced with dots.
+.PP
+An options file is parsed into a series of words, delimited by
+whitespace. Whitespace can be included in a word by enclosing the
+word in double-quotes ("). A backslash (\\) quotes the following character.
+A hash (#) starts a comment, which continues until the end of the
+line. There is no restriction on using the \fIfile\fR or \fIcall\fR
+options within an options file.
+.SH SECURITY
+.I pppd
+provides system administrators with sufficient access control that PPP
+access to a server machine can be provided to legitimate users without
+fear of compromising the security of the server or the network it's
+on. This control is provided through restrictions on which IP
+addresses the peer may use, based on its authenticated identity (if
+any), and through restrictions on which options a non-privileged user
+may use. Several of pppd's options are privileged, in particular
+those which permit potentially insecure configurations; these options
+are only accepted in files which are under the control of the system
+administrator, or if pppd is being run by root.
+.PP
+The default behaviour of pppd is to allow an unauthenticated peer to
+use a given IP address only if the system does not already have a
+route to that IP address. For example, a system with a
+permanent connection to the wider internet will normally have a
+default route, and thus all peers will have to authenticate themselves
+in order to set up a connection. On such a system, the \fIauth\fR
+option is the default. On the other hand, a system where the
+PPP link is the only connection to the internet will not normally have
+a default route, so the peer will be able to use almost any IP address
+without authenticating itself.
+.PP
+As indicated above, some security-sensitive options are privileged,
+which means that they may not be used by an ordinary non-privileged
+user running a setuid-root pppd, either on the command line, in the
+user's ~/.ppprc file, or in an options file read using the \fIfile\fR
+option. Privileged options may be used in /etc/ppp/options file or in
+an options file read using the \fIcall\fR option. If pppd is being
+run by the root user, privileged options can be used without
+restriction.
+.PP
+When opening the device, pppd uses either the invoking user's user ID
+or the root UID (that is, 0), depending on whether the device name was
+specified by the user or the system administrator. If the device name
+comes from a privileged source, that is, /etc/ppp/options or an
+options file read using the \fIcall\fR option, pppd uses full root
+privileges when opening the device. Thus, by creating an appropriate
+file under /etc/ppp/peers, the system administrator can allow users to
+establish a ppp connection via a device which they would not normally
+have permission to access. Otherwise pppd uses the invoking user's
+real UID when opening the device.
+.SH AUTHENTICATION
+Authentication is the process whereby one peer convinces the other of
+its identity. This involves the first peer sending its name to the
+other, together with some kind of secret information which could only
+come from the genuine authorized user of that name. In such an
+exchange, we will call the first peer the "client" and the other the
+"server". The client has a name by which it identifies itself to the
+server, and the server also has a name by which it identifies itself
+to the client. Generally the genuine client shares some secret (or
+password) with the server, and authenticates itself by proving that it
+knows that secret. Very often, the names used for authentication
+correspond to the internet hostnames of the peers, but this is not
+essential.
+.LP
+At present, pppd supports two authentication protocols: the Password
+Authentication Protocol (PAP) and the Challenge Handshake
+Authentication Protocol (CHAP). PAP involves the client sending its
+name and a cleartext password to the server to authenticate itself.
+In contrast, the server initiates the CHAP authentication exchange by
+sending a challenge to the client (the challenge packet includes the
+server's name). The client must respond with a response which
+includes its name plus a hash value derived from the shared secret and
+the challenge, in order to prove that it knows the secret.
+.LP
+The PPP protocol, being symmetrical, allows both peers to require the
+other to authenticate itself. In that case, two separate and
+independent authentication exchanges will occur. The two exchanges
+could use different authentication protocols, and in principle,
+different names could be used in the two exchanges.
+.LP
+The default behaviour of pppd is to agree to authenticate if
+requested, and to not require authentication from the peer. However,
+pppd will not agree to authenticate itself with a particular protocol
+if it has no secrets which could be used to do so.
+.LP
+Pppd stores secrets for use in authentication in secrets
+files (/etc/ppp/pap-secrets for PAP, /etc/ppp/chap-secrets for CHAP).
+Both secrets files have the same format. The secrets files can
+contain secrets for pppd to use in authenticating itself to other
+systems, as well as secrets for pppd to use when authenticating other
+systems to itself.
+.LP
+Each line in a secrets file contains one secret. A given secret is
+specific to a particular combination of client and server - it can
+only be used by that client to authenticate itself to that server.
+Thus each line in a secrets file has at least 3 fields: the name of
+the client, the name of the server, and the secret. These fields may
+be followed by a list of the IP addresses that the specified client
+may use when connecting to the specified server.
+.LP
+A secrets file is parsed into words as for a options file, so the
+client name, server name and secrets fields must each be one word,
+with any embedded spaces or other special characters quoted or
+escaped. Note that case is significant in the client and server names
+and in the secret.
+.LP
+If the secret starts with an `@', what follows is assumed to be the
+name of a file from which to read the secret. A "*" as the client or
+server name matches any name. When selecting a secret, pppd takes the
+best match, i.e. the match with the fewest wildcards.
+.LP
+Any following words on the same line are taken to be a list of
+acceptable IP addresses for that client. If there are only 3 words on
+the line, or if the first word is "-", then all IP addresses are
+disallowed. To allow any address, use "*". A word starting with "!"
+indicates that the specified address is \fInot\fR acceptable. An
+address may be followed by "/" and a number \fIn\fR, to indicate a
+whole subnet, i.e. all addresses which have the same value in the most
+significant \fIn\fR bits. In this form, the address may be followed
+by a plus sign ("+") to indicate that one address from the subnet is
+authorized, based on the ppp network interface unit number in use.
+In this case, the host part of the address will be set to the unit
+number plus one.
+.LP
+Thus a secrets file contains both secrets for use in authenticating
+other hosts, plus secrets which we use for authenticating ourselves to
+others. When pppd is authenticating the peer (checking the peer's
+identity), it chooses a secret with the peer's name in the first
+field and the name of the local system in the second field. The
+name of the local system defaults to the hostname, with the domain
+name appended if the \fIdomain\fR option is used. This default can be
+overridden with the \fIname\fR option, except when the
+\fIusehostname\fR option is used.
+.LP
+When pppd is choosing a secret to use in authenticating itself to the
+peer, it first determines what name it is going to use to identify
+itself to the peer. This name can be specified by the user with the
+\fIuser\fR option. If this option is not used, the name defaults to
+the name of the local system, determined as described in the previous
+paragraph. Then pppd looks for a secret with this name in the first
+field and the peer's name in the second field. Pppd will know the
+name of the peer if CHAP authentication is being used, because the
+peer will have sent it in the challenge packet. However, if PAP is being
+used, pppd will have to determine the peer's name from the options
+specified by the user. The user can specify the peer's name directly
+with the \fIremotename\fR option. Otherwise, if the remote IP address
+was specified by a name (rather than in numeric form), that name will
+be used as the peer's name. Failing that, pppd will use the null
+string as the peer's name.
+.LP
+When authenticating the peer with PAP, the supplied password is first
+compared with the secret from the secrets file. If the password
+doesn't match the secret, the password is encrypted using crypt() and
+checked against the secret again. Thus secrets for authenticating the
+peer can be stored in encrypted form if desired. If the
+\fIpapcrypt\fR option is given, the first (unencrypted) comparison is
+omitted, for better security.
+.LP
+Furthermore, if the \fIlogin\fR option was specified, the username and
+password are also checked against the system password database. Thus,
+the system administrator can set up the pap-secrets file to allow PPP
+access only to certain users, and to restrict the set of IP addresses
+that each user can use. Typically, when using the \fIlogin\fR option,
+the secret in /etc/ppp/pap-secrets would be "", which will match any
+password supplied by the peer. This avoids the need to have the same
+secret in two places.
+.LP
+Authentication must be satisfactorily completed before IPCP (or any
+other Network Control Protocol) can be started. If the peer is
+required to authenticate itself, and fails to do so, pppd will
+terminated the link (by closing LCP). If IPCP negotiates an
+unacceptable IP address for the remote host, IPCP will be closed. IP
+packets can only be sent or received when IPCP is open.
+.LP
+In some cases it is desirable to allow some hosts which can't
+authenticate themselves to connect and use one of a restricted set of
+IP addresses, even when the local host generally requires
+authentication. If the peer refuses to authenticate itself when
+requested, pppd takes that as equivalent to authenticating with PAP
+using the empty string for the username and password. Thus, by adding
+a line to the pap-secrets file which specifies the empty string for
+the client and password, it is possible to allow restricted access to
+hosts which refuse to authenticate themselves.
+.SH ROUTING
+.LP
+When IPCP negotiation is completed successfully, pppd will inform the
+kernel of the local and remote IP addresses for the ppp interface.
+This is sufficient to create a host route to the remote end of the
+link, which will enable the peers to exchange IP packets.
+Communication with other machines generally requires further
+modification to routing tables and/or ARP (Address Resolution
+Protocol) tables. In most cases the \fIdefaultroute\fR and/or
+\fIproxyarp\fR options are sufficient for this, but in some cases
+further intervention is required. The /etc/ppp/ip-up script can be
+used for this.
+.LP
+Sometimes it is desirable to add a default route through the remote
+host, as in the case of a machine whose only connection to the
+Internet is through the ppp interface. The \fIdefaultroute\fR option
+causes pppd to create such a default route when IPCP comes up, and
+delete it when the link is terminated.
+.LP
+In some cases it is desirable to use proxy ARP, for example on a
+server machine connected to a LAN, in order to allow other hosts to
+communicate with the remote host. The \fIproxyarp\fR option causes
+pppd to look for a network interface on the same subnet as the remote
+host (an interface supporting broadcast and ARP, which is up and not a
+point-to-point or loopback interface). If found, pppd creates a
+permanent, published ARP entry with the IP address of the remote host
+and the hardware address of the network interface found.
+.LP
+When the \fIdemand\fR option is used, the interface IP addresses have
+already been set at the point when IPCP comes up. If pppd has not
+been able to negotiate the same addresses that it used to configure
+the interface (for example when the peer is an ISP that uses dynamic
+IP address assignment), pppd has to change the interface IP addresses
+to the negotiated addresses. This may disrupt existing connections,
+and the use of demand dialling with peers that do dynamic IP address
+assignment is not recommended.
+.SH EXAMPLES
+.LP
+The following examples assume that the /etc/ppp/options file contains
+the \fIauth\fR option (as in the default /etc/ppp/options file in the
+ppp distribution).
+.LP
+Probably the most common use of pppd is to dial out to an ISP. This
+can be done with a command such as
+.IP
+pppd call isp
+.LP
+where the /etc/ppp/peers/isp file is set up by the system
+administrator to contain something like this:
+.IP
+ttyS0 19200 crtscts
+.br
+connect '/usr/sbin/chat -v -f /etc/ppp/chat-isp'
+.br
+noauth
+.LP
+In this example, we are using chat to dial the ISP's modem and go
+through any logon sequence required. The /etc/ppp/chat-isp file
+contains the script used by chat; it could for example contain
+something like this:
+.IP
+ABORT "NO CARRIER"
+.br
+ABORT "NO DIALTONE"
+.br
+ABORT "ERROR"
+.br
+ABORT "NO ANSWER"
+.br
+ABORT "BUSY"
+.br
+ABORT "Username/Password Incorrect"
+.br
+"" "at"
+.br
+OK "at&d0&c1"
+.br
+OK "atdt2468135"
+.br
+"name:" "^Umyuserid"
+.br
+"word:" "\\qmypassword"
+.br
+"ispts" "\\q^Uppp"
+.br
+"~-^Uppp-~"
+.LP
+See the chat(8) man page for details of chat scripts.
+.LP
+Pppd can also be used to provide a dial-in ppp service for users. If
+the users already have login accounts, the simplest way to set up the
+ppp service is to let the users log in to their accounts and run pppd
+(installed setuid-root) with a command such as
+.IP
+pppd proxyarp
+.LP
+To allow a user to use the PPP facilities, you need to allocate an IP
+address for that user's machine and create an entry in
+/etc/ppp/pap-secrets or /etc/ppp/chap-secrets (depending on which
+authentication method the PPP implementation on the user's machine
+supports), so that the user's
+machine can authenticate itself. For example, if Joe has a machine
+called "joespc" which is to be allowed to dial in to the machine
+called "server" and use the IP address joespc.my.net, you would add an
+entry like this to /etc/ppp/pap-secrets or /etc/ppp/chap-secrets:
+.IP
+joespc server "joe's secret" joespc.my.net
+.LP
+Alternatively, you can create a username called (for example) "ppp",
+whose login shell is pppd and whose home directory is /etc/ppp.
+Options to be used when pppd is run this way can be put in
+/etc/ppp/.ppprc.
+.LP
+If your serial connection is any more complicated than a piece of
+wire, you may need to arrange for some control characters to be
+escaped. In particular, it is often useful to escape XON (^Q) and
+XOFF (^S), using \fIasyncmap a0000\fR. If the path includes a telnet,
+you probably should escape ^] as well (\fIasyncmap 200a0000\fR). If
+the path includes an rlogin, you will need to use the \fIescape ff\fR
+option on the end which is running the rlogin client, since many
+rlogin implementations are not transparent; they will remove the
+sequence [0xff, 0xff, 0x73, 0x73, followed by any 8 bytes] from the
+stream.
+.SH DIAGNOSTICS
+.LP
+Messages are sent to the syslog daemon using facility LOG_DAEMON.
+(This can be overriden by recompiling pppd with the macro
+LOG_PPP defined as the desired facility.) In order to see the error
+and debug messages, you will need to edit your /etc/syslog.conf file
+to direct the messages to the desired output device or file.
+.LP
+The \fIdebug\fR option causes the contents of all control packets sent
+or received to be logged, that is, all LCP, PAP, CHAP or IPCP packets.
+This can be useful if the PPP negotiation does not succeed or if
+authentication fails.
+If debugging is enabled at compile time, the \fIdebug\fR option also
+causes other debugging messages to be logged.
+.LP
+Debugging can also be enabled or disabled by sending a SIGUSR1 signal
+to the pppd process. This signal acts as a toggle.
+.SH EXIT STATUS
+The exit status of pppd is set to indicate whether any error was
+detected, or the reason for the link being terminated. The values
+used are:
+.TP
+.B 0
+Pppd has detached, or otherwise the connection was successfully
+established and terminated at the peer's request.
+.TP
+.B 1
+An immediately fatal error of some kind occurred, such as an essential
+system call failing, or running out of virtual memory.
+.TP
+.B 2
+An error was detected in processing the options given, such as two
+mutually exclusive options being used.
+.TP
+.B 3
+Pppd is not setuid-root and the invoking user is not root.
+.TP
+.B 4
+The kernel does not support PPP, for example, the PPP kernel driver is
+not included or cannot be loaded.
+.TP
+.B 5
+Pppd terminated because it was sent a SIGINT, SIGTERM or SIGHUP
+signal.
+.TP
+.B 6
+The serial port could not be locked.
+.TP
+.B 7
+The serial port could not be opened.
+.TP
+.B 8
+The connect script failed (returned a non-zero exit status).
+.TP
+.B 9
+The command specified as the argument to the \fIpty\fR option could
+not be run.
+.TP
+.B 10
+The PPP negotiation failed, that is, it didn't reach the point where
+at least one network protocol (e.g. IP) was running.
+.TP
+.B 11
+The peer system failed (or refused) to authenticate itself.
+.TP
+.B 12
+The link was established successfully and terminated because it was
+idle.
+.TP
+.B 13
+The link was established successfully and terminated because the
+connect time limit was reached.
+.TP
+.B 14
+Callback was negotiated and an incoming call should arrive shortly.
+.TP
+.B 15
+The link was terminated because the peer is not responding to echo
+requests.
+.TP
+.B 16
+The link was terminated by the modem hanging up.
+.TP
+.B 17
+The PPP negotiation failed because serial loopback was detected.
+.TP
+.B 18
+The init script failed (returned a non-zero exit status).
+.TP
+.B 19
+We failed to authenticate ourselves to the peer.
+.SH SCRIPTS
+Pppd invokes scripts at various stages in its processing which can be
+used to perform site-specific ancillary processing. These scripts are
+usually shell scripts, but could be executable code files instead.
+Pppd does not wait for the scripts to finish. The scripts are
+executed as root (with the real and effective user-id set to 0), so
+that they can do things such as update routing tables or run
+privileged daemons. Be careful that the contents of these scripts do
+not compromise your system's security. Pppd runs the scripts with
+standard input, output and error redirected to /dev/null, and with an
+environment that is empty except for some environment variables that
+give information about the link. The environment variables that pppd
+sets are:
+.TP
+.B DEVICE
+The name of the serial tty device being used.
+.TP
+.B IFNAME
+The name of the network interface being used.
+.TP
+.B IPLOCAL
+The IP address for the local end of the link. This is only set when
+IPCP has come up.
+.TP
+.B IPREMOTE
+The IP address for the remote end of the link. This is only set when
+IPCP has come up.
+.TP
+.B PEERNAME
+The authenticated name of the peer. This is only set if the peer
+authenticates itself.
+.TP
+.B SPEED
+The baud rate of the tty device.
+.TP
+.B ORIG_UID
+The real user-id of the user who invoked pppd.
+.TP
+.B PPPLOGNAME
+The username of the real user-id that invoked pppd. This is always set.
+.P
+For the ip-down and auth-down scripts, pppd also sets the following
+variables giving statistics for the connection:
+.TP
+.B CONNECT_TIME
+The number of seconds from when the PPP negotiation started until the
+connection was terminated.
+.TP
+.B BYTES_SENT
+The number of bytes sent (at the level of the serial port) during the
+connection.
+.TP
+.B BYTES_RCVD
+The number of bytes received (at the level of the serial port) during
+the connection.
+.TP
+.B LINKNAME
+The logical name of the link, set with the \fIlinkname\fR option.
+.P
+Pppd invokes the following scripts, if they exist. It is not an error
+if they don't exist.
+.TP
+.B /etc/ppp/auth-up
+A program or script which is executed after the remote system
+successfully authenticates itself. It is executed with the parameters
+.IP
+\fIinterface-name peer-name user-name tty-device speed\fR
+.IP
+Note that this script is not executed if the peer doesn't authenticate
+itself, for example when the \fInoauth\fR option is used.
+.TP
+.B /etc/ppp/auth-down
+A program or script which is executed when the link goes down, if
+/etc/ppp/auth-up was previously executed. It is executed in the same
+manner with the same parameters as /etc/ppp/auth-up.
+.TP
+.B /etc/ppp/ip-up
+A program or script which is executed when the link is available for
+sending and receiving IP packets (that is, IPCP has come up). It is
+executed with the parameters
+.IP
+\fIinterface-name tty-device speed local-IP-address
+remote-IP-address ipparam\fR
+.TP
+.B /etc/ppp/ip-down
+A program or script which is executed when the link is no longer
+available for sending and receiving IP packets. This script can be
+used for undoing the effects of the /etc/ppp/ip-up script. It is
+invoked in the same manner and with the same parameters as the ip-up
+script.
+.TP
+.B /etc/ppp/ipv6-up
+Like /etc/ppp/ip-up, except that it is executed when the link is available
+for sending and receiving IPv6 packets. It is executed with the parameters
+.IP
+\fIinterface-name tty-device speed local-link-local-address
+remote-link-local-address ipparam\fR
+.TP
+.B /etc/ppp/ipv6-down
+Similar to /etc/ppp/ip-down, but it is executed when IPv6 packets can no
+longer be transmitted on the link. It is executed with the same parameters
+as the ipv6-up script.
+.TP
+.B /etc/ppp/ipx-up
+A program or script which is executed when the link is available for
+sending and receiving IPX packets (that is, IPXCP has come up). It is
+executed with the parameters
+.IP
+\fIinterface-name tty-device speed network-number local-IPX-node-address
+remote-IPX-node-address local-IPX-routing-protocol remote-IPX-routing-protocol
+local-IPX-router-name remote-IPX-router-name ipparam pppd-pid\fR
+.IP
+The local-IPX-routing-protocol and remote-IPX-routing-protocol field
+may be one of the following:
+.IP
+NONE to indicate that there is no routing protocol
+.br
+RIP to indicate that RIP/SAP should be used
+.br
+NLSP to indicate that Novell NLSP should be used
+.br
+RIP NLSP to indicate that both RIP/SAP and NLSP should be used
+.TP
+.B /etc/ppp/ipx-down
+A program or script which is executed when the link is no longer
+available for sending and receiving IPX packets. This script can be
+used for undoing the effects of the /etc/ppp/ipx-up script. It is
+invoked in the same manner and with the same parameters as the ipx-up
+script.
+.SH FILES
+.TP
+.B /var/run/ppp\fIn\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\fIn\fB.pid \fR(others)
+Process-ID for pppd process on ppp interface unit \fIn\fR.
+.TP
+.B /var/run/ppp-\fIname\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp-\fIname\fB.pid \fR(others)
+Process-ID for pppd process for logical link \fIname\fR (see the
+\fIlinkname\fR option).
+.TP
+.B /etc/ppp/pap-secrets
+Usernames, passwords and IP addresses for PAP authentication. This
+file should be owned by root and not readable or writable by any other
+user. Pppd will log a warning if this is not the case.
+.TP
+.B /etc/ppp/chap-secrets
+Names, secrets and IP addresses for CHAP authentication. As for
+/etc/ppp/pap-secrets, this file should be owned by root and not
+readable or writable by any other user. Pppd will log a warning if
+this is not the case.
+.TP
+.B /etc/ppp/options
+System default options for pppd, read before user default options or
+command-line options.
+.TP
+.B ~/.ppprc
+User default options, read before /etc/ppp/options.\fIttyname\fR.
+.TP
+.B /etc/ppp/options.\fIttyname
+System default options for the serial port being used, read after
+~/.ppprc. In forming the \fIttyname\fR part of this
+filename, an initial /dev/ is stripped from the port name (if
+present), and any slashes in the remaining part are converted to
+dots.
+.TP
+.B /etc/ppp/peers
+A directory containing options files which may contain privileged
+options, even if pppd was invoked by a user other than root. The
+system administrator can create options files in this directory to
+permit non-privileged users to dial out without requiring the peer to
+authenticate, but only to certain trusted peers.
+.SH SEE ALSO
+.TP
+.B RFC1144
+Jacobson, V.
+\fICompressing TCP/IP headers for low-speed serial links.\fR
+February 1990.
+.TP
+.B RFC1321
+Rivest, R.
+.I The MD5 Message-Digest Algorithm.
+April 1992.
+.TP
+.B RFC1332
+McGregor, G.
+.I PPP Internet Protocol Control Protocol (IPCP).
+May 1992.
+.TP
+.B RFC1334
+Lloyd, B.; Simpson, W.A.
+.I PPP authentication protocols.
+October 1992.
+.TP
+.B RFC1661
+Simpson, W.A.
+.I The Point\-to\-Point Protocol (PPP).
+July 1994.
+.TP
+.B RFC1662
+Simpson, W.A.
+.I PPP in HDLC-like Framing.
+July 1994.
+.TP
+.B RFC2472
+Haskin, D.
+.I IP Version 6 over PPP
+December 1998.
+.SH NOTES
+The following signals have the specified effect when sent to pppd.
+.TP
+.B SIGINT, SIGTERM
+These signals cause pppd to terminate the link (by closing LCP),
+restore the serial device settings, and exit.
+.TP
+.B SIGHUP
+This signal causes pppd to terminate the link, restore the serial
+device settings, and close the serial device. If the \fIpersist\fR or
+\fIdemand\fR option has been specified, pppd will try to reopen the
+serial device and start another connection (after the holdoff period).
+Otherwise pppd will exit. If this signal is received during the
+holdoff period, it causes pppd to end the holdoff period immediately.
+.TP
+.B SIGUSR1
+This signal toggles the state of the \fIdebug\fR option.
+.TP
+.B SIGUSR2
+This signal causes pppd to renegotiate compression. This can be
+useful to re-enable compression after it has been disabled as a result
+of a fatal decompression error. (Fatal decompression errors generally
+indicate a bug in one or other implementation.)
+
+.SH AUTHORS
+Paul Mackerras (Paul.Mackerras@cs.anu.edu.au), based on earlier work by
+Drew Perkins,
+Brad Clements,
+Karl Fox,
+Greg Christy,
+and
+Brad Parker.
diff --git a/cpukit/pppd/pppd.h b/cpukit/pppd/pppd.h
new file mode 100644
index 0000000000..95fe61531d
--- /dev/null
+++ b/cpukit/pppd/pppd.h
@@ -0,0 +1,663 @@
+/*
+ * pppd.h - PPP daemon global declarations.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ *
+ * $Id$
+ */
+
+#ifndef __PPPD_H__
+#define __PPPD_H__
+
+#include <stdio.h> /* for FILE */
+#include <limits.h> /* for NGROUPS_MAX */
+#include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */
+#include <sys/types.h> /* for u_int32_t, if defined */
+#include <sys/time.h> /* for struct timeval */
+#include <net/ppp_defs.h>
+#include <rtems/rtemsdialer.h>
+
+#if defined(__STDC__)
+#include <stdarg.h>
+#define __V(x) x
+#else
+#include <varargs.h>
+#define __V(x) (va_alist) va_dcl
+#define const
+#define volatile
+#endif
+
+#ifdef INET6
+#include "eui64.h"
+#endif
+
+/*
+ * Limits.
+ */
+
+#define NUM_PPP 1 /* One PPP interface supported (per process) */
+#define MAXWORDLEN 1024 /* max length of word in file (incl null) */
+#define MAXARGS 1 /* max # args to a command */
+#define MAXNAMELEN 256 /* max length of hostname or name for auth */
+#define MAXSECRETLEN 256 /* max length of password or secret */
+
+/*
+ * Option descriptor structure.
+ */
+
+typedef unsigned char bool;
+
+enum opt_type {
+ o_special_noarg = 0,
+ o_special = 1,
+ o_bool,
+ o_int,
+ o_uint32,
+ o_string,
+};
+
+typedef struct {
+ char *name; /* name of the option */
+ enum opt_type type;
+ void *addr;
+ char *description;
+ int flags;
+ void *addr2;
+ int upper_limit;
+ int lower_limit;
+} option_t;
+
+/* Values for flags */
+#define OPT_VALUE 0xff /* mask for presupplied value */
+#define OPT_HEX 0x100 /* int option is in hex */
+#define OPT_NOARG 0x200 /* option doesn't take argument */
+#define OPT_OR 0x400 /* OR in argument to value */
+#define OPT_INC 0x800 /* increment value */
+#define OPT_PRIV 0x1000 /* privileged option */
+#define OPT_STATIC 0x2000 /* string option goes into static array */
+#define OPT_LLIMIT 0x4000 /* check value against lower limit */
+#define OPT_ULIMIT 0x8000 /* check value against upper limit */
+#define OPT_LIMITS (OPT_LLIMIT|OPT_ULIMIT)
+#define OPT_ZEROOK 0x10000 /* 0 value is OK even if not within limits */
+#define OPT_NOINCR 0x20000 /* value mustn't be increased */
+#define OPT_ZEROINF 0x40000 /* with OPT_NOINCR, 0 == infinity */
+#define OPT_A2INFO 0x100000 /* addr2 -> option_info to update */
+#define OPT_A2COPY 0x200000 /* addr2 -> second location to rcv value */
+#define OPT_ENABLE 0x400000 /* use *addr2 as enable for option */
+#define OPT_PRIVFIX 0x800000 /* can't be overridden if noauth */
+#define OPT_PREPASS 0x1000000 /* do this opt in pre-pass to find device */
+#define OPT_INITONLY 0x2000000 /* option can only be set in init phase */
+#define OPT_DEVEQUIV 0x4000000 /* equiv to device name */
+#define OPT_DEVNAM (OPT_PREPASS | OPT_INITONLY | OPT_DEVEQUIV)
+
+#define OPT_VAL(x) ((x) & OPT_VALUE)
+
+#ifndef GIDSET_TYPE
+#define GIDSET_TYPE gid_t
+#endif
+
+/* Structure representing a list of permitted IP addresses. */
+struct permitted_ip {
+ int permit; /* 1 = permit, 0 = forbid */
+ u_int32_t base; /* match if (addr & mask) == base */
+ u_int32_t mask; /* base and mask are in network byte order */
+};
+
+/*
+ * Unfortunately, the linux kernel driver uses a different structure
+ * for statistics from the rest of the ports.
+ * This structure serves as a common representation for the bits
+ * pppd needs.
+ */
+struct pppd_stats {
+ unsigned int bytes_in;
+ unsigned int bytes_out;
+};
+
+/* Used for storing a sequence of words. Usually malloced. */
+struct wordlist {
+ struct wordlist *next;
+ char *word;
+};
+
+/*
+ * Global variables.
+ */
+
+extern int pppd_kill_link; /* Signal to terminate processing loop */
+extern int hungup; /* Physical layer has disconnected */
+extern int pppifunit; /* Interface unit number */
+extern char ifname[]; /* Interface name */
+extern int pppd_ttyfd; /* Serial device file descriptor */
+extern char hostname[]; /* Our hostname */
+extern u_char outpacket_buf[]; /* Buffer for outgoing packets */
+extern int pppd_phase; /* Current state of link - see values below */
+extern int baud_rate; /* Current link speed in bits/sec */
+extern int redirect_stderr;/* Connector's stderr should go to file */
+extern char peer_authname[];/* Authenticated name of peer */
+extern int privileged; /* We were run by real-uid root */
+extern int need_holdoff; /* Need holdoff period after link terminates */
+extern char **script_env; /* Environment variables for scripts */
+extern int detached; /* Have detached from controlling tty */
+extern GIDSET_TYPE groups[NGROUPS_MAX]; /* groups the user is in */
+extern int ngroups; /* How many groups valid in groups */
+extern struct pppd_stats link_stats; /* byte/packet counts etc. for link */
+extern int using_pty; /* using pty as device (notty or pty opt.) */
+extern int log_to_fd; /* logging to this fd as well as syslog */
+extern char *no_ppp_msg; /* message to print if ppp not in kernel */
+extern volatile int pppd_status; /* exit status for pppd */
+extern int devnam_fixed; /* can no longer change devnam */
+extern int unsuccess; /* # unsuccessful connection attempts */
+extern int do_callback; /* set if we want to do callback next */
+extern int doing_callback; /* set if this is a callback */
+extern dialerfp pppd_dialer; /* script dialer function callback */
+
+/* Values for do_callback and doing_callback */
+#define CALLBACK_DIALIN 1 /* we are expecting the call back */
+#define CALLBACK_DIALOUT 2 /* we are dialling out to call back */
+
+/*
+ * Variables set by command-line options.
+ */
+
+extern int debug; /* Debug flag */
+extern int kdebugflag; /* Tell kernel to print debug messages */
+extern int default_device; /* Using /dev/tty or equivalent */
+extern char devnam[MAXPATHLEN]; /* Device name */
+extern int crtscts; /* Use hardware flow control */
+extern bool modem; /* Use modem control lines */
+extern int inspeed; /* Input/Output speed requested */
+extern u_int32_t netmask; /* IP netmask to set on interface */
+extern bool lockflag; /* Create lock file to lock the serial dev */
+extern bool nodetach; /* Don't detach from controlling tty */
+extern bool updetach; /* Detach from controlling tty when link up */
+extern char *initializer; /* Script to initialize physical link */
+extern char *connect_script; /* Script to establish physical link */
+extern char *disconnect_script; /* Script to disestablish physical link */
+extern char *welcomer; /* Script to welcome client after connection */
+extern char *ptycommand; /* Command to run on other side of pty */
+extern int maxconnect; /* Maximum connect time (seconds) */
+extern char user[MAXNAMELEN];/* Our name for authenticating ourselves */
+extern char passwd[MAXSECRETLEN]; /* Password for PAP or CHAP */
+extern bool auth_required; /* Peer is required to authenticate */
+extern bool persist; /* Reopen link after it goes down */
+extern bool uselogin; /* Use /etc/passwd for checking PAP */
+extern char our_name[MAXNAMELEN];/* Our name for authentication purposes */
+extern char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
+extern bool explicit_remote;/* remote_name specified with remotename opt */
+extern bool demand; /* Do dial-on-demand */
+extern char *ipparam; /* Extra parameter for ip up/down scripts */
+extern bool cryptpap; /* Others' PAP passwords are encrypted */
+extern int idle_time_limit;/* Shut down link if idle for this long */
+extern int holdoff; /* Dead time before restarting */
+extern bool holdoff_specified; /* true if user gave a holdoff value */
+extern bool notty; /* Stdin/out is not a tty */
+extern char *record_file; /* File to record chars sent/received */
+extern bool sync_serial; /* Device is synchronous serial device */
+extern int maxfail; /* Max # of unsuccessful connection attempts */
+extern char linkname[MAXPATHLEN]; /* logical name for link */
+extern bool tune_kernel; /* May alter kernel settings as necessary */
+extern int connect_delay; /* Time to delay after connect script */
+
+#ifdef PPP_FILTER
+extern struct bpf_program pass_filter; /* Filter for pkts to pass */
+extern struct bpf_program active_filter; /* Filter for link-active pkts */
+#endif
+
+#ifdef MSLANMAN
+extern bool ms_lanman; /* Use LanMan password instead of NT */
+ /* Has meaning only with MS-CHAP challenges */
+#endif
+
+extern char *current_option; /* the name of the option being parsed */
+extern int privileged_option; /* set iff the current option came from root */
+extern char *option_source; /* string saying where the option came from */
+
+/*
+ * Values for phase.
+ */
+#define PHASE_DEAD 0
+#define PHASE_INITIALIZE 1
+#define PHASE_SERIALCONN 2
+#define PHASE_DORMANT 3
+#define PHASE_ESTABLISH 4
+#define PHASE_AUTHENTICATE 5
+#define PHASE_CALLBACK 6
+#define PHASE_NETWORK 7
+#define PHASE_RUNNING 8
+#define PHASE_TERMINATE 9
+#define PHASE_DISCONNECT 10
+#define PHASE_HOLDOFF 11
+
+/*
+ * The following struct gives the addresses of procedures to call
+ * for a particular protocol.
+ */
+struct protent {
+ u_short protocol; /* PPP protocol number */
+ /* Initialization procedure */
+ void (*init) __P((int unit));
+ /* Process a received packet */
+ void (*input) __P((int unit, u_char *pkt, int len));
+ /* Process a received protocol-reject */
+ void (*protrej) __P((int unit));
+ /* Lower layer has come up */
+ void (*lowerup) __P((int unit));
+ /* Lower layer has gone down */
+ void (*lowerdown) __P((int unit));
+ /* Open the protocol */
+ void (*open) __P((int unit));
+ /* Close the protocol */
+ void (*close) __P((int unit, char *reason));
+ /* Print a packet in readable form */
+ int (*printpkt) __P((u_char *pkt, int len,
+ void (*printer) __P((void *, char *, ...)),
+ void *arg));
+ /* Process a received data packet */
+ void (*datainput) __P((int unit, u_char *pkt, int len));
+ bool enabled_flag; /* 0 iff protocol is disabled */
+ char *name; /* Text name of protocol */
+ char *data_name; /* Text name of corresponding data protocol */
+ option_t *options; /* List of command-line options */
+ /* Check requested options, assign defaults */
+ void (*check_options) __P((void));
+ /* Configure interface for demand-dial */
+ int (*demand_conf) __P((int unit));
+ /* Say whether to bring up link for this pkt */
+ int (*active_pkt) __P((u_char *pkt, int len));
+};
+
+/* Table of pointers to supported protocols */
+extern struct protent *protocols[];
+
+/*
+ * Prototypes.
+ */
+
+/* Procedures exported from main.c. */
+void die __P((int)); /* Cleanup and exit */
+void quit __P((void)); /* like die(1) */
+void novm __P((char *)); /* Say we ran out of memory, and die */
+void ppptimeout __P((void (*func)(void *), void *arg, int t));
+ /* Call func(arg) after t seconds */
+void untimeout __P((void (*func)(void *), void *arg));
+ /* Cancel call to func(arg) */
+void update_link_stats __P((int)); /* Get stats at link termination */
+void new_phase __P((int)); /* signal start of new phase */
+
+/* Procedures exported from utils.c. */
+void log_packet __P((u_char *, int, char *, int));
+ /* Format a packet and log it with syslog */
+void print_string __P((void *, int, void (*) (void *, char *, ...),
+ void *)); /* Format a string for output */
+int slprintf __P((char *, int, char *, ...)); /* sprintf++ */
+int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */
+size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */
+size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */
+void pppd_dbglog __P((char *, ...)); /* log a debug message */
+void pppd_info __P((char *, ...)); /* log an informational message */
+void pppd_notice __P((char *, ...)); /* log a notice-level message */
+void pppd_warn __P((char *, ...)); /* log a warning message */
+void pppd_error __P((char *, ...)); /* log an error message */
+void pppd_fatal __P((char *, ...)); /* log an error message and die(1) */
+
+#define dbglog pppd_dbglog
+#define info pppd_info
+#define notice pppd_notice
+#define warn pppd_warn
+#define error pppd_error
+#define fatal pppd_fatal
+
+/* Procedures exported from auth.c */
+void link_required __P((int)); /* we are starting to use the link */
+void link_terminated __P((int)); /* we are finished with the link */
+void link_down __P((int)); /* the LCP layer has left the Opened state */
+void link_established __P((int)); /* the link is up; authenticate now */
+void start_networks __P((void)); /* start all the network control protos */
+void np_up __P((int, int)); /* a network protocol has come up */
+void np_down __P((int, int)); /* a network protocol has gone down */
+void np_finished __P((int, int)); /* a network protocol no longer needs link */
+void auth_peer_fail __P((int, int));
+ /* peer failed to authenticate itself */
+void auth_peer_success __P((int, int, char *, int));
+ /* peer successfully authenticated itself */
+void auth_withpeer_fail __P((int, int));
+ /* we failed to authenticate ourselves */
+void auth_withpeer_success __P((int, int));
+ /* we successfully authenticated ourselves */
+int auth_check_options __P((void));
+ /* check authentication options supplied */
+void auth_reset __P((int)); /* check what secrets we have */
+int check_passwd __P((int, char *, int, char *, int, char **));
+ /* Check peer-supplied username/password */
+int get_secret __P((int, char *, char *, unsigned char *, int *, int));
+ /* get "secret" for chap */
+int auth_ip_addr __P((int, u_int32_t));
+ /* check if IP address is authorized */
+int bad_ip_adrs __P((u_int32_t));
+ /* check if IP address is unreasonable */
+
+/* Procedures exported from demand.c */
+void demand_conf __P((void)); /* config interface(s) for demand-dial */
+void demand_block __P((void)); /* set all NPs to queue up packets */
+void demand_unblock __P((void)); /* set all NPs to pass packets */
+void demand_discard __P((void)); /* set all NPs to discard packets */
+void demand_rexmit __P((int)); /* retransmit saved frames for an NP */
+int loop_chars __P((unsigned char *, int)); /* process chars from loopback */
+int loop_frame __P((unsigned char *, int)); /* should we bring link up? */
+
+/* Procedures exported from sys-*.c */
+void sys_init __P((void)); /* Do system-dependent initialization */
+void sys_cleanup __P((void)); /* Restore system state before exiting */
+int sys_check_options __P((void)); /* Check options specified */
+void sys_close __P((void)); /* Clean up in a child before execing */
+int ppp_available __P((void)); /* Test whether ppp kernel support exists */
+int get_pty __P((int *, int *, char *, int)); /* Get pty master/slave */
+int open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */
+int establish_ppp __P((int)); /* Turn serial port into a ppp interface */
+void restore_loop __P((void)); /* Transfer ppp unit back to loopback */
+void disestablish_ppp __P((int)); /* Restore port to normal operation */
+void clean_check __P((void)); /* Check if line was 8-bit clean */
+void set_up_tty __P((int, int)); /* Set up port's speed, parameters, etc. */
+void restore_tty __P((int)); /* Restore port's original parameters */
+void setdtr __P((int, int)); /* Raise or lower port's DTR line */
+void output __P((int, u_char *, int)); /* Output a PPP packet */
+void wait_input __P((struct timeval *)); /* Wait for input, with timeout */
+
+void ppp_delay __P((void)); /* delay task for a little while */
+int read_packet __P((u_char *)); /* Read PPP packet */
+int get_loop_output __P((void)); /* Read pkts from loopback */
+void ppp_send_config __P((int, int, u_int32_t, int, int));
+ /* Configure i/f transmit parameters */
+void ppp_set_xaccm __P((int, ext_accm));
+ /* Set extended transmit ACCM */
+void ppp_recv_config __P((int, int, u_int32_t, int, int));
+ /* Configure i/f receive parameters */
+int ccp_test __P((int, u_char *, int, int));
+ /* Test support for compression scheme */
+void ccp_flags_set __P((int, int, int));
+ /* Set kernel CCP state */
+int ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */
+int get_idle_time __P((int, struct ppp_idle *));
+ /* Find out how long link has been idle */
+int get_ppp_stats __P((int, struct pppd_stats *));
+ /* Return link statistics */
+int sifvjcomp __P((int, int, int, int));
+ /* Configure VJ TCP header compression */
+int sifup __P((int)); /* Configure i/f up for one protocol */
+int sifnpmode __P((int u, int proto, enum NPmode mode));
+ /* Set mode for handling packets for proto */
+int sifdown __P((int)); /* Configure i/f down for one protocol */
+int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t));
+ /* Configure IPv4 addresses for i/f */
+int cifaddr __P((int, u_int32_t, u_int32_t));
+ /* Reset i/f IP addresses */
+#ifdef INET6
+int sif6addr __P((int, eui64_t, eui64_t));
+ /* Configure IPv6 addresses for i/f */
+int cif6addr __P((int, eui64_t, eui64_t));
+ /* Remove an IPv6 address from i/f */
+#endif
+int sifdefaultroute __P((int, u_int32_t, u_int32_t));
+ /* Create default route through i/f */
+int cifdefaultroute __P((int, u_int32_t, u_int32_t));
+ /* Delete default route through i/f */
+int sifproxyarp __P((int, u_int32_t));
+ /* Add proxy ARP entry for peer */
+int cifproxyarp __P((int, u_int32_t));
+ /* Delete proxy ARP entry for peer */
+u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */
+int lock __P((char *)); /* Create lock file for device */
+int relock __P((int)); /* Rewrite lock file with new pid */
+void unlock __P((void)); /* Delete previously-created lock file */
+void logwtmp __P((const char *, const char *, const char *));
+ /* Write entry to wtmp file */
+int get_host_seed __P((void)); /* Get host-dependent random number seed */
+int have_route_to __P((u_int32_t)); /* Check if route to addr exists */
+#ifdef PPP_FILTER
+int set_filters __P((struct bpf_program *pass, struct bpf_program *active));
+ /* Set filter programs in kernel */
+#endif
+#ifdef IPX_CHANGE
+int sipxfaddr __P((int, unsigned long, unsigned char *));
+int cipxfaddr __P((int));
+#endif
+
+/* Procedures exported from options.c */
+int parse_args __P((int argc, char **argv));
+ /* Parse options from arguments given */
+int options_from_file __P((char *filename, int must_exist, int check_prot,
+ int privileged));
+ /* Parse options from an options file */
+int options_from_user __P((void)); /* Parse options from user's .ppprc */
+int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */
+int options_from_list __P((struct wordlist *, int privileged));
+ /* Parse options from a wordlist */
+int getword __P((FILE *f, char *word, int *newlinep, char *filename));
+ /* Read a word from a file */
+void option_error __P((char *fmt, ...));
+ /* Print an error message about an option */
+int int_option __P((char *, int *));
+ /* Simplified number_option for decimal ints */
+void add_options __P((option_t *)); /* Add extra options */
+
+/*
+ * This structure is used to store information about certain
+ * options, such as where the option value came from (/etc/ppp/options,
+ * command line, etc.) and whether it came from a privileged source.
+ */
+
+struct option_info {
+ int priv; /* was value set by sysadmin? */
+ char *source; /* where option came from */
+};
+
+extern struct option_info devnam_info;
+extern struct option_info initializer_info;
+extern struct option_info connect_script_info;
+extern struct option_info disconnect_script_info;
+extern struct option_info welcomer_info;
+extern struct option_info ptycommand_info;
+
+/*
+ * Hooks to enable plugins to change various things.
+ */
+extern int (*new_phase_hook) __P((int));
+extern int (*idle_time_hook) __P((struct ppp_idle *));
+extern int (*holdoff_hook) __P((void));
+extern int (*pap_check_hook) __P((void));
+extern int (*pap_auth_hook) __P((char *user, char *passwd/*, char **msgp,
+ struct wordlist **paddrs,
+ struct wordlist **popts*/));
+extern void (*pap_logout_hook) __P((void));
+extern int (*pap_passwd_hook) __P((char *user, char *passwd));
+extern void (*ip_up_hook) __P((void));
+extern void (*ip_down_hook) __P((void));
+extern void (*auth_linkup_hook) __P((void));
+extern void (*auth_linkdown_hook) __P((void));
+
+/*
+ * Inline versions of get/put char/short/long.
+ * Pointer is advanced; we assume that both arguments
+ * are lvalues and will already be in registers.
+ * cp MUST be u_char *.
+ */
+#define GETCHAR(c, cp) { \
+ (c) = *(cp)++; \
+}
+#define PUTCHAR(c, cp) { \
+ *(cp)++ = (u_char) (c); \
+}
+
+
+#define GETSHORT(s, cp) { \
+ (s) = *(cp)++ << 8; \
+ (s) |= *(cp)++; \
+}
+#define PUTSHORT(s, cp) { \
+ *(cp)++ = (u_char) ((s) >> 8); \
+ *(cp)++ = (u_char) (s); \
+}
+
+#define GETLONG(l, cp) { \
+ (l) = *(cp)++ << 8; \
+ (l) |= *(cp)++; (l) <<= 8; \
+ (l) |= *(cp)++; (l) <<= 8; \
+ (l) |= *(cp)++; \
+}
+#define PUTLONG(l, cp) { \
+ *(cp)++ = (u_char) ((l) >> 24); \
+ *(cp)++ = (u_char) ((l) >> 16); \
+ *(cp)++ = (u_char) ((l) >> 8); \
+ *(cp)++ = (u_char) (l); \
+}
+
+#define INCPTR(n, cp) ((cp) += (n))
+#define DECPTR(n, cp) ((cp) -= (n))
+
+/*
+ * System dependent definitions for user-level 4.3BSD UNIX implementation.
+ */
+
+#define TIMEOUT(r, f, t) ppptimeout((r), (f), (t))
+#define UNTIMEOUT(r, f) untimeout((r), (f))
+
+#define BCOPY(s, d, l) memcpy(d, s, l)
+#define BZERO(s, n) memset(s, 0, n)
+
+#define PRINTMSG(m, l) { info("Remote message: %0.*v", l, m); }
+
+/*
+ * MAKEHEADER - Add Header fields to a packet.
+ */
+#define MAKEHEADER(p, t) { \
+ PUTCHAR(PPP_ALLSTATIONS, p); \
+ PUTCHAR(PPP_UI, p); \
+ PUTSHORT(t, p); }
+
+/*
+ * Exit status values.
+ */
+#define EXIT_OK 0
+#define EXIT_FATAL_ERROR 1
+#define EXIT_OPTION_ERROR 2
+#define EXIT_NOT_ROOT 3
+#define EXIT_NO_KERNEL_SUPPORT 4
+#define EXIT_USER_REQUEST 5
+#define EXIT_LOCK_FAILED 6
+#define EXIT_OPEN_FAILED 7
+#define EXIT_CONNECT_FAILED 8
+#define EXIT_PTYCMD_FAILED 9
+#define EXIT_NEGOTIATION_FAILED 10
+#define EXIT_PEER_AUTH_FAILED 11
+#define EXIT_IDLE_TIMEOUT 12
+#define EXIT_CONNECT_TIME 13
+#define EXIT_CALLBACK 14
+#define EXIT_PEER_DEAD 15
+#define EXIT_HANGUP 16
+#define EXIT_LOOPBACK 17
+#define EXIT_INIT_FAILED 18
+#define EXIT_AUTH_TOPEER_FAILED 19
+
+/*
+ * Debug macros. Slightly useful for finding bugs in pppd, not particularly
+ * useful for finding out why your connection isn't being established.
+ */
+
+#ifdef DEBUGALL
+#define DEBUGMAIN 1
+#define DEBUGFSM 1
+#define DEBUGLCP 1
+#define DEBUGIPCP 1
+#define DEBUGIPV6CP 1
+#define DEBUGUPAP 1
+#define DEBUGCHAP 1
+#endif
+#define DEBUGMAIN 1
+#define DEBUGUPAP 1
+#define DEBUGCHAP 1
+
+
+#ifdef DEBUGMAIN
+#define MAINDEBUG(x) if (debug) dbglog x
+#else
+#define MAINDEBUG(x)
+#endif
+
+#ifdef DEBUGSYS
+#define SYSDEBUG(x) if (debug) dbglog x
+#else
+#define SYSDEBUG(x)
+#endif
+
+#ifdef DEBUGFSM
+#define FSMDEBUG(x) if (debug) dbglog x
+#else
+#define FSMDEBUG(x)
+#endif
+
+#ifdef DEBUGLCP
+#define LCPDEBUG(x) if (debug) dbglog x
+#else
+#define LCPDEBUG(x)
+#endif
+
+#ifdef DEBUGIPCP
+#define IPCPDEBUG(x) if (debug) dbglog x
+#else
+#define IPCPDEBUG(x)
+#endif
+
+#ifdef DEBUGIPV6CP
+#define IPV6CPDEBUG(x) if (debug) dbglog x
+#else
+#define IPV6CPDEBUG(x)
+#endif
+
+#ifdef DEBUGUPAP
+#define UPAPDEBUG(x) if (debug) dbglog x
+#else
+#define UPAPDEBUG(x)
+#endif
+
+#ifdef DEBUGCHAP
+#define CHAPDEBUG(x) if (debug) dbglog x
+#else
+#define CHAPDEBUG(x)
+#endif
+
+#ifdef DEBUGIPXCP
+#define IPXCPDEBUG(x) if (debug) dbglog x
+#else
+#define IPXCPDEBUG(x)
+#endif
+
+#ifndef SIGTYPE
+#if defined(sun) || defined(SYSV) || defined(POSIX_SOURCE)
+#define SIGTYPE void
+#else
+#define SIGTYPE int
+#endif /* defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) */
+#endif /* SIGTYPE */
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b)? (a): (b))
+#endif
+#ifndef MAX
+#define MAX(a, b) ((a) > (b)? (a): (b))
+#endif
+
+#endif /* __PPP_H__ */
diff --git a/cpukit/pppd/preinstall.am b/cpukit/pppd/preinstall.am
new file mode 100644
index 0000000000..4a9671a238
--- /dev/null
+++ b/cpukit/pppd/preinstall.am
@@ -0,0 +1,43 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-local: $(TMPINSTALL_FILES)
+
+TMPINSTALL_FILES =
+CLEANFILES = $(TMPINSTALL_FILES)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES += $(PREINSTALL_FILES)
+
+$(PROJECT_LIB)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_LIB)
+ @: > $(PROJECT_LIB)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
+
+if HAS_NETWORKING
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/rtemspppd.h: rtemspppd.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtemspppd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtemspppd.h
+
+$(PROJECT_INCLUDE)/rtems/rtemsdialer.h: rtemsdialer.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtemsdialer.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtemsdialer.h
+
+$(PROJECT_LIB)/libpppd.a: libpppd.a $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/libpppd.a
+TMPINSTALL_FILES += $(PROJECT_LIB)/libpppd.a
+endif
diff --git a/cpukit/pppd/rtemsdialer.h b/cpukit/pppd/rtemsdialer.h
new file mode 100644
index 0000000000..611986b802
--- /dev/null
+++ b/cpukit/pppd/rtemsdialer.h
@@ -0,0 +1,24 @@
+
+#ifndef DIALER_H
+#define DIALER_H
+
+/* define constant mode values */
+#define DIALER_INIT 0
+#define DIALER_CONNECT 1
+#define DIALER_WELCOME 2
+#define DIALER_DISCONNECT 3
+
+/* define constant return values */
+#define DIALER_SUCCESS 0
+#define DIALER_INVALIDARG 1
+#define DIALER_UNEXPECTED 2
+#define DIALER_TIMEOUT 3
+#define DIALER_CMDFAILED 4
+
+/* define typedef for dialer function prototype */
+typedef int (*dialerfp)(int tty, int mode, char *pScript);
+
+/* declare default chat program dialer */
+extern int chatmain(int tty, int mode, char *pScript);
+
+#endif
diff --git a/cpukit/pppd/rtemsmain.c b/cpukit/pppd/rtemsmain.c
new file mode 100644
index 0000000000..4180453555
--- /dev/null
+++ b/cpukit/pppd/rtemsmain.c
@@ -0,0 +1,896 @@
+/*
+ * main.c - Point-to-Point Protocol main module
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ */
+
+#define RCSID "$Id$"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+
+#include "pppd.h"
+#include "magic.h"
+#include "fsm.h"
+#include "lcp.h"
+#include "ipcp.h"
+#ifdef INET6
+#include "ipv6cp.h"
+#endif
+#include "upap.h"
+#include "chap.h"
+#include "ccp.h"
+#include "pathnames.h"
+#include "patchlevel.h"
+#include "rtemsdialer.h"
+
+#ifdef CBCP_SUPPORT
+#include "cbcp.h"
+#endif
+
+#ifdef IPX_CHANGE
+#include "ipxcp.h"
+#endif /* IPX_CHANGE */
+#ifdef AT_CHANGE
+#include "atcp.h"
+#endif
+
+static const char rcsid[] = RCSID;
+
+/* interface vars */
+char ifname[32]; /* Interface name */
+int pppifunit; /* Interface unit number */
+
+char hostname[MAXNAMELEN]; /* Our hostname */
+static char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */
+
+int pppd_ttyfd; /* Serial port file descriptor */
+int baud_rate; /* Actual bits/second for serial device */
+int hungup; /* terminal has been hung up */
+int privileged; /* we're running as real uid root */
+int need_holdoff; /* need holdoff period before restarting */
+int detached; /* have detached from terminal */
+struct stat devstat; /* result of stat() on devnam */
+int prepass = 0; /* doing prepass to find device name */
+int devnam_fixed; /* set while in options.ttyxx file */
+volatile int pppd_status; /* exit status for pppd */
+int unsuccess; /* # unsuccessful connection attempts */
+int do_callback; /* != 0 if we should do callback next */
+int doing_callback; /* != 0 if we are doing callback */
+char *callback_script; /* script for doing callback */
+dialerfp pppd_dialer;
+
+int (*holdoff_hook) __P((void)) = NULL;
+int (*new_phase_hook) __P((int)) = NULL;
+
+static int fd_ppp = -1; /* fd for talking PPP */
+static int pty_master; /* fd for master side of pty */
+static int pty_slave; /* fd for slave side of pty */
+static int real_ttyfd; /* fd for actual serial port (not pty) */
+
+int pppd_phase; /* where the link is at */
+int pppd_kill_link;
+int open_ccp_flag;
+
+char **script_env; /* Env. variable values for scripts */
+int s_env_nalloc; /* # words avail at script_env */
+
+u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */
+u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */
+
+char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n";
+
+static struct timeval start_time; /* Time when link was started. */
+
+struct pppd_stats link_stats;
+int link_connect_time;
+int link_stats_valid;
+
+/* Prototypes for procedures local to this file. */
+
+static void cleanup __P((void));
+static void close_tty __P((void));
+static void get_input __P((void));
+static void calltimeout __P((void));
+static struct timeval *timeleft __P((struct timeval *));
+static void holdoff_end __P((void *));
+static int device_script __P((int, int, char *));
+
+extern char *ttyname __P((int));
+extern char *getlogin __P((void));
+int pppdmain __P((int, char *[]));
+
+/*
+ * PPP Data Link Layer "protocol" table.
+ * One entry per supported protocol.
+ * The last entry must be NULL.
+ */
+struct protent *protocols[] = {
+ &lcp_protent,
+ &pap_protent,
+ &chap_protent,
+#ifdef CBCP_SUPPORT
+ &cbcp_protent,
+#endif
+ &ipcp_protent,
+#ifdef INET6
+ &ipv6cp_protent,
+#endif
+ &ccp_protent,
+#ifdef IPX_CHANGE
+ &ipxcp_protent,
+#endif
+#ifdef AT_CHANGE
+ &atcp_protent,
+#endif
+ NULL
+};
+
+int
+pppdmain(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int i, fdflags, t;
+ char *connector;
+ struct timeval timo;
+ struct protent *protp;
+
+ new_phase(PHASE_INITIALIZE);
+
+ script_env = NULL;
+ hostname[MAXNAMELEN-1] = 0;
+ privileged = 1;
+ privileged_option = 1;
+
+ /*
+ * Initialize magic number generator now so that protocols may
+ * use magic numbers in initialization.
+ */
+ magic_init();
+
+#ifdef XXX_XXX
+ /* moved code the the rtems_pppd_reset_options function */
+
+ /*
+ * Initialize to the standard option set, then parse, in order,
+ * the system options file, the user's options file,
+ * the tty's options file, and the command line arguments.
+ */
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ (*protp->init)(0);
+#endif
+
+
+ if (!ppp_available()) {
+ option_error(no_ppp_msg);
+ return(EXIT_NO_KERNEL_SUPPORT);
+ }
+
+ /*
+ * Check that the options given are valid and consistent.
+ */
+ if (!sys_check_options()) {
+ return(EXIT_OPTION_ERROR);
+ }
+ if (!auth_check_options()) {
+ return(EXIT_OPTION_ERROR);
+ }
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (protp->check_options != NULL)
+ (*protp->check_options)();
+
+ /* default holdoff to 0 if no connect script has been given */
+ if (connect_script == 0 && !holdoff_specified)
+ holdoff = 0;
+
+ if (default_device)
+ nodetach = 1;
+
+ /*
+ * Initialize system-dependent stuff.
+ */
+ sys_init();
+ /* if (debug)
+ setlogmask(LOG_UPTO(LOG_DEBUG));
+ */
+
+ do_callback = 0;
+ for (;;) {
+
+ need_holdoff = 1;
+ pppd_ttyfd = -1;
+ real_ttyfd = -1;
+ pppd_status = EXIT_OK;
+ ++unsuccess;
+ doing_callback = do_callback;
+ do_callback = 0;
+
+ new_phase(PHASE_SERIALCONN);
+
+ /*
+ * Get a pty master/slave pair if the pty, notty, or record
+ * options were specified.
+ */
+ strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
+ pty_master = -1;
+ pty_slave = -1;
+
+ /*
+ * Open the serial device and set it up to be the ppp interface.
+ * First we open it in non-blocking mode so we can set the
+ * various termios flags appropriately. If we aren't dialling
+ * out and we want to use the modem lines, we reopen it later
+ * in order to wait for the carrier detect signal from the modem.
+ */
+ hungup = 0;
+ pppd_kill_link = 0;
+ connector = doing_callback? callback_script: connect_script;
+ if (devnam[0] != 0) {
+ for (;;) {
+ /* If the user specified the device name, become the
+ user before opening it. */
+ int err;
+ pppd_ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0);
+ err = errno;
+ if (pppd_ttyfd >= 0) {
+ break;
+ }
+ errno = err;
+ if (err != EINTR) {
+ error("Failed to open %s: %m", devnam);
+ pppd_status = EXIT_OPEN_FAILED;
+ }
+ if (!persist || err != EINTR)
+ goto fail;
+ }
+ if ((fdflags = fcntl(pppd_ttyfd, F_GETFL)) == -1
+ || fcntl(pppd_ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
+ warn("Couldn't reset non-blocking mode on device: %m");
+
+ /*
+ * Set line speed, flow control, etc.
+ * If we have a non-null connection or initializer script,
+ * on most systems we set CLOCAL for now so that we can talk
+ * to the modem before carrier comes up. But this has the
+ * side effect that we might miss it if CD drops before we
+ * get to clear CLOCAL below. On systems where we can talk
+ * successfully to the modem with CLOCAL clear and CD down,
+ * we could clear CLOCAL at this point.
+ */
+ set_up_tty(pppd_ttyfd, ((connector != NULL && connector[0] != 0)
+ || initializer != NULL));
+ real_ttyfd = pppd_ttyfd;
+ }
+
+ /* run connection script */
+ if ((connector && connector[0]) || initializer) {
+ if (real_ttyfd != -1) {
+ /* XXX do this if doing_callback == CALLBACK_DIALIN? */
+ if (!default_device && modem) {
+ setdtr(real_ttyfd, 0); /* in case modem is off hook */
+ sleep(1);
+ setdtr(real_ttyfd, 1);
+ }
+ }
+
+ if (initializer && initializer[0]) {
+ if (device_script(pppd_ttyfd, DIALER_INIT, initializer) < 0) {
+ error("Initializer script failed");
+ pppd_status = EXIT_INIT_FAILED;
+ goto fail;
+ }
+ if (pppd_kill_link)
+ goto disconnect;
+
+ info("Serial port initialized.");
+ }
+
+ if (connector && connector[0]) {
+ if (device_script(pppd_ttyfd, DIALER_CONNECT, connector) < 0) {
+ error("Connect script failed");
+ pppd_status = EXIT_CONNECT_FAILED;
+ goto fail;
+ }
+ if (pppd_kill_link)
+ goto disconnect;
+
+ info("Serial connection established.");
+ }
+
+ /* set line speed, flow control, etc.;
+ clear CLOCAL if modem option */
+ if (real_ttyfd != -1)
+ set_up_tty(real_ttyfd, 0);
+
+ if (doing_callback == CALLBACK_DIALIN)
+ connector = NULL;
+ }
+
+ /* reopen tty if necessary to wait for carrier */
+ if (connector == NULL && modem && devnam[0] != 0) {
+ for (;;) {
+ if ((i = open(devnam, O_RDWR)) >= 0)
+ break;
+ if (errno != EINTR) {
+ error("Failed to reopen %s: %m", devnam);
+ pppd_status = EXIT_OPEN_FAILED;
+ }
+ if (!persist || errno != EINTR || hungup || pppd_kill_link)
+ goto fail;
+ }
+ close(i);
+ }
+
+ info("Serial connection established.");
+ sleep(1);
+
+ /* run welcome script, if any */
+ if (welcomer && welcomer[0]) {
+ if (device_script(pppd_ttyfd, DIALER_WELCOME, welcomer) < 0)
+ warn("Welcome script failed");
+ }
+
+ /* set up the serial device as a ppp interface */
+ fd_ppp = establish_ppp(pppd_ttyfd);
+ if (fd_ppp < 0) {
+ pppd_status = EXIT_FATAL_ERROR;
+ goto disconnect;
+ }
+
+ if (!demand) {
+ info("Using interface ppp%d", pppifunit);
+ slprintf(ifname, sizeof(ifname), "ppp%d", pppifunit);
+ }
+
+ /*
+ * Start opening the connection and wait for
+ * incoming events (reply, timeout, etc.).
+ */
+ notice("Connect: %s <--> %s", ifname, ppp_devnam);
+ gettimeofday(&start_time, NULL);
+
+ lcp_lowerup(0);
+ lcp_open(0); /* Start protocol */
+
+ open_ccp_flag = 0;
+ pppd_status = EXIT_NEGOTIATION_FAILED;
+ new_phase(PHASE_ESTABLISH);
+ while (pppd_phase != PHASE_DEAD) {
+ wait_input(timeleft(&timo));
+ calltimeout();
+ get_input();
+
+ if (pppd_kill_link) {
+ lcp_close(0, "User request");
+ pppd_kill_link = 0;
+ }
+ if (open_ccp_flag) {
+ if (pppd_phase == PHASE_NETWORK || pppd_phase == PHASE_RUNNING) {
+ ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */
+ (*ccp_protent.open)(0);
+ }
+ open_ccp_flag = 0;
+ }
+ }
+
+ /*
+ * If we may want to bring the link up again, transfer
+ * the ppp unit back to the loopback. Set the
+ * real serial device back to its normal mode of operation.
+ */
+ clean_check();
+ if (demand)
+ restore_loop();
+ disestablish_ppp(pppd_ttyfd);
+ fd_ppp = -1;
+ if (!hungup)
+ lcp_lowerdown(0);
+
+ /*
+ * Run disconnector script, if requested.
+ * XXX we may not be able to do this if the line has hung up!
+ */
+ disconnect:
+ if (disconnect_script && !hungup) {
+ new_phase(PHASE_DISCONNECT);
+ if (real_ttyfd >= 0)
+ set_up_tty(real_ttyfd, 1);
+ if (device_script(pppd_ttyfd, DIALER_DISCONNECT, disconnect_script) < 0) {
+ warn("disconnect script failed");
+ } else {
+ info("Serial link disconnected.");
+ }
+ }
+
+ fail:
+ if (pty_master >= 0)
+ close(pty_master);
+ if (pty_slave >= 0)
+ close(pty_slave);
+ if (real_ttyfd >= 0)
+ close_tty();
+
+ if (!persist || (maxfail > 0 && unsuccess >= maxfail))
+ break;
+
+ pppd_kill_link = 0;
+ if (demand)
+ demand_discard();
+ t = need_holdoff? holdoff: 0;
+ if (holdoff_hook)
+ t = (*holdoff_hook)();
+ if (t > 0) {
+ new_phase(PHASE_HOLDOFF);
+ TIMEOUT(holdoff_end, NULL, t);
+ do {
+ wait_input(timeleft(&timo));
+
+ calltimeout();
+ if (pppd_kill_link) {
+ pppd_kill_link = 0;
+ new_phase(PHASE_DORMANT); /* allow signal to end holdoff */
+ }
+ } while (pppd_phase == PHASE_HOLDOFF);
+ if (!persist)
+ break;
+ }
+ }
+
+ die(pppd_status);
+ return pppd_status;
+}
+
+/*
+ * holdoff_end - called via a timeout when the holdoff period ends.
+ */
+static void
+holdoff_end(arg)
+ void *arg;
+{
+ new_phase(PHASE_DORMANT);
+}
+
+/* List of protocol names, to make our messages a little more informative. */
+struct protocol_list {
+ u_short proto;
+ const char *name;
+} protocol_list[] = {
+ { 0x21, "IP" },
+ { 0x23, "OSI Network Layer" },
+ { 0x25, "Xerox NS IDP" },
+ { 0x27, "DECnet Phase IV" },
+ { 0x29, "Appletalk" },
+ { 0x2b, "Novell IPX" },
+ { 0x2d, "VJ compressed TCP/IP" },
+ { 0x2f, "VJ uncompressed TCP/IP" },
+ { 0x31, "Bridging PDU" },
+ { 0x33, "Stream Protocol ST-II" },
+ { 0x35, "Banyan Vines" },
+ { 0x39, "AppleTalk EDDP" },
+ { 0x3b, "AppleTalk SmartBuffered" },
+ { 0x3d, "Multi-Link" },
+ { 0x3f, "NETBIOS Framing" },
+ { 0x41, "Cisco Systems" },
+ { 0x43, "Ascom Timeplex" },
+ { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" },
+ { 0x47, "DCA Remote Lan" },
+ { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" },
+ { 0x4b, "SNA over 802.2" },
+ { 0x4d, "SNA" },
+ { 0x4f, "IP6 Header Compression" },
+ { 0x6f, "Stampede Bridging" },
+ { 0xfb, "single-link compression" },
+ { 0xfd, "1st choice compression" },
+ { 0x0201, "802.1d Hello Packets" },
+ { 0x0203, "IBM Source Routing BPDU" },
+ { 0x0205, "DEC LANBridge100 Spanning Tree" },
+ { 0x0231, "Luxcom" },
+ { 0x0233, "Sigma Network Systems" },
+ { 0x8021, "Internet Protocol Control Protocol" },
+ { 0x8023, "OSI Network Layer Control Protocol" },
+ { 0x8025, "Xerox NS IDP Control Protocol" },
+ { 0x8027, "DECnet Phase IV Control Protocol" },
+ { 0x8029, "Appletalk Control Protocol" },
+ { 0x802b, "Novell IPX Control Protocol" },
+ { 0x8031, "Bridging NCP" },
+ { 0x8033, "Stream Protocol Control Protocol" },
+ { 0x8035, "Banyan Vines Control Protocol" },
+ { 0x803d, "Multi-Link Control Protocol" },
+ { 0x803f, "NETBIOS Framing Control Protocol" },
+ { 0x8041, "Cisco Systems Control Protocol" },
+ { 0x8043, "Ascom Timeplex" },
+ { 0x8045, "Fujitsu LBLB Control Protocol" },
+ { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" },
+ { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
+ { 0x804b, "SNA over 802.2 Control Protocol" },
+ { 0x804d, "SNA Control Protocol" },
+ { 0x804f, "IP6 Header Compression Control Protocol" },
+ { 0x006f, "Stampede Bridging Control Protocol" },
+ { 0x80fb, "Single Link Compression Control Protocol" },
+ { 0x80fd, "Compression Control Protocol" },
+ { 0xc021, "Link Control Protocol" },
+ { 0xc023, "Password Authentication Protocol" },
+ { 0xc025, "Link Quality Report" },
+ { 0xc027, "Shiva Password Authentication Protocol" },
+ { 0xc029, "CallBack Control Protocol (CBCP)" },
+ { 0xc081, "Container Control Protocol" },
+ { 0xc223, "Challenge Handshake Authentication Protocol" },
+ { 0xc281, "Proprietary Authentication Protocol" },
+ { 0, NULL },
+};
+
+/*
+ * protocol_name - find a name for a PPP protocol.
+ */
+const char *
+protocol_name(proto)
+ int proto;
+{
+ struct protocol_list *lp;
+
+ for (lp = protocol_list; lp->proto != 0; ++lp)
+ if (proto == lp->proto)
+ return lp->name;
+ return NULL;
+}
+
+/*
+ * get_input - called when incoming data is available.
+ */
+static void
+get_input(void)
+{
+ int len, i;
+ u_char *p;
+ u_short protocol;
+ struct protent *protp;
+
+ p = inpacket_buf; /* point to beginning of packet buffer */
+
+ len = read_packet(inpacket_buf);
+ if (len < 0)
+ return;
+
+ if (len == 0) {
+ notice("Modem hangup");
+ hungup = 1;
+ pppd_status = EXIT_HANGUP;
+ lcp_lowerdown(0); /* serial link is no longer available */
+ link_terminated(0);
+ return;
+ }
+
+ if (debug /*&& (debugflags & DBG_INPACKET)*/)
+ dbglog("rcvd %P", p, len);
+
+ if (len < PPP_HDRLEN) {
+ MAINDEBUG(("io(): Received short packet."));
+ return;
+ }
+
+ p += 2; /* Skip address and control */
+ GETSHORT(protocol, p);
+ len -= PPP_HDRLEN;
+
+ /*
+ * Toss all non-LCP packets unless LCP is OPEN.
+ */
+ if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) {
+ MAINDEBUG(("get_input: Received non-LCP packet when LCP not open."));
+ return;
+ }
+
+ /*
+ * Until we get past the authentication phase, toss all packets
+ * except LCP, LQR and authentication packets.
+ */
+ if (pppd_phase <= PHASE_AUTHENTICATE
+ && !(protocol == PPP_LCP || protocol == PPP_LQR
+ || protocol == PPP_PAP || protocol == PPP_CHAP)) {
+ MAINDEBUG(("get_input: discarding proto 0x%x in phase %d",
+ protocol, pppd_phase));
+ return;
+ }
+
+ /*
+ * Upcall the proper protocol input routine.
+ */
+ for (i = 0; (protp = protocols[i]) != NULL; ++i) {
+ if (protp->protocol == protocol && protp->enabled_flag) {
+ (*protp->input)(0, p, len);
+ return;
+ }
+ if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag
+ && protp->datainput != NULL) {
+ (*protp->datainput)(0, p, len);
+ return;
+ }
+ }
+
+ if (debug) {
+ const char *pname = protocol_name(protocol);
+ if (pname != NULL)
+ warn("Unsupported protocol '%s' (0x%x) received", pname, protocol);
+ else
+ warn("Unsupported protocol 0x%x received", protocol);
+ }
+ lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);
+
+ return;
+}
+
+/*
+ * new_phase - signal the start of a new phase of pppd's operation.
+ */
+void
+new_phase(p)
+ int p;
+{
+ pppd_phase = p;
+ if (new_phase_hook)
+ (*new_phase_hook)(p);
+}
+
+/*
+ * die - clean up state and exit with the specified status.
+ */
+void
+die(status)
+ int status;
+{
+ cleanup();
+}
+
+/*
+ * cleanup - restore anything which needs to be restored before we exit
+ */
+/* ARGSUSED */
+static void
+cleanup()
+{
+ sys_cleanup();
+
+ if (fd_ppp >= 0)
+ disestablish_ppp(pppd_ttyfd);
+ if (real_ttyfd >= 0)
+ close_tty();
+
+ sys_close();
+}
+
+/*
+ * close_tty - restore the terminal device and close it.
+ */
+static void
+close_tty()
+{
+ /* drop dtr to hang up */
+ if (!default_device && modem) {
+ setdtr(real_ttyfd, 0);
+ /*
+ * This sleep is in case the serial port has CLOCAL set by default,
+ * and consequently will reassert DTR when we close the device.
+ */
+ sleep(1);
+ }
+
+ restore_tty(real_ttyfd);
+
+ close(real_ttyfd);
+ real_ttyfd = -1;
+}
+
+/*
+ * update_link_stats - get stats at link termination.
+ */
+void
+update_link_stats(u)
+ int u;
+{
+ struct timeval now;
+ char numbuf[32];
+
+ if (!get_ppp_stats(u, &link_stats)
+ || gettimeofday(&now, NULL) < 0)
+ return;
+ link_connect_time = now.tv_sec - start_time.tv_sec;
+ link_stats_valid = 1;
+
+ slprintf(numbuf, sizeof(numbuf), "%d", link_connect_time);
+ slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_out);
+ slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_in);
+}
+
+struct callout {
+ struct timeval c_time; /* time at which to call routine */
+ void *c_arg; /* argument to routine */
+ void (*c_func) __P((void *)); /* routine */
+ struct callout *c_next;
+};
+
+static struct callout *callout = NULL; /* Callout list */
+static struct timeval timenow; /* Current time */
+
+/*
+ * timeout - Schedule a timeout.
+ *
+ * Note that this timeout takes the number of seconds, NOT hz (as in
+ * the kernel).
+ */
+void
+ppptimeout(func, arg, time)
+ void (*func) __P((void *));
+ void *arg;
+ int time;
+{
+ struct callout *newp, *p, **pp;
+
+ MAINDEBUG(("Timeout %p:%p in %d seconds.", func, arg, time));
+
+ /*
+ * Allocate timeout.
+ */
+ if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL)
+ fatal("Out of memory in timeout()!");
+ newp->c_arg = arg;
+ newp->c_func = func;
+ gettimeofday(&timenow, NULL);
+ newp->c_time.tv_sec = timenow.tv_sec + time;
+ newp->c_time.tv_usec = timenow.tv_usec;
+
+ /*
+ * Find correct place and link it in.
+ */
+ for (pp = &callout; (p = *pp); pp = &p->c_next)
+ if (newp->c_time.tv_sec < p->c_time.tv_sec
+ || (newp->c_time.tv_sec == p->c_time.tv_sec
+ && newp->c_time.tv_usec < p->c_time.tv_usec))
+ break;
+ newp->c_next = p;
+ *pp = newp;
+}
+
+
+/*
+ * untimeout - Unschedule a timeout.
+ */
+void
+untimeout(func, arg)
+ void (*func) __P((void *));
+ void *arg;
+{
+ struct callout **copp, *freep;
+
+ MAINDEBUG(("Untimeout %p:%p.", func, arg));
+
+ /*
+ * Find first matching timeout and remove it from the list.
+ */
+ for (copp = &callout; (freep = *copp); copp = &freep->c_next)
+ if (freep->c_func == func && freep->c_arg == arg) {
+ *copp = freep->c_next;
+ free((char *) freep);
+ break;
+ }
+}
+
+
+/*
+ * calltimeout - Call any timeout routines which are now due.
+ */
+static void
+calltimeout()
+{
+ struct callout *p;
+
+ while (callout != NULL) {
+ p = callout;
+
+ if (gettimeofday(&timenow, NULL) < 0)
+ fatal("Failed to get time of day: %m");
+ if (!(p->c_time.tv_sec < timenow.tv_sec
+ || (p->c_time.tv_sec == timenow.tv_sec
+ && p->c_time.tv_usec <= timenow.tv_usec)))
+ break; /* no, it's not time yet */
+
+ callout = p->c_next;
+ (*p->c_func)(p->c_arg);
+
+ free((char *) p);
+ }
+}
+
+
+/*
+ * timeleft - return the length of time until the next timeout is due.
+ */
+static struct timeval *
+timeleft(tvp)
+ struct timeval *tvp;
+{
+ if (callout == NULL)
+ return NULL;
+
+ gettimeofday(&timenow, NULL);
+ tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec;
+ tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec;
+ if (tvp->tv_usec < 0) {
+ tvp->tv_usec += 1000000;
+ tvp->tv_sec -= 1;
+ }
+ if (tvp->tv_sec < 0)
+ tvp->tv_sec = tvp->tv_usec = 0;
+
+ return tvp;
+}
+
+/*
+ * device_script - run a program to talk to the serial device
+ * (e.g. to run the connector or disconnector script).
+ */
+static int device_script(int fd, int mode, char *program)
+{
+ int iReturn = -1;
+ char pScript[128];
+
+ /* copyt script into temporary location */
+ strcpy(pScript, program);
+
+ /* check to see if dialer was initialized */
+ if ( !pppd_dialer ) {
+ /* set default dialer to chatmain */
+ pppd_dialer = chatmain;
+ }
+
+ /* check to see if dialer is set */
+ if ( pppd_dialer ) {
+ /* call the dialer */
+ iReturn = (*pppd_dialer)(fd, mode, program);
+ }
+
+ return ( -iReturn );
+}
+
+/*
+ * novm - log an error message saying we ran out of memory, and die.
+ */
+void
+novm(msg)
+ char *msg;
+{
+ fatal("Virtual memory exhausted allocating %s\n", msg);
+}
diff --git a/cpukit/pppd/rtemspppd.c b/cpukit/pppd/rtemspppd.c
new file mode 100644
index 0000000000..c1c12cd622
--- /dev/null
+++ b/cpukit/pppd/rtemspppd.c
@@ -0,0 +1,228 @@
+/*
+ * COPYRIGHT (c) 2001, Michael Siers <mikes@poliac.com>.
+ * Poliac Research, Burnsville, Minnesota USA.
+ * COPYRIGHT (c) 2001, 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include "pppd.h"
+#include "rtemspppd.h"
+
+
+/* define pppd function prototypes */
+extern void pppasyncattach(void);
+extern int pppdmain(int, char **);
+
+/* define global variables */
+rtems_id rtems_pppd_taskid;
+rtems_pppd_hookfunction rtems_pppd_errorfp;
+rtems_pppd_hookfunction rtems_pppd_exitfp;
+
+
+static rtems_task pppTask(rtems_task_argument arg)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ rtems_option options;
+ rtems_event_set in;
+ rtems_event_set out;
+ int iStatus;
+
+ /* call function to setup ppp line discipline */
+ pppasyncattach();
+
+ /* enter processing loop */
+ in = (RTEMS_EVENT_29 | RTEMS_EVENT_30);
+ options = (RTEMS_EVENT_ANY | RTEMS_WAIT);
+ while ( sc == RTEMS_SUCCESSFUL ) {
+ /* wait for the next event */
+ sc = rtems_event_receive(in, options, RTEMS_NO_TIMEOUT, &out);
+ if ( sc == RTEMS_SUCCESSFUL ) {
+ /* determine which event was sent */
+ if ( out & RTEMS_EVENT_29 ) {
+ /* terminate event received */
+ /* set value to break out of event loop */
+ sc = RTEMS_UNSATISFIED;
+ }
+ else if ( out & RTEMS_EVENT_30 ) {
+ /* connect request */
+ /* execute the pppd main code */
+ iStatus = pppdmain(0, NULL);
+ if ( iStatus == EXIT_OK ) {
+ /* check exit callback */
+ if ( rtems_pppd_exitfp ) {
+ (*rtems_pppd_exitfp)();
+ }
+ }
+ else {
+ /* check error callback */
+ if ( rtems_pppd_errorfp ) {
+ (*rtems_pppd_errorfp)();
+ }
+ }
+ }
+ }
+ }
+
+ /* terminate myself */
+ rtems_pppd_taskid = 0;
+ rtems_task_delete(RTEMS_SELF);
+}
+
+int rtems_pppd_initialize(void)
+{
+ int iReturn = (int)-1;
+ rtems_task_priority priority = 100;
+ rtems_status_code status;
+ rtems_name taskName;
+
+ /* determine priority value */
+ if ( rtems_bsdnet_config.network_task_priority ) {
+ priority = rtems_bsdnet_config.network_task_priority;
+ }
+
+ /* initialize the exit hook */
+ rtems_pppd_exitfp = (rtems_pppd_hookfunction)0;
+
+ /* create the rtems task */
+ taskName = rtems_build_name( 'p', 'p', 'p', 'd' );
+ status = rtems_task_create(taskName, priority, 8192,
+ (RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0)),
+ RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
+ &rtems_pppd_taskid);
+ if ( status == RTEMS_SUCCESSFUL ) {
+ status = rtems_task_start(rtems_pppd_taskid, pppTask, 0);
+ if ( status == RTEMS_SUCCESSFUL ) {
+ iReturn = rtems_pppd_reset_options();
+ }
+ }
+
+ return ( iReturn );
+}
+
+int rtems_pppd_terminate(void)
+{
+ /* send terminate signal to pppd task */
+ rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_29);
+
+ /* call the disconnect function */
+ rtems_pppd_disconnect();
+
+ return ( 0 );
+}
+
+int rtems_pppd_reset_options(void)
+{
+ int i;
+ struct protent *protp;
+
+ /*
+ * Initialize to the standard option set, then parse, in order,
+ * the system options file, the user's options file,
+ * the tty's options file, and the command line arguments.
+ */
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ (*protp->init)(0);
+
+ return ( 0 );
+}
+
+int rtems_pppd_set_hook(int id, rtems_pppd_hookfunction hookfp)
+{
+ int iReturn = (int)0;
+
+ switch ( id ) {
+ case RTEMS_PPPD_LINKUP_HOOK:
+ auth_linkup_hook = hookfp;
+ break;
+ case RTEMS_PPPD_LINKDOWN_HOOK:
+ auth_linkdown_hook = hookfp;
+ break;
+ case RTEMS_PPPD_IPUP_HOOK:
+ ip_up_hook = hookfp;
+ break;
+ case RTEMS_PPPD_IPDOWN_HOOK:
+ ip_down_hook = hookfp;
+ break;
+ case RTEMS_PPPD_ERROR_HOOK:
+ rtems_pppd_errorfp = hookfp;
+ break;
+ case RTEMS_PPPD_EXIT_HOOK:
+ rtems_pppd_exitfp = hookfp;
+ break;
+ default:
+ iReturn = (int)-1;
+ break;
+ }
+
+ return ( iReturn );
+}
+
+int rtems_pppd_set_dialer(rtems_pppd_dialerfunction dialerfp)
+{
+ pppd_dialer = dialerfp;
+ return ( (int)0 );
+}
+
+int rtems_pppd_set_option(const char *pOption, const char *pValue)
+{
+ int iReturn = (int)0;
+ int prevPhase;
+ struct wordlist option;
+ struct wordlist value;
+
+ if ( pOption != (const char *)0 ) {
+ /* initialize the values */
+ option.word = (char *)pOption;
+ option.next = (struct wordlist *)0;
+ if ( pValue != (const char *)0 ) {
+ option.next = &value;
+ value.word = (char *)pValue;
+ value.next = (struct wordlist *)0;
+ }
+
+ /* save current phase value */
+ prevPhase = pppd_phase;
+ pppd_phase = PHASE_INITIALIZE;
+
+ /* process option and reset phase value */
+ iReturn = options_from_list(&option, 1);
+ pppd_phase = prevPhase;
+ }
+
+ return ( iReturn );
+}
+
+int rtems_pppd_connect(void)
+{
+ /* send connect signal to pppd task */
+ rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_30);
+
+ return ( 0 );
+}
+
+static void timeout_terminate(void *arg)
+{
+ /* set pppd global variables to disconnect */
+ persist = 0;
+ pppd_kill_link = 1;
+}
+
+int rtems_pppd_disconnect(void)
+{
+ /* need to wait a little time before we can bring the link down */
+ /* set up time out in 1 seconds */
+ TIMEOUT(timeout_terminate, NULL, 1);
+
+ /* send event to wake up the pppd code */
+ /* pretend its a serial interrput */
+ rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_31);
+
+ return ( 0 );
+}
diff --git a/cpukit/pppd/rtemspppd.h b/cpukit/pppd/rtemspppd.h
new file mode 100644
index 0000000000..8503d402f6
--- /dev/null
+++ b/cpukit/pppd/rtemspppd.h
@@ -0,0 +1,40 @@
+/*
+ * COPYRIGHT (c) 2001, Michael Siers <mikes@poliac.com>.
+ * Poliac Research, Burnsville, Minnesota USA.
+ * COPYRIGHT (c) 2001, 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef RTEMSPPPD_H
+#define RTEMSPPPD_H
+
+
+/* define hook function identifiers */
+#define RTEMS_PPPD_LINKUP_HOOK 1
+#define RTEMS_PPPD_LINKDOWN_HOOK 2
+#define RTEMS_PPPD_IPUP_HOOK 3
+#define RTEMS_PPPD_IPDOWN_HOOK 4
+#define RTEMS_PPPD_ERROR_HOOK 5
+#define RTEMS_PPPD_EXIT_HOOK 6
+
+/* define hook function pointer prototype */
+typedef void (*rtems_pppd_hookfunction)(void);
+typedef int (*rtems_pppd_dialerfunction)(int tty, int mode, char *pScript);
+
+
+/* define pppd function prototyes */
+int rtems_pppd_initialize(void);
+int rtems_pppd_terminate(void);
+int rtems_pppd_reset_options(void);
+int rtems_pppd_set_hook(int id, rtems_pppd_hookfunction hookfp);
+int rtems_pppd_set_dialer(rtems_pppd_dialerfunction dialerfp);
+int rtems_pppd_set_option(const char *pOption, const char *pValue);
+int rtems_pppd_connect(void);
+int rtems_pppd_disconnect(void);
+
+#endif
diff --git a/cpukit/pppd/sys-rtems.c b/cpukit/pppd/sys-rtems.c
new file mode 100644
index 0000000000..0bcc3914ff
--- /dev/null
+++ b/cpukit/pppd/sys-rtems.c
@@ -0,0 +1,1338 @@
+/*
+ * sys-bsd.c - System-dependent procedures for setting up
+ * PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, etc.)
+ *
+ * Copyright (c) 1989 Carnegie Mellon University.
+ * Copyright (c) 1995 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 Carnegie Mellon University and The Australian National University.
+ * The names of the Universities 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 <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#ifdef PPP_FILTER
+#include <net/bpf.h>
+#endif
+
+#include <net/if.h>
+#include <net/ppp_defs.h>
+#include <net/if_ppp.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+#include <netinet/in.h>
+
+#if RTM_VERSION >= 3
+#include <sys/param.h>
+#if defined(NetBSD) && (NetBSD >= 199703)
+#include <netinet/if_inarp.h>
+#else /* NetBSD 1.2D or later */
+#include <netinet/if_ether.h>
+#endif
+#endif
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/termiostypes.h>
+extern int rtems_bsdnet_microseconds_per_tick;
+extern rtems_id rtems_pppd_taskid;
+
+#include "pppd.h"
+#include "fsm.h"
+#include "ipcp.h"
+
+static const char rcsid[] = RCSID;
+
+
+static int initdisc = -1; /* Initial TTY discipline for ppp_fd */
+static int initfdflags = -1; /* Initial file descriptor flags for ppp_fd */
+static int ppp_fd = -1; /* fd which is set to PPP discipline */
+static int rtm_seq;
+
+static int restore_term; /* 1 => we've munged the terminal */
+static struct termios inittermios; /* Initial TTY termios */
+static struct winsize wsinfo; /* Initial window size info */
+
+static int loop_slave = -1;
+static int loop_master;
+
+static unsigned char inbuf[512]; /* buffer for chars read from loopback */
+
+static int sockfd; /* socket for doing interface ioctls */
+
+static int if_is_up; /* the interface is currently up */
+static u_int32_t ifaddrs[2]; /* local and remote addresses we set */
+static u_int32_t default_route_gateway; /* gateway addr for default route */
+static u_int32_t proxy_arp_addr; /* remote addr for proxy arp */
+
+/* Prototypes for procedures local to this file. */
+static int dodefaultroute __P((u_int32_t, int));
+static int get_ether_addr __P((u_int32_t, struct sockaddr_dl *));
+
+
+/*
+ * sys_init - System-dependent initialization.
+ */
+void
+sys_init()
+{
+ /* Get an internet socket for doing socket ioctl's on. */
+ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ fatal("Couldn't create IP socket: %m");
+}
+
+/*
+ * sys_cleanup - restore any system state we modified before exiting:
+ * mark the interface down, delete default route and/or proxy arp entry.
+ * This should call die() because it's called from die().
+ */
+void
+sys_cleanup()
+{
+ struct ifreq ifr;
+
+ if (if_is_up) {
+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0
+ && ((ifr.ifr_flags & IFF_UP) != 0)) {
+ ifr.ifr_flags &= ~IFF_UP;
+ ioctl(sockfd, SIOCSIFFLAGS, &ifr);
+ }
+ }
+ if (ifaddrs[0] != 0)
+ cifaddr(0, ifaddrs[0], ifaddrs[1]);
+ if (default_route_gateway)
+ cifdefaultroute(0, 0, default_route_gateway);
+ if (proxy_arp_addr)
+ cifproxyarp(0, proxy_arp_addr);
+}
+
+/*
+ * sys_close - Clean up in a child process before execing.
+ */
+void
+sys_close()
+{
+ close(sockfd);
+ if (loop_slave >= 0) {
+ close(loop_slave);
+ close(loop_master);
+ }
+}
+
+/*
+ * sys_check_options - check the options that the user specified
+ */
+int
+sys_check_options()
+{
+ return 1;
+}
+
+/*
+ * ppp_available - check whether the system has any ppp interfaces
+ * (in fact we check whether we can do an ioctl on ppp0).
+ */
+int
+ppp_available()
+{
+ int s, ok;
+ struct ifreq ifr;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ return 1; /* can't tell */
+
+ strlcpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
+ ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
+ close(s);
+
+ return ok;
+}
+
+/*
+ * establish_ppp - Turn the serial port into a ppp interface.
+ */
+int
+establish_ppp(fd)
+ int fd;
+{
+ int taskid = (int)rtems_pppd_taskid;
+ int pppdisc = PPPDISC;
+ int x;
+
+ if (demand) {
+ /*
+ * Demand mode - prime the old ppp device to relinquish the unit.
+ */
+ if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0)
+ fatal("ioctl(transfer ppp unit): %m");
+ }
+
+ /*
+ * Save the old line discipline of fd, and set it to PPP.
+ */
+ if (ioctl(fd, TIOCGETD, &initdisc) < 0)
+ fatal("ioctl(TIOCGETD): %m");
+ if (ioctl(fd, TIOCSETD, &pppdisc) < 0)
+ fatal("ioctl(TIOCSETD): %m");
+
+ /* set pppd taskid into the driver */
+ ioctl(fd, PPPIOCSTASK, &taskid);
+
+ if (!demand) {
+ /*
+ * Find out which interface we were given.
+ */
+ if (ioctl(fd, PPPIOCGUNIT, &pppifunit) < 0)
+ fatal("ioctl(PPPIOCGUNIT): %m");
+ } else {
+ /*
+ * Check that we got the same unit again.
+ */
+ if (ioctl(fd, PPPIOCGUNIT, &x) < 0)
+ fatal("ioctl(PPPIOCGUNIT): %m");
+ if (x != pppifunit)
+ fatal("transfer_ppp failed: wanted unit %d, got %d", pppifunit, x);
+ x = TTYDISC;
+ ioctl(loop_slave, TIOCSETD, &x);
+ }
+
+ ppp_fd = fd;
+
+ /*
+ * Enable debug in the driver if requested.
+ */
+ if (kdebugflag) {
+ if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
+ warn("ioctl (PPPIOCGFLAGS): %m");
+ } else {
+ x |= (kdebugflag & 0xFF) * SC_DEBUG;
+ if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
+ warn("ioctl(PPPIOCSFLAGS): %m");
+ }
+ }
+
+ /*
+ * Set device for non-blocking reads.
+ */
+ if ((initfdflags = fcntl(fd, F_GETFL)) == -1
+ || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
+ warn("Couldn't set device to non-blocking mode: %m");
+ }
+
+ return fd;
+}
+
+/*
+ * restore_loop - reattach the ppp unit to the loopback.
+ */
+void
+restore_loop()
+{
+ int x;
+
+ /*
+ * Transfer the ppp interface back to the loopback.
+ */
+ if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0)
+ fatal("ioctl(transfer ppp unit): %m");
+ x = PPPDISC;
+ if (ioctl(loop_slave, TIOCSETD, &x) < 0)
+ fatal("ioctl(TIOCSETD): %m");
+
+ /*
+ * Check that we got the same unit again.
+ */
+ if (ioctl(loop_slave, PPPIOCGUNIT, &x) < 0)
+ fatal("ioctl(PPPIOCGUNIT): %m");
+ if (x != pppifunit)
+ fatal("transfer_ppp failed: wanted unit %d, got %d", pppifunit, x);
+ ppp_fd = loop_slave;
+}
+
+
+/*
+ * disestablish_ppp - Restore the serial port to normal operation.
+ * This shouldn't call die() because it's called from die().
+ */
+void
+disestablish_ppp(fd)
+ int fd;
+{
+ int taskid = (int)0;
+
+ /* clear pppd taskid from the driver */
+ ioctl(fd, PPPIOCSTASK, &taskid);
+
+ /* Reset non-blocking mode on fd. */
+ if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0)
+ warn("Couldn't restore device fd flags: %m");
+ initfdflags = -1;
+
+ /* Restore old line discipline. */
+ if (initdisc >= 0 && ioctl(fd, TIOCSETD, &initdisc) < 0)
+ error("ioctl(TIOCSETD): %m");
+ initdisc = -1;
+
+ if (fd == ppp_fd)
+ ppp_fd = -1;
+}
+
+/*
+ * Check whether the link seems not to be 8-bit clean.
+ */
+void
+clean_check()
+{
+ int x;
+ char *s;
+
+ if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
+ s = NULL;
+ switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
+ case SC_RCV_B7_0:
+ s = "bit 7 set to 1";
+ break;
+ case SC_RCV_B7_1:
+ s = "bit 7 set to 0";
+ break;
+ case SC_RCV_EVNP:
+ s = "odd parity";
+ break;
+ case SC_RCV_ODDP:
+ s = "even parity";
+ break;
+ }
+ if (s != NULL) {
+ warn("Serial link is not 8-bit clean:");
+ warn("All received characters had %s", s);
+ }
+ }
+}
+
+/*
+ * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
+ * at the requested speed, etc. If `local' is true, set CLOCAL
+ * regardless of whether the modem option was specified.
+ *
+ * For *BSD, we assume that speed_t values numerically equal bits/second.
+ */
+void
+set_up_tty(fd, local)
+ int fd, local;
+{
+ struct termios tios;
+
+ if (tcgetattr(fd, &tios) < 0)
+ fatal("tcgetattr: %m");
+
+ if (!restore_term) {
+ inittermios = tios;
+ ioctl(fd, TIOCGWINSZ, &wsinfo);
+ }
+
+ tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
+ if (crtscts > 0 && !local) {
+ if (crtscts == 2) {
+#ifdef CDTRCTS
+ tios.c_cflag |= CDTRCTS;
+#endif
+ } else
+ tios.c_cflag |= CRTSCTS;
+ } else if (crtscts < 0) {
+ tios.c_cflag &= ~CRTSCTS;
+#ifdef CDTRCTS
+ tios.c_cflag &= ~CDTRCTS;
+#endif
+ }
+
+ tios.c_cflag |= CS8 | CREAD | HUPCL;
+ if (local || !modem)
+ tios.c_cflag |= CLOCAL;
+ tios.c_iflag = IGNBRK | IGNPAR;
+ tios.c_oflag = 0;
+ tios.c_lflag = 0;
+ tios.c_cc[VMIN] = 1;
+ tios.c_cc[VTIME] = 0;
+
+ if (crtscts == -2) {
+ tios.c_iflag |= IXON | IXOFF;
+ tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
+ tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
+ }
+
+ if (inspeed) {
+ cfsetospeed(&tios, inspeed);
+ cfsetispeed(&tios, inspeed);
+ } else {
+ inspeed = cfgetospeed(&tios);
+ /*
+ * We can't proceed if the serial port speed is 0,
+ * since that implies that the serial port is disabled.
+ */
+ if (inspeed == 0)
+ fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
+ }
+ baud_rate = inspeed;
+
+/* if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { */
+ if (tcsetattr(fd, TCSADRAIN, &tios) < 0) {
+ fatal("tcsetattr: %m");
+ }
+
+ restore_term = 1;
+}
+
+/*
+ * restore_tty - restore the terminal to the saved settings.
+ */
+void
+restore_tty(fd)
+ int fd;
+{
+ if (restore_term) {
+ if (!default_device) {
+ /*
+ * Turn off echoing, because otherwise we can get into
+ * a loop with the tty and the modem echoing to each other.
+ * We presume we are the sole user of this tty device, so
+ * when we close it, it will revert to its defaults anyway.
+ */
+ inittermios.c_lflag &= ~(ECHO | ECHONL);
+ }
+/* if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) { */
+ if (tcsetattr(fd, TCSADRAIN, &inittermios) < 0) {
+ if (errno != ENXIO)
+ warn("tcsetattr: %m");
+ }
+ ioctl(fd, TIOCSWINSZ, &wsinfo);
+ restore_term = 0;
+ }
+}
+
+/*
+ * setdtr - control the DTR line on the serial port.
+ * This is called from die(), so it shouldn't call die().
+ */
+void
+setdtr(fd, on)
+int fd, on;
+{
+ int modembits = TIOCM_DTR;
+
+ ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
+}
+
+/*
+ * get_pty - get a pty master/slave pair and chown the slave side
+ * to the uid given. Assumes slave_name points to >= 12 bytes of space.
+ */
+int
+get_pty(master_fdp, slave_fdp, slave_name, uid)
+ int *master_fdp;
+ int *slave_fdp;
+ char *slave_name;
+ int uid;
+{
+ return 1;
+}
+
+
+/*
+ * open_ppp_loopback - open the device we use for getting
+ * packets in demand mode, and connect it to a ppp interface.
+ * Here we use a pty.
+ */
+int
+open_ppp_loopback()
+{
+ return loop_master;
+}
+
+
+/*
+ * output - Output PPP packet.
+ */
+void
+output(unit, p, len)
+ int unit;
+ u_char *p;
+ int len;
+{
+ if (debug);
+ dbglog("sent %P", p, len);
+/* printf("sent packet [%d]\n", len); */
+
+ if (write(pppd_ttyfd, p, len) < 0) {
+ if (errno != EIO)
+ error("write: %m");
+ }
+}
+
+void
+ppp_delay(void)
+{
+ rtems_interval ticks;
+
+ /* recommended delay to help negotiation */
+ ticks = 300000/rtems_bsdnet_microseconds_per_tick;
+ rtems_task_wake_after(ticks);
+}
+
+/*
+ * wait_input - wait until there is data available,
+ * for the length of time specified by *timo (indefinite
+ * if timo is NULL).
+ */
+void
+wait_input(timo)
+ struct timeval *timo;
+{
+ rtems_event_set events;
+ rtems_interval ticks = 0;
+ rtems_option wait = RTEMS_WAIT;
+
+ if(timo) {
+ if(timo->tv_sec == 0 && timo->tv_usec == 0)
+ wait = RTEMS_NO_WAIT;
+ else {
+ ticks = (timo->tv_sec * 1000000 + timo->tv_usec) /
+ rtems_bsdnet_microseconds_per_tick;
+ if(ticks <= 0)
+ ticks = 1;
+ }
+ }
+ rtems_event_receive(RTEMS_EVENT_31, RTEMS_EVENT_ANY | wait, ticks, &events);
+}
+
+/*
+ * read_packet - get a PPP packet from the serial device.
+ */
+int
+read_packet(buf)
+ u_char *buf;
+{
+ int len;
+
+ if ((len = read(pppd_ttyfd, buf, PPP_MTU + PPP_HDRLEN)) < 0) {
+ if (errno == EWOULDBLOCK || errno == EINTR) len = -1;
+ /*fatal("read: %m"); */
+ }
+
+/* printf("read packet [%d]\n", len); */
+ return len;
+}
+
+
+/*
+ * get_loop_output - read characters from the loopback, form them
+ * into frames, and detect when we want to bring the real link up.
+ * Return value is 1 if we need to bring up the link, 0 otherwise.
+ */
+int
+get_loop_output()
+{
+ int rv = 0;
+ int n;
+
+ while ((n = read(loop_master, inbuf, sizeof(inbuf))) >= 0) {
+ if (loop_chars(inbuf, n))
+ rv = 1;
+ }
+
+ if (n == 0)
+ fatal("eof on loopback");
+ if (errno != EWOULDBLOCK)
+ fatal("read from loopback: %m");
+
+ return rv;
+}
+
+
+/*
+ * ppp_send_config - configure the transmit characteristics of
+ * the ppp interface.
+ */
+void
+ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
+ int unit, mtu;
+ u_int32_t asyncmap;
+ int pcomp, accomp;
+{
+ u_int x;
+ struct ifreq ifr;
+
+ strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ ifr.ifr_mtu = mtu;
+ if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
+ fatal("ioctl(SIOCSIFMTU): %m");
+
+ if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0)
+ fatal("ioctl(PPPIOCSASYNCMAP): %m");
+
+ if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0)
+ fatal("ioctl (PPPIOCGFLAGS): %m");
+ x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT;
+ x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC;
+/* x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC; */
+ if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
+ fatal("ioctl(PPPIOCSFLAGS): %m");
+}
+
+
+/*
+ * ppp_set_xaccm - set the extended transmit ACCM for the interface.
+ */
+void
+ppp_set_xaccm(unit, accm)
+ int unit;
+ ext_accm accm;
+{
+ if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY)
+ warn("ioctl(set extended ACCM): %m");
+}
+
+
+/*
+ * ppp_recv_config - configure the receive-side characteristics of
+ * the ppp interface.
+ */
+void
+ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
+ int unit, mru;
+ u_int32_t asyncmap;
+ int pcomp, accomp;
+{
+ int x;
+
+ if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
+ fatal("ioctl(PPPIOCSMRU): %m");
+ if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0)
+ fatal("ioctl(PPPIOCSRASYNCMAP): %m");
+ if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0)
+ fatal("ioctl (PPPIOCGFLAGS): %m");
+ x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC;
+ if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
+ fatal("ioctl(PPPIOCSFLAGS): %m");
+}
+
+/*
+ * ccp_test - ask kernel whether a given compression method
+ * is acceptable for use. Returns 1 if the method and parameters
+ * are OK, 0 if the method is known but the parameters are not OK
+ * (e.g. code size should be reduced), or -1 if the method is unknown.
+ */
+int
+ccp_test(unit, opt_ptr, opt_len, for_transmit)
+ int unit, opt_len, for_transmit;
+ u_char *opt_ptr;
+{
+ struct ppp_option_data data;
+
+ data.ptr = opt_ptr;
+ data.length = opt_len;
+ data.transmit = for_transmit;
+ if (ioctl(pppd_ttyfd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
+ return 1;
+ return (errno == ENOBUFS)? 0: -1;
+}
+
+/*
+ * ccp_flags_set - inform kernel about the current state of CCP.
+ */
+void
+ccp_flags_set(unit, isopen, isup)
+ int unit, isopen, isup;
+{
+ int x;
+
+ if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
+ error("ioctl (PPPIOCGFLAGS): %m");
+ return;
+ }
+ x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN;
+ x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP;
+ if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
+ error("ioctl(PPPIOCSFLAGS): %m");
+}
+
+/*
+ * ccp_fatal_error - returns 1 if decompression was disabled as a
+ * result of an error detected after decompression of a packet,
+ * 0 otherwise. This is necessary because of patent nonsense.
+ */
+int
+ccp_fatal_error(unit)
+ int unit;
+{
+ int x;
+
+ if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
+ error("ioctl(PPPIOCGFLAGS): %m");
+ return 0;
+ }
+ return x & SC_DC_FERROR;
+}
+
+/*
+ * get_idle_time - return how long the link has been idle.
+ */
+int
+get_idle_time(u, ip)
+ int u;
+ struct ppp_idle *ip;
+{
+ return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0;
+}
+
+/*
+ * get_ppp_stats - return statistics for the link.
+ */
+int
+get_ppp_stats(u, stats)
+ int u;
+ struct pppd_stats *stats;
+{
+ struct ifpppstatsreq req;
+
+ memset (&req, 0, sizeof (req));
+ strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name));
+ if (ioctl(sockfd, SIOCGPPPSTATS, &req) < 0) {
+ error("Couldn't get PPP statistics: %m");
+ return 0;
+ }
+ stats->bytes_in = req.stats.p.ppp_ibytes;
+ stats->bytes_out = req.stats.p.ppp_obytes;
+ return 1;
+}
+
+
+#ifdef PPP_FILTER
+/*
+ * set_filters - transfer the pass and active filters to the kernel.
+ */
+int
+set_filters(pass, active)
+ struct bpf_program *pass, *active;
+{
+ int ret = 1;
+
+ if (pass->bf_len > 0) {
+ if (ioctl(ppp_fd, PPPIOCSPASS, pass) < 0) {
+ error("Couldn't set pass-filter in kernel: %m");
+ ret = 0;
+ }
+ }
+ if (active->bf_len > 0) {
+ if (ioctl(ppp_fd, PPPIOCSACTIVE, active) < 0) {
+ error("Couldn't set active-filter in kernel: %m");
+ ret = 0;
+ }
+ }
+ return ret;
+}
+#endif
+
+/*
+ * sifvjcomp - config tcp header compression
+ */
+int
+sifvjcomp(u, vjcomp, cidcomp, maxcid)
+ int u, vjcomp, cidcomp, maxcid;
+{
+ u_int x;
+
+ if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {
+ error("ioctl (PPPIOCGFLAGS): %m");
+ return 0;
+ }
+ x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP;
+ x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID;
+ if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {
+ error("ioctl(PPPIOCSFLAGS): %m");
+ return 0;
+ }
+ if (vjcomp && ioctl(ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
+ error("ioctl(PPPIOCSMAXCID): %m");
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * sifup - Config the interface up and enable IP packets to pass.
+ */
+int
+sifup(u)
+ int u;
+{
+ struct ifreq ifr;
+
+ strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
+ error("ioctl (SIOCGIFFLAGS): %m");
+ return 0;
+ }
+ ifr.ifr_flags |= IFF_UP;
+ if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
+ error("ioctl(SIOCSIFFLAGS): %m");
+ return 0;
+ }
+ if_is_up = 1;
+ return 1;
+}
+
+/*
+ * sifnpmode - Set the mode for handling packets for a given NP.
+ */
+int
+sifnpmode(u, proto, mode)
+ int u;
+ int proto;
+ enum NPmode mode;
+{
+ struct npioctl npi;
+
+ npi.protocol = proto;
+ npi.mode = mode;
+ if (ioctl(ppp_fd, PPPIOCSNPMODE, &npi) < 0) {
+ error("ioctl(set NP %d mode to %d): %m", proto, mode);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * sifdown - Config the interface down and disable IP.
+ */
+int
+sifdown(u)
+ int u;
+{
+ struct ifreq ifr;
+ int rv;
+ struct npioctl npi;
+
+ rv = 1;
+ npi.protocol = PPP_IP;
+ npi.mode = NPMODE_ERROR;
+ ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi);
+ /* ignore errors, because ppp_fd might have been closed by now. */
+
+ strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
+ error("ioctl (SIOCGIFFLAGS): %m");
+ rv = 0;
+ } else {
+ ifr.ifr_flags &= ~IFF_UP;
+ if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
+ error("ioctl(SIOCSIFFLAGS): %m");
+ rv = 0;
+ } else
+ if_is_up = 0;
+ }
+ return rv;
+}
+
+/*
+ * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
+ * if it exists.
+ */
+#define SET_SA_FAMILY(addr, family) \
+ BZERO((char *) &(addr), sizeof(addr)); \
+ addr.sa_family = (family); \
+ addr.sa_len = sizeof(addr);
+
+/*
+ * sifaddr - Config the interface IP addresses and netmask.
+ */
+int
+sifaddr(u, o, h, m)
+ int u;
+ u_int32_t o, h, m;
+{
+ struct ifaliasreq ifra;
+ struct ifreq ifr;
+
+ strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
+ SET_SA_FAMILY(ifra.ifra_addr, AF_INET);
+ ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;
+ SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
+ ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;
+ if (m != 0) {
+ SET_SA_FAMILY(ifra.ifra_mask, AF_INET);
+ ((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m;
+ } else
+ BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
+ BZERO(&ifr, sizeof(ifr));
+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) {
+ if (errno != EADDRNOTAVAIL)
+ warn("Couldn't remove interface address: %m");
+ }
+ if (ioctl(sockfd, SIOCAIFADDR, (caddr_t) &ifra) < 0) {
+ if (errno != EEXIST) {
+ error("Couldn't set interface address: %m");
+ return 0;
+ }
+ warn("Couldn't set interface address: Address %I already exists", o);
+ }
+ ifaddrs[0] = o;
+ ifaddrs[1] = h;
+ return 1;
+}
+
+/*
+ * cifaddr - Clear the interface IP addresses, and delete routes
+ * through the interface if possible.
+ */
+int
+cifaddr(u, o, h)
+ int u;
+ u_int32_t o, h;
+{
+ struct ifaliasreq ifra;
+
+ ifaddrs[0] = 0;
+ strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
+ SET_SA_FAMILY(ifra.ifra_addr, AF_INET);
+ ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;
+ SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
+ ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;
+ BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
+ if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifra) < 0) {
+ if (errno != EADDRNOTAVAIL)
+ warn("Couldn't delete interface address: %m");
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * sifdefaultroute - assign a default route through the address given.
+ */
+int
+sifdefaultroute(u, l, g)
+ int u;
+ u_int32_t l, g;
+{
+ return dodefaultroute(g, 's');
+}
+
+/*
+ * cifdefaultroute - delete a default route through the address given.
+ */
+int
+cifdefaultroute(u, l, g)
+ int u;
+ u_int32_t l, g;
+{
+ return dodefaultroute(g, 'c');
+}
+
+/*
+ * dodefaultroute - talk to a routing socket to add/delete a default route.
+ */
+static int
+dodefaultroute(g, cmd)
+ u_int32_t g;
+ int cmd;
+{
+/* int status; */
+ struct sockaddr_in address;
+ struct sockaddr_in netmask;
+ struct sockaddr_in gateway;
+
+ memset((void *) &address, 0, sizeof(address));
+ address.sin_len = sizeof address;
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = INADDR_ANY;
+
+ memset((void *) &netmask, 0, sizeof(netmask));
+ netmask.sin_len = sizeof netmask;
+ netmask.sin_addr.s_addr = INADDR_ANY;
+ netmask.sin_family = AF_INET;
+
+ if (cmd=='s') {
+ memset((void *) &gateway, 0, sizeof(gateway));
+ gateway.sin_len = sizeof gateway;
+ gateway.sin_family = AF_INET;
+ gateway.sin_addr.s_addr = g;
+
+ rtems_bsdnet_rtrequest(RTM_ADD,
+ (struct sockaddr *)&address,
+ (struct sockaddr *)&gateway,
+ (struct sockaddr *)&netmask,
+ (RTF_UP|RTF_GATEWAY|RTF_STATIC), NULL);
+ }
+ else {
+ memset((void *) &gateway, 0, sizeof(gateway));
+ gateway.sin_len = sizeof gateway;
+ gateway.sin_family = AF_INET;
+ gateway.sin_addr.s_addr = INADDR_ANY;
+
+ rtems_bsdnet_rtrequest(RTM_DELETE,
+ (struct sockaddr *)&address,
+ (struct sockaddr *)&gateway,
+ (struct sockaddr *)&netmask,
+ (RTF_UP|RTF_STATIC), NULL);
+ }
+
+ default_route_gateway = (cmd == 's')? g: 0;
+
+ return 1;
+}
+
+#if RTM_VERSION >= 3
+
+/*
+ * sifproxyarp - Make a proxy ARP entry for the peer.
+ */
+static struct {
+ struct rt_msghdr hdr;
+ struct sockaddr_inarp dst;
+ struct sockaddr_dl hwa;
+ char extra[128];
+} arpmsg;
+
+static int arpmsg_valid;
+
+int
+sifproxyarp(unit, hisaddr)
+ int unit;
+ u_int32_t hisaddr;
+{
+ int routes;
+
+ /*
+ * Get the hardware address of an interface on the same subnet
+ * as our local address.
+ */
+ memset(&arpmsg, 0, sizeof(arpmsg));
+ if (!get_ether_addr(hisaddr, &arpmsg.hwa)) {
+ error("Cannot determine ethernet address for proxy ARP");
+ return 0;
+ }
+
+ if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
+ error("Couldn't add proxy arp entry: socket: %m");
+ return 0;
+ }
+
+ arpmsg.hdr.rtm_type = RTM_ADD;
+ arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC;
+ arpmsg.hdr.rtm_version = RTM_VERSION;
+ arpmsg.hdr.rtm_seq = ++rtm_seq;
+ arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
+ arpmsg.hdr.rtm_inits = RTV_EXPIRE;
+ arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp);
+ arpmsg.dst.sin_family = AF_INET;
+ arpmsg.dst.sin_addr.s_addr = hisaddr;
+ arpmsg.dst.sin_other = SIN_PROXY;
+
+ arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg
+ + arpmsg.hwa.sdl_len;
+ if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {
+ error("Couldn't add proxy arp entry: %m");
+ close(routes);
+ return 0;
+ }
+
+ close(routes);
+ arpmsg_valid = 1;
+ proxy_arp_addr = hisaddr;
+ return 1;
+}
+
+/*
+ * cifproxyarp - Delete the proxy ARP entry for the peer.
+ */
+int
+cifproxyarp(unit, hisaddr)
+ int unit;
+ u_int32_t hisaddr;
+{
+ int routes;
+
+ if (!arpmsg_valid)
+ return 0;
+ arpmsg_valid = 0;
+
+ arpmsg.hdr.rtm_type = RTM_DELETE;
+ arpmsg.hdr.rtm_seq = ++rtm_seq;
+
+ if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
+ error("Couldn't delete proxy arp entry: socket: %m");
+ return 0;
+ }
+
+ if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {
+ error("Couldn't delete proxy arp entry: %m");
+ close(routes);
+ return 0;
+ }
+
+ close(routes);
+ proxy_arp_addr = 0;
+ return 1;
+}
+
+#else /* RTM_VERSION */
+
+/*
+ * sifproxyarp - Make a proxy ARP entry for the peer.
+ */
+int
+sifproxyarp(unit, hisaddr)
+ int unit;
+ u_int32_t hisaddr;
+{
+ struct arpreq arpreq;
+ struct {
+ struct sockaddr_dl sdl;
+ char space[128];
+ } dls;
+
+ BZERO(&arpreq, sizeof(arpreq));
+
+ /*
+ * Get the hardware address of an interface on the same subnet
+ * as our local address.
+ */
+ if (!get_ether_addr(hisaddr, &dls.sdl)) {
+ error("Cannot determine ethernet address for proxy ARP");
+ return 0;
+ }
+
+ arpreq.arp_ha.sa_len = sizeof(struct sockaddr);
+ arpreq.arp_ha.sa_family = AF_UNSPEC;
+ BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen);
+ SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
+ ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
+ arpreq.arp_flags = ATF_PERM | ATF_PUBL;
+ if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) {
+ error("Couldn't add proxy arp entry: %m");
+ return 0;
+ }
+
+ proxy_arp_addr = hisaddr;
+ return 1;
+}
+
+/*
+ * cifproxyarp - Delete the proxy ARP entry for the peer.
+ */
+int
+cifproxyarp(unit, hisaddr)
+ int unit;
+ u_int32_t hisaddr;
+{
+ struct arpreq arpreq;
+
+ BZERO(&arpreq, sizeof(arpreq));
+ SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
+ ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
+ if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) {
+ warn("Couldn't delete proxy arp entry: %m");
+ return 0;
+ }
+ proxy_arp_addr = 0;
+ return 1;
+}
+#endif /* RTM_VERSION */
+
+
+/*
+ * get_ether_addr - get the hardware address of an interface on the
+ * the same subnet as ipaddr.
+ */
+#define MAX_IFS 32
+
+static int
+get_ether_addr(ipaddr, hwaddr)
+ u_int32_t ipaddr;
+ struct sockaddr_dl *hwaddr;
+{
+ struct ifreq *ifr, *ifend, *ifp;
+ u_int32_t ina, mask;
+ struct sockaddr_dl *dla;
+ struct ifreq ifreq;
+ struct ifconf ifc;
+ struct ifreq ifs[MAX_IFS];
+
+ ifc.ifc_len = sizeof(ifs);
+ ifc.ifc_req = ifs;
+ if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
+ error("ioctl(SIOCGIFCONF): %m");
+ return 0;
+ }
+
+ /*
+ * Scan through looking for an interface with an Internet
+ * address on the same subnet as `ipaddr'.
+ */
+ ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
+ for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)
+ ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) {
+ if (ifr->ifr_addr.sa_family == AF_INET) {
+ ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
+ strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
+ /*
+ * Check that the interface is up, and not point-to-point
+ * or loopback.
+ */
+ if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
+ continue;
+ if ((ifreq.ifr_flags &
+ (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
+ != (IFF_UP|IFF_BROADCAST))
+ continue;
+ /*
+ * Get its netmask and check that it's on the right subnet.
+ */
+ if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
+ continue;
+ mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
+ if ((ipaddr & mask) != (ina & mask))
+ continue;
+
+ break;
+ }
+ }
+
+ if (ifr >= ifend)
+ return 0;
+ info("found interface %s for proxy arp", ifr->ifr_name);
+
+ /*
+ * Now scan through again looking for a link-level address
+ * for this interface.
+ */
+ ifp = ifr;
+ for (ifr = ifc.ifc_req; ifr < ifend; ) {
+ if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0
+ && ifr->ifr_addr.sa_family == AF_LINK) {
+ /*
+ * Found the link-level address - copy it out
+ */
+ dla = (struct sockaddr_dl *) &ifr->ifr_addr;
+ BCOPY(dla, hwaddr, dla->sdl_len);
+ return 1;
+ }
+ ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len);
+ }
+
+ return 0;
+}
+
+/*
+ * Return user specified netmask, modified by any mask we might determine
+ * for address `addr' (in network byte order).
+ * Here we scan through the system's list of interfaces, looking for
+ * any non-point-to-point interfaces which might appear to be on the same
+ * network as `addr'. If we find any, we OR in their netmask to the
+ * user-specified netmask.
+ */
+u_int32_t
+GetMask(addr)
+ u_int32_t addr;
+{
+ u_int32_t mask, nmask, ina;
+ struct ifreq *ifr, *ifend, ifreq;
+ struct ifconf ifc;
+ struct ifreq ifs[MAX_IFS];
+
+ addr = ntohl(addr);
+ if (IN_CLASSA(addr)) /* determine network mask for address class */
+ nmask = IN_CLASSA_NET;
+ else if (IN_CLASSB(addr))
+ nmask = IN_CLASSB_NET;
+ else
+ nmask = IN_CLASSC_NET;
+ /* class D nets are disallowed by bad_ip_adrs */
+ mask = netmask | htonl(nmask);
+
+ /*
+ * Scan through the system's network interfaces.
+ */
+ ifc.ifc_len = sizeof(ifs);
+ ifc.ifc_req = ifs;
+ if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
+ warn("ioctl(SIOCGIFCONF): %m");
+ return mask;
+ }
+ ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
+ for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)
+ ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) {
+ /*
+ * Check the interface's internet address.
+ */
+ if (ifr->ifr_addr.sa_family != AF_INET)
+ continue;
+ ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
+ if ((ntohl(ina) & nmask) != (addr & nmask))
+ continue;
+ /*
+ * Check that the interface is up, and not point-to-point or loopback.
+ */
+ strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
+ if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
+ continue;
+ if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
+ != IFF_UP)
+ continue;
+ /*
+ * Get its netmask and OR it into our mask.
+ */
+ if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
+ continue;
+ mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
+ }
+
+ return mask;
+}
+
+/*
+ * have_route_to - determine if the system has any route to
+ * a given IP address.
+ * For demand mode to work properly, we have to ignore routes
+ * through our own interface.
+ */
+int have_route_to(u_int32_t addr)
+{
+ return -1;
+}
+
+/*
+ * Use the hostid as part of the random number seed.
+ */
+int
+get_host_seed()
+{
+ return 17;
+}
diff --git a/cpukit/pppd/upap.c b/cpukit/pppd/upap.c
new file mode 100644
index 0000000000..dc6be8a98b
--- /dev/null
+++ b/cpukit/pppd/upap.c
@@ -0,0 +1,638 @@
+/*
+ * upap.c - User/Password Authentication Protocol.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ */
+
+#define RCSID "$Id$"
+
+/*
+ * TODO:
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "pppd.h"
+#include "upap.h"
+
+static const char rcsid[] = RCSID;
+
+static bool hide_password = 1;
+
+/*
+ * Command-line options.
+ */
+static option_t pap_option_list[] = {
+ { "hide-password", o_bool, &hide_password,
+ "Don't output passwords to log", 1 },
+ { "show-password", o_bool, &hide_password,
+ "Show password string in debug log messages", 0 },
+ { "pap-restart", o_int, &upap[0].us_timeouttime,
+ "Set retransmit timeout for PAP" },
+ { "pap-max-authreq", o_int, &upap[0].us_maxtransmits,
+ "Set max number of transmissions for auth-reqs" },
+ { "pap-timeout", o_int, &upap[0].us_reqtimeout,
+ "Set time limit for peer PAP authentication" },
+ { NULL }
+};
+
+/*
+ * Protocol entry points.
+ */
+static void upap_init __P((int));
+static void upap_lowerup __P((int));
+static void upap_lowerdown __P((int));
+static void upap_input __P((int, u_char *, int));
+static void upap_protrej __P((int));
+static int upap_printpkt __P((u_char *, int,
+ void (*) __P((void *, char *, ...)), void *));
+
+struct protent pap_protent = {
+ PPP_PAP,
+ upap_init,
+ upap_input,
+ upap_protrej,
+ upap_lowerup,
+ upap_lowerdown,
+ NULL,
+ NULL,
+ upap_printpkt,
+ NULL,
+ 1,
+ "PAP",
+ NULL,
+ pap_option_list,
+ NULL,
+ NULL,
+ NULL
+};
+
+upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
+
+static void upap_timeout __P((void *));
+static void upap_reqtimeout __P((void *));
+static void upap_rauthreq __P((upap_state *, u_char *, int, int));
+static void upap_rauthack __P((upap_state *, u_char *, int, int));
+static void upap_rauthnak __P((upap_state *, u_char *, int, int));
+static void upap_sauthreq __P((upap_state *));
+static void upap_sresp __P((upap_state *, u_char, u_char, char *, int));
+
+
+/*
+ * upap_init - Initialize a UPAP unit.
+ */
+static void
+upap_init(unit)
+ int unit;
+{
+ upap_state *u = &upap[unit];
+
+ u->us_unit = unit;
+ u->us_user = NULL;
+ u->us_userlen = 0;
+ u->us_passwd = NULL;
+ u->us_passwdlen = 0;
+ u->us_clientstate = UPAPCS_INITIAL;
+ u->us_serverstate = UPAPSS_INITIAL;
+ u->us_id = 0;
+ u->us_timeouttime = UPAP_DEFTIMEOUT;
+ u->us_maxtransmits = 10;
+ u->us_reqtimeout = UPAP_DEFREQTIME;
+}
+
+
+/*
+ * upap_authwithpeer - Authenticate us with our peer (start client).
+ *
+ * Set new state and send authenticate's.
+ */
+void
+upap_authwithpeer(unit, user, password)
+ int unit;
+ char *user, *password;
+{
+ upap_state *u = &upap[unit];
+
+ /* Save the username and password we're given */
+ u->us_user = user;
+ u->us_userlen = strlen(user);
+ u->us_passwd = password;
+ u->us_passwdlen = strlen(password);
+ u->us_transmits = 0;
+
+ /* Lower layer up yet? */
+ if (u->us_clientstate == UPAPCS_INITIAL ||
+ u->us_clientstate == UPAPCS_PENDING) {
+ u->us_clientstate = UPAPCS_PENDING;
+ return;
+ }
+
+ upap_sauthreq(u); /* Start protocol */
+}
+
+
+/*
+ * upap_authpeer - Authenticate our peer (start server).
+ *
+ * Set new state.
+ */
+void
+upap_authpeer(unit)
+ int unit;
+{
+ upap_state *u = &upap[unit];
+
+ /* Lower layer up yet? */
+ if (u->us_serverstate == UPAPSS_INITIAL ||
+ u->us_serverstate == UPAPSS_PENDING) {
+ u->us_serverstate = UPAPSS_PENDING;
+ return;
+ }
+
+ u->us_serverstate = UPAPSS_LISTEN;
+ if (u->us_reqtimeout > 0)
+ TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
+}
+
+
+/*
+ * upap_timeout - Retransmission timer for sending auth-reqs expired.
+ */
+static void
+upap_timeout(arg)
+ void *arg;
+{
+ upap_state *u = (upap_state *) arg;
+
+ if (u->us_clientstate != UPAPCS_AUTHREQ)
+ return;
+
+ if (u->us_transmits >= u->us_maxtransmits) {
+ /* give up in disgust */
+ error("No response to PAP authenticate-requests");
+ u->us_clientstate = UPAPCS_BADAUTH;
+ auth_withpeer_fail(u->us_unit, PPP_PAP);
+ return;
+ }
+
+ upap_sauthreq(u); /* Send Authenticate-Request */
+}
+
+
+/*
+ * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
+ */
+static void
+upap_reqtimeout(arg)
+ void *arg;
+{
+ upap_state *u = (upap_state *) arg;
+
+ if (u->us_serverstate != UPAPSS_LISTEN)
+ return; /* huh?? */
+
+ auth_peer_fail(u->us_unit, PPP_PAP);
+ u->us_serverstate = UPAPSS_BADAUTH;
+}
+
+
+/*
+ * upap_lowerup - The lower layer is up.
+ *
+ * Start authenticating if pending.
+ */
+static void
+upap_lowerup(unit)
+ int unit;
+{
+ upap_state *u = &upap[unit];
+
+ if (u->us_clientstate == UPAPCS_INITIAL)
+ u->us_clientstate = UPAPCS_CLOSED;
+ else if (u->us_clientstate == UPAPCS_PENDING) {
+ upap_sauthreq(u); /* send an auth-request */
+ }
+
+ if (u->us_serverstate == UPAPSS_INITIAL)
+ u->us_serverstate = UPAPSS_CLOSED;
+ else if (u->us_serverstate == UPAPSS_PENDING) {
+ u->us_serverstate = UPAPSS_LISTEN;
+ if (u->us_reqtimeout > 0)
+ TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
+ }
+}
+
+
+/*
+ * upap_lowerdown - The lower layer is down.
+ *
+ * Cancel all timeouts.
+ */
+static void
+upap_lowerdown(unit)
+ int unit;
+{
+ upap_state *u = &upap[unit];
+
+ if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */
+ UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
+ if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)
+ UNTIMEOUT(upap_reqtimeout, u);
+
+ u->us_clientstate = UPAPCS_INITIAL;
+ u->us_serverstate = UPAPSS_INITIAL;
+}
+
+
+/*
+ * upap_protrej - Peer doesn't speak this protocol.
+ *
+ * This shouldn't happen. In any case, pretend lower layer went down.
+ */
+static void
+upap_protrej(unit)
+ int unit;
+{
+ upap_state *u = &upap[unit];
+
+ if (u->us_clientstate == UPAPCS_AUTHREQ) {
+ error("PAP authentication failed due to protocol-reject");
+ auth_withpeer_fail(unit, PPP_PAP);
+ }
+ if (u->us_serverstate == UPAPSS_LISTEN) {
+ error("PAP authentication of peer failed (protocol-reject)");
+ auth_peer_fail(unit, PPP_PAP);
+ }
+ upap_lowerdown(unit);
+}
+
+
+/*
+ * upap_input - Input UPAP packet.
+ */
+static void
+upap_input(unit, inpacket, l)
+ int unit;
+ u_char *inpacket;
+ int l;
+{
+ upap_state *u = &upap[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 (l < UPAP_HEADERLEN) {
+ UPAPDEBUG(("pap_input: rcvd short header."));
+ return;
+ }
+ GETCHAR(code, inp);
+ GETCHAR(id, inp);
+ GETSHORT(len, inp);
+ if (len < UPAP_HEADERLEN) {
+ UPAPDEBUG(("pap_input: rcvd illegal length."));
+ return;
+ }
+ if (len > l) {
+ UPAPDEBUG(("pap_input: rcvd short packet."));
+ return;
+ }
+ len -= UPAP_HEADERLEN;
+
+ /*
+ * Action depends on code.
+ */
+ switch (code) {
+ case UPAP_AUTHREQ:
+ upap_rauthreq(u, inp, id, len);
+ break;
+
+ case UPAP_AUTHACK:
+ upap_rauthack(u, inp, id, len);
+ break;
+
+ case UPAP_AUTHNAK:
+ upap_rauthnak(u, inp, id, len);
+ break;
+
+ default: /* XXX Need code reject */
+ break;
+ }
+}
+
+
+/*
+ * upap_rauth - Receive Authenticate.
+ */
+static void
+upap_rauthreq(u, inp, id, len)
+ upap_state *u;
+ u_char *inp;
+ int id;
+ int len;
+{
+ u_char ruserlen, rpasswdlen;
+ char *ruser, *rpasswd;
+ int retcode;
+ char *msg;
+ int msglen;
+
+ if (u->us_serverstate < UPAPSS_LISTEN)
+ return;
+
+ /*
+ * If we receive a duplicate authenticate-request, we are
+ * supposed to return the same status as for the first request.
+ */
+ if (u->us_serverstate == UPAPSS_OPEN) {
+ upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */
+ return;
+ }
+ if (u->us_serverstate == UPAPSS_BADAUTH) {
+ upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */
+ return;
+ }
+
+ /*
+ * Parse user/passwd.
+ */
+ if (len < 1) {
+ UPAPDEBUG(("pap_rauth: rcvd short packet."));
+ return;
+ }
+ GETCHAR(ruserlen, inp);
+ len -= sizeof (u_char) + ruserlen + sizeof (u_char);
+ if (len < 0) {
+ UPAPDEBUG(("pap_rauth: rcvd short packet."));
+ return;
+ }
+ ruser = (char *) inp;
+ INCPTR(ruserlen, inp);
+ GETCHAR(rpasswdlen, inp);
+ if (len < rpasswdlen) {
+ UPAPDEBUG(("pap_rauth: rcvd short packet."));
+ return;
+ }
+ rpasswd = (char *) inp;
+
+ /*
+ * Check the username and password given.
+ */
+ retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,
+ rpasswdlen, &msg);
+ BZERO(rpasswd, rpasswdlen);
+ msglen = strlen(msg);
+ if (msglen > 255)
+ msglen = 255;
+
+ upap_sresp(u, retcode, id, msg, msglen);
+
+ if (retcode == UPAP_AUTHACK) {
+ u->us_serverstate = UPAPSS_OPEN;
+ auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
+ } else {
+ u->us_serverstate = UPAPSS_BADAUTH;
+ auth_peer_fail(u->us_unit, PPP_PAP);
+ }
+
+ if (u->us_reqtimeout > 0)
+ UNTIMEOUT(upap_reqtimeout, u);
+}
+
+
+/*
+ * upap_rauthack - Receive Authenticate-Ack.
+ */
+static void
+upap_rauthack(u, inp, id, len)
+ upap_state *u;
+ u_char *inp;
+ int id;
+ int len;
+{
+ u_char msglen;
+ char *msg;
+
+ if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
+ return;
+
+ /*
+ * Parse message.
+ */
+ if (len < 1) {
+ UPAPDEBUG(("pap_rauthack: ignoring missing msg-length."));
+ } else {
+ GETCHAR(msglen, inp);
+ if (msglen > 0) {
+ len -= sizeof (u_char);
+ if (len < msglen) {
+ UPAPDEBUG(("pap_rauthack: rcvd short packet."));
+ return;
+ }
+ msg = (char *) inp;
+ PRINTMSG(msg, msglen);
+ }
+ }
+
+ u->us_clientstate = UPAPCS_OPEN;
+
+ auth_withpeer_success(u->us_unit, PPP_PAP);
+}
+
+
+/*
+ * upap_rauthnak - Receive Authenticate-Nakk.
+ */
+static void
+upap_rauthnak(u, inp, id, len)
+ upap_state *u;
+ u_char *inp;
+ int id;
+ int len;
+{
+ u_char msglen;
+ char *msg;
+
+ if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
+ return;
+
+ /*
+ * Parse message.
+ */
+ if (len < 1) {
+ UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length."));
+ } else {
+ GETCHAR(msglen, inp);
+ if (msglen > 0) {
+ len -= sizeof (u_char);
+ if (len < msglen) {
+ UPAPDEBUG(("pap_rauthnak: rcvd short packet."));
+ return;
+ }
+ msg = (char *) inp;
+ PRINTMSG(msg, msglen);
+ }
+ }
+
+ u->us_clientstate = UPAPCS_BADAUTH;
+
+ error("PAP authentication failed");
+ auth_withpeer_fail(u->us_unit, PPP_PAP);
+}
+
+
+/*
+ * upap_sauthreq - Send an Authenticate-Request.
+ */
+static void
+upap_sauthreq(u)
+ upap_state *u;
+{
+ u_char *outp;
+ int outlen;
+
+ outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) +
+ u->us_userlen + u->us_passwdlen;
+ outp = outpacket_buf;
+
+ MAKEHEADER(outp, PPP_PAP);
+
+ PUTCHAR(UPAP_AUTHREQ, outp);
+ PUTCHAR(++u->us_id, outp);
+ PUTSHORT(outlen, outp);
+ PUTCHAR(u->us_userlen, outp);
+ BCOPY(u->us_user, outp, u->us_userlen);
+ INCPTR(u->us_userlen, outp);
+ PUTCHAR(u->us_passwdlen, outp);
+ BCOPY(u->us_passwd, outp, u->us_passwdlen);
+
+ output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
+
+ TIMEOUT(upap_timeout, u, u->us_timeouttime);
+ ++u->us_transmits;
+ u->us_clientstate = UPAPCS_AUTHREQ;
+}
+
+
+/*
+ * upap_sresp - Send a response (ack or nak).
+ */
+static void
+upap_sresp(u, code, id, msg, msglen)
+ upap_state *u;
+ u_char code, id;
+ char *msg;
+ int msglen;
+{
+ u_char *outp;
+ int outlen;
+
+ outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
+ outp = outpacket_buf;
+ MAKEHEADER(outp, PPP_PAP);
+
+ PUTCHAR(code, outp);
+ PUTCHAR(id, outp);
+ PUTSHORT(outlen, outp);
+ PUTCHAR(msglen, outp);
+ BCOPY(msg, outp, msglen);
+ output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
+}
+
+/*
+ * upap_printpkt - print the contents of a PAP packet.
+ */
+static char *upap_codenames[] = {
+ "AuthReq", "AuthAck", "AuthNak"
+};
+
+static int
+upap_printpkt(p, plen, printer, arg)
+ u_char *p;
+ int plen;
+ void (*printer) __P((void *, char *, ...));
+ void *arg;
+{
+ int code, id, len;
+ int mlen, ulen, wlen;
+ char *user, *pwd, *msg;
+ u_char *pstart;
+
+ if (plen < UPAP_HEADERLEN)
+ return 0;
+ pstart = p;
+ GETCHAR(code, p);
+ GETCHAR(id, p);
+ GETSHORT(len, p);
+ if (len < UPAP_HEADERLEN || len > plen)
+ return 0;
+
+ if (code >= 1 && code <= sizeof(upap_codenames) / sizeof(char *))
+ printer(arg, " %s", upap_codenames[code-1]);
+ else
+ printer(arg, " code=0x%x", code);
+ printer(arg, " id=0x%x", id);
+ len -= UPAP_HEADERLEN;
+ switch (code) {
+ case UPAP_AUTHREQ:
+ if (len < 1)
+ break;
+ ulen = p[0];
+ if (len < ulen + 2)
+ break;
+ wlen = p[ulen + 1];
+ if (len < ulen + wlen + 2)
+ break;
+ user = (char *) (p + 1);
+ pwd = (char *) (p + ulen + 2);
+ p += ulen + wlen + 2;
+ len -= ulen + wlen + 2;
+ printer(arg, " user=");
+ print_string(user, ulen, printer, arg);
+ printer(arg, " password=");
+ if (!hide_password)
+ print_string(pwd, wlen, printer, arg);
+ else
+ printer(arg, "<hidden>");
+ break;
+ case UPAP_AUTHACK:
+ case UPAP_AUTHNAK:
+ if (len < 1)
+ break;
+ mlen = p[0];
+ if (len < mlen + 1)
+ break;
+ msg = (char *) (p + 1);
+ p += mlen + 1;
+ len -= mlen + 1;
+ printer(arg, " ");
+ print_string(msg, mlen, printer, arg);
+ break;
+ }
+
+ /* print the rest of the bytes in the packet */
+ for (; len > 0; --len) {
+ GETCHAR(code, p);
+ printer(arg, " %.2x", code);
+ }
+
+ return p - pstart;
+}
diff --git a/cpukit/pppd/upap.h b/cpukit/pppd/upap.h
new file mode 100644
index 0000000000..6d5bf64026
--- /dev/null
+++ b/cpukit/pppd/upap.h
@@ -0,0 +1,87 @@
+/*
+ * upap.h - User/Password Authentication Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon 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 Carnegie Mellon 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.
+ *
+ * $Id$
+ */
+
+/*
+ * Packet header = Code, id, length.
+ */
+#define UPAP_HEADERLEN 4
+
+
+/*
+ * UPAP codes.
+ */
+#define UPAP_AUTHREQ 1 /* Authenticate-Request */
+#define UPAP_AUTHACK 2 /* Authenticate-Ack */
+#define UPAP_AUTHNAK 3 /* Authenticate-Nak */
+
+
+/*
+ * Each interface is described by upap structure.
+ */
+typedef struct upap_state {
+ int us_unit; /* Interface unit number */
+ char *us_user; /* User */
+ int us_userlen; /* User length */
+ char *us_passwd; /* Password */
+ int us_passwdlen; /* Password length */
+ int us_clientstate; /* Client state */
+ int us_serverstate; /* Server state */
+ u_char us_id; /* Current id */
+ int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */
+ int us_transmits; /* Number of auth-reqs sent */
+ int us_maxtransmits; /* Maximum number of auth-reqs to send */
+ int us_reqtimeout; /* Time to wait for auth-req from peer */
+} upap_state;
+
+
+/*
+ * Client states.
+ */
+#define UPAPCS_INITIAL 0 /* Connection down */
+#define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */
+#define UPAPCS_PENDING 2 /* Connection down, have requested auth */
+#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */
+#define UPAPCS_OPEN 4 /* We've received an Ack */
+#define UPAPCS_BADAUTH 5 /* We've received a Nak */
+
+/*
+ * Server states.
+ */
+#define UPAPSS_INITIAL 0 /* Connection down */
+#define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */
+#define UPAPSS_PENDING 2 /* Connection down, have requested auth */
+#define UPAPSS_LISTEN 3 /* Listening for an Authenticate */
+#define UPAPSS_OPEN 4 /* We've sent an Ack */
+#define UPAPSS_BADAUTH 5 /* We've sent a Nak */
+
+
+/*
+ * Timeouts.
+ */
+#define UPAP_DEFTIMEOUT 5 /* Timeout (seconds) for retransmitting req */
+#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */
+
+extern upap_state upap[];
+
+void upap_authwithpeer __P((int, char *, char *));
+void upap_authpeer __P((int));
+
+extern struct protent pap_protent;
diff --git a/cpukit/pppd/utils.c b/cpukit/pppd/utils.c
new file mode 100644
index 0000000000..15cdf6b763
--- /dev/null
+++ b/cpukit/pppd/utils.c
@@ -0,0 +1,833 @@
+/*
+ * utils.c - various utility functions used in pppd.
+ *
+ * Copyright (c) 1999 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.
+ */
+
+#define RCSID "$Id$"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <syslog.h>
+#include <pwd.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#ifdef SVR4
+#include <sys/mkdev.h>
+#endif
+
+#include "pppd.h"
+
+static const char rcsid[] = RCSID;
+
+#if defined(SUNOS4)
+extern char *strerror();
+#endif
+
+static void pr_log __P((void *, char *, ...));
+static void logit __P((int, char *, va_list));
+static void vslp_printer __P((void *, char *, ...));
+static void format_packet __P((u_char *, int, void (*) (void *, char *, ...),
+ void *));
+
+struct buffer_info {
+ char *ptr;
+ int len;
+};
+
+/*
+ * slprintf - format a message into a buffer. Like sprintf except we
+ * also specify the length of the output buffer, and we handle
+ * %r (recursive format), %m (error message), %v (visible string),
+ * %q (quoted string), %t (current time) and %I (IP address) formats.
+ * Doesn't do floating-point formats.
+ * Returns the number of chars put into buf.
+ */
+int
+slprintf __V((char *buf, int buflen, char *fmt, ...))
+{
+ va_list args;
+ int n;
+
+#if defined(__STDC__)
+ va_start(args, fmt);
+#else
+ char *buf;
+ int buflen;
+ char *fmt;
+ va_start(args);
+ buf = va_arg(args, char *);
+ buflen = va_arg(args, int);
+ fmt = va_arg(args, char *);
+#endif
+ n = vslprintf(buf, buflen, fmt, args);
+ va_end(args);
+ return n;
+}
+
+/*
+ * vslprintf - like slprintf, takes a va_list instead of a list of args.
+ */
+#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)
+
+int
+vslprintf(buf, buflen, fmt, args)
+ char *buf;
+ int buflen;
+ char *fmt;
+ va_list args;
+{
+ int c, i, n;
+ int width, prec, fillch;
+ int base, len, neg, quoted;
+ unsigned long val = 0;
+ char *str, *f, *buf0;
+ unsigned char *p;
+ char num[32];
+ time_t t;
+ u_int32_t ip;
+ static char hexchars[] = "0123456789abcdef";
+ struct buffer_info bufinfo;
+
+ buf0 = buf;
+ --buflen;
+ while (buflen > 0) {
+ for (f = fmt; *f != '%' && *f != 0; ++f)
+ ;
+ if (f > fmt) {
+ len = f - fmt;
+ if (len > buflen)
+ len = buflen;
+ memcpy(buf, fmt, len);
+ buf += len;
+ buflen -= len;
+ fmt = f;
+ }
+ if (*fmt == 0)
+ break;
+ c = *++fmt;
+ width = 0;
+ prec = -1;
+ fillch = ' ';
+ if (c == '0') {
+ fillch = '0';
+ c = *++fmt;
+ }
+ if (c == '*') {
+ width = va_arg(args, int);
+ c = *++fmt;
+ } else {
+ while (isdigit(c)) {
+ width = width * 10 + c - '0';
+ c = *++fmt;
+ }
+ }
+ if (c == '.') {
+ c = *++fmt;
+ if (c == '*') {
+ prec = va_arg(args, int);
+ c = *++fmt;
+ } else {
+ prec = 0;
+ while (isdigit(c)) {
+ prec = prec * 10 + c - '0';
+ c = *++fmt;
+ }
+ }
+ }
+ str = 0;
+ base = 0;
+ neg = 0;
+ ++fmt;
+ switch (c) {
+ case 'd':
+ i = va_arg(args, int);
+ if (i < 0) {
+ neg = 1;
+ val = -i;
+ } else
+ val = i;
+ base = 10;
+ break;
+ case 'o':
+ val = va_arg(args, unsigned int);
+ base = 8;
+ break;
+ case 'x':
+ case 'X':
+ val = va_arg(args, unsigned int);
+ base = 16;
+ break;
+ case 'p':
+ val = (unsigned long) va_arg(args, void *);
+ base = 16;
+ neg = 2;
+ break;
+ case 's':
+ str = va_arg(args, char *);
+ break;
+ case 'c':
+ num[0] = va_arg(args, int);
+ num[1] = 0;
+ str = num;
+ break;
+ case 'm':
+ str = strerror(errno);
+ break;
+ case 'I':
+ ip = va_arg(args, u_int32_t);
+ ip = ntohl(ip);
+ slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff,
+ (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
+ str = num;
+ break;
+ case 'r':
+ f = va_arg(args, char *);
+#if !defined(__PPC__)
+ n = vslprintf(buf, buflen + 1, f, va_arg(args, va_list));
+#else
+ /* HACK: On the powerpc, a va_list is an array of 1 structure */
+ n = vslprintf(buf, buflen + 1, f, va_arg(args, void *));
+#endif
+ buf += n;
+ buflen -= n;
+ continue;
+ case 't':
+ time(&t);
+ str = ctime(&t);
+ str += 4; /* chop off the day name */
+ str[15] = 0; /* chop off year and newline */
+ break;
+ case 'v': /* "visible" string */
+ case 'q': /* quoted string */
+ quoted = c == 'q';
+ p = va_arg(args, unsigned char *);
+ if (fillch == '0' && prec >= 0) {
+ n = prec;
+ } else {
+ n = strlen((char *)p);
+ if (prec >= 0 && n > prec)
+ n = prec;
+ }
+ while (n > 0 && buflen > 0) {
+ c = *p++;
+ --n;
+ if (!quoted && c >= 0x80) {
+ OUTCHAR('M');
+ OUTCHAR('-');
+ c -= 0x80;
+ }
+ if (quoted && (c == '"' || c == '\\'))
+ OUTCHAR('\\');
+ if (c < 0x20 || (0x7f <= c && c < 0xa0)) {
+ if (quoted) {
+ OUTCHAR('\\');
+ switch (c) {
+ case '\t': OUTCHAR('t'); break;
+ case '\n': OUTCHAR('n'); break;
+ case '\b': OUTCHAR('b'); break;
+ case '\f': OUTCHAR('f'); break;
+ default:
+ OUTCHAR('x');
+ OUTCHAR(hexchars[c >> 4]);
+ OUTCHAR(hexchars[c & 0xf]);
+ }
+ } else {
+ if (c == '\t')
+ OUTCHAR(c);
+ else {
+ OUTCHAR('^');
+ OUTCHAR(c ^ 0x40);
+ }
+ }
+ } else
+ OUTCHAR(c);
+ }
+ continue;
+ case 'P': /* print PPP packet */
+ bufinfo.ptr = buf;
+ bufinfo.len = buflen + 1;
+ p = va_arg(args, unsigned char *);
+ n = va_arg(args, int);
+ format_packet(p, n, vslp_printer, &bufinfo);
+ buf = bufinfo.ptr;
+ buflen = bufinfo.len - 1;
+ continue;
+ case 'B':
+ p = va_arg(args, unsigned char *);
+ for (n = prec; n > 0; --n) {
+ c = *p++;
+ if (fillch == ' ')
+ OUTCHAR(' ');
+ OUTCHAR(hexchars[(c >> 4) & 0xf]);
+ OUTCHAR(hexchars[c & 0xf]);
+ }
+ continue;
+ default:
+ *buf++ = '%';
+ if (c != '%')
+ --fmt; /* so %z outputs %z etc. */
+ --buflen;
+ continue;
+ }
+ if (base != 0) {
+ str = num + sizeof(num);
+ *--str = 0;
+ while (str > num + neg) {
+ *--str = hexchars[val % base];
+ val = val / base;
+ if (--prec <= 0 && val == 0)
+ break;
+ }
+ switch (neg) {
+ case 1:
+ *--str = '-';
+ break;
+ case 2:
+ *--str = 'x';
+ *--str = '0';
+ break;
+ }
+ len = num + sizeof(num) - 1 - str;
+ } else {
+ len = strlen(str);
+ if (prec >= 0 && len > prec)
+ len = prec;
+ }
+ if (width > 0) {
+ if (width > buflen)
+ width = buflen;
+ if ((n = width - len) > 0) {
+ buflen -= n;
+ for (; n > 0; --n)
+ *buf++ = fillch;
+ }
+ }
+ if (len > buflen)
+ len = buflen;
+ memcpy(buf, str, len);
+ buf += len;
+ buflen -= len;
+ }
+ *buf = 0;
+ return buf - buf0;
+}
+
+/*
+ * vslp_printer - used in processing a %P format
+ */
+static void
+vslp_printer __V((void *arg, char *fmt, ...))
+{
+ int n;
+ va_list pvar;
+ struct buffer_info *bi;
+
+#if defined(__STDC__)
+ va_start(pvar, fmt);
+#else
+ void *arg;
+ char *fmt;
+ va_start(pvar);
+ arg = va_arg(pvar, void *);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ bi = (struct buffer_info *) arg;
+ n = vslprintf(bi->ptr, bi->len, fmt, pvar);
+ va_end(pvar);
+
+ bi->ptr += n;
+ bi->len -= n;
+}
+
+/*
+ * log_packet - format a packet and log it.
+ */
+
+char line[256]; /* line to be logged accumulated here */
+char *linep;
+
+void
+log_packet(p, len, prefix, level)
+ u_char *p;
+ int len;
+ char *prefix;
+ int level;
+{
+ strlcpy(line, prefix, sizeof(line));
+ linep = line + strlen(line);
+ format_packet(p, len, pr_log, NULL);
+}
+
+/*
+ * format_packet - make a readable representation of a packet,
+ * calling `printer(arg, format, ...)' to output it.
+ */
+static void
+format_packet(p, len, printer, arg)
+ u_char *p;
+ int len;
+ void (*printer) __P((void *, char *, ...));
+ void *arg;
+{
+ int i, n;
+ u_short proto;
+ struct protent *protp;
+
+ if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
+ p += 2;
+ GETSHORT(proto, p);
+ len -= PPP_HDRLEN;
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (proto == protp->protocol)
+ break;
+ if (protp != NULL) {
+ printer(arg, "[%s", protp->name);
+ n = (*protp->printpkt)(p, len, printer, arg);
+ printer(arg, "]");
+ p += n;
+ len -= n;
+ } else {
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (proto == (protp->protocol & ~0x8000))
+ break;
+ if (protp != 0 && protp->data_name != 0) {
+ printer(arg, "[%s data]", protp->data_name);
+ if (len > 8)
+ printer(arg, "%.8B ...", p);
+ else
+ printer(arg, "%.*B", len, p);
+ len = 0;
+ } else
+ printer(arg, "[proto=0x%x]", proto);
+ }
+ }
+
+ if (len > 32)
+ printer(arg, "%.32B ...", p);
+ else
+ printer(arg, "%.*B", len, p);
+}
+
+static void
+pr_log __V((void *arg, char *fmt, ...))
+{
+ int n;
+ va_list pvar;
+ char buf[256];
+
+#if defined(__STDC__)
+ va_start(pvar, fmt);
+#else
+ void *arg;
+ char *fmt;
+ va_start(pvar);
+ arg = va_arg(pvar, void *);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ n = vslprintf(buf, sizeof(buf), fmt, pvar);
+ va_end(pvar);
+
+ if (linep + n + 1 > line + sizeof(line)) {
+ linep = line;
+ }
+ strlcpy(linep, buf, line + sizeof(line) - linep);
+ linep += n;
+}
+
+/*
+ * print_string - print a readable representation of a string using
+ * printer.
+ */
+void
+print_string(p_arg, len, printer, arg)
+ void *p_arg;
+ int len;
+ void (*printer) __P((void *, char *, ...));
+ void *arg;
+{
+ int c;
+ unsigned char *p = (unsigned char *)p_arg;
+
+ printer(arg, "\"");
+ for (; len > 0; --len) {
+ c = *p++;
+ if (' ' <= c && c <= '~') {
+ if (c == '\\' || c == '"')
+ printer(arg, "\\");
+ printer(arg, "%c", c);
+ } else {
+ switch (c) {
+ case '\n':
+ printer(arg, "\\n");
+ break;
+ case '\r':
+ printer(arg, "\\r");
+ break;
+ case '\t':
+ printer(arg, "\\t");
+ break;
+ default:
+ printer(arg, "\\%.3o", c);
+ }
+ }
+ }
+ printer(arg, "\"");
+}
+
+/*
+ * logit - does the hard work for fatal et al.
+ */
+static void
+logit(level, fmt, args)
+ int level;
+ char *fmt;
+ va_list args;
+{
+ int n;
+ char buf[256];
+
+ n = vslprintf(buf, sizeof(buf), fmt, args);
+/* if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { */
+ if (log_to_fd >= 0 && (debug)) {
+ if (buf[n-1] != '\n')
+ buf[n++] = '\n';
+ if (write(log_to_fd, buf, n) != n)
+ log_to_fd = -1;
+ }
+}
+
+/*
+ * fatal - log an error message and die horribly.
+ */
+void
+pppd_fatal __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if defined(__STDC__)
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_ERR, fmt, pvar);
+ va_end(pvar);
+
+ die(1); /* as promised */
+}
+
+/*
+ * error - log an error message.
+ */
+void
+pppd_error __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if defined(__STDC__)
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_ERR, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * warn - log a warning message.
+ */
+void
+pppd_warn __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if defined(__STDC__)
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_WARNING, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * notice - log a notice-level message.
+ */
+void
+pppd_notice __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if defined(__STDC__)
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_NOTICE, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * info - log an informational message.
+ */
+void
+pppd_info __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if defined(__STDC__)
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_INFO, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * dbglog - log a debug message.
+ */
+void
+pppd_dbglog __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if defined(__STDC__)
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_DEBUG, fmt, pvar);
+ va_end(pvar);
+}
+
+/* Procedures for locking the serial device using a lock file. */
+#ifndef LOCK_DIR
+#ifdef _linux_
+#define LOCK_DIR "/var/lock"
+#else
+#ifdef SVR4
+#define LOCK_DIR "/var/spool/locks"
+#else
+#define LOCK_DIR "/var/spool/lock"
+#endif
+#endif
+#endif /* LOCK_DIR */
+
+static char lock_file[MAXPATHLEN];
+
+/*
+ * lock - create a lock file for the named device
+ */
+int
+lock(dev)
+ char *dev;
+{
+#ifdef LOCKLIB
+ int result;
+
+ result = mklock (dev, (void *) 0);
+ if (result == 0) {
+ strlcpy(lock_file, sizeof(lock_file), dev);
+ return 0;
+ }
+
+ if (result > 0)
+ notice("Device %s is locked by pid %d", dev, result);
+ else
+ error("Can't create lock file %s", lock_file);
+ return -1;
+
+#else /* LOCKLIB */
+
+ char lock_buffer[12];
+ int fd, pid, n;
+
+#ifdef SVR4
+ struct stat sbuf;
+
+ if (stat(dev, &sbuf) < 0) {
+ error("Can't get device number for %s: %m", dev);
+ return -1;
+ }
+ if ((sbuf.st_mode & S_IFMT) != S_IFCHR) {
+ error("Can't lock %s: not a character device", dev);
+ return -1;
+ }
+ slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d",
+ LOCK_DIR, major(sbuf.st_dev),
+ major(sbuf.st_rdev), minor(sbuf.st_rdev));
+#else
+ char *p;
+
+ if ((p = strrchr(dev, '/')) != NULL)
+ dev = p + 1;
+ slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev);
+#endif
+
+ while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
+ if (errno != EEXIST) {
+ error("Can't create lock file %s: %m", lock_file);
+ break;
+ }
+
+ /* Read the lock file to find out who has the device locked. */
+ fd = open(lock_file, O_RDONLY, 0);
+ if (fd < 0) {
+ if (errno == ENOENT) /* This is just a timing problem. */
+ continue;
+ error("Can't open existing lock file %s: %m", lock_file);
+ break;
+ }
+#ifndef LOCK_BINARY
+ n = read(fd, lock_buffer, 11);
+#else
+ n = read(fd, &pid, sizeof(pid));
+#endif /* LOCK_BINARY */
+ close(fd);
+ fd = -1;
+ if (n <= 0) {
+ error("Can't read pid from lock file %s", lock_file);
+ break;
+ }
+
+ /* See if the process still exists. */
+#ifndef LOCK_BINARY
+ lock_buffer[n] = 0;
+ pid = atoi(lock_buffer);
+#endif /* LOCK_BINARY */
+ if (pid == getpid())
+ return 1; /* somebody else locked it for us */
+ if (pid == 0
+ || (kill(pid, 0) == -1 && errno == ESRCH)) {
+ if (unlink (lock_file) == 0) {
+ notice("Removed stale lock on %s (pid %d)", dev, pid);
+ continue;
+ }
+ warn("Couldn't remove stale lock on %s", dev);
+ } else
+ notice("Device %s is locked by pid %d", dev, pid);
+ break;
+ }
+
+ if (fd < 0) {
+ lock_file[0] = 0;
+ return -1;
+ }
+
+ pid = getpid();
+#ifndef LOCK_BINARY
+ slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
+ write (fd, lock_buffer, 11);
+#else
+ write(fd, &pid, sizeof (pid));
+#endif
+ close(fd);
+ return 0;
+
+#endif
+}
+
+/*
+ * relock - called to update our lockfile when we are about to detach,
+ * thus changing our pid (we fork, the child carries on, and the parent dies).
+ * Note that this is called by the parent, with pid equal to the pid
+ * of the child. This avoids a potential race which would exist if
+ * we had the child rewrite the lockfile (the parent might die first,
+ * and another process could think the lock was stale if it checked
+ * between when the parent died and the child rewrote the lockfile).
+ */
+int
+relock(pid)
+ int pid;
+{
+#ifdef LOCKLIB
+ /* XXX is there a way to do this? */
+ return -1;
+#else /* LOCKLIB */
+
+ int fd;
+ char lock_buffer[12];
+
+ if (lock_file[0] == 0)
+ return -1;
+ fd = open(lock_file, O_WRONLY, 0);
+ if (fd < 0) {
+ error("Couldn't reopen lock file %s: %m", lock_file);
+ lock_file[0] = 0;
+ return -1;
+ }
+
+#ifndef LOCK_BINARY
+ slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
+ write (fd, lock_buffer, 11);
+#else
+ write(fd, &pid, sizeof(pid));
+#endif /* LOCK_BINARY */
+ close(fd);
+ return 0;
+
+#endif /* LOCKLIB */
+}
+
+/*
+ * unlock - remove our lockfile
+ */
+void
+unlock()
+{
+ if (lock_file[0]) {
+#ifdef LOCKLIB
+ (void) rmlock(lock_file, (void *) 0);
+#else
+ unlink(lock_file);
+#endif
+ lock_file[0] = 0;
+ }
+}
diff --git a/cpukit/preinstall.am b/cpukit/preinstall.am
new file mode 100644
index 0000000000..b7f04acd2e
--- /dev/null
+++ b/cpukit/preinstall.am
@@ -0,0 +1,345 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES += $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)
+ @: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+
+if DEPRECATED
+$(PROJECT_INCLUDE)/asm.h: backward/asm.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/asm.h
+
+$(PROJECT_INCLUDE)/chain.h: backward/chain.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/chain.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/chain.h
+
+$(PROJECT_INCLUDE)/clockdrv.h: backward/clockdrv.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/clockdrv.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/clockdrv.h
+
+$(PROJECT_INCLUDE)/confdefs.h: backward/confdefs.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/confdefs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/confdefs.h
+
+$(PROJECT_INCLUDE)/console.h: backward/console.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/console.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/console.h
+
+$(PROJECT_INCLUDE)/imfs.h: backward/imfs.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/imfs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/imfs.h
+
+$(PROJECT_INCLUDE)/iosupp.h: backward/iosupp.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/iosupp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/iosupp.h
+
+$(PROJECT_INCLUDE)/ringbuf.h: backward/ringbuf.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ringbuf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/ringbuf.h
+
+$(PROJECT_INCLUDE)/rtc.h: backward/rtc.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtc.h
+
+$(PROJECT_INCLUDE)/spurious.h: backward/spurious.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/spurious.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/spurious.h
+
+$(PROJECT_INCLUDE)/timerdrv.h: backward/timerdrv.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/timerdrv.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/timerdrv.h
+
+$(PROJECT_INCLUDE)/vmeintr.h: backward/vmeintr.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/vmeintr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/vmeintr.h
+
+if HAS_NETWORKING
+$(PROJECT_INCLUDE)/ftpd.h: backward/ftpd.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ftpd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/ftpd.h
+
+$(PROJECT_INCLUDE)/rtemspppd.h: backward/rtemspppd.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtemspppd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtemspppd.h
+
+$(PROJECT_INCLUDE)/rtemsdialer.h: backward/rtemsdialer.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtemsdialer.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtemsdialer.h
+endif
+$(PROJECT_INCLUDE)/motorola/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/motorola
+ @: > $(PROJECT_INCLUDE)/motorola/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/motorola/$(dirstamp)
+
+$(PROJECT_INCLUDE)/motorola/mc68681.h: backward/motorola/mc68681.h $(PROJECT_INCLUDE)/motorola/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/motorola/mc68681.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/motorola/mc68681.h
+
+$(PROJECT_INCLUDE)/motorola/mc68230.h: backward/motorola/mc68230.h $(PROJECT_INCLUDE)/motorola/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/motorola/mc68230.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/motorola/mc68230.h
+
+$(PROJECT_INCLUDE)/zilog/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/zilog
+ @: > $(PROJECT_INCLUDE)/zilog/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/zilog/$(dirstamp)
+
+$(PROJECT_INCLUDE)/zilog/z8536.h: backward/zilog/z8536.h $(PROJECT_INCLUDE)/zilog/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/zilog/z8536.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/zilog/z8536.h
+
+$(PROJECT_INCLUDE)/zilog/z8036.h: backward/zilog/z8036.h $(PROJECT_INCLUDE)/zilog/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/zilog/z8036.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/zilog/z8036.h
+
+$(PROJECT_INCLUDE)/zilog/z8030.h: backward/zilog/z8030.h $(PROJECT_INCLUDE)/zilog/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/zilog/z8030.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/zilog/z8030.h
+
+if !UNIX
+$(PROJECT_INCLUDE)/dosfs.h: backward/dosfs.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/dosfs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/dosfs.h
+endif
+if HAS_ITRON
+$(PROJECT_INCLUDE)/itron.h: backward/itron.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/itron.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/itron.h
+endif
+endif
+if NEWLIB
+$(PROJECT_INCLUDE)/sys/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/sys
+ @: > $(PROJECT_INCLUDE)/sys/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/sys/$(dirstamp)
+
+$(PROJECT_INCLUDE)/memory.h: libnetworking/memory.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/memory.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/memory.h
+
+if RTEMS_PROVIDES_STDINT_H
+$(PROJECT_INCLUDE)/stdint.h: libcsupport/include/stdint.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/stdint.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/stdint.h
+endif
+if RTEMS_PROVIDES_INTTYPES_H
+$(PROJECT_INCLUDE)/inttypes.h: libcsupport/include/inttypes.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/inttypes.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/inttypes.h
+endif
+$(PROJECT_INCLUDE)/tar.h: libcsupport/include/tar.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tar.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/tar.h
+
+$(PROJECT_INCLUDE)/sys/ioccom.h: libcsupport/include/sys/ioccom.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/ioccom.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/ioccom.h
+
+$(PROJECT_INCLUDE)/sys/filio.h: libcsupport/include/sys/filio.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/filio.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/filio.h
+
+$(PROJECT_INCLUDE)/sys/ioctl.h: libcsupport/include/sys/ioctl.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/ioctl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/ioctl.h
+
+$(PROJECT_INCLUDE)/sys/sockio.h: libcsupport/include/sys/sockio.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/sockio.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/sockio.h
+
+$(PROJECT_INCLUDE)/sys/ttycom.h: libcsupport/include/sys/ttycom.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/ttycom.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/ttycom.h
+
+$(PROJECT_INCLUDE)/sys/termios.h: libcsupport/include/sys/termios.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/termios.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/termios.h
+
+$(PROJECT_INCLUDE)/sys/utsname.h: libcsupport/include/sys/utsname.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/utsname.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/utsname.h
+
+$(PROJECT_INCLUDE)/sys/cdefs.h: libcsupport/include/sys/cdefs.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/cdefs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/cdefs.h
+
+if HAS_NETWORKING
+$(PROJECT_INCLUDE)/rtems/bsdnet/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/bsdnet
+ @: > $(PROJECT_INCLUDE)/rtems/bsdnet/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/bsdnet/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/bsdnet/servers.h: libnetworking/rtems/bsdnet/servers.h $(PROJECT_INCLUDE)/rtems/bsdnet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/bsdnet/servers.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/bsdnet/servers.h
+
+$(PROJECT_INCLUDE)/rtems/bsdnet/_types.h: libnetworking/rtems/bsdnet/_types.h $(PROJECT_INCLUDE)/rtems/bsdnet/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/bsdnet/_types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/bsdnet/_types.h
+endif
+endif
+$(PROJECT_INCLUDE)/rtems/bspIo.h: include/rtems/bspIo.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/bspIo.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/bspIo.h
+
+$(PROJECT_INCLUDE)/rtems/userenv.h: include/rtems/userenv.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/userenv.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/userenv.h
+
+$(PROJECT_INCLUDE)/rtems/fs.h: include/rtems/fs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/fs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/fs.h
+
+$(PROJECT_INCLUDE)/rtems/pci.h: include/rtems/pci.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/pci.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/pci.h
+
+$(PROJECT_INCLUDE)/rtems/stdint.h: include/rtems/stdint.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/stdint.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/stdint.h
+
+$(PROJECT_INCLUDE)/rtems/concat.h: include/rtems/concat.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/concat.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/concat.h
+
+$(PROJECT_INCLUDE)/rtems/tar.h: include/rtems/tar.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/tar.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/tar.h
+
+$(PROJECT_INCLUDE)/rtems/irq.h: include/rtems/irq.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/irq.h
+
+$(PROJECT_INCLUDE)/rtems/imfs.h: libfs/src/imfs/imfs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/imfs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/imfs.h
+
+if !UNIX
+$(PROJECT_INCLUDE)/rtems/dosfs.h: libfs/src/dosfs/dosfs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/dosfs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/dosfs.h
+endif
+if !UNIX
+$(PROJECT_INCLUDE)/rtems/bdbuf.h: libblock/include/rtems/bdbuf.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/bdbuf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/bdbuf.h
+
+$(PROJECT_INCLUDE)/rtems/blkdev.h: libblock/include/rtems/blkdev.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/blkdev.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/blkdev.h
+
+$(PROJECT_INCLUDE)/rtems/diskdevs.h: libblock/include/rtems/diskdevs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/diskdevs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/diskdevs.h
+
+$(PROJECT_INCLUDE)/rtems/ramdisk.h: libblock/include/rtems/ramdisk.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/ramdisk.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/ramdisk.h
+
+$(PROJECT_INCLUDE)/rtems/ide_part_table.h: libblock/include/rtems/ide_part_table.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/ide_part_table.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/ide_part_table.h
+endif
+if HAS_NETWORKING
+$(PROJECT_INCLUDE)/rtems/ftpd.h: ftpd/ftpd.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/ftpd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/ftpd.h
+endif
+$(PROJECT_INCLUDE)/rtems/capture.h: libmisc/capture/capture.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/capture.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/capture.h
+
+$(PROJECT_INCLUDE)/rtems/capture-cli.h: libmisc/capture/capture-cli.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/capture-cli.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/capture-cli.h
+
+$(PROJECT_INCLUDE)/rtems/cpuuse.h: libmisc/cpuuse/cpuuse.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/cpuuse.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/cpuuse.h
+
+$(PROJECT_INCLUDE)/rtems/devnull.h: libmisc/devnull/devnull.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/devnull.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/devnull.h
+
+$(PROJECT_INCLUDE)/rtems/dumpbuf.h: libmisc/dumpbuf/dumpbuf.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/dumpbuf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/dumpbuf.h
+
+$(PROJECT_INCLUDE)/rtems/monitor.h: libmisc/monitor/monitor.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/monitor.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/monitor.h
+
+$(PROJECT_INCLUDE)/rtems/mw_fb.h: libmisc/mw-fb/mw_fb.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/mw_fb.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/mw_fb.h
+
+$(PROJECT_INCLUDE)/rtems/mw_uid.h: libmisc/mw-fb/mw_uid.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/mw_uid.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/mw_uid.h
+
+if LIBSHELL
+$(PROJECT_INCLUDE)/rtems/shell.h: libmisc/shell/shell.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/shell.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/shell.h
+endif
+$(PROJECT_INCLUDE)/rtems/rtmonuse.h: libmisc/rtmonuse/rtmonuse.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtmonuse.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtmonuse.h
+
+$(PROJECT_INCLUDE)/rtems/libi2c.h: libi2c/libi2c.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/libi2c.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/libi2c.h
+
+if LIBSERDBG
+$(PROJECT_INCLUDE)/rtems/serdbgcnf.h: libmisc/serdbg/serdbgcnf.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/serdbgcnf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/serdbgcnf.h
+
+$(PROJECT_INCLUDE)/rtems/serdbg.h: libmisc/serdbg/serdbg.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/serdbg.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/serdbg.h
+
+$(PROJECT_INCLUDE)/rtems/termios_printk_cnf.h: libmisc/serdbg/termios_printk_cnf.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/termios_printk_cnf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/termios_printk_cnf.h
+
+$(PROJECT_INCLUDE)/rtems/termios_printk.h: libmisc/serdbg/termios_printk.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/termios_printk.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/termios_printk.h
+endif
+$(PROJECT_INCLUDE)/rtems/stackchk.h: libmisc/stackchk/stackchk.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/stackchk.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/stackchk.h
+
+$(PROJECT_INCLUDE)/rtems/untar.h: libmisc/untar/untar.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/untar.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/untar.h
+
+$(PROJECT_INCLUDE)/rtems/fsmount.h: libmisc/fsmount/fsmount.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/fsmount.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/fsmount.h
+
diff --git a/cpukit/rtems/.cvsignore b/cpukit/rtems/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/rtems/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am
new file mode 100644
index 0000000000..352214d0d3
--- /dev/null
+++ b/cpukit/rtems/Makefile.am
@@ -0,0 +1,136 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+AM_CPPFLAGS += -D__RTEMS_INSIDE__
+
+noinst_LIBRARIES = librtems.a
+librtems_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+# include
+
+include_HEADERS = include/rtems.h
+
+# include/rtems/rtems
+include_rtems_rtemsdir = $(includedir)/rtems/rtems
+
+include_rtems_rtems_HEADERS = include/rtems/rtems/asr.h \
+ include/rtems/rtems/attr.h include/rtems/rtems/cache.h \
+ include/rtems/rtems/clock.h include/rtems/rtems/config.h \
+ include/rtems/rtems/dpmem.h include/rtems/rtems/event.h \
+ include/rtems/rtems/eventset.h include/rtems/rtems/intr.h \
+ include/rtems/rtems/message.h include/rtems/rtems/modes.h \
+ include/rtems/rtems/options.h include/rtems/rtems/part.h \
+ include/rtems/rtems/ratemon.h include/rtems/rtems/region.h \
+ include/rtems/rtems/rtemsapi.h include/rtems/rtems/sem.h \
+ include/rtems/rtems/signal.h include/rtems/rtems/status.h \
+ include/rtems/rtems/support.h include/rtems/rtems/tasks.h \
+ include/rtems/rtems/timer.h include/rtems/rtems/types.h
+
+if HAS_MP
+## We only build multiprocessing related files if HAS_MP was defined
+include_rtems_rtems_HEADERS += include/rtems/rtems/eventmp.h \
+ include/rtems/rtems/mp.h include/rtems/rtems/msgmp.h \
+ include/rtems/rtems/partmp.h include/rtems/rtems/regionmp.h \
+ include/rtems/rtems/semmp.h include/rtems/rtems/signalmp.h \
+ include/rtems/rtems/taskmp.h
+endif
+
+if INLINE
+include_rtems_rtems_HEADERS += inline/rtems/rtems/asr.inl \
+ inline/rtems/rtems/attr.inl inline/rtems/rtems/dpmem.inl \
+ inline/rtems/rtems/event.inl inline/rtems/rtems/eventset.inl \
+ inline/rtems/rtems/message.inl inline/rtems/rtems/modes.inl \
+ inline/rtems/rtems/options.inl inline/rtems/rtems/part.inl \
+ inline/rtems/rtems/ratemon.inl inline/rtems/rtems/region.inl \
+ inline/rtems/rtems/sem.inl inline/rtems/rtems/status.inl \
+ inline/rtems/rtems/support.inl inline/rtems/rtems/tasks.inl \
+ inline/rtems/rtems/timer.inl
+else
+include_rtems_rtems_HEADERS += macros/rtems/rtems/asr.inl \
+ macros/rtems/rtems/attr.inl macros/rtems/rtems/dpmem.inl \
+ macros/rtems/rtems/event.inl macros/rtems/rtems/eventset.inl \
+ macros/rtems/rtems/message.inl macros/rtems/rtems/modes.inl \
+ macros/rtems/rtems/options.inl macros/rtems/rtems/part.inl \
+ macros/rtems/rtems/ratemon.inl macros/rtems/rtems/region.inl \
+ macros/rtems/rtems/sem.inl macros/rtems/rtems/status.inl \
+ macros/rtems/rtems/support.inl macros/rtems/rtems/tasks.inl \
+ macros/rtems/rtems/timer.inl
+endif
+
+## src
+librtems_a_SOURCES =
+
+## TASK_C_FILES
+librtems_a_SOURCES += src/tasks.c src/taskcreate.c src/taskdelete.c \
+ src/taskgetnote.c src/taskident.c src/taskinitusers.c \
+ src/taskissuspended.c src/taskmode.c src/taskrestart.c src/taskresume.c \
+ src/tasksetnote.c src/tasksetpriority.c src/taskstart.c \
+ src/tasksuspend.c src/taskwakeafter.c src/taskwakewhen.c \
+ src/taskvariableadd.c src/taskvariabledelete.c src/taskvariableget.c
+
+## RATEMON_C_FILES
+librtems_a_SOURCES += src/ratemon.c src/ratemoncancel.c src/ratemoncreate.c \
+ src/ratemondelete.c src/ratemongetstatus.c src/ratemonident.c \
+ src/ratemonperiod.c src/ratemontimeout.c
+
+## INTR_C_FILES
+librtems_a_SOURCES += src/intr.c src/intrbody.c src/intrcatch.c
+
+## CLOCK_C_FILES
+librtems_a_SOURCES += src/rtclock.c src/clockget.c src/clockset.c src/clocktick.c
+
+## TIMER_C_FILES
+librtems_a_SOURCES += src/rtemstimer.c src/timercancel.c src/timercreate.c \
+ src/timerdelete.c src/timerfireafter.c src/timerfirewhen.c \
+ src/timergetinfo.c src/timerident.c src/timerreset.c src/timerserver.c \
+ src/timerserverfireafter.c src/timerserverfirewhen.c
+
+## MESSAGE_QUEUE_C_FILES
+librtems_a_SOURCES += src/msg.c src/msgqallocate.c src/msgqbroadcast.c \
+ src/msgqcreate.c src/msgqdelete.c src/msgqflush.c \
+ src/msgqgetnumberpending.c src/msgqident.c src/msgqreceive.c \
+ src/msgqsend.c src/msgqsubmit.c src/msgqtranslatereturncode.c \
+ src/msgqurgent.c
+
+## SEMAPHORE_C_FILES
+librtems_a_SOURCES += src/sem.c src/semcreate.c src/semdelete.c src/semident.c \
+ src/semobtain.c src/semrelease.c src/semflush.c \
+ src/semtranslatereturncode.c
+
+## EVENT_C_FILES
+librtems_a_SOURCES += src/event.c src/eventreceive.c src/eventseize.c \
+ src/eventsend.c src/eventsurrender.c src/eventtimeout.c
+
+## SIGNAL_C_FILES
+librtems_a_SOURCES += src/signal.c src/signalcatch.c src/signalsend.c
+
+## REGION_C_FILES
+librtems_a_SOURCES += src/region.c src/regioncreate.c src/regiondelete.c \
+ src/regionextend.c src/regiongetsegment.c src/regiongetsegmentsize.c \
+ src/regionident.c src/regionreturnsegment.c src/regiongetinfo.c \
+ src/regiongetfreeinfo.c src/regionresizesegment.c \
+ src/regionprocessqueue.c
+
+## PARTITION_C_FILES
+librtems_a_SOURCES += src/part.c src/partcreate.c src/partdelete.c \
+ src/partgetbuffer.c src/partident.c src/partreturnbuffer.c
+
+## DPMEM_C_FILES
+librtems_a_SOURCES += src/dpmem.c src/dpmemcreate.c src/dpmemdelete.c \
+ src/dpmemexternal2internal.c src/dpmemident.c \
+ src/dpmeminternal2external.c
+
+librtems_a_SOURCES += src/attr.c src/rtemsidtoname.c
+
+if HAS_MP
+# We only build multiprocessing related files if HAS_MP was defined
+librtems_a_SOURCES += src/eventmp.c src/mp.c src/msgmp.c src/partmp.c \
+ src/regionmp.c src/semmp.c src/signalmp.c src/taskmp.c
+endif
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/rtems/include/rtems.h b/cpukit/rtems/include/rtems.h
new file mode 100644
index 0000000000..2cbfee49f0
--- /dev/null
+++ b/cpukit/rtems/include/rtems.h
@@ -0,0 +1,146 @@
+/**
+ * @file rtems.h
+ */
+
+/*
+ * This include file contains information about RTEMS executive that
+ * is required by the application and is CPU independent. It includes
+ * two (2) CPU dependent files to tailor its data structures for a
+ * particular processor.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_H
+#define _RTEMS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Unless told otherwise, the RTEMS include files will hide some stuff
+ * from normal application code. Defining this crosses a boundary which
+ * is undesirable since it means your application is using RTEMS features
+ * which are not included in the formally defined and supported API.
+ * Define this at your own risk.
+ */
+
+#if (!defined(__RTEMS_VIOLATE_KERNEL_VISIBILITY__)) && (!defined(__RTEMS_INSIDE__))
+#define __RTEMS_APPLICATION__
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+
+#include <rtems/config.h>
+#include <rtems/init.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/rtems/intr.h>
+#include <rtems/rtems/cache.h>
+#include <rtems/rtems/clock.h>
+#include <rtems/extension.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/event.h>
+#include <rtems/rtems/signal.h>
+#include <rtems/rtems/event.h>
+#include <rtems/rtems/part.h>
+#include <rtems/rtems/region.h>
+#include <rtems/rtems/dpmem.h>
+#include <rtems/io.h>
+#include <rtems/fatal.h>
+#include <rtems/rtems/ratemon.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/mp.h>
+#endif
+
+#include <rtems/rtems/support.h>
+#include <rtems/score/sysstate.h>
+
+#define RTEMS_HAS_HARDWARE_FP CPU_HARDWARE_FP
+
+/*
+ * The following define the constants which may be used in name searches.
+ */
+
+#define RTEMS_SEARCH_ALL_NODES OBJECTS_SEARCH_ALL_NODES
+#define RTEMS_SEARCH_OTHER_NODES OBJECTS_SEARCH_OTHER_NODES
+#define RTEMS_SEARCH_LOCAL_NODE OBJECTS_SEARCH_LOCAL_NODE
+#define RTEMS_WHO_AM_I OBJECTS_WHO_AM_I
+
+/*
+ * Parameters and return id's for _Objects_Get_next
+ */
+
+#define RTEMS_OBJECT_ID_INITIAL_INDEX OBJECTS_ID_INITIAL_INDEX
+#define RTEMS_OBJECT_ID_FINAL_INDEX OBJECTS_ID_FINAL_INDEX
+#define RTEMS_OBJECT_ID_INITIAL(api, class, node) OBJECTS_ID_INITIAL(api, class, node)
+
+#define RTEMS_OBJECT_ID_FINAL OBJECTS_ID_FINAL
+
+/*
+ * The following constant defines the minimum stack size which every
+ * thread must exceed.
+ */
+
+#define RTEMS_MINIMUM_STACK_SIZE STACK_MINIMUM_SIZE
+
+/*
+ * Constant for indefinite wait. (actually an illegal interval)
+ */
+
+#define RTEMS_NO_TIMEOUT WATCHDOG_NO_TIMEOUT
+
+/*
+ * An MPCI must support packets of at least this size.
+ */
+
+#define RTEMS_MINIMUM_PACKET_SIZE MP_PACKET_MINIMUM_PACKET_SIZE
+
+/*
+ * The following constant defines the number of uint32_t 's
+ * in a packet which must be converted to native format in a
+ * heterogeneous system. In packets longer than
+ * MP_PACKET_MINIMUN_HETERO_CONVERSION uint32_t 's, some of the "extra" data
+ * may a user message buffer which is not automatically endian swapped.
+ */
+
+#define RTEMS_MINIMUN_HETERO_CONVERSION MP_PACKET_MINIMUN_HETERO_CONVERSION
+
+/*
+ * rtems_object_id_to_name
+ *
+ * This directive returns the name associated with the specified
+ * object ID.
+ *
+ * Input parameters:
+ * id - message queue id
+ *
+ * Output parameters:
+ * *name - user defined object name
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_object_id_to_name(
+ rtems_id id,
+ rtems_name *name
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/asr.h b/cpukit/rtems/include/rtems/rtems/asr.h
new file mode 100644
index 0000000000..6fb7f3db91
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/asr.h
@@ -0,0 +1,114 @@
+/**
+ * @file rtems/rtems/asr.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Asynchronous Signal Handler. This Handler provides the low-level
+ * support required by the Signal Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_ASR_H
+#define _RTEMS_RTEMS_ASR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/modes.h>
+
+/*
+ *
+ * The following type defines the control block used to manage
+ * each signal set.
+ */
+
+typedef uint32_t rtems_signal_set;
+
+/*
+ * Return type for ASR Handler
+ */
+
+typedef void rtems_asr;
+
+/*
+ * The following type corresponds to the applications asynchronous
+ * signal processing routine.
+ */
+
+typedef rtems_asr ( *rtems_asr_entry )(
+ rtems_signal_set
+ );
+
+/*
+ *
+ * The following defines the control structure used to manage
+ * signals. Each thread has a copy of this record.
+ */
+
+typedef struct {
+ boolean is_enabled; /* are ASRs enabled currently? */
+ rtems_asr_entry handler; /* address of RTEMS_ASR */
+ Modes_Control mode_set; /* RTEMS_ASR mode */
+ rtems_signal_set signals_posted; /* signal set */
+ rtems_signal_set signals_pending; /* pending signal set */
+ uint32_t nest_level; /* nest level of RTEMS_ASR */
+} ASR_Information;
+
+/*
+ * The following constants define the individual signals which may
+ * be used to compose a signal set.
+ */
+
+#define RTEMS_SIGNAL_0 0x00000001
+#define RTEMS_SIGNAL_1 0x00000002
+#define RTEMS_SIGNAL_2 0x00000004
+#define RTEMS_SIGNAL_3 0x00000008
+#define RTEMS_SIGNAL_4 0x00000010
+#define RTEMS_SIGNAL_5 0x00000020
+#define RTEMS_SIGNAL_6 0x00000040
+#define RTEMS_SIGNAL_7 0x00000080
+#define RTEMS_SIGNAL_8 0x00000100
+#define RTEMS_SIGNAL_9 0x00000200
+#define RTEMS_SIGNAL_10 0x00000400
+#define RTEMS_SIGNAL_11 0x00000800
+#define RTEMS_SIGNAL_12 0x00001000
+#define RTEMS_SIGNAL_13 0x00002000
+#define RTEMS_SIGNAL_14 0x00004000
+#define RTEMS_SIGNAL_15 0x00008000
+#define RTEMS_SIGNAL_16 0x00010000
+#define RTEMS_SIGNAL_17 0x00020000
+#define RTEMS_SIGNAL_18 0x00040000
+#define RTEMS_SIGNAL_19 0x00080000
+#define RTEMS_SIGNAL_20 0x00100000
+#define RTEMS_SIGNAL_21 0x00200000
+#define RTEMS_SIGNAL_22 0x00400000
+#define RTEMS_SIGNAL_23 0x00800000
+#define RTEMS_SIGNAL_24 0x01000000
+#define RTEMS_SIGNAL_25 0x02000000
+#define RTEMS_SIGNAL_26 0x04000000
+#define RTEMS_SIGNAL_27 0x08000000
+#define RTEMS_SIGNAL_28 0x10000000
+#define RTEMS_SIGNAL_29 0x20000000
+#define RTEMS_SIGNAL_30 0x40000000
+#define RTEMS_SIGNAL_31 0x80000000
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/asr.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/attr.h b/cpukit/rtems/include/rtems/rtems/attr.h
new file mode 100644
index 0000000000..22e78ee052
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/attr.h
@@ -0,0 +1,92 @@
+/**
+ * @file rtems/rtems/attr.h
+ */
+
+/*
+ * This include file contains all information about the Object Attributes
+ * Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_ATTR_H
+#define _RTEMS_RTEMS_ATTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* types */
+
+typedef uint32_t rtems_attribute;
+
+/* constants */
+
+#define RTEMS_DEFAULT_ATTRIBUTES 0x00000000
+
+#define RTEMS_NO_FLOATING_POINT 0x00000000 /* don't use FP HW */
+#define RTEMS_FLOATING_POINT 0x00000001 /* utilize coprocessor */
+
+#define RTEMS_LOCAL 0x00000000 /* local resource */
+#define RTEMS_GLOBAL 0x00000002 /* global resource */
+
+#define RTEMS_FIFO 0x00000000 /* process RTEMS_FIFO */
+#define RTEMS_PRIORITY 0x00000004 /* process by priority */
+
+#define RTEMS_SEMAPHORE_CLASS 0x00000030 /* mask */
+#define RTEMS_COUNTING_SEMAPHORE 0x00000000
+#define RTEMS_BINARY_SEMAPHORE 0x00000010
+#define RTEMS_SIMPLE_BINARY_SEMAPHORE 0x00000020
+
+#define RTEMS_NO_INHERIT_PRIORITY 0x00000000
+#define RTEMS_INHERIT_PRIORITY 0x00000040
+
+#define RTEMS_NO_PRIORITY_CEILING 0x00000000
+#define RTEMS_PRIORITY_CEILING 0x00000080
+
+#define RTEMS_APPLICATION_TASK 0x00000000
+#define RTEMS_SYSTEM_TASK 0x00000100
+
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+#define ATTRIBUTES_NOT_SUPPORTED 0
+#else
+#define ATTRIBUTES_NOT_SUPPORTED RTEMS_FLOATING_POINT
+#endif
+
+#if ( CPU_ALL_TASKS_ARE_FP == TRUE )
+#define ATTRIBUTES_REQUIRED RTEMS_FLOATING_POINT
+#else
+#define ATTRIBUTES_REQUIRED 0
+#endif
+
+/*
+ * _Attributes_Handler_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs initialization for this handler.
+ *
+ * NOTE: There is no initialization required in C. Conditional compilation
+ * takes care of this in C.
+ */
+
+#define _Attributes_Handler_initialization()
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/attr.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/cache.h b/cpukit/rtems/include/rtems/rtems/cache.h
new file mode 100644
index 0000000000..17645346c3
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/cache.h
@@ -0,0 +1,140 @@
+/**
+ * @file rtems/rtems/cache.h
+ */
+
+/*
+ * Cache Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ *
+ * The functions in this file define the API to the RTEMS Cache Manager and
+ * are divided into data cache and instruction cache functions. Data cache
+ * functions are only meaningful if a data cache is supported. Instruction
+ * cache functions are only meaningful if an instruction cache is supported.
+ *
+ * The functions below are implemented with CPU dependent support routines
+ * implemented as part of libcpu. In the event that a CPU does not support a
+ * specific function, the CPU dependent routine does nothing (but does exist).
+ *
+ * At this point, the Cache Manager makes no considerations, and provides no
+ * support for BSP specific issues such as a secondary cache. In such a system,
+ * the CPU dependent routines would have to be modified, or a BSP layer added
+ * to this Manager.
+ */
+
+#ifndef _RTEMS_RTEMS_CACHE_H
+#define _RTEMS_RTEMS_CACHE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/system.h>
+#include <sys/types.h>
+
+/*
+ * These functions will ONLY do something if the
+ * libcpu support includes data cache routines AND
+ * the CPU model supports data caching.
+ */
+
+/*
+ * This function is called to flush the data cache by performing cache
+ * copybacks. It must determine how many cache lines need to be copied
+ * back and then perform the copybacks.
+ */
+void rtems_cache_flush_multiple_data_lines( const void *, size_t );
+
+/*
+ * This function is responsible for performing a data cache invalidate.
+ * It must determine how many cache lines need to be invalidated and then
+ * perform the invalidations.
+ */
+void rtems_cache_invalidate_multiple_data_lines( const void *, size_t );
+
+/*
+ * This function is responsible for performing a data cache flush.
+ * It flushes the entire cache.
+ */
+void rtems_cache_flush_entire_data( void );
+
+/*
+ * This function is responsible for performing a data cache
+ * invalidate. It invalidates the entire cache.
+ */
+void rtems_cache_invalidate_entire_data( void );
+
+/*
+ * This function returns the data cache granularity.
+ */
+int rtems_cache_get_data_line_size( void );
+
+/*
+ * This function freezes the data cache.
+ */
+void rtems_cache_freeze_data( void );
+
+/*
+ * This function unfreezes the data cache.
+ */
+void rtems_cache_unfreeze_data( void );
+
+/*
+ * These functions enable/disable the data cache.
+ */
+void rtems_cache_enable_data( void );
+void rtems_cache_disable_data( void );
+
+/*
+ * These functions will ONLY do something if the
+ * libcpu support includes instruction cache routines AND
+ * the CPU model supports instruction caching.
+ */
+
+/*
+ * This function is responsible for performing an instruction cache
+ * invalidate. It must determine how many cache lines need to be invalidated
+ * and then perform the invalidations.
+ */
+void rtems_cache_invalidate_multiple_instruction_lines( const void *, size_t );
+
+/*
+ * This function is responsible for performing an instruction cache
+ * invalidate. It invalidates the entire cache.
+ */
+void rtems_cache_invalidate_entire_instruction( void );
+
+/*
+ * This function returns the instruction cache granularity.
+ */
+int rtems_cache_get_instruction_line_size( void );
+
+/*
+ * This function freezes the instruction cache.
+ */
+void rtems_cache_freeze_instruction( void );
+
+/*
+ * This function unfreezes the instruction cache.
+ */
+void rtems_cache_unfreeze_instruction( void );
+
+/*
+ * These functions enable/disable the instruction cache.
+ */
+void rtems_cache_enable_instruction( void );
+void rtems_cache_disable_instruction( void );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/clock.h b/cpukit/rtems/include/rtems/rtems/clock.h
new file mode 100644
index 0000000000..c5f8bb080c
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/clock.h
@@ -0,0 +1,105 @@
+/**
+ * @file rtems/rtems/clock.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Clock Manager. This manager provides facilities to set, obtain,
+ * and continually update the current date and time.
+ *
+ * This manager provides directives to:
+ *
+ * + set the current date and time
+ * + obtain the current date and time
+ * + announce a clock tick
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_CLOCK_H
+#define _RTEMS_RTEMS_CLOCK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/tod.h>
+#include <rtems/rtems/types.h>
+
+/*
+ * List of things which can be returned by the rtems_clock_get directive.
+ */
+
+typedef enum {
+ RTEMS_CLOCK_GET_TOD,
+ RTEMS_CLOCK_GET_SECONDS_SINCE_EPOCH,
+ RTEMS_CLOCK_GET_TICKS_SINCE_BOOT,
+ RTEMS_CLOCK_GET_TICKS_PER_SECOND,
+ RTEMS_CLOCK_GET_TIME_VALUE
+} rtems_clock_get_options;
+
+/*
+ * Standard flavor style to return TOD in for a rtems_clock_get option.
+ */
+
+typedef struct {
+ uint32_t seconds;
+ uint32_t microseconds;
+} rtems_clock_time_value;
+
+/*
+ * rtems_clock_get
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_clock_get directive. It returns
+ * one of the following:
+ * + current time of day
+ * + seconds since epoch
+ * + ticks since boot
+ * + ticks per second
+ */
+
+rtems_status_code rtems_clock_get(
+ rtems_clock_get_options option,
+ void *time_buffer
+);
+
+/*
+ * rtems_clock_set
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_clock_set directive. It sets
+ * the current time of day to that in the time_buffer record.
+ */
+
+rtems_status_code rtems_clock_set(
+ rtems_time_of_day *time_buffer
+);
+
+/*
+ * rtems_clock_tick
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_clock_tick directive. It is invoked
+ * to inform RTEMS of the occurrence of a clock tick.
+ */
+
+rtems_status_code rtems_clock_tick( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/config.h b/cpukit/rtems/include/rtems/rtems/config.h
new file mode 100644
index 0000000000..d9c43d556d
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/config.h
@@ -0,0 +1,56 @@
+/**
+ * @file rtems/rtems/config.h
+ */
+
+/*
+ * This include file contains the table of user defined configuration
+ * parameters specific for the RTEMS API.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_CONFIG_H
+#define _RTEMS_RTEMS_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/tasks.h>
+
+/*
+ * The following records define the Configuration Table. The
+ * information contained in this table is required in all
+ * RTEMS systems, whether single or multiprocessor. This
+ * table primarily defines the following:
+ *
+ * + required number of each object type
+ */
+
+typedef struct {
+ uint32_t maximum_tasks;
+ uint32_t maximum_timers;
+ uint32_t maximum_semaphores;
+ uint32_t maximum_message_queues;
+ uint32_t maximum_partitions;
+ uint32_t maximum_regions;
+ uint32_t maximum_ports;
+ uint32_t maximum_periods;
+ uint32_t number_of_initialization_tasks;
+ rtems_initialization_tasks_table *User_initialization_tasks_table;
+} rtems_api_configuration_table;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/dpmem.h b/cpukit/rtems/include/rtems/rtems/dpmem.h
new file mode 100644
index 0000000000..dc48eec822
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/dpmem.h
@@ -0,0 +1,159 @@
+/**
+ * @file rtems/rtems/dpmem.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Dual Ported Memory Manager. This manager provides a mechanism
+ * for converting addresses between internal and external representations
+ * for multiple dual-ported memory areas.
+ *
+ * Directives provided are:
+ *
+ * + create a port
+ * + get ID of a port
+ * + delete a port
+ * + convert external to internal address
+ * + convert internal to external address
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_DPMEM_H
+#define _RTEMS_RTEMS_DPMEM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+
+/*
+ * The following structure defines the port control block. Each port
+ * has a control block associated with it. This control block contains
+ * all information required to support the port related operations.
+ */
+
+typedef struct {
+ Objects_Control Object;
+ void *internal_base; /* base internal address */
+ void *external_base; /* base external address */
+ uint32_t length; /* length of dual-ported area */
+} Dual_ported_memory_Control;
+
+/*
+ * The following define the internal Dual Ported Memory information.
+ */
+
+RTEMS_EXTERN Objects_Information _Dual_ported_memory_Information;
+
+/*
+ * _Dual_ported_memory_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Dual_ported_memory_Manager_initialization(
+ uint32_t maximum_ports
+);
+
+/*
+ * rtems_port_create
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_port_create directive. The port
+ * will have the name name. The port maps onto an area of dual ported
+ * memory of length bytes which has internal_start and external_start
+ * as the internal and external starting addresses, respectively.
+ * It returns the id of the created port in ID.
+ */
+
+rtems_status_code rtems_port_create(
+ rtems_name name,
+ void *internal_start,
+ void *external_start,
+ uint32_t length,
+ Objects_Id *id
+);
+
+/*
+ * rtems_port_ident
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_port_ident directive. This directive
+ * returns the port ID associated with name. If more than one port is
+ * named name, then the port to which the ID belongs is arbitrary.
+ */
+
+rtems_status_code rtems_port_ident(
+ rtems_name name,
+ Objects_Id *id
+);
+
+/*
+ * rtems_port_delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_port_delete directive. It deletes
+ * the port associated with ID.
+ */
+
+rtems_status_code rtems_port_delete(
+ Objects_Id id
+);
+
+/*
+ * rtems_port_external_to_internal
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_port_external_to_internal directive.
+ * It returns the internal port address which maps to the provided
+ * external port address for the specified port ID.
+ */
+
+rtems_status_code rtems_port_external_to_internal(
+ Objects_Id id,
+ void *external,
+ void **internal
+);
+
+/*
+ * rtems_port_internal_to_external
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the Port_internal_to_external directive.
+ * It returns the external port address which maps to the provided
+ * internal port address for the specified port ID.
+ */
+
+rtems_status_code rtems_port_internal_to_external(
+ Objects_Id id,
+ void *internal,
+ void **external
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/dpmem.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h
new file mode 100644
index 0000000000..6de5e76516
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/event.h
@@ -0,0 +1,178 @@
+/**
+ * @file rtems/rtems/event.h
+ */
+
+/*
+ * This include file contains the information pertaining to the Event
+ * Manager. This manager provides a high performance method of communication
+ * and synchronization.
+ *
+ * Directives provided are:
+ *
+ * + send an event set to a task
+ * + receive event condition
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_EVENT_H
+#define _RTEMS_RTEMS_EVENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/rtems/eventset.h>
+
+/*
+ * This constant is passed as the event_in to the
+ * rtems_event_receive directive to determine which events are pending.
+ */
+
+#define EVENT_CURRENT 0
+
+/*
+ * The following enumerated types indicate what happened while the event
+ * manager was in the synchronization window.
+ */
+
+typedef enum {
+ EVENT_SYNC_SYNCHRONIZED,
+ EVENT_SYNC_NOTHING_HAPPENED,
+ EVENT_SYNC_TIMEOUT,
+ EVENT_SYNC_SATISFIED
+} Event_Sync_states;
+
+/*
+ * Event_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Event_Manager_initialization( void );
+
+/*
+ * rtems_event_send
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_event_send directive. It sends
+ * event_in to the task specified by ID. If the task is blocked
+ * waiting to receive events and the posting of event_in satisfies
+ * the task's event condition, then it is unblocked.
+ */
+
+rtems_status_code rtems_event_send (
+ Objects_Id id,
+ rtems_event_set event_in
+);
+
+/*
+ * rtems_event_receive
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_event_receive directive. This
+ * directive is invoked when the calling task wishes to receive
+ * the event_in event condition. One of the fields in the option_set
+ * parameter determines whether the receive request is satisfied if
+ * any or all of the events are pending. If the event condition
+ * is not satisfied immediately, then the task may block with an
+ * optional timeout of TICKS clock ticks or return immediately.
+ * This determination is based on another field in the option_set
+ * parameter. This directive returns the events received in the
+ * event_out parameter.
+ */
+
+rtems_status_code rtems_event_receive (
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out
+);
+
+/*
+ * _Event_Seize
+ *
+ * DESCRIPTION:
+ *
+ * This routine determines if the event condition event_in is
+ * satisfied. If so or if the no_wait option is enabled in option_set,
+ * then the procedure returns immediately. If neither of these
+ * conditions is true, then the calling task is blocked with an
+ * optional timeout of ticks clock ticks.
+ */
+
+void _Event_Seize (
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out
+);
+
+/*
+ * _Event_Surrender
+ *
+ * DESCRIPTION:
+ *
+ * This routine determines if the event condition of the_thread
+ * has been satisfied. If so, it unblocks the_thread.
+ */
+
+void _Event_Surrender (
+ Thread_Control *the_thread
+);
+
+/*
+ * _Event_Timeout
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task's event receive request
+ * has not been satisfied after the specified timeout interval.
+ * The task represented by ID will be unblocked and its status
+ * code will be set in it's control block to indicate that a timeout
+ * has occurred.
+ */
+
+void _Event_Timeout (
+ Objects_Id id,
+ void *ignored
+);
+
+/*
+ * The following defines the synchronization flag used by the
+ * Event Manager to insure that signals sent to the currently
+ * executing thread are received properly.
+ */
+
+RTEMS_EXTERN volatile Event_Sync_states _Event_Sync_state;
+
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/eventmp.h>
+#endif
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/event.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/eventmp.h b/cpukit/rtems/include/rtems/rtems/eventmp.h
new file mode 100644
index 0000000000..e3b149b7d6
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/eventmp.h
@@ -0,0 +1,149 @@
+/**
+ * @file rtems/rtems/eventmp.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the Event Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_EVENTMP_H
+#define _RTEMS_RTEMS_EVENTMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/event.h>
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote event operations.
+ */
+
+typedef enum {
+ EVENT_MP_SEND_REQUEST = 0,
+ EVENT_MP_SEND_RESPONSE = 1
+} Event_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote event operations.
+ */
+
+typedef struct {
+ rtems_packet_prefix Prefix;
+ Event_MP_Remote_operations operation;
+ rtems_event_set event_in;
+} Event_MP_Packet;
+
+/*
+ * _Event_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ *
+ * This routine is not needed since there are no process
+ * packets to be sent by this manager.
+ */
+
+/*
+ * _Event_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+rtems_status_code _Event_MP_Send_request_packet (
+ Event_MP_Remote_operations operation,
+ Objects_Id event_id,
+ rtems_event_set event_in
+);
+
+/*
+ * _Event_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _Event_MP_Send_response_packet (
+ Event_MP_Remote_operations operation,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _Event_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _Event_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/*
+ * _Event_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+/*
+ * _Event_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+/*
+ * _Event_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a event mp packet.
+ */
+
+Event_MP_Packet *_Event_MP_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/rtems/include/rtems/rtems/eventset.h b/cpukit/rtems/include/rtems/rtems/eventset.h
new file mode 100644
index 0000000000..77fbabf763
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/eventset.h
@@ -0,0 +1,91 @@
+/**
+ * @file rtems/rtems/eventset.h
+ */
+
+/*
+ * This include file contains the information pertaining to the
+ * Event Sets Handler. This handler provides methods for the manipulation
+ * of event sets which will be sent and received by tasks.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_EVENTSET_H
+#define _RTEMS_RTEMS_EVENTSET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The following defines the type used to control event sets.
+ */
+
+typedef uint32_t rtems_event_set;
+
+/*
+ * The following constants define the individual events which may
+ * be used to compose an event set.
+ */
+
+#define RTEMS_PENDING_EVENTS 0 /* receive pending events */
+#define RTEMS_ALL_EVENTS 0xFFFFFFFF
+
+#define RTEMS_EVENT_0 0x00000001
+#define RTEMS_EVENT_1 0x00000002
+#define RTEMS_EVENT_2 0x00000004
+#define RTEMS_EVENT_3 0x00000008
+#define RTEMS_EVENT_4 0x00000010
+#define RTEMS_EVENT_5 0x00000020
+#define RTEMS_EVENT_6 0x00000040
+#define RTEMS_EVENT_7 0x00000080
+#define RTEMS_EVENT_8 0x00000100
+#define RTEMS_EVENT_9 0x00000200
+#define RTEMS_EVENT_10 0x00000400
+#define RTEMS_EVENT_11 0x00000800
+#define RTEMS_EVENT_12 0x00001000
+#define RTEMS_EVENT_13 0x00002000
+#define RTEMS_EVENT_14 0x00004000
+#define RTEMS_EVENT_15 0x00008000
+#define RTEMS_EVENT_16 0x00010000
+#define RTEMS_EVENT_17 0x00020000
+#define RTEMS_EVENT_18 0x00040000
+#define RTEMS_EVENT_19 0x00080000
+#define RTEMS_EVENT_20 0x00100000
+#define RTEMS_EVENT_21 0x00200000
+#define RTEMS_EVENT_22 0x00400000
+#define RTEMS_EVENT_23 0x00800000
+#define RTEMS_EVENT_24 0x01000000
+#define RTEMS_EVENT_25 0x02000000
+#define RTEMS_EVENT_26 0x04000000
+#define RTEMS_EVENT_27 0x08000000
+#define RTEMS_EVENT_28 0x10000000
+#define RTEMS_EVENT_29 0x20000000
+#define RTEMS_EVENT_30 0x40000000
+#define RTEMS_EVENT_31 0x80000000
+
+
+/*
+ * The following constant is the value of an event set which
+ * has no events pending.
+ */
+
+#define EVENT_SETS_NONE_PENDING 0
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/eventset.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/intr.h b/cpukit/rtems/include/rtems/rtems/intr.h
new file mode 100644
index 0000000000..281cf8e57b
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/intr.h
@@ -0,0 +1,162 @@
+/**
+ * @file rtems/rtems/intr.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Interrupt Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_INTR_H
+#define _RTEMS_RTEMS_INTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/isr.h>
+
+/*
+ * Interrupt level type
+ */
+
+typedef ISR_Level rtems_interrupt_level;
+
+/*
+ * The following type defines the control block used to manage
+ * the vectors.
+ */
+
+typedef ISR_Vector_number rtems_vector_number;
+
+/*
+ * Return type for ISR Handler
+ */
+
+typedef void rtems_isr;
+
+/*
+ * Pointer to an ISR Handler
+ */
+
+typedef rtems_isr ( *rtems_isr_entry )(
+ rtems_vector_number
+ );
+
+/*
+ * _Interrupt_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine initializes the interrupt manager.
+ *
+ */
+
+void _Interrupt_Manager_initialization( void );
+
+/*
+ * rtems_interrupt_catch
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_interrupt_catch directive. This
+ * directive installs new_isr_handler as the RTEMS interrupt service
+ * routine for vector. The previous RTEMS interrupt service
+ * routine is returned in old_isr_handler.
+ */
+
+rtems_status_code rtems_interrupt_catch(
+ rtems_isr_entry new_isr_handler,
+ rtems_vector_number vector,
+ rtems_isr_entry *old_isr_handler
+);
+
+/*
+ * rtems_interrupt_disable
+ *
+ * DESCRIPTION:
+ *
+ * This routine disables all maskable interrupts and returns the
+ * previous level in _isr_cookie.
+ */
+
+#define rtems_interrupt_disable( _isr_cookie ) \
+ _ISR_Disable(_isr_cookie)
+
+/*
+ * rtems_interrupt_enable
+ *
+ * DESCRIPTION:
+ *
+ * This routine enables maskable interrupts to the level indicated
+ * _isr_cookie.
+ */
+
+#define rtems_interrupt_enable( _isr_cookie ) \
+ _ISR_Enable(_isr_cookie)
+
+/*
+ * rtems_interrupt_flash
+ *
+ * DESCRIPTION:
+ *
+ * This routine temporarily enables maskable interrupts to the
+ * level in _isr_cookie before redisabling them.
+ */
+
+#define rtems_interrupt_flash( _isr_cookie ) \
+ _ISR_Flash(_isr_cookie)
+
+/*
+ * rtems_interrupt_is_in_progress
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the processor is currently servicing
+ * an interrupt and FALSE otherwise. A return value of TRUE indicates
+ * that the caller is an interrupt service routine, NOT a thread. The
+ * directives available to an interrupt service routine are restricted.
+ */
+
+#define rtems_interrupt_is_in_progress() \
+ _ISR_Is_in_progress()
+
+/*
+ * rtems_interrupt_cause
+ *
+ * DESCRIPTION:
+ *
+ * This routine generates an interrupt.
+ *
+ * NOTE: No implementation.
+ */
+
+#define rtems_interrupt_cause( _interrupt_to_cause )
+
+/*
+ * rtems_interrupt_cause
+ *
+ * DESCRIPTION:
+ *
+ * This routine clears the specified interrupt.
+ *
+ * NOTE: No implementation.
+ */
+
+#define rtems_interrupt_clear( _interrupt_to_clear )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/message.h b/cpukit/rtems/include/rtems/rtems/message.h
new file mode 100644
index 0000000000..778500e363
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/message.h
@@ -0,0 +1,330 @@
+/**
+ * @file rtems/rtems/message.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Message Queue Manager. This manager provides a mechanism for
+ * communication and synchronization between tasks using messages.
+ *
+ * Directives provided are:
+ *
+ * + create a queue
+ * + get ID of a queue
+ * + delete a queue
+ * + put a message at the rear of a queue
+ * + put a message at the front of a queue
+ * + broadcast N messages to a queue
+ * + receive message from a queue
+ * + flush all messages on a 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_MESSAGE_H
+#define _RTEMS_RTEMS_MESSAGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/types.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/coremsg.h>
+
+/*
+ * The following enumerated type details the modes in which a message
+ * may be submitted to a message queue. The message may be posted
+ * in a send or urgent fashion.
+ */
+
+typedef enum {
+ MESSAGE_QUEUE_SEND_REQUEST = 0,
+ MESSAGE_QUEUE_URGENT_REQUEST = 1
+} Message_queue_Submit_types;
+
+/*
+ * The following records define the control block used to manage
+ * each message queue.
+ */
+
+typedef struct {
+ Objects_Control Object;
+ rtems_attribute attribute_set;
+ CORE_message_queue_Control message_queue;
+} Message_queue_Control;
+
+/*
+ * The following defines the information control block used to
+ * manage this class of objects.
+ */
+
+RTEMS_EXTERN Objects_Information _Message_queue_Information;
+
+/*
+ * _Message_queue_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Message_queue_Manager_initialization(
+ uint32_t maximum_message_queues
+);
+
+/*
+ * rtems_message_queue_create
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_message_queue_create directive. The
+ * message queue will have the name name. If the attribute_set indicates
+ * that the message queue is to be limited in the number of messages
+ * that can be outstanding, then count indicates the maximum number of
+ * messages that will be held. It returns the id of the created
+ * message queue in ID.
+ */
+
+rtems_status_code rtems_message_queue_create(
+ rtems_name name,
+ uint32_t count,
+ uint32_t max_message_size,
+ rtems_attribute attribute_set,
+ Objects_Id *id
+);
+
+/*
+ * rtems_message_queue_ident
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_message_queue_ident directive.
+ * This directive returns the message queue ID associated with NAME.
+ * If more than one message queue is named name, then the message
+ * queue to which the ID belongs is arbitrary. node indicates the
+ * extent of the search for the ID of the message queue named name.
+ * The search can be limited to a particular node or allowed to
+ * encompass all nodes.
+ */
+
+rtems_status_code rtems_message_queue_ident(
+ rtems_name name,
+ uint32_t node,
+ Objects_Id *id
+);
+
+/*
+ * rtems_message_queue_delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_message_queue_delete directive. The
+ * message queue indicated by ID is deleted.
+ */
+
+rtems_status_code rtems_message_queue_delete(
+ Objects_Id id
+);
+
+/*
+ * rtems_message_queue_send
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_message_queue_send directive.
+ * This directive sends the message buffer to the message queue
+ * indicated by ID. If one or more tasks is blocked waiting
+ * to receive a message from this message queue, then one will
+ * receive the message. The task selected to receive the
+ * message is based on the task queue discipline algorithm in
+ * use by this particular message queue. If no tasks are waiting,
+ * then the message buffer will be placed at the REAR of the
+ * chain of pending messages for this message queue.
+ */
+
+rtems_status_code rtems_message_queue_send(
+ Objects_Id id,
+ void *buffer,
+ uint32_t size
+);
+
+/*
+ * rtems_message_queue_urgent
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_message_queue_urgent directive.
+ * This directive has the same behavior as rtems_message_queue_send
+ * except that if no tasks are waiting, the message buffer will
+ * be placed at the FRONT of the chain of pending messages rather
+ * than at the REAR.
+ */
+
+rtems_status_code rtems_message_queue_urgent(
+ Objects_Id id,
+ void *buffer,
+ uint32_t size
+);
+
+/*
+ * rtems_message_queue_broadcast
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_message_queue_broadcast directive.
+ * This directive sends the message buffer to all of the tasks blocked
+ * waiting for a message on the message queue indicated by ID.
+ * If no tasks are waiting, then the message buffer will not be queued.
+ */
+
+rtems_status_code rtems_message_queue_broadcast(
+ Objects_Id id,
+ void *buffer,
+ uint32_t size,
+ uint32_t *count
+);
+
+/*
+ * rtems_message_queue_receive
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_message_queue_receive directive.
+ * This directive is invoked when the calling task wishes to receive
+ * a message from the message queue indicated by ID. The received
+ * message is to be placed in buffer. If no messages are outstanding
+ * and the option_set indicates that the task is willing to block,
+ * then the task will be blocked until a message arrives or until,
+ * optionally, timeout clock ticks have passed.
+ */
+
+rtems_status_code rtems_message_queue_receive(
+ Objects_Id id,
+ void *buffer,
+ uint32_t *size,
+ uint32_t option_set,
+ rtems_interval timeout
+);
+
+/*
+ * rtems_message_queue_flush
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_message_queue_flush directive.
+ * This directive takes all outstanding messages for the message
+ * queue indicated by ID and returns them to the inactive message
+ * chain. The number of messages flushed is returned in COUNT.
+ */
+
+rtems_status_code rtems_message_queue_flush(
+ Objects_Id id,
+ uint32_t *count
+);
+
+/*
+ * rtems_message_queue_get_number_pending
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_message_queue_get_number_pending
+ * directive. This directive returns the number of pending
+ * messages for the message queue indicated by ID
+ * chain. The number of messages pending is returned in COUNT.
+ */
+
+rtems_status_code rtems_message_queue_get_number_pending(
+ Objects_Id id,
+ uint32_t *count
+);
+
+
+/*
+ * _Message_queue_Submit
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the directives rtems_message_queue_send
+ * and rtems_message_queue_urgent. It processes a message that is
+ * to be submitted to the designated message queue. The message will
+ * either be processed as a send send message which it will be inserted
+ * at the rear of the queue or it will be processed as an urgent message
+ * which will be inserted at the front of the queue.
+ */
+
+rtems_status_code _Message_queue_Submit(
+ Objects_Id id,
+ void *buffer,
+ uint32_t size,
+ Message_queue_Submit_types submit_type
+);
+
+/*
+ * _Message_queue_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a message queue control block from
+ * the inactive chain of free message queue control blocks.
+ */
+
+Message_queue_Control *_Message_queue_Allocate (
+ uint32_t count,
+ uint32_t max_message_size
+);
+
+/*
+ * _Message_queue_Translate_core_message_queue_return_code
+ *
+ * DESCRIPTION:
+ *
+ * This function returns a RTEMS status code based on the core message queue
+ * status code specified.
+ */
+
+rtems_status_code _Message_queue_Translate_core_message_queue_return_code (
+ uint32_t the_message_queue_status
+);
+
+/*
+ *
+ * _Message_queue_Core_message_queue_mp_support
+ *
+ * Input parameters:
+ * the_thread - the remote thread the message was submitted to
+ * id - id of the message queue
+ *
+ * Output parameters: NONE
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+void _Message_queue_Core_message_queue_mp_support (
+ Thread_Control *the_thread,
+ Objects_Id id
+);
+#endif
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/message.inl>
+#endif
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/msgmp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/modes.h b/cpukit/rtems/include/rtems/rtems/modes.h
new file mode 100644
index 0000000000..5a6131297c
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/modes.h
@@ -0,0 +1,91 @@
+/**
+ * @file rtems/rtems/modes.h
+ */
+
+/*
+ * This include file contains all constants and structures associated
+ * with the RTEMS thread and RTEMS_ASR modes.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_MODES_H
+#define _RTEMS_RTEMS_MODES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/isr.h>
+
+/*
+ * The following type defines the control block used to manage
+ * each a mode set.
+ */
+
+typedef uint32_t Modes_Control;
+
+/*
+ * The following constants define the individual modes and masks
+ * which may be used to compose a mode set and to alter modes.
+ */
+
+#define RTEMS_ALL_MODE_MASKS 0x0000ffff
+
+#define RTEMS_DEFAULT_MODES 0x00000000
+#define RTEMS_CURRENT_MODE 0
+
+#define RTEMS_PREEMPT_MASK 0x00000100 /* preemption bit */
+#define RTEMS_TIMESLICE_MASK 0x00000200 /* timeslice bit */
+#define RTEMS_ASR_MASK 0x00000400 /* RTEMS_ASR enable bit */
+#define RTEMS_INTERRUPT_MASK CPU_MODES_INTERRUPT_MASK
+
+#define RTEMS_PREEMPT 0x00000000 /* enable preemption */
+#define RTEMS_NO_PREEMPT 0x00000100 /* disable preemption */
+
+#define RTEMS_NO_TIMESLICE 0x00000000 /* disable timeslicing */
+#define RTEMS_TIMESLICE 0x00000200 /* enable timeslicing */
+
+#define RTEMS_ASR 0x00000000 /* enable RTEMS_ASR */
+#define RTEMS_NO_ASR 0x00000400 /* disable RTEMS_ASR */
+
+/*
+ * The number of bits for interrupt levels is CPU dependent.
+ * RTEMS supports 0 to 256 levels in bits 0-7 of the mode.
+ */
+
+/*PAGE
+ *
+ * RTEMS_INTERRUPT_LEVEL
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the processor dependent interrupt
+ * level which corresponds to the requested interrupt level.
+ *
+ * NOTE: RTEMS supports 256 interrupt levels using the least
+ * significant eight bits of MODES.CONTROL. On any
+ * particular CPU, fewer than 256 levels may be supported.
+ */
+
+#define RTEMS_INTERRUPT_LEVEL( _mode_set ) \
+ ( (_mode_set) & RTEMS_INTERRUPT_MASK )
+
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/modes.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/mp.h b/cpukit/rtems/include/rtems/rtems/mp.h
new file mode 100644
index 0000000000..cebdb2a175
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/mp.h
@@ -0,0 +1,55 @@
+/**
+ * @file rtems/rtems/mp.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_MP_H
+#define _RTEMS_RTEMS_MP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *
+ * _Multiprocessing_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Multiprocessing_Manager_initialization ( void );
+
+/*
+ *
+ * rtems_multiprocessing_announce
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the MULTIPROCESSING_ANNOUNCE directive.
+ * It is invoked by the MPCI layer to indicate that an MPCI packet
+ * has been received.
+ */
+
+void rtems_multiprocessing_announce ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/msgmp.h b/cpukit/rtems/include/rtems/rtems/msgmp.h
new file mode 100644
index 0000000000..6fa68e93ba
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/msgmp.h
@@ -0,0 +1,179 @@
+/**
+ * @file rtems/rtems/msgmp.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the Message Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_MSGMP_H
+#define _RTEMS_RTEMS_MSGMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/message.h>
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote message queue operations.
+ */
+
+typedef enum {
+ MESSAGE_QUEUE_MP_ANNOUNCE_CREATE = 0,
+ MESSAGE_QUEUE_MP_ANNOUNCE_DELETE = 1,
+ MESSAGE_QUEUE_MP_EXTRACT_PROXY = 2,
+ MESSAGE_QUEUE_MP_RECEIVE_REQUEST = 3,
+ MESSAGE_QUEUE_MP_RECEIVE_RESPONSE = 4,
+ MESSAGE_QUEUE_MP_SEND_REQUEST = 5,
+ MESSAGE_QUEUE_MP_SEND_RESPONSE = 6,
+ MESSAGE_QUEUE_MP_URGENT_REQUEST = 7,
+ MESSAGE_QUEUE_MP_URGENT_RESPONSE = 8,
+ MESSAGE_QUEUE_MP_BROADCAST_REQUEST = 9,
+ MESSAGE_QUEUE_MP_BROADCAST_RESPONSE = 10,
+ MESSAGE_QUEUE_MP_FLUSH_REQUEST = 11,
+ MESSAGE_QUEUE_MP_FLUSH_RESPONSE = 12,
+ MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST = 13,
+ MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE = 14
+} Message_queue_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote message queue operations.
+ */
+
+typedef struct {
+ rtems_packet_prefix Prefix;
+ Message_queue_MP_Remote_operations operation;
+ rtems_name name;
+ rtems_option option_set;
+ Objects_Id proxy_id;
+ uint32_t count;
+ uint32_t size;
+ uint32_t pad0;
+ CORE_message_queue_Buffer Buffer;
+} Message_queue_MP_Packet;
+
+/*
+ * _Message_queue_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+
+void _Message_queue_MP_Send_process_packet (
+ Message_queue_MP_Remote_operations operation,
+ Objects_Id message_queue_id,
+ rtems_name name,
+ Objects_Id proxy_id
+);
+
+/*
+ * _Message_queue_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+rtems_status_code _Message_queue_MP_Send_request_packet (
+ Message_queue_MP_Remote_operations operation,
+ Objects_Id message_queue_id,
+ void *buffer,
+ uint32_t *size_p,
+ rtems_option option_set,
+ Watchdog_Interval timeout
+);
+
+/*
+ * _Message_queue_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _Message_queue_MP_Send_response_packet (
+ Message_queue_MP_Remote_operations operation,
+ Objects_Id message_queue_id,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _Message_queue_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _Message_queue_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/*
+ * _Message_queue_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _Message_queue_MP_Send_object_was_deleted (
+ Thread_Control *the_proxy
+);
+
+/*
+ * _Message_queue_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _Message_queue_MP_Send_extract_proxy (
+ void *argument
+);
+
+/*
+ * _Message_queue_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a message queue mp packet.
+ */
+
+Message_queue_MP_Packet *_Message_queue_MP_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/rtems/include/rtems/rtems/options.h b/cpukit/rtems/include/rtems/rtems/options.h
new file mode 100644
index 0000000000..70f17d700c
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/options.h
@@ -0,0 +1,55 @@
+/**
+ * @file rtems/rtems/options.h
+ */
+
+/*
+ * This include file contains information which defines the
+ * options available on many directives.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_OPTIONS_H
+#define _RTEMS_RTEMS_OPTIONS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The following type defines the control block used to manage
+ * option sets.
+ */
+
+typedef uint32_t rtems_option;
+
+/*
+ * The following constants define the individual options which may
+ * be used to compose an option set.
+ */
+
+#define RTEMS_DEFAULT_OPTIONS 0x00000000
+
+#define RTEMS_WAIT 0x00000000 /* wait on resource */
+#define RTEMS_NO_WAIT 0x00000001 /* do not wait on resource */
+
+#define RTEMS_EVENT_ALL 0x00000000 /* wait for all events */
+#define RTEMS_EVENT_ANY 0x00000002 /* wait on any event */
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/options.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/part.h b/cpukit/rtems/include/rtems/rtems/part.h
new file mode 100644
index 0000000000..75a947d881
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/part.h
@@ -0,0 +1,172 @@
+/**
+ * @file rtems/rtems/part.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Partition Manager. This manager provides facilities to
+ * dynamically allocate memory in fixed-sized units which are returned
+ * as buffers.
+ *
+ * Directives provided are:
+ *
+ * + create a partition
+ * + get an ID of a partition
+ * + delete a partition
+ * + get a buffer from a partition
+ * + return a buffer to a partition
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_PART_H
+#define _RTEMS_RTEMS_PART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/address.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/types.h>
+
+/*
+ * The following defines the control block used to manage each partition.
+ */
+
+typedef struct {
+ Objects_Control Object;
+ void *starting_address; /* physical address */
+ uint32_t length; /* in bytes */
+ uint32_t buffer_size; /* in bytes */
+ rtems_attribute attribute_set; /* attributes */
+ uint32_t number_of_used_blocks; /* or allocated buffers */
+ Chain_Control Memory; /* buffer chain */
+} Partition_Control;
+
+/*
+ * The following defines the information control block used to
+ * manage this class of objects.
+ */
+
+RTEMS_EXTERN Objects_Information _Partition_Information;
+
+/*
+ * _Partition_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Partition_Manager_initialization(
+ uint32_t maximum_partitions
+);
+
+/*
+ * rtems_partition_create
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_partition_create directive. The
+ * partition will have the name name. The memory area managed by
+ * the partition is of length bytes and starts at starting_address.
+ * The memory area will be divided into as many buffers of
+ * buffer_size bytes as possible. The attribute_set determines if
+ * the partition is global or local. It returns the id of the
+ * created partition in ID.
+ */
+
+rtems_status_code rtems_partition_create(
+ rtems_name name,
+ void *starting_address,
+ uint32_t length,
+ uint32_t buffer_size,
+ rtems_attribute attribute_set,
+ Objects_Id *id
+);
+
+/*
+ * rtems_partition_ident
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_partition_ident directive.
+ * This directive returns the partition ID associated with name.
+ * If more than one partition is named name, then the partition
+ * to which the ID belongs is arbitrary. node indicates the
+ * extent of the search for the ID of the partition named name.
+ * The search can be limited to a particular node or allowed to
+ * encompass all nodes.
+ */
+
+rtems_status_code rtems_partition_ident(
+ rtems_name name,
+ uint32_t node,
+ Objects_Id *id
+);
+
+/*
+ * rtems_partition_delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_partition_delete directive. The
+ * partition indicated by ID is deleted.
+ */
+
+rtems_status_code rtems_partition_delete(
+ Objects_Id id
+);
+
+/*
+ * rtems_partition_get_buffer
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_partition_get_buffer directive. It
+ * attempts to allocate a buffer from the partition associated with ID.
+ * If a buffer is allocated, its address is returned in buffer.
+ */
+
+rtems_status_code rtems_partition_get_buffer(
+ Objects_Id id,
+ void **buffer
+);
+
+/*
+ * rtems_partition_return_buffer
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_partition_return_buffer directive. It
+ * frees the buffer to the partition associated with ID. The buffer must
+ * have been previously allocated from the same partition.
+ */
+
+rtems_status_code rtems_partition_return_buffer(
+ Objects_Id id,
+ void *buffer
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/part.inl>
+#endif
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/partmp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/partmp.h b/cpukit/rtems/include/rtems/rtems/partmp.h
new file mode 100644
index 0000000000..9369dc286c
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/partmp.h
@@ -0,0 +1,163 @@
+/**
+ * @file rtems/rtems/partmp.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the Partition Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_PARTMP_H
+#define _RTEMS_RTEMS_PARTMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/thread.h>
+
+#include <rtems/rtems/part.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote partition operations.
+ */
+
+typedef enum {
+ PARTITION_MP_ANNOUNCE_CREATE = 0,
+ PARTITION_MP_ANNOUNCE_DELETE = 1,
+ PARTITION_MP_EXTRACT_PROXY = 2,
+ PARTITION_MP_GET_BUFFER_REQUEST = 3,
+ PARTITION_MP_GET_BUFFER_RESPONSE = 4,
+ PARTITION_MP_RETURN_BUFFER_REQUEST = 5,
+ PARTITION_MP_RETURN_BUFFER_RESPONSE = 6
+} Partition_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote partition operations.
+ */
+
+typedef struct {
+ rtems_packet_prefix Prefix;
+ Partition_MP_Remote_operations operation;
+ rtems_name name;
+ void *buffer;
+ Objects_Id proxy_id;
+} Partition_MP_Packet;
+
+/*
+ * _Partition_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+
+void _Partition_MP_Send_process_packet (
+ Partition_MP_Remote_operations operation,
+ Objects_Id partition_id,
+ rtems_name name,
+ Objects_Id proxy_id
+);
+
+/*
+ * _Partition_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+rtems_status_code _Partition_MP_Send_request_packet (
+ Partition_MP_Remote_operations operation,
+ Objects_Id partition_id,
+ void *buffer
+);
+
+/*
+ * _Partition_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _Partition_MP_Send_response_packet (
+ Partition_MP_Remote_operations operation,
+ Objects_Id partition_id,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _Partition_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _Partition_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/*
+ * _Partition_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed by the Partition since a partition
+ * cannot be deleted when buffers are in use.
+ */
+
+/*
+ * _Partition_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _Partition_MP_Send_extract_proxy (
+ void *argument
+);
+
+/*
+ * _Partition_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a partition mp packet.
+ */
+
+Partition_MP_Packet *_Partition_MP_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/rtems/include/rtems/rtems/ratemon.h b/cpukit/rtems/include/rtems/rtems/ratemon.h
new file mode 100644
index 0000000000..0d9d5aa903
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/ratemon.h
@@ -0,0 +1,216 @@
+/**
+ * @file rtems/rtems/ratemon.h
+ */
+
+/*
+ * This include file contains all the constants, structures, and
+ * prototypes associated with the Rate Monotonic Manager. This manager
+ * provides facilities to implement tasks which execute in a periodic fashion.
+ *
+ * Directives provided are:
+ *
+ * + create a rate monotonic timer
+ * + cancel a period
+ * + delete a rate monotonic timer
+ * + conclude current and start the next period
+ * + obtain status information on a period
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_RATEMON_H
+#define _RTEMS_RTEMS_RATEMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+/*
+ * The following enumerated type defines the states in which a
+ * period may be.
+ */
+
+typedef enum {
+ RATE_MONOTONIC_INACTIVE, /* off chain, never initialized */
+ RATE_MONOTONIC_OWNER_IS_BLOCKING, /* on chain, owner is blocking on it */
+ RATE_MONOTONIC_ACTIVE, /* on chain, running continuously */
+ RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING, /* on chain, expired while owner was */
+ /* was blocking on it */
+ RATE_MONOTONIC_EXPIRED /* off chain, will be reset by next */
+ /* rtems_rate_monotonic_period */
+} rtems_rate_monotonic_period_states;
+
+/*
+ * The following constant is the interval passed to the rate_monontonic_period
+ * directive to obtain status information.
+ */
+
+#define RTEMS_PERIOD_STATUS WATCHDOG_NO_TIMEOUT
+
+/*
+ * The following defines the period status structure.
+ */
+
+typedef struct {
+ rtems_rate_monotonic_period_states state;
+ uint32_t ticks_since_last_period;
+ uint32_t ticks_executed_since_last_period;
+} rtems_rate_monotonic_period_status;
+
+/*
+ * The following structure defines the control block used to manage
+ * each period.
+ */
+
+typedef struct {
+ Objects_Control Object;
+ Watchdog_Control Timer;
+ rtems_rate_monotonic_period_states state;
+ uint32_t owner_ticks_executed_at_period;
+ uint32_t time_at_period;
+ uint32_t next_length;
+ Thread_Control *owner;
+} Rate_monotonic_Control;
+
+RTEMS_EXTERN Objects_Information _Rate_monotonic_Information;
+
+/*
+ * _Rate_monotonic_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Rate_monotonic_Manager_initialization(
+ uint32_t maximum_periods
+);
+
+/*
+ * rtems_rate_monotonic_create
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rate_monotonic_create directive. The
+ * period will have the name name. It returns the id of the
+ * created period in ID.
+ */
+
+rtems_status_code rtems_rate_monotonic_create(
+ rtems_name name,
+ Objects_Id *id
+);
+
+/*
+ * rtems_rate_monotonic_ident
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_rate_monotonic_ident directive.
+ * This directive returns the period ID associated with name.
+ * If more than one period is named name, then the period
+ * to which the ID belongs is arbitrary.
+ */
+
+rtems_status_code rtems_rate_monotonic_ident(
+ rtems_name name,
+ Objects_Id *id
+);
+
+/*
+ * rtems_rate_monotonic_cancel
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_rate_monotonic_cancel directive. This
+ * directive stops the period associated with ID from continuing to
+ * run.
+ */
+
+rtems_status_code rtems_rate_monotonic_cancel(
+ Objects_Id id
+);
+
+/*
+ * rtems_rate_monotonic_delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_rate_monotonic_delete directive. The
+ * period indicated by ID is deleted.
+ */
+
+rtems_status_code rtems_rate_monotonic_delete(
+ Objects_Id id
+);
+
+/*
+ * rtems_rate_monotonic_get_status
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_rate_monotonic_get_status directive.
+ * Information about the period indicated by ID is returned.
+ *
+ */
+
+rtems_status_code rtems_rate_monotonic_get_status(
+ Objects_Id id,
+ rtems_rate_monotonic_period_status *status
+);
+
+/*
+ * rtems_rate_monotonic_period
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_rate_monotonic_period directive. When
+ * length is non-zero, this directive initiates the period associated with
+ * ID from continuing for a period of length. If length is zero, then
+ * result is set to indicate the current state of the period.
+ */
+
+rtems_status_code rtems_rate_monotonic_period(
+ Objects_Id id,
+ rtems_interval length
+);
+
+/*
+ * _Rate_monotonic_Timeout
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when the period represented
+ * by ID expires. If the task which owns this period is blocked
+ * waiting for the period to expire, then it is readied and the
+ * period is restarted. If the owning task is not waiting for the
+ * period to expire, then the period is placed in the EXPIRED
+ * state and not restarted.
+ */
+
+void _Rate_monotonic_Timeout (
+ Objects_Id id,
+ void *ignored
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/ratemon.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/region.h b/cpukit/rtems/include/rtems/rtems/region.h
new file mode 100644
index 0000000000..9c8a0cffa9
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/region.h
@@ -0,0 +1,301 @@
+/**
+ * @file rtems/rtems/region.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Region Manager. This manager provides facilities to dynamically
+ * allocate memory in variable sized units which are returned as segments.
+ *
+ * Directives provided are:
+ *
+ * + create a region
+ * + get an ID of a region
+ * + delete a region
+ * + get a segment from a region
+ * + return a segment to a region
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_REGION_H
+#define _RTEMS_RTEMS_REGION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+
+#include <rtems/score/object.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/heap.h>
+#include <rtems/debug.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/types.h>
+
+/*
+ * The following records define the control block used to manage
+ * each region.
+ */
+
+typedef struct {
+ Objects_Control Object;
+ Thread_queue_Control Wait_queue; /* waiting threads */
+ void *starting_address; /* physical start addr */
+ uint32_t length; /* physical length(bytes) */
+ uint32_t page_size; /* in bytes */
+ uint32_t maximum_segment_size; /* in bytes */
+ rtems_attribute attribute_set;
+ uint32_t number_of_used_blocks; /* blocks allocated */
+ Heap_Control Memory;
+} Region_Control;
+
+/*
+ * The following defines the information control block used to
+ * manage this class of objects.
+ */
+
+RTEMS_EXTERN Objects_Information _Region_Information;
+
+/*
+ * _Region_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Region_Manager_initialization(
+ uint32_t maximum_regions
+);
+
+/*
+ * rtems_region_create
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_region_create directive. The
+ * region will have the name name. The memory area managed by
+ * the region is of length bytes and starts at starting_address.
+ * The memory area will be divided into as many allocatable units of
+ * page_size bytes as possible. The attribute_set determines which
+ * thread queue discipline is used by the region. It returns the
+ * id of the created region in ID.
+ */
+
+rtems_status_code rtems_region_create(
+ rtems_name name,
+ void *starting_address,
+ uint32_t length,
+ uint32_t page_size,
+ rtems_attribute attribute_set,
+ Objects_Id *id
+);
+
+/*
+ * rtems_region_extend
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_region_extend directive. The
+ * region will have the name name. The memory area managed by
+ * the region will be attempted to be grown by length bytes using
+ * the memory starting at starting_address.
+ */
+
+rtems_status_code rtems_region_extend(
+ Objects_Id id,
+ void *starting_address,
+ uint32_t length
+);
+
+/*
+ * rtems_region_ident
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_region_ident directive.
+ * This directive returns the region ID associated with name.
+ * If more than one region is named name, then the region
+ * to which the ID belongs is arbitrary.
+ */
+
+rtems_status_code rtems_region_ident(
+ rtems_name name,
+ Objects_Id *id
+);
+
+/*
+ * rtems_region_get_information
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_region_get_information directive.
+ * This directive returns information about the heap associated with
+ * this region.
+ */
+
+rtems_status_code rtems_region_get_information(
+ Objects_Id id,
+ Heap_Information_block *the_info
+);
+
+/*
+ * rtems_region_get_free_information
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_region_get_free_information directive.
+ * This directive returns information about the free blocks in the
+ * heap associated with this region.
+ */
+
+rtems_status_code rtems_region_get_free_information(
+ Objects_Id id,
+ Heap_Information_block *the_info
+);
+
+/*
+ * rtems_region_delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_region_delete directive. The
+ * region indicated by ID is deleted.
+ */
+
+rtems_status_code rtems_region_delete(
+ Objects_Id id
+);
+
+/*
+ * rtems_region_get_segment
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_region_get_segment directive. It
+ * attempts to allocate a segment from the region associated with ID.
+ * If a segment of the requested size can be allocated, its address
+ * is returned in segment. If no segment is available, then the task
+ * may return immediately or block waiting for a segment with an optional
+ * timeout of timeout clock ticks. Whether the task blocks or returns
+ * immediately is based on the no_wait option in the option_set.
+ */
+
+rtems_status_code rtems_region_get_segment(
+ Objects_Id id,
+ uint32_t size,
+ rtems_option option_set,
+ rtems_interval timeout,
+ void **segment
+);
+
+/*
+ * rtems_region_get_segment_size
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_region_get_segment_size directive. It
+ * returns the size in bytes of the specified user memory area.
+ */
+
+rtems_status_code rtems_region_get_segment_size(
+ Objects_Id id,
+ void *segment,
+ size_t *size
+);
+
+/*
+ * rtems_region_return_segment
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_region_return_segment directive. It
+ * frees the segment to the region associated with ID. The segment must
+ * have been previously allocated from the same region. If freeing the
+ * segment results in enough memory being available to satisfy the
+ * rtems_region_get_segment of the first blocked task, then that task and as
+ * many subsequent tasks as possible will be unblocked with their requests
+ * satisfied.
+ */
+
+rtems_status_code rtems_region_return_segment(
+ Objects_Id id,
+ void *segment
+);
+
+/*
+ * rtems_region_resize_segment
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_region_resize_segment directive. It
+ * tries to resize segment in the region associated with 'id' to the new size
+ * 'size' in place. The first 'size' or old size bytes of the segment
+ * (whatever is less) are guaranteed to remain unmodified. The segment must
+ * have been previously allocated from the same region. If resizing the
+ * segment results in enough memory being available to satisfy the
+ * rtems_region_get_segment of the first blocked task, then that task and as
+ * many subsequent tasks as possible will be unblocked with their requests
+ * satisfied.
+ * Returns:
+ * RTEMS_SUCCESSFUL - operation successful
+ * RTEMS_UNSATISFIED - the segment can't be resized in place
+ * any other code - failure.
+ * On RTEMS_SUCCESSFUL or RTEMS_UNSATISFIED exit it returns into the
+ * 'old_size' the old size in bytes of the user memory area of the specified
+ * segment.
+ */
+
+rtems_status_code rtems_region_resize_segment(
+ Objects_Id id,
+ void *segment,
+ size_t size,
+ size_t *old_size
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/region.inl>
+extern void _Region_Process_queue(Region_Control *the_region);
+#endif
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/regionmp.h>
+#endif
+
+/*
+ * _Region_Debug_Walk
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked to verify the integrity of a heap associated
+ * with the_region.
+ */
+
+#ifdef RTEMS_DEBUG
+
+#define _Region_Debug_Walk( _the_region, _source ) \
+ do { \
+ if ( _Debug_Is_enabled( RTEMS_DEBUG_REGION ) ) \
+ _Heap_Walk( &(_the_region)->Memory, _source, FALSE ); \
+ } while ( 0 )
+
+#else
+
+#define _Region_Debug_Walk( _the_region, _source )
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/regionmp.h b/cpukit/rtems/include/rtems/rtems/regionmp.h
new file mode 100644
index 0000000000..2b0eeac29a
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/regionmp.h
@@ -0,0 +1,168 @@
+/**
+ * @file rtems/rtems/regionmp.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the Region Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_REGIONMP_H
+#define _RTEMS_RTEMS_REGIONMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote region operations.
+ */
+
+typedef enum {
+ REGION_MP_ANNOUNCE_CREATE = 0,
+ REGION_MP_ANNOUNCE_DELETE = 1,
+ REGION_MP_EXTRACT_PROXY = 2,
+ REGION_MP_GET_SEGMENT_REQUEST = 3,
+ REGION_MP_GET_SEGMENT_RESPONSE = 4,
+ REGION_MP_RETURN_SEGMENT_REQUEST = 5,
+ REGION_MP_RETURN_SEGMENT_RESPONSE = 6
+} Region_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote region operations.
+ */
+
+typedef struct {
+ rtems_packet_prefix Prefix;
+ Region_MP_Remote_operations operation;
+ rtems_name name;
+ rtems_option option_set;
+ uint32_t size;
+ Objects_Id proxy_id;
+ void *segment;
+} Region_MP_Packet;
+
+/*
+ * _Region_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+
+void _Region_MP_Send_process_packet (
+ Region_MP_Remote_operations operation,
+ Objects_Id region_id,
+ rtems_name name,
+ Objects_Id proxy_id
+);
+
+/*
+ * _Region_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+rtems_status_code _Region_MP_Send_request_packet (
+ Region_MP_Remote_operations operation,
+ Objects_Id region_id,
+ void *segment,
+ uint32_t size,
+ rtems_option option_set,
+ rtems_interval timeout
+);
+
+/*
+ * _Region_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _Region_MP_Send_response_packet (
+ Region_MP_Remote_operations operation,
+ Objects_Id region_id,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _Region_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _Region_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/*
+ * _Region_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed by the Region since a region
+ * cannot be deleted when segments are in use.
+ */
+
+/*
+ * _Region_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _Region_MP_Send_extract_proxy (
+ void *argument
+);
+
+/*
+ * _Region_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a region mp packet.
+ */
+
+Region_MP_Packet *_Region_MP_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/rtems/include/rtems/rtems/rtemsapi.h b/cpukit/rtems/include/rtems/rtems/rtemsapi.h
new file mode 100644
index 0000000000..d1c2a0538c
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/rtemsapi.h
@@ -0,0 +1,37 @@
+/**
+ * @file rtems/rtems/rtemsapi.h
+ */
+
+/*
+ * RTEMS API Support
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_RTEMSAPI_H
+#define _RTEMS_RTEMS_RTEMSAPI_H
+
+#include <rtems/config.h>
+
+/*PAGE
+ *
+ * _RTEMS_API_Initialize
+ *
+ * This routine initializes the RTEMS API by invoking the initialization
+ * routine for each RTEMS manager with the appropriate parameters
+ * from the configuration_table.
+ */
+
+void _RTEMS_API_Initialize(
+ rtems_configuration_table *configuration_table
+);
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/sem.h b/cpukit/rtems/include/rtems/rtems/sem.h
new file mode 100644
index 0000000000..3c628717c4
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/sem.h
@@ -0,0 +1,278 @@
+/**
+ * @file rtems/rtems/sem.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Semaphore Manager. This manager utilizes standard Dijkstra
+ * counting semaphores to provide synchronization and mutual exclusion
+ * capabilities.
+ *
+ * Directives provided are:
+ *
+ * + create a semaphore
+ * + get an ID of a semaphore
+ * + delete a semaphore
+ * + acquire a semaphore
+ * + release a semaphore
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_SEM_H
+#define _RTEMS_RTEMS_SEM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coresem.h>
+
+/*
+ * The following defines the control block used to manage each semaphore.
+ */
+
+typedef struct {
+ Objects_Control Object;
+ rtems_attribute attribute_set;
+ union {
+ CORE_mutex_Control mutex;
+ CORE_semaphore_Control semaphore;
+ } Core_control;
+} Semaphore_Control;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+RTEMS_EXTERN Objects_Information _Semaphore_Information;
+
+/*
+ * _Semaphore_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Semaphore_Manager_initialization(
+ uint32_t maximum_semaphores
+);
+
+/*
+ * rtems_semaphore_create
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_semaphore_create directive. The
+ * semaphore will have the name name. The starting count for
+ * the semaphore is count. The attribute_set determines if
+ * the semaphore is global or local and the thread queue
+ * discipline. It returns the id of the created semaphore in ID.
+ */
+
+rtems_status_code rtems_semaphore_create(
+ rtems_name name,
+ uint32_t count,
+ rtems_attribute attribute_set,
+ rtems_task_priority priority_ceiling,
+ rtems_id *id
+);
+
+/*
+ * rtems_semaphore_ident
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_semaphore_ident directive.
+ * This directive returns the semaphore ID associated with name.
+ * If more than one semaphore is named name, then the semaphore
+ * to which the ID belongs is arbitrary. node indicates the
+ * extent of the search for the ID of the semaphore named name.
+ * The search can be limited to a particular node or allowed to
+ * encompass all nodes.
+ */
+
+rtems_status_code rtems_semaphore_ident(
+ rtems_name name,
+ uint32_t node,
+ rtems_id *id
+);
+
+/*
+ * rtems_semaphore_delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_semaphore_delete directive. The
+ * semaphore indicated by ID is deleted.
+ */
+
+rtems_status_code rtems_semaphore_delete(
+ rtems_id id
+);
+
+/*
+ * rtems_semaphore_obtain
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_semaphore_obtain directive. It
+ * attempts to obtain a unit from the semaphore associated with ID.
+ * If a unit can be allocated, the calling task will return immediately.
+ * If no unit is available, then the task may return immediately or
+ * block waiting for a unit with an optional timeout of timeout
+ * clock ticks. Whether the task blocks or returns immediately
+ * is based on the RTEMS_NO_WAIT option in the option_set.
+ */
+
+rtems_status_code rtems_semaphore_obtain(
+ rtems_id id,
+ uint32_t option_set,
+ rtems_interval timeout
+);
+
+/*
+ * rtems_semaphore_release
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_semaphore_release directive. It
+ * frees a unit to the semaphore associated with ID. If a task was
+ * blocked waiting for a unit from this semaphore, then that task will
+ * be readied and the unit given to that task. Otherwise, the unit
+ * will be returned to the semaphore.
+ */
+
+rtems_status_code rtems_semaphore_release(
+ rtems_id id
+);
+
+/*
+ * rtems_semaphore_flush
+ *
+ * This directive allows a thread to flush the threads
+ * pending on the semaphore.
+ */
+
+rtems_status_code rtems_semaphore_flush(
+ rtems_id id
+);
+
+/*
+ * _Semaphore_Seize
+ *
+ * DESCRIPTION:
+ *
+ * This routine attempts to receive a unit from the_semaphore.
+ * If a unit is available or if the RTEMS_NO_WAIT option is enabled in
+ * option_set, then the routine returns. Otherwise, the calling task
+ * is blocked until a unit becomes available.
+ */
+
+boolean _Semaphore_Seize(
+ Semaphore_Control *the_semaphore,
+ uint32_t option_set
+);
+
+/*
+ * _Semaphore_Translate_core_mutex_return_code
+ *
+ * DESCRIPTION:
+ *
+ * This function returns a RTEMS status code based on the mutex
+ * status code specified.
+ */
+
+rtems_status_code _Semaphore_Translate_core_mutex_return_code (
+ uint32_t the_mutex_status
+);
+
+/*
+ * _Semaphore_Translate_core_semaphore_return_code
+ *
+ * DESCRIPTION:
+ *
+ * This function returns a RTEMS status code based on the semaphore
+ * status code specified.
+ */
+
+rtems_status_code _Semaphore_Translate_core_semaphore_return_code (
+ uint32_t the_mutex_status
+);
+
+/*PAGE
+ *
+ * _Semaphore_Core_mutex_mp_support
+ *
+ * DESCRIPTION:
+ *
+ * This function processes the global actions necessary for remote
+ * accesses to a global semaphore based on a core mutex. This function
+ * is called by the core.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+void _Semaphore_Core_mutex_mp_support (
+ Thread_Control *the_thread,
+ rtems_id id
+);
+#endif
+
+/*PAGE
+ *
+ * _Semaphore_Core_mp_support
+ *
+ * DESCRIPTION:
+ *
+ * This function processes the global actions necessary for remote
+ * accesses to a global semaphore based on a core semaphore. This function
+ * is called by the core.
+ */
+
+void _Semaphore_Core_semaphore_mp_support (
+ Thread_Control *the_thread,
+ rtems_id id
+);
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_MP_support
+ *
+ * DESCRIPTION:
+ *
+ * XXX
+ */
+
+void _POSIX_Semaphore_MP_support(
+ Thread_Control *the_thread,
+ Objects_Id id
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/sem.inl>
+#endif
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/semmp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/semmp.h b/cpukit/rtems/include/rtems/rtems/semmp.h
new file mode 100644
index 0000000000..9af338bbf7
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/semmp.h
@@ -0,0 +1,165 @@
+/**
+ * @file rtems/rtems/semmp.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the Semaphore Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_SEMMP_H
+#define _RTEMS_RTEMS_SEMMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote semaphore operations.
+ */
+
+typedef enum {
+ SEMAPHORE_MP_ANNOUNCE_CREATE = 0,
+ SEMAPHORE_MP_ANNOUNCE_DELETE = 1,
+ SEMAPHORE_MP_EXTRACT_PROXY = 2,
+ SEMAPHORE_MP_OBTAIN_REQUEST = 3,
+ SEMAPHORE_MP_OBTAIN_RESPONSE = 4,
+ SEMAPHORE_MP_RELEASE_REQUEST = 5,
+ SEMAPHORE_MP_RELEASE_RESPONSE = 6
+} Semaphore_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote semaphore operations.
+ */
+
+typedef struct {
+ rtems_packet_prefix Prefix;
+ Semaphore_MP_Remote_operations operation;
+ rtems_name name;
+ rtems_option option_set;
+ Objects_Id proxy_id;
+} Semaphore_MP_Packet;
+
+/*
+ * _Semaphore_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+
+void _Semaphore_MP_Send_process_packet (
+ Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ rtems_name name,
+ Objects_Id proxy_id
+);
+
+/*
+ * _Semaphore_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+rtems_status_code _Semaphore_MP_Send_request_packet (
+ Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ rtems_option option_set,
+ rtems_interval timeout
+);
+
+/*
+ * _Semaphore_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _Semaphore_MP_Send_response_packet (
+ Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _Semaphore_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _Semaphore_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/*
+ * _Semaphore_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _Semaphore_MP_Send_object_was_deleted (
+ Thread_Control *the_proxy
+);
+
+/*
+ * _Semaphore_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+
+void _Semaphore_MP_Send_extract_proxy (
+ void *argument
+);
+
+/*
+ * _Semaphore_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a semaphore mp packet.
+ */
+
+Semaphore_MP_Packet *_Semaphore_MP_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/rtems/include/rtems/rtems/signal.h b/cpukit/rtems/include/rtems/rtems/signal.h
new file mode 100644
index 0000000000..a516970ca4
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/signal.h
@@ -0,0 +1,87 @@
+/**
+ * @file rtems/rtems/signal.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Signal Manager. This manager provides capabilities required
+ * for asynchronous communication between tasks via signal sets.
+ *
+ * Directives provided are:
+ *
+ * + establish an asynchronous signal routine
+ * + send a signal set to a task
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_SIGNAL_H
+#define _RTEMS_RTEMS_SIGNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/asr.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+
+/*
+ * _Signal_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Signal_Manager_initialization( void );
+
+/*
+ * rtems_signal_catch
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_signal_catch directive. This directive
+ * is used to establish asr_handler as the Asynchronous Signal Routine
+ * (RTEMS_ASR) for the calling task. The asr_handler will execute with a
+ * mode of mode_set.
+ */
+
+rtems_status_code rtems_signal_catch(
+ rtems_asr_entry asr_handler,
+ rtems_mode mode_set
+);
+
+/*
+ * rtems_signal_send
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_signal_send directive. This directive
+ * sends the signal_set to the task specified by ID.
+ */
+
+rtems_status_code rtems_signal_send(
+ Objects_Id id,
+ rtems_signal_set signal_set
+);
+
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/signalmp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/signalmp.h b/cpukit/rtems/include/rtems/rtems/signalmp.h
new file mode 100644
index 0000000000..a706beae80
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/signalmp.h
@@ -0,0 +1,149 @@
+/**
+ * @file rtems/rtems/signalmp.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the Signal Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_SIGNALMP_H
+#define _RTEMS_RTEMS_SIGNALMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/asr.h>
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote signal operations.
+ */
+
+typedef enum {
+ SIGNAL_MP_SEND_REQUEST = 0,
+ SIGNAL_MP_SEND_RESPONSE = 1
+} Signal_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote signal operations.
+ */
+
+typedef struct {
+ rtems_packet_prefix Prefix;
+ Signal_MP_Remote_operations operation;
+ rtems_signal_set signal_in;
+} Signal_MP_Packet;
+
+/*
+ * _Signal_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ *
+ * This routine is not needed since there are no process
+ * packets to be sent by this manager.
+ */
+
+/*
+ * _Signal_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+rtems_status_code _Signal_MP_Send_request_packet (
+ Signal_MP_Remote_operations operation,
+ Objects_Id task_id,
+ rtems_signal_set signal_in
+);
+
+/*
+ * _Signal_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _Signal_MP_Send_response_packet (
+ Signal_MP_Remote_operations operation,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _Signal_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _Signal_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/*
+ * _Signal_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+/*
+ * _Signal_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+/*
+ * _Signal_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a signal mp packet.
+ */
+
+Signal_MP_Packet *_Signal_MP_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/rtems/include/rtems/rtems/status.h b/cpukit/rtems/include/rtems/rtems/status.h
new file mode 100644
index 0000000000..d088f01917
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/status.h
@@ -0,0 +1,88 @@
+/**
+ * @file rtems/rtems/status.h
+ */
+
+/*
+ * This include file contains the status codes returned from the
+ * executive directives.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_STATUS_H
+#define _RTEMS_RTEMS_STATUS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* types */
+
+/* enumerated constants */
+
+typedef enum {
+ RTEMS_SUCCESSFUL = 0, /* successful completion */
+ RTEMS_TASK_EXITTED = 1, /* returned from a thread */
+ RTEMS_MP_NOT_CONFIGURED = 2, /* multiprocessing not configured */
+ RTEMS_INVALID_NAME = 3, /* invalid object name */
+ RTEMS_INVALID_ID = 4, /* invalid object id */
+ RTEMS_TOO_MANY = 5, /* too many */
+ RTEMS_TIMEOUT = 6, /* timed out waiting */
+ RTEMS_OBJECT_WAS_DELETED = 7, /* object deleted while waiting */
+ RTEMS_INVALID_SIZE = 8, /* specified size was invalid */
+ RTEMS_INVALID_ADDRESS = 9, /* address specified is invalid */
+ RTEMS_INVALID_NUMBER = 10, /* number was invalid */
+ RTEMS_NOT_DEFINED = 11, /* item has not been initialized */
+ RTEMS_RESOURCE_IN_USE = 12, /* resources still outstanding */
+ RTEMS_UNSATISFIED = 13, /* request not satisfied */
+ RTEMS_INCORRECT_STATE = 14, /* thread is in wrong state */
+ RTEMS_ALREADY_SUSPENDED = 15, /* thread already in state */
+ RTEMS_ILLEGAL_ON_SELF = 16, /* illegal on calling thread */
+ RTEMS_ILLEGAL_ON_REMOTE_OBJECT = 17, /* illegal for remote object */
+ RTEMS_CALLED_FROM_ISR = 18, /* called from wrong environment */
+ RTEMS_INVALID_PRIORITY = 19, /* invalid thread priority */
+ RTEMS_INVALID_CLOCK = 20, /* invalid date/time */
+ RTEMS_INVALID_NODE = 21, /* invalid node id */
+ RTEMS_NOT_CONFIGURED = 22, /* directive not configured */
+ RTEMS_NOT_OWNER_OF_RESOURCE = 23, /* not owner of resource */
+ RTEMS_NOT_IMPLEMENTED = 24, /* directive not implemented */
+ RTEMS_INTERNAL_ERROR = 25, /* RTEMS inconsistency detected */
+ RTEMS_NO_MEMORY = 26, /* could not get enough memory */
+ RTEMS_IO_ERROR = 27, /* driver IO error */
+ RTEMS_PROXY_BLOCKING = 28 /* internal error only */
+} rtems_status_code;
+
+#define RTEMS_STATUS_CODES_FIRST RTEMS_SUCCESSFUL
+#define RTEMS_STATUS_CODES_LAST RTEMS_PROXY_BLOCKING
+
+extern rtems_status_code _Status_Object_name_errors_to_status[];
+
+#ifdef RTEMS_API_INIT
+rtems_status_code _Status_Object_name_errors_to_status[] = {
+ RTEMS_SUCCESSFUL, /* OBJECTS_SUCCESSFUL */
+ RTEMS_INVALID_NAME, /* OBJECTS_INVALID_NAME */
+ RTEMS_INVALID_ADDRESS, /* OBJECTS_INVALID_ADDRESS */
+ RTEMS_INVALID_ID, /* OBJECTS_INVALID_ID */
+ RTEMS_INVALID_NODE /* OBJECTS_INVALID_NODE */
+};
+#endif
+
+/*
+ * Applications are allowed to use the macros to compare status codes.
+ */
+
+#include <rtems/rtems/status.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/support.h b/cpukit/rtems/include/rtems/rtems/support.h
new file mode 100644
index 0000000000..1fd5b997fc
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/support.h
@@ -0,0 +1,101 @@
+/**
+ * @file rtems/rtems/support.h
+ */
+
+/*
+ * This include file contains information about support functions for
+ * the RTEMS API.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_SUPPORT_H
+#define _RTEMS_RTEMS_SUPPORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/types.h>
+
+/*
+ * rtems_build_name
+ *
+ * DESCRIPTION:
+ *
+ * This function returns an object name composed of the four characters
+ * C1, C2, C3, and C4.
+ *
+ * NOTE:
+ *
+ * This must be implemented as a macro for use in Configuration Tables.
+ *
+ */
+
+#define rtems_build_name( _C1, _C2, _C3, _C4 ) \
+ ( (uint32_t )(_C1) << 24 | (uint32_t )(_C2) << 16 | (uint32_t )(_C3) << 8 | (uint32_t )(_C4) )
+
+/*
+ * rtems_get_class
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the class portion of the ID.
+ *
+ */
+
+#define rtems_get_class( _id ) \
+ _Objects_Get_class( _id )
+
+/*
+ * rtems_get_node
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the node portion of the ID.
+ *
+ */
+
+#define rtems_get_node( _id ) \
+ _Objects_Get_node( _id )
+
+/*
+ * rtems_get_index
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the index portion of the ID.
+ *
+ */
+
+#define rtems_get_index( _id ) \
+ _Objects_Get_index( _id )
+
+/*
+ * Time related
+ */
+
+#define RTEMS_MILLISECONDS_TO_MICROSECONDS(_ms) \
+ TOD_MILLISECONDS_TO_MICROSECONDS(_ms)
+#define RTEMS_MILLISECONDS_TO_TICKS(_ms) \
+ TOD_MILLISECONDS_TO_TICKS(_ms)
+#define RTEMS_MICROSECONDS_TO_TICKS(_ms) \
+ TOD_MICROSECONDS_TO_TICKS(_ms)
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/support.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/taskmp.h b/cpukit/rtems/include/rtems/rtems/taskmp.h
new file mode 100644
index 0000000000..9adae0ced6
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/taskmp.h
@@ -0,0 +1,169 @@
+/**
+ * @file rtems/rtems/taskmp.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the multiprocessing support in the task manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_TASKMP_H
+#define _RTEMS_RTEMS_TASKMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/priority.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+
+/*
+ * The following enumerated type defines the list of
+ * remote task operations.
+ */
+
+typedef enum {
+ RTEMS_TASKS_MP_ANNOUNCE_CREATE = 0,
+ RTEMS_TASKS_MP_ANNOUNCE_DELETE = 1,
+ RTEMS_TASKS_MP_SUSPEND_REQUEST = 2,
+ RTEMS_TASKS_MP_SUSPEND_RESPONSE = 3,
+ RTEMS_TASKS_MP_RESUME_REQUEST = 4,
+ RTEMS_TASKS_MP_RESUME_RESPONSE = 5,
+ RTEMS_TASKS_MP_SET_PRIORITY_REQUEST = 6,
+ RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE = 7,
+ RTEMS_TASKS_MP_GET_NOTE_REQUEST = 8,
+ RTEMS_TASKS_MP_GET_NOTE_RESPONSE = 9,
+ RTEMS_TASKS_MP_SET_NOTE_REQUEST = 10,
+ RTEMS_TASKS_MP_SET_NOTE_RESPONSE = 11
+} RTEMS_tasks_MP_Remote_operations;
+
+/*
+ * The following data structure defines the packet used to perform
+ * remote task operations.
+ */
+
+typedef struct {
+ rtems_packet_prefix Prefix;
+ RTEMS_tasks_MP_Remote_operations operation;
+ rtems_name name;
+ rtems_task_priority the_priority;
+ uint32_t notepad;
+ uint32_t note;
+} RTEMS_tasks_MP_Packet;
+
+/*
+ * _RTEMS_tasks_MP_Send_process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+
+void _RTEMS_tasks_MP_Send_process_packet (
+ RTEMS_tasks_MP_Remote_operations operation,
+ Objects_Id task_id,
+ rtems_name name
+);
+
+/*
+ * _RTEMS_tasks_MP_Send_request_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ */
+
+rtems_status_code _RTEMS_tasks_MP_Send_request_packet (
+ RTEMS_tasks_MP_Remote_operations operation,
+ Objects_Id task_id,
+ rtems_task_priority the_priority,
+ uint32_t notepad,
+ uint32_t note
+);
+
+/*
+ * _RTEMS_tasks_MP_Send_response_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ */
+
+void _RTEMS_tasks_MP_Send_response_packet (
+ RTEMS_tasks_MP_Remote_operations operation,
+ Thread_Control *the_thread
+);
+
+/*
+ *
+ * _RTEMS_tasks_MP_Process_packet
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+
+void _RTEMS_tasks_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/*
+ * _RTEMS_tasks_MP_Send_object_was_deleted
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed by RTEMS_tasks since a task
+ * cannot be deleted when segments are in use.
+ */
+
+/*
+ * _RTEMS_tasks_MP_Send_extract_proxy
+ *
+ * DESCRIPTION:
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ *
+ */
+
+/*
+ * _RTEMS_tasks_MP_Get_packet
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to obtain a task mp packet.
+ */
+
+RTEMS_tasks_MP_Packet *_RTEMS_tasks_MP_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h
new file mode 100644
index 0000000000..c4a3a9dc0d
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/tasks.h
@@ -0,0 +1,470 @@
+/**
+ * @file rtems/rtems/tasks.h
+ */
+
+/*
+ * This include file contains all constants and structures associated
+ * with RTEMS tasks. This manager provides a comprehensive set of directives
+ * to create, delete, and administer tasks.
+ *
+ * Directives provided are:
+ *
+ * + create a task
+ * + get an ID of a task
+ * + start a task
+ * + restart a task
+ * + delete a task
+ * + suspend a task
+ * + resume a task
+ * + set a task's priority
+ * + change the current task's mode
+ * + get a task notepad entry
+ * + set a task notepad entry
+ * + wake up after interval
+ * + wake up when specified
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_TASKS_H
+#define _RTEMS_RTEMS_TASKS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/eventset.h>
+#include <rtems/rtems/asr.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/status.h>
+
+/*
+ * Constant to be used as the ID of current task
+ */
+
+#define RTEMS_SELF OBJECTS_ID_OF_SELF
+
+/*
+ * This constant is passed to the rtems_task_wake_after directive as the
+ * interval when a task wishes to yield the CPU.
+ */
+
+#define RTEMS_YIELD_PROCESSOR WATCHDOG_NO_TIMEOUT
+
+/*
+ * Define the type for an RTEMS API task priority.
+ */
+
+typedef Priority_Control rtems_task_priority;
+
+#define RTEMS_NO_PRIORITY RTEMS_CURRENT_PRIORITY
+
+#define RTEMS_MINIMUM_PRIORITY (PRIORITY_MINIMUM + 1)
+#define RTEMS_MAXIMUM_PRIORITY PRIORITY_MAXIMUM
+
+/*
+ * The following constant is passed to rtems_task_set_priority when the
+ * caller wants to obtain the current priority.
+ */
+
+#define RTEMS_CURRENT_PRIORITY PRIORITY_MINIMUM
+
+/*
+ * Notepads constants (indices into notepad array)
+ */
+
+#define RTEMS_NOTEPAD_FIRST 0 /* lowest numbered notepad */
+#define RTEMS_NOTEPAD_0 0 /* notepad location 0 */
+#define RTEMS_NOTEPAD_1 1 /* notepad location 1 */
+#define RTEMS_NOTEPAD_2 2 /* notepad location 2 */
+#define RTEMS_NOTEPAD_3 3 /* notepad location 3 */
+#define RTEMS_NOTEPAD_4 4 /* notepad location 4 */
+#define RTEMS_NOTEPAD_5 5 /* notepad location 5 */
+#define RTEMS_NOTEPAD_6 6 /* notepad location 6 */
+#define RTEMS_NOTEPAD_7 7 /* notepad location 7 */
+#define RTEMS_NOTEPAD_8 8 /* notepad location 8 */
+#define RTEMS_NOTEPAD_9 9 /* notepad location 9 */
+#define RTEMS_NOTEPAD_10 10 /* notepad location 10 */
+#define RTEMS_NOTEPAD_11 11 /* notepad location 11 */
+#define RTEMS_NOTEPAD_12 12 /* notepad location 12 */
+#define RTEMS_NOTEPAD_13 13 /* notepad location 13 */
+#define RTEMS_NOTEPAD_14 14 /* notepad location 14 */
+#define RTEMS_NOTEPAD_15 15 /* notepad location 15 */
+#define RTEMS_NOTEPAD_LAST RTEMS_NOTEPAD_15 /* highest numbered notepad */
+
+#define RTEMS_NUMBER_NOTEPADS (RTEMS_NOTEPAD_LAST+1)
+
+/*
+ * External API name for Thread_Control
+ */
+
+typedef Thread_Control rtems_tcb;
+
+/*
+ * The following defines the "return type" of an RTEMS task.
+ */
+
+typedef void rtems_task;
+
+/*
+ * The following defines the argument to an RTEMS task.
+ */
+
+typedef uint32_t rtems_task_argument;
+
+/*
+ * The following defines the type for the entry point of an RTEMS task.
+ */
+
+typedef rtems_task ( *rtems_task_entry )(
+ rtems_task_argument
+ );
+
+/*
+ * The following records define the Initialization Tasks Table.
+ * Each entry contains the information required by RTEMS to
+ * create and start a user task automatically at executive
+ * initialization time.
+ */
+
+typedef struct {
+ rtems_name name; /* task name */
+ uint32_t stack_size; /* task stack size */
+ rtems_task_priority initial_priority; /* task priority */
+ rtems_attribute attribute_set; /* task attributes */
+ rtems_task_entry entry_point; /* task entry point */
+ rtems_mode mode_set; /* task initial mode */
+ rtems_task_argument argument; /* task argument */
+} rtems_initialization_tasks_table;
+
+/*
+ * This is the API specific information required by each thread for
+ * the RTEMS API to function correctly.
+ */
+
+
+typedef struct {
+ uint32_t Notepads[ RTEMS_NUMBER_NOTEPADS ];
+ rtems_event_set pending_events;
+ rtems_event_set event_condition;
+ ASR_Information Signal;
+} RTEMS_API_Control;
+
+/*
+ * The following defines the information control block used to
+ * manage this class of objects.
+ */
+
+RTEMS_EXTERN Objects_Information _RTEMS_tasks_Information;
+
+/*
+ * These are used to manage the user initialization tasks.
+ */
+
+RTEMS_EXTERN rtems_initialization_tasks_table
+ *_RTEMS_tasks_User_initialization_tasks;
+RTEMS_EXTERN uint32_t _RTEMS_tasks_Number_of_initialization_tasks;
+
+/*
+ * _RTEMS_tasks_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine initializes all Task Manager related data structures.
+ */
+
+void _RTEMS_tasks_Manager_initialization(
+ uint32_t maximum_tasks,
+ uint32_t number_of_initialization_tasks,
+ rtems_initialization_tasks_table *user_tasks
+);
+
+/*
+ * rtems_task_create
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_create directive. The task
+ * will have the name name. The attribute_set can be used to indicate
+ * that the task will be globally accessible or utilize floating point.
+ * The task's stack will be stack_size bytes. The task will begin
+ * execution with initial_priority and initial_modes. It returns the
+ * id of the created task in ID.
+ */
+
+rtems_status_code rtems_task_create(
+ rtems_name name,
+ rtems_task_priority initial_priority,
+ uint32_t stack_size,
+ rtems_mode initial_modes,
+ rtems_attribute attribute_set,
+ Objects_Id *id
+);
+
+/*
+ * rtems_task_ident
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_ident directive.
+ * This directive returns the task ID associated with name.
+ * If more than one task is named name, then the task to
+ * which the ID belongs is arbitrary. node indicates the
+ * extent of the search for the ID of the task named name.
+ * The search can be limited to a particular node or allowed to
+ * encompass all nodes.
+ */
+
+rtems_status_code rtems_task_ident(
+ rtems_name name,
+ uint32_t node,
+ Objects_Id *id
+);
+
+/*
+ * rtems_task_delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_delete directive. The
+ * task indicated by ID is deleted.
+ */
+
+rtems_status_code rtems_task_delete(
+ Objects_Id id
+);
+
+/*
+ * rtems_task_get_note
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_get_note directive. The
+ * value of the indicated notepad for the task associated with ID
+ * is returned in note.
+ */
+
+rtems_status_code rtems_task_get_note(
+ Objects_Id id,
+ uint32_t notepad,
+ uint32_t *note
+);
+
+/*
+ * rtems_task_set_note
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_set_note directive. The
+ * value of the indicated notepad for the task associated with ID
+ * is returned in note.
+ */
+
+rtems_status_code rtems_task_set_note(
+ Objects_Id id,
+ uint32_t notepad,
+ uint32_t note
+);
+
+/*
+ * rtems_task_mode
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_mode directive. The current
+ * values of the modes indicated by mask of the calling task are changed
+ * to that indicated in mode_set. The former mode of the task is
+ * returned in mode_set.
+ */
+
+rtems_status_code rtems_task_mode(
+ rtems_mode mode_set,
+ rtems_mode mask,
+ rtems_mode *previous_mode_set
+);
+
+/*
+ * rtems_task_restart
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_restart directive. The
+ * task associated with ID is restarted at its initial entry
+ * point with the new argument.
+ */
+
+rtems_status_code rtems_task_restart(
+ Objects_Id id,
+ uint32_t arg
+);
+
+/*
+ * rtems_task_suspend
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_suspend directive. The
+ * SUSPENDED state is set for task associated with ID.
+ */
+
+rtems_status_code rtems_task_suspend(
+ Objects_Id id
+);
+
+/*
+ * rtems_task_resume
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_resume Directive. The
+ * SUSPENDED state is cleared for task associated with ID.
+ */
+
+rtems_status_code rtems_task_resume(
+ Objects_Id id
+);
+
+/*
+ * rtems_task_set_priority
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_set_priority directive. The
+ * current priority of the task associated with ID is set to
+ * new_priority. The former priority of that task is returned
+ * in old_priority.
+ */
+
+rtems_status_code rtems_task_set_priority(
+ Objects_Id id,
+ rtems_task_priority new_priority,
+ rtems_task_priority *old_priority
+);
+
+/*
+ * rtems_task_start
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_start directive. The
+ * starting execution point of the task associated with ID is
+ * set to entry_point with the initial argument.
+ */
+
+rtems_status_code rtems_task_start(
+ Objects_Id id,
+ rtems_task_entry entry_point,
+ rtems_task_argument argument
+);
+
+/*
+ * rtems_task_wake_when
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_wake_when directive. The
+ * calling task is blocked until the current time of day is
+ * equal to that indicated by time_buffer.
+ */
+
+rtems_status_code rtems_task_wake_when(
+ rtems_time_of_day *time_buffer
+);
+
+/*
+ * rtems_task_wake_after
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_task_wake_after directive. The
+ * calling task is blocked until the indicated number of clock
+ * ticks have occurred.
+ */
+
+rtems_status_code rtems_task_wake_after(
+ rtems_interval ticks
+);
+
+/*
+ * rtems_task_is_suspended
+ *
+ * This directive returns a status indicating whether or not
+ * the specified task is suspended.
+ */
+
+rtems_status_code rtems_task_is_suspended(
+ Objects_Id id
+);
+
+/*
+ * rtems_task_variable_add
+ *
+ * This directive adds a per task variable.
+ */
+
+rtems_status_code rtems_task_variable_add(
+ rtems_id tid,
+ void **ptr,
+ void (*dtor)(void *)
+);
+
+/*
+ * rtems_task_variable_get
+ *
+ * This directive gets the value of a task variable.
+ */
+
+rtems_status_code rtems_task_variable_get(
+ rtems_id tid,
+ void **ptr,
+ void **result
+);
+
+/*
+ * rtems_task_variable_delete
+ *
+ * This directive removes a per task variable.
+ */
+
+rtems_status_code rtems_task_variable_delete(
+ rtems_id tid,
+ void **ptr
+);
+
+/*
+ * _RTEMS_tasks_Initialize_user_tasks
+ *
+ * This routine creates and starts all configured user
+ * initialzation threads.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _RTEMS_tasks_Initialize_user_tasks( void );
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/tasks.inl>
+#endif
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/taskmp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/timer.h b/cpukit/rtems/include/rtems/rtems/timer.h
new file mode 100644
index 0000000000..8048754fd4
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/timer.h
@@ -0,0 +1,369 @@
+/**
+ * @file rtems/rtems/timer.h
+ */
+
+/*
+ * This include file contains all the constants, structures, and
+ * prototypes associated with the Timer Manager. This manager provides
+ * facilities to configure, initiate, cancel, and delete timers which will
+ * fire at specified intervals of time.
+ *
+ * Directives provided are:
+ *
+ * + create a timer
+ * + get an ID of a timer
+ * + delete a timer
+ * + set timer to fire in context of clock tick
+ * - after a number of ticks have passed
+ * - when a specified date and time has been reached
+ * + initiate the timer server task
+ * + set timer to fire in context of the timer server task
+ * - after a number of ticks have passed
+ * - when a specified date and time has been reached
+ * + reset a timer
+ * + cancel a time
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_TIMER_H
+#define _RTEMS_RTEMS_TIMER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/rtems/attr.h>
+
+/*
+ * The following enumerated type details the classes to which a timer
+ * may belong.
+ */
+
+typedef enum {
+ TIMER_INTERVAL,
+ TIMER_INTERVAL_ON_TASK,
+ TIMER_TIME_OF_DAY,
+ TIMER_TIME_OF_DAY_ON_TASK,
+ TIMER_DORMANT
+} Timer_Classes;
+
+/*
+ * The following types define a pointer to a timer service routine.
+ */
+
+typedef void rtems_timer_service_routine;
+
+typedef rtems_timer_service_routine ( *rtems_timer_service_routine_entry )(
+ rtems_id,
+ void *
+ );
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+RTEMS_EXTERN Objects_Information _Timer_Information;
+
+/*
+ * Pointer to TCB of the Timer Server. This is NULL before the
+ * server is executing and task-based timers are not allowed to be
+ * initiated until the server is started.
+ */
+
+RTEMS_EXTERN Thread_Control *_Timer_Server;
+
+/*
+ * The following chains contain the list of interval timers that are
+ * executed in the context of the Timer Server.
+ *
+ * NOTE: These are extern'ed because they do not have to be in the
+ * minimum footprint. They are only really required when
+ * task-based timers are used. Since task-based timers can
+ * not be started until the server is initiated, these structures
+ * do not have to be initialized until then. They are declared
+ * in the same file as _Timer_Server_body.
+ */
+
+extern Chain_Control _Timer_Ticks_chain;
+extern Chain_Control _Timer_Seconds_chain;
+
+/*
+ * The following records define the control block used to manage
+ * each timer.
+ */
+
+typedef struct {
+ Objects_Control Object;
+ Watchdog_Control Ticker;
+ Timer_Classes the_class;
+} Timer_Control;
+
+/*
+ * _Timer_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Timer_Manager_initialization(
+ uint32_t maximum_timers
+);
+
+/*
+ * _Timer_Server_body
+ *
+ * DESCRIPTION:
+ *
+ * This is the server for task based timers. This task executes whenever
+ * a task-based timer should fire. It services both "after" and "when"
+ * timers. It is not created automatically but must be created explicitly
+ * by the application before task-based timers may be initiated.
+ */
+
+Thread _Timer_Server_body(
+ uint32_t ignored
+);
+
+/*
+ * rtems_timer_create
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_timer_create directive. The
+ * timer will have the name name. It returns the id of the
+ * created timer in ID.
+ */
+
+rtems_status_code rtems_timer_create(
+ rtems_name name,
+ Objects_Id *id
+);
+
+/*
+ * rtems_timer_ident
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_timer_ident directive.
+ * This directive returns the timer ID associated with name.
+ * If more than one timer is named name, then the timer
+ * to which the ID belongs is arbitrary.
+ */
+
+rtems_status_code rtems_timer_ident(
+ rtems_name name,
+ Objects_Id *id
+);
+
+/*
+ * rtems_timer_cancel
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_timer_cancel directive. It is used
+ * to stop the timer associated with ID from firing.
+ */
+
+rtems_status_code rtems_timer_cancel(
+ Objects_Id id
+);
+
+/*
+ * rtems_timer_delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_timer_delete directive. The
+ * timer indicated by ID is deleted.
+ */
+
+rtems_status_code rtems_timer_delete(
+ Objects_Id id
+);
+
+/*
+ * rtems_timer_fire_after
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_timer_fire_after directive. It
+ * initiates the timer associated with ID to fire in ticks clock ticks.
+ * When the timer fires, the routine will be invoked in the context
+ * of the rtems_clock_tick directive which is normally invoked as
+ * part of servicing a periodic interupt.
+ */
+
+rtems_status_code rtems_timer_fire_after(
+ Objects_Id id,
+ rtems_interval ticks,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+);
+
+/*
+ * rtems_timer_server_fire_after
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_timer_server_fire_after directive. It
+ * initiates the timer associated with ID to fire in ticks clock
+ * ticks. When the timer fires, the routine will be invoked by the
+ * Timer Server in the context of a task NOT IN THE CONTEXT of the
+ * clock tick interrupt.
+ */
+
+rtems_status_code rtems_timer_server_fire_after(
+ Objects_Id id,
+ rtems_interval ticks,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+);
+
+/*
+ * rtems_timer_fire_when
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_timer_fire_when directive. It
+ * initiates the timer associated with ID to fire at wall_time
+ * When the timer fires, the routine will be invoked in the context
+ * of the rtems_clock_tick directive which is normally invoked as
+ * part of servicing a periodic interupt.
+ */
+
+rtems_status_code rtems_timer_fire_when(
+ Objects_Id id,
+ rtems_time_of_day *wall_time,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+);
+
+/*
+ * rtems_timer_server_fire_when
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_timer_server_fire_when directive. It
+ * initiates the timer associated with ID to fire at wall_time
+ * When the timer fires, the routine will be invoked by the
+ * Timer Server in the context of a task NOT IN THE CONTEXT of the
+ * clock tick interrupt.
+ */
+
+rtems_status_code rtems_timer_server_fire_when(
+ Objects_Id id,
+ rtems_time_of_day *wall_time,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+);
+
+/*
+ * rtems_timer_reset
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_timer_reset directive. It is used
+ * to reinitialize the interval timer associated with ID just as if
+ * rtems_timer_fire_after were re-invoked with the same arguments that
+ * were used to initiate this timer.
+ */
+
+rtems_status_code rtems_timer_reset(
+ Objects_Id id
+);
+
+/*
+ * rtems_timer_initiate_server
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_timer_initiate_server directive.
+ * It creates and starts the server that executes task-based timers.
+ * It must be invoked before any task-based timers can be initiated.
+ */
+
+#define RTEMS_TIMER_SERVER_DEFAULT_PRIORITY -1
+
+rtems_status_code rtems_timer_initiate_server(
+ uint32_t priority,
+ uint32_t stack_size,
+ rtems_attribute attribute_set
+);
+
+/*
+ * rtems_timer_get_information
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_timer_get_information directive.
+ * This directive returns information about the timer.
+ */
+
+typedef struct {
+ Timer_Classes the_class;
+ Watchdog_Interval initial;
+ Watchdog_Interval start_time;
+ Watchdog_Interval stop_time;
+} rtems_timer_information;
+
+rtems_status_code rtems_timer_get_information(
+ Objects_Id id,
+ rtems_timer_information *the_info
+);
+
+/*
+ * Macros and routines that expose the mechanisms required to service
+ * the Timer Server timer. These stop the timer, synchronize it with
+ * the current time, and restart it.
+ */
+
+extern Watchdog_Control _Timer_Seconds_timer;
+
+#define _Timer_Server_stop_ticks_timer() \
+ _Watchdog_Remove( &_Timer_Server->Timer )
+
+#define _Timer_Server_stop_seconds_timer() \
+ _Watchdog_Remove( &_Timer_Seconds_timer );
+
+void _Timer_Server_process_ticks_chain(void);
+void _Timer_Server_process_seconds_chain(void);
+
+#define _Timer_Server_reset_ticks_timer() \
+ do { \
+ if ( !_Chain_Is_empty( &_Timer_Ticks_chain ) ) { \
+ _Watchdog_Insert_ticks( &_Timer_Server->Timer, \
+ ((Watchdog_Control *)_Timer_Ticks_chain.first)->delta_interval ); \
+ } \
+ } while (0)
+
+#define _Timer_Server_reset_seconds_timer() \
+ do { \
+ if ( !_Chain_Is_empty( &_Timer_Seconds_chain ) ) { \
+ _Watchdog_Insert_seconds( &_Timer_Seconds_timer, \
+ ((Watchdog_Control *)_Timer_Seconds_chain.first)->delta_interval ); \
+ } \
+ } while (0)
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/rtems/timer.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/include/rtems/rtems/types.h b/cpukit/rtems/include/rtems/rtems/types.h
new file mode 100644
index 0000000000..810f4767b5
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/types.h
@@ -0,0 +1,114 @@
+/**
+ * @file rtems/rtems/types.h
+ */
+
+/*
+ * This include file defines the types used by the RTEMS API.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_TYPES_H
+#define _RTEMS_RTEMS_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * RTEMS basic type definitions
+ */
+
+#include <rtems/stdint.h>
+
+/* backward compatibility types */
+typedef uint8_t rtems_unsigned8;
+typedef uint16_t rtems_unsigned16;
+typedef uint32_t rtems_unsigned32;
+#if defined(uint64_t)
+/* FIXME: Some targets do not have 64-bit types */
+typedef uint64_t rtems_unsigned64;
+#endif
+
+typedef int8_t rtems_signed8;
+typedef int16_t rtems_signed16;
+typedef int32_t rtems_signed32;
+#if defined(int64_t)
+/* FIXME: Some targets do not have 64-bit types */
+typedef int64_t rtems_signed64;
+#endif
+
+#include <rtems/score/heap.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/rtems/modes.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#include <rtems/score/mppkt.h>
+#endif
+
+typedef single_precision rtems_single; /* single precision float */
+typedef double_precision rtems_double; /* double precision float */
+
+typedef boolean rtems_boolean;
+
+typedef uint32_t rtems_name;
+typedef Objects_Id rtems_id;
+
+typedef Context_Control rtems_context;
+typedef Context_Control_fp rtems_context_fp;
+typedef CPU_Interrupt_frame rtems_interrupt_frame;
+
+/*
+ * Region information block
+ */
+
+typedef Heap_Information_block region_information_block;
+
+/*
+ * Time related
+ */
+
+typedef Watchdog_Interval rtems_interval;
+typedef TOD_Control rtems_time_of_day;
+
+/*
+ * Define the type for an RTEMS API task mode.
+ */
+
+typedef Modes_Control rtems_mode;
+
+/*
+ * MPCI related entries
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+typedef MP_packet_Classes rtems_mp_packet_classes;
+typedef MP_packet_Prefix rtems_packet_prefix;
+
+typedef MPCI_initialization_entry rtems_mpci_initialization_entry;
+typedef MPCI_get_packet_entry rtems_mpci_get_packet_entry;
+typedef MPCI_return_packet_entry rtems_mpci_return_packet_entry;
+typedef MPCI_send_entry rtems_mpci_send_packet_entry;
+typedef MPCI_receive_entry rtems_mpci_receive_packet_entry;
+
+typedef MPCI_Entry rtems_mpci_entry;
+
+typedef MPCI_Control rtems_mpci_table;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/asr.inl b/cpukit/rtems/inline/rtems/rtems/asr.inl
new file mode 100644
index 0000000000..bd3b37e060
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/asr.inl
@@ -0,0 +1,130 @@
+/**
+ * @file rtems/rtems/asr.inl
+ */
+
+/*
+ * This include file contains the implemenation of all routines
+ * associated with the asynchronous signal handler which are inlined.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_ASR_INL
+#define _RTEMS_RTEMS_ASR_INL
+
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _ASR_Initialize
+ *
+ * DESCRIPTION:
+ *
+ * This routine initializes the given RTEMS_ASR information record.
+ */
+
+RTEMS_INLINE_ROUTINE void _ASR_Initialize (
+ ASR_Information *information
+)
+{
+ information->is_enabled = TRUE;
+ information->handler = NULL;
+ information->mode_set = RTEMS_DEFAULT_MODES;
+ information->signals_posted = 0;
+ information->signals_pending = 0;
+ information->nest_level = 0;
+}
+
+/*PAGE
+ *
+ * _ASR_Swap_signals
+ *
+ * DESCRIPTION:
+ *
+ * This routine atomically swaps the pending and posted signal
+ * sets. This is done when the thread alters its mode in such a
+ * way that the RTEMS_ASR disable/enable flag changes.
+ */
+
+RTEMS_INLINE_ROUTINE void _ASR_Swap_signals (
+ ASR_Information *information
+)
+{
+ rtems_signal_set _signals;
+ ISR_Level _level;
+
+ _ISR_Disable( _level );
+ _signals = information->signals_pending;
+ information->signals_pending = information->signals_posted;
+ information->signals_posted = _signals;
+ _ISR_Enable( _level );
+}
+
+/*PAGE
+ *
+ * _ASR_Is_null_handler
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the given asr_handler is NULL and
+ * FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ASR_Is_null_handler (
+ rtems_asr_entry asr_handler
+)
+{
+ return asr_handler == NULL;
+}
+
+/*PAGE
+ *
+ * _ASR_Are_signals_pending
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if there are signals pending in the
+ * given RTEMS_ASR information record and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ASR_Are_signals_pending (
+ ASR_Information *information
+)
+{
+ return information->signals_posted != 0;
+}
+
+/*PAGE
+ *
+ * _ASR_Post_signals
+ *
+ * DESCRIPTION:
+ *
+ * This routine posts the given signals into the signal_set
+ * passed in. The result is returned to the user in signal_set.
+ *
+ * NOTE: This must be implemented as a macro.
+ */
+
+RTEMS_INLINE_ROUTINE void _ASR_Post_signals(
+ rtems_signal_set signals,
+ rtems_signal_set *signal_set
+)
+{
+ ISR_Level _level;
+
+ _ISR_Disable( _level );
+ *signal_set |= signals;
+ _ISR_Enable( _level );
+}
+
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/attr.inl b/cpukit/rtems/inline/rtems/rtems/attr.inl
new file mode 100644
index 0000000000..387bf6b888
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/attr.inl
@@ -0,0 +1,215 @@
+/**
+ * @file rtems/rtems/attr.inl
+ */
+
+/*
+ * This include file contains all of the inlined routines associated
+ * with attributes.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_ATTR_INL
+#define _RTEMS_RTEMS_ATTR_INL
+
+/*PAGE
+ *
+ * _Attributes_Set
+ *
+ * DESCRIPTION:
+ *
+ * This function sets the requested new_attributes in the attribute_set
+ * passed in. The result is returned to the user.
+ */
+
+RTEMS_INLINE_ROUTINE rtems_attribute _Attributes_Set (
+ rtems_attribute new_attributes,
+ rtems_attribute attribute_set
+)
+{
+ return attribute_set | new_attributes;
+}
+
+/*PAGE
+ *
+ * _Attributes_Clear
+ *
+ * DESCRIPTION:
+ *
+ * This function clears the requested new_attributes in the attribute_set
+ * passed in. The result is returned to the user.
+ */
+
+RTEMS_INLINE_ROUTINE rtems_attribute _Attributes_Clear (
+ rtems_attribute attribute_set,
+ rtems_attribute mask
+)
+{
+ return attribute_set & ~mask;
+}
+
+/*PAGE
+ *
+ * _Attributes_Is_floating_point
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the floating point attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Attributes_Is_floating_point(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_FLOATING_POINT );
+}
+
+/*PAGE
+ *
+ * _Attributes_Is_global
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the global object attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+RTEMS_INLINE_ROUTINE boolean _Attributes_Is_global(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_GLOBAL );
+}
+#endif
+
+/*PAGE
+ *
+ * _Attributes_Is_priority
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the priority attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Attributes_Is_priority(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_PRIORITY );
+}
+
+/*PAGE
+ *
+ * _Attributes_Is_binary_semaphore
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the binary semaphore attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Attributes_Is_binary_semaphore(
+ rtems_attribute attribute_set
+)
+{
+ return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_BINARY_SEMAPHORE);
+}
+
+/*PAGE
+ *
+ * _Attributes_Is_simple_binary_semaphore
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the simple binary semaphore attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Attributes_Is_simple_binary_semaphore(
+ rtems_attribute attribute_set
+)
+{
+ return
+ ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_SIMPLE_BINARY_SEMAPHORE);
+}
+
+/*PAGE
+ *
+ * _Attributes_Is_counting_semaphore
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the counting semaphore attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Attributes_Is_counting_semaphore(
+ rtems_attribute attribute_set
+)
+{
+ return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_COUNTING_SEMAPHORE);
+}
+
+/*PAGE
+ *
+ * _Attributes_Is_inherit_priority
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the priority inheritance attribute
+ * is enabled in the attribute_set and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Attributes_Is_inherit_priority(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_INHERIT_PRIORITY );
+}
+
+/*PAGE
+ *
+ * _Attributes_Is_priority_ceiling
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the priority ceiling attribute
+ * is enabled in the attribute_set and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Attributes_Is_priority_ceiling(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_PRIORITY_CEILING );
+}
+
+/*PAGE
+ *
+ * _Attributes_Is_system_task
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the system task attribute
+ * is enabled in the attribute_set and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Attributes_Is_system_task(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_SYSTEM_TASK );
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/dpmem.inl b/cpukit/rtems/inline/rtems/rtems/dpmem.inl
new file mode 100644
index 0000000000..f80d2ebaf5
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/dpmem.inl
@@ -0,0 +1,97 @@
+/**
+ * @file rtems/rtems/dpmem.inl
+ */
+
+/*
+ * This include file contains the inline routine used in conjunction
+ * with the Dual Ported Memory Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_DPMEM_INL
+#define _RTEMS_RTEMS_DPMEM_INL
+
+
+/*PAGE
+ *
+ * _Dual_ported_memory_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This routine allocates a port control block from the inactive chain
+ * of free port control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE Dual_ported_memory_Control
+ *_Dual_ported_memory_Allocate ( void )
+{
+ return (Dual_ported_memory_Control *)
+ _Objects_Allocate( &_Dual_ported_memory_Information );
+}
+
+/*PAGE
+ *
+ * _Dual_ported_memory_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a port control block to the inactive chain
+ * of free port control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Dual_ported_memory_Free (
+ Dual_ported_memory_Control *the_port
+)
+{
+ _Objects_Free( &_Dual_ported_memory_Information, &the_port->Object );
+}
+
+/*PAGE
+ *
+ * _Dual_ported_memory_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps port IDs to port control blocks. If ID
+ * corresponds to a local port, then it returns the_port control
+ * pointer which maps to ID and location is set to OBJECTS_LOCAL.
+ * Global ports are not supported, thus if ID does not map to a
+ * local port, location is set to OBJECTS_ERROR and the_port is
+ * undefined.
+ */
+
+RTEMS_INLINE_ROUTINE Dual_ported_memory_Control *_Dual_ported_memory_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (Dual_ported_memory_Control *)
+ _Objects_Get( &_Dual_ported_memory_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _Dual_ported_memory_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_port is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Dual_ported_memory_Is_null(
+ Dual_ported_memory_Control *the_port
+)
+{
+ return ( the_port == NULL );
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/event.inl b/cpukit/rtems/inline/rtems/rtems/event.inl
new file mode 100644
index 0000000000..0ad4bc0be3
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/event.inl
@@ -0,0 +1,23 @@
+/**
+ * @file rtems/rtems/event.inl
+ */
+
+/*
+ * This include file contains the static inline implementation of
+ * macros for the Event Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_EVENT_INL
+#define _RTEMS_RTEMS_EVENT_INL
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/eventset.inl b/cpukit/rtems/inline/rtems/rtems/eventset.inl
new file mode 100644
index 0000000000..05f0e805d4
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/eventset.inl
@@ -0,0 +1,97 @@
+/**
+ * @file rtems/rtems/eventset.inl
+ */
+
+/*
+ * This include file contains the information pertaining to event sets.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_EVENTSET_INL
+#define _RTEMS_RTEMS_EVENTSET_INL
+
+/*PAGE
+ *
+ * _Event_sets_Is_empty
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if on events are posted in the event_set,
+ * and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Event_sets_Is_empty(
+ rtems_event_set the_event_set
+)
+{
+ return ( the_event_set == 0 );
+}
+
+/*PAGE
+ *
+ * _Event_sets_Post
+ *
+ * DESCRIPTION:
+ *
+ * This routine posts the given new_events into the event_set
+ * passed in. The result is returned to the user in event_set.
+ */
+
+RTEMS_INLINE_ROUTINE void _Event_sets_Post(
+ rtems_event_set the_new_events,
+ rtems_event_set *the_event_set
+)
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+ *the_event_set |= the_new_events;
+ _ISR_Enable( level );
+}
+
+/*PAGE
+ *
+ * _Event_sets_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the events in event_condition which are
+ * set in event_set.
+ */
+
+RTEMS_INLINE_ROUTINE rtems_event_set _Event_sets_Get(
+ rtems_event_set the_event_set,
+ rtems_event_set the_event_condition
+)
+{
+ return ( the_event_set & the_event_condition );
+}
+
+/*PAGE
+ *
+ * _Event_sets_Clear
+ *
+ * DESCRIPTION:
+ *
+ * This function removes the events in mask from the event_set
+ * passed in. The result is returned to the user in event_set.
+ */
+
+RTEMS_INLINE_ROUTINE rtems_event_set _Event_sets_Clear(
+ rtems_event_set the_event_set,
+ rtems_event_set the_mask
+)
+{
+ return ( the_event_set & ~(the_mask) );
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/message.inl b/cpukit/rtems/inline/rtems/rtems/message.inl
new file mode 100644
index 0000000000..06ccc32e1e
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/message.inl
@@ -0,0 +1,85 @@
+/**
+ * @file rtems/rtems/message.inl
+ */
+
+/*
+ * This include file contains the static inline implementation of all
+ * inlined routines in the Message Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_MESSAGE_INL
+#define _RTEMS_RTEMS_MESSAGE_INL
+
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Message_queue_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function places the_message at the rear of the outstanding
+ * messages on the_message_queue.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Message_queue_Is_null (
+ Message_queue_Control *the_message_queue
+)
+{
+ return ( the_message_queue == NULL );
+}
+
+
+/*PAGE
+ *
+ * _Message_queue_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine deallocates a message queue control block into
+ * the inactive chain of free message queue control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Message_queue_Free (
+ Message_queue_Control *the_message_queue
+)
+{
+ _Objects_Free( &_Message_queue_Information, &the_message_queue->Object );
+}
+
+/*PAGE
+ *
+ * _Message_queue_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps message queue IDs to message queue control
+ * blocks. If ID corresponds to a local message queue, then it
+ * returns the_message_queue control pointer which maps to ID
+ * and location is set to OBJECTS_LOCAL. If the message queue ID is
+ * global and resides on a remote node, then location is set
+ * to OBJECTS_REMOTE, and the_message_queue is undefined.
+ * Otherwise, location is set to OBJECTS_ERROR and
+ * the_message_queue is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (Message_queue_Control *)
+ _Objects_Get( &_Message_queue_Information, id, location );
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/modes.inl b/cpukit/rtems/inline/rtems/rtems/modes.inl
new file mode 100644
index 0000000000..eef7a3d9f3
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/modes.inl
@@ -0,0 +1,154 @@
+/**
+ * @file rtems/rtems/modes.inl
+ */
+
+/*
+ * This include file contains the static inline implementation of the
+ * inlined routines in the Mode Handler
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_MODES_INL
+#define _RTEMS_RTEMS_MODES_INL
+
+/*PAGE
+ *
+ * _Modes_Mask_changed
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if any of the mode flags in mask
+ * are set in mode_set, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Modes_Mask_changed (
+ Modes_Control mode_set,
+ Modes_Control masks
+)
+{
+ return ( mode_set & masks );
+}
+
+/*PAGE
+ *
+ * _Modes_Is_asr_disabled
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if mode_set indicates that Asynchronous
+ * Signal Processing is disabled, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Modes_Is_asr_disabled (
+ Modes_Control mode_set
+)
+{
+ return (mode_set & RTEMS_ASR_MASK) == RTEMS_NO_ASR;
+}
+
+/*PAGE
+ *
+ * _Modes_Is_preempt
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if mode_set indicates that preemption
+ * is enabled, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Modes_Is_preempt (
+ Modes_Control mode_set
+)
+{
+ return (mode_set & RTEMS_PREEMPT_MASK) == RTEMS_PREEMPT;
+}
+
+/*PAGE
+ *
+ * _Modes_Is_timeslice
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if mode_set indicates that timeslicing
+ * is enabled, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Modes_Is_timeslice (
+ Modes_Control mode_set
+)
+{
+ return (mode_set & RTEMS_TIMESLICE_MASK) == RTEMS_TIMESLICE;
+}
+
+/*PAGE
+ *
+ * _Modes_Get_interrupt_level
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the interrupt level portion of the mode_set.
+ */
+
+RTEMS_INLINE_ROUTINE ISR_Level _Modes_Get_interrupt_level (
+ Modes_Control mode_set
+)
+{
+ return ( mode_set & RTEMS_INTERRUPT_MASK );
+}
+
+/*PAGE
+ *
+ * _Modes_Set_interrupt_level
+ *
+ * DESCRIPTION:
+ *
+ * This routine sets the current interrupt level to that specified
+ * in the mode_set.
+ */
+
+RTEMS_INLINE_ROUTINE void _Modes_Set_interrupt_level (
+ Modes_Control mode_set
+)
+{
+ _ISR_Set_level( _Modes_Get_interrupt_level( mode_set ) );
+}
+
+/*PAGE
+ *
+ * _Modes_Change
+ *
+ * DESCRIPTION:
+ *
+ * This routine changes the modes in old_mode_set indicated by
+ * mask to the requested values in new_mode_set. The resulting
+ * mode set is returned in out_mode_set and the modes that changed
+ * is returned in changed.
+ */
+
+RTEMS_INLINE_ROUTINE void _Modes_Change (
+ Modes_Control old_mode_set,
+ Modes_Control new_mode_set,
+ Modes_Control mask,
+ Modes_Control *out_mode_set,
+ Modes_Control *changed
+)
+{
+ Modes_Control _out_mode;
+
+ _out_mode = old_mode_set;
+ _out_mode &= ~mask;
+ _out_mode |= new_mode_set & mask;
+ *changed = _out_mode ^ old_mode_set;
+ *out_mode_set = _out_mode;
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/options.inl b/cpukit/rtems/inline/rtems/rtems/options.inl
new file mode 100644
index 0000000000..1aa5ba6e0d
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/options.inl
@@ -0,0 +1,57 @@
+/**
+ * @file rtems/rtems/options.inl
+ */
+
+/*
+ * This file contains the static inline implementation of the inlined
+ * routines from the Options Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_OPTIONS_INL
+#define _RTEMS_RTEMS_OPTIONS_INL
+
+/*PAGE
+ *
+ * _Options_Is_no_wait
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the RTEMS_NO_WAIT option is enabled in
+ * option_set, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Options_Is_no_wait (
+ rtems_option option_set
+)
+{
+ return (option_set & RTEMS_NO_WAIT);
+}
+
+/*PAGE
+ *
+ * _Options_Is_any
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the RTEMS_EVENT_ANY option is enabled in
+ * OPTION_SET, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Options_Is_any (
+ rtems_option option_set
+)
+{
+ return (option_set & RTEMS_EVENT_ANY);
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/part.inl b/cpukit/rtems/inline/rtems/rtems/part.inl
new file mode 100644
index 0000000000..1e8f3b2f8d
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/part.inl
@@ -0,0 +1,201 @@
+/**
+ * @file rtems/rtems/part.inl
+ */
+
+/*
+ * This file contains the macro implementation of all inlined routines
+ * in the Partition Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_PART_INL
+#define _RTEMS_RTEMS_PART_INL
+
+/*PAGE
+ *
+ * _Partition_Allocate_buffer
+ *
+ * DESCRIPTION:
+ *
+ * This function attempts to allocate a buffer from the_partition.
+ * If successful, it returns the address of the allocated buffer.
+ * Otherwise, it returns NULL.
+ */
+
+RTEMS_INLINE_ROUTINE void *_Partition_Allocate_buffer (
+ Partition_Control *the_partition
+)
+{
+ return _Chain_Get( &the_partition->Memory );
+}
+
+/*PAGE
+ *
+ * _Partition_Free_buffer
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees the_buffer to the_partition.
+ */
+
+RTEMS_INLINE_ROUTINE void _Partition_Free_buffer (
+ Partition_Control *the_partition,
+ Chain_Node *the_buffer
+)
+{
+ _Chain_Append( &the_partition->Memory, the_buffer );
+}
+
+/*PAGE
+ *
+ * _Partition_Is_buffer_on_boundary
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_buffer is on a valid buffer
+ * boundary for the_partition, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Partition_Is_buffer_on_boundary (
+ void *the_buffer,
+ Partition_Control *the_partition
+)
+{
+ uint32_t offset;
+
+ offset = (uint32_t ) _Addresses_Subtract(
+ the_buffer,
+ the_partition->starting_address
+ );
+
+ return ((offset % the_partition->buffer_size) == 0);
+}
+
+/*PAGE
+ *
+ * _Partition_Is_buffer_valid
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_buffer is a valid buffer from
+ * the_partition, otherwise FALSE is returned.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Partition_Is_buffer_valid (
+ Chain_Node *the_buffer,
+ Partition_Control *the_partition
+)
+{
+ void *starting;
+ void *ending;
+
+ starting = the_partition->starting_address;
+ ending = _Addresses_Add_offset( starting, the_partition->length );
+
+ return (
+ _Addresses_Is_in_range( the_buffer, starting, ending ) &&
+ _Partition_Is_buffer_on_boundary( the_buffer, the_partition )
+ );
+}
+
+/*PAGE
+ *
+ * _Partition_Is_buffer_size_aligned
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the use of the specified buffer_size
+ * will result in the allocation of buffers whose first byte is
+ * properly aligned, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Partition_Is_buffer_size_aligned (
+ uint32_t buffer_size
+)
+{
+ return ((buffer_size % CPU_PARTITION_ALIGNMENT) == 0);
+}
+
+/*PAGE
+ *
+ * _Partition_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a partition control block from
+ * the inactive chain of free partition control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE Partition_Control *_Partition_Allocate ( void )
+{
+ return (Partition_Control *) _Objects_Allocate( &_Partition_Information );
+}
+
+/*PAGE
+ *
+ * _Partition_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a partition control block to the
+ * inactive chain of free partition control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Partition_Free (
+ Partition_Control *the_partition
+)
+{
+ _Objects_Free( &_Partition_Information, &the_partition->Object );
+}
+
+/*PAGE
+ *
+ * _Partition_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps partition IDs to partition control blocks.
+ * If ID corresponds to a local partition, then it returns
+ * the_partition control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. If the partition ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_partition is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_partition is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE Partition_Control *_Partition_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (Partition_Control *)
+ _Objects_Get( &_Partition_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _Partition_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_partition is NULL
+ * and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Partition_Is_null (
+ Partition_Control *the_partition
+)
+{
+ return ( the_partition == NULL );
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/ratemon.inl b/cpukit/rtems/inline/rtems/rtems/ratemon.inl
new file mode 100644
index 0000000000..97f177d66e
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/ratemon.inl
@@ -0,0 +1,145 @@
+/**
+ * @file rtems/rtems/ratemon.inl
+ */
+
+/*
+ * This file contains the static inline implementation of the inlined
+ * routines in the Rate Monotonic Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_RATEMON_INL
+#define _RTEMS_RTEMS_RATEMON_INL
+
+/*PAGE
+ *
+ * _Rate_monotonic_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a period control block from
+ * the inactive chain of free period control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE Rate_monotonic_Control *_Rate_monotonic_Allocate( void )
+{
+ return (Rate_monotonic_Control *)
+ _Objects_Allocate( &_Rate_monotonic_Information );
+}
+
+/*PAGE
+ *
+ * _Rate_monotonic_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine allocates a period control block from
+ * the inactive chain of free period control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Rate_monotonic_Free (
+ Rate_monotonic_Control *the_period
+)
+{
+ _Objects_Free( &_Rate_monotonic_Information, &the_period->Object );
+}
+
+/*PAGE
+ *
+ * _Rate_monotonic_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps period IDs to period control blocks.
+ * If ID corresponds to a local period, then it returns
+ * the_period control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. Otherwise, location is set
+ * to OBJECTS_ERROR and the_period is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE Rate_monotonic_Control *_Rate_monotonic_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (Rate_monotonic_Control *)
+ _Objects_Get( &_Rate_monotonic_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _Rate_monotonic_Is_active
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_period is in the ACTIVE state,
+ * and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Rate_monotonic_Is_active (
+ Rate_monotonic_Control *the_period
+)
+{
+ return (the_period->state == RATE_MONOTONIC_ACTIVE);
+}
+
+/*PAGE
+ *
+ * _Rate_monotonic_Is_inactive
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_period is in the ACTIVE state,
+ * and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Rate_monotonic_Is_inactive (
+ Rate_monotonic_Control *the_period
+)
+{
+ return (the_period->state == RATE_MONOTONIC_INACTIVE);
+}
+
+/*PAGE
+ *
+ * _Rate_monotonic_Is_expired
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_period is in the EXPIRED state,
+ * and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Rate_monotonic_Is_expired (
+ Rate_monotonic_Control *the_period
+)
+{
+ return (the_period->state == RATE_MONOTONIC_EXPIRED);
+}
+
+/*PAGE
+ *
+ * _Rate_monotonic_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_period is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Rate_monotonic_Is_null (
+ Rate_monotonic_Control *the_period
+)
+{
+ return (the_period == NULL);
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/region.inl b/cpukit/rtems/inline/rtems/rtems/region.inl
new file mode 100644
index 0000000000..412efec203
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/region.inl
@@ -0,0 +1,129 @@
+/**
+ * @file rtems/rtems/region.inl
+ */
+
+/*
+ * This file contains the macro implementation of the inlined
+ * routines from the Region Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_REGION_INL
+#define _RTEMS_RTEMS_REGION_INL
+
+/*PAGE
+ *
+ * _Region_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a region control block from
+ * the inactive chain of free region control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE Region_Control *_Region_Allocate( void )
+{
+ return (Region_Control *) _Objects_Allocate( &_Region_Information );
+}
+
+/*PAGE
+ *
+ * _Region_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a region control block to the
+ * inactive chain of free region control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Region_Free (
+ Region_Control *the_region
+)
+{
+ _Objects_Free( &_Region_Information, &the_region->Object );
+}
+
+/*PAGE
+ *
+ * _Region_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps region IDs to region control blocks.
+ * If ID corresponds to a local region, then it returns
+ * the_region control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. Otherwise, location is set
+ * to OBJECTS_ERROR and the_region is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE Region_Control *_Region_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (Region_Control *)
+ _Objects_Get_no_protection( &_Region_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _Region_Allocate_segment
+ *
+ * DESCRIPTION:
+ *
+ * This function attempts to allocate a segment from the_region.
+ * If successful, it returns the address of the allocated segment.
+ * Otherwise, it returns NULL.
+ */
+
+RTEMS_INLINE_ROUTINE void *_Region_Allocate_segment (
+ Region_Control *the_region,
+ uint32_t size
+)
+{
+ return _Heap_Allocate( &the_region->Memory, size );
+}
+
+/*PAGE
+ *
+ * _Region_Free_segment
+ *
+ * DESCRIPTION:
+ *
+ * This function frees the_segment to the_region.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Region_Free_segment (
+ Region_Control *the_region,
+ void *the_segment
+)
+{
+ return _Heap_Free( &the_region->Memory, the_segment );
+}
+
+/*PAGE
+ *
+ * _Region_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_region is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Region_Is_null (
+ Region_Control *the_region
+)
+{
+ return ( the_region == NULL );
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/sem.inl b/cpukit/rtems/inline/rtems/rtems/sem.inl
new file mode 100644
index 0000000000..fd1924017f
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/sem.inl
@@ -0,0 +1,105 @@
+/**
+ * @file rtems/rtems/sem.inl
+ */
+
+/*
+ * This file contains the static inlin implementation of the inlined
+ * routines from the Semaphore Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_SEM_INL
+#define _RTEMS_RTEMS_SEM_INL
+
+/*PAGE
+ *
+ * _Semaphore_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a semaphore control block from
+ * the inactive chain of free semaphore control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Allocate( void )
+{
+ return (Semaphore_Control *) _Objects_Allocate( &_Semaphore_Information );
+}
+
+/*PAGE
+ *
+ * _Semaphore_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a semaphore control block to the
+ * inactive chain of free semaphore control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Semaphore_Free (
+ Semaphore_Control *the_semaphore
+)
+{
+ _Objects_Free( &_Semaphore_Information, &the_semaphore->Object );
+}
+
+/*PAGE
+ *
+ * _Semaphore_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps semaphore IDs to semaphore control blocks.
+ * If ID corresponds to a local semaphore, then it returns
+ * the_semaphore control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. if the semaphore ID is global and
+ * resides on a remote node, then location is set to OBJECTS_REMOTE,
+ * and the_semaphore is undefined. Otherwise, location is set
+ * to OBJECTS_ERROR and the_semaphore is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (Semaphore_Control *)
+ _Objects_Get( &_Semaphore_Information, id, location );
+}
+
+RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Get_interrupt_disable (
+ Objects_Id id,
+ Objects_Locations *location,
+ ISR_Level *level
+)
+{
+ return (Semaphore_Control *)
+ _Objects_Get_isr_disable( &_Semaphore_Information, id, location, level );
+}
+
+/*PAGE
+ *
+ * _Semaphore_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_semaphore is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Semaphore_Is_null (
+ Semaphore_Control *the_semaphore
+)
+{
+ return ( the_semaphore == NULL );
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/status.inl b/cpukit/rtems/inline/rtems/rtems/status.inl
new file mode 100644
index 0000000000..c1e5d998cb
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/status.inl
@@ -0,0 +1,58 @@
+/**
+ * @file rtems/rtems/status.inl
+ */
+
+/*
+ * This include file contains the implementations of the inlined
+ * routines for the status package.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_STATUS_INL
+#define _RTEMS_RTEMS_STATUS_INL
+
+/*PAGE
+ *
+ * rtems_is_status_successful
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the status code is equal to RTEMS_SUCCESSFUL,
+ * and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean rtems_is_status_successful(
+ rtems_status_code code
+)
+{
+ return (code == RTEMS_SUCCESSFUL);
+}
+
+/*PAGE
+ *
+ * rtems_are_statuses_equal
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the status code1 is equal to code2,
+ * and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean rtems_are_statuses_equal(
+ rtems_status_code code1,
+ rtems_status_code code2
+)
+{
+ return (code1 == code2);
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/support.inl b/cpukit/rtems/inline/rtems/rtems/support.inl
new file mode 100644
index 0000000000..4c507b0daf
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/support.inl
@@ -0,0 +1,63 @@
+/**
+ * @file rtems/rtems/support.inl
+ */
+
+/*
+ * This include file contains the static inline implementation of all
+ * of the inlined routines specific to the RTEMS API.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_SUPPORT_INL
+#define _RTEMS_RTEMS_SUPPORT_INL
+
+/*PAGE
+ *
+ * rtems_is_name_valid
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the name is valid, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE rtems_boolean rtems_is_name_valid (
+ rtems_name name
+)
+{
+ return ( name != 0 );
+}
+
+/*PAGE
+ *
+ * rtems_name_to_characters
+ *
+ * DESCRIPTION:
+ *
+ * This function breaks the object name into the four component
+ * characters C1, C2, C3, and C4.
+ */
+
+RTEMS_INLINE_ROUTINE void rtems_name_to_characters(
+ rtems_name name,
+ char *c1,
+ char *c2,
+ char *c3,
+ char *c4
+)
+{
+ *c1 = (name >> 24) & 0xff;
+ *c2 = (name >> 16) & 0xff;
+ *c3 = (name >> 8) & 0xff;
+ *c4 = name & 0xff;
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/tasks.inl b/cpukit/rtems/inline/rtems/rtems/tasks.inl
new file mode 100644
index 0000000000..1926ade36b
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/tasks.inl
@@ -0,0 +1,92 @@
+/**
+ * @file rtems/rtems/tasks.inl
+ */
+
+/*
+ * This file contains the static inline implementation of all inlined
+ * routines in the with RTEMS Tasks Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_TASKS_INL
+#define _RTEMS_RTEMS_TASKS_INL
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a task control block from
+ * the inactive chain of free task control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE Thread_Control *_RTEMS_tasks_Allocate( void )
+{
+ return (Thread_Control *) _Objects_Allocate( &_RTEMS_tasks_Information );
+}
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a task control block to the
+ * inactive chain of free task control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _RTEMS_tasks_Free (
+ Thread_Control *the_task
+)
+{
+ _Objects_Free(
+ _Objects_Get_information( the_task->Object.id ),
+ &the_task->Object
+ );
+}
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Priority_to_Core
+ *
+ * DESCRIPTION:
+ *
+ * This function converts an RTEMS API priority into a core priority.
+ */
+
+RTEMS_INLINE_ROUTINE Priority_Control _RTEMS_tasks_Priority_to_Core(
+ rtems_task_priority priority
+)
+{
+ return (Priority_Control) priority;
+}
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Priority_is_valid
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_priority is a valid user task priority
+ * and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _RTEMS_tasks_Priority_is_valid (
+ rtems_task_priority the_priority
+)
+{
+ return ( ( the_priority >= RTEMS_MINIMUM_PRIORITY ) &&
+ ( the_priority <= RTEMS_MAXIMUM_PRIORITY ) );
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/inline/rtems/rtems/timer.inl b/cpukit/rtems/inline/rtems/rtems/timer.inl
new file mode 100644
index 0000000000..6660af6e40
--- /dev/null
+++ b/cpukit/rtems/inline/rtems/rtems/timer.inl
@@ -0,0 +1,144 @@
+/**
+ * @file rtems/rtems/timer.inl
+ */
+
+/*
+ * This file contains the static inline implementation of the inlined routines
+ * from the Timer Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_TIMER_INL
+#define _RTEMS_RTEMS_TIMER_INL
+
+/*PAGE
+ *
+ * _Timer_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a timer control block from
+ * the inactive chain of free timer control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE Timer_Control *_Timer_Allocate( void )
+{
+ return (Timer_Control *) _Objects_Allocate( &_Timer_Information );
+}
+
+/*PAGE
+ *
+ * _Timer_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a timer control block to the
+ * inactive chain of free timer control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Timer_Free (
+ Timer_Control *the_timer
+)
+{
+ _Objects_Free( &_Timer_Information, &the_timer->Object );
+}
+
+/*PAGE
+ *
+ * _Timer_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps timer IDs to timer control blocks.
+ * If ID corresponds to a local timer, then it returns
+ * the timer control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. Otherwise, location is set
+ * to OBJECTS_ERROR and the returned value is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE Timer_Control *_Timer_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (Timer_Control *)
+ _Objects_Get( &_Timer_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _Timer_Is_interval_class
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the class is that of an INTERVAL
+ * timer, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Timer_Is_interval_class (
+ Timer_Classes the_class
+)
+{
+ return (the_class == TIMER_INTERVAL) || (the_class == TIMER_INTERVAL_ON_TASK);
+}
+
+/*PAGE
+ *
+ * _Timer_Is_time_of_day_class
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the class is that of an INTERVAL
+ * timer, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Timer_Is_timer_of_day_class (
+ Timer_Classes the_class
+)
+{
+ return ( the_class == TIMER_TIME_OF_DAY );
+}
+
+/*PAGE
+ *
+ * _Timer_Is_dormant_class
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the class is that of a DORMANT
+ * timer, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Timer_Is_dormant_class (
+ Timer_Classes the_class
+)
+{
+ return ( the_class == TIMER_DORMANT );
+}
+
+/*PAGE
+ *
+ * _Timer_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_timer is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Timer_Is_null (
+ Timer_Control *the_timer
+)
+{
+ return ( the_timer == NULL );
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/asr.inl b/cpukit/rtems/macros/rtems/rtems/asr.inl
new file mode 100644
index 0000000000..fb85f6839f
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/asr.inl
@@ -0,0 +1,92 @@
+/**
+ * @file rtems/rtems/asr.inl
+ */
+
+/*
+ * This include file contains the implemenation of all routines
+ * associated with the asynchronous signal handler which are inlined.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_ASR_INL
+#define _RTEMS_RTEMS_ASR_INL
+
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _ASR_Initialize
+ *
+ */
+
+#define _ASR_Initialize( _information ) \
+{ \
+ (_information)->is_enabled = TRUE; \
+ (_information)->handler = NULL; \
+ (_information)->mode_set = RTEMS_DEFAULT_MODES; \
+ (_information)->signals_posted = 0; \
+ (_information)->signals_pending = 0; \
+ (_information)->nest_level = 0; \
+}
+
+/*PAGE
+ *
+ * _ASR_Swap_signals
+ *
+ */
+
+#define _ASR_Swap_signals( _information ) \
+{ \
+ rtems_signal_set _signals; \
+ ISR_Level _level; \
+ \
+ _ISR_Disable( _level ); \
+ _signals = (_information)->signals_pending; \
+ (_information)->signals_pending = (_information)->signals_posted; \
+ (_information)->signals_posted = _signals; \
+ _ISR_Enable( _level ); \
+}
+
+/*PAGE
+ *
+ * _ASR_Is_null_handler
+ *
+ */
+
+#define _ASR_Is_null_handler( _asr_handler ) \
+ ( (_asr_handler) == NULL )
+
+/*PAGE
+ *
+ * _ASR_Are_signals_pending
+ *
+ */
+
+#define _ASR_Are_signals_pending( _information ) \
+ ( (_information)->signals_posted != 0 )
+
+/*PAGE
+ *
+ * _ASR_Post_signals
+ *
+ */
+
+#define _ASR_Post_signals( _signals, _signal_set ) \
+ do { \
+ ISR_Level _level; \
+ \
+ _ISR_Disable( _level ); \
+ *(_signal_set) |= (_signals); \
+ _ISR_Enable( _level ); \
+ } while ( 0 )
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/attr.inl b/cpukit/rtems/macros/rtems/rtems/attr.inl
new file mode 100644
index 0000000000..7f40bbdad3
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/attr.inl
@@ -0,0 +1,122 @@
+/**
+ * @file rtems/rtems/attr.inl
+ */
+
+/*
+ * This include file contains all of the inlined routines associated
+ * with attributes.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_ATTR_INL
+#define _RTEMS_RTEMS_ATTR_INL
+
+/*PAGE
+ *
+ * _Attributes_Set
+ */
+
+#define _Attributes_Set( _new_attributes, _attribute_set ) \
+ ( (_attribute_set) | (_new_attributes) )
+
+/*PAGE
+ *
+ * _Attributes_Clear
+ */
+
+#define _Attributes_Clear( _attribute_set, _mask ) \
+ ( (_attribute_set) & ~(_mask) )
+
+/*PAGE
+ *
+ * _Attributes_Is_floating_point
+ *
+ */
+
+#define _Attributes_Is_floating_point( _attribute_set ) \
+ ( (_attribute_set) & RTEMS_FLOATING_POINT )
+
+/*PAGE
+ *
+ * _Attributes_Is_global
+ *
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#define _Attributes_Is_global( _attribute_set ) \
+ ( (_attribute_set) & RTEMS_GLOBAL )
+#endif
+
+/*PAGE
+ *
+ * _Attributes_Is_priority
+ *
+ */
+
+#define _Attributes_Is_priority( _attribute_set ) \
+ ( (_attribute_set) & RTEMS_PRIORITY )
+
+/*PAGE
+ *
+ * _Attributes_Is_binary_semaphore
+ *
+ */
+
+#define _Attributes_Is_binary_semaphore( _attribute_set ) \
+ (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_BINARY_SEMAPHORE)
+
+/*PAGE
+ *
+ * _Attributes_Is_simple_binary_semaphore
+ *
+ */
+
+#define _Attributes_Is_simple_binary_semaphore( _attribute_set ) \
+ (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_SIMPLE_BINARY_SEMAPHORE)
+
+/*PAGE
+ *
+ * _Attributes_Is_counting_semaphore
+ *
+ */
+
+#define _Attributes_Is_counting_semaphore( _attribute_set ) \
+ (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_COUNTING_SEMAPHORE)
+
+/*PAGE
+ *
+ * _Attributes_Is_inherit_priority
+ *
+ */
+
+#define _Attributes_Is_inherit_priority( _attribute_set ) \
+ ( (_attribute_set) & RTEMS_INHERIT_PRIORITY )
+
+/*PAGE
+ *
+ * _Attributes_Is_priority_ceiling
+ *
+ */
+
+#define _Attributes_Is_priority_ceiling( _attribute_set ) \
+ ( (_attribute_set) & RTEMS_PRIORITY_CEILING )
+
+/*PAGE
+ *
+ * _Attributes_Is_system_task
+ *
+ */
+
+#define _Attributes_Is_system_task( _attribute_set ) \
+ ( (_attribute_set) & RTEMS_SYSTEM_TASK )
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/dpmem.inl b/cpukit/rtems/macros/rtems/rtems/dpmem.inl
new file mode 100644
index 0000000000..87dae0aa92
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/dpmem.inl
@@ -0,0 +1,61 @@
+/**
+ * @file rtems/rtems/dpmem.inl
+ */
+
+/*
+ * This include file contains the inline routine used in conjunction
+ * with the Dual Ported Memory Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_DPMEM_INL
+#define _RTEMS_RTEMS_DPMEM_INL
+
+/*PAGE
+ *
+ * _Dual_ported_memory_Allocate
+ *
+ */
+
+#define _Dual_ported_memory_Allocate() \
+ (Dual_ported_memory_Control *) \
+ _Objects_Allocate( &_Dual_ported_memory_Information )
+
+/*PAGE
+ *
+ * _Dual_ported_memory_Free
+ *
+ */
+
+#define _Dual_ported_memory_Free( _the_port ) \
+ _Objects_Free( &_Dual_ported_memory_Information, &(_the_port)->Object )
+
+/*PAGE
+ *
+ * _Dual_ported_memory_Get
+ *
+ */
+
+#define _Dual_ported_memory_Get( _id, _location ) \
+ (Dual_ported_memory_Control *) \
+ _Objects_Get( &_Dual_ported_memory_Information, (_id), (_location) )
+
+
+/*PAGE
+ *
+ * _Dual_ported_memory_Is_null
+ */
+
+#define _Dual_ported_memory_Is_null( _the_port ) \
+ ( (_the_port) == NULL )
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/event.inl b/cpukit/rtems/macros/rtems/rtems/event.inl
new file mode 100644
index 0000000000..c4ad5ccc98
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/event.inl
@@ -0,0 +1,23 @@
+/**
+ * @file rtems/rtems/event.inl
+ */
+
+/*
+ * This include file contains the implementation of macros for
+ * the Event Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_EVENT_INL
+#define _RTEMS_RTEMS_EVENT_INL
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/eventset.inl b/cpukit/rtems/macros/rtems/rtems/eventset.inl
new file mode 100644
index 0000000000..3ffa637254
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/eventset.inl
@@ -0,0 +1,61 @@
+/**
+ * @file rtems/rtems/eventset.inl
+ */
+
+/*
+ * This include file contains the macro implementation of inlined
+ * routines in the event set object.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_EVENTSET_INL
+#define _RTEMS_RTEMS_EVENTSET_INL
+
+/*PAGE
+ *
+ * _Event_sets_Is_empty
+ */
+
+#define _Event_sets_Is_empty( _the_event_set ) \
+ ((_the_event_set) == 0 )
+
+/*PAGE
+ *
+ * _Event_sets_Is_empty
+ */
+
+#define _Event_sets_Post( _the_new_events, _the_event_set ) \
+ do { \
+ ISR_Level level; \
+ \
+ _ISR_Disable( level ); \
+ *(_the_event_set) |= (_the_new_events); \
+ _ISR_Enable( level ); \
+ } while (0);
+
+/*PAGE
+ *
+ * _Event_sets_Is_empty
+ */
+
+#define _Event_sets_Get( _the_event_set, _the_event_condition ) \
+ ((_the_event_set) & (_the_event_condition))
+
+/*PAGE
+ *
+ * _Event_sets_Clear
+ */
+
+#define _Event_sets_Clear( _the_event_set, _the_mask ) \
+ ((_the_event_set) & ~(_the_mask))
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/message.inl b/cpukit/rtems/macros/rtems/rtems/message.inl
new file mode 100644
index 0000000000..debb583277
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/message.inl
@@ -0,0 +1,51 @@
+/**
+ * @file rtems/rtems/message.inl
+ */
+
+/*
+ * This include file contains the macro implementation of all
+ * inlined routines in the Message Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_MESSAGE_INL
+#define _RTEMS_RTEMS_MESSAGE_INL
+
+/*PAGE
+ *
+ * _Message_queue_Is_null
+ *
+ */
+
+#define _Message_queue_Is_null( _the_message_queue ) \
+ ( (_the_message_queue) == NULL )
+
+/*PAGE
+ *
+ * _Message_queue_Free
+ *
+ */
+
+#define _Message_queue_Free( _the_message_queue ) \
+ _Objects_Free( &_Message_queue_Information, &(_the_message_queue)->Object )
+
+/*PAGE
+ *
+ * _Message_queue_Get
+ *
+ */
+
+#define _Message_queue_Get( _id, _location ) \
+ (Message_queue_Control *) \
+ _Objects_Get( &_Message_queue_Information, (_id), (_location) )
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/modes.inl b/cpukit/rtems/macros/rtems/rtems/modes.inl
new file mode 100644
index 0000000000..64a4fb3679
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/modes.inl
@@ -0,0 +1,94 @@
+/**
+ * @file rtems/rtems/modes.inl
+ */
+
+/*
+ * This include file contains the macro implementation of the
+ * inlined routines in the Mode Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_MODES_INL
+#define _RTEMS_RTEMS_MODES_INL
+
+/*PAGE
+ *
+ * _Modes_Mask_changed
+ *
+ */
+
+#define _Modes_Mask_changed( _mode_set, _masks ) \
+ ( (_mode_set) & (_masks) )
+
+/*PAGE
+ *
+ * _Modes_Is_asr_disabled
+ *
+ */
+
+#define _Modes_Is_asr_disabled( _mode_set ) \
+ (((_mode_set) & RTEMS_ASR_MASK) == RTEMS_NO_ASR)
+
+/*PAGE
+ *
+ * _Modes_Is_preempt
+ *
+ */
+
+#define _Modes_Is_preempt( _mode_set ) \
+ ( ( (_mode_set) & RTEMS_PREEMPT_MASK ) == RTEMS_PREEMPT )
+
+/*PAGE
+ *
+ * _Modes_Is_timeslice
+ *
+ */
+
+#define _Modes_Is_timeslice( _mode_set ) \
+ (((_mode_set) & RTEMS_TIMESLICE_MASK) == RTEMS_TIMESLICE)
+
+/*PAGE
+ *
+ * _Modes_Get_interrupt_level
+ *
+ */
+
+#define _Modes_Get_interrupt_level( _mode_set ) \
+ ( (_mode_set) & RTEMS_INTERRUPT_MASK )
+
+/*PAGE
+ *
+ * _Modes_Set_interrupt_level
+ *
+ */
+
+#define _Modes_Set_interrupt_level( _mode_set ) \
+ _ISR_Set_level( _Modes_Get_interrupt_level( (_mode_set) ) )
+
+/*PAGE
+ *
+ * _Modes_Change
+ *
+ */
+
+#define _Modes_Change( _old_mode_set, _new_mode_set, \
+ _mask, _out_mode_set, _changed ) \
+ { Modes_Control _out_mode; \
+ \
+ _out_mode = (_old_mode_set); \
+ _out_mode &= ~(_mask); \
+ _out_mode |= (_new_mode_set) & (_mask); \
+ *(_changed) = _out_mode ^ (_old_mode_set); \
+ *(_out_mode_set) = _out_mode; \
+ }
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/options.inl b/cpukit/rtems/macros/rtems/rtems/options.inl
new file mode 100644
index 0000000000..e1a53b233d
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/options.inl
@@ -0,0 +1,41 @@
+/**
+ * @file rtems/rtems/options.inl
+ */
+
+/*
+ * This file contains the macro implementation of the inlined
+ * routines from the Options Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_OPTIONS_INL
+#define _RTEMS_RTEMS_OPTIONS_INL
+
+/*PAGE
+ *
+ * _Options_Is_no_wait
+ *
+ */
+
+#define _Options_Is_no_wait( _option_set ) \
+ ( (_option_set) & RTEMS_NO_WAIT )
+
+/*PAGE
+ *
+ * _Options_Is_any
+ *
+ */
+
+#define _Options_Is_any( _option_set ) \
+ ( (_option_set) & RTEMS_EVENT_ANY )
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/part.inl b/cpukit/rtems/macros/rtems/rtems/part.inl
new file mode 100644
index 0000000000..c68683a5c0
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/part.inl
@@ -0,0 +1,119 @@
+/**
+ * @file rtems/rtems/part.inl
+ */
+
+/*
+ * This file contains the macro implementation of all inlined routines
+ * in the Partition Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_PART_INL
+#define _RTEMS_RTEMS_PART_INL
+
+/*PAGE
+ *
+ * _Partition_Allocate_buffer
+ *
+ */
+
+#define _Partition_Allocate_buffer( _the_partition ) \
+ _Chain_Get( &(_the_partition)->Memory )
+
+/*PAGE
+ *
+ * _Partition_Free_buffer
+ *
+ */
+
+#define _Partition_Free_buffer( _the_partition, _the_buffer ) \
+ _Chain_Append( &(_the_partition)->Memory, (_the_buffer) )
+
+/*PAGE
+ *
+ * _Partition_Is_buffer_on_boundary
+ *
+ */
+
+#define _Partition_Is_buffer_on_boundary( _the_buffer, _the_partition ) \
+ ((((uint32_t ) _Addresses_Subtract( \
+ (_the_buffer), \
+ (_the_partition)->starting_address ) \
+ ) % \
+ (_the_partition)->buffer_size) == 0)
+
+/*PAGE
+ *
+ * _Partition_Is_buffer_valid
+ *
+ */
+
+#define _Partition_Is_buffer_valid( _the_buffer, _the_partition ) \
+ ( \
+ _Addresses_Is_in_range( \
+ (_the_buffer), \
+ (_the_partition)->starting_address, \
+ _Addresses_Add_offset( \
+ (_the_partition)->starting_address, \
+ (_the_partition)->length \
+ ) \
+ ) && \
+ _Partition_Is_buffer_on_boundary( (_the_buffer), (_the_partition) ) \
+ )
+
+/*PAGE
+ *
+ * _Partition_Is_buffer_size_aligned
+ *
+ */
+
+#define _Partition_Is_buffer_size_aligned( _buffer_size ) \
+ ((_buffer_size) % CPU_PARTITION_ALIGNMENT == 0)
+
+/*PAGE
+ *
+ * _Partition_Allocate
+ *
+ */
+
+#define _Partition_Allocate() \
+ (Partition_Control *) _Objects_Allocate( &_Partition_Information )
+
+/*PAGE
+ *
+ * _Partition_Free
+ *
+ */
+
+#define _Partition_Free( _the_partition ) \
+ _Objects_Free( &_Partition_Information, &(_the_partition)->Object )
+
+/*PAGE
+ *
+ * _Partition_Get
+ *
+ */
+
+#define _Partition_Get( _id, _location ) \
+ (Partition_Control *) \
+ _Objects_Get( &_Partition_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _Partition_Is_null
+ *
+ */
+
+#define _Partition_Is_null( _the_partition ) \
+ ( (_the_partition) == NULL )
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/ratemon.inl b/cpukit/rtems/macros/rtems/rtems/ratemon.inl
new file mode 100644
index 0000000000..a98e12954b
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/ratemon.inl
@@ -0,0 +1,87 @@
+/**
+ * @file rtems/rtems/ratemon.inl
+ */
+
+/*
+ * This file contains the macro implementation of the inlined
+ * routines in the Rate Monotonic Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_RATEMON_INL
+#define _RTEMS_RTEMS_RATEMON_INL
+
+/*PAGE
+ *
+ * _Rate_monotonic_Allocate
+ *
+ */
+
+#define _Rate_monotonic_Allocate() \
+ (Rate_monotonic_Control *) \
+ _Objects_Allocate( &_Rate_monotonic_Information )
+
+/*PAGE
+ *
+ * _Rate_monotonic_Free
+ *
+ */
+
+#define _Rate_monotonic_Free( _the_period ) \
+ _Objects_Free( &_Rate_monotonic_Information, &(_the_period)->Object )
+
+/*PAGE
+ *
+ * _Rate_monotonic_Get
+ *
+ */
+
+#define _Rate_monotonic_Get( _id, _location ) \
+ (Rate_monotonic_Control *) \
+ _Objects_Get( &_Rate_monotonic_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _Rate_monotonic_Is_active
+ *
+ */
+
+#define _Rate_monotonic_Is_active( _the_period ) \
+ ((_the_period)->state == RATE_MONOTONIC_ACTIVE)
+
+/*PAGE
+ *
+ * _Rate_monotonic_Is_inactive
+ *
+ */
+
+#define _Rate_monotonic_Is_inactive( _the_period ) \
+ ((_the_period)->state == RATE_MONOTONIC_INACTIVE)
+
+/*PAGE
+ *
+ * _Rate_monotonic_Is_expired
+ *
+ */
+
+#define _Rate_monotonic_Is_expired( _the_period ) \
+ ((_the_period)->state == RATE_MONOTONIC_EXPIRED)
+
+/*PAGE
+ *
+ * _Rate_monotonic_Is_null
+ *
+ */
+
+#define _Rate_monotonic_Is_null( _the_period ) ( (_the_period) == NULL )
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/region.inl b/cpukit/rtems/macros/rtems/rtems/region.inl
new file mode 100644
index 0000000000..92f7549830
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/region.inl
@@ -0,0 +1,77 @@
+/**
+ * @file rtems/rtems/region.inl
+ */
+
+/*
+ * This file contains the macro implementation of the inlined
+ * routines from the Region Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_REGION_INL
+#define _RTEMS_RTEMS_REGION_INL
+
+/*PAGE
+ *
+ * _Region_Allocate
+ *
+ */
+
+#define _Region_Allocate() \
+ (Region_Control *) _Objects_Allocate( &_Region_Information )
+
+/*PAGE
+ *
+ * _Region_Free
+ *
+ */
+
+#define _Region_Free( _the_region ) \
+ _Objects_Free( &_Region_Information, &(_the_region)->Object )
+
+/*PAGE
+ *
+ * _Region_Get
+ *
+ */
+
+#define _Region_Get( _id, _location ) \
+ (Region_Control *) \
+ _Objects_Get_no_protection( &_Region_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _Region_Allocate_segment
+ *
+ */
+
+#define _Region_Allocate_segment( _the_region, _size ) \
+ _Heap_Allocate( &(_the_region)->Memory, (_size) )
+
+/*PAGE
+ *
+ * _Region_Free_segment
+ *
+ */
+
+#define _Region_Free_segment( _the_region, _the_segment ) \
+ _Heap_Free( &(_the_region)->Memory, (_the_segment) )
+
+/*PAGE
+ *
+ * _Region_Is_null
+ *
+ */
+
+#define _Region_Is_null( _the_region ) ( (_the_region) == NULL )
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/sem.inl b/cpukit/rtems/macros/rtems/rtems/sem.inl
new file mode 100644
index 0000000000..c7341c68f3
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/sem.inl
@@ -0,0 +1,65 @@
+/**
+ * @file rtems/rtems/sem.inl
+ */
+
+/*
+ * This file contains the macro implementation of the inlined
+ * routines from the Semaphore Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_SEM_INL
+#define _RTEMS_RTEMS_SEM_INL
+
+/*PAGE
+ *
+ * _Semaphore_Allocate
+ *
+ */
+
+#define _Semaphore_Allocate() \
+ (Semaphore_Control *) _Objects_Allocate( &_Semaphore_Information )
+
+/*PAGE
+ *
+ * _Semaphore_Free
+ *
+ */
+
+#define _Semaphore_Free( _the_semaphore ) \
+ _Objects_Free( &_Semaphore_Information, &(_the_semaphore)->Object )
+
+/*PAGE
+ *
+ * _Semaphore_Get
+ *
+ */
+
+#define _Semaphore_Get( _id, _location ) \
+ (Semaphore_Control *) \
+ _Objects_Get( &_Semaphore_Information, (_id), (_location) )
+
+#define _Semaphore_Get_interrupt_disable( _id, _location, _level ) \
+ (Semaphore_Control *) \
+ _Objects_Get_isr_disable( \
+ &_Semaphore_Information, (_id), (_location), (_level) )
+
+/*PAGE
+ *
+ * _Semaphore_Is_null
+ *
+ */
+
+#define _Semaphore_Is_null( _the_semaphore ) \
+ ( (_the_semaphore) == NULL )
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/status.inl b/cpukit/rtems/macros/rtems/rtems/status.inl
new file mode 100644
index 0000000000..dc7a949e35
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/status.inl
@@ -0,0 +1,41 @@
+/**
+ * @file rtems/rtems/status.inl
+ */
+
+/*
+ * This include file contains the implementations of the inlined
+ * routines for the status package.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_STATUS_INL
+#define _RTEMS_RTEMS_STATUS_INL
+
+/*PAGE
+ *
+ * rtems_is_status_successful
+ *
+ */
+
+#define rtems_is_status_successful( _code ) \
+ ( (_code) == RTEMS_SUCCESSFUL )
+
+/*PAGE
+ *
+ * rtems_are_statuses_equal
+ *
+ */
+
+#define rtems_are_statuses_equal( _code1, _code2 ) \
+ ((_code1) == (_code2))
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/support.inl b/cpukit/rtems/macros/rtems/rtems/support.inl
new file mode 100644
index 0000000000..53a3dd01cf
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/support.inl
@@ -0,0 +1,46 @@
+/**
+ * @file rtems/rtems/support.inl
+ */
+
+/*
+ * This include file contains the macros implementation of all
+ * of the inlined routines specific to the RTEMS API.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_SUPPORT_INL
+#define _RTEMS_RTEMS_SUPPORT_INL
+
+/*PAGE
+ *
+ * rtems_is_name_valid
+ *
+ */
+
+#define rtems_is_name_valid( _name ) \
+ ( (_name) != 0 )
+
+/*PAGE
+ *
+ * rtems_name_to_characters
+ *
+ */
+
+#define rtems_name_to_characters( _name, _c1, _c2, _c3, _c4 ) \
+ { \
+ (*(_c1) = ((_name) >> 24) & 0xff; \
+ (*(_c2) = ((_name) >> 16) & 0xff; \
+ (*(_c3) = ((_name) >> 8) & 0xff; \
+ (*(_c4) = ((_name)) & 0xff; \
+ }
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/tasks.inl b/cpukit/rtems/macros/rtems/rtems/tasks.inl
new file mode 100644
index 0000000000..0b5853a7bb
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/tasks.inl
@@ -0,0 +1,60 @@
+/**
+ * @file rtems/rtems/tasks.inl
+ */
+
+/*
+ * This file contains the macro implementation of all inlined
+ * routines in the with RTEMS Tasks Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_TASKS_INL
+#define _RTEMS_RTEMS_TASKS_INL
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Allocate
+ *
+ */
+
+#define _RTEMS_tasks_Allocate() \
+ (Thread_Control *) _Objects_Allocate( &_RTEMS_tasks_Information )
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Free
+ *
+ */
+
+#define _RTEMS_tasks_Free( _the_task ) \
+ _Objects_Free( &_RTEMS_tasks_Information, &(_the_task)->Object )
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Priority_to_Core
+ */
+
+#define _RTEMS_tasks_Priority_to_Core( _priority ) \
+ ((Priority_Control) (_priority))
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Priority_is_valid
+ *
+ */
+
+#define _RTEMS_tasks_Priority_is_valid( _the_priority ) \
+ ( ((_the_priority) >= RTEMS_MINIMUM_PRIORITY) && \
+ ((_the_priority) <= RTEMS_MAXIMUM_PRIORITY) )
+
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/macros/rtems/rtems/timer.inl b/cpukit/rtems/macros/rtems/rtems/timer.inl
new file mode 100644
index 0000000000..f29ef186ca
--- /dev/null
+++ b/cpukit/rtems/macros/rtems/rtems/timer.inl
@@ -0,0 +1,88 @@
+/**
+ * @file rtems/rtems/timer.inl
+ */
+
+/*
+ * This file contains the macro implementation of the inlined routines
+ * from the Timer Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_RTEMS_TIMER_INL
+#define _RTEMS_RTEMS_TIMER_INL
+
+/*PAGE
+ *
+ * _Timer_Allocate
+ *
+ */
+
+#define _Timer_Allocate() \
+ (Timer_Control *) _Objects_Allocate( &_Timer_Information )
+
+/*PAGE
+ *
+ * _Timer_Free
+ *
+ */
+
+#define _Timer_Free( _the_timer ) \
+ _Objects_Free( &_Timer_Information, &(_the_timer)->Object )
+
+/*PAGE
+ *
+ * _Timer_Get
+ *
+ */
+
+#define _Timer_Get( _id, _location ) \
+ (Timer_Control *) \
+ _Objects_Get( &_Timer_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _Timer_Is_interval_class
+ *
+ */
+
+#define _Timer_Is_interval_class( _the_class ) \
+ ( ((_the_class) == TIMER_INTERVAL) || \
+ ((_the_class) == TIMER_INTERVAL_ON_TASK) )
+
+/*PAGE
+ *
+ * _Timer_Is_time_of_day_class
+ *
+ */
+
+#define _Timer_Is_time_of_day_class( _the_class ) \
+ ( (_the_class) == TIMER_TIME_OF_DAY )
+
+/*PAGE
+ *
+ * _Timer_Is_dormant_class
+ *
+ */
+
+#define _Timer_Is_dormant_class( _the_class ) \
+ ( (_the_class) == TIMER_DORMANT )
+
+/*PAGE
+ *
+ * _Timer_Is_null
+ *
+ */
+
+#define _Timer_Is_null( _the_timer ) \
+ ( (_the_timer) == NULL )
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/preinstall.am b/cpukit/rtems/preinstall.am
new file mode 100644
index 0000000000..135e37b020
--- /dev/null
+++ b/cpukit/rtems/preinstall.am
@@ -0,0 +1,284 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)
+ @: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems.h: include/rtems.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/rtems/asr.h: include/rtems/rtems/asr.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/asr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/asr.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/attr.h: include/rtems/rtems/attr.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/attr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/attr.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/cache.h: include/rtems/rtems/cache.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/cache.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/cache.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/clock.h: include/rtems/rtems/clock.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/clock.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/clock.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/config.h: include/rtems/rtems/config.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/config.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/config.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/dpmem.h: include/rtems/rtems/dpmem.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/dpmem.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/dpmem.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/event.h: include/rtems/rtems/event.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/event.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/event.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/eventset.h: include/rtems/rtems/eventset.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/eventset.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/eventset.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/intr.h: include/rtems/rtems/intr.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/intr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/intr.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/message.h: include/rtems/rtems/message.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/message.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/message.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/modes.h: include/rtems/rtems/modes.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/modes.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/modes.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/options.h: include/rtems/rtems/options.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/options.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/options.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/part.h: include/rtems/rtems/part.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/part.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/part.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/ratemon.h: include/rtems/rtems/ratemon.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/ratemon.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/ratemon.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/region.h: include/rtems/rtems/region.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/region.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/region.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/rtemsapi.h: include/rtems/rtems/rtemsapi.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/rtemsapi.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/rtemsapi.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/sem.h: include/rtems/rtems/sem.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/sem.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/sem.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/signal.h: include/rtems/rtems/signal.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/signal.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/signal.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/status.h: include/rtems/rtems/status.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/status.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/status.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/support.h: include/rtems/rtems/support.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/support.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/support.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/tasks.h: include/rtems/rtems/tasks.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/tasks.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/tasks.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/timer.h: include/rtems/rtems/timer.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/timer.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/timer.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/types.h: include/rtems/rtems/types.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/types.h
+
+if HAS_MP
+$(PROJECT_INCLUDE)/rtems/rtems/eventmp.h: include/rtems/rtems/eventmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/eventmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/eventmp.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/mp.h: include/rtems/rtems/mp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/mp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/mp.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/msgmp.h: include/rtems/rtems/msgmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/msgmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/msgmp.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/partmp.h: include/rtems/rtems/partmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/partmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/partmp.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/regionmp.h: include/rtems/rtems/regionmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/regionmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/regionmp.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/semmp.h: include/rtems/rtems/semmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/semmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/semmp.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/signalmp.h: include/rtems/rtems/signalmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/signalmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/signalmp.h
+
+$(PROJECT_INCLUDE)/rtems/rtems/taskmp.h: include/rtems/rtems/taskmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/taskmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/taskmp.h
+endif
+if INLINE
+$(PROJECT_INCLUDE)/rtems/rtems/asr.inl: inline/rtems/rtems/asr.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/asr.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/asr.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/attr.inl: inline/rtems/rtems/attr.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/attr.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/attr.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/dpmem.inl: inline/rtems/rtems/dpmem.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/dpmem.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/dpmem.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/event.inl: inline/rtems/rtems/event.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/event.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/event.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/eventset.inl: inline/rtems/rtems/eventset.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/eventset.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/eventset.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/message.inl: inline/rtems/rtems/message.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/message.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/message.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/modes.inl: inline/rtems/rtems/modes.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/modes.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/modes.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/options.inl: inline/rtems/rtems/options.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/options.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/options.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/part.inl: inline/rtems/rtems/part.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/part.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/part.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/ratemon.inl: inline/rtems/rtems/ratemon.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/ratemon.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/ratemon.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/region.inl: inline/rtems/rtems/region.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/region.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/region.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/sem.inl: inline/rtems/rtems/sem.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/sem.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/sem.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/status.inl: inline/rtems/rtems/status.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/status.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/status.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/support.inl: inline/rtems/rtems/support.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/support.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/support.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/tasks.inl: inline/rtems/rtems/tasks.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/tasks.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/tasks.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/timer.inl: inline/rtems/rtems/timer.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/timer.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/timer.inl
+
+else
+$(PROJECT_INCLUDE)/rtems/rtems/asr.inl: macros/rtems/rtems/asr.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/asr.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/asr.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/attr.inl: macros/rtems/rtems/attr.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/attr.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/attr.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/dpmem.inl: macros/rtems/rtems/dpmem.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/dpmem.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/dpmem.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/event.inl: macros/rtems/rtems/event.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/event.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/event.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/eventset.inl: macros/rtems/rtems/eventset.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/eventset.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/eventset.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/message.inl: macros/rtems/rtems/message.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/message.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/message.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/modes.inl: macros/rtems/rtems/modes.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/modes.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/modes.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/options.inl: macros/rtems/rtems/options.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/options.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/options.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/part.inl: macros/rtems/rtems/part.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/part.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/part.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/ratemon.inl: macros/rtems/rtems/ratemon.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/ratemon.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/ratemon.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/region.inl: macros/rtems/rtems/region.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/region.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/region.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/sem.inl: macros/rtems/rtems/sem.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/sem.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/sem.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/status.inl: macros/rtems/rtems/status.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/status.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/status.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/support.inl: macros/rtems/rtems/support.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/support.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/support.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/tasks.inl: macros/rtems/rtems/tasks.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/tasks.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/tasks.inl
+
+$(PROJECT_INCLUDE)/rtems/rtems/timer.inl: macros/rtems/rtems/timer.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/timer.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/timer.inl
+endif
diff --git a/cpukit/rtems/src/attr.c b/cpukit/rtems/src/attr.c
new file mode 100644
index 0000000000..8b0b542441
--- /dev/null
+++ b/cpukit/rtems/src/attr.c
@@ -0,0 +1,32 @@
+/*
+ * Body for Attribute Routines
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/stack.h>
+#include <rtems/rtems/modes.h>
+
+uint32_t rtems_minimum_stack_size = STACK_MINIMUM_SIZE;
+uint32_t rtems_interrupt_mask = RTEMS_INTERRUPT_MASK;
+
+rtems_attribute rtems_interrupt_level_attribute(
+ uint32_t level
+)
+{
+ return RTEMS_INTERRUPT_LEVEL(level);
+}
diff --git a/cpukit/rtems/src/clockget.c b/cpukit/rtems/src/clockget.c
new file mode 100644
index 0000000000..d8f808ce8e
--- /dev/null
+++ b/cpukit/rtems/src/clockget.c
@@ -0,0 +1,96 @@
+/*
+ * Clock Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/clock.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_clock_get
+ *
+ * This directive returns the current date and time. If the time has
+ * not been set by a tm_set then an error is returned.
+ *
+ * Input parameters:
+ * option - which value to return
+ * time_buffer - pointer to output buffer (a time and date structure
+ * or an interval)
+ *
+ * Output parameters:
+ * time_buffer - output filled in
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_clock_get(
+ rtems_clock_get_options option,
+ void *time_buffer
+)
+{
+ ISR_Level level;
+ rtems_interval tmp;
+
+ if ( !time_buffer )
+ return RTEMS_INVALID_ADDRESS;
+
+ switch ( option ) {
+ case RTEMS_CLOCK_GET_TOD:
+ if ( !_TOD_Is_set )
+ return RTEMS_NOT_DEFINED;
+
+ *(rtems_time_of_day *)time_buffer = _TOD_Current;
+ return RTEMS_SUCCESSFUL;
+
+ case RTEMS_CLOCK_GET_SECONDS_SINCE_EPOCH:
+ if ( !_TOD_Is_set )
+ return RTEMS_NOT_DEFINED;
+
+ *(rtems_interval *)time_buffer = _TOD_Seconds_since_epoch;
+ return RTEMS_SUCCESSFUL;
+
+ case RTEMS_CLOCK_GET_TICKS_SINCE_BOOT:
+ *(rtems_interval *)time_buffer = _Watchdog_Ticks_since_boot;
+ return RTEMS_SUCCESSFUL;
+
+ case RTEMS_CLOCK_GET_TICKS_PER_SECOND:
+ *(rtems_interval *)time_buffer = _TOD_Ticks_per_second;
+ return RTEMS_SUCCESSFUL;
+
+ case RTEMS_CLOCK_GET_TIME_VALUE:
+ if ( !_TOD_Is_set )
+ return RTEMS_NOT_DEFINED;
+
+ _ISR_Disable( level );
+ ((rtems_clock_time_value *)time_buffer)->seconds =
+ _TOD_Seconds_since_epoch;
+ tmp = _TOD_Current.ticks;
+ _ISR_Enable( level );
+
+ tmp *= _TOD_Microseconds_per_tick;
+ ((rtems_clock_time_value *)time_buffer)->microseconds = tmp;
+
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* should never get here */
+
+}
diff --git a/cpukit/rtems/src/clockset.c b/cpukit/rtems/src/clockset.c
new file mode 100644
index 0000000000..befdc5339b
--- /dev/null
+++ b/cpukit/rtems/src/clockset.c
@@ -0,0 +1,57 @@
+/*
+ * Clock Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/clock.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_clock_set
+ *
+ * This directive sets the date and time for this node.
+ *
+ * Input parameters:
+ * time_buffer - pointer to the time and date structure
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_clock_set(
+ rtems_time_of_day *time_buffer
+)
+{
+ rtems_interval seconds;
+
+ if ( !time_buffer )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( _TOD_Validate( time_buffer ) ) {
+ seconds = _TOD_To_seconds( time_buffer );
+ _Thread_Disable_dispatch();
+ _TOD_Set( time_buffer, seconds );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ return RTEMS_INVALID_CLOCK;
+}
diff --git a/cpukit/rtems/src/clocktick.c b/cpukit/rtems/src/clocktick.c
new file mode 100644
index 0000000000..f02f48fb45
--- /dev/null
+++ b/cpukit/rtems/src/clocktick.c
@@ -0,0 +1,55 @@
+/*
+ * Clock Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/clock.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_clock_tick
+ *
+ * This directive notifies the executve that a tick has occurred.
+ * When the tick occurs the time manager updates and maintains
+ * the calendar time, timeslicing, and any timeout delays.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - always succeeds
+ *
+ * NOTE: This routine only works for leap-years through 2099.
+ */
+
+rtems_status_code rtems_clock_tick( void )
+{
+ _TOD_Tickle_ticks();
+
+ _Watchdog_Tickle_ticks();
+
+ _Thread_Tickle_timeslice();
+
+ if ( _Thread_Is_context_switch_necessary() &&
+ _Thread_Is_dispatching_enabled() )
+ _Thread_Dispatch();
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/clocktodtoseconds.c b/cpukit/rtems/src/clocktodtoseconds.c
new file mode 100644
index 0000000000..5bea09cc25
--- /dev/null
+++ b/cpukit/rtems/src/clocktodtoseconds.c
@@ -0,0 +1,67 @@
+/*
+ * Time of Day (TOD) Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _TOD_To_seconds
+ *
+ * This routine returns the seconds from the epoch until the
+ * current date and time.
+ *
+ * Input parameters:
+ * the_tod - pointer to the time and date structure
+ *
+ * Output parameters:
+ * returns - seconds since epoch until the_tod
+ */
+
+uint32_t _TOD_To_seconds(
+ TOD_Control *the_tod
+)
+{
+ uint32_t time;
+ uint32_t year_mod_4;
+
+ time = the_tod->day - 1;
+ year_mod_4 = the_tod->year & 3;
+
+ if ( year_mod_4 == 0 )
+ time += _TOD_Days_to_date[ 1 ][ the_tod->month ];
+ else
+ time += _TOD_Days_to_date[ 0 ][ the_tod->month ];
+
+ time += ( (the_tod->year - TOD_BASE_YEAR) / 4 ) *
+ ( (TOD_DAYS_PER_YEAR * 4) + 1);
+
+ time += _TOD_Days_since_last_leap_year[ year_mod_4 ];
+
+ time *= TOD_SECONDS_PER_DAY;
+
+ time += ((the_tod->hour * TOD_MINUTES_PER_HOUR) + the_tod->minute)
+ * TOD_SECONDS_PER_MINUTE;
+
+ time += the_tod->second;
+
+ return( time );
+}
diff --git a/cpukit/rtems/src/clocktodvalidate.c b/cpukit/rtems/src/clocktodvalidate.c
new file mode 100644
index 0000000000..6db0c9eb67
--- /dev/null
+++ b/cpukit/rtems/src/clocktodvalidate.c
@@ -0,0 +1,67 @@
+/*
+ * Time of Day (TOD) Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _TOD_Validate
+ *
+ * This kernel routine checks the validity of a date and time structure.
+ *
+ * Input parameters:
+ * the_tod - pointer to a time and date structure
+ *
+ * Output parameters:
+ * TRUE - if the date, time, and tick are valid
+ * FALSE - if the the_tod is invalid
+ *
+ * NOTE: This routine only works for leap-years through 2099.
+ */
+
+boolean _TOD_Validate(
+ TOD_Control *the_tod
+)
+{
+ uint32_t days_in_month;
+
+ if ((!the_tod) ||
+ (the_tod->ticks >= _TOD_Ticks_per_second) ||
+ (the_tod->second >= TOD_SECONDS_PER_MINUTE) ||
+ (the_tod->minute >= TOD_MINUTES_PER_HOUR) ||
+ (the_tod->hour >= TOD_HOURS_PER_DAY) ||
+ (the_tod->month == 0) ||
+ (the_tod->month > TOD_MONTHS_PER_YEAR) ||
+ (the_tod->year < TOD_BASE_YEAR) ||
+ (the_tod->day == 0) )
+ return FALSE;
+
+ if ( (the_tod->year % 4) == 0 )
+ days_in_month = _TOD_Days_per_month[ 1 ][ the_tod->month ];
+ else
+ days_in_month = _TOD_Days_per_month[ 0 ][ the_tod->month ];
+
+ if ( the_tod->day > days_in_month )
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/cpukit/rtems/src/dpmem.c b/cpukit/rtems/src/dpmem.c
new file mode 100644
index 0000000000..27ded43f5f
--- /dev/null
+++ b/cpukit/rtems/src/dpmem.c
@@ -0,0 +1,59 @@
+/*
+ * Dual Port Memory Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/rtems/dpmem.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/dpmem.h>
+
+/*PAGE
+ *
+ * _Dual_ported_memory_Manager_initialization
+ *
+ * This routine initializes all dual-ported memory manager related
+ * data structures.
+ *
+ * Input parameters:
+ * maximum_ports - number of ports to initialize
+ *
+ * Output parameters: NONE
+ */
+
+void _Dual_ported_memory_Manager_initialization(
+ uint32_t maximum_ports
+)
+{
+ _Objects_Initialize_information(
+ &_Dual_ported_memory_Information, /* object information table */
+ OBJECTS_CLASSIC_API, /* object API */
+ OBJECTS_RTEMS_PORTS, /* object class */
+ maximum_ports, /* maximum objects of this class */
+ sizeof( Dual_ported_memory_Control ),
+ /* size of this object's control block */
+ FALSE, /* TRUE if names of this object are strings */
+ RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+}
diff --git a/cpukit/rtems/src/dpmemcreate.c b/cpukit/rtems/src/dpmemcreate.c
new file mode 100644
index 0000000000..37afc59e87
--- /dev/null
+++ b/cpukit/rtems/src/dpmemcreate.c
@@ -0,0 +1,88 @@
+/*
+ * Dual Port Memory Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/rtems/dpmem.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/dpmem.h>
+
+/*PAGE
+ *
+ * rtems_port_create
+ *
+ * This directive creates a port into a dual-ported memory area.
+ *
+ * Input parameters:
+ * name - user defined port name
+ * internal_start - internal start address of port
+ * external_start - external start address of port
+ * length - physical length in bytes
+ * id - address of port id to set
+ *
+ * Output parameters:
+ * id - port id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_port_create(
+ rtems_name name,
+ void *internal_start,
+ void *external_start,
+ uint32_t length,
+ Objects_Id *id
+)
+{
+ register Dual_ported_memory_Control *the_port;
+
+ if ( !rtems_is_name_valid( name) )
+ return RTEMS_INVALID_NAME;
+
+ if ( !id )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( !_Addresses_Is_aligned( internal_start ) ||
+ !_Addresses_Is_aligned( external_start ) )
+ return RTEMS_INVALID_ADDRESS;
+
+ _Thread_Disable_dispatch(); /* to prevent deletion */
+
+ the_port = _Dual_ported_memory_Allocate();
+
+ if ( !the_port ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+
+ the_port->internal_base = internal_start;
+ the_port->external_base = external_start;
+ the_port->length = length - 1;
+
+ _Objects_Open(
+ &_Dual_ported_memory_Information,
+ &the_port->Object,
+ (Objects_Name) name
+ );
+
+ *id = the_port->Object.id;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/dpmemdelete.c b/cpukit/rtems/src/dpmemdelete.c
new file mode 100644
index 0000000000..b2cf5015bd
--- /dev/null
+++ b/cpukit/rtems/src/dpmemdelete.c
@@ -0,0 +1,65 @@
+/*
+ * Dual Port Memory Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/rtems/dpmem.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/dpmem.h>
+
+/*PAGE
+ *
+ * rtems_port_delete
+ *
+ * This directive allows a thread to delete a dual-ported memory area
+ * specified by the dual-ported memory identifier.
+ *
+ * Input parameters:
+ * id - dual-ported memory area id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_port_delete(
+ Objects_Id id
+)
+{
+ register Dual_ported_memory_Control *the_port;
+ Objects_Locations location;
+
+ the_port = _Dual_ported_memory_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* this error cannot be returned */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object );
+ _Dual_ported_memory_Free( the_port );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/dpmemexternal2internal.c b/cpukit/rtems/src/dpmemexternal2internal.c
new file mode 100644
index 0000000000..5ec6f16745
--- /dev/null
+++ b/cpukit/rtems/src/dpmemexternal2internal.c
@@ -0,0 +1,79 @@
+/*
+ * Dual Port Memory Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/rtems/dpmem.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/dpmem.h>
+
+/*PAGE
+ *
+ * rtems_port_external_to_internal
+ *
+ * This directive converts an external dual-ported memory address to an
+ * internal dual-ported memory address. If the given external address
+ * is an invalid dual-ported address, then the internal address is set
+ * to the given external address.
+ *
+ * Input parameters:
+ * id - id of dp memory object
+ * external - external address
+ * internal - pointer of internal address to set
+ *
+ * Output parameters:
+ * internal - internal address
+ * RTEMS_SUCCESSFUL - always succeeds
+ */
+
+rtems_status_code rtems_port_external_to_internal(
+ Objects_Id id,
+ void *external,
+ void **internal
+)
+{
+ register Dual_ported_memory_Control *the_port;
+ Objects_Locations location;
+ uint32_t ending;
+
+ if ( !internal )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_port = _Dual_ported_memory_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* this error cannot be returned */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ ending = _Addresses_Subtract( external, the_port->external_base );
+ if ( ending > the_port->length )
+ *internal = external;
+ else
+ *internal = _Addresses_Add_offset( the_port->internal_base,
+ ending );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/dpmemident.c b/cpukit/rtems/src/dpmemident.c
new file mode 100644
index 0000000000..7d24b3a70c
--- /dev/null
+++ b/cpukit/rtems/src/dpmemident.c
@@ -0,0 +1,59 @@
+/*
+ * Dual Port Memory Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/rtems/dpmem.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/dpmem.h>
+
+/*PAGE
+ *
+ * rtems_port_ident
+ *
+ * This directive returns the system ID associated with
+ * the port name.
+ *
+ * Input parameters:
+ * name - user defined port name
+ * id - pointer to port id
+ *
+ * Output parameters:
+ * *id - port id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_port_ident(
+ rtems_name name,
+ Objects_Id *id
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ status = _Objects_Name_to_id(
+ &_Dual_ported_memory_Information,
+ (Objects_Name) name,
+ OBJECTS_SEARCH_ALL_NODES,
+ id
+ );
+
+ return _Status_Object_name_errors_to_status[ status ];
+}
diff --git a/cpukit/rtems/src/dpmeminternal2external.c b/cpukit/rtems/src/dpmeminternal2external.c
new file mode 100644
index 0000000000..d643de478a
--- /dev/null
+++ b/cpukit/rtems/src/dpmeminternal2external.c
@@ -0,0 +1,79 @@
+/*
+ * Dual Port Memory Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/rtems/dpmem.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/dpmem.h>
+
+/*PAGE
+ *
+ * rtems_port_internal_to_external
+ *
+ * This directive converts an internal dual-ported memory address to an
+ * external dual-ported memory address. If the given internal address
+ * is an invalid dual-ported address, then the external address is set
+ * to the given internal address.
+ *
+ * Input parameters:
+ * id - id of dual-ported memory object
+ * internal - internal address to set
+ * external - pointer to external address
+ *
+ * Output parameters:
+ * external - external address
+ * RTEMS_SUCCESSFUL - always succeeds
+ */
+
+rtems_status_code rtems_port_internal_to_external(
+ Objects_Id id,
+ void *internal,
+ void **external
+)
+{
+ register Dual_ported_memory_Control *the_port;
+ Objects_Locations location;
+ uint32_t ending;
+
+ if ( !external )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_port = _Dual_ported_memory_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* this error cannot be returned */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ ending = _Addresses_Subtract( internal, the_port->internal_base );
+ if ( ending > the_port->length )
+ *external = internal;
+ else
+ *external = _Addresses_Add_offset( the_port->external_base,
+ ending );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/event.c b/cpukit/rtems/src/event.c
new file mode 100644
index 0000000000..ebc5682cde
--- /dev/null
+++ b/cpukit/rtems/src/event.c
@@ -0,0 +1,48 @@
+/*
+ * Event Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/event.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/tasks.h>
+
+/*PAGE
+ *
+ * _Event_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Event_Manager_initialization( void )
+{
+ _Event_Sync_state = EVENT_SYNC_SYNCHRONIZED;
+
+ /*
+ * Register the MP Process Packet routine.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _MPCI_Register_packet_processor( MP_PACKET_EVENT, _Event_MP_Process_packet );
+#endif
+}
diff --git a/cpukit/rtems/src/eventmp.c b/cpukit/rtems/src/eventmp.c
new file mode 100644
index 0000000000..2b19571e52
--- /dev/null
+++ b/cpukit/rtems/src/eventmp.c
@@ -0,0 +1,193 @@
+/*
+ * Multiprocessing Support for the Event Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/event.h>
+#include <rtems/score/mpci.h>
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * _Event_MP_Send_process_packet
+ *
+ * This subprogram is not needed since there are no process
+ * packets to be sent by this manager.
+ *
+ */
+
+/*PAGE
+ *
+ * _Event_MP_Send_request_packet
+ *
+ */
+
+rtems_status_code _Event_MP_Send_request_packet (
+ Event_MP_Remote_operations operation,
+ Objects_Id event_id,
+ rtems_event_set event_in
+)
+{
+ Event_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case EVENT_MP_SEND_REQUEST:
+
+ the_packet = _Event_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_EVENT;
+ the_packet->Prefix.length = sizeof ( Event_MP_Packet );
+ the_packet->Prefix.to_convert = sizeof ( Event_MP_Packet );
+ the_packet->operation = operation;
+ the_packet->Prefix.id = event_id;
+ the_packet->event_in = event_in;
+
+ return (rtems_status_code)
+ _MPCI_Send_request_packet(
+ rtems_get_node( event_id ),
+ &the_packet->Prefix,
+ STATES_READY
+ );
+
+ break;
+
+ case EVENT_MP_SEND_RESPONSE:
+ break;
+
+ }
+ /*
+ * The following line is included to satisfy compilers which
+ * produce warnings when a function does not end with a return.
+ */
+ return RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * _Event_MP_Send_response_packet
+ *
+ */
+
+void _Event_MP_Send_response_packet (
+ Event_MP_Remote_operations operation,
+ Thread_Control *the_thread
+)
+{
+ Event_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case EVENT_MP_SEND_RESPONSE:
+
+ the_packet = ( Event_MP_Packet *) the_thread->receive_packet;
+
+/*
+ * The packet being returned already contains the class, length, and
+ * to_convert fields, therefore they are not set in this routine.
+ */
+ the_packet->operation = operation;
+ the_packet->Prefix.id = the_packet->Prefix.source_tid;
+
+ _MPCI_Send_response_packet(
+ rtems_get_node( the_packet->Prefix.source_tid ),
+ &the_packet->Prefix
+ );
+ break;
+
+ case EVENT_MP_SEND_REQUEST:
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ *
+ * _Event_MP_Process_packet
+ *
+ */
+
+void _Event_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+)
+{
+ Event_MP_Packet *the_packet;
+ Thread_Control *the_thread;
+
+ the_packet = (Event_MP_Packet *) the_packet_prefix;
+
+ switch ( the_packet->operation ) {
+
+ case EVENT_MP_SEND_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_event_send(
+ the_packet->Prefix.id,
+ the_packet->event_in
+ );
+
+ _Event_MP_Send_response_packet(
+ EVENT_MP_SEND_RESPONSE,
+ _Thread_Executing
+ );
+ break;
+
+ case EVENT_MP_SEND_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ _MPCI_Return_packet( the_packet_prefix );
+
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ * _Event_MP_Send_object_was_deleted
+ *
+ * This subprogram is not needed since there are no objects
+ * deleted by this manager.
+ *
+ */
+
+/*PAGE
+ *
+ * _Event_MP_Send_extract_proxy
+ *
+ * This subprogram is not needed since there are no objects
+ * deleted by this manager.
+ *
+ */
+
+/*PAGE
+ *
+ * _Event_MP_Get_packet
+ *
+ */
+
+Event_MP_Packet *_Event_MP_Get_packet ( void )
+{
+ return ( (Event_MP_Packet *) _MPCI_Get_packet() );
+}
+
+/* end of file */
diff --git a/cpukit/rtems/src/eventreceive.c b/cpukit/rtems/src/eventreceive.c
new file mode 100644
index 0000000000..54bb7ef54c
--- /dev/null
+++ b/cpukit/rtems/src/eventreceive.c
@@ -0,0 +1,69 @@
+/*
+ * Event Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/event.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/tasks.h>
+
+/*PAGE
+ *
+ * rtems_event_receive
+ *
+ * This directive allows a thread to receive a set of events.
+ *
+ * Input parameters:
+ * event_in - input event condition
+ * option_set - options
+ * ticks - number of ticks to wait (0 means wait forever)
+ * event_out - pointer to output event set
+ *
+ * Output parameters:
+ * event out - event set
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_event_receive(
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out
+)
+{
+ RTEMS_API_Control *api;
+
+ if ( !event_out )
+ return RTEMS_INVALID_ADDRESS;
+
+ api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];
+
+ if ( _Event_sets_Is_empty( event_in ) ) {
+ *event_out = api->pending_events;
+ return RTEMS_SUCCESSFUL;
+ }
+
+ _Thread_Disable_dispatch();
+ _Event_Seize( event_in, option_set, ticks, event_out );
+ _Thread_Enable_dispatch();
+ return( _Thread_Executing->Wait.return_code );
+}
diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c
new file mode 100644
index 0000000000..2c8a1479d8
--- /dev/null
+++ b/cpukit/rtems/src/eventseize.c
@@ -0,0 +1,142 @@
+/*
+ * Event Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/event.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/tasks.h>
+
+/*PAGE
+ *
+ * _Event_Seize
+ *
+ * This routine attempts to satisfy the requested event condition
+ * for the running thread.
+ *
+ * Input parameters:
+ * event_in - the event condition to satisfy
+ * option_set - acquire event options
+ * ticks - interval to wait
+ * event_out - pointer to event set output area
+ *
+ * Output parameters: NONE
+ * *event_out - event set output area filled in
+ *
+ * INTERRUPT LATENCY:
+ * available
+ * wait
+ * check sync
+ */
+
+void _Event_Seize(
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out
+)
+{
+ Thread_Control *executing;
+ rtems_event_set seized_events;
+ rtems_event_set pending_events;
+ ISR_Level level;
+ RTEMS_API_Control *api;
+ Event_Sync_states sync_state;
+
+ executing = _Thread_Executing;
+ executing->Wait.return_code = RTEMS_SUCCESSFUL;
+
+ api = executing->API_Extensions[ THREAD_API_RTEMS ];
+
+ _ISR_Disable( level );
+ pending_events = api->pending_events;
+ seized_events = _Event_sets_Get( pending_events, event_in );
+
+ if ( !_Event_sets_Is_empty( seized_events ) &&
+ (seized_events == event_in || _Options_Is_any( option_set )) ) {
+ api->pending_events =
+ _Event_sets_Clear( pending_events, seized_events );
+ _ISR_Enable( level );
+ *event_out = seized_events;
+ return;
+ }
+
+ if ( _Options_Is_no_wait( option_set ) ) {
+ _ISR_Enable( level );
+ executing->Wait.return_code = RTEMS_UNSATISFIED;
+ *event_out = seized_events;
+ return;
+ }
+
+ _Event_Sync_state = EVENT_SYNC_NOTHING_HAPPENED;
+
+ executing->Wait.option = (uint32_t ) option_set;
+ executing->Wait.count = (uint32_t ) event_in;
+ executing->Wait.return_argument = event_out;
+
+ _ISR_Enable( level );
+
+ if ( ticks ) {
+ _Watchdog_Initialize(
+ &executing->Timer,
+ _Event_Timeout,
+ executing->Object.id,
+ NULL
+ );
+ _Watchdog_Insert_ticks( &executing->Timer, ticks );
+ }
+
+ _Thread_Set_state( executing, STATES_WAITING_FOR_EVENT );
+
+ _ISR_Disable( level );
+
+ sync_state = _Event_Sync_state;
+ _Event_Sync_state = EVENT_SYNC_SYNCHRONIZED;
+
+ switch ( sync_state ) {
+ case EVENT_SYNC_SYNCHRONIZED:
+ /*
+ * This cannot happen. It indicates that this routine did not
+ * enter the synchronization states above.
+ */
+ return;
+
+ case EVENT_SYNC_NOTHING_HAPPENED:
+ _ISR_Enable( level );
+ return;
+
+ case EVENT_SYNC_TIMEOUT:
+ executing->Wait.return_code = RTEMS_TIMEOUT;
+ _ISR_Enable( level );
+ _Thread_Unblock( executing );
+ return;
+
+ case EVENT_SYNC_SATISFIED:
+ if ( _Watchdog_Is_active( &executing->Timer ) ) {
+ _Watchdog_Deactivate( &executing->Timer );
+ _ISR_Enable( level );
+ (void) _Watchdog_Remove( &executing->Timer );
+ } else
+ _ISR_Enable( level );
+ _Thread_Unblock( executing );
+ return;
+ }
+}
diff --git a/cpukit/rtems/src/eventsend.c b/cpukit/rtems/src/eventsend.c
new file mode 100644
index 0000000000..90eed2207f
--- /dev/null
+++ b/cpukit/rtems/src/eventsend.c
@@ -0,0 +1,75 @@
+/*
+ * Event Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/event.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/tasks.h>
+
+/*PAGE
+ *
+ * rtems_event_send
+ *
+ * This directive allows a thread send an event set to another thread.
+ *
+ * Input parameters:
+ * id - thread id
+ * event - event set
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_event_send(
+ Objects_Id id,
+ rtems_event_set event_in
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+ RTEMS_API_Control *api;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return(
+ _Event_MP_Send_request_packet(
+ EVENT_MP_SEND_REQUEST,
+ id,
+ event_in
+ )
+ );
+#endif
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+ case OBJECTS_LOCAL:
+ api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
+ _Event_sets_Post( event_in, &api->pending_events );
+ _Event_Surrender( the_thread );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/eventsurrender.c b/cpukit/rtems/src/eventsurrender.c
new file mode 100644
index 0000000000..4c2d3b12ce
--- /dev/null
+++ b/cpukit/rtems/src/eventsurrender.c
@@ -0,0 +1,111 @@
+/*
+ * Event Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/event.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/tasks.h>
+
+/*PAGE
+ *
+ * _Event_Surrender
+ *
+ * This routines remove a thread from the specified threadq.
+ *
+ * Input parameters:
+ * the_thread - pointer to thread to be dequeued
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * before flash
+ * after flash
+ * check sync
+ */
+
+void _Event_Surrender(
+ Thread_Control *the_thread
+)
+{
+ ISR_Level level;
+ rtems_event_set pending_events;
+ rtems_event_set event_condition;
+ rtems_event_set seized_events;
+ rtems_option option_set;
+ RTEMS_API_Control *api;
+
+ api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
+
+ option_set = (rtems_option) the_thread->Wait.option;
+
+ _ISR_Disable( level );
+ pending_events = api->pending_events;
+ event_condition = (rtems_event_set) the_thread->Wait.count;
+
+ seized_events = _Event_sets_Get( pending_events, event_condition );
+
+ if ( !_Event_sets_Is_empty( seized_events ) ) {
+ if ( _States_Is_waiting_for_event( the_thread->current_state ) ) {
+ if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
+ api->pending_events =
+ _Event_sets_Clear( pending_events, seized_events );
+ the_thread->Wait.count = 0;
+ *(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
+
+ _ISR_Flash( level );
+
+ if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
+ _ISR_Enable( level );
+ _Thread_Unblock( the_thread );
+ }
+ else {
+ _Watchdog_Deactivate( &the_thread->Timer );
+ _ISR_Enable( level );
+ (void) _Watchdog_Remove( &the_thread->Timer );
+ _Thread_Unblock( the_thread );
+ }
+ return;
+ }
+ }
+
+ switch ( _Event_Sync_state ) {
+ case EVENT_SYNC_SYNCHRONIZED:
+ case EVENT_SYNC_SATISFIED:
+ break;
+
+ case EVENT_SYNC_NOTHING_HAPPENED:
+ case EVENT_SYNC_TIMEOUT:
+ if ( !_Thread_Is_executing( the_thread ) )
+ break;
+
+ if ( seized_events == event_condition || _Options_Is_any(option_set) ) {
+ api->pending_events =
+ _Event_sets_Clear( pending_events,seized_events );
+ the_thread->Wait.count = 0;
+ *(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
+ _Event_Sync_state = EVENT_SYNC_SATISFIED;
+ }
+ break;
+ }
+ }
+ _ISR_Enable( level );
+}
diff --git a/cpukit/rtems/src/eventtimeout.c b/cpukit/rtems/src/eventtimeout.c
new file mode 100644
index 0000000000..c21727f248
--- /dev/null
+++ b/cpukit/rtems/src/eventtimeout.c
@@ -0,0 +1,91 @@
+/*
+ * Event Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/event.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/tasks.h>
+
+/*PAGE
+ *
+ * _Event_Timeout
+ *
+ * This routine processes a thread which timeouts while waiting to
+ * receive an event_set. It is called by the watchdog handler.
+ *
+ * Input parameters:
+ * id - thread id
+ *
+ * Output parameters: NONE
+ */
+
+void _Event_Timeout(
+ Objects_Id id,
+ void *ignored
+)
+{
+ Thread_Control *the_thread;
+ Objects_Locations location;
+ ISR_Level level;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* impossible */
+ case OBJECTS_ERROR:
+ break;
+ case OBJECTS_LOCAL:
+
+ /*
+ * If the event manager is not synchronized, then it is either
+ * "nothing happened", "timeout", or "satisfied". If the_thread
+ * is the executing thread, then it is in the process of blocking
+ * and it is the thread which is responsible for the synchronization
+ * process.
+ *
+ * If it is not satisfied, then it is "nothing happened" and
+ * this is the "timeout" transition. After a request is satisfied,
+ * a timeout is not allowed to occur.
+ */
+
+ _ISR_Disable( level );
+ if ( the_thread->Wait.count ) { /* verify thread is waiting */
+ the_thread->Wait.count = 0;
+ if ( _Event_Sync_state != EVENT_SYNC_SYNCHRONIZED &&
+ _Thread_Is_executing( the_thread ) ) {
+ if ( _Event_Sync_state != EVENT_SYNC_SATISFIED ) {
+ _Event_Sync_state = EVENT_SYNC_TIMEOUT;
+ }
+ _ISR_Enable( level );
+ } else {
+ the_thread->Wait.return_code = RTEMS_TIMEOUT;
+ _ISR_Enable( level );
+ _Thread_Unblock( the_thread );
+ }
+ }
+ else {
+ _ISR_Enable( level );
+ }
+
+ _Thread_Unnest_dispatch();
+ break;
+ }
+}
diff --git a/cpukit/rtems/src/intr.c b/cpukit/rtems/src/intr.c
new file mode 100644
index 0000000000..ee5f27f6ac
--- /dev/null
+++ b/cpukit/rtems/src/intr.c
@@ -0,0 +1,35 @@
+/*
+ * Interrupt Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/score/isr.h>
+#include <rtems/rtems/intr.h>
+
+/* _Interrupt_Manager_initialization
+ *
+ * This routine initializes the interrupt manager.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _Interrupt_Manager_initialization( void )
+{
+}
diff --git a/cpukit/rtems/src/intrbody.c b/cpukit/rtems/src/intrbody.c
new file mode 100644
index 0000000000..b1d1470a7a
--- /dev/null
+++ b/cpukit/rtems/src/intrbody.c
@@ -0,0 +1,74 @@
+/*
+ * Bodies for Inlined Interrupt Manager Routines
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/score/isr.h>
+#include <rtems/rtems/intr.h>
+
+/*
+ * Real body for rtems_interrupt_disable
+ */
+
+#undef rtems_interrupt_disable
+
+rtems_interrupt_level rtems_interrupt_disable( void )
+{
+ rtems_interrupt_level previous_level;
+
+ _ISR_Disable( previous_level );
+
+ return previous_level;
+}
+
+/*
+ * Real body for rtems_interrupt_enable
+ */
+
+#undef rtems_interrupt_enable
+
+void rtems_interrupt_enable(
+ rtems_interrupt_level previous_level
+)
+{
+ _ISR_Enable( previous_level );
+}
+
+/*
+ * Real body for rtems_interrupt_flash
+ */
+
+#undef rtems_interrupt_flash
+
+void rtems_interrupt_flash(
+ rtems_interrupt_level previous_level
+)
+{
+ _ISR_Flash( previous_level );
+}
+
+/*
+ * Real body for rtems_interrupt_is_in_progress
+ */
+
+#undef rtems_interrupt_is_in_progress
+
+boolean rtems_interrupt_is_in_progress( void )
+{
+ return _ISR_Is_in_progress();
+}
diff --git a/cpukit/rtems/src/intrcatch.c b/cpukit/rtems/src/intrcatch.c
new file mode 100644
index 0000000000..ae54008d1d
--- /dev/null
+++ b/cpukit/rtems/src/intrcatch.c
@@ -0,0 +1,58 @@
+/*
+ * Interrupt Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/score/isr.h>
+#include <rtems/rtems/intr.h>
+
+/* rtems_interrupt_catch
+ *
+ * This directive allows a thread to specify what action to take when
+ * catching signals.
+ *
+ * Input parameters:
+ * new_isr_handler - address of interrupt service routine (isr)
+ * vector - interrupt vector number
+ * old_isr_handler - address at which to store previous ISR address
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - always succeeds
+ * *old_isr_handler - previous ISR address
+ */
+
+rtems_status_code rtems_interrupt_catch(
+ rtems_isr_entry new_isr_handler,
+ rtems_vector_number vector,
+ rtems_isr_entry *old_isr_handler
+)
+{
+ if ( !_ISR_Is_vector_number_valid( vector ) )
+ return RTEMS_INVALID_NUMBER;
+
+ if ( !_ISR_Is_valid_user_handler( (void *) new_isr_handler ) )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( !_ISR_Is_valid_user_handler( (void *) old_isr_handler ) )
+ return RTEMS_INVALID_ADDRESS;
+
+ _ISR_Install_vector(
+ vector, (proc_ptr)new_isr_handler, (proc_ptr *)old_isr_handler );
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/mp.c b/cpukit/rtems/src/mp.c
new file mode 100644
index 0000000000..5749dddb4a
--- /dev/null
+++ b/cpukit/rtems/src/mp.c
@@ -0,0 +1,45 @@
+/*
+ * Multiprocessing Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/mp.h>
+#include <rtems/score/mpci.h>
+
+/*PAGE
+ *
+ * _Multiprocessing_Manager_initialization
+ *
+ */
+
+void _Multiprocessing_Manager_initialization ( void )
+{
+}
+
+/*PAGE
+ *
+ * rtems_multiprocessing_announce
+ *
+ */
+
+void rtems_multiprocessing_announce ( void )
+{
+ _MPCI_Announce();
+}
+
+/* end of file */
diff --git a/cpukit/rtems/src/msg.c b/cpukit/rtems/src/msg.c
new file mode 100644
index 0000000000..555c40e64f
--- /dev/null
+++ b/cpukit/rtems/src/msg.c
@@ -0,0 +1,81 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * _Message_queue_Manager_initialization
+ *
+ * This routine initializes all message queue manager related
+ * data structures.
+ *
+ * Input parameters:
+ * maximum_message_queues - number of message queues to initialize
+ *
+ * Output parameters: NONE
+ */
+
+void _Message_queue_Manager_initialization(
+ uint32_t maximum_message_queues
+)
+{
+ _Objects_Initialize_information(
+ &_Message_queue_Information, /* object information table */
+ OBJECTS_CLASSIC_API, /* object API */
+ OBJECTS_RTEMS_MESSAGE_QUEUES, /* object class */
+ maximum_message_queues, /* maximum objects of this class */
+ sizeof( Message_queue_Control ),
+ /* size of this object's control block */
+ FALSE, /* TRUE if names of this object are strings */
+ RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ TRUE, /* TRUE if this is a global object class */
+ _Message_queue_MP_Send_extract_proxy /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Register the MP Process Packet routine.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _MPCI_Register_packet_processor(
+ MP_PACKET_MESSAGE_QUEUE,
+ _Message_queue_MP_Process_packet
+ );
+#endif
+
+}
diff --git a/cpukit/rtems/src/msgmp.c b/cpukit/rtems/src/msgmp.c
new file mode 100644
index 0000000000..bd9c353440
--- /dev/null
+++ b/cpukit/rtems/src/msgmp.c
@@ -0,0 +1,510 @@
+/*
+ * Multiprocessing Support for the Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/message.h>
+#include <rtems/score/mpci.h>
+#include <rtems/rtems/msgmp.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * _Message_queue_MP_Send_process_packet
+ *
+ */
+
+void _Message_queue_MP_Send_process_packet (
+ Message_queue_MP_Remote_operations operation,
+ Objects_Id message_queue_id,
+ rtems_name name,
+ Objects_Id proxy_id
+)
+{
+ Message_queue_MP_Packet *the_packet;
+ uint32_t node;
+
+ switch ( operation ) {
+
+ case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
+ case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
+ case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
+
+ the_packet = _Message_queue_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_MESSAGE_QUEUE;
+ the_packet->Prefix.length = sizeof ( Message_queue_MP_Packet );
+ the_packet->Prefix.to_convert = sizeof ( Message_queue_MP_Packet );
+ the_packet->operation = operation;
+ the_packet->Prefix.id = message_queue_id;
+ the_packet->name = name;
+ the_packet->proxy_id = proxy_id;
+
+ if ( operation == MESSAGE_QUEUE_MP_EXTRACT_PROXY )
+ node = rtems_get_node( message_queue_id );
+ else
+ node = MPCI_ALL_NODES;
+
+ _MPCI_Send_process_packet( node, &the_packet->Prefix );
+ break;
+
+ case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
+ case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
+ case MESSAGE_QUEUE_MP_SEND_REQUEST:
+ case MESSAGE_QUEUE_MP_SEND_RESPONSE:
+ case MESSAGE_QUEUE_MP_URGENT_REQUEST:
+ case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
+ case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
+ case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
+ case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
+ case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
+ case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
+ case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ * _Message_queue_MP_Send_request_packet
+ *
+ */
+
+rtems_status_code _Message_queue_MP_Send_request_packet (
+ Message_queue_MP_Remote_operations operation,
+ Objects_Id message_queue_id,
+ void *buffer,
+ uint32_t *size_p,
+ rtems_option option_set,
+ rtems_interval timeout
+)
+{
+ Message_queue_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case MESSAGE_QUEUE_MP_SEND_REQUEST:
+ case MESSAGE_QUEUE_MP_URGENT_REQUEST:
+ case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
+ case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
+ case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
+
+ the_packet = _Message_queue_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_MESSAGE_QUEUE;
+ the_packet->Prefix.length = sizeof(Message_queue_MP_Packet);
+ if ( size_p )
+ the_packet->Prefix.length += *size_p;
+ the_packet->Prefix.to_convert = sizeof(Message_queue_MP_Packet);
+
+ /*
+ * make sure message is not too big for our MPCI driver
+ * We have to check it here instead of waiting for MPCI because
+ * we are about to slam in the payload
+ */
+
+ if (the_packet->Prefix.length > _MPCI_table->maximum_packet_size) {
+ _Thread_Enable_dispatch();
+ return RTEMS_INVALID_SIZE;
+ }
+
+ if (! _Options_Is_no_wait(option_set))
+ the_packet->Prefix.timeout = timeout;
+
+ the_packet->operation = operation;
+ the_packet->Prefix.id = message_queue_id;
+ the_packet->option_set = option_set;
+
+ /*
+ * Copy the data into place if needed
+ */
+
+ if (buffer) {
+ the_packet->Buffer.size = *size_p;
+ _CORE_message_queue_Copy_buffer(
+ buffer,
+ the_packet->Buffer.buffer,
+ *size_p
+ );
+ }
+
+ return (rtems_status_code) _MPCI_Send_request_packet(
+ rtems_get_node(message_queue_id),
+ &the_packet->Prefix,
+ STATES_WAITING_FOR_MESSAGE
+ );
+ break;
+
+ case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
+
+ the_packet = _Message_queue_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_MESSAGE_QUEUE;
+ the_packet->Prefix.length = sizeof(Message_queue_MP_Packet);
+ the_packet->Prefix.to_convert = sizeof(Message_queue_MP_Packet);
+
+ if (! _Options_Is_no_wait(option_set))
+ the_packet->Prefix.timeout = timeout;
+
+ the_packet->operation = MESSAGE_QUEUE_MP_RECEIVE_REQUEST;
+ the_packet->Prefix.id = message_queue_id;
+ the_packet->option_set = option_set;
+ the_packet->size = 0; /* just in case of an error */
+
+ _Thread_Executing->Wait.return_argument = (uint32_t *)buffer;
+ _Thread_Executing->Wait.return_argument_1 = size_p;
+
+ return (rtems_status_code) _MPCI_Send_request_packet(
+ rtems_get_node(message_queue_id),
+ &the_packet->Prefix,
+ STATES_WAITING_FOR_MESSAGE
+ );
+ break;
+
+ case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
+ case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
+ case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
+ case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
+ case MESSAGE_QUEUE_MP_SEND_RESPONSE:
+ case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
+ case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
+ case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
+ case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
+ break;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * _Message_queue_MP_Send_response_packet
+ *
+ */
+
+void _Message_queue_MP_Send_response_packet (
+ Message_queue_MP_Remote_operations operation,
+ Objects_Id message_queue_id,
+ Thread_Control *the_thread
+)
+{
+ Message_queue_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
+ case MESSAGE_QUEUE_MP_SEND_RESPONSE:
+ case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
+ case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
+ case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
+ case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
+
+ the_packet = ( Message_queue_MP_Packet *) the_thread->receive_packet;
+
+/*
+ * The packet being returned already contains the class, length, and
+ * to_convert fields, therefore they are not set in this routine.
+ *
+ * Exception: MESSAGE_QUEUE_MP_RECEIVE_RESPONSE needs payload length
+ * added to 'length'
+ */
+ the_packet->operation = operation;
+ the_packet->Prefix.id = the_packet->Prefix.source_tid;
+
+ if (operation == MESSAGE_QUEUE_MP_RECEIVE_RESPONSE)
+ the_packet->Prefix.length += the_packet->size;
+
+ _MPCI_Send_response_packet(
+ rtems_get_node( the_packet->Prefix.source_tid ),
+ &the_packet->Prefix
+ );
+ break;
+
+ case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
+ case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
+ case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
+ case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
+ case MESSAGE_QUEUE_MP_SEND_REQUEST:
+ case MESSAGE_QUEUE_MP_URGENT_REQUEST:
+ case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
+ case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
+ case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ *
+ * _Message_queue_MP_Process_packet
+ *
+ */
+
+void _Message_queue_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+)
+{
+ Message_queue_MP_Packet *the_packet;
+ Thread_Control *the_thread;
+ boolean ignored;
+
+ the_packet = (Message_queue_MP_Packet *) the_packet_prefix;
+
+ switch ( the_packet->operation ) {
+
+ case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
+
+ ignored = _Objects_MP_Allocate_and_open(
+ &_Message_queue_Information,
+ the_packet->name,
+ the_packet->Prefix.id,
+ TRUE
+ );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
+
+ _Objects_MP_Close( &_Message_queue_Information, the_packet->Prefix.id );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
+
+ the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
+
+ if (! _Thread_Is_null( the_thread ) )
+ _Thread_queue_Extract( the_thread->Wait.queue, the_thread );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_message_queue_receive(
+ the_packet->Prefix.id,
+ the_packet->Buffer.buffer,
+ &the_packet->size,
+ the_packet->option_set,
+ the_packet->Prefix.timeout
+ );
+
+ if (! _Thread_Is_proxy_blocking( the_packet->Prefix.return_code ) )
+ _Message_queue_MP_Send_response_packet(
+ MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+
+ case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ if (the_packet->Prefix.return_code == RTEMS_SUCCESSFUL) {
+ *(uint32_t *)the_thread->Wait.return_argument_1 =
+ the_packet->size;
+
+ _CORE_message_queue_Copy_buffer(
+ the_packet->Buffer.buffer,
+ the_thread->Wait.return_argument,
+ the_packet->size
+ );
+ }
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case MESSAGE_QUEUE_MP_SEND_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_message_queue_send(
+ the_packet->Prefix.id,
+ the_packet->Buffer.buffer,
+ the_packet->Buffer.size
+ );
+
+ _Message_queue_MP_Send_response_packet(
+ MESSAGE_QUEUE_MP_SEND_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+
+ case MESSAGE_QUEUE_MP_SEND_RESPONSE:
+ case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case MESSAGE_QUEUE_MP_URGENT_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_message_queue_urgent(
+ the_packet->Prefix.id,
+ the_packet->Buffer.buffer,
+ the_packet->Buffer.size
+ );
+
+ _Message_queue_MP_Send_response_packet(
+ MESSAGE_QUEUE_MP_URGENT_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+
+ case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_message_queue_broadcast(
+ the_packet->Prefix.id,
+ the_packet->Buffer.buffer,
+ the_packet->Buffer.size,
+ &the_packet->count
+ );
+
+ _Message_queue_MP_Send_response_packet(
+ MESSAGE_QUEUE_MP_BROADCAST_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+
+ case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
+ case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
+ case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ *(uint32_t *)the_thread->Wait.return_argument = the_packet->count;
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_message_queue_flush(
+ the_packet->Prefix.id,
+ &the_packet->count
+ );
+
+ _Message_queue_MP_Send_response_packet(
+ MESSAGE_QUEUE_MP_FLUSH_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+
+ case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_message_queue_get_number_pending(
+ the_packet->Prefix.id,
+ &the_packet->count
+ );
+
+ _Message_queue_MP_Send_response_packet(
+ MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ * _Message_queue_MP_Send_object_was_deleted
+ *
+ */
+
+void _Message_queue_MP_Send_object_was_deleted (
+ Thread_Control *the_proxy
+)
+{
+ the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED;
+
+ _Message_queue_MP_Send_response_packet(
+ MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
+ the_proxy->Wait.id,
+ the_proxy
+ );
+}
+
+/*PAGE
+ *
+ * _Message_queue_MP_Send_extract_proxy
+ *
+ */
+
+void _Message_queue_MP_Send_extract_proxy (
+ void *argument
+)
+{
+ Thread_Control *the_thread = (Thread_Control *)argument;
+
+ _Message_queue_MP_Send_process_packet(
+ MESSAGE_QUEUE_MP_EXTRACT_PROXY,
+ the_thread->Wait.id,
+ (rtems_name) 0,
+ the_thread->Object.id
+ );
+}
+
+/*PAGE
+ *
+ * _Message_queue_MP_Get_packet
+ *
+ */
+
+Message_queue_MP_Packet *_Message_queue_MP_Get_packet ( void )
+{
+ return ( (Message_queue_MP_Packet *) _MPCI_Get_packet() );
+}
+
+
+/*PAGE
+ *
+ * _Message_queue_Core_message_queue_mp_support
+ *
+ * Input parameters:
+ * the_thread - the remote thread the message was submitted to
+ * id - id of the message queue
+ *
+ * Output parameters: NONE
+ */
+
+void _Message_queue_Core_message_queue_mp_support (
+ Thread_Control *the_thread,
+ Objects_Id id
+)
+{
+ the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
+
+ _Message_queue_MP_Send_response_packet(
+ MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
+ id,
+ the_thread
+ );
+}
+
+/* end of file */
diff --git a/cpukit/rtems/src/msgqallocate.c b/cpukit/rtems/src/msgqallocate.c
new file mode 100644
index 0000000000..78439c4f66
--- /dev/null
+++ b/cpukit/rtems/src/msgqallocate.c
@@ -0,0 +1,60 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * _Message_queue_Allocate
+ *
+ * Allocate a message queue and the space for its messages
+ *
+ * Input parameters:
+ * the_message_queue - the message queue to allocate message buffers
+ * count - maximum message and reserved buffer count
+ * max_message_size - maximum size of each message
+ *
+ * Output parameters:
+ * the_message_queue - set if successful, NULL otherwise
+ */
+
+Message_queue_Control *_Message_queue_Allocate (
+ uint32_t count,
+ uint32_t max_message_size
+)
+{
+ return
+ (Message_queue_Control *)_Objects_Allocate(&_Message_queue_Information);
+
+}
diff --git a/cpukit/rtems/src/msgqbroadcast.c b/cpukit/rtems/src/msgqbroadcast.c
new file mode 100644
index 0000000000..3429c387cd
--- /dev/null
+++ b/cpukit/rtems/src/msgqbroadcast.c
@@ -0,0 +1,113 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * rtems_message_queue_broadcast
+ *
+ * This directive sends a message for every thread waiting on the queue
+ * designated by id.
+ *
+ * Input parameters:
+ * id - pointer to message queue
+ * buffer - pointer to message buffer
+ * size - size of message to broadcast
+ * count - pointer to area to store number of threads made ready
+ *
+ * Output parameters:
+ * count - number of threads made ready
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_message_queue_broadcast(
+ Objects_Id id,
+ void *buffer,
+ uint32_t size,
+ uint32_t *count
+)
+{
+ register Message_queue_Control *the_message_queue;
+ Objects_Locations location;
+ CORE_message_queue_Status core_status;
+
+ if ( !buffer )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( !count )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_message_queue = _Message_queue_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Executing->Wait.return_argument = count;
+
+ return
+ _Message_queue_MP_Send_request_packet(
+ MESSAGE_QUEUE_MP_BROADCAST_REQUEST,
+ id,
+ buffer,
+ &size,
+ 0, /* option_set not used */
+ MPCI_DEFAULT_TIMEOUT
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ core_status = _CORE_message_queue_Broadcast(
+ &the_message_queue->message_queue,
+ buffer,
+ size,
+ id,
+#if defined(RTEMS_MULTIPROCESSING)
+ _Message_queue_Core_message_queue_mp_support,
+#else
+ NULL,
+#endif
+ count
+ );
+
+ _Thread_Enable_dispatch();
+ return
+ _Message_queue_Translate_core_message_queue_return_code( core_status );
+
+ }
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/msgqcreate.c b/cpukit/rtems/src/msgqcreate.c
new file mode 100644
index 0000000000..05d748187b
--- /dev/null
+++ b/cpukit/rtems/src/msgqcreate.c
@@ -0,0 +1,165 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * rtems_message_queue_create
+ *
+ * This directive creates a message queue by allocating and initializing
+ * a message queue data structure.
+ *
+ * Input parameters:
+ * name - user defined queue name
+ * count - maximum message and reserved buffer count
+ * max_message_size - maximum size of each message
+ * attribute_set - process method
+ * id - pointer to queue
+ *
+ * Output parameters:
+ * id - queue id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_message_queue_create(
+ rtems_name name,
+ uint32_t count,
+ uint32_t max_message_size,
+ rtems_attribute attribute_set,
+ Objects_Id *id
+)
+{
+ register Message_queue_Control *the_message_queue;
+ CORE_message_queue_Attributes the_msgq_attributes;
+#if defined(RTEMS_MULTIPROCESSING)
+ boolean is_global;
+#endif
+
+ if ( !rtems_is_name_valid( name ) )
+ return RTEMS_INVALID_NAME;
+
+ if ( !id )
+ return RTEMS_INVALID_ADDRESS;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( (is_global = _Attributes_Is_global( attribute_set ) ) &&
+ !_System_state_Is_multiprocessing )
+ return RTEMS_MP_NOT_CONFIGURED;
+#endif
+
+ if ( count == 0 )
+ return RTEMS_INVALID_NUMBER;
+
+ if ( max_message_size == 0 )
+ return RTEMS_INVALID_SIZE;
+
+#if defined(RTEMS_MULTIPROCESSING)
+#if 1
+ /*
+ * I am not 100% sure this should be an error.
+ * It seems reasonable to create a que with a large max size,
+ * and then just send smaller msgs from remote (or all) nodes.
+ */
+
+ if ( is_global && (_MPCI_table->maximum_packet_size < max_message_size) )
+ return RTEMS_INVALID_SIZE;
+#endif
+#endif
+
+ _Thread_Disable_dispatch(); /* protects object pointer */
+
+ the_message_queue = _Message_queue_Allocate( count, max_message_size );
+
+ if ( !the_message_queue ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( is_global &&
+ !( _Objects_MP_Allocate_and_open( &_Message_queue_Information,
+ name, the_message_queue->Object.id, FALSE ) ) ) {
+ _Message_queue_Free( the_message_queue );
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+#endif
+
+ the_message_queue->attribute_set = attribute_set;
+
+ if (_Attributes_Is_priority( attribute_set ) )
+ the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
+ else
+ the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
+
+ if ( ! _CORE_message_queue_Initialize(
+ &the_message_queue->message_queue,
+ &the_msgq_attributes,
+ count,
+ max_message_size
+ ) ) {
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( is_global )
+ _Objects_MP_Close(
+ &_Message_queue_Information, the_message_queue->Object.id);
+#endif
+
+ _Message_queue_Free( the_message_queue );
+ _Thread_Enable_dispatch();
+ return RTEMS_UNSATISFIED;
+ }
+
+ _Objects_Open(
+ &_Message_queue_Information,
+ &the_message_queue->Object,
+ (Objects_Name) name
+ );
+
+ *id = the_message_queue->Object.id;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( is_global )
+ _Message_queue_MP_Send_process_packet(
+ MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
+ the_message_queue->Object.id,
+ name,
+ 0
+ );
+#endif
+
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/msgqdelete.c b/cpukit/rtems/src/msgqdelete.c
new file mode 100644
index 0000000000..4875578946
--- /dev/null
+++ b/cpukit/rtems/src/msgqdelete.c
@@ -0,0 +1,108 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * rtems_message_queue_delete
+ *
+ * This directive allows a thread to delete the message queue specified
+ * by the given queue identifier.
+ *
+ * Input parameters:
+ * id - queue id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_message_queue_delete(
+ Objects_Id id
+)
+{
+ register Message_queue_Control *the_message_queue;
+ Objects_Locations location;
+
+ the_message_queue = _Message_queue_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ _Objects_Close( &_Message_queue_Information,
+ &the_message_queue->Object );
+
+ _CORE_message_queue_Close(
+ &the_message_queue->message_queue,
+#if defined(RTEMS_MULTIPROCESSING)
+ _Message_queue_MP_Send_object_was_deleted,
+#else
+ NULL,
+#endif
+ CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED
+ );
+
+ _Message_queue_Free( the_message_queue );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Attributes_Is_global( the_message_queue->attribute_set ) ) {
+ _Objects_MP_Close(
+ &_Message_queue_Information,
+ the_message_queue->Object.id
+ );
+
+ _Message_queue_MP_Send_process_packet(
+ MESSAGE_QUEUE_MP_ANNOUNCE_DELETE,
+ the_message_queue->Object.id,
+ 0, /* Not used */
+ 0
+ );
+ }
+#endif
+
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/msgqflush.c b/cpukit/rtems/src/msgqflush.c
new file mode 100644
index 0000000000..2132725f30
--- /dev/null
+++ b/cpukit/rtems/src/msgqflush.c
@@ -0,0 +1,93 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * rtems_message_queue_flush
+ *
+ * This directive removes all pending messages from a queue and returns
+ * the number of messages removed. If no messages were present then
+ * a count of zero is returned.
+ *
+ * Input parameters:
+ * id - queue id
+ * count - return area for count
+ *
+ * Output parameters:
+ * count - number of messages removed ( 0 = empty queue )
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_message_queue_flush(
+ Objects_Id id,
+ uint32_t *count
+)
+{
+ register Message_queue_Control *the_message_queue;
+ Objects_Locations location;
+
+ if ( !count )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_message_queue = _Message_queue_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Executing->Wait.return_argument = count;
+
+ return
+ _Message_queue_MP_Send_request_packet(
+ MESSAGE_QUEUE_MP_FLUSH_REQUEST,
+ id,
+ 0, /* buffer not used */
+ 0, /* size */
+ 0, /* option_set not used */
+ MPCI_DEFAULT_TIMEOUT
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ *count = _CORE_message_queue_Flush( &the_message_queue->message_queue );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/msgqgetnumberpending.c b/cpukit/rtems/src/msgqgetnumberpending.c
new file mode 100644
index 0000000000..682f94837d
--- /dev/null
+++ b/cpukit/rtems/src/msgqgetnumberpending.c
@@ -0,0 +1,90 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * rtems_message_queue_get_number_pending
+ *
+ * This directive returns the number of messages pending.
+ *
+ * Input parameters:
+ * id - queue id
+ * count - return area for count
+ *
+ * Output parameters:
+ * count - number of messages removed ( 0 = empty queue )
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_message_queue_get_number_pending(
+ Objects_Id id,
+ uint32_t *count
+)
+{
+ register Message_queue_Control *the_message_queue;
+ Objects_Locations location;
+
+ if ( !count )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_message_queue = _Message_queue_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Executing->Wait.return_argument = count;
+
+ return _Message_queue_MP_Send_request_packet(
+ MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST,
+ id,
+ 0, /* buffer not used */
+ 0, /* size */
+ 0, /* option_set not used */
+ MPCI_DEFAULT_TIMEOUT
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ *count = the_message_queue->message_queue.number_of_pending_messages;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/msgqident.c b/cpukit/rtems/src/msgqident.c
new file mode 100644
index 0000000000..41289a2996
--- /dev/null
+++ b/cpukit/rtems/src/msgqident.c
@@ -0,0 +1,71 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * rtems_message_queue_ident
+ *
+ * This directive returns the system ID associated with
+ * the message queue name.
+ *
+ * Input parameters:
+ * name - user defined message queue name
+ * node - node(s) to be searched
+ * id - pointer to message queue id
+ *
+ * Output parameters:
+ * *id - message queue id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_message_queue_ident(
+ rtems_name name,
+ uint32_t node,
+ Objects_Id *id
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ status = _Objects_Name_to_id(
+ &_Message_queue_Information,
+ (Objects_Name) name,
+ node,
+ id
+ );
+
+ return _Status_Object_name_errors_to_status[ status ];
+}
diff --git a/cpukit/rtems/src/msgqreceive.c b/cpukit/rtems/src/msgqreceive.c
new file mode 100644
index 0000000000..649aed45dd
--- /dev/null
+++ b/cpukit/rtems/src/msgqreceive.c
@@ -0,0 +1,114 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * rtems_message_queue_receive
+ *
+ * This directive dequeues a message from the designated message queue
+ * and copies it into the requesting thread's buffer.
+ *
+ * Input parameters:
+ * id - queue id
+ * buffer - pointer to message buffer
+ * size - size of message receive
+ * option_set - options on receive
+ * timeout - number of ticks to wait
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_message_queue_receive(
+ Objects_Id id,
+ void *buffer,
+ uint32_t *size,
+ uint32_t option_set,
+ rtems_interval timeout
+)
+{
+ register Message_queue_Control *the_message_queue;
+ Objects_Locations location;
+ boolean wait;
+
+ if ( !buffer )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( !size )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_message_queue = _Message_queue_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return _Message_queue_MP_Send_request_packet(
+ MESSAGE_QUEUE_MP_RECEIVE_REQUEST,
+ id,
+ buffer,
+ size,
+ option_set,
+ timeout
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( _Options_Is_no_wait( option_set ) )
+ wait = FALSE;
+ else
+ wait = TRUE;
+
+ _CORE_message_queue_Seize(
+ &the_message_queue->message_queue,
+ the_message_queue->Object.id,
+ buffer,
+ size,
+ wait,
+ timeout
+ );
+ _Thread_Enable_dispatch();
+ return _Message_queue_Translate_core_message_queue_return_code(
+ _Thread_Executing->Wait.return_code
+ );
+
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/msgqsend.c b/cpukit/rtems/src/msgqsend.c
new file mode 100644
index 0000000000..c7f72145b1
--- /dev/null
+++ b/cpukit/rtems/src/msgqsend.c
@@ -0,0 +1,61 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * rtems_message_queue_send
+ *
+ * This routine implements the directives q_send. It sends a
+ * message to the specified message queue.
+ *
+ * Input parameters:
+ * id - pointer to message queue
+ * buffer - pointer to message buffer
+ * size - size of message to sent urgently
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_message_queue_send(
+ Objects_Id id,
+ void *buffer,
+ uint32_t size
+)
+{
+ return( _Message_queue_Submit(id, buffer, size, MESSAGE_QUEUE_SEND_REQUEST) );
+}
diff --git a/cpukit/rtems/src/msgqsubmit.c b/cpukit/rtems/src/msgqsubmit.c
new file mode 100644
index 0000000000..bb7e68184d
--- /dev/null
+++ b/cpukit/rtems/src/msgqsubmit.c
@@ -0,0 +1,151 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * _Message_queue_Submit
+ *
+ * This routine implements the directives rtems_message_queue_send
+ * and rtems_message_queue_urgent. It processes a message that is
+ * to be submitted to the designated message queue. The message will
+ * either be processed as a send send message which it will be inserted
+ * at the rear of the queue or it will be processed as an urgent message
+ * which will be inserted at the front of the queue.
+ *
+ * Input parameters:
+ * id - pointer to message queue
+ * buffer - pointer to message buffer
+ * size - size in bytes of message to send
+ * submit_type - send or urgent message
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#define MESSAGE_QUEUE_MP_HANDLER _Message_queue_Core_message_queue_mp_support
+#else
+#define MESSAGE_QUEUE_MP_HANDLER NULL
+#endif
+
+rtems_status_code _Message_queue_Submit(
+ Objects_Id id,
+ void *buffer,
+ uint32_t size,
+ Message_queue_Submit_types submit_type
+)
+{
+ register Message_queue_Control *the_message_queue;
+ Objects_Locations location;
+ CORE_message_queue_Status msg_status;
+
+ if ( !buffer )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_message_queue = _Message_queue_Get( id, &location );
+ switch ( location )
+ {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ switch ( submit_type ) {
+ case MESSAGE_QUEUE_SEND_REQUEST:
+ return _Message_queue_MP_Send_request_packet(
+ MESSAGE_QUEUE_MP_SEND_REQUEST,
+ id,
+ buffer,
+ &size,
+ 0, /* option_set */
+ MPCI_DEFAULT_TIMEOUT
+ );
+
+ case MESSAGE_QUEUE_URGENT_REQUEST:
+ return _Message_queue_MP_Send_request_packet(
+ MESSAGE_QUEUE_MP_URGENT_REQUEST,
+ id,
+ buffer,
+ &size,
+ 0, /* option_set */
+ MPCI_DEFAULT_TIMEOUT
+ );
+ }
+ break;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ switch ( submit_type ) {
+ case MESSAGE_QUEUE_SEND_REQUEST:
+ msg_status = _CORE_message_queue_Send(
+ &the_message_queue->message_queue,
+ buffer,
+ size,
+ id,
+ MESSAGE_QUEUE_MP_HANDLER,
+ FALSE, /* sender does not block */
+ 0 /* no timeout */
+ );
+ break;
+ case MESSAGE_QUEUE_URGENT_REQUEST:
+ msg_status = _CORE_message_queue_Urgent(
+ &the_message_queue->message_queue,
+ buffer,
+ size,
+ id,
+ MESSAGE_QUEUE_MP_HANDLER,
+ FALSE, /* sender does not block */
+ 0 /* no timeout */
+ );
+ break;
+ default:
+ return RTEMS_INTERNAL_ERROR; /* should never get here */
+ }
+
+ _Thread_Enable_dispatch();
+
+ /*
+ * Since this API does not allow for blocking sends, we can directly
+ * return the returned msg_status.
+ */
+
+ return
+ _Message_queue_Translate_core_message_queue_return_code( msg_status );
+
+ }
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/msgqtranslatereturncode.c b/cpukit/rtems/src/msgqtranslatereturncode.c
new file mode 100644
index 0000000000..c61a619559
--- /dev/null
+++ b/cpukit/rtems/src/msgqtranslatereturncode.c
@@ -0,0 +1,72 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * _Message_queue_Translate_core_message_queue_return_code
+ *
+ * Input parameters:
+ * the_message_queue_status - message_queue status code to translate
+ *
+ * Output parameters:
+ * rtems status code - translated RTEMS status code
+ *
+ */
+
+rtems_status_code _Message_queue_Translate_core_return_code_[] = {
+ RTEMS_SUCCESSFUL, /* CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL */
+ RTEMS_INVALID_SIZE, /* CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE */
+ RTEMS_TOO_MANY, /* CORE_MESSAGE_QUEUE_STATUS_TOO_MANY */
+ RTEMS_UNSATISFIED, /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED */
+ RTEMS_UNSATISFIED, /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT */
+ RTEMS_OBJECT_WAS_DELETED, /* CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED */
+ RTEMS_TIMEOUT /* CORE_MESSAGE_QUEUE_STATUS_TIMEOUT */
+};
+
+rtems_status_code _Message_queue_Translate_core_message_queue_return_code (
+ uint32_t status
+)
+{
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( status == THREAD_STATUS_PROXY_BLOCKING )
+ return RTEMS_PROXY_BLOCKING;
+ else
+#endif
+ if ( status > CORE_MESSAGE_QUEUE_STATUS_TIMEOUT )
+ return RTEMS_INTERNAL_ERROR;
+ else
+ return _Message_queue_Translate_core_return_code_[status];
+}
diff --git a/cpukit/rtems/src/msgqurgent.c b/cpukit/rtems/src/msgqurgent.c
new file mode 100644
index 0000000000..8a5de65265
--- /dev/null
+++ b/cpukit/rtems/src/msgqurgent.c
@@ -0,0 +1,61 @@
+/*
+ * Message Queue Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * rtems_message_queue_urgent
+ *
+ * This routine implements the directives q_urgent. It urgents a
+ * message to the specified message queue.
+ *
+ * Input parameters:
+ * id - pointer to message queue
+ * buffer - pointer to message buffer
+ * size - size of message to sent urgently
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_message_queue_urgent(
+ Objects_Id id,
+ void *buffer,
+ uint32_t size
+)
+{
+ return(_Message_queue_Submit(id, buffer, size, MESSAGE_QUEUE_URGENT_REQUEST));
+}
diff --git a/cpukit/rtems/src/part.c b/cpukit/rtems/src/part.c
new file mode 100644
index 0000000000..35bd043679
--- /dev/null
+++ b/cpukit/rtems/src/part.c
@@ -0,0 +1,71 @@
+/*
+ * Partition Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/part.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * _Partition_Manager_initialization
+ *
+ * This routine initializes all partition manager related
+ * data structures.
+ *
+ * Input parameters:
+ * maximum_partitions - number of partitions to initialize
+ *
+ * Output parameters: NONE
+ */
+
+void _Partition_Manager_initialization(
+ uint32_t maximum_partitions
+)
+{
+ _Objects_Initialize_information(
+ &_Partition_Information, /* object information table */
+ OBJECTS_CLASSIC_API, /* object API */
+ OBJECTS_RTEMS_PARTITIONS, /* object class */
+ maximum_partitions, /* maximum objects of this class */
+ sizeof( Partition_Control ), /* size of this object's control block */
+ FALSE, /* TRUE if the name is a string */
+ RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ TRUE, /* TRUE if this is a global object class */
+ _Partition_MP_Send_extract_proxy /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Register the MP Process Packet routine.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _MPCI_Register_packet_processor(
+ MP_PACKET_PARTITION,
+ _Partition_MP_Process_packet
+ );
+#endif
+
+}
diff --git a/cpukit/rtems/src/partcreate.c b/cpukit/rtems/src/partcreate.c
new file mode 100644
index 0000000000..d77586fc76
--- /dev/null
+++ b/cpukit/rtems/src/partcreate.c
@@ -0,0 +1,129 @@
+/*
+ * Partition Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/part.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_partition_create
+ *
+ * This directive creates a partiton of fixed sized buffers from the
+ * given contiguous memory area.
+ *
+ * Input parameters:
+ * name - user defined partition name
+ * starting_address - physical start address of partition
+ * length - physical length in bytes
+ * buffer_size - size of buffers in bytes
+ * attribute_set - partition attributes
+ * id - pointer to partition id
+ *
+ * Output parameters:
+ * id - partition id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_partition_create(
+ rtems_name name,
+ void *starting_address,
+ uint32_t length,
+ uint32_t buffer_size,
+ rtems_attribute attribute_set,
+ Objects_Id *id
+)
+{
+ register Partition_Control *the_partition;
+
+ if ( !rtems_is_name_valid( name ) )
+ return RTEMS_INVALID_NAME;
+
+ if ( !starting_address )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( !id )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( length == 0 || buffer_size == 0 || length < buffer_size ||
+ !_Partition_Is_buffer_size_aligned( buffer_size ) )
+ return RTEMS_INVALID_SIZE;
+
+ if ( !_Addresses_Is_aligned( starting_address ) )
+ return RTEMS_INVALID_ADDRESS;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Attributes_Is_global( attribute_set ) &&
+ !_System_state_Is_multiprocessing )
+ return RTEMS_MP_NOT_CONFIGURED;
+#endif
+
+ _Thread_Disable_dispatch(); /* prevents deletion */
+
+ the_partition = _Partition_Allocate();
+
+ if ( !the_partition ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Attributes_Is_global( attribute_set ) &&
+ !( _Objects_MP_Allocate_and_open( &_Partition_Information, name,
+ the_partition->Object.id, FALSE ) ) ) {
+ _Partition_Free( the_partition );
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+#endif
+
+ the_partition->starting_address = starting_address;
+ the_partition->length = length;
+ the_partition->buffer_size = buffer_size;
+ the_partition->attribute_set = attribute_set;
+ the_partition->number_of_used_blocks = 0;
+
+ _Chain_Initialize( &the_partition->Memory, starting_address,
+ length / buffer_size, buffer_size );
+
+ _Objects_Open(
+ &_Partition_Information,
+ &the_partition->Object,
+ (Objects_Name) name
+ );
+
+ *id = the_partition->Object.id;
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Attributes_Is_global( attribute_set ) )
+ _Partition_MP_Send_process_packet(
+ PARTITION_MP_ANNOUNCE_CREATE,
+ the_partition->Object.id,
+ name,
+ 0 /* Not used */
+ );
+#endif
+
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/partdelete.c b/cpukit/rtems/src/partdelete.c
new file mode 100644
index 0000000000..a55c609711
--- /dev/null
+++ b/cpukit/rtems/src/partdelete.c
@@ -0,0 +1,91 @@
+/*
+ * Partition Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/part.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_partition_delete
+ *
+ * This directive allows a thread to delete a partition specified by
+ * the partition identifier, provided that none of its buffers are
+ * still allocated.
+ *
+ * Input parameters:
+ * id - partition id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_partition_delete(
+ Objects_Id id
+)
+{
+ register Partition_Control *the_partition;
+ Objects_Locations location;
+
+ the_partition = _Partition_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( the_partition->number_of_used_blocks == 0 ) {
+ _Objects_Close( &_Partition_Information, &the_partition->Object );
+ _Partition_Free( the_partition );
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Attributes_Is_global( the_partition->attribute_set ) ) {
+
+ _Objects_MP_Close(
+ &_Partition_Information,
+ the_partition->Object.id
+ );
+
+ _Partition_MP_Send_process_packet(
+ PARTITION_MP_ANNOUNCE_DELETE,
+ the_partition->Object.id,
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+ }
+#endif
+
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_RESOURCE_IN_USE;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/partgetbuffer.c b/cpukit/rtems/src/partgetbuffer.c
new file mode 100644
index 0000000000..90dd726ecd
--- /dev/null
+++ b/cpukit/rtems/src/partgetbuffer.c
@@ -0,0 +1,86 @@
+/*
+ * Partition Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/part.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_partition_get_buffer
+ *
+ * This directive will obtain a buffer from a buffer partition.
+ *
+ * Input parameters:
+ * id - partition id
+ * buffer - pointer to buffer address
+ *
+ * Output parameters:
+ * buffer - pointer to buffer address filled in
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_partition_get_buffer(
+ Objects_Id id,
+ void **buffer
+)
+{
+ register Partition_Control *the_partition;
+ Objects_Locations location;
+ void *the_buffer;
+
+ if ( !buffer )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_partition = _Partition_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Executing->Wait.return_argument = buffer;
+ return(
+ _Partition_MP_Send_request_packet(
+ PARTITION_MP_GET_BUFFER_REQUEST,
+ id,
+ 0 /* Not used */
+ )
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ the_buffer = _Partition_Allocate_buffer( the_partition );
+ if ( the_buffer ) {
+ the_partition->number_of_used_blocks += 1;
+ _Thread_Enable_dispatch();
+ *buffer = the_buffer;
+ return RTEMS_SUCCESSFUL;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_UNSATISFIED;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/partident.c b/cpukit/rtems/src/partident.c
new file mode 100644
index 0000000000..157a634912
--- /dev/null
+++ b/cpukit/rtems/src/partident.c
@@ -0,0 +1,62 @@
+/*
+ * Partition Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/part.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_partition_ident
+ *
+ * This directive returns the system ID associated with
+ * the partition name.
+ *
+ * Input parameters:
+ * name - user defined partition name
+ * node - node(s) to be searched
+ * id - pointer to partition id
+ *
+ * Output parameters:
+ * *id - partition id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_partition_ident(
+ rtems_name name,
+ uint32_t node,
+ Objects_Id *id
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ status = _Objects_Name_to_id(
+ &_Partition_Information,
+ (Objects_Name) name,
+ node,
+ id
+ );
+
+ return _Status_Object_name_errors_to_status[ status ];
+}
diff --git a/cpukit/rtems/src/partmp.c b/cpukit/rtems/src/partmp.c
new file mode 100644
index 0000000000..c69272dd81
--- /dev/null
+++ b/cpukit/rtems/src/partmp.c
@@ -0,0 +1,307 @@
+/*
+ * Multiprocessing Support for the Partition Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/score/mpci.h>
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/part.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * _Partition_MP_Send_process_packet
+ *
+ */
+
+void _Partition_MP_Send_process_packet (
+ Partition_MP_Remote_operations operation,
+ Objects_Id partition_id,
+ rtems_name name,
+ Objects_Id proxy_id
+)
+{
+ Partition_MP_Packet *the_packet;
+ uint32_t node;
+
+ switch ( operation ) {
+
+ case PARTITION_MP_ANNOUNCE_CREATE:
+ case PARTITION_MP_ANNOUNCE_DELETE:
+ case PARTITION_MP_EXTRACT_PROXY:
+
+ the_packet = _Partition_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_PARTITION;
+ the_packet->Prefix.length = sizeof ( Partition_MP_Packet );
+ the_packet->Prefix.to_convert = sizeof ( Partition_MP_Packet );
+ the_packet->operation = operation;
+ the_packet->Prefix.id = partition_id;
+ the_packet->name = name;
+ the_packet->proxy_id = proxy_id;
+
+ if ( operation == PARTITION_MP_EXTRACT_PROXY )
+ node = rtems_get_node( partition_id );
+ else
+ node = MPCI_ALL_NODES;
+
+ _MPCI_Send_process_packet( node, &the_packet->Prefix );
+ break;
+
+ case PARTITION_MP_GET_BUFFER_REQUEST:
+ case PARTITION_MP_GET_BUFFER_RESPONSE:
+ case PARTITION_MP_RETURN_BUFFER_REQUEST:
+ case PARTITION_MP_RETURN_BUFFER_RESPONSE:
+ break;
+ }
+}
+
+/*PAGE
+ *
+ * _Partition_MP_Send_request_packet
+ *
+ */
+
+rtems_status_code _Partition_MP_Send_request_packet (
+ Partition_MP_Remote_operations operation,
+ Objects_Id partition_id,
+ void *buffer
+)
+{
+ Partition_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case PARTITION_MP_GET_BUFFER_REQUEST:
+ case PARTITION_MP_RETURN_BUFFER_REQUEST:
+
+ the_packet = _Partition_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_PARTITION;
+ the_packet->Prefix.length = sizeof ( Partition_MP_Packet );
+ the_packet->Prefix.to_convert = sizeof ( Partition_MP_Packet );
+ the_packet->operation = operation;
+ the_packet->Prefix.id = partition_id;
+ the_packet->buffer = buffer;
+
+ return
+ _MPCI_Send_request_packet(
+ rtems_get_node( partition_id ),
+ &the_packet->Prefix,
+ STATES_READY /* Not used */
+ );
+
+ break;
+
+ case PARTITION_MP_ANNOUNCE_CREATE:
+ case PARTITION_MP_ANNOUNCE_DELETE:
+ case PARTITION_MP_EXTRACT_PROXY:
+ case PARTITION_MP_GET_BUFFER_RESPONSE:
+ case PARTITION_MP_RETURN_BUFFER_RESPONSE:
+ break;
+
+ }
+ /*
+ * The following line is included to satisfy compilers which
+ * produce warnings when a function does not end with a return.
+ */
+ return RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * _Partition_MP_Send_response_packet
+ *
+ */
+
+void _Partition_MP_Send_response_packet (
+ Partition_MP_Remote_operations operation,
+ Objects_Id partition_id,
+ Thread_Control *the_thread
+)
+{
+ Partition_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case PARTITION_MP_GET_BUFFER_RESPONSE:
+ case PARTITION_MP_RETURN_BUFFER_RESPONSE:
+
+ the_packet = ( Partition_MP_Packet *) the_thread->receive_packet;
+
+/*
+ * The packet being returned already contains the class, length, and
+ * to_convert fields, therefore they are not set in this routine.
+ */
+ the_packet->operation = operation;
+ the_packet->Prefix.id = the_packet->Prefix.source_tid;
+
+ _MPCI_Send_response_packet(
+ rtems_get_node( the_packet->Prefix.source_tid ),
+ &the_packet->Prefix
+ );
+ break;
+
+ case PARTITION_MP_ANNOUNCE_CREATE:
+ case PARTITION_MP_ANNOUNCE_DELETE:
+ case PARTITION_MP_EXTRACT_PROXY:
+ case PARTITION_MP_GET_BUFFER_REQUEST:
+ case PARTITION_MP_RETURN_BUFFER_REQUEST:
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ *
+ * _Partition_MP_Process_packet
+ *
+ */
+
+void _Partition_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+)
+{
+ Partition_MP_Packet *the_packet;
+ Thread_Control *the_thread;
+ boolean ignored;
+
+ the_packet = (Partition_MP_Packet *) the_packet_prefix;
+
+ switch ( the_packet->operation ) {
+
+ case PARTITION_MP_ANNOUNCE_CREATE:
+
+ ignored = _Objects_MP_Allocate_and_open(
+ &_Partition_Information,
+ the_packet->name,
+ the_packet->Prefix.id,
+ TRUE
+ );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case PARTITION_MP_ANNOUNCE_DELETE:
+
+ _Objects_MP_Close( &_Partition_Information, the_packet->Prefix.id );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case PARTITION_MP_EXTRACT_PROXY:
+
+ the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
+
+ if ( ! _Thread_Is_null( the_thread ) )
+ _Thread_queue_Extract( the_thread->Wait.queue, the_thread );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case PARTITION_MP_GET_BUFFER_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_partition_get_buffer(
+ the_packet->Prefix.id,
+ &the_packet->buffer
+ );
+
+ _Partition_MP_Send_response_packet(
+ PARTITION_MP_GET_BUFFER_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+
+ case PARTITION_MP_GET_BUFFER_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ *(void **)the_thread->Wait.return_argument = the_packet->buffer;
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case PARTITION_MP_RETURN_BUFFER_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_partition_return_buffer(
+ the_packet->Prefix.id,
+ the_packet->buffer
+ );
+
+ _Partition_MP_Send_response_packet(
+ PARTITION_MP_RETURN_BUFFER_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+
+ case PARTITION_MP_RETURN_BUFFER_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ * _Partition_MP_Send_object_was_deleted
+ *
+ * This routine is not needed by the Partition since a partition
+ * cannot be deleted when buffers are in use.
+ *
+ */
+
+/*PAGE
+ *
+ * _Partition_MP_Send_extract_proxy
+ *
+ */
+
+void _Partition_MP_Send_extract_proxy (
+ void *argument
+)
+{
+ Thread_Control *the_thread = (Thread_Control *)argument;
+
+ _Partition_MP_Send_process_packet(
+ PARTITION_MP_EXTRACT_PROXY,
+ the_thread->Wait.id,
+ (rtems_name) 0,
+ the_thread->Object.id
+ );
+
+}
+
+/*PAGE
+ *
+ * _Partition_MP_Get_packet
+ *
+ */
+
+Partition_MP_Packet *_Partition_MP_Get_packet ( void )
+{
+ return ( (Partition_MP_Packet *) _MPCI_Get_packet() );
+}
+
+/* end of file */
diff --git a/cpukit/rtems/src/partreturnbuffer.c b/cpukit/rtems/src/partreturnbuffer.c
new file mode 100644
index 0000000000..9e304b4d95
--- /dev/null
+++ b/cpukit/rtems/src/partreturnbuffer.c
@@ -0,0 +1,79 @@
+/*
+ * Partition Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/address.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/part.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_partition_return_buffer
+ *
+ * This directive will return the given buffer to the specified
+ * buffer partition.
+ *
+ * Input parameters:
+ * id - partition id
+ * buffer - pointer to buffer address
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_partition_return_buffer(
+ Objects_Id id,
+ void *buffer
+)
+{
+ register Partition_Control *the_partition;
+ Objects_Locations location;
+
+ the_partition = _Partition_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return _Partition_MP_Send_request_packet(
+ PARTITION_MP_RETURN_BUFFER_REQUEST,
+ id,
+ buffer
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( _Partition_Is_buffer_valid( buffer, the_partition ) ) {
+ _Partition_Free_buffer( the_partition, buffer );
+ the_partition->number_of_used_blocks -= 1;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/ratemon.c b/cpukit/rtems/src/ratemon.c
new file mode 100644
index 0000000000..647ee10e4a
--- /dev/null
+++ b/cpukit/rtems/src/ratemon.c
@@ -0,0 +1,61 @@
+/*
+ * Rate Monotonic Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/ratemon.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * _Rate_monotonic_Manager_initialization
+ *
+ * This routine initializes all Rate Monotonic Manager related
+ * data structures.
+ *
+ * Input parameters:
+ * maximum_periods - number of periods timers to initialize
+ *
+ * Output parameters: NONE
+ *
+ * NOTE: The Rate Monotonic Manager is built on top of the Watchdog
+ * Handler.
+ */
+
+void _Rate_monotonic_Manager_initialization(
+ uint32_t maximum_periods
+)
+{
+ _Objects_Initialize_information(
+ &_Rate_monotonic_Information, /* object information table */
+ OBJECTS_CLASSIC_API, /* object API */
+ OBJECTS_RTEMS_PERIODS, /* object class */
+ maximum_periods, /* maximum objects of this class */
+ sizeof( Rate_monotonic_Control ), /* size of this object's control block */
+ FALSE, /* TRUE if the name is a string */
+ RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+}
diff --git a/cpukit/rtems/src/ratemoncancel.c b/cpukit/rtems/src/ratemoncancel.c
new file mode 100644
index 0000000000..254a1f51f9
--- /dev/null
+++ b/cpukit/rtems/src/ratemoncancel.c
@@ -0,0 +1,68 @@
+/*
+ * Rate Monotonic Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/ratemon.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * rtems_rate_monotonic_cancel
+ *
+ * This directive allows a thread to cancel a rate monotonic timer.
+ *
+ * Input parameters:
+ * id - rate monotonic id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful and caller is not the owning thread
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_rate_monotonic_cancel(
+ Objects_Id id
+)
+{
+ Rate_monotonic_Control *the_period;
+ Objects_Locations location;
+
+ the_period = _Rate_monotonic_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+ return RTEMS_INTERNAL_ERROR; /* should never return this */
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( !_Thread_Is_executing( the_period->owner ) ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_NOT_OWNER_OF_RESOURCE;
+ }
+ (void) _Watchdog_Remove( &the_period->Timer );
+ the_period->state = RATE_MONOTONIC_INACTIVE;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/ratemoncreate.c b/cpukit/rtems/src/ratemoncreate.c
new file mode 100644
index 0000000000..5585a8ea36
--- /dev/null
+++ b/cpukit/rtems/src/ratemoncreate.c
@@ -0,0 +1,80 @@
+/*
+ * Rate Monotonic Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/ratemon.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * rtems_rate_monotonic_create
+ *
+ * This directive creates a rate monotonic timer and performs
+ * some initialization.
+ *
+ * Input parameters:
+ * name - name of period
+ * id - pointer to rate monotonic id
+ *
+ * Output parameters:
+ * id - rate monotonic id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_rate_monotonic_create(
+ rtems_name name,
+ Objects_Id *id
+)
+{
+ Rate_monotonic_Control *the_period;
+
+ if ( !rtems_is_name_valid( name ) )
+ return RTEMS_INVALID_NAME;
+
+ if ( !id )
+ return RTEMS_INVALID_ADDRESS;
+
+ _Thread_Disable_dispatch(); /* to prevent deletion */
+
+ the_period = _Rate_monotonic_Allocate();
+
+ if ( !the_period ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+
+ the_period->owner = _Thread_Executing;
+ the_period->state = RATE_MONOTONIC_INACTIVE;
+
+ _Watchdog_Initialize( &the_period->Timer, NULL, 0, NULL );
+
+ _Objects_Open(
+ &_Rate_monotonic_Information,
+ &the_period->Object,
+ (Objects_Name) name
+ );
+
+ *id = the_period->Object.id;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/ratemondelete.c b/cpukit/rtems/src/ratemondelete.c
new file mode 100644
index 0000000000..b49311acbb
--- /dev/null
+++ b/cpukit/rtems/src/ratemondelete.c
@@ -0,0 +1,66 @@
+/*
+ * Rate Monotonic Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/ratemon.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * rtems_rate_monotonic_delete
+ *
+ * This directive allows a thread to delete a rate monotonic timer.
+ *
+ * Input parameters:
+ * id - rate monotonic id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_rate_monotonic_delete(
+ Objects_Id id
+)
+{
+ Rate_monotonic_Control *the_period;
+ Objects_Locations location;
+
+ the_period = _Rate_monotonic_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ _Objects_Close( &_Rate_monotonic_Information, &the_period->Object );
+ (void) _Watchdog_Remove( &the_period->Timer );
+ the_period->state = RATE_MONOTONIC_INACTIVE;
+ _Rate_monotonic_Free( the_period );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/ratemongetstatus.c b/cpukit/rtems/src/ratemongetstatus.c
new file mode 100644
index 0000000000..e6363a7a71
--- /dev/null
+++ b/cpukit/rtems/src/ratemongetstatus.c
@@ -0,0 +1,83 @@
+/*
+ * Rate Monotonic Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/ratemon.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * rtems_rate_monotonic_get_status
+ *
+ * This directive allows a thread to obtain status information on a
+ * period.
+ *
+ * Input parameters:
+ * id - rate monotonic id
+ * status - pointer to status control block
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ *
+ */
+
+rtems_status_code rtems_rate_monotonic_get_status(
+ Objects_Id id,
+ rtems_rate_monotonic_period_status *status
+)
+{
+ Objects_Locations location;
+ Rate_monotonic_Control *the_period;
+
+ if ( !status )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_period = _Rate_monotonic_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ status->state = the_period->state;
+
+ if ( status->state == RATE_MONOTONIC_INACTIVE ) {
+ status->ticks_since_last_period = 0;
+ status->ticks_executed_since_last_period = 0;
+ } else {
+ status->ticks_since_last_period =
+ _Watchdog_Ticks_since_boot - the_period->time_at_period;
+
+ status->ticks_executed_since_last_period =
+ the_period->owner->ticks_executed -
+ the_period->owner_ticks_executed_at_period;
+ }
+
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/ratemonident.c b/cpukit/rtems/src/ratemonident.c
new file mode 100644
index 0000000000..b81b92042e
--- /dev/null
+++ b/cpukit/rtems/src/ratemonident.c
@@ -0,0 +1,59 @@
+/*
+ * Rate Monotonic Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/ratemon.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * rtems_rate_monotonic_ident
+ *
+ * This directive returns the system ID associated with
+ * the rate monotonic period name.
+ *
+ * Input parameters:
+ * name - user defined period name
+ * id - pointer to period id
+ *
+ * Output parameters:
+ * *id - region id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_rate_monotonic_ident(
+ rtems_name name,
+ Objects_Id *id
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ status = _Objects_Name_to_id(
+ &_Rate_monotonic_Information,
+ (Objects_Name) name,
+ OBJECTS_SEARCH_LOCAL_NODE,
+ id
+ );
+
+ return _Status_Object_name_errors_to_status[ status ];
+}
diff --git a/cpukit/rtems/src/ratemonperiod.c b/cpukit/rtems/src/ratemonperiod.c
new file mode 100644
index 0000000000..e722c41ca7
--- /dev/null
+++ b/cpukit/rtems/src/ratemonperiod.c
@@ -0,0 +1,167 @@
+/*
+ * Rate Monotonic Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/ratemon.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * rtems_rate_monotonic_period
+ *
+ * This directive allows a thread to manipulate a rate monotonic timer.
+ *
+ * Input parameters:
+ * id - rate monotonic id
+ * length - length of period (in ticks)
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_rate_monotonic_period(
+ Objects_Id id,
+ rtems_interval length
+)
+{
+ Rate_monotonic_Control *the_period;
+ Objects_Locations location;
+ rtems_status_code return_value;
+ rtems_rate_monotonic_period_states local_state;
+ ISR_Level level;
+
+ the_period = _Rate_monotonic_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( !_Thread_Is_executing( the_period->owner ) ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_NOT_OWNER_OF_RESOURCE;
+ }
+
+ if ( length == RTEMS_PERIOD_STATUS ) {
+ switch ( the_period->state ) {
+ case RATE_MONOTONIC_INACTIVE:
+ return_value = RTEMS_NOT_DEFINED;
+ break;
+ case RATE_MONOTONIC_ACTIVE:
+ return_value = RTEMS_SUCCESSFUL;
+ break;
+ case RATE_MONOTONIC_EXPIRED:
+ return_value = RTEMS_TIMEOUT;
+ break;
+ default: /* unreached -- only to remove warnings */
+ return_value = RTEMS_INTERNAL_ERROR;
+ break;
+ }
+ _Thread_Enable_dispatch();
+ return( return_value );
+ }
+
+ _ISR_Disable( level );
+ switch ( the_period->state ) {
+ case RATE_MONOTONIC_INACTIVE:
+ _ISR_Enable( level );
+ the_period->state = RATE_MONOTONIC_ACTIVE;
+ _Watchdog_Initialize(
+ &the_period->Timer,
+ _Rate_monotonic_Timeout,
+ id,
+ NULL
+ );
+
+ the_period->owner_ticks_executed_at_period =
+ _Thread_Executing->ticks_executed;
+
+ the_period->time_at_period = _Watchdog_Ticks_since_boot;
+ the_period->next_length = length;
+
+ _Watchdog_Insert_ticks( &the_period->Timer, length );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+
+ case RATE_MONOTONIC_ACTIVE:
+ /*
+ * This tells the _Rate_monotonic_Timeout that this task is
+ * in the process of blocking on the period and that we
+ * may be changing the length of the next period.
+ */
+
+ the_period->state = RATE_MONOTONIC_OWNER_IS_BLOCKING;
+ the_period->next_length = length;
+
+ _ISR_Enable( level );
+
+ _Thread_Executing->Wait.id = the_period->Object.id;
+ _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD );
+
+ /*
+ * Did the watchdog timer expire while we were actually blocking
+ * on it?
+ */
+
+ _ISR_Disable( level );
+ local_state = the_period->state;
+ the_period->state = RATE_MONOTONIC_ACTIVE;
+ _ISR_Enable( level );
+
+ /*
+ * If it did, then we want to unblock ourself and continue as
+ * if nothing happen. The period was reset in the timeout routine.
+ */
+
+ if ( local_state == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING )
+ _Thread_Clear_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD );
+
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ break;
+
+ case RATE_MONOTONIC_EXPIRED:
+ _ISR_Enable( level );
+ the_period->state = RATE_MONOTONIC_ACTIVE;
+ the_period->owner_ticks_executed_at_period =
+ _Thread_Executing->ticks_executed;
+ the_period->time_at_period = _Watchdog_Ticks_since_boot;
+ the_period->next_length = length;
+
+ _Watchdog_Insert_ticks( &the_period->Timer, length );
+ _Thread_Enable_dispatch();
+ return RTEMS_TIMEOUT;
+
+ case RATE_MONOTONIC_OWNER_IS_BLOCKING:
+ case RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING:
+ /*
+ * These should never happen.
+ */
+ break;
+ }
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/ratemontimeout.c b/cpukit/rtems/src/ratemontimeout.c
new file mode 100644
index 0000000000..deb9a18bc6
--- /dev/null
+++ b/cpukit/rtems/src/ratemontimeout.c
@@ -0,0 +1,85 @@
+/*
+ * Rate Monotonic Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/ratemon.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * _Rate_monotonic_Timeout
+ *
+ * This routine processes a period ending. If the owning thread
+ * is waiting for the period, that thread is unblocked and the
+ * period reinitiated. Otherwise, the period is expired.
+ * This routine is called by the watchdog handler.
+ *
+ * Input parameters:
+ * id - period id
+ *
+ * Output parameters: NONE
+ */
+
+void _Rate_monotonic_Timeout(
+ Objects_Id id,
+ void *ignored
+)
+{
+ Rate_monotonic_Control *the_period;
+ Objects_Locations location;
+ Thread_Control *the_thread;
+
+ /*
+ * When we get here, the Timer is already off the chain so we do not
+ * have to worry about that -- hence no _Watchdog_Remove().
+ */
+
+ the_period = _Rate_monotonic_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* impossible */
+ case OBJECTS_ERROR:
+ break;
+
+ case OBJECTS_LOCAL:
+ the_thread = the_period->owner;
+ if ( _States_Is_waiting_for_period( the_thread->current_state ) &&
+ the_thread->Wait.id == the_period->Object.id ) {
+ _Thread_Unblock( the_thread );
+ the_period->owner_ticks_executed_at_period =
+ the_thread->ticks_executed;
+
+ the_period->time_at_period = _Watchdog_Ticks_since_boot;
+
+ _Watchdog_Insert_ticks( &the_period->Timer, the_period->next_length );
+ } else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING ) {
+ the_period->state = RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING;
+ the_period->owner_ticks_executed_at_period =
+ the_thread->ticks_executed;
+
+ the_period->time_at_period = _Watchdog_Ticks_since_boot;
+ _Watchdog_Insert_ticks( &the_period->Timer, the_period->next_length );
+ } else
+ the_period->state = RATE_MONOTONIC_EXPIRED;
+ _Thread_Unnest_dispatch();
+ break;
+ }
+}
diff --git a/cpukit/rtems/src/region.c b/cpukit/rtems/src/region.c
new file mode 100644
index 0000000000..f8e9de5e6e
--- /dev/null
+++ b/cpukit/rtems/src/region.c
@@ -0,0 +1,75 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apimutex.h>
+
+/*PAGE
+ *
+ * _Region_Manager_initialization
+ *
+ * This routine initializes all region manager related data structures.
+ *
+ * Input parameters:
+ * maximum_regions - number of regions to initialize
+ *
+ * Output parameters: NONE
+ */
+
+void _Region_Manager_initialization(
+ uint32_t maximum_regions
+)
+{
+ /* XXX move me */
+ _API_Mutex_Initialization( 1 );
+ _API_Mutex_Allocate( _RTEMS_Allocator_Mutex );
+
+ _Objects_Initialize_information(
+ &_Region_Information, /* object information table */
+ OBJECTS_CLASSIC_API, /* object API */
+ OBJECTS_RTEMS_REGIONS, /* object class */
+ maximum_regions, /* maximum objects of this class */
+ sizeof( Region_Control ), /* size of this object's control block */
+ FALSE, /* TRUE if the name is a string */
+ RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Register the MP Process Packet routine.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _MPCI_Register_packet_processor(
+ MP_PACKET_REGION,
+ 0 /* XXX _Region_MP_Process_packet */
+ );
+#endif
+
+}
diff --git a/cpukit/rtems/src/regioncreate.c b/cpukit/rtems/src/regioncreate.c
new file mode 100644
index 0000000000..1f4b8ae94b
--- /dev/null
+++ b/cpukit/rtems/src/regioncreate.c
@@ -0,0 +1,114 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apimutex.h>
+
+/*PAGE
+ *
+ * rtems_region_create
+ *
+ * This directive creates a region of physical contiguous memory area
+ * from which variable sized segments can be allocated.
+ *
+ * Input parameters:
+ * name - user defined region name
+ * starting_address - physical start address of region
+ * length - physical length in bytes
+ * page_size - page size in bytes
+ * attribute_set - region attributes
+ * id - address of region id to set
+ *
+ * Output parameters:
+ * id - region id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_region_create(
+ rtems_name name,
+ void *starting_address,
+ uint32_t length,
+ uint32_t page_size,
+ rtems_attribute attribute_set,
+ Objects_Id *id
+)
+{
+ Region_Control *the_region;
+
+ if ( !rtems_is_name_valid( name ) )
+ return RTEMS_INVALID_NAME;
+
+ if ( !starting_address )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( !id )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( !_Addresses_Is_aligned( starting_address ) )
+ return RTEMS_INVALID_ADDRESS;
+
+ _RTEMS_Lock_allocator(); /* to prevent deletion */
+
+ the_region = _Region_Allocate();
+
+ if ( !the_region ) {
+ _RTEMS_Unlock_allocator();
+ return RTEMS_TOO_MANY;
+ }
+
+ the_region->maximum_segment_size =
+ _Heap_Initialize(&the_region->Memory, starting_address, length, page_size);
+
+ if ( !the_region->maximum_segment_size ) {
+ _Region_Free( the_region );
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_SIZE;
+ }
+
+ the_region->starting_address = starting_address;
+ the_region->length = length;
+ the_region->page_size = page_size;
+ the_region->attribute_set = attribute_set;
+ the_region->number_of_used_blocks = 0;
+
+ _Thread_queue_Initialize(
+ &the_region->Wait_queue,
+ _Attributes_Is_priority( attribute_set ) ?
+ THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
+ STATES_WAITING_FOR_SEGMENT,
+ RTEMS_TIMEOUT
+ );
+
+ _Objects_Open(
+ &_Region_Information,
+ &the_region->Object,
+ (Objects_Name) name
+ );
+
+ *id = the_region->Object.id;
+ _RTEMS_Unlock_allocator();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/regiondelete.c b/cpukit/rtems/src/regiondelete.c
new file mode 100644
index 0000000000..61409aa229
--- /dev/null
+++ b/cpukit/rtems/src/regiondelete.c
@@ -0,0 +1,76 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apimutex.h>
+
+/*PAGE
+ *
+ * rtems_region_delete
+ *
+ * This directive allows a thread to delete a region specified by
+ * the region identifier, provided that none of its segments are
+ * still allocated.
+ *
+ * Input parameters:
+ * id - region id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_region_delete(
+ Objects_Id id
+)
+{
+ register Region_Control *the_region;
+ Objects_Locations location;
+
+ _RTEMS_Lock_allocator();
+ the_region = _Region_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* this error cannot be returned */
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ _Region_Debug_Walk( the_region, 5 );
+ if ( the_region->number_of_used_blocks == 0 ) {
+ _Objects_Close( &_Region_Information, &the_region->Object );
+ _Region_Free( the_region );
+ _RTEMS_Unlock_allocator();
+ return RTEMS_SUCCESSFUL;
+ }
+ _RTEMS_Unlock_allocator();
+ return RTEMS_RESOURCE_IN_USE;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/regionextend.c b/cpukit/rtems/src/regionextend.c
new file mode 100644
index 0000000000..25883e4c28
--- /dev/null
+++ b/cpukit/rtems/src/regionextend.c
@@ -0,0 +1,100 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apimutex.h>
+
+/*PAGE
+ *
+ * rtems_region_extend
+ *
+ * This directive attempts to grow a region of physical contiguous memory area
+ * from which variable sized segments can be allocated.
+ *
+ * Input parameters:
+ * id - id of region to grow
+ * start - starting address of memory area for extension
+ * length - physical length in bytes to grow the region
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_region_extend(
+ Objects_Id id,
+ void *starting_address,
+ uint32_t length
+)
+{
+ Region_Control *the_region;
+ Objects_Locations location;
+ uint32_t amount_extended;
+ Heap_Extend_status heap_status;
+ rtems_status_code status;
+
+ if ( !starting_address )
+ return RTEMS_INVALID_ADDRESS;
+
+ status = RTEMS_SUCCESSFUL;
+
+ _RTEMS_Lock_allocator(); /* to prevent deletion */
+ the_region = _Region_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* this error cannot be returned */
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+
+ heap_status = _Heap_Extend(
+ &the_region->Memory,
+ starting_address,
+ length,
+ &amount_extended
+ );
+
+ switch ( heap_status ) {
+ case HEAP_EXTEND_SUCCESSFUL:
+ the_region->length += amount_extended;
+ the_region->maximum_segment_size += amount_extended;
+ break;
+ case HEAP_EXTEND_ERROR:
+ status = RTEMS_INVALID_ADDRESS;
+ break;
+ case HEAP_EXTEND_NOT_IMPLEMENTED:
+ status = RTEMS_NOT_IMPLEMENTED;
+ break;
+ }
+ _RTEMS_Unlock_allocator();
+ return( status );
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/regiongetfreeinfo.c b/cpukit/rtems/src/regiongetfreeinfo.c
new file mode 100644
index 0000000000..153f965d8c
--- /dev/null
+++ b/cpukit/rtems/src/regiongetfreeinfo.c
@@ -0,0 +1,82 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/apimutex.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * rtems_region_get_free_information
+ *
+ * This directive will return information about the free blocks
+ * in the region specified. Information about the used blocks
+ * will be returned as zero.
+ *
+ * Input parameters:
+ * id - region id
+ * the_info - pointer to region information block
+ *
+ * Output parameters:
+ * *the_info - region information block filled in
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_region_get_free_information(
+ Objects_Id id,
+ Heap_Information_block *the_info
+)
+{
+ register Region_Control *the_region;
+ Objects_Locations location;
+
+ if ( !the_info )
+ return RTEMS_INVALID_ADDRESS;
+
+ _RTEMS_Lock_allocator();
+ the_region = _Region_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* this error cannot be returned */
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+
+ the_info->Used.number = 0;
+ the_info->Used.total = 0;
+ the_info->Used.largest = 0;
+
+ _Heap_Get_free_information( &the_region->Memory, &the_info->Free );
+
+ _RTEMS_Unlock_allocator();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/regiongetinfo.c b/cpukit/rtems/src/regiongetinfo.c
new file mode 100644
index 0000000000..3b0497fce8
--- /dev/null
+++ b/cpukit/rtems/src/regiongetinfo.c
@@ -0,0 +1,79 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/apimutex.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * rtems_region_get_information
+ *
+ * This directive will return information about the region specified.
+ *
+ * Input parameters:
+ * id - region id
+ * the_info - pointer to region information block
+ *
+ * Output parameters:
+ * *the_info - region information block filled in
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_region_get_information(
+ Objects_Id id,
+ Heap_Information_block *the_info
+)
+{
+ register Region_Control *the_region;
+ Objects_Locations location;
+
+ if ( !the_info )
+ return RTEMS_INVALID_ADDRESS;
+
+ _RTEMS_Lock_allocator();
+ the_region = _Region_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* this error cannot be returned */
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+
+ if ( _Heap_Get_information( &the_region->Memory, the_info ) ==
+ HEAP_GET_INFORMATION_SUCCESSFUL ) {
+ _RTEMS_Unlock_allocator();
+ return RTEMS_SUCCESSFUL;
+ }
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/regiongetsegment.c b/cpukit/rtems/src/regiongetsegment.c
new file mode 100644
index 0000000000..c9793af31f
--- /dev/null
+++ b/cpukit/rtems/src/regiongetsegment.c
@@ -0,0 +1,128 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apimutex.h>
+
+/*PAGE
+ *
+ * rtems_region_get_segment
+ *
+ * This directive will obtain a segment from the given region.
+ *
+ * Input parameters:
+ * id - region id
+ * size - segment size in bytes
+ * option_set - wait option
+ * timeout - number of ticks to wait (0 means wait forever)
+ * segment - pointer to segment address
+ *
+ * Output parameters:
+ * segment - pointer to segment address filled in
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_region_get_segment(
+ Objects_Id id,
+ uint32_t size,
+ rtems_option option_set,
+ rtems_interval timeout,
+ void **segment
+)
+{
+ register Region_Control *the_region;
+ Objects_Locations location;
+ Thread_Control *executing;
+ void *the_segment;
+
+ if ( !segment )
+ return RTEMS_INVALID_ADDRESS;
+
+ *segment = NULL;
+
+ if ( size == 0 )
+ return RTEMS_INVALID_SIZE;
+
+ _RTEMS_Lock_allocator();
+ executing = _Thread_Executing;
+ the_region = _Region_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* this error cannot be returned */
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( size > the_region->maximum_segment_size ) {
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_SIZE;
+ }
+
+ _Region_Debug_Walk( the_region, 1 );
+
+ the_segment = _Region_Allocate_segment( the_region, size );
+
+ _Region_Debug_Walk( the_region, 2 );
+
+ if ( the_segment ) {
+ the_region->number_of_used_blocks += 1;
+ _RTEMS_Unlock_allocator();
+ *segment = the_segment;
+ return RTEMS_SUCCESSFUL;
+ }
+
+ if ( _Options_Is_no_wait( option_set ) ) {
+ _RTEMS_Unlock_allocator();
+ return RTEMS_UNSATISFIED;
+ }
+
+ /*
+ * Switch from using the memory allocation mutex to using a
+ * dispatching disabled critical section. We have to do this
+ * because this thread is going to block.
+ */
+ _Thread_Disable_dispatch();
+ _RTEMS_Unlock_allocator();
+
+ executing->Wait.queue = &the_region->Wait_queue;
+ executing->Wait.id = id;
+ executing->Wait.count = size;
+ executing->Wait.return_argument = segment;
+
+ _Thread_queue_Enter_critical_section( &the_region->Wait_queue );
+
+ _Thread_queue_Enqueue( &the_region->Wait_queue, timeout );
+
+ _Thread_Enable_dispatch();
+
+ return (rtems_status_code) executing->Wait.return_code;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/regiongetsegmentsize.c b/cpukit/rtems/src/regiongetsegmentsize.c
new file mode 100644
index 0000000000..b7792eac09
--- /dev/null
+++ b/cpukit/rtems/src/regiongetsegmentsize.c
@@ -0,0 +1,85 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apimutex.h>
+
+/*PAGE
+ *
+ * rtems_region_get_segment_size
+ *
+ * This directive will return the size of the segment indicated
+ *
+ * Input parameters:
+ * id - region id
+ * segment - segment address
+ * size - pointer to segment size in bytes
+ *
+ * Output parameters:
+ * size - segment size in bytes filled in
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_region_get_segment_size(
+ Objects_Id id,
+ void *segment,
+ size_t *size
+)
+{
+ register Region_Control *the_region;
+ Objects_Locations location;
+ Thread_Control *executing;
+
+ if ( !segment )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( !size )
+ return RTEMS_INVALID_ADDRESS;
+
+ _RTEMS_Lock_allocator();
+ executing = _Thread_Executing;
+ the_region = _Region_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* this error cannot be returned */
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+
+ if ( _Heap_Size_of_user_area( &the_region->Memory, segment, size ) ) {
+ _RTEMS_Unlock_allocator();
+ return RTEMS_SUCCESSFUL;
+ }
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/regionident.c b/cpukit/rtems/src/regionident.c
new file mode 100644
index 0000000000..f60903c150
--- /dev/null
+++ b/cpukit/rtems/src/regionident.c
@@ -0,0 +1,61 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apimutex.h>
+
+/*PAGE
+ *
+ * rtems_region_ident
+ *
+ * This directive returns the system ID associated with
+ * the region name.
+ *
+ * Input parameters:
+ * name - user defined region name
+ * id - pointer to region id
+ *
+ * Output parameters:
+ * *id - region id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_region_ident(
+ rtems_name name,
+ Objects_Id *id
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ status = _Objects_Name_to_id(
+ &_Region_Information,
+ (Objects_Name) name,
+ OBJECTS_SEARCH_LOCAL_NODE,
+ id
+ );
+
+ return _Status_Object_name_errors_to_status[ status ];
+}
diff --git a/cpukit/rtems/src/regionmp.c b/cpukit/rtems/src/regionmp.c
new file mode 100644
index 0000000000..6971b05c10
--- /dev/null
+++ b/cpukit/rtems/src/regionmp.c
@@ -0,0 +1,315 @@
+/*
+ * Multiprocessing Support for the Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/score/mpci.h>
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * _Region_MP_Send_process_packet
+ *
+ */
+
+void _Region_MP_Send_process_packet (
+ Region_MP_Remote_operations operation,
+ Objects_Id region_id,
+ rtems_name name,
+ Objects_Id proxy_id
+)
+{
+ Region_MP_Packet *the_packet;
+ uint32_t node;
+
+ switch ( operation ) {
+
+ case REGION_MP_ANNOUNCE_CREATE:
+ case REGION_MP_ANNOUNCE_DELETE:
+ case REGION_MP_EXTRACT_PROXY:
+
+ the_packet = _Region_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_REGION;
+ the_packet->Prefix.length = sizeof ( Region_MP_Packet );
+ the_packet->Prefix.to_convert = sizeof ( Region_MP_Packet );
+ the_packet->operation = operation;
+ the_packet->Prefix.id = region_id;
+ the_packet->name = name;
+ the_packet->proxy_id = proxy_id;
+
+ if ( operation == REGION_MP_EXTRACT_PROXY )
+ node = rtems_get_node( region_id );
+ else
+ node = MPCI_ALL_NODES;
+
+ _MPCI_Send_process_packet( node, &the_packet->Prefix );
+ break;
+
+ case REGION_MP_GET_SEGMENT_REQUEST:
+ case REGION_MP_GET_SEGMENT_RESPONSE:
+ case REGION_MP_RETURN_SEGMENT_REQUEST:
+ case REGION_MP_RETURN_SEGMENT_RESPONSE:
+ break;
+ }
+}
+
+/*PAGE
+ *
+ * _Region_MP_Send_request_packet
+ *
+ */
+
+rtems_status_code _Region_MP_Send_request_packet (
+ Region_MP_Remote_operations operation,
+ Objects_Id region_id,
+ void *segment,
+ uint32_t size,
+ rtems_option option_set,
+ rtems_interval timeout
+)
+{
+ Region_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case REGION_MP_GET_SEGMENT_REQUEST:
+ case REGION_MP_RETURN_SEGMENT_REQUEST:
+
+ the_packet = _Region_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_REGION;
+ the_packet->Prefix.length = sizeof ( Region_MP_Packet );
+ the_packet->Prefix.to_convert = sizeof ( Region_MP_Packet );
+ if ( ! _Options_Is_no_wait(option_set))
+ the_packet->Prefix.timeout = timeout;
+
+ the_packet->operation = operation;
+ the_packet->Prefix.id = region_id;
+ the_packet->segment = segment;
+ the_packet->size = size;
+ the_packet->option_set = option_set;
+
+ return (rtems_status_code) _MPCI_Send_request_packet(
+ rtems_get_node( region_id ),
+ &the_packet->Prefix,
+ STATES_READY /* Not used */
+ );
+ break;
+
+ case REGION_MP_ANNOUNCE_CREATE:
+ case REGION_MP_ANNOUNCE_DELETE:
+ case REGION_MP_EXTRACT_PROXY:
+ case REGION_MP_GET_SEGMENT_RESPONSE:
+ case REGION_MP_RETURN_SEGMENT_RESPONSE:
+ break;
+
+ }
+ /*
+ * The following line is included to satisfy compilers which
+ * produce warnings when a function does not end with a return.
+ */
+ return RTEMS_INTERNAL_ERROR;
+}
+
+/*PAGE
+ *
+ * _Region_MP_Send_response_packet
+ *
+ */
+
+void _Region_MP_Send_response_packet (
+ Region_MP_Remote_operations operation,
+ Objects_Id region_id,
+ Thread_Control *the_thread
+)
+{
+ Region_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case REGION_MP_GET_SEGMENT_RESPONSE:
+ case REGION_MP_RETURN_SEGMENT_RESPONSE:
+
+ the_packet = ( Region_MP_Packet *) the_thread->receive_packet;
+
+/*
+ * The packet being returned already contains the class, length, and
+ * to_convert fields, therefore they are not set in this routine.
+ */
+ the_packet->operation = operation;
+ the_packet->Prefix.id = the_packet->Prefix.source_tid;
+
+ _MPCI_Send_response_packet(
+ rtems_get_node( the_packet->Prefix.source_tid ),
+ &the_packet->Prefix
+ );
+ break;
+
+ case REGION_MP_ANNOUNCE_CREATE:
+ case REGION_MP_ANNOUNCE_DELETE:
+ case REGION_MP_EXTRACT_PROXY:
+ case REGION_MP_GET_SEGMENT_REQUEST:
+ case REGION_MP_RETURN_SEGMENT_REQUEST:
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ *
+ * _Region_MP_Process_packet
+ *
+ */
+
+void _Region_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+)
+{
+ Region_MP_Packet *the_packet;
+ Thread_Control *the_thread;
+ boolean ignored;
+
+ the_packet = (Region_MP_Packet *) the_packet_prefix;
+
+ switch ( the_packet->operation ) {
+
+ case REGION_MP_ANNOUNCE_CREATE:
+
+ ignored = _Objects_MP_Allocate_and_open(
+ &_Region_Information,
+ the_packet->name,
+ the_packet->Prefix.id,
+ TRUE
+ );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case REGION_MP_ANNOUNCE_DELETE:
+
+ _Objects_MP_Close( &_Region_Information, the_packet->Prefix.id );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case REGION_MP_EXTRACT_PROXY:
+
+ the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
+
+ if ( ! _Thread_Is_null( the_thread ) )
+ _Thread_queue_Extract( the_thread->Wait.queue, the_thread );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case REGION_MP_GET_SEGMENT_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_region_get_segment(
+ the_packet->Prefix.id,
+ the_packet->size,
+ the_packet->option_set,
+ the_packet->Prefix.timeout,
+ &the_packet->segment
+ );
+
+ _Region_MP_Send_response_packet(
+ REGION_MP_GET_SEGMENT_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+
+ case REGION_MP_GET_SEGMENT_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ *(void **)the_thread->Wait.return_argument = the_packet->segment;
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case REGION_MP_RETURN_SEGMENT_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_region_return_segment(
+ the_packet->Prefix.id,
+ the_packet->segment
+ );
+
+ _Region_MP_Send_response_packet(
+ REGION_MP_RETURN_SEGMENT_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+
+ case REGION_MP_RETURN_SEGMENT_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ * _Region_MP_Send_object_was_deleted
+ *
+ * This routine is not needed by the Region since a region
+ * cannot be deleted when segments are in use.
+ *
+ */
+
+/*PAGE
+ *
+ * _Region_MP_Send_extract_proxy
+ *
+ */
+
+void _Region_MP_Send_extract_proxy (
+ void *argument
+)
+{
+ Thread_Control *the_thread = (Thread_Control *)argument;
+
+ _Region_MP_Send_process_packet(
+ REGION_MP_EXTRACT_PROXY,
+ the_thread->Wait.id,
+ (rtems_name) 0,
+ the_thread->Object.id
+ );
+}
+
+/*PAGE
+ *
+ * _Region_MP_Get_packet
+ *
+ */
+
+Region_MP_Packet *_Region_MP_Get_packet ( void )
+{
+ return ( (Region_MP_Packet *) _MPCI_Get_packet() );
+}
+
+/* end of file */
diff --git a/cpukit/rtems/src/regionprocessqueue.c b/cpukit/rtems/src/regionprocessqueue.c
new file mode 100644
index 0000000000..6fdb216989
--- /dev/null
+++ b/cpukit/rtems/src/regionprocessqueue.c
@@ -0,0 +1,83 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apimutex.h>
+
+/*PAGE
+ *
+ * _Region_Process_queue
+ *
+ * If enough memory is available to satisfy the rtems_region_get_segment of
+ * the first blocked task, then that task and as many subsequent tasks as
+ * possible will be unblocked with their requests satisfied.
+ *
+ * Input parameters:
+ * the_region - the region
+ *
+ * Output parameters:
+ * none
+ */
+
+void _Region_Process_queue(
+ Region_Control *the_region
+)
+{
+ Thread_Control *the_thread;
+ void *the_segment;
+ /*
+ * Switch from using the memory allocation mutex to using a
+ * dispatching disabled critical section. We have to do this
+ * because this thread may unblock one or more threads that were
+ * waiting on memory.
+ *
+ * NOTE: Be sure to disable dispatching before unlocking the mutex
+ * since we do not want to open a window where a context
+ * switch could occur.
+ */
+ _Thread_Disable_dispatch();
+ _RTEMS_Unlock_allocator();
+
+ /*
+ * NOTE: The following loop is O(n) where n is the number of
+ * threads whose memory request is satisfied.
+ */
+ for ( ; ; ) {
+ the_thread = _Thread_queue_First( &the_region->Wait_queue );
+
+ if ( the_thread == NULL )
+ break;
+
+ the_segment = (void **) _Region_Allocate_segment(
+ the_region,
+ the_thread->Wait.count
+ );
+
+ if ( the_segment == NULL )
+ break;
+
+ *(void **)the_thread->Wait.return_argument = the_segment;
+ the_region->number_of_used_blocks += 1;
+ _Thread_queue_Extract( &the_region->Wait_queue, the_thread );
+ the_thread->Wait.return_code = RTEMS_SUCCESSFUL;
+ }
+ _Thread_Enable_dispatch();
+}
diff --git a/cpukit/rtems/src/regionresizesegment.c b/cpukit/rtems/src/regionresizesegment.c
new file mode 100644
index 0000000000..b83ed2c6e6
--- /dev/null
+++ b/cpukit/rtems/src/regionresizesegment.c
@@ -0,0 +1,101 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apimutex.h>
+
+/*PAGE
+ *
+ * rtems_region_resize_segment
+ *
+ * This directive will try to resize segment to the new size 'size'
+ * "in place".
+ *
+ * Input parameters:
+ * id - region id
+ * segment - pointer to segment address
+ * size - new required size
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_region_resize_segment(
+ Objects_Id id,
+ void *segment,
+ size_t size,
+ size_t *old_size
+)
+{
+ register Region_Control *the_region;
+ Objects_Locations location;
+ Heap_Resize_status status;
+ uint32_t avail_size;
+ uint32_t osize;
+
+ if ( !old_size )
+ return RTEMS_INVALID_ADDRESS;
+
+ _RTEMS_Lock_allocator();
+ the_region = _Region_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE: /* this error cannot be returned */
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+
+ _Region_Debug_Walk( the_region, 7 );
+
+ status = _Heap_Resize_block(
+ &the_region->Memory,
+ segment,
+ (uint32_t) size,
+ &osize,
+ &avail_size
+ );
+ *old_size = (uint32_t) osize;
+
+ _Region_Debug_Walk( the_region, 8 );
+
+ if( status == HEAP_RESIZE_SUCCESSFUL && avail_size > 0 )
+ _Region_Process_queue( the_region ); /* unlocks allocator internally */
+ else
+ _RTEMS_Unlock_allocator();
+
+ return
+ (status == HEAP_RESIZE_SUCCESSFUL) ? RTEMS_SUCCESSFUL :
+ (status == HEAP_RESIZE_UNSATISFIED) ? RTEMS_UNSATISFIED :
+ RTEMS_INVALID_ADDRESS;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/regionreturnsegment.c b/cpukit/rtems/src/regionreturnsegment.c
new file mode 100644
index 0000000000..dc080e5ed5
--- /dev/null
+++ b/cpukit/rtems/src/regionreturnsegment.c
@@ -0,0 +1,106 @@
+/*
+ * Region Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef RTEMS_REGION_SHRED_ON_FREE
+#include <string.h>
+
+#ifndef RTEMS_REGION_FREE_SHRED_PATTERN
+#define RTEMS_REGION_FREE_SHRED_PATTERN 0x00
+#endif
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/region.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apimutex.h>
+
+/*PAGE
+ *
+ * rtems_region_return_segment
+ *
+ * This directive will return a segment to its region.
+ *
+ * Input parameters:
+ * id - region id
+ * segment - pointer to segment address
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_region_return_segment(
+ Objects_Id id,
+ void *segment
+)
+{
+ register Region_Control *the_region;
+ Objects_Locations location;
+#ifdef RTEMS_REGION_FREE_SHRED_PATTERN
+ uint32_t size;
+#endif
+ int status;
+
+ _RTEMS_Lock_allocator();
+ the_region = _Region_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE: /* this error cannot be returned */
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+
+ _Region_Debug_Walk( the_region, 3 );
+
+#ifdef RTEMS_REGION_FREE_SHRED_PATTERN
+ if ( _Heap_Size_of_user_area( &the_region->Memory, segment, &size ) ) {
+ memset( segment, (RTEMS_REGION_FREE_SHRED_PATTERN & 0xFF), size );
+ } else {
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ADDRESS;
+ }
+#endif
+
+ status = _Region_Free_segment( the_region, segment );
+
+ _Region_Debug_Walk( the_region, 4 );
+
+ if ( !status ) {
+ _RTEMS_Unlock_allocator();
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ the_region->number_of_used_blocks -= 1;
+
+ _Region_Process_queue(the_region); /* unlocks allocator internally */
+
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/rtclock.c b/cpukit/rtems/src/rtclock.c
new file mode 100644
index 0000000000..652f443677
--- /dev/null
+++ b/cpukit/rtems/src/rtclock.c
@@ -0,0 +1,26 @@
+/*
+ * Clock Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/clock.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/* No initialization routine */
diff --git a/cpukit/rtems/src/rtemsidtoname.c b/cpukit/rtems/src/rtemsidtoname.c
new file mode 100644
index 0000000000..6503d9f136
--- /dev/null
+++ b/cpukit/rtems/src/rtemsidtoname.c
@@ -0,0 +1,50 @@
+/*
+ * RTEMS ID To Name Lookup
+ *
+ *
+ * COPYRIGHT (c) 1989-2003.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+
+/*PAGE
+ *
+ * rtems_object_id_to_name
+ *
+ * This directive returns the name associated with the specified
+ * object ID.
+ *
+ * Input parameters:
+ * id - message queue id
+ *
+ * Output parameters:
+ * *name - user defined object name
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_object_id_to_name(
+ rtems_id id,
+ rtems_name *name
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ status = _Objects_Id_to_name( id, (Objects_Name *) name );
+
+ return _Status_Object_name_errors_to_status[ status ];
+}
diff --git a/cpukit/rtems/src/rtemstimer.c b/cpukit/rtems/src/rtemstimer.c
new file mode 100644
index 0000000000..909bb9b15a
--- /dev/null
+++ b/cpukit/rtems/src/rtemstimer.c
@@ -0,0 +1,65 @@
+/*
+ * Timer Manager
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _Timer_Manager_initialization
+ *
+ * This routine initializes all timer manager related data structures.
+ *
+ * Input parameters:
+ * maximum_timers - number of timers to initialize
+ *
+ * Output parameters: NONE
+ */
+
+void _Timer_Manager_initialization(
+ uint32_t maximum_timers
+)
+{
+ _Objects_Initialize_information(
+ &_Timer_Information, /* object information table */
+ OBJECTS_CLASSIC_API, /* object API */
+ OBJECTS_RTEMS_TIMERS, /* object class */
+ maximum_timers, /* maximum objects of this class */
+ sizeof( Timer_Control ), /* size of this object's control block */
+ FALSE, /* TRUE if the name is a string */
+ RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Initialize the pointer to the Timer Server TCB to NULL indicating
+ * that task-based timer support is not initialized.
+ */
+
+ _Timer_Server = NULL;
+}
diff --git a/cpukit/rtems/src/sem.c b/cpukit/rtems/src/sem.c
new file mode 100644
index 0000000000..96794ba821
--- /dev/null
+++ b/cpukit/rtems/src/sem.c
@@ -0,0 +1,94 @@
+/*
+ * Semaphore Manager
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the Semaphore Manager.
+ * This manager utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * Directives provided are:
+ *
+ * + create a semaphore
+ * + get an ID of a semaphore
+ * + delete a semaphore
+ * + acquire a semaphore
+ * + release a semaphore
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/score/sysstate.h>
+
+#include <rtems/score/interr.h>
+
+/*PAGE
+ *
+ * _Semaphore_Manager_initialization
+ *
+ * This routine initializes all semaphore manager related data structures.
+ *
+ * Input parameters:
+ * maximum_semaphores - maximum configured semaphores
+ *
+ * Output parameters: NONE
+ */
+
+void _Semaphore_Manager_initialization(
+ uint32_t maximum_semaphores
+)
+{
+ _Objects_Initialize_information(
+ &_Semaphore_Information, /* object information table */
+ OBJECTS_CLASSIC_API, /* object API */
+ OBJECTS_RTEMS_SEMAPHORES, /* object class */
+ maximum_semaphores, /* maximum objects of this class */
+ sizeof( Semaphore_Control ), /* size of this object's control block */
+ FALSE, /* TRUE if the name is a string */
+ RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ TRUE, /* TRUE if this is a global object class */
+ _Semaphore_MP_Send_extract_proxy /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Register the MP Process Packet routine.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _MPCI_Register_packet_processor(
+ MP_PACKET_SEMAPHORE,
+ _Semaphore_MP_Process_packet
+ );
+#endif
+
+}
diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c
new file mode 100644
index 0000000000..ec34436b87
--- /dev/null
+++ b/cpukit/rtems/src/semcreate.c
@@ -0,0 +1,230 @@
+/*
+ * Semaphore Manager
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the Semaphore Manager.
+ * This manager utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * Directives provided are:
+ *
+ * + create a semaphore
+ * + get an ID of a semaphore
+ * + delete a semaphore
+ * + acquire a semaphore
+ * + release a semaphore
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/score/sysstate.h>
+
+#include <rtems/score/interr.h>
+
+/*PAGE
+ *
+ * rtems_semaphore_create
+ *
+ * This directive creates a semaphore and sets the initial value based
+ * on the given count. A semaphore id is returned.
+ *
+ * Input parameters:
+ * name - user defined semaphore name
+ * count - initial count of semaphore
+ * attribute_set - semaphore attributes
+ * priority_ceiling - semaphore's ceiling priority
+ * id - pointer to semaphore id
+ *
+ * Output parameters:
+ * id - semaphore id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_semaphore_create(
+ rtems_name name,
+ uint32_t count,
+ rtems_attribute attribute_set,
+ rtems_task_priority priority_ceiling,
+ rtems_id *id
+)
+{
+ register Semaphore_Control *the_semaphore;
+ CORE_mutex_Attributes the_mutex_attributes;
+ CORE_semaphore_Attributes the_semaphore_attributes;
+ uint32_t lock;
+
+ if ( !rtems_is_name_valid( name ) )
+ return RTEMS_INVALID_NAME;
+
+ if ( !id )
+ return RTEMS_INVALID_ADDRESS;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Attributes_Is_global( attribute_set ) ) {
+
+ if ( !_System_state_Is_multiprocessing )
+ return RTEMS_MP_NOT_CONFIGURED;
+
+ if ( _Attributes_Is_inherit_priority( attribute_set ) )
+ return RTEMS_NOT_DEFINED;
+
+ } else
+#endif
+
+ if ( _Attributes_Is_inherit_priority( attribute_set ) ||
+ _Attributes_Is_priority_ceiling( attribute_set ) ) {
+
+ if ( ! ( (_Attributes_Is_binary_semaphore( attribute_set ) ||
+ _Attributes_Is_simple_binary_semaphore( attribute_set )) &&
+
+ _Attributes_Is_priority( attribute_set ) ) )
+ return RTEMS_NOT_DEFINED;
+
+ }
+
+ if ( !_Attributes_Is_counting_semaphore( attribute_set ) && ( count > 1 ) )
+ return RTEMS_INVALID_NUMBER;
+
+ _Thread_Disable_dispatch(); /* prevents deletion */
+
+ the_semaphore = _Semaphore_Allocate();
+
+ if ( !the_semaphore ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Attributes_Is_global( attribute_set ) &&
+ ! ( _Objects_MP_Allocate_and_open( &_Semaphore_Information, name,
+ the_semaphore->Object.id, FALSE ) ) ) {
+ _Semaphore_Free( the_semaphore );
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+#endif
+
+ the_semaphore->attribute_set = attribute_set;
+
+ /*
+ * If it is not a counting semaphore, then it is either a
+ * simple binary semaphore or a more powerful mutex style binary
+ * semaphore.
+ */
+
+ if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) {
+ if ( _Attributes_Is_inherit_priority( attribute_set ) )
+ the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
+ else if ( _Attributes_Is_priority_ceiling( attribute_set ) )
+ the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
+ else if ( _Attributes_Is_priority( attribute_set ) )
+ the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY;
+ else
+ the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
+
+
+ if ( _Attributes_Is_binary_semaphore( attribute_set ) ) {
+ the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
+
+ switch ( the_mutex_attributes.discipline ) {
+ case CORE_MUTEX_DISCIPLINES_FIFO:
+ case CORE_MUTEX_DISCIPLINES_PRIORITY:
+ the_mutex_attributes.only_owner_release = FALSE;
+ break;
+ case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
+ case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
+ the_mutex_attributes.only_owner_release = TRUE;
+ break;
+ }
+ } else {
+ the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_BLOCKS;
+ the_mutex_attributes.only_owner_release = FALSE;
+ }
+
+ the_mutex_attributes.priority_ceiling = priority_ceiling;
+
+ if ( count == 1 )
+ lock = CORE_MUTEX_UNLOCKED;
+ else
+ lock = CORE_MUTEX_LOCKED;
+
+ _CORE_mutex_Initialize(
+ &the_semaphore->Core_control.mutex,
+ &the_mutex_attributes,
+ lock
+ );
+ } else {
+ if ( _Attributes_Is_priority( attribute_set ) )
+ the_semaphore_attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY;
+ else
+ the_semaphore_attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
+
+ /*
+ * This effectively disables limit checking.
+ */
+
+ the_semaphore_attributes.maximum_count = 0xFFFFFFFF;
+
+ /*
+ * The following are just to make Purify happy.
+ */
+
+ the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
+ the_mutex_attributes.priority_ceiling = PRIORITY_MINIMUM;
+
+ _CORE_semaphore_Initialize(
+ &the_semaphore->Core_control.semaphore,
+ &the_semaphore_attributes,
+ count
+ );
+ }
+
+ _Objects_Open(
+ &_Semaphore_Information,
+ &the_semaphore->Object,
+ (Objects_Name) name
+ );
+
+ *id = the_semaphore->Object.id;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Attributes_Is_global( attribute_set ) )
+ _Semaphore_MP_Send_process_packet(
+ SEMAPHORE_MP_ANNOUNCE_CREATE,
+ the_semaphore->Object.id,
+ name,
+ 0 /* Not used */
+ );
+#endif
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c
new file mode 100644
index 0000000000..450333a51c
--- /dev/null
+++ b/cpukit/rtems/src/semdelete.c
@@ -0,0 +1,136 @@
+/*
+ * Semaphore Manager
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the Semaphore Manager.
+ * This manager utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * Directives provided are:
+ *
+ * + create a semaphore
+ * + get an ID of a semaphore
+ * + delete a semaphore
+ * + acquire a semaphore
+ * + release a semaphore
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/score/sysstate.h>
+
+#include <rtems/score/interr.h>
+
+/*PAGE
+ *
+ * rtems_semaphore_delete
+ *
+ * This directive allows a thread to delete a semaphore specified by
+ * the semaphore id. The semaphore is freed back to the inactive
+ * semaphore chain.
+ *
+ * Input parameters:
+ * id - semaphore id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#define SEMAPHORE_MP_OBJECT_WAS_DELETED _Semaphore_MP_Send_object_was_deleted
+#else
+#define SEMAPHORE_MP_OBJECT_WAS_DELETED NULL
+#endif
+
+rtems_status_code rtems_semaphore_delete(
+ rtems_id id
+)
+{
+ register Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _Semaphore_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
+ if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) &&
+ !_Attributes_Is_simple_binary_semaphore(
+ the_semaphore->attribute_set ) ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_RESOURCE_IN_USE;
+ }
+ _CORE_mutex_Flush(
+ &the_semaphore->Core_control.mutex,
+ SEMAPHORE_MP_OBJECT_WAS_DELETED,
+ CORE_MUTEX_WAS_DELETED
+ );
+ } else {
+ _CORE_semaphore_Flush(
+ &the_semaphore->Core_control.semaphore,
+ SEMAPHORE_MP_OBJECT_WAS_DELETED,
+ CORE_SEMAPHORE_WAS_DELETED
+ );
+ }
+
+ _Objects_Close( &_Semaphore_Information, &the_semaphore->Object );
+
+ _Semaphore_Free( the_semaphore );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Attributes_Is_global( the_semaphore->attribute_set ) ) {
+
+ _Objects_MP_Close( &_Semaphore_Information, the_semaphore->Object.id );
+
+ _Semaphore_MP_Send_process_packet(
+ SEMAPHORE_MP_ANNOUNCE_DELETE,
+ the_semaphore->Object.id,
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+ }
+#endif
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/semflush.c b/cpukit/rtems/src/semflush.c
new file mode 100644
index 0000000000..823dd7692f
--- /dev/null
+++ b/cpukit/rtems/src/semflush.c
@@ -0,0 +1,102 @@
+/*
+ * rtems_semaphore_flush
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the flush directive
+ * of the Semaphore Manager.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/score/sysstate.h>
+
+#include <rtems/score/interr.h>
+
+/*PAGE
+ *
+ * rtems_semaphore_flush
+ *
+ * This directive allows a thread to flush the threads
+ * pending on the semaphore.
+ *
+ * Input parameters:
+ * id - semaphore id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#define SEND_OBJECT_WAS_DELETED _Semaphore_MP_Send_object_was_deleted
+#else
+#define SEND_OBJECT_WAS_DELETED NULL
+#endif
+
+rtems_status_code rtems_semaphore_flush(
+ rtems_id id
+)
+{
+ register Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _Semaphore_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
+ _CORE_mutex_Flush(
+ &the_semaphore->Core_control.mutex,
+ SEND_OBJECT_WAS_DELETED,
+ CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT
+ );
+ } else {
+ _CORE_semaphore_Flush(
+ &the_semaphore->Core_control.semaphore,
+ SEND_OBJECT_WAS_DELETED,
+ CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT
+ );
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/semident.c b/cpukit/rtems/src/semident.c
new file mode 100644
index 0000000000..1e92823172
--- /dev/null
+++ b/cpukit/rtems/src/semident.c
@@ -0,0 +1,86 @@
+/*
+ * Semaphore Manager
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the Semaphore Manager.
+ * This manager utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * Directives provided are:
+ *
+ * + create a semaphore
+ * + get an ID of a semaphore
+ * + delete a semaphore
+ * + acquire a semaphore
+ * + release a semaphore
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/score/sysstate.h>
+
+#include <rtems/score/interr.h>
+
+/*PAGE
+ *
+ * rtems_semaphore_ident
+ *
+ * This directive returns the system ID associated with
+ * the semaphore name.
+ *
+ * Input parameters:
+ * name - user defined semaphore name
+ * node - node(s) to be searched
+ * id - pointer to semaphore id
+ *
+ * Output parameters:
+ * *id - semaphore id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_semaphore_ident(
+ rtems_name name,
+ uint32_t node,
+ rtems_id *id
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ status = _Objects_Name_to_id(
+ &_Semaphore_Information,
+ (Objects_Name) name,
+ node,
+ id
+ );
+
+ return _Status_Object_name_errors_to_status[ status ];
+}
diff --git a/cpukit/rtems/src/semmp.c b/cpukit/rtems/src/semmp.c
new file mode 100644
index 0000000000..3cade9a50c
--- /dev/null
+++ b/cpukit/rtems/src/semmp.c
@@ -0,0 +1,367 @@
+/*
+ * Multiprocessing Support for the Semaphore Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/score/mpci.h>
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * _Semaphore_MP_Send_process_packet
+ *
+ */
+
+void _Semaphore_MP_Send_process_packet (
+ Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ rtems_name name,
+ Objects_Id proxy_id
+)
+{
+ Semaphore_MP_Packet *the_packet;
+ uint32_t node;
+
+ switch ( operation ) {
+
+ case SEMAPHORE_MP_ANNOUNCE_CREATE:
+ case SEMAPHORE_MP_ANNOUNCE_DELETE:
+ case SEMAPHORE_MP_EXTRACT_PROXY:
+
+ the_packet = _Semaphore_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_SEMAPHORE;
+ the_packet->Prefix.length = sizeof ( Semaphore_MP_Packet );
+ the_packet->Prefix.to_convert = sizeof ( Semaphore_MP_Packet );
+ the_packet->operation = operation;
+ the_packet->Prefix.id = semaphore_id;
+ the_packet->name = name;
+ the_packet->proxy_id = proxy_id;
+
+ if ( operation == SEMAPHORE_MP_EXTRACT_PROXY )
+ node = rtems_get_node( semaphore_id );
+ else
+ node = MPCI_ALL_NODES;
+
+ _MPCI_Send_process_packet( node, &the_packet->Prefix );
+ break;
+
+ case SEMAPHORE_MP_OBTAIN_REQUEST:
+ case SEMAPHORE_MP_OBTAIN_RESPONSE:
+ case SEMAPHORE_MP_RELEASE_REQUEST:
+ case SEMAPHORE_MP_RELEASE_RESPONSE:
+ break;
+ }
+}
+
+/*PAGE
+ *
+ * _Semaphore_MP_Send_request_packet
+ *
+ */
+
+rtems_status_code _Semaphore_MP_Send_request_packet (
+ Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ rtems_option option_set,
+ rtems_interval timeout
+)
+{
+ Semaphore_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case SEMAPHORE_MP_OBTAIN_REQUEST:
+ case SEMAPHORE_MP_RELEASE_REQUEST:
+
+ the_packet = _Semaphore_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_SEMAPHORE;
+ the_packet->Prefix.length = sizeof ( Semaphore_MP_Packet );
+ the_packet->Prefix.to_convert = sizeof ( Semaphore_MP_Packet );
+ if ( ! _Options_Is_no_wait(option_set))
+ the_packet->Prefix.timeout = timeout;
+
+ the_packet->operation = operation;
+ the_packet->Prefix.id = semaphore_id;
+ the_packet->option_set = option_set;
+
+ return _MPCI_Send_request_packet(
+ rtems_get_node( semaphore_id ),
+ &the_packet->Prefix,
+ STATES_WAITING_FOR_SEMAPHORE
+ );
+ break;
+
+ case SEMAPHORE_MP_ANNOUNCE_CREATE:
+ case SEMAPHORE_MP_ANNOUNCE_DELETE:
+ case SEMAPHORE_MP_EXTRACT_PROXY:
+ case SEMAPHORE_MP_OBTAIN_RESPONSE:
+ case SEMAPHORE_MP_RELEASE_RESPONSE:
+ break;
+
+ }
+ /*
+ * The following line is included to satisfy compilers which
+ * produce warnings when a function does not end with a return.
+ */
+ return RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * _Semaphore_MP_Send_response_packet
+ *
+ */
+
+void _Semaphore_MP_Send_response_packet (
+ Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ Thread_Control *the_thread
+)
+{
+ Semaphore_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case SEMAPHORE_MP_OBTAIN_RESPONSE:
+ case SEMAPHORE_MP_RELEASE_RESPONSE:
+
+ the_packet = ( Semaphore_MP_Packet *) the_thread->receive_packet;
+
+/*
+ * The packet being returned already contains the class, length, and
+ * to_convert fields, therefore they are not set in this routine.
+ */
+ the_packet->operation = operation;
+ the_packet->Prefix.id = the_packet->Prefix.source_tid;
+
+ _MPCI_Send_response_packet(
+ rtems_get_node( the_packet->Prefix.source_tid ),
+ &the_packet->Prefix
+ );
+ break;
+
+ case SEMAPHORE_MP_ANNOUNCE_CREATE:
+ case SEMAPHORE_MP_ANNOUNCE_DELETE:
+ case SEMAPHORE_MP_EXTRACT_PROXY:
+ case SEMAPHORE_MP_OBTAIN_REQUEST:
+ case SEMAPHORE_MP_RELEASE_REQUEST:
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ *
+ * _Semaphore_MP_Process_packet
+ *
+ */
+
+void _Semaphore_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+)
+{
+ Semaphore_MP_Packet *the_packet;
+ Thread_Control *the_thread;
+ boolean ignored;
+
+ the_packet = (Semaphore_MP_Packet *) the_packet_prefix;
+
+ switch ( the_packet->operation ) {
+
+ case SEMAPHORE_MP_ANNOUNCE_CREATE:
+
+ ignored = _Objects_MP_Allocate_and_open(
+ &_Semaphore_Information,
+ the_packet->name,
+ the_packet->Prefix.id,
+ TRUE
+ );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case SEMAPHORE_MP_ANNOUNCE_DELETE:
+
+ _Objects_MP_Close( &_Semaphore_Information, the_packet->Prefix.id );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case SEMAPHORE_MP_EXTRACT_PROXY:
+
+ the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
+
+ if ( ! _Thread_Is_null( the_thread ) )
+ _Thread_queue_Extract( the_thread->Wait.queue, the_thread );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case SEMAPHORE_MP_OBTAIN_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_semaphore_obtain(
+ the_packet->Prefix.id,
+ the_packet->option_set,
+ the_packet->Prefix.timeout
+ );
+
+ if ( ! _Thread_Is_proxy_blocking( the_packet->Prefix.return_code ) )
+ _Semaphore_MP_Send_response_packet(
+ SEMAPHORE_MP_OBTAIN_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+
+ case SEMAPHORE_MP_OBTAIN_RESPONSE:
+ case SEMAPHORE_MP_RELEASE_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case SEMAPHORE_MP_RELEASE_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_semaphore_release(
+ the_packet->Prefix.id
+ );
+
+ _Semaphore_MP_Send_response_packet(
+ SEMAPHORE_MP_RELEASE_RESPONSE,
+ the_packet->Prefix.id,
+ _Thread_Executing
+ );
+ break;
+ }
+}
+
+/*PAGE
+ *
+ * _Semaphore_MP_Send_object_was_deleted
+ *
+ */
+
+void _Semaphore_MP_Send_object_was_deleted (
+ Thread_Control *the_proxy
+)
+{
+ the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED;
+
+ _Semaphore_MP_Send_response_packet(
+ SEMAPHORE_MP_OBTAIN_RESPONSE,
+ the_proxy->Wait.id,
+ the_proxy
+ );
+
+}
+
+/*PAGE
+ *
+ * _Semaphore_MP_Send_extract_proxy
+ *
+ */
+
+void _Semaphore_MP_Send_extract_proxy (
+ void *argument
+)
+{
+ Thread_Control *the_thread = (Thread_Control *)argument;
+
+ _Semaphore_MP_Send_process_packet(
+ SEMAPHORE_MP_EXTRACT_PROXY,
+ the_thread->Wait.id,
+ (rtems_name) 0,
+ the_thread->Object.id
+ );
+
+}
+
+/*PAGE
+ *
+ * _Semaphore_MP_Get_packet
+ *
+ */
+
+Semaphore_MP_Packet *_Semaphore_MP_Get_packet ( void )
+{
+ return ( (Semaphore_MP_Packet *) _MPCI_Get_packet() );
+}
+
+/*PAGE
+ *
+ * _Semaphore_Core_mutex_mp_support
+ *
+ * Input parameters:
+ * the_thread - the remote thread the semaphore was surrendered to
+ * id - id of the surrendered semaphore
+ *
+ * Output parameters: NONE
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+void _Semaphore_Core_mutex_mp_support (
+ Thread_Control *the_thread,
+ Objects_Id id
+)
+{
+ the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
+
+ _Semaphore_MP_Send_response_packet(
+ SEMAPHORE_MP_OBTAIN_RESPONSE,
+ id,
+ the_thread
+ );
+}
+#endif
+
+
+/*PAGE
+ *
+ * _Semaphore_Core_semaphore_mp_support
+ *
+ * Input parameters:
+ * the_thread - the remote thread the semaphore was surrendered to
+ * id - id of the surrendered semaphore
+ *
+ * Output parameters: NONE
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+void _Semaphore_Core_semaphore_mp_support (
+ Thread_Control *the_thread,
+ Objects_Id id
+)
+{
+ the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
+
+ _Semaphore_MP_Send_response_packet(
+ SEMAPHORE_MP_OBTAIN_RESPONSE,
+ id,
+ the_thread
+ );
+}
+#endif
+/* end of file */
diff --git a/cpukit/rtems/src/semobtain.c b/cpukit/rtems/src/semobtain.c
new file mode 100644
index 0000000000..72ac454de5
--- /dev/null
+++ b/cpukit/rtems/src/semobtain.c
@@ -0,0 +1,125 @@
+/*
+ * Semaphore Manager
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the Semaphore Manager.
+ * This manager utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * Directives provided are:
+ *
+ * + create a semaphore
+ * + get an ID of a semaphore
+ * + delete a semaphore
+ * + acquire a semaphore
+ * + release a semaphore
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/score/sysstate.h>
+
+#include <rtems/score/interr.h>
+
+/*PAGE
+ *
+ * rtems_semaphore_obtain
+ *
+ * This directive allows a thread to acquire a semaphore.
+ *
+ * Input parameters:
+ * id - semaphore id
+ * option_set - wait option
+ * timeout - number of ticks to wait (0 means wait forever)
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_semaphore_obtain(
+ rtems_id id,
+ uint32_t option_set,
+ rtems_interval timeout
+)
+{
+ register Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+ boolean wait;
+ ISR_Level level;
+
+ the_semaphore = _Semaphore_Get_interrupt_disable( id, &location, &level );
+ switch ( location ) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return _Semaphore_MP_Send_request_packet(
+ SEMAPHORE_MP_OBTAIN_REQUEST,
+ id,
+ option_set,
+ timeout
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( _Options_Is_no_wait( option_set ) )
+ wait = FALSE;
+ else
+ wait = TRUE;
+
+ if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
+ _CORE_mutex_Seize(
+ &the_semaphore->Core_control.mutex,
+ id,
+ wait,
+ timeout,
+ level
+ );
+ return _Semaphore_Translate_core_mutex_return_code(
+ _Thread_Executing->Wait.return_code );
+ }
+
+ /* must be a counting semaphore */
+ _CORE_semaphore_Seize_isr_disable(
+ &the_semaphore->Core_control.semaphore,
+ id,
+ wait,
+ timeout,
+ &level
+ );
+ return _Semaphore_Translate_core_semaphore_return_code(
+ _Thread_Executing->Wait.return_code );
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/semrelease.c b/cpukit/rtems/src/semrelease.c
new file mode 100644
index 0000000000..69647132c2
--- /dev/null
+++ b/cpukit/rtems/src/semrelease.c
@@ -0,0 +1,119 @@
+/*
+ * Semaphore Manager
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the Semaphore Manager.
+ * This manager utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * Directives provided are:
+ *
+ * + create a semaphore
+ * + get an ID of a semaphore
+ * + delete a semaphore
+ * + acquire a semaphore
+ * + release a semaphore
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/score/sysstate.h>
+
+#include <rtems/score/interr.h>
+
+/*PAGE
+ *
+ * rtems_semaphore_release
+ *
+ * This directive allows a thread to release a semaphore.
+ *
+ * Input parameters:
+ * id - semaphore id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#define MUTEX_MP_SUPPORT _Semaphore_Core_mutex_mp_support
+#else
+#define MUTEX_MP_SUPPORT NULL
+#endif
+
+rtems_status_code rtems_semaphore_release(
+ rtems_id id
+)
+{
+ register Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+ CORE_mutex_Status mutex_status;
+ CORE_semaphore_Status semaphore_status;
+
+ the_semaphore = _Semaphore_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return _Semaphore_MP_Send_request_packet(
+ SEMAPHORE_MP_RELEASE_REQUEST,
+ id,
+ 0, /* Not used */
+ MPCI_DEFAULT_TIMEOUT
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
+ mutex_status = _CORE_mutex_Surrender(
+ &the_semaphore->Core_control.mutex,
+ id,
+ MUTEX_MP_SUPPORT
+ );
+ _Thread_Enable_dispatch();
+ return _Semaphore_Translate_core_mutex_return_code( mutex_status );
+ } else {
+ semaphore_status = _CORE_semaphore_Surrender(
+ &the_semaphore->Core_control.semaphore,
+ id,
+ MUTEX_MP_SUPPORT
+ );
+ _Thread_Enable_dispatch();
+ return
+ _Semaphore_Translate_core_semaphore_return_code( semaphore_status );
+ }
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/semtranslatereturncode.c b/cpukit/rtems/src/semtranslatereturncode.c
new file mode 100644
index 0000000000..cc7bfffbd6
--- /dev/null
+++ b/cpukit/rtems/src/semtranslatereturncode.c
@@ -0,0 +1,124 @@
+/*
+ * Semaphore Manager
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the Semaphore Manager.
+ * This manager utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * Directives provided are:
+ *
+ * + create a semaphore
+ * + get an ID of a semaphore
+ * + delete a semaphore
+ * + acquire a semaphore
+ * + release a semaphore
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/score/sysstate.h>
+
+#include <rtems/score/interr.h>
+
+/*PAGE
+ *
+ * _Semaphore_Translate_core_mutex_return_code
+ *
+ * Input parameters:
+ * the_mutex_status - mutex status code to translate
+ *
+ * Output parameters:
+ * rtems status code - translated RTEMS status code
+ *
+ */
+
+rtems_status_code _Semaphore_Translate_core_mutex_return_code_[] = {
+ RTEMS_SUCCESSFUL, /* CORE_MUTEX_STATUS_SUCCESSFUL */
+ RTEMS_UNSATISFIED, /* CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT */
+ RTEMS_UNSATISFIED, /* CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED */
+ RTEMS_NOT_OWNER_OF_RESOURCE, /* CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE */
+ RTEMS_OBJECT_WAS_DELETED, /* CORE_MUTEX_WAS_DELETED */
+ RTEMS_TIMEOUT, /* CORE_MUTEX_TIMEOUT */
+ RTEMS_INTERNAL_ERROR, /* CORE_MUTEX_STATUS_CEILING_VIOLATED */
+};
+
+
+rtems_status_code _Semaphore_Translate_core_mutex_return_code (
+ uint32_t the_mutex_status
+)
+{
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_mutex_status == THREAD_STATUS_PROXY_BLOCKING )
+ return RTEMS_PROXY_BLOCKING;
+ else
+#endif
+ if ( the_mutex_status > CORE_MUTEX_STATUS_CEILING_VIOLATED )
+ return RTEMS_INTERNAL_ERROR;
+ else
+ return _Semaphore_Translate_core_mutex_return_code_[the_mutex_status];
+}
+
+/*PAGE
+ *
+ * _Semaphore_Translate_core_semaphore_return_code
+ *
+ * Input parameters:
+ * the_semaphore_status - semaphore status code to translate
+ *
+ * Output parameters:
+ * rtems status code - translated RTEMS status code
+ *
+ */
+
+rtems_status_code _Semaphore_Translate_core_semaphore_return_code_[] = {
+ RTEMS_SUCCESSFUL, /* CORE_SEMAPHORE_STATUS_SUCCESSFUL */
+ RTEMS_UNSATISFIED, /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */
+ RTEMS_OBJECT_WAS_DELETED, /* CORE_SEMAPHORE_WAS_DELETED */
+ RTEMS_TIMEOUT, /* CORE_SEMAPHORE_TIMEOUT */
+ RTEMS_INTERNAL_ERROR, /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */
+
+};
+
+rtems_status_code _Semaphore_Translate_core_semaphore_return_code (
+ uint32_t the_semaphore_status
+)
+{
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_semaphore_status == THREAD_STATUS_PROXY_BLOCKING )
+ return RTEMS_PROXY_BLOCKING;
+ else
+#endif
+ if ( the_semaphore_status > CORE_MUTEX_STATUS_CEILING_VIOLATED )
+ return RTEMS_INTERNAL_ERROR;
+ else
+ return _Semaphore_Translate_core_semaphore_return_code_[the_semaphore_status];
+}
diff --git a/cpukit/rtems/src/signal.c b/cpukit/rtems/src/signal.c
new file mode 100644
index 0000000000..d54d1e2491
--- /dev/null
+++ b/cpukit/rtems/src/signal.c
@@ -0,0 +1,51 @@
+/*
+ * Signal Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/asr.h>
+#include <rtems/score/isr.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/rtems/signal.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/tasks.h>
+
+/*PAGE
+ *
+ * _Signal_Manager_initialization
+ *
+ * This routine initializes all signal manager related data structures.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _Signal_Manager_initialization( void )
+{
+ /*
+ * Register the MP Process Packet routine.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _MPCI_Register_packet_processor(
+ MP_PACKET_SIGNAL,
+ _Signal_MP_Process_packet
+ );
+#endif
+}
diff --git a/cpukit/rtems/src/signalcatch.c b/cpukit/rtems/src/signalcatch.c
new file mode 100644
index 0000000000..fd38e06e2f
--- /dev/null
+++ b/cpukit/rtems/src/signalcatch.c
@@ -0,0 +1,69 @@
+/*
+ * Signal Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/asr.h>
+#include <rtems/score/isr.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/rtems/signal.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/tasks.h>
+
+/*PAGE
+ *
+ * rtems_signal_catch
+ *
+ * This directive allows a thread to specify what action to take when
+ * catching signals.
+ *
+ * Input parameters:
+ * handler - address of asynchronous signal routine (asr)
+ * ( NULL indicates asr is invalid )
+ * mode_set - mode value for asr
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - always succeeds
+ */
+
+rtems_status_code rtems_signal_catch(
+ rtems_asr_entry asr_handler,
+ rtems_mode mode_set
+)
+{
+ Thread_Control *executing;
+ RTEMS_API_Control *api;
+ ASR_Information *asr;
+
+/* XXX normalize mode */
+ executing = _Thread_Executing;
+ api = (RTEMS_API_Control*)executing->API_Extensions[ THREAD_API_RTEMS ];
+ asr = &api->Signal;
+
+ _Thread_Disable_dispatch(); /* cannot reschedule while */
+ /* the thread is inconsistent */
+
+ if ( !_ASR_Is_null_handler( asr_handler ) ) {
+ asr->mode_set = mode_set;
+ asr->handler = asr_handler;
+ }
+ else
+ _ASR_Initialize( asr );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/signalmp.c b/cpukit/rtems/src/signalmp.c
new file mode 100644
index 0000000000..7a7f771b19
--- /dev/null
+++ b/cpukit/rtems/src/signalmp.c
@@ -0,0 +1,192 @@
+/*
+ * Multiprocessing Support for the Signal Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/score/mpci.h>
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/signal.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * _Signal_MP_Send_process_packet
+ *
+ * This subprogram is not needed since there are no process
+ * packets to be sent by this manager.
+ *
+ */
+
+/*PAGE
+ *
+ * _Signal_MP_Send_request_packet
+ *
+ */
+
+rtems_status_code _Signal_MP_Send_request_packet (
+ Signal_MP_Remote_operations operation,
+ Objects_Id task_id,
+ rtems_signal_set signal_in
+)
+{
+ Signal_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case SIGNAL_MP_SEND_REQUEST:
+
+ the_packet = _Signal_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_SIGNAL;
+ the_packet->Prefix.length = sizeof ( Signal_MP_Packet );
+ the_packet->Prefix.to_convert = sizeof ( Signal_MP_Packet );
+ the_packet->operation = operation;
+ the_packet->Prefix.id = task_id;
+ the_packet->signal_in = signal_in;
+
+ return _MPCI_Send_request_packet(
+ rtems_get_node( task_id ),
+ &the_packet->Prefix,
+ STATES_READY /* Not used */
+ );
+ break;
+
+ case SIGNAL_MP_SEND_RESPONSE:
+ break;
+
+ }
+ /*
+ * The following line is included to satisfy compilers which
+ * produce warnings when a function does not end with a return.
+ */
+ return RTEMS_INTERNAL_ERROR;
+}
+
+/*PAGE
+ *
+ * _Signal_MP_Send_response_packet
+ *
+ */
+
+void _Signal_MP_Send_response_packet (
+ Signal_MP_Remote_operations operation,
+ Thread_Control *the_thread
+)
+{
+ Signal_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case SIGNAL_MP_SEND_RESPONSE:
+
+ the_packet = ( Signal_MP_Packet *) the_thread->receive_packet;
+
+/*
+ * The packet being returned already contains the class, length, and
+ * to_convert fields, therefore they are not set in this routine.
+ */
+ the_packet->operation = operation;
+ the_packet->Prefix.id = the_packet->Prefix.source_tid;
+
+ _MPCI_Send_response_packet(
+ rtems_get_node( the_packet->Prefix.source_tid ),
+ &the_packet->Prefix
+ );
+ break;
+
+ case SIGNAL_MP_SEND_REQUEST:
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ *
+ * _Signal_MP_Process_packet
+ *
+ */
+
+void _Signal_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+)
+{
+ Signal_MP_Packet *the_packet;
+ Thread_Control *the_thread;
+
+ the_packet = (Signal_MP_Packet *) the_packet_prefix;
+
+ switch ( the_packet->operation ) {
+
+ case SIGNAL_MP_SEND_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_signal_send(
+ the_packet->Prefix.id,
+ the_packet->signal_in
+ );
+
+ _Signal_MP_Send_response_packet(
+ SIGNAL_MP_SEND_RESPONSE,
+ _Thread_Executing
+ );
+ break;
+
+ case SIGNAL_MP_SEND_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ * _Signal_MP_Send_object_was_deleted
+ *
+ * This subprogram is not needed since there are no objects
+ * deleted by this manager.
+ *
+ */
+
+/*PAGE
+ *
+ * _Signal_MP_Send_extract_proxy
+ *
+ * This subprogram is not needed since there are no objects
+ * deleted by this manager.
+ *
+ */
+
+/*PAGE
+ *
+ * _Signal_MP_Get_packet
+ *
+ */
+
+Signal_MP_Packet *_Signal_MP_Get_packet ( void )
+{
+ return ( (Signal_MP_Packet *) _MPCI_Get_packet() );
+}
+
+/* end of file */
diff --git a/cpukit/rtems/src/signalsend.c b/cpukit/rtems/src/signalsend.c
new file mode 100644
index 0000000000..2d05a5249b
--- /dev/null
+++ b/cpukit/rtems/src/signalsend.c
@@ -0,0 +1,94 @@
+/*
+ * Signal Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/asr.h>
+#include <rtems/score/isr.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/rtems/signal.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/tasks.h>
+
+/*PAGE
+ *
+ * rtems_signal_send
+ *
+ * This directive allows a thread to send signals to a thread.
+ *
+ * Input parameters:
+ * id - thread id
+ * signal_set - signal set
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_signal_send(
+ Objects_Id id,
+ rtems_signal_set signal_set
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+ RTEMS_API_Control *api;
+ ASR_Information *asr;
+
+ if ( !signal_set )
+ return RTEMS_INVALID_NUMBER;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return _Signal_MP_Send_request_packet(
+ SIGNAL_MP_SEND_REQUEST,
+ id,
+ signal_set
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
+ asr = &api->Signal;
+
+ if ( ! _ASR_Is_null_handler( asr->handler ) ) {
+ if ( asr->is_enabled ) {
+ _ASR_Post_signals( signal_set, &asr->signals_posted );
+
+ the_thread->do_post_task_switch_extension = TRUE;
+
+ if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
+ _ISR_Signals_to_thread_executing = TRUE;
+ } else {
+ _ASR_Post_signals( signal_set, &asr->signals_pending );
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_NOT_DEFINED;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c
new file mode 100644
index 0000000000..5360d980b4
--- /dev/null
+++ b/cpukit/rtems/src/taskcreate.c
@@ -0,0 +1,230 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_create
+ *
+ * This directive creates a thread by allocating and initializing a
+ * thread control block and a stack. The newly created thread is
+ * placed in the dormant state.
+ *
+ * Input parameters:
+ * name - user defined thread name
+ * initial_priority - thread priority
+ * stack_size - stack size in bytes
+ * initial_modes - initial thread mode
+ * attribute_set - thread attributes
+ * id - pointer to thread id
+ *
+ * Output parameters:
+ * id - thread id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_create(
+ rtems_name name,
+ rtems_task_priority initial_priority,
+ uint32_t stack_size,
+ rtems_mode initial_modes,
+ rtems_attribute attribute_set,
+ Objects_Id *id
+)
+{
+ register Thread_Control *the_thread;
+ boolean is_fp;
+#if defined(RTEMS_MULTIPROCESSING)
+ Objects_MP_Control *the_global_object = NULL;
+ boolean is_global;
+#endif
+ boolean status;
+ rtems_attribute the_attribute_set;
+ Priority_Control core_priority;
+ RTEMS_API_Control *api;
+ ASR_Information *asr;
+
+
+ if ( !id )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( !rtems_is_name_valid( name ) )
+ return RTEMS_INVALID_NAME;
+
+ /*
+ * Core Thread Initialize insures we get the minimum amount of
+ * stack space.
+ */
+
+ /*
+ * Fix the attribute set to match the attributes which
+ * this processor (1) requires and (2) is able to support.
+ * First add in the required flags for attribute_set
+ * Typically this might include FP if the platform
+ * or application required all tasks to be fp aware.
+ * Then turn off the requested bits which are not supported.
+ */
+
+ the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED );
+ the_attribute_set =
+ _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );
+
+ if ( _Attributes_Is_floating_point( the_attribute_set ) )
+ is_fp = TRUE;
+ else
+ is_fp = FALSE;
+
+ /*
+ * Validate the RTEMS API priority and convert it to the core priority range.
+ */
+
+ if ( !_Attributes_Is_system_task( the_attribute_set ) ) {
+ if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) )
+ return RTEMS_INVALID_PRIORITY;
+ }
+
+ core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Attributes_Is_global( the_attribute_set ) ) {
+
+ is_global = TRUE;
+
+ if ( !_System_state_Is_multiprocessing )
+ return RTEMS_MP_NOT_CONFIGURED;
+
+ } else
+ is_global = FALSE;
+#endif
+
+ /*
+ * Make sure system is MP if this task is global
+ */
+
+ /*
+ * Disable dispatch for protection
+ */
+
+ _Thread_Disable_dispatch();
+
+ /*
+ * Allocate the thread control block and -- if the task is global --
+ * allocate a global object control block.
+ *
+ * NOTE: This routine does not use the combined allocate and open
+ * global object routine because this results in a lack of
+ * control over when memory is allocated and can be freed in
+ * the event of an error.
+ */
+
+ the_thread = _RTEMS_tasks_Allocate();
+
+ if ( !the_thread ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( is_global ) {
+ the_global_object = _Objects_MP_Allocate_global_object();
+
+ if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
+ _RTEMS_tasks_Free( the_thread );
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+ }
+#endif
+
+ /*
+ * Initialize the core thread for this task.
+ */
+
+ status = _Thread_Initialize(
+ &_RTEMS_tasks_Information,
+ the_thread,
+ NULL,
+ stack_size,
+ is_fp,
+ core_priority,
+ _Modes_Is_preempt(initial_modes) ? TRUE : FALSE,
+ _Modes_Is_timeslice(initial_modes) ?
+ THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE :
+ THREAD_CPU_BUDGET_ALGORITHM_NONE,
+ NULL, /* no budget algorithm callout */
+ _Modes_Get_interrupt_level(initial_modes),
+ (Objects_Name) name
+ );
+
+ if ( !status ) {
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( is_global )
+ _Objects_MP_Free_global_object( the_global_object );
+#endif
+ _RTEMS_tasks_Free( the_thread );
+ _Thread_Enable_dispatch();
+ return RTEMS_UNSATISFIED;
+ }
+
+ api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
+ asr = &api->Signal;
+
+ asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? FALSE : TRUE;
+
+ *id = the_thread->Object.id;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( is_global ) {
+
+ the_thread->is_global = TRUE;
+
+ _Objects_MP_Open(
+ &_RTEMS_tasks_Information,
+ the_global_object,
+ name,
+ the_thread->Object.id
+ );
+
+ _RTEMS_tasks_MP_Send_process_packet(
+ RTEMS_TASKS_MP_ANNOUNCE_CREATE,
+ the_thread->Object.id,
+ name
+ );
+
+ }
+#endif
+
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/taskdelete.c b/cpukit/rtems/src/taskdelete.c
new file mode 100644
index 0000000000..9eefcb919b
--- /dev/null
+++ b/cpukit/rtems/src/taskdelete.c
@@ -0,0 +1,104 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_delete
+ *
+ * This directive allows a thread to delete itself or the thread
+ * identified in the id field. The executive halts execution
+ * of the thread and frees the thread control block.
+ *
+ * Input parameters:
+ * id - thread id
+ *
+ * Output parameters:
+ * nothing - if id is the requesting thread (always succeeds)
+ * RTEMS_SUCCESSFUL - if successful and id is
+ * not the requesting thread
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_delete(
+ Objects_Id id
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+ Objects_Information *the_information;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ the_information = _Objects_Get_information( the_thread->Object.id );
+
+ if ( !the_information ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_INVALID_ID;
+ /* This should never happen if _Thread_Get() works right */
+ }
+
+ _Thread_Close( the_information, the_thread );
+
+ _RTEMS_tasks_Free( the_thread );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( the_thread->is_global ) {
+
+ _Objects_MP_Close( &_RTEMS_tasks_Information, the_thread->Object.id );
+
+ _RTEMS_tasks_MP_Send_process_packet(
+ RTEMS_TASKS_MP_ANNOUNCE_DELETE,
+ the_thread->Object.id,
+ 0 /* Not used */
+ );
+ }
+#endif
+
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/taskgetnote.c b/cpukit/rtems/src/taskgetnote.c
new file mode 100644
index 0000000000..7d01b9455f
--- /dev/null
+++ b/cpukit/rtems/src/taskgetnote.c
@@ -0,0 +1,112 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_get_note
+ *
+ * This directive obtains the note from the specified notepad
+ * of the specified thread.
+ *
+ * Input parameters:
+ * id - thread id
+ * notepad - notepad number
+ * note - pointer to note
+ *
+ * Output parameters:
+ * note - filled in if successful
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_get_note(
+ Objects_Id id,
+ uint32_t notepad,
+ uint32_t *note
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+ RTEMS_API_Control *api;
+
+ if ( !note )
+ return RTEMS_INVALID_ADDRESS;
+
+ /*
+ * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would
+ * be checking an unsigned number for being negative.
+ */
+
+ if ( notepad > RTEMS_NOTEPAD_LAST )
+ return RTEMS_INVALID_NUMBER;
+
+ /*
+ * Optimize the most likely case to avoid the Thread_Dispatch.
+ */
+
+ if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ||
+ _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) {
+ api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];
+ *note = api->Notepads[ notepad ];
+ return RTEMS_SUCCESSFUL;
+ }
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Executing->Wait.return_argument = note;
+
+ return _RTEMS_tasks_MP_Send_request_packet(
+ RTEMS_TASKS_MP_GET_NOTE_REQUEST,
+ id,
+ 0, /* Not used */
+ notepad,
+ 0 /* Not used */
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
+ *note = api->Notepads[ notepad ];
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/taskident.c b/cpukit/rtems/src/taskident.c
new file mode 100644
index 0000000000..2c9d7169a6
--- /dev/null
+++ b/cpukit/rtems/src/taskident.c
@@ -0,0 +1,77 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_ident
+ *
+ * This directive returns the system ID associated with
+ * the thread name.
+ *
+ * Input parameters:
+ * name - user defined thread name
+ * node - node(s) to be searched
+ * id - pointer to thread id
+ *
+ * Output parameters:
+ * *id - thread id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_ident(
+ rtems_name name,
+ uint32_t node,
+ Objects_Id *id
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ if ( !id )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( name == OBJECTS_ID_OF_SELF ) {
+ *id = _Thread_Executing->Object.id;
+ return RTEMS_SUCCESSFUL;
+ }
+
+ status = _Objects_Name_to_id(
+ &_RTEMS_tasks_Information,
+ (Objects_Name) name,
+ node,
+ id
+ );
+
+ return _Status_Object_name_errors_to_status[ status ];
+}
diff --git a/cpukit/rtems/src/taskinitusers.c b/cpukit/rtems/src/taskinitusers.c
new file mode 100644
index 0000000000..68fd37c585
--- /dev/null
+++ b/cpukit/rtems/src/taskinitusers.c
@@ -0,0 +1,87 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Initialize_user_tasks
+ *
+ * This routine creates and starts all configured user
+ * initialzation threads.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _RTEMS_tasks_Initialize_user_tasks( void )
+{
+ uint32_t index;
+ uint32_t maximum;
+ rtems_id id;
+ rtems_status_code return_value;
+ rtems_initialization_tasks_table *user_tasks;
+
+ /*
+ * NOTE: This is slightly different from the Ada implementation.
+ */
+
+ user_tasks = _RTEMS_tasks_User_initialization_tasks;
+ maximum = _RTEMS_tasks_Number_of_initialization_tasks;
+
+ if ( !user_tasks || maximum == 0 )
+ return;
+
+ for ( index=0 ; index < maximum ; index++ ) {
+ return_value = rtems_task_create(
+ user_tasks[ index ].name,
+ user_tasks[ index ].initial_priority,
+ user_tasks[ index ].stack_size,
+ user_tasks[ index ].mode_set,
+ user_tasks[ index ].attribute_set,
+ &id
+ );
+
+ if ( !rtems_is_status_successful( return_value ) )
+ _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value );
+
+ return_value = rtems_task_start(
+ id,
+ user_tasks[ index ].entry_point,
+ user_tasks[ index ].argument
+ );
+
+ if ( !rtems_is_status_successful( return_value ) )
+ _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value );
+ }
+}
diff --git a/cpukit/rtems/src/taskissuspended.c b/cpukit/rtems/src/taskissuspended.c
new file mode 100644
index 0000000000..a60d23af71
--- /dev/null
+++ b/cpukit/rtems/src/taskissuspended.c
@@ -0,0 +1,81 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_is_suspended
+ *
+ * This directive returns a status indicating whether or not
+ * the specified task is suspended.
+ *
+ * Input parameters:
+ * id - thread id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful and not suspended
+ * RTEMS_ALREADY_SUSPENDED - if successful and suspended
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_is_suspended(
+ Objects_Id id
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( !_States_Is_suspended( the_thread->current_state ) ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_ALREADY_SUSPENDED;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c
new file mode 100644
index 0000000000..4deccf4918
--- /dev/null
+++ b/cpukit/rtems/src/taskmode.c
@@ -0,0 +1,129 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_mode
+ *
+ * This directive enables and disables several modes of
+ * execution for the requesting thread.
+ *
+ * Input parameters:
+ * mode_set - new mode
+ * mask - mask
+ * previous_mode_set - address of previous mode set
+ *
+ * Output:
+ * *previous_mode_set - previous mode set
+ * always return RTEMS_SUCCESSFUL;
+ */
+
+rtems_status_code rtems_task_mode(
+ rtems_mode mode_set,
+ rtems_mode mask,
+ rtems_mode *previous_mode_set
+)
+{
+ Thread_Control *executing;
+ RTEMS_API_Control *api;
+ ASR_Information *asr;
+ boolean is_asr_enabled = FALSE;
+ boolean needs_asr_dispatching = FALSE;
+ rtems_mode old_mode;
+
+ if ( !previous_mode_set )
+ return RTEMS_INVALID_ADDRESS;
+
+ executing = _Thread_Executing;
+ api = executing->API_Extensions[ THREAD_API_RTEMS ];
+ asr = &api->Signal;
+
+ old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;
+
+ if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE )
+ old_mode |= RTEMS_NO_TIMESLICE;
+ else
+ old_mode |= RTEMS_TIMESLICE;
+
+ old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;
+ old_mode |= _ISR_Get_level();
+
+ *previous_mode_set = old_mode;
+
+ /*
+ * These are generic thread scheduling characteristics.
+ */
+
+ if ( mask & RTEMS_PREEMPT_MASK )
+ executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE;
+
+ if ( mask & RTEMS_TIMESLICE_MASK ) {
+ if ( _Modes_Is_timeslice(mode_set) )
+ executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
+ else
+ executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
+ }
+
+ /*
+ * Set the new interrupt level
+ */
+
+ if ( mask & RTEMS_INTERRUPT_MASK )
+ _Modes_Set_interrupt_level( mode_set );
+
+ /*
+ * This is specific to the RTEMS API
+ */
+
+ is_asr_enabled = FALSE;
+ needs_asr_dispatching = FALSE;
+
+ if ( mask & RTEMS_ASR_MASK ) {
+ is_asr_enabled = _Modes_Is_asr_disabled( mode_set ) ? FALSE : TRUE;
+ if ( is_asr_enabled != asr->is_enabled ) {
+ asr->is_enabled = is_asr_enabled;
+ _ASR_Swap_signals( asr );
+ if ( _ASR_Are_signals_pending( asr ) ) {
+ needs_asr_dispatching = TRUE;
+ executing->do_post_task_switch_extension = TRUE;
+ }
+ }
+ }
+
+ if ( _System_state_Is_up(_System_state_Current) )
+ if ( _Thread_Evaluate_mode() || needs_asr_dispatching )
+ _Thread_Dispatch();
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/taskmp.c b/cpukit/rtems/src/taskmp.c
new file mode 100644
index 0000000000..d1b2ff815c
--- /dev/null
+++ b/cpukit/rtems/src/taskmp.c
@@ -0,0 +1,343 @@
+/*
+ * Multiprocessing Support for the RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/score/mpci.h>
+#include <rtems/score/mppkt.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/rtems/support.h>
+
+/*PAGE
+ *
+ * _RTEMS_tasks_MP_Send_process_packet
+ *
+ */
+
+void _RTEMS_tasks_MP_Send_process_packet (
+ RTEMS_tasks_MP_Remote_operations operation,
+ Objects_Id task_id,
+ rtems_name name
+)
+{
+ RTEMS_tasks_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case RTEMS_TASKS_MP_ANNOUNCE_CREATE:
+ case RTEMS_TASKS_MP_ANNOUNCE_DELETE:
+
+ the_packet = _RTEMS_tasks_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_TASKS;
+ the_packet->Prefix.length = sizeof ( RTEMS_tasks_MP_Packet );
+ the_packet->Prefix.to_convert = sizeof ( RTEMS_tasks_MP_Packet );
+ the_packet->operation = operation;
+ the_packet->Prefix.id = task_id;
+ the_packet->name = name;
+
+ _MPCI_Send_process_packet( MPCI_ALL_NODES, &the_packet->Prefix );
+ break;
+
+ case RTEMS_TASKS_MP_SUSPEND_REQUEST:
+ case RTEMS_TASKS_MP_SUSPEND_RESPONSE:
+ case RTEMS_TASKS_MP_RESUME_REQUEST:
+ case RTEMS_TASKS_MP_RESUME_RESPONSE:
+ case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST:
+ case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE:
+ case RTEMS_TASKS_MP_GET_NOTE_REQUEST:
+ case RTEMS_TASKS_MP_GET_NOTE_RESPONSE:
+ case RTEMS_TASKS_MP_SET_NOTE_REQUEST:
+ case RTEMS_TASKS_MP_SET_NOTE_RESPONSE:
+ break;
+ }
+}
+
+/*PAGE
+ *
+ * _RTEMS_tasks_MP_Send_request_packet
+ *
+ */
+
+rtems_status_code _RTEMS_tasks_MP_Send_request_packet (
+ RTEMS_tasks_MP_Remote_operations operation,
+ Objects_Id task_id,
+ rtems_task_priority new_priority,
+ uint32_t notepad,
+ uint32_t note
+)
+{
+ RTEMS_tasks_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case RTEMS_TASKS_MP_SUSPEND_REQUEST:
+ case RTEMS_TASKS_MP_RESUME_REQUEST:
+ case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST:
+ case RTEMS_TASKS_MP_GET_NOTE_REQUEST:
+ case RTEMS_TASKS_MP_SET_NOTE_REQUEST:
+
+ the_packet = _RTEMS_tasks_MP_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_TASKS;
+ the_packet->Prefix.length = sizeof ( RTEMS_tasks_MP_Packet );
+ the_packet->Prefix.to_convert = sizeof ( RTEMS_tasks_MP_Packet );
+ the_packet->operation = operation;
+ the_packet->Prefix.id = task_id;
+ the_packet->the_priority = new_priority;
+ the_packet->notepad = notepad;
+ the_packet->note = note;
+
+ return _MPCI_Send_request_packet(
+ rtems_get_node( task_id ),
+ &the_packet->Prefix,
+ STATES_READY /* Not used */
+ );
+ break;
+
+ case RTEMS_TASKS_MP_ANNOUNCE_CREATE:
+ case RTEMS_TASKS_MP_ANNOUNCE_DELETE:
+ case RTEMS_TASKS_MP_SUSPEND_RESPONSE:
+ case RTEMS_TASKS_MP_RESUME_RESPONSE:
+ case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE:
+ case RTEMS_TASKS_MP_GET_NOTE_RESPONSE:
+ case RTEMS_TASKS_MP_SET_NOTE_RESPONSE:
+ break;
+
+ }
+ /*
+ * The following line is included to satisfy compilers which
+ * produce warnings when a function does not end with a return.
+ */
+ return RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * _RTEMS_tasks_MP_Send_response_packet
+ *
+ */
+
+void _RTEMS_tasks_MP_Send_response_packet (
+ RTEMS_tasks_MP_Remote_operations operation,
+ Thread_Control *the_thread
+)
+{
+ RTEMS_tasks_MP_Packet *the_packet;
+
+ switch ( operation ) {
+
+ case RTEMS_TASKS_MP_SUSPEND_RESPONSE:
+ case RTEMS_TASKS_MP_RESUME_RESPONSE:
+ case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE:
+ case RTEMS_TASKS_MP_GET_NOTE_RESPONSE:
+ case RTEMS_TASKS_MP_SET_NOTE_RESPONSE:
+
+ the_packet = (RTEMS_tasks_MP_Packet *) the_thread->receive_packet;
+
+/*
+ * The packet being returned already contains the class, length, and
+ * to_convert fields, therefore they are not set in this routine.
+ */
+ the_packet->operation = operation;
+ the_packet->Prefix.id = the_packet->Prefix.source_tid;
+
+ _MPCI_Send_response_packet(
+ rtems_get_node( the_packet->Prefix.source_tid ),
+ &the_packet->Prefix
+ );
+ break;
+
+ case RTEMS_TASKS_MP_ANNOUNCE_CREATE:
+ case RTEMS_TASKS_MP_ANNOUNCE_DELETE:
+ case RTEMS_TASKS_MP_SUSPEND_REQUEST:
+ case RTEMS_TASKS_MP_RESUME_REQUEST:
+ case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST:
+ case RTEMS_TASKS_MP_GET_NOTE_REQUEST:
+ case RTEMS_TASKS_MP_SET_NOTE_REQUEST:
+ break;
+
+ }
+}
+
+/*PAGE
+ *
+ *
+ * _RTEMS_tasks_MP_Process_packet
+ *
+ */
+
+void _RTEMS_tasks_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+)
+{
+ RTEMS_tasks_MP_Packet *the_packet;
+ Thread_Control *the_thread;
+ boolean ignored;
+
+ the_packet = (RTEMS_tasks_MP_Packet *) the_packet_prefix;
+
+ switch ( the_packet->operation ) {
+
+ case RTEMS_TASKS_MP_ANNOUNCE_CREATE:
+
+ ignored = _Objects_MP_Allocate_and_open(
+ &_RTEMS_tasks_Information,
+ the_packet->name,
+ the_packet->Prefix.id,
+ TRUE
+ );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case RTEMS_TASKS_MP_ANNOUNCE_DELETE:
+
+ _Objects_MP_Close( &_RTEMS_tasks_Information, the_packet->Prefix.id );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case RTEMS_TASKS_MP_SUSPEND_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_task_suspend(
+ the_packet->Prefix.id
+ );
+
+ _RTEMS_tasks_MP_Send_response_packet(
+ RTEMS_TASKS_MP_SUSPEND_RESPONSE,
+ _Thread_Executing
+ );
+ break;
+
+ case RTEMS_TASKS_MP_SUSPEND_RESPONSE:
+ case RTEMS_TASKS_MP_RESUME_RESPONSE:
+ case RTEMS_TASKS_MP_SET_NOTE_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case RTEMS_TASKS_MP_RESUME_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_task_resume(
+ the_packet->Prefix.id
+ );
+
+ _RTEMS_tasks_MP_Send_response_packet(
+ RTEMS_TASKS_MP_RESUME_RESPONSE,
+ _Thread_Executing
+ );
+ break;
+
+ case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_task_set_priority(
+ the_packet->Prefix.id,
+ the_packet->the_priority,
+ &the_packet->the_priority
+ );
+
+ _RTEMS_tasks_MP_Send_response_packet(
+ RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE,
+ _Thread_Executing
+ );
+ break;
+
+ case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ *(rtems_task_priority *)the_thread->Wait.return_argument =
+ the_packet->the_priority;
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case RTEMS_TASKS_MP_GET_NOTE_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_task_get_note(
+ the_packet->Prefix.id,
+ the_packet->notepad,
+ &the_packet->note
+ );
+
+ _RTEMS_tasks_MP_Send_response_packet(
+ RTEMS_TASKS_MP_GET_NOTE_RESPONSE,
+ _Thread_Executing
+ );
+ break;
+
+ case RTEMS_TASKS_MP_GET_NOTE_RESPONSE:
+
+ the_thread = _MPCI_Process_response( the_packet_prefix );
+
+ *(uint32_t *)the_thread->Wait.return_argument = the_packet->note;
+
+ _MPCI_Return_packet( the_packet_prefix );
+ break;
+
+ case RTEMS_TASKS_MP_SET_NOTE_REQUEST:
+
+ the_packet->Prefix.return_code = rtems_task_set_note(
+ the_packet->Prefix.id,
+ the_packet->notepad,
+ the_packet->note
+ );
+
+ _RTEMS_tasks_MP_Send_response_packet(
+ RTEMS_TASKS_MP_SET_NOTE_RESPONSE,
+ _Thread_Executing
+ );
+ break;
+ }
+}
+
+/*PAGE
+ *
+ * _RTEMS_tasks_MP_Send_object_was_deleted
+ *
+ * This routine is not neededby the Tasks since a task
+ * cannot be globally deleted.
+ *
+ */
+
+/*PAGE
+ *
+ * _RTEMS_tasks_MP_Send_extract_proxy
+ *
+ * This routine is not neededby the Tasks since a task
+ * cannot be globally deleted.
+ *
+ */
+
+/*PAGE
+ *
+ * _RTEMS_tasks_MP_Get_packet
+ *
+ */
+
+RTEMS_tasks_MP_Packet *_RTEMS_tasks_MP_Get_packet ( void )
+{
+ return (RTEMS_tasks_MP_Packet *) _MPCI_Get_packet();
+}
+
+/* end of file */
diff --git a/cpukit/rtems/src/taskrestart.c b/cpukit/rtems/src/taskrestart.c
new file mode 100644
index 0000000000..b24b00b9ee
--- /dev/null
+++ b/cpukit/rtems/src/taskrestart.c
@@ -0,0 +1,83 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_restart
+ *
+ * This directive readies the specified thread. It restores
+ * the thread environment to the original values established
+ * at thread creation and start time. A thread can be restarted
+ * from any state except the dormant state.
+ *
+ * Input parameters:
+ * id - thread id
+ * argument - thread argument
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_restart(
+ Objects_Id id,
+ uint32_t argument
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( _Thread_Restart( the_thread, NULL, argument ) ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_INCORRECT_STATE;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/taskresume.c b/cpukit/rtems/src/taskresume.c
new file mode 100644
index 0000000000..4d6e5b4444
--- /dev/null
+++ b/cpukit/rtems/src/taskresume.c
@@ -0,0 +1,85 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_resume
+ *
+ * This directive will remove the specified thread
+ * from the suspended state.
+ *
+ * Input parameters:
+ * id - thread id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_resume(
+ Objects_Id id
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return _RTEMS_tasks_MP_Send_request_packet(
+ RTEMS_TASKS_MP_RESUME_REQUEST,
+ id,
+ 0, /* Not used */
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( _States_Is_suspended( the_thread->current_state ) ) {
+ _Thread_Resume( the_thread, TRUE );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_INCORRECT_STATE;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c
new file mode 100644
index 0000000000..5805cf7823
--- /dev/null
+++ b/cpukit/rtems/src/tasks.c
@@ -0,0 +1,293 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Create_extension
+ *
+ * This routine is an extension routine that is invoked as part
+ * of creating any type of task or thread in the system. If the
+ * task is created via another API, then this routine is invoked
+ * and this API given the opportunity to initialize its extension
+ * area.
+ */
+
+boolean _RTEMS_tasks_Create_extension(
+ Thread_Control *executing,
+ Thread_Control *created
+)
+{
+ RTEMS_API_Control *api;
+ int i;
+
+ api = _Workspace_Allocate( sizeof( RTEMS_API_Control ) );
+
+ if ( !api )
+ return FALSE;
+
+ created->API_Extensions[ THREAD_API_RTEMS ] = api;
+
+ api->pending_events = EVENT_SETS_NONE_PENDING;
+ _ASR_Initialize( &api->Signal );
+ created->task_variables = NULL;
+
+ for (i=0; i < RTEMS_NUMBER_NOTEPADS; i++)
+ api->Notepads[i] = 0;
+
+ return TRUE;
+}
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Start_extension
+ *
+ * This extension routine is invoked when a task is started for the
+ * first time.
+ */
+
+User_extensions_routine _RTEMS_tasks_Start_extension(
+ Thread_Control *executing,
+ Thread_Control *started
+)
+{
+ RTEMS_API_Control *api;
+
+ api = started->API_Extensions[ THREAD_API_RTEMS ];
+
+ api->pending_events = EVENT_SETS_NONE_PENDING;
+
+ _ASR_Initialize( &api->Signal );
+}
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Delete_extension
+ *
+ * This extension routine is invoked when a task is deleted.
+ */
+
+User_extensions_routine _RTEMS_tasks_Delete_extension(
+ Thread_Control *executing,
+ Thread_Control *deleted
+)
+{
+ rtems_task_variable_t *tvp, *next;
+
+ /*
+ * Free per task variable memory
+ */
+
+ tvp = deleted->task_variables;
+ deleted->task_variables = NULL;
+ while (tvp) {
+ next = (rtems_task_variable_t *)tvp->next;
+ if (_Thread_Is_executing(deleted)) {
+ if (tvp->dtor)
+ (*tvp->dtor)(*tvp->ptr);
+ *tvp->ptr = tvp->gval;
+ } else {
+ if (tvp->dtor)
+ (*tvp->dtor)(tvp->tval);
+ }
+ _Workspace_Free( tvp );
+ tvp = next;
+ }
+
+ /*
+ * Free API specific memory
+ */
+
+ (void) _Workspace_Free( deleted->API_Extensions[ THREAD_API_RTEMS ] );
+ deleted->API_Extensions[ THREAD_API_RTEMS ] = NULL;
+}
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Switch_extension
+ *
+ * This extension routine is invoked at each context switch.
+ */
+
+void _RTEMS_tasks_Switch_extension(
+ Thread_Control *executing,
+ Thread_Control *heir
+)
+{
+ rtems_task_variable_t *tvp;
+
+ /*
+ * Per Task Variables
+ */
+
+ tvp = executing->task_variables;
+ while (tvp) {
+ tvp->tval = *tvp->ptr;
+ *tvp->ptr = tvp->gval;
+ tvp = (rtems_task_variable_t *)tvp->next;
+ }
+
+ tvp = heir->task_variables;
+ while (tvp) {
+ tvp->gval = *tvp->ptr;
+ *tvp->ptr = tvp->tval;
+ tvp = (rtems_task_variable_t *)tvp->next;
+ }
+}
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Post_switch_extension
+ *
+ * This extension routine is invoked at each context switch.
+ */
+
+void _RTEMS_tasks_Post_switch_extension(
+ Thread_Control *executing
+)
+{
+ ISR_Level level;
+ RTEMS_API_Control *api;
+ ASR_Information *asr;
+ rtems_signal_set signal_set;
+ Modes_Control prev_mode;
+
+ api = executing->API_Extensions[ THREAD_API_RTEMS ];
+
+ /*
+ * Signal Processing
+ */
+
+ asr = &api->Signal;
+
+ _ISR_Disable( level );
+ signal_set = asr->signals_posted;
+ asr->signals_posted = 0;
+ _ISR_Enable( level );
+
+
+ if ( !signal_set ) /* similar to _ASR_Are_signals_pending( asr ) */
+ return;
+
+ asr->nest_level += 1;
+ rtems_task_mode( asr->mode_set, RTEMS_ALL_MODE_MASKS, &prev_mode );
+
+ (*asr->handler)( signal_set );
+
+ asr->nest_level -= 1;
+ rtems_task_mode( prev_mode, RTEMS_ALL_MODE_MASKS, &prev_mode );
+
+}
+
+API_extensions_Control _RTEMS_tasks_API_extensions = {
+ { NULL, NULL },
+ NULL, /* predriver */
+ _RTEMS_tasks_Initialize_user_tasks, /* postdriver */
+ _RTEMS_tasks_Post_switch_extension /* post switch */
+};
+
+User_extensions_Control _RTEMS_tasks_User_extensions = {
+ { NULL, NULL },
+ { { NULL, NULL }, _RTEMS_tasks_Switch_extension },
+ { _RTEMS_tasks_Create_extension, /* create */
+ _RTEMS_tasks_Start_extension, /* start */
+ _RTEMS_tasks_Start_extension, /* restart */
+ _RTEMS_tasks_Delete_extension, /* delete */
+ _RTEMS_tasks_Switch_extension, /* switch */
+ NULL, /* begin */
+ NULL, /* exitted */
+ NULL /* fatal */
+ }
+};
+
+/*PAGE
+ *
+ * _RTEMS_tasks_Manager_initialization
+ *
+ * This routine initializes all Task Manager related data structures.
+ *
+ * Input parameters:
+ * maximum_tasks - number of tasks to initialize
+ *
+ * Output parameters: NONE
+ */
+
+void _RTEMS_tasks_Manager_initialization(
+ uint32_t maximum_tasks,
+ uint32_t number_of_initialization_tasks,
+ rtems_initialization_tasks_table *user_tasks
+)
+{
+
+ _RTEMS_tasks_Number_of_initialization_tasks = number_of_initialization_tasks;
+ _RTEMS_tasks_User_initialization_tasks = user_tasks;
+
+ /*
+ * There may not be any RTEMS initialization tasks configured.
+ */
+
+ _Objects_Initialize_information(
+ &_RTEMS_tasks_Information, /* object information table */
+ OBJECTS_CLASSIC_API, /* object API */
+ OBJECTS_RTEMS_TASKS, /* object class */
+ maximum_tasks, /* maximum objects of this class */
+ sizeof( Thread_Control ), /* size of this object's control block */
+ FALSE, /* TRUE if the name is a string */
+ RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ TRUE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+ /*
+ * Add all the extensions for this API
+ */
+
+ _User_extensions_Add_API_set( &_RTEMS_tasks_User_extensions );
+
+ _API_extensions_Add( &_RTEMS_tasks_API_extensions );
+
+ /*
+ * Register the MP Process Packet routine.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _MPCI_Register_packet_processor(
+ MP_PACKET_TASKS,
+ _RTEMS_tasks_MP_Process_packet
+ );
+#endif
+
+}
diff --git a/cpukit/rtems/src/tasksetnote.c b/cpukit/rtems/src/tasksetnote.c
new file mode 100644
index 0000000000..60aabcd191
--- /dev/null
+++ b/cpukit/rtems/src/tasksetnote.c
@@ -0,0 +1,106 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_set_note
+ *
+ * This directive sets the specified notepad contents to the given
+ * note.
+ *
+ * Input parameters:
+ * id - thread id
+ * notepad - notepad number
+ * note - note value
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_set_note(
+ Objects_Id id,
+ uint32_t notepad,
+ uint32_t note
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+ RTEMS_API_Control *api;
+
+ /*
+ * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would
+ * be checking an unsigned number for being negative.
+ */
+
+ if ( notepad > RTEMS_NOTEPAD_LAST )
+ return RTEMS_INVALID_NUMBER;
+
+ /*
+ * Optimize the most likely case to avoid the Thread_Dispatch.
+ */
+
+ if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ||
+ _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) {
+ api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];
+ api->Notepads[ notepad ] = note;
+ return RTEMS_SUCCESSFUL;
+ }
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return _RTEMS_tasks_MP_Send_request_packet(
+ RTEMS_TASKS_MP_SET_NOTE_REQUEST,
+ id,
+ 0, /* Not used */
+ notepad,
+ note
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
+ api->Notepads[ notepad ] = note;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/tasksetpriority.c b/cpukit/rtems/src/tasksetpriority.c
new file mode 100644
index 0000000000..432837780c
--- /dev/null
+++ b/cpukit/rtems/src/tasksetpriority.c
@@ -0,0 +1,102 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_set_priority
+ *
+ * This directive changes the priority of the specified thread.
+ * The specified thread can be any thread in the system including
+ * the requesting thread.
+ *
+ * Input parameters:
+ * id - thread id (0 indicates requesting thread)
+ * new_priority - thread priority (0 indicates current priority)
+ * old_priority - pointer to previous priority
+ *
+ * Output parameters:
+ * old_priority - previous priority
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_set_priority(
+ Objects_Id id,
+ rtems_task_priority new_priority,
+ rtems_task_priority *old_priority
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ if ( new_priority != RTEMS_CURRENT_PRIORITY &&
+ !_RTEMS_tasks_Priority_is_valid( new_priority ) )
+ return RTEMS_INVALID_PRIORITY;
+
+ if ( !old_priority )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Executing->Wait.return_argument = old_priority;
+ return _RTEMS_tasks_MP_Send_request_packet(
+ RTEMS_TASKS_MP_SET_PRIORITY_REQUEST,
+ id,
+ new_priority,
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ /* XXX convert from core priority */
+ *old_priority = the_thread->current_priority;
+ if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
+ the_thread->real_priority = new_priority;
+ if ( the_thread->resource_count == 0 ||
+ the_thread->current_priority > new_priority )
+ _Thread_Change_priority( the_thread, new_priority, FALSE );
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/taskstart.c b/cpukit/rtems/src/taskstart.c
new file mode 100644
index 0000000000..3e1028daf0
--- /dev/null
+++ b/cpukit/rtems/src/taskstart.c
@@ -0,0 +1,88 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_start
+ *
+ * This directive readies the thread identified by the "id"
+ * based on its current priorty, to await execution. A thread
+ * can be started only from the dormant state.
+ *
+ * Input parameters:
+ * id - thread id
+ * entry_point - start execution address of thread
+ * argument - thread argument
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_start(
+ rtems_id id,
+ rtems_task_entry entry_point,
+ rtems_task_argument argument
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ if ( entry_point == NULL )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( _Thread_Start(
+ the_thread, THREAD_START_NUMERIC, entry_point, NULL, argument ) ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_INCORRECT_STATE;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/tasksuspend.c b/cpukit/rtems/src/tasksuspend.c
new file mode 100644
index 0000000000..bb27b37dc9
--- /dev/null
+++ b/cpukit/rtems/src/tasksuspend.c
@@ -0,0 +1,86 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_suspend
+ *
+ * This directive will place the specified thread in the "suspended"
+ * state. Note that the suspended state can be in addition to
+ * other waiting states.
+ *
+ * Input parameters:
+ * id - thread id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_suspend(
+ Objects_Id id
+)
+{
+ register Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ return _RTEMS_tasks_MP_Send_request_packet(
+ RTEMS_TASKS_MP_SUSPEND_REQUEST,
+ id,
+ 0, /* Not used */
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( !_States_Is_suspended( the_thread->current_state ) ) {
+ _Thread_Suspend( the_thread );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_ALREADY_SUSPENDED;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/taskvariableadd.c b/cpukit/rtems/src/taskvariableadd.c
new file mode 100644
index 0000000000..c37b0c22f5
--- /dev/null
+++ b/cpukit/rtems/src/taskvariableadd.c
@@ -0,0 +1,92 @@
+/*
+ * rtems_task_variable_add - Add a per-task variable
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * rtems_task_variable_add
+ *
+ * This directive registers a task variable.
+ */
+
+rtems_status_code rtems_task_variable_add(
+ rtems_id tid,
+ void **ptr,
+ void (*dtor)(void *)
+)
+{
+ Thread_Control *the_thread;
+ Objects_Locations location;
+ rtems_task_variable_t *tvp, *new;
+
+ if ( !ptr )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_thread = _Thread_Get (tid, &location);
+ switch (location) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ default:
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_LOCAL:
+
+ /*
+ * Figure out if the variable is already in this task's list.
+ */
+
+ tvp = the_thread->task_variables;
+ while (tvp) {
+ if (tvp->ptr == ptr) {
+ tvp->dtor = dtor;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ tvp = (rtems_task_variable_t *)tvp->next;
+ }
+
+ /*
+ * Now allocate memory for this task variable.
+ */
+
+ new = (rtems_task_variable_t *)
+ _Workspace_Allocate(sizeof(rtems_task_variable_t));
+ if (new == NULL) {
+ _Thread_Enable_dispatch();
+ return RTEMS_NO_MEMORY;
+ }
+ new->gval = *ptr;
+ new->ptr = ptr;
+ new->dtor = dtor;
+
+ new->next = (struct rtems_task_variable_tt *)the_thread->task_variables;
+ the_thread->task_variables = new;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/taskvariabledelete.c b/cpukit/rtems/src/taskvariabledelete.c
new file mode 100644
index 0000000000..cf16cdc6a2
--- /dev/null
+++ b/cpukit/rtems/src/taskvariabledelete.c
@@ -0,0 +1,85 @@
+/*
+ * rtems_task_variable_delete - Delete a per-task variable
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * rtems_task_variable_delete
+ *
+ * This directive removes a task variable.
+ */
+
+rtems_status_code rtems_task_variable_delete(
+ rtems_id tid,
+ void **ptr
+)
+{
+ Thread_Control *the_thread;
+ Objects_Locations location;
+ rtems_task_variable_t *tvp, *prev;
+
+ if ( !ptr )
+ return RTEMS_INVALID_ADDRESS;
+
+ prev = NULL;
+
+ the_thread = _Thread_Get (tid, &location);
+ switch (location) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ default:
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_LOCAL:
+ tvp = the_thread->task_variables;
+ while (tvp) {
+ if (tvp->ptr == ptr) {
+ if (prev)
+ prev->next = tvp->next;
+ else
+ the_thread->task_variables = (rtems_task_variable_t *)tvp->next;
+ if (_Thread_Is_executing(the_thread)) {
+ if (tvp->dtor)
+ (*tvp->dtor)(*tvp->ptr);
+ *tvp->ptr = tvp->gval;
+ } else {
+ if (tvp->dtor)
+ (*tvp->dtor)(tvp->tval);
+ }
+ _Workspace_Free(tvp);
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ prev = tvp;
+ tvp = (rtems_task_variable_t *)tvp->next;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/taskvariableget.c b/cpukit/rtems/src/taskvariableget.c
new file mode 100644
index 0000000000..0736d131af
--- /dev/null
+++ b/cpukit/rtems/src/taskvariableget.c
@@ -0,0 +1,82 @@
+/*
+ * rtems_task_variable_get - Get a per-task variable
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * rtems_task_variable_get
+ *
+ * This directive gets the value of a task variable.
+ */
+
+rtems_status_code rtems_task_variable_get(
+ rtems_id tid,
+ void **ptr,
+ void **result
+)
+{
+ Thread_Control *the_thread;
+ Objects_Locations location;
+ rtems_task_variable_t *tvp;
+
+ if ( !ptr )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( !result )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_thread = _Thread_Get (tid, &location);
+ switch (location) {
+ case OBJECTS_REMOTE:
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_Dispatch();
+ return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+#endif
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ default:
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_LOCAL:
+
+ /*
+ * Figure out if the variable is in this task's list.
+ */
+
+ tvp = the_thread->task_variables;
+ while (tvp) {
+ if (tvp->ptr == ptr) {
+ /*
+ * Should this return the current (i.e not the
+ * saved) value if `tid' is the current task?
+ */
+ *result = tvp->tval;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+ tvp = (rtems_task_variable_t *)tvp->next;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_INVALID_ADDRESS;
+ }
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/taskwakeafter.c b/cpukit/rtems/src/taskwakeafter.c
new file mode 100644
index 0000000000..85f2e6307d
--- /dev/null
+++ b/cpukit/rtems/src/taskwakeafter.c
@@ -0,0 +1,68 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_wake_after
+ *
+ * This directive suspends the requesting thread for the given amount
+ * of ticks.
+ *
+ * Input parameters:
+ * ticks - number of ticks to wait
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - always successful
+ */
+
+rtems_status_code rtems_task_wake_after(
+ rtems_interval ticks
+)
+{
+ _Thread_Disable_dispatch();
+ if ( ticks == 0 ) {
+ _Thread_Yield_processor();
+ } else {
+ _Thread_Set_state( _Thread_Executing, STATES_DELAYING );
+ _Watchdog_Initialize(
+ &_Thread_Executing->Timer,
+ _Thread_Delay_ended,
+ _Thread_Executing->Object.id,
+ NULL
+ );
+ _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks );
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/taskwakewhen.c b/cpukit/rtems/src/taskwakewhen.c
new file mode 100644
index 0000000000..363234fa08
--- /dev/null
+++ b/cpukit/rtems/src/taskwakewhen.c
@@ -0,0 +1,86 @@
+/*
+ * RTEMS Task Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/score/object.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/sysstate.h>
+
+/*PAGE
+ *
+ * rtems_task_wake_when
+ *
+ * This directive blocks the requesting thread until the given date and
+ * time is reached.
+ *
+ * Input parameters:
+ * time_buffer - pointer to the time and date structure
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_task_wake_when(
+ rtems_time_of_day *time_buffer
+)
+{
+ Watchdog_Interval seconds;
+
+ if ( !_TOD_Is_set )
+ return RTEMS_NOT_DEFINED;
+
+ if ( !time_buffer )
+ return RTEMS_INVALID_ADDRESS;
+
+ time_buffer->ticks = 0;
+
+ if ( !_TOD_Validate( time_buffer ) )
+ return RTEMS_INVALID_CLOCK;
+
+ seconds = _TOD_To_seconds( time_buffer );
+
+ if ( seconds <= _TOD_Seconds_since_epoch )
+ return RTEMS_INVALID_CLOCK;
+
+ _Thread_Disable_dispatch();
+ _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME );
+ _Watchdog_Initialize(
+ &_Thread_Executing->Timer,
+ _Thread_Delay_ended,
+ _Thread_Executing->Object.id,
+ NULL
+ );
+ _Watchdog_Insert_seconds(
+ &_Thread_Executing->Timer,
+ seconds - _TOD_Seconds_since_epoch
+ );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/timercancel.c b/cpukit/rtems/src/timercancel.c
new file mode 100644
index 0000000000..562524ede9
--- /dev/null
+++ b/cpukit/rtems/src/timercancel.c
@@ -0,0 +1,65 @@
+/*
+ * Timer Manager - rtems_timer_cancel directive
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_timer_cancel
+ *
+ * This directive allows a thread to cancel a timer.
+ *
+ * Input parameters:
+ * id - timer id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_timer_cancel(
+ Objects_Id id
+)
+{
+ Timer_Control *the_timer;
+ Objects_Locations location;
+
+ the_timer = _Timer_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ if ( !_Timer_Is_dormant_class( the_timer->the_class ) )
+ (void) _Watchdog_Remove( &the_timer->Ticker );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/timercreate.c b/cpukit/rtems/src/timercreate.c
new file mode 100644
index 0000000000..e303b93204
--- /dev/null
+++ b/cpukit/rtems/src/timercreate.c
@@ -0,0 +1,78 @@
+/*
+ * Timer Manager - rtems_timer_create directive
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_timer_create
+ *
+ * This directive creates a timer and performs some initialization.
+ *
+ * Input parameters:
+ * name - timer name
+ * id - pointer to timer id
+ *
+ * Output parameters:
+ * id - timer id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_timer_create(
+ rtems_name name,
+ Objects_Id *id
+)
+{
+ Timer_Control *the_timer;
+
+ if ( !rtems_is_name_valid( name ) )
+ return RTEMS_INVALID_NAME;
+
+ if ( !id )
+ return RTEMS_INVALID_ADDRESS;
+
+ _Thread_Disable_dispatch(); /* to prevent deletion */
+
+ the_timer = _Timer_Allocate();
+
+ if ( !the_timer ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+
+ the_timer->the_class = TIMER_DORMANT;
+ _Watchdog_Initialize( &the_timer->Ticker, NULL, 0, NULL );
+
+ _Objects_Open(
+ &_Timer_Information,
+ &the_timer->Object,
+ (Objects_Name) name
+ );
+
+ *id = the_timer->Object.id;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/rtems/src/timerdelete.c b/cpukit/rtems/src/timerdelete.c
new file mode 100644
index 0000000000..f40550e4a2
--- /dev/null
+++ b/cpukit/rtems/src/timerdelete.c
@@ -0,0 +1,66 @@
+/*
+ * Timer Manager - rtems_timer_delete directive
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_timer_delete
+ *
+ * This directive allows a thread to delete a timer.
+ *
+ * Input parameters:
+ * id - timer id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_timer_delete(
+ Objects_Id id
+)
+{
+ Timer_Control *the_timer;
+ Objects_Locations location;
+
+ the_timer = _Timer_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ _Objects_Close( &_Timer_Information, &the_timer->Object );
+ (void) _Watchdog_Remove( &the_timer->Ticker );
+ _Timer_Free( the_timer );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/timerfireafter.c b/cpukit/rtems/src/timerfireafter.c
new file mode 100644
index 0000000000..bb5a2b3adc
--- /dev/null
+++ b/cpukit/rtems/src/timerfireafter.c
@@ -0,0 +1,102 @@
+/*
+ * Timer Manager - rtems_timer_fire_after directive
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_timer_fire_after
+ *
+ * This directive allows a thread to start a timer.
+ *
+ * Input parameters:
+ * id - timer id
+ * ticks - interval until routine is fired
+ * routine - routine to schedule
+ * user_data - passed as argument to routine when it is fired
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_timer_fire_after(
+ Objects_Id id,
+ rtems_interval ticks,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+)
+{
+ Timer_Control *the_timer;
+ Objects_Locations location;
+ ISR_Level level;
+
+ if ( ticks == 0 )
+ return RTEMS_INVALID_NUMBER;
+
+ if ( !routine )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_timer = _Timer_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ (void) _Watchdog_Remove( &the_timer->Ticker );
+
+ _ISR_Disable( level );
+
+ /*
+ * Check to see if the watchdog has just been inserted by a
+ * higher priority interrupt. If so, abandon this insert.
+ */
+
+ if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) {
+ _ISR_Enable( level );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ /*
+ * OK. Now we now the timer was not rescheduled by an interrupt
+ * so we can atomically initialize it as in use.
+ */
+
+ the_timer->the_class = TIMER_INTERVAL;
+ _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
+ _ISR_Enable( level );
+
+
+ _Watchdog_Insert_ticks( &the_timer->Ticker, ticks );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/timerfirewhen.c b/cpukit/rtems/src/timerfirewhen.c
new file mode 100644
index 0000000000..9e165751e6
--- /dev/null
+++ b/cpukit/rtems/src/timerfirewhen.c
@@ -0,0 +1,90 @@
+/*
+ * Timer Manager - rtems_timer_fire_when directive
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_timer_fire_when
+ *
+ * This directive allows a thread to start a timer.
+ *
+ * Input parameters:
+ * id - timer id
+ * wall_time - time of day to fire timer
+ * routine - routine to schedule
+ * user_data - passed as argument to routine when it is fired
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_timer_fire_when(
+ Objects_Id id,
+ rtems_time_of_day *wall_time,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+)
+{
+ Timer_Control *the_timer;
+ Objects_Locations location;
+ rtems_interval seconds;
+
+ if ( !_TOD_Is_set )
+ return RTEMS_NOT_DEFINED;
+
+ if ( !_TOD_Validate( wall_time ) )
+ return RTEMS_INVALID_CLOCK;
+
+ if ( !routine )
+ return RTEMS_INVALID_ADDRESS;
+
+ seconds = _TOD_To_seconds( wall_time );
+ if ( seconds <= _TOD_Seconds_since_epoch )
+ return RTEMS_INVALID_CLOCK;
+
+ the_timer = _Timer_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ (void) _Watchdog_Remove( &the_timer->Ticker );
+ the_timer->the_class = TIMER_TIME_OF_DAY;
+ _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
+ _Watchdog_Insert_seconds(
+ &the_timer->Ticker,
+ seconds - _TOD_Seconds_since_epoch
+ );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/timergetinfo.c b/cpukit/rtems/src/timergetinfo.c
new file mode 100644
index 0000000000..d57f3bf669
--- /dev/null
+++ b/cpukit/rtems/src/timergetinfo.c
@@ -0,0 +1,74 @@
+/*
+ * Timer Manager - rtems_timer_get_information directive
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_timer_get_information
+ *
+ * This directive allows a thread to obtain information about a timer.
+ *
+ * Input parameters:
+ * id - timer id
+ * the_info - pointer to timer information block
+ *
+ * Output parameters:
+ * *the_info - region information block filled in
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ *
+ */
+
+rtems_status_code rtems_timer_get_information(
+ Objects_Id id,
+ rtems_timer_information *the_info
+)
+{
+ Timer_Control *the_timer;
+ Objects_Locations location;
+
+ if ( !the_info )
+ return RTEMS_INVALID_ADDRESS;
+
+ the_timer = _Timer_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ the_info->the_class = the_timer->the_class;
+ the_info->initial = the_timer->Ticker.initial;
+ the_info->start_time = the_timer->Ticker.start_time;
+ the_info->stop_time = the_timer->Ticker.stop_time;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/timerident.c b/cpukit/rtems/src/timerident.c
new file mode 100644
index 0000000000..2996e05ada
--- /dev/null
+++ b/cpukit/rtems/src/timerident.c
@@ -0,0 +1,60 @@
+/*
+ * Timer Manager - rtems_timer_ident directive
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_timer_ident
+ *
+ * This directive returns the system ID associated with
+ * the timer name.
+ *
+ * Input parameters:
+ * name - user defined message queue name
+ * id - pointer to timer id
+ *
+ * Output parameters:
+ * *id - message queue id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_timer_ident(
+ rtems_name name,
+ Objects_Id *id
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ status = _Objects_Name_to_id(
+ &_Timer_Information,
+ (Objects_Name) name,
+ OBJECTS_SEARCH_LOCAL_NODE,
+ id
+ );
+
+ return _Status_Object_name_errors_to_status[ status ];
+}
diff --git a/cpukit/rtems/src/timerreset.c b/cpukit/rtems/src/timerreset.c
new file mode 100644
index 0000000000..36f13cf18d
--- /dev/null
+++ b/cpukit/rtems/src/timerreset.c
@@ -0,0 +1,81 @@
+/*
+ * Timer Manager - rtems_timer_reset directive
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_timer_reset
+ *
+ * This directive allows a thread to reset a timer.
+ *
+ * Input parameters:
+ * id - timer id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_timer_reset(
+ Objects_Id id
+)
+{
+ Timer_Control *the_timer;
+ Objects_Locations location;
+
+ the_timer = _Timer_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ switch ( the_timer->the_class ) {
+ case TIMER_INTERVAL:
+ _Watchdog_Remove( &the_timer->Ticker );
+ _Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker );
+ break;
+ case TIMER_INTERVAL_ON_TASK:
+ _Timer_Server_stop_ticks_timer();
+ _Watchdog_Remove( &the_timer->Ticker );
+ _Timer_Server_process_ticks_chain();
+ _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
+ _Timer_Server_reset_ticks_timer();
+ break;
+ case TIMER_TIME_OF_DAY:
+ case TIMER_TIME_OF_DAY_ON_TASK:
+ case TIMER_DORMANT:
+ _Thread_Enable_dispatch();
+ return RTEMS_NOT_DEFINED;
+ }
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/timerserver.c b/cpukit/rtems/src/timerserver.c
new file mode 100644
index 0000000000..7a5f48f2d6
--- /dev/null
+++ b/cpukit/rtems/src/timerserver.c
@@ -0,0 +1,321 @@
+/*
+ * Timer Manager - rtems_timer_initiate_server directive along with
+ * the Timer Server Body and support routines
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+#include <rtems/rtems/tasks.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/thread.h>
+
+/*
+ * The following chains contain the list of interval timers that are
+ * executed in the context of the Timer Server.
+ *
+ * NOTE: These are prototyped in rtems/timer/timer.h but since we
+ * do not actually use them until after the Timer Server is
+ * initiated, we can actually declare them here and avoid forcing
+ * them into the minimum footprint.
+ */
+
+Chain_Control _Timer_Ticks_chain;
+Chain_Control _Timer_Seconds_chain;
+
+/*
+ * These variables keep track of the last time the Timer Server actually
+ * processed the chain.
+ */
+
+Watchdog_Interval _Timer_Server_seconds_last_time;
+Watchdog_Interval _Timer_Server_ticks_last_time;
+
+/*
+ * The timer used to control when the Timer Server wakes up to service
+ * "when" timers.
+ */
+
+Watchdog_Control _Timer_Seconds_timer;
+
+/*PAGE
+ *
+ * _Timer_Server_body
+ *
+ * This is the server for task based timers. This task executes whenever
+ * a task-based timer should fire. It services both "after" and "when"
+ * timers. It is not created automatically but must be created explicitly
+ * by the application before task-based timers may be initiated.
+ *
+ * Input parameters:
+ * Ignored - the task argument is ignored
+ *
+ * Output parameters: NONE
+ */
+
+Thread _Timer_Server_body(
+ uint32_t ignored
+)
+{
+ /*
+ * Initialize the "last time" markers to indicate the timer that
+ * the server was initiated.
+ */
+
+ _Timer_Server_ticks_last_time = _Watchdog_Ticks_since_boot;
+ _Timer_Server_seconds_last_time = _TOD_Seconds_since_epoch;
+
+ _Thread_Disable_dispatch();
+ while(1) {
+
+ /*
+ * Block until there is something to do.
+ */
+
+ _Thread_Set_state( _Timer_Server, STATES_DELAYING );
+ _Timer_Server_reset_ticks_timer();
+ _Timer_Server_reset_seconds_timer();
+ _Thread_Enable_dispatch();
+
+ /*
+ * At this point, at least one of the timers this task relies
+ * upon has fired. Stop them both while we process any outstanding
+ * timers. Before we block, we will restart them.
+ */
+
+ _Timer_Server_stop_ticks_timer();
+ _Timer_Server_stop_seconds_timer();
+
+ /*
+ * Disable dispatching while processing the timers since we want
+ * to mimic the environment that non-task-based TSRs execute in.
+ * This ensures that the primary difference is that _ISR_Nest_level
+ * is 0 for task-based timers and non-zero for the others.
+ */
+
+ _Thread_Disable_dispatch();
+ _Timer_Server_process_ticks_chain();
+ _Timer_Server_process_seconds_chain();
+ }
+
+ return 0; /* unreached - only to remove warnings */
+}
+
+/*PAGE
+ *
+ * rtems_timer_initiate_server
+ *
+ * This directive creates and starts the server for task-based timers.
+ * It must be invoked before any task-based timers can be initiated.
+ *
+ * Input parameters:
+ * priority - timer server priority
+ * stack_size - stack size in bytes
+ * attribute_set - timer server attributes
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+
+rtems_status_code rtems_timer_initiate_server(
+ uint32_t priority,
+ uint32_t stack_size,
+ rtems_attribute attribute_set
+)
+{
+ rtems_id id;
+ rtems_status_code status;
+ rtems_task_priority _priority;
+
+ /*
+ * Make sure the requested priority is valid.
+ */
+
+ _priority = priority;
+ if ( priority == RTEMS_TIMER_SERVER_DEFAULT_PRIORITY )
+ _priority = 0;
+ else if ( !_RTEMS_tasks_Priority_is_valid( priority ) )
+ return RTEMS_INVALID_PRIORITY;
+
+ /*
+ * Just to make sure the test versus create/start operation are atomic.
+ */
+
+ _Thread_Disable_dispatch();
+
+ if ( _Timer_Server ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_INCORRECT_STATE;
+ }
+
+ /*
+ * Create the Timer Server with the name the name of "TIME". The attribute
+ * RTEMS_SYSTEM_TASK allows us to set a priority to 0 which will makes it
+ * higher than any other task in the system. It can be viewed as a low
+ * priority interrupt. It is also always NO_PREEMPT so it looks like
+ * an interrupt to other tasks.
+ *
+ * We allow the user to override the default priority because the Timer
+ * Server can invoke TSRs which must adhere to language run-time or
+ * other library rules. For example, if using a TSR written in Ada the
+ * Server should run at the same priority as the priority Ada task.
+ * Otherwise, the priority ceiling for the mutex used to protect the
+ * GNAT run-time is violated.
+ */
+
+ status = rtems_task_create(
+ 0x4954454d, /* "TIME" */
+ _priority, /* create with priority 1 since 0 is illegal */
+ stack_size, /* let user specify stack size */
+ RTEMS_NO_PREEMPT, /* no preempt is like an interrupt */
+ /* user may want floating point but we need */
+ /* system task specified for 0 priority */
+ attribute_set | RTEMS_SYSTEM_TASK,
+ &id /* get the id back */
+ );
+ if (status) {
+ _Thread_Enable_dispatch();
+ return status;
+ }
+
+ status = rtems_task_start(
+ id, /* the id from create */
+ (rtems_task_entry) _Timer_Server_body, /* the timer server entry point */
+ 0 /* there is no argument */
+ );
+ if (status) {
+ /*
+ * One would expect a call to rtems_task_delete() here to clean up
+ * but there is actually no way (in normal circumstances) that the
+ * start can fail. The id and starting address are known to be
+ * be good. If this service fails, something is weirdly wrong on the
+ * target such as a stray write in an ISR or incorrect memory layout.
+ */
+ _Thread_Enable_dispatch();
+ return status;
+ }
+
+ /*
+ * We work with the TCB pointer, not the ID, so we need to convert
+ * to a TCB pointer from here out.
+ *
+ * NOTE: Setting the pointer to the Timer Server TCB to a value other than
+ * NULL indicates that task-based timer support is initialized.
+ */
+
+ _Timer_Server = (Thread_Control *)_Objects_Get_local_object(
+ &_RTEMS_tasks_Information,
+ _Objects_Get_index(id)
+ );
+
+ /*
+ * Initialize the timer lists that the server will manage.
+ */
+
+ _Chain_Initialize_empty( &_Timer_Ticks_chain );
+ _Chain_Initialize_empty( &_Timer_Seconds_chain );
+
+ /*
+ * Initialize the timers that will be used to control when the
+ * Timer Server wakes up and services the task-based timers.
+ */
+
+ _Watchdog_Initialize( &_Timer_Server->Timer, _Thread_Delay_ended, id, NULL );
+ _Watchdog_Initialize( &_Timer_Seconds_timer, _Thread_Delay_ended, id, NULL );
+
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * _Timer_Server_process_ticks_chain
+ *
+ * This routine is responsible for adjusting the list of task-based
+ * interval timers to reflect the passage of time.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _Timer_Server_process_ticks_chain(void)
+{
+ Watchdog_Interval snapshot;
+ Watchdog_Interval ticks;
+
+ snapshot = _Watchdog_Ticks_since_boot;
+ if ( snapshot >= _Timer_Server_ticks_last_time )
+ ticks = snapshot - _Timer_Server_ticks_last_time;
+ else
+ ticks = (0xFFFFFFFF - _Timer_Server_ticks_last_time) + snapshot;
+
+ _Timer_Server_ticks_last_time = snapshot;
+ _Watchdog_Adjust( &_Timer_Ticks_chain, WATCHDOG_FORWARD, ticks );
+}
+
+/*PAGE
+ *
+ * _Timer_Server_process_seconds_chain
+ *
+ * This routine is responsible for adjusting the list of task-based
+ * time of day timers to reflect the passage of time.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _Timer_Server_process_seconds_chain(void)
+{
+ Watchdog_Interval snapshot;
+ Watchdog_Interval ticks;
+
+ /*
+ * Process the seconds chain. Start by checking that the Time
+ * of Day (TOD) has not been set backwards. If it has then
+ * we want to adjust the _Timer_Seconds_chain to indicate this.
+ */
+
+ snapshot = _TOD_Seconds_since_epoch;
+ if ( snapshot > _Timer_Server_seconds_last_time ) {
+ /*
+ * This path is for normal forward movement and cases where the
+ * TOD has been set forward.
+ */
+
+ ticks = snapshot - _Timer_Server_seconds_last_time;
+ _Watchdog_Adjust( &_Timer_Seconds_chain, WATCHDOG_FORWARD, ticks );
+
+ } else if ( snapshot < _Timer_Server_seconds_last_time ) {
+ /*
+ * The current TOD is before the last TOD which indicates that
+ * TOD has been set backwards.
+ */
+
+ ticks = _Timer_Server_seconds_last_time - snapshot;
+ _Watchdog_Adjust( &_Timer_Seconds_chain, WATCHDOG_BACKWARD, ticks );
+ }
+ _Timer_Server_seconds_last_time = snapshot;
+}
diff --git a/cpukit/rtems/src/timerserverfireafter.c b/cpukit/rtems/src/timerserverfireafter.c
new file mode 100644
index 0000000000..1c5bddc478
--- /dev/null
+++ b/cpukit/rtems/src/timerserverfireafter.c
@@ -0,0 +1,111 @@
+/*
+ * Timer Manager - rtems_timer_server fire_after directive
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_timer_server_fire_after
+ *
+ * This directive allows a thread to start a timer which will by
+ * executed by the Timer Server when it fires.
+ *
+ * Input parameters:
+ * id - timer id
+ * ticks - interval until routine is fired
+ * routine - routine to schedule
+ * user_data - passed as argument to routine when it is fired
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_timer_server_fire_after(
+ Objects_Id id,
+ rtems_interval ticks,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+)
+{
+ Timer_Control *the_timer;
+ Objects_Locations location;
+ ISR_Level level;
+ extern Chain_Control _Timer_Ticks_chain;
+
+ if ( !_Timer_Server )
+ return RTEMS_INCORRECT_STATE;
+
+ if ( !routine )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( ticks == 0 )
+ return RTEMS_INVALID_NUMBER;
+
+ the_timer = _Timer_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ (void) _Watchdog_Remove( &the_timer->Ticker );
+
+ _ISR_Disable( level );
+
+ /*
+ * Check to see if the watchdog has just been inserted by a
+ * higher priority interrupt. If so, abandon this insert.
+ */
+
+ if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) {
+ _ISR_Enable( level );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ /*
+ * OK. Now we now the timer was not rescheduled by an interrupt
+ * so we can atomically initialize it as in use.
+ */
+
+ the_timer->the_class = TIMER_INTERVAL_ON_TASK;
+ _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
+ the_timer->Ticker.initial = ticks;
+ _ISR_Enable( level );
+
+ _Timer_Server_stop_ticks_timer();
+ _Timer_Server_process_ticks_chain();
+ _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
+ _Timer_Server_reset_ticks_timer();
+
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/rtems/src/timerserverfirewhen.c b/cpukit/rtems/src/timerserverfirewhen.c
new file mode 100644
index 0000000000..329df90ec8
--- /dev/null
+++ b/cpukit/rtems/src/timerserverfirewhen.c
@@ -0,0 +1,98 @@
+/*
+ * Timer Manager - rtems_timer_server fire_when directive
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * rtems_timer_server_fire_when
+ *
+ * This directive allows a thread to start a timer which will by
+ * executed by the Timer Server when it fires.
+ *
+ * Input parameters:
+ * id - timer id
+ * wall_time - time of day to fire timer
+ * routine - routine to schedule
+ * user_data - passed as argument to routine when it is fired
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_timer_server_fire_when(
+ Objects_Id id,
+ rtems_time_of_day *wall_time,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+)
+{
+ Timer_Control *the_timer;
+ Objects_Locations location;
+ rtems_interval seconds;
+ extern Chain_Control _Timer_Seconds_chain;
+
+ if ( !_Timer_Server )
+ return RTEMS_INCORRECT_STATE;
+
+ if ( !_TOD_Is_set )
+ return RTEMS_NOT_DEFINED;
+
+ if ( !routine )
+ return RTEMS_INVALID_ADDRESS;
+
+ if ( !_TOD_Validate( wall_time ) )
+ return RTEMS_INVALID_CLOCK;
+
+ seconds = _TOD_To_seconds( wall_time );
+ if ( seconds <= _TOD_Seconds_since_epoch )
+ return RTEMS_INVALID_CLOCK;
+
+ the_timer = _Timer_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INTERNAL_ERROR;
+
+ case OBJECTS_ERROR:
+ return RTEMS_INVALID_ID;
+
+ case OBJECTS_LOCAL:
+ (void) _Watchdog_Remove( &the_timer->Ticker );
+ the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK;
+ _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
+ the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch;
+
+ _Timer_Server_stop_seconds_timer();
+ _Timer_Server_process_seconds_chain();
+ _Watchdog_Insert( &_Timer_Seconds_chain, &the_timer->Ticker );
+ _Timer_Server_reset_seconds_timer();
+
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/sapi/.cvsignore b/cpukit/sapi/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/sapi/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/sapi/Makefile.am b/cpukit/sapi/Makefile.am
new file mode 100644
index 0000000000..8389d98732
--- /dev/null
+++ b/cpukit/sapi/Makefile.am
@@ -0,0 +1,33 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+include_rtemsdir = $(includedir)/rtems
+
+include_rtems_HEADERS = include/confdefs.h
+include_rtems_HEADERS += include/rtems/config.h include/rtems/extension.h \
+ include/rtems/fatal.h include/rtems/init.h include/rtems/io.h \
+ include/rtems/mptables.h include/rtems/sptables.h
+
+EXTRA_DIST = include/rtems/README
+
+if INLINE
+include_rtems_HEADERS += inline/rtems/extension.inl
+else
+include_rtems_HEADERS += macros/rtems/extension.inl
+endif
+
+## src
+AM_CPPFLAGS += -D__RTEMS_INSIDE__
+
+noinst_LIBRARIES = libsapi.a
+libsapi_a_SOURCES = src/debug.c src/extension.c src/extensioncreate.c \
+ src/extensiondelete.c src/extensionident.c src/fatal.c src/exinit.c \
+ src/io.c src/itronapi.c src/posixapi.c src/rtemsapi.c
+libsapi_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
new file mode 100644
index 0000000000..ae6ba1ada9
--- /dev/null
+++ b/cpukit/sapi/include/confdefs.h
@@ -0,0 +1,1188 @@
+/**
+ * @file rtems/confdefs.h
+ *
+ * This include file contains the configuration table template that will
+ * be instantiated by an application based on the setting of a number
+ * of macros. The macros are documented in the Configuring a System
+ * chapter of the Classic API User's Guide
+ *
+ * The model is to estimate the memory required for each configured item
+ * and sum those estimates. The estimate can be too high or too low for
+ * a variety of reasons:
+ *
+ * Reasons estimate is too high:
+ * + FP contexts (not all tasks are FP)
+ *
+ * Reasons estimate is too low:
+ * + stacks greater than minimum size
+ * + messages
+ * + application must account for device driver resources
+ * + application must account for add-on library resource requirements
+ *
+ * NOTE: Eventually this may be able to take into account some of
+ * the above. This procedure has evolved from just enough to
+ * support the RTEMS Test Suites into something that can be
+ * used remarkably reliably by most applications.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef __CONFIGURATION_TEMPLATE_h
+#define __CONFIGURATION_TEMPLATE_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Include the executive's configuration
+ */
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/apimutex.h>
+
+extern rtems_initialization_tasks_table Initialization_tasks[];
+extern rtems_driver_address_table Device_drivers[];
+extern rtems_configuration_table Configuration;
+extern rtems_multiprocessing_table Multiprocessing_configuration;
+#ifdef RTEMS_POSIX_API
+extern posix_api_configuration_table Configuration_POSIX_API;
+#endif
+#ifdef RTEMS_ITRON_API
+extern itron_api_configuration_table Configuration_ITRON_API;
+#endif
+
+/*
+ * RTEMS C Library and Newlib support
+ */
+
+#ifdef RTEMS_NEWLIB
+#define CONFIGURE_NEWLIB_EXTENSION 1
+#else
+#define CONFIGURE_NEWLIB_EXTENSION 0
+#endif
+
+#define CONFIGURE_MALLOC_REGION 1
+
+/*
+ * File descriptors managed by libio
+ */
+
+#ifndef CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 3
+#endif
+
+#define CONFIGURE_LIBIO_SEMAPHORES \
+ (CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS + 1)
+
+#ifdef CONFIGURE_INIT
+uint32_t rtems_libio_number_iops = CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS;
+#endif
+
+/*
+ * Termios resources
+ */
+
+#ifdef CONFIGURE_TERMIOS_DISABLED
+#define CONFIGURE_TERMIOS_SEMAPHORES 0
+#else
+
+#ifndef CONFIGURE_NUMBER_OF_TERMIOS_PORTS
+#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 1
+#endif
+
+#define CONFIGURE_TERMIOS_SEMAPHORES \
+ ((CONFIGURE_NUMBER_OF_TERMIOS_PORTS * 4) + 1)
+#endif
+
+/*
+ * PTYs
+ */
+
+#ifndef CONFIGURE_MAXIMUM_PTYS
+#define CONFIGURE_MAXIMUM_PTYS 0
+#endif
+
+#ifdef CONFIGURE_INIT
+int rtems_telnetd_maximum_ptys = CONFIGURE_MAXIMUM_PTYS;
+#else
+extern int rtems_telnetd_maximum_ptys;
+#endif
+
+/*
+ * Mount Table Configuration
+ */
+
+#include <rtems/imfs.h>
+
+#ifndef CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK
+#define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK \
+ IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK
+#endif
+#ifdef CONFIGURE_INIT
+ int imfs_rq_memfile_bytes_per_block = CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK;
+#endif /* CONFIGURE_INIT */
+
+#ifdef CONFIGURE_INIT
+#ifndef CONFIGURE_HAS_OWN_MOUNT_TABLE
+rtems_filesystem_mount_table_t configuration_mount_table = {
+#ifdef CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
+ &IMFS_ops,
+#else /* using miniIMFS as base filesystem */
+ &miniIMFS_ops,
+#endif
+ RTEMS_FILESYSTEM_READ_WRITE,
+ NULL,
+ NULL
+};
+
+rtems_filesystem_mount_table_t
+ *rtems_filesystem_mount_table = &configuration_mount_table;
+int rtems_filesystem_mount_table_size = 1;
+#endif
+
+#endif
+
+
+/*
+ * Stack Checker Requirements
+ *
+ * NOTE: This does not automatically enable reporting at program exit.
+ */
+
+#ifdef STACK_CHECKER_ON
+#define CONFIGURE_STACK_CHECKER_EXTENSION 1
+#else
+#define CONFIGURE_STACK_CHECKER_EXTENSION 0
+#endif
+
+/*
+ * Interrupt Stack Space
+ *
+ * NOTE: There is currently no way for the application to override
+ * the interrupt stack size set by the BSP.
+ */
+
+#if (CPU_ALLOCATE_INTERRUPT_STACK == 0)
+#undef CONFIGURE_INTERRUPT_STACK_MEMORY
+#define CONFIGURE_INTERRUPT_STACK_MEMORY 0
+#else
+ #ifndef CONFIGURE_INTERRUPT_STACK_MEMORY
+ #define CONFIGURE_INTERRUPT_STACK_MEMORY RTEMS_MINIMUM_STACK_SIZE
+ #endif
+#endif
+
+/*
+ * Default User Initialization Task Table. This table guarantees that
+ * one user initialization table is defined.
+ */
+
+#ifdef CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#ifdef CONFIGURE_HAS_OWN_INIT_TASK_TABLE
+
+/*
+ * The user is defining their own table information and setting the
+ * appropriate variables.
+ */
+
+#else
+
+#ifndef CONFIGURE_INIT_TASK_NAME
+#define CONFIGURE_INIT_TASK_NAME rtems_build_name( 'U', 'I', '1', ' ' )
+#endif
+
+#ifndef CONFIGURE_INIT_TASK_STACK_SIZE
+#define CONFIGURE_INIT_TASK_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE
+#endif
+
+#ifndef CONFIGURE_INIT_TASK_PRIORITY
+#define CONFIGURE_INIT_TASK_PRIORITY 1
+#endif
+
+#ifndef CONFIGURE_INIT_TASK_ATTRIBUTES
+#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
+#endif
+
+#ifndef CONFIGURE_INIT_TASK_ENTRY_POINT
+#define CONFIGURE_INIT_TASK_ENTRY_POINT Init
+#endif
+
+#ifndef CONFIGURE_INIT_TASK_INITIAL_MODES
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_NO_PREEMPT
+#endif
+
+#ifndef CONFIGURE_INIT_TASK_ARGUMENTS
+#define CONFIGURE_INIT_TASK_ARGUMENTS 0
+#endif
+
+#ifdef CONFIGURE_INIT
+rtems_initialization_tasks_table Initialization_tasks[] = {
+ { CONFIGURE_INIT_TASK_NAME,
+ CONFIGURE_INIT_TASK_STACK_SIZE,
+ CONFIGURE_INIT_TASK_PRIORITY,
+ CONFIGURE_INIT_TASK_ATTRIBUTES,
+ CONFIGURE_INIT_TASK_ENTRY_POINT,
+ CONFIGURE_INIT_TASK_INITIAL_MODES,
+ CONFIGURE_INIT_TASK_ARGUMENTS
+ }
+};
+#endif
+
+#define CONFIGURE_INIT_TASK_TABLE Initialization_tasks
+
+#define CONFIGURE_INIT_TASK_TABLE_SIZE \
+ sizeof(CONFIGURE_INIT_TASK_TABLE) / sizeof(rtems_initialization_tasks_table)
+
+#endif /* CONFIGURE_HAS_OWN_INIT_TASK_TABLE */
+
+#else /* CONFIGURE_RTEMS_INIT_TASKS_TABLE */
+
+#define CONFIGURE_INIT_TASK_TABLE NULL
+#define CONFIGURE_INIT_TASK_TABLE_SIZE 0
+#define CONFIGURE_INIT_TASK_STACK_SIZE 0
+
+#endif
+
+/*
+ * Map obsolete names to current ones
+ *
+ * NOTE: These should be obsoleted in a future release.
+ */
+
+#ifdef CONFIGURE_TEST_NEEDS_TIMER_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
+#endif
+#ifdef CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#endif
+#ifdef CONFIGURE_TEST_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#endif
+#ifdef CONFIGURE_TEST_NEEDS_RTC_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER
+#endif
+#ifdef CONFIGURE_TEST_NEEDS_STUB_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
+#endif
+
+
+/*
+ * Default Device Driver Table. Each driver needed by the test is explicitly
+ * choosen by that test. There is always a null driver entry.
+ */
+
+#define NULL_DRIVER_TABLE_ENTRY \
+ { NULL, NULL, NULL, NULL, NULL, NULL }
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#include <rtems/console.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#include <rtems/clockdrv.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
+#include <rtems/timerdrv.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER
+#include <rtems/rtc.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
+#include <rtems/devnull.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER
+ /* the ide driver needs the ATA driver */
+# ifndef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
+# define CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
+# endif
+#include <libchip/ide_ctrl.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
+#include <libchip/ata.h>
+#endif
+
+#ifndef CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE
+
+#ifdef CONFIGURE_INIT
+rtems_driver_address_table Device_drivers[] = {
+#ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+ CONSOLE_DRIVER_TABLE_ENTRY,
+#endif
+#ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+ CLOCK_DRIVER_TABLE_ENTRY,
+#endif
+#ifdef CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER
+ RTC_DRIVER_TABLE_ENTRY,
+#endif
+#ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
+ DEVNULL_DRIVER_TABLE_ENTRY,
+#endif
+#ifdef CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER
+ IDE_CONTROLLER_DRIVER_TABLE_ENTRY,
+#endif
+#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
+ ATA_DRIVER_TABLE_ENTRY,
+#endif
+#ifdef CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER
+ NULL_DRIVER_TABLE_ENTRY
+#elif !defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER)
+ NULL_DRIVER_TABLE_ENTRY
+#endif
+};
+#endif
+
+#endif /* CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE */
+
+/*
+ * Default the number of drivers per node. This value may be
+ * overridden by the user.
+ */
+
+#define CONFIGURE_NUMBER_OF_DRIVERS \
+ ((sizeof(Device_drivers) / sizeof(rtems_driver_address_table)))
+
+#ifndef CONFIGURE_MAXIMUM_DRIVERS
+#define CONFIGURE_MAXIMUM_DRIVERS CONFIGURE_NUMBER_OF_DRIVERS
+#endif
+
+/*
+ * Default the number of devices per device driver. This value may be
+ * overridden by the user.
+ */
+
+#ifndef CONFIGURE_MAXIMUM_DEVICES
+#define CONFIGURE_MAXIMUM_DEVICES 20
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
+ /*
+ * configure the priority of the ATA driver task
+ */
+# ifndef CONFIGURE_ATA_DRIVER_TASK_PRIORITY
+# define CONFIGURE_ATA_DRIVER_TASK_PRIORITY ATA_DRIVER_TASK_DEFAULT_PRIORITY
+# endif
+# ifdef CONFIGURE_INIT
+ rtems_task_priority ata_driver_task_priority
+ = CONFIGURE_ATA_DRIVER_TASK_PRIORITY;
+# endif /* CONFIGURE_INIT */
+#endif
+
+/*
+ * add bdbuf configuration and values for swapout task priority
+ */
+#ifdef CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+#include <rtems/bdbuf.h>
+/*
+ * configure the priority of the bdbuf swapout task
+ */
+#ifndef CONFIGURE_SWAPOUT_TASK_PRIORITY
+#define CONFIGURE_SWAPOUT_TASK_PRIORITY SWAPOUT_TASK_DEFAULT_PRIORITY
+#endif
+#ifdef CONFIGURE_INIT
+ rtems_task_priority swapout_task_priority
+ = CONFIGURE_SWAPOUT_TASK_PRIORITY;
+#endif /* CONFIGURE_INIT */
+#ifndef CONFIGURE_HAS_OWN_BDBUF_TABLE
+
+#ifndef CONFIGURE_BDBUF_BUFFER_COUNT
+#define CONFIGURE_BDBUF_BUFFER_COUNT 64
+#endif /* CONFIGURE_BDBUF_BUFFER_COUNT */
+
+#ifndef CONFIGURE_BDBUF_BUFFER_SIZE
+#define CONFIGURE_BDBUF_BUFFER_SIZE 512
+#endif /* CONFIGURE_BDBUF_BUFFER_SIZE */
+#ifdef CONFIGURE_INIT
+rtems_bdbuf_config rtems_bdbuf_configuration[] = {
+ {CONFIGURE_BDBUF_BUFFER_SIZE,CONFIGURE_BDBUF_BUFFER_COUNT,NULL}
+};
+int rtems_bdbuf_configuration_size =( sizeof(rtems_bdbuf_configuration)
+ /sizeof(rtems_bdbuf_configuration[0]));
+#endif /* CONFIGURE_INIT */
+#endif /* CONFIGURE_HAS_OWN_BDBUF_TABLE */
+#endif /* CONFIGURE_APPLICATION_NEEDS_LIBBLOCK */
+/*
+ * Default Multiprocessing Configuration Table. The defaults are
+ * appropriate for most of the RTEMS Multiprocessor Test Suite. Each
+ * value may be overridden within each test to customize the environment.
+ */
+
+#ifdef CONFIGURE_MP_APPLICATION
+#ifndef CONFIGURE_HAS_OWN_MULTIPROCESING_TABLE
+
+#ifndef CONFIGURE_MP_NODE_NUMBER
+#define CONFIGURE_MP_NODE_NUMBER NODE_NUMBER
+#endif
+
+#ifndef CONFIGURE_MP_MAXIMUM_NODES
+#define CONFIGURE_MP_MAXIMUM_NODES 2
+#endif
+
+#ifndef CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS
+#define CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS 32
+#endif
+
+#ifndef CONFIGURE_MP_MAXIMUM_PROXIES
+#define CONFIGURE_MP_MAXIMUM_PROXIES 32
+#endif
+
+#ifndef CONFIGURE_MP_MPCI_TABLE_POINTER
+#include <mpci.h>
+#define CONFIGURE_MP_MPCI_TABLE_POINTER &MPCI_table
+#endif
+
+#ifdef CONFIGURE_INIT
+rtems_multiprocessing_table Multiprocessing_configuration = {
+ CONFIGURE_MP_NODE_NUMBER, /* local node number */
+ CONFIGURE_MP_MAXIMUM_NODES, /* maximum # nodes in system */
+ CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS, /* maximum # global objects */
+ CONFIGURE_MP_MAXIMUM_PROXIES, /* maximum # proxies */
+ CONFIGURE_MP_MPCI_TABLE_POINTER /* pointer to MPCI config table */
+};
+#endif
+
+#define CONFIGURE_MULTIPROCESSING_TABLE &Multiprocessing_configuration
+
+#endif /* CONFIGURE_HAS_OWN_MULTIPROCESING_TABLE */
+
+#else
+
+#define CONFIGURE_MULTIPROCESSING_TABLE NULL
+
+#endif /* CONFIGURE_MP_APPLICATION */
+
+/*
+ * Default Configuration Table.
+ */
+
+#ifndef CONFIGURE_HAS_OWN_CONFIGURATION_TABLE
+
+#ifndef CONFIGURE_EXECUTIVE_RAM_WORK_AREA
+#define CONFIGURE_EXECUTIVE_RAM_WORK_AREA NULL
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_TASKS
+#define CONFIGURE_MAXIMUM_TASKS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_TIMERS
+#define CONFIGURE_MAXIMUM_TIMERS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_SEMAPHORES
+#define CONFIGURE_MAXIMUM_SEMAPHORES 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_MESSAGE_QUEUES
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_PARTITIONS
+#define CONFIGURE_MAXIMUM_PARTITIONS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_REGIONS
+#define CONFIGURE_MAXIMUM_REGIONS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_PORTS
+#define CONFIGURE_MAXIMUM_PORTS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_PERIODS
+#define CONFIGURE_MAXIMUM_PERIODS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_USER_EXTENSIONS
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 0
+#endif
+
+#ifndef CONFIGURE_MICROSECONDS_PER_TICK
+#define CONFIGURE_MICROSECONDS_PER_TICK RTEMS_MILLISECONDS_TO_MICROSECONDS(10)
+#endif
+
+#ifndef CONFIGURE_TICKS_PER_TIMESLICE
+#define CONFIGURE_TICKS_PER_TIMESLICE 50
+#endif
+
+/*
+ * Initial Extension Set
+ */
+
+#ifdef CONFIGURE_INIT
+#ifdef STACK_CHECKER_ON
+#include <rtems/stackchk.h>
+#endif
+
+#if defined(CONFIGURE_INITIAL_EXTENSIONS) || \
+ defined(STACK_CHECKER_ON)
+rtems_extensions_table Configuration_Initial_Extensions[] = {
+#ifdef CONFIGURE_INITIAL_EXTENSIONS
+ CONFIGURE_INITIAL_EXTENSIONS,
+#endif
+#ifdef STACK_CHECKER_ON
+ STACK_CHECKER_EXTENSION,
+#endif
+};
+
+#define CONFIGURE_INITIAL_EXTENSION_TABLE Configuration_Initial_Extensions
+#define CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS \
+ ((sizeof(Configuration_Initial_Extensions) / \
+ sizeof(rtems_extensions_table)))
+#else
+#define CONFIGURE_INITIAL_EXTENSION_TABLE NULL
+#define CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS 0
+#endif
+
+
+#endif
+
+/*
+ * POSIX API Configuration Parameters
+ */
+
+#ifdef RTEMS_POSIX_API
+
+#include <sys/types.h>
+#include <signal.h>
+#include <limits.h>
+#include <mqueue.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/key.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/threadsup.h>
+#include <rtems/posix/timer.h>
+
+#ifndef CONFIGURE_MAXIMUM_POSIX_THREADS
+#define CONFIGURE_MAXIMUM_POSIX_THREADS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_POSIX_MUTEXES
+#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES
+#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_POSIX_KEYS
+#define CONFIGURE_MAXIMUM_POSIX_KEYS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_POSIX_TIMERS
+#define CONFIGURE_MAXIMUM_POSIX_TIMERS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS
+#define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES
+#define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_POSIX_SEMAPHORES
+#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 0
+#endif
+
+#ifdef CONFIGURE_POSIX_INIT_THREAD_TABLE
+
+#ifdef CONFIGURE_POSIX_HAS_OWN_INIT_THREAD_TABLE
+
+/*
+ * The user is defining their own table information and setting the
+ * appropriate variables for the POSIX Initialization Thread Table.
+ */
+
+#else
+
+#ifndef CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT
+#define CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT POSIX_Init
+#endif
+
+#ifndef CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE
+#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (RTEMS_MINIMUM_STACK_SIZE * 2)
+#endif
+
+#ifdef CONFIGURE_INIT
+posix_initialization_threads_table POSIX_Initialization_threads[] = {
+ { CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT, \
+ CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE }
+};
+#endif
+
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME POSIX_Initialization_threads
+
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE \
+ sizeof(CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME) / \
+ sizeof(posix_initialization_threads_table)
+
+#endif /* CONFIGURE_POSIX_HAS_OWN_INIT_TASK_TABLE */
+
+#else /* CONFIGURE_POSIX_INIT_THREAD_TABLE */
+
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME NULL
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE 0
+
+#endif
+
+#define CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API \
+ ( \
+ sizeof (POSIX_API_Control) + \
+ (sizeof (void *) * (CONFIGURE_GNAT_KEYS + CONFIGURE_MAXIMUM_POSIX_KEYS)) \
+ )
+
+#define CONFIGURE_MEMORY_FOR_POSIX_MUTEXES(_mutexes) \
+ ((_mutexes) * \
+ ( sizeof(POSIX_Mutex_Control) + CONFIGURE_OBJECT_TABLE_STUFF + \
+ NAME_MAX ) )
+
+#define CONFIGURE_MEMORY_FOR_POSIX_CONDITION_VARIABLES(_condition_variables) \
+ ((_condition_variables) * \
+ ( sizeof(POSIX_Condition_variables_Control) + \
+ CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys) \
+ ((_keys) * \
+ ( sizeof(POSIX_Keys_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_POSIX_TIMERS(_timers) \
+ ((_timers) * (sizeof(POSIX_Timer_Control) + CONFIGURE_OBJECT_TABLE_STUFF))
+
+#define CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS(_queued_signals) \
+ ((_queued_signals) * \
+ ( sizeof(POSIX_signals_Siginfo_node) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES(_message_queues) \
+ ((_message_queues) * \
+ ( sizeof( POSIX_Message_queue_Control) + \
+ CONFIGURE_OBJECT_TABLE_STUFF + \
+ NAME_MAX ) )
+#define CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES(_semaphores) \
+ ((_semaphores) * \
+ ( sizeof( POSIX_Semaphore_Control) + \
+ CONFIGURE_OBJECT_TABLE_STUFF + \
+ NAME_MAX ) )
+
+#define CONFIGURE_MEMORY_FOR_POSIX \
+ ( \
+ CONFIGURE_MEMORY_FOR_POSIX_MUTEXES( CONFIGURE_MAXIMUM_POSIX_MUTEXES ) + \
+ CONFIGURE_MEMORY_FOR_POSIX_CONDITION_VARIABLES( \
+ CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES ) + \
+ CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS ) + \
+ CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS( \
+ CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS ) + \
+ CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES( \
+ CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES ) + \
+ CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES( \
+ CONFIGURE_MAXIMUM_POSIX_SEMAPHORES ) + \
+ CONFIGURE_MEMORY_FOR_POSIX_TIMERS( CONFIGURE_MAXIMUM_POSIX_TIMERS ) + \
+ (CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE) \
+ )
+
+
+#else
+
+#define CONFIGURE_MAXIMUM_POSIX_THREADS 0
+#define CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API 0
+#define CONFIGURE_MEMORY_FOR_POSIX 0
+
+
+#endif /* RTEMS_POSIX_API */
+
+#ifndef CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE
+#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE 0
+#endif
+
+/*
+ * ITRON API Configuration Parameters
+ */
+
+#ifdef RTEMS_ITRON_API
+
+#include <rtems/itron.h>
+#include <rtems/itron/config.h>
+#include <rtems/itron/eventflags.h>
+#include <rtems/itron/fmempool.h>
+#include <rtems/itron/mbox.h>
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/port.h>
+#include <rtems/itron/semaphore.h>
+#include <rtems/itron/task.h>
+#include <rtems/itron/vmempool.h>
+
+#ifndef CONFIGURE_MAXIMUM_ITRON_TASKS
+#define CONFIGURE_MAXIMUM_ITRON_TASKS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_ITRON_SEMAPHORES
+#define CONFIGURE_MAXIMUM_ITRON_SEMAPHORES 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_ITRON_EVENTFLAGS
+#define CONFIGURE_MAXIMUM_ITRON_EVENTFLAGS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_ITRON_MAILBOXES
+#define CONFIGURE_MAXIMUM_ITRON_MAILBOXES 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_ITRON_MESSAGE_BUFFERS
+#define CONFIGURE_MAXIMUM_ITRON_MESSAGE_BUFFERS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_ITRON_PORTS
+#define CONFIGURE_MAXIMUM_ITRON_PORTS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_ITRON_MEMORY_POOLS
+#define CONFIGURE_MAXIMUM_ITRON_MEMORY_POOLS 0
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_ITRON_FIXED_MEMORY_POOLS
+#define CONFIGURE_MAXIMUM_ITRON_FIXED_MEMORY_POOLS 0
+#endif
+
+#ifdef CONFIGURE_ITRON_INIT_TASK_TABLE
+
+#ifdef CONFIGURE_ITRON_HAS_OWN_INIT_TASK_TABLE
+
+/*
+ * The user is defining their own table information and setting the
+ * appropriate variables for the ITRON Initialization Task Table.
+ */
+
+#else
+
+#ifndef CONFIGURE_ITRON_INIT_TASK_ENTRY_POINT
+#define CONFIGURE_ITRON_INIT_TASK_ENTRY_POINT ITRON_Init
+#endif
+
+#ifndef CONFIGURE_ITRON_INIT_TASK_ATTRIBUTES
+#define CONFIGURE_ITRON_INIT_TASK_ATTRIBUTES TA_HLNG
+#endif
+
+#ifndef CONFIGURE_ITRON_INIT_TASK_PRIORITY
+#define CONFIGURE_ITRON_INIT_TASK_PRIORITY 1
+#endif
+
+#ifndef CONFIGURE_ITRON_INIT_TASK_STACK_SIZE
+#define CONFIGURE_ITRON_INIT_TASK_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE
+#endif
+
+#ifdef CONFIGURE_INIT
+itron_initialization_tasks_table ITRON_Initialization_tasks[] = {
+ { 1, /* ID */
+ { (VP) 0, /* exinfo */
+ CONFIGURE_ITRON_INIT_TASK_ATTRIBUTES, /* task attributes */
+ CONFIGURE_ITRON_INIT_TASK_ENTRY_POINT, /* task start address */
+ CONFIGURE_ITRON_INIT_TASK_PRIORITY, /* initial task priority */
+ CONFIGURE_ITRON_INIT_TASK_STACK_SIZE /* stack size */
+ }
+ }
+};
+#endif
+
+#define CONFIGURE_ITRON_INIT_TASK_TABLE_NAME ITRON_Initialization_tasks
+
+#define CONFIGURE_ITRON_INIT_TASK_TABLE_SIZE \
+ sizeof(CONFIGURE_ITRON_INIT_TASK_TABLE_NAME) / \
+ sizeof(itron_initialization_tasks_table)
+
+#endif /* CONFIGURE_ITRON_HAS_OWN_INIT_TASK_TABLE */
+
+#else /* CONFIGURE_ITRON_INIT_TASK_TABLE */
+
+#define CONFIGURE_ITRON_INIT_TASK_TABLE_NAME NULL
+#define CONFIGURE_ITRON_INIT_TASK_TABLE_SIZE 0
+
+#endif
+
+#define CONFIGURE_MEMORY_PER_TASK_FOR_ITRON_API \
+ ( \
+ sizeof (ITRON_API_Control) \
+ )
+
+#define CONFIGURE_MEMORY_FOR_ITRON_SEMAPHORES(_semaphores) \
+ ((_semaphores) * \
+ ( sizeof(ITRON_Semaphore_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_ITRON_EVENTFLAGS(_eventflags) \
+ ((_eventflags) * \
+ ( sizeof(ITRON_Eventflags_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_ITRON_MAILBOXES(_mailboxes) \
+ ((_mailboxes) * \
+ ( sizeof(ITRON_Mailbox_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_ITRON_MESSAGE_BUFFERS(_message_buffers) \
+ ((_message_buffers) * \
+ ( sizeof(ITRON_Message_buffer_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_ITRON_PORTS(_ports) \
+ ((_ports) * \
+ ( sizeof(ITRON_Port_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_ITRON_MEMORY_POOLS(_memory_pools) \
+ ((_memory_pools) * \
+ (sizeof(ITRON_Variable_memory_pool_Control) + CONFIGURE_OBJECT_TABLE_STUFF))
+
+#define CONFIGURE_MEMORY_FOR_ITRON_FIXED_MEMORY_POOLS(_fixed_memory_pools) \
+ ((_fixed_memory_pools) * \
+ ( sizeof(ITRON_Fixed_memory_pool_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#ifndef CONFIGURE_ITRON_INIT_TASK_STACK_SIZE
+#define CONFIGURE_ITRON_INIT_TASK_STACK_SIZE (RTEMS_MINIMUM_STACK_SIZE * 2)
+#endif
+
+
+#define CONFIGURE_MEMORY_FOR_ITRON \
+ ( \
+ CONFIGURE_MEMORY_FOR_ITRON_SEMAPHORES( \
+ CONFIGURE_MAXIMUM_ITRON_SEMAPHORES ) + \
+ CONFIGURE_MEMORY_FOR_ITRON_EVENTFLAGS( \
+ CONFIGURE_MAXIMUM_ITRON_EVENTFLAGS ) + \
+ CONFIGURE_MEMORY_FOR_ITRON_MAILBOXES( \
+ CONFIGURE_MAXIMUM_ITRON_MAILBOXES ) + \
+ CONFIGURE_MEMORY_FOR_ITRON_MESSAGE_BUFFERS( \
+ CONFIGURE_MAXIMUM_ITRON_MESSAGE_BUFFERS ) + \
+ CONFIGURE_MEMORY_FOR_ITRON_PORTS( \
+ CONFIGURE_MAXIMUM_ITRON_PORTS ) + \
+ CONFIGURE_MEMORY_FOR_ITRON_MEMORY_POOLS( \
+ CONFIGURE_MAXIMUM_ITRON_MEMORY_POOLS ) + \
+ CONFIGURE_MEMORY_FOR_ITRON_FIXED_MEMORY_POOLS( \
+ CONFIGURE_MAXIMUM_ITRON_FIXED_MEMORY_POOLS ) + \
+ CONFIGURE_ITRON_INIT_TASK_STACK_SIZE \
+ )
+
+
+#else
+
+#define CONFIGURE_MAXIMUM_ITRON_TASKS 0
+#define CONFIGURE_MAXIMUM_ITRON_SEMAPHORES 0
+#define CONFIGURE_MAXIMUM_ITRON_EVENTFLAGS 0
+#define CONFIGURE_MAXIMUM_ITRON_MAILBOXES 0
+#define CONFIGURE_MAXIMUM_ITRON_MESSAGE_BUFFERS 0
+#define CONFIGURE_MAXIMUM_ITRON_PORTS 0
+#define CONFIGURE_MAXIMUM_ITRON_MEMORY_POOLS 0
+#define CONFIGURE_MAXIMUM_ITRON_FIXED_MEMORY_POOLS 0
+#define CONFIGURE_MEMORY_PER_TASK_FOR_ITRON_API 0
+#define CONFIGURE_MEMORY_FOR_ITRON 0
+
+#endif /* RTEMS_ITRON_API */
+
+
+/*
+ * Calculate the RAM size based on the maximum number of objects configured.
+ */
+
+#ifndef CONFIGURE_EXECUTIVE_RAM_SIZE
+
+#define CONFIGURE_OBJECT_TABLE_STUFF \
+ ( sizeof(Objects_Control *) + sizeof(rtems_name *) + sizeof(rtems_name) )
+
+#if defined(RTEMS_NEWLIB)
+#include <reent.h>
+
+#define CONFIGURE_MEMORY_PER_TASK_FOR_LIBC_REENTRANCY sizeof(struct _reent)
+#else
+#define CONFIGURE_MEMORY_PER_TASK_FOR_LIBC_REENTRANCY 0
+#endif
+
+#define CONFIGURE_MEMORY_FOR_TASKS(_tasks) \
+ (((_tasks) + 1 ) * \
+ ((sizeof(Thread_Control) + CONTEXT_FP_SIZE + \
+ STACK_MINIMUM_SIZE + sizeof( RTEMS_API_Control ) + \
+ CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API + \
+ CONFIGURE_MEMORY_PER_TASK_FOR_ITRON_API + \
+ CONFIGURE_MEMORY_PER_TASK_FOR_LIBC_REENTRANCY + \
+ CONFIGURE_OBJECT_TABLE_STUFF)) \
+ )
+
+#define CONFIGURE_MEMORY_FOR_TIMERS(_timers) \
+ ((_timers) * ( sizeof(Timer_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_SEMAPHORES(_semaphores) \
+ ((_semaphores) * \
+ ( sizeof(Semaphore_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(_queues) \
+ ( (_queues) * \
+ ( sizeof(Message_queue_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_PARTITIONS(_partitions) \
+ ( (_partitions) * \
+ ( sizeof(Partition_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_REGIONS(_regions) \
+ ( (_regions) * \
+ ( sizeof(Region_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_PORTS(_ports) \
+ ( (_ports) * \
+ ( sizeof(Dual_ported_memory_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_PERIODS(_periods) \
+ ( (_periods) * \
+ ( sizeof(Rate_monotonic_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_USER_EXTENSIONS(_extensions) \
+ ( (_extensions) * \
+ ( sizeof(Extension_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) )
+
+#define CONFIGURE_MEMORY_FOR_DEVICES(_devices) \
+ (((_devices) + 1) * ( sizeof(rtems_driver_name_t) ) )
+
+#ifdef CONFIGURE_MP_APPLICATION
+
+#ifndef CONFIGURE_HAS_OWN_MULTIPROCESING_TABLE
+
+#define CONFIGURE_MEMORY_FOR_PROXIES(_proxies) \
+ ( ((_proxies) + 1) * ( sizeof(Thread_Proxy_control) ) )
+
+#define CONFIGURE_MEMORY_FOR_GLOBAL_OBJECTS(_global_objects) \
+ ((_global_objects) * ( sizeof(Objects_MP_Control) ) )
+
+#define CONFIGURE_MEMORY_FOR_MP \
+ ( CONFIGURE_MEMORY_FOR_PROXIES(CONFIGURE_MP_MAXIMUM_PROXIES) + \
+ CONFIGURE_MEMORY_FOR_GLOBAL_OBJECTS(CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS) + \
+ CONFIGURE_MEMORY_FOR_TASKS(1) \
+ )
+
+#endif /* CONFIGURE_HAS_OWN_MULTIPROCESING_TABLE */
+
+#else
+
+#define CONFIGURE_MEMORY_FOR_MP 0
+
+#endif
+
+#ifndef CONFIGURE_MEMORY_OVERHEAD
+#define CONFIGURE_MEMORY_OVERHEAD 0
+#endif
+
+#ifndef CONFIGURE_EXTRA_TASK_STACKS
+#define CONFIGURE_EXTRA_TASK_STACKS 0
+#endif
+
+#define CONFIGURE_API_MUTEX_MEMORY \
+ ( (1) * \
+ ( sizeof(API_Mutex_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) \
+ )
+
+#define CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD \
+ ( CONFIGURE_MEMORY_FOR_TASKS(1) + /* IDLE */ \
+ (256 * 12) + /* Ready chains */ \
+ 256 + /* name/ptr table overhead */ \
+ CONFIGURE_INTERRUPT_STACK_MEMORY + /* interrupt stack */ \
+ CONFIGURE_API_MUTEX_MEMORY /* allocation mutex */ \
+ )
+
+/*
+ * Now account for any extra memory that initialization tasks or threads
+ * may have requested.
+ */
+
+#ifdef RTEMS_POSIX_API
+#define CONFIGURE_INITIALIZATION_THREADS_STACKS_POSIX_PART \
+ (CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE - RTEMS_MINIMUM_STACK_SIZE)
+#else
+#define CONFIGURE_INITIALIZATION_THREADS_STACKS_POSIX_PART 0
+#endif
+#ifdef RTEMS_ITRON_API
+#define CONFIGURE_INITIALIZATION_THREADS_STACKS_ITRON_PART \
+ (CONFIGURE_ITRON_INIT_TASK_STACK_SIZE - RTEMS_MINIMUM_STACK_SIZE)
+#else
+#define CONFIGURE_INITIALIZATION_THREADS_STACKS_ITRON_PART 0
+#endif
+
+#define CONFIGURE_INITIALIZATION_THREADS_STACKS \
+ ((CONFIGURE_INIT_TASK_STACK_SIZE - RTEMS_MINIMUM_STACK_SIZE) + \
+ CONFIGURE_INITIALIZATION_THREADS_STACKS_POSIX_PART + \
+ CONFIGURE_INITIALIZATION_THREADS_STACKS_ITRON_PART)
+
+#define CONFIGURE_EXECUTIVE_RAM_SIZE \
+(( CONFIGURE_MEMORY_FOR_POSIX + \
+ CONFIGURE_MEMORY_FOR_ITRON + \
+ CONFIGURE_MEMORY_FOR_TASKS(CONFIGURE_MAXIMUM_TASKS + \
+ CONFIGURE_MAXIMUM_POSIX_THREADS + CONFIGURE_MAXIMUM_ADA_TASKS + \
+ CONFIGURE_MAXIMUM_ITRON_TASKS ) + \
+ CONFIGURE_INITIALIZATION_THREADS_STACKS + \
+ CONFIGURE_MEMORY_FOR_TIMERS(CONFIGURE_MAXIMUM_TIMERS) + \
+ CONFIGURE_MEMORY_FOR_SEMAPHORES(CONFIGURE_MAXIMUM_SEMAPHORES + \
+ CONFIGURE_LIBIO_SEMAPHORES + CONFIGURE_TERMIOS_SEMAPHORES) + \
+ CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(CONFIGURE_MAXIMUM_MESSAGE_QUEUES) + \
+ CONFIGURE_MEMORY_FOR_PARTITIONS(CONFIGURE_MAXIMUM_PARTITIONS) + \
+ CONFIGURE_MEMORY_FOR_REGIONS( \
+ CONFIGURE_MAXIMUM_REGIONS + CONFIGURE_MALLOC_REGION ) + \
+ CONFIGURE_MEMORY_FOR_PORTS(CONFIGURE_MAXIMUM_PORTS) + \
+ CONFIGURE_MEMORY_FOR_PERIODS(CONFIGURE_MAXIMUM_PERIODS) + \
+ CONFIGURE_MEMORY_FOR_USER_EXTENSIONS( \
+ CONFIGURE_MAXIMUM_USER_EXTENSIONS + CONFIGURE_NEWLIB_EXTENSION + \
+ CONFIGURE_STACK_CHECKER_EXTENSION ) + \
+ CONFIGURE_MEMORY_FOR_DEVICES(CONFIGURE_MAXIMUM_DEVICES) + \
+ CONFIGURE_MEMORY_FOR_MP + \
+ CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD + \
+ (((CONFIGURE_MEMORY_OVERHEAD)+1) * 1024) + \
+ (CONFIGURE_EXTRA_TASK_STACKS) + (CONFIGURE_ADA_TASKS_STACK) \
+) & 0xfffffc00)
+#endif
+
+#ifdef CONFIGURE_GNAT_RTEMS
+#define CONFIGURE_GNAT_MUTEXES 10
+#define CONFIGURE_GNAT_KEYS 1
+
+/* 20 are required to run all tests in the ACVC */
+#ifndef CONFIGURE_MAXIMUM_ADA_TASKS
+#define CONFIGURE_MAXIMUM_ADA_TASKS 20
+#endif
+
+/* This is the number of non-Ada tasks which invoked Ada code. */
+#ifndef CONFIGURE_MAXIMUM_FAKE_ADA_TASKS
+#define CONFIGURE_MAXIMUM_FAKE_ADA_TASKS 0
+#endif
+
+/* Ada tasks are allocated twice the minimum stack space */
+#define CONFIGURE_ADA_TASKS_STACK \
+ (CONFIGURE_MAXIMUM_ADA_TASKS * (RTEMS_MINIMUM_STACK_SIZE + (6 * 1024)))
+
+#else
+#define CONFIGURE_GNAT_MUTEXES 0
+#define CONFIGURE_GNAT_KEYS 0
+#define CONFIGURE_MAXIMUM_ADA_TASKS 0
+#define CONFIGURE_MAXIMUM_FAKE_ADA_TASKS 0
+#define CONFIGURE_ADA_TASKS_STACK 0
+#endif
+
+
+#ifdef CONFIGURE_INIT
+
+rtems_api_configuration_table Configuration_RTEMS_API = {
+ CONFIGURE_MAXIMUM_TASKS,
+ CONFIGURE_MAXIMUM_TIMERS,
+ CONFIGURE_MAXIMUM_SEMAPHORES + CONFIGURE_LIBIO_SEMAPHORES +
+ CONFIGURE_TERMIOS_SEMAPHORES,
+ CONFIGURE_MAXIMUM_MESSAGE_QUEUES,
+ CONFIGURE_MAXIMUM_PARTITIONS,
+ CONFIGURE_MAXIMUM_REGIONS + CONFIGURE_MALLOC_REGION,
+ CONFIGURE_MAXIMUM_PORTS,
+ CONFIGURE_MAXIMUM_PERIODS,
+ CONFIGURE_INIT_TASK_TABLE_SIZE,
+ CONFIGURE_INIT_TASK_TABLE
+};
+
+#ifdef RTEMS_POSIX_API
+posix_api_configuration_table Configuration_POSIX_API = {
+ CONFIGURE_MAXIMUM_POSIX_THREADS + CONFIGURE_MAXIMUM_ADA_TASKS,
+ CONFIGURE_MAXIMUM_POSIX_MUTEXES + CONFIGURE_GNAT_MUTEXES +
+ CONFIGURE_MAXIMUM_ADA_TASKS + CONFIGURE_MAXIMUM_FAKE_ADA_TASKS,
+ CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES +
+ CONFIGURE_MAXIMUM_ADA_TASKS + CONFIGURE_MAXIMUM_FAKE_ADA_TASKS,
+ CONFIGURE_MAXIMUM_POSIX_KEYS + CONFIGURE_GNAT_KEYS,
+ CONFIGURE_MAXIMUM_POSIX_TIMERS,
+ CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS,
+ CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES,
+ CONFIGURE_MAXIMUM_POSIX_SEMAPHORES,
+ CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE,
+ CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME
+};
+#endif
+
+#ifdef RTEMS_ITRON_API
+itron_api_configuration_table Configuration_ITRON_API = {
+ CONFIGURE_MAXIMUM_ITRON_TASKS,
+ CONFIGURE_MAXIMUM_ITRON_SEMAPHORES,
+ CONFIGURE_MAXIMUM_ITRON_EVENTFLAGS,
+ CONFIGURE_MAXIMUM_ITRON_MAILBOXES,
+ CONFIGURE_MAXIMUM_ITRON_MESSAGE_BUFFERS,
+ CONFIGURE_MAXIMUM_ITRON_PORTS,
+ CONFIGURE_MAXIMUM_ITRON_MEMORY_POOLS,
+ CONFIGURE_MAXIMUM_ITRON_FIXED_MEMORY_POOLS,
+ CONFIGURE_ITRON_INIT_TASK_TABLE_SIZE,
+ CONFIGURE_ITRON_INIT_TASK_TABLE_NAME
+};
+#endif
+
+rtems_configuration_table Configuration = {
+ CONFIGURE_EXECUTIVE_RAM_WORK_AREA,
+ CONFIGURE_EXECUTIVE_RAM_SIZE,
+ CONFIGURE_MAXIMUM_USER_EXTENSIONS + CONFIGURE_NEWLIB_EXTENSION +
+ CONFIGURE_STACK_CHECKER_EXTENSION,
+ CONFIGURE_MICROSECONDS_PER_TICK,
+ CONFIGURE_TICKS_PER_TIMESLICE,
+ CONFIGURE_MAXIMUM_DEVICES,
+ CONFIGURE_MAXIMUM_DRIVERS,
+ CONFIGURE_NUMBER_OF_DRIVERS, /* number of device drivers */
+ Device_drivers, /* pointer to driver table */
+ CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS, /* number of initial extensions */
+ CONFIGURE_INITIAL_EXTENSION_TABLE, /* pointer to initial extensions */
+ CONFIGURE_MULTIPROCESSING_TABLE, /* pointer to MP config table */
+ &Configuration_RTEMS_API, /* pointer to RTEMS API config */
+#ifdef RTEMS_POSIX_API
+ &Configuration_POSIX_API, /* pointer to POSIX API config */
+#else
+ NULL, /* pointer to POSIX API config */
+#endif
+#ifdef RTEMS_ITRON_API
+ &Configuration_ITRON_API /* pointer to ITRON API config */
+#else
+ NULL /* pointer to ITRON API config */
+#endif
+};
+#endif
+
+#endif /* CONFIGURE_HAS_OWN_CONFIGURATION_TABLE */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * Some warnings and error checking
+ */
+
+/*
+ * Make sure a task/thread of some sort is configured
+ */
+
+#if (CONFIGURE_MAXIMUM_TASKS == 0) && \
+ (CONFIGURE_MAXIMUM_POSIX_THREADS == 0) && \
+ (CONFIGURE_MAXIMUM_ADA_TASKS == 0) && \
+ (CONFIGURE_MAXIMUM_ITRON_TASKS == 0)
+#error "CONFIGURATION ERROR: No tasks or threads configured!!"
+#endif
+
+/*
+ * Make sure at least one of the initialization task/thread
+ * tables was defined.
+ */
+
+#if !defined(CONFIGURE_RTEMS_INIT_TASKS_TABLE) && \
+ !defined(CONFIGURE_POSIX_INIT_THREAD_TABLE) && \
+ !defined(CONFIGURE_ITRON_INIT_TASK_TABLE)
+#error "CONFIGURATION ERROR: No initialization tasks or threads configured!!"
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/sapi/include/rtems/README b/cpukit/sapi/include/rtems/README
new file mode 100644
index 0000000000..f29bdb45b7
--- /dev/null
+++ b/cpukit/sapi/include/rtems/README
@@ -0,0 +1,133 @@
+#
+# $Id$
+#
+
+Configuring a System Using the Template in confdefs.h
+=====================================================
+
+The file confdefs.h is a Configuration Template file which can be
+used to greatly simplify the creation and maintenance of RTEMS
+Configuration Tables. The basic concepts are:
+
+ + confdefs.h provides defaults for all configuration parameters
+
+ + applications specify only those values they wish to override
+
+ + confdefs.h can be the only file which knows the precise layout
+ of the RTEMS Configuration Tables.
+
+The Configuration Template setup is used by all RTEMS tests to
+simplify the maintenance of the tests.
+
+Here is the section from the system.h file from test tm21 from
+the Timing Test Suite:
+
+ /* configuration information */
+
+ #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+ #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
+
+ #define CONFIGURE_MAXIMUM_TASKS 102
+ #define CONFIGURE_MAXIMUM_TIMERS 100
+ #define CONFIGURE_MAXIMUM_SEMAPHORES 100
+ #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 100
+ #define CONFIGURE_MAXIMUM_PARTITIONS 100
+ #define CONFIGURE_MAXIMUM_REGIONS 100
+ #define CONFIGURE_MAXIMUM_PORTS 100
+ #define CONFIGURE_MAXIMUM_PERIODS 100
+
+ #define CONFIGURE_TICKS_PER_TIMESLICE 0
+
+ #include <confdefs.h>
+
+
+The above example overrides a number of the configuration parameters.
+It informs the template that it is a member of the Timing Suite,
+requires a console and timer driver, and that it needs 102 tasks,
+100 timers, 100 semaphores, 100 message queues, 100 partitions,
+100 regions, 100 ports, and 100 periods. By default, the test
+would have gotten no drivers, 10 tasks, and no other RTEMS objects.
+
+The following shows the configuration tables generated by the
+template by default.
+
+
+#include <bsp.h>
+
+#define NULL_DRIVER_TABLE_ENTRY \
+ { NULL, NULL, NULL, NULL, NULL, NULL }
+
+rtems_driver_address_table Device_drivers[] = {
+#ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+ CONSOLE_DRIVER_TABLE_ENTRY,
+#endif
+#ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+ CLOCK_DRIVER_TABLE_ENTRY,
+#endif
+#ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
+ STUB_DRIVER_TABLE_ENTRY,
+#endif
+ NULL_DRIVER_TABLE_ENTRY,
+};
+
+rtems_initialization_tasks_table Initialization_tasks[] = {
+ { rtems_build_name( 'U', 'I', '1', ' ' ), /* init task name */
+ RTEMS_MINIMUM_STACK_SIZE, /* init task stack size */
+ 1, /* init task priority */
+ RTEMS_DEFAULT_ATTRIBUTES, /* init task attributes */
+ Init, /* init task entry point */
+ RTEMS_NO_PREEMPT, /* init task initial mode */
+ 0 /* init task argument list */
+ }
+};
+
+#ifdef CONFIGURE_MP_APPLICATION
+/*
+ * NODE_NUMBER is assumed to be set on the compile line.
+ */
+
+rtems_multiprocessing_table Multiprocessing_configuration = {
+ NODE_NUMBER, /* local node number */
+ 2, /* maximum # nodes in system */
+ 32, /* maximum # global objects */
+ 32, /* maximum # proxies */
+ &MPCI_table /* pointer to MPCI config table */
+};
+#endif
+
+/*
+ * CONFIGURE_EXECUTIVE_RAM_SIZE is a rough guess based on the number of
+ * tasks in the system plus enough extra to get a whole 64K extra.
+ *
+ * The NULL address for the workspace area is assumed to be assigned
+ * at startup time by the BSP.
+ */
+
+rtems_configuration_table Configuration = {
+ NULL, /* executive RAM work area */
+ CONFIGURE_EXECUTIVE_RAM_SIZE, /* executive RAM size */
+ 10, /* maximum # tasks */
+ 0, /* maximum # timers */
+ 0, /* maximum # semaphores */
+ 0, /* maximum # message queues */
+ 0, /* maximum # messages */
+ 0, /* maximum # partitions */
+ 0, /* maximum # regions */
+ 0, /* maximum # dp memory areas */
+ 0, /* maximum # periods */
+ 0, /* maximum # user extensions */
+ RTEMS_MILLISECONDS_TO_MICROSECONDS(10), /* # us in a tick */
+ 50, /* # ticks in a timeslice */
+ sizeof (Initialization_tasks) / sizeof(rtems_initialization_tasks_table),
+ /* number of init tasks */
+ Initialization_tasks, /* init task(s) table */
+ sizeof (Device_drivers) / sizeof(rtems_driver_address_table),
+ /* number of device drivers */
+ Device_drivers, /* pointer to driver address table */
+ NULL, /* pointer to initial extensions */
+#ifdef CONFIGURE_MP_APPLICATION
+ &Multiprocessing_configuration
+#else
+ NULL /* ptr to MP config table */
+#endif
+};
diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h
new file mode 100644
index 0000000000..cb7af0dc8c
--- /dev/null
+++ b/cpukit/sapi/include/rtems/config.h
@@ -0,0 +1,186 @@
+/**
+ * @file rtems/config.h
+ */
+
+/*
+ * This include file contains the table of user defined configuration
+ * parameters.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_CONFIG_H
+#define _RTEMS_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Unlimited object support. Changes the configuration table entry for POSIX
+ * or RTEMS APIs to bounded only by the memory of the work-space.
+ *
+ * Use the macro to define the resource unlimited before placing in
+ * the configuration table.
+ */
+
+#include <rtems/score/object.h>
+#define RTEMS_UNLIMITED_OBJECTS OBJECTS_UNLIMITED_OBJECTS
+
+#define rtems_resource_unlimited(resource) \
+ ( resource | RTEMS_UNLIMITED_OBJECTS )
+
+/*
+ * This is kind of kludgy but it allows targets to totally ignore the
+ * optional APIs like POSIX and ITRON safely.
+ */
+
+#ifdef RTEMS_POSIX_API
+#include <rtems/posix/config.h>
+#else
+typedef void *posix_api_configuration_table;
+#endif
+
+#ifdef RTEMS_ITRON_API
+#include <rtems/itron.h>
+#include <rtems/itron/config.h>
+#else
+typedef void *itron_api_configuration_table;
+#endif
+
+#include <rtems/rtems/config.h>
+
+/* XXX <rtems/rtems/config.h> should cover these
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/tasks.h>
+*/
+
+#include <rtems/extension.h>
+#include <rtems/io.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*
+ * The following records define the Multiprocessor Configuration
+ * Table. This table defines the multiprocessor system
+ * characteristics which must be known by RTEMS in a multiprocessor
+ * system.
+ */
+
+typedef struct {
+ uint32_t node; /* local node number */
+ uint32_t maximum_nodes; /* maximum # nodes in system */
+ uint32_t maximum_global_objects; /* maximum # global objects */
+ uint32_t maximum_proxies; /* maximum # proxies */
+#if defined(RTEMS_MULTIPROCESSING)
+ rtems_mpci_table *User_mpci_table; /* pointer to MPCI table */
+#else
+ void *User_mpci_table; /* pointer to MPCI table */
+#endif
+} rtems_multiprocessing_table;
+
+/*
+ * The following records define the Configuration Table. The
+ * information contained in this table is required in all
+ * RTEMS systems, whether single or multiprocessor. This
+ * table primarily defines the following:
+ *
+ * + location and size of the RTEMS Workspace
+ * + microseconds per clock tick
+ * + clock ticks per task timeslice
+ * + required number of each object type for each API configured
+ */
+
+typedef struct {
+ void *work_space_start;
+ uint32_t work_space_size;
+ uint32_t maximum_extensions;
+ uint32_t microseconds_per_tick;
+ uint32_t ticks_per_timeslice;
+ uint32_t maximum_devices;
+ uint32_t maximum_drivers;
+ uint32_t number_of_device_drivers;
+ rtems_driver_address_table *Device_driver_table;
+ uint32_t number_of_initial_extensions;
+ rtems_extensions_table *User_extension_table;
+ rtems_multiprocessing_table *User_multiprocessing_table;
+ rtems_api_configuration_table *RTEMS_api_configuration;
+ posix_api_configuration_table *POSIX_api_configuration;
+ itron_api_configuration_table *ITRON_api_configuration;
+} rtems_configuration_table;
+
+/*
+ * The following are provided strictly for the convenience of
+ * the user. They are not used in RTEMS itself.
+ */
+
+SAPI_EXTERN rtems_configuration_table *_Configuration_Table;
+SAPI_EXTERN rtems_multiprocessing_table *_Configuration_MP_table;
+
+/*
+ * Some handy macros to avoid dependencies on either the BSP
+ * or the exact format of the configuration table.
+ */
+
+#define rtems_configuration_get_table() \
+ (&_Configuration_Table)
+
+#define rtems_configuration_get_work_space_start() \
+ (_Configuration_Table->work_space_start)
+
+#define rtems_configuration_get_work_space_size() \
+ (_Configuration_Table->work_space_size)
+
+#define rtems_configuration_get_maximum_extensions() \
+ (_Configuration_Table->maximum_extensions)
+
+#define rtems_configuration_get_microseconds_per_tick() \
+ (_Configuration_Table->microseconds_per_tick)
+#define rtems_configuration_get_milliseconds_per_tick() \
+ (_Configuration_Table->microseconds_per_tick / 1000)
+
+#define rtems_configuration_get_ticks_per_timeslice() \
+ (_Configuration_Table->ticks_per_timeslice)
+
+#define rtems_configuration_get_maximum_devices() \
+ (_Configuration_Table->maximum_devices)
+
+#define rtems_configuration_get_number_of_device_drivers() \
+ (_Configuration_Table->number_of_device_drivers)
+
+#define rtems_configuration_get_device_driver_table() \
+ (_Configuration_Table->device_driver_table)
+
+#define rtems_configuration_get_number_of_initial_extensions() \
+ (_Configuration_Table->number_of_initial_extensions)
+
+#define rtems_configuration_get_user_extension_table() \
+ (_Configuration_Table->user_extension_table)
+
+#define rtems_configuration_get_user_multiprocessing_table() \
+ (_Configuration_Table->User_multiprocessing_table)
+
+#define rtems_configuration_get_rtems_api_configuration() \
+ (_Configuration_Table->RTEMS_api_configuration)
+
+#define rtems_configuration_get_posix_api_configuration() \
+ (_Configuration_Table->POSIX_api_configuration)
+
+#define rtems_configuration_get_itron_api_configuration() \
+ (_Configuration_Table->ITRON_api_configuration)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/sapi/include/rtems/extension.h b/cpukit/sapi/include/rtems/extension.h
new file mode 100644
index 0000000000..65ac6ce280
--- /dev/null
+++ b/cpukit/sapi/include/rtems/extension.h
@@ -0,0 +1,140 @@
+/**
+ * @file rtems/extension.h
+ */
+
+/*
+ * This include file contains all the constants, structures, and
+ * prototypes associated with the User Extension Manager. This manager
+ * provides a mechanism for manipulating sets of user-defined extensions.
+ *
+ * Directives provided are:
+ *
+ * + create user extension set
+ * + get ID of user extension set
+ * + delete user extension set
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_EXTENSION_H
+#define _RTEMS_EXTENSION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+#include <rtems/score/userext.h>
+#include <rtems/rtems/status.h> /* XXX */
+#include <rtems/rtems/types.h> /* XXX */
+
+/*
+ * Extension related types
+ */
+
+typedef User_extensions_routine rtems_extension;
+typedef User_extensions_thread_create_extension rtems_task_create_extension;
+typedef User_extensions_thread_delete_extension rtems_task_delete_extension;
+typedef User_extensions_thread_start_extension rtems_task_start_extension;
+typedef User_extensions_thread_restart_extension rtems_task_restart_extension;
+typedef User_extensions_thread_switch_extension rtems_task_switch_extension;
+typedef User_extensions_thread_post_switch_extension
+ rtems_task_post_switch_extension;
+typedef User_extensions_thread_begin_extension rtems_task_begin_extension;
+typedef User_extensions_thread_exitted_extension rtems_task_exitted_extension;
+typedef User_extensions_fatal_extension rtems_fatal_extension;
+
+typedef User_extensions_Table rtems_extensions_table;
+
+/*
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+
+SAPI_EXTERN Objects_Information _Extension_Information;
+
+/*
+ * The following records define the control block used to manage
+ * each extension.
+ */
+
+typedef struct {
+ Objects_Control Object;
+ User_extensions_Control Extension;
+} Extension_Control;
+
+/*
+ * _Extension_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _Extension_Manager_initialization(
+ uint32_t maximum_extensions
+);
+
+/*
+ * rtems_extension_create
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_extension_create directive. The
+ * extension will have the name name. The entry points of the
+ * routines which constitute this extension set are in EXTENSION_TABLE.
+ * It returns the id of the created extension in ID.
+ */
+
+rtems_status_code rtems_extension_create(
+ rtems_name name,
+ rtems_extensions_table *extension_table,
+ Objects_Id *id
+);
+
+/*
+ * rtems_extension_ident
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_extension_ident directive.
+ * This directive returns the extension ID associated with name.
+ * If more than one extension is named name, then the extension
+ * to which the ID belongs is arbitrary.
+ */
+
+rtems_status_code rtems_extension_ident(
+ rtems_name name,
+ Objects_Id *id
+);
+
+/*
+ * rtems_extension_delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_extension_delete directive. The
+ * extension indicated by ID is deleted.
+ */
+
+rtems_status_code rtems_extension_delete(
+ Objects_Id id
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/extension.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/sapi/include/rtems/fatal.h b/cpukit/sapi/include/rtems/fatal.h
new file mode 100644
index 0000000000..9d870776c4
--- /dev/null
+++ b/cpukit/sapi/include/rtems/fatal.h
@@ -0,0 +1,51 @@
+/**
+ * @file rtems/fatal.h
+ */
+
+/*
+ * This include file contains constants and prototypes related
+ * to the Fatal Error Manager. This manager processes all fatal or
+ * irrecoverable errors.
+ *
+ * This manager provides directives to:
+ *
+ * + announce a fatal error has occurred
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_FATAL_H
+#define _RTEMS_FATAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * rtems_fatal_error_occurred
+ *
+ * DESCRIPTION:
+ *
+ * This is the routine which implements the rtems_fatal_error_occurred
+ * directive. It is invoked when the application or RTEMS
+ * determines that a fatal error has occurred.
+ */
+
+void rtems_fatal_error_occurred(
+ uint32_t the_error
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/sapi/include/rtems/init.h b/cpukit/sapi/include/rtems/init.h
new file mode 100644
index 0000000000..6de3a22a6d
--- /dev/null
+++ b/cpukit/sapi/include/rtems/init.h
@@ -0,0 +1,97 @@
+/**
+ * @file rtems/init.h
+ *
+ *
+ * This include file contains all the constants and structures associated
+ * with the Initialization Manager. This manager is responsible for
+ * initializing RTEMS, creating and starting all configured initialization
+ * tasks, invoking the initialization routine for each user-supplied device
+ * driver, and initializing the optional multiprocessor layer.
+ *
+ * This manager provides directives to:
+ *
+ * + initialize the RTEMS executive
+ * + shutdown the RTEMS executive
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_INIT_H
+#define _RTEMS_INIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/types.h>
+#include <rtems/config.h>
+#include <rtems/rtems/intr.h>
+
+/*
+ * The following defines the default Multiprocessing Configuration
+ * Table. This table is used in a single processor system.
+ */
+
+extern const rtems_multiprocessing_table
+ _Initialization_Default_multiprocessing_table;
+
+/*
+ * rtems_initialize_executive_early
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the early portion of rtems_initialize_executive
+ * directive up to the pretasking hook. This directive is invoked at system
+ * startup to initialize the RTEMS multitasking environment.
+ */
+
+rtems_interrupt_level rtems_initialize_executive_early(
+ rtems_configuration_table *configuration_table,
+ rtems_cpu_table *cpu_table
+);
+
+/*
+ * rtems_initialize_executive_late
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the early portion of rtems_initialize_executive
+ * directive up to the pretasking hook. This directive is invoked at system
+ * startup to initialize the RTEMS multitasking environment.
+ */
+
+void rtems_initialize_executive_late(
+ rtems_interrupt_level bsp_level
+);
+
+/*
+ * rtems_shutdown_executive
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_shutdown_executive directive. The
+ * invocation of this directive results in the RTEMS environment being
+ * shutdown and multitasking halted. From the application's perspective,
+ * invocation of this directive results in the rtems_initialize_executive
+ * directive exitting to the startup code which invoked it.
+ */
+
+void rtems_shutdown_executive(
+ uint32_t result
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/sapi/include/rtems/io.h b/cpukit/sapi/include/rtems/io.h
new file mode 100644
index 0000000000..66d6360dd0
--- /dev/null
+++ b/cpukit/sapi/include/rtems/io.h
@@ -0,0 +1,275 @@
+/**
+ * @file rtems/io.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Input/Output Manager. This manager provides a well defined
+ * mechanism for accessing device drivers and a structured methodology for
+ * organizing device drivers.
+ *
+ * Directives provided are:
+ *
+ * + initialize a device driver
+ * + open a device driver
+ * + close a device driver
+ * + read from a device driver
+ * + write to a device driver
+ * + special device services
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_IO_H
+#define _RTEMS_IO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/status.h>
+
+/*
+ *
+ * The following defines the types for:
+ *
+ * + major and minor numbers
+ * + the return type of a device driver entry
+ * + a pointer to a device driver entry
+ * + an entry in the the Device Driver Address Table. Each entry in this
+ * table corresponds to an application provided device driver and
+ * defines the entry points for that device driver.
+ */
+
+typedef uint32_t rtems_device_major_number;
+typedef uint32_t rtems_device_minor_number;
+
+typedef rtems_status_code rtems_device_driver;
+
+typedef rtems_device_driver ( *rtems_device_driver_entry )(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+ );
+
+typedef struct {
+ rtems_device_driver_entry initialization_entry; /* initialization procedure */
+ rtems_device_driver_entry open_entry; /* open request procedure */
+ rtems_device_driver_entry close_entry; /* close request procedure */
+ rtems_device_driver_entry read_entry; /* read request procedure */
+ rtems_device_driver_entry write_entry; /* write request procedure */
+ rtems_device_driver_entry control_entry; /* special functions procedure */
+} rtems_driver_address_table;
+
+/*
+ * Table for the io device names
+ */
+
+typedef struct {
+ char *device_name;
+ size_t device_name_length;
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+} rtems_driver_name_t;
+
+/*
+ * This is the table of device names.
+ */
+
+/*
+ * The following declare the data required to manage the Driver
+ * Address Table and Device Name Table.
+ */
+
+SAPI_EXTERN uint32_t _IO_Number_of_drivers;
+SAPI_EXTERN rtems_driver_address_table *_IO_Driver_address_table;
+SAPI_EXTERN uint32_t _IO_Number_of_devices;
+SAPI_EXTERN rtems_driver_name_t *_IO_Driver_name_table;
+
+/*
+ * _IO_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _IO_Manager_initialization(
+ rtems_driver_address_table *driver_table,
+ uint32_t drivers_in_table,
+ uint32_t number_of_drivers,
+ uint32_t number_of_devices
+);
+
+/*
+ * rtems_io_register_driver
+ *
+ * DESCRIPTION:
+ *
+ * Register a driver into the device driver table.
+ *
+ */
+
+rtems_status_code rtems_io_register_driver(
+ rtems_device_major_number major,
+ rtems_driver_address_table *driver_table,
+ rtems_device_major_number *registered_major
+);
+
+/*
+ * rtems_io_unregister_driver
+ *
+ * DESCRIPTION:
+ *
+ * Unregister a driver from the device driver table.
+ *
+ */
+
+rtems_status_code rtems_io_unregister_driver(
+ rtems_device_major_number major
+);
+
+/*
+ * rtems_io_register_name
+ *
+ * DESCRIPTION:
+ *
+ * Associate a name with a driver.
+ *
+ */
+
+rtems_status_code rtems_io_register_name(
+ const char *device_name,
+ rtems_device_major_number major,
+ rtems_device_minor_number minor
+);
+
+
+/*
+ * rtems_io_lookup_name
+ *
+ * DESCRIPTION:
+ *
+ * Find what driver "owns" this name
+ */
+
+rtems_status_code rtems_io_lookup_name(
+ const char *name,
+ rtems_driver_name_t *device_info
+);
+
+
+/*
+ * rtems_io_initialize
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_io_initialize directive. It is invoked
+ * to initialize a device driver or an individual device.
+ */
+
+rtems_status_code rtems_io_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/*
+ * rtems_io_open
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_io_open directive. It is invoked
+ * to open a device.
+ */
+
+rtems_status_code rtems_io_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/*
+ * rtems_io_close
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_io_close directive. It is invoked
+ * to close a device.
+ */
+
+rtems_status_code rtems_io_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/*
+ * rtems_io_read
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_io_read directive. It is invoked
+ * to read from a device.
+ */
+
+rtems_status_code rtems_io_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/*
+ * rtems_io_write
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_io_write directive. It is invoked
+ * to write to a device.
+ */
+
+rtems_status_code rtems_io_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/*
+ * rtems_io_control
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the rtems_io_control directive. It is invoked
+ * to perform a device specific operation on a device.
+ */
+
+rtems_status_code rtems_io_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/*
+ * _IO_Initialize_all_drivers
+ *
+ * DESCRIPTION:
+ *
+ * This routine initializes all of the device drivers configured
+ * in the Device Driver Address Table.
+ */
+
+void _IO_Initialize_all_drivers( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/sapi/include/rtems/mptables.h b/cpukit/sapi/include/rtems/mptables.h
new file mode 100644
index 0000000000..bcb51c5e96
--- /dev/null
+++ b/cpukit/sapi/include/rtems/mptables.h
@@ -0,0 +1,28 @@
+/* mptables.h
+ *
+ * This include file contains the executive's pre-initialized tables
+ * used in a multiprocessor configuration.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_MPTABLES_H
+#define _RTEMS_MPTABLES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/sapi/include/rtems/sptables.h b/cpukit/sapi/include/rtems/sptables.h
new file mode 100644
index 0000000000..a5af70b171
--- /dev/null
+++ b/cpukit/sapi/include/rtems/sptables.h
@@ -0,0 +1,73 @@
+/**
+ * @file rtems/sptables.h
+ *
+ * This include file contains the executive's pre-initialized tables
+ * used when in a single processor configuration.
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SPTABLES_H
+#define _RTEMS_SPTABLES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/config.h>
+
+#include <rtems/debug.h>
+#include <rtems/fatal.h>
+#include <rtems/init.h>
+#include <rtems/io.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/rtems/intr.h>
+#include <rtems/rtems/clock.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/rtems/dpmem.h>
+#include <rtems/rtems/event.h>
+#include <rtems/rtems/message.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/mp.h>
+#endif
+#include <rtems/rtems/part.h>
+#include <rtems/rtems/ratemon.h>
+#include <rtems/rtems/region.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/rtems/signal.h>
+#include <rtems/rtems/timer.h>
+
+/*
+ * This is the default Multiprocessing Configuration Table.
+ * It is used in single processor configurations.
+ */
+
+#if defined(SAPI_INIT)
+const rtems_multiprocessing_table
+ _Initialization_Default_multiprocessing_table = {
+ 1, /* local node number */
+ 1, /* maximum number nodes in system */
+ 0, /* maximum number global objects */
+ 0, /* maximum number proxies */
+ NULL, /* pointer to MPCI address table */
+};
+#else
+extern const rtems_multiprocessing_table
+ _Initialization_Default_multiprocessing_table;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/sapi/inline/rtems/extension.inl b/cpukit/sapi/inline/rtems/extension.inl
new file mode 100644
index 0000000000..c989acea48
--- /dev/null
+++ b/cpukit/sapi/inline/rtems/extension.inl
@@ -0,0 +1,93 @@
+/**
+ * @file rtems/extension.inl
+ *
+ * This file contains the static inline implementation of the inlined routines
+ * from the Extension Manager.
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef __EXTENSION_MANAGER_inl
+#define __EXTENSION_MANAGER_inl
+
+/*PAGE
+ *
+ * _Extension_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a extension control block from
+ * the inactive chain of free extension control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE Extension_Control *_Extension_Allocate( void )
+{
+ return (Extension_Control *) _Objects_Allocate( &_Extension_Information );
+}
+
+/*PAGE
+ *
+ * _Extension_Free
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a extension control block to the
+ * inactive chain of free extension control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Extension_Free (
+ Extension_Control *the_extension
+)
+{
+ _Objects_Free( &_Extension_Information, &the_extension->Object );
+}
+
+/*PAGE
+ *
+ * _Extension_Get
+ *
+ * DESCRIPTION:
+ *
+ * This function maps extension IDs to extension control blocks.
+ * If ID corresponds to a local extension, then it returns
+ * the extension control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. Otherwise, location is set
+ * to OBJECTS_ERROR and the returned value is undefined.
+ */
+
+RTEMS_INLINE_ROUTINE Extension_Control *_Extension_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ return (Extension_Control *)
+ _Objects_Get( &_Extension_Information, id, location );
+}
+
+/*PAGE
+ *
+ * _Extension_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the_extension is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Extension_Is_null (
+ Extension_Control *the_extension
+)
+{
+ return ( the_extension == NULL );
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/sapi/macros/rtems/extension.inl b/cpukit/sapi/macros/rtems/extension.inl
new file mode 100644
index 0000000000..fea7635119
--- /dev/null
+++ b/cpukit/sapi/macros/rtems/extension.inl
@@ -0,0 +1,60 @@
+/**
+ * @file rtems/extension.inl
+ *
+ * This file contains the macro implementation of the inlined routines
+ * from the Extension Manager.
+ */
+
+/*
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef __EXTENSION_inl
+#define __EXTENSION_inl
+
+/*PAGE
+ *
+ * _Extension_Allocate
+ *
+ */
+
+#define _Extension_Allocate() \
+ (Extension_Control *) _Objects_Allocate( &_Extension_Information )
+
+/*PAGE
+ *
+ * _Extension_Free
+ *
+ */
+
+#define _Extension_Free( _the_extension ) \
+ _Objects_Free( &_Extension_Information, &(_the_extension)->Object )
+
+/*PAGE
+ *
+ * _Extension_Get
+ *
+ */
+
+#define _Extension_Get( _id, _location ) \
+ (Extension_Control *) \
+ _Objects_Get( &_Extension_Information, (_id), (_location) )
+
+/*PAGE
+ *
+ * _Extension_Is_null
+ *
+ */
+
+#define _Extension_Is_null( _the_extension ) \
+ ( (_the_extension) == NULL )
+
+#endif
+/* end of include file */
diff --git a/cpukit/sapi/preinstall.am b/cpukit/sapi/preinstall.am
new file mode 100644
index 0000000000..31089a20d9
--- /dev/null
+++ b/cpukit/sapi/preinstall.am
@@ -0,0 +1,62 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/confdefs.h: include/confdefs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/confdefs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/confdefs.h
+
+$(PROJECT_INCLUDE)/rtems/config.h: include/rtems/config.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/config.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/config.h
+
+$(PROJECT_INCLUDE)/rtems/extension.h: include/rtems/extension.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/extension.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/extension.h
+
+$(PROJECT_INCLUDE)/rtems/fatal.h: include/rtems/fatal.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/fatal.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/fatal.h
+
+$(PROJECT_INCLUDE)/rtems/init.h: include/rtems/init.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/init.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/init.h
+
+$(PROJECT_INCLUDE)/rtems/io.h: include/rtems/io.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/io.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/io.h
+
+$(PROJECT_INCLUDE)/rtems/mptables.h: include/rtems/mptables.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/mptables.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/mptables.h
+
+$(PROJECT_INCLUDE)/rtems/sptables.h: include/rtems/sptables.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/sptables.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/sptables.h
+
+if INLINE
+$(PROJECT_INCLUDE)/rtems/extension.inl: inline/rtems/extension.inl $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/extension.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/extension.inl
+
+else
+$(PROJECT_INCLUDE)/rtems/extension.inl: macros/rtems/extension.inl $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/extension.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/extension.inl
+endif
diff --git a/cpukit/sapi/src/debug.c b/cpukit/sapi/src/debug.c
new file mode 100644
index 0000000000..905280ef2c
--- /dev/null
+++ b/cpukit/sapi/src/debug.c
@@ -0,0 +1,65 @@
+/*
+ * Debug Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/debug.h>
+
+/*PAGE
+ *
+ * _Debug_Manager_initialization
+ */
+
+void _Debug_Manager_initialization( void )
+{
+ rtems_debug_disable( RTEMS_DEBUG_ALL_MASK );
+}
+
+/*PAGE
+ *
+ * rtems_debug_enable
+ */
+
+void rtems_debug_enable (
+ rtems_debug_control to_be_enabled
+)
+{
+ _Debug_Level |= to_be_enabled;
+}
+
+/*PAGE
+ *
+ * rtems_debug_disable
+ */
+
+void rtems_debug_disable (
+ rtems_debug_control to_be_disabled
+)
+{
+ _Debug_Level &= ~to_be_disabled;
+}
+
+/*PAGE
+ *
+ * _Debug_Is_enabled
+ */
+
+boolean _Debug_Is_enabled(
+ rtems_debug_control level
+)
+{
+ return (_Debug_Level & level);
+}
diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c
new file mode 100644
index 0000000000..1b8a4c52ae
--- /dev/null
+++ b/cpukit/sapi/src/exinit.c
@@ -0,0 +1,303 @@
+/*
+ * Initialization Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * SCORE_INIT and SAPI_INIT are defined so all of the super core and
+ * super API data will be included in this object file.
+ */
+
+#define SAPI_INIT
+#define SCORE_INIT
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/debug.h>
+#include <rtems/extension.h>
+#include <rtems/fatal.h>
+#include <rtems/init.h>
+#include <rtems/io.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/score/apiext.h>
+#include <rtems/score/apimutex.h>
+#include <rtems/score/copyrt.h>
+#include <rtems/score/heap.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+#include <rtems/score/priority.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/score/wkspace.h>
+
+#include <rtems/sptables.h>
+
+
+#include <rtems/rtems/rtemsapi.h>
+#ifdef RTEMS_POSIX_API
+#include <rtems/posix/posixapi.h>
+#endif
+#ifdef RTEMS_ITRON_API
+#include <rtems/itron/itronapi.h>
+#endif
+
+Objects_Information *_Internal_Objects[ OBJECTS_INTERNAL_CLASSES_LAST + 1 ];
+
+rtems_interrupt_level rtems_initialize_executive_early(
+ rtems_configuration_table *configuration_table,
+ rtems_cpu_table *cpu_table
+)
+{
+ rtems_interrupt_level bsp_level;
+ rtems_multiprocessing_table *multiprocessing_table;
+
+ /*
+ * Dispatching and interrupts are disabled until the end of the
+ * initialization sequence. This prevents an inadvertent context
+ * switch before the executive is initialized.
+ */
+
+ _ISR_Disable( bsp_level );
+
+ if ( configuration_table == NULL )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_NO_CONFIGURATION_TABLE
+ );
+
+ /*
+ * Initialize the system state based on whether this is an MP system.
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ multiprocessing_table = configuration_table->User_multiprocessing_table;
+
+ _System_state_Handler_initialization(
+ (multiprocessing_table) ? TRUE : FALSE
+ );
+#else
+ multiprocessing_table = NULL;
+
+ _System_state_Handler_initialization( FALSE );
+#endif
+
+ /*
+ * Provided just for user convenience.
+ */
+
+ _Configuration_Table = configuration_table;
+ _Configuration_MP_table = multiprocessing_table;
+
+ /*
+ * Internally we view single processor systems as a very restricted
+ * multiprocessor system.
+ */
+
+ if ( multiprocessing_table == NULL )
+ multiprocessing_table =
+ (void *)&_Initialization_Default_multiprocessing_table;
+
+ if ( cpu_table == NULL )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_NO_CPU_TABLE
+ );
+
+ _CPU_Initialize( cpu_table, _Thread_Dispatch );
+
+ /*
+ * Do this as early as possible to insure no debugging output
+ * is even attempted to be printed.
+ */
+
+ _Debug_Manager_initialization();
+
+ _API_extensions_Initialization();
+
+ _Thread_Dispatch_initialization();
+
+ _Workspace_Handler_initialization(
+ (void *)configuration_table->work_space_start,
+ configuration_table->work_space_size
+ );
+
+ _User_extensions_Handler_initialization(
+ configuration_table->number_of_initial_extensions,
+ configuration_table->User_extension_table
+ );
+
+ _ISR_Handler_initialization();
+
+ _Objects_Handler_initialization(
+ multiprocessing_table->node,
+ multiprocessing_table->maximum_nodes,
+ multiprocessing_table->maximum_global_objects
+ );
+
+ _Objects_Information_table[OBJECTS_INTERNAL_API] = _Internal_Objects;
+
+ _Priority_Handler_initialization();
+
+ _Watchdog_Handler_initialization();
+
+ _TOD_Handler_initialization( configuration_table->microseconds_per_tick );
+
+ _Thread_Handler_initialization(
+ configuration_table->ticks_per_timeslice,
+ configuration_table->maximum_extensions,
+ multiprocessing_table->maximum_proxies
+ );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _MPCI_Handler_initialization(
+ multiprocessing_table->User_mpci_table,
+ RTEMS_TIMEOUT
+ );
+#endif
+
+/* MANAGERS */
+
+ _RTEMS_API_Initialize( configuration_table );
+
+ _Extension_Manager_initialization( configuration_table->maximum_extensions );
+
+ _IO_Manager_initialization(
+ configuration_table->Device_driver_table,
+ configuration_table->number_of_device_drivers,
+ configuration_table->maximum_drivers,
+ configuration_table->maximum_devices
+ );
+
+#ifdef RTEMS_POSIX_API
+ _POSIX_API_Initialize( configuration_table );
+#endif
+
+#ifdef RTEMS_ITRON_API
+ _ITRON_API_Initialize( configuration_table );
+#endif
+
+ _System_state_Set( SYSTEM_STATE_BEFORE_MULTITASKING );
+
+ /*
+ * No threads should be created before this point!!!
+ * _Thread_Executing and _Thread_Heir are not set.
+ *
+ * At this point all API extensions are in place. After the call to
+ * _Thread_Create_idle() _Thread_Executing and _Thread_Heir will be set.
+ */
+
+ _Thread_Create_idle();
+
+
+ /*
+ * Scheduling can properly occur now as long as we avoid dispatching.
+ */
+
+ if ( cpu_table->pretasking_hook )
+ (*cpu_table->pretasking_hook)();
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _MPCI_Create_server();
+#endif
+
+ /*
+ * Run the API and BSPs predriver hook.
+ */
+
+ _API_extensions_Run_predriver();
+
+ if ( _CPU_Table.predriver_hook )
+ (*_CPU_Table.predriver_hook)();
+
+ /*
+ * Initialize all the device drivers and initialize the MPCI layer.
+ *
+ * NOTE: The MPCI may be build upon a device driver.
+ */
+
+ _IO_Initialize_all_drivers();
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _System_state_Is_multiprocessing ) {
+ _MPCI_Initialization();
+ _MPCI_Internal_packets_Send_process_packet(
+ MPCI_PACKETS_SYSTEM_VERIFY
+ );
+ }
+#endif
+
+ /*
+ * Run the APIs and BSPs postdriver hooks.
+ *
+ * The API extensions are supposed to create user initialization tasks.
+ */
+
+ _API_extensions_Run_postdriver();
+
+ if ( _CPU_Table.postdriver_hook )
+ (*_CPU_Table.postdriver_hook)();
+
+ return bsp_level;
+}
+
+void rtems_initialize_executive_late(
+ rtems_interrupt_level bsp_level
+)
+{
+
+ _System_state_Set( SYSTEM_STATE_BEGIN_MULTITASKING );
+
+ _Thread_Start_multitasking();
+
+ /*
+ * Restore the interrupt level to what the BSP had. Technically,
+ * this is unnecessary since the BSP should have all interrupts
+ * disabled when rtems_initialize_executive is invoked. But this keeps
+ * the ISR Disable/Enable calls paired.
+ */
+
+ _ISR_Enable( bsp_level );
+}
+
+/*PAGE
+ *
+ * rtems_shutdown_executive
+ *
+ * This kernel routine shutdowns the executive. It halts multitasking
+ * and returns control to the application execution "thread" which
+ * initialially invoked the rtems_initialize_executive directive.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void rtems_shutdown_executive(
+ uint32_t result
+)
+{
+ if ( _System_state_Current != SYSTEM_STATE_SHUTDOWN ) {
+ _System_state_Set( SYSTEM_STATE_SHUTDOWN );
+ _Thread_Stop_multitasking();
+ }
+}
diff --git a/cpukit/sapi/src/extension.c b/cpukit/sapi/src/extension.c
new file mode 100644
index 0000000000..26fe365a03
--- /dev/null
+++ b/cpukit/sapi/src/extension.c
@@ -0,0 +1,55 @@
+/*
+ * Extension Manager
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/extension.h>
+
+/*PAGE
+ *
+ * _Extension_Manager_initialization
+ *
+ * This routine initializes all extension manager related data structures.
+ *
+ * Input parameters:
+ * maximum_extensions - number of extensions to initialize
+ *
+ * Output parameters: NONE
+ */
+
+void _Extension_Manager_initialization(
+ uint32_t maximum_extensions
+)
+{
+ _Objects_Initialize_information(
+ &_Extension_Information,
+ OBJECTS_CLASSIC_API, /* object API */
+ OBJECTS_RTEMS_EXTENSIONS,
+ maximum_extensions,
+ sizeof( Extension_Control ),
+ FALSE, /* TRUE if the name is a string */
+ RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+}
diff --git a/cpukit/sapi/src/extensioncreate.c b/cpukit/sapi/src/extensioncreate.c
new file mode 100644
index 0000000000..20ad321098
--- /dev/null
+++ b/cpukit/sapi/src/extensioncreate.c
@@ -0,0 +1,73 @@
+/*
+ * Extension Manager -- rtems_extension_create
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/extension.h>
+
+/*PAGE
+ *
+ * rtems_extension_create
+ *
+ * This directive creates a extension and performs some initialization.
+ *
+ * Input parameters:
+ * name - extension name
+ * extension_table - pointer to extension set information
+ * id - pointer to extension id
+ *
+ * Output parameters:
+ * id - extension id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_extension_create(
+ rtems_name name,
+ rtems_extensions_table *extension_table,
+ Objects_Id *id
+)
+{
+ Extension_Control *the_extension;
+
+ if ( !rtems_is_name_valid( name ) )
+ return RTEMS_INVALID_NAME;
+
+ _Thread_Disable_dispatch(); /* to prevent deletion */
+
+ the_extension = _Extension_Allocate();
+
+ if ( !the_extension ) {
+ _Thread_Enable_dispatch();
+ return RTEMS_TOO_MANY;
+ }
+
+ _User_extensions_Add_set( &the_extension->Extension, extension_table );
+
+ _Objects_Open(
+ &_Extension_Information,
+ &the_extension->Object,
+ (Objects_Name) name
+ );
+
+ *id = the_extension->Object.id;
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/sapi/src/extensiondelete.c b/cpukit/sapi/src/extensiondelete.c
new file mode 100644
index 0000000000..4e3d937ecf
--- /dev/null
+++ b/cpukit/sapi/src/extensiondelete.c
@@ -0,0 +1,60 @@
+/*
+ * Extension Manager -- rtems_extension_delete
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/extension.h>
+
+/*PAGE
+ *
+ * rtems_extension_delete
+ *
+ * This directive allows a thread to delete a extension.
+ *
+ * Input parameters:
+ * id - extension id
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_extension_delete(
+ Objects_Id id
+)
+{
+ Extension_Control *the_extension;
+ Objects_Locations location;
+
+ the_extension = _Extension_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE: /* should never return this */
+ return RTEMS_INVALID_ID;
+ case OBJECTS_LOCAL:
+ _User_extensions_Remove_set( &the_extension->Extension );
+ _Objects_Close( &_Extension_Information, &the_extension->Object );
+ _Extension_Free( the_extension );
+ _Thread_Enable_dispatch();
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
+}
diff --git a/cpukit/sapi/src/extensionident.c b/cpukit/sapi/src/extensionident.c
new file mode 100644
index 0000000000..d23a614f5b
--- /dev/null
+++ b/cpukit/sapi/src/extensionident.c
@@ -0,0 +1,57 @@
+/*
+ * Extension Manager -- rtems_extension_ident
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/rtems/support.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/extension.h>
+
+/*PAGE
+ *
+ * rtems_extension_ident
+ *
+ * This directive returns the system ID associated with
+ * the extension name.
+ *
+ * Input parameters:
+ * name - user defined message queue name
+ * id - pointer to extension id
+ *
+ * Output parameters:
+ * *id - message queue id
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_extension_ident(
+ rtems_name name,
+ Objects_Id *id
+)
+{
+ Objects_Name_or_id_lookup_errors status;
+
+ status = _Objects_Name_to_id(
+ &_Extension_Information,
+ (Objects_Name) name,
+ OBJECTS_SEARCH_LOCAL_NODE,
+ id
+ );
+
+ return _Status_Object_name_errors_to_status[ status ];
+}
diff --git a/cpukit/sapi/src/fatal.c b/cpukit/sapi/src/fatal.c
new file mode 100644
index 0000000000..cecc7d4bb7
--- /dev/null
+++ b/cpukit/sapi/src/fatal.c
@@ -0,0 +1,41 @@
+/*
+ * Fatal Error Manager
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/fatal.h>
+#include <rtems/score/interr.h>
+
+/*PAGE
+ *
+ * rtems_fatal_error_occurred
+ *
+ * This directive will invoke the internal fatal error handler.
+ *
+ * Input parameters:
+ * the_error - fatal error status code
+ *
+ * Output parameters: NONE
+ */
+
+void rtems_fatal_error_occurred(
+ uint32_t the_error
+)
+{
+ _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, FALSE, the_error );
+
+/* will not return from this routine */
+}
diff --git a/cpukit/sapi/src/io.c b/cpukit/sapi/src/io.c
new file mode 100644
index 0000000000..823427fd47
--- /dev/null
+++ b/cpukit/sapi/src/io.c
@@ -0,0 +1,423 @@
+/*
+ * Input/Output Manager
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/io.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+
+#include <string.h>
+
+/*PAGE
+ *
+ * _IO_Manager_initialization
+ *
+ * The IO manager has been extended to support runtime driver
+ * registration. The driver table is now allocated in the
+ * workspace.
+ *
+ */
+
+void _IO_Manager_initialization(
+ rtems_driver_address_table *driver_table,
+ uint32_t drivers_in_table,
+ uint32_t number_of_drivers,
+ uint32_t number_of_devices
+)
+{
+ void *tmp;
+ uint32_t index;
+ rtems_driver_name_t *np;
+
+ if ( number_of_drivers < drivers_in_table )
+ number_of_drivers = drivers_in_table;
+
+ tmp = _Workspace_Allocate_or_fatal_error(
+ sizeof( rtems_driver_address_table ) * ( number_of_drivers )
+ );
+
+ _IO_Driver_address_table = (rtems_driver_address_table *) tmp;
+
+ memset(
+ _IO_Driver_address_table, 0,
+ sizeof( rtems_driver_address_table ) * ( number_of_drivers )
+ );
+
+ if ( drivers_in_table )
+ for ( index = 0 ; index < drivers_in_table ; index++ )
+ _IO_Driver_address_table[index] = driver_table[index];
+
+ _IO_Number_of_drivers = number_of_drivers;
+ _IO_Number_of_devices = number_of_devices;
+
+ tmp = _Workspace_Allocate_or_fatal_error(
+ sizeof( rtems_driver_name_t ) * ( number_of_devices + 1 )
+ );
+
+ _IO_Driver_name_table = (rtems_driver_name_t *) tmp;
+
+ for( index=0, np = _IO_Driver_name_table ;
+ index < _IO_Number_of_devices ;
+ index++, np++ ) {
+ np->device_name = 0;
+ np->device_name_length = 0;
+ np->major = 0;
+ np->minor = 0;
+ }
+}
+
+/*PAGE
+ *
+ * _IO_Initialize_all_drivers
+ *
+ * This routine initializes all device drivers
+ *
+ * Input Paramters: NONE
+ *
+ * Output Parameters: NONE
+ */
+
+void _IO_Initialize_all_drivers( void )
+{
+ rtems_device_major_number major;
+
+ for ( major=0 ; major < _IO_Number_of_drivers ; major ++ )
+ (void) rtems_io_initialize( major, 0, NULL);
+}
+
+/*PAGE
+ *
+ * rtems_io_register_driver
+ *
+ * Register a driver into the device driver table.
+ *
+ * Input Paramters:
+ * major - device major number (0 means allocate
+ * a number)
+ * driver_table - driver callout function table
+ * registered_major - the major number which is registered
+ *
+ * Output Parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_io_register_driver(
+ rtems_device_major_number major,
+ rtems_driver_address_table *driver_table,
+ rtems_device_major_number *registered_major
+)
+{
+ *registered_major = 0;
+
+ /*
+ * Test for initialise/open being present to indicate the driver slot is
+ * in use.
+ */
+
+ if ( major >= _IO_Number_of_drivers )
+ return RTEMS_INVALID_NUMBER;
+
+ if ( major == 0 )
+ {
+ for ( major = _IO_Number_of_drivers - 1 ; major ; major-- )
+ if ( _IO_Driver_address_table[major].initialization_entry == 0 &&
+ _IO_Driver_address_table[major].open_entry == 0 )
+ break;
+
+ if (( major == 0 ) &&
+ ( _IO_Driver_address_table[major].initialization_entry == 0 &&
+ _IO_Driver_address_table[major].open_entry == 0 ))
+ return RTEMS_TOO_MANY;
+ }
+
+ if ( _IO_Driver_address_table[major].initialization_entry == 0 &&
+ _IO_Driver_address_table[major].open_entry == 0 )
+ {
+ _IO_Driver_address_table[major] = *driver_table;
+ *registered_major = major;
+
+ rtems_io_initialize( major, 0, NULL );
+
+ return RTEMS_SUCCESSFUL;
+ }
+
+ return RTEMS_RESOURCE_IN_USE;
+}
+
+/*PAGE
+ *
+ * rtems_io_unregister_driver
+ *
+ * Unregister a driver from the device driver table.
+ *
+ * Input Paramters:
+ * major - device major number
+ *
+ * Output Parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+rtems_status_code rtems_io_unregister_driver(
+ rtems_device_major_number major
+)
+{
+ if ( major < _IO_Number_of_drivers )
+ {
+ memset(
+ &_IO_Driver_address_table[major],
+ 0,
+ sizeof( rtems_driver_address_table )
+ );
+ return RTEMS_SUCCESSFUL;
+ }
+ return RTEMS_UNSATISFIED;
+}
+
+/*PAGE
+ *
+ * rtems_io_register_name
+ *
+ * Associate a name with a driver
+ *
+ * Input Paramters:
+ * device_name - pointer to name string to associate with device
+ * major - device major number to receive name
+ * minor - device minor number to receive name
+ *
+ * Output Parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+#if 0
+rtems_status_code rtems_io_register_name(
+ const char *device_name,
+ rtems_device_major_number major,
+ rtems_device_minor_number minor
+ )
+{
+ rtems_driver_name_t *np;
+ uint32_t level;
+ uint32_t index;
+
+ /* find an empty slot */
+ for( index=0, np = _IO_Driver_name_table ;
+ index < _IO_Number_of_devices ;
+ index++, np++ )
+ {
+
+ _ISR_Disable(level);
+ if (np->device_name == 0)
+ {
+ np->device_name = device_name;
+ np->device_name_length = strlen(device_name);
+ np->major = major;
+ np->minor = minor;
+ _ISR_Enable(level);
+
+ return RTEMS_SUCCESSFUL;
+ }
+ _ISR_Enable(level);
+ }
+
+ return RTEMS_TOO_MANY;
+}
+#endif
+
+/*PAGE
+ *
+ * rtems_io_initialize
+ *
+ * This routine is the initialization directive of the IO manager.
+ *
+ * Input Paramters:
+ * major - device driver number
+ * minor - device number
+ * argument - pointer to argument(s)
+ *
+ * Output Parameters:
+ * returns - return code
+ */
+
+rtems_status_code rtems_io_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+)
+{
+ rtems_device_driver_entry callout;
+
+ if ( major >= _IO_Number_of_drivers )
+ return RTEMS_INVALID_NUMBER;
+
+ callout = _IO_Driver_address_table[major].initialization_entry;
+ return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * rtems_io_open
+ *
+ * This routine is the open directive of the IO manager.
+ *
+ * Input Paramters:
+ * major - device driver number
+ * minor - device number
+ * argument - pointer to argument(s)
+ *
+ * Output Parameters:
+ * returns - return code
+ */
+
+rtems_status_code rtems_io_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+)
+{
+ rtems_device_driver_entry callout;
+
+ if ( major >= _IO_Number_of_drivers )
+ return RTEMS_INVALID_NUMBER;
+
+ callout = _IO_Driver_address_table[major].open_entry;
+ return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * rtems_io_close
+ *
+ * This routine is the close directive of the IO manager.
+ *
+ * Input Paramters:
+ * major - device driver number
+ * minor - device number
+ * argument - pointer to argument(s)
+ *
+ * Output Parameters:
+ * returns - return code
+ */
+
+rtems_status_code rtems_io_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+)
+{
+ rtems_device_driver_entry callout;
+
+ if ( major >= _IO_Number_of_drivers )
+ return RTEMS_INVALID_NUMBER;
+
+ callout = _IO_Driver_address_table[major].close_entry;
+ return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * rtems_io_read
+ *
+ * This routine is the read directive of the IO manager.
+ *
+ * Input Paramters:
+ * major - device driver number
+ * minor - device number
+ * argument - pointer to argument(s)
+ *
+ * Output Parameters:
+ * returns - return code
+ */
+
+rtems_status_code rtems_io_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+)
+{
+ rtems_device_driver_entry callout;
+
+ if ( major >= _IO_Number_of_drivers )
+ return RTEMS_INVALID_NUMBER;
+
+ callout = _IO_Driver_address_table[major].read_entry;
+ return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * rtems_io_write
+ *
+ * This routine is the write directive of the IO manager.
+ *
+ * Input Paramters:
+ * major - device driver number
+ * minor - device number
+ * argument - pointer to argument(s)
+ *
+ * Output Parameters:
+ * returns - return code
+ */
+
+rtems_status_code rtems_io_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+)
+{
+ rtems_device_driver_entry callout;
+
+ if ( major >= _IO_Number_of_drivers )
+ return RTEMS_INVALID_NUMBER;
+
+ callout = _IO_Driver_address_table[major].write_entry;
+ return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * rtems_io_control
+ *
+ * This routine is the control directive of the IO manager.
+ *
+ * Input Paramters:
+ * major - device driver number
+ * minor - device number
+ * argument - pointer to argument(s)
+ *
+ * Output Parameters:
+ * returns - return code
+ */
+
+rtems_status_code rtems_io_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+)
+{
+ rtems_device_driver_entry callout;
+
+ if ( major >= _IO_Number_of_drivers )
+ return RTEMS_INVALID_NUMBER;
+
+ callout = _IO_Driver_address_table[major].control_entry;
+ return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/sapi/src/itronapi.c b/cpukit/sapi/src/itronapi.c
new file mode 100644
index 0000000000..e52a64e370
--- /dev/null
+++ b/cpukit/sapi/src/itronapi.c
@@ -0,0 +1,123 @@
+/*
+ * ITRON API Initialization Support
+ *
+ * NOTE:
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+
+/*
+ * ITRON_API_INIT is defined so all of the ITRON API
+ * data will be included in this object file.
+ */
+
+#define ITRON_API_INIT
+
+#include <rtems/system.h> /* include this before checking RTEMS_ITRON_API */
+#ifdef RTEMS_ITRON_API
+
+#include <rtems/itron.h>
+
+#include <sys/types.h>
+#include <rtems/config.h>
+#include <rtems/score/object.h>
+
+#include <rtems/itron/eventflags.h>
+#include <rtems/itron/fmempool.h>
+#include <rtems/itron/mbox.h>
+#include <rtems/itron/msgbuffer.h>
+#include <rtems/itron/port.h>
+#include <rtems/itron/semaphore.h>
+#include <rtems/itron/task.h>
+#include <rtems/itron/vmempool.h>
+
+/*PAGE
+ *
+ * _ITRON_API_Initialize
+ *
+ * XXX
+ */
+
+itron_api_configuration_table _ITRON_Default_configuration = {
+ 0, /* maximum_tasks */
+ 0, /* maximum_semaphores */
+ 0, /* maximum_eventflags */
+ 0, /* maximum_mailboxes */
+ 0, /* maximum_message_buffers */
+ 0, /* maximum_ports */
+ 0, /* maximum_memory_pools */
+ 0, /* maximum_fixed_memory_pools */
+ 0, /* number_of_initialization_tasks */
+ NULL /* User_initialization_tasks_table */
+};
+
+Objects_Information *_ITRON_Objects[ OBJECTS_ITRON_CLASSES_LAST + 1 ];
+
+void _ITRON_API_Initialize(
+ rtems_configuration_table *configuration_table
+)
+{
+ itron_api_configuration_table *api_configuration;
+
+ /* XXX need to assert here based on size assumptions */
+
+ assert( sizeof(ID) == sizeof(Objects_Id) );
+
+ api_configuration = configuration_table->ITRON_api_configuration;
+ if ( !api_configuration )
+ api_configuration = &_ITRON_Default_configuration;
+
+ _Objects_Information_table[OBJECTS_ITRON_API] = _ITRON_Objects;
+
+ _ITRON_Task_Manager_initialization(
+ api_configuration->maximum_tasks,
+ api_configuration->number_of_initialization_tasks,
+ api_configuration->User_initialization_tasks_table
+ );
+
+ _ITRON_Semaphore_Manager_initialization(
+ api_configuration->maximum_semaphores
+ );
+
+ _ITRON_Eventflags_Manager_initialization(
+ api_configuration->maximum_eventflags
+ );
+
+ _ITRON_Fixed_memory_pool_Manager_initialization(
+ api_configuration->maximum_fixed_memory_pools
+ );
+
+ _ITRON_Mailbox_Manager_initialization(
+ api_configuration->maximum_mailboxes
+ );
+
+ _ITRON_Message_buffer_Manager_initialization(
+ api_configuration->maximum_message_buffers
+ );
+
+ _ITRON_Port_Manager_initialization(
+ api_configuration->maximum_ports
+ );
+
+ _ITRON_Variable_memory_pool_Manager_initialization(
+ api_configuration->maximum_memory_pools
+ );
+
+
+}
+
+#endif
+/* end of file */
diff --git a/cpukit/sapi/src/posixapi.c b/cpukit/sapi/src/posixapi.c
new file mode 100644
index 0000000000..a86962c912
--- /dev/null
+++ b/cpukit/sapi/src/posixapi.c
@@ -0,0 +1,119 @@
+/*
+ * RTEMS API Initialization Support
+ *
+ * NOTE:
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+
+/*
+ * POSIX_API_INIT is defined so all of the POSIX API
+ * data will be included in this object file.
+ */
+
+#define POSIX_API_INIT
+
+#include <rtems/system.h> /* include this before checking RTEMS_POSIX_API */
+#ifdef RTEMS_POSIX_API
+
+#include <sys/types.h>
+#include <mqueue.h>
+#include <rtems/config.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/config.h>
+#include <rtems/posix/key.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/mutex.h>
+#include <rtems/posix/priority.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/timer.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_API_Initialize
+ *
+ * XXX
+ */
+
+posix_api_configuration_table _POSIX_Default_configuration = {
+ 0, /* maximum_threads */
+ 0, /* maximum_mutexes */
+ 0, /* maximum_condition_variables */
+ 0, /* maximum_keys */
+ 0, /* maximum_timers */
+ 0, /* maximum_queued_signals */
+ 0, /* number_of_initialization_threads */
+ 0, /* maximum_message_queues */
+ 0, /* maximum_semaphores */
+ NULL /* User_initialization_threads_table */
+};
+
+Objects_Information *_POSIX_Objects[ OBJECTS_POSIX_CLASSES_LAST + 1 ];
+
+
+void _POSIX_API_Initialize(
+ rtems_configuration_table *configuration_table
+)
+{
+ posix_api_configuration_table *api_configuration;
+
+ /* XXX need to assert here based on size assumptions */
+
+ assert( sizeof(pthread_t) == sizeof(Objects_Id) );
+
+ api_configuration = configuration_table->POSIX_api_configuration;
+ if ( !api_configuration )
+ api_configuration = &_POSIX_Default_configuration;
+
+ _Objects_Information_table[OBJECTS_POSIX_API] = _POSIX_Objects;
+
+ _POSIX_signals_Manager_Initialization(
+ api_configuration->maximum_queued_signals
+ );
+
+ _POSIX_Threads_Manager_initialization(
+ api_configuration->maximum_threads,
+ api_configuration->number_of_initialization_threads,
+ api_configuration->User_initialization_threads_table
+ );
+
+ _POSIX_Condition_variables_Manager_initialization(
+ api_configuration->maximum_condition_variables
+ );
+
+ _POSIX_Key_Manager_initialization( api_configuration->maximum_keys );
+
+ _POSIX_Mutex_Manager_initialization(
+ api_configuration->maximum_mutexes
+ );
+
+ _POSIX_Message_queue_Manager_initialization(
+ api_configuration->maximum_message_queues
+ );
+
+ _POSIX_Semaphore_Manager_initialization(
+ api_configuration->maximum_semaphores
+ );
+
+ _POSIX_Timer_Manager_initialization ( api_configuration->maximum_timers );
+}
+
+#endif
+/* end of file */
diff --git a/cpukit/sapi/src/rtemsapi.c b/cpukit/sapi/src/rtemsapi.c
new file mode 100644
index 0000000000..282f697e7e
--- /dev/null
+++ b/cpukit/sapi/src/rtemsapi.c
@@ -0,0 +1,101 @@
+/*
+ * POSIX API Initialization Support
+ *
+ * NOTE:
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * RTEMS_API_INIT is defined so all of the RTEMS API
+ * data will be included in this object file.
+ */
+
+#define RTEMS_API_INIT
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/rtemsapi.h>
+
+#include <rtems/rtems/intr.h>
+#include <rtems/rtems/clock.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/rtems/dpmem.h>
+#include <rtems/rtems/event.h>
+#include <rtems/rtems/message.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/mp.h>
+#endif
+#include <rtems/rtems/part.h>
+#include <rtems/rtems/ratemon.h>
+#include <rtems/rtems/region.h>
+#include <rtems/rtems/sem.h>
+#include <rtems/rtems/signal.h>
+#include <rtems/rtems/timer.h>
+
+Objects_Information *_RTEMS_Objects[ OBJECTS_RTEMS_CLASSES_LAST + 1 ];
+
+/*PAGE
+ *
+ * _RTEMS_API_Initialize
+ *
+ * XXX
+ */
+
+void _RTEMS_API_Initialize(
+ rtems_configuration_table *configuration_table
+)
+{
+ rtems_api_configuration_table *api_configuration;
+
+ api_configuration = configuration_table->RTEMS_api_configuration;
+
+ _Objects_Information_table[OBJECTS_CLASSIC_API] = _RTEMS_Objects;
+
+ _Attributes_Handler_initialization();
+
+ _Interrupt_Manager_initialization();
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _Multiprocessing_Manager_initialization();
+#endif
+
+ _RTEMS_tasks_Manager_initialization(
+ api_configuration->maximum_tasks,
+ api_configuration->number_of_initialization_tasks,
+ api_configuration->User_initialization_tasks_table
+ );
+
+ _Timer_Manager_initialization( api_configuration->maximum_timers );
+
+ _Signal_Manager_initialization();
+
+ _Event_Manager_initialization();
+
+ _Message_queue_Manager_initialization(
+ api_configuration->maximum_message_queues
+ );
+
+ _Semaphore_Manager_initialization( api_configuration->maximum_semaphores );
+
+ _Partition_Manager_initialization( api_configuration->maximum_partitions );
+
+ _Region_Manager_initialization( api_configuration->maximum_regions );
+
+ _Dual_ported_memory_Manager_initialization( api_configuration->maximum_ports);
+
+ _Rate_monotonic_Manager_initialization( api_configuration->maximum_periods );
+}
+
+/* end of file */
diff --git a/cpukit/score/.cvsignore b/cpukit/score/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/Doxyfile b/cpukit/score/Doxyfile
new file mode 100644
index 0000000000..dd384bf7ba
--- /dev/null
+++ b/cpukit/score/Doxyfile
@@ -0,0 +1,1079 @@
+# Doxyfile 1.3.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = RTEMS SuperCore
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = score_doxy
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en
+# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese,
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = include inline cpu/no_cpu
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc
+
+FILE_PATTERNS = *.h *.inl
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+
+INPUT_FILTER =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output dir.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimised for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assigments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED = RTEMS_INLINES FALSE=0 \
+ CPU_USE_GENERIC_BITFIELD_DATA=0
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse the
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this
+# option is superceded by the HAVE_DOT option below. This is only a fallback. It is
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similiar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes that
+# lay further from the root node will be omitted. Note that setting this option to
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that a graph may be further truncated if the graph's image dimensions are
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT).
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
new file mode 100644
index 0000000000..04ddb00229
--- /dev/null
+++ b/cpukit/score/Makefile.am
@@ -0,0 +1,164 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+SUBDIRS = cpu
+
+## include
+
+include_rtemsdir = $(includedir)/rtems
+
+include_rtems_HEADERS = include/rtems/debug.h include/rtems/system.h \
+ include/rtems/seterr.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+
+include_rtems_score_HEADERS = include/rtems/score/address.h \
+ include/rtems/score/apiext.h include/rtems/score/apimutex.h \
+ include/rtems/score/bitfield.h include/rtems/score/chain.h \
+ include/rtems/score/context.h include/rtems/score/copyrt.h \
+ include/rtems/score/coremsg.h include/rtems/score/coremutex.h \
+ include/rtems/score/coresem.h include/rtems/score/heap.h \
+ include/rtems/score/interr.h include/rtems/score/isr.h \
+ include/rtems/score/object.h include/rtems/score/priority.h \
+ include/rtems/score/stack.h include/rtems/score/states.h \
+ include/rtems/score/sysstate.h include/rtems/score/thread.h \
+ include/rtems/score/threadq.h include/rtems/score/tod.h \
+ include/rtems/score/tqdata.h include/rtems/score/userext.h \
+ include/rtems/score/watchdog.h include/rtems/score/wkspace.h \
+ include/rtems/score/cpuopts.h
+
+if HAS_MP
+# We only build multiprocessing related files if HAS_MP was defined
+include_rtems_score_HEADERS += include/rtems/score/mpci.h \
+ include/rtems/score/mppkt.h include/rtems/score/objectmp.h \
+ include/rtems/score/threadmp.h
+endif
+
+## inline
+if INLINE
+include_rtems_score_HEADERS += inline/rtems/score/address.inl \
+ inline/rtems/score/chain.inl inline/rtems/score/coremsg.inl \
+ inline/rtems/score/coremutex.inl inline/rtems/score/coresem.inl \
+ inline/rtems/score/heap.inl inline/rtems/score/isr.inl \
+ inline/rtems/score/object.inl inline/rtems/score/priority.inl \
+ inline/rtems/score/stack.inl inline/rtems/score/states.inl \
+ inline/rtems/score/sysstate.inl inline/rtems/score/thread.inl \
+ inline/rtems/score/tod.inl inline/rtems/score/tqdata.inl \
+ inline/rtems/score/userext.inl inline/rtems/score/watchdog.inl \
+ inline/rtems/score/wkspace.inl
+
+if HAS_MP
+## We only build multiprocessing related files if HAS_MP was defined
+include_rtems_score_HEADERS += inline/rtems/score/mppkt.inl \
+ inline/rtems/score/objectmp.inl inline/rtems/score/threadmp.inl
+endif
+else
+## macros
+include_rtems_score_HEADERS += macros/rtems/score/address.inl \
+ macros/rtems/score/chain.inl macros/rtems/score/coremsg.inl \
+ macros/rtems/score/coremutex.inl macros/rtems/score/coresem.inl \
+ macros/rtems/score/heap.inl macros/rtems/score/isr.inl \
+ macros/rtems/score/object.inl macros/rtems/score/priority.inl \
+ macros/rtems/score/stack.inl macros/rtems/score/states.inl \
+ macros/rtems/score/sysstate.inl macros/rtems/score/thread.inl \
+ macros/rtems/score/tod.inl macros/rtems/score/tqdata.inl \
+ macros/rtems/score/userext.inl macros/rtems/score/watchdog.inl \
+ macros/rtems/score/wkspace.inl
+if HAS_MP
+## We only build multiprocessing related files if HAS_MP was defined
+include_rtems_score_HEADERS += macros/rtems/score/mppkt.inl \
+ macros/rtems/score/objectmp.inl macros/rtems/score/threadmp.inl
+endif
+endif
+
+EXTRA_DIST = macros/README
+
+## src
+
+AM_CPPFLAGS += -D__RTEMS_INSIDE__
+
+noinst_LIBRARIES = libscore.a
+libscore_a_SOURCES =
+libscore_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+# We only build multiprocessing related files if HAS_MP was defined
+if HAS_MP
+libscore_a_SOURCES += src/mpci.c src/objectmp.c src/threadmp.c
+endif
+
+## CORE_MESSAGE_QUEUE_C_FILES
+libscore_a_SOURCES += src/coremsg.c src/coremsgbroadcast.c \
+ src/coremsgclose.c src/coremsgflush.c src/coremsgflushwait.c \
+ src/coremsginsert.c src/coremsgflushsupp.c src/coremsgseize.c \
+ src/coremsgsubmit.c
+
+## CORE_MUTEX_C_FILES
+libscore_a_SOURCES += src/coremutex.c src/coremutexflush.c \
+ src/coremutexseize.c src/coremutexsurrender.c
+
+## CORE_SEMAPHORE_C_FILES
+libscore_a_SOURCES += src/coresem.c src/coresemflush.c src/coresemseize.c \
+ src/coresemsurrender.c
+
+## HEAP_C_FILES
+libscore_a_SOURCES += src/heap.c src/heapallocate.c src/heapextend.c src/heapfree.c \
+ src/heapsizeofuserarea.c src/heapwalk.c src/heapgetinfo.c \
+ src/heapgetfreeinfo.c src/heapallocatealigned.c \
+ src/heapresizeblock.c
+
+## OBJECT_C_FILES
+libscore_a_SOURCES += src/object.c src/objectallocate.c \
+ src/objectallocatebyindex.c src/objectclearname.c \
+ src/objectcomparenameraw.c src/objectcomparenamestring.c \
+ src/objectcopynameraw.c src/objectcopynamestring.c \
+ src/objectextendinformation.c src/objectfree.c src/objectget.c \
+ src/objectgetisr.c src/objectgetbyindex.c src/objectgetnext.c \
+ src/objectinitializeinformation.c src/objectnametoid.c \
+ src/objectshrinkinformation.c src/objectgetnoprotection.c \
+ src/objectidtoname.c
+
+## THREAD_C_FILES
+libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \
+ src/threadclearstate.c src/threadclose.c src/threadcreateidle.c \
+ src/threaddelayended.c src/threaddispatch.c src/threadevaluatemode.c \
+ src/threadget.c src/threadhandler.c src/threadidlebody.c \
+ src/threadinitialize.c src/threadloadenv.c src/threadready.c \
+ src/threadresettimeslice.c src/threadreset.c src/threadrestart.c \
+ src/threadresume.c src/threadrotatequeue.c src/threadsetpriority.c \
+ src/threadsetstate.c src/threadsettransient.c src/threadstackallocate.c \
+ src/threadstackfree.c src/threadstart.c src/threadstartmultitasking.c \
+ src/threadsuspend.c src/threadtickletimeslice.c \
+ src/threadyieldprocessor.c src/iterateoverthreads.c
+
+## THREADQ_C_FILES
+libscore_a_SOURCES += src/threadq.c src/threadqdequeue.c \
+ src/threadqdequeuefifo.c src/threadqdequeuepriority.c \
+ src/threadqenqueue.c src/threadqenqueuefifo.c \
+ src/threadqenqueuepriority.c src/threadqextract.c \
+ src/threadqextractfifo.c src/threadqextractpriority.c \
+ src/threadqextractwithproxy.c src/threadqfirst.c src/threadqfirstfifo.c \
+ src/threadqfirstpriority.c src/threadqflush.c src/threadqtimeout.c
+
+## TOD_C_FILES
+libscore_a_SOURCES += src/coretod.c src/coretodset.c src/coretodtickle.c \
+ src/coretodtoseconds.c src/coretodvalidate.c
+
+## WATCHDOG_C_FILES
+libscore_a_SOURCES += src/watchdog.c src/watchdogadjust.c src/watchdoginsert.c \
+ src/watchdogremove.c src/watchdogtickle.c
+
+## STD_C_FILES
+libscore_a_SOURCES += src/apiext.c src/chain.c \
+ src/interr.c src/isr.c src/userext.c src/wkspace.c
+
+EXTRA_DIST += src/Unlimited.txt
+
+DISTCLEANFILES = include/rtems/score/cpuopts.h
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/subdirs.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/.cvsignore b/cpukit/score/cpu/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/Makefile.am b/cpukit/score/cpu/Makefile.am
new file mode 100644
index 0000000000..fa2e9d16c8
--- /dev/null
+++ b/cpukit/score/cpu/Makefile.am
@@ -0,0 +1,12 @@
+##
+## $Id$
+##
+
+SUBDIRS = @RTEMS_CPU@
+
+DIST_SUBDIRS = arm c4x h8300 i386 m68k mips nios2 no_cpu powerpc sh sparc \
+ unix
+DIST_SUBDIRS += avr
+
+include $(top_srcdir)/automake/subdirs.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/arm/.cvsignore b/cpukit/score/cpu/arm/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/arm/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/arm/ChangeLog b/cpukit/score/cpu/arm/ChangeLog
new file mode 100644
index 0000000000..85a5e9553c
--- /dev/null
+++ b/cpukit/score/cpu/arm/ChangeLog
@@ -0,0 +1,414 @@
+2006-06-02 Jay Monkman <jtm@lopingdog.com>
+
+ * cpu.c, cpu_asm.S: Fixed ARM Data Abort handling.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16, unsigned32.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h: Remove private version of CONCAT macros.
+ Include <rtems/concat.h> instead.
+
+2005-09-15 Jay Monkman <jtm@lopingdog.com>
+
+ PR 365/rtems
+ * rtems/score/arm.h, rtems/score/cpu.h: Removed unused ARM_HAS_CLZ
+ macro.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/arm.h, rtems/score/cpu.h,
+ rtems/score/cpu_asm.h, rtems/score/types.h: New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: *_swap_u32( uint32_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: #include <rtems/stdint.h>.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove build-variant support.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Use __rtems_score_types_h as preprocessor
+ guard.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * asm.h: Add doxygen preamble.
+
+2004-10-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/arm.h: Add doxygen preamble.
+ * rtems/score/cpu.h: Add doxygen preamble.
+ * rtems/score/cpu_asm.h: Add doxygen preamble.
+ * rtems/score/types.h: Add doxygen preamble.
+
+2004-09-29 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: i960 obsoleted and all references removed.
+
+2004-08-19 Jay Monkman <jtm@lopingdog.com>
+
+ PR 671/bsps
+ * rtems/score/cpu.h: Fixed bug in _CPU_ISR_Set_level, where input param
+ was always ignored.
+
+2004-04-09 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Fix typo.
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Remove (Merged into $(top_srcdir)/configure.ac).
+ * Makefile.am: Don't include multilib.am.
+ Reflect merging configure.ac into $(top_srcdir)/configure.ac.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Install asm.h to $(includedir)/rtems.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu_asm.S: Include <rtems/asm.h> instead of <asm.h>.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu.c, rtems/score/cpu.h: Convert to using c99 fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: RTEMS_TOP([../../../..]).
+
+2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Move RTEMS_TOP one subdir down.
+
+2004-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add PREINSTALL_DIRS.
+
+2004-01-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Re-add dirstamps to PREINSTALL_FILES.
+ Add PREINSTALL_FILES to CLEANFILES.
+
+2004-01-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Requires automake >= 1.8.1.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, again.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Convert to using automake compilation rules.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use mkdir_p. Remove dirs from PREINSTALL_FILES.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require automake >= 1.8, autoconf >= 2.59.
+
+2003-12-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Remove TMPINSTALL_FILES.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Don't use gmake rules for preinstallation.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CANONICAL_HOST.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CPU.
+
+2003-09-26 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Obsoleting HP PA-RISC port and removing all
+ references.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * asm.h, cpu.c, cpu_asm.S, rtems/score/arm.h, rtems/score/cpu.h,
+ rtems/score/cpu_asm.h, rtems/score/types.h: URL for license changed.
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-04-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use "all-local:" instead of "all:".
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+
+2003-03-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/arm.h: Remove ARM_HAS_THUMB (Unused).
+
+2003-03-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/cpu.h: Set up CPU_*_ENDIAN based on -D__ARMEL__ and
+ -D__ARMEB__. Fix minor typo in comment.
+
+2003-02-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/arm.h: Set up ARM_HAS_FPU based on -D__SOFTFP__.
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require autoconf-2.57 + automake-1.7.2.
+ * Makefile.am: Eliminate C_O_FILES, S_O_FILES, libscorecpu_a_OBJECTS.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix package name.
+
+2002-11-04 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c: Removed warning.
+
+2002-11-01 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c: Removed warnings.
+
+2002-10-31 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Removed warning.
+
+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-10-04 Jay Monkman <jtm@smoothsmoothie.com>
+
+ * rtems/score/cpu.h: Fix u16 and u32 swap routines.
+
+2002-08-05 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h, rtems/score/types.h: Updated to fix some typos.
+
+2002-07-30 Jay Monkman <jtm@smoothsmoothie.com>
+
+ * cpu.c, cpu_asm.S, rtems/score/arm.h, rtems/score/cpu.h,
+ rtems/score/cpu_asm.h, rtems/score/types.h: ARM port works
+ well enough to run all sptests, tmtests, and ttcp.
+ In addition to general cleanup, there has been considerable
+ optimization to interrupt disable/enable, endian swapping,
+ and context switching.
+
+2002-07-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use .$(OBJEXT) instead of .o.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use . instead of .o.
+
+2002-07-17 Jay Monkman <jtm@smoothsmoothie.com>
+
+ * rtems/score/cpu_asm.h: Enhanced to include register offsets.
+ * Makefile.am: Install rtems/score/cpu_asm.h.
+ * cpu.c: Significantly enhanced including the implementation of
+ _CPU_ISR_Get_level.
+ * cpu_asm.S: Improved behavior of context switch and interrupt
+ dispatching.
+ * rtems/score/arm.h: Improved the CPU model name determination.
+ * rtems/score/cpu.h: Improved interrupt disable/enable functions.
+
+2002-07-05 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Filled in something that was marked XXX.
+
+2002-07-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: RTEMS_TOP(../../../..).
+
+2002-07-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems.c: Remove.
+ * Makefile.am: Reflect changes above.
+
+2002-07-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_PROJECT_ROOT.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add RTEMS_PROG_CCAS
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AC_CONFIG_AUX_DIR(../../../..).
+ Add AC_PROG_RANLIB.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/../../../automake/*.am.
+ Use ../../../aclocal.
+
+2002-04-18 Jay Monkman <jtm@smoothsmoothie.com>
+
+ * rtems/score/cpu.h (CPU_ISR_Disable and CPU_ISR_Enable): Correct them
+ where they correctly inform the compiler about the register they
+ are modifying.
+
+2001-04-03 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
+ * rtems/score/a29ktypes.h: Removed.
+ * rtems/score/types.h: New file via CVS magic.
+ * Makefile.am, 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-02-04 Joel Sherrill <joel@OARcorp.com>
+
+ * configure.ac: Removed references to rtems/Makefile and
+ rtems/score/Makefile.
+
+2002-01-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/Makefile.am: Removed.
+ * rtems/score/Makefile.am: Removed.
+ * configure.ac: Reflect changes above.
+ * Makefile.am: Reflect changes above.
+
+2002-02-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CUSTOM_BSP.
+
+2002-01-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * cpu.c: Include rtems/bspIo.h instead of bspIo.h.
+
+2001-12-20 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use RTEMS_ENV_RTEMSCPU.
+
+2001-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add multilib support.
+
+2001-12-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * asm.h: include cpuopts.h instead of targopts.h
+ * rtems/score/arm.h: Use __arm__.
+
+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.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/Makefile.am: Use 'PREINSTALL_FILES ='.
+ * Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, rtems/score/Makefile.am:
+ Apply include_*HEADERS instead of H_FILES.
+
+2001-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Added _CPU_Initialize_vectors().
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
+ Switch to GNU canonicalization.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, formatting.
+ * rtems/Makefile.am: Formatting.
+ * rtems/score/Makefile.am: Formatting.
+
+2000-08-29 Joel Sherrill <joel.sherrill@OARcorp.com>
+
+ * cpu.c: Spacing issues.
+ * rtems/score/cpu.h: Removed warning by setting _level.
+
+2000-08-29 Joel Sherrill <joel.sherrill@OARcorp.com>
+
+ * Makefile.am: Added S_O_FILES to list of objects.
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: New file.
diff --git a/cpukit/score/cpu/arm/Makefile.am b/cpukit/score/cpu/arm/Makefile.am
new file mode 100644
index 0000000000..2290aa4123
--- /dev/null
+++ b/cpukit/score/cpu/arm/Makefile.am
@@ -0,0 +1,19 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/cpu_asm.h \
+ rtems/score/arm.h rtems/score/types.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/arm/cpu.c b/cpukit/score/cpu/arm/cpu.c
new file mode 100644
index 0000000000..e1e6f8da51
--- /dev/null
+++ b/cpukit/score/cpu/arm/cpu.c
@@ -0,0 +1,368 @@
+/*
+ * ARM CPU Dependent Source
+ *
+ *
+ * COPYRIGHT (c) 2000 Canon Research Centre France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * Copyright (c) 2002 Advent Networks, Inc
+ * Jay Monkman <jmonkman@adventnetworks.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+#include <rtems/system.h>
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/cpu.h>
+
+/* _CPU_Initialize
+ *
+ * This routine performs processor dependent initialization.
+ *
+ * INPUT PARAMETERS:
+ * cpu_table - CPU table to initialize
+ * thread_dispatch - address of ISR disptaching routine (unused)
+ *
+ */
+
+uint32_t g_data_abort_cnt = 0;
+uint32_t g_data_abort_insn_list[1024];
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch) /* ignored on this CPU */
+)
+{
+ _CPU_Table = *cpu_table;
+}
+
+/*
+ *
+ * _CPU_ISR_Get_level - returns the current interrupt level
+ */
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ uint32_t reg = 0; /* to avoid warning */
+
+ asm volatile ("mrs %0, cpsr \n" \
+ "and %0, %0, #0xc0 \n" \
+ : "=r" (reg) \
+ : "0" (reg) );
+
+ return reg;
+}
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This kernel routine installs the RTEMS handler for the
+ * specified vector.
+ *
+ * Input parameters:
+ * vector - interrupt vector number
+ * new_handler - replacement ISR for this vector number
+ * old_handler - pointer to store former ISR for this vector number
+ *
+ * FIXME: This vector scheme should be changed to allow FIQ to be
+ * handled better. I'd like to be able to put VectorTable
+ * elsewhere - JTM
+ *
+ *
+ * Output parameters: NONE
+ *
+ */
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ /* pointer on the redirection table in RAM */
+ long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
+
+ if (old_handler != NULL) {
+ old_handler = *(proc_ptr *)(VectorTable + vector);
+ }
+
+ *(VectorTable + vector) = (long)new_handler ;
+
+}
+
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ uint32_t *stack_base,
+ uint32_t size,
+ uint32_t new_level,
+ void *entry_point,
+ boolean is_fp
+)
+{
+ the_context->register_sp = (uint32_t )stack_base + size ;
+ the_context->register_lr = (uint32_t )entry_point;
+ the_context->register_cpsr = new_level | 0x13;
+}
+
+
+/*
+ * _CPU_Install_interrupt_stack - this function is empty since the
+ * BSP must set up the interrupt stacks.
+ */
+
+void _CPU_Install_interrupt_stack( void )
+{
+}
+
+void _defaultExcHandler (CPU_Exception_frame *ctx)
+{
+ printk("\n\r");
+ printk("----------------------------------------------------------\n\r");
+#if 1
+ printk("Exception 0x%x caught at PC 0x%x by thread %d\n",
+ ctx->register_ip, ctx->register_lr - 4,
+ _Thread_Executing->Object.id);
+#endif
+ printk("----------------------------------------------------------\n\r");
+ printk("Processor execution context at time of the fault was :\n\r");
+ printk("----------------------------------------------------------\n\r");
+#if 0
+ printk(" r0 = %8x r1 = %8x r2 = %8x r3 = %8x\n\r",
+ ctx->register_r0, ctx->register_r1,
+ ctx->register_r2, ctx->register_r3);
+ printk(" r4 = %8x r5 = %8x r6 = %8x r7 = %8x\n\r",
+ ctx->register_r4, ctx->register_r5,
+ ctx->register_r6, ctx->register_r7);
+ printk(" r8 = %8x r9 = %8x r10 = %8x\n\r",
+ ctx->register_r8, ctx->register_r9, ctx->register_r10);
+ printk(" fp = %8x ip = %8x sp = %8x pc = %8x\n\r",
+ ctx->register_fp, ctx->register_ip,
+ ctx->register_sp, ctx->register_lr - 4);
+ printk("----------------------------------------------------------\n\r");
+#endif
+ if (_ISR_Nest_level > 0) {
+ /*
+ * In this case we shall not delete the task interrupted as
+ * it has nothing to do with the fault. We cannot return either
+ * because the eip points to the faulty instruction so...
+ */
+ printk("Exception while executing ISR!!!. System locked\n\r");
+ while(1);
+ }
+ else {
+ printk("*********** FAULTY THREAD WILL BE DELETED **************\n\r");
+ rtems_task_delete(_Thread_Executing->Object.id);
+ }
+}
+
+cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
+
+extern void _Exception_Handler_Undef_Swi();
+extern void _Exception_Handler_Abort();
+extern void _exc_data_abort();
+/* FIXME: put comments here */
+void rtems_exception_init_mngt()
+{
+ ISR_Level level;
+
+ _CPU_ISR_Disable(level);
+ _CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF,
+ _Exception_Handler_Undef_Swi,
+ NULL);
+
+ _CPU_ISR_install_vector(ARM_EXCEPTION_SWI,
+ _Exception_Handler_Undef_Swi,
+ NULL);
+
+ _CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT,
+ _Exception_Handler_Abort,
+ NULL);
+
+ _CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT,
+ _exc_data_abort,
+ NULL);
+
+ _CPU_ISR_install_vector(ARM_EXCEPTION_FIQ,
+ _Exception_Handler_Abort,
+ NULL);
+
+ _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ,
+ _Exception_Handler_Abort,
+ NULL);
+
+ _CPU_ISR_Enable(level);
+}
+
+#define INSN_MASK 0xc5
+
+#define INSN_STM1 0x80
+#define INSN_STM2 0x84
+#define INSN_STR 0x40
+#define INSN_STRB 0x44
+
+#define INSN_LDM1 0x81
+#define INSN_LDM23 0x85
+#define INSN_LDR 0x41
+#define INSN_LDRB 0x45
+
+#define GET_RD(x) ((x & 0x0000f000) >> 12)
+#define GET_RN(x) ((x & 0x000f0000) >> 16)
+
+#define GET_U(x) ((x & 0x00800000) >> 23)
+#define GET_I(x) ((x & 0x02000000) >> 25)
+
+#define GET_REG(r, ctx) (((uint32_t *)ctx)[r])
+#define SET_REG(r, ctx, v) (((uint32_t *)ctx)[r] = v)
+#define GET_OFFSET(insn) (insn & 0xfff)
+
+char *_print_full_context_mode2txt[0x20]={
+ [0x10]="user", /* User */
+ [0x11]="fiq", /* FIQ - Fast Interrupt Request */
+ [0x12]="irq", /* IRQ - Interrupt Request */
+ [0x13]="super", /* Supervisor */
+ [0x17]="abort", /* Abort */
+ [0x1b]="undef", /* Undefined */
+ [0x1f]="system" /* System */
+ };
+
+void _print_full_context(uint32_t spsr)
+{
+ char *mode;
+ uint32_t prev_sp,prev_lr,cpsr,tmp;
+ int i;
+
+ printk("active thread thread 0x%08x\n", _Thread_Executing->Object.id);
+
+ mode=_print_full_context_mode2txt[spsr&0x1f];
+ if(!mode) mode="unknown";
+
+ asm volatile (" MRS %[cpsr], cpsr \n"
+ " ORR %[tmp], %[spsr], #0xc0 \n"
+ " MSR cpsr_c, %[tmp] \n"
+ " MOV %[prev_sp], sp \n"
+ " MOV %[prev_lr], lr \n"
+ " MSR cpsr_c, %[cpsr] \n"
+ : [prev_sp] "=&r" (prev_sp), [prev_lr] "=&r" (prev_lr),
+ [cpsr] "=&r" (cpsr), [tmp] "=&r" (tmp)
+ : [spsr] "r" (spsr)
+ : "cc");
+
+ printk("Previous sp=0x%08x lr=0x%08x and actual cpsr=%08x\n", prev_sp, prev_lr, cpsr);
+
+ for(i=0;i<48;){
+ printk(" 0x%08x",((uint32_t*)prev_sp)[i++]);
+ if((i%6) == 0)
+ printk("\n");
+ }
+
+}
+
+/* This function is supposed to figure out what caused the
+ * data abort, do that, then return.
+ *
+ * All unhandled instructions cause the system to hang.
+ */
+
+void do_data_abort(uint32_t insn, uint32_t spsr,
+ Context_Control *ctx)
+{
+ /* Clarify, which type is correct, CPU_Exception_frame or Context_Control */
+
+ uint8_t decode;
+ uint8_t insn_type;
+
+ uint32_t rn;
+ uint32_t rd;
+
+ uint8_t *src_addr;
+ uint32_t tmp;
+
+ g_data_abort_insn_list[g_data_abort_cnt & 0x3ff] = ctx->register_lr - 8;
+ g_data_abort_cnt++;
+
+ decode = ((insn >> 20) & 0xff);
+
+ insn_type = decode & INSN_MASK;
+ switch(insn_type) {
+ case INSN_STM1:
+ printk("\n\nINSN_STM1\n");
+ break;
+ case INSN_STM2:
+ printk("\n\nINSN_STM2\n");
+ break;
+ case INSN_STR:
+ printk("\n\nINSN_STR\n");
+ break;
+ case INSN_STRB:
+ printk("\n\nINSN_STRB\n");
+ break;
+ case INSN_LDM1:
+ printk("\n\nINSN_LDM1\n");
+ break;
+ case INSN_LDM23:
+ printk("\n\nINSN_LDM23\n");
+ break;
+ case INSN_LDR:
+ printk("\n\nINSN_LDR\n");
+
+#if 0
+ rn = GET_RN(insn);
+ rd = GET_RD(insn);
+
+ /* immediate offset/index */
+ if (GET_I(insn) == 0) {
+ switch(decode & 0x12) { /* P and W bits */
+ case 0x00: /* P=0, W=0 -> base is updated, post-indexed */
+ printk("\tPost-indexed\n");
+ break;
+ case 0x02: /* P=0, W=1 -> user mode access */
+ printk("\tUser mode\n");
+ break;
+ case 0x10: /* P=1, W=0 -> base not updated */
+ src_addr = (uint8_t *)GET_REG(rn, ctx);
+ if (GET_U(insn) == 0) {
+ src_addr -= GET_OFFSET(insn);
+ } else {
+ src_addr += GET_OFFSET(insn);
+ }
+ tmp = (src_addr[0] |
+ (src_addr[1] << 8) |
+ (src_addr[2] << 16) |
+ (src_addr[3] << 24));
+ SET_REG(rd, ctx, tmp);
+ return;
+ break;
+ case 0x12: /* P=1, W=1 -> base is updated, pre-indexed */
+ printk("\tPre-indexed\n");
+ break;
+ }
+ }
+#endif
+
+ break;
+ case INSN_LDRB:
+ printk("\n\nINSN_LDRB\n");
+ break;
+ default:
+ printk("\n\nUnrecognized instruction\n");
+ break;
+ }
+
+ printk("data_abort at address 0x%x, instruction: 0x%x, spsr = 0x%x\n",
+ ctx->register_lr - 8, insn, spsr);
+
+ _print_full_context(spsr);
+
+ /* disable interrupts, wait forever */
+ _CPU_ISR_Disable(tmp);
+ while(1) {
+ continue;
+ }
+ return;
+}
diff --git a/cpukit/score/cpu/arm/cpu_asm.S b/cpukit/score/cpu/arm/cpu_asm.S
new file mode 100644
index 0000000000..7abc881e45
--- /dev/null
+++ b/cpukit/score/cpu/arm/cpu_asm.S
@@ -0,0 +1,164 @@
+/*
+ * $Id$
+ *
+ * This file contains all assembly code for the ARM implementation
+ * of RTEMS.
+ *
+ * Copyright (c) 2002 by Advent Networks, Inc.
+ * Jay Monkman <jmonkman@adventnetworks.com>
+ *
+ * COPYRIGHT (c) 2000 Canon Research Centre France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+#include <rtems/asm.h>
+#include <rtems/score/cpu_asm.h>
+
+
+/*
+ * void _CPU_Context_switch( run_context, heir_context )
+ * void _CPU_Context_restore( run_context, heir_context )
+ *
+ * This routine performs a normal non-FP context.
+ *
+ * R0 = run_context R1 = heir_context
+ *
+ * This function copies the current registers to where r0 points, then
+ * restores the ones from where r1 points.
+ *
+ * Using the ldm/stm opcodes save 2-3 us on 100 MHz ARM9TDMI with
+ * a 16 bit data bus.
+ *
+ */
+ .globl _CPU_Context_switch
+_CPU_Context_switch:
+/* Start saving context */
+ mrs r2, cpsr
+ stmia r0, {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
+
+
+/* Start restoring context */
+_restore:
+ ldmia r1, {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
+ msr cpsr, r2
+ mov pc, lr
+
+/*
+ * void _CPU_Context_restore( new_context )
+ *
+ * This function copies the restores the registers from where r0 points.
+ * It must match _CPU_Context_switch()
+ *
+ */
+ .globl _CPU_Context_restore
+_CPU_Context_restore:
+ mov r1, r0
+ b _restore
+
+
+
+/* FIXME: _Exception_Handler_Undef_Swi is untested */
+ .globl _Exception_Handler_Undef_Swi
+_Exception_Handler_Undef_Swi:
+/* FIXME: This should use load and store multiple instructions */
+ sub r13,r13,#SIZE_REGS
+ str r4, [r13, #REG_R4]
+ str r5, [r13, #REG_R5]
+ str r6, [r13, #REG_R6]
+ str r7, [r13, #REG_R7]
+ str r8, [r13, #REG_R8]
+ str r9, [r13, #REG_R9]
+ str r10, [r13, #REG_R10]
+ str r11, [r13, #REG_R11]
+ str sp, [r13, #REG_SP]
+ str lr, [r13, #REG_LR]
+ mrs r0, cpsr /* read the status */
+ and r0, r0,#0x1f /* we keep the mode as exception number */
+ str r0, [r13, #REG_PC] /* we store it in a free place */
+ mov r0, r13 /* put frame address in r0 (C arg 1) */
+
+ ldr r1, =SWI_Handler
+ ldr lr, =_go_back_1
+ ldr pc,[r1] /* call handler */
+_go_back_1:
+ ldr r4, [r13, #REG_R4]
+ ldr r5, [r13, #REG_R5]
+ ldr r6, [r13, #REG_R6]
+ ldr r7, [r13, #REG_R7]
+ ldr r8, [r13, #REG_R8]
+ ldr r9, [r13, #REG_R9]
+ ldr r10, [r13, #REG_R10]
+ ldr r11, [r13, #REG_R11]
+ ldr sp, [r13, #REG_SP]
+ ldr lr, [r13, #REG_LR]
+ add r13,r13,#SIZE_REGS
+ movs pc,r14 /* return */
+
+/* FIXME: _Exception_Handler_Abort is untested */
+ .globl _Exception_Handler_Abort
+_Exception_Handler_Abort:
+/* FIXME: This should use load and store multiple instructions */
+ sub r13,r13,#SIZE_REGS
+ str r4, [r13, #REG_R4]
+ str r5, [r13, #REG_R5]
+ str r6, [r13, #REG_R6]
+ str r7, [r13, #REG_R7]
+ str r8, [r13, #REG_R8]
+ str r9, [r13, #REG_R9]
+ str sp, [r13, #REG_R11]
+ str lr, [r13, #REG_SP]
+ str lr, [r13, #REG_LR]
+ mrs r0, cpsr /* read the status */
+ and r0, r0,#0x1f /* we keep the mode as exception number */
+ str r0, [r13, #REG_PC] /* we store it in a free place */
+ mov r0, r13 /* put frame address in ro (C arg 1) */
+
+ ldr r1, =_currentExcHandler
+ ldr lr, =_go_back_2
+ ldr pc,[r1] /* call handler */
+_go_back_2:
+ ldr r4, [r13, #REG_R4]
+ ldr r5, [r13, #REG_R5]
+ ldr r6, [r13, #REG_R6]
+ ldr r7, [r13, #REG_R7]
+ ldr r8, [r13, #REG_R8]
+ ldr r9, [r13, #REG_R9]
+ ldr r10, [r13, #REG_R10]
+ ldr sp, [r13, #REG_R11]
+ ldr lr, [r13, #REG_SP]
+ ldr lr, [r13, #REG_LR]
+ add r13,r13,#SIZE_REGS
+ subs pc,r14,#4 /* return */
+
+#define ABORT_REGS_OFFS 32-REG_R4
+#define ABORT_SIZE_REGS SIZE_REGS+ABORT_REGS_OFFS
+
+ .globl _exc_data_abort
+_exc_data_abort:
+ sub sp, sp, #ABORT_SIZE_REGS /* reserve register frame */
+ stmia sp, {r0-r11}
+ add sp, sp, #ABORT_REGS_OFFS /* the Context_Control structure starts by CPSR, R4, ... */
+
+ str ip, [sp, #REG_PC] /* store R12 (ip) somewhere, oh hackery, hackery, hack */
+ str lr, [sp, #REG_LR]
+
+ mov r1, lr
+ ldr r0, [r1, #-8] /* r0 = bad instruction */
+ mrs r1, spsr /* r1 = spsr */
+ mov r2, r13 /* r2 = exception frame of Context_Control type */
+ bl do_data_abort
+
+ ldr lr, [sp, #REG_LR]
+ ldr ip, [sp, #REG_PC] /* restore R12 (ip) */
+
+ sub sp, sp, #ABORT_REGS_OFFS
+ ldmia sp, {r0-r11}
+ add sp, sp, #ABORT_SIZE_REGS
+
+ subs pc, r14, #4 /* return to the instruction */
+ /* _AFTER_ the aborted one */
diff --git a/cpukit/score/cpu/arm/preinstall.am b/cpukit/score/cpu/arm/preinstall.am
new file mode 100644
index 0000000000..0e1110f6cd
--- /dev/null
+++ b/cpukit/score/cpu/arm/preinstall.am
@@ -0,0 +1,45 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/cpu_asm.h: rtems/score/cpu_asm.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/arm.h: rtems/score/arm.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/arm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/arm.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
diff --git a/cpukit/score/cpu/arm/rtems/asm.h b/cpukit/score/cpu/arm/rtems/asm.h
new file mode 100644
index 0000000000..5c33a2565a
--- /dev/null
+++ b/cpukit/score/cpu/arm/rtems/asm.h
@@ -0,0 +1,122 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ *
+ *
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ */
+
+/*
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ * COPYRIGHT (c) 2000 Canon Research Centre France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/arm.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/*
+ * define macros for all of the registers on this CPU
+ *
+ * EXAMPLE: #define d0 REG (d0)
+ */
+
+#define r0 REG(r0)
+#define r1 REG(r1)
+#define r2 REG(r2)
+#define r3 REG(r3)
+#define r4 REG(r4)
+#define r5 REG(r5)
+#define r6 REG(r6)
+#define r7 REG(r7)
+#define r8 REG(r8)
+#define r9 REG(r9)
+#define r10 REG(r10)
+#define r11 REG(r11)
+#define r12 REG(r12)
+#define r13 REG(r13)
+#define r14 REG(r14)
+#define r15 REG(r15)
+
+#define CPSR REG(CPSR)
+
+#define SPSR REG(SPSR)
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA
+#define END_DATA
+#define BEGIN_BSS
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .globl SYM (sym)
+#define EXTERN(sym) .globl SYM (sym)
+
+#endif
diff --git a/cpukit/score/cpu/arm/rtems/score/arm.h b/cpukit/score/cpu/arm/rtems/score/arm.h
new file mode 100644
index 0000000000..e9a21baf7c
--- /dev/null
+++ b/cpukit/score/cpu/arm/rtems/score/arm.h
@@ -0,0 +1,77 @@
+/**
+ * @file rtems/score/arm.h
+ */
+
+/*
+ * $Id$
+ *
+ * COPYRIGHT (c) 2000 Canon Research Centre France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * Copyright (c) 2002 Advent Networks, Inc.
+ * Jay Monkman <jmonkman@adventnetworks.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+#ifndef _RTEMS_SCORE_ARM_H
+#define _RTEMS_SCORE_ARM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the "arm"
+ * family when executing in protected mode. It does
+ * this by setting variables to indicate which implementation
+ * dependent features are present in a particular member
+ * of the family.
+ */
+#if defined(__ARM_ARCH_4__)
+# define CPU_MODEL_NAME "ARMv4"
+
+#elif defined(__ARM_ARCH_4T__)
+# define CPU_MODEL_NAME "ARMv4T"
+
+#elif defined(__ARM_ARCH_5__)
+# define CPU_MODEL_NAME "ARMv5"
+
+#elif defined(__ARM_ARCH_5T__)
+# define CPU_MODEL_NAME "ARMv5T"
+
+#elif defined(__ARM_ARCH_5E__)
+# define CPU_MODEL_NAME "ARMv5E"
+
+#elif defined(__ARM_ARCH_5TE__)
+# define CPU_MODEL_NAME "ARMv5TE"
+
+#else
+# error "Unsupported CPU Model"
+
+#endif
+
+/* All ARM CPUs are assumed to not have floating point units */
+#if defined(__SOFTFP__)
+#define ARM_HAS_FPU 0
+#else
+#define ARM_HAS_FPU 1
+# error "FPU-support not yet implemented for the arm"
+#endif
+
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "ARM"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_ARM_H */
diff --git a/cpukit/score/cpu/arm/rtems/score/cpu.h b/cpukit/score/cpu/arm/rtems/score/cpu.h
new file mode 100644
index 0000000000..ca1ac70334
--- /dev/null
+++ b/cpukit/score/cpu/arm/rtems/score/cpu.h
@@ -0,0 +1,845 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * $Id$
+ *
+ * This include file contains information pertaining to the ARM
+ * processor.
+ *
+ * Copyright (c) 2006 OAR Corporation
+ *
+ * Copyright (c) 2002 Advent Networks, Inc.
+ * Jay Monkman <jmonkman@adventnetworks.com>
+ *
+ * COPYRIGHT (c) 2000 Canon Research Centre France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+/* FIXME: finish commenting/cleaning up this file */
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/arm.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+
+/* conditional compilation parameters */
+
+/*
+ * Should the calls to _Thread_Enable_dispatch be inlined?
+ *
+ * If TRUE, then they are inlined.
+ * If FALSE, then a subroutine call is made.
+ *
+ * Basically this is an example of the classic trade-off of size
+ * versus speed. Inlining the call (TRUE) typically increases the
+ * size of RTEMS while speeding up the enabling of dispatching.
+ * [NOTE: In general, the _Thread_Dispatch_disable_level will
+ * only be 0 or 1 unless you are in an interrupt handler and that
+ * interrupt handler invokes the executive.] When not inlined
+ * something calls _Thread_Enable_dispatch which in turns calls
+ * _Thread_Dispatch. If the enable dispatch is inlined, then
+ * one subroutine call is avoided entirely.]
+ */
+
+#define CPU_INLINE_ENABLE_DISPATCH TRUE
+
+/*
+ * Should the body of the search loops in _Thread_queue_Enqueue_priority
+ * be unrolled one time? In unrolled each iteration of the loop examines
+ * two "nodes" on the chain being searched. Otherwise, only one node
+ * is examined per iteration.
+ *
+ * If TRUE, then the loops are unrolled.
+ * If FALSE, then the loops are not unrolled.
+ *
+ * The primary factor in making this decision is the cost of disabling
+ * and enabling interrupts (_ISR_Flash) versus the cost of rest of the
+ * body of the loop. On some CPUs, the flash is more expensive than
+ * one iteration of the loop body. In this case, it might be desirable
+ * to unroll the loop. It is important to note that on some CPUs, this
+ * code is the longest interrupt disable period in RTEMS. So it is
+ * necessary to strike a balance when setting this parameter.
+ */
+
+#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
+
+/*
+ * Does RTEMS manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in _Interrupt_Manager_initialization.
+ * If FALSE, nothing is done.
+ *
+ * If the CPU supports a dedicated interrupt stack in hardware,
+ * then it is generally the responsibility of the BSP to allocate it
+ * and set it up.
+ *
+ * If the CPU does not support a dedicated interrupt stack, then
+ * the porter has two options: (1) execute interrupts on the
+ * stack of the interrupted task, and (2) have RTEMS manage a dedicated
+ * interrupt stack.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
+
+/*
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * If TRUE, then it must be installed during initialization.
+ * If FALSE, then no installation is performed.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ */
+
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
+
+/*
+ * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * If TRUE, then the memory is allocated during initialization.
+ * If FALSE, then the memory is allocated during initialization.
+ *
+ * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
+ */
+
+#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
+
+/*
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ */
+
+#define CPU_ISR_PASSES_FRAME_POINTER 0
+
+/*
+ * Does the CPU have hardware floating point?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
+ *
+ * If there is a FP coprocessor such as the i387 or mc68881, then
+ * the answer is TRUE.
+ *
+ * The macro name "ARM_HAS_FPU" should be made CPU specific.
+ * It indicates whether or not this CPU model has FP support. For
+ * example, it would be possible to have an i386_nofp CPU model
+ * which set this to false to indicate that you have an i386 without
+ * an i387 and wish to leave floating point support out of RTEMS.
+ */
+
+#if ( ARM_HAS_FPU == 1 )
+#define CPU_HARDWARE_FP TRUE
+#else
+#define CPU_HARDWARE_FP FALSE
+#endif
+
+#define CPU_SOFTWARE_FP FALSE
+
+/*
+ * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
+ *
+ * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
+ */
+
+#define CPU_ALL_TASKS_ARE_FP FALSE
+
+/*
+ * Should the IDLE task have a floating point context?
+ *
+ * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * If FALSE, then the IDLE task does not have a floating point context.
+ *
+ * Setting this to TRUE negatively impacts the time required to preempt
+ * the IDLE task from an interrupt because the floating point context
+ * must be saved as part of the preemption.
+ */
+
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+/*
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ *
+ * If the floating point context does NOT have to be saved as part of
+ * interrupt dispatching, then it should be safe to set this to TRUE.
+ *
+ * Setting this flag to TRUE results in using a different algorithm
+ * for deciding when to save and restore the floating point context.
+ * The deferred FP switch algorithm minimizes the number of times
+ * the FP context is saved and restored. The FP context is not saved
+ * until a context switch is made to another, different FP task.
+ * Thus in a system with only one FP task, the FP context will never
+ * be saved or restored.
+ */
+
+#define CPU_USE_DEFERRED_FP_SWITCH FALSE
+
+/*
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine _CPU_Thread_Idle_body
+ * must be provided and is the default IDLE thread body instead of
+ * _CPU_Thread_Idle_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ *
+ * This is intended to allow for supporting processors which have
+ * a low power or idle mode. When the IDLE thread is executed, then
+ * the CPU can be powered down.
+ *
+ * The order of precedence for selecting the IDLE thread body is:
+ *
+ * 1. BSP provided
+ * 2. CPU dependent (if provided)
+ * 3. generic (if no BSP and no CPU dependent)
+ */
+
+#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
+
+/*
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * If TRUE, then the grows upward.
+ * If FALSE, then the grows toward smaller addresses.
+ */
+
+#define CPU_STACK_GROWS_UP FALSE
+
+/*
+ * The following is the variable attribute used to force alignment
+ * of critical RTEMS structures. On some processors it may make
+ * sense to have these aligned on tighter boundaries than
+ * the minimum requirements of the compiler in order to have as
+ * much of the critical data area as possible in a cache line.
+ *
+ * The placement of this macro in the declaration of the variables
+ * is based on the syntactically requirements of the GNU C
+ * "__attribute__" extension. For example with GNU C, use
+ * the following to force a structures to a 32 byte boundary.
+ *
+ * __attribute__ ((aligned (32)))
+ *
+ * NOTE: Currently only the Priority Bit Map table uses this feature.
+ * To benefit from using this, the data must be heavily
+ * used so it will stay in the cache and used frequently enough
+ * in the executive to justify turning this on.
+ */
+
+#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned (32)))
+
+/*
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ */
+
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+
+#if defined(__ARMEL__)
+#define CPU_BIG_ENDIAN FALSE
+#define CPU_LITTLE_ENDIAN TRUE
+#elif defined(__ARMEB__)
+#define CPU_BIG_ENDIAN TRUE
+#define CPU_LITTLE_ENDIAN FALSE
+#else
+#error "Unknown endianness"
+#endif
+
+/*
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
+ */
+
+#define CPU_MODES_INTERRUPT_MASK 0x000000c0
+
+/*
+ * Processor defined structures required by cpukit/score.
+ */
+
+/* may need to put some structures here. */
+
+/*
+ * Contexts
+ *
+ * Generally there are 2 types of context to save.
+ * 1. Interrupt registers to save
+ * 2. Task level registers to save
+ *
+ * This means we have the following 3 context items:
+ * 1. task level context stuff:: Context_Control
+ * 2. floating point task stuff:: Context_Control_fp
+ * 3. special interrupt level context :: Context_Control_interrupt
+ *
+ * On some processors, it is cost-effective to save only the callee
+ * preserved registers during a task context switch. This means
+ * that the ISR code needs to save those registers which do not
+ * persist across function calls. It is not mandatory to make this
+ * distinctions between the caller/callee saves registers for the
+ * purpose of minimizing context saved during task switch and on interrupts.
+ * If the cost of saving extra registers is minimal, simplicity is the
+ * choice. Save the same context on interrupt entry as for tasks in
+ * this case.
+ *
+ * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
+ * care should be used in designing the context area.
+ *
+ * On some CPUs with hardware floating point support, the Context_Control_fp
+ * structure will not be used or it simply consist of an array of a
+ * fixed number of bytes. This is done when the floating point context
+ * is dumped by a "FP save context" type instruction and the format
+ * is not really defined by the CPU. In this case, there is no need
+ * to figure out the exact format -- only the size. Of course, although
+ * this is enough information for RTEMS, it is probably not enough for
+ * a debugger such as gdb. But that is another problem.
+ */
+typedef struct {
+ uint32_t register_cpsr;
+ uint32_t register_r4;
+ uint32_t register_r5;
+ uint32_t register_r6;
+ uint32_t register_r7;
+ uint32_t register_r8;
+ uint32_t register_r9;
+ uint32_t register_r10;
+ uint32_t register_fp;
+ uint32_t register_sp;
+ uint32_t register_lr;
+ uint32_t register_pc;
+} Context_Control;
+
+typedef struct {
+ double some_float_register;
+} Context_Control_fp;
+
+typedef struct {
+ uint32_t register_r0;
+ uint32_t register_r1;
+ uint32_t register_r2;
+ uint32_t register_r3;
+ uint32_t register_ip;
+ uint32_t register_lr;
+} CPU_Exception_frame;
+
+typedef void (*cpuExcHandlerType) (CPU_Exception_frame*);
+extern cpuExcHandlerType _currentExcHandler;
+extern void rtems_exception_init_mngt();
+
+/*
+ * The following structure defines the set of information saved
+ * on the current stack by RTEMS upon receipt of each interrupt
+ * that will lead to re-enter the kernel to signal the thread.
+ */
+
+typedef CPU_Exception_frame CPU_Interrupt_frame;
+
+/*
+ * The following table contains the information required to configure
+ * the XXX processor specific parameters.
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+ /* end of fields required on all CPUs */
+
+} rtems_cpu_table;
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ */
+
+/*
+ * Macros to access ARM specific additions to the CPU Table
+ *
+ * none required
+ */
+
+/* There are no CPU specific additions to the CPU Table for this port. */
+
+/*
+ * This variable is optional. It is used on CPUs on which it is difficult
+ * to generate an "uninitialized" FP context. It is filled in by
+ * _CPU_Initialize and copied into the task's FP context area during
+ * _CPU_Context_Initialize.
+ */
+
+SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
+
+/*
+ * The size of the floating point context area. On some CPUs this
+ * will not be a "sizeof" because the format of the floating point
+ * area is not defined -- only the size is. This is usually on
+ * CPUs with a "floating point save context" instruction.
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/*
+ * Amount of extra stack (above minimum stack size) required by
+ * MPCI receive server thread. Remember that in a multiprocessor
+ * system this thread must exist and be able to process all directives.
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+/*
+ * This defines the number of entries in the ISR_Vector_table managed
+ * by RTEMS.
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 8
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
+
+/*
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level.
+ */
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/*
+ * Should be large enough to run all RTEMS tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ */
+
+#define CPU_STACK_MINIMUM_SIZE (1024*4)
+
+/*
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ */
+
+#define CPU_ALIGNMENT 4
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
+ * then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
+ * enough for the partition, then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * stack. This alignment requirement may be stricter than that for the
+ * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
+ * is strict enough for the stack, then this should be set to 0.
+ *
+ * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
+ */
+
+#define CPU_STACK_ALIGNMENT 4
+
+/* ISR handler macros */
+
+/*
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ */
+
+#define _CPU_Initialize_vectors()
+
+/*
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in _level.
+ */
+
+#define _CPU_ISR_Disable( _level ) \
+ { \
+ int reg; \
+ asm volatile ("MRS %0, cpsr \n" \
+ "ORR %1, %0, #0xc0 \n" \
+ "MSR cpsr, %1 \n" \
+ : "=&r" (_level), "=&r" (reg)); \
+ }
+
+/*
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * _level is not modified.
+ */
+
+#define _CPU_ISR_Enable( _level ) \
+ { \
+ asm volatile ("MSR cpsr, %0 \n" \
+ : : "r" (_level)); \
+ }
+
+/*
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ */
+
+#define _CPU_ISR_Flash( _level ) \
+ { \
+ int reg; \
+ asm volatile ("MRS %0, cpsr \n" \
+ "MSR cpsr, %1 \n" \
+ "MSR cpsr, %0 \n" \
+ : "=&r" (reg) \
+ : "r" (_level)); \
+ }
+
+/*
+ * Map interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a generic fashion are undefined. Someday,
+ * it would be nice if these were "mapped" by the application
+ * via a callout. For example, m68k has 8 levels 0 - 7, levels
+ * 8 - 255 would be available for bsp/application specific meaning.
+ * This could be used to manage a programmable interrupt controller
+ * via the rtems_task_mode directive.
+ *
+ * The get routine usually must be implemented as a subroutine.
+ */
+
+#define _CPU_ISR_Set_level( new_level ) \
+ { \
+ int reg = 0; /* to avoid warning */ \
+ asm volatile ("MRS %0, cpsr \n" \
+ "BIC %0, %0, #0xc0 \n" \
+ "ORR %0, %0, %2 \n" \
+ "MSR cpsr_c, %0 \n" \
+ : "=r" (reg) \
+ : "0" (reg), "r" (new_level)); \
+ }
+
+
+uint32_t _CPU_ISR_Get_level( void );
+
+/* end of ISR handler macros */
+
+/* Context handler macros */
+
+/*
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * This routine generally does not set any unnecessary register
+ * in the context. The state of the "general data" registers is
+ * undefined at task start time.
+ *
+ * NOTE: This is_fp parameter is TRUE if the thread is to be a floating
+ * point thread. This is typically only used on CPUs where the
+ * FPU may be easily disabled by software such as on the SPARC
+ * where the PSR contains an enable FPU bit.
+ */
+
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ uint32_t *stack_base,
+ uint32_t size,
+ uint32_t new_level,
+ void *entry_point,
+ boolean is_fp
+);
+
+/*
+ * This routine is responsible for somehow restarting the currently
+ * executing task. If you are lucky, then all that is necessary
+ * is restoring the context. Otherwise, there will need to be
+ * a special assembly routine which does something special in this
+ * case. Context_Restore should work most of the time. It will
+ * not work if restarting self conflicts with the stack frame
+ * assumptions of restoring a context.
+ */
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+/*
+ * The purpose of this macro is to allow the initial pointer into
+ * a floating point context area (used to save the floating point
+ * context) to be at an arbitrary place in the floating point
+ * context area.
+ *
+ * This is necessary because some FP units are designed to have
+ * their context saved as a stack which grows into lower addresses.
+ * Other FP units can be saved by simply moving registers into offsets
+ * from the base of the context area. Finally some FP units provide
+ * a "dump context" instruction which could fill in from high to low
+ * or low to high based on the whim of the CPU designers.
+ */
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
+
+/*
+ * This routine initializes the FP context area passed to it to.
+ * There are a few standard ways in which to initialize the
+ * floating point context. The code included for this macro assumes
+ * that this is a CPU in which a "initial" FP context was saved into
+ * _CPU_Null_fp_context and it simply copies it to the destination
+ * context passed to it.
+ *
+ * Other models include (1) not doing anything, and (2) putting
+ * a "null FP status word" in the correct place in the FP context.
+ */
+
+#define _CPU_Context_Initialize_fp( _destination ) \
+ { \
+ *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
+ }
+
+/* end of Context handler macros */
+
+/* Fatal Error manager macros */
+
+/*
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ */
+
+#define _CPU_Fatal_halt( _error ) \
+ do { \
+ int _level; \
+ _CPU_ISR_Disable( _level ); \
+ asm volatile ("mov r0, %0\n" \
+ : "=r" (_error) \
+ : "0" (_error) \
+ : "r0" ); \
+ while(1) ; \
+ } while(0);
+
+
+/* end of Fatal Error manager macros */
+
+/* Bitfield handler macros */
+/*
+ * If we had a particularly fast function for finding the first
+ * bit set in a word, it would go here. Since we don't (*), we'll
+ * just use the universal macros.
+ *
+ * (*) On ARM V5 and later, there's a CLZ function which could be
+ * used to implement much quicker than the default macro.
+ */
+#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
+
+/* functions */
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+typedef enum {
+ ARM_EXCEPTION_RESET = 0,
+ ARM_EXCEPTION_UNDEF = 1,
+ ARM_EXCEPTION_SWI = 2,
+ ARM_EXCEPTION_PREF_ABORT = 3,
+ ARM_EXCEPTION_DATA_ABORT = 4,
+ ARM_EXCEPTION_RESERVED = 5,
+ ARM_EXCEPTION_IRQ = 6,
+ ARM_EXCEPTION_FIQ = 7,
+ MAX_EXCEPTIONS = 8
+} Arm_symbolic_exception_name;
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_Install_interrupt_stack
+ *
+ * This routine installs the hardware interrupt stack pointer.
+ *
+ * NOTE: It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK
+ * is TRUE.
+ */
+
+void _CPU_Install_interrupt_stack( void );
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally 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.
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+#if (ARM_HAS_FPU == 1)
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+#endif /* (ARM_HAS_FPU == 1) */
+
+/* The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * This version will work on any processor, but if there is a better
+ * way for your CPU PLEASE use it. The most common way to do this is to:
+ *
+ * swap least significant two bytes with 16-bit rotate
+ * swap upper and lower 16-bits
+ * swap most significant two bytes with 16-bit rotate
+ *
+ * Some CPUs have special instructions which swap a 32-bit quantity in
+ * a single instruction (e.g. i486). It is probably best to avoid
+ * an "endian swapping control bit" in the CPU. One good reason is
+ * that interrupts would probably have to be disabled to ensure that
+ * an interrupt does not try to access the same "chunk" with the wrong
+ * endian. Another good reason is that on some CPUs, the endian bit
+ * endianness for ALL fetches -- both code and data -- so the code
+ * will be fetched incorrectly.
+ */
+
+static inline uint32_t CPU_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t tmp = value; /* make compiler warnings go away */
+ asm volatile ("EOR %1, %0, %0, ROR #16\n"
+ "BIC %1, %1, #0xff0000\n"
+ "MOV %0, %0, ROR #8\n"
+ "EOR %0, %0, %1, LSR #8\n"
+ : "=r" (value), "=r" (tmp)
+ : "0" (value), "1" (tmp));
+
+ return value;
+}
+
+static inline uint16_t CPU_swap_u16(uint16_t value)
+{
+ uint16_t lower;
+ uint16_t upper;
+
+ value = value & (uint16_t ) 0xffff;
+ lower = (value >> 8) ;
+ upper = (value << 8) ;
+
+ return (lower | upper);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/arm/rtems/score/cpu_asm.h b/cpukit/score/cpu/arm/rtems/score/cpu_asm.h
new file mode 100644
index 0000000000..59b567ca2c
--- /dev/null
+++ b/cpukit/score/cpu/arm/rtems/score/cpu_asm.h
@@ -0,0 +1,39 @@
+/**
+ * @file rtems/score/cpu_asm.h
+ */
+
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002 by Advent Networks, Inc.
+ * Jay Monkman <jmonkman@adventnetworks.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * This file is the include file for cpu_asm.S
+ *
+ *
+ */
+
+#ifndef _RTEMS_SCORE_CPU_ASM_H
+#define _RTEMS_SCORE_CPU_ASM_H
+
+
+/* Registers saved in context switch: */
+.set REG_CPSR, 0
+.set REG_R4, 4
+.set REG_R5, 8
+.set REG_R6, 12
+.set REG_R7, 16
+.set REG_R8, 20
+.set REG_R9, 24
+.set REG_R10, 28
+.set REG_R11, 32
+.set REG_SP, 36
+.set REG_LR, 40
+.set REG_PC, 44
+.set SIZE_REGS, REG_PC + 4
+
+#endif
diff --git a/cpukit/score/cpu/arm/rtems/score/types.h b/cpukit/score/cpu/arm/rtems/score/types.h
new file mode 100644
index 0000000000..8edfc13a10
--- /dev/null
+++ b/cpukit/score/cpu/arm/rtems/score/types.h
@@ -0,0 +1,54 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * $Id$
+ *
+ * This include file contains type definitions pertaining to the
+ * arm processor family.
+ *
+ * COPYRIGHT (c) 2000 Canon Research Centre France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+
+typedef signed long long signed64; /* 64 bit signed integer */
+
+typedef uint32_t boolean; /* Boolean value */
+typedef uint16_t Priority_Bit_map_control;
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void arm_cpu_isr;
+typedef void ( *arm_cpu_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/avr/.cvsignore b/cpukit/score/cpu/avr/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/avr/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/avr/ChangeLog b/cpukit/score/cpu/avr/ChangeLog
new file mode 100644
index 0000000000..e57a655e4e
--- /dev/null
+++ b/cpukit/score/cpu/avr/ChangeLog
@@ -0,0 +1,79 @@
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Part of a large patch to improve Doxygen output.
+ As a side-effect, grammar and spelling errors were corrected, spacing
+ errors were address, and some variable names were improved.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16, unsigned32.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h: Remove private version of CONCAT macros.
+ Include <rtems/concat.h> instead.
+
+2005-02-19 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Remove traces from NO_CPU.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/avr.h, rtems/score/cpu.h,
+ rtems/score/cpu_asm.h, rtems/score/types.h: New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: *_swap_u32( uint32_t ).
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove build-variant support.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * asm.h: Add doxygen preamble.
+
+2004-10-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/avr.h: Add doxygen preamble.
+ * rtems/score/cpu.h: Add doxygen preamble.
+ * rtems/score/cpu_asm.h: Add doxygen preamble.
+ * rtems/score/types.h: Add doxygen preamble.
+
+2004-11-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/types.h: s/no_cpu/avr/g.
+ Use POSIX types from rtems/stdint.h.
+
+2004-09-29 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: i960 obsoleted and all references removed.
+
+2004-09-23 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/types.h, rtems/score/cpu.h, rtems/score/cpu_asm.h,
+ rtems/score/avr.h, Makefile.am, asm.h, cpu.c, cpu_asm.c, README:
+ New.
+
diff --git a/cpukit/score/cpu/avr/Makefile.am b/cpukit/score/cpu/avr/Makefile.am
new file mode 100644
index 0000000000..69bd4636b9
--- /dev/null
+++ b/cpukit/score/cpu/avr/Makefile.am
@@ -0,0 +1,19 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/avr.h \
+ rtems/score/cpu_asm.h rtems/score/types.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c cpu_asm.c
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/avr/README b/cpukit/score/cpu/avr/README
new file mode 100644
index 0000000000..20ac7cc023
--- /dev/null
+++ b/cpukit/score/cpu/avr/README
@@ -0,0 +1,5 @@
+WARNING
+=======
+
+This is just a stub and not a complete and functional port.
+
diff --git a/cpukit/score/cpu/avr/cpu.c b/cpukit/score/cpu/avr/cpu.c
new file mode 100644
index 0000000000..2796c707ea
--- /dev/null
+++ b/cpukit/score/cpu/avr/cpu.c
@@ -0,0 +1,185 @@
+/*
+ * XXX CPU Dependent Source
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/wkspace.h>
+
+/* _CPU_Initialize
+ *
+ * This routine performs processor dependent initialization.
+ *
+ * INPUT PARAMETERS:
+ * cpu_table - CPU table to initialize
+ * thread_dispatch - address of disptaching routine
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch) /* ignored on this CPU */
+)
+{
+ /*
+ * The thread_dispatch argument is the address of the entry point
+ * for the routine called at the end of an ISR once it has been
+ * decided a context switch is necessary. On some compilation
+ * systems it is difficult to call a high-level language routine
+ * from assembly. This allows us to trick these systems.
+ *
+ * If you encounter this problem save the entry point in a CPU
+ * dependent variable.
+ */
+
+ _CPU_Thread_dispatch_pointer = thread_dispatch;
+
+ /*
+ * If there is not an easy way to initialize the FP context
+ * during Context_Initialize, then it is usually easier to
+ * save an "uninitialized" FP context here and copy it to
+ * the task's during Context_Initialize.
+ */
+
+ /* FP context initialization support goes here */
+
+ _CPU_Table = *cpu_table;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Get_level
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ /*
+ * This routine returns the current interrupt level.
+ */
+
+ return 0;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_install_raw_handler
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ /*
+ * This is where we install the interrupt handler into the "raw" interrupt
+ * table used by the CPU to dispatch interrupt handlers.
+ */
+}
+
+/*PAGE
+ *
+ * _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
+ *
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ *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.
+ */
+
+ _CPU_ISR_install_raw_handler( vector, new_handler, old_handler );
+
+ /*
+ * 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;
+}
+
+/*PAGE
+ *
+ * _CPU_Install_interrupt_stack
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Install_interrupt_stack( void )
+{
+}
+
+/*PAGE
+ *
+ * _CPU_Thread_Idle_body
+ *
+ * NOTES:
+ *
+ * 1. This is the same as the regular CPU independent algorithm.
+ *
+ * 2. If you implement this using a "halt", "idle", or "shutdown"
+ * instruction, then don't forget to put it in an infinite loop.
+ *
+ * 3. Be warned. Some processors with onboard DMA have been known
+ * to stop the DMA if the CPU were put in IDLE mode. This might
+ * also be a problem with other on-chip peripherals. So use this
+ * hook with caution.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Thread_Idle_body( void )
+{
+
+ for( ; ; )
+ /* insert your "halt" instruction here */ ;
+}
diff --git a/cpukit/score/cpu/avr/cpu_asm.c b/cpukit/score/cpu/avr/cpu_asm.c
new file mode 100644
index 0000000000..2ca67a07ad
--- /dev/null
+++ b/cpukit/score/cpu/avr/cpu_asm.c
@@ -0,0 +1,182 @@
+/* cpu_asm.c ===> cpu_asm.S or cpu_asm.s
+ *
+ * This file contains the basic algorithms for all assembly code used
+ * in an specific CPU port of RTEMS. These algorithms must be implemented
+ * in assembly language
+ *
+ * NOTE: This is supposed to be a .S or .s file NOT a C file.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+/*
+ * This is supposed to be an assembly file. This means that system.h
+ * and cpu.h should not be included in a "real" cpu_asm file. An
+ * implementation in assembly should include "cpu_asm.h>
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/cpu.h>
+/* #include "cpu_asm.h> */
+
+/*
+ * _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.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+)
+{
+}
+
+/*
+ * _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.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+)
+{
+}
+
+/* _CPU_Context_switch
+ *
+ * This routine performs a normal non-FP context switch.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+)
+{
+}
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally 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.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+)
+{
+}
+
+/* void __ISR_Handler()
+ *
+ * This routine provides the RTEMS interrupt management.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _ISR_Handler()
+{
+ /*
+ * This discussion ignores a lot of the ugly details in a real
+ * implementation such as saving enough registers/state to be
+ * able to do something real. Keep in mind that the goal is
+ * to invoke a user's ISR handler which is written in C and
+ * uses a certain set of registers.
+ *
+ * Also note that the exact order is to a large extent flexible.
+ * Hardware will dictate a sequence for a certain subset of
+ * _ISR_Handler while requirements for setting
+ */
+
+ /*
+ * At entry to "common" _ISR_Handler, the vector number must be
+ * available. On some CPUs the hardware puts either the vector
+ * number or the offset into the vector table for this ISR in a
+ * known place. If the hardware does not give us this information,
+ * then the assembly portion of RTEMS for this port will contain
+ * a set of distinct interrupt entry points which somehow place
+ * the vector number in a known place (which is safe if another
+ * interrupt nests this one) and branches to _ISR_Handler.
+ *
+ * save some or all context on stack
+ * may need to save some special interrupt information for exit
+ *
+ * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
+ * if ( _ISR_Nest_level == 0 )
+ * switch to software interrupt stack
+ * #endif
+ *
+ * _ISR_Nest_level++;
+ *
+ * _Thread_Dispatch_disable_level++;
+ *
+ * (*_ISR_Vector_table[ vector ])( vector );
+ *
+ * _Thread_Dispatch_disable_level--;
+ *
+ * --_ISR_Nest_level;
+ *
+ * if ( _ISR_Nest_level )
+ * goto the label "exit interrupt (simple case)"
+ *
+ * if ( _Thread_Dispatch_disable_level )
+ * _ISR_Signals_to_thread_executing = FALSE;
+ * goto the label "exit interrupt (simple case)"
+ *
+ * if ( _Context_Switch_necessary || _ISR_Signals_to_thread_executing ) {
+ * _ISR_Signals_to_thread_executing = FALSE;
+ * call _Thread_Dispatch() or prepare to return to _ISR_Dispatch
+ * prepare to get out of interrupt
+ * return from interrupt (maybe to _ISR_Dispatch)
+ *
+ * LABEL "exit interrupt (simple case):
+ * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
+ * if outermost interrupt
+ * restore stack
+ * #endif
+ * prepare to get out of interrupt
+ * return from interrupt
+ */
+}
diff --git a/cpukit/score/cpu/avr/preinstall.am b/cpukit/score/cpu/avr/preinstall.am
new file mode 100644
index 0000000000..022d2f5a85
--- /dev/null
+++ b/cpukit/score/cpu/avr/preinstall.am
@@ -0,0 +1,45 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/avr.h: rtems/score/avr.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/avr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/avr.h
+
+$(PROJECT_INCLUDE)/rtems/score/cpu_asm.h: rtems/score/cpu_asm.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
diff --git a/cpukit/score/cpu/avr/rtems/asm.h b/cpukit/score/cpu/avr/rtems/asm.h
new file mode 100644
index 0000000000..b2c25cc0ac
--- /dev/null
+++ b/cpukit/score/cpu/avr/rtems/asm.h
@@ -0,0 +1,97 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ */
+
+/*
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ * COPYRIGHT (c) 1994-1997.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/avr.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/*
+ * define macros for all of the registers on this CPU
+ *
+ * EXAMPLE: #define d0 REG (d0)
+ */
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA
+#define END_DATA
+#define BEGIN_BSS
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .globl SYM (sym)
+#define EXTERN(sym) .globl SYM (sym)
+
+#endif
diff --git a/cpukit/score/cpu/avr/rtems/score/avr.h b/cpukit/score/cpu/avr/rtems/score/avr.h
new file mode 100644
index 0000000000..2ccce31b0d
--- /dev/null
+++ b/cpukit/score/cpu/avr/rtems/score/avr.h
@@ -0,0 +1,90 @@
+/**
+ * @file rtems/score/avr.h
+ */
+
+/*
+ * This file sets up basic CPU dependency settings based on
+ * compiler settings. For example, it can determine if
+ * floating point is available. This particular implementation
+ * is specified to the avr port.
+ *
+ * Copyright 2004, Ralf Corsepius, Ulm, Germany.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef _RTEMS_SCORE_AVR_H
+#define _RTEMS_SCORE_AVR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the NO CPU family.
+ * It does this by setting variables to indicate which
+ * implementation dependent features are present in a particular
+ * member of the family.
+ *
+ * This is a good place to list all the known CPU models
+ * that this port supports and which RTEMS CPU model they correspond
+ * to.
+ */
+
+/*
+ * Figure out all CPU Model Feature Flags based upon compiler
+ * predefines.
+ */
+#if defined(__AVR__)
+
+#if defined(__AVR_ARCH__)
+#if __AVR_ARCH__ == 1
+#define CPU_MODEL_NAME "avr1"
+#define AVR_HAS_FPU 1
+
+#elif __AVR_ARCH__ == 2
+#define CPU_MODEL_NAME "avr2"
+#define AVR_HAS_FPU 1
+
+#elif __AVR_ARCH__ == 3
+#define CPU_MODEL_NAME "avr3"
+#define AVR_HAS_FPU 1
+
+#elif __AVR_ARCH__ == 4
+#define CPU_MODEL_NAME "avr4"
+#define AVR_HAS_FPU 1
+
+#elif __AVR_ARCH__ == 5
+#define CPU_MODEL_NAME "avr5"
+#define AVR_HAS_FPU 1
+
+#else
+#error "Unsupported __AVR_ARCH__"
+#endif
+#else
+#error "__AVR_ARCH__ undefined"
+#endif
+
+#else
+
+#error "Unsupported CPU Model"
+
+#endif
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "avr"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_AVR_H */
diff --git a/cpukit/score/cpu/avr/rtems/score/cpu.h b/cpukit/score/cpu/avr/rtems/score/cpu.h
new file mode 100644
index 0000000000..c614ea8342
--- /dev/null
+++ b/cpukit/score/cpu/avr/rtems/score/cpu.h
@@ -0,0 +1,1141 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * This include file contains information pertaining to the AVR
+ * processor.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/avr.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+
+/* conditional compilation parameters */
+
+/*
+ * Should the calls to _Thread_Enable_dispatch be inlined?
+ *
+ * If TRUE, then they are inlined.
+ * If FALSE, then a subroutine call is made.
+ *
+ * Basically this is an example of the classic trade-off of size
+ * versus speed. Inlining the call (TRUE) typically increases the
+ * size of RTEMS while speeding up the enabling of dispatching.
+ * [NOTE: In general, the _Thread_Dispatch_disable_level will
+ * only be 0 or 1 unless you are in an interrupt handler and that
+ * interrupt handler invokes the executive.] When not inlined
+ * something calls _Thread_Enable_dispatch which in turns calls
+ * _Thread_Dispatch. If the enable dispatch is inlined, then
+ * one subroutine call is avoided entirely.]
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_INLINE_ENABLE_DISPATCH FALSE
+
+/*
+ * Should the body of the search loops in _Thread_queue_Enqueue_priority
+ * be unrolled one time? In unrolled each iteration of the loop examines
+ * two "nodes" on the chain being searched. Otherwise, only one node
+ * is examined per iteration.
+ *
+ * If TRUE, then the loops are unrolled.
+ * If FALSE, then the loops are not unrolled.
+ *
+ * The primary factor in making this decision is the cost of disabling
+ * and enabling interrupts (_ISR_Flash) versus the cost of rest of the
+ * body of the loop. On some CPUs, the flash is more expensive than
+ * one iteration of the loop body. In this case, it might be desirable
+ * to unroll the loop. It is important to note that on some CPUs, this
+ * code is the longest interrupt disable period in RTEMS. So it is
+ * necessary to strike a balance when setting this parameter.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
+
+/*
+ * Does RTEMS manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in _ISR_Handler_initialization.
+ * If FALSE, nothing is done.
+ *
+ * If the CPU supports a dedicated interrupt stack in hardware,
+ * then it is generally the responsibility of the BSP to allocate it
+ * and set it up.
+ *
+ * If the CPU does not support a dedicated interrupt stack, then
+ * the porter has two options: (1) execute interrupts on the
+ * stack of the interrupted task, and (2) have RTEMS manage a dedicated
+ * interrupt stack.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
+
+/*
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * If TRUE, then it must be installed during initialization.
+ * If FALSE, then no installation is performed.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
+
+/*
+ * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * If TRUE, then the memory is allocated during initialization.
+ * If FALSE, then the memory is allocated during initialization.
+ *
+ * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
+
+/*
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_ISR_PASSES_FRAME_POINTER 0
+
+/*
+ * Does the CPU have hardware floating point?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
+ *
+ * If there is a FP coprocessor such as the i387 or mc68881, then
+ * the answer is TRUE.
+ *
+ * The macro name "AVR_HAS_FPU" should be made CPU specific.
+ * It indicates whether or not this CPU model has FP support. For
+ * example, it would be possible to have an i386_nofp CPU model
+ * which set this to false to indicate that you have an i386 without
+ * an i387 and wish to leave floating point support out of RTEMS.
+ *
+ * The CPU_SOFTWARE_FP is used to indicate whether or not there
+ * is software implemented floating point that must be context
+ * switched. The determination of whether or not this applies
+ * is very tool specific and the state saved/restored is also
+ * compiler specific.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#if ( AVR_HAS_FPU == 1 )
+#define CPU_HARDWARE_FP TRUE
+#else
+#define CPU_HARDWARE_FP FALSE
+#endif
+#define CPU_SOFTWARE_FP FALSE
+
+/*
+ * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
+ *
+ * So far, the only CPUs in which this option has been used are the
+ * HP PA-RISC and PowerPC. On the PA-RISC, The HP C compiler and
+ * gcc both implicitly used the floating point registers to perform
+ * integer multiplies. Similarly, the PowerPC port of gcc has been
+ * seen to allocate floating point local variables and touch the FPU
+ * even when the flow through a subroutine (like vfprintf()) might
+ * not use floating point formats.
+ *
+ * If a function which you would not think utilize the FP unit DOES,
+ * then one can not easily predict which tasks will use the FP hardware.
+ * In this case, this option should be TRUE.
+ *
+ * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_ALL_TASKS_ARE_FP TRUE
+
+/*
+ * Should the IDLE task have a floating point context?
+ *
+ * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * If FALSE, then the IDLE task does not have a floating point context.
+ *
+ * Setting this to TRUE negatively impacts the time required to preempt
+ * the IDLE task from an interrupt because the floating point context
+ * must be saved as part of the preemption.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+/*
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ *
+ * If the floating point context does NOT have to be saved as part of
+ * interrupt dispatching, then it should be safe to set this to TRUE.
+ *
+ * Setting this flag to TRUE results in using a different algorithm
+ * for deciding when to save and restore the floating point context.
+ * The deferred FP switch algorithm minimizes the number of times
+ * the FP context is saved and restored. The FP context is not saved
+ * until a context switch is made to another, different FP task.
+ * Thus in a system with only one FP task, the FP context will never
+ * be saved or restored.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+/*
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine _CPU_Thread_Idle_body
+ * must be provided and is the default IDLE thread body instead of
+ * _CPU_Thread_Idle_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ *
+ * This is intended to allow for supporting processors which have
+ * a low power or idle mode. When the IDLE thread is executed, then
+ * the CPU can be powered down.
+ *
+ * The order of precedence for selecting the IDLE thread body is:
+ *
+ * 1. BSP provided
+ * 2. CPU dependent (if provided)
+ * 3. generic (if no BSP and no CPU dependent)
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE
+
+/*
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * If TRUE, then the grows upward.
+ * If FALSE, then the grows toward smaller addresses.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_STACK_GROWS_UP TRUE
+
+/*
+ * The following is the variable attribute used to force alignment
+ * of critical RTEMS structures. On some processors it may make
+ * sense to have these aligned on tighter boundaries than
+ * the minimum requirements of the compiler in order to have as
+ * much of the critical data area as possible in a cache line.
+ *
+ * The placement of this macro in the declaration of the variables
+ * is based on the syntactically requirements of the GNU C
+ * "__attribute__" extension. For example with GNU C, use
+ * the following to force a structures to a 32 byte boundary.
+ *
+ * __attribute__ ((aligned (32)))
+ *
+ * NOTE: Currently only the Priority Bit Map table uses this feature.
+ * To benefit from using this, the data must be heavily
+ * used so it will stay in the cache and used frequently enough
+ * in the executive to justify turning this on.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_STRUCTURE_ALIGNMENT
+
+/*
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+#define CPU_BIG_ENDIAN TRUE
+#define CPU_LITTLE_ENDIAN FALSE
+
+/*
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_MODES_INTERRUPT_MASK 0x00000001
+
+/*
+ * Processor defined structures required for cpukit/score.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/* may need to put some structures here. */
+
+/*
+ * Contexts
+ *
+ * Generally there are 2 types of context to save.
+ * 1. Interrupt registers to save
+ * 2. Task level registers to save
+ *
+ * This means we have the following 3 context items:
+ * 1. task level context stuff:: Context_Control
+ * 2. floating point task stuff:: Context_Control_fp
+ * 3. special interrupt level context :: Context_Control_interrupt
+ *
+ * On some processors, it is cost-effective to save only the callee
+ * preserved registers during a task context switch. This means
+ * that the ISR code needs to save those registers which do not
+ * persist across function calls. It is not mandatory to make this
+ * distinctions between the caller/callee saves registers for the
+ * purpose of minimizing context saved during task switch and on interrupts.
+ * If the cost of saving extra registers is minimal, simplicity is the
+ * choice. Save the same context on interrupt entry as for tasks in
+ * this case.
+ *
+ * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
+ * care should be used in designing the context area.
+ *
+ * On some CPUs with hardware floating point support, the Context_Control_fp
+ * structure will not be used or it simply consist of an array of a
+ * fixed number of bytes. This is done when the floating point context
+ * is dumped by a "FP save context" type instruction and the format
+ * is not really defined by the CPU. In this case, there is no need
+ * to figure out the exact format -- only the size. Of course, although
+ * this is enough information for RTEMS, it is probably not enough for
+ * a debugger such as gdb. But that is another problem.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+typedef struct {
+ uint32_t some_integer_register;
+ uint32_t some_system_register;
+} Context_Control;
+
+typedef struct {
+ double some_float_register;
+} Context_Control_fp;
+
+typedef struct {
+ uint32_t special_interrupt_register;
+} CPU_Interrupt_frame;
+
+
+/*
+ * The following table contains the information required to configure
+ * the XXX processor specific parameters.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+ /* end of fields required on all CPUs */
+
+} rtems_cpu_table;
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/*
+ * Macros to access AVR specific additions to the CPU Table
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/* There are no CPU specific additions to the CPU Table for this port. */
+
+/*
+ * This variable is optional. It is used on CPUs on which it is difficult
+ * to generate an "uninitialized" FP context. It is filled in by
+ * _CPU_Initialize and copied into the task's FP context area during
+ * _CPU_Context_Initialize.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
+
+/*
+ * On some CPUs, RTEMS supports a software managed interrupt stack.
+ * This stack is allocated by the Interrupt Manager and the switch
+ * is performed in _ISR_Handler. These variables contain pointers
+ * to the lowest and highest addresses in the chunk of memory allocated
+ * for the interrupt stack. Since it is unknown whether the stack
+ * grows up or down (in general), this give the CPU dependent
+ * code the option of picking the version it wants to use.
+ *
+ * NOTE: These two variables are required if the macro
+ * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+/*
+ * With some compilation systems, it is difficult if not impossible to
+ * call a high-level language routine from assembly language. This
+ * is especially true of commercial Ada compilers and name mangling
+ * C++ ones. This variable can be optionally defined by the CPU porter
+ * and contains the address of the routine _Thread_Dispatch. This
+ * can make it easier to invoke that routine at the end of the interrupt
+ * sequence (if a dispatch is necessary).
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
+
+/*
+ * Nothing prevents the porter from declaring more CPU specific variables.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/* XXX: if needed, put more variables here */
+
+/*
+ * The size of the floating point context area. On some CPUs this
+ * will not be a "sizeof" because the format of the floating point
+ * area is not defined -- only the size is. This is usually on
+ * CPUs with a "floating point save context" instruction.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/*
+ * Amount of extra stack (above minimum stack size) required by
+ * MPCI receive server thread. Remember that in a multiprocessor
+ * system this thread must exist and be able to process all directives.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+/*
+ * This defines the number of entries in the ISR_Vector_table managed
+ * by RTEMS.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 32
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
+
+/*
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level.
+ */
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/*
+ * Should be large enough to run all RTEMS tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_STACK_MINIMUM_SIZE (1024*4)
+
+/*
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_ALIGNMENT 8
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
+ * then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2 although it should be
+ * a multiple of 2 greater than or equal to 2. The requirement
+ * to be a multiple of 2 is because the heap uses the least
+ * significant field of the front and back flags to indicate
+ * that a block is in use or free. So you do not want any odd
+ * length blocks really putting length data in that bit.
+ *
+ * On byte oriented architectures, CPU_HEAP_ALIGNMENT normally will
+ * have to be greater or equal to than CPU_ALIGNMENT to ensure that
+ * elements allocated from the heap meet all restrictions.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
+ * enough for the partition, then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * stack. This alignment requirement may be stricter than that for the
+ * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
+ * is strict enough for the stack, then this should be set to 0.
+ *
+ * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_STACK_ALIGNMENT 0
+
+/*
+ * ISR handler macros
+ */
+
+/*
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define _CPU_Initialize_vectors()
+
+/*
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in _level.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define _CPU_ISR_Disable( _isr_cookie ) \
+ { \
+ (_isr_cookie) = 0; /* do something to prevent warnings */ \
+ }
+
+/*
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * _level is not modified.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define _CPU_ISR_Enable( _isr_cookie ) \
+ { \
+ }
+
+/*
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define _CPU_ISR_Flash( _isr_cookie ) \
+ { \
+ }
+
+/*
+ * Map interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a generic fashion are undefined. Someday,
+ * it would be nice if these were "mapped" by the application
+ * via a callout. For example, m68k has 8 levels 0 - 7, levels
+ * 8 - 255 would be available for bsp/application specific meaning.
+ * This could be used to manage a programmable interrupt controller
+ * via the rtems_task_mode directive.
+ *
+ * The get routine usually must be implemented as a subroutine.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define _CPU_ISR_Set_level( new_level ) \
+ { \
+ }
+
+uint32_t _CPU_ISR_Get_level( void );
+
+/* end of ISR handler macros */
+
+/* Context handler macros */
+
+/*
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * This routine generally does not set any unnecessary register
+ * in the context. The state of the "general data" registers is
+ * undefined at task start time.
+ *
+ * NOTE: This is_fp parameter is TRUE if the thread is to be a floating
+ * point thread. This is typically only used on CPUs where the
+ * FPU may be easily disabled by software such as on the SPARC
+ * where the PSR contains an enable FPU bit.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
+ _isr, _entry_point, _is_fp ) \
+ { \
+ }
+
+/*
+ * This routine is responsible for somehow restarting the currently
+ * executing task. If you are lucky, then all that is necessary
+ * is restoring the context. Otherwise, there will need to be
+ * a special assembly routine which does something special in this
+ * case. Context_Restore should work most of the time. It will
+ * not work if restarting self conflicts with the stack frame
+ * assumptions of restoring a context.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+/*
+ * The purpose of this macro is to allow the initial pointer into
+ * a floating point context area (used to save the floating point
+ * context) to be at an arbitrary place in the floating point
+ * context area.
+ *
+ * This is necessary because some FP units are designed to have
+ * their context saved as a stack which grows into lower addresses.
+ * Other FP units can be saved by simply moving registers into offsets
+ * from the base of the context area. Finally some FP units provide
+ * a "dump context" instruction which could fill in from high to low
+ * or low to high based on the whim of the CPU designers.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
+
+/*
+ * This routine initializes the FP context area passed to it to.
+ * There are a few standard ways in which to initialize the
+ * floating point context. The code included for this macro assumes
+ * that this is a CPU in which a "initial" FP context was saved into
+ * _CPU_Null_fp_context and it simply copies it to the destination
+ * context passed to it.
+ *
+ * Other models include (1) not doing anything, and (2) putting
+ * a "null FP status word" in the correct place in the FP context.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define _CPU_Context_Initialize_fp( _destination ) \
+ { \
+ *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
+ }
+
+/* end of Context handler macros */
+
+/* Fatal Error manager macros */
+
+/*
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define _CPU_Fatal_halt( _error ) \
+ { \
+ }
+
+/* end of Fatal Error manager macros */
+
+/* Bitfield handler macros */
+
+/*
+ * This routine sets _output to the bit number of the first bit
+ * set in _value. _value is of CPU dependent type Priority_Bit_map_control.
+ * This type may be either 16 or 32 bits wide although only the 16
+ * least significant bits will be used.
+ *
+ * There are a number of variables in using a "find first bit" type
+ * instruction.
+ *
+ * (1) What happens when run on a value of zero?
+ * (2) Bits may be numbered from MSB to LSB or vice-versa.
+ * (3) The numbering may be zero or one based.
+ * (4) The "find first bit" instruction may search from MSB or LSB.
+ *
+ * RTEMS guarantees that (1) will never happen so it is not a concern.
+ * (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
+ * _CPU_Priority_bits_index(). These three form a set of routines
+ * which must logically operate together. Bits in the _value are
+ * set and cleared based on masks built by _CPU_Priority_mask().
+ * The basic major and minor values calculated by _Priority_Major()
+ * and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
+ * to properly range between the values returned by the "find first bit"
+ * instruction. This makes it possible for _Priority_Get_highest() to
+ * calculate the major and directly index into the minor table.
+ * This mapping is necessary to ensure that 0 (a high priority major/minor)
+ * is the first bit found.
+ *
+ * This entire "find first bit" and mapping process depends heavily
+ * on the manner in which a priority is broken into a major and minor
+ * components with the major being the 4 MSB of a priority and minor
+ * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
+ * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next
+ * to the lowest priority.
+ *
+ * If your CPU does not have a "find first bit" instruction, then
+ * there are ways to make do without it. Here are a handful of ways
+ * to implement this in software:
+ *
+ * - a series of 16 bit test instructions
+ * - a "binary search using if's"
+ * - _number = 0
+ * if _value > 0x00ff
+ * _value >>=8
+ * _number = 8;
+ *
+ * if _value > 0x0000f
+ * _value >=8
+ * _number += 4
+ *
+ * _number += bit_set_table[ _value ]
+ *
+ * where bit_set_table[ 16 ] has values which indicate the first
+ * bit set
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ (_output) = 0; /* do something to prevent warnings */ \
+ }
+
+#endif
+
+/* end of Bitfield handler macros */
+
+/*
+ * This routine builds the mask which corresponds to the bit fields
+ * as searched by _CPU_Bitfield_Find_first_bit(). See the discussion
+ * for that routine.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_Mask( _bit_number ) \
+ ( 1 << (_bit_number) )
+
+#endif
+
+/*
+ * This routine translates the bit numbers returned by
+ * _CPU_Bitfield_Find_first_bit() into something suitable for use as
+ * a major or minor component of a priority. See the discussion
+ * for that routine.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_bits_index( _priority ) \
+ (_priority)
+
+#endif
+
+/* end of Priority handler macros */
+
+/* functions */
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/*
+ * _CPU_ISR_install_raw_handler
+ *
+ * This routine installs a "raw" interrupt handler directly into the
+ * processor's vector table.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_Install_interrupt_stack
+ *
+ * This routine installs the hardware interrupt stack pointer.
+ *
+ * NOTE: It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK
+ * is TRUE.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Install_interrupt_stack( void );
+
+/*
+ * _CPU_Thread_Idle_body
+ *
+ * This routine is the CPU dependent IDLE thread body.
+ *
+ * NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
+ * is TRUE.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Thread_Idle_body( void );
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally 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.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+/* The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * This version will work on any processor, but if there is a better
+ * way for your CPU PLEASE use it. The most common way to do this is to:
+ *
+ * swap least significant two bytes with 16-bit rotate
+ * swap upper and lower 16-bits
+ * swap most significant two bytes with 16-bit rotate
+ *
+ * Some CPUs have special instructions which swap a 32-bit quantity in
+ * a single instruction (e.g. i486). It is probably best to avoid
+ * an "endian swapping control bit" in the CPU. One good reason is
+ * that interrupts would probably have to be disabled to ensure that
+ * an interrupt does not try to access the same "chunk" with the wrong
+ * endian. Another good reason is that on some CPUs, the endian bit
+ * endianness for ALL fetches -- both code and data -- so the code
+ * will be fetched incorrectly.
+ *
+ * AVR Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+static inline uint32_t CPU_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t byte1, byte2, byte3, byte4, swapped;
+
+ byte4 = (value >> 24) & 0xff;
+ byte3 = (value >> 16) & 0xff;
+ byte2 = (value >> 8) & 0xff;
+ byte1 = value & 0xff;
+
+ swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
+ return( swapped );
+}
+
+#define CPU_swap_u16( value ) \
+ (((value&0xff) << 8) | ((value >> 8)&0xff))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/avr/rtems/score/cpu_asm.h b/cpukit/score/cpu/avr/rtems/score/cpu_asm.h
new file mode 100644
index 0000000000..a509b36ae6
--- /dev/null
+++ b/cpukit/score/cpu/avr/rtems/score/cpu_asm.h
@@ -0,0 +1,72 @@
+/**
+ * @file rtems/score/cpu_asm.h
+ */
+
+/*
+ * Very loose template for an include file for the cpu_asm.? file
+ * if it is implemented as a ".S" file (preprocessed by cpp) instead
+ * of a ".s" file (preprocessed by gm4 or gasp).
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef _RTEMS_SCORE_CPU_ASM_H
+#define _RTEMS_SCORE_CPU_ASM_H
+
+/* pull in the generated offsets */
+
+#include <rtems/score/offsets.h>
+
+/*
+ * Hardware General Registers
+ */
+
+/* put something here */
+
+/*
+ * Hardware Floating Point Registers
+ */
+
+/* put something here */
+
+/*
+ * Hardware Control Registers
+ */
+
+/* put something here */
+
+/*
+ * Calling Convention
+ */
+
+/* put something here */
+
+/*
+ * Temporary registers
+ */
+
+/* put something here */
+
+/*
+ * Floating Point Registers - SW Conventions
+ */
+
+/* put something here */
+
+/*
+ * Temporary floating point registers
+ */
+
+/* put something here */
+
+#endif
+
+/* end of file */
diff --git a/cpukit/score/cpu/avr/rtems/score/types.h b/cpukit/score/cpu/avr/rtems/score/types.h
new file mode 100644
index 0000000000..b5c59a065a
--- /dev/null
+++ b/cpukit/score/cpu/avr/rtems/score/types.h
@@ -0,0 +1,54 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains type definitions pertaining to the Intel
+ * avr processor family.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef uint64_t unsigned64; /* unsigned 64-bit integer */
+
+typedef uint16_t Priority_Bit_map_control;
+
+typedef int64_t signed64; /* 64 bit signed integer */
+
+typedef uint32_t boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void avr_isr;
+typedef void ( *avr_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/c4x/.cvsignore b/cpukit/score/cpu/c4x/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/c4x/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/c4x/ChangeLog b/cpukit/score/cpu/c4x/ChangeLog
new file mode 100644
index 0000000000..9d93922440
--- /dev/null
+++ b/cpukit/score/cpu/c4x/ChangeLog
@@ -0,0 +1,343 @@
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Part of a large patch to improve Doxygen output.
+ As a side-effect, grammar and spelling errors were corrected, spacing
+ errors were address, and some variable names were improved.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16, unsigned32.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h: Remove private version of CONCAT macros.
+ Include <rtems/concat.h> instead.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2005-02-02 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR rtems/752
+ * rtems/tic4x/c4xio.h: New (relocated from .).
+ New header guard.
+ * c4xio.h: Remove.
+ * Makefile.am: Reflect changes above.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/c4x.h, rtems/score/cpu.h,
+ rtems/score/cpu_asm.h, rtems/score/types.h: New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: *_swap_u32( uint32_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: #include <rtems/stdint.h>.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove build-variant support.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Use __rtems_score_types_h as preprocessor
+ guard.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * asm.h: Add doxygen preamble.
+
+2004-10-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/c4x.h: Add doxygen preamble.
+ * rtems/score/cpu.h: Add doxygen preamble.
+ * rtems/score/cpu_asm.h: Add doxygen preamble.
+ * rtems/score/types.h: Add doxygen preamble.
+
+2004-09-29 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: i960 obsoleted and all references removed.
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Remove (Merged into $(top_srcdir)/configure.ac).
+ * Makefile.am: Don't include multilib.am.
+ Reflect merging configure.ac into $(top_srcdir)/configure.ac.
+
+2004-04-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Install c4xio.h to $(includedir)/rtems/c4x.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Install asm.h to $(includedir)/rtems.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu_asm.S: Include <rtems/asm.h> instead of <asm.h>.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * c4xio.h, cpu.c, irq.c, rtems/score/cpu.h: Convert to using c99
+ fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: RTEMS_TOP([../../../..]).
+
+2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Move RTEMS_TOP one subdir down.
+
+2004-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add PREINSTALL_DIRS.
+
+2004-01-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Re-add dirstamps to PREINSTALL_FILES.
+ Add PREINSTALL_FILES to CLEANFILES.
+
+2004-01-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Requires automake >= 1.8.1.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, again.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Convert to using automake compilation rules.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use mkdir_p. Remove dirs from PREINSTALL_FILES.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require automake >= 1.8, autoconf >= 2.59.
+
+2003-12-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Remove TMPINSTALL_FILES.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Don't use gmake rules for preinstallation.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CANONICAL_HOST.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CPU.
+
+2003-09-26 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Obsoleting HP PA-RISC port and removing all
+ references.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, cpu_asm.S, irq.c, rtems/score/c4x.h, rtems/score/cpu.h,
+ rtems/score/cpu_asm.h, rtems/score/types.h: URL for license changed.
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+
+2003-02-11 Joel Sherrill <joel@OARcorp.com>
+
+ * irq.c: Rework logic that decides when to call
+ _Thread_Dispatch. Analysis by Sergei Organov <osv@javad.ru>
+ determined that _ISR_Signals_to_thread_executing was not being
+ honored and/or cleared properly.
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require autoconf-2.57 + automake-1.7.2.
+ * Makefile.am: Eliminate C_O_FILES, S_O_FILES, libscorecpu_a_OBJECTS.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix package name.
+
+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-07-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use .$(OBJEXT) instead of .o.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use . instead of .o.
+
+2002-07-05 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, irq.c, rtems/score/cpu.h: Filled in something that was
+ marked XXX.
+
+2002-07-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: RTEMS_TOP(../../../..).
+
+2002-07-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems.c: Remove.
+ * Makefile.am: Reflect changes above.
+
+2002-07-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_PROJECT_ROOT.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add RTEMS_PROG_CCAS
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AC_CONFIG_AUX_DIR(../../../..).
+ Add AC_PROG_RANLIB.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/../../../automake/*.am.
+ Use ../../../aclocal.
+
+2001-04-03 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
+ * rtems/score/c4xtypes.h: Removed.
+ * rtems/score/types.h: New file via CVS magic.
+ * Makefile.am, 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.
+
+2002-01-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/Makefile.am: Removed.
+ * rtems/score/Makefile.am: Removed.
+ * configure.ac: Reflect changes above.
+ * Makefile.am: Reflect changes above.
+
+2002-02-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * asm.h: Remove #include <rtems/score/targopts.h>.
+ Add #include <rtems/score/cpuopts.h>.
+
+
+
+2002-02-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CUSTOM_BSP.
+
+2001-12-20 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use RTEMS_ENV_RTEMSCPU.
+
+2001-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add multilib support.
+
+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.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/Makefile.am: Use 'PREINSTALL_FILES ='.
+ * Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, rtems/score/Makefile.am:
+ Apply include_*HEADERS instead of H_FILES.
+
+2001-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Added _CPU_Initialize_vectors().
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
+ Switch to GNU canonicalization.
+
+2000-10-18 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/c4x.h: Modified to properly multilib. This required
+ using only macros predefined by gcc.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, formatting.
+ * rtems/Makefile.am: formatting.
+ * rtems/score/Makefile.am: formatting.
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: New file.
diff --git a/cpukit/score/cpu/c4x/Makefile.am b/cpukit/score/cpu/c4x/Makefile.am
new file mode 100644
index 0000000000..e8ccf6da39
--- /dev/null
+++ b/cpukit/score/cpu/c4x/Makefile.am
@@ -0,0 +1,22 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_tic4xdir = $(includedir)/rtems/tic4x
+include_rtems_tic4x_HEADERS = rtems/tic4x/c4xio.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/c4x.h \
+ rtems/score/types.h rtems/score/cpu_asm.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c irq.c cpu_asm.S
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/c4x/cpu.c b/cpukit/score/cpu/c4x/cpu.c
new file mode 100644
index 0000000000..b9655b642f
--- /dev/null
+++ b/cpukit/score/cpu/c4x/cpu.c
@@ -0,0 +1,199 @@
+/*
+ * C4x CPU Dependent Source
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/wkspace.h>
+
+
+/* _CPU_Initialize
+ *
+ * This routine performs processor dependent initialization.
+ *
+ * INPUT PARAMETERS:
+ * cpu_table - CPU table to initialize
+ * thread_dispatch - address of disptaching routine
+ *
+ * C4x Specific Information:
+ *
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch) /* ignored on this CPU */
+)
+{
+#if 0
+ /*
+ * The thread_dispatch argument is the address of the entry point
+ * for the routine called at the end of an ISR once it has been
+ * decided a context switch is necessary. On some compilation
+ * systems it is difficult to call a high-level language routine
+ * from assembly. This allows us to trick these systems.
+ *
+ * If you encounter this problem save the entry point in a CPU
+ * dependent variable.
+ */
+
+ _CPU_Thread_dispatch_pointer = thread_dispatch;
+#endif
+
+#if (CPU_HARDWARE_FP == TRUE)
+ /*
+ * If there is not an easy way to initialize the FP context
+ * during Context_Initialize, then it is usually easier to
+ * save an "uninitialized" FP context here and copy it to
+ * the task's during Context_Initialize.
+ */
+
+ /* FP context initialization support goes here */
+#endif
+
+ _CPU_Table = *cpu_table;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_install_raw_handler
+ *
+ * C4x Specific Information:
+ *
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ void **ittp;
+
+ /*
+ * This is where we install the interrupt handler into the "raw" interrupt
+ * table used by the CPU to dispatch interrupt handlers.
+ */
+
+ ittp = c4x_get_ittp();
+ *old_handler = ittp[ vector ];
+ ittp[ vector ] = new_handler;
+}
+
+/*XXX */
+
+#define C4X_CACHE 1
+#define C4X_BASE_ST (C4X_CACHE==1) ? 0x4800 : 0x4000
+
+void _CPU_Context_Initialize(
+ Context_Control *_the_context,
+ void *_stack_base,
+ uint32_t _size,
+ uint32_t _isr,
+ void (*_entry_point)(void),
+ int _is_fp
+)
+{
+ unsigned int *_stack;
+ _stack = (unsigned int *)_stack_base;
+
+ *_stack = (unsigned int) _entry_point;
+ _the_context->sp = (unsigned int) _stack;
+ _the_context->st = C4X_BASE_ST;
+ if ( _isr == 0 )
+ _the_context->st |= C4X_ST_GIE;
+}
+
+/*PAGE
+ *
+ * _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
+ *
+ *
+ * C4x Specific Information:
+ *
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ proc_ptr ignored;
+ extern void rtems_irq_prologue_0(void);
+ extern void rtems_irq_prologue_1(void);
+ void *entry;
+
+ *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.
+ */
+
+ entry = (void *)rtems_irq_prologue_0 +
+ ((rtems_irq_prologue_1 - rtems_irq_prologue_0) * vector);
+ _CPU_ISR_install_raw_handler( vector, entry, &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;
+}
+
+/*PAGE
+ *
+ * _CPU_Thread_Idle_body
+ *
+ * NOTES:
+ *
+ * 1. This is the same as the regular CPU independent algorithm.
+ *
+ * 2. If you implement this using a "halt", "idle", or "shutdown"
+ * instruction, then don't forget to put it in an infinite loop.
+ *
+ * 3. Be warned. Some processors with onboard DMA have been known
+ * to stop the DMA if the CPU were put in IDLE mode. This might
+ * also be a problem with other on-chip peripherals. So use this
+ * hook with caution.
+ *
+ * C4x Specific Information:
+ *
+ *
+ */
+
+#if (CPU_PROVIDES_IDLE_THREAD_BODY == 1)
+void _CPU_Thread_Idle_body( void )
+{
+
+ for( ; ; ) {
+ __asm__( "idle" );
+ __asm__( "nop" );
+ __asm__( "nop" );
+ __asm__( "nop" );
+ /* insert your "halt" instruction here */ ;
+ }
+}
+#endif
diff --git a/cpukit/score/cpu/c4x/cpu_asm.S b/cpukit/score/cpu/c4x/cpu_asm.S
new file mode 100644
index 0000000000..020c3a8d9e
--- /dev/null
+++ b/cpukit/score/cpu/c4x/cpu_asm.S
@@ -0,0 +1,769 @@
+/* cpu_asm.c ===> cpu_asm.S or cpu_asm.s
+ *
+ * This file contains the basic algorithms for all assembly code used
+ * in an specific CPU port of RTEMS. These algorithms must be implemented
+ * in assembly language
+ *
+ * NOTE: This is supposed to be a .S or .s file NOT a C file.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/asm.h>
+
+/*
+ * _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.
+ *
+ * void _CPU_Context_save_fp(
+ * void **fp_context_ptr
+ *
+ * C4x Specific Information:
+ *
+ * There is no distiniction between FP and integer context in this port.
+ */
+
+/*
+ * _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.
+ *
+ * void _CPU_Context_restore_fp(
+ * void **fp_context_ptr
+ * )
+ *
+ * C4x Specific Information:
+ *
+ * There is no distiniction between FP and integer context in this port.
+ */
+
+
+/* _CPU_Context_switch
+ *
+ * This routine performs a normal non-FP context switch.
+ *
+ * void _CPU_Context_switch(
+ * Context_Control *run,
+ * Context_Control *heir
+ * )
+ *
+ * TMS320C3x General-Purpose Applications User's Guide, section 2.4
+ * (p 2-11 and following), Context Switching in Interrupts and
+ * Subroutines states that "If the program is in a subroutine, it
+ * must preserve the dedicated C registers as follows:"
+ *
+ * Save as Integers Save as Floating-Point
+ * ================ ======================
+ * R4 R8 R6 R7
+ * AR4 AR5
+ * AR6 AR7
+ * FP DP (small model only)
+ * SP
+ */
+
+ .global SYM(_CPU_Context_switch)
+SYM(_CPU_Context_switch):
+ .if .REGPARM == 0
+ ldi sp, ar0
+ ldi *ar0, ar2 ; get the location of running context
+ .endif
+ sti st,*ar2++ ; store status word
+ sti ar3,*ar2++ ; store ar3
+ sti ar4,*ar2++ ; store ar4
+ sti ar5,*ar2++ ; store ar5
+ sti ar6,*ar2++ ; store ar6
+ sti ar7,*ar2++ ; store ar7
+ sti r4,*ar2++ ; store integer portion of r4
+ sti r5,*ar2++ ; store integer portion of r5
+ stf r6,*ar2++ ; store float portion of r6
+ stf r7,*ar2++ ; store float portion of r7
+ .if .TMS320C40
+ sti r8,*ar2++ ; store integer portion of r8
+ .endif
+ sti sp,*ar2++ ; store sp
+
+ ; end of save
+
+ .if .REGPARM == 0
+ ldi *-ar0(2), ar2 ; get the location of heir context
+ .else
+ ldi r2,ar2
+ .endif
+_local_restore:
+ ldi *ar2++,ar0 ; load status word into register
+ ldi *ar2++,ar3 ; load ar3
+ ldi *ar2++,ar4 ; load ar4
+ ldi *ar2++,ar5 ; load ar5
+ ldi *ar2++,ar6 ; load ar6
+ ldi *ar2++,ar7 ; load ar7
+ ldi *ar2++,r4 ; load integer portion of r4
+ ldi *ar2++,r5 ; load integer portion of r5
+ ldf *ar2++,r6 ; load float portion of r6
+ ldf *ar2++,r7 ; load float portion of r7
+ .if .TMS320C40
+ ldi *ar2++,r8 ; load integer portion of r8
+ .endif
+ ldi *ar2++,sp ; load sp
+ ldi ar0,st ; restore status word and interrupts
+ rets
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally 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.
+ *
+ * void _CPU_Context_restore(
+ * Context_Control *new_context
+ * )
+ */
+
+ .global SYM(_CPU_Context_restore)
+SYM(_CPU_Context_restore):
+ .if .REGPARM == 0
+ ldi sp, ar0
+ ldi *ar0, ar2 ; get the location of context to restore
+ .endif
+ br _local_restore
+
+/* void _ISR_Handler()
+ *
+ * This routine provides the RTEMS interrupt management.
+ *
+ * void _ISR_Handler()
+ */
+
+ /*
+ * At entry to "common" _ISR_Handler, the vector number must be
+ * available. On some CPUs the hardware puts either the vector
+ * number or the offset into the vector table for this ISR in a
+ * known place. If the hardware does not give us this information,
+ * then the assembly portion of RTEMS for this port will contain
+ * a set of distinct interrupt entry points which somehow place
+ * the vector number in a known place (which is safe if another
+ * interrupt nests this one) and branches to _ISR_Handler.
+ */
+
+ /*
+ * save some or all context on stack
+ * may need to save some special interrupt information for exit
+ *
+ * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
+ * if ( _ISR_Nest_level == 0 )
+ * switch to software interrupt stack
+ * #endif
+ *
+ * _ISR_Nest_level++;
+ *
+ * _Thread_Dispatch_disable_level++;
+ *
+ * (*_ISR_Vector_table[ vector ])( vector );
+ *
+ * --_ISR_Nest_level;
+ *
+ * if ( _ISR_Nest_level )
+ * goto the label "exit interrupt (simple case)"
+ *
+ * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
+ * restore stack
+ * #endif
+ *
+ * if ( !_Context_Switch_necessary )
+ * goto the label "exit interrupt (simple case)"
+ *
+ * if ( !_ISR_Signals_to_thread_executing )
+ * _ISR_Signals_to_thread_executing = FALSE;
+ * goto the label "exit interrupt (simple case)"
+ *
+ * call _Thread_Dispatch() or prepare to return to _ISR_Dispatch
+ *
+ * prepare to get out of interrupt
+ * return from interrupt (maybe to _ISR_Dispatch)
+ *
+ * LABEL "exit interrupt (simple case):
+ * prepare to get out of interrupt
+ * return from interrupt
+ */
+
+ .global SYM(_ISR_Handler_save_registers)
+SYM(_ISR_Handler_save_registers):
+ ; no push st because it is already pushed
+ ; no push ar2 because it is already pushed and vector number loaded
+ push ar0
+ push ar1
+ push dp
+ push ir0
+ push ir1
+ push rs
+ push re
+ push rc
+ push bk
+
+ push r0
+ pushf r0
+ push r1
+ pushf r1
+ push r2
+ pushf r2
+ push r3
+ pushf r3
+ ; no push r4 because other part of register is in basic context
+ push r4
+ pushf r4
+ ; no push r5 because other part of register is in basic context
+ push r5
+ pushf r5
+ push r6
+ pushf r6
+ ; no pushf r6 because other part of register is in basic context
+ push r7
+ pushf r7
+ ; no pushf r7 because other part of register is in basic context
+ .if .TMS320C40
+ push r8
+ ; no pushf r8 because other part of register is in basic context
+ push r9
+ pushf r9
+ push r10
+ pushf r10
+ push r11
+ pushf r11
+ .endif
+
+ ldi sp,r2
+ call SYM(__ISR_Handler)
+
+ .if .TMS320C40
+ popf r11
+ pop r11
+ popf r10
+ pop r10
+ popf r9
+ pop r9
+ ; no popf r8 because other part of register is in basic context
+ pop r8
+ .endif
+ ; no popf r7 because other part of register is in basic context
+ popf r7
+ pop r7
+ ; no popf r6 because other part of register is in basic context
+ popf r6
+ pop r6
+ ; no popf r5 because other part of register is in basic context
+ popf r5
+ pop r5
+ ; no pop r4 because other part of register is in basic context
+ popf r4
+ pop r4
+ popf r3
+ pop r3
+ popf r2
+ pop r2
+ popf r1
+ pop r1
+ popf r0
+ pop r0
+
+ pop bk
+ pop rc
+ pop re
+ pop rs
+ pop ir1
+ pop ir0
+ pop dp
+ pop ar1
+ pop ar0
+ pop ar2 ; because the vector numbers goes here
+ pop st
+ reti
+
+/*
+ * Prologues so we can know the vector number. Generated by this script:
+ *
+ * i=0
+ * while test $i -lt 64
+ * do
+ *
+ * printf "\t.global\tSYM(rtems_irq_prologue_%X)\n" $i
+ * printf "SYM(rtems_irq_prologue_%X):\n" $i
+ * printf "\tpush\tst\n"
+ * printf "\tpush\tar2\n"
+ * printf "\tldi\t0x%x,ar2\n" $i
+ * printf "\tbr\tSYM(_ISR_Handler_save_registers)\n"
+ * printf "\n"
+ * i=`expr $i + 1`
+ *
+ * done
+ */
+
+ .global SYM(rtems_irq_prologue_0)
+SYM(rtems_irq_prologue_0):
+ push st
+ push ar2
+ ldi 0x0,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_1)
+SYM(rtems_irq_prologue_1):
+ push st
+ push ar2
+ ldi 0x1,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_2)
+SYM(rtems_irq_prologue_2):
+ push st
+ push ar2
+ ldi 0x2,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_3)
+SYM(rtems_irq_prologue_3):
+ push st
+ push ar2
+ ldi 0x3,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_4)
+SYM(rtems_irq_prologue_4):
+ push st
+ push ar2
+ ldi 0x4,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_5)
+SYM(rtems_irq_prologue_5):
+ push st
+ push ar2
+ ldi 0x5,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_6)
+SYM(rtems_irq_prologue_6):
+ push st
+ push ar2
+ ldi 0x6,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_7)
+SYM(rtems_irq_prologue_7):
+ push st
+ push ar2
+ ldi 0x7,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_8)
+SYM(rtems_irq_prologue_8):
+ push st
+ push ar2
+ ldi 0x8,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_9)
+SYM(rtems_irq_prologue_9):
+ push st
+ push ar2
+ ldi 0x9,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_A)
+SYM(rtems_irq_prologue_A):
+ push st
+ push ar2
+ ldi 0xa,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_B)
+SYM(rtems_irq_prologue_B):
+ push st
+ push ar2
+ ldi 0xb,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_C)
+SYM(rtems_irq_prologue_C):
+ push st
+ push ar2
+ ldi 0xc,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_D)
+SYM(rtems_irq_prologue_D):
+ push st
+ push ar2
+ ldi 0xd,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_E)
+SYM(rtems_irq_prologue_E):
+ push st
+ push ar2
+ ldi 0xe,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_F)
+SYM(rtems_irq_prologue_F):
+ push st
+ push ar2
+ ldi 0xf,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_10)
+SYM(rtems_irq_prologue_10):
+ push st
+ push ar2
+ ldi 0x10,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_11)
+SYM(rtems_irq_prologue_11):
+ push st
+ push ar2
+ ldi 0x11,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_12)
+SYM(rtems_irq_prologue_12):
+ push st
+ push ar2
+ ldi 0x12,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_13)
+SYM(rtems_irq_prologue_13):
+ push st
+ push ar2
+ ldi 0x13,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_14)
+SYM(rtems_irq_prologue_14):
+ push st
+ push ar2
+ ldi 0x14,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_15)
+SYM(rtems_irq_prologue_15):
+ push st
+ push ar2
+ ldi 0x15,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_16)
+SYM(rtems_irq_prologue_16):
+ push st
+ push ar2
+ ldi 0x16,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_17)
+SYM(rtems_irq_prologue_17):
+ push st
+ push ar2
+ ldi 0x17,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_18)
+SYM(rtems_irq_prologue_18):
+ push st
+ push ar2
+ ldi 0x18,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_19)
+SYM(rtems_irq_prologue_19):
+ push st
+ push ar2
+ ldi 0x19,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_1A)
+SYM(rtems_irq_prologue_1A):
+ push st
+ push ar2
+ ldi 0x1a,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_1B)
+SYM(rtems_irq_prologue_1B):
+ push st
+ push ar2
+ ldi 0x1b,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_1C)
+SYM(rtems_irq_prologue_1C):
+ push st
+ push ar2
+ ldi 0x1c,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_1D)
+SYM(rtems_irq_prologue_1D):
+ push st
+ push ar2
+ ldi 0x1d,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_1E)
+SYM(rtems_irq_prologue_1E):
+ push st
+ push ar2
+ ldi 0x1e,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_1F)
+SYM(rtems_irq_prologue_1F):
+ push st
+ push ar2
+ ldi 0x1f,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_20)
+SYM(rtems_irq_prologue_20):
+ push st
+ push ar2
+ ldi 0x20,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_21)
+SYM(rtems_irq_prologue_21):
+ push st
+ push ar2
+ ldi 0x21,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_22)
+SYM(rtems_irq_prologue_22):
+ push st
+ push ar2
+ ldi 0x22,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_23)
+SYM(rtems_irq_prologue_23):
+ push st
+ push ar2
+ ldi 0x23,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_24)
+SYM(rtems_irq_prologue_24):
+ push st
+ push ar2
+ ldi 0x24,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_25)
+SYM(rtems_irq_prologue_25):
+ push st
+ push ar2
+ ldi 0x25,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_26)
+SYM(rtems_irq_prologue_26):
+ push st
+ push ar2
+ ldi 0x26,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_27)
+SYM(rtems_irq_prologue_27):
+ push st
+ push ar2
+ ldi 0x27,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_28)
+SYM(rtems_irq_prologue_28):
+ push st
+ push ar2
+ ldi 0x28,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_29)
+SYM(rtems_irq_prologue_29):
+ push st
+ push ar2
+ ldi 0x29,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_2A)
+SYM(rtems_irq_prologue_2A):
+ push st
+ push ar2
+ ldi 0x2a,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_2B)
+SYM(rtems_irq_prologue_2B):
+ push st
+ push ar2
+ ldi 0x2b,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_2C)
+SYM(rtems_irq_prologue_2C):
+ push st
+ push ar2
+ ldi 0x2c,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_2D)
+SYM(rtems_irq_prologue_2D):
+ push st
+ push ar2
+ ldi 0x2d,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_2E)
+SYM(rtems_irq_prologue_2E):
+ push st
+ push ar2
+ ldi 0x2e,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_2F)
+SYM(rtems_irq_prologue_2F):
+ push st
+ push ar2
+ ldi 0x2f,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_30)
+SYM(rtems_irq_prologue_30):
+ push st
+ push ar2
+ ldi 0x30,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_31)
+SYM(rtems_irq_prologue_31):
+ push st
+ push ar2
+ ldi 0x31,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_32)
+SYM(rtems_irq_prologue_32):
+ push st
+ push ar2
+ ldi 0x32,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_33)
+SYM(rtems_irq_prologue_33):
+ push st
+ push ar2
+ ldi 0x33,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_34)
+SYM(rtems_irq_prologue_34):
+ push st
+ push ar2
+ ldi 0x34,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_35)
+SYM(rtems_irq_prologue_35):
+ push st
+ push ar2
+ ldi 0x35,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_36)
+SYM(rtems_irq_prologue_36):
+ push st
+ push ar2
+ ldi 0x36,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_37)
+SYM(rtems_irq_prologue_37):
+ push st
+ push ar2
+ ldi 0x37,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_38)
+SYM(rtems_irq_prologue_38):
+ push st
+ push ar2
+ ldi 0x38,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_39)
+SYM(rtems_irq_prologue_39):
+ push st
+ push ar2
+ ldi 0x39,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_3A)
+SYM(rtems_irq_prologue_3A):
+ push st
+ push ar2
+ ldi 0x3a,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_3B)
+SYM(rtems_irq_prologue_3B):
+ push st
+ push ar2
+ ldi 0x3b,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_3C)
+SYM(rtems_irq_prologue_3C):
+ push st
+ push ar2
+ ldi 0x3c,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_3D)
+SYM(rtems_irq_prologue_3D):
+ push st
+ push ar2
+ ldi 0x3d,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_3E)
+SYM(rtems_irq_prologue_3E):
+ push st
+ push ar2
+ ldi 0x3e,ar2
+ br SYM(_ISR_Handler_save_registers)
+
+ .global SYM(rtems_irq_prologue_3F)
+SYM(rtems_irq_prologue_3F):
+ push st
+ push ar2
+ ldi 0x3f,ar2
+ br SYM(_ISR_Handler_save_registers)
diff --git a/cpukit/score/cpu/c4x/irq.c b/cpukit/score/cpu/c4x/irq.c
new file mode 100644
index 0000000000..104b3afdc4
--- /dev/null
+++ b/cpukit/score/cpu/c4x/irq.c
@@ -0,0 +1,89 @@
+/*
+ * C4x CPU Dependent Source
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/cpu.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+
+/*
+ * This routine provides the RTEMS interrupt management.
+ */
+
+#if( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ unsigned long *_old_stack_ptr;
+#endif
+
+register unsigned long *stack_ptr asm("sp");
+
+void __ISR_Handler(uint32_t vector, void *isr_sp)
+{
+ register uint32_t level;
+
+ /* already disabled when we get here */
+ /* _CPU_ISR_Disable( level ); */
+
+ _Thread_Dispatch_disable_level++;
+
+#if 0
+ if ( stack_ptr > (_Thread_Executing->Start.stack +
+ _Thread_Executing->Start.Initial_stack.size) ) {
+ printk( "Blown interrupt stack at 0x%x\n", stack_ptr );
+ }
+#endif
+
+#if( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ if ( _ISR_Nest_level == 0 ) {
+ /* Install irq stack */
+ _old_stack_ptr = stack_ptr;
+ stack_ptr = _CPU_Interrupt_stack_low;
+ }
+#endif
+
+ _ISR_Nest_level++;
+
+ /* leave it to the ISR to decide if they get reenabled */
+ /* _CPU_ISR_Enable( level ); */
+
+ /* call isp */
+ if ( _ISR_Vector_table[ vector] )
+ (*_ISR_Vector_table[ vector ])(
+ vector, isr_sp - sizeof(CPU_Interrupt_frame) + 1 );
+
+ _CPU_ISR_Disable( level );
+
+ _ISR_Nest_level--;
+
+#if( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ if ( _ISR_Nest_level == 0 ) /* restore old stack pointer */
+ stack_ptr = _old_stack_ptr;
+#endif
+
+ _Thread_Dispatch_disable_level--;
+
+ _CPU_ISR_Enable( level );
+
+ if ( _ISR_Nest_level )
+ return;
+
+ if ( _Thread_Dispatch_disable_level ) {
+ _ISR_Signals_to_thread_executing = FALSE;
+ return;
+ }
+
+ if ( _Context_Switch_necessary || _ISR_Signals_to_thread_executing ) {
+ _ISR_Signals_to_thread_executing = FALSE;
+ _Thread_Dispatch();
+ }
+}
diff --git a/cpukit/score/cpu/c4x/preinstall.am b/cpukit/score/cpu/c4x/preinstall.am
new file mode 100644
index 0000000000..4fecf81f59
--- /dev/null
+++ b/cpukit/score/cpu/c4x/preinstall.am
@@ -0,0 +1,54 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/tic4x/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/tic4x
+ @: > $(PROJECT_INCLUDE)/rtems/tic4x/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/tic4x/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/tic4x/c4xio.h: rtems/tic4x/c4xio.h $(PROJECT_INCLUDE)/rtems/tic4x/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/tic4x/c4xio.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/tic4x/c4xio.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/c4x.h: rtems/score/c4x.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/c4x.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/c4x.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
+$(PROJECT_INCLUDE)/rtems/score/cpu_asm.h: rtems/score/cpu_asm.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h
+
diff --git a/cpukit/score/cpu/c4x/rtems/asm.h b/cpukit/score/cpu/c4x/rtems/asm.h
new file mode 100644
index 0000000000..d99484e96c
--- /dev/null
+++ b/cpukit/score/cpu/c4x/rtems/asm.h
@@ -0,0 +1,97 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ */
+
+/*
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ * COPYRIGHT (c) 1994-1997.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/c4x.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/*
+ * define macros for all of the registers on this CPU
+ *
+ * EXAMPLE: #define d0 REG (d0)
+ */
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA
+#define END_DATA
+#define BEGIN_BSS
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .globl SYM (sym)
+#define EXTERN(sym) .globl SYM (sym)
+
+#endif
diff --git a/cpukit/score/cpu/c4x/rtems/score/c4x.h b/cpukit/score/cpu/c4x/rtems/score/c4x.h
new file mode 100644
index 0000000000..c7b8f75c58
--- /dev/null
+++ b/cpukit/score/cpu/c4x/rtems/score/c4x.h
@@ -0,0 +1,367 @@
+/**
+ * @file rtems/score/c4x.h
+ */
+
+/*
+ * This file is an example (i.e. "no CPU") of the file which is
+ * created for each CPU family port of RTEMS.
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef _RTEMS_SCORE_C4X_H
+#define _RTEMS_SCORE_C4X_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the "no cpu"
+ * family when executing in protected mode. It does
+ * this by setting variables to indicate which implementation
+ * dependent features are present in a particular member
+ * of the family.
+ */
+
+#if defined(_C30)
+#define CPU_MODEL_NAME "C30"
+
+#elif defined(_C31)
+#define CPU_MODEL_NAME "C31"
+
+#elif defined(_C32)
+#define CPU_MODEL_NAME "C32"
+
+#elif defined(_C33)
+#define CPU_MODEL_NAME "C33"
+
+#elif defined(_C40)
+#define CPU_MODEL_NAME "C40"
+
+#elif defined(_C44)
+#define CPU_MODEL_NAME "C44"
+
+#else
+
+#error "Unsupported CPU Model"
+
+#endif
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "Texas Instruments C3x/C4x"
+
+/*
+ * This port is a little unusual in that even though there are "floating
+ * point registers", the notion of floating point is very inherent to
+ * applications. In addition, the calling conventions require that
+ * only a few extended registers be preserved across subroutine calls.
+ * The overhead of including these few registers in the basic
+ * context is small compared to the overhead of managing the notion
+ * of separate floating point contexts. So we decided to pretend that
+ * there is no FPU on the C3x or C4x.
+ */
+
+#define C4X_HAS_FPU 0
+
+/*
+ * Routines to manipulate the bits in the Status Word (ST).
+ */
+
+#define C4X_ST_C 0x0001
+#define C4X_ST_V 0x0002
+#define C4X_ST_Z 0x0004
+#define C4X_ST_N 0x0008
+#define C4X_ST_UF 0x0010
+#define C4X_ST_LV 0x0020
+#define C4X_ST_LUF 0x0040
+#define C4X_ST_OVM 0x0080
+#define C4X_ST_RM 0x0100
+#define C4X_ST_CF 0x0400
+#define C4X_ST_CE 0x0800
+#define C4X_ST_CC 0x1000
+#define C4X_ST_GIE 0x2000
+
+#ifndef _TMS320C40
+#define C3X_IE_INTERRUPT_MASK_BITS 0xffff
+#define C3x_IE_INTERRUPTS_ALL_ENABLED 0x0000
+#define C3x_IE_INTERRUPTS_ALL_DISABLED 0xffff
+#endif
+
+#ifndef ASM
+
+/*
+ * A nop macro.
+ */
+
+#define c4x_nop() \
+ __asm__("nop");
+
+/*
+ * Routines to set and clear individual bits in the ST (status word).
+ *
+ * cpu_st_bit_clear - clear bit in ST
+ * cpu_st_bit_set - set bit in ST
+ * cpu_st_get - obtain entire ST
+ */
+
+#ifdef _TMS320C40
+#define c4x_gie_nop()
+#else
+#define c4x_gie_nop() { c4x_nop(); c4x_nop(); }
+#endif
+
+#define cpu_st_bit_clear(_st_bit) \
+ do { \
+ __asm__("andn %0,st" : : "g" (_st_bit) : "cc"); \
+ c4x_gie_nop(); \
+ } while (0)
+
+#define cpu_st_bit_set(_st_bit) \
+ do { \
+ __asm__("or %0,st" : : "g" (_st_bit) : "cc"); \
+ c4x_gie_nop(); \
+ } while (0)
+
+static inline unsigned int cpu_st_get(void)
+{
+ register unsigned int st_value;
+ __asm__("ldi st, %0" : "=r" (st_value));
+ return st_value;
+}
+
+/*
+ * Routines to manipulate the Global Interrupt Enable (GIE) bit in
+ * the Status Word (ST).
+ *
+ * c4x_global_interrupts_get - returns current GIE setting
+ * c4x_global_interrupts_disable - disables global interrupts
+ * c4x_global_interrupts_enable - enables global interrupts
+ * c4x_global_interrupts_restore - restores GIE to pre-disable state
+ * c4x_global_interrupts_flash - temporarily enable global interrupts
+ */
+
+#define c4x_global_interrupts_get() \
+ (cpu_st_get() & C4X_ST_GIE)
+
+#define c4x_global_interrupts_disable() \
+ cpu_st_bit_clear(C4X_ST_GIE)
+
+#define c4x_global_interrupts_enable() \
+ cpu_st_bit_set(C4X_ST_GIE)
+
+#define c4x_global_interrupts_restore(_old_level) \
+ cpu_st_bit_set(_old_level)
+
+#define c4x_global_interrupts_flash(_old_level) \
+ do { \
+ cpu_st_bit_set(_old_level); \
+ cpu_st_bit_clear(C4X_ST_GIE); \
+ } while (0)
+
+#ifndef _TMS320C40
+
+/*
+ * Routines to set and get the IF register
+ *
+ * c3x_get_if - obtains IF register
+ * c3x_set_if - sets IF register
+ */
+
+static inline unsigned int c3x_get_if(void)
+{
+ register unsigned int _if_value;
+
+ __asm__( "ldi if, %0" : "=r" (_if_value) );
+ return _if_value;
+}
+
+static inline void c3x_set_if(unsigned int _if_value)
+{
+ __asm__( "ldi %0, if" : : "g" (_if_value) : "if", "cc");
+}
+
+/*
+ * Routines to set and get the IE register
+ *
+ * c3x_get_ie - obtains IE register
+ * c3x_set_ie - sets IE register
+ */
+
+static inline unsigned int c3x_get_ie(void)
+{
+ register unsigned int _ie_value;
+
+ __asm__ volatile ( "ldi ie, %0" : "=r" (_ie_value) );
+ return _ie_value;
+}
+
+static inline void c3x_set_ie(unsigned int _ie_value)
+{
+ __asm__ volatile ( "ldi %0, ie" : : "g" (_ie_value) : "ie", "cc");
+}
+
+/*
+ * Routines to manipulates the mask portion of the IE register.
+ *
+ * c3x_ie_mask_all - returns previous IE mask
+ * c3x_ie_mask_restore - restores previous IE mask
+ * c3x_ie_mask_flash - temporarily restores previous IE mask
+ * c3x_ie_mask_set - sets a specific set of the IE mask
+ */
+
+#define c3x_ie_mask_all( _isr_cookie ) \
+ do { \
+ __asm__("ldi ie,%0\n" \
+ "\tandn 0ffffh, ie" \
+ : "=r" (_isr_cookie): : "ie", "cc" ); \
+ } while (0)
+
+#define c3x_ie_mask_restore( _isr_cookie ) \
+ do { \
+ __asm__("or %0, ie" \
+ : : "g" (_isr_cookie) : "ie", "cc" ); \
+ } while (0)
+
+#define c3x_ie_mask_flash( _isr_cookie ) \
+ do { \
+ __asm__("or %0, ie\n" \
+ "\tandn 0ffffh, ie" \
+ : : "g" (_isr_cookie) : "ie", "cc" ); \
+ } while (0)
+
+#define c3x_ie_mask_set( _new_mask ) \
+ do { unsigned int _ie_mask; \
+ unsigned int _ie_value; \
+ \
+ if ( _new_mask == 0 ) _ie_mask = 0; \
+ else _ie_mask = 0xffff; \
+ _ie_value = c3x_get_ie(); \
+ _ie_value &= C4X_IE_INTERRUPT_MASK_BITS; \
+ _ie_value |= _ie_mask; \
+ c3x_set_ie(_ie_value); \
+ } while (0)
+#endif
+/* end of C3x specific interrupt flag routines */
+
+/*
+ * This is a section of C4x specific interrupt flag management routines.
+ */
+
+#ifdef _TMS320C40
+
+/*
+ * Routines to set and get the IIF register
+ *
+ * c4x_get_iif - obtains IIF register
+ * c4x_set_iif - sets IIF register
+ */
+
+static inline unsigned int c4x_get_iif(void)
+{
+ register unsigned int _iif_value;
+
+ __asm__( "ldi iif, %0" : "=r" (_iif_value) );
+ return _iif_value;
+}
+
+static inline void c4x_set_iif(unsigned int _iif_value)
+{
+ __asm__( "ldi %0, iif" : : "g" (_iif_value) : "iif", "cc");
+}
+
+/*
+ * Routines to set and get the IIE register
+ *
+ * c4x_get_iie - obtains IIE register
+ * c4x_set_iie - sets IIE register
+ */
+
+static inline unsigned int c4x_get_iie(void)
+{
+ register unsigned int _iie_value;
+
+ __asm__( "ldi iie, %0" : "=r" (_iie_value) );
+ return _iie_value;
+}
+
+static inline void c4x_set_iie(unsigned int _iie_value)
+{
+ __asm__( "ldi %0, iie" : : "g" (_iie_value) : "iie", "cc");
+}
+
+/*
+ * Routines to manipulates the mask portion of the IIE register.
+ *
+ * c4x_ie_mask_all - returns previous IIE mask
+ * c4x_ie_mask_restore - restores previous IIE mask
+ * c4x_ie_mask_flash - temporarily restores previous IIE mask
+ * c4x_ie_mask_set - sets a specific set of the IIE mask
+ */
+
+#if 0
+#warning "C4x IIE masking routines not implemented."
+#define c4x_iie_mask_all( _isr_cookie )
+#define c4x_iie_mask_restore( _isr_cookie )
+#define c4x_iie_mask_flash( _isr_cookie )
+#define c4x_iie_mask_set( _new_mask )
+#endif
+
+#endif
+/* end of C4x specific interrupt flag routines */
+
+/*
+ * Routines to access the Interrupt Trap Table Pointer
+ *
+ * c4x_get_ittp - get ITTP
+ * c4x_set_ittp - set ITTP
+ */
+
+static inline void * c4x_get_ittp(void)
+{
+ register unsigned int _if_value;
+
+ __asm__( "ldi if, %0" : "=r" (_if_value) );
+ return (void *)((_if_value & 0xffff0000) >> 8);
+}
+
+static inline void c4x_set_ittp(void *_ittp_value)
+{
+ unsigned int _if_value;
+ unsigned int _ittp_field;
+
+#ifdef _TMS320C40
+ _if_value = c4x_get_iif();
+#else
+ _if_value = c3x_get_if();
+#endif
+ _if_value &= 0xffff;
+ _ittp_field = (((unsigned int) _ittp_value) >> 8);
+ _if_value |= _ittp_field << 16 ;
+#ifdef _TMS320C40
+ c4x_set_iif( _if_value );
+#else
+ c3x_set_if( _if_value );
+#endif
+}
+
+#endif /* ifndef ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_C4X_H */
diff --git a/cpukit/score/cpu/c4x/rtems/score/cpu.h b/cpukit/score/cpu/c4x/rtems/score/cpu.h
new file mode 100644
index 0000000000..b268a44499
--- /dev/null
+++ b/cpukit/score/cpu/c4x/rtems/score/cpu.h
@@ -0,0 +1,1260 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * This include file contains information pertaining to the C4x
+ * processor.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/c4x.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+
+/* conditional compilation parameters */
+
+/*
+ * Should the calls to _Thread_Enable_dispatch be inlined?
+ *
+ * If TRUE, then they are inlined.
+ * If FALSE, then a subroutine call is made.
+ *
+ * Basically this is an example of the classic trade-off of size
+ * versus speed. Inlining the call (TRUE) typically increases the
+ * size of RTEMS while speeding up the enabling of dispatching.
+ * [NOTE: In general, the _Thread_Dispatch_disable_level will
+ * only be 0 or 1 unless you are in an interrupt handler and that
+ * interrupt handler invokes the executive.] When not inlined
+ * something calls _Thread_Enable_dispatch which in turns calls
+ * _Thread_Dispatch. If the enable dispatch is inlined, then
+ * one subroutine call is avoided entirely.]
+ *
+ * C4x Specific Information:
+ *
+ * We might as well try to inline this code until there is a
+ * code space problem.
+ */
+
+#define CPU_INLINE_ENABLE_DISPATCH TRUE
+
+/*
+ * Should the body of the search loops in _Thread_queue_Enqueue_priority
+ * be unrolled one time? In unrolled each iteration of the loop examines
+ * two "nodes" on the chain being searched. Otherwise, only one node
+ * is examined per iteration.
+ *
+ * If TRUE, then the loops are unrolled.
+ * If FALSE, then the loops are not unrolled.
+ *
+ * The primary factor in making this decision is the cost of disabling
+ * and enabling interrupts (_ISR_Flash) versus the cost of rest of the
+ * body of the loop. On some CPUs, the flash is more expensive than
+ * one iteration of the loop body. In this case, it might be desirable
+ * to unroll the loop. It is important to note that on some CPUs, this
+ * code is the longest interrupt disable period in RTEMS. So it is
+ * necessary to strike a balance when setting this parameter.
+ *
+ * C4x Specific Information:
+ *
+ * We might as well unroll this loop until there is a reason not to do so.
+ */
+
+#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
+
+/*
+ * Does RTEMS manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in _Interrupt_Manager_initialization.
+ * If FALSE, nothing is done.
+ *
+ * If the CPU supports a dedicated interrupt stack in hardware,
+ * then it is generally the responsibility of the BSP to allocate it
+ * and set it up.
+ *
+ * If the CPU does not support a dedicated interrupt stack, then
+ * the porter has two options: (1) execute interrupts on the
+ * stack of the interrupted task, and (2) have RTEMS manage a dedicated
+ * interrupt stack.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ *
+ * C4x Specific Information:
+ *
+ * Initial investigation indicates a software managed stack will be needed.
+ * But the implementation does not currently include support for one.
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
+
+/*
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * If TRUE, then it must be installed during initialization.
+ * If FALSE, then no installation is performed.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ *
+ * Initial investigation indicates a software managed stack will be needed.
+ */
+
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
+
+/*
+ * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * If TRUE, then the memory is allocated during initialization.
+ * If FALSE, then the memory is allocated during initialization.
+ *
+ * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ *
+ * Until we know what to do with the memory, we should not allocated it.
+ */
+
+#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
+
+/*
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ *
+ * The interrupt code will have to be written before this is answered
+ * but the answer should be yes.
+ */
+
+#define CPU_ISR_PASSES_FRAME_POINTER 1
+
+/*
+ * Does the CPU have hardware floating point?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
+ *
+ * If there is a FP coprocessor such as the i387 or mc68881, then
+ * the answer is TRUE.
+ *
+ * The macro name "C4X_HAS_FPU" should be made CPU specific.
+ * It indicates whether or not this CPU model has FP support. For
+ * example, it would be possible to have an i386_nofp CPU model
+ * which set this to false to indicate that you have an i386 without
+ * an i387 and wish to leave floating point support out of RTEMS.
+ *
+ * C4x Specific Information:
+ *
+ * See c4x.h for more details but the bottom line is that the
+ * few extended registers required to be preserved across subroutines
+ * calls are considered part of the integer context. This eliminates
+ * overhead.
+ *
+ * The C4X_HAS_FPU refers to the extended precision registers R0-R7
+ * (plus R8-R11 on some models).
+ *
+ * XXX check that we even need to have the context area pointer in
+ * the TCB in this case.
+ */
+
+#if ( C4X_HAS_FPU == 1 )
+#define CPU_HARDWARE_FP TRUE
+#else
+#define CPU_HARDWARE_FP FALSE
+#endif
+#define CPU_SOFTWARE_FP FALSE
+
+/*
+ * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
+ *
+ * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
+ *
+ * C4x Specific Information:
+ *
+ * There is no known reason to make all tasks include the extended
+ * precision registers (i.e. floating point context).
+ */
+
+#define CPU_ALL_TASKS_ARE_FP FALSE
+
+/*
+ * Should the IDLE task have a floating point context?
+ *
+ * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * If FALSE, then the IDLE task does not have a floating point context.
+ *
+ * Setting this to TRUE negatively impacts the time required to preempt
+ * the IDLE task from an interrupt because the floating point context
+ * must be saved as part of the preemption.
+ *
+ * C4x Specific Information:
+ *
+ * There is no known reason to make the IDLE task floating point and
+ * no point in wasting the memory or increasing the context switch
+ * time for the IDLE task.
+ */
+
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+/*
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ *
+ * If the floating point context does NOT have to be saved as part of
+ * interrupt dispatching, then it should be safe to set this to TRUE.
+ *
+ * Setting this flag to TRUE results in using a different algorithm
+ * for deciding when to save and restore the floating point context.
+ * The deferred FP switch algorithm minimizes the number of times
+ * the FP context is saved and restored. The FP context is not saved
+ * until a context switch is made to another, different FP task.
+ * Thus in a system with only one FP task, the FP context will never
+ * be saved or restored.
+ *
+ * C4x Specific Information:
+ *
+ * There is no reason to avoid the deferred FP switch logic on this
+ * CPU family.
+ */
+
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+/*
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine _CPU_Thread_Idle_body
+ * must be provided and is the default IDLE thread body instead of
+ * _CPU_Thread_Idle_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ *
+ * This is intended to allow for supporting processors which have
+ * a low power or idle mode. When the IDLE thread is executed, then
+ * the CPU can be powered down.
+ *
+ * The order of precedence for selecting the IDLE thread body is:
+ *
+ * 1. BSP provided
+ * 2. CPU dependent (if provided)
+ * 3. generic (if no BSP and no CPU dependent)
+ *
+ * C4x Specific Information:
+ *
+ * There is currently no reason to avoid using the generic implementation.
+ * In the future, a C4x specific IDLE thread body may be added to take
+ * advantage of low power modes.
+ */
+
+#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
+
+/*
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * If TRUE, then the grows upward.
+ * If FALSE, then the grows toward smaller addresses.
+ *
+ * C4x Specific Information:
+ *
+ * The system stack grows from low to high memory.
+ *
+ * C4x Specific Information:
+ *
+ * This setting was derived from the discussion of stack management
+ * in section 6.1 (p. 6-29) System and User Stack Management of the
+ * TMS32C3x User's Guide (rev L, July 1997) which states: "A push
+ * performs a preincrement, and a pop performs a postdecrement of the
+ * system-stack pointer." There are instructions for making "a stack"
+ * run from high to low memory but this appears to be the exception.
+ */
+
+#define CPU_STACK_GROWS_UP TRUE
+
+/*
+ * The following is the variable attribute used to force alignment
+ * of critical RTEMS structures. On some processors it may make
+ * sense to have these aligned on tighter boundaries than
+ * the minimum requirements of the compiler in order to have as
+ * much of the critical data area as possible in a cache line.
+ *
+ * The placement of this macro in the declaration of the variables
+ * is based on the syntactically requirements of the GNU C
+ * "__attribute__" extension. For example with GNU C, use
+ * the following to force a structures to a 32 byte boundary.
+ *
+ * __attribute__ ((aligned (32)))
+ *
+ * NOTE: Currently only the Priority Bit Map table uses this feature.
+ * To benefit from using this, the data must be heavily
+ * used so it will stay in the cache and used frequently enough
+ * in the executive to justify turning this on.
+ *
+ * C4x Specific Information:
+ *
+ * The C4x is word oriented and there should be no alignment issues.
+ */
+
+#define CPU_STRUCTURE_ALIGNMENT
+
+/*
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ *
+ * C4x Specific Information:
+ *
+ */
+
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+#define CPU_BIG_ENDIAN TRUE
+#define CPU_LITTLE_ENDIAN FALSE
+
+/*
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
+ *
+ * C4x Specific Information:
+ *
+ * Currently we are only supporting interrupt levels 0 (all on) and
+ * 1 (all off). Levels 2-255 COULD be looked up in a user provided
+ * table that gives GIE and IE Mask settings. But this is not the
+ * case today.
+ */
+
+#define CPU_MODES_INTERRUPT_MASK 0x000000FF
+
+/*
+ * Processor defined structures required for cpukit/score.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+/* may need to put some structures here. */
+
+/*
+ * Contexts
+ *
+ * Generally there are 2 types of context to save.
+ * 1. Interrupt registers to save
+ * 2. Task level registers to save
+ *
+ * This means we have the following 3 context items:
+ * 1. task level context stuff:: Context_Control
+ * 2. floating point task stuff:: Context_Control_fp
+ * 3. special interrupt level context :: Context_Control_interrupt
+ *
+ * On some processors, it is cost-effective to save only the callee
+ * preserved registers during a task context switch. This means
+ * that the ISR code needs to save those registers which do not
+ * persist across function calls. It is not mandatory to make this
+ * distinctions between the caller/callee saves registers for the
+ * purpose of minimizing context saved during task switch and on interrupts.
+ * If the cost of saving extra registers is minimal, simplicity is the
+ * choice. Save the same context on interrupt entry as for tasks in
+ * this case.
+ *
+ * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
+ * care should be used in designing the context area.
+ *
+ * On some CPUs with hardware floating point support, the Context_Control_fp
+ * structure will not be used or it simply consist of an array of a
+ * fixed number of bytes. This is done when the floating point context
+ * is dumped by a "FP save context" type instruction and the format
+ * is not really defined by the CPU. In this case, there is no need
+ * to figure out the exact format -- only the size. Of course, although
+ * this is enough information for RTEMS, it is probably not enough for
+ * a debugger such as gdb. But that is another problem.
+ *
+ * C4x Specific Information:
+ *
+ * From email with Michael Hayes:
+ * > > But what are the rules for what is passed in what registers?
+ *
+ * Args are passed in the following registers (in order):
+ *
+ * AR2, R2, R3, RC, RS, RE
+ *
+ * However, the first and second floating point values are always in R2
+ * and R3 (and all other floats are on the stack). Structs are always
+ * passed on the stack. If the last argument is an ellipsis, the
+ * previous argument is passed on the stack so that its address can be
+ * taken for the stdargs macros.
+ *
+ * > > What is assumed to be preserved across calls?
+ *
+ * AR3, AR4, AR5, AR6, AR7
+ * R4, R5, R8 (using STI/LDI)
+ * R6, R7 (using STF/LDF)
+ *
+ * > > What is assumed to be scratch registers?
+ *
+ * R0, R1, R2, R3, AR0, AR1, AR2, IR0, IR1, BK, RS, RE, RC, R9, R10, R11
+ *
+ * Based on this information, the task specific context is quite small
+ * but the interrupt context is much larger. In fact, it could
+ * easily be argued that there is no point in distinguishing between
+ * integer and floating point contexts on the Cxx since there is
+ * so little context involved. So that is the decision made.
+ *
+ * Not Mentioned in list: DP
+ *
+ * Assumed to be global resources:
+ *
+ * C3X: IE, IF, and IOF
+ * C4X: DIE, IIF, and IIF
+ */
+
+
+typedef struct {
+ unsigned int st;
+ unsigned int ar3;
+ unsigned int ar4;
+ unsigned int ar5;
+ unsigned int ar6;
+ unsigned int ar7;
+ unsigned int r4_sti; /* other part of register is in interrupt context */
+ unsigned int r5_sti; /* other part of register is in interrupt context */
+ unsigned int r6_stf; /* other part of register is in interrupt context */
+ unsigned int r7_stf; /* other part of register is in interrupt context */
+#ifdef _TMS320C40
+ unsigned int r8_sti; /* other part of register is in interrupt context */
+#endif
+ unsigned int sp;
+} Context_Control;
+
+typedef struct {
+} Context_Control_fp;
+
+/*
+ * This is the order the interrupt entry code pushes the registers.
+ */
+
+typedef struct {
+ void *interrupted;
+ unsigned int st;
+ unsigned int ar2; /* because the vector numbers goes here */
+ unsigned int ar0;
+ unsigned int ar1;
+ unsigned int dp;
+ unsigned int ir0;
+ unsigned int ir1;
+ unsigned int rs;
+ unsigned int re;
+ unsigned int rc;
+ unsigned int bk;
+ unsigned int r0_sti;
+ unsigned int r0_stf;
+ unsigned int r1_sti;
+ unsigned int r1_stf;
+ unsigned int r2_sti;
+ unsigned int r2_stf;
+ unsigned int r3_sti;
+ unsigned int r3_stf;
+ unsigned int r4_stf; /* other part of register is in basic context */
+ unsigned int r5_stf; /* other part of register is in basic context */
+ unsigned int r6_sti; /* other part of register is in basic context */
+ unsigned int r7_sti; /* other part of register is in basic context */
+
+#ifdef _TMS320C40
+ unsigned int r8_sti; /* other part of register is in basic context */
+ unsigned int r9_sti;
+ unsigned int r9_stf;
+ unsigned int r10_sti;
+ unsigned int r10_stf;
+ unsigned int r11_sti;
+ unsigned int r11_stf;
+#endif
+
+} CPU_Interrupt_frame;
+
+/*
+ * The following table contains the information required to configure
+ * the C4x processor specific parameters.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+ /* end of fields required on all CPUs */
+
+} rtems_cpu_table;
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ */
+
+/*
+ * Macros to access C4X specific additions to the CPU Table
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+/* There are no CPU specific additions to the CPU Table for this port. */
+
+#if 0
+/*
+ * This variable is optional. It is used on CPUs on which it is difficult
+ * to generate an "uninitialized" FP context. It is filled in by
+ * _CPU_Initialize and copied into the task's FP context area during
+ * _CPU_Context_Initialize.
+ *
+ * C4x Specific Information:
+ *
+ * Unused
+ */
+
+SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
+#endif
+
+/*
+ * On some CPUs, RTEMS supports a software managed interrupt stack.
+ * This stack is allocated by the Interrupt Manager and the switch
+ * is performed in _ISR_Handler. These variables contain pointers
+ * to the lowest and highest addresses in the chunk of memory allocated
+ * for the interrupt stack. Since it is unknown whether the stack
+ * grows up or down (in general), this give the CPU dependent
+ * code the option of picking the version it wants to use.
+ *
+ * NOTE: These two variables are required if the macro
+ * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+/*
+ * With some compilation systems, it is difficult if not impossible to
+ * call a high-level language routine from assembly language. This
+ * is especially true of commercial Ada compilers and name mangling
+ * C++ ones. This variable can be optionally defined by the CPU porter
+ * and contains the address of the routine _Thread_Dispatch. This
+ * can make it easier to invoke that routine at the end of the interrupt
+ * sequence (if a dispatch is necessary).
+ *
+ * C4x Specific Information:
+ *
+ * This port should not require this.
+ */
+
+#if 0
+SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
+#endif
+
+/*
+ * Nothing prevents the porter from declaring more CPU specific variables.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+/* XXX: if needed, put more variables here */
+
+/*
+ * The size of the floating point context area. On some CPUs this
+ * will not be a "sizeof" because the format of the floating point
+ * area is not defined -- only the size is. This is usually on
+ * CPUs with a "floating point save context" instruction.
+ *
+ * C4x Specific Information:
+ *
+ * If we decide to have a separate floating point context, then
+ * the answer is the size of the data structure. Otherwise, we
+ * need to define it as 0 to let upper level configuration work.
+ */
+
+#if ( C4X_HAS_FPU == 1 )
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+#else
+#define CPU_CONTEXT_FP_SIZE 0
+#endif
+
+/*
+ * Amount of extra stack (above minimum stack size) required by
+ * MPCI receive server thread. Remember that in a multiprocessor
+ * system this thread must exist and be able to process all directives.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+/*
+ * This defines the number of entries in the ISR_Vector_table managed
+ * by RTEMS.
+ *
+ * C4x Specific Information:
+ *
+ * Based on the information provided in section 7.6.1 (p. 7-26)
+ * titled "TMS320C30 and TMS320C31 Interrupt Vector Table" and section
+ * 7.6.2 "TMS320C32 Interrupt Vector Table" of the TMS32C3x User's
+ * Guide (rev L, July 1997), vectors are numbered 0x00 - 0x3F. Thus
+ * there are 0x40 or 64 vectors.
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 0x40
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
+
+/*
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level.
+ */
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/*
+ * Should be large enough to run all RTEMS tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+#define CPU_STACK_MINIMUM_SIZE (1024)
+
+/*
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ * As best I can tell, there are no restrictions since this is a word
+ * -- not byte -- oriented archtiecture.
+ */
+
+#define CPU_ALIGNMENT 0
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
+ * then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ *
+ * A CPU_HEAP_ALIGNMENT of 2 comes close to disabling all the rounding
+ * while still ensuring that the least significant bit of the front
+ * and back flags can be used as the used bit -- not part of the size.
+ */
+
+#define CPU_HEAP_ALIGNMENT 2
+
+/*
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
+ * enough for the partition, then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ * I think a CPU_PARTITION_ALIGNMENT of 1 will effectively disable all
+ * the rounding.
+ */
+
+#define CPU_PARTITION_ALIGNMENT 1
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * stack. This alignment requirement may be stricter than that for the
+ * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
+ * is strict enough for the stack, then this should be set to 0.
+ *
+ * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+#define CPU_STACK_ALIGNMENT 0
+
+/*
+ * ISR handler macros
+ *
+ * C4x Specific Information:
+ *
+ * These macros disable interrupts using the GIE (global interrupts enable)
+ * bit in the status word.
+ */
+
+/*
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ */
+
+#define _CPU_Initialize_vectors()
+
+/*
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in _isr_cookie.
+ */
+
+#define _CPU_ISR_Disable( _isr_cookie ) \
+ do { \
+ (_isr_cookie) = c4x_global_interrupts_get(); \
+ c4x_global_interrupts_disable(); \
+ } while (0)
+
+/*
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * _isr_cookie is not modified.
+ */
+
+#define _CPU_ISR_Enable( _isr_cookie ) \
+ c4x_global_interrupts_restore( _isr_cookie )
+
+/*
+ * This temporarily restores the interrupt to _isr_cookie before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _isr_cookie is not
+ * modified.
+ */
+
+#define _CPU_ISR_Flash( _isr_cookie ) \
+ c4x_global_interrupts_flash( _isr_cookie )
+
+/*
+ * Map interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a generic fashion are undefined. Someday,
+ * it would be nice if these were "mapped" by the application
+ * via a callout. For example, m68k has 8 levels 0 - 7, levels
+ * 8 - 255 would be available for bsp/application specific meaning.
+ * This could be used to manage a programmable interrupt controller
+ * via the rtems_task_mode directive.
+ *
+ * The get routine usually must be implemented as a subroutine.
+ *
+ * C4x Specific Information:
+ *
+ * The C4x port probably needs to allow the BSP to define
+ * a mask table for all values 0-255. For now, 0 is global
+ * interrupts enabled and and non-zero is global interrupts
+ * disabled. In the future, values 1-254 could be defined as
+ * specific combinations of the global interrupt enabled and the IE mask.
+ *
+ * The logic for setting the mask field is something like this:
+ * _ie_value = c4x_get_ie();
+ * _ie_value &= C4X_IE_INTERRUPT_MASK_BITS;
+ * _ie_value |= _ie_mask;
+ * c4x_set_ie(_ie_value);
+ *
+ * NOTE: If this is implemented, then the context of each task
+ * must be extended to include the IE register.
+ */
+
+#define _CPU_ISR_Set_level( _new_level ) \
+ do { \
+ if ( _new_level == 0 ) c4x_global_interrupts_enable(); \
+ else c4x_global_interrupts_disable(); \
+ } while (0)
+
+/* if GIE = 1, then logical level is 0. */
+#define _CPU_ISR_Get_level() \
+ (c4x_global_interrupts_get() ? 0 : 1)
+
+
+/* end of ISR handler macros */
+
+/* Context handler macros */
+
+/*
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * This routine generally does not set any unnecessary register
+ * in the context. The state of the "general data" registers is
+ * undefined at task start time.
+ *
+ * NOTE: This is_fp parameter is TRUE if the thread is to be a floating
+ * point thread. This is typically only used on CPUs where the
+ * FPU may be easily disabled by software such as on the SPARC
+ * where the PSR contains an enable FPU bit.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+void _CPU_Context_Initialize(
+ Context_Control *_the_context,
+ void *_stack_base,
+ uint32_t _size,
+ uint32_t _isr,
+ void (*_entry_point)(void),
+ int _is_fp
+);
+
+/*
+ * This routine is responsible for somehow restarting the currently
+ * executing task. If you are lucky, then all that is necessary
+ * is restoring the context. Otherwise, there will need to be
+ * a special assembly routine which does something special in this
+ * case. Context_Restore should work most of the time. It will
+ * not work if restarting self conflicts with the stack frame
+ * assumptions of restoring a context.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+#if ( C4X_HAS_FPU == 1 )
+/*
+ * The purpose of this macro is to allow the initial pointer into
+ * a floating point context area (used to save the floating point
+ * context) to be at an arbitrary place in the floating point
+ * context area.
+ *
+ * This is necessary because some FP units are designed to have
+ * their context saved as a stack which grows into lower addresses.
+ * Other FP units can be saved by simply moving registers into offsets
+ * from the base of the context area. Finally some FP units provide
+ * a "dump context" instruction which could fill in from high to low
+ * or low to high based on the whim of the CPU designers.
+ *
+ * C4x Specific Information:
+ *
+ * No Floating Point from RTEMS perspective.
+ */
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
+#endif
+
+#if ( C4X_HAS_FPU == 1 )
+/*
+ * This routine initializes the FP context area passed to it to.
+ * There are a few standard ways in which to initialize the
+ * floating point context. The code included for this macro assumes
+ * that this is a CPU in which a "initial" FP context was saved into
+ * _CPU_Null_fp_context and it simply copies it to the destination
+ * context passed to it.
+ *
+ * Other models include (1) not doing anything, and (2) putting
+ * a "null FP status word" in the correct place in the FP context.
+ *
+ * C4x Specific Information:
+ *
+ * No Floating Point from RTEMS perspective.
+ */
+
+#define _CPU_Context_Initialize_fp( _destination ) \
+ do { \
+ *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
+ } while (0)
+#endif
+
+/* end of Context handler macros */
+
+/* Fatal Error manager macros */
+
+/*
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+#define _CPU_Fatal_halt( _error ) \
+ do { \
+ } while (0)
+
+/* end of Fatal Error manager macros */
+
+/* Bitfield handler macros */
+
+/*
+ * This routine sets _output to the bit number of the first bit
+ * set in _value. _value is of CPU dependent type Priority_Bit_map_control.
+ * This type may be either 16 or 32 bits wide although only the 16
+ * least significant bits will be used.
+ *
+ * There are a number of variables in using a "find first bit" type
+ * instruction.
+ *
+ * (1) What happens when run on a value of zero?
+ * (2) Bits may be numbered from MSB to LSB or vice-versa.
+ * (3) The numbering may be zero or one based.
+ * (4) The "find first bit" instruction may search from MSB or LSB.
+ *
+ * RTEMS guarantees that (1) will never happen so it is not a concern.
+ * (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
+ * _CPU_Priority_bits_index(). These three form a set of routines
+ * which must logically operate together. Bits in the _value are
+ * set and cleared based on masks built by _CPU_Priority_mask().
+ * The basic major and minor values calculated by _Priority_Major()
+ * and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
+ * to properly range between the values returned by the "find first bit"
+ * instruction. This makes it possible for _Priority_Get_highest() to
+ * calculate the major and directly index into the minor table.
+ * This mapping is necessary to ensure that 0 (a high priority major/minor)
+ * is the first bit found.
+ *
+ * This entire "find first bit" and mapping process depends heavily
+ * on the manner in which a priority is broken into a major and minor
+ * components with the major being the 4 MSB of a priority and minor
+ * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
+ * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next
+ * to the lowest priority.
+ *
+ * If your CPU does not have a "find first bit" instruction, then
+ * there are ways to make do without it. Here are a handful of ways
+ * to implement this in software:
+ *
+ * - a series of 16 bit test instructions
+ * - a "binary search using if's"
+ * - _number = 0
+ * if _value > 0x00ff
+ * _value >>=8
+ * _number = 8;
+ *
+ * if _value > 0x0000f
+ * _value >=8
+ * _number += 4
+ *
+ * _number += bit_set_table[ _value ]
+ *
+ * where bit_set_table[ 16 ] has values which indicate the first
+ * bit set
+ *
+ * C4x Specific Information:
+ *
+ * There does not appear to be a simple way to do this on this
+ * processor family that is better than the generic algorithm.
+ * Almost certainly, a hand-optimized assembly version of the
+ * generic algorithm could be written although it is not
+ * worth the development effort at this time.
+ */
+
+#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ do { \
+ (_output) = 0; /* do something to prevent warnings */ \
+ } while (0)
+
+#endif
+
+/* end of Bitfield handler macros */
+
+/*
+ * This routine builds the mask which corresponds to the bit fields
+ * as searched by _CPU_Bitfield_Find_first_bit(). See the discussion
+ * for that routine.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_Mask( _bit_number ) \
+ ( 1 << (_bit_number) )
+
+#endif
+
+/*
+ * This routine translates the bit numbers returned by
+ * _CPU_Bitfield_Find_first_bit() into something suitable for use as
+ * a major or minor component of a priority. See the discussion
+ * for that routine.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_bits_index( _priority ) \
+ (_priority)
+
+#endif
+
+/* end of Priority handler macros */
+
+/* functions */
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/*
+ * _CPU_ISR_install_raw_handler
+ *
+ * This routine installs a "raw" interrupt handler directly into the
+ * processor's vector table.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_Thread_Idle_body
+ *
+ * This routine is the CPU dependent IDLE thread body.
+ *
+ * NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ * is TRUE.
+ */
+
+#if (CPU_PROVIDES_IDLE_THREAD_BODY == 1)
+void _CPU_Thread_Idle_body( void );
+#endif
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally 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.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ *
+ * C4x Specific Information:
+ *
+ * No Floating Point from RTEMS perspective.
+ */
+
+#if ( C4X_HAS_FPU == 1 )
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+#endif
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ *
+ * C4x Specific Information:
+ *
+ * No Floating Point from RTEMS perspective.
+ */
+
+#if ( C4X_HAS_FPU == 1 )
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+#endif
+
+/* The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * This version will work on any processor, but if there is a better
+ * way for your CPU PLEASE use it. The most common way to do this is to:
+ *
+ * swap least significant two bytes with 16-bit rotate
+ * swap upper and lower 16-bits
+ * swap most significant two bytes with 16-bit rotate
+ *
+ * Some CPUs have special instructions which swap a 32-bit quantity in
+ * a single instruction (e.g. i486). It is probably best to avoid
+ * an "endian swapping control bit" in the CPU. One good reason is
+ * that interrupts would probably have to be disabled to ensure that
+ * an interrupt does not try to access the same "chunk" with the wrong
+ * endian. Another good reason is that on some CPUs, the endian bit
+ * endianness for ALL fetches -- both code and data -- so the code
+ * will be fetched incorrectly.
+ *
+ * C4x Specific Information:
+ *
+ * XXXanswer
+ */
+
+static inline uint32_t CPU_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t byte1, byte2, byte3, byte4, swapped;
+
+ byte4 = (value >> 24) & 0xff;
+ byte3 = (value >> 16) & 0xff;
+ byte2 = (value >> 8) & 0xff;
+ byte1 = value & 0xff;
+
+ swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
+ return( swapped );
+}
+
+#define CPU_swap_u16( value ) \
+ (((value&0xff) << 8) | ((value >> 8)&0xff))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/c4x/rtems/score/cpu_asm.h b/cpukit/score/cpu/c4x/rtems/score/cpu_asm.h
new file mode 100644
index 0000000000..a509b36ae6
--- /dev/null
+++ b/cpukit/score/cpu/c4x/rtems/score/cpu_asm.h
@@ -0,0 +1,72 @@
+/**
+ * @file rtems/score/cpu_asm.h
+ */
+
+/*
+ * Very loose template for an include file for the cpu_asm.? file
+ * if it is implemented as a ".S" file (preprocessed by cpp) instead
+ * of a ".s" file (preprocessed by gm4 or gasp).
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef _RTEMS_SCORE_CPU_ASM_H
+#define _RTEMS_SCORE_CPU_ASM_H
+
+/* pull in the generated offsets */
+
+#include <rtems/score/offsets.h>
+
+/*
+ * Hardware General Registers
+ */
+
+/* put something here */
+
+/*
+ * Hardware Floating Point Registers
+ */
+
+/* put something here */
+
+/*
+ * Hardware Control Registers
+ */
+
+/* put something here */
+
+/*
+ * Calling Convention
+ */
+
+/* put something here */
+
+/*
+ * Temporary registers
+ */
+
+/* put something here */
+
+/*
+ * Floating Point Registers - SW Conventions
+ */
+
+/* put something here */
+
+/*
+ * Temporary floating point registers
+ */
+
+/* put something here */
+
+#endif
+
+/* end of file */
diff --git a/cpukit/score/cpu/c4x/rtems/score/types.h b/cpukit/score/cpu/c4x/rtems/score/types.h
new file mode 100644
index 0000000000..e4ac80fa02
--- /dev/null
+++ b/cpukit/score/cpu/c4x/rtems/score/types.h
@@ -0,0 +1,54 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains type definitions pertaining to the
+ * Texas Instruments C4x processor family.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+
+typedef uint16_t Priority_Bit_map_control;
+
+typedef signed long long signed64; /* 64 bit signed integer */
+
+typedef uint32_t boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void c4x_isr;
+typedef void ( *c4x_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/c4x/rtems/tic4x/c4xio.h b/cpukit/score/cpu/c4x/rtems/tic4x/c4xio.h
new file mode 100644
index 0000000000..d3715b9c69
--- /dev/null
+++ b/cpukit/score/cpu/c4x/rtems/tic4x/c4xio.h
@@ -0,0 +1,110 @@
+/*
+ * C4X IO Information
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_TIC4X_C4XIO_H
+#define _RTEMS_TIC4X_C4XIO_H
+
+/*
+ * Address defines
+ */
+
+#ifdef _TMS320C40
+#define C4X_TIMER_0 ((struct c4x_timer*)0x100020)
+#else
+#define C4X_TIMER_0 ((struct c4x_timer*)0x808020)
+#define C4X_TIMER_1 ((struct c4x_timer*)0x808030)
+#endif
+
+/* XXX how portable */
+
+/* C32 Internal Control Registers */
+#define C4X_STRB0_REG 0x808064
+#define C4X_STRB1_REG 0x808068
+#define C4X_IOSTRB_REG 0x808060
+
+/* C32 Internal RAM Locations */
+/* XXX how long */
+#define C4X_RAM_BLK_0 0x87fe00
+#define C4X_RAM_BLK_1 0x87ff00
+
+/*
+ * Data Structures to Overlay the Peripherals on the CPU
+ */
+
+struct c4x_timer {
+ volatile int tcontrol;
+ volatile int r1[3];
+ volatile int tcounter;
+ volatile int r2[3];
+ volatile int tperiod;
+};
+
+
+
+
+/*
+ * Timer Support Routines
+ *
+ * The following section of C4x timer code is based on C40 specific
+ * timer code from Ran Cabell <rcabell@norfolk.infi.net>. The
+ * only C3x/C4x difference spotted was the address of the timer.
+ * The names have been changed to be more RTEMS like.
+ */
+
+#define c4x_timer_get_control( _timer ) (volatile int)(_timer->tcontrol)
+
+#define c4x_timer_set_control( _timer, _value ) \
+ do { \
+ (volatile int)(_timer->tcontrol) = _value; \
+ } while (0);
+
+#define c4x_timer_start( _timer ) \
+ c4x_timer_set_control(_timer, 0x02c1 )
+
+#define c4x_timer_stop( _timer ) _timer->tcontrol = 0
+
+#define c4x_timer_get_counter( _timer ) (volatile int)(_timer->tcounter)
+
+#define c4x_timer_set_counter( _timer, _value ) \
+ do { \
+ (volatile int)(_timer->tcounter) = _value; \
+ } while (0);
+
+#define c4x_timer_get_period( _timer ) (volatile int)(_timer->tperiod)
+
+#define c4x_timer_set_period( _timer, _value ) \
+ do { \
+ (volatile int)(_timer->tperiod) = _value; \
+ } while (0);
+
+/*
+ * IO Flags
+ *
+ * NOTE: iof on c3x, iiof on c4x
+ */
+
+#ifdef _TMS320C40
+
+#else
+
+static inline uint32_t c3x_get_iof( void )
+{
+ register uint32_t iof_value;
+
+ __asm__ volatile ("ldi iof, %0" : "=r" (iof_value));
+ return iof_value;
+}
+
+static inline void c3x_set_iof( uint32_t value )
+{
+ __asm__ volatile ("ldi %0,iof" : : "g" (value) : "iof", "cc");
+}
+
+#endif
+
+
+#endif
+/* end if include file */
diff --git a/cpukit/score/cpu/h8300/.cvsignore b/cpukit/score/cpu/h8300/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/h8300/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/h8300/ChangeLog b/cpukit/score/cpu/h8300/ChangeLog
new file mode 100644
index 0000000000..2ab126b563
--- /dev/null
+++ b/cpukit/score/cpu/h8300/ChangeLog
@@ -0,0 +1,338 @@
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Part of a large patch to improve Doxygen output.
+ As a side-effect, grammar and spelling errors were corrected, spacing
+ errors were address, and some variable names were improved.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16, unsigned32.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h: Remove private version of CONCAT macros.
+ Include <rtems/concat.h> instead.
+
+2005-02-19 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Remove traces from NO_CPU.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/cpu.h, rtems/score/h8300.h,
+ rtems/score/types.h: New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/h8300.h: Remove RTEMS_CPU_HAS_16_BIT_ADDRESSES.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: #include <rtems/stdint.h>.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove build-variant support.
+
+2004-12-10 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 733/rtems
+ * rtems/score/cpu.h: Remove output arg from inline asm in
+ _CPU_ISR_Disable.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Use __rtems_score_types_h as preprocessor
+ guard.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * asm.h: Add doxygen preamble.
+
+2004-10-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Add doxygen preamble.
+ * rtems/score/h8300.h: Add doxygen preamble.
+ * rtems/score/types.h: Add doxygen preamble.
+
+2004-09-29 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: i960 obsoleted and all references removed.
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Remove (Merged into $(top_srcdir)/configure.ac).
+ * Makefile.am: Don't include multilib.am.
+ Reflect merging configure.ac into $(top_srcdir)/configure.ac.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Install asm.h to $(includedir)/rtems.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu.c, rtems/score/cpu.h: Convert to using c99 fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: RTEMS_TOP([../../../..]).
+
+2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Move RTEMS_TOP one subdir down.
+
+2004-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add PREINSTALL_DIRS.
+
+2004-01-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Re-add dirstamps to PREINSTALL_FILES.
+ Add PREINSTALL_FILES to CLEANFILES.
+
+2004-01-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Requires automake >= 1.8.1.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, again.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Convert to using automake compilation rules.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use mkdir_p. Remove dirs from PREINSTALL_FILES.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require automake >= 1.8, autoconf >= 2.59.
+
+2003-12-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Remove TMPINSTALL_FILES.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Don't use gmake rules for preinstallation.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CANONICAL_HOST.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CPU.
+
+2003-09-26 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Obsoleting HP PA-RISC port and removing all
+ references.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * asm.h, cpu.c, cpu_asm.S, rtems/score/cpu.h, rtems/score/h8300.h,
+ rtems/score/types.h: URL for license changed.
+
+2003-08-14 Joel Sherrill <joel@OARcorp.com>
+
+ PR 455/bsps
+ * rtems/score/cpu.h: Added missing CPU_swap_u16().
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require autoconf-2.57 + automake-1.7.2.
+ * Makefile.am: Eliminate C_O_FILES, S_O_FILES, libscorecpu_a_OBJECTS.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix package name.
+
+2002-11-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/cpu.h: Add prototype of H8BD_Install_IRQ to eliminate
+ warning.
+
+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-07-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use .$(OBJEXT) instead of .o.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use . instead of .o.
+
+2002-07-05 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Filled in something that was marked XXX.
+
+2002-07-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: RTEMS_TOP(../../../..).
+
+2002-07-04 Joel Sherrill <joel@OARcorp.com>
+
+ * Makefile.am: Remove reference to deprecated rtems.c.
+
+2002-07-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems.c: Remove.
+ * Makefile.am: Reflect changes above.
+
+2002-07-01 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Fixed comments and renamed
+ CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK to
+ CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK to be consistent with other code.
+
+2002-07-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_PROJECT_ROOT.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add RTEMS_PROG_CCAS
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AC_CONFIG_AUX_DIR(../../../..).
+ Add AC_PROG_RANLIB.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/../../../automake/*.am.
+ Use ../../../aclocal.
+
+2001-04-03 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
+ * rtems/score/h8300types.h: Removed.
+ * rtems/score/types.h: New file via CVS magic.
+ * Makefile.am, 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.
+
+2002-01-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/Makefile.am: Removed.
+ * rtems/score/Makefile.am: Removed.
+ * configure.ac: Reflect changes above.
+ * Makefile.am: Reflect changes above.
+
+2002-01-07 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/cpu.h: #include <rtems/bspIo.h>.
+
+2001-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add multilib support.
+
+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.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/Makefile.am: Use 'PREINSTALL_FILES ='.
+ * Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, rtems/score/Makefile.am:
+ Apply include_*HEADERS instead of H_FILES.
+
+2001-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Added _CPU_Initialize_vectors().
+ * cpu_asm.S: Modify to properly dereference _ISR_Vector_table
+ now that it is dynamically allocated.
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
+ Switch to GNU canonicalization.
+
+2000-10-18 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu_asm.S, rtems/score/cpu.h: Modified to better support
+ multilibing. These changes result in the code being able to
+ compile with the default gcc settings. It is not functional
+ in this configuration but does compile.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am.
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: New file.
diff --git a/cpukit/score/cpu/h8300/Makefile.am b/cpukit/score/cpu/h8300/Makefile.am
new file mode 100644
index 0000000000..e3a0692391
--- /dev/null
+++ b/cpukit/score/cpu/h8300/Makefile.am
@@ -0,0 +1,19 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/h8300.h \
+ rtems/score/types.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/h8300/README b/cpukit/score/cpu/h8300/README
new file mode 100644
index 0000000000..a55c61c662
--- /dev/null
+++ b/cpukit/score/cpu/h8300/README
@@ -0,0 +1,31 @@
+#
+# $Id$
+#
+
+
+This port was done by Philip Quaife <philip@qs.co.nz> of Q Solutions
+using RTEMS 3.5.1 under DOS and Hiview. Philip used an H8300H
+to develop and test this port.
+
+It was updated to 4.5 and merged into the main development trunk
+by Joel Sherrill <joel@OARcorp.com>. As part of the merger, the
+port was made to conditionally compile for the H8, H8300H, and H8300S
+series.
+
+The status of each CPU subfamily is as follows.
+
+H8 - Although RTEMS compiles with for these CPUs, it does not
+ truly support them. All code that will not work on these
+ CPUs is conditionally disabled. These CPUs have a 16-bit
+ address space. Thus although a port is technically
+ feasible, some work will to be performed on RTEMS to
+ further minimize its footprint and address pointer
+ manipulation issues.
+
+H8H - Port was developed on this class of H8 so there should be
+ no problems.
+
+H8S - Port should work on this class of H8 but it is untested.
+
+--joel
+28 June 2000
diff --git a/cpukit/score/cpu/h8300/cpu.c b/cpukit/score/cpu/h8300/cpu.c
new file mode 100644
index 0000000000..f49978bb55
--- /dev/null
+++ b/cpukit/score/cpu/h8300/cpu.c
@@ -0,0 +1,174 @@
+/*
+ * Hitachi H8300 CPU Dependent Source
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/wkspace.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 */
+)
+{
+ /*
+ * The thread_dispatch argument is the address of the entry point
+ * for the routine called at the end of an ISR once it has been
+ * decided a context switch is necessary. On some compilation
+ * systems it is difficult to call a high-level language routine
+ * from assembly. This allows us to trick these systems.
+ *
+ * If you encounter this problem save the entry point in a CPU
+ * dependent variable.
+ */
+
+ _CPU_Thread_dispatch_pointer = thread_dispatch;
+
+ /*
+ * If there is not an easy way to initialize the FP context
+ * during Context_Initialize, then it is usually easier to
+ * save an "uninitialized" FP context here and copy it to
+ * the task's during Context_Initialize.
+ */
+
+ /* FP context initialization support goes here */
+
+ _CPU_Table = *cpu_table;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Get_level
+ *
+ * This routine returns the current interrupt level.
+ */
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ unsigned int _ccr;
+
+#if defined(__H8300__)
+#warning "How do we get ccr on base CPU models"
+#else
+ asm volatile ( "stc ccr, %0" : "=m" (_ccr) : );
+#endif
+
+ if ( _ccr & 0x80 )
+ return 1;
+ return 0;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_install_raw_handler
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ /*
+ * This is where we install the interrupt handler into the "raw" interrupt
+ * table used by the CPU to dispatch interrupt handlers.
+ * Use Debug level IRQ Handlers
+ */
+ H8BD_Install_IRQ(vector,new_handler,old_handler);
+}
+
+/*PAGE
+ *
+ * _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(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ *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.
+ */
+
+ _CPU_ISR_install_raw_handler( vector, new_handler, old_handler );
+
+ /*
+ * 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;
+}
+
+/*PAGE
+ *
+ * _CPU_Install_interrupt_stack
+ */
+
+void _CPU_Install_interrupt_stack( void )
+{
+}
+
+/*PAGE
+ *
+ * _CPU_Thread_Idle_body
+ *
+ * NOTES:
+ *
+ * 1. This is the same as the regular CPU independent algorithm.
+ *
+ * 2. If you implement this using a "halt", "idle", or "shutdown"
+ * instruction, then don't forget to put it in an infinite loop.
+ *
+ * 3. Be warned. Some processors with onboard DMA have been known
+ * to stop the DMA if the CPU were put in IDLE mode. This might
+ * also be a problem with other on-chip peripherals. So use this
+ * hook with caution.
+ */
+
+#if 0
+void _CPU_Thread_Idle_body( void )
+{
+
+ for( ; ; )
+ IDLE_Monitor();
+ /*asm(" sleep \n"); */
+ /* insert your "halt" instruction here */ ;
+}
+#endif
diff --git a/cpukit/score/cpu/h8300/cpu_asm.S b/cpukit/score/cpu/h8300/cpu_asm.S
new file mode 100644
index 0000000000..e006e015f4
--- /dev/null
+++ b/cpukit/score/cpu/h8300/cpu_asm.S
@@ -0,0 +1,224 @@
+/*
+ * Hitachi H8 Score CPU functions
+ * Copyright Comnet Technologies Ltd 1999
+ *
+ * Based on example code and other ports with this copyright:
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+
+;.equ RUNCONTEXT_ARG, er0
+;.equ HEIRCONTEXT_ARG, er1
+
+/*
+ * Make sure we tell the assembler what type of CPU model we are
+ * being compiled for.
+ */
+
+#if defined(__H8300H__)
+ .h8300h
+#endif
+#if defined(__H8300S__)
+ .h8300s
+#endif
+ .text
+
+ .text
+/*
+ GCC Compiled with optimisations and Wimplicit decs to ensure
+ that stack from doesn't change
+
+ Supposedly R2 and R3 do not need to be saved but who knows
+
+ Arg1 = er0 (not on stack)
+ Arg2 = er1 (not on stack)
+*/
+
+ .align 2
+
+ .global __CPU_Context_switch
+
+__CPU_Context_switch:
+ /* Save Context */
+#if defined(__H8300H__) || defined(__H8300S__)
+ stc.w ccr,@(0:16,er0)
+ mov.l er7,@(2:16,er0)
+ mov.l er6,@(6:16,er0)
+ mov.l er5,@(10:16,er0)
+ mov.l er4,@(14:16,er0)
+ mov.l er3,@(18:16,er0)
+ mov.l er2,@(22:16,er0)
+
+ /* Install New context */
+
+restore:
+ mov.l @(22:16,er1),er2
+ mov.l @(18:16,er1),er3
+ mov.l @(14:16,er1),er4
+ mov.l @(10:16,er1),er5
+ mov.l @(6:16,er1),er6
+ mov.l @(2:16,er1),er7
+ ldc.w @(0:16,er1),ccr
+#endif
+
+ rts
+
+ .align 2
+
+ .global __CPU_Context_restore
+
+__CPU_Context_restore:
+
+#if defined(__H8300H__) || defined(__H8300S__)
+ mov.l er0,er1
+ jmp @restore:24
+#endif
+
+
+
+/*
+ VHandler for Vectored Interrupts
+
+ All IRQ's are vectored to routine _ISR_#vector_number
+ This routine stacks er0 and loads er0 with vector number
+ before transferring to here
+
+*/
+ .align 2
+ .global __ISR_Handler
+ .extern __ISR_Nest_level
+ .extern __Vector_table
+ .extern __Context_switch_necessary
+
+
+__ISR_Handler:
+#if defined(__H8300H__) || defined(__H8300S__)
+ mov.l er1,@-er7
+ mov.l er2,@-er7
+ mov.l er3,@-er7
+ mov.l er4,@-er7
+ mov.l er5,@-er7
+ mov.l er6,@-er7
+
+/* Set IRQ Stack */
+ orc #0xc0,ccr
+ mov.l er7,er6 ; save stack pointer
+ mov.l @__ISR_Nest_level,er1
+ bne nested
+ mov.l @__CPU_Interrupt_stack_high,er7
+
+nested:
+ mov.l er6,@-er7 ; save sp so pop regardless of nest level
+
+;; Inc system counters
+ mov.l @__ISR_Nest_level,er1
+ inc.l #1,er1
+ mov.l er1,@__ISR_Nest_level
+ mov.l @__Thread_Dispatch_disable_level,er1
+ inc.l #1,er1
+ mov.l er1,@__Thread_Dispatch_disable_level
+
+/* Vector to ISR */
+
+ mov.l @__ISR_Vector_table,er1
+ mov er0,er2 ; copy vector
+ shll.l er2
+ shll.l er2 ; vector = vector * 4 (sizeof(int))
+ add.l er2,er1
+ mov.l @er1,er1
+ jsr @er1 ; er0 = arg1 =vector
+
+ orc #0xc0,ccr
+ mov.l @__ISR_Nest_level,er1
+ dec.l #1,er1
+ mov.l er1,@__ISR_Nest_level
+ mov.l @__Thread_Dispatch_disable_level,er1
+ dec.l #1,er1
+ mov.l er1,@__Thread_Dispatch_disable_level
+ bne exit
+
+ mov.l @__Context_Switch_necessary,er1
+ bne bframe ; If yes then dispatch next task
+
+ mov.l @__ISR_Signals_to_thread_executing,er1
+ beq exit ; If no signals waiting
+
+ /* Context switch here through ISR_Dispatch */
+
+bframe:
+ orc #0xc0,ccr
+/* Pop Stack */
+ mov @er7+,er6
+ mov er6,er7
+ mov.l #0,er2
+ mov.l er2,@__ISR_Signals_to_thread_executing
+
+ /* Set up IRQ stack frame and dispatch to _ISR_Dispatch */
+
+ mov.l #0xc0000000,er2 /* Disable IRQ */
+ or.l #_ISR_Dispatch,er2
+ mov.l er2,@-er7
+ rte
+
+/* Inner IRQ Return, pop flags and return */
+exit:
+/* Pop Stack */
+ orc #0x80,ccr
+ mov @er7+,er6
+ mov er6,er7
+ mov @er7+,er6
+ mov @er7+,er5
+ mov @er7+,er4
+ mov @er7+,er3
+ mov @er7+,er2
+ mov @er7+,er1
+ mov @er7+,er0
+#endif
+ rte
+
+/*
+ Called from ISR_Handler as a way of ending IRQ
+ but allowing dispatch to another task.
+ Must use RTE as CCR is still on stack but IRQ has been serviced.
+ CCR and PC occupy same word so rte can be used.
+ now using task stack
+*/
+
+ .align 2
+ .global _ISR_Dispatch
+
+_ISR_Dispatch:
+
+#if defined(__H8300H__) || defined(__H8300S__)
+ jsr @__Thread_Dispatch
+ mov @er7+,er6
+ mov @er7+,er5
+ mov @er7+,er4
+ mov @er7+,er3
+ mov @er7+,er2
+ mov @er7+,er1
+ mov @er7+,er0
+#endif
+ rte
+
+
+ .align 2
+ .global __CPU_Context_save_fp
+
+__CPU_Context_save_fp:
+ rts
+
+
+ .align 2
+ .global __CPU_Context_restore_fp
+
+__CPU_Context_restore_fp:
+ rts
diff --git a/cpukit/score/cpu/h8300/preinstall.am b/cpukit/score/cpu/h8300/preinstall.am
new file mode 100644
index 0000000000..51f8a16f5d
--- /dev/null
+++ b/cpukit/score/cpu/h8300/preinstall.am
@@ -0,0 +1,41 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/h8300.h: rtems/score/h8300.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/h8300.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/h8300.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
diff --git a/cpukit/score/cpu/h8300/rtems/asm.h b/cpukit/score/cpu/h8300/rtems/asm.h
new file mode 100644
index 0000000000..da3b80aeb7
--- /dev/null
+++ b/cpukit/score/cpu/h8300/rtems/asm.h
@@ -0,0 +1,120 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ */
+
+/*
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#define ASM
+#include <rtems/score/h8300.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/*
+ * define macros for all of the registers on this CPU
+ *
+ * EXAMPLE: #define d0 REG (d0)
+ */
+#define r0 REG(r0)
+#define r1 REG(r1)
+#define r2 REG(r2)
+#define r3 REG(r3)
+#define r4 REG(r4)
+#define r5 REG(r5)
+#define r6 REG(r6)
+#define r7 REG(r7)
+
+#define er0 REG(er0)
+#define er1 REG(er1)
+#define er2 REG(er2)
+#define er3 REG(er3)
+#define er4 REG(er4)
+#define er5 REG(er5)
+#define er6 REG(er6)
+#define er7 REG(er7)
+
+#define sp REG(sp)
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE asm ( ".text
+#define END_CODE ");
+#define BEGIN_DATA
+#define END_DATA
+#define BEGIN_BSS
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .globl SYM (sym)
+#define EXTERN(sym) .globl SYM (sym)
+
+#endif
+
+ asm( \".h8300h\" );
diff --git a/cpukit/score/cpu/h8300/rtems/score/cpu.h b/cpukit/score/cpu/h8300/rtems/score/cpu.h
new file mode 100644
index 0000000000..c7f3b3c77b
--- /dev/null
+++ b/cpukit/score/cpu/h8300/rtems/score/cpu.h
@@ -0,0 +1,1188 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * This include file contains information pertaining to the H8300
+ * processor.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/h8300.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+
+#include <rtems/bspIo.h> /* printk */
+
+/* conditional compilation parameters */
+
+/*
+ * Should the calls to _Thread_Enable_dispatch be inlined?
+ *
+ * If TRUE, then they are inlined.
+ * If FALSE, then a subroutine call is made.
+ *
+ * Basically this is an example of the classic trade-off of size
+ * versus speed. Inlining the call (TRUE) typically increases the
+ * size of RTEMS while speeding up the enabling of dispatching.
+ * [NOTE: In general, the _Thread_Dispatch_disable_level will
+ * only be 0 or 1 unless you are in an interrupt handler and that
+ * interrupt handler invokes the executive.] When not inlined
+ * something calls _Thread_Enable_dispatch which in turns calls
+ * _Thread_Dispatch. If the enable dispatch is inlined, then
+ * one subroutine call is avoided entirely.]
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_INLINE_ENABLE_DISPATCH FALSE
+
+/*
+ * Should the body of the search loops in _Thread_queue_Enqueue_priority
+ * be unrolled one time? In unrolled each iteration of the loop examines
+ * two "nodes" on the chain being searched. Otherwise, only one node
+ * is examined per iteration.
+ *
+ * If TRUE, then the loops are unrolled.
+ * If FALSE, then the loops are not unrolled.
+ *
+ * The primary factor in making this decision is the cost of disabling
+ * and enabling interrupts (_ISR_Flash) versus the cost of rest of the
+ * body of the loop. On some CPUs, the flash is more expensive than
+ * one iteration of the loop body. In this case, it might be desirable
+ * to unroll the loop. It is important to note that on some CPUs, this
+ * code is the longest interrupt disable period in RTEMS. So it is
+ * necessary to strike a balance when setting this parameter.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
+
+/*
+ * Does RTEMS manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in _ISR_Handler_initialization.
+ * If FALSE, nothing is done.
+ *
+ * If the CPU supports a dedicated interrupt stack in hardware,
+ * then it is generally the responsibility of the BSP to allocate it
+ * and set it up.
+ *
+ * If the CPU does not support a dedicated interrupt stack, then
+ * the porter has two options: (1) execute interrupts on the
+ * stack of the interrupted task, and (2) have RTEMS manage a dedicated
+ * interrupt stack.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
+
+/*
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * If TRUE, then it must be installed during initialization.
+ * If FALSE, then no installation is performed.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
+
+/*
+ * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * If TRUE, then the memory is allocated during initialization.
+ * If FALSE, then the memory is allocated during initialization.
+ *
+ * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
+
+/*
+ * Does the CPU have hardware floating point?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
+ *
+ * If there is a FP coprocessor such as the i387 or mc68881, then
+ * the answer is TRUE.
+ *
+ * The macro name "H8300_HAS_FPU" should be made CPU specific.
+ * It indicates whether or not this CPU model has FP support. For
+ * example, it would be possible to have an i386_nofp CPU model
+ * which set this to false to indicate that you have an i386 without
+ * an i387 and wish to leave floating point support out of RTEMS.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_HARDWARE_FP FALSE
+
+/*
+ * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
+ *
+ * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_ALL_TASKS_ARE_FP FALSE
+
+/*
+ * Should the IDLE task have a floating point context?
+ *
+ * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * If FALSE, then the IDLE task does not have a floating point context.
+ *
+ * Setting this to TRUE negatively impacts the time required to preempt
+ * the IDLE task from an interrupt because the floating point context
+ * must be saved as part of the preemption.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+/*
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ *
+ * If the floating point context does NOT have to be saved as part of
+ * interrupt dispatching, then it should be safe to set this to TRUE.
+ *
+ * Setting this flag to TRUE results in using a different algorithm
+ * for deciding when to save and restore the floating point context.
+ * The deferred FP switch algorithm minimizes the number of times
+ * the FP context is saved and restored. The FP context is not saved
+ * until a context switch is made to another, different FP task.
+ * Thus in a system with only one FP task, the FP context will never
+ * be saved or restored.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+/*
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine _CPU_Internal_threads_Idle_thread_body
+ * must be provided and is the default IDLE thread body instead of
+ * _Internal_threads_Idle_thread_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ *
+ * This is intended to allow for supporting processors which have
+ * a low power or idle mode. When the IDLE thread is executed, then
+ * the CPU can be powered down.
+ *
+ * The order of precedence for selecting the IDLE thread body is:
+ *
+ * 1. BSP provided
+ * 2. CPU dependent (if provided)
+ * 3. generic (if no BSP and no CPU dependent)
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ * The port initially called a BSP dependent routine called
+ * IDLE_Monitor. The idle task body can be overridden by
+ * the BSP in newer versions of RTEMS.
+ */
+
+#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
+
+/*
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * If TRUE, then the grows upward.
+ * If FALSE, then the grows toward smaller addresses.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_STACK_GROWS_UP FALSE
+
+/*
+ * The following is the variable attribute used to force alignment
+ * of critical RTEMS structures. On some processors it may make
+ * sense to have these aligned on tighter boundaries than
+ * the minimum requirements of the compiler in order to have as
+ * much of the critical data area as possible in a cache line.
+ *
+ * The placement of this macro in the declaration of the variables
+ * is based on the syntactically requirements of the GNU C
+ * "__attribute__" extension. For example with GNU C, use
+ * the following to force a structures to a 32 byte boundary.
+ *
+ * __attribute__ ((aligned (32)))
+ *
+ * NOTE: Currently only the Priority Bit Map table uses this feature.
+ * To benefit from using this, the data must be heavily
+ * used so it will stay in the cache and used frequently enough
+ * in the executive to justify turning this on.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_STRUCTURE_ALIGNMENT
+
+/*
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ */
+
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+#define CPU_BIG_ENDIAN TRUE
+#define CPU_LITTLE_ENDIAN FALSE
+
+/*
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_MODES_INTERRUPT_MASK 0x00000001
+
+/*
+ * Processor defined structures required for cpukit/score.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+/* may need to put some structures here. */
+
+/*
+ * Contexts
+ *
+ * Generally there are 2 types of context to save.
+ * 1. Interrupt registers to save
+ * 2. Task level registers to save
+ *
+ * This means we have the following 3 context items:
+ * 1. task level context stuff:: Context_Control
+ * 2. floating point task stuff:: Context_Control_fp
+ * 3. special interrupt level context :: Context_Control_interrupt
+ *
+ * On some processors, it is cost-effective to save only the callee
+ * preserved registers during a task context switch. This means
+ * that the ISR code needs to save those registers which do not
+ * persist across function calls. It is not mandatory to make this
+ * distinctions between the caller/callee saves registers for the
+ * purpose of minimizing context saved during task switch and on interrupts.
+ * If the cost of saving extra registers is minimal, simplicity is the
+ * choice. Save the same context on interrupt entry as for tasks in
+ * this case.
+ *
+ * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
+ * care should be used in designing the context area.
+ *
+ * On some CPUs with hardware floating point support, the Context_Control_fp
+ * structure will not be used or it simply consist of an array of a
+ * fixed number of bytes. This is done when the floating point context
+ * is dumped by a "FP save context" type instruction and the format
+ * is not really defined by the CPU. In this case, there is no need
+ * to figure out the exact format -- only the size. Of course, although
+ * this is enough information for RTEMS, it is probably not enough for
+ * a debugger such as gdb. But that is another problem.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+
+
+#define nogap __attribute__ ((packed))
+
+typedef struct {
+ uint16_t ccr nogap;
+ void *er7 nogap;
+ void *er6 nogap;
+ uint32_t er5 nogap;
+ uint32_t er4 nogap;
+ uint32_t er3 nogap;
+ uint32_t er2 nogap;
+ uint32_t er1 nogap;
+ uint32_t er0 nogap;
+ uint32_t xxx nogap;
+} Context_Control;
+
+typedef struct {
+ double some_float_register[2];
+} Context_Control_fp;
+
+typedef struct {
+ uint32_t special_interrupt_register;
+} CPU_Interrupt_frame;
+
+
+/*
+ * The following table contains the information required to configure
+ * the XXX processor specific parameters.
+ *
+ * NOTE: The interrupt_stack_size field is required if
+ * CPU_ALLOCATE_INTERRUPT_STACK is defined as TRUE.
+ *
+ * The pretasking_hook, predriver_hook, and postdriver_hook,
+ * and the do_zero_of_workspace fields are required on ALL CPUs.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+} rtems_cpu_table;
+
+/*
+ * This variable is optional. It is used on CPUs on which it is difficult
+ * to generate an "uninitialized" FP context. It is filled in by
+ * _CPU_Initialize and copied into the task's FP context area during
+ * _CPU_Context_Initialize.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
+
+/*
+ * On some CPUs, RTEMS supports a software managed interrupt stack.
+ * This stack is allocated by the Interrupt Manager and the switch
+ * is performed in _ISR_Handler. These variables contain pointers
+ * to the lowest and highest addresses in the chunk of memory allocated
+ * for the interrupt stack. Since it is unknown whether the stack
+ * grows up or down (in general), this give the CPU dependent
+ * code the option of picking the version it wants to use.
+ *
+ * NOTE: These two variables are required if the macro
+ * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+/*
+ * With some compilation systems, it is difficult if not impossible to
+ * call a high-level language routine from assembly language. This
+ * is especially true of commercial Ada compilers and name mangling
+ * C++ ones. This variable can be optionally defined by the CPU porter
+ * and contains the address of the routine _Thread_Dispatch. This
+ * can make it easier to invoke that routine at the end of the interrupt
+ * sequence (if a dispatch is necessary).
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
+
+/*
+ * Nothing prevents the porter from declaring more CPU specific variables.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+/* XXX: if needed, put more variables here */
+
+/*
+ * The size of the floating point context area. On some CPUs this
+ * will not be a "sizeof" because the format of the floating point
+ * area is not defined -- only the size is. This is usually on
+ * CPUs with a "floating point save context" instruction.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/*
+ * Amount of extra stack (above minimum stack size) required by
+ * system initialization thread. Remember that in a multiprocessor
+ * system the system intialization thread becomes the MP server thread.
+ *
+ * H8300 Specific Information:
+ *
+ * It is highly unlikely the H8300 will get used in a multiprocessor system.
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+/*
+ * This defines the number of entries in the ISR_Vector_table managed
+ * by RTEMS.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 64
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
+
+/*
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level.
+ */
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/*
+ * Should be large enough to run all RTEMS tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_STACK_MINIMUM_SIZE (1536)
+
+/*
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_ALIGNMENT 8
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
+ * then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
+ * enough for the partition, then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * stack. This alignment requirement may be stricter than that for the
+ * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
+ * is strict enough for the stack, then this should be set to 0.
+ *
+ * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_STACK_ALIGNMENT 2
+
+/*
+ * ISR handler macros
+ */
+
+/*
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ */
+
+#define _CPU_Initialize_vectors()
+
+/* COPE With Brain dead version of GCC distributed with Hitachi HIView Tools.
+ Note requires ISR_Level be uint16_t or assembler croaks.
+*/
+
+#if (__GNUC__ == 2 && __GNUC_MINOR__ == 7 )
+
+
+/*
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in _level.
+ */
+
+#define _CPU_ISR_Disable( _isr_cookie ) \
+ do { \
+ asm volatile( "stc.w ccr, @-er7 ;\n orc #0xC0,ccr ;\n mov.w @er7+,%0" : : "r" (_isr_cookie) ); \
+ } while (0)
+
+
+/*
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * _level is not modified.
+ */
+
+
+#define _CPU_ISR_Enable( _isr_cookie ) \
+ do { \
+ asm volatile( "mov.w %0,@-er7 ;\n ldc.w @er7+, ccr" : : "r" (_isr_cookie) ); \
+ } while (0)
+
+
+/*
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ */
+
+
+#define _CPU_ISR_Flash( _isr_cookie ) \
+ do { \
+ asm volatile( "mov.w %0,@-er7 ;\n ldc.w @er7+, ccr ;\n orc #0xC0,ccr" : : "r" (_isr_cookie) ); \
+ } while (0)
+
+/* end of ISR handler macros */
+
+#else /* modern gcc version */
+
+/*
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in _level.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#if defined(__H8300H__) || defined(__H8300S__)
+#define _CPU_ISR_Disable( _isr_cookie ) \
+ do { \
+ unsigned char __ccr; \
+ asm volatile( "stc ccr, %0 ; orc #0x80,ccr " \
+ : "=m" (__ccr) /* : "0" (__ccr) */ ); \
+ (_isr_cookie) = __ccr; \
+ } while (0)
+#else
+#define _CPU_ISR_Disable( _isr_cookie ) (_isr_cookie) = 0
+#endif
+
+
+/*
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * _level is not modified.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#if defined(__H8300H__) || defined(__H8300S__)
+#define _CPU_ISR_Enable( _isr_cookie ) \
+ do { \
+ unsigned char __ccr = (unsigned char) (_isr_cookie); \
+ asm volatile( "ldc %0, ccr" : : "m" (__ccr) ); \
+ } while (0)
+#else
+#define _CPU_ISR_Enable( _isr_cookie )
+#endif
+
+/*
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#if defined(__H8300H__) || defined(__H8300S__)
+#define _CPU_ISR_Flash( _isr_cookie ) \
+ do { \
+ unsigned char __ccr = (unsigned char) (_isr_cookie); \
+ asm volatile( "ldc %0, ccr ; orc #0x80,ccr " : : "m" (__ccr) ); \
+ } while (0)
+#else
+#define _CPU_ISR_Flash( _isr_cookie )
+#endif
+
+#endif /* end of old gcc */
+
+
+/*
+ * Map interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a generic fashion are undefined. Someday,
+ * it would be nice if these were "mapped" by the application
+ * via a callout. For example, m68k has 8 levels 0 - 7, levels
+ * 8 - 255 would be available for bsp/application specific meaning.
+ * This could be used to manage a programmable interrupt controller
+ * via the rtems_task_mode directive.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define _CPU_ISR_Set_level( _new_level ) \
+ { \
+ if ( _new_level ) asm volatile ( "orc #0x80,ccr\n" ); \
+ else asm volatile ( "andc #0x7f,ccr\n" ); \
+ }
+
+uint32_t _CPU_ISR_Get_level( void );
+
+/* end of ISR handler macros */
+
+/* Context handler macros */
+
+/*
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * This routine generally does not set any unnecessary register
+ * in the context. The state of the "general data" registers is
+ * undefined at task start time.
+ *
+ * NOTE: This is_fp parameter is TRUE if the thread is to be a floating
+ * point thread. This is typically only used on CPUs where the
+ * FPU may be easily disabled by software such as on the SPARC
+ * where the PSR contains an enable FPU bit.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+
+#define CPU_CCR_INTERRUPTS_ON 0x80
+#define CPU_CCR_INTERRUPTS_OFF 0x00
+
+#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
+ _isr, _entry_point, _is_fp ) \
+ /* Locate Me */ \
+ do { \
+ uint32_t _stack; \
+ \
+ if ( (_isr) ) (_the_context)->ccr = CPU_CCR_INTERRUPTS_OFF; \
+ else (_the_context)->ccr = CPU_CCR_INTERRUPTS_ON; \
+ \
+ _stack = ((uint32_t )(_stack_base)) + (_size) - 4; \
+ *((proc_ptr *)(_stack)) = (_entry_point); \
+ (_the_context)->er7 = (void *) _stack; \
+ (_the_context)->er6 = (void *) _stack; \
+ (_the_context)->er5 = 0; \
+ (_the_context)->er4 = 1; \
+ (_the_context)->er3 = 2; \
+ } while (0)
+
+
+/*
+ * This routine is responsible for somehow restarting the currently
+ * executing task. If you are lucky, then all that is necessary
+ * is restoring the context. Otherwise, there will need to be
+ * a special assembly routine which does something special in this
+ * case. Context_Restore should work most of the time. It will
+ * not work if restarting self conflicts with the stack frame
+ * assumptions of restoring a context.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+/*
+ * The purpose of this macro is to allow the initial pointer into
+ * a floating point context area (used to save the floating point
+ * context) to be at an arbitrary place in the floating point
+ * context area.
+ *
+ * This is necessary because some FP units are designed to have
+ * their context saved as a stack which grows into lower addresses.
+ * Other FP units can be saved by simply moving registers into offsets
+ * from the base of the context area. Finally some FP units provide
+ * a "dump context" instruction which could fill in from high to low
+ * or low to high based on the whim of the CPU designers.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) (_base) + (_offset) )
+
+/*
+ * This routine initializes the FP context area passed to it to.
+ * There are a few standard ways in which to initialize the
+ * floating point context. The code included for this macro assumes
+ * that this is a CPU in which a "initial" FP context was saved into
+ * _CPU_Null_fp_context and it simply copies it to the destination
+ * context passed to it.
+ *
+ * Other models include (1) not doing anything, and (2) putting
+ * a "null FP status word" in the correct place in the FP context.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define _CPU_Context_Initialize_fp( _destination ) \
+ { \
+ *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
+ }
+
+/* end of Context handler macros */
+
+/* Fatal Error manager macros */
+
+/*
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define _CPU_Fatal_halt( _error ) \
+ printk("Fatal Error %d Halted\n",_error); \
+ for(;;)
+
+
+/* end of Fatal Error manager macros */
+
+/* Bitfield handler macros */
+
+/*
+ * This routine sets _output to the bit number of the first bit
+ * set in _value. _value is of CPU dependent type Priority_Bit_map_control.
+ * This type may be either 16 or 32 bits wide although only the 16
+ * least significant bits will be used.
+ *
+ * There are a number of variables in using a "find first bit" type
+ * instruction.
+ *
+ * (1) What happens when run on a value of zero?
+ * (2) Bits may be numbered from MSB to LSB or vice-versa.
+ * (3) The numbering may be zero or one based.
+ * (4) The "find first bit" instruction may search from MSB or LSB.
+ *
+ * RTEMS guarantees that (1) will never happen so it is not a concern.
+ * (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
+ * _CPU_Priority_bits_index(). These three form a set of routines
+ * which must logically operate together. Bits in the _value are
+ * set and cleared based on masks built by _CPU_Priority_mask().
+ * The basic major and minor values calculated by _Priority_Major()
+ * and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
+ * to properly range between the values returned by the "find first bit"
+ * instruction. This makes it possible for _Priority_Get_highest() to
+ * calculate the major and directly index into the minor table.
+ * This mapping is necessary to ensure that 0 (a high priority major/minor)
+ * is the first bit found.
+ *
+ * This entire "find first bit" and mapping process depends heavily
+ * on the manner in which a priority is broken into a major and minor
+ * components with the major being the 4 MSB of a priority and minor
+ * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
+ * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next
+ * to the lowest priority.
+ *
+ * If your CPU does not have a "find first bit" instruction, then
+ * there are ways to make do without it. Here are a handful of ways
+ * to implement this in software:
+ *
+ * - a series of 16 bit test instructions
+ * - a "binary search using if's"
+ * - _number = 0
+ * if _value > 0x00ff
+ * _value >>=8
+ * _number = 8;
+ *
+ * if _value > 0x0000f
+ * _value >=8
+ * _number += 4
+ *
+ * _number += bit_set_table[ _value ]
+ *
+ * where bit_set_table[ 16 ] has values which indicate the first
+ * bit set
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ (_output) = 0; /* do something to prevent warnings */ \
+ }
+
+#endif
+
+/* end of Bitfield handler macros */
+
+/*
+ * This routine builds the mask which corresponds to the bit fields
+ * as searched by _CPU_Bitfield_Find_first_bit(). See the discussion
+ * for that routine.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_Mask( _bit_number ) \
+ ( 1 << (_bit_number) )
+
+#endif
+
+/*
+ * This routine translates the bit numbers returned by
+ * _CPU_Bitfield_Find_first_bit() into something suitable for use as
+ * a major or minor component of a priority. See the discussion
+ * for that routine.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_bits_index( _priority ) \
+ (_priority)
+
+#endif
+
+/* end of Priority handler macros */
+
+/* functions */
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/*
+ * _CPU_ISR_install_raw_handler
+ *
+ * This routine installs a "raw" interrupt handler directly into the
+ * processor's vector table.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_Install_interrupt_stack
+ *
+ * This routine installs the hardware interrupt stack pointer.
+ *
+ * NOTE: It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK
+ * is TRUE.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+void _CPU_Install_interrupt_stack( void );
+
+/*
+ * _CPU_Internal_threads_Idle_thread_body
+ *
+ * This routine is the CPU dependent IDLE thread body.
+ *
+ * NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
+ * is TRUE.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+void _CPU_Thread_Idle_body( void );
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _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.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ *
+ * H8300 Specific Information:
+ *
+ * XXX
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+/* The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * This version will work on any processor, but if there is a better
+ * way for your CPU PLEASE use it. The most common way to do this is to:
+ *
+ * swap least significant two bytes with 16-bit rotate
+ * swap upper and lower 16-bits
+ * swap most significant two bytes with 16-bit rotate
+ *
+ * Some CPUs have special instructions which swap a 32-bit quantity in
+ * a single instruction (e.g. i486). It is probably best to avoid
+ * an "endian swapping control bit" in the CPU. One good reason is
+ * that interrupts would probably have to be disabled to ensure that
+ * an interrupt does not try to access the same "chunk" with the wrong
+ * endian. Another good reason is that on some CPUs, the endian bit
+ * endianness for ALL fetches -- both code and data -- so the code
+ * will be fetched incorrectly.
+ *
+ * H8300 Specific Information:
+ *
+ * This is the generic implementation.
+ */
+
+static inline uint32_t CPU_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t byte1, byte2, byte3, byte4, swapped;
+
+ byte4 = (value >> 24) & 0xff;
+ byte3 = (value >> 16) & 0xff;
+ byte2 = (value >> 8) & 0xff;
+ byte1 = value & 0xff;
+
+ swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
+ return( swapped );
+}
+
+#define CPU_swap_u16( value ) \
+ (((value&0xff) << 8) | ((value >> 8)&0xff))
+
+/* to be provided by the BSP */
+extern void H8BD_Install_IRQ(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/h8300/rtems/score/h8300.h b/cpukit/score/cpu/h8300/rtems/score/h8300.h
new file mode 100644
index 0000000000..4abb36bbb2
--- /dev/null
+++ b/cpukit/score/cpu/h8300/rtems/score/h8300.h
@@ -0,0 +1,43 @@
+/**
+ * @file rtems/score/h8300.h
+ */
+
+/*
+ * This file contains information pertaining to the Hitachi H8/300
+ * processor family.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_H8300_H
+#define _RTEMS_SCORE_H8300_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the "h8300"
+ * family when executing in protected mode. It does
+ * this by setting variables to indicate which implementation
+ * dependent features are present in a particular member
+ * of the family.
+ */
+
+#define CPU_NAME "Hitachi H8300"
+#define CPU_MODEL_NAME "h8300"
+#define H8300_HAS_FPU 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/h8300/rtems/score/types.h b/cpukit/score/cpu/h8300/rtems/score/types.h
new file mode 100644
index 0000000000..33d9420ebe
--- /dev/null
+++ b/cpukit/score/cpu/h8300/rtems/score/types.h
@@ -0,0 +1,54 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains type definitions pertaining to the Hitachi
+ * h8300 processor family.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+
+typedef uint16_t Priority_Bit_map_control;
+
+typedef signed long long signed64; /* 64 bit signed integer */
+
+typedef uint32_t boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void h8300_isr;
+typedef void ( *h8300_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/i386/.cvsignore b/cpukit/score/cpu/i386/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/i386/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/i386/ChangeLog b/cpukit/score/cpu/i386/ChangeLog
new file mode 100644
index 0000000000..2316547971
--- /dev/null
+++ b/cpukit/score/cpu/i386/ChangeLog
@@ -0,0 +1,349 @@
+2006-02-01 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Increase default stack size on i386 from 1K to 4K.
+ Most i386 targets are not memory strapped so making this a bit large
+ is not a burden. It lets more tests run. ticker and psxtimer will not
+ even run with 1K of stack.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16, unsigned32.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h: Remove private version of CONCAT macros.
+ Include <rtems/concat.h> instead.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/cpu.h, rtems/score/i386.h, rtems/score/idtr.h,
+ rtems/score/interrupts.h, rtems/score/registers.h,
+ rtems/score/types.h: New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/i386.h: *_swap_u32( uint32_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/i386.h: *_swap_u16( uint16_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: #include <rtems/stdint.h>.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove build-variant support.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Use __rtems_score_types_h as preprocessor
+ guard.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * asm.h: Add doxygen preamble.
+
+2004-10-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Add doxygen preamble.
+ * rtems/score/i386.h: Add doxygen preamble.
+ * rtems/score/idtr.h: Add doxygen preamble.
+ * rtems/score/interrupts.h: Add doxygen preamble.
+ * rtems/score/registers.h: Add doxygen preamble.
+ * rtems/score/types.h: Add doxygen preamble.
+
+2004-04-16 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/i386.h: Rename i386_swap_U* to i386_swap_u* (API
+ consistency with other ports).
+
+2004-04-09 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu_asm.S: Convert asm comments to C-comments to prevent gcc-3.4.0pre
+ from choking on them.
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Remove (Merged into $(top_srcdir)/configure.ac).
+ * Makefile.am: Don't include multilib.am.
+ Reflect merging configure.ac into $(top_srcdir)/configure.ac.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Install asm.h to $(includedir)/rtems.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu_asm.S: Include <rtems/asm.h> instead of <asm.h>.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu.c, cpu_asm.S, rtems/score/cpu.h, rtems/score/interrupts.h:
+ Convert to using c99 fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: RTEMS_TOP([../../../..]).
+
+2004-02-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR 565/rtems
+ * asm.h: Various hacks.
+
+2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Move RTEMS_TOP one subdir down.
+
+2004-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add PREINSTALL_DIRS.
+
+2004-01-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Re-add dirstamps to PREINSTALL_FILES.
+ Add PREINSTALL_FILES to CLEANFILES.
+
+2004-01-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Requires automake >= 1.8.1.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, again.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Convert to using automake compilation rules.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use mkdir_p. Remove dirs from PREINSTALL_FILES.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require automake >= 1.8, autoconf >= 2.59.
+
+2003-12-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Remove TMPINSTALL_FILES.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Don't use gmake rules for preinstallation.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CANONICAL_HOST.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CPU.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, cpu_asm.S, rtems/score/cpu.h, rtems/score/i386.h,
+ rtems/score/idtr.h, rtems/score/interrupts.h,
+ rtems/score/registers.h, rtems/score/types.h: URL for license
+ changed.
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require autoconf-2.57 + automake-1.7.2.
+ * Makefile.am: Eliminate C_O_FILES, S_O_FILES, libscorecpu_a_OBJECTS.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix package name.
+
+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-07-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use .$(OBJEXT) instead of .o.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use . instead of .o.
+
+2002-07-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: RTEMS_TOP(../../../..).
+
+2002-07-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems.S: Remove.
+ * Makefile.am: Reflect changes above.
+
+2002-07-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_PROJECT_ROOT.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add RTEMS_PROG_CCAS
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AC_CONFIG_AUX_DIR(../../../..).
+ Add AC_PROG_RANLIB.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/../../../automake/*.am.
+ Use ../../../aclocal.
+
+2002-03-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/idtr.h: New file, extracted from libcpu/cpu.h.
+ * rtems/score/interrupts.h: New file, extracted from libcpu/cpu.h.
+ * rtems/score/registers.h: New file, moved from libcpu.
+ * Makefile.am: Reflect changes above.
+ * cpu.c: Don't include cpuModel.h,
+ #include <rtems.h>,
+ #include <rtems/score/i386types.h>,
+ #include <rtems/score/idtr.h>.
+ * rtems/score/cpu.h: Don't include libcpu/cpu.h.
+ #include <rtems/score/interrupts.h>,
+ #include <rtems/score/registers.h>.
+
+2001-04-03 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
+ * rtems/score/i386types.h: Removed.
+ * rtems/score/types.h: New file via CVS magic.
+ * Makefile.am, 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-02-05 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/Makefile.am, rtems/score/Makefile.am: Removed again.
+
+2002-01-31 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/Makefile.am: Removed.
+ * rtems/score/Makefile.am: Removed.
+ * configure.ac: Reflect changes above.
+ * Makefile.am: Reflect changes above.
+
+2001-01-30 Joel Sherrill <joel@OARcorp.com>
+
+ * Makefile.am: Corrected so .h files from rtems/score/ are installed.
+
+2002-01-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * cpu.c: Include rtems/bspIo.h instead of bspIo.h.
+
+2001-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add multilib support.
+
+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.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/Makefile.am: Use 'PREINSTALL_FILES ='.
+ * Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, rtems/score/Makefile.am:
+ Apply include_*HEADERS instead of H_FILES.
+
+2001-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Added _CPU_Initialize_vectors().
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
+ Switch to GNU canonicalization.
+
+2000-09-12 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/i386.h: Corrected "#elsif" to be "#elif".
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am.
+
+2000-08-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/i386.h: cpu-variant define handling
+ Rewrite due to introduction of multilib defines.
+ * asm.h: include cpuopts.h instead of targopts.h
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: New file.
diff --git a/cpukit/score/cpu/i386/Makefile.am b/cpukit/score/cpu/i386/Makefile.am
new file mode 100644
index 0000000000..f6c8e7f6d7
--- /dev/null
+++ b/cpukit/score/cpu/i386/Makefile.am
@@ -0,0 +1,20 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS= rtems/asm.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/i386.h \
+ rtems/score/types.h rtems/score/interrupts.h rtems/score/registers.h \
+ rtems/score/idtr.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/i386/cpu.c b/cpukit/score/cpu/i386/cpu.c
new file mode 100644
index 0000000000..d9f1e1aa47
--- /dev/null
+++ b/cpukit/score/cpu/i386/cpu.c
@@ -0,0 +1,197 @@
+/*
+ * Intel i386 Dependent Source
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <rtems/system.h>
+#include <rtems/score/types.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/idtr.h>
+
+#include <rtems/bspIo.h>
+#include <rtems/score/thread.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 */
+)
+{
+#if CPU_HARDWARE_FP
+ register uint16_t fp_status asm ("ax");
+ register void *fp_context;
+#endif
+
+ _CPU_Table = *cpu_table;
+
+ /*
+ * The following code saves a NULL i387 context which is given
+ * to each task at start and restart time. The following code
+ * is based upon that provided in the i386 Programmer's
+ * Manual and should work on any coprocessor greater than
+ * the i80287.
+ *
+ * NOTE: The NO WAIT form of the coprocessor instructions
+ * MUST be used in case there is not a coprocessor
+ * to wait for.
+ */
+
+#if CPU_HARDWARE_FP
+ fp_status = 0xa5a5;
+ asm volatile( "fninit" );
+ asm volatile( "fnstsw %0" : "=a" (fp_status) : "0" (fp_status) );
+
+ if ( fp_status == 0 ) {
+
+ fp_context = &_CPU_Null_fp_context;
+
+ asm volatile( "fsave (%0)" : "=r" (fp_context)
+ : "0" (fp_context)
+ );
+ }
+#endif
+
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Get_level
+ */
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ uint32_t level;
+
+ i386_get_interrupt_level( level );
+
+ return level;
+}
+
+void _CPU_Thread_Idle_body ()
+{
+ while(1){
+ asm volatile ("hlt");
+ }
+}
+
+void _defaultExcHandler (CPU_Exception_frame *ctx)
+{
+ unsigned int faultAddr = 0;
+ printk("----------------------------------------------------------\n");
+ printk("Exception %d caught at PC %x by thread %d\n",
+ ctx->idtIndex,
+ ctx->eip,
+ _Thread_Executing->Object.id);
+ printk("----------------------------------------------------------\n");
+ printk("Processor execution context at time of the fault was :\n");
+ printk("----------------------------------------------------------\n");
+ printk(" EAX = %x EBX = %x ECX = %x EDX = %x\n",
+ ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
+ printk(" ESI = %x EDI = %x EBP = %x ESP = %x\n",
+ ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
+ printk("----------------------------------------------------------\n");
+ printk("Error code pushed by processor itself (if not 0) = %x\n",
+ ctx->faultCode);
+ printk("----------------------------------------------------------\n");
+ if (ctx->idtIndex == I386_EXCEPTION_PAGE_FAULT){
+ faultAddr = i386_get_cr2();
+ printk("Page fault linear address (CR2) = %x\n", faultAddr);
+ printk("----------------------------------------------------------\n\n");
+ }
+ if (_ISR_Nest_level > 0) {
+ /*
+ * In this case we shall not delete the task interrupted as
+ * it has nothing to do with the fault. We cannot return either
+ * because the eip points to the faulty instruction so...
+ */
+ printk("Exception while executing ISR!!!. System locked\n");
+ _CPU_Fatal_halt(faultAddr);
+ }
+ else {
+ /*
+ * OK I could probably use a simplified version but at least this
+ * should work.
+ */
+ printk(" ************ FAULTY THREAD WILL BE DELETED **************\n");
+ rtems_task_delete(_Thread_Executing->Object.id);
+ }
+}
+
+cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
+
+extern void rtems_exception_prologue_0();
+extern void rtems_exception_prologue_1();
+extern void rtems_exception_prologue_2();
+extern void rtems_exception_prologue_3();
+extern void rtems_exception_prologue_4();
+extern void rtems_exception_prologue_5();
+extern void rtems_exception_prologue_6();
+extern void rtems_exception_prologue_7();
+extern void rtems_exception_prologue_8();
+extern void rtems_exception_prologue_9();
+extern void rtems_exception_prologue_10();
+extern void rtems_exception_prologue_11();
+extern void rtems_exception_prologue_12();
+extern void rtems_exception_prologue_13();
+extern void rtems_exception_prologue_14();
+extern void rtems_exception_prologue_16();
+extern void rtems_exception_prologue_17();
+extern void rtems_exception_prologue_18();
+
+static rtems_raw_irq_hdl tbl[] = {
+ rtems_exception_prologue_0,
+ rtems_exception_prologue_1,
+ rtems_exception_prologue_2,
+ rtems_exception_prologue_3,
+ rtems_exception_prologue_4,
+ rtems_exception_prologue_5,
+ rtems_exception_prologue_6,
+ rtems_exception_prologue_7,
+ rtems_exception_prologue_8,
+ rtems_exception_prologue_9,
+ rtems_exception_prologue_10,
+ rtems_exception_prologue_11,
+ rtems_exception_prologue_12,
+ rtems_exception_prologue_13,
+ rtems_exception_prologue_14,
+ rtems_exception_prologue_16,
+ rtems_exception_prologue_17,
+ rtems_exception_prologue_18,
+};
+
+void rtems_exception_init_mngt()
+{
+ unsigned int i,j;
+ interrupt_gate_descriptor *currentIdtEntry;
+ unsigned limit;
+ unsigned level;
+
+ i = sizeof(tbl) / sizeof (rtems_raw_irq_hdl);
+
+ i386_get_info_from_IDTR (&currentIdtEntry, &limit);
+
+ _CPU_ISR_Disable(level);
+ for (j = 0; j < i; j++) {
+ create_interrupt_gate_descriptor (&currentIdtEntry[j], tbl[j]);
+ }
+ _CPU_ISR_Enable(level);
+}
diff --git a/cpukit/score/cpu/i386/cpu_asm.S b/cpukit/score/cpu/i386/cpu_asm.S
new file mode 100644
index 0000000000..7630aa3b35
--- /dev/null
+++ b/cpukit/score/cpu/i386/cpu_asm.S
@@ -0,0 +1,274 @@
+/* cpu_asm.s
+ *
+ * This file contains all assembly code for the Intel i386 implementation
+ * of RTEMS.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/asm.h>
+
+/*
+ * Format of i386 Register structure
+ */
+
+.set REG_EFLAGS, 0
+.set REG_ESP, REG_EFLAGS + 4
+.set REG_EBP, REG_ESP + 4
+.set REG_EBX, REG_EBP + 4
+.set REG_ESI, REG_EBX + 4
+.set REG_EDI, REG_ESI + 4
+.set SIZE_REGS, REG_EDI + 4
+
+ BEGIN_CODE
+
+/*
+ * void _CPU_Context_switch( run_context, heir_context )
+ *
+ * This routine performs a normal non-FP context.
+ */
+
+ .p2align 1
+ PUBLIC (_CPU_Context_switch)
+
+.set RUNCONTEXT_ARG, 4 /* save context argument */
+.set HEIRCONTEXT_ARG, 8 /* restore context argument */
+
+SYM (_CPU_Context_switch):
+ movl RUNCONTEXT_ARG(esp),eax /* eax = running threads context */
+ pushf /* push eflags */
+ popl REG_EFLAGS(eax) /* save eflags */
+ movl esp,REG_ESP(eax) /* save stack pointer */
+ movl ebp,REG_EBP(eax) /* save base pointer */
+ movl ebx,REG_EBX(eax) /* save ebx */
+ movl esi,REG_ESI(eax) /* save source register */
+ movl edi,REG_EDI(eax) /* save destination register */
+
+ movl HEIRCONTEXT_ARG(esp),eax /* eax = heir threads context */
+
+restore:
+ pushl REG_EFLAGS(eax) /* push eflags */
+ popf /* restore eflags */
+ movl REG_ESP(eax),esp /* restore stack pointer */
+ movl REG_EBP(eax),ebp /* restore base pointer */
+ movl REG_EBX(eax),ebx /* restore ebx */
+ movl REG_ESI(eax),esi /* restore source register */
+ movl REG_EDI(eax),edi /* restore destination register */
+ ret
+
+/*
+ * NOTE: May be unnecessary to reload some registers.
+ */
+
+/*
+ * void _CPU_Context_restore( new_context )
+ *
+ * This routine performs a normal non-FP context.
+ */
+
+ PUBLIC (_CPU_Context_restore)
+
+.set NEWCONTEXT_ARG, 4 /* context to restore argument */
+
+SYM (_CPU_Context_restore):
+
+ movl NEWCONTEXT_ARG(esp),eax /* eax = running threads context */
+ jmp restore
+
+/*PAGE
+ * void _CPU_Context_save_fp_context( &fp_context_ptr )
+ * void _CPU_Context_restore_fp_context( &fp_context_ptr )
+ *
+ * This section is used to context switch an i80287, i80387,
+ * the built-in coprocessor or the i80486 or compatible.
+ */
+
+.set FPCONTEXT_ARG, 4 /* FP context argument */
+
+ .p2align 1
+ PUBLIC (_CPU_Context_save_fp)
+SYM (_CPU_Context_save_fp):
+ movl FPCONTEXT_ARG(esp),eax /* eax = &ptr to FP context area */
+ movl (eax),eax /* eax = FP context area */
+ fsave (eax) /* save FP context */
+ ret
+
+ .p2align 1
+ PUBLIC (_CPU_Context_restore_fp)
+SYM (_CPU_Context_restore_fp):
+ movl FPCONTEXT_ARG(esp),eax /* eax = &ptr to FP context area */
+ movl (eax),eax /* eax = FP context area */
+ frstor (eax) /* restore FP context */
+ ret
+
+ PUBLIC (_Exception_Handler)
+SYM (_Exception_Handler):
+ pusha /* Push general purpose registers */
+ pushl esp /* Push exception frame address */
+ movl _currentExcHandler, eax /* Call function storead in _currentExcHandler */
+ call * eax
+ addl $4, esp
+ popa /* restore general purpose registers */
+ addl $8, esp /* skill vector number and faultCode */
+ iret
+
+#define DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY(_vector) \
+ .p2align 4 ; \
+ PUBLIC (rtems_exception_prologue_ ## _vector ) ; \
+SYM (rtems_exception_prologue_ ## _vector ): \
+ pushl $ _vector ; \
+ jmp SYM (_Exception_Handler) ;
+
+#define DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY(_vector) \
+ .p2align 4 ; \
+ PUBLIC (rtems_exception_prologue_ ## _vector ) ; \
+SYM (rtems_exception_prologue_ ## _vector ): \
+ pushl $ 0 ; \
+ pushl $ _vector ; \
+ jmp SYM (_Exception_Handler) ;
+
+/*
+ * Divide Error
+ */
+DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (0)
+/*
+ * Debug Exception
+ */
+DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (1)
+/*
+ * NMI
+ */
+DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (2)
+/*
+ * Breakpoint
+ */
+DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (3)
+/*
+ * Overflow
+ */
+DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (4)
+/*
+ * Bound Range Exceeded
+ */
+DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (5)
+/*
+ * Invalid Opcode
+ */
+DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (6)
+/*
+ * No Math Coproc
+ */
+DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (7)
+/*
+ * Double Fault
+ */
+DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (8)
+/*
+ * Coprocessor segment overrun
+ */
+DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (9)
+/*
+ * Invalid TSS
+ */
+DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (10)
+/*
+ * Segment Not Present
+ */
+DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (11)
+/*
+ * Stack segment Fault
+ */
+DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (12)
+/*
+ * General Protection Fault
+ */
+DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (13)
+/*
+ * Page Fault
+ */
+DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (14)
+/*
+ * Floating point error (NB 15 is reserved it is therefor skipped)
+ */
+DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (16)
+/*
+ * Aligment Check
+ */
+DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (17)
+/*
+ * Machine Check
+ */
+DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (18)
+
+
+/*
+ * void *i386_Logical_to_physical(
+ * uint16_t segment,
+ * void *address
+ * );
+ *
+ * Returns thirty-two bit physical address for segment:address.
+ */
+
+.set SEGMENT_ARG, 4
+.set ADDRESS_ARG, 8
+
+ PUBLIC (i386_Logical_to_physical)
+
+SYM (i386_Logical_to_physical):
+
+ xorl eax,eax /* clear eax */
+ movzwl SEGMENT_ARG(esp),ecx /* ecx = segment value */
+ movl $ SYM (_Global_descriptor_table),edx
+ /* edx = address of our GDT */
+ addl ecx,edx /* edx = address of desired entry */
+ movb 7(edx),ah /* ah = base 31:24 */
+ movb 4(edx),al /* al = base 23:16 */
+ shll $16,eax /* move ax into correct bits */
+ movw 2(edx),ax /* ax = base 0:15 */
+ movl ADDRESS_ARG(esp),ecx /* ecx = address to convert */
+ addl eax,ecx /* ecx = physical address equivalent */
+ movl ecx,eax /* eax = ecx */
+ ret
+
+/*
+ * void *i386_Physical_to_logical(
+ * uint16_t segment,
+ * void *address
+ * );
+ *
+ * Returns thirty-two bit physical address for segment:address.
+ */
+
+/*
+ *.set SEGMENT_ARG, 4
+ *.set ADDRESS_ARG, 8 -- use sets from above
+ */
+
+ PUBLIC (i386_Physical_to_logical)
+
+SYM (i386_Physical_to_logical):
+ xorl eax,eax /* clear eax */
+ movzwl SEGMENT_ARG(esp),ecx /* ecx = segment value */
+ movl $ SYM (_Global_descriptor_table),edx
+ /* edx = address of our GDT */
+ addl ecx,edx /* edx = address of desired entry */
+ movb 7(edx),ah /* ah = base 31:24 */
+ movb 4(edx),al /* al = base 23:16 */
+ shll $16,eax /* move ax into correct bits */
+ movw 2(edx),ax /* ax = base 0:15 */
+ movl ADDRESS_ARG(esp),ecx /* ecx = address to convert */
+ subl eax,ecx /* ecx = logical address equivalent */
+ movl ecx,eax /* eax = ecx */
+ ret
+
+END_CODE
+
+END
diff --git a/cpukit/score/cpu/i386/preinstall.am b/cpukit/score/cpu/i386/preinstall.am
new file mode 100644
index 0000000000..92d4df2515
--- /dev/null
+++ b/cpukit/score/cpu/i386/preinstall.am
@@ -0,0 +1,53 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/i386.h: rtems/score/i386.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/i386.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/i386.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
+$(PROJECT_INCLUDE)/rtems/score/interrupts.h: rtems/score/interrupts.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/interrupts.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/interrupts.h
+
+$(PROJECT_INCLUDE)/rtems/score/registers.h: rtems/score/registers.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/registers.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/registers.h
+
+$(PROJECT_INCLUDE)/rtems/score/idtr.h: rtems/score/idtr.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/idtr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/idtr.h
+
diff --git a/cpukit/score/cpu/i386/rtems/asm.h b/cpukit/score/cpu/i386/rtems/asm.h
new file mode 100644
index 0000000000..7c6fcad58a
--- /dev/null
+++ b/cpukit/score/cpu/i386/rtems/asm.h
@@ -0,0 +1,138 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ */
+
+/*
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ * COPYRIGHT (c) 1994-1997.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/i386.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__
+#endif
+
+/*
+ * Looks like there is a bug in gcc 2.6.2 where this is not
+ * defined correctly when configured as i386-coff and
+ * i386-aout.
+ */
+
+#undef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__ %
+
+/*
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+*/
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT0 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT0 (__REGISTER_PREFIX__, x)
+
+#define eax REG (eax)
+#define ebx REG (ebx)
+#define ecx REG (ecx)
+#define edx REG (edx)
+#define esi REG (esi)
+#define edi REG (edi)
+#define esp REG (esp)
+#define ebp REG (ebp)
+#define cr0 REG (cr0)
+
+#define ax REG (ax)
+#define bx REG (bx)
+#define cx REG (cx)
+#define dx REG (dx)
+#define si REG (si)
+#define di REG (di)
+#define sp REG (sp)
+#define bp REG (bp)
+
+#define ah REG (ah)
+#define bh REG (bh)
+#define ch REG (ch)
+#define dh REG (dh)
+
+#define al REG (al)
+#define bl REG (bl)
+#define cl REG (cl)
+#define dl REG (dl)
+
+#define cs REG (cs)
+#define ds REG (ds)
+#define es REG (es)
+#define fs REG (fs)
+#define gs REG (gs)
+#define ss REG (ss)
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA .data
+#define END_DATA
+#define BEGIN_BSS .bss
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .globl SYM (sym)
+#define EXTERN(sym) .globl SYM (sym)
+
+#endif
diff --git a/cpukit/score/cpu/i386/rtems/score/cpu.h b/cpukit/score/cpu/i386/rtems/score/cpu.h
new file mode 100644
index 0000000000..3a6188da32
--- /dev/null
+++ b/cpukit/score/cpu/i386/rtems/score/cpu.h
@@ -0,0 +1,515 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * This include file contains information pertaining to the Intel
+ * i386 processor.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/i386.h> /* pick up machine definitions */
+
+#ifndef ASM
+#include <rtems/score/types.h>
+#include <rtems/score/interrupts.h> /* formerly in libcpu/cpu.h> */
+#include <rtems/score/registers.h> /* formerly part of libcpu */
+#endif
+
+/* conditional compilation parameters */
+
+#define CPU_INLINE_ENABLE_DISPATCH TRUE
+#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE
+
+/*
+ * i386 has an RTEMS allocated and managed interrupt stack.
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
+#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
+
+/*
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ */
+
+#define CPU_ISR_PASSES_FRAME_POINTER 0
+
+/*
+ * Some family members have no FP, some have an FPU such as the i387
+ * for the i386, others have it built in (i486DX, Pentium).
+ */
+
+#if ( I386_HAS_FPU == 1 )
+#define CPU_HARDWARE_FP TRUE /* i387 for i386 */
+#else
+#define CPU_HARDWARE_FP FALSE
+#endif
+#define CPU_SOFTWARE_FP FALSE
+
+#define CPU_ALL_TASKS_ARE_FP FALSE
+#define CPU_IDLE_TASK_IS_FP FALSE
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+#define CPU_STACK_GROWS_UP FALSE
+#define CPU_STRUCTURE_ALIGNMENT
+
+/*
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine _CPU_Thread_Idle_body
+ * must be provided and is the default IDLE thread body instead of
+ * _CPU_Thread_Idle_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ */
+
+#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE
+
+/*
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ */
+
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+#define CPU_BIG_ENDIAN FALSE
+#define CPU_LITTLE_ENDIAN TRUE
+
+/* structures */
+
+/*
+ * Basic integer context for the i386 family.
+ */
+
+typedef struct {
+ uint32_t eflags; /* extended flags register */
+ void *esp; /* extended stack pointer register */
+ void *ebp; /* extended base pointer register */
+ uint32_t ebx; /* extended bx register */
+ uint32_t esi; /* extended source index register */
+ uint32_t edi; /* extended destination index flags register */
+} Context_Control;
+
+/*
+ * FP context save area for the i387 numeric coprocessors.
+ */
+
+typedef struct {
+ uint8_t fp_save_area[108]; /* context size area for I80387 */
+ /* 28 bytes for environment */
+} Context_Control_fp;
+
+
+/*
+ * The following structure defines the set of information saved
+ * on the current stack by RTEMS upon receipt of execptions.
+ *
+ * idtIndex is either the interrupt number or the trap/exception number.
+ * faultCode is the code pushed by the processor on some exceptions.
+ */
+
+typedef struct {
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t esp0;
+ uint32_t ebx;
+ uint32_t edx;
+ uint32_t ecx;
+ uint32_t eax;
+ uint32_t idtIndex;
+ uint32_t faultCode;
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t eflags;
+} CPU_Exception_frame;
+
+typedef void (*cpuExcHandlerType) (CPU_Exception_frame*);
+extern cpuExcHandlerType _currentExcHandler;
+extern void rtems_exception_init_mngt();
+
+/*
+ * The following structure defines the set of information saved
+ * on the current stack by RTEMS upon receipt of each interrupt
+ * that will lead to re-enter the kernel to signal the thread.
+ */
+
+typedef CPU_Exception_frame CPU_Interrupt_frame;
+
+typedef enum {
+ I386_EXCEPTION_DIVIDE_BY_ZERO = 0,
+ I386_EXCEPTION_DEBUG = 1,
+ I386_EXCEPTION_NMI = 2,
+ I386_EXCEPTION_BREAKPOINT = 3,
+ I386_EXCEPTION_OVERFLOW = 4,
+ I386_EXCEPTION_BOUND = 5,
+ I386_EXCEPTION_ILLEGAL_INSTR = 6,
+ I386_EXCEPTION_MATH_COPROC_UNAVAIL = 7,
+ I386_EXCEPTION_DOUBLE_FAULT = 8,
+ I386_EXCEPTION_I386_COPROC_SEG_ERR = 9,
+ I386_EXCEPTION_INVALID_TSS = 10,
+ I386_EXCEPTION_SEGMENT_NOT_PRESENT = 11,
+ I386_EXCEPTION_STACK_SEGMENT_FAULT = 12,
+ I386_EXCEPTION_GENERAL_PROT_ERR = 13,
+ I386_EXCEPTION_PAGE_FAULT = 14,
+ I386_EXCEPTION_INTEL_RES15 = 15,
+ I386_EXCEPTION_FLOAT_ERROR = 16,
+ I386_EXCEPTION_ALIGN_CHECK = 17,
+ I386_EXCEPTION_MACHINE_CHECK = 18,
+ I386_EXCEPTION_ENTER_RDBG = 50 /* to enter manually RDBG */
+
+} Intel_symbolic_exception_name;
+
+
+/*
+ * The following table contains the information required to configure
+ * the i386 specific parameters.
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+ /* end of fields required on all CPUs */
+
+ uint32_t interrupt_table_segment;
+ void *interrupt_table_offset;
+} rtems_cpu_table;
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ */
+
+/*
+ * Macros to access i386 specific additions to the CPU Table
+ */
+
+#define rtems_cpu_configuration_get_interrupt_table_segment() \
+ (_CPU_Table.interrupt_table_segment)
+
+#define rtems_cpu_configuration_get_interrupt_table_offset() \
+ (_CPU_Table.interrupt_table_offset)
+
+/*
+ * context size area for floating point
+ *
+ * NOTE: This is out of place on the i386 to avoid a forward reference.
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/* variables */
+
+SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+/* constants */
+
+/*
+ * This defines the number of levels and the mask used to pick those
+ * bits out of a thread mode.
+ */
+
+#define CPU_MODES_INTERRUPT_LEVEL 0x00000001 /* interrupt level in mode */
+#define CPU_MODES_INTERRUPT_MASK 0x00000001 /* interrupt level in mode */
+
+/*
+ * extra stack required by the MPCI receive server thread
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 1024
+
+/*
+ * i386 family supports 256 distinct vectors.
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
+
+/*
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level.
+ */
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/*
+ * Minimum size of a thread's stack.
+ */
+
+#define CPU_STACK_MINIMUM_SIZE 4096
+
+/*
+ * i386 is pretty tolerant of alignment. Just put things on 4 byte boundaries.
+ */
+
+#define CPU_ALIGNMENT 4
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * On i386 thread stacks require no further alignment after allocation
+ * from the Workspace.
+ */
+
+#define CPU_STACK_ALIGNMENT 0
+
+/* macros */
+
+/*
+ * ISR handler macros
+ *
+ * These macros perform the following functions:
+ * + initialize the RTEMS vector table
+ * + disable all maskable CPU interrupts
+ * + restore previous interrupt level (enable)
+ * + temporarily restore interrupts (flash)
+ * + set a particular level
+ */
+
+#define _CPU_Initialize_vectors()
+
+#define _CPU_ISR_Disable( _level ) i386_disable_interrupts( _level )
+
+#define _CPU_ISR_Enable( _level ) i386_enable_interrupts( _level )
+
+#define _CPU_ISR_Flash( _level ) i386_flash_interrupts( _level )
+
+#define _CPU_ISR_Set_level( _new_level ) \
+ { \
+ if ( _new_level ) asm volatile ( "cli" ); \
+ else asm volatile ( "sti" ); \
+ }
+
+uint32_t _CPU_ISR_Get_level( void );
+
+/* end of ISR handler macros */
+
+/*
+ * Context handler macros
+ *
+ * These macros perform the following functions:
+ * + initialize a context area
+ * + restart the current thread
+ * + calculate the initial pointer into a FP context area
+ * + initialize an FP context area
+ */
+
+#define CPU_EFLAGS_INTERRUPTS_ON 0x00003202
+#define CPU_EFLAGS_INTERRUPTS_OFF 0x00003002
+
+#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
+ _isr, _entry_point, _is_fp ) \
+ do { \
+ uint32_t _stack; \
+ \
+ if ( (_isr) ) (_the_context)->eflags = CPU_EFLAGS_INTERRUPTS_OFF; \
+ else (_the_context)->eflags = CPU_EFLAGS_INTERRUPTS_ON; \
+ \
+ _stack = ((uint32_t )(_stack_base)) + (_size) - 4; \
+ \
+ *((proc_ptr *)(_stack)) = (_entry_point); \
+ (_the_context)->ebp = (void *) _stack; \
+ (_the_context)->esp = (void *) _stack; \
+ } while (0)
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
+
+#define _CPU_Context_Initialize_fp( _fp_area ) \
+ { \
+ uint32_t *_source = (uint32_t *) &_CPU_Null_fp_context; \
+ uint32_t *_destination = *(_fp_area); \
+ uint32_t _index; \
+ \
+ for ( _index=0 ; _index < CPU_CONTEXT_FP_SIZE/4 ; _index++ ) \
+ *_destination++ = *_source++; \
+ }
+
+/* end of Context handler macros */
+
+/*
+ * Fatal Error manager macros
+ *
+ * These macros perform the following functions:
+ * + disable interrupts and halt the CPU
+ */
+
+#define _CPU_Fatal_halt( _error ) \
+ { \
+ asm volatile ( "cli ; \
+ movl %0,%%eax ; \
+ hlt" \
+ : "=r" ((_error)) : "0" ((_error)) \
+ ); \
+ }
+
+/* end of Fatal Error manager macros */
+
+/*
+ * Bitfield handler macros
+ *
+ * These macros perform the following functions:
+ * + scan for the highest numbered (MSB) set in a 16 bit bitfield
+ */
+
+#define CPU_USE_GENERIC_BITFIELD_CODE FALSE
+#define CPU_USE_GENERIC_BITFIELD_DATA FALSE
+
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ register uint16_t __value_in_register = (_value); \
+ \
+ _output = 0; \
+ \
+ asm volatile ( "bsfw %0,%1 " \
+ : "=r" (__value_in_register), "=r" (_output) \
+ : "0" (__value_in_register), "1" (_output) \
+ ); \
+ }
+
+/* end of Bitfield handler macros */
+
+/*
+ * Priority handler macros
+ *
+ * These macros perform the following functions:
+ * + return a mask with the bit for this major/minor portion of
+ * of thread priority set.
+ * + translate the bit number returned by "Bitfield_find_first_bit"
+ * into an index into the thread ready chain bit maps
+ */
+
+#define _CPU_Priority_Mask( _bit_number ) \
+ ( 1 << (_bit_number) )
+
+#define _CPU_Priority_bits_index( _priority ) \
+ (_priority)
+
+/* functions */
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/*
+ * _CPU_ISR_install_raw_handler
+ *
+ * This routine installs a "raw" interrupt handler directly into the
+ * processor's vector table.
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_Thread_Idle_body
+ *
+ * Use the halt instruction of low power mode of a particular i386 model.
+ */
+
+#if (CPU_PROVIDES_IDLE_THREAD_BODY == TRUE)
+
+void _CPU_Thread_Idle_body( void );
+
+#endif /* CPU_PROVIDES_IDLE_THREAD_BODY */
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally used only to restart self in an
+ * efficient manner and avoid stack conflicts.
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/i386/rtems/score/i386.h b/cpukit/score/cpu/i386/rtems/score/i386.h
new file mode 100644
index 0000000000..881187091d
--- /dev/null
+++ b/cpukit/score/cpu/i386/rtems/score/i386.h
@@ -0,0 +1,246 @@
+/**
+ * @file rtems/score/i386.h
+ */
+
+/*
+ * This include file contains information pertaining to the Intel
+ * i386 processor.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_I386_H
+#define _RTEMS_SCORE_I386_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section contains the information required to build
+ * RTEMS for a particular member of the Intel i386
+ * family when executing in protected mode. It does
+ * this by setting variables to indicate which implementation
+ * dependent features are present in a particular member
+ * of the family.
+ *
+ * Currently recognized:
+ * i386_fp (i386 DX or SX w/i387)
+ * i386_nofp (i386 DX or SX w/o i387)
+ * i486dx
+ * i486sx
+ * pentium
+ * pentiumpro
+ *
+ * CPU Model Feature Flags:
+ *
+ * I386_HAS_BSWAP: Defined to "1" if the instruction for endian swapping
+ * (bswap) should be used. This instruction appears to
+ * be present in all i486's and above.
+ *
+ * I386_HAS_FPU: Defined to "1" if the CPU has an FPU.
+ *
+ */
+
+#if defined(_SOFT_FLOAT)
+#define I386_HAS_FPU 0
+#else
+#define I386_HAS_FPU 1
+#endif
+
+#if defined(__pentiumpro__)
+
+#define CPU_MODEL_NAME "Pentium Pro"
+
+#elif defined(__i586__)
+
+# if defined(__pentium__)
+# define CPU_MODEL_NAME "Pentium"
+# elif defined(__k6__)
+# define CPU_MODEL_NAME "K6"
+# else
+# define CPU_MODEL_NAME "i586"
+# endif
+
+#elif defined(__i486__)
+
+# if !defined(_SOFT_FLOAT)
+# define CPU_MODEL_NAME "i486dx"
+# else
+# define CPU_MODEL_NAME "i486sx"
+# endif
+
+#elif defined(__i386__)
+
+#define I386_HAS_BSWAP 0
+
+# if !defined(_SOFT_FLOAT)
+# define CPU_MODEL_NAME "i386 with i387"
+# else
+# define CPU_MODEL_NAME "i386 w/o i387"
+# endif
+
+#else
+#error "Unknown CPU Model"
+#endif
+
+/*
+ * Set default values for CPU model feature flags
+ *
+ * NOTE: These settings are chosen to reflect most of the family members.
+ */
+
+#ifndef I386_HAS_FPU
+#define I386_HAS_FPU 1
+#endif
+
+#ifndef I386_HAS_BSWAP
+#define I386_HAS_BSWAP 1
+#endif
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "Intel i386"
+
+#ifndef ASM
+
+/*
+ * The following routine swaps the endian format of an unsigned int.
+ * It must be static so it can be referenced indirectly.
+ */
+
+static inline uint32_t i386_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t lout;
+
+#if (I386_HAS_BSWAP == 0)
+ asm volatile( "rorw $8,%%ax;"
+ "rorl $16,%0;"
+ "rorw $8,%%ax" : "=a" (lout) : "0" (value) );
+#else
+ __asm__ volatile( "bswap %0" : "=r" (lout) : "0" (value));
+#endif
+ return( lout );
+}
+
+static inline uint16_t i386_swap_u16(
+ uint16_t value
+)
+{
+ unsigned short sout;
+
+ __asm__ volatile( "rorw $8,%0" : "=r" (sout) : "0" (value));
+ return (sout);
+}
+
+
+/*
+ * Added for pagination management
+ */
+
+static inline unsigned int i386_get_cr0()
+{
+ register unsigned int segment = 0;
+
+ asm volatile ( "movl %%cr0,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline void i386_set_cr0(unsigned int segment)
+{
+ asm volatile ( "movl %0,%%cr0" : "=r" (segment) : "0" (segment) );
+}
+
+static inline unsigned int i386_get_cr2()
+{
+ register unsigned int segment = 0;
+
+ asm volatile ( "movl %%cr2,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline unsigned int i386_get_cr3()
+{
+ register unsigned int segment = 0;
+
+ asm volatile ( "movl %%cr3,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline void i386_set_cr3(unsigned int segment)
+{
+ asm volatile ( "movl %0,%%cr3" : "=r" (segment) : "0" (segment) );
+}
+
+/* routines */
+
+/*
+ * i386_Logical_to_physical
+ *
+ * Converts logical address to physical address.
+ */
+
+void *i386_Logical_to_physical(
+ unsigned short segment,
+ void *address
+);
+
+/*
+ * i386_Physical_to_logical
+ *
+ * Converts physical address to logical address.
+ */
+
+void *i386_Physical_to_logical(
+ unsigned short segment,
+ void *address
+);
+
+
+/*
+ * "Simpler" names for a lot of the things defined in this file
+ */
+
+/* segment access routines */
+
+#define get_cs() i386_get_cs()
+#define get_ds() i386_get_ds()
+#define get_es() i386_get_es()
+#define get_ss() i386_get_ss()
+#define get_fs() i386_get_fs()
+#define get_gs() i386_get_gs()
+
+#define CPU_swap_u32( _value ) i386_swap_u32( _value )
+#define CPU_swap_u16( _value ) i386_swap_u16( _value )
+
+/* i80x86 I/O instructions */
+
+#define outport_byte( _port, _value ) i386_outport_byte( _port, _value )
+#define outport_word( _port, _value ) i386_outport_word( _port, _value )
+#define outport_long( _port, _value ) i386_outport_long( _port, _value )
+#define inport_byte( _port, _value ) i386_inport_byte( _port, _value )
+#define inport_word( _port, _value ) i386_inport_word( _port, _value )
+#define inport_long( _port, _value ) i386_inport_long( _port, _value )
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/i386/rtems/score/idtr.h b/cpukit/score/cpu/i386/rtems/score/idtr.h
new file mode 100644
index 0000000000..bdc465a622
--- /dev/null
+++ b/cpukit/score/cpu/i386/rtems/score/idtr.h
@@ -0,0 +1,66 @@
+/**
+ * @file rtems/score/idtr.h
+ */
+
+/*
+ * This file contains definitions for data structure related
+ * to Intel system programming. More information can be found
+ * on Intel site and more precisely in the following book :
+ *
+ * Pentium Processor familly
+ * Developper's Manual
+ *
+ * Volume 3 : Architecture and Programming Manual
+ *
+ * Formerly contained in and extracted from libcpu/i386/cpu.h.
+ *
+ * Copyright (C) 1998 Eric Valette (valette@crf.canon.fr)
+ * Canon Centre Recherche France.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ * Applications must not include this file directly.
+ */
+
+#ifndef _RTEMS_SCORE_IDTR_H
+#define _RTEMS_SCORE_IDTR_H
+
+/*
+ * See page 14.9 Figure 14-2.
+ *
+ */
+typedef struct
+{
+ unsigned int low_offsets_bits:16;
+ unsigned int segment_selector:16;
+ unsigned int fixed_value_bits:8;
+ unsigned int gate_type:5;
+ unsigned int privilege:2;
+ unsigned int present:1;
+ unsigned int high_offsets_bits:16;
+} interrupt_gate_descriptor;
+
+/*
+ * C callable function enabling to create a interrupt_gate_descriptor
+ */
+extern void create_interrupt_gate_descriptor (interrupt_gate_descriptor*, rtems_raw_irq_hdl);
+
+/*
+ * C callable function enabling to get easily usable info from
+ * the actual value of IDT register.
+ */
+extern void i386_get_info_from_IDTR (interrupt_gate_descriptor** table,
+ unsigned* limit);
+
+/*
+ * C callable function enabling to change the value of IDT register. Must be called
+ * with interrupts masked at processor level!!!.
+ */
+extern void i386_set_IDTR (interrupt_gate_descriptor* table,
+ unsigned limit);
+
+#endif
diff --git a/cpukit/score/cpu/i386/rtems/score/interrupts.h b/cpukit/score/cpu/i386/rtems/score/interrupts.h
new file mode 100644
index 0000000000..89034a00f0
--- /dev/null
+++ b/cpukit/score/cpu/i386/rtems/score/interrupts.h
@@ -0,0 +1,79 @@
+/**
+ * @file rtems/score/interrupts.h
+ */
+
+/*
+ * i386 interrupt macros.
+ *
+ * Formerly contained in and extracted from libcpu/i386/cpu.h
+ *
+ * COPYRIGHT (c) 1998 valette@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ * Applications must not include this file directly.
+ */
+
+#ifndef _RTEMS_SCORE_INTERRUPTS_H
+#define _RTEMS_SCORE_INTERRUPTS_H
+
+#ifndef ASM
+
+struct __rtems_raw_irq_connect_data__;
+
+typedef void (*rtems_raw_irq_hdl) (void);
+typedef void (*rtems_raw_irq_enable) (const struct __rtems_raw_irq_connect_data__*);
+typedef void (*rtems_raw_irq_disable) (const struct __rtems_raw_irq_connect_data__*);
+typedef int (*rtems_raw_irq_is_enabled) (const struct __rtems_raw_irq_connect_data__*);
+
+/*
+ * Interrupt Level Macros
+ */
+
+#define i386_disable_interrupts( _level ) \
+ { \
+ asm volatile ( "pushf ; \
+ cli ; \
+ pop %0" \
+ : "=rm" ((_level)) \
+ ); \
+ }
+
+#define i386_enable_interrupts( _level ) \
+ { \
+ asm volatile ( "push %0 ; \
+ popf" \
+ : : "rm" ((_level)) : "cc" \
+ ); \
+ }
+
+#define i386_flash_interrupts( _level ) \
+ { \
+ asm volatile ( "push %0 ; \
+ popf ; \
+ cli" \
+ : : "rm" ((_level)) : "cc" \
+ ); \
+ }
+
+#define i386_get_interrupt_level( _level ) \
+ do { \
+ register uint32_t _eflags; \
+ \
+ asm volatile ( "pushf ; \
+ pop %0" \
+ : "=rm" ((_eflags)) \
+ ); \
+ \
+ _level = (_eflags & EFLAGS_INTR_ENABLE) ? 0 : 1; \
+ } while (0)
+
+#define _CPU_ISR_Disable( _level ) i386_disable_interrupts( _level )
+#define _CPU_ISR_Enable( _level ) i386_enable_interrupts( _level )
+
+#endif
+#endif
diff --git a/cpukit/score/cpu/i386/rtems/score/registers.h b/cpukit/score/cpu/i386/rtems/score/registers.h
new file mode 100644
index 0000000000..6a39b53baf
--- /dev/null
+++ b/cpukit/score/cpu/i386/rtems/score/registers.h
@@ -0,0 +1,186 @@
+/**
+ * @file rtems/score/registers.h
+ */
+
+/*
+ * This file contains definition and constants related to Intel Cpu
+ *
+ * COPYRIGHT (c) 1998 valette@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_REGISTERS_H
+#define _RTEMS_SCORE_REGISTERS_H
+
+/*
+ * definition related to EFLAGS
+ */
+#define EFLAGS_CARRY 0x1
+#define EFLAGS_PARITY 0x4
+
+#define EFLAGS_AUX_CARRY 0x10
+#define EFLAGS_ZERO 0x40
+#define EFLAGS_SIGN 0x80
+
+#define EFLAGS_TRAP 0x100
+#define EFLAGS_INTR_ENABLE 0x200
+#define EFLAGS_DIRECTION 0x400
+#define EFLAGS_OVERFLOW 0x800
+
+#define EFLAGS_IOPL_MASK 0x3000
+#define EFLAGS_NESTED_TASK 0x8000
+
+#define EFLAGS_RESUME 0x10000
+#define EFLAGS_VIRTUAL_MODE 0x20000
+#define EFLAGS_ALIGN_CHECK 0x40000
+#define EFLAGS_VIRTUAL_INTR 0x80000
+
+#define EFLAGS_VIRTUAL_INTR_PEND 0x100000
+#define EFLAGS_ID 0x200000
+
+/*
+ * definitions related to CR0
+ */
+#define CR0_PROTECTION_ENABLE 0x1
+#define CR0_MONITOR_COPROC 0x2
+#define CR0_COPROC_SOFT_EMUL 0x4
+#define CR0_FLOATING_INSTR_EXCEPTION 0x8
+
+#define CR0_EXTENSION_TYPE 0x10
+#define CR0_NUMERIC_ERROR 0x20
+
+#define CR0_WRITE_PROTECT 0x10000
+#define CR0_ALIGMENT_MASK 0x40000
+
+#define CR0_NO_WRITE_THROUGH 0x20000000
+#define CR0_PAGE_LEVEL_CACHE_DISABLE 0x40000000
+#define CR0_PAGING 0x80000000
+
+/*
+ * definitions related to CR3
+ */
+
+#define CR3_PAGE_CACHE_DISABLE 0x10
+#define CR3_PAGE_WRITE_THROUGH 0x8
+
+
+#ifndef ASM
+
+/*
+ * definition of eflags registers has a bit field structure
+ */
+typedef struct {
+ /*
+ * fist byte : bits 0->7
+ */
+ unsigned int carry : 1;
+ unsigned int : 1;
+ unsigned int parity : 1;
+ unsigned int : 1;
+
+ unsigned int auxiliary_carry : 1;
+ unsigned int : 1;
+ unsigned int zero : 1; /* result is zero */
+ unsigned int sign : 1; /* result is less than zero */
+ /*
+ * Second byte : bits 7->15
+ */
+ unsigned int trap : 1;
+ unsigned int intr_enable : 1; /* set => intr on */
+ unsigned int direction : 1; /* set => autodecrement */
+ unsigned int overflow : 1;
+
+ unsigned int IO_privilege : 2;
+ unsigned int nested_task : 1;
+ unsigned int : 1;
+ /*
+ * Third byte : bits 15->23
+ */
+ unsigned int resume : 1;
+ unsigned int virtual_mode : 1;
+ unsigned int aligment_check : 1;
+ unsigned int virtual_intr : 1;
+
+ unsigned int virtual_intr_pending : 1;
+ unsigned int id : 1;
+ unsigned int : 2;
+
+ /*
+ * fourth byte : bits 24->31 : UNUSED
+ */
+ unsigned int : 8;
+}eflags_bits;
+
+typedef union {
+ eflags_bits eflags;
+ unsigned int i;
+}eflags;
+/*
+ * definition of eflags registers has a bit field structure
+ */
+typedef struct {
+ /*
+ * fist byte : bits 0->7
+ */
+ unsigned int protection_enable : 1;
+ unsigned int monitor_coproc : 1;
+ unsigned int coproc_soft_emul : 1;
+ unsigned int floating_instr_except : 1;
+
+ unsigned int extension_type : 1;
+ unsigned int numeric_error : 1;
+ unsigned int : 2;
+ /*
+ * second byte 8->15 : UNUSED
+ */
+ unsigned int : 8;
+ /*
+ * third byte 16->23
+ */
+ unsigned int write_protect : 1;
+ unsigned int : 1;
+ unsigned int aligment_mask : 1;
+ unsigned int : 1;
+
+ unsigned int : 4;
+ /*
+ * fourth byte 24->31
+ */
+ unsigned int : 4;
+
+ unsigned int : 1;
+ unsigned int no_write_through : 1;
+ unsigned int page_level_cache_disable : 1;
+ unsigned int paging : 1;
+}cr0_bits;
+
+typedef union {
+ cr0_bits cr0;
+ unsigned int i;
+}cr0;
+
+/*
+ * definition of cr3 registers has a bit field structure
+ */
+typedef struct {
+
+ unsigned int : 3;
+ unsigned int page_write_transparent : 1;
+ unsigned int page_cache_disable : 1;
+ unsigned int : 7;
+ unsigned int page_directory_base :20;
+}cr3_bits;
+
+typedef union {
+ cr3_bits cr3;
+ unsigned int i;
+}cr3;
+
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/i386/rtems/score/types.h b/cpukit/score/cpu/i386/rtems/score/types.h
new file mode 100644
index 0000000000..f661ae32ef
--- /dev/null
+++ b/cpukit/score/cpu/i386/rtems/score/types.h
@@ -0,0 +1,55 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains type definitions pertaining to the Intel
+ * i386 processor family.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+
+typedef uint16_t Priority_Bit_map_control;
+
+typedef signed long long signed64; /* 64 bit signed integer */
+
+typedef uint32_t boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void i386_isr;
+
+typedef i386_isr ( *i386_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/m68k/.cvsignore b/cpukit/score/cpu/m68k/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/m68k/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/m68k/ChangeLog b/cpukit/score/cpu/m68k/ChangeLog
new file mode 100644
index 0000000000..dcddc9fda3
--- /dev/null
+++ b/cpukit/score/cpu/m68k/ChangeLog
@@ -0,0 +1,451 @@
+2006-06-19 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 1091/patch
+ * cpu_asm.S: Reduce mask from 0xffc to 0x3fc so only the vector
+ bits are used when calculating the exception vector.
+
+2006-02-28 Eric Norum <norume@aps.anl.gov>
+
+ PR 904/patch
+ * rtems/score/m68k.h: Just "cc" in the clobbered register list for
+ interrupt enable/disable/flash operations. The "memory" barrier will
+ move the the generic interrupt enable/disable/flash macros.
+
+2006-02-24 Eric Norum <norume@aps.anl.gov>
+
+ PR 904/patch
+ * rtems/score/m68k.h: Add "memory" to the clobbered register list for
+ interrupt enable/disable/flash operations. This is necessary to prevent
+ the compiler from hoisting/sinking other operations past the interrupt
+ enable/disable/flash operations.
+
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Part of a large patch to improve Doxygen output.
+ As a side-effect, grammar and spelling errors were corrected, spacing
+ errors were address, and some variable names were improved.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16, unsigned32.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h: Remove private version of CONCAT macros.
+ Include <rtems/concat.h> instead.
+
+2005-06-07 Brett Swimley <brett.swimley@aedbozeman.com>
+
+ PR 803/patch
+ * rtems/score/cpu.h, rtems/score/m68k.h: Correct definition of _VBR.
+
+2005-05-20 Chris Johns <chrisj@rtems.org>
+
+ * rtems/score/cpu.h, rtems/score/m68k.h: Change declaration of _VBR.
+
+2005-05-04 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/m68k.h: Change _ColdFire_VBR to _VBR.
+
+2005-05-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Change definition of _VBR to a simple pointer.
+ * rtems/score/m68k.h: Remove use of _Coldfire_VBR.
+
+2005-05-03 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c: Remove warning.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/m68k/m68302.h, rtems/m68k/m68360.h, rtems/m68k/qsm.h,
+ rtems/m68k/sim.h, rtems/score/m68k.h: Header guards cleanup.
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2005-01-31 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR rtems/752
+ * rtems/m68k/m68302.h, rtems/m68k/m68360.h, rtems/m68k/qsm.h,
+ rtems/m68k/sim.h: New (relocated from .).
+ * m68302.h, m68360.h, qsm.h, sim.h: Remove.
+ * Makefile.am: Reflect changes above.
+
+2005-01-28 Eric Norum <norume@aps.anl.gov>
+
+ * rtems/score/cpu.h, rtems/score/m68k.h: ColdFire ISA A+ instructions
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/cpu.h, rtems/score/m68k.h, rtems/score/types.h:
+ New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/m68k.h: *_swap_u32( uint32_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/m68k.h: *_swap_u16( uint16_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: #include <rtems/stdint.h>.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove build-variant support.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Use __rtems_score_types_h as preprocessor
+ guard.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * asm.h: Add doxygen preamble.
+
+2004-11-19 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/m68k.h: Use (defined(__mc68020__) && !defined(__mcpu32__))
+ instead of defined(__mc68020__) to reflect GCC-3.4's expectations.
+
+2004-11-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Add doxygen preamble.
+ * rtems/score/m68k.h: Add doxygen preamble.
+ * rtems/score/types.h: Add doxygen preamble.
+
+2004-07-25 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/m68k.h: Add include of <stdint.h> for uint32_t used by
+ endian swapping routines.
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Remove (Merged into $(top_srcdir)/configure.ac).
+ * Makefile.am: Don't include multilib.am.
+ Reflect merging configure.ac into $(top_srcdir)/configure.ac.
+
+2004-04-03 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Install m68302.h m68360.h qsm.h sim.h
+ to $(includedir)/rtems/m68k.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Install asm.h to $(includedir)/rtems.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu_asm.S: Include <rtems/asm.h> instead of <asm.h>.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu.c, m68302.h, rtems/score/cpu.h, rtems/score/m68k.h: Convert to
+ using c99 fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: RTEMS_TOP([../../../..]).
+
+2004-01-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR 561/rtems
+ * asm.h: Add CONCAT0, EVAL. Let SYM and REG use CONCAT0 and EVAL.
+
+2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Move RTEMS_TOP one subdir down.
+
+2004-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add PREINSTALL_DIRS.
+
+2004-01-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Re-add dirstamps to PREINSTALL_FILES.
+ Add PREINSTALL_FILES to CLEANFILES.
+
+2004-01-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Requires automake >= 1.8.1.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, again.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Convert to using automake compilation rules.
+
+2004-01-07 Joel Sherrill <joel@OARcorp.com>
+
+ * qsm.h, sim.h: Remove efi68k and efi332 references as they are no
+ longer in the tree.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use mkdir_p. Remove dirs from PREINSTALL_FILES.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require automake >= 1.8, autoconf >= 2.59.
+
+2003-12-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Remove TMPINSTALL_FILES.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Don't use gmake rules for preinstallation.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CANONICAL_HOST.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CPU.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, cpu_asm.S, rtems/score/cpu.h, rtems/score/m68k.h,
+ rtems/score/types.h: URL for license changed.
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+
+2003-02-06 Ilya Alexeev <ilya@continuum.ru>
+
+ * m68360.h: Correct the order of fields in the ethernet structure
+ to account for the typo in MC68360UM (page 7-248).
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require autoconf-2.57 + automake-1.7.2.
+ * Makefile.am: Eliminate C_O_FILES, S_O_FILES, libscorecpu_a_OBJECTS.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix package name.
+
+2002-11-01 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c: Removed warnings.
+
+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-26 Eric Norum <eric.norum@usask.ca>
+
+ * cpu_asm.S: More PR267 tinkering which eliminates some conditional
+ compilation.
+
+2002-08-14 Brett Swimley <brett.swimley@aedinc.net>
+
+ * cpu_asm.S: Per PR267, the _ISR_Handler() function never was modifying
+ _ISR_Nest_level, and _Watchdog_Insert() requires this variable
+ to be modified to determine if an interrupt may have modified
+ the watchdog chain. Prior to modifying _ISR_Handler(), I had
+ a test that would fail if _ISR_Flash was not commented out in
+ _Watchdog_Insert(). After this modification was made, my test
+ ran flawlessly.
+
+2002-08-05 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR260 eliminate use of make-target-options. This impacted
+ RTEMS allowing a distinction between the CPU32 and CPU32+ in the
+ SuperCore and required that the m68k optimized memcpy be moved
+ to libcpu.
+ * memcpy.c: Moved to libcpu.
+ * Makefile.am: Modified to reflect above.
+
+2002-07-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use .$(OBJEXT) instead of .o.
+
+2002-07-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: RTEMS_TOP(../../../..).
+
+2002-07-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems.S: Remove.
+ * Makefile.am: Reflect changes above.
+
+2002-07-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_PROJECT_ROOT.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add RTEMS_PROG_CCAS
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AC_CONFIG_AUX_DIR(../../../..).
+ Add AC_PROG_RANLIB.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/../../../automake/*.am.
+ Use ../../../aclocal.
+
+2002-05-28 Chris Johns <ccj@acm.org>
+
+ * rtems/score/m68k.h: Per PR227, mc68060 does not require FPSP
+ since it is now multilib'ed.
+
+2001-04-03 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
+ * include/rtems/score/ispsh7750.h, score/ispsh7750.c: 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.
+
+2002-03-15 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/m68k.h: m68k_swap_u32 fix typo.
+
+2002-03-06 Victor V. Vengerov <vvv@oktet.ru>
+
+ * rtems/score/m68k.h [M68K_COLDFIRE_ARCH] (CPU_swap_u16, CPU_swap_u32):
+ Generic implementation of endian swap primitives added for Coldfire
+ family.
+
+2002-01-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/Makefile.am: Removed.
+ * rtems/score/Makefile.am: Removed.
+ * configure.ac: Reflect changes above.
+ * Makefile.am: Reflect changes above.
+
+2001-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add multilib support.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/Makefile.am: Use 'PREINSTALL_FILES ='.
+ * Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-08-09 Chris Johns <ccj@acm.org>
+
+ * cpu_asm.S: This patch was co-developed with Eric Norum
+ <eric.norum@usask.ca>. It closes a one instruction window
+ on some m68k CPU cores. It fixes symptoms seen as:
+ 1) No more `interrupt handler invoked twice for
+ a single interrupt'.
+ 2) No more `lockup when mc68360 CPM and PIT interrupts
+ are at different levels'.
+ It does insert a little more overhead on machines without hardware
+ interrupt stacks but correctness has a price.
+
+2001-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, rtems/score/Makefile.am:
+ Apply include_*HEADERS instead of H_FILES.
+
+2001-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Added _CPU_Initialize_vectors().
+ * cpu_asm.S: Modify to properly dereference _ISR_Vector_table
+ now that it is dynamically allocated.
+
+2000-12-19 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c: Do not read or write raw interrupt vector table if
+ we are on a CPU that does not have a %vbr register and the
+ BSP is configured as having the table in ROM.
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
+ Switch to GNU canonicalization.
+
+2000-10-19 Antti P Miettinen <anmietti@trshp.ntc.nokia.com>
+
+ * rtems/score/cpu.h: define CPU_Exception_frame for rdbg.
+ * m68302.h: Make buffer pointer in m302_SCC_bd volatile.
+
+2000-10-12 John S Gwynne <jgwynne@mrcday.com>
+
+ * sim.h: These changes enable RTEMS to automatically generate
+ the ram_init file used by gdb with the BDM patches. The 332 has
+ on-board chip select lines (for RAM and FLASH) that must be
+ configured before use of these peripherals. These patches parse
+ data from start.c where the chip select lines are configured in
+ the runtime executable and automatically generates the gdb
+ initialization file using the same settings. A great time saver.
+ A similar file, ram_init_FW (flash writable), is also generated
+ that the flash programming tool uses.
+ * BSP/start/start.c: Must be modified to support above.
+ * BSP/start/ram_init.ld, BSP/start/ram_init.sed: New files.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am.
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: New file.
diff --git a/cpukit/score/cpu/m68k/Makefile.am b/cpukit/score/cpu/m68k/Makefile.am
new file mode 100644
index 0000000000..ff7e0d1c2c
--- /dev/null
+++ b/cpukit/score/cpu/m68k/Makefile.am
@@ -0,0 +1,24 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_m68kdir = $(includedir)/rtems/m68k
+include_rtems_m68k_HEADERS = rtems/m68k/m68302.h rtems/m68k/m68360.h \
+ rtems/m68k/qsm.h rtems/m68k/sim.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/m68k.h \
+ rtems/score/types.h
+
+libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/m68k/cpu.c b/cpukit/score/cpu/m68k/cpu.c
new file mode 100644
index 0000000000..c622115ea4
--- /dev/null
+++ b/cpukit/score/cpu/m68k/cpu.c
@@ -0,0 +1,212 @@
+/*
+ * Motorola MC68xxx Dependent Source
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+
+/* _CPU_Initialize
+ *
+ * This routine performs processor dependent initialization.
+ *
+ * INPUT PARAMETERS:
+ * cpu_table - CPU table to initialize
+ * thread_dispatch - entry pointer to thread dispatcher
+ *
+ * OUTPUT PARAMETERS: NONE
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch) /* ignored on this CPU */
+)
+{
+#if ( M68K_HAS_VBR == 0 )
+ /* fill the isr redirect table with the code to place the format/id
+ onto the stack */
+
+ uint32_t slot;
+
+ for (slot = 0; slot < CPU_INTERRUPT_NUMBER_OF_VECTORS; slot++)
+ {
+ _CPU_ISR_jump_table[slot].move_a7 = M68K_MOVE_A7;
+ _CPU_ISR_jump_table[slot].format_id = slot << 2;
+ _CPU_ISR_jump_table[slot].jmp = M68K_JMP;
+ _CPU_ISR_jump_table[slot].isr_handler = (uint32_t ) 0xDEADDEAD;
+ }
+#endif /* M68K_HAS_VBR */
+
+ _CPU_Table = *cpu_table;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Get_level
+ */
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ uint32_t level;
+
+ m68k_get_interrupt_level( level );
+
+ return level;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_install_raw_handler
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ proc_ptr *interrupt_table = NULL;
+
+#if (M68K_HAS_FPSP_PACKAGE == 1)
+ /*
+ * If this vector being installed is one related to FP, then the
+ * FPSP will install the handler itself and handle it completely
+ * with no intervention from RTEMS.
+ */
+
+ if (*_FPSP_install_raw_handler &&
+ (*_FPSP_install_raw_handler)(vector, new_handler, *old_handler))
+ return;
+#endif
+
+
+ /*
+ * On CPU models without a VBR, it is necessary for there to be some
+ * header code for each ISR which saves a register, loads the vector
+ * number, and jumps to _ISR_Handler.
+ */
+
+ m68k_get_vbr( interrupt_table );
+#if ( M68K_HAS_VBR == 1 )
+ *old_handler = interrupt_table[ vector ];
+ interrupt_table[ vector ] = new_handler;
+#else
+
+ /*
+ * Install handler into RTEMS jump table and if VBR table is in
+ * RAM, install the pointer to the appropriate jump table slot.
+ * If the VBR table is in ROM, it is the BSP's responsibility to
+ * load it appropriately to vector to the RTEMS jump table.
+ */
+
+ *old_handler = (proc_ptr) _CPU_ISR_jump_table[vector].isr_handler;
+ _CPU_ISR_jump_table[vector].isr_handler = (uint32_t ) new_handler;
+ if ( (uint32_t ) interrupt_table != 0xFFFFFFFF )
+ interrupt_table[ vector ] = (proc_ptr) &_CPU_ISR_jump_table[vector];
+#endif /* M68K_HAS_VBR */
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_install_vector
+ *
+ * This kernel routine installs the RTEMS handler for the
+ * specified vector.
+ *
+ * Input parameters:
+ * vector - interrupt vector number
+ * new_handler - replacement ISR for this vector number
+ * old_handler - former ISR for this vector number
+ *
+ * Output parameters: NONE
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ proc_ptr ignored = 0; /* to avoid warning */
+
+ *old_handler = _ISR_Vector_table[ vector ];
+
+ _CPU_ISR_install_raw_handler( vector, _ISR_Handler, &ignored );
+
+ _ISR_Vector_table[ vector ] = new_handler;
+}
+
+
+/*PAGE
+ *
+ * _CPU_Install_interrupt_stack
+ */
+
+void _CPU_Install_interrupt_stack( void )
+{
+#if ( M68K_HAS_SEPARATE_STACKS == 1 )
+ void *isp = _CPU_Interrupt_stack_high;
+
+ asm volatile ( "movec %0,%%isp" : "=r" (isp) : "0" (isp) );
+#endif
+}
+
+#if ( M68K_HAS_BFFFO != 1 )
+/*
+ * Returns table for duplication of the BFFFO instruction (16 bits only)
+ */
+const unsigned char __BFFFOtable[256] = {
+ 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 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,
+ 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, 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, 0, 0
+};
+#endif
+
+/*PAGE
+ *
+ * The following code context switches the software FPU emulation
+ * code provided with GCC.
+ */
+
+#if (CPU_SOFTWARE_FP == TRUE)
+extern Context_Control_fp _fpCCR;
+
+void CPU_Context_save_fp (void **fp_context_ptr)
+{
+ Context_Control_fp *fp;
+
+ fp = (Context_Control_fp *) *fp_context_ptr;
+
+ *fp = _fpCCR;
+}
+
+void CPU_Context_restore_fp (void **fp_context_ptr)
+{
+ Context_Control_fp *fp;
+
+ fp = (Context_Control_fp *) *fp_context_ptr;
+
+ _fpCCR = *fp;
+}
+#endif
diff --git a/cpukit/score/cpu/m68k/cpu_asm.S b/cpukit/score/cpu/m68k/cpu_asm.S
new file mode 100644
index 0000000000..e53816dde3
--- /dev/null
+++ b/cpukit/score/cpu/m68k/cpu_asm.S
@@ -0,0 +1,265 @@
+/* cpu_asm.s
+ *
+ * This file contains all assembly code for the MC68020 implementation
+ * of RTEMS.
+ *
+ * COPYRIGHT (c) 1989-2001.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+
+#include <rtems/asm.h>
+
+ .text
+
+/* void _CPU_Context_switch( run_context, heir_context )
+ *
+ * This routine performs a normal non-FP context.
+ */
+
+ .align 4
+ .global SYM (_CPU_Context_switch)
+
+.set RUNCONTEXT_ARG, 4 | save context argument
+.set HEIRCONTEXT_ARG, 8 | restore context argument
+
+SYM (_CPU_Context_switch):
+ moval a7@(RUNCONTEXT_ARG),a0| a0 = running thread context
+ movw sr,d1 | d1 = status register
+ movml d1-d7/a2-a7,a0@ | save context
+
+ moval a7@(HEIRCONTEXT_ARG),a0| a0 = heir thread context
+restore: movml a0@,d1-d7/a2-a7 | restore context
+ movw d1,sr | restore status register
+ rts
+
+/*PAGE
+ * void __CPU_Context_save_fp_context( &fp_context_ptr )
+ * void __CPU_Context_restore_fp_context( &fp_context_ptr )
+ *
+ * These routines are used to context switch a MC68881 or MC68882.
+ *
+ * NOTE: Context save and restore code is based upon the code shown
+ * on page 6-38 of the MC68881/68882 Users Manual (rev 1).
+ *
+ * CPU_FP_CONTEXT_SIZE is higher than expected to account for the
+ * -1 pushed at end of this sequence.
+ *
+ * Neither of these entries is required if we have software FPU
+ * emulation. But if we don't have an FPU or emulation, then
+ * we need the stub versions of these routines.
+ */
+
+#if (CPU_SOFTWARE_FP == FALSE)
+
+.set FPCONTEXT_ARG, 4 | save FP context argument
+
+ .align 4
+ .global SYM (_CPU_Context_save_fp)
+SYM (_CPU_Context_save_fp):
+#if ( M68K_HAS_FPU == 1 )
+ moval a7@(FPCONTEXT_ARG),a1 | a1 = &ptr to context area
+ moval a1@,a0 | a0 = Save context area
+ fsave a0@- | save 68881/68882 state frame
+ tstb a0@ | check for a null frame
+ beq.b nosv | Yes, skip save of user model
+ fmovem fp0-fp7,a0@- | save data registers (fp0-fp7)
+ fmovem fpc/fps/fpi,a0@- | and save control registers
+ movl #-1,a0@- | place not-null flag on stack
+nosv: movl a0,a1@ | save pointer to saved context
+#endif
+ rts
+
+ .align 4
+ .global SYM (_CPU_Context_restore_fp)
+SYM (_CPU_Context_restore_fp):
+#if ( M68K_HAS_FPU == 1 )
+ moval a7@(FPCONTEXT_ARG),a1 | a1 = &ptr to context area
+ moval a1@,a0 | a0 = address of saved context
+ tstb a0@ | Null context frame?
+ beq.b norst | Yes, skip fp restore
+ addql #4,a0 | throwaway non-null flag
+ fmovem a0@+,fpc/fps/fpi | restore control registers
+ fmovem a0@+,fp0-fp7 | restore data regs (fp0-fp7)
+norst: frestore a0@+ | restore the fp state frame
+ movl a0,a1@ | save pointer to saved context
+#endif
+ rts
+#endif
+
+/*PAGE
+ * void _ISR_Handler()
+ *
+ * This routine provides the RTEMS interrupt management.
+ *
+ * NOTE:
+ * Upon entry, the master stack will contain an interrupt stack frame
+ * back to the interrupted thread and the interrupt stack will contain
+ * a throwaway interrupt stack frame. If dispatching is enabled, and this
+ * is the outer most interrupt, and a context switch is necessary or
+ * the current thread has pending signals, then set up the master stack to
+ * transfer control to the interrupt dispatcher.
+ */
+
+#if ( M68K_COLDFIRE_ARCH == 1 )
+.set SR_OFFSET, 2 | Status register offset
+.set PC_OFFSET, 4 | Program Counter offset
+.set FVO_OFFSET, 0 | Format/vector offset
+#elif ( M68K_HAS_VBR == 1)
+.set SR_OFFSET, 0 | Status register offset
+.set PC_OFFSET, 2 | Program Counter offset
+.set FVO_OFFSET, 6 | Format/vector offset
+#else
+.set SR_OFFSET, 2 | Status register offset
+.set PC_OFFSET, 4 | Program Counter offset
+.set FVO_OFFSET, 0 | Format/vector offset placed in the stack
+#endif /* M68K_HAS_VBR */
+
+.set SAVED, 16 | space for saved registers
+
+ .align 4
+ .global SYM (_ISR_Handler)
+
+SYM (_ISR_Handler):
+ addql #1,SYM (_Thread_Dispatch_disable_level) | disable multitasking
+#if ( M68K_COLDFIRE_ARCH == 0 )
+ moveml d0-d1/a0-a1,a7@- | save d0-d1,a0-a1
+#else
+ lea a7@(-SAVED),a7
+ movm.l d0-d1/a0-a1,a7@ | save d0-d1,a0-a1
+#endif
+ movew a7@(SAVED+FVO_OFFSET),d0 | d0 = F/VO
+ andl #0x03fc,d0 | d0 = vector offset in vbr
+
+
+#if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 )
+ movel _CPU_Interrupt_stack_high,a0 | a0 now point just above interrupt stack
+ cmpl _CPU_Interrupt_stack_low,a7 | stack below interrupt stack?
+ bcs.b 1f | yes, switch to interrupt stack
+ cmpl a0,a7 | stack above interrupt stack?
+ bcs.b 2f | no, do not switch stacks
+1:
+ movel a7,a1 | copy task stack pointer
+ movel a0,a7 | switch to interrupt stack
+ movel a1,a7@- | store task stack pointer on interrupt stack
+2:
+#endif /* CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 */
+
+ addql #1,SYM(_ISR_Nest_level) | one nest level deeper
+
+ movel SYM (_ISR_Vector_table),a0 | a0= base of RTEMS table
+#if ( M68K_HAS_PREINDEXING == 1 )
+ movel (a0,d0:w:1),a0 | a0 = address of user routine
+#else
+ addal d0,a0 | a0 = address of vector
+ movel (a0),a0 | a0 = address of user routine
+#endif
+
+ lsrl #2,d0 | d0 = vector number
+ movel d0,a7@- | push vector number
+ jbsr a0@ | invoke the user ISR
+ addql #4,a7 | remove vector number
+ subql #1,SYM(_ISR_Nest_level) | Reduce interrupt-nesting count
+
+#if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 )
+ movel _CPU_Interrupt_stack_high,a0
+ subql #4,a0
+ cmpl a0,a7 | At top of interrupt stack?
+ bne.b 1f | No, do not restore task stack pointer
+ movel (a7),a7 | Restore task stack pointer
+1:
+#endif /* CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 */
+ subql #1,SYM (_Thread_Dispatch_disable_level)
+ | unnest multitasking
+ bne.b exit | If dispatch disabled, exit
+
+#if ( M68K_HAS_SEPARATE_STACKS == 1 )
+ movew #0xf000,d0 | isolate format nibble
+ andw a7@(SAVED+FVO_OFFSET),d0 | get F/VO
+ cmpiw #0x1000,d0 | is it a throwaway isf?
+ bne.b exit | NOT outer level, so branch
+#else
+/*
+ * If we have a CPU which allows a higher-priority interrupt to preempt a
+ * lower priority handler before the lower-priority handler can increment
+ * _Thread_Dispatch_disable_level then we must check the PC on the stack to
+ * see if it is _ISR_Handler. If it is we have the case of nesting interrupts
+ * without the dispatch level being incremented.
+ */
+ #if ( M68K_COLDFIRE_ARCH == 0 && M68K_MC68060_ARCH == 0 )
+ cmpl #_ISR_Handler,a7@(SAVED+PC_OFFSET)
+ beq.b exit
+ #endif
+#endif
+ tstl SYM (_Context_Switch_necessary)
+ | Is thread switch necessary?
+ bne.b bframe | Yes, invoke dispatcher
+
+ tstl SYM (_ISR_Signals_to_thread_executing)
+ | signals sent to Run_thread
+ | while in interrupt handler?
+ beq.b exit | No, then exit
+
+bframe: clrl SYM (_ISR_Signals_to_thread_executing)
+ | If sent, will be processed
+#if ( M68K_HAS_SEPARATE_STACKS == 1 )
+ movec msp,a0 | a0 = master stack pointer
+ movew #0,a0@- | push format word
+ movel #SYM(_ISR_Dispatch),a0@- | push return addr
+ movew a0@(6),a0@- | push saved sr
+ movec a0,msp | set master stack pointer
+#else
+ jsr SYM (_Thread_Dispatch) | Perform context switch
+#endif
+
+#if ( M68K_COLDFIRE_ARCH == 0 )
+exit: moveml a7@+,d0-d1/a0-a1 | restore d0-d1,a0-a1
+#else
+exit: moveml a7@,d0-d1/a0-a1 | restore d0-d1,a0-a1
+ lea a7@(SAVED),a7
+#endif
+
+#if ( M68K_HAS_VBR == 0 )
+ addql #2,a7 | pop format/id
+#endif /* M68K_HAS_VBR */
+ rte | return to thread
+ | OR _Isr_dispatch
+
+/*PAGE
+ * void _ISR_Dispatch()
+ *
+ * Entry point from the outermost interrupt service routine exit.
+ * The current stack is the supervisor mode stack if this processor
+ * has separate stacks.
+ *
+ * 1. save all registers not preserved across C calls.
+ * 2. invoke the _Thread_Dispatch routine to switch tasks
+ * or a signal to the currently executing task.
+ * 3. restore all registers not preserved across C calls.
+ * 4. return from interrupt
+ */
+
+ .global SYM (_ISR_Dispatch)
+SYM (_ISR_Dispatch):
+#if ( M68K_COLDFIRE_ARCH == 0 )
+ movml d0-d1/a0-a1,a7@-
+ jsr SYM (_Thread_Dispatch)
+ movml a7@+,d0-d1/a0-a1
+#else
+ lea a7@(-SAVED),a7
+ movml d0-d1/a0-a1,a7@
+ jsr SYM (_Thread_Dispatch)
+ movml a7@,d0-d1/a0-a1
+ lea a7@(SAVED),a7
+#endif
+
+#if ( M68K_HAS_VBR == 0 )
+ addql #2,a7 | pop format/id
+#endif /* M68K_HAS_VBR */
+ rte
diff --git a/cpukit/score/cpu/m68k/preinstall.am b/cpukit/score/cpu/m68k/preinstall.am
new file mode 100644
index 0000000000..d7bebcdd63
--- /dev/null
+++ b/cpukit/score/cpu/m68k/preinstall.am
@@ -0,0 +1,62 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/m68k/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/m68k
+ @: > $(PROJECT_INCLUDE)/rtems/m68k/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/m68k/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/m68k/m68302.h: rtems/m68k/m68302.h $(PROJECT_INCLUDE)/rtems/m68k/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/m68k/m68302.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/m68k/m68302.h
+
+$(PROJECT_INCLUDE)/rtems/m68k/m68360.h: rtems/m68k/m68360.h $(PROJECT_INCLUDE)/rtems/m68k/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/m68k/m68360.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/m68k/m68360.h
+
+$(PROJECT_INCLUDE)/rtems/m68k/qsm.h: rtems/m68k/qsm.h $(PROJECT_INCLUDE)/rtems/m68k/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/m68k/qsm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/m68k/qsm.h
+
+$(PROJECT_INCLUDE)/rtems/m68k/sim.h: rtems/m68k/sim.h $(PROJECT_INCLUDE)/rtems/m68k/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/m68k/sim.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/m68k/sim.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/m68k.h: rtems/score/m68k.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/m68k.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/m68k.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
diff --git a/cpukit/score/cpu/m68k/rtems/asm.h b/cpukit/score/cpu/m68k/rtems/asm.h
new file mode 100644
index 0000000000..9381607dac
--- /dev/null
+++ b/cpukit/score/cpu/m68k/rtems/asm.h
@@ -0,0 +1,140 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ */
+
+/*
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ * COPYRIGHT (c) 1994-1997.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/cpu.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT0 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT0 (__REGISTER_PREFIX__, x)
+
+#define d0 REG (d0)
+#define d1 REG (d1)
+#define d2 REG (d2)
+#define d3 REG (d3)
+#define d4 REG (d4)
+#define d5 REG (d5)
+#define d6 REG (d6)
+#define d7 REG (d7)
+#define a0 REG (a0)
+#define a1 REG (a1)
+#define a2 REG (a2)
+#define a3 REG (a3)
+#define a4 REG (a4)
+#define a5 REG (a5)
+#define a6 REG (a6)
+#define a7 REG (a7)
+#define sp REG (sp)
+
+#define msp REG (msp)
+#define usp REG (usp)
+#define isp REG (isp)
+#define sr REG (sr)
+#define vbr REG (vbr)
+#define dfc REG (dfc)
+#define sfc REG (sfc)
+
+/* mcf52xx special regs */
+#define cacr REG (cacr)
+#define acr0 REG (acr0)
+#define acr1 REG (acr1)
+#define rambar0 REG (rambar0)
+#define mbar REG (mbar)
+
+
+#define fp0 REG (fp0)
+#define fp1 REG (fp1)
+#define fp2 REG (fp2)
+#define fp3 REG (fp3)
+#define fp4 REG (fp4)
+#define fp5 REG (fp5)
+#define fp6 REG (fp6)
+#define fp7 REG (fp7)
+
+#define fpc REG (fpc)
+#define fpi REG (fpi)
+#define fps REG (fps)
+#define fpsr REG (fpsr)
+
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA .data
+#define END_DATA
+#define BEGIN_BSS .bss
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .globl SYM (sym)
+#define EXTERN(sym) .globl SYM (sym)
+
+#endif
diff --git a/cpukit/score/cpu/m68k/rtems/m68k/m68302.h b/cpukit/score/cpu/m68k/rtems/m68k/m68302.h
new file mode 100644
index 0000000000..8f5da7cb50
--- /dev/null
+++ b/cpukit/score/cpu/m68k/rtems/m68k/m68302.h
@@ -0,0 +1,660 @@
+/*
+ *------------------------------------------------------------------
+ *
+ * m68302.h - Definitions for Motorola MC68302 processor.
+ *
+ * Section references in this file refer to revision 2 of Motorola's
+ * "MC68302 Integrated Multiprotocol Processor User's Manual".
+ * (Motorola document MC68302UM/AD REV 2.)
+ *
+ * Based on Don Meyer's cpu68302.h that was posted in comp.sys.m68k
+ * on 17 February, 1993.
+ *
+ * Copyright 1995 David W. Glessner.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the following conditions are met:
+ * 1. Redistribution of source code and documentation must retain
+ * the above copyright notice, this list of conditions and the
+ * following disclaimer.
+ * 2. 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" without warranty of any kind,
+ * either expressed or implied, including, but not limited to, the
+ * implied warranties of merchantability, title and fitness for a
+ * particular purpose.
+ *
+ *
+ * $Id$
+ *
+ *------------------------------------------------------------------
+ */
+
+#ifndef _RTEMS_M68K_M68302_H
+#define _RTEMS_M68K_M68302_H
+
+/*
+ * BAR - Base Address Register
+ * Section 2.7
+ */
+#define M302_BAR (*((volatile uint16_t *) 0xf2))
+
+/*
+ * SCR - System Control Register
+ * Section 3.8.1
+ */
+#define M302_SCR (*((volatile uint32_t *) 0xf4))
+/*
+ * SCR bits
+ */
+#define RBIT_SCR_IPA 0x08000000
+#define RBIT_SCR_HWT 0x04000000
+#define RBIT_SCR_WPV 0x02000000
+#define RBIT_SCR_ADC 0x01000000
+
+#define RBIT_SCR_ERRE 0x00400000
+#define RBIT_SCR_VGE 0x00200000
+#define RBIT_SCR_WPVE 0x00100000
+#define RBIT_SCR_RMCST 0x00080000
+#define RBIT_SCR_EMWS 0x00040000
+#define RBIT_SCR_ADCE 0x00020000
+#define RBIT_SCR_BCLM 0x00010000
+
+#define RBIT_SCR_FRZW 0x00008000
+#define RBIT_SCR_FRZ2 0x00004000
+#define RBIT_SCR_FRZ1 0x00002000
+#define RBIT_SCR_SAM 0x00001000
+#define RBIT_SCR_HWDEN 0x00000800
+#define RBIT_SCR_HWDCN2 0x00000400
+#define RBIT_SCR_HWDCN1 0x00000200 /* 512 clocks */
+#define RBIT_SCR_HWDCN0 0x00000100 /* 128 clocks */
+
+#define RBIT_SCR_LPREC 0x00000080
+#define RBIT_SCR_LPP16 0x00000040
+#define RBIT_SCR_LPEN 0x00000020
+#define RBIT_SCR_LPCLKDIV 0x0000001f
+
+
+/*
+ * 68000 interrupt and trap vector numbers
+ */
+#define M68K_IVEC_BUS_ERROR 2
+#define M68K_IVEC_ADDRESS_ERROR 3
+#define M68K_IVEC_ILLEGAL_OPCODE 4
+#define M68K_IVEC_ZERO_DIVIDE 5
+#define M68K_IVEC_CHK 6
+#define M68K_IVEC_TRAPV 7
+#define M68K_IVEC_PRIVILEGE 8
+#define M68K_IVEC_TRACE 9
+#define M68K_IVEC_LINE_A 10
+#define M68K_IVEC_LINE_F 11
+/* Unassigned, Reserved 12-14 */
+#define M68K_IVEC_UNINITIALIZED_INT 15
+/* Unassigned, Reserved 16-23 */
+#define M68K_IVEC_SPURIOUS_INT 24
+
+#define M68K_IVEC_LEVEL1_AUTOVECTOR 25
+#define M68K_IVEC_LEVEL2_AUTOVECTOR 26
+#define M68K_IVEC_LEVEL3_AUTOVECTOR 27
+#define M68K_IVEC_LEVEL4_AUTOVECTOR 28
+#define M68K_IVEC_LEVEL5_AUTOVECTOR 29
+#define M68K_IVEC_LEVEL6_AUTOVECTOR 30
+#define M68K_IVEC_LEVEL7_AUTOVECTOR 31
+
+#define M68K_IVEC_TRAP0 32
+#define M68K_IVEC_TRAP1 33
+#define M68K_IVEC_TRAP2 34
+#define M68K_IVEC_TRAP3 35
+#define M68K_IVEC_TRAP4 36
+#define M68K_IVEC_TRAP5 37
+#define M68K_IVEC_TRAP6 38
+#define M68K_IVEC_TRAP7 39
+#define M68K_IVEC_TRAP8 40
+#define M68K_IVEC_TRAP9 41
+#define M68K_IVEC_TRAP10 42
+#define M68K_IVEC_TRAP11 43
+#define M68K_IVEC_TRAP12 44
+#define M68K_IVEC_TRAP13 45
+#define M68K_IVEC_TRAP14 46
+#define M68K_IVEC_TRAP15 47
+/*
+ * Unassigned, Reserved 48-59
+ *
+ * Note: Vectors 60-63 are used by the MC68302 (e.g. BAR, SCR).
+ */
+
+/*
+ * MC68302 Interrupt Vectors
+ * Section 3.2
+ */
+enum m68302_ivec_e {
+ M302_IVEC_ERR =0,
+ M302_IVEC_PB8 =1, /* General-Purpose Interrupt 0 */
+ M302_IVEC_SMC2 =2,
+ M302_IVEC_SMC1 =3,
+ M302_IVEC_TIMER3 =4,
+ M302_IVEC_SCP =5,
+ M302_IVEC_TIMER2 =6,
+ M302_IVEC_PB9 =7, /* General-Purpose Interrupt 1 */
+ M302_IVEC_SCC3 =8,
+ M302_IVEC_TIMER1 =9,
+ M302_IVEC_SCC2 =10,
+ M302_IVEC_IDMA =11,
+ M302_IVEC_SDMA =12, /* SDMA Channels Bus Error */
+ M302_IVEC_SCC1 =13,
+ M302_IVEC_PB10 =14, /* General-Purpose Interrupt 2 */
+ M302_IVEC_PB11 =15, /* General-Purpose Interrupt 3 */
+ M302_IVEC_IRQ1 =17, /* External Device */
+ M302_IVEC_IRQ6 =22, /* External Device */
+ M302_IVEC_IRQ7 =23 /* External Device */
+};
+
+
+/*
+ * GIMR - Global Interrupt Mode Register
+ * Section 3.2.5.1
+ */
+#define RBIT_GIMR_MOD (1<<15)
+#define RBIT_GIMR_IV7 (1<<14)
+#define RBIT_GIMR_IV6 (1<<13)
+#define RBIT_GIMR_IV1 (1<<12)
+#define RBIT_GIMR_ET7 (1<<10)
+#define RBIT_GIMR_ET6 (1<<9)
+#define RBIT_GIMR_ET1 (1<<8)
+#define RBIT_GIMR_VECTOR (7<<5)
+
+/*
+ * IPR - Interrupt Pending Register (Section 3.2.5.2)
+ * IMR - Interrupt Mask Register (Section 3.2.5.3)
+ * ISR - Interrupt In-Service Register (Section 3.2.5.4)
+ */
+#define RBIT_IPR_PB11 (1<<15)
+#define RBIT_IPR_PB10 (1<<14)
+#define RBIT_IPR_SCC1 (1<<13)
+#define RBIT_IPR_SDMA (1<<12)
+#define RBIT_IPR_IDMA (1<<11)
+#define RBIT_IPR_SCC2 (1<<10)
+#define RBIT_IPR_TIMER1 (1<<9)
+#define RBIT_IPR_SCC3 (1<<8)
+#define RBIT_IPR_PB9 (1<<7)
+#define RBIT_IPR_TIMER2 (1<<6)
+#define RBIT_IPR_SCP (1<<5)
+#define RBIT_IPR_TIMER3 (1<<4)
+#define RBIT_IPR_SMC1 (1<<3)
+#define RBIT_IPR_SMC2 (1<<2)
+#define RBIT_IPR_PB8 (1<<1)
+#define RBIT_IPR_ERR (1<<0)
+
+#define RBIT_ISR_PB11 (1<<15)
+#define RBIT_ISR_PB10 (1<<14)
+#define RBIT_ISR_SCC1 (1<<13)
+#define RBIT_ISR_SDMA (1<<12)
+#define RBIT_ISR_IDMA (1<<11)
+#define RBIT_ISR_SCC2 (1<<10)
+#define RBIT_ISR_TIMER1 (1<<9)
+#define RBIT_ISR_SCC3 (1<<8)
+#define RBIT_ISR_PB9 (1<<7)
+#define RBIT_ISR_TIMER2 (1<<6)
+#define RBIT_ISR_SCP (1<<5)
+#define RBIT_ISR_TIMER3 (1<<4)
+#define RBIT_ISR_SMC1 (1<<3)
+#define RBIT_ISR_SMC2 (1<<2)
+#define RBIT_ISR_PB8 (1<<1)
+
+#define RBIT_IMR_PB11 (1<<15) /* PB11 Interrupt Mask */
+#define RBIT_IMR_PB10 (1<<14) /* PB10 Interrupt Mask */
+#define RBIT_IMR_SCC1 (1<<13) /* SCC1 Interrupt Mask */
+#define RBIT_IMR_SDMA (1<<12) /* SDMA Interrupt Mask */
+#define RBIT_IMR_IDMA (1<<11) /* IDMA Interrupt Mask */
+#define RBIT_IMR_SCC2 (1<<10) /* SCC2 Interrupt Mask */
+#define RBIT_IMR_TIMER1 (1<<9) /* TIMER1 Interrupt Mask */
+#define RBIT_IMR_SCC3 (1<<8) /* SCC3 Interrupt Mask */
+#define RBIT_IMR_PB9 (1<<7) /* PB9 Interrupt Mask */
+#define RBIT_IMR_TIMER2 (1<<6) /* TIMER2 Interrupt Mask */
+#define RBIT_IMR_SCP (1<<5) /* SCP Interrupt Mask */
+#define RBIT_IMR_TIMER3 (1<<4) /* TIMER3 Interrupt Mask */
+#define RBIT_IMR_SMC1 (1<<3) /* SMC1 Interrupt Mask */
+#define RBIT_IMR_SMC2 (1<<2) /* SMC2 Interrupt Mask */
+#define RBIT_IMR_PB8 (1<<1) /* PB8 Interrupt Mask */
+
+
+/*
+ * DRAM Refresh
+ * Section 3.9
+ *
+ * The DRAM refresh memory map replaces the SCC2 Tx BD 6 and Tx BD 7
+ * structures in the parameter RAM.
+ *
+ * Access to the DRAM registers can be accomplished by
+ * the following approach:
+ *
+ * volatile m302_DRAM_refresh_t *dram;
+ * dram = (volatile m302_DRAM_refresh_t *) &m302.scc2.bd.tx[6];
+ *
+ * Then simply use pointer references (e.g. dram->count = 3).
+ */
+typedef struct {
+ uint16_t dram_high; /* DRAM high address and FC */
+ uint16_t dram_low; /* DRAM low address */
+ uint16_t increment; /* increment step (bytes/row) */
+ uint16_t count; /* RAM refresh cycle count (#rows) */
+ uint16_t t_ptr_h; /* temporary refresh high addr & FC */
+ uint16_t t_ptr_l; /* temporary refresh low address */
+ uint16_t t_count; /* temporary refresh cycles count */
+ uint16_t res; /* reserved */
+} m302_DRAM_refresh_t;
+
+
+/*
+ * TMR - Timer Mode Register (for timers 1 and 2)
+ * Section 3.5.2.1
+ */
+#define RBIT_TMR_ICLK_STOP (0<<1)
+#define RBIT_TMR_ICLK_MASTER (1<<1)
+#define RBIT_TMR_ICLK_MASTER16 (2<<1)
+#define RBIT_TMR_ICLK_TIN (3<<1)
+
+#define RBIT_TMR_OM (1<<5)
+#define RBIT_TMR_ORI (1<<4)
+#define RBIT_TMR_FRR (1<<3)
+#define RBIT_TMR_RST (1<<0)
+
+
+/*
+ * TER - Timer Event Register (for timers 1 and 2)
+ * Section 3.5.2.5
+ */
+#define RBIT_TER_REF (1<<1) /* Output Reference Event */
+#define RBIT_TER_CAP (1<<0) /* Capture Event */
+
+
+/*
+ * SCC Buffer Descriptors and Buffer Descriptors Table
+ * Section 4.5.5
+ */
+typedef struct m302_SCC_bd {
+ uint16_t status; /* status and control */
+ uint16_t length; /* data length */
+ volatile uint8_t *buffer; /* data buffer pointer */
+} m302_SCC_bd_t;
+
+typedef struct {
+ m302_SCC_bd_t rx[8]; /* receive buffer descriptors */
+ m302_SCC_bd_t tx[8]; /* transmit buffer descriptors */
+} m302_SCC_bd_table_t;
+
+
+/*
+ * SCC Parameter RAM (offset 0x080 from an SCC Base)
+ * Section 4.5.6
+ *
+ * Each SCC parameter RAM area begins at offset 0x80 from each SCC base
+ * area (0x400, 0x500, or 0x600 from the dual-port RAM base).
+ *
+ * Offsets 0x9c-0xbf from each SCC base area compose the protocol-specific
+ * portion of the SCC parameter RAM.
+ */
+typedef struct {
+ uint8_t rfcr; /* Rx Function Code */
+ uint8_t tfcr; /* Tx Function Code */
+ uint16_t mrblr; /* Maximum Rx Buffer Length */
+ uint16_t _rstate; /* Rx Internal State */
+ uint8_t res2;
+ uint8_t rbd; /* Rx Internal Buffer Number */
+ uint32_t _rdptr; /* Rx Internal Data Pointer */
+ uint16_t _rcount; /* Rx Internal Byte Count */
+ uint16_t _rtmp; /* Rx Temp */
+ uint16_t _tstate; /* Tx Internal State */
+ uint8_t res7;
+ uint8_t tbd; /* Tx Internal Buffer Number */
+ uint32_t _tdptr; /* Tx Internal Data Pointer */
+ uint16_t _tcount; /* Tx Internal Byte Count */
+ uint16_t _ttmp; /* Tx Temp */
+} m302_SCC_parameters_t;
+
+/*
+ * UART-Specific SCC Parameter RAM
+ * Section 4.5.11.3
+ */
+typedef struct {
+ uint16_t max_idl; /* Maximum IDLE Characters (rx) */
+ uint16_t idlc; /* Temporary rx IDLE counter */
+ uint16_t brkcr; /* Break Count Register (tx) */
+ uint16_t parec; /* Receive Parity Error Counter */
+ uint16_t frmec; /* Receive Framing Error Counter */
+ uint16_t nosec; /* Receive Noise Counter */
+ uint16_t brkec; /* Receive Break Condition Counter */
+ uint16_t uaddr1; /* UART ADDRESS Character 1 */
+ uint16_t uaddr2; /* UART ADDRESS Character 2 */
+ uint16_t rccr; /* Receive Control Character Register */
+ uint16_t character[8]; /* Control Characters 1 through 8*/
+} m302_SCC_UartSpecific_t;
+/*
+ * This definition allows for the checking of receive buffers
+ * for errors.
+ */
+
+#define RCV_ERR 0x003F
+
+/*
+ * UART receive buffer descriptor bit definitions.
+ * Section 4.5.11.14
+ */
+#define RBIT_UART_CTRL (1<<11) /* buffer contains a control char */
+#define RBIT_UART_ADDR (1<<10) /* first byte contains an address */
+#define RBIT_UART_MATCH (1<<9) /* indicates which addr char matched */
+#define RBIT_UART_IDLE (1<<8) /* buffer closed due to IDLE sequence */
+#define RBIT_UART_BR (1<<5) /* break sequence was received */
+#define RBIT_UART_FR (1<<4) /* framing error was received */
+#define RBIT_UART_PR (1<<3) /* parity error was received */
+#define RBIT_UART_OV (1<<1) /* receiver overrun occurred */
+#define RBIT_UART_CD (1<<0) /* carrier detect lost */
+#define RBIT_UART_STATUS 0x003B /* all status bits */
+
+/*
+ * UART transmit buffer descriptor bit definitions.
+ * Section 4.5.11.15
+ */
+#define RBIT_UART_CR (1<<11) /* clear-to-send report
+ * this results in two idle bits
+ * between back-to-back frames
+ */
+#define RBIT_UART_A (1<<10) /* buffer contains address characters
+ * only valid in multidrop mode (UM0=1)
+ */
+#define RBIT_UART_PREAMBLE (1<<9) /* send preamble before data */
+#define RBIT_UART_CTS_LOST (1<<0) /* CTS lost */
+
+/*
+ * UART event register
+ * Section 4.5.11.16
+ */
+#define M302_UART_EV_CTS (1<<7) /* CTS status changed */
+#define M302_UART_EV_CD (1<<6) /* carrier detect status changed */
+#define M302_UART_EV_IDL (1<<5) /* IDLE sequence status changed */
+#define M302_UART_EV_BRK (1<<4) /* break character was received */
+#define M302_UART_EV_CCR (1<<3) /* control character received */
+#define M302_UART_EV_TX (1<<1) /* buffer has been transmitted */
+#define M302_UART_EV_RX (1<<0) /* buffer has been received */
+
+
+/*
+ * HDLC-Specific SCC Parameter RAM
+ * Section 4.5.12.3
+ *
+ * c_mask_l should be 0xF0B8 for 16-bit CRC, 0xdebb for 32-bit CRC
+ * c_mask_h is a don't care for 16-bit CRC, 0x20E2 for 32-bit CRC
+ */
+typedef struct {
+ uint16_t rcrc_l; /* Temp Receive CRC Low */
+ uint16_t rcrc_h; /* Temp Receive CRC High */
+ uint16_t c_mask_l; /* CRC Mask Low */
+ uint16_t c_mask_h; /* CRC Mask High */
+ uint16_t tcrc_l; /* Temp Transmit CRC Low */
+ uint16_t tcrc_h; /* Temp Transmit CRC High */
+
+ uint16_t disfc; /* Discard Frame Counter */
+ uint16_t crcec; /* CRC Error Counter */
+ uint16_t abtsc; /* Abort Sequence Counter */
+ uint16_t nmarc; /* Nonmatching Address Received Cntr */
+ uint16_t retrc; /* Frame Retransmission Counter */
+
+ uint16_t mflr; /* Maximum Frame Length Register */
+ uint16_t max_cnt; /* Maximum_Length Counter */
+
+ uint16_t hmask; /* User Defined Frame Address Mask */
+ uint16_t haddr1; /* User Defined Frame Address */
+ uint16_t haddr2; /* " */
+ uint16_t haddr3; /* " */
+ uint16_t haddr4; /* " */
+} m302_SCC_HdlcSpecific_t;
+/*
+ * HDLC receiver buffer descriptor bit definitions
+ * Section 4.5.12.10
+ */
+#define RBIT_HDLC_EMPTY_BIT 0x8000 /* buffer associated with BD is empty */
+#define RBIT_HDLC_LAST_BIT 0x0800 /* buffer is last in a frame */
+#define RBIT_HDLC_FIRST_BIT 0x0400 /* buffer is first in a frame */
+#define RBIT_HDLC_FRAME_LEN 0x0020 /* receiver frame length violation */
+#define RBIT_HDLC_NONOCT_Rx 0x0010 /* received non-octet aligned frame */
+#define RBIT_HDLC_ABORT_SEQ 0x0008 /* received abort sequence */
+#define RBIT_HDLC_CRC_ERROR 0x0004 /* frame contains a CRC error */
+#define RBIT_HDLC_OVERRUN 0x0002 /* receiver overrun occurred */
+#define RBIT_HDLC_CD_LOST 0x0001 /* carrier detect lost */
+
+/*
+ * HDLC transmit buffer descriptor bit definitions
+ * Section 4.5.12.11
+ */
+#define RBIT_HDLC_READY_BIT 0x8000 /* buffer is ready to transmit */
+#define RBIT_HDLC_EXT_BUFFER 0x4000 /* buffer is in external memory */
+#define RBIT_HDLC_WRAP_BIT 0x2000 /* last buffer in bd table, so wrap */
+#define RBIT_HDLC_WAKE_UP 0x1000 /* interrupt when buffer serviced */
+#define RBIT_HDLC_LAST_BIT 0x0800 /* buffer is last in the frame */
+#define RBIT_HDLC_TxCRC_BIT 0x0400 /* transmit a CRC sequence */
+#define RBIT_HDLC_UNDERRUN 0x0002 /* transmitter underrun */
+#define RBIT_HDLC_CTS_LOST 0x0001 /* CTS lost */
+
+/*
+ * HDLC event register bit definitions
+ * Section 4.5.12.12
+ */
+#define RBIT_HDLC_CTS 0x80 /* CTS status changed */
+#define RBIT_HDLC_CD 0x40 /* carrier detect status changed */
+#define RBIT_HDLC_IDL 0x20 /* IDLE sequence status changed */
+#define RBIT_HDLC_TXE 0x10 /* transmit error */
+#define RBIT_HDLC_RXF 0x08 /* received frame */
+#define RBIT_HDLC_BSY 0x04 /* frame rcvd and discarded due to
+ * lack of buffers
+ */
+#define RBIT_HDLC_TXB 0x02 /* buffer has been transmitted */
+#define RBIT_HDLC_RXB 0x01 /* received buffer */
+
+
+
+typedef struct {
+ m302_SCC_bd_table_t bd; /* +000 Buffer Descriptor Table */
+ m302_SCC_parameters_t parm; /* +080 Common Parameter RAM */
+ union { /* +09C Protocol-Specific Parm RAM */
+ m302_SCC_UartSpecific_t uart;
+ m302_SCC_HdlcSpecific_t hdlc;
+ } prot;
+ uint8_t res[0x040]; /* +0C0 reserved, (not implemented) */
+} m302_SCC_t;
+
+
+/*
+ * Common SCC Registers
+ */
+typedef struct {
+ uint16_t res1;
+ uint16_t scon; /* SCC Configuration Register 4.5.2 */
+ uint16_t scm; /* SCC Mode Register 4.5.3 */
+ uint16_t dsr; /* SCC Data Synchronization Register 4.5.4 */
+ uint8_t scce; /* SCC Event Register 4.5.8.1 */
+ uint8_t res2;
+ uint8_t sccm; /* SCC Mask Register 4.5.8.2 */
+ uint8_t res3;
+ uint8_t sccs; /* SCC Status Register 4.5.8.3 */
+ uint8_t res4;
+ uint16_t res5;
+} m302_SCC_Registers_t;
+
+/*
+ * SCON - SCC Configuration Register
+ * Section 4.5.2
+ */
+#define RBIT_SCON_WOMS (1<<15) /* Wired-OR Mode Select (NMSI mode only)
+ * When set, the TXD driver is an
+ * open-drain output */
+#define RBIT_SCON_EXTC (1<<14) /* External Clock Source */
+#define RBIT_SCON_TCS (1<<13) /* Transmit Clock Source */
+#define RBIT_SCON_RCS (1<<12) /* Receive Clock Source */
+
+/*
+ * SCM - SCC Mode Register bit definitions
+ * Section 4.5.3
+ * The parameter-specific mode bits occupy bits 15 through 6.
+ */
+#define RBIT_SCM_ENR (1<<3) /* Enable receiver */
+#define RBIT_SCM_ENT (1<<2) /* Enable transmitter */
+
+
+/*
+ * Internal MC68302 Registers
+ * starts at offset 0x800 from dual-port RAM base
+ * Section 2.8
+ */
+typedef struct {
+ /* offset +800 */
+ uint16_t res0;
+ uint16_t cmr; /* IDMA Channel Mode Register */
+ uint32_t sapr; /* IDMA Source Address Pointer */
+ uint32_t dapr; /* IDMA Destination Address Pointer */
+ uint16_t bcr; /* IDMA Byte Count Register */
+ uint8_t csr; /* IDMA Channel Status Register */
+ uint8_t res1;
+ uint8_t fcr; /* IDMA Function Code Register */
+ uint8_t res2;
+
+ /* offset +812 */
+ uint16_t gimr; /* Global Interrupt Mode Register */
+ uint16_t ipr; /* Interrupt Pending Register */
+ uint16_t imr; /* Interrupt Mask Register */
+ uint16_t isr; /* Interrupt In-Service Register */
+ uint16_t res3;
+ uint16_t res4;
+
+ /* offset +81e */
+ uint16_t pacnt; /* Port A Control Register */
+ uint16_t paddr; /* Port A Data Direction Register */
+ uint16_t padat; /* Port A Data Register */
+ uint16_t pbcnt; /* Port B Control Register */
+ uint16_t pbddr; /* Port B Data Direction Register */
+ uint16_t pbdat; /* Port B Data Register */
+ uint16_t res5;
+
+ /* offset +82c */
+ uint16_t res6;
+ uint16_t res7;
+
+ uint16_t br0; /* Base Register (CS0) */
+ uint16_t or0; /* Option Register (CS0) */
+ uint16_t br1; /* Base Register (CS1) */
+ uint16_t or1; /* Option Register (CS1) */
+ uint16_t br2; /* Base Register (CS2) */
+ uint16_t or2; /* Option Register (CS2) */
+ uint16_t br3; /* Base Register (CS3) */
+ uint16_t or3; /* Option Register (CS3) */
+
+ /* offset +840 */
+ uint16_t tmr1; /* Timer Unit 1 Mode Register */
+ uint16_t trr1; /* Timer Unit 1 Reference Register */
+ uint16_t tcr1; /* Timer Unit 1 Capture Register */
+ uint16_t tcn1; /* Timer Unit 1 Counter */
+ uint8_t res8;
+ uint8_t ter1; /* Timer Unit 1 Event Register */
+ uint16_t wrr; /* Watchdog Reference Register */
+ uint16_t wcn; /* Watchdog Counter */
+ uint16_t res9;
+ uint16_t tmr2; /* Timer Unit 2 Mode Register */
+ uint16_t trr2; /* Timer Unit 2 Reference Register */
+ uint16_t tcr2; /* Timer Unit 2 Capture Register */
+ uint16_t tcn2; /* Timer Unit 2 Counter */
+ uint8_t resa;
+ uint8_t ter2; /* Timer Unit 2 Event Register */
+ uint16_t resb;
+ uint16_t resc;
+ uint16_t resd;
+
+ /* offset +860 */
+ uint8_t cr; /* Command Register */
+ uint8_t rese[0x1f];
+
+ /* offset +880, +890, +8a0 */
+ m302_SCC_Registers_t scc[3]; /* SCC1, SCC2, SCC3 Registers */
+
+ /* offset +8b0 */
+ uint16_t spmode; /* SCP,SMC Mode and Clock Cntrl Reg */
+ uint16_t simask; /* Serial Interface Mask Register */
+ uint16_t simode; /* Serial Interface Mode Register */
+} m302_internalReg_t ;
+
+
+/*
+ * MC68302 dual-port RAM structure.
+ * (Includes System RAM, Parameter RAM, and Internal Registers).
+ * Section 2.8
+ */
+typedef struct {
+ uint8_t mem[0x240]; /* +000 User Data Memory */
+ uint8_t res1[0x1c0]; /* +240 reserved, (not implemented) */
+ m302_SCC_t scc1; /* +400 SCC1 */
+ m302_SCC_t scc2; /* +500 SCC2 */
+ m302_SCC_t scc3; /* +600 SCC3 */
+ uint8_t res2[0x100]; /* +700 reserved, (not implemented) */
+ m302_internalReg_t reg; /* +800 68302 Internal Registers */
+} m302_dualPortRAM_t;
+
+/* some useful defines the some of the registers above */
+
+
+/* ----
+ MC68302 Chip Select Registers
+ p3-46 2nd Edition
+
+ */
+#define BR_ENABLED 1
+#define BR_DISABLED 0
+#define BR_FC_NULL 0
+#define BR_READ_ONLY 0
+#define BR_READ_WRITE 2
+#define OR_DTACK_0 0x0000
+#define OR_DTACK_1 0x2000
+#define OR_DTACK_2 0x4000
+#define OR_DTACK_3 0x6000
+#define OR_DTACK_4 0x8000
+#define OR_DTACK_5 0xA000
+#define OR_DTACK_6 0xC000
+#define OR_DTACK_EXT 0xE000
+#define OR_SIZE_64K 0x1FE0
+#define OR_SIZE_128K 0x1FC0
+#define OR_SIZE_256K 0x1F80
+#define OR_SIZE_512K 0x1F00
+#define OR_SIZE_1M 0x1E00
+#define OR_SIZE_2M 0x1C00
+#define OR_MASK_RW 0x0000
+#define OR_NO_MASK_RW 0x0002
+#define OR_MASK_FC 0x0000
+#define OR_NO_MASK_FC 0x0001
+
+#define MAKE_BR(base_address, enable, rw, fc) \
+ ((base_address >> 11) | fc | rw | enable)
+
+#define MAKE_OR(bsize, DtAck, RW_Mask, FC_Mask) \
+ (DtAck | ((~(bsize - 1) & 0x00FFFFFF) >> 11) | FC_Mask | RW_Mask)
+
+#define __REG_CAT(r, n) r ## n
+#define WRITE_BR(csel, base_address, enable, rw, fc) \
+ __REG_CAT(m302.reg.br, csel) = MAKE_BR(base_address, enable, rw, fc)
+#define WRITE_OR(csel, bsize, DtAck, RW_Mask, FC_Mask) \
+ __REG_CAT(m302.reg.or, csel) = MAKE_OR(bsize, DtAck, RW_Mask, FC_Mask)
+
+/* ----
+ MC68302 Watchdog Timer Enable Bit
+
+ */
+#define WATCHDOG_ENABLE (1)
+#define WATCHDOG_TRIGGER() (m302.reg.wrr = 0x10 | WATCHDOG_ENABLE, m302.reg.wcn = 0)
+#define WATCHDOG_TOGGLE() (m302.reg.wcn = WATCHDOG_TIMEOUT_PERIOD)
+#define DISABLE_WATCHDOG() (m302.reg.wrr = 0)
+
+/*
+ * Declare the variable that's used to reference the variables in
+ * the dual-port RAM.
+ */
+extern volatile m302_dualPortRAM_t m302;
+
+#endif
diff --git a/cpukit/score/cpu/m68k/rtems/m68k/m68360.h b/cpukit/score/cpu/m68k/rtems/m68k/m68360.h
new file mode 100644
index 0000000000..d36b8b5908
--- /dev/null
+++ b/cpukit/score/cpu/m68k/rtems/m68k/m68360.h
@@ -0,0 +1,889 @@
+/*
+ **************************************************************************
+ **************************************************************************
+ ** **
+ ** MOTOROLA MC68360 QUAD INTEGRATED COMMUNICATIONS CONTROLLER (QUICC) **
+ ** **
+ ** HARDWARE DECLARATIONS **
+ ** **
+ ** **
+ ** Submitted By: **
+ ** **
+ ** W. Eric Norum **
+ ** Saskatchewan Accelerator Laboratory **
+ ** University of Saskatchewan **
+ ** 107 North Road **
+ ** Saskatoon, Saskatchewan, CANADA **
+ ** S7N 5C6 **
+ ** **
+ ** eric@skatter.usask.ca **
+ ** **
+ ** $Id$ **
+ ** **
+ **************************************************************************
+ **************************************************************************
+ */
+
+#ifndef _RTEMS_M68K_M68360_H
+#define _RTEMS_M68K_M68360_H
+
+/*
+ *************************************************************************
+ * REGISTER SUBBLOCKS *
+ *************************************************************************
+ */
+
+/*
+ * Memory controller registers
+ */
+typedef struct m360MEMCRegisters_ {
+ unsigned long br;
+ unsigned long or;
+ unsigned long _pad[2];
+} m360MEMCRegisters_t;
+
+/*
+ * Serial Communications Controller registers
+ */
+typedef struct m360SCCRegisters_ {
+ unsigned long gsmr_l;
+ unsigned long gsmr_h;
+ unsigned short psmr;
+ unsigned short _pad0;
+ unsigned short todr;
+ unsigned short dsr;
+ unsigned short scce;
+ unsigned short _pad1;
+ unsigned short sccm;
+ unsigned char _pad2;
+ unsigned char sccs;
+ unsigned long _pad3[2];
+} m360SCCRegisters_t;
+
+/*
+ * Serial Management Controller registers
+ */
+typedef struct m360SMCRegisters_ {
+ unsigned short _pad0;
+ unsigned short smcmr;
+ unsigned short _pad1;
+ unsigned char smce;
+ unsigned char _pad2;
+ unsigned short _pad3;
+ unsigned char smcm;
+ unsigned char _pad4;
+ unsigned long _pad5;
+} m360SMCRegisters_t;
+
+
+/*
+ *************************************************************************
+ * Miscellaneous Parameters *
+ *************************************************************************
+ */
+typedef struct m360MiscParms_ {
+ unsigned short rev_num;
+ unsigned short _res1;
+ unsigned long _res2;
+ unsigned long _res3;
+} m360MiscParms_t;
+
+/*
+ *************************************************************************
+ * RISC Timers *
+ *************************************************************************
+ */
+typedef struct m360TimerParms_ {
+ unsigned short tm_base;
+ unsigned short _tm_ptr;
+ unsigned short _r_tmr;
+ unsigned short _r_tmv;
+ unsigned long tm_cmd;
+ unsigned long tm_cnt;
+} m360TimerParms_t;
+
+/*
+ * RISC Controller Configuration Register (RCCR)
+ * All other bits in this register are either reserved or
+ * used only with a Motorola-supplied RAM microcode packge.
+ */
+#define M360_RCCR_TIME (1<<15) /* Enable timer */
+#define M360_RCCR_TIMEP(x) ((x)<<8) /* Timer period */
+
+/*
+ * Command register
+ * Set up this register before issuing a M360_CR_OP_SET_TIMER command.
+ */
+#define M360_TM_CMD_V (1<<31) /* Set to enable timer */
+#define M360_TM_CMD_R (1<<30) /* Set for automatic restart */
+#define M360_TM_CMD_TIMER(x) ((x)<<16) /* Select timer */
+#define M360_TM_CMD_PERIOD(x) (x) /* Timer period (16 bits) */
+
+/*
+ *************************************************************************
+ * DMA Controllers *
+ *************************************************************************
+ */
+typedef struct m360IDMAparms_ {
+ unsigned short ibase;
+ unsigned short ibptr;
+ unsigned long _istate;
+ unsigned long _itemp;
+} m360IDMAparms_t;
+
+/*
+ *************************************************************************
+ * Serial Communication Controllers *
+ *************************************************************************
+ */
+typedef struct m360SCCparms_ {
+ unsigned short rbase;
+ unsigned short tbase;
+ unsigned char rfcr;
+ unsigned char tfcr;
+ unsigned short mrblr;
+ unsigned long _rstate;
+ unsigned long _pad0;
+ unsigned short _rbptr;
+ unsigned short _pad1;
+ unsigned long _pad2;
+ unsigned long _tstate;
+ unsigned long _pad3;
+ unsigned short _tbptr;
+ unsigned short _pad4;
+ unsigned long _pad5;
+ unsigned long _rcrc;
+ unsigned long _tcrc;
+ union {
+ struct {
+ unsigned long _res0;
+ unsigned long _res1;
+ unsigned short max_idl;
+ unsigned short _idlc;
+ unsigned short brkcr;
+ unsigned short parec;
+ unsigned short frmec;
+ unsigned short nosec;
+ unsigned short brkec;
+ unsigned short brklen;
+ unsigned short uaddr[2];
+ unsigned short _rtemp;
+ unsigned short toseq;
+ unsigned short character[8];
+ unsigned short rccm;
+ unsigned short rccr;
+ unsigned short rlbc;
+ } uart;
+ struct {
+ unsigned long crc_p;
+ unsigned long crc_c;
+ } transparent;
+
+ } un;
+} m360SCCparms_t;
+
+typedef struct m360SCCENparms_ {
+ unsigned short rbase;
+ unsigned short tbase;
+ unsigned char rfcr;
+ unsigned char tfcr;
+ unsigned short mrblr;
+ unsigned long _rstate;
+ unsigned long _pad0;
+ unsigned short _rbptr;
+ unsigned short _pad1;
+ unsigned long _pad2;
+ unsigned long _tstate;
+ unsigned long _pad3;
+ unsigned short _tbptr;
+ unsigned short _pad4;
+ unsigned long _pad5;
+ unsigned long _rcrc;
+ unsigned long _tcrc;
+ union {
+ struct {
+ unsigned long _res0;
+ unsigned long _res1;
+ unsigned short max_idl;
+ unsigned short _idlc;
+ unsigned short brkcr;
+ unsigned short parec;
+ unsigned short frmec;
+ unsigned short nosec;
+ unsigned short brkec;
+ unsigned short brklen;
+ unsigned short uaddr[2];
+ unsigned short _rtemp;
+ unsigned short toseq;
+ unsigned short character[8];
+ unsigned short rccm;
+ unsigned short rccr;
+ unsigned short rlbc;
+ } uart;
+ struct {
+ unsigned long c_pres;
+ unsigned long c_mask;
+ unsigned long crcec;
+ unsigned long alec;
+ unsigned long disfc;
+ unsigned short pads;
+ unsigned short ret_lim;
+ unsigned short _ret_cnt;
+ unsigned short mflr;
+ unsigned short minflr;
+ unsigned short maxd1;
+ unsigned short maxd2;
+ unsigned short _maxd;
+ unsigned short dma_cnt;
+ unsigned short _max_b;
+ unsigned short gaddr1;
+ unsigned short gaddr2;
+ unsigned short gaddr3;
+ unsigned short gaddr4;
+ unsigned long _tbuf0data0;
+ unsigned long _tbuf0data1;
+ unsigned long _tbuf0rba0;
+ unsigned long _tbuf0crc;
+ unsigned short _tbuf0bcnt;
+ unsigned short paddr_h;
+ unsigned short paddr_m;
+ unsigned short paddr_l;
+ unsigned short p_per;
+ unsigned short _rfbd_ptr;
+ unsigned short _tfbd_ptr;
+ unsigned short _tlbd_ptr;
+ unsigned long _tbuf1data0;
+ unsigned long _tbuf1data1;
+ unsigned long _tbuf1rba0;
+ unsigned long _tbuf1crc;
+ unsigned short _tbuf1bcnt;
+ unsigned short _tx_len;
+ unsigned short iaddr1;
+ unsigned short iaddr2;
+ unsigned short iaddr3;
+ unsigned short iaddr4;
+ unsigned short _boff_cnt;
+ unsigned short taddr_h;
+ unsigned short taddr_m;
+ unsigned short taddr_l;
+ } ethernet;
+ struct {
+ unsigned long crc_p;
+ unsigned long crc_c;
+ } transparent;
+ } un;
+} m360SCCENparms_t;
+
+/*
+ * Receive and transmit function code register bits
+ * These apply to the function code registers of all devices, not just SCC.
+ */
+#define M360_RFCR_MOT (1<<4)
+#define M360_RFCR_DMA_SPACE 0x8
+#define M360_TFCR_MOT (1<<4)
+#define M360_TFCR_DMA_SPACE 0x8
+
+/*
+ *************************************************************************
+ * Serial Management Controllers *
+ *************************************************************************
+ */
+typedef struct m360SMCparms_ {
+ unsigned short rbase;
+ unsigned short tbase;
+ unsigned char rfcr;
+ unsigned char tfcr;
+ unsigned short mrblr;
+ unsigned long _rstate;
+ unsigned long _pad0;
+ unsigned short _rbptr;
+ unsigned short _pad1;
+ unsigned long _pad2;
+ unsigned long _tstate;
+ unsigned long _pad3;
+ unsigned short _tbptr;
+ unsigned short _pad4;
+ unsigned long _pad5;
+ union {
+ struct {
+ unsigned short max_idl;
+ unsigned short _pad0;
+ unsigned short brklen;
+ unsigned short brkec;
+ unsigned short brkcr;
+ unsigned short _r_mask;
+ } uart;
+ struct {
+ unsigned short _pad0[5];
+ } transparent;
+ } un;
+} m360SMCparms_t;
+
+/*
+ * Mode register
+ */
+#define M360_SMCMR_CLEN(x) ((x)<<11) /* Character length */
+#define M360_SMCMR_2STOP (1<<10) /* 2 stop bits */
+#define M360_SMCMR_PARITY (1<<9) /* Enable parity */
+#define M360_SMCMR_EVEN (1<<8) /* Even parity */
+#define M360_SMCMR_SM_GCI (0<<4) /* GCI Mode */
+#define M360_SMCMR_SM_UART (2<<4) /* UART Mode */
+#define M360_SMCMR_SM_TRANSPARENT (3<<4) /* Transparent Mode */
+#define M360_SMCMR_DM_LOOPBACK (1<<2) /* Local loopback mode */
+#define M360_SMCMR_DM_ECHO (2<<2) /* Echo mode */
+#define M360_SMCMR_TEN (1<<1) /* Enable transmitter */
+#define M360_SMCMR_REN (1<<0) /* Enable receiver */
+
+/*
+ * Event and mask registers (SMCE, SMCM)
+ */
+#define M360_SMCE_BRK (1<<4)
+#define M360_SMCE_BSY (1<<2)
+#define M360_SMCE_TX (1<<1)
+#define M360_SMCE_RX (1<<0)
+
+/*
+ *************************************************************************
+ * Serial Peripheral Interface *
+ *************************************************************************
+ */
+typedef struct m360SPIparms_ {
+ unsigned short rbase;
+ unsigned short tbase;
+ unsigned char rfcr;
+ unsigned char tfcr;
+ unsigned short mrblr;
+ unsigned long _rstate;
+ unsigned long _pad0;
+ unsigned short _rbptr;
+ unsigned short _pad1;
+ unsigned long _pad2;
+ unsigned long _tstate;
+ unsigned long _pad3;
+ unsigned short _tbptr;
+ unsigned short _pad4;
+ unsigned long _pad5;
+} m360SPIparms_t;
+
+/*
+ * Mode register (SPMODE)
+ */
+#define M360_SPMODE_LOOP (1<<14) /* Local loopback mode */
+#define M360_SPMODE_CI (1<<13) /* Clock invert */
+#define M360_SPMODE_CP (1<<12) /* Clock phase */
+#define M360_SPMODE_DIV16 (1<<11) /* Divide BRGCLK by 16 */
+#define M360_SPMODE_REV (1<<10) /* Reverse data */
+#define M360_SPMODE_MASTER (1<<9) /* SPI is master */
+#define M360_SPMODE_EN (1<<8) /* Enable SPI */
+#define M360_SPMODE_CLEN(x) ((x)<<4) /* Character length */
+#define M360_SPMODE_PM(x) (x) /* Prescaler modulus */
+
+/*
+ * Mode register (SPCOM)
+ */
+#define M360_SPCOM_STR (1<<7) /* Start transmit */
+
+/*
+ * Event and mask registers (SPIE, SPIM)
+ */
+#define M360_SPIE_MME (1<<5) /* Multi-master error */
+#define M360_SPIE_TXE (1<<4) /* Tx error */
+#define M360_SPIE_BSY (1<<2) /* Busy condition*/
+#define M360_SPIE_TXB (1<<1) /* Tx buffer */
+#define M360_SPIE_RXB (1<<0) /* Rx buffer */
+
+/*
+ *************************************************************************
+ * SDMA (SCC, SMC, SPI) Buffer Descriptors *
+ *************************************************************************
+ */
+typedef struct m360BufferDescriptor_ {
+ unsigned short status;
+ unsigned short length;
+ volatile void *buffer;
+} m360BufferDescriptor_t;
+
+/*
+ * Bits in receive buffer descriptor status word
+ */
+#define M360_BD_EMPTY (1<<15) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_WRAP (1<<13) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_INTERRUPT (1<<12) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_LAST (1<<11) /* Ethernet, SPI */
+#define M360_BD_CONTROL_CHAR (1<<11) /* SCC UART */
+#define M360_BD_FIRST_IN_FRAME (1<<10) /* Ethernet */
+#define M360_BD_ADDRESS (1<<10) /* SCC UART */
+#define M360_BD_CONTINUOUS (1<<9) /* SCC UART, SMC UART, SPI */
+#define M360_BD_MISS (1<<8) /* Ethernet */
+#define M360_BD_IDLE (1<<8) /* SCC UART, SMC UART */
+#define M360_BD_ADDRSS_MATCH (1<<7) /* SCC UART */
+#define M360_BD_LONG (1<<5) /* Ethernet */
+#define M360_BD_BREAK (1<<5) /* SCC UART, SMC UART */
+#define M360_BD_NONALIGNED (1<<4) /* Ethernet */
+#define M360_BD_FRAMING_ERROR (1<<4) /* SCC UART, SMC UART */
+#define M360_BD_SHORT (1<<3) /* Ethernet */
+#define M360_BD_PARITY_ERROR (1<<3) /* SCC UART, SMC UART */
+#define M360_BD_CRC_ERROR (1<<2) /* Ethernet */
+#define M360_BD_OVERRUN (1<<1) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_COLLISION (1<<0) /* Ethernet */
+#define M360_BD_CARRIER_LOST (1<<0) /* SCC UART */
+#define M360_BD_MASTER_ERROR (1<<0) /* SPI */
+
+/*
+ * Bits in transmit buffer descriptor status word
+ * Many bits have the same meaning as those in receiver buffer descriptors.
+ */
+#define M360_BD_READY (1<<15) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_PAD (1<<14) /* Ethernet */
+#define M360_BD_CTS_REPORT (1<<11) /* SCC UART */
+#define M360_BD_TX_CRC (1<<10) /* Ethernet */
+#define M360_BD_DEFER (1<<9) /* Ethernet */
+#define M360_BD_HEARTBEAT (1<<8) /* Ethernet */
+#define M360_BD_PREAMBLE (1<<8) /* SCC UART, SMC UART */
+#define M360_BD_LATE_COLLISION (1<<7) /* Ethernet */
+#define M360_BD_NO_STOP_BIT (1<<7) /* SCC UART */
+#define M360_BD_RETRY_LIMIT (1<<6) /* Ethernet */
+#define M360_BD_RETRY_COUNT(x) (((x)&0x3C)>>2) /* Ethernet */
+#define M360_BD_UNDERRUN (1<<1) /* Ethernet, SPI */
+#define M360_BD_CARRIER_LOST (1<<0) /* Ethernet */
+#define M360_BD_CTS_LOST (1<<0) /* SCC UART */
+
+/*
+ *************************************************************************
+ * IDMA Buffer Descriptors *
+ *************************************************************************
+ */
+typedef struct m360IDMABufferDescriptor_ {
+ unsigned short status;
+ unsigned short _pad;
+ unsigned long length;
+ void *source;
+ void *destination;
+} m360IDMABufferDescriptor_t;
+
+/*
+ *************************************************************************
+ * RISC Communication Processor Module Command Register (CR) *
+ *************************************************************************
+ */
+#define M360_CR_RST (1<<15) /* Reset communication processor */
+#define M360_CR_OP_INIT_RX_TX (0<<8) /* SCC, SMC UART, SMC GCI, SPI */
+#define M360_CR_OP_INIT_RX (1<<8) /* SCC, SMC UART, SPI */
+#define M360_CR_OP_INIT_TX (2<<8) /* SCC, SMC UART, SPI */
+#define M360_CR_OP_INIT_HUNT (3<<8) /* SCC, SMC UART */
+#define M360_CR_OP_STOP_TX (4<<8) /* SCC, SMC UART */
+#define M360_CR_OP_GR_STOP_TX (5<<8) /* SCC */
+#define M360_CR_OP_INIT_IDMA (5<<8) /* IDMA */
+#define M360_CR_OP_RESTART_TX (6<<8) /* SCC, SMC UART */
+#define M360_CR_OP_CLOSE_RX_BD (7<<8) /* SCC, SMC UART, SPI */
+#define M360_CR_OP_SET_GRP_ADDR (8<<8) /* SCC */
+#define M360_CR_OP_SET_TIMER (8<<8) /* Timer */
+#define M360_CR_OP_GCI_TIMEOUT (9<<8) /* SMC GCI */
+#define M360_CR_OP_RESERT_BCS (10<<8) /* SCC */
+#define M360_CR_OP_GCI_ABORT (10<<8) /* SMC GCI */
+#define M360_CR_CHAN_SCC1 (0<<4) /* Channel selection */
+#define M360_CR_CHAN_SCC2 (4<<4)
+#define M360_CR_CHAN_SPI (5<<4)
+#define M360_CR_CHAN_TIMER (5<<4)
+#define M360_CR_CHAN_SCC3 (8<<4)
+#define M360_CR_CHAN_SMC1 (9<<4)
+#define M360_CR_CHAN_IDMA1 (9<<4)
+#define M360_CR_CHAN_SCC4 (12<<4)
+#define M360_CR_CHAN_SMC2 (13<<4)
+#define M360_CR_CHAN_IDMA2 (13<<4)
+#define M360_CR_FLG (1<<0) /* Command flag */
+
+/*
+ *************************************************************************
+ * System Protection Control Register (SYPCR) *
+ *************************************************************************
+ */
+#define M360_SYPCR_SWE (1<<7) /* Software watchdog enable */
+#define M360_SYPCR_SWRI (1<<6) /* Software watchdog reset select */
+#define M360_SYPCR_SWT1 (1<<5) /* Software watchdog timing bit 1 */
+#define M360_SYPCR_SWT0 (1<<4) /* Software watchdog timing bit 0 */
+#define M360_SYPCR_DBFE (1<<3) /* Double bus fault monitor enable */
+#define M360_SYPCR_BME (1<<2) /* Bus monitor external enable */
+#define M360_SYPCR_BMT1 (1<<1) /* Bus monitor timing bit 1 */
+#define M360_SYPCR_BMT0 (1<<0) /* Bus monitor timing bit 0 */
+
+/*
+ *************************************************************************
+ * Memory Control Registers *
+ *************************************************************************
+ */
+#define M360_GMR_RCNT(x) ((x)<<24) /* Refresh count */
+#define M360_GMR_RFEN (1<<23) /* Refresh enable */
+#define M360_GMR_RCYC(x) ((x)<<21) /* Refresh cycle length */
+#define M360_GMR_PGS(x) ((x)<<18) /* Page size */
+#define M360_GMR_DPS_32BIT (0<<16) /* DRAM port size */
+#define M360_GMR_DPS_16BIT (1<<16)
+#define M360_GMR_DPS_8BIT (2<<16)
+#define M360_GMR_DPS_DSACK (3<<16)
+#define M360_GMR_WBT40 (1<<15) /* Wait between 040 transfers */
+#define M360_GMR_WBTQ (1<<14) /* Wait between 360 transfers */
+#define M360_GMR_SYNC (1<<13) /* Synchronous external access */
+#define M360_GMR_EMWS (1<<12) /* External master wait state */
+#define M360_GMR_OPAR (1<<11) /* Odd parity */
+#define M360_GMR_PBEE (1<<10) /* Parity bus error enable */
+#define M360_GMR_TSS40 (1<<9) /* TS* sample for 040 */
+#define M360_GMR_NCS (1<<8) /* No CPU space */
+#define M360_GMR_DWQ (1<<7) /* Delay write for 360 */
+#define M360_GMR_DW40 (1<<6) /* Delay write for 040 */
+#define M360_GMR_GAMX (1<<5) /* Global address mux enable */
+
+#define M360_MEMC_BR_FC(x) ((x)<<7) /* Function code limit */
+#define M360_MEMC_BR_TRLXQ (1<<6) /* Relax timing requirements */
+#define M360_MEMC_BR_BACK40 (1<<5) /* Burst acknowledge to 040 */
+#define M360_MEMC_BR_CSNT40 (1<<4) /* CS* negate timing for 040 */
+#define M360_MEMC_BR_CSNTQ (1<<3) /* CS* negate timing for 360 */
+#define M360_MEMC_BR_PAREN (1<<2) /* Enable parity checking */
+#define M360_MEMC_BR_WP (1<<1) /* Write Protect */
+#define M360_MEMC_BR_V (1<<0) /* Base/Option register are valid */
+
+#define M360_MEMC_OR_TCYC(x) ((x)<<28) /* Cycle length (clocks) */
+#define M360_MEMC_OR_WAITS(x) M360_MEMC_OR_TCYC((x)+1)
+#define M360_MEMC_OR_2KB 0x0FFFF800 /* Address range */
+#define M360_MEMC_OR_4KB 0x0FFFF000
+#define M360_MEMC_OR_8KB 0x0FFFE000
+#define M360_MEMC_OR_16KB 0x0FFFC000
+#define M360_MEMC_OR_32KB 0x0FFF8000
+#define M360_MEMC_OR_64KB 0x0FFF0000
+#define M360_MEMC_OR_128KB 0x0FFE0000
+#define M360_MEMC_OR_256KB 0x0FFC0000
+#define M360_MEMC_OR_512KB 0x0FF80000
+#define M360_MEMC_OR_1MB 0x0FF00000
+#define M360_MEMC_OR_2MB 0x0FE00000
+#define M360_MEMC_OR_4MB 0x0FC00000
+#define M360_MEMC_OR_8MB 0x0F800000
+#define M360_MEMC_OR_16MB 0x0F000000
+#define M360_MEMC_OR_32MB 0x0E000000
+#define M360_MEMC_OR_64MB 0x0C000000
+#define M360_MEMC_OR_128MB 0x08000000
+#define M360_MEMC_OR_256MB 0x00000000
+#define M360_MEMC_OR_FCMC(x) ((x)<<7) /* Function code mask */
+#define M360_MEMC_OR_BCYC(x) ((x)<<5) /* Burst cycle length (clocks) */
+#define M360_MEMC_OR_PGME (1<<3) /* Page mode enable */
+#define M360_MEMC_OR_32BIT (0<<1) /* Port size */
+#define M360_MEMC_OR_16BIT (1<<1)
+#define M360_MEMC_OR_8BIT (2<<1)
+#define M360_MEMC_OR_DSACK (3<<1)
+#define M360_MEMC_OR_DRAM (1<<0) /* Dynamic RAM select */
+
+/*
+ *************************************************************************
+ * SI Mode Register (SIMODE) *
+ *************************************************************************
+ */
+#define M360_SI_SMC2_BITS 0xFFFF0000 /* All SMC2 bits */
+#define M360_SI_SMC2_TDM (1<<31) /* Multiplexed SMC2 */
+#define M360_SI_SMC2_BRG1 (0<<28) /* SMC2 clock souce */
+#define M360_SI_SMC2_BRG2 (1<<28)
+#define M360_SI_SMC2_BRG3 (2<<28)
+#define M360_SI_SMC2_BRG4 (3<<28)
+#define M360_SI_SMC2_CLK5 (0<<28)
+#define M360_SI_SMC2_CLK6 (1<<28)
+#define M360_SI_SMC2_CLK7 (2<<28)
+#define M360_SI_SMC2_CLK8 (3<<28)
+#define M360_SI_SMC1_BITS 0x0000FFFF /* All SMC1 bits */
+#define M360_SI_SMC1_TDM (1<<15) /* Multiplexed SMC1 */
+#define M360_SI_SMC1_BRG1 (0<<12) /* SMC1 clock souce */
+#define M360_SI_SMC1_BRG2 (1<<12)
+#define M360_SI_SMC1_BRG3 (2<<12)
+#define M360_SI_SMC1_BRG4 (3<<12)
+#define M360_SI_SMC1_CLK1 (0<<12)
+#define M360_SI_SMC1_CLK2 (1<<12)
+#define M360_SI_SMC1_CLK3 (2<<12)
+#define M360_SI_SMC1_CLK4 (3<<12)
+
+/*
+ *************************************************************************
+ * SDMA Configuration Register (SDMA) *
+ *************************************************************************
+ */
+#define M360_SDMA_FREEZE (2<<13) /* Freeze on next bus cycle */
+#define M360_SDMA_SISM_7 (7<<8) /* Normal interrupt service mask */
+#define M360_SDMA_SAID_4 (4<<4) /* Normal arbitration ID */
+#define M360_SDMA_INTE (1<<1) /* SBER interrupt enable */
+#define M360_SDMA_INTB (1<<0) /* SBKP interrupt enable */
+
+/*
+ *************************************************************************
+ * Baud (sic) Rate Generators *
+ *************************************************************************
+ */
+#define M360_BRG_RST (1<<17) /* Reset generator */
+#define M360_BRG_EN (1<<16) /* Enable generator */
+#define M360_BRG_EXTC_BRGCLK (0<<14) /* Source is BRGCLK */
+#define M360_BRG_EXTC_CLK2 (1<<14) /* Source is CLK2 pin */
+#define M360_BRG_EXTC_CLK6 (2<<14) /* Source is CLK6 pin */
+#define M360_BRG_ATB (1<<13) /* Autobaud */
+#define M360_BRG_115200 (13<<1) /* Assume 25 MHz clock */
+#define M360_BRG_57600 (26<<1)
+#define M360_BRG_38400 (40<<1)
+#define M360_BRG_19200 (80<<1)
+#define M360_BRG_9600 (162<<1)
+#define M360_BRG_4800 (324<<1)
+#define M360_BRG_2400 (650<<1)
+#define M360_BRG_1200 (1301<<1)
+#define M360_BRG_600 (2603<<1)
+#define M360_BRG_300 ((324<<1) | 1)
+#define M360_BRG_150 ((650<<1) | 1)
+#define M360_BRG_75 ((1301<<1) | 1)
+
+/*
+ *************************************************************************
+ * MC68360 DUAL-PORT RAM AND REGISTERS *
+ *************************************************************************
+ */
+typedef struct m360_ {
+ /*
+ * Dual-port RAM
+ */
+ unsigned char dpram0[0x400]; /* Microcode program */
+ unsigned char dpram1[0x200];
+ unsigned char dpram2[0x100]; /* Microcode scratch */
+ unsigned char dpram3[0x100]; /* Not on REV A or B masks */
+ unsigned char _rsv0[0xC00-0x800];
+ m360SCCENparms_t scc1p;
+ unsigned char _rsv1[0xCB0-0xC00-sizeof(m360SCCENparms_t)];
+ m360MiscParms_t miscp;
+ unsigned char _rsv2[0xD00-0xCB0-sizeof(m360MiscParms_t)];
+ m360SCCparms_t scc2p;
+ unsigned char _rsv3[0xD80-0xD00-sizeof(m360SCCparms_t)];
+ m360SPIparms_t spip;
+ unsigned char _rsv4[0xDB0-0xD80-sizeof(m360SPIparms_t)];
+ m360TimerParms_t tmp;
+ unsigned char _rsv5[0xE00-0xDB0-sizeof(m360TimerParms_t)];
+ m360SCCparms_t scc3p;
+ unsigned char _rsv6[0xE70-0xE00-sizeof(m360SCCparms_t)];
+ m360IDMAparms_t idma1p;
+ unsigned char _rsv7[0xE80-0xE70-sizeof(m360IDMAparms_t)];
+ m360SMCparms_t smc1p;
+ unsigned char _rsv8[0xF00-0xE80-sizeof(m360SMCparms_t)];
+ m360SCCparms_t scc4p;
+ unsigned char _rsv9[0xF70-0xF00-sizeof(m360SCCparms_t)];
+ m360IDMAparms_t idma2p;
+ unsigned char _rsv10[0xF80-0xF70-sizeof(m360IDMAparms_t)];
+ m360SMCparms_t smc2p;
+ unsigned char _rsv11[0x1000-0xF80-sizeof(m360SMCparms_t)];
+
+ /*
+ * SIM Block
+ */
+ unsigned long mcr;
+ unsigned long _pad00;
+ unsigned char avr;
+ unsigned char rsr;
+ unsigned short _pad01;
+ unsigned char clkocr;
+ unsigned char _pad02;
+ unsigned short _pad03;
+ unsigned short pllcr;
+ unsigned short _pad04;
+ unsigned short cdvcr;
+ unsigned short pepar;
+ unsigned long _pad05[2];
+ unsigned short _pad06;
+ unsigned char sypcr;
+ unsigned char swiv;
+ unsigned short _pad07;
+ unsigned short picr;
+ unsigned short _pad08;
+ unsigned short pitr;
+ unsigned short _pad09;
+ unsigned char _pad10;
+ unsigned char swsr;
+ unsigned long bkar;
+ unsigned long bcar;
+ unsigned long _pad11[2];
+
+ /*
+ * MEMC Block
+ */
+ unsigned long gmr;
+ unsigned short mstat;
+ unsigned short _pad12;
+ unsigned long _pad13[2];
+ m360MEMCRegisters_t memc[8];
+ unsigned char _pad14[0xF0-0xD0];
+ unsigned char _pad15[0x100-0xF0];
+ unsigned char _pad16[0x500-0x100];
+
+ /*
+ * IDMA1 Block
+ */
+ unsigned short iccr;
+ unsigned short _pad17;
+ unsigned short cmr1;
+ unsigned short _pad18;
+ unsigned long sapr1;
+ unsigned long dapr1;
+ unsigned long bcr1;
+ unsigned char fcr1;
+ unsigned char _pad19;
+ unsigned char cmar1;
+ unsigned char _pad20;
+ unsigned char csr1;
+ unsigned char _pad21;
+ unsigned short _pad22;
+
+ /*
+ * SDMA Block
+ */
+ unsigned char sdsr;
+ unsigned char _pad23;
+ unsigned short sdcr;
+ unsigned long sdar;
+
+ /*
+ * IDMA2 Block
+ */
+ unsigned short _pad24;
+ unsigned short cmr2;
+ unsigned long sapr2;
+ unsigned long dapr2;
+ unsigned long bcr2;
+ unsigned char fcr2;
+ unsigned char _pad26;
+ unsigned char cmar2;
+ unsigned char _pad27;
+ unsigned char csr2;
+ unsigned char _pad28;
+ unsigned short _pad29;
+ unsigned long _pad30;
+
+ /*
+ * CPIC Block
+ */
+ unsigned long cicr;
+ unsigned long cipr;
+ unsigned long cimr;
+ unsigned long cisr;
+
+ /*
+ * Parallel I/O Block
+ */
+ unsigned short padir;
+ unsigned short papar;
+ unsigned short paodr;
+ unsigned short padat;
+ unsigned long _pad31[2];
+ unsigned short pcdir;
+ unsigned short pcpar;
+ unsigned short pcso;
+ unsigned short pcdat;
+ unsigned short pcint;
+ unsigned short _pad32;
+ unsigned long _pad33[5];
+
+ /*
+ * TIMER Block
+ */
+ unsigned short tgcr;
+ unsigned short _pad34;
+ unsigned long _pad35[3];
+ unsigned short tmr1;
+ unsigned short tmr2;
+ unsigned short trr1;
+ unsigned short trr2;
+ unsigned short tcr1;
+ unsigned short tcr2;
+ unsigned short tcn1;
+ unsigned short tcn2;
+ unsigned short tmr3;
+ unsigned short tmr4;
+ unsigned short trr3;
+ unsigned short trr4;
+ unsigned short tcr3;
+ unsigned short tcr4;
+ unsigned short tcn3;
+ unsigned short tcn4;
+ unsigned short ter1;
+ unsigned short ter2;
+ unsigned short ter3;
+ unsigned short ter4;
+ unsigned long _pad36[2];
+
+ /*
+ * CP Block
+ */
+ unsigned short cr;
+ unsigned short _pad37;
+ unsigned short rccr;
+ unsigned short _pad38;
+ unsigned long _pad39[3];
+ unsigned short _pad40;
+ unsigned short rter;
+ unsigned short _pad41;
+ unsigned short rtmr;
+ unsigned long _pad42[5];
+
+ /*
+ * BRG Block
+ */
+ unsigned long brgc1;
+ unsigned long brgc2;
+ unsigned long brgc3;
+ unsigned long brgc4;
+
+ /*
+ * SCC Block
+ */
+ m360SCCRegisters_t scc1;
+ m360SCCRegisters_t scc2;
+ m360SCCRegisters_t scc3;
+ m360SCCRegisters_t scc4;
+
+ /*
+ * SMC Block
+ */
+ m360SMCRegisters_t smc1;
+ m360SMCRegisters_t smc2;
+
+ /*
+ * SPI Block
+ */
+ unsigned short spmode;
+ unsigned short _pad43[2];
+ unsigned char spie;
+ unsigned char _pad44;
+ unsigned short _pad45;
+ unsigned char spim;
+ unsigned char _pad46[2];
+ unsigned char spcom;
+ unsigned short _pad47[2];
+
+ /*
+ * PIP Block
+ */
+ unsigned short pipc;
+ unsigned short _pad48;
+ unsigned short ptpr;
+ unsigned long pbdir;
+ unsigned long pbpar;
+ unsigned short _pad49;
+ unsigned short pbodr;
+ unsigned long pbdat;
+ unsigned long _pad50[6];
+
+ /*
+ * SI Block
+ */
+ unsigned long simode;
+ unsigned char sigmr;
+ unsigned char _pad51;
+ unsigned char sistr;
+ unsigned char sicmr;
+ unsigned long _pad52;
+ unsigned long sicr;
+ unsigned short _pad53;
+ unsigned short sirp[2];
+ unsigned short _pad54;
+ unsigned long _pad55[2];
+ unsigned char siram[256];
+} m360_t;
+
+extern volatile m360_t m360;
+
+#endif /* _RTEMS_M68K_M68360_H */
diff --git a/cpukit/score/cpu/m68k/rtems/m68k/qsm.h b/cpukit/score/cpu/m68k/rtems/m68k/qsm.h
new file mode 100644
index 0000000000..b6bd8e0cf7
--- /dev/null
+++ b/cpukit/score/cpu/m68k/rtems/m68k/qsm.h
@@ -0,0 +1,204 @@
+/*
+ *-------------------------------------------------------------------
+ *
+ * QSM -- Queued Serial Module
+ *
+ * The QSM contains two serial interfaces: (a) the queued serial
+ * peripheral interface (QSPI) and the serial communication interface
+ * (SCI). The QSPI provides peripheral expansion and/or interprocessor
+ * communication through a full-duplex, synchronous, three-wire bus. A
+ * self contained RAM queue permits serial data transfers without CPU
+ * intervention and automatic continuous sampling. The SCI provides a
+ * standard non-return to zero mark/space format with wakeup functions
+ * to allow the CPU to run uninterrupted until woken
+ *
+ * For more information, refer to Motorola's "Modular Microcontroller
+ * Family Queued Serial Module Reference Manual" (Motorola document
+ * QSMRM/AD).
+ *
+ * This file was created by John S. Gwynne to support Motorola's 68332 MCU.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the following conditions are met:
+ * 1. Redistribution of source code and documentation must retain
+ * the above authorship, this list of conditions and the
+ * following disclaimer.
+ * 2. 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" without warranty of any kind,
+ * either expressed or implied, including, but not limited to, the
+ * implied warranties of merchantability, title and fitness for a
+ * particular purpose.
+ *
+ *------------------------------------------------------------------
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_M68K_QSM_H
+#define _RTEMS_M68K_QSM_H
+
+/* SAM-- shift and mask */
+#undef SAM
+#define SAM(a,b,c) ((a << b) & c)
+
+
+/* QSM_CRB (QSM Control Register Block) base address of the QSM
+ control registers */
+#if SIM_MM == 0
+#define QSM_CRB 0x7ffc00
+#else
+#undef SIM_MM
+#define SIM_MM 1
+#define QSM_CRB 0xfffc00
+#endif
+
+
+#define QSMCR (volatile unsigned short int * const)(0x00 + QSM_CRB)
+ /* QSM Configuration Register */
+#define STOP 0x8000 /* Stop Enable */
+#define FRZ 0x6000 /* Freeze Control */
+#define SUPV 0x0080 /* Supervisor/Unrestricted */
+#define IARB 0x000f /* Inerrupt Arbitration */
+
+
+#define QTEST (volatile unsigned short int * const)(0x02 + QSM_CRB)
+ /* QSM Test Register */
+/* Used only for factor testing */
+
+
+#define QILR (volatile unsigned char * const)(0x04 + QSM_CRB)
+ /* QSM Interrupt Level Register */
+#define ILQSPI 0x38 /* Interrupt Level for QSPI */
+#define ILSCI 0x07 /* Interrupt Level for SCI */
+
+
+#define QIVR (volatile unsigned char * const)(0x05 + QSM_CRB)
+ /* QSM Interrupt Vector Register */
+#define INTV 0xff /* Interrupt Vector Number */
+
+
+#define SCCR0 (volatile unsigned short int * const)(0x08 + QSM_CRB)
+ /* SCI Control Register 0 */
+#define SCBR 0x1fff /* SCI Baud Rate */
+
+
+#define SCCR1 (volatile unsigned short int * const)(0x0a + QSM_CRB)
+ /* SCI Control Register 1 */
+#define LOOPS 0x4000 /* Loop Mode */
+#define WOMS 0x2000 /* Wired-OR Mode for SCI Pins */
+#define ILT 0x1000 /* Idle-Line Detect Type */
+#define PT 0x0800 /* Parity Type */
+#define PE 0x0400 /* Parity Enable */
+#define M 0x0200 /* Mode Select */
+#define WAKE 0x0100 /* Wakeup by Address Mark */
+#define TIE 0x0080 /* Transmit Complete Interrupt Enable */
+#define TCIE 0x0040 /* Transmit Complete Interrupt Enable */
+#define RIE 0x0020 /* Receiver Interrupt Enable */
+#define ILIE 0x0010 /* Idle-Line Interrupt Enable */
+#define TE 0x0008 /* Transmitter Enable */
+#define RE 0x0004 /* Receiver Enable */
+#define RWU 0x0002 /* Receiver Wakeup */
+#define SBK 0x0001 /* Send Break */
+
+
+#define SCSR (volatile unsigned short int * const)(0x0c + QSM_CRB)
+ /* SCI Status Register */
+#define TDRE 0x0100 /* Transmit Data Register Empty */
+#define TC 0x0080 /* Transmit Complete */
+#define RDRF 0x0040 /* Receive Data Register Full */
+#define RAF 0x0020 /* Receiver Active */
+#define IDLE 0x0010 /* Idle-Line Detected */
+#define OR 0x0008 /* Overrun Error */
+#define NF 0x0004 /* Noise Error Flag */
+#define FE 0x0002 /* Framing Error */
+#define PF 0x0001 /* Parity Error */
+
+
+#define SCDR (volatile unsigned short int * const)(0x0e + QSM_CRB)
+ /* SCI Data Register */
+
+
+#define PORTQS (volatile unsigned char * const)(0x15 + QSM_CRB)
+ /* Port QS Data Register */
+
+#define PQSPAR (volatile unsigned char * const)(0x16 + QSM_CRB)
+ /* PORT QS Pin Assignment Rgister */
+/* Any bit cleared (zero) defines the corresponding pin to be an I/O
+ pin. Any bit set defines the corresponding pin to be a QSPI
+ signal. */
+/* note: PQS2 is a digital I/O pin unless the SPI is enabled in which
+ case it becomes the SPI serial clock SCK. */
+/* note: PQS7 is a digital I/O pin unless the SCI transmitter is
+ enabled in which case it becomes the SCI serial output TxD. */
+#define QSMFun 0x0
+#define QSMDis 0x1
+/*
+ * PQSPAR Field | QSM Function | Discrete I/O pin
+ *------------------+--------------+------------------ */
+#define PQSPA0 0 /* MISO | PQS0 */
+#define PQSPA1 1 /* MOSI | PQS1 */
+#define PQSPA2 2 /* SCK | PQS2 (see note)*/
+#define PQSPA3 3 /* PCSO/!SS | PQS3 */
+#define PQSPA4 4 /* PCS1 | PQS4 */
+#define PQSPA5 5 /* PCS2 | PQS5 */
+#define PQSPA6 6 /* PCS3 | PQS6 */
+#define PQSPA7 7 /* TxD | PQS7 (see note)*/
+
+
+#define DDRQS (volatile unsigned char * const)(0x17 + QSM_CRB)
+ /* PORT QS Data Direction Register */
+/* Clearing a bit makes the corresponding pin an input; setting a bit
+ makes the pin an output. */
+
+
+#define SPCR0 (volatile unsigned short int * const)(0x18 + QSM_CRB)
+ /* QSPI Control Register 0 */
+#define MSTR 0x8000 /* Master/Slave Mode Select */
+#define WOMQ 0x4000 /* Wired-OR Mode for QSPI Pins */
+#define BITS 0x3c00 /* Bits Per Transfer */
+#define CPOL 0x0200 /* Clock Polarity */
+#define CPHA 0x0100 /* Clock Phase */
+#define SPBR 0x00ff /* Serial Clock Baud Rate */
+
+
+#define SPCR1 (volatile unsigned short int * const)(0x1a + QSM_CRB)
+ /* QSPI Control Register 1 */
+#define SPE 0x8000 /* QSPI Enable */
+#define DSCKL 0x7f00 /* Delay before SCK */
+#define DTL 0x00ff /* Length of Delay after Transfer */
+
+
+#define SPCR2 (volatile unsigned short int * const)(0x1c + QSM_CRB)
+ /* QSPI Control Register 2 */
+#define SPIFIE 0x8000 /* SPI Finished Interrupt Enable */
+#define WREN 0x4000 /* Wrap Enable */
+#define WRTO 0x2000 /* Wrap To */
+#define ENDQP 0x0f00 /* Ending Queue Pointer */
+#define NEWQP 0x000f /* New Queue Pointer Value */
+
+
+#define SPCR3 (volatile unsigned char * const)(0x1e + QSM_CRB)
+ /* QSPI Control Register 3 */
+#define LOOPQ 0x0400 /* QSPI Loop Mode */
+#define HMIE 0x0200 /* HALTA and MODF Interrupt Enable */
+#define HALT 0x0100 /* Halt */
+
+
+#define SPSR (volatile unsigned char * const)(0x1f + QSM_CRB)
+ /* QSPI Status Register */
+#define SPIF 0x0080 /* QSPI Finished Flag */
+#define MODF 0x0040 /* Mode Fault Flag */
+#define HALTA 0x0020 /* Halt Acknowlwdge Flag */
+#define CPTQP x0000f /* Completed Queue Pointer */
+
+#define QSPIRR (volatile unsigned char * const)(0x100 + QSM_CRB)
+ /* QSPI Receive Data RAM */
+#define QSPITR (volatile unsigned char * const)(0x120 + QSM_CRB)
+ /* QSPI Transmit Data RAM */
+#define QSPIcR (volatile unsigned char * const)(0x140 + QSM_CRB)
+ /* QSPI Command RAM */
+
+#endif /* _RTEMS_M68K_QSM_H */
diff --git a/cpukit/score/cpu/m68k/rtems/m68k/sim.h b/cpukit/score/cpu/m68k/rtems/m68k/sim.h
new file mode 100644
index 0000000000..8ca58d8b6b
--- /dev/null
+++ b/cpukit/score/cpu/m68k/rtems/m68k/sim.h
@@ -0,0 +1,333 @@
+/*
+ *-------------------------------------------------------------------
+ *
+ * SIM -- System Integration Module
+ *
+ * The system integration module (SIM) is used on many Motorola 16-
+ * and 32-bit MCUs for the following functions:
+ *
+ * () System configuration and protection. Bus and software watchdog
+ * monitors are provided in addition to periodic interrupt generators.
+ *
+ * () Clock signal generation for other intermodule bus (IMB) members
+ * and external devices.
+ *
+ * () The generation of chip-select signals that simplify external
+ * circuitry interface.
+ *
+ * () Data ports that are available for general purpose input and
+ * output.
+ *
+ * () A system test block that is intended only for factory tests.
+ *
+ * For more information, refer to Motorola's "Modular Microcontroller
+ * Family System Integration Module Reference Manual" (Motorola document
+ * SIMRM/AD).
+ *
+ * This file was created by John S. Gwynne to support Motorola's 68332 MCU.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the following conditions are met:
+ * 1. Redistribution of source code and documentation must retain
+ * the above authorship, this list of conditions and the
+ * following disclaimer.
+ * 2. 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" without warranty of any kind,
+ * either expressed or implied, including, but not limited to, the
+ * implied warranties of merchantability, title and fitness for a
+ * particular purpose.
+ *
+ *------------------------------------------------------------------
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_M68K_SIM_H
+#define _RTEMS_M68K_SIM_H
+
+
+/* SAM-- shift and mask */
+#undef SAM
+#define SAM(a,b,c) ((a << b) & c)
+
+/*
+ * These macros make this file usable from assembly.
+ */
+
+#ifdef ASM
+#define SIM_VOLATILE_USHORT_POINTER
+#define SIM_VOLATILE_UCHAR_POINTER
+#else
+#define SIM_VOLATILE_USHORT_POINTER (volatile unsigned short int * const)
+#define SIM_VOLATILE_UCHAR_POINTER (volatile unsigned char * const)
+#endif
+
+/* SIM_CRB (SIM Control Register Block) base address of the SIM
+ control registers */
+#ifndef SIM_CRB
+#if SIM_MM == 0
+#define SIM_CRB 0x7ffa00
+#else /* SIM_MM */
+#undef SIM_MM
+#define SIM_MM 1
+#define SIM_CRB 0xfffa00
+#endif /* SIM_MM */
+#endif /* SIM_CRB */
+
+
+#define SIMCR SIM_VOLATILE_USHORT_POINTER(0x00 + SIM_CRB)
+ /* Module Configuration Register */
+#define EXOFF 0x8000 /* External Clock Off */
+#define FRZSW 0x4000 /* Freeze Software Enable */
+#define FRZBM 0x2000 /* Freeze Bus Monitor Enable */
+#define SLVEN 0x0800 /* Factory Test Model Enabled (ro)*/
+#define SHEN 0x0300 /* Show Cycle Enable */
+#define SUPV 0x0080 /* Supervisor/Unrestricted Data Space */
+#define MM 0x0040 /* Module Mapping */
+#define IARB 0x000f /* Interrupt Arbitration Field */
+
+
+
+#define SIMTR SIM_VOLATILE_USHORT_POINTER(0x02 + SIM_CRB)
+ /* SIM Test Register */
+/* Used only for factor testing */
+
+
+
+#define SYNCR SIM_VOLATILE_USHORT_POINTER(0x04 + SIM_CRB)
+ /* Clock Synthesizer Control Register */
+#define VCO 0x8000 /* Frequency Control (VCO) */
+#define PRESCALE 0x4000 /* Frequency Control Bit (Prescale) */
+#define COUNTER 0x3f00 /* Frequency Control Counter */
+#define EDIV 0x0080 /* ECLK Divide Rate */
+#define SLIMP 0x0010 /* Limp Mode Status */
+#define SLOCK 0x0008 /* Synthesizer Lock */
+#define RSTEN 0x0004 /* Reset Enable */
+#define STSIM 0x0002 /* Stop Mode SIM Clock */
+#define STEXT 0x0001 /* Stop Mode External Clock */
+
+
+
+#define RSR SIM_VOLATILE_UCHAR_POINTER(0x07 + SIM_CRB)
+ /* Reset Status Register */
+#define EXT 0x0080 /* External Reset */
+#define POW 0x0040 /* Power-On Reset */
+#define SW 0x0020 /* Software Watchdog Reset */
+#define DBF 0x0010 /* Double Bus Fault Reset */
+#define LOC 0x0004 /* Loss of Clock Reset */
+#define SYS 0x0002 /* System Reset */
+#define TST 0x0001 /* Test Submodule Reset */
+
+
+
+#define SIMTRE SIM_VOLATILE_USHORT_POINTER(0x08 + SIM_CRB)
+ /* System Integration Test Register */
+/* Used only for factor testing */
+
+
+
+#define PORTE0 SIM_VOLATILE_UCHAR_POINTER(0x11 + SIM_CRB)
+#define PORTE1 SIM_VOLATILE_UCHAR_POINTER(0x13 + SIM_CRB)
+ /* Port E Data Register */
+#define DDRE SIM_VOLATILE_UCHAR_POINTER(0x15 + SIM_CRB)
+ /* Port E Data Direction Register */
+#define PEPAR SIM_VOLATILE_UCHAR_POINTER(0x17 + SIM_CRB)
+ /* Port E Pin Assignment Register */
+/* Any bit cleared (zero) defines the corresponding pin to be an I/O
+ pin. Any bit set defines the corresponding pin to be a bus control
+ signal. */
+
+
+
+#define PORTF0 SIM_VOLATILE_UCHAR_POINTER(0x19 + SIM_CRB)
+#define PORTF1 SIM_VOLATILE_UCHAR_POINTER(0x1b + SIM_CRB)
+ /* Port F Data Register */
+#define DDRF SIM_VOLATILE_UCHAR_POINTER(0x1d + SIM_CRB)
+ /* Port E Data Direction Register */
+#define PFPAR SIM_VOLATILE_UCHAR_POINTER(0x1f + SIM_CRB)
+/* Any bit cleared (zero) defines the corresponding pin to be an I/O
+ pin. Any bit set defines the corresponding pin to be a bus control
+ signal. */
+
+
+
+#define SYPCR SIM_VOLATILE_UCHAR_POINTER(0x21 + SIM_CRB)
+/* !!! can write to only once after reset !!! */
+ /* System Protection Control Register */
+#define SWE 0x80 /* Software Watch Enable */
+#define SWP 0x40 /* Software Watchdog Prescale */
+#define SWT 0x30 /* Software Watchdog Timing */
+#define HME 0x08 /* Halt Monitor Enable */
+#define BME 0x04 /* Bus Monitor External Enable */
+#define BMT 0x03 /* Bus Monitor Timing */
+
+
+
+#define PICR SIM_VOLATILE_USHORT_POINTER(0x22 + SIM_CRB)
+ /* Periodic Interrupt Control Reg. */
+#define PIRQL 0x0700 /* Periodic Interrupt Request Level */
+#define PIV 0x00ff /* Periodic Interrupt Level */
+
+
+
+#define PITR SIM_VOLATILE_USHORT_POINTER(0x24 + SIM_CRB)
+ /* Periodic Interrupt Timer Register */
+#define PTP 0x0100 /* Periodic Timer Prescaler Control */
+#define PITM 0x00ff /* Periodic Interrupt Timing Modulus */
+
+
+
+#define SWSR SIM_VOLATILE_UCHAR_POINTER(0x27 + SIM_CRB)
+ /* Software Service Register */
+/* write 0x55 then 0xaa to service the software watchdog */
+
+
+
+#define TSTMSRA SIM_VOLATILE_USHORT_POINTER(0x30 + SIM_CRB)
+ /* Test Module Master Shift A */
+#define TSTMSRB SIM_VOLATILE_USHORT_POINTER(0x32 + SIM_CRB)
+ /* Test Module Master Shift A */
+#define TSTSC SIM_VOLATILE_USHORT_POINTER(0x34 + SIM_CRB)
+ /* Test Module Shift Count */
+#define TSTRC SIM_VOLATILE_USHORT_POINTER(0x36 + SIM_CRB)
+ /* Test Module Repetition Counter */
+#define CREG SIM_VOLATILE_USHORT_POINTER(0x38 + SIM_CRB)
+ /* Test Module Control */
+#define DREG SIM_VOLATILE_USHORT_POINTER(0x3a + SIM_CRB)
+ /* Test Module Distributed */
+/* Used only for factor testing */
+
+
+
+#define PORTC SIM_VOLATILE_UCHAR_POINTER(0x41 + SIM_CRB)
+ /* Port C Data */
+
+
+
+#define CSPAR0 SIM_VOLATILE_USHORT_POINTER(0x44 + SIM_CRB)
+ /* Chip Select Pin Assignment
+ Resgister 0 */
+/* CSPAR0 contains seven two-bit fields that determine the functions
+ of corresponding chip-select pins. CSPAR0[15:14] are not
+ used. These bits always read zero; write have no effect. CSPAR0 bit
+ 1 always reads one; writes to CSPAR0 bit 1 have no effect. */
+#define CSPAR1 SIM_VOLATILE_USHORT_POINTER(0x46 + SIM_CRB)
+ /* Chip Select Pin Assignment
+ Register 1 */
+/* CSPAR1 contains five two-bit fields that determine the finctions of
+ corresponding chip-select pins. CSPAR1[15:10] are not used. These
+ bits always read zero; writes have no effect. */
+/*
+ *
+ * Bit Field | Description
+ * ------------+---------------
+ * 00 | Discrete Output
+ * 01 | Alternate Function
+ * 10 | Chip Select (8-bit port)
+ * 11 | Chip Select (16-bit port)
+ */
+#define DisOut 0x0
+#define AltFun 0x1
+#define CS8bit 0x2
+#define CS16bit 0x3
+/*
+ *
+ * CSPARx Field |Chip Select Signal | Alternate Signal | Discrete Output
+ *-----------------+--------------------+--------------------+---------------*/
+#define CS_5 12 /* !CS5 | FC2 | PC2 */
+#define CS_4 10 /* !CS4 | FC1 | PC1 */
+#define CS_3 8 /* !CS3 | FC0 | PC0 */
+#define CS_2 6 /* !CS2 | !BGACK | */
+#define CS_1 4 /* !CS1 | !BG | */
+#define CS_0 2 /* !CS0 | !BR | */
+#define CSBOOT 0 /* !CSBOOT | | */
+/* | | | */
+#define CS_10 8 /* !CS10 | ADDR23 | ECLK */
+#define CS_9 6 /* !CS9 | ADDR22 | PC6 */
+#define CS_8 4 /* !CS8 | ADDR21 | PC5 */
+#define CS_7 2 /* !CS7 | ADDR20 | PC4 */
+#define CS_6 0 /* !CS6 | ADDR19 | PC3 */
+
+#define BS_2K 0x0
+#define BS_8K 0x1
+#define BS_16K 0x2
+#define BS_64K 0x3
+#define BS_128K 0x4
+#define BS_256K 0x5
+#define BS_512K 0x6
+#define BS_1M 0x7
+
+#define CSBARBT SIM_VOLATILE_USHORT_POINTER(0x48 + SIM_CRB)
+#define CSBAR0 SIM_VOLATILE_USHORT_POINTER(0x4c + SIM_CRB)
+#define CSBAR1 SIM_VOLATILE_USHORT_POINTER(0x50 + SIM_CRB)
+#define CSBAR2 SIM_VOLATILE_USHORT_POINTER(0x54 + SIM_CRB)
+#define CSBAR3 SIM_VOLATILE_USHORT_POINTER(0x58 + SIM_CRB)
+#define CSBAR4 SIM_VOLATILE_USHORT_POINTER(0x5c + SIM_CRB)
+#define CSBAR5 SIM_VOLATILE_USHORT_POINTER(0x60 + SIM_CRB)
+#define CSBAR6 SIM_VOLATILE_USHORT_POINTER(0x64 + SIM_CRB)
+#define CSBAR7 SIM_VOLATILE_USHORT_POINTER(0x68 + SIM_CRB)
+#define CSBAR8 SIM_VOLATILE_USHORT_POINTER(0x6c + SIM_CRB)
+#define CSBAR9 SIM_VOLATILE_USHORT_POINTER(0x70 + SIM_CRB)
+#define CSBAR10 SIM_VOLATILE_USHORT_POINTER(0x74 + SIM_CRB)
+
+#define MODE 0x8000
+#define Disable 0
+#define LowerByte 0x2000
+#define UpperByte 0x4000
+#define BothBytes 0x6000
+#define ReadOnly 0x0800
+#define WriteOnly 0x1000
+#define ReadWrite 0x1800
+#define SyncAS 0x0
+#define SyncDS 0x0400
+
+#define WaitStates_0 (0x0 << 6)
+#define WaitStates_1 (0x1 << 6)
+#define WaitStates_2 (0x2 << 6)
+#define WaitStates_3 (0x3 << 6)
+#define WaitStates_4 (0x4 << 6)
+#define WaitStates_5 (0x5 << 6)
+#define WaitStates_6 (0x6 << 6)
+#define WaitStates_7 (0x7 << 6)
+#define WaitStates_8 (0x8 << 6)
+#define WaitStates_9 (0x9 << 6)
+#define WaitStates_10 (0xa << 6)
+#define WaitStates_11 (0xb << 6)
+#define WaitStates_12 (0xc << 6)
+#define WaitStates_13 (0xd << 6)
+#define FastTerm (0xe << 6)
+#define External (0xf << 6)
+
+#define CPUSpace (0x0 << 4)
+#define UserSpace (0x1 << 4)
+#define SupSpace (0x2 << 4)
+#define UserSupSpace (0x3 << 4)
+
+#define IPLevel_any 0x0
+#define IPLevel_1 0x2
+#define IPLevel_2 0x4
+#define IPLevel_3 0x6
+#define IPLevel_4 0x8
+#define IPLevel_5 0xa
+#define IPLevel_6 0xc
+#define IPLevel_7 0xe
+
+#define AVEC 1
+
+#define CSORBT SIM_VOLATILE_USHORT_POINTER(0x4a + SIM_CRB)
+#define CSOR0 SIM_VOLATILE_USHORT_POINTER(0x4e + SIM_CRB)
+#define CSOR1 SIM_VOLATILE_USHORT_POINTER(0x52 + SIM_CRB)
+#define CSOR2 SIM_VOLATILE_USHORT_POINTER(0x56 + SIM_CRB)
+#define CSOR3 SIM_VOLATILE_USHORT_POINTER(0x5a + SIM_CRB)
+#define CSOR4 SIM_VOLATILE_USHORT_POINTER(0x5e + SIM_CRB)
+#define CSOR5 SIM_VOLATILE_USHORT_POINTER(0x62 + SIM_CRB)
+#define CSOR6 SIM_VOLATILE_USHORT_POINTER(0x66 + SIM_CRB)
+#define CSOR7 SIM_VOLATILE_USHORT_POINTER(0x6a + SIM_CRB)
+#define CSOR8 SIM_VOLATILE_USHORT_POINTER(0x6e + SIM_CRB)
+#define CSOR9 SIM_VOLATILE_USHORT_POINTER(0x72 + SIM_CRB)
+#define CSOR10 SIM_VOLATILE_USHORT_POINTER(0x76 + SIM_CRB)
+
+#endif /* _RTEMS_M68K_SIM_H */
diff --git a/cpukit/score/cpu/m68k/rtems/score/cpu.h b/cpukit/score/cpu/m68k/rtems/score/cpu.h
new file mode 100644
index 0000000000..4ae760d5af
--- /dev/null
+++ b/cpukit/score/cpu/m68k/rtems/score/cpu.h
@@ -0,0 +1,701 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * This include file contains information pertaining to the Motorola
+ * m68xxx processor family.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/m68k.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+
+/* conditional compilation parameters */
+
+#define CPU_INLINE_ENABLE_DISPATCH TRUE
+#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE
+
+/*
+ * Use the m68k's hardware interrupt stack support and have the
+ * interrupt manager allocate the memory for it.
+ */
+
+#if ( M68K_HAS_SEPARATE_STACKS == 1)
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK 0
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK 1
+#else
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK 1
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK 0
+#endif
+#define CPU_ALLOCATE_INTERRUPT_STACK 1
+
+/*
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ */
+
+#define CPU_ISR_PASSES_FRAME_POINTER 0
+
+/*
+ * Some family members have no FP, some have an FPU such as the
+ * MC68881/MC68882 for the MC68020, others have it built in (MC68030, 040).
+ *
+ * NOTE: If on a CPU without hardware FP, then one can use software
+ * emulation. The gcc software FP emulation code has data which
+ * must be contexted switched on a per task basis.
+ */
+
+#if ( M68K_HAS_FPU == 1 )
+#define CPU_HARDWARE_FP TRUE
+#define CPU_SOFTWARE_FP FALSE
+#else
+#define CPU_HARDWARE_FP FALSE
+#if defined(__GNUC__)
+#define CPU_SOFTWARE_FP TRUE
+#else
+#define CPU_SOFTWARE_FP FALSE
+#endif
+#endif
+
+/*
+ * All tasks are not by default floating point tasks on this CPU.
+ * The IDLE task does not have a floating point context on this CPU.
+ * It is safe to use the deferred floating point context switch
+ * algorithm on this CPU.
+ */
+
+#define CPU_ALL_TASKS_ARE_FP FALSE
+#define CPU_IDLE_TASK_IS_FP FALSE
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE
+#define CPU_STACK_GROWS_UP FALSE
+#define CPU_STRUCTURE_ALIGNMENT
+
+/*
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ */
+
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+#define CPU_BIG_ENDIAN TRUE
+#define CPU_LITTLE_ENDIAN FALSE
+
+#ifndef ASM
+/* structures */
+
+/*
+ * Basic integer context for the m68k family.
+ */
+
+typedef struct {
+ uint32_t sr; /* (sr) status register */
+ uint32_t d2; /* (d2) data register 2 */
+ uint32_t d3; /* (d3) data register 3 */
+ uint32_t d4; /* (d4) data register 4 */
+ uint32_t d5; /* (d5) data register 5 */
+ uint32_t d6; /* (d6) data register 6 */
+ uint32_t d7; /* (d7) data register 7 */
+ void *a2; /* (a2) address register 2 */
+ void *a3; /* (a3) address register 3 */
+ void *a4; /* (a4) address register 4 */
+ void *a5; /* (a5) address register 5 */
+ void *a6; /* (a6) address register 6 */
+ void *a7_msp; /* (a7) master stack pointer */
+} Context_Control;
+
+/*
+ * Floating point context ares
+ */
+
+#if (CPU_SOFTWARE_FP == TRUE)
+
+/*
+ * This is the same as gcc's view of the software FP condition code
+ * register _fpCCR. The implementation of the emulation code is
+ * in the gcc-VERSION/config/m68k directory. This structure is
+ * correct as of gcc 2.7.2.2.
+ */
+
+typedef struct {
+ uint16_t _exception_bits;
+ uint16_t _trap_enable_bits;
+ uint16_t _sticky_bits;
+ uint16_t _rounding_mode;
+ uint16_t _format;
+ uint16_t _last_operation;
+ union {
+ float sf;
+ double df;
+ } _operand1;
+ union {
+ float sf;
+ double df;
+ } _operand2;
+} Context_Control_fp;
+
+#else
+
+/*
+ * FP context save area for the M68881/M68882 numeric coprocessors.
+ */
+
+typedef struct {
+ uint8_t fp_save_area[332]; /* 216 bytes for FSAVE/FRESTORE */
+ /* 96 bytes for FMOVEM FP0-7 */
+ /* 12 bytes for FMOVEM CREGS */
+ /* 4 bytes for non-null flag */
+} Context_Control_fp;
+#endif
+
+/*
+ * The following structures define the set of information saved
+ * on the current stack by RTEMS upon receipt of each exc/interrupt.
+ * These are not used by m68k handlers.
+ * The exception frame is for rdbg.
+ */
+
+typedef struct {
+ uint32_t vecnum; /* vector number */
+} CPU_Interrupt_frame;
+
+typedef struct {
+ uint32_t vecnum; /* vector number */
+ uint32_t sr; /* status register */
+ uint32_t pc; /* program counter */
+ uint32_t d0, d1, d2, d3, d4, d5, d6, d7;
+ uint32_t a0, a1, a2, a3, a4, a5, a6, a7;
+} CPU_Exception_frame;
+
+/*
+ * The following table contains the information required to configure
+ * the m68k specific parameters.
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+ /* end of fields required on all CPUs */
+
+ m68k_isr *interrupt_vector_table;
+} rtems_cpu_table;
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ */
+
+/*
+ * Macros to access M68K specific additions to the CPU Table
+ */
+
+#define rtems_cpu_configuration_get_interrupt_vector_table() \
+ (_CPU_Table.interrupt_vector_table)
+
+/* variables */
+
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+extern void* _VBR;
+
+#if ( M68K_HAS_VBR == 0 )
+
+/*
+ * Table of ISR handler entries that resides in RAM. The FORMAT/ID is
+ * pushed onto the stack. This is not is the same order as VBR processors.
+ * The ISR handler takes the format and uses it for dispatching the user
+ * handler.
+ *
+ * FIXME : should be moved to below CPU_INTERRUPT_NUMBER_OF_VECTORS
+ *
+ */
+
+typedef struct {
+ uint16_t move_a7; /* move #FORMAT_ID,%a7@- */
+ uint16_t format_id;
+ uint16_t jmp; /* jmp _ISR_Handlers */
+ uint32_t isr_handler;
+} _CPU_ISR_handler_entry;
+
+#define M68K_MOVE_A7 0x3F3C
+#define M68K_JMP 0x4EF9
+
+ /* points to jsr-exception-table in targets wo/ VBR register */
+SCORE_EXTERN _CPU_ISR_handler_entry _CPU_ISR_jump_table[256];
+
+#endif /* M68K_HAS_VBR */
+#endif /* ASM */
+
+/* constants */
+
+/*
+ * This defines the number of levels and the mask used to pick those
+ * bits out of a thread mode.
+ */
+
+#define CPU_MODES_INTERRUPT_LEVEL 0x00000007 /* interrupt level in mode */
+#define CPU_MODES_INTERRUPT_MASK 0x00000007 /* interrupt level in mode */
+
+/*
+ * context size area for floating point
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/*
+ * extra stack required by the MPCI receive server thread
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 1024
+
+/*
+ * m68k family supports 256 distinct vectors.
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
+
+/*
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level.
+ */
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/*
+ * Minimum size of a thread's stack.
+ */
+
+#define CPU_STACK_MINIMUM_SIZE 4096
+
+/*
+ * m68k is pretty tolerant of alignment. Just put things on 4 byte boundaries.
+ */
+
+#define CPU_ALIGNMENT 4
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * On m68k thread stacks require no further alignment after allocation
+ * from the Workspace.
+ */
+
+#define CPU_STACK_ALIGNMENT 0
+
+#ifndef ASM
+
+/* macros */
+
+/*
+ * ISR handler macros
+ *
+ * These macros perform the following functions:
+ * + initialize the RTEMS vector table
+ * + disable all maskable CPU interrupts
+ * + restore previous interrupt level (enable)
+ * + temporarily restore interrupts (flash)
+ * + set a particular level
+ */
+
+#define _CPU_Initialize_vectors()
+
+#define _CPU_ISR_Disable( _level ) \
+ m68k_disable_interrupts( _level )
+
+#define _CPU_ISR_Enable( _level ) \
+ m68k_enable_interrupts( _level )
+
+#define _CPU_ISR_Flash( _level ) \
+ m68k_flash_interrupts( _level )
+
+#define _CPU_ISR_Set_level( _newlevel ) \
+ m68k_set_interrupt_level( _newlevel )
+
+uint32_t _CPU_ISR_Get_level( void );
+
+/* end of ISR handler macros */
+
+/*
+ * Context handler macros
+ *
+ * These macros perform the following functions:
+ * + initialize a context area
+ * + restart the current thread
+ * + calculate the initial pointer into a FP context area
+ * + initialize an FP context area
+ */
+
+#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
+ _isr, _entry_point, _is_fp ) \
+ do { \
+ uint32_t _stack; \
+ \
+ (_the_context)->sr = 0x3000 | ((_isr) << 8); \
+ _stack = (uint32_t )(_stack_base) + (_size) - 4; \
+ (_the_context)->a7_msp = (void *)_stack; \
+ *(void **)_stack = (void *)(_entry_point); \
+ } while ( 0 )
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ { asm volatile( "movew %0,%%sr ; " \
+ "moval %1,%%a7 ; " \
+ "rts" \
+ : "=d" ((_the_context)->sr), "=d" ((_the_context)->a7_msp) \
+ : "0" ((_the_context)->sr), "1" ((_the_context)->a7_msp) ); \
+ }
+
+/*
+ * Floating Point Context Area Support routines
+ */
+
+#if (CPU_SOFTWARE_FP == TRUE)
+
+/*
+ * This software FP implementation is only for GCC.
+ */
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ((void *) _Addresses_Add_offset( (_base), (_offset) ) )
+
+
+#define _CPU_Context_Initialize_fp( _fp_area ) \
+ { \
+ Context_Control_fp *_fp; \
+ _fp = *(Context_Control_fp **)_fp_area; \
+ _fp->_exception_bits = 0; \
+ _fp->_trap_enable_bits = 0; \
+ _fp->_sticky_bits = 0; \
+ _fp->_rounding_mode = 0; /* ROUND_TO_NEAREST */ \
+ _fp->_format = 0; /* NIL */ \
+ _fp->_last_operation = 0; /* NOOP */ \
+ _fp->_operand1.df = 0; \
+ _fp->_operand2.df = 0; \
+ }
+#else
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ((void *) \
+ _Addresses_Add_offset( \
+ (_base), \
+ (_offset) + CPU_CONTEXT_FP_SIZE - 4 \
+ ) \
+ )
+
+#define _CPU_Context_Initialize_fp( _fp_area ) \
+ { uint32_t *_fp_context = (uint32_t *)*(_fp_area); \
+ \
+ *(--(_fp_context)) = 0; \
+ *(_fp_area) = (uint8_t *)(_fp_context); \
+ }
+#endif
+
+/* end of Context handler macros */
+
+/*
+ * _CPU_Thread_Idle_body
+ *
+ * This routine is the CPU dependent IDLE thread body.
+ *
+ * NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
+ * is TRUE.
+ */
+
+void _CPU_Thread_Idle_body( void );
+
+/*
+ * Fatal Error manager macros
+ *
+ * These macros perform the following functions:
+ * + disable interrupts and halt the CPU
+ */
+
+#if ( M68K_COLDFIRE_ARCH == 1 )
+#define _CPU_Fatal_halt( _error ) \
+ { asm volatile( "move.w %%sr,%%d0\n\t" \
+ "or.l %2,%%d0\n\t" \
+ "move.w %%d0,%%sr\n\t" \
+ "move.l %1,%%d0\n\t" \
+ "move.l #0xDEADBEEF,%%d1\n\t" \
+ "halt" \
+ : "=g" (_error) \
+ : "0" (_error), "d"(0x0700) \
+ : "d0", "d1" ); \
+ }
+#else
+#define _CPU_Fatal_halt( _error ) \
+ { asm volatile( "movl %0,%%d0; " \
+ "orw #0x0700,%%sr; " \
+ "stop #0x2700" : "=d" ((_error)) : "0" ((_error)) ); \
+ }
+#endif
+
+/* end of Fatal Error manager macros */
+
+/*
+ * Bitfield handler macros
+ *
+ * These macros perform the following functions:
+ * + scan for the highest numbered (MSB) set in a 16 bit bitfield
+ *
+ * NOTE:
+ *
+ * It appears that on the M68020 bitfield are always 32 bits wide
+ * when in a register. This code forces the bitfield to be in
+ * memory (it really always is anyway). This allows us to
+ * have a real 16 bit wide bitfield which operates "correctly."
+ */
+
+#define CPU_USE_GENERIC_BITFIELD_CODE FALSE
+#define CPU_USE_GENERIC_BITFIELD_DATA FALSE
+
+#if ( M68K_HAS_BFFFO == 1 )
+
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ asm volatile( "bfffo (%1),#0,#16,%0" : "=d" (_output) : "a" (&_value));
+
+#elif ( M68K_HAS_ISA_APLUS == 1 )
+ /* This is simplified by the fact that RTEMS never calls it with _value=0 */
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ asm volatile ( \
+ " swap %0\n" \
+ " ff1.l %0\n" \
+ : "=d" ((_output)) \
+ : "0" ((_value)) \
+ : "cc" ) ;
+
+#else
+/* duplicates BFFFO results for 16 bits (i.e., 15-(_priority) in
+ _CPU_Priority_bits_index is not needed), handles the 0 case, and
+ does not molest _value -- jsg */
+#if ( M68K_COLDFIRE_ARCH == 1 )
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ extern const unsigned char __BFFFOtable[256]; \
+ register int dumby; \
+ \
+ asm volatile ( \
+ " clr.l %1\n" \
+ " move.w %2,%1\n" \
+ " lsr.l #8,%1\n" \
+ " beq.s 1f\n" \
+ " move.b (%3,%1),%0\n" \
+ " bra.s 0f\n" \
+ "1: move.w %2,%1\n" \
+ " move.b (%3,%1),%0\n" \
+ " addq.l #8,%0\n" \
+ "0: and.l #0xff,%0\n" \
+ : "=&d" ((_output)), "=&d" ((dumby)) \
+ : "d" ((_value)), "ao" ((__BFFFOtable)) \
+ : "cc" ) ; \
+ }
+#elif ( M68K_HAS_EXTB_L == 1 )
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ extern const unsigned char __BFFFOtable[256]; \
+ register int dumby; \
+ \
+ asm volatile ( " move.w %2,%1\n" \
+ " lsr.w #8,%1\n" \
+ " beq.s 1f\n" \
+ " move.b (%3,%1.w),%0\n" \
+ " extb.l %0\n" \
+ " bra.s 0f\n" \
+ "1: moveq.l #8,%0\n" \
+ " add.b (%3,%2.w),%0\n" \
+ "0:\n" \
+ : "=&d" ((_output)), "=&d" ((dumby)) \
+ : "d" ((_value)), "ao" ((__BFFFOtable)) \
+ : "cc" ) ; \
+ }
+#else
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ extern const unsigned char __BFFFOtable[256]; \
+ register int dumby; \
+ \
+ asm volatile ( " move.w %2,%1\n" \
+ " lsr.w #8,%1\n" \
+ " beq.s 1f\n" \
+ " move.b (%3,%1.w),%0\n" \
+ " and.l #0x000000ff,%0\n"\
+ " bra.s 0f\n" \
+ "1: moveq.l #8,%0\n" \
+ " add.b (%3,%2.w),%0\n" \
+ "0:\n" \
+ : "=&d" ((_output)), "=&d" ((dumby)) \
+ : "d" ((_value)), "ao" ((__BFFFOtable)) \
+ : "cc" ) ; \
+ }
+#endif
+
+#endif
+
+/* end of Bitfield handler macros */
+
+/*
+ * Priority handler macros
+ *
+ * These macros perform the following functions:
+ * + return a mask with the bit for this major/minor portion of
+ * of thread priority set.
+ * + translate the bit number returned by "Bitfield_find_first_bit"
+ * into an index into the thread ready chain bit maps
+ */
+
+#define _CPU_Priority_Mask( _bit_number ) \
+ ( 0x8000 >> (_bit_number) )
+
+#define _CPU_Priority_bits_index( _priority ) \
+ (_priority)
+
+/* end of Priority handler macros */
+
+/* functions */
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/*
+ * _CPU_ISR_install_raw_handler
+ *
+ * This routine installs a "raw" interrupt handler directly into the
+ * processor's vector table.
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_Install_interrupt_stack
+ *
+ * This routine installs the hardware interrupt stack pointer.
+ */
+
+void _CPU_Install_interrupt_stack( void );
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+#if (M68K_HAS_FPSP_PACKAGE == 1)
+/*
+ * Hooks for the Floating Point Support Package (FPSP) provided by Motorola
+ *
+ * NOTES:
+ *
+ * Motorola 68k family CPU's before the 68040 used a coprocessor
+ * (68881 or 68882) to handle floating point. The 68040 has internal
+ * floating point support -- but *not* the complete support provided by
+ * the 68881 or 68882. The leftover functions are taken care of by the
+ * M68040 Floating Point Support Package. Quoting from the MC68040
+ * Microprocessors User's Manual, Section 9, Floating-Point Unit (MC68040):
+ *
+ * "When used with the M68040FPSP, the MC68040 FPU is fully
+ * compliant with IEEE floating-point standards."
+ *
+ * M68KFPSPInstallExceptionHandlers is in libcpu/m68k/MODEL/fpsp and
+ * is invoked early in the application code to ensure that proper FP
+ * behavior is installed. This is not left to the BSP to call, since
+ * this would force all applications using that BSP to use FPSP which
+ * is not necessarily desirable.
+ *
+ * There is a similar package for the 68060 but RTEMS does not yet
+ * support the 68060.
+ */
+
+void M68KFPSPInstallExceptionHandlers (void);
+
+SCORE_EXTERN int (*_FPSP_install_raw_handler)(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+#endif
+
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/m68k/rtems/score/m68k.h b/cpukit/score/cpu/m68k/rtems/score/m68k.h
new file mode 100644
index 0000000000..45277bfc20
--- /dev/null
+++ b/cpukit/score/cpu/m68k/rtems/score/m68k.h
@@ -0,0 +1,439 @@
+/**
+ * @file rtems/score/m68k.h
+ */
+
+/*
+ * This include file contains information pertaining to the Motorola
+ * m68xxx processor family.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_M68K_H
+#define _RTEMS_SCORE_M68K_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section contains the information required to build
+ * RTEMS for a particular member of the Motorola MC68xxx
+ * family. It does this by setting variables to indicate
+ * which implementation dependent features are present in
+ * a particular member of the family.
+ *
+ * Currently recognized:
+ * -m68000
+ * -m68000 -msoft-float
+ * -m68020
+ * -m68020 -msoft-float
+ * -m68030
+ * -m68040 -msoft-float
+ * -m68040
+ * -m68040 -msoft-float
+ * -m68060
+ * -m68060 -msoft-float
+ * -m68302 (no FP) (deprecated, use -m68000)
+ * -m68332 (no FP) (deprecated, use -mcpu32)
+ * -mcpu32 (no FP)
+ * -m5200 (no FP)
+ * -m528x (no FP, ISA A+)
+ *
+ * As of gcc 2.8.1 and egcs 1.1, there is no distinction made between
+ * the CPU32 and CPU32+. The option -mcpu32 generates code which can
+ * be run on either core. RTEMS distinguishes between these two cores
+ * because they have different alignment rules which impact performance.
+ * If you are using a CPU32+, then the symbol RTEMS__mcpu32p__ should
+ * be defined in your custom file (see make/custom/gen68360.cfg for an
+ * example of how to do this. If gcc ever distinguishes between these
+ * two cores, then RTEMS__mcpu32p__ usage will be replaced with the
+ * appropriate compiler defined predefine.
+ *
+ * Here is some information on the 040 variants (courtesy of Doug McBride,
+ * mcbride@rodin.colorado.edu):
+ *
+ * "The 68040 is a superset of the 68EC040 and the 68LC040. The
+ * 68EC040 and 68LC040 do not have FPU's. The 68LC040 and the
+ * 68EC040 have renamed the DLE pin as JS0 which must be tied to
+ * Gnd or Vcc. The 68EC040 has renamed the MDIS pin as JS1. The
+ * 68EC040 has access control units instead of memory management units.
+ * The 68EC040 should not have the PFLUSH or PTEST instructions executed
+ * (cause an indeterminate result). The 68EC040 and 68LC040 do not
+ * implement the DLE or multiplexed bus modes. The 68EC040 does not
+ * implement the output buffer impedance selection mode of operation."
+ *
+ * M68K_HAS_EXTB_L is used to enable/disable usage of the extb.l instruction
+ * which is not available for 68000 or 68ec000 cores (68000, 68001, 68008,
+ * 68010, 68302, 68306, 68307). This instruction is available on the 68020
+ * up and the cpu32 based models.
+ *
+ * M68K_HAS_MISALIGNED is non-zero if the CPU allows byte-misaligned
+ * data access (68020, 68030, 68040, 68060, CPU32+).
+ *
+ * NOTE:
+ * Eventually it would be nice to evaluate doing a lot of this section
+ * by having each model specify which core it uses and then go from there.
+ */
+
+/*
+ * Figure out all CPU Model Feature Flags based upon compiler
+ * predefines. Notice the only exception to this is that
+ * gcc does not distinguish between CPU32 and CPU32+. This
+ * feature selection logic is setup such that if RTEMS__mcpu32p__
+ * is defined, then CPU32+ rules are used. Otherwise, the safe
+ * but less efficient CPU32 rules are used for the CPU32+.
+ */
+
+#if (defined(__mc68020__) && !defined(__mcpu32__))
+
+#define CPU_MODEL_NAME "m68020"
+#define M68K_HAS_VBR 1
+#define M68K_HAS_SEPARATE_STACKS 1
+#define M68K_HAS_BFFFO 1
+#define M68K_HAS_PREINDEXING 1
+#define M68K_HAS_EXTB_L 1
+#define M68K_HAS_MISALIGNED 1
+# if defined (__HAVE_68881__)
+# define M68K_HAS_FPU 1
+# define M68K_HAS_FPSP_PACKAGE 0
+# else
+# define M68K_HAS_FPU 0
+# define M68K_HAS_FPSP_PACKAGE 0
+# endif
+
+#elif defined(__mc68030__)
+
+#define CPU_MODEL_NAME "m68030"
+#define M68K_HAS_VBR 1
+#define M68K_HAS_SEPARATE_STACKS 1
+#define M68K_HAS_BFFFO 1
+#define M68K_HAS_PREINDEXING 1
+#define M68K_HAS_EXTB_L 1
+#define M68K_HAS_MISALIGNED 1
+# if defined (__HAVE_68881__)
+# define M68K_HAS_FPU 1
+# define M68K_HAS_FPSP_PACKAGE 0
+# else
+# define M68K_HAS_FPU 0
+# define M68K_HAS_FPSP_PACKAGE 0
+# endif
+
+#elif defined(__mc68040__)
+
+#define CPU_MODEL_NAME "m68040"
+#define M68K_HAS_VBR 1
+#define M68K_HAS_SEPARATE_STACKS 1
+#define M68K_HAS_BFFFO 1
+#define M68K_HAS_PREINDEXING 1
+#define M68K_HAS_EXTB_L 1
+#define M68K_HAS_MISALIGNED 1
+# if defined (__HAVE_68881__)
+# define M68K_HAS_FPU 1
+# define M68K_HAS_FPSP_PACKAGE 1
+# else
+# define M68K_HAS_FPU 0
+# define M68K_HAS_FPSP_PACKAGE 0
+# endif
+
+#elif defined(__mc68060__)
+
+#define CPU_MODEL_NAME "m68060"
+#define M68K_HAS_VBR 1
+#define M68K_HAS_SEPARATE_STACKS 0
+#define M68K_HAS_BFFFO 1
+#define M68K_HAS_PREINDEXING 1
+#define M68K_HAS_EXTB_L 1
+#define M68K_HAS_MISALIGNED 1
+# if defined (__HAVE_68881__)
+# define M68K_HAS_FPU 1
+# define M68K_HAS_FPSP_PACKAGE 0
+# else
+# define M68K_HAS_FPU 0
+# define M68K_HAS_FPSP_PACKAGE 0
+# endif
+
+#elif defined(__mc68302__)
+
+#define CPU_MODEL_NAME "m68302"
+#define M68K_HAS_VBR 0
+#define M68K_HAS_SEPARATE_STACKS 0
+#define M68K_HAS_BFFFO 0
+#define M68K_HAS_PREINDEXING 0
+#define M68K_HAS_EXTB_L 0
+#define M68K_HAS_MISALIGNED 0
+#define M68K_HAS_FPU 0
+#define M68K_HAS_FPSP_PACKAGE 0
+
+ /* gcc and egcs do not distinguish between CPU32 and CPU32+ */
+#elif defined(RTEMS__mcpu32p__)
+
+#define CPU_MODEL_NAME "mcpu32+"
+#define M68K_HAS_VBR 1
+#define M68K_HAS_SEPARATE_STACKS 0
+#define M68K_HAS_BFFFO 0
+#define M68K_HAS_PREINDEXING 1
+#define M68K_HAS_EXTB_L 1
+#define M68K_HAS_MISALIGNED 1
+#define M68K_HAS_FPU 0
+#define M68K_HAS_FPSP_PACKAGE 0
+
+#elif defined(__mcpu32__)
+
+#define CPU_MODEL_NAME "mcpu32"
+#define M68K_HAS_VBR 1
+#define M68K_HAS_SEPARATE_STACKS 0
+#define M68K_HAS_BFFFO 0
+#define M68K_HAS_PREINDEXING 1
+#define M68K_HAS_EXTB_L 1
+#define M68K_HAS_MISALIGNED 0
+#define M68K_HAS_FPU 0
+#define M68K_HAS_FPSP_PACKAGE 0
+
+#elif defined(__mcf528x__)
+/* Motorola ColdFire ISA A+ - RISC/68020 hybrid */
+#define CPU_MODEL_NAME "m528x"
+#define M68K_HAS_VBR 1
+#define M68K_HAS_BFFFO 0
+#define M68K_HAS_SEPARATE_STACKS 0
+#define M68K_HAS_PREINDEXING 0
+#define M68K_HAS_EXTB_L 1
+#define M68K_HAS_MISALIGNED 1
+#define M68K_HAS_FPU 0
+#define M68K_HAS_FPSP_PACKAGE 0
+#define M68K_COLDFIRE_ARCH 1
+#define M68K_HAS_ISA_APLUS 1
+
+#elif defined(__mcf5200__)
+/* Motorola ColdFire V2 core - RISC/68020 hybrid */
+#define CPU_MODEL_NAME "m5200"
+#define M68K_HAS_VBR 1
+#define M68K_HAS_BFFFO 0
+#define M68K_HAS_SEPARATE_STACKS 0
+#define M68K_HAS_PREINDEXING 0
+#define M68K_HAS_EXTB_L 1
+#define M68K_HAS_MISALIGNED 1
+#define M68K_HAS_FPU 0
+#define M68K_HAS_FPSP_PACKAGE 0
+#define M68K_COLDFIRE_ARCH 1
+#define M68K_HAS_ISA_APLUS 0
+
+#elif defined(__mc68000__)
+
+#define CPU_MODEL_NAME "m68000"
+#define M68K_HAS_VBR 0
+#define M68K_HAS_SEPARATE_STACKS 0
+#define M68K_HAS_BFFFO 0
+#define M68K_HAS_PREINDEXING 0
+#define M68K_HAS_EXTB_L 0
+#define M68K_HAS_MISALIGNED 0
+# if defined (__HAVE_68881__)
+# define M68K_HAS_FPU 1
+# define M68K_HAS_FPSP_PACKAGE 0
+# else
+# define M68K_HAS_FPU 0
+# define M68K_HAS_FPSP_PACKAGE 0
+# endif
+
+#else
+
+#error "Unsupported CPU model -- are you sure you're running a 68k compiler?"
+
+#endif
+
+#ifndef ASM
+#include <rtems/score/types.h>
+#include <stdint.h>
+#endif
+
+/*
+ * If the above did not specify a ColdFire architecture, then set
+ * this flag to indicate that it is not a ColdFire CPU.
+ */
+
+#if !defined(M68K_COLDFIRE_ARCH)
+#define M68K_COLDFIRE_ARCH 0
+#endif
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#if ( M68K_COLDFIRE_ARCH == 1 )
+ #define CPU_NAME "Motorola ColdFire"
+#else
+ #define CPU_NAME "Motorola MC68xxx"
+#endif
+
+#ifndef ASM
+
+#if ( M68K_COLDFIRE_ARCH == 1 )
+#define m68k_disable_interrupts( _level ) \
+ do { register uint32_t _tmpsr = 0x0700; \
+ asm volatile ( "move.w %%sr,%0\n\t" \
+ "or.l %0,%1\n\t" \
+ "move.w %1,%%sr" \
+ : "=d" (_level), "=d"(_tmpsr) : "1"(_tmpsr) \
+ : "cc" ); \
+ } while( 0 )
+#else
+#define m68k_disable_interrupts( _level ) \
+ asm volatile ( "move.w %%sr,%0\n\t" \
+ "or.w #0x0700,%%sr" \
+ : "=d" (_level) \
+ : : "cc" )
+#endif
+
+#define m68k_enable_interrupts( _level ) \
+ asm volatile ( "move.w %0,%%sr " : : "d" (_level) : "cc");
+
+#if ( M68K_COLDFIRE_ARCH == 1 )
+#define m68k_flash_interrupts( _level ) \
+ do { register uint32_t _tmpsr = 0x0700; \
+ asm volatile ( "move.w %2,%%sr\n\t" \
+ "or.l %2,%1\n\t" \
+ "move.w %1,%%sr" \
+ : "=d"(_tmpsr) : "0"(_tmpsr), "d"(_level) \
+ : "cc"); \
+ } while( 0 )
+#else
+#define m68k_flash_interrupts( _level ) \
+ asm volatile ( "move.w %0,%%sr\n\t" \
+ "or.w #0x0700,%%sr" \
+ : : "d" (_level) \
+ : "cc" )
+#endif
+
+#define m68k_get_interrupt_level( _level ) \
+ do { \
+ register uint32_t _tmpsr; \
+ \
+ asm volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \
+ _level = (_tmpsr & 0x0700) >> 8; \
+ } while (0)
+
+#define m68k_set_interrupt_level( _newlevel ) \
+ do { \
+ register uint32_t _tmpsr; \
+ \
+ asm volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \
+ _tmpsr = (_tmpsr & 0xf8ff) | ((_newlevel) << 8); \
+ asm volatile( "move.w %0,%%sr" : : "d" (_tmpsr)); \
+ } while (0)
+
+#if ( M68K_HAS_VBR == 1 && M68K_COLDFIRE_ARCH == 0 )
+#define m68k_get_vbr( vbr ) \
+ asm volatile ( "movec %%vbr,%0 " : "=r" (vbr))
+
+#define m68k_set_vbr( vbr ) \
+ asm volatile ( "movec %0,%%vbr " : : "r" (vbr))
+
+#elif ( M68K_COLDFIRE_ARCH == 1 )
+extern void* _VBR;
+#define m68k_get_vbr( _vbr ) _vbr = &_VBR
+
+#define m68k_set_vbr( _vbr ) \
+ do { \
+ asm volatile ( "movec %0,%%vbr " : : "r" (_vbr)); \
+ _VBR = (void *)_vbr; \
+ } while(0)
+
+#else
+#define m68k_get_vbr( _vbr ) _vbr = (void *)_VBR
+#define m68k_set_vbr( _vbr )
+#endif
+
+/*
+ * The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ */
+#if ( M68K_COLDFIRE_ARCH == 1 )
+
+/* There are no rotate commands in Coldfire architecture. We will use
+ * generic implementation of endian swapping for Coldfire.
+ */
+static inline uint32_t m68k_swap_u32(
+ uint32_t value
+ )
+{
+ uint32_t byte1, byte2, byte3, byte4, swapped;
+
+ byte4 = (value >> 24) & 0xff;
+ byte3 = (value >> 16) & 0xff;
+ byte2 = (value >> 8) & 0xff;
+ byte1 = value & 0xff;
+
+ swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
+ return( swapped );
+}
+
+static inline uint16_t m68k_swap_u16(
+ uint16_t value
+)
+{
+ return (((value & 0xff) << 8) | ((value >> 8) & 0xff));
+}
+
+#else
+
+static inline uint32_t m68k_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t swapped = value;
+
+ asm volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) );
+ asm volatile( "swap %0" : "=d" (swapped) : "0" (swapped) );
+ asm volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) );
+
+ return( swapped );
+}
+
+static inline uint16_t m68k_swap_u16(
+ uint16_t value
+)
+{
+ uint16_t swapped = value;
+
+ asm volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) );
+
+ return( swapped );
+}
+#endif
+
+#define CPU_swap_u32( value ) m68k_swap_u32( value )
+#define CPU_swap_u16( value ) m68k_swap_u16( value )
+
+
+/*
+ * _CPU_virtual_to_physical
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to map virtual addresses to physical
+ * addresses.
+ *
+ * FIXME: ASSUMES THAT VIRTUAL ADDRESSES ARE THE SAME AS THE
+ * PHYSICAL ADDRESSES
+ */
+static inline void * _CPU_virtual_to_physical (
+ const void * d_addr )
+{
+ return (void *) d_addr;
+}
+
+
+#endif /* !ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_M68K_H */
diff --git a/cpukit/score/cpu/m68k/rtems/score/types.h b/cpukit/score/cpu/m68k/rtems/score/types.h
new file mode 100644
index 0000000000..76495ba4f6
--- /dev/null
+++ b/cpukit/score/cpu/m68k/rtems/score/types.h
@@ -0,0 +1,55 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains type definitions pertaining to the Motorola
+ * m68xxx processor family.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+
+typedef uint16_t Priority_Bit_map_control;
+
+typedef signed long long signed64; /* 64 bit signed integer */
+
+typedef uint32_t boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void m68k_isr;
+
+typedef void ( *m68k_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/mips/.cvsignore b/cpukit/score/cpu/mips/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/mips/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/mips/ChangeLog b/cpukit/score/cpu/mips/ChangeLog
new file mode 100644
index 0000000000..5007e66b32
--- /dev/null
+++ b/cpukit/score/cpu/mips/ChangeLog
@@ -0,0 +1,526 @@
+2006-06-02 Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+ * cpu.c: Added __mips==32 to fix build problems on those targets
+ caused by the Bruce Robinson.
+
+2006-06-08 Bruce Robinson <brucer@pmccorp.com>
+
+ * cpu.c: Add int64 types for __mips==3 cpus, incorporate
+ mips_interrupt_mask() into mask computations
+ * cpu_asm.S: Add int64 register save/restores for __mips==3 cpus. Adjustment
+ of mips1 vs mips3 macros.
+ * cpu.h: Add int64 types for __mips==3 cpus.
+
+2006-03-17 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * cpu.c (_CPU_Initialize): Add fpu initialization.
+ * rtems/score/cpu.h: Setup CPU_*_ENDIAN from GCC's__MIPS{EL|EB}__.
+ (Partial merger of submission by Bruce Robinson <brucer@pmccorp.com>).
+
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Part of a large patch to improve Doxygen output.
+ As a side-effect, grammar and spelling errors were corrected, spacing
+ errors were address, and some variable names were improved.
+
+2005-11-18 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Eliminate use of unsigned32.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16, unsigned32.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h: Remove private version of CONCAT macros.
+ Include <rtems/concat.h> instead.
+
+2005-04-26 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/asm.h: Eliminate warnings.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/mips/idtcpu.h, rtems/mips/iregdef.h, rtems/score/mips.h:
+ Header guards cleanup.
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2005-02-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR rtems/752
+ * rtems/mips/idtcpu.h rtems/mips/iregdef.h: New (relocated from .).
+ New header guards.
+ * idtcpu.h, iregdef.h: Remove.
+ * Makefile.am: Reflect changes above.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/cpu.h, rtems/score/mips.h, rtems/score/types.h:
+ New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: *_swap_u32( uint32_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: #include <rtems/stdint.h>.
+
+2005-01-07 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Remove warnings.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-03 Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+ PR 739
+ * iregdef.h: Fixes gcc warning about redundant definition of R_SZ
+ when compiling cpu_asm.S. Problem was a #define sneaked in in
+ version 1.11, no ill effects would have only affected R4000
+ builds.
+
+2005-01-03 Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+ PR 737
+ * cpu_asm.S: Fixes gcc warning about instructions in branch delay
+ slot when compiling cpu_asm.S
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove build-variant support.
+
+2004-12-02 Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+ PR 730
+ * cpu_asm.S: Collected PR 601 changes for commit to cvshead
+ for rtems-4.7.
+
+2004-04-09 Joel Sherrill <joel@OARcorp.com>
+
+ PR 605/bsps
+ * cpu.c: Do not use C++ style comments.
+
+2004-04-07 Greg Menke <gregory.menke@gsfc.nasa.gov>
+ PR 601
+ * cpu_asm.S: Added __mips==32 support for R4000 processors running
+ 32 bit code. Fixed #define problems that caused fpu code to
+ always be included even when no fpu is present.
+
+2004-04-03 Art Ferrer <arturo.b.ferrer@nasa.gov>
+
+ PR 598/bsps
+ * cpu_asm.S, rtems/score/cpu.h: Add save of floating point
+ status/control register on context switches. Missing this register
+ was causing intermittent floating point errors.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, cpu_asm.S, rtems/score/cpu.h, rtems/score/mips.h,
+ rtems/score/types.h: URL for license changed.
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require autoconf-2.57 + automake-1.7.2.
+ * Makefile.am: Eliminate C_O_FILES, S_O_FILES, libscorecpu_a_OBJECTS.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix package name.
+
+2002-11-04 Joel Sherrill <joel@OARcorp.com>
+
+ * idtcpu.h: Removed warning.
+
+2002-11-01 Joel Sherrill <joel@OARcorp.com>
+
+ * idtcpu.h: Removed warnings.
+
+2002-10-28 Joel Sherrill <joel@OARcorp.com>
+
+ * idtcpu.h: Removed warning by turning extra token at the end of
+ an endif into a comment.
+
+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-14 Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+ * cpu_asm.S: Clarified some comments, removed code that forced
+ SR_IEP on when returning from an interrupt.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add RTEMS_PROG_CCAS
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AC_CONFIG_AUX_DIR(../../../..).
+ Add AC_PROG_RANLIB.
+
+2002-06-20 Greg Menke <gregory.menke@gsfc.nasa.gov>
+ * cpu_asm.S: Added SR_IEO to context restore to fix isr disabled
+ deadlock caused by interrupt arriving while dispatching.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/../../../automake/*.am.
+ Use ../../../aclocal.
+
+2001-04-03 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
+ * rtems/score/mipstypes.h: Removed.
+ * rtems/score/types.h: New file via CVS magic.
+ * Makefile.am, 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.
+
+2002-03-20 Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+ * cpu_asm.S: Now compiles on 4600 and 4650.
+
+2002-03-13 Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+ * cpu_asm.S: Fixed a sneaky return from int w/ ints disabled bug.
+ * rtems/score/cpu.h: Fixed register numbering in comments and made
+ interrupt enable/disable more robust.
+
+2002-03-05 Greg Menke <gregory.menke@gsfc.nasa.gov>
+ * cpu_asm.S: Added support for the debug exception vector, cleaned
+ up the exception processing & exception return stuff. Re-added
+ EPC in the task context structure so the gdb stub will know where
+ a thread is executing. Should've left it there in the first place...
+ * idtcpu.h: Added support for the debug exception vector.
+ * cpu.c: Added ___exceptionTaskStack to hold a pointer to the
+ stack frame in an interrupt so context switch code can get the
+ userspace EPC when scheduling.
+ * rtems/score/cpu.h: Re-added EPC to the task context.
+
+2002-02-27 Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+ * cpu_asm.S: Fixed exception return address, modified FP context
+ switch so FPU is properly enabled and also doesn't screw up the
+ exception FP handling.
+ * idtcpu.h: Added C0_TAR, the MIPS target address register used for
+ returning from exceptions.
+ * iregdef.h: Added R_TAR to the stack frame so the target address
+ can be saved on a per-exception basis. The new entry is past the
+ end of the frame gdb cares about, so doesn't affect gdb or cpu.h
+ stuff.
+ * rtems/score/cpu.h: added an #ifdef so cpu_asm.S can include it
+ to obtain FPU defines without syntax errors generated by the C
+ defintions.
+ * cpu.c: Improved interrupt level saves & restores.
+
+2002-02-08 Joel Sherrill <joel@OARcorp.com>
+
+ * iregdef.h, rtems/score/cpu.h: Reordered register in the
+ exception stack frame to better match gdb's expectations.
+
+2001-02-05 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu_asm.S: Enhanced to save/restore more registers on
+ exceptions.
+ * rtems/score/cpu.h (CPU_Interrupt_frame): Enhanced to list every
+ register individually and document when it is saved.
+ * idtcpu.h: Added constants for the coprocessor 1 registers
+ revision and status.
+
+2001-02-05 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/Makefile.am, rtems/score/Makefile.am: Removed again.
+
+2001-02-04 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: IDLE task should not be FP. This was a mistake
+ in the previous patch that has now been confirmed.
+
+2001-02-01 Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+ * cpu.c: Enhancements and fixes for modifying the SR when changing
+ the interrupt level.
+ * cpu_asm.S: Fixed handling of FP enable bit so it is properly
+ managed on a per-task basis, improved handling of interrupt levels,
+ and made deferred FP contexts work on the MIPS.
+ * rtems/score/cpu.h: Modified to support above changes.
+
+2002-01-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/Makefile.am: Removed.
+ * rtems/score/Makefile.am: Removed.
+ * configure.ac: Reflect changes above.
+ * Makefile.am: Reflect changes above.
+
+2002-02-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * asm.h: Remove #include <rtems/score/targopts.h>.
+ Add #include <rtems/score/cpuopts.h>.
+ * configure.ac: Remove RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP).
+
+
+2001-12-20 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use RTEMS_ENV_RTEMSCPU.
+
+2001-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add multilib support.
+
+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.
+
+2001-10-12 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu_asm.S: _CPU_Context_save_fp in was incorrectly in conditional
+ compilation block with (CPU_HARDWARE_FP == FALSE). Reported by
+ Wayne Bullaughey <wayne@wmi.com>.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/Makefile.am: Use 'PREINSTALL_FILES ='.
+ * Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-07-03 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c: Fixed typo.
+
+2000-05-24 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/mips.h: Added constants for MIPS exception numbers.
+ All exceptions should be given low numbers and thus can be installed
+ and processed in a uniform manner. Variances between various MIPS
+ ISA levels were not accounted for.
+
+2001-05-24 Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+ * Assisted in design and debug by Joel Sherrill <joel@OARcorp.com>.
+ * cpu_asm.S: Now works on Mongoose-V. Missed in previous patch.
+
+2001-05-22 Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+ * rtems/score/cpu.h: Add the interrupt stack structure and enhance
+ the context initialization to account for floating point tasks.
+ * rtems/score/mips.h: Added the routines mips_set_cause(),
+ mips_get_fcr31(), and mips_set_fcr31().
+ * Assisted in design and debug by Joel Sherrill <joel@OARcorp.com>.
+
+2001-05-07 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu_asm.S: Merged patches from Gregory Menke
+ <Gregory.D.Menke.1@gsfc.nasa.gov> that clean up
+ stack usage and include nops in the delay slots.
+
+2001-04-20 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu_asm.S: Added code to save and restore SR and EPC to
+ properly support nested interrupts. Note that the ISR
+ (not RTEMS) enables interrupts allowing the nesting to occur.
+
+2001-03-14 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, rtems/score/cpu.h, rtems/score/mipstypes.h:
+ Removed unused variable _CPU_Thread_dispatch_pointer
+ and cleaned numerous comments.
+
+2001-03-13 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, cpu_asm.S, iregdef.h, rtems/score/cpu.h, rtems/score/mips.h:
+ Merged MIPS1 and MIPS3 code reducing the number of lines of assembly.
+ Also reimplemented some assembly routines in C further reducing
+ the amount of assembly and increasing maintainability.
+
+2001-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, rtems/score/Makefile.am:
+ Apply include_*HEADERS instead of H_FILES.
+
+2001-01-12 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/mips.h (mips_get_sr, mips_set_sr): Corrected
+ register constraints from "general" to "register".
+
+2001-01-09 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu_asm.S: Use SR_INTERRUPT_ENABLE_BITS instead of SR_XXX constants
+ to make it easier to conditionalize the code for various ISA levels.
+
+2001-01-08 Joel Sherrill <joel@OARcorp.com>
+
+ * idtcpu.h: Commented out definition of "wait". It was stupid to
+ use such a common word as a macro.
+ * rtems/score/cpu.h (_CPU_ISR_Disable): Fixed for mips ISA 3.
+ * rtems/score/mips.h: Added include of <idtcpu.h>.
+ * rtems/score/mips.h (mips_enable_in_interrupt_mask): Corrected.
+
+2001-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Added _CPU_Initialize_vectors().
+ * cpu_asm.S: Eliminated warning for duplicate definition of EXTERN.
+
+2000-12-19 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu_asm.S (_ISR_Handler): Return to the address in the EPC register.
+ Previous code resulting in the interrupted immediately returning
+ to the caller of the routine it was inside.
+
+2000-12-19 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c (_CPU_Initialize): Do not initialize _ISR_Vector_table() here
+ because it has not been allocated yet.
+
+2000-12-13 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c: Removed duplicate declaration for _ISR_Vector_table.
+ * cpu_asm.S: Removed assembly language to vector ISR handler
+ on MIPS ISA I. Now call mips_vector_isr_handlers() in libcpu or BSP.
+ * rtems/score/cpu.h (CPU_INTERRUPT_NUMBER_OF_VECTORS): No
+ longer a constant -- get the real value from libcpu.
+
+2000-12-13 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu_asm.h: Removed.
+ * Makefile.am: Remove cpu_asm.h.
+ * rtems/score/mips64orion.h: Renamed mips.h.
+ * rtems/score/mips.h: New file, formerly mips64orion.h.
+ Header rewritten.
+ (mips_get_sr, mips_set_sr, mips_enable_in_interrupt_mask,
+ mips_disable_in_interrupt_mask): New macros.
+ * rtems/score/Makefile.am: Reflect renaming mips64orion.h.
+ * asm.h: Include <mips.h> not <mips64orion.h>. Now includes the
+ few defines that were in <cpu_asm.h>.
+ * cpu.c (_CPU_ISR_Get_level): Added MIPS ISA I version of this routine.
+ MIPS ISA 3 is still in assembly for now.
+ (_CPU_Thread_Idle_body): Rewrote in C.
+ * cpu_asm.S: Rewrote file header.
+ (FRAME,ENDFRAME) now in asm.h.
+ (_CPU_ISR_Get_level): Removed ISA I version and rewrote in C.
+ (_CPU_ISR_Set_level): Removed ISA I version and rewrote in C.
+ (_CPU_Context_switch): MIPS ISA I now manages preserves SR_IEC and
+ leaves other bits in SR alone on task switch.
+ (mips_enable_interrupts,mips_disable_interrupts,
+ mips_enable_global_interrupts,mips_disable_global_interrupts,
+ disable_int, enable_int): Removed.
+ (mips_get_sr): Rewritten as C macro.
+ (_CPU_Thread_Idle_body): Rewritten in C.
+ (init_exc_vecs): Rewritten in C as mips_install_isr_entries() and
+ placed in libcpu.
+ (exc_tlb_code, exc_xtlb_code, exc_cache_code, exc_norm_code): Moved
+ to libcpu/mips/shared/interrupts.
+ (general): Cleaned up comment blocks and #if 0 areas.
+ * idtcpu.h: Made ifdef report an error.
+ * iregdef.h: Removed warning.
+ * rtems/score/cpu.h (CPU_INTERRUPT_NUMBER_OF_VECTORS): Now a variable
+ number defined by libcpu.
+ (_CPU_ISR_Disable, _CPU_ISR_Enable): Rewritten to use new routines
+ to access SR.
+ (_CPU_ISR_Set_level): Rewritten as macro for ISA I.
+ (_CPU_Context_Initialize): Honor ISR level in task initialization.
+ (_CPU_Fatal_halt): Use new _CPU_ISR_Disable() macro.
+
+2000-12-06 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: When mips ISA level is 1, registers in the
+ context should be 32 not 64 bits.
+
+2000-11-30 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu_asm.S: Changed "_CPU_Ccontext_switch_restore: typo to
+ correct name of _CPU_Context_switch_restore. Added dummy
+ version of exc_utlb_code() so applications would link.
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
+ Switch to GNU canonicalization.
+
+2000-10-24 Alan Cudmore <alanc@linuxstart.com> and
+ Joel Sherrill <joel@OARcorp.com>
+
+ * This is a major reworking of the mips64orion port to use
+ gcc predefines as much as possible and a big push to multilib
+ the mips port. The mips64orion port was copied/renamed to mips
+ to be more like other GNU tools. Alan did most of the technical
+ work of determining how to map old macro names used by the mips64orion
+ port to standard compiler macro definitions. Joel did the merge
+ with CVS magic to keep individual file history and did the BSP
+ modifications. Details follow:
+ * Makefile.am: idtmon.h in mips64orion port not present.
+ * asm.h: MIPS64ORION replaced with MIPS. Frame setup macros added.
+ * cpu.c: Comments added.
+ * cpu_asm.S: Conditionals changed. MIPS ISA level 1 support added.
+ First attempt at exception/interrupt processing for ISA level 1
+ and minus any use of IDT/MON added.
+ * idtcpu.h: Conditionals changed to use gcc predefines.
+ * iregdef.h: Ditto.
+ * cpu_asm.h: No real change. Merger required commit.
+ * rtems/Makefile.am: Ditto.
+ * rtems/score/Makefile.am: Ditto.
+ * rtems/score/cpu.h: Change MIPS64ORION to MIPS.
+ * rtems/score/mips64orion.h: Change MIPS64ORION to MIPS. Convert
+ from using RTEMS_CPU_MODEL to gcc predefines to figre things out.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am.
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: New file.
diff --git a/cpukit/score/cpu/mips/Makefile.am b/cpukit/score/cpu/mips/Makefile.am
new file mode 100644
index 0000000000..bb7d3faf4b
--- /dev/null
+++ b/cpukit/score/cpu/mips/Makefile.am
@@ -0,0 +1,22 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_mipsdir = $(includedir)/rtems/mips
+include_rtems_mips_HEADERS = rtems/mips/idtcpu.h rtems/mips/iregdef.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/mips.h \
+ rtems/score/types.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/mips/cpu.c b/cpukit/score/cpu/mips/cpu.c
new file mode 100644
index 0000000000..320fc7ba2f
--- /dev/null
+++ b/cpukit/score/cpu/mips/cpu.c
@@ -0,0 +1,288 @@
+/*
+ * Mips CPU Dependent Source
+ *
+ * 2002: Greg Menke (gregory.menke@gsfc.nasa.gov)
+ * Overhauled interrupt level and interrupt enable/disable code
+ * to more exactly support MIPS. Our mods were for MIPS1 processors
+ * MIPS3 ports are affected, though apps written to the old behavior
+ * should still work OK.
+ *
+ * Conversion to MIPS port by Alan Cudmore <alanc@linuxstart.com> and
+ * Joel Sherrill <joel@OARcorp.com>.
+ *
+ * These changes made the code conditional on standard cpp predefines,
+ * merged the mips1 and mips3 code sequences as much as possible,
+ * and moved some of the assembly code to C. Alan did much of the
+ * initial analysis and rework. Joel took over from there and
+ * wrote the JMR3904 BSP so this could be tested. Joel also
+ * added the new interrupt vectoring support in libcpu and
+ * tried to better support the various interrupt controllers.
+ *
+ * Original MIP64ORION port by Craig Lebakken <craigl@transition.com>
+ * COPYRIGHT (c) 1996 by Transition Networks Inc.
+ *
+ * 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 Transition Networks not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * Transition Networks makes no representations about the
+ * suitability of this software for any purpose.
+ *
+ * COPYRIGHT (c) 1989-2001.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/wkspace.h>
+
+
+
+
+/*
+** Exception stack frame pointer used in cpu_asm to pass the exception stack frame
+** address to the context switch code.
+*/
+#if (__mips == 1) || (__mips == 32)
+typedef uint32_t ESF_PTR_TYPE;
+#elif (__mips == 3)
+typedef uint64_t ESF_PTR_TYPE;
+#else
+#error "unknown MIPS ISA"
+#endif
+
+ESF_PTR_TYPE __exceptionStackFrame = 0;
+
+
+
+
+/* _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 */
+)
+{
+ /*
+ * If there is not an easy way to initialize the FP context
+ * during Context_Initialize, then it is usually easier to
+ * save an "uninitialized" FP context here and copy it to
+ * the task's during Context_Initialize.
+ */
+
+#if CPU_HARDWARE_FP
+ /* FP context initialization support goes here */
+ _CPU_Null_fp_context.fpcs = 0x1000000; /* Set FS flag in floating point coprocessor
+ control register to prevent underflow and
+ inexact exceptions */
+#endif
+ _CPU_Table = *cpu_table;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Get_level
+ *
+ * This routine returns the current interrupt level.
+ */
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ unsigned int sr;
+
+ mips_get_sr(sr);
+
+ /* printf("current sr=%08X, ",sr); */
+
+#if (__mips == 3) || (__mips == 32)
+/* IE bit and shift down hardware ints into bits 1 thru 6 */
+ sr = (sr & SR_IE) | ((sr & mips_interrupt_mask()) >> 9);
+
+#elif __mips == 1
+/* IEC bit and shift down hardware ints into bits 1 thru 6 */
+ sr = (sr & SR_IEC) | ((sr & mips_interrupt_mask()) >> 9);
+
+#else
+#error "CPU ISR level: unknown MIPS level for SR handling"
+#endif
+ return sr;
+}
+
+
+void _CPU_ISR_Set_level( uint32_t new_level )
+{
+ unsigned int sr, srbits;
+
+ /*
+ ** mask off the int level bits only so we can
+ ** preserve software int settings and FP enable
+ ** for this thread. Note we don't force software ints
+ ** enabled when changing level, they were turned on
+ ** when this task was created, but may have been turned
+ ** off since, so we'll just leave them alone.
+ */
+
+ new_level &= 0xff;
+
+ mips_get_sr(sr);
+
+#if (__mips == 3) || (__mips == 32)
+ mips_set_sr( (sr & ~SR_IE) ); /* first disable ie bit (recommended) */
+
+ srbits = sr & ~(0xfc00 | SR_IE);
+
+ sr = srbits | ((new_level==0)? (mips_interrupt_mask() | SR_IE): \
+ (((new_level<<9) & mips_interrupt_mask()) | \
+ ((new_level & 1)?SR_IE:0)));
+/*
+ if ( (new_level & SR_EXL) == (sr & SR_EXL) )
+ return;
+
+ if ( (new_level & SR_EXL) == 0 ) {
+ sr &= ~SR_EXL; * clear the EXL bit *
+ mips_set_sr(sr);
+ } else {
+
+ sr |= SR_EXL|SR_IE; * enable exception level *
+ mips_set_sr(sr); * first disable ie bit (recommended) *
+ }
+*/
+
+#elif __mips == 1
+ mips_set_sr( (sr & ~SR_IEC) );
+ srbits = sr & ~(0xfc00 | SR_IEC);
+ sr = srbits | ((new_level==0)?0xfc01:( ((new_level<<9) & 0xfc00) | \
+ (new_level & SR_IEC)));
+#else
+#error "CPU ISR level: unknown MIPS level for SR handling"
+#endif
+ mips_set_sr( sr );
+}
+
+
+
+/*PAGE
+ *
+ * _CPU_ISR_install_raw_handler
+ *
+ * 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_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ /*
+ * This is where we install the interrupt handler into the "raw" interrupt
+ * table used by the CPU to dispatch interrupt handlers.
+ *
+ * Because all interrupts are vectored through the same exception handler
+ * this is not necessary on thi sport.
+ */
+}
+
+/*PAGE
+ *
+ * _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(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ *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.
+ */
+
+ _CPU_ISR_install_raw_handler( vector, _ISR_Handler, old_handler );
+
+ /*
+ * 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;
+}
+
+/*PAGE
+ *
+ * _CPU_Install_interrupt_stack
+ */
+
+void _CPU_Install_interrupt_stack( void )
+{
+/* we don't support this yet */
+}
+
+/*PAGE
+ *
+ * _CPU_Internal_threads_Idle_thread_body
+ *
+ * NOTES:
+ *
+ * 1. This is the same as the regular CPU independent algorithm.
+ *
+ * 2. If you implement this using a "halt", "idle", or "shutdown"
+ * instruction, then don't forget to put it in an infinite loop.
+ *
+ * 3. Be warned. Some processors with onboard DMA have been known
+ * to stop the DMA if the CPU were put in IDLE mode. This might
+ * also be a problem with other on-chip peripherals. So use this
+ * hook with caution.
+ */
+
+void _CPU_Thread_Idle_body( void )
+{
+#if (__mips == 3) || (__mips == 32)
+ for( ; ; )
+ asm volatile("wait"); /* use wait to enter low power mode */
+#elif __mips == 1
+ for( ; ; )
+ ;
+#else
+#error "IDLE: __mips not set to 1 or 3"
+#endif
+}
diff --git a/cpukit/score/cpu/mips/cpu_asm.S b/cpukit/score/cpu/mips/cpu_asm.S
new file mode 100644
index 0000000000..e3bed37abd
--- /dev/null
+++ b/cpukit/score/cpu/mips/cpu_asm.S
@@ -0,0 +1,1153 @@
+/*
+ * This file contains the basic algorithms for all assembly code used
+ * in an specific CPU port of RTEMS. These algorithms must be implemented
+ * in assembly language
+ *
+ * History:
+ * Baseline: no_cpu
+ * 1996: Ported to MIPS64ORION by Craig Lebakken <craigl@transition.com>
+ * COPYRIGHT (c) 1996 by Transition Networks Inc.
+ * To anyone who acknowledges that the modifications to this file to
+ * port it to the MIPS64ORION are 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 Transition Networks not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Transition
+ * Networks makes no representations about the suitability
+ * of this software for any purpose.
+ * 2000: Reworked by Alan Cudmore <alanc@linuxstart.com> to become
+ * the baseline of the more general MIPS port.
+ * 2001: Joel Sherrill <joel@OARcorp.com> continued this rework,
+ * rewriting as much as possible in C and added the JMR3904 BSP
+ * so testing could be performed on a simulator.
+ * 2001: Greg Menke <gregory.menke@gsfc.nasa.gov>, bench tested ISR
+ * performance, tweaking this code and the isr vectoring routines
+ * to reduce overhead & latencies. Added optional
+ * instrumentation as well.
+ * 2002: Greg Menke <gregory.menke@gsfc.nasa.gov>, overhauled cpu_asm.S,
+ * cpu.c and cpu.h to manage FP vs int only tasks, interrupt levels
+ * and deferred FP contexts.
+ * 2002: Joel Sherrill <joel@OARcorp.com> enhanced the exception processing
+ * by increasing the amount of context saved/restored.
+ * 2004: 24March, Art Ferrer, NASA/GSFC, added save of FP status/control
+ * register to fix intermittent FP error encountered on ST5 mission
+ * implementation on Mongoose V processor.
+ * 2004: April 7, Greg Menke <gregory.menke@gsfc.nasa.gov> Added __mips==32
+ * support for R4000 processors running 32 bit code. Fixed #define
+ * problems that caused fpu code to always be included even when no
+ * fpu is present.
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/asm.h>
+#include <rtems/mips/iregdef.h>
+#include <rtems/mips/idtcpu.h>
+
+#define ASSEMBLY_ONLY
+#include <rtems/score/cpu.h>
+
+#if TRUE
+#else
+#error TRUE is not true
+#endif
+#if FALSE
+#error FALSE is not false
+#else
+#endif
+
+/*
+#if ( CPU_HARDWARE_FP == TRUE )
+#warning CPU_HARDWARE_FP == TRUE
+#else
+#warning CPU_HARDWARE_FP != TRUE
+#endif
+*/
+
+
+/* enable debugging shadow writes to misc ram, this is a vestigal
+* Mongoose-ism debug tool- but may be handy in the future so we
+* left it in...
+*/
+
+/* #define INSTRUMENT_ISR_VECTORING */
+/* #define INSTRUMENT_EXECUTING_THREAD */
+
+
+
+/* Ifdefs prevent the duplication of code for MIPS ISA Level 3 ( R4xxx )
+ * and MIPS ISA Level 1 (R3xxx).
+ */
+
+#if __mips == 3
+/* 64 bit register operations */
+#define NOP nop
+#define ADD dadd
+#define STREG sd
+#define LDREG ld
+#define MFCO dmfc0 /* Only use this op for coprocessor registers that are 64 bit in R4000 architecture */
+#define MTCO dmtc0 /* Only use this op for coprocessor registers that are 64 bit in R4000 architecture */
+#define ADDU addu
+#define ADDIU addiu
+#if (__mips_fpr==32)
+#define STREGC1 swc1
+#define LDREGC1 lwc1
+#elif (__mips_fpr==64) /* Use these instructions if there are 64 bit floating point registers. This requires FR bit to be set in C0_SR */
+#define STREGC1 sdc1
+#define LDREGC1 ldc1
+#endif
+#define R_SZ 8
+#define F_SZ 8
+#define SZ_INT 8
+#define SZ_INT_POW2 3
+
+/* XXX if we don't always want 64 bit register ops, then another ifdef */
+
+#elif (__mips == 1 ) || (__mips == 32)
+/* 32 bit register operations*/
+#define NOP nop
+#define ADD add
+#define STREG sw
+#define LDREG lw
+#define MFCO mfc0
+#define MTCO mtc0
+#define ADDU add
+#define ADDIU addi
+#define STREGC1 swc1
+#define LDREGC1 lwc1
+#define R_SZ 4
+#define F_SZ 4
+#define SZ_INT 4
+#define SZ_INT_POW2 2
+#else
+#error "mips assembly: what size registers do I deal with?"
+#endif
+
+
+#define ISR_VEC_SIZE 4
+#define EXCP_STACK_SIZE (NREGS*R_SZ)
+
+
+#ifdef __GNUC__
+#define ASM_EXTERN(x,size) .extern x,size
+#else
+#define ASM_EXTERN(x,size)
+#endif
+
+/* NOTE: these constants must match the Context_Control structure in cpu.h */
+#define S0_OFFSET 0
+#define S1_OFFSET 1
+#define S2_OFFSET 2
+#define S3_OFFSET 3
+#define S4_OFFSET 4
+#define S5_OFFSET 5
+#define S6_OFFSET 6
+#define S7_OFFSET 7
+#define SP_OFFSET 8
+#define FP_OFFSET 9
+#define RA_OFFSET 10
+#define C0_SR_OFFSET 11
+#define C0_EPC_OFFSET 12
+
+/* NOTE: these constants must match the Context_Control_fp structure in cpu.h */
+#define FP0_OFFSET 0
+#define FP1_OFFSET 1
+#define FP2_OFFSET 2
+#define FP3_OFFSET 3
+#define FP4_OFFSET 4
+#define FP5_OFFSET 5
+#define FP6_OFFSET 6
+#define FP7_OFFSET 7
+#define FP8_OFFSET 8
+#define FP9_OFFSET 9
+#define FP10_OFFSET 10
+#define FP11_OFFSET 11
+#define FP12_OFFSET 12
+#define FP13_OFFSET 13
+#define FP14_OFFSET 14
+#define FP15_OFFSET 15
+#define FP16_OFFSET 16
+#define FP17_OFFSET 17
+#define FP18_OFFSET 18
+#define FP19_OFFSET 19
+#define FP20_OFFSET 20
+#define FP21_OFFSET 21
+#define FP22_OFFSET 22
+#define FP23_OFFSET 23
+#define FP24_OFFSET 24
+#define FP25_OFFSET 25
+#define FP26_OFFSET 26
+#define FP27_OFFSET 27
+#define FP28_OFFSET 28
+#define FP29_OFFSET 29
+#define FP30_OFFSET 30
+#define FP31_OFFSET 31
+#define FPCS_OFFSET 32
+
+
+ASM_EXTERN(__exceptionStackFrame, SZ_INT)
+
+
+
+/*
+ * _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.
+ */
+
+/* void _CPU_Context_save_fp(
+ * void **fp_context_ptr
+ * );
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE )
+FRAME(_CPU_Context_save_fp,sp,0,ra)
+ .set noreorder
+ .set noat
+
+ /*
+ ** Make sure the FPU is on before we save state. This code
+ ** is here because the FPU context switch might occur when an
+ ** integer task is switching out with a FP task switching in.
+ */
+ mfc0 t0,C0_SR
+ li t2,SR_CU1
+ move t1,t0
+ or t0,t2 /* turn on the fpu */
+#if (__mips == 3) || (__mips == 32)
+ li t2,SR_IE
+#elif __mips == 1
+ li t2,SR_IEC
+#endif
+ not t2
+ and t0,t2 /* turn off interrupts */
+ mtc0 t0,C0_SR
+
+ lw a1,(a0) /* get address of context storage area */
+ move t0,ra
+ jal _CPU_Context_save_fp_from_exception
+ NOP
+
+ /*
+ ** Reassert the task's state because we've not saved it yet.
+ */
+ mtc0 t1,C0_SR
+ j t0
+ NOP
+
+ .globl _CPU_Context_save_fp_from_exception
+_CPU_Context_save_fp_from_exception:
+ STREGC1 $f0,FP0_OFFSET*F_SZ(a1)
+ STREGC1 $f1,FP1_OFFSET*F_SZ(a1)
+ STREGC1 $f2,FP2_OFFSET*F_SZ(a1)
+ STREGC1 $f3,FP3_OFFSET*F_SZ(a1)
+ STREGC1 $f4,FP4_OFFSET*F_SZ(a1)
+ STREGC1 $f5,FP5_OFFSET*F_SZ(a1)
+ STREGC1 $f6,FP6_OFFSET*F_SZ(a1)
+ STREGC1 $f7,FP7_OFFSET*F_SZ(a1)
+ STREGC1 $f8,FP8_OFFSET*F_SZ(a1)
+ STREGC1 $f9,FP9_OFFSET*F_SZ(a1)
+ STREGC1 $f10,FP10_OFFSET*F_SZ(a1)
+ STREGC1 $f11,FP11_OFFSET*F_SZ(a1)
+ STREGC1 $f12,FP12_OFFSET*F_SZ(a1)
+ STREGC1 $f13,FP13_OFFSET*F_SZ(a1)
+ STREGC1 $f14,FP14_OFFSET*F_SZ(a1)
+ STREGC1 $f15,FP15_OFFSET*F_SZ(a1)
+ STREGC1 $f16,FP16_OFFSET*F_SZ(a1)
+ STREGC1 $f17,FP17_OFFSET*F_SZ(a1)
+ STREGC1 $f18,FP18_OFFSET*F_SZ(a1)
+ STREGC1 $f19,FP19_OFFSET*F_SZ(a1)
+ STREGC1 $f20,FP20_OFFSET*F_SZ(a1)
+ STREGC1 $f21,FP21_OFFSET*F_SZ(a1)
+ STREGC1 $f22,FP22_OFFSET*F_SZ(a1)
+ STREGC1 $f23,FP23_OFFSET*F_SZ(a1)
+ STREGC1 $f24,FP24_OFFSET*F_SZ(a1)
+ STREGC1 $f25,FP25_OFFSET*F_SZ(a1)
+ STREGC1 $f26,FP26_OFFSET*F_SZ(a1)
+ STREGC1 $f27,FP27_OFFSET*F_SZ(a1)
+ STREGC1 $f28,FP28_OFFSET*F_SZ(a1)
+ STREGC1 $f29,FP29_OFFSET*F_SZ(a1)
+ STREGC1 $f30,FP30_OFFSET*F_SZ(a1)
+ STREGC1 $f31,FP31_OFFSET*F_SZ(a1)
+ cfc1 a0,$31 /* Read FP status/conrol reg */
+ cfc1 a0,$31 /* Two reads clear pipeline */
+ NOP
+ NOP
+ sw a0, FPCS_OFFSET*F_SZ(a1) /* Store value to FPCS location */
+ NOP
+ j ra
+ NOP
+ .set at
+ENDFRAME(_CPU_Context_save_fp)
+#endif
+
+/*
+ * _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.
+ */
+
+/* void _CPU_Context_restore_fp(
+ * void **fp_context_ptr
+ * )
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE )
+FRAME(_CPU_Context_restore_fp,sp,0,ra)
+ .set noat
+ .set noreorder
+
+ /*
+ ** Make sure the FPU is on before we retrieve state. This code
+ ** is here because the FPU context switch might occur when an
+ ** integer task is switching out with a FP task switching in.
+ */
+ mfc0 t0,C0_SR
+ li t2,SR_CU1
+ move t1,t0
+ or t0,t2 /* turn on the fpu */
+#if (__mips == 3) || (__mips == 32)
+ li t2,SR_IE
+#elif __mips == 1
+ li t2,SR_IEC
+#endif
+ not t2
+ and t0,t2 /* turn off interrupts */
+ mtc0 t0,C0_SR
+
+ lw a1,(a0) /* get address of context storage area */
+ move t0,ra
+ jal _CPU_Context_restore_fp_from_exception
+ NOP
+
+ /*
+ ** Reassert the old task's state because we've not restored the
+ ** new one yet.
+ */
+ mtc0 t1,C0_SR
+ j t0
+ NOP
+
+ .globl _CPU_Context_restore_fp_from_exception
+_CPU_Context_restore_fp_from_exception:
+ LDREGC1 $f0,FP0_OFFSET*F_SZ(a1)
+ LDREGC1 $f1,FP1_OFFSET*F_SZ(a1)
+ LDREGC1 $f2,FP2_OFFSET*F_SZ(a1)
+ LDREGC1 $f3,FP3_OFFSET*F_SZ(a1)
+ LDREGC1 $f4,FP4_OFFSET*F_SZ(a1)
+ LDREGC1 $f5,FP5_OFFSET*F_SZ(a1)
+ LDREGC1 $f6,FP6_OFFSET*F_SZ(a1)
+ LDREGC1 $f7,FP7_OFFSET*F_SZ(a1)
+ LDREGC1 $f8,FP8_OFFSET*F_SZ(a1)
+ LDREGC1 $f9,FP9_OFFSET*F_SZ(a1)
+ LDREGC1 $f10,FP10_OFFSET*F_SZ(a1)
+ LDREGC1 $f11,FP11_OFFSET*F_SZ(a1)
+ LDREGC1 $f12,FP12_OFFSET*F_SZ(a1)
+ LDREGC1 $f13,FP13_OFFSET*F_SZ(a1)
+ LDREGC1 $f14,FP14_OFFSET*F_SZ(a1)
+ LDREGC1 $f15,FP15_OFFSET*F_SZ(a1)
+ LDREGC1 $f16,FP16_OFFSET*F_SZ(a1)
+ LDREGC1 $f17,FP17_OFFSET*F_SZ(a1)
+ LDREGC1 $f18,FP18_OFFSET*F_SZ(a1)
+ LDREGC1 $f19,FP19_OFFSET*F_SZ(a1)
+ LDREGC1 $f20,FP20_OFFSET*F_SZ(a1)
+ LDREGC1 $f21,FP21_OFFSET*F_SZ(a1)
+ LDREGC1 $f22,FP22_OFFSET*F_SZ(a1)
+ LDREGC1 $f23,FP23_OFFSET*F_SZ(a1)
+ LDREGC1 $f24,FP24_OFFSET*F_SZ(a1)
+ LDREGC1 $f25,FP25_OFFSET*F_SZ(a1)
+ LDREGC1 $f26,FP26_OFFSET*F_SZ(a1)
+ LDREGC1 $f27,FP27_OFFSET*F_SZ(a1)
+ LDREGC1 $f28,FP28_OFFSET*F_SZ(a1)
+ LDREGC1 $f29,FP29_OFFSET*F_SZ(a1)
+ LDREGC1 $f30,FP30_OFFSET*F_SZ(a1)
+ LDREGC1 $f31,FP31_OFFSET*F_SZ(a1)
+ cfc1 a0,$31 /* Read from FP status/control reg */
+ cfc1 a0,$31 /* Two reads clear pipeline */
+ NOP /* NOPs ensure execution */
+ NOP
+ lw a0,FPCS_OFFSET*F_SZ(a1) /* Load saved FPCS value */
+ NOP
+ ctc1 a0,$31 /* Restore FPCS register */
+ NOP
+ j ra
+ NOP
+ .set at
+ENDFRAME(_CPU_Context_restore_fp)
+#endif
+
+/* _CPU_Context_switch
+ *
+ * This routine performs a normal non-FP context switch.
+ */
+
+/* void _CPU_Context_switch(
+ * Context_Control *run,
+ * Context_Control *heir
+ * )
+ */
+
+FRAME(_CPU_Context_switch,sp,0,ra)
+ .set noreorder
+
+ mfc0 t0,C0_SR
+#if (__mips == 3) || (__mips == 32)
+ li t1,SR_IE
+#elif __mips == 1
+ li t1,SR_IEC
+#endif
+ STREG t0,C0_SR_OFFSET*R_SZ(a0) /* save the task's SR */
+ not t1
+ and t0,t1 /* mask off interrupts while we context switch */
+ mtc0 t0,C0_SR
+ NOP
+
+ STREG ra,RA_OFFSET*R_SZ(a0) /* save current context */
+ STREG sp,SP_OFFSET*R_SZ(a0)
+ STREG fp,FP_OFFSET*R_SZ(a0)
+ STREG s0,S0_OFFSET*R_SZ(a0)
+ STREG s1,S1_OFFSET*R_SZ(a0)
+ STREG s2,S2_OFFSET*R_SZ(a0)
+ STREG s3,S3_OFFSET*R_SZ(a0)
+ STREG s4,S4_OFFSET*R_SZ(a0)
+ STREG s5,S5_OFFSET*R_SZ(a0)
+ STREG s6,S6_OFFSET*R_SZ(a0)
+ STREG s7,S7_OFFSET*R_SZ(a0)
+
+
+ /*
+ ** this code grabs the userspace EPC if we're dispatching from
+ ** an interrupt frame or supplies the address of the dispatch
+ ** routines if not. This is entirely for the gdbstub's benefit so
+ ** it can know where each task is running.
+ **
+ ** Its value is only set when calling threadDispatch from
+ ** the interrupt handler and is cleared immediately when this
+ ** routine gets it.
+ */
+
+ la t0,__exceptionStackFrame /* see if we're coming in from an exception */
+ LDREG t1, (t0)
+ NOP
+ beqz t1,1f
+
+ STREG zero, (t0) /* and clear it */
+ NOP
+ LDREG t0,R_EPC*R_SZ(t1) /* get the userspace EPC from the frame */
+ b 2f
+ NOP
+
+1: la t0,_Thread_Dispatch /* if ==0, we're switched out */
+
+2: STREG t0,C0_EPC_OFFSET*R_SZ(a0)
+
+
+_CPU_Context_switch_restore:
+ LDREG ra,RA_OFFSET*R_SZ(a1) /* restore context */
+ LDREG sp,SP_OFFSET*R_SZ(a1)
+ LDREG fp,FP_OFFSET*R_SZ(a1)
+ LDREG s0,S0_OFFSET*R_SZ(a1)
+ LDREG s1,S1_OFFSET*R_SZ(a1)
+ LDREG s2,S2_OFFSET*R_SZ(a1)
+ LDREG s3,S3_OFFSET*R_SZ(a1)
+ LDREG s4,S4_OFFSET*R_SZ(a1)
+ LDREG s5,S5_OFFSET*R_SZ(a1)
+ LDREG s6,S6_OFFSET*R_SZ(a1)
+ LDREG s7,S7_OFFSET*R_SZ(a1)
+
+ LDREG t0, C0_SR_OFFSET*R_SZ(a1)
+
+/* NOP */
+/*#if (__mips == 3) || (__mips == 32) */
+/* andi t0,SR_EXL */
+/* bnez t0,_CPU_Context_1 */ /* set exception level from restore context */
+/* li t0,~SR_EXL */
+/* MFC0 t1,C0_SR */
+/* NOP */
+/* and t1,t0 */
+/* MTC0 t1,C0_SR */
+/* */
+/*#elif __mips == 1 */
+/* */
+/* andi t0,(SR_INTERRUPT_ENABLE_BITS) */ /* we know 0 disabled */
+/* beq t0,$0,_CPU_Context_1 */ /* set level from restore context */
+/* MFC0 t0,C0_SR */
+/* NOP */
+/* or t0,(SR_INTERRUPT_ENABLE_BITS) */ /* new_sr = old sr with enabled */
+/* MTC0 t0,C0_SR */ /* set with enabled */
+/* NOP */
+
+
+/*
+** Incorporate the incoming task's FP coprocessor state and interrupt mask/enable
+** into the status register. We jump thru the requisite hoops to ensure we
+** maintain all other SR bits as global values.
+**
+** Get the task's FPU enable, int mask & int enable bits. Although we keep the
+** software int enables on a per-task basis, the rtems_task_create
+** Interrupt Level & int level manipulation functions cannot enable/disable them,
+** so they are automatically enabled for all tasks. To turn them off, a task
+** must itself manipulate the SR register.
+**
+** Although something of a hack on this processor, we treat the SR register
+** int enables as the RTEMS interrupt level. We use the int level
+** value as a bitmask, not as any sort of greater than/less than metric.
+** Manipulation of a task's interrupt level corresponds directly to manipulation
+** of that task's SR bits, as seen in cpu.c
+**
+** Note, interrupts are disabled before context is saved, though the task's
+** interrupt enable state is recorded. The task swapping in will apply its
+** specific SR bits, including interrupt enable. If further task-specific
+** SR bits are arranged, it is this code, the cpu.c interrupt level stuff and
+** cpu.h task initialization code that will be affected.
+*/
+
+ li t2,SR_CU1
+ or t2,SR_IMASK
+
+ /* int enable bits */
+#if (__mips == 3) || (__mips == 32)
+ /*
+ ** Save IE
+ */
+ or t2,SR_IE
+#elif __mips == 1
+ /*
+ ** Save current, previous & old int enables. This is key because
+ ** we can dispatch from within the stack frame used by an
+ ** interrupt service. The int enables nest, but not beyond
+ ** previous and old because of the dispatch interlock seen
+ ** in the interrupt processing code.
+ */
+ or t2,SR_IEC + SR_IEP + SR_IEO
+#endif
+ and t0,t2 /* keep only the per-task bits */
+
+ mfc0 t1,C0_SR /* grab the current SR */
+ not t2
+ and t1,t2 /* mask off the old task's per-task bits */
+ or t1,t0 /* or in the new task's bits */
+ mtc0 t1,C0_SR /* and load the new SR */
+ NOP
+
+/* _CPU_Context_1: */
+ j ra
+ NOP
+ENDFRAME(_CPU_Context_switch)
+
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally 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.
+ *
+ * void _CPU_Context_restore(
+ * Context_Control *new_context
+ * );
+ */
+
+FRAME(_CPU_Context_restore,sp,0,ra)
+ .set noreorder
+ move a1,a0
+ j _CPU_Context_switch_restore
+ NOP
+
+ENDFRAME(_CPU_Context_restore)
+
+
+ASM_EXTERN(_ISR_Nest_level,4)
+ASM_EXTERN(_Thread_Dispatch_disable_level,4)
+ASM_EXTERN(_Context_Switch_necessary,4)
+ASM_EXTERN(_ISR_Signals_to_thread_executing,4)
+ASM_EXTERN(_Thread_Executing,4)
+
+.extern _Thread_Dispatch
+.extern _ISR_Vector_table
+
+
+
+
+
+/* void _DBG_Handler()
+ *
+ * This routine services the (at least) MIPS1 debug vector,
+ * only used the the hardware debugging features. This code,
+ * while optional, is best located here because its intrinsically
+ * associated with exceptions in general & thus tied pretty
+ * closely to _ISR_Handler.
+ *
+ */
+
+
+FRAME(_DBG_Handler,sp,0,ra)
+ .set noreorder
+ la k0,_ISR_Handler
+ j k0
+ NOP
+ .set reorder
+ENDFRAME(_DBG_Handler)
+
+
+
+
+
+/* void __ISR_Handler()
+ *
+ * This routine provides the RTEMS interrupt management.
+ *
+ * void _ISR_Handler()
+ *
+ *
+ * This discussion ignores a lot of the ugly details in a real
+ * implementation such as saving enough registers/state to be
+ * able to do something real. Keep in mind that the goal is
+ * to invoke a user's ISR handler which is written in C and
+ * uses a certain set of registers.
+ *
+ * Also note that the exact order is to a large extent flexible.
+ * Hardware will dictate a sequence for a certain subset of
+ * _ISR_Handler while requirements for setting
+ *
+ * At entry to "common" _ISR_Handler, the vector number must be
+ * available. On some CPUs the hardware puts either the vector
+ * number or the offset into the vector table for this ISR in a
+ * known place. If the hardware does not give us this information,
+ * then the assembly portion of RTEMS for this port will contain
+ * a set of distinct interrupt entry points which somehow place
+ * the vector number in a known place (which is safe if another
+ * interrupt nests this one) and branches to _ISR_Handler.
+ *
+ */
+
+FRAME(_ISR_Handler,sp,0,ra)
+ .set noreorder
+
+ /* Q: _ISR_Handler, not using IDT/SIM ...save extra regs? */
+
+ /* wastes a lot of stack space for context?? */
+ ADDIU sp,sp,-EXCP_STACK_SIZE
+
+ STREG ra, R_RA*R_SZ(sp) /* store ra on the stack */
+ STREG v0, R_V0*R_SZ(sp)
+ STREG v1, R_V1*R_SZ(sp)
+ STREG a0, R_A0*R_SZ(sp)
+ STREG a1, R_A1*R_SZ(sp)
+ STREG a2, R_A2*R_SZ(sp)
+ STREG a3, R_A3*R_SZ(sp)
+ STREG t0, R_T0*R_SZ(sp)
+ STREG t1, R_T1*R_SZ(sp)
+ STREG t2, R_T2*R_SZ(sp)
+ STREG t3, R_T3*R_SZ(sp)
+ STREG t4, R_T4*R_SZ(sp)
+ STREG t5, R_T5*R_SZ(sp)
+ STREG t6, R_T6*R_SZ(sp)
+ STREG t7, R_T7*R_SZ(sp)
+ mflo t0
+ STREG t8, R_T8*R_SZ(sp)
+ STREG t0, R_MDLO*R_SZ(sp)
+ STREG t9, R_T9*R_SZ(sp)
+ mfhi t0
+ STREG gp, R_GP*R_SZ(sp)
+ STREG t0, R_MDHI*R_SZ(sp)
+ STREG fp, R_FP*R_SZ(sp)
+
+ .set noat
+ STREG AT, R_AT*R_SZ(sp)
+ .set at
+
+ mfc0 t0,C0_SR
+ MFCO t1,C0_EPC
+ STREG t0,R_SR*R_SZ(sp)
+ STREG t1,R_EPC*R_SZ(sp)
+
+
+#ifdef INSTRUMENT_EXECUTING_THREAD
+ lw t2, _Thread_Executing
+ NOP
+ sw t2, 0x8001FFF0
+#endif
+
+ /* determine if an interrupt generated this exception */
+
+ mfc0 t0,C0_CAUSE
+ NOP
+
+ and t1,t0,CAUSE_EXCMASK
+ beq t1, 0, _ISR_Handler_1
+
+_ISR_Handler_Exception:
+
+ /* If we return from the exception, it is assumed nothing
+ * bad is going on and we can continue to run normally.
+ * But we want to save the entire CPU context so exception
+ * handlers can look at it and change it.
+ *
+ * NOTE: This is the path the debugger stub will take.
+ */
+
+ /* already got t0 = cause in the interrupt test above */
+ STREG t0,R_CAUSE*R_SZ(sp)
+
+ STREG sp, R_SP*R_SZ(sp)
+
+ STREG s0,R_S0*R_SZ(sp) /* save s0 - s7 */
+ STREG s1,R_S1*R_SZ(sp)
+ STREG s2,R_S2*R_SZ(sp)
+ STREG s3,R_S3*R_SZ(sp)
+ STREG s4,R_S4*R_SZ(sp)
+ STREG s5,R_S5*R_SZ(sp)
+ STREG s6,R_S6*R_SZ(sp)
+ STREG s7,R_S7*R_SZ(sp)
+
+ /* CP0 special registers */
+
+#if __mips == 1
+ mfc0 t0,C0_TAR
+#endif
+ MFCO t1,C0_BADVADDR
+
+#if __mips == 1
+ STREG t0,R_TAR*R_SZ(sp)
+#else
+ NOP
+#endif
+ STREG t1,R_BADVADDR*R_SZ(sp)
+
+#if ( CPU_HARDWARE_FP == TRUE )
+ mfc0 t0,C0_SR /* FPU is enabled, save state */
+ NOP
+ srl t0,t0,16
+ andi t0,t0,(SR_CU1 >> 16)
+ beqz t0, 1f
+ NOP
+
+ la a1,R_F0*R_SZ(sp)
+ jal _CPU_Context_save_fp_from_exception
+ NOP
+ mfc1 t0,C1_REVISION
+ mfc1 t1,C1_STATUS
+ STREG t0,R_FEIR*R_SZ(sp)
+ STREG t1,R_FCSR*R_SZ(sp)
+
+1:
+#endif
+
+ move a0,sp
+ jal mips_vector_exceptions
+ NOP
+
+
+ /*
+ ** Note, if the exception vector returns, rely on it to have
+ ** adjusted EPC so we will return to some correct address. If
+ ** this is not done, we might get stuck in an infinite loop because
+ ** we'll return to the instruction where the exception occured and
+ ** it could throw again.
+ **
+ ** It is expected the only code using the exception processing is
+ ** either the gdb stub or some user code which is either going to
+ ** panic or do something useful. Regardless, it is up to each
+ ** exception routine to properly adjust EPC, so the code below
+ ** may be helpful for doing just that.
+ */
+
+/* *********************************************************************
+** this code follows the R3000's exception return logic, but is not
+** needed because the gdb stub does it for us. It might be useful
+** for something else at some point...
+**
+ * compute the address of the instruction we'll return to *
+
+ LDREG t1, R_CAUSE*R_SZ(sp)
+ LDREG t0, R_EPC*R_SZ(sp)
+
+ * first see if the exception happened in the delay slot *
+ li t3,CAUSE_BD
+ AND t4,t1,t3
+ beqz t4,excnodelay
+ NOP
+
+ * it did, now see if the branch occured or not *
+ li t3,CAUSE_BT
+ AND t4,t1,t3
+ beqz t4,excnobranch
+ NOP
+
+ * branch was taken, we resume at the branch target *
+ LDREG t0, R_TAR*R_SZ(sp)
+ j excreturn
+ NOP
+
+excnobranch:
+ ADDU t0,R_SZ
+
+excnodelay:
+ ADDU t0,R_SZ
+
+excreturn:
+ STREG t0, R_EPC*R_SZ(sp)
+ NOP
+********************************************************************* */
+
+
+ /* if we're returning into mips_break, move to the next instruction */
+
+ LDREG t0,R_EPC*R_SZ(sp)
+ la t1,mips_break
+ xor t2,t0,t1
+ bnez t2,3f
+
+ addu t0,R_SZ
+ STREG t0,R_EPC*R_SZ(sp)
+ NOP
+3:
+
+
+
+
+#if ( CPU_HARDWARE_FP == TRUE )
+ mfc0 t0,C0_SR /* FPU is enabled, restore state */
+ NOP
+ srl t0,t0,16
+ andi t0,t0,(SR_CU1 >> 16)
+ beqz t0, 2f
+ NOP
+
+ la a1,R_F0*R_SZ(sp)
+ jal _CPU_Context_restore_fp_from_exception
+ NOP
+ LDREG t0,R_FEIR*R_SZ(sp)
+ LDREG t1,R_FCSR*R_SZ(sp)
+ mtc1 t0,C1_REVISION
+ mtc1 t1,C1_STATUS
+2:
+#endif
+ LDREG s0,R_S0*R_SZ(sp) /* restore s0 - s7 */
+ LDREG s1,R_S1*R_SZ(sp)
+ LDREG s2,R_S2*R_SZ(sp)
+ LDREG s3,R_S3*R_SZ(sp)
+ LDREG s4,R_S4*R_SZ(sp)
+ LDREG s5,R_S5*R_SZ(sp)
+ LDREG s6,R_S6*R_SZ(sp)
+ LDREG s7,R_S7*R_SZ(sp)
+
+ /* do NOT restore the sp as this could mess up the world */
+ /* do NOT restore the cause as this could mess up the world */
+
+ /*
+ ** Jump all the way out. If theres a pending interrupt, just
+ ** let it be serviced later. Since we're probably using the
+ ** gdb stub, we've already disrupted the ISR service timing
+ ** anyhow. We oughtn't mix exception and interrupt processing
+ ** in the same exception call in case the exception stuff
+ ** might interfere with the dispatching & timer ticks.
+ */
+ j _ISR_Handler_exit
+ NOP
+
+_ISR_Handler_1:
+
+ mfc0 t1,C0_SR
+ and t0,CAUSE_IPMASK
+ and t0,t1
+
+ /* external interrupt not enabled, ignore */
+ /* but if it's not an exception or an interrupt, */
+ /* Then where did it come from??? */
+
+ beq t0,zero,_ISR_Handler_exit
+ NOP
+
+
+ /*
+ * save some or all context on stack
+ * may need to save some special interrupt information for exit
+ *
+ * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
+ * if ( _ISR_Nest_level == 0 )
+ * switch to software interrupt stack
+ * #endif
+ */
+
+
+ /*
+ * _ISR_Nest_level++;
+ */
+ lw t0,_ISR_Nest_level
+ NOP
+ add t0,t0,1
+ sw t0,_ISR_Nest_level
+ /*
+ * _Thread_Dispatch_disable_level++;
+ */
+ lw t1,_Thread_Dispatch_disable_level
+ NOP
+ add t1,t1,1
+ sw t1,_Thread_Dispatch_disable_level
+
+ /*
+ * Call the CPU model or BSP specific routine to decode the
+ * interrupt source and actually vector to device ISR handlers.
+ */
+
+#ifdef INSTRUMENT_ISR_VECTORING
+ NOP
+ li t1, 1
+ sw t1, 0x8001e000
+#endif
+
+ move a0,sp
+ jal mips_vector_isr_handlers
+ NOP
+
+#ifdef INSTRUMENT_ISR_VECTORING
+ li t1, 0
+ sw t1, 0x8001e000
+ NOP
+#endif
+
+ /*
+ * --_ISR_Nest_level;
+ */
+ lw t2,_ISR_Nest_level
+ NOP
+ add t2,t2,-1
+ sw t2,_ISR_Nest_level
+ /*
+ * --_Thread_Dispatch_disable_level;
+ */
+ lw t1,_Thread_Dispatch_disable_level
+ NOP
+ add t1,t1,-1
+ sw t1,_Thread_Dispatch_disable_level
+ /*
+ * if ( _Thread_Dispatch_disable_level || _ISR_Nest_level )
+ * goto the label "exit interrupt (simple case)"
+ */
+ or t0,t2,t1
+ bne t0,zero,_ISR_Handler_exit
+ NOP
+
+
+ /*
+ * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
+ * restore stack
+ * #endif
+ *
+ * if ( !_Context_Switch_necessary && !_ISR_Signals_to_thread_executing )
+ * goto the label "exit interrupt (simple case)"
+ */
+ lw t0,_Context_Switch_necessary
+ lw t1,_ISR_Signals_to_thread_executing
+ NOP
+ or t0,t0,t1
+ beq t0,zero,_ISR_Handler_exit
+ NOP
+
+
+
+#ifdef INSTRUMENT_EXECUTING_THREAD
+ lw t0,_Thread_Executing
+ NOP
+ sw t0,0x8001FFF4
+#endif
+
+/*
+** Turn on interrupts before entering Thread_Dispatch which
+** will run for a while, thus allowing new interrupts to
+** be serviced. Observe the Thread_Dispatch_disable_level interlock
+** that prevents recursive entry into Thread_Dispatch.
+*/
+
+ mfc0 t0, C0_SR
+#if __mips == 1
+
+ li t1,SR_IEC
+ or t0, t1
+
+#elif (__mips == 3) || (__mips == 32)
+
+ /*
+ ** clear XL and set IE so we can get interrupts.
+ */
+ li t1, SR_EXL
+ not t1
+ and t0,t1
+ or t0, SR_IE
+
+#endif
+ mtc0 t0, C0_SR
+ NOP
+
+ /* save off our stack frame so the context switcher can get to it */
+ la t0,__exceptionStackFrame
+ STREG sp,(t0)
+
+ jal _Thread_Dispatch
+ NOP
+
+ /*
+ ** And make sure its clear in case we didn't dispatch. if we did, its
+ ** already cleared
+ */
+ la t0,__exceptionStackFrame
+ STREG zero,(t0)
+ NOP
+
+/*
+** turn interrupts back off while we restore context so
+** a badly timed interrupt won't mess things up
+*/
+ mfc0 t0, C0_SR
+
+#if __mips == 1
+
+ /* ints off, current & prev kernel mode on (kernel mode enabled is bit clear..argh!) */
+ li t1,SR_IEC | SR_KUP | SR_KUC
+ not t1
+ and t0, t1
+ mtc0 t0, C0_SR
+ NOP
+
+#elif (__mips == 3) || (__mips == 32)
+
+ /* make sure EXL and IE are set so ints are disabled & we can update EPC for the return */
+ li t1,SR_IE /* Clear IE first (recommended) */
+ not t1
+ and t0,t1
+ mtc0 t0,C0_SR
+ NOP
+
+ /* apply task's SR with EXL set so the eret will return properly */
+ or t0, SR_EXL | SR_IE
+ mtc0 t0, C0_SR
+ NOP
+
+ /* store new EPC value, which we can do since EXL=0 */
+ LDREG t0, R_EPC*R_SZ(sp)
+ NOP
+ MTCO t0, C0_EPC
+ NOP
+
+#endif
+
+
+
+
+
+
+#ifdef INSTRUMENT_EXECUTING_THREAD
+ lw t0,_Thread_Executing
+ NOP
+ sw t0,0x8001FFF8
+#endif
+
+
+ /*
+ * prepare to get out of interrupt
+ * return from interrupt (maybe to _ISR_Dispatch)
+ *
+ * LABEL "exit interrupt (simple case):"
+ * prepare to get out of interrupt
+ * return from interrupt
+ */
+
+_ISR_Handler_exit:
+/*
+** Skip the SR restore because its a global register. _CPU_Context_switch_restore
+** adjusts it according to each task's configuration. If we didn't dispatch, the
+** SR value isn't changed, so all we need to do is return.
+**
+*/
+ /* restore context from stack */
+
+#ifdef INSTRUMENT_EXECUTING_THREAD
+ lw t0,_Thread_Executing
+ NOP
+ sw t0, 0x8001FFFC
+#endif
+
+ LDREG t8, R_MDLO*R_SZ(sp)
+ LDREG t0, R_T0*R_SZ(sp)
+ mtlo t8
+ LDREG t8, R_MDHI*R_SZ(sp)
+ LDREG t1, R_T1*R_SZ(sp)
+ mthi t8
+ LDREG t2, R_T2*R_SZ(sp)
+ LDREG t3, R_T3*R_SZ(sp)
+ LDREG t4, R_T4*R_SZ(sp)
+ LDREG t5, R_T5*R_SZ(sp)
+ LDREG t6, R_T6*R_SZ(sp)
+ LDREG t7, R_T7*R_SZ(sp)
+ LDREG t8, R_T8*R_SZ(sp)
+ LDREG t9, R_T9*R_SZ(sp)
+ LDREG gp, R_GP*R_SZ(sp)
+ LDREG fp, R_FP*R_SZ(sp)
+ LDREG ra, R_RA*R_SZ(sp)
+ LDREG a0, R_A0*R_SZ(sp)
+ LDREG a1, R_A1*R_SZ(sp)
+ LDREG a2, R_A2*R_SZ(sp)
+ LDREG a3, R_A3*R_SZ(sp)
+ LDREG v1, R_V1*R_SZ(sp)
+ LDREG v0, R_V0*R_SZ(sp)
+
+#if __mips == 1
+ LDREG k1, R_EPC*R_SZ(sp)
+#endif
+
+ .set noat
+ LDREG AT, R_AT*R_SZ(sp)
+ .set at
+
+ ADDIU sp,sp,EXCP_STACK_SIZE
+
+#if (__mips == 3) || (__mips == 32)
+ eret
+#elif __mips == 1
+ j k1
+ rfe
+#endif
+ NOP
+
+ .set reorder
+ENDFRAME(_ISR_Handler)
+
+
+
+
+FRAME(mips_break,sp,0,ra)
+ .set noreorder
+ break 0x0 /* this statement must be first in this function, assumed so by mips-stub.c */
+ NOP
+ j ra
+ NOP
+ .set reorder
+ENDFRAME(mips_break)
+
diff --git a/cpukit/score/cpu/mips/preinstall.am b/cpukit/score/cpu/mips/preinstall.am
new file mode 100644
index 0000000000..bf7ed03a0c
--- /dev/null
+++ b/cpukit/score/cpu/mips/preinstall.am
@@ -0,0 +1,54 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/mips/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/mips
+ @: > $(PROJECT_INCLUDE)/rtems/mips/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/mips/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/mips/idtcpu.h: rtems/mips/idtcpu.h $(PROJECT_INCLUDE)/rtems/mips/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/mips/idtcpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/mips/idtcpu.h
+
+$(PROJECT_INCLUDE)/rtems/mips/iregdef.h: rtems/mips/iregdef.h $(PROJECT_INCLUDE)/rtems/mips/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/mips/iregdef.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/mips/iregdef.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/mips.h: rtems/score/mips.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/mips.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/mips.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
diff --git a/cpukit/score/cpu/mips/rtems/asm.h b/cpukit/score/cpu/mips/rtems/asm.h
new file mode 100644
index 0000000000..c20c663509
--- /dev/null
+++ b/cpukit/score/cpu/mips/rtems/asm.h
@@ -0,0 +1,158 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ */
+
+/*
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ * COPYRIGHT (c) 1994-1997.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * $Id$
+ */
+/* @(#)asm.h 03/15/96 1.1 */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/mips.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/*
+ * define macros for all of the registers on this CPU
+ *
+ * EXAMPLE: #define d0 REG (d0)
+ */
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA
+#define END_DATA
+#define BEGIN_BSS
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .globl SYM (sym)
+#define EXTERN(sym) .globl SYM (sym)
+
+/*
+ * Debugger macros for assembly language routines. Allows the
+ * programmer to set up the necessary stack frame info
+ * required by debuggers to do stack traces.
+ */
+
+#ifndef XDS
+#define FRAME(name,frm_reg,offset,ret_reg) \
+ .globl name; \
+ .ent name; \
+name:; \
+ .frame frm_reg,offset,ret_reg
+#define ENDFRAME(name) \
+ .end name
+#else
+#define FRAME(name,frm_reg,offset,ret_reg) \
+ .globl _##name;\
+_##name:
+#define ENDFRAME(name)
+#endif /* XDS */
+
+/*
+ * Hardware Floating Point Registers
+ */
+
+#define R_FP0 0
+#define R_FP1 1
+#define R_FP2 2
+#define R_FP3 3
+#define R_FP4 4
+#define R_FP5 5
+#define R_FP6 6
+#define R_FP7 7
+#define R_FP8 8
+#define R_FP9 9
+#define R_FP10 10
+#define R_FP11 11
+#define R_FP12 12
+#define R_FP13 13
+#define R_FP14 14
+#define R_FP15 15
+#define R_FP16 16
+#define R_FP17 17
+#define R_FP18 18
+#define R_FP19 19
+#define R_FP20 20
+#define R_FP21 21
+#define R_FP22 22
+#define R_FP23 23
+#define R_FP24 24
+#define R_FP25 25
+#define R_FP26 26
+#define R_FP27 27
+#define R_FP28 28
+#define R_FP29 29
+#define R_FP30 30
+#define R_FP31 31
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/score/cpu/mips/rtems/mips/idtcpu.h b/cpukit/score/cpu/mips/rtems/mips/idtcpu.h
new file mode 100644
index 0000000000..a35fc48a63
--- /dev/null
+++ b/cpukit/score/cpu/mips/rtems/mips/idtcpu.h
@@ -0,0 +1,695 @@
+/*
+
+Based upon IDT provided code with the following release:
+
+This source code has been made available to you by IDT on an AS-IS
+basis. Anyone receiving this source is licensed under IDT copyrights
+to use it in any way he or she deems fit, including copying it,
+modifying it, compiling it, and redistributing it either with or
+without modifications. No license under IDT patents or patent
+applications is to be implied by the copyright license.
+
+Any user of this software should understand that IDT cannot provide
+technical support for this software and will not be responsible for
+any consequences resulting from the use of this software.
+
+Any person who transfers this source code or any derivative work must
+include the IDT copyright notice, this paragraph, and the preceeding
+two paragraphs in the transferred software.
+
+COPYRIGHT IDT CORPORATION 1996
+LICENSED MATERIAL - PROGRAM PROPERTY OF IDT
+
+ $Id$
+*/
+
+/*
+** idtcpu.h -- cpu related defines
+*/
+
+#ifndef _RTEMS_MIPS_IDTCPU_H
+#define _RTEMS_MIPS_IDTCPU_H
+
+/*
+ * 950313: Ketan added Register definition for XContext reg.
+ * added define for WAIT instruction.
+ * 950421: Ketan added Register definition for Config reg (R3081)
+ */
+
+/*
+** memory configuration and mapping
+*/
+#define K0BASE 0x80000000
+#define K0SIZE 0x20000000
+#define K1BASE 0xa0000000
+#define K1SIZE 0x20000000
+#define K2BASE 0xc0000000
+#define K2SIZE 0x20000000
+#if __mips == 3
+#define KSBASE 0xe0000000
+#define KSSIZE 0x20000000
+#endif
+
+#define KUBASE 0
+#define KUSIZE 0x80000000
+
+/*
+** Exception Vectors
+*/
+#if __mips == 1
+#define UT_VEC K0BASE /* utlbmiss vector */
+#define DB_VEC (K0BASE+0x40) /* debug vector */
+#define E_VEC (K0BASE+0x80) /* exception vector */
+#elif __mips == 32
+#define T_VEC (K0BASE+0x000) /* tlbmiss vector */
+#define X_VEC (K0BASE+0x080) /* xtlbmiss vector */
+#define C_VEC (K0BASE+0x100) /* cache error vector */
+#define E_VEC (K0BASE+0x180) /* exception vector */
+#elif __mips == 3
+#define T_VEC (K0BASE+0x000) /* tlbmiss vector */
+#define X_VEC (K0BASE+0x080) /* xtlbmiss vector */
+#define C_VEC (K0BASE+0x100) /* cache error vector */
+#define E_VEC (K0BASE+0x180) /* exception vector */
+#else
+#error "EXCEPTION VECTORS: unknown ISA level"
+#endif
+#define R_VEC (K1BASE+0x1fc00000) /* reset vector */
+
+/*
+** Address conversion macros
+*/
+#ifdef CLANGUAGE
+#define CAST(as) (as)
+#else
+#define CAST(as)
+#endif
+#define K0_TO_K1(x) (CAST(unsigned)(x)|0xA0000000) /* kseg0 to kseg1 */
+#define K1_TO_K0(x) (CAST(unsigned)(x)&0x9FFFFFFF) /* kseg1 to kseg0 */
+#define K0_TO_PHYS(x) (CAST(unsigned)(x)&0x1FFFFFFF) /* kseg0 to physical */
+#define K1_TO_PHYS(x) (CAST(unsigned)(x)&0x1FFFFFFF) /* kseg1 to physical */
+#define PHYS_TO_K0(x) (CAST(unsigned)(x)|0x80000000) /* physical to kseg0 */
+#define PHYS_TO_K1(x) (CAST(unsigned)(x)|0xA0000000) /* physical to kseg1 */
+
+/*
+** Cache size constants
+*/
+#define MINCACHE 0x200 /* 512 For 3041. */
+#define MAXCACHE 0x40000 /* 256*1024 256k */
+
+#if __mips == 32
+/* R4000 configuration register definitions */
+#define CFG_CM 0x80000000 /* Master-Checker mode */
+#define CFG_ECMASK 0x70000000 /* System Clock Ratio */
+#define CFG_ECBY2 0x00000000 /* divide by 2 */
+#define CFG_ECBY3 0x10000000 /* divide by 3 */
+#define CFG_ECBY4 0x20000000 /* divide by 4 */
+#define CFG_EPMASK 0x0f000000 /* Transmit data pattern */
+#define CFG_EPD 0x00000000 /* D */
+#define CFG_EPDDX 0x01000000 /* DDX */
+#define CFG_EPDDXX 0x02000000 /* DDXX */
+#define CFG_EPDXDX 0x03000000 /* DXDX */
+#define CFG_EPDDXXX 0x04000000 /* DDXXX */
+#define CFG_EPDDXXXX 0x05000000 /* DDXXXX */
+#define CFG_EPDXXDXX 0x06000000 /* DXXDXX */
+#define CFG_EPDDXXXXX 0x07000000 /* DDXXXXX */
+#define CFG_EPDXXXDXXX 0x08000000 /* DXXXDXXX */
+#define CFG_SBMASK 0x00c00000 /* Secondary cache block size */
+#define CFG_SBSHIFT 22
+#define CFG_SB4 0x00000000 /* 4 words */
+#define CFG_SB8 0x00400000 /* 8 words */
+#define CFG_SB16 0x00800000 /* 16 words */
+#define CFG_SB32 0x00c00000 /* 32 words */
+#define CFG_SS 0x00200000 /* Split secondary cache */
+#define CFG_SW 0x00100000 /* Secondary cache port width */
+#define CFG_EWMASK 0x000c0000 /* System port width */
+#define CFG_EWSHIFT 18
+#define CFG_EW64 0x00000000 /* 64 bit */
+#define CFG_EW32 0x00010000 /* 32 bit */
+#define CFG_SC 0x00020000 /* Secondary cache absent */
+#define CFG_SM 0x00010000 /* Dirty Shared mode disabled */
+#define CFG_BE 0x00008000 /* Big Endian */
+#define CFG_EM 0x00004000 /* ECC mode enable */
+#define CFG_EB 0x00002000 /* Block ordering */
+#define CFG_ICMASK 0x00000e00 /* Instruction cache size */
+#define CFG_ICSHIFT 9
+#define CFG_DCMASK 0x000001c0 /* Data cache size */
+#define CFG_DCSHIFT 6
+#define CFG_IB 0x00000020 /* Instruction cache block size */
+#define CFG_DB 0x00000010 /* Data cache block size */
+#define CFG_CU 0x00000008 /* Update on Store Conditional */
+#define CFG_K0MASK 0x00000007 /* KSEG0 coherency algorithm */
+
+/*
+ * R4000 primary cache mode
+ */
+#define CFG_C_UNCACHED 2
+#define CFG_C_NONCOHERENT 3
+#define CFG_C_COHERENTXCL 4
+#define CFG_C_COHERENTXCLW 5
+#define CFG_C_COHERENTUPD 6
+
+/*
+ * R4000 cache operations (should be in assembler...?)
+ */
+#define Index_Invalidate_I 0x0 /* 0 0 */
+#define Index_Writeback_Inv_D 0x1 /* 0 1 */
+#define Index_Invalidate_SI 0x2 /* 0 2 */
+#define Index_Writeback_Inv_SD 0x3 /* 0 3 */
+#define Index_Load_Tag_I 0x4 /* 1 0 */
+#define Index_Load_Tag_D 0x5 /* 1 1 */
+#define Index_Load_Tag_SI 0x6 /* 1 2 */
+#define Index_Load_Tag_SD 0x7 /* 1 3 */
+#define Index_Store_Tag_I 0x8 /* 2 0 */
+#define Index_Store_Tag_D 0x9 /* 2 1 */
+#define Index_Store_Tag_SI 0xA /* 2 2 */
+#define Index_Store_Tag_SD 0xB /* 2 3 */
+#define Create_Dirty_Exc_D 0xD /* 3 1 */
+#define Create_Dirty_Exc_SD 0xF /* 3 3 */
+#define Hit_Invalidate_I 0x10 /* 4 0 */
+#define Hit_Invalidate_D 0x11 /* 4 1 */
+#define Hit_Invalidate_SI 0x12 /* 4 2 */
+#define Hit_Invalidate_SD 0x13 /* 4 3 */
+#define Hit_Writeback_Inv_D 0x15 /* 5 1 */
+#define Hit_Writeback_Inv_SD 0x17 /* 5 3 */
+#define Fill_I 0x14 /* 5 0 */
+#define Hit_Writeback_D 0x19 /* 6 1 */
+#define Hit_Writeback_SD 0x1B /* 6 3 */
+#define Hit_Writeback_I 0x18 /* 6 0 */
+#define Hit_Set_Virtual_SI 0x1E /* 7 2 */
+#define Hit_Set_Virtual_SD 0x1F /* 7 3 */
+
+#ifndef WAIT
+#define WAIT .word 0x42000020
+#endif /* WAIT */
+
+/* Disabled by joel -- horrible overload of common word.
+#ifndef wait
+#define wait .word 0x42000020
+#endif wait
+*/
+
+#endif
+
+#if __mips == 3
+/* R4000 configuration register definitions */
+#define CFG_CM 0x80000000 /* Master-Checker mode */
+#define CFG_ECMASK 0x70000000 /* System Clock Ratio */
+#define CFG_ECBY2 0x00000000 /* divide by 2 */
+#define CFG_ECBY3 0x10000000 /* divide by 3 */
+#define CFG_ECBY4 0x20000000 /* divide by 4 */
+#define CFG_EPMASK 0x0f000000 /* Transmit data pattern */
+#define CFG_EPD 0x00000000 /* D */
+#define CFG_EPDDX 0x01000000 /* DDX */
+#define CFG_EPDDXX 0x02000000 /* DDXX */
+#define CFG_EPDXDX 0x03000000 /* DXDX */
+#define CFG_EPDDXXX 0x04000000 /* DDXXX */
+#define CFG_EPDDXXXX 0x05000000 /* DDXXXX */
+#define CFG_EPDXXDXX 0x06000000 /* DXXDXX */
+#define CFG_EPDDXXXXX 0x07000000 /* DDXXXXX */
+#define CFG_EPDXXXDXXX 0x08000000 /* DXXXDXXX */
+#define CFG_SBMASK 0x00c00000 /* Secondary cache block size */
+#define CFG_SBSHIFT 22
+#define CFG_SB4 0x00000000 /* 4 words */
+#define CFG_SB8 0x00400000 /* 8 words */
+#define CFG_SB16 0x00800000 /* 16 words */
+#define CFG_SB32 0x00c00000 /* 32 words */
+#define CFG_SS 0x00200000 /* Split secondary cache */
+#define CFG_SW 0x00100000 /* Secondary cache port width */
+#define CFG_EWMASK 0x000c0000 /* System port width */
+#define CFG_EWSHIFT 18
+#define CFG_EW64 0x00000000 /* 64 bit */
+#define CFG_EW32 0x00010000 /* 32 bit */
+#define CFG_SC 0x00020000 /* Secondary cache absent */
+#define CFG_SM 0x00010000 /* Dirty Shared mode disabled */
+#define CFG_BE 0x00008000 /* Big Endian */
+#define CFG_EM 0x00004000 /* ECC mode enable */
+#define CFG_EB 0x00002000 /* Block ordering */
+#define CFG_ICMASK 0x00000e00 /* Instruction cache size */
+#define CFG_ICSHIFT 9
+#define CFG_DCMASK 0x000001c0 /* Data cache size */
+#define CFG_DCSHIFT 6
+#define CFG_IB 0x00000020 /* Instruction cache block size */
+#define CFG_DB 0x00000010 /* Data cache block size */
+#define CFG_CU 0x00000008 /* Update on Store Conditional */
+#define CFG_K0MASK 0x00000007 /* KSEG0 coherency algorithm */
+
+/*
+ * R4000 primary cache mode
+ */
+#define CFG_C_UNCACHED 2
+#define CFG_C_NONCOHERENT 3
+#define CFG_C_COHERENTXCL 4
+#define CFG_C_COHERENTXCLW 5
+#define CFG_C_COHERENTUPD 6
+
+/*
+ * R4000 cache operations (should be in assembler...?)
+ */
+#define Index_Invalidate_I 0x0 /* 0 0 */
+#define Index_Writeback_Inv_D 0x1 /* 0 1 */
+#define Index_Invalidate_SI 0x2 /* 0 2 */
+#define Index_Writeback_Inv_SD 0x3 /* 0 3 */
+#define Index_Load_Tag_I 0x4 /* 1 0 */
+#define Index_Load_Tag_D 0x5 /* 1 1 */
+#define Index_Load_Tag_SI 0x6 /* 1 2 */
+#define Index_Load_Tag_SD 0x7 /* 1 3 */
+#define Index_Store_Tag_I 0x8 /* 2 0 */
+#define Index_Store_Tag_D 0x9 /* 2 1 */
+#define Index_Store_Tag_SI 0xA /* 2 2 */
+#define Index_Store_Tag_SD 0xB /* 2 3 */
+#define Create_Dirty_Exc_D 0xD /* 3 1 */
+#define Create_Dirty_Exc_SD 0xF /* 3 3 */
+#define Hit_Invalidate_I 0x10 /* 4 0 */
+#define Hit_Invalidate_D 0x11 /* 4 1 */
+#define Hit_Invalidate_SI 0x12 /* 4 2 */
+#define Hit_Invalidate_SD 0x13 /* 4 3 */
+#define Hit_Writeback_Inv_D 0x15 /* 5 1 */
+#define Hit_Writeback_Inv_SD 0x17 /* 5 3 */
+#define Fill_I 0x14 /* 5 0 */
+#define Hit_Writeback_D 0x19 /* 6 1 */
+#define Hit_Writeback_SD 0x1B /* 6 3 */
+#define Hit_Writeback_I 0x18 /* 6 0 */
+#define Hit_Set_Virtual_SI 0x1E /* 7 2 */
+#define Hit_Set_Virtual_SD 0x1F /* 7 3 */
+
+#ifndef WAIT
+#define WAIT .word 0x42000020
+#endif /* WAIT */
+
+/* Disabled by joel -- horrible overload of common word.
+#ifndef wait
+#define wait .word 0x42000020
+#endif wait
+*/
+
+#endif
+
+/*
+** TLB resource defines
+*/
+#if __mips == 1
+#define N_TLB_ENTRIES 64
+#define TLB_PGSIZE 0x1000
+#define RANDBASE 8
+#define TLBLO_PFNMASK 0xfffff000
+#define TLBLO_PFNSHIFT 12
+#define TLBLO_N 0x800 /* non-cacheable */
+#define TLBLO_D 0x400 /* writeable */
+#define TLBLO_V 0x200 /* valid bit */
+#define TLBLO_G 0x100 /* global access bit */
+
+#define TLBHI_VPNMASK 0xfffff000
+#define TLBHI_VPNSHIFT 12
+#define TLBHI_PIDMASK 0xfc0
+#define TLBHI_PIDSHIFT 6
+#define TLBHI_NPID 64
+
+#define TLBINX_PROBE 0x80000000
+#define TLBINX_INXMASK 0x00003f00
+#define TLBINX_INXSHIFT 8
+
+#define TLBRAND_RANDMASK 0x00003f00
+#define TLBRAND_RANDSHIFT 8
+
+#define TLBCTXT_BASEMASK 0xffe00000
+#define TLBCTXT_BASESHIFT 21
+
+#define TLBCTXT_VPNMASK 0x001ffffc
+#define TLBCTXT_VPNSHIFT 2
+#endif
+#if __mips == 3
+#define N_TLB_ENTRIES 48
+
+#define TLBHI_VPN2MASK 0xffffe000
+#define TLBHI_PIDMASK 0x000000ff
+#define TLBHI_NPID 256
+
+#define TLBLO_PFNMASK 0x3fffffc0
+#define TLBLO_PFNSHIFT 6
+#define TLBLO_D 0x00000004 /* writeable */
+#define TLBLO_V 0x00000002 /* valid bit */
+#define TLBLO_G 0x00000001 /* global access bit */
+#define TLBLO_CMASK 0x00000038 /* cache algorithm mask */
+#define TLBLO_CSHIFT 3
+
+#define TLBLO_UNCACHED (CFG_C_UNCACHED<<TLBLO_CSHIFT)
+#define TLBLO_NONCOHERENT (CFG_C_NONCOHERENT<<TLBLO_CSHIFT)
+#define TLBLO_COHERENTXCL (CFG_C_COHERENTXCL<<TLBLO_CSHIFT)
+#define TLBLO_COHERENTXCLW (CFG_C_COHERENTXCLW<<TLBLO_CSHIFT)
+#define TLBLO_COHERENTUPD (CFG_C_COHERENTUPD<<TLBLO_CSHIFT)
+
+#define TLBINX_PROBE 0x80000000
+#define TLBINX_INXMASK 0x0000003f
+
+#define TLBRAND_RANDMASK 0x0000003f
+
+#define TLBCTXT_BASEMASK 0xff800000
+#define TLBCTXT_BASESHIFT 23
+
+#define TLBCTXT_VPN2MASK 0x007ffff0
+#define TLBCTXT_VPN2SHIFT 4
+
+#define TLBPGMASK_MASK 0x01ffe000
+#endif
+
+#if __mips == 32
+#define N_TLB_ENTRIES 16
+
+#define TLBHI_VPN2MASK 0xffffe000
+#define TLBHI_PIDMASK 0x000000ff
+#define TLBHI_NPID 256
+
+#define TLBLO_PFNMASK 0x3fffffc0
+#define TLBLO_PFNSHIFT 6
+#define TLBLO_D 0x00000004 /* writeable */
+#define TLBLO_V 0x00000002 /* valid bit */
+#define TLBLO_G 0x00000001 /* global access bit */
+#define TLBLO_CMASK 0x00000038 /* cache algorithm mask */
+#define TLBLO_CSHIFT 3
+
+#define TLBLO_UNCACHED (CFG_C_UNCACHED<<TLBLO_CSHIFT)
+#define TLBLO_NONCOHERENT (CFG_C_NONCOHERENT<<TLBLO_CSHIFT)
+#define TLBLO_COHERENTXCL (CFG_C_COHERENTXCL<<TLBLO_CSHIFT)
+#define TLBLO_COHERENTXCLW (CFG_C_COHERENTXCLW<<TLBLO_CSHIFT)
+#define TLBLO_COHERENTUPD (CFG_C_COHERENTUPD<<TLBLO_CSHIFT)
+
+#define TLBINX_PROBE 0x80000000
+#define TLBINX_INXMASK 0x0000003f
+
+#define TLBRAND_RANDMASK 0x0000003f
+
+#define TLBCTXT_BASEMASK 0xff800000
+#define TLBCTXT_BASESHIFT 23
+
+#define TLBCTXT_VPN2MASK 0x007ffff0
+#define TLBCTXT_VPN2SHIFT 4
+
+#define TLBPGMASK_MASK 0x01ffe000
+#endif
+
+#if __mips == 1
+
+
+/* definitions for Debug and Cache Invalidate control (DCIC) register bits */
+#define DCIC_TR 0x80000000 /* Trap enable */
+#define DCIC_UD 0x40000000 /* User debug enable */
+#define DCIC_KD 0x20000000 /* Kernel debug enable */
+#define DCIC_TE 0x10000000 /* Trace enable */
+#define DCIC_DW 0x08000000 /* Enable data breakpoints on write */
+#define DCIC_DR 0x04000000 /* Enable data breakpoints on read */
+#define DCIC_DAE 0x02000000 /* Enable data addresss breakpoints */
+#define DCIC_PCE 0x01000000 /* Enable instruction breakpoints */
+#define DCIC_DE 0x00800000 /* Debug enable */
+#define DCIC_DL 0x00008000 /* Data cache line invalidate */
+#define DCIC_IL 0x00004000 /* Instruction cache line invalidate */
+#define DCIC_D 0x00002000 /* Data cache invalidate enable */
+#define DCIC_I 0x00001000 /* Instr. cache invalidate enable */
+#define DCIC_T 0x00000020 /* Trace, set by CPU */
+#define DCIC_W 0x00000010 /* Write reference, set by CPU */
+#define DCIC_R 0x00000008 /* Read reference, set by CPU */
+#define DCIC_DA 0x00000004 /* Data address, set by CPU */
+#define DCIC_PC 0x00000002 /* Program counter, set by CPU */
+#define DCIC_DB 0x00000001 /* Debug, set by CPU */
+
+
+
+
+#define SR_CUMASK 0xf0000000 /* coproc usable bits */
+#define SR_CU3 0x80000000 /* Coprocessor 3 usable */
+#define SR_CU2 0x40000000 /* Coprocessor 2 usable */
+#define SR_CU1 0x20000000 /* Coprocessor 1 usable */
+#define SR_CU0 0x10000000 /* Coprocessor 0 usable */
+
+#define SR_BEV 0x00400000 /* use boot exception vectors */
+
+/* Cache control bits */
+#define SR_TS 0x00200000 /* TLB shutdown */
+#define SR_PE 0x00100000 /* cache parity error */
+#define SR_CM 0x00080000 /* cache miss */
+#define SR_PZ 0x00040000 /* cache parity zero */
+#define SR_SWC 0x00020000 /* swap cache */
+#define SR_ISC 0x00010000 /* Isolate data cache */
+
+/*
+** status register interrupt masks and bits
+*/
+
+#define SR_IMASK 0x0000ff00 /* Interrupt mask */
+#define SR_IMASK8 0x00000000 /* mask level 8 */
+#define SR_IMASK7 0x00008000 /* mask level 7 */
+#define SR_IMASK6 0x0000c000 /* mask level 6 */
+#define SR_IMASK5 0x0000e000 /* mask level 5 */
+#define SR_IMASK4 0x0000f000 /* mask level 4 */
+#define SR_IMASK3 0x0000f800 /* mask level 3 */
+#define SR_IMASK2 0x0000fc00 /* mask level 2 */
+#define SR_IMASK1 0x0000fe00 /* mask level 1 */
+#define SR_IMASK0 0x0000ff00 /* mask level 0 */
+
+#define SR_IMASKSHIFT 8
+
+#define SR_IBIT8 0x00008000 /* bit level 8 */
+#define SR_IBIT7 0x00004000 /* bit level 7 */
+#define SR_IBIT6 0x00002000 /* bit level 6 */
+#define SR_IBIT5 0x00001000 /* bit level 5 */
+#define SR_IBIT4 0x00000800 /* bit level 4 */
+#define SR_IBIT3 0x00000400 /* bit level 3 */
+#define SR_IBIT2 0x00000200 /* bit level 2 */
+#define SR_IBIT1 0x00000100 /* bit level 1 */
+
+#define SR_KUO 0x00000020 /* old kernel/user, 0 => k, 1 => u */
+#define SR_IEO 0x00000010 /* old interrupt enable, 1 => enable */
+#define SR_KUP 0x00000008 /* prev kernel/user, 0 => k, 1 => u */
+#define SR_IEP 0x00000004 /* prev interrupt enable, 1 => enable */
+#define SR_KUC 0x00000002 /* cur kernel/user, 0 => k, 1 => u */
+#define SR_IEC 0x00000001 /* cur interrupt enable, 1 => enable */
+#endif
+
+#if __mips == 3
+#define SR_CUMASK 0xf0000000 /* coproc usable bits */
+#define SR_CU3 0x80000000 /* Coprocessor 3 usable */
+#define SR_CU2 0x40000000 /* Coprocessor 2 usable */
+#define SR_CU1 0x20000000 /* Coprocessor 1 usable */
+#define SR_CU0 0x10000000 /* Coprocessor 0 usable */
+
+#define SR_RP 0x08000000 /* Reduced power operation */
+#define SR_FR 0x04000000 /* Additional floating point registers */
+#define SR_RE 0x02000000 /* Reverse endian in user mode */
+
+#define SR_BEV 0x00400000 /* Use boot exception vectors */
+#define SR_TS 0x00200000 /* TLB shutdown */
+#define SR_SR 0x00100000 /* Soft reset */
+#define SR_CH 0x00040000 /* Cache hit */
+#define SR_CE 0x00020000 /* Use cache ECC */
+#define SR_DE 0x00010000 /* Disable cache exceptions */
+
+/*
+** status register interrupt masks and bits
+*/
+
+#define SR_IMASK 0x0000ff00 /* Interrupt mask */
+#define SR_IMASK8 0x00000000 /* mask level 8 */
+#define SR_IMASK7 0x00008000 /* mask level 7 */
+#define SR_IMASK6 0x0000c000 /* mask level 6 */
+#define SR_IMASK5 0x0000e000 /* mask level 5 */
+#define SR_IMASK4 0x0000f000 /* mask level 4 */
+#define SR_IMASK3 0x0000f800 /* mask level 3 */
+#define SR_IMASK2 0x0000fc00 /* mask level 2 */
+#define SR_IMASK1 0x0000fe00 /* mask level 1 */
+#define SR_IMASK0 0x0000ff00 /* mask level 0 */
+
+#define SR_IMASKSHIFT 8
+
+#define SR_IBIT8 0x00008000 /* bit level 8 */
+#define SR_IBIT7 0x00004000 /* bit level 7 */
+#define SR_IBIT6 0x00002000 /* bit level 6 */
+#define SR_IBIT5 0x00001000 /* bit level 5 */
+#define SR_IBIT4 0x00000800 /* bit level 4 */
+#define SR_IBIT3 0x00000400 /* bit level 3 */
+#define SR_IBIT2 0x00000200 /* bit level 2 */
+#define SR_IBIT1 0x00000100 /* bit level 1 */
+
+#define SR_KSMASK 0x00000018 /* Kernel mode mask */
+#define SR_KSUSER 0x00000010 /* User mode */
+#define SR_KSSUPER 0x00000008 /* Supervisor mode */
+#define SR_KSKERNEL 0x00000000 /* Kernel mode */
+#define SR_ERL 0x00000004 /* Error level */
+#define SR_EXL 0x00000002 /* Exception level */
+#define SR_IE 0x00000001 /* Interrupts enabled */
+#endif
+
+#if __mips == 32
+#define SR_CUMASK 0xf0000000 /* coproc usable bits */
+#define SR_CU3 0x80000000 /* Coprocessor 3 usable */
+#define SR_CU2 0x40000000 /* Coprocessor 2 usable */
+#define SR_CU1 0x20000000 /* Coprocessor 1 usable */
+#define SR_CU0 0x10000000 /* Coprocessor 0 usable */
+
+#define SR_RP 0x08000000 /* Reduced power operation */
+#define SR_FR 0x04000000 /* Additional floating point registers */
+#define SR_RE 0x02000000 /* Reverse endian in user mode */
+
+#define SR_BEV 0x00400000 /* Use boot exception vectors */
+#define SR_TS 0x00200000 /* TLB shutdown */
+#define SR_SR 0x00100000 /* Soft reset */
+#define SR_CH 0x00040000 /* Cache hit */
+#define SR_CE 0x00020000 /* Use cache ECC */
+#define SR_DE 0x00010000 /* Disable cache exceptions */
+
+/*
+** status register interrupt masks and bits
+*/
+
+#define SR_IMASK 0x0000ff00 /* Interrupt mask */
+#define SR_IMASK8 0x00000000 /* mask level 8 */
+#define SR_IMASK7 0x00008000 /* mask level 7 */
+#define SR_IMASK6 0x0000c000 /* mask level 6 */
+#define SR_IMASK5 0x0000e000 /* mask level 5 */
+#define SR_IMASK4 0x0000f000 /* mask level 4 */
+#define SR_IMASK3 0x0000f800 /* mask level 3 */
+#define SR_IMASK2 0x0000fc00 /* mask level 2 */
+#define SR_IMASK1 0x0000fe00 /* mask level 1 */
+#define SR_IMASK0 0x0000ff00 /* mask level 0 */
+
+#define SR_IMASKSHIFT 8
+
+#define SR_IBIT8 0x00008000 /* bit level 8 */
+#define SR_IBIT7 0x00004000 /* bit level 7 */
+#define SR_IBIT6 0x00002000 /* bit level 6 */
+#define SR_IBIT5 0x00001000 /* bit level 5 */
+#define SR_IBIT4 0x00000800 /* bit level 4 */
+#define SR_IBIT3 0x00000400 /* bit level 3 */
+#define SR_IBIT2 0x00000200 /* bit level 2 */
+#define SR_IBIT1 0x00000100 /* bit level 1 */
+
+#define SR_KSMASK 0x00000018 /* Kernel mode mask */
+#define SR_KSUSER 0x00000010 /* User mode */
+#define SR_KSSUPER 0x00000008 /* Supervisor mode */
+#define SR_KSKERNEL 0x00000000 /* Kernel mode */
+#define SR_ERL 0x00000004 /* Error level */
+#define SR_EXL 0x00000002 /* Exception level */
+#define SR_IE 0x00000001 /* Interrupts enabled */
+#endif
+
+/*
+ * Cause Register
+ */
+#define CAUSE_BD 0x80000000 /* Branch delay slot */
+#define CAUSE_BT 0x40000000 /* Branch Taken */
+#define CAUSE_CEMASK 0x30000000 /* coprocessor error */
+#define CAUSE_CESHIFT 28
+
+
+#define CAUSE_IPMASK 0x0000FF00 /* Pending interrupt mask */
+#define CAUSE_IPSHIFT 8
+
+#define CAUSE_EXCMASK 0x0000003C /* Cause code bits */
+#define CAUSE_EXCSHIFT 2
+
+#ifndef XDS
+/*
+** Coprocessor 0 registers
+*/
+#define C0_INX $0 /* tlb index */
+#define C0_RAND $1 /* tlb random */
+#if __mips == 1
+#define C0_TLBLO $2 /* tlb entry low */
+#endif
+#if __mips == 3
+#define C0_TLBLO0 $2 /* tlb entry low 0 */
+#define C0_TLBLO1 $3 /* tlb entry low 1 */
+#endif
+
+#if __mips == 32
+#define C0_TLBLO0 $2 /* tlb entry low 0 */
+#define C0_TLBLO1 $3 /* tlb entry low 1 */
+#endif
+
+
+#define C0_CTXT $4 /* tlb context */
+
+#if __mips == 3
+#define C0_PAGEMASK $5 /* tlb page mask */
+#define C0_WIRED $6 /* number of wired tlb entries */
+#endif
+
+#if __mips == 32
+#define C0_PAGEMASK $5 /* tlb page mask */
+#define C0_WIRED $6 /* number of wired tlb entries */
+#endif
+
+#if __mips == 1
+#define C0_TAR $6
+#endif
+
+#define C0_BADVADDR $8 /* bad virtual address */
+
+#if __mips == 3
+#define C0_COUNT $9 /* cycle count */
+#endif
+#if __mips == 32
+#define C0_COUNT $9 /* cycle count */
+#endif
+
+#define C0_TLBHI $10 /* tlb entry hi */
+
+#if __mips == 3
+#define C0_COMPARE $11 /* cyccle count comparator */
+#endif
+
+#if __mips == 32
+#define C0_COMPARE $11 /* cyccle count comparator */
+#endif
+
+#define C0_SR $12 /* status register */
+#define C0_CAUSE $13 /* exception cause */
+#define C0_EPC $14 /* exception pc */
+#define C0_PRID $15 /* revision identifier */
+
+#if __mips == 1
+#define C0_CONFIG $3 /* configuration register R3081*/
+#endif
+
+#if __mips == 3
+#define C0_CONFIG $16 /* configuration register */
+#define C0_LLADDR $17 /* linked load address */
+#define C0_WATCHLO $18 /* watchpoint trap register */
+#define C0_WATCHHI $19 /* watchpoint trap register */
+#define C0_XCTXT $20 /* extended tlb context */
+#define C0_ECC $26 /* secondary cache ECC control */
+#define C0_CACHEERR $27 /* cache error status */
+#define C0_TAGLO $28 /* cache tag lo */
+#define C0_TAGHI $29 /* cache tag hi */
+#define C0_ERRPC $30 /* cache error pc */
+#endif
+
+#if __mips == 32
+#define C0_CONFIG $16 /* configuration register */
+#define C0_LLADDR $17 /* linked load address */
+#define C0_WATCHLO $18 /* watchpoint trap register */
+#define C0_WATCHHI $19 /* watchpoint trap register */
+#define C0_XCTXT $20 /* extended tlb context */
+#define C0_ECC $26 /* secondary cache ECC control */
+#define C0_CACHEERR $27 /* cache error status */
+#define C0_TAGLO $28 /* cache tag lo */
+#define C0_TAGHI $29 /* cache tag hi */
+#define C0_ERRPC $30 /* cache error pc */
+#endif
+
+
+#define C1_REVISION $0
+#define C1_STATUS $31
+
+#endif /* XDS */
+
+#ifdef R4650
+#define IWATCH $18
+#define DWATCH $19
+#define IBASE $0
+#define IBOUND $1
+#define DBASE $2
+#define DBOUND $3
+#define CALG $17
+#endif
+
+#endif /* _RTEMS_MIPS_IDTCPU_H */
+
diff --git a/cpukit/score/cpu/mips/rtems/mips/iregdef.h b/cpukit/score/cpu/mips/rtems/mips/iregdef.h
new file mode 100644
index 0000000000..4e35e6fdba
--- /dev/null
+++ b/cpukit/score/cpu/mips/rtems/mips/iregdef.h
@@ -0,0 +1,332 @@
+/*
+
+Based upon IDT provided code with the following release:
+
+This source code has been made available to you by IDT on an AS-IS
+basis. Anyone receiving this source is licensed under IDT copyrights
+to use it in any way he or she deems fit, including copying it,
+modifying it, compiling it, and redistributing it either with or
+without modifications. No license under IDT patents or patent
+applications is to be implied by the copyright license.
+
+Any user of this software should understand that IDT cannot provide
+technical support for this software and will not be responsible for
+any consequences resulting from the use of this software.
+
+Any person who transfers this source code or any derivative work must
+include the IDT copyright notice, this paragraph, and the preceeding
+two paragraphs in the transferred software.
+
+COPYRIGHT IDT CORPORATION 1996
+LICENSED MATERIAL - PROGRAM PROPERTY OF IDT
+
+ $Id$
+*/
+
+/*
+** iregdef.h - IDT R3000 register structure header file
+**
+** Copyright 1989 Integrated Device Technology, Inc
+** All Rights Reserved
+**
+*/
+#ifndef _RTEMS_MIPS_IREGDEF_H
+#define _RTEMS_MIPS_IREGDEF_H
+
+/*
+ * 950313: Ketan added sreg/lreg and R_SZ for 64-bit saves
+ * added Register definition for XContext reg.
+ * Look towards end of this file.
+ */
+/*
+** register names
+*/
+#define r0 $0
+#define r1 $1
+#define r2 $2
+#define r3 $3
+#define r4 $4
+#define r5 $5
+#define r6 $6
+#define r7 $7
+#define r8 $8
+#define r9 $9
+#define r10 $10
+#define r11 $11
+#define r12 $12
+#define r13 $13
+
+#define r14 $14
+#define r15 $15
+#define r16 $16
+#define r17 $17
+#define r18 $18
+#define r19 $19
+#define r20 $20
+#define r21 $21
+#define r22 $22
+#define r23 $23
+#define r24 $24
+#define r25 $25
+#define r26 $26
+#define r27 $27
+#define r28 $28
+#define r29 $29
+#define r30 $30
+#define r31 $31
+
+#define fp0 $f0
+#define fp1 $f1
+#define fp2 $f2
+#define fp3 $f3
+#define fp4 $f4
+#define fp5 $f5
+#define fp6 $f6
+#define fp7 $f7
+#define fp8 $f8
+#define fp9 $f9
+#define fp10 $f10
+#define fp11 $f11
+#define fp12 $f12
+#define fp13 $f13
+#define fp14 $f14
+#define fp15 $f15
+#define fp16 $f16
+#define fp17 $f17
+#define fp18 $f18
+#define fp19 $f19
+#define fp20 $f20
+#define fp21 $f21
+#define fp22 $f22
+#define fp23 $f23
+#define fp24 $f24
+#define fp25 $f25
+#define fp26 $f26
+#define fp27 $f27
+#define fp28 $f28
+#define fp29 $f29
+#define fp30 $f30
+#define fp31 $f31
+
+#define fcr0 $0
+#define fcr30 $30
+#define fcr31 $31
+
+#define zero $0 /* wired zero */
+#define AT $at /* assembler temp */
+#define v0 $2 /* return value */
+#define v1 $3
+#define a0 $4 /* argument registers a0-a3 */
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define t0 $8 /* caller saved t0-t9 */
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+#define s0 $16 /* callee saved s0-s8 */
+#define s1 $17
+#define s2 $18
+#define s3 $19
+#define s4 $20
+#define s5 $21
+#define s6 $22
+#define s7 $23
+#define t8 $24
+#define t9 $25
+#define k0 $26 /* kernel usage */
+#define k1 $27 /* kernel usage */
+#define gp $28 /* sdata pointer */
+#define sp $29 /* stack pointer */
+#define s8 $30 /* yet another saved reg for the callee */
+#define fp $30 /* frame pointer - this is being phased out by MIPS */
+#define ra $31 /* return address */
+
+
+/*
+** relative position of registers in interrupt/exception frame
+*/
+#define R_R0 0
+#define R_R1 1
+#define R_R2 2
+#define R_R3 3
+#define R_R4 4
+#define R_R5 5
+#define R_R6 6
+#define R_R7 7
+#define R_R8 8
+#define R_R9 9
+#define R_R10 10
+#define R_R11 11
+#define R_R12 12
+#define R_R13 13
+#define R_R14 14
+#define R_R15 15
+#define R_R16 16
+#define R_R17 17
+#define R_R18 18
+#define R_R19 19
+#define R_R20 20
+#define R_R21 21
+#define R_R22 22
+#define R_R23 23
+#define R_R24 24
+#define R_R25 25
+#define R_R26 26
+#define R_R27 27
+#define R_R28 28
+#define R_R29 29
+#define R_R30 30
+#define R_R31 31
+
+#define R_SR 32
+#define R_MDLO 33
+#define R_MDHI 34
+#define R_BADVADDR 35
+#define R_CAUSE 36
+#define R_EPC 37
+
+#define R_F0 38
+#define R_F1 39
+#define R_F2 40
+#define R_F3 41
+#define R_F4 42
+#define R_F5 43
+#define R_F6 44
+#define R_F7 45
+#define R_F8 46
+#define R_F9 47
+#define R_F10 48
+#define R_F11 49
+#define R_F12 50
+#define R_F13 41
+#define R_F14 42
+#define R_F15 43
+#define R_F16 44
+#define R_F17 45
+#define R_F18 56
+#define R_F19 57
+#define R_F20 58
+#define R_F21 59
+#define R_F22 60
+#define R_F23 61
+#define R_F24 62
+#define R_F25 63
+#define R_F26 64
+#define R_F27 65
+#define R_F28 66
+#define R_F29 67
+#define R_F30 68
+#define R_F31 69
+#define R_FCSR 70
+#define R_FEIR 71
+#define R_TLBHI 72
+
+#if __mips == 1
+#define R_TLBLO 73
+#endif
+#if (__mips == 3 ) || ( __mips == 32)
+#define R_TLBLO0 73
+#endif
+
+#define R_INX 74
+#define R_RAND 75
+#define R_CTXT 76
+#define R_EXCTYPE 77
+#define R_MODE 78
+#define R_PRID 79
+#define R_TAR 80
+#if __mips == 1
+#define NREGS 81
+#endif
+#if (__mips == 3 ) || ( __mips == 32)
+#define R_TLBLO1 81
+#define R_PAGEMASK 82
+#define R_WIRED 83
+#define R_COUNT 84
+#define R_COMPARE 85
+#define R_CONFIG 86
+#define R_LLADDR 87
+#define R_WATCHLO 88
+#define R_WATCHHI 89
+#define R_ECC 90
+#define R_CACHEERR 91
+#define R_TAGLO 92
+#define R_TAGHI 93
+#define R_ERRPC 94
+#define R_XCTXT 95 /* Ketan added from SIM64bit */
+
+#define NREGS 96
+#endif
+
+/*
+** For those who like to think in terms of the compiler names for the regs
+*/
+#define R_ZERO R_R0
+#define R_AT R_R1
+#define R_V0 R_R2
+#define R_V1 R_R3
+#define R_A0 R_R4
+#define R_A1 R_R5
+#define R_A2 R_R6
+#define R_A3 R_R7
+#define R_T0 R_R8
+#define R_T1 R_R9
+#define R_T2 R_R10
+#define R_T3 R_R11
+#define R_T4 R_R12
+#define R_T5 R_R13
+#define R_T6 R_R14
+#define R_T7 R_R15
+#define R_S0 R_R16
+#define R_S1 R_R17
+#define R_S2 R_R18
+#define R_S3 R_R19
+#define R_S4 R_R20
+#define R_S5 R_R21
+#define R_S6 R_R22
+#define R_S7 R_R23
+#define R_T8 R_R24
+#define R_T9 R_R25
+#define R_K0 R_R26
+#define R_K1 R_R27
+#define R_GP R_R28
+#define R_SP R_R29
+#define R_FP R_R30
+#define R_RA R_R31
+
+/* disabled for RTEMS */
+#if 0
+/* Ketan added the following */
+#if __mips == 1
+#define sreg sw
+#define lreg lw
+#define rmfc0 mfc0
+#define rmtc0 mtc0
+#define R_SZ 4
+#endif /* __mips == 1 */
+
+/* #ifdef __mips == 3 */
+#if __mips < 3
+#define sreg sw
+#define lreg lw
+#define rmfc0 mfc0
+#define rmtc0 mtc0
+#define R_SZ 4
+#else
+#define sreg sd
+#define lreg ld
+#define rmfc0 dmfc0
+#define rmtc0 dmtc0
+#define R_SZ 8
+#endif
+/* #endif __mips == 3 */
+/* Ketan till here */
+#endif
+
+#endif /* _RTEMS_MIPS_IREGDEF_H */
+
diff --git a/cpukit/score/cpu/mips/rtems/score/cpu.h b/cpukit/score/cpu/mips/rtems/score/cpu.h
new file mode 100644
index 0000000000..417738c189
--- /dev/null
+++ b/cpukit/score/cpu/mips/rtems/score/cpu.h
@@ -0,0 +1,1229 @@
+/*
+ * Mips CPU Dependent Header File
+ *
+ * Conversion to MIPS port by Alan Cudmore <alanc@linuxstart.com> and
+ * Joel Sherrill <joel@OARcorp.com>.
+ *
+ * These changes made the code conditional on standard cpp predefines,
+ * merged the mips1 and mips3 code sequences as much as possible,
+ * and moved some of the assembly code to C. Alan did much of the
+ * initial analysis and rework. Joel took over from there and
+ * wrote the JMR3904 BSP so this could be tested. Joel also
+ * added the new interrupt vectoring support in libcpu and
+ * tried to better support the various interrupt controllers.
+ *
+ * Original MIP64ORION port by Craig Lebakken <craigl@transition.com>
+ * COPYRIGHT (c) 1996 by Transition Networks Inc.
+ *
+ * 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 Transition Networks not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * Transition Networks makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/mips.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+
+/* conditional compilation parameters */
+
+/*
+ * Should the calls to _Thread_Enable_dispatch be inlined?
+ *
+ * If TRUE, then they are inlined.
+ * If FALSE, then a subroutine call is made.
+ *
+ * Basically this is an example of the classic trade-off of size
+ * versus speed. Inlining the call (TRUE) typically increases the
+ * size of RTEMS while speeding up the enabling of dispatching.
+ * [NOTE: In general, the _Thread_Dispatch_disable_level will
+ * only be 0 or 1 unless you are in an interrupt handler and that
+ * interrupt handler invokes the executive.] When not inlined
+ * something calls _Thread_Enable_dispatch which in turns calls
+ * _Thread_Dispatch. If the enable dispatch is inlined, then
+ * one subroutine call is avoided entirely.]
+ */
+
+#define CPU_INLINE_ENABLE_DISPATCH FALSE
+
+/*
+ * Should the body of the search loops in _Thread_queue_Enqueue_priority
+ * be unrolled one time? In unrolled each iteration of the loop examines
+ * two "nodes" on the chain being searched. Otherwise, only one node
+ * is examined per iteration.
+ *
+ * If TRUE, then the loops are unrolled.
+ * If FALSE, then the loops are not unrolled.
+ *
+ * The primary factor in making this decision is the cost of disabling
+ * and enabling interrupts (_ISR_Flash) versus the cost of rest of the
+ * body of the loop. On some CPUs, the flash is more expensive than
+ * one iteration of the loop body. In this case, it might be desirable
+ * to unroll the loop. It is important to note that on some CPUs, this
+ * code is the longest interrupt disable period in RTEMS. So it is
+ * necessary to strike a balance when setting this parameter.
+ */
+
+#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
+
+/*
+ * Does RTEMS manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in _Interrupt_Manager_initialization.
+ * If FALSE, nothing is done.
+ *
+ * If the CPU supports a dedicated interrupt stack in hardware,
+ * then it is generally the responsibility of the BSP to allocate it
+ * and set it up.
+ *
+ * If the CPU does not support a dedicated interrupt stack, then
+ * the porter has two options: (1) execute interrupts on the
+ * stack of the interrupted task, and (2) have RTEMS manage a dedicated
+ * interrupt stack.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
+
+/*
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * If TRUE, then it must be installed during initialization.
+ * If FALSE, then no installation is performed.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ */
+
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
+
+/*
+ * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * If TRUE, then the memory is allocated during initialization.
+ * If FALSE, then the memory is allocated during initialization.
+ *
+ * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
+ */
+
+#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
+
+/*
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ *
+ */
+
+#define CPU_ISR_PASSES_FRAME_POINTER 1
+
+
+
+/*
+ * Does the CPU have hardware floating point?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
+ *
+ * If there is a FP coprocessor such as the i387 or mc68881, then
+ * the answer is TRUE.
+ *
+ * The macro name "MIPS_HAS_FPU" should be made CPU specific.
+ * It indicates whether or not this CPU model has FP support. For
+ * example, it would be possible to have an i386_nofp CPU model
+ * which set this to false to indicate that you have an i386 without
+ * an i387 and wish to leave floating point support out of RTEMS.
+ */
+
+#if ( MIPS_HAS_FPU == 1 )
+#define CPU_HARDWARE_FP TRUE
+#else
+#define CPU_HARDWARE_FP FALSE
+#endif
+
+/*
+ * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
+ *
+ * So far, the only CPU in which this option has been used is the
+ * HP PA-RISC. The HP C compiler and gcc both implicitly use the
+ * floating point registers to perform integer multiplies. If
+ * a function which you would not think utilize the FP unit DOES,
+ * then one can not easily predict which tasks will use the FP hardware.
+ * In this case, this option should be TRUE.
+ *
+ * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
+ */
+
+#define CPU_ALL_TASKS_ARE_FP FALSE
+
+/*
+ * Should the IDLE task have a floating point context?
+ *
+ * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * If FALSE, then the IDLE task does not have a floating point context.
+ *
+ * Setting this to TRUE negatively impacts the time required to preempt
+ * the IDLE task from an interrupt because the floating point context
+ * must be saved as part of the preemption.
+ */
+
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+/*
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ *
+ * If the floating point context does NOT have to be saved as part of
+ * interrupt dispatching, then it should be safe to set this to TRUE.
+ *
+ * Setting this flag to TRUE results in using a different algorithm
+ * for deciding when to save and restore the floating point context.
+ * The deferred FP switch algorithm minimizes the number of times
+ * the FP context is saved and restored. The FP context is not saved
+ * until a context switch is made to another, different FP task.
+ * Thus in a system with only one FP task, the FP context will never
+ * be saved or restored.
+ */
+
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+/*
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine _CPU_Internal_threads_Idle_thread_body
+ * must be provided and is the default IDLE thread body instead of
+ * _Internal_threads_Idle_thread_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ *
+ * This is intended to allow for supporting processors which have
+ * a low power or idle mode. When the IDLE thread is executed, then
+ * the CPU can be powered down.
+ *
+ * The order of precedence for selecting the IDLE thread body is:
+ *
+ * 1. BSP provided
+ * 2. CPU dependent (if provided)
+ * 3. generic (if no BSP and no CPU dependent)
+ */
+
+/* we can use the low power wait instruction for the IDLE thread */
+#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE
+
+/*
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * If TRUE, then the grows upward.
+ * If FALSE, then the grows toward smaller addresses.
+ */
+
+/* our stack grows down */
+#define CPU_STACK_GROWS_UP FALSE
+
+/*
+ * The following is the variable attribute used to force alignment
+ * of critical RTEMS structures. On some processors it may make
+ * sense to have these aligned on tighter boundaries than
+ * the minimum requirements of the compiler in order to have as
+ * much of the critical data area as possible in a cache line.
+ *
+ * The placement of this macro in the declaration of the variables
+ * is based on the syntactically requirements of the GNU C
+ * "__attribute__" extension. For example with GNU C, use
+ * the following to force a structures to a 32 byte boundary.
+ *
+ * __attribute__ ((aligned (32)))
+ *
+ * NOTE: Currently only the Priority Bit Map table uses this feature.
+ * To benefit from using this, the data must be heavily
+ * used so it will stay in the cache and used frequently enough
+ * in the executive to justify turning this on.
+ */
+
+/* our cache line size is 16 bytes */
+#if __GNUC__
+#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned (16)))
+#else
+#define CPU_STRUCTURE_ALIGNMENT
+#endif
+
+/*
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ */
+
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+
+/* __MIPSEB__ or __MIPSEL__ is defined by GCC based on -EB or -EL command line options */
+#if defined(__MIPSEB__)
+#define CPU_BIG_ENDIAN TRUE
+#define CPU_LITTLE_ENDIAN FALSE
+#elif defined(__MIPSEL__)
+#define CPU_BIG_ENDIAN FALSE
+#define CPU_LITTLE_ENDIAN TRUE
+#else
+#error "Unknown endianness"
+#endif
+
+/*
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
+ */
+
+#define CPU_MODES_INTERRUPT_MASK 0x000000ff
+
+/*
+ * Processor defined structures
+ *
+ * Examples structures include the descriptor tables from the i386
+ * and the processor control structure on the i960ca.
+ */
+
+/* may need to put some structures here. */
+
+/*
+ * Contexts
+ *
+ * Generally there are 2 types of context to save.
+ * 1. Interrupt registers to save
+ * 2. Task level registers to save
+ *
+ * This means we have the following 3 context items:
+ * 1. task level context stuff:: Context_Control
+ * 2. floating point task stuff:: Context_Control_fp
+ * 3. special interrupt level context :: Context_Control_interrupt
+ *
+ * On some processors, it is cost-effective to save only the callee
+ * preserved registers during a task context switch. This means
+ * that the ISR code needs to save those registers which do not
+ * persist across function calls. It is not mandatory to make this
+ * distinctions between the caller/callee saves registers for the
+ * purpose of minimizing context saved during task switch and on interrupts.
+ * If the cost of saving extra registers is minimal, simplicity is the
+ * choice. Save the same context on interrupt entry as for tasks in
+ * this case.
+ *
+ * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
+ * care should be used in designing the context area.
+ *
+ * On some CPUs with hardware floating point support, the Context_Control_fp
+ * structure will not be used or it simply consist of an array of a
+ * fixed number of bytes. This is done when the floating point context
+ * is dumped by a "FP save context" type instruction and the format
+ * is not really defined by the CPU. In this case, there is no need
+ * to figure out the exact format -- only the size. Of course, although
+ * this is enough information for RTEMS, it is probably not enough for
+ * a debugger such as gdb. But that is another problem.
+ */
+
+#ifndef ASSEMBLY_ONLY
+
+/* WARNING: If this structure is modified, the constants in cpu.h must be updated. */
+#if (__mips == 1) || (__mips == 32)
+#define __MIPS_REGISTER_TYPE uint32_t
+#define __MIPS_FPU_REGISTER_TYPE uint32_t
+#elif __mips == 3
+#define __MIPS_REGISTER_TYPE uint64_t
+#define __MIPS_FPU_REGISTER_TYPE uint64_t
+#else
+#error "mips register size: unknown architecture level!!"
+#endif
+typedef struct {
+ __MIPS_REGISTER_TYPE s0;
+ __MIPS_REGISTER_TYPE s1;
+ __MIPS_REGISTER_TYPE s2;
+ __MIPS_REGISTER_TYPE s3;
+ __MIPS_REGISTER_TYPE s4;
+ __MIPS_REGISTER_TYPE s5;
+ __MIPS_REGISTER_TYPE s6;
+ __MIPS_REGISTER_TYPE s7;
+ __MIPS_REGISTER_TYPE sp;
+ __MIPS_REGISTER_TYPE fp;
+ __MIPS_REGISTER_TYPE ra;
+ __MIPS_REGISTER_TYPE c0_sr;
+ __MIPS_REGISTER_TYPE c0_epc;
+} Context_Control;
+
+/* WARNING: If this structure is modified, the constants in cpu.h
+ * must also be updated.
+ */
+
+typedef struct {
+#if ( CPU_HARDWARE_FP == TRUE )
+ __MIPS_FPU_REGISTER_TYPE fp0;
+ __MIPS_FPU_REGISTER_TYPE fp1;
+ __MIPS_FPU_REGISTER_TYPE fp2;
+ __MIPS_FPU_REGISTER_TYPE fp3;
+ __MIPS_FPU_REGISTER_TYPE fp4;
+ __MIPS_FPU_REGISTER_TYPE fp5;
+ __MIPS_FPU_REGISTER_TYPE fp6;
+ __MIPS_FPU_REGISTER_TYPE fp7;
+ __MIPS_FPU_REGISTER_TYPE fp8;
+ __MIPS_FPU_REGISTER_TYPE fp9;
+ __MIPS_FPU_REGISTER_TYPE fp10;
+ __MIPS_FPU_REGISTER_TYPE fp11;
+ __MIPS_FPU_REGISTER_TYPE fp12;
+ __MIPS_FPU_REGISTER_TYPE fp13;
+ __MIPS_FPU_REGISTER_TYPE fp14;
+ __MIPS_FPU_REGISTER_TYPE fp15;
+ __MIPS_FPU_REGISTER_TYPE fp16;
+ __MIPS_FPU_REGISTER_TYPE fp17;
+ __MIPS_FPU_REGISTER_TYPE fp18;
+ __MIPS_FPU_REGISTER_TYPE fp19;
+ __MIPS_FPU_REGISTER_TYPE fp20;
+ __MIPS_FPU_REGISTER_TYPE fp21;
+ __MIPS_FPU_REGISTER_TYPE fp22;
+ __MIPS_FPU_REGISTER_TYPE fp23;
+ __MIPS_FPU_REGISTER_TYPE fp24;
+ __MIPS_FPU_REGISTER_TYPE fp25;
+ __MIPS_FPU_REGISTER_TYPE fp26;
+ __MIPS_FPU_REGISTER_TYPE fp27;
+ __MIPS_FPU_REGISTER_TYPE fp28;
+ __MIPS_FPU_REGISTER_TYPE fp29;
+ __MIPS_FPU_REGISTER_TYPE fp30;
+ __MIPS_FPU_REGISTER_TYPE fp31;
+ uint32_t fpcs;
+#endif
+} Context_Control_fp;
+
+/*
+ * This struct reflects the stack frame employed in ISR_Handler. Note
+ * that the ISR routine save some of the registers to this frame for
+ * all interrupts and exceptions. Other registers are saved only on
+ * exceptions, while others are not touched at all. The untouched
+ * registers are not normally disturbed by high-level language
+ * programs so they can be accessed when required.
+ *
+ * The registers and their ordering in this struct must directly
+ * correspond to the layout and ordering of * shown in iregdef.h,
+ * as cpu_asm.S uses those definitions to fill the stack frame.
+ * This struct provides access to the stack frame for C code.
+ *
+ * Similarly, this structure is used by debugger stubs and exception
+ * processing routines so be careful when changing the format.
+ *
+ * NOTE: The comments with this structure and cpu_asm.S should be kept
+ * in sync. When in doubt, look in the code to see if the
+ * registers you're interested in are actually treated as expected.
+ * The order of the first portion of this structure follows the
+ * order of registers expected by gdb.
+ */
+
+typedef struct
+{
+ __MIPS_REGISTER_TYPE r0; /* 0 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE at; /* 1 -- saved always */
+ __MIPS_REGISTER_TYPE v0; /* 2 -- saved always */
+ __MIPS_REGISTER_TYPE v1; /* 3 -- saved always */
+ __MIPS_REGISTER_TYPE a0; /* 4 -- saved always */
+ __MIPS_REGISTER_TYPE a1; /* 5 -- saved always */
+ __MIPS_REGISTER_TYPE a2; /* 6 -- saved always */
+ __MIPS_REGISTER_TYPE a3; /* 7 -- saved always */
+ __MIPS_REGISTER_TYPE t0; /* 8 -- saved always */
+ __MIPS_REGISTER_TYPE t1; /* 9 -- saved always */
+ __MIPS_REGISTER_TYPE t2; /* 10 -- saved always */
+ __MIPS_REGISTER_TYPE t3; /* 11 -- saved always */
+ __MIPS_REGISTER_TYPE t4; /* 12 -- saved always */
+ __MIPS_REGISTER_TYPE t5; /* 13 -- saved always */
+ __MIPS_REGISTER_TYPE t6; /* 14 -- saved always */
+ __MIPS_REGISTER_TYPE t7; /* 15 -- saved always */
+ __MIPS_REGISTER_TYPE s0; /* 16 -- saved on exceptions */
+ __MIPS_REGISTER_TYPE s1; /* 17 -- saved on exceptions */
+ __MIPS_REGISTER_TYPE s2; /* 18 -- saved on exceptions */
+ __MIPS_REGISTER_TYPE s3; /* 19 -- saved on exceptions */
+ __MIPS_REGISTER_TYPE s4; /* 20 -- saved on exceptions */
+ __MIPS_REGISTER_TYPE s5; /* 21 -- saved on exceptions */
+ __MIPS_REGISTER_TYPE s6; /* 22 -- saved on exceptions */
+ __MIPS_REGISTER_TYPE s7; /* 23 -- saved on exceptions */
+ __MIPS_REGISTER_TYPE t8; /* 24 -- saved always */
+ __MIPS_REGISTER_TYPE t9; /* 25 -- saved always */
+ __MIPS_REGISTER_TYPE k0; /* 26 -- NOT FILLED IN, kernel tmp reg */
+ __MIPS_REGISTER_TYPE k1; /* 27 -- NOT FILLED IN, kernel tmp reg */
+ __MIPS_REGISTER_TYPE gp; /* 28 -- saved always */
+ __MIPS_REGISTER_TYPE sp; /* 29 -- saved on exceptions NOT RESTORED */
+ __MIPS_REGISTER_TYPE fp; /* 30 -- saved always */
+ __MIPS_REGISTER_TYPE ra; /* 31 -- saved always */
+ __MIPS_REGISTER_TYPE c0_sr; /* 32 -- saved always, some bits are */
+ /* manipulated per-thread */
+ __MIPS_REGISTER_TYPE mdlo; /* 33 -- saved always */
+ __MIPS_REGISTER_TYPE mdhi; /* 34 -- saved always */
+ __MIPS_REGISTER_TYPE badvaddr; /* 35 -- saved on exceptions, read-only */
+ __MIPS_REGISTER_TYPE cause; /* 36 -- saved on exceptions NOT restored */
+ __MIPS_REGISTER_TYPE epc; /* 37 -- saved always, read-only register */
+ /* but logically restored */
+ __MIPS_FPU_REGISTER_TYPE f0; /* 38 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f1; /* 39 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f2; /* 40 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f3; /* 41 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f4; /* 42 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f5; /* 43 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f6; /* 44 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f7; /* 45 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f8; /* 46 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f9; /* 47 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f10; /* 48 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f11; /* 49 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f12; /* 50 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f13; /* 51 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f14; /* 52 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f15; /* 53 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f16; /* 54 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f17; /* 55 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f18; /* 56 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f19; /* 57 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f20; /* 58 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f21; /* 59 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f22; /* 60 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f23; /* 61 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f24; /* 62 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f25; /* 63 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f26; /* 64 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f27; /* 65 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f28; /* 66 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f29; /* 67 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f30; /* 68 -- saved if FP enabled */
+ __MIPS_FPU_REGISTER_TYPE f31; /* 69 -- saved if FP enabled */
+ __MIPS_REGISTER_TYPE fcsr; /* 70 -- saved on exceptions */
+ /* (oddly not documented on MGV) */
+ __MIPS_REGISTER_TYPE feir; /* 71 -- saved on exceptions */
+ /* (oddly not documented on MGV) */
+
+ /* GDB does not seem to care about anything past this point */
+
+ __MIPS_REGISTER_TYPE tlbhi; /* 72 - NOT FILLED IN, doesn't exist on */
+ /* all MIPS CPUs (at least MGV) */
+#if __mips == 1
+ __MIPS_REGISTER_TYPE tlblo; /* 73 - NOT FILLED IN, doesn't exist on */
+ /* all MIPS CPUs (at least MGV) */
+#endif
+#if (__mips == 3) || (__mips == 32)
+ __MIPS_REGISTER_TYPE tlblo0; /* 73 - NOT FILLED IN, doesn't exist on */
+ /* all MIPS CPUs (at least MGV) */
+#endif
+
+ __MIPS_REGISTER_TYPE inx; /* 74 -- NOT FILLED IN, doesn't exist on */
+ /* all MIPS CPUs (at least MGV) */
+ __MIPS_REGISTER_TYPE rand; /* 75 -- NOT FILLED IN, doesn't exist on */
+ /* all MIPS CPUs (at least MGV) */
+ __MIPS_REGISTER_TYPE ctxt; /* 76 -- NOT FILLED IN, doesn't exist on */
+ /* all MIPS CPUs (at least MGV) */
+ __MIPS_REGISTER_TYPE exctype; /* 77 -- NOT FILLED IN (not enough info) */
+ __MIPS_REGISTER_TYPE mode; /* 78 -- NOT FILLED IN (not enough info) */
+ __MIPS_REGISTER_TYPE prid; /* 79 -- NOT FILLED IN (not need to do so) */
+ __MIPS_REGISTER_TYPE tar ; /* 80 -- target address register, filled on exceptions */
+ /* end of __mips == 1 so NREGS == 81 */
+#if (__mips == 3) || (__mips == 32)
+ __MIPS_REGISTER_TYPE tlblo1; /* 81 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE pagemask; /* 82 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE wired; /* 83 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE count; /* 84 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE compare; /* 85 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE config; /* 86 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE lladdr; /* 87 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE watchlo; /* 88 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE watchhi; /* 89 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE ecc; /* 90 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE cacheerr; /* 91 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE taglo; /* 92 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE taghi; /* 93 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE errpc; /* 94 -- NOT FILLED IN */
+ __MIPS_REGISTER_TYPE xctxt; /* 95 -- NOT FILLED IN */
+ /* end of __mips == 3 so NREGS == 96 */
+#endif
+
+} CPU_Interrupt_frame;
+
+
+/*
+ * The following table contains the information required to configure
+ * the mips processor specific parameters.
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+ /* end of fields required on all CPUs */
+
+ uint32_t clicks_per_microsecond;
+} rtems_cpu_table;
+
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ */
+
+/*
+ * Macros to access MIPS specific additions to the CPU Table
+ */
+
+#define rtems_cpu_configuration_get_clicks_per_microsecond() \
+ (_CPU_Table.clicks_per_microsecond)
+
+/*
+ * This variable is optional. It is used on CPUs on which it is difficult
+ * to generate an "uninitialized" FP context. It is filled in by
+ * _CPU_Initialize and copied into the task's FP context area during
+ * _CPU_Context_Initialize.
+ */
+
+SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
+
+/*
+ * On some CPUs, RTEMS supports a software managed interrupt stack.
+ * This stack is allocated by the Interrupt Manager and the switch
+ * is performed in _ISR_Handler. These variables contain pointers
+ * to the lowest and highest addresses in the chunk of memory allocated
+ * for the interrupt stack. Since it is unknown whether the stack
+ * grows up or down (in general), this give the CPU dependent
+ * code the option of picking the version it wants to use.
+ *
+ * NOTE: These two variables are required if the macro
+ * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
+ */
+
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+/*
+ * With some compilation systems, it is difficult if not impossible to
+ * call a high-level language routine from assembly language. This
+ * is especially true of commercial Ada compilers and name mangling
+ * C++ ones. This variable can be optionally defined by the CPU porter
+ * and contains the address of the routine _Thread_Dispatch. This
+ * can make it easier to invoke that routine at the end of the interrupt
+ * sequence (if a dispatch is necessary).
+ *
+
+SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
+ *
+ * NOTE: Not needed on this port.
+ */
+
+
+
+/*
+ * Nothing prevents the porter from declaring more CPU specific variables.
+ */
+
+/* XXX: if needed, put more variables here */
+
+/*
+ * The size of the floating point context area. On some CPUs this
+ * will not be a "sizeof" because the format of the floating point
+ * area is not defined -- only the size is. This is usually on
+ * CPUs with a "floating point save context" instruction.
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/*
+ * Amount of extra stack (above minimum stack size) required by
+ * system initialization thread. Remember that in a multiprocessor
+ * system the system intialization thread becomes the MP server thread.
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+/*
+ * This defines the number of entries in the ISR_Vector_table managed
+ * by RTEMS.
+ */
+
+extern unsigned int mips_interrupt_number_of_vectors;
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS (mips_interrupt_number_of_vectors)
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
+
+/*
+ * Should be large enough to run all RTEMS tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ */
+
+#define CPU_STACK_MINIMUM_SIZE (2048*sizeof(uint32_t))
+
+
+/*
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ */
+
+#define CPU_ALIGNMENT 8
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
+ * then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
+ * enough for the partition, then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * stack. This alignment requirement may be stricter than that for the
+ * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
+ * is strict enough for the stack, then this should be set to 0.
+ *
+ * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
+ */
+
+#define CPU_STACK_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * ISR handler macros
+ */
+
+/*
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ */
+
+#define _CPU_Initialize_vectors()
+
+/*
+ * Declare the function that is present in the shared libcpu directory,
+ * that returns the processor dependent interrupt mask.
+ */
+
+uint32_t mips_interrupt_mask( void );
+
+/*
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in _level.
+ */
+
+#define _CPU_ISR_Disable( _level ) \
+ do { \
+ unsigned int _scratch; \
+ mips_get_sr( _scratch ); \
+ mips_set_sr( _scratch & ~SR_INTERRUPT_ENABLE_BITS ); \
+ _level = _scratch & SR_INTERRUPT_ENABLE_BITS; \
+ } while(0)
+
+/*
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * _level is not modified.
+ */
+
+#define _CPU_ISR_Enable( _level ) \
+ do { \
+ unsigned int _scratch; \
+ mips_get_sr( _scratch ); \
+ mips_set_sr( (_scratch & ~SR_INTERRUPT_ENABLE_BITS) | (_level & SR_INTERRUPT_ENABLE_BITS) ); \
+ } while(0)
+
+/*
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ */
+
+#define _CPU_ISR_Flash( _xlevel ) \
+ do { \
+ unsigned int _scratch2 = _xlevel; \
+ _CPU_ISR_Enable( _scratch2 ); \
+ _CPU_ISR_Disable( _scratch2 ); \
+ _xlevel = _scratch2; \
+ } while(0)
+
+/*
+ * Map interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a generic fashion are undefined. Someday,
+ * it would be nice if these were "mapped" by the application
+ * via a callout. For example, m68k has 8 levels 0 - 7, levels
+ * 8 - 255 would be available for bsp/application specific meaning.
+ * This could be used to manage a programmable interrupt controller
+ * via the rtems_task_mode directive.
+ *
+ * On the MIPS, 0 is all on. Non-zero is all off. This only
+ * manipulates the IEC.
+ */
+
+uint32_t _CPU_ISR_Get_level( void ); /* in cpu.c */
+
+void _CPU_ISR_Set_level( uint32_t ); /* in cpu.c */
+
+/* end of ISR handler macros */
+
+/* Context handler macros */
+
+/*
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * This routine generally does not set any unnecessary register
+ * in the context. The state of the "general data" registers is
+ * undefined at task start time.
+ *
+ * NOTE: This is_fp parameter is TRUE if the thread is to be a floating
+ * point thread. This is typically only used on CPUs where the
+ * FPU may be easily disabled by software such as on the SPARC
+ * where the PSR contains an enable FPU bit.
+ *
+ * The per-thread status register holds the interrupt enable, FP enable
+ * and global interrupt enable for that thread. It means each thread can
+ * enable its own set of interrupts. If interrupts are disabled, RTEMS
+ * can still dispatch via blocking calls. This is the function of the
+ * "Interrupt Level", and on the MIPS, it controls the IEC bit and all
+ * the hardware interrupts as defined in the SR. Software ints
+ * are automatically enabled for all threads, as they will only occur under
+ * program control anyhow. Besides, the interrupt level parm is only 8 bits,
+ * and controlling the software ints plus the others would require 9.
+ *
+ * If the Interrupt Level is 0, all ints are on. Otherwise, the
+ * Interrupt Level should supply a bit pattern to impose on the SR
+ * interrupt bits; bit 0 applies to the mips1 IEC bit/mips3 EXL&IE, bits 1 thru 6
+ * apply to the SR register Intr bits from bit 10 thru bit 15. Bit 7 of
+ * the Interrupt Level parameter is unused at this time.
+ *
+ * These are the only per-thread SR bits, the others are maintained
+ * globally & explicitly preserved by the Context Switch code in cpu_asm.s
+ */
+
+
+#if (__mips == 3) || (__mips == 32)
+#define _INTON SR_IE
+#if __mips_fpr==64
+#define _EXTRABITS SR_FR
+#else
+#define _EXTRABITS 0
+#endif /* __mips_fpr==64 */
+#endif /* __mips == 3 */
+#if __mips == 1
+#define _INTON SR_IEC
+#define _EXTRABITS 0 /* make sure we're in user mode on MIPS1 processors */
+#endif /* __mips == 1 */
+
+#define _CPU_Context_Initialize( _the_context, _stack_base, _size, _isr, _entry_point, _is_fp ) \
+ { \
+ uint32_t _stack_tmp = \
+ (uint32_t )(_stack_base) + (_size) - CPU_STACK_ALIGNMENT; \
+ uint32_t _intlvl = _isr & 0xff; \
+ _stack_tmp &= ~(CPU_STACK_ALIGNMENT - 1); \
+ (_the_context)->sp = _stack_tmp; \
+ (_the_context)->fp = _stack_tmp; \
+ (_the_context)->ra = (__MIPS_REGISTER_TYPE)_entry_point; \
+ (_the_context)->c0_sr = ((_intlvl==0)?(mips_interrupt_mask() | 0x300 | _INTON): \
+ ( ((_intlvl<<9) & mips_interrupt_mask()) | 0x300 | ((_intlvl & 1)?_INTON:0)) ) | \
+ SR_CU0 | ((_is_fp)?SR_CU1:0) | _EXTRABITS; \
+ }
+
+
+
+/*
+ * This routine is responsible for somehow restarting the currently
+ * executing task. If you are lucky, then all that is necessary
+ * is restoring the context. Otherwise, there will need to be
+ * a special assembly routine which does something special in this
+ * case. Context_Restore should work most of the time. It will
+ * not work if restarting self conflicts with the stack frame
+ * assumptions of restoring a context.
+ */
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+/*
+ * The purpose of this macro is to allow the initial pointer into
+ * A floating point context area (used to save the floating point
+ * context) to be at an arbitrary place in the floating point
+ * context area.
+ *
+ * This is necessary because some FP units are designed to have
+ * their context saved as a stack which grows into lower addresses.
+ * Other FP units can be saved by simply moving registers into offsets
+ * from the base of the context area. Finally some FP units provide
+ * a "dump context" instruction which could fill in from high to low
+ * or low to high based on the whim of the CPU designers.
+ */
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
+
+/*
+ * This routine initializes the FP context area passed to it to.
+ * There are a few standard ways in which to initialize the
+ * floating point context. The code included for this macro assumes
+ * that this is a CPU in which a "initial" FP context was saved into
+ * _CPU_Null_fp_context and it simply copies it to the destination
+ * context passed to it.
+ *
+ * Other models include (1) not doing anything, and (2) putting
+ * a "null FP status word" in the correct place in the FP context.
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE )
+#define _CPU_Context_Initialize_fp( _destination ) \
+ { \
+ *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
+ }
+#endif
+
+/* end of Context handler macros */
+
+/* Fatal Error manager macros */
+
+/*
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ */
+
+#define _CPU_Fatal_halt( _error ) \
+ do { \
+ unsigned int _level; \
+ _CPU_ISR_Disable(_level); \
+ loop: goto loop; \
+ } while (0)
+
+
+extern void mips_break( int error );
+
+/* Bitfield handler macros */
+
+/*
+ * This routine sets _output to the bit number of the first bit
+ * set in _value. _value is of CPU dependent type Priority_Bit_map_control.
+ * This type may be either 16 or 32 bits wide although only the 16
+ * least significant bits will be used.
+ *
+ * There are a number of variables in using a "find first bit" type
+ * instruction.
+ *
+ * (1) What happens when run on a value of zero?
+ * (2) Bits may be numbered from MSB to LSB or vice-versa.
+ * (3) The numbering may be zero or one based.
+ * (4) The "find first bit" instruction may search from MSB or LSB.
+ *
+ * RTEMS guarantees that (1) will never happen so it is not a concern.
+ * (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
+ * _CPU_Priority_bits_index(). These three form a set of routines
+ * which must logically operate together. Bits in the _value are
+ * set and cleared based on masks built by _CPU_Priority_mask().
+ * The basic major and minor values calculated by _Priority_Major()
+ * and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
+ * to properly range between the values returned by the "find first bit"
+ * instruction. This makes it possible for _Priority_Get_highest() to
+ * calculate the major and directly index into the minor table.
+ * This mapping is necessary to ensure that 0 (a high priority major/minor)
+ * is the first bit found.
+ *
+ * This entire "find first bit" and mapping process depends heavily
+ * on the manner in which a priority is broken into a major and minor
+ * components with the major being the 4 MSB of a priority and minor
+ * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
+ * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next
+ * to the lowest priority.
+ *
+ * If your CPU does not have a "find first bit" instruction, then
+ * there are ways to make do without it. Here are a handful of ways
+ * to implement this in software:
+ *
+ * - a series of 16 bit test instructions
+ * - a "binary search using if's"
+ * - _number = 0
+ * if _value > 0x00ff
+ * _value >>=8
+ * _number = 8;
+ *
+ * if _value > 0x0000f
+ * _value >=8
+ * _number += 4
+ *
+ * _number += bit_set_table[ _value ]
+ *
+ * where bit_set_table[ 16 ] has values which indicate the first
+ * bit set
+ */
+
+#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ (_output) = 0; /* do something to prevent warnings */ \
+ }
+
+#endif
+
+/* end of Bitfield handler macros */
+
+/*
+ * This routine builds the mask which corresponds to the bit fields
+ * as searched by _CPU_Bitfield_Find_first_bit(). See the discussion
+ * for that routine.
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_Mask( _bit_number ) \
+ ( 1 << (_bit_number) )
+
+#endif
+
+/*
+ * This routine translates the bit numbers returned by
+ * _CPU_Bitfield_Find_first_bit() into something suitable for use as
+ * a major or minor component of a priority. See the discussion
+ * for that routine.
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_bits_index( _priority ) \
+ (_priority)
+
+#endif
+
+/* end of Priority handler macros */
+
+/* functions */
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/*
+ * _CPU_ISR_install_raw_handler
+ *
+ * This routine installs a "raw" interrupt handler directly into the
+ * processor's vector table.
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_Install_interrupt_stack
+ *
+ * This routine installs the hardware interrupt stack pointer.
+ *
+ * NOTE: It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK
+ * is TRUE.
+ */
+
+void _CPU_Install_interrupt_stack( void );
+
+/*
+ * _CPU_Internal_threads_Idle_thread_body
+ *
+ * This routine is the CPU dependent IDLE thread body.
+ *
+ * NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
+ * is TRUE.
+ */
+
+void _CPU_Thread_Idle_body( void );
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally 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.
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+/* The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * This version will work on any processor, but if there is a better
+ * way for your CPU PLEASE use it. The most common way to do this is to:
+ *
+ * swap least significant two bytes with 16-bit rotate
+ * swap upper and lower 16-bits
+ * swap most significant two bytes with 16-bit rotate
+ *
+ * Some CPUs have special instructions which swap a 32-bit quantity in
+ * a single instruction (e.g. i486). It is probably best to avoid
+ * an "endian swapping control bit" in the CPU. One good reason is
+ * that interrupts would probably have to be disabled to ensure that
+ * an interrupt does not try to access the same "chunk" with the wrong
+ * endian. Another good reason is that on some CPUs, the endian bit
+ * endianness for ALL fetches -- both code and data -- so the code
+ * will be fetched incorrectly.
+ */
+
+static inline uint32_t CPU_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t byte1, byte2, byte3, byte4, swapped;
+
+ byte4 = (value >> 24) & 0xff;
+ byte3 = (value >> 16) & 0xff;
+ byte2 = (value >> 8) & 0xff;
+ byte1 = value & 0xff;
+
+ swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
+ return( swapped );
+}
+
+#define CPU_swap_u16( value ) \
+ (((value&0xff) << 8) | ((value >> 8)&0xff))
+
+
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/mips/rtems/score/mips.h b/cpukit/score/cpu/mips/rtems/score/mips.h
new file mode 100644
index 0000000000..97307b6f97
--- /dev/null
+++ b/cpukit/score/cpu/mips/rtems/score/mips.h
@@ -0,0 +1,283 @@
+/**
+ * @file rtems/score/mips.h
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2001.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_MIPS_H
+#define _RTEMS_SCORE_MIPS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ASM
+#include <rtems/mips/idtcpu.h>
+#endif
+
+/*
+ * SR bits that enable/disable interrupts
+ *
+ * NOTE: XXX what about SR_ERL?
+ */
+
+#if (__mips == 3) || (__mips == 32)
+#ifdef ASM
+#define SR_INTERRUPT_ENABLE_BITS 0x01
+#else
+#define SR_INTERRUPT_ENABLE_BITS SR_IE
+#endif
+
+#elif __mips == 1
+#define SR_INTERRUPT_ENABLE_BITS SR_IEC
+
+#else
+#error "mips interrupt enable bits: unknown architecture level!"
+#endif
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the "no cpu"
+ * family when executing in protected mode. It does
+ * this by setting variables to indicate which implementation
+ * dependent features are present in a particular member
+ * of the family.
+ */
+
+#if defined(__mips_soft_float)
+#define MIPS_HAS_FPU 0
+#else
+#define MIPS_HAS_FPU 1
+#endif
+
+
+#if (__mips == 1)
+#define CPU_MODEL_NAME "ISA Level 1 or 2"
+#elif (__mips == 3) || (__mips == 32)
+#if defined(__mips64)
+#define CPU_MODEL_NAME "ISA Level 4"
+#else
+#define CPU_MODEL_NAME "ISA Level 3"
+#endif
+#else
+#error "Unknown MIPS ISA level"
+#endif
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "MIPS"
+
+/*
+ * RTEMS Vector numbers for exception conditions. This is a direct
+ * map to the causes.
+ */
+
+#define MIPS_EXCEPTION_BASE 0
+
+#define MIPS_EXCEPTION_INT MIPS_EXCEPTION_BASE+0
+#define MIPS_EXCEPTION_MOD MIPS_EXCEPTION_BASE+1
+#define MIPS_EXCEPTION_TLBL MIPS_EXCEPTION_BASE+2
+#define MIPS_EXCEPTION_TLBS MIPS_EXCEPTION_BASE+3
+#define MIPS_EXCEPTION_ADEL MIPS_EXCEPTION_BASE+4
+#define MIPS_EXCEPTION_ADES MIPS_EXCEPTION_BASE+5
+#define MIPS_EXCEPTION_IBE MIPS_EXCEPTION_BASE+6
+#define MIPS_EXCEPTION_DBE MIPS_EXCEPTION_BASE+7
+#define MIPS_EXCEPTION_SYSCALL MIPS_EXCEPTION_BASE+8
+#define MIPS_EXCEPTION_BREAK MIPS_EXCEPTION_BASE+9
+#define MIPS_EXCEPTION_RI MIPS_EXCEPTION_BASE+10
+#define MIPS_EXCEPTION_CPU MIPS_EXCEPTION_BASE+11
+#define MIPS_EXCEPTION_OVERFLOW MIPS_EXCEPTION_BASE+12
+#define MIPS_EXCEPTION_TRAP MIPS_EXCEPTION_BASE+13
+#define MIPS_EXCEPTION_VCEI MIPS_EXCEPTION_BASE+14
+/* FPE only on mips2 and higher */
+#define MIPS_EXCEPTION_FPE MIPS_EXCEPTION_BASE+15
+#define MIPS_EXCEPTION_C2E MIPS_EXCEPTION_BASE+16
+/* 17-22 reserved */
+#define MIPS_EXCEPTION_WATCH MIPS_EXCEPTION_BASE+23
+/* 24-30 reserved */
+#define MIPS_EXCEPTION_VCED MIPS_EXCEPTION_BASE+31
+
+#define MIPS_INTERRUPT_BASE MIPS_EXCEPTION_BASE+32
+
+/*
+ * Some macros to access registers
+ */
+
+#define mips_get_sr( _x ) \
+ do { \
+ asm volatile( "mfc0 %0, $12; nop" : "=r" (_x) : ); \
+ } while (0)
+
+#define mips_set_sr( _x ) \
+ do { \
+ register unsigned int __x = (_x); \
+ asm volatile( "mtc0 %0, $12; nop" : : "r" (__x) ); \
+ } while (0)
+
+
+/*
+ * Access the Cause register
+ */
+
+#define mips_get_cause( _x ) \
+ do { \
+ asm volatile( "mfc0 %0, $13; nop" : "=r" (_x) : ); \
+ } while (0)
+
+
+#define mips_set_cause( _x ) \
+ do { \
+ register unsigned int __x = (_x); \
+ asm volatile( "mtc0 %0, $13; nop" : : "r" (__x) ); \
+ } while (0)
+
+
+
+
+/*
+ * Access the Debug Cache Invalidate Control register
+ */
+
+#define mips_get_dcic( _x ) \
+ do { \
+ asm volatile( "mfc0 %0, $7; nop" : "=r" (_x) : ); \
+ } while (0)
+
+
+#define mips_set_dcic( _x ) \
+ do { \
+ register unsigned int __x = (_x); \
+ asm volatile( "mtc0 %0, $7; nop" : : "r" (__x) ); \
+ } while (0)
+
+
+
+
+/*
+ * Access the Breakpoint Program Counter & Mask registers
+ * (_x for BPC, _y for mask)
+ */
+
+#define mips_get_bpcrm( _x, _y ) \
+ do { \
+ asm volatile( "mfc0 %0, $3; nop" : "=r" (_x) : ); \
+ asm volatile( "mfc0 %0, $11; nop" : "=r" (_y) : ); \
+ } while (0)
+
+
+#define mips_set_bpcrm( _x, _y ) \
+ do { \
+ register unsigned int __x = (_x); \
+ register unsigned int __y = (_y); \
+ asm volatile( "mtc0 %0, $11; nop" : : "r" (__y) ); \
+ asm volatile( "mtc0 %0, $3; nop" : : "r" (__x) ); \
+ } while (0)
+
+
+
+
+
+
+/*
+ * Access the Breakpoint Data Address & Mask registers
+ * (_x for BDA, _y for mask)
+ */
+
+#define mips_get_bdarm( _x, _y ) \
+ do { \
+ asm volatile( "mfc0 %0, $5; nop" : "=r" (_x) : ); \
+ asm volatile( "mfc0 %0, $9; nop" : "=r" (_y) : ); \
+ } while (0)
+
+
+#define mips_set_bdarm( _x, _y ) \
+ do { \
+ register unsigned int __x = (_x); \
+ register unsigned int __y = (_y); \
+ asm volatile( "mtc0 %0, $9; nop" : : "r" (__y) ); \
+ asm volatile( "mtc0 %0, $5; nop" : : "r" (__x) ); \
+ } while (0)
+
+
+
+
+
+
+
+/*
+ * Access FCR31
+ */
+
+#if ( MIPS_HAS_FPU == 1 )
+
+#define mips_get_fcr31( _x ) \
+ do { \
+ asm volatile( "cfc1 %0, $31; nop" : "=r" (_x) : ); \
+ } while(0)
+
+
+#define mips_set_fcr31( _x ) \
+ do { \
+ register unsigned int __x = (_x); \
+ asm volatile( "ctc1 %0, $31; nop" : : "r" (__x) ); \
+ } while(0)
+
+#else
+
+#define mips_get_fcr31( _x )
+#define mips_set_fcr31( _x )
+
+#endif
+
+/*
+ * Manipulate interrupt mask
+ *
+ * mips_unmask_interrupt( _mask)
+ * enables interrupts - mask is positioned so it only needs to be or'ed
+ * into the status reg. This also does some other things !!!! Caution
+ * should be used if invoking this while in the middle of a debugging
+ * session where the client may have nested interrupts.
+ *
+ * mips_mask_interrupt( _mask )
+ * disable the interrupt - mask is the complement of the bits to be
+ * cleared - i.e. to clear ext int 5 the mask would be - 0xffff7fff
+ *
+ *
+ * NOTE: mips_mask_interrupt() used to be disable_int().
+ * mips_unmask_interrupt() used to be enable_int().
+ *
+ */
+
+#define mips_enable_in_interrupt_mask( _mask ) \
+ do { \
+ unsigned int _sr; \
+ mips_get_sr( _sr ); \
+ _sr |= (_mask); \
+ mips_set_sr( _sr ); \
+ } while (0)
+
+#define mips_disable_in_interrupt_mask( _mask ) \
+ do { \
+ unsigned int _sr; \
+ mips_get_sr( _sr ); \
+ _sr &= ~(_mask); \
+ mips_set_sr( _sr ); \
+ } while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_MIPS_H */
+/* end of include file */
diff --git a/cpukit/score/cpu/mips/rtems/score/types.h b/cpukit/score/cpu/mips/rtems/score/types.h
new file mode 100644
index 0000000000..c5a218e214
--- /dev/null
+++ b/cpukit/score/cpu/mips/rtems/score/types.h
@@ -0,0 +1,55 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains type definitions pertaining to the MIPS
+ * processor family.
+ *
+ * COPYRIGHT (c) 1989-2001.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+/* @(#)mipstypes.h 08/20/96 1.4 */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+
+typedef uint16_t Priority_Bit_map_control;
+
+typedef signed long long signed64; /* 64 bit signed integer */
+
+typedef uint32_t boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void mips_isr;
+typedef void ( *mips_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/nios2/.cvsignore b/cpukit/score/cpu/nios2/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/nios2/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/nios2/ChangeLog b/cpukit/score/cpu/nios2/ChangeLog
new file mode 100644
index 0000000000..05836ba0eb
--- /dev/null
+++ b/cpukit/score/cpu/nios2/ChangeLog
@@ -0,0 +1,18 @@
+2006-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * .cvsignore: New file.
+
+2006-08-09 Kolja Waschk <waschk@telos.de>
+
+ * rtems/score/cpu.h, rtems/score/cpu_asm.h, rtems/score/nios2.h,
+ rtems/score/types.h: New files.
+
+2006-08-09 Kolja Waschk <waschk@telos.de>
+
+ * ChangeLog, Makefile.am, cpu.c, cpu_asm.S, irq.c, preinstall.am,
+ rtems/asm.h: New files.
+
+2005-12-09 Kolja Waschk <rtemsdev@ixo.de>
+
+ Derived from no_cpu
+
diff --git a/cpukit/score/cpu/nios2/Makefile.am b/cpukit/score/cpu/nios2/Makefile.am
new file mode 100644
index 0000000000..c1680f82fc
--- /dev/null
+++ b/cpukit/score/cpu/nios2/Makefile.am
@@ -0,0 +1,25 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+CLEANFILES =
+DISTCLEANFILES =
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/nios2.h \
+ rtems/score/cpu_asm.h rtems/score/types.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c irq.c cpu_asm.S
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+all-local: $(PREINSTALL_FILES)
+
+include $(srcdir)/preinstall.am
+
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/nios2/cpu.c b/cpukit/score/cpu/nios2/cpu.c
new file mode 100644
index 0000000000..f2f9863cf0
--- /dev/null
+++ b/cpukit/score/cpu/nios2/cpu.c
@@ -0,0 +1,197 @@
+/*
+ * NIOS2 CPU Dependent Source
+ *
+ * COPYRIGHT (c) 1989-2006
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/wkspace.h>
+
+/* _CPU_Initialize
+ *
+ * This routine performs processor dependent initialization.
+ *
+ * INPUT PARAMETERS:
+ * cpu_table - CPU table to initialize
+ * thread_dispatch - address of disptaching routine
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch) /* ignored on this CPU */
+)
+{
+ /*
+ * The thread_dispatch argument is the address of the entry point
+ * for the routine called at the end of an ISR once it has been
+ * decided a context switch is necessary. On some compilation
+ * systems it is difficult to call a high-level language routine
+ * from assembly. This allows us to trick these systems.
+ *
+ * If you encounter this problem save the entry point in a CPU
+ * dependent variable.
+ */
+
+ _CPU_Thread_dispatch_pointer = thread_dispatch;
+
+ /*
+ * If there is not an easy way to initialize the FP context
+ * during Context_Initialize, then it is usually easier to
+ * save an "uninitialized" FP context here and copy it to
+ * the task's during Context_Initialize.
+ */
+
+ /* FP context initialization support goes here */
+
+ _CPU_Table = *cpu_table;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Get_level
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ /*
+ * This routine returns the current interrupt level.
+ */
+
+ return 0;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_install_raw_handler
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ /*
+ * This is where we install the interrupt handler into the "raw" interrupt
+ * table used by the CPU to dispatch interrupt handlers.
+ */
+}
+
+/*PAGE
+ *
+ * _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
+ *
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ *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.
+ */
+
+ _CPU_ISR_install_raw_handler( vector, new_handler, old_handler );
+
+ /*
+ * 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;
+}
+
+/*PAGE
+ *
+ * _CPU_Install_interrupt_stack
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Install_interrupt_stack( void )
+{
+}
+
+/*PAGE
+ *
+ * _CPU_Thread_Idle_body
+ *
+ * NOTES:
+ *
+ * 1. This is the same as the regular CPU independent algorithm.
+ *
+ * 2. If you implement this using a "halt", "idle", or "shutdown"
+ * instruction, then don't forget to put it in an infinite loop.
+ *
+ * 3. Be warned. Some processors with onboard DMA have been known
+ * to stop the DMA if the CPU were put in IDLE mode. This might
+ * also be a problem with other on-chip peripherals. So use this
+ * hook with caution.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Thread_Idle_body( void )
+{
+#if 1
+ for(;;);
+#else
+ for(;;)
+ {
+ uint32_t st = __builtin_rdctl(0); /* read status register */
+
+ /* Differentiate between IRQ off and on (for debugging) */
+ if(st & 1)
+ for(;;);
+ else
+ for(;;);
+
+ /* insert your "halt" instruction here */ ;
+ }
+#endif
+}
diff --git a/cpukit/score/cpu/nios2/cpu_asm.S b/cpukit/score/cpu/nios2/cpu_asm.S
new file mode 100644
index 0000000000..2244430703
--- /dev/null
+++ b/cpukit/score/cpu/nios2/cpu_asm.S
@@ -0,0 +1,388 @@
+/*
+ * $Id$
+ *
+ * This file contains all assembly code for the
+ * NIOS2 implementation of RTEMS.
+ *
+ * Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
+ *
+ * Derived from no_cpu/cpu_asm.S, 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.rtems.com/license/LICENSE.
+ *
+ */
+
+#include <rtems/asm.h>
+#include <rtems/score/cpu_asm.h>
+
+ .set noat
+
+ .extern _ISR_Nest_level
+ .extern _ISR_Signals_to_thread_executing
+ .extern _Context_Switch_necessary
+ .extern _Thread_Dispatch
+ .extern _Thread_Dispatch_disable_level
+
+/* ===================================================================== */
+
+/*
+ * void _CPU_Context_switch( run_context, heir_context )
+ * void _CPU_Context_restore( run_context, heir_context )
+ *
+ * This routine performs a normal non-FP context switch.
+ */
+
+ .globl _CPU_Context_switch
+
+_CPU_Context_switch:
+
+ rdctl r6, status
+ stw r16, 0(r4)
+ stw r17, 4(r4)
+ stw r18, 8(r4)
+ stw r19, 12(r4)
+ stw r20, 16(r4)
+ stw r21, 20(r4)
+ stw r22, 24(r4)
+ stw r23, 28(r4)
+ stw gp, 32(r4)
+ stw fp, 36(r4)
+ stw sp, 40(r4)
+ stw ra, 44(r4)
+ /* r6 saved status */
+ stw r6, 48(r4)
+
+_CPU_Context_switch_restore:
+
+ ldw r16, 0(r5)
+ ldw r17, 4(r5)
+ ldw r18, 8(r5)
+ ldw r19, 12(r5)
+ ldw r20, 16(r5)
+ ldw r21, 20(r5)
+ ldw r22, 24(r5)
+ ldw r23, 28(r5)
+ ldw gp, 32(r5)
+ ldw fp, 36(r5)
+ ldw sp, 40(r5)
+
+ /* Disable interrupts */
+ wrctl status, r0
+
+ ldw ea, 44(r5)
+ ldw at, 48(r5)
+ /* FIXME: Always have interrupts enabled when we return from Context_switch */
+ ori at, at, 1
+ wrctl estatus, at
+
+ eret
+
+ .globl _CPU_Context_restore
+
+_CPU_Context_restore:
+
+ /* Copy first to second arg, then re-use 2nd half of Context_switch */
+ mov r5, r4
+ br _CPU_Context_switch_restore
+
+
+/* ===================================================================== */
+
+ .globl _exception_vector
+
+_exception_vector:
+
+ /*
+ * First, re-wind so we're pointed to the instruction where the exception
+ * occurred.
+ */
+
+ addi ea, ea, -4
+
+ /*
+ * Now test to determine the cause of the exception.
+ */
+
+ /* TODO: Look at [ea] if there was an unknown/trap instruction */
+
+ /* If interrupts are globally disabled, it certainly was no interrupt */
+ rdctl et, estatus
+ andi et, et, 1
+ beq et, zero, _Exception_Handler
+
+ /* If no interrupts are pending, it was a software exception */
+ rdctl et, ipending
+ beq et, zero, _Exception_Handler
+
+ /*
+ * Falling through to here means that this was a hardware interrupt.
+ */
+
+ br _ISR_Handler
+
+/* =====================================================================
+ * Exception handler:
+ * Responsible for unimplemented instructions and other software
+ * exceptions. Not responsible for hardware interrupts. Currently,
+ * software exceptions are regarded as error conditions, and the
+ * handling isn't perfect. */
+
+_Exception_Handler:
+
+ /* stw et, 108(sp') => stw et, -20(sp) */
+ stw et, -20(sp)
+ mov et, sp
+ addi sp, sp, -128
+
+ stw r1, 0(sp)
+ stw r2, 4(sp)
+ stw r3, 8(sp)
+
+ rdctl r1, estatus
+ rdctl r2, ienable
+ rdctl r3, ipending
+
+ stw r4, 12(sp)
+ stw r5, 16(sp)
+ stw r6, 20(sp)
+ stw r7, 24(sp)
+ stw r8, 28(sp)
+ stw r9, 32(sp)
+ stw r10, 36(sp)
+ stw r11, 40(sp)
+ stw r12, 44(sp)
+ stw r13, 48(sp)
+ stw r14, 52(sp)
+ stw r15, 56(sp)
+ stw r16, 60(sp)
+ stw r17, 64(sp)
+ stw r18, 68(sp)
+ stw r19, 72(sp)
+ stw r20, 76(sp)
+ stw r21, 80(sp)
+ stw r22, 84(sp)
+ stw r23, 88(sp)
+ stw gp, 92(sp)
+ stw fp, 96(sp)
+ /* sp */
+ stw et, 100(sp)
+ stw ra, 104(sp)
+ /* stw et, 108(sp) */
+ stw ea, 112(sp)
+
+ /* status */
+ stw r1, 116(sp)
+ /* ienable */
+ stw r2, 120(sp)
+ /* ipending */
+ stw r3, 124(sp)
+
+ /*
+ * Restore the global pointer.
+ */
+
+ movhi gp, %hiadj(_gp)
+ addi gp, gp, %lo(_gp)
+
+ /*
+ * Pass a pointer to the stack frame as the input argument of the
+ * exception handler (CPU_Exception_frame *).
+ */
+
+ mov r4, sp
+
+ /*
+ * Call the exception handler.
+ */
+
+ .extern __Exception_Handler
+ call __Exception_Handler
+
+stuck_in_exception:
+ br stuck_in_exception
+
+ /*
+ * Restore the saved registers, so that all general purpose registers
+ * have been restored to their state at the time the interrupt occured.
+ */
+
+ ldw r1, 0(sp)
+ ldw r2, 4(sp)
+ ldw r3, 8(sp)
+ ldw r4, 12(sp)
+ ldw r5, 16(sp)
+ ldw r6, 20(sp)
+ ldw r7, 24(sp)
+ ldw r8, 28(sp)
+ ldw r9, 32(sp)
+ ldw r10, 36(sp)
+ ldw r11, 40(sp)
+ ldw r12, 44(sp)
+ ldw r13, 48(sp)
+ ldw r14, 52(sp)
+ ldw r15, 56(sp)
+ ldw r16, 60(sp)
+ ldw r17, 64(sp)
+ ldw r18, 68(sp)
+ ldw r19, 72(sp)
+ ldw r20, 76(sp)
+ ldw r21, 80(sp)
+ ldw r22, 84(sp)
+ ldw r23, 88(sp)
+ ldw gp, 92(sp)
+ ldw fp, 96(sp)
+ ldw ra, 104(sp)
+
+ /* Disable interrupts */
+ wrctl status, r0
+
+ ldw ea, 112(sp)
+ ldw et, 116(sp)
+
+ /* FIXME: Enable interrupts after exception processing */
+ ori et, et, 1
+ wrctl estatus, et
+ ldw et, 108(sp)
+
+ /* Restore stack pointer */
+ ldw sp, 100(sp)
+
+ eret
+
+/* ===================================================================== */
+
+ .section .text
+
+_ISR_Handler:
+
+ /*
+ * Process an external hardware interrupt.
+ *
+ * First, preserve all callee saved registers on
+ * the stack. (See the Nios2 ABI documentation for details).
+ *
+ * Do we really need to save all?
+ *
+ * If this is interrupting a task (and not another interrupt),
+ * everything is saved into the task's stack, thus putting us
+ * in a situation similar to when the task calls a subroutine
+ * (and only the CPU_Context_Control subset needs to be changed)
+ */
+
+ rdctl et, estatus
+
+ /* Keep this in the same order as CPU_Interrupt_frame: */
+
+ addi sp, sp, -76
+ stw r1, 0(sp)
+ stw r2, 4(sp)
+ stw r3, 8(sp)
+ stw r4, 12(sp)
+ stw r5, 16(sp)
+ stw r6, 20(sp)
+ stw r7, 24(sp)
+ stw r8, 28(sp)
+ stw r9, 32(sp)
+ stw r10, 36(sp)
+ stw r11, 40(sp)
+ stw r12, 44(sp)
+ stw r13, 48(sp)
+ stw r14, 52(sp)
+ stw r15, 56(sp)
+ stw ra, 60(sp)
+ stw gp, 64(sp)
+ /* et contains status */
+ stw et, 68(sp)
+ stw ea, 72(sp)
+
+ /*
+ * Obtain a bitlist of the pending interrupts.
+ */
+
+ rdctl et, ipending
+
+ /*
+ * Restore the global pointer to the expected value.
+ */
+
+ movhi gp, %hiadj(_gp)
+ addi gp, gp, %lo(_gp)
+
+ /*
+ * Search through the bit list stored in r24(et) to find the first enabled
+ * bit. The offset of this bit is the index of the interrupt that is
+ * to be handled.
+ */
+
+ mov r4, zero
+6:
+ andi r3, r24, 1
+ bne r3, zero, 7f
+ addi r4, r4, 1
+ srli r24, r24, 1
+ br 6b
+7:
+
+ /*
+ * Having located the interrupt source, r4 contains the index of the
+ * interrupt to be handled. r5, the 2nd argument to the function,
+ * will point to the CPU_Interrupt_frame.
+ */
+
+ mov r5, sp
+
+ .extern __ISR_Handler
+ call __ISR_Handler
+
+ /*
+ * Now that the interrupt processing is complete, prepare to return to
+ * the interrupted code.
+ */
+
+ /*
+ * Restore the saved registers, so that all general purpose registers
+ * have been restored to their state at the time the interrupt occured.
+ */
+
+ ldw r1, 0(sp)
+ ldw r2, 4(sp)
+ ldw r3, 8(sp)
+ ldw r4, 12(sp)
+ ldw r5, 16(sp)
+ ldw r6, 20(sp)
+ ldw r7, 24(sp)
+ ldw r8, 28(sp)
+ ldw r9, 32(sp)
+ ldw r10, 36(sp)
+ ldw r11, 40(sp)
+ ldw r12, 44(sp)
+ ldw r13, 48(sp)
+ ldw r14, 52(sp)
+ ldw r15, 56(sp)
+ ldw ra, 60(sp)
+ ldw gp, 64(sp)
+
+ /* Disable interrupts */
+ wrctl status, r0
+
+ /* Restore the exception registers */
+
+ /* load saved ea into ea */
+ ldw ea, 72(sp)
+ /* load saved estatus into et */
+ ldw et, 68(sp)
+ /* Always have interrupts enabled when we return from interrupt */
+ ori et, et, 1
+ wrctl estatus, et
+ /* Restore the stack pointer */
+ addi sp, sp, 76
+
+ /*
+ * Return to the interrupted instruction.
+ */
+ eret
+
+
diff --git a/cpukit/score/cpu/nios2/irq.c b/cpukit/score/cpu/nios2/irq.c
new file mode 100644
index 0000000000..ac9385010d
--- /dev/null
+++ b/cpukit/score/cpu/nios2/irq.c
@@ -0,0 +1,94 @@
+/*
+ * NIOS2 exception and interrupt handler
+ *
+ * Derived from c4x/irq.c
+ *
+ * Copyright (c) 2006
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/cpu.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+
+/*
+ * This routine provides the RTEMS interrupt management.
+ *
+ * Upon entry, interrupts are disabled
+ */
+
+#if( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ unsigned long *_old_stack_ptr;
+#endif
+
+register unsigned long *stack_ptr asm("sp");
+
+void __ISR_Handler(uint32_t vector, CPU_Interrupt_frame *ifr)
+{
+ register uint32_t level;
+
+ /* Interrupts are disabled upon entry to this Handler */
+
+#if( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ if ( _ISR_Nest_level == 0 ) {
+ /* Install irq stack */
+ _old_stack_ptr = stack_ptr;
+ stack_ptr = _CPU_Interrupt_stack_high - 4;
+ }
+#endif
+
+ _ISR_Nest_level++;
+
+ _Thread_Dispatch_disable_level++;
+
+ if ( _ISR_Vector_table[ vector] )
+ {
+ (*_ISR_Vector_table[ vector ])(vector, ifr);
+ };
+
+ /* Make sure that interrupts are disabled again */
+ _CPU_ISR_Disable( level );
+
+ _Thread_Dispatch_disable_level--;
+
+ _ISR_Nest_level--;
+
+ if( _ISR_Nest_level == 0)
+ {
+#if( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ stack_ptr = _old_stack_ptr;
+#endif
+
+ if( _Thread_Dispatch_disable_level == 0 )
+ {
+ if ( _Context_Switch_necessary || _ISR_Signals_to_thread_executing )
+ {
+ _ISR_Signals_to_thread_executing = FALSE;
+ _CPU_ISR_Enable( level );
+ _Thread_Dispatch();
+ /* may have switched to another task and not return here immed. */
+ _CPU_ISR_Disable( level ); /* Keep _pairs_ of Enable/Disable */
+ }
+ }
+ else
+ {
+ _ISR_Signals_to_thread_executing = FALSE;
+ };
+ };
+
+ _CPU_ISR_Enable( level );
+}
+
+void __Exception_Handler(CPU_Exception_frame *efr)
+{
+ _CPU_Fatal_halt(0xECC0);
+}
+
+
diff --git a/cpukit/score/cpu/nios2/preinstall.am b/cpukit/score/cpu/nios2/preinstall.am
new file mode 100644
index 0000000000..59d5889b39
--- /dev/null
+++ b/cpukit/score/cpu/nios2/preinstall.am
@@ -0,0 +1,43 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES += $(PREINSTALL_DIRS)
+
+PREINSTALL_FILES =
+CLEANFILES += $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/nios2.h: rtems/score/nios2.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/nios2.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/nios2.h
+
+$(PROJECT_INCLUDE)/rtems/score/cpu_asm.h: rtems/score/cpu_asm.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
diff --git a/cpukit/score/cpu/nios2/rtems/asm.h b/cpukit/score/cpu/nios2/rtems/asm.h
new file mode 100644
index 0000000000..390048d353
--- /dev/null
+++ b/cpukit/score/cpu/nios2/rtems/asm.h
@@ -0,0 +1,97 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ */
+
+/*
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ * COPYRIGHT (c) 1994-1997.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/nios2.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/*
+ * define macros for all of the registers on this CPU
+ *
+ * EXAMPLE: #define d0 REG (d0)
+ */
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA
+#define END_DATA
+#define BEGIN_BSS
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .globl SYM (sym)
+#define EXTERN(sym) .globl SYM (sym)
+
+#endif
diff --git a/cpukit/score/cpu/nios2/rtems/score/cpu.h b/cpukit/score/cpu/nios2/rtems/score/cpu.h
new file mode 100644
index 0000000000..f05641def9
--- /dev/null
+++ b/cpukit/score/cpu/nios2/rtems/score/cpu.h
@@ -0,0 +1,1404 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * This include file contains information pertaining to the XXX
+ * processor.
+ *
+ * @note This file is part of a porting template that is intended
+ * to be used as the starting point when porting RTEMS to a new
+ * CPU family. The following needs to be done when using this as
+ * the starting point for a new port:
+ *
+ * + Anywhere there is an XXX, it should be replaced
+ * with information about the CPU family being ported to.
+ *
+ * + At the end of each comment section, there is a heading which
+ * says "Port Specific Information:". When porting to RTEMS,
+ * add CPU family specific information in this section
+ */
+
+/* COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/nios2.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+
+/* conditional compilation parameters */
+
+/**
+ * Should the calls to @ref _Thread_Enable_dispatch be inlined?
+ *
+ * If TRUE, then they are inlined.
+ * If FALSE, then a subroutine call is made.
+ *
+ * This conditional is an example of the classic trade-off of size
+ * versus speed. Inlining the call (TRUE) typically increases the
+ * size of RTEMS while speeding up the enabling of dispatching.
+ *
+ * @note In general, the @ref _Thread_Dispatch_disable_level will
+ * only be 0 or 1 unless you are in an interrupt handler and that
+ * interrupt handler invokes the executive.] When not inlined
+ * something calls @ref _Thread_Enable_dispatch which in turns calls
+ * @ref _Thread_Dispatch. If the enable dispatch is inlined, then
+ * one subroutine call is avoided entirely.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_INLINE_ENABLE_DISPATCH FALSE
+
+/**
+ * Should the body of the search loops in _Thread_queue_Enqueue_priority
+ * be unrolled one time? In unrolled each iteration of the loop examines
+ * two "nodes" on the chain being searched. Otherwise, only one node
+ * is examined per iteration.
+ *
+ * If TRUE, then the loops are unrolled.
+ * If FALSE, then the loops are not unrolled.
+ *
+ * The primary factor in making this decision is the cost of disabling
+ * and enabling interrupts (_ISR_Flash) versus the cost of rest of the
+ * body of the loop. On some CPUs, the flash is more expensive than
+ * one iteration of the loop body. In this case, it might be desirable
+ * to unroll the loop. It is important to note that on some CPUs, this
+ * code is the longest interrupt disable period in RTEMS. So it is
+ * necessary to strike a balance when setting this parameter.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
+
+/**
+ * Does RTEMS manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in @ref _ISR_Handler_initialization.
+ * If FALSE, nothing is done.
+ *
+ * If the CPU supports a dedicated interrupt stack in hardware,
+ * then it is generally the responsibility of the BSP to allocate it
+ * and set it up.
+ *
+ * If the CPU does not support a dedicated interrupt stack, then
+ * the porter has two options: (1) execute interrupts on the
+ * stack of the interrupted task, and (2) have RTEMS manage a dedicated
+ * interrupt stack.
+ *
+ * If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * @ref CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
+
+/**
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * If TRUE, then it must be installed during initialization.
+ * If FALSE, then no installation is performed.
+ *
+ * If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * @ref CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
+
+/**
+ * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * If TRUE, then the memory is allocated during initialization.
+ * If FALSE, then the memory is allocated during initialization.
+ *
+ * This should be TRUE is @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE
+ * or @ref CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
+
+/**
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_ISR_PASSES_FRAME_POINTER 1
+
+/**
+ * @def CPU_HARDWARE_FP
+ *
+ * Does the CPU have hardware floating point?
+ *
+ * If TRUE, then the @ref RTEMS_FLOATING_POINT task attribute is supported.
+ * If FALSE, then the @ref RTEMS_FLOATING_POINT task attribute is ignored.
+ *
+ * If there is a FP coprocessor such as the i387 or mc68881, then
+ * the answer is TRUE.
+ *
+ * It indicates whether or not this CPU model has FP support. For
+ * example, it would be possible to have an i386_nofp CPU model
+ * which set this to false to indicate that you have an i386 without
+ * an i387 and wish to leave floating point support out of RTEMS.
+ */
+
+/**
+ * @def CPU_SOFTWARE_FP
+ *
+ * Does the CPU have no hardware floating point and GCC provides a
+ * software floating point implementation which must be context
+ * switched?
+ *
+ * This feature conditional is used to indicate whether or not there
+ * is software implemented floating point that must be context
+ * switched. The determination of whether or not this applies
+ * is very tool specific and the state saved/restored is also
+ * compiler specific.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_HARDWARE_FP FALSE
+#define CPU_SOFTWARE_FP FALSE
+
+/**
+ * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
+ *
+ * If TRUE, then the @ref RTEMS_FLOATING_POINT task attribute is assumed.
+ * If FALSE, then the @ref RTEMS_FLOATING_POINT task attribute is followed.
+ *
+ * So far, the only CPUs in which this option has been used are the
+ * HP PA-RISC and PowerPC. On the PA-RISC, The HP C compiler and
+ * gcc both implicitly used the floating point registers to perform
+ * integer multiplies. Similarly, the PowerPC port of gcc has been
+ * seen to allocate floating point local variables and touch the FPU
+ * even when the flow through a subroutine (like vfprintf()) might
+ * not use floating point formats.
+ *
+ * If a function which you would not think utilize the FP unit DOES,
+ * then one can not easily predict which tasks will use the FP hardware.
+ * In this case, this option should be TRUE.
+ *
+ * If @ref CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_ALL_TASKS_ARE_FP FALSE
+
+/**
+ * Should the IDLE task have a floating point context?
+ *
+ * If TRUE, then the IDLE task is created as a @ref RTEMS_FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * If FALSE, then the IDLE task does not have a floating point context.
+ *
+ * Setting this to TRUE negatively impacts the time required to preempt
+ * the IDLE task from an interrupt because the floating point context
+ * must be saved as part of the preemption.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+/**
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ *
+ * If the floating point context does NOT have to be saved as part of
+ * interrupt dispatching, then it should be safe to set this to TRUE.
+ *
+ * Setting this flag to TRUE results in using a different algorithm
+ * for deciding when to save and restore the floating point context.
+ * The deferred FP switch algorithm minimizes the number of times
+ * the FP context is saved and restored. The FP context is not saved
+ * until a context switch is made to another, different FP task.
+ * Thus in a system with only one FP task, the FP context will never
+ * be saved or restored.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+/**
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine @ref _CPU_Thread_Idle_body
+ * must be provided and is the default IDLE thread body instead of
+ * @ref _CPU_Thread_Idle_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ *
+ * This is intended to allow for supporting processors which have
+ * a low power or idle mode. When the IDLE thread is executed, then
+ * the CPU can be powered down.
+ *
+ * The order of precedence for selecting the IDLE thread body is:
+ *
+ * -# BSP provided
+ * -# CPU dependent (if provided)
+ * -# generic (if no BSP and no CPU dependent)
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE
+
+/**
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * If TRUE, then the grows upward.
+ * If FALSE, then the grows toward smaller addresses.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_STACK_GROWS_UP FALSE
+
+/**
+ * The following is the variable attribute used to force alignment
+ * of critical RTEMS structures. On some processors it may make
+ * sense to have these aligned on tighter boundaries than
+ * the minimum requirements of the compiler in order to have as
+ * much of the critical data area as possible in a cache line.
+ *
+ * The placement of this macro in the declaration of the variables
+ * is based on the syntactically requirements of the GNU C
+ * "__attribute__" extension. For example with GNU C, use
+ * the following to force a structures to a 32 byte boundary.
+ *
+ * __attribute__ ((aligned (32)))
+ *
+ * @note Currently only the Priority Bit Map table uses this feature.
+ * To benefit from using this, the data must be heavily
+ * used so it will stay in the cache and used frequently enough
+ * in the executive to justify turning this on.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_STRUCTURE_ALIGNMENT
+
+/**
+ * @defgroup CPUEndian Processor Dependent Endianness Support
+ *
+ * This group assists in issues related to processor endianness.
+ */
+
+/**
+ * @ingroup CPUEndian
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ *
+ * @note @a CPU_BIG_ENDIAN and @a CPU_LITTLE_ENDIAN should NOT have the
+ * same values.
+ *
+ * @see CPU_LITTLE_ENDIAN
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_BIG_ENDIAN FALSE
+
+/**
+ * @ingroup CPUEndian
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ *
+ * @note @ref CPU_BIG_ENDIAN and @ref CPU_LITTLE_ENDIAN should NOT have the
+ * same values.
+ *
+ * @see CPU_BIG_ENDIAN
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_LITTLE_ENDIAN TRUE
+
+/**
+ * @ingroup CPUInterrupt
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine @ref _CPU_ISR_Set_level.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_MODES_INTERRUPT_MASK 0x00000001
+
+/*
+ * Processor defined structures required for cpukit/score.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/* may need to put some structures here. */
+
+/**
+ * @defgroup CPUContext Processor Dependent Context Management
+ *
+ * From the highest level viewpoint, there are 2 types of context to save.
+ *
+ * -# Interrupt registers to save
+ * -# Task level registers to save
+ *
+ * Since RTEMS handles integer and floating point contexts separately, this
+ * means we have the following 3 context items:
+ *
+ * -# task level context stuff:: Context_Control
+ * -# floating point task stuff:: Context_Control_fp
+ * -# special interrupt level context :: CPU_Interrupt_frame
+ *
+ * On some processors, it is cost-effective to save only the callee
+ * preserved registers during a task context switch. This means
+ * that the ISR code needs to save those registers which do not
+ * persist across function calls. It is not mandatory to make this
+ * distinctions between the caller/callee saves registers for the
+ * purpose of minimizing context saved during task switch and on interrupts.
+ * If the cost of saving extra registers is minimal, simplicity is the
+ * choice. Save the same context on interrupt entry as for tasks in
+ * this case.
+ *
+ * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
+ * care should be used in designing the context area.
+ *
+ * On some CPUs with hardware floating point support, the Context_Control_fp
+ * structure will not be used or it simply consist of an array of a
+ * fixed number of bytes. This is done when the floating point context
+ * is dumped by a "FP save context" type instruction and the format
+ * is not really defined by the CPU. In this case, there is no need
+ * to figure out the exact format -- only the size. Of course, although
+ * this is enough information for RTEMS, it is probably not enough for
+ * a debugger such as gdb. But that is another problem.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/**
+ * @ingroup CPUContext Management
+ * This defines the minimal set of integer and processor state registers
+ * that must be saved during a voluntary context switch from one thread
+ * to another.
+ */
+typedef struct {
+ uint32_t r16;
+ uint32_t r17;
+ uint32_t r18;
+ uint32_t r19;
+ uint32_t r20;
+ uint32_t r21;
+ uint32_t r22;
+ uint32_t r23;
+ uint32_t gp;
+ uint32_t fp;
+ uint32_t sp;
+ uint32_t ra;
+ uint32_t status;
+ /* ienable? */
+ /* ipending? */
+} Context_Control;
+
+/**
+ * @ingroup CPUContext Management
+ * This defines the complete set of floating point registers that must
+ * be saved during any context switch from one thread to another.
+ */
+typedef struct {
+} Context_Control_fp;
+
+/**
+ * @ingroup CPUContext Management
+ * This defines the set of integer and processor state registers that must
+ * be saved during an interrupt. This set does not include any which are
+ * in @ref Context_Control.
+ */
+typedef struct {
+ uint32_t r1;
+ uint32_t r2;
+ uint32_t r3;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+ uint32_t r12;
+ uint32_t r13;
+ uint32_t r14;
+ uint32_t r15;
+ uint32_t ra;
+ uint32_t gp;
+ uint32_t et;
+ uint32_t ea;
+} CPU_Interrupt_frame;
+
+/**
+ * @ingroup CPUContext Management
+ * This defines the set of integer and processor state registers that are
+ * saved during a software exception.
+ */
+typedef struct {
+ uint32_t r1;
+ uint32_t r2;
+ uint32_t r3;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+ uint32_t r12;
+ uint32_t r13;
+ uint32_t r14;
+ uint32_t r15;
+ uint32_t r16;
+ uint32_t r17;
+ uint32_t r18;
+ uint32_t r19;
+ uint32_t r20;
+ uint32_t r21;
+ uint32_t r22;
+ uint32_t r23;
+ uint32_t gp;
+ uint32_t fp;
+ uint32_t sp;
+ uint32_t ra;
+ uint32_t et;
+ uint32_t ea;
+ uint32_t status;
+ uint32_t ienable;
+ uint32_t ipending;
+} CPU_Exception_frame;
+
+
+/**
+ * The following table contains the information required to configure
+ * the XXX processor specific parameters.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+typedef struct {
+ /** This element points to the BSP's pretasking hook. */
+ void (*pretasking_hook)( void );
+ /** This element points to the BSP's predriver hook. */
+ void (*predriver_hook)( void );
+ /** This element points to the BSP's postdriver hook. */
+ void (*postdriver_hook)( void );
+ /** This element points to the BSP's optional idle task which may override
+ * the default one provided with RTEMS.
+ */
+ void (*idle_task)( void );
+ /** If this element is TRUE, then RTEMS will zero the Executive Workspace.
+ * When this element is FALSE, it is assumed that the BSP or invoking
+ * environment has ensured that memory was cleared before RTEMS was
+ * invoked.
+ */
+ boolean do_zero_of_workspace;
+ /** This field specifies the size of the IDLE task's stack. If less than or
+ * equal to the minimum stack size, then the IDLE task will have the minimum
+ * stack size.
+ */
+ uint32_t idle_task_stack_size;
+ /** This field specifies the size of the interrupt stack. If less than or
+ * equal to the minimum stack size, then the interrupt stack will be of
+ * minimum stack size.
+ */
+ uint32_t interrupt_stack_size;
+ /** The MPCI Receive server is assumed to have a stack of at least
+ * minimum stack size. This field specifies the amount of extra
+ * stack this task will be given in bytes.
+ */
+ uint32_t extra_mpci_receive_server_stack;
+ /** The BSP may want to provide it's own stack allocation routines.
+ * In this case, the BSP will provide this stack allocation hook.
+ */
+ void * (*stack_allocate_hook)( uint32_t );
+ /** The BSP may want to provide it's own stack free routines.
+ * In this case, the BSP will provide this stack free hook.
+ */
+ void (*stack_free_hook)( void *);
+ /* end of fields required on all CPUs */
+} rtems_cpu_table;
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/*
+ * Macros to access NIOS2 specific additions to the CPU Table
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/* There are no CPU specific additions to the CPU Table for this port. */
+
+/**
+ * This variable is optional. It is used on CPUs on which it is difficult
+ * to generate an "uninitialized" FP context. It is filled in by
+ * @ref _CPU_Initialize and copied into the task's FP context area during
+ * @ref _CPU_Context_Initialize.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#if 0
+SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
+#endif
+
+/**
+ * @defgroup CPUInterrupt Processor Dependent Interrupt Management
+ *
+ * On some CPUs, RTEMS supports a software managed interrupt stack.
+ * This stack is allocated by the Interrupt Manager and the switch
+ * is performed in @ref _ISR_Handler. These variables contain pointers
+ * to the lowest and highest addresses in the chunk of memory allocated
+ * for the interrupt stack. Since it is unknown whether the stack
+ * grows up or down (in general), this give the CPU dependent
+ * code the option of picking the version it wants to use.
+ *
+ * @note These two variables are required if the macro
+ * @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/**
+ * @ingroup CPUInterrupt
+ * This variable points to the lowest physical address of the interrupt
+ * stack.
+ */
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+
+/**
+ * @ingroup CPUInterrupt
+ * This variable points to the lowest physical address of the interrupt
+ * stack.
+ */
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+/**
+ * @ingroup CPUInterrupt
+ * With some compilation systems, it is difficult if not impossible to
+ * call a high-level language routine from assembly language. This
+ * is especially true of commercial Ada compilers and name mangling
+ * C++ ones. This variable can be optionally defined by the CPU porter
+ * and contains the address of the routine @ref _Thread_Dispatch. This
+ * can make it easier to invoke that routine at the end of the interrupt
+ * sequence (if a dispatch is necessary).
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
+
+/*
+ * Nothing prevents the porter from declaring more CPU specific variables.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/* XXX: if needed, put more variables here */
+
+/**
+ * @ingroup CPUContext
+ * The size of the floating point context area. On some CPUs this
+ * will not be a "sizeof" because the format of the floating point
+ * area is not defined -- only the size is. This is usually on
+ * CPUs with a "floating point save context" instruction.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/**
+ * Amount of extra stack (above minimum stack size) required by
+ * MPCI receive server thread. Remember that in a multiprocessor
+ * system this thread must exist and be able to process all directives.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+/**
+ * @ingroup CPUInterrupt
+ * This defines the number of entries in the @ref _ISR_Vector_table managed
+ * by RTEMS.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 32
+
+/**
+ * @ingroup CPUInterrupt
+ * This defines the highest interrupt vector number for this port.
+ */
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
+
+/**
+ * @ingroup CPUInterrupt
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable @a _ISR_Nest_level.
+ */
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/**
+ * @ingroup CPUContext
+ * Should be large enough to run all RTEMS tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_STACK_MINIMUM_SIZE (1024*4)
+/* kawk: was *4 */
+
+/**
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_ALIGNMENT 4
+
+/**
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by @ref CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * @ref CPU_ALIGNMENT. If the @ref CPU_ALIGNMENT is strict enough for
+ * the heap, then this should be set to @ref CPU_ALIGNMENT.
+ *
+ * @note This does not have to be a power of 2 although it should be
+ * a multiple of 2 greater than or equal to 2. The requirement
+ * to be a multiple of 2 is because the heap uses the least
+ * significant field of the front and back flags to indicate
+ * that a block is in use or free. So you do not want any odd
+ * length blocks really putting length data in that bit.
+ *
+ * On byte oriented architectures, @ref CPU_HEAP_ALIGNMENT normally will
+ * have to be greater or equal to than @ref CPU_ALIGNMENT to ensure that
+ * elements allocated from the heap meet all restrictions.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+
+/**
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * @ref CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as @ref CPU_ALIGNMENT. If the @ref CPU_ALIGNMENT is
+ * strict enough for the partition, then this should be set to
+ * @ref CPU_ALIGNMENT.
+ *
+ * @note This does not have to be a power of 2. It does have to
+ * be greater or equal to than @ref CPU_ALIGNMENT.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/**
+ * This number corresponds to the byte alignment requirement for the
+ * stack. This alignment requirement may be stricter than that for the
+ * data types alignment specified by @ref CPU_ALIGNMENT. If the
+ * @ref CPU_ALIGNMENT is strict enough for the stack, then this should be
+ * set to 0.
+ *
+ * @note This must be a power of 2 either 0 or greater than @ref CPU_ALIGNMENT.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_STACK_ALIGNMENT 0
+
+/*
+ * ISR handler macros
+ */
+
+/**
+ * @ingroup CPUInterrupt
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_Initialize_vectors()
+
+/**
+ * @ingroup CPUInterrupt
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in @a _isr_cookie.
+ *
+ * @param _isr_cookie (out) will contain the previous level cookie
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_ISR_Disable( _isr_cookie ) \
+ { \
+ _isr_cookie = __builtin_rdctl(0); /* read status register */ \
+ __builtin_wrctl(0, 0); /* write 0 to status register */ \
+ }
+
+/**
+ * @ingroup CPUInterrupt
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * @a _isr_cookie is not modified.
+ *
+ * @param _isr_cookie (in) contain the previous level cookie
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_ISR_Enable( _isr_cookie ) \
+ { \
+ __builtin_wrctl( 0, _isr_cookie ); \
+ }
+
+/**
+ * @ingroup CPUInterrupt
+ * This temporarily restores the interrupt to @a _isr_cookie before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter @a _isr_cookie is not
+ * modified.
+ *
+ * @param _isr_cookie (in) contain the previous level cookie
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_ISR_Flash( _isr_cookie ) \
+ { \
+ __builtin_wrctl( 0, _isr_cookie ); \
+ /* TODO: Does NIOS2 get a chance to \
+ process IRQ between these statements? */ \
+ __builtin_wrctl( 0, 0 ); \
+ }
+
+/**
+ * @ingroup CPUInterrupt
+ *
+ * This routine and @ref _CPU_ISR_Get_level
+ * Map the interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a generic fashion are undefined. Someday,
+ * it would be nice if these were "mapped" by the application
+ * via a callout. For example, m68k has 8 levels 0 - 7, levels
+ * 8 - 255 would be available for bsp/application specific meaning.
+ * This could be used to manage a programmable interrupt controller
+ * via the rtems_task_mode directive.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_ISR_Set_level( new_level ) \
+ _CPU_ISR_Enable( ( new_level==0 ) ? 1 : 0 );
+
+/**
+ * @ingroup CPUInterrupt
+ * Return the current interrupt disable level for this task in
+ * the format used by the interrupt level portion of the task mode.
+ *
+ * @note This routine usually must be implemented as a subroutine.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+uint32_t _CPU_ISR_Get_level( void );
+
+/* end of ISR handler macros */
+
+/* Context handler macros */
+
+/**
+ * @ingroup CPUContext
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * This routine generally does not set any unnecessary register
+ * in the context. The state of the "general data" registers is
+ * undefined at task start time.
+ *
+ * @param _the_context (in) is the context structure to be initialized
+ * @param _stack_base (in) is the lowest physical address of this task's stack
+ * @param _size (in) is the size of this task's stack
+ * @param _isr (in) is the interrupt disable level
+ * @param _entry_point (in) is the thread's entry point. This is
+ * always @a _Thread_Handler
+ * @param _is_fp (in) is TRUE if the thread is to be a floating
+ * point thread. This is typically only used on CPUs where the
+ * FPU may be easily disabled by software such as on the SPARC
+ * where the PSR contains an enable FPU bit.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
+ _isr, _entry_point, _is_fp ) \
+ do { \
+ extern char _gp[]; \
+ uint32_t _stack = (uint32_t )(_stack_base) + (_size) - 4; \
+ (_the_context)->gp = (void *)_gp; \
+ (_the_context)->fp = (void *)_stack; \
+ (_the_context)->sp = (void *)_stack; \
+ (_the_context)->ra = (void *)(_entry_point); \
+ (_the_context)->status = 0x1; /* IRQs enabled */ \
+ } while ( 0 )
+
+/*
+ * This routine is responsible for somehow restarting the currently
+ * executing task. If you are lucky, then all that is necessary
+ * is restoring the context. Otherwise, there will need to be
+ * a special assembly routine which does something special in this
+ * case. @ref _CPU_Context_Restore should work most of the time. It will
+ * not work if restarting self conflicts with the stack frame
+ * assumptions of restoring a context.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+/**
+ * @ingroup CPUContext
+ * The purpose of this macro is to allow the initial pointer into
+ * a floating point context area (used to save the floating point
+ * context) to be at an arbitrary place in the floating point
+ * context area.
+ *
+ * This is necessary because some FP units are designed to have
+ * their context saved as a stack which grows into lower addresses.
+ * Other FP units can be saved by simply moving registers into offsets
+ * from the base of the context area. Finally some FP units provide
+ * a "dump context" instruction which could fill in from high to low
+ * or low to high based on the whim of the CPU designers.
+ *
+ * @param _base (in) is the lowest physical address of the floating point
+ * context area
+ * @param _offset (in) is the offset into the floating point area
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#if 1
+#define _CPU_Context_Fp_start( _base, _offset )
+#else
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
+#endif
+
+/**
+ * This routine initializes the FP context area passed to it to.
+ * There are a few standard ways in which to initialize the
+ * floating point context. The code included for this macro assumes
+ * that this is a CPU in which a "initial" FP context was saved into
+ * @a _CPU_Null_fp_context and it simply copies it to the destination
+ * context passed to it.
+ *
+ * Other floating point context save/restore models include:
+ * -# not doing anything, and
+ * -# putting a "null FP status word" in the correct place in the FP context.
+ *
+ * @param _destination (in) is the floating point context area
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#if 1
+#define _CPU_Context_Initialize_fp( _destination )
+#else
+#define _CPU_Context_Initialize_fp( _destination ) \
+ { \
+ *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
+ }
+#endif
+
+/* end of Context handler macros */
+
+/* Fatal Error manager macros */
+
+/**
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_Fatal_halt( _error ) \
+ { \
+ __builtin_wrctl(0, 0); /* write 0 to status register (disable interrupts) */ \
+ __asm volatile ("mov et, %z0" : : "rM" (_error)); /* write error code to ET register */ \
+ for(;;); \
+ }
+
+/* end of Fatal Error manager macros */
+
+/* Bitfield handler macros */
+
+/**
+ * @defgroup CPUBitfield Processor Dependent Bitfield Manipulation
+ *
+ * This set of routines are used to implement fast searches for
+ * the most important ready task.
+ */
+
+/**
+ * @ingroup CPUBitfield
+ * This definition is set to TRUE if the port uses the generic bitfield
+ * manipulation implementation.
+ */
+#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+
+/**
+ * @ingroup CPUBitfield
+ * This definition is set to TRUE if the port uses the data tables provided
+ * by the generic bitfield manipulation implementation.
+ * This can occur when actually using the generic bitfield manipulation
+ * implementation or when implementing the same algorithm in assembly
+ * language for improved performance. It is unlikely that a port will use
+ * the data if it has a bitfield scan instruction.
+ */
+#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
+
+/**
+ * @ingroup CPUBitfield
+ * This routine sets @a _output to the bit number of the first bit
+ * set in @a _value. @a _value is of CPU dependent type
+ * @a Priority_Bit_map_control. This type may be either 16 or 32 bits
+ * wide although only the 16 least significant bits will be used.
+ *
+ * There are a number of variables in using a "find first bit" type
+ * instruction.
+ *
+ * -# What happens when run on a value of zero?
+ * -# Bits may be numbered from MSB to LSB or vice-versa.
+ * -# The numbering may be zero or one based.
+ * -# The "find first bit" instruction may search from MSB or LSB.
+ *
+ * RTEMS guarantees that (1) will never happen so it is not a concern.
+ * (2),(3), (4) are handled by the macros @ref _CPU_Priority_Mask and
+ * @ref _CPU_Priority_bits_index. These three form a set of routines
+ * which must logically operate together. Bits in the _value are
+ * set and cleared based on masks built by @ref _CPU_Priority_Mask.
+ * The basic major and minor values calculated by @ref _Priority_Major
+ * and @ref _Priority_Minor are "massaged" by @ref _CPU_Priority_bits_index
+ * to properly range between the values returned by the "find first bit"
+ * instruction. This makes it possible for @ref _Priority_Get_highest to
+ * calculate the major and directly index into the minor table.
+ * This mapping is necessary to ensure that 0 (a high priority major/minor)
+ * is the first bit found.
+ *
+ * This entire "find first bit" and mapping process depends heavily
+ * on the manner in which a priority is broken into a major and minor
+ * components with the major being the 4 MSB of a priority and minor
+ * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
+ * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next
+ * to the lowest priority.
+ *
+ * If your CPU does not have a "find first bit" instruction, then
+ * there are ways to make do without it. Here are a handful of ways
+ * to implement this in software:
+ *
+@verbatim
+ - a series of 16 bit test instructions
+ - a "binary search using if's"
+ - _number = 0
+ if _value > 0x00ff
+ _value >>=8
+ _number = 8;
+
+ if _value > 0x0000f
+ _value >=8
+ _number += 4
+
+ _number += bit_set_table[ _value ]
+@endverbatim
+
+ * where bit_set_table[ 16 ] has values which indicate the first
+ * bit set
+ *
+ * @param _value (in) is the value to be scanned
+ * @param _output (in) is the first bit set
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ (_output) = 0; /* do something to prevent warnings */ \
+ }
+#endif
+
+/* end of Bitfield handler macros */
+
+/**
+ * This routine builds the mask which corresponds to the bit fields
+ * as searched by @ref _CPU_Bitfield_Find_first_bit. See the discussion
+ * for that routine.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_Mask( _bit_number ) \
+ ( 1 << (_bit_number) )
+
+#endif
+
+/**
+ * @ingroup CPUBitfield
+ * This routine translates the bit numbers returned by
+ * @ref _CPU_Bitfield_Find_first_bit into something suitable for use as
+ * a major or minor component of a priority. See the discussion
+ * for that routine.
+ *
+ * @param _priority (in) is the major or minor number to translate
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_bits_index( _priority ) \
+ (_priority)
+
+#endif
+
+/* end of Priority handler macros */
+
+/* functions */
+
+/**
+ * This routine performs CPU dependent initialization.
+ *
+ * @param cpu_table (in) is the CPU Dependent Configuration Table
+ * @param thread_dispatch (in) is the address of @ref _Thread_Dispatch
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/**
+ * @ingroup CPUInterrupt
+ * This routine installs a "raw" interrupt handler directly into the
+ * processor's vector table.
+ *
+ * @param vector (in) is the vector number
+ * @param new_handler (in) is the raw ISR handler to install
+ * @param old_handler (in) is the previously installed ISR Handler
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/**
+ * @ingroup CPUInterrupt
+ * This routine installs an interrupt vector.
+ *
+ * @param vector (in) is the vector number
+ * @param new_handler (in) is the RTEMS ISR handler to install
+ * @param old_handler (in) is the previously installed ISR Handler
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/**
+ * @ingroup CPUInterrupt
+ * This routine installs the hardware interrupt stack pointer.
+ *
+ * @note It need only be provided if @ref CPU_HAS_HARDWARE_INTERRUPT_STACK
+ * is TRUE.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Install_interrupt_stack( void );
+
+/**
+ * This routine is the CPU dependent IDLE thread body.
+ *
+ * @note It need only be provided if @ref CPU_PROVIDES_IDLE_THREAD_BODY
+ * is TRUE.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Thread_Idle_body( void );
+
+/**
+ * @ingroup CPUContext
+ * This routine switches from the run context to the heir context.
+ *
+ * @param run (in) points to the context of the currently executing task
+ * @param heir (in) points to the context of the heir task
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/**
+ * @ingroup CPUContext
+ * This routine is generally used only to restart self in an
+ * efficient manner. It may simply be a label in @ref _CPU_Context_switch.
+ *
+ * @param new_context (in) points to the context to be restored.
+ *
+ * @note May be unnecessary to reload some registers.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/**
+ * @ingroup CPUContext
+ * This routine saves the floating point context passed to it.
+ *
+ * @param fp_context_ptr (in) is a pointer to a pointer to a floating
+ * point context area
+ *
+ * @return on output @a *fp_context_ptr will contain the address that
+ * should be used with @ref _CPU_Context_restore_fp to restore this context.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/**
+ * @ingroup CPUContext
+ * This routine restores the floating point context passed to it.
+ *
+ * @param fp_context_ptr (in) is a pointer to a pointer to a floating
+ * point context area to restore
+ *
+ * @return on output @a *fp_context_ptr will contain the address that
+ * should be used with @ref _CPU_Context_save_fp to save this context.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+/**
+ * @ingroup CPUEndian
+ * The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * This version will work on any processor, but if there is a better
+ * way for your CPU PLEASE use it. The most common way to do this is to:
+ *
+ * swap least significant two bytes with 16-bit rotate
+ * swap upper and lower 16-bits
+ * swap most significant two bytes with 16-bit rotate
+ *
+ * Some CPUs have special instructions which swap a 32-bit quantity in
+ * a single instruction (e.g. i486). It is probably best to avoid
+ * an "endian swapping control bit" in the CPU. One good reason is
+ * that interrupts would probably have to be disabled to insure that
+ * an interrupt does not try to access the same "chunk" with the wrong
+ * endian. Another good reason is that on some CPUs, the endian bit
+ * endianness for ALL fetches -- both code and data -- so the code
+ * will be fetched incorrectly.
+ *
+ * @param value (in) is the value to be swapped
+ * @return the value after being endian swapped
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+static inline uint32_t CPU_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t byte1, byte2, byte3, byte4, swapped;
+
+ byte4 = (value >> 24) & 0xff;
+ byte3 = (value >> 16) & 0xff;
+ byte2 = (value >> 8) & 0xff;
+ byte1 = value & 0xff;
+
+ swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
+ return( swapped );
+}
+
+/**
+ * @ingroup CPUEndian
+ * This routine swaps a 16 bir quantity.
+ *
+ * @param value (in) is the value to be swapped
+ * @return the value after being endian swapped
+ */
+#define CPU_swap_u16( value ) \
+ (((value&0xff) << 8) | ((value >> 8)&0xff))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/nios2/rtems/score/cpu_asm.h b/cpukit/score/cpu/nios2/rtems/score/cpu_asm.h
new file mode 100644
index 0000000000..7d6a8fe809
--- /dev/null
+++ b/cpukit/score/cpu/nios2/rtems/score/cpu_asm.h
@@ -0,0 +1,74 @@
+/**
+ * @file rtems/score/cpu_asm.h
+ */
+
+/*
+ * Very loose template for an include file for the cpu_asm.? file
+ * if it is implemented as a ".S" file (preprocessed by cpp) instead
+ * of a ".s" file (preprocessed by gm4 or gasp).
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef _RTEMS_SCORE_CPU_ASM_H
+#define _RTEMS_SCORE_CPU_ASM_H
+
+/* pull in the generated offsets */
+
+/*
+#include <rtems/score/offsets.h>
+*/
+
+/*
+ * Hardware General Registers
+ */
+
+/* put something here */
+
+/*
+ * Hardware Floating Point Registers
+ */
+
+/* put something here */
+
+/*
+ * Hardware Control Registers
+ */
+
+/* put something here */
+
+/*
+ * Calling Convention
+ */
+
+/* put something here */
+
+/*
+ * Temporary registers
+ */
+
+/* put something here */
+
+/*
+ * Floating Point Registers - SW Conventions
+ */
+
+/* put something here */
+
+/*
+ * Temporary floating point registers
+ */
+
+/* put something here */
+
+#endif
+
+/* end of file */
diff --git a/cpukit/score/cpu/nios2/rtems/score/nios2.h b/cpukit/score/cpu/nios2/rtems/score/nios2.h
new file mode 100644
index 0000000000..abd52cad5c
--- /dev/null
+++ b/cpukit/score/cpu/nios2/rtems/score/nios2.h
@@ -0,0 +1,62 @@
+/* nios2.h
+ *
+ * This file sets up basic CPU dependency settings based on
+ * compiler settings. For example, it can determine if
+ * floating point is available. This particular implementation
+ * is specific to the NIOS2 port.
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef _RTEMS_SCORE_NIOS2_H
+#define _RTEMS_SCORE_NIOS2_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the NIOS2 family.
+ * It does this by setting variables to indicate which
+ * implementation dependent features are present in a particular
+ * member of the family.
+ *
+ * This is a good place to list all the known CPU models
+ * that this port supports and which RTEMS CPU model they correspond
+ * to.
+ */
+
+/*
+ * Define the name of the CPU family and specific model.
+ */
+
+#define CPU_NAME "NIOS2"
+#define CPU_MODEL_NAME "nios2"
+
+/*
+ * See also nios2-rtems-gcc -print-multi-lib for all valid combinations of
+ *
+ * -mno-hw-mul
+ * -mhw-mulx
+ * -mstack-check
+ * -pg
+ * -EB
+ * -mcustom-fpu-cfg=60-1
+ * -mcustom-fpu-cfg=60-2
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_NIOS2_H */
diff --git a/cpukit/score/cpu/nios2/rtems/score/types.h b/cpukit/score/cpu/nios2/rtems/score/types.h
new file mode 100644
index 0000000000..17ffaf5f5f
--- /dev/null
+++ b/cpukit/score/cpu/nios2/rtems/score/types.h
@@ -0,0 +1,54 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains type definitions pertaining to the
+ * Altera Nios II processor family.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+
+typedef uint16_t Priority_Bit_map_control;
+
+typedef signed long long signed64; /* 64 bit signed integer */
+
+typedef uint32_t boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void nios2_isr;
+typedef void ( *nios2_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/no_cpu/.cvsignore b/cpukit/score/cpu/no_cpu/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/no_cpu/ChangeLog b/cpukit/score/cpu/no_cpu/ChangeLog
new file mode 100644
index 0000000000..dbc5ba076b
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/ChangeLog
@@ -0,0 +1,301 @@
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/asm.h, rtems/score/cpu.h, rtems/score/types.h: Part of a large
+ patch to improve Doxygen output. As a side-effect, grammar and
+ spelling errors were corrected, spacing errors were address, and some
+ variable names were improved.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16, unsigned32.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h: Remove private version of CONCAT macros.
+ Include <rtems/concat.h> instead.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/cpu.h, rtems/score/cpu_asm.h,
+ rtems/score/no_cpu.h, rtems/score/types.h: New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: *_swap_u32( uint32_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: #include <rtems/stdint.h>.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove build-variant support.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Use __rtems_score_types_h as preprocessor
+ guard.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * asm.h: Add doxygen preamble.
+
+2004-10-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Add doxygen preamble.
+ * rtems/score/cpu_asm.h: Add doxygen preamble.
+ * rtems/score/types.h: Add doxygen preamble.
+
+2004-09-29 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: i960 obsoleted and all references removed.
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Remove (Merged into$(top_srcdir)/configure.ac).
+ * Makefile.am: Don't include multilib.am.
+ Reflect merging configure.ac into $(top_srcdir)/configure.ac.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Install asm.h to $(includedir)/rtems.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu.c, rtems/score/cpu.h: Convert to using c99 fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: RTEMS_TOP([../../../..]).
+
+2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Move RTEMS_TOP one subdir down.
+
+2004-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add PREINSTALL_DIRS.
+
+2004-01-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Re-add dirstamps to PREINSTALL_FILES.
+ Add PREINSTALL_FILES to CLEANFILES.
+
+2004-01-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Requires automake >= 1.8.1.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, again.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Convert to using automake compilation rules.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use mkdir_p. Remove dirs from PREINSTALL_FILES.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require automake >= 1.8, autoconf >= 2.59.
+
+2003-12-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Remove TMPINSTALL_FILES.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Don't use gmake rules for preinstallation.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CANONICAL_HOST.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CPU.
+
+2003-09-26 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Obsoleting HP PA-RISC port and removing all
+ references.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, cpu_asm.c, rtems/score/cpu.h, rtems/score/cpu_asm.h,
+ rtems/score/no_cpu.h, rtems/score/types.h: URL for license changed.
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+
+2003-02-11 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu_asm.c: Rework logic that decides when to call
+ _Thread_Dispatch. Analysis by Sergei Organov <osv@javad.ru>
+ determined that _ISR_Signals_to_thread_executing was not being
+ honored and/or cleared properly.
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require autoconf-2.57 + automake-1.7.2.
+ * Makefile.am: Eliminate C_O_FILES, S_O_FILES, libscorecpu_a_OBJECTS.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix package name.
+
+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-07-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use .$(OBJEXT) instead of .o.
+
+2002-07-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: RTEMS_TOP(../../../..).
+
+2002-07-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems.c: Remove.
+ * Makefile.am: Reflect changes above.
+
+2002-07-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_PROJECT_ROOT.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add RTEMS_PROG_CCAS
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AC_CONFIG_AUX_DIR(../../../..).
+ Add AC_PROG_RANLIB.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/../../../automake/*.am.
+ Use ../../../aclocal.
+
+2001-04-03 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
+ * rtems/score/no_cputypes.h: Removed.
+ * rtems/score/types.h: New file via CVS magic.
+ * Makefile.am, 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.
+
+2002-01-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/Makefile.am: Removed.
+ * rtems/score/Makefile.am: Removed.
+ * configure.ac: Reflect changes above.
+ * Makefile.am: Reflect changes above.
+
+2001-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add multilib support.
+
+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.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/Makefile.am: Use 'PREINSTALL_FILES ='.
+ * Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, rtems/score/Makefile.am:
+ Apply include_*HEADERS instead of H_FILES.
+
+2001-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Added _CPU_Initialize_vectors().
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
+ Switch to GNU canonicalization.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am.
+
+2000-08-25 Joel Sherrill <joel.sherrill@OARcorp.com>
+
+ * rtems/score/no_cpu.h: Modified so there are fewer and
+ more consistent variations on "no cpu" so it is easier
+ to sed the source as the starting point for a new port.
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: New file.
diff --git a/cpukit/score/cpu/no_cpu/Makefile.am b/cpukit/score/cpu/no_cpu/Makefile.am
new file mode 100644
index 0000000000..1c74eb72f4
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/Makefile.am
@@ -0,0 +1,19 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/no_cpu.h \
+ rtems/score/cpu_asm.h rtems/score/types.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c cpu_asm.c
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/no_cpu/cpu.c b/cpukit/score/cpu/no_cpu/cpu.c
new file mode 100644
index 0000000000..2796c707ea
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/cpu.c
@@ -0,0 +1,185 @@
+/*
+ * XXX CPU Dependent Source
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/wkspace.h>
+
+/* _CPU_Initialize
+ *
+ * This routine performs processor dependent initialization.
+ *
+ * INPUT PARAMETERS:
+ * cpu_table - CPU table to initialize
+ * thread_dispatch - address of disptaching routine
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch) /* ignored on this CPU */
+)
+{
+ /*
+ * The thread_dispatch argument is the address of the entry point
+ * for the routine called at the end of an ISR once it has been
+ * decided a context switch is necessary. On some compilation
+ * systems it is difficult to call a high-level language routine
+ * from assembly. This allows us to trick these systems.
+ *
+ * If you encounter this problem save the entry point in a CPU
+ * dependent variable.
+ */
+
+ _CPU_Thread_dispatch_pointer = thread_dispatch;
+
+ /*
+ * If there is not an easy way to initialize the FP context
+ * during Context_Initialize, then it is usually easier to
+ * save an "uninitialized" FP context here and copy it to
+ * the task's during Context_Initialize.
+ */
+
+ /* FP context initialization support goes here */
+
+ _CPU_Table = *cpu_table;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Get_level
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ /*
+ * This routine returns the current interrupt level.
+ */
+
+ return 0;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_install_raw_handler
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ /*
+ * This is where we install the interrupt handler into the "raw" interrupt
+ * table used by the CPU to dispatch interrupt handlers.
+ */
+}
+
+/*PAGE
+ *
+ * _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
+ *
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ *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.
+ */
+
+ _CPU_ISR_install_raw_handler( vector, new_handler, old_handler );
+
+ /*
+ * 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;
+}
+
+/*PAGE
+ *
+ * _CPU_Install_interrupt_stack
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Install_interrupt_stack( void )
+{
+}
+
+/*PAGE
+ *
+ * _CPU_Thread_Idle_body
+ *
+ * NOTES:
+ *
+ * 1. This is the same as the regular CPU independent algorithm.
+ *
+ * 2. If you implement this using a "halt", "idle", or "shutdown"
+ * instruction, then don't forget to put it in an infinite loop.
+ *
+ * 3. Be warned. Some processors with onboard DMA have been known
+ * to stop the DMA if the CPU were put in IDLE mode. This might
+ * also be a problem with other on-chip peripherals. So use this
+ * hook with caution.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Thread_Idle_body( void )
+{
+
+ for( ; ; )
+ /* insert your "halt" instruction here */ ;
+}
diff --git a/cpukit/score/cpu/no_cpu/cpu_asm.c b/cpukit/score/cpu/no_cpu/cpu_asm.c
new file mode 100644
index 0000000000..2ca67a07ad
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/cpu_asm.c
@@ -0,0 +1,182 @@
+/* cpu_asm.c ===> cpu_asm.S or cpu_asm.s
+ *
+ * This file contains the basic algorithms for all assembly code used
+ * in an specific CPU port of RTEMS. These algorithms must be implemented
+ * in assembly language
+ *
+ * NOTE: This is supposed to be a .S or .s file NOT a C file.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+/*
+ * This is supposed to be an assembly file. This means that system.h
+ * and cpu.h should not be included in a "real" cpu_asm file. An
+ * implementation in assembly should include "cpu_asm.h>
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/cpu.h>
+/* #include "cpu_asm.h> */
+
+/*
+ * _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.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+)
+{
+}
+
+/*
+ * _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.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+)
+{
+}
+
+/* _CPU_Context_switch
+ *
+ * This routine performs a normal non-FP context switch.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+)
+{
+}
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally 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.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+)
+{
+}
+
+/* void __ISR_Handler()
+ *
+ * This routine provides the RTEMS interrupt management.
+ *
+ * NO_CPU Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+void _ISR_Handler()
+{
+ /*
+ * This discussion ignores a lot of the ugly details in a real
+ * implementation such as saving enough registers/state to be
+ * able to do something real. Keep in mind that the goal is
+ * to invoke a user's ISR handler which is written in C and
+ * uses a certain set of registers.
+ *
+ * Also note that the exact order is to a large extent flexible.
+ * Hardware will dictate a sequence for a certain subset of
+ * _ISR_Handler while requirements for setting
+ */
+
+ /*
+ * At entry to "common" _ISR_Handler, the vector number must be
+ * available. On some CPUs the hardware puts either the vector
+ * number or the offset into the vector table for this ISR in a
+ * known place. If the hardware does not give us this information,
+ * then the assembly portion of RTEMS for this port will contain
+ * a set of distinct interrupt entry points which somehow place
+ * the vector number in a known place (which is safe if another
+ * interrupt nests this one) and branches to _ISR_Handler.
+ *
+ * save some or all context on stack
+ * may need to save some special interrupt information for exit
+ *
+ * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
+ * if ( _ISR_Nest_level == 0 )
+ * switch to software interrupt stack
+ * #endif
+ *
+ * _ISR_Nest_level++;
+ *
+ * _Thread_Dispatch_disable_level++;
+ *
+ * (*_ISR_Vector_table[ vector ])( vector );
+ *
+ * _Thread_Dispatch_disable_level--;
+ *
+ * --_ISR_Nest_level;
+ *
+ * if ( _ISR_Nest_level )
+ * goto the label "exit interrupt (simple case)"
+ *
+ * if ( _Thread_Dispatch_disable_level )
+ * _ISR_Signals_to_thread_executing = FALSE;
+ * goto the label "exit interrupt (simple case)"
+ *
+ * if ( _Context_Switch_necessary || _ISR_Signals_to_thread_executing ) {
+ * _ISR_Signals_to_thread_executing = FALSE;
+ * call _Thread_Dispatch() or prepare to return to _ISR_Dispatch
+ * prepare to get out of interrupt
+ * return from interrupt (maybe to _ISR_Dispatch)
+ *
+ * LABEL "exit interrupt (simple case):
+ * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
+ * if outermost interrupt
+ * restore stack
+ * #endif
+ * prepare to get out of interrupt
+ * return from interrupt
+ */
+}
diff --git a/cpukit/score/cpu/no_cpu/preinstall.am b/cpukit/score/cpu/no_cpu/preinstall.am
new file mode 100644
index 0000000000..75e46c0ddd
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/preinstall.am
@@ -0,0 +1,45 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/no_cpu.h: rtems/score/no_cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/no_cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/no_cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/cpu_asm.h: rtems/score/cpu_asm.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
diff --git a/cpukit/score/cpu/no_cpu/rtems/asm.h b/cpukit/score/cpu/no_cpu/rtems/asm.h
new file mode 100644
index 0000000000..7dd89312b7
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/rtems/asm.h
@@ -0,0 +1,125 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ */
+
+/*
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ * COPYRIGHT (c) 1994-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/no_cpu.h>
+
+#ifndef __USER_LABEL_PREFIX__
+/**
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ *
+ * This symbol is prefixed to all C program symbols.
+ */
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+/**
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ *
+ * This symbol is prefixed to all register names.
+ */
+#define __REGISTER_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/** Use the right prefix for global labels. */
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/** Use the right prefix for registers. */
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/*
+ * define macros for all of the registers on this CPU
+ *
+ * EXAMPLE: #define d0 REG (d0)
+ */
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+/** This macro is used to denote the beginning of a code declaration. */
+#define BEGIN_CODE_DCL .text
+/** This macro is used to denote the end of a code declaration. */
+#define END_CODE_DCL
+/** This macro is used to denote the beginning of a data declaration section. */
+#define BEGIN_DATA_DCL .data
+/** This macro is used to denote the end of a data declaration section. */
+#define END_DATA_DCL
+/** This macro is used to denote the beginning of a code section. */
+#define BEGIN_CODE .text
+/** This macro is used to denote the end of a code section. */
+#define END_CODE
+/** This macro is used to denote the beginning of a data section. */
+#define BEGIN_DATA
+/** This macro is used to denote the end of a data section. */
+#define END_DATA
+/** This macro is used to denote the beginning of the
+ * unitialized data section.
+ */
+#define BEGIN_BSS
+/** This macro is used to denote the end of the unitialized data section. */
+#define END_BSS
+/** This macro is used to denote the end of the assembly file. */
+#define END
+
+/**
+ * This macro is used to declare a public global symbol.
+ *
+ * @note This must be tailored for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+#define PUBLIC(sym) .globl SYM (sym)
+
+/**
+ * This macro is used to prototype a public global symbol.
+ *
+ * @note This must be tailored for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+#define EXTERN(sym) .globl SYM (sym)
+
+#endif
diff --git a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
new file mode 100644
index 0000000000..eaef597df5
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
@@ -0,0 +1,1325 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * This include file contains information pertaining to the XXX
+ * processor.
+ *
+ * @note This file is part of a porting template that is intended
+ * to be used as the starting point when porting RTEMS to a new
+ * CPU family. The following needs to be done when using this as
+ * the starting point for a new port:
+ *
+ * + Anywhere there is an XXX, it should be replaced
+ * with information about the CPU family being ported to.
+ *
+ * + At the end of each comment section, there is a heading which
+ * says "Port Specific Information:". When porting to RTEMS,
+ * add CPU family specific information in this section
+ */
+
+/* COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/no_cpu.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+
+/* conditional compilation parameters */
+
+/**
+ * Should the calls to @ref _Thread_Enable_dispatch be inlined?
+ *
+ * If TRUE, then they are inlined.
+ * If FALSE, then a subroutine call is made.
+ *
+ * This conditional is an example of the classic trade-off of size
+ * versus speed. Inlining the call (TRUE) typically increases the
+ * size of RTEMS while speeding up the enabling of dispatching.
+ *
+ * @note In general, the @ref _Thread_Dispatch_disable_level will
+ * only be 0 or 1 unless you are in an interrupt handler and that
+ * interrupt handler invokes the executive.] When not inlined
+ * something calls @ref _Thread_Enable_dispatch which in turns calls
+ * @ref _Thread_Dispatch. If the enable dispatch is inlined, then
+ * one subroutine call is avoided entirely.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_INLINE_ENABLE_DISPATCH FALSE
+
+/**
+ * Should the body of the search loops in _Thread_queue_Enqueue_priority
+ * be unrolled one time? In unrolled each iteration of the loop examines
+ * two "nodes" on the chain being searched. Otherwise, only one node
+ * is examined per iteration.
+ *
+ * If TRUE, then the loops are unrolled.
+ * If FALSE, then the loops are not unrolled.
+ *
+ * The primary factor in making this decision is the cost of disabling
+ * and enabling interrupts (_ISR_Flash) versus the cost of rest of the
+ * body of the loop. On some CPUs, the flash is more expensive than
+ * one iteration of the loop body. In this case, it might be desirable
+ * to unroll the loop. It is important to note that on some CPUs, this
+ * code is the longest interrupt disable period in RTEMS. So it is
+ * necessary to strike a balance when setting this parameter.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
+
+/**
+ * Does RTEMS manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in @ref _ISR_Handler_initialization.
+ * If FALSE, nothing is done.
+ *
+ * If the CPU supports a dedicated interrupt stack in hardware,
+ * then it is generally the responsibility of the BSP to allocate it
+ * and set it up.
+ *
+ * If the CPU does not support a dedicated interrupt stack, then
+ * the porter has two options: (1) execute interrupts on the
+ * stack of the interrupted task, and (2) have RTEMS manage a dedicated
+ * interrupt stack.
+ *
+ * If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * @ref CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
+
+/**
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * If TRUE, then it must be installed during initialization.
+ * If FALSE, then no installation is performed.
+ *
+ * If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * @ref CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
+
+/**
+ * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * If TRUE, then the memory is allocated during initialization.
+ * If FALSE, then the memory is allocated during initialization.
+ *
+ * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
+
+/**
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_ISR_PASSES_FRAME_POINTER 0
+
+/**
+ * @def CPU_HARDWARE_FP
+ *
+ * Does the CPU have hardware floating point?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
+ *
+ * If there is a FP coprocessor such as the i387 or mc68881, then
+ * the answer is TRUE.
+ *
+ * The macro name "NO_CPU_HAS_FPU" should be made CPU specific.
+ * It indicates whether or not this CPU model has FP support. For
+ * example, it would be possible to have an i386_nofp CPU model
+ * which set this to false to indicate that you have an i386 without
+ * an i387 and wish to leave floating point support out of RTEMS.
+ */
+
+/**
+ * @def CPU_SOFTWARE_FP
+ *
+ * Does the CPU have no hardware floating point and GCC provides a
+ * software floating point implementation which must be context
+ * switched?
+ *
+ * This feature conditional is used to indicate whether or not there
+ * is software implemented floating point that must be context
+ * switched. The determination of whether or not this applies
+ * is very tool specific and the state saved/restored is also
+ * compiler specific.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#if ( NO_CPU_HAS_FPU == 1 )
+#define CPU_HARDWARE_FP TRUE
+#else
+#define CPU_HARDWARE_FP FALSE
+#endif
+#define CPU_SOFTWARE_FP FALSE
+
+/**
+ * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
+ *
+ * So far, the only CPUs in which this option has been used are the
+ * HP PA-RISC and PowerPC. On the PA-RISC, The HP C compiler and
+ * gcc both implicitly used the floating point registers to perform
+ * integer multiplies. Similarly, the PowerPC port of gcc has been
+ * seen to allocate floating point local variables and touch the FPU
+ * even when the flow through a subroutine (like vfprintf()) might
+ * not use floating point formats.
+ *
+ * If a function which you would not think utilize the FP unit DOES,
+ * then one can not easily predict which tasks will use the FP hardware.
+ * In this case, this option should be TRUE.
+ *
+ * If @ref CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_ALL_TASKS_ARE_FP TRUE
+
+/**
+ * Should the IDLE task have a floating point context?
+ *
+ * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * If FALSE, then the IDLE task does not have a floating point context.
+ *
+ * Setting this to TRUE negatively impacts the time required to preempt
+ * the IDLE task from an interrupt because the floating point context
+ * must be saved as part of the preemption.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+/**
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ *
+ * If the floating point context does NOT have to be saved as part of
+ * interrupt dispatching, then it should be safe to set this to TRUE.
+ *
+ * Setting this flag to TRUE results in using a different algorithm
+ * for deciding when to save and restore the floating point context.
+ * The deferred FP switch algorithm minimizes the number of times
+ * the FP context is saved and restored. The FP context is not saved
+ * until a context switch is made to another, different FP task.
+ * Thus in a system with only one FP task, the FP context will never
+ * be saved or restored.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+/**
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine @ref _CPU_Thread_Idle_body
+ * must be provided and is the default IDLE thread body instead of
+ * @ref _CPU_Thread_Idle_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ *
+ * This is intended to allow for supporting processors which have
+ * a low power or idle mode. When the IDLE thread is executed, then
+ * the CPU can be powered down.
+ *
+ * The order of precedence for selecting the IDLE thread body is:
+ *
+ * -# BSP provided
+ * -# CPU dependent (if provided)
+ * -# generic (if no BSP and no CPU dependent)
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE
+
+/**
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * If TRUE, then the grows upward.
+ * If FALSE, then the grows toward smaller addresses.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_STACK_GROWS_UP TRUE
+
+/**
+ * The following is the variable attribute used to force alignment
+ * of critical RTEMS structures. On some processors it may make
+ * sense to have these aligned on tighter boundaries than
+ * the minimum requirements of the compiler in order to have as
+ * much of the critical data area as possible in a cache line.
+ *
+ * The placement of this macro in the declaration of the variables
+ * is based on the syntactically requirements of the GNU C
+ * "__attribute__" extension. For example with GNU C, use
+ * the following to force a structures to a 32 byte boundary.
+ *
+ * __attribute__ ((aligned (32)))
+ *
+ * @note Currently only the Priority Bit Map table uses this feature.
+ * To benefit from using this, the data must be heavily
+ * used so it will stay in the cache and used frequently enough
+ * in the executive to justify turning this on.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_STRUCTURE_ALIGNMENT
+
+/**
+ * @defgroup CPUEndian Processor Dependent Endianness Support
+ *
+ * This group assists in issues related to processor endianness.
+ */
+
+/**
+ * @ingroup CPUEndian
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ *
+ * @note @a CPU_BIG_ENDIAN and @a CPU_LITTLE_ENDIAN should NOT have the
+ * same values.
+ *
+ * @see CPU_LITTLE_ENDIAN
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_BIG_ENDIAN TRUE
+
+/**
+ * @ingroup CPUEndian
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ *
+ * @note @ref CPU_BIG_ENDIAN and @ref CPU_LITTLE_ENDIAN should NOT have the
+ * same values.
+ *
+ * @see CPU_BIG_ENDIAN
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_LITTLE_ENDIAN FALSE
+
+/**
+ * @ingroup CPUInterrupt
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine @ref _CPU_ISR_Set_level.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_MODES_INTERRUPT_MASK 0x00000001
+
+/*
+ * Processor defined structures required for cpukit/score.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/* may need to put some structures here. */
+
+/**
+ * @defgroup CPUContext Processor Dependent Context Management
+ *
+ * From the highest level viewpoint, there are 2 types of context to save.
+ *
+ * -# Interrupt registers to save
+ * -# Task level registers to save
+ *
+ * Since RTEMS handles integer and floating point contexts separately, this
+ * means we have the following 3 context items:
+ *
+ * -# task level context stuff:: Context_Control
+ * -# floating point task stuff:: Context_Control_fp
+ * -# special interrupt level context :: CPU_Interrupt_frame
+ *
+ * On some processors, it is cost-effective to save only the callee
+ * preserved registers during a task context switch. This means
+ * that the ISR code needs to save those registers which do not
+ * persist across function calls. It is not mandatory to make this
+ * distinctions between the caller/callee saves registers for the
+ * purpose of minimizing context saved during task switch and on interrupts.
+ * If the cost of saving extra registers is minimal, simplicity is the
+ * choice. Save the same context on interrupt entry as for tasks in
+ * this case.
+ *
+ * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
+ * care should be used in designing the context area.
+ *
+ * On some CPUs with hardware floating point support, the Context_Control_fp
+ * structure will not be used or it simply consist of an array of a
+ * fixed number of bytes. This is done when the floating point context
+ * is dumped by a "FP save context" type instruction and the format
+ * is not really defined by the CPU. In this case, there is no need
+ * to figure out the exact format -- only the size. Of course, although
+ * this is enough information for RTEMS, it is probably not enough for
+ * a debugger such as gdb. But that is another problem.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/**
+ * @ingroup CPUContext Management
+ * This defines the minimal set of integer and processor state registers
+ * that must be saved during a voluntary context switch from one thread
+ * to another.
+ */
+typedef struct {
+ /** This field is a hint that a port will have a number of integer
+ * registers that need to be saved at a context switch.
+ */
+ uint32_t some_integer_register;
+ /** This field is a hint that a port will have a number of system
+ * registers that need to be saved at a context switch.
+ */
+ uint32_t some_system_register;
+} Context_Control;
+
+/**
+ * @ingroup CPUContext Management
+ * This defines the complete set of floating point registers that must
+ * be saved during any context switch from one thread to another.
+ */
+typedef struct {
+ /** FPU registers are listed here */
+ double some_float_register;
+} Context_Control_fp;
+
+/**
+ * @ingroup CPUContext Management
+ * This defines the set of integer and processor state registers that must
+ * be saved during an interrupt. This set does not include any which are
+ * in @ref Context_Control.
+ */
+typedef struct {
+ /** This field is a hint that a port will have a number of integer
+ * registers that need to be saved when an interrupt occurs or
+ * when a context switch occurs at the end of an ISR.
+ */
+ uint32_t special_interrupt_register;
+} CPU_Interrupt_frame;
+
+
+/**
+ * The following table contains the information required to configure
+ * the XXX processor specific parameters.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+typedef struct {
+ /** This element points to the BSP's pretasking hook. */
+ void (*pretasking_hook)( void );
+ /** This element points to the BSP's predriver hook. */
+ void (*predriver_hook)( void );
+ /** This element points to the BSP's postdriver hook. */
+ void (*postdriver_hook)( void );
+ /** This element points to the BSP's optional idle task which may override
+ * the default one provided with RTEMS.
+ */
+ void (*idle_task)( void );
+ /** If this element is TRUE, then RTEMS will zero the Executive Workspace.
+ * When this element is FALSE, it is assumed that the BSP or invoking
+ * environment has ensured that memory was cleared before RTEMS was
+ * invoked.
+ */
+ boolean do_zero_of_workspace;
+ /** This field specifies the size of the IDLE task's stack. If less than or
+ * equal to the minimum stack size, then the IDLE task will have the minimum
+ * stack size.
+ */
+ uint32_t idle_task_stack_size;
+ /** This field specifies the size of the interrupt stack. If less than or
+ * equal to the minimum stack size, then the interrupt stack will be of
+ * minimum stack size.
+ */
+ uint32_t interrupt_stack_size;
+ /** The MPCI Receive server is assumed to have a stack of at least
+ * minimum stack size. This field specifies the amount of extra
+ * stack this task will be given in bytes.
+ */
+ uint32_t extra_mpci_receive_server_stack;
+ /** The BSP may want to provide it's own stack allocation routines.
+ * In this case, the BSP will provide this stack allocation hook.
+ */
+ void * (*stack_allocate_hook)( uint32_t );
+ /** The BSP may want to provide it's own stack free routines.
+ * In this case, the BSP will provide this stack free hook.
+ */
+ void (*stack_free_hook)( void *);
+ /* end of fields required on all CPUs */
+} rtems_cpu_table;
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/*
+ * Macros to access NO_CPU specific additions to the CPU Table
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/* There are no CPU specific additions to the CPU Table for this port. */
+
+/**
+ * This variable is optional. It is used on CPUs on which it is difficult
+ * to generate an "uninitialized" FP context. It is filled in by
+ * @ref _CPU_Initialize and copied into the task's FP context area during
+ * @ref _CPU_Context_Initialize.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
+
+/**
+ * @defgroup CPUInterrupt Processor Dependent Interrupt Management
+ *
+ * On some CPUs, RTEMS supports a software managed interrupt stack.
+ * This stack is allocated by the Interrupt Manager and the switch
+ * is performed in @ref _ISR_Handler. These variables contain pointers
+ * to the lowest and highest addresses in the chunk of memory allocated
+ * for the interrupt stack. Since it is unknown whether the stack
+ * grows up or down (in general), this give the CPU dependent
+ * code the option of picking the version it wants to use.
+ *
+ * @note These two variables are required if the macro
+ * @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/**
+ * @ingroup CPUInterrupt
+ * This variable points to the lowest physical address of the interrupt
+ * stack.
+ */
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+
+/**
+ * @ingroup CPUInterrupt
+ * This variable points to the lowest physical address of the interrupt
+ * stack.
+ */
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+/**
+ * @ingroup CPUInterrupt
+ * With some compilation systems, it is difficult if not impossible to
+ * call a high-level language routine from assembly language. This
+ * is especially true of commercial Ada compilers and name mangling
+ * C++ ones. This variable can be optionally defined by the CPU porter
+ * and contains the address of the routine @ref _Thread_Dispatch. This
+ * can make it easier to invoke that routine at the end of the interrupt
+ * sequence (if a dispatch is necessary).
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
+
+/*
+ * Nothing prevents the porter from declaring more CPU specific variables.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+/* XXX: if needed, put more variables here */
+
+/**
+ * @ingroup CPUContext
+ * The size of the floating point context area. On some CPUs this
+ * will not be a "sizeof" because the format of the floating point
+ * area is not defined -- only the size is. This is usually on
+ * CPUs with a "floating point save context" instruction.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/**
+ * Amount of extra stack (above minimum stack size) required by
+ * MPCI receive server thread. Remember that in a multiprocessor
+ * system this thread must exist and be able to process all directives.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+/**
+ * @ingroup CPUInterrupt
+ * This defines the number of entries in the @ref _ISR_Vector_table managed
+ * by RTEMS.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 32
+
+/**
+ * @ingroup CPUInterrupt
+ * This defines the highest interrupt vector number for this port.
+ */
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
+
+/**
+ * @ingroup CPUInterrupt
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable @a _ISR_Nest_level.
+ */
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/**
+ * @ingroup CPUContext
+ * Should be large enough to run all RTEMS tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_STACK_MINIMUM_SIZE (1024*4)
+
+/**
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_ALIGNMENT 8
+
+/**
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by @ref CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * @ref CPU_ALIGNMENT. If the @ref CPU_ALIGNMENT is strict enough for
+ * the heap, then this should be set to @ref CPU_ALIGNMENT.
+ *
+ * @note This does not have to be a power of 2 although it should be
+ * a multiple of 2 greater than or equal to 2. The requirement
+ * to be a multiple of 2 is because the heap uses the least
+ * significant field of the front and back flags to indicate
+ * that a block is in use or free. So you do not want any odd
+ * length blocks really putting length data in that bit.
+ *
+ * On byte oriented architectures, @ref CPU_HEAP_ALIGNMENT normally will
+ * have to be greater or equal to than @ref CPU_ALIGNMENT to ensure that
+ * elements allocated from the heap meet all restrictions.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+
+/**
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * @ref CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as @ref CPU_ALIGNMENT. If the @ref CPU_ALIGNMENT is
+ * strict enough for the partition, then this should be set to
+ * @ref CPU_ALIGNMENT.
+ *
+ * @note This does not have to be a power of 2. It does have to
+ * be greater or equal to than @ref CPU_ALIGNMENT.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/**
+ * This number corresponds to the byte alignment requirement for the
+ * stack. This alignment requirement may be stricter than that for the
+ * data types alignment specified by @ref CPU_ALIGNMENT. If the
+ * @ref CPU_ALIGNMENT is strict enough for the stack, then this should be
+ * set to 0.
+ *
+ * @note This must be a power of 2 either 0 or greater than @ref CPU_ALIGNMENT.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define CPU_STACK_ALIGNMENT 0
+
+/*
+ * ISR handler macros
+ */
+
+/**
+ * @ingroup CPUInterrupt
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_Initialize_vectors()
+
+/**
+ * @ingroup CPUInterrupt
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in @a _isr_cookie.
+ *
+ * @param[out] _isr_cookie will contain the previous level cookie
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_ISR_Disable( _isr_cookie ) \
+ { \
+ (_isr_cookie) = 0; /* do something to prevent warnings */ \
+ }
+
+/**
+ * @ingroup CPUInterrupt
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * @a _isr_cookie is not modified.
+ *
+ * @param[in] _isr_cookie contain the previous level cookie
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_ISR_Enable( _isr_cookie ) \
+ { \
+ }
+
+/**
+ * @ingroup CPUInterrupt
+ * This temporarily restores the interrupt to @a _isr_cookie before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter @a _isr_cookie is not
+ * modified.
+ *
+ * @param[in] _isr_cookie contain the previous level cookie
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_ISR_Flash( _isr_cookie ) \
+ { \
+ }
+
+/**
+ * @ingroup CPUInterrupt
+ *
+ * This routine and @ref _CPU_ISR_Get_level
+ * Map the interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a generic fashion are undefined. Someday,
+ * it would be nice if these were "mapped" by the application
+ * via a callout. For example, m68k has 8 levels 0 - 7, levels
+ * 8 - 255 would be available for bsp/application specific meaning.
+ * This could be used to manage a programmable interrupt controller
+ * via the rtems_task_mode directive.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_ISR_Set_level( new_level ) \
+ { \
+ }
+
+/**
+ * @ingroup CPUInterrupt
+ * Return the current interrupt disable level for this task in
+ * the format used by the interrupt level portion of the task mode.
+ *
+ * @note This routine usually must be implemented as a subroutine.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+uint32_t _CPU_ISR_Get_level( void );
+
+/* end of ISR handler macros */
+
+/* Context handler macros */
+
+/**
+ * @ingroup CPUContext
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * This routine generally does not set any unnecessary register
+ * in the context. The state of the "general data" registers is
+ * undefined at task start time.
+ *
+ * @param[in] _the_context is the context structure to be initialized
+ * @param[in] _stack_base is the lowest physical address of this task's stack
+ * @param[in] _size is the size of this task's stack
+ * @param[in] _isr is the interrupt disable level
+ * @param[in] _entry_point is the thread's entry point. This is
+ * always @a _Thread_Handler
+ * @param[in] _is_fp is TRUE if the thread is to be a floating
+ * point thread. This is typically only used on CPUs where the
+ * FPU may be easily disabled by software such as on the SPARC
+ * where the PSR contains an enable FPU bit.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
+ _isr, _entry_point, _is_fp ) \
+ { \
+ }
+
+/**
+ * This routine is responsible for somehow restarting the currently
+ * executing task. If you are lucky, then all that is necessary
+ * is restoring the context. Otherwise, there will need to be
+ * a special assembly routine which does something special in this
+ * case. For many ports, simply adding a label to the restore path
+ * of @ref _CPU_Context_switch will work. On other ports, it may be
+ * possibly to load a few arguments and jump to the restore path. It will
+ * not work if restarting self conflicts with the stack frame
+ * assumptions of restoring a context.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+/**
+ * @ingroup CPUContext
+ * The purpose of this macro is to allow the initial pointer into
+ * a floating point context area (used to save the floating point
+ * context) to be at an arbitrary place in the floating point
+ * context area.
+ *
+ * This is necessary because some FP units are designed to have
+ * their context saved as a stack which grows into lower addresses.
+ * Other FP units can be saved by simply moving registers into offsets
+ * from the base of the context area. Finally some FP units provide
+ * a "dump context" instruction which could fill in from high to low
+ * or low to high based on the whim of the CPU designers.
+ *
+ * @param[in] _base is the lowest physical address of the floating point
+ * context area
+ * @param[in] _offset is the offset into the floating point area
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
+
+/**
+ * This routine initializes the FP context area passed to it to.
+ * There are a few standard ways in which to initialize the
+ * floating point context. The code included for this macro assumes
+ * that this is a CPU in which a "initial" FP context was saved into
+ * @a _CPU_Null_fp_context and it simply copies it to the destination
+ * context passed to it.
+ *
+ * Other floating point context save/restore models include:
+ * -# not doing anything, and
+ * -# putting a "null FP status word" in the correct place in the FP context.
+ *
+ * @param[in] _destination is the floating point context area
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_Context_Initialize_fp( _destination ) \
+ { \
+ *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
+ }
+
+/* end of Context handler macros */
+
+/* Fatal Error manager macros */
+
+/**
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#define _CPU_Fatal_halt( _error ) \
+ { \
+ }
+
+/* end of Fatal Error manager macros */
+
+/* Bitfield handler macros */
+
+/**
+ * @defgroup CPUBitfield Processor Dependent Bitfield Manipulation
+ *
+ * This set of routines are used to implement fast searches for
+ * the most important ready task.
+ */
+
+/**
+ * @ingroup CPUBitfield
+ * This definition is set to TRUE if the port uses the generic bitfield
+ * manipulation implementation.
+ */
+#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+
+/**
+ * @ingroup CPUBitfield
+ * This definition is set to TRUE if the port uses the data tables provided
+ * by the generic bitfield manipulation implementation.
+ * This can occur when actually using the generic bitfield manipulation
+ * implementation or when implementing the same algorithm in assembly
+ * language for improved performance. It is unlikely that a port will use
+ * the data if it has a bitfield scan instruction.
+ */
+#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
+
+/**
+ * @ingroup CPUBitfield
+ * This routine sets @a _output to the bit number of the first bit
+ * set in @a _value. @a _value is of CPU dependent type
+ * @a Priority_Bit_map_control. This type may be either 16 or 32 bits
+ * wide although only the 16 least significant bits will be used.
+ *
+ * There are a number of variables in using a "find first bit" type
+ * instruction.
+ *
+ * -# What happens when run on a value of zero?
+ * -# Bits may be numbered from MSB to LSB or vice-versa.
+ * -# The numbering may be zero or one based.
+ * -# The "find first bit" instruction may search from MSB or LSB.
+ *
+ * RTEMS guarantees that (1) will never happen so it is not a concern.
+ * (2),(3), (4) are handled by the macros @ref _CPU_Priority_Mask and
+ * @ref _CPU_Priority_bits_index. These three form a set of routines
+ * which must logically operate together. Bits in the _value are
+ * set and cleared based on masks built by @ref _CPU_Priority_Mask.
+ * The basic major and minor values calculated by @ref _Priority_Major
+ * and @ref _Priority_Minor are "massaged" by @ref _CPU_Priority_bits_index
+ * to properly range between the values returned by the "find first bit"
+ * instruction. This makes it possible for @ref _Priority_Get_highest to
+ * calculate the major and directly index into the minor table.
+ * This mapping is necessary to ensure that 0 (a high priority major/minor)
+ * is the first bit found.
+ *
+ * This entire "find first bit" and mapping process depends heavily
+ * on the manner in which a priority is broken into a major and minor
+ * components with the major being the 4 MSB of a priority and minor
+ * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
+ * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next
+ * to the lowest priority.
+ *
+ * If your CPU does not have a "find first bit" instruction, then
+ * there are ways to make do without it. Here are a handful of ways
+ * to implement this in software:
+ *
+@verbatim
+ - a series of 16 bit test instructions
+ - a "binary search using if's"
+ - _number = 0
+ if _value > 0x00ff
+ _value >>=8
+ _number = 8;
+
+ if _value > 0x0000f
+ _value >=8
+ _number += 4
+
+ _number += bit_set_table[ _value ]
+@endverbatim
+
+ * where bit_set_table[ 16 ] has values which indicate the first
+ * bit set
+ *
+ * @param[in] _value is the value to be scanned
+ * @param[in] _output is the first bit set
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ (_output) = 0; /* do something to prevent warnings */ \
+ }
+#endif
+
+/* end of Bitfield handler macros */
+
+/**
+ * This routine builds the mask which corresponds to the bit fields
+ * as searched by @ref _CPU_Bitfield_Find_first_bit. See the discussion
+ * for that routine.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_Mask( _bit_number ) \
+ ( 1 << (_bit_number) )
+
+#endif
+
+/**
+ * @ingroup CPUBitfield
+ * This routine translates the bit numbers returned by
+ * @ref _CPU_Bitfield_Find_first_bit into something suitable for use as
+ * a major or minor component of a priority. See the discussion
+ * for that routine.
+ *
+ * @param[in] _priority is the major or minor number to translate
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_bits_index( _priority ) \
+ (_priority)
+
+#endif
+
+/* end of Priority handler macros */
+
+/* functions */
+
+/**
+ * This routine performs CPU dependent initialization.
+ *
+ * @param[in] cpu_table is the CPU Dependent Configuration Table
+ * @param[in] thread_dispatch is the address of @ref _Thread_Dispatch
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/**
+ * @ingroup CPUInterrupt
+ * This routine installs a "raw" interrupt handler directly into the
+ * processor's vector table.
+ *
+ * @param[in] vector is the vector number
+ * @param[in] new_handler is the raw ISR handler to install
+ * @param[in] old_handler is the previously installed ISR Handler
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/**
+ * @ingroup CPUInterrupt
+ * This routine installs an interrupt vector.
+ *
+ * @param[in] vector is the vector number
+ * @param[in] new_handler is the RTEMS ISR handler to install
+ * @param[in] old_handler is the previously installed ISR Handler
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/**
+ * @ingroup CPUInterrupt
+ * This routine installs the hardware interrupt stack pointer.
+ *
+ * @note It need only be provided if @ref CPU_HAS_HARDWARE_INTERRUPT_STACK
+ * is TRUE.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Install_interrupt_stack( void );
+
+/**
+ * This routine is the CPU dependent IDLE thread body.
+ *
+ * @note It need only be provided if @ref CPU_PROVIDES_IDLE_THREAD_BODY
+ * is TRUE.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Thread_Idle_body( void );
+
+/**
+ * @ingroup CPUContext
+ * This routine switches from the run context to the heir context.
+ *
+ * @param[in] run points to the context of the currently executing task
+ * @param[in] heir points to the context of the heir task
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/**
+ * @ingroup CPUContext
+ * This routine is generally used only to restart self in an
+ * efficient manner. It may simply be a label in @ref _CPU_Context_switch.
+ *
+ * @param[in] new_context points to the context to be restored.
+ *
+ * @note May be unnecessary to reload some registers.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/**
+ * @ingroup CPUContext
+ * This routine saves the floating point context passed to it.
+ *
+ * @param[in] fp_context_ptr is a pointer to a pointer to a floating
+ * point context area
+ *
+ * @return on output @a *fp_context_ptr will contain the address that
+ * should be used with @ref _CPU_Context_restore_fp to restore this context.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/**
+ * @ingroup CPUContext
+ * This routine restores the floating point context passed to it.
+ *
+ * @param[in] fp_context_ptr is a pointer to a pointer to a floating
+ * point context area to restore
+ *
+ * @return on output @a *fp_context_ptr will contain the address that
+ * should be used with @ref _CPU_Context_save_fp to save this context.
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+/**
+ * @ingroup CPUEndian
+ * The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * This version will work on any processor, but if there is a better
+ * way for your CPU PLEASE use it. The most common way to do this is to:
+ *
+ * swap least significant two bytes with 16-bit rotate
+ * swap upper and lower 16-bits
+ * swap most significant two bytes with 16-bit rotate
+ *
+ * Some CPUs have special instructions which swap a 32-bit quantity in
+ * a single instruction (e.g. i486). It is probably best to avoid
+ * an "endian swapping control bit" in the CPU. One good reason is
+ * that interrupts would probably have to be disabled to ensure that
+ * an interrupt does not try to access the same "chunk" with the wrong
+ * endian. Another good reason is that on some CPUs, the endian bit
+ * endianness for ALL fetches -- both code and data -- so the code
+ * will be fetched incorrectly.
+ *
+ * @param[in] value is the value to be swapped
+ * @return the value after being endian swapped
+ *
+ * Port Specific Information:
+ *
+ * XXX document implementation including references if appropriate
+ */
+static inline uint32_t CPU_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t byte1, byte2, byte3, byte4, swapped;
+
+ byte4 = (value >> 24) & 0xff;
+ byte3 = (value >> 16) & 0xff;
+ byte2 = (value >> 8) & 0xff;
+ byte1 = value & 0xff;
+
+ swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
+ return( swapped );
+}
+
+/**
+ * @ingroup CPUEndian
+ * This routine swaps a 16 bir quantity.
+ *
+ * @param[in] value is the value to be swapped
+ * @return the value after being endian swapped
+ */
+#define CPU_swap_u16( value ) \
+ (((value&0xff) << 8) | ((value >> 8)&0xff))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/no_cpu/rtems/score/cpu_asm.h b/cpukit/score/cpu/no_cpu/rtems/score/cpu_asm.h
new file mode 100644
index 0000000000..a509b36ae6
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/rtems/score/cpu_asm.h
@@ -0,0 +1,72 @@
+/**
+ * @file rtems/score/cpu_asm.h
+ */
+
+/*
+ * Very loose template for an include file for the cpu_asm.? file
+ * if it is implemented as a ".S" file (preprocessed by cpp) instead
+ * of a ".s" file (preprocessed by gm4 or gasp).
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef _RTEMS_SCORE_CPU_ASM_H
+#define _RTEMS_SCORE_CPU_ASM_H
+
+/* pull in the generated offsets */
+
+#include <rtems/score/offsets.h>
+
+/*
+ * Hardware General Registers
+ */
+
+/* put something here */
+
+/*
+ * Hardware Floating Point Registers
+ */
+
+/* put something here */
+
+/*
+ * Hardware Control Registers
+ */
+
+/* put something here */
+
+/*
+ * Calling Convention
+ */
+
+/* put something here */
+
+/*
+ * Temporary registers
+ */
+
+/* put something here */
+
+/*
+ * Floating Point Registers - SW Conventions
+ */
+
+/* put something here */
+
+/*
+ * Temporary floating point registers
+ */
+
+/* put something here */
+
+#endif
+
+/* end of file */
diff --git a/cpukit/score/cpu/no_cpu/rtems/score/no_cpu.h b/cpukit/score/cpu/no_cpu/rtems/score/no_cpu.h
new file mode 100644
index 0000000000..d6b532dd06
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/rtems/score/no_cpu.h
@@ -0,0 +1,69 @@
+/* no_cpu.h
+ *
+ * This file sets up basic CPU dependency settings based on
+ * compiler settings. For example, it can determine if
+ * floating point is available. This particular implementation
+ * is specified to the NO CPU port.
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef _RTEMS_SCORE_NO_CPU_H
+#define _RTEMS_SCORE_NO_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the NO CPU family.
+ * It does this by setting variables to indicate which
+ * implementation dependent features are present in a particular
+ * member of the family.
+ *
+ * This is a good place to list all the known CPU models
+ * that this port supports and which RTEMS CPU model they correspond
+ * to.
+ */
+
+#if defined(rtems_multilib)
+/*
+ * Figure out all CPU Model Feature Flags based upon compiler
+ * predefines.
+ */
+
+#define CPU_MODEL_NAME "rtems_multilib"
+#define NOCPU_HAS_FPU 1
+
+#elif defined(no_cpu)
+
+#define CPU_MODEL_NAME "no_cpu_model"
+#define NOCPU_HAS_FPU 1
+
+#else
+
+#error "Unsupported CPU Model"
+
+#endif
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "NO CPU"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_NO_CPU_H */
diff --git a/cpukit/score/cpu/no_cpu/rtems/score/types.h b/cpukit/score/cpu/no_cpu/rtems/score/types.h
new file mode 100644
index 0000000000..e3703d976a
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/rtems/score/types.h
@@ -0,0 +1,63 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains type definitions pertaining to the Intel
+ * no_cpu processor family.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+/** This defines an unsigned 64-bit integer. */
+typedef unsigned long long unsigned64;
+
+/** This defines the type for a priority bit map entry. */
+typedef uint16_t Priority_Bit_map_control;
+
+/** This defines the type for a 64 bit signed integer */
+typedef signed long long signed64;
+
+/** This defines the type for a Boolean value, */
+typedef uint32_t boolean; /* Boolean value */
+
+/** This defines the type for a single precision float. */
+typedef float single_precision;
+/** This defines the type for a double precision float. */
+typedef double double_precision;
+
+/** This defines the return type for an ISR entry point. */
+typedef void no_cpu_isr;
+
+/** This defines the prototype for an ISR entry point. */
+typedef no_cpu_isr ( *no_cpu_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/powerpc/.cvsignore b/cpukit/score/cpu/powerpc/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/powerpc/ChangeLog b/cpukit/score/cpu/powerpc/ChangeLog
new file mode 100644
index 0000000000..de4e664d21
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/ChangeLog
@@ -0,0 +1,689 @@
+2006-08-09 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Because gcc implicitly uses floating point turn on
+ floating point for all threads if there is a hardware FPU.
+
+2006-07-12 Till Straumann <strauman@slac.stanford.edu>
+
+ * rtems/old-exceptions/cpu.h, rtems/powerpc/registers.h:
+ Checked inline assembly; added early-clobber '&' to output operands
+ of multi-instruction asms.
+
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/new-exceptions/cpu.h, rtems/old-exceptions/cpu.h,
+ rtems/score/cpu.h: Part of a large patch to improve Doxygen output.
+ As a side-effect, grammar and spelling errors were corrected, spacing
+ errors were address, and some variable names were improved.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16, unsigned32.
+
+2005-11-02 Till Straumann <strauman@slac.stanford.edu>
+
+ * rtems/powerpc/registers.h: recognize mpc7457 CPU; added definitions
+ for high bats (#4..7) on 7450 CPUs
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h: Remove private version of CONCAT macros.
+ Include <rtems/concat.h> instead.
+
+2005-05-06 Jennifer Averett <jennifer.averett@oarcorp.com>
+
+ * rtems/score/powerpc.h: Removed warning
+
+2005-02-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Add "defined(mpc7400) || defined(mpc7450)
+ || defined(mpc7455)" to altivec (gcc-3.2.x compatibility).
+
+2005-02-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h (CPU_HARDWARE_FP, CPU_ALL_TASKS_ARE_FP,
+ CPU_IDLE_TASK_IS_FP): Remove.
+ * rtems/old-exceptions/cpu.h (CPU_HARDWARE_FP, CPU_ALL_TASKS_ARE_FP,
+ CPU_IDLE_TASK_IS_FP): Remove.
+ * rtems/score/cpu.h (CPU_HARDWARE_FP, CPU_ALL_TASKS_ARE_FP,
+ CPU_IDLE_TASK_IS_FP, CPU_SOFTWARE_FP): New.
+
+2005-02-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Derive CPU_{BIG|LITTLE}_ENDIAN from
+ __BIG_ENDIAN__.
+
+2005-02-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h (CPU_PROVIDES_IDLE_THREAD_BODY,
+ CPU_STACK_GROWS_UP, CPU_STRUCTURE_ALIGNMENT,
+ CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES, CPU_BIG_ENDIAN,
+ CPU_LITTLE_ENDIAN): Add.
+ * rtems/old-exceptions/cpu.h (CPU_PROVIDES_IDLE_THREAD_BODY,
+ CPU_STACK_GROWS_UP, CPU_STRUCTURE_ALIGNMENT,
+ CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES, CPU_BIG_ENDIAN,
+ CPU_LITTLE_ENDIAN): Remove.
+ * rtems/new-exceptions/cpu.h (CPU_PROVIDES_IDLE_THREAD_BODY,
+ CPU_STACK_GROWS_UP, CPU_STRUCTURE_ALIGNMENT,
+ CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES, CPU_BIG_ENDIAN,
+ CPU_LITTLE_ENDIAN): Remove.
+
+2005-02-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h:
+ (rtems_cpu_configuration_get_serial_per_sec,
+ rtems_cpu_configuration_get_serial_external_clock,
+ rtems_cpu_configuration_get_serial_xon_xoff,
+ rtems_cpu_configuration_get_serial_cts_rts,
+ rtems_cpu_configuration_get_serial_rate,
+ rtems_cpu_configuration_get_timer_average_overhead,
+ rtems_cpu_configuration_get_timer_least_valid,
+ rtems_cpu_configuration_get_timer_internal_clock,
+ rtems_cpu_configuration_get_clock_speed): New.
+ * rtems/old-exceptions/cpu.h:
+ (rtems_cpu_configuration_get_serial_per_sec,
+ rtems_cpu_configuration_get_serial_external_clock,
+ rtems_cpu_configuration_get_serial_xon_xoff,
+ rtems_cpu_configuration_get_serial_cts_rts,
+ rtems_cpu_configuration_get_serial_rate,
+ rtems_cpu_configuration_get_timer_average_overhead,
+ rtems_cpu_configuration_get_timer_least_valid,
+ rtems_cpu_configuration_get_timer_internal_clock,
+ rtems_cpu_configuration_get_clock_speed): Remove.
+
+2005-02-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h, rtems/old-exceptions/cpu.h
+ (rtems_cpu_table): Sync defines between {old|new}-exceptions.
+
+2005-02-18 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h (Context_Control,
+ Context_Control_fp, CPU_Interrupt_frame): Remove.
+ * rtems/old-exceptions/cpu.h (Context_Control,
+ Context_Control_fp, CPU_Interrupt_frame): Remove.
+ * rtems/score/cpu.h (Context_Control,
+ Context_Control_fp, CPU_Interrupt_frame): Add.
+
+2005-02-16 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h (CPU_STACK_MINIMUM_SIZE,
+ CPU_ALIGNMENT, CPU_HEAP_ALIGNMENT,
+ CPU_PARTITION_ALIGNMENT, CPU_STACK_ALIGNMENT): Remove.
+ * rtems/old-exceptions/cpu.h (CPU_STACK_MINIMUM_SIZE,
+ CPU_ALIGNMENT, CPU_HEAP_ALIGNMENT,
+ CPU_PARTITION_ALIGNMENT, CPU_STACK_ALIGNMENT): Remove.
+ * rtems/score/cpu.h (CPU_STACK_MINIMUM_SIZE,
+ CPU_ALIGNMENT, CPU_HEAP_ALIGNMENT,
+ CPU_PARTITION_ALIGNMENT, CPU_STACK_ALIGNMENT): Add.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h: Remove CPU_MINIMUM_STACK_FRAME_SIZE.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h (_CPU_Bitfield_Find_first_bit,
+ _CPU_Priority_Mask, _CPU_Priority_bits_index): Remove.
+ * rtems/old-exceptions/cpu.h (_CPU_Bitfield_Find_first_bit,
+ _CPU_Priority_Mask, _CPU_Priority_bits_index): Remove.
+ * rtems/score/cpu.h (_CPU_Bitfield_Find_first_bit,
+ _CPU_Priority_Mask, _CPU_Priority_bits_index): New.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h (_CPU_msrs): Remove (Unused).
+ * rtems/old-exceptions/cpu.h (_CPU_msrs): Remove (Unused).
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h (_CPU_ISR_install_vector,
+ _CPU_Initialize, _CPU_Install_interrupt_stack, _CPU_Context_switch,
+ _CPU_Context_restore, _CPU_Context_save_fp, _CPU_Context_restore_fp,
+ _CPU_Fatal_error): Remove.
+ * rtems/old-exceptions/cpu.h (_CPU_ISR_install_vector,
+ _CPU_Initialize, _CPU_Install_interrupt_stack, _CPU_Context_switch,
+ _CPU_Context_restore, _CPU_Context_save_fp, _CPU_Context_restore_fp,
+ _CPU_Fatal_error): Remove.
+ * rtems/score/cpu.h (_CPU_ISR_install_vector,
+ _CPU_Initialize, _CPU_Install_interrupt_stack, _CPU_Context_switch,
+ _CPU_Context_restore, _CPU_Context_save_fp, _CPU_Context_restore_fp,
+ _CPU_Fatal_error): New.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/old-exceptions/cpu.h (_CPU_Context_Initialize,
+ _CPU_Context_Restart_self, _CPU_Context_Fp_start,
+ _CPU_Context_Initialize_fp): Remove.
+ * rtems/new-exceptions/cpu.h (_CPU_Context_Initialize,
+ _CPU_Context_Restart_self, _CPU_Context_Fp_start,
+ _CPU_Context_Initialize_fp): Remove.
+ * rtems/score/cpu.h (_CPU_Context_Initialize,
+ _CPU_Context_Restart_self, _CPU_Context_Fp_start,
+ _CPU_Context_Initialize_fp): New.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/old-exceptions/cpu.h (PPC_Get_timebase_register): Remove.
+ * rtems/powerpc/registers.h (PPC_Get_timebase_register,
+ PPC_Set_timebase_register): Remove.
+ * rtems/score/cpu.h (PPC_Get_timebase_register,
+ PPC_Set_timebase_register): New.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/powerpc/registers.h (PPC_Set_decrementer,
+ PPC_Get_decrementer): Remove.
+ * rtems/old-exceptions/cpu.h (PPC_Set_decrementer): Remove.
+ * rtems/score/cpu.h (PPC_Set_decrementer, PPC_Get_decrementer): New.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/old-exceptions/cpu.h (CPU_Get_timebase_low, rtems_bsp_delay,
+ rtems_bsp_delay_in_bus_cycles): Remove.
+ * rtems/powerpc/registers.h (CPU_Get_timebase_low, rtems_bsp_delay,
+ rtems_bsp_delay_in_bus_cycles): Remove.
+ * rtems/score/cpu.h (CPU_Get_timebase_low, rtems_bsp_delay,
+ rtems_bsp_delay_in_bus_cycles): New.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h
+ (rtems_cpu_configuration_get_clicks_per_usec,
+ rtems_cpu_configuration_get_exceptions_in_ram): Remove.
+ * rtems/old-exceptions/cpu.h
+ (rtems_cpu_configuration_get_clicks_per_usec,
+ rtems_cpu_configuration_get_exceptions_in_ram): Remove.
+ * rtems/score/cpu.h
+ (rtems_cpu_configuration_get_clicks_per_usec,
+ rtems_cpu_configuration_get_exceptions_in_ram): New.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h (CPU_swap_u32, CPU_swap_u16): Remove.
+ * rtems/old-exceptions/cpu.h (CPU_swap_u32, CPU_swap_u16): Remove.
+ * rtems/score/cpu.h (CPU_swap_u32, CPU_swap_u16): New.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/old-exceptions/cpu.h: Add _CPU_MSG_GET
+ (old/new exception processing ABI compatibility).
+ * rtems/powerpc/registers.h: Use C99 fixed size types.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Add __ALTIVEC__ support.
+
+2005-02-15 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Merge ppc603 and ppc603e
+ PPC_IRQ_*/PPC_TLB_* defines.
+
+2005-02-14 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h (mpc8260): PPC_ALIGNMENT 8.
+
+2005-02-14 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Remove PPC_HAS_RFCI (Unused).
+
+2005-02-13 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Remove PPC_HAS_EXCEPTION_PREFIX (Unused).
+
+2005-02-13 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Remove PPC_CACHE_ALIGN_POWER (Unused).
+
+2005-02-13 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Remove PPC_LOW_POWER_MODE* (Unused).
+
+2005-02-13 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Remove PPC_HAS_EVPR (Unused).
+
+2005-02-13 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Remove PPC_USE_MULTIPLE (Unused).
+
+2005-02-13 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Remove PPC_D_CACHE, PPC_I_CACHE defines.
+
+2005-02-13 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Remove PPC_MSR_* defines.
+
+2005-02-13 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/old-exceptions/cpu.h: Add _PPC_MSR_DISABLE_MASK.
+ Use _PPC_MSR_DISABLE_MASK instead of PPC_MSR_DISABLE_MASK to set up
+ _disable_mask.
+
+2005-02-12 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * cpu.c: New (Stub file for consistency with other ports).
+ * Makefile.am: Reflect changes above.
+
+2005-02-10 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h, rtems/old-exceptions/cpu.h, rtems/score/powerpc.h:
+ Remove PPC_ABI_POWEROPEN.
+
+2005-02-10 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: Remove hard-coded PPC_HAS_FPU.
+ Tie PPC_HAS_FPU to _SOFT_FLOAT.
+
+2005-02-09 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/old-exceptions/cpu.h, rtems/score/powerpc.h:
+ Remove PPC_ABI_GCC27.
+
+2005-02-09 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h, rtems/score/powerpc.h: Remove XCOFF support.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * rtems/new-exceptions/cpu.h, rtems/old-exceptions/cpu.h,
+ rtems/powerpc/registers.h: New header guards.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/cpu.h, rtems/score/powerpc.h,
+ rtems/score/ppc.h, rtems/score/types.h: New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h: *_swap_u32( uint32_t ).
+ * rtems/old-exceptions/cpu.h: *_swap_u32( uint32_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: #include <rtems/stdint.h>.
+
+2004-11-22 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/old-exceptions/cpu.h: Make compile in assembly.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Use __rtems_score_types_h as preprocessor
+ guard.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * asm.h: Add doxygen preamble.
+
+2004-10-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Add doxygen preamble.
+ * rtems/score/powerpc.h: Add doxygen preamble.
+ * rtems/score/ppc.h: Add doxygen preamble.
+ * rtems/score/types.h: Add doxygen preamble.
+
+2004-10-20 Eric Norum <norume@aps.anl.gov>
+
+ Add Kate Feng's MVME5500 BSP
+ * rtems/powerpc/registers.h, rtems/score/powerpc.h
+
+2004-09-29 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/new-exceptions/cpu.h, rtems/old-exceptions/cpu.h: i960
+ obsoleted and all references removed.
+
+2004-04-13 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * asm.h: Include rtems/score/powerpc.h instead of
+ rtems/score/ppc.h.
+
+2004-04-13 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/powerpc.h: New (Copied and renamed from rtems/score/ppc.h)
+ for consistency with other ports.
+ * rtems/score/ppc.h: Deprecation wrapper to rtems/score/powerpc.h.
+ * Makefile.am: Reflect changes above.
+ * rtems/score/cpu.h: Include rtems/score/powerpc.h instead of
+ rtems/score/ppc.h.
+
+2004-04-12 David Querbach <querbach@realtime.bc.ca>
+
+ * asm.h, rtems/new-exceptions/cpu.h, rtems/score/ppc.h: addition of
+ MPC555 support as part of the addition of the SS555 BSP.
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Remove (Merged into $(top_srcdir)/configure.ac).
+ * Makefile.am: Don't include multilib.am.
+ Reflect merging configure.ac into $(top_srcdir)/configure.ac.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Install asm.h to $(includedir)/rtems.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/new-exceptions/cpu.h, rtems/old-exceptions/cpu.h,
+ rtems/powerpc/registers.h: Convert to using c99 fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: RTEMS_TOP([../../../..]).
+
+2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Move RTEMS_TOP one subdir down.
+
+2004-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add PREINSTALL_DIRS.
+
+2004-01-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Re-add dirstamps to PREINSTALL_FILES.
+ Add PREINSTALL_FILES to CLEANFILES.
+
+2004-01-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Requires automake >= 1.8.1.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, again.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Convert to using automake compilation rules.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use mkdir_p. Remove dirs from PREINSTALL_FILES.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require automake >= 1.8, autoconf >= 2.59.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Remove all LIB-related rules.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Don't use gmake rules for preinstallation.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CANONICAL_HOST.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CPU.
+
+2003-09-26 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/new-exceptions/cpu.h, rtems/old-exceptions/cpu.h: Obsoleting HP
+ PA-RISC port and removing all references.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/new-exceptions/cpu.h, rtems/old-exceptions/cpu.h,
+ rtems/powerpc/registers.h, rtems/score/ppc.h, rtems/score/types.h:
+ URL for license changed.
+
+2003-08-21 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 457/bsps
+ * rtems/powerpc/registers.h: Add a few definitions for the PowerPC
+ thermal assistance unit.
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-07-18 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 288/rtems
+ * rtems/new-exceptions/cpu.h: _ISR_Nest_level is now properly
+ maintained and does not reside in SPRG0.
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+
+2003-02-20 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 349/bsps
+ * rtems/powerpc/registers.h: Add definitions for HID1 and DABR SPRs.
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require autoconf-2.57 + automake-1.7.2.
+ * Makefile.am: Eliminate C_O_FILES, S_O_FILES, libscorecpu_a_OBJECTS.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix package name.
+
+2002-11-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/new-exceptions/cpu.h: Remove sections on
+ CPU_INLINE_ENABLE_DISPATCH and CPU_UNROLL_ENQUEUE_PRIORITY.
+ * rtems/old-exceptions/cpu.h: Remove sections on
+ CPU_INLINE_ENABLE_DISPATCH and CPU_UNROLL_ENQUEUE_PRIORITY.
+ * rtems/score/cpu.h: Insert sections on
+ CPU_INLINE_ENABLE_DISPATCH and CPU_UNROLL_ENQUEUE_PRIORITY.
+
+2002-10-31 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/new-exceptions/cpu.h: Removed warnings.
+
+
+2002-10-31 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/new-exceptions/cpu.h: Removed warnings.
+
+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-07-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use .$(OBJEXT) instead of .o.
+
+2002-07-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: RTEMS_TOP(../../../..).
+
+2002-07-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_PROJECT_ROOT.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add RTEMS_PROG_CCAS
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AC_CONFIG_AUX_DIR(../../../..).
+ Add AC_PROG_RANLIB.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/../../../automake/*.am.
+ Use ../../../aclocal.
+
+2002-05-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/ppc.h: Remove PPC_DEBUG_MODEL.
+
+2001-05-14 Till Straumann <strauman@slac.stanford.edu>
+
+ * rtems/powerpc/registers.h, rtems/score/ppc.h: Per PR213, add
+ support for the MPC74000 (AKA G4); there is no AltiVec support yet,
+ however.
+2002-04-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/ppc.h: Remove rtems_multilib.
+ Add mpc555 (Based on comments from Sergei Organov <osv@javad.ru>).
+ * rtems/old-exceptions/cpu.h: Remove _CPU_Data_Cache_Block_Flush.
+ Remove _CPU_Data_Cache_Block_Invalidate.
+
+2002-04-18 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * asm.h: Include cpuopts.h instead of targopts.h.
+ * rtems/new-exceptions/cpu.h: Relocated from
+ libbsp/powerpc/support/new_exception_processing/rtems/score/cpu.h
+ * rtems/old-exceptions/cpu.h: Relocated from
+ c/src/lib/libbsp/powerpc/support/old_exception_processing/rtems/score/cpu.h
+ * rtems/powerpc/registers.h: Relocated and renamed from
+ libcpu/powerpc/shared/include/cpu.h.
+ * rtems/score/cpu.h: New.
+ * 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/ppctypes.h: Removed.
+ * rtems/score/types.h: New file via CVS magic.
+ * Makefile.am, 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.
+
+2002-01-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Reflect changes from 2002-01-23.
+
+2002-01-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/Makefile.am: Removed.
+ * rtems/score/Makefile.am: Removed.
+ * configure.ac: Reflect changes above.
+ AC_CONFIG_SRCDIR(asm.h).
+
+2002-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/Makefile.am: New.
+ * rtems/.cvsignore: New.
+ * rtems/score/Makefile.am: New.
+ * rtems/score/.cvsignore: New.
+ * rtems/score/ppc.h: Relocated from shared/.
+ * rtems/score/ppctypes.h: Relocated from shared/.
+ * asm.h: Relocated from shared/.
+ * shared/Makefile.am: Removed.
+ * shared/asm.h: Removed.
+ * shared/ppc.h: Removed.
+ * shared/ppctypes.h: Removed.
+ * shared/.cvsignore: Removed.
+ * Makefile.am: Reflect changes above.
+ * configure.ac: Reflect changes above.
+
+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.
+
+2001-11-14 Joel Sherrill <joel@OARcorp.com>
+
+ * shared/ppc.h: The mpc8260 uses the new exception processing model
+ and thus does not need to define PPC_USE_SPRG.
+
+2001-11-14 Andrew Dachs <A.Dachs@SSTL.co.uk>
+
+ * shared/ppc.h: mpc8260 has double FPU not single FPU.
+
+2001-11-08 Dennis Ehlin (ECS) <Dennis.Ehlin@ecs.ericsson.se>
+
+ This modification is part of the submitted modifications necessary to
+ support the IBM PPC405 family. This submission was reviewed by
+ Thomas Doerfler <Thomas.Doerfler@imd-systems.de> who ensured it did
+ not negatively impact the ppc403 BSPs. The submission and tracking
+ process was captured as PR50.
+ * shared/asm.h, shared/ppc.h: Added PPC405 support.
+
+2001-10-22 Andy Dachs <a.dachs@sstl.co.uk>
+
+ * shared/ppc.h: Added mpc8260 support.
+
+2001-10-12 Joel Sherrill <joel@OARcorp.com>
+
+ * shared/ppctypes.h: Fixed typo.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * shared/Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, rtems/score/Makefile.am:
+ Apply include_*HEADERS instead of H_FILES.
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
+ Switch to GNU canonicalization.
+
+2000-10-20 Joel Sherrill <joel@OARcorp.com>
+
+ * shared/ppc.h: For multilibs, derive PPC_HAS_FPU from _SOFT_FLOAT.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am.
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: New file.
diff --git a/cpukit/score/cpu/powerpc/Makefile.am b/cpukit/score/cpu/powerpc/Makefile.am
new file mode 100644
index 0000000000..b9732b4225
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/Makefile.am
@@ -0,0 +1,31 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/powerpc.h rtems/score/cpu.h \
+ rtems/score/types.h
+if DEPRECATED
+include_rtems_score_HEADERS += rtems/score/ppc.h
+endif
+
+include_rtems_old_exceptionsdir = $(includedir)/rtems/old-exceptions
+include_rtems_old_exceptions_HEADERS = rtems/old-exceptions/cpu.h
+
+include_rtems_new_exceptionsdir = $(includedir)/rtems/new-exceptions
+include_rtems_new_exceptions_HEADERS = rtems/new-exceptions/cpu.h
+
+include_rtems_powerpcdir = $(includedir)/rtems/powerpc
+include_rtems_powerpc_HEADERS = rtems/powerpc/registers.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/powerpc/cpu.c b/cpukit/score/cpu/powerpc/cpu.c
new file mode 100644
index 0000000000..0004ed57cf
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/cpu.c
@@ -0,0 +1,12 @@
+/*
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+/*
+ * For now, this file is just a stub to work around
+ * structural deficiencies of the powerpc port.
+ */
diff --git a/cpukit/score/cpu/powerpc/preinstall.am b/cpukit/score/cpu/powerpc/preinstall.am
new file mode 100644
index 0000000000..49fa2db38c
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/preinstall.am
@@ -0,0 +1,73 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/powerpc.h: rtems/score/powerpc.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/powerpc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/powerpc.h
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
+if DEPRECATED
+$(PROJECT_INCLUDE)/rtems/score/ppc.h: rtems/score/ppc.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/ppc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/ppc.h
+endif
+$(PROJECT_INCLUDE)/rtems/old-exceptions/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/old-exceptions
+ @: > $(PROJECT_INCLUDE)/rtems/old-exceptions/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/old-exceptions/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/old-exceptions/cpu.h: rtems/old-exceptions/cpu.h $(PROJECT_INCLUDE)/rtems/old-exceptions/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/old-exceptions/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/old-exceptions/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/new-exceptions/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/new-exceptions
+ @: > $(PROJECT_INCLUDE)/rtems/new-exceptions/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/new-exceptions/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/new-exceptions/cpu.h: rtems/new-exceptions/cpu.h $(PROJECT_INCLUDE)/rtems/new-exceptions/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/new-exceptions/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/new-exceptions/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/powerpc/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/powerpc
+ @: > $(PROJECT_INCLUDE)/rtems/powerpc/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/powerpc/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/powerpc/registers.h: rtems/powerpc/registers.h $(PROJECT_INCLUDE)/rtems/powerpc/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/powerpc/registers.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/powerpc/registers.h
+
diff --git a/cpukit/score/cpu/powerpc/rtems/asm.h b/cpukit/score/cpu/powerpc/rtems/asm.h
new file mode 100644
index 0000000000..b115d26c5a
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/rtems/asm.h
@@ -0,0 +1,261 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ */
+
+/*
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ * COPYRIGHT (c) 1995.
+ * i-cubed ltd.
+ *
+ * COPYRIGHT (c) 1994.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/powerpc.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#ifndef __FLOAT_REGISTER_PREFIX__
+#define __FLOAT_REGISTER_PREFIX__ __REGISTER_PREFIX__
+#endif
+
+#ifndef __PROC_LABEL_PREFIX__
+#define __PROC_LABEL_PREFIX__ __USER_LABEL_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for procedure labels. */
+
+#define PROC(x) CONCAT1 (__PROC_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/* Use the right prefix for floating point registers. */
+
+#define FREG(x) CONCAT1 (__FLOAT_REGISTER_PREFIX__, x)
+
+/*
+ * define macros for all of the registers on this CPU
+ *
+ * EXAMPLE: #define d0 REG (d0)
+ */
+#define r0 REG(0)
+#define r1 REG(1)
+#define r2 REG(2)
+#define r3 REG(3)
+#define r4 REG(4)
+#define r5 REG(5)
+#define r6 REG(6)
+#define r7 REG(7)
+#define r8 REG(8)
+#define r9 REG(9)
+#define r10 REG(10)
+#define r11 REG(11)
+#define r12 REG(12)
+#define r13 REG(13)
+#define r14 REG(14)
+#define r15 REG(15)
+#define r16 REG(16)
+#define r17 REG(17)
+#define r18 REG(18)
+#define r19 REG(19)
+#define r20 REG(20)
+#define r21 REG(21)
+#define r22 REG(22)
+#define r23 REG(23)
+#define r24 REG(24)
+#define r25 REG(25)
+#define r26 REG(26)
+#define r27 REG(27)
+#define r28 REG(28)
+#define r29 REG(29)
+#define r30 REG(30)
+#define r31 REG(31)
+#define f0 FREG(0)
+#define f1 FREG(1)
+#define f2 FREG(2)
+#define f3 FREG(3)
+#define f4 FREG(4)
+#define f5 FREG(5)
+#define f6 FREG(6)
+#define f7 FREG(7)
+#define f8 FREG(8)
+#define f9 FREG(9)
+#define f10 FREG(10)
+#define f11 FREG(11)
+#define f12 FREG(12)
+#define f13 FREG(13)
+#define f14 FREG(14)
+#define f15 FREG(15)
+#define f16 FREG(16)
+#define f17 FREG(17)
+#define f18 FREG(18)
+#define f19 FREG(19)
+#define f20 FREG(20)
+#define f21 FREG(21)
+#define f22 FREG(22)
+#define f23 FREG(23)
+#define f24 FREG(24)
+#define f25 FREG(25)
+#define f26 FREG(26)
+#define f27 FREG(27)
+#define f28 FREG(28)
+#define f29 FREG(29)
+#define f30 FREG(30)
+#define f31 FREG(31)
+
+/*
+ * Some special purpose registers (SPRs).
+ */
+#define srr0 0x01a
+#define srr1 0x01b
+#if defined(ppc403) || defined(ppc405)
+#define srr2 0x3de /* IBM 400 series only */
+#define srr3 0x3df /* IBM 400 series only */
+#endif /* ppc403 or ppc405 */
+
+#define sprg0 0x110
+#define sprg1 0x111
+#define sprg2 0x112
+#define sprg3 0x113
+
+#define dar 0x013 /* Data Address Register */
+#define dec 0x016 /* Decrementer Register */
+
+#if defined(ppc403) || defined(ppc405)
+/* the following SPR/DCR registers exist only in IBM 400 series */
+#define dear 0x3d5
+#define evpr 0x3d6 /* SPR: exception vector prefix register */
+#define iccr 0x3fb /* SPR: instruction cache control reg. */
+#define dccr 0x3fa /* SPR: data cache control reg. */
+
+#if defined (ppc403)
+#define exisr 0x040 /* DCR: external interrupt status register */
+#define exier 0x042 /* DCR: external interrupt enable register */
+#endif /* ppc403 */
+#if defined(ppc405)
+#define exisr 0x0C0 /* DCR: external interrupt status register */
+#define exier 0x0C2 /* DCR: external interrupt enable register */
+#endif /* ppc405 */
+
+#define br0 0x080 /* DCR: memory bank register 0 */
+#define br1 0x081 /* DCR: memory bank register 1 */
+#define br2 0x082 /* DCR: memory bank register 2 */
+#define br3 0x083 /* DCR: memory bank register 3 */
+#define br4 0x084 /* DCR: memory bank register 4 */
+#define br5 0x085 /* DCR: memory bank register 5 */
+#define br6 0x086 /* DCR: memory bank register 6 */
+#define br7 0x087 /* DCR: memory bank register 7 */
+/* end of IBM400 series register definitions */
+
+#elif defined(mpc555)
+/* The following registers are for the MPC5xx */
+#define eie 0x050 /* External Interrupt Enable Register */
+#define eid 0x051 /* External Interrupt Disable Register */
+#define nri 0x052 /* Non-Recoverable Interrupt Register */
+
+#elif defined(mpc860) || defined(mpc821)
+/* The following registers are for the MPC8x0 */
+#define der 0x095 /* Debug Enable Register */
+#define ictrl 0x09E /* Instruction Support Control Register */
+#define immr 0x27E /* Internal Memory Map Register */
+/* end of MPC8x0 registers */
+#endif
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC_VAR(sym) .globl SYM (sym)
+#define EXTERN_VAR(sym) .extern SYM (sym)
+#define PUBLIC_PROC(sym) .globl PROC (sym)
+#define EXTERN_PROC(sym) .extern PROC (sym)
+
+/* Other potentially assembler specific operations */
+#if PPC_ASM == PPC_ASM_ELF
+#define ALIGN(n,p) .align p
+#define DESCRIPTOR(x) \
+ .section .descriptors,"aw"; \
+ PUBLIC_VAR (x); \
+SYM (x):; \
+ .long PROC (x); \
+ .long s.got; \
+ .long 0
+
+#define EXT_SYM_REF(x) .long x
+#define EXT_PROC_REF(x) .long x
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA .data
+#define END_DATA
+#define BEGIN_BSS .bss
+#define END_BSS
+#define END
+
+#else
+#error "PPC_ASM_TYPE is not properly defined"
+#endif
+#ifndef PPC_ASM
+#error "PPC_ASM_TYPE is not properly defined"
+#endif
+
+
+#endif
diff --git a/cpukit/score/cpu/powerpc/rtems/new-exceptions/cpu.h b/cpukit/score/cpu/powerpc/rtems/new-exceptions/cpu.h
new file mode 100644
index 0000000000..23db538a7f
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/rtems/new-exceptions/cpu.h
@@ -0,0 +1,374 @@
+/* cpu.h
+ *
+ * This include file contains information pertaining to the PowerPC
+ * processor.
+ *
+ * Modified for MPC8260 Andy Dachs <a.dachs@sstl.co.uk>
+ * Surrey Satellite Technology Limited (SSTL), 2001
+ *
+ * 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.h:
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_NEW_EXCEPTIONS_CPU_H
+#define _RTEMS_NEW_EXCEPTIONS_CPU_H
+
+#ifndef _RTEMS_SCORE_CPU_H
+#error "You should include <rtems/score/cpu.h>"
+#endif
+
+#include <rtems/powerpc/registers.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* conditional compilation parameters */
+
+/*
+ * Does RTEMS manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in _ISR_Handler_initialization.
+ * If FALSE, nothing is done.
+ *
+ * If the CPU supports a dedicated interrupt stack in hardware,
+ * then it is generally the responsibility of the BSP to allocate it
+ * and set it up.
+ *
+ * If the CPU does not support a dedicated interrupt stack, then
+ * the porter has two options: (1) execute interrupts on the
+ * stack of the interrupted task, and (2) have RTEMS manage a dedicated
+ * interrupt stack.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
+
+/*
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * If TRUE, then it must be installed during initialization.
+ * If FALSE, then no installation is performed.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ */
+
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
+
+/*
+ * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * If TRUE, then the memory is allocated during initialization.
+ * If FALSE, then the memory is allocated during initialization.
+ *
+ * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
+ */
+
+#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
+
+/*
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ */
+
+#define CPU_ISR_PASSES_FRAME_POINTER 0
+
+/*
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ *
+ * If the floating point context does NOT have to be saved as part of
+ * interrupt dispatching, then it should be safe to set this to TRUE.
+ *
+ * Setting this flag to TRUE results in using a different algorithm
+ * for deciding when to save and restore the floating point context.
+ * The deferred FP switch algorithm minimizes the number of times
+ * the FP context is saved and restored. The FP context is not saved
+ * until a context switch is made to another, different FP task.
+ * Thus in a system with only one FP task, the FP context will never
+ * be saved or restored.
+ *
+ * Note, however that compilers may use floating point registers/
+ * instructions for optimization or they may save/restore FP registers
+ * on the stack. You must not use deferred switching in these cases
+ * and on the PowerPC attempting to do so will raise a "FP unavailable"
+ * exception.
+ */
+/*
+ * ACB Note: This could make debugging tricky..
+ */
+
+/* conservative setting (FALSE); probably doesn't affect performance too much */
+#define CPU_USE_DEFERRED_FP_SWITCH FALSE
+
+/*
+ * Processor defined structures required for cpukit/score.
+ */
+
+#ifndef ASM
+
+/*
+ * The following table contains the information required to configure
+ * the PowerPC processor specific parameters.
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+ /* end of fields required on all CPUs */
+
+ uint32_t clicks_per_usec; /* Timer clicks per microsecond */
+ boolean exceptions_in_RAM; /* TRUE if in RAM */
+
+#if (defined(ppc403) || defined(ppc405) \
+ || defined(mpc860) || defined(mpc821) || defined(mpc8260))
+ uint32_t serial_per_sec; /* Serial clocks per second */
+ boolean serial_external_clock;
+ boolean serial_xon_xoff;
+ boolean serial_cts_rts;
+ uint32_t serial_rate;
+ uint32_t timer_average_overhead; /* Average overhead of timer in ticks */
+ uint32_t timer_least_valid; /* Least valid number from timer */
+ boolean timer_internal_clock; /* TRUE, when timer runs with CPU clk */
+#endif
+
+#if (defined(mpc555) \
+ || defined(mpc860) || defined(mpc821) || defined(mpc8260))
+ uint32_t clock_speed; /* Speed of CPU in Hz */
+#endif
+} rtems_cpu_table;
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ */
+
+/*
+ * This variable is optional. It is used on CPUs on which it is difficult
+ * to generate an "uninitialized" FP context. It is filled in by
+ * _CPU_Initialize and copied into the task's FP context area during
+ * _CPU_Context_Initialize.
+ */
+
+/* EXTERN Context_Control_fp _CPU_Null_fp_context; */
+
+/*
+ * On some CPUs, RTEMS supports a software managed interrupt stack.
+ * This stack is allocated by the Interrupt Manager and the switch
+ * is performed in _ISR_Handler. These variables contain pointers
+ * to the lowest and highest addresses in the chunk of memory allocated
+ * for the interrupt stack. Since it is unknown whether the stack
+ * grows up or down (in general), this give the CPU dependent
+ * code the option of picking the version it wants to use.
+ *
+ * NOTE: These two variables are required if the macro
+ * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
+ */
+
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+#endif /* ndef ASM */
+
+/*
+ * This defines the number of levels and the mask used to pick those
+ * bits out of a thread mode.
+ */
+
+#define CPU_MODES_INTERRUPT_LEVEL 0x00000001 /* interrupt level in mode */
+#define CPU_MODES_INTERRUPT_MASK 0x00000001 /* interrupt level in mode */
+
+/*
+ * With some compilation systems, it is difficult if not impossible to
+ * call a high-level language routine from assembly language. This
+ * is especially true of commercial Ada compilers and name mangling
+ * C++ ones. This variable can be optionally defined by the CPU porter
+ * and contains the address of the routine _Thread_Dispatch. This
+ * can make it easier to invoke that routine at the end of the interrupt
+ * sequence (if a dispatch is necessary).
+ */
+
+/* EXTERN void (*_CPU_Thread_dispatch_pointer)(); */
+
+/*
+ * Nothing prevents the porter from declaring more CPU specific variables.
+ */
+
+#ifndef ASM
+
+SCORE_EXTERN struct {
+ uint32_t *Disable_level;
+ void *Stack;
+ volatile boolean *Switch_necessary;
+ boolean *Signal;
+
+} _CPU_IRQ_info CPU_STRUCTURE_ALIGNMENT;
+
+#endif /* ndef ASM */
+
+/*
+ * The size of the floating point context area. On some CPUs this
+ * will not be a "sizeof" because the format of the floating point
+ * area is not defined -- only the size is. This is usually on
+ * CPUs with a "floating point save context" instruction.
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/*
+ * (Optional) # of bytes for libmisc/stackchk to check
+ * If not specifed, then it defaults to something reasonable
+ * for most architectures.
+ */
+
+#define CPU_STACK_CHECK_SIZE (128)
+
+/*
+ * Amount of extra stack (above minimum stack size) required by
+ * MPCI receive server thread. Remember that in a multiprocessor
+ * system this thread must exist and be able to process all directives.
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+/*
+ * This defines the number of entries in the ISR_Vector_table managed
+ * by RTEMS.
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS (PPC_INTERRUPT_MAX)
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (PPC_INTERRUPT_MAX - 1)
+
+/*
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level. Note that
+ * this is not an option - RTEMS/score _relies_ on _ISR_Nest_level
+ * being maintained (e.g. watchdog queues).
+ */
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/*
+ * ISR handler macros
+ */
+
+#define _CPU_Initialize_vectors()
+
+/*
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in _isr_cookie.
+ */
+
+#ifndef ASM
+
+static inline uint32_t _CPU_ISR_Get_level( void )
+{
+ register unsigned int msr;
+ _CPU_MSR_GET(msr);
+ if (msr & MSR_EE) return 0;
+ else return 1;
+}
+
+static inline void _CPU_ISR_Set_level( uint32_t level )
+{
+ register unsigned int msr;
+ _CPU_MSR_GET(msr);
+ if (!(level & CPU_MODES_INTERRUPT_MASK)) {
+ msr |= MSR_EE;
+ }
+ else {
+ msr &= ~MSR_EE;
+ }
+ _CPU_MSR_SET(msr);
+}
+
+void BSP_panic(char *);
+
+/* Fatal Error manager macros */
+
+/*
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ */
+
+void _BSP_Fatal_error(unsigned int);
+
+#define _CPU_Fatal_halt( _error ) \
+ _BSP_Fatal_error(_error)
+
+/* end of Fatal Error manager macros */
+
+/*
+ * Until all new-exception processing BSPs have fixed
+ * PR288, we let the good BSPs pass
+ *
+ * PPC_BSP_HAS_FIXED_PR288
+ *
+ * in SPRG0 and let _CPU_Initialize assert this.
+ */
+
+#define PPC_BSP_HAS_FIXED_PR288 0x600dbabe
+
+#endif /* ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/powerpc/rtems/old-exceptions/cpu.h b/cpukit/score/cpu/powerpc/rtems/old-exceptions/cpu.h
new file mode 100644
index 0000000000..19b76da56b
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/rtems/old-exceptions/cpu.h
@@ -0,0 +1,506 @@
+/* cpu.h
+ *
+ * This include file contains information pertaining to the PowerPC
+ * processor.
+ *
+ * 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.h:
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_OLD_EXCEPTIONS_CPU_H
+#define _RTEMS_OLD_EXCEPTIONS_CPU_H
+
+#ifndef _RTEMS_SCORE_CPU_H
+#error "You should include <rtems/score/cpu.h>"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ASM
+struct CPU_Interrupt_frame;
+typedef void ( *ppc_isr_entry )( int, struct CPU_Interrupt_frame * );
+#endif
+
+/* conditional compilation parameters */
+
+/*
+ * Does RTEMS manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in _ISR_Handler_initialization.
+ * If FALSE, nothing is done.
+ *
+ * If the CPU supports a dedicated interrupt stack in hardware,
+ * then it is generally the responsibility of the BSP to allocate it
+ * and set it up.
+ *
+ * If the CPU does not support a dedicated interrupt stack, then
+ * the porter has two options: (1) execute interrupts on the
+ * stack of the interrupted task, and (2) have RTEMS manage a dedicated
+ * interrupt stack.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
+
+/*
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * If TRUE, then it must be installed during initialization.
+ * If FALSE, then no installation is performed.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ */
+
+/*
+ * ACB: This is a lie, but it gets us a handle on a call to set up
+ * a variable derived from the top of the interrupt stack.
+ */
+
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
+
+/*
+ * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * If TRUE, then the memory is allocated during initialization.
+ * If FALSE, then the memory is allocated during initialization.
+ *
+ * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
+ */
+
+#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
+
+/*
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ */
+
+#define CPU_ISR_PASSES_FRAME_POINTER 1
+
+/*
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ *
+ * If the floating point context does NOT have to be saved as part of
+ * interrupt dispatching, then it should be safe to set this to TRUE.
+ *
+ * Setting this flag to TRUE results in using a different algorithm
+ * for deciding when to save and restore the floating point context.
+ * The deferred FP switch algorithm minimizes the number of times
+ * the FP context is saved and restored. The FP context is not saved
+ * until a context switch is made to another, different FP task.
+ * Thus in a system with only one FP task, the FP context will never
+ * be saved or restored.
+ */
+/*
+ * ACB Note: This could make debugging tricky..
+ */
+
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+/*
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
+ *
+ * The interrupt level is bit mapped for the PowerPC family. The
+ * bits are set to 0 to indicate that a particular exception source
+ * enabled and 1 if it is disabled. This keeps with RTEMS convention
+ * that interrupt level 0 means all sources are enabled.
+ *
+ * The bits are assigned to correspond to enable bits in the MSR.
+ */
+
+#define PPC_INTERRUPT_LEVEL_ME 0x01
+#define PPC_INTERRUPT_LEVEL_EE 0x02
+#define PPC_INTERRUPT_LEVEL_CE 0x04
+
+/* XXX should these be maskable? */
+#if 0
+#define PPC_INTERRUPT_LEVEL_DE 0x08
+#define PPC_INTERRUPT_LEVEL_BE 0x10
+#define PPC_INTERRUPT_LEVEL_SE 0x20
+#endif
+
+#define CPU_MODES_INTERRUPT_MASK 0x00000007
+
+/*
+ * Processor defined structures required for cpukit/score.
+ */
+
+#ifndef ASM
+/*
+ * The following table contains the information required to configure
+ * the PowerPC processor specific parameters.
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+ /* end of fields required on all CPUs */
+
+ uint32_t clicks_per_usec; /* Timer clicks per microsecond */
+ void (*spurious_handler)(uint32_t vector, CPU_Interrupt_frame *);
+ boolean exceptions_in_RAM; /* TRUE if in RAM */
+
+#if (defined(ppc403) || defined(ppc405) \
+ || defined(mpc860) || defined(mpc821) || defined(mpc8260))
+ uint32_t serial_per_sec; /* Serial clocks per second */
+ boolean serial_external_clock;
+ boolean serial_xon_xoff;
+ boolean serial_cts_rts;
+ uint32_t serial_rate;
+ uint32_t timer_average_overhead; /* Average overhead of timer in ticks */
+ uint32_t timer_least_valid; /* Least valid number from timer */
+ boolean timer_internal_clock; /* TRUE, when timer runs with CPU clk */
+#endif
+
+#if (defined(mpc555) \
+ || defined(mpc860) || defined(mpc821) || defined(mpc8260))
+ uint32_t clock_speed; /* Speed of CPU in Hz */
+#endif
+} rtems_cpu_table;
+#endif
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ */
+
+/*
+ * Macros to access PowerPC specific additions to the CPU Table
+ */
+
+#ifndef ASM
+#define rtems_cpu_configuration_get_spurious_handler() \
+ (_CPU_Table.spurious_handler)
+#endif /* ASM */
+
+/*
+ * The following type defines an entry in the PPC's trap table.
+ *
+ * NOTE: The instructions chosen are RTEMS dependent although one is
+ * obligated to use two of the four instructions to perform a
+ * long jump. The other instructions load one register with the
+ * trap type (a.k.a. vector) and another with the psr.
+ */
+
+#ifndef ASM
+typedef struct {
+ uint32_t stwu_r1; /* stwu %r1, -(??+IP_END)(%1)*/
+ uint32_t stw_r0; /* stw %r0, IP_0(%r1) */
+ uint32_t li_r0_IRQ; /* li %r0, _IRQ */
+ uint32_t b_Handler; /* b PROC (_ISR_Handler) */
+} CPU_Trap_table_entry;
+#endif
+
+/*
+ * This variable is optional. It is used on CPUs on which it is difficult
+ * to generate an "uninitialized" FP context. It is filled in by
+ * _CPU_Initialize and copied into the task's FP context area during
+ * _CPU_Context_Initialize.
+ */
+
+#ifndef ASM
+/* EXTERN Context_Control_fp _CPU_Null_fp_context; */
+#endif
+
+/*
+ * On some CPUs, RTEMS supports a software managed interrupt stack.
+ * This stack is allocated by the Interrupt Manager and the switch
+ * is performed in _ISR_Handler. These variables contain pointers
+ * to the lowest and highest addresses in the chunk of memory allocated
+ * for the interrupt stack. Since it is unknown whether the stack
+ * grows up or down (in general), this give the CPU dependent
+ * code the option of picking the version it wants to use.
+ *
+ * NOTE: These two variables are required if the macro
+ * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
+ */
+
+#ifndef ASM
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+#endif
+
+/*
+ * With some compilation systems, it is difficult if not impossible to
+ * call a high-level language routine from assembly language. This
+ * is especially true of commercial Ada compilers and name mangling
+ * C++ ones. This variable can be optionally defined by the CPU porter
+ * and contains the address of the routine _Thread_Dispatch. This
+ * can make it easier to invoke that routine at the end of the interrupt
+ * sequence (if a dispatch is necessary).
+ */
+
+#ifndef ASM
+/* EXTERN void (*_CPU_Thread_dispatch_pointer)(); */
+#endif
+
+/*
+ * Nothing prevents the porter from declaring more CPU specific variables.
+ */
+
+
+#ifndef ASM
+SCORE_EXTERN struct {
+ uint32_t volatile* Nest_level;
+ uint32_t volatile* Disable_level;
+ void *Vector_table;
+ void *Stack;
+ uint32_t Default_r2;
+ uint32_t Default_r13;
+ volatile boolean *Switch_necessary;
+ boolean *Signal;
+
+ uint32_t msr_initial;
+} _CPU_IRQ_info CPU_STRUCTURE_ALIGNMENT;
+#endif
+
+/*
+ * The size of the floating point context area. On some CPUs this
+ * will not be a "sizeof" because the format of the floating point
+ * area is not defined -- only the size is. This is usually on
+ * CPUs with a "floating point save context" instruction.
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/*
+ * (Optional) # of bytes for libmisc/stackchk to check
+ * If not specifed, then it defaults to something reasonable
+ * for most architectures.
+ */
+
+#define CPU_STACK_CHECK_SIZE (128)
+
+/*
+ * Amount of extra stack (above minimum stack size) required by
+ * MPCI receive server thread. Remember that in a multiprocessor
+ * system this thread must exist and be able to process all directives.
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+/*
+ * This defines the number of entries in the ISR_Vector_table managed
+ * by RTEMS.
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS (PPC_INTERRUPT_MAX)
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (PPC_INTERRUPT_MAX - 1)
+
+/*
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level.
+ */
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS TRUE
+
+/*
+ * ISR handler macros
+ */
+
+#ifndef ASM
+void _CPU_Initialize_vectors(void);
+#endif
+
+/*
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in _isr_cookie.
+ */
+
+#ifndef ASM
+extern const unsigned int _PPC_MSR_DISABLE_MASK;
+
+#define _CPU_MSR_GET( _msr_value ) \
+ do { \
+ _msr_value = 0; \
+ asm volatile ("mfmsr %0" : "=&r" ((_msr_value)) : "0" ((_msr_value))); \
+ } while (0)
+
+/* FIXME: Backward compatibility
+ * new-exception-processing uses _CPU_MSR_GET
+ * old-exception-processing had used _CPU_MSR_Value
+ */
+#define _CPU_MSR_Value(_msr_value) _CPU_MSR_GET(_msr_value)
+
+#define _CPU_MSR_SET( _msr_value ) \
+{ asm volatile ("mtmsr %0" : "=&r" ((_msr_value)) : "0" ((_msr_value))); }
+
+#if 0
+#define _CPU_ISR_Disable( _isr_cookie ) \
+ { register unsigned int _disable_mask = _PPC_MSR_DISABLE_MASK; \
+ _isr_cookie = 0; \
+ asm volatile (
+ "mfmsr %0" : \
+ "=r" ((_isr_cookie)) : \
+ "0" ((_isr_cookie)) \
+ ); \
+ asm volatile (
+ "andc %1,%0,%1" : \
+ "=r" ((_isr_cookie)), "=&r" ((_disable_mask)) : \
+ "0" ((_isr_cookie)), "1" ((_disable_mask)) \
+ ); \
+ asm volatile (
+ "mtmsr %1" : \
+ "=r" ((_disable_mask)) : \
+ "0" ((_disable_mask)) \
+ ); \
+ }
+#endif
+
+#define _CPU_ISR_Disable( _isr_cookie ) \
+ { register unsigned int _disable_mask = _PPC_MSR_DISABLE_MASK; \
+ _isr_cookie = 0; \
+ asm volatile ( \
+ "mfmsr %0; andc %1,%0,%1; mtmsr %1" : \
+ "=&r" ((_isr_cookie)), "=&r" ((_disable_mask)) : \
+ "0" ((_isr_cookie)), "1" ((_disable_mask)) \
+ ); \
+ }
+#endif
+
+/*
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * _isr_cookie is not modified.
+ */
+
+#ifndef ASM
+#define _CPU_ISR_Enable( _isr_cookie ) \
+ { \
+ asm volatile ( "mtmsr %0" : \
+ "=r" ((_isr_cookie)) : \
+ "0" ((_isr_cookie))); \
+ }
+#endif
+
+/*
+ * This temporarily restores the interrupt to _isr_cookie before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _isr_cookie is not
+ * modified.
+ *
+ * NOTE: The version being used is not very optimized but it does
+ * not trip a problem in gcc where the disable mask does not
+ * get loaded. Check this for future (post 10/97 gcc versions.
+ */
+
+#ifndef ASM
+#define _CPU_ISR_Flash( _isr_cookie ) \
+ { register unsigned int _disable_mask = _PPC_MSR_DISABLE_MASK; \
+ asm volatile ( \
+ "mtmsr %0; andc %1,%0,%1; mtmsr %1" : \
+ "=&r" ((_isr_cookie)), "=&r" ((_disable_mask)) : \
+ "0" ((_isr_cookie)), "1" ((_disable_mask)) \
+ ); \
+ }
+#endif
+
+/*
+ * Map interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a generic fashion are undefined. Someday,
+ * it would be nice if these were "mapped" by the application
+ * via a callout. For example, m68k has 8 levels 0 - 7, levels
+ * 8 - 255 would be available for bsp/application specific meaning.
+ * This could be used to manage a programmable interrupt controller
+ * via the rtems_task_mode directive.
+ */
+
+#ifndef ASM
+uint32_t _CPU_ISR_Calculate_level(
+ uint32_t new_level
+);
+
+void _CPU_ISR_Set_level(
+ uint32_t new_level
+);
+
+uint32_t _CPU_ISR_Get_level( void );
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+#endif
+
+/* end of ISR handler macros */
+
+/* Fatal Error manager macros */
+
+/*
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ */
+
+#define _CPU_Fatal_halt( _error ) \
+ _CPU_Fatal_error(_error)
+
+/* end of Fatal Error manager macros */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/powerpc/rtems/powerpc/registers.h b/cpukit/score/cpu/powerpc/rtems/powerpc/registers.h
new file mode 100644
index 0000000000..f9cab2f565
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/rtems/powerpc/registers.h
@@ -0,0 +1,349 @@
+/*
+ * This file contains some powerpc MSR and registers access definitions.
+ *
+ * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
+ * Canon Centre Recherche France.
+ *
+ * Added MPC8260 Andy Dachs <a.dachs@sstl.co.uk>
+ * Surrey Satellite Technology Limited
+ *
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_POWERPC_REGISTERS_H
+#define _RTEMS_POWERPC_REGISTERS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Bit encodings for Machine State Register (MSR) */
+#define MSR_VE (1<<25) /* Alti-Vec enable (7400+) */
+#define MSR_POW (1<<18) /* Enable Power Management */
+#define MSR_TGPR (1<<17) /* TLB Update registers in use */
+#define MSR_ILE (1<<16) /* Interrupt Little-Endian enable */
+#define MSR_EE (1<<15) /* External Interrupt enable */
+#define MSR_PR (1<<14) /* Supervisor/User privilege */
+#define MSR_FP (1<<13) /* Floating Point enable */
+#define MSR_ME (1<<12) /* Machine Check enable */
+#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */
+#define MSR_SE (1<<10) /* Single Step */
+#define MSR_BE (1<<9) /* Branch Trace */
+#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */
+#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */
+#define MSR_IR (1<<5) /* Instruction MMU enable */
+#define MSR_DR (1<<4) /* Data MMU enable */
+#define MSR_RI (1<<1) /* Recoverable Exception */
+#define MSR_LE (1<<0) /* Little-Endian enable */
+
+#define MSR_ MSR_ME|MSR_RI
+#define MSR_KERNEL MSR_|MSR_IR|MSR_DR
+#define MSR_USER MSR_KERNEL|MSR_PR|MSR_EE
+
+/* Bit encodings for Hardware Implementation Register (HID0)
+ on PowerPC 603, 604, etc. processors (not 601). */
+
+/* WARNING: HID0/HID1 are *truely* implementation dependent!
+ * you *cannot* rely on the same bits to be present,
+ * at the same place or even in the same register
+ * on different CPU familys.
+ * E.g., EMCP isHID0_DOZE is HID0_HI_BAT_EN on the
+ * on the 7450s. IFFT is XBSEN on 7450 and so on...
+ */
+#define HID0_EMCP (1<<31) /* Enable Machine Check pin */
+#define HID0_EBA (1<<29) /* Enable Bus Address Parity */
+#define HID0_EBD (1<<28) /* Enable Bus Data Parity */
+#define HID0_SBCLK (1<<27)
+#define HID0_TBEN (1<<26) /* 7455:this bit must be set
+ * and TBEN signal must be asserted
+ * to enable the time base and
+ * decrementer.
+ */
+#define HID0_EICE (1<<26)
+#define HID0_ECLK (1<<25)
+#define HID0_PAR (1<<24)
+#define HID0_DOZE (1<<23)
+/* this HI_BAT_EN only on 7445, 7447, 7448, 7455 & 7457 !! */
+#define HID0_7455_HIGH_BAT_EN (1<<23)
+
+#define HID0_NAP (1<<22)
+#define HID0_SLEEP (1<<21)
+#define HID0_DPM (1<<20)
+#define HID0_ICE (1<<15) /* Instruction Cache Enable */
+#define HID0_DCE (1<<14) /* Data Cache Enable */
+#define HID0_ILOCK (1<<13) /* Instruction Cache Lock */
+#define HID0_DLOCK (1<<12) /* Data Cache Lock */
+#define HID0_ICFI (1<<11) /* Instruction Cache Flash Invalidate */
+#define HID0_DCI (1<<10) /* Data Cache Invalidate */
+/* this bit is XSBSEN (xtended block size enable) on 7447, 7448, 7455 and 7457 only */
+#define HID0_7455_XBSEN (1<<8)
+#define HID0_SIED (1<<7) /* Serial Instruction Execution [Disable] */
+#define HID0_BTIC (1<<5) /* Branch Target Instruction Cache [Enable] */
+/* S.K. Feng 10/03, added for MPC7455 */
+#define HID0_LRSTK (1<<4) /* Link register stack enable (7455) */
+#define HID0_FOLD (1<<3) /* Branch folding enable (7455) */
+
+#define HID0_BHTE (1<<2) /* Branch History Table Enable */
+#define HID0_BTCD (1<<1) /* Branch target cache disable */
+
+/* fpscr settings */
+#define FPSCR_FX (1<<31)
+#define FPSCR_FEX (1<<30)
+
+#define _MACH_prep 1
+#define _MACH_Pmac 2 /* pmac or pmac clone (non-chrp) */
+#define _MACH_chrp 4 /* chrp machine */
+#define _MACH_mbx 8 /* Motorola MBX board */
+#define _MACH_apus 16 /* amiga with phase5 powerup */
+#define _MACH_fads 32 /* Motorola FADS board */
+
+/* see residual.h for these */
+#define _PREP_Motorola 0x01 /* motorola prep */
+#define _PREP_Firm 0x02 /* firmworks prep */
+#define _PREP_IBM 0x00 /* ibm prep */
+#define _PREP_Bull 0x03 /* bull prep */
+
+/* these are arbitrary */
+#define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */
+#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */
+
+#define _GLOBAL(n)\
+ .globl n;\
+n:
+
+#define TBRU 269 /* Time base Upper/Lower (Reading) */
+#define TBRL 268
+#define TBWU 284 /* Time base Upper/Lower (Writing) */
+#define TBWL 285
+#define XER 1
+#define LR 8
+#define CTR 9
+#define HID0 1008 /* Hardware Implementation */
+#define HID1 1009 /* Hardware Implementation */
+#define DABR 1013 /* Data Access Breakpoint */
+#define PVR 287 /* Processor Version */
+#define IBAT0U 528 /* Instruction BAT #0 Upper/Lower */
+#define IBAT0L 529
+#define IBAT1U 530 /* Instruction BAT #1 Upper/Lower */
+#define IBAT1L 531
+#define IBAT2U 532 /* Instruction BAT #2 Upper/Lower */
+#define IBAT2L 533
+#define IBAT3U 534 /* Instruction BAT #3 Upper/Lower */
+#define IBAT3L 535
+
+/* Only present on 7445, 7447, 7448, 7455 and 7457 (if HID0[HIGH_BAT_EN]) */
+#define IBAT4U 560 /* Instruction BAT #0 Upper/Lower */
+#define IBAT4L 561
+#define IBAT5U 562 /* Instruction BAT #1 Upper/Lower */
+#define IBAT5L 563
+#define IBAT6U 564 /* Instruction BAT #2 Upper/Lower */
+#define IBAT6L 565
+#define IBAT7U 566 /* Instruction BAT #3 Upper/Lower */
+#define IBAT7L 567
+
+#define DBAT0U 536 /* Data BAT #0 Upper/Lower */
+#define DBAT0L 537
+#define DBAT1U 538 /* Data BAT #1 Upper/Lower */
+#define DBAT1L 539
+#define DBAT2U 540 /* Data BAT #2 Upper/Lower */
+#define DBAT2L 541
+#define DBAT3U 542 /* Data BAT #3 Upper/Lower */
+#define DBAT3L 543
+
+/* Only present on 7445, 7447, 7448, 7455 and 7457 (if HID0[HIGH_BAT_EN]) */
+#define DBAT4U 568 /* Instruction BAT #0 Upper/Lower */
+#define DBAT4L 569
+#define DBAT5U 570 /* Instruction BAT #1 Upper/Lower */
+#define DBAT5L 571
+#define DBAT6U 572 /* Instruction BAT #2 Upper/Lower */
+#define DBAT6L 573
+#define DBAT7U 574 /* Instruction BAT #3 Upper/Lower */
+#define DBAT7L 575
+
+#define DMISS 976 /* TLB Lookup/Refresh registers */
+#define DCMP 977
+#define HASH1 978
+#define HASH2 979
+#define IMISS 980
+#define ICMP 981
+#define RPA 982
+#define SDR1 25 /* MMU hash base register */
+#define DAR 19 /* Data Address Register */
+#define SPR0 272 /* Supervisor Private Registers */
+#define SPRG0 272
+#define SPR1 273
+#define SPRG1 273
+#define SPR2 274
+#define SPRG2 274
+#define SPR3 275
+#define SPRG3 275
+#define DSISR 18
+#define SRR0 26 /* Saved Registers (exception) */
+#define SRR1 27
+#define IABR 1010 /* Instruction Address Breakpoint */
+#define DEC 22 /* Decrementer */
+#define EAR 282 /* External Address Register */
+
+#define MSSCR0 1014 /* Memory Subsystem Control Register */
+
+#define L2CR 1017 /* PPC 750 and 74xx L2 control register */
+
+#define L2CR_L2E (1<<31) /* enable */
+#define L2CR_L2I (1<<21) /* global invalidate */
+
+/* watch out L2IO and L2DO are different between 745x and 7400/7410 */
+/* Oddly, the following L2CR bit defintions in 745x
+ * is different from that of 7400 and 7410.
+ * Though not used in 7400 and 7410, it is appeded with _745x just
+ * to be clarified.
+ */
+#define L2CR_L2IO_745x 0x100000 /* (1<<20) L2 Instruction-Only */
+#define L2CR_L2DO_745x 0x10000 /* (1<<16) L2 Data-Only */
+#define L2CR_LOCK_745x (L2CR_L2IO_745x|L2CR_L2DO_745x)
+#define L2CR_L3OH0 0x00080000 /* 12:L3 output hold 0 */
+
+#define L3CR 1018 /* PPC 7450/7455 L3 control register */
+#define L3CR_L3IO_745x 0x400000 /* (1<<22) L3 Instruction-Only */
+#define L3CR_L3DO_745x 0x40 /* (1<<6) L3 Data-Only */
+
+#define L3CR_LOCK_745x (L3CR_L3IO_745x|L3CR_L3DO_745x)
+
+#define L3CR_RESERVED 0x0438003a /* Reserved bits in L3CR */
+#define L3CR_L3E 0x80000000 /* 0: L3 enable */
+#define L3CR_L3PE 0x40000000 /* 1: L3 data parity checking enable */
+#define L3CR_L3APE 0x20000000 /* 2: L3 address parity checking enable */
+#define L3CR_L3SIZ 0x10000000 /* 3: L3 size (0=1MB, 1=2MB) */
+#define L3SIZ_1M 0x00000000
+#define L3SIZ_2M 0x10000000
+#define L3CR_L3CLKEN 0x08000000 /* 4: Enables the L3_CLK[0:1] signals */
+#define L3CR_L3CLK 0x03800000 /* 6-8: L3 clock ratio */
+#define L3CLK_60 0x00000000 /* core clock / 6 */
+#define L3CLK_20 0x01000000 /* / 2 */
+#define L3CLK_25 0x01800000 /* / 2.5 */
+#define L3CLK_30 0x02000000 /* / 3 */
+#define L3CLK_35 0x02800000 /* / 3.5 */
+#define L3CLK_40 0x03000000 /* / 4 */
+#define L3CLK_50 0x03800000 /* / 5 */
+#define L3CR_L3IO 0x00400000 /* 9: L3 instruction-only mode */
+#define L3CR_L3SPO 0x00040000 /* 13: L3 sample point override */
+#define L3CR_L3CKSP 0x00030000 /* 14-15: L3 clock sample point */
+#define L3CKSP_2 0x00000000 /* 2 clocks */
+#define L3CKSP_3 0x00010000 /* 3 clocks */
+#define L3CKSP_4 0x00020000 /* 4 clocks */
+#define L3CKSP_5 0x00030000 /* 5 clocks */
+#define L3CR_L3PSP 0x0000e000 /* 16-18: L3 P-clock sample point */
+#define L3PSP_0 0x00000000 /* 0 clocks */
+#define L3PSP_1 0x00002000 /* 1 clocks */
+#define L3PSP_2 0x00004000 /* 2 clocks */
+#define L3PSP_3 0x00006000 /* 3 clocks */
+#define L3PSP_4 0x00008000 /* 4 clocks */
+#define L3PSP_5 0x0000a000 /* 5 clocks */
+#define L3CR_L3REP 0x00001000 /* 19: L3 replacement algorithm (0=default, 1=alternate) */
+#define L3CR_L3HWF 0x00000800 /* 20: L3 hardware flush */
+#define L3CR_L3I 0x00000400 /* 21: L3 global invaregisters.h.orig
+lidate */
+#define L3CR_L3RT 0x00000300 /* 22-23: L3 SRAM type */
+#define L3RT_MSUG2_DDR 0x00000000 /* MSUG2 DDR SRAM */
+#define L3RT_PIPELINE_LATE 0x00000100 /* Pipelined (register-register) synchronous late-write SRAM */
+#define L3RT_PB2_SRAM 0x00000300 /* PB2 SRAM */
+#define L3CR_L3NIRCA 0x00000080 /* 24: L3 non-integer ratios clock adjustment for the SRAM */
+#define L3CR_L3DO 0x00000040 /* 25: L3 data-only mode */
+#define L3CR_PMEN 0x00000004 /* 29: Private memory enable */
+#define L3CR_PMSIZ 0x00000004 /* 31: Private memory size (0=1MB, 1=2MB) */
+
+#define THRM1 1020
+#define THRM2 1021
+#define THRM3 1022
+#define THRM1_TIN (1<<(31-0))
+#define THRM1_TIV (1<<(31-1))
+#define THRM1_THRES (0x7f<<(31-8))
+#define THRM1_TID (1<<(31-29))
+#define THRM1_TIE (1<<(31-30))
+#define THRM1_V (1<<(31-31))
+#define THRM3_SITV (0x1fff << (31-30))
+#define THRM3_E (1<<(31-31))
+
+/* Segment Registers */
+#define SR0 0
+#define SR1 1
+#define SR2 2
+#define SR3 3
+#define SR4 4
+#define SR5 5
+#define SR6 6
+#define SR7 7
+#define SR8 8
+#define SR9 9
+#define SR10 10
+#define SR11 11
+#define SR12 12
+#define SR13 13
+#define SR14 14
+#define SR15 15
+
+#define _CPU_MSR_GET( _msr_value ) \
+ do { \
+ _msr_value = 0; \
+ asm volatile ("mfmsr %0" : "=&r" ((_msr_value)) : "0" ((_msr_value))); \
+ } while (0)
+
+#define _CPU_MSR_SET( _msr_value ) \
+{ asm volatile ("mtmsr %0" : "=&r" ((_msr_value)) : "0" ((_msr_value))); }
+
+#define _CPU_ISR_Disable( _isr_cookie ) \
+ { register unsigned int _disable_mask = MSR_EE; \
+ _isr_cookie = 0; \
+ asm volatile ( \
+ "mfmsr %0; andc %1,%0,%1; mtmsr %1" : \
+ "=&r" ((_isr_cookie)), "=&r" ((_disable_mask)) : \
+ "0" ((_isr_cookie)), "1" ((_disable_mask)) \
+ ); \
+ }
+
+
+/*
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * _isr_cookie is not modified.
+ */
+
+#define _CPU_ISR_Enable( _isr_cookie ) \
+ { \
+ asm volatile ( "mtmsr %0" : \
+ "=r" ((_isr_cookie)) : \
+ "0" ((_isr_cookie))); \
+ }
+
+/*
+ * This temporarily restores the interrupt to _isr_cookie before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _isr_cookie is not
+ * modified.
+ *
+ * NOTE: The version being used is not very optimized but it does
+ * not trip a problem in gcc where the disable mask does not
+ * get loaded. Check this for future (post 10/97 gcc versions.
+ */
+
+#define _CPU_ISR_Flash( _isr_cookie ) \
+ { register unsigned int _disable_mask = MSR_EE; \
+ asm volatile ( \
+ "mtmsr %0; andc %1,%0,%1; mtmsr %1" : \
+ "=&r" ((_isr_cookie)), "=&r" ((_disable_mask)) : \
+ "0" ((_isr_cookie)), "1" ((_disable_mask)) \
+ ); \
+ }
+
+
+/* end of ISR handler macros */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_POWERPC_REGISTERS_H */
diff --git a/cpukit/score/cpu/powerpc/rtems/score/cpu.h b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
new file mode 100644
index 0000000000..b3115bb312
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
@@ -0,0 +1,783 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#include <rtems/score/powerpc.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+
+/* conditional compilation parameters */
+
+/*
+ * Should the calls to _Thread_Enable_dispatch be inlined?
+ *
+ * If TRUE, then they are inlined.
+ * If FALSE, then a subroutine call is made.
+ *
+ * Basically this is an example of the classic trade-off of size
+ * versus speed. Inlining the call (TRUE) typically increases the
+ * size of RTEMS while speeding up the enabling of dispatching.
+ * [NOTE: In general, the _Thread_Dispatch_disable_level will
+ * only be 0 or 1 unless you are in an interrupt handler and that
+ * interrupt handler invokes the executive.] When not inlined
+ * something calls _Thread_Enable_dispatch which in turns calls
+ * _Thread_Dispatch. If the enable dispatch is inlined, then
+ * one subroutine call is avoided entirely.]
+ */
+
+#define CPU_INLINE_ENABLE_DISPATCH FALSE
+
+/*
+ * Should the body of the search loops in _Thread_queue_Enqueue_priority
+ * be unrolled one time? In unrolled each iteration of the loop examines
+ * two "nodes" on the chain being searched. Otherwise, only one node
+ * is examined per iteration.
+ *
+ * If TRUE, then the loops are unrolled.
+ * If FALSE, then the loops are not unrolled.
+ *
+ * The primary factor in making this decision is the cost of disabling
+ * and enabling interrupts (_ISR_Flash) versus the cost of rest of the
+ * body of the loop. On some CPUs, the flash is more expensive than
+ * one iteration of the loop body. In this case, it might be desirable
+ * to unroll the loop. It is important to note that on some CPUs, this
+ * code is the longest interrupt disable period in RTEMS. So it is
+ * necessary to strike a balance when setting this parameter.
+ */
+
+#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE
+
+/*
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine _CPU_Thread_Idle_body
+ * must be provided and is the default IDLE thread body instead of
+ * _CPU_Thread_Idle_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ *
+ * This is intended to allow for supporting processors which have
+ * a low power or idle mode. When the IDLE thread is executed, then
+ * the CPU can be powered down.
+ *
+ * The order of precedence for selecting the IDLE thread body is:
+ *
+ * 1. BSP provided
+ * 2. CPU dependent (if provided)
+ * 3. generic (if no BSP and no CPU dependent)
+ */
+
+#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
+
+/*
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * If TRUE, then the grows upward.
+ * If FALSE, then the grows toward smaller addresses.
+ */
+
+#define CPU_STACK_GROWS_UP FALSE
+
+/*
+ * The following is the variable attribute used to force alignment
+ * of critical RTEMS structures. On some processors it may make
+ * sense to have these aligned on tighter boundaries than
+ * the minimum requirements of the compiler in order to have as
+ * much of the critical data area as possible in a cache line.
+ *
+ * The placement of this macro in the declaration of the variables
+ * is based on the syntactically requirements of the GNU C
+ * "__attribute__" extension. For example with GNU C, use
+ * the following to force a structures to a 32 byte boundary.
+ *
+ * __attribute__ ((aligned (32)))
+ *
+ * NOTE: Currently only the Priority Bit Map table uses this feature.
+ * To benefit from using this, the data must be heavily
+ * used so it will stay in the cache and used frequently enough
+ * in the executive to justify turning this on.
+ */
+
+#define CPU_STRUCTURE_ALIGNMENT \
+ __attribute__ ((aligned (PPC_CACHE_ALIGNMENT)))
+
+/*
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ */
+
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+
+#if defined(__BIG_ENDIAN__) || defined(_BIG_ENDIAN)
+#define CPU_BIG_ENDIAN TRUE
+#define CPU_LITTLE_ENDIAN FALSE
+#else
+#define CPU_BIG_ENDIAN FALSE
+#define CPU_LITTLE_ENDIAN TRUE
+#endif
+
+/*
+ * Does the CPU have hardware floating point?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
+ *
+ * If there is a FP coprocessor such as the i387 or mc68881, then
+ * the answer is TRUE.
+ *
+ * The macro name "PPC_HAS_FPU" should be made CPU specific.
+ * It indicates whether or not this CPU model has FP support. For
+ * example, it would be possible to have an i386_nofp CPU model
+ * which set this to false to indicate that you have an i386 without
+ * an i387 and wish to leave floating point support out of RTEMS.
+ */
+
+#if ( PPC_HAS_FPU == 1 )
+#define CPU_HARDWARE_FP TRUE
+#define CPU_SOFTWARE_FP FALSE
+#else
+#define CPU_HARDWARE_FP FALSE
+#define CPU_SOFTWARE_FP FALSE
+#endif
+
+/*
+ * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
+ *
+ * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
+ *
+ * PowerPC Note: It appears the GCC can implicitly generate FPU
+ * and Altivec instructions when you least expect them. So make
+ * all tasks floating point.
+ */
+
+#define CPU_ALL_TASKS_ARE_FP CPU_HARDWARE_FP
+
+/*
+ * Should the IDLE task have a floating point context?
+ *
+ * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * If FALSE, then the IDLE task does not have a floating point context.
+ *
+ * Setting this to TRUE negatively impacts the time required to preempt
+ * the IDLE task from an interrupt because the floating point context
+ * must be saved as part of the preemption.
+ */
+
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+/*
+ * Processor defined structures required for cpukit/score.
+ */
+
+/*
+ * Contexts
+ *
+ * Generally there are 2 types of context to save.
+ * 1. Interrupt registers to save
+ * 2. Task level registers to save
+ *
+ * This means we have the following 3 context items:
+ * 1. task level context stuff:: Context_Control
+ * 2. floating point task stuff:: Context_Control_fp
+ * 3. special interrupt level context :: Context_Control_interrupt
+ *
+ * On some processors, it is cost-effective to save only the callee
+ * preserved registers during a task context switch. This means
+ * that the ISR code needs to save those registers which do not
+ * persist across function calls. It is not mandatory to make this
+ * distinctions between the caller/callee saves registers for the
+ * purpose of minimizing context saved during task switch and on interrupts.
+ * If the cost of saving extra registers is minimal, simplicity is the
+ * choice. Save the same context on interrupt entry as for tasks in
+ * this case.
+ *
+ * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
+ * care should be used in designing the context area.
+ *
+ * On some CPUs with hardware floating point support, the Context_Control_fp
+ * structure will not be used or it simply consist of an array of a
+ * fixed number of bytes. This is done when the floating point context
+ * is dumped by a "FP save context" type instruction and the format
+ * is not really defined by the CPU. In this case, there is no need
+ * to figure out the exact format -- only the size. Of course, although
+ * this is enough information for RTEMS, it is probably not enough for
+ * a debugger such as gdb. But that is another problem.
+ */
+
+#ifndef ASM
+typedef struct {
+ uint32_t gpr1; /* Stack pointer for all */
+ uint32_t gpr2; /* Reserved SVR4, section ptr EABI + */
+ uint32_t gpr13; /* Section ptr SVR4/EABI */
+ uint32_t gpr14; /* Non volatile for all */
+ uint32_t gpr15; /* Non volatile for all */
+ uint32_t gpr16; /* Non volatile for all */
+ uint32_t gpr17; /* Non volatile for all */
+ uint32_t gpr18; /* Non volatile for all */
+ uint32_t gpr19; /* Non volatile for all */
+ uint32_t gpr20; /* Non volatile for all */
+ uint32_t gpr21; /* Non volatile for all */
+ uint32_t gpr22; /* Non volatile for all */
+ uint32_t gpr23; /* Non volatile for all */
+ uint32_t gpr24; /* Non volatile for all */
+ uint32_t gpr25; /* Non volatile for all */
+ uint32_t gpr26; /* Non volatile for all */
+ uint32_t gpr27; /* Non volatile for all */
+ uint32_t gpr28; /* Non volatile for all */
+ uint32_t gpr29; /* Non volatile for all */
+ uint32_t gpr30; /* Non volatile for all */
+ uint32_t gpr31; /* Non volatile for all */
+ uint32_t cr; /* PART of the CR is non volatile for all */
+ uint32_t pc; /* Program counter/Link register */
+ uint32_t msr; /* Initial interrupt level */
+} Context_Control;
+
+typedef struct {
+ /* The ABIs (PowerOpen/SVR4/EABI) only require saving f14-f31 over
+ * procedure calls. However, this would mean that the interrupt
+ * frame had to hold f0-f13, and the fpscr. And as the majority
+ * of tasks will not have an FP context, we will save the whole
+ * context here.
+ */
+#if (PPC_HAS_DOUBLE == 1)
+ double f[32];
+ double fpscr;
+#else
+ float f[32];
+ float fpscr;
+#endif
+} Context_Control_fp;
+#endif /* ASM */
+
+#ifndef ASM
+typedef struct CPU_Interrupt_frame {
+ uint32_t stacklink; /* Ensure this is a real frame (also reg1 save) */
+ uint32_t calleeLr; /* link register used by callees: SVR4/EABI */
+
+ /* This is what is left out of the primary contexts */
+ uint32_t gpr0;
+ uint32_t gpr2; /* play safe */
+ uint32_t gpr3;
+ uint32_t gpr4;
+ uint32_t gpr5;
+ uint32_t gpr6;
+ uint32_t gpr7;
+ uint32_t gpr8;
+ uint32_t gpr9;
+ uint32_t gpr10;
+ uint32_t gpr11;
+ uint32_t gpr12;
+ uint32_t gpr13; /* Play safe */
+ uint32_t gpr28; /* For internal use by the IRQ handler */
+ uint32_t gpr29; /* For internal use by the IRQ handler */
+ uint32_t gpr30; /* For internal use by the IRQ handler */
+ uint32_t gpr31; /* For internal use by the IRQ handler */
+ uint32_t cr; /* Bits of this are volatile, so no-one may save */
+ uint32_t ctr;
+ uint32_t xer;
+ uint32_t lr;
+ uint32_t pc;
+ uint32_t msr;
+ uint32_t pad[3];
+} CPU_Interrupt_frame;
+#endif /* ASM */
+
+#ifdef _OLD_EXCEPTIONS
+#include <rtems/old-exceptions/cpu.h>
+#else
+#include <rtems/new-exceptions/cpu.h>
+#endif
+
+/*
+ * Should be large enough to run all RTEMS tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ */
+
+#define CPU_STACK_MINIMUM_SIZE (1024*8)
+
+/*
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ */
+
+#define CPU_ALIGNMENT (PPC_ALIGNMENT)
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
+ * then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_HEAP_ALIGNMENT (PPC_ALIGNMENT)
+
+/*
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
+ * enough for the partition, then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_PARTITION_ALIGNMENT (PPC_ALIGNMENT)
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * stack. This alignment requirement may be stricter than that for the
+ * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
+ * is strict enough for the stack, then this should be set to 0.
+ *
+ * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
+ */
+
+#define CPU_STACK_ALIGNMENT (PPC_STACK_ALIGNMENT)
+
+#ifndef ASM
+/* The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * This version will work on any processor, but if there is a better
+ * way for your CPU PLEASE use it. The most common way to do this is to:
+ *
+ * swap least significant two bytes with 16-bit rotate
+ * swap upper and lower 16-bits
+ * swap most significant two bytes with 16-bit rotate
+ *
+ * Some CPUs have special instructions which swap a 32-bit quantity in
+ * a single instruction (e.g. i486). It is probably best to avoid
+ * an "endian swapping control bit" in the CPU. One good reason is
+ * that interrupts would probably have to be disabled to ensure that
+ * an interrupt does not try to access the same "chunk" with the wrong
+ * endian. Another good reason is that on some CPUs, the endian bit
+ * endianness for ALL fetches -- both code and data -- so the code
+ * will be fetched incorrectly.
+ */
+
+static inline uint32_t CPU_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t swapped;
+
+ asm volatile("rlwimi %0,%1,8,24,31;"
+ "rlwimi %0,%1,24,16,23;"
+ "rlwimi %0,%1,8,8,15;"
+ "rlwimi %0,%1,24,0,7;" :
+ "=&r" ((swapped)) : "r" ((value)));
+
+ return( swapped );
+}
+
+#define CPU_swap_u16( value ) \
+ (((value&0xff) << 8) | ((value >> 8)&0xff))
+
+#endif /* ASM */
+
+#ifndef ASM
+/*
+ * Macros to access PowerPC specific additions to the CPU Table
+ */
+
+#define rtems_cpu_configuration_get_clicks_per_usec() \
+ (_CPU_Table.clicks_per_usec)
+
+#define rtems_cpu_configuration_get_exceptions_in_ram() \
+ (_CPU_Table.exceptions_in_RAM)
+
+#if (defined(ppc403) || defined(ppc405) \
+ || defined(mpc860) || defined(mpc821) || defined(mpc8260))
+
+#define rtems_cpu_configuration_get_serial_per_sec() \
+ (_CPU_Table.serial_per_sec)
+
+#define rtems_cpu_configuration_get_serial_external_clock() \
+ (_CPU_Table.serial_external_clock)
+
+#define rtems_cpu_configuration_get_serial_xon_xoff() \
+ (_CPU_Table.serial_xon_xoff)
+
+#define rtems_cpu_configuration_get_serial_cts_rts() \
+ (_CPU_Table.serial_cts_rts)
+
+#define rtems_cpu_configuration_get_serial_rate() \
+ (_CPU_Table.serial_rate)
+
+#define rtems_cpu_configuration_get_timer_average_overhead() \
+ (_CPU_Table.timer_average_overhead)
+
+#define rtems_cpu_configuration_get_timer_least_valid() \
+ (_CPU_Table.timer_least_valid)
+
+#define rtems_cpu_configuration_get_timer_internal_clock() \
+ (_CPU_Table.timer_internal_clock)
+
+#endif
+
+#if (defined(mpc555) \
+ || defined(mpc860) || defined(mpc821) || defined(mpc8260))
+#define rtems_cpu_configuration_get_clock_speed() \
+ (_CPU_Table.clock_speed)
+#endif
+
+#endif /* ASM */
+
+#ifndef ASM
+/*
+ * Simple spin delay in microsecond units for device drivers.
+ * This is very dependent on the clock speed of the target.
+ */
+
+#define CPU_Get_timebase_low( _value ) \
+ asm volatile( "mftb %0" : "=r" (_value) )
+
+#define rtems_bsp_delay( _microseconds ) \
+ do { \
+ uint32_t start, ticks, now; \
+ CPU_Get_timebase_low( start ) ; \
+ ticks = (_microseconds) * rtems_cpu_configuration_get_clicks_per_usec(); \
+ do \
+ CPU_Get_timebase_low( now ) ; \
+ while (now - start < ticks); \
+ } while (0)
+
+#define rtems_bsp_delay_in_bus_cycles( _cycles ) \
+ do { \
+ uint32_t start, now; \
+ CPU_Get_timebase_low( start ); \
+ do \
+ CPU_Get_timebase_low( now ); \
+ while (now - start < (_cycles)); \
+ } while (0)
+
+#endif /* ASM */
+
+#ifndef ASM
+/*
+ * Routines to access the decrementer register
+ */
+
+#define PPC_Set_decrementer( _clicks ) \
+ do { \
+ asm volatile( "mtdec %0" : : "r" ((_clicks)) ); \
+ } while (0)
+
+#define PPC_Get_decrementer( _clicks ) \
+ asm volatile( "mfdec %0" : "=r" (_clicks) )
+
+#endif /* ASM */
+
+#ifndef ASM
+/*
+ * Routines to access the time base register
+ */
+
+static inline uint64_t PPC_Get_timebase_register( void )
+{
+ uint32_t tbr_low;
+ uint32_t tbr_high;
+ uint32_t tbr_high_old;
+ uint64_t tbr;
+
+ do {
+ asm volatile( "mftbu %0" : "=r" (tbr_high_old));
+ asm volatile( "mftb %0" : "=r" (tbr_low));
+ asm volatile( "mftbu %0" : "=r" (tbr_high));
+ } while ( tbr_high_old != tbr_high );
+
+ tbr = tbr_high;
+ tbr <<= 32;
+ tbr |= tbr_low;
+ return tbr;
+}
+
+static inline void PPC_Set_timebase_register (uint64_t tbr)
+{
+ uint32_t tbr_low;
+ uint32_t tbr_high;
+
+ tbr_low = (tbr & 0xffffffff) ;
+ tbr_high = (tbr >> 32) & 0xffffffff;
+ asm volatile( "mtspr 284, %0" : : "r" (tbr_low));
+ asm volatile( "mtspr 285, %0" : : "r" (tbr_high));
+
+}
+#endif /* ASM */
+
+#ifndef ASM
+/* Context handler macros */
+
+/*
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * This routine generally does not set any unnecessary register
+ * in the context. The state of the "general data" registers is
+ * undefined at task start time.
+ */
+
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ uint32_t *stack_base,
+ uint32_t size,
+ uint32_t new_level,
+ void *entry_point,
+ boolean is_fp
+);
+
+/*
+ * This routine is responsible for somehow restarting the currently
+ * executing task. If you are lucky, then all that is necessary
+ * is restoring the context. Otherwise, there will need to be
+ * a special assembly routine which does something special in this
+ * case. Context_Restore should work most of the time. It will
+ * not work if restarting self conflicts with the stack frame
+ * assumptions of restoring a context.
+ */
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+/*
+ * The purpose of this macro is to allow the initial pointer into
+ * a floating point context area (used to save the floating point
+ * context) to be at an arbitrary place in the floating point
+ * context area.
+ *
+ * This is necessary because some FP units are designed to have
+ * their context saved as a stack which grows into lower addresses.
+ * Other FP units can be saved by simply moving registers into offsets
+ * from the base of the context area. Finally some FP units provide
+ * a "dump context" instruction which could fill in from high to low
+ * or low to high based on the whim of the CPU designers.
+ */
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
+
+/*
+ * This routine initializes the FP context area passed to it to.
+ * There are a few standard ways in which to initialize the
+ * floating point context. The code included for this macro assumes
+ * that this is a CPU in which a "initial" FP context was saved into
+ * _CPU_Null_fp_context and it simply copies it to the destination
+ * context passed to it.
+ *
+ * Other models include (1) not doing anything, and (2) putting
+ * a "null FP status word" in the correct place in the FP context.
+ */
+
+#define _CPU_Context_Initialize_fp( _destination ) \
+ { \
+ ((Context_Control_fp *) *((void **) _destination))->fpscr = PPC_INIT_FPSCR; \
+ }
+
+/* end of Context handler macros */
+#endif /* ASM */
+
+#ifndef ASM
+/* Bitfield handler macros */
+
+/*
+ * This routine sets _output to the bit number of the first bit
+ * set in _value. _value is of CPU dependent type Priority_Bit_map_control.
+ * This type may be either 16 or 32 bits wide although only the 16
+ * least significant bits will be used.
+ *
+ * There are a number of variables in using a "find first bit" type
+ * instruction.
+ *
+ * (1) What happens when run on a value of zero?
+ * (2) Bits may be numbered from MSB to LSB or vice-versa.
+ * (3) The numbering may be zero or one based.
+ * (4) The "find first bit" instruction may search from MSB or LSB.
+ *
+ * RTEMS guarantees that (1) will never happen so it is not a concern.
+ * (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
+ * _CPU_Priority_Bits_index(). These three form a set of routines
+ * which must logically operate together. Bits in the _value are
+ * set and cleared based on masks built by _CPU_Priority_mask().
+ * The basic major and minor values calculated by _Priority_Major()
+ * and _Priority_Minor() are "massaged" by _CPU_Priority_Bits_index()
+ * to properly range between the values returned by the "find first bit"
+ * instruction. This makes it possible for _Priority_Get_highest() to
+ * calculate the major and directly index into the minor table.
+ * This mapping is necessary to ensure that 0 (a high priority major/minor)
+ * is the first bit found.
+ *
+ * This entire "find first bit" and mapping process depends heavily
+ * on the manner in which a priority is broken into a major and minor
+ * components with the major being the 4 MSB of a priority and minor
+ * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
+ * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next
+ * to the lowest priority.
+ *
+ * If your CPU does not have a "find first bit" instruction, then
+ * there are ways to make do without it. Here are a handful of ways
+ * to implement this in software:
+ *
+ * - a series of 16 bit test instructions
+ * - a "binary search using if's"
+ * - _number = 0
+ * if _value > 0x00ff
+ * _value >>=8
+ * _number = 8;
+ *
+ * if _value > 0x0000f
+ * _value >=8
+ * _number += 4
+ *
+ * _number += bit_set_table[ _value ]
+ *
+ * where bit_set_table[ 16 ] has values which indicate the first
+ * bit set
+ */
+
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ asm volatile ("cntlzw %0, %1" : "=r" ((_output)), "=r" ((_value)) : \
+ "1" ((_value))); \
+ }
+
+/* end of Bitfield handler macros */
+
+/*
+ * This routine builds the mask which corresponds to the bit fields
+ * as searched by _CPU_Bitfield_Find_first_bit(). See the discussion
+ * for that routine.
+ */
+
+#define _CPU_Priority_Mask( _bit_number ) \
+ ( 0x80000000 >> (_bit_number) )
+
+/*
+ * This routine translates the bit numbers returned by
+ * _CPU_Bitfield_Find_first_bit() into something suitable for use as
+ * a major or minor component of a priority. See the discussion
+ * for that routine.
+ */
+
+#define _CPU_Priority_bits_index( _priority ) \
+ (_priority)
+
+/* end of Priority handler macros */
+#endif /* ASM */
+
+/* functions */
+
+#ifndef ASM
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_Install_interrupt_stack
+ *
+ * This routine installs the hardware interrupt stack pointer.
+ *
+ * NOTE: It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK
+ * is TRUE.
+ */
+
+void _CPU_Install_interrupt_stack( void );
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _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.
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+void _CPU_Fatal_error(
+ uint32_t _error
+);
+
+#endif /* ASM */
+
+#endif /* _RTEMS_SCORE_CPU_H */
diff --git a/cpukit/score/cpu/powerpc/rtems/score/powerpc.h b/cpukit/score/cpu/powerpc/rtems/score/powerpc.h
new file mode 100644
index 0000000000..0142e6fe6c
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/rtems/score/powerpc.h
@@ -0,0 +1,560 @@
+/**
+ * @file rtems/score/powerpc.h
+ */
+
+/*
+ * This file contains definitions for the IBM/Motorola PowerPC
+ * family members.
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * MPC860 support code was added by Jay Monkman <jmonkman@frasca.com>
+ * MPC8260 support added by Andy Dachs <a.dachs@sstl.co.uk>
+ * Surrey Satellite Technology Limited
+ *
+ * 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/no_cpu.h:
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ *
+ * Note:
+ * This file is included by both C and assembler code ( -DASM )
+ *
+ * $Id$
+ */
+
+
+#ifndef _RTEMS_SCORE_POWERPC_H
+#define _RTEMS_SCORE_POWERPC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/types.h>
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "PowerPC"
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the PowerPC family. It does
+ * this by setting variables to indicate which implementation
+ * dependent features are present in a particular member
+ * of the family.
+ *
+ * The following architectural feature definitions are defaulted
+ * unless specifically set by the model definition:
+ *
+ * + PPC_INTERRUPT_MAX - 16
+ * + PPC_CACHE_ALIGNMENT - 32
+ * + PPC_HAS_FPU - 1
+ * + PPC_HAS_DOUBLE - 1 if PPC_HAS_FPU,
+ * - 0 otherwise
+ */
+
+/*
+ * Figure out all CPU Model Feature Flags based upon compiler
+ * predefines.
+ */
+
+#if defined(ppc403) || defined(ppc405)
+/*
+ * IBM 403
+ *
+ * Developed for 403GA. Book checked for 403GB.
+ *
+ * Does not have user mode.
+ */
+
+#if defined(ppc403)
+#define CPU_MODEL_NAME "PowerPC 403"
+#elif defined (ppc405)
+#define CPU_MODEL_NAME "PowerPC 405"
+#endif
+#define PPC_ALIGNMENT 4
+#define PPC_CACHE_ALIGNMENT 16
+
+#elif defined(mpc555)
+
+#define CPU_MODEL_NAME "PowerPC 555"
+
+/* Copied from mpc505 */
+#define PPC_ALIGNMENT 4
+#define PPC_CACHE_ALIGNMENT 16
+
+#elif defined(mpc505) || defined(mpc509)
+/*
+ * Submitted by Sergei Organov <osv@Javad.RU> as a patch against
+ * 3.6.0 long after 4.0 was released. This is just an attempt
+ * to get the setting correct.
+ */
+
+#define CPU_MODEL_NAME "PowerPC 505/509"
+
+#define PPC_ALIGNMENT 4
+#define PPC_CACHE_ALIGNMENT 16
+
+#elif defined(ppc601)
+
+/*
+ * Submitted with original port -- book checked only.
+ */
+
+#define CPU_MODEL_NAME "PowerPC 601"
+
+#define PPC_ALIGNMENT 8
+
+#elif defined(ppc602)
+/*
+ * Submitted with original port -- book checked only.
+ */
+
+#define CPU_MODEL_NAME "PowerPC 602"
+
+#define PPC_ALIGNMENT 4
+#define PPC_HAS_DOUBLE 0
+
+#elif defined(ppc603)
+/*
+ * Submitted with original port -- book checked only.
+ */
+
+#define CPU_MODEL_NAME "PowerPC 603"
+
+#define PPC_ALIGNMENT 8
+
+#elif defined(ppc603e)
+
+#define CPU_MODEL_NAME "PowerPC 603e"
+/*
+ * Submitted with original port.
+ *
+ * Known to work on real hardware.
+ */
+
+#define PPC_ALIGNMENT 8
+
+#elif defined(mpc604)
+/*
+ * Submitted with original port -- book checked only.
+ */
+
+#define CPU_MODEL_NAME "PowerPC 604"
+
+#define PPC_ALIGNMENT 8
+
+#elif defined(mpc860)
+/*
+ * Added by Jay Monkman (jmonkman@frasca.com) 6/28/98
+ * with some changes by Darlene Stewart (Darlene.Stewart@iit.nrc.ca)
+ */
+#define CPU_MODEL_NAME "PowerPC MPC860"
+
+#define PPC_ALIGNMENT 4
+#define PPC_CACHE_ALIGNMENT 16
+#define PPC_INTERRUPT_MAX 71
+
+#elif defined(mpc821)
+/*
+ * Added by Andrew Bray <andy@chaos.org.uk> 6/April/1999
+ */
+#define CPU_MODEL_NAME "PowerPC MPC821"
+
+#define PPC_ALIGNMENT 4
+#define PPC_CACHE_ALIGNMENT 16
+#define PPC_INTERRUPT_MAX 71
+
+#elif defined(mpc750)
+#define CPU_MODEL_NAME "PowerPC 750"
+#define PPC_ALIGNMENT 8
+
+#elif defined(__ALTIVEC__) \
+ || defined(mpc7400) || defined(mpc7450) || defined(mpc7455)
+
+/* ppc altivec family */
+#if defined(mpc7400)
+#define CPU_MODEL_NAME "PowerPC 7400"
+#elif defined(mpc7450)
+#define CPU_MODEL_NAME "PowerPC 7400"
+#elif defined(mpc7455)
+#define CPU_MODEL_NAME "PowerPC 7455"
+#else
+#define CPU_MODEL_NAME "PowerPC Altivec"
+#endif
+
+#define PPC_ALIGNMENT 8
+#define PPC_CACHE_ALIGNMENT 32
+
+#elif defined(mpc8260)
+/*
+ * Added by Andy Dachs <a.dachs@sstl.co.uk> 23/11/2000
+ */
+#define CPU_MODEL_NAME "PowerPC MPC8260"
+
+#define PPC_ALIGNMENT 8
+#define PPC_CACHE_ALIGNMENT 32
+#define PPC_INTERRUPT_MAX 125
+#else
+
+#error "Unsupported CPU Model"
+
+#endif
+
+/*
+ * Application binary interfaces.
+ *
+ * PPC_ABI MUST be defined as one of these.
+ * Only big endian is currently supported.
+ */
+/*
+ * SVR4 ABI
+ */
+#define PPC_ABI_SVR4 2
+/*
+ * Embedded ABI
+ */
+#define PPC_ABI_EABI 3
+
+/*
+ * Default to the EABI used by current GNU tools
+ */
+
+#ifndef PPC_ABI
+#define PPC_ABI PPC_ABI_EABI
+#endif
+
+#if (PPC_ABI == PPC_ABI_SVR4)
+#define PPC_STACK_ALIGNMENT 16
+#elif (PPC_ABI == PPC_ABI_EABI)
+#define PPC_STACK_ALIGNMENT 8
+#else
+#error "PPC_ABI is not properly defined"
+#endif
+
+/*
+ * Assemblers.
+ * PPC_ASM MUST be defined as one of these.
+ *
+ * PPC_ASM_ELF: ELF assembler. Currently used for all ABIs.
+ *
+ * NOTE: Only PPC_ABI_ELF is currently fully supported.
+ */
+
+#define PPC_ASM_ELF 0
+
+/*
+ * Default to the assembler format used by the current GNU tools.
+ */
+
+#ifndef PPC_ASM
+#define PPC_ASM PPC_ASM_ELF
+#endif
+
+/*
+ * If the maximum number of exception sources has not been defined,
+ * then default it to 16.
+ */
+
+#ifndef PPC_INTERRUPT_MAX
+#define PPC_INTERRUPT_MAX 16
+#endif
+
+/*
+ * Unless specified otherwise, the cache line size is defaulted to 32.
+ *
+ * The derive the power of 2 the cache line is.
+ */
+
+#ifndef PPC_CACHE_ALIGNMENT
+#define PPC_CACHE_ALIGNMENT 32
+#endif
+
+/*
+ * Unless specified above, assume PPC_HAS_FPU to be a synonym for _SOFT_FLOAT.
+ * FIXME: Should we tie PPC_HAS_FPU to _SOFT_FLOAT, directly
+ * and disallow explicitly setting PPC_HAS_FPU?
+ */
+
+#ifndef PPC_HAS_FPU
+#ifdef _SOFT_FLOAT
+#define PPC_HAS_FPU 0
+#else
+#define PPC_HAS_FPU 1
+#endif
+#endif
+
+/*
+ * Unless specified above, If the model has FP support, it is assumed to
+ * support doubles (8-byte floating point numbers).
+ *
+ * If the model does NOT have FP support, then the model does
+ * NOT have double length FP registers.
+ */
+
+#ifndef PPC_HAS_DOUBLE
+#if (PPC_HAS_FPU)
+#define PPC_HAS_DOUBLE 1
+#else
+#define PPC_HAS_DOUBLE 0
+#endif
+#endif
+
+/*
+ * The following exceptions are not maskable, and are not
+ * necessarily predictable, so cannot be offered to RTEMS:
+ * Alignment exception - handled by the CPU module
+ * Data exceptions.
+ * Instruction exceptions.
+ */
+
+/*
+ * Base Interrupt vectors supported on all models.
+ */
+#define PPC_IRQ_SYSTEM_RESET 0 /* 0x00100 - System reset. */
+#define PPC_IRQ_MCHECK 1 /* 0x00200 - Machine check */
+#define PPC_IRQ_PROTECT 2 /* 0x00300 - Protection violation */
+#define PPC_IRQ_ISI 3 /* 0x00400 - Instruction Fetch error */
+#define PPC_IRQ_EXTERNAL 4 /* 0x00500 - External interrupt */
+#define PPC_IRQ_ALIGNMENT 5 /* 0X00600 - Alignment exception */
+#define PPC_IRQ_PROGRAM 6 /* 0x00700 - Program exception */
+#define PPC_IRQ_NOFP 7 /* 0x00800 - Floating point unavailable */
+#define PPC_IRQ_DECREMENTER 8 /* 0x00900 - Decrementer interrupt */
+#define PPC_IRQ_RESERVED_A 9 /* 0x00a00 - Implementation Reserved */
+#define PPC_IRQ_RESERVED_B 10 /* 0x00b00 - Implementation Reserved */
+#define PPC_IRQ_SCALL 11 /* 0x00c00 - System call */
+#define PPC_IRQ_TRACE 12 /* 0x00d00 - Trace Exception */
+#define PPC_IRQ_FP_ASST 13 /* ox00e00 - Floating point assist */
+#define PPC_STD_IRQ_LAST PPC_IRQ_FP_ASST
+
+#define PPC_IRQ_FIRST PPC_IRQ_SYSTEM_RESET
+
+#if defined(ppc403) || defined(ppc405)
+
+#define PPC_IRQ_CRIT PPC_IRQ_SYSTEM_RESET /*0x00100- Critical int. pin */
+#define PPC_IRQ_PIT (PPC_STD_IRQ_LAST+1) /*0x01000- Pgm interval timer*/
+#define PPC_IRQ_FIT (PPC_STD_IRQ_LAST+2) /*0x01010- Fixed int. timer */
+#define PPC_IRQ_WATCHDOG (PPC_STD_IRQ_LAST+3) /*0x01020- Watchdog timer */
+#define PPC_IRQ_DEBUG (PPC_STD_IRQ_LAST+4) /*0x02000- Debug exceptions */
+#define PPC_IRQ_LAST PPC_IRQ_DEBUG
+
+#elif defined(mpc505) || defined(mpc509)
+#define PPC_IRQ_SOFTEMU (PPC_STD_IRQ_LAST+1) /* Software emulation. */
+#define PPC_IRQ_DATA_BP (PPC_STD_IRQ_LAST+ 2)
+#define PPC_IRQ_INST_BP (PPC_STD_IRQ_LAST+ 3)
+#define PPC_IRQ_MEXT_BP (PPC_STD_IRQ_LAST+ 4)
+#define PPC_IRQ_NMEXT_BP (PPC_STD_IRQ_LAST+ 5)
+
+#elif defined(mpc555)
+#define PPC_IRQ_SOFTEMU (PPC_STD_IRQ_LAST+1) /* Software emulation. */
+#define PPC_IRQ_INST_PE (PPC_STD_IRQ_LAST+2) /* Insn protection error */
+#define PPC_IRQ_DATA_PE (PPC_STD_IRQ_LAST+3) /* Data protection error */
+#define PPC_IRQ_DATA_BP (PPC_STD_IRQ_LAST+4) /* Data breakpoint */
+#define PPC_IRQ_INST_BP (PPC_STD_IRQ_LAST+5) /* Insn breakpoint */
+#define PPC_IRQ_MEXT_BP (PPC_STD_IRQ_LAST+6) /* Maskable ext bkpt */
+#define PPC_IRQ_NMEXT_BP (PPC_STD_IRQ_LAST+7) /* Non-maskable ext bkpt */
+#define PPC_IRQ_LAST PPC_IRQ_NMEXT_BP
+
+#elif defined(ppc601)
+#undef PPC_IRQ_TRACE
+#define PPC_IRQ_TRACE (PPC_STD_IRQ_LAST+1) /*0x02000-Run/Trace Exception*/
+#define PPC_IRQ_LAST PPC_IRQ_TRACE
+
+#elif defined(ppc602)
+#define PPC_IRQ_LAST (PPC_STD_IRQ_LAST)
+
+#elif defined(ppc603) || defined(ppc603e)
+#define PPC_IRQ_TRANS_MISS (PPC_STD_IRQ_LAST+1) /*0x1000-Ins Translation Miss*/
+#define PPC_IRQ_DATA_LOAD (PPC_STD_IRQ_LAST+2) /*0x1100-Data Load Trans Miss*/
+#define PPC_IRQ_DATA_STORE (PPC_STD_IRQ_LAST+3) /*0x1200-Data Store Miss */
+#define PPC_IRQ_ADDR_BRK (PPC_STD_IRQ_LAST+4) /*0x1300-Instruction Bkpoint */
+#define PPC_IRQ_SYS_MGT (PPC_STD_IRQ_LAST+5) /*0x1400-System Management */
+#define PPC_IRQ_LAST PPC_IRQ_SYS_MGT
+
+#elif defined(mpc604)
+#define PPC_IRQ_ADDR_BRK (PPC_STD_IRQ_LAST+1) /*0x1300- Inst. addr break */
+#define PPC_IRQ_SYS_MGT (PPC_STD_IRQ_LAST+2) /*0x1400- System Management */
+#define PPC_IRQ_LAST PPC_IRQ_SYS_MGT
+
+#elif defined(mpc860) || defined(mpc821)
+#define PPC_IRQ_EMULATE (PPC_STD_IRQ_LAST+1) /*0x1000-Software emulation */
+#define PPC_IRQ_INST_MISS (PPC_STD_IRQ_LAST+2) /*0x1100-Instruction TLB miss*/
+#define PPC_IRQ_DATA_MISS (PPC_STD_IRQ_LAST+3) /*0x1200-Data TLB miss */
+#define PPC_IRQ_INST_ERR (PPC_STD_IRQ_LAST+4) /*0x1300-Instruction TLB err */
+#define PPC_IRQ_DATA_ERR (PPC_STD_IRQ_LAST+5) /*0x1400-Data TLB error */
+#define PPC_IRQ_DATA_BPNT (PPC_STD_IRQ_LAST+6) /*0x1C00-Data breakpoint */
+#define PPC_IRQ_INST_BPNT (PPC_STD_IRQ_LAST+7) /*0x1D00-Inst breakpoint */
+#define PPC_IRQ_IO_BPNT (PPC_STD_IRQ_LAST+8) /*0x1E00-Peripheral breakpnt */
+#define PPC_IRQ_DEV_PORT (PPC_STD_IRQ_LAST+9) /*0x1F00-Development port */
+#define PPC_IRQ_IRQ0 (PPC_STD_IRQ_LAST + 10)
+#define PPC_IRQ_LVL0 (PPC_STD_IRQ_LAST + 11)
+#define PPC_IRQ_IRQ1 (PPC_STD_IRQ_LAST + 12)
+#define PPC_IRQ_LVL1 (PPC_STD_IRQ_LAST + 13)
+#define PPC_IRQ_IRQ2 (PPC_STD_IRQ_LAST + 14)
+#define PPC_IRQ_LVL2 (PPC_STD_IRQ_LAST + 15)
+#define PPC_IRQ_IRQ3 (PPC_STD_IRQ_LAST + 16)
+#define PPC_IRQ_LVL3 (PPC_STD_IRQ_LAST + 17)
+#define PPC_IRQ_IRQ4 (PPC_STD_IRQ_LAST + 18)
+#define PPC_IRQ_LVL4 (PPC_STD_IRQ_LAST + 19)
+#define PPC_IRQ_IRQ5 (PPC_STD_IRQ_LAST + 20)
+#define PPC_IRQ_LVL5 (PPC_STD_IRQ_LAST + 21)
+#define PPC_IRQ_IRQ6 (PPC_STD_IRQ_LAST + 22)
+#define PPC_IRQ_LVL6 (PPC_STD_IRQ_LAST + 23)
+#define PPC_IRQ_IRQ7 (PPC_STD_IRQ_LAST + 24)
+#define PPC_IRQ_LVL7 (PPC_STD_IRQ_LAST + 25)
+#define PPC_IRQ_CPM_ERROR (PPC_STD_IRQ_LAST + 26)
+#define PPC_IRQ_CPM_PC4 (PPC_STD_IRQ_LAST + 27)
+#define PPC_IRQ_CPM_PC5 (PPC_STD_IRQ_LAST + 28)
+#define PPC_IRQ_CPM_SMC2 (PPC_STD_IRQ_LAST + 29)
+#define PPC_IRQ_CPM_SMC1 (PPC_STD_IRQ_LAST + 30)
+#define PPC_IRQ_CPM_SPI (PPC_STD_IRQ_LAST + 31)
+#define PPC_IRQ_CPM_PC6 (PPC_STD_IRQ_LAST + 32)
+#define PPC_IRQ_CPM_TIMER4 (PPC_STD_IRQ_LAST + 33)
+#define PPC_IRQ_CPM_RESERVED_8 (PPC_STD_IRQ_LAST + 34)
+#define PPC_IRQ_CPM_PC7 (PPC_STD_IRQ_LAST + 35)
+#define PPC_IRQ_CPM_PC8 (PPC_STD_IRQ_LAST + 36)
+#define PPC_IRQ_CPM_PC9 (PPC_STD_IRQ_LAST + 37)
+#define PPC_IRQ_CPM_TIMER3 (PPC_STD_IRQ_LAST + 38)
+#define PPC_IRQ_CPM_RESERVED_D (PPC_STD_IRQ_LAST + 39)
+#define PPC_IRQ_CPM_PC10 (PPC_STD_IRQ_LAST + 40)
+#define PPC_IRQ_CPM_PC11 (PPC_STD_IRQ_LAST + 41)
+#define PPC_IRQ_CPM_I2C (PPC_STD_IRQ_LAST + 42)
+#define PPC_IRQ_CPM_RISC_TIMER (PPC_STD_IRQ_LAST + 43)
+#define PPC_IRQ_CPM_TIMER2 (PPC_STD_IRQ_LAST + 44)
+#define PPC_IRQ_CPM_RESERVED_13 (PPC_STD_IRQ_LAST + 45)
+#define PPC_IRQ_CPM_IDMA2 (PPC_STD_IRQ_LAST + 46)
+#define PPC_IRQ_CPM_IDMA1 (PPC_STD_IRQ_LAST + 47)
+#define PPC_IRQ_CPM_SDMA_ERROR (PPC_STD_IRQ_LAST + 48)
+#define PPC_IRQ_CPM_PC12 (PPC_STD_IRQ_LAST + 49)
+#define PPC_IRQ_CPM_PC13 (PPC_STD_IRQ_LAST + 50)
+#define PPC_IRQ_CPM_TIMER1 (PPC_STD_IRQ_LAST + 51)
+#define PPC_IRQ_CPM_PC14 (PPC_STD_IRQ_LAST + 52)
+#define PPC_IRQ_CPM_SCC4 (PPC_STD_IRQ_LAST + 53)
+#define PPC_IRQ_CPM_SCC3 (PPC_STD_IRQ_LAST + 54)
+#define PPC_IRQ_CPM_SCC2 (PPC_STD_IRQ_LAST + 55)
+#define PPC_IRQ_CPM_SCC1 (PPC_STD_IRQ_LAST + 56)
+#define PPC_IRQ_CPM_PC15 (PPC_STD_IRQ_LAST + 57)
+
+#define PPC_IRQ_LAST PPC_IRQ_CPM_PC15
+
+#elif defined(mpc8260)
+
+#define PPC_IRQ_INST_MISS (PPC_STD_IRQ_LAST+1) /*0x1000-Instruction TLB miss*/
+#define PPC_IRQ_DATA_MISS (PPC_STD_IRQ_LAST+2) /*0x1100-Data TLB miss */
+#define PPC_IRQ_DATA_L_MISS (PPC_STD_IRQ_LAST+3) /*0x1200-Data TLB load miss */
+#define PPC_IRQ_DATA_S_MISS (PPC_STD_IRQ_LAST+4) /*0x1300-Data TLB store miss */
+#define PPC_IRQ_INST_BPNT (PPC_STD_IRQ_LAST+5) /*0x1400-Inst address breakpoint */
+#define PPC_IRQ_SYS_MGT (PPC_STD_IRQ_LAST+6) /*0x1500-System Management */
+/* 0x1600 - 0x2F00 reserved */
+#define PPC_IRQ_CPM_NONE (PPC_STD_IRQ_LAST + 50)
+#define PPC_IRQ_CPM_I2C (PPC_STD_IRQ_LAST + 51)
+#define PPC_IRQ_CPM_SPI (PPC_STD_IRQ_LAST + 52)
+#define PPC_IRQ_CPM_RISC_TIMER (PPC_STD_IRQ_LAST + 53)
+#define PPC_IRQ_CPM_SMC1 (PPC_STD_IRQ_LAST + 54)
+#define PPC_IRQ_CPM_SMC2 (PPC_STD_IRQ_LAST + 55)
+#define PPC_IRQ_CPM_IDMA1 (PPC_STD_IRQ_LAST + 56)
+#define PPC_IRQ_CPM_IDMA2 (PPC_STD_IRQ_LAST + 57)
+#define PPC_IRQ_CPM_IDMA3 (PPC_STD_IRQ_LAST + 58)
+#define PPC_IRQ_CPM_IDMA4 (PPC_STD_IRQ_LAST + 59)
+#define PPC_IRQ_CPM_SDMA (PPC_STD_IRQ_LAST + 60)
+#define PPC_IRQ_CPM_RES_A (PPC_STD_IRQ_LAST + 61)
+#define PPC_IRQ_CPM_TIMER1 (PPC_STD_IRQ_LAST + 62)
+#define PPC_IRQ_CPM_TIMER2 (PPC_STD_IRQ_LAST + 63)
+#define PPC_IRQ_CPM_TIMER3 (PPC_STD_IRQ_LAST + 64)
+#define PPC_IRQ_CPM_TIMER4 (PPC_STD_IRQ_LAST + 65)
+#define PPC_IRQ_CPM_TMCNT (PPC_STD_IRQ_LAST + 66)
+#define PPC_IRQ_CPM_PIT (PPC_STD_IRQ_LAST + 67)
+#define PPC_IRQ_CPM_RES_B (PPC_STD_IRQ_LAST + 68)
+#define PPC_IRQ_CPM_IRQ1 (PPC_STD_IRQ_LAST + 69)
+#define PPC_IRQ_CPM_IRQ2 (PPC_STD_IRQ_LAST + 70)
+#define PPC_IRQ_CPM_IRQ3 (PPC_STD_IRQ_LAST + 71)
+#define PPC_IRQ_CPM_IRQ4 (PPC_STD_IRQ_LAST + 72)
+#define PPC_IRQ_CPM_IRQ5 (PPC_STD_IRQ_LAST + 73)
+#define PPC_IRQ_CPM_IRQ6 (PPC_STD_IRQ_LAST + 74)
+#define PPC_IRQ_CPM_IRQ7 (PPC_STD_IRQ_LAST + 75)
+#define PPC_IRQ_CPM_RES_C (PPC_STD_IRQ_LAST + 76)
+#define PPC_IRQ_CPM_RES_D (PPC_STD_IRQ_LAST + 77)
+#define PPC_IRQ_CPM_RES_E (PPC_STD_IRQ_LAST + 78)
+#define PPC_IRQ_CPM_RES_F (PPC_STD_IRQ_LAST + 79)
+#define PPC_IRQ_CPM_RES_G (PPC_STD_IRQ_LAST + 80)
+#define PPC_IRQ_CPM_RES_H (PPC_STD_IRQ_LAST + 81)
+#define PPC_IRQ_CPM_FCC1 (PPC_STD_IRQ_LAST + 82)
+#define PPC_IRQ_CPM_FCC2 (PPC_STD_IRQ_LAST + 83)
+#define PPC_IRQ_CPM_FCC3 (PPC_STD_IRQ_LAST + 84)
+#define PPC_IRQ_CPM_RES_I (PPC_STD_IRQ_LAST + 85)
+#define PPC_IRQ_CPM_MCC1 (PPC_STD_IRQ_LAST + 86)
+#define PPC_IRQ_CPM_MCC2 (PPC_STD_IRQ_LAST + 87)
+#define PPC_IRQ_CPM_RES_J (PPC_STD_IRQ_LAST + 88)
+#define PPC_IRQ_CPM_RES_K (PPC_STD_IRQ_LAST + 89)
+#define PPC_IRQ_CPM_SCC1 (PPC_STD_IRQ_LAST + 90)
+#define PPC_IRQ_CPM_SCC2 (PPC_STD_IRQ_LAST + 91)
+#define PPC_IRQ_CPM_SCC3 (PPC_STD_IRQ_LAST + 92)
+#define PPC_IRQ_CPM_SCC4 (PPC_STD_IRQ_LAST + 93)
+#define PPC_IRQ_CPM_RES_L (PPC_STD_IRQ_LAST + 94)
+#define PPC_IRQ_CPM_RES_M (PPC_STD_IRQ_LAST + 95)
+#define PPC_IRQ_CPM_RES_N (PPC_STD_IRQ_LAST + 96)
+#define PPC_IRQ_CPM_RES_O (PPC_STD_IRQ_LAST + 97)
+#define PPC_IRQ_CPM_PC15 (PPC_STD_IRQ_LAST + 98)
+#define PPC_IRQ_CPM_PC14 (PPC_STD_IRQ_LAST + 99)
+#define PPC_IRQ_CPM_PC13 (PPC_STD_IRQ_LAST + 100)
+#define PPC_IRQ_CPM_PC12 (PPC_STD_IRQ_LAST + 101)
+#define PPC_IRQ_CPM_PC11 (PPC_STD_IRQ_LAST + 102)
+#define PPC_IRQ_CPM_PC10 (PPC_STD_IRQ_LAST + 103)
+#define PPC_IRQ_CPM_PC9 (PPC_STD_IRQ_LAST + 104)
+#define PPC_IRQ_CPM_PC8 (PPC_STD_IRQ_LAST + 105)
+#define PPC_IRQ_CPM_PC7 (PPC_STD_IRQ_LAST + 106)
+#define PPC_IRQ_CPM_PC6 (PPC_STD_IRQ_LAST + 107)
+#define PPC_IRQ_CPM_PC5 (PPC_STD_IRQ_LAST + 108)
+#define PPC_IRQ_CPM_PC4 (PPC_STD_IRQ_LAST + 109)
+#define PPC_IRQ_CPM_PC3 (PPC_STD_IRQ_LAST + 110)
+#define PPC_IRQ_CPM_PC2 (PPC_STD_IRQ_LAST + 111)
+#define PPC_IRQ_CPM_PC1 (PPC_STD_IRQ_LAST + 112)
+#define PPC_IRQ_CPM_PC0 (PPC_STD_IRQ_LAST + 113)
+
+#define PPC_IRQ_LAST PPC_IRQ_CPM_PC0
+
+#endif
+
+
+/*
+ * If the maximum number of exception sources is too low,
+ * then fix it
+ */
+
+#if PPC_INTERRUPT_MAX <= PPC_IRQ_LAST
+#undef PPC_INTERRUPT_MAX
+#define PPC_INTERRUPT_MAX ((PPC_IRQ_LAST) + 1)
+#endif
+
+/*
+ * Initial value for the FPSCR register
+ */
+
+#define PPC_INIT_FPSCR 0x000000f8
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_POWERPC_H */
diff --git a/cpukit/score/cpu/powerpc/rtems/score/ppc.h b/cpukit/score/cpu/powerpc/rtems/score/ppc.h
new file mode 100644
index 0000000000..e5f09a7b35
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/rtems/score/ppc.h
@@ -0,0 +1,19 @@
+/**
+ * @file rtems/score/ppc.h
+ */
+
+/*
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_PPC_H
+#define _RTEMS_SCORE_PPC_H
+#ifndef RTEMS_NO_WARN_DEPRECATED
+#warning <rtems/score/ppc.h> is deprecated, use <rtems/score/powerpc.h> instead
+#endif
+#include <rtems/score/powerpc.h>
+#endif
diff --git a/cpukit/score/cpu/powerpc/rtems/score/types.h b/cpukit/score/cpu/powerpc/rtems/score/types.h
new file mode 100644
index 0000000000..15617d09ff
--- /dev/null
+++ b/cpukit/score/cpu/powerpc/rtems/score/types.h
@@ -0,0 +1,70 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains type definitions pertaining to the PowerPC
+ * processor family.
+ *
+ * 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/no_cputypes.h:
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+
+typedef uint32_t Priority_Bit_map_control;
+
+typedef signed long long signed64; /* 64 bit signed integer */
+
+typedef uint32_t boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void ppc_isr;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/sh/.cvsignore b/cpukit/score/cpu/sh/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/sh/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/sh/ChangeLog b/cpukit/score/cpu/sh/ChangeLog
new file mode 100644
index 0000000000..e5224b9ed8
--- /dev/null
+++ b/cpukit/score/cpu/sh/ChangeLog
@@ -0,0 +1,339 @@
+2006-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, rtems/score/sh.h: Recognize sh2e variant so multilibs will all
+ compile.
+
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Part of a large patch to improve Doxygen output.
+ As a side-effect, grammar and spelling errors were corrected, spacing
+ errors were address, and some variable names were improved.
+
+2006-01-11 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h: Remove private version of CONCAT macros.
+ Include <rtems/concat.h> instead.
+
+2005-02-19 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Remove traces from NO_CPU.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/cpu.h, rtems/score/sh.h, rtems/score/sh_io.h,
+ rtems/score/types.h: New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/sh.h: *_swap_u32( uint32_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/sh.h: *_swap_u16( uint16_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: #include <rtems/stdint.h>.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove build-variant support.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Use __rtems_score_types_h as preprocessor
+ guard.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * asm.h: Add doxygen preamble.
+
+2004-10-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Add doxygen preamble.
+ * rtems/score/sh.h: Add doxygen preamble.
+ * rtems/score/sh_io.h: Add doxygen preamble.
+ * rtems/score/types.h: Add doxygen preamble.
+
+2004-09-29 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: i960 obsoleted and all references removed.
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Remove (Merged into$(top_srcdir)/configure.ac).
+ * Makefile.am: Don't include multilib.am.
+ Reflect merging configure.ac into $(top_srcdir)/configure.ac.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Install asm.h to $(includedir)/rtems.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu.c, rtems/score/cpu.h, rtems/score/sh.h, rtems/score/sh_io.h:
+ Convert to using c99 fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: RTEMS_TOP([../../../..]).
+
+2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Move RTEMS_TOP one subdir down.
+
+2004-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add PREINSTALL_DIRS.
+
+2004-01-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Re-add dirstamps to PREINSTALL_FILES.
+ Add PREINSTALL_FILES to CLEANFILES.
+
+2004-01-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Requires automake >= 1.8.1.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, again.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Convert to using automake compilation rules.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use mkdir_p. Remove dirs from PREINSTALL_FILES.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require automake >= 1.8, autoconf >= 2.59.
+
+2003-12-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Remove TMPINSTALL_FILES.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Don't use gmake rules for preinstallation.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CANONICAL_HOST.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CPU.
+
+2003-09-26 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Obsoleting HP PA-RISC port and removing all
+ references.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * asm.h, cpu.c, rtems/score/cpu.h, rtems/score/sh.h,
+ rtems/score/sh_io.h, rtems/score/types.h: URL for license changed.
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require autoconf-2.57 + automake-1.7.2.
+ * Makefile.am: Eliminate C_O_FILES, S_O_FILES, libscorecpu_a_OBJECTS.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix package name.
+
+2002-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add nostdinc to AM_INIT_AUTOMAKE.
+
+2002-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/sh.h: Fix typo in comment (Starus->Status).
+
+2002-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Reformat.
+ Add autom4te*cache.
+ Remove autom4te.cache.
+
+2002-07-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use .$(OBJEXT) instead of .o.
+
+2002-07-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: RTEMS_TOP(../../../..).
+
+2002-07-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems.c: Remove.
+ * Makefile.am: Reflect changes above.
+
+2002-07-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_PROJECT_ROOT.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add RTEMS_PROG_CCAS
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AC_CONFIG_AUX_DIR(../../../..).
+ Add AC_PROG_RANLIB.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/../../../automake/*.am.
+ Use ../../../aclocal.
+
+2002-04-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems.c: Adaptation to gcc-3.0.x.
+
+2001-04-03 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
+ * rtems/score/shtypes.h: Removed.
+ * rtems/score/types.h: New file via CVS magic.
+ * Makefile.am, 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.
+
+2002-01-31 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Reflect 2002-01-23 changes.
+
+2002-01-31 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Reflect 2002-01-23 changes.
+
+2002-01-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/Makefile.am: Removed.
+ * rtems/score/Makefile.am: Removed.
+ * configure.ac: Reflect changes above.
+
+2001-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add multilib support.
+
+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.
+
+2001-10-15 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * cpu.c: Fix #ifdefs, add missing #endif.
+
+2001-10-12 Joel Sherrill <joel@OARcorp.com>
+
+ * asm.h, cpu.c, rtems.c, rtems/score/cpu.h, rtems/score/sh.h,
+ rtems/score/sh_io.h, rtems/score/shtypes.h: Consistency changes
+ and made sure there were no includes from the libcpu tree.
+
+2001-10-12 Alexandra Kossovsky <sasha@oktet.ru>
+
+ * cpu.c, rtems/score/cpu.h, rtems/score/sh.h: Modified to
+ support SH4. Reviewed by Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+ who did the original SH port.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/Makefile.am: Use 'PREINSTALL_FILES ='.
+ * Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-07-25 Radzislaw Galler <rgaller@et.put.poznan.pl>
+
+ * cpu.c (_CPU_ISR_install_vector): Corrected interrupt range
+ checking which was SH1 specific. It didn't work for SH2 (has more
+ interrupt sources).
+
+2001-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, rtems/score/Makefile.am:
+ Apply include_*HEADERS instead of H_FILES.
+
+2001-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Added _CPU_Initialize_vectors().
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
+ Switch to GNU canonicalization.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am.
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: New file.
diff --git a/cpukit/score/cpu/sh/Makefile.am b/cpukit/score/cpu/sh/Makefile.am
new file mode 100644
index 0000000000..8ce6a27ea3
--- /dev/null
+++ b/cpukit/score/cpu/sh/Makefile.am
@@ -0,0 +1,19 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/types.h \
+ rtems/score/sh.h rtems/score/sh_io.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/sh/cpu.c b/cpukit/score/cpu/sh/cpu.c
new file mode 100644
index 0000000000..3ed3131199
--- /dev/null
+++ b/cpukit/score/cpu/sh/cpu.c
@@ -0,0 +1,254 @@
+/*
+ * This file contains information pertaining to the Hitachi SH
+ * processor.
+ *
+ * Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
+ * Bernd Becker (becker@faw.uni-ulm.de)
+ *
+ * COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * COPYRIGHT (c) 1998-2001.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/sh_io.h>
+#include <rtems/score/cpu.h>
+#include <rtems/score/sh.h>
+
+/* referenced in start.S */
+extern proc_ptr vectab[] ;
+
+proc_ptr vectab[256] ;
+
+extern proc_ptr _Hardware_isr_Table[];
+
+/* _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 */
+)
+{
+ register uint32_t level = 0;
+
+ /*
+ * The thread_dispatch argument is the address of the entry point
+ * for the routine called at the end of an ISR once it has been
+ * decided a context switch is necessary. On some compilation
+ * systems it is difficult to call a high-level language routine
+ * from assembly. This allows us to trick these systems.
+ *
+ * If you encounter this problem save the entry point in a CPU
+ * dependent variable.
+ */
+
+ _CPU_Thread_dispatch_pointer = thread_dispatch;
+
+ /*
+ * If there is not an easy way to initialize the FP context
+ * during Context_Initialize, then it is usually easier to
+ * save an "uninitialized" FP context here and copy it to
+ * the task's during Context_Initialize.
+ */
+
+ /* FP context initialization support goes here */
+ /* FIXME: When not to use SH4_FPSCR_PR ? */
+#ifdef __SH4__
+ _CPU_Null_fp_context.fpscr = SH4_FPSCR_DN | SH4_FPSCR_RM | SH4_FPSCR_PR;
+#endif
+#ifdef __SH3E__
+ /* FIXME: Wild guess :) */
+ _CPU_Null_fp_context.fpscr = SH4_FPSCR_DN | SH4_FPSCR_RM;
+#endif
+
+ _CPU_Table = *cpu_table;
+
+ /* enable interrupts */
+ _CPU_ISR_Set_level( level);
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Get_level
+ */
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ /*
+ * This routine returns the current interrupt level.
+ */
+
+ register uint32_t _mask ;
+
+ sh_get_interrupt_level( _mask );
+
+ return ( _mask);
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_install_raw_handler
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ /*
+ * This is where we install the interrupt handler into the "raw" interrupt
+ * table used by the CPU to dispatch interrupt handlers.
+ */
+ volatile proc_ptr *vbr ;
+
+#if SH_PARANOID_ISR
+ uint32_t level ;
+
+ sh_disable_interrupts( level );
+#endif
+
+ /* get vbr */
+ asm ( "stc vbr,%0" : "=r" (vbr) );
+
+ *old_handler = vbr[vector] ;
+ vbr[vector] = new_handler ;
+
+#if SH_PARANOID_ISR
+ sh_enable_interrupts( level );
+#endif
+}
+
+
+/*PAGE
+ *
+ * _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
+ *
+ */
+
+#if defined(__sh1__) || defined(__sh2__)
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ proc_ptr ignored ;
+#if 0
+ if(( vector <= 113) && ( vector >= 11))
+ {
+#endif
+ *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.
+ */
+ _CPU_ISR_install_raw_handler(vector,
+ _Hardware_isr_Table[vector],
+ &ignored );
+
+ /*
+ * We put the actual user ISR address in '_ISR_Vector_table'.
+ * This will be used by __ISR_Handler so the user gets control.
+ */
+
+ _ISR_Vector_table[ vector ] = new_handler;
+#if 0
+ }
+#endif
+}
+#endif /* _CPU_ISR_install_vector */
+
+/*PAGE
+ *
+ * _CPU_Thread_Idle_body
+ *
+ * NOTES:
+ *
+ * 1. This is the same as the regular CPU independent algorithm.
+ *
+ * 2. If you implement this using a "halt", "idle", or "shutdown"
+ * instruction, then don't forget to put it in an infinite loop.
+ *
+ * 3. Be warned. Some processors with onboard DMA have been known
+ * to stop the DMA if the CPU were put in IDLE mode. This might
+ * also be a problem with other on-chip peripherals. So use this
+ * hook with caution.
+ */
+
+#if (CPU_PROVIDES_IDLE_THREAD_BODY == TRUE)
+void _CPU_Thread_Idle_body( void )
+{
+
+ for( ; ; )
+ {
+ asm volatile("nop");
+ }
+ /* insert your "halt" instruction here */ ;
+}
+#endif
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+uint8_t _bit_set_table[16] =
+ { 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1,0};
+
+
+#endif
+
+void _CPU_Context_Initialize(
+ Context_Control *_the_context,
+ void *_stack_base,
+ uint32_t _size,
+ uint32_t _isr,
+ void (*_entry_point)(void),
+ int _is_fp )
+{
+ _the_context->r15 = (uint32_t *) ((uint32_t ) (_stack_base) + (_size) );
+#if defined(__sh1__) || defined(__sh2__) || defined(__SH2E__)
+ _the_context->sr = (_isr << 4) & 0x00f0 ;
+#else
+ _the_context->sr = SH4_SR_MD | ((_isr << 4) & 0x00f0);
+#endif
+ _the_context->pr = (uint32_t *) _entry_point ;
+
+
+#if 0 && SH_HAS_FPU
+ /* Disable FPU if it is non-fp task */
+ if(!_is_fp)
+ _the_context->sr |= SH4_SR_FD;
+#endif
+}
diff --git a/cpukit/score/cpu/sh/preinstall.am b/cpukit/score/cpu/sh/preinstall.am
new file mode 100644
index 0000000000..f688e1b8bc
--- /dev/null
+++ b/cpukit/score/cpu/sh/preinstall.am
@@ -0,0 +1,45 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
+$(PROJECT_INCLUDE)/rtems/score/sh.h: rtems/score/sh.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/sh.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/sh.h
+
+$(PROJECT_INCLUDE)/rtems/score/sh_io.h: rtems/score/sh_io.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/sh_io.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/sh_io.h
+
diff --git a/cpukit/score/cpu/sh/rtems/asm.h b/cpukit/score/cpu/sh/rtems/asm.h
new file mode 100644
index 0000000000..56e11313d7
--- /dev/null
+++ b/cpukit/score/cpu/sh/rtems/asm.h
@@ -0,0 +1,136 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ */
+
+/*
+ * Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
+ * Bernd Becker (becker@faw.uni-ulm.de)
+ *
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ *
+ * COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * COPYRIGHT (c) 1998-2001.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/sh.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/*
+ * define macros for all of the registers on this CPU
+ *
+ * EXAMPLE: #define d0 REG (d0)
+ */
+#define r0 REG (r0)
+#define r1 REG (r1)
+#define r2 REG (r2)
+#define r3 REG (r3)
+#define r4 REG (r4)
+#define r5 REG (r5)
+#define r6 REG (r6)
+#define r7 REG (r7)
+#define r8 REG (r8)
+#define r9 REG (r9)
+#define r10 REG (r10)
+#define r11 REG (r11)
+#define r12 REG (r12)
+#define r13 REG (r13)
+#define r14 REG (r14)
+#define r15 REG (r15)
+#define vbr REG (vbr)
+#define gbr REG (gbr)
+#define pr REG (pr)
+#define mach REG (mach)
+#define macl REG (macl)
+#define sr REG (sr)
+#define pc REG (pc)
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA
+#define END_DATA
+#define BEGIN_BSS
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .global SYM (sym)
+#define EXTERN(sym) .global SYM (sym)
+
+#endif
diff --git a/cpukit/score/cpu/sh/rtems/score/cpu.h b/cpukit/score/cpu/sh/rtems/score/cpu.h
new file mode 100644
index 0000000000..b3da785134
--- /dev/null
+++ b/cpukit/score/cpu/sh/rtems/score/cpu.h
@@ -0,0 +1,946 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * This include file contains information pertaining to the Hitachi SH
+ * processor.
+ *
+ * Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
+ * Bernd Becker (becker@faw.uni-ulm.de)
+ *
+ * COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * COPYRIGHT (c) 1998-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/sh.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+#if 0 && defined(__SH4__)
+#include <rtems/score/sh4_regs.h>
+#endif
+
+/* conditional compilation parameters */
+
+/*
+ * Should the calls to _Thread_Enable_dispatch be inlined?
+ *
+ * If TRUE, then they are inlined.
+ * If FALSE, then a subroutine call is made.
+ *
+ * Basically this is an example of the classic trade-off of size
+ * versus speed. Inlining the call (TRUE) typically increases the
+ * size of RTEMS while speeding up the enabling of dispatching.
+ * [NOTE: In general, the _Thread_Dispatch_disable_level will
+ * only be 0 or 1 unless you are in an interrupt handler and that
+ * interrupt handler invokes the executive.] When not inlined
+ * something calls _Thread_Enable_dispatch which in turns calls
+ * _Thread_Dispatch. If the enable dispatch is inlined, then
+ * one subroutine call is avoided entirely.]
+ */
+
+#define CPU_INLINE_ENABLE_DISPATCH FALSE
+
+/*
+ * Should the body of the search loops in _Thread_queue_Enqueue_priority
+ * be unrolled one time? In unrolled each iteration of the loop examines
+ * two "nodes" on the chain being searched. Otherwise, only one node
+ * is examined per iteration.
+ *
+ * If TRUE, then the loops are unrolled.
+ * If FALSE, then the loops are not unrolled.
+ *
+ * The primary factor in making this decision is the cost of disabling
+ * and enabling interrupts (_ISR_Flash) versus the cost of rest of the
+ * body of the loop. On some CPUs, the flash is more expensive than
+ * one iteration of the loop body. In this case, it might be desirable
+ * to unroll the loop. It is important to note that on some CPUs, this
+ * code is the longest interrupt disable period in RTEMS. So it is
+ * necessary to strike a balance when setting this parameter.
+ */
+
+#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
+
+/*
+ * Does RTEMS manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in _ISR_Handler_initialization.
+ * If FALSE, nothing is done.
+ *
+ * If the CPU supports a dedicated interrupt stack in hardware,
+ * then it is generally the responsibility of the BSP to allocate it
+ * and set it up.
+ *
+ * If the CPU does not support a dedicated interrupt stack, then
+ * the porter has two options: (1) execute interrupts on the
+ * stack of the interrupted task, and (2) have RTEMS manage a dedicated
+ * interrupt stack.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
+
+/*
+ * We define the interrupt stack in the linker script
+ */
+#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
+
+/*
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ */
+
+#define CPU_ISR_PASSES_FRAME_POINTER 0
+
+/*
+ * Does the CPU have hardware floating point?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
+ *
+ * We currently support sh1 only, which has no FPU, other SHes have an FPU
+ *
+ * The macro name "SH_HAS_FPU" should be made CPU specific.
+ * It indicates whether or not this CPU model has FP support. For
+ * example, it would be possible to have an i386_nofp CPU model
+ * which set this to false to indicate that you have an i386 without
+ * an i387 and wish to leave floating point support out of RTEMS.
+ */
+
+#if SH_HAS_FPU
+#define CPU_HARDWARE_FP TRUE
+#define CPU_SOFTWARE_FP FALSE
+#else
+#define CPU_SOFTWARE_FP FALSE
+#define CPU_HARDWARE_FP FALSE
+#endif
+
+/*
+ * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
+ *
+ * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
+ */
+
+#if SH_HAS_FPU
+#define CPU_ALL_TASKS_ARE_FP TRUE
+#else
+#define CPU_ALL_TASKS_ARE_FP FALSE
+#endif
+
+/*
+ * Should the IDLE task have a floating point context?
+ *
+ * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * If FALSE, then the IDLE task does not have a floating point context.
+ *
+ * Setting this to TRUE negatively impacts the time required to preempt
+ * the IDLE task from an interrupt because the floating point context
+ * must be saved as part of the preemption.
+ */
+
+#if SH_HAS_FPU
+#define CPU_IDLE_TASK_IS_FP TRUE
+#else
+#define CPU_IDLE_TASK_IS_FP FALSE
+#endif
+
+/*
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ *
+ * If the floating point context does NOT have to be saved as part of
+ * interrupt dispatching, then it should be safe to set this to TRUE.
+ *
+ * Setting this flag to TRUE results in using a different algorithm
+ * for deciding when to save and restore the floating point context.
+ * The deferred FP switch algorithm minimizes the number of times
+ * the FP context is saved and restored. The FP context is not saved
+ * until a context switch is made to another, different FP task.
+ * Thus in a system with only one FP task, the FP context will never
+ * be saved or restored.
+ */
+
+#if SH_HAS_FPU
+#define CPU_USE_DEFERRED_FP_SWITCH FALSE
+#else
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+#endif
+
+/*
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine _CPU_Thread_Idle_body
+ * must be provided and is the default IDLE thread body instead of
+ * _CPU_Thread_Idle_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ *
+ * This is intended to allow for supporting processors which have
+ * a low power or idle mode. When the IDLE thread is executed, then
+ * the CPU can be powered down.
+ *
+ * The order of precedence for selecting the IDLE thread body is:
+ *
+ * 1. BSP provided
+ * 2. CPU dependent (if provided)
+ * 3. generic (if no BSP and no CPU dependent)
+ */
+
+#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE
+
+/*
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * If TRUE, then the grows upward.
+ * If FALSE, then the grows toward smaller addresses.
+ */
+
+#define CPU_STACK_GROWS_UP FALSE
+
+/*
+ * The following is the variable attribute used to force alignment
+ * of critical RTEMS structures. On some processors it may make
+ * sense to have these aligned on tighter boundaries than
+ * the minimum requirements of the compiler in order to have as
+ * much of the critical data area as possible in a cache line.
+ *
+ * The placement of this macro in the declaration of the variables
+ * is based on the syntactically requirements of the GNU C
+ * "__attribute__" extension. For example with GNU C, use
+ * the following to force a structures to a 32 byte boundary.
+ *
+ * __attribute__ ((aligned (32)))
+ *
+ * NOTE: Currently only the Priority Bit Map table uses this feature.
+ * To benefit from using this, the data must be heavily
+ * used so it will stay in the cache and used frequently enough
+ * in the executive to justify turning this on.
+ */
+
+#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned(16)))
+
+/*
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ *
+ * NOTE: SHes can be big or little endian, the default is big endian
+ */
+
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+
+/* __LITTLE_ENDIAN__ is defined if -ml is given to gcc */
+#if defined(__LITTLE_ENDIAN__)
+#define CPU_BIG_ENDIAN FALSE
+#define CPU_LITTLE_ENDIAN TRUE
+#else
+#define CPU_BIG_ENDIAN TRUE
+#define CPU_LITTLE_ENDIAN FALSE
+#endif
+
+/*
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
+ */
+
+#define CPU_MODES_INTERRUPT_MASK 0x0000000f
+
+/*
+ * Processor defined structures required for cpukit/score.
+ */
+
+/* may need to put some structures here. */
+
+/*
+ * Contexts
+ *
+ * Generally there are 2 types of context to save.
+ * 1. Interrupt registers to save
+ * 2. Task level registers to save
+ *
+ * This means we have the following 3 context items:
+ * 1. task level context stuff:: Context_Control
+ * 2. floating point task stuff:: Context_Control_fp
+ * 3. special interrupt level context :: Context_Control_interrupt
+ *
+ * On some processors, it is cost-effective to save only the callee
+ * preserved registers during a task context switch. This means
+ * that the ISR code needs to save those registers which do not
+ * persist across function calls. It is not mandatory to make this
+ * distinctions between the caller/callee saves registers for the
+ * purpose of minimizing context saved during task switch and on interrupts.
+ * If the cost of saving extra registers is minimal, simplicity is the
+ * choice. Save the same context on interrupt entry as for tasks in
+ * this case.
+ *
+ * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
+ * care should be used in designing the context area.
+ *
+ * On some CPUs with hardware floating point support, the Context_Control_fp
+ * structure will not be used or it simply consist of an array of a
+ * fixed number of bytes. This is done when the floating point context
+ * is dumped by a "FP save context" type instruction and the format
+ * is not really defined by the CPU. In this case, there is no need
+ * to figure out the exact format -- only the size. Of course, although
+ * this is enough information for RTEMS, it is probably not enough for
+ * a debugger such as gdb. But that is another problem.
+ */
+
+typedef struct {
+ uint32_t *r15; /* stack pointer */
+
+ uint32_t macl;
+ uint32_t mach;
+ uint32_t *pr;
+
+ uint32_t *r14; /* frame pointer/call saved */
+
+ uint32_t r13; /* call saved */
+ uint32_t r12; /* call saved */
+ uint32_t r11; /* call saved */
+ uint32_t r10; /* call saved */
+ uint32_t r9; /* call saved */
+ uint32_t r8; /* call saved */
+
+ uint32_t *r7; /* arg in */
+ uint32_t *r6; /* arg in */
+
+#if 0
+ uint32_t *r5; /* arg in */
+ uint32_t *r4; /* arg in */
+#endif
+
+ uint32_t *r3; /* scratch */
+ uint32_t *r2; /* scratch */
+ uint32_t *r1; /* scratch */
+
+ uint32_t *r0; /* arg return */
+
+ uint32_t gbr;
+ uint32_t sr;
+
+} Context_Control;
+
+typedef struct {
+#if SH_HAS_FPU
+#ifdef SH4_USE_X_REGISTERS
+ union {
+ float f[16];
+ double d[8];
+ } x;
+#endif
+ union {
+ float f[16];
+ double d[8];
+ } r;
+ float fpul; /* fp communication register */
+ uint32_t fpscr; /* fp control register */
+#endif /* SH_HAS_FPU */
+} Context_Control_fp;
+
+typedef struct {
+} CPU_Interrupt_frame;
+
+
+/*
+ * The following table contains the information required to configure
+ * the SH processor specific parameters.
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+ /* end of fields required on all CPUs */
+ uint32_t clicks_per_second ; /* cpu frequency in Hz */
+} rtems_cpu_table;
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ */
+
+/*
+ * Macros to access SH specific additions to the CPU Table
+ */
+
+#define rtems_cpu_configuration_get_clicks_per_second() \
+ (_CPU_Table.clicks_per_second)
+
+/*
+ * This variable is optional. It is used on CPUs on which it is difficult
+ * to generate an "uninitialized" FP context. It is filled in by
+ * _CPU_Initialize and copied into the task's FP context area during
+ * _CPU_Context_Initialize.
+ */
+
+#if SH_HAS_FPU
+SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
+#endif
+
+/*
+ * On some CPUs, RTEMS supports a software managed interrupt stack.
+ * This stack is allocated by the Interrupt Manager and the switch
+ * is performed in _ISR_Handler. These variables contain pointers
+ * to the lowest and highest addresses in the chunk of memory allocated
+ * for the interrupt stack. Since it is unknown whether the stack
+ * grows up or down (in general), this give the CPU dependent
+ * code the option of picking the version it wants to use.
+ *
+ * NOTE: These two variables are required if the macro
+ * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
+ */
+
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+/*
+ * With some compilation systems, it is difficult if not impossible to
+ * call a high-level language routine from assembly language. This
+ * is especially true of commercial Ada compilers and name mangling
+ * C++ ones. This variable can be optionally defined by the CPU porter
+ * and contains the address of the routine _Thread_Dispatch. This
+ * can make it easier to invoke that routine at the end of the interrupt
+ * sequence (if a dispatch is necessary).
+ */
+
+SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
+
+/*
+ * Nothing prevents the porter from declaring more CPU specific variables.
+ */
+
+/* XXX: if needed, put more variables here */
+SCORE_EXTERN void CPU_delay( uint32_t microseconds );
+
+/*
+ * The size of the floating point context area. On some CPUs this
+ * will not be a "sizeof" because the format of the floating point
+ * area is not defined -- only the size is. This is usually on
+ * CPUs with a "floating point save context" instruction.
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/*
+ * Amount of extra stack (above minimum stack size) required by
+ * MPCI receive server thread. Remember that in a multiprocessor
+ * system this thread must exist and be able to process all directives.
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+/*
+ * This defines the number of entries in the ISR_Vector_table managed
+ * by RTEMS.
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
+
+/*
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level.
+ */
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/*
+ * Should be large enough to run all RTEMS tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ *
+ * We have been able to run the sptests with this value, but have not
+ * been able to run the tmtest suite.
+ */
+
+#define CPU_STACK_MINIMUM_SIZE 4096
+
+/*
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ */
+#if defined(__SH4__)
+/* FIXME: sh3 and SH3E? */
+#define CPU_ALIGNMENT 8
+#else
+#define CPU_ALIGNMENT 4
+#endif
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
+ * then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
+ * enough for the partition, then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * stack. This alignment requirement may be stricter than that for the
+ * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
+ * is strict enough for the stack, then this should be set to 0.
+ *
+ * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
+ */
+
+#define CPU_STACK_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * ISR handler macros
+ */
+
+/*
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ *
+ * SH Specific Information: NONE
+ */
+
+#define _CPU_Initialize_vectors()
+
+/*
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in _level.
+ */
+
+#define _CPU_ISR_Disable( _level) \
+ sh_disable_interrupts( _level )
+
+/*
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * _level is not modified.
+ */
+
+#define _CPU_ISR_Enable( _level) \
+ sh_enable_interrupts( _level)
+
+/*
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ */
+
+#define _CPU_ISR_Flash( _level) \
+ sh_flash_interrupts( _level)
+
+/*
+ * Map interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a generic fashion are undefined. Someday,
+ * it would be nice if these were "mapped" by the application
+ * via a callout. For example, m68k has 8 levels 0 - 7, levels
+ * 8 - 255 would be available for bsp/application specific meaning.
+ * This could be used to manage a programmable interrupt controller
+ * via the rtems_task_mode directive.
+ */
+
+#define _CPU_ISR_Set_level( _newlevel) \
+ sh_set_interrupt_level(_newlevel)
+
+uint32_t _CPU_ISR_Get_level( void );
+
+/* end of ISR handler macros */
+
+/* Context handler macros */
+
+/*
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * This routine generally does not set any unnecessary register
+ * in the context. The state of the "general data" registers is
+ * undefined at task start time.
+ *
+ * NOTE: This is_fp parameter is TRUE if the thread is to be a floating
+ * point thread. This is typically only used on CPUs where the
+ * FPU may be easily disabled by software such as on the SPARC
+ * where the PSR contains an enable FPU bit.
+ */
+
+/*
+ * FIXME: defined as a function for debugging - should be a macro
+ */
+SCORE_EXTERN void _CPU_Context_Initialize(
+ Context_Control *_the_context,
+ void *_stack_base,
+ uint32_t _size,
+ uint32_t _isr,
+ void (*_entry_point)(void),
+ int _is_fp );
+
+/*
+ * This routine is responsible for somehow restarting the currently
+ * executing task. If you are lucky, then all that is necessary
+ * is restoring the context. Otherwise, there will need to be
+ * a special assembly routine which does something special in this
+ * case. Context_Restore should work most of the time. It will
+ * not work if restarting self conflicts with the stack frame
+ * assumptions of restoring a context.
+ */
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+/*
+ * The purpose of this macro is to allow the initial pointer into
+ * a floating point context area (used to save the floating point
+ * context) to be at an arbitrary place in the floating point
+ * context area.
+ *
+ * This is necessary because some FP units are designed to have
+ * their context saved as a stack which grows into lower addresses.
+ * Other FP units can be saved by simply moving registers into offsets
+ * from the base of the context area. Finally some FP units provide
+ * a "dump context" instruction which could fill in from high to low
+ * or low to high based on the whim of the CPU designers.
+ */
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
+
+/*
+ * This routine initializes the FP context area passed to it to.
+ * There are a few standard ways in which to initialize the
+ * floating point context. The code included for this macro assumes
+ * that this is a CPU in which a "initial" FP context was saved into
+ * _CPU_Null_fp_context and it simply copies it to the destination
+ * context passed to it.
+ *
+ * Other models include (1) not doing anything, and (2) putting
+ * a "null FP status word" in the correct place in the FP context.
+ * SH1, SH2, SH3 have no FPU, but the SH3e and SH4 have.
+ */
+
+#if SH_HAS_FPU
+#define _CPU_Context_Initialize_fp( _destination ) \
+ do { \
+ *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context;\
+ } while(0)
+#else
+#define _CPU_Context_Initialize_fp( _destination ) \
+ { }
+#endif
+
+/* end of Context handler macros */
+
+/* Fatal Error manager macros */
+
+/*
+ * FIXME: Trap32 ???
+ *
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * invokes a Trap32 Instruction which returns to the breakpoint
+ * routine of cmon.
+ */
+
+#ifdef BSP_FATAL_HALT
+ /* we manage the fatal error in the board support package */
+ void bsp_fatal_halt( uint32_t _error);
+#define _CPU_Fatal_halt( _error ) bsp_fatal_halt( _error)
+#else
+#define _CPU_Fatal_halt( _error)\
+{ \
+ asm volatile("mov.l %0,r0"::"m" (_error)); \
+ asm volatile("mov #1, r4"); \
+ asm volatile("trapa #34"); \
+}
+#endif
+
+/* end of Fatal Error manager macros */
+
+/* Bitfield handler macros */
+
+/*
+ * This routine sets _output to the bit number of the first bit
+ * set in _value. _value is of CPU dependent type Priority_Bit_map_control.
+ * This type may be either 16 or 32 bits wide although only the 16
+ * least significant bits will be used.
+ *
+ * There are a number of variables in using a "find first bit" type
+ * instruction.
+ *
+ * (1) What happens when run on a value of zero?
+ * (2) Bits may be numbered from MSB to LSB or vice-versa.
+ * (3) The numbering may be zero or one based.
+ * (4) The "find first bit" instruction may search from MSB or LSB.
+ *
+ * RTEMS guarantees that (1) will never happen so it is not a concern.
+ * (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
+ * _CPU_Priority_bits_index(). These three form a set of routines
+ * which must logically operate together. Bits in the _value are
+ * set and cleared based on masks built by _CPU_Priority_mask().
+ * The basic major and minor values calculated by _Priority_Major()
+ * and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
+ * to properly range between the values returned by the "find first bit"
+ * instruction. This makes it possible for _Priority_Get_highest() to
+ * calculate the major and directly index into the minor table.
+ * This mapping is necessary to ensure that 0 (a high priority major/minor)
+ * is the first bit found.
+ *
+ * This entire "find first bit" and mapping process depends heavily
+ * on the manner in which a priority is broken into a major and minor
+ * components with the major being the 4 MSB of a priority and minor
+ * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
+ * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next
+ * to the lowest priority.
+ *
+ * If your CPU does not have a "find first bit" instruction, then
+ * there are ways to make do without it. Here are a handful of ways
+ * to implement this in software:
+ *
+ * - a series of 16 bit test instructions
+ * - a "binary search using if's"
+ * - _number = 0
+ * if _value > 0x00ff
+ * _value >>=8
+ * _number = 8;
+ *
+ * if _value > 0x0000f
+ * _value >=8
+ * _number += 4
+ *
+ * _number += bit_set_table[ _value ]
+ *
+ * where bit_set_table[ 16 ] has values which indicate the first
+ * bit set
+ */
+
+#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+extern uint8_t _bit_set_table[];
+
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ _output = 0;\
+ if(_value > 0x00ff) \
+ { _value >>= 8; _output = 8; } \
+ if(_value > 0x000f) \
+ { _output += 4; _value >>= 4; } \
+ _output += _bit_set_table[ _value]; }
+
+#endif
+
+/* end of Bitfield handler macros */
+
+/*
+ * This routine builds the mask which corresponds to the bit fields
+ * as searched by _CPU_Bitfield_Find_first_bit(). See the discussion
+ * for that routine.
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_Mask( _bit_number ) \
+ ( 1 << (_bit_number) )
+
+#endif
+
+/*
+ * This routine translates the bit numbers returned by
+ * _CPU_Bitfield_Find_first_bit() into something suitable for use as
+ * a major or minor component of a priority. See the discussion
+ * for that routine.
+ */
+
+#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
+
+#define _CPU_Priority_bits_index( _priority ) \
+ (_priority)
+
+#endif
+
+/* end of Priority handler macros */
+
+/* functions */
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/*
+ * _CPU_ISR_install_raw_handler
+ *
+ * This routine installs a "raw" interrupt handler directly into the
+ * processor's vector table.
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_Install_interrupt_stack
+ *
+ * This routine installs the hardware interrupt stack pointer.
+ *
+ * NOTE: It needs only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK
+ * is TRUE.
+ */
+
+void _CPU_Install_interrupt_stack( void );
+
+/*
+ * _CPU_Thread_Idle_body
+ *
+ * This routine is the CPU dependent IDLE thread body.
+ *
+ * NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
+ * is TRUE.
+ */
+
+void _CPU_Thread_Idle_body( void );
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally used only to restart self in an
+ * efficient manner. It may simply be a label in _CPU_Context_switch.
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/sh/rtems/score/sh.h b/cpukit/score/cpu/sh/rtems/score/sh.h
new file mode 100644
index 0000000000..b19855abe1
--- /dev/null
+++ b/cpukit/score/cpu/sh/rtems/score/sh.h
@@ -0,0 +1,273 @@
+/**
+ * @file rtems/score/sh.h
+ */
+
+/*
+ * This include file contains information pertaining to the Hitachi SH
+ * processor.
+ *
+ * Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
+ * Bernd Becker (becker@faw.uni-ulm.de)
+ *
+ * COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
+ *
+ *
+ * COPYRIGHT (c) 1998-2001.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_SH_H
+#define _RTEMS_SCORE_SH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the "SH" family.
+ *
+ * It does this by setting variables to indicate which implementation
+ * dependent features are present in a particular member of the family.
+ */
+
+/*
+ * Figure out all CPU Model Feature Flags based upon compiler
+ * predefines.
+ */
+
+#if defined(__SH2E__) || defined(__SH3E__) || \
+ defined(__SH4__) || defined(__SH4_SINGLE_ONLY__)
+
+/*
+ * Define this if you want to use XD-registers.
+ * Then this registers will be saved/restored on context switch.
+ * ! They will not be saved/restored on interrupts!
+ */
+#define SH4_USE_X_REGISTERS 0
+
+#if defined(__LITTLE_ENDIAN__)
+#define SH_HAS_FPU 1
+#else
+/* FIXME: Context_Control_fp does not support big endian */
+#warning FPU not supported
+#define SH_HAS_FPU 0
+#endif
+
+#elif defined(__sh1__) || defined(__sh2__) || defined(__sh3__)
+#define SH_HAS_FPU 0
+#else
+#warning Cannot detect FPU support, assuming no FPU
+#define SH_HAS_FPU 0
+#endif
+
+/* this should not be here */
+#ifndef CPU_MODEL_NAME
+#define CPU_MODEL_NAME "SH-Multilib"
+#endif
+
+/*
+ * If the following macro is set to 0 there will be no software irq stack
+ */
+
+#ifndef SH_HAS_SEPARATE_STACKS
+#define SH_HAS_SEPARATE_STACKS 1
+#endif
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "Hitachi SH"
+
+#ifndef ASM
+
+#if defined(__sh1__) || defined(__sh2__)
+
+/*
+ * Mask for disabling interrupts
+ */
+#define SH_IRQDIS_VALUE 0xf0
+
+#define sh_disable_interrupts( _level ) \
+ asm volatile ( \
+ "stc sr,%0\n\t" \
+ "ldc %1,sr\n\t"\
+ : "=&r" (_level ) \
+ : "r" (SH_IRQDIS_VALUE) );
+
+#define sh_enable_interrupts( _level ) \
+ asm volatile( "ldc %0,sr\n\t" \
+ "nop\n\t" \
+ :: "r" (_level) );
+
+/*
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ */
+
+#define sh_flash_interrupts( _level ) \
+ asm volatile( \
+ "ldc %1,sr\n\t" \
+ "nop\n\t" \
+ "ldc %0,sr\n\t" \
+ "nop\n\t" \
+ : : "r" (SH_IRQDIS_VALUE), "r" (_level) );
+
+#else
+
+#define SH_IRQDIS_MASK 0xf0
+
+#define sh_disable_interrupts( _level ) \
+ asm volatile ( \
+ "stc sr,%0\n\t" \
+ "mov %0,r5\n\t" \
+ "or %1,r5\n\t" \
+ "ldc r5,sr\n\t"\
+ : "=&r" (_level ) \
+ : "r" (SH_IRQDIS_MASK) \
+ : "r5" );
+
+#define sh_enable_interrupts( _level ) \
+ asm volatile( "ldc %0,sr\n\t" \
+ "nop\n\t" \
+ :: "r" (_level) );
+
+/*
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ */
+
+#define sh_flash_interrupts( _level ) \
+ asm volatile( \
+ "stc sr,r5\n\t" \
+ "ldc %1,sr\n\t" \
+ "nop\n\t" \
+ "or %0,r5\n\t" \
+ "ldc r5,sr\n\t" \
+ "nop\n\t" \
+ : : "r" (SH_IRQDIS_MASK), "r" (_level) : "r5");
+
+#endif
+
+#define sh_get_interrupt_level( _level ) \
+{ \
+ register uint32_t _tmpsr ; \
+ \
+ asm volatile( "stc sr, %0" : "=r" (_tmpsr) ); \
+ _level = (_tmpsr & 0xf0) >> 4 ; \
+}
+
+#define sh_set_interrupt_level( _newlevel ) \
+{ \
+ register uint32_t _tmpsr; \
+ \
+ asm volatile ( "stc sr, %0" : "=r" (_tmpsr) ); \
+ _tmpsr = ( _tmpsr & ~0xf0 ) | ((_newlevel) << 4) ; \
+ asm volatile( "ldc %0,sr" :: "r" (_tmpsr) ); \
+}
+
+/*
+ * The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ */
+
+static inline uint32_t sh_swap_u32(
+ uint32_t value
+)
+{
+ register uint32_t swapped;
+
+ asm volatile (
+ "swap.b %1,%0; "
+ "swap.w %0,%0; "
+ "swap.b %0,%0"
+ : "=r" (swapped)
+ : "r" (value) );
+
+ return( swapped );
+}
+
+static inline uint16_t sh_swap_u16(
+ uint16_t value
+)
+{
+ register uint16_t swapped ;
+
+ asm volatile ( "swap.b %1,%0" : "=r" (swapped) : "r" (value) );
+
+ return( swapped );
+}
+
+#define CPU_swap_u32( value ) sh_swap_u32( value )
+#define CPU_swap_u16( value ) sh_swap_u16( value )
+
+extern unsigned int sh_set_irq_priority(
+ unsigned int irq,
+ unsigned int prio );
+
+#endif /* !ASM */
+
+/*
+ * Bits on SH-4 registers.
+ * See SH-4 Programming manual for more details.
+ *
+ * Added by Alexandra Kossovsky <sasha@oktet.ru>
+ */
+
+#if defined(__SH4__)
+#define SH4_SR_MD 0x40000000 /* Priveleged mode */
+#define SH4_SR_RB 0x20000000 /* General register bank specifier */
+#define SH4_SR_BL 0x10000000 /* Exeption/interrupt masking bit */
+#define SH4_SR_FD 0x00008000 /* FPU disable bit */
+#define SH4_SR_M 0x00000200 /* For signed division:
+ divisor (module) is negative */
+#define SH4_SR_Q 0x00000100 /* For signed division:
+ dividend (and quotient) is negative */
+#define SH4_SR_IMASK 0x000000f0 /* Interrupt mask level */
+#define SH4_SR_IMASK_S 4
+#define SH4_SR_S 0x00000002 /* Saturation for MAC instruction:
+ if set, data in MACH/L register
+ is restricted to 48/32 bits
+ for MAC.W/L instructions */
+#define SH4_SR_T 0x00000001 /* 1 if last condiyion was true */
+#define SH4_SR_RESERV 0x8fff7d0d /* Reserved bits, read/write as 0 */
+
+/* FPSCR -- FPU Status/Control Register */
+#define SH4_FPSCR_FR 0x00200000 /* FPU register bank specifier */
+#define SH4_FPSCR_SZ 0x00100000 /* FMOV 64-bit transfer mode */
+#define SH4_FPSCR_PR 0x00080000 /* Double-percision floating-point
+ operations flag */
+ /* SH4_FPSCR_SZ & SH4_FPSCR_PR != 1 */
+#define SH4_FPSCR_DN 0x00040000 /* Treat denormalized number as zero */
+#define SH4_FPSCR_CAUSE 0x0003f000 /* FPU exeption cause field */
+#define SH4_FPSCR_CAUSE_S 12
+#define SH4_FPSCR_ENABLE 0x00000f80 /* FPU exeption enable field */
+#define SH4_FPSCR_ENABLE_s 7
+#define SH4_FPSCR_FLAG 0x0000007d /* FPU exeption flag field */
+#define SH4_FPSCR_FLAG_S 2
+#define SH4_FPSCR_RM 0x00000001 /* Rounding mode:
+ 1/0 -- round to zero/nearest */
+#define SH4_FPSCR_RESERV 0xffd00000 /* Reserved bits, read/write as 0 */
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/sh/rtems/score/sh_io.h b/cpukit/score/cpu/sh/rtems/score/sh_io.h
new file mode 100644
index 0000000000..e3f91bdcde
--- /dev/null
+++ b/cpukit/score/cpu/sh/rtems/score/sh_io.h
@@ -0,0 +1,51 @@
+/**
+ * @file rtems/score/sh_io.h
+ */
+
+/*
+ * These are some macros to access memory mapped devices
+ * on the SH7000-architecture.
+ *
+ * Inspired from the linux kernel's include/asm/io.h
+ *
+ * Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
+ * Bernd Becker (becker@faw.uni-ulm.de)
+ *
+ * COPYRIGHT (c) 1996-1998, FAW Ulm, Germany
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * COPYRIGHT (c) 1998-2001.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_SH_IO_H
+#define _RTEMS_SCORE_SH_IO_H
+
+#define readb(addr) (*(volatile unsigned char *) (addr))
+#define readw(addr) (*(volatile unsigned short *) (addr))
+#define readl(addr) (*(volatile unsigned int *) (addr))
+#define read8(addr) (*(volatile uint8_t *) (addr))
+#define read16(addr) (*(volatile uint16_t *) (addr))
+#define read32(addr) (*(volatile uint32_t *) (addr))
+
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+#define write8(b,addr) ((*(volatile uint8_t *) (addr)) = (b))
+#define write16(b,addr) ((*(volatile uint16_t *) (addr)) = (b))
+#define write32(b,addr) ((*(volatile uint32_t *) (addr)) = (b))
+
+#define inb(addr) readb(addr)
+#define outb(b,addr) writeb(b,addr)
+
+#endif
diff --git a/cpukit/score/cpu/sh/rtems/score/types.h b/cpukit/score/cpu/sh/rtems/score/types.h
new file mode 100644
index 0000000000..2484b3bf5a
--- /dev/null
+++ b/cpukit/score/cpu/sh/rtems/score/types.h
@@ -0,0 +1,65 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains information pertaining to the Hitachi SH
+ * processor.
+ *
+ * Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
+ * Bernd Becker (becker@faw.uni-ulm.de)
+ *
+ * COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * COPYRIGHT (c) 1998-2001.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+
+typedef uint16_t Priority_Bit_map_control;
+
+typedef signed long long signed64; /* 64 bit signed integer */
+
+typedef uint16_t boolean; /* Boolean value, external */
+ /* data bus has 16 bits */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void sh_isr;
+typedef void ( *sh_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/sparc/.cvsignore b/cpukit/score/cpu/sparc/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/score/cpu/sparc/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/score/cpu/sparc/ChangeLog b/cpukit/score/cpu/sparc/ChangeLog
new file mode 100644
index 0000000000..3cad2c9cfa
--- /dev/null
+++ b/cpukit/score/cpu/sparc/ChangeLog
@@ -0,0 +1,341 @@
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Part of a large patch to improve Doxygen output.
+ As a side-effect, grammar and spelling errors were corrected, spacing
+ errors were address, and some variable names were improved.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16, unsigned32.
+
+2005-10-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/asm.h: Remove private version of CONCAT macros.
+ Include <rtems/concat.h> instead.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/cpu.h, rtems/score/sparc.h,
+ rtems/score/types.h: New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: *_swap_u32( uint32_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: #include <rtems/stdint.h>.
+
+2005-01-22 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Fix broken #endif.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove build-variant support.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Use __rtems_score_types_h as preprocessor
+ guard.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * asm.h: Add doxygen preamble.
+
+2004-10-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Add doxygen preamble.
+ * rtems/score/sparc.h: Add doxygen preamble.
+ * rtems/score/types.h: Add doxygen preamble.
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: Remove (Merged into$(top_srcdir)/configure.ac).
+ * Makefile.am: Don't include multilib.am.
+ Reflect merging configure.ac into $(top_srcdir)/configure.ac.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Install asm.h to $(includedir)/rtems.
+
+2004-04-01 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu_asm.S: Include <rtems/asm.h> instead of <asm.h>.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu.c, rtems/score/cpu.h, rtems/score/sparc.h: Convert to using
+ c99 fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: RTEMS_TOP([../../../..]).
+
+2004-02-26 Andreas Karlsson <andreas.karlsson@space.se>
+
+ 604/bsps
+ * cpu_asm.S: Close window while restoring interrupted task state which
+ resulted in CWP corruption.
+
+2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Move RTEMS_TOP one subdir down.
+
+2004-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add PREINSTALL_DIRS.
+
+2004-01-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Re-add dirstamps to PREINSTALL_FILES.
+ Add PREINSTALL_FILES to CLEANFILES.
+
+2004-01-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Requires automake >= 1.8.1.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, again.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Convert to using automake compilation rules.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use mkdir_p. Remove dirs from PREINSTALL_FILES.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require automake >= 1.8, autoconf >= 2.59.
+
+2003-12-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Remove TMPINSTALL_FILES.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Don't use gmake rules for preinstallation.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CANONICAL_HOST.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CPU.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, cpu_asm.S, rtems/score/cpu.h, rtems/score/sparc.h,
+ rtems/score/types.h: URL for license changed.
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require autoconf-2.57 + automake-1.7.2.
+ * Makefile.am: Eliminate C_O_FILES, S_O_FILES, libscorecpu_a_OBJECTS.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix package name.
+
+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-08 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * cpu.c: Move pointer into #ifdef to avoid compiler warning.
+
+2002-07-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use .$(OBJEXT) instead of .o.
+
+2002-07-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: RTEMS_TOP(../../../..).
+
+2002-07-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems.S: Remove.
+ * Makefile.am: Reflect changes above.
+
+2002-07-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_PROJECT_ROOT.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Add RTEMS_PROG_CCAS
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AC_CONFIG_AUX_DIR(../../../..).
+ Add AC_PROG_RANLIB.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/../../../automake/*.am.
+ Use ../../../aclocal.
+
+2002-04-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * cpu.c: Remove call to sparc_init_tbr/NO_TABLE_MOVE.
+ * rtems/score/cpu.h: Remove NO_TABLE_MOVE conditional code.
+
+
+2001-04-03 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
+ * rtems/score/sparctypes.h: Removed.
+ * rtems/score/types.h: New file via CVS magic.
+ * Makefile.am, rtems/score/cpu.h: Account for name change.
+
+2002-03-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * cpu.c: Replace NO_TABLE_MOVE-support by external function
+ (code moved to libcpu/sparc/tbr/tbr.c).
+ * cpu.h: Replace NO_TABLE_MOVE-support by external function
+ (code moved to libcpu/sparc/tbr/tbr.h).
+ * sparc.h: Add sparc_init_tbr (implemented in libcpu/sparc/tbr/tbr.c).
+
+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.
+
+2002-01-31 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Reflect 2002-01-23 changes.
+
+2001-01-30 Joel Sherrill <joel@OARcorp.com>
+
+ * Makefile.am: Corrected so .h files from rtems/score/ are installed.
+
+2002-01-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/Makefile.am: Removed.
+ * rtems/score/Makefile.am: Removed.
+ * configure.ac: Reflect changes above.
+
+2001-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add multilib support.
+
+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.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+
+2001-09-27 Jiri Gaisler <jiri@gaisler.com>
+
+ * cpu_asm.S: Small patch to fix a bug in the rtems sparc port. The
+ bug has been there all the time, but only hits the leon bsp since the
+ leon cpu has a 5-stage pipeline (erc32 has 4 stages).
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/Makefile.am: Use 'PREINSTALL_FILES ='.
+ * Makefile.am: Use 'PREINSTALL_FILES ='.
+
+
+2001-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, rtems/score/Makefile.am:
+ Apply include_*HEADERS instead of H_FILES.
+
+2001-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Added _CPU_Initialize_vectors().
+ * cpu_asm.S: Modify to properly dereference _ISR_Vector_table
+ now that it is dynamically allocated.
+
+2000-12-06 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c: Added include of <rtems/rtems/cache.h> to eliminate warning.
+
+2000-11-21 Jiri Gaisler <jgais@ws.estec.esa.nl>
+
+ * cpu_asm.S: Fix for CPUs with FPU revision B or C.
+
+2000-11-14 Jiri Gaisler <jgais@ws.estec.esa.nl>
+
+ * cpu.c, rtems/cpu/sparc.h: Make floating point optional based
+ on gcc arguments. Do not initialize FP context if there is
+ no FPU. Flush instruction cache after installing RTEMS trap handler.
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
+ Switch to GNU canonicalization.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am.
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: New file.
diff --git a/cpukit/score/cpu/sparc/Makefile.am b/cpukit/score/cpu/sparc/Makefile.am
new file mode 100644
index 0000000000..6d4c4aead1
--- /dev/null
+++ b/cpukit/score/cpu/sparc/Makefile.am
@@ -0,0 +1,19 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/sparc.h rtems/score/cpu.h \
+ rtems/score/types.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/sparc/README b/cpukit/score/cpu/sparc/README
new file mode 100644
index 0000000000..c4c2200075
--- /dev/null
+++ b/cpukit/score/cpu/sparc/README
@@ -0,0 +1,110 @@
+#
+# $Id$
+#
+
+This file discusses SPARC specific issues which are important to
+this port. The primary topics in this file are:
+
+ + Global Register Usage
+ + Stack Frame
+ + EF bit in the PSR
+
+
+Global Register Usage
+=====================
+
+This information on register usage is based heavily on a comment in the
+file gcc-2.7.0/config/sparc/sparc.h in the the gcc 2.7.0 source.
+
+ + g0 is hardwired to 0
+ + On non-v9 systems:
+ - g1 is free to use as temporary.
+ - g2-g4 are reserved for applications. Gcc normally uses them as
+ temporaries, but this can be disabled via the -mno-app-regs option.
+ - g5 through g7 are reserved for the operating system.
+ + On v9 systems:
+ - g1 and g5 are free to use as temporaries.
+ - g2-g4 are reserved for applications (the compiler will not normally use
+ them, but they can be used as temporaries with -mapp-regs).
+ - g6-g7 are reserved for the operating system.
+
+ NOTE: As of gcc 2.7.0 register g1 was used in the following scenarios:
+
+ + as a temporary by the 64 bit sethi pattern
+ + when restoring call-preserved registers in large stack frames
+
+RTEMS places no constraints on the usage of the global registers. Although
+gcc assumes that either g5-g7 (non-V9) or g6-g7 (V9) are reserved for the
+operating system, RTEMS does not assume any special use for them.
+
+
+
+Stack Frame
+===========
+
+The stack grows downward (i.e. to lower addresses) on the SPARC architecture.
+
+The following is the organization of the stack frame:
+
+
+
+ | ............... |
+ fp | |
+ +-------------------------------+
+ | |
+ | Local registers, temporaries, |
+ | and saved floats | x bytes
+ | |
+ sp + x +-------------------------------+
+ | |
+ | outgoing parameters past |
+ | the sixth one | x bytes
+ | |
+ sp + 92 +-------------------------------+ *
+ | | *
+ | area for callee to save | *
+ | register arguments | * 24 bytes
+ | | *
+ sp + 68 +-------------------------------+ *
+ | | *
+ | structure return pointer | * 4 bytes
+ | | *
+ sp + 64 +-------------------------------+ *
+ | | *
+ | local register set | * 32 bytes
+ | | *
+ sp + 32 +-------------------------------+ *
+ | | *
+ | input register set | * 32 bytes
+ | | *
+ sp +-------------------------------+ *
+
+
+* = minimal stack frame
+
+x = optional components
+
+EF bit in the PSR
+=================
+
+The EF (enable floating point unit) in the PSR is utilized in this port to
+prevent non-floating point tasks from performing floating point
+operations. This bit is maintained as part of the integer context.
+However, the floating point context is switched BEFORE the integer
+context. Thus the EF bit in place at the time of the FP switch may
+indicate that FP operations are disabled. This occurs on certain task
+switches, when the EF bit will be 0 for the outgoing task and thus a fault
+will be generated on the first FP operation of the FP context save.
+
+The remedy for this is to enable FP access as the first step in both the
+save and restore of the FP context area. This bit will be subsequently
+reloaded by the integer context switch.
+
+Two of the scenarios which demonstrate this problem are outlined below:
+
+1. When the first FP task is switched to. The system tasks are not FP and
+thus would be unable to restore the FP context of the incoming task.
+
+2. On a deferred FP context switch. In this case, the system might switch
+from FP Task A to non-FP Task B and then to FP Task C. In this scenario,
+the floating point state must technically be saved by a non-FP task.
diff --git a/cpukit/score/cpu/sparc/cpu.c b/cpukit/score/cpu/sparc/cpu.c
new file mode 100644
index 0000000000..16f7c81dfb
--- /dev/null
+++ b/cpukit/score/cpu/sparc/cpu.c
@@ -0,0 +1,330 @@
+/*
+ * SPARC Dependent Source
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/rtems/cache.h>
+
+/*
+ * This initializes the set of opcodes placed in each trap
+ * table entry. The routine which installs a handler is responsible
+ * for filling in the fields for the _handler address and the _vector
+ * trap type.
+ *
+ * The constants following this structure are masks for the fields which
+ * must be filled in when the handler is installed.
+ */
+
+const CPU_Trap_table_entry _CPU_Trap_slot_template = {
+ 0xa1480000, /* mov %psr, %l0 */
+ 0x29000000, /* sethi %hi(_handler), %l4 */
+ 0x81c52000, /* jmp %l4 + %lo(_handler) */
+ 0xa6102000 /* mov _vector, %l3 */
+};
+
+/*PAGE
+ *
+ * _CPU_Initialize
+ *
+ * This routine performs processor dependent initialization.
+ *
+ * Input Parameters:
+ * cpu_table - CPU table to initialize
+ * thread_dispatch - address of disptaching routine
+ *
+ * Output Parameters: NONE
+ *
+ * NOTE: There is no need to save the pointer to the thread dispatch routine.
+ * The SPARC's assembly code can reference it directly with no problems.
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch) /* ignored on this CPU */
+)
+{
+#if (SPARC_HAS_FPU == 1)
+ void *pointer;
+
+ /*
+ * This seems to be the most appropriate way to obtain an initial
+ * FP context on the SPARC. The NULL fp context is copied it to
+ * the task's FP context during Context_Initialize.
+ */
+
+ pointer = &_CPU_Null_fp_context;
+ _CPU_Context_save_fp( &pointer );
+#endif
+
+ /*
+ * Grab our own copy of the user's CPU table.
+ */
+
+ _CPU_Table = *cpu_table;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Get_level
+ *
+ * Input Parameters: NONE
+ *
+ * Output Parameters:
+ * returns the current interrupt level (PIL field of the PSR)
+ */
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ uint32_t level;
+
+ sparc_get_interrupt_level( level );
+
+ return level;
+}
+
+/*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:
+ *
+ * On the SPARC, there are really only 256 vectors. However, the executive
+ * has no easy, fast, reliable way to determine which traps are synchronous
+ * and which are asynchronous. By default, synchronous traps return to the
+ * instruction which caused the interrupt. So if you 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.
+ *
+ * So vectors 0 through 255 are treated as regular asynchronous traps which
+ * provide the "correct" return address. Vectors 256 through 512 are assumed
+ * by the executive to be synchronous and to require that the return address
+ * be fudged.
+ *
+ * If you use this mechanism to install a trap handler which must reexecute
+ * the instruction which caused the trap, then it should be installed as
+ * an asynchronous trap. This will avoid the executive changing the return
+ * address.
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ uint32_t real_vector;
+ CPU_Trap_table_entry *tbr;
+ CPU_Trap_table_entry *slot;
+ uint32_t u32_tbr;
+ uint32_t u32_handler;
+
+ /*
+ * Get the "real" trap number for this vector ignoring the synchronous
+ * versus asynchronous indicator included with our vector numbers.
+ */
+
+ real_vector = SPARC_REAL_TRAP_NUMBER( vector );
+
+ /*
+ * Get the current base address of the trap table and calculate a pointer
+ * to the slot we are interested in.
+ */
+
+ sparc_get_tbr( u32_tbr );
+
+ u32_tbr &= 0xfffff000;
+
+ tbr = (CPU_Trap_table_entry *) u32_tbr;
+
+ slot = &tbr[ 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->mov_psr_l0 == _CPU_Trap_slot_template.mov_psr_l0 ) {
+ u32_handler =
+ ((slot->sethi_of_handler_to_l4 & HIGH_BITS_MASK) << HIGH_BITS_SHIFT) |
+ (slot->jmp_to_low_of_handler_plus_l4 & LOW_BITS_MASK);
+ *old_handler = (proc_ptr) u32_handler;
+ } else
+ *old_handler = 0;
+
+ /*
+ * Copy the template to the slot and then fix it.
+ */
+
+ *slot = _CPU_Trap_slot_template;
+
+ u32_handler = (uint32_t ) new_handler;
+
+ slot->mov_vector_l3 |= vector;
+ slot->sethi_of_handler_to_l4 |=
+ (u32_handler & HIGH_BITS_MASK) >> HIGH_BITS_SHIFT;
+ slot->jmp_to_low_of_handler_plus_l4 |= (u32_handler & LOW_BITS_MASK);
+
+ /* need to flush icache after this !!! */
+
+ rtems_cache_invalidate_entire_instruction();
+
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_install_vector
+ *
+ * This kernel routine installs the RTEMS handler for the
+ * specified vector.
+ *
+ * Input parameters:
+ * vector - interrupt vector number
+ * new_handler - replacement ISR for this vector number
+ * old_handler - pointer to former ISR for this vector number
+ *
+ * Output parameters:
+ * *old_handler - former ISR for this vector number
+ *
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ uint32_t real_vector;
+ proc_ptr ignored;
+
+ /*
+ * Get the "real" trap number for this vector ignoring the synchronous
+ * versus asynchronous indicator included with our vector numbers.
+ */
+
+ real_vector = SPARC_REAL_TRAP_NUMBER( vector );
+
+ /*
+ * Return the previous ISR handler.
+ */
+
+ *old_handler = _ISR_Vector_table[ real_vector ];
+
+ /*
+ * Install the wrapper so this ISR can be invoked properly.
+ */
+
+ _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[ real_vector ] = new_handler;
+}
+
+/*PAGE
+ *
+ * _CPU_Context_Initialize
+ *
+ * This kernel routine initializes the basic non-FP context area associated
+ * with each thread.
+ *
+ * Input parameters:
+ * the_context - pointer to the context area
+ * stack_base - address of memory for the SPARC
+ * size - size in bytes of the stack area
+ * new_level - interrupt level for this context area
+ * entry_point - the starting execution point for this this context
+ * is_fp - TRUE if this context is associated with an FP thread
+ *
+ * Output parameters: NONE
+ */
+
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ uint32_t *stack_base,
+ uint32_t size,
+ uint32_t new_level,
+ void *entry_point,
+ boolean is_fp
+)
+{
+ uint32_t stack_high; /* highest "stack aligned" address */
+ uint32_t the_size;
+ uint32_t tmp_psr;
+
+ /*
+ * On CPUs with stacks which grow down (i.e. SPARC), we build the stack
+ * based on the stack_high address.
+ */
+
+ stack_high = ((uint32_t )(stack_base) + size);
+ stack_high &= ~(CPU_STACK_ALIGNMENT - 1);
+
+ the_size = size & ~(CPU_STACK_ALIGNMENT - 1);
+
+ /*
+ * See the README in this directory for a diagram of the stack.
+ */
+
+ the_context->o7 = ((uint32_t ) entry_point) - 8;
+ the_context->o6_sp = stack_high - CPU_MINIMUM_STACK_FRAME_SIZE;
+ the_context->i6_fp = stack_high;
+
+ /*
+ * Build the PSR for the task. Most everything can be 0 and the
+ * CWP is corrected during the context switch.
+ *
+ * The EF bit determines if the floating point unit is available.
+ * The FPU is ONLY enabled if the context is associated with an FP task
+ * and this SPARC model has an FPU.
+ */
+
+ sparc_get_psr( tmp_psr );
+ tmp_psr &= ~SPARC_PSR_PIL_MASK;
+ tmp_psr |= (new_level << 8) & SPARC_PSR_PIL_MASK;
+ tmp_psr &= ~SPARC_PSR_EF_MASK; /* disabled by default */
+
+#if (SPARC_HAS_FPU == 1)
+ /*
+ * If this bit is not set, then a task gets a fault when it accesses
+ * a floating point register. This is a nice way to detect floating
+ * point tasks which are not currently declared as such.
+ */
+
+ if ( is_fp )
+ tmp_psr |= SPARC_PSR_EF_MASK;
+#endif
+ the_context->psr = tmp_psr;
+}
diff --git a/cpukit/score/cpu/sparc/cpu_asm.S b/cpukit/score/cpu/sparc/cpu_asm.S
new file mode 100644
index 0000000000..95d5627be5
--- /dev/null
+++ b/cpukit/score/cpu/sparc/cpu_asm.S
@@ -0,0 +1,806 @@
+/* cpu_asm.s
+ *
+ * This file contains the basic algorithms for all assembly code used
+ * in an specific CPU port of RTEMS. These algorithms must be implemented
+ * in assembly language.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * Ported to ERC32 implementation of the SPARC by On-Line Applications
+ * Research Corporation (OAR) under contract to the European Space
+ * Agency (ESA).
+ *
+ * ERC32 modifications of respective RTEMS file: COPYRIGHT (c) 1995.
+ * European Space Agency.
+ *
+ * $Id$
+ */
+
+#include <rtems/asm.h>
+
+#if (SPARC_HAS_FPU == 1)
+
+/*
+ * void _CPU_Context_save_fp(
+ * void **fp_context_ptr
+ * )
+ *
+ * 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.
+ *
+ * NOTE: See the README in this directory for information on the
+ * management of the "EF" bit in the PSR.
+ */
+
+ .align 4
+ PUBLIC(_CPU_Context_save_fp)
+SYM(_CPU_Context_save_fp):
+ save %sp, -CPU_MINIMUM_STACK_FRAME_SIZE, %sp
+
+ /*
+ * The following enables the floating point unit.
+ */
+
+ mov %psr, %l0
+ sethi %hi(SPARC_PSR_EF_MASK), %l1
+ or %l1, %lo(SPARC_PSR_EF_MASK), %l1
+ or %l0, %l1, %l0
+ mov %l0, %psr ! **** ENABLE FLOAT ACCESS ****
+ nop; nop; nop; ! Need three nops before EF is
+ ld [%i0], %l0 ! active due to pipeline delay!!!
+ std %f0, [%l0 + FO_F1_OFFSET]
+ std %f2, [%l0 + F2_F3_OFFSET]
+ std %f4, [%l0 + F4_F5_OFFSET]
+ std %f6, [%l0 + F6_F7_OFFSET]
+ std %f8, [%l0 + F8_F9_OFFSET]
+ std %f10, [%l0 + F1O_F11_OFFSET]
+ std %f12, [%l0 + F12_F13_OFFSET]
+ std %f14, [%l0 + F14_F15_OFFSET]
+ std %f16, [%l0 + F16_F17_OFFSET]
+ std %f18, [%l0 + F18_F19_OFFSET]
+ std %f20, [%l0 + F2O_F21_OFFSET]
+ std %f22, [%l0 + F22_F23_OFFSET]
+ std %f24, [%l0 + F24_F25_OFFSET]
+ std %f26, [%l0 + F26_F27_OFFSET]
+ std %f28, [%l0 + F28_F29_OFFSET]
+ std %f30, [%l0 + F3O_F31_OFFSET]
+ st %fsr, [%l0 + FSR_OFFSET]
+ ret
+ restore
+
+/*
+ * void _CPU_Context_restore_fp(
+ * void **fp_context_ptr
+ * )
+ *
+ * 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.
+ *
+ * NOTE: See the README in this directory for information on the
+ * management of the "EF" bit in the PSR.
+ */
+
+ .align 4
+ PUBLIC(_CPU_Context_restore_fp)
+SYM(_CPU_Context_restore_fp):
+ save %sp, -CPU_MINIMUM_STACK_FRAME_SIZE , %sp
+
+ /*
+ * The following enables the floating point unit.
+ */
+
+ mov %psr, %l0
+ sethi %hi(SPARC_PSR_EF_MASK), %l1
+ or %l1, %lo(SPARC_PSR_EF_MASK), %l1
+ or %l0, %l1, %l0
+ mov %l0, %psr ! **** ENABLE FLOAT ACCESS ****
+ nop; nop; nop; ! Need three nops before EF is
+ ld [%i0], %l0 ! active due to pipeline delay!!!
+ ldd [%l0 + FO_F1_OFFSET], %f0
+ ldd [%l0 + F2_F3_OFFSET], %f2
+ ldd [%l0 + F4_F5_OFFSET], %f4
+ ldd [%l0 + F6_F7_OFFSET], %f6
+ ldd [%l0 + F8_F9_OFFSET], %f8
+ ldd [%l0 + F1O_F11_OFFSET], %f10
+ ldd [%l0 + F12_F13_OFFSET], %f12
+ ldd [%l0 + F14_F15_OFFSET], %f14
+ ldd [%l0 + F16_F17_OFFSET], %f16
+ ldd [%l0 + F18_F19_OFFSET], %f18
+ ldd [%l0 + F2O_F21_OFFSET], %f20
+ ldd [%l0 + F22_F23_OFFSET], %f22
+ ldd [%l0 + F24_F25_OFFSET], %f24
+ ldd [%l0 + F26_F27_OFFSET], %f26
+ ldd [%l0 + F28_F29_OFFSET], %f28
+ ldd [%l0 + F3O_F31_OFFSET], %f30
+ ld [%l0 + FSR_OFFSET], %fsr
+ ret
+ restore
+
+#endif /* SPARC_HAS_FPU */
+
+/*
+ * void _CPU_Context_switch(
+ * Context_Control *run,
+ * Context_Control *heir
+ * )
+ *
+ * This routine performs a normal non-FP context switch.
+ */
+
+ .align 4
+ PUBLIC(_CPU_Context_switch)
+SYM(_CPU_Context_switch):
+ ! skip g0
+ st %g1, [%o0 + G1_OFFSET] ! save the global registers
+ std %g2, [%o0 + G2_OFFSET]
+ std %g4, [%o0 + G4_OFFSET]
+ std %g6, [%o0 + G6_OFFSET]
+
+ std %l0, [%o0 + L0_OFFSET] ! save the local registers
+ std %l2, [%o0 + L2_OFFSET]
+ std %l4, [%o0 + L4_OFFSET]
+ std %l6, [%o0 + L6_OFFSET]
+
+ std %i0, [%o0 + I0_OFFSET] ! save the input registers
+ std %i2, [%o0 + I2_OFFSET]
+ std %i4, [%o0 + I4_OFFSET]
+ std %i6, [%o0 + I6_FP_OFFSET]
+
+ std %o0, [%o0 + O0_OFFSET] ! save the output registers
+ std %o2, [%o0 + O2_OFFSET]
+ std %o4, [%o0 + O4_OFFSET]
+ std %o6, [%o0 + O6_SP_OFFSET]
+
+ rd %psr, %o2
+ st %o2, [%o0 + PSR_OFFSET] ! save status register
+
+ /*
+ * This is entered from _CPU_Context_restore with:
+ * o1 = context to restore
+ * o2 = psr
+ */
+
+ PUBLIC(_CPU_Context_restore_heir)
+SYM(_CPU_Context_restore_heir):
+ /*
+ * Flush all windows with valid contents except the current one.
+ * In examining the set register windows, one may logically divide
+ * the windows into sets (some of which may be empty) based on their
+ * current status:
+ *
+ * + current (i.e. in use),
+ * + used (i.e. a restore would not trap)
+ * + invalid (i.e. 1 in corresponding bit in WIM)
+ * + unused
+ *
+ * Either the used or unused set of windows may be empty.
+ *
+ * NOTE: We assume only one bit is set in the WIM at a time.
+ *
+ * Given a CWP of 5 and a WIM of 0x1, the registers are divided
+ * into sets as follows:
+ *
+ * + 0 - invalid
+ * + 1-4 - unused
+ * + 5 - current
+ * + 6-7 - used
+ *
+ * In this case, we only would save the used windows -- 6 and 7.
+ *
+ * Traps are disabled for the same logical period as in a
+ * flush all windows trap handler.
+ *
+ * Register Usage while saving the windows:
+ * g1 = current PSR
+ * g2 = current wim
+ * g3 = CWP
+ * g4 = wim scratch
+ * g5 = scratch
+ */
+
+ ld [%o1 + PSR_OFFSET], %g1 ! g1 = saved psr
+
+ and %o2, SPARC_PSR_CWP_MASK, %g3 ! g3 = CWP
+ ! g1 = psr w/o cwp
+ andn %g1, SPARC_PSR_ET_MASK | SPARC_PSR_CWP_MASK, %g1
+ or %g1, %g3, %g1 ! g1 = heirs psr
+ mov %g1, %psr ! restore status register and
+ ! **** DISABLE TRAPS ****
+ mov %wim, %g2 ! g2 = wim
+ mov 1, %g4
+ sll %g4, %g3, %g4 ! g4 = WIM mask for CW invalid
+
+save_frame_loop:
+ sll %g4, 1, %g5 ! rotate the "wim" left 1
+ srl %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g4
+ or %g4, %g5, %g4 ! g4 = wim if we do one restore
+
+ /*
+ * If a restore would not underflow, then continue.
+ */
+
+ andcc %g4, %g2, %g0 ! Any windows to flush?
+ bnz done_flushing ! No, then continue
+ nop
+
+ restore ! back one window
+
+ /*
+ * Now save the window just as if we overflowed to it.
+ */
+
+ std %l0, [%sp + CPU_STACK_FRAME_L0_OFFSET]
+ std %l2, [%sp + CPU_STACK_FRAME_L2_OFFSET]
+ std %l4, [%sp + CPU_STACK_FRAME_L4_OFFSET]
+ std %l6, [%sp + CPU_STACK_FRAME_L6_OFFSET]
+
+ std %i0, [%sp + CPU_STACK_FRAME_I0_OFFSET]
+ std %i2, [%sp + CPU_STACK_FRAME_I2_OFFSET]
+ std %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET]
+ std %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET]
+
+ ba save_frame_loop
+ nop
+
+done_flushing:
+
+ add %g3, 1, %g3 ! calculate desired WIM
+ and %g3, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g3
+ mov 1, %g4
+ sll %g4, %g3, %g4 ! g4 = new WIM
+ mov %g4, %wim
+
+ or %g1, SPARC_PSR_ET_MASK, %g1
+ mov %g1, %psr ! **** ENABLE TRAPS ****
+ ! and restore CWP
+ nop
+ nop
+ nop
+
+ ! skip g0
+ ld [%o1 + G1_OFFSET], %g1 ! restore the global registers
+ ldd [%o1 + G2_OFFSET], %g2
+ ldd [%o1 + G4_OFFSET], %g4
+ ldd [%o1 + G6_OFFSET], %g6
+
+ ldd [%o1 + L0_OFFSET], %l0 ! restore the local registers
+ ldd [%o1 + L2_OFFSET], %l2
+ ldd [%o1 + L4_OFFSET], %l4
+ ldd [%o1 + L6_OFFSET], %l6
+
+ ldd [%o1 + I0_OFFSET], %i0 ! restore the output registers
+ ldd [%o1 + I2_OFFSET], %i2
+ ldd [%o1 + I4_OFFSET], %i4
+ ldd [%o1 + I6_FP_OFFSET], %i6
+
+ ldd [%o1 + O2_OFFSET], %o2 ! restore the output registers
+ ldd [%o1 + O4_OFFSET], %o4
+ ldd [%o1 + O6_SP_OFFSET], %o6
+ ! do o0/o1 last to avoid destroying heir context pointer
+ ldd [%o1 + O0_OFFSET], %o0 ! overwrite heir pointer
+
+ jmp %o7 + 8 ! return
+ nop ! delay slot
+
+/*
+ * void _CPU_Context_restore(
+ * Context_Control *new_context
+ * )
+ *
+ * This routine is generally used only to perform restart self.
+ *
+ * NOTE: It is unnecessary to reload some registers.
+ */
+
+ .align 4
+ PUBLIC(_CPU_Context_restore)
+SYM(_CPU_Context_restore):
+ save %sp, -CPU_MINIMUM_STACK_FRAME_SIZE, %sp
+ rd %psr, %o2
+ ba SYM(_CPU_Context_restore_heir)
+ mov %i0, %o1 ! in the delay slot
+
+/*
+ * void _ISR_Handler()
+ *
+ * This routine provides the RTEMS interrupt management.
+ *
+ * We enter this handler from the 4 instructions in the trap table with
+ * the following registers assumed to be set as shown:
+ *
+ * l0 = PSR
+ * l1 = PC
+ * l2 = nPC
+ * l3 = trap type
+ *
+ * NOTE: By an executive defined convention, trap type is between 0 and 255 if
+ * it is an asynchonous trap and 256 and 511 if it is synchronous.
+ */
+
+ .align 4
+ PUBLIC(_ISR_Handler)
+SYM(_ISR_Handler):
+ /*
+ * Fix the return address for synchronous traps.
+ */
+
+ andcc %l3, SPARC_SYNCHRONOUS_TRAP_BIT_MASK, %g0
+ ! Is this a synchronous trap?
+ be,a win_ovflow ! No, then skip the adjustment
+ nop ! DELAY
+ mov %l1, %l6 ! save trapped pc for debug info
+ mov %l2, %l1 ! do not return to the instruction
+ add %l2, 4, %l2 ! indicated
+
+win_ovflow:
+ /*
+ * Save the globals this block uses.
+ *
+ * These registers are not restored from the locals. Their contents
+ * are saved directly from the locals into the ISF below.
+ */
+
+ mov %g4, %l4 ! save the globals this block uses
+ mov %g5, %l5
+
+ /*
+ * When at a "window overflow" trap, (wim == (1 << cwp)).
+ * If we get here like that, then process a window overflow.
+ */
+
+ rd %wim, %g4
+ srl %g4, %l0, %g5 ! g5 = win >> cwp ; shift count and CWP
+ ! are LS 5 bits ; how convenient :)
+ cmp %g5, 1 ! Is this an invalid window?
+ bne dont_do_the_window ! No, then skip all this stuff
+ ! we are using the delay slot
+
+ /*
+ * The following is same as a 1 position right rotate of WIM
+ */
+
+ srl %g4, 1, %g5 ! g5 = WIM >> 1
+ sll %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS-1 , %g4
+ ! g4 = WIM << (Number Windows - 1)
+ or %g4, %g5, %g4 ! g4 = (WIM >> 1) |
+ ! (WIM << (Number Windows - 1))
+
+ /*
+ * At this point:
+ *
+ * g4 = the new WIM
+ * g5 is free
+ */
+
+ /*
+ * Since we are tinkering with the register windows, we need to
+ * make sure that all the required information is in global registers.
+ */
+
+ save ! Save into the window
+ wr %g4, 0, %wim ! WIM = new WIM
+ nop ! delay slots
+ nop
+ nop
+
+ /*
+ * Now save the window just as if we overflowed to it.
+ */
+
+ std %l0, [%sp + CPU_STACK_FRAME_L0_OFFSET]
+ std %l2, [%sp + CPU_STACK_FRAME_L2_OFFSET]
+ std %l4, [%sp + CPU_STACK_FRAME_L4_OFFSET]
+ std %l6, [%sp + CPU_STACK_FRAME_L6_OFFSET]
+
+ std %i0, [%sp + CPU_STACK_FRAME_I0_OFFSET]
+ std %i2, [%sp + CPU_STACK_FRAME_I2_OFFSET]
+ std %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET]
+ std %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET]
+
+ restore
+ nop
+
+dont_do_the_window:
+ /*
+ * Global registers %g4 and %g5 are saved directly from %l4 and
+ * %l5 directly into the ISF below.
+ */
+
+save_isf:
+
+ /*
+ * Save the state of the interrupted task -- especially the global
+ * registers -- in the Interrupt Stack Frame. Note that the ISF
+ * includes a regular minimum stack frame which will be used if
+ * needed by register window overflow and underflow handlers.
+ *
+ * REGISTERS SAME AS AT _ISR_Handler
+ */
+
+ sub %fp, CONTEXT_CONTROL_INTERRUPT_FRAME_SIZE, %sp
+ ! make space for ISF
+
+ std %l0, [%sp + ISF_PSR_OFFSET] ! save psr, PC
+ st %l2, [%sp + ISF_NPC_OFFSET] ! save nPC
+ st %g1, [%sp + ISF_G1_OFFSET] ! save g1
+ std %g2, [%sp + ISF_G2_OFFSET] ! save g2, g3
+ std %l4, [%sp + ISF_G4_OFFSET] ! save g4, g5 -- see above
+ std %g6, [%sp + ISF_G6_OFFSET] ! save g6, g7
+
+ std %i0, [%sp + ISF_I0_OFFSET] ! save i0, i1
+ std %i2, [%sp + ISF_I2_OFFSET] ! save i2, i3
+ std %i4, [%sp + ISF_I4_OFFSET] ! save i4, i5
+ std %i6, [%sp + ISF_I6_FP_OFFSET] ! save i6/fp, i7
+
+ rd %y, %g1
+ st %g1, [%sp + ISF_Y_OFFSET] ! save y
+ st %l6, [%sp + ISF_TPC_OFFSET] ! save real trapped pc
+
+ mov %sp, %o1 ! 2nd arg to ISR Handler
+
+ /*
+ * Increment ISR nest level and Thread dispatch disable level.
+ *
+ * Register usage for this section:
+ *
+ * l4 = _Thread_Dispatch_disable_level pointer
+ * l5 = _ISR_Nest_level pointer
+ * l6 = _Thread_Dispatch_disable_level value
+ * l7 = _ISR_Nest_level value
+ *
+ * NOTE: It is assumed that l4 - l7 will be preserved until the ISR
+ * nest and thread dispatch disable levels are unnested.
+ */
+
+ sethi %hi(SYM(_Thread_Dispatch_disable_level)), %l4
+ ld [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))], %l6
+ sethi %hi(SYM(_ISR_Nest_level)), %l5
+ ld [%l5 + %lo(SYM(_ISR_Nest_level))], %l7
+
+ add %l6, 1, %l6
+ st %l6, [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))]
+
+ add %l7, 1, %l7
+ st %l7, [%l5 + %lo(SYM(_ISR_Nest_level))]
+
+ /*
+ * If ISR nest level was zero (now 1), then switch stack.
+ */
+
+ mov %sp, %fp
+ subcc %l7, 1, %l7 ! outermost interrupt handler?
+ bnz dont_switch_stacks ! No, then do not switch stacks
+
+ sethi %hi(SYM(_CPU_Interrupt_stack_high)), %g4
+ ld [%g4 + %lo(SYM(_CPU_Interrupt_stack_high))], %sp
+
+dont_switch_stacks:
+ /*
+ * Make sure we have a place on the stack for the window overflow
+ * trap handler to write into. At this point it is safe to
+ * enable traps again.
+ */
+
+ sub %sp, CPU_MINIMUM_STACK_FRAME_SIZE, %sp
+
+ /*
+ * Check if we have an external interrupt (trap 0x11 - 0x1f). If so,
+ * set the PIL in the %psr to mask off interrupts with lower priority.
+ * The original %psr in %l0 is not modified since it will be restored
+ * when the interrupt handler returns.
+ */
+
+ mov %l0, %g5
+ and %l3, 0x0ff, %g4
+
+/* This is a fix for ERC32 with FPU rev.B or rev.C */
+
+#if defined(FPU_REVB)
+
+
+ subcc %g4, 0x08, %g0
+ be fpu_revb
+ subcc %g4, 0x11, %g0
+ bl dont_fix_pil
+ subcc %g4, 0x1f, %g0
+ bg dont_fix_pil
+ sll %g4, 8, %g4
+ and %g4, SPARC_PSR_PIL_MASK, %g4
+ andn %l0, SPARC_PSR_PIL_MASK, %g5
+ or %g4, %g5, %g5
+ srl %l0, 12, %g4
+ andcc %g4, 1, %g0
+ be dont_fix_pil
+ nop
+ ba,a enable_irq
+
+
+fpu_revb:
+ srl %l0, 12, %g4 ! check if EF is set in %psr
+ andcc %g4, 1, %g0
+ be dont_fix_pil ! if FPU disabled than continue as normal
+ and %l3, 0xff, %g4
+ subcc %g4, 0x08, %g0
+ bne enable_irq ! if not a FPU exception then do two fmovs
+ set __sparc_fq, %g4
+ st %fsr, [%g4] ! if FQ is not empty and FQ[1] = fmovs
+ ld [%g4], %g4 ! than this is bug 3.14
+ srl %g4, 13, %g4
+ andcc %g4, 1, %g0
+ be dont_fix_pil
+ set __sparc_fq, %g4
+ std %fq, [%g4]
+ ld [%g4+4], %g4
+ set 0x81a00020, %g5
+ subcc %g4, %g5, %g0
+ bne,a dont_fix_pil2
+ wr %l0, SPARC_PSR_ET_MASK, %psr ! **** ENABLE TRAPS ****
+ ba,a simple_return
+
+enable_irq:
+ or %g5, SPARC_PSR_PIL_MASK, %g4
+ wr %g4, SPARC_PSR_ET_MASK, %psr ! **** ENABLE TRAPS ****
+ nop; nop; nop
+ fmovs %f0, %f0
+ ba dont_fix_pil
+ fmovs %f0, %f0
+
+ .data
+ .global __sparc_fq
+ .align 8
+__sparc_fq:
+ .word 0,0
+
+ .text
+/* end of ERC32 FPU rev.B/C fix */
+
+#else
+
+ subcc %g4, 0x11, %g0
+ bl dont_fix_pil
+ subcc %g4, 0x1f, %g0
+ bg dont_fix_pil
+ sll %g4, 8, %g4
+ and %g4, SPARC_PSR_PIL_MASK, %g4
+ andn %l0, SPARC_PSR_PIL_MASK, %g5
+ or %g4, %g5, %g5
+#endif
+
+dont_fix_pil:
+ wr %g5, SPARC_PSR_ET_MASK, %psr ! **** ENABLE TRAPS ****
+dont_fix_pil2:
+
+ /*
+ * Vector to user's handler.
+ *
+ * NOTE: TBR may no longer have vector number in it since
+ * we just enabled traps. It is definitely in l3.
+ */
+
+ sethi %hi(SYM(_ISR_Vector_table)), %g4
+ ld [%g4+%lo(SYM(_ISR_Vector_table))], %g4
+ and %l3, 0xFF, %g5 ! remove synchronous trap indicator
+ sll %g5, 2, %g5 ! g5 = offset into table
+ ld [%g4 + %g5], %g4 ! g4 = _ISR_Vector_table[ vector ]
+
+
+ ! o1 = 2nd arg = address of the ISF
+ ! WAS LOADED WHEN ISF WAS SAVED!!!
+ mov %l3, %o0 ! o0 = 1st arg = vector number
+ call %g4, 0
+ nop ! delay slot
+
+ /*
+ * Redisable traps so we can finish up the interrupt processing.
+ * This is a VERY conservative place to do this.
+ *
+ * NOTE: %l0 has the PSR which was in place when we took the trap.
+ */
+
+ mov %l0, %psr ! **** DISABLE TRAPS ****
+
+ /*
+ * Decrement ISR nest level and Thread dispatch disable level.
+ *
+ * Register usage for this section:
+ *
+ * l4 = _Thread_Dispatch_disable_level pointer
+ * l5 = _ISR_Nest_level pointer
+ * l6 = _Thread_Dispatch_disable_level value
+ * l7 = _ISR_Nest_level value
+ */
+
+ sub %l6, 1, %l6
+ st %l6, [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))]
+
+ st %l7, [%l5 + %lo(SYM(_ISR_Nest_level))]
+
+ /*
+ * If dispatching is disabled (includes nested interrupt case),
+ * then do a "simple" exit.
+ */
+
+ orcc %l6, %g0, %g0 ! Is dispatching disabled?
+ bnz simple_return ! Yes, then do a "simple" exit
+ nop ! delay slot
+
+ /*
+ * If a context switch is necessary, then do fudge stack to
+ * return to the interrupt dispatcher.
+ */
+
+ sethi %hi(SYM(_Context_Switch_necessary)), %l4
+ ld [%l4 + %lo(SYM(_Context_Switch_necessary))], %l5
+
+ orcc %l5, %g0, %g0 ! Is thread switch necessary?
+ bnz SYM(_ISR_Dispatch) ! yes, then invoke the dispatcher
+ nop ! delay slot
+
+ /*
+ * Finally, check to see if signals were sent to the currently
+ * executing task. If so, we need to invoke the interrupt dispatcher.
+ */
+
+ sethi %hi(SYM(_ISR_Signals_to_thread_executing)), %l6
+ ld [%l6 + %lo(SYM(_ISR_Signals_to_thread_executing))], %l7
+
+ orcc %l7, %g0, %g0 ! Were signals sent to the currently
+ ! executing thread?
+ bz simple_return ! yes, then invoke the dispatcher
+ ! use the delay slot to clear the signals
+ ! to the currently executing task flag
+ st %g0, [%l6 + %lo(SYM(_ISR_Signals_to_thread_executing))]
+
+
+ /*
+ * Invoke interrupt dispatcher.
+ */
+
+ PUBLIC(_ISR_Dispatch)
+SYM(_ISR_Dispatch):
+
+ /*
+ * The following subtract should get us back on the interrupted
+ * tasks stack and add enough room to invoke the dispatcher.
+ * When we enable traps, we are mostly back in the context
+ * of the task and subsequent interrupts can operate normally.
+ */
+
+ sub %fp, CPU_MINIMUM_STACK_FRAME_SIZE, %sp
+
+ or %l0, SPARC_PSR_ET_MASK, %l7 ! l7 = PSR with ET=1
+ mov %l7, %psr ! **** ENABLE TRAPS ****
+ nop
+ nop
+ nop
+
+ call SYM(_Thread_Dispatch), 0
+ nop
+
+ /*
+ * We invoked _Thread_Dispatch in a state similar to the interrupted
+ * task. In order to safely be able to tinker with the register
+ * windows and get the task back to its pre-interrupt state,
+ * we need to disable interrupts disabled so we can safely tinker
+ * with the register windowing. In particular, the CWP in the PSR
+ * is fragile during this period. (See PR578.)
+ */
+ mov 2,%g1 ! syscall (disable interrupts)
+ ta 0 ! syscall (disable interrupts)
+
+ /*
+ * The CWP in place at this point may be different from
+ * that which was in effect at the beginning of the ISR if we
+ * have been context switched between the beginning of this invocation
+ * of _ISR_Handler and this point. Thus the CWP and WIM should
+ * not be changed back to their values at ISR entry time. Any
+ * changes to the PSR must preserve the CWP.
+ */
+
+simple_return:
+ ld [%fp + ISF_Y_OFFSET], %l5 ! restore y
+ wr %l5, 0, %y
+
+ ldd [%fp + ISF_PSR_OFFSET], %l0 ! restore psr, PC
+ ld [%fp + ISF_NPC_OFFSET], %l2 ! restore nPC
+ rd %psr, %l3
+ and %l3, SPARC_PSR_CWP_MASK, %l3 ! want "current" CWP
+ andn %l0, SPARC_PSR_CWP_MASK, %l0 ! want rest from task
+ or %l3, %l0, %l0 ! install it later...
+ andn %l0, SPARC_PSR_ET_MASK, %l0
+
+ /*
+ * Restore tasks global and out registers
+ */
+
+ mov %fp, %g1
+
+ ! g1 is restored later
+ ldd [%fp + ISF_G2_OFFSET], %g2 ! restore g2, g3
+ ldd [%fp + ISF_G4_OFFSET], %g4 ! restore g4, g5
+ ldd [%fp + ISF_G6_OFFSET], %g6 ! restore g6, g7
+
+ ldd [%fp + ISF_I0_OFFSET], %i0 ! restore i0, i1
+ ldd [%fp + ISF_I2_OFFSET], %i2 ! restore i2, i3
+ ldd [%fp + ISF_I4_OFFSET], %i4 ! restore i4, i5
+ ldd [%fp + ISF_I6_FP_OFFSET], %i6 ! restore i6/fp, i7
+
+ /*
+ * Registers:
+ *
+ * ALL global registers EXCEPT G1 and the input registers have
+ * already been restored and thuse off limits.
+ *
+ * The following is the contents of the local registers:
+ *
+ * l0 = original psr
+ * l1 = return address (i.e. PC)
+ * l2 = nPC
+ * l3 = CWP
+ */
+
+ /*
+ * if (CWP + 1) is an invalid window then we need to reload it.
+ *
+ * WARNING: Traps should now be disabled
+ */
+
+ mov %l0, %psr ! **** DISABLE TRAPS ****
+ nop
+ nop
+ nop
+ rd %wim, %l4
+ add %l0, 1, %l6 ! l6 = cwp + 1
+ and %l6, SPARC_PSR_CWP_MASK, %l6 ! do the modulo on it
+ srl %l4, %l6, %l5 ! l5 = win >> cwp + 1 ; shift count
+ ! and CWP are conveniently LS 5 bits
+ cmp %l5, 1 ! Is tasks window invalid?
+ bne good_task_window
+
+ /*
+ * The following code is the same as a 1 position left rotate of WIM.
+ */
+
+ sll %l4, 1, %l5 ! l5 = WIM << 1
+ srl %l4, SPARC_NUMBER_OF_REGISTER_WINDOWS-1 , %l4
+ ! l4 = WIM >> (Number Windows - 1)
+ or %l4, %l5, %l4 ! l4 = (WIM << 1) |
+ ! (WIM >> (Number Windows - 1))
+
+ /*
+ * Now restore the window just as if we underflowed to it.
+ */
+
+ wr %l4, 0, %wim ! WIM = new WIM
+ nop ! must delay after writing WIM
+ nop
+ nop
+ restore ! now into the tasks window
+
+ ldd [%g1 + CPU_STACK_FRAME_L0_OFFSET], %l0
+ ldd [%g1 + CPU_STACK_FRAME_L2_OFFSET], %l2
+ ldd [%g1 + CPU_STACK_FRAME_L4_OFFSET], %l4
+ ldd [%g1 + CPU_STACK_FRAME_L6_OFFSET], %l6
+ ldd [%g1 + CPU_STACK_FRAME_I0_OFFSET], %i0
+ ldd [%g1 + CPU_STACK_FRAME_I2_OFFSET], %i2
+ ldd [%g1 + CPU_STACK_FRAME_I4_OFFSET], %i4
+ ldd [%g1 + CPU_STACK_FRAME_I6_FP_OFFSET], %i6
+ ! reload of sp clobbers ISF
+ save ! Back to ISR dispatch window
+
+good_task_window:
+
+ mov %l0, %psr ! **** DISABLE TRAPS ****
+ ! and restore condition codes.
+ ld [%g1 + ISF_G1_OFFSET], %g1 ! restore g1
+ jmp %l1 ! transfer control and
+ rett %l2 ! go back to tasks window
+
+/* end of file */
diff --git a/cpukit/score/cpu/sparc/preinstall.am b/cpukit/score/cpu/sparc/preinstall.am
new file mode 100644
index 0000000000..52c11434de
--- /dev/null
+++ b/cpukit/score/cpu/sparc/preinstall.am
@@ -0,0 +1,41 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/sparc.h: rtems/score/sparc.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/sparc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/sparc.h
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
diff --git a/cpukit/score/cpu/sparc/rtems/asm.h b/cpukit/score/cpu/sparc/rtems/asm.h
new file mode 100644
index 0000000000..dafc584a64
--- /dev/null
+++ b/cpukit/score/cpu/sparc/rtems/asm.h
@@ -0,0 +1,119 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ */
+
+/*
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/cpu.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+/* XXX __USER_LABEL_PREFIX__ and __REGISTER_PREFIX__ do not work on gcc 2.7.0 */
+/* XXX The following ifdef magic fixes the problem but results in a warning */
+/* XXX when compiling assembly code. */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/*
+ * define macros for all of the registers on this CPU
+ *
+ * EXAMPLE: #define d0 REG (d0)
+ */
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA
+#define END_DATA
+#define BEGIN_BSS
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .globl SYM (sym)
+#define EXTERN(sym) .globl SYM (sym)
+
+/*
+ * Entry for traps which jump to a programmer-specified trap handler.
+ */
+
+#define TRAP(_vector, _handler) \
+ mov %psr, %l0 ; \
+ sethi %hi(_handler), %l4 ; \
+ jmp %l4+%lo(_handler); \
+ mov _vector, %l3
+
+/*
+ * Used for the reset trap to avoid a supervisor instruction
+ */
+
+#define RTRAP(_vector, _handler) \
+ mov %g0, %l0 ; \
+ sethi %hi(_handler), %l4 ; \
+ jmp %l4+%lo(_handler); \
+ mov _vector, %l3
+
+#endif
diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h
new file mode 100644
index 0000000000..27ea69f0b1
--- /dev/null
+++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
@@ -0,0 +1,1003 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * This include file contains information pertaining to the port of
+ * the executive to the SPARC processor.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/sparc.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+
+/* conditional compilation parameters */
+
+/*
+ * Should the calls to _Thread_Enable_dispatch be inlined?
+ *
+ * If TRUE, then they are inlined.
+ * If FALSE, then a subroutine call is made.
+ */
+
+#define CPU_INLINE_ENABLE_DISPATCH TRUE
+
+/*
+ * Should the body of the search loops in _Thread_queue_Enqueue_priority
+ * be unrolled one time? In unrolled each iteration of the loop examines
+ * two "nodes" on the chain being searched. Otherwise, only one node
+ * is examined per iteration.
+ *
+ * If TRUE, then the loops are unrolled.
+ * If FALSE, then the loops are not unrolled.
+ *
+ * This parameter could go either way on the SPARC. The interrupt flash
+ * code is relatively lengthy given the requirements for nops following
+ * writes to the psr. But if the clock speed were high enough, this would
+ * not represent a great deal of time.
+ */
+
+#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
+
+/*
+ * Does the executive manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in _ISR_Handler_initialization.
+ * If FALSE, nothing is done.
+ *
+ * The SPARC does not have a dedicated HW interrupt stack and one has
+ * been implemented in SW.
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
+
+/*
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * If TRUE, then it must be installed during initialization.
+ * If FALSE, then no installation is performed.
+ *
+ * The SPARC does not have a dedicated HW interrupt stack.
+ */
+
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
+
+/*
+ * Do we allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * If TRUE, then the memory is allocated during initialization.
+ * If FALSE, then the memory is allocated during initialization.
+ */
+
+#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
+
+/*
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ */
+
+#define CPU_ISR_PASSES_FRAME_POINTER 0
+
+/*
+ * Does the CPU have hardware floating point?
+ *
+ * If TRUE, then the FLOATING_POINT task attribute is supported.
+ * If FALSE, then the FLOATING_POINT task attribute is ignored.
+ */
+
+#if ( SPARC_HAS_FPU == 1 )
+#define CPU_HARDWARE_FP TRUE
+#else
+#define CPU_HARDWARE_FP FALSE
+#endif
+#define CPU_SOFTWARE_FP FALSE
+
+/*
+ * Are all tasks FLOATING_POINT tasks implicitly?
+ *
+ * If TRUE, then the FLOATING_POINT task attribute is assumed.
+ * If FALSE, then the FLOATING_POINT task attribute is followed.
+ */
+
+#define CPU_ALL_TASKS_ARE_FP FALSE
+
+/*
+ * Should the IDLE task have a floating point context?
+ *
+ * If TRUE, then the IDLE task is created as a FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * If FALSE, then the IDLE task does not have a floating point context.
+ */
+
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+/*
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ */
+
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+/*
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine _CPU_Thread_Idle_body
+ * must be provided and is the default IDLE thread body instead of
+ * _CPU_Thread_Idle_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ */
+
+#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
+
+/*
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * If TRUE, then the grows upward.
+ * If FALSE, then the grows toward smaller addresses.
+ *
+ * The stack grows to lower addresses on the SPARC.
+ */
+
+#define CPU_STACK_GROWS_UP FALSE
+
+/*
+ * The following is the variable attribute used to force alignment
+ * of critical data structures. On some processors it may make
+ * sense to have these aligned on tighter boundaries than
+ * the minimum requirements of the compiler in order to have as
+ * much of the critical data area as possible in a cache line.
+ *
+ * The SPARC does not appear to have particularly strict alignment
+ * requirements. This value was chosen to take advantages of caches.
+ */
+
+#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned (16)))
+
+/*
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ */
+
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+#define CPU_BIG_ENDIAN TRUE
+#define CPU_LITTLE_ENDIAN FALSE
+
+/*
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
+ *
+ * The SPARC has 16 interrupt levels in the PIL field of the PSR.
+ */
+
+#define CPU_MODES_INTERRUPT_MASK 0x0000000F
+
+/*
+ * This structure represents the organization of the minimum stack frame
+ * for the SPARC. More framing information is required in certain situaions
+ * such as when there are a large number of out parameters or when the callee
+ * must save floating point registers.
+ */
+
+#ifndef ASM
+
+typedef struct {
+ uint32_t l0;
+ uint32_t l1;
+ uint32_t l2;
+ uint32_t l3;
+ uint32_t l4;
+ uint32_t l5;
+ uint32_t l6;
+ uint32_t l7;
+ uint32_t i0;
+ uint32_t i1;
+ uint32_t i2;
+ uint32_t i3;
+ uint32_t i4;
+ uint32_t i5;
+ uint32_t i6_fp;
+ uint32_t i7;
+ void *structure_return_address;
+ /*
+ * The following are for the callee to save the register arguments in
+ * should this be necessary.
+ */
+ uint32_t saved_arg0;
+ uint32_t saved_arg1;
+ uint32_t saved_arg2;
+ uint32_t saved_arg3;
+ uint32_t saved_arg4;
+ uint32_t saved_arg5;
+ uint32_t pad0;
+} CPU_Minimum_stack_frame;
+
+#endif /* ASM */
+
+#define CPU_STACK_FRAME_L0_OFFSET 0x00
+#define CPU_STACK_FRAME_L1_OFFSET 0x04
+#define CPU_STACK_FRAME_L2_OFFSET 0x08
+#define CPU_STACK_FRAME_L3_OFFSET 0x0c
+#define CPU_STACK_FRAME_L4_OFFSET 0x10
+#define CPU_STACK_FRAME_L5_OFFSET 0x14
+#define CPU_STACK_FRAME_L6_OFFSET 0x18
+#define CPU_STACK_FRAME_L7_OFFSET 0x1c
+#define CPU_STACK_FRAME_I0_OFFSET 0x20
+#define CPU_STACK_FRAME_I1_OFFSET 0x24
+#define CPU_STACK_FRAME_I2_OFFSET 0x28
+#define CPU_STACK_FRAME_I3_OFFSET 0x2c
+#define CPU_STACK_FRAME_I4_OFFSET 0x30
+#define CPU_STACK_FRAME_I5_OFFSET 0x34
+#define CPU_STACK_FRAME_I6_FP_OFFSET 0x38
+#define CPU_STACK_FRAME_I7_OFFSET 0x3c
+#define CPU_STRUCTURE_RETURN_ADDRESS_OFFSET 0x40
+#define CPU_STACK_FRAME_SAVED_ARG0_OFFSET 0x44
+#define CPU_STACK_FRAME_SAVED_ARG1_OFFSET 0x48
+#define CPU_STACK_FRAME_SAVED_ARG2_OFFSET 0x4c
+#define CPU_STACK_FRAME_SAVED_ARG3_OFFSET 0x50
+#define CPU_STACK_FRAME_SAVED_ARG4_OFFSET 0x54
+#define CPU_STACK_FRAME_SAVED_ARG5_OFFSET 0x58
+#define CPU_STACK_FRAME_PAD0_OFFSET 0x5c
+
+#define CPU_MINIMUM_STACK_FRAME_SIZE 0x60
+
+/*
+ * Contexts
+ *
+ * Generally there are 2 types of context to save.
+ * 1. Interrupt registers to save
+ * 2. Task level registers to save
+ *
+ * This means we have the following 3 context items:
+ * 1. task level context stuff:: Context_Control
+ * 2. floating point task stuff:: Context_Control_fp
+ * 3. special interrupt level context :: Context_Control_interrupt
+ *
+ * On the SPARC, we are relatively conservative in that we save most
+ * of the CPU state in the context area. The ET (enable trap) bit and
+ * the CWP (current window pointer) fields of the PSR are considered
+ * system wide resources and are not maintained on a per-thread basis.
+ */
+
+#ifndef ASM
+
+typedef struct {
+ /*
+ * Using a double g0_g1 will put everything in this structure on a
+ * double word boundary which allows us to use double word loads
+ * and stores safely in the context switch.
+ */
+ double g0_g1;
+ uint32_t g2;
+ uint32_t g3;
+ uint32_t g4;
+ uint32_t g5;
+ uint32_t g6;
+ uint32_t g7;
+
+ uint32_t l0;
+ uint32_t l1;
+ uint32_t l2;
+ uint32_t l3;
+ uint32_t l4;
+ uint32_t l5;
+ uint32_t l6;
+ uint32_t l7;
+
+ uint32_t i0;
+ uint32_t i1;
+ uint32_t i2;
+ uint32_t i3;
+ uint32_t i4;
+ uint32_t i5;
+ uint32_t i6_fp;
+ uint32_t i7;
+
+ uint32_t o0;
+ uint32_t o1;
+ uint32_t o2;
+ uint32_t o3;
+ uint32_t o4;
+ uint32_t o5;
+ uint32_t o6_sp;
+ uint32_t o7;
+
+ uint32_t psr;
+} Context_Control;
+
+#endif /* ASM */
+
+/*
+ * Offsets of fields with Context_Control for assembly routines.
+ */
+
+#define G0_OFFSET 0x00
+#define G1_OFFSET 0x04
+#define G2_OFFSET 0x08
+#define G3_OFFSET 0x0C
+#define G4_OFFSET 0x10
+#define G5_OFFSET 0x14
+#define G6_OFFSET 0x18
+#define G7_OFFSET 0x1C
+
+#define L0_OFFSET 0x20
+#define L1_OFFSET 0x24
+#define L2_OFFSET 0x28
+#define L3_OFFSET 0x2C
+#define L4_OFFSET 0x30
+#define L5_OFFSET 0x34
+#define L6_OFFSET 0x38
+#define L7_OFFSET 0x3C
+
+#define I0_OFFSET 0x40
+#define I1_OFFSET 0x44
+#define I2_OFFSET 0x48
+#define I3_OFFSET 0x4C
+#define I4_OFFSET 0x50
+#define I5_OFFSET 0x54
+#define I6_FP_OFFSET 0x58
+#define I7_OFFSET 0x5C
+
+#define O0_OFFSET 0x60
+#define O1_OFFSET 0x64
+#define O2_OFFSET 0x68
+#define O3_OFFSET 0x6C
+#define O4_OFFSET 0x70
+#define O5_OFFSET 0x74
+#define O6_SP_OFFSET 0x78
+#define O7_OFFSET 0x7C
+
+#define PSR_OFFSET 0x80
+
+#define CONTEXT_CONTROL_SIZE 0x84
+
+/*
+ * The floating point context area.
+ */
+
+#ifndef ASM
+
+typedef struct {
+ double f0_f1;
+ double f2_f3;
+ double f4_f5;
+ double f6_f7;
+ double f8_f9;
+ double f10_f11;
+ double f12_f13;
+ double f14_f15;
+ double f16_f17;
+ double f18_f19;
+ double f20_f21;
+ double f22_f23;
+ double f24_f25;
+ double f26_f27;
+ double f28_f29;
+ double f30_f31;
+ uint32_t fsr;
+} Context_Control_fp;
+
+#endif /* ASM */
+
+/*
+ * Offsets of fields with Context_Control_fp for assembly routines.
+ */
+
+#define FO_F1_OFFSET 0x00
+#define F2_F3_OFFSET 0x08
+#define F4_F5_OFFSET 0x10
+#define F6_F7_OFFSET 0x18
+#define F8_F9_OFFSET 0x20
+#define F1O_F11_OFFSET 0x28
+#define F12_F13_OFFSET 0x30
+#define F14_F15_OFFSET 0x38
+#define F16_F17_OFFSET 0x40
+#define F18_F19_OFFSET 0x48
+#define F2O_F21_OFFSET 0x50
+#define F22_F23_OFFSET 0x58
+#define F24_F25_OFFSET 0x60
+#define F26_F27_OFFSET 0x68
+#define F28_F29_OFFSET 0x70
+#define F3O_F31_OFFSET 0x78
+#define FSR_OFFSET 0x80
+
+#define CONTEXT_CONTROL_FP_SIZE 0x84
+
+#ifndef ASM
+
+/*
+ * Context saved on stack for an interrupt.
+ *
+ * NOTE: The PSR, PC, and NPC are only saved in this structure for the
+ * benefit of the user's handler.
+ */
+
+typedef struct {
+ CPU_Minimum_stack_frame Stack_frame;
+ uint32_t psr;
+ uint32_t pc;
+ uint32_t npc;
+ uint32_t g1;
+ uint32_t g2;
+ uint32_t g3;
+ uint32_t g4;
+ uint32_t g5;
+ uint32_t g6;
+ uint32_t g7;
+ uint32_t i0;
+ uint32_t i1;
+ uint32_t i2;
+ uint32_t i3;
+ uint32_t i4;
+ uint32_t i5;
+ uint32_t i6_fp;
+ uint32_t i7;
+ uint32_t y;
+ uint32_t tpc;
+} CPU_Interrupt_frame;
+
+#endif /* ASM */
+
+/*
+ * Offsets of fields with CPU_Interrupt_frame for assembly routines.
+ */
+
+#define ISF_STACK_FRAME_OFFSET 0x00
+#define ISF_PSR_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x00
+#define ISF_PC_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x04
+#define ISF_NPC_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x08
+#define ISF_G1_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x0c
+#define ISF_G2_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x10
+#define ISF_G3_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x14
+#define ISF_G4_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x18
+#define ISF_G5_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x1c
+#define ISF_G6_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x20
+#define ISF_G7_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x24
+#define ISF_I0_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x28
+#define ISF_I1_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x2c
+#define ISF_I2_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x30
+#define ISF_I3_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x34
+#define ISF_I4_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x38
+#define ISF_I5_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x3c
+#define ISF_I6_FP_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x40
+#define ISF_I7_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x44
+#define ISF_Y_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x48
+#define ISF_TPC_OFFSET CPU_MINIMUM_STACK_FRAME_SIZE + 0x4c
+
+#define CONTEXT_CONTROL_INTERRUPT_FRAME_SIZE CPU_MINIMUM_STACK_FRAME_SIZE + 0x50
+#ifndef ASM
+
+/*
+ * The following table contains the information required to configure
+ * the processor specific parameters.
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+ /* end of fields required on all CPUs */
+
+} rtems_cpu_table;
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ */
+
+/*
+ * Macros to access SPARC specific additions to the CPU Table
+ */
+
+/* There are no CPU specific additions to the CPU Table for this port. */
+
+/*
+ * This variable is contains the initialize context for the FP unit.
+ * It is filled in by _CPU_Initialize and copied into the task's FP
+ * context area during _CPU_Context_Initialize.
+ */
+
+SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context CPU_STRUCTURE_ALIGNMENT;
+
+/*
+ * This stack is allocated by the Interrupt Manager and the switch
+ * is performed in _ISR_Handler. These variables contain pointers
+ * to the lowest and highest addresses in the chunk of memory allocated
+ * for the interrupt stack. Since it is unknown whether the stack
+ * grows up or down (in general), this give the CPU dependent
+ * code the option of picking the version it wants to use. Thus
+ * both must be present if either is.
+ *
+ * The SPARC supports a software based interrupt stack and these
+ * are required.
+ */
+
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+/*
+ * The following type defines an entry in the SPARC's trap table.
+ *
+ * NOTE: The instructions chosen are RTEMS dependent although one is
+ * obligated to use two of the four instructions to perform a
+ * long jump. The other instructions load one register with the
+ * trap type (a.k.a. vector) and another with the psr.
+ */
+
+typedef struct {
+ uint32_t mov_psr_l0; /* mov %psr, %l0 */
+ uint32_t sethi_of_handler_to_l4; /* sethi %hi(_handler), %l4 */
+ uint32_t jmp_to_low_of_handler_plus_l4; /* jmp %l4 + %lo(_handler) */
+ uint32_t mov_vector_l3; /* mov _vector, %l3 */
+} CPU_Trap_table_entry;
+
+/*
+ * This is the set of opcodes for the instructions loaded into a trap
+ * table entry. The routine which installs a handler is responsible
+ * for filling in the fields for the _handler address and the _vector
+ * trap type.
+ *
+ * The constants following this structure are masks for the fields which
+ * must be filled in when the handler is installed.
+ */
+
+extern const CPU_Trap_table_entry _CPU_Trap_slot_template;
+
+/*
+ * The size of the floating point context area.
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+#endif
+
+/*
+ * Amount of extra stack (above minimum stack size) required by
+ * MPCI receive server thread. Remember that in a multiprocessor
+ * system this thread must exist and be able to process all directives.
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 1024
+
+/*
+ * This defines the number of entries in the ISR_Vector_table managed
+ * by the executive.
+ *
+ * On the SPARC, there are really only 256 vectors. However, the executive
+ * has no easy, fast, reliable way to determine which traps are synchronous
+ * and which are asynchronous. By default, synchronous traps return to the
+ * instruction which caused the interrupt. So if you 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.
+ *
+ * So vectors 0 through 255 are treated as regular asynchronous traps which
+ * provide the "correct" return address. Vectors 256 through 512 are assumed
+ * by the executive to be synchronous and to require that the return address
+ * be fudged.
+ *
+ * If you use this mechanism to install a trap handler which must reexecute
+ * the instruction which caused the trap, then it should be installed as
+ * an asynchronous trap. This will avoid the executive changing the return
+ * address.
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER 511
+
+#define SPARC_SYNCHRONOUS_TRAP_BIT_MASK 0x100
+#define SPARC_ASYNCHRONOUS_TRAP( _trap ) (_trap)
+#define SPARC_SYNCHRONOUS_TRAP( _trap ) ((_trap) + 256 )
+
+#define SPARC_REAL_TRAP_NUMBER( _trap ) ((_trap) % 256)
+
+/*
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level.
+ */
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/*
+ * Should be large enough to run all tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ *
+ * This appears to be a fairly generous number for the SPARC since
+ * represents a call depth of about 20 routines based on the minimum
+ * stack frame.
+ */
+
+#define CPU_STACK_MINIMUM_SIZE (1024*4)
+
+/*
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ *
+ * On the SPARC, this is required for double word loads and stores.
+ */
+
+#define CPU_ALIGNMENT 8
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
+ * then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
+ * enough for the partition, then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * stack. This alignment requirement may be stricter than that for the
+ * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
+ * is strict enough for the stack, then this should be set to 0.
+ *
+ * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
+ *
+ * The alignment restrictions for the SPARC are not that strict but this
+ * should unsure that the stack is always sufficiently alignment that the
+ * window overflow, underflow, and flush routines can use double word loads
+ * and stores.
+ */
+
+#define CPU_STACK_ALIGNMENT 16
+
+#ifndef ASM
+
+extern unsigned int sparc_disable_interrupts();
+extern void sparc_enable_interrupts();
+
+/*
+ * ISR handler macros
+ */
+
+/*
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ */
+
+#define _CPU_Initialize_vectors()
+
+/*
+ * Disable all interrupts for a critical section. The previous
+ * level is returned in _level.
+ */
+
+#define _CPU_ISR_Disable( _level ) \
+ (_level) = sparc_disable_interrupts()
+
+/*
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of a critical section. The parameter
+ * _level is not modified.
+ */
+
+#define _CPU_ISR_Enable( _level ) \
+ sparc_enable_interrupts( _level )
+/*
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ */
+
+#define _CPU_ISR_Flash( _level ) \
+ sparc_flash_interrupts( _level )
+
+/*
+ * Map interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a straight fashion are undefined.
+ */
+
+#define _CPU_ISR_Set_level( _newlevel ) \
+ sparc_enable_interrupts( _newlevel << 8)
+
+uint32_t _CPU_ISR_Get_level( void );
+
+/* end of ISR handler macros */
+
+/* Context handler macros */
+
+/*
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * NOTE: Implemented as a subroutine for the SPARC port.
+ */
+
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ uint32_t *stack_base,
+ uint32_t size,
+ uint32_t new_level,
+ void *entry_point,
+ boolean is_fp
+);
+
+/*
+ * This routine is responsible for somehow restarting the currently
+ * executing task.
+ *
+ * On the SPARC, this is is relatively painless but requires a small
+ * amount of wrapper code before using the regular restore code in
+ * of the context switch.
+ */
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+/*
+ * The FP context area for the SPARC is a simple structure and nothing
+ * special is required to find the "starting load point"
+ */
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
+
+/*
+ * This routine initializes the FP context area passed to it to.
+ *
+ * The SPARC allows us to use the simple initialization model
+ * in which an "initial" FP context was saved into _CPU_Null_fp_context
+ * at CPU initialization and it is simply copied into the destination
+ * context.
+ */
+
+#define _CPU_Context_Initialize_fp( _destination ) \
+ do { \
+ *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
+ } while (0)
+
+/* end of Context handler macros */
+
+/* Fatal Error manager macros */
+
+/*
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ */
+
+#define _CPU_Fatal_halt( _error ) \
+ do { \
+ uint32_t level; \
+ \
+ level = sparc_disable_interrupts(); \
+ asm volatile ( "mov %0, %%g1 " : "=r" (level) : "0" (level) ); \
+ while (1); /* loop forever */ \
+ } while (0)
+
+/* end of Fatal Error manager macros */
+
+/* Bitfield handler macros */
+
+/*
+ * The SPARC port uses the generic C algorithm for bitfield scan if the
+ * CPU model does not have a scan instruction.
+ */
+
+#if ( SPARC_HAS_BITSCAN == 0 )
+#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
+#else
+#error "scan instruction not currently supported by RTEMS!!"
+#endif
+
+/* end of Bitfield handler macros */
+
+/* Priority handler handler macros */
+
+/*
+ * The SPARC port uses the generic C algorithm for bitfield scan if the
+ * CPU model does not have a scan instruction.
+ */
+
+#if ( SPARC_HAS_BITSCAN == 1 )
+#error "scan instruction not currently supported by RTEMS!!"
+#endif
+
+/* end of Priority handler macros */
+
+/* functions */
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/*
+ * _CPU_ISR_install_raw_handler
+ *
+ * This routine installs new_handler to be directly called from the trap
+ * table.
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+#if (CPU_PROVIDES_IDLE_THREAD_BODY == TRUE)
+
+/*
+ * _CPU_Thread_Idle_body
+ *
+ * Some SPARC implementations have low power, sleep, or idle modes. This
+ * tries to take advantage of those models.
+ */
+
+void _CPU_Thread_Idle_body( void );
+
+#endif /* CPU_PROVIDES_IDLE_THREAD_BODY */
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally used only to restart self in an
+ * efficient manner.
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * CPU_swap_u32
+ *
+ * The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * This version will work on any processor, but if you come across a better
+ * way for the SPARC PLEASE use it. The most common way to swap a 32-bit
+ * entity as shown below is not any more efficient on the SPARC.
+ *
+ * swap least significant two bytes with 16-bit rotate
+ * swap upper and lower 16-bits
+ * swap most significant two bytes with 16-bit rotate
+ *
+ * It is not obvious how the SPARC can do significantly better than the
+ * generic code. gcc 2.7.0 only generates about 12 instructions for the
+ * following code at optimization level four (i.e. -O4).
+ */
+
+static inline uint32_t CPU_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t byte1, byte2, byte3, byte4, swapped;
+
+ byte4 = (value >> 24) & 0xff;
+ byte3 = (value >> 16) & 0xff;
+ byte2 = (value >> 8) & 0xff;
+ byte1 = value & 0xff;
+
+ swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
+ return( swapped );
+}
+
+#define CPU_swap_u16( value ) \
+ (((value&0xff) << 8) | ((value >> 8)&0xff))
+
+#endif /* ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/sparc/rtems/score/sparc.h b/cpukit/score/cpu/sparc/rtems/score/sparc.h
new file mode 100644
index 0000000000..2cb9933fb8
--- /dev/null
+++ b/cpukit/score/cpu/sparc/rtems/score/sparc.h
@@ -0,0 +1,268 @@
+/**
+ * @file rtems/score/sparc.h
+ */
+
+/*
+ * This include file contains information pertaining to the SPARC
+ * processor family.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_SPARC_H
+#define _RTEMS_SCORE_SPARC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the "sparc" family. It does
+ * this by setting variables to indicate which implementation
+ * dependent features are present in a particular member
+ * of the family.
+ *
+ * Currently recognized feature flags:
+ *
+ * + SPARC_HAS_FPU
+ * 0 - no HW FPU
+ * 1 - has HW FPU (assumed to be compatible w/90C602)
+ *
+ * + SPARC_HAS_BITSCAN
+ * 0 - does not have scan instructions
+ * 1 - has scan instruction (not currently implemented)
+ *
+ * + SPARC_NUMBER_OF_REGISTER_WINDOWS
+ * 8 is the most common number supported by SPARC implementations.
+ * SPARC_PSR_CWP_MASK is derived from this value.
+ */
+
+/*
+ * Some higher end SPARCs have a bitscan instructions. It would
+ * be nice to take advantage of them. Right now, there is no
+ * port to a CPU model with this feature and no (untested) code
+ * that is based on this feature flag.
+ */
+
+#define SPARC_HAS_BITSCAN 0
+
+/*
+ * This should be OK until a port to a higher end SPARC processor
+ * is made that has more than 8 register windows. If this cannot
+ * be determined based on multilib settings (v7/v8/v9), then the
+ * cpu_asm.S code that depends on this will have to move to libcpu.
+ */
+
+#define SPARC_NUMBER_OF_REGISTER_WINDOWS 8
+
+/*
+ * This should be determined based on some soft float derived
+ * cpp predefine but gcc does not currently give us that information.
+ */
+
+
+#if defined(_SOFT_FLOAT)
+#define SPARC_HAS_FPU 0
+#else
+#define SPARC_HAS_FPU 1
+#endif
+
+#if SPARC_HAS_FPU
+#define CPU_MODEL_NAME "w/FPU"
+#else
+#define CPU_MODEL_NAME "w/soft-float"
+#endif
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "SPARC"
+
+/*
+ * Miscellaneous constants
+ */
+
+/*
+ * PSR masks and starting bit positions
+ *
+ * NOTE: Reserved bits are ignored.
+ */
+
+#if (SPARC_NUMBER_OF_REGISTER_WINDOWS == 8)
+#define SPARC_PSR_CWP_MASK 0x07 /* bits 0 - 4 */
+#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 16)
+#define SPARC_PSR_CWP_MASK 0x0F /* bits 0 - 4 */
+#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 32)
+#define SPARC_PSR_CWP_MASK 0x1F /* bits 0 - 4 */
+#else
+#error "Unsupported number of register windows for this cpu"
+#endif
+
+#define SPARC_PSR_ET_MASK 0x00000020 /* bit 5 */
+#define SPARC_PSR_PS_MASK 0x00000040 /* bit 6 */
+#define SPARC_PSR_S_MASK 0x00000080 /* bit 7 */
+#define SPARC_PSR_PIL_MASK 0x00000F00 /* bits 8 - 11 */
+#define SPARC_PSR_EF_MASK 0x00001000 /* bit 12 */
+#define SPARC_PSR_EC_MASK 0x00002000 /* bit 13 */
+#define SPARC_PSR_ICC_MASK 0x00F00000 /* bits 20 - 23 */
+#define SPARC_PSR_VER_MASK 0x0F000000 /* bits 24 - 27 */
+#define SPARC_PSR_IMPL_MASK 0xF0000000 /* bits 28 - 31 */
+
+#define SPARC_PSR_CWP_BIT_POSITION 0 /* bits 0 - 4 */
+#define SPARC_PSR_ET_BIT_POSITION 5 /* bit 5 */
+#define SPARC_PSR_PS_BIT_POSITION 6 /* bit 6 */
+#define SPARC_PSR_S_BIT_POSITION 7 /* bit 7 */
+#define SPARC_PSR_PIL_BIT_POSITION 8 /* bits 8 - 11 */
+#define SPARC_PSR_EF_BIT_POSITION 12 /* bit 12 */
+#define SPARC_PSR_EC_BIT_POSITION 13 /* bit 13 */
+#define SPARC_PSR_ICC_BIT_POSITION 20 /* bits 20 - 23 */
+#define SPARC_PSR_VER_BIT_POSITION 24 /* bits 24 - 27 */
+#define SPARC_PSR_IMPL_BIT_POSITION 28 /* bits 28 - 31 */
+
+#ifndef ASM
+
+/*
+ * Standard nop
+ */
+
+#define nop() \
+ do { \
+ asm volatile ( "nop" ); \
+ } while ( 0 )
+
+/*
+ * Get and set the PSR
+ */
+
+#define sparc_get_psr( _psr ) \
+ do { \
+ (_psr) = 0; \
+ asm volatile( "rd %%psr, %0" : "=r" (_psr) : "0" (_psr) ); \
+ } while ( 0 )
+
+#define sparc_set_psr( _psr ) \
+ do { \
+ asm volatile ( "mov %0, %%psr " : "=r" ((_psr)) : "0" ((_psr)) ); \
+ nop(); \
+ nop(); \
+ nop(); \
+ } while ( 0 )
+
+/*
+ * Get and set the TBR
+ */
+
+#define sparc_get_tbr( _tbr ) \
+ do { \
+ (_tbr) = 0; /* to avoid unitialized warnings */ \
+ asm volatile( "rd %%tbr, %0" : "=r" (_tbr) : "0" (_tbr) ); \
+ } while ( 0 )
+
+#define sparc_set_tbr( _tbr ) \
+ do { \
+ asm volatile( "wr %0, 0, %%tbr" : "=r" (_tbr) : "0" (_tbr) ); \
+ } while ( 0 )
+
+/*
+ * Get and set the WIM
+ */
+
+#define sparc_get_wim( _wim ) \
+ do { \
+ asm volatile( "rd %%wim, %0" : "=r" (_wim) : "0" (_wim) ); \
+ } while ( 0 )
+
+#define sparc_set_wim( _wim ) \
+ do { \
+ asm volatile( "wr %0, %%wim" : "=r" (_wim) : "0" (_wim) ); \
+ nop(); \
+ nop(); \
+ nop(); \
+ } while ( 0 )
+
+/*
+ * Get and set the Y
+ */
+
+#define sparc_get_y( _y ) \
+ do { \
+ asm volatile( "rd %%y, %0" : "=r" (_y) : "0" (_y) ); \
+ } while ( 0 )
+
+#define sparc_set_y( _y ) \
+ do { \
+ asm volatile( "wr %0, %%y" : "=r" (_y) : "0" (_y) ); \
+ } while ( 0 )
+
+/*
+ * Manipulate the interrupt level in the psr
+ *
+ */
+
+/*
+#define sparc_disable_interrupts( _level ) \
+ do { \
+ register unsigned int _newlevel; \
+ \
+ sparc_get_psr( _level ); \
+ (_newlevel) = (_level) | SPARC_PSR_PIL_MASK; \
+ sparc_set_psr( _newlevel ); \
+ } while ( 0 )
+
+#define sparc_enable_interrupts( _level ) \
+ do { \
+ unsigned int _tmp; \
+ \
+ sparc_get_psr( _tmp ); \
+ _tmp &= ~SPARC_PSR_PIL_MASK; \
+ _tmp |= (_level) & SPARC_PSR_PIL_MASK; \
+ sparc_set_psr( _tmp ); \
+ } while ( 0 )
+*/
+
+#define sparc_flash_interrupts( _level ) \
+ do { \
+ register uint32_t _ignored = 0; \
+ \
+ sparc_enable_interrupts( (_level) ); \
+ sparc_disable_interrupts( _ignored ); \
+ } while ( 0 )
+
+/*
+#define sparc_set_interrupt_level( _new_level ) \
+ do { \
+ register uint32_t _new_psr_level = 0; \
+ \
+ sparc_get_psr( _new_psr_level ); \
+ _new_psr_level &= ~SPARC_PSR_PIL_MASK; \
+ _new_psr_level |= \
+ (((_new_level) << SPARC_PSR_PIL_BIT_POSITION) & SPARC_PSR_PIL_MASK); \
+ sparc_set_psr( _new_psr_level ); \
+ } while ( 0 )
+*/
+
+#define sparc_get_interrupt_level( _level ) \
+ do { \
+ register uint32_t _psr_level = 0; \
+ \
+ sparc_get_psr( _psr_level ); \
+ (_level) = \
+ (_psr_level & SPARC_PSR_PIL_MASK) >> SPARC_PSR_PIL_BIT_POSITION; \
+ } while ( 0 )
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_SPARC_H */
diff --git a/cpukit/score/cpu/sparc/rtems/score/types.h b/cpukit/score/cpu/sparc/rtems/score/types.h
new file mode 100644
index 0000000000..6652791907
--- /dev/null
+++ b/cpukit/score/cpu/sparc/rtems/score/types.h
@@ -0,0 +1,54 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains type definitions pertaining to the
+ * SPARC processor family.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+
+typedef uint16_t Priority_Bit_map_control;
+
+typedef signed long long signed64; /* 64 bit signed integer */
+
+typedef uint32_t boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void sparc_isr;
+typedef void ( *sparc_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/unix/.cvsignore b/cpukit/score/cpu/unix/.cvsignore
new file mode 100644
index 0000000000..6e8f9300d4
--- /dev/null
+++ b/cpukit/score/cpu/unix/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+Makefile.in
+stamp-h.in
diff --git a/cpukit/score/cpu/unix/ChangeLog b/cpukit/score/cpu/unix/ChangeLog
new file mode 100644
index 0000000000..e975f30fa6
--- /dev/null
+++ b/cpukit/score/cpu/unix/ChangeLog
@@ -0,0 +1,348 @@
+2006-01-16 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Part of a large patch to improve Doxygen output.
+ As a side-effect, grammar and spelling errors were corrected, spacing
+ errors were address, and some variable names were improved.
+
+2005-11-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Eliminate unsigned16, unsigned32.
+
+2005-02-19 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Remove traces from NO_CPU.
+
+2005-02-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Split out preinstallation rules.
+ * preinstall.am: New (Split out from Makefile.am).
+
+2005-02-04 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ PR 754/rtems
+ * rtems/asm.h: New (relocated from .).
+ * asm.h: Remove (moved to rtems/asm.h).
+ * Makefile.am: Reflect changes above.
+
+2004-01-28 Ralf Corsepius <ralf.corsepiu@rtems.org>
+
+ * asm.h, rtems/score/cpu.h, rtems/score/types.h, rtems/score/unix.h:
+ New header guards.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Remove signed8, signed16, signed32,
+ unsigned8, unsigned16, unsigned32.
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/cpu.h: *_swap_u32( uint32_t ).
+
+2005-01-24 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: #include <rtems/stdint.h>.
+
+2005-01-07 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Eliminate CFLAGS_OPTIMIZE_V.
+
+2005-01-01 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * Makefile.am: Remove build-variant support.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * rtems/score/types.h: Use __rtems_score_types_h as preprocessor
+ guard.
+
+2004-11-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * asm.h: Add doxygen preamble.
+
+2004-10-02 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Add doxygen preamble.
+ * rtems/score/types.h: Add doxygen preamble.
+ * rtems/score/unix.h: Add doxygen preamble.
+
+2004-09-29 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: i960 obsoleted and all references removed.
+
+2004-04-13 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * asm.h: New (stub file. For consistency with other ports, only).
+ * Makefile.am: Add asm.h.
+
+2004-04-12 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Remove defining _POSIX_C_SOURCE for solaris.
+
+2004-04-09 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * Makefile.am: Remove LIBC_DEFINES (Unsupported).
+
+2004-04-06 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * rtems/score/cpu.h: Remove unixsize.h.
+ * configure.ac: Remove (Merged into $(top_srcdir)/configure.ac).
+ * Makefile.am: Remove unixsize.h.
+ Don't include multilib.am.
+ Reflect merging configure.ac into $(top_srcdir)/configure.ac.
+
+2004-03-30 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * cpu.c, rtems/score/cpu.h: Convert to using c99 fixed size types.
+
+2004-03-29 Ralf Corsepius <ralf_corsepius@rtems.org>
+
+ * configure.ac: RTEMS_TOP([../../../..]).
+
+2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Move RTEMS_TOP one subdir down.
+
+2004-01-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add PREINSTALL_DIRS.
+
+2004-01-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Re-add dirstamps to PREINSTALL_FILES.
+ Add PREINSTALL_FILES to CLEANFILES.
+
+2004-01-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Requires automake >= 1.8.1.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am, again.
+
+2004-01-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Convert to using automake compilation rules.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use mkdir_p. Remove dirs from PREINSTALL_FILES.
+
+2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require automake >= 1.8, autoconf >= 2.59.
+
+2003-12-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Remove TMPINSTALL_FILES.
+
+2003-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add $(dirstamp) to preinstallation rules.
+
+2003-11-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Don't use gmake rules for preinstallation.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CANONICAL_HOST.
+
+2003-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_CHECK_CPU.
+
+2003-09-26 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Obsoleting HP PA-RISC port and removing all
+ references.
+
+2003-09-04 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, rtems/score/cpu.h, rtems/score/types.h, rtems/score/unix.h:
+ URL for license changed.
+
+2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use rtems-bugs@rtems.com as bug report email address.
+
+2003-04-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add PREINSTALL_FILES and TMPINSTALL_FILES to
+ all-local (Sync with other Makefile.ams).
+
+2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove AC_CONFIG_AUX_DIR.
+
+2003-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Per PR315, eliminate warning for structure
+ alignment requests that are too large.
+
+2002-12-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Require autoconf-2.57 + automake-1.7.2.
+ * Makefile.am: Eliminate C_O_FILES, S_O_FILES, libscorecpu_a_OBJECTS.
+
+2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix package name.
+
+2002-11-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Generate unixsize.h on the fly, filter out
+ autoconf-2.53 PACKAGE crap.
+ * rtems/score/.cvsignore: unixsize*
+
+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-07-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Build libscorecpu.a instead of rtems-cpu.rel.
+
+2002-07-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use .$(OBJEXT) instead of .o.
+
+2002-07-05 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: RTEMS_TOP(../../../..).
+
+2002-07-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove RTEMS_PROJECT_ROOT.
+
+2002-06-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Use AC_CONFIG_AUX_DIR(../../../..).
+ Add AC_PROG_RANLIB.
+
+2002-06-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Remove references to RTEMS_BSP.
+
+2002-06-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include $(top_srcdir)/../../../automake/*.am.
+ Use ../../../aclocal.
+
+2001-04-03 Joel Sherrill <joel@OARcorp.com>
+
+ * Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
+ * rtems/score/unixtypes.h: Removed.
+ * rtems/score/types.h: New file via CVS magic.
+ * Makefile.am, rtems/score/cpu.h: Account for name change.
+
+2001-03-28 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c: Define fix_syscall_errno() to nothing so MP links.
+
+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.
+
+2002-02-13 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * configure.ac: Fix the test to determine cpu context size.
+
+2001-02-05 Joel Sherrill <joel@OARcorp.com>
+
+ * .cvsignore: Added stamp-h.in.
+
+2002-01-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Merge in rtems/Makefile.am and
+ rtems/score/Makefile.am. Remove gensize. Require automake-1.5.
+ * rtems/Makefile.am: Removed.
+ * rtems/score/Makefile.am: Removed.
+ * rtems/score/.cvsignore: Add unixsize.h*. Add stamp-h*.
+ * configure.ac: Add AM_CONFIG_HEADER(rtems/score/unixsize.h).
+ * rtems/score/cpu.h: Replace CPU_CONTEXT_SIZE_IN_BYTES with
+ SIZEOF_CPU_CONTEXT.
+
+2001-12-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Add multilib support.
+
+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.
+
+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.
+
+2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * .cvsignore: Add autom4te.cache for autoconf > 2.52.
+ * configure.in: Remove.
+ * configure.ac: New file, generated from configure.in by autoupdate.
+
+2001-09-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/Makefile.am: Use 'PREINSTALL_FILES ='.
+
+2001-05-07 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/cpu.h: Remove #undef __STRICT_ANSI__.
+
+2001-02-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am, rtems/score/Makefile.am:
+ Apply include_*HEADERS instead of H_FILES.
+
+2001-01-25 Joel Sherrill <joel@OARcorp.com>
+
+ * cpu.c, rtems/score/cpu.h: Bug report from Peter Mueller
+ <peter.o.mueller@gmx.de> because of not correcting for the ISR
+ vector table now being allocated from the workspace.
+
+2001-01-03 Joel Sherrill <joel@OARcorp.com>
+
+ * rtems/score/cpu.h: Added _CPU_Initialize_vectors().
+
+2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
+
+2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
+
+2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
+ Switch to GNU canonicalization.
+
+2000-09-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Use += to set up AM_CPPFLAGS.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * rtems/score/Makefile.am: Use PROJECT_TOPdir in path to gensize.
+
+2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * Makefile.am: Include compile.am.
+
+2000-08-10 Joel Sherrill <joel@OARcorp.com>
+
+ * ChangeLog: New file.
diff --git a/cpukit/score/cpu/unix/Makefile.am b/cpukit/score/cpu/unix/Makefile.am
new file mode 100644
index 0000000000..fdf5dbf979
--- /dev/null
+++ b/cpukit/score/cpu/unix/Makefile.am
@@ -0,0 +1,21 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+AM_CPPFLAGS += -DCPU_SYNC_IO
+
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = rtems/asm.h
+
+include_rtems_scoredir = $(includedir)/rtems/score
+include_rtems_score_HEADERS = rtems/score/types.h rtems/score/cpu.h \
+ rtems/score/unix.h
+
+noinst_LIBRARIES = libscorecpu.a
+libscorecpu_a_SOURCES = cpu.c
+libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/unix/cpu.c b/cpukit/score/cpu/unix/cpu.c
new file mode 100644
index 0000000000..c0c700fab6
--- /dev/null
+++ b/cpukit/score/cpu/unix/cpu.c
@@ -0,0 +1,1137 @@
+/*
+ * UNIX Simulator Dependent Source
+ *
+ * COPYRIGHT (c) 1994,95 by Division Incorporated
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/interr.h>
+
+#if defined(__linux__)
+#define _XOPEN_SOURCE
+#define MALLOC_0_RETURNS_NULL
+#endif
+
+#include <sys/types.h>
+#include <sys/times.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <unistd.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/sem.h>
+#endif
+#include <string.h> /* memset */
+
+#ifndef SA_RESTART
+#define SA_RESTART 0
+#endif
+
+typedef struct {
+ jmp_buf regs;
+ int isr_level;
+} Context_Control_overlay;
+
+void _CPU_Signal_initialize(void);
+void _CPU_Stray_signal(int);
+void _CPU_ISR_Handler(int);
+
+static sigset_t _CPU_Signal_mask;
+static Context_Control_overlay _CPU_Context_Default_with_ISRs_enabled;
+static Context_Control_overlay _CPU_Context_Default_with_ISRs_disabled;
+
+/*
+ * Sync IO support, an entry for each fd that can be set
+ */
+
+void _CPU_Sync_io_Init();
+
+static rtems_sync_io_handler _CPU_Sync_io_handlers[FD_SETSIZE];
+static int sync_io_nfds;
+static fd_set sync_io_readfds;
+static fd_set sync_io_writefds;
+static fd_set sync_io_exceptfds;
+
+/*
+ * Which cpu are we? Used by libcpu and libbsp.
+ */
+
+int cpu_number;
+
+/*PAGE
+ *
+ * _CPU_Initialize_vectors()
+ *
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ *
+ * UNIX Specific Information:
+ *
+ * Complete initialization since the table is now allocated.
+ */
+
+sigset_t posix_empty_mask;
+
+void _CPU_Initialize_vectors(void)
+{
+ uint32_t i;
+ proc_ptr old_handler;
+
+ /*
+ * Generate an empty mask to be used by disable_support
+ */
+
+ sigemptyset(&posix_empty_mask);
+
+ /*
+ * Block all the signals except SIGTRAP for the debugger
+ * and fatal error signals.
+ */
+
+ (void) sigfillset(&_CPU_Signal_mask);
+ (void) sigdelset(&_CPU_Signal_mask, SIGTRAP);
+ (void) sigdelset(&_CPU_Signal_mask, SIGABRT);
+#if !defined(__CYGWIN__)
+ (void) sigdelset(&_CPU_Signal_mask, SIGIOT);
+#endif
+ (void) sigdelset(&_CPU_Signal_mask, SIGCONT);
+ (void) sigdelset(&_CPU_Signal_mask, SIGSEGV);
+ (void) sigdelset(&_CPU_Signal_mask, SIGBUS);
+ (void) sigdelset(&_CPU_Signal_mask, SIGFPE);
+
+ _CPU_ISR_Enable(1);
+
+ /*
+ * Set the handler for all signals to be signal_handler
+ * which will then vector out to the correct handler
+ * for whichever signal actually happened. Initially
+ * set the vectors to the stray signal handler.
+ */
+
+ for (i = 0; i < CPU_INTERRUPT_NUMBER_OF_VECTORS; i++)
+ (void)_CPU_ISR_install_vector(i, _CPU_Stray_signal, &old_handler);
+
+ _CPU_Signal_initialize();
+}
+
+void _CPU_Signal_initialize( void )
+{
+ struct sigaction act;
+ sigset_t mask;
+
+ /* mark them all active except for TraceTrap and Abort */
+
+ mask = _CPU_Signal_mask;
+ sigprocmask(SIG_UNBLOCK, &mask, 0);
+
+ act.sa_handler = _CPU_ISR_Handler;
+ act.sa_mask = mask;
+ act.sa_flags = SA_RESTART;
+
+ sigaction(SIGHUP, &act, 0);
+ sigaction(SIGINT, &act, 0);
+ sigaction(SIGQUIT, &act, 0);
+ sigaction(SIGILL, &act, 0);
+#ifdef SIGEMT
+ sigaction(SIGEMT, &act, 0);
+#endif
+ sigaction(SIGFPE, &act, 0);
+ sigaction(SIGKILL, &act, 0);
+ sigaction(SIGBUS, &act, 0);
+ sigaction(SIGSEGV, &act, 0);
+#ifdef SIGSYS
+ sigaction(SIGSYS, &act, 0);
+#endif
+ sigaction(SIGPIPE, &act, 0);
+ sigaction(SIGALRM, &act, 0);
+ sigaction(SIGTERM, &act, 0);
+ sigaction(SIGUSR1, &act, 0);
+ sigaction(SIGUSR2, &act, 0);
+ sigaction(SIGCHLD, &act, 0);
+#ifdef SIGCLD
+ sigaction(SIGCLD, &act, 0);
+#endif
+#ifdef SIGPWR
+ sigaction(SIGPWR, &act, 0);
+#endif
+ sigaction(SIGVTALRM, &act, 0);
+ sigaction(SIGPROF, &act, 0);
+ sigaction(SIGIO, &act, 0);
+ sigaction(SIGWINCH, &act, 0);
+ sigaction(SIGSTOP, &act, 0);
+ sigaction(SIGTTIN, &act, 0);
+ sigaction(SIGTTOU, &act, 0);
+ sigaction(SIGURG, &act, 0);
+#ifdef SIGLOST
+ sigaction(SIGLOST, &act, 0);
+#endif
+}
+
+/*PAGE
+ *
+ * _CPU_Context_From_CPU_Init
+ */
+
+void _CPU_Context_From_CPU_Init()
+{
+
+#if defined(__hppa__) && defined(RTEMS_UNIXLIB_SETJMP)
+ /*
+ * HACK - set the _SYSTEM_ID to 0x20c so that setjmp/longjmp
+ * will handle the full 32 floating point registers.
+ */
+
+ {
+ extern uint32_t _SYSTEM_ID;
+
+ _SYSTEM_ID = 0x20c;
+ }
+#endif
+
+ /*
+ * get default values to use in _CPU_Context_Initialize()
+ */
+
+ if ( sizeof(Context_Control_overlay) > sizeof(Context_Control) )
+ _CPU_Fatal_halt( 0xdeadf00d );
+
+ (void) memset(
+ &_CPU_Context_Default_with_ISRs_enabled,
+ 0,
+ sizeof(Context_Control_overlay)
+ );
+ (void) memset(
+ &_CPU_Context_Default_with_ISRs_disabled,
+ 0,
+ sizeof(Context_Control_overlay)
+ );
+
+ _CPU_ISR_Set_level( 0 );
+ _CPU_Context_switch(
+ (Context_Control *) &_CPU_Context_Default_with_ISRs_enabled,
+ (Context_Control *) &_CPU_Context_Default_with_ISRs_enabled
+ );
+
+ _CPU_ISR_Set_level( 1 );
+ _CPU_Context_switch(
+ (Context_Control *) &_CPU_Context_Default_with_ISRs_disabled,
+ (Context_Control *) &_CPU_Context_Default_with_ISRs_disabled
+ );
+}
+
+/*PAGE
+ *
+ * _CPU_Sync_io_Init
+ */
+
+void _CPU_Sync_io_Init()
+{
+ int fd;
+
+ for (fd = 0; fd < FD_SETSIZE; fd++)
+ _CPU_Sync_io_handlers[fd] = NULL;
+
+ sync_io_nfds = 0;
+ FD_ZERO(&sync_io_readfds);
+ FD_ZERO(&sync_io_writefds);
+ FD_ZERO(&sync_io_exceptfds);
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Get_level
+ */
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ sigset_t old_mask;
+
+ sigemptyset( &old_mask );
+ sigprocmask(SIG_BLOCK, 0, &old_mask);
+
+ if (memcmp((void *)&posix_empty_mask, (void *)&old_mask, sizeof(sigset_t)))
+ return 1;
+
+ return 0;
+}
+
+/* _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 */
+)
+{
+ /*
+ * If something happened where the public Context_Control is not
+ * at least as large as the private Context_Control_overlay, then
+ * we are in trouble.
+ */
+
+ if ( sizeof(Context_Control_overlay) > sizeof(Context_Control) )
+ _CPU_Fatal_error(0x100 + 1);
+
+ /*
+ * The thread_dispatch argument is the address of the entry point
+ * for the routine called at the end of an ISR once it has been
+ * decided a context switch is necessary. On some compilation
+ * systems it is difficult to call a high-level language routine
+ * from assembly. This allows us to trick these systems.
+ *
+ * If you encounter this problem save the entry point in a CPU
+ * dependent variable.
+ */
+
+ _CPU_Thread_dispatch_pointer = thread_dispatch;
+
+ /*
+ * XXX; If there is not an easy way to initialize the FP context
+ * during Context_Initialize, then it is usually easier to
+ * save an "uninitialized" FP context here and copy it to
+ * the task's during Context_Initialize.
+ */
+
+ /* XXX: FP context initialization support */
+
+ _CPU_Table = *cpu_table;
+
+ _CPU_Sync_io_Init();
+
+ _CPU_Context_From_CPU_Init();
+
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_install_raw_handler
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ _CPU_Fatal_halt( 0xdeaddead );
+}
+
+/*PAGE
+ *
+ * _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(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ *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.
+ */
+
+ /*
+ * We put the actual user ISR address in '_ISR_vector_table'. This will
+ * be used by the _CPU_ISR_Handler so the user gets control.
+ */
+
+ _ISR_Vector_table[ vector ] = new_handler;
+}
+
+/*PAGE
+ *
+ * _CPU_Install_interrupt_stack
+ */
+
+void _CPU_Install_interrupt_stack( void )
+{
+}
+
+/*PAGE
+ *
+ * _CPU_Thread_Idle_body
+ *
+ * Stop until we get a signal which is the logically the same thing
+ * entering low-power or sleep mode on a real processor and waiting for
+ * an interrupt. This significantly reduces the consumption of host
+ * CPU cycles which is again similar to low power mode.
+ */
+
+void _CPU_Thread_Idle_body( void )
+{
+#if CPU_SYNC_IO
+ extern void _Thread_Dispatch(void);
+ int fd;
+#endif
+
+ while (1) {
+#ifdef RTEMS_DEBUG
+ /* interrupts had better be enabled at this point! */
+ if (_CPU_ISR_Get_level() != 0)
+ abort();
+#endif
+
+ /*
+ * Block on a select statement, the CPU interface added allow the
+ * user to add new descriptors which are to be blocked on
+ */
+
+#if CPU_SYNC_IO
+ if (sync_io_nfds) {
+ int result;
+ fd_set readfds, writefds, exceptfds;
+
+ readfds = sync_io_readfds;
+ writefds = sync_io_writefds;
+ exceptfds = sync_io_exceptfds;
+ result = select(sync_io_nfds,
+ &readfds,
+ &writefds,
+ &exceptfds,
+ NULL);
+
+ if (result < 0) {
+ if (errno != EINTR)
+ _CPU_Fatal_error(0x200); /* FIXME : what number should go here !! */
+ _Thread_Dispatch();
+ continue;
+ }
+
+ for (fd = 0; fd < sync_io_nfds; fd++) {
+ boolean read = FD_ISSET(fd, &readfds);
+ boolean write = FD_ISSET(fd, &writefds);
+ boolean except = FD_ISSET(fd, &exceptfds);
+
+ if (_CPU_Sync_io_handlers[fd] && (read || write || except))
+ _CPU_Sync_io_handlers[fd](fd, read, write, except);
+ }
+
+ _Thread_Dispatch();
+ } else
+ pause();
+#else
+ pause();
+#endif
+
+ }
+
+}
+
+/*PAGE
+ *
+ * _CPU_Context_Initialize
+ */
+
+void _CPU_Context_Initialize(
+ Context_Control *_the_context,
+ uint32_t *_stack_base,
+ uint32_t _size,
+ uint32_t _new_level,
+ void *_entry_point,
+ boolean _is_fp
+)
+{
+ uint32_t *addr;
+ uint32_t jmp_addr;
+ uint32_t _stack_low; /* lowest "stack aligned" address */
+ uint32_t _stack_high; /* highest "stack aligned" address */
+ uint32_t _the_size;
+
+ jmp_addr = (uint32_t ) _entry_point;
+
+ /*
+ * On CPUs with stacks which grow down, we build the stack
+ * based on the _stack_high address. On CPUs with stacks which
+ * grow up, we build the stack based on the _stack_low address.
+ */
+
+ _stack_low = (uint32_t )(_stack_base) + CPU_STACK_ALIGNMENT - 1;
+ _stack_low &= ~(CPU_STACK_ALIGNMENT - 1);
+
+ _stack_high = (uint32_t )(_stack_base) + _size;
+ _stack_high &= ~(CPU_STACK_ALIGNMENT - 1);
+
+ if (_stack_high > _stack_low)
+ _the_size = _stack_high - _stack_low;
+ else
+ _the_size = _stack_low - _stack_high;
+
+ /*
+ * Slam our jmp_buf template into the context we are creating
+ */
+
+ if ( _new_level == 0 )
+ *(Context_Control_overlay *)_the_context =
+ _CPU_Context_Default_with_ISRs_enabled;
+ else
+ *(Context_Control_overlay *)_the_context =
+ _CPU_Context_Default_with_ISRs_disabled;
+
+ addr = (uint32_t *)_the_context;
+
+#if defined(__hppa__)
+ *(addr + RP_OFF) = jmp_addr;
+ *(addr + SP_OFF) = (uint32_t )(_stack_low + CPU_FRAME_SIZE);
+
+ /*
+ * See if we are using shared libraries by checking
+ * bit 30 in 24 off of newp. If bit 30 is set then
+ * we are using shared libraries and the jump address
+ * points to the pointer, so we put that into rp instead.
+ */
+
+ if (jmp_addr & 0x40000000) {
+ jmp_addr &= 0xfffffffc;
+ *(addr + RP_OFF) = *(uint32_t *)jmp_addr;
+ }
+#elif defined(__sparc__)
+
+ /*
+ * See /usr/include/sys/stack.h in Solaris 2.3 for a nice
+ * diagram of the stack.
+ */
+
+ asm ("ta 0x03"); /* flush registers */
+
+ *(addr + RP_OFF) = jmp_addr + ADDR_ADJ_OFFSET;
+ *(addr + SP_OFF) = (uint32_t )(_stack_high - CPU_FRAME_SIZE);
+ *(addr + FP_OFF) = (uint32_t )(_stack_high);
+
+#elif defined(__i386__)
+
+ /*
+ * This information was gathered by disassembling setjmp().
+ */
+
+ {
+ uint32_t stack_ptr;
+
+ stack_ptr = _stack_high - CPU_FRAME_SIZE;
+
+ *(addr + EBX_OFF) = 0xFEEDFEED;
+ *(addr + ESI_OFF) = 0xDEADDEAD;
+ *(addr + EDI_OFF) = 0xDEAFDEAF;
+ *(addr + EBP_OFF) = stack_ptr;
+ *(addr + ESP_OFF) = stack_ptr;
+ *(addr + RET_OFF) = jmp_addr;
+
+ addr = (uint32_t *) stack_ptr;
+
+ addr[ 0 ] = jmp_addr;
+ addr[ 1 ] = (uint32_t ) stack_ptr;
+ addr[ 2 ] = (uint32_t ) stack_ptr;
+ }
+
+#else
+#error "UNKNOWN CPU!!!"
+#endif
+
+}
+
+/*PAGE
+ *
+ * _CPU_Context_restore
+ */
+
+void _CPU_Context_restore(
+ Context_Control *next
+)
+{
+ Context_Control_overlay *nextp = (Context_Control_overlay *)next;
+
+ _CPU_ISR_Enable(nextp->isr_level);
+ longjmp( nextp->regs, 0 );
+}
+
+/*PAGE
+ *
+ * _CPU_Context_switch
+ */
+
+static void do_jump(
+ Context_Control_overlay *currentp,
+ Context_Control_overlay *nextp
+);
+
+void _CPU_Context_switch(
+ Context_Control *current,
+ Context_Control *next
+)
+{
+ Context_Control_overlay *currentp = (Context_Control_overlay *)current;
+ Context_Control_overlay *nextp = (Context_Control_overlay *)next;
+#if 0
+ int status;
+#endif
+
+ currentp->isr_level = _CPU_ISR_Disable_support();
+
+ do_jump( currentp, nextp );
+
+#if 0
+ if (sigsetjmp(currentp->regs, 1) == 0) { /* Save the current context */
+ siglongjmp(nextp->regs, 0); /* Switch to the new context */
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ status
+ );
+ }
+#endif
+
+#ifdef RTEMS_DEBUG
+ if (_CPU_ISR_Get_level() == 0)
+ abort();
+#endif
+
+ _CPU_ISR_Enable(currentp->isr_level);
+}
+
+static void do_jump(
+ Context_Control_overlay *currentp,
+ Context_Control_overlay *nextp
+)
+{
+ int status;
+
+ if (setjmp(currentp->regs) == 0) { /* Save the current context */
+ longjmp(nextp->regs, 0); /* Switch to the new context */
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ status
+ );
+ }
+}
+
+/*PAGE
+ *
+ * _CPU_Save_float_context
+ */
+
+void _CPU_Save_float_context(
+ Context_Control_fp *fp_context
+)
+{
+}
+
+/*PAGE
+ *
+ * _CPU_Restore_float_context
+ */
+
+void _CPU_Restore_float_context(
+ Context_Control_fp *fp_context
+)
+{
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Disable_support
+ */
+
+uint32_t _CPU_ISR_Disable_support(void)
+{
+ int status;
+ sigset_t old_mask;
+
+ sigemptyset( &old_mask );
+ status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, &old_mask);
+ if ( status )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ status
+ );
+
+ if (memcmp((void *)&posix_empty_mask, (void *)&old_mask, sizeof(sigset_t)))
+ return 1;
+
+ return 0;
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Enable
+ */
+
+void _CPU_ISR_Enable(
+ uint32_t level
+)
+{
+ int status;
+
+ if (level == 0)
+ status = sigprocmask(SIG_UNBLOCK, &_CPU_Signal_mask, 0);
+ else
+ status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, 0);
+
+ if ( status )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ status
+ );
+}
+
+/*PAGE
+ *
+ * _CPU_ISR_Handler
+ *
+ * External interrupt handler.
+ * This is installed as a UNIX signal handler.
+ * It vectors out to specific user interrupt handlers.
+ */
+
+void _CPU_ISR_Handler(int vector)
+{
+ extern void _Thread_Dispatch(void);
+ extern uint32_t _Thread_Dispatch_disable_level;
+ extern boolean _Context_Switch_necessary;
+
+ if (_ISR_Nest_level++ == 0) {
+ /* switch to interrupt stack */
+ }
+
+ _Thread_Dispatch_disable_level++;
+
+ if (_ISR_Vector_table[vector]) {
+ _ISR_Vector_table[vector](vector);
+ } else {
+ _CPU_Stray_signal(vector);
+ }
+
+ if (_ISR_Nest_level-- == 0) {
+ /* switch back to original stack */
+ }
+
+ _Thread_Dispatch_disable_level--;
+
+ if (_Thread_Dispatch_disable_level == 0 &&
+ (_Context_Switch_necessary || _ISR_Signals_to_thread_executing)) {
+ _ISR_Signals_to_thread_executing = FALSE;
+ _CPU_ISR_Enable(0);
+ _Thread_Dispatch();
+ }
+}
+
+/*PAGE
+ *
+ * _CPU_Stray_signal
+ */
+
+void _CPU_Stray_signal(int sig_num)
+{
+ char buffer[ 4 ];
+
+ /*
+ * print "stray" msg about ones which that might mean something
+ * Avoid using the stdio section of the library.
+ * The following is generally safe.
+ */
+
+ switch (sig_num)
+ {
+#ifdef SIGCLD
+ case SIGCLD:
+ break;
+#endif
+ default:
+ {
+ /*
+ * We avoid using the stdio section of the library.
+ * The following is generally safe
+ */
+
+ int digit;
+ int number = sig_num;
+ int len = 0;
+
+ digit = number / 100;
+ number %= 100;
+ if (digit) buffer[len++] = '0' + digit;
+
+ digit = number / 10;
+ number %= 10;
+ if (digit || len) buffer[len++] = '0' + digit;
+
+ digit = number;
+ buffer[len++] = '0' + digit;
+
+ buffer[ len++ ] = '\n';
+
+ write( 2, "Stray signal ", 13 );
+ write( 2, buffer, len );
+
+ }
+ }
+
+ /*
+ * If it was a "fatal" signal, then exit here
+ * If app code has installed a hander for one of these, then
+ * we won't call _CPU_Stray_signal, so this is ok.
+ */
+
+ switch (sig_num) {
+ case SIGINT:
+ case SIGHUP:
+ case SIGQUIT:
+ case SIGILL:
+#ifdef SIGEMT
+ case SIGEMT:
+#endif
+ case SIGKILL:
+ case SIGBUS:
+ case SIGSEGV:
+ case SIGTERM:
+#if !defined(__CYGWIN__)
+ case SIGIOT:
+#endif
+ _CPU_Fatal_error(0x100 + sig_num);
+ }
+}
+
+/*PAGE
+ *
+ * _CPU_Fatal_error
+ */
+
+void _CPU_Fatal_error(uint32_t error)
+{
+ setitimer(ITIMER_REAL, 0, 0);
+
+ if ( error ) {
+#ifdef RTEMS_DEBUG
+ abort();
+#endif
+ if (getenv("RTEMS_DEBUG"))
+ abort();
+ }
+
+ _exit(error);
+}
+
+/*
+ * Special Purpose Routines to hide the use of UNIX system calls.
+ */
+
+int _CPU_Set_sync_io_handler(
+ int fd,
+ boolean read,
+ boolean write,
+ boolean except,
+ rtems_sync_io_handler handler
+)
+{
+ if ((fd < FD_SETSIZE) && (_CPU_Sync_io_handlers[fd] == NULL)) {
+ if (read)
+ FD_SET(fd, &sync_io_readfds);
+ else
+ FD_CLR(fd, &sync_io_readfds);
+ if (write)
+ FD_SET(fd, &sync_io_writefds);
+ else
+ FD_CLR(fd, &sync_io_writefds);
+ if (except)
+ FD_SET(fd, &sync_io_exceptfds);
+ else
+ FD_CLR(fd, &sync_io_exceptfds);
+ _CPU_Sync_io_handlers[fd] = handler;
+ if ((fd + 1) > sync_io_nfds)
+ sync_io_nfds = fd + 1;
+ return 0;
+ }
+ return -1;
+}
+
+int _CPU_Clear_sync_io_handler(
+ int fd
+)
+{
+ if ((fd < FD_SETSIZE) && _CPU_Sync_io_handlers[fd]) {
+ FD_CLR(fd, &sync_io_readfds);
+ FD_CLR(fd, &sync_io_writefds);
+ FD_CLR(fd, &sync_io_exceptfds);
+ _CPU_Sync_io_handlers[fd] = NULL;
+ sync_io_nfds = 0;
+ for (fd = 0; fd < FD_SETSIZE; fd++)
+ if (FD_ISSET(fd, &sync_io_readfds) ||
+ FD_ISSET(fd, &sync_io_writefds) ||
+ FD_ISSET(fd, &sync_io_exceptfds))
+ sync_io_nfds = fd + 1;
+ return 0;
+ }
+ return -1;
+}
+
+int _CPU_Get_clock_vector( void )
+{
+ return SIGALRM;
+}
+
+void _CPU_Start_clock(
+ int microseconds
+)
+{
+ struct itimerval new;
+
+ new.it_value.tv_sec = 0;
+ new.it_value.tv_usec = microseconds;
+ new.it_interval.tv_sec = 0;
+ new.it_interval.tv_usec = microseconds;
+
+ setitimer(ITIMER_REAL, &new, 0);
+}
+
+void _CPU_Stop_clock( void )
+{
+ struct itimerval new;
+ struct sigaction act;
+
+ /*
+ * Set the SIGALRM signal to ignore any last
+ * signals that might come in while we are
+ * disarming the timer and removing the interrupt
+ * vector.
+ */
+
+ (void) memset(&act, 0, sizeof(act));
+ act.sa_handler = SIG_IGN;
+
+ sigaction(SIGALRM, &act, 0);
+
+ (void) memset(&new, 0, sizeof(new));
+ setitimer(ITIMER_REAL, &new, 0);
+}
+
+#if 0
+extern void fix_syscall_errno( void );
+#endif
+#define fix_syscall_errno()
+
+#if defined(RTEMS_MULTIPROCESSING)
+int _CPU_SHM_Semid;
+
+void _CPU_SHM_Init(
+ uint32_t maximum_nodes,
+ boolean is_master_node,
+ void **shm_address,
+ uint32_t *shm_length
+)
+{
+ int i;
+ int shmid;
+ char *shm_addr;
+ key_t shm_key;
+ key_t sem_key;
+ int status = 0; /* to avoid unitialized warnings */
+ int shm_size;
+
+ if (getenv("RTEMS_SHM_KEY"))
+ shm_key = strtol(getenv("RTEMS_SHM_KEY"), 0, 0);
+ else
+#ifdef RTEMS_SHM_KEY
+ shm_key = RTEMS_SHM_KEY;
+#else
+ shm_key = 0xa000;
+#endif
+
+ if (getenv("RTEMS_SHM_SIZE"))
+ shm_size = strtol(getenv("RTEMS_SHM_SIZE"), 0, 0);
+ else
+#ifdef RTEMS_SHM_SIZE
+ shm_size = RTEMS_SHM_SIZE;
+#else
+ shm_size = 64 * 1024;
+#endif
+
+ if (getenv("RTEMS_SHM_SEMAPHORE_KEY"))
+ sem_key = strtol(getenv("RTEMS_SHM_SEMAPHORE_KEY"), 0, 0);
+ else
+#ifdef RTEMS_SHM_SEMAPHORE_KEY
+ sem_key = RTEMS_SHM_SEMAPHORE_KEY;
+#else
+ sem_key = 0xa001;
+#endif
+
+ shmid = shmget(shm_key, shm_size, IPC_CREAT | 0660);
+ if ( shmid == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ perror( "shmget" );
+ _CPU_Fatal_halt( 0xdead0001 );
+ }
+
+ shm_addr = shmat(shmid, (char *)0, SHM_RND);
+ if ( shm_addr == (void *)-1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ perror( "shmat" );
+ _CPU_Fatal_halt( 0xdead0002 );
+ }
+
+ _CPU_SHM_Semid = semget(sem_key, maximum_nodes + 1, IPC_CREAT | 0660);
+ if ( _CPU_SHM_Semid == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ perror( "semget" );
+ _CPU_Fatal_halt( 0xdead0003 );
+ }
+
+ if ( is_master_node ) {
+ for ( i=0 ; i <= maximum_nodes ; i++ ) {
+#if !HAS_UNION_SEMUN
+ union semun {
+ int val;
+ struct semid_ds *buf;
+ unsigned short int *array;
+#if defined(__linux__)
+ struct seminfo *__buf;
+#endif
+ } ;
+#endif
+ union semun help ;
+ help.val = 1;
+ status = semctl( _CPU_SHM_Semid, i, SETVAL, help );
+
+ fix_syscall_errno(); /* in case of newlib */
+ if ( status == -1 ) {
+ _CPU_Fatal_halt( 0xdead0004 );
+ }
+ }
+ }
+
+ *shm_address = shm_addr;
+ *shm_length = shm_size;
+
+}
+#endif
+
+int _CPU_Get_pid( void )
+{
+ return getpid();
+}
+
+#if defined(RTEMS_MULTIPROCESSING)
+/*
+ * Define this to use signals for MPCI shared memory driver.
+ * If undefined, the shared memory driver will poll from the
+ * clock interrupt.
+ * Ref: ../shmsupp/getcfg.c
+ *
+ * BEWARE:: many UN*X kernels and debuggers become severely confused when
+ * debugging programs which use signals. The problem is *much*
+ * worse when using multiple signals, since ptrace(2) tends to
+ * drop all signals except 1 in the case of multiples.
+ * On hpux9, this problem was so bad, we couldn't use interrupts
+ * with the shared memory driver if we ever hoped to debug
+ * RTEMS programs.
+ * Maybe systems that use /proc don't have this problem...
+ */
+
+
+int _CPU_SHM_Get_vector( void )
+{
+#ifdef CPU_USE_SHM_INTERRUPTS
+ return SIGUSR1;
+#else
+ return 0;
+#endif
+}
+
+void _CPU_SHM_Send_interrupt(
+ int pid,
+ int vector
+)
+{
+ kill((pid_t) pid, vector);
+}
+
+void _CPU_SHM_Lock(
+ int semaphore
+)
+{
+ struct sembuf sb;
+
+ sb.sem_num = semaphore;
+ sb.sem_op = -1;
+ sb.sem_flg = 0;
+
+ while (1) {
+ int status = -1;
+
+ status = semop(_CPU_SHM_Semid, &sb, 1);
+ if ( status >= 0 )
+ break;
+ if ( status == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ if (errno == EINTR)
+ continue;
+ perror("shm lock");
+ _CPU_Fatal_halt( 0xdead0005 );
+ }
+ }
+
+}
+
+void _CPU_SHM_Unlock(
+ int semaphore
+)
+{
+ struct sembuf sb;
+ int status;
+
+ sb.sem_num = semaphore;
+ sb.sem_op = 1;
+ sb.sem_flg = 0;
+
+ while (1) {
+ status = semop(_CPU_SHM_Semid, &sb, 1);
+ if ( status >= 0 )
+ break;
+
+ if ( status == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ if (errno == EINTR)
+ continue;
+ perror("shm unlock");
+ _CPU_Fatal_halt( 0xdead0006 );
+ }
+ }
+
+}
+#endif
diff --git a/cpukit/score/cpu/unix/preinstall.am b/cpukit/score/cpu/unix/preinstall.am
new file mode 100644
index 0000000000..a7bff00426
--- /dev/null
+++ b/cpukit/score/cpu/unix/preinstall.am
@@ -0,0 +1,41 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/asm.h: rtems/asm.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/asm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/asm.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+
+$(PROJECT_INCLUDE)/rtems/score/cpu.h: rtems/score/cpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu.h
+
+$(PROJECT_INCLUDE)/rtems/score/unix.h: rtems/score/unix.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/unix.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/unix.h
+
diff --git a/cpukit/score/cpu/unix/rtems/asm.h b/cpukit/score/cpu/unix/rtems/asm.h
new file mode 100644
index 0000000000..24abe24387
--- /dev/null
+++ b/cpukit/score/cpu/unix/rtems/asm.h
@@ -0,0 +1,36 @@
+/**
+ * @file rtems/asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ *
+ * This file is a "just an incomplete stub" and provided for consistency
+ * with other ports, only.
+ */
+
+/*
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/unix.h>
+
+#endif
diff --git a/cpukit/score/cpu/unix/rtems/score/cpu.h b/cpukit/score/cpu/unix/rtems/score/cpu.h
new file mode 100644
index 0000000000..f2058fc655
--- /dev/null
+++ b/cpukit/score/cpu/unix/rtems/score/cpu.h
@@ -0,0 +1,1111 @@
+/**
+ * @file rtems/score/cpu.h
+ */
+
+/*
+ * This include file contains information pertaining to the
+ * UNIX port of RTEMS.
+ *
+ * COPYRIGHT (c) 1994 by Division Incorporated
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/unix.h> /* pick up machine definitions */
+#ifndef ASM
+#include <rtems/score/types.h>
+#endif
+
+#if defined(linux)
+#define MALLOC_0_RETURNS_NULL
+#endif
+
+/* conditional compilation parameters */
+
+/*
+ * Should the calls to _Thread_Enable_dispatch be inlined?
+ *
+ * If TRUE, then they are inlined.
+ * If FALSE, then a subroutine call is made.
+ *
+ * Basically this is an example of the classic trade-off of size
+ * versus speed. Inlining the call (TRUE) typically increases the
+ * size of RTEMS while speeding up the enabling of dispatching.
+ * [NOTE: In general, the _Thread_Dispatch_disable_level will
+ * only be 0 or 1 unless you are in an interrupt handler and that
+ * interrupt handler invokes the executive.] When not inlined
+ * something calls _Thread_Enable_dispatch which in turns calls
+ * _Thread_Dispatch. If the enable dispatch is inlined, then
+ * one subroutine call is avoided entirely.]
+ */
+
+#define CPU_INLINE_ENABLE_DISPATCH FALSE
+
+/*
+ * Should the body of the search loops in _Thread_queue_Enqueue_priority
+ * be unrolled one time? In unrolled each iteration of the loop examines
+ * two "nodes" on the chain being searched. Otherwise, only one node
+ * is examined per iteration.
+ *
+ * If TRUE, then the loops are unrolled.
+ * If FALSE, then the loops are not unrolled.
+ *
+ * The primary factor in making this decision is the cost of disabling
+ * and enabling interrupts (_ISR_Flash) versus the cost of rest of the
+ * body of the loop. On some CPUs, the flash is more expensive than
+ * one iteration of the loop body. In this case, it might be desirable
+ * to unroll the loop. It is important to note that on some CPUs, this
+ * code is the longest interrupt disable period in RTEMS. So it is
+ * necessary to strike a balance when setting this parameter.
+ */
+
+#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
+
+/*
+ * Does RTEMS manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in _ISR_Handler_initialization.
+ * If FALSE, nothing is done.
+ *
+ * If the CPU supports a dedicated interrupt stack in hardware,
+ * then it is generally the responsibility of the BSP to allocate it
+ * and set it up.
+ *
+ * If the CPU does not support a dedicated interrupt stack, then
+ * the porter has two options: (1) execute interrupts on the
+ * stack of the interrupted task, and (2) have RTEMS manage a dedicated
+ * interrupt stack.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
+
+/*
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * If TRUE, then it must be installed during initialization.
+ * If FALSE, then no installation is performed.
+ *
+ * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
+ *
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
+ * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
+ * possible that both are FALSE for a particular CPU. Although it
+ * is unclear what that would imply about the interrupt processing
+ * procedure on that CPU.
+ */
+
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
+
+/*
+ * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * If TRUE, then the memory is allocated during initialization.
+ * If FALSE, then the memory is allocated during initialization.
+ *
+ * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
+ */
+
+#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
+
+/*
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ */
+
+#define CPU_ISR_PASSES_FRAME_POINTER 0
+
+/*
+ * Does the CPU have hardware floating point?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
+ *
+ * If there is a FP coprocessor such as the i387 or mc68881, then
+ * the answer is TRUE.
+ *
+ * The macro name "UNIX_HAS_FPU" should be made CPU specific.
+ * It indicates whether or not this CPU model has FP support. For
+ * example, it would be possible to have an i386_nofp CPU model
+ * which set this to false to indicate that you have an i386 without
+ * an i387 and wish to leave floating point support out of RTEMS.
+ */
+
+#define CPU_HARDWARE_FP TRUE
+#define CPU_SOFTWARE_FP FALSE
+
+/*
+ * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
+ *
+ * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
+ * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
+ *
+ * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
+ */
+
+#define CPU_ALL_TASKS_ARE_FP FALSE
+
+/*
+ * Should the IDLE task have a floating point context?
+ *
+ * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * If FALSE, then the IDLE task does not have a floating point context.
+ *
+ * Setting this to TRUE negatively impacts the time required to preempt
+ * the IDLE task from an interrupt because the floating point context
+ * must be saved as part of the preemption.
+ */
+
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+/*
+ * Should the saving of the floating point registers be deferred
+ * until a context switch is made to another different floating point
+ * task?
+ *
+ * If TRUE, then the floating point context will not be stored until
+ * necessary. It will remain in the floating point registers and not
+ * disturned until another floating point task is switched to.
+ *
+ * If FALSE, then the floating point context is saved when a floating
+ * point task is switched out and restored when the next floating point
+ * task is restored. The state of the floating point registers between
+ * those two operations is not specified.
+ *
+ * If the floating point context does NOT have to be saved as part of
+ * interrupt dispatching, then it should be safe to set this to TRUE.
+ *
+ * Setting this flag to TRUE results in using a different algorithm
+ * for deciding when to save and restore the floating point context.
+ * The deferred FP switch algorithm minimizes the number of times
+ * the FP context is saved and restored. The FP context is not saved
+ * until a context switch is made to another, different FP task.
+ * Thus in a system with only one FP task, the FP context will never
+ * be saved or restored.
+ */
+
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+/*
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * If TRUE, then the routine _CPU_Thread_Idle_body
+ * must be provided and is the default IDLE thread body instead of
+ * _CPU_Thread_Idle_body.
+ *
+ * If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ *
+ * This is intended to allow for supporting processors which have
+ * a low power or idle mode. When the IDLE thread is executed, then
+ * the CPU can be powered down.
+ *
+ * The order of precedence for selecting the IDLE thread body is:
+ *
+ * 1. BSP provided
+ * 2. CPU dependent (if provided)
+ * 3. generic (if no BSP and no CPU dependent)
+ */
+
+#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE
+
+/*
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * If TRUE, then the grows upward.
+ * If FALSE, then the grows toward smaller addresses.
+ */
+
+#if defined(__hppa__)
+#define CPU_STACK_GROWS_UP TRUE
+#elif defined(__sparc__) || defined(__i386__)
+#define CPU_STACK_GROWS_UP FALSE
+#else
+#error "unknown CPU!!"
+#endif
+
+
+/*
+ * The following is the variable attribute used to force alignment
+ * of critical RTEMS structures. On some processors it may make
+ * sense to have these aligned on tighter boundaries than
+ * the minimum requirements of the compiler in order to have as
+ * much of the critical data area as possible in a cache line.
+ *
+ * The placement of this macro in the declaration of the variables
+ * is based on the syntactically requirements of the GNU C
+ * "__attribute__" extension. For example with GNU C, use
+ * the following to force a structures to a 32 byte boundary.
+ *
+ * __attribute__ ((aligned (32)))
+ *
+ * NOTE: Currently only the Priority Bit Map table uses this feature.
+ * To benefit from using this, the data must be heavily
+ * used so it will stay in the cache and used frequently enough
+ * in the executive to justify turning this on.
+ *
+ * This is really not critical on the POSIX simulator ports as
+ * performance is not the goal here.
+ */
+
+#define CPU_STRUCTURE_ALIGNMENT
+
+/*
+ * Define what is required to specify how the network to host conversion
+ * routines are handled.
+ */
+
+#if defined(__hppa__) || defined(__sparc__)
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+#define CPU_BIG_ENDIAN TRUE
+#define CPU_LITTLE_ENDIAN FALSE
+#elif defined(__i386__)
+#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
+#define CPU_BIG_ENDIAN FALSE
+#define CPU_LITTLE_ENDIAN TRUE
+#else
+#error "Unknown CPU!!!"
+#endif
+
+/*
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
+ */
+
+#define CPU_MODES_INTERRUPT_MASK 0x00000001
+
+#define CPU_NAME "UNIX"
+
+/*
+ * Processor defined structures required for cpukit/score.
+ */
+
+/* may need to put some structures here. */
+
+#if defined(__hppa__)
+/*
+ * Word indices within a jmp_buf structure
+ */
+
+#ifdef RTEMS_NEWLIB_SETJMP
+#define RP_OFF 6
+#define SP_OFF 2
+#define R3_OFF 10
+#define R4_OFF 11
+#define R5_OFF 12
+#define R6_OFF 13
+#define R7_OFF 14
+#define R8_OFF 15
+#define R9_OFF 16
+#define R10_OFF 17
+#define R11_OFF 18
+#define R12_OFF 19
+#define R13_OFF 20
+#define R14_OFF 21
+#define R15_OFF 22
+#define R16_OFF 23
+#define R17_OFF 24
+#define R18_OFF 25
+#define DP_OFF 26
+#endif
+
+#ifdef RTEMS_UNIXLIB_SETJMP
+#define RP_OFF 0
+#define SP_OFF 1
+#define R3_OFF 4
+#define R4_OFF 5
+#define R5_OFF 6
+#define R6_OFF 7
+#define R7_OFF 8
+#define R8_OFF 9
+#define R9_OFF 10
+#define R10_OFF 11
+#define R11_OFF 12
+#define R12_OFF 13
+#define R13_OFF 14
+#define R14_OFF 15
+#define R15_OFF 16
+#define R16_OFF 17
+#define R17_OFF 18
+#define R18_OFF 19
+#define DP_OFF 20
+#endif
+#endif
+
+#if defined(__i386__)
+
+#ifdef RTEMS_NEWLIB
+#error "Newlib not installed"
+#endif
+
+/*
+ * For i386 targets
+ */
+
+#ifdef RTEMS_UNIXLIB
+#if defined(__FreeBSD__)
+#define RET_OFF 0
+#define EBX_OFF 1
+#define EBP_OFF 2
+#define ESP_OFF 3
+#define ESI_OFF 4
+#define EDI_OFF 5
+#elif defined(__CYGWIN__)
+#define EAX_OFF 0
+#define EBX_OFF 1
+#define ECX_OFF 2
+#define EDX_OFF 3
+#define ESI_OFF 4
+#define EDI_OFF 5
+#define EBP_OFF 6
+#define ESP_OFF 7
+#define RET_OFF 8
+#else
+/* Linux */
+#define EBX_OFF 0
+#define ESI_OFF 1
+#define EDI_OFF 2
+#define EBP_OFF 3
+#define ESP_OFF 4
+#define RET_OFF 5
+#endif
+#endif
+
+#endif
+
+#if defined(__sparc__)
+
+/*
+ * Word indices within a jmp_buf structure
+ */
+
+#ifdef RTEMS_NEWLIB
+#define ADDR_ADJ_OFFSET -8
+#define SP_OFF 0
+#define RP_OFF 1
+#define FP_OFF 2
+#endif
+
+#ifdef RTEMS_UNIXLIB
+#define ADDR_ADJ_OFFSET 0
+#define G0_OFF 0
+#define SP_OFF 1
+#define RP_OFF 2
+#define FP_OFF 3
+#define I7_OFF 4
+#endif
+
+#endif
+
+/*
+ * Contexts
+ *
+ * Generally there are 2 types of context to save.
+ * 1. Interrupt registers to save
+ * 2. Task level registers to save
+ *
+ * This means we have the following 3 context items:
+ * 1. task level context stuff:: Context_Control
+ * 2. floating point task stuff:: Context_Control_fp
+ * 3. special interrupt level context :: Context_Control_interrupt
+ *
+ * On some processors, it is cost-effective to save only the callee
+ * preserved registers during a task context switch. This means
+ * that the ISR code needs to save those registers which do not
+ * persist across function calls. It is not mandatory to make this
+ * distinctions between the caller/callee saves registers for the
+ * purpose of minimizing context saved during task switch and on interrupts.
+ * If the cost of saving extra registers is minimal, simplicity is the
+ * choice. Save the same context on interrupt entry as for tasks in
+ * this case.
+ *
+ * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
+ * care should be used in designing the context area.
+ *
+ * On some CPUs with hardware floating point support, the Context_Control_fp
+ * structure will not be used or it simply consist of an array of a
+ * fixed number of bytes. This is done when the floating point context
+ * is dumped by a "FP save context" type instruction and the format
+ * is not really defined by the CPU. In this case, there is no need
+ * to figure out the exact format -- only the size. Of course, although
+ * this is enough information for RTEMS, it is probably not enough for
+ * a debugger such as gdb. But that is another problem.
+ */
+
+/*
+ * This is really just the area for the following fields.
+ *
+ * jmp_buf regs;
+ * uint32_t isr_level;
+ *
+ * Doing it this way avoids conflicts between the native stuff and the
+ * RTEMS stuff.
+ *
+ * NOTE:
+ * hpux9 setjmp is optimized for the case where the setjmp buffer
+ * is 8 byte aligned. In a RISC world, this seems likely to enable
+ * 8 byte copies, especially for the float registers.
+ * So we always align them on 8 byte boundaries.
+ */
+
+#ifdef __GNUC__
+#define CONTEXT_STRUCTURE_ALIGNMENT __attribute__ ((aligned (8)))
+#else
+#define CONTEXT_STRUCTURE_ALIGNMENT
+#endif
+
+typedef struct {
+ char Area[ SIZEOF_CPU_CONTEXT ] CONTEXT_STRUCTURE_ALIGNMENT;
+} Context_Control;
+
+typedef struct {
+} Context_Control_fp;
+
+typedef struct {
+} CPU_Interrupt_frame;
+
+
+/*
+ * The following table contains the information required to configure
+ * the UNIX Simulator specific parameters.
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ uint32_t idle_task_stack_size;
+ uint32_t interrupt_stack_size;
+ uint32_t extra_mpci_receive_server_stack;
+ void * (*stack_allocate_hook)( uint32_t );
+ void (*stack_free_hook)( void* );
+ /* end of required fields */
+} rtems_cpu_table;
+
+/*
+ * Macros to access required entires in the CPU Table are in
+ * the file rtems/system.h.
+ */
+
+/*
+ * Macros to access UNIX specific additions to the CPU Table
+ */
+
+/* There are no CPU specific additions to the CPU Table for this port. */
+
+/*
+ * This variable is optional. It is used on CPUs on which it is difficult
+ * to generate an "uninitialized" FP context. It is filled in by
+ * _CPU_Initialize and copied into the task's FP context area during
+ * _CPU_Context_Initialize.
+ */
+
+SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
+
+/*
+ * On some CPUs, RTEMS supports a software managed interrupt stack.
+ * This stack is allocated by the Interrupt Manager and the switch
+ * is performed in _ISR_Handler. These variables contain pointers
+ * to the lowest and highest addresses in the chunk of memory allocated
+ * for the interrupt stack. Since it is unknown whether the stack
+ * grows up or down (in general), this give the CPU dependent
+ * code the option of picking the version it wants to use.
+ *
+ * NOTE: These two variables are required if the macro
+ * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
+ */
+
+SCORE_EXTERN void *_CPU_Interrupt_stack_low;
+SCORE_EXTERN void *_CPU_Interrupt_stack_high;
+
+/*
+ * With some compilation systems, it is difficult if not impossible to
+ * call a high-level language routine from assembly language. This
+ * is especially true of commercial Ada compilers and name mangling
+ * C++ ones. This variable can be optionally defined by the CPU porter
+ * and contains the address of the routine _Thread_Dispatch. This
+ * can make it easier to invoke that routine at the end of the interrupt
+ * sequence (if a dispatch is necessary).
+ */
+
+SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
+
+/*
+ * Nothing prevents the porter from declaring more CPU specific variables.
+ */
+
+/* XXX: if needed, put more variables here */
+
+/*
+ * The size of the floating point context area. On some CPUs this
+ * will not be a "sizeof" because the format of the floating point
+ * area is not defined -- only the size is. This is usually on
+ * CPUs with a "floating point save context" instruction.
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/*
+ * The size of a frame on the stack
+ */
+
+#if defined(__hppa__)
+#define CPU_FRAME_SIZE (32 * 4)
+#elif defined(__sparc__)
+#define CPU_FRAME_SIZE (112) /* based on disassembled test code */
+#elif defined(__i386__)
+#define CPU_FRAME_SIZE (24) /* return address, sp, and bp pushed plus fudge */
+#else
+#error "Unknown CPU!!!"
+#endif
+
+/*
+ * Amount of extra stack (above minimum stack size) required by
+ * MPCI receive server thread. Remember that in a multiprocessor
+ * system this thread must exist and be able to process all directives.
+ */
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+/*
+ * This defines the number of entries in the ISR_Vector_table managed
+ * by RTEMS.
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 64
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
+
+/*
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level.
+ */
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/*
+ * Should be large enough to run all RTEMS tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ */
+
+#define CPU_STACK_MINIMUM_SIZE (16 * 1024)
+
+/*
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ */
+
+#define CPU_ALIGNMENT 8
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
+ * then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
+ * enough for the partition, then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * This number corresponds to the byte alignment requirement for the
+ * stack. This alignment requirement may be stricter than that for the
+ * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
+ * is strict enough for the stack, then this should be set to 0.
+ *
+ * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
+ */
+
+#define CPU_STACK_ALIGNMENT 64
+
+/*
+ * ISR handler macros
+ */
+
+/*
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ */
+
+void _CPU_Initialize_vectors(void);
+
+/*
+ * Disable all interrupts for an RTEMS critical section. The previous
+ * level is returned in _level.
+ */
+
+extern uint32_t _CPU_ISR_Disable_support(void);
+
+#define _CPU_ISR_Disable( _level ) \
+ do { \
+ (_level) = _CPU_ISR_Disable_support(); \
+ } while ( 0 )
+
+/*
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of an RTEMS critical section. The parameter
+ * _level is not modified.
+ */
+
+void _CPU_ISR_Enable(uint32_t level);
+
+/*
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long RTEMS critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ */
+
+#define _CPU_ISR_Flash( _level ) \
+ do { \
+ register uint32_t _ignored = 0; \
+ _CPU_ISR_Enable( (_level) ); \
+ _CPU_ISR_Disable( _ignored ); \
+ } while ( 0 )
+
+/*
+ * Map interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a generic fashion are undefined. Someday,
+ * it would be nice if these were "mapped" by the application
+ * via a callout. For example, m68k has 8 levels 0 - 7, levels
+ * 8 - 255 would be available for bsp/application specific meaning.
+ * This could be used to manage a programmable interrupt controller
+ * via the rtems_task_mode directive.
+ */
+
+#define _CPU_ISR_Set_level( new_level ) \
+ { \
+ if ( new_level == 0 ) _CPU_ISR_Enable( 0 ); \
+ else _CPU_ISR_Enable( 1 ); \
+ }
+
+uint32_t _CPU_ISR_Get_level( void );
+
+/* end of ISR handler macros */
+
+/* Context handler macros */
+
+/*
+ * This routine is responsible for somehow restarting the currently
+ * executing task. If you are lucky, then all that is necessary
+ * is restoring the context. Otherwise, there will need to be
+ * a special assembly routine which does something special in this
+ * case. Context_Restore should work most of the time. It will
+ * not work if restarting self conflicts with the stack frame
+ * assumptions of restoring a context.
+ */
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+/*
+ * The purpose of this macro is to allow the initial pointer into
+ * a floating point context area (used to save the floating point
+ * context) to be at an arbitrary place in the floating point
+ * context area.
+ *
+ * This is necessary because some FP units are designed to have
+ * their context saved as a stack which grows into lower addresses.
+ * Other FP units can be saved by simply moving registers into offsets
+ * from the base of the context area. Finally some FP units provide
+ * a "dump context" instruction which could fill in from high to low
+ * or low to high based on the whim of the CPU designers.
+ */
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
+
+/*
+ * This routine initializes the FP context area passed to it to.
+ * There are a few standard ways in which to initialize the
+ * floating point context. The code included for this macro assumes
+ * that this is a CPU in which a "initial" FP context was saved into
+ * _CPU_Null_fp_context and it simply copies it to the destination
+ * context passed to it.
+ *
+ * Other models include (1) not doing anything, and (2) putting
+ * a "null FP status word" in the correct place in the FP context.
+ */
+
+#define _CPU_Context_Initialize_fp( _destination ) \
+ { \
+ *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
+ }
+
+#define _CPU_Context_save_fp( _fp_context ) \
+ _CPU_Save_float_context( *(Context_Control_fp **)(_fp_context))
+
+#define _CPU_Context_restore_fp( _fp_context ) \
+ _CPU_Restore_float_context( *(Context_Control_fp **)(_fp_context))
+
+extern void _CPU_Context_Initialize(
+ Context_Control *_the_context,
+ uint32_t *_stack_base,
+ uint32_t _size,
+ uint32_t _new_level,
+ void *_entry_point,
+ boolean _is_fp
+);
+
+/* end of Context handler macros */
+
+/* Fatal Error manager macros */
+
+/*
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ */
+
+#define _CPU_Fatal_halt( _error ) \
+ _CPU_Fatal_error( _error )
+
+/* end of Fatal Error manager macros */
+
+/* Bitfield handler macros */
+
+/*
+ * This routine sets _output to the bit number of the first bit
+ * set in _value. _value is of CPU dependent type Priority_Bit_map_control.
+ * This type may be either 16 or 32 bits wide although only the 16
+ * least significant bits will be used.
+ *
+ * There are a number of variables in using a "find first bit" type
+ * instruction.
+ *
+ * (1) What happens when run on a value of zero?
+ * (2) Bits may be numbered from MSB to LSB or vice-versa.
+ * (3) The numbering may be zero or one based.
+ * (4) The "find first bit" instruction may search from MSB or LSB.
+ *
+ * RTEMS guarantees that (1) will never happen so it is not a concern.
+ * (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
+ * _CPU_Priority_bits_index(). These three form a set of routines
+ * which must logically operate together. Bits in the _value are
+ * set and cleared based on masks built by _CPU_Priority_mask().
+ * The basic major and minor values calculated by _Priority_Major()
+ * and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
+ * to properly range between the values returned by the "find first bit"
+ * instruction. This makes it possible for _Priority_Get_highest() to
+ * calculate the major and directly index into the minor table.
+ * This mapping is necessary to ensure that 0 (a high priority major/minor)
+ * is the first bit found.
+ *
+ * This entire "find first bit" and mapping process depends heavily
+ * on the manner in which a priority is broken into a major and minor
+ * components with the major being the 4 MSB of a priority and minor
+ * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
+ * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next
+ * to the lowest priority.
+ *
+ * If your CPU does not have a "find first bit" instruction, then
+ * there are ways to make do without it. Here are a handful of ways
+ * to implement this in software:
+ *
+ * - a series of 16 bit test instructions
+ * - a "binary search using if's"
+ * - _number = 0
+ * if _value > 0x00ff
+ * _value >>=8
+ * _number = 8;
+ *
+ * if _value > 0x0000f
+ * _value >=8
+ * _number += 4
+ *
+ * _number += bit_set_table[ _value ]
+ *
+ * where bit_set_table[ 16 ] has values which indicate the first
+ * bit set
+ */
+
+/*
+ * The UNIX port uses the generic C algorithm for bitfield scan to avoid
+ * dependencies on either a native bitscan instruction or an ffs() in the
+ * C library.
+ */
+
+#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
+
+/* end of Bitfield handler macros */
+
+/* Priority handler handler macros */
+
+/*
+ * The UNIX port uses the generic C algorithm for bitfield scan to avoid
+ * dependencies on either a native bitscan instruction or an ffs() in the
+ * C library.
+ */
+
+/* end of Priority handler macros */
+
+/* functions */
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/*
+ * _CPU_ISR_install_raw_handler
+ *
+ * This routine installs a "raw" interrupt handler directly into the
+ * processor's vector table.
+ */
+
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_Install_interrupt_stack
+ *
+ * This routine installs the hardware interrupt stack pointer.
+ *
+ * NOTE: It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK
+ * is TRUE.
+ */
+
+void _CPU_Install_interrupt_stack( void );
+
+/*
+ * _CPU_Thread_Idle_body
+ *
+ * This routine is the CPU dependent IDLE thread body.
+ *
+ * NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
+ * is TRUE.
+ */
+
+void _CPU_Thread_Idle_body( void );
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _CPU_Context_restore
+ *
+ * This routine is generally 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.
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/*
+ * _CPU_Save_float_context
+ *
+ * This routine saves the floating point context passed to it.
+ */
+
+void _CPU_Save_float_context(
+ Context_Control_fp *fp_context_ptr
+);
+
+/*
+ * _CPU_Restore_float_context
+ *
+ * This routine restores the floating point context passed to it.
+ */
+
+void _CPU_Restore_float_context(
+ Context_Control_fp *fp_context_ptr
+);
+
+
+void _CPU_ISR_Set_signal_level(
+ uint32_t level
+);
+
+void _CPU_Fatal_error(
+ uint32_t _error
+);
+
+/* The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * This version will work on any processor, but if there is a better
+ * way for your CPU PLEASE use it. The most common way to do this is to:
+ *
+ * swap least significant two bytes with 16-bit rotate
+ * swap upper and lower 16-bits
+ * swap most significant two bytes with 16-bit rotate
+ *
+ * Some CPUs have special instructions which swap a 32-bit quantity in
+ * a single instruction (e.g. i486). It is probably best to avoid
+ * an "endian swapping control bit" in the CPU. One good reason is
+ * that interrupts would probably have to be disabled to ensure that
+ * an interrupt does not try to access the same "chunk" with the wrong
+ * endian. Another good reason is that on some CPUs, the endian bit
+ * endianness for ALL fetches -- both code and data -- so the code
+ * will be fetched incorrectly.
+ */
+
+static inline uint32_t CPU_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t byte1, byte2, byte3, byte4, swapped;
+
+ byte4 = (value >> 24) & 0xff;
+ byte3 = (value >> 16) & 0xff;
+ byte2 = (value >> 8) & 0xff;
+ byte1 = value & 0xff;
+
+ swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
+ return( swapped );
+}
+
+#define CPU_swap_u16( value ) \
+ (((value&0xff) << 8) | ((value >> 8)&0xff))
+
+/*
+ * Special Purpose Routines to hide the use of UNIX system calls.
+ */
+
+
+/*
+ * Pointer to a sync io Handler
+ */
+
+typedef void ( *rtems_sync_io_handler )(
+ int fd,
+ boolean read,
+ boolean wrtie,
+ boolean except
+);
+
+/* returns -1 if fd to large, 0 is successful */
+int _CPU_Set_sync_io_handler(
+ int fd,
+ boolean read,
+ boolean write,
+ boolean except,
+ rtems_sync_io_handler handler
+);
+
+/* returns -1 if fd to large, o if successful */
+int _CPU_Clear_sync_io_handler(
+ int fd
+);
+
+int _CPU_Get_clock_vector( void );
+
+void _CPU_Start_clock(
+ int microseconds
+);
+
+void _CPU_Stop_clock( void );
+
+#if defined(RTEMS_MULTIPROCESSING)
+
+void _CPU_SHM_Init(
+ uint32_t maximum_nodes,
+ boolean is_master_node,
+ void **shm_address,
+ uint32_t *shm_length
+);
+
+int _CPU_Get_pid( void );
+
+int _CPU_SHM_Get_vector( void );
+
+void _CPU_SHM_Send_interrupt(
+ int pid,
+ int vector
+);
+
+void _CPU_SHM_Lock(
+ int semaphore
+);
+
+void _CPU_SHM_Unlock(
+ int semaphore
+);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/unix/rtems/score/types.h b/cpukit/score/cpu/unix/rtems/score/types.h
new file mode 100644
index 0000000000..0ed9a72479
--- /dev/null
+++ b/cpukit/score/cpu/unix/rtems/score/types.h
@@ -0,0 +1,69 @@
+/**
+ * @file rtems/score/types.h
+ */
+
+/*
+ * This include file contains type definitions which are appropriate
+ * for a typical modern UNIX box using GNU C for the RTEMS simulator.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#ifndef ASM
+
+#include <rtems/stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * some C++ compilers (eg: HP's) don't do 'signed' or 'volatile'
+ */
+#if defined(__cplusplus) && !defined(__GNUC__)
+#define signed
+#define volatile
+#endif
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+
+typedef uint16_t Priority_Bit_map_control;
+
+
+/*
+ * some C++ compilers (eg: HP's) don't do 'long long'
+ */
+#if defined(__GNUC__)
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+typedef signed long long signed64; /* 64 bit signed integer */
+#endif
+
+typedef uint32_t boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+typedef void unix_isr;
+
+typedef unix_isr ( *unix_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
diff --git a/cpukit/score/cpu/unix/rtems/score/unix.h b/cpukit/score/cpu/unix/rtems/score/unix.h
new file mode 100644
index 0000000000..cd8c3ffb51
--- /dev/null
+++ b/cpukit/score/cpu/unix/rtems/score/unix.h
@@ -0,0 +1,73 @@
+/**
+ * @file rtems/score/unix.h
+ */
+
+/*
+ * This include file contains the definitions required by RTEMS
+ * which are typical for a modern UNIX computer using GCC.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_UNIX_H
+#define _RTEMS_SCORE_UNIX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the "unix"
+ * family when executing in protected mode. It does
+ * this by setting variables to indicate which implementation
+ * dependent features are present in a particular member
+ * of the family.
+ */
+
+#if defined(rtems_multilib)
+/*
+ * Figure out all CPU Model Feature Flags based upon compiler
+ * predefines.
+ */
+
+#define CPU_MODEL_NAME "rtems_multilib"
+
+#elif defined(hpux)
+
+#define CPU_MODEL_NAME "HP-UX"
+
+#elif defined(solaris2)
+
+#define CPU_MODEL_NAME "Solaris"
+
+#elif defined(__linux__) || defined(linux)
+
+#define CPU_MODEL_NAME "Linux"
+
+#elif defined(__CYGWIN__)
+
+#define CPU_MODEL_NAME "Cygwin"
+
+#elif defined(__FreeBSD__)
+
+#define CPU_MODEL_NAME "FreeBSD"
+
+#else
+
+#error "Unsupported CPU Model"
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/include/rtems/debug.h b/cpukit/score/include/rtems/debug.h
new file mode 100644
index 0000000000..abdb6200d0
--- /dev/null
+++ b/cpukit/score/include/rtems/debug.h
@@ -0,0 +1,79 @@
+/**
+ * @file rtems/debug.h
+ *
+ * This include file contains the information pertaining to the debug
+ * support within RTEMS. It is currently cast in the form of a
+ * Manager since it is externally accessible.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_DEBUG_H
+#define _RTEMS_DEBUG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The following type is used to manage the debug mask.
+ */
+typedef uint32_t rtems_debug_control;
+
+/*
+ * These constants represent various classes of debugging.
+ */
+
+/** Macro which indicates that all debugging modes are enabled */
+#define RTEMS_DEBUG_ALL_MASK 0xffffffff
+
+/** Macro which indicates that debugging for heaps/regions is enabled */
+#define RTEMS_DEBUG_REGION 0x00000001
+
+/**
+ * This variable contains the current debug level.
+ */
+SCORE_EXTERN rtems_debug_control _Debug_Level;
+
+/**
+ * This routine performs the initialization necessary for this manager.
+ */
+void _Debug_Manager_initialization( void );
+
+/**
+ * This routine enables the specified types of debug checks.
+ */
+void rtems_debug_enable (
+ rtems_debug_control to_be_enabled
+);
+
+/**
+ * This routine disables the specified types of debug checks.
+ */
+void rtems_debug_disable (
+ rtems_debug_control to_be_disabled
+);
+
+/**
+ * This routine returns TRUE if the requested debug level is
+ * enabled, and FALSE otherwise.
+ */
+boolean _Debug_Is_enabled(
+ rtems_debug_control level
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/.cvsignore b/cpukit/score/include/rtems/score/.cvsignore
new file mode 100644
index 0000000000..d9ecd15e8c
--- /dev/null
+++ b/cpukit/score/include/rtems/score/.cvsignore
@@ -0,0 +1 @@
+cpuopts.h
diff --git a/cpukit/score/include/rtems/score/address.h b/cpukit/score/include/rtems/score/address.h
new file mode 100644
index 0000000000..405c5b715c
--- /dev/null
+++ b/cpukit/score/include/rtems/score/address.h
@@ -0,0 +1,43 @@
+/**
+ * @file rtems/score/address.h
+ *
+ * This include file contains the information required to manipulate
+ * physical addresses.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_ADDRESS_H
+#define _RTEMS_SCORE_ADDRESS_H
+
+/**
+ * @defgroup ScoreAddress Address Handler
+ *
+ * This handler encapsulates functionality which abstracts address
+ * manipulation in a portable manner.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/address.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/apiext.h b/cpukit/score/include/rtems/score/apiext.h
new file mode 100644
index 0000000000..e1135fbd63
--- /dev/null
+++ b/cpukit/score/include/rtems/score/apiext.h
@@ -0,0 +1,127 @@
+/**
+ * @file rtems/score/apiext.h
+ *
+ * This is the API Extensions Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_APIEXT_H
+#define _RTEMS_SCORE_APIEXT_H
+
+/**
+ * @defgroup ScoreAPIExtension API Extension Handler
+ *
+ * This handler encapsulates functionality which provides mechanisms for the
+ * SuperCore to perform API specific actions without there beingg
+ * "up-references" from the SuperCore to APIs. If these referencesg
+ * were allowed in the implementation, the cohesion would be too high
+ * and adding an API would be more difficult. The SuperCore is supposed
+ * to be largely independent of any API.
+ */
+/**@{*/
+
+#include <rtems/score/chain.h>
+#include <rtems/score/thread.h>
+
+/**
+ * This type defines the prototype of the Predriver Hook.
+ */
+typedef void (*API_extensions_Predriver_hook)(void);
+
+/**
+ * This type defines the prototype of the Postdriver Hook.
+ */
+typedef void (*API_extensions_Postdriver_hook)(void);
+
+/**
+ * This type defines the prototype of the Postswitch Hook.
+ */
+typedef void (*API_extensions_Postswitch_hook)(
+ Thread_Control *
+ );
+
+/**
+ * The control structure which defines the points at which an API
+ * can add an extension to the system initialization thread.
+ */
+typedef struct {
+ /** This field allows this structure to be used with the Chain Handler. */
+ Chain_Node Node;
+ /**
+ * This field is the callout invoked during RTEMS initialization after
+ * RTEMS data structures are initialized before device driver initialization
+ * has occurred.
+ *
+ * @note If this field is NULL, no extension is invoked.
+ */
+ API_extensions_Predriver_hook predriver_hook;
+ /**
+ * This field is the callout invoked during RTEMS initialization after
+ * RTEMS data structures and device driver initialization has occurred
+ * but before multitasking is initiated.
+ *
+ * @note If this field is NULL, no extension is invoked.
+ */
+ API_extensions_Postdriver_hook postdriver_hook;
+ /**
+ * This field is the callout invoked during each context switch
+ * in the context of the heir thread.
+ *
+ * @note If this field is NULL, no extension is invoked.
+ */
+ API_extensions_Postswitch_hook postswitch_hook;
+} API_extensions_Control;
+
+/**
+ * This is the list of API extensions to the system initialization.
+ */
+SCORE_EXTERN Chain_Control _API_extensions_List;
+
+/** @brief Initialize the API Extensions Handler
+ *
+ * This routine initializes the API extension handler.
+ */
+void _API_extensions_Initialization( void );
+
+/** @brief Add Extension Set to the Active Set
+ *
+ * This routine adds an extension to the active set of API extensions.
+ *
+ * @param[in] the_extension is the extension set to add.
+ */
+void _API_extensions_Add(
+ API_extensions_Control *the_extension
+);
+
+/** @brief Execute all Pre-Driver Extensions
+ *
+ * This routine executes all of the predriver callouts.
+ */
+void _API_extensions_Run_predriver( void );
+
+/** @brief Execute all Post-Driver Extensions
+ *
+ * This routine executes all of the postdriver callouts.
+ */
+void _API_extensions_Run_postdriver( void );
+
+/** @brief Execute all Post Context Switch Extensions
+ *
+ * This routine executes all of the post context switch callouts.
+ */
+void _API_extensions_Run_postswitch( void );
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/apimutex.h b/cpukit/score/include/rtems/score/apimutex.h
new file mode 100644
index 0000000000..ea257f4a7e
--- /dev/null
+++ b/cpukit/score/include/rtems/score/apimutex.h
@@ -0,0 +1,172 @@
+/**
+ * @file rtems/score/apimutex.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the API Mutex Handler. This handler is used by API level
+ * routines to manage mutual exclusion.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_APIMUTEX_H
+#define _RTEMS_SCORE_APIMUTEX_H
+
+/**
+ * @defgroup ScoreAPIMutex API Mutex Handler
+ *
+ * This handler encapsulates functionality which provides mutexes to be used
+ * in the implementation of API functionality.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/coremutex.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+
+/**
+ * The following defines the control block used to manage each API mutex.
+ * An API Mutex is an aggregration of an Object and a SuperCore Mutex.
+ */
+typedef struct {
+ /** This field allows each API Mutex to be a full-fledged RTEMS object. */
+ Objects_Control Object;
+ /** This field contains the SuperCore mutex information. */
+ CORE_mutex_Control Mutex;
+} API_Mutex_Control;
+
+/**
+ * The following variable is the information control block used to manage
+ * this class of objects.
+ */
+SCORE_EXTERN Objects_Information _API_Mutex_Information;
+
+/**
+ * This routine performs the initialization necessary for this handler.
+ *
+ * @param[in] _maximum_mutexes is the maximum number of API mutexes
+ * that may exist at any time
+ */
+#if defined(RTEMS_MULTIPROCESSING)
+#define _API_Mutex_Initialization( _maximum_mutexes ) \
+ _Objects_Initialize_information( \
+ &_API_Mutex_Information, \
+ OBJECTS_INTERNAL_API, \
+ OBJECTS_INTERNAL_MUTEXES, \
+ _maximum_mutexes, \
+ sizeof( API_Mutex_Control ), \
+ FALSE, \
+ 0, \
+ FALSE, \
+ NULL \
+ );
+#else
+#define _API_Mutex_Initialization( _maximum_mutexes ) \
+ _Objects_Initialize_information( \
+ &_API_Mutex_Information, \
+ OBJECTS_INTERNAL_API, \
+ OBJECTS_INTERNAL_MUTEXES, \
+ _maximum_mutexes, \
+ sizeof( API_Mutex_Control ), \
+ FALSE, \
+ 0 \
+ );
+#endif
+
+/**
+ * This routine allocates an API mutex from the inactive set.
+ *
+ * @param[out] _the_mutex will contain the allocated mutex.
+ */
+#define _API_Mutex_Allocate( _the_mutex ) \
+ do { \
+ CORE_mutex_Attributes attr = \
+ { CORE_MUTEX_NESTING_IS_ERROR, FALSE, \
+ CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT, 0 }; \
+ (_the_mutex) = (API_Mutex_Control *) \
+ _Objects_Allocate( &_API_Mutex_Information ); \
+ _CORE_mutex_Initialize( \
+ &(_the_mutex)->Mutex, &attr, CORE_MUTEX_UNLOCKED ); \
+ } while (0)
+
+/**
+ * This routine acquires the specified API mutex.
+ *
+ * @param[in] _the_mutex is the mutex to acquire.
+ */
+#define _API_Mutex_Lock( _the_mutex ) \
+ do { \
+ ISR_Level _level; \
+ _ISR_Disable( _level ); \
+ _CORE_mutex_Seize( \
+ &(_the_mutex)->Mutex, (_the_mutex)->Object.id, TRUE, 0, (_level) ); \
+ } while (0)
+
+/**
+ * This routine releases the specified API mutex.
+ *
+ * @param[in] _the_mutex is the mutex to release.
+ */
+
+#define _API_Mutex_Unlock( _the_mutex ) \
+ do { \
+ _Thread_Disable_dispatch(); \
+ _CORE_mutex_Surrender( \
+ &(_the_mutex)->Mutex, (_the_mutex)->Object.id, NULL ); \
+ _Thread_Enable_dispatch(); \
+ } while (0);
+
+/**
+ * This variable points to the API Mutex instance that is used
+ * to protect all memory allocation and deallocation in RTEMS.
+ *
+ * @note When the APIs all use this for allocation and deallocation
+ * protection, then this possibly should be renamed and moved to a
+ * higher level in the hierarchy.
+ */
+SCORE_EXTERN API_Mutex_Control *_RTEMS_Allocator_Mutex;
+
+/**
+ * This macro locks the RTEMS Allocation Mutex.
+ *
+ * @see _RTEMS_Allocator_Mutex
+ */
+#define _RTEMS_Lock_allocator() \
+ _API_Mutex_Lock( _RTEMS_Allocator_Mutex )
+
+/**
+ * This macro unlocks the RTEMS Allocation Mutex.
+ *
+ * @see _RTEMS_Allocator_Mutex
+ */
+#define _RTEMS_Unlock_allocator() \
+ _API_Mutex_Unlock( _RTEMS_Allocator_Mutex )
+
+/*
+ * There are no inlines for this handler.
+ */
+
+#ifndef __RTEMS_APPLICATION__
+/* #include <rtems/score/apimutex.inl> */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/bitfield.h b/cpukit/score/include/rtems/score/bitfield.h
new file mode 100644
index 0000000000..bfeef76dfc
--- /dev/null
+++ b/cpukit/score/include/rtems/score/bitfield.h
@@ -0,0 +1,106 @@
+/**
+ * @file rtems/score/bitfield.h
+ *
+ * This include file contains all bit field manipulation routines.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_BITFIELD_H
+#define _RTEMS_SCORE_BITFIELD_H
+
+/**
+ * @defgroup ScoreBitfield Bitfield Handler
+ *
+ * This handler encapsulates functionality that is used to manipulate the
+ * priority bitfields used to lookup which priority has the highest
+ * priority ready to execute thread.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if ( CPU_USE_GENERIC_BITFIELD_DATA == TRUE )
+
+/**
+ * This table is used by the generic bitfield routines to perform
+ * a highly optimized bit scan without the use of special CPU
+ * instructions.
+ */
+#ifndef SCORE_INIT
+extern const unsigned char __log2table[256];
+#else
+const unsigned char __log2table[256] = {
+ 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 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,
+ 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, 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, 0, 0
+};
+#endif
+
+#endif
+
+/**
+ * This routine returns the @a _bit_number of the first bit set
+ * in the specified value. The correspondence between @a _bit_number
+ * and actual bit position is processor dependent. The search for
+ * the first bit set may run from most to least significant bit
+ * or vice-versa.
+ *
+ * @param[in] _value is the value to bit scan.
+ * @param[in] _bit_number is the position of the first bit set.
+ *
+ * @note This routine is used when the executing thread is removed
+ * from the ready state and, as a result, its performance has a
+ * significant impact on the performance of the executive as a whole.
+ *
+ * @note This routine must be a macro because if a CPU specific version
+ * is used it will most likely use inline assembly.
+ */
+#if ( CPU_USE_GENERIC_BITFIELD_CODE == FALSE )
+#define _Bitfield_Find_first_bit( _value, _bit_number ) \
+ _CPU_Bitfield_Find_first_bit( _value, _bit_number )
+#else
+#define _Bitfield_Find_first_bit( _value, _bit_number ) \
+ { \
+ register uint32_t __value = (uint32_t ) (_value); \
+ register const unsigned char *__p = __log2table; \
+ \
+ if ( __value < 0x100 ) \
+ (_bit_number) = __p[ __value ] + 8; \
+ else \
+ (_bit_number) = __p[ __value >> 8 ]; \
+ }
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/chain.h b/cpukit/score/include/rtems/score/chain.h
new file mode 100644
index 0000000000..4a908cd19c
--- /dev/null
+++ b/cpukit/score/include/rtems/score/chain.h
@@ -0,0 +1,198 @@
+/**
+ * @file rtems/score/chain.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Doubly-Linked Chain Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CHAIN_H
+#define _RTEMS_SCORE_CHAIN_H
+
+/**
+ * @defgroup ScoreChain Chain Handler
+ *
+ * The Chain Handler is used to manage sets of entities. This handler
+ * provides two data structures. The Chain Node data structure is included
+ * as the first part of every data structure that will be placed on
+ * a chain. The second data structure is Chain Control which is used
+ * to manage a set of Chain Nodes.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/address.h>
+
+/**
+ * @typedef Chain_Node
+ *
+ * This type definition promotes the name for the Chain Node used by
+ * all RTEMS code. It is a separate type definition because a forward
+ * reference is required to define it. See @ref Chain_Node_struct for
+ * detailed information.
+ */
+typedef struct Chain_Node_struct Chain_Node;
+
+/**
+ * @struct Chain_Node_struct
+ *
+ * This is used to manage each element (node) which is placed
+ * on a chain.
+ *
+ * @note Typically, a more complicated structure will use the
+ * chain package. The more complicated structure will
+ * include a chain node as the first element in its
+ * control structure. It will then call the chain package
+ * with a pointer to that node element. The node pointer
+ * and the higher level structure start at the same address
+ * so the user can cast the pointers back and forth.
+ *
+ */
+struct Chain_Node_struct {
+ /** This points to the node after to this one on this chain. */
+ Chain_Node *next;
+ /** This points to the node immediate prior to this one on this chain. */
+ Chain_Node *previous;
+};
+
+/**
+ * @struct Chain_Control
+ *
+ * This is used to manage a chain. A chain consists of a doubly
+ * linked list of zero or more nodes.
+ *
+ * @note This implementation does not require special checks for
+ * manipulating the first and last elements on the chain.
+ * To accomplish this the @a Chain_Control structure is
+ * treated as two overlapping @ref Chain_Node structures.
+ * The permanent head of the chain overlays a node structure on the
+ * @a first and @a permanent_null fields. The permanent tail
+ * of the chain overlays a node structure on the
+ * @a permanent_null and @a last elements of the structure.
+ *
+ */
+typedef struct {
+ /** This points to the first node on this chain. */
+ Chain_Node *first;
+ /** This field is always 0. */
+ Chain_Node *permanent_null;
+ /** This points to the last node on this chain. */
+ Chain_Node *last;
+} Chain_Control;
+
+/**
+ * @brief Initialize a Chain Header
+ *
+ * This routine initializes @a the_chain structure to manage the
+ * contiguous array of @a number_nodes nodes which starts at
+ * @a starting_address. Each node is of @a node_size bytes.
+ *
+ * @param[in] the_chain specifies the chain to initialize
+ * @param[in] starting_address is the starting address of the array
+ * of elements
+ * @param[in] number_nodes is the numebr of nodes that will be in the chain
+ * @param[in] node_size is the size of each node
+ */
+void _Chain_Initialize(
+ Chain_Control *the_chain,
+ void *starting_address,
+ uint32_t number_nodes,
+ uint32_t node_size
+);
+
+#ifndef RTEMS_INLINES
+/**
+ * @brief Get the first node (do not disable interrupts)
+ *
+ * This method attempts to obtain the first node from @a the_chain.
+ *
+ * @param[in] the_chain points to the chain to operate upon
+ * @return If successful, a chain node is returned. Otherwise, NULL
+ * is returned.
+ */
+Chain_Node *_Chain_Get_first_unprotected(
+ Chain_Control *the_chain
+);
+#endif
+
+/**
+ * @brief Extract the specified node from a chain
+ *
+ * This routine extracts @a the_node from the chain on which it resides.
+ * It disables interrupts to ensure the atomicity of the
+ * extract operation.
+ *
+ * @arg the_node specifies the node to extract
+ */
+void _Chain_Extract(
+ Chain_Node *the_node
+);
+
+/**
+ * @brief Obtain the first node on a chain
+ *
+ * This function removes the first node from @a the_chain and returns
+ * a pointer to that node. If @a the_chain is empty, then NULL is returned.
+ *
+ * @return This method returns a pointer a node. If a node was removed,
+ * then a pointer to that node is returned. If @a the_chain was
+ * empty, then NULL is returned.
+ *
+ * @note It disables interrupts to ensure the atomicity of the get operation.
+ */
+Chain_Node *_Chain_Get(
+ Chain_Control *the_chain
+);
+
+/**
+ * @brief Insert a node on a chain
+ *
+ * This routine inserts @a the_node on a chain immediately following
+ * @a after_node.
+ *
+ * @note It disables interrupts to ensure the atomicity
+ * of the extract operation.
+ */
+void _Chain_Insert(
+ Chain_Node *after_node,
+ Chain_Node *the_node
+);
+
+/**
+ * @brief Append a node on the end of a chain
+ *
+ * This routine appends @a the_node onto the end of @a the_chain.
+ *
+ * @note It disables interrupts to ensure the atomicity of the
+ * append operation.
+ */
+void _Chain_Append(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/chain.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/context.h b/cpukit/score/include/rtems/score/context.h
new file mode 100644
index 0000000000..87c61957ba
--- /dev/null
+++ b/cpukit/score/include/rtems/score/context.h
@@ -0,0 +1,153 @@
+/**
+ * @file rtems/score/context.h
+ *
+ * This include file contains all information about each thread's context.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CONTEXT_H
+#define _RTEMS_SCORE_CONTEXT_H
+
+/**
+ * @defgroup ScoreContext Context Handler
+ *
+ * This handler encapsulates functionality which abstracts thread context
+ * management in a portable manner.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/cpu.h>
+
+/**
+ * @brief Size of Floating Point Context Area
+ *
+ * This constant defines the number of bytes required
+ * to store a full floating point context.
+ */
+#define CONTEXT_FP_SIZE CPU_CONTEXT_FP_SIZE
+
+/**
+ * @brief Is Context Switch Needed?
+ *
+ * This variable is set to TRUE when a reschedule operation
+ * has determined that the processor should be taken away from the
+ * currently executing thread and given to the heir thread.
+ */
+
+SCORE_EXTERN volatile boolean _Context_Switch_necessary;
+
+/**
+ * @brief Initialize Context Area
+ * This routine initializes @a _the_context such that the stack
+ * pointer, interrupt level, and entry point are correct for the
+ * thread's initial state.
+ *
+ * @param[in] _the_context will be initialized
+ * @param[in] _stack is the lowest physical address of the thread's
+ * context
+ * @param[in] _size is the size in octets of the thread's context
+ * @param[in] _isr is the ISR enable level for this thread
+ * @param[in] _entry is this thread's entry point
+ * @param[in] _is_fp is set to TRUE if this thread has floating point
+ * enabled
+ */
+#define _Context_Initialize(_the_context, _stack, _size, _isr, _entry, _is_fp) \
+ _CPU_Context_Initialize( _the_context, _stack, _size, _isr, _entry, _is_fp )
+
+/**
+ * @brief Perform Context Switch
+ *
+ * This routine saves the current context into the @a _executing
+ * context record and restores the context specified by @a _heir.
+ *
+ * @param[in] _executing is the currently executing thread's context
+ * @param[in] _heir is the context of the thread to be switched to
+ */
+#define _Context_Switch( _executing, _heir ) \
+ _CPU_Context_switch( _executing, _heir )
+
+/**
+ * @brief Restart Currently Executing Thread
+ *
+ * This routine restarts the calling thread by restoring its initial
+ * stack pointer and returning to the thread's entry point.
+ *
+ * @param[in] _the_context is the context of the thread to restart
+ */
+#define _Context_Restart_self( _the_context ) \
+ _CPU_Context_Restart_self( _the_context )
+
+/**
+ * @brief Return Starting Address of Floating Point Context
+ *
+ * This function returns the starting address of the floating
+ * point context save area. It is assumed that the are reserved
+ * for the floating point save area is large enough.
+ *
+ * @param[in] _base is lowest physical address of the floating point
+ * context save area.
+ * @param[in] _offset is the offset into the floating point area
+ *
+ * @return the initial FP context pointer
+ */
+#define _Context_Fp_start( _base, _offset ) \
+ _CPU_Context_Fp_start( (_base), (_offset) )
+
+/**
+ * @brief Initialize Floating Point Context Area
+ *
+ * This routine initializes the floating point context save
+ * area to contain an initial known state.
+ *
+ * @param[in] _fp_area is the base address of the floating point
+ * context save area to initialize.
+ */
+#define _Context_Initialize_fp( _fp_area ) \
+ _CPU_Context_Initialize_fp( _fp_area )
+
+/**
+ * @brief Restore Floating Point Context Area
+ *
+ * This routine restores the floating point context contained
+ * in the @a _fp area. It is assumed that the current
+ * floating point context has been saved by a previous invocation
+ * of @a _Context_Save_fp.
+ *
+ * @param[in] _fp points to the floating point context area to restore.
+ */
+#define _Context_Restore_fp( _fp ) \
+ _CPU_Context_restore_fp( _fp )
+
+/**
+ * @brief Save Floating Point Context Area
+ *
+ * This routine saves the current floating point context
+ * in the @a _fp area.
+ *
+ * @param[in] _fp points to the floating point context area to restore.
+ */
+#define _Context_Save_fp( _fp ) \
+ _CPU_Context_save_fp( _fp )
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/copyrt.h b/cpukit/score/include/rtems/score/copyrt.h
new file mode 100644
index 0000000000..c89806b920
--- /dev/null
+++ b/cpukit/score/include/rtems/score/copyrt.h
@@ -0,0 +1,42 @@
+/**
+ * @file rtems/score/copyrt.h
+ *
+ * This include file contains the copyright notice for RTEMS
+ * which is included in every binary copy of the executive.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_COPYRT_H
+#define _RTEMS_SCORE_COPYRT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This is the copyright string for RTEMS.
+ */
+#ifdef SCORE_INIT
+const char _Copyright_Notice[] =
+"COPYRIGHT (c) 1989-2004.\n\
+On-Line Applications Research Corporation (OAR).\n";
+#else
+extern const char _Copyright_Notice[];
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/coremsg.h b/cpukit/score/include/rtems/score/coremsg.h
new file mode 100644
index 0000000000..08343a1e19
--- /dev/null
+++ b/cpukit/score/include/rtems/score/coremsg.h
@@ -0,0 +1,424 @@
+/**
+ * @file rtems/score/coremsg.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Message queue Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_COREMSG_H
+#define _RTEMS_SCORE_COREMSG_H
+
+/**
+ * @defgroup ScoreMessageQueue Message Queue Handler
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * Message Queue services used in all of the APIs supported by RTEMS.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <limits.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/watchdog.h>
+
+/**
+ * @brief Message Queue MP Callback Prototype
+ *
+ * The following type defines the callout which the API provides
+ * to support global/multiprocessor operations on message_queues.
+ */
+typedef void ( *CORE_message_queue_API_mp_support_callout )(
+ Thread_Control *,
+ Objects_Id
+ );
+
+/**
+ * @brief Message Buffer Contents Management Structure
+ *
+ * The following defines the data types needed to manipulate
+ * the contents of message buffers.
+ *
+ * @note The buffer field is normally longer than a single uint32_t
+ * but since messages are variable length we just make a ptr to 1.
+ */
+typedef struct {
+ /** This field is the size of this message. */
+ uint32_t size;
+ /** This field contains the actual message. */
+ uint32_t buffer[1];
+} CORE_message_queue_Buffer;
+
+/**
+ * @brief Message Structure
+ *
+ * The following records define the organization of a message
+ * buffer.
+ */
+typedef struct {
+ /** This element allows this structure to be placed on chains. */
+ Chain_Node Node;
+ /** This field is the priority of this message. */
+ int priority;
+ /** This field points to the contents of the message. */
+ CORE_message_queue_Buffer Contents;
+} CORE_message_queue_Buffer_control;
+
+/**
+ * @brief Message Queue Blocking Disciplines
+ *
+ * This enumerated types defines the possible blocking disciplines
+ * for a message queue.
+ */
+typedef enum {
+ /** This value indicates that pending messages are in FIFO order. */
+ CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO,
+ /** This value indicates that pending messages are in priority order. */
+ CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY
+} CORE_message_queue_Disciplines;
+
+/**
+ * @brief Message Priority for Appending
+ *
+ * This is the priority constant used when appending messages onto
+ * a message queue.
+ */
+#define CORE_MESSAGE_QUEUE_SEND_REQUEST INT_MAX
+
+/**
+ * @brief Message Priority for Prepending
+ *
+ * This is the priority constant used when prepending messages onto
+ * a message queue.
+ */
+#define CORE_MESSAGE_QUEUE_URGENT_REQUEST INT_MIN
+
+/**
+ * @brief Message Insertion Operation Types
+ *
+ * The following type details the modes in which a message
+ * may be submitted to a message queue. The message may be posted
+ * in a send or urgent fashion.
+ *
+ * @note All other values are message priorities. Numerically smaller
+ * priorities indicate higher priority messages.
+ */
+typedef int CORE_message_queue_Submit_types;
+
+/**
+ * @brief Core Message Queue Return Statuses
+ *
+ * This enumerated type defines the possible set of Core Message
+ * Queue handler return statuses.
+ */
+typedef enum {
+ /** This value indicates the operation completed sucessfully. */
+ CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL,
+ /** This value indicates that the message was too large for this queue. */
+ CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE,
+ /** This value indicates that there are too many messages pending. */
+ CORE_MESSAGE_QUEUE_STATUS_TOO_MANY,
+ /** This value indicates that a receive was unsuccessful. */
+ CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED,
+ /** This value indicates that a blocking send was unsuccessful. */
+ CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT,
+ /** This value indicates that the message queue being blocked upon
+ * was deleted while the thread was waiting.
+ */
+ CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED,
+ /** This value indicates that the thread had to timeout while waiting
+ * to receive a message because one did not become available.
+ */
+ CORE_MESSAGE_QUEUE_STATUS_TIMEOUT,
+ /** This value indicates that a blocking receive was unsuccessful. */
+ CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT
+} CORE_message_queue_Status;
+
+/**
+ * @brief Message Queue Attributes Type
+ *
+ * The following defines the control block used to manage the
+ * attributes of each message queue.
+ */
+typedef struct {
+ /** This field specifies the order in which blocking tasks will be ordered. */
+ CORE_message_queue_Disciplines discipline;
+} CORE_message_queue_Attributes;
+
+/**
+ * @brief Message Queue Notification Callback Prototype
+ *
+ * The following defines the type for a Notification handler. A notification
+ * handler is invoked when the message queue makes a 0->1 transition on
+ * pending messages.
+ */
+typedef void (*CORE_message_queue_Notify_Handler)( void * );
+
+/**
+ * @brief Core Message Queue Control Structure
+ *
+ * The following defines the control block used to manage each
+ * Message Queue
+ */
+typedef struct {
+ /** This field is the Waiting Queue used to manage the set of tasks
+ * which are blocked waiting to receive a message from this queue.
+ */
+ Thread_queue_Control Wait_queue;
+ /** This element is the set of attributes which define this instance's
+ * behavior.
+ */
+ CORE_message_queue_Attributes Attributes;
+ /** This element is maximum number of messages which may be pending
+ * at any given time.
+ */
+ uint32_t maximum_pending_messages;
+ /** This element is the number of messages which are currently pending.
+ */
+ uint32_t number_of_pending_messages;
+ /** This is the size in bytes of the largest message which may be
+ * sent via this queue.
+ */
+ uint32_t maximum_message_size;
+ /** This chain is the set of pending messages. It may be ordered by
+ * message priority or in FIFO order.
+ */
+ Chain_Control Pending_messages;
+ /** This is the address of the memory allocated for message buffers.
+ * It is allocated are part of message queue initialization and freed
+ * as part of destroying it.
+ */
+ CORE_message_queue_Buffer *message_buffers;
+ /** This is the routine invoked when the message queue transitions
+ * from zero (0) messages pending to one (1) message pending.
+ */
+ CORE_message_queue_Notify_Handler notify_handler;
+ /** This field is the argument passed to the @ref notify_argument. */
+ void *notify_argument;
+ /** This chain is the set of inactive messages. A message is inactive
+ * when it does not contain a pending message.
+ */
+ Chain_Control Inactive_messages;
+} CORE_message_queue_Control;
+
+/**
+ * @brief Initialize a Message Queue
+ *
+ * This routine initializes @a the_message_queue based on the parameters passed.
+ *
+ * @param[in] the_message_queue points to the message queue to initialize
+ * @param[in] the_message_queue_attributes points to the attributes that
+ * will be used with this message queue instance
+ * @param[in] maximum_pending_messages is the maximum number of messages
+ * that will be allowed to pend at any given time
+ * @param[in] maximum_message_size is the size of largest message that
+ * may be sent to this message queue instance
+ *
+ * @return TRUE if the message queue can be initialized. In general,
+ * FALSE will only be returned if memory for the pending
+ * messages cannot be allocated.
+ */
+boolean _CORE_message_queue_Initialize(
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Attributes *the_message_queue_attributes,
+ uint32_t maximum_pending_messages,
+ uint32_t maximum_message_size
+);
+
+/**
+ * @brief Close a Message Queue
+ *
+ * This function closes a message by returning all allocated space and
+ * flushing @a the_message_queue's task wait queue.
+ *
+ * @param[in] the_message_queue points to the message queue to close
+ * @param[in] remote_extract_callout is the routine to call for each thread
+ * that is extracted from the set of waiting threads
+ * @param[in] status is the status that each waiting thread will return
+ * from it's blocking service
+ */
+void _CORE_message_queue_Close(
+ CORE_message_queue_Control *the_message_queue,
+ Thread_queue_Flush_callout remote_extract_callout,
+ uint32_t status
+);
+
+/**
+ * @brief Flush Pending Messages
+ *
+ * This function flushes @a the_message_queue's pending message queue. The
+ * number of messages flushed from the queue is returned.
+ *
+ * @param[in] the_message_queue points to the message queue to flush
+ *
+ * @return This method returns the number of message pending messages flushed.
+ */
+uint32_t _CORE_message_queue_Flush(
+ CORE_message_queue_Control *the_message_queue
+);
+
+/**
+ * @brief Flush Messages Support Routine
+ *
+ * This routine flushes all outstanding messages and returns
+ * them to the inactive message chain.
+ *
+ * @param[in] the_message_queue points to the message queue to flush
+ *
+ * @return This method returns the number of message pending messages flushed.
+ */
+uint32_t _CORE_message_queue_Flush_support(
+ CORE_message_queue_Control *the_message_queue
+);
+
+/**
+ * @brief Flush Waiting Threads.
+ *
+ * This function flushes the threads which are blocked on
+ * @a the_message_queue's pending message queue. They are
+ * unblocked whether blocked sending or receiving.
+ *
+ * @param[in] the_message_queue points to the message queue to flush
+ */
+void _CORE_message_queue_Flush_waiting_threads(
+ CORE_message_queue_Control *the_message_queue
+);
+
+/**
+ * @brief Broadcast a Message to the Message Queue
+ *
+ * This function sends a message for every thread waiting on the queue and
+ * returns the number of threads made ready by the message.
+ *
+ * @param[in] the_message_queue points to the message queue
+ * @param[in] buffer is the starting address of the message to broadcast
+ * @param[in] size is the size of the message being broadcast
+ * @param[in] id is the RTEMS object Id associated with this message queue.
+ * It is used when unblocking a remote thread.
+ * @param[in] api_message_queue_mp_support is the routine to invoke if
+ * a thread that is unblocked is actually a remote thread.
+ * @param[out] count points to the variable that will contain the
+ * number of tasks that are sent this message
+ * @return @a *count will contain the number of messages sent
+ * @return indication of the successful completion or reason for failure
+ */
+CORE_message_queue_Status _CORE_message_queue_Broadcast(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ uint32_t size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
+ uint32_t *count
+);
+
+/**
+ * @brief Submit a Message to the Message Queue
+ *
+ * This routine implements the send and urgent message functions. It
+ * processes a message that is to be submitted to the designated
+ * message queue. The message will either be processed as a
+ * send message which it will be inserted at the rear of the queue
+ * or it will be processed as an urgent message which will be inserted
+ * at the front of the queue.
+ *
+ * @param[in] the_message_queue points to the message queue
+ * @param[in] buffer is the starting address of the message to send
+ * @param[in] size is the size of the message being send
+ * @param[in] id is the RTEMS object Id associated with this message queue.
+ * It is used when unblocking a remote thread.
+ * @param[in] api_message_queue_mp_support is the routine to invoke if
+ * a thread that is unblocked is actually a remote thread.
+ * @param[in] submit_type determines whether the message is prepended,
+ * appended, or enqueued in priority order.
+ * @param[in] wait indicates whether the calling thread is willing to block
+ * if the message queue is full.
+ * @param[in] timeout is the maximum number of clock ticks that the calling
+ * thread is willing to block if the message queue is full.
+ * @return indication of the successful completion or reason for failure
+ */
+CORE_message_queue_Status _CORE_message_queue_Submit(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ uint32_t size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
+ CORE_message_queue_Submit_types submit_type,
+ boolean wait,
+ Watchdog_Interval timeout
+);
+
+/**
+ * @brief Size a Message from the Message Queue
+ *
+ * This kernel routine dequeues a message, copies the message buffer to
+ * a given destination buffer, and frees the message buffer to the
+ * inactive message pool. The thread will be blocked if wait is TRUE,
+ * otherwise an error will be given to the thread if no messages are available.
+ *
+ * @param[in] the_message_queue points to the message queue
+ * @param[in] id is the RTEMS object Id associated with this message queue.
+ * It is used when unblocking a remote thread.
+ * @param[in] buffer is the starting address of the message buffer to
+ * to be filled in with a message
+ * @param[in] size is the size of the @a buffer and indicates the maximum
+ * size message that the caller can receive.
+ * @param[in] wait indicates whether the calling thread is willing to block
+ * if the message queue is empty.
+ * @param[in] timeout is the maximum number of clock ticks that the calling
+ * thread is willing to block if the message queue is empty.
+ *
+ * @return indication of the successful completion or reason for failure
+ * @note Returns message priority via return are in TCB.
+ */
+void _CORE_message_queue_Seize(
+ CORE_message_queue_Control *the_message_queue,
+ Objects_Id id,
+ void *buffer,
+ uint32_t *size,
+ boolean wait,
+ Watchdog_Interval timeout
+);
+
+/**
+ * This kernel routine inserts the specified message into the
+ * message queue. It is assumed that the message has been filled
+ * in before this routine is called.
+ *
+ * @param[in] the_message_queue points to the message queue
+ * @param[in] the_message is the message to enqueue
+ * @param[in] submit_type determines whether the message is prepended,
+ * appended, or enqueued in priority order.
+ */
+void _CORE_message_queue_Insert_message(
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message,
+ CORE_message_queue_Submit_types submit_type
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/coremsg.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/coremutex.h b/cpukit/score/include/rtems/score/coremutex.h
new file mode 100644
index 0000000000..4015ac97e4
--- /dev/null
+++ b/cpukit/score/include/rtems/score/coremutex.h
@@ -0,0 +1,360 @@
+/**
+ * @file rtems/score/coremutex.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Mutex Handler. A mutex is an enhanced version of the standard
+ * Dijkstra binary semaphore used to provide synchronization and mutual
+ * exclusion capabilities.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_COREMUTEX_H
+#define _RTEMS_SCORE_COREMUTEX_H
+
+/**
+ * @defgroup ScoreMutex Mutex Handler
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * Mutex services used in all of the APIs supported by RTEMS.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/sysstate.h>
+
+/**
+ * @brief MP Support Callback Prototype
+ *
+ * The following type defines the callout which the API provides
+ * to support global/multiprocessor operations on mutexes.
+ */
+typedef void ( *CORE_mutex_API_mp_support_callout )(
+ Thread_Control *,
+ Objects_Id
+ );
+
+/**
+ * @brief Blocking Disciplines Enumerated Type
+ *
+ * This enumerated type defines the blocking disciplines for a mutex.
+ */
+typedef enum {
+ /** This specifies that threads will wait for the mutex in FIFO order. */
+ CORE_MUTEX_DISCIPLINES_FIFO,
+ /** This specifies that threads will wait for the mutex in priority order. */
+ CORE_MUTEX_DISCIPLINES_PRIORITY,
+ /** This specifies that threads will wait for the mutex in priority order.
+ * Additionally, the Priority Inheritance Protocol will be in effect.
+ */
+ CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT,
+ /** This specifies that threads will wait for the mutex in priority order.
+ * Additionally, the Priority Ceiling Protocol will be in effect.
+ */
+ CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
+} CORE_mutex_Disciplines;
+
+/**
+ * @brief Mutex method return statuses
+ *
+ * This enumerated type defines the possible Mutex handler return statuses.
+ */
+typedef enum {
+ /** This status indicates that the operation completed successfully. */
+ CORE_MUTEX_STATUS_SUCCESSFUL,
+ /** This status indicates that the calling task did not want to block
+ * and the operation was unable to complete immediately because the
+ * resource was unavailable.
+ */
+ CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT,
+ /** This status indicates that an attempt was made to relock a mutex
+ * for which nesting is not configured.
+ */
+ CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED,
+ /** This status indicates that an attempt was made to release a mutex
+ * by a thread other than the thread which locked it.
+ */
+ CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE,
+ /** This status indicates that the thread was blocked waiting for an
+ * operation to complete and the mutex was deleted.
+ */
+ CORE_MUTEX_WAS_DELETED,
+ /** This status indicates that the calling task was willing to block
+ * but the operation was unable to complete within the time allotted
+ * because the resource never became available.
+ */
+ CORE_MUTEX_TIMEOUT,
+ /** This status indicates that a thread of logically greater importance
+ * than the ceiling priority attempted to lock this mutex.
+ */
+ CORE_MUTEX_STATUS_CEILING_VIOLATED
+} CORE_mutex_Status;
+
+/**
+ * @brief Mutex Lock Nesting Behavior Enumeration
+ *
+ * This enumerated type defines the possible behaviors for
+ * lock nesting.
+ */
+typedef enum {
+ /**
+ * This sequence has no blocking or errors:
+ *
+ * + lock(m)
+ * + lock(m)
+ * + unlock(m)
+ * + unlock(m)
+ */
+ CORE_MUTEX_NESTING_ACQUIRES,
+ /**
+ * This sequence returns an error at the indicated point:
+ *
+ * + lock(m)
+ * + lock(m) - already locked error
+ * + unlock(m)
+ */
+ CORE_MUTEX_NESTING_IS_ERROR,
+ /**
+ * This sequence performs as indicated:
+ * + lock(m)
+ * + lock(m) - deadlocks or timeouts
+ * + unlock(m) - releases
+ */
+ CORE_MUTEX_NESTING_BLOCKS
+} CORE_mutex_Nesting_behaviors;
+
+/**
+ * This is the value of a mutex when it is unlocked.
+ */
+#define CORE_MUTEX_UNLOCKED 1
+
+/**
+ * This is the value of a mutex when it is locked.
+ */
+#define CORE_MUTEX_LOCKED 0
+
+/**
+ * @brief Core Mutex Attributes
+ *
+ * The following defines the control block used to manage the
+ * attributes of each mutex.
+ */
+typedef struct {
+ /** This field determines what the behavior of this mutex instance will
+ * be when attempting to acquire the mutex when it is already locked.
+ */
+ CORE_mutex_Nesting_behaviors lock_nesting_behavior;
+ /** When this field is TRUE, then only the thread that locked the mutex
+ * is allowed to unlock it.
+ */
+ boolean only_owner_release;
+ /** This field indicates whether threads waiting on the mutex block in
+ * FIFO or priority order.
+ */
+ CORE_mutex_Disciplines discipline;
+ /** This field contains the ceiling priority to be used if that protocol
+ * is selected.
+ */
+ Priority_Control priority_ceiling;
+} CORE_mutex_Attributes;
+
+/**
+ * @brief Core Mutex Control Structure
+ *
+ * The following defines the control block used to manage each mutex.
+ */
+typedef struct {
+ /** This field is the Waiting Queue used to manage the set of tasks
+ * which are blocked waiting to lock the mutex.
+ */
+ Thread_queue_Control Wait_queue;
+ /** This element is the set of attributes which define this instance's
+ * behavior.
+ */
+ CORE_mutex_Attributes Attributes;
+ /** This element contains the current state of the mutex.
+ */
+ uint32_t lock;
+ /** This element contains the number of times the mutex has been acquired
+ * nested. This must be zero (0) before the mutex is actually unlocked.
+ */
+ uint32_t nest_count;
+ /** This is the number of waiting threads. */
+ uint32_t blocked_count;
+ /** This element points to the thread which is currently holding this mutex.
+ * The holder is the last thread to successfully lock the mutex and which
+ * has not unlocked it. If the thread is not locked, there is no holder.
+ */
+ Thread_Control *holder;
+ /** This element contains the object Id of the holding thread. */
+ Objects_Id holder_id;
+} CORE_mutex_Control;
+
+/**
+ * @brief Initialize a Core Mutex
+ *
+ * This routine initializes the mutex based on the parameters passed.
+ *
+ * @param[in] the_mutex is the mutex to initalize
+ * @param[in] the_mutex_attributes is the attributes associated with this
+ * mutex instance
+ * @param[in] initial_lock is the initial value of the mutex
+ */
+void _CORE_mutex_Initialize(
+ CORE_mutex_Control *the_mutex,
+ CORE_mutex_Attributes *the_mutex_attributes,
+ uint32_t initial_lock
+);
+
+#ifndef __RTEMS_APPLICATION__
+/**
+ * @brief Seize Mutex with Quick Success Path
+ *
+ * This routine attempts to receive a unit from the_mutex.
+ * If a unit is available or if the wait flag is FALSE, then the routine
+ * returns. Otherwise, the calling task is blocked until a unit becomes
+ * available.
+ *
+ * @param[in] the_mutex is the mutex to attempt to lock
+ * @param[in] level_p is the interrupt level holder
+ *
+ * @return This routine returns 0 if "trylock" can resolve whether or not
+ * the mutex is immediately obtained or there was an error attempting to
+ * get it. It returns 1 to indicate that the caller cannot obtain
+ * the mutex and will have to block to do so.
+ *
+ * @note For performance reasons, this routine is implemented as
+ * a macro that uses two support routines.
+ */
+RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock(
+ CORE_mutex_Control *the_mutex,
+ ISR_Level *level_p
+);
+
+/**
+ * @brief Seize Mutex with Blockign
+ *
+ * This routine performs the blocking portion of a mutex obtain.
+ * It is an actual subroutine and is not implemented as something
+ * that may be inlined.
+ *
+ * @param[in] the_mutex is the mutex to attempt to lock
+ * @param[in] timeout is the maximum number of ticks to block
+ */
+void _CORE_mutex_Seize_interrupt_blocking(
+ CORE_mutex_Control *the_mutex,
+ Watchdog_Interval timeout
+);
+
+/**
+ * @brief Sieze Interrupt Wrapper
+ *
+ * This routine attempts to obtain the mutex. If the mutex is available,
+ * then it will return immediately. Otherwise, it will invoke the
+ * support routine @a _Core_mutex_Seize_interrupt_blocking.
+ *
+ * @param[in] _the_mutex is the mutex to attempt to lock
+ * @param[in] _id is the Id of the owning API level Semaphore object
+ * @param[in] _wait is TRUE if the thread is willing to wait
+ * @param[in] _timeout is the maximum number of ticks to block
+ * @param[in] _level is a temporary variable used to contain the ISR
+ * disable level cookie
+ *
+ * @note If the mutex is called from an interrupt service routine,
+ * with context switching disabled, or before multitasking,
+ * then a fatal error is generated.
+ */
+#define _CORE_mutex_Seize( \
+ _the_mutex, _id, _wait, _timeout, _level ) \
+ do { \
+ if ( _Thread_Dispatch_disable_level \
+ && (_wait) \
+ && (_System_state_Get() >= SYSTEM_STATE_BEGIN_MULTITASKING ) \
+ ) { \
+ _Internal_error_Occurred( \
+ INTERNAL_ERROR_CORE, \
+ FALSE, \
+ 18 /* called from wrong environment */); \
+ } \
+ if ( _CORE_mutex_Seize_interrupt_trylock( _the_mutex, &_level ) ) { \
+ if ( !_wait ) { \
+ _ISR_Enable( _level ); \
+ _Thread_Executing->Wait.return_code = \
+ CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT; \
+ } else { \
+ _Thread_queue_Enter_critical_section( &(_the_mutex)->Wait_queue ); \
+ _Thread_Executing->Wait.queue = &(_the_mutex)->Wait_queue; \
+ _Thread_Executing->Wait.id = _id; \
+ _Thread_Disable_dispatch(); \
+ _ISR_Enable( _level ); \
+ _CORE_mutex_Seize_interrupt_blocking( _the_mutex, _timeout ); \
+ } \
+ } \
+ } while (0)
+
+/**
+ * @brief Surrender the Mutex
+ *
+ * This routine frees a unit to the mutex. If a task was blocked waiting for
+ * a unit from this mutex, then that task will be readied and the unit
+ * given to that task. Otherwise, the unit will be returned to the mutex.
+ *
+ * @param[in] the_mutex is the mutex to surrender
+ * @param[in] id is the id of the RTEMS Object associated with this mutex
+ * @param[in] api_mutex_mp_support is the routine that will be called when
+ * unblocking a remote mutex
+ *
+ * @return an indication of whether the routine succeeded or failed
+ */
+CORE_mutex_Status _CORE_mutex_Surrender(
+ CORE_mutex_Control *the_mutex,
+ Objects_Id id,
+ CORE_mutex_API_mp_support_callout api_mutex_mp_support
+);
+
+/**
+ * @brief Flush all waiting threads
+ *
+ * This routine assists in the deletion of a mutex by flushing the associated
+ * wait queue.
+ *
+ * @param[in] the_mutex is the mutex to flush
+ * @param[in] remote_extract_callout is the routine to invoke when a remote
+ * thread is extracted
+ * @param[in] status is the status value which each unblocked thread will
+ * return to its caller.
+ */
+void _CORE_mutex_Flush(
+ CORE_mutex_Control *the_mutex,
+ Thread_queue_Flush_callout remote_extract_callout,
+ uint32_t status
+);
+
+#include <rtems/score/coremutex.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/coresem.h b/cpukit/score/include/rtems/score/coresem.h
new file mode 100644
index 0000000000..54621fce84
--- /dev/null
+++ b/cpukit/score/include/rtems/score/coresem.h
@@ -0,0 +1,196 @@
+/**
+ * @file rtems/score/coresem.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Counting Semaphore Handler. A counting semaphore is the
+ * standard Dijkstra binary semaphore used to provide synchronization
+ * and mutual exclusion capabilities.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CORESEM_H
+#define _RTEMS_SCORE_CORESEM_H
+
+/**
+ * @defgroup ScoreSemaphore Semaphore Handler
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * Semaphore services used in all of the APIs supported by RTEMS.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/watchdog.h>
+
+/**
+ * The following type defines the callout which the API provides
+ * to support global/multiprocessor operations on semaphores.
+ */
+typedef void ( *CORE_semaphore_API_mp_support_callout )(
+ Thread_Control *,
+ Objects_Id
+ );
+
+/**
+ * Blocking disciplines for a semaphore.
+ */
+typedef enum {
+ /** This specifies that threads will wait for the semaphore in FIFO order. */
+ CORE_SEMAPHORE_DISCIPLINES_FIFO,
+ /** This specifies that threads will wait for the semaphore in
+ * priority order.
+ */
+ CORE_SEMAPHORE_DISCIPLINES_PRIORITY
+} CORE_semaphore_Disciplines;
+
+/**
+ * Core Semaphore handler return statuses.
+ */
+typedef enum {
+ /** This status indicates that the operation completed successfully. */
+ CORE_SEMAPHORE_STATUS_SUCCESSFUL,
+ /** This status indicates that the calling task did not want to block
+ * and the operation was unable to complete immediately because the
+ * resource was unavailable.
+ */
+ CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT,
+ /** This status indicates that the thread was blocked waiting for an
+ * operation to complete and the semaphore was deleted.
+ */
+ CORE_SEMAPHORE_WAS_DELETED,
+ /** This status indicates that the calling task was willing to block
+ * but the operation was unable to complete within the time allotted
+ * because the resource never became available.
+ */
+ CORE_SEMAPHORE_TIMEOUT,
+ /** This status indicates that an attempt was made to unlock the semaphore
+ * and this would have made its count greater than that allowed.
+ */
+ CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED
+} CORE_semaphore_Status;
+
+/**
+ * The following defines the control block used to manage the
+ * attributes of each semaphore.
+ */
+typedef struct {
+ /** This element indicates the maximum count this semaphore may have. */
+ uint32_t maximum_count;
+ /** This field indicates whether threads waiting on the semaphore block in
+ * FIFO or priority order.
+ */
+ CORE_semaphore_Disciplines discipline;
+} CORE_semaphore_Attributes;
+
+/**
+ * The following defines the control block used to manage each
+ * counting semaphore.
+ */
+typedef struct {
+ /** This field is the Waiting Queue used to manage the set of tasks
+ * which are blocked waiting to obtain the semaphore.
+ */
+ Thread_queue_Control Wait_queue;
+ /** This element is the set of attributes which define this instance's
+ * behavior.
+ */
+ CORE_semaphore_Attributes Attributes;
+ /** This element contains the current count of this semaphore. */
+ uint32_t count;
+} CORE_semaphore_Control;
+
+/**
+ * This routine initializes the semaphore based on the parameters passed.
+ *
+ * @param[in] the_semaphore is the semaphore to initialize
+ * @param[in] the_semaphore_attributes define the behavior of this instance
+ * @param[in] initial_value is the initial count of the semaphore
+ */
+void _CORE_semaphore_Initialize(
+ CORE_semaphore_Control *the_semaphore,
+ CORE_semaphore_Attributes *the_semaphore_attributes,
+ uint32_t initial_value
+);
+
+/**
+ * This routine attempts to receive a unit from the_semaphore.
+ * If a unit is available or if the wait flag is FALSE, then the routine
+ * returns. Otherwise, the calling task is blocked until a unit becomes
+ * available.
+ *
+ * @param[in] the_semaphore is the semaphore to seize
+ * @param[in] id is the Id of the API level Semaphore object associated
+ * with this instance of a SuperCore Semaphore
+ * @param[in] wait is TRUE if the calling thread is willing to wait
+ * @param[in] timeout is the number of ticks the calling thread is willing
+ * to wait if @a wait is TRUE.
+ */
+void _CORE_semaphore_Seize(
+ CORE_semaphore_Control *the_semaphore,
+ Objects_Id id,
+ boolean wait,
+ Watchdog_Interval timeout
+);
+
+/**
+ * This routine frees a unit to the semaphore. If a task was blocked waiting
+ * for a unit from this semaphore, then that task will be readied and the unit
+ * given to that task. Otherwise, the unit will be returned to the semaphore.
+ *
+ * @param[in] the_semaphore is the semaphore to surrender
+ * @param[in] id is the Id of the API level Semaphore object associated
+ * with this instance of a SuperCore Semaphore
+ * @param[in] api_semaphore_mp_support is the routine to invoke if the
+ * thread unblocked is remote
+ *
+ * @return an indication of whether the routine succeeded or failed
+ */
+CORE_semaphore_Status _CORE_semaphore_Surrender(
+ CORE_semaphore_Control *the_semaphore,
+ Objects_Id id,
+ CORE_semaphore_API_mp_support_callout api_semaphore_mp_support
+);
+
+/**
+ * This routine assists in the deletion of a semaphore by flushing the
+ * associated wait queue.
+ *
+ * @param[in] the_semaphore is the semaphore to flush
+ * @param[in] remote_extract_callout is the routine to invoke if the
+ * thread unblocked is remote
+ * @param[in] status is the status to be returned to the unblocked thread
+ */
+void _CORE_semaphore_Flush(
+ CORE_semaphore_Control *the_semaphore,
+ Thread_queue_Flush_callout remote_extract_callout,
+ uint32_t status
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/coresem.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/heap.h b/cpukit/score/include/rtems/score/heap.h
new file mode 100644
index 0000000000..c00e2c7098
--- /dev/null
+++ b/cpukit/score/include/rtems/score/heap.h
@@ -0,0 +1,519 @@
+/**
+ * @file rtems/score/heap.h
+ *
+ * This include file contains the information pertaining to the Heap
+ * Handler. A heap is a doubly linked list of variable size
+ * blocks which are allocated using the first fit method. Garbage
+ * collection is performed each time a block is returned to the heap by
+ * coalescing neighbor blocks. Control information for both allocated
+ * and unallocated blocks is contained in the heap space. A heap control
+ * structure contains control information for the heap.
+ *
+ * FIXME: the alignment routines could be made faster should we require only
+ * powers of two to be supported both for 'page_size' and for
+ * 'alignment' arguments. However, both workspace and malloc heaps are
+ * initialized with CPU_HEAP_ALIGNMENT as 'page_size', and while all
+ * the BSPs seem to use CPU_ALIGNMENT (that is power of two) as
+ * CPU_HEAP_ALIGNMENT, for whatever reason CPU_HEAP_ALIGNMENT is only
+ * required to be multiple of CPU_ALIGNMENT and explicitly not
+ * required to be a power of two.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_HEAP_H
+#define _RTEMS_SCORE_HEAP_H
+
+/**
+ * @defgroup ScoreHeap Heap Handler
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * Heap services used in all of the APIs supported by RTEMS.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This type defines unsigned integer type to store 'void*'. Analog of C99
+ * 'uintptr_t'. This should work on 16/32/64 bit architectures.
+ *
+ * FIXME: Something like this should better be defined by
+ * 'rtems/score/types.h' and used here.
+ */
+
+typedef uintptr_t _H_uptr_t;
+
+/**
+ * Forward reference
+ *
+ * @ref Heap_Block
+ */
+typedef struct Heap_Block_struct Heap_Block;
+
+/**
+ * The following defines the data structure used to manage individual blocks
+ * in a heap. When the block is allocated, the 'next' and 'prev' fields, as
+ * well as 'prev_size' field of the next block, are not used by the heap
+ * manager and thus the address returned for the block starts at the address
+ * of the 'next' field and the size of the user accessible area includes the
+ * size of the 'prev_size' field.
+ *
+ * @note The 'next' and 'prev' pointers are only valid when the block is free.
+ * Caution must be taken to ensure that every block is large enough to
+ * hold them and that they are not accessed while the block is actually
+ * allocated (i.e., not free).
+ *
+ * @note The 'prev_size' field is only valid when HEAP_PREV_USED bit is clear
+ * in the 'size' field indicating that previous block is not allocated.
+ * If the bit is set, the 'prev_size' field is part of user-accessible
+ * space of the previous allocated block and thus shouldn't be accessed
+ * by the heap manager code. This trick allows to further decrease
+ * overhead in the used blocks to the size of 'size' field (4 bytes).
+ *
+ */
+
+struct Heap_Block_struct {
+ /** size of prev block (if prev block is free) */
+ uint32_t prev_size;
+ /** size of block in bytes and status of prev block */
+ uint32_t size;
+ /** pointer to the next free block */
+ Heap_Block *next;
+ /** pointer to the previous free block */
+ Heap_Block *prev;
+};
+
+/**
+ * This flag used in the 'size' field of each heap block to indicate
+ * if previous block is free or in use. As sizes are always multiples of
+ * 4, the 2 least significant bits would always be 0, and we use one of them
+ * to store the flag.
+ */
+
+#define HEAP_PREV_USED 1 /* indicates previous block is in use */
+
+/**
+ * The following constants reflect various requirements of the
+ * heap data structures which impact the management of a heap.
+ */
+
+#define HEAP_MIN_BLOCK_SIZE (sizeof(Heap_Block))
+
+/**
+ * Offset of the block header from the block pointer. Equal to the
+ * offsetof(Heap_Block.size).
+ */
+#define HEAP_BLOCK_HEADER_OFFSET (sizeof(uint32_t))
+
+/**
+ * Offset of user data pointer from the block pointer. Equal to the
+ * offsetof(Heap_Block.next).
+ */
+#define HEAP_BLOCK_USER_OFFSET (sizeof(uint32_t) * 2)
+
+/**
+ * Num bytes of overhead in used block. Equal to the sizeof(Heap_Block.size).
+ */
+#define HEAP_BLOCK_USED_OVERHEAD \
+ (HEAP_BLOCK_USER_OFFSET - HEAP_BLOCK_HEADER_OFFSET)
+
+/** Size of the permanent dummy last block. */
+#define HEAP_OVERHEAD HEAP_BLOCK_USER_OFFSET
+
+/**
+ * Run-time heap statistics.
+ *
+ * @note (double)searches/allocs gives mean number of searches per alloc while
+ * max_search gives maximum number of searches ever performed on a
+ * single call to alloc.
+ *
+ * @note the statistics is always gathered. I believe the imposed overhead is
+ * rather small. Feel free to make it compile-time option if you think
+ * the overhead is too high for your application.
+ */
+
+typedef struct Heap_Statistics_tag {
+ /** instance number of this heap */
+ uint32_t instance;
+ /** the size of the memory for heap */
+ uint32_t size;
+ /** current free size */
+ uint32_t free_size;
+ /** minimum free size ever */
+ uint32_t min_free_size;
+ /** current number of free blocks */
+ uint32_t free_blocks;
+ /** maximum number of free blocks ever */
+ uint32_t max_free_blocks;
+ /** current number of used blocks */
+ uint32_t used_blocks;
+ /** maximum number of blocks searched ever */
+ uint32_t max_search;
+ /** total number of successful calls to alloc */
+ uint32_t allocs;
+ /** total number of searches ever */
+ uint32_t searches;
+ /** total number of suceessful calls to free */
+ uint32_t frees;
+ /** total number of successful resizes */
+ uint32_t resizes;
+} Heap_Statistics;
+
+/**
+ * Control block used to manage each heap.
+ */
+typedef struct {
+ /** head and tail of circular list of free blocks */
+ Heap_Block free_list;
+ /** allocation unit and alignment */
+ uint32_t page_size;
+ /** minimum block size aligned on page_size */
+ uint32_t min_block_size;
+ /** first address of memory for the heap */
+ void *begin;
+ /** first address past end of memory for the heap */
+ void *end;
+ /** first valid block address in the heap */
+ Heap_Block *start;
+ /** last valid block address in the heap */
+ Heap_Block *final;
+ /** run-time statistics */
+ Heap_Statistics stats;
+} Heap_Control;
+
+/**
+ * Status codes for _Heap_Extend
+ */
+
+typedef enum {
+ HEAP_EXTEND_SUCCESSFUL,
+ HEAP_EXTEND_ERROR,
+ HEAP_EXTEND_NOT_IMPLEMENTED
+} Heap_Extend_status;
+
+/**
+ * Status codes for _Heap_Resize_block
+ */
+
+typedef enum {
+ HEAP_RESIZE_SUCCESSFUL,
+ HEAP_RESIZE_UNSATISFIED,
+ HEAP_RESIZE_FATAL_ERROR
+} Heap_Resize_status;
+
+/**
+ * Status codes for _Heap_Get_information
+ */
+
+typedef enum {
+ HEAP_GET_INFORMATION_SUCCESSFUL = 0,
+ HEAP_GET_INFORMATION_BLOCK_ERROR
+} Heap_Get_information_status;
+
+/**
+ * Information block returned by the Heap routines used to
+ * obtain heap information. This information is returned about
+ * either free or used blocks.
+ */
+typedef struct {
+ /** Number of blocks of this type. */
+ uint32_t number;
+ /** Largest blocks of this type. */
+ uint32_t largest;
+ /** Total size of the blocks of this type. */
+ uint32_t total;
+} Heap_Information;
+
+/**
+ * Information block returned by _Heap_Get_information
+ */
+typedef struct {
+ /** This field is information on the used blocks in the heap. */
+ Heap_Information Free;
+ /** This field is information on the used blocks in the heap. */
+ Heap_Information Used;
+} Heap_Information_block;
+
+/**
+ * This routine initializes @a the_heap record to manage the
+ * contiguous heap of @a size bytes which starts at @a starting_address.
+ * Blocks of memory are allocated from the heap in multiples of
+ * @a page_size byte units. If @a page_size is 0 or is not multiple of
+ * CPU_ALIGNMENT, it's aligned up to the nearest CPU_ALIGNMENT boundary.
+ *
+ * @param[in] the_heap is the heap to operate upon
+ * @param[in] starting_address is the starting address of the memory for
+ * the heap
+ * @param[in] size is the size in bytes of the memory area for the heap
+ * @param[in] page_size is the size in bytes of the allocation unit
+ *
+ * @return This method returns the maximum memory available. If
+ * unsuccessful, 0 will be returned.
+ */
+uint32_t _Heap_Initialize(
+ Heap_Control *the_heap,
+ void *starting_address,
+ uint32_t size,
+ uint32_t page_size
+);
+
+/**
+ * This routine grows @a the_heap memory area using the size bytes which
+ * begin at @a starting_address.
+ *
+ * @param[in] the_heap is the heap to operate upon
+ * @param[in] starting_address is the starting address of the memory
+ * to add to the heap
+ * @param[in] size is the size in bytes of the memory area to add
+ * @param[in] amount_extended points to a user area to return the
+ * @return a status indicating success or the reason for failure
+ * @return *size filled in with the amount of memory added to the heap
+ */
+Heap_Extend_status _Heap_Extend(
+ Heap_Control *the_heap,
+ void *starting_address,
+ uint32_t size,
+ uint32_t *amount_extended
+);
+
+/**
+ * This function attempts to allocate a block of @a size bytes from
+ * @a the_heap. If insufficient memory is free in @a the_heap to allocate
+ * a block of the requested size, then NULL is returned.
+ *
+ * @param[in] the_heap is the heap to operate upon
+ * @param[in] size is the amount of memory to allocate in bytes
+ * @return NULL if unsuccessful and a pointer to the block if successful
+ */
+void *_Heap_Allocate(
+ Heap_Control *the_heap,
+ uint32_t size
+);
+
+/**
+ * This function attempts to allocate a memory block of @a size bytes from
+ * @a the_heap so that the start of the user memory is aligned on the
+ * @a alignment boundary. If @a alignment is 0, it is set to CPU_ALIGNMENT.
+ * Any other value of @a alignment is taken "as is", i.e., even odd
+ * alignments are possible.
+ * Returns pointer to the start of the memory block if success, NULL if
+ * failure.
+ *
+ * @param[in] the_heap is the heap to operate upon
+ * @param[in] size is the amount of memory to allocate in bytes
+ * @param[in] alignment the required alignment
+ * @return NULL if unsuccessful and a pointer to the block if successful
+ */
+void *_Heap_Allocate_aligned(
+ Heap_Control *the_heap,
+ uint32_t size,
+ uint32_t alignment
+);
+
+/**
+ * This function sets @a *size to the size of the block of user memory
+ * which begins at @a starting_address. The size returned in @a *size could
+ * be greater than the size requested for allocation.
+ * Returns TRUE if the @a starting_address is in the heap, and FALSE
+ * otherwise.
+ *
+ * @param[in] the_heap is the heap to operate upon
+ * @param[in] starting_address is the starting address of the user block
+ * to obtain the size of
+ * @param[in] size points to a user area to return the size in
+ * @return TRUE if successfully able to determine the size, FALSE otherwise
+ * @return *size filled in with the size of the user area for this block
+ */
+boolean _Heap_Size_of_user_area(
+ Heap_Control *the_heap,
+ void *starting_address,
+ size_t *size
+);
+
+/**
+ * This function tries to resize in place the block that is pointed to by the
+ * @a starting_address to the new @a size.
+ *
+ * @param[in] the_heap is the heap to operate upon
+ * @param[in] starting_address is the starting address of the user block
+ * to be resized
+ * @param[in] size is the new size
+ * @param[in] old_mem_size points to a user area to return the size of the
+ * user memory area of the block before resizing.
+ * @param[in] avail_mem_size points to a user area to return the size of
+ * the user memory area of the free block that has been enlarged or
+ * created due to resizing, 0 if none.
+ * @return HEAP_RESIZE_SUCCESSFUL if successfully able to resize the block,
+ * HEAP_RESIZE_UNSATISFIED if the block can't be resized in place,
+ * HEAP_RESIZE_FATAL_ERROR if failure
+ * @return *old_mem_size filled in with the size of the user memory area of
+ * the block before resizing.
+ * @return *avail_mem_size filled in with the size of the user memory area
+ * of the free block that has been enlarged or created due to
+ * resizing, 0 if none.
+ */
+Heap_Resize_status _Heap_Resize_block(
+ Heap_Control *the_heap,
+ void *starting_address,
+ uint32_t size,
+ uint32_t *old_mem_size,
+ uint32_t *avail_mem_size
+);
+
+/**
+ * This routine returns the block of memory which begins
+ * at @a starting_address to @a the_heap. Any coalescing which is
+ * possible with the freeing of this routine is performed.
+ *
+ * @param[in] the_heap is the heap to operate upon
+ * @param[in] start_address is the starting address of the user block
+ * to free
+ * @return TRUE if successfully freed, FALSE otherwise
+ */
+boolean _Heap_Free(
+ Heap_Control *the_heap,
+ void *start_address
+);
+
+/**
+ * This routine walks the heap to verify its integrity.
+ *
+ * @param[in] the_heap is the heap to operate upon
+ * @param[in] source is a user specified integer which may be used to
+ * indicate where in the application this was invoked from
+ * @param[in] do_dump is set to TRUE if errors should be printed
+ * @return TRUE if the test passed fine, FALSE otherwise.
+ */
+boolean _Heap_Walk(
+ Heap_Control *the_heap,
+ int source,
+ boolean do_dump
+);
+
+/**
+ * This routine walks the heap and tots up the free and allocated
+ * sizes.
+ *
+ * @param[in] the_heap pointer to heap header
+ * @param[in] the_info pointer to a status information area
+ * @return *the_info is filled with status information
+ * @return 0=success, otherwise heap is corrupt.
+ */
+Heap_Get_information_status _Heap_Get_information(
+ Heap_Control *the_heap,
+ Heap_Information_block *the_info
+);
+
+/**
+ * This heap routine returns information about the free blocks
+ * in the specified heap.
+ *
+ * @param[in] the_heap pointer to heap header.
+ * @param[in] info pointer to the free block information.
+ *
+ * @return free block information filled in.
+ */
+void _Heap_Get_free_information(
+ Heap_Control *the_heap,
+ Heap_Information *info
+);
+
+#if !defined(__RTEMS_APPLICATION__)
+
+/**
+ * A pointer to unsigned integer conversion.
+ */
+#define _H_p2u(_p) ((_H_uptr_t)(_p))
+
+#include <rtems/score/heap.inl>
+
+/**
+ * Convert user requested 'size' of memory block to the block size.
+ *
+ * @note This is an internal routine used by _Heap_Allocate() and
+ * _Heap_Allocate_aligned(). Refer to 'heap.c' for details.
+ *
+ * @param[in] size is the size of the block requested
+ * @param[in] page_size is the page size of this heap instance
+ * @param[in] min_size is minimum size block that should be allocated
+ * from this heap instance
+ *
+ * @return This method returns block size on success, 0 if overflow occured.
+ */
+extern uint32_t _Heap_Calc_block_size(
+ uint32_t size,
+ uint32_t page_size,
+ uint32_t min_size
+);
+
+/**
+ * This method allocates a block of size @a alloc_size from @a the_block
+ * belonging to @a the_heap. Split @a the_block if possible, otherwise
+ * allocate it entirely. When split, make the lower part used, and leave
+ * the upper part free.
+ *
+ * This is an internal routines used by _Heap_Allocate() and
+ * _Heap_Allocate_aligned(). Refer to 'heap.c' for details.
+ *
+ * @param[in] the_heap is the heap to operate upon
+ * @param[in] the_block is the block to allocates the requested size from
+ * @param[in] alloc_size is the requested number of bytes to take out of
+ * the block
+ *
+ * @return This methods returns the size of the allocated block.
+ */
+extern uint32_t _Heap_Block_allocate(
+ Heap_Control* the_heap,
+ Heap_Block* the_block,
+ uint32_t alloc_size
+);
+
+/*
+ * Debug support
+ */
+
+#if defined(RTEMS_DEBUG)
+#define RTEMS_HEAP_DEBUG
+#endif
+
+/**
+ * We do asserts only for heaps with instance number greater than 0 assuming
+ * that the heap used for malloc is initialized first and thus has instance
+ * number 0. Asserting malloc heap may lead to troubles as printf may invoke
+ * malloc thus probably leading to infinite recursion.
+ */
+#if defined(RTEMS_HEAP_DEBUG)
+#include <assert.h>
+
+#define _HAssert(cond_) \
+ do { \
+ if(the_heap->stats.instance && !(cond_)) \
+ __assert(__FILE__, __LINE__, #cond_); \
+ } while(0)
+
+#else /* !defined(RTEMS_HEAP_DEBUG) */
+
+#define _HAssert(cond_) ((void)0)
+
+#endif /* !defined(RTEMS_HEAP_DEBUG) */
+
+#endif /* !defined(__RTEMS_APPLICATION__) */
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/interr.h b/cpukit/score/include/rtems/score/interr.h
new file mode 100644
index 0000000000..a9fb98c0ae
--- /dev/null
+++ b/cpukit/score/include/rtems/score/interr.h
@@ -0,0 +1,103 @@
+/**
+ * @file rtems/score/interr.h
+ *
+ * This include file contains constants and prototypes related
+ * to the Internal Error Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_INTERR_H
+#define _RTEMS_SCORE_INTERR_H
+
+/**
+ * @defgroup ScoreIntErr Internal Error Handler
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * Semaphore services used in all of the APIs supported by RTEMS.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This type lists the possible sources from which an error
+ * can be reported.
+ */
+typedef enum {
+ INTERNAL_ERROR_CORE,
+ INTERNAL_ERROR_RTEMS_API,
+ INTERNAL_ERROR_POSIX_API,
+ INTERNAL_ERROR_ITRON_API
+} Internal_errors_Source;
+
+/**
+ * A list of errors which are generated internally by the executive core.
+ */
+typedef enum {
+ INTERNAL_ERROR_NO_CONFIGURATION_TABLE,
+ INTERNAL_ERROR_NO_CPU_TABLE,
+ INTERNAL_ERROR_INVALID_WORKSPACE_ADDRESS,
+ INTERNAL_ERROR_TOO_LITTLE_WORKSPACE,
+ INTERNAL_ERROR_WORKSPACE_ALLOCATION,
+ INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL,
+ INTERNAL_ERROR_THREAD_EXITTED,
+ INTERNAL_ERROR_INCONSISTENT_MP_INFORMATION,
+ INTERNAL_ERROR_INVALID_NODE,
+ INTERNAL_ERROR_NO_MPCI,
+ INTERNAL_ERROR_BAD_PACKET,
+ INTERNAL_ERROR_OUT_OF_PACKETS,
+ INTERNAL_ERROR_OUT_OF_GLOBAL_OBJECTS,
+ INTERNAL_ERROR_OUT_OF_PROXIES,
+ INTERNAL_ERROR_INVALID_GLOBAL_ID,
+ INTERNAL_ERROR_BAD_STACK_HOOK,
+ INTERNAL_ERROR_BAD_ATTRIBUTES
+} Internal_errors_Core_list;
+
+/**
+ * This type holds the fatal error information.
+ */
+typedef struct {
+ /** This is the source of the error. */
+ Internal_errors_Source the_source;
+ /** This indicates if the error is internal of external. */
+ boolean is_internal;
+ /** This is the error code. */
+ uint32_t the_error;
+} Internal_errors_Information;
+
+/**
+ * When a fatal error occurs, the error information is stored here.
+ */
+SCORE_EXTERN Internal_errors_Information Internal_errors_What_happened;
+
+/** @brief Internal error Occurred
+ *
+ * This routine is invoked when the application or the executive itself
+ * determines that a fatal error has occurred.
+ */
+void _Internal_error_Occurred(
+ Internal_errors_Source the_source,
+ boolean is_internal,
+ uint32_t the_error
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/isr.h b/cpukit/score/include/rtems/score/isr.h
new file mode 100644
index 0000000000..1359e91fd8
--- /dev/null
+++ b/cpukit/score/include/rtems/score/isr.h
@@ -0,0 +1,212 @@
+/**
+ * @file rtems/score/isr.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the management of processor interrupt levels. This handler
+ * supports interrupt critical sections, vectoring of user interrupt
+ * handlers, nesting of interrupts, and manipulating interrupt levels.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_ISR_H
+#define _RTEMS_SCORE_ISR_H
+
+/**
+ * @defgroup ScoreISR ISR Handler
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * ISR services used in all of the APIs supported by RTEMS.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The following type defines the control block used to manage
+ * the interrupt level portion of the status register.
+ */
+typedef uint32_t ISR_Level;
+
+/**
+ * The following type defines the type used to manage the vectors.
+ */
+typedef uint32_t ISR_Vector_number;
+
+/**
+ * Return type for ISR Handler
+ */
+typedef void ISR_Handler;
+
+/**
+ * Pointer to an ISR Handler
+ */
+#if (CPU_ISR_PASSES_FRAME_POINTER == 1)
+typedef ISR_Handler ( *ISR_Handler_entry )(
+ ISR_Vector_number,
+ CPU_Interrupt_frame *
+ );
+#else
+typedef ISR_Handler ( *ISR_Handler_entry )(
+ ISR_Vector_number
+ );
+#endif
+
+/**
+ * This constant promotes out the number of vectors truly supported by
+ * the current CPU being used. This is usually the number of distinct vectors
+ * the cpu can vector.
+ */
+#define ISR_NUMBER_OF_VECTORS CPU_INTERRUPT_NUMBER_OF_VECTORS
+
+/**
+ * This constant promotes out the highest valid interrupt vector number.
+ */
+#define ISR_INTERRUPT_MAXIMUM_VECTOR_NUMBER CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER
+
+/**
+ * The following is TRUE if signals have been sent to the currently
+ * executing thread by an ISR handler.
+ */
+SCORE_EXTERN boolean _ISR_Signals_to_thread_executing;
+
+/**
+ * The following contains the interrupt service routine nest level.
+ * When this variable is zero, a thread is executing.
+ */
+SCORE_EXTERN volatile uint32_t _ISR_Nest_level;
+
+/**
+ * The following declares the Vector Table. Application
+ * interrupt service routines are vectored by the ISR Handler via this table.
+ */
+SCORE_EXTERN ISR_Handler_entry *_ISR_Vector_table;
+
+/**
+ * This routine performs the initialization necessary for this handler.
+ */
+void _ISR_Handler_initialization ( void );
+
+/**
+ * This routine disables all interrupts so that a critical section
+ * of code can be executing without being interrupted. Upon return,
+ * the argument _level will contain the previous interrupt mask level.
+ */
+#define _ISR_Disable( _level ) \
+ do { \
+ _CPU_ISR_Disable( _level ); \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ } while (0)
+
+/**
+ * This routine enables interrupts to the previous interrupt mask
+ * LEVEL. It is used at the end of a critical section of code to
+ * enable interrupts so they can be processed again.
+ */
+#define _ISR_Enable( _level ) \
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _CPU_ISR_Enable( _level ); \
+ } while (0)
+
+/**
+ * This routine temporarily enables interrupts to the previous
+ * interrupt mask level and then disables all interrupts so that
+ * the caller can continue into the second part of a critical
+ * section. This routine is used to temporarily enable interrupts
+ * during a long critical section. It is used in long sections of
+ * critical code when a point is reached at which interrupts can
+ * be temporarily enabled. Deciding where to flash interrupts
+ * in a long critical section is often difficult and the point
+ * must be selected with care to ensure that the critical section
+ * properly protects itself.
+ */
+#define _ISR_Flash( _level ) \
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _CPU_ISR_Flash( _level ); \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ } while (0)
+
+/**
+ * This routine installs new_handler as the interrupt service routine
+ * for the specified vector. The previous interrupt service routine is
+ * returned as old_handler.
+ */
+#define _ISR_Install_vector( _vector, _new_handler, _old_handler ) \
+ _CPU_ISR_install_vector( _vector, _new_handler, _old_handler )
+
+/**
+ * This routine returns the current interrupt level.
+ */
+#define _ISR_Get_level() \
+ _CPU_ISR_Get_level()
+
+/**
+ * This routine sets the current interrupt level to that specified
+ * by new_level. The new interrupt level is effective when the
+ * routine exits.
+ */
+#define _ISR_Set_level( _new_level ) \
+ _CPU_ISR_Set_level( _new_level )
+
+/**
+ * This routine is the interrupt dispatcher. ALL interrupts
+ * are vectored to this routine so that minimal context can be saved
+ * and setup performed before the application's high-level language
+ * interrupt service routine is invoked. After the application's
+ * interrupt service routine returns control to this routine, it
+ * will determine if a thread dispatch is necessary. If so, it will
+ * ensure that the necessary thread scheduling operations are
+ * performed when the outermost interrupt service routine exits.
+ *
+ * @note Implemented in assembly language.
+ */
+void _ISR_Handler( void );
+
+/**
+ * This routine provides a wrapper so that the routine
+ * @ref _Thread_Dispatch can be invoked when a reschedule is necessary
+ * at the end of the outermost interrupt service routine. This
+ * wrapper is necessary to establish the processor context needed
+ * by _Thread_Dispatch and to save the processor context which is
+ * corrupted by _Thread_Dispatch. This context typically consists
+ * of registers which are not preserved across routine invocations.
+ *
+ * @note Implemented in assembly language.
+ */
+void _ISR_Dispatch( void );
+
+/**
+ * This function returns TRUE if the processor is currently servicing
+ * and interrupt and FALSE otherwise. A return value of TRUE indicates
+ * that the caller is an interrupt service routine, NOT a thread. The
+ */
+#if (CPU_PROVIDES_ISR_IS_IN_PROGRESS == TRUE)
+boolean _ISR_Is_in_progress( void );
+#else
+#define _ISR_Is_in_progress() \
+ (_ISR_Nest_level != 0)
+#endif
+
+#include <rtems/score/isr.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/mpci.h b/cpukit/score/include/rtems/score/mpci.h
new file mode 100644
index 0000000000..18abdaf043
--- /dev/null
+++ b/cpukit/score/include/rtems/score/mpci.h
@@ -0,0 +1,424 @@
+/**
+ * @file rtems/score/mpci.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the MPCI layer. It provides mechanisms to utilize packets.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_MPCI_H
+#define _RTEMS_SCORE_MPCI_H
+
+/**
+ * @defgroup ScoreMPCI MPCI Handler
+ *
+ * The MPCI Handler encapsulates functionality which is related to the
+ * generation, receipt, and processing of remote operations in a
+ * multiprocessor system. This handler contains the message passing
+ * support for making remote service calls as well as the server thread
+ * which processes requests from remote nodes.
+*/
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/mppkt.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/score/coresem.h>
+
+/**
+ * The following constants define the stack size requirements for
+ * the system threads.
+ */
+#define MPCI_RECEIVE_SERVER_STACK_SIZE \
+ ( STACK_MINIMUM_SIZE + \
+ CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK + \
+ _CPU_Table.extra_mpci_receive_server_stack \
+ )
+
+/**
+ * The following defines the node number used when a broadcast is desired.
+ */
+#define MPCI_ALL_NODES 0
+
+/**
+ * For packets associated with requests that don't already have a timeout,
+ * use the one specified by this MPCI driver. The value specified by
+ * the MPCI driver sets an upper limit on how long a remote request
+ * should take to complete.
+ */
+#define MPCI_DEFAULT_TIMEOUT 0xFFFFFFFF
+
+/**
+ * This type is returned by all user provided MPCI routines.
+ */
+typedef void MPCI_Entry;
+
+/**
+ * This type defines the prototype for the initization entry point
+ * in an Multiprocessor Communications Interface.
+ */
+typedef MPCI_Entry ( *MPCI_initialization_entry )( void );
+
+/**
+ * This type defines the prototype for the get packet entry point
+ * in an Multiprocessor Communications Interface. The single
+ * parameter will point to the packet allocated.
+ */
+typedef MPCI_Entry ( *MPCI_get_packet_entry )(
+ MP_packet_Prefix **
+ );
+
+/**
+ * This type defines the prototype for the return packet entry point
+ * in an Multiprocessor Communications Interface. The single
+ * parameter will point to a packet previously allocated by the
+ * get packet MPCI entry.
+ */
+typedef MPCI_Entry ( *MPCI_return_packet_entry )(
+ MP_packet_Prefix *
+ );
+
+/**
+ * This type defines the prototype for send get packet entry point
+ * in an Multiprocessor Communications Interface. The single
+ * parameter will point to a packet previously allocated by the
+ * get packet entry point that has been filled in by the caller.
+ */
+typedef MPCI_Entry ( *MPCI_send_entry )(
+ uint32_t,
+ MP_packet_Prefix *
+ );
+
+/**
+ * This type defines the prototype for the receive packet entry point
+ * in an Multiprocessor Communications Interface. The single
+ * parameter will point to a packet allocated and filled in by the
+ * receive packet handler. The caller will block until a packet is
+ * received.
+ */
+typedef MPCI_Entry ( *MPCI_receive_entry )(
+ MP_packet_Prefix **
+ );
+
+/**
+ * This type defines the Multiprocessor Communications
+ * Interface (MPCI) Table. This table defines the user-provided
+ * MPCI which is a required part of a multiprocessor system.
+ *
+ * For non-blocking local operations that become remote operations,
+ * we need a timeout. This is a per-driver timeout: default_timeout
+ */
+typedef struct {
+ /** This fields contains the timeout for MPCI operations in ticks. */
+ uint32_t default_timeout;
+ /** This field contains the maximum size of a packet supported by this
+ * MPCI layer. This size places a limit on the size of a message
+ * which can be transmitted over this interface.
+ **/
+ uint32_t maximum_packet_size;
+ /** This field points to the MPCI initialization entry point. */
+ MPCI_initialization_entry initialization;
+ /** This field points to the MPCI get packet entry point. */
+ MPCI_get_packet_entry get_packet;
+ /** This field points to the MPCI return packet entry point. */
+ MPCI_return_packet_entry return_packet;
+ /** This field points to the MPCI send packet entry point. */
+ MPCI_send_entry send_packet;
+ /** This field points to the MPCI receive packet entry point. */
+ MPCI_receive_entry receive_packet;
+} MPCI_Control;
+
+/**
+ * The following defines the type for packet processing routines
+ * invoked by the MPCI Receive server.
+ */
+typedef void (*MPCI_Packet_processor)( MP_packet_Prefix * );
+
+/**
+ * The following enumerated type defines the list of
+ * internal MP operations.
+ */
+typedef enum {
+ MPCI_PACKETS_SYSTEM_VERIFY = 0
+} MPCI_Internal_Remote_operations;
+
+/**
+ * The following data structure defines the packet used to perform
+ * remote event operations.
+ */
+typedef struct {
+ /** This field is the general header for all packets. */
+ MP_packet_Prefix Prefix;
+ /** This value specifies the operation. */
+ MPCI_Internal_Remote_operations operation;
+ /** This is the maximum number of nodes in the system. It must agree
+ * on all nodes.
+ */
+ uint32_t maximum_nodes;
+ /** This field is the maximum number of concurrently existent
+ * globally offered objects.
+ */
+ uint32_t maximum_global_objects;
+} MPCI_Internal_packet;
+
+/**
+ * This is the core semaphore which the MPCI Receive Server blocks on.
+ */
+SCORE_EXTERN CORE_semaphore_Control _MPCI_Semaphore;
+
+/**
+ * The following thread queue is used to maintain a list of tasks
+ * which currently have outstanding remote requests.
+ */
+SCORE_EXTERN Thread_queue_Control _MPCI_Remote_blocked_threads;
+
+/**
+ * The following define the internal pointers to the user's
+ * configuration information.
+ */
+SCORE_EXTERN MPCI_Control *_MPCI_table;
+
+/** @brief Pointer to MP Thread Control Block
+ *
+ * The following is used to determine when the multiprocessing receive
+ * thread is executing so that a proxy can be allocated instead of
+ * blocking the multiprocessing receive thread.
+ */
+SCORE_EXTERN Thread_Control *_MPCI_Receive_server_tcb;
+
+/**
+ * The following table contains the process packet routines provided
+ * by each object that supports MP operations.
+ */
+SCORE_EXTERN MPCI_Packet_processor
+ _MPCI_Packet_processors[MP_PACKET_CLASSES_LAST+1];
+
+/**
+ * This routine performs the initialization necessary for this handler.
+ *
+ * @param[in] users_mpci_table is a pointer to the application configured
+ * MPCI Table. This table contains pointers to the MPCI Layers
+ * entry points.
+ * @param[in] timeout_status is the value which should be returned to
+ * blocking threads when they timeout on a remote operation.
+ */
+void _MPCI_Handler_initialization(
+ MPCI_Control *users_mpci_table,
+ uint32_t timeout_status
+);
+
+/**
+ * This routine creates the packet receive server used in MP systems.
+ */
+void _MPCI_Create_server( void );
+
+/**
+ * This routine initializes the MPCI driver by
+ * invoking the user provided MPCI initialization callout.
+ */
+void _MPCI_Initialization ( void );
+
+/**
+ * This routine registers the MPCI packet processor for the
+ * designated object class.
+ *
+ * @param[in] the_class is the class indicator for packets which will
+ * be processed by @a the_packet_processor method.
+ * @param[in] the_packet_processor is a pointer to a method which is
+ * invoked when packets with @a the_class are received.
+ */
+void _MPCI_Register_packet_processor(
+ MP_packet_Classes the_class,
+ MPCI_Packet_processor the_packet_processor
+
+);
+
+/**
+ * This function obtains a packet by invoking the user provided
+ * MPCI get packet callout.
+ *
+ * @return This method returns a pointer to a MPCI packet which can be
+ * filled in by the caller and used to perform a subsequent
+ * remote operation.
+ */
+MP_packet_Prefix *_MPCI_Get_packet ( void );
+
+/**
+ * This routine deallocates a packet by invoking the user provided
+ * MPCI return packet callout.
+ *
+ * @param[in] the_packet is the MP packet to deallocate.
+ */
+void _MPCI_Return_packet (
+ MP_packet_Prefix *the_packet
+);
+
+/**
+ * This routine sends a process packet by invoking the user provided
+ * MPCI send callout.
+ *
+ * @param[in] destination is the node which should receive this packet.
+ * @param[in] the_packet is the packet to be sent.
+ */
+void _MPCI_Send_process_packet (
+ uint32_t destination,
+ MP_packet_Prefix *the_packet
+);
+
+/**
+ * This routine sends a request packet by invoking the user provided
+ * MPCI send callout.
+ *
+ * @param[in] destination is the node which should receive this packet.
+ * @param[in] the_packet is the packet to be sent.
+ * @param[in] extra_state is the extra thread state bits which should be
+ * set in addition to the remote operation pending state. It
+ * may indicate the caller is blocking on a message queue
+ * operation.
+ *
+ * @return This method returns the operation status from the remote node.
+ */
+uint32_t _MPCI_Send_request_packet (
+ uint32_t destination,
+ MP_packet_Prefix *the_packet,
+ States_Control extra_state
+);
+
+/**
+ * This routine sends a response packet by invoking the user provided
+ * MPCI send callout.
+ *
+ * @param[in] destination is the node which should receive this packet.
+ * @param[in] the_packet is the packet to be sent.
+ */
+void _MPCI_Send_response_packet (
+ uint32_t destination,
+ MP_packet_Prefix *the_packet
+);
+
+/**
+ * This routine receives a packet by invoking the user provided
+ * MPCI receive callout.
+ *
+ * @return This method returns the packet received.
+ */
+MP_packet_Prefix *_MPCI_Receive_packet ( void );
+
+/**
+ * This routine is responsible for passing @a the_packet to the thread
+ * waiting on the remote operation to complete. The unblocked thread is
+ * responsible for eventually freeing @a the_packet.
+ *
+ * @param[in] the_packet is the response packet to be processed.
+ *
+ * @return This method returns a pointer to the thread which was if unblocked
+ * or NULL if the waiting thread no longer exists.
+ */
+Thread_Control *_MPCI_Process_response (
+ MP_packet_Prefix *the_packet
+);
+
+/**
+ * This is the server thread which receives and processes all MCPI packets.
+ *
+ * @param[in] ignored is the thread argument. It is not used.
+ */
+Thread _MPCI_Receive_server(
+ uint32_t ignored
+);
+
+/**
+ * This routine informs RTEMS of the availability of an MPCI packet.
+ */
+void _MPCI_Announce ( void );
+
+/**
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ *
+ * @param[in] operation is the remote operation to perform.
+ */
+void _MPCI_Internal_packets_Send_process_packet (
+ MPCI_Internal_Remote_operations operation
+);
+
+/**
+ * _MPCI_Internal_packets_Send_request_packet
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ *
+ * This routine is not needed since there are no request
+ * packets to be sent by this manager.
+ */
+
+/**
+ * _MPCI_Internal_packets_Send_response_packet
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ *
+ * This routine is not needed since there are no response
+ * packets to be sent by this manager.
+ */
+
+/**
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+void _MPCI_Internal_packets_Process_packet (
+ MP_packet_Prefix *the_packet_prefix
+);
+
+/**
+ * _MPCI_Internal_packets_Send_object_was_deleted
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+/**
+ * _MPCI_Internal_packets_Send_extract_proxy
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+/**
+ * This routine is used to obtain a internal threads mp packet.
+ */
+MPCI_Internal_packet *_MPCI_Internal_packets_Get_packet ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/mppkt.h b/cpukit/score/include/rtems/score/mppkt.h
new file mode 100644
index 0000000000..b194610500
--- /dev/null
+++ b/cpukit/score/include/rtems/score/mppkt.h
@@ -0,0 +1,123 @@
+/**
+ * @file rtems/score/mppkt.h
+ *
+ * This package is the specification for the Packet Handler.
+ * This handler defines the basic packet and provides
+ * mechanisms to utilize packets based on this prefix.
+ * Packets are the fundamental basis for messages passed between
+ * nodes in an MP system.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_MPPKT_H
+#define _RTEMS_SCORE_MPPKT_H
+
+/**
+ * @defgroup ScoreMPPacket MP Packet Handler
+ *
+ * This handler encapsulates the primary definition of MPCI packets. This
+ * handler defines the part of the packet that is common to all remote
+ * operations.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/watchdog.h>
+
+/**
+ * The following enumerated type defines the packet classes.
+ *
+ * @note In general, each class corresponds to a manager
+ * which supports global operations. Each manager
+ * defines the set of supported operations.
+ */
+typedef enum {
+ MP_PACKET_MPCI_INTERNAL = 0,
+ MP_PACKET_TASKS = 1,
+ MP_PACKET_MESSAGE_QUEUE = 2,
+ MP_PACKET_SEMAPHORE = 3,
+ MP_PACKET_PARTITION = 4,
+ MP_PACKET_REGION = 5,
+ MP_PACKET_EVENT = 6,
+ MP_PACKET_SIGNAL = 7
+} MP_packet_Classes;
+
+/**
+ * This constant defines the first entry in the MP_packet_Classes enumeration.
+ */
+#define MP_PACKET_CLASSES_FIRST MP_PACKET_MPCI_INTERNAL
+
+/**
+ * This constant defines the last entry in the MP_packet_Classes enumeration.
+ */
+#define MP_PACKET_CLASSES_LAST MP_PACKET_SIGNAL
+
+/**
+ * The following record contains the prefix for every packet
+ * passed between nodes in an MP system.
+ *
+ * @note This structure is padded to ensure that anything following it
+ * is on a 16 byte boundary. This is the most stringent structure
+ * alignment rule encountered yet.
+ */
+typedef struct {
+ /** This field indicates the API class of the operation being performed. */
+ MP_packet_Classes the_class;
+ /** This field is the id of the object to be acted upon. */
+ Objects_Id id;
+ /** This field is the ID of the originating thread. */
+ Objects_Id source_tid;
+ /** This field is the priority of the originating thread. */
+ Priority_Control source_priority;
+ /** This field is where the status of the operation will be returned. */
+ uint32_t return_code;
+ /** This field is the length of the data following the prefix. */
+ uint32_t length;
+ /** This field is the length of the data which required network conversion. */
+ uint32_t to_convert;
+ /** This field is the requested timeout for this operation. */
+ Watchdog_Interval timeout;
+} MP_packet_Prefix;
+
+/**
+ * An MPCI must support packets of at least this size.
+ */
+#define MP_PACKET_MINIMUM_PACKET_SIZE 64
+
+/**
+ * The following constant defines the number of uint32_t 's
+ * in a packet which must be converted to native format in a
+ * heterogeneous system. In packets longer than
+ * MP_PACKET_MINIMUN_HETERO_CONVERSION uint32_t 's, some of the "extra" data
+ * may a user message buffer which is not automatically endian swapped.
+ */
+#define MP_PACKET_MINIMUN_HETERO_CONVERSION \
+ ( sizeof( MP_packet_Prefix ) / sizeof( uint32_t ) )
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/mppkt.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/object.h b/cpukit/score/include/rtems/score/object.h
new file mode 100644
index 0000000000..2a9c0b0280
--- /dev/null
+++ b/cpukit/score/include/rtems/score/object.h
@@ -0,0 +1,810 @@
+/**
+ * @file rtems/score/object.h
+ */
+
+/*
+ * This include file contains all the constants and structures associated
+ * with the Object Handler. This Handler provides mechanisms which
+ * can be used to initialize and manipulate all objects which have
+ * ids.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_OBJECT_H
+#define _RTEMS_SCORE_OBJECT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+
+/**
+ * The following type defines the control block used to manage
+ * object names.
+ */
+typedef void * Objects_Name;
+
+/**
+ * Space for object names is allocated in multiples of this.
+ *
+ * NOTE: Must be a power of 2. Matches the name manipulation routines.
+ */
+#define OBJECTS_NAME_ALIGNMENT sizeof( uint32_t )
+
+/**
+ * Functions which compare names are prototyped like this.
+ */
+typedef boolean (*Objects_Name_comparators)(
+ void * /* name_1 */,
+ void * /* name_2 */,
+ uint16_t /* length */
+);
+
+#if defined(RTEMS_USE_16_BIT_OBJECT)
+/**
+ * The following type defines the control block used to manage
+ * object IDs. The format is as follows (0=LSB):
+ *
+ * Bits 0 .. 7 = index (up to 254 objects of a type)
+ * Bits 8 .. 10 = API (up to 7 API classes)
+ * Bits 11 .. 15 = class (up to 31 object types per API)
+ */
+typedef uint16_t Objects_Id;
+
+/**
+ * This type is used to store the maximum number of allowed objects
+ * of each type.
+ */
+typedef uint8_t Objects_Maximum;
+
+#define OBJECTS_INDEX_START_BIT 0
+#define OBJECTS_API_START_BIT 8
+#define OBJECTS_CLASS_START_BIT 11
+
+#define OBJECTS_INDEX_MASK (Objects_Id)0x00ff
+#define OBJECTS_API_MASK (Objects_Id)0x0700
+#define OBJECTS_CLASS_MASK (Objects_Id)0xF800
+
+#define OBJECTS_INDEX_VALID_BITS (Objects_Id)0x00ff
+#define OBJECTS_API_VALID_BITS (Objects_Id)0x0007
+/* OBJECTS_NODE_VALID_BITS should not be used with 16 bit Ids */
+#define OBJECTS_CLASS_VALID_BITS (Objects_Id)0x001f
+
+#define OBJECTS_UNLIMITED_OBJECTS 0x8000
+
+#define OBJECTS_ID_INITIAL_INDEX (0)
+#define OBJECTS_ID_FINAL_INDEX (0xff)
+
+#else
+/**
+ * The following type defines the control block used to manage
+ * object IDs. The format is as follows (0=LSB):
+ *
+ * Bits 0 .. 15 = index (up to 65535 objects of a type)
+ * Bits 16 .. 23 = node (up to 255 nodes)
+ * Bits 24 .. 26 = API (up to 7 API classes)
+ * Bits 27 .. 31 = class (up to 31 object types per API)
+ */
+typedef uint32_t Objects_Id;
+
+/**
+ * This type is used to store the maximum number of allowed objects
+ * of each type.
+ */
+typedef uint16_t Objects_Maximum;
+
+/**
+ * This is the bit position of the starting bit of the index portion of
+ * the object Id.
+ */
+#define OBJECTS_INDEX_START_BIT 0
+
+
+/**
+ * This is the bit position of the starting bit of the node portion of
+ * the object Id.
+ */
+#define OBJECTS_NODE_START_BIT 16
+
+/**
+ * This is the bit position of the starting bit of the API portion of
+ * the object Id.
+ */
+#define OBJECTS_API_START_BIT 24
+
+/**
+ * This is the bit position of the starting bit of the class portion of
+ * the object Id.
+ */
+#define OBJECTS_CLASS_START_BIT 27
+
+/**
+ * This mask is used to extract the index portion of an object Id.
+ */
+#define OBJECTS_INDEX_MASK (Objects_Id)0x0000ffff
+
+/**
+ * This mask is used to extract the node portion of an object Id.
+ */
+#define OBJECTS_NODE_MASK (Objects_Id)0x00ff0000
+
+/**
+ * This mask is used to extract the API portion of an object Id.
+ */
+#define OBJECTS_API_MASK (Objects_Id)0x07000000
+
+/**
+ * This mask is used to extract the class portion of an object Id.
+ */
+#define OBJECTS_CLASS_MASK (Objects_Id)0xf8000000
+
+/**
+ * This mask represents the bits that is used to ensure no extra bits
+ * are set after shifting to extract the index portion of an object Id.
+ */
+#define OBJECTS_INDEX_VALID_BITS (Objects_Id)0x0000ffff
+
+/**
+ * This mask represents the bits that is used to ensure no extra bits
+ * are set after shifting to extract the node portion of an object Id.
+ */
+#define OBJECTS_NODE_VALID_BITS (Objects_Id)0x000000ff
+
+/**
+ * This mask represents the bits that is used to ensure no extra bits
+ * are set after shifting to extract the API portion of an object Id.
+ */
+#define OBJECTS_API_VALID_BITS (Objects_Id)0x00000007
+
+/**
+ * This mask represents the bits that is used to ensure no extra bits
+ * are set after shifting to extract the class portion of an object Id.
+ */
+#define OBJECTS_CLASS_VALID_BITS (Objects_Id)0x0000001f
+
+/**
+ * Mask to enable unlimited objects. This is used in the configuration
+ * table when specifying the number of configured objects.
+ */
+#define OBJECTS_UNLIMITED_OBJECTS 0x80000000
+
+/**
+ * This is the lowest value for the index portion of an object Id.
+ */
+#define OBJECTS_ID_INITIAL_INDEX (0)
+
+/**
+ * This is the highest value for the index portion of an object Id.
+ */
+#define OBJECTS_ID_FINAL_INDEX (0xff)
+#endif
+
+/**
+ * This enumerated type is used in the class field of the object ID.
+ */
+typedef enum {
+ OBJECTS_NO_API = 0,
+ OBJECTS_INTERNAL_API = 1,
+ OBJECTS_CLASSIC_API = 2,
+ OBJECTS_POSIX_API = 3,
+ OBJECTS_ITRON_API = 4
+} Objects_APIs;
+
+/** This macro is used to generically specify the last API index. */
+#define OBJECTS_APIS_LAST OBJECTS_ITRON_API
+
+/**
+ * This enumerated type is used in the class field of the object ID
+ * for RTEMS internal object classes.
+ */
+typedef enum {
+ OBJECTS_INTERNAL_NO_CLASS = 0,
+ OBJECTS_INTERNAL_THREADS = 1,
+ OBJECTS_INTERNAL_MUTEXES = 2
+} Objects_Internal_API;
+
+/** This macro is used to generically specify the last API index. */
+#define OBJECTS_INTERNAL_CLASSES_LAST OBJECTS_INTERNAL_MUTEXES
+
+/**
+ * This enumerated type is used in the class field of the object ID
+ * for the RTEMS Classic API.
+ */
+typedef enum {
+ OBJECTS_CLASSIC_NO_CLASS = 0,
+ OBJECTS_RTEMS_TASKS = 1,
+ OBJECTS_RTEMS_TIMERS = 2,
+ OBJECTS_RTEMS_SEMAPHORES = 3,
+ OBJECTS_RTEMS_MESSAGE_QUEUES = 4,
+ OBJECTS_RTEMS_PARTITIONS = 5,
+ OBJECTS_RTEMS_REGIONS = 6,
+ OBJECTS_RTEMS_PORTS = 7,
+ OBJECTS_RTEMS_PERIODS = 8,
+ OBJECTS_RTEMS_EXTENSIONS = 9
+} Objects_Classic_API;
+
+/** This macro is used to generically specify the last API index. */
+#define OBJECTS_RTEMS_CLASSES_LAST OBJECTS_RTEMS_EXTENSIONS
+
+/**
+ * This enumerated type is used in the class field of the object ID
+ * for the POSIX API.
+ */
+typedef enum {
+ OBJECTS_POSIX_NO_CLASS = 0,
+ OBJECTS_POSIX_THREADS = 1,
+ OBJECTS_POSIX_KEYS = 2,
+ OBJECTS_POSIX_INTERRUPTS = 3,
+ OBJECTS_POSIX_MESSAGE_QUEUE_FDS = 4,
+ OBJECTS_POSIX_MESSAGE_QUEUES = 5,
+ OBJECTS_POSIX_MUTEXES = 6,
+ OBJECTS_POSIX_SEMAPHORES = 7,
+ OBJECTS_POSIX_CONDITION_VARIABLES = 8,
+ OBJECTS_POSIX_TIMERS = 9
+} Objects_POSIX_API;
+
+/** This macro is used to generically specify the last API index. */
+#define OBJECTS_POSIX_CLASSES_LAST OBJECTS_POSIX_TIMERS
+
+/**
+ * This enumerated type is used in the class field of the object ID
+ * for the ITRON API.
+ */
+typedef enum {
+ OBJECTS_ITRON_NO_CLASS = 0,
+ OBJECTS_ITRON_TASKS = 1,
+ OBJECTS_ITRON_EVENTFLAGS = 2,
+ OBJECTS_ITRON_MAILBOXES = 3,
+ OBJECTS_ITRON_MESSAGE_BUFFERS = 4,
+ OBJECTS_ITRON_PORTS = 5,
+ OBJECTS_ITRON_SEMAPHORES = 6,
+ OBJECTS_ITRON_VARIABLE_MEMORY_POOLS = 7,
+ OBJECTS_ITRON_FIXED_MEMORY_POOLS = 8
+} Objects_ITRON_API;
+
+/** This macro is used to generically specify the last API index. */
+#define OBJECTS_ITRON_CLASSES_LAST OBJECTS_ITRON_FIXED_MEMORY_POOLS
+
+/**
+ * This enumerated type lists the locations which may be returned
+ * by _Objects_Get. These codes indicate the success of locating
+ * an object with the specified ID.
+ */
+typedef enum {
+ OBJECTS_LOCAL = 0, /* object is local */
+ OBJECTS_REMOTE = 1, /* object is remote */
+ OBJECTS_ERROR = 2 /* id was invalid */
+} Objects_Locations;
+
+/**
+ * The following type defines the callout used when a local task
+ * is extracted from a remote thread queue (i.e. it's proxy must
+ * extracted from the remote queue).
+ */
+typedef void ( *Objects_Thread_queue_Extract_callout )( void * );
+
+/**
+ * The following defines the Object Control Block used to manage
+ * each object local to this node.
+ */
+typedef struct {
+ /** This is the chain node portion of an object. */
+ Chain_Node Node;
+ /** This is the object's ID. */
+ Objects_Id id;
+ /** This is the object's name. */
+ Objects_Name name;
+} Objects_Control;
+
+/**
+ * The following defines the structure for the information used to
+ * manage each class of objects.
+ */
+typedef struct {
+ /** This field indicates the API of this object class. */
+ Objects_APIs the_api;
+ /** This is the class of this object set. */
+ uint16_t the_class;
+ /** This is the minimum valid id of this object class. */
+ Objects_Id minimum_id;
+ /** This is the maximum valid id of this object class. */
+ Objects_Id maximum_id;
+ /** This is the maximum number of objects in this class. */
+ Objects_Maximum maximum;
+ /** This is the TRUE if unlimited objects in this class. */
+ boolean auto_extend;
+ /** This is the number of objects in a block. */
+ uint32_t allocation_size;
+ /** This is the size in bytes of each object instance. */
+ uint32_t size;
+ /** This points to the table of local objects. */
+ Objects_Control **local_table;
+ /** This points to the table of local object names. */
+ Objects_Name *name_table;
+ /** This is the chain of inactive control blocks. */
+ Chain_Control Inactive;
+ /** This is the number of objects on the Inactive list. */
+ Objects_Maximum inactive;
+ /** This is the number of inactive objects per block. */
+ uint32_t *inactive_per_block;
+ /** This is a table to the chain of inactive object memory blocks. */
+ void **object_blocks;
+ /** This is the TRUE if names are strings. */
+ boolean is_string;
+ /** This is the maximum length of names. */
+ uint16_t name_length;
+ /** This is this object class' method called when extracting a thread. */
+ Objects_Thread_queue_Extract_callout extract;
+#if defined(RTEMS_MULTIPROCESSING)
+ /** This is this object class' pointer to the global name table */
+ Chain_Control *global_table;
+#endif
+} Objects_Information;
+
+/**
+ * The following is referenced to the node number of the local node.
+ */
+#if defined(RTEMS_MULTIPROCESSING)
+SCORE_EXTERN uint16_t _Objects_Local_node;
+#else
+#define _Objects_Local_node 1
+#endif
+
+/**
+ * The following is referenced to the number of nodes in the system.
+ */
+#if defined(RTEMS_MULTIPROCESSING)
+SCORE_EXTERN uint16_t _Objects_Maximum_nodes;
+#else
+#define _Objects_Maximum_nodes 1
+#endif
+
+/**
+ * The following is the list of information blocks per API for each object
+ * class. From the ID, we can go to one of these information blocks,
+ * and obtain a pointer to the appropriate object control block.
+ */
+SCORE_EXTERN Objects_Information
+ **_Objects_Information_table[OBJECTS_APIS_LAST + 1];
+
+/**
+ * The following defines the constant which may be used
+ * with _Objects_Get to manipulate the calling task.
+ */
+#define OBJECTS_ID_OF_SELF ((Objects_Id) 0)
+
+/**
+ * The following constant is used to specify that a name to ID search
+ * should search through all nodes.
+ */
+#define OBJECTS_SEARCH_ALL_NODES 0
+
+/**
+ * The following constant is used to specify that a name to ID search
+ * should search through all nodes except the current node.
+ */
+#define OBJECTS_SEARCH_OTHER_NODES 0x7FFFFFFE
+
+/**
+ * The following constant is used to specify that a name to ID search
+ * should search only on this node.
+ */
+#define OBJECTS_SEARCH_LOCAL_NODE 0x7FFFFFFF
+
+/**
+ * The following constant is used to specify that a name to ID search
+ * is being asked for the ID of the currently executing task.
+ */
+#define OBJECTS_WHO_AM_I 0
+
+/**
+ * This macros calculates the lowest ID for the specified api, class,
+ * and node.
+ */
+#define OBJECTS_ID_INITIAL(_api, _class, _node) \
+ _Objects_Build_id( (_api), (_class), (_node), OBJECTS_ID_INITIAL_INDEX )
+
+/**
+ * This macro specifies the highest object ID value
+ */
+#define OBJECTS_ID_FINAL ((Objects_Id)~0)
+
+/**
+ * This function performs the initialization necessary for this handler.
+ *
+ * @param[in] node indicates the identifying number of this node.
+ * @param[in] maximum_nodes is the maximum number of nodes in this system.
+ * @param[in] maximum_global_objects is maximum number of global objects
+ * concurrently offered in the system.
+ */
+void _Objects_Handler_initialization(
+ uint32_t node,
+ uint32_t maximum_nodes,
+ uint32_t maximum_global_objects
+);
+
+/**
+ * This function extends an object class information record.
+ *
+ * @param[in] information points to an object class information block.
+ */
+void _Objects_Extend_information(
+ Objects_Information *information
+);
+
+/**
+ * This function shrink an object class information record.
+ *
+ * @param[in] information points to an object class information block.
+ */
+void _Objects_Shrink_information(
+ Objects_Information *information
+);
+
+/**
+ * This function initializes an object class information record.
+ * SUPPORTS_GLOBAL is TRUE if the object class supports global
+ * objects, and FALSE otherwise. Maximum indicates the number
+ * of objects required in this class and size indicates the size
+ * in bytes of each control block for this object class. The
+ * name length and string designator are also set. In addition,
+ * the class may be a task, therefore this information is also included.
+ *
+ * @param[in] information points to an object class information block.
+ * @param[in] the_api indicates the API associated with this information block.
+ * @param[in] the_class indicates the class of object being managed
+ * by this information block. It is specific to @a the_api.
+ * @param[in] maximum is the maximum number of instances of this object
+ * class which may be concurrently active.
+ * @param[in] size is the size of the data structure for this class.
+ * @param[in] is_string is TRUE if this object uses string style names.
+ * @param[in] maximum_name_length is the maximum length of object names.
+ */
+void _Objects_Initialize_information (
+ Objects_Information *information,
+ Objects_APIs the_api,
+ uint32_t the_class,
+ uint32_t maximum,
+ uint16_t size,
+ boolean is_string,
+ uint32_t maximum_name_length
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ boolean supports_global,
+ Objects_Thread_queue_Extract_callout extract
+#endif
+);
+
+/**
+ * This function allocates a object control block from
+ * the inactive chain of free object control blocks.
+ *
+ * @param[in] information points to an object class information block.
+ */
+Objects_Control *_Objects_Allocate(
+ Objects_Information *information
+);
+
+/**
+ * This function allocates the object control block
+ * specified by the index from the inactive chain of
+ * free object control blocks.
+ *
+ * @param[in] information points to an object class information block.
+ * @param[in] index is the index of the object to allocate.
+ * @param[in] sizeof_control is the size of the object control block.
+ */
+Objects_Control *_Objects_Allocate_by_index(
+ Objects_Information *information,
+ uint16_t index,
+ uint16_t sizeof_control
+);
+
+/**
+ *
+ * This function frees a object control block to the
+ * inactive chain of free object control blocks.
+ *
+ * @param[in] information points to an object class information block.
+ * @param[in] the_object points to the object to deallocate.
+ */
+void _Objects_Free(
+ Objects_Information *information,
+ Objects_Control *the_object
+);
+
+/**
+ * This method zeroes out the name.
+ *
+ * @param[in] name points to the name to be zeroed out.
+ * @param[in] length is the length of the object name field.
+ */
+void _Objects_Clear_name(
+ void *name,
+ uint16_t length
+);
+
+/**
+ * This method copies a string style object name from source to destination.
+ *
+ * @param[in] source is the source name to copy.
+ * @param[in] destination is the destination of the copy.
+ * @param[in] length is the number of bytes to copy.
+ */
+void _Objects_Copy_name_string(
+ void *source,
+ void *destination,
+ uint16_t length
+);
+
+/**
+ * This method copies a raw style object name from source to destination.
+ *
+ * @param[in] source is the source name to copy.
+ * @param[in] destination is the destination of the copy.
+ * @param[in] length is the number of bytes to copy.
+ */
+void _Objects_Copy_name_raw(
+ void *source,
+ void *destination,
+ uint16_t length
+);
+
+/**
+ * This method compares two string style object names.
+ *
+ * @param[in] name_1 is the left hand name to compare.
+ * @param[in] name_2 is the right hand name to compare.
+ * @param[in] length is the length of the names to compare.
+ */
+boolean _Objects_Compare_name_string(
+ void *name_1,
+ void *name_2,
+ uint16_t length
+);
+
+/**
+ * This method compares two raw style object names.
+ *
+ * @param[in] name_1 is the left hand name to compare.
+ * @param[in] name_2 is the right hand name to compare.
+ * @param[in] length is the length of the names to compare.
+ */
+boolean _Objects_Compare_name_raw(
+ void *name_1,
+ void *name_2,
+ uint16_t length
+);
+
+/**
+ * This function implements the common portion of the object
+ * identification directives. This directive returns the object
+ * id associated with name. If more than one object of this class
+ * is named name, then the object to which the id belongs is
+ * arbitrary. Node indicates the extent of the search for the
+ * id of the object named name. If the object class supports global
+ * objects, then the search can be limited to a particular node
+ * or allowed to encompass all nodes.
+ */
+typedef enum {
+ OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL,
+ OBJECTS_INVALID_NAME,
+ OBJECTS_INVALID_ADDRESS,
+ OBJECTS_INVALID_ID,
+ OBJECTS_INVALID_NODE
+} Objects_Name_or_id_lookup_errors;
+
+/** This macro defines the first entry in the
+ * @ref Objects_Name_or_id_lookup_errors enumerated list.
+ */
+#define OBJECTS_NAME_ERRORS_FIRST OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL
+
+/** This macro defines the last entry in the
+ * @ref Objects_Name_or_id_lookup_errors enumerated list.
+ */
+#define OBJECTS_NAME_ERRORS_LAST OBJECTS_INVALID_NODE
+
+/**
+ * This method converts an object name to an Id. It performs a look up
+ * using the object information block for this object class.
+ *
+ * @param[in] information points to an object class information block.
+ * @param[in] name is the name of the object to find.
+ * @param[in] node is the set of nodes to search.
+ * @param[in] id will contain the Id if the search is successful.
+ *
+ * @return This method returns one of the values from the
+ * @ref Objects_Name_or_id_lookup_errors enumeration to indicate
+ * successful or failure. On success @a id will contain the Id of
+ * the requested object.
+ */
+Objects_Name_or_id_lookup_errors _Objects_Name_to_id(
+ Objects_Information *information,
+ Objects_Name name,
+ uint32_t node,
+ Objects_Id *id
+);
+
+/**
+ * This function implements the common portion of the object Id
+ * to name directives. This function returns the name
+ * associated with object id.
+ *
+ * @param[in] id is the Id of the object whose name we are locating.
+ * @param[in] name will contain the name of the object, if found.
+ *
+ * @return This method returns one of the values from the
+ * @ref Objects_Name_or_id_lookup_errors enumeration to indicate
+ * successful or failure. On success @a name will contain the name of
+ * the requested object.
+ *
+ * @note This function currently does not support string names.
+ */
+Objects_Name_or_id_lookup_errors _Objects_Id_to_name (
+ Objects_Id id,
+ Objects_Name *name
+);
+
+/**
+ * This function maps object ids to object control blocks.
+ * If id corresponds to a local object, then it returns
+ * the_object control pointer which maps to id and location
+ * is set to OBJECTS_LOCAL. If the object class supports global
+ * objects and the object id is global and resides on a remote
+ * node, then location is set to OBJECTS_REMOTE, and the_object
+ * is undefined. Otherwise, location is set to OBJECTS_ERROR
+ * and the_object is undefined.
+ *
+ * @param[in] information points to an object class information block.
+ * @param[in] id is the Id of the object whose name we are locating.
+ * @param[in] location will contain an indication of success or failure.
+ *
+ * @return This method returns one of the values from the
+ * @ref Objects_Name_or_id_lookup_errors enumeration to indicate
+ * successful or failure. On success @a id will contain the Id of
+ * the requested object.
+ *
+ * @note _Objects_Get returns with dispatching disabled for
+ * local and remote objects. _Objects_Get_isr_disable returns with
+ * dispatching disabled for remote objects and interrupts for local
+ * objects.
+ */
+Objects_Control *_Objects_Get (
+ Objects_Information *information,
+ Objects_Id id,
+ Objects_Locations *location
+);
+
+/**
+ * This function maps object ids to object control blocks.
+ * If id corresponds to a local object, then it returns
+ * the_object control pointer which maps to id and location
+ * is set to OBJECTS_LOCAL. If the object class supports global
+ * objects and the object id is global and resides on a remote
+ * node, then location is set to OBJECTS_REMOTE, and the_object
+ * is undefined. Otherwise, location is set to OBJECTS_ERROR
+ * and the_object is undefined.
+ *
+ * @param[in] information points to an object class information block.
+ * @param[in] id is the Id of the object whose name we are locating.
+ * @param[in] location will contain an indication of success or failure.
+ * @param[in] level is the interrupt level being turned.
+ *
+ * @return This method returns one of the values from the
+ * @ref Objects_Name_or_id_lookup_errors enumeration to indicate
+ * successful or failure. On success @a name will contain the name of
+ * the requested object.
+ *
+ * @note _Objects_Get returns with dispatching disabled for
+ * local and remote objects. _Objects_Get_isr_disable returns with
+ * dispatching disabled for remote objects and interrupts for local
+ * objects.
+ */
+Objects_Control *_Objects_Get_isr_disable(
+ Objects_Information *information,
+ Objects_Id id,
+ Objects_Locations *location,
+ ISR_Level *level
+);
+
+/**
+ * This function maps object index to object control blocks which must.
+ * be local. The parameter the_object control pointer which maps to id
+ * and location is set to OBJECTS_LOCAL. Otherwise, location is set to
+ OBJECTS_ERROR and the_object is undefined.
+ *
+ * @param[in] information points to an object class information block.
+ * @param[in] id is the Id of the object whose name we are locating.
+ * @param[in] location will contain an indication of success or failure.
+ *
+ * @return This method returns a pointer to the object associated with ID.
+ *
+ * @return This method returns one of the values from the
+ * @ref Objects_Name_or_id_lookup_errors enumeration to indicate
+ * successful or failure. On success @a id will contain the id of
+ * the requested object.
+ *
+ * @note _Objects_Get returns with dispatching disabled for
+ * local and remote objects. _Objects_Get_isr_disable returns with
+ * dispatching disabled for remote objects and interrupts for local
+ * objects.
+ */
+Objects_Control *_Objects_Get_by_index (
+ Objects_Information *information,
+ Objects_Id id,
+ Objects_Locations *location
+);
+
+/**
+ * This function maps object ids to object control blocks.
+ * If id corresponds to a local object, then it returns
+ * the_object control pointer which maps to id and location
+ * is set to OBJECTS_LOCAL. If the object class supports global
+ * objects and the object id is global and resides on a remote
+ * node, then location is set to OBJECTS_REMOTE, and the_object
+ * is undefined. Otherwise, location is set to OBJECTS_ERROR
+ * and the_object is undefined.
+ *
+ * @param[in] information points to an object class information block.
+ * @param[in] id is the Id of the object whose name we are locating.
+ * @param[in] location will contain an indication of success or failure.
+ *
+ * @return This method returns one of the values from the
+ * @ref Objects_Name_or_id_lookup_errors enumeration to indicate
+ * successful or failure. On success @a id will contain the Id of
+ * the requested object.
+ *
+ * @note _Objects_Get returns with dispatching disabled for
+ * local and remote objects. _Objects_Get_isr_disable returns with
+ * dispatching disabled for remote objects and interrupts for local
+ * objects.
+ */
+Objects_Control *_Objects_Get_no_protection(
+ Objects_Information *information,
+ Objects_Id id,
+ Objects_Locations *location
+);
+
+/**
+ * Like @ref _Objects_Get, but is used to find "next" open object.
+ *
+ * @param[in] information points to an object class information block.
+ * @param[in] id is the Id of the object whose name we are locating.
+ * @param[in] location_p will contain an indication of success or failure.
+ * @param[in] next_id_p is the Id of the next object we will look at.
+ *
+ * @return This method returns the pointer to the object located or
+ * NULL on error.
+ */
+Objects_Control *_Objects_Get_next(
+ Objects_Information *information,
+ Objects_Id id,
+ Objects_Locations *location_p,
+ Objects_Id *next_id_p
+);
+
+/*
+ * Pieces of object.inl are promoted out to the user
+ */
+
+#include <rtems/score/object.inl>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/objectmp.h b/cpukit/score/include/rtems/score/objectmp.h
new file mode 100644
index 0000000000..6275304012
--- /dev/null
+++ b/cpukit/score/include/rtems/score/objectmp.h
@@ -0,0 +1,190 @@
+/**
+ * @file rtems/score/objectmp.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the manipulation of Global RTEMS Objects.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_OBJECTMP_H
+#define _RTEMS_SCORE_OBJECTMP_H
+
+/**
+ * @defgroup ScoreObjectMP Object Handler Multiprocessing Support
+ *
+ * This handler encapsulates functionality which is used to manage
+ * objects which have been declared to be globally visible. This handler
+ * knows objects from all of the nodes in the system.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This defines the Global Object Control Block used to manage
+ * objects resident on other nodes. It is derived from Object.
+ */
+typedef struct {
+ /** This is an object control structure. */
+ Objects_Control Object;
+ /** This is the name of the object. Using an unsigned thirty two
+ * bit value is broken but works. If any API is MP with variable
+ * length names .. BOOM!!!!
+ */
+ uint32_t name;
+} Objects_MP_Control;
+
+/** @brief Objects MP Handler initialization
+ *
+ * This routine intializes the inactive global object chain
+ * based on the maximum number of global objects configured.
+ *
+ * @param[in] node is this node's number.
+ * @param[in] maximum_nodes is the maximum number of nodes in the system.
+ * @param[in] maximum_global_objects is the maximum number of concurrently
+ * created global objects.
+ */
+void _Objects_MP_Handler_initialization (
+ uint32_t node,
+ uint32_t maximum_nodes,
+ uint32_t maximum_global_objects
+);
+
+/** @brief Objects MP Open
+ *
+ * This routine place the specified global object in the
+ * specified information table.
+ *
+ * @param[in] information points to the object information table for this
+ * object class.
+ * @param[in] the_global_object points to the object being opened.
+ * @param[in] the_name is the name of the object being opened.
+ * @param[in] the_id is the Id of the object being opened.
+ *
+ * @todo This method only works for object types with 4 byte object names.
+ * It does not support variable length object names.
+ */
+void _Objects_MP_Open (
+ Objects_Information *information,
+ Objects_MP_Control *the_global_object,
+ uint32_t the_name,
+ Objects_Id the_id
+);
+
+/** @brief Objects MP Allocate and open
+ *
+ * This routine allocates a global object control block
+ * and places it in the specified information table. If the
+ * allocation fails, then is_fatal_error determines the
+ * error processing actions taken.
+ *
+ * @param[in] information points to the object information table for this
+ * object class.
+ * @param[in] the_name is the name of the object being opened.
+ * @param[in] the_id is the Id of the object being opened.
+ * @param[in] is_fatal_error is TRUE if not being able to allocate the
+ * object is considered a fatal error.
+ *
+ * @todo This method only works for object types with 4 byte object names.
+ * It does not support variable length object names.
+ */
+boolean _Objects_MP_Allocate_and_open (
+ Objects_Information *information,
+ uint32_t the_name,
+ Objects_Id the_id,
+ boolean is_fatal_error
+);
+
+/** @brief Objects MP Close
+ *
+ * This routine removes a global object from the specified
+ * information table and deallocates the global object control block.
+ */
+void _Objects_MP_Close (
+ Objects_Information *information,
+ Objects_Id the_id
+);
+
+/** @brief Objects MP Global name search
+ *
+ * This routine looks for the object with the_name in the global
+ * object tables indicated by information. It returns the ID of the
+ * object with that name if one is found.
+ *
+ * @param[in] information points to the object information table for this
+ * object class.
+ * @param[in] the_name is the name of the object being searched for.
+ * @param[in] nodes_to_search indicates the set of nodes to search.
+ * @param[in] the_id will contain the Id of the object if found.
+ *
+ * @return This method returns one of the
+ * @ref Objects_Name_or_id_lookup_errors. If successful, @a the_id
+ * will contain the Id of the object.
+ */
+Objects_Name_or_id_lookup_errors _Objects_MP_Global_name_search (
+ Objects_Information *information,
+ Objects_Name the_name,
+ uint32_t nodes_to_search,
+ Objects_Id *the_id
+);
+
+/** @brief Objects MP Is remote
+ *
+ * This function searches the Global Object Table managed
+ * by information for the object indicated by ID. If the object
+ * is found, then location is set to objects_remote, otherwise
+ * location is set to objects_error. In both cases, the_object
+ * is undefined.
+ *
+ * @param[in] information points to the object information table for this
+ * object class.
+ * @param[in] the_id is the Id of the object being opened.
+ * @param[in] location will contain the location of the object.
+ * @param[in] the_object will contain a pointer to the object.
+ *
+ * @return This method fills in @a location to indicate successful location
+ * of the object or error. On success, @a the_object will be
+ * filled in.
+ */
+void _Objects_MP_Is_remote (
+ Objects_Information *information,
+ Objects_Id the_id,
+ Objects_Locations *location,
+ Objects_Control **the_object
+);
+
+/**
+ * This is the maximum number of global objects configured.
+ */
+SCORE_EXTERN uint32_t _Objects_MP_Maximum_global_objects;
+
+/**
+ * The following chain header is used to manage the set of
+ * inactive global object control blocks.
+ */
+SCORE_EXTERN Chain_Control _Objects_MP_Inactive_global_objects;
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/objectmp.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/priority.h b/cpukit/score/include/rtems/score/priority.h
new file mode 100644
index 0000000000..bfe43e282d
--- /dev/null
+++ b/cpukit/score/include/rtems/score/priority.h
@@ -0,0 +1,133 @@
+/**
+ * @file rtems/score/priority.h
+ *
+ * This include file contains all thread priority manipulation routines.
+ * This Handler provides mechanisms which can be used to
+ * initialize and manipulate thread priorities.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_PRIORITY_H
+#define _RTEMS_SCORE_PRIORITY_H
+
+/**
+ * @defgroup ScorePriority Priority Handler
+ *
+ * This handler encapsulates functionality which is used to manage
+ * thread priorities. At the SuperCore level 256 priority levels
+ * are supported with lower numbers representing logically more important
+ * threads. The priority level 0 is reserved for internal RTEMS use.
+ * Typically it is assigned to threads which defer internal RTEMS
+ * actions from an interrupt to thread level to improve interrupt response.
+ * Priority level 255 is assigned to the IDLE thread and really should not
+ * be used by application threads. The default IDLE thread implementation
+ * is an infinite "branch to self" loop which never yields to other threads
+ * at the same priority.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The following type defines the control block used to manage
+ * thread priorities.
+ *
+ * @note Priority 0 is reserved for internal threads only.
+ */
+typedef uint32_t Priority_Control;
+
+/** This defines the highest (most important) thread priority. */
+#define PRIORITY_MINIMUM 0
+/** This defines the lowest (least important) thread priority. */
+#define PRIORITY_MAXIMUM 255
+
+/**
+ * The following record defines the information associated with
+ * each thread to manage its interaction with the priority bit maps.
+ */
+typedef struct {
+ /** This is the address of minor bit map slot. */
+ Priority_Bit_map_control *minor;
+ /** This is the priority bit map ready mask. */
+ Priority_Bit_map_control ready_major;
+ /** This is the priority bit map ready mask. */
+ Priority_Bit_map_control ready_minor;
+ /** This is the priority bit map block mask. */
+ Priority_Bit_map_control block_major;
+ /** This is the priority bit map block mask. */
+ Priority_Bit_map_control block_minor;
+} Priority_Information;
+
+/**
+ * Each sixteen bit entry in this array is associated with one of
+ * the sixteen entries in the Priority Bit map.
+ */
+SCORE_EXTERN volatile Priority_Bit_map_control _Priority_Major_bit_map;
+
+/** Each bit in the Priority Bitmap indicates whether or not there are
+ * threads ready at a particular priority. The mapping of
+ * individual priority levels to particular bits is processor
+ * dependent as is the value of each bit used to indicate that
+ * threads are ready at that priority.
+ */
+SCORE_EXTERN Priority_Bit_map_control
+ _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT;
+
+/*
+ * The definition of the Priority_Bit_map_control type is CPU dependent.
+ *
+ */
+
+#if ( CPU_USE_GENERIC_BITFIELD_CODE == FALSE )
+/**
+ * This method returns the priority bit mask for the specified major
+ * or minor bit number.
+ *
+ * @param[in] _bit_number is the bit number for which we need a mask
+ *
+ * @return the priority bit mask
+ *
+ * @note This may simply be a pass through to a CPU dependent implementation.
+ */
+#define _Priority_Mask( _bit_number ) \
+ _CPU_Priority_Mask( _bit_number )
+#endif
+
+#if ( CPU_USE_GENERIC_BITFIELD_CODE == FALSE )
+/**
+ * This method returns the bit index position for the specified priority.
+ *
+ * @param[in] _priority is the priority for which we need the index.
+ *
+ * @return This method returns the array index into the priority bit map.
+ *
+ * @note This may simply be a pass through to a CPU dependent implementation.
+ */
+#define _Priority_Bits_index( _priority ) \
+ _CPU_Priority_bits_index( _priority )
+#endif
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/priority.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/stack.h b/cpukit/score/include/rtems/score/stack.h
new file mode 100644
index 0000000000..f7e3456569
--- /dev/null
+++ b/cpukit/score/include/rtems/score/stack.h
@@ -0,0 +1,62 @@
+/**
+ * @file rtems/score/stack.h
+ *
+ * This include file contains all information about the thread
+ * Stack Handler. This Handler provides mechanisms which can be used to
+ * initialize and utilize stacks.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_STACK_H
+#define _RTEMS_SCORE_STACK_H
+
+/**
+ * @defgroup ScoreStack Stack Handler
+ *
+ * This handler encapsulates functionality which is used in the management
+ * of thread stacks.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The following constant defines the minimum stack size which every
+ * thread must exceed.
+ */
+#define STACK_MINIMUM_SIZE CPU_STACK_MINIMUM_SIZE
+
+/**
+ * The following defines the control block used to manage each stack.
+ */
+typedef struct {
+ /** This is the stack size. */
+ uint32_t size;
+ /** This is the low memory address of stack. */
+ void *area;
+} Stack_Control;
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/stack.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/states.h b/cpukit/score/include/rtems/score/states.h
new file mode 100644
index 0000000000..8e0b07f138
--- /dev/null
+++ b/cpukit/score/include/rtems/score/states.h
@@ -0,0 +1,120 @@
+/**
+ * @file rtems/score/states.h
+ *
+ * This include file contains thread execution state information.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_STATES_H
+#define _RTEMS_SCORE_STATES_H
+
+/**
+ * @defgroup ScoreStates Thread States Handler
+ *
+ * This handler encapsulates functionality which relates to the management of
+ * the state bitmap associated with each thread.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The following type defines the control block used to manage a
+ * thread's state.
+ */
+typedef uint32_t States_Control;
+
+/*
+ * The following constants define the individual states which may be
+ * be used to compose and manipulate a thread's state.
+ */
+
+/** This macro corresponds to all states being set. */
+#define STATES_ALL_SET 0xfffff /* all states */
+/** This macro corresponds to a task being ready. */
+#define STATES_READY 0x00000 /* ready to run */
+/** This macro corresponds to a task being created but not yet started. */
+#define STATES_DORMANT 0x00001 /* created not started */
+/** This macro corresponds to a task being suspended. */
+#define STATES_SUSPENDED 0x00002 /* waiting for resume */
+/** This macro corresponds to a task being in an internal state transition. */
+#define STATES_TRANSIENT 0x00004 /* in transition */
+/** This macro corresponds to a task which is waiting for a timeout. */
+#define STATES_DELAYING 0x00008 /* wait for timeout */
+/** This macro corresponds to a task waiting until a specific TOD. */
+#define STATES_WAITING_FOR_TIME 0x00010 /* wait for TOD */
+/** This macro corresponds to a task waiting for a variable length buffer. */
+#define STATES_WAITING_FOR_BUFFER 0x00020
+/** This macro corresponds to a task waiting for a fixed size segment. */
+#define STATES_WAITING_FOR_SEGMENT 0x00040
+/** This macro corresponds to a task waiting for a message. */
+#define STATES_WAITING_FOR_MESSAGE 0x00080
+/** This macro corresponds to a task waiting for an event. */
+#define STATES_WAITING_FOR_EVENT 0x00100
+/** This macro corresponds to a task waiting for a semaphore. */
+#define STATES_WAITING_FOR_SEMAPHORE 0x00200
+/** This macro corresponds to a task waiting for a mutex. */
+#define STATES_WAITING_FOR_MUTEX 0x00400
+/** This macro corresponds to a task waiting for a condition variable. */
+#define STATES_WAITING_FOR_CONDITION_VARIABLE 0x00800
+/** This macro corresponds to a task waiting for a join while exiting. */
+#define STATES_WAITING_FOR_JOIN_AT_EXIT 0x01000
+/** This macro corresponds to a task waiting for a reply to an MPCI request. */
+#define STATES_WAITING_FOR_RPC_REPLY 0x02000
+/** This macro corresponds to a task waiting for a period. */
+#define STATES_WAITING_FOR_PERIOD 0x04000
+/** This macro corresponds to a task waiting for a signal. */
+#define STATES_WAITING_FOR_SIGNAL 0x08000
+/** This macro corresponds to a task which is in an interruptible
+ * blocking state.
+ */
+#define STATES_INTERRUPTIBLE_BY_SIGNAL 0x10000
+
+/** This macro corresponds to a task waiting for a local object operation. */
+#define STATES_LOCALLY_BLOCKED ( STATES_WAITING_FOR_BUFFER | \
+ STATES_WAITING_FOR_SEGMENT | \
+ STATES_WAITING_FOR_MESSAGE | \
+ STATES_WAITING_FOR_SEMAPHORE | \
+ STATES_WAITING_FOR_MUTEX | \
+ STATES_WAITING_FOR_CONDITION_VARIABLE | \
+ STATES_WAITING_FOR_JOIN_AT_EXIT | \
+ STATES_WAITING_FOR_SIGNAL )
+
+/** This macro corresponds to a task waiting which is blocked on
+ * a thread queue. */
+#define STATES_WAITING_ON_THREAD_QUEUE \
+ ( STATES_LOCALLY_BLOCKED | \
+ STATES_WAITING_FOR_RPC_REPLY )
+
+/** This macro corresponds to a task waiting which is blocked. */
+#define STATES_BLOCKED ( STATES_DELAYING | \
+ STATES_WAITING_FOR_TIME | \
+ STATES_WAITING_FOR_PERIOD | \
+ STATES_WAITING_FOR_EVENT | \
+ STATES_WAITING_ON_THREAD_QUEUE | \
+ STATES_INTERRUPTIBLE_BY_SIGNAL )
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/states.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/sysstate.h b/cpukit/score/include/rtems/score/sysstate.h
new file mode 100644
index 0000000000..fa53602688
--- /dev/null
+++ b/cpukit/score/include/rtems/score/sysstate.h
@@ -0,0 +1,91 @@
+/**
+ * @file rtems/score/sysstate.h
+ *
+ * This include file contains information regarding the system state.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_SYSSTATE_H
+#define _RTEMS_SCORE_SYSSTATE_H
+
+/**
+ * @defgroup ScoreSysState System State Handler
+ *
+ * This handler encapsulates functionality related to the management of the
+ * internal system state of RTEMS.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* types */
+
+/* enumerated constants */
+
+/**
+ * The following type defines the possible system states.
+ */
+typedef enum {
+ /** This indicates that the system state is between the start
+ * of rtems_initialize_executive_early and the end of the first
+ * phase of initialization.
+ */
+ SYSTEM_STATE_BEFORE_INITIALIZATION,
+ /** This indicates that the system state is between end of the first
+ * phase of initializatin but before multitasking is started.
+ */
+ SYSTEM_STATE_BEFORE_MULTITASKING,
+ /** This indicates that the system state is attempting to initiate
+ * multitasking.
+ */
+ SYSTEM_STATE_BEGIN_MULTITASKING,
+ /** This indicates that the system is up and operating normally. */
+ SYSTEM_STATE_UP,
+ /** This indicates that the system is in the midst of a shutdown. */
+ SYSTEM_STATE_SHUTDOWN,
+ /** This indicates that a fatal error has occurred. */
+ SYSTEM_STATE_FAILED
+} System_state_Codes;
+
+/** This defines the first system state. */
+#define SYSTEM_STATE_CODES_FIRST SYSTEM_STATE_BEFORE_INITIALIZATION
+/** This defines the highest value system state. */
+#define SYSTEM_STATE_CODES_LAST SYSTEM_STATE_FAILED
+
+/**
+ * The following variable indicates whether or not this is
+ * an multiprocessing system.
+ */
+SCORE_EXTERN boolean _System_state_Is_multiprocessing;
+
+/**
+ * The following variable contains the current system state.
+ */
+SCORE_EXTERN System_state_Codes _System_state_Current;
+
+/*
+ * Make it possible for the application to get the system state information.
+ */
+
+#include <rtems/score/sysstate.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
new file mode 100644
index 0000000000..7fbae11397
--- /dev/null
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -0,0 +1,751 @@
+/**
+ * @file rtems/score/thread.h
+ *
+ * This include file contains all constants and structures associated
+ * with the thread control block.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_THREAD_H
+#define _RTEMS_SCORE_THREAD_H
+
+/**
+ * @defgroup ScoreThread Thread Handler
+ *
+ * This handler encapsulates functionality related to the management of
+ * threads. This includes the creation, deletion, and scheduling of threads.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/context.h>
+#include <rtems/score/cpu.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mppkt.h>
+#endif
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/tqdata.h>
+#include <rtems/score/watchdog.h>
+
+/**
+ * The following defines the "return type" of a thread.
+ *
+ * @note This cannot always be right. Some APIs have void
+ * tasks/threads, others return pointers, others may
+ * return a numeric value. Hopefully a pointer is
+ * always at least as big as an uint32_t . :)
+ */
+typedef void *Thread;
+
+/**
+ * The following defines the ways in which the entry point for a
+ * thread can be invoked. Basically, it can be passed any
+ * combination/permutation of a pointer and an uint32_t value.
+ *
+ * @note For now, we are ignoring the return type.
+ */
+typedef enum {
+ THREAD_START_NUMERIC,
+ THREAD_START_POINTER,
+ THREAD_START_BOTH_POINTER_FIRST,
+ THREAD_START_BOTH_NUMERIC_FIRST
+} Thread_Start_types;
+
+/** This type corresponds to a very simple style thread entry point. */
+typedef Thread ( *Thread_Entry )(); /* basic type */
+
+/** This type corresponds to a thread entry point which takes a single
+ * unsigned thirty-two bit integer as an argument.
+ */
+typedef Thread ( *Thread_Entry_numeric )( uint32_t );
+
+/** This type corresponds to a thread entry point which takes a single
+ * untyped pointer as an argument.
+ */
+typedef Thread ( *Thread_Entry_pointer )( void * );
+
+/** This type corresponds to a thread entry point which takes a single
+ * untyped pointer and an unsigned thirty-two bit integer as arguments.
+ */
+typedef Thread ( *Thread_Entry_both_pointer_first )( void *, uint32_t );
+
+/** This type corresponds to a thread entry point which takes a single
+ * unsigned thirty-two bit integer and an untyped pointer and an
+ * as arguments.
+ */
+typedef Thread ( *Thread_Entry_both_numeric_first )( uint32_t , void * );
+
+/**
+ * The following lists the algorithms used to manage the thread cpu budget.
+ *
+ * Reset Timeslice: At each context switch, reset the time quantum.
+ * Exhaust Timeslice: Only reset the quantum once it is consumed.
+ * Callout: Execute routine when budget is consumed.
+ */
+typedef enum {
+ THREAD_CPU_BUDGET_ALGORITHM_NONE,
+ THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE,
+ THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE,
+ THREAD_CPU_BUDGET_ALGORITHM_CALLOUT
+} Thread_CPU_budget_algorithms;
+
+/** This type defines the Thread Control Block structure.
+ */
+typedef struct Thread_Control_struct Thread_Control;
+
+/** This defines thes the entry point for the thread specific timeslice
+ * budget management algorithm.
+ */
+typedef void (*Thread_CPU_budget_algorithm_callout )( Thread_Control * );
+
+/** @brief Per Task Variable Manager Structure Forward Reference
+ *
+ * Forward reference to the per task variable structure.
+ */
+struct rtems_task_variable_tt;
+
+/** @brief Per Task Variable Manager Structure
+ *
+ * This is the internal structure used to manager per Task Variables.
+ */
+typedef struct {
+ /** This field points to the next per task variable for this task. */
+ struct rtems_task_variable_tt *next;
+ /** This field points to the physical memory location of this per
+ * task variable.
+ */
+ void **ptr;
+ /** This field is to the global value for this per task variable. */
+ void *gval;
+ /** This field is to this thread's value for this per task variable. */
+ void *tval;
+ /** This field points to the destructor for this per task variable. */
+ void (*dtor)(void *);
+} rtems_task_variable_t;
+
+/**
+ * The following structure contains the information which defines
+ * the starting state of a thread.
+ */
+typedef struct {
+ /** This field is the starting address for the thread. */
+ Thread_Entry entry_point;
+ /** This field indicatres the how task is invoked. */
+ Thread_Start_types prototype;
+ /** This field is the pointer argument passed at thread start. */
+ void *pointer_argument;
+ /** This field is the numeric argument passed at thread start. */
+ uint32_t numeric_argument;
+ /*-------------- initial execution modes ----------------- */
+ /** This field indicates whether the thread was preemptible when
+ * it started.
+ */
+ boolean is_preemptible;
+ /** This field indicates the CPU budget algorith. */
+ Thread_CPU_budget_algorithms budget_algorithm;
+ /** This field is the routine to invoke when the CPU allotment is
+ * consumed.
+ */
+ Thread_CPU_budget_algorithm_callout budget_callout;
+ /** This field is the initial ISR disable level of this thread. */
+ uint32_t isr_level;
+ /** This field is the initial priority. */
+ Priority_Control initial_priority;
+ /** This field indicates whether the SuperCore allocated the stack. */
+ boolean core_allocated_stack;
+ /** This field is the stack information. */
+ Stack_Control Initial_stack;
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ /** This field is the initial FP context area address. */
+ void *fp_context;
+#endif
+ /** This field is the initial stack area address. */
+ void *stack;
+} Thread_Start_information;
+
+/**
+ * The following structure contains the information necessary to manage
+ * a thread which it is waiting for a resource.
+ */
+#define THREAD_STATUS_PROXY_BLOCKING 0x1111111
+
+/** @brief Thread Blocking Management Information
+ *
+ * This contains the information required to manage a thread while it is
+ * blocked and to return information to it.
+ */
+typedef struct {
+ /** This field is the Id of the object this thread is waiting upon. */
+ Objects_Id id;
+ /** This field is used to return an integer while when blocked. */
+ uint32_t count;
+ /** This field is the first pointer to a user return argument. */
+ void *return_argument;
+ /** This field is the second pointer to a user return argument. */
+ void *return_argument_1;
+ /** This field contains any options in effect on this blocking operation. */
+ uint32_t option;
+ /** This field will contain the return status from a blocking operation.
+ *
+ * @note The following assumes that all API return codes can be
+ * treated as an uint32_t.
+ */
+ uint32_t return_code;
+
+ /** This field is the chain header for the second through Nth tasks
+ * of the same priority blocked waiting on the same object.
+ */
+ Chain_Control Block2n;
+ /** This field points to the thread queue on which this thread is blocked. */
+ Thread_queue_Control *queue;
+} Thread_Wait_information;
+
+/**
+ * The following defines the control block used to manage
+ * each thread proxy.
+ *
+ * @note It is critical that proxies and threads have identical
+ * memory images for the shared part.
+ */
+typedef struct {
+ /** This field is the object management structure for each proxy. */
+ Objects_Control Object;
+ /** This field is the current execution state of this proxy. */
+ States_Control current_state;
+ /** This field is the current priority state of this proxy. */
+ Priority_Control current_priority;
+ /** This field is the base priority of this proxy. */
+ Priority_Control real_priority;
+ /** This field is the number of mutexes currently held by this proxy. */
+ uint32_t resource_count;
+ /** This field is the blocking information for this proxy. */
+ Thread_Wait_information Wait;
+ /** This field is the Watchdog used to manage proxy delays and timeouts. */
+ Watchdog_Control Timer;
+#if defined(RTEMS_MULTIPROCESSING)
+ /** This field is the received response packet in an MP system. */
+ MP_packet_Prefix *receive_packet;
+#endif
+ /****************** end of common block ********************/
+ /** This field is used to manage the set of proxies in the system. */
+ Chain_Node Active;
+} Thread_Proxy_control;
+
+/**
+ * The following record defines the control block used
+ * to manage each thread.
+ *
+ * @note It is critical that proxies and threads have identical
+ * memory images for the shared part.
+ */
+typedef enum {
+ /** This value is for the Classic RTEMS API. */
+ THREAD_API_RTEMS,
+ /** This value is for the POSIX API. */
+ THREAD_API_POSIX,
+ /** This value is for the ITRON API. */
+ THREAD_API_ITRON
+} Thread_APIs;
+
+/** This macro defines the first API which has threads. */
+#define THREAD_API_FIRST THREAD_API_RTEMS
+
+/** This macro defines the last API which has threads. */
+#define THREAD_API_LAST THREAD_API_ITRON
+
+/**
+ * This structure defines the Thread Control Block (TCB).
+ */
+struct Thread_Control_struct {
+ /** This field is the object management structure for each thread. */
+ Objects_Control Object;
+ /** This field is the current execution state of this thread. */
+ States_Control current_state;
+ /** This field is the current priority state of this thread. */
+ Priority_Control current_priority;
+ /** This field is the base priority of this thread. */
+ Priority_Control real_priority;
+ /** This field is the number of mutexes currently held by this thread. */
+ uint32_t resource_count;
+ /** This field is the blocking information for this thread. */
+ Thread_Wait_information Wait;
+ /** This field is the Watchdog used to manage thread delays and timeouts. */
+ Watchdog_Control Timer;
+#if defined(RTEMS_MULTIPROCESSING)
+ /** This field is the received response packet in an MP system. */
+ MP_packet_Prefix *receive_packet;
+#endif
+ /*================= end of common block =================*/
+ /** This field is the number of nested suspend calls. */
+ uint32_t suspend_count;
+ /** This field is true if the thread is offered globally */
+ boolean is_global;
+ /** This field is is true if the post task context switch should be
+ * executed for this thread at the next context switch.
+ */
+ boolean do_post_task_switch_extension;
+ /** This field is true if the thread is preemptible. */
+ boolean is_preemptible;
+ /** This field is the GNAT self context pointer. */
+ void *rtems_ada_self;
+ /** This field is the length of the time quantum that this thread is
+ * allowed to consume. The algorithm used to manage limits on CPU usage
+ * is specified by budget_algorithm.
+ */
+ uint32_t cpu_time_budget;
+ /** This field is the algorithm used to manage this thread's time
+ * quantum. The algorithm may be specified as none which case,
+ * no limit is in place.
+ */
+ Thread_CPU_budget_algorithms budget_algorithm;
+ /** This field is the method invoked with the budgeted time is consumed. */
+ Thread_CPU_budget_algorithm_callout budget_callout;
+
+ /** This field is the number of clock ticks executed by this thread
+ * since it was created.
+ */
+ uint32_t ticks_executed;
+ /** This field points to the Ready FIFO for this priority. */
+ Chain_Control *ready;
+ /** This field contains precalculated priority map indices. */
+ Priority_Information Priority_map;
+ /** This field contains information about the starting state of
+ * this thread.
+ */
+ Thread_Start_information Start;
+ /** This field contains the context of this thread. */
+ Context_Control Registers;
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ /** This field points to the floating point context for this thread.
+ * If NULL, the thread is integer only.
+ */
+ void *fp_context;
+#endif
+ /** This field points to the newlib reentrancy structure for this thread. */
+ struct _reent *libc_reent;
+ /** This array contains the API extension area pointers. */
+ void *API_Extensions[ THREAD_API_LAST + 1 ];
+ /** This field points to the user extension pointers. */
+ void **extensions;
+ /** This field points to the set of per task variables. */
+ rtems_task_variable_t *task_variables;
+};
+
+/**
+ * Self for the GNU Ada Run-Time
+ */
+SCORE_EXTERN void *rtems_ada_self;
+
+/**
+ * The following defines the information control block used to
+ * manage this class of objects.
+ */
+SCORE_EXTERN Objects_Information _Thread_Internal_information;
+
+/**
+ * The following define the thread control pointers used to access
+ * and manipulate the idle thread.
+ */
+SCORE_EXTERN Thread_Control *_Thread_Idle;
+
+/**
+ * The following context area contains the context of the "thread"
+ * which invoked the start multitasking routine. This context is
+ * restored as the last action of the stop multitasking routine. Thus
+ * control of the processor can be returned to the environment
+ * which initiated the system.
+ */
+SCORE_EXTERN Context_Control _Thread_BSP_context;
+
+/**
+ * The following declares the dispatch critical section nesting
+ * counter which is used to prevent context switches at inopportune
+ * moments.
+ */
+SCORE_EXTERN volatile uint32_t _Thread_Dispatch_disable_level;
+
+/**
+ * If this is non-zero, then the post-task switch extension
+ * is run regardless of the state of the per thread flag.
+ */
+SCORE_EXTERN uint32_t _Thread_Do_post_task_switch_extension;
+
+/**
+ * The following holds how many user extensions are in the system. This
+ * is used to determine how many user extension data areas to allocate
+ * per thread.
+ */
+SCORE_EXTERN uint32_t _Thread_Maximum_extensions;
+
+/**
+ * The following is used to manage the length of a timeslice quantum.
+ */
+SCORE_EXTERN uint32_t _Thread_Ticks_per_timeslice;
+
+/**
+ * The following points to the array of FIFOs used to manage the
+ * set of ready threads.
+ */
+SCORE_EXTERN Chain_Control *_Thread_Ready_chain;
+
+/**
+ * The following points to the thread which is currently executing.
+ * This thread is implicitly manipulated by numerous directives.
+ */
+SCORE_EXTERN Thread_Control *_Thread_Executing;
+
+/**
+ * The following points to the highest priority ready thread
+ * in the system. Unless the current thread is not preemptibl,
+ * then this thread will be context switched to when the next
+ * dispatch occurs.
+ */
+SCORE_EXTERN Thread_Control *_Thread_Heir;
+
+/**
+ * The following points to the thread whose floating point
+ * context is currently loaded.
+ */
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+SCORE_EXTERN Thread_Control *_Thread_Allocated_fp;
+#endif
+
+/**
+ * The C library re-enter-rant global pointer. Some C library implementations
+ * such as newlib have a single global pointer that changed during a context
+ * switch. The pointer points to that global pointer. The Thread control block
+ * holds a pointer to the task specific data.
+ */
+SCORE_EXTERN struct _reent **_Thread_libc_reent;
+
+/**
+ * This routine performs the initialization necessary for this handler.
+ */
+void _Thread_Handler_initialization (
+ uint32_t ticks_per_timeslice,
+ uint32_t maximum_extensions,
+ uint32_t maximum_proxies
+);
+
+/**
+ * This routine creates the idle thread.
+ *
+ * @warning No thread should be created before this one.
+ */
+void _Thread_Create_idle( void );
+
+/**
+ * This routine initiates multitasking. It is invoked only as
+ * part of initialization and its invocation is the last act of
+ * the non-multitasking part of the system initialization.
+ */
+void _Thread_Start_multitasking( void );
+
+/**
+ * This routine is responsible for transferring control of the
+ * processor from the executing thread to the heir thread. As part
+ * of this process, it is responsible for the following actions:
+ *
+ * + saving the context of the executing thread
+ * + restoring the context of the heir thread
+ * + dispatching any signals for the resulting executing thread
+ */
+void _Thread_Dispatch( void );
+
+/**
+ * Allocate the requested stack space for the thread.
+ * return the actual size allocated after any adjustment
+ * or return zero if the allocation failed.
+ * Set the Start.stack field to the address of the stack
+ */
+
+uint32_t _Thread_Stack_Allocate(
+ Thread_Control *the_thread,
+ uint32_t stack_size
+);
+
+/**
+ * Deallocate the Thread's stack.
+ */
+void _Thread_Stack_Free(
+ Thread_Control *the_thread
+);
+
+/**
+ * This routine initializes the specified the thread. It allocates
+ * all memory associated with this thread. It completes by adding
+ * the thread to the local object table so operations on this
+ * thread id are allowed.
+ *
+ * @note If stack_area is NULL, it is allocated from the workspace.
+ *
+ * @note If the stack is allocated from the workspace, then it is
+ * guaranteed to be of at least minimum size.
+ */
+boolean _Thread_Initialize(
+ Objects_Information *information,
+ Thread_Control *the_thread,
+ void *stack_area,
+ uint32_t stack_size,
+ boolean is_fp,
+ Priority_Control priority,
+ boolean is_preemptible,
+ Thread_CPU_budget_algorithms budget_algorithm,
+ Thread_CPU_budget_algorithm_callout budget_callout,
+ uint32_t isr_level,
+ Objects_Name name
+);
+
+/**
+ * This routine initializes the executable information for a thread
+ * and makes it ready to execute. After this routine executes, the
+ * thread competes with all other threads for CPU time.
+ */
+boolean _Thread_Start(
+ Thread_Control *the_thread,
+ Thread_Start_types the_prototype,
+ void *entry_point,
+ void *pointer_argument,
+ uint32_t numeric_argument
+);
+
+/**
+ * This support routine restarts the specified task in a way that the
+ * next time this thread executes, it will begin execution at its
+ * original starting point.
+ *
+ * TODO: multiple task arg profiles
+ */
+boolean _Thread_Restart(
+ Thread_Control *the_thread,
+ void *pointer_argument,
+ uint32_t numeric_argument
+);
+
+/**
+ * This routine resets a thread to its initial state but does
+ * not restart it.
+ */
+void _Thread_Reset(
+ Thread_Control *the_thread,
+ void *pointer_argument,
+ uint32_t numeric_argument
+);
+
+/**
+ * This routine frees all memory associated with the specified
+ * thread and removes it from the local object table so no further
+ * operations on this thread are allowed.
+ */
+void _Thread_Close(
+ Objects_Information *information,
+ Thread_Control *the_thread
+);
+
+/**
+ * This routine removes any set states for the_thread. It performs
+ * any necessary scheduling operations including the selection of
+ * a new heir thread.
+ */
+void _Thread_Ready(
+ Thread_Control *the_thread
+);
+
+/**
+ * This routine clears the indicated STATES for the_thread. It performs
+ * any necessary scheduling operations including the selection of
+ * a new heir thread.
+ */
+void _Thread_Clear_state(
+ Thread_Control *the_thread,
+ States_Control state
+);
+
+/**
+ * This routine sets the indicated states for the_thread. It performs
+ * any necessary scheduling operations including the selection of
+ * a new heir thread.
+ */
+void _Thread_Set_state(
+ Thread_Control *the_thread,
+ States_Control state
+);
+
+/**
+ * This routine sets the TRANSIENT state for the_thread. It performs
+ * any necessary scheduling operations including the selection of
+ * a new heir thread.
+ */
+void _Thread_Set_transient(
+ Thread_Control *the_thread
+);
+
+/**
+ * This routine is invoked upon expiration of the currently
+ * executing thread's timeslice. If no other thread's are ready
+ * at the priority of the currently executing thread, then the
+ * executing thread's timeslice is reset. Otherwise, the
+ * currently executing thread is placed at the rear of the
+ * FIFO for this priority and a new heir is selected.
+ */
+void _Thread_Reset_timeslice( void );
+
+/**
+ * This routine is invoked as part of processing each clock tick.
+ * It is responsible for determining if the current thread allows
+ * timeslicing and, if so, when its timeslice expires.
+ */
+void _Thread_Tickle_timeslice( void );
+
+/**
+ * This routine is invoked when a thread wishes to voluntarily
+ * transfer control of the processor to another thread of equal
+ * or greater priority.
+ */
+void _Thread_Yield_processor( void );
+
+/**
+ * This routine is invoked to rotate the ready queue for the
+ * given priority. It can be used to yeild the processor
+ * by rotating the executing threads ready queue.
+ */
+void _Thread_Rotate_Ready_Queue(
+ Priority_Control priority
+);
+
+/**
+ * This routine initializes the context of the_thread to its
+ * appropriate starting state.
+ */
+void _Thread_Load_environment(
+ Thread_Control *the_thread
+);
+
+/**
+ * This routine is the wrapper function for all threads. It is
+ * the starting point for all threads. The user provided thread
+ * entry point is invoked by this routine. Operations
+ * which must be performed immediately before and after the user's
+ * thread executes are found here.
+ */
+void _Thread_Handler( void );
+
+/**
+ * This routine is invoked when a thread must be unblocked at the
+ * end of a time based delay (i.e. wake after or wake when).
+ */
+void _Thread_Delay_ended(
+ Objects_Id id,
+ void *ignored
+);
+
+/**
+ * This routine changes the current priority of the_thread to
+ * new_priority. It performs any necessary scheduling operations
+ * including the selection of a new heir thread.
+ */
+void _Thread_Change_priority (
+ Thread_Control *the_thread,
+ Priority_Control new_priority,
+ boolean prepend_it
+);
+
+/**
+ * This routine updates the priority related fields in the_thread
+ * control block to indicate the current priority is now new_priority.
+ */
+void _Thread_Set_priority(
+ Thread_Control *the_thread,
+ Priority_Control new_priority
+);
+
+/**
+ * This routine updates the related suspend fields in the_thread
+ * control block to indicate the current nested level.
+ */
+void _Thread_Suspend(
+ Thread_Control *the_thread
+);
+
+/**
+ * This routine updates the related suspend fields in the_thread
+ * control block to indicate the current nested level. A force
+ * parameter of TRUE will force a resume and clear the suspend count.
+ */
+void _Thread_Resume(
+ Thread_Control *the_thread,
+ boolean force
+);
+
+/**
+ * This routine evaluates the current scheduling information for the
+ * system and determines if a context switch is required. This
+ * is usually called after changing an execution mode such as preemptability
+ * for a thread.
+ */
+boolean _Thread_Evaluate_mode( void );
+
+#ifndef RTEMS_INLINES
+/**
+ * @note If we are not using static inlines, this must be a real
+ * subroutine call.
+ */
+Thread_Control *_Thread_Get (
+ Objects_Id id,
+ Objects_Locations *location
+);
+#endif
+
+#if (CPU_PROVIDES_IDLE_THREAD_BODY == FALSE)
+/**
+ * This routine is the body of the system idle thread.
+ */
+Thread _Thread_Idle_body(
+ uint32_t ignored
+);
+#endif
+
+/** This defines the type for a method which operates on a single thread.
+ */
+typedef void (*rtems_per_thread_routine)( Thread_Control * );
+
+/**
+ * This routine iterates over all threads regardless of API and
+ * invokes the specified routine.
+ */
+void rtems_iterate_over_all_threads(
+ rtems_per_thread_routine routine
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/thread.inl>
+#endif
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/threadmp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/threadmp.h b/cpukit/score/include/rtems/score/threadmp.h
new file mode 100644
index 0000000000..d187f69398
--- /dev/null
+++ b/cpukit/score/include/rtems/score/threadmp.h
@@ -0,0 +1,88 @@
+/**
+ * @file rtems/score/threadmp.h
+ *
+ * This include file contains the specification for all routines
+ * and data specific to the multiprocessing portion of the thread package.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_THREADMP_H
+#define _RTEMS_SCORE_THREADMP_H
+
+/**
+ * @defgroup ScoreThreadMP Thread Handler Multiprocessing Support
+ *
+ * This handler encapsulates functionality which is related to managing
+ * threads in a multiprocessor system configuration. This handler must
+ * manage proxies which represent remote threads blocking on local
+ * operations.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief _Thread_MP_Handler_initialization
+ *
+ * This routine initializes the multiprocessing portion of the Thread Handler.
+ */
+void _Thread_MP_Handler_initialization (
+ uint32_t maximum_proxies
+);
+
+/** @brief _Thread_MP_Allocate_proxy
+ *
+ * This allocates a proxy control block from
+ * the inactive chain of free proxy control blocks.
+ *
+ * @note This function returns a thread control pointer
+ * because proxies are substitutes for remote threads.
+ */
+Thread_Control *_Thread_MP_Allocate_proxy (
+ States_Control the_state
+);
+
+/** @brief _Thread_MP_Find_proxy
+ *
+ * This function removes the proxy control block for the specified
+ * id from the active chain of proxy control blocks.
+ */
+Thread_Control *_Thread_MP_Find_proxy (
+ Objects_Id the_id
+);
+
+/** @brief Active Proxy Set
+ *
+ * The following chain is used to manage the active set proxies.
+ */
+SCORE_EXTERN Chain_Control _Thread_MP_Active_proxies;
+
+/** @brief Inactive Proxy Set
+ *
+ * The following chain is used to manage the inactive set of proxies.
+ */
+SCORE_EXTERN Chain_Control _Thread_MP_Inactive_proxies;
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/threadmp.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h
new file mode 100644
index 0000000000..51ac3377ba
--- /dev/null
+++ b/cpukit/score/include/rtems/score/threadq.h
@@ -0,0 +1,230 @@
+/**
+ * @file rtems/score/threadq.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the manipulation of objects.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_THREADQ_H
+#define _RTEMS_SCORE_THREADQ_H
+
+/**
+ * @defgroup ScoreThreadQ Thread Queue Handler
+ *
+ * This handler encapsulates functionality related to managing sets of threads
+ * blocked waiting for resources.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/tqdata.h>
+
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+/**
+ * Constant for indefinite wait.
+ */
+#define THREAD_QUEUE_WAIT_FOREVER WATCHDOG_NO_TIMEOUT
+
+/**
+ * The following type defines the callout used when a remote task
+ * is extracted from a local thread queue.
+ */
+typedef void ( *Thread_queue_Flush_callout )(
+ Thread_Control *
+ );
+
+/** @brief Thread queue Dequeue
+ *
+ * This function returns a pointer to a thread waiting on
+ * the_thread_queue. The selection of this thread is based on
+ * the discipline of the_thread_queue. If no threads are waiting
+ * on the_thread_queue, then NULL is returned.
+ */
+Thread_Control *_Thread_queue_Dequeue(
+ Thread_queue_Control *the_thread_queue
+);
+
+/** @brief Thread queue Enqueue
+ *
+ * This routine enqueues the currently executing thread on
+ * the_thread_queue with an optional timeout.
+ */
+void _Thread_queue_Enqueue(
+ Thread_queue_Control *the_thread_queue,
+ Watchdog_Interval timeout
+);
+
+/** @brief Thread queue Extract
+ *
+ * This routine removes the_thread from the_thread_queue
+ * and cancels any timeouts associated with this blocking.
+ */
+void _Thread_queue_Extract(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread
+);
+
+/** @brief Thread queue Extract with proxy
+ *
+ * This routine extracts the_thread from the_thread_queue
+ * and ensures that if there is a proxy for this task on
+ * another node, it is also dealt with.
+ */
+boolean _Thread_queue_Extract_with_proxy(
+ Thread_Control *the_thread
+);
+
+/** @brief Thread queue First
+ *
+ * This function returns a pointer to the "first" thread
+ * on the_thread_queue. The "first" thread is selected
+ * based on the discipline of the_thread_queue.
+ */
+Thread_Control *_Thread_queue_First(
+ Thread_queue_Control *the_thread_queue
+);
+
+/** @brief Thread queue Flush
+ *
+ * This routine unblocks all threads blocked on the_thread_queue
+ * and cancels any associated timeouts.
+ */
+void _Thread_queue_Flush(
+ Thread_queue_Control *the_thread_queue,
+ Thread_queue_Flush_callout remote_extract_callout,
+ uint32_t status
+);
+
+/** @brief Thread queue Initialize
+ *
+ * This routine initializes the_thread_queue based on the
+ * discipline indicated in attribute_set. The state set on
+ * threads which block on the_thread_queue is state.
+ */
+void _Thread_queue_Initialize(
+ Thread_queue_Control *the_thread_queue,
+ Thread_queue_Disciplines the_discipline,
+ States_Control state,
+ uint32_t timeout_status
+);
+
+/** @brief Thread queue Dequeue priority
+ *
+ * This function returns a pointer to the highest priority
+ * thread waiting on the_thread_queue. If no threads are waiting
+ * on the_thread_queue, then NULL is returned.
+ */
+Thread_Control *_Thread_queue_Dequeue_priority(
+ Thread_queue_Control *the_thread_queue
+);
+
+/** @brief Thread queue Enqueue priority
+ *
+ * This routine enqueues the currently executing thread on
+ * the_thread_queue with an optional timeout using the
+ * priority discipline.
+ */
+void _Thread_queue_Enqueue_priority(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread
+);
+
+/** @brief Thread queue Extract priority
+ *
+ * This routine removes the_thread from the_thread_queue
+ * and cancels any timeouts associated with this blocking.
+ */
+void _Thread_queue_Extract_priority(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread
+);
+
+/** @brief Thread queue First priority
+ *
+ * This function returns a pointer to the "first" thread
+ * on the_thread_queue. The "first" thread is the highest
+ * priority thread waiting on the_thread_queue.
+ */
+Thread_Control *_Thread_queue_First_priority(
+ Thread_queue_Control *the_thread_queue
+);
+
+/** @brief Thread queue Dequeue FIFO
+ *
+ * This function returns a pointer to the thread which has
+ * been waiting the longest on the_thread_queue. If no
+ * threads are waiting on the_thread_queue, then NULL is returned.
+ */
+Thread_Control *_Thread_queue_Dequeue_fifo(
+ Thread_queue_Control *the_thread_queue
+);
+
+/** @brief Thread queue Enqueue FIFO
+ *
+ * This routine enqueues the currently executing thread on
+ * the_thread_queue with an optional timeout using the
+ * FIFO discipline.
+ */
+void _Thread_queue_Enqueue_fifo(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread
+);
+
+/** @brief Thread queue Extract FIFO
+ *
+ * This routine removes the_thread from the_thread_queue
+ * and cancels any timeouts associated with this blocking.
+ */
+void _Thread_queue_Extract_fifo(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread
+);
+
+/** @brief Thread queue First FIFO
+ *
+ * This function returns a pointer to the "first" thread
+ * on the_thread_queue. The first thread is the thread
+ * which has been waiting longest on the_thread_queue.
+ */
+Thread_Control *_Thread_queue_First_fifo(
+ Thread_queue_Control *the_thread_queue
+);
+
+/** @brief Thread queue timeout
+ *
+ * This routine is invoked when a task's request has not
+ * been satisfied after the timeout interval specified to
+ * enqueue. The task represented by ID will be unblocked and
+ * its status code will be set in it's control block to indicate
+ * that a timeout has occurred.
+ */
+void _Thread_queue_Timeout (
+ Objects_Id id,
+ void *ignored
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/tod.h b/cpukit/score/include/rtems/score/tod.h
new file mode 100644
index 0000000000..af416a529d
--- /dev/null
+++ b/cpukit/score/include/rtems/score/tod.h
@@ -0,0 +1,314 @@
+/**
+ * @file rtems/score/tod.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Time of Day Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TOD_H
+#define _RTEMS_SCORE_TOD_H
+
+/**
+ * @defgroup ScoreTOD Time Of Day (TOD) Handler
+ *
+ * This handler encapsulates functionality used to manage time of day.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+#include <rtems/score/watchdog.h>
+
+/** @defgroup ScoreTODConstants TOD Constants
+ * The following constants are related to the time of day.
+ */
+/**@{*/
+
+/**
+ * This constant represents the number of seconds in a minute.
+ */
+#define TOD_SECONDS_PER_MINUTE (uint32_t)60
+
+/**
+ * This constant represents the number of minutes per hour.
+ */
+#define TOD_MINUTES_PER_HOUR (uint32_t)60
+
+/**
+ * This constant represents the number of months in a year.
+ */
+#define TOD_MONTHS_PER_YEAR (uint32_t)12
+
+/**
+ * This constant represents the number of days in a non-leap year.
+ */
+#define TOD_DAYS_PER_YEAR (uint32_t)365
+
+/**
+ * This constant represents the number of hours per day.
+ */
+#define TOD_HOURS_PER_DAY (uint32_t)24
+
+/**
+ * This constant represents the number of seconds in a day which does
+ * not include a leap second.
+ */
+#define TOD_SECONDS_PER_DAY (uint32_t) (TOD_SECONDS_PER_MINUTE * \
+ TOD_MINUTES_PER_HOUR * \
+ TOD_HOURS_PER_DAY)
+
+/**
+ * This constant represents the number of seconds in a non-leap year.
+ */
+#define TOD_SECONDS_PER_NON_LEAP_YEAR (365 * TOD_SECONDS_PER_DAY)
+
+/**
+ * This constant represents the number of seconds in a millisecond.
+ */
+#define TOD_MILLISECONDS_PER_SECOND (uint32_t)1000
+
+/**
+ * This constant represents the number of microseconds in a second.
+ */
+#define TOD_MICROSECONDS_PER_SECOND (uint32_t)1000000
+
+/**
+ * This constant represents the number of nanoseconds in a second.
+ */
+#define TOD_NANOSECONDS_PER_SECOND (uint32_t)1000000000
+
+/**
+ * This constant represents the number of nanoseconds in a second.
+ */
+#define TOD_NANOSECONDS_PER_MICROSECOND (uint32_t)1000
+
+/**@}*/
+
+/** @brief RTEMS Epoch Year
+ *
+ * The following constant define the earliest year to which an
+ * time of day can be initialized. This is considered the
+ * epoch.
+ */
+#define TOD_BASE_YEAR 1988
+
+/**
+ * The following record defines the time of control block. This
+ * control block is used to maintain the current time of day.
+ *
+ * @note This is an RTEID style time/date.
+ */
+typedef struct {
+ /** This field is the year, A.D. */
+ uint32_t year;
+ /** This field is the month, 1 -> 12 */
+ uint32_t month;
+ /** This field is the day, 1 -> 31 */
+ uint32_t day;
+ /** This field is the hour, 0 -> 23 */
+ uint32_t hour;
+ /** This field is the minute, 0 -> 59 */
+ uint32_t minute;
+ /** This field is the second, 0 -> 59 */
+ uint32_t second;
+ /** This field is the elapsed ticks between secs */
+ uint32_t ticks;
+} TOD_Control;
+
+/** @brief Is the Time Of Day Set
+ *
+ * This is TRUE if the application has set the current
+ * time of day, and FALSE otherwise.
+ */
+SCORE_EXTERN boolean _TOD_Is_set;
+
+/** @brief Current Time of Day
+ * The following contains the current time of day.
+ */
+SCORE_EXTERN TOD_Control _TOD_Current;
+
+/** @brief Seconds Since RTEMS Epoch
+ * The following contains the number of seconds from 00:00:00
+ * January 1, TOD_BASE_YEAR until the current time of day.
+ */
+SCORE_EXTERN Watchdog_Interval _TOD_Seconds_since_epoch;
+
+/** @brief Microseconds per Clock Tick
+ *
+ * The following contains the number of microseconds per tick.
+ */
+SCORE_EXTERN uint32_t _TOD_Microseconds_per_tick;
+
+/** @brief Clock Ticks per Second
+ *
+ * The following contains the number of clock ticks per second.
+ *
+ * @note If one second is NOT evenly divisible by the number of microseconds
+ * per clock tick, this value will contain only the integer portion
+ * of the division. This means that the interval between clock ticks
+ * can be a source of error in the current time of day.
+ */
+SCORE_EXTERN uint32_t _TOD_Ticks_per_second;
+
+/** @brief Watchdog Set Managed by Seconds
+ *
+ * This is the control structure for the watchdog timer which
+ * fires to service the seconds chain.
+ */
+SCORE_EXTERN Watchdog_Control _TOD_Seconds_watchdog;
+
+#ifdef SCORE_INIT
+
+/*
+ * The following array contains the number of days in all months.
+ * The first dimension should be 1 for leap years, and 0 otherwise.
+ * The second dimension should range from 1 to 12 for January to
+ * February, respectively.
+ */
+const uint32_t _TOD_Days_per_month[ 2 ][ 13 ] = {
+ { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+/*
+ * The following array contains the number of days in all months
+ * up to the month indicated by the index of the second dimension.
+ * The first dimension should be 1 for leap years, and 0 otherwise.
+ */
+const uint16_t _TOD_Days_to_date[2][13] = {
+ { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
+ { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
+};
+
+/*
+ * The following array contains the number of days in the years
+ * since the last leap year. The index should be 0 for leap
+ * years, and the number of years since the beginning of a leap
+ * year otherwise.
+ */
+const uint16_t _TOD_Days_since_last_leap_year[4] = { 0, 366, 731, 1096 };
+
+#else
+
+/** @brief Convert Month to Julian Days
+ *
+ * This is a prototype for a table which assists in converting the
+ * current day into the Julian days since the first of the year.
+ */
+extern const uint16_t _TOD_Days_to_date[2][13]; /* Julian days */
+
+/** @brief Days since Beginning of Last Leap Year
+ *
+ * This is a prototype for a table which assists in calculating the
+ * number of days since the beginning of the last leap year.
+ */
+extern const uint16_t _TOD_Days_since_last_leap_year[4];
+
+/** @brief Days Per Month Table
+ *
+ * This is a prototype for a table which holds the number of days
+ * per month for a leap year and non-leap year.
+ */
+extern const uint32_t _TOD_Days_per_month[2][13];
+
+#endif
+
+/** @brief _TOD_Handler_initialization
+ *
+ * This routine performs the initialization necessary for this handler.
+ */
+void _TOD_Handler_initialization(
+ uint32_t microseconds_per_tick
+);
+
+/** @brief _TOD_Set
+ *
+ * This routine sets the current time of day to THE_TOD and
+ * the equivalent SECONDS_SINCE_EPOCH.
+ */
+void _TOD_Set(
+ TOD_Control *the_tod,
+ Watchdog_Interval seconds_since_epoch
+);
+
+/** @brief _TOD_Validate
+ *
+ * This function returns TRUE if THE_TOD contains
+ * a valid time of day, and FALSE otherwise.
+ */
+boolean _TOD_Validate(
+ TOD_Control *the_tod
+);
+
+/** @brief _TOD_To_seconds
+ *
+ * This function returns the number seconds between the epoch and THE_TOD.
+ */
+Watchdog_Interval _TOD_To_seconds(
+ TOD_Control *the_tod
+);
+
+/** @brief _TOD_Tickle
+ *
+ * This routine is scheduled as a watchdog function and is invoked at
+ * each second boundary. It updates the current time of day to indicate
+ * that a second has passed and processes the seconds watchdog chain.
+ */
+void _TOD_Tickle(
+ Objects_Id id,
+ void *ignored
+);
+
+/** @brief TOD_MILLISECONDS_TO_MICROSECONDS
+ *
+ * This routine converts an interval expressed in milliseconds to microseconds.
+ *
+ * @note This must be a macro so it can be used in "static" tables.
+ */
+#define TOD_MILLISECONDS_TO_MICROSECONDS(_ms) ((_ms) * 1000)
+
+/** @brief TOD_MICROSECONDS_TO_TICKS
+ *
+ * This routine converts an interval expressed in microseconds to ticks.
+ *
+ * @note This must be a macro so it can be used in "static" tables.
+ */
+#define TOD_MICROSECONDS_TO_TICKS(_us) \
+ ((_us) / _TOD_Microseconds_per_tick)
+
+/** @brief TOD_MILLISECONDS_TO_TICKS
+ *
+ * This routine converts an interval expressed in milliseconds to ticks.
+ *
+ * @note This must be a macro so it can be used in "static" tables.
+ */
+
+#define TOD_MILLISECONDS_TO_TICKS(_ms) \
+ (TOD_MILLISECONDS_TO_MICROSECONDS(_ms) / _TOD_Microseconds_per_tick)
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/tod.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/tqdata.h b/cpukit/score/include/rtems/score/tqdata.h
new file mode 100644
index 0000000000..b70124ff9e
--- /dev/null
+++ b/cpukit/score/include/rtems/score/tqdata.h
@@ -0,0 +1,126 @@
+/**
+ * @file rtems/score/tqdata.h
+ *
+ * This include file contains all the constants and structures
+ * needed to declare a thread queue.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TQDATA_H
+#define _RTEMS_SCORE_TQDATA_H
+
+/**
+ * @defgroup ScoreThreadQData Thread Queue Handler Data Definition
+ *
+ * This handler defines the data shared between the thread and thread
+ * queue handlers. Having this handler define these data structure
+ * avoids potentially circular references.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/chain.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+
+/**
+ * The following enumerated type details all of the disciplines
+ * supported by the Thread Queue Handler.
+ */
+typedef enum {
+ THREAD_QUEUE_DISCIPLINE_FIFO, /* FIFO queue discipline */
+ THREAD_QUEUE_DISCIPLINE_PRIORITY /* PRIORITY queue discipline */
+} Thread_queue_Disciplines;
+
+/**
+ * The following enumerated types indicate what happened while the thread
+ * queue was in the synchronization window.
+ */
+typedef enum {
+ THREAD_QUEUE_SYNCHRONIZED,
+ THREAD_QUEUE_NOTHING_HAPPENED,
+ THREAD_QUEUE_TIMEOUT,
+ THREAD_QUEUE_SATISFIED
+} Thread_queue_States;
+
+/**
+ * This is one of the constants used to manage the priority queues.
+ *
+ * There are four chains used to maintain a priority -- each chain
+ * manages a distinct set of task priorities. The number of chains
+ * is determined by TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS.
+ * The following set must be consistent.
+ *
+ * The set below configures 4 headers -- each contains 64 priorities.
+ * Header x manages priority range (x*64) through ((x*64)+63). If
+ * the priority is more than half way through the priority range it
+ * is in, then the search is performed from the rear of the chain.
+ * This halves the search time to find the insertion point.
+ */
+#define TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS 4
+
+/**
+ * This is one of the constants used to manage the priority queues.
+ * @ref TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS for more details.
+ */
+#define TASK_QUEUE_DATA_PRIORITIES_PER_HEADER 64
+
+/**
+ * This is one of the constants used to manage the priority queues.
+ * @ref TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS for more details.
+ */
+#define TASK_QUEUE_DATA_REVERSE_SEARCH_MASK 0x20
+
+/**
+ * This is the structure used to manage sets of tasks which are blocked
+ * waiting to acquire a resource.
+ */
+typedef struct {
+ /** This union contains the data structures used to manage the blocked
+ * set of tasks which varies based upon the discipline.
+ */
+ union {
+ /** This is the FIFO discipline list. */
+ Chain_Control Fifo;
+ /** This is the set of lists for priority discipline waiting. */
+ Chain_Control Priority[TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS];
+ } Queues;
+ /** This field is used to manage the critical section. */
+ Thread_queue_States sync_state;
+ /** This field indicates the thread queue's blocking discipline. */
+ Thread_queue_Disciplines discipline;
+ /** This indicates the blocking state for threads waiting on this
+ * thread queue.
+ */
+ States_Control state;
+ /** This is the status value returned to threads which timeout while
+ * waiting on this thread queue.
+ */
+ uint32_t timeout_status;
+} Thread_queue_Control;
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/tqdata.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/userext.h b/cpukit/score/include/rtems/score/userext.h
new file mode 100644
index 0000000000..dcc8c80031
--- /dev/null
+++ b/cpukit/score/include/rtems/score/userext.h
@@ -0,0 +1,300 @@
+/**
+ * @file rtems/score/userext.h
+ *
+ * This include file contains all information about user extensions. This
+ * Handler provides mechanisms which can be used to initialize and manipulate
+ * all user extensions.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_USEREXT_H
+#define _RTEMS_SCORE_USEREXT_H
+
+/**
+ * @defgroup ScoreUserExt User Extension Handler
+ *
+ * This handler encapsulates functionality related to the management of
+ * the user extensions to the SuperCore that are available to the user.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/interr.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/thread.h>
+
+/*@}*/
+
+/** @defgroup ScoreUserExtStruct User Extension Handler Structures
+ *
+ * The following records defines the User Extension Table.
+ * This table defines the application dependent routines which
+ * are invoked at critical points in the life of each thread and
+ * the system as a whole.
+ */
+/*@{*/
+
+/**
+ * This type indicates the return type of a user extension method.
+ */
+typedef void User_extensions_routine;
+
+/**
+ * This type defines the prototype of a thread creation extension handler.
+ * The handler is passed the thread executing and the thread being created.
+ */
+typedef boolean ( *User_extensions_thread_create_extension )(
+ Thread_Control *,
+ Thread_Control *
+ );
+
+/**
+ * This type defines the prototype of a thread deletion extension handler.
+ * The handler is passed the thread executing and the thread being deleted.
+ */
+typedef User_extensions_routine ( *User_extensions_thread_delete_extension )(
+ Thread_Control *,
+ Thread_Control *
+ );
+
+/**
+ * This type defines the prototype of thread starting extension handler.
+ * The handler is passed the thread executing and the thread being started.
+ */
+typedef User_extensions_routine ( *User_extensions_thread_start_extension )(
+ Thread_Control *,
+ Thread_Control *
+ );
+
+/**
+ * This type defines the prototype of a thread restarting extension handler.
+ * The handler is passed the thread executing and the thread being restarted.
+ */
+typedef User_extensions_routine ( *User_extensions_thread_restart_extension )(
+ Thread_Control *,
+ Thread_Control *
+ );
+
+/**
+ * This type defines the prototype of thread context switch extension handler.
+ * The handler is passed the thread currently executing and the thread being
+ * switched to.
+ */
+typedef User_extensions_routine ( *User_extensions_thread_switch_extension )(
+ Thread_Control *,
+ Thread_Control *
+ );
+
+/**
+ * This type defines the prototype of a post context switch extension handler.
+ * The handler is passed the thread thread being switched to.
+ */
+typedef User_extensions_routine (*User_extensions_thread_post_switch_extension)(
+ Thread_Control *
+ );
+
+/**
+ * This type defines the prototype of a thread beginning to execute
+ * extension handler. The handler is passed the thread executing. This
+ * extension is executed in the context of the beginning thread.
+ */
+typedef User_extensions_routine ( *User_extensions_thread_begin_extension )(
+ Thread_Control *
+ );
+
+/**
+ * This type defines the prototype of a thread exiting extension handler.
+ * The handler is passed the thread exiting.
+ */
+typedef User_extensions_routine ( *User_extensions_thread_exitted_extension )(
+ Thread_Control *
+ );
+
+/**
+ * This type defines the prototype of the fatal error extension handler.
+ * The handler is passed an indicator of the source of the fatal error,
+ * whether it is internal to RTEMS and an error code.
+ */
+typedef User_extensions_routine ( *User_extensions_fatal_extension )(
+ Internal_errors_Source /* the_source */,
+ boolean /* is_internal */,
+ uint32_t /* the_error */
+ );
+
+/**
+ * This type defines a set of user extensions.
+ */
+typedef struct {
+ /** This field is the thread creation handler. */
+ User_extensions_thread_create_extension thread_create;
+ /** This field is the thread starting handler. */
+ User_extensions_thread_start_extension thread_start;
+ /** This field is the thread restarting handler. */
+ User_extensions_thread_restart_extension thread_restart;
+ /** This field is the thread deleting handler */
+ User_extensions_thread_delete_extension thread_delete;
+ /** This field is thread context switch handler. */
+ User_extensions_thread_switch_extension thread_switch;
+ /** This field is the thread beginning handler. */
+ User_extensions_thread_begin_extension thread_begin;
+ /** This field is thread exiting handler. */
+ User_extensions_thread_exitted_extension thread_exitted;
+ /** This field is the fatal error extension. */
+ User_extensions_fatal_extension fatal;
+} User_extensions_Table;
+
+/**
+ * This is used to manage the list of switch handlers. They are managed
+ * separately from other extensions for performance reasons.
+ */
+typedef struct {
+ /** This field is a Chain Node structure and allows this to be placed on
+ * chains for set management.
+ */
+ Chain_Node Node;
+ /** This field is the thread switch extension. */
+ User_extensions_thread_switch_extension thread_switch;
+} User_extensions_Switch_control;
+
+/**
+ * This is used to manage each user extension set.
+ * The switch control is part of the extensions control even
+ * if not used due to the extension not having a switch
+ * handler.
+ */
+typedef struct {
+ /** This field is a Chain Node structure and allows this to be placed on
+ * chains for set management.
+ */
+ Chain_Node Node;
+ /** This field is the thread switch user extension. */
+ User_extensions_Switch_control Switch;
+ /** This field is the rest of this user extension's entry points. */
+ User_extensions_Table Callouts;
+} User_extensions_Control;
+
+/**
+ * This is used to manage the list of active extensions.
+ */
+SCORE_EXTERN Chain_Control _User_extensions_List;
+
+/**
+ * This is used to manage a chain of user extension task
+ * switch nodes.
+ */
+SCORE_EXTERN Chain_Control _User_extensions_Switches_list;
+
+/*@}*/
+/** @addtogroup ScoreUserExt */
+
+/*@{*/
+
+/** @brief User extensions Thread create
+ *
+ * This routine is used to invoke the user extension for
+ * the thread creation operate.
+ *
+ * @param[in] the_thread is the thread being created.
+ *
+ * @return This method returns TRUE if the user extension executed
+ * successfully.
+ */
+boolean _User_extensions_Thread_create (
+ Thread_Control *the_thread
+);
+
+/** @brief User extensions Thread delete
+ *
+ * This routine is used to invoke the user extension for
+ * the thread deletion operation.
+ *
+ * @param[in] the_thread is the thread being deleted.
+ */
+void _User_extensions_Thread_delete (
+ Thread_Control *the_thread
+);
+
+/** @brief User extensions Thread start
+ *
+ * This routine is used to invoke the user extension for
+ * the thread start operation.
+ *
+ * @param[in] the_thread is the thread being started.
+ */
+void _User_extensions_Thread_start (
+ Thread_Control *the_thread
+);
+
+/** @brief User extensions Thread restart
+ *
+ * This routine is used to invoke the user extension for
+ * the thread restart operation.
+ *
+ * @param[in] the_thread is the thread being restarted.
+ */
+void _User_extensions_Thread_restart (
+ Thread_Control *the_thread
+);
+
+/** @brief User extensions Thread begin
+ *
+ * This routine is used to invoke the user extension which
+ * is invoked when a thread begins.
+ *
+ * @param[in] executing is the thread beginning to execute.
+ */
+void _User_extensions_Thread_begin (
+ Thread_Control *executing
+);
+
+/** @brief User extensions Thread exitted
+ *
+ * This routine is used to invoke the user extension which
+ * is invoked when a thread exits.
+ *
+ * @param[in] executing is the thread voluntarily exiting.
+ */
+void _User_extensions_Thread_exitted (
+ Thread_Control *executing
+);
+
+/** @brief User extensions Fatal
+ *
+ * This routine is used to invoke the user extension invoked
+ * when a fatal error occurs.
+ *
+ * @param[in] the_source is the source of the fatal error.
+ * @param[in] is_internal is TRUE if the error originated inside RTEMS.
+ * @param[in] the_error is an indication of the actual error.
+ */
+void _User_extensions_Fatal (
+ Internal_errors_Source the_source,
+ boolean is_internal,
+ uint32_t the_error
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/userext.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/watchdog.h b/cpukit/score/include/rtems/score/watchdog.h
new file mode 100644
index 0000000000..fc902ad8c7
--- /dev/null
+++ b/cpukit/score/include/rtems/score/watchdog.h
@@ -0,0 +1,244 @@
+/**
+ * @file rtems/score/watchdog.h
+ *
+ * This include file contains all the constants and structures associated
+ * with watchdog timers. This Handler provides mechanisms which can be
+ * used to initialize and manipulate watchdog timers.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_WATCHDOG_H
+#define _RTEMS_SCORE_WATCHDOG_H
+
+/**
+ * @defgroup ScoreWatchdog Watchdog Handler
+ *
+ * This handler encapsulates functionality related to the scheduling of
+ * watchdog functions to be called at specific times in the future.
+ *
+ * @note This handler does not have anything to do with hardware watchdog
+ * timers.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+
+/** @brief Maximum Interval Length
+ *
+ * The following type defines the control block used to manage
+ * intervals.
+ */
+#define WATCHDOG_MAXIMUM_INTERVAL ((Watchdog_Interval) 0xffffffff)
+
+/** @brief Watchdog Interval Type
+ *
+ * This type is used to specify the length of intervals.
+ */
+typedef uint32_t Watchdog_Interval;
+
+/** @brief Watchdog Service Routine Return Type
+ *
+ * This type defines the return type from a Watchdog Service Routine.
+ */
+typedef void Watchdog_Service_routine;
+
+/** @brief Watchdog Service Routine Pointer Type
+ *
+ * This type define a pointer to a watchdog service routine.
+ */
+typedef Watchdog_Service_routine ( *Watchdog_Service_routine_entry )(
+ Objects_Id,
+ void *
+ );
+
+/** @brief No timeout constant
+ *
+ * This is the constant for indefinite wait. It is actually an
+ * illegal interval.
+ */
+#define WATCHDOG_NO_TIMEOUT 0
+
+/** @brief Watchdog States Type
+ *
+ * This enumerated type is the set of the states in which a
+ * watchdog timer may be at any given time.
+ */
+
+typedef enum {
+ /** This is the state when the watchdog is off all chains */
+ WATCHDOG_INACTIVE,
+ /** This is the state when the watchdog is off all chains, but we are
+ * currently searching for the insertion point.
+ */
+ WATCHDOG_BEING_INSERTED,
+ /** This is the state when the watchdog is on a chain, and allowed to fire. */
+ WATCHDOG_ACTIVE,
+ /** This is the state when the watchdog is on a chain, but we should
+ * remove without firing if it expires.
+ */
+ WATCHDOG_REMOVE_IT
+} Watchdog_States;
+
+/** @brief Watchdog Adjustment Directions Type
+ *
+ * The following enumerated type details the manner in which
+ * a watchdog chain may be adjusted by the @ref _Watchdog_Adjust
+ * routine. The direction indicates a movement FORWARD
+ * or BACKWARD in time.
+ */
+typedef enum {
+ /** adjust delta value forward */
+ WATCHDOG_FORWARD,
+ /** adjust delta value backward */
+ WATCHDOG_BACKWARD
+} Watchdog_Adjust_directions;
+
+/** @brief Watchdog Control Structure
+ *
+ * The following record defines the control block used
+ * to manage each watchdog timer.
+ */
+typedef struct {
+ /** This field is a Chain Node structure and allows this to be placed on
+ * chains for set management.
+ */
+ Chain_Node Node;
+ /** This field is the state of the watchdog. */
+ Watchdog_States state;
+ /** This field is the initially requested interval. */
+ Watchdog_Interval initial;
+ /** This field is the remaining portion of the interval. */
+ Watchdog_Interval delta_interval;
+ /** This field is the number of system clock ticks when this was scheduled. */
+ Watchdog_Interval start_time;
+ /** This field is the number of system clock ticks when this was suspended. */
+ Watchdog_Interval stop_time;
+ /** This field is the function to invoke. */
+ Watchdog_Service_routine_entry routine;
+ /** This field is the Id to pass as an argument to the routine. */
+ Objects_Id id;
+ /** This field is an untyped pointer to user data that is passed to the
+ * watchdog handler routine.
+ */
+ void *user_data;
+} Watchdog_Control;
+
+/** @brief Watchdog Synchronization Level
+ *
+ * This used for synchronization purposes
+ * during an insert on a watchdog delta chain.
+ */
+SCORE_EXTERN volatile uint32_t _Watchdog_Sync_level;
+
+/** @brief Watchdog Synchronization Count
+ *
+ * This used for synchronization purposes
+ * during an insert on a watchdog delta chain.
+ */
+SCORE_EXTERN volatile uint32_t _Watchdog_Sync_count;
+
+/** @brief Ticks Since System Boot
+ *
+ * This contains the number of ticks since the system was booted.
+ */
+
+SCORE_EXTERN volatile Watchdog_Interval _Watchdog_Ticks_since_boot;
+
+/** @brief Per Ticks Watchdog List
+ *
+ * This is the watchdog chain which is managed at ticks.
+ */
+SCORE_EXTERN Chain_Control _Watchdog_Ticks_chain;
+
+/** @brief Per Seconds Watchdog List
+ *
+ * This is the watchdog chain which is managed at second boundaries.
+ */
+SCORE_EXTERN Chain_Control _Watchdog_Seconds_chain;
+
+/** @brief Watchdog Handler Initialization
+ *
+ * This routine initializes the watchdog handler. The watchdog
+ * synchronization flag is initialized and the watchdog chains are
+ * initialized and emptied.
+ */
+void _Watchdog_Handler_initialization( void );
+
+/** @brief Remove Watchdog from List
+ *
+ * This routine removes @a the_watchdog from the watchdog chain on which
+ * it resides and returns the state @a the_watchdog timer was in.
+ *
+ * @param[in] the_watchdog will be removed
+ * @return the state in which @a the_watchdog was in when removed
+ */
+Watchdog_States _Watchdog_Remove (
+ Watchdog_Control *the_watchdog
+);
+
+/** @brief Watchdog Adjust
+ *
+ * This routine adjusts the @a header watchdog chain in the forward
+ * or backward @a direction for @a units ticks.
+ *
+ * @param[in] header is the watchdog chain to adjust
+ * @param[in] direction is the direction to adjust @a header
+ * @param[in] units is the number of units to adjust @a header
+ */
+void _Watchdog_Adjust (
+ Chain_Control *header,
+ Watchdog_Adjust_directions direction,
+ Watchdog_Interval units
+);
+
+/** @brief Watchdog Insert
+ *
+ * This routine inserts @a the_watchdog into the @a header watchdog chain
+ * for a time of @a units.
+ *
+ * @param[in] header is @a the_watchdog list to insert @a the_watchdog on
+ * @param[in] the_watchdog is the watchdog to insert
+ */
+void _Watchdog_Insert (
+ Chain_Control *header,
+ Watchdog_Control *the_watchdog
+);
+
+/** @brief Watchdog Tickle
+ *
+ * This routine is invoked at appropriate intervals to update
+ * the @a header watchdog chain.
+ *
+ * @param[in] header is the watchdog chain to tickle
+ */
+
+void _Watchdog_Tickle (
+ Chain_Control *header
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/watchdog.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/wkspace.h b/cpukit/score/include/rtems/score/wkspace.h
new file mode 100644
index 0000000000..2fcc22a0aa
--- /dev/null
+++ b/cpukit/score/include/rtems/score/wkspace.h
@@ -0,0 +1,82 @@
+/**
+ * @file rtems/score/wkspace.h
+ *
+ * This include file contains information related to the
+ * RAM Workspace. This Handler provides mechanisms which can be used to
+ * define, initialize and manipulate the workspace.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_WKSPACE_H
+#define _RTEMS_SCORE_WKSPACE_H
+
+/**
+ * @defgroup ScoreWorkspace Workspace Handler
+ *
+ * This handler encapsulates functionality related to the management of
+ * the RTEMS Executive Workspace.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/heap.h>
+#include <rtems/score/interr.h>
+
+/** @brief Executive Workspace Control
+ *
+ * The is the heap control structure that used to manage the
+ * RTEMS Executive Workspace.
+ */
+SCORE_EXTERN Heap_Control _Workspace_Area; /* executive heap header */
+
+/** @brief Workspace Handler Initialization
+ *
+ * This routine performs the initialization necessary for this handler.
+ *
+ * @param[in] starting_address is the base address of the RTEMS Executive
+ * Workspace
+ * @param[in] size is the number of bytes in the RTEMS Executive Workspace
+ */
+void _Workspace_Handler_initialization(
+ void *starting_address,
+ uint32_t size
+);
+
+/** @brief Workspace Allocate or Fail with Fatal Error
+ *
+ * This routine returns the address of a block of memory of @a size
+ * bytes. If a block of the appropriate size cannot be allocated
+ * from the workspace, then the internal error handler is invoked.
+ *
+ * @param[in] size is the desired number of bytes to allocate
+ * @return If successful, the starting address of the allocated memory
+ */
+void *_Workspace_Allocate_or_fatal_error(
+ uint32_t size
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/wkspace.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/seterr.h b/cpukit/score/include/rtems/seterr.h
new file mode 100644
index 0000000000..2548258d87
--- /dev/null
+++ b/cpukit/score/include/rtems/seterr.h
@@ -0,0 +1,45 @@
+/**
+ * @file rtems/seterr.h
+ *
+ * This file contains macros and definitions which ease the burden
+ * of consistently setting errno and returning -1.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SETERR_H
+#define _RTEMS_SETERR_H
+
+/**
+ * This is a helper macro which will set the variable errno and return
+ * -1 to the caller. This pattern is common to many POSIX methods.
+ *
+ * @param[in] _error is the error code
+ */
+#define rtems_set_errno_and_return_minus_one( _error ) \
+ do { errno = (_error); return -1; } while(0)
+
+/**
+ * This is a helper macro which will set the variable errno and return
+ * -1 to the caller. This pattern is common to many POSIX methods.
+ *
+ * @param[in] _error is the error code
+ * @param[in] _cast is the type to which -1 must be cast
+ *
+ * @note It is similar to @ref rtems_set_errno_and_return_minus_one but
+ * this -1 value is cast to something other than an int.
+ */
+#define rtems_set_errno_and_return_minus_one_cast( _error, _cast ) \
+ do { errno = (_error); return (_cast) -1; } while(0)
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/system.h b/cpukit/score/include/rtems/system.h
new file mode 100644
index 0000000000..9558155daf
--- /dev/null
+++ b/cpukit/score/include/rtems/system.h
@@ -0,0 +1,268 @@
+/**
+ * @file rtems/system.h
+ *
+ * This include file contains information that is included in every
+ * function in the executive. This must be the first include file
+ * included in all internal RTEMS files.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SYSTEM_H
+#define _RTEMS_SYSTEM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** This macro defines the major version portion of an RTEMS release.
+ *
+ * @note Use this macros to test for features in specific releases.
+ */
+#define __RTEMS_MAJOR__ 4
+
+/** This macro defines the minor version portion of an RTEMS release.
+ *
+ * @note Use this macros to test for features in specific releases.
+ */
+#define __RTEMS_MINOR__ 6
+
+/** This macro defines the revision version portion of an RTEMS release.
+ *
+ * @note Use this macros to test for features in specific releases.
+ */
+#define __RTEMS_REVISION__ 99
+
+/*
+ * The cpu options include file defines all cpu dependent
+ * parameters for this build of RTEMS. It must be included
+ * first so the basic macro definitions are in place.
+ */
+#include <rtems/score/cpuopts.h>
+
+/**
+ * The following ensures that all data is declared in the space
+ * of the initialization routine for either the Initialization Manager
+ * or the initialization file for the appropriate API. It is
+ * referenced as "external" in every other file.
+ */
+#ifdef SCORE_INIT
+#undef SCORE_EXTERN
+#define SCORE_EXTERN
+#else
+#undef SCORE_EXTERN
+#define SCORE_EXTERN extern
+#endif
+
+/**
+ * The following ensures that all data is declared in the space
+ * of the initialization routine for either the Initialization Manager
+ * or the initialization file for the appropriate API. It is
+ * referenced as "external" in every other file.
+ */
+#ifdef SAPI_INIT
+#undef SAPI_EXTERN
+#define SAPI_EXTERN
+#else
+#undef SAPI_EXTERN
+#define SAPI_EXTERN extern
+#endif
+
+/**
+ * The following ensures that all data is declared in the space
+ * of the initialization routine for either the Initialization Manager
+ * or the initialization file for the appropriate API. It is
+ * referenced as "external" in every other file.
+ */
+#ifdef RTEMS_API_INIT
+#undef RTEMS_EXTERN
+#define RTEMS_EXTERN
+#else
+#undef RTEMS_EXTERN
+#define RTEMS_EXTERN extern
+#endif
+
+/**
+ * The following ensures that all data is declared in the space
+ * of the initialization routine for either the Initialization Manager
+ * or the initialization file for the appropriate API. It is
+ * referenced as "external" in every other file.
+ */
+#ifdef POSIX_API_INIT
+#undef POSIX_EXTERN
+#define POSIX_EXTERN
+#else
+#undef POSIX_EXTERN
+#define POSIX_EXTERN extern
+#endif
+
+/**
+ * The following ensures that all data is declared in the space
+ * of the initialization routine for either the Initialization Manager
+ * or the initialization file for the appropriate API. It is
+ * referenced as "external" in every other file.
+ */
+#ifdef ITRON_API_INIT
+#undef ITRON_EXTERN
+#define ITRON_EXTERN
+#else
+#undef ITRON_EXTERN
+#define ITRON_EXTERN extern
+#endif
+
+/**
+ * The following (in conjunction with compiler arguments) are used
+ * to choose between the use of static inline functions and macro
+ * functions. The static inline implementation allows better
+ * type checking with no cost in code size or execution speed.
+ */
+#ifdef RTEMS_INLINES
+# ifdef __GNUC__
+# define RTEMS_INLINE_ROUTINE static __inline__
+# else
+# define RTEMS_INLINE_ROUTINE static inline
+# endif
+#else
+# define RTEMS_INLINE_ROUTINE
+#endif
+
+/**
+ * The following macro is a compiler specific way to ensure that memory
+ * writes are not reordered around certian points. This specifically can
+ * impact interrupt disable and thread dispatching critical sections.
+ */
+#ifdef __GNUC__
+ #define RTEMS_COMPILER_MEMORY_BARRIER() asm volatile("" ::: "memory")
+#else
+ #define RTEMS_COMPILER_MEMORY_BARRIER()
+#endif
+
+#ifdef RTEMS_POSIX_API
+/** The following is used by the POSIX implementation to catch bad paths. */
+int POSIX_MP_NOT_IMPLEMENTED( void );
+
+/** The following is used by the POSIX implementation to catch bad paths. */
+int POSIX_NOT_IMPLEMENTED( void );
+
+/** The following is used by the POSIX implementation to catch bad paths. */
+int POSIX_BOTTOM_REACHED( void );
+#endif
+
+/*
+ * Include a base set of files.
+ */
+
+/**
+ * XXX: Eventually proc_ptr needs to disappear!!!
+ */
+typedef void * proc_ptr;
+
+#include <stddef.h>
+
+#if !defined( TRUE ) || (TRUE != 1)
+/** Boolean constant TRUE */
+#undef TRUE
+#define TRUE (1)
+#endif
+
+#if !defined( FALSE ) || (FALSE != 0)
+/** Boolean constant TRUE */
+#undef FALSE
+#define FALSE (0)
+#endif
+
+#include <rtems/stdint.h>
+#include <rtems/score/cpu.h> /* processor specific information */
+
+/**
+ * This macro is used to obtain the offset of a field in a structure.
+ */
+#define RTEMS_offsetof(type, field) \
+ ((uint32_t ) &(((type *) 0)->field))
+
+/**
+ * The following is the extern for the RTEMS version string.
+ *
+ * @note The contents of this string are CPU specific.
+ */
+extern const char _RTEMS_version[];
+
+/**
+ * The following is the extern for the RTEMS copyright string.
+ */
+extern const char _Copyright_Notice[];
+
+/**
+ * The following defines the CPU dependent information table.
+ */
+SCORE_EXTERN rtems_cpu_table _CPU_Table;
+
+/*
+ * Macros to access CPU Table fields required by ALL ports.
+ */
+
+/** This macro assists in accessing the CPU Specific Configuration Table. */
+#define rtems_cpu_configuration_get_table() (&_CPU_Table)
+
+
+/** This macro assists in accessing the pretasking BSP hook. */
+#define rtems_cpu_configuration_get_pretasking_hook() \
+ (_CPU_Table.pretasking_hook)
+
+/** This macro assists in accessing the predriver BSP hook. */
+#define rtems_cpu_configuration_get_predriver_hook() \
+ (_CPU_Table.predriver_hook)
+
+/** This macro assists in accessing the postdriver BSP hook. */
+#define rtems_cpu_configuration_get_postdriver_hook() \
+ (_CPU_Table.postdriver_hook)
+
+/** This macro assists in accessing the BSP specific IDLE task entry point. */
+#define rtems_cpu_configuration_get_idle_task() \
+ (_CPU_Table.idle_task)
+
+/**
+ * This macro assists in accessing the field which indicates whether
+ * RTEMS is responsible for zeroing the Executive Workspace.
+ */
+#define rtems_cpu_configuration_get_do_zero_of_workspace() \
+ (_CPU_Table.do_zero_of_workspace)
+
+/** This macro assists in accessing the IDLE task stack point size. */
+#define rtems_cpu_configuration_get_idle_task_stack_size() \
+ (_CPU_Table.idle_task_stack_size)
+
+/** This macro assists in accessing the interrupt stack size. */
+#define rtems_cpu_configuration_get_interrupt_stack_size() \
+ (_CPU_Table.interrupt_stack_size)
+
+/** This macro assists in accessing the size of the MPCI receiver server. */
+#define rtems_cpu_configuration_get_extra_mpci_receive_server_stack() \
+ (_CPU_Table.extra_mpci_receive_server_stack)
+
+/** This macro assists in accessing the BSP stack allocation hook. */
+#define rtems_cpu_configuration_get_stack_allocate_hook() \
+ (_CPU_Table.stack_allocate_hook)
+
+/** This macro assists in accessing the BSP stack allocation free hook. */
+#define rtems_cpu_configuration_get_stack_free_hook() \
+ (_CPU_Table.stack_free_hook)
+
+/** This macro defines the maximum length of a Classic API name. */
+#define RTEMS_MAXIMUM_NAME_LENGTH sizeof(rtems_name)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/address.inl b/cpukit/score/inline/rtems/score/address.inl
new file mode 100644
index 0000000000..19cf03699c
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/address.inl
@@ -0,0 +1,136 @@
+/**
+ * @file rtems/score/address.inl
+ *
+ * This include file contains the bodies of the routines
+ * about addresses which are inlined.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_ADDRESS_INL
+#define _RTEMS_SCORE_ADDRESS_INL
+
+/**
+ * @addtogroup ScoreAddress
+ * @{
+ */
+
+/** @brief Add Offset to Address
+ *
+ * This function is used to add an @a offset to a @a base address.
+ * It returns the resulting address. This address is typically
+ * converted to an access type before being used further.
+ *
+ * @param[in] base is the base address.
+ * @param[in] offset is the offset to add to @a base.
+ *
+ * @return This method returns the resulting address.
+ */
+RTEMS_INLINE_ROUTINE void *_Addresses_Add_offset (
+ void *base,
+ uint32_t offset
+)
+{
+ return (void *)((char *)base + offset);
+}
+
+/** @brief Subtract Offset from Offset
+ *
+ * This function is used to subtract an @a offset from a @a base
+ * address. It returns the resulting address. This address is
+ * typically converted to an access type before being used further.
+ *
+ * @param[in] base is the base address.
+ * @param[in] offset is the offset to subtract to @a base.
+ *
+ * @return This method returns the resulting address.
+ */
+
+RTEMS_INLINE_ROUTINE void *_Addresses_Subtract_offset (
+ void *base,
+ uint32_t offset
+)
+{
+ return (void *)((char *)base - offset);
+}
+
+/** @brief Subtract Two Offsets
+ *
+ * This function is used to subtract two addresses. It returns the
+ * resulting offset.
+ *
+ * @param[in] left is the address on the left hand side of the subtraction.
+ * @param[in] right is the address on the right hand side of the subtraction.
+ *
+ * @return This method returns the resulting address.
+ *
+ * @note The cast of an address to an uint32_t makes this code
+ * dependent on an addresses being thirty two bits.
+ */
+RTEMS_INLINE_ROUTINE uint32_t _Addresses_Subtract (
+ void *left,
+ void *right
+)
+{
+ return ((char *) left - (char *) right);
+}
+
+/** @brief Is Address Aligned
+ *
+ * This function returns TRUE if the given address is correctly
+ * aligned for this processor and FALSE otherwise. Proper alignment
+ * is based on correctness and efficiency.
+ *
+ * @param[in] address is the address being checked for alignment.
+ *
+ * @return This method returns TRUE if the address is aligned and
+ * FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Addresses_Is_aligned (
+ void *address
+)
+{
+#if (CPU_ALIGNMENT == 0)
+ return TRUE;
+#else
+ return (((uintptr_t)address % CPU_ALIGNMENT) == 0);
+#endif
+}
+
+/** @brief Is Address In Range
+ *
+ * This function returns TRUE if the given address is within the
+ * memory range specified and FALSE otherwise. base is the address
+ * of the first byte in the memory range and limit is the address
+ * of the last byte in the memory range. The base address is
+ * assumed to be lower than the limit address.
+ *
+ * @param[in] address is the address to check.
+ * @param[in] base is the lowest address of the range to check against.
+ * @param[in] limit is the highest address of the range to check against.
+ *
+ * @return This method returns TRUE if the given @a address is within the
+ * memory range specified and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Addresses_Is_in_range (
+ void *address,
+ void *base,
+ void *limit
+)
+{
+ return (address >= base && address <= limit);
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/chain.inl b/cpukit/score/inline/rtems/score/chain.inl
new file mode 100644
index 0000000000..d394ec93e1
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/chain.inl
@@ -0,0 +1,391 @@
+/**
+ * @file rtems/score/chain.inl
+ *
+ * This include file contains the bodies of the routines which are
+ * associated with doubly linked chains and inlined.
+ *
+ * @note The routines in this file are ordered from simple
+ * to complex. No other Chain Handler routine is referenced
+ * unless it has already been defined.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CHAIN_INL
+#define _RTEMS_SCORE_CHAIN_INL
+
+/**
+ * @addtogroup ScoreChain
+ * @{
+ */
+
+/** @brief Are Two Nodes Equal
+ *
+ * This function returns TRUE if @a left and @a right are equal,
+ * and FALSE otherwise.
+ *
+ * @param[in] left is the node on the left hand side of the comparison.
+ * @param[in] right is the node on the left hand side of the comparison.
+ *
+ * @return This function returns TRUE if @a left and @a right are equal,
+ * and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Chain_Are_nodes_equal(
+ Chain_Node *left,
+ Chain_Node *right
+)
+{
+ return left == right;
+}
+
+/** @brief Is this Chain Control Pointer Null
+ *
+ * This function returns TRUE if the_chain is NULL and FALSE otherwise.
+ *
+ * @param[in] the_chain is the chain to be checked for empty status.
+ *
+ * @return This method returns TRUE if the_chain is NULL and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Chain_Is_null(
+ Chain_Control *the_chain
+)
+{
+ return (the_chain == NULL);
+}
+
+/** @brief Is the Chain Node Pointer NULL
+ *
+ * This function returns TRUE if the_node is NULL and FALSE otherwise.
+ *
+ * @param[in] the_node is the node pointer to check.
+ *
+ * @return This method returns TRUE if the_node is NULL and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Chain_Is_null_node(
+ Chain_Node *the_node
+)
+{
+ return (the_node == NULL);
+}
+
+/** @brief Return pointer to Chain Head
+ *
+ * This function returns a pointer to the first node on the chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the permanent head node of the chain.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Head(
+ Chain_Control *the_chain
+)
+{
+ return (Chain_Node *) the_chain;
+}
+
+/** @brief Return pointer to Chain Tail
+ *
+ * This function returns a pointer to the last node on the chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the permanent tail node of the chain.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Tail(
+ Chain_Control *the_chain
+)
+{
+ return (Chain_Node *) &the_chain->permanent_null;
+}
+
+/** @brief Is the Chain Empty
+ *
+ * This function returns TRUE if there a no nodes on @a the_chain and
+ * FALSE otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This function returns TRUE if there a no nodes on @a the_chain and
+ * FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Chain_Is_empty(
+ Chain_Control *the_chain
+)
+{
+ return (the_chain->first == _Chain_Tail(the_chain));
+}
+
+/** @brief Is this the First Node on the Chain
+ *
+ * This function returns TRUE if the_node is the first node on a chain and
+ * FALSE otherwise.
+ *
+ * @param[in] the_node is the node the caller wants to know if it is
+ * the first node on a chain.
+ *
+ * @return This function returns TRUE if @a the_node is the first node on
+ * a chain and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Chain_Is_first(
+ Chain_Node *the_node
+)
+{
+ return (the_node->previous == NULL);
+}
+
+/** @brief Is this the Last Node on the Chain
+ *
+ * This function returns TRUE if @a the_node is the last node on a chain and
+ * FALSE otherwise.
+ *
+ * @param[in] the_node is the node to check as the last node.
+ *
+ * @return This function returns TRUE if @a the_node is the last node on
+ * a chain and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Chain_Is_last(
+ Chain_Node *the_node
+)
+{
+ return (the_node->next == NULL);
+}
+
+/** @brief Does this Chain have only One Node
+ *
+ * This function returns TRUE if there is only one node on @a the_chain and
+ * FALSE otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This function returns TRUE if there is only one node on
+ * @a the_chain and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Chain_Has_only_one_node(
+ Chain_Control *the_chain
+)
+{
+ return (the_chain->first == the_chain->last);
+}
+
+/** @brief Is this Node the Chain Head
+ *
+ * This function returns TRUE if @a the_node is the head of the_chain and
+ * FALSE otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to check for being the Chain Head.
+ *
+ * @return This function returns TRUE if @a the_node is the head of
+ * @a the_chain and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Chain_Is_head(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ return (the_node == _Chain_Head(the_chain));
+}
+
+/** @brief Is this Node the Chail Tail
+ *
+ * This function returns TRUE if the_node is the tail of the_chain and
+ * FALSE otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to check for being the Chain Tail.
+ */
+RTEMS_INLINE_ROUTINE boolean _Chain_Is_tail(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ return (the_node == _Chain_Tail(the_chain));
+}
+
+/** @brief Initialize this Chain as Empty
+ *
+ * This routine initializes the specified chain to contain zero nodes.
+ *
+ * @param[in] the_chain is the chain to be initialized.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Initialize_empty(
+ Chain_Control *the_chain
+)
+{
+ the_chain->first = _Chain_Tail(the_chain);
+ the_chain->permanent_null = NULL;
+ the_chain->last = _Chain_Head(the_chain);
+}
+
+/** @brief Extract this Node (unprotected)
+ *
+ * This routine extracts the_node from the chain on which it resides.
+ * It does NOT disable interrupts to ensure the atomicity of the
+ * extract operation.
+ *
+ * @param[in] the_node is the node to be extracted.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Extract_unprotected(
+ Chain_Node *the_node
+)
+{
+ Chain_Node *next;
+ Chain_Node *previous;
+
+ next = the_node->next;
+ previous = the_node->previous;
+ next->previous = previous;
+ previous->next = next;
+}
+
+/** @brief Get the First Node (unprotected)
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. It does NOT disable interrupts to ensure
+ * the atomicity of the get operation.
+ *
+ * @param[in] the_chain is the chain to attempt to get the first node from.
+ *
+ * @return This method returns the first node on the chain even if it is
+ * the Chain Tail.
+ *
+ * @note This routine assumes that there is at least one node on the chain
+ * and always returns a node even if it is the Chain Tail.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Get_first_unprotected(
+ Chain_Control *the_chain
+)
+{
+ Chain_Node *return_node;
+ Chain_Node *new_first;
+
+ return_node = the_chain->first;
+ new_first = return_node->next;
+ the_chain->first = new_first;
+ new_first->previous = _Chain_Head(the_chain);
+
+ return return_node;
+}
+
+/** @brief Get the First Node (unprotected)
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. If the_chain is empty, then NULL is returned.
+ *
+ * @param[in] the_chain is the chain to attempt to get the first node from.
+ *
+ * @return This method returns the first node on the chain or NULL if the
+ * chain is empty.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * get operation.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Get_unprotected(
+ Chain_Control *the_chain
+)
+{
+ if ( !_Chain_Is_empty(the_chain))
+ return _Chain_Get_first_unprotected(the_chain);
+ else
+ return NULL;
+}
+
+/** @brief Insert a Node (unprotected)
+ *
+ * This routine inserts the_node on a chain immediately following
+ * after_node.
+ *
+ * @param[in] after_node is the node which will precede @a the_node on the
+ * chain.
+ * @param[in] the_node is the node to be inserted.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity
+ * of the extract operation.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Insert_unprotected(
+ Chain_Node *after_node,
+ Chain_Node *the_node
+)
+{
+ Chain_Node *before_node;
+
+ the_node->previous = after_node;
+ before_node = after_node->next;
+ after_node->next = the_node;
+ the_node->next = before_node;
+ before_node->previous = the_node;
+}
+
+/** @brief Append a Node (unprotected)
+ *
+ * This routine appends the_node onto the end of the_chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to be appended.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * append operation.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Append_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ Chain_Node *old_last_node;
+
+ the_node->next = _Chain_Tail(the_chain);
+ old_last_node = the_chain->last;
+ the_chain->last = the_node;
+ old_last_node->next = the_node;
+ the_node->previous = old_last_node;
+}
+
+/** @brief Prepend a Node (unprotected)
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to be prepended.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * prepend operation.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Prepend_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ _Chain_Insert_unprotected(_Chain_Head(the_chain), the_node);
+}
+
+/** @brief Prepend a Node (protected)
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to be prepended.
+ *
+ * @note It disables interrupts to ensure the atomicity of the
+ * prepend operation.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Prepend(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ _Chain_Insert(_Chain_Head(the_chain), the_node);
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/coremsg.inl b/cpukit/score/inline/rtems/score/coremsg.inl
new file mode 100644
index 0000000000..ece05d13f3
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/coremsg.inl
@@ -0,0 +1,228 @@
+/**
+ * @file rtems/score/coremsg.inl
+ *
+ * This include file contains the static inline implementation of all
+ * inlined routines in the Core Message Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_COREMSG_INL
+#define _RTEMS_SCORE_COREMSG_INL
+
+/**
+ * @addtogroup ScoreMessageQueue
+ * @{
+ */
+
+#include <string.h> /* needed for memcpy */
+
+/**
+ * This routine sends a message to the end of the specified message queue.
+ */
+
+RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Send(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ uint32_t size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
+ boolean wait,
+ Watchdog_Interval timeout
+)
+{
+ return _CORE_message_queue_Submit(
+ the_message_queue,
+ buffer,
+ size,
+ id,
+#if defined(RTEMS_MULTIPROCESSING)
+ api_message_queue_mp_support,
+#else
+ NULL,
+#endif
+ CORE_MESSAGE_QUEUE_SEND_REQUEST,
+ wait, /* sender may block */
+ timeout /* timeout interval */
+ );
+}
+
+/**
+ * This routine sends a message to the front of the specified message queue.
+ */
+
+RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Urgent(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ uint32_t size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
+ boolean wait,
+ Watchdog_Interval timeout
+)
+{
+ return _CORE_message_queue_Submit(
+ the_message_queue,
+ buffer,
+ size,
+ id,
+#if defined(RTEMS_MULTIPROCESSING)
+ api_message_queue_mp_support,
+#else
+ NULL,
+#endif
+ CORE_MESSAGE_QUEUE_URGENT_REQUEST,
+ wait, /* sender may block */
+ timeout /* timeout interval */
+ );
+}
+
+/**
+ * This routine copies the contents of the source message buffer
+ * to the destination message buffer.
+ */
+
+RTEMS_INLINE_ROUTINE void _CORE_message_queue_Copy_buffer (
+ void *source,
+ void *destination,
+ uint32_t size
+)
+{
+ memcpy(destination, source, size);
+}
+
+/**
+ * This function allocates a message buffer from the inactive
+ * message buffer chain.
+ */
+
+RTEMS_INLINE_ROUTINE CORE_message_queue_Buffer_control *
+_CORE_message_queue_Allocate_message_buffer (
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ return (CORE_message_queue_Buffer_control *)
+ _Chain_Get( &the_message_queue->Inactive_messages );
+}
+
+/**
+ * This routine frees a message buffer to the inactive
+ * message buffer chain.
+ */
+
+RTEMS_INLINE_ROUTINE void _CORE_message_queue_Free_message_buffer (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message
+)
+{
+ _Chain_Append( &the_message_queue->Inactive_messages, &the_message->Node );
+}
+
+/**
+ * This function removes the first message from the_message_queue
+ * and returns a pointer to it.
+ */
+
+RTEMS_INLINE_ROUTINE
+ CORE_message_queue_Buffer_control *_CORE_message_queue_Get_pending_message (
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ return (CORE_message_queue_Buffer_control *)
+ _Chain_Get_unprotected( &the_message_queue->Pending_messages );
+}
+
+/**
+ * This function returns TRUE if the priority attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _CORE_message_queue_Is_priority(
+ CORE_message_queue_Attributes *the_attribute
+)
+{
+ return (the_attribute->discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY);
+}
+
+/**
+ * This routine places the_message at the rear of the outstanding
+ * messages on the_message_queue.
+ */
+
+RTEMS_INLINE_ROUTINE void _CORE_message_queue_Append_unprotected (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message
+)
+{
+ _Chain_Append_unprotected(
+ &the_message_queue->Pending_messages,
+ &the_message->Node
+ );
+}
+
+/**
+ * This routine places the_message at the front of the outstanding
+ * messages on the_message_queue.
+ */
+
+RTEMS_INLINE_ROUTINE void _CORE_message_queue_Prepend_unprotected (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message
+)
+{
+ _Chain_Prepend_unprotected(
+ &the_message_queue->Pending_messages,
+ &the_message->Node
+ );
+}
+
+/**
+ * This function returns TRUE if the_message_queue is TRUE and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _CORE_message_queue_Is_null (
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ return ( the_message_queue == NULL );
+}
+
+/**
+ * This function returns TRUE if notification is enabled on this message
+ * queue and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _CORE_message_queue_Is_notify_enabled (
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ return (the_message_queue->notify_handler != NULL);
+}
+
+/**
+ * This routine initializes the notification information for the_message_queue.
+ */
+
+RTEMS_INLINE_ROUTINE void _CORE_message_queue_Set_notify (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Notify_Handler the_handler,
+ void *the_argument
+)
+{
+ the_message_queue->notify_handler = the_handler;
+ the_message_queue->notify_argument = the_argument;
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/coremutex.inl b/cpukit/score/inline/rtems/score/coremutex.inl
new file mode 100644
index 0000000000..2bde4a888f
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/coremutex.inl
@@ -0,0 +1,201 @@
+/**
+ * @file rtems/score/coremutex.inl
+ *
+ * This include file contains all of the inlined routines associated
+ * with the CORE mutexes.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_COREMUTEX_INL
+#define _RTEMS_SCORE_COREMUTEX_INL
+
+/**
+ * @addtogroup ScoreMutex
+ * @{
+ */
+
+/**
+ * @brief Is Mutex Locked
+ *
+ * This routine returns TRUE if the mutex specified is locked and FALSE
+ * otherwise.
+ *
+ * @param[in] the_mutex is the mutex to check
+ *
+ * @return This method returns TRUE if the mutex is locked.
+ */
+RTEMS_INLINE_ROUTINE boolean _CORE_mutex_Is_locked(
+ CORE_mutex_Control *the_mutex
+)
+{
+ return the_mutex->lock == CORE_MUTEX_LOCKED;
+}
+
+/**
+ * @brief Does Core Mutex Use FIFO Blocking
+ *
+ * This routine returns TRUE if the mutex's wait discipline is FIFO and FALSE
+ * otherwise.
+ *
+ * @param[in] the_attribute is the attribute set of the mutex
+ *
+ * @return This method returns TRUE if the mutex is using FIFO blocking order.
+ */
+RTEMS_INLINE_ROUTINE boolean _CORE_mutex_Is_fifo(
+ CORE_mutex_Attributes *the_attribute
+)
+{
+ return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_FIFO;
+}
+
+/**
+ * @brief Doex Core Mutex Use Priority Blocking
+ *
+ * This routine returns TRUE if the mutex's wait discipline is PRIORITY and
+ * FALSE otherwise.
+ *
+ * @param[in] the_attribute is the attribute set of the mutex
+ *
+ * @return This method returns TRUE if the mutex is using
+ * priority blocking order.
+ */
+RTEMS_INLINE_ROUTINE boolean _CORE_mutex_Is_priority(
+ CORE_mutex_Attributes *the_attribute
+)
+{
+ return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY;
+}
+
+/**
+ * @brief Does Mutex Use Priority Inheritance
+ *
+ * This routine returns TRUE if the mutex's wait discipline is
+ * INHERIT_PRIORITY and FALSE otherwise.
+ *
+ * @param[in] the_attribute is the attribute set of the mutex
+ *
+ * @return This method returns TRUE if the mutex is using priority
+ * inheritance.
+ */
+RTEMS_INLINE_ROUTINE boolean _CORE_mutex_Is_inherit_priority(
+ CORE_mutex_Attributes *the_attribute
+)
+{
+ return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
+}
+
+/**
+ * @brief Does Mutex Use Priority Ceiling
+ *
+ * This routine returns TRUE if the mutex's wait discipline is
+ * PRIORITY_CEILING and FALSE otherwise.
+ *
+ * @param[in] the_attribute is the attribute set of the mutex
+ *
+ * @return This method returns TRUE if the mutex is using priority
+ * ceiling.
+ */
+RTEMS_INLINE_ROUTINE boolean _CORE_mutex_Is_priority_ceiling(
+ CORE_mutex_Attributes *the_attribute
+)
+{
+ return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
+}
+
+/*
+ * Seize Mutex with Quick Success Path
+ *
+ * NOTE: There is no MACRO version of this routine. A body is in
+ * coremutexseize.c that is duplicated from the .inl by hand.
+ *
+ * NOTE: The Doxygen for this routine is in the .h file.
+ */
+RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock(
+ CORE_mutex_Control *the_mutex,
+ ISR_Level *level_p
+)
+{
+ Thread_Control *executing;
+ ISR_Level level = *level_p;
+
+ /* disabled when you get here */
+
+ executing = _Thread_Executing;
+ executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
+ if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
+ the_mutex->lock = CORE_MUTEX_LOCKED;
+ the_mutex->holder = executing;
+ the_mutex->holder_id = executing->Object.id;
+ the_mutex->nest_count = 1;
+ if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
+ _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
+ executing->resource_count++;
+ if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
+ _ISR_Enable( level );
+ return 0;
+ }
+ /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING */
+ {
+ Priority_Control ceiling;
+ Priority_Control current;
+
+ ceiling = the_mutex->Attributes.priority_ceiling;
+ current = executing->current_priority;
+ if ( current == ceiling ) {
+ _ISR_Enable( level );
+ return 0;
+ }
+ if ( current > ceiling ) {
+ _Thread_Disable_dispatch();
+ _ISR_Enable( level );
+ _Thread_Change_priority(
+ the_mutex->holder,
+ the_mutex->Attributes.priority_ceiling,
+ FALSE
+ );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ /* if ( current < ceiling ) */ {
+ executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
+ the_mutex->nest_count = 0; /* undo locking above */
+ executing->resource_count--; /* undo locking above */
+ _ISR_Enable( level );
+ return 0;
+ }
+ }
+ return 0;
+ }
+
+ if ( _Thread_Is_executing( the_mutex->holder ) ) {
+ switch ( the_mutex->Attributes.lock_nesting_behavior ) {
+ case CORE_MUTEX_NESTING_ACQUIRES:
+ the_mutex->nest_count++;
+ _ISR_Enable( level );
+ return 0;
+ case CORE_MUTEX_NESTING_IS_ERROR:
+ executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
+ _ISR_Enable( level );
+ return 0;
+ case CORE_MUTEX_NESTING_BLOCKS:
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/coresem.inl b/cpukit/score/inline/rtems/score/coresem.inl
new file mode 100644
index 0000000000..c7e6b69605
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/coresem.inl
@@ -0,0 +1,112 @@
+/**
+ * @file rtems/score/coresem.inl
+ *
+ * This include file contains all of the inlined routines associated
+ * with the CORE semaphore.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CORESEM_INL
+#define _RTEMS_SCORE_CORESEM_INL
+
+/**
+ * @addtogroup ScoreSemaphore
+ * @{
+ */
+
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+
+/**
+ * This function returns TRUE if the priority attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ *
+ * @param[in] the_attribute is the attribute set to test
+ * @return TRUE if the priority attribute is enabled
+ */
+RTEMS_INLINE_ROUTINE boolean _CORE_semaphore_Is_priority(
+ CORE_semaphore_Attributes *the_attribute
+)
+{
+ return ( the_attribute->discipline == CORE_SEMAPHORE_DISCIPLINES_PRIORITY );
+}
+
+/**
+ * This routine returns the current count associated with the semaphore.
+ *
+ * @param[in] the_semaphore is the semaphore to obtain the count of
+ * @return the current count of this semaphore
+ */
+RTEMS_INLINE_ROUTINE uint32_t _CORE_semaphore_Get_count(
+ CORE_semaphore_Control *the_semaphore
+)
+{
+ return the_semaphore->count;
+}
+
+/**
+ * This routine attempts to receive a unit from the_semaphore.
+ * If a unit is available or if the wait flag is FALSE, then the routine
+ * returns. Otherwise, the calling task is blocked until a unit becomes
+ * available.
+ *
+ * @param[in] the_semaphore is the semaphore to obtain
+ * @param[in] id is the Id of the owning API level Semaphore object
+ * @param[in] wait is TRUE if the thread is willing to wait
+ * @param[in] timeout is the maximum number of ticks to block
+ * @param[in] level_p is a temporary variable used to contain the ISR
+ * disable level cookie
+ *
+ * @note There is currently no MACRO version of this routine.
+ */
+RTEMS_INLINE_ROUTINE void _CORE_semaphore_Seize_isr_disable(
+ CORE_semaphore_Control *the_semaphore,
+ Objects_Id id,
+ boolean wait,
+ Watchdog_Interval timeout,
+ ISR_Level *level_p
+)
+{
+ Thread_Control *executing;
+ ISR_Level level = *level_p;
+
+ /* disabled when you get here */
+
+ executing = _Thread_Executing;
+ executing->Wait.return_code = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
+ if ( the_semaphore->count != 0 ) {
+ the_semaphore->count -= 1;
+ _ISR_Enable( level );
+ return;
+ }
+
+ if ( !wait ) {
+ _ISR_Enable( level );
+ executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT;
+ return;
+ }
+
+ _Thread_Disable_dispatch();
+ _Thread_queue_Enter_critical_section( &the_semaphore->Wait_queue );
+ executing->Wait.queue = &the_semaphore->Wait_queue;
+ executing->Wait.id = id;
+ _ISR_Enable( level );
+
+ _Thread_queue_Enqueue( &the_semaphore->Wait_queue, timeout );
+ _Thread_Enable_dispatch();
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/heap.inl b/cpukit/score/inline/rtems/score/heap.inl
new file mode 100644
index 0000000000..d34ce759ee
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/heap.inl
@@ -0,0 +1,370 @@
+/**
+ * @file rtems/score/heap.inl
+ *
+ * This file contains the static inline implementation of the inlined
+ * routines from the heap handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_HEAP_INL
+#define _RTEMS_SCORE_HEAP_INL
+
+/**
+ * @addtogroup ScoreHeap
+ * @{
+ */
+
+#include <rtems/score/address.h>
+
+/**
+ * This function returns the head of the specified heap.
+ *
+ * @param[in] the_heap points to the heap being operated upon
+ *
+ * @return This method returns a pointer to the dummy head of the free
+ * block list.
+ */
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Head (
+ Heap_Control *the_heap
+)
+{
+ return &the_heap->free_list;
+}
+
+/**
+ * This function returns the tail of the specified heap.
+ *
+ * @param[in] the_heap points to the heap being operated upon
+ *
+ * @return This method returns a pointer to the dummy tail of the heap
+ * free list.
+ */
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Tail (
+ Heap_Control *the_heap
+)
+{
+ return &the_heap->free_list;
+}
+
+/**
+ * Return the first free block of the specified heap.
+ *
+ * @param[in] the_heap points to the heap being operated upon
+ *
+ * @return This method returns a pointer to the first free block.
+ */
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_First (
+ Heap_Control *the_heap
+)
+{
+ return _Heap_Head(the_heap)->next;
+}
+
+/**
+ * Return the last free block of the specified heap.
+ *
+ * @param[in] the_heap points to the heap being operated upon
+ *
+ * @return This method returns a pointer to the last block on the free list.
+ */
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Last (
+ Heap_Control *the_heap
+)
+{
+ return _Heap_Tail(the_heap)->prev;
+}
+
+/**
+ * This function removes 'the_block' from doubly-linked list.
+ *
+ * @param[in] the_block is the block to remove from the heap used block
+ * list.
+ */
+RTEMS_INLINE_ROUTINE void _Heap_Block_remove (
+ Heap_Block *the_block
+)
+{
+ Heap_Block *block = the_block;
+
+ Heap_Block *next = block->next;
+ Heap_Block *prev = block->prev;
+ prev->next = next;
+ next->prev = prev;
+}
+
+/**
+ * This function replaces @a old_block by @a new_block in doubly-linked list.
+ * When a block is allocated, the memory is allocated from the low memory
+ * address range of the block. This means that the upper address range of
+ * the memory block must be added to the free block list in place of the
+ * lower address portion being allocated. This method is also used as part
+ * of resizing a block.
+ *
+ * @param[in] old_block is the block which is currently on the list.
+ * @param[in] new_block is the new block which will replace it on the list.
+ */
+
+RTEMS_INLINE_ROUTINE void _Heap_Block_replace (
+ Heap_Block *old_block,
+ Heap_Block *new_block
+)
+{
+ Heap_Block *block = old_block;
+ Heap_Block *next = block->next;
+ Heap_Block *prev = block->prev;
+
+ block = new_block;
+ block->next = next;
+ block->prev = prev;
+ next->prev = prev->next = block;
+}
+
+/**
+ * This function inserts @a the_block after @a prev_block
+ * in the doubly-linked free block list.
+ *
+ * @param[in] prev_block is the previous block in the free list.
+ * @param[in] the_block is the block being freed.
+ */
+RTEMS_INLINE_ROUTINE void _Heap_Block_insert_after (
+ Heap_Block *prev_block,
+ Heap_Block *the_block
+)
+{
+ Heap_Block *prev = prev_block;
+ Heap_Block *block = the_block;
+
+ Heap_Block *next = prev->next;
+ block->next = next;
+ block->prev = prev;
+ next->prev = prev->next = block;
+}
+
+/**
+ * Return TRUE if @a value is a multiple of @a alignment, FALSE otherwise
+ *
+ * @param[in] value is the address to verify alignment of.
+ * @param[in] alignment is the alignment factor to verify.
+ *
+ * @return This method returns TRUE if the address is aligned and false
+ * otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Heap_Is_aligned (
+ uint32_t value,
+ uint32_t alignment
+)
+{
+ return (value % alignment) == 0;
+}
+
+/**
+ * Align @a *value up to the nearest multiple of @a alignment.
+ *
+ * @param[in] value is a pointer to be aligned.
+ * @param[in] alignment is the alignment value.
+ *
+ * @return Upon return, @a value will contain the aligned result.
+ */
+RTEMS_INLINE_ROUTINE void _Heap_Align_up (
+ uint32_t *value,
+ uint32_t alignment
+)
+{
+ uint32_t v = *value;
+ uint32_t a = alignment;
+ uint32_t r = v % a;
+ *value = r ? v - r + a : v;
+}
+
+/**
+ * Align @a *value down to the nearest multiple of @a alignment.
+ *
+ * @param[in] value is a pointer to be aligned.
+ * @param[in] alignment is the alignment value.
+ *
+ * @return Upon return, @a value will contain the aligned result.
+ */
+RTEMS_INLINE_ROUTINE void _Heap_Align_down (
+ uint32_t *value,
+ uint32_t alignment
+)
+{
+ uint32_t v = *value;
+ *value = v - (v % alignment);
+}
+
+/**
+ * Return TRUE if @a ptr is aligned at @a alignment boundary,
+ * FALSE otherwise.
+ *
+ * @param[in] ptr is the pointer to verify alignment of.
+ * @param[in] alignment is the alignment factor.
+ *
+ * @return This method returns TRUE if @a ptr is aligned at @a alignment
+ * boundary, and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Heap_Is_aligned_ptr (
+ void *ptr,
+ uint32_t alignment
+)
+{
+ return (_H_p2u(ptr) % alignment) == 0;
+}
+
+/**
+ * Align @a *value up to the nearest multiple of @a alignment.
+ *
+ * @param[in] value is a pointer to be aligned.
+ * @param[in] alignment is the alignment value.
+ *
+ * @return Upon return, @a value will contain the aligned result.
+ */
+RTEMS_INLINE_ROUTINE void _Heap_Align_up_uptr (
+ _H_uptr_t *value,
+ uint32_t alignment
+)
+{
+ _H_uptr_t v = *value;
+ uint32_t a = alignment;
+ _H_uptr_t r = v % a;
+ *value = r ? v - r + a : v;
+}
+
+/**
+ * Align @a *value down to the nearest multiple of @a alignment.
+ *
+ * @param[in] value is a pointer to be aligned.
+ * @param[in] alignment is the alignment value.
+ *
+ * @return Upon return, @a value will contain the aligned result.
+ */
+RTEMS_INLINE_ROUTINE void _Heap_Align_down_uptr (
+ _H_uptr_t *value,
+ uint32_t alignment
+)
+{
+ _H_uptr_t v = *value;
+ *value = v - (v % alignment);
+}
+
+/**
+ * This function calculates and returns a block's location (address)
+ * in the heap based upon a base address @a base and an @a offset.
+ *
+ * @param[in] base is the base address of the memory area.
+ * @param[in] offset is the byte offset into @a base.
+ *
+ * @return This method returns a pointer to the block's address.
+ */
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Block_at(
+ void *base,
+ uint32_t offset
+)
+{
+ return (Heap_Block *) _Addresses_Add_offset( base, offset );
+}
+
+/**
+ * This function returns the starting address of the portion of @a the_block
+ * which the user may access.
+ *
+ * @param[in] the_block is the heap block to find the user area of.
+ *
+ * @return This method returns a pointer to the start of the user area in
+ * the block.
+ */
+RTEMS_INLINE_ROUTINE void *_Heap_User_area (
+ Heap_Block *the_block
+)
+{
+ return (void *) _Addresses_Add_offset ( the_block, HEAP_BLOCK_USER_OFFSET );
+}
+
+/**
+ * Fill @a *the_block with the address of the beginning of the block given
+ * pointer to the user accessible area @a base.
+ *
+ * @param[in] the_heap points to the heap being operated upon
+ * @param[in] base points to the user area in the block.
+ * @param[in] the_block will be the address of the heap block.
+ *
+ * @return This method returns a pointer to the heap block based upon the
+ * given heap and user pointer.
+ */
+RTEMS_INLINE_ROUTINE void _Heap_Start_of_block (
+ Heap_Control *the_heap,
+ void *base,
+ Heap_Block **the_block
+)
+{
+ _H_uptr_t addr = _H_p2u(base);
+ /* The address passed could be greater than the block address plus
+ * HEAP_BLOCK_USER_OFFSET as _Heap_Allocate_aligned() may produce such user
+ * pointers. To get rid of this offset we need to align the address down
+ * to the nearest 'page_size' boundary. */
+ _Heap_Align_down_uptr ( &addr, the_heap->page_size );
+ *the_block = (Heap_Block *)(addr - HEAP_BLOCK_USER_OFFSET);
+}
+
+/**
+ * This function returns TRUE if the previous block of @a the_block
+ * is in use, and FALSE otherwise.
+ *
+ * @param[in] the_block is the block to operate upon.
+ *
+ * @return This method returns TRUE if the previous block is used and FALSE
+ * if the previous block is free.
+ */
+RTEMS_INLINE_ROUTINE boolean _Heap_Is_prev_used (
+ Heap_Block *the_block
+)
+{
+ return (the_block->size & HEAP_PREV_USED);
+}
+
+/**
+ * This function returns the size of @a the_block in bytes.
+ *
+ * @param[in] the_block is the block to operate upon.
+ *
+ * @return This method returns the size of the specified heap block in bytes.
+ */
+RTEMS_INLINE_ROUTINE uint32_t _Heap_Block_size (
+ Heap_Block *the_block
+)
+{
+ return (the_block->size & ~HEAP_PREV_USED);
+}
+
+/**
+ * This function returns TRUE if @a the_block is within the memory area
+ * managed by @a the_heap, and FALSE otherwise.
+ *
+ * @param[in] the_heap points to the heap being operated upon
+ * @param[in] the_block is the block address to check.
+ *
+ * @return This method returns TRUE if @a the_block appears to have been
+ * allocated from @a the_heap, and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Heap_Is_block_in (
+ Heap_Control *the_heap,
+ Heap_Block *the_block
+)
+{
+ return _Addresses_Is_in_range( the_block, the_heap->start, the_heap->final );
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/isr.inl b/cpukit/score/inline/rtems/score/isr.inl
new file mode 100644
index 0000000000..74c0588619
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/isr.inl
@@ -0,0 +1,54 @@
+/**
+ * @file rtems/score/isr.inl
+ *
+ * This include file contains the static implementation of all
+ * inlined routines in the Interrupt Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_ISR_INL
+#define _RTEMS_SCORE_ISR_INL
+
+/**
+ * @addtogroup ScoreISR
+ * @{
+ */
+
+/**
+ * This function returns TRUE if the vector is a valid vector number
+ * for this processor and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ISR_Is_vector_number_valid (
+ uint32_t vector
+)
+{
+ return ( vector <= CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER );
+}
+
+/**
+ * This function returns TRUE if handler is the entry point of a valid
+ * use interrupt service routine and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _ISR_Is_valid_user_handler (
+ void *handler
+)
+{
+ return ( handler != NULL);
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/mppkt.inl b/cpukit/score/inline/rtems/score/mppkt.inl
new file mode 100644
index 0000000000..acb6d5d029
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/mppkt.inl
@@ -0,0 +1,57 @@
+/**
+ * @file rtems/score/mppkt.inl
+ *
+ * This package is the implementation of the Packet Handler
+ * routines which are inlined.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_MPPKT_INL
+#define _RTEMS_SCORE_MPPKT_INL
+
+/**
+ * @addtogroup ScoreMPPacket
+ * @{
+ */
+
+/**
+ * This function returns TRUE if the the_packet_class is valid,
+ * and FALSE otherwise.
+ *
+ * @note Check for lower bounds (MP_PACKET_CLASSES_FIRST ) is unnecessary
+ * because this enum starts at lower bound of zero.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Mp_packet_Is_valid_packet_class (
+ MP_packet_Classes the_packet_class
+)
+{
+ return ( the_packet_class <= MP_PACKET_CLASSES_LAST );
+}
+
+/**
+ * This function returns TRUE if the the_packet_class is null,
+ * and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Mp_packet_Is_null (
+ MP_packet_Prefix *the_packet
+)
+{
+ return the_packet == NULL;
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/object.inl b/cpukit/score/inline/rtems/score/object.inl
new file mode 100644
index 0000000000..e3e17bdb69
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/object.inl
@@ -0,0 +1,307 @@
+/**
+ * @file rtems/score/object.inl
+ */
+
+/*
+ *
+ * This include file contains the static inline implementation of all
+ * of the inlined routines in the Object Handler.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_OBJECT_INL
+#define _RTEMS_SCORE_OBJECT_INL
+
+/**
+ * This function builds an object's id from the processor node and index
+ * values specified.
+ *
+ * @param[in] the_api indicates the API associated with this Id.
+ * @param[in] the_class indicates the class of object.
+ * It is specific to @a the_api.
+ * @param[in] node is the node where this object resides.
+ * @param[in] index is the instance number of this object.
+ *
+ * @return This method returns an object Id constructed from the arguments.
+ */
+RTEMS_INLINE_ROUTINE Objects_Id _Objects_Build_id(
+ Objects_APIs the_api,
+ uint32_t the_class,
+ uint32_t node,
+ uint32_t index
+)
+{
+ return (( (Objects_Id) the_api ) << OBJECTS_API_START_BIT) |
+ (( (Objects_Id) the_class ) << OBJECTS_CLASS_START_BIT) |
+ (( (Objects_Id) node ) << OBJECTS_NODE_START_BIT) |
+ (( (Objects_Id) index ) << OBJECTS_INDEX_START_BIT);
+}
+
+/**
+ * This function returns the API portion of the ID.
+ *
+ * @param[in] id is the object Id to be processed.
+ *
+ * @return This method returns an object Id constructed from the arguments.
+ */
+RTEMS_INLINE_ROUTINE Objects_APIs _Objects_Get_API(
+ Objects_Id id
+)
+{
+ return (Objects_APIs) ((id >> OBJECTS_API_START_BIT) & OBJECTS_API_VALID_BITS);
+}
+
+/**
+ * This function returns the class portion of the ID.
+ *
+ * @param[in] id is the object Id to be processed
+ */
+RTEMS_INLINE_ROUTINE uint32_t _Objects_Get_class(
+ Objects_Id id
+)
+{
+ return (uint32_t )
+ ((id >> OBJECTS_CLASS_START_BIT) & OBJECTS_CLASS_VALID_BITS);
+}
+
+/**
+ * This function returns the node portion of the ID.
+ *
+ * @param[in] id is the object Id to be processed
+ *
+ * @return This method returns the node portion of an object ID.
+ */
+RTEMS_INLINE_ROUTINE uint32_t _Objects_Get_node(
+ Objects_Id id
+)
+{
+ return (id >> OBJECTS_NODE_START_BIT) & OBJECTS_NODE_VALID_BITS;
+}
+
+/**
+ * This function returns the index portion of the ID.
+ *
+ * @param[in] id is the Id to be processed
+ *
+ * @return This method returns the class portion of the specified object ID.
+ */
+RTEMS_INLINE_ROUTINE uint32_t _Objects_Get_index(
+ Objects_Id id
+)
+{
+ return (id >> OBJECTS_INDEX_START_BIT) & OBJECTS_INDEX_VALID_BITS;
+}
+
+/**
+ * This function returns TRUE if the class is valid.
+ *
+ * @param[in] the_class is the class portion of an object ID.
+ *
+ * @return This method returns TRUE if the specified class value is valid
+ * and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Objects_Is_class_valid(
+ uint32_t the_class
+)
+{
+ /* XXX how do we determine this now? */
+ return TRUE; /* the_class && the_class <= OBJECTS_CLASSES_LAST; */
+}
+
+#if defined(RTEMS_MULTIPROCESSING)
+/**
+ * This function returns TRUE if the node is of the local object, and
+ * FALSE otherwise.
+ *
+ * @param[in] node is the node number and corresponds to the node number
+ * portion of an object ID.
+ *
+ * @return This method returns TRUE if the specified node is the local node
+ * and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Objects_Is_local_node(
+ uint32_t node
+)
+{
+ return ( node == _Objects_Local_node );
+}
+#endif
+
+/**
+ * This function returns TRUE if the id is of a local object, and
+ * FALSE otherwise.
+ *
+ * @param[in] id is an object ID
+ *
+ * @return This method returns TRUE if the specified object Id is local
+ * and FALSE otherwise.
+ *
+ * @note On a single processor configuration, this always returns TRUE.
+ */
+RTEMS_INLINE_ROUTINE boolean _Objects_Is_local_id(
+ Objects_Id id
+)
+{
+#if defined(RTEMS_MULTIPROCESSING)
+ return _Objects_Is_local_node( _Objects_Get_node(id) );
+#else
+ return TRUE;
+#endif
+}
+
+/**
+ * This function returns TRUE if left and right are equal,
+ * and FALSE otherwise.
+ *
+ * @param[in] left is the Id on the left hand side of the comparison
+ * @param[in] right is the Id on the right hand side of the comparison
+ *
+ * @return This method returns TRUE if the specified object IDs are equal
+ * and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Objects_Are_ids_equal(
+ Objects_Id left,
+ Objects_Id right
+)
+{
+ return ( left == right );
+}
+
+/**
+ * This function returns a pointer to the local_table object
+ * referenced by the index.
+ *
+ * @param[in] information points to an Object Information Table
+ * @param[in] index is the index of the object the caller wants to access
+ *
+ * @return This method returns a pointer to a local object or NULL if the
+ * index is invalid.
+ */
+RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Get_local_object(
+ Objects_Information *information,
+ uint16_t index
+)
+{
+ if ( index > information->maximum )
+ return NULL;
+ return information->local_table[ index ];
+}
+
+/**
+ * This function sets the pointer to the local_table object
+ * referenced by the index.
+ *
+ * @param[in] information points to an Object Information Table
+ * @param[in] index is the index of the object the caller wants to access
+ * @param[in] the_object is the local object pointer
+ */
+
+RTEMS_INLINE_ROUTINE void _Objects_Set_local_object(
+ Objects_Information *information,
+ uint16_t index,
+ Objects_Control *the_object
+)
+{
+ if ( index <= information->maximum )
+ information->local_table[ index ] = the_object;
+}
+
+/**
+ * This function return the information structure given
+ * an id of an object.
+ *
+ * @param[in] id is an object ID
+ *
+ *
+ * @return This method returns a pointer to the Object Information Table
+ * for the class of objects which corresponds to this object ID.
+ */
+RTEMS_INLINE_ROUTINE Objects_Information *_Objects_Get_information(
+ Objects_Id id
+)
+{
+ Objects_APIs the_api;
+ uint16_t the_class;
+
+
+ the_class = _Objects_Get_class( id );
+
+ if ( !_Objects_Is_class_valid( the_class ) )
+ return NULL;
+
+ the_api = _Objects_Get_API( id );
+ return _Objects_Information_table[ the_api ][ the_class ];
+}
+
+/**
+ * This function places the_object control pointer and object name
+ * in the Local Pointer and Local Name Tables, respectively.
+ *
+ * @param[in] information points to an Object Information Table
+ * @param[in] the_object is a pointer to an object
+ * @param[in] name is the name of the object to make accessible
+ */
+RTEMS_INLINE_ROUTINE void _Objects_Open(
+ Objects_Information *information,
+ Objects_Control *the_object,
+ Objects_Name name
+)
+{
+ uint32_t index;
+
+ index = _Objects_Get_index( the_object->id );
+ _Objects_Set_local_object( information, index, the_object );
+
+ if ( information->is_string )
+ /* _Objects_Copy_name_string( name, the_object->name ); */
+ the_object->name = name;
+ else
+ /* _Objects_Copy_name_raw( name, the_object->name, information->name_length ); */
+ the_object->name = name;
+}
+
+/**
+ * This function removes the_object control pointer and object name
+ * in the Local Pointer and Local Name Tables.
+ *
+ * @param[in] information points to an Object Information Table
+ * @param[in] the_object is a pointer to an object
+ */
+RTEMS_INLINE_ROUTINE void _Objects_Close(
+ Objects_Information *information,
+ Objects_Control *the_object
+)
+{
+ uint32_t index;
+
+ index = _Objects_Get_index( the_object->id );
+ _Objects_Set_local_object( information, index, NULL );
+ /* _Objects_Clear_name( the_object->name, information->name_length ); */
+ the_object->name = 0;
+}
+
+/**
+ * This function removes the_object from the namespace.
+ *
+ * @param[in] information points to an Object Information Table
+ * @param[in] the_object is a pointer to an object
+ */
+RTEMS_INLINE_ROUTINE void _Objects_Namespace_remove(
+ Objects_Information *information,
+ Objects_Control *the_object
+)
+{
+ /* _Objects_Clear_name( the_object->name, information->name_length ); */
+ the_object->name = 0;
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/objectmp.inl b/cpukit/score/inline/rtems/score/objectmp.inl
new file mode 100644
index 0000000000..ddcb4f4eb1
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/objectmp.inl
@@ -0,0 +1,67 @@
+/**
+ * @file rtems/score/objectmp.inl
+ *
+ * This include file contains the bodies of all inlined routines
+ * which deal with global objects.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_OBJECTMP_INL
+#define _RTEMS_SCORE_OBJECTMP_INL
+
+/**
+ * @addtogroup ScoreObjectMP
+ * @{
+ */
+
+/**
+ * This function allocates a Global Object control block.
+ */
+
+RTEMS_INLINE_ROUTINE Objects_MP_Control *_Objects_MP_Allocate_global_object (
+ void
+)
+{
+ return (Objects_MP_Control *)
+ _Chain_Get( &_Objects_MP_Inactive_global_objects );
+}
+
+/**
+ * This routine deallocates a Global Object control block.
+ */
+
+RTEMS_INLINE_ROUTINE void _Objects_MP_Free_global_object (
+ Objects_MP_Control *the_object
+)
+{
+ _Chain_Append(
+ &_Objects_MP_Inactive_global_objects,
+ &the_object->Object.Node
+ );
+}
+
+/**
+ * This function returns whether the global object is NULL or not.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Objects_MP_Is_null_global_object (
+ Objects_MP_Control *the_object
+)
+{
+ return( the_object == NULL );
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/priority.inl b/cpukit/score/inline/rtems/score/priority.inl
new file mode 100644
index 0000000000..1bc8ea5742
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/priority.inl
@@ -0,0 +1,201 @@
+/**
+ * @file rtems/score/priority.inl
+ *
+ * This file contains the static inline implementation of all inlined
+ * routines in the Priority Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_PRIORITY_INL
+#define _RTEMS_SCORE_PRIORITY_INL
+
+/**
+ * @addtogroup ScorePriority
+ * @{
+ */
+
+#include <rtems/score/bitfield.h>
+
+/**
+ * This routine performs the initialization necessary for this handler.
+ */
+
+RTEMS_INLINE_ROUTINE void _Priority_Handler_initialization( void )
+{
+ uint32_t index;
+
+ _Priority_Major_bit_map = 0;
+ for ( index=0 ; index <16 ; index++ )
+ _Priority_Bit_map[ index ] = 0;
+}
+
+/**
+ * This function returns TRUE if the_priority if valid for a
+ * user task, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Priority_Is_valid (
+ Priority_Control the_priority
+)
+{
+ /*
+ * Since PRIORITY_MINIMUM is 0 and priorities are stored unsigned,
+ * then checking for less than 0 is unnecessary.
+ */
+
+ return ( the_priority <= PRIORITY_MAXIMUM );
+}
+
+/**
+ * This function returns the major portion of the_priority.
+ */
+
+RTEMS_INLINE_ROUTINE uint32_t _Priority_Major (
+ Priority_Control the_priority
+)
+{
+ return ( the_priority / 16 );
+}
+
+/**
+ * This function returns the minor portion of the_priority.
+ */
+
+RTEMS_INLINE_ROUTINE uint32_t _Priority_Minor (
+ Priority_Control the_priority
+)
+{
+ return ( the_priority % 16 );
+}
+
+#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE )
+
+/**
+ * This function returns the mask associated with the major or minor
+ * number passed to it.
+ */
+
+RTEMS_INLINE_ROUTINE uint32_t _Priority_Mask (
+ uint32_t bit_number
+)
+{
+ return (0x8000 >> bit_number);
+}
+
+
+/**
+ * This function translates the bit numbers returned by the bit scan
+ * of a priority bit field into something suitable for use as
+ * a major or minor component of a priority.
+ */
+
+RTEMS_INLINE_ROUTINE uint32_t _Priority_Bits_index (
+ uint32_t bit_number
+)
+{
+ return bit_number;
+}
+
+#endif
+
+/**
+ * This routine uses the_priority_map to update the priority
+ * bit maps to indicate that a thread has been readied.
+ */
+
+RTEMS_INLINE_ROUTINE void _Priority_Add_to_bit_map (
+ Priority_Information *the_priority_map
+)
+{
+ *the_priority_map->minor |= the_priority_map->ready_minor;
+ _Priority_Major_bit_map |= the_priority_map->ready_major;
+}
+
+/**
+ * This routine uses the_priority_map to update the priority
+ * bit maps to indicate that a thread has been removed from the
+ * ready state.
+ */
+
+RTEMS_INLINE_ROUTINE void _Priority_Remove_from_bit_map (
+ Priority_Information *the_priority_map
+)
+{
+ *the_priority_map->minor &= the_priority_map->block_minor;
+ if ( *the_priority_map->minor == 0 )
+ _Priority_Major_bit_map &= the_priority_map->block_major;
+}
+
+/**
+ * This function returns the priority of the highest priority
+ * ready thread.
+ */
+
+RTEMS_INLINE_ROUTINE Priority_Control _Priority_Get_highest( void )
+{
+ Priority_Bit_map_control minor;
+ Priority_Bit_map_control major;
+
+ _Bitfield_Find_first_bit( _Priority_Major_bit_map, major );
+ _Bitfield_Find_first_bit( _Priority_Bit_map[major], minor );
+
+ return (_Priority_Bits_index( major ) << 4) +
+ _Priority_Bits_index( minor );
+}
+
+/**
+ * This routine initializes the_priority_map so that it
+ * contains the information necessary to manage a thread
+ * at new_priority.
+ */
+
+RTEMS_INLINE_ROUTINE void _Priority_Initialize_information(
+ Priority_Information *the_priority_map,
+ Priority_Control new_priority
+)
+{
+ Priority_Bit_map_control major;
+ Priority_Bit_map_control minor;
+ Priority_Bit_map_control mask;
+
+ major = _Priority_Major( new_priority );
+ minor = _Priority_Minor( new_priority );
+
+ the_priority_map->minor =
+ &_Priority_Bit_map[ _Priority_Bits_index(major) ];
+
+ mask = _Priority_Mask( major );
+ the_priority_map->ready_major = mask;
+ the_priority_map->block_major = ~mask;
+
+ mask = _Priority_Mask( minor );
+ the_priority_map->ready_minor = mask;
+ the_priority_map->block_minor = ~mask;
+}
+
+/**
+ * This function returns TRUE if the priority GROUP is empty, and
+ * FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Priority_Is_group_empty (
+ Priority_Control the_priority
+)
+{
+ return the_priority == 0;
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/stack.inl b/cpukit/score/inline/rtems/score/stack.inl
new file mode 100644
index 0000000000..863d703aa3
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/stack.inl
@@ -0,0 +1,75 @@
+/**
+ * @file rtems/score/stack.inl
+ *
+ * This file contains the static inline implementation of the inlined
+ * routines from the Stack Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_STACK_INL
+#define _RTEMS_SCORE_STACK_INL
+
+/**
+ * @addtogroup ScoreStack
+ * @{
+ */
+
+/**
+ * This routine initializes the_stack record to indicate that
+ * size bytes of memory starting at starting_address have been
+ * reserved for a stack.
+ */
+
+RTEMS_INLINE_ROUTINE void _Stack_Initialize (
+ Stack_Control *the_stack,
+ void *starting_address,
+ uint32_t size
+)
+{
+ the_stack->area = starting_address;
+ the_stack->size = size;
+}
+
+/**
+ * This function returns TRUE if size bytes is enough memory for
+ * a valid stack area on this processor, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Stack_Is_enough (
+ uint32_t size
+)
+{
+ return ( size >= STACK_MINIMUM_SIZE );
+}
+
+/**
+ * This function increases the stack size to ensure that the thread
+ * has the desired amount of stack space after the initial stack
+ * pointer is determined based on alignment restrictions.
+ *
+ * @note
+ *
+ * The amount of adjustment for alignment is CPU dependent.
+ */
+
+RTEMS_INLINE_ROUTINE uint32_t _Stack_Adjust_size (
+ uint32_t size
+)
+{
+ return size + CPU_STACK_ALIGNMENT;
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/states.inl b/cpukit/score/inline/rtems/score/states.inl
new file mode 100644
index 0000000000..7eaaa1a841
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/states.inl
@@ -0,0 +1,287 @@
+/**
+ * @file rtems/score/states.inl
+ *
+ * This file contains the macro implementation of the inlined
+ * routines associated with thread state information.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_STATES_INL
+#define _RTEMS_SCORE_STATES_INL
+
+/**
+ * @addtogroup ScoreStates
+ * @{
+ */
+
+/**
+ * This function sets the given states_to_set into the current_state
+ * passed in. The result is returned to the user in current_state.
+ */
+
+RTEMS_INLINE_ROUTINE States_Control _States_Set (
+ States_Control states_to_set,
+ States_Control current_state
+)
+{
+ return (current_state | states_to_set);
+}
+
+/**
+ * This function clears the given states_to_clear into the current_state
+ * passed in. The result is returned to the user in current_state.
+ */
+
+RTEMS_INLINE_ROUTINE States_Control _States_Clear (
+ States_Control states_to_clear,
+ States_Control current_state
+)
+{
+ return (current_state & ~states_to_clear);
+}
+
+/**
+ * This function returns TRUE if the_states indicates that the
+ * state is READY, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_ready (
+ States_Control the_states
+)
+{
+ return (the_states == STATES_READY);
+}
+
+/**
+ * This function returns TRUE if the DORMANT state is the ONLY state
+ * set in the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_only_dormant (
+ States_Control the_states
+)
+{
+ return (the_states == STATES_DORMANT);
+}
+
+/**
+ * This function returns TRUE if the DORMANT state is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_dormant (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_DORMANT);
+}
+
+/**
+ * This function returns TRUE if the SUSPENDED state is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_suspended (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_SUSPENDED);
+}
+
+/**
+ * This function returns TRUE if the TRANSIENT state is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_transient (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_TRANSIENT);
+}
+
+/**
+ * This function returns TRUE if the DELAYING state is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_delaying (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_DELAYING);
+}
+
+/**
+ * This function returns TRUE if the WAITING_FOR_BUFFER state is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_waiting_for_buffer (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_FOR_BUFFER);
+}
+
+/**
+ * This function returns TRUE if the WAITING_FOR_SEGMENT state is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_waiting_for_segment (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_FOR_SEGMENT);
+}
+
+/**
+ * This function returns TRUE if the WAITING_FOR_MESSAGE state is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_waiting_for_message (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_FOR_MESSAGE);
+}
+
+/**
+ * This function returns TRUE if the WAITING_FOR_EVENT state is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_waiting_for_event (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_FOR_EVENT);
+}
+
+/**
+ * This function returns TRUE if the WAITING_FOR_MUTEX state
+ * is set in the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_waiting_for_mutex (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_FOR_MUTEX);
+}
+
+/**
+ * This function returns TRUE if the WAITING_FOR_SEMAPHORE state
+ * is set in the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_waiting_for_semaphore (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_FOR_SEMAPHORE);
+}
+
+/**
+ * This function returns TRUE if the WAITING_FOR_TIME state is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_waiting_for_time (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_FOR_TIME);
+}
+
+/**
+ * This function returns TRUE if the WAITING_FOR_TIME state is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_waiting_for_rpc_reply (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_FOR_RPC_REPLY);
+}
+
+/**
+ * This function returns TRUE if the WAITING_FOR_PERIOD state is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_waiting_for_period (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_FOR_PERIOD);
+}
+
+/**
+ * This function returns TRUE if one of the states which indicates
+ * that a task is blocked waiting for a local resource is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_locally_blocked (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_LOCALLY_BLOCKED);
+}
+
+/**
+ * This function returns TRUE if one of the states which indicates
+ * that a task is blocked waiting for a local resource is set in
+ * the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_waiting_on_thread_queue (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_ON_THREAD_QUEUE);
+}
+
+/**
+ * This function returns TRUE if one of the states which indicates
+ * that a task is blocked is set in the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Is_blocked (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_BLOCKED);
+}
+
+/**
+ * This function returns TRUE if any of the states in the mask
+ * are set in the_states, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _States_Are_set (
+ States_Control the_states,
+ States_Control mask
+)
+{
+ return ( (the_states & mask) != STATES_READY);
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/sysstate.inl b/cpukit/score/inline/rtems/score/sysstate.inl
new file mode 100644
index 0000000000..a786c40476
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/sysstate.inl
@@ -0,0 +1,123 @@
+/**
+ * @file rtems/score/sysstate.inl
+ *
+ * This file contains the inline implementation of routines regarding the
+ * system state.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_SYSSTATE_INL
+#define _RTEMS_SCORE_SYSSTATE_INL
+
+/**
+ * @addtogroup ScoreSysState
+ * @{
+ */
+
+/**
+ * This routine initializes the system state handler.
+ */
+
+RTEMS_INLINE_ROUTINE void _System_state_Handler_initialization (
+ boolean is_multiprocessing
+)
+{
+ _System_state_Current = SYSTEM_STATE_BEFORE_INITIALIZATION;
+ _System_state_Is_multiprocessing = is_multiprocessing;
+}
+
+/**
+ * This routine sets the current system state to that specified by
+ * the called.
+ */
+
+RTEMS_INLINE_ROUTINE void _System_state_Set (
+ System_state_Codes state
+)
+{
+ _System_state_Current = state;
+}
+
+/**
+ * This function returns the current system state.
+ */
+
+RTEMS_INLINE_ROUTINE System_state_Codes _System_state_Get ( void )
+{
+ return _System_state_Current;
+}
+
+/**
+ * This function returns TRUE if the state is equal to the
+ * "before initialization" state, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _System_state_Is_before_initialization (
+ System_state_Codes state
+)
+{
+ return (state == SYSTEM_STATE_BEFORE_INITIALIZATION);
+}
+
+/**
+ * This function returns TRUE if the state is equal to the
+ * "before multitasking" state, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _System_state_Is_before_multitasking (
+ System_state_Codes state
+)
+{
+ return (state == SYSTEM_STATE_BEFORE_MULTITASKING);
+}
+
+/**
+ * This function returns TRUE if the state is equal to the
+ * "begin multitasking" state, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _System_state_Is_begin_multitasking (
+ System_state_Codes state
+)
+{
+ return (state == SYSTEM_STATE_BEGIN_MULTITASKING);
+}
+
+/**
+ * This function returns TRUE if the state is equal to the
+ * "up" state, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _System_state_Is_up (
+ System_state_Codes state
+)
+{
+ return (state == SYSTEM_STATE_UP);
+}
+
+/**
+ * This function returns TRUE if the state is equal to the
+ * "failed" state, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _System_state_Is_failed (
+ System_state_Codes state
+)
+{
+ return (state == SYSTEM_STATE_FAILED);
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/thread.inl b/cpukit/score/inline/rtems/score/thread.inl
new file mode 100644
index 0000000000..125f7cf5f7
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/thread.inl
@@ -0,0 +1,334 @@
+/**
+ * @file rtems/score/thread.inl
+ *
+ * This file contains the macro implementation of the inlined
+ * routines from the Thread handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_THREAD_INL
+#define _RTEMS_SCORE_THREAD_INL
+
+/**
+ * @addtogroup ScoreThread
+ * @{
+ */
+
+/**
+ * This routine halts multitasking and returns control to
+ * the "thread" (i.e. the BSP) which initially invoked the
+ * routine which initialized the system.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_Stop_multitasking( void )
+{
+ _Context_Switch( &_Thread_Executing->Registers, &_Thread_BSP_context );
+}
+
+/**
+ * This function returns TRUE if the_thread is the currently executing
+ * thread, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Thread_Is_executing (
+ Thread_Control *the_thread
+)
+{
+ return ( the_thread == _Thread_Executing );
+}
+
+/**
+ * This function returns TRUE if the_thread is the heir
+ * thread, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Thread_Is_heir (
+ Thread_Control *the_thread
+)
+{
+ return ( the_thread == _Thread_Heir );
+}
+
+/**
+ * This function returns TRUE if the currently executing thread
+ * is also the heir thread, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Thread_Is_executing_also_the_heir( void )
+{
+ return ( _Thread_Executing == _Thread_Heir );
+}
+
+/**
+ * This routine clears any blocking state for the_thread. It performs
+ * any necessary scheduling operations including the selection of
+ * a new heir thread.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_Unblock (
+ Thread_Control *the_thread
+)
+{
+ _Thread_Clear_state( the_thread, STATES_BLOCKED );
+}
+
+/**
+ * This routine resets the current context of the calling thread
+ * to that of its initial state.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_Restart_self( void )
+{
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ if ( _Thread_Executing->fp_context != NULL )
+ _Context_Restore_fp( &_Thread_Executing->fp_context );
+#endif
+
+ _CPU_Context_Restart_self( &_Thread_Executing->Registers );
+}
+
+/**
+ * This function returns a pointer to the highest priority
+ * ready thread.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_Calculate_heir( void )
+{
+ _Thread_Heir = (Thread_Control *)
+ _Thread_Ready_chain[ _Priority_Get_highest() ].first;
+}
+
+/**
+ * This function returns TRUE if the floating point context of
+ * the_thread is currently loaded in the floating point unit, and
+ * FALSE otherwise.
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+RTEMS_INLINE_ROUTINE boolean _Thread_Is_allocated_fp (
+ Thread_Control *the_thread
+)
+{
+ return ( the_thread == _Thread_Allocated_fp );
+}
+#endif
+
+/**
+ * This routine is invoked when the currently loaded floating
+ * point context is now longer associated with an active thread.
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+RTEMS_INLINE_ROUTINE void _Thread_Deallocate_fp( void )
+{
+ _Thread_Allocated_fp = NULL;
+}
+#endif
+
+/**
+ * This routine prevents dispatching.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_Disable_dispatch( void )
+{
+ _Thread_Dispatch_disable_level += 1;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+}
+
+/**
+ * This routine allows dispatching to occur again. If this is
+ * the outer most dispatching critical section, then a dispatching
+ * operation will be performed and, if necessary, control of the
+ * processor will be transferred to the heir thread.
+ */
+
+#if ( CPU_INLINE_ENABLE_DISPATCH == TRUE )
+RTEMS_INLINE_ROUTINE void _Thread_Enable_dispatch()
+{
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ if ( (--_Thread_Dispatch_disable_level) == 0 )
+ _Thread_Dispatch();
+}
+#endif
+
+#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE )
+void _Thread_Enable_dispatch( void );
+#endif
+
+/**
+ * This routine allows dispatching to occur again. However,
+ * no dispatching operation is performed even if this is the outer
+ * most dispatching critical section.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_Unnest_dispatch( void )
+{
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ _Thread_Dispatch_disable_level -= 1;
+}
+
+/**
+ * This function returns TRUE if dispatching is disabled, and FALSE
+ * otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Thread_Is_dispatching_enabled( void )
+{
+ return ( _Thread_Dispatch_disable_level == 0 );
+}
+
+/**
+ * This function returns TRUE if dispatching is disabled, and FALSE
+ * otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Thread_Is_context_switch_necessary( void )
+{
+ return ( _Context_Switch_necessary );
+}
+
+/**
+ * This routine initializes the thread dispatching subsystem.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_Dispatch_initialization( void )
+{
+ _Thread_Dispatch_disable_level = 1;
+}
+
+/**
+ * This function returns TRUE if the_thread is NULL and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Thread_Is_null (
+ Thread_Control *the_thread
+)
+{
+ return ( the_thread == NULL );
+}
+
+/**
+ * This function maps thread IDs to thread control
+ * blocks. If ID corresponds to a local thread, then it
+ * returns the_thread control pointer which maps to ID
+ * and location is set to OBJECTS_LOCAL. If the thread ID is
+ * global and resides on a remote node, then location is set
+ * to OBJECTS_REMOTE, and the_thread is undefined.
+ * Otherwise, location is set to OBJECTS_ERROR and
+ * the_thread is undefined.
+ *
+ * @note The performance of many RTEMS services depends upon
+ * the quick execution of the "good object" path in this
+ * routine. If there is a possibility of saving a few
+ * cycles off the execution time, this routine is worth
+ * further optimization attention.
+ */
+
+RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ uint32_t the_api;
+ uint32_t the_class;
+ Objects_Information *information;
+ Thread_Control *tp = (Thread_Control *) 0;
+
+ if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) {
+ _Thread_Disable_dispatch();
+ *location = OBJECTS_LOCAL;
+ tp = _Thread_Executing;
+ goto done;
+ }
+
+ the_api = _Objects_Get_API( id );
+ if ( the_api && the_api > OBJECTS_APIS_LAST ) {
+ *location = OBJECTS_ERROR;
+ goto done;
+ }
+
+ the_class = _Objects_Get_class( id );
+ if ( the_class != 1 ) { /* threads are always first class :) */
+ *location = OBJECTS_ERROR;
+ goto done;
+ }
+
+ information = _Objects_Information_table[ the_api ][ the_class ];
+
+ if ( !information ) {
+ *location = OBJECTS_ERROR;
+ goto done;
+ }
+
+ tp = (Thread_Control *) _Objects_Get( information, id, location );
+
+done:
+ return tp;
+}
+
+
+/** @brief _Thread_Is_proxy_blocking
+ *
+ * status which indicates that a proxy is blocking, and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE boolean _Thread_Is_proxy_blocking (
+ uint32_t code
+)
+{
+ return (code == THREAD_STATUS_PROXY_BLOCKING);
+}
+
+/**
+ * This routine allocates an internal thread.
+ */
+
+RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Internal_allocate( void )
+{
+ return (Thread_Control *) _Objects_Allocate( &_Thread_Internal_information );
+}
+
+/**
+ * This routine frees an internal thread.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_Internal_free (
+ Thread_Control *the_task
+)
+{
+ _Objects_Free( &_Thread_Internal_information, &the_task->Object );
+}
+
+/**
+ * This routine returns the C library re-enterant pointer.
+ */
+
+RTEMS_INLINE_ROUTINE struct _reent **_Thread_Get_libc_reent( void )
+{
+ return _Thread_libc_reent;
+}
+
+/**
+ * This routine set the C library re-enterant pointer.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_Set_libc_reent (
+ struct _reent **libc_reent
+)
+{
+ _Thread_libc_reent = libc_reent;
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/threadmp.inl b/cpukit/score/inline/rtems/score/threadmp.inl
new file mode 100644
index 0000000000..582384fcac
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/threadmp.inl
@@ -0,0 +1,61 @@
+/**
+ * @file rtems/score/threadmp.inl
+ *
+ * This include file contains the bodies of all inlined routines
+ * for the multiprocessing part of thread package.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_THREADMP_INL
+#define _RTEMS_SCORE_THREADMP_INL
+
+/**
+ * @addtogroup ScoreThreadMP
+ * @{
+ */
+
+/**
+ * This function returns true if the thread in question is the
+ * multiprocessing receive thread.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Thread_MP_Is_receive (
+ Thread_Control *the_thread
+)
+{
+ extern Thread_Control *_MPCI_Receive_server_tcb;
+ return the_thread == _MPCI_Receive_server_tcb;
+}
+
+/**
+ * This routine frees a proxy control block to the
+ * inactive chain of free proxy control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_MP_Free_proxy (
+ Thread_Control *the_thread
+)
+{
+ Thread_Proxy_control *the_proxy;
+
+ the_proxy = (Thread_Proxy_control *) the_thread;
+
+ _Chain_Extract( &the_proxy->Active );
+
+ _Chain_Append( &_Thread_MP_Inactive_proxies, &the_thread->Object.Node );
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/tod.inl b/cpukit/score/inline/rtems/score/tod.inl
new file mode 100644
index 0000000000..428989b0f7
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/tod.inl
@@ -0,0 +1,61 @@
+/**
+ * @file rtems/score/tod.inl
+ *
+ * This file contains the static inline implementation of the inlined routines
+ * from the Time of Day Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TOD_INL
+#define _RTEMS_SCORE_TOD_INL
+
+/**
+ * @addtogroup ScoreTOD
+ * @{
+ */
+
+/**
+ * This routine increments the ticks field of the current time of
+ * day at each clock tick.
+ */
+
+RTEMS_INLINE_ROUTINE void _TOD_Tickle_ticks( void )
+{
+ _TOD_Current.ticks += 1;
+ _Watchdog_Ticks_since_boot += 1;
+}
+
+/**
+ * This routine deactivates updating of the current time of day.
+ */
+
+RTEMS_INLINE_ROUTINE void _TOD_Deactivate( void )
+{
+ _Watchdog_Remove( &_TOD_Seconds_watchdog );
+}
+
+/**
+ * This routine activates updating of the current time of day.
+ */
+
+RTEMS_INLINE_ROUTINE void _TOD_Activate(
+ Watchdog_Interval ticks
+)
+{
+ _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, ticks );
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/tqdata.inl b/cpukit/score/inline/rtems/score/tqdata.inl
new file mode 100644
index 0000000000..d1248f4b74
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/tqdata.inl
@@ -0,0 +1,69 @@
+/**
+ * @file rtems/score/tqdata.inl
+ *
+ * This file contains the static inline implementation of the inlined
+ * routines needed to support the Thread Queue Data.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TQDATA_INL
+#define _RTEMS_SCORE_TQDATA_INL
+
+/**
+ * @addtogroup ScoreThreadQ
+ * @{
+ */
+
+/**
+ * This function returns the index of the priority chain on which
+ * a thread of the_priority should be placed.
+ */
+
+RTEMS_INLINE_ROUTINE uint32_t _Thread_queue_Header_number (
+ Priority_Control the_priority
+)
+{
+ return (the_priority / TASK_QUEUE_DATA_PRIORITIES_PER_HEADER);
+}
+
+/**
+ * This function returns TRUE if the_priority indicates that the
+ * enqueue search should start at the front of this priority
+ * group chain, and FALSE if the search should start at the rear.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Thread_queue_Is_reverse_search (
+ Priority_Control the_priority
+)
+{
+ return ( the_priority & TASK_QUEUE_DATA_REVERSE_SEARCH_MASK );
+}
+
+/**
+ * This routine is invoked to indicate that the specified thread queue is
+ * entering a critical section.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Enter_critical_section (
+ Thread_queue_Control *the_thread_queue
+)
+{
+ the_thread_queue->sync_state = THREAD_QUEUE_NOTHING_HAPPENED;
+}
+
+/**
+ * @}
+ */
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/userext.inl b/cpukit/score/inline/rtems/score/userext.inl
new file mode 100644
index 0000000000..6dd5cb6fff
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/userext.inl
@@ -0,0 +1,156 @@
+/**
+ * @file rtems/score/userext.inl
+ *
+ * This file contains the macro implementation of the inlined routines
+ * from the User Extension Handler
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_USEREXT_INL
+#define _RTEMS_SCORE_USEREXT_INL
+
+#include <rtems/score/wkspace.h>
+
+#include <string.h> /* memset */
+
+/**
+ * @addtogroup ScoreUserExt
+ * @{
+ */
+
+/**
+ * This routine is used to add a user extension set to the active list.
+ *
+ * @note Must be before _User_extensions_Handler_initialization to
+ * ensure proper inlining.
+ */
+
+RTEMS_INLINE_ROUTINE void _User_extensions_Add_set (
+ User_extensions_Control *the_extension,
+ User_extensions_Table *extension_table
+)
+{
+ the_extension->Callouts = *extension_table;
+
+ _Chain_Append( &_User_extensions_List, &the_extension->Node );
+
+ /*
+ * If a switch handler is present, append it to the switch chain.
+ */
+
+ if ( extension_table->thread_switch != NULL ) {
+ the_extension->Switch.thread_switch = extension_table->thread_switch;
+ _Chain_Append( &_User_extensions_Switches_list, &the_extension->Switch.Node );
+ }
+}
+
+/**
+ * This routine performs the initialization necessary for this handler.
+ */
+
+RTEMS_INLINE_ROUTINE void _User_extensions_Handler_initialization (
+ uint32_t number_of_extensions,
+ User_extensions_Table *initial_extensions
+)
+{
+ User_extensions_Control *extension;
+ uint32_t i;
+
+ _Chain_Initialize_empty( &_User_extensions_List );
+ _Chain_Initialize_empty( &_User_extensions_Switches_list );
+
+ if ( initial_extensions ) {
+ extension = (User_extensions_Control *)
+ _Workspace_Allocate_or_fatal_error(
+ number_of_extensions * sizeof( User_extensions_Control )
+ );
+
+ memset (
+ extension,
+ 0,
+ number_of_extensions * sizeof( User_extensions_Control )
+ );
+
+ for ( i = 0 ; i < number_of_extensions ; i++ ) {
+ _User_extensions_Add_set (extension, &initial_extensions[i]);
+ extension++;
+ }
+ }
+}
+
+/**
+ * This routine is used to add an API extension set to the active list.
+ */
+
+RTEMS_INLINE_ROUTINE void _User_extensions_Add_API_set (
+ User_extensions_Control *the_extension
+)
+{
+ _Chain_Append( &_User_extensions_List, &the_extension->Node );
+
+ /*
+ * If a switch handler is present, append it to the switch chain.
+ */
+
+ if ( the_extension->Callouts.thread_switch != NULL ) {
+ the_extension->Switch.thread_switch = the_extension->Callouts.thread_switch;
+ _Chain_Append(
+ &_User_extensions_Switches_list, &the_extension->Switch.Node );
+ }
+}
+
+/**
+ * This routine is used to remove a user extension set from the active list.
+ */
+
+RTEMS_INLINE_ROUTINE void _User_extensions_Remove_set (
+ User_extensions_Control *the_extension
+)
+{
+ _Chain_Extract( &the_extension->Node );
+
+ /*
+ * If a switch handler is present, remove it.
+ */
+
+ if ( the_extension->Callouts.thread_switch != NULL )
+ _Chain_Extract( &the_extension->Switch.Node );
+}
+
+/**
+ * This routine is used to invoke the user extension which
+ * is invoked when a context switch occurs.
+ */
+
+RTEMS_INLINE_ROUTINE void _User_extensions_Thread_switch (
+ Thread_Control *executing,
+ Thread_Control *heir
+)
+{
+ Chain_Node *the_node;
+ User_extensions_Switch_control *the_extension_switch;
+
+ for ( the_node = _User_extensions_Switches_list.first ;
+ !_Chain_Is_tail( &_User_extensions_Switches_list, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_extension_switch = (User_extensions_Switch_control *) the_node;
+
+ (*the_extension_switch->thread_switch)( executing, heir );
+ }
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/watchdog.inl b/cpukit/score/inline/rtems/score/watchdog.inl
new file mode 100644
index 0000000000..436d902c4b
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/watchdog.inl
@@ -0,0 +1,258 @@
+/**
+ * @file rtems/score/watchdog.inl
+ *
+ * This file contains the static inline implementation of all inlined
+ * routines in the Watchdog Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_WATCHDOG_INL
+#define _RTEMS_SCORE_WATCHDOG_INL
+
+/**
+ * @addtogroup ScoreWatchdog
+ * @{
+ */
+
+/**
+ * This routine initializes the specified watchdog. The watchdog is
+ * made inactive, the watchdog id and handler routine are set to the
+ * specified values.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Initialize(
+ Watchdog_Control *the_watchdog,
+ Watchdog_Service_routine_entry routine,
+ Objects_Id id,
+ void *user_data
+)
+{
+ the_watchdog->state = WATCHDOG_INACTIVE;
+ the_watchdog->routine = routine;
+ the_watchdog->id = id;
+ the_watchdog->user_data = user_data;
+}
+
+/**
+ * This routine returns TRUE if the watchdog timer is in the ACTIVE
+ * state, and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Watchdog_Is_active(
+ Watchdog_Control *the_watchdog
+)
+{
+
+ return ( the_watchdog->state == WATCHDOG_ACTIVE );
+
+}
+
+/**
+ * This routine activates THE_WATCHDOG timer which is already
+ * on a watchdog chain.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Activate(
+ Watchdog_Control *the_watchdog
+)
+{
+
+ the_watchdog->state = WATCHDOG_ACTIVE;
+
+}
+
+/**
+ * This routine deactivates THE_WATCHDOG timer which will remain
+ * on a watchdog chain.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Deactivate(
+ Watchdog_Control *the_watchdog
+)
+{
+
+ the_watchdog->state = WATCHDOG_REMOVE_IT;
+
+}
+
+/**
+ * This routine is invoked at each clock tick to update the ticks
+ * watchdog chain.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_ticks( void )
+{
+
+ _Watchdog_Tickle( &_Watchdog_Ticks_chain );
+
+}
+
+/**
+ * This routine is invoked at each clock tick to update the seconds
+ * watchdog chain.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_seconds( void )
+{
+
+ _Watchdog_Tickle( &_Watchdog_Seconds_chain );
+
+}
+
+/**
+ * This routine inserts THE_WATCHDOG into the ticks watchdog chain
+ * for a time of UNITS ticks. The INSERT_MODE indicates whether
+ * THE_WATCHDOG is to be activated automatically or later, explicitly
+ * by the caller.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Insert_ticks(
+ Watchdog_Control *the_watchdog,
+ Watchdog_Interval units
+)
+{
+
+ the_watchdog->initial = units;
+
+ _Watchdog_Insert( &_Watchdog_Ticks_chain, the_watchdog );
+
+}
+
+/**
+ * This routine inserts THE_WATCHDOG into the seconds watchdog chain
+ * for a time of UNITS seconds. The INSERT_MODE indicates whether
+ * THE_WATCHDOG is to be activated automatically or later, explicitly
+ * by the caller.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Insert_seconds(
+ Watchdog_Control *the_watchdog,
+ Watchdog_Interval units
+)
+{
+
+ the_watchdog->initial = units;
+
+ _Watchdog_Insert( &_Watchdog_Seconds_chain, the_watchdog );
+
+}
+
+/**
+ * This routine adjusts the seconds watchdog chain in the forward
+ * or backward DIRECTION for UNITS seconds. This is invoked when the
+ * current time of day is changed.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Adjust_seconds(
+ Watchdog_Adjust_directions direction,
+ Watchdog_Interval units
+)
+{
+
+ _Watchdog_Adjust( &_Watchdog_Seconds_chain, direction, units );
+
+}
+
+/**
+ * This routine adjusts the ticks watchdog chain in the forward
+ * or backward DIRECTION for UNITS ticks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Adjust_ticks(
+ Watchdog_Adjust_directions direction,
+ Watchdog_Interval units
+)
+{
+
+ _Watchdog_Adjust( &_Watchdog_Ticks_chain, direction, units );
+
+}
+
+/**
+ * This routine resets THE_WATCHDOG timer to its state at INSERT
+ * time. This routine is valid only on interval watchdog timers
+ * and is used to make an interval watchdog timer fire "every" so
+ * many ticks.
+ */
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Reset(
+ Watchdog_Control *the_watchdog
+)
+{
+
+ (void) _Watchdog_Remove( the_watchdog );
+
+ _Watchdog_Insert( &_Watchdog_Ticks_chain, the_watchdog );
+
+}
+
+/**
+ * This routine returns a pointer to the watchdog timer following
+ * THE_WATCHDOG on the watchdog chain.
+ */
+
+RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Next(
+ Watchdog_Control *the_watchdog
+)
+{
+
+ return ( (Watchdog_Control *) the_watchdog->Node.next );
+
+}
+
+/**
+ * This routine returns a pointer to the watchdog timer preceding
+ * THE_WATCHDOG on the watchdog chain.
+ */
+
+RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Previous(
+ Watchdog_Control *the_watchdog
+)
+{
+
+ return ( (Watchdog_Control *) the_watchdog->Node.previous );
+
+}
+
+/**
+ * This routine returns a pointer to the first watchdog timer
+ * on the watchdog chain HEADER.
+ */
+
+RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_First(
+ Chain_Control *header
+)
+{
+
+ return ( (Watchdog_Control *) header->first );
+
+}
+
+/**
+ * This routine returns a pointer to the last watchdog timer
+ * on the watchdog chain HEADER.
+ */
+
+RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Last(
+ Chain_Control *header
+)
+{
+
+ return ( (Watchdog_Control *) header->last );
+
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/wkspace.inl b/cpukit/score/inline/rtems/score/wkspace.inl
new file mode 100644
index 0000000000..736bb17712
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/wkspace.inl
@@ -0,0 +1,56 @@
+/**
+ * @file rtems/score/wkspace.inl
+ *
+ * This include file contains the bodies of the routines which contains
+ * information related to the RAM Workspace.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_WKSPACE_INL
+#define _RTEMS_SCORE_WKSPACE_INL
+
+/**
+ * @addtogroup ScoreWorkspace
+ * @{
+ */
+
+/**
+ * This routine returns the address of a block of memory of size
+ * bytes. If a block of the appropriate size cannot be allocated
+ * from the workspace, then NULL is returned.
+ */
+
+RTEMS_INLINE_ROUTINE void *_Workspace_Allocate(
+ uint32_t size
+)
+{
+ return _Heap_Allocate( &_Workspace_Area, size );
+}
+
+/**
+ * This function frees the specified block of memory. If the block
+ * belongs to the Workspace and can be successfully freed, then
+ * TRUE is returned. Otherwise FALSE is returned.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Workspace_Free(
+ void *block
+)
+{
+ return _Heap_Free( &_Workspace_Area, block );
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/README b/cpukit/score/macros/README
new file mode 100644
index 0000000000..c2d2e607d6
--- /dev/null
+++ b/cpukit/score/macros/README
@@ -0,0 +1,14 @@
+#
+# $Id$
+#
+
+The files in this directory are not considered the "primary" source
+of inlined routines for RTEMS. The "inline" directory contains
+the implementations of the inlined basis which are regularly
+tested. In general, an effort is made to keep the contents of
+this directory up to date but testing is only performed irregularly
+and even then it is usually with a single target processor and BSP.
+
+The primary purpose of the code in this directory is to ensure
+that RTEMS can be compiled using a C compiler which does not support
+static inline routines.
diff --git a/cpukit/score/macros/rtems/score/address.inl b/cpukit/score/macros/rtems/score/address.inl
new file mode 100644
index 0000000000..3797e8906d
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/address.inl
@@ -0,0 +1,75 @@
+/* macros/address.h
+ *
+ * This include file contains the bodies of the routines
+ * about addresses which are inlined.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_ADDRESS_INL
+#define _RTEMS_SCORE_ADDRESS_INL
+
+/*PAGE
+ *
+ * _Addresses_Add_offset
+ *
+ */
+
+#define _Addresses_Add_offset( _base, _offset ) \
+ ((void *)((char *)(_base) + (_offset)))
+
+/*PAGE
+ *
+ * _Addresses_Subtract_offset
+ *
+ */
+
+#define _Addresses_Subtract_offset( _base, _offset ) \
+ ((void *)((char *)(_base) - (_offset)))
+
+/*PAGE
+ *
+ * _Addresses_Subtract
+ *
+ * NOTE: The cast of an address to an uint32_t makes this code
+ * dependent on an addresses being thirty two bits.
+ */
+
+#define _Addresses_Subtract( _left, _right ) \
+ ((void *)(_left) - (void *)(_right))
+
+/*PAGE
+ *
+ * _Addresses_Is_aligned
+ *
+ */
+
+#if (CPU_ALIGNMENT == 0)
+#define _Addresses_Is_aligned( _address ) \
+ (TRUE)
+#elif defined(RTEMS_CPU_HAS_16_BIT_ADDRESSES)
+#define _Addresses_Is_aligned( _address ) \
+ ( ( (unsigned short)(_address) % CPU_ALIGNMENT ) == 0 )
+#else
+#define _Addresses_Is_aligned( _address ) \
+ ( ( (uint32_t )(_address) % CPU_ALIGNMENT ) == 0 )
+#endif
+
+/*PAGE
+ *
+ * _Addresses_Is_in_range
+ *
+ */
+
+#define _Addresses_Is_in_range( _address, _base, _limit ) \
+ ( (_address) >= (_base) && (_address) <= (_limit) )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/chain.inl b/cpukit/score/macros/rtems/score/chain.inl
new file mode 100644
index 0000000000..a11a25b671
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/chain.inl
@@ -0,0 +1,199 @@
+/* macros/chain.h
+ *
+ * This include file contains the bodies of the routines which are
+ * associated with doubly linked chains and inlined.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CHAIN_INL
+#define _RTEMS_SCORE_CHAIN_INL
+
+/*PAGE
+ *
+ * _Chain_Are_nodes_equal
+ */
+
+#define _Chain_Are_nodes_equal( _left, _right ) \
+ ( (_left) == (_right) )
+
+/*PAGE
+ *
+ * _Chain_Is_null
+ */
+
+#define _Chain_Is_null( _the_chain ) \
+ ( (_the_chain) == NULL )
+
+/*PAGE
+ *
+ * _Chain_Is_null_node
+ */
+
+#define _Chain_Is_null_node( _the_node ) \
+ ( (_the_node) == NULL )
+
+/*PAGE
+ *
+ * _Chain_Head
+ */
+
+#define _Chain_Head( _the_chain ) \
+ ((Chain_Node *) ((void *)(_the_chain)))
+
+/*PAGE
+ *
+ * _Chain_Tail
+ */
+
+#define _Chain_Tail( _the_chain ) \
+ ((Chain_Node *) ((void *)&(_the_chain)->permanent_null))
+
+/*PAGE
+ *
+ * _Chain_Is_empty
+ */
+
+#define _Chain_Is_empty( _the_chain ) \
+ ( (_the_chain)->first == _Chain_Tail( (_the_chain) ) )
+
+/*PAGE
+ *
+ * _Chain_Is_first
+ */
+
+#define _Chain_Is_first( _the_node ) \
+ ( (the_node)->previous == NULL )
+
+/*PAGE
+ *
+ * _Chain_Is_last
+ */
+
+#define _Chain_Is_last( _the_node ) \
+ ( (_the_node)->next == NULL )
+
+/*PAGE
+ *
+ * _Chain_Has_only_one_node
+ */
+
+#define _Chain_Has_only_one_node( _the_chain ) \
+ ( (_the_chain)->first == (_the_chain)->last )
+
+/*PAGE
+ *
+ * _Chain_Is_head
+ */
+
+#define _Chain_Is_head( _the_chain, _the_node ) \
+ ( (_the_node) == _Chain_Head( (_the_chain) ) )
+
+/*PAGE
+ *
+ * _Chain_Is_tail
+ */
+
+#define _Chain_Is_tail( _the_chain, _the_node ) \
+ ( (_the_node) == _Chain_Tail( (_the_chain) ) )
+
+/*PAGE
+ *
+ * Chain_Initialize_empty
+ */
+
+#define _Chain_Initialize_empty( _the_chain ) \
+{ \
+ (_the_chain)->first = _Chain_Tail( (_the_chain) ); \
+ (_the_chain)->permanent_null = NULL; \
+ (_the_chain)->last = _Chain_Head( (_the_chain) ); \
+}
+
+/*PAGE
+ *
+ * _Chain_Extract_unprotected
+ */
+
+#define _Chain_Extract_unprotected( _the_node ) \
+{ \
+ Chain_Node *_next; \
+ Chain_Node *_previous; \
+ \
+ _next = (_the_node)->next; \
+ _previous = (_the_node)->previous; \
+ _next->previous = _previous; \
+ _previous->next = _next; \
+}
+
+/*PAGE
+ *
+ * _Chain_Get_unprotected
+ */
+
+/*PAGE
+ *
+ * Chain_Get_unprotected
+ */
+
+#define _Chain_Get_unprotected( _the_chain ) \
+ (( !_Chain_Is_empty( (_the_chain) ) ) \
+ ? _Chain_Get_first_unprotected( (_the_chain) ) \
+ : NULL)
+
+/*PAGE
+ *
+ * _Chain_Insert_unprotected
+ */
+
+#define _Chain_Insert_unprotected( _after_node, _the_node ) \
+do { \
+ Chain_Node *_before_node; \
+ \
+ (_the_node)->previous = (_after_node); \
+ _before_node = (_after_node)->next; \
+ (_after_node)->next = (_the_node); \
+ (_the_node)->next = _before_node; \
+ _before_node->previous = (_the_node); \
+} while (0)
+
+/*PAGE
+ *
+ * _Chain_Append_unprotected
+ */
+
+#define _Chain_Append_unprotected( _the_chain, _the_node ) \
+{ \
+ Chain_Node *_old_last_node; \
+ \
+ (_the_node)->next = _Chain_Tail( (_the_chain) ); \
+ _old_last_node = (_the_chain)->last; \
+ (_the_chain)->last = (_the_node); \
+ _old_last_node->next = (_the_node); \
+ (_the_node)->previous = _old_last_node; \
+}
+
+/*PAGE
+ *
+ * _Chain_Prepend_unprotected
+ */
+
+#define _Chain_Prepend_unprotected( _the_chain, _the_node ) \
+ _Chain_Insert_unprotected( _Chain_Head( (_the_chain) ), (_the_node) )
+
+/*PAGE
+ *
+ * _Chain_Prepend
+ */
+
+#define _Chain_Prepend( _the_chain, _the_node ) \
+ _Chain_Insert( _Chain_Head( (_the_chain) ), (_the_node) )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/coremsg.inl b/cpukit/score/macros/rtems/score/coremsg.inl
new file mode 100644
index 0000000000..4a7e3652ef
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/coremsg.inl
@@ -0,0 +1,148 @@
+/* coremsg.inl
+ *
+ * This include file contains the macro implementation of all
+ * inlined routines in the Core Message Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_COREMSG_INL
+#define _RTEMS_SCORE_COREMSG_INL
+
+#include <string.h> /* for memcpy */
+
+/*PAGE
+ *
+ * _CORE_message_queue_Send
+ *
+ */
+
+#define _CORE_message_queue_Send( _the_message_queue, _buffer, _size, \
+ _id, _api_message_queue_mp_support, _wait, _timeout ) \
+ _CORE_message_queue_Submit( (_the_message_queue), (_buffer), (_size), \
+ (_id), (_api_message_queue_mp_support), \
+ CORE_MESSAGE_QUEUE_SEND_REQUEST, (_wait), (_timeout) )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Urgent
+ *
+ */
+
+#define _CORE_message_queue_Urgent( _the_message_queue, _buffer, _size, \
+ _id, _api_message_queue_mp_support, _wait, _timeout ) \
+ _CORE_message_queue_Submit( (_the_message_queue), (_buffer), (_size), \
+ (_id), (_api_message_queue_mp_support), \
+ CORE_MESSAGE_QUEUE_URGENT_REQUEST, (_wait), (_timeout) )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Copy_buffer
+ */
+
+#define _CORE_message_queue_Copy_buffer( _source, _destination, _size ) \
+ memcpy( _destination, _source, _size)
+
+/*PAGE
+ *
+ * _CORE_message_queue_Allocate_message_buffer
+ *
+ */
+
+#define _CORE_message_queue_Allocate_message_buffer( _the_message_queue ) \
+ (CORE_message_queue_Buffer_control *) \
+ _Chain_Get( &(_the_message_queue)->Inactive_messages )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Free_message_buffer
+ *
+ */
+
+#define _CORE_message_queue_Free_message_buffer( _the_message_queue, _the_message ) \
+ _Chain_Append( \
+ &(_the_message_queue)->Inactive_messages, \
+ &(_the_message)->Node \
+ )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Is_priority
+ *
+ */
+
+#define _CORE_message_queue_Is_priority( _the_attribute ) \
+ ((_the_attribute)->discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY)
+
+/*PAGE
+ *
+ * _CORE_message_queue_Get_pending_message
+ *
+ */
+
+#define _CORE_message_queue_Get_pending_message( _the_message_queue ) \
+ (CORE_message_queue_Buffer_control *) \
+ _Chain_Get_unprotected( &(_the_message_queue)->Pending_messages )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Append
+ *
+ */
+
+#define _CORE_message_queue_Append_unprotected( \
+ _the_message_queue, _the_message ) \
+ _Chain_Append_unprotected( &(_the_message_queue)->Pending_messages, \
+ &(_the_message)->Node )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Prepend
+ *
+ */
+
+#define _CORE_message_queue_Prepend_unprotected( \
+ _the_message_queue, _the_message ) \
+ _Chain_Prepend_unprotected( &(_the_message_queue)->Pending_messages, \
+ &(_the_message)->Node )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Is_null
+ *
+ */
+
+#define _CORE_message_queue_Is_null( _the_message_queue ) \
+ ( (_the_message_queue) == NULL )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Is_notify_enabled
+ *
+ */
+
+#define _CORE_message_queue_Is_notify_enabled( _the_message_queue ) \
+ ( (_the_message_queue)->notify_handler != NULL )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Set_notify
+ *
+ */
+
+#define _CORE_message_queue_Set_notify( \
+ _the_message_queue, _the_handler, _the_argument ) \
+ do { \
+ (_the_message_queue)->notify_handler = (_the_handler); \
+ (_the_message_queue)->notify_argument = (_the_argument); \
+ } while ( 0 )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/coremutex.inl b/cpukit/score/macros/rtems/score/coremutex.inl
new file mode 100644
index 0000000000..e0620d337a
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/coremutex.inl
@@ -0,0 +1,81 @@
+/* macros/coremutex.h
+ *
+ * This include file contains all of the inlined routines associated
+ * with core mutexes.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_COREMUTEX_INL
+#define _RTEMS_SCORE_COREMUTEX_INL
+
+
+/*PAGE
+ *
+ * _CORE_mutex_Is_locked
+ *
+ */
+
+#define _CORE_mutex_Is_locked( _the_mutex ) \
+ ( (_the_mutex)->lock == CORE_MUTEX_LOCKED )
+
+/*PAGE
+ *
+ * _CORE_mutex_Is_fifo
+ *
+ */
+
+#define _CORE_mutex_Is_fifo( _the_attribute ) \
+ ( (_the_attribute)->discipline == CORE_MUTEX_DISCIPLINES_FIFO )
+
+/*PAGE
+ *
+ * _CORE_mutex_Is_priority
+ *
+ */
+
+#define _CORE_mutex_Is_priority( _the_attribute ) \
+ ( (_the_attribute)->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY )
+
+/*PAGE
+ *
+ * _CORE_mutex_Is_inherit_priority
+ *
+ */
+
+#define _CORE_mutex_Is_inherit_priority( _the_attribute ) \
+ ( (_the_attribute)->discipline == \
+ CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT )
+
+/*PAGE
+ *
+ * _CORE_mutex_Is_priority_ceiling
+ *
+ */
+
+#define _CORE_mutex_Is_priority_ceiling( _the_attribute )\
+ ( (_the_attribute)->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING )
+
+/*PAGE
+ *
+ * _CORE_mutex_Seize_interrupt_trylock
+ *
+ * NOTE: This is not really a MACRO version of this routine.
+ * A body is in coremutexseize.c that is duplicated
+ * from the .inl by hand.
+ */
+
+int _CORE_mutex_Seize_interrupt_trylock(
+ CORE_mutex_Control *the_mutex,
+ ISR_Level *level_p
+);
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/coresem.inl b/cpukit/score/macros/rtems/score/coresem.inl
new file mode 100644
index 0000000000..51e5949004
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/coresem.inl
@@ -0,0 +1,71 @@
+/* macros/coresem.h
+ *
+ * This include file contains all of the inlined routines associated
+ * with core semaphores.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_CORESEM_INL
+#define _RTEMS_SCORE_CORESEM_INL
+
+/*PAGE
+ *
+ * _CORE_semaphore_Is_priority
+ *
+ */
+
+#define _CORE_semaphore_Is_priority( _the_attribute ) \
+ ( (_the_attribute)->discipline == CORE_SEMAPHORE_DISCIPLINES_PRIORITY )
+
+/*PAGE
+ *
+ * _CORE_semaphore_Get_count
+ *
+ */
+
+#define _CORE_semaphore_Get_count( _the_semaphore ) \
+ ( (_the_semaphore)->count )
+
+/*PAGE
+ *
+ * _CORE_semaphore_Seize_isr_disable
+ */
+
+#define _CORE_semaphore_Seize_isr_disable( \
+ _the_semaphore, _id, _wait, _timeout, _level_p) \
+{ \
+ Thread_Control *executing; \
+ ISR_Level level = *(_level_p); \
+ \
+ /* disabled when you get here */ \
+ \
+ executing = _Thread_Executing; \
+ executing->Wait.return_code = CORE_SEMAPHORE_STATUS_SUCCESSFUL; \
+ if ( (_the_semaphore)->count != 0 ) { \
+ (_the_semaphore)->count -= 1; \
+ _ISR_Enable( level ); \
+ } else if ( !(_wait) ) { \
+ _ISR_Enable( level ); \
+ executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT; \
+ } else { \
+ _Thread_Disable_dispatch(); \
+ _Thread_queue_Enter_critical_section( &(_the_semaphore)->Wait_queue ); \
+ executing->Wait.queue = &(_the_semaphore)->Wait_queue; \
+ executing->Wait.id = (_id); \
+ _ISR_Enable( level ); \
+ \
+ _Thread_queue_Enqueue( &(_the_semaphore)->Wait_queue, (_timeout) ); \
+ _Thread_Enable_dispatch(); \
+ } \
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/heap.inl b/cpukit/score/macros/rtems/score/heap.inl
new file mode 100644
index 0000000000..78accba6b1
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/heap.inl
@@ -0,0 +1,221 @@
+/* heap.inl
+ *
+ * This file contains the macro implementation of the inlined
+ * routines from the heap handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_HEAP_INL
+#define _RTEMS_SCORE_HEAP_INL
+
+/*
+ * WARNING: this file is only visually checked against
+ * '../../../inline/rtems/score/heap.inl'. Use those file for reference
+ * if you encounter problems.
+ */
+
+#include <rtems/score/address.h>
+
+/*PAGE
+ *
+ * _Heap_Head
+ */
+
+#define _Heap_Head( _the_heap ) (&(_the_heap)->free_list)
+
+/*PAGE
+ *
+ * _Heap_Tail
+ */
+
+#define _Heap_Tail( _the_heap ) (&(_the_heap)->free_list)
+
+/*PAGE
+ *
+ * _Heap_First
+ */
+
+#define _Heap_First( _the_heap ) (_Heap_Head(_the_heap)->next)
+
+/*PAGE
+ *
+ * _Heap_Last
+ */
+
+#define _Heap_Last( _the_heap ) (_Heap_Tail(_the_heap)->prev)
+
+/*PAGE
+ *
+ * _Heap_Block_remove
+ *
+ */
+
+#define _Heap_Block_remove( _the_block ) \
+ do { \
+ Heap_Block *block = (_the_block); \
+ Heap_Block *next = block->next; \
+ Heap_Block *prev = block->prev; \
+ prev->next = next; \
+ next->prev = prev; \
+ } while(0)
+
+/*PAGE
+ *
+ * _Heap_Block_replace
+ *
+ */
+
+#define _Heap_Block_replace( _old_block, _new_block ) \
+ do { \
+ Heap_Block *block = (_old_block); \
+ Heap_Block *next = block->next; \
+ Heap_Block *prev = block->prev; \
+ block = (_new_block); \
+ block->next = next; \
+ block->prev = prev; \
+ next->prev = prev->next = block; \
+ } while(0)
+
+/*PAGE
+ *
+ * _Heap_Block_insert_after
+ *
+ */
+
+#define _Heap_Block_insert_after( _prev_block, _the_block ) \
+ do { \
+ Heap_Block *prev = (_prev_block); \
+ Heap_Block *block = (_the_block); \
+ Heap_Block *next = prev->next; \
+ block->next = next; \
+ block->prev = prev; \
+ next->prev = prev->next = block; \
+ } while(0)
+
+/*PAGE
+ *
+ * _Heap_Is_aligned
+ */
+
+#define _Heap_Is_aligned( _value, _alignment ) \
+ (((_value) % (_alignment)) == 0)
+
+/*PAGE
+ *
+ * _Heap_Align_up
+ */
+
+#define _Heap_Align_up( _value, _alignment ) \
+ do { \
+ uint32_t v = *(_value); \
+ uint32_t a = (_alignment); \
+ uint32_t r = v % a; \
+ *(_value) = r ? v - r + a : v; \
+ } while(0)
+
+/*PAGE
+ *
+ * _Heap_Align_down
+ */
+
+#define _Heap_Align_down( _value, _alignment ) \
+ do { \
+ uint32_t v = *(_value); \
+ *(_value) = v - (v % (_alignment)); \
+ } while(0)
+
+/*PAGE
+ *
+ * _Heap_Is_aligned_ptr
+ */
+
+#define _Heap_Is_aligned_ptr( _ptr, _alignment ) \
+ ((_H_p2u(_ptr) % (_alignment)) == 0)
+
+/*PAGE
+ *
+ * _Heap_Align_up_uptr
+ */
+
+#define _Heap_Align_up_uptr( _value, _alignment ) \
+ do { \
+ _H_uptr_t v = *(_value); \
+ uint32_t a = (_alignment); \
+ _H_uptr_t r = v % a; \
+ *(_value) = r ? v - r + a : v; \
+ } while(0)
+
+/*PAGE
+ *
+ * _Heap_Align_down_uptr
+ */
+
+#define _Heap_Align_down_uptr( _value, _alignment ) \
+ do { \
+ _H_uptr_t v = *(_value); \
+ *(_value) = v - (v % (_alignment)); \
+ } while(0)
+
+/*PAGE
+ *
+ * _Heap_Block_at
+ */
+
+#define _Heap_Block_at( _base, _offset ) \
+ ( (Heap_Block *) _Addresses_Add_offset( (_base), (_offset) ) )
+
+/*PAGE
+ *
+ * _Heap_User_area
+ */
+
+#define _Heap_User_area( _the_block ) \
+ ((void *) _Addresses_Add_offset( (_the_block), HEAP_BLOCK_USER_OFFSET ))
+
+/*PAGE
+ *
+ * _Heap_Start_of_block
+ */
+
+#define _Heap_Start_of_block( _the_heap, _base, _the_block_ptr ) \
+ do { \
+ _H_uptr_t addr = _H_p2u(_base); \
+ _Heap_Align_down( &addr, (_the_heap)->page_size ); \
+ *(_the_block_ptr) = (Heap_Block *)(addr - HEAP_BLOCK_USER_OFFSET); \
+ } while(0)
+
+/*PAGE
+ *
+ * _Heap_Is_prev_used
+ */
+
+#define _Heap_Is_prev_used( _the_block ) \
+ ((_the_block)->size & HEAP_PREV_USED)
+
+/*PAGE
+ *
+ * _Heap_Block_size
+ */
+
+#define _Heap_Block_size( _the_block ) \
+ ((_the_block)->size & ~HEAP_PREV_USED)
+
+/*PAGE
+ *
+ * _Heap_Is_block_in
+ */
+
+#define _Heap_Is_block_in( _the_heap, _the_block ) \
+ ( _Addresses_Is_in_range( (_the_block), \
+ (_the_heap)->start, (_the_heap)->final ) )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/isr.inl b/cpukit/score/macros/rtems/score/isr.inl
new file mode 100644
index 0000000000..a193a88d75
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/isr.inl
@@ -0,0 +1,38 @@
+/* isr.inl
+ *
+ * This include file contains the macro implementation of all
+ * inlined routines in the Interrupt Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_ISR_INL
+#define _RTEMS_SCORE_ISR_INL
+
+/*PAGE
+ *
+ * _ISR_Is_vector_number_valid
+ *
+ */
+
+#define _ISR_Is_vector_number_valid( _vector ) \
+ ( (_vector) <= CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER )
+
+/*PAGE
+ *
+ * _ISR_Is_valid_user_handler
+ *
+ */
+
+#define _ISR_Is_valid_user_handler( _handler ) \
+ ((_handler) != NULL)
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/mppkt.inl b/cpukit/score/macros/rtems/score/mppkt.inl
new file mode 100644
index 0000000000..fcb423138b
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/mppkt.inl
@@ -0,0 +1,40 @@
+/* macros/mppkt.h
+ *
+ * This package is the implementation of the Packet Handler
+ * routines which are inlined.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_MPPKT_INL
+#define _RTEMS_SCORE_MPPKT_INL
+
+/*PAGE
+ *
+ * _Mp_packet_Is_valid_packet_class
+ *
+ * NOTE: Check for lower bounds (MP_PACKET_CLASSES_FIRST ) is unnecessary
+ * because this enum starts at lower bound of zero.
+ */
+
+#define _Mp_packet_Is_valid_packet_class( _the_packet_class ) \
+ ( (_the_packet_class) <= MP_PACKET_CLASSES_LAST )
+
+/*PAGE
+ *
+ * _Mp_packet_Is_null
+ *
+ */
+
+#define _Mp_packet_Is_null ( _the_packet ) \
+ ( (_the_packet) == NULL )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/object.inl b/cpukit/score/macros/rtems/score/object.inl
new file mode 100644
index 0000000000..69c8a0a2bf
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/object.inl
@@ -0,0 +1,198 @@
+/**
+ * @file rtems/score/object.inl
+ */
+
+/*
+ * This include file contains the macro implementation of all
+ * of the inlined routines in the Object Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_OBJECT_INL
+#define _RTEMS_SCORE_OBJECT_INL
+
+/*PAGE
+ *
+ * _Objects_Build_id
+ *
+ */
+
+#define _Objects_Build_id( _the_api, _the_class, _node, _index ) \
+ ( (( (Objects_Id) _the_api ) << OBJECTS_API_START_BIT) | \
+ (( (Objects_Id) _the_class ) << OBJECTS_CLASS_START_BIT) | \
+ (( (Objects_Id) _node ) << OBJECTS_NODE_START_BIT) | \
+ (( (Objects_Id) _index ) << OBJECTS_INDEX_START_BIT) )
+
+/*PAGE
+ *
+ * _Objects_Get_API
+ */
+
+#define _Objects_Get_API( _id ) \
+ (Objects_APIs) \
+ (((_id) >> OBJECTS_API_START_BIT) & OBJECTS_API_VALID_BITS)
+
+/*PAGE
+ *
+ * _Objects_Get_class
+ */
+
+#define _Objects_Get_class( _id ) \
+ (uint32_t ) \
+ (((_id) >> OBJECTS_CLASS_START_BIT) & OBJECTS_CLASS_VALID_BITS)
+
+/*PAGE
+ *
+ * _Objects_Get_node
+ *
+ */
+
+#define _Objects_Get_node( _id ) \
+ (((_id) >> OBJECTS_NODE_START_BIT) & OBJECTS_NODE_VALID_BITS)
+
+/*PAGE
+ *
+ * _Objects_Get_index
+ *
+ */
+
+#define _Objects_Get_index( _id ) \
+ (((_id) >> OBJECTS_INDEX_START_BIT) & OBJECTS_INDEX_VALID_BITS)
+
+/*PAGE
+ *
+ * _Objects_Is_class_valid
+ *
+ */
+
+#define _Objects_Is_class_valid( _the_class ) \
+ ( (_the_class) /* XXX && (_the_class) <= OBJECTS_CLASSES_LAST */ )
+
+/*PAGE
+ *
+ * _Objects_Is_local_node
+ *
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#define _Objects_Is_local_node( _node ) \
+ ( (_node) == _Objects_Local_node )
+#endif
+
+/*PAGE
+ *
+ * _Objects_Is_local_id
+ *
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+#define _Objects_Is_local_id( _id ) \
+ _Objects_Is_local_node( _Objects_Get_node(_id) )
+#else
+#define _Objects_Is_local_id( _id ) \
+ TRUE
+#endif
+
+/*PAGE
+ *
+ * _Objects_Are_ids_equal
+ *
+ */
+
+#define _Objects_Are_ids_equal( _left, _right ) \
+ ( (_left) == (_right) )
+
+/*PAGE
+ *
+ * _Objects_Get_local_object
+ *
+ */
+
+#define _Objects_Get_local_object( _information, _index ) \
+ ( ( (_index) > (_information)->maximum) ? NULL : \
+ (_information)->local_table[ (_index) ] )
+
+/*PAGE
+ *
+ * _Objects_Set_local_object
+ *
+ */
+
+#define _Objects_Set_local_object( information, index, the_object ) \
+ { \
+ if ( index <= information->maximum) \
+ information->local_table[ index ] = the_object; \
+ }
+
+
+/*PAGE
+ *
+ * _Objects_Get_information
+ *
+ */
+
+#define _Objects_Get_information( id ) \
+ ( \
+ ( !_Objects_Is_class_valid( _Objects_Get_class( id ) ) ) ? \
+ NULL : \
+ _Objects_Information_table[ _Objects_Get_API( id ) ] \
+ [ _Objects_Get_class( id ) ] \
+ )
+
+/*PAGE
+ *
+ * _Objects_Open
+ *
+ */
+
+#define _Objects_Open( _information, _the_object, _name ) \
+ do { \
+ uint32_t _index; \
+ \
+ _index = _Objects_Get_index( (_the_object)->id ); \
+ (_information)->local_table[ _index ] = (_the_object); \
+ \
+ if ( (_information)->is_string ) \
+ /* _Objects_Copy_name_string( (_name), (_the_object)->name ); */\
+ (_the_object)->name = (_name); \
+ else \
+ /* _Objects_Copy_name_raw( \
+ (_name), (_the_object)->name, (_information)->name_length ); */ \
+ (_the_object)->name = (_name); \
+ } while (0)
+
+/*PAGE
+ *
+ * _Objects_Close
+ *
+ */
+
+#define _Objects_Close( _information, _the_object ) \
+ do { \
+ uint32_t _index; \
+ \
+ _index = _Objects_Get_index( (_the_object)->id ); \
+ (_information)->local_table[ _index ] = (Objects_Control *) NULL; \
+ /* _Objects_Clear_name( (_the_object)->name, (_information)->name_length ); */ \
+ (_the_object)->name = 0; \
+ } while (0)
+
+/*PAGE
+ *
+ * _Objects_Namespace_remove
+ */
+
+#define _Objects_Namespace_remove( _information, _the_object ) \
+ (_the_object)->name = 0; \
+ /* _Objects_Clear_name( (_the_object)->name, (_information)->name_length ) */
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/objectmp.inl b/cpukit/score/macros/rtems/score/objectmp.inl
new file mode 100644
index 0000000000..008eebfc7a
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/objectmp.inl
@@ -0,0 +1,49 @@
+/* macros/objectmp.inl
+ *
+ * This include file contains the bodies of all inlined routines
+ * which deal with global objects.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_OBJECTMP_INL
+#define _RTEMS_SCORE_OBJECTMP_INL
+
+/*PAGE
+ *
+ * _Objects_MP_Allocate_global_object
+ *
+ */
+
+#define _Objects_MP_Allocate_global_object() \
+ (Objects_MP_Control *) \
+ _Chain_Get( &_Objects_MP_Inactive_global_objects )
+
+/*PAGE
+ * _Objects_MP_Free_global_object
+ *
+ */
+
+#define _Objects_MP_Free_global_object( _the_object ) \
+ _Chain_Append( \
+ &_Objects_MP_Inactive_global_objects, \
+ &(_the_object)->Object.Node \
+ )
+
+/*PAGE
+ * _Objects_MP_Is_null_global_object
+ *
+ */
+
+#define _Objects_MP_Is_null_global_object( _the_object ) \
+ ( (_the_object) == NULL )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/priority.inl b/cpukit/score/macros/rtems/score/priority.inl
new file mode 100644
index 0000000000..a46d6d4ab0
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/priority.inl
@@ -0,0 +1,169 @@
+/* priority.inl
+ *
+ * This file contains the macro implementation of all inlined routines
+ * in the Priority Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_PRIORITY_INL
+#define _RTEMS_SCORE_PRIORITY_INL
+
+#include <rtems/score/bitfield.h>
+
+/*PAGE
+ *
+ * _Priority_Handler_initialization
+ *
+ */
+
+#define _Priority_Handler_initialization() \
+ { \
+ uint32_t index; \
+ \
+ _Priority_Major_bit_map = 0; \
+ for ( index=0 ; index <16 ; index++ ) \
+ _Priority_Bit_map[ index ] = 0; \
+ }
+
+/*PAGE
+ *
+ * _Priority_Is_valid
+ *
+ */
+
+ /*
+ * Since PRIORITY_MINIMUM is 0 and priorities are stored unsigned,
+ * then checking for less than 0 is unnecessary.
+ */
+
+#define _Priority_Is_valid( _the_priority ) \
+ ( (_the_priority) <= PRIORITY_MAXIMUM )
+
+/*PAGE
+ *
+ * _Priority_Major
+ *
+ */
+
+#define _Priority_Major( _the_priority ) ( (_the_priority) / 16 )
+
+/*PAGE
+ *
+ * _Priority_Minor
+ *
+ */
+
+#define _Priority_Minor( _the_priority ) ( (_the_priority) % 16 )
+
+#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE )
+
+/*PAGE
+ *
+ * _Priority_Mask
+ *
+ */
+
+#define _Priority_Mask( _bit_number ) \
+ (0x8000 >> _bit_number)
+
+/*PAGE
+ *
+ * _Priority_Bits_index
+ *
+ */
+
+#define _Priority_Bits_index( _bit_number ) \
+ (_bit_number)
+
+#endif
+
+/*PAGE
+ *
+ * _Priority_Add_to_bit_map
+ *
+ */
+
+#define _Priority_Add_to_bit_map( _the_priority_map ) \
+ { \
+ *(_the_priority_map)->minor |= (_the_priority_map)->ready_minor; \
+ _Priority_Major_bit_map |= (_the_priority_map)->ready_major; \
+ }
+
+/*PAGE
+ *
+ * _Priority_Remove_from_bit_map
+ *
+ */
+
+#define _Priority_Remove_from_bit_map( _the_priority_map ) \
+ { \
+ *(_the_priority_map)->minor &= (_the_priority_map)->block_minor; \
+ if ( *(_the_priority_map)->minor == 0 ) \
+ _Priority_Major_bit_map &= (_the_priority_map)->block_major; \
+ }
+
+/*PAGE
+ *
+ * _Priority_Get_highest
+ *
+ */
+
+#define _Priority_Get_highest( _high_priority ) \
+ { \
+ Priority_Bit_map_control minor; \
+ Priority_Bit_map_control major; \
+ \
+ _Bitfield_Find_first_bit( _Priority_Major_bit_map, major ); \
+ _Bitfield_Find_first_bit( _Priority_Bit_map[major], minor ); \
+ \
+ (_high_priority) = (_Priority_Bits_index( major ) * 16) + \
+ _Priority_Bits_index( minor ); \
+ }
+
+/*PAGE
+ *
+ * _Priority_Initialize_information
+ *
+ */
+
+#define _Priority_Initialize_information( \
+ _the_priority_map, _new_priority ) \
+ { \
+ Priority_Bit_map_control _major; \
+ Priority_Bit_map_control _minor; \
+ Priority_Bit_map_control _mask; \
+ \
+ _major = _Priority_Major( (_new_priority) ); \
+ _minor = _Priority_Minor( (_new_priority) ); \
+ \
+ (_the_priority_map)->minor = \
+ &_Priority_Bit_map[ _Priority_Bits_index(_major) ]; \
+ \
+ _mask = _Priority_Mask( _major ); \
+ (_the_priority_map)->ready_major = _mask; \
+ (_the_priority_map)->block_major = ~_mask; \
+ \
+ _mask = _Priority_Mask( _minor ); \
+ (_the_priority_map)->ready_minor = _mask; \
+ (_the_priority_map)->block_minor = ~_mask; \
+ }
+
+/*PAGE
+ *
+ * _Priority_Is_group_empty
+ *
+ */
+
+#define _Priority_Is_group_empty ( _the_priority ) \
+ ( (_the_priority) == 0 )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/stack.inl b/cpukit/score/macros/rtems/score/stack.inl
new file mode 100644
index 0000000000..48d63bd861
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/stack.inl
@@ -0,0 +1,49 @@
+/* stack.inl
+ *
+ * This file contains the macro implementation of the inlined
+ * routines from the Stack Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_STACK_INL
+#define _RTEMS_SCORE_STACK_INL
+
+/*PAGE
+ *
+ * _Stack_Initialize
+ *
+ */
+
+#define _Stack_Initialize( _the_stack, _starting_address, _size ) \
+ { \
+ (_the_stack)->area = (_starting_address); \
+ (_the_stack)->size = (_size); \
+ }
+
+/*PAGE
+ *
+ * _Stack_Is_enough
+ *
+ */
+
+#define _Stack_Is_enough( _size ) \
+ ( (_size) >= STACK_MINIMUM_SIZE )
+
+/*PAGE
+ *
+ * _Stack_Adjust_size
+ */
+
+#define _Stack_Adjust_size( _size ) \
+ ((_size) + CPU_STACK_ALIGNMENT)
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/states.inl b/cpukit/score/macros/rtems/score/states.inl
new file mode 100644
index 0000000000..32ab000d24
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/states.inl
@@ -0,0 +1,209 @@
+/* states.inl
+ *
+ * This file contains the macro implementation of the inlined
+ * routines associated with thread state information.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_STATES_INL
+#define _RTEMS_SCORE_STATES_INL
+
+/*PAGE
+ *
+ * _States_Set
+ *
+ */
+
+#define _States_Set( _states_to_set, _current_state ) \
+ ((_current_state) | (_states_to_set))
+
+/*PAGE
+ *
+ * _States_Clear
+ *
+ */
+
+#define _States_Clear( _states_to_clear, _current_state ) \
+ ((_current_state) & ~(_states_to_clear))
+
+/*PAGE
+ *
+ * _States_Is_ready
+ *
+ */
+
+#define _States_Is_ready( _the_states ) \
+ ( (_the_states) == STATES_READY )
+
+/*PAGE
+ *
+ * _States_Is_only_dormant
+ *
+ */
+
+#define _States_Is_only_dormant( _the_states ) \
+ ( (_the_states) == STATES_DORMANT )
+
+/*PAGE
+ *
+ * _States_Is_dormant
+ *
+ */
+
+#define _States_Is_dormant( _the_states ) \
+ ( (_the_states) & STATES_DORMANT )
+
+/*PAGE
+ *
+ * _States_Is_suspended
+ *
+ */
+
+#define _States_Is_suspended( _the_states ) \
+ ( (_the_states) & STATES_SUSPENDED )
+
+/*PAGE
+ *
+ * _States_Is_Transient
+ *
+ */
+
+#define _States_Is_transient( _the_states ) \
+ ( (_the_states) & STATES_TRANSIENT )
+
+/*PAGE
+ *
+ * _States_Is_delaying
+ *
+ */
+
+#define _States_Is_delaying( _the_states ) \
+ ( (_the_states) & STATES_DELAYING )
+
+/*PAGE
+ *
+ * _States_Is_waiting_for_buffer
+ *
+ */
+
+#define _States_Is_waiting_for_buffer( _the_states ) \
+ ( (_the_states) & STATES_WAITING_FOR_BUFFER )
+
+/*PAGE
+ *
+ * _States_Is_waiting_for_segment
+ *
+ */
+
+#define _States_Is_waiting_for_segment( _the_states ) \
+ ( (_the_states) & STATES_WAITING_FOR_SEGMENT )
+
+/*PAGE
+ *
+ * _States_Is_waiting_for_message
+ *
+ */
+
+#define _States_Is_waiting_for_message( _the_states ) \
+ ( (_the_states) & STATES_WAITING_FOR_MESSAGE )
+
+/*PAGE
+ *
+ * _States_Is_waiting_for_event
+ *
+ */
+
+#define _States_Is_waiting_for_event( _the_states ) \
+ ( (_the_states) & STATES_WAITING_FOR_EVENT )
+
+/*PAGE
+ *
+ * _States_Is_waiting_for_mutex
+ *
+ */
+
+#define _States_Is_waiting_for_mutex( _the_states ) \
+ ( (_the_states) & STATES_WAITING_FOR_MUTEX )
+
+/*PAGE
+ *
+ * _States_Is_waiting_for_semaphore
+ *
+ */
+
+#define _States_Is_waiting_for_semaphore( _the_states ) \
+ ( (_the_states) & STATES_WAITING_FOR_SEMAPHORE )
+
+/*PAGE
+ *
+ * _States_Is_waiting_for_time
+ *
+ */
+
+#define _States_Is_waiting_for_time( _the_states ) \
+ ( (_the_states) & STATES_WAITING_FOR_TIME )
+
+/*PAGE
+ *
+ * _States_Is_waiting_for_rpc_reply
+ *
+ */
+
+#define _States_Is_waiting_for_rpc_reply( _the_states ) \
+ ( (_the_states) & STATES_WAITING_FOR_RPC_REPLY )
+
+/*PAGE
+ *
+ * _States_Is_waiting_for_period
+ *
+ */
+
+#define _States_Is_waiting_for_period( _the_states ) \
+ ( (_the_states) & STATES_WAITING_FOR_PERIOD )
+
+/*PAGE
+ *
+ * _States_Is_locally_blocked
+ *
+ */
+
+#define _States_Is_locally_blocked( _the_states ) \
+ ( (_the_states) & STATES_LOCALLY_BLOCKED )
+
+/*PAGE
+ *
+ * _States_Is_waiting_on_thread_queue
+ *
+ */
+
+#define _States_Is_waiting_on_thread_queue( _the_states ) \
+ ( (_the_states) & STATES_WAITING_ON_THREAD_QUEUE )
+
+/*PAGE
+ *
+ * _States_Is_blocked
+ *
+ */
+
+#define _States_Is_blocked( _the_states ) \
+ ( (_the_states) & STATES_BLOCKED )
+
+/*PAGE
+ *
+ * _States_Are_set
+ *
+ */
+
+#define _States_Are_set( _the_states, _mask ) \
+ ( ((_the_states) & (_mask)) != STATES_READY )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/sysstate.inl b/cpukit/score/macros/rtems/score/sysstate.inl
new file mode 100644
index 0000000000..618bbaf976
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/sysstate.inl
@@ -0,0 +1,89 @@
+/* sysstates.inl
+ *
+ * This file contains the macro implementation of routines regarding the
+ * system state.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_SYSSTATE_INL
+#define _RTEMS_SCORE_SYSSTATE_INL
+
+/*PAGE
+ *
+ * _System_state_Handler_initialization
+ */
+
+#define _System_state_Handler_initialization( _is_multiprocessing ) \
+ do { \
+ _System_state_Current = SYSTEM_STATE_BEFORE_INITIALIZATION; \
+ _System_state_Is_multiprocessing = (_is_multiprocessing); \
+ } while ( 0 )
+
+/*PAGE
+ *
+ * _System_state_Set
+ */
+
+#define _System_state_Set( _state ) \
+ do { \
+ _System_state_Current = (_state); \
+ } while ( 0 )
+
+/*PAGE
+ *
+ * _System_state_Get
+ */
+
+#define _System_state_Get() \
+ (_System_state_Current)
+
+/*PAGE
+ *
+ * _System_state_Is_before_initialization
+ */
+
+#define _System_state_Is_before_initialization( _state ) \
+ ((_state) == SYSTEM_STATE_BEFORE_INITIALIZATION)
+
+/*PAGE
+ *
+ * _System_state_Is_before_multitasking
+ */
+
+#define _System_state_Is_before_multitasking( _state ) \
+ ((_state) == SYSTEM_STATE_BEFORE_MULTITASKING)
+
+/*PAGE
+ *
+ * _System_state_Is_begin_multitasking
+ */
+
+#define _System_state_Is_begin_multitasking( _state ) \
+ ((_state) == SYSTEM_STATE_BEGIN_MULTITASKING)
+
+/*PAGE
+ *
+ * _System_state_Is_up
+ */
+
+#define _System_state_Is_up( _state ) \
+ ((_state) == SYSTEM_STATE_UP)
+
+/*PAGE
+ *
+ * _System_state_Is_failed
+ */
+
+#define _System_state_Is_failed( _state ) \
+ ((_state) == SYSTEM_STATE_FAILED)
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/thread.inl b/cpukit/score/macros/rtems/score/thread.inl
new file mode 100644
index 0000000000..3ace7af4e2
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/thread.inl
@@ -0,0 +1,242 @@
+/* thread.inl
+ *
+ * This file contains the macro implementation of the inlined
+ * routines from the Thread handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_THREAD_INL
+#define _RTEMS_SCORE_THREAD_INL
+
+/*PAGE
+ *
+ * _Thread_Stop_multitasking
+ *
+ */
+
+#define _Thread_Stop_multitasking() \
+ _Context_Switch( &_Thread_Executing->Registers, &_Thread_BSP_context );
+
+/*PAGE
+ *
+ * _Thread_Is_executing
+ *
+ */
+
+#define _Thread_Is_executing( _the_thread ) \
+ ( (_the_thread) == _Thread_Executing )
+
+/*PAGE
+ *
+ * _Thread_Is_heir
+ *
+ */
+
+#define _Thread_Is_heir( _the_thread ) \
+ ( (_the_thread) == _Thread_Heir )
+
+/*PAGE
+ *
+ * _Thread_Is_executing_also_the_heir
+ *
+ */
+
+#define _Thread_Is_executing_also_the_heir() \
+ ( _Thread_Executing == _Thread_Heir )
+
+/*PAGE
+ *
+ * _Thread_Unblock
+ *
+ */
+
+#define _Thread_Unblock( _the_thread ) \
+ _Thread_Clear_state( (_the_thread), STATES_BLOCKED );
+
+/*PAGE
+ *
+ * _Thread_Restart_self
+ *
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+#define _Thread_Restart_self() \
+ { \
+ if ( _Thread_Executing->fp_context != NULL ) \
+ _Context_Restore_fp( &_Thread_Executing->fp_context ); \
+ \
+ _CPU_Context_Restart_self( &_Thread_Executing->Registers ); \
+ }
+#else
+#define _Thread_Restart_self() \
+ { \
+ _CPU_Context_Restart_self( &_Thread_Executing->Registers ); \
+ }
+#endif
+
+/*PAGE
+ *
+ * _Thread_Calculate_heir
+ *
+ */
+
+#define _Thread_Calculate_heir() \
+ { \
+ Priority_Control highest; \
+ \
+ _Priority_Get_highest( highest ); \
+ \
+ _Thread_Heir = (Thread_Control *) _Thread_Ready_chain[ highest ].first; \
+ }
+
+/*PAGE
+ *
+ * _Thread_Is_allocated_fp
+ *
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+#define _Thread_Is_allocated_fp( _the_thread ) \
+ ( (_the_thread) == _Thread_Allocated_fp )
+#endif
+
+/*PAGE
+ *
+ * _Thread_Deallocate_fp
+ *
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+#define _Thread_Deallocate_fp() \
+ _Thread_Allocated_fp = NULL
+#endif
+
+/*PAGE
+ *
+ * _Thread_Disable_dispatch
+ *
+ */
+
+#define _Thread_Disable_dispatch() \
+ do { \
+ _Thread_Dispatch_disable_level += 1; \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ } while (0)
+
+/*PAGE
+ *
+ * _Thread_Enable_dispatch
+ *
+ */
+
+#if ( CPU_INLINE_ENABLE_DISPATCH == TRUE )
+#define _Thread_Enable_dispatch() \
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ if ( (--_Thread_Dispatch_disable_level) == 0 ) \
+ _Thread_Dispatch(); \
+ } while (0)
+#endif
+
+#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE )
+void _Thread_Enable_dispatch( void );
+#endif
+
+/*PAGE
+ *
+ * _Thread_Unnest_dispatch
+ *
+ */
+
+#define _Thread_Unnest_dispatch() \
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _Thread_Dispatch_disable_level -= 1; \
+ } while (0)
+
+/*PAGE
+ *
+ * _Thread_Is_dispatching_enabled
+ *
+ */
+
+#define _Thread_Is_dispatching_enabled() \
+ ( _Thread_Dispatch_disable_level == 0 )
+
+/*PAGE
+ *
+ * _Thread_Is_context_switch_necessary
+ *
+ */
+
+#define _Thread_Is_context_switch_necessary() \
+ ( _Context_Switch_necessary == TRUE )
+
+/*PAGE
+ *
+ * _Thread_Dispatch_initialization
+ *
+ */
+
+#define _Thread_Dispatch_initialization() \
+ _Thread_Dispatch_disable_level = 1
+
+/*PAGE
+ *
+ * _Thread_Is_null
+ *
+ */
+
+#define _Thread_Is_null( _the_thread ) \
+ ( (_the_thread) == NULL )
+
+/*
+ * _Thread_Is_proxy_blocking
+ *
+ */
+
+#define _Thread_Is_proxy_blocking( _code ) \
+ ( (_code) == THREAD_STATUS_PROXY_BLOCKING )
+
+/*
+ * _Thread_Internal_allocate
+ *
+ */
+
+#define _Thread_Internal_allocate() \
+ ((Thread_Control *) _Objects_Allocate( &_Thread_Internal_information ))
+
+/*
+ * _Thread_Internal_free
+ *
+ */
+
+#define _Thread_Internal_free( _the_task ) \
+ _Objects_Free( &_Thread_Internal_information, &(_the_task)->Object )
+
+/*
+ * _Thread_Get_libc_reent
+ */
+
+#define _Thread_Get_libc_reent() \
+ (_Thread_libc_reent)
+
+/*
+ * _Thread_Set_libc_reent
+ */
+
+#define _Thread_Set_libc_reent(_libc_reent) \
+ do { \
+ _Thread_libc_reent = (_libc_reent); \
+ } while (0)
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/threadmp.inl b/cpukit/score/macros/rtems/score/threadmp.inl
new file mode 100644
index 0000000000..94c261f912
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/threadmp.inl
@@ -0,0 +1,50 @@
+/* macros/threadmp.h
+ *
+ * This include file contains the bodies of all inlined routines
+ * for the multiprocessing part of thread package.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_THREADMP_INL
+#define _RTEMS_SCORE_THREADMP_INL
+
+/*PAGE
+ *
+ * _Thread_MP_Is_receive
+ *
+ */
+
+extern Thread_Control *_MPCI_Receive_server_tcb;
+#define _Thread_MP_Is_receive( _the_thread ) \
+ ( (_the_thread) == _MPCI_Receive_server_tcb)
+
+/*PAGE
+ *
+ * _Thread_MP_Free_proxy
+ *
+ */
+
+#define _Thread_MP_Free_proxy( _the_thread ) \
+{ \
+ Thread_Proxy_control *_the_proxy; \
+ \
+ _the_proxy = (Thread_Proxy_control *) (_the_thread); \
+ \
+ _Chain_Extract( &_the_proxy->Active ); \
+ \
+ _Chain_Append( \
+ &_Thread_MP_Inactive_proxies, \
+ &(_the_thread)->Object.Node \
+ ); \
+}
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/tod.inl b/cpukit/score/macros/rtems/score/tod.inl
new file mode 100644
index 0000000000..00e5a249f0
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/tod.inl
@@ -0,0 +1,48 @@
+/* tod.inl
+ *
+ * This file contains the macro implementation of the inlined routines
+ * from the Time of Day Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TOD_INL
+#define _RTEMS_SCORE_TOD_INL
+
+/*PAGE
+ *
+ * _TOD_Tickle_ticks
+ *
+ */
+
+#define _TOD_Tickle_ticks() \
+ _TOD_Current.ticks++; \
+ _Watchdog_Ticks_since_boot++
+
+/*PAGE
+ *
+ * _TOD_Deactivate
+ *
+ */
+
+#define _TOD_Deactivate() \
+ _Watchdog_Remove( &_TOD_Seconds_watchdog )
+
+/*PAGE
+ *
+ * _TOD_Activate
+ *
+ */
+
+#define _TOD_Activate( _ticks ) \
+ _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, (_ticks) )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/tqdata.inl b/cpukit/score/macros/rtems/score/tqdata.inl
new file mode 100644
index 0000000000..8ea7725839
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/tqdata.inl
@@ -0,0 +1,49 @@
+/* tqdata.inl
+ *
+ * This file contains the macro implementation of the inlined
+ * routines needed to support the Thread Queue Data.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_TQDATA_INL
+#define _RTEMS_SCORE_TQDATA_INL
+
+/*PAGE
+ *
+ * _Thread_queue_Header_number
+ *
+ */
+
+#define _Thread_queue_Header_number( _the_priority ) \
+ ((_the_priority) / TASK_QUEUE_DATA_PRIORITIES_PER_HEADER)
+
+/*PAGE
+ *
+ * _Thread_queue_Is_reverse_search
+ *
+ */
+
+#define _Thread_queue_Is_reverse_search( _the_priority ) \
+ ( (_the_priority) & TASK_QUEUE_DATA_REVERSE_SEARCH_MASK )
+
+/*PAGE
+ *
+ * _Thread_queue_Enter_critical_section
+ *
+ */
+
+#define _Thread_queue_Enter_critical_section( _the_thread_queue ) \
+ do { \
+ (_the_thread_queue)->sync_state = THREAD_QUEUE_NOTHING_HAPPENED; \
+ } while ( 0 )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/userext.inl b/cpukit/score/macros/rtems/score/userext.inl
new file mode 100644
index 0000000000..b18e212e3e
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/userext.inl
@@ -0,0 +1,133 @@
+/* userext.inl
+ *
+ * This file contains the macro implementation of the inlined routines
+ * from the User Extension Handler
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_USEREXT_INL
+#define _RTEMS_SCORE_USEREXT_INL
+
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _User_extensions_Add_set
+ *
+ * NOTE: Must be before _User_extensions_Handler_initialization to
+ * ensure proper inlining.
+ */
+
+#define _User_extensions_Add_set( _the_extension, _extension_table ) \
+ do { \
+ (_the_extension)->Callouts = *(_extension_table); \
+ \
+ _Chain_Append( &_User_extensions_List, &(_the_extension)->Node ); \
+ \
+ if ( (_the_extension)->Callouts.thread_switch != NULL ) { \
+ (_the_extension)->Switch.thread_switch = \
+ (_the_extension)->Callouts.thread_switch; \
+ _Chain_Append( \
+ &_User_extensions_Switches_list, \
+ &(_the_extension)->Switch.Node \
+ ); \
+ } \
+ } while ( 0 )
+
+
+/*PAGE
+ *
+ * _User_extensions_Handler_initialization
+ *
+ */
+
+#define _User_extensions_Handler_initialization( \
+ _number_of_extensions, _initial_extensions \
+) \
+ { \
+ User_extensions_Control *extension; \
+ uint32_t i; \
+ \
+ _Chain_Initialize_empty( &_User_extensions_List ); \
+ _Chain_Initialize_empty( &_User_extensions_Switches_list ); \
+ \
+ if ( (_initial_extensions) ) { \
+ extension = (User_extensions_Control *) \
+ _Workspace_Allocate_or_fatal_error( \
+ sizeof(User_extensions_Control) * _number_of_extensions ); \
+ \
+ memset ( \
+ extension, \
+ 0, \
+ _number_of_extensions * sizeof( User_extensions_Control ) \
+ ); \
+ \
+ for ( i = 0 ; i < _number_of_extensions ; i++ ) { \
+ _User_extensions_Add_set (extension, &_initial_extensions[i]); \
+ extension++; \
+ } \
+ } \
+ }
+
+/*PAGE
+ *
+ * _User_extensions_Add_API_set
+ */
+
+#define _User_extensions_Add_API_set( _the_extension ) \
+ do { \
+ _Chain_Append( &_User_extensions_List, &(_the_extension)->Node ); \
+ \
+ if ( (_the_extension)->Callouts.thread_switch != NULL ) { \
+ (_the_extension)->Switch.thread_switch = \
+ (_the_extension)->Callouts.thread_switch; \
+ _Chain_Append( \
+ &_User_extensions_Switches_list, &(_the_extension)->Switch.Node ); \
+ } \
+ } while ( 0 )
+
+/*PAGE
+ *
+ * _User_extensions_Remove_set
+ */
+
+#define _User_extensions_Remove_set( _the_extension ) \
+ do { \
+ _Chain_Extract( &(_the_extension)->Node ); \
+ \
+ if ( (_the_extension)->Callouts.thread_switch != NULL ) { \
+ _Chain_Extract( &(_the_extension)->Node ); \
+ } \
+ } while (0)
+
+/*PAGE
+ *
+ * _User_extensions_Thread_switch
+ *
+ */
+
+#define _User_extensions_Thread_switch( _executing, _heir ) \
+ do { \
+ Chain_Node *the_node; \
+ User_extensions_Switch_control *the_extension_switch; \
+ \
+ for ( the_node = _User_extensions_Switches_list.first ; \
+ !_Chain_Is_tail( &_User_extensions_Switches_list, the_node ) ; \
+ the_node = the_node->next ) { \
+ \
+ the_extension_switch = (User_extensions_Switch_control *) the_node; \
+ \
+ (*the_extension_switch->thread_switch)( _executing, _heir ); \
+ } \
+ } while (0)
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/watchdog.inl b/cpukit/score/macros/rtems/score/watchdog.inl
new file mode 100644
index 0000000000..ca02774781
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/watchdog.inl
@@ -0,0 +1,171 @@
+/* watchdog.inl
+ *
+ * This file contains the macro implementation of all inlined routines
+ * in the Watchdog Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_WATCHDOG_INL
+#define _RTEMS_SCORE_WATCHDOG_INL
+
+#include <rtems/score/object.h>
+
+/*PAGE
+ *
+ * _Watchdog_Initialize
+ *
+ */
+
+#define _Watchdog_Initialize( _the_watchdog, _routine, _id, _user_data ) \
+ { \
+ (_the_watchdog)->state = WATCHDOG_INACTIVE; \
+ (_the_watchdog)->routine = (_routine); \
+ (_the_watchdog)->id = (_id); \
+ (_the_watchdog)->user_data = (_user_data); \
+ }
+
+/*PAGE
+ *
+ * _Watchdog_Is_active
+ *
+ */
+
+#define _Watchdog_Is_active( _the_watchdog ) \
+ ( (_the_watchdog)->state == WATCHDOG_ACTIVE )
+
+/*PAGE
+ *
+ * _Watchdog_Activate
+ *
+ */
+
+#define _Watchdog_Activate( _the_watchdog ) \
+ (_the_watchdog)->state = WATCHDOG_ACTIVE
+
+/*PAGE
+ *
+ * _Watchdog_Deactivate
+ *
+ */
+
+#define _Watchdog_Deactivate( _the_watchdog ) \
+ (_the_watchdog)->state = WATCHDOG_REMOVE_IT
+
+/*PAGE
+ *
+ * _Watchdog_Tickle_ticks
+ *
+ */
+
+#define _Watchdog_Tickle_ticks() \
+ _Watchdog_Tickle( &_Watchdog_Ticks_chain )
+
+/*PAGE
+ *
+ * _Watchdog_Tickle_seconds
+ *
+ */
+
+#define _Watchdog_Tickle_seconds() \
+ _Watchdog_Tickle( &_Watchdog_Seconds_chain )
+
+/*PAGE
+ *
+ * _Watchdog_Insert_ticks
+ *
+ */
+
+#define _Watchdog_Insert_ticks( _the_watchdog, _units ) \
+ do { \
+ (_the_watchdog)->initial = (_units); \
+ _Watchdog_Insert( &_Watchdog_Ticks_chain, (_the_watchdog) ); \
+ } while ( 0 )
+
+/*PAGE
+ *
+ * _Watchdog_Insert_seconds
+ *
+ */
+
+#define _Watchdog_Insert_seconds( _the_watchdog, _units ) \
+ do { \
+ (_the_watchdog)->initial = (_units); \
+ _Watchdog_Insert( &_Watchdog_Seconds_chain, (_the_watchdog) ); \
+ } while ( 0 )
+
+/*PAGE
+ *
+ * _Watchdog_Adjust_seconds
+ *
+ */
+
+#define _Watchdog_Adjust_seconds( _direction, _units ) \
+ _Watchdog_Adjust( &_Watchdog_Seconds_chain, (_direction), (_units) )
+
+/*PAGE
+ *
+ * _Watchdog_Adjust_ticks
+ *
+ */
+
+#define _Watchdog_Adjust_ticks( _direction, _units ) \
+ _Watchdog_Adjust( &_Watchdog_Ticks_chain, (_direction), (_units) )
+
+/*PAGE
+ *
+ * _Watchdog_Reset
+ *
+ */
+
+#define _Watchdog_Reset( _the_watchdog ) \
+ { \
+ (void) _Watchdog_Remove( (_the_watchdog) ); \
+ _Watchdog_Insert( &_Watchdog_Ticks_chain, (_the_watchdog) ); \
+ }
+
+/*PAGE
+ *
+ * _Watchdog_Next
+ *
+ */
+
+#define _Watchdog_Next( _watchdog ) \
+ ((Watchdog_Control *) (_watchdog)->Node.next)
+
+/*PAGE
+ *
+ * _Watchdog_Previous
+ *
+ */
+
+#define _Watchdog_Previous( _watchdog ) \
+ ((Watchdog_Control *) (_watchdog)->Node.previous)
+
+/*PAGE
+ *
+ * _Watchdog_First
+ *
+ */
+
+#define _Watchdog_First( _header ) \
+ ((Watchdog_Control *) (_header)->first)
+
+/*PAGE
+ *
+ * _Watchdog_Last
+ *
+ */
+
+#define _Watchdog_Last( _header ) \
+ ((Watchdog_Control *) (_header)->last)
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/wkspace.inl b/cpukit/score/macros/rtems/score/wkspace.inl
new file mode 100644
index 0000000000..27a20e68e8
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/wkspace.inl
@@ -0,0 +1,38 @@
+/* wkspace.inl
+ *
+ * This file contains the macro implementation of the inlined routines
+ * from the RAM Workspace Handler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_WKSPACE_INL
+#define _RTEMS_SCORE_WKSPACE_INL
+
+/*PAGE
+ *
+ * _Workspace_Allocate
+ *
+ */
+
+#define _Workspace_Allocate( _size ) \
+ _Heap_Allocate( &_Workspace_Area, (_size) )
+
+/*PAGE
+ *
+ * _Workspace_Free
+ *
+ */
+
+#define _Workspace_Free( _block ) \
+ _Heap_Free( &_Workspace_Area, (_block) )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/mainpage.h b/cpukit/score/mainpage.h
new file mode 100644
index 0000000000..9bd4051c5d
--- /dev/null
+++ b/cpukit/score/mainpage.h
@@ -0,0 +1,5 @@
+/**
+ * @mainpage
+
+This is the RTEMS SuperCore documentation.
+*/
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
new file mode 100644
index 0000000000..81ed119404
--- /dev/null
+++ b/cpukit/score/preinstall.am
@@ -0,0 +1,331 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES += $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/debug.h: include/rtems/debug.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/debug.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/debug.h
+
+$(PROJECT_INCLUDE)/rtems/system.h: include/rtems/system.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/system.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/system.h
+
+$(PROJECT_INCLUDE)/rtems/seterr.h: include/rtems/seterr.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/seterr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/seterr.h
+
+$(PROJECT_INCLUDE)/rtems/score/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems/score
+ @: > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/score/address.h: include/rtems/score/address.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/address.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/address.h
+
+$(PROJECT_INCLUDE)/rtems/score/apiext.h: include/rtems/score/apiext.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/apiext.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/apiext.h
+
+$(PROJECT_INCLUDE)/rtems/score/apimutex.h: include/rtems/score/apimutex.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/apimutex.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/apimutex.h
+
+$(PROJECT_INCLUDE)/rtems/score/bitfield.h: include/rtems/score/bitfield.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/bitfield.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/bitfield.h
+
+$(PROJECT_INCLUDE)/rtems/score/chain.h: include/rtems/score/chain.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/chain.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/chain.h
+
+$(PROJECT_INCLUDE)/rtems/score/context.h: include/rtems/score/context.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/context.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/context.h
+
+$(PROJECT_INCLUDE)/rtems/score/copyrt.h: include/rtems/score/copyrt.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/copyrt.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/copyrt.h
+
+$(PROJECT_INCLUDE)/rtems/score/coremsg.h: include/rtems/score/coremsg.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coremsg.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coremsg.h
+
+$(PROJECT_INCLUDE)/rtems/score/coremutex.h: include/rtems/score/coremutex.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coremutex.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coremutex.h
+
+$(PROJECT_INCLUDE)/rtems/score/coresem.h: include/rtems/score/coresem.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coresem.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coresem.h
+
+$(PROJECT_INCLUDE)/rtems/score/heap.h: include/rtems/score/heap.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/heap.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/heap.h
+
+$(PROJECT_INCLUDE)/rtems/score/interr.h: include/rtems/score/interr.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/interr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/interr.h
+
+$(PROJECT_INCLUDE)/rtems/score/isr.h: include/rtems/score/isr.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/isr.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/isr.h
+
+$(PROJECT_INCLUDE)/rtems/score/object.h: include/rtems/score/object.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/object.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/object.h
+
+$(PROJECT_INCLUDE)/rtems/score/priority.h: include/rtems/score/priority.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/priority.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/priority.h
+
+$(PROJECT_INCLUDE)/rtems/score/stack.h: include/rtems/score/stack.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/stack.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/stack.h
+
+$(PROJECT_INCLUDE)/rtems/score/states.h: include/rtems/score/states.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/states.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/states.h
+
+$(PROJECT_INCLUDE)/rtems/score/sysstate.h: include/rtems/score/sysstate.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/sysstate.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/sysstate.h
+
+$(PROJECT_INCLUDE)/rtems/score/thread.h: include/rtems/score/thread.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/thread.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/thread.h
+
+$(PROJECT_INCLUDE)/rtems/score/threadq.h: include/rtems/score/threadq.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/threadq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/threadq.h
+
+$(PROJECT_INCLUDE)/rtems/score/tod.h: include/rtems/score/tod.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/tod.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/tod.h
+
+$(PROJECT_INCLUDE)/rtems/score/tqdata.h: include/rtems/score/tqdata.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/tqdata.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/tqdata.h
+
+$(PROJECT_INCLUDE)/rtems/score/userext.h: include/rtems/score/userext.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/userext.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/userext.h
+
+$(PROJECT_INCLUDE)/rtems/score/watchdog.h: include/rtems/score/watchdog.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/watchdog.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/watchdog.h
+
+$(PROJECT_INCLUDE)/rtems/score/wkspace.h: include/rtems/score/wkspace.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/wkspace.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/wkspace.h
+
+$(PROJECT_INCLUDE)/rtems/score/cpuopts.h: include/rtems/score/cpuopts.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpuopts.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpuopts.h
+
+if HAS_MP
+$(PROJECT_INCLUDE)/rtems/score/mpci.h: include/rtems/score/mpci.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/mpci.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/mpci.h
+
+$(PROJECT_INCLUDE)/rtems/score/mppkt.h: include/rtems/score/mppkt.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/mppkt.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/mppkt.h
+
+$(PROJECT_INCLUDE)/rtems/score/objectmp.h: include/rtems/score/objectmp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/objectmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/objectmp.h
+
+$(PROJECT_INCLUDE)/rtems/score/threadmp.h: include/rtems/score/threadmp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/threadmp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/threadmp.h
+endif
+if INLINE
+$(PROJECT_INCLUDE)/rtems/score/address.inl: inline/rtems/score/address.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/address.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/address.inl
+
+$(PROJECT_INCLUDE)/rtems/score/chain.inl: inline/rtems/score/chain.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/chain.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/chain.inl
+
+$(PROJECT_INCLUDE)/rtems/score/coremsg.inl: inline/rtems/score/coremsg.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coremsg.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coremsg.inl
+
+$(PROJECT_INCLUDE)/rtems/score/coremutex.inl: inline/rtems/score/coremutex.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coremutex.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coremutex.inl
+
+$(PROJECT_INCLUDE)/rtems/score/coresem.inl: inline/rtems/score/coresem.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coresem.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coresem.inl
+
+$(PROJECT_INCLUDE)/rtems/score/heap.inl: inline/rtems/score/heap.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/heap.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/heap.inl
+
+$(PROJECT_INCLUDE)/rtems/score/isr.inl: inline/rtems/score/isr.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/isr.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/isr.inl
+
+$(PROJECT_INCLUDE)/rtems/score/object.inl: inline/rtems/score/object.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/object.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/object.inl
+
+$(PROJECT_INCLUDE)/rtems/score/priority.inl: inline/rtems/score/priority.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/priority.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/priority.inl
+
+$(PROJECT_INCLUDE)/rtems/score/stack.inl: inline/rtems/score/stack.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/stack.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/stack.inl
+
+$(PROJECT_INCLUDE)/rtems/score/states.inl: inline/rtems/score/states.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/states.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/states.inl
+
+$(PROJECT_INCLUDE)/rtems/score/sysstate.inl: inline/rtems/score/sysstate.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/sysstate.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/sysstate.inl
+
+$(PROJECT_INCLUDE)/rtems/score/thread.inl: inline/rtems/score/thread.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/thread.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/thread.inl
+
+$(PROJECT_INCLUDE)/rtems/score/tod.inl: inline/rtems/score/tod.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/tod.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/tod.inl
+
+$(PROJECT_INCLUDE)/rtems/score/tqdata.inl: inline/rtems/score/tqdata.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/tqdata.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/tqdata.inl
+
+$(PROJECT_INCLUDE)/rtems/score/userext.inl: inline/rtems/score/userext.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/userext.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/userext.inl
+
+$(PROJECT_INCLUDE)/rtems/score/watchdog.inl: inline/rtems/score/watchdog.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/watchdog.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/watchdog.inl
+
+$(PROJECT_INCLUDE)/rtems/score/wkspace.inl: inline/rtems/score/wkspace.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/wkspace.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/wkspace.inl
+
+if HAS_MP
+$(PROJECT_INCLUDE)/rtems/score/mppkt.inl: inline/rtems/score/mppkt.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/mppkt.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/mppkt.inl
+
+$(PROJECT_INCLUDE)/rtems/score/objectmp.inl: inline/rtems/score/objectmp.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/objectmp.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/objectmp.inl
+
+$(PROJECT_INCLUDE)/rtems/score/threadmp.inl: inline/rtems/score/threadmp.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/threadmp.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/threadmp.inl
+endif
+else
+$(PROJECT_INCLUDE)/rtems/score/address.inl: macros/rtems/score/address.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/address.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/address.inl
+
+$(PROJECT_INCLUDE)/rtems/score/chain.inl: macros/rtems/score/chain.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/chain.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/chain.inl
+
+$(PROJECT_INCLUDE)/rtems/score/coremsg.inl: macros/rtems/score/coremsg.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coremsg.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coremsg.inl
+
+$(PROJECT_INCLUDE)/rtems/score/coremutex.inl: macros/rtems/score/coremutex.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coremutex.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coremutex.inl
+
+$(PROJECT_INCLUDE)/rtems/score/coresem.inl: macros/rtems/score/coresem.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coresem.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coresem.inl
+
+$(PROJECT_INCLUDE)/rtems/score/heap.inl: macros/rtems/score/heap.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/heap.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/heap.inl
+
+$(PROJECT_INCLUDE)/rtems/score/isr.inl: macros/rtems/score/isr.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/isr.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/isr.inl
+
+$(PROJECT_INCLUDE)/rtems/score/object.inl: macros/rtems/score/object.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/object.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/object.inl
+
+$(PROJECT_INCLUDE)/rtems/score/priority.inl: macros/rtems/score/priority.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/priority.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/priority.inl
+
+$(PROJECT_INCLUDE)/rtems/score/stack.inl: macros/rtems/score/stack.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/stack.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/stack.inl
+
+$(PROJECT_INCLUDE)/rtems/score/states.inl: macros/rtems/score/states.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/states.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/states.inl
+
+$(PROJECT_INCLUDE)/rtems/score/sysstate.inl: macros/rtems/score/sysstate.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/sysstate.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/sysstate.inl
+
+$(PROJECT_INCLUDE)/rtems/score/thread.inl: macros/rtems/score/thread.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/thread.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/thread.inl
+
+$(PROJECT_INCLUDE)/rtems/score/tod.inl: macros/rtems/score/tod.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/tod.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/tod.inl
+
+$(PROJECT_INCLUDE)/rtems/score/tqdata.inl: macros/rtems/score/tqdata.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/tqdata.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/tqdata.inl
+
+$(PROJECT_INCLUDE)/rtems/score/userext.inl: macros/rtems/score/userext.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/userext.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/userext.inl
+
+$(PROJECT_INCLUDE)/rtems/score/watchdog.inl: macros/rtems/score/watchdog.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/watchdog.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/watchdog.inl
+
+$(PROJECT_INCLUDE)/rtems/score/wkspace.inl: macros/rtems/score/wkspace.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/wkspace.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/wkspace.inl
+
+if HAS_MP
+$(PROJECT_INCLUDE)/rtems/score/mppkt.inl: macros/rtems/score/mppkt.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/mppkt.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/mppkt.inl
+
+$(PROJECT_INCLUDE)/rtems/score/objectmp.inl: macros/rtems/score/objectmp.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/objectmp.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/objectmp.inl
+
+$(PROJECT_INCLUDE)/rtems/score/threadmp.inl: macros/rtems/score/threadmp.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/threadmp.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/threadmp.inl
+endif
+endif
diff --git a/cpukit/score/src/Unlimited.txt b/cpukit/score/src/Unlimited.txt
new file mode 100644
index 0000000000..be777d338a
--- /dev/null
+++ b/cpukit/score/src/Unlimited.txt
@@ -0,0 +1,387 @@
+#
+# $Id$
+#
+
+This document explains how the unlimited objects support works. This was
+written by Chris Johns <ccj@acm.org> of Objective Design Systems as a
+design document. This was submitted as part of the patch which added
+this capability.
+
+Unlimited Local Node Objects
+============================
+
+1. Why ?
+
+This patch changes the way RTEMS allocates, frees, and manages the
+'Objects_Control' structure.
+
+The 'Objects_Control' structure is at the root of all objects in
+RTEMS. The RTEMS and POSIX API allows users to create tasks, message
+queues, semaphores and other resources. These are all a type of
+Object. The POSIX API allow similar operations. These also map to
+Objects.
+
+Currently the number of objects that can be created is a static value
+loaded into the Configuration table before starting the kernel. The
+application cannot exceed these limits. Various means are used to tune
+this value. During development the value is usually set large. This
+saves having to change it everytime a developer adds a new
+resource. With a large team of developers the configuration table file
+can cycle through a large number of revisions. The wasted memory is
+only recovered when memory runs short. The issue of the configuration
+table parameters become more important the less memory you have.
+
+The Configuration table requires a calculation to occur at compile
+time to set the size of the Workspace. The calculation is an
+estimate. You need to specify an overhead value for memory that can
+not be calculated. An example of memory that cannot be calculated is
+stack sizes. This issue is not directly related to allowing unlimited
+objects how-ever the need to calculate the memory usage for a system
+in this manner is prone to error.
+
+I would like to see download support added to RTEMS. The kernel
+configuration being set at boot time means a download application can
+be limited. This can defeat one of the purposes of using downloaded
+code, no need to change ROMs. In a system I worked on the cost to
+change ROMS in a complete system was high and could take a week. This
+change is the first phase of supporting downloaded applications.
+
+1.1 How do Objects work ?
+
+All applications interact with the super core (c/src/exec/score) via
+an API. The central structure used in the super core is the
+`object'. Two application interfaces exist. They are RTEMS and
+POSIX. Both map to the super core using objects.
+
+An object in RTEMS is a resource which the user (through the API)
+creates. The different types of objects are referred to as classes of
+objects. An object is referenced by an id. This is of type `rtems_id'
+and is a 32bit unsigned integer. The id is unique for each object no
+matter what class.
+
+Objects are anchored by the `_Object_Information' structure. There is
+one per type or class of object. A global table of pointers to each
+information structure for a class of objects is held in
+`Objects_Information_table'.
+
+Objects consist of 6 main structures. The `_Object_Information' is the
+root structure. It contains pointers to the `local_table',
+`name_table', `global_table', the Inactive chain, and the object
+memory. It also contains the various variables which describe the
+object. We are only concerned with the `local_table', `name_table',
+Inactive chain, and the object memory to support unlimited objects.
+
+The `local_table' holds the pointers to open objects. A `local_table
+entry which is null is free and the object will be sitting on the
+Inactive chain. The index into the table is based on part of the
+id. Given an id the you can find the index into the `local_table', and
+therefore the object. The `local_table' has the entries for the
+indexes below the minimum_id's index. The minimum_id is always set to
+1 (the change allows another value to be selected if require). The
+index of 0 is reserved and never used. This allows any actions using
+an id of zero to fail or map to a special case.
+
+The `name_table' holds the names of the objects. Each entry in this
+table is the maximum size the name of the object can be. The size of
+names is not constrained by the object code (but is by the MP object
+code, and the API and should be fixed).
+
+The `global_table' and code that uses it has not changed. I did not
+look at the this code, and I am not farmilar with it.
+
+The Inactive chain stores objects which are free or not
+allocated. This design saves searching for a free object when
+allocating therefore providing a deterministic allocation scheme. When
+the chain is empty a null is returned.
+
+The change documented below basically extends the `local_table' and
+`name_table' structures at run-time. The memory used be these table
+is not large compared to the memory for the objects, and so are never
+reduced in size once extended. The object's memory grows and shrinks
+depending of the user's usage.
+
+Currently, the user specifies the total number of objects in the
+Configuration table. The change alters the function of the values in
+the Configuration table. A flag can be masked on to the value which
+selects the extending mode. If the user does not set the flag the
+object code operates with an object ceiling. A small performance
+overhead will be incurred as the allocate and free routines are now
+not inlined and a check of the auto_extend flag is made. The remaining
+value field of the Configuration table entry is total number of
+objects that can be allocated when not in unlimited mode.
+
+If the user masks the flag on to a value on the Configuration table
+auto-exdending mode is selected for that class of object. The value
+becomes the allocation unit size. If there are no free objects the
+object's tables are extended by the allocation unit number of
+objects. The object table is shrunk when the user frees objects. The
+table must have one free allocation block, and at least half the
+allocation size of another block before the object memory of the free
+allocation block is returned to the heap. This stops threshold
+thrashing when objects around the allocation unit size and created and
+destroyed.
+
+At least one allocation block size of objects is created and never
+destroyed.
+
+The change to support unlimited objects has extended the object
+information structure.
+
+The flag, `auto_extend' controls if the object can be automatically
+extended. The user masks the flag RTEMS_UNLIMITED_FLAGS onto the
+Configuration table number to select the auto-extend mode. This is
+passed to the `_Objects_Initialize_information' function in the
+parameter maximum. The flag is tested for and the auto_extend flag
+updated to reflect the state of the flag before being stipped from the
+maximum.
+
+The `allocation_size' is set to the parameter maxium in the function
+`_Objects_Initialize_information' if `auto_extend' is true. Making the
+allocation size small causes the memory to be allocated and freed more
+often. This only effects the performance times for creating a resource
+such as a task. It does how-ever give you fine grain memory
+control. If the performance of creating resources is not a problem
+make the size small.
+
+The size of the object is required to be stored. It is used when
+extending the object information.
+
+A count of the object on the Inactive list is maintained. This is used
+during freeing objects. If the count is above 1.5 times the
+`allocation_size' an attempt is made to shrink the object
+informtation. Shrinking might not always succeed as a single
+allocation block might not be free. Random freeing of objects can
+result in some fragmentation. Any further allocations will use the
+free objects before extending the object's information tables.
+
+A table of inactive objects per block is maintained. This table, like
+the `local_table' and `name_table' grows as more blocks are
+allocated. A check is made of a blocks inactive count when an object
+which is part of that block is freed. If the total inactive count
+exceeds 1.5 times the allocation size, and the block's inactive count
+is the allocation_size, the objects data block is returnd to the
+workspace heap.
+
+The `objects_blocks' is a table of pointers. The object_block's pointers
+point to the object's data block. The object's data block is a single
+allocation of the name space and object space. This was two separate
+allocations but is now one. The objects_block's table is use to
+determine if a block is allocated, and the address of the memory block
+to be returned to the workspace heap when the object informtation
+space is shrunk.
+
+2.0 Detail Of the Auto-Extend Patch to rtems-4.0.0, Snapshot 19990302
+
+o Configuration table support.
+
+ Added a flag OBJECTS_UNLIMITED_OBJECTS to score/headers/object.h
+ header file. This is referenced in the file sapi/headers/config.h to
+ create the flag RTEMS_UNLIMITED_OBJECTS. A macro is provided to take
+ a resource count and apply the flag. The macro is called
+ `rtems_resource_unlimited'. The user uses this macro when building a
+ configuration table. It can be used with the condefs.h header file.
+
+o Object Information Structure
+
+ The object information structure, Objects_Information, has been
+ extended with the follow fields :
+
+ boolean auto_extend -
+
+ When true the object's information tables can be extended untill
+ all memory is used. When false the current functionallity is
+ maintained.
+
+ uint32_t allocation_size -
+
+ When auto_extend is true, it is the value in the Configuration
+ table and is the number of objects the object's information
+ tables are extended or shrunk.
+
+ uint32_t size -
+
+ The size of the object. It is used to calculate the size of
+ memory required to be allocated when extending the table.
+
+ uint32_t inactive -
+
+ The number of elements on the Inactive chain.
+
+ uint32_t *inactive_per_block -
+
+ Pointer to a table of counts of the inactive objects from a
+ block on the Inactive chain. It is used to know which blocks are
+ all free and therefore can be returned to the heap.
+
+ void **object_blocks -
+
+ Pointer to a table of pointers to the object data. The table
+ holds the pointer used to return a block to the heap when
+ shrinking the object's information tables.
+
+o Changes to Existing Object Functions
+
+ Two functions prototypes are added. They are :
+
+ _Objects_Extend_information,
+ _Objects_Shrink_information
+ _Object_Allocate, and
+ _Object_Free
+
+ The last were inlined, how-ever now they are not as they are too
+ complex to implement as macros now.
+
+o Object Inline and Macro Changes
+
+ The functions :
+
+ _Object_Allocate, and
+ _Object_Free
+
+ are now not inlined. The function :
+
+ _Objects_Get_local_object, and
+ _Objects_Set_local_object
+
+ have been added. There was no provided interface to allow an API to
+ get/set an objects local pointer given an index. The POSIX code
+ should be updated to use this interface.
+
+ The function :
+
+ _Objects_Get_information
+
+ has been moved to be an inline function. It is used in the get
+ object call which the API uses for every object reference.
+
+o Object Initialisation
+
+ The function _Objects_Initialize_information has been changed to
+ initialisation of the information structure's fields then call the
+ new function _Objects_Extend_information.
+
+ The first block of objects is always allocated and never
+ released. This means with the auto-extend flag set to true the user
+ still sees the same behaviour expected without this change. That is
+ the number objects specified in the Configuration table is the
+ number of object allocated during RTEMS initialisation. If not
+ enough memory is found during this initial extend a fatal error
+ occurs. The fatal error only occurs for this case of extending the
+ object's information tables.
+
+o Object Information Extend
+
+ The _Object_Information_Extend is a new function. It takes some of
+ the code form the old _Object_Initialize_information function. The
+ function extends an object's information base.
+
+ Extending the first time is a special case. The function assumes the
+ maximum index will be less than the minimum index. This means the
+ minimum index must be greater than 0 at initialisation. The other
+ special case made is coping the tables from the old location to the
+ new location. The first block case is trapped and tables are
+ initialised instead. Workspace allocation for the first block is
+ tested for an if the first block the allocate or fatal error call is
+ made. This traps an RTEMS initialise allocation error.
+
+ The remainder of the code deals with all cases of extending the
+ object's information.
+
+ The current block count is first determined, then a scan of the
+ object_block table is made to locate a free slot. Blocks can be
+ freed in any order. The index base for the block is also determined.
+
+ If the index base is greater than the maximum index, the tables must
+ grow. To grow the tables, a new larger memory block is allocated and
+ the tables copied. The object's information structure is then
+ updated to point to the new tables. The tables are allocated in one
+ memory block from the work-space heap. The single block is then
+ broken down in the required tables.
+
+ Once the tables are copied, and the new extended parts initialised
+ the table pointers in the object's information structure are
+ updated. This is protected by masking interrupts.
+
+ The old table's memory block is returned to the heap.
+
+ The names table and object is allocated. This again is a single
+ block which is divided.
+
+ The objects are initialised onto a local Inactive chain. They are
+ then copied to the object's Inactive chain to complete the
+ initialisation.
+
+o Object Informtation Shrink
+
+ The _Object_Shrink_information function is new. It is required to
+ scan all the blocks to see which one has no objects allocated. The
+ last object freed might not belong to a block which is completely
+ free.
+
+ Once a block is located, the Inactive chain is interated down
+ looking for objects which belong to the block of object being
+ released.
+
+ Once the Inactive chain scan is complete the names table and object
+ memory is returned to the work-space heap and the table references cleared.
+
+ XXX - I am not sure if this should occur if better protection or
+ different code to provide better protection.
+
+ The information tables do not change size. Once extended they never
+ shrink.
+
+o Object Allocation
+
+ The _Objects_Allocate attempts to get an object from the Inactive
+ chain. If auto-extend mode is not enabled no further processing
+ occurs. The extra overhead for this implemetation is the function is
+ not inlined and check of a boolean occurs. It should effect the
+ timing figures.
+
+ If auto-extend is enabled, a further check is made to see if the get
+ from the Inactive chain suceeded in getting an object. If it failed
+ a call is made to extend the object's information tables.
+
+ The get from the Inactive chain is retried. The result of this is
+ returned to the user. A failure here is the users problem.
+
+o Object Free
+
+ The _Objects_Free puts the object back onto the Inactive
+ chain. Again if auto-extend mode is not enabled no further
+ processing occurs and performance overhead will low.
+
+ If auto-extend mode is enabled, a check is to see if the number of
+ Inactive objects is one and a half times the allocation size. If
+ there are that many free objects an attempt is made to shrink the
+ object's information.
+
+o Object Index and the Get Function
+
+ The existing code allocates the number of object specified in the
+ configuration table, how-ever it makes the local_table have one more
+ element. This is the slot for an id of 0. The 0 slot is always a
+ NULL providing a simple check for a 0 id for object classes.
+
+ The existing _Objects_Get code removes the minimum id, which I think
+ could only be 1 from the index, then adds one for the 0 slot.
+
+ This change removes this index adjustment code in _Objects_Get.
+
+ The extend information starts the index count when scanning for free
+ blocks at the minumun index. This means the base index for a block
+ will always be adjusted by the minimum index. The extend information
+ function only ever allocates the allocation size of
+ objects. Finially the object's local_table size is the maximum plus
+ the minumum index size. The maximum is really the maximum index.
+
+ This means the values in the object's information structure and
+ tables do not need the index adjustments which existed before.
+
+o The Test
+
+ A new sample test, unlimited is provided. It attempts to test this
+ change.
+
+
diff --git a/cpukit/score/src/apiext.c b/cpukit/score/src/apiext.c
new file mode 100644
index 0000000000..5a2c5f52c7
--- /dev/null
+++ b/cpukit/score/src/apiext.c
@@ -0,0 +1,107 @@
+/* apiext.c
+ *
+ * XXX
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+
+/*PAGE
+ *
+ * _API_extensions_Initialization
+ */
+
+void _API_extensions_Initialization( void )
+{
+ _Chain_Initialize_empty( &_API_extensions_List );
+}
+
+/*PAGE
+ *
+ * _API_extensions_Add
+ */
+
+void _API_extensions_Add(
+ API_extensions_Control *the_extension
+)
+{
+ _Chain_Append( &_API_extensions_List, &the_extension->Node );
+}
+
+/*PAGE
+ *
+ * _API_extensions_Run_predriver
+ */
+
+void _API_extensions_Run_predriver( void )
+{
+ Chain_Node *the_node;
+ API_extensions_Control *the_extension;
+
+ for ( the_node = _API_extensions_List.first ;
+ !_Chain_Is_tail( &_API_extensions_List, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_extension = (API_extensions_Control *) the_node;
+
+ if ( the_extension->predriver_hook )
+ (*the_extension->predriver_hook)();
+ }
+}
+
+/*PAGE
+ *
+ * _API_extensions_Run_postdriver
+ */
+
+void _API_extensions_Run_postdriver( void )
+{
+ Chain_Node *the_node;
+ API_extensions_Control *the_extension;
+
+ for ( the_node = _API_extensions_List.first ;
+ !_Chain_Is_tail( &_API_extensions_List, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_extension = (API_extensions_Control *) the_node;
+
+ if ( the_extension->postdriver_hook )
+ (*the_extension->postdriver_hook)();
+ }
+}
+
+/*PAGE
+ *
+ * _API_extensions_Run_postswitch
+ */
+
+void _API_extensions_Run_postswitch( void )
+{
+ Chain_Node *the_node;
+ API_extensions_Control *the_extension;
+
+ for ( the_node = _API_extensions_List.first ;
+ !_Chain_Is_tail( &_API_extensions_List, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_extension = (API_extensions_Control *) the_node;
+
+ if ( the_extension->postswitch_hook )
+ (*the_extension->postswitch_hook)( _Thread_Executing );
+ }
+}
+
+/* end of file */
diff --git a/cpukit/score/src/chain.c b/cpukit/score/src/chain.c
new file mode 100644
index 0000000000..aa0387ef53
--- /dev/null
+++ b/cpukit/score/src/chain.c
@@ -0,0 +1,205 @@
+/*
+ * Chain Handler
+ *
+ * NOTE:
+ *
+ * The order of this file is to allow proper compilation due to the
+ * order of inlining required by the compiler.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Chain_Initialize
+ *
+ * This kernel routine initializes a doubly linked chain.
+ *
+ * Input parameters:
+ * the_chain - pointer to chain header
+ * starting_address - starting address of first node
+ * number_nodes - number of nodes in chain
+ * node_size - size of node in bytes
+ *
+ * Output parameters: NONE
+ */
+
+void _Chain_Initialize(
+ Chain_Control *the_chain,
+ void *starting_address,
+ uint32_t number_nodes,
+ uint32_t node_size
+)
+{
+ uint32_t count;
+ Chain_Node *current;
+ Chain_Node *next;
+
+ count = number_nodes;
+ current = _Chain_Head( the_chain );
+ the_chain->permanent_null = NULL;
+ next = starting_address;
+ while ( count-- ) {
+ current->next = next;
+ next->previous = current;
+ current = next;
+ next = (Chain_Node *)
+ _Addresses_Add_offset( (void *) next, node_size );
+ }
+ current->next = _Chain_Tail( the_chain );
+ the_chain->last = current;
+}
+
+/*PAGE
+ *
+ * _Chain_Get_first_unprotected
+ */
+
+#ifndef RTEMS_INLINES
+Chain_Node *_Chain_Get_first_unprotected(
+ Chain_Control *the_chain
+)
+{
+ Chain_Node *return_node;
+ Chain_Node *new_first;
+
+ return_node = the_chain->first;
+ new_first = return_node->next;
+ the_chain->first = new_first;
+ new_first->previous = _Chain_Head( the_chain );
+
+ return return_node;
+}
+#endif /* RTEMS_INLINES */
+
+/*PAGE
+ *
+ * _Chain_Get
+ *
+ * This kernel routine returns a pointer to a node taken from the
+ * given chain.
+ *
+ * Input parameters:
+ * the_chain - pointer to chain header
+ *
+ * Output parameters:
+ * return_node - pointer to node in chain allocated
+ * CHAIN_END - if no nodes available
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+Chain_Node *_Chain_Get(
+ Chain_Control *the_chain
+)
+{
+ ISR_Level level;
+ Chain_Node *return_node;
+
+ return_node = NULL;
+ _ISR_Disable( level );
+ if ( !_Chain_Is_empty( the_chain ) )
+ return_node = _Chain_Get_first_unprotected( the_chain );
+ _ISR_Enable( level );
+ return return_node;
+}
+
+/*PAGE
+ *
+ * _Chain_Append
+ *
+ * This kernel routine puts a node on the end of the specified chain.
+ *
+ * Input parameters:
+ * the_chain - pointer to chain header
+ * node - address of node to put at rear of chain
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+void _Chain_Append(
+ Chain_Control *the_chain,
+ Chain_Node *node
+)
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+ _Chain_Append_unprotected( the_chain, node );
+ _ISR_Enable( level );
+}
+
+/*PAGE
+ *
+ * _Chain_Extract
+ *
+ * This kernel routine deletes the given node from a chain.
+ *
+ * Input parameters:
+ * node - pointer to node in chain to be deleted
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+void _Chain_Extract(
+ Chain_Node *node
+)
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+ _Chain_Extract_unprotected( node );
+ _ISR_Enable( level );
+}
+
+/*PAGE
+ *
+ * _Chain_Insert
+ *
+ * This kernel routine inserts a given node after a specified node
+ * a requested chain.
+ *
+ * Input parameters:
+ * after_node - pointer to node in chain to be inserted after
+ * node - pointer to node to be inserted
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+void _Chain_Insert(
+ Chain_Node *after_node,
+ Chain_Node *node
+)
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+ _Chain_Insert_unprotected( after_node, node );
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/coremsg.c b/cpukit/score/src/coremsg.c
new file mode 100644
index 0000000000..765d2d5a64
--- /dev/null
+++ b/cpukit/score/src/coremsg.c
@@ -0,0 +1,125 @@
+/*
+ * CORE Message Queue Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_message_queue_Initialize
+ *
+ * This routine initializes a newly created message queue based on the
+ * specified data.
+ *
+ * Input parameters:
+ * the_message_queue - the message queue to initialize
+ * the_class - the API specific object class
+ * the_message_queue_attributes - the message queue's attributes
+ * maximum_pending_messages - maximum message and reserved buffer count
+ * maximum_message_size - maximum size of each message
+ *
+ * Output parameters:
+ * TRUE - if the message queue is initialized
+ * FALSE - if the message queue is NOT initialized
+ */
+
+boolean _CORE_message_queue_Initialize(
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Attributes *the_message_queue_attributes,
+ uint32_t maximum_pending_messages,
+ uint32_t maximum_message_size
+)
+{
+ uint32_t message_buffering_required;
+ uint32_t allocated_message_size;
+
+ the_message_queue->maximum_pending_messages = maximum_pending_messages;
+ the_message_queue->number_of_pending_messages = 0;
+ the_message_queue->maximum_message_size = maximum_message_size;
+ _CORE_message_queue_Set_notify( the_message_queue, NULL, NULL );
+
+ /*
+ * Round size up to multiple of a pointer for chain init and
+ * check for overflow on adding overhead to each message.
+ */
+
+ allocated_message_size = maximum_message_size;
+ if (allocated_message_size & (sizeof(uint32_t) - 1)) {
+ allocated_message_size += sizeof(uint32_t);
+ allocated_message_size &= ~(sizeof(uint32_t) - 1);
+ }
+
+ if (allocated_message_size < maximum_message_size)
+ return FALSE;
+
+ /*
+ * Calculate how much total memory is required for message buffering and
+ * check for overflow on the multiplication.
+ */
+ message_buffering_required = maximum_pending_messages *
+ (allocated_message_size + sizeof(CORE_message_queue_Buffer_control));
+
+ if (message_buffering_required < allocated_message_size)
+ return FALSE;
+
+ /*
+ * Attempt to allocate the message memory
+ */
+ the_message_queue->message_buffers = (CORE_message_queue_Buffer *)
+ _Workspace_Allocate( message_buffering_required );
+
+ if (the_message_queue->message_buffers == 0)
+ return FALSE;
+
+ /*
+ * Initialize the pool of inactive messages, pending messages,
+ * and set of waiting threads.
+ */
+ _Chain_Initialize (
+ &the_message_queue->Inactive_messages,
+ the_message_queue->message_buffers,
+ maximum_pending_messages,
+ allocated_message_size + sizeof( CORE_message_queue_Buffer_control )
+ );
+
+ _Chain_Initialize_empty( &the_message_queue->Pending_messages );
+
+ _Thread_queue_Initialize(
+ &the_message_queue->Wait_queue,
+ _CORE_message_queue_Is_priority( the_message_queue_attributes ) ?
+ THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
+ STATES_WAITING_FOR_MESSAGE,
+ CORE_MESSAGE_QUEUE_STATUS_TIMEOUT
+ );
+
+ return TRUE;
+}
diff --git a/cpukit/score/src/coremsgbroadcast.c b/cpukit/score/src/coremsgbroadcast.c
new file mode 100644
index 0000000000..7bb02283a3
--- /dev/null
+++ b/cpukit/score/src/coremsgbroadcast.c
@@ -0,0 +1,115 @@
+/*
+ * CORE Message Queue Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_message_queue_Broadcast
+ *
+ * This function sends a message for every thread waiting on the queue and
+ * returns the number of threads made ready by the message.
+ *
+ * Input parameters:
+ * the_message_queue - message is submitted to this message queue
+ * buffer - pointer to message buffer
+ * size - size in bytes of message to send
+ * id - id of message queue
+ * api_message_queue_mp_support - api specific mp support callout
+ * count - area to store number of threads made ready
+ *
+ * Output parameters:
+ * count - number of threads made ready
+ * CORE_MESSAGE_QUEUE_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+CORE_message_queue_Status _CORE_message_queue_Broadcast(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ uint32_t size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
+ uint32_t *count
+)
+{
+ Thread_Control *the_thread;
+ uint32_t number_broadcasted;
+ Thread_Wait_information *waitp;
+ uint32_t constrained_size;
+
+ /*
+ * If there are pending messages, then there can't be threads
+ * waiting for us to send them a message.
+ *
+ * NOTE: This check is critical because threads can block on
+ * send and receive and this ensures that we are broadcasting
+ * the message to threads waiting to receive -- not to send.
+ */
+
+ if ( the_message_queue->number_of_pending_messages != 0 ) {
+ *count = 0;
+ return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
+ }
+
+ /*
+ * There must be no pending messages if there is a thread waiting to
+ * receive a message.
+ */
+
+ number_broadcasted = 0;
+ while ((the_thread = _Thread_queue_Dequeue(&the_message_queue->Wait_queue))) {
+ waitp = &the_thread->Wait;
+ number_broadcasted += 1;
+
+ constrained_size = size;
+ if ( size > the_message_queue->maximum_message_size )
+ constrained_size = the_message_queue->maximum_message_size;
+
+ _CORE_message_queue_Copy_buffer(
+ buffer,
+ waitp->return_argument,
+ constrained_size
+ );
+
+ *(uint32_t *)the_thread->Wait.return_argument_1 = size;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ (*api_message_queue_mp_support) ( the_thread, id );
+#endif
+
+ }
+ *count = number_broadcasted;
+ return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
+}
diff --git a/cpukit/score/src/coremsgclose.c b/cpukit/score/src/coremsgclose.c
new file mode 100644
index 0000000000..7cc25d3f7e
--- /dev/null
+++ b/cpukit/score/src/coremsgclose.c
@@ -0,0 +1,80 @@
+/*
+ * CORE Message Queue Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_message_queue_Close
+ *
+ * This function closes a message by returning all allocated space and
+ * flushing the message_queue's task wait queue.
+ *
+ * Input parameters:
+ * the_message_queue - the message_queue to be flushed
+ * remote_extract_callout - function to invoke remotely
+ * status - status to pass to thread
+ *
+ * Output parameters: NONE
+ */
+
+void _CORE_message_queue_Close(
+ CORE_message_queue_Control *the_message_queue,
+ Thread_queue_Flush_callout remote_extract_callout,
+ uint32_t status
+)
+{
+
+ /*
+ * This will flush blocked threads whether they were blocked on
+ * a send or receive.
+ */
+
+ _Thread_queue_Flush(
+ &the_message_queue->Wait_queue,
+ remote_extract_callout,
+ status
+ );
+
+ /*
+ * This removes all messages from the pending message queue. Since
+ * we just flushed all waiting threads, we don't have to worry about
+ * the flush satisfying any blocked senders as a side-effect.
+ */
+
+ if ( the_message_queue->number_of_pending_messages != 0 )
+ (void) _CORE_message_queue_Flush_support( the_message_queue );
+
+ (void) _Workspace_Free( the_message_queue->message_buffers );
+
+}
diff --git a/cpukit/score/src/coremsgflush.c b/cpukit/score/src/coremsgflush.c
new file mode 100644
index 0000000000..1f4ee1839b
--- /dev/null
+++ b/cpukit/score/src/coremsgflush.c
@@ -0,0 +1,58 @@
+/*
+ * CORE Message Queue Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_message_queue_Flush
+ *
+ * This function flushes the message_queue's pending message queue. The
+ * number of messages flushed from the queue is returned.
+ *
+ * Input parameters:
+ * the_message_queue - the message_queue to be flushed
+ *
+ * Output parameters:
+ * returns - the number of messages flushed from the queue
+ */
+
+uint32_t _CORE_message_queue_Flush(
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ if ( the_message_queue->number_of_pending_messages != 0 )
+ return _CORE_message_queue_Flush_support( the_message_queue );
+ else
+ return 0;
+}
diff --git a/cpukit/score/src/coremsgflushsupp.c b/cpukit/score/src/coremsgflushsupp.c
new file mode 100644
index 0000000000..0b16760eb1
--- /dev/null
+++ b/cpukit/score/src/coremsgflushsupp.c
@@ -0,0 +1,108 @@
+/*
+ * CORE Message Queue Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_message_queue_Flush_support
+ *
+ * This message handler routine removes all messages from a message queue
+ * and returns them to the inactive message pool. The number of messages
+ * flushed from the queue is returned
+ *
+ * Input parameters:
+ * the_message_queue - pointer to message queue
+ *
+ * Output parameters:
+ * returns - number of messages placed on inactive chain
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+uint32_t _CORE_message_queue_Flush_support(
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ ISR_Level level;
+ Chain_Node *inactive_first;
+ Chain_Node *message_queue_first;
+ Chain_Node *message_queue_last;
+ uint32_t count;
+
+ /*
+ * Currently, RTEMS supports no API that has both flush and blocking
+ * sends. Thus, this routine assumes that there are no senders
+ * blocked waiting to send messages. In the event, that an API is
+ * added that can flush a message queue when threads are blocked
+ * waiting to send, there are two basic behaviors envisioned:
+ *
+ * (1) The thread queue of pending senders is a logical extension
+ * of the pending message queue. In this case, it should be
+ * flushed using the _Thread_queue_Flush() service with a status
+ * such as CORE_MESSAGE_QUEUE_SENDER_FLUSHED (which currently does
+ * not exist). This can be implemented without changing the "big-O"
+ * of the message flushing part of the routine.
+ *
+ * (2) Only the actual messages queued should be purged. In this case,
+ * the blocked sender threads must be allowed to send their messages.
+ * In this case, the implementation will be forced to individually
+ * dequeue the senders and queue their messages. This will force
+ * this routine to have "big O(n)" where n is the number of blocked
+ * senders. If there are more messages pending than senders blocked,
+ * then the existing flush code can be used to dispose of the remaining
+ * pending messages.
+ *
+ * For now, though, we are very happy to have a small routine with
+ * fixed execution time that only deals with pending messages.
+ */
+
+ _ISR_Disable( level );
+ inactive_first = the_message_queue->Inactive_messages.first;
+ message_queue_first = the_message_queue->Pending_messages.first;
+ message_queue_last = the_message_queue->Pending_messages.last;
+
+ the_message_queue->Inactive_messages.first = message_queue_first;
+ message_queue_last->next = inactive_first;
+ inactive_first->previous = message_queue_last;
+ message_queue_first->previous =
+ _Chain_Head( &the_message_queue->Inactive_messages );
+
+ _Chain_Initialize_empty( &the_message_queue->Pending_messages );
+
+ count = the_message_queue->number_of_pending_messages;
+ the_message_queue->number_of_pending_messages = 0;
+ _ISR_Enable( level );
+ return count;
+}
diff --git a/cpukit/score/src/coremsgflushwait.c b/cpukit/score/src/coremsgflushwait.c
new file mode 100644
index 0000000000..e96ef14f0b
--- /dev/null
+++ b/cpukit/score/src/coremsgflushwait.c
@@ -0,0 +1,73 @@
+/*
+ * CORE Message Queue Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_message_queue_Flush_waiting_threads
+ *
+ * This function flushes the message_queue's task wait queue. The number
+ * of messages flushed from the queue is returned.
+ *
+ * Input parameters:
+ * the_message_queue - the message_queue to be flushed
+ *
+ * Output parameters:
+ * returns - the number of messages flushed from the queue
+ */
+
+void _CORE_message_queue_Flush_waiting_threads(
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ /* XXX this is not supported for global message queues */
+
+ /*
+ * IF there are no pending messages,
+ * THEN threads may be blocked waiting to RECEIVE a message,
+ *
+ * IF the pending message queue is full
+ * THEN threads may be blocked waiting to SEND a message
+ *
+ * But in either case, we will return "unsatisfied nowait"
+ * to indicate that the blocking condition was not satisfied
+ * and that the blocking state was canceled.
+ */
+
+ _Thread_queue_Flush(
+ &the_message_queue->Wait_queue,
+ NULL,
+ CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT
+ );
+}
diff --git a/cpukit/score/src/coremsginsert.c b/cpukit/score/src/coremsginsert.c
new file mode 100644
index 0000000000..2402755447
--- /dev/null
+++ b/cpukit/score/src/coremsginsert.c
@@ -0,0 +1,117 @@
+/*
+ * CORE Message Queue Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * COPYRIGHT (c) 1989-2005.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_message_queue_Insert_message
+ *
+ * This kernel routine inserts the specified message into the
+ * message queue. It is assumed that the message has been filled
+ * in before this routine is called.
+ *
+ * Input parameters:
+ * the_message_queue - pointer to message queue
+ * the_message - message to insert
+ * priority - insert indication
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * insert
+ */
+
+void _CORE_message_queue_Insert_message(
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message,
+ CORE_message_queue_Submit_types submit_type
+)
+{
+ ISR_Level level;
+ boolean notify = FALSE;
+
+ the_message->priority = submit_type;
+
+ switch ( submit_type ) {
+ case CORE_MESSAGE_QUEUE_SEND_REQUEST:
+ _ISR_Disable( level );
+ if ( the_message_queue->number_of_pending_messages++ == 0 )
+ notify = TRUE;
+ _CORE_message_queue_Append_unprotected(the_message_queue, the_message);
+ _ISR_Enable( level );
+ break;
+ case CORE_MESSAGE_QUEUE_URGENT_REQUEST:
+ _ISR_Disable( level );
+ if ( the_message_queue->number_of_pending_messages++ == 0 )
+ notify = TRUE;
+ _CORE_message_queue_Prepend_unprotected(the_message_queue, the_message);
+ _ISR_Enable( level );
+ break;
+ default:
+ {
+ CORE_message_queue_Buffer_control *this_message;
+ Chain_Node *the_node;
+ Chain_Control *the_header;
+
+ the_header = &the_message_queue->Pending_messages;
+ the_node = the_header->first;
+ while ( !_Chain_Is_tail( the_header, the_node ) ) {
+
+ this_message = (CORE_message_queue_Buffer_control *) the_node;
+
+ if ( this_message->priority <= the_message->priority ) {
+ the_node = the_node->next;
+ continue;
+ }
+
+ break;
+ }
+ _ISR_Disable( level );
+ if ( the_message_queue->number_of_pending_messages++ == 0 )
+ notify = TRUE;
+ _Chain_Insert_unprotected( the_node->previous, &the_message->Node );
+ _ISR_Enable( level );
+ }
+ break;
+ }
+
+ /*
+ * According to POSIX, does this happen before or after the message
+ * is actually enqueued. It is logical to think afterwards, because
+ * the message is actually in the queue at this point.
+ */
+
+ if ( notify && the_message_queue->notify_handler )
+ (*the_message_queue->notify_handler)( the_message_queue->notify_argument );
+}
diff --git a/cpukit/score/src/coremsgseize.c b/cpukit/score/src/coremsgseize.c
new file mode 100644
index 0000000000..c550df5b72
--- /dev/null
+++ b/cpukit/score/src/coremsgseize.c
@@ -0,0 +1,140 @@
+/*
+ * CORE Message Queue Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_message_queue_Seize
+ *
+ * This kernel routine dequeues a message, copies the message buffer to
+ * a given destination buffer, and frees the message buffer to the
+ * inactive message pool. The thread will be blocked if wait is TRUE,
+ * otherwise an error will be given to the thread if no messages are available.
+ *
+ * Input parameters:
+ * the_message_queue - pointer to message queue
+ * id - id of object we are waitig on
+ * buffer - pointer to message buffer to be filled
+ * size - pointer to the size of buffer to be filled
+ * wait - TRUE if wait is allowed, FALSE otherwise
+ * timeout - time to wait for a message
+ *
+ * Output parameters: NONE
+ *
+ * NOTE: Dependent on BUFFER_LENGTH
+ *
+ * INTERRUPT LATENCY:
+ * available
+ * wait
+ */
+
+void _CORE_message_queue_Seize(
+ CORE_message_queue_Control *the_message_queue,
+ Objects_Id id,
+ void *buffer,
+ uint32_t *size,
+ boolean wait,
+ Watchdog_Interval timeout
+)
+{
+ ISR_Level level;
+ CORE_message_queue_Buffer_control *the_message;
+ Thread_Control *executing;
+ Thread_Control *the_thread;
+
+ executing = _Thread_Executing;
+ executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
+ _ISR_Disable( level );
+ if ( the_message_queue->number_of_pending_messages != 0 ) {
+ the_message_queue->number_of_pending_messages -= 1;
+
+ the_message = _CORE_message_queue_Get_pending_message( the_message_queue );
+ _ISR_Enable( level );
+
+ *size = the_message->Contents.size;
+ _Thread_Executing->Wait.count = the_message->priority;
+ _CORE_message_queue_Copy_buffer(the_message->Contents.buffer,buffer,*size);
+
+ /*
+ * There could be a thread waiting to send a message. If there
+ * is not, then we can go ahead and free the buffer.
+ *
+ * NOTE: If we note that the queue was not full before this receive,
+ * then we can avoid this dequeue.
+ */
+
+ the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
+ if ( !the_thread ) {
+ _CORE_message_queue_Free_message_buffer( the_message_queue, the_message );
+ return;
+ }
+
+ /*
+ * There was a thread waiting to send a message. This code
+ * puts the messages in the message queue on behalf of the
+ * waiting task.
+ */
+
+ the_message->priority = the_thread->Wait.count;
+ the_message->Contents.size = (uint32_t )the_thread->Wait.return_argument_1;
+ _CORE_message_queue_Copy_buffer(
+ the_thread->Wait.return_argument,
+ the_message->Contents.buffer,
+ the_message->Contents.size
+ );
+
+ _CORE_message_queue_Insert_message(
+ the_message_queue,
+ the_message,
+ the_message->priority
+ );
+ return;
+ }
+
+ if ( !wait ) {
+ _ISR_Enable( level );
+ executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT;
+ return;
+ }
+
+ _Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
+ executing->Wait.queue = &the_message_queue->Wait_queue;
+ executing->Wait.id = id;
+ executing->Wait.return_argument = buffer;
+ executing->Wait.return_argument_1 = (void *)size;
+ /* Wait.count will be filled in with the message priority */
+ _ISR_Enable( level );
+
+ _Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
+}
diff --git a/cpukit/score/src/coremsgsubmit.c b/cpukit/score/src/coremsgsubmit.c
new file mode 100644
index 0000000000..020c68533d
--- /dev/null
+++ b/cpukit/score/src/coremsgsubmit.c
@@ -0,0 +1,179 @@
+/*
+ * CORE Message Queue Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coremsg.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_message_queue_Submit
+ *
+ * This routine implements the send and urgent message functions. It
+ * processes a message that is to be submitted to the designated
+ * message queue. The message will either be processed as a
+ * send message which it will be inserted at the rear of the queue
+ * or it will be processed as an urgent message which will be inserted
+ * at the front of the queue.
+ *
+ * Input parameters:
+ * the_message_queue - message is submitted to this message queue
+ * buffer - pointer to message buffer
+ * size - size in bytes of message to send
+ * id - id of message queue
+ * api_message_queue_mp_support - api specific mp support callout
+ * submit_type - send or urgent message
+ *
+ * Output parameters:
+ * CORE_MESSAGE_QUEUE_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+CORE_message_queue_Status _CORE_message_queue_Submit(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ uint32_t size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
+ CORE_message_queue_Submit_types submit_type,
+ boolean wait,
+ Watchdog_Interval timeout
+)
+{
+ ISR_Level level;
+ CORE_message_queue_Buffer_control *the_message;
+ Thread_Control *the_thread;
+
+ if ( size > the_message_queue->maximum_message_size ) {
+ return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
+ }
+
+ /*
+ * Is there a thread currently waiting on this message queue?
+ */
+
+ if ( the_message_queue->number_of_pending_messages == 0 ) {
+ the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
+ if ( the_thread ) {
+ _CORE_message_queue_Copy_buffer(
+ buffer,
+ the_thread->Wait.return_argument,
+ size
+ );
+ *(uint32_t *)the_thread->Wait.return_argument_1 = size;
+ the_thread->Wait.count = submit_type;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ (*api_message_queue_mp_support) ( the_thread, id );
+#endif
+ return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
+ }
+ }
+
+ /*
+ * No one waiting on the message queue at this time, so attempt to
+ * queue the message up for a future receive.
+ */
+
+ if ( the_message_queue->number_of_pending_messages <
+ the_message_queue->maximum_pending_messages ) {
+
+ the_message =
+ _CORE_message_queue_Allocate_message_buffer( the_message_queue );
+
+ /*
+ * NOTE: If the system is consistent, this error should never occur.
+ */
+
+ if ( !the_message ) {
+ return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
+ }
+
+ _CORE_message_queue_Copy_buffer(
+ buffer,
+ the_message->Contents.buffer,
+ size
+ );
+ the_message->Contents.size = size;
+ the_message->priority = submit_type;
+
+ _CORE_message_queue_Insert_message(
+ the_message_queue,
+ the_message,
+ submit_type
+ );
+ return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
+ }
+
+ /*
+ * No message buffers were available so we may need to return an
+ * overflow error or block the sender until the message is placed
+ * on the queue.
+ */
+
+ if ( !wait ) {
+ return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
+ }
+
+ /*
+ * Do NOT block on a send if the caller is in an ISR. It is
+ * deadly to block in an ISR.
+ */
+
+ if ( _ISR_Is_in_progress() ) {
+ return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
+ }
+
+ /*
+ * WARNING!! executing should NOT be used prior to this point.
+ * Thus the unusual choice to open a new scope and declare
+ * it as a variable. Doing this emphasizes how dangerous it
+ * would be to use this variable prior to here.
+ */
+
+ {
+ Thread_Control *executing = _Thread_Executing;
+
+ _ISR_Disable( level );
+ _Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
+ executing->Wait.queue = &the_message_queue->Wait_queue;
+ executing->Wait.id = id;
+ executing->Wait.return_argument = buffer;
+ executing->Wait.return_argument_1 = (void *)size;
+ executing->Wait.count = submit_type;
+ _ISR_Enable( level );
+
+ _Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
+ }
+
+ return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT;
+}
diff --git a/cpukit/score/src/coremutex.c b/cpukit/score/src/coremutex.c
new file mode 100644
index 0000000000..173418ffc0
--- /dev/null
+++ b/cpukit/score/src/coremutex.c
@@ -0,0 +1,81 @@
+/*
+ * Mutex Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the Mutex Handler.
+ * This handler provides synchronization and mutual exclusion capabilities.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+
+/*PAGE
+ *
+ * _CORE_mutex_Initialize
+ *
+ * This routine initializes a mutex at create time and set the control
+ * structure according to the values passed.
+ *
+ * Input parameters:
+ * the_mutex - the mutex control block to initialize
+ * the_mutex_attributes - the mutex attributes specified at create time
+ * initial_lock - mutex initial lock or unlocked status
+ *
+ * Output parameters: NONE
+ */
+
+void _CORE_mutex_Initialize(
+ CORE_mutex_Control *the_mutex,
+ CORE_mutex_Attributes *the_mutex_attributes,
+ uint32_t initial_lock
+)
+{
+
+/* Add this to the RTEMS environment later ?????????
+ rtems_assert( initial_lock == CORE_MUTEX_LOCKED ||
+ initial_lock == CORE_MUTEX_UNLOCKED );
+ */
+
+ the_mutex->Attributes = *the_mutex_attributes;
+ the_mutex->lock = initial_lock;
+ the_mutex->blocked_count = 0;
+
+ if ( initial_lock == CORE_MUTEX_LOCKED ) {
+ the_mutex->nest_count = 1;
+ the_mutex->holder = _Thread_Executing;
+ the_mutex->holder_id = _Thread_Executing->Object.id;
+ if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
+ _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
+ _Thread_Executing->resource_count++;
+ } else {
+ the_mutex->nest_count = 0;
+ the_mutex->holder = NULL;
+ the_mutex->holder_id = 0;
+ }
+
+ _Thread_queue_Initialize(
+ &the_mutex->Wait_queue,
+ _CORE_mutex_Is_fifo( the_mutex_attributes ) ?
+ THREAD_QUEUE_DISCIPLINE_FIFO : THREAD_QUEUE_DISCIPLINE_PRIORITY,
+ STATES_WAITING_FOR_MUTEX,
+ CORE_MUTEX_TIMEOUT
+ );
+}
diff --git a/cpukit/score/src/coremutexflush.c b/cpukit/score/src/coremutexflush.c
new file mode 100644
index 0000000000..2006f2dee8
--- /dev/null
+++ b/cpukit/score/src/coremutexflush.c
@@ -0,0 +1,55 @@
+/*
+ * Mutex Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the Mutex Handler.
+ * This handler provides synchronization and mutual exclusion capabilities.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+
+/*PAGE
+ *
+ * _CORE_mutex_Flush
+ *
+ * This function a flushes the mutex's task wait queue.
+ *
+ * Input parameters:
+ * the_mutex - the mutex to be flushed
+ * remote_extract_callout - function to invoke remotely
+ * status - status to pass to thread
+ *
+ * Output parameters: NONE
+ */
+
+void _CORE_mutex_Flush(
+ CORE_mutex_Control *the_mutex,
+ Thread_queue_Flush_callout remote_extract_callout,
+ uint32_t status
+)
+{
+ _Thread_queue_Flush(
+ &the_mutex->Wait_queue,
+ remote_extract_callout,
+ status
+ );
+}
diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c
new file mode 100644
index 0000000000..6b04d200ac
--- /dev/null
+++ b/cpukit/score/src/coremutexseize.c
@@ -0,0 +1,142 @@
+/*
+ * Mutex Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the Mutex Handler.
+ * This handler provides synchronization and mutual exclusion capabilities.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+
+/*PAGE
+ *
+ * _CORE_mutex_Seize (interrupt blocking support)
+ *
+ * This routine blocks the caller thread after an attempt attempts to obtain
+ * the specified mutex has failed.
+ *
+ * Input parameters:
+ * the_mutex - pointer to mutex control block
+ * timeout - number of ticks to wait (0 means forever)
+ */
+
+void _CORE_mutex_Seize_interrupt_blocking(
+ CORE_mutex_Control *the_mutex,
+ Watchdog_Interval timeout
+)
+{
+ Thread_Control *executing;
+
+ executing = _Thread_Executing;
+ if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
+ if ( the_mutex->holder->current_priority > executing->current_priority ) {
+ _Thread_Change_priority(
+ the_mutex->holder,
+ executing->current_priority,
+ FALSE
+ );
+ }
+ }
+
+ the_mutex->blocked_count++;
+ _Thread_queue_Enqueue( &the_mutex->Wait_queue, timeout );
+
+ _Thread_Enable_dispatch();
+}
+
+#if !defined(RTEMS_INLINES)
+int _CORE_mutex_Seize_interrupt_trylock(
+ CORE_mutex_Control *the_mutex,
+ ISR_Level *level_p
+)
+{
+ Thread_Control *executing;
+ ISR_Level level = *level_p;
+
+ /* disabled when you get here */
+
+ executing = _Thread_Executing;
+ executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
+ if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
+ the_mutex->lock = CORE_MUTEX_LOCKED;
+ the_mutex->holder = executing;
+ the_mutex->holder_id = executing->Object.id;
+ the_mutex->nest_count = 1;
+ if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
+ _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
+ executing->resource_count++;
+
+ if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
+ _ISR_Enable( level );
+ return 0;
+ }
+ /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING */
+ {
+ Priority_Control ceiling;
+ Priority_Control current;
+
+ ceiling = the_mutex->Attributes.priority_ceiling;
+ current = executing->current_priority;
+ if ( current == ceiling ) {
+ _ISR_Enable( level );
+ return 0;
+ }
+ if ( current > ceiling ) {
+ _Thread_Disable_dispatch();
+ _ISR_Enable( level );
+ _Thread_Change_priority(
+ the_mutex->holder,
+ the_mutex->Attributes.priority_ceiling,
+ FALSE
+ );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ /* if ( current < ceiling ) */ {
+ executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
+ the_mutex->nest_count = 0; /* undo locking above */
+ executing->resource_count--; /* undo locking above */
+ _ISR_Enable( level );
+ return 0;
+ }
+ }
+ return 0;
+ }
+
+ if ( _Thread_Is_executing( the_mutex->holder ) ) {
+ switch ( the_mutex->Attributes.lock_nesting_behavior ) {
+ case CORE_MUTEX_NESTING_ACQUIRES:
+ the_mutex->nest_count++;
+ _ISR_Enable( level );
+ return 0;
+ case CORE_MUTEX_NESTING_IS_ERROR:
+ executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
+ _ISR_Enable( level );
+ return 0;
+ case CORE_MUTEX_NESTING_BLOCKS:
+ break;
+ }
+ }
+
+ return 1;
+}
+#endif
diff --git a/cpukit/score/src/coremutexsurrender.c b/cpukit/score/src/coremutexsurrender.c
new file mode 100644
index 0000000000..e6f52e229d
--- /dev/null
+++ b/cpukit/score/src/coremutexsurrender.c
@@ -0,0 +1,156 @@
+/*
+ * Mutex Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the Mutex Handler.
+ * This handler provides synchronization and mutual exclusion capabilities.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+
+/*
+ * _CORE_mutex_Surrender
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a unit to the mutex. If a task was blocked waiting for
+ * a unit from this mutex, then that task will be readied and the unit
+ * given to that task. Otherwise, the unit will be returned to the mutex.
+ *
+ * Input parameters:
+ * the_mutex - the mutex to be flushed
+ * id - id of parent mutex
+ * api_mutex_mp_support - api dependent MP support actions
+ *
+ * Output parameters:
+ * CORE_MUTEX_STATUS_SUCCESSFUL - if successful
+ * core error code - if unsuccessful
+ */
+
+CORE_mutex_Status _CORE_mutex_Surrender(
+ CORE_mutex_Control *the_mutex,
+ Objects_Id id,
+ CORE_mutex_API_mp_support_callout api_mutex_mp_support
+)
+{
+ Thread_Control *the_thread;
+ Thread_Control *holder;
+
+ holder = the_mutex->holder;
+
+ /*
+ * The following code allows a thread (or ISR) other than the thread
+ * which acquired the mutex to release that mutex. This is only
+ * allowed when the mutex in quetion is FIFO or simple Priority
+ * discipline. But Priority Ceiling or Priority Inheritance mutexes
+ * must be released by the thread which acquired them.
+ */
+
+ if ( the_mutex->Attributes.only_owner_release ) {
+ if ( !_Thread_Is_executing( holder ) )
+ return CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE;
+ }
+
+ /* XXX already unlocked -- not right status */
+
+ if ( !the_mutex->nest_count )
+ return CORE_MUTEX_STATUS_SUCCESSFUL;
+
+ the_mutex->nest_count--;
+
+ if ( the_mutex->nest_count != 0 ) {
+ switch ( the_mutex->Attributes.lock_nesting_behavior ) {
+ case CORE_MUTEX_NESTING_ACQUIRES:
+ return CORE_MUTEX_STATUS_SUCCESSFUL;
+ case CORE_MUTEX_NESTING_IS_ERROR:
+ /* should never occur */
+ return CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
+ case CORE_MUTEX_NESTING_BLOCKS:
+ /* Currently no API exercises this behavior. */
+ break;
+ }
+ }
+
+ if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
+ _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
+ holder->resource_count--;
+ the_mutex->holder = NULL;
+ the_mutex->holder_id = 0;
+
+ /*
+ * Whether or not someone is waiting for the mutex, an
+ * inherited priority must be lowered if this is the last
+ * mutex (i.e. resource) this task has.
+ */
+
+ if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
+ _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
+ if ( holder->resource_count == 0 &&
+ holder->real_priority != holder->current_priority ) {
+ _Thread_Change_priority( holder, holder->real_priority, TRUE );
+ }
+ }
+
+ if ( ( the_thread = _Thread_queue_Dequeue( &the_mutex->Wait_queue ) ) ) {
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
+
+ the_mutex->holder = NULL;
+ the_mutex->holder_id = the_thread->Object.id;
+ the_mutex->nest_count = 1;
+
+ ( *api_mutex_mp_support)( the_thread, id );
+
+ } else
+#endif
+ {
+
+ the_mutex->holder = the_thread;
+ the_mutex->holder_id = the_thread->Object.id;
+ the_mutex->nest_count = 1;
+
+ switch ( the_mutex->Attributes.discipline ) {
+ case CORE_MUTEX_DISCIPLINES_FIFO:
+ case CORE_MUTEX_DISCIPLINES_PRIORITY:
+ break;
+ case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
+ the_thread->resource_count++;
+ break;
+ case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
+ the_thread->resource_count++;
+ if (the_mutex->Attributes.priority_ceiling <
+ the_thread->current_priority){
+ _Thread_Change_priority(
+ the_thread,
+ the_mutex->Attributes.priority_ceiling,
+ FALSE
+ );
+ }
+ break;
+ }
+ }
+ } else
+ the_mutex->lock = CORE_MUTEX_UNLOCKED;
+
+ return CORE_MUTEX_STATUS_SUCCESSFUL;
+}
diff --git a/cpukit/score/src/coresem.c b/cpukit/score/src/coresem.c
new file mode 100644
index 0000000000..9030f20ae1
--- /dev/null
+++ b/cpukit/score/src/coresem.c
@@ -0,0 +1,66 @@
+/*
+ * CORE Semaphore Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Semaphore Handler.
+ * This core object utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * CORE_semaphore_Initialize
+ *
+ * This function initialize a semaphore and sets the initial value based
+ * on the given count.
+ *
+ * Input parameters:
+ * the_semaphore - the semaphore control block to initialize
+ * the_semaphore_attributes - the attributes specified at create time
+ * initial_value - semaphore's initial value
+ *
+ * Output parameters: NONE
+ */
+
+void _CORE_semaphore_Initialize(
+ CORE_semaphore_Control *the_semaphore,
+ CORE_semaphore_Attributes *the_semaphore_attributes,
+ uint32_t initial_value
+)
+{
+
+ the_semaphore->Attributes = *the_semaphore_attributes;
+ the_semaphore->count = initial_value;
+
+ _Thread_queue_Initialize(
+ &the_semaphore->Wait_queue,
+ _CORE_semaphore_Is_priority( the_semaphore_attributes ) ?
+ THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
+ STATES_WAITING_FOR_SEMAPHORE,
+ CORE_SEMAPHORE_TIMEOUT
+ );
+}
diff --git a/cpukit/score/src/coresemflush.c b/cpukit/score/src/coresemflush.c
new file mode 100644
index 0000000000..14d10039d2
--- /dev/null
+++ b/cpukit/score/src/coresemflush.c
@@ -0,0 +1,61 @@
+/*
+ * CORE Semaphore Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Semaphore Handler.
+ * This core object utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_semaphore_Flush
+ *
+ * This function a flushes the semaphore's task wait queue.
+ *
+ * Input parameters:
+ * the_semaphore - the semaphore to be flushed
+ * remote_extract_callout - function to invoke remotely
+ * status - status to pass to thread
+ *
+ * Output parameters: NONE
+ */
+
+void _CORE_semaphore_Flush(
+ CORE_semaphore_Control *the_semaphore,
+ Thread_queue_Flush_callout remote_extract_callout,
+ uint32_t status
+)
+{
+
+ _Thread_queue_Flush(
+ &the_semaphore->Wait_queue,
+ remote_extract_callout,
+ status
+ );
+
+}
diff --git a/cpukit/score/src/coresemseize.c b/cpukit/score/src/coresemseize.c
new file mode 100644
index 0000000000..49c835b80b
--- /dev/null
+++ b/cpukit/score/src/coresemseize.c
@@ -0,0 +1,84 @@
+/*
+ * CORE Semaphore Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Semaphore Handler.
+ * This core object utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_semaphore_Seize
+ *
+ * This routine attempts to allocate a core semaphore to the calling thread.
+ *
+ * Input parameters:
+ * the_semaphore - pointer to semaphore control block
+ * id - id of object to wait on
+ * wait - TRUE if wait is allowed, FALSE otherwise
+ * timeout - number of ticks to wait (0 means forever)
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * available
+ * wait
+ */
+
+void _CORE_semaphore_Seize(
+ CORE_semaphore_Control *the_semaphore,
+ Objects_Id id,
+ boolean wait,
+ Watchdog_Interval timeout
+)
+{
+ Thread_Control *executing;
+ ISR_Level level;
+
+ executing = _Thread_Executing;
+ executing->Wait.return_code = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
+ _ISR_Disable( level );
+ if ( the_semaphore->count != 0 ) {
+ the_semaphore->count -= 1;
+ _ISR_Enable( level );
+ return;
+ }
+
+ if ( !wait ) {
+ _ISR_Enable( level );
+ executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT;
+ return;
+ }
+
+ _Thread_queue_Enter_critical_section( &the_semaphore->Wait_queue );
+ executing->Wait.queue = &the_semaphore->Wait_queue;
+ executing->Wait.id = id;
+ _ISR_Enable( level );
+
+ _Thread_queue_Enqueue( &the_semaphore->Wait_queue, timeout );
+}
diff --git a/cpukit/score/src/coresemsurrender.c b/cpukit/score/src/coresemsurrender.c
new file mode 100644
index 0000000000..837d150391
--- /dev/null
+++ b/cpukit/score/src/coresemsurrender.c
@@ -0,0 +1,79 @@
+/*
+ * CORE Semaphore Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Semaphore Handler.
+ * This core object utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _CORE_semaphore_Surrender
+ *
+ * Input parameters:
+ * the_semaphore - the semaphore to be flushed
+ * id - id of parent semaphore
+ * api_semaphore_mp_support - api dependent MP support actions
+ *
+ * Output parameters:
+ * CORE_SEMAPHORE_STATUS_SUCCESSFUL - if successful
+ * core error code - if unsuccessful
+ *
+ * Output parameters:
+ */
+
+CORE_semaphore_Status _CORE_semaphore_Surrender(
+ CORE_semaphore_Control *the_semaphore,
+ Objects_Id id,
+ CORE_semaphore_API_mp_support_callout api_semaphore_mp_support
+)
+{
+ Thread_Control *the_thread;
+ ISR_Level level;
+ CORE_semaphore_Status status;
+
+ status = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
+
+ if ( (the_thread = _Thread_queue_Dequeue(&the_semaphore->Wait_queue)) ) {
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ (*api_semaphore_mp_support) ( the_thread, id );
+#endif
+
+ } else {
+ _ISR_Disable( level );
+ if ( the_semaphore->count < the_semaphore->Attributes.maximum_count )
+ the_semaphore->count += 1;
+ else
+ status = CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED;
+ _ISR_Enable( level );
+ }
+
+ return status;
+}
diff --git a/cpukit/score/src/coretod.c b/cpukit/score/src/coretod.c
new file mode 100644
index 0000000000..4824be2c36
--- /dev/null
+++ b/cpukit/score/src/coretod.c
@@ -0,0 +1,63 @@
+/*
+ * Time of Day (TOD) Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _TOD_Handler_initialization
+ *
+ * This routine initializes the time of day handler.
+ *
+ * Input parameters:
+ * microseconds_per_tick - microseconds between clock ticks
+ *
+ * Output parameters: NONE
+ */
+
+void _TOD_Handler_initialization(
+ uint32_t microseconds_per_tick
+)
+{
+ _TOD_Microseconds_per_tick = microseconds_per_tick;
+
+ _TOD_Seconds_since_epoch = 0;
+
+ _TOD_Current.year = TOD_BASE_YEAR;
+ _TOD_Current.month = 1;
+ _TOD_Current.day = 1;
+ _TOD_Current.hour = 0;
+ _TOD_Current.minute = 0;
+ _TOD_Current.second = 0;
+ _TOD_Current.ticks = 0;
+
+ if ( microseconds_per_tick == 0 )
+ _TOD_Ticks_per_second = 0;
+ else
+ _TOD_Ticks_per_second =
+ TOD_MICROSECONDS_PER_SECOND / microseconds_per_tick;
+
+ _Watchdog_Initialize( &_TOD_Seconds_watchdog, _TOD_Tickle, 0, NULL );
+
+ _TOD_Is_set = FALSE;
+ _TOD_Activate( _TOD_Ticks_per_second );
+}
diff --git a/cpukit/score/src/coretodset.c b/cpukit/score/src/coretodset.c
new file mode 100644
index 0000000000..ae7ec65b30
--- /dev/null
+++ b/cpukit/score/src/coretodset.c
@@ -0,0 +1,66 @@
+/*
+ * Time of Day (TOD) Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _TOD_Set
+ *
+ * This rountine sets the current date and time with the specified
+ * new date and time structure.
+ *
+ * Input parameters:
+ * the_tod - pointer to the time and date structure
+ * seconds_since_epoch - seconds since system epoch
+ *
+ * Output parameters: NONE
+ */
+
+void _TOD_Set(
+ TOD_Control *the_tod,
+ Watchdog_Interval seconds_since_epoch
+)
+{
+ Watchdog_Interval ticks_until_next_second;
+
+ _Thread_Disable_dispatch();
+ _TOD_Deactivate();
+
+ if ( seconds_since_epoch < _TOD_Seconds_since_epoch )
+ _Watchdog_Adjust_seconds( WATCHDOG_BACKWARD,
+ _TOD_Seconds_since_epoch - seconds_since_epoch );
+ else
+ _Watchdog_Adjust_seconds( WATCHDOG_FORWARD,
+ seconds_since_epoch - _TOD_Seconds_since_epoch );
+
+ ticks_until_next_second = _TOD_Ticks_per_second;
+ if ( ticks_until_next_second > the_tod->ticks )
+ ticks_until_next_second -= the_tod->ticks;
+
+ _TOD_Current = *the_tod;
+ _TOD_Seconds_since_epoch = seconds_since_epoch;
+ _TOD_Is_set = TRUE;
+ _TOD_Activate( ticks_until_next_second );
+
+ _Thread_Enable_dispatch();
+}
diff --git a/cpukit/score/src/coretodtickle.c b/cpukit/score/src/coretodtickle.c
new file mode 100644
index 0000000000..d2c0fe3d46
--- /dev/null
+++ b/cpukit/score/src/coretodtickle.c
@@ -0,0 +1,71 @@
+/*
+ * Time of Day (TOD) Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _TOD_Tickle
+ *
+ * This routine updates the calendar time and tickles the
+ * per second watchdog timer chain.
+ *
+ * Input parameters:
+ * ignored - this parameter is ignored
+ *
+ * Output parameters: NONE
+ *
+ * NOTE: This routine only works for leap-years through 2099.
+ */
+
+void _TOD_Tickle(
+ Objects_Id id,
+ void *ignored
+)
+{
+ uint32_t leap;
+
+ _TOD_Current.ticks = 0;
+ ++_TOD_Seconds_since_epoch;
+ if ( ++_TOD_Current.second >= TOD_SECONDS_PER_MINUTE ) {
+ _TOD_Current.second = 0;
+ if ( ++_TOD_Current.minute >= TOD_MINUTES_PER_HOUR ) {
+ _TOD_Current.minute = 0;
+ if ( ++_TOD_Current.hour >= TOD_HOURS_PER_DAY ) {
+ _TOD_Current.hour = 0;
+ if ( _TOD_Current.year & 0x3 ) leap = 0;
+ else leap = 1;
+ if ( ++_TOD_Current.day >
+ _TOD_Days_per_month[ leap ][ _TOD_Current.month ]) {
+ _TOD_Current.day = 1;
+ if ( ++_TOD_Current.month > TOD_MONTHS_PER_YEAR ) {
+ _TOD_Current.month = 1;
+ _TOD_Current.year++;
+ }
+ }
+ }
+ }
+ }
+
+ _Watchdog_Tickle_seconds();
+ _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, _TOD_Ticks_per_second );
+}
diff --git a/cpukit/score/src/coretodtoseconds.c b/cpukit/score/src/coretodtoseconds.c
new file mode 100644
index 0000000000..5bea09cc25
--- /dev/null
+++ b/cpukit/score/src/coretodtoseconds.c
@@ -0,0 +1,67 @@
+/*
+ * Time of Day (TOD) Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _TOD_To_seconds
+ *
+ * This routine returns the seconds from the epoch until the
+ * current date and time.
+ *
+ * Input parameters:
+ * the_tod - pointer to the time and date structure
+ *
+ * Output parameters:
+ * returns - seconds since epoch until the_tod
+ */
+
+uint32_t _TOD_To_seconds(
+ TOD_Control *the_tod
+)
+{
+ uint32_t time;
+ uint32_t year_mod_4;
+
+ time = the_tod->day - 1;
+ year_mod_4 = the_tod->year & 3;
+
+ if ( year_mod_4 == 0 )
+ time += _TOD_Days_to_date[ 1 ][ the_tod->month ];
+ else
+ time += _TOD_Days_to_date[ 0 ][ the_tod->month ];
+
+ time += ( (the_tod->year - TOD_BASE_YEAR) / 4 ) *
+ ( (TOD_DAYS_PER_YEAR * 4) + 1);
+
+ time += _TOD_Days_since_last_leap_year[ year_mod_4 ];
+
+ time *= TOD_SECONDS_PER_DAY;
+
+ time += ((the_tod->hour * TOD_MINUTES_PER_HOUR) + the_tod->minute)
+ * TOD_SECONDS_PER_MINUTE;
+
+ time += the_tod->second;
+
+ return( time );
+}
diff --git a/cpukit/score/src/coretodvalidate.c b/cpukit/score/src/coretodvalidate.c
new file mode 100644
index 0000000000..6db0c9eb67
--- /dev/null
+++ b/cpukit/score/src/coretodvalidate.c
@@ -0,0 +1,67 @@
+/*
+ * Time of Day (TOD) Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _TOD_Validate
+ *
+ * This kernel routine checks the validity of a date and time structure.
+ *
+ * Input parameters:
+ * the_tod - pointer to a time and date structure
+ *
+ * Output parameters:
+ * TRUE - if the date, time, and tick are valid
+ * FALSE - if the the_tod is invalid
+ *
+ * NOTE: This routine only works for leap-years through 2099.
+ */
+
+boolean _TOD_Validate(
+ TOD_Control *the_tod
+)
+{
+ uint32_t days_in_month;
+
+ if ((!the_tod) ||
+ (the_tod->ticks >= _TOD_Ticks_per_second) ||
+ (the_tod->second >= TOD_SECONDS_PER_MINUTE) ||
+ (the_tod->minute >= TOD_MINUTES_PER_HOUR) ||
+ (the_tod->hour >= TOD_HOURS_PER_DAY) ||
+ (the_tod->month == 0) ||
+ (the_tod->month > TOD_MONTHS_PER_YEAR) ||
+ (the_tod->year < TOD_BASE_YEAR) ||
+ (the_tod->day == 0) )
+ return FALSE;
+
+ if ( (the_tod->year % 4) == 0 )
+ days_in_month = _TOD_Days_per_month[ 1 ][ the_tod->month ];
+ else
+ days_in_month = _TOD_Days_per_month[ 0 ][ the_tod->month ];
+
+ if ( the_tod->day > days_in_month )
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/cpukit/score/src/heap.c b/cpukit/score/src/heap.c
new file mode 100644
index 0000000000..5e7a8804d2
--- /dev/null
+++ b/cpukit/score/src/heap.c
@@ -0,0 +1,267 @@
+/*
+ * Heap Handler
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/heap.h>
+
+static uint32_t instance = 0;
+
+/*PAGE
+ *
+ * _Heap_Initialize
+ *
+ * This kernel routine initializes a heap.
+ *
+ * Input parameters:
+ * the_heap - pointer to heap header
+ * starting_address - starting address of heap
+ * size - size of heap
+ * page_size - allocatable unit of memory
+ *
+ * Output parameters:
+ * returns - maximum memory available if RTEMS_SUCCESSFUL
+ * 0 - otherwise
+ *
+ * This is what a heap looks like in memory immediately after initialization:
+ *
+ *
+ * +--------------------------------+ <- begin = starting_address
+ * | unused space due to alignment |
+ * | size < page_size |
+ * 0 +--------------------------------+ <- first block
+ * | prev_size = page_size |
+ * 4 +--------------------------------+
+ * | size = size0 | 1 |
+ * 8 +---------------------+----------+ <- aligned on page_size
+ * | next = HEAP_TAIL | |
+ * 12 +---------------------+ |
+ * | prev = HEAP_HEAD | memory |
+ * +---------------------+ |
+ * | available |
+ * | |
+ * | for allocation |
+ * | |
+ * size0 +--------------------------------+ <- last dummy block
+ * | prev_size = size0 |
+ * +4 +--------------------------------+
+ * | size = page_size | 0 | <- prev block is free
+ * +8 +--------------------------------+ <- aligned on page_size
+ * | unused space due to alignment |
+ * | size < page_size |
+ * +--------------------------------+ <- end = begin + size
+ *
+ * This is what a heap looks like after first allocation of SIZE bytes.
+ * BSIZE stands for SIZE + 4 aligned up on 'page_size' boundary if allocation
+ * has been performed by _Heap_Allocate(). If allocation has been performed
+ * by _Heap_Allocate_aligned(), the block size BSIZE is defined differently
+ * (see 'heapallocatealigned.c' for details).
+ *
+ * +--------------------------------+ <- begin = starting_address
+ * | unused space due to alignment |
+ * | size < page_size |
+ * 0 +--------------------------------+ <- used block
+ * | prev_size = page_size |
+ * 4 +--------------------------------+
+ * | size = BSIZE | 1 | <- prev block is used
+ * 8 +--------------------------------+ <- aligned on page_size
+ * | . | Pointer returned to the user
+ * | . | is 8 for _Heap_Allocate()
+ * | . | and is in range
+ * 8 + | user-accessible | [8,8+page_size) for
+ * page_size +- - - - - -+ _Heap_Allocate_aligned()
+ * | area |
+ * | . |
+ * BSIZE +- - - - - . - - - - -+ <- free block
+ * | . |
+ * BSIZE +4 +--------------------------------+
+ * | size = S = size0 - BSIZE | 1 | <- prev block is used
+ * BSIZE +8 +-------------------+------------+ <- aligned on page_size
+ * | next = HEAP_TAIL | |
+ * BSIZE +12 +-------------------+ |
+ * | prev = HEAP_HEAD | memory |
+ * +-------------------+ |
+ * | . available |
+ * | . |
+ * | . for |
+ * | . |
+ * BSIZE +S+0 +-------------------+ allocation + <- last dummy block
+ * | prev_size = S | |
+ * +S+4 +-------------------+------------+
+ * | size = page_size | 0 | <- prev block is free
+ * +S+8 +--------------------------------+ <- aligned on page_size
+ * | unused space due to alignment |
+ * | size < page_size |
+ * +--------------------------------+ <- end = begin + size
+ *
+ */
+
+uint32_t _Heap_Initialize(
+ Heap_Control *the_heap,
+ void *starting_address,
+ uint32_t size,
+ uint32_t page_size
+)
+{
+ Heap_Block *the_block;
+ uint32_t the_size;
+ _H_uptr_t start;
+ _H_uptr_t aligned_start;
+ uint32_t overhead;
+ Heap_Statistics *const stats = &the_heap->stats;
+
+ if(page_size == 0)
+ page_size = CPU_ALIGNMENT;
+ else
+ _Heap_Align_up( &page_size, CPU_ALIGNMENT );
+
+ /* Calculate aligned_start so that aligned_start + HEAP_BLOCK_USER_OFFSET
+ (value of user pointer) is aligned on 'page_size' boundary. Make sure
+ resulting 'aligned_start' is not below 'starting_address'. */
+ start = _H_p2u(starting_address);
+ aligned_start = start + HEAP_BLOCK_USER_OFFSET;
+ _Heap_Align_up_uptr ( &aligned_start, page_size );
+ aligned_start -= HEAP_BLOCK_USER_OFFSET;
+
+ /* Calculate 'min_block_size'. It's HEAP_MIN_BLOCK_SIZE aligned up to the
+ nearest multiple of 'page_size'. */
+ the_heap->min_block_size = HEAP_MIN_BLOCK_SIZE;
+ _Heap_Align_up ( &the_heap->min_block_size, page_size );
+
+ /* Calculate 'the_size' -- size of the first block so that there is enough
+ space at the end for the permanent last block. It is equal to 'size'
+ minus total overhead aligned down to the nearest multiple of
+ 'page_size'. */
+ overhead = HEAP_OVERHEAD + (aligned_start - start);
+ if ( size < overhead )
+ return 0; /* Too small area for the heap */
+ the_size = size - overhead;
+ _Heap_Align_down ( &the_size, page_size );
+ if ( the_size == 0 )
+ return 0; /* Too small area for the heap */
+
+ the_heap->page_size = page_size;
+ the_heap->begin = starting_address;
+ the_heap->end = starting_address + size;
+
+ the_block = (Heap_Block *) aligned_start;
+
+ the_block->prev_size = page_size;
+ the_block->size = the_size | HEAP_PREV_USED;
+ the_block->next = _Heap_Tail( the_heap );
+ the_block->prev = _Heap_Head( the_heap );
+ _Heap_Head(the_heap)->next = the_block;
+ _Heap_Tail(the_heap)->prev = the_block;
+ the_heap->start = the_block;
+
+ _HAssert(_Heap_Is_aligned(the_heap->page_size, CPU_ALIGNMENT));
+ _HAssert(_Heap_Is_aligned(the_heap->min_block_size, page_size));
+ _HAssert(_Heap_Is_aligned_ptr(_Heap_User_area(the_block), page_size));
+
+ the_block = _Heap_Block_at( the_block, the_size );
+ the_heap->final = the_block; /* Permanent final block of the heap */
+ the_block->prev_size = the_size; /* Previous block is free */
+ the_block->size = page_size;
+
+ stats->size = size;
+ stats->free_size = the_size;
+ stats->min_free_size = the_size;
+ stats->free_blocks = 1;
+ stats->max_free_blocks = 1;
+ stats->used_blocks = 0;
+ stats->max_search = 0;
+ stats->allocs = 0;
+ stats->searches = 0;
+ stats->frees = 0;
+ stats->resizes = 0;
+ stats->instance = instance++;
+
+ return ( the_size - HEAP_BLOCK_USED_OVERHEAD );
+}
+
+/*PAGE
+ *
+ * Internal routines shared by _Heap_Allocate() and _Heap_Allocate_aligned().
+ *
+ * Note: there is no reason to put them into a separate file(s) as they are
+ * always required for heap to be useful.
+ */
+
+/*
+ * Convert user requested 'size' of memory block to the block size.
+ * Return block size on success, 0 if overflow occured
+ */
+uint32_t _Heap_Calc_block_size(
+ uint32_t size,
+ uint32_t page_size,
+ uint32_t min_size)
+{
+ uint32_t block_size = size + HEAP_BLOCK_USED_OVERHEAD;
+ _Heap_Align_up(&block_size, page_size);
+ if (block_size < min_size) block_size = min_size;
+ /* 'block_size' becomes <= 'size' if and only if overflow occured. */
+ return (block_size > size) ? block_size : 0;
+}
+
+/*
+ * Allocate block of size 'alloc_size' from 'the_block' belonging to
+ * 'the_heap'. Split 'the_block' if possible, otherwise allocate it entirely.
+ * When split, make the lower part used, and leave the upper part free.
+ * Return the size of allocated block.
+ */
+uint32_t _Heap_Block_allocate(
+ Heap_Control* the_heap,
+ Heap_Block* the_block,
+ uint32_t alloc_size
+)
+{
+ Heap_Statistics *const stats = &the_heap->stats;
+ uint32_t const block_size = _Heap_Block_size(the_block);
+ uint32_t const the_rest = block_size - alloc_size;
+
+ _HAssert(_Heap_Is_aligned(block_size, the_heap->page_size));
+ _HAssert(_Heap_Is_aligned(alloc_size, the_heap->page_size));
+ _HAssert(alloc_size <= block_size);
+ _HAssert(_Heap_Is_prev_used(the_block));
+
+ if(the_rest >= the_heap->min_block_size) {
+ /* Split the block so that upper part is still free, and lower part
+ becomes used. This is slightly less optimal than leaving lower part
+ free as it requires replacing block in the free blocks list, but it
+ makes it possible to reuse this code in the _Heap_Resize_block(). */
+ Heap_Block *next_block = _Heap_Block_at(the_block, alloc_size);
+ _Heap_Block_replace(the_block, next_block);
+ the_block->size = alloc_size | HEAP_PREV_USED;
+ next_block->size = the_rest | HEAP_PREV_USED;
+ _Heap_Block_at(next_block, the_rest)->prev_size = the_rest;
+ }
+ else {
+ /* Don't split the block as remainder is either zero or too small to be
+ used as a separate free block. Change 'alloc_size' to the size of the
+ block and remove the block from the list of free blocks. */
+ _Heap_Block_remove(the_block);
+ alloc_size = block_size;
+ _Heap_Block_at(the_block, alloc_size)->size |= HEAP_PREV_USED;
+ stats->free_blocks -= 1;
+ }
+ /* Update statistics */
+ stats->free_size -= alloc_size;
+ if(stats->min_free_size > stats->free_size)
+ stats->min_free_size = stats->free_size;
+ stats->used_blocks += 1;
+ return alloc_size;
+}
diff --git a/cpukit/score/src/heapallocate.c b/cpukit/score/src/heapallocate.c
new file mode 100644
index 0000000000..e2a7ecdc25
--- /dev/null
+++ b/cpukit/score/src/heapallocate.c
@@ -0,0 +1,81 @@
+/*
+ * Heap Handler
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/heap.h>
+
+/*PAGE
+ *
+ * _Heap_Allocate
+ *
+ * This kernel routine allocates the requested size of memory
+ * from the specified heap.
+ *
+ * Input parameters:
+ * the_heap - pointer to heap header.
+ * size - size in bytes of the memory block to allocate.
+ *
+ * Output parameters:
+ * returns - starting address of memory block allocated
+ */
+
+void *_Heap_Allocate(
+ Heap_Control *the_heap,
+ uint32_t size
+)
+{
+ uint32_t the_size;
+ uint32_t search_count;
+ Heap_Block *the_block;
+ void *ptr = NULL;
+ Heap_Statistics *const stats = &the_heap->stats;
+ Heap_Block *const tail = _Heap_Tail(the_heap);
+
+ the_size =
+ _Heap_Calc_block_size(size, the_heap->page_size, the_heap->min_block_size);
+ if(the_size == 0)
+ return NULL;
+
+ /* Find large enough free block. */
+ for(the_block = _Heap_First(the_heap), search_count = 0;
+ the_block != tail;
+ the_block = the_block->next, ++search_count)
+ {
+ /* As we always coalesce free blocks, prev block must have been used. */
+ _HAssert(_Heap_Is_prev_used(the_block));
+
+ /* Don't bother to mask out the HEAP_PREV_USED bit as it won't change the
+ result of the comparison. */
+ if(the_block->size >= the_size) {
+ (void)_Heap_Block_allocate(the_heap, the_block, the_size );
+
+ ptr = _Heap_User_area(the_block);
+
+ stats->allocs += 1;
+ stats->searches += search_count + 1;
+
+ _HAssert(_Heap_Is_aligned_ptr(ptr, the_heap->page_size));
+ break;
+ }
+ }
+
+ if(stats->max_search < search_count)
+ stats->max_search = search_count;
+
+ return ptr;
+}
diff --git a/cpukit/score/src/heapallocatealigned.c b/cpukit/score/src/heapallocatealigned.c
new file mode 100644
index 0000000000..741b389e77
--- /dev/null
+++ b/cpukit/score/src/heapallocatealigned.c
@@ -0,0 +1,194 @@
+/*
+ * Heap Handler
+ *
+ * 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$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/heap.h>
+
+#if defined(RTEMS_HEAP_DEBUG)
+
+static void
+check_result(
+ Heap_Control* the_heap,
+ Heap_Block* the_block,
+ _H_uptr_t user_addr,
+ _H_uptr_t aligned_user_addr,
+ uint32_t size)
+{
+ _H_uptr_t const user_area = _H_p2u(_Heap_User_area(the_block));
+ _H_uptr_t const block_end = _H_p2u(the_block)
+ + _Heap_Block_size(the_block) + HEAP_BLOCK_HEADER_OFFSET;
+ _H_uptr_t const user_end = aligned_user_addr + size;
+ _H_uptr_t const heap_start = _H_p2u(the_heap->start) + HEAP_OVERHEAD;
+ _H_uptr_t const heap_end = _H_p2u(the_heap->final)
+ + HEAP_BLOCK_HEADER_OFFSET;
+ uint32_t const page_size = the_heap->page_size;
+
+ _HAssert(user_addr == user_area);
+ _HAssert(aligned_user_addr - user_area < page_size);
+ _HAssert(aligned_user_addr >= user_area);
+ _HAssert(aligned_user_addr < block_end);
+ _HAssert(user_end > user_area);
+ _HAssert(user_end <= block_end);
+ _HAssert(aligned_user_addr >= heap_start);
+ _HAssert(aligned_user_addr < heap_end);
+ _HAssert(user_end > heap_start);
+ _HAssert(user_end <= heap_end);
+}
+
+#else /* !defined(RTEMS_HEAP_DEBUG) */
+
+#define check_result(a, b, c, d, e) ((void)0)
+
+#endif /* !defined(RTEMS_HEAP_DEBUG) */
+
+/*PAGE
+ *
+ * _Heap_Allocate_aligned
+ *
+ * This kernel routine allocates the requested size of memory
+ * from the specified heap so that returned address is aligned according to
+ * the 'alignment'.
+ *
+ * Input parameters:
+ * the_heap - pointer to the heap control block.
+ * size - size in bytes of the memory block to allocate.
+ * alignment - required user pointer alignment in bytes
+ *
+ * Output parameters:
+ * returns - starting address of memory block allocated. The address is
+ * aligned on specified boundary.
+ */
+
+void *_Heap_Allocate_aligned(
+ Heap_Control *the_heap,
+ uint32_t size,
+ uint32_t alignment
+)
+{
+ uint32_t search_count;
+ Heap_Block *the_block;
+
+ void *user_ptr = NULL;
+ uint32_t const page_size = the_heap->page_size;
+ Heap_Statistics *const stats = &the_heap->stats;
+ Heap_Block *const tail = _Heap_Tail(the_heap);
+
+ uint32_t const end_to_user_offs = size - HEAP_BLOCK_HEADER_OFFSET;
+
+ uint32_t const the_size =
+ _Heap_Calc_block_size(size, page_size, the_heap->min_block_size);
+
+ if(the_size == 0)
+ return NULL;
+
+ if(alignment == 0)
+ alignment = CPU_ALIGNMENT;
+
+ /* Find large enough free block that satisfies the alignment requirements. */
+
+ for(the_block = _Heap_Head(the_heap)->next, search_count = 0;
+ the_block != tail;
+ the_block = the_block->next, ++search_count)
+ {
+ uint32_t const block_size = _Heap_Block_size(the_block);
+
+ /* As we always coalesce free blocks, prev block must have been used. */
+ _HAssert(_Heap_Is_prev_used(the_block));
+
+ if(block_size >= the_size) { /* the_block is large enough. */
+
+ _H_uptr_t user_addr;
+ _H_uptr_t aligned_user_addr;
+ _H_uptr_t const user_area = _H_p2u(_Heap_User_area(the_block));
+
+ /* Calculate 'aligned_user_addr' that will become the user pointer we
+ return. It should be at least 'end_to_user_offs' bytes less than the
+ the 'block_end' and should be aligned on 'alignment' boundary.
+ Calculations are from the 'block_end' as we are going to split free
+ block so that the upper part of the block becomes used block. */
+ _H_uptr_t const block_end = _H_p2u(the_block) + block_size;
+ aligned_user_addr = block_end - end_to_user_offs;
+ _Heap_Align_down_uptr(&aligned_user_addr, alignment);
+
+ /* 'user_addr' is the 'aligned_user_addr' further aligned down to the
+ 'page_size' boundary. We need it as blocks' user areas should begin
+ only at 'page_size' aligned addresses */
+ user_addr = aligned_user_addr;
+ _Heap_Align_down_uptr(&user_addr, page_size);
+
+ /* Make sure 'user_addr' calculated didn't run out of 'the_block. */
+ if(user_addr >= user_area) {
+
+ /* The block seems to be acceptable. Check if the remainder of
+ 'the_block' is less than 'min_block_size' so that 'the_block' won't
+ actually be split at the address we assume. */
+ if(user_addr - user_area < the_heap->min_block_size) {
+
+ /* The block won't be split, so 'user_addr' will be equal to the
+ 'user_area'. */
+ user_addr = user_area;
+
+ /* We can't allow the distance between 'user_addr' and
+ 'aligned_user_addr' to be outside of [0,page_size) range. If we do,
+ we will need to store this distance somewhere to be able to
+ resurrect the block address from the user pointer. (Having the
+ distance within [0,page_size) range allows resurrection by
+ aligning user pointer down to the nearest 'page_size' boundary.) */
+ if(aligned_user_addr - user_addr >= page_size) {
+
+ /* The user pointer will be too far from 'user_addr'. See if we
+ can make 'aligned_user_addr' to be close enough to the
+ 'user_addr'. */
+ aligned_user_addr = user_addr;
+ _Heap_Align_up_uptr(&aligned_user_addr, alignment);
+ if(aligned_user_addr - user_addr >= page_size) {
+ /* No, we can't use the block */
+ aligned_user_addr = 0;
+ }
+ }
+ }
+
+ if(aligned_user_addr) {
+
+ /* The block is indeed acceptable: calculate the size of the block
+ to be allocated and perform allocation. */
+ uint32_t const alloc_size =
+ block_end - user_addr + HEAP_BLOCK_USER_OFFSET;
+
+ _HAssert(_Heap_Is_aligned_ptr((void*)aligned_user_addr, alignment));
+
+ (void)_Heap_Block_allocate(the_heap, the_block, alloc_size);
+
+ stats->searches += search_count + 1;
+ stats->allocs += 1;
+
+ check_result(the_heap, the_block, user_addr,
+ aligned_user_addr, size);
+
+ user_ptr = (void*)aligned_user_addr;
+ break;
+ }
+ }
+ }
+ }
+
+ if(stats->max_search < search_count)
+ stats->max_search = search_count;
+
+ return user_ptr;
+}
diff --git a/cpukit/score/src/heapextend.c b/cpukit/score/src/heapextend.c
new file mode 100644
index 0000000000..0bcf194532
--- /dev/null
+++ b/cpukit/score/src/heapextend.c
@@ -0,0 +1,104 @@
+/*
+ * Heap Handler
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/heap.h>
+
+/*PAGE
+ *
+ * _Heap_Extend
+ *
+ * This routine grows the_heap memory area using the size bytes which
+ * begin at starting_address.
+ *
+ * Input parameters:
+ * the_heap - pointer to heap header.
+ * starting_address - pointer to the memory area.
+ * size - size in bytes of the memory block to allocate.
+ *
+ * Output parameters:
+ * *amount_extended - amount of memory added to the_heap
+ */
+
+Heap_Extend_status _Heap_Extend(
+ Heap_Control *the_heap,
+ void *starting_address,
+ uint32_t size,
+ uint32_t *amount_extended
+)
+{
+ uint32_t the_size;
+ Heap_Statistics *const stats = &the_heap->stats;
+
+ /*
+ * The overhead was taken from the original heap memory.
+ */
+
+ Heap_Block *old_final;
+ Heap_Block *new_final;
+
+ /*
+ * There are five possibilities for the location of starting
+ * address:
+ *
+ * 1. non-contiguous lower address (NOT SUPPORTED)
+ * 2. contiguous lower address (NOT SUPPORTED)
+ * 3. in the heap (ERROR)
+ * 4. contiguous higher address (SUPPORTED)
+ * 5. non-contiguous higher address (NOT SUPPORTED)
+ *
+ * As noted, this code only supports (4).
+ */
+
+ if ( starting_address >= the_heap->begin && /* case 3 */
+ starting_address < the_heap->end
+ )
+ return HEAP_EXTEND_ERROR;
+
+ if ( starting_address != the_heap->end )
+ return HEAP_EXTEND_NOT_IMPLEMENTED; /* cases 1, 2, and 5 */
+
+ /*
+ * Currently only case 4 should make it to this point.
+ * The basic trick is to make the extend area look like a used
+ * block and free it.
+ */
+
+ old_final = the_heap->final;
+ the_heap->end = _Addresses_Add_offset( the_heap->end, size );
+ the_size = _Addresses_Subtract( the_heap->end, old_final ) - HEAP_OVERHEAD;
+ _Heap_Align_down( &the_size, the_heap->page_size );
+
+ *amount_extended = size;
+
+ if( the_size < the_heap->min_block_size )
+ return HEAP_EXTEND_SUCCESSFUL;
+
+ old_final->size = the_size | (old_final->size & HEAP_PREV_USED);
+ new_final = _Heap_Block_at( old_final, the_size );
+ new_final->size = HEAP_PREV_USED;
+ the_heap->final = new_final;
+
+ stats->size += size;
+ stats->used_blocks += 1;
+ stats->frees -= 1; /* Don't count subsequent call as actual free() */
+
+ _Heap_Free( the_heap, _Heap_User_area( old_final ) );
+
+ return HEAP_EXTEND_SUCCESSFUL;
+}
diff --git a/cpukit/score/src/heapfree.c b/cpukit/score/src/heapfree.c
new file mode 100644
index 0000000000..e0e2e72d85
--- /dev/null
+++ b/cpukit/score/src/heapfree.c
@@ -0,0 +1,132 @@
+/*
+ * Heap Handler
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/heap.h>
+
+/*PAGE
+ *
+ * _Heap_Free
+ *
+ * This kernel routine returns the memory designated by the
+ * given heap and given starting address to the memory pool.
+ *
+ * Input parameters:
+ * the_heap - pointer to heap header
+ * starting_address - starting address of the memory block to free.
+ *
+ * Output parameters:
+ * TRUE - if starting_address is valid heap address
+ * FALSE - if starting_address is invalid heap address
+ */
+
+boolean _Heap_Free(
+ Heap_Control *the_heap,
+ void *starting_address
+)
+{
+ Heap_Block *the_block;
+ Heap_Block *next_block;
+ uint32_t the_size;
+ uint32_t next_size;
+ Heap_Statistics *const stats = &the_heap->stats;
+ boolean next_is_free;
+
+ _Heap_Start_of_block( the_heap, starting_address, &the_block );
+
+ if ( !_Heap_Is_block_in( the_heap, the_block ) ) {
+ _HAssert(starting_address == NULL);
+ _HAssert(FALSE);
+ return( FALSE );
+ }
+
+ the_size = _Heap_Block_size( the_block );
+ next_block = _Heap_Block_at( the_block, the_size );
+
+ if ( !_Heap_Is_block_in( the_heap, next_block ) ) {
+ _HAssert(FALSE);
+ return( FALSE );
+ }
+
+ if ( !_Heap_Is_prev_used( next_block ) ) {
+ _HAssert(FALSE);
+ return( FALSE );
+ }
+
+ next_size = _Heap_Block_size( next_block );
+ next_is_free = next_block < the_heap->final &&
+ !_Heap_Is_prev_used(_Heap_Block_at(next_block, next_size));
+
+ if ( !_Heap_Is_prev_used( the_block ) ) {
+ uint32_t const prev_size = the_block->prev_size;
+ Heap_Block *const prev_block = _Heap_Block_at( the_block, -prev_size );
+
+ if ( !_Heap_Is_block_in( the_heap, prev_block ) ) {
+ _HAssert(FALSE);
+ return( FALSE );
+ }
+
+ /* As we always coalesce free blocks, the block that preceedes prev_block
+ must have been used. */
+ if ( !_Heap_Is_prev_used ( prev_block) ) {
+ _HAssert(FALSE);
+ return( FALSE );
+ }
+
+ if ( next_is_free ) { /* coalesce both */
+ uint32_t const size = the_size + prev_size + next_size;
+ _Heap_Block_remove( next_block );
+ stats->free_blocks -= 1;
+ prev_block->size = size | HEAP_PREV_USED;
+ next_block = _Heap_Block_at( prev_block, size );
+ _HAssert(!_Heap_Is_prev_used( next_block));
+ next_block->prev_size = size;
+ }
+ else { /* coalesce prev */
+ uint32_t const size = the_size + prev_size;
+ prev_block->size = size | HEAP_PREV_USED;
+ next_block->size &= ~HEAP_PREV_USED;
+ next_block->prev_size = size;
+ }
+ }
+ else if ( next_is_free ) { /* coalesce next */
+ uint32_t const size = the_size + next_size;
+ _Heap_Block_replace( next_block, the_block );
+ the_block->size = size | HEAP_PREV_USED;
+ next_block = _Heap_Block_at( the_block, size );
+ next_block->prev_size = size;
+ }
+ else { /* no coalesce */
+ /* Add 'the_block' to the head of the free blocks list as it tends to
+ produce less fragmentation than adding to the tail. */
+ _Heap_Block_insert_after( _Heap_Head( the_heap), the_block );
+ the_block->size = the_size | HEAP_PREV_USED;
+ next_block->size &= ~HEAP_PREV_USED;
+ next_block->prev_size = the_size;
+
+ stats->free_blocks += 1;
+ if ( stats->max_free_blocks < stats->free_blocks )
+ stats->max_free_blocks = stats->free_blocks;
+ }
+
+ stats->used_blocks -= 1;
+ stats->free_size += the_size;
+ stats->frees += 1;
+
+ return( TRUE );
+}
diff --git a/cpukit/score/src/heapgetfreeinfo.c b/cpukit/score/src/heapgetfreeinfo.c
new file mode 100644
index 0000000000..b53931414b
--- /dev/null
+++ b/cpukit/score/src/heapgetfreeinfo.c
@@ -0,0 +1,63 @@
+/*
+ * Heap Handler
+ *
+ * COPYRIGHT (c) 1989-2004.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/heap.h>
+
+/*PAGE
+ *
+ * _Heap_Get_free_information
+ *
+ * This heap routine returns information about the free blocks
+ * in the specified heap.
+ *
+ * Input parameters:
+ * the_heap - pointer to heap header.
+ * info - pointer to the free block information.
+ *
+ * Output parameters:
+ * returns - free block information filled in.
+ */
+
+void _Heap_Get_free_information(
+ Heap_Control *the_heap,
+ Heap_Information *info
+)
+{
+ Heap_Block *the_block;
+ Heap_Block *const tail = _Heap_Tail(the_heap);
+
+ info->number = 0;
+ info->largest = 0;
+ info->total = 0;
+
+ for(the_block = _Heap_First(the_heap);
+ the_block != tail;
+ the_block = the_block->next)
+ {
+ uint32_t const the_size = _Heap_Block_size(the_block);
+
+ /* As we always coalesce free blocks, prev block must have been used. */
+ _HAssert(_Heap_Is_prev_used(the_block));
+
+ info->number++;
+ info->total += the_size;
+ if ( info->largest < the_size )
+ info->largest = the_size;
+ }
+}
diff --git a/cpukit/score/src/heapgetinfo.c b/cpukit/score/src/heapgetinfo.c
new file mode 100644
index 0000000000..525b790d07
--- /dev/null
+++ b/cpukit/score/src/heapgetinfo.c
@@ -0,0 +1,83 @@
+/*
+ * Heap Handler
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/heap.h>
+
+/*PAGE
+ *
+ * _Heap_Get_information
+ *
+ * This kernel routine walks the heap and tots up the free and allocated
+ * sizes. Derived from _Heap_Walk.
+ *
+ * Input parameters:
+ * the_heap - pointer to heap header
+ * the_info - pointer for information to be returned
+ *
+ * Output parameters:
+ * *the_info - contains information about heap
+ * return 0=success, otherwise heap is corrupt.
+ */
+
+Heap_Get_information_status _Heap_Get_information(
+ Heap_Control *the_heap,
+ Heap_Information_block *the_info
+)
+{
+ Heap_Block *the_block = the_heap->start;
+ Heap_Block *const end = the_heap->final;
+
+ _HAssert(the_block->prev_size == HEAP_PREV_USED);
+ _HAssert(_Heap_Is_prev_used(the_block));
+
+ the_info->Free.number = 0;
+ the_info->Free.total = 0;
+ the_info->Free.largest = 0;
+ the_info->Used.number = 0;
+ the_info->Used.total = 0;
+ the_info->Used.largest = 0;
+
+ while ( the_block != end ) {
+ uint32_t const the_size = _Heap_Block_size(the_block);
+ Heap_Block *const next_block = _Heap_Block_at(the_block, the_size);
+
+ if ( _Heap_Is_prev_used(next_block) ) {
+ the_info->Used.number++;
+ the_info->Used.total += the_size;
+ if ( the_info->Used.largest < the_size )
+ the_info->Used.largest = the_size;
+ } else {
+ the_info->Free.number++;
+ the_info->Free.total += the_size;
+ if ( the_info->Free.largest < the_size )
+ the_info->Free.largest = the_size;
+ if ( the_size != next_block->prev_size )
+ return HEAP_GET_INFORMATION_BLOCK_ERROR;
+ }
+
+ the_block = next_block;
+ }
+
+ /* Handle the last dummy block. Don't consider this block to be
+ "used" as client never allocated it. Make 'Used.total' contain this
+ blocks' overhead though. */
+ the_info->Used.total += HEAP_OVERHEAD;
+
+ return HEAP_GET_INFORMATION_SUCCESSFUL;
+}
diff --git a/cpukit/score/src/heapresizeblock.c b/cpukit/score/src/heapresizeblock.c
new file mode 100644
index 0000000000..661ef20b51
--- /dev/null
+++ b/cpukit/score/src/heapresizeblock.c
@@ -0,0 +1,170 @@
+/*
+ * Heap Handler
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/heap.h>
+
+/*
+ * _Heap_Resize_block
+ *
+ * DESCRIPTION:
+ *
+ * This routine tries to resize in place the block that is pointed to by the
+ * 'starting_address' to the new 'size'.
+ *
+ * Input parameters:
+ * the_heap - pointer to heap header
+ * starting_address - starting address of the memory block
+ * size - new size
+ *
+ * Output parameters:
+ * 'old_mem_size' - the size of the user memory area of the block before
+ * resizing.
+ * 'avail_mem_size' - the size of the user memory area of the free block
+ * that has been enlarged or created due to resizing,
+ * 0 if none.
+ * Returns
+ * HEAP_RESIZE_SUCCESSFUL - if success
+ * HEAP_RESIZE_UNSATISFIED - if the block can't be resized in place
+ * HEAP_RESIZE_FATAL_ERROR - if failure
+ */
+
+Heap_Resize_status _Heap_Resize_block(
+ Heap_Control *the_heap,
+ void *starting_address,
+ uint32_t size,
+ uint32_t *old_mem_size,
+ uint32_t *avail_mem_size
+)
+{
+ Heap_Block *the_block;
+ Heap_Block *next_block;
+ uint32_t next_block_size;
+ boolean next_is_used;
+ Heap_Block *next_next_block;
+ uint32_t old_block_size;
+ uint32_t old_user_size;
+ uint32_t prev_used_flag;
+ Heap_Statistics *const stats = &the_heap->stats;
+ uint32_t const min_block_size = the_heap->min_block_size;
+ uint32_t const page_size = the_heap->page_size;
+
+ *old_mem_size = 0;
+ *avail_mem_size = 0;
+
+ _Heap_Start_of_block(the_heap, starting_address, &the_block);
+ _HAssert(_Heap_Is_block_in(the_heap, the_block));
+ if (!_Heap_Is_block_in(the_heap, the_block))
+ return HEAP_RESIZE_FATAL_ERROR;
+
+ prev_used_flag = the_block->size & HEAP_PREV_USED;
+ old_block_size = _Heap_Block_size(the_block);
+ next_block = _Heap_Block_at(the_block, old_block_size);
+
+ _HAssert(_Heap_Is_block_in(the_heap, next_block));
+ _HAssert(_Heap_Is_prev_used(next_block));
+ if ( !_Heap_Is_block_in(the_heap, next_block) ||
+ !_Heap_Is_prev_used(next_block))
+ return HEAP_RESIZE_FATAL_ERROR;
+
+ next_block_size = _Heap_Block_size(next_block);
+ next_next_block = _Heap_Block_at(next_block, next_block_size);
+ next_is_used = (next_block == the_heap->final) ||
+ _Heap_Is_prev_used(next_next_block);
+
+ /* See _Heap_Size_of_user_area() source for explanations */
+ old_user_size = _Addresses_Subtract(next_block, starting_address)
+ + HEAP_BLOCK_HEADER_OFFSET;
+
+ *old_mem_size = old_user_size;
+
+ if (size > old_user_size) {
+ /* Need to extend the block: allocate part of the next block and then
+ merge 'the_block' and allocated block together. */
+ if (next_is_used) /* Next block is in use, -- no way to extend */
+ return HEAP_RESIZE_UNSATISFIED;
+ else {
+ uint32_t add_block_size = size - old_user_size;
+ _Heap_Align_up(&add_block_size, page_size);
+ if (add_block_size < min_block_size)
+ add_block_size = min_block_size;
+ if (add_block_size > next_block_size)
+ return HEAP_RESIZE_UNSATISFIED; /* Next block is too small or none. */
+ add_block_size =
+ _Heap_Block_allocate(the_heap, next_block, add_block_size);
+ /* Merge two subsequent blocks */
+ the_block->size = (old_block_size + add_block_size) | prev_used_flag;
+ --stats->used_blocks;
+ }
+ } else {
+
+ /* Calculate how much memory we could free */
+ uint32_t free_block_size = old_user_size - size;
+ _Heap_Align_down(&free_block_size, page_size);
+
+ if (free_block_size > 0) {
+
+ /* To free some memory the block should be shortened so that it can
+ can hold 'size' user bytes and still remain not shorter than
+ 'min_block_size'. */
+
+ uint32_t new_block_size = old_block_size - free_block_size;
+
+ if (new_block_size < min_block_size) {
+ uint32_t delta = min_block_size - new_block_size;
+ _HAssert(free_block_size >= delta);
+ free_block_size -= delta;
+ if (free_block_size == 0) {
+ ++stats->resizes;
+ return HEAP_RESIZE_SUCCESSFUL;
+ }
+ new_block_size += delta;
+ }
+
+ _HAssert(new_block_size >= min_block_size);
+ _HAssert(new_block_size + free_block_size == old_block_size);
+ _HAssert(_Heap_Is_aligned(new_block_size, page_size));
+ _HAssert(_Heap_Is_aligned(free_block_size, page_size));
+
+ if (!next_is_used) {
+ /* Extend the next block to the low addresses by 'free_block_size' */
+ Heap_Block *const new_next_block =
+ _Heap_Block_at(the_block, new_block_size);
+ uint32_t const new_next_block_size =
+ next_block_size + free_block_size;
+ _HAssert(_Heap_Is_block_in(the_heap, next_next_block));
+ the_block->size = new_block_size | prev_used_flag;
+ new_next_block->size = new_next_block_size | HEAP_PREV_USED;
+ next_next_block->prev_size = new_next_block_size;
+ _Heap_Block_replace(next_block, new_next_block);
+ the_heap->stats.free_size += free_block_size;
+ *avail_mem_size = new_next_block_size - HEAP_BLOCK_USED_OVERHEAD;
+
+ } else if (free_block_size >= min_block_size) {
+ /* Split the block into 2 used parts, then free the second one. */
+ the_block->size = new_block_size | prev_used_flag;
+ next_block = _Heap_Block_at(the_block, new_block_size);
+ next_block->size = free_block_size | HEAP_PREV_USED;
+ ++stats->used_blocks; /* We have created used block */
+ --stats->frees; /* Don't count next call in stats */
+ _Heap_Free(the_heap, _Heap_User_area(next_block));
+ *avail_mem_size = free_block_size - HEAP_BLOCK_USED_OVERHEAD;
+ }
+ }
+ }
+
+ ++stats->resizes;
+ return HEAP_RESIZE_SUCCESSFUL;
+}
diff --git a/cpukit/score/src/heapsizeofuserarea.c b/cpukit/score/src/heapsizeofuserarea.c
new file mode 100644
index 0000000000..9b075e5433
--- /dev/null
+++ b/cpukit/score/src/heapsizeofuserarea.c
@@ -0,0 +1,87 @@
+/*
+ * Heap Handler
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/heap.h>
+
+/*PAGE
+ *
+ * _Heap_Size_of_user_area
+ *
+ * This kernel routine sets '*size' to the size of the block of memory
+ * which begins at 'starting_address'.
+ * It returns TRUE if the 'starting_address' is in the heap, and FALSE
+ * otherwise.
+ *
+ * Input parameters:
+ * the_heap - pointer to heap header
+ * starting_address - starting address of the memory block
+ * size - pointer to size of area
+ *
+ * Output parameters:
+ * size - size of area filled in
+ * TRUE - if starting_address is valid heap address
+ * FALSE - if starting_address is invalid heap address
+ */
+
+boolean _Heap_Size_of_user_area(
+ Heap_Control *the_heap,
+ void *starting_address,
+ size_t *size
+)
+{
+ Heap_Block *the_block;
+ Heap_Block *next_block;
+ uint32_t the_size;
+
+ if ( !_Addresses_Is_in_range(
+ starting_address, (void *)the_heap->start, (void *)the_heap->final ) )
+ return( FALSE );
+
+ _Heap_Start_of_block( the_heap, starting_address, &the_block );
+
+ _HAssert(_Heap_Is_block_in( the_heap, the_block ));
+ if ( !_Heap_Is_block_in( the_heap, the_block ) )
+ return( FALSE );
+
+ the_size = _Heap_Block_size( the_block );
+ next_block = _Heap_Block_at( the_block, the_size );
+
+ _HAssert(_Heap_Is_block_in( the_heap, next_block ));
+ _HAssert(_Heap_Is_prev_used( next_block ));
+ if (
+ !_Heap_Is_block_in( the_heap, next_block ) ||
+ !_Heap_Is_prev_used( next_block )
+ )
+ return( FALSE );
+
+ /* 'starting_address' could be greater than 'the_block' address plus
+ HEAP_BLOCK_USER_OFFSET as _Heap_Allocate_aligned() may produce such user
+ pointers. To get rid of this offset we calculate user size as difference
+ between the end of 'the_block' (='next_block') and 'starting_address'
+ and then add correction equal to the offset of the 'size' field of the
+ 'Heap_Block' structure. The correction is due to the fact that
+ 'prev_size' field of the next block is actually used as user accessible
+ area of 'the_block'. */
+
+ *size = _Addresses_Subtract ( next_block, starting_address )
+ + HEAP_BLOCK_HEADER_OFFSET;
+
+ return( TRUE );
+}
+
diff --git a/cpukit/score/src/heapwalk.c b/cpukit/score/src/heapwalk.c
new file mode 100644
index 0000000000..b85529cf9d
--- /dev/null
+++ b/cpukit/score/src/heapwalk.c
@@ -0,0 +1,176 @@
+/*
+ * Heap Handler
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/heap.h>
+
+/*PAGE
+ *
+ * _Heap_Walk
+ *
+ * This kernel routine walks the heap and verifies its correctness.
+ *
+ * Input parameters:
+ * the_heap - pointer to heap header
+ * source - a numeric indicator of the invoker of this routine
+ * do_dump - when TRUE print the information
+ *
+ * Output parameters: NONE
+ */
+
+#if !defined(RTEMS_HEAP_DEBUG)
+
+boolean _Heap_Walk(
+ Heap_Control *the_heap,
+ int source,
+ boolean do_dump
+)
+{
+ return TRUE;
+}
+
+#else /* defined(RTEMS_HEAP_DEBUG) */
+
+#include <stdio.h>
+
+boolean _Heap_Walk(
+ Heap_Control *the_heap,
+ int source,
+ boolean do_dump
+)
+{
+ Heap_Block *the_block = the_heap->start;
+ Heap_Block *const end = the_heap->final;
+ Heap_Block *const tail = _Heap_Tail(the_heap);
+ int error = 0;
+ int passes = 0;
+
+ /*
+ * We don't want to allow walking the heap until we have
+ * transferred control to the user task so we watch the
+ * system state.
+ */
+
+ if ( !_System_state_Is_up( _System_state_Get() ) )
+ return FALSE;
+
+ if (source < 0)
+ source = the_heap->stats.instance;
+
+ if (do_dump == TRUE)
+ printf("\nPASS: %d start %p final %p first %p last %p begin %p end %p\n",
+ source, the_block, end,
+ _Heap_First(the_heap), _Heap_Last(the_heap),
+ the_heap->begin, the_heap->end);
+
+ /*
+ * Handle the 1st block
+ */
+
+ if (!_Heap_Is_prev_used(the_block)) {
+ printf("PASS: %d !HEAP_PREV_USED flag of 1st block isn't set\n", source);
+ error = 1;
+ }
+
+ if (the_block->prev_size != the_heap->page_size) {
+ printf("PASS: %d !prev_size of 1st block isn't page_size\n", source);
+ error = 1;
+ }
+
+ while ( the_block < end ) {
+ uint32_t const the_size = _Heap_Block_size(the_block);
+ Heap_Block *const next_block = _Heap_Block_at(the_block, the_size);
+ boolean prev_used = _Heap_Is_prev_used(the_block);
+
+ if (do_dump) {
+ printf("PASS: %d block %p size %d(%c)",
+ source, the_block, the_size, (prev_used ? 'U' : 'F'));
+ if (prev_used)
+ printf(" prev_size %d", the_block->prev_size);
+ else
+ printf(" (prev_size) %d", the_block->prev_size);
+ }
+
+ if (!_Heap_Is_block_in(the_heap, next_block)) {
+ if (do_dump) printf("\n");
+ printf("PASS: %d !block %p is out of heap\n", source, next_block);
+ error = 1;
+ break;
+ }
+
+ if (!_Heap_Is_prev_used(next_block)) {
+ if (do_dump)
+ printf( " prev %p next %p", the_block->prev, the_block->next);
+ if (_Heap_Block_size(the_block) != next_block->prev_size) {
+ if (do_dump) printf("\n");
+ printf("PASS: %d !front and back sizes don't match", source);
+ error = 1;
+ }
+ if (!prev_used) {
+ if (do_dump || error) printf("\n");
+ printf("PASS: %d !two consecutive blocks are free", source);
+ error = 1;
+ }
+
+ { /* Check if 'the_block' is in the free block list */
+ Heap_Block* block = _Heap_First(the_heap);
+ while(block != the_block && block != tail)
+ block = block->next;
+ if(block != the_block) {
+ if (do_dump || error) printf("\n");
+ printf("PASS: %d !the_block not in the free list", source);
+ error = 1;
+ }
+ }
+
+ }
+ if (do_dump || error) printf("\n");
+
+ if (the_size < the_heap->min_block_size) {
+ printf("PASS: %d !block size is too small\n", source);
+ error = 1;
+ break;
+ }
+ if (!_Heap_Is_aligned( the_size, the_heap->page_size)) {
+ printf("PASS: %d !block size is misaligned\n", source);
+ error = 1;
+ }
+
+ if (++passes > (do_dump ? 10 : 0) && error)
+ break;
+
+ the_block = next_block;
+ }
+
+ if (the_block != end) {
+ printf("PASS: %d !last block address isn't equal to 'final'\n", source);
+ error = 1;
+ }
+
+ if (_Heap_Block_size(the_block) != the_heap->page_size) {
+ printf("PASS: %d !last block's size isn't page_size\n", source);
+ error = 1;
+ }
+
+ if(do_dump && error)
+ abort();
+
+ return error == 0;
+
+}
+#endif /* defined(RTEMS_HEAP_DEBUG) */
diff --git a/cpukit/score/src/interr.c b/cpukit/score/src/interr.c
new file mode 100644
index 0000000000..90ebafdf21
--- /dev/null
+++ b/cpukit/score/src/interr.c
@@ -0,0 +1,64 @@
+/*
+ * Internal Error Handler
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/userext.h>
+
+/*PAGE
+ *
+ * _Internal_error_Occurred
+ *
+ * This routine will invoke the fatal error handler supplied by the user
+ * followed by the the default one provided by the executive. The default
+ * error handler assumes no hardware is present to help inform the user
+ * of the problem. Halt stores the error code in a known register,
+ * disables interrupts, and halts the CPU. If the CPU does not have a
+ * halt instruction, it will loop to itself.
+ *
+ * Input parameters:
+ * the_source - what subsystem the error originated in
+ * is_internal - if the error was internally generated
+ * the_error - fatal error status code
+ *
+ * Output parameters:
+ * As much information as possible is stored in a CPU dependent fashion.
+ * See the CPU dependent code for more information.
+ *
+ * NOTE: The the_error is not necessarily a directive status code.
+ */
+
+void _Internal_error_Occurred(
+ Internal_errors_Source the_source,
+ boolean is_internal,
+ uint32_t the_error
+)
+{
+
+ Internal_errors_What_happened.the_source = the_source;
+ Internal_errors_What_happened.is_internal = is_internal;
+ Internal_errors_What_happened.the_error = the_error;
+
+ _User_extensions_Fatal( the_source, is_internal, the_error );
+
+ _System_state_Set( SYSTEM_STATE_FAILED );
+
+ _CPU_Fatal_halt( the_error );
+
+ /* will not return from this routine */
+}
diff --git a/cpukit/score/src/isr.c b/cpukit/score/src/isr.c
new file mode 100644
index 0000000000..af7ebbfba7
--- /dev/null
+++ b/cpukit/score/src/isr.c
@@ -0,0 +1,69 @@
+/*
+ * ISR Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/wkspace.h>
+
+/* _ISR_Handler_initialization
+ *
+ * This routine initializes the ISR handler.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _ISR_Handler_initialization( void )
+{
+ _ISR_Signals_to_thread_executing = FALSE;
+
+ _ISR_Nest_level = 0;
+
+ _ISR_Vector_table = _Workspace_Allocate_or_fatal_error(
+ sizeof(ISR_Handler_entry) * ISR_NUMBER_OF_VECTORS
+ );
+
+ _CPU_Initialize_vectors();
+
+#if ( CPU_ALLOCATE_INTERRUPT_STACK == TRUE )
+
+ if ( _CPU_Table.interrupt_stack_size < STACK_MINIMUM_SIZE )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL
+ );
+
+ _CPU_Interrupt_stack_low =
+ _Workspace_Allocate_or_fatal_error( _CPU_Table.interrupt_stack_size );
+
+ _CPU_Interrupt_stack_high = _Addresses_Add_offset(
+ _CPU_Interrupt_stack_low,
+ _CPU_Table.interrupt_stack_size
+ );
+
+#endif
+
+#if ( CPU_HAS_HARDWARE_INTERRUPT_STACK == TRUE )
+ _CPU_Install_interrupt_stack();
+#endif
+
+}
diff --git a/cpukit/score/src/iterateoverthreads.c b/cpukit/score/src/iterateoverthreads.c
new file mode 100644
index 0000000000..3841a45dfd
--- /dev/null
+++ b/cpukit/score/src/iterateoverthreads.c
@@ -0,0 +1,50 @@
+/*
+ * rtems_iterate_over_all_threads
+ *
+ * This function operates by as follows:
+ * for all threads
+ * invoke specified function
+ *
+ * COPYRIGHT (c) 1989-2003.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+
+void rtems_iterate_over_all_threads(rtems_per_thread_routine routine)
+{
+ uint32_t i;
+ uint32_t api_index;
+ Thread_Control *the_thread;
+ Objects_Information *information;
+
+ for ( api_index = 1 ;
+ api_index <= OBJECTS_APIS_LAST ;
+ api_index++ ) {
+ if ( !_Objects_Information_table[ api_index ] )
+ continue;
+ information = _Objects_Information_table[ api_index ][ 1 ];
+ if ( information ) {
+ for ( i=1 ; i <= information->maximum ; i++ ) {
+ the_thread = (Thread_Control *)information->local_table[ i ];
+
+ if ( !the_thread )
+ continue;
+
+ (*routine)(the_thread);
+ }
+ }
+ }
+
+}
diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c
new file mode 100644
index 0000000000..58f99c81e9
--- /dev/null
+++ b/cpukit/score/src/mpci.c
@@ -0,0 +1,528 @@
+/*
+ * Multiprocessing Communications Interface (MPCI) Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/cpu.h>
+#include <rtems/score/interr.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#include <rtems/score/mppkt.h>
+#endif
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/score/sysstate.h>
+
+#include <rtems/score/coresem.h>
+
+/*PAGE
+ *
+ * _MPCI_Handler_initialization
+ *
+ * This subprogram performs the initialization necessary for this handler.
+ */
+
+void _MPCI_Handler_initialization(
+ MPCI_Control *users_mpci_table,
+ uint32_t timeout_status
+)
+{
+ CORE_semaphore_Attributes attributes;
+
+ if ( _System_state_Is_multiprocessing && !users_mpci_table )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_NO_MPCI
+ );
+
+ _MPCI_table = users_mpci_table;
+
+ if ( !_System_state_Is_multiprocessing )
+ return;
+
+ /*
+ * Register the MP Process Packet routine.
+ */
+
+ _MPCI_Register_packet_processor(
+ MP_PACKET_MPCI_INTERNAL,
+ _MPCI_Internal_packets_Process_packet
+ );
+
+ /*
+ * Create the counting semaphore used by the MPCI Receive Server.
+ */
+
+ attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
+
+ _CORE_semaphore_Initialize(
+ &_MPCI_Semaphore,
+ &attributes, /* the_semaphore_attributes */
+ 0 /* initial_value */
+ );
+
+ _Thread_queue_Initialize(
+ &_MPCI_Remote_blocked_threads,
+ THREAD_QUEUE_DISCIPLINE_FIFO,
+ STATES_WAITING_FOR_RPC_REPLY,
+ timeout_status
+ );
+}
+
+/*PAGE
+ *
+ * _MPCI_Create_server
+ *
+ * This subprogram creates the MPCI receive server.
+ */
+
+char *_MPCI_Internal_name = "MPCI";
+
+void _MPCI_Create_server( void )
+{
+
+ if ( !_System_state_Is_multiprocessing )
+ return;
+
+ /*
+ * Initialize the MPCI Receive Server
+ */
+
+ _MPCI_Receive_server_tcb = _Thread_Internal_allocate();
+
+ _Thread_Initialize(
+ &_Thread_Internal_information,
+ _MPCI_Receive_server_tcb,
+ NULL, /* allocate the stack */
+ MPCI_RECEIVE_SERVER_STACK_SIZE,
+ CPU_ALL_TASKS_ARE_FP,
+ PRIORITY_MINIMUM,
+ FALSE, /* no preempt */
+ THREAD_CPU_BUDGET_ALGORITHM_NONE,
+ NULL, /* no budget algorithm callout */
+ 0, /* all interrupts enabled */
+ _MPCI_Internal_name
+ );
+
+ _Thread_Start(
+ _MPCI_Receive_server_tcb,
+ THREAD_START_NUMERIC,
+ (void *) _MPCI_Receive_server,
+ NULL,
+ 0
+ );
+}
+
+/*PAGE
+ *
+ * _MPCI_Initialization
+ *
+ * This subprogram initializes the MPCI driver by
+ * invoking the user provided MPCI initialization callout.
+ */
+
+void _MPCI_Initialization ( void )
+{
+ (*_MPCI_table->initialization)();
+}
+
+/*PAGE
+ *
+ * _MPCI_Register_packet_processor
+ *
+ * This routine registers the MPCI packet processor for the
+ * designated object class.
+ */
+
+void _MPCI_Register_packet_processor(
+ MP_packet_Classes the_class,
+ MPCI_Packet_processor the_packet_processor
+
+)
+{
+ _MPCI_Packet_processors[ the_class ] = the_packet_processor;
+}
+
+/*PAGE
+ *
+ * _MPCI_Get_packet
+ *
+ * This subprogram obtains a packet by invoking the user provided
+ * MPCI get packet callout.
+ */
+
+MP_packet_Prefix *_MPCI_Get_packet ( void )
+{
+ MP_packet_Prefix *the_packet;
+
+ (*_MPCI_table->get_packet)( &the_packet );
+
+ if ( the_packet == NULL )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_OUT_OF_PACKETS
+ );
+
+ /*
+ * Put in a default timeout that will be used for
+ * all packets that do not otherwise have a timeout.
+ */
+
+ the_packet->timeout = MPCI_DEFAULT_TIMEOUT;
+
+ return the_packet;
+}
+
+/*PAGE
+ *
+ * _MPCI_Return_packet
+ *
+ * This subprogram returns a packet by invoking the user provided
+ * MPCI return packet callout.
+ */
+
+void _MPCI_Return_packet (
+ MP_packet_Prefix *the_packet
+)
+{
+ (*_MPCI_table->return_packet)( the_packet );
+}
+
+/*PAGE
+ *
+ * _MPCI_Send_process_packet
+ *
+ * This subprogram sends a process packet by invoking the user provided
+ * MPCI send callout.
+ */
+
+void _MPCI_Send_process_packet (
+ uint32_t destination,
+ MP_packet_Prefix *the_packet
+)
+{
+ the_packet->source_tid = _Thread_Executing->Object.id;
+ the_packet->to_convert =
+ ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) /
+ sizeof(uint32_t );
+
+ (*_MPCI_table->send_packet)( destination, the_packet );
+}
+
+/*PAGE
+ *
+ * _MPCI_Send_request_packet
+ *
+ * This subprogram sends a request packet by invoking the user provided
+ * MPCI send callout.
+ */
+
+uint32_t _MPCI_Send_request_packet (
+ uint32_t destination,
+ MP_packet_Prefix *the_packet,
+ States_Control extra_state
+)
+{
+ the_packet->source_tid = _Thread_Executing->Object.id;
+ the_packet->source_priority = _Thread_Executing->current_priority;
+ the_packet->to_convert =
+ ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) /
+ sizeof(uint32_t );
+
+ _Thread_Executing->Wait.id = the_packet->id;
+
+ _Thread_Executing->Wait.queue = &_MPCI_Remote_blocked_threads;
+
+ _Thread_Disable_dispatch();
+
+ (*_MPCI_table->send_packet)( destination, the_packet );
+
+ _Thread_queue_Enter_critical_section( &_MPCI_Remote_blocked_threads );
+
+ /*
+ * See if we need a default timeout
+ */
+
+ if (the_packet->timeout == MPCI_DEFAULT_TIMEOUT)
+ the_packet->timeout = _MPCI_table->default_timeout;
+
+ _Thread_queue_Enqueue( &_MPCI_Remote_blocked_threads, the_packet->timeout );
+
+ _Thread_Executing->current_state =
+ _States_Set( extra_state, _Thread_Executing->current_state );
+
+ _Thread_Enable_dispatch();
+
+ return _Thread_Executing->Wait.return_code;
+}
+
+/*PAGE
+ *
+ * _MPCI_Send_response_packet
+ *
+ * This subprogram sends a response packet by invoking the user provided
+ * MPCI send callout.
+ */
+
+void _MPCI_Send_response_packet (
+ uint32_t destination,
+ MP_packet_Prefix *the_packet
+)
+{
+ the_packet->source_tid = _Thread_Executing->Object.id;
+
+ (*_MPCI_table->send_packet)( destination, the_packet );
+}
+
+/*PAGE
+ *
+ * _MPCI_Receive_packet
+ *
+ * This subprogram receives a packet by invoking the user provided
+ * MPCI receive callout.
+ */
+
+MP_packet_Prefix *_MPCI_Receive_packet ( void )
+{
+ MP_packet_Prefix *the_packet;
+
+ (*_MPCI_table->receive_packet)( &the_packet );
+
+ return the_packet;
+}
+
+/*PAGE
+ *
+ * _MPCI_Process_response
+ *
+ * This subprogram obtains a packet by invoking the user provided
+ * MPCI get packet callout.
+ */
+
+Thread_Control *_MPCI_Process_response (
+ MP_packet_Prefix *the_packet
+)
+{
+ Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _Thread_Get( the_packet->id, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE:
+ the_thread = NULL; /* IMPOSSIBLE */
+ break;
+ case OBJECTS_LOCAL:
+ _Thread_queue_Extract( &_MPCI_Remote_blocked_threads, the_thread );
+ the_thread->Wait.return_code = the_packet->return_code;
+ _Thread_Unnest_dispatch();
+ break;
+ }
+
+ return the_thread;
+}
+
+/*PAGE
+ *
+ * _MPCI_Receive_server
+ *
+ */
+
+Thread _MPCI_Receive_server(
+ uint32_t ignored
+)
+{
+
+ MP_packet_Prefix *the_packet;
+ MPCI_Packet_processor the_function;
+ Thread_Control *executing;
+
+ executing = _Thread_Executing;
+
+ for ( ; ; ) {
+
+ executing->receive_packet = NULL;
+
+ _Thread_Disable_dispatch();
+ _CORE_semaphore_Seize( &_MPCI_Semaphore, 0, TRUE, WATCHDOG_NO_TIMEOUT );
+ _Thread_Enable_dispatch();
+
+ for ( ; ; ) {
+ the_packet = _MPCI_Receive_packet();
+
+ if ( !the_packet )
+ break;
+
+ executing->receive_packet = the_packet;
+
+ if ( !_Mp_packet_Is_valid_packet_class ( the_packet->the_class ) )
+ break;
+
+ the_function = _MPCI_Packet_processors[ the_packet->the_class ];
+
+ if ( !the_function )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_BAD_PACKET
+ );
+
+ (*the_function)( the_packet );
+ }
+ }
+
+ return 0; /* unreached - only to remove warnings */
+}
+
+/*PAGE
+ *
+ * _MPCI_Announce
+ *
+ */
+
+void _MPCI_Announce ( void )
+{
+ _Thread_Disable_dispatch();
+ (void) _CORE_semaphore_Surrender( &_MPCI_Semaphore, 0, 0 );
+ _Thread_Enable_dispatch();
+}
+
+/*PAGE
+ *
+ * _MPCI_Internal_packets_Send_process_packet
+ *
+ */
+
+void _MPCI_Internal_packets_Send_process_packet (
+ MPCI_Internal_Remote_operations operation
+)
+{
+ MPCI_Internal_packet *the_packet;
+
+ switch ( operation ) {
+
+ case MPCI_PACKETS_SYSTEM_VERIFY:
+
+ the_packet = _MPCI_Internal_packets_Get_packet();
+ the_packet->Prefix.the_class = MP_PACKET_MPCI_INTERNAL;
+ the_packet->Prefix.length = sizeof ( MPCI_Internal_packet );
+ the_packet->Prefix.to_convert = sizeof ( MPCI_Internal_packet );
+ the_packet->operation = operation;
+
+ the_packet->maximum_nodes = _Objects_Maximum_nodes;
+
+ the_packet->maximum_global_objects = _Objects_MP_Maximum_global_objects;
+
+ _MPCI_Send_process_packet( MPCI_ALL_NODES, &the_packet->Prefix );
+ break;
+ }
+}
+
+/*PAGE
+ *
+ * _MPCI_Internal_packets_Send_request_packet
+ *
+ * This subprogram is not needed since there are no request
+ * packets to be sent by this manager.
+ *
+ */
+
+/*PAGE
+ *
+ * _MPCI_Internal_packets_Send_response_packet
+ *
+ * This subprogram is not needed since there are no response
+ * packets to be sent by this manager.
+ *
+ */
+
+/*PAGE
+ *
+ *
+ * _MPCI_Internal_packets_Process_packet
+ *
+ */
+
+void _MPCI_Internal_packets_Process_packet (
+ MP_packet_Prefix *the_packet_prefix
+)
+{
+ MPCI_Internal_packet *the_packet;
+ uint32_t maximum_nodes;
+ uint32_t maximum_global_objects;
+
+ the_packet = (MPCI_Internal_packet *) the_packet_prefix;
+
+ switch ( the_packet->operation ) {
+
+ case MPCI_PACKETS_SYSTEM_VERIFY:
+
+ maximum_nodes = the_packet->maximum_nodes;
+ maximum_global_objects = the_packet->maximum_global_objects;
+ if ( maximum_nodes != _Objects_Maximum_nodes ||
+ maximum_global_objects != _Objects_MP_Maximum_global_objects ) {
+
+ _MPCI_Return_packet( the_packet_prefix );
+
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_INCONSISTENT_MP_INFORMATION
+ );
+ }
+
+ _MPCI_Return_packet( the_packet_prefix );
+
+ break;
+ }
+}
+
+/*PAGE
+ *
+ * _MPCI_Internal_packets_Send_object_was_deleted
+ *
+ * This subprogram is not needed since there are no objects
+ * deleted by this manager.
+ *
+ */
+
+/*PAGE
+ *
+ * _MPCI_Internal_packets_Send_extract_proxy
+ *
+ * This subprogram is not needed since there are no objects
+ * deleted by this manager.
+ *
+ */
+
+/*PAGE
+ *
+ * _MPCI_Internal_packets_Get_packet
+ *
+ */
+
+MPCI_Internal_packet *_MPCI_Internal_packets_Get_packet ( void )
+{
+ return ( (MPCI_Internal_packet *) _MPCI_Get_packet() );
+}
+
+/* end of file */
diff --git a/cpukit/score/src/object.c b/cpukit/score/src/object.c
new file mode 100644
index 0000000000..ba486217a7
--- /dev/null
+++ b/cpukit/score/src/object.c
@@ -0,0 +1,68 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Handler_initialization
+ *
+ * This routine initializes the object handler.
+ *
+ * Input parameters:
+ * node - local node
+ * maximum_nodes - number of nodes in the system
+ * maximum_global_objects - number of configured global objects
+ *
+ * Output parameters: NONE
+ */
+
+void _Objects_Handler_initialization(
+ uint32_t node,
+ uint32_t maximum_nodes,
+ uint32_t maximum_global_objects
+)
+{
+ if ( node < 1 || node > maximum_nodes )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_INVALID_NODE
+ );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _Objects_Local_node = node;
+ _Objects_Maximum_nodes = maximum_nodes;
+
+ _Objects_MP_Handler_initialization(
+ node,
+ maximum_nodes,
+ maximum_global_objects
+ );
+#endif
+}
diff --git a/cpukit/score/src/objectallocate.c b/cpukit/score/src/objectallocate.c
new file mode 100644
index 0000000000..c2a6b5efe2
--- /dev/null
+++ b/cpukit/score/src/objectallocate.c
@@ -0,0 +1,72 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a object control block from
+ * the inactive chain of free object control blocks.
+ */
+
+Objects_Control *_Objects_Allocate(
+ Objects_Information *information
+)
+{
+ Objects_Control *the_object =
+ (Objects_Control *) _Chain_Get( &information->Inactive );
+
+ if ( information->auto_extend ) {
+ /*
+ * If the list is empty then we are out of objects and need to
+ * extend information base.
+ */
+
+ if ( !the_object ) {
+ _Objects_Extend_information( information );
+ the_object = (Objects_Control *) _Chain_Get( &information->Inactive );
+ }
+
+ if ( the_object ) {
+ uint32_t block;
+
+ block = _Objects_Get_index( the_object->id ) -
+ _Objects_Get_index( information->minimum_id );
+ block /= information->allocation_size;
+
+ information->inactive_per_block[ block ]--;
+ information->inactive--;
+ }
+ }
+
+ return the_object;
+}
diff --git a/cpukit/score/src/objectallocatebyindex.c b/cpukit/score/src/objectallocatebyindex.c
new file mode 100644
index 0000000000..1a4ca6da85
--- /dev/null
+++ b/cpukit/score/src/objectallocatebyindex.c
@@ -0,0 +1,77 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Allocate_by_index
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates the object control block
+ * specified by the index from the inactive chain of
+ * free object control blocks.
+ */
+
+Objects_Control *_Objects_Allocate_by_index(
+ Objects_Information *information,
+ uint16_t index,
+ uint16_t sizeof_control
+)
+{
+ Objects_Control *the_object;
+
+ if ( index && information->maximum >= index ) {
+ the_object = information->local_table[ index ];
+ if ( the_object )
+ return NULL;
+
+ /* XXX
+ * This whole section of code needs to be addressed.
+ * + The 0 should be dealt with more properly so we can autoextend.
+ * + The pointer arithmetic is probably too expensive.
+ * + etc.
+ */
+
+ the_object = (Objects_Control *) _Addresses_Add_offset(
+ information->object_blocks[ 0 ],
+ (sizeof_control * (index - 1))
+ );
+ _Chain_Extract( &the_object->Node );
+
+ return the_object;
+ }
+
+ /*
+ * Autoextend will have to be thought out as it applies
+ * to user assigned indices.
+ */
+
+ return NULL;
+}
diff --git a/cpukit/score/src/objectclearname.c b/cpukit/score/src/objectclearname.c
new file mode 100644
index 0000000000..1c90def6fa
--- /dev/null
+++ b/cpukit/score/src/objectclearname.c
@@ -0,0 +1,50 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Clear_name
+ *
+ * This method clears the specified name so that no caller can do a name to
+ * ID/object lookup past this point.
+ */
+
+void _Objects_Clear_name(
+ void *name,
+ uint16_t length
+)
+{
+ uint32_t index;
+ uint32_t maximum = length / OBJECTS_NAME_ALIGNMENT;
+ uint32_t *name_ptr = (uint32_t *) name;
+
+ for ( index=0 ; index < maximum ; index++ )
+ *name_ptr++ = 0;
+}
diff --git a/cpukit/score/src/objectcomparenameraw.c b/cpukit/score/src/objectcomparenameraw.c
new file mode 100644
index 0000000000..870d55d651
--- /dev/null
+++ b/cpukit/score/src/objectcomparenameraw.c
@@ -0,0 +1,61 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Compare_name_raw
+ *
+ * XXX
+ */
+
+boolean _Objects_Compare_name_raw(
+ void *name_1,
+ void *name_2,
+ uint16_t length
+)
+{
+#if 0
+ uint32_t *name_1_p = (uint32_t *) name_1;
+ uint32_t *name_2_p = (uint32_t *) name_2;
+ uint32_t tmp_length = length / OBJECTS_NAME_ALIGNMENT;
+#endif
+
+ if ( name_1 == name_2 )
+ return TRUE;
+ return FALSE;
+
+#if 0
+ while ( tmp_length-- )
+ if ( *name_1_p++ != *name_2_p++ )
+ return FALSE;
+
+ return TRUE;
+#endif
+}
diff --git a/cpukit/score/src/objectcomparenamestring.c b/cpukit/score/src/objectcomparenamestring.c
new file mode 100644
index 0000000000..a9b3be1e7b
--- /dev/null
+++ b/cpukit/score/src/objectcomparenamestring.c
@@ -0,0 +1,57 @@
+/*
+ * Object Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+#include <string.h>
+
+/*PAGE
+ *
+ * _Objects_Compare_name_string
+ *
+ * This routine compares the name of an object with the specified string.
+ *
+ * Input parameters:
+ * name_1 - one name
+ * name_2 - other name
+ * length - maximum length to compare
+ *
+ * Output parameters:
+ * returns - TRUE on a match
+ */
+
+boolean _Objects_Compare_name_string(
+ void *name_1,
+ void *name_2,
+ uint16_t length
+)
+{
+ if ( !strncmp( name_1, name_2, length ) )
+ return TRUE;
+ return FALSE;
+}
diff --git a/cpukit/score/src/objectcopynameraw.c b/cpukit/score/src/objectcopynameraw.c
new file mode 100644
index 0000000000..2a9cd069d6
--- /dev/null
+++ b/cpukit/score/src/objectcopynameraw.c
@@ -0,0 +1,50 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Copy_name_raw
+ *
+ * XXX
+ */
+
+void _Objects_Copy_name_raw(
+ void *source,
+ void *destination,
+ uint16_t length
+)
+{
+ uint32_t *source_p = (uint32_t *) source;
+ uint32_t *destination_p = (uint32_t *) destination;
+ uint32_t tmp_length = length / OBJECTS_NAME_ALIGNMENT;
+
+ while ( tmp_length-- )
+ *destination_p++ = *source_p++;
+}
diff --git a/cpukit/score/src/objectcopynamestring.c b/cpukit/score/src/objectcopynamestring.c
new file mode 100644
index 0000000000..3ae0213b6d
--- /dev/null
+++ b/cpukit/score/src/objectcopynamestring.c
@@ -0,0 +1,53 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Copy_name_string
+ *
+ * XXX
+ */
+
+void _Objects_Copy_name_string(
+ void *source,
+ void *destination,
+ uint16_t length
+)
+{
+ uint8_t *source_p = (uint8_t *) source;
+ uint8_t *destination_p = (uint8_t *) destination;
+
+ *destination_p = '\0';
+ if ( source_p ) {
+ do {
+ *destination_p++ = *source_p;
+ } while ( *source_p++ );
+ }
+}
diff --git a/cpukit/score/src/objectextendinformation.c b/cpukit/score/src/objectextendinformation.c
new file mode 100644
index 0000000000..538ab139bb
--- /dev/null
+++ b/cpukit/score/src/objectextendinformation.c
@@ -0,0 +1,295 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+#include <string.h> /* for memcpy() */
+
+/*PAGE
+ *
+ * _Objects_Extend_information
+ *
+ * This routine extends all object information related data structures.
+ *
+ * Input parameters:
+ * information - object information table
+ *
+ * Output parameters: NONE
+ */
+
+void _Objects_Extend_information(
+ Objects_Information *information
+)
+{
+ Objects_Control *the_object;
+ void *name_area;
+ Chain_Control Inactive;
+ uint32_t block_count;
+ uint32_t block;
+ uint32_t index_base;
+ uint32_t minimum_index;
+ uint32_t index;
+
+ /*
+ * Search for a free block of indexes. The block variable ends up set
+ * to block_count + 1 if the table needs to be extended.
+ */
+
+ minimum_index = _Objects_Get_index( information->minimum_id );
+ index_base = minimum_index;
+ block = 0;
+
+ if ( information->maximum < minimum_index )
+ block_count = 0;
+ else {
+ block_count = information->maximum / information->allocation_size;
+
+ for ( ; block < block_count; block++ ) {
+ if ( information->object_blocks[ block ] == NULL )
+ break;
+ else
+ index_base += information->allocation_size;
+ }
+ }
+
+ /*
+ * If the index_base is the maximum we need to grow the tables.
+ */
+
+ if (index_base >= information->maximum ) {
+ ISR_Level level;
+ void **object_blocks;
+ Objects_Name *name_table;
+ uint32_t *inactive_per_block;
+ Objects_Control **local_table;
+ uint32_t maximum;
+ void *old_tables;
+
+ /*
+ * Growing the tables means allocating a new area, doing a copy and
+ * updating the information table.
+ *
+ * If the maximum is minimum we do not have a table to copy. First
+ * time through.
+ *
+ * The allocation has :
+ *
+ * void *objects[block_count];
+ * uint32_t inactive_count[block_count];
+ * Objects_Name *name_table[block_count];
+ * Objects_Control *local_table[maximum];
+ *
+ * This is the order in memory. Watch changing the order. See the memcpy
+ * below.
+ */
+
+ /*
+ * Up the block count and maximum
+ */
+
+ block_count++;
+
+ maximum = information->maximum + information->allocation_size;
+
+ /*
+ * Allocate the tables and break it up.
+ */
+
+ if ( information->auto_extend ) {
+ object_blocks = (void**)
+ _Workspace_Allocate(
+ block_count *
+ (sizeof(void *) + sizeof(uint32_t ) + sizeof(Objects_Name *)) +
+ ((maximum + minimum_index) * sizeof(Objects_Control *))
+ );
+
+ if ( !object_blocks )
+ return;
+ }
+ else {
+ object_blocks = (void**)
+ _Workspace_Allocate_or_fatal_error(
+ block_count *
+ (sizeof(void *) + sizeof(uint32_t ) + sizeof(Objects_Name *)) +
+ ((maximum + minimum_index) * sizeof(Objects_Control *))
+ );
+ }
+
+ /*
+ * Break the block into the various sections.
+ *
+ */
+
+ inactive_per_block = (uint32_t *) _Addresses_Add_offset(
+ object_blocks, block_count * sizeof(void*) );
+ name_table = (Objects_Name *) _Addresses_Add_offset(
+ inactive_per_block, block_count * sizeof(uint32_t ) );
+ local_table = (Objects_Control **) _Addresses_Add_offset(
+ name_table, block_count * sizeof(Objects_Name *) );
+
+ /*
+ * Take the block count down. Saves all the (block_count - 1)
+ * in the copies.
+ */
+
+ block_count--;
+
+ if ( information->maximum > minimum_index ) {
+
+ /*
+ * Copy each section of the table over. This has to be performed as
+ * separate parts as size of each block has changed.
+ */
+
+ memcpy( object_blocks,
+ information->object_blocks,
+ block_count * sizeof(void*) );
+ memcpy( inactive_per_block,
+ information->inactive_per_block,
+ block_count * sizeof(uint32_t ) );
+ memcpy( name_table,
+ information->name_table,
+ block_count * sizeof(Objects_Name *) );
+ memcpy( local_table,
+ information->local_table,
+ (information->maximum + minimum_index) * sizeof(Objects_Control *) );
+ }
+ else {
+
+ /*
+ * Deal with the special case of the 0 to minimum_index
+ */
+ for ( index = 0; index < minimum_index; index++ ) {
+ local_table[ index ] = NULL;
+ }
+ }
+
+ /*
+ * Initialise the new entries in the table.
+ */
+
+ object_blocks[block_count] = NULL;
+ inactive_per_block[block_count] = 0;
+ name_table[block_count] = NULL;
+
+ for ( index=index_base ;
+ index < ( information->allocation_size + index_base );
+ index++ ) {
+ local_table[ index ] = NULL;
+ }
+
+ _ISR_Disable( level );
+
+ old_tables = information->object_blocks;
+
+ information->object_blocks = object_blocks;
+ information->inactive_per_block = inactive_per_block;
+ information->name_table = name_table;
+ information->local_table = local_table;
+ information->maximum = maximum;
+ information->maximum_id = _Objects_Build_id(
+ information->the_api,
+ information->the_class,
+ _Objects_Local_node,
+ information->maximum
+ );
+
+ _ISR_Enable( level );
+
+ if ( old_tables )
+ _Workspace_Free( old_tables );
+
+ block_count++;
+ }
+
+ /*
+ * Allocate the name table, and the objects
+ */
+
+ if ( information->auto_extend ) {
+ information->object_blocks[ block ] =
+ _Workspace_Allocate(
+ (information->allocation_size * information->name_length) +
+ (information->allocation_size * information->size)
+ );
+
+ if ( !information->object_blocks[ block ] )
+ return;
+ }
+ else {
+ information->object_blocks[ block ] =
+ _Workspace_Allocate_or_fatal_error(
+ (information->allocation_size * information->name_length) +
+ (information->allocation_size * information->size)
+ );
+ }
+
+ name_area = (Objects_Name *) _Addresses_Add_offset(
+ information->object_blocks[ block ],
+ (information->allocation_size * information->size)
+ );
+ information->name_table[ block ] = name_area;
+
+ /*
+ * Initialize objects .. add to a local chain first.
+ */
+
+ _Chain_Initialize(
+ &Inactive,
+ information->object_blocks[ block ],
+ information->allocation_size,
+ information->size
+ );
+
+ /*
+ * Move from the local chain, initialise, then append to the inactive chain
+ */
+
+ index = index_base;
+
+ while ( (the_object = (Objects_Control *) _Chain_Get( &Inactive ) ) != NULL ) {
+
+ the_object->id = _Objects_Build_id(
+ information->the_api,
+ information->the_class,
+ _Objects_Local_node,
+ index
+ );
+
+ the_object->name = (void *) name_area;
+
+ name_area = _Addresses_Add_offset( name_area, information->name_length );
+
+ _Chain_Append( &information->Inactive, &the_object->Node );
+
+ index++;
+ }
+
+ information->inactive_per_block[ block ] = information->allocation_size;
+ information->inactive += information->allocation_size;
+}
diff --git a/cpukit/score/src/objectfree.c b/cpukit/score/src/objectfree.c
new file mode 100644
index 0000000000..af12a0fe8b
--- /dev/null
+++ b/cpukit/score/src/objectfree.c
@@ -0,0 +1,69 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Free
+ *
+ * DESCRIPTION:
+ *
+ * This function frees a object control block to the
+ * inactive chain of free object control blocks.
+ */
+
+void _Objects_Free(
+ Objects_Information *information,
+ Objects_Control *the_object
+)
+{
+ uint32_t allocation_size = information->allocation_size;
+
+ _Chain_Append( &information->Inactive, &the_object->Node );
+
+ if ( information->auto_extend ) {
+ uint32_t block;
+
+ block =
+ _Objects_Get_index( the_object->id ) - _Objects_Get_index( information->minimum_id );
+ block /= information->allocation_size;
+
+ information->inactive_per_block[ block ]++;
+ information->inactive++;
+
+ /*
+ * Check if the threshold level has been met of
+ * 1.5 x allocation_size are free.
+ */
+
+ if ( information->inactive > ( allocation_size + ( allocation_size >> 1 ) ) ) {
+ _Objects_Shrink_information( information );
+ }
+ }
+}
diff --git a/cpukit/score/src/objectget.c b/cpukit/score/src/objectget.c
new file mode 100644
index 0000000000..dd798a8976
--- /dev/null
+++ b/cpukit/score/src/objectget.c
@@ -0,0 +1,87 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Get
+ *
+ * This routine sets the object pointer for the given
+ * object id based on the given object information structure.
+ *
+ * Input parameters:
+ * information - pointer to entry in table for this class
+ * id - object id to search for
+ * location - address of where to store the location
+ *
+ * Output parameters:
+ * returns - address of object if local
+ * location - one of the following:
+ * OBJECTS_ERROR - invalid object ID
+ * OBJECTS_REMOTE - remote object
+ * OBJECTS_LOCAL - local object
+ */
+
+Objects_Control *_Objects_Get(
+ Objects_Information *information,
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ Objects_Control *the_object;
+ uint32_t index;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ index = id - information->minimum_id + 1;
+#else
+ /* index = _Objects_Get_index( id ); */
+ index = id & 0x0000ffff;
+ /* This should work but doesn't always :( */
+ /* index = (uint16_t ) id; */
+#endif
+
+ if ( information->maximum >= index ) {
+ _Thread_Disable_dispatch();
+ if ( (the_object = information->local_table[ index ]) != NULL ) {
+ *location = OBJECTS_LOCAL;
+ return the_object;
+ }
+ _Thread_Enable_dispatch();
+ *location = OBJECTS_ERROR;
+ return NULL;
+ }
+ *location = OBJECTS_ERROR;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _Objects_MP_Is_remote( information, id, location, &the_object );
+ return the_object;
+#else
+ return NULL;
+#endif
+}
diff --git a/cpukit/score/src/objectgetbyindex.c b/cpukit/score/src/objectgetbyindex.c
new file mode 100644
index 0000000000..199dcb9b2b
--- /dev/null
+++ b/cpukit/score/src/objectgetbyindex.c
@@ -0,0 +1,77 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Get_by_index
+ *
+ * This routine sets the object pointer for the given
+ * object id based on the given object information structure.
+ *
+ * Input parameters:
+ * information - pointer to entry in table for this class
+ * index - object index to check for
+ * location - address of where to store the location
+ *
+ * Output parameters:
+ * returns - address of object if local
+ * location - one of the following:
+ * OBJECTS_ERROR - invalid object ID
+ * OBJECTS_REMOTE - remote object
+ * OBJECTS_LOCAL - local object
+ */
+
+Objects_Control *_Objects_Get_by_index(
+ Objects_Information *information,
+ uint32_t index,
+ Objects_Locations *location
+)
+{
+ Objects_Control *the_object;
+
+ if ( information->maximum >= index ) {
+ _Thread_Disable_dispatch();
+ the_object = information->local_table[ index ];
+ if ( the_object ) {
+ *location = OBJECTS_LOCAL;
+ return( the_object );
+ }
+ _Thread_Enable_dispatch();
+ *location = OBJECTS_ERROR;
+ return( NULL );
+ }
+
+ /*
+ * With just an index, you can't access a remote object.
+ */
+
+ *location = OBJECTS_ERROR;
+ return NULL;
+}
diff --git a/cpukit/score/src/objectgetisr.c b/cpukit/score/src/objectgetisr.c
new file mode 100644
index 0000000000..8a53c7b8b5
--- /dev/null
+++ b/cpukit/score/src/objectgetisr.c
@@ -0,0 +1,93 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Get_isr_disable
+ *
+ * This routine sets the object pointer for the given
+ * object id based on the given object information structure.
+ *
+ * Input parameters:
+ * information - pointer to entry in table for this class
+ * id - object id to search for
+ * location - address of where to store the location
+ * level - pointer to previous interrupt level
+ *
+ * Output parameters:
+ * returns - address of object if local
+ * location - one of the following:
+ * OBJECTS_ERROR - invalid object ID
+ * OBJECTS_REMOTE - remote object
+ * OBJECTS_LOCAL - local object
+ * *level - previous interrupt level
+ */
+
+Objects_Control *_Objects_Get_isr_disable(
+ Objects_Information *information,
+ Objects_Id id,
+ Objects_Locations *location,
+ ISR_Level *level_p
+)
+{
+ Objects_Control *the_object;
+ uint32_t index;
+ ISR_Level level;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ index = id - information->minimum_id + 1;
+#else
+ /* index = _Objects_Get_index( id ); */
+ index = id & 0x0000ffff;
+ /* This should work but doesn't always :( */
+ /* index = (uint16_t ) id; */
+#endif
+
+ _ISR_Disable( level );
+ if ( information->maximum >= index ) {
+ if ( (the_object = information->local_table[ index ]) != NULL ) {
+ *location = OBJECTS_LOCAL;
+ *level_p = level;
+ return the_object;
+ }
+ _ISR_Enable( level );
+ *location = OBJECTS_ERROR;
+ return NULL;
+ }
+ _ISR_Enable( level );
+ *location = OBJECTS_ERROR;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _Objects_MP_Is_remote( information, id, location, &the_object );
+ return the_object;
+#else
+ return NULL;
+#endif
+}
diff --git a/cpukit/score/src/objectgetnext.c b/cpukit/score/src/objectgetnext.c
new file mode 100644
index 0000000000..a27ecf7dad
--- /dev/null
+++ b/cpukit/score/src/objectgetnext.c
@@ -0,0 +1,94 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Get_next
+ *
+ * Like _Objects_Get, but considers the 'id' as a "hint" and
+ * finds next valid one after that point.
+ * Mostly used for monitor and debug traversal of an object.
+ *
+ * Input parameters:
+ * information - pointer to entry in table for this class
+ * id - object id to search for
+ * location - address of where to store the location
+ * next_id - address to store next id to try
+ *
+ * Output parameters:
+ * returns - address of object if local
+ * location - one of the following:
+ * OBJECTS_ERROR - invalid object ID
+ * OBJECTS_REMOTE - remote object
+ * OBJECTS_LOCAL - local object
+ * next_id - will contain a reasonable "next" id to continue traversal
+ *
+ * NOTE:
+ * assumes can add '1' to an id to get to next index.
+ */
+
+Objects_Control *
+_Objects_Get_next(
+ Objects_Information *information,
+ Objects_Id id,
+ Objects_Locations *location_p,
+ Objects_Id *next_id_p
+)
+{
+ Objects_Control *object;
+ Objects_Id next_id;
+
+ if (_Objects_Get_index(id) == OBJECTS_ID_INITIAL_INDEX)
+ next_id = information->minimum_id;
+ else
+ next_id = id;
+
+ do {
+ /* walked off end of list? */
+ if (_Objects_Get_index(next_id) > information->maximum)
+ {
+ *location_p = OBJECTS_ERROR;
+ goto final;
+ }
+
+ /* try to grab one */
+ object = _Objects_Get(information, next_id, location_p);
+
+ next_id++;
+
+ } while (*location_p != OBJECTS_LOCAL);
+
+ *next_id_p = next_id;
+ return object;
+
+final:
+ *next_id_p = OBJECTS_ID_FINAL;
+ return 0;
+}
diff --git a/cpukit/score/src/objectgetnoprotection.c b/cpukit/score/src/objectgetnoprotection.c
new file mode 100644
index 0000000000..7f3981e1e0
--- /dev/null
+++ b/cpukit/score/src/objectgetnoprotection.c
@@ -0,0 +1,87 @@
+/*
+ * Object Handler -- Object Get
+ *
+ *
+ * COPYRIGHT (c) 1989-2002.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Get_no_protection
+ *
+ * This routine sets the object pointer for the given
+ * object id based on the given object information structure.
+ *
+ * Input parameters:
+ * information - pointer to entry in table for this class
+ * id - object id to search for
+ * location - address of where to store the location
+ *
+ * Output parameters:
+ * returns - address of object if local
+ * location - one of the following:
+ * OBJECTS_ERROR - invalid object ID
+ * OBJECTS_REMOTE - remote object
+ * OBJECTS_LOCAL - local object
+ */
+
+Objects_Control *_Objects_Get_no_protection(
+ Objects_Information *information,
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ Objects_Control *the_object;
+ uint32_t index;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ index = id - information->minimum_id + 1;
+#else
+ /* index = _Objects_Get_index( id ); */
+ index = id & 0x0000ffff;
+ /* This should work but doesn't always :( */
+ /* index = (uint16_t ) id; */
+#endif
+
+ if ( information->maximum >= index ) {
+ if ( (the_object = information->local_table[ index ]) != NULL ) {
+ *location = OBJECTS_LOCAL;
+ return the_object;
+ }
+ *location = OBJECTS_ERROR;
+ return NULL;
+ }
+ *location = OBJECTS_ERROR;
+
+/*
+ * Not supported for multiprocessing
+ */
+#if 0 && defined(RTEMS_MULTIPROCESSING)
+ _Objects_MP_Is_remote( information, id, location, &the_object );
+ return the_object;
+#endif
+ return NULL;
+}
diff --git a/cpukit/score/src/objectidtoname.c b/cpukit/score/src/objectidtoname.c
new file mode 100644
index 0000000000..bb96010957
--- /dev/null
+++ b/cpukit/score/src/objectidtoname.c
@@ -0,0 +1,73 @@
+/*
+ * Obtain Object Name Given ID
+ *
+ *
+ * COPYRIGHT (c) 1989-2003.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * _Objects_Id_to_name
+ *
+ * DESCRIPTION:
+ *
+ * This routine returns the name associated with the given ID.
+ *
+ * INPUT:
+ *
+ * id - id of object to lookup name
+ * name - pointer to location in which to store name
+ *
+ */
+
+
+Objects_Name_or_id_lookup_errors _Objects_Id_to_name (
+ Objects_Id id,
+ Objects_Name *name
+)
+{
+ uint32_t the_api;
+ uint32_t the_class;
+ Objects_Information *information;
+ Objects_Control *the_object = (Objects_Control *) 0;
+ Objects_Locations ignored_location;
+
+ if ( !name )
+ return OBJECTS_INVALID_NAME;
+
+ the_api = _Objects_Get_API( id );
+ if ( the_api && the_api > OBJECTS_APIS_LAST )
+ return OBJECTS_INVALID_ID;
+
+ the_class = _Objects_Get_class( id );
+
+ information = _Objects_Information_table[ the_api ][ the_class ];
+ if ( !information )
+ return OBJECTS_INVALID_ID;
+
+ if ( information->is_string )
+ return OBJECTS_INVALID_ID;
+
+ the_object = _Objects_Get( information, id, &ignored_location );
+ if ( !the_object )
+ return OBJECTS_INVALID_ID;
+
+ *name = the_object->name;
+ _Thread_Enable_dispatch();
+ return OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL;
+}
diff --git a/cpukit/score/src/objectinitializeinformation.c b/cpukit/score/src/objectinitializeinformation.c
new file mode 100644
index 0000000000..ee9129ecfe
--- /dev/null
+++ b/cpukit/score/src/objectinitializeinformation.c
@@ -0,0 +1,181 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Initialize_information
+ *
+ * This routine initializes all object information related data structures.
+ *
+ * Input parameters:
+ * information - object information table
+ * maximum - maximum objects of this class
+ * size - size of this object's control block
+ * is_string - TRUE if names for this object are strings
+ * maximum_name_length - maximum length of each object's name
+ * When multiprocessing is configured,
+ * supports_global - TRUE if this is a global object class
+ * extract_callout - pointer to threadq extract callout
+ *
+ * Output parameters: NONE
+ */
+
+void _Objects_Initialize_information(
+ Objects_Information *information,
+ Objects_APIs the_api,
+ uint32_t the_class,
+ uint32_t maximum,
+ uint16_t size,
+ boolean is_string,
+ uint32_t maximum_name_length
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ boolean supports_global,
+ Objects_Thread_queue_Extract_callout extract
+#endif
+)
+{
+ static Objects_Control *null_local_table = NULL;
+ uint32_t minimum_index;
+ uint32_t name_length;
+#if defined(RTEMS_MULTIPROCESSING)
+ uint32_t index;
+#endif
+
+ information->the_api = the_api;
+ information->the_class = the_class;
+ information->is_string = is_string;
+
+ information->local_table = 0;
+ information->name_table = 0;
+ information->inactive_per_block = 0;
+ information->object_blocks = 0;
+
+ information->inactive = 0;
+
+ /*
+ * Set the entry in the object information table.
+ */
+
+ _Objects_Information_table[ the_api ][ the_class ] = information;
+
+ /*
+ * Set the size of the object
+ */
+
+ information->size = size;
+
+ /*
+ * Are we operating in unlimited, or auto-extend mode
+ */
+
+ information->auto_extend = (maximum & OBJECTS_UNLIMITED_OBJECTS) ? TRUE : FALSE;
+ maximum &= ~OBJECTS_UNLIMITED_OBJECTS;
+
+ /*
+ * The allocation unit is the maximum value
+ */
+
+ information->allocation_size = maximum;
+
+ /*
+ * Provide a null local table entry for the case of any empty table.
+ */
+
+ information->local_table = &null_local_table;
+
+ /*
+ * Calculate minimum and maximum Id's
+ */
+
+ if ( maximum == 0 ) minimum_index = 0;
+ else minimum_index = 1;
+
+ information->minimum_id =
+ _Objects_Build_id( the_api, the_class, _Objects_Local_node, minimum_index );
+
+ /*
+ * Calculate the maximum name length
+ */
+
+ name_length = maximum_name_length;
+
+ if ( name_length & (OBJECTS_NAME_ALIGNMENT-1) )
+ name_length = (name_length + OBJECTS_NAME_ALIGNMENT) &
+ ~(OBJECTS_NAME_ALIGNMENT-1);
+
+ information->name_length = name_length;
+
+ _Chain_Initialize_empty( &information->Inactive );
+
+ /*
+ * Initialize objects .. if there are any
+ */
+
+ if ( maximum ) {
+
+ /*
+ * Reset the maximum value. It will be updated when the information is
+ * extended.
+ */
+
+ information->maximum = 0;
+
+ /*
+ * Always have the maximum size available so the current performance
+ * figures are create are met. If the user moves past the maximum
+ * number then a performance hit is taken.
+ */
+
+ _Objects_Extend_information( information );
+
+ }
+
+ /*
+ * Take care of multiprocessing
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+ information->extract = extract;
+
+ if ( supports_global == TRUE && _System_state_Is_multiprocessing ) {
+
+ information->global_table =
+ (Chain_Control *) _Workspace_Allocate_or_fatal_error(
+ (_Objects_Maximum_nodes + 1) * sizeof(Chain_Control)
+ );
+
+ for ( index=1; index <= _Objects_Maximum_nodes ; index++ )
+ _Chain_Initialize_empty( &information->global_table[ index ] );
+ }
+ else
+ information->global_table = NULL;
+#endif
+}
diff --git a/cpukit/score/src/objectmp.c b/cpukit/score/src/objectmp.c
new file mode 100644
index 0000000000..1eb678557a
--- /dev/null
+++ b/cpukit/score/src/objectmp.c
@@ -0,0 +1,280 @@
+/*
+ * Multiprocessing Support for the Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/thread.h>
+
+/*PAGE
+ *
+ * _Objects_MP_Handler_initialization
+ *
+ */
+
+void _Objects_MP_Handler_initialization (
+ uint32_t node,
+ uint32_t maximum_nodes,
+ uint32_t maximum_global_objects
+)
+{
+ _Objects_MP_Maximum_global_objects = maximum_global_objects;
+
+ if ( maximum_global_objects == 0 ) {
+ _Chain_Initialize_empty( &_Objects_MP_Inactive_global_objects );
+ return;
+ }
+
+ _Chain_Initialize(
+ &_Objects_MP_Inactive_global_objects,
+ _Workspace_Allocate_or_fatal_error(
+ maximum_global_objects * sizeof( Objects_MP_Control )
+ ),
+ maximum_global_objects,
+ sizeof( Objects_MP_Control )
+ );
+
+}
+
+/*PAGE
+ *
+ * _Objects_MP_Open
+ *
+ */
+
+void _Objects_MP_Open (
+ Objects_Information *information,
+ Objects_MP_Control *the_global_object,
+ uint32_t the_name, /* XXX -- wrong for variable */
+ Objects_Id the_id
+)
+{
+ the_global_object->Object.id = the_id;
+ the_global_object->name = the_name;
+
+ _Chain_Prepend(
+ &information->global_table[ _Objects_Get_node( the_id ) ],
+ &the_global_object->Object.Node
+ );
+
+}
+
+/*PAGE
+ *
+ * _Objects_MP_Allocate_and_open
+ *
+ */
+
+boolean _Objects_MP_Allocate_and_open (
+ Objects_Information *information,
+ uint32_t the_name, /* XXX -- wrong for variable */
+ Objects_Id the_id,
+ boolean is_fatal_error
+)
+{
+ Objects_MP_Control *the_global_object;
+
+ the_global_object = _Objects_MP_Allocate_global_object();
+ if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
+
+ if ( is_fatal_error == FALSE )
+ return FALSE;
+
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_OUT_OF_GLOBAL_OBJECTS
+ );
+
+ }
+
+ _Objects_MP_Open( information, the_global_object, the_name, the_id );
+
+ return TRUE;
+}
+
+/*PAGE
+ *
+ * _Objects_MP_Close
+ *
+ */
+
+void _Objects_MP_Close (
+ Objects_Information *information,
+ Objects_Id the_id
+)
+{
+ Chain_Control *the_chain;
+ Chain_Node *the_node;
+ Objects_MP_Control *the_object;
+
+ the_chain = &information->global_table[ _Objects_Get_node( the_id ) ];
+
+ for ( the_node = the_chain->first ;
+ !_Chain_Is_tail( the_chain, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_object = (Objects_MP_Control *) the_node;
+
+ if ( _Objects_Are_ids_equal( the_object->Object.id, the_id ) ) {
+
+ _Chain_Extract( the_node );
+ _Objects_MP_Free_global_object( the_object );
+ return;
+ }
+
+ }
+
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_INVALID_GLOBAL_ID
+ );
+}
+
+/*PAGE
+ *
+ * _Objects_MP_Global_name_search
+ *
+ */
+
+Objects_Name_or_id_lookup_errors _Objects_MP_Global_name_search (
+ Objects_Information *information,
+ Objects_Name the_name,
+ uint32_t nodes_to_search,
+ Objects_Id *the_id
+)
+{
+ uint32_t low_node;
+ uint32_t high_node;
+ uint32_t node_index;
+ Chain_Control *the_chain;
+ Chain_Node *the_node;
+ Objects_MP_Control *the_object;
+ uint32_t name_to_use;
+
+ name_to_use = (uint32_t)the_name; /* XXX only fixed length names */
+
+ if ( nodes_to_search > _Objects_Maximum_nodes )
+ return OBJECTS_INVALID_NODE;
+
+ if ( information->global_table == NULL )
+ return OBJECTS_INVALID_NAME;
+
+ if ( nodes_to_search == OBJECTS_SEARCH_ALL_NODES ||
+ nodes_to_search == OBJECTS_SEARCH_OTHER_NODES ) {
+ low_node = 1;
+ high_node = _Objects_Maximum_nodes;
+ } else {
+ low_node =
+ high_node = nodes_to_search;
+ }
+
+ _Thread_Disable_dispatch();
+
+ for ( node_index = low_node ; node_index <= high_node ; node_index++ ) {
+
+ /*
+ * NOTE: The local node was search (if necessary) by
+ * _Objects_Name_to_id before this was invoked.
+ */
+
+ if ( !_Objects_Is_local_node( node_index ) ) {
+ the_chain = &information->global_table[ node_index ];
+
+ for ( the_node = the_chain->first ;
+ !_Chain_Is_tail( the_chain, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_object = (Objects_MP_Control *) the_node;
+
+ if ( the_object->name == name_to_use ) {
+ *the_id = the_object->Object.id;
+ _Thread_Enable_dispatch();
+ return OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL;
+ }
+ }
+ }
+ }
+
+ _Thread_Enable_dispatch();
+ return OBJECTS_INVALID_NAME;
+}
+
+/*PAGE
+ *
+ * _Objects_MP_Is_remote
+ *
+ */
+
+void _Objects_MP_Is_remote (
+ Objects_Information *information,
+ Objects_Id the_id,
+ Objects_Locations *location,
+ Objects_Control **the_object
+)
+{
+ uint32_t node;
+ Chain_Control *the_chain;
+ Chain_Node *the_node;
+ Objects_MP_Control *the_global_object;
+
+ node = _Objects_Get_node( the_id );
+
+ /*
+ * NOTE: The local node was search (if necessary) by
+ * _Objects_Name_to_id before this was invoked.
+ *
+ * The NODE field of an object id cannot be 0
+ * because 0 is an invalid node number.
+ */
+
+ if ( node == 0 ||
+ _Objects_Is_local_node( node ) ||
+ node > _Objects_Maximum_nodes ||
+ information->global_table == NULL ) {
+
+ *location = OBJECTS_ERROR;
+ *the_object = NULL;
+ return;
+ }
+
+ _Thread_Disable_dispatch();
+
+ the_chain = &information->global_table[ node ];
+
+ for ( the_node = the_chain->first ;
+ !_Chain_Is_tail( the_chain, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_global_object = (Objects_MP_Control *) the_node;
+
+ if ( _Objects_Are_ids_equal( the_global_object->Object.id, the_id ) ) {
+ _Thread_Unnest_dispatch();
+ *location = OBJECTS_REMOTE;
+ *the_object = (Objects_Control *) the_global_object;
+ return;
+ }
+ }
+
+ _Thread_Enable_dispatch();
+ *location = OBJECTS_ERROR;
+ *the_object = NULL;
+
+}
diff --git a/cpukit/score/src/objectnametoid.c b/cpukit/score/src/objectnametoid.c
new file mode 100644
index 0000000000..533c4b0ec4
--- /dev/null
+++ b/cpukit/score/src/objectnametoid.c
@@ -0,0 +1,105 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Name_to_id
+ *
+ * These kernel routines search the object table(s) for the given
+ * object name and returns the associated object id.
+ *
+ * Input parameters:
+ * information - object information
+ * name - user defined object name
+ * node - node indentifier (0 indicates any node)
+ * id - address of return ID
+ *
+ * Output parameters:
+ * id - object id
+ * OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+Objects_Name_or_id_lookup_errors _Objects_Name_to_id(
+ Objects_Information *information,
+ Objects_Name name,
+ uint32_t node,
+ Objects_Id *id
+)
+{
+ boolean search_local_node;
+ Objects_Control *the_object;
+ uint32_t index;
+ uint32_t name_length;
+ Objects_Name_comparators compare_them;
+
+ if ( !id )
+ return OBJECTS_INVALID_ADDRESS;
+
+ if ( name == 0 )
+ return OBJECTS_INVALID_NAME;
+
+ search_local_node = FALSE;
+
+ if ( information->maximum != 0 &&
+ (node == OBJECTS_SEARCH_ALL_NODES || node == OBJECTS_SEARCH_LOCAL_NODE
+#if defined(RTEMS_MULTIPROCESSING)
+ || _Objects_Is_local_node( node )
+#endif
+ ))
+ search_local_node = TRUE;
+
+ if ( search_local_node ) {
+ name_length = information->name_length;
+
+ if ( information->is_string ) compare_them = _Objects_Compare_name_string;
+ else compare_them = _Objects_Compare_name_raw;
+
+ for ( index = 1; index <= information->maximum; index++ ) {
+ the_object = information->local_table[ index ];
+ if ( !the_object || !the_object->name )
+ continue;
+
+ if ( (*compare_them)( name, the_object->name, name_length ) ) {
+ *id = the_object->id;
+ return OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL;
+ }
+ }
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Objects_Is_local_node( node ) || node == OBJECTS_SEARCH_LOCAL_NODE )
+ return OBJECTS_INVALID_NAME;
+
+ return ( _Objects_MP_Global_name_search( information, name, node, id ) );
+#else
+ return OBJECTS_INVALID_NAME;
+#endif
+}
diff --git a/cpukit/score/src/objectshrinkinformation.c b/cpukit/score/src/objectshrinkinformation.c
new file mode 100644
index 0000000000..2ecea75267
--- /dev/null
+++ b/cpukit/score/src/objectshrinkinformation.c
@@ -0,0 +1,119 @@
+/*
+ * Object Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/address.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Objects_Shrink_information
+ *
+ * This routine shrinks object information related data structures.
+ * The object's name and object space are released. The local_table
+ * etc block does not shrink. The InActive list needs to be scanned
+ * to find the objects are remove them.
+ * Input parameters:
+ * information - object information table
+ * the_block - the block to remove
+ *
+ * Output parameters: NONE
+ */
+
+void _Objects_Shrink_information(
+ Objects_Information *information
+)
+{
+ Objects_Control *the_object;
+ Objects_Control *extract_me;
+ uint32_t block_count;
+ uint32_t block;
+ uint32_t index_base;
+ uint32_t index;
+
+ /*
+ * Search the list to find block or chunnk with all objects inactive.
+ */
+
+ index_base = _Objects_Get_index( information->minimum_id );
+ block_count = ( information->maximum - index_base ) / information->allocation_size;
+
+ for ( block = 0; block < block_count; block++ ) {
+ if ( information->inactive_per_block[ block ] == information->allocation_size ) {
+
+ /*
+ * XXX - Not to sure how to use a chain where you need to iterate and
+ * and remove elements.
+ */
+
+ the_object = (Objects_Control *) information->Inactive.first;
+
+ /*
+ * Assume the Inactive chain is never empty at this point
+ */
+
+ do {
+ index = _Objects_Get_index( the_object->id );
+
+ if ((index >= index_base) &&
+ (index < (index_base + information->allocation_size))) {
+
+ /*
+ * Get the next node before the node is extracted
+ */
+
+ extract_me = the_object;
+
+ if ( !_Chain_Is_last( &the_object->Node ) )
+ the_object = (Objects_Control *) the_object->Node.next;
+ else
+ the_object = NULL;
+
+ _Chain_Extract( &extract_me->Node );
+ }
+ else {
+ the_object = (Objects_Control *) the_object->Node.next;
+ }
+ }
+ while ( the_object && !_Chain_Is_last( &the_object->Node ) );
+
+ /*
+ * Free the memory and reset the structures in the object' information
+ */
+
+ _Workspace_Free( information->object_blocks[ block ] );
+ information->name_table[ block ] = NULL;
+ information->object_blocks[ block ] = NULL;
+ information->inactive_per_block[ block ] = 0;
+
+ information->inactive -= information->allocation_size;
+
+ return;
+ }
+
+ index_base += information->allocation_size;
+ }
+}
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c
new file mode 100644
index 0000000000..58b62b7116
--- /dev/null
+++ b/cpukit/score/src/thread.c
@@ -0,0 +1,111 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Handler_initialization
+ *
+ * This routine initializes all thread manager related data structures.
+ *
+ * Input parameters:
+ * ticks_per_timeslice - clock ticks per quantum
+ * maximum_proxies - number of proxies to initialize
+ *
+ * Output parameters: NONE
+ */
+
+void _Thread_Handler_initialization(
+ uint32_t ticks_per_timeslice,
+ uint32_t maximum_extensions,
+ uint32_t maximum_proxies
+)
+{
+ uint32_t index;
+
+ /*
+ * BOTH stacks hooks must be set or both must be NULL.
+ * Do not allow mixture.
+ */
+
+ if ( !( ( _CPU_Table.stack_allocate_hook == 0 )
+ == ( _CPU_Table.stack_free_hook == 0 ) ) )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_BAD_STACK_HOOK
+ );
+
+ _Context_Switch_necessary = FALSE;
+ _Thread_Executing = NULL;
+ _Thread_Heir = NULL;
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ _Thread_Allocated_fp = NULL;
+#endif
+
+ _Thread_Do_post_task_switch_extension = 0;
+
+ _Thread_Maximum_extensions = maximum_extensions;
+
+ _Thread_Ticks_per_timeslice = ticks_per_timeslice;
+
+ _Thread_Ready_chain = (Chain_Control *) _Workspace_Allocate_or_fatal_error(
+ (PRIORITY_MAXIMUM + 1) * sizeof(Chain_Control)
+ );
+
+ for ( index=0; index <= PRIORITY_MAXIMUM ; index++ )
+ _Chain_Initialize_empty( &_Thread_Ready_chain[ index ] );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ _Thread_MP_Handler_initialization( maximum_proxies );
+#endif
+
+ /*
+ * Initialize this class of objects.
+ */
+
+ _Objects_Initialize_information(
+ &_Thread_Internal_information,
+ OBJECTS_INTERNAL_API,
+ OBJECTS_INTERNAL_THREADS,
+ ( _System_state_Is_multiprocessing ) ? 2 : 1,
+ sizeof( Thread_Control ),
+ /* size of this object's control block */
+ TRUE, /* TRUE if names for this object are strings */
+ 8 /* maximum length of each object's name */
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ FALSE, /* TRUE if this is a global object class */
+ NULL /* Proxy extraction support callout */
+#endif
+ );
+
+}
diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c
new file mode 100644
index 0000000000..89d0d2cd5f
--- /dev/null
+++ b/cpukit/score/src/threadchangepriority.c
@@ -0,0 +1,117 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Change_priority
+ *
+ * This kernel routine changes the priority of the thread. The
+ * thread chain is adjusted if necessary.
+ *
+ * Input parameters:
+ * the_thread - pointer to thread control block
+ * new_priority - ultimate priority
+ * prepend_it - TRUE if the thread should be prepended to the chain
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * ready chain
+ * select heir
+ */
+
+void _Thread_Change_priority(
+ Thread_Control *the_thread,
+ Priority_Control new_priority,
+ boolean prepend_it
+)
+{
+ ISR_Level level;
+ /* boolean do_prepend = FALSE; */
+
+ /*
+ * If this is a case where prepending the task to its priority is
+ * potentially desired, then we need to consider whether to do it.
+ * This usually occurs when a task lowers its priority implcitly as
+ * the result of losing inherited priority. Normal explicit priority
+ * change calls (e.g. rtems_task_set_priority) should always do an
+ * append not a prepend.
+ */
+
+ /*
+ * Techically, the prepend should conditional on the thread lowering
+ * its priority but that does allow cxd2004 of the acvc 2.0.1 to
+ * pass with rtems 4.0.0. This should change when gnat redoes its
+ * priority scheme.
+ */
+/*
+ if ( prepend_it &&
+ _Thread_Is_executing( the_thread ) &&
+ new_priority >= the_thread->current_priority )
+ prepend_it = TRUE;
+*/
+
+ _Thread_Set_transient( the_thread );
+
+ if ( the_thread->current_priority != new_priority )
+ _Thread_Set_priority( the_thread, new_priority );
+
+ _ISR_Disable( level );
+
+ the_thread->current_state =
+ _States_Clear( STATES_TRANSIENT, the_thread->current_state );
+
+ if ( ! _States_Is_ready( the_thread->current_state ) ) {
+ /*
+ * XXX If a task is to be reordered while blocked on a priority
+ * XXX priority ordered thread queue, then this is where that
+ * XXX should occur.
+ */
+ _ISR_Enable( level );
+ return;
+ }
+
+ _Priority_Add_to_bit_map( &the_thread->Priority_map );
+ if ( prepend_it )
+ _Chain_Prepend_unprotected( the_thread->ready, &the_thread->Object.Node );
+ else
+ _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node );
+
+ _ISR_Flash( level );
+
+ _Thread_Calculate_heir();
+
+ if ( !_Thread_Is_executing_also_the_heir() &&
+ _Thread_Executing->is_preemptible )
+ _Context_Switch_necessary = TRUE;
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/threadclearstate.c b/cpukit/score/src/threadclearstate.c
new file mode 100644
index 0000000000..bb7deffe06
--- /dev/null
+++ b/cpukit/score/src/threadclearstate.c
@@ -0,0 +1,85 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Clear_state
+ *
+ * This kernel routine clears the appropriate states in the
+ * requested thread. The thread ready chain is adjusted if
+ * necessary and the Heir thread is set accordingly.
+ *
+ * Input parameters:
+ * the_thread - pointer to thread control block
+ * state - state set to clear
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * priority map
+ * select heir
+ */
+
+
+void _Thread_Clear_state(
+ Thread_Control *the_thread,
+ States_Control state
+)
+{
+ ISR_Level level;
+ States_Control current_state;
+
+ _ISR_Disable( level );
+ current_state = the_thread->current_state;
+
+ if ( current_state & state ) {
+ current_state =
+ the_thread->current_state = _States_Clear( state, current_state );
+
+ if ( _States_Is_ready( current_state ) ) {
+
+ _Priority_Add_to_bit_map( &the_thread->Priority_map );
+
+ _Chain_Append_unprotected(the_thread->ready, &the_thread->Object.Node);
+
+ _ISR_Flash( level );
+
+ if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
+ _Thread_Heir = the_thread;
+ if ( _Thread_Executing->is_preemptible ||
+ the_thread->current_priority == 0 )
+ _Context_Switch_necessary = TRUE;
+ }
+ }
+ }
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/threadclose.c b/cpukit/score/src/threadclose.c
new file mode 100644
index 0000000000..e506b2666d
--- /dev/null
+++ b/cpukit/score/src/threadclose.c
@@ -0,0 +1,77 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * _Thread_Close
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees all memory associated with the specified
+ * thread and removes it from the local object table so no further
+ * operations on this thread are allowed.
+ */
+
+void _Thread_Close(
+ Objects_Information *information,
+ Thread_Control *the_thread
+)
+{
+ _User_extensions_Thread_delete( the_thread );
+
+ _Objects_Close( information, &the_thread->Object );
+
+ _Thread_Set_state( the_thread, STATES_TRANSIENT );
+
+ if ( !_Thread_queue_Extract_with_proxy( the_thread ) ) {
+ if ( _Watchdog_Is_active( &the_thread->Timer ) )
+ (void) _Watchdog_Remove( &the_thread->Timer );
+ }
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
+ if ( _Thread_Is_allocated_fp( the_thread ) )
+ _Thread_Deallocate_fp();
+#endif
+ the_thread->fp_context = NULL;
+
+ if ( the_thread->Start.fp_context )
+ (void) _Workspace_Free( the_thread->Start.fp_context );
+#endif
+
+ _Thread_Stack_Free( the_thread );
+
+ if ( the_thread->extensions )
+ (void) _Workspace_Free( the_thread->extensions );
+
+ the_thread->Start.stack = NULL;
+ the_thread->extensions = NULL;
+}
diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c
new file mode 100644
index 0000000000..f9d4d21ba9
--- /dev/null
+++ b/cpukit/score/src/threadcreateidle.c
@@ -0,0 +1,100 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Create_idle
+ */
+
+const char *_Thread_Idle_name = "IDLE";
+
+void _Thread_Create_idle( void )
+{
+ void *idle;
+ uint32_t idle_task_stack_size;
+
+ /*
+ * The entire workspace is zeroed during its initialization. Thus, all
+ * fields not explicitly assigned were explicitly zeroed by
+ * _Workspace_Initialization.
+ */
+
+ _Thread_Idle = _Thread_Internal_allocate();
+
+ /*
+ * Initialize the IDLE task.
+ */
+
+#if (CPU_PROVIDES_IDLE_THREAD_BODY == TRUE)
+ idle = (void *) _CPU_Thread_Idle_body;
+#else
+ idle = (void *) _Thread_Idle_body;
+#endif
+
+ if ( _CPU_Table.idle_task )
+ idle = _CPU_Table.idle_task;
+
+ idle_task_stack_size = _CPU_Table.idle_task_stack_size;
+ if ( idle_task_stack_size < STACK_MINIMUM_SIZE )
+ idle_task_stack_size = STACK_MINIMUM_SIZE;
+
+ _Thread_Initialize(
+ &_Thread_Internal_information,
+ _Thread_Idle,
+ NULL, /* allocate the stack */
+ idle_task_stack_size,
+ CPU_IDLE_TASK_IS_FP,
+ PRIORITY_MAXIMUM,
+ TRUE, /* preemptable */
+ THREAD_CPU_BUDGET_ALGORITHM_NONE,
+ NULL, /* no budget algorithm callout */
+ 0, /* all interrupts enabled */
+ (Objects_Name) _Thread_Idle_name
+ );
+
+ /*
+ * WARNING!!! This is necessary to "kick" start the system and
+ * MUST be done before _Thread_Start is invoked.
+ */
+
+ _Thread_Heir =
+ _Thread_Executing = _Thread_Idle;
+
+ _Thread_Start(
+ _Thread_Idle,
+ THREAD_START_NUMERIC,
+ idle,
+ NULL,
+ 0
+ );
+
+}
diff --git a/cpukit/score/src/threaddelayended.c b/cpukit/score/src/threaddelayended.c
new file mode 100644
index 0000000000..0f6998acbe
--- /dev/null
+++ b/cpukit/score/src/threaddelayended.c
@@ -0,0 +1,64 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Delay_ended
+ *
+ * This routine processes a thread whose delay period has ended.
+ * It is called by the watchdog handler.
+ *
+ * Input parameters:
+ * id - thread id
+ *
+ * Output parameters: NONE
+ */
+
+void _Thread_Delay_ended(
+ Objects_Id id,
+ void *ignored
+)
+{
+ Thread_Control *the_thread;
+ Objects_Locations location;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE: /* impossible */
+ break;
+ case OBJECTS_LOCAL:
+ _Thread_Unblock( the_thread );
+ _Thread_Unnest_dispatch();
+ break;
+ }
+}
diff --git a/cpukit/score/src/threaddispatch.c b/cpukit/score/src/threaddispatch.c
new file mode 100644
index 0000000000..96f4fa6c3f
--- /dev/null
+++ b/cpukit/score/src/threaddispatch.c
@@ -0,0 +1,144 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Dispatch
+ *
+ * This kernel routine determines if a dispatch is needed, and if so
+ * dispatches to the heir thread. Once the heir is running an attempt
+ * is made to dispatch any ASRs.
+ *
+ * ALTERNATE ENTRY POINTS:
+ * void _Thread_Enable_dispatch();
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * dispatch thread
+ * no dispatch thread
+ */
+
+#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE )
+void _Thread_Enable_dispatch( void )
+{
+ if ( --_Thread_Dispatch_disable_level )
+ return;
+ _Thread_Dispatch();
+}
+#endif
+
+void _Thread_Dispatch( void )
+{
+ Thread_Control *executing;
+ Thread_Control *heir;
+ ISR_Level level;
+
+ executing = _Thread_Executing;
+ _ISR_Disable( level );
+ while ( _Context_Switch_necessary == TRUE ) {
+ heir = _Thread_Heir;
+ _Thread_Dispatch_disable_level = 1;
+ _Context_Switch_necessary = FALSE;
+ _Thread_Executing = heir;
+ executing->rtems_ada_self = rtems_ada_self;
+ rtems_ada_self = heir->rtems_ada_self;
+ if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
+ heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
+ _ISR_Enable( level );
+
+ heir->ticks_executed++;
+
+ /*
+ * Switch libc's task specific data.
+ */
+ if ( _Thread_libc_reent ) {
+ executing->libc_reent = *_Thread_libc_reent;
+ *_Thread_libc_reent = heir->libc_reent;
+ }
+
+ _User_extensions_Thread_switch( executing, heir );
+
+ /*
+ * If the CPU has hardware floating point, then we must address saving
+ * and restoring it as part of the context switch.
+ *
+ * The second conditional compilation section selects the algorithm used
+ * to context switch between floating point tasks. The deferred algorithm
+ * can be significantly better in a system with few floating point tasks
+ * because it reduces the total number of save and restore FP context
+ * operations. However, this algorithm can not be used on all CPUs due
+ * to unpredictable use of FP registers by some compilers for integer
+ * operations.
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+#if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
+ if ( executing->fp_context != NULL )
+ _Context_Save_fp( &executing->fp_context );
+#endif
+#endif
+
+ _Context_Switch( &executing->Registers, &heir->Registers );
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
+ if ( (executing->fp_context != NULL) && !_Thread_Is_allocated_fp( executing ) ) {
+ if ( _Thread_Allocated_fp != NULL )
+ _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
+ _Context_Restore_fp( &executing->fp_context );
+ _Thread_Allocated_fp = executing;
+ }
+#else
+ if ( executing->fp_context != NULL )
+ _Context_Restore_fp( &executing->fp_context );
+#endif
+#endif
+
+ executing = _Thread_Executing;
+
+ _ISR_Disable( level );
+ }
+
+ _Thread_Dispatch_disable_level = 0;
+
+ _ISR_Enable( level );
+
+ if ( _Thread_Do_post_task_switch_extension ||
+ executing->do_post_task_switch_extension ) {
+ executing->do_post_task_switch_extension = FALSE;
+ _API_extensions_Run_postswitch();
+ }
+
+}
diff --git a/cpukit/score/src/threadevaluatemode.c b/cpukit/score/src/threadevaluatemode.c
new file mode 100644
index 0000000000..f4d99b12cc
--- /dev/null
+++ b/cpukit/score/src/threadevaluatemode.c
@@ -0,0 +1,53 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Evaluate_mode
+ *
+ * XXX
+ */
+
+boolean _Thread_Evaluate_mode( void )
+{
+ Thread_Control *executing;
+
+ executing = _Thread_Executing;
+
+ if ( !_States_Is_ready( executing->current_state ) ||
+ ( !_Thread_Is_heir( executing ) && executing->is_preemptible ) ) {
+ _Context_Switch_necessary = TRUE;
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/cpukit/score/src/threadget.c b/cpukit/score/src/threadget.c
new file mode 100644
index 0000000000..f2c34a1d4e
--- /dev/null
+++ b/cpukit/score/src/threadget.c
@@ -0,0 +1,87 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Get
+ *
+ * NOTE: If we are not using static inlines, this must be a real
+ * subroutine call.
+ *
+ * NOTE: XXX... This routine may be able to be optimized.
+ */
+
+#ifndef RTEMS_INLINES
+
+Thread_Control *_Thread_Get (
+ Objects_Id id,
+ Objects_Locations *location
+)
+{
+ uint32_t the_api;
+ uint32_t the_class;
+ Objects_Information *information;
+ Thread_Control *tp = (Thread_Control *) 0;
+
+ if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) {
+ _Thread_Disable_dispatch();
+ *location = OBJECTS_LOCAL;
+ tp = _Thread_Executing;
+ goto done;
+ }
+
+ the_api = _Objects_Get_API( id );
+ if ( the_api && the_api > OBJECTS_APIS_LAST ) {
+ *location = OBJECTS_ERROR;
+ goto done;
+ }
+
+ the_class = _Objects_Get_class( id );
+ if ( the_class != 1 ) { /* threads are always first class :) */
+ *location = OBJECTS_ERROR;
+ goto done;
+ }
+
+ information = _Objects_Information_table[ the_api ][ the_class ];
+
+ if ( !information ) {
+ *location = OBJECTS_ERROR;
+ goto done;
+ }
+
+ tp = (Thread_Control *) _Objects_Get( information, id, location );
+
+done:
+ return tp;
+}
+
+#endif
diff --git a/cpukit/score/src/threadhandler.c b/cpukit/score/src/threadhandler.c
new file mode 100644
index 0000000000..c6cf23e660
--- /dev/null
+++ b/cpukit/score/src/threadhandler.c
@@ -0,0 +1,168 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Handler
+ *
+ * This routine is the "primal" entry point for all threads.
+ * _Context_Initialize() dummies up the thread's initial context
+ * to cause the first Context_Switch() to jump to _Thread_Handler().
+ *
+ * This routine is the default thread exitted error handler. It is
+ * returned to when a thread exits. The configured fatal error handler
+ * is invoked to process the exit.
+ *
+ * NOTE:
+ *
+ * On entry, it is assumed all interrupts are blocked and that this
+ * routine needs to set the initial isr level. This may or may not
+ * actually be needed by the context switch routine and as a result
+ * interrupts may already be at there proper level. Either way,
+ * setting the initial isr level properly here is safe.
+ *
+ * Currently this is only really needed for the posix port,
+ * ref: _Context_Switch in unix/cpu.c
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _Thread_Handler( void )
+{
+ ISR_Level level;
+ Thread_Control *executing;
+#if defined(__USE_INIT_FINI__) || defined(__USE__MAIN__)
+ static char doneConstructors;
+ char doneCons;
+#endif
+#if defined(__USE_INIT_FINI__)
+ extern void _init(void);
+#endif
+#if defined(__USE__MAIN__)
+ extern void _main(void);
+#endif
+
+ executing = _Thread_Executing;
+
+ /*
+ * have to put level into a register for those cpu's that use
+ * inline asm here
+ */
+
+ level = executing->Start.isr_level;
+ _ISR_Set_level(level);
+
+#if defined(__USE_INIT_FINI__) || defined(__USE__MAIN__)
+ doneCons = doneConstructors;
+ doneConstructors = 1;
+#endif
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
+ if ( (executing->fp_context != NULL) && !_Thread_Is_allocated_fp( executing ) ) {
+ if ( _Thread_Allocated_fp != NULL )
+ _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
+ _Thread_Allocated_fp = executing;
+ }
+#endif
+#endif
+
+
+ /*
+ * Take care that 'begin' extensions get to complete before
+ * 'switch' extensions can run. This means must keep dispatch
+ * disabled until all 'begin' extensions complete.
+ */
+
+ _User_extensions_Thread_begin( executing );
+
+ /*
+ * At this point, the dispatch disable level BETTER be 1.
+ */
+
+ _Thread_Enable_dispatch();
+#if defined(__USE_INIT_FINI__)
+ if (!doneCons && (volatile void *)_init)
+ _init ();
+#endif
+#if defined(__USE__MAIN__)
+ if (!doneCons && _main)
+ __main ();
+#endif
+
+
+ switch ( executing->Start.prototype ) {
+ case THREAD_START_NUMERIC:
+ executing->Wait.return_argument =
+ (*(Thread_Entry_numeric) executing->Start.entry_point)(
+ executing->Start.numeric_argument
+ );
+ break;
+ case THREAD_START_POINTER:
+ executing->Wait.return_argument =
+ (*(Thread_Entry_pointer) executing->Start.entry_point)(
+ executing->Start.pointer_argument
+ );
+ break;
+ case THREAD_START_BOTH_POINTER_FIRST:
+ executing->Wait.return_argument =
+ (*(Thread_Entry_both_pointer_first) executing->Start.entry_point)(
+ executing->Start.pointer_argument,
+ executing->Start.numeric_argument
+ );
+ break;
+ case THREAD_START_BOTH_NUMERIC_FIRST:
+ executing->Wait.return_argument =
+ (*(Thread_Entry_both_numeric_first) executing->Start.entry_point)(
+ executing->Start.numeric_argument,
+ executing->Start.pointer_argument
+ );
+ break;
+ }
+
+ /*
+ * In the switch above, the return code from the user thread body
+ * was placed in return_argument. This assumed that if it returned
+ * anything (which is not supporting in all APIs), then it would be
+ * able to fit in a (void *).
+ */
+
+ _User_extensions_Thread_exitted( executing );
+
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_THREAD_EXITTED
+ );
+}
diff --git a/cpukit/score/src/threadidlebody.c b/cpukit/score/src/threadidlebody.c
new file mode 100644
index 0000000000..22856f7bd1
--- /dev/null
+++ b/cpukit/score/src/threadidlebody.c
@@ -0,0 +1,55 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Idle_body
+ *
+ * This kernel routine is the idle thread. The idle thread runs any time
+ * no other thread is ready to run. This thread loops forever with
+ * interrupts enabled.
+ *
+ * Input parameters:
+ * ignored - this parameter is ignored
+ *
+ * Output parameters: NONE
+ */
+
+#if (CPU_PROVIDES_IDLE_THREAD_BODY == FALSE)
+Thread _Thread_Idle_body(
+ uint32_t ignored
+)
+{
+ for( ; ; ) ;
+ return 0; /* to avoid warning */
+}
+#endif
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
new file mode 100644
index 0000000000..0ed4cdfe69
--- /dev/null
+++ b/cpukit/score/src/threadinitialize.c
@@ -0,0 +1,228 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Initialize
+ *
+ * This routine initializes the specified the thread. It allocates
+ * all memory associated with this thread. It completes by adding
+ * the thread to the local object table so operations on this
+ * thread id are allowed.
+ */
+
+boolean _Thread_Initialize(
+ Objects_Information *information,
+ Thread_Control *the_thread,
+ void *stack_area,
+ uint32_t stack_size,
+ boolean is_fp,
+ Priority_Control priority,
+ boolean is_preemptible,
+ Thread_CPU_budget_algorithms budget_algorithm,
+ Thread_CPU_budget_algorithm_callout budget_callout,
+ uint32_t isr_level,
+ Objects_Name name
+)
+{
+ uint32_t actual_stack_size = 0;
+ void *stack = NULL;
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ void *fp_area;
+#endif
+ void *extensions_area;
+
+ /*
+ * Initialize the Ada self pointer
+ */
+
+ the_thread->rtems_ada_self = NULL;
+
+ /*
+ * Allocate and Initialize the stack for this thread.
+ */
+
+
+ if ( !stack_area ) {
+ if ( !_Stack_Is_enough( stack_size ) )
+ actual_stack_size = STACK_MINIMUM_SIZE;
+ else
+ actual_stack_size = stack_size;
+
+ actual_stack_size = _Thread_Stack_Allocate( the_thread, actual_stack_size );
+
+ if ( !actual_stack_size || actual_stack_size < stack_size )
+ return FALSE; /* stack allocation failed */
+
+ stack = the_thread->Start.stack;
+ the_thread->Start.core_allocated_stack = TRUE;
+ } else {
+ stack = stack_area;
+ actual_stack_size = stack_size;
+ the_thread->Start.core_allocated_stack = FALSE;
+ }
+
+ _Stack_Initialize(
+ &the_thread->Start.Initial_stack,
+ stack,
+ actual_stack_size
+ );
+
+ /*
+ * Allocate the floating point area for this thread
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ if ( is_fp ) {
+
+ fp_area = _Workspace_Allocate( CONTEXT_FP_SIZE );
+ if ( !fp_area ) {
+ _Thread_Stack_Free( the_thread );
+ return FALSE;
+ }
+ fp_area = _Context_Fp_start( fp_area, 0 );
+
+ } else
+ fp_area = NULL;
+
+ the_thread->fp_context = fp_area;
+ the_thread->Start.fp_context = fp_area;
+#endif
+
+ /*
+ * Initialize the thread timer
+ */
+ _Watchdog_Initialize( &the_thread->Timer, NULL, 0, NULL );
+
+ /*
+ * Clear the libc reent hook.
+ */
+
+ the_thread->libc_reent = NULL;
+
+ /*
+ * Allocate the extensions area for this thread
+ */
+
+ if ( _Thread_Maximum_extensions ) {
+ extensions_area = _Workspace_Allocate(
+ (_Thread_Maximum_extensions + 1) * sizeof( void * )
+ );
+
+ if ( !extensions_area ) {
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ if ( fp_area )
+ (void) _Workspace_Free( fp_area );
+#endif
+
+ _Thread_Stack_Free( the_thread );
+
+ return FALSE;
+ }
+ } else
+ extensions_area = NULL;
+
+ the_thread->extensions = (void **) extensions_area;
+
+ /*
+ * Clear the extensions area so extension users can determine
+ * if they are linked to the thread. An extension user may
+ * create the extension long after tasks have been created
+ * so they cannot rely on the thread create user extension
+ * call.
+ */
+
+ if ( the_thread->extensions ) {
+ int i;
+ for ( i = 0; i < (_Thread_Maximum_extensions + 1); i++ )
+ the_thread->extensions[i] = NULL;
+ }
+
+ /*
+ * General initialization
+ */
+
+ the_thread->Start.is_preemptible = is_preemptible;
+ the_thread->Start.budget_algorithm = budget_algorithm;
+ the_thread->Start.budget_callout = budget_callout;
+
+ switch ( budget_algorithm ) {
+ case THREAD_CPU_BUDGET_ALGORITHM_NONE:
+ case THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE:
+ break;
+ case THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE:
+ the_thread->cpu_time_budget = _Thread_Ticks_per_timeslice;
+ break;
+ case THREAD_CPU_BUDGET_ALGORITHM_CALLOUT:
+ break;
+ }
+
+ the_thread->Start.isr_level = isr_level;
+
+ the_thread->current_state = STATES_DORMANT;
+ the_thread->resource_count = 0;
+ the_thread->suspend_count = 0;
+ the_thread->real_priority = priority;
+ the_thread->Start.initial_priority = priority;
+ the_thread->ticks_executed = 0;
+
+ _Thread_Set_priority( the_thread, priority );
+
+ /*
+ * Open the object
+ */
+
+ _Objects_Open( information, &the_thread->Object, name );
+
+ /*
+ * Invoke create extensions
+ */
+
+ if ( !_User_extensions_Thread_create( the_thread ) ) {
+
+ if ( extensions_area )
+ (void) _Workspace_Free( extensions_area );
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ if ( fp_area )
+ (void) _Workspace_Free( fp_area );
+#endif
+
+ _Thread_Stack_Free( the_thread );
+
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
diff --git a/cpukit/score/src/threadloadenv.c b/cpukit/score/src/threadloadenv.c
new file mode 100644
index 0000000000..b586a20621
--- /dev/null
+++ b/cpukit/score/src/threadloadenv.c
@@ -0,0 +1,76 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Load_environment
+ *
+ * Load starting environment for another thread from its start area in the
+ * thread. Only called from t_restart and t_start.
+ *
+ * Input parameters:
+ * the_thread - thread control block pointer
+ *
+ * Output parameters: NONE
+ */
+
+void _Thread_Load_environment(
+ Thread_Control *the_thread
+)
+{
+ boolean is_fp;
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ if ( the_thread->Start.fp_context ) {
+ the_thread->fp_context = the_thread->Start.fp_context;
+ _Context_Initialize_fp( &the_thread->fp_context );
+ is_fp = TRUE;
+ } else
+#endif
+ is_fp = FALSE;
+
+
+ the_thread->do_post_task_switch_extension = FALSE;
+ the_thread->is_preemptible = the_thread->Start.is_preemptible;
+ the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
+ the_thread->budget_callout = the_thread->Start.budget_callout;
+
+ _Context_Initialize(
+ &the_thread->Registers,
+ the_thread->Start.Initial_stack.area,
+ the_thread->Start.Initial_stack.size,
+ the_thread->Start.isr_level,
+ _Thread_Handler,
+ is_fp
+ );
+
+}
diff --git a/cpukit/score/src/threadmp.c b/cpukit/score/src/threadmp.c
new file mode 100644
index 0000000000..8cac0a99b9
--- /dev/null
+++ b/cpukit/score/src/threadmp.c
@@ -0,0 +1,168 @@
+/*
+ * Multiprocessing Support for the Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/mpci.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/isr.h>
+
+/*PAGE
+ *
+ * _Thread_MP_Handler_initialization
+ *
+ */
+
+void _Thread_MP_Handler_initialization (
+ uint32_t maximum_proxies
+)
+{
+
+ _Chain_Initialize_empty( &_Thread_MP_Active_proxies );
+
+ if ( maximum_proxies == 0 ) {
+ _Chain_Initialize_empty( &_Thread_MP_Inactive_proxies );
+ return;
+ }
+
+
+ _Chain_Initialize(
+ &_Thread_MP_Inactive_proxies,
+ _Workspace_Allocate_or_fatal_error(
+ maximum_proxies * sizeof( Thread_Proxy_control )
+ ),
+ maximum_proxies,
+ sizeof( Thread_Proxy_control )
+ );
+
+}
+
+/*PAGE
+ *
+ * _Thread_MP_Allocate_proxy
+ *
+ */
+
+Thread_Control *_Thread_MP_Allocate_proxy (
+ States_Control the_state
+)
+{
+ Thread_Control *the_thread;
+ Thread_Proxy_control *the_proxy;
+
+ the_thread = (Thread_Control *)_Chain_Get( &_Thread_MP_Inactive_proxies );
+
+ if ( !_Thread_Is_null( the_thread ) ) {
+
+ the_proxy = (Thread_Proxy_control *) the_thread;
+
+ _Thread_Executing->Wait.return_code = THREAD_STATUS_PROXY_BLOCKING;
+
+ the_proxy->receive_packet = _MPCI_Receive_server_tcb->receive_packet;
+
+ the_proxy->Object.id = _MPCI_Receive_server_tcb->receive_packet->source_tid;
+
+ the_proxy->current_priority =
+ _MPCI_Receive_server_tcb->receive_packet->source_priority;
+
+ the_proxy->current_state = _States_Set( STATES_DORMANT, the_state );
+
+ the_proxy->Wait = _Thread_Executing->Wait;
+
+ _Chain_Append( &_Thread_MP_Active_proxies, &the_proxy->Active );
+
+ return the_thread;
+ }
+
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_OUT_OF_PROXIES
+ );
+
+ /*
+ * NOTE: The following return ensures that the compiler will
+ * think that all paths return a value.
+ */
+
+ return NULL;
+}
+
+/*PAGE
+ *
+ * _Thread_MP_Find_proxy
+ *
+ */
+
+/*
+ * The following macro provides the offset of the Active element
+ * in the Thread_Proxy_control structure. This is the logical
+ * equivalent of the POSITION attribute in Ada.
+ */
+
+#define _Thread_MP_Proxy_Active_offset \
+ ((uint32_t )&(((Thread_Proxy_control *)0))->Active)
+
+Thread_Control *_Thread_MP_Find_proxy (
+ Objects_Id the_id
+)
+{
+
+ Chain_Node *proxy_node;
+ Thread_Control *the_thread;
+ ISR_Level level;
+
+restart:
+
+ _ISR_Disable( level );
+
+ for ( proxy_node = _Thread_MP_Active_proxies.first;
+ !_Chain_Is_tail( &_Thread_MP_Active_proxies, proxy_node ) ;
+ ) {
+
+ the_thread = (Thread_Control *) _Addresses_Subtract_offset(
+ proxy_node,
+ _Thread_MP_Proxy_Active_offset
+ );
+
+ if ( _Objects_Are_ids_equal( the_thread->Object.id, the_id ) ) {
+ _ISR_Enable( level );
+ return the_thread;
+ }
+
+ _ISR_Flash( level );
+
+ proxy_node = proxy_node->next;
+
+ /*
+ * A proxy which is only dormant is not in a blocking state.
+ * Therefore, we are looking at proxy which has been moved from
+ * active to inactive chain (by an ISR) and need to restart
+ * the search.
+ */
+
+ if ( _States_Is_only_dormant( the_thread->current_state ) ) {
+ _ISR_Enable( level );
+ goto restart;
+ }
+ }
+
+ _ISR_Enable( level );
+ return NULL;
+}
diff --git a/cpukit/score/src/threadq.c b/cpukit/score/src/threadq.c
new file mode 100644
index 0000000000..d17c3d8f7e
--- /dev/null
+++ b/cpukit/score/src/threadq.c
@@ -0,0 +1,69 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Initialize
+ *
+ * This routine initializes the specified threadq.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to a threadq header
+ * discipline - queueing discipline
+ * state - state of waiting threads
+ * timeout_status - return on a timeout
+ *
+ * Output parameters: NONE
+ */
+
+void _Thread_queue_Initialize(
+ Thread_queue_Control *the_thread_queue,
+ Thread_queue_Disciplines the_discipline,
+ States_Control state,
+ uint32_t timeout_status
+)
+{
+ uint32_t index;
+
+ the_thread_queue->state = state;
+ the_thread_queue->discipline = the_discipline;
+ the_thread_queue->timeout_status = timeout_status;
+ the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED;
+
+ switch ( the_discipline ) {
+ case THREAD_QUEUE_DISCIPLINE_FIFO:
+ _Chain_Initialize_empty( &the_thread_queue->Queues.Fifo );
+ break;
+ case THREAD_QUEUE_DISCIPLINE_PRIORITY:
+ for( index=0 ;
+ index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
+ index++)
+ _Chain_Initialize_empty( &the_thread_queue->Queues.Priority[index] );
+ break;
+ }
+
+}
diff --git a/cpukit/score/src/threadqdequeue.c b/cpukit/score/src/threadqdequeue.c
new file mode 100644
index 0000000000..d5968b0210
--- /dev/null
+++ b/cpukit/score/src/threadqdequeue.c
@@ -0,0 +1,65 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Dequeue
+ *
+ * This routine removes a thread from the specified threadq. If the
+ * threadq discipline is FIFO, it unblocks a thread, and cancels its
+ * timeout timer. Priority discipline is processed elsewhere.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to threadq
+ *
+ * Output parameters:
+ * returns - thread dequeued or NULL
+ *
+ * INTERRUPT LATENCY:
+ * check sync
+ */
+
+Thread_Control *_Thread_queue_Dequeue(
+ Thread_queue_Control *the_thread_queue
+)
+{
+ Thread_Control *the_thread;
+
+ switch ( the_thread_queue->discipline ) {
+ case THREAD_QUEUE_DISCIPLINE_FIFO:
+ the_thread = _Thread_queue_Dequeue_fifo( the_thread_queue );
+ break;
+ case THREAD_QUEUE_DISCIPLINE_PRIORITY:
+ the_thread = _Thread_queue_Dequeue_priority( the_thread_queue );
+ break;
+ default: /* this is only to prevent warnings */
+ the_thread = NULL;
+ break;
+ }
+
+ return( the_thread );
+}
diff --git a/cpukit/score/src/threadqdequeuefifo.c b/cpukit/score/src/threadqdequeuefifo.c
new file mode 100644
index 0000000000..ff76bff3d9
--- /dev/null
+++ b/cpukit/score/src/threadqdequeuefifo.c
@@ -0,0 +1,89 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Dequeue_fifo
+ *
+ * This routine removes a thread from the specified threadq.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to threadq
+ *
+ * Output parameters:
+ * returns - thread dequeued or NULL
+ *
+ * INTERRUPT LATENCY:
+ * check sync
+ * FIFO
+ */
+
+Thread_Control *_Thread_queue_Dequeue_fifo(
+ Thread_queue_Control *the_thread_queue
+)
+{
+ ISR_Level level;
+ Thread_Control *the_thread;
+
+ _ISR_Disable( level );
+ if ( !_Chain_Is_empty( &the_thread_queue->Queues.Fifo ) ) {
+
+ the_thread = (Thread_Control *)
+ _Chain_Get_first_unprotected( &the_thread_queue->Queues.Fifo );
+
+ if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
+ _ISR_Enable( level );
+ _Thread_Unblock( the_thread );
+ } else {
+ _Watchdog_Deactivate( &the_thread->Timer );
+ _ISR_Enable( level );
+ (void) _Watchdog_Remove( &the_thread->Timer );
+ _Thread_Unblock( the_thread );
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ _Thread_MP_Free_proxy( the_thread );
+#endif
+
+ return the_thread;
+ }
+
+ switch ( the_thread_queue->sync_state ) {
+ case THREAD_QUEUE_SYNCHRONIZED:
+ case THREAD_QUEUE_SATISFIED:
+ _ISR_Enable( level );
+ return NULL;
+
+ case THREAD_QUEUE_NOTHING_HAPPENED:
+ case THREAD_QUEUE_TIMEOUT:
+ the_thread_queue->sync_state = THREAD_QUEUE_SATISFIED;
+ _ISR_Enable( level );
+ return _Thread_Executing;
+ }
+ return NULL; /* this is only to prevent warnings */
+}
diff --git a/cpukit/score/src/threadqdequeuepriority.c b/cpukit/score/src/threadqdequeuepriority.c
new file mode 100644
index 0000000000..1b02a71158
--- /dev/null
+++ b/cpukit/score/src/threadqdequeuepriority.c
@@ -0,0 +1,128 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Dequeue_priority
+ *
+ * This routine removes a thread from the specified PRIORITY based
+ * threadq, unblocks it, and cancels its timeout timer.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to thread queue
+ *
+ * Output parameters:
+ * returns - thread dequeued or NULL
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+Thread_Control *_Thread_queue_Dequeue_priority(
+ Thread_queue_Control *the_thread_queue
+)
+{
+ uint32_t index;
+ ISR_Level level;
+ Thread_Control *the_thread = NULL; /* just to remove warnings */
+ Thread_Control *new_first_thread;
+ Chain_Node *new_first_node;
+ Chain_Node *new_second_node;
+ Chain_Node *last_node;
+ Chain_Node *next_node;
+ Chain_Node *previous_node;
+
+ _ISR_Disable( level );
+ for( index=0 ;
+ index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
+ index++ ) {
+ if ( !_Chain_Is_empty( &the_thread_queue->Queues.Priority[ index ] ) ) {
+ the_thread = (Thread_Control *)
+ the_thread_queue->Queues.Priority[ index ].first;
+ goto dequeue;
+ }
+ }
+
+ switch ( the_thread_queue->sync_state ) {
+ case THREAD_QUEUE_SYNCHRONIZED:
+ case THREAD_QUEUE_SATISFIED:
+ _ISR_Enable( level );
+ return NULL;
+
+ case THREAD_QUEUE_NOTHING_HAPPENED:
+ case THREAD_QUEUE_TIMEOUT:
+ the_thread_queue->sync_state = THREAD_QUEUE_SATISFIED;
+ _ISR_Enable( level );
+ return _Thread_Executing;
+ }
+
+dequeue:
+ new_first_node = the_thread->Wait.Block2n.first;
+ new_first_thread = (Thread_Control *) new_first_node;
+ next_node = the_thread->Object.Node.next;
+ previous_node = the_thread->Object.Node.previous;
+
+ if ( !_Chain_Is_empty( &the_thread->Wait.Block2n ) ) {
+ last_node = the_thread->Wait.Block2n.last;
+ new_second_node = new_first_node->next;
+
+ previous_node->next = new_first_node;
+ next_node->previous = new_first_node;
+ new_first_node->next = next_node;
+ new_first_node->previous = previous_node;
+
+ if ( !_Chain_Has_only_one_node( &the_thread->Wait.Block2n ) ) {
+ /* > two threads on 2-n */
+ new_second_node->previous =
+ _Chain_Head( &new_first_thread->Wait.Block2n );
+
+ new_first_thread->Wait.Block2n.first = new_second_node;
+ new_first_thread->Wait.Block2n.last = last_node;
+
+ last_node->next = _Chain_Tail( &new_first_thread->Wait.Block2n );
+ }
+ } else {
+ previous_node->next = next_node;
+ next_node->previous = previous_node;
+ }
+
+ if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
+ _ISR_Enable( level );
+ _Thread_Unblock( the_thread );
+ } else {
+ _Watchdog_Deactivate( &the_thread->Timer );
+ _ISR_Enable( level );
+ (void) _Watchdog_Remove( &the_thread->Timer );
+ _Thread_Unblock( the_thread );
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ _Thread_MP_Free_proxy( the_thread );
+#endif
+ return( the_thread );
+}
diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c
new file mode 100644
index 0000000000..848b256b53
--- /dev/null
+++ b/cpukit/score/src/threadqenqueue.c
@@ -0,0 +1,83 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+/*PAGE
+ *
+ * _Thread_queue_Enqueue
+ *
+ * This routine blocks a thread, places it on a thread, and optionally
+ * starts a timeout timer.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to threadq
+ * timeout - interval to wait
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+void _Thread_queue_Enqueue(
+ Thread_queue_Control *the_thread_queue,
+ Watchdog_Interval timeout
+)
+{
+ Thread_Control *the_thread;
+
+ the_thread = _Thread_Executing;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet )
+ the_thread = _Thread_MP_Allocate_proxy( the_thread_queue->state );
+ else
+#endif
+ _Thread_Set_state( the_thread, the_thread_queue->state );
+
+ if ( timeout ) {
+ _Watchdog_Initialize(
+ &the_thread->Timer,
+ _Thread_queue_Timeout,
+ the_thread->Object.id,
+ NULL
+ );
+
+ _Watchdog_Insert_ticks( &the_thread->Timer, timeout );
+ }
+
+ switch( the_thread_queue->discipline ) {
+ case THREAD_QUEUE_DISCIPLINE_FIFO:
+ _Thread_queue_Enqueue_fifo( the_thread_queue, the_thread );
+ break;
+ case THREAD_QUEUE_DISCIPLINE_PRIORITY:
+ _Thread_queue_Enqueue_priority( the_thread_queue, the_thread );
+ break;
+ }
+}
diff --git a/cpukit/score/src/threadqenqueuefifo.c b/cpukit/score/src/threadqenqueuefifo.c
new file mode 100644
index 0000000000..b4cba6a532
--- /dev/null
+++ b/cpukit/score/src/threadqenqueuefifo.c
@@ -0,0 +1,101 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Enqueue_fifo
+ *
+ * This routine places a blocked thread on a FIFO thread queue.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to threadq
+ * the_thread - pointer to the thread to block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+void _Thread_queue_Enqueue_fifo (
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread
+)
+{
+ ISR_Level level;
+ Thread_queue_States sync_state;
+
+ _ISR_Disable( level );
+
+ sync_state = the_thread_queue->sync_state;
+ the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED;
+
+ switch ( sync_state ) {
+ case THREAD_QUEUE_SYNCHRONIZED:
+ /*
+ * This should never happen. It indicates that someone did not
+ * enter a thread queue critical section.
+ */
+ break;
+
+ case THREAD_QUEUE_NOTHING_HAPPENED:
+ _Chain_Append_unprotected(
+ &the_thread_queue->Queues.Fifo,
+ &the_thread->Object.Node
+ );
+ _ISR_Enable( level );
+ return;
+
+ case THREAD_QUEUE_TIMEOUT:
+ the_thread->Wait.return_code = the_thread->Wait.queue->timeout_status;
+ _ISR_Enable( level );
+ break;
+
+ case THREAD_QUEUE_SATISFIED:
+ if ( _Watchdog_Is_active( &the_thread->Timer ) ) {
+ _Watchdog_Deactivate( &the_thread->Timer );
+ _ISR_Enable( level );
+ (void) _Watchdog_Remove( &the_thread->Timer );
+ } else
+ _ISR_Enable( level );
+ break;
+ }
+
+ /*
+ * Global objects with thread queue's should not be operated on from an
+ * ISR. But the sync code still must allow short timeouts to be processed
+ * correctly.
+ */
+
+ _Thread_Unblock( the_thread );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ _Thread_MP_Free_proxy( the_thread );
+#endif
+
+}
diff --git a/cpukit/score/src/threadqenqueuepriority.c b/cpukit/score/src/threadqenqueuepriority.c
new file mode 100644
index 0000000000..5c49a4c6d8
--- /dev/null
+++ b/cpukit/score/src/threadqenqueuepriority.c
@@ -0,0 +1,221 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Enqueue_priority
+ *
+ * This routine places a blocked thread on a priority thread queue.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to threadq
+ * thread - thread to insert
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * forward less than
+ * forward equal
+ */
+
+void _Thread_queue_Enqueue_priority(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread
+)
+{
+ Priority_Control search_priority;
+ Thread_Control *search_thread;
+ ISR_Level level;
+ Chain_Control *header;
+ uint32_t header_index;
+ Chain_Node *the_node;
+ Chain_Node *next_node;
+ Chain_Node *previous_node;
+ Chain_Node *search_node;
+ Priority_Control priority;
+ States_Control block_state;
+ Thread_queue_States sync_state;
+
+ _Chain_Initialize_empty( &the_thread->Wait.Block2n );
+
+ priority = the_thread->current_priority;
+ header_index = _Thread_queue_Header_number( priority );
+ header = &the_thread_queue->Queues.Priority[ header_index ];
+ block_state = the_thread_queue->state;
+
+ if ( _Thread_queue_Is_reverse_search( priority ) )
+ goto restart_reverse_search;
+
+restart_forward_search:
+ search_priority = PRIORITY_MINIMUM - 1;
+ _ISR_Disable( level );
+ search_thread = (Thread_Control *) header->first;
+ while ( !_Chain_Is_tail( header, (Chain_Node *)search_thread ) ) {
+ search_priority = search_thread->current_priority;
+ if ( priority <= search_priority )
+ break;
+
+#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE )
+ search_thread = (Thread_Control *) search_thread->Object.Node.next;
+ if ( _Chain_Is_tail( header, (Chain_Node *)search_thread ) )
+ break;
+ search_priority = search_thread->current_priority;
+ if ( priority <= search_priority )
+ break;
+#endif
+ _ISR_Flash( level );
+ if ( !_States_Are_set( search_thread->current_state, block_state) ) {
+ _ISR_Enable( level );
+ goto restart_forward_search;
+ }
+ search_thread =
+ (Thread_Control *)search_thread->Object.Node.next;
+ }
+
+ if ( the_thread_queue->sync_state != THREAD_QUEUE_NOTHING_HAPPENED )
+ goto synchronize;
+
+ the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED;
+
+ if ( priority == search_priority )
+ goto equal_priority;
+
+ search_node = (Chain_Node *) search_thread;
+ previous_node = search_node->previous;
+ the_node = (Chain_Node *) the_thread;
+
+ the_node->next = search_node;
+ the_node->previous = previous_node;
+ previous_node->next = the_node;
+ search_node->previous = the_node;
+ _ISR_Enable( level );
+ return;
+
+restart_reverse_search:
+ search_priority = PRIORITY_MAXIMUM + 1;
+
+ _ISR_Disable( level );
+ search_thread = (Thread_Control *) header->last;
+ while ( !_Chain_Is_head( header, (Chain_Node *)search_thread ) ) {
+ search_priority = search_thread->current_priority;
+ if ( priority >= search_priority )
+ break;
+#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE )
+ search_thread = (Thread_Control *) search_thread->Object.Node.previous;
+ if ( _Chain_Is_head( header, (Chain_Node *)search_thread ) )
+ break;
+ search_priority = search_thread->current_priority;
+ if ( priority >= search_priority )
+ break;
+#endif
+ _ISR_Flash( level );
+ if ( !_States_Are_set( search_thread->current_state, block_state) ) {
+ _ISR_Enable( level );
+ goto restart_reverse_search;
+ }
+ search_thread = (Thread_Control *)
+ search_thread->Object.Node.previous;
+ }
+
+ if ( the_thread_queue->sync_state != THREAD_QUEUE_NOTHING_HAPPENED )
+ goto synchronize;
+
+ the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED;
+
+ if ( priority == search_priority )
+ goto equal_priority;
+
+ search_node = (Chain_Node *) search_thread;
+ next_node = search_node->next;
+ the_node = (Chain_Node *) the_thread;
+
+ the_node->next = next_node;
+ the_node->previous = search_node;
+ search_node->next = the_node;
+ next_node->previous = the_node;
+ _ISR_Enable( level );
+ return;
+
+equal_priority: /* add at end of priority group */
+ search_node = _Chain_Tail( &search_thread->Wait.Block2n );
+ previous_node = search_node->previous;
+ the_node = (Chain_Node *) the_thread;
+
+ the_node->next = search_node;
+ the_node->previous = previous_node;
+ previous_node->next = the_node;
+ search_node->previous = the_node;
+ _ISR_Enable( level );
+ return;
+
+synchronize:
+
+ sync_state = the_thread_queue->sync_state;
+ the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED;
+
+ switch ( sync_state ) {
+ case THREAD_QUEUE_SYNCHRONIZED:
+ /*
+ * This should never happen. It indicates that someone did not
+ * enter a thread queue critical section.
+ */
+ break;
+
+ case THREAD_QUEUE_NOTHING_HAPPENED:
+ /*
+ * This should never happen. All of this was dealt with above.
+ */
+ break;
+
+ case THREAD_QUEUE_TIMEOUT:
+ the_thread->Wait.return_code = the_thread->Wait.queue->timeout_status;
+ _ISR_Enable( level );
+ break;
+
+ case THREAD_QUEUE_SATISFIED:
+ if ( _Watchdog_Is_active( &the_thread->Timer ) ) {
+ _Watchdog_Deactivate( &the_thread->Timer );
+ _ISR_Enable( level );
+ (void) _Watchdog_Remove( &the_thread->Timer );
+ } else
+ _ISR_Enable( level );
+ break;
+ }
+
+ /*
+ * Global objects with thread queue's should not be operated on from an
+ * ISR. But the sync code still must allow short timeouts to be processed
+ * correctly.
+ */
+
+ _Thread_Unblock( the_thread );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ _Thread_MP_Free_proxy( the_thread );
+#endif
+}
diff --git a/cpukit/score/src/threadqextract.c b/cpukit/score/src/threadqextract.c
new file mode 100644
index 0000000000..a8faef03f7
--- /dev/null
+++ b/cpukit/score/src/threadqextract.c
@@ -0,0 +1,57 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Extract
+ *
+ * This routine removes a specific thread from the specified threadq,
+ * deletes any timeout, and unblocks the thread.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to a threadq header
+ * the_thread - pointer to a thread control block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY: NONE
+ */
+
+void _Thread_queue_Extract(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread
+)
+{
+ switch ( the_thread_queue->discipline ) {
+ case THREAD_QUEUE_DISCIPLINE_FIFO:
+ _Thread_queue_Extract_fifo( the_thread_queue, the_thread );
+ break;
+ case THREAD_QUEUE_DISCIPLINE_PRIORITY:
+ _Thread_queue_Extract_priority( the_thread_queue, the_thread );
+ break;
+ }
+}
diff --git a/cpukit/score/src/threadqextractfifo.c b/cpukit/score/src/threadqextractfifo.c
new file mode 100644
index 0000000000..145bf314a3
--- /dev/null
+++ b/cpukit/score/src/threadqextractfifo.c
@@ -0,0 +1,76 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Extract_fifo
+ *
+ * This routine removes a specific thread from the specified threadq,
+ * deletes any timeout, and unblocks the thread.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to a threadq header
+ * the_thread - pointer to the thread to block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * EXTRACT_FIFO
+ */
+
+void _Thread_queue_Extract_fifo(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread
+)
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+
+ if ( !_States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
+ _ISR_Enable( level );
+ return;
+ }
+
+ _Chain_Extract_unprotected( &the_thread->Object.Node );
+
+ if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
+ _ISR_Enable( level );
+ } else {
+ _Watchdog_Deactivate( &the_thread->Timer );
+ _ISR_Enable( level );
+ (void) _Watchdog_Remove( &the_thread->Timer );
+ }
+
+ _Thread_Unblock( the_thread );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ _Thread_MP_Free_proxy( the_thread );
+#endif
+
+}
diff --git a/cpukit/score/src/threadqextractpriority.c b/cpukit/score/src/threadqextractpriority.c
new file mode 100644
index 0000000000..dfadc25425
--- /dev/null
+++ b/cpukit/score/src/threadqextractpriority.c
@@ -0,0 +1,107 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Extract_priority
+ *
+ * This routine removes a specific thread from the specified threadq,
+ * deletes any timeout, and unblocks the thread.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to a threadq header
+ * the_thread - pointer to a thread control block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * EXTRACT_PRIORITY
+ */
+
+void _Thread_queue_Extract_priority(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread
+)
+{
+ ISR_Level level;
+ Chain_Node *the_node;
+ Chain_Node *next_node;
+ Chain_Node *previous_node;
+ Thread_Control *new_first_thread;
+ Chain_Node *new_first_node;
+ Chain_Node *new_second_node;
+ Chain_Node *last_node;
+
+ the_node = (Chain_Node *) the_thread;
+ _ISR_Disable( level );
+ if ( _States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
+ next_node = the_node->next;
+ previous_node = the_node->previous;
+
+ if ( !_Chain_Is_empty( &the_thread->Wait.Block2n ) ) {
+ new_first_node = the_thread->Wait.Block2n.first;
+ new_first_thread = (Thread_Control *) new_first_node;
+ last_node = the_thread->Wait.Block2n.last;
+ new_second_node = new_first_node->next;
+
+ previous_node->next = new_first_node;
+ next_node->previous = new_first_node;
+ new_first_node->next = next_node;
+ new_first_node->previous = previous_node;
+
+ if ( !_Chain_Has_only_one_node( &the_thread->Wait.Block2n ) ) {
+ /* > two threads on 2-n */
+ new_second_node->previous =
+ _Chain_Head( &new_first_thread->Wait.Block2n );
+ new_first_thread->Wait.Block2n.first = new_second_node;
+
+ new_first_thread->Wait.Block2n.last = last_node;
+ last_node->next = _Chain_Tail( &new_first_thread->Wait.Block2n );
+ }
+ } else {
+ previous_node->next = next_node;
+ next_node->previous = previous_node;
+ }
+
+ if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
+ _ISR_Enable( level );
+ _Thread_Unblock( the_thread );
+ } else {
+ _Watchdog_Deactivate( &the_thread->Timer );
+ _ISR_Enable( level );
+ (void) _Watchdog_Remove( &the_thread->Timer );
+ _Thread_Unblock( the_thread );
+ }
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ _Thread_MP_Free_proxy( the_thread );
+#endif
+ }
+ else
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/threadqextractwithproxy.c b/cpukit/score/src/threadqextractwithproxy.c
new file mode 100644
index 0000000000..fcf071a9ae
--- /dev/null
+++ b/cpukit/score/src/threadqextractwithproxy.c
@@ -0,0 +1,66 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Extract_with_proxy
+ *
+ * This routine extracts the_thread from the_thread_queue
+ * and ensures that if there is a proxy for this task on
+ * another node, it is also dealt with.
+ *
+ * XXX
+ */
+
+boolean _Thread_queue_Extract_with_proxy(
+ Thread_Control *the_thread
+)
+{
+ States_Control state;
+ Objects_Information *the_information;
+ Objects_Thread_queue_Extract_callout proxy_extract_callout;
+
+ state = the_thread->current_state;
+
+ if ( _States_Is_waiting_on_thread_queue( state ) ) {
+ if ( _States_Is_waiting_for_rpc_reply( state ) &&
+ _States_Is_locally_blocked( state ) ) {
+
+ the_information = _Objects_Get_information( the_thread->Wait.id );
+
+ proxy_extract_callout =
+ (Objects_Thread_queue_Extract_callout) the_information->extract;
+
+ if ( proxy_extract_callout )
+ (*proxy_extract_callout)( the_thread );
+ }
+ _Thread_queue_Extract( the_thread->Wait.queue, the_thread );
+
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/cpukit/score/src/threadqfirst.c b/cpukit/score/src/threadqfirst.c
new file mode 100644
index 0000000000..bcbe759eda
--- /dev/null
+++ b/cpukit/score/src/threadqfirst.c
@@ -0,0 +1,61 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_First
+ *
+ * This routines returns a pointer to the first thread on the
+ * specified threadq.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to thread queue
+ *
+ * Output parameters:
+ * returns - first thread or NULL
+ */
+
+Thread_Control *_Thread_queue_First(
+ Thread_queue_Control *the_thread_queue
+)
+{
+ Thread_Control *the_thread;
+
+ switch ( the_thread_queue->discipline ) {
+ case THREAD_QUEUE_DISCIPLINE_FIFO:
+ the_thread = _Thread_queue_First_fifo( the_thread_queue );
+ break;
+ case THREAD_QUEUE_DISCIPLINE_PRIORITY:
+ the_thread = _Thread_queue_First_priority( the_thread_queue );
+ break;
+ default: /* this is only to prevent warnings */
+ the_thread = NULL;
+ break;
+ }
+
+ return the_thread;
+}
diff --git a/cpukit/score/src/threadqfirstfifo.c b/cpukit/score/src/threadqfirstfifo.c
new file mode 100644
index 0000000000..b002f1f448
--- /dev/null
+++ b/cpukit/score/src/threadqfirstfifo.c
@@ -0,0 +1,50 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_First_fifo
+ *
+ * This routines returns a pointer to the first thread on the
+ * specified threadq.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to threadq
+ *
+ * Output parameters:
+ * returns - first thread or NULL
+ */
+
+Thread_Control *_Thread_queue_First_fifo(
+ Thread_queue_Control *the_thread_queue
+)
+{
+ if ( !_Chain_Is_empty( &the_thread_queue->Queues.Fifo ) )
+ return (Thread_Control *) the_thread_queue->Queues.Fifo.first;
+
+ return NULL;
+}
diff --git a/cpukit/score/src/threadqfirstpriority.c b/cpukit/score/src/threadqfirstpriority.c
new file mode 100644
index 0000000000..81ac2742eb
--- /dev/null
+++ b/cpukit/score/src/threadqfirstpriority.c
@@ -0,0 +1,56 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_First_priority
+ *
+ * This routines returns a pointer to the first thread on the
+ * specified threadq.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to thread queue
+ *
+ * Output parameters:
+ * returns - first thread or NULL
+ */
+
+Thread_Control *_Thread_queue_First_priority (
+ Thread_queue_Control *the_thread_queue
+)
+{
+ uint32_t index;
+
+ for( index=0 ;
+ index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
+ index++ ) {
+ if ( !_Chain_Is_empty( &the_thread_queue->Queues.Priority[ index ] ) )
+ return (Thread_Control *)
+ the_thread_queue->Queues.Priority[ index ].first;
+ }
+ return NULL;
+}
diff --git a/cpukit/score/src/threadqflush.c b/cpukit/score/src/threadqflush.c
new file mode 100644
index 0000000000..ecb9b0df20
--- /dev/null
+++ b/cpukit/score/src/threadqflush.c
@@ -0,0 +1,58 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Flush
+ *
+ * This kernel routine flushes the given thread queue.
+ *
+ * Input parameters:
+ * the_thread_queue - pointer to threadq to be flushed
+ * remote_extract_callout - pointer to routine which extracts a remote thread
+ * status - status to return to the thread
+ *
+ * Output parameters: NONE
+ */
+
+void _Thread_queue_Flush(
+ Thread_queue_Control *the_thread_queue,
+ Thread_queue_Flush_callout remote_extract_callout,
+ uint32_t status
+)
+{
+ Thread_Control *the_thread;
+
+ while ( (the_thread = _Thread_queue_Dequeue( the_thread_queue )) ) {
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ ( *remote_extract_callout )( the_thread );
+ else
+#endif
+ the_thread->Wait.return_code = status;
+ }
+}
diff --git a/cpukit/score/src/threadqtimeout.c b/cpukit/score/src/threadqtimeout.c
new file mode 100644
index 0000000000..8913aa123a
--- /dev/null
+++ b/cpukit/score/src/threadqtimeout.c
@@ -0,0 +1,81 @@
+/*
+ * Thread Queue Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/tqdata.h>
+
+/*PAGE
+ *
+ * _Thread_queue_Timeout
+ *
+ * This routine processes a thread which timeouts while waiting on
+ * a thread queue. It is called by the watchdog handler.
+ *
+ * Input parameters:
+ * id - thread id
+ *
+ * Output parameters: NONE
+ */
+
+void _Thread_queue_Timeout(
+ Objects_Id id,
+ void *ignored
+)
+{
+ Thread_Control *the_thread;
+ Thread_queue_Control *the_thread_queue;
+ Objects_Locations location;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE: /* impossible */
+ break;
+ case OBJECTS_LOCAL:
+ the_thread_queue = the_thread->Wait.queue;
+
+ /*
+ * If the_thread_queue is not synchronized, then it is either
+ * "nothing happened", "timeout", or "satisfied". If the_thread
+ * is the executing thread, then it is in the process of blocking
+ * and it is the thread which is responsible for the synchronization
+ * process.
+ *
+ * If it is not satisfied, then it is "nothing happened" and
+ * this is the "timeout" transition. After a request is satisfied,
+ * a timeout is not allowed to occur.
+ */
+
+ if ( the_thread_queue->sync_state != THREAD_QUEUE_SYNCHRONIZED &&
+ _Thread_Is_executing( the_thread ) ) {
+ if ( the_thread_queue->sync_state != THREAD_QUEUE_SATISFIED )
+ the_thread_queue->sync_state = THREAD_QUEUE_TIMEOUT;
+ } else {
+ the_thread->Wait.return_code = the_thread->Wait.queue->timeout_status;
+ _Thread_queue_Extract( the_thread->Wait.queue, the_thread );
+ }
+ _Thread_Unnest_dispatch();
+ break;
+ }
+}
diff --git a/cpukit/score/src/threadready.c b/cpukit/score/src/threadready.c
new file mode 100644
index 0000000000..c7f035fec0
--- /dev/null
+++ b/cpukit/score/src/threadready.c
@@ -0,0 +1,78 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Ready
+ *
+ * This kernel routine readies the requested thread, the thread chain
+ * is adjusted. A new heir thread may be selected.
+ *
+ * Input parameters:
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters: NONE
+ *
+ * NOTE: This routine uses the "blocking" heir selection mechanism.
+ * This ensures the correct heir after a thread restart.
+ *
+ * INTERRUPT LATENCY:
+ * ready chain
+ * select heir
+ */
+
+void _Thread_Ready(
+ Thread_Control *the_thread
+)
+{
+ ISR_Level level;
+ Thread_Control *heir;
+
+ _ISR_Disable( level );
+
+ the_thread->current_state = STATES_READY;
+
+ _Priority_Add_to_bit_map( &the_thread->Priority_map );
+
+ _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node );
+
+ _ISR_Flash( level );
+
+ _Thread_Calculate_heir();
+
+ heir = _Thread_Heir;
+
+ if ( !_Thread_Is_executing( heir ) && _Thread_Executing->is_preemptible )
+ _Context_Switch_necessary = TRUE;
+
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/threadreset.c b/cpukit/score/src/threadreset.c
new file mode 100644
index 0000000000..f4c12f38f7
--- /dev/null
+++ b/cpukit/score/src/threadreset.c
@@ -0,0 +1,68 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * _Thread_Reset
+ *
+ * DESCRIPTION:
+ *
+ * This routine resets a thread to its initial stat but does
+ * not actually restart it. Some APIs do this in separate
+ * operations and this division helps support this.
+ */
+
+void _Thread_Reset(
+ Thread_Control *the_thread,
+ void *pointer_argument,
+ uint32_t numeric_argument
+)
+{
+ the_thread->resource_count = 0;
+ the_thread->suspend_count = 0;
+ the_thread->is_preemptible = the_thread->Start.is_preemptible;
+ the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
+ the_thread->budget_callout = the_thread->Start.budget_callout;
+
+ the_thread->Start.pointer_argument = pointer_argument;
+ the_thread->Start.numeric_argument = numeric_argument;
+
+ if ( !_Thread_queue_Extract_with_proxy( the_thread ) ) {
+
+ if ( _Watchdog_Is_active( &the_thread->Timer ) )
+ (void) _Watchdog_Remove( &the_thread->Timer );
+ }
+
+ if ( the_thread->current_priority != the_thread->Start.initial_priority ) {
+ the_thread->real_priority = the_thread->Start.initial_priority;
+ _Thread_Set_priority( the_thread, the_thread->Start.initial_priority );
+ }
+}
diff --git a/cpukit/score/src/threadresettimeslice.c b/cpukit/score/src/threadresettimeslice.c
new file mode 100644
index 0000000000..ff383834df
--- /dev/null
+++ b/cpukit/score/src/threadresettimeslice.c
@@ -0,0 +1,75 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Reset_timeslice
+ *
+ * This routine will remove the running thread from the ready chain
+ * and place it immediately at the rear of this chain and then the
+ * timeslice counter is reset. The heir THREAD will be updated if
+ * the running is also the currently the heir.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * ready chain
+ * select heir
+ */
+
+void _Thread_Reset_timeslice( void )
+{
+ ISR_Level level;
+ Thread_Control *executing;
+ Chain_Control *ready;
+
+ executing = _Thread_Executing;
+ ready = executing->ready;
+ _ISR_Disable( level );
+ if ( _Chain_Has_only_one_node( ready ) ) {
+ _ISR_Enable( level );
+ return;
+ }
+ _Chain_Extract_unprotected( &executing->Object.Node );
+ _Chain_Append_unprotected( ready, &executing->Object.Node );
+
+ _ISR_Flash( level );
+
+ if ( _Thread_Is_heir( executing ) )
+ _Thread_Heir = (Thread_Control *) ready->first;
+
+ _Context_Switch_necessary = TRUE;
+
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
new file mode 100644
index 0000000000..a55f601330
--- /dev/null
+++ b/cpukit/score/src/threadrestart.c
@@ -0,0 +1,68 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * _Thread_Restart
+ *
+ * DESCRIPTION:
+ *
+ * This support routine restarts the specified task in a way that the
+ * next time this thread executes, it will begin execution at its
+ * original starting point.
+ */
+
+boolean _Thread_Restart(
+ Thread_Control *the_thread,
+ void *pointer_argument,
+ uint32_t numeric_argument
+)
+{
+ if ( !_States_Is_dormant( the_thread->current_state ) ) {
+
+ _Thread_Set_transient( the_thread );
+
+ _Thread_Reset( the_thread, pointer_argument, numeric_argument );
+
+ _Thread_Load_environment( the_thread );
+
+ _Thread_Ready( the_thread );
+
+ _User_extensions_Thread_restart( the_thread );
+
+ if ( _Thread_Is_executing ( the_thread ) )
+ _Thread_Restart_self();
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/cpukit/score/src/threadresume.c b/cpukit/score/src/threadresume.c
new file mode 100644
index 0000000000..7f3555fe04
--- /dev/null
+++ b/cpukit/score/src/threadresume.c
@@ -0,0 +1,98 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Resume
+ *
+ * This kernel routine clears the SUSPEND state if the suspend_count
+ * drops below one. If the force parameter is set the suspend_count
+ * is forced back to zero. The thread ready chain is adjusted if
+ * necessary and the Heir thread is set accordingly.
+ *
+ * Input parameters:
+ * the_thread - pointer to thread control block
+ * force - force the suspend count back to 0
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * priority map
+ * select heir
+ */
+
+
+void _Thread_Resume(
+ Thread_Control *the_thread,
+ boolean force
+)
+{
+
+ ISR_Level level;
+ States_Control current_state;
+
+ _ISR_Disable( level );
+
+ if ( force == TRUE )
+ the_thread->suspend_count = 0;
+ else
+ the_thread->suspend_count--;
+
+ if ( the_thread->suspend_count > 0 ) {
+ _ISR_Enable( level );
+ return;
+ }
+
+ current_state = the_thread->current_state;
+ if ( current_state & STATES_SUSPENDED ) {
+ current_state =
+ the_thread->current_state = _States_Clear(STATES_SUSPENDED, current_state);
+
+ if ( _States_Is_ready( current_state ) ) {
+
+ _Priority_Add_to_bit_map( &the_thread->Priority_map );
+
+ _Chain_Append_unprotected(the_thread->ready, &the_thread->Object.Node);
+
+ _ISR_Flash( level );
+
+ if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
+ _Thread_Heir = the_thread;
+ if ( _Thread_Executing->is_preemptible ||
+ the_thread->current_priority == 0 )
+ _Context_Switch_necessary = TRUE;
+ }
+ }
+ }
+
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/threadrotatequeue.c b/cpukit/score/src/threadrotatequeue.c
new file mode 100644
index 0000000000..28388ccbc6
--- /dev/null
+++ b/cpukit/score/src/threadrotatequeue.c
@@ -0,0 +1,90 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Rotate_Ready_Queue
+ *
+ * This kernel routine will rotate the ready queue.
+ * remove the running THREAD from the ready chain
+ * and place it immediatly at the rear of this chain. Reset timeslice
+ * and yield the processor functions both use this routine, therefore if
+ * reset is TRUE and this is the only thread on the chain then the
+ * timeslice counter is reset. The heir THREAD will be updated if the
+ * running is also the currently the heir.
+ *
+ * Input parameters:
+ * Priority of the queue we wish to modify.
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * ready chain
+ * select heir
+ */
+
+void _Thread_Rotate_Ready_Queue(
+ Priority_Control priority
+)
+{
+ ISR_Level level;
+ Thread_Control *executing;
+ Chain_Control *ready;
+ Chain_Node *node;
+
+ ready = &_Thread_Ready_chain[ priority ];
+ executing = _Thread_Executing;
+
+ if ( ready == executing->ready ) {
+ _Thread_Yield_processor();
+ return;
+ }
+
+ _ISR_Disable( level );
+
+ if ( !_Chain_Is_empty( ready ) ) {
+ if (!_Chain_Has_only_one_node( ready ) ) {
+ node = _Chain_Get_first_unprotected( ready );
+ _Chain_Append_unprotected( ready, node );
+ }
+ }
+
+ _ISR_Flash( level );
+
+ if ( _Thread_Heir->ready == ready )
+ _Thread_Heir = (Thread_Control *) ready->first;
+
+ if ( executing != _Thread_Heir )
+ _Context_Switch_necessary = TRUE;
+
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/threadsetpriority.c b/cpukit/score/src/threadsetpriority.c
new file mode 100644
index 0000000000..ba1482f5b5
--- /dev/null
+++ b/cpukit/score/src/threadsetpriority.c
@@ -0,0 +1,56 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Set_priority
+ *
+ * This directive enables and disables several modes of
+ * execution for the requesting thread.
+ *
+ * Input parameters:
+ * the_thread - pointer to thread priority
+ * new_priority - new priority
+ *
+ * Output: NONE
+ */
+
+void _Thread_Set_priority(
+ Thread_Control *the_thread,
+ Priority_Control new_priority
+)
+{
+ the_thread->current_priority = new_priority;
+ the_thread->ready = &_Thread_Ready_chain[ new_priority ];
+
+ _Priority_Initialize_information( &the_thread->Priority_map, new_priority );
+}
diff --git a/cpukit/score/src/threadsetstate.c b/cpukit/score/src/threadsetstate.c
new file mode 100644
index 0000000000..f1cc469f1c
--- /dev/null
+++ b/cpukit/score/src/threadsetstate.c
@@ -0,0 +1,87 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Set_state
+ *
+ * This kernel routine sets the requested state in the THREAD. The
+ * THREAD chain is adjusted if necessary.
+ *
+ * Input parameters:
+ * the_thread - pointer to thread control block
+ * state - state to be set
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * ready chain
+ * select map
+ */
+
+void _Thread_Set_state(
+ Thread_Control *the_thread,
+ States_Control state
+)
+{
+ ISR_Level level;
+ Chain_Control *ready;
+
+ ready = the_thread->ready;
+ _ISR_Disable( level );
+ if ( !_States_Is_ready( the_thread->current_state ) ) {
+ the_thread->current_state =
+ _States_Set( state, the_thread->current_state );
+ _ISR_Enable( level );
+ return;
+ }
+
+ the_thread->current_state = state;
+
+ if ( _Chain_Has_only_one_node( ready ) ) {
+
+ _Chain_Initialize_empty( ready );
+ _Priority_Remove_from_bit_map( &the_thread->Priority_map );
+
+ } else
+ _Chain_Extract_unprotected( &the_thread->Object.Node );
+
+ _ISR_Flash( level );
+
+ if ( _Thread_Is_heir( the_thread ) )
+ _Thread_Calculate_heir();
+
+ if ( _Thread_Is_executing( the_thread ) )
+ _Context_Switch_necessary = TRUE;
+
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/threadsettransient.c b/cpukit/score/src/threadsettransient.c
new file mode 100644
index 0000000000..ab0a1d451d
--- /dev/null
+++ b/cpukit/score/src/threadsettransient.c
@@ -0,0 +1,77 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Set_transient
+ *
+ * This kernel routine places the requested thread in the transient state
+ * which will remove it from the ready queue, if necessary. No
+ * rescheduling is necessary because it is assumed that the transient
+ * state will be cleared before dispatching is enabled.
+ *
+ * Input parameters:
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+void _Thread_Set_transient(
+ Thread_Control *the_thread
+)
+{
+ ISR_Level level;
+ uint32_t old_state;
+ Chain_Control *ready;
+
+ ready = the_thread->ready;
+ _ISR_Disable( level );
+
+ old_state = the_thread->current_state;
+ the_thread->current_state = _States_Set( STATES_TRANSIENT, old_state );
+
+ if ( _States_Is_ready( old_state ) ) {
+ if ( _Chain_Has_only_one_node( ready ) ) {
+
+ _Chain_Initialize_empty( ready );
+ _Priority_Remove_from_bit_map( &the_thread->Priority_map );
+
+ } else
+ _Chain_Extract_unprotected( &the_thread->Object.Node );
+ }
+
+ _ISR_Enable( level );
+
+}
diff --git a/cpukit/score/src/threadstackallocate.c b/cpukit/score/src/threadstackallocate.c
new file mode 100644
index 0000000000..6464d2caec
--- /dev/null
+++ b/cpukit/score/src/threadstackallocate.c
@@ -0,0 +1,85 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Stack_Allocate
+ *
+ * Allocate the requested stack space for the thread.
+ * return the actual size allocated after any adjustment
+ * or return zero if the allocation failed.
+ * Set the Start.stack field to the address of the stack
+ */
+
+uint32_t _Thread_Stack_Allocate(
+ Thread_Control *the_thread,
+ uint32_t stack_size
+)
+{
+ void *stack_addr = 0;
+ uint32_t the_stack_size = stack_size;
+
+ if ( !_Stack_Is_enough( the_stack_size ) )
+ the_stack_size = STACK_MINIMUM_SIZE;
+
+ /*
+ * Call ONLY the CPU table stack allocate hook, _or_ the
+ * the RTEMS workspace allocate. This is so the stack free
+ * routine can call the correct deallocation routine.
+ */
+
+ if ( _CPU_Table.stack_allocate_hook ) {
+ stack_addr = (*_CPU_Table.stack_allocate_hook)( the_stack_size );
+ } else {
+
+ /*
+ * First pad the requested size so we allocate enough memory
+ * so the context initialization can align it properly. The address
+ * returned the workspace allocate must be directly stored in the
+ * stack control block because it is later used in the free sequence.
+ *
+ * Thus it is the responsibility of the CPU dependent code to
+ * get and keep the stack adjust factor, the stack alignment, and
+ * the context initialization sequence in sync.
+ */
+
+ the_stack_size = _Stack_Adjust_size( the_stack_size );
+ stack_addr = _Workspace_Allocate( the_stack_size );
+ }
+
+ if ( !stack_addr )
+ the_stack_size = 0;
+
+ the_thread->Start.stack = stack_addr;
+
+ return the_stack_size;
+}
diff --git a/cpukit/score/src/threadstackfree.c b/cpukit/score/src/threadstackfree.c
new file mode 100644
index 0000000000..305b1eafba
--- /dev/null
+++ b/cpukit/score/src/threadstackfree.c
@@ -0,0 +1,60 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * _Thread_Stack_Free
+ *
+ * Deallocate the Thread's stack.
+ */
+
+void _Thread_Stack_Free(
+ Thread_Control *the_thread
+)
+{
+ /*
+ * If the API provided the stack space, then don't free it.
+ */
+
+ if ( !the_thread->Start.core_allocated_stack )
+ return;
+
+ /*
+ * Call ONLY the CPU table stack free hook, or the
+ * the RTEMS workspace free. This is so the free
+ * routine properly matches the allocation of the stack.
+ */
+
+ if ( _CPU_Table.stack_free_hook )
+ (*_CPU_Table.stack_free_hook)( the_thread->Start.Initial_stack.area );
+ else
+ _Workspace_Free( the_thread->Start.Initial_stack.area );
+}
diff --git a/cpukit/score/src/threadstart.c b/cpukit/score/src/threadstart.c
new file mode 100644
index 0000000000..6c9fc3337b
--- /dev/null
+++ b/cpukit/score/src/threadstart.c
@@ -0,0 +1,70 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * _Thread_Start
+ *
+ * DESCRIPTION:
+ *
+ * This routine initializes the executable information for a thread
+ * and makes it ready to execute. After this routine executes, the
+ * thread competes with all other threads for CPU time.
+ */
+
+boolean _Thread_Start(
+ Thread_Control *the_thread,
+ Thread_Start_types the_prototype,
+ void *entry_point,
+ void *pointer_argument,
+ uint32_t numeric_argument
+)
+{
+ if ( _States_Is_dormant( the_thread->current_state ) ) {
+
+ the_thread->Start.entry_point = (Thread_Entry) entry_point;
+
+ the_thread->Start.prototype = the_prototype;
+ the_thread->Start.pointer_argument = pointer_argument;
+ the_thread->Start.numeric_argument = numeric_argument;
+
+ _Thread_Load_environment( the_thread );
+
+ _Thread_Ready( the_thread );
+
+ _User_extensions_Thread_start( the_thread );
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
diff --git a/cpukit/score/src/threadstartmultitasking.c b/cpukit/score/src/threadstartmultitasking.c
new file mode 100644
index 0000000000..9422c54cba
--- /dev/null
+++ b/cpukit/score/src/threadstartmultitasking.c
@@ -0,0 +1,93 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Start_multitasking
+ *
+ * This kernel routine readies the requested thread, the thread chain
+ * is adjusted. A new heir thread may be selected.
+ *
+ * Input parameters:
+ * system_thread - pointer to system initialization thread control block
+ * idle_thread - pointer to idle thread control block
+ *
+ * Output parameters: NONE
+ *
+ * NOTE: This routine uses the "blocking" heir selection mechanism.
+ * This ensures the correct heir after a thread restart.
+ *
+ * INTERRUPT LATENCY:
+ * ready chain
+ * select heir
+ */
+
+void _Thread_Start_multitasking( void )
+{
+ /*
+ * The system is now multitasking and completely initialized.
+ * This system thread now either "goes away" in a single processor
+ * system or "turns into" the server thread in an MP system.
+ */
+
+ _System_state_Set( SYSTEM_STATE_UP );
+
+ _Context_Switch_necessary = FALSE;
+
+ _Thread_Executing = _Thread_Heir;
+
+ /*
+ * Get the init task(s) running.
+ *
+ * Note: Thread_Dispatch() is normally used to dispatch threads. As
+ * part of its work, Thread_Dispatch() restores floating point
+ * state for the heir task.
+ *
+ * This code avoids Thread_Dispatch(), and so we have to restore
+ * (actually initialize) the floating point state "by hand".
+ *
+ * Ignore the CPU_USE_DEFERRED_FP_SWITCH because we must always
+ * switch in the first thread if it is FP.
+ */
+
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ /*
+ * don't need to worry about saving BSP's floating point state
+ */
+
+ if ( _Thread_Heir->fp_context != NULL )
+ _Context_Restore_fp( &_Thread_Heir->fp_context );
+#endif
+
+ _Context_Switch( &_Thread_BSP_context, &_Thread_Heir->Registers );
+}
diff --git a/cpukit/score/src/threadsuspend.c b/cpukit/score/src/threadsuspend.c
new file mode 100644
index 0000000000..87ee0d6a80
--- /dev/null
+++ b/cpukit/score/src/threadsuspend.c
@@ -0,0 +1,86 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Suspend
+ *
+ * This kernel routine sets the SUSPEND state in the THREAD. The
+ * THREAD chain and suspend count are adjusted if necessary.
+ *
+ * Input parameters:
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * ready chain
+ * select map
+ */
+
+void _Thread_Suspend(
+ Thread_Control *the_thread
+)
+{
+ ISR_Level level;
+ Chain_Control *ready;
+
+ ready = the_thread->ready;
+ _ISR_Disable( level );
+ the_thread->suspend_count++;
+ if ( !_States_Is_ready( the_thread->current_state ) ) {
+ the_thread->current_state =
+ _States_Set( STATES_SUSPENDED, the_thread->current_state );
+ _ISR_Enable( level );
+ return;
+ }
+
+ the_thread->current_state = STATES_SUSPENDED;
+
+ if ( _Chain_Has_only_one_node( ready ) ) {
+
+ _Chain_Initialize_empty( ready );
+ _Priority_Remove_from_bit_map( &the_thread->Priority_map );
+
+ } else
+ _Chain_Extract_unprotected( &the_thread->Object.Node );
+
+ _ISR_Flash( level );
+
+ if ( _Thread_Is_heir( the_thread ) )
+ _Thread_Calculate_heir();
+
+ if ( _Thread_Is_executing( the_thread ) )
+ _Context_Switch_necessary = TRUE;
+
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/threadtickletimeslice.c b/cpukit/score/src/threadtickletimeslice.c
new file mode 100644
index 0000000000..0666066b28
--- /dev/null
+++ b/cpukit/score/src/threadtickletimeslice.c
@@ -0,0 +1,90 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Tickle_timeslice
+ *
+ * This scheduler routine determines if timeslicing is enabled
+ * for the currently executing thread and, if so, updates the
+ * timeslice count and checks for timeslice expiration.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _Thread_Tickle_timeslice( void )
+{
+ Thread_Control *executing;
+
+ executing = _Thread_Executing;
+
+ /*
+ * Increment the number of ticks this thread has been executing
+ */
+
+ executing->ticks_executed++;
+
+ /*
+ * If the thread is not preemptible or is not ready, then
+ * just return.
+ */
+
+ if ( !executing->is_preemptible )
+ return;
+
+ if ( !_States_Is_ready( executing->current_state ) )
+ return;
+
+ /*
+ * The cpu budget algorithm determines what happens next.
+ */
+
+ switch ( executing->budget_algorithm ) {
+ case THREAD_CPU_BUDGET_ALGORITHM_NONE:
+ break;
+
+ case THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE:
+ case THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE:
+ if ( --executing->cpu_time_budget == 0 ) {
+ _Thread_Reset_timeslice();
+ executing->cpu_time_budget = _Thread_Ticks_per_timeslice;
+ }
+ break;
+
+ case THREAD_CPU_BUDGET_ALGORITHM_CALLOUT:
+ if ( --executing->cpu_time_budget == 0 )
+ (*executing->budget_callout)( executing );
+ break;
+ }
+}
diff --git a/cpukit/score/src/threadyieldprocessor.c b/cpukit/score/src/threadyieldprocessor.c
new file mode 100644
index 0000000000..7f2325ed78
--- /dev/null
+++ b/cpukit/score/src/threadyieldprocessor.c
@@ -0,0 +1,76 @@
+/*
+ * Thread Handler
+ *
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*PAGE
+ *
+ * _Thread_Yield_processor
+ *
+ * This kernel routine will remove the running THREAD from the ready chain
+ * and place it immediatly at the rear of this chain. Reset timeslice
+ * and yield the processor functions both use this routine, therefore if
+ * reset is TRUE and this is the only thread on the chain then the
+ * timeslice counter is reset. The heir THREAD will be updated if the
+ * running is also the currently the heir.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * ready chain
+ * select heir
+ */
+
+void _Thread_Yield_processor( void )
+{
+ ISR_Level level;
+ Thread_Control *executing;
+ Chain_Control *ready;
+
+ executing = _Thread_Executing;
+ ready = executing->ready;
+ _ISR_Disable( level );
+ if ( !_Chain_Has_only_one_node( ready ) ) {
+ _Chain_Extract_unprotected( &executing->Object.Node );
+ _Chain_Append_unprotected( ready, &executing->Object.Node );
+
+ _ISR_Flash( level );
+
+ if ( _Thread_Is_heir( executing ) )
+ _Thread_Heir = (Thread_Control *) ready->first;
+ _Context_Switch_necessary = TRUE;
+ }
+ else if ( !_Thread_Is_heir( executing ) )
+ _Context_Switch_necessary = TRUE;
+
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/userext.c b/cpukit/score/src/userext.c
new file mode 100644
index 0000000000..469200ef76
--- /dev/null
+++ b/cpukit/score/src/userext.c
@@ -0,0 +1,205 @@
+/*
+ * User Extension Handler
+ *
+ * NOTE: XXX
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/userext.h>
+
+/*PAGE
+ *
+ * _User_extensions_Thread_create
+ */
+
+boolean _User_extensions_Thread_create (
+ Thread_Control *the_thread
+)
+{
+ Chain_Node *the_node;
+ User_extensions_Control *the_extension;
+ boolean status;
+
+ for ( the_node = _User_extensions_List.first ;
+ !_Chain_Is_tail( &_User_extensions_List, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_extension = (User_extensions_Control *) the_node;
+
+ if ( the_extension->Callouts.thread_create != NULL ) {
+ status = (*the_extension->Callouts.thread_create)(
+ _Thread_Executing,
+ the_thread
+ );
+ if ( !status )
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/*PAGE
+ *
+ * _User_extensions_Thread_delete
+ */
+
+void _User_extensions_Thread_delete (
+ Thread_Control *the_thread
+)
+{
+ Chain_Node *the_node;
+ User_extensions_Control *the_extension;
+
+ for ( the_node = _User_extensions_List.last ;
+ !_Chain_Is_head( &_User_extensions_List, the_node ) ;
+ the_node = the_node->previous ) {
+
+ the_extension = (User_extensions_Control *) the_node;
+
+ if ( the_extension->Callouts.thread_delete != NULL )
+ (*the_extension->Callouts.thread_delete)(
+ _Thread_Executing,
+ the_thread
+ );
+ }
+}
+
+/*PAGE
+ *
+ * _User_extensions_Thread_start
+ *
+ */
+
+void _User_extensions_Thread_start (
+ Thread_Control *the_thread
+)
+{
+ Chain_Node *the_node;
+ User_extensions_Control *the_extension;
+
+ for ( the_node = _User_extensions_List.first ;
+ !_Chain_Is_tail( &_User_extensions_List, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_extension = (User_extensions_Control *) the_node;
+
+ if ( the_extension->Callouts.thread_start != NULL )
+ (*the_extension->Callouts.thread_start)(
+ _Thread_Executing,
+ the_thread
+ );
+ }
+}
+
+/*PAGE
+ *
+ * _User_extensions_Thread_restart
+ *
+ */
+
+void _User_extensions_Thread_restart (
+ Thread_Control *the_thread
+)
+{
+ Chain_Node *the_node;
+ User_extensions_Control *the_extension;
+
+ for ( the_node = _User_extensions_List.first ;
+ !_Chain_Is_tail( &_User_extensions_List, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_extension = (User_extensions_Control *) the_node;
+
+ if ( the_extension->Callouts.thread_restart != NULL )
+ (*the_extension->Callouts.thread_restart)(
+ _Thread_Executing,
+ the_thread
+ );
+ }
+}
+
+/*PAGE
+ *
+ * _User_extensions_Thread_begin
+ *
+ */
+
+void _User_extensions_Thread_begin (
+ Thread_Control *executing
+)
+{
+ Chain_Node *the_node;
+ User_extensions_Control *the_extension;
+
+ for ( the_node = _User_extensions_List.first ;
+ !_Chain_Is_tail( &_User_extensions_List, the_node ) ;
+ the_node = the_node->next ) {
+
+ the_extension = (User_extensions_Control *) the_node;
+
+ if ( the_extension->Callouts.thread_begin != NULL )
+ (*the_extension->Callouts.thread_begin)( executing );
+ }
+}
+
+/*PAGE
+ *
+ * _User_extensions_Thread_exitted
+ */
+
+void _User_extensions_Thread_exitted (
+ Thread_Control *executing
+)
+{
+ Chain_Node *the_node;
+ User_extensions_Control *the_extension;
+
+ for ( the_node = _User_extensions_List.last ;
+ !_Chain_Is_head( &_User_extensions_List, the_node ) ;
+ the_node = the_node->previous ) {
+
+ the_extension = (User_extensions_Control *) the_node;
+
+ if ( the_extension->Callouts.thread_exitted != NULL )
+ (*the_extension->Callouts.thread_exitted)( executing );
+ }
+}
+
+/*PAGE
+ *
+ * _User_extensions_Fatal
+ */
+
+void _User_extensions_Fatal (
+ Internal_errors_Source the_source,
+ boolean is_internal,
+ uint32_t the_error
+)
+{
+ Chain_Node *the_node;
+ User_extensions_Control *the_extension;
+
+ for ( the_node = _User_extensions_List.last ;
+ !_Chain_Is_head( &_User_extensions_List, the_node ) ;
+ the_node = the_node->previous ) {
+
+ the_extension = (User_extensions_Control *) the_node;
+
+ if ( the_extension->Callouts.fatal != NULL )
+ (*the_extension->Callouts.fatal)( the_source, is_internal, the_error );
+ }
+}
diff --git a/cpukit/score/src/watchdog.c b/cpukit/score/src/watchdog.c
new file mode 100644
index 0000000000..591f2de117
--- /dev/null
+++ b/cpukit/score/src/watchdog.c
@@ -0,0 +1,42 @@
+/*
+ * Watchdog Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _Watchdog_Handler_initialization
+ *
+ * This routine initializes the watchdog handler.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _Watchdog_Handler_initialization( void )
+{
+ _Watchdog_Sync_count = 0;
+ _Watchdog_Sync_level = 0;
+ _Watchdog_Ticks_since_boot = 0;
+
+ _Chain_Initialize_empty( &_Watchdog_Ticks_chain );
+ _Chain_Initialize_empty( &_Watchdog_Seconds_chain );
+}
diff --git a/cpukit/score/src/watchdogadjust.c b/cpukit/score/src/watchdogadjust.c
new file mode 100644
index 0000000000..42cfbcaf8c
--- /dev/null
+++ b/cpukit/score/src/watchdogadjust.c
@@ -0,0 +1,87 @@
+/*
+ * Watchdog Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _Watchdog_Adjust
+ *
+ * This routine adjusts the delta chain backward or forward in response
+ * to a time change.
+ *
+ * Input parameters:
+ * header - pointer to the delta chain to be adjusted
+ * direction - forward or backward adjustment to delta chain
+ * units - units to adjust
+ *
+ * Output parameters:
+ */
+
+void _Watchdog_Adjust(
+ Chain_Control *header,
+ Watchdog_Adjust_directions direction,
+ Watchdog_Interval units
+)
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+
+ /*
+ * NOTE: It is safe NOT to make 'header' a pointer
+ * to volatile data (contrast this with watchdoginsert.c)
+ * because we call _Watchdog_Tickle() below and
+ * hence the compiler must not assume *header to remain
+ * unmodified across that call.
+ *
+ * Till Straumann, 7/2003
+ */
+ if ( !_Chain_Is_empty( header ) ) {
+ switch ( direction ) {
+ case WATCHDOG_BACKWARD:
+ _Watchdog_First( header )->delta_interval += units;
+ break;
+ case WATCHDOG_FORWARD:
+ while ( units ) {
+ if ( units < _Watchdog_First( header )->delta_interval ) {
+ _Watchdog_First( header )->delta_interval -= units;
+ break;
+ } else {
+ units -= _Watchdog_First( header )->delta_interval;
+ _Watchdog_First( header )->delta_interval = 1;
+
+ _ISR_Enable( level );
+
+ _Watchdog_Tickle( header );
+
+ _ISR_Disable( level );
+
+ if ( _Chain_Is_empty( header ) )
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ _ISR_Enable( level );
+
+}
diff --git a/cpukit/score/src/watchdoginsert.c b/cpukit/score/src/watchdoginsert.c
new file mode 100644
index 0000000000..9fcbcba1d1
--- /dev/null
+++ b/cpukit/score/src/watchdoginsert.c
@@ -0,0 +1,123 @@
+/*
+ * Watchdog Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _Watchdog_Insert
+ *
+ * This routine inserts a watchdog timer on to the appropriate delta
+ * chain while updating the delta interval counters.
+ */
+
+void _Watchdog_Insert(
+ Chain_Control *header,
+ Watchdog_Control *the_watchdog
+)
+{
+ ISR_Level level;
+ Watchdog_Control *after;
+ uint32_t insert_isr_nest_level;
+ Watchdog_Interval delta_interval;
+
+
+ insert_isr_nest_level = _ISR_Nest_level;
+
+ _ISR_Disable( level );
+
+ /*
+ * Check to see if the watchdog has just been inserted by a
+ * higher priority interrupt. If so, abandon this insert.
+ */
+
+ if ( the_watchdog->state != WATCHDOG_INACTIVE ) {
+ _ISR_Enable( level );
+ return;
+ }
+
+ the_watchdog->state = WATCHDOG_BEING_INSERTED;
+ _Watchdog_Sync_count++;
+
+restart:
+ delta_interval = the_watchdog->initial;
+
+ /*
+ * We CANT use _Watchdog_First() here, because a TICK interrupt
+ * could modify the chain during the _ISR_Flash() below. Hence,
+ * the header is pointing to volatile data. The _Watchdog_First()
+ * INLINE routine (but not the macro - note the subtle difference)
+ * casts away the 'volatile'...
+ *
+ * Also, this is only necessary because we call no other routine
+ * from this piece of code, hence the compiler thinks it's safe to
+ * cache *header!!
+ *
+ * Till Straumann, 7/2003 (gcc-3.2.2 -O4 on powerpc)
+ *
+ */
+ for ( after = (Watchdog_Control *) ((volatile Chain_Control *)header)->first ;
+ ;
+ after = _Watchdog_Next( after ) ) {
+
+ if ( delta_interval == 0 || !_Watchdog_Next( after ) )
+ break;
+
+ if ( delta_interval < after->delta_interval ) {
+ after->delta_interval -= delta_interval;
+ break;
+ }
+
+ delta_interval -= after->delta_interval;
+
+ /*
+ * If you experience problems comment out the _ISR_Flash line.
+ * 3.2.0 was the first release with this critical section redesigned.
+ * Under certain circumstances, the PREVIOUS critical section algorithm
+ * used around this flash point allowed interrupts to execute
+ * which violated the design assumptions. The critical section
+ * mechanism used here WAS redesigned to address this.
+ */
+
+ _ISR_Flash( level );
+
+ if ( the_watchdog->state != WATCHDOG_BEING_INSERTED ) {
+ goto exit_insert;
+ }
+
+ if ( _Watchdog_Sync_level > insert_isr_nest_level ) {
+ _Watchdog_Sync_level = insert_isr_nest_level;
+ goto restart;
+ }
+ }
+
+ _Watchdog_Activate( the_watchdog );
+
+ the_watchdog->delta_interval = delta_interval;
+
+ _Chain_Insert_unprotected( after->Node.previous, &the_watchdog->Node );
+
+ the_watchdog->start_time = _Watchdog_Ticks_since_boot;
+
+exit_insert:
+ _Watchdog_Sync_level = insert_isr_nest_level;
+ _Watchdog_Sync_count--;
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/watchdogremove.c b/cpukit/score/src/watchdogremove.c
new file mode 100644
index 0000000000..3ce3367657
--- /dev/null
+++ b/cpukit/score/src/watchdogremove.c
@@ -0,0 +1,73 @@
+/*
+ * Watchdog Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _Watchdog_Remove
+ *
+ * The routine removes a watchdog from a delta chain and updates
+ * the delta counters of the remaining watchdogs.
+ */
+
+Watchdog_States _Watchdog_Remove(
+ Watchdog_Control *the_watchdog
+)
+{
+ ISR_Level level;
+ Watchdog_States previous_state;
+ Watchdog_Control *next_watchdog;
+
+ _ISR_Disable( level );
+ previous_state = the_watchdog->state;
+ switch ( previous_state ) {
+ case WATCHDOG_INACTIVE:
+ break;
+
+ case WATCHDOG_BEING_INSERTED:
+
+ /*
+ * It is not actually on the chain so just change the state and
+ * the Insert operation we interrupted will be aborted.
+ */
+ the_watchdog->state = WATCHDOG_INACTIVE;
+ break;
+
+ case WATCHDOG_ACTIVE:
+ case WATCHDOG_REMOVE_IT:
+
+ the_watchdog->state = WATCHDOG_INACTIVE;
+ next_watchdog = _Watchdog_Next( the_watchdog );
+
+ if ( _Watchdog_Next(next_watchdog) )
+ next_watchdog->delta_interval += the_watchdog->delta_interval;
+
+ if ( _Watchdog_Sync_count )
+ _Watchdog_Sync_level = _ISR_Nest_level;
+
+ _Chain_Extract_unprotected( &the_watchdog->Node );
+ break;
+ }
+ the_watchdog->stop_time = _Watchdog_Ticks_since_boot;
+
+ _ISR_Enable( level );
+ return( previous_state );
+}
diff --git a/cpukit/score/src/watchdogtickle.c b/cpukit/score/src/watchdogtickle.c
new file mode 100644
index 0000000000..2fca11b8ac
--- /dev/null
+++ b/cpukit/score/src/watchdogtickle.c
@@ -0,0 +1,129 @@
+/*
+ * Watchdog Handler
+ *
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/watchdog.h>
+
+/*PAGE
+ *
+ * _Watchdog_Tickle
+ *
+ * This routine decrements the delta counter in response to a tick. The
+ * delta chain is updated accordingly.
+ *
+ * Input parameters:
+ * header - pointer to the delta chain to be tickled
+ *
+ * Output parameters: NONE
+ */
+
+void _Watchdog_Tickle(
+ Chain_Control *header
+)
+{
+ ISR_Level level;
+ Watchdog_Control *the_watchdog;
+ Watchdog_States watchdog_state;
+
+ /*
+ * See the comment in watchdoginsert.c and watchdogadjust.c
+ * about why it's safe not to declare header a pointer to
+ * volatile data - till, 2003/7
+ */
+
+ _ISR_Disable( level );
+
+ if ( _Chain_Is_empty( header ) )
+ goto leave;
+
+ the_watchdog = _Watchdog_First( header );
+
+ /*
+ * For some reason, on rare occasions the_watchdog->delta_interval
+ * of the head of the watchdog chain is 0. Before this test was
+ * added, on these occasions an event (which usually was supposed
+ * to have a timeout of 1 tick would have a delta_interval of 0, which
+ * would be decremented to 0xFFFFFFFF by the unprotected
+ * "the_watchdog->delta_interval--;" operation.
+ * This would mean the event would not timeout, and also the chain would
+ * be blocked, because a timeout with a very high number would be at the
+ * head, rather than at the end.
+ * The test "if (the_watchdog->delta_interval != 0)"
+ * here prevents this from occuring.
+ *
+ * We were not able to categorically identify the situation that causes
+ * this, but proved it to be true empirically. So this check causes
+ * correct behaviour in this circumstance.
+ *
+ * The belief is that a race condition exists whereby an event at the head
+ * of the chain is removed (by a pending ISR or higher priority task)
+ * during the _ISR_Flash( level ); in _Watchdog_Insert, but the watchdog
+ * to be inserted has already had its delta_interval adjusted to 0, and
+ * so is added to the head of the chain with a delta_interval of 0.
+ *
+ * Steven Johnson - 12/2005 (gcc-3.2.3 -O3 on powerpc)
+ */
+ if (the_watchdog->delta_interval != 0) {
+ the_watchdog->delta_interval--;
+ if ( the_watchdog->delta_interval != 0 )
+ goto leave;
+ }
+
+ do {
+ watchdog_state = _Watchdog_Remove( the_watchdog );
+
+ _ISR_Enable( level );
+
+ switch( watchdog_state ) {
+ case WATCHDOG_ACTIVE:
+ (*the_watchdog->routine)(
+ the_watchdog->id,
+ the_watchdog->user_data
+ );
+ break;
+
+ case WATCHDOG_INACTIVE:
+ /*
+ * This state indicates that the watchdog is not on any chain.
+ * Thus, it is NOT on a chain being tickled. This case should
+ * never occur.
+ */
+ break;
+
+ case WATCHDOG_BEING_INSERTED:
+ /*
+ * This state indicates that the watchdog is in the process of
+ * BEING inserted on the chain. Thus, it can NOT be on a chain
+ * being tickled. This case should never occur.
+ */
+ break;
+
+ case WATCHDOG_REMOVE_IT:
+ break;
+ }
+
+ _ISR_Disable( level );
+
+ the_watchdog = _Watchdog_First( header );
+ } while ( !_Chain_Is_empty( header ) &&
+ (the_watchdog->delta_interval == 0) );
+
+leave:
+ _ISR_Enable(level);
+}
diff --git a/cpukit/score/src/wkspace.c b/cpukit/score/src/wkspace.c
new file mode 100644
index 0000000000..97c1820119
--- /dev/null
+++ b/cpukit/score/src/wkspace.c
@@ -0,0 +1,91 @@
+/*
+ * Workspace Handler
+ *
+ * XXX
+ *
+ * NOTE:
+ *
+ * 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.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/interr.h>
+
+/*PAGE
+ *
+ * _Workspace_Handler_initialization
+ */
+
+void _Workspace_Handler_initialization(
+ void *starting_address,
+ uint32_t size
+)
+{
+ uint32_t *zero_out_array;
+ uint32_t index;
+ uint32_t memory_available;
+
+ if ( !starting_address || !_Addresses_Is_aligned( starting_address ) )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_INVALID_WORKSPACE_ADDRESS
+ );
+
+ if ( _CPU_Table.do_zero_of_workspace ) {
+ for( zero_out_array = (uint32_t *) starting_address, index = 0 ;
+ index < size / sizeof( uint32_t ) ;
+ index++ )
+ zero_out_array[ index ] = 0;
+ }
+
+ memory_available = _Heap_Initialize(
+ &_Workspace_Area,
+ starting_address,
+ size,
+ CPU_HEAP_ALIGNMENT
+ );
+
+ if ( memory_available == 0 )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_TOO_LITTLE_WORKSPACE
+ );
+}
+
+/*PAGE
+ *
+ * _Workspace_Allocate_or_fatal_error
+ *
+ */
+
+void *_Workspace_Allocate_or_fatal_error(
+ uint32_t size
+)
+{
+ void *memory;
+
+ memory = _Workspace_Allocate( size );
+
+ if ( memory == NULL )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ INTERNAL_ERROR_WORKSPACE_ALLOCATION
+ );
+
+ return memory;
+}
diff --git a/cpukit/telnetd/.cvsignore b/cpukit/telnetd/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/telnetd/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/telnetd/Makefile.am b/cpukit/telnetd/Makefile.am
new file mode 100644
index 0000000000..2f48393056
--- /dev/null
+++ b/cpukit/telnetd/Makefile.am
@@ -0,0 +1,21 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/compile.am
+
+if HAS_NETWORKING
+if LIBSHELL
+include_rtemsdir = $(includedir)/rtems
+include_rtems_HEADERS = pty.h telnetd.h
+
+project_lib_LIBRARIES = libtelnetd.a
+libtelnetd_a_SOURCES = pty.c pty.h telnetd.c telnetd.h icmds.c
+libtelnetd_a_CPPFLAGS = $(AM_CPPFLAGS)
+endif
+endif
+
+EXTRA_DIST = README
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/telnetd/README b/cpukit/telnetd/README
new file mode 100644
index 0000000000..0c964c412d
--- /dev/null
+++ b/cpukit/telnetd/README
@@ -0,0 +1,28 @@
+#
+# $Id$
+#
+
+Author: fernando.ruiz@ctv.es (correo@fernando-ruiz.com)
+
+This directory contains a telnetd server
+primary features:
+
+ + create a user shell pseudo-terminal task.
+
+This code has not been extensively tested. It is provided as a tool
+for RTEMS users to open more shell tcp/ip pseudo-terminal.
+Suggestions and comments are appreciated.
+
+Read libmisc/shell for more information.
+
+NOTES:
+
+1. OOB not yet implemented. Only a reduced negotiation is implemented.
+
+2. If you have tcp/ip inited you can start telnetd daemon.
+ You need register pseudo-terminals driver into device drivers table.
+ 16 ptyX termios device terminales are created into /dev/.
+ Calling rtems_initialize_telnetd() starts the daemon.
+ Enjoy it.
+
+FUTURE:
diff --git a/cpukit/telnetd/icmds.c b/cpukit/telnetd/icmds.c
new file mode 100644
index 0000000000..c8e7972da8
--- /dev/null
+++ b/cpukit/telnetd/icmds.c
@@ -0,0 +1,49 @@
+#include <rtems/shell.h>
+#include <rtems/rtems_bsdnet.h>
+
+/*+++++++++++++++++++++++++++++++++++++++++++++*/
+static int main_inet(int argc,char * argv[]) {
+ rtems_bsdnet_show_inet_routes ();
+ return 0;
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++*/
+static int main_mbuf(int argc,char * argv[]) {
+ rtems_bsdnet_show_mbuf_stats ();
+ return 0;
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++*/
+static int main_if(int argc,char * argv[]) {
+ rtems_bsdnet_show_if_stats ();
+ return 0;
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++*/
+static int main_ip(int argc,char * argv[]) {
+ rtems_bsdnet_show_ip_stats ();
+ return 0;
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++*/
+static int main_icmp(int argc,char * argv[]) {
+ rtems_bsdnet_show_icmp_stats ();
+ return 0;
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++*/
+static int main_tcp(int argc,char * argv[]) {
+ rtems_bsdnet_show_tcp_stats ();
+ return 0;
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++*/
+static int main_udp(int argc,char * argv[]) {
+ rtems_bsdnet_show_udp_stats ();
+ return 0;
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++*/
+
+void _rtems_telnetd_register_icmds(void) {
+ shell_add_cmd("inet" ,"net","inet routes" ,main_inet);
+ shell_add_cmd("mbuf" ,"net","mbuf stats" ,main_mbuf);
+ shell_add_cmd("if" ,"net","if stats" ,main_if );
+ shell_add_cmd("ip" ,"net","ip stats" ,main_ip );
+ shell_add_cmd("icmp" ,"net","icmp stats" ,main_icmp);
+ shell_add_cmd("tcp" ,"net","tcp stats" ,main_tcp );
+ shell_add_cmd("udp" ,"net","udp stats" ,main_udp );
+}
diff --git a/cpukit/telnetd/preinstall.am b/cpukit/telnetd/preinstall.am
new file mode 100644
index 0000000000..486b60910b
--- /dev/null
+++ b/cpukit/telnetd/preinstall.am
@@ -0,0 +1,45 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-local: $(TMPINSTALL_FILES)
+
+TMPINSTALL_FILES =
+CLEANFILES = $(TMPINSTALL_FILES)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES += $(PREINSTALL_FILES)
+
+$(PROJECT_LIB)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_LIB)
+ @: > $(PROJECT_LIB)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
+
+if HAS_NETWORKING
+if LIBSHELL
+$(PROJECT_INCLUDE)/rtems/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/rtems
+ @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+
+$(PROJECT_INCLUDE)/rtems/pty.h: pty.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/pty.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/pty.h
+
+$(PROJECT_INCLUDE)/rtems/telnetd.h: telnetd.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/telnetd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/telnetd.h
+
+$(PROJECT_LIB)/libtelnetd.a: libtelnetd.a $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/libtelnetd.a
+TMPINSTALL_FILES += $(PROJECT_LIB)/libtelnetd.a
+endif
+endif
diff --git a/cpukit/telnetd/pty.c b/cpukit/telnetd/pty.c
new file mode 100644
index 0000000000..a650833cde
--- /dev/null
+++ b/cpukit/telnetd/pty.c
@@ -0,0 +1,408 @@
+/*
+ * /dev/ptyXX (A first version for pseudo-terminals)
+ *
+ * Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
+ * May 2001
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*-----------------------------------------*/
+#include <termios.h>
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/pty.h>
+#include <rtems/bspIo.h>
+/*-----------------------------------------*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+/*-----------------------------------------*/
+#define IAC_ESC 255
+#define IAC_DONT 254
+#define IAC_DO 253
+#define IAC_WONT 252
+#define IAC_WILL 251
+#define IAC_SB 250
+#define IAC_GA 249
+#define IAC_EL 248
+#define IAC_EC 247
+#define IAC_AYT 246
+#define IAC_AO 245
+#define IAC_IP 244
+#define IAC_BRK 243
+#define IAC_DMARK 242
+#define IAC_NOP 241
+#define IAC_SE 240
+#define IAC_EOR 239
+
+typedef struct {
+ char *devname;
+ struct rtems_termios_tty *ttyp;
+ tcflag_t c_cflag;
+ int opened;
+ int socket;
+
+ int last_cr;
+ int iac_mode;
+} pty_t;
+
+
+static int ptys_initted=FALSE;
+static pty_t *ptys;
+
+size_t rtems_pty_maximum_ptys;
+
+/* This procedure returns the devname for a free pty slot.
+ * If no slot available (field socket>=0)
+ * then the socket argument is closed
+ */
+
+char * rtems_pty_get(int socket) {
+ int ndx;
+ if (!ptys_initted) return NULL;
+ for (ndx=0;ndx<rtems_pty_maximum_ptys;ndx++) {
+ if (ptys[ndx].socket<0) {
+ ptys[ndx].socket=socket;
+ return ptys[ndx].devname;
+ };
+ };
+ close(socket);
+ return NULL;
+}
+
+
+/*-----------------------------------------------------------*/
+/*
+ * The NVT terminal is negociated in PollRead and PollWrite
+ * with every BYTE sendded or received.
+ * A litle status machine in the pty_read_byte(int minor)
+ *
+ */
+static const char IAC_AYT_RSP[]="\r\nAYT? Yes, RTEMS-SHELL is here\r\n";
+static const char IAC_BRK_RSP[]="<*Break*>";
+static const char IAC_IP_RSP []="<*Interrupt*>";
+
+
+static
+int send_iac(int minor,unsigned char mode,unsigned char option) {
+ unsigned char buf[3];
+ buf[0]=IAC_ESC;
+ buf[1]=mode;
+ buf[2]=option;
+ return write(ptys[minor].socket,buf,sizeof(buf));
+}
+
+int read_pty(int minor) { /* Characters writed in the client side*/
+ unsigned char value;
+ int count;
+ int result;
+ count=read(ptys[minor].socket,&value,sizeof(value));
+ if (count<1) {
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+ /* If you don't read from the socket the system ends the task */
+ rtems_task_delete(RTEMS_SELF);
+ };
+ switch(ptys[minor].iac_mode) {
+ case IAC_ESC:
+ ptys[minor].iac_mode=0;
+ switch(value) {
+ case IAC_ESC :
+ return IAC_ESC;
+ case IAC_DONT:
+ case IAC_DO :
+ case IAC_WONT:
+ case IAC_WILL:
+ ptys[minor].iac_mode=value;
+ return -1;
+ case IAC_SB :
+ return -100;
+ case IAC_GA :
+ return -1;
+ case IAC_EL :
+ return 0x03; /* Ctrl-C*/
+ case IAC_EC :
+ return '\b';
+ case IAC_AYT :
+ write(ptys[minor].socket,IAC_AYT_RSP,strlen(IAC_AYT_RSP));
+ return -1;
+ case IAC_AO :
+ return -1;
+ case IAC_IP :
+ write(ptys[minor].socket,IAC_IP_RSP,strlen(IAC_IP_RSP));
+ return -1;
+ case IAC_BRK :
+ write(ptys[minor].socket,IAC_BRK_RSP,strlen(IAC_BRK_RSP));
+ return -1;
+ case IAC_DMARK:
+ return -2;
+ case IAC_NOP :
+ return -1;
+ case IAC_SE :
+ return -101;
+ case IAC_EOR :
+ return -102;
+ default :
+ return -1;
+ };
+ break;
+ case IAC_WILL:
+ ptys[minor].iac_mode=0;
+ if (value==34){send_iac(minor,IAC_DONT, 34); /*LINEMODE*/
+ send_iac(minor,IAC_DO , 1);} else /*ECHO */
+ {send_iac(minor,IAC_DONT,value);};
+ return -1;
+ case IAC_DONT:
+ ptys[minor].iac_mode=0;
+ return -1;
+ case IAC_DO :
+ ptys[minor].iac_mode=0;
+ if (value==3) {send_iac(minor,IAC_WILL, 3);} else /* GO AHEAD*/
+ if (value==1) { } else /* ECHO */
+ {send_iac(minor,IAC_WONT,value);};
+ return -1;
+ case IAC_WONT:
+ ptys[minor].iac_mode=0;
+ if (value==1) {send_iac(minor,IAC_WILL, 1);} else /* ECHO */
+ {send_iac(minor,IAC_WONT,value);};
+ return -1;
+ default:
+ ptys[minor].iac_mode=0;
+ if (value==IAC_ESC) {
+ ptys[minor].iac_mode=value;
+ return -1;
+ } else {
+ result=value;
+ if (ptys[minor].last_cr && ((value=='\n')||(value=='\0'))) result=-1;
+ ptys[minor].last_cr=(value=='\r');
+ return result;
+ };
+ };
+
+}
+
+/*-----------------------------------------------------------*/
+static int ptySetAttributes(int minor,const struct termios *t);
+static int ptyPollInitialize(int major,int minor,void * arg) ;
+static int ptyShutdown(int major,int minor,void * arg) ;
+static int ptyPollWrite(int minor, const char * buf,int len) ;
+static int ptyPollRead(int minor) ;
+static const rtems_termios_callbacks * pty_get_termios_handlers(int polled) ;
+/*-----------------------------------------------------------*/
+/* Set the 'Hardware' */
+/*-----------------------------------------------------------*/
+static int
+ptySetAttributes(int minor,const struct termios *t) {
+ if (minor<rtems_pty_maximum_ptys) {
+ ptys[minor].c_cflag=t->c_cflag;
+ } else {
+ return -1;
+ };
+ return 0;
+}
+/*-----------------------------------------------------------*/
+static int
+ptyPollInitialize(int major,int minor,void * arg) {
+ rtems_libio_open_close_args_t * args = arg;
+ struct termios t;
+ if (minor<rtems_pty_maximum_ptys) {
+ if (ptys[minor].socket<0) return -1;
+ ptys[minor].opened=TRUE;
+ ptys[minor].ttyp=args->iop->data1;
+ t.c_cflag=B9600|CS8;/* termios default */
+ return ptySetAttributes(minor,&t);
+ } else {
+ return -1;
+ };
+}
+/*-----------------------------------------------------------*/
+static int
+ptyShutdown(int major,int minor,void * arg) {
+ if (minor<rtems_pty_maximum_ptys) {
+ ptys[minor].opened=FALSE;
+ if (ptys[minor].socket>=0) close(ptys[minor].socket);
+ ptys[minor].socket=-1;
+ chown(ptys[minor].devname,2,0);
+ } else {
+ return -1;
+ };
+ return 0;
+}
+/*-----------------------------------------------------------*/
+/* Write Characters into pty device */
+/*-----------------------------------------------------------*/
+static int
+ptyPollWrite(int minor, const char * buf,int len) {
+ int count;
+ if (minor<rtems_pty_maximum_ptys) {
+ if (ptys[minor].socket<0) return -1;
+ count=write(ptys[minor].socket,buf,len);
+ } else {
+ count=-1;
+ };
+ return count;
+}
+/*-----------------------------------------------------------*/
+static int
+ptyPollRead(int minor) {
+ int result;
+ if (minor<rtems_pty_maximum_ptys) {
+ if (ptys[minor].socket<0) return -1;
+ result=read_pty(minor);
+ return result;
+ };
+ return -1;
+}
+/*-----------------------------------------------------------*/
+static const rtems_termios_callbacks pty_poll_callbacks = {
+ ptyPollInitialize, /* FirstOpen*/
+ ptyShutdown, /* LastClose*/
+ ptyPollRead, /* PollRead */
+ ptyPollWrite, /* Write */
+ ptySetAttributes, /* setAttributes */
+ NULL, /* stopRemoteTX */
+ NULL, /* StartRemoteTX */
+ 0 /* outputUsesInterrupts */
+};
+/*-----------------------------------------------------------*/
+static const rtems_termios_callbacks * pty_get_termios_handlers(int polled) {
+ return &pty_poll_callbacks;
+}
+/*-----------------------------------------------------------*/
+static void init_ptys(void) {
+ int ndx;
+ ptys = malloc( sizeof(pty_t) * rtems_pty_maximum_ptys );
+ for (ndx=0;ndx<rtems_pty_maximum_ptys;ndx++) {
+ ptys[ndx].devname=malloc(strlen("/dev/ptyXX")+1);
+ sprintf(ptys[ndx].devname,"/dev/pty%X",ndx);
+ ptys[ndx].ttyp=NULL;
+ ptys[ndx].c_cflag=CS8|B9600;
+ ptys[ndx].socket=-1;
+ ptys[ndx].opened=FALSE;
+
+ };
+ ptys_initted=TRUE;
+}
+
+
+/*-----------------------------------------------------------*/
+/* pty_initialize
+ *
+ * This routine initializes the pty IO driver.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ */
+/*-----------------------------------------------------------*/
+rtems_device_driver pty_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ int ndx;
+ rtems_status_code status;
+
+ /*
+ * Set up ptys
+ */
+
+ init_ptys();
+
+ /*
+ * Register the devices
+ */
+ for (ndx=0;ndx<rtems_pty_maximum_ptys;ndx++) {
+ status = rtems_io_register_name(ptys[ndx].devname, major, ndx);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+ chmod(ptys[ndx].devname,0660);
+ chown(ptys[ndx].devname,2,0); /* tty,root*/
+ };
+ printk("Device: /dev/pty%X../dev/pty%X (%d)pseudo-terminals registered.\n",
+ 0,rtems_pty_maximum_ptys-1,rtems_pty_maximum_ptys);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * Open entry point
+ */
+
+rtems_device_driver pty_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_status_code sc ;
+ sc = rtems_termios_open(major,minor,arg,pty_get_termios_handlers(FALSE));
+ return sc;
+}
+
+/*
+ * Close entry point
+ */
+
+rtems_device_driver pty_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_close(arg);
+}
+
+/*
+ * read bytes from the pty
+ */
+
+rtems_device_driver pty_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_read(arg);
+}
+
+/*
+ * write bytes to the pty
+ */
+
+rtems_device_driver pty_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_write(arg);
+}
+
+/*
+ * IO Control entry point
+ */
+
+rtems_device_driver pty_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_ioctl(arg);
+}
diff --git a/cpukit/telnetd/pty.h b/cpukit/telnetd/pty.h
new file mode 100644
index 0000000000..7445f604a3
--- /dev/null
+++ b/cpukit/telnetd/pty.h
@@ -0,0 +1,70 @@
+/*
+ * /dev/ptyXX (A first version for pseudo-terminals)
+ *
+ * Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
+ * May 2001
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_PTY_H
+#define _RTEMS_PTY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+
+/* Number of ptys to setup */
+extern size_t rtems_pty_maximum_ptys;
+
+/* Return the devname for a free pty slot.
+ * If no slot available (socket>=0)
+ * then the socket argument is closed
+ */
+char * rtems_pty_get(int socket);
+
+
+/* OBSOLETE */
+#define get_pty rtems_pty_get
+
+rtems_device_driver pty_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg);
+rtems_device_driver pty_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg);
+rtems_device_driver pty_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg);
+rtems_device_driver pty_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg);
+rtems_device_driver pty_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg);
+rtems_device_driver pty_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg);
+
+
+#define PTY_DRIVER_TABLE_ENTRY \
+ { pty_initialize , pty_open , pty_close , \
+ pty_read , pty_write , pty_control }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/telnetd/telnetd.c b/cpukit/telnetd/telnetd.c
new file mode 100644
index 0000000000..ce5e331976
--- /dev/null
+++ b/cpukit/telnetd/telnetd.c
@@ -0,0 +1,136 @@
+/***********************************************************/
+/*
+ *
+ * The telnet DAEMON
+ *
+ * Author: 17,may 2001
+ *
+ * WORK: fernando.ruiz@ctv.es
+ * HOME: correo@fernando-ruiz.com
+ *
+ * After start the net you can start this daemon.
+ * It uses the previously inited pseudo-terminales (pty.c)
+ * getting a new terminal with getpty(). This function
+ * gives a terminal name passing a opened socket like parameter.
+ *
+ * With register_telnetd() you add a new command in the shell to start
+ * this daemon interactively. (Login in /dev/console of course)
+ *
+ * Sorry but OOB is not still implemented. (This is the first version)
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/error.h>
+#include <rtems/pty.h>
+#include <rtems/shell.h>
+#include <rtems/telnetd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h> /* memset */
+#include <stdio.h>
+
+/* FIXME: This should not be here */
+extern void _rtems_telnetd_register_icmds(void);
+
+/***********************************************************/
+rtems_id telnetd_task_id =0;
+uint32_t telnetd_stack_size =16384;
+rtems_task_priority telnetd_task_priority=100;
+/***********************************************************/
+rtems_task rtems_task_telnetd(rtems_task_argument task_argument) {
+ int des_socket,
+ acp_socket;
+ struct sockaddr_in srv;
+ char * devname;
+ int i=1;
+ socklen_t size_adr;
+ if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
+ perror("telnetd:socket");
+ rtems_task_delete(RTEMS_SELF);
+ };
+ setsockopt(des_socket,SOL_SOCKET,0,&i,sizeof(i));
+ memset(&srv,0,sizeof(srv));
+ srv.sin_family=AF_INET;
+ srv.sin_port=htons(23);
+ size_adr=sizeof(srv);
+ if ((bind(des_socket,(struct sockaddr *)&srv,size_adr))<0) {
+ perror("telnetd:bind");
+ close(des_socket);
+ rtems_task_delete(RTEMS_SELF);
+ };
+ if ((listen(des_socket,5))<0) {
+ perror("telnetd:listen");
+ close(des_socket);
+ rtems_task_delete(RTEMS_SELF);
+ };
+ do {
+ acp_socket=accept(des_socket,(struct sockaddr*)&srv,&size_adr);
+ if (acp_socket<0) {
+ perror("telnetd:accept");
+ break;
+ };
+ if ((devname = rtems_pty_get(acp_socket)) ) {
+ shell_init(&devname[5],
+ telnetd_stack_size,
+ telnetd_task_priority,
+ devname,B9600|CS8,FALSE);
+ } else {
+ close(acp_socket);
+ };
+ } while(1);
+ close(des_socket);
+ rtems_task_delete(RTEMS_SELF);
+}
+/***********************************************************/
+int rtems_telnetd_initialize(void) {
+ rtems_status_code sc;
+
+ _rtems_telnetd_register_icmds(); /* stats for tcp/ip */
+
+ if (telnetd_task_id ) return RTEMS_RESOURCE_IN_USE;
+ if (telnetd_stack_size<=0 ) telnetd_stack_size =16384;
+ if (telnetd_task_priority<=2) telnetd_task_priority=100;
+ sc=rtems_task_create(new_rtems_name("tlnd"),
+ 100,RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &telnetd_task_id);
+ if (sc!=RTEMS_SUCCESSFUL) {
+ rtems_error(sc,"creating task telnetd");
+ return (int)sc;
+ };
+ sc=rtems_task_start(telnetd_task_id,
+ rtems_task_telnetd,
+ (rtems_task_argument)NULL);
+ if (sc!=RTEMS_SUCCESSFUL) {
+ rtems_error(sc,"starting task telnetd");
+ };
+ return (int)sc;
+}
+/***********************************************************/
+int rtems_telnetd_main(int argc,char * argv[]) {
+ rtems_status_code sc;
+ if (telnetd_task_id) {
+ printf("ERROR:telnetd already started\n");
+ return 1;
+ };
+ if (argc>1) telnetd_stack_size =str2int(argv[1]);
+ if (argc>2) telnetd_task_priority=str2int(argv[2]);
+ sc=rtems_initialize_telnetd();
+ if (sc!=RTEMS_SUCCESSFUL) return sc;
+ printf("rtems_telnetd() started with stacksize=%u,priority=%d\n",
+ telnetd_stack_size,telnetd_task_priority);
+ return 0;
+}
+/***********************************************************/
+int rtems_telnetd_register(void) {
+ shell_add_cmd("telnetd","telnet","telnetd [stacksize [tsk_priority]]",main_telnetd);
+ return 0;
+}
+/***********************************************************/
diff --git a/cpukit/telnetd/telnetd.h b/cpukit/telnetd/telnetd.h
new file mode 100644
index 0000000000..c8c068c9fb
--- /dev/null
+++ b/cpukit/telnetd/telnetd.h
@@ -0,0 +1,39 @@
+/*
+ * (A first version for telnetd)
+ *
+ * Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
+ * May 2001
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * rtems_initialize_telnetd() starts the daemon.
+ * main_telnetd() is the main_proc for the command telnetd in the shell
+ * register_telnetd() add a new command in the shell to start
+ * interactively the telnetd daemon.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_TELNETD_H
+#define _RTEMS_TELNETD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int rtems_telnetd_initialize(void);
+extern int rtems_telnetd_main(int argc,char * argv[]);
+extern int rtems_telnetd_register(void);
+
+/* OBSOLETE */
+#define rtems_initialize_telnetd rtems_telnetd_initialize
+#define main_telnetd rtems_telnetd_main
+#define register_telnetd rtems_telnetd_register
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/wrapup/.cvsignore b/cpukit/wrapup/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/wrapup/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/wrapup/Makefile.am b/cpukit/wrapup/Makefile.am
new file mode 100644
index 0000000000..1ff4a1d3af
--- /dev/null
+++ b/cpukit/wrapup/Makefile.am
@@ -0,0 +1,105 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+## Setup the variant build subdirectory
+ARCH = o-optimize
+
+project_lib_LIBRARIES = librtemscpu.a
+librtemscpu_a_SOURCES =
+
+TMP_LIBS =
+TMP_LIBS += ../score/cpu/@RTEMS_CPU@/libscorecpu.a
+TMP_LIBS += ../score/libscore.a
+TMP_LIBS += ../sapi/libsapi.a
+TMP_LIBS += ../rtems/librtems.a
+
+if HAS_POSIX
+TMP_LIBS += ../posix/libposix.a
+endif
+
+if HAS_ITRON
+TMP_LIBS += ../itron/libitron.a
+endif
+
+TMP_LIBS += ../libcsupport/libcsupport.a
+if !UNIX
+TMP_LIBS += ../libblock/libblock.a
+TMP_LIBS += ../libfs/libdosfs.a
+endif
+TMP_LIBS += ../libfs/libimfs.a
+
+TMP_LIBS += ../libmisc/libmonitor.a
+TMP_LIBS += ../libmisc/libuntar.a
+TMP_LIBS += ../libmisc/libstackchk.a
+TMP_LIBS += ../libmisc/libcpuuse.a
+TMP_LIBS += ../libmisc/librtmonuse.a
+
+## XXX temporarily removed because it causes a
+## XXX number of BSPs to not link "main(){}" used by autoconf
+# if LIBSERDBG
+# TMP_LIBS += ../libmisc/libserdbg.a
+# endif
+
+if LIBSHELL
+TMP_LIBS += ../libmisc/libshell.a
+endif
+
+TMP_LIBS += ../libmisc/libdumpbuf.a
+TMP_LIBS += ../libmisc/libdevnull.a
+TMP_LIBS += ../libmisc/libdummy.a
+TMP_LIBS += ../libmisc/libmw-fb.a
+TMP_LIBS += ../libmisc/libcapture.a
+TMP_LIBS += ../libmisc/libfsmount.a
+
+TMP_LIBS += ../libi2c/libi2c.a
+
+if HAS_NETWORKING
+TMP_LIBS += ../libnetworking/libnetworking.a
+TMP_LIBS += ../libnetworking/libc.a
+TMP_LIBS += ../libnetworking/lib.a
+endif
+
+if LIBRPC
+TMP_LIBS += ../librpc/librpc.a
+TMP_LIBS += ../librpc/libxdr.a
+endif
+
+librtemscpu.a: $(TMP_LIBS)
+ rm -f $@
+ $(mkdir_p) $(ARCH)
+ rm -rf $(ARCH)/*.$(OBJEXT) $(ARCH)/*.rel
+ for f in $(TMP_LIBS); do \
+ case $$f in \
+ *.$(OBJEXT) | *.rel) \
+ if test -f $(ARCH)/`basename $$f`; then \
+ if cmp $$f $(ARCH)/`basename $$f`; then \
+ true; \
+ else \
+ echo 1>&2 "ERROR -- `basename $$f` in multiple files"; \
+ exit 1; \
+ fi; \
+ else \
+ cp $$f $(ARCH)/; \
+ chmod a-w $(ARCH)/`basename $$f`; \
+ fi; \
+ ;; \
+ *.a) \
+ cd $(ARCH); \
+ $(AR) xv ../$$f || exit 1; \
+ chmod a-w * ; \
+ cd ..; \
+ ;; \
+ esac; \
+ done
+ $(AR) rc $@ $(ARCH)/*
+ rm -f $(ARCH)/*.$(OBJEXT) $(ARCH)/*.rel
+ $(RANLIB) $@
+
+all-local: $(TMPINSTALL_FILES)
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/wrapup/preinstall.am b/cpukit/wrapup/preinstall.am
new file mode 100644
index 0000000000..71683f364e
--- /dev/null
+++ b/cpukit/wrapup/preinstall.am
@@ -0,0 +1,24 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-local: $(TMPINSTALL_FILES)
+
+TMPINSTALL_FILES =
+CLEANFILES = $(TMPINSTALL_FILES)
+
+$(PROJECT_LIB)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_LIB)
+ @: > $(PROJECT_LIB)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
+
+$(PROJECT_LIB)/librtemscpu.a: librtemscpu.a $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/librtemscpu.a
+TMPINSTALL_FILES += $(PROJECT_LIB)/librtemscpu.a
+
diff --git a/cpukit/zlib/.cvsignore b/cpukit/zlib/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/cpukit/zlib/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/cpukit/zlib/ChangeLog b/cpukit/zlib/ChangeLog
index d162e90e78..0141b562d8 100644
--- a/cpukit/zlib/ChangeLog
+++ b/cpukit/zlib/ChangeLog
@@ -1,805 +1,31 @@
+2005-10-30 Ralf Corsepius <ralf.corsepius@rtems.org>
- ChangeLog file for zlib
+ * zconf.h: Hard-code using unistd.h.
+ Hard-code Z_PREFIX.
-Changes in 1.2.2.2 (30 December 2004)
-- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
- avoid implicit memcpy calls (portability for no-library compilation)
-- Increase sprintf() buffer size in gzdopen() to allow for large numbers
-- Add INFLATE_STRICT to check distances against zlib header
-- Improve WinCE errno handling and comments [Chang]
-- Remove comment about no gzip header processing in FAQ
-- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
-- Add updated make_vms.com [Coghlan], update README
-- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
- fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
-- Add FAQ entry and comments in deflate.c on uninitialized memory access
-- Add Solaris 9 make options in configure [Gilbert]
-- Allow strerror() usage in gzio.c for STDC
-- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
-- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
-- Use z_off_t for adler32_combine() and crc32_combine() lengths
-- Make adler32() much faster for small len
-- Use OS_CODE in deflate() default gzip header
+2005-10-28 Ralf Corsepius <ralf.corsepius@rtems.org>
-Changes in 1.2.2.1 (31 October 2004)
-- Allow inflateSetDictionary() call for raw inflate
-- Fix inflate header crc check bug for file names and comments
-- Add deflateSetHeader() and gz_header structure for custom gzip headers
-- Add inflateGetheader() to retrieve gzip headers
-- Add crc32_combine() and adler32_combine() functions
-- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
-- Use zstreamp consistently in zlib.h (inflate_back functions)
-- Remove GUNZIP condition from definition of inflate_mode in inflate.h
- and in contrib/inflate86/inffast.S [Truta, Anderson]
-- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
-- Update projects/README.projects and projects/visualc6 [Truta]
-- Update win32/DLL_FAQ.txt [Truta]
-- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
-- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
-- Use a new algorithm for setting strm->data_type in trees.c [Truta]
-- Do not define an exit() prototype in zutil.c unless DEBUG defined
-- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
-- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
-- Fix Darwin build version identification [Peterson]
+ * zconf.in.h: Remove (Unused).
+ * zconf.h: Use uint_least*_t types.
+ * crc32.c, zutil.c, zutil.h: Misc. type fixes.
-Changes in 1.2.2 (3 October 2004)
-- Update zlib.h comments on gzip in-memory processing
-- Set adler to 1 in inflateReset() to support Java test suite [Walles]
-- Add contrib/dotzlib [Ravn]
-- Update win32/DLL_FAQ.txt [Truta]
-- Update contrib/minizip [Vollant]
-- Move contrib/visual-basic.txt to old/ [Truta]
-- Fix assembler builds in projects/visualc6/ [Truta]
+2005-10-28 Ralf Corsepius <ralf.corsepius@rtems.org>
-Changes in 1.2.1.2 (9 September 2004)
-- Update INDEX file
-- Fix trees.c to update strm->data_type (no one ever noticed!)
-- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
-- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
-- Add limited multitasking protection to DYNAMIC_CRC_TABLE
-- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
-- Don't declare strerror() under VMS [Mozilla]
-- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
-- Update contrib/ada [Anisimkov]
-- Update contrib/minizip [Vollant]
-- Fix configure to not hardcode directories for Darwin [Peterson]
-- Fix gzio.c to not return error on empty files [Brown]
-- Fix indentation; update version in contrib/delphi/ZLib.pas and
- contrib/pascal/zlibpas.pas [Truta]
-- Update mkasm.bat in contrib/masmx86 [Truta]
-- Update contrib/untgz [Truta]
-- Add projects/README.projects [Truta]
-- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
-- Update win32/DLL_FAQ.txt [Truta]
-- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
-- Remove an unnecessary assignment to curr in inftrees.c [Truta]
-- Add OS/2 to exe builds in configure [Poltorak]
-- Remove err dummy parameter in zlib.h [Kientzle]
+ * Makefile.am: New.
+ * preinstall.am: New.
-Changes in 1.2.1.1 (9 January 2004)
-- Update email address in README
-- Several FAQ updates
-- Fix a big fat bug in inftrees.c that prevented decoding valid
- dynamic blocks with only literals and no distance codes --
- Thanks to "Hot Emu" for the bug report and sample file
-- Add a note to puff.c on no distance codes case.
+2005-10-28 Ralf Corsepius <ralf.corsepius@rtems.org>
-Changes in 1.2.1 (17 November 2003)
-- Remove a tab in contrib/gzappend/gzappend.c
-- Update some interfaces in contrib for new zlib functions
-- Update zlib version number in some contrib entries
-- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
-- Support shared libraries on Hurd and KFreeBSD [Brown]
-- Fix error in NO_DIVIDE option of adler32.c
+ * adler32.c, compress.c, crc32.c, deflate.c, deflate.h, gzio.c,
+ trees.c, uncompr.c, zconf.h, zconf.in.h, zutil.c, zutil.h: Reformat
+ CVS Ids.
-Changes in 1.2.0.8 (4 November 2003)
-- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
-- Add experimental NO_DIVIDE #define in adler32.c
- - Possibly faster on some processors (let me know if it is)
-- Correct Z_BLOCK to not return on first inflate call if no wrap
-- Fix strm->data_type on inflate() return to correctly indicate EOB
-- Add deflatePrime() function for appending in the middle of a byte
-- Add contrib/gzappend for an example of appending to a stream
-- Update win32/DLL_FAQ.txt [Truta]
-- Delete Turbo C comment in README [Truta]
-- Improve some indentation in zconf.h [Truta]
-- Fix infinite loop on bad input in configure script [Church]
-- Fix gzeof() for concatenated gzip files [Johnson]
-- Add example to contrib/visual-basic.txt [Michael B.]
-- Add -p to mkdir's in Makefile.in [vda]
-- Fix configure to properly detect presence or lack of printf functions
-- Add AS400 support [Monnerat]
-- Add a little Cygwin support [Wilson]
+2005-10-28 Ralf Corsepius <ralf.corsepius@rtems.org>
-Changes in 1.2.0.7 (21 September 2003)
-- Correct some debug formats in contrib/infback9
-- Cast a type in a debug statement in trees.c
-- Change search and replace delimiter in configure from % to # [Beebe]
-- Update contrib/untgz to 0.2 with various fixes [Truta]
-- Add build support for Amiga [Nikl]
-- Remove some directories in old that have been updated to 1.2
-- Add dylib building for Mac OS X in configure and Makefile.in
-- Remove old distribution stuff from Makefile
-- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
-- Update links in README
+ * ChangeLog.zlib: Renamed version of zlib's ChangeLog.
+ * FAQ, INDEX, README, adler32.c, algorithm.txt, compress.c, crc32.c,
+ crc32.h, deflate.c, deflate.h, gzio.c, infback.c, inffast.c,
+ inffast.h, inffixed.h, inflate.c, inflate.h, trees.c, trees.h,
+ uncompr.c, zconf.h, zconf.in.h, zlib.3, zlib.h, zutil.c, zutil.h,
+ inftrees.h, inftrees.c, ChangeLog: Import from zlib-1.2.2.2.tar.gz.
-Changes in 1.2.0.6 (13 September 2003)
-- Minor FAQ updates
-- Update contrib/minizip to 1.00 [Vollant]
-- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
-- Update POSTINC comment for 68060 [Nikl]
-- Add contrib/infback9 with deflate64 decoding (unsupported)
-- For MVS define NO_vsnprintf and undefine FAR [van Burik]
-- Add pragma for fdopen on MVS [van Burik]
-
-Changes in 1.2.0.5 (8 September 2003)
-- Add OF to inflateBackEnd() declaration in zlib.h
-- Remember start when using gzdopen in the middle of a file
-- Use internal off_t counters in gz* functions to properly handle seeks
-- Perform more rigorous check for distance-too-far in inffast.c
-- Add Z_BLOCK flush option to return from inflate at block boundary
-- Set strm->data_type on return from inflate
- - Indicate bits unused, if at block boundary, and if in last block
-- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
-- Add condition so old NO_DEFLATE define still works for compatibility
-- FAQ update regarding the Windows DLL [Truta]
-- INDEX update: add qnx entry, remove aix entry [Truta]
-- Install zlib.3 into mandir [Wilson]
-- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
-- Adapt the zlib interface to the new DLL convention guidelines [Truta]
-- Introduce ZLIB_WINAPI macro to allow the export of functions using
- the WINAPI calling convention, for Visual Basic [Vollant, Truta]
-- Update msdos and win32 scripts and makefiles [Truta]
-- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
-- Add contrib/ada [Anisimkov]
-- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
-- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
-- Add contrib/masm686 [Truta]
-- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
- [Truta, Vollant]
-- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
-- Remove contrib/delphi2; add a new contrib/delphi [Truta]
-- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
- and fix some method prototypes [Truta]
-- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
- [Truta]
-- Avoid the use of backslash (\) in contrib/minizip [Vollant]
-- Fix file time handling in contrib/untgz; update makefiles [Truta]
-- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
- [Vollant]
-- Remove contrib/vstudio/vc15_16 [Vollant]
-- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
-- Update README.contrib [Truta]
-- Invert the assignment order of match_head and s->prev[...] in
- INSERT_STRING [Truta]
-- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
- [Truta]
-- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
-- Fix prototype of syncsearch in inflate.c [Truta]
-- Introduce ASMINF macro to be enabled when using an ASM implementation
- of inflate_fast [Truta]
-- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
-- Modify test_gzio in example.c to take a single file name as a
- parameter [Truta]
-- Exit the example.c program if gzopen fails [Truta]
-- Add type casts around strlen in example.c [Truta]
-- Remove casting to sizeof in minigzip.c; give a proper type
- to the variable compared with SUFFIX_LEN [Truta]
-- Update definitions of STDC and STDC99 in zconf.h [Truta]
-- Synchronize zconf.h with the new Windows DLL interface [Truta]
-- Use SYS16BIT instead of __32BIT__ to distinguish between
- 16- and 32-bit platforms [Truta]
-- Use far memory allocators in small 16-bit memory models for
- Turbo C [Truta]
-- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
- zlibCompileFlags [Truta]
-- Cygwin has vsnprintf [Wilson]
-- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
-- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
-
-Changes in 1.2.0.4 (10 August 2003)
-- Minor FAQ updates
-- Be more strict when checking inflateInit2's windowBits parameter
-- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
-- Add gzip wrapper option to deflateInit2 using windowBits
-- Add updated QNX rule in configure and qnx directory [Bonnefoy]
-- Make inflate distance-too-far checks more rigorous
-- Clean up FAR usage in inflate
-- Add casting to sizeof() in gzio.c and minigzip.c
-
-Changes in 1.2.0.3 (19 July 2003)
-- Fix silly error in gzungetc() implementation [Vollant]
-- Update contrib/minizip and contrib/vstudio [Vollant]
-- Fix printf format in example.c
-- Correct cdecl support in zconf.in.h [Anisimkov]
-- Minor FAQ updates
-
-Changes in 1.2.0.2 (13 July 2003)
-- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
-- Attempt to avoid warnings in crc32.c for pointer-int conversion
-- Add AIX to configure, remove aix directory [Bakker]
-- Add some casts to minigzip.c
-- Improve checking after insecure sprintf() or vsprintf() calls
-- Remove #elif's from crc32.c
-- Change leave label to inf_leave in inflate.c and infback.c to avoid
- library conflicts
-- Remove inflate gzip decoding by default--only enable gzip decoding by
- special request for stricter backward compatibility
-- Add zlibCompileFlags() function to return compilation information
-- More typecasting in deflate.c to avoid warnings
-- Remove leading underscore from _Capital #defines [Truta]
-- Fix configure to link shared library when testing
-- Add some Windows CE target adjustments [Mai]
-- Remove #define ZLIB_DLL in zconf.h [Vollant]
-- Add zlib.3 [Rodgers]
-- Update RFC URL in deflate.c and algorithm.txt [Mai]
-- Add zlib_dll_FAQ.txt to contrib [Truta]
-- Add UL to some constants [Truta]
-- Update minizip and vstudio [Vollant]
-- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
-- Expand use of NO_DUMMY_DECL to avoid all dummy structures
-- Added iostream3 to contrib [Schwardt]
-- Replace rewind() with fseek() for WinCE [Truta]
-- Improve setting of zlib format compression level flags
- - Report 0 for huffman and rle strategies and for level == 0 or 1
- - Report 2 only for level == 6
-- Only deal with 64K limit when necessary at compile time [Truta]
-- Allow TOO_FAR check to be turned off at compile time [Truta]
-- Add gzclearerr() function [Souza]
-- Add gzungetc() function
-
-Changes in 1.2.0.1 (17 March 2003)
-- Add Z_RLE strategy for run-length encoding [Truta]
- - When Z_RLE requested, restrict matches to distance one
- - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
-- Correct FASTEST compilation to allow level == 0
-- Clean up what gets compiled for FASTEST
-- Incorporate changes to zconf.in.h [Vollant]
- - Refine detection of Turbo C need for dummy returns
- - Refine ZLIB_DLL compilation
- - Include additional header file on VMS for off_t typedef
-- Try to use _vsnprintf where it supplants vsprintf [Vollant]
-- Add some casts in inffast.c
-- Enchance comments in zlib.h on what happens if gzprintf() tries to
- write more than 4095 bytes before compression
-- Remove unused state from inflateBackEnd()
-- Remove exit(0) from minigzip.c, example.c
-- Get rid of all those darn tabs
-- Add "check" target to Makefile.in that does the same thing as "test"
-- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
-- Update contrib/inflate86 [Anderson]
-- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
-- Add msdos and win32 directories with makefiles [Truta]
-- More additions and improvements to the FAQ
-
-Changes in 1.2.0 (9 March 2003)
-- New and improved inflate code
- - About 20% faster
- - Does not allocate 32K window unless and until needed
- - Automatically detects and decompresses gzip streams
- - Raw inflate no longer needs an extra dummy byte at end
- - Added inflateBack functions using a callback interface--even faster
- than inflate, useful for file utilities (gzip, zip)
- - Added inflateCopy() function to record state for random access on
- externally generated deflate streams (e.g. in gzip files)
- - More readable code (I hope)
-- New and improved crc32()
- - About 50% faster, thanks to suggestions from Rodney Brown
-- Add deflateBound() and compressBound() functions
-- Fix memory leak in deflateInit2()
-- Permit setting dictionary for raw deflate (for parallel deflate)
-- Fix const declaration for gzwrite()
-- Check for some malloc() failures in gzio.c
-- Fix bug in gzopen() on single-byte file 0x1f
-- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
- and next buffer doesn't start with 0x8b
-- Fix uncompress() to return Z_DATA_ERROR on truncated input
-- Free memory at end of example.c
-- Remove MAX #define in trees.c (conflicted with some libraries)
-- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
-- Declare malloc() and free() in gzio.c if STDC not defined
-- Use malloc() instead of calloc() in zutil.c if int big enough
-- Define STDC for AIX
-- Add aix/ with approach for compiling shared library on AIX
-- Add HP-UX support for shared libraries in configure
-- Add OpenUNIX support for shared libraries in configure
-- Use $cc instead of gcc to build shared library
-- Make prefix directory if needed when installing
-- Correct Macintosh avoidance of typedef Byte in zconf.h
-- Correct Turbo C memory allocation when under Linux
-- Use libz.a instead of -lz in Makefile (assure use of compiled library)
-- Update configure to check for snprintf or vsnprintf functions and their
- return value, warn during make if using an insecure function
-- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
- is lost when library is used--resolution is to build new zconf.h
-- Documentation improvements (in zlib.h):
- - Document raw deflate and inflate
- - Update RFCs URL
- - Point out that zlib and gzip formats are different
- - Note that Z_BUF_ERROR is not fatal
- - Document string limit for gzprintf() and possible buffer overflow
- - Note requirement on avail_out when flushing
- - Note permitted values of flush parameter of inflate()
-- Add some FAQs (and even answers) to the FAQ
-- Add contrib/inflate86/ for x86 faster inflate
-- Add contrib/blast/ for PKWare Data Compression Library decompression
-- Add contrib/puff/ simple inflate for deflate format description
-
-Changes in 1.1.4 (11 March 2002)
-- ZFREE was repeated on same allocation on some error conditions.
- This creates a security problem described in
- http://www.zlib.org/advisory-2002-03-11.txt
-- Returned incorrect error (Z_MEM_ERROR) on some invalid data
-- Avoid accesses before window for invalid distances with inflate window
- less than 32K.
-- force windowBits > 8 to avoid a bug in the encoder for a window size
- of 256 bytes. (A complete fix will be available in 1.1.5).
-
-Changes in 1.1.3 (9 July 1998)
-- fix "an inflate input buffer bug that shows up on rare but persistent
- occasions" (Mark)
-- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
-- fix gzseek(..., SEEK_SET) in write mode
-- fix crc check after a gzeek (Frank Faubert)
-- fix miniunzip when the last entry in a zip file is itself a zip file
- (J Lillge)
-- add contrib/asm586 and contrib/asm686 (Brian Raiter)
- See http://www.muppetlabs.com/~breadbox/software/assembly.html
-- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
-- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
-- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
-- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
-- added a FAQ file
-
-- Support gzdopen on Mac with Metrowerks (Jason Linhart)
-- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
-- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
-- avoid some warnings with Borland C (Tom Tanner)
-- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
-- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant)
-- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
-- use libdir and includedir in Makefile.in (Tim Mooney)
-- support shared libraries on OSF1 V4 (Tim Mooney)
-- remove so_locations in "make clean" (Tim Mooney)
-- fix maketree.c compilation error (Glenn, Mark)
-- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
-- new Makefile.riscos (Rich Walker)
-- initialize static descriptors in trees.c for embedded targets (Nick Smith)
-- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
-- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
-- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
-- fix maketree.c to allow clean compilation of inffixed.h (Mark)
-- fix parameter check in deflateCopy (Gunther Nikl)
-- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
-- Many portability patches by Christian Spieler:
- . zutil.c, zutil.h: added "const" for zmem*
- . Make_vms.com: fixed some typos
- . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
- . msdos/Makefile.msc: remove "default rtl link library" info from obj files
- . msdos/Makefile.*: use model-dependent name for the built zlib library
- . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
- new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
-- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
-- replace __far with _far for better portability (Christian Spieler, Tom Lane)
-- fix test for errno.h in configure (Tim Newsham)
-
-Changes in 1.1.2 (19 March 98)
-- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
- See http://www.winimage.com/zLibDll/unzip.html
-- preinitialize the inflate tables for fixed codes, to make the code
- completely thread safe (Mark)
-- some simplifications and slight speed-up to the inflate code (Mark)
-- fix gzeof on non-compressed files (Allan Schrum)
-- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
-- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
-- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
-- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
-- do not wrap extern "C" around system includes (Tom Lane)
-- mention zlib binding for TCL in README (Andreas Kupries)
-- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
-- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
-- allow "configure --prefix $HOME" (Tim Mooney)
-- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
-- move Makefile.sas to amiga/Makefile.sas
-
-Changes in 1.1.1 (27 Feb 98)
-- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson)
-- remove block truncation heuristic which had very marginal effect for zlib
- (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
- compression ratio on some files. This also allows inlining _tr_tally for
- matches in deflate_slow.
-- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
-
-Changes in 1.1.0 (24 Feb 98)
-- do not return STREAM_END prematurely in inflate (John Bowler)
-- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
-- compile with -DFASTEST to get compression code optimized for speed only
-- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
-- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
- on Sun but significant on HP)
-
-- add a pointer to experimental unzip library in README (Gilles Vollant)
-- initialize variable gcc in configure (Chris Herborth)
-
-Changes in 1.0.9 (17 Feb 1998)
-- added gzputs and gzgets functions
-- do not clear eof flag in gzseek (Mark Diekhans)
-- fix gzseek for files in transparent mode (Mark Diekhans)
-- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
-- replace EXPORT with ZEXPORT to avoid conflict with other programs
-- added compress2 in zconf.h, zlib.def, zlib.dnt
-- new asm code from Gilles Vollant in contrib/asm386
-- simplify the inflate code (Mark):
- . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
- . ZALLOC the length list in inflate_trees_fixed() instead of using stack
- . ZALLOC the value area for huft_build() instead of using stack
- . Simplify Z_FINISH check in inflate()
-
-- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
-- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
-- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
- the declaration of FAR (Gilles VOllant)
-- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
-- read_buf buf parameter of type Bytef* instead of charf*
-- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
-- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
-- fix check for presence of directories in "make install" (Ian Willis)
-
-Changes in 1.0.8 (27 Jan 1998)
-- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
-- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
-- added compress2() to allow setting the compression level
-- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
-- use constant arrays for the static trees in trees.c instead of computing
- them at run time (thanks to Ken Raeburn for this suggestion). To create
- trees.h, compile with GEN_TREES_H and run "make test".
-- check return code of example in "make test" and display result
-- pass minigzip command line options to file_compress
-- simplifying code of inflateSync to avoid gcc 2.8 bug
-
-- support CC="gcc -Wall" in configure -s (QingLong)
-- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
-- fix test for shared library support to avoid compiler warnings
-- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
-- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
-- do not use fdopen for Metrowerks on Mac (Brad Pettit))
-- add checks for gzputc and gzputc in example.c
-- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
-- use const for the CRC table (Ken Raeburn)
-- fixed "make uninstall" for shared libraries
-- use Tracev instead of Trace in infblock.c
-- in example.c use correct compressed length for test_sync
-- suppress +vnocompatwarnings in configure for HPUX (not always supported)
-
-Changes in 1.0.7 (20 Jan 1998)
-- fix gzseek which was broken in write mode
-- return error for gzseek to negative absolute position
-- fix configure for Linux (Chun-Chung Chen)
-- increase stack space for MSC (Tim Wegner)
-- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
-- define EXPORTVA for gzprintf (Gilles Vollant)
-- added man page zlib.3 (Rick Rodgers)
-- for contrib/untgz, fix makedir() and improve Makefile
-
-- check gzseek in write mode in example.c
-- allocate extra buffer for seeks only if gzseek is actually called
-- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
-- add inflateSyncPoint in zconf.h
-- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
-
-Changes in 1.0.6 (19 Jan 1998)
-- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
- gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
-- Fix a deflate bug occuring only with compression level 0 (thanks to
- Andy Buckler for finding this one).
-- In minigzip, pass transparently also the first byte for .Z files.
-- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
-- check Z_FINISH in inflate (thanks to Marc Schluper)
-- Implement deflateCopy (thanks to Adam Costello)
-- make static libraries by default in configure, add --shared option.
-- move MSDOS or Windows specific files to directory msdos
-- suppress the notion of partial flush to simplify the interface
- (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
-- suppress history buffer provided by application to simplify the interface
- (this feature was not implemented anyway in 1.0.4)
-- next_in and avail_in must be initialized before calling inflateInit or
- inflateInit2
-- add EXPORT in all exported functions (for Windows DLL)
-- added Makefile.nt (thanks to Stephen Williams)
-- added the unsupported "contrib" directory:
- contrib/asm386/ by Gilles Vollant <info@winimage.com>
- 386 asm code replacing longest_match().
- contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
- A C++ I/O streams interface to the zlib gz* functions
- contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
- Another C++ I/O streams interface
- contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
- A very simple tar.gz file extractor using zlib
- contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
- How to use compress(), uncompress() and the gz* functions from VB.
-- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
- level) in minigzip (thanks to Tom Lane)
-
-- use const for rommable constants in deflate
-- added test for gzseek and gztell in example.c
-- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
-- add undocumented function zError to convert error code to string
- (for Tim Smithers)
-- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
-- Use default memcpy for Symantec MSDOS compiler.
-- Add EXPORT keyword for check_func (needed for Windows DLL)
-- add current directory to LD_LIBRARY_PATH for "make test"
-- create also a link for libz.so.1
-- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
-- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
-- added -soname for Linux in configure (Chun-Chung Chen,
-- assign numbers to the exported functions in zlib.def (for Windows DLL)
-- add advice in zlib.h for best usage of deflateSetDictionary
-- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
-- allow compilation with ANSI keywords only enabled for TurboC in large model
-- avoid "versionString"[0] (Borland bug)
-- add NEED_DUMMY_RETURN for Borland
-- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
-- allow compilation with CC
-- defined STDC for OS/2 (David Charlap)
-- limit external names to 8 chars for MVS (Thomas Lund)
-- in minigzip.c, use static buffers only for 16-bit systems
-- fix suffix check for "minigzip -d foo.gz"
-- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
-- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
-- added makelcc.bat for lcc-win32 (Tom St Denis)
-- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
-- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
-- check for unistd.h in configure (for off_t)
-- remove useless check parameter in inflate_blocks_free
-- avoid useless assignment of s->check to itself in inflate_blocks_new
-- do not flush twice in gzclose (thanks to Ken Raeburn)
-- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
-- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
-- work around buggy fclose on pipes for HP/UX
-- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
-- fix configure if CC is already equal to gcc
-
-Changes in 1.0.5 (3 Jan 98)
-- Fix inflate to terminate gracefully when fed corrupted or invalid data
-- Use const for rommable constants in inflate
-- Eliminate memory leaks on error conditions in inflate
-- Removed some vestigial code in inflate
-- Update web address in README
-
-Changes in 1.0.4 (24 Jul 96)
-- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
- bit, so the decompressor could decompress all the correct data but went
- on to attempt decompressing extra garbage data. This affected minigzip too.
-- zlibVersion and gzerror return const char* (needed for DLL)
-- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
-- use z_error only for DEBUG (avoid problem with DLLs)
-
-Changes in 1.0.3 (2 Jul 96)
-- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
- small and medium models; this makes the library incompatible with previous
- versions for these models. (No effect in large model or on other systems.)
-- return OK instead of BUF_ERROR if previous deflate call returned with
- avail_out as zero but there is nothing to do
-- added memcmp for non STDC compilers
-- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
-- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
-- better check for 16-bit mode MSC (avoids problem with Symantec)
-
-Changes in 1.0.2 (23 May 96)
-- added Windows DLL support
-- added a function zlibVersion (for the DLL support)
-- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
-- Bytef is define's instead of typedef'd only for Borland C
-- avoid reading uninitialized memory in example.c
-- mention in README that the zlib format is now RFC1950
-- updated Makefile.dj2
-- added algorithm.doc
-
-Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
-- fix array overlay in deflate.c which sometimes caused bad compressed data
-- fix inflate bug with empty stored block
-- fix MSDOS medium model which was broken in 0.99
-- fix deflateParams() which could generated bad compressed data.
-- Bytef is define'd instead of typedef'ed (work around Borland bug)
-- added an INDEX file
-- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
- Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
-- speed up adler32 for modern machines without auto-increment
-- added -ansi for IRIX in configure
-- static_init_done in trees.c is an int
-- define unlink as delete for VMS
-- fix configure for QNX
-- add configure branch for SCO and HPUX
-- avoid many warnings (unused variables, dead assignments, etc...)
-- no fdopen for BeOS
-- fix the Watcom fix for 32 bit mode (define FAR as empty)
-- removed redefinition of Byte for MKWERKS
-- work around an MWKERKS bug (incorrect merge of all .h files)
-
-Changes in 0.99 (27 Jan 96)
-- allow preset dictionary shared between compressor and decompressor
-- allow compression level 0 (no compression)
-- add deflateParams in zlib.h: allow dynamic change of compression level
- and compression strategy.
-- test large buffers and deflateParams in example.c
-- add optional "configure" to build zlib as a shared library
-- suppress Makefile.qnx, use configure instead
-- fixed deflate for 64-bit systems (detected on Cray)
-- fixed inflate_blocks for 64-bit systems (detected on Alpha)
-- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
-- always return Z_BUF_ERROR when deflate() has nothing to do
-- deflateInit and inflateInit are now macros to allow version checking
-- prefix all global functions and types with z_ with -DZ_PREFIX
-- make falloc completely reentrant (inftrees.c)
-- fixed very unlikely race condition in ct_static_init
-- free in reverse order of allocation to help memory manager
-- use zlib-1.0/* instead of zlib/* inside the tar.gz
-- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
- -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
-- allow gzread on concatenated .gz files
-- deflateEnd now returns Z_DATA_ERROR if it was premature
-- deflate is finally (?) fully deterministic (no matches beyond end of input)
-- Document Z_SYNC_FLUSH
-- add uninstall in Makefile
-- Check for __cpluplus in zlib.h
-- Better test in ct_align for partial flush
-- avoid harmless warnings for Borland C++
-- initialize hash_head in deflate.c
-- avoid warning on fdopen (gzio.c) for HP cc -Aa
-- include stdlib.h for STDC compilers
-- include errno.h for Cray
-- ignore error if ranlib doesn't exist
-- call ranlib twice for NeXTSTEP
-- use exec_prefix instead of prefix for libz.a
-- renamed ct_* as _tr_* to avoid conflict with applications
-- clear z->msg in inflateInit2 before any error return
-- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
-- fixed typo in zconf.h (_GNUC__ => __GNUC__)
-- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
-- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
-- in fcalloc, normalize pointer if size > 65520 bytes
-- don't use special fcalloc for 32 bit Borland C++
-- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
-- use Z_BINARY instead of BINARY
-- document that gzclose after gzdopen will close the file
-- allow "a" as mode in gzopen.
-- fix error checking in gzread
-- allow skipping .gz extra-field on pipes
-- added reference to Perl interface in README
-- put the crc table in FAR data (I dislike more and more the medium model :)
-- added get_crc_table
-- added a dimension to all arrays (Borland C can't count).
-- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
-- guard against multiple inclusion of *.h (for precompiled header on Mac)
-- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
-- don't use unsized arrays to avoid silly warnings by Visual C++:
- warning C4746: 'inflate_mask' : unsized array treated as '__far'
- (what's wrong with far data in far model?).
-- define enum out of inflate_blocks_state to allow compilation with C++
-
-Changes in 0.95 (16 Aug 95)
-- fix MSDOS small and medium model (now easier to adapt to any compiler)
-- inlined send_bits
-- fix the final (:-) bug for deflate with flush (output was correct but
- not completely flushed in rare occasions).
-- default window size is same for compression and decompression
- (it's now sufficient to set MAX_WBITS in zconf.h).
-- voidp -> voidpf and voidnp -> voidp (for consistency with other
- typedefs and because voidnp was not near in large model).
-
-Changes in 0.94 (13 Aug 95)
-- support MSDOS medium model
-- fix deflate with flush (could sometimes generate bad output)
-- fix deflateReset (zlib header was incorrectly suppressed)
-- added support for VMS
-- allow a compression level in gzopen()
-- gzflush now calls fflush
-- For deflate with flush, flush even if no more input is provided.
-- rename libgz.a as libz.a
-- avoid complex expression in infcodes.c triggering Turbo C bug
-- work around a problem with gcc on Alpha (in INSERT_STRING)
-- don't use inline functions (problem with some gcc versions)
-- allow renaming of Byte, uInt, etc... with #define.
-- avoid warning about (unused) pointer before start of array in deflate.c
-- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
-- avoid reserved word 'new' in trees.c
-
-Changes in 0.93 (25 June 95)
-- temporarily disable inline functions
-- make deflate deterministic
-- give enough lookahead for PARTIAL_FLUSH
-- Set binary mode for stdin/stdout in minigzip.c for OS/2
-- don't even use signed char in inflate (not portable enough)
-- fix inflate memory leak for segmented architectures
-
-Changes in 0.92 (3 May 95)
-- don't assume that char is signed (problem on SGI)
-- Clear bit buffer when starting a stored block
-- no memcpy on Pyramid
-- suppressed inftest.c
-- optimized fill_window, put longest_match inline for gcc
-- optimized inflate on stored blocks.
-- untabify all sources to simplify patches
-
-Changes in 0.91 (2 May 95)
-- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
-- Document the memory requirements in zconf.h
-- added "make install"
-- fix sync search logic in inflateSync
-- deflate(Z_FULL_FLUSH) now works even if output buffer too short
-- after inflateSync, don't scare people with just "lo world"
-- added support for DJGPP
-
-Changes in 0.9 (1 May 95)
-- don't assume that zalloc clears the allocated memory (the TurboC bug
- was Mark's bug after all :)
-- let again gzread copy uncompressed data unchanged (was working in 0.71)
-- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
-- added a test of inflateSync in example.c
-- moved MAX_WBITS to zconf.h because users might want to change that.
-- document explicitly that zalloc(64K) on MSDOS must return a normalized
- pointer (zero offset)
-- added Makefiles for Microsoft C, Turbo C, Borland C++
-- faster crc32()
-
-Changes in 0.8 (29 April 95)
-- added fast inflate (inffast.c)
-- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
- is incompatible with previous versions of zlib which returned Z_OK.
-- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
- (actually that was not a compiler bug, see 0.81 above)
-- gzread no longer reads one extra byte in certain cases
-- In gzio destroy(), don't reference a freed structure
-- avoid many warnings for MSDOS
-- avoid the ERROR symbol which is used by MS Windows
-
-Changes in 0.71 (14 April 95)
-- Fixed more MSDOS compilation problems :( There is still a bug with
- TurboC large model.
-
-Changes in 0.7 (14 April 95)
-- Added full inflate support.
-- Simplified the crc32() interface. The pre- and post-conditioning
- (one's complement) is now done inside crc32(). WARNING: this is
- incompatible with previous versions; see zlib.h for the new usage.
-
-Changes in 0.61 (12 April 95)
-- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
-
-Changes in 0.6 (11 April 95)
-- added minigzip.c
-- added gzdopen to reopen a file descriptor as gzFile
-- added transparent reading of non-gziped files in gzread.
-- fixed bug in gzread (don't read crc as data)
-- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
-- don't allocate big arrays in the stack (for MSDOS)
-- fix some MSDOS compilation problems
-
-Changes in 0.5:
-- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
- not yet Z_FULL_FLUSH.
-- support decompression but only in a single step (forced Z_FINISH)
-- added opaque object for zalloc and zfree.
-- added deflateReset and inflateReset
-- added a variable zlib_version for consistency checking.
-- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
- Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
-
-Changes in 0.4:
-- avoid "zip" everywhere, use zlib instead of ziplib.
-- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
- if compression method == 8.
-- added adler32 and crc32
-- renamed deflateOptions as deflateInit2, call one or the other but not both
-- added the method parameter for deflateInit2.
-- added inflateInit2
-- simplied considerably deflateInit and inflateInit by not supporting
- user-provided history buffer. This is supported only in deflateInit2
- and inflateInit2.
-
-Changes in 0.3:
-- prefix all macro names with Z_
-- use Z_FINISH instead of deflateEnd to finish compression.
-- added Z_HUFFMAN_ONLY
-- added gzerror()
diff --git a/cpukit/zlib/ChangeLog.zlib b/cpukit/zlib/ChangeLog.zlib
new file mode 100644
index 0000000000..d162e90e78
--- /dev/null
+++ b/cpukit/zlib/ChangeLog.zlib
@@ -0,0 +1,805 @@
+
+ ChangeLog file for zlib
+
+Changes in 1.2.2.2 (30 December 2004)
+- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
+ avoid implicit memcpy calls (portability for no-library compilation)
+- Increase sprintf() buffer size in gzdopen() to allow for large numbers
+- Add INFLATE_STRICT to check distances against zlib header
+- Improve WinCE errno handling and comments [Chang]
+- Remove comment about no gzip header processing in FAQ
+- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
+- Add updated make_vms.com [Coghlan], update README
+- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
+ fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
+- Add FAQ entry and comments in deflate.c on uninitialized memory access
+- Add Solaris 9 make options in configure [Gilbert]
+- Allow strerror() usage in gzio.c for STDC
+- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
+- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
+- Use z_off_t for adler32_combine() and crc32_combine() lengths
+- Make adler32() much faster for small len
+- Use OS_CODE in deflate() default gzip header
+
+Changes in 1.2.2.1 (31 October 2004)
+- Allow inflateSetDictionary() call for raw inflate
+- Fix inflate header crc check bug for file names and comments
+- Add deflateSetHeader() and gz_header structure for custom gzip headers
+- Add inflateGetheader() to retrieve gzip headers
+- Add crc32_combine() and adler32_combine() functions
+- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
+- Use zstreamp consistently in zlib.h (inflate_back functions)
+- Remove GUNZIP condition from definition of inflate_mode in inflate.h
+ and in contrib/inflate86/inffast.S [Truta, Anderson]
+- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
+- Update projects/README.projects and projects/visualc6 [Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
+- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
+- Use a new algorithm for setting strm->data_type in trees.c [Truta]
+- Do not define an exit() prototype in zutil.c unless DEBUG defined
+- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
+- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
+- Fix Darwin build version identification [Peterson]
+
+Changes in 1.2.2 (3 October 2004)
+- Update zlib.h comments on gzip in-memory processing
+- Set adler to 1 in inflateReset() to support Java test suite [Walles]
+- Add contrib/dotzlib [Ravn]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update contrib/minizip [Vollant]
+- Move contrib/visual-basic.txt to old/ [Truta]
+- Fix assembler builds in projects/visualc6/ [Truta]
+
+Changes in 1.2.1.2 (9 September 2004)
+- Update INDEX file
+- Fix trees.c to update strm->data_type (no one ever noticed!)
+- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
+- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
+- Add limited multitasking protection to DYNAMIC_CRC_TABLE
+- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
+- Don't declare strerror() under VMS [Mozilla]
+- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
+- Update contrib/ada [Anisimkov]
+- Update contrib/minizip [Vollant]
+- Fix configure to not hardcode directories for Darwin [Peterson]
+- Fix gzio.c to not return error on empty files [Brown]
+- Fix indentation; update version in contrib/delphi/ZLib.pas and
+ contrib/pascal/zlibpas.pas [Truta]
+- Update mkasm.bat in contrib/masmx86 [Truta]
+- Update contrib/untgz [Truta]
+- Add projects/README.projects [Truta]
+- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
+- Remove an unnecessary assignment to curr in inftrees.c [Truta]
+- Add OS/2 to exe builds in configure [Poltorak]
+- Remove err dummy parameter in zlib.h [Kientzle]
+
+Changes in 1.2.1.1 (9 January 2004)
+- Update email address in README
+- Several FAQ updates
+- Fix a big fat bug in inftrees.c that prevented decoding valid
+ dynamic blocks with only literals and no distance codes --
+ Thanks to "Hot Emu" for the bug report and sample file
+- Add a note to puff.c on no distance codes case.
+
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+ - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Update win32/DLL_FAQ.txt [Truta]
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and replace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+ - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+ the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+ [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+ and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+ [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+ [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+ INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+ [Truta]
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+ of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+ parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+ to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+ 16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+ Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+ zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+
+Changes in 1.2.0.4 (10 August 2003)
+- Minor FAQ updates
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+- Minor FAQ updates
+
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+ library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+ special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+ - Report 0 for huffman and rle strategies and for level == 0 or 1
+ - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+ - When Z_RLE requested, restrict matches to distance one
+ - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+ - Refine detection of Turbo C need for dummy returns
+ - Refine ZLIB_DLL compilation
+ - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enchance comments in zlib.h on what happens if gzprintf() tries to
+ write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+ - About 20% faster
+ - Does not allocate 32K window unless and until needed
+ - Automatically detects and decompresses gzip streams
+ - Raw inflate no longer needs an extra dummy byte at end
+ - Added inflateBack functions using a callback interface--even faster
+ than inflate, useful for file utilities (gzip, zip)
+ - Added inflateCopy() function to record state for random access on
+ externally generated deflate streams (e.g. in gzip files)
+ - More readable code (I hope)
+- New and improved crc32()
+ - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+ and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+ return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+ is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+ - Document raw deflate and inflate
+ - Update RFCs URL
+ - Point out that zlib and gzip formats are different
+ - Note that Z_BUF_ERROR is not fatal
+ - Document string limit for gzprintf() and possible buffer overflow
+ - Note requirement on avail_out when flushing
+ - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions.
+ This creates a security problem described in
+ http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+ less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+ of 256 bytes. (A complete fix will be available in 1.1.5).
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+ occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+ (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean" (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+ . zutil.c, zutil.h: added "const" for zmem*
+ . Make_vms.com: fixed some typos
+ . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+ . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+ . msdos/Makefile.*: use model-dependent name for the built zlib library
+ . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+ new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+ See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+ completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+ (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+ compression ratio on some files. This also allows inlining _tr_tally for
+ matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+ on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+ the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+ them at run time (thanks to Ken Raeburn for this suggestion). To create
+ trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+ gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occuring only with compression level 0 (thanks to
+ Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+ (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+ (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+ inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+ contrib/asm386/ by Gilles Vollant <info@winimage.com>
+ 386 asm code replacing longest_match().
+ contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+ A C++ I/O streams interface to the zlib gz* functions
+ contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
+ Another C++ I/O streams interface
+ contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+ A very simple tar.gz file extractor using zlib
+ contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+ How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+ level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+ (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+ bit, so the decompressor could decompress all the correct data but went
+ on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+ small and medium models; this makes the library incompatible with previous
+ versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+ avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+ Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+ and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+ -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+ warning C4746: 'inflate_mask' : unsized array treated as '__far'
+ (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+ not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+ (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+ typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+ was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+ pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+ is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+ (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+ TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+ (one's complement) is now done inside crc32(). WARNING: this is
+ incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+ not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+ Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+ if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+ user-provided history buffer. This is supported only in deflateInit2
+ and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
diff --git a/cpukit/zlib/Makefile b/cpukit/zlib/Makefile
deleted file mode 100644
index 29f53de5a7..0000000000
--- a/cpukit/zlib/Makefile
+++ /dev/null
@@ -1,154 +0,0 @@
-# Makefile for zlib
-# Copyright (C) 1995-2003 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile and test, type:
-# ./configure; make test
-# The call of configure is optional if you don't have special requirements
-# If you wish to build zlib as a shared library, use: ./configure -s
-
-# To use the asm code, type:
-# cp contrib/asm?86/match.S ./match.S
-# make LOC=-DASMV OBJA=match.o
-
-# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
-# make install
-# To install in $HOME instead of /usr/local, use:
-# make install prefix=$HOME
-
-CC=cc
-
-CFLAGS=-O
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-g -DDEBUG
-#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
-# -Wstrict-prototypes -Wmissing-prototypes
-
-LDFLAGS=libz.a
-LDSHARED=$(CC)
-CPP=$(CC) -E
-
-LIBS=libz.a
-SHAREDLIB=libz.so
-SHAREDLIBV=libz.so.1.2.2.2
-SHAREDLIBM=libz.so.1
-
-AR=ar rc
-RANLIB=ranlib
-TAR=tar
-SHELL=/bin/sh
-EXE=
-
-prefix = /usr/local
-exec_prefix = ${prefix}
-libdir = ${exec_prefix}/lib
-includedir = ${prefix}/include
-mandir = ${prefix}/share/man
-man3dir = ${mandir}/man3
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infback.o inftrees.o inffast.o
-
-OBJA =
-# to use the asm code: make OBJA=match.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example$(EXE) minigzip$(EXE)
-
-check: test
-test: all
- @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
- echo hello world | ./minigzip | ./minigzip -d || \
- echo ' *** minigzip test FAILED ***' ; \
- if ./example; then \
- echo ' *** zlib test OK ***'; \
- else \
- echo ' *** zlib test FAILED ***'; \
- fi
-
-libz.a: $(OBJS) $(OBJA)
- $(AR) $@ $(OBJS) $(OBJA)
- -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
-
-match.o: match.S
- $(CPP) match.S > _match.s
- $(CC) -c _match.s
- mv _match.o match.o
- rm -f _match.s
-
-$(SHAREDLIBV): $(OBJS)
- $(LDSHARED) -o $@ $(OBJS)
- rm -f $(SHAREDLIB) $(SHAREDLIBM)
- ln -s $@ $(SHAREDLIB)
- ln -s $@ $(SHAREDLIBM)
-
-example$(EXE): example.o $(LIBS)
- $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
-
-minigzip$(EXE): minigzip.o $(LIBS)
- $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
-
-install: $(LIBS)
- -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi
- -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi
- -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi
- -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi
- cp zlib.h zconf.h $(includedir)
- chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h
- cp $(LIBS) $(libdir)
- cd $(libdir); chmod 755 $(LIBS)
- -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
- cd $(libdir); if test -f $(SHAREDLIBV); then \
- rm -f $(SHAREDLIB) $(SHAREDLIBM); \
- ln -s $(SHAREDLIBV) $(SHAREDLIB); \
- ln -s $(SHAREDLIBV) $(SHAREDLIBM); \
- (ldconfig || true) >/dev/null 2>&1; \
- fi
- cp zlib.3 $(man3dir)
- chmod 644 $(man3dir)/zlib.3
-# The ranlib in install is needed on NeXTSTEP which checks file times
-# ldconfig is for Linux
-
-uninstall:
- cd $(includedir); \
- cd $(libdir); rm -f libz.a; \
- if test -f $(SHAREDLIBV); then \
- rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
- fi
- cd $(man3dir); rm -f zlib.3
-
-mostlyclean: clean
-clean:
- rm -f *.o *~ example$(EXE) minigzip$(EXE) \
- libz.* foo.gz so_locations \
- _match.s maketree contrib/infback9/*.o
-
-maintainer-clean: distclean
-distclean: clean
- cp -p Makefile.in Makefile
- cp -p zconf.in.h zconf.h
- rm -f .DS_Store
-
-tags:
- etags *.[ch]
-
-depend:
- makedepend -- $(CFLAGS) -- *.[ch]
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-adler32.o: zlib.h zconf.h
-compress.o: zlib.h zconf.h
-crc32.o: crc32.h zlib.h zconf.h
-deflate.o: deflate.h zutil.h zlib.h zconf.h
-example.o: zlib.h zconf.h
-gzio.o: zutil.h zlib.h zconf.h
-inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-inftrees.o: zutil.h zlib.h zconf.h inftrees.h
-minigzip.o: zlib.h zconf.h
-trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
-uncompr.o: zlib.h zconf.h
-zutil.o: zutil.h zlib.h zconf.h
diff --git a/cpukit/zlib/Makefile.am b/cpukit/zlib/Makefile.am
new file mode 100644
index 0000000000..a36d96c42a
--- /dev/null
+++ b/cpukit/zlib/Makefile.am
@@ -0,0 +1,28 @@
+#
+# $Id$
+#
+
+include $(top_srcdir)/automake/compile.am
+
+project_lib_LIBRARIES = libz.a
+
+libz_a_SOURCES = adler32.c
+libz_a_SOURCES += compress.c
+libz_a_SOURCES += crc32.c crc32.h
+libz_a_SOURCES += deflate.c deflate.h
+libz_a_SOURCES += gzio.c
+libz_a_SOURCES += infback.c
+libz_a_SOURCES += inffast.c inffast.h
+libz_a_SOURCES += inffixed.h
+libz_a_SOURCES += inflate.c inflate.h
+libz_a_SOURCES += inftrees.c inftrees.h
+libz_a_SOURCES += trees.c trees.h
+libz_a_SOURCES += uncompr.c
+libz_a_SOURCES += zconf.h
+libz_a_SOURCES += zlib.h
+libz_a_SOURCES += zutil.c zutil.h
+
+include_HEADERS = zlib.h zconf.h
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/zlib/Makefile.in b/cpukit/zlib/Makefile.in
deleted file mode 100644
index 29f53de5a7..0000000000
--- a/cpukit/zlib/Makefile.in
+++ /dev/null
@@ -1,154 +0,0 @@
-# Makefile for zlib
-# Copyright (C) 1995-2003 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile and test, type:
-# ./configure; make test
-# The call of configure is optional if you don't have special requirements
-# If you wish to build zlib as a shared library, use: ./configure -s
-
-# To use the asm code, type:
-# cp contrib/asm?86/match.S ./match.S
-# make LOC=-DASMV OBJA=match.o
-
-# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
-# make install
-# To install in $HOME instead of /usr/local, use:
-# make install prefix=$HOME
-
-CC=cc
-
-CFLAGS=-O
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-g -DDEBUG
-#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
-# -Wstrict-prototypes -Wmissing-prototypes
-
-LDFLAGS=libz.a
-LDSHARED=$(CC)
-CPP=$(CC) -E
-
-LIBS=libz.a
-SHAREDLIB=libz.so
-SHAREDLIBV=libz.so.1.2.2.2
-SHAREDLIBM=libz.so.1
-
-AR=ar rc
-RANLIB=ranlib
-TAR=tar
-SHELL=/bin/sh
-EXE=
-
-prefix = /usr/local
-exec_prefix = ${prefix}
-libdir = ${exec_prefix}/lib
-includedir = ${prefix}/include
-mandir = ${prefix}/share/man
-man3dir = ${mandir}/man3
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infback.o inftrees.o inffast.o
-
-OBJA =
-# to use the asm code: make OBJA=match.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example$(EXE) minigzip$(EXE)
-
-check: test
-test: all
- @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
- echo hello world | ./minigzip | ./minigzip -d || \
- echo ' *** minigzip test FAILED ***' ; \
- if ./example; then \
- echo ' *** zlib test OK ***'; \
- else \
- echo ' *** zlib test FAILED ***'; \
- fi
-
-libz.a: $(OBJS) $(OBJA)
- $(AR) $@ $(OBJS) $(OBJA)
- -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
-
-match.o: match.S
- $(CPP) match.S > _match.s
- $(CC) -c _match.s
- mv _match.o match.o
- rm -f _match.s
-
-$(SHAREDLIBV): $(OBJS)
- $(LDSHARED) -o $@ $(OBJS)
- rm -f $(SHAREDLIB) $(SHAREDLIBM)
- ln -s $@ $(SHAREDLIB)
- ln -s $@ $(SHAREDLIBM)
-
-example$(EXE): example.o $(LIBS)
- $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
-
-minigzip$(EXE): minigzip.o $(LIBS)
- $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
-
-install: $(LIBS)
- -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi
- -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi
- -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi
- -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi
- cp zlib.h zconf.h $(includedir)
- chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h
- cp $(LIBS) $(libdir)
- cd $(libdir); chmod 755 $(LIBS)
- -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
- cd $(libdir); if test -f $(SHAREDLIBV); then \
- rm -f $(SHAREDLIB) $(SHAREDLIBM); \
- ln -s $(SHAREDLIBV) $(SHAREDLIB); \
- ln -s $(SHAREDLIBV) $(SHAREDLIBM); \
- (ldconfig || true) >/dev/null 2>&1; \
- fi
- cp zlib.3 $(man3dir)
- chmod 644 $(man3dir)/zlib.3
-# The ranlib in install is needed on NeXTSTEP which checks file times
-# ldconfig is for Linux
-
-uninstall:
- cd $(includedir); \
- cd $(libdir); rm -f libz.a; \
- if test -f $(SHAREDLIBV); then \
- rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
- fi
- cd $(man3dir); rm -f zlib.3
-
-mostlyclean: clean
-clean:
- rm -f *.o *~ example$(EXE) minigzip$(EXE) \
- libz.* foo.gz so_locations \
- _match.s maketree contrib/infback9/*.o
-
-maintainer-clean: distclean
-distclean: clean
- cp -p Makefile.in Makefile
- cp -p zconf.in.h zconf.h
- rm -f .DS_Store
-
-tags:
- etags *.[ch]
-
-depend:
- makedepend -- $(CFLAGS) -- *.[ch]
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-adler32.o: zlib.h zconf.h
-compress.o: zlib.h zconf.h
-crc32.o: crc32.h zlib.h zconf.h
-deflate.o: deflate.h zutil.h zlib.h zconf.h
-example.o: zlib.h zconf.h
-gzio.o: zutil.h zlib.h zconf.h
-inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-inftrees.o: zutil.h zlib.h zconf.h inftrees.h
-minigzip.o: zlib.h zconf.h
-trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
-uncompr.o: zlib.h zconf.h
-zutil.o: zutil.h zlib.h zconf.h
diff --git a/cpukit/zlib/adler32.c b/cpukit/zlib/adler32.c
index 007ba26277..b2fbcee282 100644
--- a/cpukit/zlib/adler32.c
+++ b/cpukit/zlib/adler32.c
@@ -3,7 +3,7 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id$ */
+/* $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h"
diff --git a/cpukit/zlib/amiga/Makefile.pup b/cpukit/zlib/amiga/Makefile.pup
deleted file mode 100644
index 3f7e15537f..0000000000
--- a/cpukit/zlib/amiga/Makefile.pup
+++ /dev/null
@@ -1,66 +0,0 @@
-# Amiga powerUP (TM) Makefile
-# makefile for libpng and SAS C V6.58/7.00 PPC compiler
-# Copyright (C) 1998 by Andreas R. Kleinert
-
-LIBNAME = libzip.a
-
-CC = scppc
-CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \
- OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER
-AR = ppc-amigaos-ar cr
-RANLIB = ppc-amigaos-ranlib
-LD = ppc-amigaos-ld -r
-LDFLAGS = -o
-LDLIBS = LIB:scppc.a LIB:end.o
-RM = delete quiet
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infback.o inftrees.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example minigzip
-
-check: test
-test: all
- example
- echo hello world | minigzip | minigzip -d
-
-$(LIBNAME): $(OBJS)
- $(AR) $@ $(OBJS)
- -$(RANLIB) $@
-
-example: example.o $(LIBNAME)
- $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
-
-minigzip: minigzip.o $(LIBNAME)
- $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
-
-mostlyclean: clean
-clean:
- $(RM) *.o example minigzip $(LIBNAME) foo.gz
-
-zip:
- zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \
- descrip.mms *.[ch]
-
-tgz:
- cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
- zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-adler32.o: zlib.h zconf.h
-compress.o: zlib.h zconf.h
-crc32.o: crc32.h zlib.h zconf.h
-deflate.o: deflate.h zutil.h zlib.h zconf.h
-example.o: zlib.h zconf.h
-gzio.o: zutil.h zlib.h zconf.h
-inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-inftrees.o: zutil.h zlib.h zconf.h inftrees.h
-minigzip.o: zlib.h zconf.h
-trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
-uncompr.o: zlib.h zconf.h
-zutil.o: zutil.h zlib.h zconf.h
diff --git a/cpukit/zlib/amiga/Makefile.sas b/cpukit/zlib/amiga/Makefile.sas
deleted file mode 100644
index d6842b89c3..0000000000
--- a/cpukit/zlib/amiga/Makefile.sas
+++ /dev/null
@@ -1,65 +0,0 @@
-# SMakefile for zlib
-# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly
-# Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>
-# Amiga, SAS/C 6.56 & Smake
-
-CC=sc
-CFLAGS=OPT
-#CFLAGS=OPT CPU=68030
-#CFLAGS=DEBUG=LINE
-LDFLAGS=LIB z.lib
-
-SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \
- NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \
- DEF=POSTINC
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infback.o inftrees.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: SCOPTIONS example minigzip
-
-check: test
-test: all
- example
- echo hello world | minigzip | minigzip -d
-
-install: z.lib
- copy clone zlib.h zconf.h INCLUDE:
- copy clone z.lib LIB:
-
-z.lib: $(OBJS)
- oml z.lib r $(OBJS)
-
-example: example.o z.lib
- $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)
-
-minigzip: minigzip.o z.lib
- $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)
-
-mostlyclean: clean
-clean:
- -delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS
-
-SCOPTIONS: Makefile.sas
- copy to $@ <from <
-$(SCOPTIONS)
-<
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-adler32.o: zlib.h zconf.h
-compress.o: zlib.h zconf.h
-crc32.o: crc32.h zlib.h zconf.h
-deflate.o: deflate.h zutil.h zlib.h zconf.h
-example.o: zlib.h zconf.h
-gzio.o: zutil.h zlib.h zconf.h
-inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-inftrees.o: zutil.h zlib.h zconf.h inftrees.h
-minigzip.o: zlib.h zconf.h
-trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
-uncompr.o: zlib.h zconf.h
-zutil.o: zutil.h zlib.h zconf.h
diff --git a/cpukit/zlib/as400/bndsrc b/cpukit/zlib/as400/bndsrc
deleted file mode 100644
index 9cf94bb356..0000000000
--- a/cpukit/zlib/as400/bndsrc
+++ /dev/null
@@ -1,132 +0,0 @@
-STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB')
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/* Version 1.1.3 entry points. */
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-
-/********************************************************************/
-/* *MODULE ADLER32 ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("adler32")
-
-/********************************************************************/
-/* *MODULE COMPRESS ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("compress")
- EXPORT SYMBOL("compress2")
-
-/********************************************************************/
-/* *MODULE CRC32 ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("crc32")
- EXPORT SYMBOL("get_crc_table")
-
-/********************************************************************/
-/* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("deflate")
- EXPORT SYMBOL("deflateEnd")
- EXPORT SYMBOL("deflateSetDictionary")
- EXPORT SYMBOL("deflateCopy")
- EXPORT SYMBOL("deflateReset")
- EXPORT SYMBOL("deflateParams")
- EXPORT SYMBOL("deflatePrime")
- EXPORT SYMBOL("deflateInit_")
- EXPORT SYMBOL("deflateInit2_")
-
-/********************************************************************/
-/* *MODULE GZIO ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("gzopen")
- EXPORT SYMBOL("gzdopen")
- EXPORT SYMBOL("gzsetparams")
- EXPORT SYMBOL("gzread")
- EXPORT SYMBOL("gzwrite")
- EXPORT SYMBOL("gzprintf")
- EXPORT SYMBOL("gzputs")
- EXPORT SYMBOL("gzgets")
- EXPORT SYMBOL("gzputc")
- EXPORT SYMBOL("gzgetc")
- EXPORT SYMBOL("gzflush")
- EXPORT SYMBOL("gzseek")
- EXPORT SYMBOL("gzrewind")
- EXPORT SYMBOL("gztell")
- EXPORT SYMBOL("gzeof")
- EXPORT SYMBOL("gzclose")
- EXPORT SYMBOL("gzerror")
-
-/********************************************************************/
-/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("inflate")
- EXPORT SYMBOL("inflateEnd")
- EXPORT SYMBOL("inflateSetDictionary")
- EXPORT SYMBOL("inflateSync")
- EXPORT SYMBOL("inflateReset")
- EXPORT SYMBOL("inflateInit_")
- EXPORT SYMBOL("inflateInit2_")
- EXPORT SYMBOL("inflateSyncPoint")
-
-/********************************************************************/
-/* *MODULE UNCOMPR ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("uncompress")
-
-/********************************************************************/
-/* *MODULE ZUTIL ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("zlibVersion")
- EXPORT SYMBOL("zError")
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/* Version 1.2.1 additional entry points. */
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-
-/********************************************************************/
-/* *MODULE COMPRESS ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("compressBound")
-
-/********************************************************************/
-/* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("deflateBound")
-
-/********************************************************************/
-/* *MODULE GZIO ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("gzungetc")
- EXPORT SYMBOL("gzclearerr")
-
-/********************************************************************/
-/* *MODULE INFBACK ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("inflateBack")
- EXPORT SYMBOL("inflateBackEnd")
- EXPORT SYMBOL("inflateBackInit_")
-
-/********************************************************************/
-/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("inflateCopy")
-
-/********************************************************************/
-/* *MODULE ZUTIL ZLIB 01/02/01 00:15:09 */
-/********************************************************************/
-
- EXPORT SYMBOL("zlibCompileFlags")
-
-ENDPGMEXP
diff --git a/cpukit/zlib/as400/compile.clp b/cpukit/zlib/as400/compile.clp
deleted file mode 100644
index 3c47bb4b22..0000000000
--- a/cpukit/zlib/as400/compile.clp
+++ /dev/null
@@ -1,123 +0,0 @@
-/******************************************************************************/
-/* */
-/* ZLIB */
-/* */
-/* Compile sources into modules and link them into a service program. */
-/* */
-/******************************************************************************/
-
- PGM
-
-/* Configuration adjustable parameters. */
-
- DCL VAR(&SRCLIB) TYPE(*CHAR) LEN(10) +
- VALUE('ZLIB') /* Source library. */
- DCL VAR(&SRCFILE) TYPE(*CHAR) LEN(10) +
- VALUE('SOURCES') /* Source member file. */
- DCL VAR(&CTLFILE) TYPE(*CHAR) LEN(10) +
- VALUE('TOOLS') /* Control member file. */
-
- DCL VAR(&MODLIB) TYPE(*CHAR) LEN(10) +
- VALUE('ZLIB') /* Module library. */
-
- DCL VAR(&SRVLIB) TYPE(*CHAR) LEN(10) +
- VALUE('LGPL') /* Service program library. */
-
- DCL VAR(&CFLAGS) TYPE(*CHAR) +
- VALUE('OPTIMIZE(40)') /* Compile options. */
-
-
-/* Working storage. */
-
- DCL VAR(&CMDLEN) TYPE(*DEC) LEN(15 5) VALUE(300) /* Command length. */
- DCL VAR(&CMD) TYPE(*CHAR) LEN(512)
-
-
-/* Compile sources into modules. */
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/ADLER32) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/COMPRESS) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/CRC32) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/DEFLATE) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/GZIO) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/INFBACK) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/INFFAST) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/INFLATE) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/INFTREES) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/TREES) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/UNCOMPR) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/ZUTIL) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
-
-/* Link modules into a service program. */
-
- CRTSRVPGM SRVPGM(&SRVLIB/ZLIB) +
- MODULE(&MODLIB/ADLER32 &MODLIB/COMPRESS +
- &MODLIB/CRC32 &MODLIB/DEFLATE +
- &MODLIB/GZIO &MODLIB/INFBACK +
- &MODLIB/INFFAST &MODLIB/INFLATE +
- &MODLIB/INFTREES &MODLIB/TREES +
- &MODLIB/UNCOMPR &MODLIB/ZUTIL) +
- SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) +
- TEXT('ZLIB 1.2.2') TGTRLS(V4R4M0)
-
- ENDPGM
diff --git a/cpukit/zlib/as400/readme.txt b/cpukit/zlib/as400/readme.txt
deleted file mode 100644
index 27ca6763bf..0000000000
--- a/cpukit/zlib/as400/readme.txt
+++ /dev/null
@@ -1,111 +0,0 @@
- ZLIB version 1.2.2 for AS400 installation instructions
-
-I) From an AS400 *SAVF file:
-
-1) Unpacking archive to an AS400 save file
-
-On the AS400:
-
-_ Create the ZLIB AS400 library:
-
- CRTLIB LIB(ZLIB) TYPE(PROD) TEXT('ZLIB compression API library')
-
-_ Create a work save file, for example:
-
- CRTSAVF FILE(ZLIB/ZLIBSAVF)
-
-On a PC connected to the target AS400:
-
-_ Unpack the save file image to a PC file "ZLIBSAVF"
-_ Upload this file into the save file on the AS400, for example
- using ftp in BINARY mode.
-
-
-2) Populating the ZLIB AS400 source library
-
-On the AS400:
-
-_ Extract the saved objects into the ZLIB AS400 library using:
-
-RSTOBJ OBJ(*ALL) SAVLIB(ZLIB) DEV(*SAVF) SAVF(ZLIB/ZLIBSAVF) RSTLIB(ZLIB)
-
-
-3) Customize installation:
-
-_ Edit CL member ZLIB/TOOLS(COMPILE) and change parameters if needed,
- according to the comments.
-
-_ Compile this member with:
-
- CRTCLPGM PGM(ZLIB/COMPILE) SRCFILE(ZLIB/TOOLS) SRCMBR(COMPILE)
-
-
-4) Compile and generate the service program:
-
-_ This can now be done by executing:
-
- CALL PGM(ZLIB/COMPILE)
-
-
-
-II) From the original source distribution:
-
-1) On the AS400, create the source library:
-
- CRTLIB LIB(ZLIB) TYPE(PROD) TEXT('ZLIB compression API library')
-
-2) Create the source files:
-
- CRTSRCPF FILE(ZLIB/SOURCES) RCDLEN(112) TEXT('ZLIB library modules')
- CRTSRCPF FILE(ZLIB/H) RCDLEN(112) TEXT('ZLIB library includes')
- CRTSRCPF FILE(ZLIB/TOOLS) RCDLEN(112) TEXT('ZLIB library control utilities')
-
-3) From the machine hosting the distribution files, upload them (with
- FTP in text mode, for example) according to the following table:
-
- Original AS400 AS400 AS400 AS400
- file file member type description
- SOURCES Original ZLIB C subprogram sources
- adler32.c ADLER32 C ZLIB - Compute the Adler-32 checksum of a dta strm
- compress.c COMPRESS C ZLIB - Compress a memory buffer
- crc32.c CRC32 C ZLIB - Compute the CRC-32 of a data stream
- deflate.c DEFLATE C ZLIB - Compress data using the deflation algorithm
- gzio.c GZIO C ZLIB - IO on .gz files
- infback.c INFBACK C ZLIB - Inflate using a callback interface
- inffast.c INFFAST C ZLIB - Fast proc. literals & length/distance pairs
- inflate.c INFLATE C ZLIB - Interface to inflate modules
- inftrees.c INFTREES C ZLIB - Generate Huffman trees for efficient decode
- trees.c TREES C ZLIB - Output deflated data using Huffman coding
- uncompr.c UNCOMPR C ZLIB - Decompress a memory buffer
- zutil.c ZUTIL C ZLIB - Target dependent utility functions
- H Original ZLIB C and ILE/RPG include files
- crc32.h CRC32 C ZLIB - CRC32 tables
- deflate.h DEFLATE C ZLIB - Internal compression state
- inffast.h INFFAST C ZLIB - Header to use inffast.c
- inffixed.h INFFIXED C ZLIB - Table for decoding fixed codes
- inflate.h INFLATE C ZLIB - Internal inflate state definitions
- inftrees.h INFTREES C ZLIB - Header to use inftrees.c
- trees.h TREES C ZLIB - Created automatically with -DGEN_TREES_H
- zconf.h ZCONF C ZLIB - Compression library configuration
- zlib.h ZLIB C ZLIB - Compression library C user interface
- as400/zlib.inc ZLIB.INC RPGLE ZLIB - Compression library ILE RPG user interface
- zutil.h ZUTIL C ZLIB - Internal interface and configuration
- TOOLS Building source software & AS/400 README
- as400/bndsrc BNDSRC Entry point exportation list
- as400/compile.clp COMPILE CLP Compile sources & generate service program
- as400/readme.txt README TXT Installation instructions
-
-4) Continue as in I)3).
-
-
-
-
-Notes: For AS400 ILE RPG programmers, a /copy member defining the ZLIB
- API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC).
- Please read comments in this member for more information.
-
- Remember that most foreign textual data are ASCII coded: this
- implementation does not handle conversion from/to ASCII, so
- text data code conversions must be done explicitely.
-
- Always open zipped files in binary mode.
diff --git a/cpukit/zlib/as400/zlib.inc b/cpukit/zlib/as400/zlib.inc
deleted file mode 100644
index 04c33090b5..0000000000
--- a/cpukit/zlib/as400/zlib.inc
+++ /dev/null
@@ -1,327 +0,0 @@
- * ZLIB.INC - Interface to the general purpose compression library
- *
- * ILE RPG400 version by Patrick Monnerat, DATASPHERE.
- * Version 1.2.2.2
- *
- *
- * WARNING:
- * Procedures inflateInit(), inflateInit2(), deflateInit(),
- * deflateInit2() and inflateBackInit() need to be called with
- * two additional arguments:
- * the package version string and the stream control structure.
- * size. This is needed because RPG lacks some macro feature.
- * Call these procedures as:
- * inflateInit(...: ZLIB_VERSION: %size(z_stream))
- *
- /if not defined(ZLIB_H_)
- /define ZLIB_H_
- *
- **************************************************************************
- * Constants
- **************************************************************************
- *
- D ZLIB_VERSION C '1.2.2.2' Header's version
- D ZLIB_VERNUM C X'1222'
- *
- D Z_NO_FLUSH C 0
- D Z_SYNC_FLUSH C 2
- D Z_FULL_FLUSH C 3
- D Z_FINISH C 4
- D Z_BLOCK C 5
- *
- D Z_OK C 0
- D Z_STREAM_END C 1
- D Z_NEED_DICT C 2
- D Z_ERRNO C -1
- D Z_STREAM_ERROR C -2
- D Z_DATA_ERROR C -3
- D Z_MEM_ERROR C -4
- D Z_BUF_ERROR C -5
- DZ_VERSION_ERROR C -6
- *
- D Z_NO_COMPRESSION...
- D C 0
- D Z_BEST_SPEED C 1
- D Z_BEST_COMPRESSION...
- D C 9
- D Z_DEFAULT_COMPRESSION...
- D C -1
- *
- D Z_FILTERED C 1
- D Z_HUFFMAN_ONLY C 2
- D Z_RLE C 3
- D Z_DEFAULT_STRATEGY...
- D C 0
- *
- D Z_BINARY C 0
- D Z_ASCII C 1
- D Z_UNKNOWN C 2
- *
- D Z_DEFLATED C 8
- *
- D Z_NULL C 0
- *
- **************************************************************************
- * Types
- **************************************************************************
- *
- D z_streamp S * Stream struct ptr
- D gzFile S * File pointer
- D z_off_t S 10i 0 Stream offsets
- *
- **************************************************************************
- * Structures
- **************************************************************************
- *
- * The GZIP encode/decode stream support structure.
- *
- D z_stream DS align based(z_streamp)
- D zs_next_in * Next input byte
- D zs_avail_in 10U 0 Byte cnt at next_in
- D zs_total_in 10U 0 Total bytes read
- D zs_next_out * Output buffer ptr
- D zs_avail_out 10U 0 Room left @ next_out
- D zs_total_out 10U 0 Total bytes written
- D zs_msg * Last errmsg or null
- D zs_state * Internal state
- D zs_zalloc * procptr Int. state allocator
- D zs_free * procptr Int. state dealloc.
- D zs_opaque * Private alloc. data
- D zs_data_type 10i 0 ASC/BIN best guess
- D zs_adler 10u 0 Uncompr. adler32 val
- D 10U 0 Reserved
- D 10U 0 Ptr. alignment
- *
- **************************************************************************
- * Utility function prototypes
- **************************************************************************
- *
- D compress PR 10I 0 extproc('compress')
- D dest 32767 options(*varsize) Destination buffer
- D destLen 10U 0 Destination length
- D source 32767 const options(*varsize) Source buffer
- D sourceLen 10u 0 value Source length
- *
- D compress2 PR 10I 0 extproc('compress2')
- D dest 32767 options(*varsize) Destination buffer
- D destLen 10U 0 Destination length
- D source 32767 const options(*varsize) Source buffer
- D sourceLen 10U 0 value Source length
- D level 10I 0 value Compression level
- *
- D compressBound PR 10U 0 extproc('compressBound')
- D sourceLen 10U 0 value
- *
- D uncompress PR 10I 0 extproc('uncompress')
- D dest 32767 options(*varsize) Destination buffer
- D destLen 10U 0 Destination length
- D source 32767 const options(*varsize) Source buffer
- D sourceLen 10U 0 value Source length
- *
- D gzopen PR extproc('gzopen')
- D like(gzFile)
- D path * value options(*string) File pathname
- D mode * value options(*string) Open mode
- *
- D gzdopen PR extproc('gzdopen')
- D like(gzFile)
- D fd 10i 0 value File descriptor
- D mode * value options(*string) Open mode
- *
- D gzsetparams PR 10I 0 extproc('gzsetparams')
- D file value like(gzFile) File pointer
- D level 10I 0 value
- D strategy 10i 0 value
- *
- D gzread PR 10I 0 extproc('gzread')
- D file value like(gzFile) File pointer
- D buf 32767 options(*varsize) Buffer
- D len 10u 0 value Buffer length
- *
- D gzwrite PR 10I 0 extproc('gzwrite')
- D file value like(gzFile) File pointer
- D buf 32767 const options(*varsize) Buffer
- D len 10u 0 value Buffer length
- *
- D gzputs PR 10I 0 extproc('gzputs')
- D file value like(gzFile) File pointer
- D s * value options(*string) String to output
- *
- D gzgets PR * extproc('gzgets')
- D file value like(gzFile) File pointer
- D buf 32767 options(*varsize) Read buffer
- D len 10i 0 value Buffer length
- *
- D gzflush PR 10i 0 extproc('gzflush')
- D file value like(gzFile) File pointer
- D flush 10I 0 value Type of flush
- *
- D gzseek PR extproc('gzseek')
- D like(z_off_t)
- D file value like(gzFile) File pointer
- D offset value like(z_off_t) Offset
- D whence 10i 0 value Origin
- *
- D gzrewind PR 10i 0 extproc('gzrewind')
- D file value like(gzFile) File pointer
- *
- D gztell PR extproc('gztell')
- D like(z_off_t)
- D file value like(gzFile) File pointer
- *
- D gzeof PR 10i 0 extproc('gzeof')
- D file value like(gzFile) File pointer
- *
- D gzclose PR 10i 0 extproc('gzclose')
- D file value like(gzFile) File pointer
- *
- D gzerror PR * extproc('gzerror') Error string
- D file value like(gzFile) File pointer
- D errnum 10I 0 Error code
- *
- D gzclearerr PR extproc('gzclearerr')
- D file value like(gzFile) File pointer
- *
- **************************************************************************
- * Basic function prototypes
- **************************************************************************
- *
- D zlibVersion PR * extproc('zlibVersion') Version string
- *
- D deflateInit PR 10I 0 extproc('deflateInit_') Init. compression
- D strm like(z_stream) Compression stream
- D level 10I 0 value Compression level
- D version * value options(*string) Version string
- D stream_size 10i 0 value Stream struct. size
- *
- D deflate PR 10I 0 extproc('deflate') Compress data
- D strm like(z_stream) Compression stream
- D flush 10I 0 value Flush type required
- *
- D deflateEnd PR 10I 0 extproc('deflateEnd') Termin. compression
- D strm like(z_stream) Compression stream
- *
- D inflateInit PR 10I 0 extproc('inflateInit_') Init. expansion
- D strm like(z_stream) Expansion stream
- D version * value options(*string) Version string
- D stream_size 10i 0 value Stream struct. size
- *
- D inflate PR 10I 0 extproc('inflate') Expand data
- D strm like(z_stream) Expansion stream
- D flush 10I 0 value Flush type required
- *
- D inflateEnd PR 10I 0 extproc('inflateEnd') Termin. expansion
- D strm like(z_stream) Expansion stream
- *
- **************************************************************************
- * Advanced function prototypes
- **************************************************************************
- *
- D deflateInit2 PR 10I 0 extproc('deflateInit2_') Init. compression
- D strm like(z_stream) Compression stream
- D level 10I 0 value Compression level
- D method 10I 0 value Compression method
- D windowBits 10I 0 value log2(window size)
- D memLevel 10I 0 value Mem/cmpress tradeoff
- D strategy 10I 0 value Compression stategy
- D version * value options(*string) Version string
- D stream_size 10i 0 value Stream struct. size
- *
- D deflateSetDictionary...
- D PR 10I 0 extproc('deflateSetDictionary') Init. dictionary
- D strm like(z_stream) Compression stream
- D dictionary 32767 const options(*varsize) Dictionary bytes
- D dictLength 10U 0 value Dictionary length
- *
- D deflateCopy PR 10I 0 extproc('deflateCopy') Compress strm 2 strm
- D dest like(z_stream) Destination stream
- D source like(z_stream) Source stream
- *
- D deflateReset PR 10I 0 extproc('deflateReset') End and init. stream
- D strm like(z_stream) Compression stream
- *
- D deflateParams PR 10I 0 extproc('deflateParams') Change level & strat
- D strm like(z_stream) Compression stream
- D level 10I 0 value Compression level
- D strategy 10I 0 value Compression stategy
- *
- D deflateBound PR 10U 0 extproc('deflateBound') Change level & strat
- D strm like(z_stream) Compression stream
- D sourcelen 10U 0 value Compression level
- *
- D deflatePrime PR 10I 0 extproc('deflatePrime') Change level & strat
- D strm like(z_stream) Compression stream
- D bits 10I 0 value Number of bits to insert
- D value 10I 0 value Bits to insert
- *
- D inflateInit2 PR 10I 0 extproc('inflateInit2_') Init. expansion
- D strm like(z_stream) Expansion stream
- D windowBits 10I 0 value log2(window size)
- D version * value options(*string) Version string
- D stream_size 10i 0 value Stream struct. size
- *
- D inflateSetDictionary...
- D PR 10I 0 extproc('inflateSetDictionary') Init. dictionary
- D strm like(z_stream) Expansion stream
- D dictionary 32767 const options(*varsize) Dictionary bytes
- D dictLength 10U 0 value Dictionary length
- *
- D inflateSync PR 10I 0 extproc('inflateSync') Sync. expansion
- D strm like(z_stream) Expansion stream
- *
- D inflateCopy PR 10I 0 extproc('inflateCopy')
- D dest like(z_stream) Destination stream
- D source like(z_stream) Source stream
- *
- D inflateReset PR 10I 0 extproc('inflateReset') End and init. stream
- D strm like(z_stream) Expansion stream
- *
- D inflateBackInit...
- D PR 10I 0 extproc('inflateBackInit_')
- D strm like(z_stream) Expansion stream
- D windowBits 10I 0 value Log2(buffer size)
- D window 32767 options(*varsize) Buffer
- D version * value options(*string) Version string
- D stream_size 10i 0 value Stream struct. size
- *
- D inflateBack PR 10I 0 extproc('inflateBack')
- D strm like(z_stream) Expansion stream
- D in * value procptr Input function
- D in_desc * value Input descriptor
- D out * value procptr Output function
- D out_desc * value Output descriptor
- *
- D inflateBackEnd PR 10I 0 extproc('inflateBackEnd')
- D strm like(z_stream) Expansion stream
- *
- D zlibCompileFlags...
- D PR 10U 0 extproc('zlibCompileFlags')
- *
- **************************************************************************
- * Checksum function prototypes
- **************************************************************************
- *
- D adler32 PR 10U 0 extproc('adler32') New checksum
- D adler 10U 0 value Old checksum
- D buf 32767 const options(*varsize) Bytes to accumulate
- D len 10U 0 value Buffer length
- *
- D crc32 PR 10U 0 extproc('crc32') New checksum
- D crc 10U 0 value Old checksum
- D buf 32767 const options(*varsize) Bytes to accumulate
- D len 10U 0 value Buffer length
- *
- **************************************************************************
- * Miscellaneous function prototypes
- **************************************************************************
- *
- D zError PR * extproc('zError') Error string
- D err 10I 0 value Error code
- *
- D inflateSyncPoint...
- D PR 10I 0 extproc('inflateSyncPoint')
- D strm like(z_stream) Expansion stream
- *
- D get_crc_table PR * extproc('get_crc_table') Ptr to ulongs
- *
- /endif
diff --git a/cpukit/zlib/compress.c b/cpukit/zlib/compress.c
index df04f0148e..7dfd8c3c7d 100644
--- a/cpukit/zlib/compress.c
+++ b/cpukit/zlib/compress.c
@@ -3,7 +3,7 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id$ */
+/* $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h"
diff --git a/cpukit/zlib/configure b/cpukit/zlib/configure
deleted file mode 100755
index e3ea897d5a..0000000000
--- a/cpukit/zlib/configure
+++ /dev/null
@@ -1,446 +0,0 @@
-#!/bin/sh
-# configure script for zlib. This script is needed only if
-# you wish to build a shared library and your system supports them,
-# of if you need special compiler, flags or install directory.
-# Otherwise, you can just use directly "make test; make install"
-#
-# To create a shared library, use "configure --shared"; by default a static
-# library is created. If the primitive shared library support provided here
-# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz
-#
-# To impose specific compiler or flags or install directory, use for example:
-# prefix=$HOME CC=cc CFLAGS="-O4" ./configure
-# or for csh/tcsh users:
-# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
-# LDSHARED is the command to be used to create a shared library
-
-# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
-# If you have problems, try without defining CC and CFLAGS before reporting
-# an error.
-
-LIBS=libz.a
-LDFLAGS="-L. ${LIBS}"
-VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
-VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h`
-VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h`
-AR=${AR-"ar rc"}
-RANLIB=${RANLIB-"ranlib"}
-prefix=${prefix-/usr/local}
-exec_prefix=${exec_prefix-'${prefix}'}
-libdir=${libdir-'${exec_prefix}/lib'}
-includedir=${includedir-'${prefix}/include'}
-mandir=${mandir-'${prefix}/share/man'}
-shared_ext='.so'
-shared=0
-gcc=0
-old_cc="$CC"
-old_cflags="$CFLAGS"
-
-while test $# -ge 1
-do
-case "$1" in
- -h* | --h*)
- echo 'usage:'
- echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]'
- echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]'
- exit 0;;
- -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
- -e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
- -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
- -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;;
- -p* | --p*) prefix="$2"; shift; shift;;
- -e* | --e*) exec_prefix="$2"; shift; shift;;
- -l* | --l*) libdir="$2"; shift; shift;;
- -i* | --i*) includedir="$2"; shift; shift;;
- -s* | --s*) shared=1; shift;;
- *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1;;
- esac
-done
-
-test=ztest$$
-cat > $test.c <<EOF
-extern int getchar();
-int hello() {return getchar();}
-EOF
-
-test -z "$CC" && echo Checking for gcc...
-cc=${CC-gcc}
-cflags=${CFLAGS-"-O3"}
-# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
-case "$cc" in
- *gcc*) gcc=1;;
-esac
-
-if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
- CC="$cc"
- SFLAGS=${CFLAGS-"-fPIC -O3"}
- CFLAGS="$cflags"
- case `(uname -s || echo unknown) 2>/dev/null` in
- Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1"};;
- CYGWIN* | Cygwin* | cygwin* | OS/2* )
- EXE='.exe';;
- QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
- # (alain.bonnefoy@icbt.com)
- LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"};;
- HP-UX*) LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
- shared_ext='.sl'
- SHAREDLIB='libz.sl';;
- Darwin*) shared_ext='.dylib'
- SHAREDLIB=libz$shared_ext
- SHAREDLIBV=libz.$VER$shared_ext
- SHAREDLIBM=libz.$VER1$shared_ext
- LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER"};;
- *) LDSHARED=${LDSHARED-"$cc -shared"};;
- esac
-else
- # find system name and corresponding cc options
- CC=${CC-cc}
- case `(uname -sr || echo unknown) 2>/dev/null` in
- HP-UX*) SFLAGS=${CFLAGS-"-O +z"}
- CFLAGS=${CFLAGS-"-O"}
-# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
- LDSHARED=${LDSHARED-"ld -b"}
- shared_ext='.sl'
- SHAREDLIB='libz.sl';;
- IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
- CFLAGS=${CFLAGS-"-ansi -O2"}
- LDSHARED=${LDSHARED-"cc -shared"};;
- OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
- CFLAGS=${CFLAGS-"-O -std1"}
- LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};;
- OSF1*) SFLAGS=${CFLAGS-"-O -std1"}
- CFLAGS=${CFLAGS-"-O -std1"}
- LDSHARED=${LDSHARED-"cc -shared"};;
- QNX*) SFLAGS=${CFLAGS-"-4 -O"}
- CFLAGS=${CFLAGS-"-4 -O"}
- LDSHARED=${LDSHARED-"cc"}
- RANLIB=${RANLIB-"true"}
- AR="cc -A";;
- SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
- CFLAGS=${CFLAGS-"-O3"}
- LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};;
- SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."}
- CFLAGS=${CFLAGS-"-fast -xcg89"}
- LDSHARED=${LDSHARED-"cc -G"};;
- SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
- CFLAGS=${CFLAGS-"-O2"}
- LDSHARED=${LDSHARED-"ld"};;
- SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
- CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"}
- LDSHARED=${LDSHARED-"cc -xarch=v9b"};;
- UNIX_System_V\ 4.2.0)
- SFLAGS=${CFLAGS-"-KPIC -O"}
- CFLAGS=${CFLAGS-"-O"}
- LDSHARED=${LDSHARED-"cc -G"};;
- UNIX_SV\ 4.2MP)
- SFLAGS=${CFLAGS-"-Kconform_pic -O"}
- CFLAGS=${CFLAGS-"-O"}
- LDSHARED=${LDSHARED-"cc -G"};;
- OpenUNIX\ 5)
- SFLAGS=${CFLAGS-"-KPIC -O"}
- CFLAGS=${CFLAGS-"-O"}
- LDSHARED=${LDSHARED-"cc -G"};;
- AIX*) # Courtesy of dbakker@arrayasolutions.com
- SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
- CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
- LDSHARED=${LDSHARED-"xlc -G"};;
- # send working options for other systems to support@gzip.org
- *) SFLAGS=${CFLAGS-"-O"}
- CFLAGS=${CFLAGS-"-O"}
- LDSHARED=${LDSHARED-"cc -shared"};;
- esac
-fi
-
-SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
-SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
-SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
-
-if test $shared -eq 1; then
- echo Checking for shared library support...
- # we must test in two steps (cc then ld), required at least on SunOS 4.x
- if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" &&
- test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then
- CFLAGS="$SFLAGS"
- LIBS="$SHAREDLIBV"
- echo Building shared library $SHAREDLIBV with $CC.
- elif test -z "$old_cc" -a -z "$old_cflags"; then
- echo No shared library support.
- shared=0;
- else
- echo 'No shared library support; try without defining CC and CFLAGS'
- shared=0;
- fi
-fi
-if test $shared -eq 0; then
- LDSHARED="$CC"
- echo Building static library $LIBS version $VER with $CC.
-else
- LDFLAGS="-L. ${SHAREDLIBV}"
-fi
-
-cat > $test.c <<EOF
-#include <unistd.h>
-int main() { return 0; }
-EOF
-if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- sed < zconf.in.h "/HAVE_UNISTD_H/s%0%1%" > zconf.h
- echo "Checking for unistd.h... Yes."
-else
- cp -p zconf.in.h zconf.h
- echo "Checking for unistd.h... No."
-fi
-
-cat > $test.c <<EOF
-#include <stdio.h>
-#include <stdarg.h>
-#include "zconf.h"
-
-int main()
-{
-#ifndef STDC
- choke me
-#endif
-
- return 0;
-}
-EOF
-
-if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()"
-
- cat > $test.c <<EOF
-#include <stdio.h>
-#include <stdarg.h>
-
-int mytest(char *fmt, ...)
-{
- char buf[20];
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
- return 0;
-}
-
-int main()
-{
- return (mytest("Hello%d\n", 1));
-}
-EOF
-
- if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
- echo "Checking for vsnprintf() in stdio.h... Yes."
-
- cat >$test.c <<EOF
-#include <stdio.h>
-#include <stdarg.h>
-
-int mytest(char *fmt, ...)
-{
- int n;
- char buf[20];
- va_list ap;
-
- va_start(ap, fmt);
- n = vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
- return n;
-}
-
-int main()
-{
- return (mytest("Hello%d\n", 1));
-}
-EOF
-
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of vsnprintf()... Yes."
- else
- CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
- echo "Checking for return value of vsnprintf()... No."
- echo " WARNING: apparently vsnprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
- fi
- else
- CFLAGS="$CFLAGS -DNO_vsnprintf"
- echo "Checking for vsnprintf() in stdio.h... No."
- echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib"
- echo " can build but will be open to possible buffer-overflow security"
- echo " vulnerabilities."
-
- cat >$test.c <<EOF
-#include <stdio.h>
-#include <stdarg.h>
-
-int mytest(char *fmt, ...)
-{
- int n;
- char buf[20];
- va_list ap;
-
- va_start(ap, fmt);
- n = vsprintf(buf, fmt, ap);
- va_end(ap);
- return n;
-}
-
-int main()
-{
- return (mytest("Hello%d\n", 1));
-}
-EOF
-
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of vsprintf()... Yes."
- else
- CFLAGS="$CFLAGS -DHAS_vsprintf_void"
- echo "Checking for return value of vsprintf()... No."
- echo " WARNING: apparently vsprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
- fi
- fi
-else
- echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()"
-
- cat >$test.c <<EOF
-#include <stdio.h>
-
-int mytest()
-{
- char buf[20];
-
- snprintf(buf, sizeof(buf), "%s", "foo");
- return 0;
-}
-
-int main()
-{
- return (mytest());
-}
-EOF
-
- if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
- echo "Checking for snprintf() in stdio.h... Yes."
-
- cat >$test.c <<EOF
-#include <stdio.h>
-
-int mytest()
-{
- char buf[20];
-
- return snprintf(buf, sizeof(buf), "%s", "foo");
-}
-
-int main()
-{
- return (mytest());
-}
-EOF
-
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of snprintf()... Yes."
- else
- CFLAGS="$CFLAGS -DHAS_snprintf_void"
- echo "Checking for return value of snprintf()... No."
- echo " WARNING: apparently snprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
- fi
- else
- CFLAGS="$CFLAGS -DNO_snprintf"
- echo "Checking for snprintf() in stdio.h... No."
- echo " WARNING: snprintf() not found, falling back to sprintf(). zlib"
- echo " can build but will be open to possible buffer-overflow security"
- echo " vulnerabilities."
-
- cat >$test.c <<EOF
-#include <stdio.h>
-
-int mytest()
-{
- char buf[20];
-
- return sprintf(buf, "%s", "foo");
-}
-
-int main()
-{
- return (mytest());
-}
-EOF
-
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of sprintf()... Yes."
- else
- CFLAGS="$CFLAGS -DHAS_sprintf_void"
- echo "Checking for return value of sprintf()... No."
- echo " WARNING: apparently sprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
- fi
- fi
-fi
-
-cat >$test.c <<EOF
-#include <errno.h>
-int main() { return 0; }
-EOF
-if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for errno.h... Yes."
-else
- echo "Checking for errno.h... No."
- CFLAGS="$CFLAGS -DNO_ERRNO_H"
-fi
-
-cat > $test.c <<EOF
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-caddr_t hello() {
- return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0);
-}
-EOF
-if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- CFLAGS="$CFLAGS -DUSE_MMAP"
- echo Checking for mmap support... Yes.
-else
- echo Checking for mmap support... No.
-fi
-
-CPP=${CPP-"$CC -E"}
-case $CFLAGS in
- *ASMV*)
- if test "`nm $test.o | grep _hello`" = ""; then
- CPP="$CPP -DNO_UNDERLINE"
- echo Checking for underline in external names... No.
- else
- echo Checking for underline in external names... Yes.
- fi;;
-esac
-
-rm -f $test.[co] $test $test$shared_ext
-
-# udpate Makefile
-sed < Makefile.in "
-/^CC *=/s#=.*#=$CC#
-/^CFLAGS *=/s#=.*#=$CFLAGS#
-/^CPP *=/s#=.*#=$CPP#
-/^LDSHARED *=/s#=.*#=$LDSHARED#
-/^LIBS *=/s#=.*#=$LIBS#
-/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
-/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
-/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
-/^AR *=/s#=.*#=$AR#
-/^RANLIB *=/s#=.*#=$RANLIB#
-/^EXE *=/s#=.*#=$EXE#
-/^prefix *=/s#=.*#=$prefix#
-/^exec_prefix *=/s#=.*#=$exec_prefix#
-/^libdir *=/s#=.*#=$libdir#
-/^includedir *=/s#=.*#=$includedir#
-/^mandir *=/s#=.*#=$mandir#
-/^LDFLAGS *=/s#=.*#=$LDFLAGS#
-" > Makefile
diff --git a/cpukit/zlib/contrib/README.contrib b/cpukit/zlib/contrib/README.contrib
deleted file mode 100644
index 732d48c957..0000000000
--- a/cpukit/zlib/contrib/README.contrib
+++ /dev/null
@@ -1,67 +0,0 @@
-All files under this contrib directory are UNSUPPORTED. There were
-provided by users of zlib and were not tested by the authors of zlib.
-Use at your own risk. Please contact the authors of the contributions
-for help about these, not the zlib authors. Thanks.
-
-
-ada/ by Dmitriy Anisimkov <anisimkov@yahoo.com>
- Support for Ada
- See http://zlib-ada.sourceforge.net/
-
-asm586/
-asm686/ by Brian Raiter <breadbox@muppetlabs.com>
- asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax
- See http://www.muppetlabs.com/~breadbox/software/assembly.html
-
-blast/ by Mark Adler <madler@alumni.caltech.edu>
- Decompressor for output of PKWare Data Compression Library (DCL)
-
-delphi/ by Cosmin Truta <cosmint@cs.ubbcluj.ro>
- Support for Delphi and C++ Builder
-
-dotzlib/ by Henrik Ravn <henrik@ravn.com>
- Support for Microsoft .Net and Visual C++ .Net
-
-infback9/ by Mark Adler <madler@alumni.caltech.edu>
- Unsupported diffs to infback to decode the deflate64 format
-
-inflate86/ by Chris Anderson <christop@charm.net>
- Tuned x86 gcc asm code to replace inflate_fast()
-
-iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
- A C++ I/O streams interface to the zlib gz* functions
-
-iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
- Another C++ I/O streams interface
-
-iostream3/ by Ludwig Schwardt <schwardt@sun.ac.za>
- and Kevin Ruland <kevin@rodin.wustl.edu>
- Yet another C++ I/O streams interface
-
-masm686/ by Dan Higdon <hdan@kinesoft.com>
- and Chuck Walbourn <chuckw@kinesoft.com>
- asm code for Pentium Pro/PII, using the MASM syntax
-
-masmx86/ by Gilles Vollant <info@winimage.com>
- x86 asm code to replace longest_match() and inflate_fast(),
- for Visual C++ and MASM
-
-minizip/ by Gilles Vollant <info@winimage.com>
- Mini zip and unzip based on zlib
- See http://www.winimage.com/zLibDll/unzip.html
-
-pascal/ by Bob Dellaca <bobdl@xtra.co.nz> et al.
- Support for Pascal
-
-puff/ by Mark Adler <madler@alumni.caltech.edu>
- Small, low memory usage inflate. Also serves to provide an
- unambiguous description of the deflate format.
-
-testzlib/ by Gilles Vollant <info@winimage.com>
- Example of the use of zlib
-
-untgz/ by Pedro A. Aranda Gutierrez <paag@tid.es>
- A very simple tar.gz file extractor using zlib
-
-vstudio/ by Gilles Vollant <info@winimage.com>
- Building a minizip-enhanced zlib with Microsoft Visual Studio
diff --git a/cpukit/zlib/contrib/ada/buffer_demo.adb b/cpukit/zlib/contrib/ada/buffer_demo.adb
deleted file mode 100644
index cd63fa48f8..0000000000
--- a/cpukit/zlib/contrib/ada/buffer_demo.adb
+++ /dev/null
@@ -1,106 +0,0 @@
-----------------------------------------------------------------
--- ZLib for Ada thick binding. --
--- --
--- Copyright (C) 2002-2004 Dmitriy Anisimkov --
--- --
--- Open source license information is in the zlib.ads file. --
-----------------------------------------------------------------
---
--- $Id$
-
--- This demo program provided by Dr Steve Sangwine <sjs@essex.ac.uk>
---
--- Demonstration of a problem with Zlib-Ada (already fixed) when a buffer
--- of exactly the correct size is used for decompressed data, and the last
--- few bytes passed in to Zlib are checksum bytes.
-
--- This program compresses a string of text, and then decompresses the
--- compressed text into a buffer of the same size as the original text.
-
-with Ada.Streams; use Ada.Streams;
-with Ada.Text_IO;
-
-with ZLib; use ZLib;
-
-procedure Buffer_Demo is
- EOL : Character renames ASCII.LF;
- Text : constant String
- := "Four score and seven years ago our fathers brought forth," & EOL &
- "upon this continent, a new nation, conceived in liberty," & EOL &
- "and dedicated to the proposition that `all men are created equal'.";
-
- Source : Stream_Element_Array (1 .. Text'Length);
- for Source'Address use Text'Address;
-
-begin
- Ada.Text_IO.Put (Text);
- Ada.Text_IO.New_Line;
- Ada.Text_IO.Put_Line
- ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes");
-
- declare
- Compressed_Data : Stream_Element_Array (1 .. Text'Length);
- L : Stream_Element_Offset;
- begin
- Compress : declare
- Compressor : Filter_Type;
- I : Stream_Element_Offset;
- begin
- Deflate_Init (Compressor);
-
- -- Compress the whole of T at once.
-
- Translate (Compressor, Source, I, Compressed_Data, L, Finish);
- pragma Assert (I = Source'Last);
-
- Close (Compressor);
-
- Ada.Text_IO.Put_Line
- ("Compressed size : "
- & Stream_Element_Offset'Image (L) & " bytes");
- end Compress;
-
- -- Now we decompress the data, passing short blocks of data to Zlib
- -- (because this demonstrates the problem - the last block passed will
- -- contain checksum information and there will be no output, only a
- -- check inside Zlib that the checksum is correct).
-
- Decompress : declare
- Decompressor : Filter_Type;
-
- Uncompressed_Data : Stream_Element_Array (1 .. Text'Length);
-
- Block_Size : constant := 4;
- -- This makes sure that the last block contains
- -- only Adler checksum data.
-
- P : Stream_Element_Offset := Compressed_Data'First - 1;
- O : Stream_Element_Offset;
- begin
- Inflate_Init (Decompressor);
-
- loop
- Translate
- (Decompressor,
- Compressed_Data
- (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)),
- P,
- Uncompressed_Data
- (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last),
- O,
- No_Flush);
-
- Ada.Text_IO.Put_Line
- ("Total in : " & Count'Image (Total_In (Decompressor)) &
- ", out : " & Count'Image (Total_Out (Decompressor)));
-
- exit when P = L;
- end loop;
-
- Ada.Text_IO.New_Line;
- Ada.Text_IO.Put_Line
- ("Decompressed text matches original text : "
- & Boolean'Image (Uncompressed_Data = Source));
- end Decompress;
- end;
-end Buffer_Demo;
diff --git a/cpukit/zlib/contrib/ada/mtest.adb b/cpukit/zlib/contrib/ada/mtest.adb
deleted file mode 100644
index 5f17228cd2..0000000000
--- a/cpukit/zlib/contrib/ada/mtest.adb
+++ /dev/null
@@ -1,156 +0,0 @@
-----------------------------------------------------------------
--- ZLib for Ada thick binding. --
--- --
--- Copyright (C) 2002-2003 Dmitriy Anisimkov --
--- --
--- Open source license information is in the zlib.ads file. --
-----------------------------------------------------------------
--- Continuous test for ZLib multithreading. If the test would fail
--- we should provide thread safe allocation routines for the Z_Stream.
---
--- $Id$
-
-with ZLib;
-with Ada.Streams;
-with Ada.Numerics.Discrete_Random;
-with Ada.Text_IO;
-with Ada.Exceptions;
-with Ada.Task_Identification;
-
-procedure MTest is
- use Ada.Streams;
- use ZLib;
-
- Stop : Boolean := False;
-
- pragma Atomic (Stop);
-
- subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
-
- package Random_Elements is
- new Ada.Numerics.Discrete_Random (Visible_Symbols);
-
- task type Test_Task;
-
- task body Test_Task is
- Buffer : Stream_Element_Array (1 .. 100_000);
- Gen : Random_Elements.Generator;
-
- Buffer_First : Stream_Element_Offset;
- Compare_First : Stream_Element_Offset;
-
- Deflate : Filter_Type;
- Inflate : Filter_Type;
-
- procedure Further (Item : in Stream_Element_Array);
-
- procedure Read_Buffer
- (Item : out Ada.Streams.Stream_Element_Array;
- Last : out Ada.Streams.Stream_Element_Offset);
-
- -------------
- -- Further --
- -------------
-
- procedure Further (Item : in Stream_Element_Array) is
-
- procedure Compare (Item : in Stream_Element_Array);
-
- -------------
- -- Compare --
- -------------
-
- procedure Compare (Item : in Stream_Element_Array) is
- Next_First : Stream_Element_Offset := Compare_First + Item'Length;
- begin
- if Buffer (Compare_First .. Next_First - 1) /= Item then
- raise Program_Error;
- end if;
-
- Compare_First := Next_First;
- end Compare;
-
- procedure Compare_Write is new ZLib.Write (Write => Compare);
- begin
- Compare_Write (Inflate, Item, No_Flush);
- end Further;
-
- -----------------
- -- Read_Buffer --
- -----------------
-
- procedure Read_Buffer
- (Item : out Ada.Streams.Stream_Element_Array;
- Last : out Ada.Streams.Stream_Element_Offset)
- is
- Buff_Diff : Stream_Element_Offset := Buffer'Last - Buffer_First;
- Next_First : Stream_Element_Offset;
- begin
- if Item'Length <= Buff_Diff then
- Last := Item'Last;
-
- Next_First := Buffer_First + Item'Length;
-
- Item := Buffer (Buffer_First .. Next_First - 1);
-
- Buffer_First := Next_First;
- else
- Last := Item'First + Buff_Diff;
- Item (Item'First .. Last) := Buffer (Buffer_First .. Buffer'Last);
- Buffer_First := Buffer'Last + 1;
- end if;
- end Read_Buffer;
-
- procedure Translate is new Generic_Translate
- (Data_In => Read_Buffer,
- Data_Out => Further);
-
- begin
- Random_Elements.Reset (Gen);
-
- Buffer := (others => 20);
-
- Main : loop
- for J in Buffer'Range loop
- Buffer (J) := Random_Elements.Random (Gen);
-
- Deflate_Init (Deflate);
- Inflate_Init (Inflate);
-
- Buffer_First := Buffer'First;
- Compare_First := Buffer'First;
-
- Translate (Deflate);
-
- if Compare_First /= Buffer'Last + 1 then
- raise Program_Error;
- end if;
-
- Ada.Text_IO.Put_Line
- (Ada.Task_Identification.Image
- (Ada.Task_Identification.Current_Task)
- & Stream_Element_Offset'Image (J)
- & ZLib.Count'Image (Total_Out (Deflate)));
-
- Close (Deflate);
- Close (Inflate);
-
- exit Main when Stop;
- end loop;
- end loop Main;
- exception
- when E : others =>
- Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E));
- Stop := True;
- end Test_Task;
-
- Test : array (1 .. 4) of Test_Task;
-
- pragma Unreferenced (Test);
-
- Dummy : Character;
-
-begin
- Ada.Text_IO.Get_Immediate (Dummy);
- Stop := True;
-end MTest;
diff --git a/cpukit/zlib/contrib/ada/read.adb b/cpukit/zlib/contrib/ada/read.adb
deleted file mode 100644
index 00effd7209..0000000000
--- a/cpukit/zlib/contrib/ada/read.adb
+++ /dev/null
@@ -1,156 +0,0 @@
-----------------------------------------------------------------
--- ZLib for Ada thick binding. --
--- --
--- Copyright (C) 2002-2003 Dmitriy Anisimkov --
--- --
--- Open source license information is in the zlib.ads file. --
-----------------------------------------------------------------
-
--- $Id$
-
--- Test/demo program for the generic read interface.
-
-with Ada.Numerics.Discrete_Random;
-with Ada.Streams;
-with Ada.Text_IO;
-
-with ZLib;
-
-procedure Read is
-
- use Ada.Streams;
-
- ------------------------------------
- -- Test configuration parameters --
- ------------------------------------
-
- File_Size : Stream_Element_Offset := 100_000;
-
- Continuous : constant Boolean := False;
- -- If this constant is True, the test would be repeated again and again,
- -- with increment File_Size for every iteration.
-
- Header : constant ZLib.Header_Type := ZLib.Default;
- -- Do not use Header other than Default in ZLib versions 1.1.4 and older.
-
- Init_Random : constant := 8;
- -- We are using the same random sequence, in case of we catch bug,
- -- so we would be able to reproduce it.
-
- -- End --
-
- Pack_Size : Stream_Element_Offset;
- Offset : Stream_Element_Offset;
-
- Filter : ZLib.Filter_Type;
-
- subtype Visible_Symbols
- is Stream_Element range 16#20# .. 16#7E#;
-
- package Random_Elements is new
- Ada.Numerics.Discrete_Random (Visible_Symbols);
-
- Gen : Random_Elements.Generator;
- Period : constant Stream_Element_Offset := 200;
- -- Period constant variable for random generator not to be very random.
- -- Bigger period, harder random.
-
- Read_Buffer : Stream_Element_Array (1 .. 2048);
- Read_First : Stream_Element_Offset;
- Read_Last : Stream_Element_Offset;
-
- procedure Reset;
-
- procedure Read
- (Item : out Stream_Element_Array;
- Last : out Stream_Element_Offset);
- -- this procedure is for generic instantiation of
- -- ZLib.Read
- -- reading data from the File_In.
-
- procedure Read is new ZLib.Read
- (Read,
- Read_Buffer,
- Rest_First => Read_First,
- Rest_Last => Read_Last);
-
- ----------
- -- Read --
- ----------
-
- procedure Read
- (Item : out Stream_Element_Array;
- Last : out Stream_Element_Offset) is
- begin
- Last := Stream_Element_Offset'Min
- (Item'Last,
- Item'First + File_Size - Offset);
-
- for J in Item'First .. Last loop
- if J < Item'First + Period then
- Item (J) := Random_Elements.Random (Gen);
- else
- Item (J) := Item (J - Period);
- end if;
-
- Offset := Offset + 1;
- end loop;
- end Read;
-
- -----------
- -- Reset --
- -----------
-
- procedure Reset is
- begin
- Random_Elements.Reset (Gen, Init_Random);
- Pack_Size := 0;
- Offset := 1;
- Read_First := Read_Buffer'Last + 1;
- Read_Last := Read_Buffer'Last;
- end Reset;
-
-begin
- Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
-
- loop
- for Level in ZLib.Compression_Level'Range loop
-
- Ada.Text_IO.Put ("Level ="
- & ZLib.Compression_Level'Image (Level));
-
- -- Deflate using generic instantiation.
-
- ZLib.Deflate_Init
- (Filter,
- Level,
- Header => Header);
-
- Reset;
-
- Ada.Text_IO.Put
- (Stream_Element_Offset'Image (File_Size) & " ->");
-
- loop
- declare
- Buffer : Stream_Element_Array (1 .. 1024);
- Last : Stream_Element_Offset;
- begin
- Read (Filter, Buffer, Last);
-
- Pack_Size := Pack_Size + Last - Buffer'First + 1;
-
- exit when Last < Buffer'Last;
- end;
- end loop;
-
- Ada.Text_IO.Put_Line (Stream_Element_Offset'Image (Pack_Size));
-
- ZLib.Close (Filter);
- end loop;
-
- exit when not Continuous;
-
- File_Size := File_Size + 1;
- end loop;
-end Read;
diff --git a/cpukit/zlib/contrib/ada/readme.txt b/cpukit/zlib/contrib/ada/readme.txt
deleted file mode 100644
index ce4d2cadf0..0000000000
--- a/cpukit/zlib/contrib/ada/readme.txt
+++ /dev/null
@@ -1,65 +0,0 @@
- ZLib for Ada thick binding (ZLib.Ada)
- Release 1.3
-
-ZLib.Ada is a thick binding interface to the popular ZLib data
-compression library, available at http://www.gzip.org/zlib/.
-It provides Ada-style access to the ZLib C library.
-
-
- Here are the main changes since ZLib.Ada 1.2:
-
-- Attension: ZLib.Read generic routine have a initialization requirement
- for Read_Last parameter now. It is a bit incompartible with previous version,
- but extends functionality, we could use new parameters Allow_Read_Some and
- Flush now.
-
-- Added Is_Open routines to ZLib and ZLib.Streams packages.
-
-- Add pragma Assert to check Stream_Element is 8 bit.
-
-- Fix extraction to buffer with exact known decompressed size. Error reported by
- Steve Sangwine.
-
-- Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits
- computers. Patch provided by Pascal Obry.
-
-- Add Status_Error exception definition.
-
-- Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit.
-
-
- How to build ZLib.Ada under GNAT
-
-You should have the ZLib library already build on your computer, before
-building ZLib.Ada. Make the directory of ZLib.Ada sources current and
-issue the command:
-
- gnatmake test -largs -L<directory where libz.a is> -lz
-
-Or use the GNAT project file build for GNAT 3.15 or later:
-
- gnatmake -Pzlib.gpr -L<directory where libz.a is>
-
-
- How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2
-
-1. Make a project with all *.ads and *.adb files from the distribution.
-2. Build the libz.a library from the ZLib C sources.
-3. Rename libz.a to z.lib.
-4. Add the library z.lib to the project.
-5. Add the libc.lib library from the ObjectAda distribution to the project.
-6. Build the executable using test.adb as a main procedure.
-
-
- How to use ZLib.Ada
-
-The source files test.adb and read.adb are small demo programs that show
-the main functionality of ZLib.Ada.
-
-The routines from the package specifications are commented.
-
-
-Homepage: http://zlib-ada.sourceforge.net/
-Author: Dmitriy Anisimkov <anisimkov@yahoo.com>
-
-Contributors: Pascal Obry <pascal@obry.org>, Steve Sangwine <sjs@essex.ac.uk>
diff --git a/cpukit/zlib/contrib/ada/test.adb b/cpukit/zlib/contrib/ada/test.adb
deleted file mode 100644
index 8444647144..0000000000
--- a/cpukit/zlib/contrib/ada/test.adb
+++ /dev/null
@@ -1,463 +0,0 @@
-----------------------------------------------------------------
--- ZLib for Ada thick binding. --
--- --
--- Copyright (C) 2002-2003 Dmitriy Anisimkov --
--- --
--- Open source license information is in the zlib.ads file. --
-----------------------------------------------------------------
-
--- $Id$
-
--- The program has a few aims.
--- 1. Test ZLib.Ada95 thick binding functionality.
--- 2. Show the example of use main functionality of the ZLib.Ada95 binding.
--- 3. Build this program automatically compile all ZLib.Ada95 packages under
--- GNAT Ada95 compiler.
-
-with ZLib.Streams;
-with Ada.Streams.Stream_IO;
-with Ada.Numerics.Discrete_Random;
-
-with Ada.Text_IO;
-
-with Ada.Calendar;
-
-procedure Test is
-
- use Ada.Streams;
- use Stream_IO;
-
- ------------------------------------
- -- Test configuration parameters --
- ------------------------------------
-
- File_Size : Count := 100_000;
- Continuous : constant Boolean := False;
-
- Header : constant ZLib.Header_Type := ZLib.Default;
- -- ZLib.None;
- -- ZLib.Auto;
- -- ZLib.GZip;
- -- Do not use Header other then Default in ZLib versions 1.1.4
- -- and older.
-
- Strategy : constant ZLib.Strategy_Type := ZLib.Default_Strategy;
- Init_Random : constant := 10;
-
- -- End --
-
- In_File_Name : constant String := "testzlib.in";
- -- Name of the input file
-
- Z_File_Name : constant String := "testzlib.zlb";
- -- Name of the compressed file.
-
- Out_File_Name : constant String := "testzlib.out";
- -- Name of the decompressed file.
-
- File_In : File_Type;
- File_Out : File_Type;
- File_Back : File_Type;
- File_Z : ZLib.Streams.Stream_Type;
-
- Filter : ZLib.Filter_Type;
-
- Time_Stamp : Ada.Calendar.Time;
-
- procedure Generate_File;
- -- Generate file of spetsified size with some random data.
- -- The random data is repeatable, for the good compression.
-
- procedure Compare_Streams
- (Left, Right : in out Root_Stream_Type'Class);
- -- The procedure compearing data in 2 streams.
- -- It is for compare data before and after compression/decompression.
-
- procedure Compare_Files (Left, Right : String);
- -- Compare files. Based on the Compare_Streams.
-
- procedure Copy_Streams
- (Source, Target : in out Root_Stream_Type'Class;
- Buffer_Size : in Stream_Element_Offset := 1024);
- -- Copying data from one stream to another. It is for test stream
- -- interface of the library.
-
- procedure Data_In
- (Item : out Stream_Element_Array;
- Last : out Stream_Element_Offset);
- -- this procedure is for generic instantiation of
- -- ZLib.Generic_Translate.
- -- reading data from the File_In.
-
- procedure Data_Out (Item : in Stream_Element_Array);
- -- this procedure is for generic instantiation of
- -- ZLib.Generic_Translate.
- -- writing data to the File_Out.
-
- procedure Stamp;
- -- Store the timestamp to the local variable.
-
- procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count);
- -- Print the time statistic with the message.
-
- procedure Translate is new ZLib.Generic_Translate
- (Data_In => Data_In,
- Data_Out => Data_Out);
- -- This procedure is moving data from File_In to File_Out
- -- with compression or decompression, depend on initialization of
- -- Filter parameter.
-
- -------------------
- -- Compare_Files --
- -------------------
-
- procedure Compare_Files (Left, Right : String) is
- Left_File, Right_File : File_Type;
- begin
- Open (Left_File, In_File, Left);
- Open (Right_File, In_File, Right);
- Compare_Streams (Stream (Left_File).all, Stream (Right_File).all);
- Close (Left_File);
- Close (Right_File);
- end Compare_Files;
-
- ---------------------
- -- Compare_Streams --
- ---------------------
-
- procedure Compare_Streams
- (Left, Right : in out Ada.Streams.Root_Stream_Type'Class)
- is
- Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#);
- Left_Last, Right_Last : Stream_Element_Offset;
- begin
- loop
- Read (Left, Left_Buffer, Left_Last);
- Read (Right, Right_Buffer, Right_Last);
-
- if Left_Last /= Right_Last then
- Ada.Text_IO.Put_Line ("Compare error :"
- & Stream_Element_Offset'Image (Left_Last)
- & " /= "
- & Stream_Element_Offset'Image (Right_Last));
-
- raise Constraint_Error;
-
- elsif Left_Buffer (0 .. Left_Last)
- /= Right_Buffer (0 .. Right_Last)
- then
- Ada.Text_IO.Put_Line ("ERROR: IN and OUT files is not equal.");
- raise Constraint_Error;
-
- end if;
-
- exit when Left_Last < Left_Buffer'Last;
- end loop;
- end Compare_Streams;
-
- ------------------
- -- Copy_Streams --
- ------------------
-
- procedure Copy_Streams
- (Source, Target : in out Ada.Streams.Root_Stream_Type'Class;
- Buffer_Size : in Stream_Element_Offset := 1024)
- is
- Buffer : Stream_Element_Array (1 .. Buffer_Size);
- Last : Stream_Element_Offset;
- begin
- loop
- Read (Source, Buffer, Last);
- Write (Target, Buffer (1 .. Last));
-
- exit when Last < Buffer'Last;
- end loop;
- end Copy_Streams;
-
- -------------
- -- Data_In --
- -------------
-
- procedure Data_In
- (Item : out Stream_Element_Array;
- Last : out Stream_Element_Offset) is
- begin
- Read (File_In, Item, Last);
- end Data_In;
-
- --------------
- -- Data_Out --
- --------------
-
- procedure Data_Out (Item : in Stream_Element_Array) is
- begin
- Write (File_Out, Item);
- end Data_Out;
-
- -------------------
- -- Generate_File --
- -------------------
-
- procedure Generate_File is
- subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
-
- package Random_Elements is
- new Ada.Numerics.Discrete_Random (Visible_Symbols);
-
- Gen : Random_Elements.Generator;
- Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10;
-
- Buffer_Count : constant Count := File_Size / Buffer'Length;
- -- Number of same buffers in the packet.
-
- Density : constant Count := 30; -- from 0 to Buffer'Length - 2;
-
- procedure Fill_Buffer (J, D : in Count);
- -- Change the part of the buffer.
-
- -----------------
- -- Fill_Buffer --
- -----------------
-
- procedure Fill_Buffer (J, D : in Count) is
- begin
- for K in 0 .. D loop
- Buffer
- (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1))
- := Random_Elements.Random (Gen);
-
- end loop;
- end Fill_Buffer;
-
- begin
- Random_Elements.Reset (Gen, Init_Random);
-
- Create (File_In, Out_File, In_File_Name);
-
- Fill_Buffer (1, Buffer'Length - 2);
-
- for J in 1 .. Buffer_Count loop
- Write (File_In, Buffer);
-
- Fill_Buffer (J, Density);
- end loop;
-
- -- fill remain size.
-
- Write
- (File_In,
- Buffer
- (1 .. Stream_Element_Offset
- (File_Size - Buffer'Length * Buffer_Count)));
-
- Flush (File_In);
- Close (File_In);
- end Generate_File;
-
- ---------------------
- -- Print_Statistic --
- ---------------------
-
- procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is
- use Ada.Calendar;
- use Ada.Text_IO;
-
- package Count_IO is new Integer_IO (ZLib.Count);
-
- Curr_Dur : Duration := Clock - Time_Stamp;
- begin
- Put (Msg);
-
- Set_Col (20);
- Ada.Text_IO.Put ("size =");
-
- Count_IO.Put
- (Data_Size,
- Width => Stream_IO.Count'Image (File_Size)'Length);
-
- Put_Line (" duration =" & Duration'Image (Curr_Dur));
- end Print_Statistic;
-
- -----------
- -- Stamp --
- -----------
-
- procedure Stamp is
- begin
- Time_Stamp := Ada.Calendar.Clock;
- end Stamp;
-
-begin
- Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
-
- loop
- Generate_File;
-
- for Level in ZLib.Compression_Level'Range loop
-
- Ada.Text_IO.Put_Line ("Level ="
- & ZLib.Compression_Level'Image (Level));
-
- -- Test generic interface.
- Open (File_In, In_File, In_File_Name);
- Create (File_Out, Out_File, Z_File_Name);
-
- Stamp;
-
- -- Deflate using generic instantiation.
-
- ZLib.Deflate_Init
- (Filter => Filter,
- Level => Level,
- Strategy => Strategy,
- Header => Header);
-
- Translate (Filter);
- Print_Statistic ("Generic compress", ZLib.Total_Out (Filter));
- ZLib.Close (Filter);
-
- Close (File_In);
- Close (File_Out);
-
- Open (File_In, In_File, Z_File_Name);
- Create (File_Out, Out_File, Out_File_Name);
-
- Stamp;
-
- -- Inflate using generic instantiation.
-
- ZLib.Inflate_Init (Filter, Header => Header);
-
- Translate (Filter);
- Print_Statistic ("Generic decompress", ZLib.Total_Out (Filter));
-
- ZLib.Close (Filter);
-
- Close (File_In);
- Close (File_Out);
-
- Compare_Files (In_File_Name, Out_File_Name);
-
- -- Test stream interface.
-
- -- Compress to the back stream.
-
- Open (File_In, In_File, In_File_Name);
- Create (File_Back, Out_File, Z_File_Name);
-
- Stamp;
-
- ZLib.Streams.Create
- (Stream => File_Z,
- Mode => ZLib.Streams.Out_Stream,
- Back => ZLib.Streams.Stream_Access
- (Stream (File_Back)),
- Back_Compressed => True,
- Level => Level,
- Strategy => Strategy,
- Header => Header);
-
- Copy_Streams
- (Source => Stream (File_In).all,
- Target => File_Z);
-
- -- Flushing internal buffers to the back stream.
-
- ZLib.Streams.Flush (File_Z, ZLib.Finish);
-
- Print_Statistic ("Write compress",
- ZLib.Streams.Write_Total_Out (File_Z));
-
- ZLib.Streams.Close (File_Z);
-
- Close (File_In);
- Close (File_Back);
-
- -- Compare reading from original file and from
- -- decompression stream.
-
- Open (File_In, In_File, In_File_Name);
- Open (File_Back, In_File, Z_File_Name);
-
- ZLib.Streams.Create
- (Stream => File_Z,
- Mode => ZLib.Streams.In_Stream,
- Back => ZLib.Streams.Stream_Access
- (Stream (File_Back)),
- Back_Compressed => True,
- Header => Header);
-
- Stamp;
- Compare_Streams (Stream (File_In).all, File_Z);
-
- Print_Statistic ("Read decompress",
- ZLib.Streams.Read_Total_Out (File_Z));
-
- ZLib.Streams.Close (File_Z);
- Close (File_In);
- Close (File_Back);
-
- -- Compress by reading from compression stream.
-
- Open (File_Back, In_File, In_File_Name);
- Create (File_Out, Out_File, Z_File_Name);
-
- ZLib.Streams.Create
- (Stream => File_Z,
- Mode => ZLib.Streams.In_Stream,
- Back => ZLib.Streams.Stream_Access
- (Stream (File_Back)),
- Back_Compressed => False,
- Level => Level,
- Strategy => Strategy,
- Header => Header);
-
- Stamp;
- Copy_Streams
- (Source => File_Z,
- Target => Stream (File_Out).all);
-
- Print_Statistic ("Read compress",
- ZLib.Streams.Read_Total_Out (File_Z));
-
- ZLib.Streams.Close (File_Z);
-
- Close (File_Out);
- Close (File_Back);
-
- -- Decompress to decompression stream.
-
- Open (File_In, In_File, Z_File_Name);
- Create (File_Back, Out_File, Out_File_Name);
-
- ZLib.Streams.Create
- (Stream => File_Z,
- Mode => ZLib.Streams.Out_Stream,
- Back => ZLib.Streams.Stream_Access
- (Stream (File_Back)),
- Back_Compressed => False,
- Header => Header);
-
- Stamp;
-
- Copy_Streams
- (Source => Stream (File_In).all,
- Target => File_Z);
-
- Print_Statistic ("Write decompress",
- ZLib.Streams.Write_Total_Out (File_Z));
-
- ZLib.Streams.Close (File_Z);
- Close (File_In);
- Close (File_Back);
-
- Compare_Files (In_File_Name, Out_File_Name);
- end loop;
-
- Ada.Text_IO.Put_Line (Count'Image (File_Size) & " Ok.");
-
- exit when not Continuous;
-
- File_Size := File_Size + 1;
- end loop;
-end Test;
diff --git a/cpukit/zlib/contrib/ada/zlib-streams.adb b/cpukit/zlib/contrib/ada/zlib-streams.adb
deleted file mode 100644
index 10a4732959..0000000000
--- a/cpukit/zlib/contrib/ada/zlib-streams.adb
+++ /dev/null
@@ -1,225 +0,0 @@
-----------------------------------------------------------------
--- ZLib for Ada thick binding. --
--- --
--- Copyright (C) 2002-2003 Dmitriy Anisimkov --
--- --
--- Open source license information is in the zlib.ads file. --
-----------------------------------------------------------------
-
--- $Id$
-
-with Ada.Unchecked_Deallocation;
-
-package body ZLib.Streams is
-
- -----------
- -- Close --
- -----------
-
- procedure Close (Stream : in out Stream_Type) is
- procedure Free is new Ada.Unchecked_Deallocation
- (Stream_Element_Array, Buffer_Access);
- begin
- if Stream.Mode = Out_Stream or Stream.Mode = Duplex then
- -- We should flush the data written by the writer.
-
- Flush (Stream, Finish);
-
- Close (Stream.Writer);
- end if;
-
- if Stream.Mode = In_Stream or Stream.Mode = Duplex then
- Close (Stream.Reader);
- Free (Stream.Buffer);
- end if;
- end Close;
-
- ------------
- -- Create --
- ------------
-
- procedure Create
- (Stream : out Stream_Type;
- Mode : in Stream_Mode;
- Back : in Stream_Access;
- Back_Compressed : in Boolean;
- Level : in Compression_Level := Default_Compression;
- Strategy : in Strategy_Type := Default_Strategy;
- Header : in Header_Type := Default;
- Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset
- := Default_Buffer_Size;
- Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset
- := Default_Buffer_Size)
- is
-
- subtype Buffer_Subtype is Stream_Element_Array (1 .. Read_Buffer_Size);
-
- procedure Init_Filter
- (Filter : in out Filter_Type;
- Compress : in Boolean);
-
- -----------------
- -- Init_Filter --
- -----------------
-
- procedure Init_Filter
- (Filter : in out Filter_Type;
- Compress : in Boolean) is
- begin
- if Compress then
- Deflate_Init
- (Filter, Level, Strategy, Header => Header);
- else
- Inflate_Init (Filter, Header => Header);
- end if;
- end Init_Filter;
-
- begin
- Stream.Back := Back;
- Stream.Mode := Mode;
-
- if Mode = Out_Stream or Mode = Duplex then
- Init_Filter (Stream.Writer, Back_Compressed);
- Stream.Buffer_Size := Write_Buffer_Size;
- else
- Stream.Buffer_Size := 0;
- end if;
-
- if Mode = In_Stream or Mode = Duplex then
- Init_Filter (Stream.Reader, not Back_Compressed);
-
- Stream.Buffer := new Buffer_Subtype;
- Stream.Rest_First := Stream.Buffer'Last + 1;
- Stream.Rest_Last := Stream.Buffer'Last;
- end if;
- end Create;
-
- -----------
- -- Flush --
- -----------
-
- procedure Flush
- (Stream : in out Stream_Type;
- Mode : in Flush_Mode := Sync_Flush)
- is
- Buffer : Stream_Element_Array (1 .. Stream.Buffer_Size);
- Last : Stream_Element_Offset;
- begin
- loop
- Flush (Stream.Writer, Buffer, Last, Mode);
-
- Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last));
-
- exit when Last < Buffer'Last;
- end loop;
- end Flush;
-
- -------------
- -- Is_Open --
- -------------
-
- function Is_Open (Stream : Stream_Type) return Boolean is
- begin
- return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer);
- end Is_Open;
-
- ----------
- -- Read --
- ----------
-
- procedure Read
- (Stream : in out Stream_Type;
- Item : out Stream_Element_Array;
- Last : out Stream_Element_Offset)
- is
-
- procedure Read
- (Item : out Stream_Element_Array;
- Last : out Stream_Element_Offset);
-
- ----------
- -- Read --
- ----------
-
- procedure Read
- (Item : out Stream_Element_Array;
- Last : out Stream_Element_Offset) is
- begin
- Ada.Streams.Read (Stream.Back.all, Item, Last);
- end Read;
-
- procedure Read is new ZLib.Read
- (Read => Read,
- Buffer => Stream.Buffer.all,
- Rest_First => Stream.Rest_First,
- Rest_Last => Stream.Rest_Last);
-
- begin
- Read (Stream.Reader, Item, Last);
- end Read;
-
- -------------------
- -- Read_Total_In --
- -------------------
-
- function Read_Total_In (Stream : in Stream_Type) return Count is
- begin
- return Total_In (Stream.Reader);
- end Read_Total_In;
-
- --------------------
- -- Read_Total_Out --
- --------------------
-
- function Read_Total_Out (Stream : in Stream_Type) return Count is
- begin
- return Total_Out (Stream.Reader);
- end Read_Total_Out;
-
- -----------
- -- Write --
- -----------
-
- procedure Write
- (Stream : in out Stream_Type;
- Item : in Stream_Element_Array)
- is
-
- procedure Write (Item : in Stream_Element_Array);
-
- -----------
- -- Write --
- -----------
-
- procedure Write (Item : in Stream_Element_Array) is
- begin
- Ada.Streams.Write (Stream.Back.all, Item);
- end Write;
-
- procedure Write is new ZLib.Write
- (Write => Write,
- Buffer_Size => Stream.Buffer_Size);
-
- begin
- Write (Stream.Writer, Item, No_Flush);
- end Write;
-
- --------------------
- -- Write_Total_In --
- --------------------
-
- function Write_Total_In (Stream : in Stream_Type) return Count is
- begin
- return Total_In (Stream.Writer);
- end Write_Total_In;
-
- ---------------------
- -- Write_Total_Out --
- ---------------------
-
- function Write_Total_Out (Stream : in Stream_Type) return Count is
- begin
- return Total_Out (Stream.Writer);
- end Write_Total_Out;
-
-end ZLib.Streams;
diff --git a/cpukit/zlib/contrib/ada/zlib-streams.ads b/cpukit/zlib/contrib/ada/zlib-streams.ads
deleted file mode 100644
index 7dcbf7e8b6..0000000000
--- a/cpukit/zlib/contrib/ada/zlib-streams.ads
+++ /dev/null
@@ -1,114 +0,0 @@
-----------------------------------------------------------------
--- ZLib for Ada thick binding. --
--- --
--- Copyright (C) 2002-2003 Dmitriy Anisimkov --
--- --
--- Open source license information is in the zlib.ads file. --
-----------------------------------------------------------------
-
--- $Id$
-
-package ZLib.Streams is
-
- type Stream_Mode is (In_Stream, Out_Stream, Duplex);
-
- type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
-
- type Stream_Type is
- new Ada.Streams.Root_Stream_Type with private;
-
- procedure Read
- (Stream : in out Stream_Type;
- Item : out Ada.Streams.Stream_Element_Array;
- Last : out Ada.Streams.Stream_Element_Offset);
-
- procedure Write
- (Stream : in out Stream_Type;
- Item : in Ada.Streams.Stream_Element_Array);
-
- procedure Flush
- (Stream : in out Stream_Type;
- Mode : in Flush_Mode := Sync_Flush);
- -- Flush the written data to the back stream,
- -- all data placed to the compressor is flushing to the Back stream.
- -- Should not be used untill necessary, becouse it is decreasing
- -- compression.
-
- function Read_Total_In (Stream : in Stream_Type) return Count;
- pragma Inline (Read_Total_In);
- -- Return total number of bytes read from back stream so far.
-
- function Read_Total_Out (Stream : in Stream_Type) return Count;
- pragma Inline (Read_Total_Out);
- -- Return total number of bytes read so far.
-
- function Write_Total_In (Stream : in Stream_Type) return Count;
- pragma Inline (Write_Total_In);
- -- Return total number of bytes written so far.
-
- function Write_Total_Out (Stream : in Stream_Type) return Count;
- pragma Inline (Write_Total_Out);
- -- Return total number of bytes written to the back stream.
-
- procedure Create
- (Stream : out Stream_Type;
- Mode : in Stream_Mode;
- Back : in Stream_Access;
- Back_Compressed : in Boolean;
- Level : in Compression_Level := Default_Compression;
- Strategy : in Strategy_Type := Default_Strategy;
- Header : in Header_Type := Default;
- Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset
- := Default_Buffer_Size;
- Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset
- := Default_Buffer_Size);
- -- Create the Comression/Decompression stream.
- -- If mode is In_Stream then Write operation is disabled.
- -- If mode is Out_Stream then Read operation is disabled.
-
- -- If Back_Compressed is true then
- -- Data written to the Stream is compressing to the Back stream
- -- and data read from the Stream is decompressed data from the Back stream.
-
- -- If Back_Compressed is false then
- -- Data written to the Stream is decompressing to the Back stream
- -- and data read from the Stream is compressed data from the Back stream.
-
- -- !!! When the Need_Header is False ZLib-Ada is using undocumented
- -- ZLib 1.1.4 functionality to do not create/wait for ZLib headers.
-
- function Is_Open (Stream : Stream_Type) return Boolean;
-
- procedure Close (Stream : in out Stream_Type);
-
-private
-
- use Ada.Streams;
-
- type Buffer_Access is access all Stream_Element_Array;
-
- type Stream_Type
- is new Root_Stream_Type with
- record
- Mode : Stream_Mode;
-
- Buffer : Buffer_Access;
- Rest_First : Stream_Element_Offset;
- Rest_Last : Stream_Element_Offset;
- -- Buffer for Read operation.
- -- We need to have this buffer in the record
- -- becouse not all read data from back stream
- -- could be processed during the read operation.
-
- Buffer_Size : Stream_Element_Offset;
- -- Buffer size for write operation.
- -- We do not need to have this buffer
- -- in the record becouse all data could be
- -- processed in the write operation.
-
- Back : Stream_Access;
- Reader : Filter_Type;
- Writer : Filter_Type;
- end record;
-
-end ZLib.Streams;
diff --git a/cpukit/zlib/contrib/ada/zlib-thin.adb b/cpukit/zlib/contrib/ada/zlib-thin.adb
deleted file mode 100644
index 30924ed7ab..0000000000
--- a/cpukit/zlib/contrib/ada/zlib-thin.adb
+++ /dev/null
@@ -1,141 +0,0 @@
-----------------------------------------------------------------
--- ZLib for Ada thick binding. --
--- --
--- Copyright (C) 2002-2003 Dmitriy Anisimkov --
--- --
--- Open source license information is in the zlib.ads file. --
-----------------------------------------------------------------
-
--- $Id$
-
-package body ZLib.Thin is
-
- ZLIB_VERSION : constant Chars_Ptr := zlibVersion;
-
- Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit;
-
- --------------
- -- Avail_In --
- --------------
-
- function Avail_In (Strm : in Z_Stream) return UInt is
- begin
- return Strm.Avail_In;
- end Avail_In;
-
- ---------------
- -- Avail_Out --
- ---------------
-
- function Avail_Out (Strm : in Z_Stream) return UInt is
- begin
- return Strm.Avail_Out;
- end Avail_Out;
-
- ------------------
- -- Deflate_Init --
- ------------------
-
- function Deflate_Init
- (strm : Z_Streamp;
- level : Int;
- method : Int;
- windowBits : Int;
- memLevel : Int;
- strategy : Int)
- return Int is
- begin
- return deflateInit2
- (strm,
- level,
- method,
- windowBits,
- memLevel,
- strategy,
- ZLIB_VERSION,
- Z_Stream_Size);
- end Deflate_Init;
-
- ------------------
- -- Inflate_Init --
- ------------------
-
- function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is
- begin
- return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size);
- end Inflate_Init;
-
- ------------------------
- -- Last_Error_Message --
- ------------------------
-
- function Last_Error_Message (Strm : in Z_Stream) return String is
- use Interfaces.C.Strings;
- begin
- if Strm.msg = Null_Ptr then
- return "";
- else
- return Value (Strm.msg);
- end if;
- end Last_Error_Message;
-
- ------------
- -- Set_In --
- ------------
-
- procedure Set_In
- (Strm : in out Z_Stream;
- Buffer : in Voidp;
- Size : in UInt) is
- begin
- Strm.Next_In := Buffer;
- Strm.Avail_In := Size;
- end Set_In;
-
- ------------------
- -- Set_Mem_Func --
- ------------------
-
- procedure Set_Mem_Func
- (Strm : in out Z_Stream;
- Opaque : in Voidp;
- Alloc : in alloc_func;
- Free : in free_func) is
- begin
- Strm.opaque := Opaque;
- Strm.zalloc := Alloc;
- Strm.zfree := Free;
- end Set_Mem_Func;
-
- -------------
- -- Set_Out --
- -------------
-
- procedure Set_Out
- (Strm : in out Z_Stream;
- Buffer : in Voidp;
- Size : in UInt) is
- begin
- Strm.Next_Out := Buffer;
- Strm.Avail_Out := Size;
- end Set_Out;
-
- --------------
- -- Total_In --
- --------------
-
- function Total_In (Strm : in Z_Stream) return ULong is
- begin
- return Strm.Total_In;
- end Total_In;
-
- ---------------
- -- Total_Out --
- ---------------
-
- function Total_Out (Strm : in Z_Stream) return ULong is
- begin
- return Strm.Total_Out;
- end Total_Out;
-
-end ZLib.Thin;
diff --git a/cpukit/zlib/contrib/ada/zlib-thin.ads b/cpukit/zlib/contrib/ada/zlib-thin.ads
deleted file mode 100644
index 2bc085f0aa..0000000000
--- a/cpukit/zlib/contrib/ada/zlib-thin.ads
+++ /dev/null
@@ -1,450 +0,0 @@
-----------------------------------------------------------------
--- ZLib for Ada thick binding. --
--- --
--- Copyright (C) 2002-2003 Dmitriy Anisimkov --
--- --
--- Open source license information is in the zlib.ads file. --
-----------------------------------------------------------------
-
--- $Id$
-
-with Interfaces.C.Strings;
-
-with System;
-
-private package ZLib.Thin is
-
- -- From zconf.h
-
- MAX_MEM_LEVEL : constant := 9; -- zconf.h:105
- -- zconf.h:105
- MAX_WBITS : constant := 15; -- zconf.h:115
- -- 32K LZ77 window
- -- zconf.h:115
- SEEK_SET : constant := 8#0000#; -- zconf.h:244
- -- Seek from beginning of file.
- -- zconf.h:244
- SEEK_CUR : constant := 1; -- zconf.h:245
- -- Seek from current position.
- -- zconf.h:245
- SEEK_END : constant := 2; -- zconf.h:246
- -- Set file pointer to EOF plus "offset"
- -- zconf.h:246
-
- type Byte is new Interfaces.C.unsigned_char; -- 8 bits
- -- zconf.h:214
- type UInt is new Interfaces.C.unsigned; -- 16 bits or more
- -- zconf.h:216
- type Int is new Interfaces.C.int;
-
- type ULong is new Interfaces.C.unsigned_long; -- 32 bits or more
- -- zconf.h:217
- subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr;
-
- type ULong_Access is access ULong;
- type Int_Access is access Int;
-
- subtype Voidp is System.Address; -- zconf.h:232
-
- subtype Byte_Access is Voidp;
-
- Nul : constant Voidp := System.Null_Address;
- -- end from zconf
-
- Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125
- -- zlib.h:125
- Z_PARTIAL_FLUSH : constant := 1; -- zlib.h:126
- -- will be removed, use
- -- Z_SYNC_FLUSH instead
- -- zlib.h:126
- Z_SYNC_FLUSH : constant := 2; -- zlib.h:127
- -- zlib.h:127
- Z_FULL_FLUSH : constant := 3; -- zlib.h:128
- -- zlib.h:128
- Z_FINISH : constant := 4; -- zlib.h:129
- -- zlib.h:129
- Z_OK : constant := 8#0000#; -- zlib.h:132
- -- zlib.h:132
- Z_STREAM_END : constant := 1; -- zlib.h:133
- -- zlib.h:133
- Z_NEED_DICT : constant := 2; -- zlib.h:134
- -- zlib.h:134
- Z_ERRNO : constant := -1; -- zlib.h:135
- -- zlib.h:135
- Z_STREAM_ERROR : constant := -2; -- zlib.h:136
- -- zlib.h:136
- Z_DATA_ERROR : constant := -3; -- zlib.h:137
- -- zlib.h:137
- Z_MEM_ERROR : constant := -4; -- zlib.h:138
- -- zlib.h:138
- Z_BUF_ERROR : constant := -5; -- zlib.h:139
- -- zlib.h:139
- Z_VERSION_ERROR : constant := -6; -- zlib.h:140
- -- zlib.h:140
- Z_NO_COMPRESSION : constant := 8#0000#; -- zlib.h:145
- -- zlib.h:145
- Z_BEST_SPEED : constant := 1; -- zlib.h:146
- -- zlib.h:146
- Z_BEST_COMPRESSION : constant := 9; -- zlib.h:147
- -- zlib.h:147
- Z_DEFAULT_COMPRESSION : constant := -1; -- zlib.h:148
- -- zlib.h:148
- Z_FILTERED : constant := 1; -- zlib.h:151
- -- zlib.h:151
- Z_HUFFMAN_ONLY : constant := 2; -- zlib.h:152
- -- zlib.h:152
- Z_DEFAULT_STRATEGY : constant := 8#0000#; -- zlib.h:153
- -- zlib.h:153
- Z_BINARY : constant := 8#0000#; -- zlib.h:156
- -- zlib.h:156
- Z_ASCII : constant := 1; -- zlib.h:157
- -- zlib.h:157
- Z_UNKNOWN : constant := 2; -- zlib.h:158
- -- zlib.h:158
- Z_DEFLATED : constant := 8; -- zlib.h:161
- -- zlib.h:161
- Z_NULL : constant := 8#0000#; -- zlib.h:164
- -- for initializing zalloc, zfree, opaque
- -- zlib.h:164
- type gzFile is new Voidp; -- zlib.h:646
-
- type Z_Stream is private;
-
- type Z_Streamp is access all Z_Stream; -- zlib.h:89
-
- type alloc_func is access function
- (Opaque : Voidp;
- Items : UInt;
- Size : UInt)
- return Voidp; -- zlib.h:63
-
- type free_func is access procedure (opaque : Voidp; address : Voidp);
-
- function zlibVersion return Chars_Ptr;
-
- function Deflate (strm : Z_Streamp; flush : Int) return Int;
-
- function DeflateEnd (strm : Z_Streamp) return Int;
-
- function Inflate (strm : Z_Streamp; flush : Int) return Int;
-
- function InflateEnd (strm : Z_Streamp) return Int;
-
- function deflateSetDictionary
- (strm : Z_Streamp;
- dictionary : Byte_Access;
- dictLength : UInt)
- return Int;
-
- function deflateCopy (dest : Z_Streamp; source : Z_Streamp) return Int;
- -- zlib.h:478
-
- function deflateReset (strm : Z_Streamp) return Int; -- zlib.h:495
-
- function deflateParams
- (strm : Z_Streamp;
- level : Int;
- strategy : Int)
- return Int; -- zlib.h:506
-
- function inflateSetDictionary
- (strm : Z_Streamp;
- dictionary : Byte_Access;
- dictLength : UInt)
- return Int; -- zlib.h:548
-
- function inflateSync (strm : Z_Streamp) return Int; -- zlib.h:565
-
- function inflateReset (strm : Z_Streamp) return Int; -- zlib.h:580
-
- function compress
- (dest : Byte_Access;
- destLen : ULong_Access;
- source : Byte_Access;
- sourceLen : ULong)
- return Int; -- zlib.h:601
-
- function compress2
- (dest : Byte_Access;
- destLen : ULong_Access;
- source : Byte_Access;
- sourceLen : ULong;
- level : Int)
- return Int; -- zlib.h:615
-
- function uncompress
- (dest : Byte_Access;
- destLen : ULong_Access;
- source : Byte_Access;
- sourceLen : ULong)
- return Int;
-
- function gzopen (path : Chars_Ptr; mode : Chars_Ptr) return gzFile;
-
- function gzdopen (fd : Int; mode : Chars_Ptr) return gzFile;
-
- function gzsetparams
- (file : gzFile;
- level : Int;
- strategy : Int)
- return Int;
-
- function gzread
- (file : gzFile;
- buf : Voidp;
- len : UInt)
- return Int;
-
- function gzwrite
- (file : in gzFile;
- buf : in Voidp;
- len : in UInt)
- return Int;
-
- function gzprintf (file : in gzFile; format : in Chars_Ptr) return Int;
-
- function gzputs (file : in gzFile; s : in Chars_Ptr) return Int;
-
- function gzgets
- (file : gzFile;
- buf : Chars_Ptr;
- len : Int)
- return Chars_Ptr;
-
- function gzputc (file : gzFile; char : Int) return Int;
-
- function gzgetc (file : gzFile) return Int;
-
- function gzflush (file : gzFile; flush : Int) return Int;
-
- function gzseek
- (file : gzFile;
- offset : Int;
- whence : Int)
- return Int;
-
- function gzrewind (file : gzFile) return Int;
-
- function gztell (file : gzFile) return Int;
-
- function gzeof (file : gzFile) return Int;
-
- function gzclose (file : gzFile) return Int;
-
- function gzerror (file : gzFile; errnum : Int_Access) return Chars_Ptr;
-
- function adler32
- (adler : ULong;
- buf : Byte_Access;
- len : UInt)
- return ULong;
-
- function crc32
- (crc : ULong;
- buf : Byte_Access;
- len : UInt)
- return ULong;
-
- function deflateInit
- (strm : Z_Streamp;
- level : Int;
- version : Chars_Ptr;
- stream_size : Int)
- return Int;
-
- function deflateInit2
- (strm : Z_Streamp;
- level : Int;
- method : Int;
- windowBits : Int;
- memLevel : Int;
- strategy : Int;
- version : Chars_Ptr;
- stream_size : Int)
- return Int;
-
- function Deflate_Init
- (strm : Z_Streamp;
- level : Int;
- method : Int;
- windowBits : Int;
- memLevel : Int;
- strategy : Int)
- return Int;
- pragma Inline (Deflate_Init);
-
- function inflateInit
- (strm : Z_Streamp;
- version : Chars_Ptr;
- stream_size : Int)
- return Int;
-
- function inflateInit2
- (strm : in Z_Streamp;
- windowBits : in Int;
- version : in Chars_Ptr;
- stream_size : in Int)
- return Int;
-
- function inflateBackInit
- (strm : in Z_Streamp;
- windowBits : in Int;
- window : in Byte_Access;
- version : in Chars_Ptr;
- stream_size : in Int)
- return Int;
- -- Size of window have to be 2**windowBits.
-
- function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int;
- pragma Inline (Inflate_Init);
-
- function zError (err : Int) return Chars_Ptr;
-
- function inflateSyncPoint (z : Z_Streamp) return Int;
-
- function get_crc_table return ULong_Access;
-
- -- Interface to the available fields of the z_stream structure.
- -- The application must update next_in and avail_in when avail_in has
- -- dropped to zero. It must update next_out and avail_out when avail_out
- -- has dropped to zero. The application must initialize zalloc, zfree and
- -- opaque before calling the init function.
-
- procedure Set_In
- (Strm : in out Z_Stream;
- Buffer : in Voidp;
- Size : in UInt);
- pragma Inline (Set_In);
-
- procedure Set_Out
- (Strm : in out Z_Stream;
- Buffer : in Voidp;
- Size : in UInt);
- pragma Inline (Set_Out);
-
- procedure Set_Mem_Func
- (Strm : in out Z_Stream;
- Opaque : in Voidp;
- Alloc : in alloc_func;
- Free : in free_func);
- pragma Inline (Set_Mem_Func);
-
- function Last_Error_Message (Strm : in Z_Stream) return String;
- pragma Inline (Last_Error_Message);
-
- function Avail_Out (Strm : in Z_Stream) return UInt;
- pragma Inline (Avail_Out);
-
- function Avail_In (Strm : in Z_Stream) return UInt;
- pragma Inline (Avail_In);
-
- function Total_In (Strm : in Z_Stream) return ULong;
- pragma Inline (Total_In);
-
- function Total_Out (Strm : in Z_Stream) return ULong;
- pragma Inline (Total_Out);
-
- function inflateCopy
- (dest : in Z_Streamp;
- Source : in Z_Streamp)
- return Int;
-
- function compressBound (Source_Len : in ULong) return ULong;
-
- function deflateBound
- (Strm : in Z_Streamp;
- Source_Len : in ULong)
- return ULong;
-
- function gzungetc (C : in Int; File : in gzFile) return Int;
-
- function zlibCompileFlags return ULong;
-
-private
-
- type Z_Stream is record -- zlib.h:68
- Next_In : Voidp := Nul; -- next input byte
- Avail_In : UInt := 0; -- number of bytes available at next_in
- Total_In : ULong := 0; -- total nb of input bytes read so far
- Next_Out : Voidp := Nul; -- next output byte should be put there
- Avail_Out : UInt := 0; -- remaining free space at next_out
- Total_Out : ULong := 0; -- total nb of bytes output so far
- msg : Chars_Ptr; -- last error message, NULL if no error
- state : Voidp; -- not visible by applications
- zalloc : alloc_func := null; -- used to allocate the internal state
- zfree : free_func := null; -- used to free the internal state
- opaque : Voidp; -- private data object passed to
- -- zalloc and zfree
- data_type : Int; -- best guess about the data type:
- -- ascii or binary
- adler : ULong; -- adler32 value of the uncompressed
- -- data
- reserved : ULong; -- reserved for future use
- end record;
-
- pragma Convention (C, Z_Stream);
-
- pragma Import (C, zlibVersion, "zlibVersion");
- pragma Import (C, Deflate, "deflate");
- pragma Import (C, DeflateEnd, "deflateEnd");
- pragma Import (C, Inflate, "inflate");
- pragma Import (C, InflateEnd, "inflateEnd");
- pragma Import (C, deflateSetDictionary, "deflateSetDictionary");
- pragma Import (C, deflateCopy, "deflateCopy");
- pragma Import (C, deflateReset, "deflateReset");
- pragma Import (C, deflateParams, "deflateParams");
- pragma Import (C, inflateSetDictionary, "inflateSetDictionary");
- pragma Import (C, inflateSync, "inflateSync");
- pragma Import (C, inflateReset, "inflateReset");
- pragma Import (C, compress, "compress");
- pragma Import (C, compress2, "compress2");
- pragma Import (C, uncompress, "uncompress");
- pragma Import (C, gzopen, "gzopen");
- pragma Import (C, gzdopen, "gzdopen");
- pragma Import (C, gzsetparams, "gzsetparams");
- pragma Import (C, gzread, "gzread");
- pragma Import (C, gzwrite, "gzwrite");
- pragma Import (C, gzprintf, "gzprintf");
- pragma Import (C, gzputs, "gzputs");
- pragma Import (C, gzgets, "gzgets");
- pragma Import (C, gzputc, "gzputc");
- pragma Import (C, gzgetc, "gzgetc");
- pragma Import (C, gzflush, "gzflush");
- pragma Import (C, gzseek, "gzseek");
- pragma Import (C, gzrewind, "gzrewind");
- pragma Import (C, gztell, "gztell");
- pragma Import (C, gzeof, "gzeof");
- pragma Import (C, gzclose, "gzclose");
- pragma Import (C, gzerror, "gzerror");
- pragma Import (C, adler32, "adler32");
- pragma Import (C, crc32, "crc32");
- pragma Import (C, deflateInit, "deflateInit_");
- pragma Import (C, inflateInit, "inflateInit_");
- pragma Import (C, deflateInit2, "deflateInit2_");
- pragma Import (C, inflateInit2, "inflateInit2_");
- pragma Import (C, zError, "zError");
- pragma Import (C, inflateSyncPoint, "inflateSyncPoint");
- pragma Import (C, get_crc_table, "get_crc_table");
-
- -- since zlib 1.2.0:
-
- pragma Import (C, inflateCopy, "inflateCopy");
- pragma Import (C, compressBound, "compressBound");
- pragma Import (C, deflateBound, "deflateBound");
- pragma Import (C, gzungetc, "gzungetc");
- pragma Import (C, zlibCompileFlags, "zlibCompileFlags");
-
- pragma Import (C, inflateBackInit, "inflateBackInit_");
-
- -- I stopped binding the inflateBack routines, becouse realize that
- -- it does not support zlib and gzip headers for now, and have no
- -- symmetric deflateBack routines.
- -- ZLib-Ada is symmetric regarding deflate/inflate data transformation
- -- and has a similar generic callback interface for the
- -- deflate/inflate transformation based on the regular Deflate/Inflate
- -- routines.
-
- -- pragma Import (C, inflateBack, "inflateBack");
- -- pragma Import (C, inflateBackEnd, "inflateBackEnd");
-
-end ZLib.Thin;
diff --git a/cpukit/zlib/contrib/ada/zlib.adb b/cpukit/zlib/contrib/ada/zlib.adb
deleted file mode 100644
index 8927b48f1b..0000000000
--- a/cpukit/zlib/contrib/ada/zlib.adb
+++ /dev/null
@@ -1,701 +0,0 @@
-----------------------------------------------------------------
--- ZLib for Ada thick binding. --
--- --
--- Copyright (C) 2002-2004 Dmitriy Anisimkov --
--- --
--- Open source license information is in the zlib.ads file. --
-----------------------------------------------------------------
-
--- $Id$
-
-with Ada.Exceptions;
-with Ada.Unchecked_Conversion;
-with Ada.Unchecked_Deallocation;
-
-with Interfaces.C.Strings;
-
-with ZLib.Thin;
-
-package body ZLib is
-
- use type Thin.Int;
-
- type Z_Stream is new Thin.Z_Stream;
-
- type Return_Code_Enum is
- (OK,
- STREAM_END,
- NEED_DICT,
- ERRNO,
- STREAM_ERROR,
- DATA_ERROR,
- MEM_ERROR,
- BUF_ERROR,
- VERSION_ERROR);
-
- type Flate_Step_Function is access
- function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int;
- pragma Convention (C, Flate_Step_Function);
-
- type Flate_End_Function is access
- function (Ctrm : in Thin.Z_Streamp) return Thin.Int;
- pragma Convention (C, Flate_End_Function);
-
- type Flate_Type is record
- Step : Flate_Step_Function;
- Done : Flate_End_Function;
- end record;
-
- subtype Footer_Array is Stream_Element_Array (1 .. 8);
-
- Simple_GZip_Header : constant Stream_Element_Array (1 .. 10)
- := (16#1f#, 16#8b#, -- Magic header
- 16#08#, -- Z_DEFLATED
- 16#00#, -- Flags
- 16#00#, 16#00#, 16#00#, 16#00#, -- Time
- 16#00#, -- XFlags
- 16#03# -- OS code
- );
- -- The simplest gzip header is not for informational, but just for
- -- gzip format compatibility.
- -- Note that some code below is using assumption
- -- Simple_GZip_Header'Last > Footer_Array'Last, so do not make
- -- Simple_GZip_Header'Last <= Footer_Array'Last.
-
- Return_Code : constant array (Thin.Int range <>) of Return_Code_Enum
- := (0 => OK,
- 1 => STREAM_END,
- 2 => NEED_DICT,
- -1 => ERRNO,
- -2 => STREAM_ERROR,
- -3 => DATA_ERROR,
- -4 => MEM_ERROR,
- -5 => BUF_ERROR,
- -6 => VERSION_ERROR);
-
- Flate : constant array (Boolean) of Flate_Type
- := (True => (Step => Thin.Deflate'Access,
- Done => Thin.DeflateEnd'Access),
- False => (Step => Thin.Inflate'Access,
- Done => Thin.InflateEnd'Access));
-
- Flush_Finish : constant array (Boolean) of Flush_Mode
- := (True => Finish, False => No_Flush);
-
- procedure Raise_Error (Stream : in Z_Stream);
- pragma Inline (Raise_Error);
-
- procedure Raise_Error (Message : in String);
- pragma Inline (Raise_Error);
-
- procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int);
-
- procedure Free is new Ada.Unchecked_Deallocation
- (Z_Stream, Z_Stream_Access);
-
- function To_Thin_Access is new Ada.Unchecked_Conversion
- (Z_Stream_Access, Thin.Z_Streamp);
-
- procedure Translate_GZip
- (Filter : in out Filter_Type;
- In_Data : in Ada.Streams.Stream_Element_Array;
- In_Last : out Ada.Streams.Stream_Element_Offset;
- Out_Data : out Ada.Streams.Stream_Element_Array;
- Out_Last : out Ada.Streams.Stream_Element_Offset;
- Flush : in Flush_Mode);
- -- Separate translate routine for make gzip header.
-
- procedure Translate_Auto
- (Filter : in out Filter_Type;
- In_Data : in Ada.Streams.Stream_Element_Array;
- In_Last : out Ada.Streams.Stream_Element_Offset;
- Out_Data : out Ada.Streams.Stream_Element_Array;
- Out_Last : out Ada.Streams.Stream_Element_Offset;
- Flush : in Flush_Mode);
- -- translate routine without additional headers.
-
- -----------------
- -- Check_Error --
- -----------------
-
- procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is
- use type Thin.Int;
- begin
- if Code /= Thin.Z_OK then
- Raise_Error
- (Return_Code_Enum'Image (Return_Code (Code))
- & ": " & Last_Error_Message (Stream));
- end if;
- end Check_Error;
-
- -----------
- -- Close --
- -----------
-
- procedure Close
- (Filter : in out Filter_Type;
- Ignore_Error : in Boolean := False)
- is
- Code : Thin.Int;
- begin
- if not Ignore_Error and then not Is_Open (Filter) then
- raise Status_Error;
- end if;
-
- Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm));
-
- if Ignore_Error or else Code = Thin.Z_OK then
- Free (Filter.Strm);
- else
- declare
- Error_Message : constant String
- := Last_Error_Message (Filter.Strm.all);
- begin
- Free (Filter.Strm);
- Ada.Exceptions.Raise_Exception
- (ZLib_Error'Identity,
- Return_Code_Enum'Image (Return_Code (Code))
- & ": " & Error_Message);
- end;
- end if;
- end Close;
-
- -----------
- -- CRC32 --
- -----------
-
- function CRC32
- (CRC : in Unsigned_32;
- Data : in Ada.Streams.Stream_Element_Array)
- return Unsigned_32
- is
- use Thin;
- begin
- return Unsigned_32 (crc32 (ULong (CRC),
- Data'Address,
- Data'Length));
- end CRC32;
-
- procedure CRC32
- (CRC : in out Unsigned_32;
- Data : in Ada.Streams.Stream_Element_Array) is
- begin
- CRC := CRC32 (CRC, Data);
- end CRC32;
-
- ------------------
- -- Deflate_Init --
- ------------------
-
- procedure Deflate_Init
- (Filter : in out Filter_Type;
- Level : in Compression_Level := Default_Compression;
- Strategy : in Strategy_Type := Default_Strategy;
- Method : in Compression_Method := Deflated;
- Window_Bits : in Window_Bits_Type := Default_Window_Bits;
- Memory_Level : in Memory_Level_Type := Default_Memory_Level;
- Header : in Header_Type := Default)
- is
- use type Thin.Int;
- Win_Bits : Thin.Int := Thin.Int (Window_Bits);
- begin
- if Is_Open (Filter) then
- raise Status_Error;
- end if;
-
- -- We allow ZLib to make header only in case of default header type.
- -- Otherwise we would either do header by ourselfs, or do not do
- -- header at all.
-
- if Header = None or else Header = GZip then
- Win_Bits := -Win_Bits;
- end if;
-
- -- For the GZip CRC calculation and make headers.
-
- if Header = GZip then
- Filter.CRC := 0;
- Filter.Offset := Simple_GZip_Header'First;
- else
- Filter.Offset := Simple_GZip_Header'Last + 1;
- end if;
-
- Filter.Strm := new Z_Stream;
- Filter.Compression := True;
- Filter.Stream_End := False;
- Filter.Header := Header;
-
- if Thin.Deflate_Init
- (To_Thin_Access (Filter.Strm),
- Level => Thin.Int (Level),
- method => Thin.Int (Method),
- windowBits => Win_Bits,
- memLevel => Thin.Int (Memory_Level),
- strategy => Thin.Int (Strategy)) /= Thin.Z_OK
- then
- Raise_Error (Filter.Strm.all);
- end if;
- end Deflate_Init;
-
- -----------
- -- Flush --
- -----------
-
- procedure Flush
- (Filter : in out Filter_Type;
- Out_Data : out Ada.Streams.Stream_Element_Array;
- Out_Last : out Ada.Streams.Stream_Element_Offset;
- Flush : in Flush_Mode)
- is
- No_Data : Stream_Element_Array := (1 .. 0 => 0);
- Last : Stream_Element_Offset;
- begin
- Translate (Filter, No_Data, Last, Out_Data, Out_Last, Flush);
- end Flush;
-
- -----------------------
- -- Generic_Translate --
- -----------------------
-
- procedure Generic_Translate
- (Filter : in out ZLib.Filter_Type;
- In_Buffer_Size : in Integer := Default_Buffer_Size;
- Out_Buffer_Size : in Integer := Default_Buffer_Size)
- is
- In_Buffer : Stream_Element_Array
- (1 .. Stream_Element_Offset (In_Buffer_Size));
- Out_Buffer : Stream_Element_Array
- (1 .. Stream_Element_Offset (Out_Buffer_Size));
- Last : Stream_Element_Offset;
- In_Last : Stream_Element_Offset;
- In_First : Stream_Element_Offset;
- Out_Last : Stream_Element_Offset;
- begin
- Main : loop
- Data_In (In_Buffer, Last);
-
- In_First := In_Buffer'First;
-
- loop
- Translate
- (Filter => Filter,
- In_Data => In_Buffer (In_First .. Last),
- In_Last => In_Last,
- Out_Data => Out_Buffer,
- Out_Last => Out_Last,
- Flush => Flush_Finish (Last < In_Buffer'First));
-
- if Out_Buffer'First <= Out_Last then
- Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last));
- end if;
-
- exit Main when Stream_End (Filter);
-
- -- The end of in buffer.
-
- exit when In_Last = Last;
-
- In_First := In_Last + 1;
- end loop;
- end loop Main;
-
- end Generic_Translate;
-
- ------------------
- -- Inflate_Init --
- ------------------
-
- procedure Inflate_Init
- (Filter : in out Filter_Type;
- Window_Bits : in Window_Bits_Type := Default_Window_Bits;
- Header : in Header_Type := Default)
- is
- use type Thin.Int;
- Win_Bits : Thin.Int := Thin.Int (Window_Bits);
-
- procedure Check_Version;
- -- Check the latest header types compatibility.
-
- procedure Check_Version is
- begin
- if Version <= "1.1.4" then
- Raise_Error
- ("Inflate header type " & Header_Type'Image (Header)
- & " incompatible with ZLib version " & Version);
- end if;
- end Check_Version;
-
- begin
- if Is_Open (Filter) then
- raise Status_Error;
- end if;
-
- case Header is
- when None =>
- Check_Version;
-
- -- Inflate data without headers determined
- -- by negative Win_Bits.
-
- Win_Bits := -Win_Bits;
- when GZip =>
- Check_Version;
-
- -- Inflate gzip data defined by flag 16.
-
- Win_Bits := Win_Bits + 16;
- when Auto =>
- Check_Version;
-
- -- Inflate with automatic detection
- -- of gzip or native header defined by flag 32.
-
- Win_Bits := Win_Bits + 32;
- when Default => null;
- end case;
-
- Filter.Strm := new Z_Stream;
- Filter.Compression := False;
- Filter.Stream_End := False;
- Filter.Header := Header;
-
- if Thin.Inflate_Init
- (To_Thin_Access (Filter.Strm), Win_Bits) /= Thin.Z_OK
- then
- Raise_Error (Filter.Strm.all);
- end if;
- end Inflate_Init;
-
- -------------
- -- Is_Open --
- -------------
-
- function Is_Open (Filter : in Filter_Type) return Boolean is
- begin
- return Filter.Strm /= null;
- end Is_Open;
-
- -----------------
- -- Raise_Error --
- -----------------
-
- procedure Raise_Error (Message : in String) is
- begin
- Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message);
- end Raise_Error;
-
- procedure Raise_Error (Stream : in Z_Stream) is
- begin
- Raise_Error (Last_Error_Message (Stream));
- end Raise_Error;
-
- ----------
- -- Read --
- ----------
-
- procedure Read
- (Filter : in out Filter_Type;
- Item : out Ada.Streams.Stream_Element_Array;
- Last : out Ada.Streams.Stream_Element_Offset;
- Flush : in Flush_Mode := No_Flush)
- is
- In_Last : Stream_Element_Offset;
- Item_First : Ada.Streams.Stream_Element_Offset := Item'First;
- V_Flush : Flush_Mode := Flush;
-
- begin
- pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1);
- pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last);
-
- loop
- if Rest_Last = Buffer'First - 1 then
- V_Flush := Finish;
-
- elsif Rest_First > Rest_Last then
- Read (Buffer, Rest_Last);
- Rest_First := Buffer'First;
-
- if Rest_Last < Buffer'First then
- V_Flush := Finish;
- end if;
- end if;
-
- Translate
- (Filter => Filter,
- In_Data => Buffer (Rest_First .. Rest_Last),
- In_Last => In_Last,
- Out_Data => Item (Item_First .. Item'Last),
- Out_Last => Last,
- Flush => V_Flush);
-
- Rest_First := In_Last + 1;
-
- exit when Stream_End (Filter)
- or else Last = Item'Last
- or else (Last >= Item'First and then Allow_Read_Some);
-
- Item_First := Last + 1;
- end loop;
- end Read;
-
- ----------------
- -- Stream_End --
- ----------------
-
- function Stream_End (Filter : in Filter_Type) return Boolean is
- begin
- if Filter.Header = GZip and Filter.Compression then
- return Filter.Stream_End
- and then Filter.Offset = Footer_Array'Last + 1;
- else
- return Filter.Stream_End;
- end if;
- end Stream_End;
-
- --------------
- -- Total_In --
- --------------
-
- function Total_In (Filter : in Filter_Type) return Count is
- begin
- return Count (Thin.Total_In (To_Thin_Access (Filter.Strm).all));
- end Total_In;
-
- ---------------
- -- Total_Out --
- ---------------
-
- function Total_Out (Filter : in Filter_Type) return Count is
- begin
- return Count (Thin.Total_Out (To_Thin_Access (Filter.Strm).all));
- end Total_Out;
-
- ---------------
- -- Translate --
- ---------------
-
- procedure Translate
- (Filter : in out Filter_Type;
- In_Data : in Ada.Streams.Stream_Element_Array;
- In_Last : out Ada.Streams.Stream_Element_Offset;
- Out_Data : out Ada.Streams.Stream_Element_Array;
- Out_Last : out Ada.Streams.Stream_Element_Offset;
- Flush : in Flush_Mode) is
- begin
- if Filter.Header = GZip and then Filter.Compression then
- Translate_GZip
- (Filter => Filter,
- In_Data => In_Data,
- In_Last => In_Last,
- Out_Data => Out_Data,
- Out_Last => Out_Last,
- Flush => Flush);
- else
- Translate_Auto
- (Filter => Filter,
- In_Data => In_Data,
- In_Last => In_Last,
- Out_Data => Out_Data,
- Out_Last => Out_Last,
- Flush => Flush);
- end if;
- end Translate;
-
- --------------------
- -- Translate_Auto --
- --------------------
-
- procedure Translate_Auto
- (Filter : in out Filter_Type;
- In_Data : in Ada.Streams.Stream_Element_Array;
- In_Last : out Ada.Streams.Stream_Element_Offset;
- Out_Data : out Ada.Streams.Stream_Element_Array;
- Out_Last : out Ada.Streams.Stream_Element_Offset;
- Flush : in Flush_Mode)
- is
- use type Thin.Int;
- Code : Thin.Int;
-
- begin
- if not Is_Open (Filter) then
- raise Status_Error;
- end if;
-
- if Out_Data'Length = 0 and then In_Data'Length = 0 then
- raise Constraint_Error;
- end if;
-
- Set_Out (Filter.Strm.all, Out_Data'Address, Out_Data'Length);
- Set_In (Filter.Strm.all, In_Data'Address, In_Data'Length);
-
- Code := Flate (Filter.Compression).Step
- (To_Thin_Access (Filter.Strm),
- Thin.Int (Flush));
-
- if Code = Thin.Z_STREAM_END then
- Filter.Stream_End := True;
- else
- Check_Error (Filter.Strm.all, Code);
- end if;
-
- In_Last := In_Data'Last
- - Stream_Element_Offset (Avail_In (Filter.Strm.all));
- Out_Last := Out_Data'Last
- - Stream_Element_Offset (Avail_Out (Filter.Strm.all));
- end Translate_Auto;
-
- --------------------
- -- Translate_GZip --
- --------------------
-
- procedure Translate_GZip
- (Filter : in out Filter_Type;
- In_Data : in Ada.Streams.Stream_Element_Array;
- In_Last : out Ada.Streams.Stream_Element_Offset;
- Out_Data : out Ada.Streams.Stream_Element_Array;
- Out_Last : out Ada.Streams.Stream_Element_Offset;
- Flush : in Flush_Mode)
- is
- Out_First : Stream_Element_Offset;
-
- procedure Add_Data (Data : in Stream_Element_Array);
- -- Add data to stream from the Filter.Offset till necessary,
- -- used for add gzip headr/footer.
-
- procedure Put_32
- (Item : in out Stream_Element_Array;
- Data : in Unsigned_32);
- pragma Inline (Put_32);
-
- --------------
- -- Add_Data --
- --------------
-
- procedure Add_Data (Data : in Stream_Element_Array) is
- Data_First : Stream_Element_Offset renames Filter.Offset;
- Data_Last : Stream_Element_Offset;
- Data_Len : Stream_Element_Offset; -- -1
- Out_Len : Stream_Element_Offset; -- -1
- begin
- Out_First := Out_Last + 1;
-
- if Data_First > Data'Last then
- return;
- end if;
-
- Data_Len := Data'Last - Data_First;
- Out_Len := Out_Data'Last - Out_First;
-
- if Data_Len <= Out_Len then
- Out_Last := Out_First + Data_Len;
- Data_Last := Data'Last;
- else
- Out_Last := Out_Data'Last;
- Data_Last := Data_First + Out_Len;
- end if;
-
- Out_Data (Out_First .. Out_Last) := Data (Data_First .. Data_Last);
-
- Data_First := Data_Last + 1;
- Out_First := Out_Last + 1;
- end Add_Data;
-
- ------------
- -- Put_32 --
- ------------
-
- procedure Put_32
- (Item : in out Stream_Element_Array;
- Data : in Unsigned_32)
- is
- D : Unsigned_32 := Data;
- begin
- for J in Item'First .. Item'First + 3 loop
- Item (J) := Stream_Element (D and 16#FF#);
- D := Shift_Right (D, 8);
- end loop;
- end Put_32;
-
- begin
- Out_Last := Out_Data'First - 1;
-
- if not Filter.Stream_End then
- Add_Data (Simple_GZip_Header);
-
- Translate_Auto
- (Filter => Filter,
- In_Data => In_Data,
- In_Last => In_Last,
- Out_Data => Out_Data (Out_First .. Out_Data'Last),
- Out_Last => Out_Last,
- Flush => Flush);
-
- CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last));
- end if;
-
- if Filter.Stream_End and then Out_Last <= Out_Data'Last then
- -- This detection method would work only when
- -- Simple_GZip_Header'Last > Footer_Array'Last
-
- if Filter.Offset = Simple_GZip_Header'Last + 1 then
- Filter.Offset := Footer_Array'First;
- end if;
-
- declare
- Footer : Footer_Array;
- begin
- Put_32 (Footer, Filter.CRC);
- Put_32 (Footer (Footer'First + 4 .. Footer'Last),
- Unsigned_32 (Total_In (Filter)));
- Add_Data (Footer);
- end;
- end if;
- end Translate_GZip;
-
- -------------
- -- Version --
- -------------
-
- function Version return String is
- begin
- return Interfaces.C.Strings.Value (Thin.zlibVersion);
- end Version;
-
- -----------
- -- Write --
- -----------
-
- procedure Write
- (Filter : in out Filter_Type;
- Item : in Ada.Streams.Stream_Element_Array;
- Flush : in Flush_Mode := No_Flush)
- is
- Buffer : Stream_Element_Array (1 .. Buffer_Size);
- In_Last : Stream_Element_Offset;
- Out_Last : Stream_Element_Offset;
- In_First : Stream_Element_Offset := Item'First;
- begin
- if Item'Length = 0 and Flush = No_Flush then
- return;
- end if;
-
- loop
- Translate
- (Filter => Filter,
- In_Data => Item (In_First .. Item'Last),
- In_Last => In_Last,
- Out_Data => Buffer,
- Out_Last => Out_Last,
- Flush => Flush);
-
- if Out_Last >= Buffer'First then
- Write (Buffer (1 .. Out_Last));
- end if;
-
- exit when In_Last = Item'Last or Stream_End (Filter);
-
- In_First := In_Last + 1;
- end loop;
- end Write;
-
-end ZLib;
diff --git a/cpukit/zlib/contrib/ada/zlib.ads b/cpukit/zlib/contrib/ada/zlib.ads
deleted file mode 100644
index 9ada859572..0000000000
--- a/cpukit/zlib/contrib/ada/zlib.ads
+++ /dev/null
@@ -1,328 +0,0 @@
-------------------------------------------------------------------------------
--- ZLib for Ada thick binding. --
--- --
--- Copyright (C) 2002-2004 Dmitriy Anisimkov --
--- --
--- This library is free software; you can redistribute it and/or modify --
--- it under the terms of the GNU General Public License as published by --
--- the Free Software Foundation; either version 2 of the License, or (at --
--- your option) any later version. --
--- --
--- This library is distributed in the hope that it will be useful, but --
--- WITHOUT ANY WARRANTY; without even the implied warranty of --
--- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --
--- General Public License for more details. --
--- --
--- You should have received a copy of the GNU General Public License --
--- along with this library; if not, write to the Free Software Foundation, --
--- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --
--- --
--- As a special exception, if other files instantiate generics from this --
--- unit, or you link this unit with other files to produce an executable, --
--- this unit does not by itself cause the resulting executable to be --
--- covered by the GNU General Public License. This exception does not --
--- however invalidate any other reasons why the executable file might be --
--- covered by the GNU Public License. --
-------------------------------------------------------------------------------
-
--- $Id$
-
-with Ada.Streams;
-
-with Interfaces;
-
-package ZLib is
-
- ZLib_Error : exception;
- Status_Error : exception;
-
- type Compression_Level is new Integer range -1 .. 9;
-
- type Flush_Mode is private;
-
- type Compression_Method is private;
-
- type Window_Bits_Type is new Integer range 8 .. 15;
-
- type Memory_Level_Type is new Integer range 1 .. 9;
-
- type Unsigned_32 is new Interfaces.Unsigned_32;
-
- type Strategy_Type is private;
-
- type Header_Type is (None, Auto, Default, GZip);
- -- Header type usage have a some limitation for inflate.
- -- See comment for Inflate_Init.
-
- subtype Count is Ada.Streams.Stream_Element_Count;
-
- Default_Memory_Level : constant Memory_Level_Type := 8;
- Default_Window_Bits : constant Window_Bits_Type := 15;
-
- ----------------------------------
- -- Compression method constants --
- ----------------------------------
-
- Deflated : constant Compression_Method;
- -- Only one method allowed in this ZLib version
-
- ---------------------------------
- -- Compression level constants --
- ---------------------------------
-
- No_Compression : constant Compression_Level := 0;
- Best_Speed : constant Compression_Level := 1;
- Best_Compression : constant Compression_Level := 9;
- Default_Compression : constant Compression_Level := -1;
-
- --------------------------
- -- Flush mode constants --
- --------------------------
-
- No_Flush : constant Flush_Mode;
- -- Regular way for compression, no flush
-
- Partial_Flush : constant Flush_Mode;
- -- Will be removed, use Z_SYNC_FLUSH instead
-
- Sync_Flush : constant Flush_Mode;
- -- All pending output is flushed to the output buffer and the output
- -- is aligned on a byte boundary, so that the decompressor can get all
- -- input data available so far. (In particular avail_in is zero after the
- -- call if enough output space has been provided before the call.)
- -- Flushing may degrade compression for some compression algorithms and so
- -- it should be used only when necessary.
-
- Block_Flush : constant Flush_Mode;
- -- Z_BLOCK requests that inflate() stop
- -- if and when it get to the next deflate block boundary. When decoding the
- -- zlib or gzip format, this will cause inflate() to return immediately
- -- after the header and before the first block. When doing a raw inflate,
- -- inflate() will go ahead and process the first block, and will return
- -- when it gets to the end of that block, or when it runs out of data.
-
- Full_Flush : constant Flush_Mode;
- -- All output is flushed as with SYNC_FLUSH, and the compression state
- -- is reset so that decompression can restart from this point if previous
- -- compressed data has been damaged or if random access is desired. Using
- -- Full_Flush too often can seriously degrade the compression.
-
- Finish : constant Flush_Mode;
- -- Just for tell the compressor that input data is complete.
-
- ------------------------------------
- -- Compression strategy constants --
- ------------------------------------
-
- -- RLE stategy could be used only in version 1.2.0 and later.
-
- Filtered : constant Strategy_Type;
- Huffman_Only : constant Strategy_Type;
- RLE : constant Strategy_Type;
- Default_Strategy : constant Strategy_Type;
-
- Default_Buffer_Size : constant := 4096;
-
- type Filter_Type is tagged limited private;
- -- The filter is for compression and for decompression.
- -- The usage of the type is depend of its initialization.
-
- function Version return String;
- pragma Inline (Version);
- -- Return string representation of the ZLib version.
-
- procedure Deflate_Init
- (Filter : in out Filter_Type;
- Level : in Compression_Level := Default_Compression;
- Strategy : in Strategy_Type := Default_Strategy;
- Method : in Compression_Method := Deflated;
- Window_Bits : in Window_Bits_Type := Default_Window_Bits;
- Memory_Level : in Memory_Level_Type := Default_Memory_Level;
- Header : in Header_Type := Default);
- -- Compressor initialization.
- -- When Header parameter is Auto or Default, then default zlib header
- -- would be provided for compressed data.
- -- When Header is GZip, then gzip header would be set instead of
- -- default header.
- -- When Header is None, no header would be set for compressed data.
-
- procedure Inflate_Init
- (Filter : in out Filter_Type;
- Window_Bits : in Window_Bits_Type := Default_Window_Bits;
- Header : in Header_Type := Default);
- -- Decompressor initialization.
- -- Default header type mean that ZLib default header is expecting in the
- -- input compressed stream.
- -- Header type None mean that no header is expecting in the input stream.
- -- GZip header type mean that GZip header is expecting in the
- -- input compressed stream.
- -- Auto header type mean that header type (GZip or Native) would be
- -- detected automatically in the input stream.
- -- Note that header types parameter values None, GZip and Auto are
- -- supported for inflate routine only in ZLib versions 1.2.0.2 and later.
- -- Deflate_Init is supporting all header types.
-
- function Is_Open (Filter : in Filter_Type) return Boolean;
- pragma Inline (Is_Open);
- -- Is the filter opened for compression or decompression.
-
- procedure Close
- (Filter : in out Filter_Type;
- Ignore_Error : in Boolean := False);
- -- Closing the compression or decompressor.
- -- If stream is closing before the complete and Ignore_Error is False,
- -- The exception would be raised.
-
- generic
- with procedure Data_In
- (Item : out Ada.Streams.Stream_Element_Array;
- Last : out Ada.Streams.Stream_Element_Offset);
- with procedure Data_Out
- (Item : in Ada.Streams.Stream_Element_Array);
- procedure Generic_Translate
- (Filter : in out Filter_Type;
- In_Buffer_Size : in Integer := Default_Buffer_Size;
- Out_Buffer_Size : in Integer := Default_Buffer_Size);
- -- Compress/decompress data fetch from Data_In routine and pass the result
- -- to the Data_Out routine. User should provide Data_In and Data_Out
- -- for compression/decompression data flow.
- -- Compression or decompression depend on Filter initialization.
-
- function Total_In (Filter : in Filter_Type) return Count;
- pragma Inline (Total_In);
- -- Returns total number of input bytes read so far
-
- function Total_Out (Filter : in Filter_Type) return Count;
- pragma Inline (Total_Out);
- -- Returns total number of bytes output so far
-
- function CRC32
- (CRC : in Unsigned_32;
- Data : in Ada.Streams.Stream_Element_Array)
- return Unsigned_32;
- pragma Inline (CRC32);
- -- Compute CRC32, it could be necessary for make gzip format
-
- procedure CRC32
- (CRC : in out Unsigned_32;
- Data : in Ada.Streams.Stream_Element_Array);
- pragma Inline (CRC32);
- -- Compute CRC32, it could be necessary for make gzip format
-
- -------------------------------------------------
- -- Below is more complex low level routines. --
- -------------------------------------------------
-
- procedure Translate
- (Filter : in out Filter_Type;
- In_Data : in Ada.Streams.Stream_Element_Array;
- In_Last : out Ada.Streams.Stream_Element_Offset;
- Out_Data : out Ada.Streams.Stream_Element_Array;
- Out_Last : out Ada.Streams.Stream_Element_Offset;
- Flush : in Flush_Mode);
- -- Compress/decompress the In_Data buffer and place the result into
- -- Out_Data. In_Last is the index of last element from In_Data accepted by
- -- the Filter. Out_Last is the last element of the received data from
- -- Filter. To tell the filter that incoming data are complete put the
- -- Flush parameter to Finish.
-
- function Stream_End (Filter : in Filter_Type) return Boolean;
- pragma Inline (Stream_End);
- -- Return the true when the stream is complete.
-
- procedure Flush
- (Filter : in out Filter_Type;
- Out_Data : out Ada.Streams.Stream_Element_Array;
- Out_Last : out Ada.Streams.Stream_Element_Offset;
- Flush : in Flush_Mode);
- pragma Inline (Flush);
- -- Flushing the data from the compressor.
-
- generic
- with procedure Write
- (Item : in Ada.Streams.Stream_Element_Array);
- -- User should provide this routine for accept
- -- compressed/decompressed data.
-
- Buffer_Size : in Ada.Streams.Stream_Element_Offset
- := Default_Buffer_Size;
- -- Buffer size for Write user routine.
-
- procedure Write
- (Filter : in out Filter_Type;
- Item : in Ada.Streams.Stream_Element_Array;
- Flush : in Flush_Mode := No_Flush);
- -- Compress/Decompress data from Item to the generic parameter procedure
- -- Write. Output buffer size could be set in Buffer_Size generic parameter.
-
- generic
- with procedure Read
- (Item : out Ada.Streams.Stream_Element_Array;
- Last : out Ada.Streams.Stream_Element_Offset);
- -- User should provide data for compression/decompression
- -- thru this routine.
-
- Buffer : in out Ada.Streams.Stream_Element_Array;
- -- Buffer for keep remaining data from the previous
- -- back read.
-
- Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset;
- -- Rest_First have to be initialized to Buffer'Last + 1
- -- Rest_Last have to be initialized to Buffer'Last
- -- before usage.
-
- Allow_Read_Some : in Boolean := False;
- -- Is it allowed to return Last < Item'Last before end of data.
-
- procedure Read
- (Filter : in out Filter_Type;
- Item : out Ada.Streams.Stream_Element_Array;
- Last : out Ada.Streams.Stream_Element_Offset;
- Flush : in Flush_Mode := No_Flush);
- -- Compress/Decompress data from generic parameter procedure Read to the
- -- Item. User should provide Buffer and initialized Rest_First, Rest_Last
- -- indicators. If Allow_Read_Some is True, Read routines could return
- -- Last < Item'Last only at end of stream.
-
-private
-
- use Ada.Streams;
-
- pragma Assert (Ada.Streams.Stream_Element'Size = 8);
- pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8);
-
- type Flush_Mode is new Integer range 0 .. 5;
-
- type Compression_Method is new Integer range 8 .. 8;
-
- type Strategy_Type is new Integer range 0 .. 3;
-
- No_Flush : constant Flush_Mode := 0;
- Partial_Flush : constant Flush_Mode := 1;
- Sync_Flush : constant Flush_Mode := 2;
- Full_Flush : constant Flush_Mode := 3;
- Finish : constant Flush_Mode := 4;
- Block_Flush : constant Flush_Mode := 5;
-
- Filtered : constant Strategy_Type := 1;
- Huffman_Only : constant Strategy_Type := 2;
- RLE : constant Strategy_Type := 3;
- Default_Strategy : constant Strategy_Type := 0;
-
- Deflated : constant Compression_Method := 8;
-
- type Z_Stream;
-
- type Z_Stream_Access is access all Z_Stream;
-
- type Filter_Type is tagged limited record
- Strm : Z_Stream_Access;
- Compression : Boolean;
- Stream_End : Boolean;
- Header : Header_Type;
- CRC : Unsigned_32;
- Offset : Stream_Element_Offset;
- -- Offset for gzip header/footer output.
- end record;
-
-end ZLib;
diff --git a/cpukit/zlib/contrib/ada/zlib.gpr b/cpukit/zlib/contrib/ada/zlib.gpr
deleted file mode 100644
index 296b22aa96..0000000000
--- a/cpukit/zlib/contrib/ada/zlib.gpr
+++ /dev/null
@@ -1,20 +0,0 @@
-project Zlib is
-
- for Languages use ("Ada");
- for Source_Dirs use (".");
- for Object_Dir use ".";
- for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo");
-
- package Compiler is
- for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst");
- end Compiler;
-
- package Linker is
- for Default_Switches ("ada") use ("-lz");
- end Linker;
-
- package Builder is
- for Default_Switches ("ada") use ("-s", "-gnatQ");
- end Builder;
-
-end Zlib;
diff --git a/cpukit/zlib/contrib/asm586/README.586 b/cpukit/zlib/contrib/asm586/README.586
deleted file mode 100644
index 6bb78f3206..0000000000
--- a/cpukit/zlib/contrib/asm586/README.586
+++ /dev/null
@@ -1,43 +0,0 @@
-This is a patched version of zlib modified to use
-Pentium-optimized assembly code in the deflation algorithm. The files
-changed/added by this patch are:
-
-README.586
-match.S
-
-The effectiveness of these modifications is a bit marginal, as the the
-program's bottleneck seems to be mostly L1-cache contention, for which
-there is no real way to work around without rewriting the basic
-algorithm. The speedup on average is around 5-10% (which is generally
-less than the amount of variance between subsequent executions).
-However, when used at level 9 compression, the cache contention can
-drop enough for the assembly version to achieve 10-20% speedup (and
-sometimes more, depending on the amount of overall redundancy in the
-files). Even here, though, cache contention can still be the limiting
-factor, depending on the nature of the program using the zlib library.
-This may also mean that better improvements will be seen on a Pentium
-with MMX, which suffers much less from L1-cache contention, but I have
-not yet verified this.
-
-Note that this code has been tailored for the Pentium in particular,
-and will not perform well on the Pentium Pro (due to the use of a
-partial register in the inner loop).
-
-If you are using an assembler other than GNU as, you will have to
-translate match.S to use your assembler's syntax. (Have fun.)
-
-Brian Raiter
-breadbox@muppetlabs.com
-April, 1998
-
-
-Added for zlib 1.1.3:
-
-The patches come from
-http://www.muppetlabs.com/~breadbox/software/assembly.html
-
-To compile zlib with this asm file, copy match.S to the zlib directory
-then do:
-
-CFLAGS="-O3 -DASMV" ./configure
-make OBJA=match.o
diff --git a/cpukit/zlib/contrib/asm586/match.S b/cpukit/zlib/contrib/asm586/match.S
deleted file mode 100644
index 8f1614078f..0000000000
--- a/cpukit/zlib/contrib/asm586/match.S
+++ /dev/null
@@ -1,354 +0,0 @@
-/* match.s -- Pentium-optimized version of longest_match()
- * Written for zlib 1.1.2
- * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License.
- */
-
-#ifndef NO_UNDERLINE
-#define match_init _match_init
-#define longest_match _longest_match
-#endif
-
-#define MAX_MATCH (258)
-#define MIN_MATCH (3)
-#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
-#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
-
-/* stack frame offsets */
-
-#define wmask 0 /* local copy of s->wmask */
-#define window 4 /* local copy of s->window */
-#define windowbestlen 8 /* s->window + bestlen */
-#define chainlenscanend 12 /* high word: current chain len */
- /* low word: last bytes sought */
-#define scanstart 16 /* first two bytes of string */
-#define scanalign 20 /* dword-misalignment of string */
-#define nicematch 24 /* a good enough match size */
-#define bestlen 28 /* size of best match so far */
-#define scan 32 /* ptr to string wanting match */
-
-#define LocalVarsSize (36)
-/* saved ebx 36 */
-/* saved edi 40 */
-/* saved esi 44 */
-/* saved ebp 48 */
-/* return address 52 */
-#define deflatestate 56 /* the function arguments */
-#define curmatch 60
-
-/* Offsets for fields in the deflate_state structure. These numbers
- * are calculated from the definition of deflate_state, with the
- * assumption that the compiler will dword-align the fields. (Thus,
- * changing the definition of deflate_state could easily cause this
- * program to crash horribly, without so much as a warning at
- * compile time. Sigh.)
- */
-#define dsWSize 36
-#define dsWMask 44
-#define dsWindow 48
-#define dsPrev 56
-#define dsMatchLen 88
-#define dsPrevMatch 92
-#define dsStrStart 100
-#define dsMatchStart 104
-#define dsLookahead 108
-#define dsPrevLen 112
-#define dsMaxChainLen 116
-#define dsGoodMatch 132
-#define dsNiceMatch 136
-
-
-.file "match.S"
-
-.globl match_init, longest_match
-
-.text
-
-/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
-
-longest_match:
-
-/* Save registers that the compiler may be using, and adjust %esp to */
-/* make room for our stack frame. */
-
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %ebx
- subl $LocalVarsSize, %esp
-
-/* Retrieve the function arguments. %ecx will hold cur_match */
-/* throughout the entire function. %edx will hold the pointer to the */
-/* deflate_state structure during the function's setup (before */
-/* entering the main loop). */
-
- movl deflatestate(%esp), %edx
- movl curmatch(%esp), %ecx
-
-/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
-
- movl dsNiceMatch(%edx), %eax
- movl dsLookahead(%edx), %ebx
- cmpl %eax, %ebx
- jl LookaheadLess
- movl %eax, %ebx
-LookaheadLess: movl %ebx, nicematch(%esp)
-
-/* register Bytef *scan = s->window + s->strstart; */
-
- movl dsWindow(%edx), %esi
- movl %esi, window(%esp)
- movl dsStrStart(%edx), %ebp
- lea (%esi,%ebp), %edi
- movl %edi, scan(%esp)
-
-/* Determine how many bytes the scan ptr is off from being */
-/* dword-aligned. */
-
- movl %edi, %eax
- negl %eax
- andl $3, %eax
- movl %eax, scanalign(%esp)
-
-/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
-/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
-
- movl dsWSize(%edx), %eax
- subl $MIN_LOOKAHEAD, %eax
- subl %eax, %ebp
- jg LimitPositive
- xorl %ebp, %ebp
-LimitPositive:
-
-/* unsigned chain_length = s->max_chain_length; */
-/* if (s->prev_length >= s->good_match) { */
-/* chain_length >>= 2; */
-/* } */
-
- movl dsPrevLen(%edx), %eax
- movl dsGoodMatch(%edx), %ebx
- cmpl %ebx, %eax
- movl dsMaxChainLen(%edx), %ebx
- jl LastMatchGood
- shrl $2, %ebx
-LastMatchGood:
-
-/* chainlen is decremented once beforehand so that the function can */
-/* use the sign flag instead of the zero flag for the exit test. */
-/* It is then shifted into the high word, to make room for the scanend */
-/* scanend value, which it will always accompany. */
-
- decl %ebx
- shll $16, %ebx
-
-/* int best_len = s->prev_length; */
-
- movl dsPrevLen(%edx), %eax
- movl %eax, bestlen(%esp)
-
-/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-
- addl %eax, %esi
- movl %esi, windowbestlen(%esp)
-
-/* register ush scan_start = *(ushf*)scan; */
-/* register ush scan_end = *(ushf*)(scan+best_len-1); */
-
- movw (%edi), %bx
- movw %bx, scanstart(%esp)
- movw -1(%edi,%eax), %bx
- movl %ebx, chainlenscanend(%esp)
-
-/* Posf *prev = s->prev; */
-/* uInt wmask = s->w_mask; */
-
- movl dsPrev(%edx), %edi
- movl dsWMask(%edx), %edx
- mov %edx, wmask(%esp)
-
-/* Jump into the main loop. */
-
- jmp LoopEntry
-
-.balign 16
-
-/* do {
- * match = s->window + cur_match;
- * if (*(ushf*)(match+best_len-1) != scan_end ||
- * *(ushf*)match != scan_start) continue;
- * [...]
- * } while ((cur_match = prev[cur_match & wmask]) > limit
- * && --chain_length != 0);
- *
- * Here is the inner loop of the function. The function will spend the
- * majority of its time in this loop, and majority of that time will
- * be spent in the first ten instructions.
- *
- * Within this loop:
- * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
- * %ecx = curmatch
- * %edx = curmatch & wmask
- * %esi = windowbestlen - i.e., (window + bestlen)
- * %edi = prev
- * %ebp = limit
- *
- * Two optimization notes on the choice of instructions:
- *
- * The first instruction uses a 16-bit address, which costs an extra,
- * unpairable cycle. This is cheaper than doing a 32-bit access and
- * zeroing the high word, due to the 3-cycle misalignment penalty which
- * would occur half the time. This also turns out to be cheaper than
- * doing two separate 8-bit accesses, as the memory is so rarely in the
- * L1 cache.
- *
- * The window buffer, however, apparently spends a lot of time in the
- * cache, and so it is faster to retrieve the word at the end of the
- * match string with two 8-bit loads. The instructions that test the
- * word at the beginning of the match string, however, are executed
- * much less frequently, and there it was cheaper to use 16-bit
- * instructions, which avoided the necessity of saving off and
- * subsequently reloading one of the other registers.
- */
-LookupLoop:
- /* 1 U & V */
- movw (%edi,%edx,2), %cx /* 2 U pipe */
- movl wmask(%esp), %edx /* 2 V pipe */
- cmpl %ebp, %ecx /* 3 U pipe */
- jbe LeaveNow /* 3 V pipe */
- subl $0x00010000, %ebx /* 4 U pipe */
- js LeaveNow /* 4 V pipe */
-LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
- andl %ecx, %edx /* 5 V pipe */
- cmpb %bl, %al /* 6 U pipe */
- jnz LookupLoop /* 6 V pipe */
- movb (%esi,%ecx), %ah
- cmpb %bh, %ah
- jnz LookupLoop
- movl window(%esp), %eax
- movw (%eax,%ecx), %ax
- cmpw scanstart(%esp), %ax
- jnz LookupLoop
-
-/* Store the current value of chainlen. */
-
- movl %ebx, chainlenscanend(%esp)
-
-/* Point %edi to the string under scrutiny, and %esi to the string we */
-/* are hoping to match it up with. In actuality, %esi and %edi are */
-/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
-/* initialized to -(MAX_MATCH_8 - scanalign). */
-
- movl window(%esp), %esi
- movl scan(%esp), %edi
- addl %ecx, %esi
- movl scanalign(%esp), %eax
- movl $(-MAX_MATCH_8), %edx
- lea MAX_MATCH_8(%edi,%eax), %edi
- lea MAX_MATCH_8(%esi,%eax), %esi
-
-/* Test the strings for equality, 8 bytes at a time. At the end,
- * adjust %edx so that it is offset to the exact byte that mismatched.
- *
- * We already know at this point that the first three bytes of the
- * strings match each other, and they can be safely passed over before
- * starting the compare loop. So what this code does is skip over 0-3
- * bytes, as much as necessary in order to dword-align the %edi
- * pointer. (%esi will still be misaligned three times out of four.)
- *
- * It should be confessed that this loop usually does not represent
- * much of the total running time. Replacing it with a more
- * straightforward "rep cmpsb" would not drastically degrade
- * performance.
- */
-LoopCmps:
- movl (%esi,%edx), %eax
- movl (%edi,%edx), %ebx
- xorl %ebx, %eax
- jnz LeaveLoopCmps
- movl 4(%esi,%edx), %eax
- movl 4(%edi,%edx), %ebx
- xorl %ebx, %eax
- jnz LeaveLoopCmps4
- addl $8, %edx
- jnz LoopCmps
- jmp LenMaximum
-LeaveLoopCmps4: addl $4, %edx
-LeaveLoopCmps: testl $0x0000FFFF, %eax
- jnz LenLower
- addl $2, %edx
- shrl $16, %eax
-LenLower: subb $1, %al
- adcl $0, %edx
-
-/* Calculate the length of the match. If it is longer than MAX_MATCH, */
-/* then automatically accept it as the best possible match and leave. */
-
- lea (%edi,%edx), %eax
- movl scan(%esp), %edi
- subl %edi, %eax
- cmpl $MAX_MATCH, %eax
- jge LenMaximum
-
-/* If the length of the match is not longer than the best match we */
-/* have so far, then forget it and return to the lookup loop. */
-
- movl deflatestate(%esp), %edx
- movl bestlen(%esp), %ebx
- cmpl %ebx, %eax
- jg LongerMatch
- movl chainlenscanend(%esp), %ebx
- movl windowbestlen(%esp), %esi
- movl dsPrev(%edx), %edi
- movl wmask(%esp), %edx
- andl %ecx, %edx
- jmp LookupLoop
-
-/* s->match_start = cur_match; */
-/* best_len = len; */
-/* if (len >= nice_match) break; */
-/* scan_end = *(ushf*)(scan+best_len-1); */
-
-LongerMatch: movl nicematch(%esp), %ebx
- movl %eax, bestlen(%esp)
- movl %ecx, dsMatchStart(%edx)
- cmpl %ebx, %eax
- jge LeaveNow
- movl window(%esp), %esi
- addl %eax, %esi
- movl %esi, windowbestlen(%esp)
- movl chainlenscanend(%esp), %ebx
- movw -1(%edi,%eax), %bx
- movl dsPrev(%edx), %edi
- movl %ebx, chainlenscanend(%esp)
- movl wmask(%esp), %edx
- andl %ecx, %edx
- jmp LookupLoop
-
-/* Accept the current string, with the maximum possible length. */
-
-LenMaximum: movl deflatestate(%esp), %edx
- movl $MAX_MATCH, bestlen(%esp)
- movl %ecx, dsMatchStart(%edx)
-
-/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
-/* return s->lookahead; */
-
-LeaveNow:
- movl deflatestate(%esp), %edx
- movl bestlen(%esp), %ebx
- movl dsLookahead(%edx), %eax
- cmpl %eax, %ebx
- jg LookaheadRet
- movl %ebx, %eax
-LookaheadRet:
-
-/* Restore the stack and return from whence we came. */
-
- addl $LocalVarsSize, %esp
- popl %ebx
- popl %esi
- popl %edi
- popl %ebp
-match_init: ret
diff --git a/cpukit/zlib/contrib/asm686/README.686 b/cpukit/zlib/contrib/asm686/README.686
deleted file mode 100644
index a593f23afd..0000000000
--- a/cpukit/zlib/contrib/asm686/README.686
+++ /dev/null
@@ -1,34 +0,0 @@
-This is a patched version of zlib, modified to use
-Pentium-Pro-optimized assembly code in the deflation algorithm. The
-files changed/added by this patch are:
-
-README.686
-match.S
-
-The speedup that this patch provides varies, depending on whether the
-compiler used to build the original version of zlib falls afoul of the
-PPro's speed traps. My own tests show a speedup of around 10-20% at
-the default compression level, and 20-30% using -9, against a version
-compiled using gcc 2.7.2.3. Your mileage may vary.
-
-Note that this code has been tailored for the PPro/PII in particular,
-and will not perform particuarly well on a Pentium.
-
-If you are using an assembler other than GNU as, you will have to
-translate match.S to use your assembler's syntax. (Have fun.)
-
-Brian Raiter
-breadbox@muppetlabs.com
-April, 1998
-
-
-Added for zlib 1.1.3:
-
-The patches come from
-http://www.muppetlabs.com/~breadbox/software/assembly.html
-
-To compile zlib with this asm file, copy match.S to the zlib directory
-then do:
-
-CFLAGS="-O3 -DASMV" ./configure
-make OBJA=match.o
diff --git a/cpukit/zlib/contrib/asm686/match.S b/cpukit/zlib/contrib/asm686/match.S
deleted file mode 100644
index 8e86c33c28..0000000000
--- a/cpukit/zlib/contrib/asm686/match.S
+++ /dev/null
@@ -1,327 +0,0 @@
-/* match.s -- Pentium-Pro-optimized version of longest_match()
- * Written for zlib 1.1.2
- * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License.
- */
-
-#ifndef NO_UNDERLINE
-#define match_init _match_init
-#define longest_match _longest_match
-#endif
-
-#define MAX_MATCH (258)
-#define MIN_MATCH (3)
-#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
-#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
-
-/* stack frame offsets */
-
-#define chainlenwmask 0 /* high word: current chain len */
- /* low word: s->wmask */
-#define window 4 /* local copy of s->window */
-#define windowbestlen 8 /* s->window + bestlen */
-#define scanstart 16 /* first two bytes of string */
-#define scanend 12 /* last two bytes of string */
-#define scanalign 20 /* dword-misalignment of string */
-#define nicematch 24 /* a good enough match size */
-#define bestlen 28 /* size of best match so far */
-#define scan 32 /* ptr to string wanting match */
-
-#define LocalVarsSize (36)
-/* saved ebx 36 */
-/* saved edi 40 */
-/* saved esi 44 */
-/* saved ebp 48 */
-/* return address 52 */
-#define deflatestate 56 /* the function arguments */
-#define curmatch 60
-
-/* Offsets for fields in the deflate_state structure. These numbers
- * are calculated from the definition of deflate_state, with the
- * assumption that the compiler will dword-align the fields. (Thus,
- * changing the definition of deflate_state could easily cause this
- * program to crash horribly, without so much as a warning at
- * compile time. Sigh.)
- */
-#define dsWSize 36
-#define dsWMask 44
-#define dsWindow 48
-#define dsPrev 56
-#define dsMatchLen 88
-#define dsPrevMatch 92
-#define dsStrStart 100
-#define dsMatchStart 104
-#define dsLookahead 108
-#define dsPrevLen 112
-#define dsMaxChainLen 116
-#define dsGoodMatch 132
-#define dsNiceMatch 136
-
-
-.file "match.S"
-
-.globl match_init, longest_match
-
-.text
-
-/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
-
-longest_match:
-
-/* Save registers that the compiler may be using, and adjust %esp to */
-/* make room for our stack frame. */
-
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %ebx
- subl $LocalVarsSize, %esp
-
-/* Retrieve the function arguments. %ecx will hold cur_match */
-/* throughout the entire function. %edx will hold the pointer to the */
-/* deflate_state structure during the function's setup (before */
-/* entering the main loop). */
-
- movl deflatestate(%esp), %edx
- movl curmatch(%esp), %ecx
-
-/* uInt wmask = s->w_mask; */
-/* unsigned chain_length = s->max_chain_length; */
-/* if (s->prev_length >= s->good_match) { */
-/* chain_length >>= 2; */
-/* } */
-
- movl dsPrevLen(%edx), %eax
- movl dsGoodMatch(%edx), %ebx
- cmpl %ebx, %eax
- movl dsWMask(%edx), %eax
- movl dsMaxChainLen(%edx), %ebx
- jl LastMatchGood
- shrl $2, %ebx
-LastMatchGood:
-
-/* chainlen is decremented once beforehand so that the function can */
-/* use the sign flag instead of the zero flag for the exit test. */
-/* It is then shifted into the high word, to make room for the wmask */
-/* value, which it will always accompany. */
-
- decl %ebx
- shll $16, %ebx
- orl %eax, %ebx
- movl %ebx, chainlenwmask(%esp)
-
-/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
-
- movl dsNiceMatch(%edx), %eax
- movl dsLookahead(%edx), %ebx
- cmpl %eax, %ebx
- jl LookaheadLess
- movl %eax, %ebx
-LookaheadLess: movl %ebx, nicematch(%esp)
-
-/* register Bytef *scan = s->window + s->strstart; */
-
- movl dsWindow(%edx), %esi
- movl %esi, window(%esp)
- movl dsStrStart(%edx), %ebp
- lea (%esi,%ebp), %edi
- movl %edi, scan(%esp)
-
-/* Determine how many bytes the scan ptr is off from being */
-/* dword-aligned. */
-
- movl %edi, %eax
- negl %eax
- andl $3, %eax
- movl %eax, scanalign(%esp)
-
-/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
-/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
-
- movl dsWSize(%edx), %eax
- subl $MIN_LOOKAHEAD, %eax
- subl %eax, %ebp
- jg LimitPositive
- xorl %ebp, %ebp
-LimitPositive:
-
-/* int best_len = s->prev_length; */
-
- movl dsPrevLen(%edx), %eax
- movl %eax, bestlen(%esp)
-
-/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-
- addl %eax, %esi
- movl %esi, windowbestlen(%esp)
-
-/* register ush scan_start = *(ushf*)scan; */
-/* register ush scan_end = *(ushf*)(scan+best_len-1); */
-/* Posf *prev = s->prev; */
-
- movzwl (%edi), %ebx
- movl %ebx, scanstart(%esp)
- movzwl -1(%edi,%eax), %ebx
- movl %ebx, scanend(%esp)
- movl dsPrev(%edx), %edi
-
-/* Jump into the main loop. */
-
- movl chainlenwmask(%esp), %edx
- jmp LoopEntry
-
-.balign 16
-
-/* do {
- * match = s->window + cur_match;
- * if (*(ushf*)(match+best_len-1) != scan_end ||
- * *(ushf*)match != scan_start) continue;
- * [...]
- * } while ((cur_match = prev[cur_match & wmask]) > limit
- * && --chain_length != 0);
- *
- * Here is the inner loop of the function. The function will spend the
- * majority of its time in this loop, and majority of that time will
- * be spent in the first ten instructions.
- *
- * Within this loop:
- * %ebx = scanend
- * %ecx = curmatch
- * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
- * %esi = windowbestlen - i.e., (window + bestlen)
- * %edi = prev
- * %ebp = limit
- */
-LookupLoop:
- andl %edx, %ecx
- movzwl (%edi,%ecx,2), %ecx
- cmpl %ebp, %ecx
- jbe LeaveNow
- subl $0x00010000, %edx
- js LeaveNow
-LoopEntry: movzwl -1(%esi,%ecx), %eax
- cmpl %ebx, %eax
- jnz LookupLoop
- movl window(%esp), %eax
- movzwl (%eax,%ecx), %eax
- cmpl scanstart(%esp), %eax
- jnz LookupLoop
-
-/* Store the current value of chainlen. */
-
- movl %edx, chainlenwmask(%esp)
-
-/* Point %edi to the string under scrutiny, and %esi to the string we */
-/* are hoping to match it up with. In actuality, %esi and %edi are */
-/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
-/* initialized to -(MAX_MATCH_8 - scanalign). */
-
- movl window(%esp), %esi
- movl scan(%esp), %edi
- addl %ecx, %esi
- movl scanalign(%esp), %eax
- movl $(-MAX_MATCH_8), %edx
- lea MAX_MATCH_8(%edi,%eax), %edi
- lea MAX_MATCH_8(%esi,%eax), %esi
-
-/* Test the strings for equality, 8 bytes at a time. At the end,
- * adjust %edx so that it is offset to the exact byte that mismatched.
- *
- * We already know at this point that the first three bytes of the
- * strings match each other, and they can be safely passed over before
- * starting the compare loop. So what this code does is skip over 0-3
- * bytes, as much as necessary in order to dword-align the %edi
- * pointer. (%esi will still be misaligned three times out of four.)
- *
- * It should be confessed that this loop usually does not represent
- * much of the total running time. Replacing it with a more
- * straightforward "rep cmpsb" would not drastically degrade
- * performance.
- */
-LoopCmps:
- movl (%esi,%edx), %eax
- xorl (%edi,%edx), %eax
- jnz LeaveLoopCmps
- movl 4(%esi,%edx), %eax
- xorl 4(%edi,%edx), %eax
- jnz LeaveLoopCmps4
- addl $8, %edx
- jnz LoopCmps
- jmp LenMaximum
-LeaveLoopCmps4: addl $4, %edx
-LeaveLoopCmps: testl $0x0000FFFF, %eax
- jnz LenLower
- addl $2, %edx
- shrl $16, %eax
-LenLower: subb $1, %al
- adcl $0, %edx
-
-/* Calculate the length of the match. If it is longer than MAX_MATCH, */
-/* then automatically accept it as the best possible match and leave. */
-
- lea (%edi,%edx), %eax
- movl scan(%esp), %edi
- subl %edi, %eax
- cmpl $MAX_MATCH, %eax
- jge LenMaximum
-
-/* If the length of the match is not longer than the best match we */
-/* have so far, then forget it and return to the lookup loop. */
-
- movl deflatestate(%esp), %edx
- movl bestlen(%esp), %ebx
- cmpl %ebx, %eax
- jg LongerMatch
- movl windowbestlen(%esp), %esi
- movl dsPrev(%edx), %edi
- movl scanend(%esp), %ebx
- movl chainlenwmask(%esp), %edx
- jmp LookupLoop
-
-/* s->match_start = cur_match; */
-/* best_len = len; */
-/* if (len >= nice_match) break; */
-/* scan_end = *(ushf*)(scan+best_len-1); */
-
-LongerMatch: movl nicematch(%esp), %ebx
- movl %eax, bestlen(%esp)
- movl %ecx, dsMatchStart(%edx)
- cmpl %ebx, %eax
- jge LeaveNow
- movl window(%esp), %esi
- addl %eax, %esi
- movl %esi, windowbestlen(%esp)
- movzwl -1(%edi,%eax), %ebx
- movl dsPrev(%edx), %edi
- movl %ebx, scanend(%esp)
- movl chainlenwmask(%esp), %edx
- jmp LookupLoop
-
-/* Accept the current string, with the maximum possible length. */
-
-LenMaximum: movl deflatestate(%esp), %edx
- movl $MAX_MATCH, bestlen(%esp)
- movl %ecx, dsMatchStart(%edx)
-
-/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
-/* return s->lookahead; */
-
-LeaveNow:
- movl deflatestate(%esp), %edx
- movl bestlen(%esp), %ebx
- movl dsLookahead(%edx), %eax
- cmpl %eax, %ebx
- jg LookaheadRet
- movl %ebx, %eax
-LookaheadRet:
-
-/* Restore the stack and return from whence we came. */
-
- addl $LocalVarsSize, %esp
- popl %ebx
- popl %esi
- popl %edi
- popl %ebp
-match_init: ret
diff --git a/cpukit/zlib/contrib/blast/Makefile b/cpukit/zlib/contrib/blast/Makefile
deleted file mode 100644
index 9be80bafe0..0000000000
--- a/cpukit/zlib/contrib/blast/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-blast: blast.c blast.h
- cc -DTEST -o blast blast.c
-
-test: blast
- blast < test.pk | cmp - test.txt
-
-clean:
- rm -f blast blast.o
diff --git a/cpukit/zlib/contrib/blast/README b/cpukit/zlib/contrib/blast/README
deleted file mode 100644
index e3a60b3f5c..0000000000
--- a/cpukit/zlib/contrib/blast/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Read blast.h for purpose and usage.
-
-Mark Adler
-madler@alumni.caltech.edu
diff --git a/cpukit/zlib/contrib/blast/blast.c b/cpukit/zlib/contrib/blast/blast.c
deleted file mode 100644
index 4ce697a41f..0000000000
--- a/cpukit/zlib/contrib/blast/blast.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/* blast.c
- * Copyright (C) 2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in blast.h
- * version 1.1, 16 Feb 2003
- *
- * blast.c decompresses data compressed by the PKWare Compression Library.
- * This function provides functionality similar to the explode() function of
- * the PKWare library, hence the name "blast".
- *
- * This decompressor is based on the excellent format description provided by
- * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the
- * example Ben provided in the post is incorrect. The distance 110001 should
- * instead be 111000. When corrected, the example byte stream becomes:
- *
- * 00 04 82 24 25 8f 80 7f
- *
- * which decompresses to "AIAIAIAIAIAIA" (without the quotes).
- */
-
-/*
- * Change history:
- *
- * 1.0 12 Feb 2003 - First version
- * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data
- */
-
-#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
-#include "blast.h" /* prototype for blast() */
-
-#define local static /* for local function definitions */
-#define MAXBITS 13 /* maximum code length */
-#define MAXWIN 4096 /* maximum window size */
-
-/* input and output state */
-struct state {
- /* input state */
- blast_in infun; /* input function provided by user */
- void *inhow; /* opaque information passed to infun() */
- unsigned char *in; /* next input location */
- unsigned left; /* available input at in */
- int bitbuf; /* bit buffer */
- int bitcnt; /* number of bits in bit buffer */
-
- /* input limit error return state for bits() and decode() */
- jmp_buf env;
-
- /* output state */
- blast_out outfun; /* output function provided by user */
- void *outhow; /* opaque information passed to outfun() */
- unsigned next; /* index of next write location in out[] */
- int first; /* true to check distances (for first 4K) */
- unsigned char out[MAXWIN]; /* output buffer and sliding window */
-};
-
-/*
- * Return need bits from the input stream. This always leaves less than
- * eight bits in the buffer. bits() works properly for need == 0.
- *
- * Format notes:
- *
- * - Bits are stored in bytes from the least significant bit to the most
- * significant bit. Therefore bits are dropped from the bottom of the bit
- * buffer, using shift right, and new bytes are appended to the top of the
- * bit buffer, using shift left.
- */
-local int bits(struct state *s, int need)
-{
- int val; /* bit accumulator */
-
- /* load at least need bits into val */
- val = s->bitbuf;
- while (s->bitcnt < need) {
- if (s->left == 0) {
- s->left = s->infun(s->inhow, &(s->in));
- if (s->left == 0) longjmp(s->env, 1); /* out of input */
- }
- val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */
- s->left--;
- s->bitcnt += 8;
- }
-
- /* drop need bits and update buffer, always zero to seven bits left */
- s->bitbuf = val >> need;
- s->bitcnt -= need;
-
- /* return need bits, zeroing the bits above that */
- return val & ((1 << need) - 1);
-}
-
-/*
- * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
- * each length, which for a canonical code are stepped through in order.
- * symbol[] are the symbol values in canonical order, where the number of
- * entries is the sum of the counts in count[]. The decoding process can be
- * seen in the function decode() below.
- */
-struct huffman {
- short *count; /* number of symbols of each length */
- short *symbol; /* canonically ordered symbols */
-};
-
-/*
- * Decode a code from the stream s using huffman table h. Return the symbol or
- * a negative value if there is an error. If all of the lengths are zero, i.e.
- * an empty code, or if the code is incomplete and an invalid code is received,
- * then -9 is returned after reading MAXBITS bits.
- *
- * Format notes:
- *
- * - The codes as stored in the compressed data are bit-reversed relative to
- * a simple integer ordering of codes of the same lengths. Hence below the
- * bits are pulled from the compressed data one at a time and used to
- * build the code value reversed from what is in the stream in order to
- * permit simple integer comparisons for decoding.
- *
- * - The first code for the shortest length is all ones. Subsequent codes of
- * the same length are simply integer decrements of the previous code. When
- * moving up a length, a one bit is appended to the code. For a complete
- * code, the last code of the longest length will be all zeros. To support
- * this ordering, the bits pulled during decoding are inverted to apply the
- * more "natural" ordering starting with all zeros and incrementing.
- */
-local int decode(struct state *s, struct huffman *h)
-{
- int len; /* current number of bits in code */
- int code; /* len bits being decoded */
- int first; /* first code of length len */
- int count; /* number of codes of length len */
- int index; /* index of first code of length len in symbol table */
- int bitbuf; /* bits from stream */
- int left; /* bits left in next or left to process */
- short *next; /* next number of codes */
-
- bitbuf = s->bitbuf;
- left = s->bitcnt;
- code = first = index = 0;
- len = 1;
- next = h->count + 1;
- while (1) {
- while (left--) {
- code |= (bitbuf & 1) ^ 1; /* invert code */
- bitbuf >>= 1;
- count = *next++;
- if (code < first + count) { /* if length len, return symbol */
- s->bitbuf = bitbuf;
- s->bitcnt = (s->bitcnt - len) & 7;
- return h->symbol[index + (code - first)];
- }
- index += count; /* else update for next length */
- first += count;
- first <<= 1;
- code <<= 1;
- len++;
- }
- left = (MAXBITS+1) - len;
- if (left == 0) break;
- if (s->left == 0) {
- s->left = s->infun(s->inhow, &(s->in));
- if (s->left == 0) longjmp(s->env, 1); /* out of input */
- }
- bitbuf = *(s->in)++;
- s->left--;
- if (left > 8) left = 8;
- }
- return -9; /* ran out of codes */
-}
-
-/*
- * Given a list of repeated code lengths rep[0..n-1], where each byte is a
- * count (high four bits + 1) and a code length (low four bits), generate the
- * list of code lengths. This compaction reduces the size of the object code.
- * Then given the list of code lengths length[0..n-1] representing a canonical
- * Huffman code for n symbols, construct the tables required to decode those
- * codes. Those tables are the number of codes of each length, and the symbols
- * sorted by length, retaining their original order within each length. The
- * return value is zero for a complete code set, negative for an over-
- * subscribed code set, and positive for an incomplete code set. The tables
- * can be used if the return value is zero or positive, but they cannot be used
- * if the return value is negative. If the return value is zero, it is not
- * possible for decode() using that table to return an error--any stream of
- * enough bits will resolve to a symbol. If the return value is positive, then
- * it is possible for decode() using that table to return an error for received
- * codes past the end of the incomplete lengths.
- */
-local int construct(struct huffman *h, const unsigned char *rep, int n)
-{
- int symbol; /* current symbol when stepping through length[] */
- int len; /* current length when stepping through h->count[] */
- int left; /* number of possible codes left of current length */
- short offs[MAXBITS+1]; /* offsets in symbol table for each length */
- short length[256]; /* code lengths */
-
- /* convert compact repeat counts into symbol bit length list */
- symbol = 0;
- do {
- len = *rep++;
- left = (len >> 4) + 1;
- len &= 15;
- do {
- length[symbol++] = len;
- } while (--left);
- } while (--n);
- n = symbol;
-
- /* count number of codes of each length */
- for (len = 0; len <= MAXBITS; len++)
- h->count[len] = 0;
- for (symbol = 0; symbol < n; symbol++)
- (h->count[length[symbol]])++; /* assumes lengths are within bounds */
- if (h->count[0] == n) /* no codes! */
- return 0; /* complete, but decode() will fail */
-
- /* check for an over-subscribed or incomplete set of lengths */
- left = 1; /* one possible code of zero length */
- for (len = 1; len <= MAXBITS; len++) {
- left <<= 1; /* one more bit, double codes left */
- left -= h->count[len]; /* deduct count from possible codes */
- if (left < 0) return left; /* over-subscribed--return negative */
- } /* left > 0 means incomplete */
-
- /* generate offsets into symbol table for each length for sorting */
- offs[1] = 0;
- for (len = 1; len < MAXBITS; len++)
- offs[len + 1] = offs[len] + h->count[len];
-
- /*
- * put symbols in table sorted by length, by symbol order within each
- * length
- */
- for (symbol = 0; symbol < n; symbol++)
- if (length[symbol] != 0)
- h->symbol[offs[length[symbol]]++] = symbol;
-
- /* return zero for complete set, positive for incomplete set */
- return left;
-}
-
-/*
- * Decode PKWare Compression Library stream.
- *
- * Format notes:
- *
- * - First byte is 0 if literals are uncoded or 1 if they are coded. Second
- * byte is 4, 5, or 6 for the number of extra bits in the distance code.
- * This is the base-2 logarithm of the dictionary size minus six.
- *
- * - Compressed data is a combination of literals and length/distance pairs
- * terminated by an end code. Literals are either Huffman coded or
- * uncoded bytes. A length/distance pair is a coded length followed by a
- * coded distance to represent a string that occurs earlier in the
- * uncompressed data that occurs again at the current location.
- *
- * - A bit preceding a literal or length/distance pair indicates which comes
- * next, 0 for literals, 1 for length/distance.
- *
- * - If literals are uncoded, then the next eight bits are the literal, in the
- * normal bit order in th stream, i.e. no bit-reversal is needed. Similarly,
- * no bit reversal is needed for either the length extra bits or the distance
- * extra bits.
- *
- * - Literal bytes are simply written to the output. A length/distance pair is
- * an instruction to copy previously uncompressed bytes to the output. The
- * copy is from distance bytes back in the output stream, copying for length
- * bytes.
- *
- * - Distances pointing before the beginning of the output data are not
- * permitted.
- *
- * - Overlapped copies, where the length is greater than the distance, are
- * allowed and common. For example, a distance of one and a length of 518
- * simply copies the last byte 518 times. A distance of four and a length of
- * twelve copies the last four bytes three times. A simple forward copy
- * ignoring whether the length is greater than the distance or not implements
- * this correctly.
- */
-local int decomp(struct state *s)
-{
- int lit; /* true if literals are coded */
- int dict; /* log2(dictionary size) - 6 */
- int symbol; /* decoded symbol, extra bits for distance */
- int len; /* length for copy */
- int dist; /* distance for copy */
- int copy; /* copy counter */
- unsigned char *from, *to; /* copy pointers */
- static int virgin = 1; /* build tables once */
- static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */
- static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */
- static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */
- static struct huffman litcode = {litcnt, litsym}; /* length code */
- static struct huffman lencode = {lencnt, lensym}; /* length code */
- static struct huffman distcode = {distcnt, distsym};/* distance code */
- /* bit lengths of literal codes */
- static const unsigned char litlen[] = {
- 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8,
- 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5,
- 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12,
- 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27,
- 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45,
- 44, 173};
- /* bit lengths of length codes 0..15 */
- static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23};
- /* bit lengths of distance codes 0..63 */
- static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248};
- static const short base[16] = { /* base for length codes */
- 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264};
- static const char extra[16] = { /* extra bits for length codes */
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
-
- /* set up decoding tables (once--might not be thread-safe) */
- if (virgin) {
- construct(&litcode, litlen, sizeof(litlen));
- construct(&lencode, lenlen, sizeof(lenlen));
- construct(&distcode, distlen, sizeof(distlen));
- virgin = 0;
- }
-
- /* read header */
- lit = bits(s, 8);
- if (lit > 1) return -1;
- dict = bits(s, 8);
- if (dict < 4 || dict > 6) return -2;
-
- /* decode literals and length/distance pairs */
- do {
- if (bits(s, 1)) {
- /* get length */
- symbol = decode(s, &lencode);
- len = base[symbol] + bits(s, extra[symbol]);
- if (len == 519) break; /* end code */
-
- /* get distance */
- symbol = len == 2 ? 2 : dict;
- dist = decode(s, &distcode) << symbol;
- dist += bits(s, symbol);
- dist++;
- if (s->first && dist > s->next)
- return -3; /* distance too far back */
-
- /* copy length bytes from distance bytes back */
- do {
- to = s->out + s->next;
- from = to - dist;
- copy = MAXWIN;
- if (s->next < dist) {
- from += copy;
- copy = dist;
- }
- copy -= s->next;
- if (copy > len) copy = len;
- len -= copy;
- s->next += copy;
- do {
- *to++ = *from++;
- } while (--copy);
- if (s->next == MAXWIN) {
- if (s->outfun(s->outhow, s->out, s->next)) return 1;
- s->next = 0;
- s->first = 0;
- }
- } while (len != 0);
- }
- else {
- /* get literal and write it */
- symbol = lit ? decode(s, &litcode) : bits(s, 8);
- s->out[s->next++] = symbol;
- if (s->next == MAXWIN) {
- if (s->outfun(s->outhow, s->out, s->next)) return 1;
- s->next = 0;
- s->first = 0;
- }
- }
- } while (1);
- return 0;
-}
-
-/* See comments in blast.h */
-int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow)
-{
- struct state s; /* input/output state */
- int err; /* return value */
-
- /* initialize input state */
- s.infun = infun;
- s.inhow = inhow;
- s.left = 0;
- s.bitbuf = 0;
- s.bitcnt = 0;
-
- /* initialize output state */
- s.outfun = outfun;
- s.outhow = outhow;
- s.next = 0;
- s.first = 1;
-
- /* return if bits() or decode() tries to read past available input */
- if (setjmp(s.env) != 0) /* if came back here via longjmp(), */
- err = 2; /* then skip decomp(), return error */
- else
- err = decomp(&s); /* decompress */
-
- /* write any leftover output and update the error code if needed */
- if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0)
- err = 1;
- return err;
-}
-
-#ifdef TEST
-/* Example of how to use blast() */
-#include <stdio.h>
-#include <stdlib.h>
-
-#define CHUNK 16384
-
-local unsigned inf(void *how, unsigned char **buf)
-{
- static unsigned char hold[CHUNK];
-
- *buf = hold;
- return fread(hold, 1, CHUNK, (FILE *)how);
-}
-
-local int outf(void *how, unsigned char *buf, unsigned len)
-{
- return fwrite(buf, 1, len, (FILE *)how) != len;
-}
-
-/* Decompress a PKWare Compression Library stream from stdin to stdout */
-int main(void)
-{
- int ret, n;
-
- /* decompress to stdout */
- ret = blast(inf, stdin, outf, stdout);
- if (ret != 0) fprintf(stderr, "blast error: %d\n", ret);
-
- /* see if there are any leftover bytes */
- n = 0;
- while (getchar() != EOF) n++;
- if (n) fprintf(stderr, "blast warning: %d unused bytes of input\n", n);
-
- /* return blast() error code */
- return ret;
-}
-#endif
diff --git a/cpukit/zlib/contrib/blast/blast.h b/cpukit/zlib/contrib/blast/blast.h
deleted file mode 100644
index ce9e5410f4..0000000000
--- a/cpukit/zlib/contrib/blast/blast.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* blast.h -- interface for blast.c
- Copyright (C) 2003 Mark Adler
- version 1.1, 16 Feb 2003
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Mark Adler madler@alumni.caltech.edu
- */
-
-
-/*
- * blast() decompresses the PKWare Data Compression Library (DCL) compressed
- * format. It provides the same functionality as the explode() function in
- * that library. (Note: PKWare overused the "implode" verb, and the format
- * used by their library implode() function is completely different and
- * incompatible with the implode compression method supported by PKZIP.)
- */
-
-
-typedef unsigned (*blast_in)(void *how, unsigned char **buf);
-typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len);
-/* Definitions for input/output functions passed to blast(). See below for
- * what the provided functions need to do.
- */
-
-
-int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow);
-/* Decompress input to output using the provided infun() and outfun() calls.
- * On success, the return value of blast() is zero. If there is an error in
- * the source data, i.e. it is not in the proper format, then a negative value
- * is returned. If there is not enough input available or there is not enough
- * output space, then a positive error is returned.
- *
- * The input function is invoked: len = infun(how, &buf), where buf is set by
- * infun() to point to the input buffer, and infun() returns the number of
- * available bytes there. If infun() returns zero, then blast() returns with
- * an input error. (blast() only asks for input if it needs it.) inhow is for
- * use by the application to pass an input descriptor to infun(), if desired.
- *
- * The output function is invoked: err = outfun(how, buf, len), where the bytes
- * to be written are buf[0..len-1]. If err is not zero, then blast() returns
- * with an output error. outfun() is always called with len <= 4096. outhow
- * is for use by the application to pass an output descriptor to outfun(), if
- * desired.
- *
- * The return codes are:
- *
- * 2: ran out of input before completing decompression
- * 1: output error before completing decompression
- * 0: successful decompression
- * -1: literal flag not zero or one
- * -2: dictionary size not in 4..6
- * -3: distance is too far back
- *
- * At the bottom of blast.c is an example program that uses blast() that can be
- * compiled to produce a command-line decompression filter by defining TEST.
- */
diff --git a/cpukit/zlib/contrib/blast/test.pk b/cpukit/zlib/contrib/blast/test.pk
deleted file mode 100644
index be10b2bbb2..0000000000
--- a/cpukit/zlib/contrib/blast/test.pk
+++ /dev/null
Binary files differ
diff --git a/cpukit/zlib/contrib/blast/test.txt b/cpukit/zlib/contrib/blast/test.txt
deleted file mode 100644
index bfdf1c5dca..0000000000
--- a/cpukit/zlib/contrib/blast/test.txt
+++ /dev/null
@@ -1 +0,0 @@
-AIAIAIAIAIAIA \ No newline at end of file
diff --git a/cpukit/zlib/contrib/delphi/ZLib.pas b/cpukit/zlib/contrib/delphi/ZLib.pas
deleted file mode 100644
index b9d33e2d72..0000000000
--- a/cpukit/zlib/contrib/delphi/ZLib.pas
+++ /dev/null
@@ -1,557 +0,0 @@
-{*******************************************************}
-{ }
-{ Borland Delphi Supplemental Components }
-{ ZLIB Data Compression Interface Unit }
-{ }
-{ Copyright (c) 1997,99 Borland Corporation }
-{ }
-{*******************************************************}
-
-{ Updated for zlib 1.2.x by Cosmin Truta <cosmint@cs.ubbcluj.ro> }
-
-unit ZLib;
-
-interface
-
-uses SysUtils, Classes;
-
-type
- TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
- TFree = procedure (AppData, Block: Pointer); cdecl;
-
- // Internal structure. Ignore.
- TZStreamRec = packed record
- next_in: PChar; // next input byte
- avail_in: Integer; // number of bytes available at next_in
- total_in: Longint; // total nb of input bytes read so far
-
- next_out: PChar; // next output byte should be put here
- avail_out: Integer; // remaining free space at next_out
- total_out: Longint; // total nb of bytes output so far
-
- msg: PChar; // last error message, NULL if no error
- internal: Pointer; // not visible by applications
-
- zalloc: TAlloc; // used to allocate the internal state
- zfree: TFree; // used to free the internal state
- AppData: Pointer; // private data object passed to zalloc and zfree
-
- data_type: Integer; // best guess about the data type: ascii or binary
- adler: Longint; // adler32 value of the uncompressed data
- reserved: Longint; // reserved for future use
- end;
-
- // Abstract ancestor class
- TCustomZlibStream = class(TStream)
- private
- FStrm: TStream;
- FStrmPos: Integer;
- FOnProgress: TNotifyEvent;
- FZRec: TZStreamRec;
- FBuffer: array [Word] of Char;
- protected
- procedure Progress(Sender: TObject); dynamic;
- property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
- constructor Create(Strm: TStream);
- end;
-
-{ TCompressionStream compresses data on the fly as data is written to it, and
- stores the compressed data to another stream.
-
- TCompressionStream is write-only and strictly sequential. Reading from the
- stream will raise an exception. Using Seek to move the stream pointer
- will raise an exception.
-
- Output data is cached internally, written to the output stream only when
- the internal output buffer is full. All pending output data is flushed
- when the stream is destroyed.
-
- The Position property returns the number of uncompressed bytes of
- data that have been written to the stream so far.
-
- CompressionRate returns the on-the-fly percentage by which the original
- data has been compressed: (1 - (CompressedBytes / UncompressedBytes)) * 100
- If raw data size = 100 and compressed data size = 25, the CompressionRate
- is 75%
-
- The OnProgress event is called each time the output buffer is filled and
- written to the output stream. This is useful for updating a progress
- indicator when you are writing a large chunk of data to the compression
- stream in a single call.}
-
-
- TCompressionLevel = (clNone, clFastest, clDefault, clMax);
-
- TCompressionStream = class(TCustomZlibStream)
- private
- function GetCompressionRate: Single;
- public
- constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream);
- destructor Destroy; override;
- function Read(var Buffer; Count: Longint): Longint; override;
- function Write(const Buffer; Count: Longint): Longint; override;
- function Seek(Offset: Longint; Origin: Word): Longint; override;
- property CompressionRate: Single read GetCompressionRate;
- property OnProgress;
- end;
-
-{ TDecompressionStream decompresses data on the fly as data is read from it.
-
- Compressed data comes from a separate source stream. TDecompressionStream
- is read-only and unidirectional; you can seek forward in the stream, but not
- backwards. The special case of setting the stream position to zero is
- allowed. Seeking forward decompresses data until the requested position in
- the uncompressed data has been reached. Seeking backwards, seeking relative
- to the end of the stream, requesting the size of the stream, and writing to
- the stream will raise an exception.
-
- The Position property returns the number of bytes of uncompressed data that
- have been read from the stream so far.
-
- The OnProgress event is called each time the internal input buffer of
- compressed data is exhausted and the next block is read from the input stream.
- This is useful for updating a progress indicator when you are reading a
- large chunk of data from the decompression stream in a single call.}
-
- TDecompressionStream = class(TCustomZlibStream)
- public
- constructor Create(Source: TStream);
- destructor Destroy; override;
- function Read(var Buffer; Count: Longint): Longint; override;
- function Write(const Buffer; Count: Longint): Longint; override;
- function Seek(Offset: Longint; Origin: Word): Longint; override;
- property OnProgress;
- end;
-
-
-
-{ CompressBuf compresses data, buffer to buffer, in one call.
- In: InBuf = ptr to compressed data
- InBytes = number of bytes in InBuf
- Out: OutBuf = ptr to newly allocated buffer containing decompressed data
- OutBytes = number of bytes in OutBuf }
-procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
- out OutBuf: Pointer; out OutBytes: Integer);
-
-
-{ DecompressBuf decompresses data, buffer to buffer, in one call.
- In: InBuf = ptr to compressed data
- InBytes = number of bytes in InBuf
- OutEstimate = zero, or est. size of the decompressed data
- Out: OutBuf = ptr to newly allocated buffer containing decompressed data
- OutBytes = number of bytes in OutBuf }
-procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
- OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
-
-{ DecompressToUserBuf decompresses data, buffer to buffer, in one call.
- In: InBuf = ptr to compressed data
- InBytes = number of bytes in InBuf
- Out: OutBuf = ptr to user-allocated buffer to contain decompressed data
- BufSize = number of bytes in OutBuf }
-procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
- const OutBuf: Pointer; BufSize: Integer);
-
-const
- zlib_version = '1.2.2';
-
-type
- EZlibError = class(Exception);
- ECompressionError = class(EZlibError);
- EDecompressionError = class(EZlibError);
-
-implementation
-
-uses ZLibConst;
-
-const
- Z_NO_FLUSH = 0;
- Z_PARTIAL_FLUSH = 1;
- Z_SYNC_FLUSH = 2;
- Z_FULL_FLUSH = 3;
- Z_FINISH = 4;
-
- Z_OK = 0;
- Z_STREAM_END = 1;
- Z_NEED_DICT = 2;
- Z_ERRNO = (-1);
- Z_STREAM_ERROR = (-2);
- Z_DATA_ERROR = (-3);
- Z_MEM_ERROR = (-4);
- Z_BUF_ERROR = (-5);
- Z_VERSION_ERROR = (-6);
-
- Z_NO_COMPRESSION = 0;
- Z_BEST_SPEED = 1;
- Z_BEST_COMPRESSION = 9;
- Z_DEFAULT_COMPRESSION = (-1);
-
- Z_FILTERED = 1;
- Z_HUFFMAN_ONLY = 2;
- Z_RLE = 3;
- Z_DEFAULT_STRATEGY = 0;
-
- Z_BINARY = 0;
- Z_ASCII = 1;
- Z_UNKNOWN = 2;
-
- Z_DEFLATED = 8;
-
-
-{$L adler32.obj}
-{$L compress.obj}
-{$L crc32.obj}
-{$L deflate.obj}
-{$L infback.obj}
-{$L inffast.obj}
-{$L inflate.obj}
-{$L inftrees.obj}
-{$L trees.obj}
-{$L uncompr.obj}
-{$L zutil.obj}
-
-procedure adler32; external;
-procedure compressBound; external;
-procedure crc32; external;
-procedure deflateInit2_; external;
-procedure deflateParams; external;
-
-function _malloc(Size: Integer): Pointer; cdecl;
-begin
- Result := AllocMem(Size);
-end;
-
-procedure _free(Block: Pointer); cdecl;
-begin
- FreeMem(Block);
-end;
-
-procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;
-begin
- FillChar(P^, count, B);
-end;
-
-procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
-begin
- Move(source^, dest^, count);
-end;
-
-
-
-// deflate compresses data
-function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
- recsize: Integer): Integer; external;
-function deflate(var strm: TZStreamRec; flush: Integer): Integer; external;
-function deflateEnd(var strm: TZStreamRec): Integer; external;
-
-// inflate decompresses data
-function inflateInit_(var strm: TZStreamRec; version: PChar;
- recsize: Integer): Integer; external;
-function inflate(var strm: TZStreamRec; flush: Integer): Integer; external;
-function inflateEnd(var strm: TZStreamRec): Integer; external;
-function inflateReset(var strm: TZStreamRec): Integer; external;
-
-
-function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
-begin
-// GetMem(Result, Items*Size);
- Result := AllocMem(Items * Size);
-end;
-
-procedure zlibFreeMem(AppData, Block: Pointer); cdecl;
-begin
- FreeMem(Block);
-end;
-
-{function zlibCheck(code: Integer): Integer;
-begin
- Result := code;
- if code < 0 then
- raise EZlibError.Create('error'); //!!
-end;}
-
-function CCheck(code: Integer): Integer;
-begin
- Result := code;
- if code < 0 then
- raise ECompressionError.Create('error'); //!!
-end;
-
-function DCheck(code: Integer): Integer;
-begin
- Result := code;
- if code < 0 then
- raise EDecompressionError.Create('error'); //!!
-end;
-
-procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
- out OutBuf: Pointer; out OutBytes: Integer);
-var
- strm: TZStreamRec;
- P: Pointer;
-begin
- FillChar(strm, sizeof(strm), 0);
- strm.zalloc := zlibAllocMem;
- strm.zfree := zlibFreeMem;
- OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
- GetMem(OutBuf, OutBytes);
- try
- strm.next_in := InBuf;
- strm.avail_in := InBytes;
- strm.next_out := OutBuf;
- strm.avail_out := OutBytes;
- CCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm)));
- try
- while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do
- begin
- P := OutBuf;
- Inc(OutBytes, 256);
- ReallocMem(OutBuf, OutBytes);
- strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
- strm.avail_out := 256;
- end;
- finally
- CCheck(deflateEnd(strm));
- end;
- ReallocMem(OutBuf, strm.total_out);
- OutBytes := strm.total_out;
- except
- FreeMem(OutBuf);
- raise
- end;
-end;
-
-
-procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
- OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
-var
- strm: TZStreamRec;
- P: Pointer;
- BufInc: Integer;
-begin
- FillChar(strm, sizeof(strm), 0);
- strm.zalloc := zlibAllocMem;
- strm.zfree := zlibFreeMem;
- BufInc := (InBytes + 255) and not 255;
- if OutEstimate = 0 then
- OutBytes := BufInc
- else
- OutBytes := OutEstimate;
- GetMem(OutBuf, OutBytes);
- try
- strm.next_in := InBuf;
- strm.avail_in := InBytes;
- strm.next_out := OutBuf;
- strm.avail_out := OutBytes;
- DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
- try
- while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do
- begin
- P := OutBuf;
- Inc(OutBytes, BufInc);
- ReallocMem(OutBuf, OutBytes);
- strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
- strm.avail_out := BufInc;
- end;
- finally
- DCheck(inflateEnd(strm));
- end;
- ReallocMem(OutBuf, strm.total_out);
- OutBytes := strm.total_out;
- except
- FreeMem(OutBuf);
- raise
- end;
-end;
-
-procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
- const OutBuf: Pointer; BufSize: Integer);
-var
- strm: TZStreamRec;
-begin
- FillChar(strm, sizeof(strm), 0);
- strm.zalloc := zlibAllocMem;
- strm.zfree := zlibFreeMem;
- strm.next_in := InBuf;
- strm.avail_in := InBytes;
- strm.next_out := OutBuf;
- strm.avail_out := BufSize;
- DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
- try
- if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then
- raise EZlibError.CreateRes(@sTargetBufferTooSmall);
- finally
- DCheck(inflateEnd(strm));
- end;
-end;
-
-// TCustomZlibStream
-
-constructor TCustomZLibStream.Create(Strm: TStream);
-begin
- inherited Create;
- FStrm := Strm;
- FStrmPos := Strm.Position;
- FZRec.zalloc := zlibAllocMem;
- FZRec.zfree := zlibFreeMem;
-end;
-
-procedure TCustomZLibStream.Progress(Sender: TObject);
-begin
- if Assigned(FOnProgress) then FOnProgress(Sender);
-end;
-
-
-// TCompressionStream
-
-constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel;
- Dest: TStream);
-const
- Levels: array [TCompressionLevel] of ShortInt =
- (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
-begin
- inherited Create(Dest);
- FZRec.next_out := FBuffer;
- FZRec.avail_out := sizeof(FBuffer);
- CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec)));
-end;
-
-destructor TCompressionStream.Destroy;
-begin
- FZRec.next_in := nil;
- FZRec.avail_in := 0;
- try
- if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
- while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END)
- and (FZRec.avail_out = 0) do
- begin
- FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
- FZRec.next_out := FBuffer;
- FZRec.avail_out := sizeof(FBuffer);
- end;
- if FZRec.avail_out < sizeof(FBuffer) then
- FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out);
- finally
- deflateEnd(FZRec);
- end;
- inherited Destroy;
-end;
-
-function TCompressionStream.Read(var Buffer; Count: Longint): Longint;
-begin
- raise ECompressionError.CreateRes(@sInvalidStreamOp);
-end;
-
-function TCompressionStream.Write(const Buffer; Count: Longint): Longint;
-begin
- FZRec.next_in := @Buffer;
- FZRec.avail_in := Count;
- if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
- while (FZRec.avail_in > 0) do
- begin
- CCheck(deflate(FZRec, 0));
- if FZRec.avail_out = 0 then
- begin
- FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
- FZRec.next_out := FBuffer;
- FZRec.avail_out := sizeof(FBuffer);
- FStrmPos := FStrm.Position;
- Progress(Self);
- end;
- end;
- Result := Count;
-end;
-
-function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
-begin
- if (Offset = 0) and (Origin = soFromCurrent) then
- Result := FZRec.total_in
- else
- raise ECompressionError.CreateRes(@sInvalidStreamOp);
-end;
-
-function TCompressionStream.GetCompressionRate: Single;
-begin
- if FZRec.total_in = 0 then
- Result := 0
- else
- Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0;
-end;
-
-
-// TDecompressionStream
-
-constructor TDecompressionStream.Create(Source: TStream);
-begin
- inherited Create(Source);
- FZRec.next_in := FBuffer;
- FZRec.avail_in := 0;
- DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec)));
-end;
-
-destructor TDecompressionStream.Destroy;
-begin
- FStrm.Seek(-FZRec.avail_in, 1);
- inflateEnd(FZRec);
- inherited Destroy;
-end;
-
-function TDecompressionStream.Read(var Buffer; Count: Longint): Longint;
-begin
- FZRec.next_out := @Buffer;
- FZRec.avail_out := Count;
- if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
- while (FZRec.avail_out > 0) do
- begin
- if FZRec.avail_in = 0 then
- begin
- FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));
- if FZRec.avail_in = 0 then
- begin
- Result := Count - FZRec.avail_out;
- Exit;
- end;
- FZRec.next_in := FBuffer;
- FStrmPos := FStrm.Position;
- Progress(Self);
- end;
- CCheck(inflate(FZRec, 0));
- end;
- Result := Count;
-end;
-
-function TDecompressionStream.Write(const Buffer; Count: Longint): Longint;
-begin
- raise EDecompressionError.CreateRes(@sInvalidStreamOp);
-end;
-
-function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
-var
- I: Integer;
- Buf: array [0..4095] of Char;
-begin
- if (Offset = 0) and (Origin = soFromBeginning) then
- begin
- DCheck(inflateReset(FZRec));
- FZRec.next_in := FBuffer;
- FZRec.avail_in := 0;
- FStrm.Position := 0;
- FStrmPos := 0;
- end
- else if ( (Offset >= 0) and (Origin = soFromCurrent)) or
- ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then
- begin
- if Origin = soFromBeginning then Dec(Offset, FZRec.total_out);
- if Offset > 0 then
- begin
- for I := 1 to Offset div sizeof(Buf) do
- ReadBuffer(Buf, sizeof(Buf));
- ReadBuffer(Buf, Offset mod sizeof(Buf));
- end;
- end
- else
- raise EDecompressionError.CreateRes(@sInvalidStreamOp);
- Result := FZRec.total_out;
-end;
-
-
-end.
diff --git a/cpukit/zlib/contrib/delphi/ZLibConst.pas b/cpukit/zlib/contrib/delphi/ZLibConst.pas
deleted file mode 100644
index cdfe13671d..0000000000
--- a/cpukit/zlib/contrib/delphi/ZLibConst.pas
+++ /dev/null
@@ -1,11 +0,0 @@
-unit ZLibConst;
-
-interface
-
-resourcestring
- sTargetBufferTooSmall = 'ZLib error: target buffer may be too small';
- sInvalidStreamOp = 'Invalid stream operation';
-
-implementation
-
-end.
diff --git a/cpukit/zlib/contrib/delphi/readme.txt b/cpukit/zlib/contrib/delphi/readme.txt
deleted file mode 100644
index 2dc9a8bba2..0000000000
--- a/cpukit/zlib/contrib/delphi/readme.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-
-Overview
-========
-
-This directory contains an update to the ZLib interface unit,
-distributed by Borland as a Delphi supplemental component.
-
-The original ZLib unit is Copyright (c) 1997,99 Borland Corp.,
-and is based on zlib version 1.0.4. There are a series of bugs
-and security problems associated with that old zlib version, and
-we recommend the users to update their ZLib unit.
-
-
-Summary of modifications
-========================
-
-- Improved makefile, adapted to zlib version 1.2.1.
-
-- Some field types from TZStreamRec are changed from Integer to
- Longint, for consistency with the zlib.h header, and for 64-bit
- readiness.
-
-- The zlib_version constant is updated.
-
-- The new Z_RLE strategy has its corresponding symbolic constant.
-
-- The allocation and deallocation functions and function types
- (TAlloc, TFree, zlibAllocMem and zlibFreeMem) are now cdecl,
- and _malloc and _free are added as C RTL stubs. As a result,
- the original C sources of zlib can be compiled out of the box,
- and linked to the ZLib unit.
-
-
-Suggestions for improvements
-============================
-
-Currently, the ZLib unit provides only a limited wrapper around
-the zlib library, and much of the original zlib functionality is
-missing. Handling compressed file formats like ZIP/GZIP or PNG
-cannot be implemented without having this functionality.
-Applications that handle these formats are either using their own,
-duplicated code, or not using the ZLib unit at all.
-
-Here are a few suggestions:
-
-- Checksum class wrappers around adler32() and crc32(), similar
- to the Java classes that implement the java.util.zip.Checksum
- interface.
-
-- The ability to read and write raw deflate streams, without the
- zlib stream header and trailer. Raw deflate streams are used
- in the ZIP file format.
-
-- The ability to read and write gzip streams, used in the GZIP
- file format, and normally produced by the gzip program.
-
-- The ability to select a different compression strategy, useful
- to PNG and MNG image compression, and to multimedia compression
- in general. Besides the compression level
-
- TCompressionLevel = (clNone, clFastest, clDefault, clMax);
-
- which, in fact, could have used the 'z' prefix and avoided
- TColor-like symbols
-
- TCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax);
-
- there could be a compression strategy
-
- TCompressionStrategy = (zsDefault, zsFiltered, zsHuffmanOnly, zsRle);
-
-- ZIP and GZIP stream handling via TStreams.
-
-
---
-Cosmin Truta <cosmint@cs.ubbcluj.ro>
diff --git a/cpukit/zlib/contrib/delphi/zlibd32.mak b/cpukit/zlib/contrib/delphi/zlibd32.mak
deleted file mode 100644
index 88fafa0b14..0000000000
--- a/cpukit/zlib/contrib/delphi/zlibd32.mak
+++ /dev/null
@@ -1,93 +0,0 @@
-# Makefile for zlib
-# For use with Delphi and C++ Builder under Win32
-# Updated for zlib 1.2.x by Cosmin Truta
-
-# ------------ Borland C++ ------------
-
-# This project uses the Delphi (fastcall/register) calling convention:
-LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl
-
-CC = bcc32
-LD = bcc32
-AR = tlib
-# do not use "-pr" in CFLAGS
-CFLAGS = -a -d -k- -O2 $(LOC)
-LDFLAGS =
-
-
-# variables
-ZLIB_LIB = zlib.lib
-
-OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
-OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
-OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infback.obj
-OBJP2 = +inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
-
-
-# targets
-all: $(ZLIB_LIB) example.exe minigzip.exe
-
-.c.obj:
- $(CC) -c $(CFLAGS) $*.c
-
-adler32.obj: adler32.c zlib.h zconf.h
-
-compress.obj: compress.c zlib.h zconf.h
-
-crc32.obj: crc32.c zlib.h zconf.h crc32.h
-
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
-
-gzio.obj: gzio.c zutil.h zlib.h zconf.h
-
-infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h
-
-inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
-
-trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
-
-uncompr.obj: uncompr.c zlib.h zconf.h
-
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
-
-example.obj: example.c zlib.h zconf.h
-
-minigzip.obj: minigzip.c zlib.h zconf.h
-
-
-# For the sake of the old Borland make,
-# the command line is cut to fit in the MS-DOS 128 byte limit:
-$(ZLIB_LIB): $(OBJ1) $(OBJ2)
- -del $(ZLIB_LIB)
- $(AR) $(ZLIB_LIB) $(OBJP1)
- $(AR) $(ZLIB_LIB) $(OBJP2)
-
-
-# testing
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-example.exe: example.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
-
-minigzip.exe: minigzip.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
-
-
-# cleanup
-clean:
- -del *.obj
- -del *.exe
- -del *.lib
- -del *.tds
- -del zlib.bak
- -del foo.gz
-
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib.build b/cpukit/zlib/contrib/dotzlib/DotZLib.build
deleted file mode 100644
index 7f90d6bc7c..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib.build
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<project name="DotZLib" default="build" basedir="./DotZLib">
- <description>A .Net wrapper library around ZLib1.dll</description>
-
- <property name="nunit.location" value="c:/program files/NUnit V2.1/bin" />
- <property name="build.root" value="bin" />
-
- <property name="debug" value="true" />
- <property name="nunit" value="true" />
-
- <property name="build.folder" value="${build.root}/debug/" if="${debug}" />
- <property name="build.folder" value="${build.root}/release/" unless="${debug}" />
-
- <target name="clean" description="Remove all generated files">
- <delete dir="${build.root}" failonerror="false" />
- </target>
-
- <target name="build" description="compiles the source code">
-
- <mkdir dir="${build.folder}" />
- <csc target="library" output="${build.folder}DotZLib.dll" debug="${debug}">
- <references basedir="${nunit.location}">
- <includes if="${nunit}" name="nunit.framework.dll" />
- </references>
- <sources>
- <includes name="*.cs" />
- <excludes name="UnitTests.cs" unless="${nunit}" />
- </sources>
- <arg value="/d:nunit" if="${nunit}" />
- </csc>
- </target>
-
-</project> \ No newline at end of file
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib.chm b/cpukit/zlib/contrib/dotzlib/DotZLib.chm
deleted file mode 100644
index f214a444ae..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib.chm
+++ /dev/null
Binary files differ
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib.sln b/cpukit/zlib/contrib/dotzlib/DotZLib.sln
deleted file mode 100644
index ac45ca048b..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib.sln
+++ /dev/null
@@ -1,21 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- Debug = Debug
- Release = Release
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET
- {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET
- {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET
- {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs b/cpukit/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs
deleted file mode 100644
index 0491bfc2b0..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-//
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-//
-[assembly: AssemblyTitle("DotZLib")]
-[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Henrik Ravn")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-//
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Revision and Build Numbers
-// by using the '*' as shown below:
-
-[assembly: AssemblyVersion("1.0.*")]
-
-//
-// In order to sign your assembly you must specify a key to use. Refer to the
-// Microsoft .NET Framework documentation for more information on assembly signing.
-//
-// Use the attributes below to control which key is used for signing.
-//
-// Notes:
-// (*) If no key is specified, the assembly is not signed.
-// (*) KeyName refers to a key that has been installed in the Crypto Service
-// Provider (CSP) on your machine. KeyFile refers to a file which contains
-// a key.
-// (*) If the KeyFile and the KeyName values are both specified, the
-// following processing occurs:
-// (1) If the KeyName can be found in the CSP, that key is used.
-// (2) If the KeyName does not exist and the KeyFile does exist, the key
-// in the KeyFile is installed into the CSP and used.
-// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
-// When specifying the KeyFile, the location of the KeyFile should be
-// relative to the project output directory which is
-// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
-// located in the project directory, you would specify the AssemblyKeyFile
-// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
-// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
-// documentation for more information on this.
-//
-[assembly: AssemblyDelaySign(false)]
-[assembly: AssemblyKeyFile("")]
-[assembly: AssemblyKeyName("")]
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs b/cpukit/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs
deleted file mode 100644
index 788b2fcece..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs
+++ /dev/null
@@ -1,202 +0,0 @@
-//
-// © Copyright Henrik Ravn 2004
-//
-// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-using System;
-using System.Runtime.InteropServices;
-using System.Text;
-
-
-namespace DotZLib
-{
- #region ChecksumGeneratorBase
- /// <summary>
- /// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s
- /// </summary>
- /// <example></example>
- public abstract class ChecksumGeneratorBase : ChecksumGenerator
- {
- /// <summary>
- /// The value of the current checksum
- /// </summary>
- protected uint _current;
-
- /// <summary>
- /// Initializes a new instance of the checksum generator base - the current checksum is
- /// set to zero
- /// </summary>
- public ChecksumGeneratorBase()
- {
- _current = 0;
- }
-
- /// <summary>
- /// Initializes a new instance of the checksum generator basewith a specified value
- /// </summary>
- /// <param name="initialValue">The value to set the current checksum to</param>
- public ChecksumGeneratorBase(uint initialValue)
- {
- _current = initialValue;
- }
-
- /// <summary>
- /// Resets the current checksum to zero
- /// </summary>
- public void Reset() { _current = 0; }
-
- /// <summary>
- /// Gets the current checksum value
- /// </summary>
- public uint Value { get { return _current; } }
-
- /// <summary>
- /// Updates the current checksum with part of an array of bytes
- /// </summary>
- /// <param name="data">The data to update the checksum with</param>
- /// <param name="offset">Where in <c>data</c> to start updating</param>
- /// <param name="count">The number of bytes from <c>data</c> to use</param>
- /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
- /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
- /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
- /// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one.
- /// This is therefore the only method a derived class has to implement</remarks>
- public abstract void Update(byte[] data, int offset, int count);
-
- /// <summary>
- /// Updates the current checksum with an array of bytes.
- /// </summary>
- /// <param name="data">The data to update the checksum with</param>
- public void Update(byte[] data)
- {
- Update(data, 0, data.Length);
- }
-
- /// <summary>
- /// Updates the current checksum with the data from a string
- /// </summary>
- /// <param name="data">The string to update the checksum with</param>
- /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
- public void Update(string data)
- {
- Update(Encoding.UTF8.GetBytes(data));
- }
-
- /// <summary>
- /// Updates the current checksum with the data from a string, using a specific encoding
- /// </summary>
- /// <param name="data">The string to update the checksum with</param>
- /// <param name="encoding">The encoding to use</param>
- public void Update(string data, Encoding encoding)
- {
- Update(encoding.GetBytes(data));
- }
-
- }
- #endregion
-
- #region CRC32
- /// <summary>
- /// Implements a CRC32 checksum generator
- /// </summary>
- public sealed class CRC32Checksum : ChecksumGeneratorBase
- {
- #region DLL imports
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern uint crc32(uint crc, int data, uint length);
-
- #endregion
-
- /// <summary>
- /// Initializes a new instance of the CRC32 checksum generator
- /// </summary>
- public CRC32Checksum() : base() {}
-
- /// <summary>
- /// Initializes a new instance of the CRC32 checksum generator with a specified value
- /// </summary>
- /// <param name="initialValue">The value to set the current checksum to</param>
- public CRC32Checksum(uint initialValue) : base(initialValue) {}
-
- /// <summary>
- /// Updates the current checksum with part of an array of bytes
- /// </summary>
- /// <param name="data">The data to update the checksum with</param>
- /// <param name="offset">Where in <c>data</c> to start updating</param>
- /// <param name="count">The number of bytes from <c>data</c> to use</param>
- /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
- /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
- /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
- public override void Update(byte[] data, int offset, int count)
- {
- if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
- if ((offset+count) > data.Length) throw new ArgumentException();
- GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
- try
- {
- _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
- }
- finally
- {
- hData.Free();
- }
- }
-
- }
- #endregion
-
- #region Adler
- /// <summary>
- /// Implements a checksum generator that computes the Adler checksum on data
- /// </summary>
- public sealed class AdlerChecksum : ChecksumGeneratorBase
- {
- #region DLL imports
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern uint adler32(uint adler, int data, uint length);
-
- #endregion
-
- /// <summary>
- /// Initializes a new instance of the Adler checksum generator
- /// </summary>
- public AdlerChecksum() : base() {}
-
- /// <summary>
- /// Initializes a new instance of the Adler checksum generator with a specified value
- /// </summary>
- /// <param name="initialValue">The value to set the current checksum to</param>
- public AdlerChecksum(uint initialValue) : base(initialValue) {}
-
- /// <summary>
- /// Updates the current checksum with part of an array of bytes
- /// </summary>
- /// <param name="data">The data to update the checksum with</param>
- /// <param name="offset">Where in <c>data</c> to start updating</param>
- /// <param name="count">The number of bytes from <c>data</c> to use</param>
- /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
- /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
- /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
- public override void Update(byte[] data, int offset, int count)
- {
- if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
- if ((offset+count) > data.Length) throw new ArgumentException();
- GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
- try
- {
- _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
- }
- finally
- {
- hData.Free();
- }
- }
-
- }
- #endregion
-
-} \ No newline at end of file
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs b/cpukit/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs
deleted file mode 100644
index c1cab3a02c..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-//
-// © Copyright Henrik Ravn 2004
-//
-// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-using System;
-using System.Diagnostics;
-
-namespace DotZLib
-{
-
- /// <summary>
- /// This class implements a circular buffer
- /// </summary>
- internal class CircularBuffer
- {
- #region Private data
- private int _capacity;
- private int _head;
- private int _tail;
- private int _size;
- private byte[] _buffer;
- #endregion
-
- public CircularBuffer(int capacity)
- {
- Debug.Assert( capacity > 0 );
- _buffer = new byte[capacity];
- _capacity = capacity;
- _head = 0;
- _tail = 0;
- _size = 0;
- }
-
- public int Size { get { return _size; } }
-
- public int Put(byte[] source, int offset, int count)
- {
- Debug.Assert( count > 0 );
- int trueCount = Math.Min(count, _capacity - Size);
- for (int i = 0; i < trueCount; ++i)
- _buffer[(_tail+i) % _capacity] = source[offset+i];
- _tail += trueCount;
- _tail %= _capacity;
- _size += trueCount;
- return trueCount;
- }
-
- public bool Put(byte b)
- {
- if (Size == _capacity) // no room
- return false;
- _buffer[_tail++] = b;
- _tail %= _capacity;
- ++_size;
- return true;
- }
-
- public int Get(byte[] destination, int offset, int count)
- {
- int trueCount = Math.Min(count,Size);
- for (int i = 0; i < trueCount; ++i)
- destination[offset + i] = _buffer[(_head+i) % _capacity];
- _head += trueCount;
- _head %= _capacity;
- _size -= trueCount;
- return trueCount;
- }
-
- public int Get()
- {
- if (Size == 0)
- return -1;
-
- int result = (int)_buffer[_head++ % _capacity];
- --_size;
- return result;
- }
-
- }
-}
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib/CodecBase.cs b/cpukit/zlib/contrib/dotzlib/DotZLib/CodecBase.cs
deleted file mode 100644
index 42e6da3a56..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib/CodecBase.cs
+++ /dev/null
@@ -1,198 +0,0 @@
-//
-// © Copyright Henrik Ravn 2004
-//
-// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace DotZLib
-{
- /// <summary>
- /// Implements the common functionality needed for all <see cref="Codec"/>s
- /// </summary>
- public abstract class CodecBase : Codec, IDisposable
- {
-
- #region Data members
-
- /// <summary>
- /// Instance of the internal zlib buffer structure that is
- /// passed to all functions in the zlib dll
- /// </summary>
- internal ZStream _ztream = new ZStream();
-
- /// <summary>
- /// True if the object instance has been disposed, false otherwise
- /// </summary>
- protected bool _isDisposed = false;
-
- /// <summary>
- /// The size of the internal buffers
- /// </summary>
- protected const int kBufferSize = 16384;
-
- private byte[] _outBuffer = new byte[kBufferSize];
- private byte[] _inBuffer = new byte[kBufferSize];
-
- private GCHandle _hInput;
- private GCHandle _hOutput;
-
- private uint _checksum = 0;
-
- #endregion
-
- /// <summary>
- /// Initializes a new instance of the <c>CodeBase</c> class.
- /// </summary>
- public CodecBase()
- {
- try
- {
- _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);
- _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);
- }
- catch (Exception)
- {
- CleanUp(false);
- throw;
- }
- }
-
-
- #region Codec Members
-
- /// <summary>
- /// Occurs when more processed data are available.
- /// </summary>
- public event DataAvailableHandler DataAvailable;
-
- /// <summary>
- /// Fires the <see cref="DataAvailable"/> event
- /// </summary>
- protected void OnDataAvailable()
- {
- if (_ztream.total_out > 0)
- {
- if (DataAvailable != null)
- DataAvailable( _outBuffer, 0, (int)_ztream.total_out);
- resetOutput();
- }
- }
-
- /// <summary>
- /// Adds more data to the codec to be processed.
- /// </summary>
- /// <param name="data">Byte array containing the data to be added to the codec</param>
- /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
- public void Add(byte[] data)
- {
- Add(data,0,data.Length);
- }
-
- /// <summary>
- /// Adds more data to the codec to be processed.
- /// </summary>
- /// <param name="data">Byte array containing the data to be added to the codec</param>
- /// <param name="offset">The index of the first byte to add from <c>data</c></param>
- /// <param name="count">The number of bytes to add</param>
- /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
- /// <remarks>This must be implemented by a derived class</remarks>
- public abstract void Add(byte[] data, int offset, int count);
-
- /// <summary>
- /// Finishes up any pending data that needs to be processed and handled.
- /// </summary>
- /// <remarks>This must be implemented by a derived class</remarks>
- public abstract void Finish();
-
- /// <summary>
- /// Gets the checksum of the data that has been added so far
- /// </summary>
- public uint Checksum { get { return _checksum; } }
-
- #endregion
-
- #region Destructor & IDisposable stuff
-
- /// <summary>
- /// Destroys this instance
- /// </summary>
- ~CodecBase()
- {
- CleanUp(false);
- }
-
- /// <summary>
- /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class
- /// </summary>
- public void Dispose()
- {
- CleanUp(true);
- }
-
- /// <summary>
- /// Performs any codec specific cleanup
- /// </summary>
- /// <remarks>This must be implemented by a derived class</remarks>
- protected abstract void CleanUp();
-
- // performs the release of the handles and calls the dereived CleanUp()
- private void CleanUp(bool isDisposing)
- {
- if (!_isDisposed)
- {
- CleanUp();
- if (_hInput.IsAllocated)
- _hInput.Free();
- if (_hOutput.IsAllocated)
- _hOutput.Free();
-
- _isDisposed = true;
- }
- }
-
-
- #endregion
-
- #region Helper methods
-
- /// <summary>
- /// Copies a number of bytes to the internal codec buffer - ready for proccesing
- /// </summary>
- /// <param name="data">The byte array that contains the data to copy</param>
- /// <param name="startIndex">The index of the first byte to copy</param>
- /// <param name="count">The number of bytes to copy from <c>data</c></param>
- protected void copyInput(byte[] data, int startIndex, int count)
- {
- Array.Copy(data, startIndex, _inBuffer,0, count);
- _ztream.next_in = _hInput.AddrOfPinnedObject();
- _ztream.total_in = 0;
- _ztream.avail_in = (uint)count;
-
- }
-
- /// <summary>
- /// Resets the internal output buffers to a known state - ready for processing
- /// </summary>
- protected void resetOutput()
- {
- _ztream.total_out = 0;
- _ztream.avail_out = kBufferSize;
- _ztream.next_out = _hOutput.AddrOfPinnedObject();
- }
-
- /// <summary>
- /// Updates the running checksum property
- /// </summary>
- /// <param name="newSum">The new checksum value</param>
- protected void setChecksum(uint newSum)
- {
- _checksum = newSum;
- }
- #endregion
-
- }
-}
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib/Deflater.cs b/cpukit/zlib/contrib/dotzlib/DotZLib/Deflater.cs
deleted file mode 100644
index c2477925b6..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib/Deflater.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-//
-// © Copyright Henrik Ravn 2004
-//
-// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-using System;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace DotZLib
-{
-
- /// <summary>
- /// Implements a data compressor, using the deflate algorithm in the ZLib dll
- /// </summary>
- public sealed class Deflater : CodecBase
- {
- #region Dll imports
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
- private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size);
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern int deflate(ref ZStream sz, int flush);
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern int deflateReset(ref ZStream sz);
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern int deflateEnd(ref ZStream sz);
- #endregion
-
- /// <summary>
- /// Constructs an new instance of the <c>Deflater</c>
- /// </summary>
- /// <param name="level">The compression level to use for this <c>Deflater</c></param>
- public Deflater(CompressLevel level) : base()
- {
- int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream));
- if (retval != 0)
- throw new ZLibException(retval, "Could not initialize deflater");
-
- resetOutput();
- }
-
- /// <summary>
- /// Adds more data to the codec to be processed.
- /// </summary>
- /// <param name="data">Byte array containing the data to be added to the codec</param>
- /// <param name="offset">The index of the first byte to add from <c>data</c></param>
- /// <param name="count">The number of bytes to add</param>
- /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
- public override void Add(byte[] data, int offset, int count)
- {
- if (data == null) throw new ArgumentNullException();
- if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
- if ((offset+count) > data.Length) throw new ArgumentException();
-
- int total = count;
- int inputIndex = offset;
- int err = 0;
-
- while (err >= 0 && inputIndex < total)
- {
- copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
- while (err >= 0 && _ztream.avail_in > 0)
- {
- err = deflate(ref _ztream, (int)FlushTypes.None);
- if (err == 0)
- while (_ztream.avail_out == 0)
- {
- OnDataAvailable();
- err = deflate(ref _ztream, (int)FlushTypes.None);
- }
- inputIndex += (int)_ztream.total_in;
- }
- }
- setChecksum( _ztream.adler );
- }
-
-
- /// <summary>
- /// Finishes up any pending data that needs to be processed and handled.
- /// </summary>
- public override void Finish()
- {
- int err;
- do
- {
- err = deflate(ref _ztream, (int)FlushTypes.Finish);
- OnDataAvailable();
- }
- while (err == 0);
- setChecksum( _ztream.adler );
- deflateReset(ref _ztream);
- resetOutput();
- }
-
- /// <summary>
- /// Closes the internal zlib deflate stream
- /// </summary>
- protected override void CleanUp() { deflateEnd(ref _ztream); }
-
- }
-}
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib/DotZLib.cs b/cpukit/zlib/contrib/dotzlib/DotZLib/DotZLib.cs
deleted file mode 100644
index be184b4c71..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib/DotZLib.cs
+++ /dev/null
@@ -1,288 +0,0 @@
-//
-// © Copyright Henrik Ravn 2004
-//
-// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-using System;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Text;
-
-
-namespace DotZLib
-{
-
- #region Internal types
-
- /// <summary>
- /// Defines constants for the various flush types used with zlib
- /// </summary>
- internal enum FlushTypes
- {
- None, Partial, Sync, Full, Finish, Block
- }
-
- #region ZStream structure
- // internal mapping of the zlib zstream structure for marshalling
- [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)]
- internal struct ZStream
- {
- public IntPtr next_in;
- public uint avail_in;
- public uint total_in;
-
- public IntPtr next_out;
- public uint avail_out;
- public uint total_out;
-
- [MarshalAs(UnmanagedType.LPStr)]
- string msg;
- uint state;
-
- uint zalloc;
- uint zfree;
- uint opaque;
-
- int data_type;
- public uint adler;
- uint reserved;
- }
-
- #endregion
-
- #endregion
-
- #region Public enums
- /// <summary>
- /// Defines constants for the available compression levels in zlib
- /// </summary>
- public enum CompressLevel : int
- {
- /// <summary>
- /// The default compression level with a reasonable compromise between compression and speed
- /// </summary>
- Default = -1,
- /// <summary>
- /// No compression at all. The data are passed straight through.
- /// </summary>
- None = 0,
- /// <summary>
- /// The maximum compression rate available.
- /// </summary>
- Best = 9,
- /// <summary>
- /// The fastest available compression level.
- /// </summary>
- Fastest = 1
- }
- #endregion
-
- #region Exception classes
- /// <summary>
- /// The exception that is thrown when an error occurs on the zlib dll
- /// </summary>
- public class ZLibException : ApplicationException
- {
- /// <summary>
- /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
- /// error message and error code
- /// </summary>
- /// <param name="errorCode">The zlib error code that caused the exception</param>
- /// <param name="msg">A message that (hopefully) describes the error</param>
- public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg))
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
- /// error code
- /// </summary>
- /// <param name="errorCode">The zlib error code that caused the exception</param>
- public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode))
- {
- }
- }
- #endregion
-
- #region Interfaces
-
- /// <summary>
- /// Declares methods and properties that enables a running checksum to be calculated
- /// </summary>
- public interface ChecksumGenerator
- {
- /// <summary>
- /// Gets the current value of the checksum
- /// </summary>
- uint Value { get; }
-
- /// <summary>
- /// Clears the current checksum to 0
- /// </summary>
- void Reset();
-
- /// <summary>
- /// Updates the current checksum with an array of bytes
- /// </summary>
- /// <param name="data">The data to update the checksum with</param>
- void Update(byte[] data);
-
- /// <summary>
- /// Updates the current checksum with part of an array of bytes
- /// </summary>
- /// <param name="data">The data to update the checksum with</param>
- /// <param name="offset">Where in <c>data</c> to start updating</param>
- /// <param name="count">The number of bytes from <c>data</c> to use</param>
- /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
- /// <exception cref="ArgumentNullException"><c>data</c> is a null reference</exception>
- /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
- void Update(byte[] data, int offset, int count);
-
- /// <summary>
- /// Updates the current checksum with the data from a string
- /// </summary>
- /// <param name="data">The string to update the checksum with</param>
- /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
- void Update(string data);
-
- /// <summary>
- /// Updates the current checksum with the data from a string, using a specific encoding
- /// </summary>
- /// <param name="data">The string to update the checksum with</param>
- /// <param name="encoding">The encoding to use</param>
- void Update(string data, Encoding encoding);
- }
-
-
- /// <summary>
- /// Represents the method that will be called from a codec when new data
- /// are available.
- /// </summary>
- /// <paramref name="data">The byte array containing the processed data</paramref>
- /// <paramref name="startIndex">The index of the first processed byte in <c>data</c></paramref>
- /// <paramref name="count">The number of processed bytes available</paramref>
- /// <remarks>On return from this method, the data may be overwritten, so grab it while you can.
- /// You cannot assume that startIndex will be zero.
- /// </remarks>
- public delegate void DataAvailableHandler(byte[] data, int startIndex, int count);
-
- /// <summary>
- /// Declares methods and events for implementing compressors/decompressors
- /// </summary>
- public interface Codec
- {
- /// <summary>
- /// Occurs when more processed data are available.
- /// </summary>
- event DataAvailableHandler DataAvailable;
-
- /// <summary>
- /// Adds more data to the codec to be processed.
- /// </summary>
- /// <param name="data">Byte array containing the data to be added to the codec</param>
- /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
- void Add(byte[] data);
-
- /// <summary>
- /// Adds more data to the codec to be processed.
- /// </summary>
- /// <param name="data">Byte array containing the data to be added to the codec</param>
- /// <param name="offset">The index of the first byte to add from <c>data</c></param>
- /// <param name="count">The number of bytes to add</param>
- /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
- void Add(byte[] data, int offset, int count);
-
- /// <summary>
- /// Finishes up any pending data that needs to be processed and handled.
- /// </summary>
- void Finish();
-
- /// <summary>
- /// Gets the checksum of the data that has been added so far
- /// </summary>
- uint Checksum { get; }
-
-
- }
-
- #endregion
-
- #region Classes
- /// <summary>
- /// Encapsulates general information about the ZLib library
- /// </summary>
- public class Info
- {
- #region DLL imports
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern uint zlibCompileFlags();
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern string zlibVersion();
- #endregion
-
- #region Private stuff
- private uint _flags;
-
- // helper function that unpacks a bitsize mask
- private static int bitSize(uint bits)
- {
- switch (bits)
- {
- case 0: return 16;
- case 1: return 32;
- case 2: return 64;
- }
- return -1;
- }
- #endregion
-
- /// <summary>
- /// Constructs an instance of the <c>Info</c> class.
- /// </summary>
- public Info()
- {
- _flags = zlibCompileFlags();
- }
-
- /// <summary>
- /// True if the library is compiled with debug info
- /// </summary>
- public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } }
-
- /// <summary>
- /// True if the library is compiled with assembly optimizations
- /// </summary>
- public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } }
-
- /// <summary>
- /// Gets the size of the unsigned int that was compiled into Zlib
- /// </summary>
- public int SizeOfUInt { get { return bitSize(_flags & 3); } }
-
- /// <summary>
- /// Gets the size of the unsigned long that was compiled into Zlib
- /// </summary>
- public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } }
-
- /// <summary>
- /// Gets the size of the pointers that were compiled into Zlib
- /// </summary>
- public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } }
-
- /// <summary>
- /// Gets the size of the z_off_t type that was compiled into Zlib
- /// </summary>
- public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } }
-
- /// <summary>
- /// Gets the version of ZLib as a string, e.g. "1.2.1"
- /// </summary>
- public static string Version { get { return zlibVersion(); } }
- }
-
- #endregion
-
-}
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj b/cpukit/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj
deleted file mode 100644
index 71eeb8590a..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj
+++ /dev/null
@@ -1,141 +0,0 @@
-<VisualStudioProject>
- <CSHARP
- ProjectType = "Local"
- ProductVersion = "7.10.3077"
- SchemaVersion = "2.0"
- ProjectGuid = "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
- >
- <Build>
- <Settings
- ApplicationIcon = ""
- AssemblyKeyContainerName = ""
- AssemblyName = "DotZLib"
- AssemblyOriginatorKeyFile = ""
- DefaultClientScript = "JScript"
- DefaultHTMLPageLayout = "Grid"
- DefaultTargetSchema = "IE50"
- DelaySign = "false"
- OutputType = "Library"
- PreBuildEvent = ""
- PostBuildEvent = ""
- RootNamespace = "DotZLib"
- RunPostBuildEvent = "OnBuildSuccess"
- StartupObject = ""
- >
- <Config
- Name = "Debug"
- AllowUnsafeBlocks = "false"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "DEBUG;TRACE"
- DocumentationFile = "docs\DotZLib.xml"
- DebugSymbols = "true"
- FileAlignment = "4096"
- IncrementalBuild = "false"
- NoStdLib = "false"
- NoWarn = "1591"
- Optimize = "false"
- OutputPath = "bin\Debug\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- <Config
- Name = "Release"
- AllowUnsafeBlocks = "false"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "TRACE"
- DocumentationFile = "docs\DotZLib.xml"
- DebugSymbols = "false"
- FileAlignment = "4096"
- IncrementalBuild = "false"
- NoStdLib = "false"
- NoWarn = ""
- Optimize = "true"
- OutputPath = "bin\Release\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- </Settings>
- <References>
- <Reference
- Name = "System"
- AssemblyName = "System"
- HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.dll"
- />
- <Reference
- Name = "System.Data"
- AssemblyName = "System.Data"
- HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
- />
- <Reference
- Name = "System.XML"
- AssemblyName = "System.Xml"
- HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
- />
- <Reference
- Name = "nunit.framework"
- AssemblyName = "nunit.framework"
- HintPath = "E:\apps\NUnit V2.1\\bin\nunit.framework.dll"
- AssemblyFolderKey = "hklm\dn\nunit.framework"
- />
- </References>
- </Build>
- <Files>
- <Include>
- <File
- RelPath = "AssemblyInfo.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "ChecksumImpl.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "CircularBuffer.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "CodecBase.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "Deflater.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "DotZLib.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "GZipStream.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "Inflater.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "UnitTests.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- </Include>
- </Files>
- </CSHARP>
-</VisualStudioProject>
-
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib/GZipStream.cs b/cpukit/zlib/contrib/dotzlib/DotZLib/GZipStream.cs
deleted file mode 100644
index b161300b18..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib/GZipStream.cs
+++ /dev/null
@@ -1,301 +0,0 @@
-//
-// © Copyright Henrik Ravn 2004
-//
-// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-using System;
-using System.IO;
-using System.Runtime.InteropServices;
-
-namespace DotZLib
-{
- /// <summary>
- /// Implements a compressed <see cref="Stream"/>, in GZip (.gz) format.
- /// </summary>
- public class GZipStream : Stream, IDisposable
- {
- #region Dll Imports
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
- private static extern IntPtr gzopen(string name, string mode);
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern int gzclose(IntPtr gzFile);
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern int gzwrite(IntPtr gzFile, int data, int length);
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern int gzread(IntPtr gzFile, int data, int length);
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern int gzgetc(IntPtr gzFile);
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern int gzputc(IntPtr gzFile, int c);
-
- #endregion
-
- #region Private data
- private IntPtr _gzFile;
- private bool _isDisposed = false;
- private bool _isWriting;
- #endregion
-
- #region Constructors
- /// <summary>
- /// Creates a new file as a writeable GZipStream
- /// </summary>
- /// <param name="fileName">The name of the compressed file to create</param>
- /// <param name="level">The compression level to use when adding data</param>
- /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
- public GZipStream(string fileName, CompressLevel level)
- {
- _isWriting = true;
- _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level));
- if (_gzFile == IntPtr.Zero)
- throw new ZLibException(-1, "Could not open " + fileName);
- }
-
- /// <summary>
- /// Opens an existing file as a readable GZipStream
- /// </summary>
- /// <param name="fileName">The name of the file to open</param>
- /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
- public GZipStream(string fileName)
- {
- _isWriting = false;
- _gzFile = gzopen(fileName, "rb");
- if (_gzFile == IntPtr.Zero)
- throw new ZLibException(-1, "Could not open " + fileName);
-
- }
- #endregion
-
- #region Access properties
- /// <summary>
- /// Returns true of this stream can be read from, false otherwise
- /// </summary>
- public override bool CanRead
- {
- get
- {
- return !_isWriting;
- }
- }
-
-
- /// <summary>
- /// Returns false.
- /// </summary>
- public override bool CanSeek
- {
- get
- {
- return false;
- }
- }
-
- /// <summary>
- /// Returns true if this tsream is writeable, false otherwise
- /// </summary>
- public override bool CanWrite
- {
- get
- {
- return _isWriting;
- }
- }
- #endregion
-
- #region Destructor & IDispose stuff
-
- /// <summary>
- /// Destroys this instance
- /// </summary>
- ~GZipStream()
- {
- cleanUp(false);
- }
-
- /// <summary>
- /// Closes the external file handle
- /// </summary>
- public void Dispose()
- {
- cleanUp(true);
- }
-
- // Does the actual closing of the file handle.
- private void cleanUp(bool isDisposing)
- {
- if (!_isDisposed)
- {
- gzclose(_gzFile);
- _isDisposed = true;
- }
- }
- #endregion
-
- #region Basic reading and writing
- /// <summary>
- /// Attempts to read a number of bytes from the stream.
- /// </summary>
- /// <param name="buffer">The destination data buffer</param>
- /// <param name="offset">The index of the first destination byte in <c>buffer</c></param>
- /// <param name="count">The number of bytes requested</param>
- /// <returns>The number of bytes read</returns>
- /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
- /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
- /// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is &gt; buffer.Length</exception>
- /// <exception cref="NotSupportedException">If this stream is not readable.</exception>
- /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
- public override int Read(byte[] buffer, int offset, int count)
- {
- if (!CanRead) throw new NotSupportedException();
- if (buffer == null) throw new ArgumentNullException();
- if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
- if ((offset+count) > buffer.Length) throw new ArgumentException();
- if (_isDisposed) throw new ObjectDisposedException("GZipStream");
-
- GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
- int result;
- try
- {
- result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
- if (result < 0)
- throw new IOException();
- }
- finally
- {
- h.Free();
- }
- return result;
- }
-
- /// <summary>
- /// Attempts to read a single byte from the stream.
- /// </summary>
- /// <returns>The byte that was read, or -1 in case of error or End-Of-File</returns>
- public override int ReadByte()
- {
- if (!CanRead) throw new NotSupportedException();
- if (_isDisposed) throw new ObjectDisposedException("GZipStream");
- return gzgetc(_gzFile);
- }
-
- /// <summary>
- /// Writes a number of bytes to the stream
- /// </summary>
- /// <param name="buffer"></param>
- /// <param name="offset"></param>
- /// <param name="count"></param>
- /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
- /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
- /// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is &gt; buffer.Length</exception>
- /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
- /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
- public override void Write(byte[] buffer, int offset, int count)
- {
- if (!CanWrite) throw new NotSupportedException();
- if (buffer == null) throw new ArgumentNullException();
- if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
- if ((offset+count) > buffer.Length) throw new ArgumentException();
- if (_isDisposed) throw new ObjectDisposedException("GZipStream");
-
- GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
- try
- {
- int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
- if (result < 0)
- throw new IOException();
- }
- finally
- {
- h.Free();
- }
- }
-
- /// <summary>
- /// Writes a single byte to the stream
- /// </summary>
- /// <param name="value">The byte to add to the stream.</param>
- /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
- /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
- public override void WriteByte(byte value)
- {
- if (!CanWrite) throw new NotSupportedException();
- if (_isDisposed) throw new ObjectDisposedException("GZipStream");
-
- int result = gzputc(_gzFile, (int)value);
- if (result < 0)
- throw new IOException();
- }
- #endregion
-
- #region Position & length stuff
- /// <summary>
- /// Not supported.
- /// </summary>
- /// <param name="value"></param>
- /// <exception cref="NotSupportedException">Always thrown</exception>
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
-
- /// <summary>
- /// Not suppported.
- /// </summary>
- /// <param name="offset"></param>
- /// <param name="origin"></param>
- /// <returns></returns>
- /// <exception cref="NotSupportedException">Always thrown</exception>
- public override long Seek(long offset, SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
-
- /// <summary>
- /// Flushes the <c>GZipStream</c>.
- /// </summary>
- /// <remarks>In this implementation, this method does nothing. This is because excessive
- /// flushing may degrade the achievable compression rates.</remarks>
- public override void Flush()
- {
- // left empty on purpose
- }
-
- /// <summary>
- /// Gets/sets the current position in the <c>GZipStream</c>. Not suppported.
- /// </summary>
- /// <remarks>In this implementation this property is not supported</remarks>
- /// <exception cref="NotSupportedException">Always thrown</exception>
- public override long Position
- {
- get
- {
- throw new NotSupportedException();
- }
- set
- {
- throw new NotSupportedException();
- }
- }
-
- /// <summary>
- /// Gets the size of the stream. Not suppported.
- /// </summary>
- /// <remarks>In this implementation this property is not supported</remarks>
- /// <exception cref="NotSupportedException">Always thrown</exception>
- public override long Length
- {
- get
- {
- throw new NotSupportedException();
- }
- }
- #endregion
- }
-}
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib/Inflater.cs b/cpukit/zlib/contrib/dotzlib/DotZLib/Inflater.cs
deleted file mode 100644
index 8ed5451d66..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib/Inflater.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-//
-// © Copyright Henrik Ravn 2004
-//
-// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-using System;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace DotZLib
-{
-
- /// <summary>
- /// Implements a data decompressor, using the inflate algorithm in the ZLib dll
- /// </summary>
- public class Inflater : CodecBase
- {
- #region Dll imports
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
- private static extern int inflateInit_(ref ZStream sz, string vs, int size);
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern int inflate(ref ZStream sz, int flush);
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern int inflateReset(ref ZStream sz);
-
- [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
- private static extern int inflateEnd(ref ZStream sz);
- #endregion
-
- /// <summary>
- /// Constructs an new instance of the <c>Inflater</c>
- /// </summary>
- public Inflater() : base()
- {
- int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream));
- if (retval != 0)
- throw new ZLibException(retval, "Could not initialize inflater");
-
- resetOutput();
- }
-
-
- /// <summary>
- /// Adds more data to the codec to be processed.
- /// </summary>
- /// <param name="data">Byte array containing the data to be added to the codec</param>
- /// <param name="offset">The index of the first byte to add from <c>data</c></param>
- /// <param name="count">The number of bytes to add</param>
- /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
- public override void Add(byte[] data, int offset, int count)
- {
- if (data == null) throw new ArgumentNullException();
- if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
- if ((offset+count) > data.Length) throw new ArgumentException();
-
- int total = count;
- int inputIndex = offset;
- int err = 0;
-
- while (err >= 0 && inputIndex < total)
- {
- copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
- err = inflate(ref _ztream, (int)FlushTypes.None);
- if (err == 0)
- while (_ztream.avail_out == 0)
- {
- OnDataAvailable();
- err = inflate(ref _ztream, (int)FlushTypes.None);
- }
-
- inputIndex += (int)_ztream.total_in;
- }
- setChecksum( _ztream.adler );
- }
-
-
- /// <summary>
- /// Finishes up any pending data that needs to be processed and handled.
- /// </summary>
- public override void Finish()
- {
- int err;
- do
- {
- err = inflate(ref _ztream, (int)FlushTypes.Finish);
- OnDataAvailable();
- }
- while (err == 0);
- setChecksum( _ztream.adler );
- inflateReset(ref _ztream);
- resetOutput();
- }
-
- /// <summary>
- /// Closes the internal zlib inflate stream
- /// </summary>
- protected override void CleanUp() { inflateEnd(ref _ztream); }
-
-
- }
-}
diff --git a/cpukit/zlib/contrib/dotzlib/DotZLib/UnitTests.cs b/cpukit/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
deleted file mode 100644
index 2f374b6e30..0000000000
--- a/cpukit/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
+++ /dev/null
@@ -1,274 +0,0 @@
-//
-// © Copyright Henrik Ravn 2004
-//
-// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-using System;
-using System.Collections;
-using System.IO;
-
-// uncomment the define below to include unit tests
-//#define nunit
-#if nunit
-using NUnit.Framework;
-
-// Unit tests for the DotZLib class library
-// ----------------------------------------
-//
-// Use this with NUnit 2 from http://www.nunit.org
-//
-
-namespace DotZLibTests
-{
- using DotZLib;
-
- // helper methods
- internal class Utils
- {
- public static bool byteArrEqual( byte[] lhs, byte[] rhs )
- {
- if (lhs.Length != rhs.Length)
- return false;
- for (int i = lhs.Length-1; i >= 0; --i)
- if (lhs[i] != rhs[i])
- return false;
- return true;
- }
-
- }
-
-
- [TestFixture]
- public class CircBufferTests
- {
- #region Circular buffer tests
- [Test]
- public void SinglePutGet()
- {
- CircularBuffer buf = new CircularBuffer(10);
- Assert.AreEqual( 0, buf.Size );
- Assert.AreEqual( -1, buf.Get() );
-
- Assert.IsTrue(buf.Put( 1 ));
- Assert.AreEqual( 1, buf.Size );
- Assert.AreEqual( 1, buf.Get() );
- Assert.AreEqual( 0, buf.Size );
- Assert.AreEqual( -1, buf.Get() );
- }
-
- [Test]
- public void BlockPutGet()
- {
- CircularBuffer buf = new CircularBuffer(10);
- byte[] arr = {1,2,3,4,5,6,7,8,9,10};
- Assert.AreEqual( 10, buf.Put(arr,0,10) );
- Assert.AreEqual( 10, buf.Size );
- Assert.IsFalse( buf.Put(11) );
- Assert.AreEqual( 1, buf.Get() );
- Assert.IsTrue( buf.Put(11) );
-
- byte[] arr2 = (byte[])arr.Clone();
- Assert.AreEqual( 9, buf.Get(arr2,1,9) );
- Assert.IsTrue( Utils.byteArrEqual(arr,arr2) );
- }
-
- #endregion
- }
-
- [TestFixture]
- public class ChecksumTests
- {
- #region CRC32 Tests
- [Test]
- public void CRC32_Null()
- {
- CRC32Checksum crc32 = new CRC32Checksum();
- Assert.AreEqual( 0, crc32.Value );
-
- crc32 = new CRC32Checksum(1);
- Assert.AreEqual( 1, crc32.Value );
-
- crc32 = new CRC32Checksum(556);
- Assert.AreEqual( 556, crc32.Value );
- }
-
- [Test]
- public void CRC32_Data()
- {
- CRC32Checksum crc32 = new CRC32Checksum();
- byte[] data = { 1,2,3,4,5,6,7 };
- crc32.Update(data);
- Assert.AreEqual( 0x70e46888, crc32.Value );
-
- crc32 = new CRC32Checksum();
- crc32.Update("penguin");
- Assert.AreEqual( 0x0e5c1a120, crc32.Value );
-
- crc32 = new CRC32Checksum(1);
- crc32.Update("penguin");
- Assert.AreEqual(0x43b6aa94, crc32.Value);
-
- }
- #endregion
-
- #region Adler tests
-
- [Test]
- public void Adler_Null()
- {
- AdlerChecksum adler = new AdlerChecksum();
- Assert.AreEqual(0, adler.Value);
-
- adler = new AdlerChecksum(1);
- Assert.AreEqual( 1, adler.Value );
-
- adler = new AdlerChecksum(556);
- Assert.AreEqual( 556, adler.Value );
- }
-
- [Test]
- public void Adler_Data()
- {
- AdlerChecksum adler = new AdlerChecksum(1);
- byte[] data = { 1,2,3,4,5,6,7 };
- adler.Update(data);
- Assert.AreEqual( 0x5b001d, adler.Value );
-
- adler = new AdlerChecksum();
- adler.Update("penguin");
- Assert.AreEqual(0x0bcf02f6, adler.Value );
-
- adler = new AdlerChecksum(1);
- adler.Update("penguin");
- Assert.AreEqual(0x0bd602f7, adler.Value);
-
- }
- #endregion
- }
-
- [TestFixture]
- public class InfoTests
- {
- #region Info tests
- [Test]
- public void Info_Version()
- {
- Info info = new Info();
- Assert.AreEqual("1.2.2", Info.Version);
- Assert.AreEqual(32, info.SizeOfUInt);
- Assert.AreEqual(32, info.SizeOfULong);
- Assert.AreEqual(32, info.SizeOfPointer);
- Assert.AreEqual(32, info.SizeOfOffset);
- }
- #endregion
- }
-
- [TestFixture]
- public class DeflateInflateTests
- {
- #region Deflate tests
- [Test]
- public void Deflate_Init()
- {
- using (Deflater def = new Deflater(CompressLevel.Default))
- {
- }
- }
-
- private ArrayList compressedData = new ArrayList();
- private uint adler1;
-
- private ArrayList uncompressedData = new ArrayList();
- private uint adler2;
-
- public void CDataAvail(byte[] data, int startIndex, int count)
- {
- for (int i = 0; i < count; ++i)
- compressedData.Add(data[i+startIndex]);
- }
-
- [Test]
- public void Deflate_Compress()
- {
- compressedData.Clear();
-
- byte[] testData = new byte[35000];
- for (int i = 0; i < testData.Length; ++i)
- testData[i] = 5;
-
- using (Deflater def = new Deflater((CompressLevel)5))
- {
- def.DataAvailable += new DataAvailableHandler(CDataAvail);
- def.Add(testData);
- def.Finish();
- adler1 = def.Checksum;
- }
- }
- #endregion
-
- #region Inflate tests
- [Test]
- public void Inflate_Init()
- {
- using (Inflater inf = new Inflater())
- {
- }
- }
-
- private void DDataAvail(byte[] data, int startIndex, int count)
- {
- for (int i = 0; i < count; ++i)
- uncompressedData.Add(data[i+startIndex]);
- }
-
- [Test]
- public void Inflate_Expand()
- {
- uncompressedData.Clear();
-
- using (Inflater inf = new Inflater())
- {
- inf.DataAvailable += new DataAvailableHandler(DDataAvail);
- inf.Add((byte[])compressedData.ToArray(typeof(byte)));
- inf.Finish();
- adler2 = inf.Checksum;
- }
- Assert.AreEqual( adler1, adler2 );
- }
- #endregion
- }
-
- [TestFixture]
- public class GZipStreamTests
- {
- #region GZipStream test
- [Test]
- public void GZipStream_WriteRead()
- {
- using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best))
- {
- BinaryWriter writer = new BinaryWriter(gzOut);
- writer.Write("hi there");
- writer.Write(Math.PI);
- writer.Write(42);
- }
-
- using (GZipStream gzIn = new GZipStream("gzstream.gz"))
- {
- BinaryReader reader = new BinaryReader(gzIn);
- string s = reader.ReadString();
- Assert.AreEqual("hi there",s);
- double d = reader.ReadDouble();
- Assert.AreEqual(Math.PI, d);
- int i = reader.ReadInt32();
- Assert.AreEqual(42,i);
- }
-
- }
- #endregion
- }
-}
-
-#endif \ No newline at end of file
diff --git a/cpukit/zlib/contrib/dotzlib/LICENSE_1_0.txt b/cpukit/zlib/contrib/dotzlib/LICENSE_1_0.txt
deleted file mode 100644
index 30aac2cf47..0000000000
--- a/cpukit/zlib/contrib/dotzlib/LICENSE_1_0.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/cpukit/zlib/contrib/dotzlib/readme.txt b/cpukit/zlib/contrib/dotzlib/readme.txt
deleted file mode 100644
index b2395720d4..0000000000
--- a/cpukit/zlib/contrib/dotzlib/readme.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-This directory contains a .Net wrapper class library for the ZLib1.dll
-
-The wrapper includes support for inflating/deflating memory buffers,
-.Net streaming wrappers for the gz streams part of zlib, and wrappers
-for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples.
-
-Directory structure:
---------------------
-
-LICENSE_1_0.txt - License file.
-readme.txt - This file.
-DotZLib.chm - Class library documentation
-DotZLib.build - NAnt build file
-DotZLib.sln - Microsoft Visual Studio 2003 solution file
-
-DotZLib\*.cs - Source files for the class library
-
-Unit tests:
------------
-The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher.
-To include unit tests in the build, define nunit before building.
-
-
-Build instructions:
--------------------
-
-1. Using Visual Studio.Net 2003:
- Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll)
- will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on
- you are building the release or debug version of the library. Check
- DotZLib/UnitTests.cs for instructions on how to include unit tests in the
- build.
-
-2. Using NAnt:
- Open a command prompt with access to the build environment and run nant
- in the same directory as the DotZLib.build file.
- You can define 2 properties on the nant command-line to control the build:
- debug={true|false} to toggle between release/debug builds (default=true).
- nunit={true|false} to include or esclude unit tests (default=true).
- Also the target clean will remove binaries.
- Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release
- or ./DotZLib/bin/debug, depending on whether you are building the release
- or debug version of the library.
-
- Examples:
- nant -D:debug=false -D:nunit=false
- will build a release mode version of the library without unit tests.
- nant
- will build a debug version of the library with unit tests
- nant clean
- will remove all previously built files.
-
-
----------------------------------
-Copyright (c) Henrik Ravn 2004
-
-Use, modification and distribution are subject to the Boost Software License, Version 1.0.
-(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
diff --git a/cpukit/zlib/contrib/infback9/README b/cpukit/zlib/contrib/infback9/README
deleted file mode 100644
index e75ed13294..0000000000
--- a/cpukit/zlib/contrib/infback9/README
+++ /dev/null
@@ -1 +0,0 @@
-See infback9.h for what this is and how to use it.
diff --git a/cpukit/zlib/contrib/infback9/infback9.c b/cpukit/zlib/contrib/infback9/infback9.c
deleted file mode 100644
index f5ddde67da..0000000000
--- a/cpukit/zlib/contrib/infback9/infback9.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/* infback9.c -- inflate deflate64 data using a call-back interface
- * Copyright (C) 1995-2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infback9.h"
-#include "inftree9.h"
-#include "inflate9.h"
-
-#define WSIZE 65536UL
-
-/*
- strm provides memory allocation functions in zalloc and zfree, or
- Z_NULL to use the library memory allocation functions.
-
- window is a user-supplied window and output buffer that is 64K bytes.
- */
-int ZEXPORT inflateBack9Init_(strm, window, version, stream_size)
-z_stream FAR *strm;
-unsigned char FAR *window;
-const char *version;
-int stream_size;
-{
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL || window == Z_NULL)
- return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)ZALLOC(strm, 1,
- sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (voidpf)state;
- state->window = window;
- return Z_OK;
-}
-
-/*
- Build and output length and distance decoding tables for fixed code
- decoding.
- */
-#ifdef MAKEFIXED
-#include <stdio.h>
-
-void makefixed9(void)
-{
- unsigned sym, bits, low, size;
- code *next, *lenfix, *distfix;
- struct inflate_state state;
- code fixed[544];
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state.lens[sym++] = 8;
- while (sym < 256) state.lens[sym++] = 9;
- while (sym < 280) state.lens[sym++] = 7;
- while (sym < 288) state.lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state.lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work);
-
- /* write tables */
- puts(" /* inffix9.h -- table for decoding deflate64 fixed codes");
- puts(" * Generated automatically by makefixed9().");
- puts(" */");
- puts("");
- puts(" /* WARNING: this file should *not* be used by applications.");
- puts(" It is part of the implementation of this library and is");
- puts(" subject to change. Applications should only use zlib.h.");
- puts(" */");
- puts("");
- size = 1U << 9;
- printf(" static const code lenfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 6) == 0) printf("\n ");
- printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
- lenfix[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
- size = 1U << 5;
- printf("\n static const code distfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 5) == 0) printf("\n ");
- printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
- distfix[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
-}
-#endif /* MAKEFIXED */
-
-/* Macros for inflateBack(): */
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
-/* Assure that some input is available. If input is requested, but denied,
- then return a Z_BUF_ERROR from inflateBack(). */
-#define PULL() \
- do { \
- if (have == 0) { \
- have = in(in_desc, &next); \
- if (have == 0) { \
- next = Z_NULL; \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflateBack()
- with an error if there is no input available. */
-#define PULLBYTE() \
- do { \
- PULL(); \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
-/* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflateBack() with
- an error. */
-#define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
-/* Return the low n bits of the bit accumulator (n <= 16) */
-#define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
-/* Assure that some output space is available, by writing out the window
- if it's full. If the write fails, return from inflateBack() with a
- Z_BUF_ERROR. */
-#define ROOM() \
- do { \
- if (left == 0) { \
- put = window; \
- left = WSIZE; \
- wrap = 1; \
- if (out(out_desc, put, (unsigned)left)) { \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
-/*
- strm provides the memory allocation functions and window buffer on input,
- and provides information on the unused input on return. For Z_DATA_ERROR
- returns, strm will also provide an error message.
-
- in() and out() are the call-back input and output functions. When
- inflateBack() needs more input, it calls in(). When inflateBack() has
- filled the window with output, or when it completes with data in the
- window, it calls out() to write out the data. The application must not
- change the provided input until in() is called again or inflateBack()
- returns. The application must not change the window/output buffer until
- inflateBack() returns.
-
- in() and out() are called with a descriptor parameter provided in the
- inflateBack() call. This parameter can be a structure that provides the
- information required to do the read or write, as well as accumulated
- information on the input and output such as totals and check values.
-
- in() should return zero on failure. out() should return non-zero on
- failure. If either in() or out() fails, than inflateBack() returns a
- Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
- was in() or out() that caused in the error. Otherwise, inflateBack()
- returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
- error, or Z_MEM_ERROR if it could not allocate memory for the state.
- inflateBack() can also return Z_STREAM_ERROR if the input parameters
- are not correct, i.e. strm is Z_NULL or the state was not initialized.
- */
-int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc)
-z_stream FAR *strm;
-in_func in;
-void FAR *in_desc;
-out_func out;
-void FAR *out_desc;
-{
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have; /* available input */
- unsigned long left; /* available output */
- inflate_mode mode; /* current inflate mode */
- int lastblock; /* true if processing last block */
- int wrap; /* true if the window has wrapped */
- unsigned long write; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if needed */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned extra; /* extra bits needed */
- unsigned long length; /* literal or length of data to copy */
- unsigned long offset; /* distance back to copy string from */
- unsigned long copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code const FAR *lencode; /* starting table for length/literal codes */
- code const FAR *distcode; /* starting table for distance codes */
- unsigned lenbits; /* index bits for lencode */
- unsigned distbits; /* index bits for distcode */
- code this; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-#include "inffix9.h"
-
- /* Check that the strm exists and that the state was initialized */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
-
- /* Reset the state */
- strm->msg = Z_NULL;
- mode = TYPE;
- lastblock = 0;
- write = 0;
- wrap = 0;
- window = state->window;
- next = strm->next_in;
- have = next != Z_NULL ? strm->avail_in : 0;
- hold = 0;
- bits = 0;
- put = window;
- left = WSIZE;
- lencode = Z_NULL;
- distcode = Z_NULL;
-
- /* Inflate until end of block marked as last */
- for (;;)
- switch (mode) {
- case TYPE:
- /* determine and dispatch block type */
- if (lastblock) {
- BYTEBITS();
- mode = DONE;
- break;
- }
- NEEDBITS(3);
- lastblock = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- lastblock ? " (last)" : ""));
- mode = STORED;
- break;
- case 1: /* fixed block */
- lencode = lenfix;
- lenbits = 9;
- distcode = distfix;
- distbits = 5;
- Tracev((stderr, "inflate: fixed codes block%s\n",
- lastblock ? " (last)" : ""));
- mode = LEN; /* decode codes */
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- lastblock ? " (last)" : ""));
- mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- mode = BAD;
- }
- DROPBITS(2);
- break;
-
- case STORED:
- /* get and verify stored block length */
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- mode = BAD;
- break;
- }
- length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %lu\n",
- length));
- INITBITS();
-
- /* copy stored block from input to output */
- while (length != 0) {
- copy = length;
- PULL();
- ROOM();
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- length -= copy;
- }
- Tracev((stderr, "inflate: stored end\n"));
- mode = TYPE;
- break;
-
- case TABLE:
- /* get dynamic table entries descriptor */
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
- if (state->nlen > 286) {
- strm->msg = (char *)"too many length symbols";
- mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: table sizes ok\n"));
-
- /* get code length code lengths (not a typo) */
- state->have = 0;
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- lencode = (code const FAR *)(state->next);
- lenbits = 7;
- ret = inflate_table9(CODES, state->lens, 19, &(state->next),
- &(lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
-
- /* get length and distance code code lengths */
- state->have = 0;
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- this = lencode[BITS(lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
- }
- else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- mode = BAD;
- break;
- }
- len = (unsigned)(state->lens[state->have - 1]);
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (mode == BAD) break;
-
- /* build code tables */
- state->next = state->codes;
- lencode = (code const FAR *)(state->next);
- lenbits = 9;
- ret = inflate_table9(LENS, state->lens, state->nlen,
- &(state->next), &(lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- mode = BAD;
- break;
- }
- distcode = (code const FAR *)(state->next);
- distbits = 6;
- ret = inflate_table9(DISTS, state->lens + state->nlen,
- state->ndist, &(state->next), &(distbits),
- state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- mode = LEN;
-
- case LEN:
- /* get a literal, length, or end-of-block code */
- for (;;) {
- this = lencode[BITS(lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- length = (unsigned)this.val;
-
- /* process literal */
- if (this.op == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- ROOM();
- *put++ = (unsigned char)(length);
- left--;
- mode = LEN;
- break;
- }
-
- /* process end of block */
- if (this.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- mode = TYPE;
- break;
- }
-
- /* invalid code */
- if (this.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- mode = BAD;
- break;
- }
-
- /* length code -- get extra bits, if any */
- extra = (unsigned)(this.op) & 31;
- if (extra != 0) {
- NEEDBITS(extra);
- length += BITS(extra);
- DROPBITS(extra);
- }
- Tracevv((stderr, "inflate: length %lu\n", length));
-
- /* get distance code */
- for (;;) {
- this = distcode[BITS(distbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if ((this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- if (this.op & 64) {
- strm->msg = (char *)"invalid distance code";
- mode = BAD;
- break;
- }
- offset = (unsigned)this.val;
-
- /* get distance extra bits, if any */
- extra = (unsigned)(this.op) & 15;
- if (extra != 0) {
- NEEDBITS(extra);
- offset += BITS(extra);
- DROPBITS(extra);
- }
- if (offset > WSIZE - (wrap ? 0: left)) {
- strm->msg = (char *)"invalid distance too far back";
- mode = BAD;
- break;
- }
- Tracevv((stderr, "inflate: distance %lu\n", offset));
-
- /* copy match from window to output */
- do {
- ROOM();
- copy = WSIZE - offset;
- if (copy < left) {
- from = put + copy;
- copy = left - copy;
- }
- else {
- from = put - offset;
- copy = left;
- }
- if (copy > length) copy = length;
- length -= copy;
- left -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- } while (length != 0);
- break;
-
- case DONE:
- /* inflate stream terminated properly -- write leftover output */
- ret = Z_STREAM_END;
- if (left < WSIZE) {
- if (out(out_desc, window, (unsigned)(WSIZE - left)))
- ret = Z_BUF_ERROR;
- }
- goto inf_leave;
-
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
-
- default: /* can't happen, but makes compilers happy */
- ret = Z_STREAM_ERROR;
- goto inf_leave;
- }
-
- /* Return unused input */
- inf_leave:
- strm->next_in = next;
- strm->avail_in = have;
- return ret;
-}
-
-int ZEXPORT inflateBack9End(strm)
-z_stream FAR *strm;
-{
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
diff --git a/cpukit/zlib/contrib/infback9/infback9.h b/cpukit/zlib/contrib/infback9/infback9.h
deleted file mode 100644
index 10bf58c368..0000000000
--- a/cpukit/zlib/contrib/infback9/infback9.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* infback9.h -- header for using inflateBack9 functions
- * Copyright (C) 2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * This header file and associated patches provide a decoder for PKWare's
- * undocumented deflate64 compression method (method 9). Use with infback9.c,
- * inftree9.h, inftree9.c, and inffix9.h. These patches are not supported.
- * This should be compiled with zlib, since it uses zutil.h and zutil.o.
- * This code has not yet been tested on 16-bit architectures. See the
- * comments in zlib.h for inflateBack() usage. These functions are used
- * identically, except that there is no windowBits parameter, and a 64K
- * window must be provided. Also if int's are 16 bits, then a zero for
- * the third parameter of the "out" function actually means 65536UL.
- * zlib.h must be included before this header file.
- */
-
-ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm,
- in_func in, void FAR *in_desc,
- out_func out, void FAR *out_desc));
-ZEXTERN int ZEXPORT inflateBack9End OF((z_stream FAR *strm));
-ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm,
- unsigned char FAR *window,
- const char *version,
- int stream_size));
-#define inflateBack9Init(strm, window) \
- inflateBack9Init_((strm), (window), \
- ZLIB_VERSION, sizeof(z_stream))
diff --git a/cpukit/zlib/contrib/infback9/inffix9.h b/cpukit/zlib/contrib/infback9/inffix9.h
deleted file mode 100644
index ee5671d2df..0000000000
--- a/cpukit/zlib/contrib/infback9/inffix9.h
+++ /dev/null
@@ -1,107 +0,0 @@
- /* inffix9.h -- table for decoding deflate64 fixed codes
- * Generated automatically by makefixed9().
- */
-
- /* WARNING: this file should *not* be used by applications.
- It is part of the implementation of this library and is
- subject to change. Applications should only use zlib.h.
- */
-
- static const code lenfix[512] = {
- {96,7,0},{0,8,80},{0,8,16},{132,8,115},{130,7,31},{0,8,112},
- {0,8,48},{0,9,192},{128,7,10},{0,8,96},{0,8,32},{0,9,160},
- {0,8,0},{0,8,128},{0,8,64},{0,9,224},{128,7,6},{0,8,88},
- {0,8,24},{0,9,144},{131,7,59},{0,8,120},{0,8,56},{0,9,208},
- {129,7,17},{0,8,104},{0,8,40},{0,9,176},{0,8,8},{0,8,136},
- {0,8,72},{0,9,240},{128,7,4},{0,8,84},{0,8,20},{133,8,227},
- {131,7,43},{0,8,116},{0,8,52},{0,9,200},{129,7,13},{0,8,100},
- {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},
- {128,7,8},{0,8,92},{0,8,28},{0,9,152},{132,7,83},{0,8,124},
- {0,8,60},{0,9,216},{130,7,23},{0,8,108},{0,8,44},{0,9,184},
- {0,8,12},{0,8,140},{0,8,76},{0,9,248},{128,7,3},{0,8,82},
- {0,8,18},{133,8,163},{131,7,35},{0,8,114},{0,8,50},{0,9,196},
- {129,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},{0,8,130},
- {0,8,66},{0,9,228},{128,7,7},{0,8,90},{0,8,26},{0,9,148},
- {132,7,67},{0,8,122},{0,8,58},{0,9,212},{130,7,19},{0,8,106},
- {0,8,42},{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},
- {128,7,5},{0,8,86},{0,8,22},{65,8,0},{131,7,51},{0,8,118},
- {0,8,54},{0,9,204},{129,7,15},{0,8,102},{0,8,38},{0,9,172},
- {0,8,6},{0,8,134},{0,8,70},{0,9,236},{128,7,9},{0,8,94},
- {0,8,30},{0,9,156},{132,7,99},{0,8,126},{0,8,62},{0,9,220},
- {130,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
- {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{133,8,131},
- {130,7,31},{0,8,113},{0,8,49},{0,9,194},{128,7,10},{0,8,97},
- {0,8,33},{0,9,162},{0,8,1},{0,8,129},{0,8,65},{0,9,226},
- {128,7,6},{0,8,89},{0,8,25},{0,9,146},{131,7,59},{0,8,121},
- {0,8,57},{0,9,210},{129,7,17},{0,8,105},{0,8,41},{0,9,178},
- {0,8,9},{0,8,137},{0,8,73},{0,9,242},{128,7,4},{0,8,85},
- {0,8,21},{144,8,3},{131,7,43},{0,8,117},{0,8,53},{0,9,202},
- {129,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},
- {0,8,69},{0,9,234},{128,7,8},{0,8,93},{0,8,29},{0,9,154},
- {132,7,83},{0,8,125},{0,8,61},{0,9,218},{130,7,23},{0,8,109},
- {0,8,45},{0,9,186},{0,8,13},{0,8,141},{0,8,77},{0,9,250},
- {128,7,3},{0,8,83},{0,8,19},{133,8,195},{131,7,35},{0,8,115},
- {0,8,51},{0,9,198},{129,7,11},{0,8,99},{0,8,35},{0,9,166},
- {0,8,3},{0,8,131},{0,8,67},{0,9,230},{128,7,7},{0,8,91},
- {0,8,27},{0,9,150},{132,7,67},{0,8,123},{0,8,59},{0,9,214},
- {130,7,19},{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},
- {0,8,75},{0,9,246},{128,7,5},{0,8,87},{0,8,23},{77,8,0},
- {131,7,51},{0,8,119},{0,8,55},{0,9,206},{129,7,15},{0,8,103},
- {0,8,39},{0,9,174},{0,8,7},{0,8,135},{0,8,71},{0,9,238},
- {128,7,9},{0,8,95},{0,8,31},{0,9,158},{132,7,99},{0,8,127},
- {0,8,63},{0,9,222},{130,7,27},{0,8,111},{0,8,47},{0,9,190},
- {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},
- {0,8,16},{132,8,115},{130,7,31},{0,8,112},{0,8,48},{0,9,193},
- {128,7,10},{0,8,96},{0,8,32},{0,9,161},{0,8,0},{0,8,128},
- {0,8,64},{0,9,225},{128,7,6},{0,8,88},{0,8,24},{0,9,145},
- {131,7,59},{0,8,120},{0,8,56},{0,9,209},{129,7,17},{0,8,104},
- {0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},{0,9,241},
- {128,7,4},{0,8,84},{0,8,20},{133,8,227},{131,7,43},{0,8,116},
- {0,8,52},{0,9,201},{129,7,13},{0,8,100},{0,8,36},{0,9,169},
- {0,8,4},{0,8,132},{0,8,68},{0,9,233},{128,7,8},{0,8,92},
- {0,8,28},{0,9,153},{132,7,83},{0,8,124},{0,8,60},{0,9,217},
- {130,7,23},{0,8,108},{0,8,44},{0,9,185},{0,8,12},{0,8,140},
- {0,8,76},{0,9,249},{128,7,3},{0,8,82},{0,8,18},{133,8,163},
- {131,7,35},{0,8,114},{0,8,50},{0,9,197},{129,7,11},{0,8,98},
- {0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
- {128,7,7},{0,8,90},{0,8,26},{0,9,149},{132,7,67},{0,8,122},
- {0,8,58},{0,9,213},{130,7,19},{0,8,106},{0,8,42},{0,9,181},
- {0,8,10},{0,8,138},{0,8,74},{0,9,245},{128,7,5},{0,8,86},
- {0,8,22},{65,8,0},{131,7,51},{0,8,118},{0,8,54},{0,9,205},
- {129,7,15},{0,8,102},{0,8,38},{0,9,173},{0,8,6},{0,8,134},
- {0,8,70},{0,9,237},{128,7,9},{0,8,94},{0,8,30},{0,9,157},
- {132,7,99},{0,8,126},{0,8,62},{0,9,221},{130,7,27},{0,8,110},
- {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},
- {96,7,0},{0,8,81},{0,8,17},{133,8,131},{130,7,31},{0,8,113},
- {0,8,49},{0,9,195},{128,7,10},{0,8,97},{0,8,33},{0,9,163},
- {0,8,1},{0,8,129},{0,8,65},{0,9,227},{128,7,6},{0,8,89},
- {0,8,25},{0,9,147},{131,7,59},{0,8,121},{0,8,57},{0,9,211},
- {129,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},{0,8,137},
- {0,8,73},{0,9,243},{128,7,4},{0,8,85},{0,8,21},{144,8,3},
- {131,7,43},{0,8,117},{0,8,53},{0,9,203},{129,7,13},{0,8,101},
- {0,8,37},{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},
- {128,7,8},{0,8,93},{0,8,29},{0,9,155},{132,7,83},{0,8,125},
- {0,8,61},{0,9,219},{130,7,23},{0,8,109},{0,8,45},{0,9,187},
- {0,8,13},{0,8,141},{0,8,77},{0,9,251},{128,7,3},{0,8,83},
- {0,8,19},{133,8,195},{131,7,35},{0,8,115},{0,8,51},{0,9,199},
- {129,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
- {0,8,67},{0,9,231},{128,7,7},{0,8,91},{0,8,27},{0,9,151},
- {132,7,67},{0,8,123},{0,8,59},{0,9,215},{130,7,19},{0,8,107},
- {0,8,43},{0,9,183},{0,8,11},{0,8,139},{0,8,75},{0,9,247},
- {128,7,5},{0,8,87},{0,8,23},{77,8,0},{131,7,51},{0,8,119},
- {0,8,55},{0,9,207},{129,7,15},{0,8,103},{0,8,39},{0,9,175},
- {0,8,7},{0,8,135},{0,8,71},{0,9,239},{128,7,9},{0,8,95},
- {0,8,31},{0,9,159},{132,7,99},{0,8,127},{0,8,63},{0,9,223},
- {130,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},
- {0,8,79},{0,9,255}
- };
-
- static const code distfix[32] = {
- {128,5,1},{135,5,257},{131,5,17},{139,5,4097},{129,5,5},
- {137,5,1025},{133,5,65},{141,5,16385},{128,5,3},{136,5,513},
- {132,5,33},{140,5,8193},{130,5,9},{138,5,2049},{134,5,129},
- {142,5,32769},{128,5,2},{135,5,385},{131,5,25},{139,5,6145},
- {129,5,7},{137,5,1537},{133,5,97},{141,5,24577},{128,5,4},
- {136,5,769},{132,5,49},{140,5,12289},{130,5,13},{138,5,3073},
- {134,5,193},{142,5,49153}
- };
diff --git a/cpukit/zlib/contrib/infback9/inflate9.h b/cpukit/zlib/contrib/infback9/inflate9.h
deleted file mode 100644
index ee9a79394b..0000000000
--- a/cpukit/zlib/contrib/infback9/inflate9.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* inflate9.h -- internal inflate state definition
- * Copyright (C) 1995-2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Possible inflate modes between inflate() calls */
-typedef enum {
- TYPE, /* i: waiting for type bits, including last-flag bit */
- STORED, /* i: waiting for stored size (length and complement) */
- TABLE, /* i: waiting for dynamic block table lengths */
- LEN, /* i: waiting for length/lit code */
- DONE, /* finished check, done -- remain here until reset */
- BAD /* got a data error -- remain here until reset */
-} inflate_mode;
-
-/*
- State transitions between above modes -
-
- (most modes can go to the BAD mode -- not shown for clarity)
-
- Read deflate blocks:
- TYPE -> STORED or TABLE or LEN or DONE
- STORED -> TYPE
- TABLE -> LENLENS -> CODELENS -> LEN
- Read deflate codes:
- LEN -> LEN or TYPE
- */
-
-/* state maintained between inflate() calls. Approximately 7K bytes. */
-struct inflate_state {
- /* sliding window */
- unsigned char FAR *window; /* allocated sliding window, if needed */
- /* dynamic table building */
- unsigned ncode; /* number of code length code lengths */
- unsigned nlen; /* number of length code lengths */
- unsigned ndist; /* number of distance code lengths */
- unsigned have; /* number of code lengths in lens[] */
- code FAR *next; /* next available space in codes[] */
- unsigned short lens[320]; /* temporary storage for code lengths */
- unsigned short work[288]; /* work area for code table building */
- code codes[ENOUGH]; /* space for code tables */
-};
diff --git a/cpukit/zlib/contrib/infback9/inftree9.c b/cpukit/zlib/contrib/infback9/inftree9.c
deleted file mode 100644
index 29bef6ab99..0000000000
--- a/cpukit/zlib/contrib/infback9/inftree9.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/* inftree9.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftree9.h"
-
-#define MAXBITS 15
-
-const char inflate9_copyright[] =
- " inflate9 1.2.2.2 Copyright 1995-2004 Mark Adler ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/*
- Build a set of tables to decode the provided canonical Huffman code.
- The code lengths are lens[0..codes-1]. The result starts at *table,
- whose indices are 0..2^bits-1. work is a writable array of at least
- lens shorts, which is used as a work area. type is the type of code
- to be generated, CODES, LENS, or DISTS. On return, zero is success,
- -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
- on return points to the next available entry's address. bits is the
- requested root table index bits, and on return it is the actual root
- table index bits. It will differ if the request is greater than the
- longest code or if it is less than the shortest code.
- */
-int inflate_table9(type, lens, codes, table, bits, work)
-codetype type;
-unsigned short FAR *lens;
-unsigned codes;
-code FAR * FAR *table;
-unsigned FAR *bits;
-unsigned short FAR *work;
-{
- unsigned len; /* a code's length in bits */
- unsigned sym; /* index of code symbols */
- unsigned min, max; /* minimum and maximum code lengths */
- unsigned root; /* number of index bits for root table */
- unsigned curr; /* number of index bits for current table */
- unsigned drop; /* code bits to drop for sub-table */
- int left; /* number of prefix codes available */
- unsigned used; /* code entries in table used */
- unsigned huff; /* Huffman code */
- unsigned incr; /* for incrementing code, index */
- unsigned fill; /* index for replicating entries */
- unsigned low; /* low bits for current root entry */
- unsigned mask; /* mask for low root bits */
- code this; /* table entry for duplication */
- code FAR *next; /* next available space in table */
- const unsigned short FAR *base; /* base value table to use */
- const unsigned short FAR *extra; /* extra bits table to use */
- int end; /* use base and extra for symbol > end */
- unsigned short count[MAXBITS+1]; /* number of codes of each length */
- unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
- static const unsigned short lbase[31] = { /* Length codes 257..285 base */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17,
- 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115,
- 131, 163, 195, 227, 3, 0, 0};
- static const unsigned short lext[31] = { /* Length codes 257..285 extra */
- 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
- 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
- 133, 133, 133, 133, 144, 72, 199};
- static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
- 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
- 4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153};
- static const unsigned short dext[32] = { /* Distance codes 0..31 extra */
- 128, 128, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132,
- 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138,
- 139, 139, 140, 140, 141, 141, 142, 142};
-
- /*
- Process a set of code lengths to create a canonical Huffman code. The
- code lengths are lens[0..codes-1]. Each length corresponds to the
- symbols 0..codes-1. The Huffman code is generated by first sorting the
- symbols by length from short to long, and retaining the symbol order
- for codes with equal lengths. Then the code starts with all zero bits
- for the first code of the shortest length, and the codes are integer
- increments for the same length, and zeros are appended as the length
- increases. For the deflate format, these bits are stored backwards
- from their more natural integer increment ordering, and so when the
- decoding tables are built in the large loop below, the integer codes
- are incremented backwards.
-
- This routine assumes, but does not check, that all of the entries in
- lens[] are in the range 0..MAXBITS. The caller must assure this.
- 1..MAXBITS is interpreted as that code length. zero means that that
- symbol does not occur in this code.
-
- The codes are sorted by computing a count of codes for each length,
- creating from that a table of starting indices for each length in the
- sorted table, and then entering the symbols in order in the sorted
- table. The sorted table is work[], with that space being provided by
- the caller.
-
- The length counts are used for other purposes as well, i.e. finding
- the minimum and maximum length codes, determining if there are any
- codes at all, checking for a valid set of lengths, and looking ahead
- at length counts to determine sub-table sizes when building the
- decoding tables.
- */
-
- /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
- for (len = 0; len <= MAXBITS; len++)
- count[len] = 0;
- for (sym = 0; sym < codes; sym++)
- count[lens[sym]]++;
-
- /* bound code lengths, force root to be within code lengths */
- root = *bits;
- for (max = MAXBITS; max >= 1; max--)
- if (count[max] != 0) break;
- if (root > max) root = max;
- if (max == 0) return -1; /* no codes! */
- for (min = 1; min <= MAXBITS; min++)
- if (count[min] != 0) break;
- if (root < min) root = min;
-
- /* check for an over-subscribed or incomplete set of lengths */
- left = 1;
- for (len = 1; len <= MAXBITS; len++) {
- left <<= 1;
- left -= count[len];
- if (left < 0) return -1; /* over-subscribed */
- }
- if (left > 0 && (type == CODES || (codes - count[0] != 1)))
- return -1; /* incomplete set */
-
- /* generate offsets into symbol table for each length for sorting */
- offs[1] = 0;
- for (len = 1; len < MAXBITS; len++)
- offs[len + 1] = offs[len] + count[len];
-
- /* sort symbols by length, by symbol order within each length */
- for (sym = 0; sym < codes; sym++)
- if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
-
- /*
- Create and fill in decoding tables. In this loop, the table being
- filled is at next and has curr index bits. The code being used is huff
- with length len. That code is converted to an index by dropping drop
- bits off of the bottom. For codes where len is less than drop + curr,
- those top drop + curr - len bits are incremented through all values to
- fill the table with replicated entries.
-
- root is the number of index bits for the root table. When len exceeds
- root, sub-tables are created pointed to by the root entry with an index
- of the low root bits of huff. This is saved in low to check for when a
- new sub-table should be started. drop is zero when the root table is
- being filled, and drop is root when sub-tables are being filled.
-
- When a new sub-table is needed, it is necessary to look ahead in the
- code lengths to determine what size sub-table is needed. The length
- counts are used for this, and so count[] is decremented as codes are
- entered in the tables.
-
- used keeps track of how many table entries have been allocated from the
- provided *table space. It is checked when a LENS table is being made
- against the space in *table, ENOUGH, minus the maximum space needed by
- the worst case distance code, MAXD. This should never happen, but the
- sufficiency of ENOUGH has not been proven exhaustively, hence the check.
- This assumes that when type == LENS, bits == 9.
-
- sym increments through all symbols, and the loop terminates when
- all codes of length max, i.e. all codes, have been processed. This
- routine permits incomplete codes, so another loop after this one fills
- in the rest of the decoding tables with invalid code markers.
- */
-
- /* set up for code type */
- switch (type) {
- case CODES:
- base = extra = work; /* dummy value--not used */
- end = 19;
- break;
- case LENS:
- base = lbase;
- base -= 257;
- extra = lext;
- extra -= 257;
- end = 256;
- break;
- default: /* DISTS */
- base = dbase;
- extra = dext;
- end = -1;
- }
-
- /* initialize state for loop */
- huff = 0; /* starting code */
- sym = 0; /* starting code symbol */
- len = min; /* starting code length */
- next = *table; /* current table to fill in */
- curr = root; /* current table index bits */
- drop = 0; /* current bits to drop from code for index */
- low = (unsigned)(-1); /* trigger new sub-table when len > root */
- used = 1U << root; /* use root table entries */
- mask = used - 1; /* mask for comparing low */
-
- /* check available table space */
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* process all codes and make table entries */
- for (;;) {
- /* create table entry */
- this.bits = (unsigned char)(len - drop);
- if ((int)(work[sym]) < end) {
- this.op = (unsigned char)0;
- this.val = work[sym];
- }
- else if ((int)(work[sym]) > end) {
- this.op = (unsigned char)(extra[work[sym]]);
- this.val = base[work[sym]];
- }
- else {
- this.op = (unsigned char)(32 + 64); /* end of block */
- this.val = 0;
- }
-
- /* replicate for those indices with low len bits equal to huff */
- incr = 1U << (len - drop);
- fill = 1U << curr;
- do {
- fill -= incr;
- next[(huff >> drop) + fill] = this;
- } while (fill != 0);
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
-
- /* go to next symbol, update count, len */
- sym++;
- if (--(count[len]) == 0) {
- if (len == max) break;
- len = lens[work[sym]];
- }
-
- /* create new sub-table if needed */
- if (len > root && (huff & mask) != low) {
- /* if first time, transition to sub-tables */
- if (drop == 0)
- drop = root;
-
- /* increment past last table */
- next += 1U << curr;
-
- /* determine length of next table */
- curr = len - drop;
- left = (int)(1 << curr);
- while (curr + drop < max) {
- left -= count[curr + drop];
- if (left <= 0) break;
- curr++;
- left <<= 1;
- }
-
- /* check for enough space */
- used += 1U << curr;
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* point entry in root table to sub-table */
- low = huff & mask;
- (*table)[low].op = (unsigned char)curr;
- (*table)[low].bits = (unsigned char)root;
- (*table)[low].val = (unsigned short)(next - *table);
- }
- }
-
- /*
- Fill in rest of table for incomplete codes. This loop is similar to the
- loop above in incrementing huff for table indices. It is assumed that
- len is equal to curr + drop, so there is no loop needed to increment
- through high index bits. When the current sub-table is filled, the loop
- drops back to the root table to fill in any remaining entries there.
- */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)(len - drop);
- this.val = (unsigned short)0;
- while (huff != 0) {
- /* when done with sub-table, drop back to root table */
- if (drop != 0 && (huff & mask) != low) {
- drop = 0;
- len = root;
- next = *table;
- curr = root;
- this.bits = (unsigned char)len;
- }
-
- /* put invalid code marker in table */
- next[huff >> drop] = this;
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
- }
-
- /* set return parameters */
- *table += used;
- *bits = root;
- return 0;
-}
diff --git a/cpukit/zlib/contrib/infback9/inftree9.h b/cpukit/zlib/contrib/infback9/inftree9.h
deleted file mode 100644
index 6a699a798f..0000000000
--- a/cpukit/zlib/contrib/infback9/inftree9.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* inftree9.h -- header to use inftree9.c
- * Copyright (C) 1995-2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Structure for decoding tables. Each entry provides either the
- information needed to do the operation requested by the code that
- indexed that table entry, or it provides a pointer to another
- table that indexes more bits of the code. op indicates whether
- the entry is a pointer to another table, a literal, a length or
- distance, an end-of-block, or an invalid code. For a table
- pointer, the low four bits of op is the number of index bits of
- that table. For a length or distance, the low four bits of op
- is the number of extra bits to get after the code. bits is
- the number of bits in this code or part of the code to drop off
- of the bit buffer. val is the actual byte to output in the case
- of a literal, the base length or distance, or the offset from
- the current table to the next table. Each entry is four bytes. */
-typedef struct {
- unsigned char op; /* operation, extra bits, table bits */
- unsigned char bits; /* bits in this part of the code */
- unsigned short val; /* offset in table or code value */
-} code;
-
-/* op values as set by inflate_table():
- 00000000 - literal
- 0000tttt - table link, tttt != 0 is the number of table index bits
- 100eeeee - length or distance, eeee is the number of extra bits
- 01100000 - end of block
- 01000000 - invalid code
- */
-
-/* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1004 code structures (850 for length/literals
- and 154 for distances, the latter actually the result of an
- exhaustive search). The true maximum is not known, but the value
- below is more than safe. */
-#define ENOUGH 1440
-#define MAXD 154
-
-/* Type of code to build for inftable() */
-typedef enum {
- CODES,
- LENS,
- DISTS
-} codetype;
-
-extern int inflate_table9 OF((codetype type, unsigned short FAR *lens,
- unsigned codes, code FAR * FAR *table,
- unsigned FAR *bits, unsigned short FAR *work));
diff --git a/cpukit/zlib/contrib/inflate86/inffas86.c b/cpukit/zlib/contrib/inflate86/inffas86.c
deleted file mode 100644
index 6da76358cc..0000000000
--- a/cpukit/zlib/contrib/inflate86/inffas86.c
+++ /dev/null
@@ -1,1157 +0,0 @@
-/* inffas86.c is a hand tuned assembler version of
- *
- * inffast.c -- fast decoding
- * Copyright (C) 1995-2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Copyright (C) 2003 Chris Anderson <christop@charm.net>
- * Please use the copyright conditions above.
- *
- * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also
- * slightly quicker on x86 systems because, instead of using rep movsb to copy
- * data, it uses rep movsw, which moves data in 2-byte chunks instead of single
- * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
- * from http://fedora.linux.duke.edu/fc1_x86_64
- * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
- * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version,
- * when decompressing mozilla-source-1.3.tar.gz.
- *
- * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
- * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at
- * the moment. I have successfully compiled and tested this code with gcc2.96,
- * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S
- * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
- * enabled. I will attempt to merge the MMX code into this version. Newer
- * versions of this and inffast.S can be found at
- * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-/* Mark Adler's comments from inffast.c: */
-
-/*
- Decode literal, length, and distance codes and write out the resulting
- literal and match bytes until either not enough input or output is
- available, an end-of-block is encountered, or a data error is encountered.
- When large enough input and output buffers are supplied to inflate(), for
- example, a 16K input buffer and a 64K output buffer, more than 95% of the
- inflate execution time is spent in this routine.
-
- Entry assumptions:
-
- state->mode == LEN
- strm->avail_in >= 6
- strm->avail_out >= 258
- start >= strm->avail_out
- state->bits < 8
-
- On return, state->mode is one of:
-
- LEN -- ran out of enough output space or enough available input
- TYPE -- reached end of block code, inflate() to interpret next block
- BAD -- error in block data
-
- Notes:
-
- - The maximum input bits used by a length/distance pair is 15 bits for the
- length code, 5 bits for the length extra, 15 bits for the distance code,
- and 13 bits for the distance extra. This totals 48 bits, or six bytes.
- Therefore if strm->avail_in >= 6, then there is enough input to avoid
- checking for available input while decoding.
-
- - The maximum bytes that a single length/distance pair can output is 258
- bytes, which is the maximum length that can be coded. inflate_fast()
- requires strm->avail_out >= 258 for each loop to avoid checking for
- output space.
- */
-void inflate_fast(strm, start)
-z_streamp strm;
-unsigned start; /* inflate()'s starting value for strm->avail_out */
-{
- struct inflate_state FAR *state;
- struct inffast_ar {
-/* 64 32 x86 x86_64 */
-/* ar offset register */
-/* 0 0 */ void *esp; /* esp save */
-/* 8 4 */ void *ebp; /* ebp save */
-/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */
-/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */
-/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */
-/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */
-/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */
-/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */
-/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */
-/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */
-/* 80 40 */ unsigned long hold; /* edx rdx local strm->hold */
-/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */
-/* 92 48 */ unsigned wsize; /* window size */
-/* 96 52 */ unsigned write; /* window write index */
-/*100 56 */ unsigned lmask; /* r12 mask for lcode */
-/*104 60 */ unsigned dmask; /* r13 mask for dcode */
-/*108 64 */ unsigned len; /* r14 match length */
-/*112 68 */ unsigned dist; /* r15 match distance */
-/*116 72 */ unsigned status; /* set when state chng*/
- } ar;
-
-#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
-#define PAD_AVAIL_IN 6
-#define PAD_AVAIL_OUT 258
-#else
-#define PAD_AVAIL_IN 5
-#define PAD_AVAIL_OUT 257
-#endif
-
- /* copy state to local variables */
- state = (struct inflate_state FAR *)strm->state;
- ar.in = strm->next_in;
- ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
- ar.out = strm->next_out;
- ar.beg = ar.out - (start - strm->avail_out);
- ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
- ar.wsize = state->wsize;
- ar.write = state->write;
- ar.window = state->window;
- ar.hold = state->hold;
- ar.bits = state->bits;
- ar.lcode = state->lencode;
- ar.dcode = state->distcode;
- ar.lmask = (1U << state->lenbits) - 1;
- ar.dmask = (1U << state->distbits) - 1;
-
- /* decode literals and length/distances until end-of-block or not enough
- input data or output space */
-
- /* align in on 1/2 hold size boundary */
- while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
- ar.hold += (unsigned long)*ar.in++ << ar.bits;
- ar.bits += 8;
- }
-
-#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
- __asm__ __volatile__ (
-" leaq %0, %%rax\n"
-" movq %%rbp, 8(%%rax)\n" /* save regs rbp and rsp */
-" movq %%rsp, (%%rax)\n"
-" movq %%rax, %%rsp\n" /* make rsp point to &ar */
-" movq 16(%%rsp), %%rsi\n" /* rsi = in */
-" movq 32(%%rsp), %%rdi\n" /* rdi = out */
-" movq 24(%%rsp), %%r9\n" /* r9 = last */
-" movq 48(%%rsp), %%r10\n" /* r10 = end */
-" movq 64(%%rsp), %%rbp\n" /* rbp = lcode */
-" movq 72(%%rsp), %%r11\n" /* r11 = dcode */
-" movq 80(%%rsp), %%rdx\n" /* rdx = hold */
-" movl 88(%%rsp), %%ebx\n" /* ebx = bits */
-" movl 100(%%rsp), %%r12d\n" /* r12d = lmask */
-" movl 104(%%rsp), %%r13d\n" /* r13d = dmask */
- /* r14d = len */
- /* r15d = dist */
-" cld\n"
-" cmpq %%rdi, %%r10\n"
-" je .L_one_time\n" /* if only one decode left */
-" cmpq %%rsi, %%r9\n"
-" je .L_one_time\n"
-" jmp .L_do_loop\n"
-
-".L_one_time:\n"
-" movq %%r12, %%r8\n" /* r8 = lmask */
-" cmpb $32, %%bl\n"
-" ja .L_get_length_code_one_time\n"
-
-" lodsl\n" /* eax = *(uint *)in++ */
-" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
-" addb $32, %%bl\n" /* bits += 32 */
-" shlq %%cl, %%rax\n"
-" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
-" jmp .L_get_length_code_one_time\n"
-
-".align 32,0x90\n"
-".L_while_test:\n"
-" cmpq %%rdi, %%r10\n"
-" jbe .L_break_loop\n"
-" cmpq %%rsi, %%r9\n"
-" jbe .L_break_loop\n"
-
-".L_do_loop:\n"
-" movq %%r12, %%r8\n" /* r8 = lmask */
-" cmpb $32, %%bl\n"
-" ja .L_get_length_code\n" /* if (32 < bits) */
-
-" lodsl\n" /* eax = *(uint *)in++ */
-" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
-" addb $32, %%bl\n" /* bits += 32 */
-" shlq %%cl, %%rax\n"
-" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
-
-".L_get_length_code:\n"
-" andq %%rdx, %%r8\n" /* r8 &= hold */
-" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
-
-" movb %%ah, %%cl\n" /* cl = this.bits */
-" subb %%ah, %%bl\n" /* bits -= this.bits */
-" shrq %%cl, %%rdx\n" /* hold >>= this.bits */
-
-" testb %%al, %%al\n"
-" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
-
-" movq %%r12, %%r8\n" /* r8 = lmask */
-" shrl $16, %%eax\n" /* output this.val char */
-" stosb\n"
-
-".L_get_length_code_one_time:\n"
-" andq %%rdx, %%r8\n" /* r8 &= hold */
-" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
-
-".L_dolen:\n"
-" movb %%ah, %%cl\n" /* cl = this.bits */
-" subb %%ah, %%bl\n" /* bits -= this.bits */
-" shrq %%cl, %%rdx\n" /* hold >>= this.bits */
-
-" testb %%al, %%al\n"
-" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
-
-" shrl $16, %%eax\n" /* output this.val char */
-" stosb\n"
-" jmp .L_while_test\n"
-
-".align 32,0x90\n"
-".L_test_for_length_base:\n"
-" movl %%eax, %%r14d\n" /* len = this */
-" shrl $16, %%r14d\n" /* len = this.val */
-" movb %%al, %%cl\n"
-
-" testb $16, %%al\n"
-" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
-" andb $15, %%cl\n" /* op &= 15 */
-" jz .L_decode_distance\n" /* if (!op) */
-
-".L_add_bits_to_len:\n"
-" subb %%cl, %%bl\n"
-" xorl %%eax, %%eax\n"
-" incl %%eax\n"
-" shll %%cl, %%eax\n"
-" decl %%eax\n"
-" andl %%edx, %%eax\n" /* eax &= hold */
-" shrq %%cl, %%rdx\n"
-" addl %%eax, %%r14d\n" /* len += hold & mask[op] */
-
-".L_decode_distance:\n"
-" movq %%r13, %%r8\n" /* r8 = dmask */
-" cmpb $32, %%bl\n"
-" ja .L_get_distance_code\n" /* if (32 < bits) */
-
-" lodsl\n" /* eax = *(uint *)in++ */
-" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
-" addb $32, %%bl\n" /* bits += 32 */
-" shlq %%cl, %%rax\n"
-" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
-
-".L_get_distance_code:\n"
-" andq %%rdx, %%r8\n" /* r8 &= hold */
-" movl (%%r11,%%r8,4), %%eax\n" /* eax = dcode[hold & dmask] */
-
-".L_dodist:\n"
-" movl %%eax, %%r15d\n" /* dist = this */
-" shrl $16, %%r15d\n" /* dist = this.val */
-" movb %%ah, %%cl\n"
-" subb %%ah, %%bl\n" /* bits -= this.bits */
-" shrq %%cl, %%rdx\n" /* hold >>= this.bits */
-" movb %%al, %%cl\n" /* cl = this.op */
-
-" testb $16, %%al\n" /* if ((op & 16) == 0) */
-" jz .L_test_for_second_level_dist\n"
-" andb $15, %%cl\n" /* op &= 15 */
-" jz .L_check_dist_one\n"
-
-".L_add_bits_to_dist:\n"
-" subb %%cl, %%bl\n"
-" xorl %%eax, %%eax\n"
-" incl %%eax\n"
-" shll %%cl, %%eax\n"
-" decl %%eax\n" /* (1 << op) - 1 */
-" andl %%edx, %%eax\n" /* eax &= hold */
-" shrq %%cl, %%rdx\n"
-" addl %%eax, %%r15d\n" /* dist += hold & ((1 << op) - 1) */
-
-".L_check_window:\n"
-" movq %%rsi, %%r8\n" /* save in so from can use it's reg */
-" movq %%rdi, %%rax\n"
-" subq 40(%%rsp), %%rax\n" /* nbytes = out - beg */
-
-" cmpl %%r15d, %%eax\n"
-" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */
-
-" movl %%r14d, %%ecx\n" /* ecx = len */
-" movq %%rdi, %%rsi\n"
-" subq %%r15, %%rsi\n" /* from = out - dist */
-
-" sarl %%ecx\n"
-" jnc .L_copy_two\n" /* if len % 2 == 0 */
-
-" rep movsw\n"
-" movb (%%rsi), %%al\n"
-" movb %%al, (%%rdi)\n"
-" incq %%rdi\n"
-
-" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */
-" jmp .L_while_test\n"
-
-".L_copy_two:\n"
-" rep movsw\n"
-" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */
-" jmp .L_while_test\n"
-
-".align 32,0x90\n"
-".L_check_dist_one:\n"
-" cmpl $1, %%r15d\n" /* if dist 1, is a memset */
-" jne .L_check_window\n"
-" cmpq %%rdi, 40(%%rsp)\n" /* if out == beg, outside window */
-" je .L_check_window\n"
-
-" movl %%r14d, %%ecx\n" /* ecx = len */
-" movb -1(%%rdi), %%al\n"
-" movb %%al, %%ah\n"
-
-" sarl %%ecx\n"
-" jnc .L_set_two\n"
-" movb %%al, (%%rdi)\n"
-" incq %%rdi\n"
-
-".L_set_two:\n"
-" rep stosw\n"
-" jmp .L_while_test\n"
-
-".align 32,0x90\n"
-".L_test_for_second_level_length:\n"
-" testb $64, %%al\n"
-" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
-
-" xorl %%eax, %%eax\n"
-" incl %%eax\n"
-" shll %%cl, %%eax\n"
-" decl %%eax\n"
-" andl %%edx, %%eax\n" /* eax &= hold */
-" addl %%r14d, %%eax\n" /* eax += len */
-" movl (%%rbp,%%rax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
-" jmp .L_dolen\n"
-
-".align 32,0x90\n"
-".L_test_for_second_level_dist:\n"
-" testb $64, %%al\n"
-" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
-
-" xorl %%eax, %%eax\n"
-" incl %%eax\n"
-" shll %%cl, %%eax\n"
-" decl %%eax\n"
-" andl %%edx, %%eax\n" /* eax &= hold */
-" addl %%r15d, %%eax\n" /* eax += dist */
-" movl (%%r11,%%rax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
-" jmp .L_dodist\n"
-
-".align 32,0x90\n"
-".L_clip_window:\n"
-" movl %%eax, %%ecx\n" /* ecx = nbytes */
-" movl 92(%%rsp), %%eax\n" /* eax = wsize, prepare for dist cmp */
-" negl %%ecx\n" /* nbytes = -nbytes */
-
-" cmpl %%r15d, %%eax\n"
-" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */
-
-" addl %%r15d, %%ecx\n" /* nbytes = dist - nbytes */
-" cmpl $0, 96(%%rsp)\n"
-" jne .L_wrap_around_window\n" /* if (write != 0) */
-
-" movq 56(%%rsp), %%rsi\n" /* from = window */
-" subl %%ecx, %%eax\n" /* eax -= nbytes */
-" addq %%rax, %%rsi\n" /* from += wsize - nbytes */
-
-" movl %%r14d, %%eax\n" /* eax = len */
-" cmpl %%ecx, %%r14d\n"
-" jbe .L_do_copy\n" /* if (nbytes >= len) */
-
-" subl %%ecx, %%eax\n" /* eax -= nbytes */
-" rep movsb\n"
-" movq %%rdi, %%rsi\n"
-" subq %%r15, %%rsi\n" /* from = &out[ -dist ] */
-" jmp .L_do_copy\n"
-
-".align 32,0x90\n"
-".L_wrap_around_window:\n"
-" movl 96(%%rsp), %%eax\n" /* eax = write */
-" cmpl %%eax, %%ecx\n"
-" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */
-
-" movl 92(%%rsp), %%esi\n" /* from = wsize */
-" addq 56(%%rsp), %%rsi\n" /* from += window */
-" addq %%rax, %%rsi\n" /* from += write */
-" subq %%rcx, %%rsi\n" /* from -= nbytes */
-" subl %%eax, %%ecx\n" /* nbytes -= write */
-
-" movl %%r14d, %%eax\n" /* eax = len */
-" cmpl %%ecx, %%eax\n"
-" jbe .L_do_copy\n" /* if (nbytes >= len) */
-
-" subl %%ecx, %%eax\n" /* len -= nbytes */
-" rep movsb\n"
-" movq 56(%%rsp), %%rsi\n" /* from = window */
-" movl 96(%%rsp), %%ecx\n" /* nbytes = write */
-" cmpl %%ecx, %%eax\n"
-" jbe .L_do_copy\n" /* if (nbytes >= len) */
-
-" subl %%ecx, %%eax\n" /* len -= nbytes */
-" rep movsb\n"
-" movq %%rdi, %%rsi\n"
-" subq %%r15, %%rsi\n" /* from = out - dist */
-" jmp .L_do_copy\n"
-
-".align 32,0x90\n"
-".L_contiguous_in_window:\n"
-" movq 56(%%rsp), %%rsi\n" /* rsi = window */
-" addq %%rax, %%rsi\n"
-" subq %%rcx, %%rsi\n" /* from += write - nbytes */
-
-" movl %%r14d, %%eax\n" /* eax = len */
-" cmpl %%ecx, %%eax\n"
-" jbe .L_do_copy\n" /* if (nbytes >= len) */
-
-" subl %%ecx, %%eax\n" /* len -= nbytes */
-" rep movsb\n"
-" movq %%rdi, %%rsi\n"
-" subq %%r15, %%rsi\n" /* from = out - dist */
-" jmp .L_do_copy\n" /* if (nbytes >= len) */
-
-".align 32,0x90\n"
-".L_do_copy:\n"
-" movl %%eax, %%ecx\n" /* ecx = len */
-" rep movsb\n"
-
-" movq %%r8, %%rsi\n" /* move in back to %esi, toss from */
-" jmp .L_while_test\n"
-
-".L_test_for_end_of_block:\n"
-" testb $32, %%al\n"
-" jz .L_invalid_literal_length_code\n"
-" movl $1, 116(%%rsp)\n"
-" jmp .L_break_loop_with_status\n"
-
-".L_invalid_literal_length_code:\n"
-" movl $2, 116(%%rsp)\n"
-" jmp .L_break_loop_with_status\n"
-
-".L_invalid_distance_code:\n"
-" movl $3, 116(%%rsp)\n"
-" jmp .L_break_loop_with_status\n"
-
-".L_invalid_distance_too_far:\n"
-" movl $4, 116(%%rsp)\n"
-" jmp .L_break_loop_with_status\n"
-
-".L_break_loop:\n"
-" movl $0, 116(%%rsp)\n"
-
-".L_break_loop_with_status:\n"
-/* put in, out, bits, and hold back into ar and pop esp */
-" movq %%rsi, 16(%%rsp)\n" /* in */
-" movq %%rdi, 32(%%rsp)\n" /* out */
-" movl %%ebx, 88(%%rsp)\n" /* bits */
-" movq %%rdx, 80(%%rsp)\n" /* hold */
-" movq (%%rsp), %%rax\n" /* restore rbp and rsp */
-" movq 8(%%rsp), %%rbp\n"
-" movq %%rax, %%rsp\n"
- :
- : "m" (ar)
- : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
- "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
- );
-#elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 )
- __asm__ __volatile__ (
-" leal %0, %%eax\n"
-" movl %%esp, (%%eax)\n" /* save esp, ebp */
-" movl %%ebp, 4(%%eax)\n"
-" movl %%eax, %%esp\n"
-" movl 8(%%esp), %%esi\n" /* esi = in */
-" movl 16(%%esp), %%edi\n" /* edi = out */
-" movl 40(%%esp), %%edx\n" /* edx = hold */
-" movl 44(%%esp), %%ebx\n" /* ebx = bits */
-" movl 32(%%esp), %%ebp\n" /* ebp = lcode */
-
-" cld\n"
-" jmp .L_do_loop\n"
-
-".align 32,0x90\n"
-".L_while_test:\n"
-" cmpl %%edi, 24(%%esp)\n" /* out < end */
-" jbe .L_break_loop\n"
-" cmpl %%esi, 12(%%esp)\n" /* in < last */
-" jbe .L_break_loop\n"
-
-".L_do_loop:\n"
-" cmpb $15, %%bl\n"
-" ja .L_get_length_code\n" /* if (15 < bits) */
-
-" xorl %%eax, %%eax\n"
-" lodsw\n" /* al = *(ushort *)in++ */
-" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
-" addb $16, %%bl\n" /* bits += 16 */
-" shll %%cl, %%eax\n"
-" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
-
-".L_get_length_code:\n"
-" movl 56(%%esp), %%eax\n" /* eax = lmask */
-" andl %%edx, %%eax\n" /* eax &= hold */
-" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */
-
-".L_dolen:\n"
-" movb %%ah, %%cl\n" /* cl = this.bits */
-" subb %%ah, %%bl\n" /* bits -= this.bits */
-" shrl %%cl, %%edx\n" /* hold >>= this.bits */
-
-" testb %%al, %%al\n"
-" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
-
-" shrl $16, %%eax\n" /* output this.val char */
-" stosb\n"
-" jmp .L_while_test\n"
-
-".align 32,0x90\n"
-".L_test_for_length_base:\n"
-" movl %%eax, %%ecx\n" /* len = this */
-" shrl $16, %%ecx\n" /* len = this.val */
-" movl %%ecx, 64(%%esp)\n" /* save len */
-" movb %%al, %%cl\n"
-
-" testb $16, %%al\n"
-" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
-" andb $15, %%cl\n" /* op &= 15 */
-" jz .L_decode_distance\n" /* if (!op) */
-" cmpb %%cl, %%bl\n"
-" jae .L_add_bits_to_len\n" /* if (op <= bits) */
-
-" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */
-" xorl %%eax, %%eax\n"
-" lodsw\n" /* al = *(ushort *)in++ */
-" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
-" addb $16, %%bl\n" /* bits += 16 */
-" shll %%cl, %%eax\n"
-" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
-" movb %%ch, %%cl\n" /* move op back to ecx */
-
-".L_add_bits_to_len:\n"
-" subb %%cl, %%bl\n"
-" xorl %%eax, %%eax\n"
-" incl %%eax\n"
-" shll %%cl, %%eax\n"
-" decl %%eax\n"
-" andl %%edx, %%eax\n" /* eax &= hold */
-" shrl %%cl, %%edx\n"
-" addl %%eax, 64(%%esp)\n" /* len += hold & mask[op] */
-
-".L_decode_distance:\n"
-" cmpb $15, %%bl\n"
-" ja .L_get_distance_code\n" /* if (15 < bits) */
-
-" xorl %%eax, %%eax\n"
-" lodsw\n" /* al = *(ushort *)in++ */
-" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
-" addb $16, %%bl\n" /* bits += 16 */
-" shll %%cl, %%eax\n"
-" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
-
-".L_get_distance_code:\n"
-" movl 60(%%esp), %%eax\n" /* eax = dmask */
-" movl 36(%%esp), %%ecx\n" /* ecx = dcode */
-" andl %%edx, %%eax\n" /* eax &= hold */
-" movl (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */
-
-".L_dodist:\n"
-" movl %%eax, %%ebp\n" /* dist = this */
-" shrl $16, %%ebp\n" /* dist = this.val */
-" movb %%ah, %%cl\n"
-" subb %%ah, %%bl\n" /* bits -= this.bits */
-" shrl %%cl, %%edx\n" /* hold >>= this.bits */
-" movb %%al, %%cl\n" /* cl = this.op */
-
-" testb $16, %%al\n" /* if ((op & 16) == 0) */
-" jz .L_test_for_second_level_dist\n"
-" andb $15, %%cl\n" /* op &= 15 */
-" jz .L_check_dist_one\n"
-" cmpb %%cl, %%bl\n"
-" jae .L_add_bits_to_dist\n" /* if (op <= bits) 97.6% */
-
-" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */
-" xorl %%eax, %%eax\n"
-" lodsw\n" /* al = *(ushort *)in++ */
-" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
-" addb $16, %%bl\n" /* bits += 16 */
-" shll %%cl, %%eax\n"
-" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
-" movb %%ch, %%cl\n" /* move op back to ecx */
-
-".L_add_bits_to_dist:\n"
-" subb %%cl, %%bl\n"
-" xorl %%eax, %%eax\n"
-" incl %%eax\n"
-" shll %%cl, %%eax\n"
-" decl %%eax\n" /* (1 << op) - 1 */
-" andl %%edx, %%eax\n" /* eax &= hold */
-" shrl %%cl, %%edx\n"
-" addl %%eax, %%ebp\n" /* dist += hold & ((1 << op) - 1) */
-
-".L_check_window:\n"
-" movl %%esi, 8(%%esp)\n" /* save in so from can use it's reg */
-" movl %%edi, %%eax\n"
-" subl 20(%%esp), %%eax\n" /* nbytes = out - beg */
-
-" cmpl %%ebp, %%eax\n"
-" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */
-
-" movl 64(%%esp), %%ecx\n" /* ecx = len */
-" movl %%edi, %%esi\n"
-" subl %%ebp, %%esi\n" /* from = out - dist */
-
-" sarl %%ecx\n"
-" jnc .L_copy_two\n" /* if len % 2 == 0 */
-
-" rep movsw\n"
-" movb (%%esi), %%al\n"
-" movb %%al, (%%edi)\n"
-" incl %%edi\n"
-
-" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
-" movl 32(%%esp), %%ebp\n" /* ebp = lcode */
-" jmp .L_while_test\n"
-
-".L_copy_two:\n"
-" rep movsw\n"
-" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
-" movl 32(%%esp), %%ebp\n" /* ebp = lcode */
-" jmp .L_while_test\n"
-
-".align 32,0x90\n"
-".L_check_dist_one:\n"
-" cmpl $1, %%ebp\n" /* if dist 1, is a memset */
-" jne .L_check_window\n"
-" cmpl %%edi, 20(%%esp)\n"
-" je .L_check_window\n" /* out == beg, if outside window */
-
-" movl 64(%%esp), %%ecx\n" /* ecx = len */
-" movb -1(%%edi), %%al\n"
-" movb %%al, %%ah\n"
-
-" sarl %%ecx\n"
-" jnc .L_set_two\n"
-" movb %%al, (%%edi)\n"
-" incl %%edi\n"
-
-".L_set_two:\n"
-" rep stosw\n"
-" movl 32(%%esp), %%ebp\n" /* ebp = lcode */
-" jmp .L_while_test\n"
-
-".align 32,0x90\n"
-".L_test_for_second_level_length:\n"
-" testb $64, %%al\n"
-" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
-
-" xorl %%eax, %%eax\n"
-" incl %%eax\n"
-" shll %%cl, %%eax\n"
-" decl %%eax\n"
-" andl %%edx, %%eax\n" /* eax &= hold */
-" addl 64(%%esp), %%eax\n" /* eax += len */
-" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
-" jmp .L_dolen\n"
-
-".align 32,0x90\n"
-".L_test_for_second_level_dist:\n"
-" testb $64, %%al\n"
-" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
-
-" xorl %%eax, %%eax\n"
-" incl %%eax\n"
-" shll %%cl, %%eax\n"
-" decl %%eax\n"
-" andl %%edx, %%eax\n" /* eax &= hold */
-" addl %%ebp, %%eax\n" /* eax += dist */
-" movl 36(%%esp), %%ecx\n" /* ecx = dcode */
-" movl (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
-" jmp .L_dodist\n"
-
-".align 32,0x90\n"
-".L_clip_window:\n"
-" movl %%eax, %%ecx\n"
-" movl 48(%%esp), %%eax\n" /* eax = wsize */
-" negl %%ecx\n" /* nbytes = -nbytes */
-" movl 28(%%esp), %%esi\n" /* from = window */
-
-" cmpl %%ebp, %%eax\n"
-" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */
-
-" addl %%ebp, %%ecx\n" /* nbytes = dist - nbytes */
-" cmpl $0, 52(%%esp)\n"
-" jne .L_wrap_around_window\n" /* if (write != 0) */
-
-" subl %%ecx, %%eax\n"
-" addl %%eax, %%esi\n" /* from += wsize - nbytes */
-
-" movl 64(%%esp), %%eax\n" /* eax = len */
-" cmpl %%ecx, %%eax\n"
-" jbe .L_do_copy\n" /* if (nbytes >= len) */
-
-" subl %%ecx, %%eax\n" /* len -= nbytes */
-" rep movsb\n"
-" movl %%edi, %%esi\n"
-" subl %%ebp, %%esi\n" /* from = out - dist */
-" jmp .L_do_copy\n"
-
-".align 32,0x90\n"
-".L_wrap_around_window:\n"
-" movl 52(%%esp), %%eax\n" /* eax = write */
-" cmpl %%eax, %%ecx\n"
-" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */
-
-" addl 48(%%esp), %%esi\n" /* from += wsize */
-" addl %%eax, %%esi\n" /* from += write */
-" subl %%ecx, %%esi\n" /* from -= nbytes */
-" subl %%eax, %%ecx\n" /* nbytes -= write */
-
-" movl 64(%%esp), %%eax\n" /* eax = len */
-" cmpl %%ecx, %%eax\n"
-" jbe .L_do_copy\n" /* if (nbytes >= len) */
-
-" subl %%ecx, %%eax\n" /* len -= nbytes */
-" rep movsb\n"
-" movl 28(%%esp), %%esi\n" /* from = window */
-" movl 52(%%esp), %%ecx\n" /* nbytes = write */
-" cmpl %%ecx, %%eax\n"
-" jbe .L_do_copy\n" /* if (nbytes >= len) */
-
-" subl %%ecx, %%eax\n" /* len -= nbytes */
-" rep movsb\n"
-" movl %%edi, %%esi\n"
-" subl %%ebp, %%esi\n" /* from = out - dist */
-" jmp .L_do_copy\n"
-
-".align 32,0x90\n"
-".L_contiguous_in_window:\n"
-" addl %%eax, %%esi\n"
-" subl %%ecx, %%esi\n" /* from += write - nbytes */
-
-" movl 64(%%esp), %%eax\n" /* eax = len */
-" cmpl %%ecx, %%eax\n"
-" jbe .L_do_copy\n" /* if (nbytes >= len) */
-
-" subl %%ecx, %%eax\n" /* len -= nbytes */
-" rep movsb\n"
-" movl %%edi, %%esi\n"
-" subl %%ebp, %%esi\n" /* from = out - dist */
-" jmp .L_do_copy\n" /* if (nbytes >= len) */
-
-".align 32,0x90\n"
-".L_do_copy:\n"
-" movl %%eax, %%ecx\n"
-" rep movsb\n"
-
-" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
-" movl 32(%%esp), %%ebp\n" /* ebp = lcode */
-" jmp .L_while_test\n"
-
-".L_test_for_end_of_block:\n"
-" testb $32, %%al\n"
-" jz .L_invalid_literal_length_code\n"
-" movl $1, 72(%%esp)\n"
-" jmp .L_break_loop_with_status\n"
-
-".L_invalid_literal_length_code:\n"
-" movl $2, 72(%%esp)\n"
-" jmp .L_break_loop_with_status\n"
-
-".L_invalid_distance_code:\n"
-" movl $3, 72(%%esp)\n"
-" jmp .L_break_loop_with_status\n"
-
-".L_invalid_distance_too_far:\n"
-" movl 8(%%esp), %%esi\n"
-" movl $4, 72(%%esp)\n"
-" jmp .L_break_loop_with_status\n"
-
-".L_break_loop:\n"
-" movl $0, 72(%%esp)\n"
-
-".L_break_loop_with_status:\n"
-/* put in, out, bits, and hold back into ar and pop esp */
-" movl %%esi, 8(%%esp)\n" /* save in */
-" movl %%edi, 16(%%esp)\n" /* save out */
-" movl %%ebx, 44(%%esp)\n" /* save bits */
-" movl %%edx, 40(%%esp)\n" /* save hold */
-" movl 4(%%esp), %%ebp\n" /* restore esp, ebp */
-" movl (%%esp), %%esp\n"
- :
- : "m" (ar)
- : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
- );
-#elif defined( _MSC_VER ) && ! defined( _M_AMD64 )
- __asm {
- lea eax, ar
- mov [eax], esp /* save esp, ebp */
- mov [eax+4], ebp
- mov esp, eax
- mov esi, [esp+8] /* esi = in */
- mov edi, [esp+16] /* edi = out */
- mov edx, [esp+40] /* edx = hold */
- mov ebx, [esp+44] /* ebx = bits */
- mov ebp, [esp+32] /* ebp = lcode */
-
- cld
- jmp L_do_loop
-
-ALIGN 4
-L_while_test:
- cmp [esp+24], edi
- jbe L_break_loop
- cmp [esp+12], esi
- jbe L_break_loop
-
-L_do_loop:
- cmp bl, 15
- ja L_get_length_code /* if (15 < bits) */
-
- xor eax, eax
- lodsw /* al = *(ushort *)in++ */
- mov cl, bl /* cl = bits, needs it for shifting */
- add bl, 16 /* bits += 16 */
- shl eax, cl
- or edx, eax /* hold |= *((ushort *)in)++ << bits */
-
-L_get_length_code:
- mov eax, [esp+56] /* eax = lmask */
- and eax, edx /* eax &= hold */
- mov eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */
-
-L_dolen:
- mov cl, ah /* cl = this.bits */
- sub bl, ah /* bits -= this.bits */
- shr edx, cl /* hold >>= this.bits */
-
- test al, al
- jnz L_test_for_length_base /* if (op != 0) 45.7% */
-
- shr eax, 16 /* output this.val char */
- stosb
- jmp L_while_test
-
-ALIGN 4
-L_test_for_length_base:
- mov ecx, eax /* len = this */
- shr ecx, 16 /* len = this.val */
- mov [esp+64], ecx /* save len */
- mov cl, al
-
- test al, 16
- jz L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
- and cl, 15 /* op &= 15 */
- jz L_decode_distance /* if (!op) */
- cmp bl, cl
- jae L_add_bits_to_len /* if (op <= bits) */
-
- mov ch, cl /* stash op in ch, freeing cl */
- xor eax, eax
- lodsw /* al = *(ushort *)in++ */
- mov cl, bl /* cl = bits, needs it for shifting */
- add bl, 16 /* bits += 16 */
- shl eax, cl
- or edx, eax /* hold |= *((ushort *)in)++ << bits */
- mov cl, ch /* move op back to ecx */
-
-L_add_bits_to_len:
- sub bl, cl
- xor eax, eax
- inc eax
- shl eax, cl
- dec eax
- and eax, edx /* eax &= hold */
- shr edx, cl
- add [esp+64], eax /* len += hold & mask[op] */
-
-L_decode_distance:
- cmp bl, 15
- ja L_get_distance_code /* if (15 < bits) */
-
- xor eax, eax
- lodsw /* al = *(ushort *)in++ */
- mov cl, bl /* cl = bits, needs it for shifting */
- add bl, 16 /* bits += 16 */
- shl eax, cl
- or edx, eax /* hold |= *((ushort *)in)++ << bits */
-
-L_get_distance_code:
- mov eax, [esp+60] /* eax = dmask */
- mov ecx, [esp+36] /* ecx = dcode */
- and eax, edx /* eax &= hold */
- mov eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */
-
-L_dodist:
- mov ebp, eax /* dist = this */
- shr ebp, 16 /* dist = this.val */
- mov cl, ah
- sub bl, ah /* bits -= this.bits */
- shr edx, cl /* hold >>= this.bits */
- mov cl, al /* cl = this.op */
-
- test al, 16 /* if ((op & 16) == 0) */
- jz L_test_for_second_level_dist
- and cl, 15 /* op &= 15 */
- jz L_check_dist_one
- cmp bl, cl
- jae L_add_bits_to_dist /* if (op <= bits) 97.6% */
-
- mov ch, cl /* stash op in ch, freeing cl */
- xor eax, eax
- lodsw /* al = *(ushort *)in++ */
- mov cl, bl /* cl = bits, needs it for shifting */
- add bl, 16 /* bits += 16 */
- shl eax, cl
- or edx, eax /* hold |= *((ushort *)in)++ << bits */
- mov cl, ch /* move op back to ecx */
-
-L_add_bits_to_dist:
- sub bl, cl
- xor eax, eax
- inc eax
- shl eax, cl
- dec eax /* (1 << op) - 1 */
- and eax, edx /* eax &= hold */
- shr edx, cl
- add ebp, eax /* dist += hold & ((1 << op) - 1) */
-
-L_check_window:
- mov [esp+8], esi /* save in so from can use it's reg */
- mov eax, edi
- sub eax, [esp+20] /* nbytes = out - beg */
-
- cmp eax, ebp
- jb L_clip_window /* if (dist > nbytes) 4.2% */
-
- mov ecx, [esp+64] /* ecx = len */
- mov esi, edi
- sub esi, ebp /* from = out - dist */
-
- sar ecx, 1
- jnc L_copy_two
-
- rep movsw
- mov al, [esi]
- mov [edi], al
- inc edi
-
- mov esi, [esp+8] /* move in back to %esi, toss from */
- mov ebp, [esp+32] /* ebp = lcode */
- jmp L_while_test
-
-L_copy_two:
- rep movsw
- mov esi, [esp+8] /* move in back to %esi, toss from */
- mov ebp, [esp+32] /* ebp = lcode */
- jmp L_while_test
-
-ALIGN 4
-L_check_dist_one:
- cmp ebp, 1 /* if dist 1, is a memset */
- jne L_check_window
- cmp [esp+20], edi
- je L_check_window /* out == beg, if outside window */
-
- mov ecx, [esp+64] /* ecx = len */
- mov al, [edi-1]
- mov ah, al
-
- sar ecx, 1
- jnc L_set_two
- mov [edi], al /* memset out with from[-1] */
- inc edi
-
-L_set_two:
- rep stosw
- mov ebp, [esp+32] /* ebp = lcode */
- jmp L_while_test
-
-ALIGN 4
-L_test_for_second_level_length:
- test al, 64
- jnz L_test_for_end_of_block /* if ((op & 64) != 0) */
-
- xor eax, eax
- inc eax
- shl eax, cl
- dec eax
- and eax, edx /* eax &= hold */
- add eax, [esp+64] /* eax += len */
- mov eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/
- jmp L_dolen
-
-ALIGN 4
-L_test_for_second_level_dist:
- test al, 64
- jnz L_invalid_distance_code /* if ((op & 64) != 0) */
-
- xor eax, eax
- inc eax
- shl eax, cl
- dec eax
- and eax, edx /* eax &= hold */
- add eax, ebp /* eax += dist */
- mov ecx, [esp+36] /* ecx = dcode */
- mov eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/
- jmp L_dodist
-
-ALIGN 4
-L_clip_window:
- mov ecx, eax
- mov eax, [esp+48] /* eax = wsize */
- neg ecx /* nbytes = -nbytes */
- mov esi, [esp+28] /* from = window */
-
- cmp eax, ebp
- jb L_invalid_distance_too_far /* if (dist > wsize) */
-
- add ecx, ebp /* nbytes = dist - nbytes */
- cmp dword ptr [esp+52], 0
- jne L_wrap_around_window /* if (write != 0) */
-
- sub eax, ecx
- add esi, eax /* from += wsize - nbytes */
-
- mov eax, [esp+64] /* eax = len */
- cmp eax, ecx
- jbe L_do_copy /* if (nbytes >= len) */
-
- sub eax, ecx /* len -= nbytes */
- rep movsb
- mov esi, edi
- sub esi, ebp /* from = out - dist */
- jmp L_do_copy
-
-ALIGN 4
-L_wrap_around_window:
- mov eax, [esp+52] /* eax = write */
- cmp ecx, eax
- jbe L_contiguous_in_window /* if (write >= nbytes) */
-
- add esi, [esp+48] /* from += wsize */
- add esi, eax /* from += write */
- sub esi, ecx /* from -= nbytes */
- sub ecx, eax /* nbytes -= write */
-
- mov eax, [esp+64] /* eax = len */
- cmp eax, ecx
- jbe L_do_copy /* if (nbytes >= len) */
-
- sub eax, ecx /* len -= nbytes */
- rep movsb
- mov esi, [esp+28] /* from = window */
- mov ecx, [esp+52] /* nbytes = write */
- cmp eax, ecx
- jbe L_do_copy /* if (nbytes >= len) */
-
- sub eax, ecx /* len -= nbytes */
- rep movsb
- mov esi, edi
- sub esi, ebp /* from = out - dist */
- jmp L_do_copy
-
-ALIGN 4
-L_contiguous_in_window:
- add esi, eax
- sub esi, ecx /* from += write - nbytes */
-
- mov eax, [esp+64] /* eax = len */
- cmp eax, ecx
- jbe L_do_copy /* if (nbytes >= len) */
-
- sub eax, ecx /* len -= nbytes */
- rep movsb
- mov esi, edi
- sub esi, ebp /* from = out - dist */
- jmp L_do_copy
-
-ALIGN 4
-L_do_copy:
- mov ecx, eax
- rep movsb
-
- mov esi, [esp+8] /* move in back to %esi, toss from */
- mov ebp, [esp+32] /* ebp = lcode */
- jmp L_while_test
-
-L_test_for_end_of_block:
- test al, 32
- jz L_invalid_literal_length_code
- mov dword ptr [esp+72], 1
- jmp L_break_loop_with_status
-
-L_invalid_literal_length_code:
- mov dword ptr [esp+72], 2
- jmp L_break_loop_with_status
-
-L_invalid_distance_code:
- mov dword ptr [esp+72], 3
- jmp L_break_loop_with_status
-
-L_invalid_distance_too_far:
- mov esi, [esp+4]
- mov dword ptr [esp+72], 4
- jmp L_break_loop_with_status
-
-L_break_loop:
- mov dword ptr [esp+72], 0
-
-L_break_loop_with_status:
-/* put in, out, bits, and hold back into ar and pop esp */
- mov [esp+8], esi /* save in */
- mov [esp+16], edi /* save out */
- mov [esp+44], ebx /* save bits */
- mov [esp+40], edx /* save hold */
- mov ebp, [esp+4] /* restore esp, ebp */
- mov esp, [esp]
- }
-#else
-#error "x86 architecture not defined"
-#endif
-
- if (ar.status > 1) {
- if (ar.status == 2)
- strm->msg = "invalid literal/length code";
- else if (ar.status == 3)
- strm->msg = "invalid distance code";
- else
- strm->msg = "invalid distance too far back";
- state->mode = BAD;
- }
- else if ( ar.status == 1 ) {
- state->mode = TYPE;
- }
-
- /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
- ar.len = ar.bits >> 3;
- ar.in -= ar.len;
- ar.bits -= ar.len << 3;
- ar.hold &= (1U << ar.bits) - 1;
-
- /* update state and return */
- strm->next_in = ar.in;
- strm->next_out = ar.out;
- strm->avail_in = (unsigned)(ar.in < ar.last ?
- PAD_AVAIL_IN + (ar.last - ar.in) :
- PAD_AVAIL_IN - (ar.in - ar.last));
- strm->avail_out = (unsigned)(ar.out < ar.end ?
- PAD_AVAIL_OUT + (ar.end - ar.out) :
- PAD_AVAIL_OUT - (ar.out - ar.end));
- state->hold = ar.hold;
- state->bits = ar.bits;
- return;
-}
-
diff --git a/cpukit/zlib/contrib/inflate86/inffast.S b/cpukit/zlib/contrib/inflate86/inffast.S
deleted file mode 100644
index 2245a2905b..0000000000
--- a/cpukit/zlib/contrib/inflate86/inffast.S
+++ /dev/null
@@ -1,1368 +0,0 @@
-/*
- * inffast.S is a hand tuned assembler version of:
- *
- * inffast.c -- fast decoding
- * Copyright (C) 1995-2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Copyright (C) 2003 Chris Anderson <christop@charm.net>
- * Please use the copyright conditions above.
- *
- * This version (Jan-23-2003) of inflate_fast was coded and tested under
- * GNU/Linux on a pentium 3, using the gcc-3.2 compiler distribution. On that
- * machine, I found that gzip style archives decompressed about 20% faster than
- * the gcc-3.2 -O3 -fomit-frame-pointer compiled version. Your results will
- * depend on how large of a buffer is used for z_stream.next_in & next_out
- * (8K-32K worked best for my 256K cpu cache) and how much overhead there is in
- * stream processing I/O and crc32/addler32. In my case, this routine used
- * 70% of the cpu time and crc32 used 20%.
- *
- * I am confident that this version will work in the general case, but I have
- * not tested a wide variety of datasets or a wide variety of platforms.
- *
- * Jan-24-2003 -- Added -DUSE_MMX define for slightly faster inflating.
- * It should be a runtime flag instead of compile time flag...
- *
- * Jan-26-2003 -- Added runtime check for MMX support with cpuid instruction.
- * With -DUSE_MMX, only MMX code is compiled. With -DNO_MMX, only non-MMX code
- * is compiled. Without either option, runtime detection is enabled. Runtime
- * detection should work on all modern cpus and the recomended algorithm (flip
- * ID bit on eflags and then use the cpuid instruction) is used in many
- * multimedia applications. Tested under win2k with gcc-2.95 and gas-2.12
- * distributed with cygwin3. Compiling with gcc-2.95 -c inffast.S -o
- * inffast.obj generates a COFF object which can then be linked with MSVC++
- * compiled code. Tested under FreeBSD 4.7 with gcc-2.95.
- *
- * Jan-28-2003 -- Tested Athlon XP... MMX mode is slower than no MMX (and
- * slower than compiler generated code). Adjusted cpuid check to use the MMX
- * code only for Pentiums < P4 until I have more data on the P4. Speed
- * improvment is only about 15% on the Athlon when compared with code generated
- * with MSVC++. Not sure yet, but I think the P4 will also be slower using the
- * MMX mode because many of it's x86 ALU instructions execute in .5 cycles and
- * have less latency than MMX ops. Added code to buffer the last 11 bytes of
- * the input stream since the MMX code grabs bits in chunks of 32, which
- * differs from the inffast.c algorithm. I don't think there would have been
- * read overruns where a page boundary was crossed (a segfault), but there
- * could have been overruns when next_in ends on unaligned memory (unintialized
- * memory read).
- *
- * Mar-13-2003 -- P4 MMX is slightly slower than P4 NO_MMX. I created a C
- * version of the non-MMX code so that it doesn't depend on zstrm and zstate
- * structure offsets which are hard coded in this file. This was last tested
- * with zlib-1.2.0 which is currently in beta testing, newer versions of this
- * and inffas86.c can be found at http://www.eetbeetee.com/zlib/ and
- * http://www.charm.net/~christop/zlib/
- */
-
-
-/*
- * if you have underscore linking problems (_inflate_fast undefined), try
- * using -DGAS_COFF
- */
-#if ! defined( GAS_COFF ) && ! defined( GAS_ELF )
-
-#if defined( WIN32 ) || defined( __CYGWIN__ )
-#define GAS_COFF /* windows object format */
-#else
-#define GAS_ELF
-#endif
-
-#endif /* ! GAS_COFF && ! GAS_ELF */
-
-
-#if defined( GAS_COFF )
-
-/* coff externals have underscores */
-#define inflate_fast _inflate_fast
-#define inflate_fast_use_mmx _inflate_fast_use_mmx
-
-#endif /* GAS_COFF */
-
-
-.file "inffast.S"
-
-.globl inflate_fast
-
-.text
-.align 4,0
-.L_invalid_literal_length_code_msg:
-.string "invalid literal/length code"
-
-.align 4,0
-.L_invalid_distance_code_msg:
-.string "invalid distance code"
-
-.align 4,0
-.L_invalid_distance_too_far_msg:
-.string "invalid distance too far back"
-
-#if ! defined( NO_MMX )
-.align 4,0
-.L_mask: /* mask[N] = ( 1 << N ) - 1 */
-.long 0
-.long 1
-.long 3
-.long 7
-.long 15
-.long 31
-.long 63
-.long 127
-.long 255
-.long 511
-.long 1023
-.long 2047
-.long 4095
-.long 8191
-.long 16383
-.long 32767
-.long 65535
-.long 131071
-.long 262143
-.long 524287
-.long 1048575
-.long 2097151
-.long 4194303
-.long 8388607
-.long 16777215
-.long 33554431
-.long 67108863
-.long 134217727
-.long 268435455
-.long 536870911
-.long 1073741823
-.long 2147483647
-.long 4294967295
-#endif /* NO_MMX */
-
-.text
-
-/*
- * struct z_stream offsets, in zlib.h
- */
-#define next_in_strm 0 /* strm->next_in */
-#define avail_in_strm 4 /* strm->avail_in */
-#define next_out_strm 12 /* strm->next_out */
-#define avail_out_strm 16 /* strm->avail_out */
-#define msg_strm 24 /* strm->msg */
-#define state_strm 28 /* strm->state */
-
-/*
- * struct inflate_state offsets, in inflate.h
- */
-#define mode_state 0 /* state->mode */
-#define wsize_state 32 /* state->wsize */
-#define write_state 40 /* state->write */
-#define window_state 44 /* state->window */
-#define hold_state 48 /* state->hold */
-#define bits_state 52 /* state->bits */
-#define lencode_state 68 /* state->lencode */
-#define distcode_state 72 /* state->distcode */
-#define lenbits_state 76 /* state->lenbits */
-#define distbits_state 80 /* state->distbits */
-
-/*
- * inflate_fast's activation record
- */
-#define local_var_size 64 /* how much local space for vars */
-#define strm_sp 88 /* first arg: z_stream * (local_var_size + 24) */
-#define start_sp 92 /* second arg: unsigned int (local_var_size + 28) */
-
-/*
- * offsets for local vars on stack
- */
-#define out 60 /* unsigned char* */
-#define window 56 /* unsigned char* */
-#define wsize 52 /* unsigned int */
-#define write 48 /* unsigned int */
-#define in 44 /* unsigned char* */
-#define beg 40 /* unsigned char* */
-#define buf 28 /* char[ 12 ] */
-#define len 24 /* unsigned int */
-#define last 20 /* unsigned char* */
-#define end 16 /* unsigned char* */
-#define dcode 12 /* code* */
-#define lcode 8 /* code* */
-#define dmask 4 /* unsigned int */
-#define lmask 0 /* unsigned int */
-
-/*
- * typedef enum inflate_mode consts, in inflate.h
- */
-#define INFLATE_MODE_TYPE 11 /* state->mode flags enum-ed in inflate.h */
-#define INFLATE_MODE_BAD 26
-
-
-#if ! defined( USE_MMX ) && ! defined( NO_MMX )
-
-#define RUN_TIME_MMX
-
-#define CHECK_MMX 1
-#define DO_USE_MMX 2
-#define DONT_USE_MMX 3
-
-.globl inflate_fast_use_mmx
-
-.data
-
-.align 4,0
-inflate_fast_use_mmx: /* integer flag for run time control 1=check,2=mmx,3=no */
-.long CHECK_MMX
-
-#if defined( GAS_ELF )
-/* elf info */
-.type inflate_fast_use_mmx,@object
-.size inflate_fast_use_mmx,4
-#endif
-
-#endif /* RUN_TIME_MMX */
-
-#if defined( GAS_COFF )
-/* coff info: scl 2 = extern, type 32 = function */
-.def inflate_fast; .scl 2; .type 32; .endef
-#endif
-
-.text
-
-.align 32,0x90
-inflate_fast:
- pushl %edi
- pushl %esi
- pushl %ebp
- pushl %ebx
- pushf /* save eflags (strm_sp, state_sp assumes this is 32 bits) */
- subl $local_var_size, %esp
- cld
-
-#define strm_r %esi
-#define state_r %edi
-
- movl strm_sp(%esp), strm_r
- movl state_strm(strm_r), state_r
-
- /* in = strm->next_in;
- * out = strm->next_out;
- * last = in + strm->avail_in - 11;
- * beg = out - (start - strm->avail_out);
- * end = out + (strm->avail_out - 257);
- */
- movl avail_in_strm(strm_r), %edx
- movl next_in_strm(strm_r), %eax
-
- addl %eax, %edx /* avail_in += next_in */
- subl $11, %edx /* avail_in -= 11 */
-
- movl %eax, in(%esp)
- movl %edx, last(%esp)
-
- movl start_sp(%esp), %ebp
- movl avail_out_strm(strm_r), %ecx
- movl next_out_strm(strm_r), %ebx
-
- subl %ecx, %ebp /* start -= avail_out */
- negl %ebp /* start = -start */
- addl %ebx, %ebp /* start += next_out */
-
- subl $257, %ecx /* avail_out -= 257 */
- addl %ebx, %ecx /* avail_out += out */
-
- movl %ebx, out(%esp)
- movl %ebp, beg(%esp)
- movl %ecx, end(%esp)
-
- /* wsize = state->wsize;
- * write = state->write;
- * window = state->window;
- * hold = state->hold;
- * bits = state->bits;
- * lcode = state->lencode;
- * dcode = state->distcode;
- * lmask = ( 1 << state->lenbits ) - 1;
- * dmask = ( 1 << state->distbits ) - 1;
- */
-
- movl lencode_state(state_r), %eax
- movl distcode_state(state_r), %ecx
-
- movl %eax, lcode(%esp)
- movl %ecx, dcode(%esp)
-
- movl $1, %eax
- movl lenbits_state(state_r), %ecx
- shll %cl, %eax
- decl %eax
- movl %eax, lmask(%esp)
-
- movl $1, %eax
- movl distbits_state(state_r), %ecx
- shll %cl, %eax
- decl %eax
- movl %eax, dmask(%esp)
-
- movl wsize_state(state_r), %eax
- movl write_state(state_r), %ecx
- movl window_state(state_r), %edx
-
- movl %eax, wsize(%esp)
- movl %ecx, write(%esp)
- movl %edx, window(%esp)
-
- movl hold_state(state_r), %ebp
- movl bits_state(state_r), %ebx
-
-#undef strm_r
-#undef state_r
-
-#define in_r %esi
-#define from_r %esi
-#define out_r %edi
-
- movl in(%esp), in_r
- movl last(%esp), %ecx
- cmpl in_r, %ecx
- ja .L_align_long /* if in < last */
-
- addl $11, %ecx /* ecx = &in[ avail_in ] */
- subl in_r, %ecx /* ecx = avail_in */
- movl $12, %eax
- subl %ecx, %eax /* eax = 12 - avail_in */
- leal buf(%esp), %edi
- rep movsb /* memcpy( buf, in, avail_in ) */
- movl %eax, %ecx
- xorl %eax, %eax
- rep stosb /* memset( &buf[ avail_in ], 0, 12 - avail_in ) */
- leal buf(%esp), in_r /* in = buf */
- movl in_r, last(%esp) /* last = in, do just one iteration */
- jmp .L_is_aligned
-
- /* align in_r on long boundary */
-.L_align_long:
- testl $3, in_r
- jz .L_is_aligned
- xorl %eax, %eax
- movb (in_r), %al
- incl in_r
- movl %ebx, %ecx
- addl $8, %ebx
- shll %cl, %eax
- orl %eax, %ebp
- jmp .L_align_long
-
-.L_is_aligned:
- movl out(%esp), out_r
-
-#if defined( NO_MMX )
- jmp .L_do_loop
-#endif
-
-#if defined( USE_MMX )
- jmp .L_init_mmx
-#endif
-
-/*** Runtime MMX check ***/
-
-#if defined( RUN_TIME_MMX )
-.L_check_mmx:
- cmpl $DO_USE_MMX, inflate_fast_use_mmx
- je .L_init_mmx
- ja .L_do_loop /* > 2 */
-
- pushl %eax
- pushl %ebx
- pushl %ecx
- pushl %edx
- pushf
- movl (%esp), %eax /* copy eflags to eax */
- xorl $0x200000, (%esp) /* try toggling ID bit of eflags (bit 21)
- * to see if cpu supports cpuid...
- * ID bit method not supported by NexGen but
- * bios may load a cpuid instruction and
- * cpuid may be disabled on Cyrix 5-6x86 */
- popf
- pushf
- popl %edx /* copy new eflags to edx */
- xorl %eax, %edx /* test if ID bit is flipped */
- jz .L_dont_use_mmx /* not flipped if zero */
- xorl %eax, %eax
- cpuid
- cmpl $0x756e6547, %ebx /* check for GenuineIntel in ebx,ecx,edx */
- jne .L_dont_use_mmx
- cmpl $0x6c65746e, %ecx
- jne .L_dont_use_mmx
- cmpl $0x49656e69, %edx
- jne .L_dont_use_mmx
- movl $1, %eax
- cpuid /* get cpu features */
- shrl $8, %eax
- andl $15, %eax
- cmpl $6, %eax /* check for Pentium family, is 0xf for P4 */
- jne .L_dont_use_mmx
- testl $0x800000, %edx /* test if MMX feature is set (bit 23) */
- jnz .L_use_mmx
- jmp .L_dont_use_mmx
-.L_use_mmx:
- movl $DO_USE_MMX, inflate_fast_use_mmx
- jmp .L_check_mmx_pop
-.L_dont_use_mmx:
- movl $DONT_USE_MMX, inflate_fast_use_mmx
-.L_check_mmx_pop:
- popl %edx
- popl %ecx
- popl %ebx
- popl %eax
- jmp .L_check_mmx
-#endif
-
-
-/*** Non-MMX code ***/
-
-#if defined ( NO_MMX ) || defined( RUN_TIME_MMX )
-
-#define hold_r %ebp
-#define bits_r %bl
-#define bitslong_r %ebx
-
-.align 32,0x90
-.L_while_test:
- /* while (in < last && out < end)
- */
- cmpl out_r, end(%esp)
- jbe .L_break_loop /* if (out >= end) */
-
- cmpl in_r, last(%esp)
- jbe .L_break_loop
-
-.L_do_loop:
- /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
- *
- * do {
- * if (bits < 15) {
- * hold |= *((unsigned short *)in)++ << bits;
- * bits += 16
- * }
- * this = lcode[hold & lmask]
- */
- cmpb $15, bits_r
- ja .L_get_length_code /* if (15 < bits) */
-
- xorl %eax, %eax
- lodsw /* al = *(ushort *)in++ */
- movb bits_r, %cl /* cl = bits, needs it for shifting */
- addb $16, bits_r /* bits += 16 */
- shll %cl, %eax
- orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
-
-.L_get_length_code:
- movl lmask(%esp), %edx /* edx = lmask */
- movl lcode(%esp), %ecx /* ecx = lcode */
- andl hold_r, %edx /* edx &= hold */
- movl (%ecx,%edx,4), %eax /* eax = lcode[hold & lmask] */
-
-.L_dolen:
- /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
- *
- * dolen:
- * bits -= this.bits;
- * hold >>= this.bits
- */
- movb %ah, %cl /* cl = this.bits */
- subb %ah, bits_r /* bits -= this.bits */
- shrl %cl, hold_r /* hold >>= this.bits */
-
- /* check if op is a literal
- * if (op == 0) {
- * PUP(out) = this.val;
- * }
- */
- testb %al, %al
- jnz .L_test_for_length_base /* if (op != 0) 45.7% */
-
- shrl $16, %eax /* output this.val char */
- stosb
- jmp .L_while_test
-
-.L_test_for_length_base:
- /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = len
- *
- * else if (op & 16) {
- * len = this.val
- * op &= 15
- * if (op) {
- * if (op > bits) {
- * hold |= *((unsigned short *)in)++ << bits;
- * bits += 16
- * }
- * len += hold & mask[op];
- * bits -= op;
- * hold >>= op;
- * }
- */
-#define len_r %edx
- movl %eax, len_r /* len = this */
- shrl $16, len_r /* len = this.val */
- movb %al, %cl
-
- testb $16, %al
- jz .L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
- andb $15, %cl /* op &= 15 */
- jz .L_save_len /* if (!op) */
- cmpb %cl, bits_r
- jae .L_add_bits_to_len /* if (op <= bits) */
-
- movb %cl, %ch /* stash op in ch, freeing cl */
- xorl %eax, %eax
- lodsw /* al = *(ushort *)in++ */
- movb bits_r, %cl /* cl = bits, needs it for shifting */
- addb $16, bits_r /* bits += 16 */
- shll %cl, %eax
- orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
- movb %ch, %cl /* move op back to ecx */
-
-.L_add_bits_to_len:
- movl $1, %eax
- shll %cl, %eax
- decl %eax
- subb %cl, bits_r
- andl hold_r, %eax /* eax &= hold */
- shrl %cl, hold_r
- addl %eax, len_r /* len += hold & mask[op] */
-
-.L_save_len:
- movl len_r, len(%esp) /* save len */
-#undef len_r
-
-.L_decode_distance:
- /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = dist
- *
- * if (bits < 15) {
- * hold |= *((unsigned short *)in)++ << bits;
- * bits += 16
- * }
- * this = dcode[hold & dmask];
- * dodist:
- * bits -= this.bits;
- * hold >>= this.bits;
- * op = this.op;
- */
-
- cmpb $15, bits_r
- ja .L_get_distance_code /* if (15 < bits) */
-
- xorl %eax, %eax
- lodsw /* al = *(ushort *)in++ */
- movb bits_r, %cl /* cl = bits, needs it for shifting */
- addb $16, bits_r /* bits += 16 */
- shll %cl, %eax
- orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
-
-.L_get_distance_code:
- movl dmask(%esp), %edx /* edx = dmask */
- movl dcode(%esp), %ecx /* ecx = dcode */
- andl hold_r, %edx /* edx &= hold */
- movl (%ecx,%edx,4), %eax /* eax = dcode[hold & dmask] */
-
-#define dist_r %edx
-.L_dodist:
- movl %eax, dist_r /* dist = this */
- shrl $16, dist_r /* dist = this.val */
- movb %ah, %cl
- subb %ah, bits_r /* bits -= this.bits */
- shrl %cl, hold_r /* hold >>= this.bits */
-
- /* if (op & 16) {
- * dist = this.val
- * op &= 15
- * if (op > bits) {
- * hold |= *((unsigned short *)in)++ << bits;
- * bits += 16
- * }
- * dist += hold & mask[op];
- * bits -= op;
- * hold >>= op;
- */
- movb %al, %cl /* cl = this.op */
-
- testb $16, %al /* if ((op & 16) == 0) */
- jz .L_test_for_second_level_dist
- andb $15, %cl /* op &= 15 */
- jz .L_check_dist_one
- cmpb %cl, bits_r
- jae .L_add_bits_to_dist /* if (op <= bits) 97.6% */
-
- movb %cl, %ch /* stash op in ch, freeing cl */
- xorl %eax, %eax
- lodsw /* al = *(ushort *)in++ */
- movb bits_r, %cl /* cl = bits, needs it for shifting */
- addb $16, bits_r /* bits += 16 */
- shll %cl, %eax
- orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
- movb %ch, %cl /* move op back to ecx */
-
-.L_add_bits_to_dist:
- movl $1, %eax
- shll %cl, %eax
- decl %eax /* (1 << op) - 1 */
- subb %cl, bits_r
- andl hold_r, %eax /* eax &= hold */
- shrl %cl, hold_r
- addl %eax, dist_r /* dist += hold & ((1 << op) - 1) */
- jmp .L_check_window
-
-.L_check_window:
- /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
- * %ecx = nbytes
- *
- * nbytes = out - beg;
- * if (dist <= nbytes) {
- * from = out - dist;
- * do {
- * PUP(out) = PUP(from);
- * } while (--len > 0) {
- * }
- */
-
- movl in_r, in(%esp) /* save in so from can use it's reg */
- movl out_r, %eax
- subl beg(%esp), %eax /* nbytes = out - beg */
-
- cmpl dist_r, %eax
- jb .L_clip_window /* if (dist > nbytes) 4.2% */
-
- movl len(%esp), %ecx
- movl out_r, from_r
- subl dist_r, from_r /* from = out - dist */
-
- subl $3, %ecx
- movb (from_r), %al
- movb %al, (out_r)
- movb 1(from_r), %al
- movb 2(from_r), %dl
- addl $3, from_r
- movb %al, 1(out_r)
- movb %dl, 2(out_r)
- addl $3, out_r
- rep movsb
-
- movl in(%esp), in_r /* move in back to %esi, toss from */
- jmp .L_while_test
-
-.align 16,0x90
-.L_check_dist_one:
- cmpl $1, dist_r
- jne .L_check_window
- cmpl out_r, beg(%esp)
- je .L_check_window
-
- decl out_r
- movl len(%esp), %ecx
- movb (out_r), %al
- subl $3, %ecx
-
- movb %al, 1(out_r)
- movb %al, 2(out_r)
- movb %al, 3(out_r)
- addl $4, out_r
- rep stosb
-
- jmp .L_while_test
-
-.align 16,0x90
-.L_test_for_second_level_length:
- /* else if ((op & 64) == 0) {
- * this = lcode[this.val + (hold & mask[op])];
- * }
- */
- testb $64, %al
- jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */
-
- movl $1, %eax
- shll %cl, %eax
- decl %eax
- andl hold_r, %eax /* eax &= hold */
- addl %edx, %eax /* eax += this.val */
- movl lcode(%esp), %edx /* edx = lcode */
- movl (%edx,%eax,4), %eax /* eax = lcode[val + (hold&mask[op])] */
- jmp .L_dolen
-
-.align 16,0x90
-.L_test_for_second_level_dist:
- /* else if ((op & 64) == 0) {
- * this = dcode[this.val + (hold & mask[op])];
- * }
- */
- testb $64, %al
- jnz .L_invalid_distance_code /* if ((op & 64) != 0) */
-
- movl $1, %eax
- shll %cl, %eax
- decl %eax
- andl hold_r, %eax /* eax &= hold */
- addl %edx, %eax /* eax += this.val */
- movl dcode(%esp), %edx /* edx = dcode */
- movl (%edx,%eax,4), %eax /* eax = dcode[val + (hold&mask[op])] */
- jmp .L_dodist
-
-.align 16,0x90
-.L_clip_window:
- /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
- * %ecx = nbytes
- *
- * else {
- * if (dist > wsize) {
- * invalid distance
- * }
- * from = window;
- * nbytes = dist - nbytes;
- * if (write == 0) {
- * from += wsize - nbytes;
- */
-#define nbytes_r %ecx
- movl %eax, nbytes_r
- movl wsize(%esp), %eax /* prepare for dist compare */
- negl nbytes_r /* nbytes = -nbytes */
- movl window(%esp), from_r /* from = window */
-
- cmpl dist_r, %eax
- jb .L_invalid_distance_too_far /* if (dist > wsize) */
-
- addl dist_r, nbytes_r /* nbytes = dist - nbytes */
- cmpl $0, write(%esp)
- jne .L_wrap_around_window /* if (write != 0) */
-
- subl nbytes_r, %eax
- addl %eax, from_r /* from += wsize - nbytes */
-
- /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
- * %ecx = nbytes, %eax = len
- *
- * if (nbytes < len) {
- * len -= nbytes;
- * do {
- * PUP(out) = PUP(from);
- * } while (--nbytes);
- * from = out - dist;
- * }
- * }
- */
-#define len_r %eax
- movl len(%esp), len_r
- cmpl nbytes_r, len_r
- jbe .L_do_copy1 /* if (nbytes >= len) */
-
- subl nbytes_r, len_r /* len -= nbytes */
- rep movsb
- movl out_r, from_r
- subl dist_r, from_r /* from = out - dist */
- jmp .L_do_copy1
-
- cmpl nbytes_r, len_r
- jbe .L_do_copy1 /* if (nbytes >= len) */
-
- subl nbytes_r, len_r /* len -= nbytes */
- rep movsb
- movl out_r, from_r
- subl dist_r, from_r /* from = out - dist */
- jmp .L_do_copy1
-
-.L_wrap_around_window:
- /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
- * %ecx = nbytes, %eax = write, %eax = len
- *
- * else if (write < nbytes) {
- * from += wsize + write - nbytes;
- * nbytes -= write;
- * if (nbytes < len) {
- * len -= nbytes;
- * do {
- * PUP(out) = PUP(from);
- * } while (--nbytes);
- * from = window;
- * nbytes = write;
- * if (nbytes < len) {
- * len -= nbytes;
- * do {
- * PUP(out) = PUP(from);
- * } while(--nbytes);
- * from = out - dist;
- * }
- * }
- * }
- */
-#define write_r %eax
- movl write(%esp), write_r
- cmpl write_r, nbytes_r
- jbe .L_contiguous_in_window /* if (write >= nbytes) */
-
- addl wsize(%esp), from_r
- addl write_r, from_r
- subl nbytes_r, from_r /* from += wsize + write - nbytes */
- subl write_r, nbytes_r /* nbytes -= write */
-#undef write_r
-
- movl len(%esp), len_r
- cmpl nbytes_r, len_r
- jbe .L_do_copy1 /* if (nbytes >= len) */
-
- subl nbytes_r, len_r /* len -= nbytes */
- rep movsb
- movl window(%esp), from_r /* from = window */
- movl write(%esp), nbytes_r /* nbytes = write */
- cmpl nbytes_r, len_r
- jbe .L_do_copy1 /* if (nbytes >= len) */
-
- subl nbytes_r, len_r /* len -= nbytes */
- rep movsb
- movl out_r, from_r
- subl dist_r, from_r /* from = out - dist */
- jmp .L_do_copy1
-
-.L_contiguous_in_window:
- /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
- * %ecx = nbytes, %eax = write, %eax = len
- *
- * else {
- * from += write - nbytes;
- * if (nbytes < len) {
- * len -= nbytes;
- * do {
- * PUP(out) = PUP(from);
- * } while (--nbytes);
- * from = out - dist;
- * }
- * }
- */
-#define write_r %eax
- addl write_r, from_r
- subl nbytes_r, from_r /* from += write - nbytes */
-#undef write_r
-
- movl len(%esp), len_r
- cmpl nbytes_r, len_r
- jbe .L_do_copy1 /* if (nbytes >= len) */
-
- subl nbytes_r, len_r /* len -= nbytes */
- rep movsb
- movl out_r, from_r
- subl dist_r, from_r /* from = out - dist */
-
-.L_do_copy1:
- /* regs: %esi = from, %esi = in, %ebp = hold, %bl = bits, %edi = out
- * %eax = len
- *
- * while (len > 0) {
- * PUP(out) = PUP(from);
- * len--;
- * }
- * }
- * } while (in < last && out < end);
- */
-#undef nbytes_r
-#define in_r %esi
- movl len_r, %ecx
- rep movsb
-
- movl in(%esp), in_r /* move in back to %esi, toss from */
- jmp .L_while_test
-
-#undef len_r
-#undef dist_r
-
-#endif /* NO_MMX || RUN_TIME_MMX */
-
-
-/*** MMX code ***/
-
-#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
-
-.align 32,0x90
-.L_init_mmx:
- emms
-
-#undef bits_r
-#undef bitslong_r
-#define bitslong_r %ebp
-#define hold_mm %mm0
- movd %ebp, hold_mm
- movl %ebx, bitslong_r
-
-#define used_mm %mm1
-#define dmask2_mm %mm2
-#define lmask2_mm %mm3
-#define lmask_mm %mm4
-#define dmask_mm %mm5
-#define tmp_mm %mm6
-
- movd lmask(%esp), lmask_mm
- movq lmask_mm, lmask2_mm
- movd dmask(%esp), dmask_mm
- movq dmask_mm, dmask2_mm
- pxor used_mm, used_mm
- movl lcode(%esp), %ebx /* ebx = lcode */
- jmp .L_do_loop_mmx
-
-.align 32,0x90
-.L_while_test_mmx:
- /* while (in < last && out < end)
- */
- cmpl out_r, end(%esp)
- jbe .L_break_loop /* if (out >= end) */
-
- cmpl in_r, last(%esp)
- jbe .L_break_loop
-
-.L_do_loop_mmx:
- psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
-
- cmpl $32, bitslong_r
- ja .L_get_length_code_mmx /* if (32 < bits) */
-
- movd bitslong_r, tmp_mm
- movd (in_r), %mm7
- addl $4, in_r
- psllq tmp_mm, %mm7
- addl $32, bitslong_r
- por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */
-
-.L_get_length_code_mmx:
- pand hold_mm, lmask_mm
- movd lmask_mm, %eax
- movq lmask2_mm, lmask_mm
- movl (%ebx,%eax,4), %eax /* eax = lcode[hold & lmask] */
-
-.L_dolen_mmx:
- movzbl %ah, %ecx /* ecx = this.bits */
- movd %ecx, used_mm
- subl %ecx, bitslong_r /* bits -= this.bits */
-
- testb %al, %al
- jnz .L_test_for_length_base_mmx /* if (op != 0) 45.7% */
-
- shrl $16, %eax /* output this.val char */
- stosb
- jmp .L_while_test_mmx
-
-.L_test_for_length_base_mmx:
-#define len_r %edx
- movl %eax, len_r /* len = this */
- shrl $16, len_r /* len = this.val */
-
- testb $16, %al
- jz .L_test_for_second_level_length_mmx /* if ((op & 16) == 0) 8% */
- andl $15, %eax /* op &= 15 */
- jz .L_decode_distance_mmx /* if (!op) */
-
- psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
- movd %eax, used_mm
- movd hold_mm, %ecx
- subl %eax, bitslong_r
- andl .L_mask(,%eax,4), %ecx
- addl %ecx, len_r /* len += hold & mask[op] */
-
-.L_decode_distance_mmx:
- psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
-
- cmpl $32, bitslong_r
- ja .L_get_dist_code_mmx /* if (32 < bits) */
-
- movd bitslong_r, tmp_mm
- movd (in_r), %mm7
- addl $4, in_r
- psllq tmp_mm, %mm7
- addl $32, bitslong_r
- por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */
-
-.L_get_dist_code_mmx:
- movl dcode(%esp), %ebx /* ebx = dcode */
- pand hold_mm, dmask_mm
- movd dmask_mm, %eax
- movq dmask2_mm, dmask_mm
- movl (%ebx,%eax,4), %eax /* eax = dcode[hold & lmask] */
-
-.L_dodist_mmx:
-#define dist_r %ebx
- movzbl %ah, %ecx /* ecx = this.bits */
- movl %eax, dist_r
- shrl $16, dist_r /* dist = this.val */
- subl %ecx, bitslong_r /* bits -= this.bits */
- movd %ecx, used_mm
-
- testb $16, %al /* if ((op & 16) == 0) */
- jz .L_test_for_second_level_dist_mmx
- andl $15, %eax /* op &= 15 */
- jz .L_check_dist_one_mmx
-
-.L_add_bits_to_dist_mmx:
- psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
- movd %eax, used_mm /* save bit length of current op */
- movd hold_mm, %ecx /* get the next bits on input stream */
- subl %eax, bitslong_r /* bits -= op bits */
- andl .L_mask(,%eax,4), %ecx /* ecx = hold & mask[op] */
- addl %ecx, dist_r /* dist += hold & mask[op] */
-
-.L_check_window_mmx:
- movl in_r, in(%esp) /* save in so from can use it's reg */
- movl out_r, %eax
- subl beg(%esp), %eax /* nbytes = out - beg */
-
- cmpl dist_r, %eax
- jb .L_clip_window_mmx /* if (dist > nbytes) 4.2% */
-
- movl len_r, %ecx
- movl out_r, from_r
- subl dist_r, from_r /* from = out - dist */
-
- subl $3, %ecx
- movb (from_r), %al
- movb %al, (out_r)
- movb 1(from_r), %al
- movb 2(from_r), %dl
- addl $3, from_r
- movb %al, 1(out_r)
- movb %dl, 2(out_r)
- addl $3, out_r
- rep movsb
-
- movl in(%esp), in_r /* move in back to %esi, toss from */
- movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */
- jmp .L_while_test_mmx
-
-.align 16,0x90
-.L_check_dist_one_mmx:
- cmpl $1, dist_r
- jne .L_check_window_mmx
- cmpl out_r, beg(%esp)
- je .L_check_window_mmx
-
- decl out_r
- movl len_r, %ecx
- movb (out_r), %al
- subl $3, %ecx
-
- movb %al, 1(out_r)
- movb %al, 2(out_r)
- movb %al, 3(out_r)
- addl $4, out_r
- rep stosb
-
- movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */
- jmp .L_while_test_mmx
-
-.align 16,0x90
-.L_test_for_second_level_length_mmx:
- testb $64, %al
- jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */
-
- andl $15, %eax
- psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
- movd hold_mm, %ecx
- andl .L_mask(,%eax,4), %ecx
- addl len_r, %ecx
- movl (%ebx,%ecx,4), %eax /* eax = lcode[hold & lmask] */
- jmp .L_dolen_mmx
-
-.align 16,0x90
-.L_test_for_second_level_dist_mmx:
- testb $64, %al
- jnz .L_invalid_distance_code /* if ((op & 64) != 0) */
-
- andl $15, %eax
- psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
- movd hold_mm, %ecx
- andl .L_mask(,%eax,4), %ecx
- movl dcode(%esp), %eax /* ecx = dcode */
- addl dist_r, %ecx
- movl (%eax,%ecx,4), %eax /* eax = lcode[hold & lmask] */
- jmp .L_dodist_mmx
-
-.align 16,0x90
-.L_clip_window_mmx:
-#define nbytes_r %ecx
- movl %eax, nbytes_r
- movl wsize(%esp), %eax /* prepare for dist compare */
- negl nbytes_r /* nbytes = -nbytes */
- movl window(%esp), from_r /* from = window */
-
- cmpl dist_r, %eax
- jb .L_invalid_distance_too_far /* if (dist > wsize) */
-
- addl dist_r, nbytes_r /* nbytes = dist - nbytes */
- cmpl $0, write(%esp)
- jne .L_wrap_around_window_mmx /* if (write != 0) */
-
- subl nbytes_r, %eax
- addl %eax, from_r /* from += wsize - nbytes */
-
- cmpl nbytes_r, len_r
- jbe .L_do_copy1_mmx /* if (nbytes >= len) */
-
- subl nbytes_r, len_r /* len -= nbytes */
- rep movsb
- movl out_r, from_r
- subl dist_r, from_r /* from = out - dist */
- jmp .L_do_copy1_mmx
-
- cmpl nbytes_r, len_r
- jbe .L_do_copy1_mmx /* if (nbytes >= len) */
-
- subl nbytes_r, len_r /* len -= nbytes */
- rep movsb
- movl out_r, from_r
- subl dist_r, from_r /* from = out - dist */
- jmp .L_do_copy1_mmx
-
-.L_wrap_around_window_mmx:
-#define write_r %eax
- movl write(%esp), write_r
- cmpl write_r, nbytes_r
- jbe .L_contiguous_in_window_mmx /* if (write >= nbytes) */
-
- addl wsize(%esp), from_r
- addl write_r, from_r
- subl nbytes_r, from_r /* from += wsize + write - nbytes */
- subl write_r, nbytes_r /* nbytes -= write */
-#undef write_r
-
- cmpl nbytes_r, len_r
- jbe .L_do_copy1_mmx /* if (nbytes >= len) */
-
- subl nbytes_r, len_r /* len -= nbytes */
- rep movsb
- movl window(%esp), from_r /* from = window */
- movl write(%esp), nbytes_r /* nbytes = write */
- cmpl nbytes_r, len_r
- jbe .L_do_copy1_mmx /* if (nbytes >= len) */
-
- subl nbytes_r, len_r /* len -= nbytes */
- rep movsb
- movl out_r, from_r
- subl dist_r, from_r /* from = out - dist */
- jmp .L_do_copy1_mmx
-
-.L_contiguous_in_window_mmx:
-#define write_r %eax
- addl write_r, from_r
- subl nbytes_r, from_r /* from += write - nbytes */
-#undef write_r
-
- cmpl nbytes_r, len_r
- jbe .L_do_copy1_mmx /* if (nbytes >= len) */
-
- subl nbytes_r, len_r /* len -= nbytes */
- rep movsb
- movl out_r, from_r
- subl dist_r, from_r /* from = out - dist */
-
-.L_do_copy1_mmx:
-#undef nbytes_r
-#define in_r %esi
- movl len_r, %ecx
- rep movsb
-
- movl in(%esp), in_r /* move in back to %esi, toss from */
- movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */
- jmp .L_while_test_mmx
-
-#undef hold_r
-#undef bitslong_r
-
-#endif /* USE_MMX || RUN_TIME_MMX */
-
-
-/*** USE_MMX, NO_MMX, and RUNTIME_MMX from here on ***/
-
-.L_invalid_distance_code:
- /* else {
- * strm->msg = "invalid distance code";
- * state->mode = BAD;
- * }
- */
- movl $.L_invalid_distance_code_msg, %ecx
- movl $INFLATE_MODE_BAD, %edx
- jmp .L_update_stream_state
-
-.L_test_for_end_of_block:
- /* else if (op & 32) {
- * state->mode = TYPE;
- * break;
- * }
- */
- testb $32, %al
- jz .L_invalid_literal_length_code /* if ((op & 32) == 0) */
-
- movl $0, %ecx
- movl $INFLATE_MODE_TYPE, %edx
- jmp .L_update_stream_state
-
-.L_invalid_literal_length_code:
- /* else {
- * strm->msg = "invalid literal/length code";
- * state->mode = BAD;
- * }
- */
- movl $.L_invalid_literal_length_code_msg, %ecx
- movl $INFLATE_MODE_BAD, %edx
- jmp .L_update_stream_state
-
-.L_invalid_distance_too_far:
- /* strm->msg = "invalid distance too far back";
- * state->mode = BAD;
- */
- movl in(%esp), in_r /* from_r has in's reg, put in back */
- movl $.L_invalid_distance_too_far_msg, %ecx
- movl $INFLATE_MODE_BAD, %edx
- jmp .L_update_stream_state
-
-.L_update_stream_state:
- /* set strm->msg = %ecx, strm->state->mode = %edx */
- movl strm_sp(%esp), %eax
- testl %ecx, %ecx /* if (msg != NULL) */
- jz .L_skip_msg
- movl %ecx, msg_strm(%eax) /* strm->msg = msg */
-.L_skip_msg:
- movl state_strm(%eax), %eax /* state = strm->state */
- movl %edx, mode_state(%eax) /* state->mode = edx (BAD | TYPE) */
- jmp .L_break_loop
-
-.align 32,0x90
-.L_break_loop:
-
-/*
- * Regs:
- *
- * bits = %ebp when mmx, and in %ebx when non-mmx
- * hold = %hold_mm when mmx, and in %ebp when non-mmx
- * in = %esi
- * out = %edi
- */
-
-#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
-
-#if defined( RUN_TIME_MMX )
-
- cmpl $DO_USE_MMX, inflate_fast_use_mmx
- jne .L_update_next_in
-
-#endif /* RUN_TIME_MMX */
-
- movl %ebp, %ebx
-
-.L_update_next_in:
-
-#endif
-
-#define strm_r %eax
-#define state_r %edx
-
- /* len = bits >> 3;
- * in -= len;
- * bits -= len << 3;
- * hold &= (1U << bits) - 1;
- * state->hold = hold;
- * state->bits = bits;
- * strm->next_in = in;
- * strm->next_out = out;
- */
- movl strm_sp(%esp), strm_r
- movl %ebx, %ecx
- movl state_strm(strm_r), state_r
- shrl $3, %ecx
- subl %ecx, in_r
- shll $3, %ecx
- subl %ecx, %ebx
- movl out_r, next_out_strm(strm_r)
- movl %ebx, bits_state(state_r)
- movl %ebx, %ecx
-
- leal buf(%esp), %ebx
- cmpl %ebx, last(%esp)
- jne .L_buf_not_used /* if buf != last */
-
- subl %ebx, in_r /* in -= buf */
- movl next_in_strm(strm_r), %ebx
- movl %ebx, last(%esp) /* last = strm->next_in */
- addl %ebx, in_r /* in += strm->next_in */
- movl avail_in_strm(strm_r), %ebx
- subl $11, %ebx
- addl %ebx, last(%esp) /* last = &strm->next_in[ avail_in - 11 ] */
-
-.L_buf_not_used:
- movl in_r, next_in_strm(strm_r)
-
- movl $1, %ebx
- shll %cl, %ebx
- decl %ebx
-
-#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
-
-#if defined( RUN_TIME_MMX )
-
- cmpl $DO_USE_MMX, inflate_fast_use_mmx
- jne .L_update_hold
-
-#endif /* RUN_TIME_MMX */
-
- psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
- movd hold_mm, %ebp
-
- emms
-
-.L_update_hold:
-
-#endif /* USE_MMX || RUN_TIME_MMX */
-
- andl %ebx, %ebp
- movl %ebp, hold_state(state_r)
-
-#define last_r %ebx
-
- /* strm->avail_in = in < last ? 11 + (last - in) : 11 - (in - last) */
- movl last(%esp), last_r
- cmpl in_r, last_r
- jbe .L_last_is_smaller /* if (in >= last) */
-
- subl in_r, last_r /* last -= in */
- addl $11, last_r /* last += 11 */
- movl last_r, avail_in_strm(strm_r)
- jmp .L_fixup_out
-.L_last_is_smaller:
- subl last_r, in_r /* in -= last */
- negl in_r /* in = -in */
- addl $11, in_r /* in += 11 */
- movl in_r, avail_in_strm(strm_r)
-
-#undef last_r
-#define end_r %ebx
-
-.L_fixup_out:
- /* strm->avail_out = out < end ? 257 + (end - out) : 257 - (out - end)*/
- movl end(%esp), end_r
- cmpl out_r, end_r
- jbe .L_end_is_smaller /* if (out >= end) */
-
- subl out_r, end_r /* end -= out */
- addl $257, end_r /* end += 257 */
- movl end_r, avail_out_strm(strm_r)
- jmp .L_done
-.L_end_is_smaller:
- subl end_r, out_r /* out -= end */
- negl out_r /* out = -out */
- addl $257, out_r /* out += 257 */
- movl out_r, avail_out_strm(strm_r)
-
-#undef end_r
-#undef strm_r
-#undef state_r
-
-.L_done:
- addl $local_var_size, %esp
- popf
- popl %ebx
- popl %ebp
- popl %esi
- popl %edi
- ret
-
-#if defined( GAS_ELF )
-/* elf info */
-.type inflate_fast,@function
-.size inflate_fast,.-inflate_fast
-#endif
diff --git a/cpukit/zlib/contrib/iostream/test.cpp b/cpukit/zlib/contrib/iostream/test.cpp
deleted file mode 100644
index 7d265b3b5c..0000000000
--- a/cpukit/zlib/contrib/iostream/test.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-
-#include "zfstream.h"
-
-int main() {
-
- // Construct a stream object with this filebuffer. Anything sent
- // to this stream will go to standard out.
- gzofstream os( 1, ios::out );
-
- // This text is getting compressed and sent to stdout.
- // To prove this, run 'test | zcat'.
- os << "Hello, Mommy" << endl;
-
- os << setcompressionlevel( Z_NO_COMPRESSION );
- os << "hello, hello, hi, ho!" << endl;
-
- setcompressionlevel( os, Z_DEFAULT_COMPRESSION )
- << "I'm compressing again" << endl;
-
- os.close();
-
- return 0;
-
-}
diff --git a/cpukit/zlib/contrib/iostream/zfstream.cpp b/cpukit/zlib/contrib/iostream/zfstream.cpp
deleted file mode 100644
index d0cd85faaf..0000000000
--- a/cpukit/zlib/contrib/iostream/zfstream.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-
-#include "zfstream.h"
-
-gzfilebuf::gzfilebuf() :
- file(NULL),
- mode(0),
- own_file_descriptor(0)
-{ }
-
-gzfilebuf::~gzfilebuf() {
-
- sync();
- if ( own_file_descriptor )
- close();
-
-}
-
-gzfilebuf *gzfilebuf::open( const char *name,
- int io_mode ) {
-
- if ( is_open() )
- return NULL;
-
- char char_mode[10];
- char *p = char_mode;
-
- if ( io_mode & ios::in ) {
- mode = ios::in;
- *p++ = 'r';
- } else if ( io_mode & ios::app ) {
- mode = ios::app;
- *p++ = 'a';
- } else {
- mode = ios::out;
- *p++ = 'w';
- }
-
- if ( io_mode & ios::binary ) {
- mode |= ios::binary;
- *p++ = 'b';
- }
-
- // Hard code the compression level
- if ( io_mode & (ios::out|ios::app )) {
- *p++ = '9';
- }
-
- // Put the end-of-string indicator
- *p = '\0';
-
- if ( (file = gzopen(name, char_mode)) == NULL )
- return NULL;
-
- own_file_descriptor = 1;
-
- return this;
-
-}
-
-gzfilebuf *gzfilebuf::attach( int file_descriptor,
- int io_mode ) {
-
- if ( is_open() )
- return NULL;
-
- char char_mode[10];
- char *p = char_mode;
-
- if ( io_mode & ios::in ) {
- mode = ios::in;
- *p++ = 'r';
- } else if ( io_mode & ios::app ) {
- mode = ios::app;
- *p++ = 'a';
- } else {
- mode = ios::out;
- *p++ = 'w';
- }
-
- if ( io_mode & ios::binary ) {
- mode |= ios::binary;
- *p++ = 'b';
- }
-
- // Hard code the compression level
- if ( io_mode & (ios::out|ios::app )) {
- *p++ = '9';
- }
-
- // Put the end-of-string indicator
- *p = '\0';
-
- if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
- return NULL;
-
- own_file_descriptor = 0;
-
- return this;
-
-}
-
-gzfilebuf *gzfilebuf::close() {
-
- if ( is_open() ) {
-
- sync();
- gzclose( file );
- file = NULL;
-
- }
-
- return this;
-
-}
-
-int gzfilebuf::setcompressionlevel( int comp_level ) {
-
- return gzsetparams(file, comp_level, -2);
-
-}
-
-int gzfilebuf::setcompressionstrategy( int comp_strategy ) {
-
- return gzsetparams(file, -2, comp_strategy);
-
-}
-
-
-streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
-
- return streampos(EOF);
-
-}
-
-int gzfilebuf::underflow() {
-
- // If the file hasn't been opened for reading, error.
- if ( !is_open() || !(mode & ios::in) )
- return EOF;
-
- // if a buffer doesn't exists, allocate one.
- if ( !base() ) {
-
- if ( (allocate()) == EOF )
- return EOF;
- setp(0,0);
-
- } else {
-
- if ( in_avail() )
- return (unsigned char) *gptr();
-
- if ( out_waiting() ) {
- if ( flushbuf() == EOF )
- return EOF;
- }
-
- }
-
- // Attempt to fill the buffer.
-
- int result = fillbuf();
- if ( result == EOF ) {
- // disable get area
- setg(0,0,0);
- return EOF;
- }
-
- return (unsigned char) *gptr();
-
-}
-
-int gzfilebuf::overflow( int c ) {
-
- if ( !is_open() || !(mode & ios::out) )
- return EOF;
-
- if ( !base() ) {
- if ( allocate() == EOF )
- return EOF;
- setg(0,0,0);
- } else {
- if (in_avail()) {
- return EOF;
- }
- if (out_waiting()) {
- if (flushbuf() == EOF)
- return EOF;
- }
- }
-
- int bl = blen();
- setp( base(), base() + bl);
-
- if ( c != EOF ) {
-
- *pptr() = c;
- pbump(1);
-
- }
-
- return 0;
-
-}
-
-int gzfilebuf::sync() {
-
- if ( !is_open() )
- return EOF;
-
- if ( out_waiting() )
- return flushbuf();
-
- return 0;
-
-}
-
-int gzfilebuf::flushbuf() {
-
- int n;
- char *q;
-
- q = pbase();
- n = pptr() - q;
-
- if ( gzwrite( file, q, n) < n )
- return EOF;
-
- setp(0,0);
-
- return 0;
-
-}
-
-int gzfilebuf::fillbuf() {
-
- int required;
- char *p;
-
- p = base();
-
- required = blen();
-
- int t = gzread( file, p, required );
-
- if ( t <= 0) return EOF;
-
- setg( base(), base(), base()+t);
-
- return t;
-
-}
-
-gzfilestream_common::gzfilestream_common() :
- ios( gzfilestream_common::rdbuf() )
-{ }
-
-gzfilestream_common::~gzfilestream_common()
-{ }
-
-void gzfilestream_common::attach( int fd, int io_mode ) {
-
- if ( !buffer.attach( fd, io_mode) )
- clear( ios::failbit | ios::badbit );
- else
- clear();
-
-}
-
-void gzfilestream_common::open( const char *name, int io_mode ) {
-
- if ( !buffer.open( name, io_mode ) )
- clear( ios::failbit | ios::badbit );
- else
- clear();
-
-}
-
-void gzfilestream_common::close() {
-
- if ( !buffer.close() )
- clear( ios::failbit | ios::badbit );
-
-}
-
-gzfilebuf *gzfilestream_common::rdbuf()
-{
- return &buffer;
-}
-
-gzifstream::gzifstream() :
- ios( gzfilestream_common::rdbuf() )
-{
- clear( ios::badbit );
-}
-
-gzifstream::gzifstream( const char *name, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
-{
- gzfilestream_common::open( name, io_mode );
-}
-
-gzifstream::gzifstream( int fd, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
-{
- gzfilestream_common::attach( fd, io_mode );
-}
-
-gzifstream::~gzifstream() { }
-
-gzofstream::gzofstream() :
- ios( gzfilestream_common::rdbuf() )
-{
- clear( ios::badbit );
-}
-
-gzofstream::gzofstream( const char *name, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
-{
- gzfilestream_common::open( name, io_mode );
-}
-
-gzofstream::gzofstream( int fd, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
-{
- gzfilestream_common::attach( fd, io_mode );
-}
-
-gzofstream::~gzofstream() { }
diff --git a/cpukit/zlib/contrib/iostream/zfstream.h b/cpukit/zlib/contrib/iostream/zfstream.h
deleted file mode 100644
index ed79098a3a..0000000000
--- a/cpukit/zlib/contrib/iostream/zfstream.h
+++ /dev/null
@@ -1,128 +0,0 @@
-
-#ifndef zfstream_h
-#define zfstream_h
-
-#include <fstream.h>
-#include "zlib.h"
-
-class gzfilebuf : public streambuf {
-
-public:
-
- gzfilebuf( );
- virtual ~gzfilebuf();
-
- gzfilebuf *open( const char *name, int io_mode );
- gzfilebuf *attach( int file_descriptor, int io_mode );
- gzfilebuf *close();
-
- int setcompressionlevel( int comp_level );
- int setcompressionstrategy( int comp_strategy );
-
- inline int is_open() const { return (file !=NULL); }
-
- virtual streampos seekoff( streamoff, ios::seek_dir, int );
-
- virtual int sync();
-
-protected:
-
- virtual int underflow();
- virtual int overflow( int = EOF );
-
-private:
-
- gzFile file;
- short mode;
- short own_file_descriptor;
-
- int flushbuf();
- int fillbuf();
-
-};
-
-class gzfilestream_common : virtual public ios {
-
- friend class gzifstream;
- friend class gzofstream;
- friend gzofstream &setcompressionlevel( gzofstream &, int );
- friend gzofstream &setcompressionstrategy( gzofstream &, int );
-
-public:
- virtual ~gzfilestream_common();
-
- void attach( int fd, int io_mode );
- void open( const char *name, int io_mode );
- void close();
-
-protected:
- gzfilestream_common();
-
-private:
- gzfilebuf *rdbuf();
-
- gzfilebuf buffer;
-
-};
-
-class gzifstream : public gzfilestream_common, public istream {
-
-public:
-
- gzifstream();
- gzifstream( const char *name, int io_mode = ios::in );
- gzifstream( int fd, int io_mode = ios::in );
-
- virtual ~gzifstream();
-
-};
-
-class gzofstream : public gzfilestream_common, public ostream {
-
-public:
-
- gzofstream();
- gzofstream( const char *name, int io_mode = ios::out );
- gzofstream( int fd, int io_mode = ios::out );
-
- virtual ~gzofstream();
-
-};
-
-template<class T> class gzomanip {
- friend gzofstream &operator<<(gzofstream &, const gzomanip<T> &);
-public:
- gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { }
-private:
- gzofstream &(*func)(gzofstream &, T);
- T val;
-};
-
-template<class T> gzofstream &operator<<(gzofstream &s, const gzomanip<T> &m)
-{
- return (*m.func)(s, m.val);
-}
-
-inline gzofstream &setcompressionlevel( gzofstream &s, int l )
-{
- (s.rdbuf())->setcompressionlevel(l);
- return s;
-}
-
-inline gzofstream &setcompressionstrategy( gzofstream &s, int l )
-{
- (s.rdbuf())->setcompressionstrategy(l);
- return s;
-}
-
-inline gzomanip<int> setcompressionlevel(int l)
-{
- return gzomanip<int>(&setcompressionlevel,l);
-}
-
-inline gzomanip<int> setcompressionstrategy(int l)
-{
- return gzomanip<int>(&setcompressionstrategy,l);
-}
-
-#endif
diff --git a/cpukit/zlib/contrib/iostream2/zstream.h b/cpukit/zlib/contrib/iostream2/zstream.h
deleted file mode 100644
index 861ef2bad9..0000000000
--- a/cpukit/zlib/contrib/iostream2/zstream.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- *
- * Copyright (c) 1997
- * Christian Michelsen Research AS
- * Advanced Computing
- * Fantoftvegen 38, 5036 BERGEN, Norway
- * http://www.cmr.no
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Christian Michelsen Research AS makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-
-#ifndef ZSTREAM__H
-#define ZSTREAM__H
-
-/*
- * zstream.h - C++ interface to the 'zlib' general purpose compression library
- * $Id$
- */
-
-#include <strstream.h>
-#include <string.h>
-#include <stdio.h>
-#include "zlib.h"
-
-#if defined(_WIN32)
-# include <fcntl.h>
-# include <io.h>
-# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
-#else
-# define SET_BINARY_MODE(file)
-#endif
-
-class zstringlen {
-public:
- zstringlen(class izstream&);
- zstringlen(class ozstream&, const char*);
- size_t value() const { return val.word; }
-private:
- struct Val { unsigned char byte; size_t word; } val;
-};
-
-// ----------------------------- izstream -----------------------------
-
-class izstream
-{
- public:
- izstream() : m_fp(0) {}
- izstream(FILE* fp) : m_fp(0) { open(fp); }
- izstream(const char* name) : m_fp(0) { open(name); }
- ~izstream() { close(); }
-
- /* Opens a gzip (.gz) file for reading.
- * open() can be used to read a file which is not in gzip format;
- * in this case read() will directly read from the file without
- * decompression. errno can be checked to distinguish two error
- * cases (if errno is zero, the zlib error is Z_MEM_ERROR).
- */
- void open(const char* name) {
- if (m_fp) close();
- m_fp = ::gzopen(name, "rb");
- }
-
- void open(FILE* fp) {
- SET_BINARY_MODE(fp);
- if (m_fp) close();
- m_fp = ::gzdopen(fileno(fp), "rb");
- }
-
- /* Flushes all pending input if necessary, closes the compressed file
- * and deallocates all the (de)compression state. The return value is
- * the zlib error number (see function error() below).
- */
- int close() {
- int r = ::gzclose(m_fp);
- m_fp = 0; return r;
- }
-
- /* Binary read the given number of bytes from the compressed file.
- */
- int read(void* buf, size_t len) {
- return ::gzread(m_fp, buf, len);
- }
-
- /* Returns the error message for the last error which occurred on the
- * given compressed file. errnum is set to zlib error number. If an
- * error occurred in the file system and not in the compression library,
- * errnum is set to Z_ERRNO and the application may consult errno
- * to get the exact error code.
- */
- const char* error(int* errnum) {
- return ::gzerror(m_fp, errnum);
- }
-
- gzFile fp() { return m_fp; }
-
- private:
- gzFile m_fp;
-};
-
-/*
- * Binary read the given (array of) object(s) from the compressed file.
- * If the input file was not in gzip format, read() copies the objects number
- * of bytes into the buffer.
- * returns the number of uncompressed bytes actually read
- * (0 for end of file, -1 for error).
- */
-template <class T, class Items>
-inline int read(izstream& zs, T* x, Items items) {
- return ::gzread(zs.fp(), x, items*sizeof(T));
-}
-
-/*
- * Binary input with the '>' operator.
- */
-template <class T>
-inline izstream& operator>(izstream& zs, T& x) {
- ::gzread(zs.fp(), &x, sizeof(T));
- return zs;
-}
-
-
-inline zstringlen::zstringlen(izstream& zs) {
- zs > val.byte;
- if (val.byte == 255) zs > val.word;
- else val.word = val.byte;
-}
-
-/*
- * Read length of string + the string with the '>' operator.
- */
-inline izstream& operator>(izstream& zs, char* x) {
- zstringlen len(zs);
- ::gzread(zs.fp(), x, len.value());
- x[len.value()] = '\0';
- return zs;
-}
-
-inline char* read_string(izstream& zs) {
- zstringlen len(zs);
- char* x = new char[len.value()+1];
- ::gzread(zs.fp(), x, len.value());
- x[len.value()] = '\0';
- return x;
-}
-
-// ----------------------------- ozstream -----------------------------
-
-class ozstream
-{
- public:
- ozstream() : m_fp(0), m_os(0) {
- }
- ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION)
- : m_fp(0), m_os(0) {
- open(fp, level);
- }
- ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION)
- : m_fp(0), m_os(0) {
- open(name, level);
- }
- ~ozstream() {
- close();
- }
-
- /* Opens a gzip (.gz) file for writing.
- * The compression level parameter should be in 0..9
- * errno can be checked to distinguish two error cases
- * (if errno is zero, the zlib error is Z_MEM_ERROR).
- */
- void open(const char* name, int level = Z_DEFAULT_COMPRESSION) {
- char mode[4] = "wb\0";
- if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
- if (m_fp) close();
- m_fp = ::gzopen(name, mode);
- }
-
- /* open from a FILE pointer.
- */
- void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) {
- SET_BINARY_MODE(fp);
- char mode[4] = "wb\0";
- if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
- if (m_fp) close();
- m_fp = ::gzdopen(fileno(fp), mode);
- }
-
- /* Flushes all pending output if necessary, closes the compressed file
- * and deallocates all the (de)compression state. The return value is
- * the zlib error number (see function error() below).
- */
- int close() {
- if (m_os) {
- ::gzwrite(m_fp, m_os->str(), m_os->pcount());
- delete[] m_os->str(); delete m_os; m_os = 0;
- }
- int r = ::gzclose(m_fp); m_fp = 0; return r;
- }
-
- /* Binary write the given number of bytes into the compressed file.
- */
- int write(const void* buf, size_t len) {
- return ::gzwrite(m_fp, (voidp) buf, len);
- }
-
- /* Flushes all pending output into the compressed file. The parameter
- * _flush is as in the deflate() function. The return value is the zlib
- * error number (see function gzerror below). flush() returns Z_OK if
- * the flush_ parameter is Z_FINISH and all output could be flushed.
- * flush() should be called only when strictly necessary because it can
- * degrade compression.
- */
- int flush(int _flush) {
- os_flush();
- return ::gzflush(m_fp, _flush);
- }
-
- /* Returns the error message for the last error which occurred on the
- * given compressed file. errnum is set to zlib error number. If an
- * error occurred in the file system and not in the compression library,
- * errnum is set to Z_ERRNO and the application may consult errno
- * to get the exact error code.
- */
- const char* error(int* errnum) {
- return ::gzerror(m_fp, errnum);
- }
-
- gzFile fp() { return m_fp; }
-
- ostream& os() {
- if (m_os == 0) m_os = new ostrstream;
- return *m_os;
- }
-
- void os_flush() {
- if (m_os && m_os->pcount()>0) {
- ostrstream* oss = new ostrstream;
- oss->fill(m_os->fill());
- oss->flags(m_os->flags());
- oss->precision(m_os->precision());
- oss->width(m_os->width());
- ::gzwrite(m_fp, m_os->str(), m_os->pcount());
- delete[] m_os->str(); delete m_os; m_os = oss;
- }
- }
-
- private:
- gzFile m_fp;
- ostrstream* m_os;
-};
-
-/*
- * Binary write the given (array of) object(s) into the compressed file.
- * returns the number of uncompressed bytes actually written
- * (0 in case of error).
- */
-template <class T, class Items>
-inline int write(ozstream& zs, const T* x, Items items) {
- return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T));
-}
-
-/*
- * Binary output with the '<' operator.
- */
-template <class T>
-inline ozstream& operator<(ozstream& zs, const T& x) {
- ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));
- return zs;
-}
-
-inline zstringlen::zstringlen(ozstream& zs, const char* x) {
- val.byte = 255; val.word = ::strlen(x);
- if (val.word < 255) zs < (val.byte = val.word);
- else zs < val;
-}
-
-/*
- * Write length of string + the string with the '<' operator.
- */
-inline ozstream& operator<(ozstream& zs, const char* x) {
- zstringlen len(zs, x);
- ::gzwrite(zs.fp(), (voidp) x, len.value());
- return zs;
-}
-
-#ifdef _MSC_VER
-inline ozstream& operator<(ozstream& zs, char* const& x) {
- return zs < (const char*) x;
-}
-#endif
-
-/*
- * Ascii write with the << operator;
- */
-template <class T>
-inline ostream& operator<<(ozstream& zs, const T& x) {
- zs.os_flush();
- return zs.os() << x;
-}
-
-#endif
diff --git a/cpukit/zlib/contrib/iostream2/zstream_test.cpp b/cpukit/zlib/contrib/iostream2/zstream_test.cpp
deleted file mode 100644
index 6273f62d62..0000000000
--- a/cpukit/zlib/contrib/iostream2/zstream_test.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#include "zstream.h"
-#include <math.h>
-#include <stdlib.h>
-#include <iomanip.h>
-
-void main() {
- char h[256] = "Hello";
- char* g = "Goodbye";
- ozstream out("temp.gz");
- out < "This works well" < h < g;
- out.close();
-
- izstream in("temp.gz"); // read it back
- char *x = read_string(in), *y = new char[256], z[256];
- in > y > z;
- in.close();
- cout << x << endl << y << endl << z << endl;
-
- out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results
- out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl;
- out << z << endl << y << endl << x << endl;
- out << 1.1234567890123456789 << endl;
-
- delete[] x; delete[] y;
-}
diff --git a/cpukit/zlib/contrib/iostream3/README b/cpukit/zlib/contrib/iostream3/README
deleted file mode 100644
index f7b319ab91..0000000000
--- a/cpukit/zlib/contrib/iostream3/README
+++ /dev/null
@@ -1,35 +0,0 @@
-These classes provide a C++ stream interface to the zlib library. It allows you
-to do things like:
-
- gzofstream outf("blah.gz");
- outf << "These go into the gzip file " << 123 << endl;
-
-It does this by deriving a specialized stream buffer for gzipped files, which is
-the way Stroustrup would have done it. :->
-
-The gzifstream and gzofstream classes were originally written by Kevin Ruland
-and made available in the zlib contrib/iostream directory. The older version still
-compiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of
-this version.
-
-The new classes are as standard-compliant as possible, closely following the
-approach of the standard library's fstream classes. It compiles under gcc versions
-3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard
-library naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs
-from the previous one in the following respects:
-- added showmanyc
-- added setbuf, with support for unbuffered output via setbuf(0,0)
-- a few bug fixes of stream behavior
-- gzipped output file opened with default compression level instead of maximum level
-- setcompressionlevel()/strategy() members replaced by single setcompression()
-
-The code is provided "as is", with the permission to use, copy, modify, distribute
-and sell it for any purpose without fee.
-
-Ludwig Schwardt
-<schwardt@sun.ac.za>
-
-DSP Lab
-Electrical & Electronic Engineering Department
-University of Stellenbosch
-South Africa
diff --git a/cpukit/zlib/contrib/iostream3/TODO b/cpukit/zlib/contrib/iostream3/TODO
deleted file mode 100644
index 7032f97be0..0000000000
--- a/cpukit/zlib/contrib/iostream3/TODO
+++ /dev/null
@@ -1,17 +0,0 @@
-Possible upgrades to gzfilebuf:
-
-- The ability to do putback (e.g. putbackfail)
-
-- The ability to seek (zlib supports this, but could be slow/tricky)
-
-- Simultaneous read/write access (does it make sense?)
-
-- Support for ios_base::ate open mode
-
-- Locale support?
-
-- Check public interface to see which calls give problems
- (due to dependence on library internals)
-
-- Override operator<<(ostream&, gzfilebuf*) to allow direct copying
- of stream buffer to stream ( i.e. os << is.rdbuf(); )
diff --git a/cpukit/zlib/contrib/iostream3/test.cc b/cpukit/zlib/contrib/iostream3/test.cc
deleted file mode 100644
index 94235334f2..0000000000
--- a/cpukit/zlib/contrib/iostream3/test.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Test program for gzifstream and gzofstream
- *
- * by Ludwig Schwardt <schwardt@sun.ac.za>
- * original version by Kevin Ruland <kevin@rodin.wustl.edu>
- */
-
-#include "zfstream.h"
-#include <iostream> // for cout
-
-int main() {
-
- gzofstream outf;
- gzifstream inf;
- char buf[80];
-
- outf.open("test1.txt.gz");
- outf << "The quick brown fox sidestepped the lazy canine\n"
- << 1.3 << "\nPlan " << 9 << std::endl;
- outf.close();
- std::cout << "Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\n"
- << "The quick brown fox sidestepped the lazy canine\n"
- << 1.3 << "\nPlan " << 9 << std::endl;
-
- std::cout << "\nReading 'test1.txt.gz' (buffered) produces:\n";
- inf.open("test1.txt.gz");
- while (inf.getline(buf,80,'\n')) {
- std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
- }
- inf.close();
-
- outf.rdbuf()->pubsetbuf(0,0);
- outf.open("test2.txt.gz");
- outf << setcompression(Z_NO_COMPRESSION)
- << "The quick brown fox sidestepped the lazy canine\n"
- << 1.3 << "\nPlan " << 9 << std::endl;
- outf.close();
- std::cout << "\nWrote the same message to 'test2.txt.gz' in uncompressed form";
-
- std::cout << "\nReading 'test2.txt.gz' (unbuffered) produces:\n";
- inf.rdbuf()->pubsetbuf(0,0);
- inf.open("test2.txt.gz");
- while (inf.getline(buf,80,'\n')) {
- std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
- }
- inf.close();
-
- return 0;
-
-}
diff --git a/cpukit/zlib/contrib/iostream3/zfstream.cc b/cpukit/zlib/contrib/iostream3/zfstream.cc
deleted file mode 100644
index 94eb933444..0000000000
--- a/cpukit/zlib/contrib/iostream3/zfstream.cc
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * A C++ I/O streams interface to the zlib gz* functions
- *
- * by Ludwig Schwardt <schwardt@sun.ac.za>
- * original version by Kevin Ruland <kevin@rodin.wustl.edu>
- *
- * This version is standard-compliant and compatible with gcc 3.x.
- */
-
-#include "zfstream.h"
-#include <cstring> // for strcpy, strcat, strlen (mode strings)
-#include <cstdio> // for BUFSIZ
-
-// Internal buffer sizes (default and "unbuffered" versions)
-#define BIGBUFSIZE BUFSIZ
-#define SMALLBUFSIZE 1
-
-/*****************************************************************************/
-
-// Default constructor
-gzfilebuf::gzfilebuf()
-: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false),
- buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true)
-{
- // No buffers to start with
- this->disable_buffer();
-}
-
-// Destructor
-gzfilebuf::~gzfilebuf()
-{
- // Sync output buffer and close only if responsible for file
- // (i.e. attached streams should be left open at this stage)
- this->sync();
- if (own_fd)
- this->close();
- // Make sure internal buffer is deallocated
- this->disable_buffer();
-}
-
-// Set compression level and strategy
-int
-gzfilebuf::setcompression(int comp_level,
- int comp_strategy)
-{
- return gzsetparams(file, comp_level, comp_strategy);
-}
-
-// Open gzipped file
-gzfilebuf*
-gzfilebuf::open(const char *name,
- std::ios_base::openmode mode)
-{
- // Fail if file already open
- if (this->is_open())
- return NULL;
- // Don't support simultaneous read/write access (yet)
- if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
- return NULL;
-
- // Build mode string for gzopen and check it [27.8.1.3.2]
- char char_mode[6] = "\0\0\0\0\0";
- if (!this->open_mode(mode, char_mode))
- return NULL;
-
- // Attempt to open file
- if ((file = gzopen(name, char_mode)) == NULL)
- return NULL;
-
- // On success, allocate internal buffer and set flags
- this->enable_buffer();
- io_mode = mode;
- own_fd = true;
- return this;
-}
-
-// Attach to gzipped file
-gzfilebuf*
-gzfilebuf::attach(int fd,
- std::ios_base::openmode mode)
-{
- // Fail if file already open
- if (this->is_open())
- return NULL;
- // Don't support simultaneous read/write access (yet)
- if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
- return NULL;
-
- // Build mode string for gzdopen and check it [27.8.1.3.2]
- char char_mode[6] = "\0\0\0\0\0";
- if (!this->open_mode(mode, char_mode))
- return NULL;
-
- // Attempt to attach to file
- if ((file = gzdopen(fd, char_mode)) == NULL)
- return NULL;
-
- // On success, allocate internal buffer and set flags
- this->enable_buffer();
- io_mode = mode;
- own_fd = false;
- return this;
-}
-
-// Close gzipped file
-gzfilebuf*
-gzfilebuf::close()
-{
- // Fail immediately if no file is open
- if (!this->is_open())
- return NULL;
- // Assume success
- gzfilebuf* retval = this;
- // Attempt to sync and close gzipped file
- if (this->sync() == -1)
- retval = NULL;
- if (gzclose(file) < 0)
- retval = NULL;
- // File is now gone anyway (postcondition [27.8.1.3.8])
- file = NULL;
- own_fd = false;
- // Destroy internal buffer if it exists
- this->disable_buffer();
- return retval;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-// Convert int open mode to mode string
-bool
-gzfilebuf::open_mode(std::ios_base::openmode mode,
- char* c_mode) const
-{
- bool testb = mode & std::ios_base::binary;
- bool testi = mode & std::ios_base::in;
- bool testo = mode & std::ios_base::out;
- bool testt = mode & std::ios_base::trunc;
- bool testa = mode & std::ios_base::app;
-
- // Check for valid flag combinations - see [27.8.1.3.2] (Table 92)
- // Original zfstream hardcoded the compression level to maximum here...
- // Double the time for less than 1% size improvement seems
- // excessive though - keeping it at the default level
- // To change back, just append "9" to the next three mode strings
- if (!testi && testo && !testt && !testa)
- strcpy(c_mode, "w");
- if (!testi && testo && !testt && testa)
- strcpy(c_mode, "a");
- if (!testi && testo && testt && !testa)
- strcpy(c_mode, "w");
- if (testi && !testo && !testt && !testa)
- strcpy(c_mode, "r");
- // No read/write mode yet
-// if (testi && testo && !testt && !testa)
-// strcpy(c_mode, "r+");
-// if (testi && testo && testt && !testa)
-// strcpy(c_mode, "w+");
-
- // Mode string should be empty for invalid combination of flags
- if (strlen(c_mode) == 0)
- return false;
- if (testb)
- strcat(c_mode, "b");
- return true;
-}
-
-// Determine number of characters in internal get buffer
-std::streamsize
-gzfilebuf::showmanyc()
-{
- // Calls to underflow will fail if file not opened for reading
- if (!this->is_open() || !(io_mode & std::ios_base::in))
- return -1;
- // Make sure get area is in use
- if (this->gptr() && (this->gptr() < this->egptr()))
- return std::streamsize(this->egptr() - this->gptr());
- else
- return 0;
-}
-
-// Fill get area from gzipped file
-gzfilebuf::int_type
-gzfilebuf::underflow()
-{
- // If something is left in the get area by chance, return it
- // (this shouldn't normally happen, as underflow is only supposed
- // to be called when gptr >= egptr, but it serves as error check)
- if (this->gptr() && (this->gptr() < this->egptr()))
- return traits_type::to_int_type(*(this->gptr()));
-
- // If the file hasn't been opened for reading, produce error
- if (!this->is_open() || !(io_mode & std::ios_base::in))
- return traits_type::eof();
-
- // Attempt to fill internal buffer from gzipped file
- // (buffer must be guaranteed to exist...)
- int bytes_read = gzread(file, buffer, buffer_size);
- // Indicates error or EOF
- if (bytes_read <= 0)
- {
- // Reset get area
- this->setg(buffer, buffer, buffer);
- return traits_type::eof();
- }
- // Make all bytes read from file available as get area
- this->setg(buffer, buffer, buffer + bytes_read);
-
- // Return next character in get area
- return traits_type::to_int_type(*(this->gptr()));
-}
-
-// Write put area to gzipped file
-gzfilebuf::int_type
-gzfilebuf::overflow(int_type c)
-{
- // Determine whether put area is in use
- if (this->pbase())
- {
- // Double-check pointer range
- if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
- return traits_type::eof();
- // Add extra character to buffer if not EOF
- if (!traits_type::eq_int_type(c, traits_type::eof()))
- {
- *(this->pptr()) = traits_type::to_char_type(c);
- this->pbump(1);
- }
- // Number of characters to write to file
- int bytes_to_write = this->pptr() - this->pbase();
- // Overflow doesn't fail if nothing is to be written
- if (bytes_to_write > 0)
- {
- // If the file hasn't been opened for writing, produce error
- if (!this->is_open() || !(io_mode & std::ios_base::out))
- return traits_type::eof();
- // If gzipped file won't accept all bytes written to it, fail
- if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write)
- return traits_type::eof();
- // Reset next pointer to point to pbase on success
- this->pbump(-bytes_to_write);
- }
- }
- // Write extra character to file if not EOF
- else if (!traits_type::eq_int_type(c, traits_type::eof()))
- {
- // If the file hasn't been opened for writing, produce error
- if (!this->is_open() || !(io_mode & std::ios_base::out))
- return traits_type::eof();
- // Impromptu char buffer (allows "unbuffered" output)
- char_type last_char = traits_type::to_char_type(c);
- // If gzipped file won't accept this character, fail
- if (gzwrite(file, &last_char, 1) != 1)
- return traits_type::eof();
- }
-
- // If you got here, you have succeeded (even if c was EOF)
- // The return value should therefore be non-EOF
- if (traits_type::eq_int_type(c, traits_type::eof()))
- return traits_type::not_eof(c);
- else
- return c;
-}
-
-// Assign new buffer
-std::streambuf*
-gzfilebuf::setbuf(char_type* p,
- std::streamsize n)
-{
- // First make sure stuff is sync'ed, for safety
- if (this->sync() == -1)
- return NULL;
- // If buffering is turned off on purpose via setbuf(0,0), still allocate one...
- // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at
- // least a buffer of size 1 (very inefficient though, therefore make it bigger?)
- // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)
- if (!p || !n)
- {
- // Replace existing buffer (if any) with small internal buffer
- this->disable_buffer();
- buffer = NULL;
- buffer_size = 0;
- own_buffer = true;
- this->enable_buffer();
- }
- else
- {
- // Replace existing buffer (if any) with external buffer
- this->disable_buffer();
- buffer = p;
- buffer_size = n;
- own_buffer = false;
- this->enable_buffer();
- }
- return this;
-}
-
-// Write put area to gzipped file (i.e. ensures that put area is empty)
-int
-gzfilebuf::sync()
-{
- return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-// Allocate internal buffer
-void
-gzfilebuf::enable_buffer()
-{
- // If internal buffer required, allocate one
- if (own_buffer && !buffer)
- {
- // Check for buffered vs. "unbuffered"
- if (buffer_size > 0)
- {
- // Allocate internal buffer
- buffer = new char_type[buffer_size];
- // Get area starts empty and will be expanded by underflow as need arises
- this->setg(buffer, buffer, buffer);
- // Setup entire internal buffer as put area.
- // The one-past-end pointer actually points to the last element of the buffer,
- // so that overflow(c) can safely add the extra character c to the sequence.
- // These pointers remain in place for the duration of the buffer
- this->setp(buffer, buffer + buffer_size - 1);
- }
- else
- {
- // Even in "unbuffered" case, (small?) get buffer is still required
- buffer_size = SMALLBUFSIZE;
- buffer = new char_type[buffer_size];
- this->setg(buffer, buffer, buffer);
- // "Unbuffered" means no put buffer
- this->setp(0, 0);
- }
- }
- else
- {
- // If buffer already allocated, reset buffer pointers just to make sure no
- // stale chars are lying around
- this->setg(buffer, buffer, buffer);
- this->setp(buffer, buffer + buffer_size - 1);
- }
-}
-
-// Destroy internal buffer
-void
-gzfilebuf::disable_buffer()
-{
- // If internal buffer exists, deallocate it
- if (own_buffer && buffer)
- {
- // Preserve unbuffered status by zeroing size
- if (!this->pbase())
- buffer_size = 0;
- delete[] buffer;
- buffer = NULL;
- this->setg(0, 0, 0);
- this->setp(0, 0);
- }
- else
- {
- // Reset buffer pointers to initial state if external buffer exists
- this->setg(buffer, buffer, buffer);
- if (buffer)
- this->setp(buffer, buffer + buffer_size - 1);
- else
- this->setp(0, 0);
- }
-}
-
-/*****************************************************************************/
-
-// Default constructor initializes stream buffer
-gzifstream::gzifstream()
-: std::istream(NULL), sb()
-{ this->init(&sb); }
-
-// Initialize stream buffer and open file
-gzifstream::gzifstream(const char* name,
- std::ios_base::openmode mode)
-: std::istream(NULL), sb()
-{
- this->init(&sb);
- this->open(name, mode);
-}
-
-// Initialize stream buffer and attach to file
-gzifstream::gzifstream(int fd,
- std::ios_base::openmode mode)
-: std::istream(NULL), sb()
-{
- this->init(&sb);
- this->attach(fd, mode);
-}
-
-// Open file and go into fail() state if unsuccessful
-void
-gzifstream::open(const char* name,
- std::ios_base::openmode mode)
-{
- if (!sb.open(name, mode | std::ios_base::in))
- this->setstate(std::ios_base::failbit);
- else
- this->clear();
-}
-
-// Attach to file and go into fail() state if unsuccessful
-void
-gzifstream::attach(int fd,
- std::ios_base::openmode mode)
-{
- if (!sb.attach(fd, mode | std::ios_base::in))
- this->setstate(std::ios_base::failbit);
- else
- this->clear();
-}
-
-// Close file
-void
-gzifstream::close()
-{
- if (!sb.close())
- this->setstate(std::ios_base::failbit);
-}
-
-/*****************************************************************************/
-
-// Default constructor initializes stream buffer
-gzofstream::gzofstream()
-: std::ostream(NULL), sb()
-{ this->init(&sb); }
-
-// Initialize stream buffer and open file
-gzofstream::gzofstream(const char* name,
- std::ios_base::openmode mode)
-: std::ostream(NULL), sb()
-{
- this->init(&sb);
- this->open(name, mode);
-}
-
-// Initialize stream buffer and attach to file
-gzofstream::gzofstream(int fd,
- std::ios_base::openmode mode)
-: std::ostream(NULL), sb()
-{
- this->init(&sb);
- this->attach(fd, mode);
-}
-
-// Open file and go into fail() state if unsuccessful
-void
-gzofstream::open(const char* name,
- std::ios_base::openmode mode)
-{
- if (!sb.open(name, mode | std::ios_base::out))
- this->setstate(std::ios_base::failbit);
- else
- this->clear();
-}
-
-// Attach to file and go into fail() state if unsuccessful
-void
-gzofstream::attach(int fd,
- std::ios_base::openmode mode)
-{
- if (!sb.attach(fd, mode | std::ios_base::out))
- this->setstate(std::ios_base::failbit);
- else
- this->clear();
-}
-
-// Close file
-void
-gzofstream::close()
-{
- if (!sb.close())
- this->setstate(std::ios_base::failbit);
-}
diff --git a/cpukit/zlib/contrib/iostream3/zfstream.h b/cpukit/zlib/contrib/iostream3/zfstream.h
deleted file mode 100644
index 8574479ae1..0000000000
--- a/cpukit/zlib/contrib/iostream3/zfstream.h
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * A C++ I/O streams interface to the zlib gz* functions
- *
- * by Ludwig Schwardt <schwardt@sun.ac.za>
- * original version by Kevin Ruland <kevin@rodin.wustl.edu>
- *
- * This version is standard-compliant and compatible with gcc 3.x.
- */
-
-#ifndef ZFSTREAM_H
-#define ZFSTREAM_H
-
-#include <istream> // not iostream, since we don't need cin/cout
-#include <ostream>
-#include "zlib.h"
-
-/*****************************************************************************/
-
-/**
- * @brief Gzipped file stream buffer class.
- *
- * This class implements basic_filebuf for gzipped files. It doesn't yet support
- * seeking (allowed by zlib but slow/limited), putback and read/write access
- * (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
- * file streambuf.
-*/
-class gzfilebuf : public std::streambuf
-{
-public:
- // Default constructor.
- gzfilebuf();
-
- // Destructor.
- virtual
- ~gzfilebuf();
-
- /**
- * @brief Set compression level and strategy on the fly.
- * @param comp_level Compression level (see zlib.h for allowed values)
- * @param comp_strategy Compression strategy (see zlib.h for allowed values)
- * @return Z_OK on success, Z_STREAM_ERROR otherwise.
- *
- * Unfortunately, these parameters cannot be modified separately, as the
- * previous zfstream version assumed. Since the strategy is seldom changed,
- * it can default and setcompression(level) then becomes like the old
- * setcompressionlevel(level).
- */
- int
- setcompression(int comp_level,
- int comp_strategy = Z_DEFAULT_STRATEGY);
-
- /**
- * @brief Check if file is open.
- * @return True if file is open.
- */
- bool
- is_open() const { return (file != NULL); }
-
- /**
- * @brief Open gzipped file.
- * @param name File name.
- * @param mode Open mode flags.
- * @return @c this on success, NULL on failure.
- */
- gzfilebuf*
- open(const char* name,
- std::ios_base::openmode mode);
-
- /**
- * @brief Attach to already open gzipped file.
- * @param fd File descriptor.
- * @param mode Open mode flags.
- * @return @c this on success, NULL on failure.
- */
- gzfilebuf*
- attach(int fd,
- std::ios_base::openmode mode);
-
- /**
- * @brief Close gzipped file.
- * @return @c this on success, NULL on failure.
- */
- gzfilebuf*
- close();
-
-protected:
- /**
- * @brief Convert ios open mode int to mode string used by zlib.
- * @return True if valid mode flag combination.
- */
- bool
- open_mode(std::ios_base::openmode mode,
- char* c_mode) const;
-
- /**
- * @brief Number of characters available in stream buffer.
- * @return Number of characters.
- *
- * This indicates number of characters in get area of stream buffer.
- * These characters can be read without accessing the gzipped file.
- */
- virtual std::streamsize
- showmanyc();
-
- /**
- * @brief Fill get area from gzipped file.
- * @return First character in get area on success, EOF on error.
- *
- * This actually reads characters from gzipped file to stream
- * buffer. Always buffered.
- */
- virtual int_type
- underflow();
-
- /**
- * @brief Write put area to gzipped file.
- * @param c Extra character to add to buffer contents.
- * @return Non-EOF on success, EOF on error.
- *
- * This actually writes characters in stream buffer to
- * gzipped file. With unbuffered output this is done one
- * character at a time.
- */
- virtual int_type
- overflow(int_type c = traits_type::eof());
-
- /**
- * @brief Installs external stream buffer.
- * @param p Pointer to char buffer.
- * @param n Size of external buffer.
- * @return @c this on success, NULL on failure.
- *
- * Call setbuf(0,0) to enable unbuffered output.
- */
- virtual std::streambuf*
- setbuf(char_type* p,
- std::streamsize n);
-
- /**
- * @brief Flush stream buffer to file.
- * @return 0 on success, -1 on error.
- *
- * This calls underflow(EOF) to do the job.
- */
- virtual int
- sync();
-
-//
-// Some future enhancements
-//
-// virtual int_type uflow();
-// virtual int_type pbackfail(int_type c = traits_type::eof());
-// virtual pos_type
-// seekoff(off_type off,
-// std::ios_base::seekdir way,
-// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
-// virtual pos_type
-// seekpos(pos_type sp,
-// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
-
-private:
- /**
- * @brief Allocate internal buffer.
- *
- * This function is safe to call multiple times. It will ensure
- * that a proper internal buffer exists if it is required. If the
- * buffer already exists or is external, the buffer pointers will be
- * reset to their original state.
- */
- void
- enable_buffer();
-
- /**
- * @brief Destroy internal buffer.
- *
- * This function is safe to call multiple times. It will ensure
- * that the internal buffer is deallocated if it exists. In any
- * case, it will also reset the buffer pointers.
- */
- void
- disable_buffer();
-
- /**
- * Underlying file pointer.
- */
- gzFile file;
-
- /**
- * Mode in which file was opened.
- */
- std::ios_base::openmode io_mode;
-
- /**
- * @brief True if this object owns file descriptor.
- *
- * This makes the class responsible for closing the file
- * upon destruction.
- */
- bool own_fd;
-
- /**
- * @brief Stream buffer.
- *
- * For simplicity this remains allocated on the free store for the
- * entire life span of the gzfilebuf object, unless replaced by setbuf.
- */
- char_type* buffer;
-
- /**
- * @brief Stream buffer size.
- *
- * Defaults to system default buffer size (typically 8192 bytes).
- * Modified by setbuf.
- */
- std::streamsize buffer_size;
-
- /**
- * @brief True if this object owns stream buffer.
- *
- * This makes the class responsible for deleting the buffer
- * upon destruction.
- */
- bool own_buffer;
-};
-
-/*****************************************************************************/
-
-/**
- * @brief Gzipped file input stream class.
- *
- * This class implements ifstream for gzipped files. Seeking and putback
- * is not supported yet.
-*/
-class gzifstream : public std::istream
-{
-public:
- // Default constructor
- gzifstream();
-
- /**
- * @brief Construct stream on gzipped file to be opened.
- * @param name File name.
- * @param mode Open mode flags (forced to contain ios::in).
- */
- explicit
- gzifstream(const char* name,
- std::ios_base::openmode mode = std::ios_base::in);
-
- /**
- * @brief Construct stream on already open gzipped file.
- * @param fd File descriptor.
- * @param mode Open mode flags (forced to contain ios::in).
- */
- explicit
- gzifstream(int fd,
- std::ios_base::openmode mode = std::ios_base::in);
-
- /**
- * Obtain underlying stream buffer.
- */
- gzfilebuf*
- rdbuf() const
- { return const_cast<gzfilebuf*>(&sb); }
-
- /**
- * @brief Check if file is open.
- * @return True if file is open.
- */
- bool
- is_open() { return sb.is_open(); }
-
- /**
- * @brief Open gzipped file.
- * @param name File name.
- * @param mode Open mode flags (forced to contain ios::in).
- *
- * Stream will be in state good() if file opens successfully;
- * otherwise in state fail(). This differs from the behavior of
- * ifstream, which never sets the state to good() and therefore
- * won't allow you to reuse the stream for a second file unless
- * you manually clear() the state. The choice is a matter of
- * convenience.
- */
- void
- open(const char* name,
- std::ios_base::openmode mode = std::ios_base::in);
-
- /**
- * @brief Attach to already open gzipped file.
- * @param fd File descriptor.
- * @param mode Open mode flags (forced to contain ios::in).
- *
- * Stream will be in state good() if attach succeeded; otherwise
- * in state fail().
- */
- void
- attach(int fd,
- std::ios_base::openmode mode = std::ios_base::in);
-
- /**
- * @brief Close gzipped file.
- *
- * Stream will be in state fail() if close failed.
- */
- void
- close();
-
-private:
- /**
- * Underlying stream buffer.
- */
- gzfilebuf sb;
-};
-
-/*****************************************************************************/
-
-/**
- * @brief Gzipped file output stream class.
- *
- * This class implements ofstream for gzipped files. Seeking and putback
- * is not supported yet.
-*/
-class gzofstream : public std::ostream
-{
-public:
- // Default constructor
- gzofstream();
-
- /**
- * @brief Construct stream on gzipped file to be opened.
- * @param name File name.
- * @param mode Open mode flags (forced to contain ios::out).
- */
- explicit
- gzofstream(const char* name,
- std::ios_base::openmode mode = std::ios_base::out);
-
- /**
- * @brief Construct stream on already open gzipped file.
- * @param fd File descriptor.
- * @param mode Open mode flags (forced to contain ios::out).
- */
- explicit
- gzofstream(int fd,
- std::ios_base::openmode mode = std::ios_base::out);
-
- /**
- * Obtain underlying stream buffer.
- */
- gzfilebuf*
- rdbuf() const
- { return const_cast<gzfilebuf*>(&sb); }
-
- /**
- * @brief Check if file is open.
- * @return True if file is open.
- */
- bool
- is_open() { return sb.is_open(); }
-
- /**
- * @brief Open gzipped file.
- * @param name File name.
- * @param mode Open mode flags (forced to contain ios::out).
- *
- * Stream will be in state good() if file opens successfully;
- * otherwise in state fail(). This differs from the behavior of
- * ofstream, which never sets the state to good() and therefore
- * won't allow you to reuse the stream for a second file unless
- * you manually clear() the state. The choice is a matter of
- * convenience.
- */
- void
- open(const char* name,
- std::ios_base::openmode mode = std::ios_base::out);
-
- /**
- * @brief Attach to already open gzipped file.
- * @param fd File descriptor.
- * @param mode Open mode flags (forced to contain ios::out).
- *
- * Stream will be in state good() if attach succeeded; otherwise
- * in state fail().
- */
- void
- attach(int fd,
- std::ios_base::openmode mode = std::ios_base::out);
-
- /**
- * @brief Close gzipped file.
- *
- * Stream will be in state fail() if close failed.
- */
- void
- close();
-
-private:
- /**
- * Underlying stream buffer.
- */
- gzfilebuf sb;
-};
-
-/*****************************************************************************/
-
-/**
- * @brief Gzipped file output stream manipulator class.
- *
- * This class defines a two-argument manipulator for gzofstream. It is used
- * as base for the setcompression(int,int) manipulator.
-*/
-template<typename T1, typename T2>
- class gzomanip2
- {
- public:
- // Allows insertor to peek at internals
- template <typename Ta, typename Tb>
- friend gzofstream&
- operator<<(gzofstream&,
- const gzomanip2<Ta,Tb>&);
-
- // Constructor
- gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
- T1 v1,
- T2 v2);
- private:
- // Underlying manipulator function
- gzofstream&
- (*func)(gzofstream&, T1, T2);
-
- // Arguments for manipulator function
- T1 val1;
- T2 val2;
- };
-
-/*****************************************************************************/
-
-// Manipulator function thunks through to stream buffer
-inline gzofstream&
-setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
-{
- (gzs.rdbuf())->setcompression(l, s);
- return gzs;
-}
-
-// Manipulator constructor stores arguments
-template<typename T1, typename T2>
- inline
- gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
- T1 v1,
- T2 v2)
- : func(f), val1(v1), val2(v2)
- { }
-
-// Insertor applies underlying manipulator function to stream
-template<typename T1, typename T2>
- inline gzofstream&
- operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
- { return (*m.func)(s, m.val1, m.val2); }
-
-// Insert this onto stream to simplify setting of compression level
-inline gzomanip2<int,int>
-setcompression(int l, int s = Z_DEFAULT_STRATEGY)
-{ return gzomanip2<int,int>(&setcompression, l, s); }
-
-#endif // ZFSTREAM_H
diff --git a/cpukit/zlib/contrib/masm686/match.asm b/cpukit/zlib/contrib/masm686/match.asm
deleted file mode 100644
index 2287804d44..0000000000
--- a/cpukit/zlib/contrib/masm686/match.asm
+++ /dev/null
@@ -1,408 +0,0 @@
-
-; match.asm -- Pentium-Pro optimized version of longest_match()
-;
-; Updated for zlib 1.1.3 and converted to MASM 6.1x
-; Copyright (C) 2000 Dan Higdon <hdan@kinesoft.com>
-; and Chuck Walbourn <chuckw@kinesoft.com>
-; Corrections by Cosmin Truta <cosmint@cs.ubbcluj.ro>
-;
-; This is free software; you can redistribute it and/or modify it
-; under the terms of the GNU General Public License.
-
-; Based on match.S
-; Written for zlib 1.1.2
-; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
-
- .686P
- .MODEL FLAT
-
-;===========================================================================
-; EQUATES
-;===========================================================================
-
-MAX_MATCH EQU 258
-MIN_MATCH EQU 3
-MIN_LOOKAHEAD EQU (MAX_MATCH + MIN_MATCH + 1)
-MAX_MATCH_8 EQU ((MAX_MATCH + 7) AND (NOT 7))
-
-;===========================================================================
-; STRUCTURES
-;===========================================================================
-
-; This STRUCT assumes a 4-byte alignment
-
-DEFLATE_STATE STRUCT
-ds_strm dd ?
-ds_status dd ?
-ds_pending_buf dd ?
-ds_pending_buf_size dd ?
-ds_pending_out dd ?
-ds_pending dd ?
-ds_wrap dd ?
-ds_data_type db ?
-ds_method db ?
- db ? ; padding
- db ? ; padding
-ds_last_flush dd ?
-ds_w_size dd ? ; used
-ds_w_bits dd ?
-ds_w_mask dd ? ; used
-ds_window dd ? ; used
-ds_window_size dd ?
-ds_prev dd ? ; used
-ds_head dd ?
-ds_ins_h dd ?
-ds_hash_size dd ?
-ds_hash_bits dd ?
-ds_hash_mask dd ?
-ds_hash_shift dd ?
-ds_block_start dd ?
-ds_match_length dd ? ; used
-ds_prev_match dd ? ; used
-ds_match_available dd ?
-ds_strstart dd ? ; used
-ds_match_start dd ? ; used
-ds_lookahead dd ? ; used
-ds_prev_length dd ? ; used
-ds_max_chain_length dd ? ; used
-ds_max_laxy_match dd ?
-ds_level dd ?
-ds_strategy dd ?
-ds_good_match dd ? ; used
-ds_nice_match dd ? ; used
-
-; Don't need anymore of the struct for match
-DEFLATE_STATE ENDS
-
-;===========================================================================
-; CODE
-;===========================================================================
-_TEXT SEGMENT
-
-;---------------------------------------------------------------------------
-; match_init
-;---------------------------------------------------------------------------
- ALIGN 4
-PUBLIC _match_init
-_match_init PROC
- ; no initialization needed
- ret
-_match_init ENDP
-
-;---------------------------------------------------------------------------
-; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
-;---------------------------------------------------------------------------
- ALIGN 4
-
-PUBLIC _longest_match
-_longest_match PROC
-
-; Since this code uses EBP for a scratch register, the stack frame must
-; be manually constructed and referenced relative to the ESP register.
-
-; Stack image
-; Variables
-chainlenwmask = 0 ; high word: current chain len
- ; low word: s->wmask
-window = 4 ; local copy of s->window
-windowbestlen = 8 ; s->window + bestlen
-scanend = 12 ; last two bytes of string
-scanstart = 16 ; first two bytes of string
-scanalign = 20 ; dword-misalignment of string
-nicematch = 24 ; a good enough match size
-bestlen = 28 ; size of best match so far
-scan = 32 ; ptr to string wanting match
-varsize = 36 ; number of bytes (also offset to last saved register)
-
-; Saved Registers (actually pushed into place)
-ebx_save = 36
-edi_save = 40
-esi_save = 44
-ebp_save = 48
-
-; Parameters
-retaddr = 52
-deflatestate = 56
-curmatch = 60
-
-; Save registers that the compiler may be using
- push ebp
- push edi
- push esi
- push ebx
-
-; Allocate local variable space
- sub esp,varsize
-
-; Retrieve the function arguments. ecx will hold cur_match
-; throughout the entire function. edx will hold the pointer to the
-; deflate_state structure during the function's setup (before
-; entering the main loop).
-
- mov edx, [esp+deflatestate]
-ASSUME edx:PTR DEFLATE_STATE
-
- mov ecx, [esp+curmatch]
-
-; uInt wmask = s->w_mask;
-; unsigned chain_length = s->max_chain_length;
-; if (s->prev_length >= s->good_match) {
-; chain_length >>= 2;
-; }
-
- mov eax, [edx].ds_prev_length
- mov ebx, [edx].ds_good_match
- cmp eax, ebx
- mov eax, [edx].ds_w_mask
- mov ebx, [edx].ds_max_chain_length
- jl SHORT LastMatchGood
- shr ebx, 2
-LastMatchGood:
-
-; chainlen is decremented once beforehand so that the function can
-; use the sign flag instead of the zero flag for the exit test.
-; It is then shifted into the high word, to make room for the wmask
-; value, which it will always accompany.
-
- dec ebx
- shl ebx, 16
- or ebx, eax
- mov [esp+chainlenwmask], ebx
-
-; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- mov eax, [edx].ds_nice_match
- mov ebx, [edx].ds_lookahead
- cmp ebx, eax
- jl SHORT LookaheadLess
- mov ebx, eax
-LookaheadLess:
- mov [esp+nicematch], ebx
-
-;/* register Bytef *scan = s->window + s->strstart; */
-
- mov esi, [edx].ds_window
- mov [esp+window], esi
- mov ebp, [edx].ds_strstart
- lea edi, [esi+ebp]
- mov [esp+scan],edi
-
-;/* Determine how many bytes the scan ptr is off from being */
-;/* dword-aligned. */
-
- mov eax, edi
- neg eax
- and eax, 3
- mov [esp+scanalign], eax
-
-;/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
-;/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
-
- mov eax, [edx].ds_w_size
- sub eax, MIN_LOOKAHEAD
- sub ebp, eax
- jg SHORT LimitPositive
- xor ebp, ebp
-LimitPositive:
-
-;/* int best_len = s->prev_length; */
-
- mov eax, [edx].ds_prev_length
- mov [esp+bestlen], eax
-
-;/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-
- add esi, eax
- mov [esp+windowbestlen], esi
-
-;/* register ush scan_start = *(ushf*)scan; */
-;/* register ush scan_end = *(ushf*)(scan+best_len-1); */
-;/* Posf *prev = s->prev; */
-
- movzx ebx, WORD PTR[edi]
- mov [esp+scanstart], ebx
- movzx ebx, WORD PTR[eax+edi-1]
- mov [esp+scanend], ebx
- mov edi, [edx].ds_prev
-
-;/* Jump into the main loop. */
-
- mov edx, [esp+chainlenwmask]
- jmp SHORT LoopEntry
-
-;/* do {
-; * match = s->window + cur_match;
-; * if (*(ushf*)(match+best_len-1) != scan_end ||
-; * *(ushf*)match != scan_start) continue;
-; * [...]
-; * } while ((cur_match = prev[cur_match & wmask]) > limit
-; * && --chain_length != 0);
-; *
-; * Here is the inner loop of the function. The function will spend the
-; * majority of its time in this loop, and majority of that time will
-; * be spent in the first ten instructions.
-; *
-; * Within this loop:
-; * %ebx = scanend
-; * %ecx = curmatch
-; * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
-; * %esi = windowbestlen - i.e., (window + bestlen)
-; * %edi = prev
-; * %ebp = limit
-; */
-
- ALIGN 4
-LookupLoop:
- and ecx, edx
- movzx ecx, WORD PTR[edi+ecx*2]
- cmp ecx, ebp
- jbe LeaveNow
- sub edx, 000010000H
- js LeaveNow
-
-LoopEntry:
- movzx eax, WORD PTR[esi+ecx-1]
- cmp eax, ebx
- jnz SHORT LookupLoop
-
- mov eax, [esp+window]
- movzx eax, WORD PTR[eax+ecx]
- cmp eax, [esp+scanstart]
- jnz SHORT LookupLoop
-
-;/* Store the current value of chainlen. */
-
- mov [esp+chainlenwmask], edx
-
-;/* Point %edi to the string under scrutiny, and %esi to the string we */
-;/* are hoping to match it up with. In actuality, %esi and %edi are */
-;/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
-;/* initialized to -(MAX_MATCH_8 - scanalign). */
-
- mov esi, [esp+window]
- mov edi, [esp+scan]
- add esi, ecx
- mov eax, [esp+scanalign]
- mov edx, -MAX_MATCH_8
- lea edi, [edi+eax+MAX_MATCH_8]
- lea esi, [esi+eax+MAX_MATCH_8]
-
-;/* Test the strings for equality, 8 bytes at a time. At the end,
-; * adjust %edx so that it is offset to the exact byte that mismatched.
-; *
-; * We already know at this point that the first three bytes of the
-; * strings match each other, and they can be safely passed over before
-; * starting the compare loop. So what this code does is skip over 0-3
-; * bytes, as much as necessary in order to dword-align the %edi
-; * pointer. (%esi will still be misaligned three times out of four.)
-; *
-; * It should be confessed that this loop usually does not represent
-; * much of the total running time. Replacing it with a more
-; * straightforward "rep cmpsb" would not drastically degrade
-; * performance.
-; */
-
-LoopCmps:
- mov eax, DWORD PTR[esi+edx]
- xor eax, DWORD PTR[edi+edx]
- jnz SHORT LeaveLoopCmps
-
- mov eax, DWORD PTR[esi+edx+4]
- xor eax, DWORD PTR[edi+edx+4]
- jnz SHORT LeaveLoopCmps4
-
- add edx, 8
- jnz SHORT LoopCmps
- jmp LenMaximum
- ALIGN 4
-
-LeaveLoopCmps4:
- add edx, 4
-
-LeaveLoopCmps:
- test eax, 00000FFFFH
- jnz SHORT LenLower
-
- add edx, 2
- shr eax, 16
-
-LenLower:
- sub al, 1
- adc edx, 0
-
-;/* Calculate the length of the match. If it is longer than MAX_MATCH, */
-;/* then automatically accept it as the best possible match and leave. */
-
- lea eax, [edi+edx]
- mov edi, [esp+scan]
- sub eax, edi
- cmp eax, MAX_MATCH
- jge SHORT LenMaximum
-
-;/* If the length of the match is not longer than the best match we */
-;/* have so far, then forget it and return to the lookup loop. */
-
- mov edx, [esp+deflatestate]
- mov ebx, [esp+bestlen]
- cmp eax, ebx
- jg SHORT LongerMatch
- mov esi, [esp+windowbestlen]
- mov edi, [edx].ds_prev
- mov ebx, [esp+scanend]
- mov edx, [esp+chainlenwmask]
- jmp LookupLoop
- ALIGN 4
-
-;/* s->match_start = cur_match; */
-;/* best_len = len; */
-;/* if (len >= nice_match) break; */
-;/* scan_end = *(ushf*)(scan+best_len-1); */
-
-LongerMatch:
- mov ebx, [esp+nicematch]
- mov [esp+bestlen], eax
- mov [edx].ds_match_start, ecx
- cmp eax, ebx
- jge SHORT LeaveNow
- mov esi, [esp+window]
- add esi, eax
- mov [esp+windowbestlen], esi
- movzx ebx, WORD PTR[edi+eax-1]
- mov edi, [edx].ds_prev
- mov [esp+scanend], ebx
- mov edx, [esp+chainlenwmask]
- jmp LookupLoop
- ALIGN 4
-
-;/* Accept the current string, with the maximum possible length. */
-
-LenMaximum:
- mov edx, [esp+deflatestate]
- mov DWORD PTR[esp+bestlen], MAX_MATCH
- mov [edx].ds_match_start, ecx
-
-;/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
-;/* return s->lookahead; */
-
-LeaveNow:
- mov edx, [esp+deflatestate]
- mov ebx, [esp+bestlen]
- mov eax, [edx].ds_lookahead
- cmp ebx, eax
- jg SHORT LookaheadRet
- mov eax, ebx
-LookaheadRet:
-
-; Restore the stack and return from whence we came.
-
- add esp, varsize
- pop ebx
- pop esi
- pop edi
- pop ebp
- ret
-
-_longest_match ENDP
-
-_TEXT ENDS
-END
diff --git a/cpukit/zlib/contrib/masmx64/bld_ml64.bat b/cpukit/zlib/contrib/masmx64/bld_ml64.bat
deleted file mode 100644
index 8f9343d0af..0000000000
--- a/cpukit/zlib/contrib/masmx64/bld_ml64.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-ml64.exe /Flinffasx64 /c /Zi inffasx64.asm
-ml64.exe /Flgvmat64 /c /Zi gvmat64.asm
diff --git a/cpukit/zlib/contrib/masmx86/gvmat32.asm b/cpukit/zlib/contrib/masmx86/gvmat32.asm
deleted file mode 100644
index e841a7fda2..0000000000
--- a/cpukit/zlib/contrib/masmx86/gvmat32.asm
+++ /dev/null
@@ -1,909 +0,0 @@
-;
-; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86
-; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
-; File written by Gilles Vollant, by modifiying the longest_match
-; from Jean-loup Gailly in deflate.c
-; It need wmask == 0x7fff
-; (assembly code is faster with a fixed wmask)
-;
-; For Visual C++ 4.2 and ML 6.11c (version in directory \MASM611C of Win95 DDK)
-; I compile with : "ml /coff /Zi /c gvmat32.asm"
-;
-
-;uInt longest_match_7fff(s, cur_match)
-; deflate_state *s;
-; IPos cur_match; /* current match */
-
- NbStack equ 76
- cur_match equ dword ptr[esp+NbStack-0]
- str_s equ dword ptr[esp+NbStack-4]
-; 5 dword on top (ret,ebp,esi,edi,ebx)
- adrret equ dword ptr[esp+NbStack-8]
- pushebp equ dword ptr[esp+NbStack-12]
- pushedi equ dword ptr[esp+NbStack-16]
- pushesi equ dword ptr[esp+NbStack-20]
- pushebx equ dword ptr[esp+NbStack-24]
-
- chain_length equ dword ptr [esp+NbStack-28]
- limit equ dword ptr [esp+NbStack-32]
- best_len equ dword ptr [esp+NbStack-36]
- window equ dword ptr [esp+NbStack-40]
- prev equ dword ptr [esp+NbStack-44]
- scan_start equ word ptr [esp+NbStack-48]
- wmask equ dword ptr [esp+NbStack-52]
- match_start_ptr equ dword ptr [esp+NbStack-56]
- nice_match equ dword ptr [esp+NbStack-60]
- scan equ dword ptr [esp+NbStack-64]
-
- windowlen equ dword ptr [esp+NbStack-68]
- match_start equ dword ptr [esp+NbStack-72]
- strend equ dword ptr [esp+NbStack-76]
- NbStackAdd equ (NbStack-24)
-
- .386p
-
- name gvmatch
- .MODEL FLAT
-
-
-
-; all the +addstr offsets are due to the addition of pending_buf_size in zlib 1.04
-; and adding gzhead and gzindex in zlib 1.2.2.1
-; in the deflate_state structure since the asm code was first written
-; (if you compile with zlib 1.0.4 or older, set addstr to 0).
-; (if you compiler with zlib between 1.04 and 1.2.1, set addstr to 4)
-; Note : these value are good with a 8 bytes boundary pack structure
-
- addstr equ 4+8
- dep_chain_length equ 70h+addstr
- dep_window equ 2ch+addstr
- dep_strstart equ 60h+addstr
- dep_prev_length equ 6ch+addstr
- dep_nice_match equ 84h+addstr
- dep_w_size equ 20h+addstr
- dep_prev equ 34h+addstr
- dep_w_mask equ 28h+addstr
- dep_good_match equ 80h+addstr
- dep_match_start equ 64h+addstr
- dep_lookahead equ 68h+addstr
-
-
-_TEXT segment
-
-IFDEF NOUNDERLINE
- public longest_match_7fff
- public longest_match_686
-; public match_init
-ELSE
- public _longest_match_7fff
- public _longest_match_686
-; public _match_init
-ENDIF
-
- MAX_MATCH equ 258
- MIN_MATCH equ 3
- MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
-
-
-
-IFDEF NOUNDERLINE
-;match_init proc near
-; ret
-;match_init endp
-ELSE
-;_match_init proc near
-; ret
-;_match_init endp
-ENDIF
-
-
-IFDEF NOUNDERLINE
-longest_match_7fff proc near
-ELSE
-_longest_match_7fff proc near
-ENDIF
-
- mov edx,[esp+4]
-
-
-
- push ebp
- push edi
- push esi
- push ebx
-
- sub esp,NbStackAdd
-
-; initialize or check the variables used in match.asm.
- mov ebp,edx
-
-; chain_length = s->max_chain_length
-; if (prev_length>=good_match) chain_length >>= 2
- mov edx,[ebp+dep_chain_length]
- mov ebx,[ebp+dep_prev_length]
- cmp [ebp+dep_good_match],ebx
- ja noshr
- shr edx,2
-noshr:
-; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop
- inc edx
- mov edi,[ebp+dep_nice_match]
- mov chain_length,edx
- mov eax,[ebp+dep_lookahead]
- cmp eax,edi
-; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
- jae nolookaheadnicematch
- mov edi,eax
-nolookaheadnicematch:
-; best_len = s->prev_length
- mov best_len,ebx
-
-; window = s->window
- mov esi,[ebp+dep_window]
- mov ecx,[ebp+dep_strstart]
- mov window,esi
-
- mov nice_match,edi
-; scan = window + strstart
- add esi,ecx
- mov scan,esi
-; dx = *window
- mov dx,word ptr [esi]
-; bx = *(window+best_len-1)
- mov bx,word ptr [esi+ebx-1]
- add esi,MAX_MATCH-1
-; scan_start = *scan
- mov scan_start,dx
-; strend = scan + MAX_MATCH-1
- mov strend,esi
-; bx = scan_end = *(window+best_len-1)
-
-; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-; s->strstart - (IPos)MAX_DIST(s) : NIL;
-
- mov esi,[ebp+dep_w_size]
- sub esi,MIN_LOOKAHEAD
-; here esi = MAX_DIST(s)
- sub ecx,esi
- ja nodist
- xor ecx,ecx
-nodist:
- mov limit,ecx
-
-; prev = s->prev
- mov edx,[ebp+dep_prev]
- mov prev,edx
-
-;
- mov edx,dword ptr [ebp+dep_match_start]
- mov bp,scan_start
- mov eax,cur_match
- mov match_start,edx
-
- mov edx,window
- mov edi,edx
- add edi,best_len
- mov esi,prev
- dec edi
-; windowlen = window + best_len -1
- mov windowlen,edi
-
- jmp beginloop2
- align 4
-
-; here, in the loop
-; eax = ax = cur_match
-; ecx = limit
-; bx = scan_end
-; bp = scan_start
-; edi = windowlen (window + best_len -1)
-; esi = prev
-
-
-;// here; chain_length <=16
-normalbeg0add16:
- add chain_length,16
- jz exitloop
-normalbeg0:
- cmp word ptr[edi+eax],bx
- je normalbeg2noroll
-rcontlabnoroll:
-; cur_match = prev[cur_match & wmask]
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
-; if cur_match > limit, go to exitloop
- cmp ecx,eax
- jnb exitloop
-; if --chain_length != 0, go to exitloop
- dec chain_length
- jnz normalbeg0
- jmp exitloop
-
-normalbeg2noroll:
-; if (scan_start==*(cur_match+window)) goto normalbeg2
- cmp bp,word ptr[edx+eax]
- jne rcontlabnoroll
- jmp normalbeg2
-
-contloop3:
- mov edi,windowlen
-
-; cur_match = prev[cur_match & wmask]
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
-; if cur_match > limit, go to exitloop
- cmp ecx,eax
-jnbexitloopshort1:
- jnb exitloop
-; if --chain_length != 0, go to exitloop
-
-
-; begin the main loop
-beginloop2:
- sub chain_length,16+1
-; if chain_length <=16, don't use the unrolled loop
- jna normalbeg0add16
-
-do16:
- cmp word ptr[edi+eax],bx
- je normalbeg2dc0
-
-maccn MACRO lab
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
- cmp ecx,eax
- jnb exitloop
- cmp word ptr[edi+eax],bx
- je lab
- ENDM
-
-rcontloop0:
- maccn normalbeg2dc1
-
-rcontloop1:
- maccn normalbeg2dc2
-
-rcontloop2:
- maccn normalbeg2dc3
-
-rcontloop3:
- maccn normalbeg2dc4
-
-rcontloop4:
- maccn normalbeg2dc5
-
-rcontloop5:
- maccn normalbeg2dc6
-
-rcontloop6:
- maccn normalbeg2dc7
-
-rcontloop7:
- maccn normalbeg2dc8
-
-rcontloop8:
- maccn normalbeg2dc9
-
-rcontloop9:
- maccn normalbeg2dc10
-
-rcontloop10:
- maccn short normalbeg2dc11
-
-rcontloop11:
- maccn short normalbeg2dc12
-
-rcontloop12:
- maccn short normalbeg2dc13
-
-rcontloop13:
- maccn short normalbeg2dc14
-
-rcontloop14:
- maccn short normalbeg2dc15
-
-rcontloop15:
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
- cmp ecx,eax
- jnb exitloop
-
- sub chain_length,16
- ja do16
- jmp normalbeg0add16
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-normbeg MACRO rcontlab,valsub
-; if we are here, we know that *(match+best_len-1) == scan_end
- cmp bp,word ptr[edx+eax]
-; if (match != scan_start) goto rcontlab
- jne rcontlab
-; calculate the good chain_length, and we'll compare scan and match string
- add chain_length,16-valsub
- jmp iseq
- ENDM
-
-
-normalbeg2dc11:
- normbeg rcontloop11,11
-
-normalbeg2dc12:
- normbeg short rcontloop12,12
-
-normalbeg2dc13:
- normbeg short rcontloop13,13
-
-normalbeg2dc14:
- normbeg short rcontloop14,14
-
-normalbeg2dc15:
- normbeg short rcontloop15,15
-
-normalbeg2dc10:
- normbeg rcontloop10,10
-
-normalbeg2dc9:
- normbeg rcontloop9,9
-
-normalbeg2dc8:
- normbeg rcontloop8,8
-
-normalbeg2dc7:
- normbeg rcontloop7,7
-
-normalbeg2dc6:
- normbeg rcontloop6,6
-
-normalbeg2dc5:
- normbeg rcontloop5,5
-
-normalbeg2dc4:
- normbeg rcontloop4,4
-
-normalbeg2dc3:
- normbeg rcontloop3,3
-
-normalbeg2dc2:
- normbeg rcontloop2,2
-
-normalbeg2dc1:
- normbeg rcontloop1,1
-
-normalbeg2dc0:
- normbeg rcontloop0,0
-
-
-; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end
-
-normalbeg2:
- mov edi,window
-
- cmp bp,word ptr[edi+eax]
- jne contloop3 ; if *(ushf*)match != scan_start, continue
-
-iseq:
-; if we are here, we know that *(match+best_len-1) == scan_end
-; and (match == scan_start)
-
- mov edi,edx
- mov esi,scan ; esi = scan
- add edi,eax ; edi = window + cur_match = match
-
- mov edx,[esi+3] ; compare manually dword at match+3
- xor edx,[edi+3] ; and scan +3
-
- jz begincompare ; if equal, go to long compare
-
-; we will determine the unmatch byte and calculate len (in esi)
- or dl,dl
- je eq1rr
- mov esi,3
- jmp trfinval
-eq1rr:
- or dx,dx
- je eq1
-
- mov esi,4
- jmp trfinval
-eq1:
- and edx,0ffffffh
- jz eq11
- mov esi,5
- jmp trfinval
-eq11:
- mov esi,6
- jmp trfinval
-
-begincompare:
- ; here we now scan and match begin same
- add edi,6
- add esi,6
- mov ecx,(MAX_MATCH-(2+4))/4 ; scan for at most MAX_MATCH bytes
- repe cmpsd ; loop until mismatch
-
- je trfin ; go to trfin if not unmatch
-; we determine the unmatch byte
- sub esi,4
- mov edx,[edi-4]
- xor edx,[esi]
-
- or dl,dl
- jnz trfin
- inc esi
-
- or dx,dx
- jnz trfin
- inc esi
-
- and edx,0ffffffh
- jnz trfin
- inc esi
-
-trfin:
- sub esi,scan ; esi = len
-trfinval:
-; here we have finised compare, and esi contain len of equal string
- cmp esi,best_len ; if len > best_len, go newbestlen
- ja short newbestlen
-; now we restore edx, ecx and esi, for the big loop
- mov esi,prev
- mov ecx,limit
- mov edx,window
- jmp contloop3
-
-newbestlen:
- mov best_len,esi ; len become best_len
-
- mov match_start,eax ; save new position as match_start
- cmp esi,nice_match ; if best_len >= nice_match, exit
- jae exitloop
- mov ecx,scan
- mov edx,window ; restore edx=window
- add ecx,esi
- add esi,edx
-
- dec esi
- mov windowlen,esi ; windowlen = window + best_len-1
- mov bx,[ecx-1] ; bx = *(scan+best_len-1) = scan_end
-
-; now we restore ecx and esi, for the big loop :
- mov esi,prev
- mov ecx,limit
- jmp contloop3
-
-exitloop:
-; exit : s->match_start=match_start
- mov ebx,match_start
- mov ebp,str_s
- mov ecx,best_len
- mov dword ptr [ebp+dep_match_start],ebx
- mov eax,dword ptr [ebp+dep_lookahead]
- cmp ecx,eax
- ja minexlo
- mov eax,ecx
-minexlo:
-; return min(best_len,s->lookahead)
-
-; restore stack and register ebx,esi,edi,ebp
- add esp,NbStackAdd
-
- pop ebx
- pop esi
- pop edi
- pop ebp
- ret
-InfoAuthor:
-; please don't remove this string !
-; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary!
- db 0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah
-
-
-
-IFDEF NOUNDERLINE
-longest_match_7fff endp
-ELSE
-_longest_match_7fff endp
-ENDIF
-
-
-IFDEF NOUNDERLINE
-cpudetect32 proc near
-ELSE
-_cpudetect32 proc near
-ENDIF
-
- push ebx
-
- pushfd ; push original EFLAGS
- pop eax ; get original EFLAGS
- mov ecx, eax ; save original EFLAGS
- xor eax, 40000h ; flip AC bit in EFLAGS
- push eax ; save new EFLAGS value on stack
- popfd ; replace current EFLAGS value
- pushfd ; get new EFLAGS
- pop eax ; store new EFLAGS in EAX
- xor eax, ecx ; can’t toggle AC bit, processor=80386
- jz end_cpu_is_386 ; jump if 80386 processor
- push ecx
- popfd ; restore AC bit in EFLAGS first
-
- pushfd
- pushfd
- pop ecx
-
- mov eax, ecx ; get original EFLAGS
- xor eax, 200000h ; flip ID bit in EFLAGS
- push eax ; save new EFLAGS value on stack
- popfd ; replace current EFLAGS value
- pushfd ; get new EFLAGS
- pop eax ; store new EFLAGS in EAX
- popfd ; restore original EFLAGS
- xor eax, ecx ; can’t toggle ID bit,
- je is_old_486 ; processor=old
-
- mov eax,1
- db 0fh,0a2h ;CPUID
-
-exitcpudetect:
- pop ebx
- ret
-
-end_cpu_is_386:
- mov eax,0300h
- jmp exitcpudetect
-
-is_old_486:
- mov eax,0400h
- jmp exitcpudetect
-
-IFDEF NOUNDERLINE
-cpudetect32 endp
-ELSE
-_cpudetect32 endp
-ENDIF
-
-
-
-
-MAX_MATCH equ 258
-MIN_MATCH equ 3
-MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1)
-MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h)
-
-
-;;; stack frame offsets
-
-chainlenwmask equ esp + 0 ; high word: current chain len
- ; low word: s->wmask
-window equ esp + 4 ; local copy of s->window
-windowbestlen equ esp + 8 ; s->window + bestlen
-scanstart equ esp + 16 ; first two bytes of string
-scanend equ esp + 12 ; last two bytes of string
-scanalign equ esp + 20 ; dword-misalignment of string
-nicematch equ esp + 24 ; a good enough match size
-bestlen equ esp + 28 ; size of best match so far
-scan equ esp + 32 ; ptr to string wanting match
-
-LocalVarsSize equ 36
-; saved ebx byte esp + 36
-; saved edi byte esp + 40
-; saved esi byte esp + 44
-; saved ebp byte esp + 48
-; return address byte esp + 52
-deflatestate equ esp + 56 ; the function arguments
-curmatch equ esp + 60
-
-;;; Offsets for fields in the deflate_state structure. These numbers
-;;; are calculated from the definition of deflate_state, with the
-;;; assumption that the compiler will dword-align the fields. (Thus,
-;;; changing the definition of deflate_state could easily cause this
-;;; program to crash horribly, without so much as a warning at
-;;; compile time. Sigh.)
-
-dsWSize equ 36+addstr-4
-dsWMask equ 44+addstr-4
-dsWindow equ 48+addstr-4
-dsPrev equ 56+addstr-4
-dsMatchLen equ 88+addstr-4
-dsPrevMatch equ 92+addstr-4
-dsStrStart equ 100+addstr-4
-dsMatchStart equ 104+addstr-4
-dsLookahead equ 108+addstr-4
-dsPrevLen equ 112+addstr-4
-dsMaxChainLen equ 116+addstr-4
-dsGoodMatch equ 132+addstr-4
-dsNiceMatch equ 136+addstr-4
-
-
-;;; match.asm -- Pentium-Pro-optimized version of longest_match()
-;;; Written for zlib 1.1.2
-;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
-;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html
-;;;
-;;; This is free software; you can redistribute it and/or modify it
-;;; under the terms of the GNU General Public License.
-
-;GLOBAL _longest_match, _match_init
-
-
-;SECTION .text
-
-;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
-
-;_longest_match:
-IFDEF NOUNDERLINE
-longest_match_686 proc near
-ELSE
-_longest_match_686 proc near
-ENDIF
-
-
-;;; Save registers that the compiler may be using, and adjust esp to
-;;; make room for our stack frame.
-
- push ebp
- push edi
- push esi
- push ebx
- sub esp, LocalVarsSize
-
-;;; Retrieve the function arguments. ecx will hold cur_match
-;;; throughout the entire function. edx will hold the pointer to the
-;;; deflate_state structure during the function's setup (before
-;;; entering the main loop.
-
- mov edx, [deflatestate]
- mov ecx, [curmatch]
-
-;;; uInt wmask = s->w_mask;
-;;; unsigned chain_length = s->max_chain_length;
-;;; if (s->prev_length >= s->good_match) {
-;;; chain_length >>= 2;
-;;; }
-
- mov eax, [edx + dsPrevLen]
- mov ebx, [edx + dsGoodMatch]
- cmp eax, ebx
- mov eax, [edx + dsWMask]
- mov ebx, [edx + dsMaxChainLen]
- jl LastMatchGood
- shr ebx, 2
-LastMatchGood:
-
-;;; chainlen is decremented once beforehand so that the function can
-;;; use the sign flag instead of the zero flag for the exit test.
-;;; It is then shifted into the high word, to make room for the wmask
-;;; value, which it will always accompany.
-
- dec ebx
- shl ebx, 16
- or ebx, eax
- mov [chainlenwmask], ebx
-
-;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- mov eax, [edx + dsNiceMatch]
- mov ebx, [edx + dsLookahead]
- cmp ebx, eax
- jl LookaheadLess
- mov ebx, eax
-LookaheadLess: mov [nicematch], ebx
-
-;;; register Bytef *scan = s->window + s->strstart;
-
- mov esi, [edx + dsWindow]
- mov [window], esi
- mov ebp, [edx + dsStrStart]
- lea edi, [esi + ebp]
- mov [scan], edi
-
-;;; Determine how many bytes the scan ptr is off from being
-;;; dword-aligned.
-
- mov eax, edi
- neg eax
- and eax, 3
- mov [scanalign], eax
-
-;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
-
- mov eax, [edx + dsWSize]
- sub eax, MIN_LOOKAHEAD
- sub ebp, eax
- jg LimitPositive
- xor ebp, ebp
-LimitPositive:
-
-;;; int best_len = s->prev_length;
-
- mov eax, [edx + dsPrevLen]
- mov [bestlen], eax
-
-;;; Store the sum of s->window + best_len in esi locally, and in esi.
-
- add esi, eax
- mov [windowbestlen], esi
-
-;;; register ush scan_start = *(ushf*)scan;
-;;; register ush scan_end = *(ushf*)(scan+best_len-1);
-;;; Posf *prev = s->prev;
-
- movzx ebx, word ptr [edi]
- mov [scanstart], ebx
- movzx ebx, word ptr [edi + eax - 1]
- mov [scanend], ebx
- mov edi, [edx + dsPrev]
-
-;;; Jump into the main loop.
-
- mov edx, [chainlenwmask]
- jmp short LoopEntry
-
-align 4
-
-;;; do {
-;;; match = s->window + cur_match;
-;;; if (*(ushf*)(match+best_len-1) != scan_end ||
-;;; *(ushf*)match != scan_start) continue;
-;;; [...]
-;;; } while ((cur_match = prev[cur_match & wmask]) > limit
-;;; && --chain_length != 0);
-;;;
-;;; Here is the inner loop of the function. The function will spend the
-;;; majority of its time in this loop, and majority of that time will
-;;; be spent in the first ten instructions.
-;;;
-;;; Within this loop:
-;;; ebx = scanend
-;;; ecx = curmatch
-;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
-;;; esi = windowbestlen - i.e., (window + bestlen)
-;;; edi = prev
-;;; ebp = limit
-
-LookupLoop:
- and ecx, edx
- movzx ecx, word ptr [edi + ecx*2]
- cmp ecx, ebp
- jbe LeaveNow
- sub edx, 00010000h
- js LeaveNow
-LoopEntry: movzx eax, word ptr [esi + ecx - 1]
- cmp eax, ebx
- jnz LookupLoop
- mov eax, [window]
- movzx eax, word ptr [eax + ecx]
- cmp eax, [scanstart]
- jnz LookupLoop
-
-;;; Store the current value of chainlen.
-
- mov [chainlenwmask], edx
-
-;;; Point edi to the string under scrutiny, and esi to the string we
-;;; are hoping to match it up with. In actuality, esi and edi are
-;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
-;;; initialized to -(MAX_MATCH_8 - scanalign).
-
- mov esi, [window]
- mov edi, [scan]
- add esi, ecx
- mov eax, [scanalign]
- mov edx, 0fffffef8h; -(MAX_MATCH_8)
- lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]
- lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]
-
-;;; Test the strings for equality, 8 bytes at a time. At the end,
-;;; adjust edx so that it is offset to the exact byte that mismatched.
-;;;
-;;; We already know at this point that the first three bytes of the
-;;; strings match each other, and they can be safely passed over before
-;;; starting the compare loop. So what this code does is skip over 0-3
-;;; bytes, as much as necessary in order to dword-align the edi
-;;; pointer. (esi will still be misaligned three times out of four.)
-;;;
-;;; It should be confessed that this loop usually does not represent
-;;; much of the total running time. Replacing it with a more
-;;; straightforward "rep cmpsb" would not drastically degrade
-;;; performance.
-
-LoopCmps:
- mov eax, [esi + edx]
- xor eax, [edi + edx]
- jnz LeaveLoopCmps
- mov eax, [esi + edx + 4]
- xor eax, [edi + edx + 4]
- jnz LeaveLoopCmps4
- add edx, 8
- jnz LoopCmps
- jmp short LenMaximum
-LeaveLoopCmps4: add edx, 4
-LeaveLoopCmps: test eax, 0000FFFFh
- jnz LenLower
- add edx, 2
- shr eax, 16
-LenLower: sub al, 1
- adc edx, 0
-
-;;; Calculate the length of the match. If it is longer than MAX_MATCH,
-;;; then automatically accept it as the best possible match and leave.
-
- lea eax, [edi + edx]
- mov edi, [scan]
- sub eax, edi
- cmp eax, MAX_MATCH
- jge LenMaximum
-
-;;; If the length of the match is not longer than the best match we
-;;; have so far, then forget it and return to the lookup loop.
-
- mov edx, [deflatestate]
- mov ebx, [bestlen]
- cmp eax, ebx
- jg LongerMatch
- mov esi, [windowbestlen]
- mov edi, [edx + dsPrev]
- mov ebx, [scanend]
- mov edx, [chainlenwmask]
- jmp LookupLoop
-
-;;; s->match_start = cur_match;
-;;; best_len = len;
-;;; if (len >= nice_match) break;
-;;; scan_end = *(ushf*)(scan+best_len-1);
-
-LongerMatch: mov ebx, [nicematch]
- mov [bestlen], eax
- mov [edx + dsMatchStart], ecx
- cmp eax, ebx
- jge LeaveNow
- mov esi, [window]
- add esi, eax
- mov [windowbestlen], esi
- movzx ebx, word ptr [edi + eax - 1]
- mov edi, [edx + dsPrev]
- mov [scanend], ebx
- mov edx, [chainlenwmask]
- jmp LookupLoop
-
-;;; Accept the current string, with the maximum possible length.
-
-LenMaximum: mov edx, [deflatestate]
- mov dword ptr [bestlen], MAX_MATCH
- mov [edx + dsMatchStart], ecx
-
-;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
-;;; return s->lookahead;
-
-LeaveNow:
- mov edx, [deflatestate]
- mov ebx, [bestlen]
- mov eax, [edx + dsLookahead]
- cmp ebx, eax
- jg LookaheadRet
- mov eax, ebx
-LookaheadRet:
-
-;;; Restore the stack and return from whence we came.
-
- add esp, LocalVarsSize
- pop ebx
- pop esi
- pop edi
- pop ebp
-
- ret
-; please don't remove this string !
-; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary!
- db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah
-
-IFDEF NOUNDERLINE
-longest_match_686 endp
-ELSE
-_longest_match_686 endp
-ENDIF
-
-_TEXT ends
-end
diff --git a/cpukit/zlib/contrib/masmx86/gvmat32c.c b/cpukit/zlib/contrib/masmx86/gvmat32c.c
deleted file mode 100644
index 9ed25f3432..0000000000
--- a/cpukit/zlib/contrib/masmx86/gvmat32c.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
- * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
- * File written by Gilles Vollant, by modifiying the longest_match
- * from Jean-loup Gailly in deflate.c
- * it prepare all parameters and call the assembly longest_match_gvasm
- * longest_match execute standard C code is wmask != 0x7fff
- * (assembly code is faster with a fixed wmask)
- *
- */
-
-#include "deflate.h"
-
-#ifdef ASMV
-#define NIL 0
-
-#define UNALIGNED_OK
-
-
-/* if your C compiler don't add underline before function name,
- define ADD_UNDERLINE_ASMFUNC */
-#ifdef ADD_UNDERLINE_ASMFUNC
-#define longest_match_7fff _longest_match_7fff
-#define longest_match_686 _longest_match_686
-#define cpudetect32 _cpudetect32
-#endif
-
-
-
-void match_init()
-{
-}
-
-unsigned long cpudetect32();
-
-uInt longest_match_c(
- deflate_state *s,
- IPos cur_match); /* current match */
-
-
-uInt longest_match_7fff(
- deflate_state *s,
- IPos cur_match); /* current match */
-
-uInt longest_match_686(
- deflate_state *s,
- IPos cur_match); /* current match */
-
-uInt longest_match(
- deflate_state *s,
- IPos cur_match) /* current match */
-{
- static uInt iIsPPro=2;
-
- if ((s->w_mask == 0x7fff) && (iIsPPro==0))
- return longest_match_7fff(s,cur_match);
-
- if (iIsPPro==1)
- return longest_match_686(s,cur_match);
-
- if (iIsPPro==2)
- iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
-
- return longest_match_c(s,cur_match);
-}
-
-
-
-uInt longest_match_c(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2:
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-
-#endif /* ASMV */
diff --git a/cpukit/zlib/contrib/masmx86/inffas32.asm b/cpukit/zlib/contrib/masmx86/inffas32.asm
deleted file mode 100644
index 531bcefffc..0000000000
--- a/cpukit/zlib/contrib/masmx86/inffas32.asm
+++ /dev/null
@@ -1,1036 +0,0 @@
-; 75 "inffast.S"
-;FILE "inffast.S"
-
-;;;GLOBAL _inflate_fast
-
-;;;SECTION .text
-
-
-
- .586p
- .mmx
-
- name inflate_fast_x86
- .MODEL FLAT
-
-_DATA segment
-inflate_fast_use_mmx:
- dd 1
-
-
-_TEXT segment
-PUBLIC _inflate_fast
-
-ALIGN 4
-_inflate_fast:
- jmp inflate_fast_entry
-
-
-
-ALIGN 4
- db 'Fast decoding Code from Chris Anderson'
- db 0
-
-ALIGN 4
-invalid_literal_length_code_msg:
- db 'invalid literal/length code'
- db 0
-
-ALIGN 4
-invalid_distance_code_msg:
- db 'invalid distance code'
- db 0
-
-ALIGN 4
-invalid_distance_too_far_msg:
- db 'invalid distance too far back'
- db 0
-
-
-ALIGN 4
-inflate_fast_mask:
-dd 0
-dd 1
-dd 3
-dd 7
-dd 15
-dd 31
-dd 63
-dd 127
-dd 255
-dd 511
-dd 1023
-dd 2047
-dd 4095
-dd 8191
-dd 16383
-dd 32767
-dd 65535
-dd 131071
-dd 262143
-dd 524287
-dd 1048575
-dd 2097151
-dd 4194303
-dd 8388607
-dd 16777215
-dd 33554431
-dd 67108863
-dd 134217727
-dd 268435455
-dd 536870911
-dd 1073741823
-dd 2147483647
-dd 4294967295
-
-
-; head was added in zlib 1.2.2.1, so we add addstr
-; set addstr to 0 with zlib 1.2.1 of below
-addstr equ 4
-
-mode_state equ 0 ;/* state->mode */
-wsize_state equ 32+addstr ;/* state->wsize */
-write_state equ (36+4+addstr) ;/* state->write */
-window_state equ (40+4+addstr) ;/* state->window */
-hold_state equ (44+4+addstr) ;/* state->hold */
-bits_state equ (48+4+addstr) ;/* state->bits */
-lencode_state equ (64+4+addstr) ;/* state->lencode */
-distcode_state equ (68+4+addstr) ;/* state->distcode */
-lenbits_state equ (72+4+addstr) ;/* state->lenbits */
-distbits_state equ (76+4+addstr) ;/* state->distbits */
-
-
-;;SECTION .text
-; 205 "inffast.S"
-;GLOBAL inflate_fast_use_mmx
-
-;SECTION .data
-
-
-; GLOBAL inflate_fast_use_mmx:object
-;.size inflate_fast_use_mmx, 4
-; 226 "inffast.S"
-;SECTION .text
-
-ALIGN 4
-inflate_fast_entry:
- push edi
- push esi
- push ebp
- push ebx
- pushfd
- sub esp,64
- cld
-
-
-
-
- mov esi, [esp+88]
- mov edi, [esi+28]
-
-
-
-
-
-
-
- mov edx, [esi+4]
- mov eax, [esi+0]
-
- add edx,eax
- sub edx,11
-
- mov [esp+44],eax
- mov [esp+20],edx
-
- mov ebp, [esp+92]
- mov ecx, [esi+16]
- mov ebx, [esi+12]
-
- sub ebp,ecx
- neg ebp
- add ebp,ebx
-
- sub ecx,257
- add ecx,ebx
-
- mov [esp+60],ebx
- mov [esp+40],ebp
- mov [esp+16],ecx
-; 285 "inffast.S"
- mov eax, [edi+lencode_state]
- mov ecx, [edi+distcode_state]
-
- mov [esp+8],eax
- mov [esp+12],ecx
-
- mov eax,1
- mov ecx, [edi+lenbits_state]
- shl eax,cl
- dec eax
- mov [esp+0],eax
-
- mov eax,1
- mov ecx, [edi+distbits_state]
- shl eax,cl
- dec eax
- mov [esp+4],eax
-
- mov eax, [edi+wsize_state]
- mov ecx, [edi+write_state]
- mov edx, [edi+window_state]
-
- mov [esp+52],eax
- mov [esp+48],ecx
- mov [esp+56],edx
-
- mov ebp, [edi+hold_state]
- mov ebx, [edi+bits_state]
-; 321 "inffast.S"
- mov esi, [esp+44]
- mov ecx, [esp+20]
- cmp ecx,esi
- ja L_align_long
-
- add ecx,11
- sub ecx,esi
- mov eax,12
- sub eax,ecx
- lea edi, [esp+28]
- rep movsb
- mov ecx,eax
- xor eax,eax
- rep stosb
- lea esi, [esp+28]
- mov [esp+20],esi
- jmp L_is_aligned
-
-
-L_align_long:
- test esi,3
- jz L_is_aligned
- xor eax,eax
- mov al, [esi]
- inc esi
- mov ecx,ebx
- add ebx,8
- shl eax,cl
- or ebp,eax
- jmp L_align_long
-
-L_is_aligned:
- mov edi, [esp+60]
-; 366 "inffast.S"
-L_check_mmx:
- cmp dword ptr [inflate_fast_use_mmx],2
- je L_init_mmx
- ja L_do_loop
-
- push eax
- push ebx
- push ecx
- push edx
- pushfd
- mov eax, [esp]
- xor dword ptr [esp],0200000h
-
-
-
-
- popfd
- pushfd
- pop edx
- xor edx,eax
- jz L_dont_use_mmx
- xor eax,eax
- cpuid
- cmp ebx,0756e6547h
- jne L_dont_use_mmx
- cmp ecx,06c65746eh
- jne L_dont_use_mmx
- cmp edx,049656e69h
- jne L_dont_use_mmx
- mov eax,1
- cpuid
- shr eax,8
- and eax,15
- cmp eax,6
- jne L_dont_use_mmx
- test edx,0800000h
- jnz L_use_mmx
- jmp L_dont_use_mmx
-L_use_mmx:
- mov dword ptr [inflate_fast_use_mmx],2
- jmp L_check_mmx_pop
-L_dont_use_mmx:
- mov dword ptr [inflate_fast_use_mmx],3
-L_check_mmx_pop:
- pop edx
- pop ecx
- pop ebx
- pop eax
- jmp L_check_mmx
-; 426 "inffast.S"
-ALIGN 4
-L_do_loop:
-; 437 "inffast.S"
- cmp bl,15
- ja L_get_length_code
-
- xor eax,eax
- lodsw
- mov cl,bl
- add bl,16
- shl eax,cl
- or ebp,eax
-
-L_get_length_code:
- mov edx, [esp+0]
- mov ecx, [esp+8]
- and edx,ebp
- mov eax, [ecx+edx*4]
-
-L_dolen:
-
-
-
-
-
-
- mov cl,ah
- sub bl,ah
- shr ebp,cl
-
-
-
-
-
-
- test al,al
- jnz L_test_for_length_base
-
- shr eax,16
- stosb
-
-L_while_test:
-
-
- cmp [esp+16],edi
- jbe L_break_loop
-
- cmp [esp+20],esi
- ja L_do_loop
- jmp L_break_loop
-
-L_test_for_length_base:
-; 502 "inffast.S"
- mov edx,eax
- shr edx,16
- mov cl,al
-
- test al,16
- jz L_test_for_second_level_length
- and cl,15
- jz L_save_len
- cmp bl,cl
- jae L_add_bits_to_len
-
- mov ch,cl
- xor eax,eax
- lodsw
- mov cl,bl
- add bl,16
- shl eax,cl
- or ebp,eax
- mov cl,ch
-
-L_add_bits_to_len:
- mov eax,1
- shl eax,cl
- dec eax
- sub bl,cl
- and eax,ebp
- shr ebp,cl
- add edx,eax
-
-L_save_len:
- mov [esp+24],edx
-
-
-L_decode_distance:
-; 549 "inffast.S"
- cmp bl,15
- ja L_get_distance_code
-
- xor eax,eax
- lodsw
- mov cl,bl
- add bl,16
- shl eax,cl
- or ebp,eax
-
-L_get_distance_code:
- mov edx, [esp+4]
- mov ecx, [esp+12]
- and edx,ebp
- mov eax, [ecx+edx*4]
-
-
-L_dodist:
- mov edx,eax
- shr edx,16
- mov cl,ah
- sub bl,ah
- shr ebp,cl
-; 584 "inffast.S"
- mov cl,al
-
- test al,16
- jz L_test_for_second_level_dist
- and cl,15
- jz L_check_dist_one
- cmp bl,cl
- jae L_add_bits_to_dist
-
- mov ch,cl
- xor eax,eax
- lodsw
- mov cl,bl
- add bl,16
- shl eax,cl
- or ebp,eax
- mov cl,ch
-
-L_add_bits_to_dist:
- mov eax,1
- shl eax,cl
- dec eax
- sub bl,cl
- and eax,ebp
- shr ebp,cl
- add edx,eax
- jmp L_check_window
-
-L_check_window:
-; 625 "inffast.S"
- mov [esp+44],esi
- mov eax,edi
- sub eax, [esp+40]
-
- cmp eax,edx
- jb L_clip_window
-
- mov ecx, [esp+24]
- mov esi,edi
- sub esi,edx
-
- sub ecx,3
- mov al, [esi]
- mov [edi],al
- mov al, [esi+1]
- mov dl, [esi+2]
- add esi,3
- mov [edi+1],al
- mov [edi+2],dl
- add edi,3
- rep movsb
-
- mov esi, [esp+44]
- jmp L_while_test
-
-ALIGN 4
-L_check_dist_one:
- cmp edx,1
- jne L_check_window
- cmp [esp+40],edi
- je L_check_window
-
- dec edi
- mov ecx, [esp+24]
- mov al, [edi]
- sub ecx,3
-
- mov [edi+1],al
- mov [edi+2],al
- mov [edi+3],al
- add edi,4
- rep stosb
-
- jmp L_while_test
-
-ALIGN 4
-L_test_for_second_level_length:
-
-
-
-
- test al,64
- jnz L_test_for_end_of_block
-
- mov eax,1
- shl eax,cl
- dec eax
- and eax,ebp
- add eax,edx
- mov edx, [esp+8]
- mov eax, [edx+eax*4]
- jmp L_dolen
-
-ALIGN 4
-L_test_for_second_level_dist:
-
-
-
-
- test al,64
- jnz L_invalid_distance_code
-
- mov eax,1
- shl eax,cl
- dec eax
- and eax,ebp
- add eax,edx
- mov edx, [esp+12]
- mov eax, [edx+eax*4]
- jmp L_dodist
-
-ALIGN 4
-L_clip_window:
-; 721 "inffast.S"
- mov ecx,eax
- mov eax, [esp+52]
- neg ecx
- mov esi, [esp+56]
-
- cmp eax,edx
- jb L_invalid_distance_too_far
-
- add ecx,edx
- cmp dword ptr [esp+48],0
- jne L_wrap_around_window
-
- sub eax,ecx
- add esi,eax
-; 749 "inffast.S"
- mov eax, [esp+24]
- cmp eax,ecx
- jbe L_do_copy1
-
- sub eax,ecx
- rep movsb
- mov esi,edi
- sub esi,edx
- jmp L_do_copy1
-
- cmp eax,ecx
- jbe L_do_copy1
-
- sub eax,ecx
- rep movsb
- mov esi,edi
- sub esi,edx
- jmp L_do_copy1
-
-L_wrap_around_window:
-; 793 "inffast.S"
- mov eax, [esp+48]
- cmp ecx,eax
- jbe L_contiguous_in_window
-
- add esi, [esp+52]
- add esi,eax
- sub esi,ecx
- sub ecx,eax
-
-
- mov eax, [esp+24]
- cmp eax,ecx
- jbe L_do_copy1
-
- sub eax,ecx
- rep movsb
- mov esi, [esp+56]
- mov ecx, [esp+48]
- cmp eax,ecx
- jbe L_do_copy1
-
- sub eax,ecx
- rep movsb
- mov esi,edi
- sub esi,edx
- jmp L_do_copy1
-
-L_contiguous_in_window:
-; 836 "inffast.S"
- add esi,eax
- sub esi,ecx
-
-
- mov eax, [esp+24]
- cmp eax,ecx
- jbe L_do_copy1
-
- sub eax,ecx
- rep movsb
- mov esi,edi
- sub esi,edx
-
-L_do_copy1:
-; 862 "inffast.S"
- mov ecx,eax
- rep movsb
-
- mov esi, [esp+44]
- jmp L_while_test
-; 878 "inffast.S"
-ALIGN 4
-L_init_mmx:
- emms
-
-
-
-
-
- movd mm0,ebp
- mov ebp,ebx
-; 896 "inffast.S"
- movd mm4,[esp+0]
- movq mm3,mm4
- movd mm5,[esp+4]
- movq mm2,mm5
- pxor mm1,mm1
- mov ebx, [esp+8]
- jmp L_do_loop_mmx
-
-ALIGN 4
-L_do_loop_mmx:
- psrlq mm0,mm1
-
- cmp ebp,32
- ja L_get_length_code_mmx
-
- movd mm6,ebp
- movd mm7,[esi]
- add esi,4
- psllq mm7,mm6
- add ebp,32
- por mm0,mm7
-
-L_get_length_code_mmx:
- pand mm4,mm0
- movd eax,mm4
- movq mm4,mm3
- mov eax, [ebx+eax*4]
-
-L_dolen_mmx:
- movzx ecx,ah
- movd mm1,ecx
- sub ebp,ecx
-
- test al,al
- jnz L_test_for_length_base_mmx
-
- shr eax,16
- stosb
-
-L_while_test_mmx:
-
-
- cmp [esp+16],edi
- jbe L_break_loop
-
- cmp [esp+20],esi
- ja L_do_loop_mmx
- jmp L_break_loop
-
-L_test_for_length_base_mmx:
-
- mov edx,eax
- shr edx,16
-
- test al,16
- jz L_test_for_second_level_length_mmx
- and eax,15
- jz L_decode_distance_mmx
-
- psrlq mm0,mm1
- movd mm1,eax
- movd ecx,mm0
- sub ebp,eax
- and ecx, [inflate_fast_mask+eax*4]
- add edx,ecx
-
-L_decode_distance_mmx:
- psrlq mm0,mm1
-
- cmp ebp,32
- ja L_get_dist_code_mmx
-
- movd mm6,ebp
- movd mm7,[esi]
- add esi,4
- psllq mm7,mm6
- add ebp,32
- por mm0,mm7
-
-L_get_dist_code_mmx:
- mov ebx, [esp+12]
- pand mm5,mm0
- movd eax,mm5
- movq mm5,mm2
- mov eax, [ebx+eax*4]
-
-L_dodist_mmx:
-
- movzx ecx,ah
- mov ebx,eax
- shr ebx,16
- sub ebp,ecx
- movd mm1,ecx
-
- test al,16
- jz L_test_for_second_level_dist_mmx
- and eax,15
- jz L_check_dist_one_mmx
-
-L_add_bits_to_dist_mmx:
- psrlq mm0,mm1
- movd mm1,eax
- movd ecx,mm0
- sub ebp,eax
- and ecx, [inflate_fast_mask+eax*4]
- add ebx,ecx
-
-L_check_window_mmx:
- mov [esp+44],esi
- mov eax,edi
- sub eax, [esp+40]
-
- cmp eax,ebx
- jb L_clip_window_mmx
-
- mov ecx,edx
- mov esi,edi
- sub esi,ebx
-
- sub ecx,3
- mov al, [esi]
- mov [edi],al
- mov al, [esi+1]
- mov dl, [esi+2]
- add esi,3
- mov [edi+1],al
- mov [edi+2],dl
- add edi,3
- rep movsb
-
- mov esi, [esp+44]
- mov ebx, [esp+8]
- jmp L_while_test_mmx
-
-ALIGN 4
-L_check_dist_one_mmx:
- cmp ebx,1
- jne L_check_window_mmx
- cmp [esp+40],edi
- je L_check_window_mmx
-
- dec edi
- mov ecx,edx
- mov al, [edi]
- sub ecx,3
-
- mov [edi+1],al
- mov [edi+2],al
- mov [edi+3],al
- add edi,4
- rep stosb
-
- mov ebx, [esp+8]
- jmp L_while_test_mmx
-
-ALIGN 4
-L_test_for_second_level_length_mmx:
- test al,64
- jnz L_test_for_end_of_block
-
- and eax,15
- psrlq mm0,mm1
- movd ecx,mm0
- and ecx, [inflate_fast_mask+eax*4]
- add ecx,edx
- mov eax, [ebx+ecx*4]
- jmp L_dolen_mmx
-
-ALIGN 4
-L_test_for_second_level_dist_mmx:
- test al,64
- jnz L_invalid_distance_code
-
- and eax,15
- psrlq mm0,mm1
- movd ecx,mm0
- and ecx, [inflate_fast_mask+eax*4]
- mov eax, [esp+12]
- add ecx,ebx
- mov eax, [eax+ecx*4]
- jmp L_dodist_mmx
-
-ALIGN 4
-L_clip_window_mmx:
-
- mov ecx,eax
- mov eax, [esp+52]
- neg ecx
- mov esi, [esp+56]
-
- cmp eax,ebx
- jb L_invalid_distance_too_far
-
- add ecx,ebx
- cmp dword ptr [esp+48],0
- jne L_wrap_around_window_mmx
-
- sub eax,ecx
- add esi,eax
-
- cmp edx,ecx
- jbe L_do_copy1_mmx
-
- sub edx,ecx
- rep movsb
- mov esi,edi
- sub esi,ebx
- jmp L_do_copy1_mmx
-
- cmp edx,ecx
- jbe L_do_copy1_mmx
-
- sub edx,ecx
- rep movsb
- mov esi,edi
- sub esi,ebx
- jmp L_do_copy1_mmx
-
-L_wrap_around_window_mmx:
-
- mov eax, [esp+48]
- cmp ecx,eax
- jbe L_contiguous_in_window_mmx
-
- add esi, [esp+52]
- add esi,eax
- sub esi,ecx
- sub ecx,eax
-
-
- cmp edx,ecx
- jbe L_do_copy1_mmx
-
- sub edx,ecx
- rep movsb
- mov esi, [esp+56]
- mov ecx, [esp+48]
- cmp edx,ecx
- jbe L_do_copy1_mmx
-
- sub edx,ecx
- rep movsb
- mov esi,edi
- sub esi,ebx
- jmp L_do_copy1_mmx
-
-L_contiguous_in_window_mmx:
-
- add esi,eax
- sub esi,ecx
-
-
- cmp edx,ecx
- jbe L_do_copy1_mmx
-
- sub edx,ecx
- rep movsb
- mov esi,edi
- sub esi,ebx
-
-L_do_copy1_mmx:
-
-
- mov ecx,edx
- rep movsb
-
- mov esi, [esp+44]
- mov ebx, [esp+8]
- jmp L_while_test_mmx
-; 1174 "inffast.S"
-L_invalid_distance_code:
-
-
-
-
-
- mov ecx, invalid_distance_code_msg
- mov edx,26
- jmp L_update_stream_state
-
-L_test_for_end_of_block:
-
-
-
-
-
- test al,32
- jz L_invalid_literal_length_code
-
- mov ecx,0
- mov edx,11
- jmp L_update_stream_state
-
-L_invalid_literal_length_code:
-
-
-
-
-
- mov ecx, invalid_literal_length_code_msg
- mov edx,26
- jmp L_update_stream_state
-
-L_invalid_distance_too_far:
-
-
-
- mov esi, [esp+44]
- mov ecx, invalid_distance_too_far_msg
- mov edx,26
- jmp L_update_stream_state
-
-L_update_stream_state:
-
- mov eax, [esp+88]
- test ecx,ecx
- jz L_skip_msg
- mov [eax+24],ecx
-L_skip_msg:
- mov eax, [eax+28]
- mov [eax+mode_state],edx
- jmp L_break_loop
-
-ALIGN 4
-L_break_loop:
-; 1243 "inffast.S"
- cmp dword ptr [inflate_fast_use_mmx],2
- jne L_update_next_in
-
-
-
- mov ebx,ebp
-
-L_update_next_in:
-; 1266 "inffast.S"
- mov eax, [esp+88]
- mov ecx,ebx
- mov edx, [eax+28]
- shr ecx,3
- sub esi,ecx
- shl ecx,3
- sub ebx,ecx
- mov [eax+12],edi
- mov [edx+bits_state],ebx
- mov ecx,ebx
-
- lea ebx, [esp+28]
- cmp [esp+20],ebx
- jne L_buf_not_used
-
- sub esi,ebx
- mov ebx, [eax+0]
- mov [esp+20],ebx
- add esi,ebx
- mov ebx, [eax+4]
- sub ebx,11
- add [esp+20],ebx
-
-L_buf_not_used:
- mov [eax+0],esi
-
- mov ebx,1
- shl ebx,cl
- dec ebx
-
-
-
-
-
- cmp dword ptr [inflate_fast_use_mmx],2
- jne L_update_hold
-
-
-
- psrlq mm0,mm1
- movd ebp,mm0
-
- emms
-
-L_update_hold:
-
-
-
- and ebp,ebx
- mov [edx+hold_state],ebp
-
-
-
-
- mov ebx, [esp+20]
- cmp ebx,esi
- jbe L_last_is_smaller
-
- sub ebx,esi
- add ebx,11
- mov [eax+4],ebx
- jmp L_fixup_out
-L_last_is_smaller:
- sub esi,ebx
- neg esi
- add esi,11
- mov [eax+4],esi
-
-
-
-
-L_fixup_out:
-
- mov ebx, [esp+16]
- cmp ebx,edi
- jbe L_end_is_smaller
-
- sub ebx,edi
- add ebx,257
- mov [eax+16],ebx
- jmp L_done
-L_end_is_smaller:
- sub edi,ebx
- neg edi
- add edi,257
- mov [eax+16],edi
-
-
-
-
-
-L_done:
- add esp,64
- popfd
- pop ebx
- pop ebp
- pop esi
- pop edi
- ret
-
-
-
-
-_TEXT ends
-end
diff --git a/cpukit/zlib/contrib/masmx86/mkasm.bat b/cpukit/zlib/contrib/masmx86/mkasm.bat
deleted file mode 100755
index 70a51f8377..0000000000
--- a/cpukit/zlib/contrib/masmx86/mkasm.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-cl /DASMV /I..\.. /O2 /c gvmat32c.c
-ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm
-ml /coff /Zi /c /Flinffas32.lst inffas32.asm
diff --git a/cpukit/zlib/contrib/masmx86/readme.txt b/cpukit/zlib/contrib/masmx86/readme.txt
deleted file mode 100644
index 7b57167b71..0000000000
--- a/cpukit/zlib/contrib/masmx86/readme.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-
-Summary
--------
-This directory contains ASM implementations of the functions
-longest_match() and inflate_fast().
-
-
-Use instructions
-----------------
-Copy these files into the zlib source directory, then run the
-appropriate makefile, as suggested below.
-
-
-Build instructions
-------------------
-* With Microsoft C and MASM:
-nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" OBJA="gvmat32c.obj gvmat32.obj inffas32.obj"
-
-* With Borland C and TASM:
-make -f win32/Makefile.bor LOCAL_ZLIB="-DASMV -DASMINF" OBJA="gvmat32c.obj gvmat32.obj inffas32.obj" OBJPA="+gvmat32c.obj+gvmat32.obj+inffas32.obj"
-
diff --git a/cpukit/zlib/contrib/minizip/ChangeLogUnzip b/cpukit/zlib/contrib/minizip/ChangeLogUnzip
deleted file mode 100644
index 4be4d16249..0000000000
--- a/cpukit/zlib/contrib/minizip/ChangeLogUnzip
+++ /dev/null
@@ -1,63 +0,0 @@
-Change in 1.01b (20 may 04)
-- Integrate patch from Debian package (submited by Mark Brown)
-- Add tools mztools from Xavier Roche
-
-Change in 1.01 (8 may 04)
-- fix buffer overrun risk in unzip.c (Xavier Roche)
-- fix a minor buffer insecurity in minizip.c (Mike Whittaker)
-
-Change in 1.00: (10 sept 03)
-- rename to 1.00
-- cosmetic code change
-
-Change in 0.22: (19 May 03)
-- crypting support (unless you define NOCRYPT)
-- append file in existing zipfile
-
-Change in 0.21: (10 Mar 03)
-- bug fixes
-
-Change in 0.17: (27 Jan 02)
-- bug fixes
-
-Change in 0.16: (19 Jan 02)
-- Support of ioapi for virtualize zip file access
-
-Change in 0.15: (19 Mar 98)
-- fix memory leak in minizip.c
-
-Change in 0.14: (10 Mar 98)
-- fix bugs in minizip.c sample for zipping big file
-- fix problem in month in date handling
-- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for
- comment handling
-
-Change in 0.13: (6 Mar 98)
-- fix bugs in zip.c
-- add real minizip sample
-
-Change in 0.12: (4 Mar 98)
-- add zip.c and zip.h for creates .zip file
-- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly)
-- fix miniunz.c for file without specific record for directory
-
-Change in 0.11: (3 Mar 98)
-- fix bug in unzGetCurrentFileInfo for get extra field and comment
-- enhance miniunz sample, remove the bad unztst.c sample
-
-Change in 0.10: (2 Mar 98)
-- fix bug in unzReadCurrentFile
-- rename unzip* to unz* function and structure
-- remove Windows-like hungary notation variable name
-- modify some structure in unzip.h
-- add somes comment in source
-- remove unzipGetcCurrentFile function
-- replace ZUNZEXPORT by ZEXPORT
-- add unzGetLocalExtrafield for get the local extrafield info
-- add a new sample, miniunz.c
-
-Change in 0.4: (25 Feb 98)
-- suppress the type unzipFileInZip.
- Only on file in the zipfile can be open at the same time
-- fix somes typo in code
-- added tm_unz structure in unzip_file_info (date/time in readable format)
diff --git a/cpukit/zlib/contrib/minizip/Makefile b/cpukit/zlib/contrib/minizip/Makefile
deleted file mode 100644
index 84eaad20d4..0000000000
--- a/cpukit/zlib/contrib/minizip/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-CC=cc
-CFLAGS=-O -I../..
-
-UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a
-ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a
-
-.c.o:
- $(CC) -c $(CFLAGS) $*.c
-
-all: miniunz minizip
-
-miniunz: $(UNZ_OBJS)
- $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS)
-
-minizip: $(ZIP_OBJS)
- $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)
-
-test: miniunz minizip
- ./minizip test readme.txt
- ./miniunz -l test.zip
- mv readme.txt readme.old
- ./miniunz test.zip
-
-clean:
- /bin/rm -f *.o *~ minizip miniunz
diff --git a/cpukit/zlib/contrib/minizip/crypt.h b/cpukit/zlib/contrib/minizip/crypt.h
deleted file mode 100644
index 7f8a634280..0000000000
--- a/cpukit/zlib/contrib/minizip/crypt.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* crypt.h -- base code for crypt/uncrypt ZIPfile
-
-
- Version 1.01, May 8th, 2004
-
- Copyright (C) 1998-2004 Gilles Vollant
-
- This code is a modified version of crypting code in Infozip distribution
-
- The encryption/decryption parts of this source code (as opposed to the
- non-echoing password parts) were originally written in Europe. The
- whole source package can be freely distributed, including from the USA.
- (Prior to January 2000, re-export from the US was a violation of US law.)
-
- This encryption code is a direct transcription of the algorithm from
- Roger Schlafly, described by Phil Katz in the file appnote.txt. This
- file (appnote.txt) is distributed with the PKZIP program (even in the
- version without encryption capabilities).
-
- If you don't need crypting in your application, just define symbols
- NOCRYPT and NOUNCRYPT.
-
- This code support the "Traditional PKWARE Encryption".
-
- The new AES encryption added on Zip format by Winzip (see the page
- http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
- Encryption is not supported.
-*/
-
-#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
-
-/***********************************************************************
- * Return the next byte in the pseudo-random sequence
- */
-static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
-{
- unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
- * unpredictable manner on 16-bit systems; not a problem
- * with any known compiler so far, though */
-
- temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
- return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
-}
-
-/***********************************************************************
- * Update the encryption keys with the next byte of plain text
- */
-static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
-{
- (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
- (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
- (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
- {
- register int keyshift = (int)((*(pkeys+1)) >> 24);
- (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
- }
- return c;
-}
-
-
-/***********************************************************************
- * Initialize the encryption keys and the random header according to
- * the given password.
- */
-static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
-{
- *(pkeys+0) = 305419896L;
- *(pkeys+1) = 591751049L;
- *(pkeys+2) = 878082192L;
- while (*passwd != '\0') {
- update_keys(pkeys,pcrc_32_tab,(int)*passwd);
- passwd++;
- }
-}
-
-#define zdecode(pkeys,pcrc_32_tab,c) \
- (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
-
-#define zencode(pkeys,pcrc_32_tab,c,t) \
- (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
-
-#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-
-#define RAND_HEAD_LEN 12
- /* "last resort" source for second part of crypt seed pattern */
-# ifndef ZCR_SEED2
-# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
-# endif
-
-static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
- const char *passwd; /* password string */
- unsigned char *buf; /* where to write header */
- int bufSize;
- unsigned long* pkeys;
- const unsigned long* pcrc_32_tab;
- unsigned long crcForCrypting;
-{
- int n; /* index in random header */
- int t; /* temporary */
- int c; /* random byte */
- unsigned char header[RAND_HEAD_LEN-2]; /* random header */
- static unsigned calls = 0; /* ensure different random header each time */
-
- if (bufSize<RAND_HEAD_LEN)
- return 0;
-
- /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
- * output of rand() to get less predictability, since rand() is
- * often poorly implemented.
- */
- if (++calls == 1)
- {
- srand((unsigned)(time(NULL) ^ ZCR_SEED2));
- }
- init_keys(passwd, pkeys, pcrc_32_tab);
- for (n = 0; n < RAND_HEAD_LEN-2; n++)
- {
- c = (rand() >> 7) & 0xff;
- header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
- }
- /* Encrypt random header (last two bytes is high word of crc) */
- init_keys(passwd, pkeys, pcrc_32_tab);
- for (n = 0; n < RAND_HEAD_LEN-2; n++)
- {
- buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
- }
- buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
- buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
- return n;
-}
-
-#endif
diff --git a/cpukit/zlib/contrib/minizip/ioapi.c b/cpukit/zlib/contrib/minizip/ioapi.c
deleted file mode 100644
index c9e69f27ca..0000000000
--- a/cpukit/zlib/contrib/minizip/ioapi.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* ioapi.c -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
-
- Version 1.01, May 8th, 2004
-
- Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "zlib.h"
-#include "ioapi.h"
-
-
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-voidpf ZCALLBACK fopen_file_func OF((
- voidpf opaque,
- const char* filename,
- int mode));
-
-uLong ZCALLBACK fread_file_func OF((
- voidpf opaque,
- voidpf stream,
- void* buf,
- uLong size));
-
-uLong ZCALLBACK fwrite_file_func OF((
- voidpf opaque,
- voidpf stream,
- const void* buf,
- uLong size));
-
-long ZCALLBACK ftell_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-long ZCALLBACK fseek_file_func OF((
- voidpf opaque,
- voidpf stream,
- uLong offset,
- int origin));
-
-int ZCALLBACK fclose_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-int ZCALLBACK ferror_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-
-voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
- voidpf opaque;
- const char* filename;
- int mode;
-{
- FILE* file = NULL;
- const char* mode_fopen = NULL;
- if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
- mode_fopen = "rb";
- else
- if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
- mode_fopen = "r+b";
- else
- if (mode & ZLIB_FILEFUNC_MODE_CREATE)
- mode_fopen = "wb";
-
- if ((filename!=NULL) && (mode_fopen != NULL))
- file = fopen(filename, mode_fopen);
- return file;
-}
-
-
-uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- void* buf;
- uLong size;
-{
- uLong ret;
- ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
- return ret;
-}
-
-
-uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- const void* buf;
- uLong size;
-{
- uLong ret;
- ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
- return ret;
-}
-
-long ZCALLBACK ftell_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- long ret;
- ret = ftell((FILE *)stream);
- return ret;
-}
-
-long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
- voidpf opaque;
- voidpf stream;
- uLong offset;
- int origin;
-{
- int fseek_origin=0;
- long ret;
- switch (origin)
- {
- case ZLIB_FILEFUNC_SEEK_CUR :
- fseek_origin = SEEK_CUR;
- break;
- case ZLIB_FILEFUNC_SEEK_END :
- fseek_origin = SEEK_END;
- break;
- case ZLIB_FILEFUNC_SEEK_SET :
- fseek_origin = SEEK_SET;
- break;
- default: return -1;
- }
- ret = 0;
- fseek((FILE *)stream, offset, fseek_origin);
- return ret;
-}
-
-int ZCALLBACK fclose_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret;
- ret = fclose((FILE *)stream);
- return ret;
-}
-
-int ZCALLBACK ferror_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret;
- ret = ferror((FILE *)stream);
- return ret;
-}
-
-void fill_fopen_filefunc (pzlib_filefunc_def)
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- pzlib_filefunc_def->zopen_file = fopen_file_func;
- pzlib_filefunc_def->zread_file = fread_file_func;
- pzlib_filefunc_def->zwrite_file = fwrite_file_func;
- pzlib_filefunc_def->ztell_file = ftell_file_func;
- pzlib_filefunc_def->zseek_file = fseek_file_func;
- pzlib_filefunc_def->zclose_file = fclose_file_func;
- pzlib_filefunc_def->zerror_file = ferror_file_func;
- pzlib_filefunc_def->opaque = NULL;
-}
diff --git a/cpukit/zlib/contrib/minizip/ioapi.h b/cpukit/zlib/contrib/minizip/ioapi.h
deleted file mode 100644
index b76116178a..0000000000
--- a/cpukit/zlib/contrib/minizip/ioapi.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
-
- Version 1.01, May 8th, 2004
-
- Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-#ifndef _ZLIBIOAPI_H
-#define _ZLIBIOAPI_H
-
-
-#define ZLIB_FILEFUNC_SEEK_CUR (1)
-#define ZLIB_FILEFUNC_SEEK_END (2)
-#define ZLIB_FILEFUNC_SEEK_SET (0)
-
-#define ZLIB_FILEFUNC_MODE_READ (1)
-#define ZLIB_FILEFUNC_MODE_WRITE (2)
-#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
-
-#define ZLIB_FILEFUNC_MODE_EXISTING (4)
-#define ZLIB_FILEFUNC_MODE_CREATE (8)
-
-
-#ifndef ZCALLBACK
-
-#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
-#define ZCALLBACK CALLBACK
-#else
-#define ZCALLBACK
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
-typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
-typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
-typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
-
-typedef struct zlib_filefunc_def_s
-{
- open_file_func zopen_file;
- read_file_func zread_file;
- write_file_func zwrite_file;
- tell_file_func ztell_file;
- seek_file_func zseek_file;
- close_file_func zclose_file;
- testerror_file_func zerror_file;
- voidpf opaque;
-} zlib_filefunc_def;
-
-
-
-void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
-#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
-#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
-#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
-#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
-#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/cpukit/zlib/contrib/minizip/iowin32.c b/cpukit/zlib/contrib/minizip/iowin32.c
deleted file mode 100644
index 940dc0b498..0000000000
--- a/cpukit/zlib/contrib/minizip/iowin32.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* iowin32.c -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
- This IO API version uses the Win32 API (for Microsoft Windows)
-
- Version 1.01, May 8th, 2004
-
- Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-#include <stdlib.h>
-
-#include "zlib.h"
-#include "ioapi.h"
-#include "iowin32.h"
-
-#ifndef INVALID_HANDLE_VALUE
-#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
-#endif
-
-#ifndef INVALID_SET_FILE_POINTER
-#define INVALID_SET_FILE_POINTER ((DWORD)-1)
-#endif
-
-voidpf ZCALLBACK win32_open_file_func OF((
- voidpf opaque,
- const char* filename,
- int mode));
-
-uLong ZCALLBACK win32_read_file_func OF((
- voidpf opaque,
- voidpf stream,
- void* buf,
- uLong size));
-
-uLong ZCALLBACK win32_write_file_func OF((
- voidpf opaque,
- voidpf stream,
- const void* buf,
- uLong size));
-
-long ZCALLBACK win32_tell_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-long ZCALLBACK win32_seek_file_func OF((
- voidpf opaque,
- voidpf stream,
- uLong offset,
- int origin));
-
-int ZCALLBACK win32_close_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-int ZCALLBACK win32_error_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-typedef struct
-{
- HANDLE hf;
- int error;
-} WIN32FILE_IOWIN;
-
-voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode)
- voidpf opaque;
- const char* filename;
- int mode;
-{
- const char* mode_fopen = NULL;
- DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
- HANDLE hFile = 0;
- voidpf ret=NULL;
-
- dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0;
-
- if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
- {
- dwDesiredAccess = GENERIC_READ;
- dwCreationDisposition = OPEN_EXISTING;
- dwShareMode = FILE_SHARE_READ;
- }
- else
- if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
- {
- dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
- dwCreationDisposition = OPEN_EXISTING;
- }
- else
- if (mode & ZLIB_FILEFUNC_MODE_CREATE)
- {
- dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
- dwCreationDisposition = CREATE_ALWAYS;
- }
-
- if ((filename!=NULL) && (dwDesiredAccess != 0))
- hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL,
- dwCreationDisposition, dwFlagsAndAttributes, NULL);
-
- if (hFile == INVALID_HANDLE_VALUE)
- hFile = NULL;
-
- if (hFile != NULL)
- {
- WIN32FILE_IOWIN w32fiow;
- w32fiow.hf = hFile;
- w32fiow.error = 0;
- ret = malloc(sizeof(WIN32FILE_IOWIN));
- if (ret==NULL)
- CloseHandle(hFile);
- else *((WIN32FILE_IOWIN*)ret) = w32fiow;
- }
- return ret;
-}
-
-
-uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- void* buf;
- uLong size;
-{
- uLong ret=0;
- HANDLE hFile = NULL;
- if (stream!=NULL)
- hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
- if (hFile != NULL)
- if (!ReadFile(hFile, buf, size, &ret, NULL))
- {
- DWORD dwErr = GetLastError();
- if (dwErr == ERROR_HANDLE_EOF)
- dwErr = 0;
- ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
- }
-
- return ret;
-}
-
-
-uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- const void* buf;
- uLong size;
-{
- uLong ret=0;
- HANDLE hFile = NULL;
- if (stream!=NULL)
- hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-
- if (hFile !=NULL)
- if (!WriteFile(hFile, buf, size, &ret, NULL))
- {
- DWORD dwErr = GetLastError();
- if (dwErr == ERROR_HANDLE_EOF)
- dwErr = 0;
- ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
- }
-
- return ret;
-}
-
-long ZCALLBACK win32_tell_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- long ret=-1;
- HANDLE hFile = NULL;
- if (stream!=NULL)
- hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
- if (hFile != NULL)
- {
- DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
- if (dwSet == INVALID_SET_FILE_POINTER)
- {
- DWORD dwErr = GetLastError();
- ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
- ret = -1;
- }
- else
- ret=(long)dwSet;
- }
- return ret;
-}
-
-long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin)
- voidpf opaque;
- voidpf stream;
- uLong offset;
- int origin;
-{
- DWORD dwMoveMethod=0xFFFFFFFF;
- HANDLE hFile = NULL;
-
- long ret=-1;
- if (stream!=NULL)
- hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
- switch (origin)
- {
- case ZLIB_FILEFUNC_SEEK_CUR :
- dwMoveMethod = FILE_CURRENT;
- break;
- case ZLIB_FILEFUNC_SEEK_END :
- dwMoveMethod = FILE_END;
- break;
- case ZLIB_FILEFUNC_SEEK_SET :
- dwMoveMethod = FILE_BEGIN;
- break;
- default: return -1;
- }
-
- if (hFile != NULL)
- {
- DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
- if (dwSet == INVALID_SET_FILE_POINTER)
- {
- DWORD dwErr = GetLastError();
- ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
- ret = -1;
- }
- else
- ret=0;
- }
- return ret;
-}
-
-int ZCALLBACK win32_close_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret=-1;
-
- if (stream!=NULL)
- {
- HANDLE hFile;
- hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
- if (hFile != NULL)
- {
- CloseHandle(hFile);
- ret=0;
- }
- free(stream);
- }
- return ret;
-}
-
-int ZCALLBACK win32_error_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret=-1;
- if (stream!=NULL)
- {
- ret = ((WIN32FILE_IOWIN*)stream) -> error;
- }
- return ret;
-}
-
-void fill_win32_filefunc (pzlib_filefunc_def)
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- pzlib_filefunc_def->zopen_file = win32_open_file_func;
- pzlib_filefunc_def->zread_file = win32_read_file_func;
- pzlib_filefunc_def->zwrite_file = win32_write_file_func;
- pzlib_filefunc_def->ztell_file = win32_tell_file_func;
- pzlib_filefunc_def->zseek_file = win32_seek_file_func;
- pzlib_filefunc_def->zclose_file = win32_close_file_func;
- pzlib_filefunc_def->zerror_file = win32_error_file_func;
- pzlib_filefunc_def->opaque=NULL;
-}
diff --git a/cpukit/zlib/contrib/minizip/iowin32.h b/cpukit/zlib/contrib/minizip/iowin32.h
deleted file mode 100644
index 8774fe7406..0000000000
--- a/cpukit/zlib/contrib/minizip/iowin32.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* iowin32.h -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
- This IO API version uses the Win32 API (for Microsoft Windows)
-
- Version 1.01, May 8th, 2004
-
- Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-#include <windows.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/cpukit/zlib/contrib/minizip/miniunz.c b/cpukit/zlib/contrib/minizip/miniunz.c
deleted file mode 100644
index a6b06a2082..0000000000
--- a/cpukit/zlib/contrib/minizip/miniunz.c
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- miniunz.c
- Version 1.01b, May 30th, 2004
-
- Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef unix
-# include <unistd.h>
-# include <utime.h>
-#else
-# include <direct.h>
-# include <io.h>
-#endif
-
-#include "unzip.h"
-
-#define CASESENSITIVITY (0)
-#define WRITEBUFFERSIZE (8192)
-#define MAXFILENAME (256)
-
-#ifdef WIN32
-#define USEWIN32IOAPI
-#include "iowin32.h"
-#endif
-/*
- mini unzip, demo of unzip package
-
- usage :
- Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
-
- list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
- if it exists
-*/
-
-
-/* change_file_date : change the date/time of a file
- filename : the filename of the file where date/time must be modified
- dosdate : the new date at the MSDos format (4 bytes)
- tmu_date : the SAME new date at the tm_unz format */
-void change_file_date(filename,dosdate,tmu_date)
- const char *filename;
- uLong dosdate;
- tm_unz tmu_date;
-{
-#ifdef WIN32
- HANDLE hFile;
- FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
-
- hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE,
- 0,NULL,OPEN_EXISTING,0,NULL);
- GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
- DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
- LocalFileTimeToFileTime(&ftLocal,&ftm);
- SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
- CloseHandle(hFile);
-#else
-#ifdef unix
- struct utimbuf ut;
- struct tm newdate;
- newdate.tm_sec = tmu_date.tm_sec;
- newdate.tm_min=tmu_date.tm_min;
- newdate.tm_hour=tmu_date.tm_hour;
- newdate.tm_mday=tmu_date.tm_mday;
- newdate.tm_mon=tmu_date.tm_mon;
- if (tmu_date.tm_year > 1900)
- newdate.tm_year=tmu_date.tm_year - 1900;
- else
- newdate.tm_year=tmu_date.tm_year ;
- newdate.tm_isdst=-1;
-
- ut.actime=ut.modtime=mktime(&newdate);
- utime(filename,&ut);
-#endif
-#endif
-}
-
-
-/* mymkdir and change_file_date are not 100 % portable
- As I don't know well Unix, I wait feedback for the unix portion */
-
-int mymkdir(dirname)
- const char* dirname;
-{
- int ret=0;
-#ifdef WIN32
- ret = mkdir(dirname);
-#else
-#ifdef unix
- ret = mkdir (dirname,0775);
-#endif
-#endif
- return ret;
-}
-
-int makedir (newdir)
- char *newdir;
-{
- char *buffer ;
- char *p;
- int len = (int)strlen(newdir);
-
- if (len <= 0)
- return 0;
-
- buffer = (char*)malloc(len+1);
- strcpy(buffer,newdir);
-
- if (buffer[len-1] == '/') {
- buffer[len-1] = '\0';
- }
- if (mymkdir(buffer) == 0)
- {
- free(buffer);
- return 1;
- }
-
- p = buffer+1;
- while (1)
- {
- char hold;
-
- while(*p && *p != '\\' && *p != '/')
- p++;
- hold = *p;
- *p = 0;
- if ((mymkdir(buffer) == -1) && (errno == ENOENT))
- {
- printf("couldn't create directory %s\n",buffer);
- free(buffer);
- return 0;
- }
- if (hold == 0)
- break;
- *p++ = hold;
- }
- free(buffer);
- return 1;
-}
-
-void do_banner()
-{
- printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
- printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
-}
-
-void do_help()
-{
- printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
- " -e Extract without pathname (junk paths)\n" \
- " -x Extract with pathname\n" \
- " -v list files\n" \
- " -l list files\n" \
- " -d directory to extract into\n" \
- " -o overwrite files without prompting\n" \
- " -p extract crypted file using password\n\n");
-}
-
-
-int do_list(uf)
- unzFile uf;
-{
- uLong i;
- unz_global_info gi;
- int err;
-
- err = unzGetGlobalInfo (uf,&gi);
- if (err!=UNZ_OK)
- printf("error %d with zipfile in unzGetGlobalInfo \n",err);
- printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
- printf(" ------ ------ ---- ----- ---- ---- ------ ----\n");
- for (i=0;i<gi.number_entry;i++)
- {
- char filename_inzip[256];
- unz_file_info file_info;
- uLong ratio=0;
- const char *string_method;
- char charCrypt=' ';
- err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
- break;
- }
- if (file_info.uncompressed_size>0)
- ratio = (file_info.compressed_size*100)/file_info.uncompressed_size;
-
- /* display a '*' if the file is crypted */
- if ((file_info.flag & 1) != 0)
- charCrypt='*';
-
- if (file_info.compression_method==0)
- string_method="Stored";
- else
- if (file_info.compression_method==Z_DEFLATED)
- {
- uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
- if (iLevel==0)
- string_method="Defl:N";
- else if (iLevel==1)
- string_method="Defl:X";
- else if ((iLevel==2) || (iLevel==3))
- string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
- }
- else
- string_method="Unkn. ";
-
- printf("%7lu %6s%c%7lu %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
- file_info.uncompressed_size,string_method,
- charCrypt,
- file_info.compressed_size,
- ratio,
- (uLong)file_info.tmu_date.tm_mon + 1,
- (uLong)file_info.tmu_date.tm_mday,
- (uLong)file_info.tmu_date.tm_year % 100,
- (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
- (uLong)file_info.crc,filename_inzip);
- if ((i+1)<gi.number_entry)
- {
- err = unzGoToNextFile(uf);
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzGoToNextFile\n",err);
- break;
- }
- }
- }
-
- return 0;
-}
-
-
-int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
- unzFile uf;
- const int* popt_extract_without_path;
- int* popt_overwrite;
- const char* password;
-{
- char filename_inzip[256];
- char* filename_withoutpath;
- char* p;
- int err=UNZ_OK;
- FILE *fout=NULL;
- void* buf;
- uInt size_buf;
-
- unz_file_info file_info;
- uLong ratio=0;
- err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
-
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
- return err;
- }
-
- size_buf = WRITEBUFFERSIZE;
- buf = (void*)malloc(size_buf);
- if (buf==NULL)
- {
- printf("Error allocating memory\n");
- return UNZ_INTERNALERROR;
- }
-
- p = filename_withoutpath = filename_inzip;
- while ((*p) != '\0')
- {
- if (((*p)=='/') || ((*p)=='\\'))
- filename_withoutpath = p+1;
- p++;
- }
-
- if ((*filename_withoutpath)=='\0')
- {
- if ((*popt_extract_without_path)==0)
- {
- printf("creating directory: %s\n",filename_inzip);
- mymkdir(filename_inzip);
- }
- }
- else
- {
- const char* write_filename;
- int skip=0;
-
- if ((*popt_extract_without_path)==0)
- write_filename = filename_inzip;
- else
- write_filename = filename_withoutpath;
-
- err = unzOpenCurrentFilePassword(uf,password);
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
- }
-
- if (((*popt_overwrite)==0) && (err==UNZ_OK))
- {
- char rep=0;
- FILE* ftestexist;
- ftestexist = fopen(write_filename,"rb");
- if (ftestexist!=NULL)
- {
- fclose(ftestexist);
- do
- {
- char answer[128];
- int ret;
-
- printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
- ret = scanf("%1s",answer);
- if (ret != 1)
- {
- exit(EXIT_FAILURE);
- }
- rep = answer[0] ;
- if ((rep>='a') && (rep<='z'))
- rep -= 0x20;
- }
- while ((rep!='Y') && (rep!='N') && (rep!='A'));
- }
-
- if (rep == 'N')
- skip = 1;
-
- if (rep == 'A')
- *popt_overwrite=1;
- }
-
- if ((skip==0) && (err==UNZ_OK))
- {
- fout=fopen(write_filename,"wb");
-
- /* some zipfile don't contain directory alone before file */
- if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
- (filename_withoutpath!=(char*)filename_inzip))
- {
- char c=*(filename_withoutpath-1);
- *(filename_withoutpath-1)='\0';
- makedir(write_filename);
- *(filename_withoutpath-1)=c;
- fout=fopen(write_filename,"wb");
- }
-
- if (fout==NULL)
- {
- printf("error opening %s\n",write_filename);
- }
- }
-
- if (fout!=NULL)
- {
- printf(" extracting: %s\n",write_filename);
-
- do
- {
- err = unzReadCurrentFile(uf,buf,size_buf);
- if (err<0)
- {
- printf("error %d with zipfile in unzReadCurrentFile\n",err);
- break;
- }
- if (err>0)
- if (fwrite(buf,err,1,fout)!=1)
- {
- printf("error in writing extracted file\n");
- err=UNZ_ERRNO;
- break;
- }
- }
- while (err>0);
- if (fout)
- fclose(fout);
-
- if (err==0)
- change_file_date(write_filename,file_info.dosDate,
- file_info.tmu_date);
- }
-
- if (err==UNZ_OK)
- {
- err = unzCloseCurrentFile (uf);
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzCloseCurrentFile\n",err);
- }
- }
- else
- unzCloseCurrentFile(uf); /* don't lose the error */
- }
-
- free(buf);
- return err;
-}
-
-
-int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
- unzFile uf;
- int opt_extract_without_path;
- int opt_overwrite;
- const char* password;
-{
- uLong i;
- unz_global_info gi;
- int err;
- FILE* fout=NULL;
-
- err = unzGetGlobalInfo (uf,&gi);
- if (err!=UNZ_OK)
- printf("error %d with zipfile in unzGetGlobalInfo \n",err);
-
- for (i=0;i<gi.number_entry;i++)
- {
- if (do_extract_currentfile(uf,&opt_extract_without_path,
- &opt_overwrite,
- password) != UNZ_OK)
- break;
-
- if ((i+1)<gi.number_entry)
- {
- err = unzGoToNextFile(uf);
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzGoToNextFile\n",err);
- break;
- }
- }
- }
-
- return 0;
-}
-
-int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
- unzFile uf;
- const char* filename;
- int opt_extract_without_path;
- int opt_overwrite;
- const char* password;
-{
- int err = UNZ_OK;
- if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
- {
- printf("file %s not found in the zipfile\n",filename);
- return 2;
- }
-
- if (do_extract_currentfile(uf,&opt_extract_without_path,
- &opt_overwrite,
- password) == UNZ_OK)
- return 0;
- else
- return 1;
-}
-
-
-int main(argc,argv)
- int argc;
- char *argv[];
-{
- const char *zipfilename=NULL;
- const char *filename_to_extract=NULL;
- const char *password=NULL;
- char filename_try[MAXFILENAME+16] = "";
- int i;
- int opt_do_list=0;
- int opt_do_extract=1;
- int opt_do_extract_withoutpath=0;
- int opt_overwrite=0;
- int opt_extractdir=0;
- const char *dirname=NULL;
- unzFile uf=NULL;
-
- do_banner();
- if (argc==1)
- {
- do_help();
- return 0;
- }
- else
- {
- for (i=1;i<argc;i++)
- {
- if ((*argv[i])=='-')
- {
- const char *p=argv[i]+1;
-
- while ((*p)!='\0')
- {
- char c=*(p++);;
- if ((c=='l') || (c=='L'))
- opt_do_list = 1;
- if ((c=='v') || (c=='V'))
- opt_do_list = 1;
- if ((c=='x') || (c=='X'))
- opt_do_extract = 1;
- if ((c=='e') || (c=='E'))
- opt_do_extract = opt_do_extract_withoutpath = 1;
- if ((c=='o') || (c=='O'))
- opt_overwrite=1;
- if ((c=='d') || (c=='D'))
- {
- opt_extractdir=1;
- dirname=argv[i+1];
- }
-
- if (((c=='p') || (c=='P')) && (i+1<argc))
- {
- password=argv[i+1];
- i++;
- }
- }
- }
- else
- {
- if (zipfilename == NULL)
- zipfilename = argv[i];
- else if ((filename_to_extract==NULL) && (!opt_extractdir))
- filename_to_extract = argv[i] ;
- }
- }
- }
-
- if (zipfilename!=NULL)
- {
-
-# ifdef USEWIN32IOAPI
- zlib_filefunc_def ffunc;
-# endif
-
- strncpy(filename_try, zipfilename,MAXFILENAME-1);
- /* strncpy doesnt append the trailing NULL, of the string is too long. */
- filename_try[ MAXFILENAME ] = '\0';
-
-# ifdef USEWIN32IOAPI
- fill_win32_filefunc(&ffunc);
- uf = unzOpen2(zipfilename,&ffunc);
-# else
- uf = unzOpen(zipfilename);
-# endif
- if (uf==NULL)
- {
- strcat(filename_try,".zip");
-# ifdef USEWIN32IOAPI
- uf = unzOpen2(filename_try,&ffunc);
-# else
- uf = unzOpen(filename_try);
-# endif
- }
- }
-
- if (uf==NULL)
- {
- printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
- return 1;
- }
- printf("%s opened\n",filename_try);
-
- if (opt_do_list==1)
- return do_list(uf);
- else if (opt_do_extract==1)
- {
- if (opt_extractdir && chdir(dirname))
- {
- printf("Error changing into %s, aborting\n", dirname);
- exit(-1);
- }
-
- if (filename_to_extract == NULL)
- return do_extract(uf,opt_do_extract_withoutpath,opt_overwrite,password);
- else
- return do_extract_onefile(uf,filename_to_extract,
- opt_do_extract_withoutpath,opt_overwrite,password);
- }
- unzCloseCurrentFile(uf);
-
- return 0;
-}
diff --git a/cpukit/zlib/contrib/minizip/minizip.c b/cpukit/zlib/contrib/minizip/minizip.c
deleted file mode 100644
index 918c32225c..0000000000
--- a/cpukit/zlib/contrib/minizip/minizip.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- minizip.c
- Version 1.01b, May 30th, 2004
-
- Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef unix
-# include <unistd.h>
-# include <utime.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-#else
-# include <direct.h>
-# include <io.h>
-#endif
-
-#include "zip.h"
-
-#ifdef WIN32
-#define USEWIN32IOAPI
-#include "iowin32.h"
-#endif
-
-
-
-#define WRITEBUFFERSIZE (16384)
-#define MAXFILENAME (256)
-
-#ifdef WIN32
-uLong filetime(f, tmzip, dt)
- char *f; /* name of file to get info on */
- tm_zip *tmzip; /* return value: access, modific. and creation times */
- uLong *dt; /* dostime */
-{
- int ret = 0;
- {
- FILETIME ftLocal;
- HANDLE hFind;
- WIN32_FIND_DATA ff32;
-
- hFind = FindFirstFile(f,&ff32);
- if (hFind != INVALID_HANDLE_VALUE)
- {
- FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
- FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
- FindClose(hFind);
- ret = 1;
- }
- }
- return ret;
-}
-#else
-#ifdef unix
-uLong filetime(f, tmzip, dt)
- char *f; /* name of file to get info on */
- tm_zip *tmzip; /* return value: access, modific. and creation times */
- uLong *dt; /* dostime */
-{
- int ret=0;
- struct stat s; /* results of stat() */
- struct tm* filedate;
- time_t tm_t=0;
-
- if (strcmp(f,"-")!=0)
- {
- char name[MAXFILENAME+1];
- int len = strlen(f);
- if (len > MAXFILENAME)
- len = MAXFILENAME;
-
- strncpy(name, f,MAXFILENAME-1);
- /* strncpy doesnt append the trailing NULL, of the string is too long. */
- name[ MAXFILENAME ] = '\0';
-
- if (name[len - 1] == '/')
- name[len - 1] = '\0';
- /* not all systems allow stat'ing a file with / appended */
- if (stat(name,&s)==0)
- {
- tm_t = s.st_mtime;
- ret = 1;
- }
- }
- filedate = localtime(&tm_t);
-
- tmzip->tm_sec = filedate->tm_sec;
- tmzip->tm_min = filedate->tm_min;
- tmzip->tm_hour = filedate->tm_hour;
- tmzip->tm_mday = filedate->tm_mday;
- tmzip->tm_mon = filedate->tm_mon ;
- tmzip->tm_year = filedate->tm_year;
-
- return ret;
-}
-#else
-uLong filetime(f, tmzip, dt)
- char *f; /* name of file to get info on */
- tm_zip *tmzip; /* return value: access, modific. and creation times */
- uLong *dt; /* dostime */
-{
- return 0;
-}
-#endif
-#endif
-
-
-
-
-int check_exist_file(filename)
- const char* filename;
-{
- FILE* ftestexist;
- int ret = 1;
- ftestexist = fopen(filename,"rb");
- if (ftestexist==NULL)
- ret = 0;
- else
- fclose(ftestexist);
- return ret;
-}
-
-void do_banner()
-{
- printf("MiniZip 1.01b, demo of zLib + Zip package written by Gilles Vollant\n");
- printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
-}
-
-void do_help()
-{
- printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] file.zip [files_to_add]\n\n" \
- " -o Overwrite existing file.zip\n" \
- " -a Append to existing file.zip\n" \
- " -0 Store only\n" \
- " -1 Compress faster\n" \
- " -9 Compress better\n\n");
-}
-
-/* calculate the CRC32 of a file,
- because to encrypt a file, we need known the CRC32 of the file before */
-int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
-{
- unsigned long calculate_crc=0;
- int err=ZIP_OK;
- FILE * fin = fopen(filenameinzip,"rb");
- unsigned long size_read = 0;
- unsigned long total_read = 0;
- if (fin==NULL)
- {
- err = ZIP_ERRNO;
- }
-
- if (err == ZIP_OK)
- do
- {
- err = ZIP_OK;
- size_read = (int)fread(buf,1,size_buf,fin);
- if (size_read < size_buf)
- if (feof(fin)==0)
- {
- printf("error in reading %s\n",filenameinzip);
- err = ZIP_ERRNO;
- }
-
- if (size_read>0)
- calculate_crc = crc32(calculate_crc,buf,size_read);
- total_read += size_read;
-
- } while ((err == ZIP_OK) && (size_read>0));
-
- if (fin)
- fclose(fin);
-
- *result_crc=calculate_crc;
- printf("file %s crc %x\n",filenameinzip,calculate_crc);
- return err;
-}
-
-int main(argc,argv)
- int argc;
- char *argv[];
-{
- int i;
- int opt_overwrite=0;
- int opt_compress_level=Z_DEFAULT_COMPRESSION;
- int zipfilenamearg = 0;
- char filename_try[MAXFILENAME+16];
- int zipok;
- int err=0;
- int size_buf=0;
- void* buf=NULL;
- const char* password=NULL;
-
-
- do_banner();
- if (argc==1)
- {
- do_help();
- return 0;
- }
- else
- {
- for (i=1;i<argc;i++)
- {
- if ((*argv[i])=='-')
- {
- const char *p=argv[i]+1;
-
- while ((*p)!='\0')
- {
- char c=*(p++);;
- if ((c=='o') || (c=='O'))
- opt_overwrite = 1;
- if ((c=='a') || (c=='A'))
- opt_overwrite = 2;
- if ((c>='0') && (c<='9'))
- opt_compress_level = c-'0';
-
- if (((c=='p') || (c=='P')) && (i+1<argc))
- {
- password=argv[i+1];
- i++;
- }
- }
- }
- else
- if (zipfilenamearg == 0)
- zipfilenamearg = i ;
- }
- }
-
- size_buf = WRITEBUFFERSIZE;
- buf = (void*)malloc(size_buf);
- if (buf==NULL)
- {
- printf("Error allocating memory\n");
- return ZIP_INTERNALERROR;
- }
-
- if (zipfilenamearg==0)
- zipok=0;
- else
- {
- int i,len;
- int dot_found=0;
-
- zipok = 1 ;
- strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
- /* strncpy doesnt append the trailing NULL, of the string is too long. */
- filename_try[ MAXFILENAME ] = '\0';
-
- len=(int)strlen(filename_try);
- for (i=0;i<len;i++)
- if (filename_try[i]=='.')
- dot_found=1;
-
- if (dot_found==0)
- strcat(filename_try,".zip");
-
- if (opt_overwrite==2)
- {
- /* if the file don't exist, we not append file */
- if (check_exist_file(filename_try)==0)
- opt_overwrite=1;
- }
- else
- if (opt_overwrite==0)
- if (check_exist_file(filename_try)!=0)
- {
- char rep=0;
- do
- {
- char answer[128];
- int ret;
- printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
- ret = scanf("%1s",answer);
- if (ret != 1)
- {
- exit(EXIT_FAILURE);
- }
- rep = answer[0] ;
- if ((rep>='a') && (rep<='z'))
- rep -= 0x20;
- }
- while ((rep!='Y') && (rep!='N') && (rep!='A'));
- if (rep=='N')
- zipok = 0;
- if (rep=='A')
- opt_overwrite = 2;
- }
- }
-
- if (zipok==1)
- {
- zipFile zf;
- int errclose;
-# ifdef USEWIN32IOAPI
- zlib_filefunc_def ffunc;
- fill_win32_filefunc(&ffunc);
- zf = zipOpen2(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
-# else
- zf = zipOpen(filename_try,(opt_overwrite==2) ? 2 : 0);
-# endif
-
- if (zf == NULL)
- {
- printf("error opening %s\n",filename_try);
- err= ZIP_ERRNO;
- }
- else
- printf("creating %s\n",filename_try);
-
- for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
- {
- if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
- ((argv[i][1]=='o') || (argv[i][1]=='O') ||
- (argv[i][1]=='a') || (argv[i][1]=='A') ||
- (argv[i][1]=='p') || (argv[i][1]=='P') ||
- ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
- (strlen(argv[i]) == 2)))
- {
- FILE * fin;
- int size_read;
- const char* filenameinzip = argv[i];
- zip_fileinfo zi;
- unsigned long crcFile=0;
-
- zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
- zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
- zi.dosDate = 0;
- zi.internal_fa = 0;
- zi.external_fa = 0;
- filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
-
-/*
- err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
- NULL,0,NULL,0,NULL / * comment * /,
- (opt_compress_level != 0) ? Z_DEFLATED : 0,
- opt_compress_level);
-*/
- if ((password != NULL) && (err==ZIP_OK))
- err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
-
- err = zipOpenNewFileInZip3(zf,filenameinzip,&zi,
- NULL,0,NULL,0,NULL /* comment*/,
- (opt_compress_level != 0) ? Z_DEFLATED : 0,
- opt_compress_level,0,
- /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
- -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
- password,crcFile);
-
- if (err != ZIP_OK)
- printf("error in opening %s in zipfile\n",filenameinzip);
- else
- {
- fin = fopen(filenameinzip,"rb");
- if (fin==NULL)
- {
- err=ZIP_ERRNO;
- printf("error in opening %s for reading\n",filenameinzip);
- }
- }
-
- if (err == ZIP_OK)
- do
- {
- err = ZIP_OK;
- size_read = (int)fread(buf,1,size_buf,fin);
- if (size_read < size_buf)
- if (feof(fin)==0)
- {
- printf("error in reading %s\n",filenameinzip);
- err = ZIP_ERRNO;
- }
-
- if (size_read>0)
- {
- err = zipWriteInFileInZip (zf,buf,size_read);
- if (err<0)
- {
- printf("error in writing %s in the zipfile\n",
- filenameinzip);
- }
-
- }
- } while ((err == ZIP_OK) && (size_read>0));
-
- if (fin)
- fclose(fin);
-
- if (err<0)
- err=ZIP_ERRNO;
- else
- {
- err = zipCloseFileInZip(zf);
- if (err!=ZIP_OK)
- printf("error in closing %s in the zipfile\n",
- filenameinzip);
- }
- }
- }
- errclose = zipClose(zf,NULL);
- if (errclose != ZIP_OK)
- printf("error in closing %s\n",filename_try);
- }
- else
- {
- do_help();
- }
-
- free(buf);
- return 0;
-}
diff --git a/cpukit/zlib/contrib/minizip/mztools.c b/cpukit/zlib/contrib/minizip/mztools.c
deleted file mode 100644
index c1266bc6c8..0000000000
--- a/cpukit/zlib/contrib/minizip/mztools.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- Additional tools for Minizip
- Code: Xavier Roche '2004
- License: Same as ZLIB (www.gzip.org)
-*/
-
-/* Code */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "zlib.h"
-#include "unzip.h"
-
-#define READ_8(adr) ((unsigned char)*(adr))
-#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
-#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
-
-#define WRITE_8(buff, n) do { \
- *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
-} while(0)
-#define WRITE_16(buff, n) do { \
- WRITE_8((unsigned char*)(buff), n); \
- WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
-} while(0)
-#define WRITE_32(buff, n) do { \
- WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
- WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
-} while(0)
-
-extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
-const char* file;
-const char* fileOut;
-const char* fileOutTmp;
-uLong* nRecovered;
-uLong* bytesRecovered;
-{
- int err = Z_OK;
- FILE* fpZip = fopen(file, "rb");
- FILE* fpOut = fopen(fileOut, "wb");
- FILE* fpOutCD = fopen(fileOutTmp, "wb");
- if (fpZip != NULL && fpOut != NULL) {
- int entries = 0;
- uLong totalBytes = 0;
- char header[30];
- char filename[256];
- char extra[1024];
- int offset = 0;
- int offsetCD = 0;
- while ( fread(header, 1, 30, fpZip) == 30 ) {
- int currentOffset = offset;
-
- /* File entry */
- if (READ_32(header) == 0x04034b50) {
- unsigned int version = READ_16(header + 4);
- unsigned int gpflag = READ_16(header + 6);
- unsigned int method = READ_16(header + 8);
- unsigned int filetime = READ_16(header + 10);
- unsigned int filedate = READ_16(header + 12);
- unsigned int crc = READ_32(header + 14); /* crc */
- unsigned int cpsize = READ_32(header + 18); /* compressed size */
- unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
- unsigned int fnsize = READ_16(header + 26); /* file name length */
- unsigned int extsize = READ_16(header + 28); /* extra field length */
- filename[0] = extra[0] = '\0';
-
- /* Header */
- if (fwrite(header, 1, 30, fpOut) == 30) {
- offset += 30;
- } else {
- err = Z_ERRNO;
- break;
- }
-
- /* Filename */
- if (fnsize > 0) {
- if (fread(filename, 1, fnsize, fpZip) == fnsize) {
- if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
- offset += fnsize;
- } else {
- err = Z_ERRNO;
- break;
- }
- } else {
- err = Z_ERRNO;
- break;
- }
- } else {
- err = Z_STREAM_ERROR;
- break;
- }
-
- /* Extra field */
- if (extsize > 0) {
- if (fread(extra, 1, extsize, fpZip) == extsize) {
- if (fwrite(extra, 1, extsize, fpOut) == extsize) {
- offset += extsize;
- } else {
- err = Z_ERRNO;
- break;
- }
- } else {
- err = Z_ERRNO;
- break;
- }
- }
-
- /* Data */
- {
- int dataSize = cpsize;
- if (dataSize == 0) {
- dataSize = uncpsize;
- }
- if (dataSize > 0) {
- char* data = malloc(dataSize);
- if (data != NULL) {
- if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
- if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
- offset += dataSize;
- totalBytes += dataSize;
- } else {
- err = Z_ERRNO;
- }
- } else {
- err = Z_ERRNO;
- }
- free(data);
- if (err != Z_OK) {
- break;
- }
- } else {
- err = Z_MEM_ERROR;
- break;
- }
- }
- }
-
- /* Central directory entry */
- {
- char header[46];
- char* comment = "";
- int comsize = (int) strlen(comment);
- WRITE_32(header, 0x02014b50);
- WRITE_16(header + 4, version);
- WRITE_16(header + 6, version);
- WRITE_16(header + 8, gpflag);
- WRITE_16(header + 10, method);
- WRITE_16(header + 12, filetime);
- WRITE_16(header + 14, filedate);
- WRITE_32(header + 16, crc);
- WRITE_32(header + 20, cpsize);
- WRITE_32(header + 24, uncpsize);
- WRITE_16(header + 28, fnsize);
- WRITE_16(header + 30, extsize);
- WRITE_16(header + 32, comsize);
- WRITE_16(header + 34, 0); /* disk # */
- WRITE_16(header + 36, 0); /* int attrb */
- WRITE_32(header + 38, 0); /* ext attrb */
- WRITE_32(header + 42, currentOffset);
- /* Header */
- if (fwrite(header, 1, 46, fpOutCD) == 46) {
- offsetCD += 46;
-
- /* Filename */
- if (fnsize > 0) {
- if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
- offsetCD += fnsize;
- } else {
- err = Z_ERRNO;
- break;
- }
- } else {
- err = Z_STREAM_ERROR;
- break;
- }
-
- /* Extra field */
- if (extsize > 0) {
- if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
- offsetCD += extsize;
- } else {
- err = Z_ERRNO;
- break;
- }
- }
-
- /* Comment field */
- if (comsize > 0) {
- if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
- offsetCD += comsize;
- } else {
- err = Z_ERRNO;
- break;
- }
- }
-
-
- } else {
- err = Z_ERRNO;
- break;
- }
- }
-
- /* Success */
- entries++;
-
- } else {
- break;
- }
- }
-
- /* Final central directory */
- {
- int entriesZip = entries;
- char header[22];
- char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
- int comsize = (int) strlen(comment);
- if (entriesZip > 0xffff) {
- entriesZip = 0xffff;
- }
- WRITE_32(header, 0x06054b50);
- WRITE_16(header + 4, 0); /* disk # */
- WRITE_16(header + 6, 0); /* disk # */
- WRITE_16(header + 8, entriesZip); /* hack */
- WRITE_16(header + 10, entriesZip); /* hack */
- WRITE_32(header + 12, offsetCD); /* size of CD */
- WRITE_32(header + 16, offset); /* offset to CD */
- WRITE_16(header + 20, comsize); /* comment */
-
- /* Header */
- if (fwrite(header, 1, 22, fpOutCD) == 22) {
-
- /* Comment field */
- if (comsize > 0) {
- if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
- err = Z_ERRNO;
- }
- }
-
- } else {
- err = Z_ERRNO;
- }
- }
-
- /* Final merge (file + central directory) */
- fclose(fpOutCD);
- if (err == Z_OK) {
- fpOutCD = fopen(fileOutTmp, "rb");
- if (fpOutCD != NULL) {
- int nRead;
- char buffer[8192];
- while ( (nRead = fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
- if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
- err = Z_ERRNO;
- break;
- }
- }
- fclose(fpOutCD);
- }
- }
-
- /* Close */
- fclose(fpZip);
- fclose(fpOut);
-
- /* Wipe temporary file */
- (void)remove(fileOutTmp);
-
- /* Number of recovered entries */
- if (err == Z_OK) {
- if (nRecovered != NULL) {
- *nRecovered = entries;
- }
- if (bytesRecovered != NULL) {
- *bytesRecovered = totalBytes;
- }
- }
- } else {
- err = Z_STREAM_ERROR;
- }
- return err;
-}
diff --git a/cpukit/zlib/contrib/minizip/mztools.h b/cpukit/zlib/contrib/minizip/mztools.h
deleted file mode 100644
index 88b34592bf..0000000000
--- a/cpukit/zlib/contrib/minizip/mztools.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- Additional tools for Minizip
- Code: Xavier Roche '2004
- License: Same as ZLIB (www.gzip.org)
-*/
-
-#ifndef _zip_tools_H
-#define _zip_tools_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#include "unzip.h"
-
-/* Repair a ZIP file (missing central directory)
- file: file to recover
- fileOut: output file after recovery
- fileOutTmp: temporary file name used for recovery
-*/
-extern int ZEXPORT unzRepair(const char* file,
- const char* fileOut,
- const char* fileOutTmp,
- uLong* nRecovered,
- uLong* bytesRecovered);
-
-#endif
diff --git a/cpukit/zlib/contrib/minizip/unzip.c b/cpukit/zlib/contrib/minizip/unzip.c
deleted file mode 100644
index e14de9e5ba..0000000000
--- a/cpukit/zlib/contrib/minizip/unzip.c
+++ /dev/null
@@ -1,1595 +0,0 @@
-/* unzip.c -- IO for uncompress .zip files using zlib
- Version 1.01d, September 22th, 2004
-
- Copyright (C) 1998-2004 Gilles Vollant
-
- Read unzip.h for more info
-*/
-
-/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
-compatibility with older software. The following is from the original crypt.c. Code
-woven in by Terry Thorsen 1/2003.
-*/
-/*
- Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
-
- See the accompanying file LICENSE, version 2000-Apr-09 or later
- (the contents of which are also included in zip.h) for terms of use.
- If, for some reason, all these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
-*/
-/*
- crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
-
- The encryption/decryption parts of this source code (as opposed to the
- non-echoing password parts) were originally written in Europe. The
- whole source package can be freely distributed, including from the USA.
- (Prior to January 2000, re-export from the US was a violation of US law.)
- */
-
-/*
- This encryption code is a direct transcription of the algorithm from
- Roger Schlafly, described by Phil Katz in the file appnote.txt. This
- file (appnote.txt) is distributed with the PKZIP program (even in the
- version without encryption capabilities).
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "zlib.h"
-#include "unzip.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-
-#ifndef CASESENSITIVITYDEFAULT_NO
-# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
-# define CASESENSITIVITYDEFAULT_NO
-# endif
-#endif
-
-
-#ifndef UNZ_BUFSIZE
-#define UNZ_BUFSIZE (16384)
-#endif
-
-#ifndef UNZ_MAXFILENAMEINZIP
-#define UNZ_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-
-
-
-
-const char unz_copyright[] =
- " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-/* unz_file_info_interntal contain internal info about a file in zipfile*/
-typedef struct unz_file_info_internal_s
-{
- uLong offset_curfile;/* relative offset of local header 4 bytes */
-} unz_file_info_internal;
-
-
-/* file_in_zip_read_info_s contain internal information about a file in zipfile,
- when reading and decompress it */
-typedef struct
-{
- char *read_buffer; /* internal buffer for compressed data */
- z_stream stream; /* zLib stream structure for inflate */
-
- uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
- uLong stream_initialised; /* flag set if stream structure is initialised*/
-
- uLong offset_local_extrafield;/* offset of the local extra field */
- uInt size_local_extrafield;/* size of the local extra field */
- uLong pos_local_extrafield; /* position in the local extra field in read*/
-
- uLong crc32; /* crc32 of all data uncompressed */
- uLong crc32_wait; /* crc32 we must obtain after decompress all */
- uLong rest_read_compressed; /* number of byte to be decompressed */
- uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- uLong compression_method; /* compression method (0==store) */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
- int raw;
-} file_in_zip_read_info_s;
-
-
-/* unz_s contain internal information about the zipfile
-*/
-typedef struct
-{
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- unz_global_info gi; /* public global information */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
- uLong num_file; /* number of the current file in the zipfile*/
- uLong pos_in_central_dir; /* pos of the current file in the central dir*/
- uLong current_file_ok; /* flag about the usability of the current file*/
- uLong central_pos; /* position of the beginning of the central dir*/
-
- uLong size_central_dir; /* size of the central directory */
- uLong offset_central_dir; /* offset of start of central directory with
- respect to the starting disk number */
-
- unz_file_info cur_file_info; /* public info about the current file in zip*/
- unz_file_info_internal cur_file_info_internal; /* private info about it*/
- file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
- file if we are decompressing it */
- int encrypted;
-# ifndef NOUNCRYPT
- unsigned long keys[3]; /* keys defining the pseudo-random sequence */
- const unsigned long* pcrc_32_tab;
-# endif
-} unz_s;
-
-
-#ifndef NOUNCRYPT
-#include "crypt.h"
-#endif
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-
-
-local int unzlocal_getByte OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- int *pi));
-
-local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- int *pi;
-{
- unsigned char c;
- int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
- if (err==1)
- {
- *pi = (int)c;
- return UNZ_OK;
- }
- else
- {
- if (ZERROR(*pzlib_filefunc_def,filestream))
- return UNZ_ERRNO;
- else
- return UNZ_EOF;
- }
-}
-
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int unzlocal_getShort OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-local int unzlocal_getLong OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<16;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<24;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-
-/* My own strcmpi / strcasecmp */
-local int strcmpcasenosensitive_internal (fileName1,fileName2)
- const char* fileName1;
- const char* fileName2;
-{
- for (;;)
- {
- char c1=*(fileName1++);
- char c2=*(fileName2++);
- if ((c1>='a') && (c1<='z'))
- c1 -= 0x20;
- if ((c2>='a') && (c2<='z'))
- c2 -= 0x20;
- if (c1=='\0')
- return ((c2=='\0') ? 0 : -1);
- if (c2=='\0')
- return 1;
- if (c1<c2)
- return -1;
- if (c1>c2)
- return 1;
- }
-}
-
-
-#ifdef CASESENSITIVITYDEFAULT_NO
-#define CASESENSITIVITYDEFAULTVALUE 2
-#else
-#define CASESENSITIVITYDEFAULTVALUE 1
-#endif
-
-#ifndef STRCMPCASENOSENTIVEFUNCTION
-#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
-#endif
-
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-
-*/
-extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
- const char* fileName1;
- const char* fileName2;
- int iCaseSensitivity;
-{
- if (iCaseSensitivity==0)
- iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
-
- if (iCaseSensitivity==1)
- return strcmp(fileName1,fileName2);
-
- return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-
-/*
- Locate the Central directory of a zipfile (at the end, just before
- the global comment)
-*/
-local uLong unzlocal_SearchCentralDir OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream));
-
-local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
-{
- unsigned char* buf;
- uLong uSizeFile;
- uLong uBackRead;
- uLong uMaxBack=0xffff; /* maximum size of global comment */
- uLong uPosFound=0;
-
- if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
- return 0;
-
-
- uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
-
- if (uMaxBack>uSizeFile)
- uMaxBack = uSizeFile;
-
- buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
- if (buf==NULL)
- return 0;
-
- uBackRead = 4;
- while (uBackRead<uMaxBack)
- {
- uLong uReadSize,uReadPos ;
- int i;
- if (uBackRead+BUFREADCOMMENT>uMaxBack)
- uBackRead = uMaxBack;
- else
- uBackRead+=BUFREADCOMMENT;
- uReadPos = uSizeFile-uBackRead ;
-
- uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
- (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
- if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- break;
-
- if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
- break;
-
- for (i=(int)uReadSize-3; (i--)>0;)
- if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
- ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
- {
- uPosFound = uReadPos+i;
- break;
- }
-
- if (uPosFound!=0)
- break;
- }
- TRYFREE(buf);
- return uPosFound;
-}
-
-/*
- Open a Zip file. path contain the full pathname (by example,
- on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
- "zlib/zlib114.zip".
- If the zipfile cannot be opened (file doesn't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
- const char *path;
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- unz_s us;
- unz_s *s;
- uLong central_pos,uL;
-
- uLong number_disk; /* number of the current dist, used for
- spaning ZIP, unsupported, always 0*/
- uLong number_disk_with_CD; /* number the the disk with central dir, used
- for spaning ZIP, unsupported, always 0*/
- uLong number_entry_CD; /* total number of entries in
- the central dir
- (same than number_entry on nospan) */
-
- int err=UNZ_OK;
-
- if (unz_copyright[0]!=' ')
- return NULL;
-
- if (pzlib_filefunc_def==NULL)
- fill_fopen_filefunc(&us.z_filefunc);
- else
- us.z_filefunc = *pzlib_filefunc_def;
-
- us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
- path,
- ZLIB_FILEFUNC_MODE_READ |
- ZLIB_FILEFUNC_MODE_EXISTING);
- if (us.filestream==NULL)
- return NULL;
-
- central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
- if (central_pos==0)
- err=UNZ_ERRNO;
-
- if (ZSEEK(us.z_filefunc, us.filestream,
- central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
- /* the signature, already checked */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of this disk */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of the disk with the start of the central directory */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir on this disk */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((number_entry_CD!=us.gi.number_entry) ||
- (number_disk_with_CD!=0) ||
- (number_disk!=0))
- err=UNZ_BADZIPFILE;
-
- /* size of the central directory */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* offset of start of central directory with respect to the
- starting disk number */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* zipfile comment length */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
- (err==UNZ_OK))
- err=UNZ_BADZIPFILE;
-
- if (err!=UNZ_OK)
- {
- ZCLOSE(us.z_filefunc, us.filestream);
- return NULL;
- }
-
- us.byte_before_the_zipfile = central_pos -
- (us.offset_central_dir+us.size_central_dir);
- us.central_pos = central_pos;
- us.pfile_in_zip_read = NULL;
- us.encrypted = 0;
-
-
- s=(unz_s*)ALLOC(sizeof(unz_s));
- *s=us;
- unzGoToFirstFile((unzFile)s);
- return (unzFile)s;
-}
-
-
-extern unzFile ZEXPORT unzOpen (path)
- const char *path;
-{
- return unzOpen2(path, NULL);
-}
-
-/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzClose (file)
- unzFile file;
-{
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- if (s->pfile_in_zip_read!=NULL)
- unzCloseCurrentFile(file);
-
- ZCLOSE(s->z_filefunc, s->filestream);
- TRYFREE(s);
- return UNZ_OK;
-}
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
- unzFile file;
- unz_global_info *pglobal_info;
-{
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- *pglobal_info=s->gi;
- return UNZ_OK;
-}
-
-
-/*
- Translate date/time from Dos format to tm_unz (readable more easilty)
-*/
-local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
- uLong ulDosDate;
- tm_unz* ptm;
-{
- uLong uDate;
- uDate = (uLong)(ulDosDate>>16);
- ptm->tm_mday = (uInt)(uDate&0x1f) ;
- ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
- ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
-
- ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
- ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
- ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
-}
-
-/*
- Get Info about the current file in the zipfile, with internal only info
-*/
-local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
- unz_file_info *pfile_info,
- unz_file_info_internal
- *pfile_info_internal,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-
-local int unzlocal_GetCurrentFileInfoInternal (file,
- pfile_info,
- pfile_info_internal,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- unz_file_info_internal *pfile_info_internal;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- unz_s* s;
- unz_file_info file_info;
- unz_file_info_internal file_info_internal;
- int err=UNZ_OK;
- uLong uMagic;
- long lSeek=0;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (ZSEEK(s->z_filefunc, s->filestream,
- s->pos_in_central_dir+s->byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
-
- /* we check the magic */
- if (err==UNZ_OK)
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
- err=UNZ_ERRNO;
- else if (uMagic!=0x02014b50)
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
- err=UNZ_ERRNO;
-
- unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
- err=UNZ_ERRNO;
-
- lSeek+=file_info.size_filename;
- if ((err==UNZ_OK) && (szFileName!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_filename<fileNameBufferSize)
- {
- *(szFileName+file_info.size_filename)='\0';
- uSizeRead = file_info.size_filename;
- }
- else
- uSizeRead = fileNameBufferSize;
-
- if ((file_info.size_filename>0) && (fileNameBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek -= uSizeRead;
- }
-
-
- if ((err==UNZ_OK) && (extraField!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_extra<extraFieldBufferSize)
- uSizeRead = file_info.size_file_extra;
- else
- uSizeRead = extraFieldBufferSize;
-
- if (lSeek!=0)
- if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
- lSeek=0;
- else
- err=UNZ_ERRNO;
- if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek += file_info.size_file_extra - uSizeRead;
- }
- else
- lSeek+=file_info.size_file_extra;
-
-
- if ((err==UNZ_OK) && (szComment!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_comment<commentBufferSize)
- {
- *(szComment+file_info.size_file_comment)='\0';
- uSizeRead = file_info.size_file_comment;
- }
- else
- uSizeRead = commentBufferSize;
-
- if (lSeek!=0)
- if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
- lSeek=0;
- else
- err=UNZ_ERRNO;
- if ((file_info.size_file_comment>0) && (commentBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek+=file_info.size_file_comment - uSizeRead;
- }
- else
- lSeek+=file_info.size_file_comment;
-
- if ((err==UNZ_OK) && (pfile_info!=NULL))
- *pfile_info=file_info;
-
- if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
- *pfile_info_internal=file_info_internal;
-
- return err;
-}
-
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem.
-*/
-extern int ZEXPORT unzGetCurrentFileInfo (file,
- pfile_info,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
- szFileName,fileNameBufferSize,
- extraField,extraFieldBufferSize,
- szComment,commentBufferSize);
-}
-
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-extern int ZEXPORT unzGoToFirstFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- s->pos_in_central_dir=s->offset_central_dir;
- s->num_file=0;
- err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-extern int ZEXPORT unzGoToNextFile (file)
- unzFile file;
-{
- unz_s* s;
- int err;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
- if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
- if (s->num_file+1==s->gi.number_entry)
- return UNZ_END_OF_LIST_OF_FILE;
-
- s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
- s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
- s->num_file++;
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzipStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
- unzFile file;
- const char *szFileName;
- int iCaseSensitivity;
-{
- unz_s* s;
- int err;
-
- /* We remember the 'current' position in the file so that we can jump
- * back there if we fail.
- */
- unz_file_info cur_file_infoSaved;
- unz_file_info_internal cur_file_info_internalSaved;
- uLong num_fileSaved;
- uLong pos_in_central_dirSaved;
-
-
- if (file==NULL)
- return UNZ_PARAMERROR;
-
- if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
- return UNZ_PARAMERROR;
-
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
-
- /* Save the current state */
- num_fileSaved = s->num_file;
- pos_in_central_dirSaved = s->pos_in_central_dir;
- cur_file_infoSaved = s->cur_file_info;
- cur_file_info_internalSaved = s->cur_file_info_internal;
-
- err = unzGoToFirstFile(file);
-
- while (err == UNZ_OK)
- {
- char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
- err = unzGetCurrentFileInfo(file,NULL,
- szCurrentFileName,sizeof(szCurrentFileName)-1,
- NULL,0,NULL,0);
- if (err == UNZ_OK)
- {
- if (unzStringFileNameCompare(szCurrentFileName,
- szFileName,iCaseSensitivity)==0)
- return UNZ_OK;
- err = unzGoToNextFile(file);
- }
- }
-
- /* We failed, so restore the state of the 'current file' to where we
- * were.
- */
- s->num_file = num_fileSaved ;
- s->pos_in_central_dir = pos_in_central_dirSaved ;
- s->cur_file_info = cur_file_infoSaved;
- s->cur_file_info_internal = cur_file_info_internalSaved;
- return err;
-}
-
-
-/*
-///////////////////////////////////////////
-// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
-// I need random access
-//
-// Further optimization could be realized by adding an ability
-// to cache the directory in memory. The goal being a single
-// comprehensive file read to put the file I need in a memory.
-*/
-
-/*
-typedef struct unz_file_pos_s
-{
- uLong pos_in_zip_directory; // offset in file
- uLong num_of_file; // # of file
-} unz_file_pos;
-*/
-
-extern int ZEXPORT unzGetFilePos(file, file_pos)
- unzFile file;
- unz_file_pos* file_pos;
-{
- unz_s* s;
-
- if (file==NULL || file_pos==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
-
- file_pos->pos_in_zip_directory = s->pos_in_central_dir;
- file_pos->num_of_file = s->num_file;
-
- return UNZ_OK;
-}
-
-extern int ZEXPORT unzGoToFilePos(file, file_pos)
- unzFile file;
- unz_file_pos* file_pos;
-{
- unz_s* s;
- int err;
-
- if (file==NULL || file_pos==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- /* jump to the right spot */
- s->pos_in_central_dir = file_pos->pos_in_zip_directory;
- s->num_file = file_pos->num_of_file;
-
- /* set the current file */
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- /* return results */
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-/*
-// Unzip Helper Functions - should be here?
-///////////////////////////////////////////
-*/
-
-/*
- Read the local header of the current zipfile
- Check the coherency of the local header and info in the end of central
- directory about this file
- store in *piSizeVar the size of extra info in local header
- (filename and size of extra field data)
-*/
-local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
- poffset_local_extrafield,
- psize_local_extrafield)
- unz_s* s;
- uInt* piSizeVar;
- uLong *poffset_local_extrafield;
- uInt *psize_local_extrafield;
-{
- uLong uMagic,uData,uFlags;
- uLong size_filename;
- uLong size_extra_field;
- int err=UNZ_OK;
-
- *piSizeVar = 0;
- *poffset_local_extrafield = 0;
- *psize_local_extrafield = 0;
-
- if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
- s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
-
- if (err==UNZ_OK)
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
- err=UNZ_ERRNO;
- else if (uMagic!=0x04034b50)
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
-/*
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
- err=UNZ_BADZIPFILE;
-*/
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
- err=UNZ_BADZIPFILE;
-
- if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
- err=UNZ_BADZIPFILE;
-
- *piSizeVar += (uInt)size_filename;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
- err=UNZ_ERRNO;
- *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
- SIZEZIPLOCALHEADER + size_filename;
- *psize_local_extrafield = (uInt)size_extra_field;
-
- *piSizeVar += (uInt)size_extra_field;
-
- return err;
-}
-
-/*
- Open for reading data the current file in the zipfile.
- If there is no error and the file is opened, the return value is UNZ_OK.
-*/
-extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
- unzFile file;
- int* method;
- int* level;
- int raw;
- const char* password;
-{
- int err=UNZ_OK;
- uInt iSizeVar;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uLong offset_local_extrafield; /* offset of the local extra field */
- uInt size_local_extrafield; /* size of the local extra field */
-# ifndef NOUNCRYPT
- char source[12];
-# else
- if (password != NULL)
- return UNZ_PARAMERROR;
-# endif
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_PARAMERROR;
-
- if (s->pfile_in_zip_read != NULL)
- unzCloseCurrentFile(file);
-
- if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
- &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
- return UNZ_BADZIPFILE;
-
- pfile_in_zip_read_info = (file_in_zip_read_info_s*)
- ALLOC(sizeof(file_in_zip_read_info_s));
- if (pfile_in_zip_read_info==NULL)
- return UNZ_INTERNALERROR;
-
- pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
- pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
- pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
- pfile_in_zip_read_info->pos_local_extrafield=0;
- pfile_in_zip_read_info->raw=raw;
-
- if (pfile_in_zip_read_info->read_buffer==NULL)
- {
- TRYFREE(pfile_in_zip_read_info);
- return UNZ_INTERNALERROR;
- }
-
- pfile_in_zip_read_info->stream_initialised=0;
-
- if (method!=NULL)
- *method = (int)s->cur_file_info.compression_method;
-
- if (level!=NULL)
- {
- *level = 6;
- switch (s->cur_file_info.flag & 0x06)
- {
- case 6 : *level = 1; break;
- case 4 : *level = 2; break;
- case 2 : *level = 9; break;
- }
- }
-
- if ((s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- err=UNZ_BADZIPFILE;
-
- pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
- pfile_in_zip_read_info->crc32=0;
- pfile_in_zip_read_info->compression_method =
- s->cur_file_info.compression_method;
- pfile_in_zip_read_info->filestream=s->filestream;
- pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
- pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
-
- pfile_in_zip_read_info->stream.total_out = 0;
-
- if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
- (!raw))
- {
- pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
- pfile_in_zip_read_info->stream.zfree = (free_func)0;
- pfile_in_zip_read_info->stream.opaque = (voidpf)0;
- pfile_in_zip_read_info->stream.next_in = (voidpf)0;
- pfile_in_zip_read_info->stream.avail_in = 0;
-
- err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
- if (err == Z_OK)
- pfile_in_zip_read_info->stream_initialised=1;
- else
- return err;
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END.
- * In unzip, i don't wait absolutely Z_STREAM_END because I known the
- * size of both compressed and uncompressed data
- */
- }
- pfile_in_zip_read_info->rest_read_compressed =
- s->cur_file_info.compressed_size ;
- pfile_in_zip_read_info->rest_read_uncompressed =
- s->cur_file_info.uncompressed_size ;
-
-
- pfile_in_zip_read_info->pos_in_zipfile =
- s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
- iSizeVar;
-
- pfile_in_zip_read_info->stream.avail_in = (uInt)0;
-
- s->pfile_in_zip_read = pfile_in_zip_read_info;
-
-# ifndef NOUNCRYPT
- if (password != NULL)
- {
- int i;
- s->pcrc_32_tab = get_crc_table();
- init_keys(password,s->keys,s->pcrc_32_tab);
- if (ZSEEK(s->z_filefunc, s->filestream,
- s->pfile_in_zip_read->pos_in_zipfile +
- s->pfile_in_zip_read->byte_before_the_zipfile,
- SEEK_SET)!=0)
- return UNZ_INTERNALERROR;
- if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
- return UNZ_INTERNALERROR;
-
- for (i = 0; i<12; i++)
- zdecode(s->keys,s->pcrc_32_tab,source[i]);
-
- s->pfile_in_zip_read->pos_in_zipfile+=12;
- s->encrypted=1;
- }
-# endif
-
-
- return UNZ_OK;
-}
-
-extern int ZEXPORT unzOpenCurrentFile (file)
- unzFile file;
-{
- return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
-}
-
-extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
- unzFile file;
- const char* password;
-{
- return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
-}
-
-extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
- unzFile file;
- int* method;
- int* level;
- int raw;
-{
- return unzOpenCurrentFile3(file, method, level, raw, NULL);
-}
-
-/*
- Read bytes from the current file.
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-extern int ZEXPORT unzReadCurrentFile (file, buf, len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- int err=UNZ_OK;
- uInt iRead = 0;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if ((pfile_in_zip_read_info->read_buffer == NULL))
- return UNZ_END_OF_LIST_OF_FILE;
- if (len==0)
- return 0;
-
- pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
-
- pfile_in_zip_read_info->stream.avail_out = (uInt)len;
-
- if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
- (!(pfile_in_zip_read_info->raw)))
- pfile_in_zip_read_info->stream.avail_out =
- (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
-
- if ((len>pfile_in_zip_read_info->rest_read_compressed+
- pfile_in_zip_read_info->stream.avail_in) &&
- (pfile_in_zip_read_info->raw))
- pfile_in_zip_read_info->stream.avail_out =
- (uInt)pfile_in_zip_read_info->rest_read_compressed+
- pfile_in_zip_read_info->stream.avail_in;
-
- while (pfile_in_zip_read_info->stream.avail_out>0)
- {
- if ((pfile_in_zip_read_info->stream.avail_in==0) &&
- (pfile_in_zip_read_info->rest_read_compressed>0))
- {
- uInt uReadThis = UNZ_BUFSIZE;
- if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
- uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
- if (uReadThis == 0)
- return UNZ_EOF;
- if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->pos_in_zipfile +
- pfile_in_zip_read_info->byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
- if (ZREAD(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->read_buffer,
- uReadThis)!=uReadThis)
- return UNZ_ERRNO;
-
-
-# ifndef NOUNCRYPT
- if(s->encrypted)
- {
- uInt i;
- for(i=0;i<uReadThis;i++)
- pfile_in_zip_read_info->read_buffer[i] =
- zdecode(s->keys,s->pcrc_32_tab,
- pfile_in_zip_read_info->read_buffer[i]);
- }
-# endif
-
-
- pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
-
- pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
-
- pfile_in_zip_read_info->stream.next_in =
- (Bytef*)pfile_in_zip_read_info->read_buffer;
- pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
- }
-
- if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
- {
- uInt uDoCopy,i ;
-
- if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
- (pfile_in_zip_read_info->rest_read_compressed == 0))
- return (iRead==0) ? UNZ_EOF : iRead;
-
- if (pfile_in_zip_read_info->stream.avail_out <
- pfile_in_zip_read_info->stream.avail_in)
- uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
- else
- uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
-
- for (i=0;i<uDoCopy;i++)
- *(pfile_in_zip_read_info->stream.next_out+i) =
- *(pfile_in_zip_read_info->stream.next_in+i);
-
- pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
- pfile_in_zip_read_info->stream.next_out,
- uDoCopy);
- pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
- pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
- pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
- pfile_in_zip_read_info->stream.next_out += uDoCopy;
- pfile_in_zip_read_info->stream.next_in += uDoCopy;
- pfile_in_zip_read_info->stream.total_out += uDoCopy;
- iRead += uDoCopy;
- }
- else
- {
- uLong uTotalOutBefore,uTotalOutAfter;
- const Bytef *bufBefore;
- uLong uOutThis;
- int flush=Z_SYNC_FLUSH;
-
- uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
- bufBefore = pfile_in_zip_read_info->stream.next_out;
-
- /*
- if ((pfile_in_zip_read_info->rest_read_uncompressed ==
- pfile_in_zip_read_info->stream.avail_out) &&
- (pfile_in_zip_read_info->rest_read_compressed == 0))
- flush = Z_FINISH;
- */
- err=inflate(&pfile_in_zip_read_info->stream,flush);
-
- if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
- err = Z_DATA_ERROR;
-
- uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
- uOutThis = uTotalOutAfter-uTotalOutBefore;
-
- pfile_in_zip_read_info->crc32 =
- crc32(pfile_in_zip_read_info->crc32,bufBefore,
- (uInt)(uOutThis));
-
- pfile_in_zip_read_info->rest_read_uncompressed -=
- uOutThis;
-
- iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
-
- if (err==Z_STREAM_END)
- return (iRead==0) ? UNZ_EOF : iRead;
- if (err!=Z_OK)
- break;
- }
- }
-
- if (err==Z_OK)
- return iRead;
- return err;
-}
-
-
-/*
- Give the current position in uncompressed data
-*/
-extern z_off_t ZEXPORT unztell (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- return (z_off_t)pfile_in_zip_read_info->stream.total_out;
-}
-
-
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-extern int ZEXPORT unzeof (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
- return 1;
- else
- return 0;
-}
-
-
-
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field that can be read
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uInt read_now;
- uLong size_to_read;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
- pfile_in_zip_read_info->pos_local_extrafield);
-
- if (buf==NULL)
- return (int)size_to_read;
-
- if (len>size_to_read)
- read_now = (uInt)size_to_read;
- else
- read_now = (uInt)len ;
-
- if (read_now==0)
- return 0;
-
- if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->offset_local_extrafield +
- pfile_in_zip_read_info->pos_local_extrafield,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (ZREAD(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- buf,read_now)!=read_now)
- return UNZ_ERRNO;
-
- return (int)read_now;
-}
-
-/*
- Close the file in zip opened with unzipOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-extern int ZEXPORT unzCloseCurrentFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
-
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
- (!pfile_in_zip_read_info->raw))
- {
- if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
- err=UNZ_CRCERROR;
- }
-
-
- TRYFREE(pfile_in_zip_read_info->read_buffer);
- pfile_in_zip_read_info->read_buffer = NULL;
- if (pfile_in_zip_read_info->stream_initialised)
- inflateEnd(&pfile_in_zip_read_info->stream);
-
- pfile_in_zip_read_info->stream_initialised = 0;
- TRYFREE(pfile_in_zip_read_info);
-
- s->pfile_in_zip_read=NULL;
-
- return err;
-}
-
-
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
- unzFile file;
- char *szComment;
- uLong uSizeBuf;
-{
- int err=UNZ_OK;
- unz_s* s;
- uLong uReadThis ;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- uReadThis = uSizeBuf;
- if (uReadThis>s->gi.size_comment)
- uReadThis = s->gi.size_comment;
-
- if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (uReadThis>0)
- {
- *szComment='\0';
- if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
- return UNZ_ERRNO;
- }
-
- if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
- *(szComment+s->gi.size_comment)='\0';
- return (int)uReadThis;
-}
-
-/* Additions by RX '2004 */
-extern uLong ZEXPORT unzGetOffset (file)
- unzFile file;
-{
- unz_s* s;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return 0;
- if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
- if (s->num_file==s->gi.number_entry)
- return 0;
- return s->pos_in_central_dir;
-}
-
-extern int ZEXPORT unzSetOffset (file, pos)
- unzFile file;
- uLong pos;
-{
- unz_s* s;
- int err;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- s->pos_in_central_dir = pos;
- s->num_file = s->gi.number_entry; /* hack */
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
diff --git a/cpukit/zlib/contrib/minizip/unzip.h b/cpukit/zlib/contrib/minizip/unzip.h
deleted file mode 100644
index 0c7c6f143c..0000000000
--- a/cpukit/zlib/contrib/minizip/unzip.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/* unzip.h -- IO for uncompress .zip files using zlib
- Version 1.01, May 8th, 2004
-
- Copyright (C) 1998-2004 Gilles Vollant
-
- This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
- WinZip, InfoZip tools and compatible.
- Encryption and multi volume ZipFile (span) are not supported.
- Old compressions used by old PKZip 1.x are not supported
-
-
- I WAIT FEEDBACK at mail info@winimage.com
- Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
-
- Condition of use and distribution are the same than zlib :
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
-
-*/
-
-/* for more info about .ZIP format, see
- http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
- http://www.info-zip.org/pub/infozip/doc/
- PkWare has also a specification at :
- ftp://ftp.pkware.com/probdesc.zip
-*/
-
-#ifndef _unz_H
-#define _unz_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
-typedef struct TagunzFile__ { int unused; } unzFile__;
-typedef unzFile__ *unzFile;
-#else
-typedef voidp unzFile;
-#endif
-
-
-#define UNZ_OK (0)
-#define UNZ_END_OF_LIST_OF_FILE (-100)
-#define UNZ_ERRNO (Z_ERRNO)
-#define UNZ_EOF (0)
-#define UNZ_PARAMERROR (-102)
-#define UNZ_BADZIPFILE (-103)
-#define UNZ_INTERNALERROR (-104)
-#define UNZ_CRCERROR (-105)
-
-/* tm_unz contain date/time info */
-typedef struct tm_unz_s
-{
- uInt tm_sec; /* seconds after the minute - [0,59] */
- uInt tm_min; /* minutes after the hour - [0,59] */
- uInt tm_hour; /* hours since midnight - [0,23] */
- uInt tm_mday; /* day of the month - [1,31] */
- uInt tm_mon; /* months since January - [0,11] */
- uInt tm_year; /* years - [1980..2044] */
-} tm_unz;
-
-/* unz_global_info structure contain global data about the ZIPfile
- These data comes from the end of central dir */
-typedef struct unz_global_info_s
-{
- uLong number_entry; /* total number of entries in
- the central dir on this disk */
- uLong size_comment; /* size of the global comment of the zipfile */
-} unz_global_info;
-
-
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_info_s
-{
- uLong version; /* version made by 2 bytes */
- uLong version_needed; /* version needed to extract 2 bytes */
- uLong flag; /* general purpose bit flag 2 bytes */
- uLong compression_method; /* compression method 2 bytes */
- uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
- uLong crc; /* crc-32 4 bytes */
- uLong compressed_size; /* compressed size 4 bytes */
- uLong uncompressed_size; /* uncompressed size 4 bytes */
- uLong size_filename; /* filename length 2 bytes */
- uLong size_file_extra; /* extra field length 2 bytes */
- uLong size_file_comment; /* file comment length 2 bytes */
-
- uLong disk_num_start; /* disk number start 2 bytes */
- uLong internal_fa; /* internal file attributes 2 bytes */
- uLong external_fa; /* external file attributes 4 bytes */
-
- tm_unz tmu_date;
-} unz_file_info;
-
-extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
- const char* fileName2,
- int iCaseSensitivity));
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-*/
-
-
-extern unzFile ZEXPORT unzOpen OF((const char *path));
-/*
- Open a Zip file. path contain the full pathname (by example,
- on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
- "zlib/zlib113.zip".
- If the zipfile cannot be opened (file don't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-
-extern unzFile ZEXPORT unzOpen2 OF((const char *path,
- zlib_filefunc_def* pzlib_filefunc_def));
-/*
- Open a Zip file, like unzOpen, but provide a set of file low level API
- for read/write the zip file (see ioapi.h)
-*/
-
-extern int ZEXPORT unzClose OF((unzFile file));
-/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
- return UNZ_OK if there is no problem. */
-
-extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
- unz_global_info *pglobal_info));
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
-
-
-extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
- char *szComment,
- uLong uSizeBuf));
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-
-
-/***************************************************************************/
-/* Unzip package allow you browse the directory of the zipfile */
-
-extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-
-extern int ZEXPORT unzGoToNextFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-
-extern int ZEXPORT unzLocateFile OF((unzFile file,
- const char *szFileName,
- int iCaseSensitivity));
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-
-
-/* ****************************************** */
-/* Ryan supplied functions */
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_pos_s
-{
- uLong pos_in_zip_directory; /* offset in zip file directory */
- uLong num_of_file; /* # of file */
-} unz_file_pos;
-
-extern int ZEXPORT unzGetFilePos(
- unzFile file,
- unz_file_pos* file_pos);
-
-extern int ZEXPORT unzGoToFilePos(
- unzFile file,
- unz_file_pos* file_pos);
-
-/* ****************************************** */
-
-extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
- unz_file_info *pfile_info,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-/*
- Get Info about the current file
- if pfile_info!=NULL, the *pfile_info structure will contain somes info about
- the current file
- if szFileName!=NULL, the filemane string will be copied in szFileName
- (fileNameBufferSize is the size of the buffer)
- if extraField!=NULL, the extra field information will be copied in extraField
- (extraFieldBufferSize is the size of the buffer).
- This is the Central-header version of the extra field
- if szComment!=NULL, the comment string of the file will be copied in szComment
- (commentBufferSize is the size of the buffer)
-*/
-
-/***************************************************************************/
-/* for reading the content of the current zipfile, you can open it, read data
- from it, and close it (you can close it before reading all the file)
- */
-
-extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
-/*
- Open for reading data the current file in the zipfile.
- If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
- const char* password));
-/*
- Open for reading data the current file in the zipfile.
- password is a crypting password
- If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
- int* method,
- int* level,
- int raw));
-/*
- Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
- if raw==1
- *method will receive method of compression, *level will receive level of
- compression
- note : you can set level parameter as NULL (if you did not want known level,
- but you CANNOT set method parameter as NULL
-*/
-
-extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
- int* method,
- int* level,
- int raw,
- const char* password));
-/*
- Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
- if raw==1
- *method will receive method of compression, *level will receive level of
- compression
- note : you can set level parameter as NULL (if you did not want known level,
- but you CANNOT set method parameter as NULL
-*/
-
-
-extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
-/*
- Close the file in zip opened with unzOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-
-extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read bytes from the current file (opened by unzOpenCurrentFile)
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-
-extern z_off_t ZEXPORT unztell OF((unzFile file));
-/*
- Give the current position in uncompressed data
-*/
-
-extern int ZEXPORT unzeof OF((unzFile file));
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-
-extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-
-/***************************************************************************/
-
-/* Get the current file offset */
-extern uLong ZEXPORT unzGetOffset (unzFile file);
-
-/* Set the current file offset */
-extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _unz_H */
diff --git a/cpukit/zlib/contrib/minizip/zip.c b/cpukit/zlib/contrib/minizip/zip.c
deleted file mode 100644
index 2ccd7fd1ad..0000000000
--- a/cpukit/zlib/contrib/minizip/zip.c
+++ /dev/null
@@ -1,1188 +0,0 @@
-/* zip.c -- IO on .zip files using zlib
- Version 1.01, May 8th, 2004
-
- Copyright (C) 1998-2004 Gilles Vollant
-
- Read zip.h for more info
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "zlib.h"
-#include "zip.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-#ifndef VERSIONMADEBY
-# define VERSIONMADEBY (0x0) /* platform depedent */
-#endif
-
-#ifndef Z_BUFSIZE
-#define Z_BUFSIZE (16384)
-#endif
-
-#ifndef Z_MAXFILENAMEINZIP
-#define Z_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-/*
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-*/
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-#ifndef DEF_MEM_LEVEL
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-#endif
-const char zip_copyright[] =
- " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-
-#define SIZEDATA_INDATABLOCK (4096-(4*4))
-
-#define LOCALHEADERMAGIC (0x04034b50)
-#define CENTRALHEADERMAGIC (0x02014b50)
-#define ENDHEADERMAGIC (0x06054b50)
-
-#define FLAG_LOCALHEADER_OFFSET (0x06)
-#define CRC_LOCALHEADER_OFFSET (0x0e)
-
-#define SIZECENTRALHEADER (0x2e) /* 46 */
-
-typedef struct linkedlist_datablock_internal_s
-{
- struct linkedlist_datablock_internal_s* next_datablock;
- uLong avail_in_this_block;
- uLong filled_in_this_block;
- uLong unused; /* for future use and alignement */
- unsigned char data[SIZEDATA_INDATABLOCK];
-} linkedlist_datablock_internal;
-
-typedef struct linkedlist_data_s
-{
- linkedlist_datablock_internal* first_block;
- linkedlist_datablock_internal* last_block;
-} linkedlist_data;
-
-
-typedef struct
-{
- z_stream stream; /* zLib stream structure for inflate */
- int stream_initialised; /* 1 is stream is initialised */
- uInt pos_in_buffered_data; /* last written byte in buffered_data */
-
- uLong pos_local_header; /* offset of the local header of the file
- currenty writing */
- char* central_header; /* central header data for the current file */
- uLong size_centralheader; /* size of the central header for cur file */
- uLong flag; /* flag of the file currently writing */
-
- int method; /* compression method of file currenty wr.*/
- int raw; /* 1 for directly writing raw data */
- Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
- uLong dosDate;
- uLong crc32;
- int encrypt;
-#ifndef NOCRYPT
- unsigned long keys[3]; /* keys defining the pseudo-random sequence */
- const unsigned long* pcrc_32_tab;
- int crypt_header_size;
-#endif
-} curfile_info;
-
-typedef struct
-{
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- linkedlist_data central_dir;/* datablock with central dir in construction*/
- int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
- curfile_info ci; /* info on the file curretly writing */
-
- uLong begin_pos; /* position of the beginning of the zipfile */
- uLong add_position_when_writting_offset;
- uLong number_entry;
-} zip_internal;
-
-
-
-#ifndef NOCRYPT
-#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-#include "crypt.h"
-#endif
-
-local linkedlist_datablock_internal* allocate_new_datablock()
-{
- linkedlist_datablock_internal* ldi;
- ldi = (linkedlist_datablock_internal*)
- ALLOC(sizeof(linkedlist_datablock_internal));
- if (ldi!=NULL)
- {
- ldi->next_datablock = NULL ;
- ldi->filled_in_this_block = 0 ;
- ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
- }
- return ldi;
-}
-
-local void free_datablock(ldi)
- linkedlist_datablock_internal* ldi;
-{
- while (ldi!=NULL)
- {
- linkedlist_datablock_internal* ldinext = ldi->next_datablock;
- TRYFREE(ldi);
- ldi = ldinext;
- }
-}
-
-local void init_linkedlist(ll)
- linkedlist_data* ll;
-{
- ll->first_block = ll->last_block = NULL;
-}
-
-local void free_linkedlist(ll)
- linkedlist_data* ll;
-{
- free_datablock(ll->first_block);
- ll->first_block = ll->last_block = NULL;
-}
-
-
-local int add_data_in_datablock(ll,buf,len)
- linkedlist_data* ll;
- const void* buf;
- uLong len;
-{
- linkedlist_datablock_internal* ldi;
- const unsigned char* from_copy;
-
- if (ll==NULL)
- return ZIP_INTERNALERROR;
-
- if (ll->last_block == NULL)
- {
- ll->first_block = ll->last_block = allocate_new_datablock();
- if (ll->first_block == NULL)
- return ZIP_INTERNALERROR;
- }
-
- ldi = ll->last_block;
- from_copy = (unsigned char*)buf;
-
- while (len>0)
- {
- uInt copy_this;
- uInt i;
- unsigned char* to_copy;
-
- if (ldi->avail_in_this_block==0)
- {
- ldi->next_datablock = allocate_new_datablock();
- if (ldi->next_datablock == NULL)
- return ZIP_INTERNALERROR;
- ldi = ldi->next_datablock ;
- ll->last_block = ldi;
- }
-
- if (ldi->avail_in_this_block < len)
- copy_this = (uInt)ldi->avail_in_this_block;
- else
- copy_this = (uInt)len;
-
- to_copy = &(ldi->data[ldi->filled_in_this_block]);
-
- for (i=0;i<copy_this;i++)
- *(to_copy+i)=*(from_copy+i);
-
- ldi->filled_in_this_block += copy_this;
- ldi->avail_in_this_block -= copy_this;
- from_copy += copy_this ;
- len -= copy_this;
- }
- return ZIP_OK;
-}
-
-
-
-/****************************************************************************/
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-/* ===========================================================================
- Inputs a long in LSB order to the given file
- nbByte == 1, 2 or 4 (byte, short or long)
-*/
-
-local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream, uLong x, int nbByte));
-local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong x;
- int nbByte;
-{
- unsigned char buf[4];
- int n;
- for (n = 0; n < nbByte; n++)
- {
- buf[n] = (unsigned char)(x & 0xff);
- x >>= 8;
- }
- if (x != 0)
- { /* data overflow - hack for ZIP64 (X Roche) */
- for (n = 0; n < nbByte; n++)
- {
- buf[n] = 0xff;
- }
- }
-
- if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
- return ZIP_ERRNO;
- else
- return ZIP_OK;
-}
-
-local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
-local void ziplocal_putValue_inmemory (dest, x, nbByte)
- void* dest;
- uLong x;
- int nbByte;
-{
- unsigned char* buf=(unsigned char*)dest;
- int n;
- for (n = 0; n < nbByte; n++) {
- buf[n] = (unsigned char)(x & 0xff);
- x >>= 8;
- }
-
- if (x != 0)
- { /* data overflow - hack for ZIP64 */
- for (n = 0; n < nbByte; n++)
- {
- buf[n] = 0xff;
- }
- }
-}
-
-/****************************************************************************/
-
-
-local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
- const tm_zip* ptm;
- uLong dosDate;
-{
- uLong year = (uLong)ptm->tm_year;
- if (year>1980)
- year-=1980;
- else if (year>80)
- year-=80;
- return
- (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
- ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
-}
-
-
-/****************************************************************************/
-
-local int ziplocal_getByte OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- int *pi));
-
-local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- int *pi;
-{
- unsigned char c;
- int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
- if (err==1)
- {
- *pi = (int)c;
- return ZIP_OK;
- }
- else
- {
- if (ZERROR(*pzlib_filefunc_def,filestream))
- return ZIP_ERRNO;
- else
- return ZIP_EOF;
- }
-}
-
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int ziplocal_getShort OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==ZIP_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-local int ziplocal_getLong OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<16;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<24;
-
- if (err==ZIP_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-/*
- Locate the Central directory of a zipfile (at the end, just before
- the global comment)
-*/
-local uLong ziplocal_SearchCentralDir OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream));
-
-local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
-{
- unsigned char* buf;
- uLong uSizeFile;
- uLong uBackRead;
- uLong uMaxBack=0xffff; /* maximum size of global comment */
- uLong uPosFound=0;
-
- if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
- return 0;
-
-
- uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
-
- if (uMaxBack>uSizeFile)
- uMaxBack = uSizeFile;
-
- buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
- if (buf==NULL)
- return 0;
-
- uBackRead = 4;
- while (uBackRead<uMaxBack)
- {
- uLong uReadSize,uReadPos ;
- int i;
- if (uBackRead+BUFREADCOMMENT>uMaxBack)
- uBackRead = uMaxBack;
- else
- uBackRead+=BUFREADCOMMENT;
- uReadPos = uSizeFile-uBackRead ;
-
- uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
- (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
- if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- break;
-
- if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
- break;
-
- for (i=(int)uReadSize-3; (i--)>0;)
- if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
- ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
- {
- uPosFound = uReadPos+i;
- break;
- }
-
- if (uPosFound!=0)
- break;
- }
- TRYFREE(buf);
- return uPosFound;
-}
-#endif /* !NO_ADDFILEINEXISTINGZIP*/
-
-/************************************************************/
-extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
- const char *pathname;
- int append;
- zipcharpc* globalcomment;
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- zip_internal ziinit;
- zip_internal* zi;
- int err=ZIP_OK;
-
-
- if (pzlib_filefunc_def==NULL)
- fill_fopen_filefunc(&ziinit.z_filefunc);
- else
- ziinit.z_filefunc = *pzlib_filefunc_def;
-
- ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
- (ziinit.z_filefunc.opaque,
- pathname,
- (append == APPEND_STATUS_CREATE) ?
- (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
- (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
-
- if (ziinit.filestream == NULL)
- return NULL;
- ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
- ziinit.in_opened_file_inzip = 0;
- ziinit.ci.stream_initialised = 0;
- ziinit.number_entry = 0;
- ziinit.add_position_when_writting_offset = 0;
- init_linkedlist(&(ziinit.central_dir));
-
-
- zi = (zip_internal*)ALLOC(sizeof(zip_internal));
- if (zi==NULL)
- {
- ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
- return NULL;
- }
-
- /* now we add file in a zipfile */
-# ifndef NO_ADDFILEINEXISTINGZIP
- if (append == APPEND_STATUS_ADDINZIP)
- {
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
-
- uLong size_central_dir; /* size of the central directory */
- uLong offset_central_dir; /* offset of start of central directory */
- uLong central_pos,uL;
-
- uLong number_disk; /* number of the current dist, used for
- spaning ZIP, unsupported, always 0*/
- uLong number_disk_with_CD; /* number the the disk with central dir, used
- for spaning ZIP, unsupported, always 0*/
- uLong number_entry;
- uLong number_entry_CD; /* total number of entries in
- the central dir
- (same than number_entry on nospan) */
- uLong size_comment;
-
- central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
- if (central_pos==0)
- err=ZIP_ERRNO;
-
- if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
- central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=ZIP_ERRNO;
-
- /* the signature, already checked */
- if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* number of this disk */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* number of the disk with the start of the central directory */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* total number of entries in the central dir on this disk */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* total number of entries in the central dir */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- if ((number_entry_CD!=number_entry) ||
- (number_disk_with_CD!=0) ||
- (number_disk!=0))
- err=ZIP_BADZIPFILE;
-
- /* size of the central directory */
- if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* offset of start of central directory with respect to the
- starting disk number */
- if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* zipfile comment length */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- if ((central_pos<offset_central_dir+size_central_dir) &&
- (err==ZIP_OK))
- err=ZIP_BADZIPFILE;
-
- if (err!=ZIP_OK)
- {
- ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
- return NULL;
- }
-
- byte_before_the_zipfile = central_pos -
- (offset_central_dir+size_central_dir);
- ziinit.add_position_when_writting_offset = byte_before_the_zipfile ;
-
- {
- uLong size_central_dir_to_read = size_central_dir;
- size_t buf_size = SIZEDATA_INDATABLOCK;
- void* buf_read = (void*)ALLOC(buf_size);
- if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
- offset_central_dir + byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET) != 0)
- err=ZIP_ERRNO;
-
- while ((size_central_dir_to_read>0) && (err==ZIP_OK))
- {
- uLong read_this = SIZEDATA_INDATABLOCK;
- if (read_this > size_central_dir_to_read)
- read_this = size_central_dir_to_read;
- if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
- err=ZIP_ERRNO;
-
- if (err==ZIP_OK)
- err = add_data_in_datablock(&ziinit.central_dir,buf_read,
- (uLong)read_this);
- size_central_dir_to_read-=read_this;
- }
- TRYFREE(buf_read);
- }
- ziinit.begin_pos = byte_before_the_zipfile;
- ziinit.number_entry = number_entry_CD;
-
- if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
- offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=ZIP_ERRNO;
- }
-# endif /* !NO_ADDFILEINEXISTINGZIP*/
-
- if (err != ZIP_OK)
- {
- TRYFREE(zi);
- return NULL;
- }
- else
- {
- *zi = ziinit;
- return (zipFile)zi;
- }
-}
-
-extern zipFile ZEXPORT zipOpen (pathname, append)
- const char *pathname;
- int append;
-{
- return zipOpen2(pathname,append,NULL,NULL);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw,
- windowBits, memLevel, strategy,
- password, crcForCrypting)
- zipFile file;
- const char* filename;
- const zip_fileinfo* zipfi;
- const void* extrafield_local;
- uInt size_extrafield_local;
- const void* extrafield_global;
- uInt size_extrafield_global;
- const char* comment;
- int method;
- int level;
- int raw;
- int windowBits;
- int memLevel;
- int strategy;
- const char* password;
- uLong crcForCrypting;
-{
- zip_internal* zi;
- uInt size_filename;
- uInt size_comment;
- uInt i;
- int err = ZIP_OK;
-
-# ifdef NOCRYPT
- if (password != NULL)
- return ZIP_PARAMERROR;
-# endif
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- if ((method!=0) && (method!=Z_DEFLATED))
- return ZIP_PARAMERROR;
-
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 1)
- {
- err = zipCloseFileInZip (file);
- if (err != ZIP_OK)
- return err;
- }
-
-
- if (filename==NULL)
- filename="-";
-
- if (comment==NULL)
- size_comment = 0;
- else
- size_comment = (uInt)strlen(comment);
-
- size_filename = (uInt)strlen(filename);
-
- if (zipfi == NULL)
- zi->ci.dosDate = 0;
- else
- {
- if (zipfi->dosDate != 0)
- zi->ci.dosDate = zipfi->dosDate;
- else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
- }
-
- zi->ci.flag = 0;
- if ((level==8) || (level==9))
- zi->ci.flag |= 2;
- if ((level==2))
- zi->ci.flag |= 4;
- if ((level==1))
- zi->ci.flag |= 6;
- if (password != NULL)
- zi->ci.flag |= 1;
-
- zi->ci.crc32 = 0;
- zi->ci.method = method;
- zi->ci.encrypt = 0;
- zi->ci.stream_initialised = 0;
- zi->ci.pos_in_buffered_data = 0;
- zi->ci.raw = raw;
- zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
- zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
- size_extrafield_global + size_comment;
- zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
-
- ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
- /* version info */
- ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
- ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
- ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
- ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
- ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
-
- if (zipfi==NULL)
- ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
- else
- ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
-
- if (zipfi==NULL)
- ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
- else
- ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
-
- ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
-
- for (i=0;i<size_filename;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
-
- for (i=0;i<size_extrafield_global;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
- *(((const char*)extrafield_global)+i);
-
- for (i=0;i<size_comment;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
- size_extrafield_global+i) = *(comment+i);
- if (zi->ci.central_header == NULL)
- return ZIP_INTERNALERROR;
-
- /* write the local header */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
-
- if ((err==ZIP_OK) && (size_filename>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
- err = ZIP_ERRNO;
-
- if ((err==ZIP_OK) && (size_extrafield_local>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
- !=size_extrafield_local)
- err = ZIP_ERRNO;
-
- zi->ci.stream.avail_in = (uInt)0;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- zi->ci.stream.total_in = 0;
- zi->ci.stream.total_out = 0;
-
- if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- {
- zi->ci.stream.zalloc = (alloc_func)0;
- zi->ci.stream.zfree = (free_func)0;
- zi->ci.stream.opaque = (voidpf)0;
-
- if (windowBits>0)
- windowBits = -windowBits;
-
- err = deflateInit2(&zi->ci.stream, level,
- Z_DEFLATED, windowBits, memLevel, strategy);
-
- if (err==Z_OK)
- zi->ci.stream_initialised = 1;
- }
-# ifndef NOCRYPT
- zi->ci.crypt_header_size = 0;
- if ((err==Z_OK) && (password != NULL))
- {
- unsigned char bufHead[RAND_HEAD_LEN];
- unsigned int sizeHead;
- zi->ci.encrypt = 1;
- zi->ci.pcrc_32_tab = get_crc_table();
- /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
-
- sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
- zi->ci.crypt_header_size = sizeHead;
-
- if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
- err = ZIP_ERRNO;
- }
-# endif
-
- if (err==Z_OK)
- zi->in_opened_file_inzip = 1;
- return err;
-}
-
-extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw)
- zipFile file;
- const char* filename;
- const zip_fileinfo* zipfi;
- const void* extrafield_local;
- uInt size_extrafield_local;
- const void* extrafield_global;
- uInt size_extrafield_global;
- const char* comment;
- int method;
- int level;
- int raw;
-{
- return zipOpenNewFileInZip3 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw,
- -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
- NULL, 0);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level)
- zipFile file;
- const char* filename;
- const zip_fileinfo* zipfi;
- const void* extrafield_local;
- uInt size_extrafield_local;
- const void* extrafield_global;
- uInt size_extrafield_global;
- const char* comment;
- int method;
- int level;
-{
- return zipOpenNewFileInZip2 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, 0);
-}
-
-local int zipFlushWriteBuffer(zi)
- zip_internal* zi;
-{
- int err=ZIP_OK;
-
- if (zi->ci.encrypt != 0)
- {
-#ifndef NOCRYPT
- uInt i;
- int t;
- for (i=0;i<zi->ci.pos_in_buffered_data;i++)
- zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
- zi->ci.buffered_data[i],t);
-#endif
- }
- if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
- !=zi->ci.pos_in_buffered_data)
- err = ZIP_ERRNO;
- zi->ci.pos_in_buffered_data = 0;
- return err;
-}
-
-extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
- zipFile file;
- const void* buf;
- unsigned len;
-{
- zip_internal* zi;
- int err=ZIP_OK;
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 0)
- return ZIP_PARAMERROR;
-
- zi->ci.stream.next_in = (void*)buf;
- zi->ci.stream.avail_in = len;
- zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
-
- while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
- {
- if (zi->ci.stream.avail_out == 0)
- {
- if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
- err = ZIP_ERRNO;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- }
-
-
- if(err != ZIP_OK)
- break;
-
- if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- {
- uLong uTotalOutBefore = zi->ci.stream.total_out;
- err=deflate(&zi->ci.stream, Z_NO_FLUSH);
- zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
-
- }
- else
- {
- uInt copy_this,i;
- if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
- copy_this = zi->ci.stream.avail_in;
- else
- copy_this = zi->ci.stream.avail_out;
- for (i=0;i<copy_this;i++)
- *(((char*)zi->ci.stream.next_out)+i) =
- *(((const char*)zi->ci.stream.next_in)+i);
- {
- zi->ci.stream.avail_in -= copy_this;
- zi->ci.stream.avail_out-= copy_this;
- zi->ci.stream.next_in+= copy_this;
- zi->ci.stream.next_out+= copy_this;
- zi->ci.stream.total_in+= copy_this;
- zi->ci.stream.total_out+= copy_this;
- zi->ci.pos_in_buffered_data += copy_this;
- }
- }
- }
-
- return err;
-}
-
-extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
- zipFile file;
- uLong uncompressed_size;
- uLong crc32;
-{
- zip_internal* zi;
- uLong compressed_size;
- int err=ZIP_OK;
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 0)
- return ZIP_PARAMERROR;
- zi->ci.stream.avail_in = 0;
-
- if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- while (err==ZIP_OK)
- {
- uLong uTotalOutBefore;
- if (zi->ci.stream.avail_out == 0)
- {
- if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
- err = ZIP_ERRNO;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- }
- uTotalOutBefore = zi->ci.stream.total_out;
- err=deflate(&zi->ci.stream, Z_FINISH);
- zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
- }
-
- if (err==Z_STREAM_END)
- err=ZIP_OK; /* this is normal */
-
- if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
- if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
- err = ZIP_ERRNO;
-
- if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- {
- err=deflateEnd(&zi->ci.stream);
- zi->ci.stream_initialised = 0;
- }
-
- if (!zi->ci.raw)
- {
- crc32 = (uLong)zi->ci.crc32;
- uncompressed_size = (uLong)zi->ci.stream.total_in;
- }
- compressed_size = (uLong)zi->ci.stream.total_out;
-# ifndef NOCRYPT
- compressed_size += zi->ci.crypt_header_size;
-# endif
-
- ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
- ziplocal_putValue_inmemory(zi->ci.central_header+20,
- compressed_size,4); /*compr size*/
- if (zi->ci.stream.data_type == Z_ASCII)
- ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+24,
- uncompressed_size,4); /*uncompr size*/
-
- if (err==ZIP_OK)
- err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
- (uLong)zi->ci.size_centralheader);
- free(zi->ci.central_header);
-
- if (err==ZIP_OK)
- {
- long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
- if (ZSEEK(zi->z_filefunc,zi->filestream,
- zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err = ZIP_ERRNO;
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
-
- if (err==ZIP_OK) /* compressed size, unknown */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
-
- if (err==ZIP_OK) /* uncompressed size, unknown */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
-
- if (ZSEEK(zi->z_filefunc,zi->filestream,
- cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err = ZIP_ERRNO;
- }
-
- zi->number_entry ++;
- zi->in_opened_file_inzip = 0;
-
- return err;
-}
-
-extern int ZEXPORT zipCloseFileInZip (file)
- zipFile file;
-{
- return zipCloseFileInZipRaw (file,0,0);
-}
-
-extern int ZEXPORT zipClose (file, global_comment)
- zipFile file;
- const char* global_comment;
-{
- zip_internal* zi;
- int err = 0;
- uLong size_centraldir = 0;
- uLong centraldir_pos_inzip ;
- uInt size_global_comment;
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 1)
- {
- err = zipCloseFileInZip (file);
- }
-
- if (global_comment==NULL)
- size_global_comment = 0;
- else
- size_global_comment = (uInt)strlen(global_comment);
-
-
- centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
- if (err==ZIP_OK)
- {
- linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
- while (ldi!=NULL)
- {
- if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,
- ldi->data,ldi->filled_in_this_block)
- !=ldi->filled_in_this_block )
- err = ZIP_ERRNO;
-
- size_centraldir += ldi->filled_in_this_block;
- ldi = ldi->next_datablock;
- }
- }
- free_datablock(zi->central_dir.first_block);
-
- if (err==ZIP_OK) /* Magic End */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
-
- if (err==ZIP_OK) /* number of this disk */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
- if (err==ZIP_OK) /* number of the disk with the start of the central directory */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
- if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-
- if (err==ZIP_OK) /* total number of entries in the central dir */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-
- if (err==ZIP_OK) /* size of the central directory */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
-
- if (err==ZIP_OK) /* offset of start of central directory with respect to the
- starting disk number */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
- (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
-
- if (err==ZIP_OK) /* zipfile comment length */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
-
- if ((err==ZIP_OK) && (size_global_comment>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,
- global_comment,size_global_comment) != size_global_comment)
- err = ZIP_ERRNO;
-
- if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
- if (err == ZIP_OK)
- err = ZIP_ERRNO;
-
- TRYFREE(zi);
-
- return err;
-}
diff --git a/cpukit/zlib/contrib/minizip/zip.h b/cpukit/zlib/contrib/minizip/zip.h
deleted file mode 100644
index d5112c4dcb..0000000000
--- a/cpukit/zlib/contrib/minizip/zip.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/* zip.h -- IO for compress .zip files using zlib
- Version 1.01, May 8th, 2004
-
- Copyright (C) 1998-2004 Gilles Vollant
-
- This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
- WinZip, InfoZip tools and compatible.
- Encryption and multi volume ZipFile (span) are not supported.
- Old compressions used by old PKZip 1.x are not supported
-
- For uncompress .zip file, look at unzip.h
-
-
- I WAIT FEEDBACK at mail info@winimage.com
- Visit also http://www.winimage.com/zLibDll/unzip.html for evolution
-
- Condition of use and distribution are the same than zlib :
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
-
-*/
-
-/* for more info about .ZIP format, see
- http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
- http://www.info-zip.org/pub/infozip/doc/
- PkWare has also a specification at :
- ftp://ftp.pkware.com/probdesc.zip
-*/
-
-#ifndef _zip_H
-#define _zip_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
-typedef struct TagzipFile__ { int unused; } zipFile__;
-typedef zipFile__ *zipFile;
-#else
-typedef voidp zipFile;
-#endif
-
-#define ZIP_OK (0)
-#define ZIP_EOF (0)
-#define ZIP_ERRNO (Z_ERRNO)
-#define ZIP_PARAMERROR (-102)
-#define ZIP_BADZIPFILE (-103)
-#define ZIP_INTERNALERROR (-104)
-
-#ifndef DEF_MEM_LEVEL
-# if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-# else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-# endif
-#endif
-/* default memLevel */
-
-/* tm_zip contain date/time info */
-typedef struct tm_zip_s
-{
- uInt tm_sec; /* seconds after the minute - [0,59] */
- uInt tm_min; /* minutes after the hour - [0,59] */
- uInt tm_hour; /* hours since midnight - [0,23] */
- uInt tm_mday; /* day of the month - [1,31] */
- uInt tm_mon; /* months since January - [0,11] */
- uInt tm_year; /* years - [1980..2044] */
-} tm_zip;
-
-typedef struct
-{
- tm_zip tmz_date; /* date in understandable format */
- uLong dosDate; /* if dos_date == 0, tmu_date is used */
-/* uLong flag; */ /* general purpose bit flag 2 bytes */
-
- uLong internal_fa; /* internal file attributes 2 bytes */
- uLong external_fa; /* external file attributes 4 bytes */
-} zip_fileinfo;
-
-typedef const char* zipcharpc;
-
-
-#define APPEND_STATUS_CREATE (0)
-#define APPEND_STATUS_CREATEAFTER (1)
-#define APPEND_STATUS_ADDINZIP (2)
-
-extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
-/*
- Create a zipfile.
- pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
- an Unix computer "zlib/zlib113.zip".
- if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
- will be created at the end of the file.
- (useful if the file contain a self extractor code)
- if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
- add files in existing zip (be sure you don't add file that doesn't exist)
- If the zipfile cannot be opened, the return value is NULL.
- Else, the return value is a zipFile Handle, usable with other function
- of this zip package.
-*/
-
-/* Note : there is no delete function into a zipfile.
- If you want delete file into a zipfile, you must open a zipfile, and create another
- Of couse, you can use RAW reading and writing to copy the file you did not want delte
-*/
-
-extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
- int append,
- zipcharpc* globalcomment,
- zlib_filefunc_def* pzlib_filefunc_def));
-
-extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level));
-/*
- Open a file in the ZIP for writing.
- filename : the filename in zip (if NULL, '-' without quote will be used
- *zipfi contain supplemental information
- if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
- contains the extrafield data the the local header
- if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
- contains the extrafield data the the local header
- if comment != NULL, comment contain the comment string
- method contain the compression method (0 for store, Z_DEFLATED for deflate)
- level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
-*/
-
-
-extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw));
-
-/*
- Same than zipOpenNewFileInZip, except if raw=1, we write raw file
- */
-
-extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw,
- int windowBits,
- int memLevel,
- int strategy,
- const char* password,
- uLong crcForCtypting));
-
-/*
- Same than zipOpenNewFileInZip2, except
- windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
- password : crypting password (NULL for no crypting)
- crcForCtypting : crc of file to compress (needed for crypting)
- */
-
-
-extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
- const void* buf,
- unsigned len));
-/*
- Write data in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
-/*
- Close the current file in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
- uLong uncompressed_size,
- uLong crc32));
-/*
- Close the current file in the zipfile, for fiel opened with
- parameter raw=1 in zipOpenNewFileInZip2
- uncompressed_size and crc32 are value for the uncompressed size
-*/
-
-extern int ZEXPORT zipClose OF((zipFile file,
- const char* global_comment));
-/*
- Close the zipfile
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _zip_H */
diff --git a/cpukit/zlib/contrib/pascal/example.pas b/cpukit/zlib/contrib/pascal/example.pas
deleted file mode 100644
index 5518b36a73..0000000000
--- a/cpukit/zlib/contrib/pascal/example.pas
+++ /dev/null
@@ -1,599 +0,0 @@
-(* example.c -- usage example of the zlib compression library
- * Copyright (C) 1995-2003 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Pascal translation
- * Copyright (C) 1998 by Jacques Nomssi Nzali.
- * For conditions of distribution and use, see copyright notice in readme.txt
- *
- * Adaptation to the zlibpas interface
- * Copyright (C) 2003 by Cosmin Truta.
- * For conditions of distribution and use, see copyright notice in readme.txt
- *)
-
-program example;
-
-{$DEFINE TEST_COMPRESS}
-{DO NOT $DEFINE TEST_GZIO}
-{$DEFINE TEST_DEFLATE}
-{$DEFINE TEST_INFLATE}
-{$DEFINE TEST_FLUSH}
-{$DEFINE TEST_SYNC}
-{$DEFINE TEST_DICT}
-
-uses SysUtils, zlibpas;
-
-const TESTFILE = 'foo.gz';
-
-(* "hello world" would be more standard, but the repeated "hello"
- * stresses the compression code better, sorry...
- *)
-const hello: PChar = 'hello, hello!';
-
-const dictionary: PChar = 'hello';
-
-var dictId: LongInt; (* Adler32 value of the dictionary *)
-
-procedure CHECK_ERR(err: Integer; msg: String);
-begin
- if err <> Z_OK then
- begin
- WriteLn(msg, ' error: ', err);
- Halt(1);
- end;
-end;
-
-procedure EXIT_ERR(const msg: String);
-begin
- WriteLn('Error: ', msg);
- Halt(1);
-end;
-
-(* ===========================================================================
- * Test compress and uncompress
- *)
-{$IFDEF TEST_COMPRESS}
-procedure test_compress(compr: Pointer; comprLen: LongInt;
- uncompr: Pointer; uncomprLen: LongInt);
-var err: Integer;
- len: LongInt;
-begin
- len := StrLen(hello)+1;
-
- err := compress(compr, comprLen, hello, len);
- CHECK_ERR(err, 'compress');
-
- StrCopy(PChar(uncompr), 'garbage');
-
- err := uncompress(uncompr, uncomprLen, compr, comprLen);
- CHECK_ERR(err, 'uncompress');
-
- if StrComp(PChar(uncompr), hello) <> 0 then
- EXIT_ERR('bad uncompress')
- else
- WriteLn('uncompress(): ', PChar(uncompr));
-end;
-{$ENDIF}
-
-(* ===========================================================================
- * Test read/write of .gz files
- *)
-{$IFDEF TEST_GZIO}
-procedure test_gzio(const fname: PChar; (* compressed file name *)
- uncompr: Pointer;
- uncomprLen: LongInt);
-var err: Integer;
- len: Integer;
- zfile: gzFile;
- pos: LongInt;
-begin
- len := StrLen(hello)+1;
-
- zfile := gzopen(fname, 'wb');
- if zfile = NIL then
- begin
- WriteLn('gzopen error');
- Halt(1);
- end;
- gzputc(zfile, 'h');
- if gzputs(zfile, 'ello') <> 4 then
- begin
- WriteLn('gzputs err: ', gzerror(zfile, err));
- Halt(1);
- end;
- {$IFDEF GZ_FORMAT_STRING}
- if gzprintf(zfile, ', %s!', 'hello') <> 8 then
- begin
- WriteLn('gzprintf err: ', gzerror(zfile, err));
- Halt(1);
- end;
- {$ELSE}
- if gzputs(zfile, ', hello!') <> 8 then
- begin
- WriteLn('gzputs err: ', gzerror(zfile, err));
- Halt(1);
- end;
- {$ENDIF}
- gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *)
- gzclose(zfile);
-
- zfile := gzopen(fname, 'rb');
- if zfile = NIL then
- begin
- WriteLn('gzopen error');
- Halt(1);
- end;
-
- StrCopy(PChar(uncompr), 'garbage');
-
- if gzread(zfile, uncompr, uncomprLen) <> len then
- begin
- WriteLn('gzread err: ', gzerror(zfile, err));
- Halt(1);
- end;
- if StrComp(PChar(uncompr), hello) <> 0 then
- begin
- WriteLn('bad gzread: ', PChar(uncompr));
- Halt(1);
- end
- else
- WriteLn('gzread(): ', PChar(uncompr));
-
- pos := gzseek(zfile, -8, SEEK_CUR);
- if (pos <> 6) or (gztell(zfile) <> pos) then
- begin
- WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile));
- Halt(1);
- end;
-
- if gzgetc(zfile) <> ' ' then
- begin
- WriteLn('gzgetc error');
- Halt(1);
- end;
-
- if gzungetc(' ', zfile) <> ' ' then
- begin
- WriteLn('gzungetc error');
- Halt(1);
- end;
-
- gzgets(zfile, PChar(uncompr), uncomprLen);
- uncomprLen := StrLen(PChar(uncompr));
- if uncomprLen <> 7 then (* " hello!" *)
- begin
- WriteLn('gzgets err after gzseek: ', gzerror(zfile, err));
- Halt(1);
- end;
- if StrComp(PChar(uncompr), hello + 6) <> 0 then
- begin
- WriteLn('bad gzgets after gzseek');
- Halt(1);
- end
- else
- WriteLn('gzgets() after gzseek: ', PChar(uncompr));
-
- gzclose(zfile);
-end;
-{$ENDIF}
-
-(* ===========================================================================
- * Test deflate with small buffers
- *)
-{$IFDEF TEST_DEFLATE}
-procedure test_deflate(compr: Pointer; comprLen: LongInt);
-var c_stream: z_stream; (* compression stream *)
- err: Integer;
- len: LongInt;
-begin
- len := StrLen(hello)+1;
-
- c_stream.zalloc := NIL;
- c_stream.zfree := NIL;
- c_stream.opaque := NIL;
-
- err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
- CHECK_ERR(err, 'deflateInit');
-
- c_stream.next_in := hello;
- c_stream.next_out := compr;
-
- while (c_stream.total_in <> len) and
- (c_stream.total_out < comprLen) do
- begin
- c_stream.avail_out := 1; { force small buffers }
- c_stream.avail_in := 1;
- err := deflate(c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, 'deflate');
- end;
-
- (* Finish the stream, still forcing small buffers: *)
- while TRUE do
- begin
- c_stream.avail_out := 1;
- err := deflate(c_stream, Z_FINISH);
- if err = Z_STREAM_END then
- break;
- CHECK_ERR(err, 'deflate');
- end;
-
- err := deflateEnd(c_stream);
- CHECK_ERR(err, 'deflateEnd');
-end;
-{$ENDIF}
-
-(* ===========================================================================
- * Test inflate with small buffers
- *)
-{$IFDEF TEST_INFLATE}
-procedure test_inflate(compr: Pointer; comprLen : LongInt;
- uncompr: Pointer; uncomprLen : LongInt);
-var err: Integer;
- d_stream: z_stream; (* decompression stream *)
-begin
- StrCopy(PChar(uncompr), 'garbage');
-
- d_stream.zalloc := NIL;
- d_stream.zfree := NIL;
- d_stream.opaque := NIL;
-
- d_stream.next_in := compr;
- d_stream.avail_in := 0;
- d_stream.next_out := uncompr;
-
- err := inflateInit(d_stream);
- CHECK_ERR(err, 'inflateInit');
-
- while (d_stream.total_out < uncomprLen) and
- (d_stream.total_in < comprLen) do
- begin
- d_stream.avail_out := 1; (* force small buffers *)
- d_stream.avail_in := 1;
- err := inflate(d_stream, Z_NO_FLUSH);
- if err = Z_STREAM_END then
- break;
- CHECK_ERR(err, 'inflate');
- end;
-
- err := inflateEnd(d_stream);
- CHECK_ERR(err, 'inflateEnd');
-
- if StrComp(PChar(uncompr), hello) <> 0 then
- EXIT_ERR('bad inflate')
- else
- WriteLn('inflate(): ', PChar(uncompr));
-end;
-{$ENDIF}
-
-(* ===========================================================================
- * Test deflate with large buffers and dynamic change of compression level
- *)
-{$IFDEF TEST_DEFLATE}
-procedure test_large_deflate(compr: Pointer; comprLen: LongInt;
- uncompr: Pointer; uncomprLen: LongInt);
-var c_stream: z_stream; (* compression stream *)
- err: Integer;
-begin
- c_stream.zalloc := NIL;
- c_stream.zfree := NIL;
- c_stream.opaque := NIL;
-
- err := deflateInit(c_stream, Z_BEST_SPEED);
- CHECK_ERR(err, 'deflateInit');
-
- c_stream.next_out := compr;
- c_stream.avail_out := Integer(comprLen);
-
- (* At this point, uncompr is still mostly zeroes, so it should compress
- * very well:
- *)
- c_stream.next_in := uncompr;
- c_stream.avail_in := Integer(uncomprLen);
- err := deflate(c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, 'deflate');
- if c_stream.avail_in <> 0 then
- EXIT_ERR('deflate not greedy');
-
- (* Feed in already compressed data and switch to no compression: *)
- deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
- c_stream.next_in := compr;
- c_stream.avail_in := Integer(comprLen div 2);
- err := deflate(c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, 'deflate');
-
- (* Switch back to compressing mode: *)
- deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
- c_stream.next_in := uncompr;
- c_stream.avail_in := Integer(uncomprLen);
- err := deflate(c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, 'deflate');
-
- err := deflate(c_stream, Z_FINISH);
- if err <> Z_STREAM_END then
- EXIT_ERR('deflate should report Z_STREAM_END');
-
- err := deflateEnd(c_stream);
- CHECK_ERR(err, 'deflateEnd');
-end;
-{$ENDIF}
-
-(* ===========================================================================
- * Test inflate with large buffers
- *)
-{$IFDEF TEST_INFLATE}
-procedure test_large_inflate(compr: Pointer; comprLen: LongInt;
- uncompr: Pointer; uncomprLen: LongInt);
-var err: Integer;
- d_stream: z_stream; (* decompression stream *)
-begin
- StrCopy(PChar(uncompr), 'garbage');
-
- d_stream.zalloc := NIL;
- d_stream.zfree := NIL;
- d_stream.opaque := NIL;
-
- d_stream.next_in := compr;
- d_stream.avail_in := Integer(comprLen);
-
- err := inflateInit(d_stream);
- CHECK_ERR(err, 'inflateInit');
-
- while TRUE do
- begin
- d_stream.next_out := uncompr; (* discard the output *)
- d_stream.avail_out := Integer(uncomprLen);
- err := inflate(d_stream, Z_NO_FLUSH);
- if err = Z_STREAM_END then
- break;
- CHECK_ERR(err, 'large inflate');
- end;
-
- err := inflateEnd(d_stream);
- CHECK_ERR(err, 'inflateEnd');
-
- if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then
- begin
- WriteLn('bad large inflate: ', d_stream.total_out);
- Halt(1);
- end
- else
- WriteLn('large_inflate(): OK');
-end;
-{$ENDIF}
-
-(* ===========================================================================
- * Test deflate with full flush
- *)
-{$IFDEF TEST_FLUSH}
-procedure test_flush(compr: Pointer; var comprLen : LongInt);
-var c_stream: z_stream; (* compression stream *)
- err: Integer;
- len: Integer;
-begin
- len := StrLen(hello)+1;
-
- c_stream.zalloc := NIL;
- c_stream.zfree := NIL;
- c_stream.opaque := NIL;
-
- err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
- CHECK_ERR(err, 'deflateInit');
-
- c_stream.next_in := hello;
- c_stream.next_out := compr;
- c_stream.avail_in := 3;
- c_stream.avail_out := Integer(comprLen);
- err := deflate(c_stream, Z_FULL_FLUSH);
- CHECK_ERR(err, 'deflate');
-
- Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *)
- c_stream.avail_in := len - 3;
-
- err := deflate(c_stream, Z_FINISH);
- if err <> Z_STREAM_END then
- CHECK_ERR(err, 'deflate');
-
- err := deflateEnd(c_stream);
- CHECK_ERR(err, 'deflateEnd');
-
- comprLen := c_stream.total_out;
-end;
-{$ENDIF}
-
-(* ===========================================================================
- * Test inflateSync()
- *)
-{$IFDEF TEST_SYNC}
-procedure test_sync(compr: Pointer; comprLen: LongInt;
- uncompr: Pointer; uncomprLen : LongInt);
-var err: Integer;
- d_stream: z_stream; (* decompression stream *)
-begin
- StrCopy(PChar(uncompr), 'garbage');
-
- d_stream.zalloc := NIL;
- d_stream.zfree := NIL;
- d_stream.opaque := NIL;
-
- d_stream.next_in := compr;
- d_stream.avail_in := 2; (* just read the zlib header *)
-
- err := inflateInit(d_stream);
- CHECK_ERR(err, 'inflateInit');
-
- d_stream.next_out := uncompr;
- d_stream.avail_out := Integer(uncomprLen);
-
- inflate(d_stream, Z_NO_FLUSH);
- CHECK_ERR(err, 'inflate');
-
- d_stream.avail_in := Integer(comprLen-2); (* read all compressed data *)
- err := inflateSync(d_stream); (* but skip the damaged part *)
- CHECK_ERR(err, 'inflateSync');
-
- err := inflate(d_stream, Z_FINISH);
- if err <> Z_DATA_ERROR then
- EXIT_ERR('inflate should report DATA_ERROR');
- (* Because of incorrect adler32 *)
-
- err := inflateEnd(d_stream);
- CHECK_ERR(err, 'inflateEnd');
-
- WriteLn('after inflateSync(): hel', PChar(uncompr));
-end;
-{$ENDIF}
-
-(* ===========================================================================
- * Test deflate with preset dictionary
- *)
-{$IFDEF TEST_DICT}
-procedure test_dict_deflate(compr: Pointer; comprLen: LongInt);
-var c_stream: z_stream; (* compression stream *)
- err: Integer;
-begin
- c_stream.zalloc := NIL;
- c_stream.zfree := NIL;
- c_stream.opaque := NIL;
-
- err := deflateInit(c_stream, Z_BEST_COMPRESSION);
- CHECK_ERR(err, 'deflateInit');
-
- err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary));
- CHECK_ERR(err, 'deflateSetDictionary');
-
- dictId := c_stream.adler;
- c_stream.next_out := compr;
- c_stream.avail_out := Integer(comprLen);
-
- c_stream.next_in := hello;
- c_stream.avail_in := StrLen(hello)+1;
-
- err := deflate(c_stream, Z_FINISH);
- if err <> Z_STREAM_END then
- EXIT_ERR('deflate should report Z_STREAM_END');
-
- err := deflateEnd(c_stream);
- CHECK_ERR(err, 'deflateEnd');
-end;
-{$ENDIF}
-
-(* ===========================================================================
- * Test inflate with a preset dictionary
- *)
-{$IFDEF TEST_DICT}
-procedure test_dict_inflate(compr: Pointer; comprLen: LongInt;
- uncompr: Pointer; uncomprLen: LongInt);
-var err: Integer;
- d_stream: z_stream; (* decompression stream *)
-begin
- StrCopy(PChar(uncompr), 'garbage');
-
- d_stream.zalloc := NIL;
- d_stream.zfree := NIL;
- d_stream.opaque := NIL;
-
- d_stream.next_in := compr;
- d_stream.avail_in := Integer(comprLen);
-
- err := inflateInit(d_stream);
- CHECK_ERR(err, 'inflateInit');
-
- d_stream.next_out := uncompr;
- d_stream.avail_out := Integer(uncomprLen);
-
- while TRUE do
- begin
- err := inflate(d_stream, Z_NO_FLUSH);
- if err = Z_STREAM_END then
- break;
- if err = Z_NEED_DICT then
- begin
- if d_stream.adler <> dictId then
- EXIT_ERR('unexpected dictionary');
- err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary));
- end;
- CHECK_ERR(err, 'inflate with dict');
- end;
-
- err := inflateEnd(d_stream);
- CHECK_ERR(err, 'inflateEnd');
-
- if StrComp(PChar(uncompr), hello) <> 0 then
- EXIT_ERR('bad inflate with dict')
- else
- WriteLn('inflate with dictionary: ', PChar(uncompr));
-end;
-{$ENDIF}
-
-var compr, uncompr: Pointer;
- comprLen, uncomprLen: LongInt;
-
-begin
- if zlibVersion^ <> ZLIB_VERSION[1] then
- EXIT_ERR('Incompatible zlib version');
-
- WriteLn('zlib version: ', zlibVersion);
- WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags]));
-
- comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *)
- uncomprLen := comprLen;
- GetMem(compr, comprLen);
- GetMem(uncompr, uncomprLen);
- if (compr = NIL) or (uncompr = NIL) then
- EXIT_ERR('Out of memory');
- (* compr and uncompr are cleared to avoid reading uninitialized
- * data and to ensure that uncompr compresses well.
- *)
- FillChar(compr^, comprLen, 0);
- FillChar(uncompr^, uncomprLen, 0);
-
- {$IFDEF TEST_COMPRESS}
- WriteLn('** Testing compress');
- test_compress(compr, comprLen, uncompr, uncomprLen);
- {$ENDIF}
-
- {$IFDEF TEST_GZIO}
- WriteLn('** Testing gzio');
- if ParamCount >= 1 then
- test_gzio(ParamStr(1), uncompr, uncomprLen)
- else
- test_gzio(TESTFILE, uncompr, uncomprLen);
- {$ENDIF}
-
- {$IFDEF TEST_DEFLATE}
- WriteLn('** Testing deflate with small buffers');
- test_deflate(compr, comprLen);
- {$ENDIF}
- {$IFDEF TEST_INFLATE}
- WriteLn('** Testing inflate with small buffers');
- test_inflate(compr, comprLen, uncompr, uncomprLen);
- {$ENDIF}
-
- {$IFDEF TEST_DEFLATE}
- WriteLn('** Testing deflate with large buffers');
- test_large_deflate(compr, comprLen, uncompr, uncomprLen);
- {$ENDIF}
- {$IFDEF TEST_INFLATE}
- WriteLn('** Testing inflate with large buffers');
- test_large_inflate(compr, comprLen, uncompr, uncomprLen);
- {$ENDIF}
-
- {$IFDEF TEST_FLUSH}
- WriteLn('** Testing deflate with full flush');
- test_flush(compr, comprLen);
- {$ENDIF}
- {$IFDEF TEST_SYNC}
- WriteLn('** Testing inflateSync');
- test_sync(compr, comprLen, uncompr, uncomprLen);
- {$ENDIF}
- comprLen := uncomprLen;
-
- {$IFDEF TEST_DICT}
- WriteLn('** Testing deflate and inflate with preset dictionary');
- test_dict_deflate(compr, comprLen);
- test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
- {$ENDIF}
-
- FreeMem(compr, comprLen);
- FreeMem(uncompr, uncomprLen);
-end.
diff --git a/cpukit/zlib/contrib/pascal/readme.txt b/cpukit/zlib/contrib/pascal/readme.txt
deleted file mode 100644
index 60e87c8a33..0000000000
--- a/cpukit/zlib/contrib/pascal/readme.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-
-This directory contains a Pascal (Delphi, Kylix) interface to the
-zlib data compression library.
-
-
-Directory listing
-=================
-
-zlibd32.mak makefile for Borland C++
-example.pas usage example of zlib
-zlibpas.pas the Pascal interface to zlib
-readme.txt this file
-
-
-Compatibility notes
-===================
-
-- Although the name "zlib" would have been more normal for the
- zlibpas unit, this name is already taken by Borland's ZLib unit.
- This is somehow unfortunate, because that unit is not a genuine
- interface to the full-fledged zlib functionality, but a suite of
- class wrappers around zlib streams. Other essential features,
- such as checksums, are missing.
- It would have been more appropriate for that unit to have a name
- like "ZStreams", or something similar.
-
-- The C and zlib-supplied types int, uInt, long, uLong, etc. are
- translated directly into Pascal types of similar sizes (Integer,
- LongInt, etc.), to avoid namespace pollution. In particular,
- there is no conversion of unsigned int into a Pascal unsigned
- integer. The Word type is non-portable and has the same size
- (16 bits) both in a 16-bit and in a 32-bit environment, unlike
- Integer. Even if there is a 32-bit Cardinal type, there is no
- real need for unsigned int in zlib under a 32-bit environment.
-
-- Except for the callbacks, the zlib function interfaces are
- assuming the calling convention normally used in Pascal
- (__pascal for DOS and Windows16, __fastcall for Windows32).
- Since the cdecl keyword is used, the old Turbo Pascal does
- not work with this interface.
-
-- The gz* function interfaces are not translated, to avoid
- interfacing problems with the C runtime library. Besides,
- gzprintf(gzFile file, const char *format, ...)
- cannot be translated into Pascal.
-
-
-Legal issues
-============
-
-The zlibpas interface is:
- Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler.
- Copyright (C) 1998 by Bob Dellaca.
- Copyright (C) 2003 by Cosmin Truta.
-
-The example program is:
- Copyright (C) 1995-2003 by Jean-loup Gailly.
- Copyright (C) 1998,1999,2000 by Jacques Nomssi Nzali.
- Copyright (C) 2003 by Cosmin Truta.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
diff --git a/cpukit/zlib/contrib/pascal/zlibd32.mak b/cpukit/zlib/contrib/pascal/zlibd32.mak
deleted file mode 100644
index 88fafa0b14..0000000000
--- a/cpukit/zlib/contrib/pascal/zlibd32.mak
+++ /dev/null
@@ -1,93 +0,0 @@
-# Makefile for zlib
-# For use with Delphi and C++ Builder under Win32
-# Updated for zlib 1.2.x by Cosmin Truta
-
-# ------------ Borland C++ ------------
-
-# This project uses the Delphi (fastcall/register) calling convention:
-LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl
-
-CC = bcc32
-LD = bcc32
-AR = tlib
-# do not use "-pr" in CFLAGS
-CFLAGS = -a -d -k- -O2 $(LOC)
-LDFLAGS =
-
-
-# variables
-ZLIB_LIB = zlib.lib
-
-OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
-OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
-OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infback.obj
-OBJP2 = +inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
-
-
-# targets
-all: $(ZLIB_LIB) example.exe minigzip.exe
-
-.c.obj:
- $(CC) -c $(CFLAGS) $*.c
-
-adler32.obj: adler32.c zlib.h zconf.h
-
-compress.obj: compress.c zlib.h zconf.h
-
-crc32.obj: crc32.c zlib.h zconf.h crc32.h
-
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
-
-gzio.obj: gzio.c zutil.h zlib.h zconf.h
-
-infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h
-
-inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
-
-trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
-
-uncompr.obj: uncompr.c zlib.h zconf.h
-
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
-
-example.obj: example.c zlib.h zconf.h
-
-minigzip.obj: minigzip.c zlib.h zconf.h
-
-
-# For the sake of the old Borland make,
-# the command line is cut to fit in the MS-DOS 128 byte limit:
-$(ZLIB_LIB): $(OBJ1) $(OBJ2)
- -del $(ZLIB_LIB)
- $(AR) $(ZLIB_LIB) $(OBJP1)
- $(AR) $(ZLIB_LIB) $(OBJP2)
-
-
-# testing
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-example.exe: example.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
-
-minigzip.exe: minigzip.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
-
-
-# cleanup
-clean:
- -del *.obj
- -del *.exe
- -del *.lib
- -del *.tds
- -del zlib.bak
- -del foo.gz
-
diff --git a/cpukit/zlib/contrib/pascal/zlibpas.pas b/cpukit/zlib/contrib/pascal/zlibpas.pas
deleted file mode 100644
index 94103d2364..0000000000
--- a/cpukit/zlib/contrib/pascal/zlibpas.pas
+++ /dev/null
@@ -1,236 +0,0 @@
-(* zlibpas -- Pascal interface to the zlib data compression library
- *
- * Copyright (C) 2003 Cosmin Truta.
- * Derived from original sources by Bob Dellaca.
- * For conditions of distribution and use, see copyright notice in readme.txt
- *)
-
-unit zlibpas;
-
-interface
-
-const
- ZLIB_VERSION = '1.2.2';
-
-type
- alloc_func = function(opaque: Pointer; items, size: Integer): Pointer;
- cdecl;
- free_func = procedure(opaque, address: Pointer);
- cdecl;
-
- in_func = function(opaque: Pointer; var buf: PByte): Integer;
- cdecl;
- out_func = function(opaque: Pointer; buf: PByte; size: Integer): Integer;
- cdecl;
-
- z_streamp = ^z_stream;
- z_stream = packed record
- next_in: PChar; (* next input byte *)
- avail_in: Integer; (* number of bytes available at next_in *)
- total_in: LongInt; (* total nb of input bytes read so far *)
-
- next_out: PChar; (* next output byte should be put there *)
- avail_out: Integer; (* remaining free space at next_out *)
- total_out: LongInt; (* total nb of bytes output so far *)
-
- msg: PChar; (* last error message, NULL if no error *)
- state: Pointer; (* not visible by applications *)
-
- zalloc: alloc_func; (* used to allocate the internal state *)
- zfree: free_func; (* used to free the internal state *)
- opaque: Pointer; (* private data object passed to zalloc and zfree *)
-
- data_type: Integer; (* best guess about the data type: ascii or binary *)
- adler: LongInt; (* adler32 value of the uncompressed data *)
- reserved: LongInt; (* reserved for future use *)
- end;
-
-(* constants *)
-const
- Z_NO_FLUSH = 0;
- Z_PARTIAL_FLUSH = 1;
- Z_SYNC_FLUSH = 2;
- Z_FULL_FLUSH = 3;
- Z_FINISH = 4;
-
- Z_OK = 0;
- Z_STREAM_END = 1;
- Z_NEED_DICT = 2;
- Z_ERRNO = -1;
- Z_STREAM_ERROR = -2;
- Z_DATA_ERROR = -3;
- Z_MEM_ERROR = -4;
- Z_BUF_ERROR = -5;
- Z_VERSION_ERROR = -6;
-
- Z_NO_COMPRESSION = 0;
- Z_BEST_SPEED = 1;
- Z_BEST_COMPRESSION = 9;
- Z_DEFAULT_COMPRESSION = -1;
-
- Z_FILTERED = 1;
- Z_HUFFMAN_ONLY = 2;
- Z_RLE = 3;
- Z_DEFAULT_STRATEGY = 0;
-
- Z_BINARY = 0;
- Z_ASCII = 1;
- Z_UNKNOWN = 2;
-
- Z_DEFLATED = 8;
-
-(* basic functions *)
-function zlibVersion: PChar;
-function deflateInit(var strm: z_stream; level: Integer): Integer;
-function deflate(var strm: z_stream; flush: Integer): Integer;
-function deflateEnd(var strm: z_stream): Integer;
-function inflateInit(var strm: z_stream): Integer;
-function inflate(var strm: z_stream; flush: Integer): Integer;
-function inflateEnd(var strm: z_stream): Integer;
-
-(* advanced functions *)
-function deflateInit2(var strm: z_stream; level, method, windowBits,
- memLevel, strategy: Integer): Integer;
-function deflateSetDictionary(var strm: z_stream; const dictionary: PChar;
- dictLength: Integer): Integer;
-function deflateCopy(var dest, source: z_stream): Integer;
-function deflateReset(var strm: z_stream): Integer;
-function deflateParams(var strm: z_stream; level, strategy: Integer): Integer;
-function deflateBound(var strm: z_stream; sourceLen: LongInt): LongInt;
-function deflatePrime(var strm: z_stream; bits, value: Integer): Integer;
-function inflateInit2(var strm: z_stream; windowBits: Integer): Integer;
-function inflateSetDictionary(var strm: z_stream; const dictionary: PChar;
- dictLength: Integer): Integer;
-function inflateSync(var strm: z_stream): Integer;
-function inflateCopy(var dest, source: z_stream): Integer;
-function inflateReset(var strm: z_stream): Integer;
-function inflateBackInit(var strm: z_stream;
- windowBits: Integer; window: PChar): Integer;
-function inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer;
- out_fn: out_func; out_desc: Pointer): Integer;
-function inflateBackEnd(var strm: z_stream): Integer;
-function zlibCompileFlags: LongInt;
-
-(* utility functions *)
-function compress(dest: PChar; var destLen: LongInt;
- const source: PChar; sourceLen: LongInt): Integer;
-function compress2(dest: PChar; var destLen: LongInt;
- const source: PChar; sourceLen: LongInt;
- level: Integer): Integer;
-function compressBound(sourceLen: LongInt): LongInt;
-function uncompress(dest: PChar; var destLen: LongInt;
- const source: PChar; sourceLen: LongInt): Integer;
-
-(* checksum functions *)
-function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt;
-function crc32(crc: LongInt; const buf: PChar; len: Integer): LongInt;
-
-(* various hacks, don't look :) *)
-function deflateInit_(var strm: z_stream; level: Integer;
- const version: PChar; stream_size: Integer): Integer;
-function inflateInit_(var strm: z_stream; const version: PChar;
- stream_size: Integer): Integer;
-function deflateInit2_(var strm: z_stream;
- level, method, windowBits, memLevel, strategy: Integer;
- const version: PChar; stream_size: Integer): Integer;
-function inflateInit2_(var strm: z_stream; windowBits: Integer;
- const version: PChar; stream_size: Integer): Integer;
-function inflateBackInit_(var strm: z_stream;
- windowBits: Integer; window: PChar;
- const version: PChar; stream_size: Integer): Integer;
-
-
-implementation
-
-{$L adler32.obj}
-{$L compress.obj}
-{$L crc32.obj}
-{$L deflate.obj}
-{$L infback.obj}
-{$L inffast.obj}
-{$L inflate.obj}
-{$L inftrees.obj}
-{$L trees.obj}
-{$L uncompr.obj}
-{$L zutil.obj}
-
-function adler32; external;
-function compress; external;
-function compress2; external;
-function compressBound; external;
-function crc32; external;
-function deflate; external;
-function deflateBound; external;
-function deflateCopy; external;
-function deflateEnd; external;
-function deflateInit_; external;
-function deflateInit2_; external;
-function deflateParams; external;
-function deflatePrime; external;
-function deflateReset; external;
-function deflateSetDictionary; external;
-function inflate; external;
-function inflateBack; external;
-function inflateBackEnd; external;
-function inflateBackInit_; external;
-function inflateCopy; external;
-function inflateEnd; external;
-function inflateInit_; external;
-function inflateInit2_; external;
-function inflateReset; external;
-function inflateSetDictionary; external;
-function inflateSync; external;
-function uncompress; external;
-function zlibCompileFlags; external;
-function zlibVersion; external;
-
-function deflateInit(var strm: z_stream; level: Integer): Integer;
-begin
- Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream));
-end;
-
-function deflateInit2(var strm: z_stream; level, method, windowBits, memLevel,
- strategy: Integer): Integer;
-begin
- Result := deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- ZLIB_VERSION, sizeof(z_stream));
-end;
-
-function inflateInit(var strm: z_stream): Integer;
-begin
- Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream));
-end;
-
-function inflateInit2(var strm: z_stream; windowBits: Integer): Integer;
-begin
- Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, sizeof(z_stream));
-end;
-
-function inflateBackInit(var strm: z_stream;
- windowBits: Integer; window: PChar): Integer;
-begin
- Result := inflateBackInit_(strm, windowBits, window,
- ZLIB_VERSION, sizeof(z_stream));
-end;
-
-function _malloc(Size: Integer): Pointer; cdecl;
-begin
- GetMem(Result, Size);
-end;
-
-procedure _free(Block: Pointer); cdecl;
-begin
- FreeMem(Block);
-end;
-
-procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;
-begin
- FillChar(P^, count, B);
-end;
-
-procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
-begin
- Move(source^, dest^, count);
-end;
-
-end.
diff --git a/cpukit/zlib/contrib/puff/Makefile b/cpukit/zlib/contrib/puff/Makefile
deleted file mode 100644
index b6b69404c7..0000000000
--- a/cpukit/zlib/contrib/puff/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-puff: puff.c puff.h
- cc -DTEST -o puff puff.c
-
-test: puff
- puff zeros.raw
-
-clean:
- rm -f puff puff.o
diff --git a/cpukit/zlib/contrib/puff/README b/cpukit/zlib/contrib/puff/README
deleted file mode 100644
index bbc4cb595e..0000000000
--- a/cpukit/zlib/contrib/puff/README
+++ /dev/null
@@ -1,63 +0,0 @@
-Puff -- A Simple Inflate
-3 Mar 2003
-Mark Adler
-madler@alumni.caltech.edu
-
-What this is --
-
-puff.c provides the routine puff() to decompress the deflate data format. It
-does so more slowly than zlib, but the code is about one-fifth the size of the
-inflate code in zlib, and written to be very easy to read.
-
-Why I wrote this --
-
-puff.c was written to document the deflate format unambiguously, by virtue of
-being working C code. It is meant to supplement RFC 1951, which formally
-describes the deflate format. I have received many questions on details of the
-deflate format, and I hope that reading this code will answer those questions.
-puff.c is heavily commented with details of the deflate format, especially
-those little nooks and cranies of the format that might not be obvious from a
-specification.
-
-puff.c may also be useful in applications where code size or memory usage is a
-very limited resource, and speed is not as important.
-
-How to use it --
-
-Well, most likely you should just be reading puff.c and using zlib for actual
-applications, but if you must ...
-
-Include puff.h in your code, which provides this prototype:
-
-int puff(unsigned char *dest, /* pointer to destination pointer */
- unsigned long *destlen, /* amount of output space */
- unsigned char *source, /* pointer to source data pointer */
- unsigned long *sourcelen); /* amount of input available */
-
-Then you can call puff() to decompress a deflate stream that is in memory in
-its entirety at source, to a sufficiently sized block of memory for the
-decompressed data at dest. puff() is the only external symbol in puff.c The
-only C library functions that puff.c needs are setjmp() and longjmp(), which
-are used to simplify error checking in the code to improve readabilty. puff.c
-does no memory allocation, and uses less than 2K bytes off of the stack.
-
-If destlen is not enough space for the uncompressed data, then inflate will
-return an error without writing more than destlen bytes. Note that this means
-that in order to decompress the deflate data successfully, you need to know
-the size of the uncompressed data ahead of time.
-
-If needed, puff() can determine the size of the uncompressed data with no
-output space. This is done by passing dest equal to (unsigned char *)0. Then
-the initial value of *destlen is ignored and *destlen is set to the length of
-the uncompressed data. So if the size of the uncompressed data is not known,
-then two passes of puff() can be used--first to determine the size, and second
-to do the actual inflation after allocating the appropriate memory. Not
-pretty, but it works. (This is one of the reasons you should be using zlib.)
-
-The deflate format is self-terminating. If the deflate stream does not end
-in *sourcelen bytes, puff() will return an error without reading at or past
-endsource.
-
-On return, *sourcelen is updated to the amount of input data consumed, and
-*destlen is updated to the size of the uncompressed data. See the comments
-in puff.c for the possible return codes for puff().
diff --git a/cpukit/zlib/contrib/puff/puff.c b/cpukit/zlib/contrib/puff/puff.c
deleted file mode 100644
index ce0cc405e3..0000000000
--- a/cpukit/zlib/contrib/puff/puff.c
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- * puff.c
- * Copyright (C) 2002-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in puff.h
- * version 1.8, 9 Jan 2004
- *
- * puff.c is a simple inflate written to be an unambiguous way to specify the
- * deflate format. It is not written for speed but rather simplicity. As a
- * side benefit, this code might actually be useful when small code is more
- * important than speed, such as bootstrap applications. For typical deflate
- * data, zlib's inflate() is about four times as fast as puff(). zlib's
- * inflate compiles to around 20K on my machine, whereas puff.c compiles to
- * around 4K on my machine (a PowerPC using GNU cc). If the faster decode()
- * function here is used, then puff() is only twice as slow as zlib's
- * inflate().
- *
- * All dynamically allocated memory comes from the stack. The stack required
- * is less than 2K bytes. This code is compatible with 16-bit int's and
- * assumes that long's are at least 32 bits. puff.c uses the short data type,
- * assumed to be 16 bits, for arrays in order to to conserve memory. The code
- * works whether integers are stored big endian or little endian.
- *
- * In the comments below are "Format notes" that describe the inflate process
- * and document some of the less obvious aspects of the format. This source
- * code is meant to supplement RFC 1951, which formally describes the deflate
- * format:
- *
- * http://www.zlib.org/rfc-deflate.html
- */
-
-/*
- * Change history:
- *
- * 1.0 10 Feb 2002 - First version
- * 1.1 17 Feb 2002 - Clarifications of some comments and notes
- * - Update puff() dest and source pointers on negative
- * errors to facilitate debugging deflators
- * - Remove longest from struct huffman -- not needed
- * - Simplify offs[] index in construct()
- * - Add input size and checking, using longjmp() to
- * maintain easy readability
- * - Use short data type for large arrays
- * - Use pointers instead of long to specify source and
- * destination sizes to avoid arbitrary 4 GB limits
- * 1.2 17 Mar 2002 - Add faster version of decode(), doubles speed (!),
- * but leave simple version for readabilty
- * - Make sure invalid distances detected if pointers
- * are 16 bits
- * - Fix fixed codes table error
- * - Provide a scanning mode for determining size of
- * uncompressed data
- * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Jean-loup]
- * - Add a puff.h file for the interface
- * - Add braces in puff() for else do [Jean-loup]
- * - Use indexes instead of pointers for readability
- * 1.4 31 Mar 2002 - Simplify construct() code set check
- * - Fix some comments
- * - Add FIXLCODES #define
- * 1.5 6 Apr 2002 - Minor comment fixes
- * 1.6 7 Aug 2002 - Minor format changes
- * 1.7 3 Mar 2003 - Added test code for distribution
- * - Added zlib-like license
- * 1.8 9 Jan 2004 - Added some comments on no distance codes case
- */
-
-#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
-#include "puff.h" /* prototype for puff() */
-
-#define local static /* for local function definitions */
-#define NIL ((unsigned char *)0) /* for no output option */
-
-/*
- * Maximums for allocations and loops. It is not useful to change these --
- * they are fixed by the deflate format.
- */
-#define MAXBITS 15 /* maximum bits in a code */
-#define MAXLCODES 286 /* maximum number of literal/length codes */
-#define MAXDCODES 30 /* maximum number of distance codes */
-#define MAXCODES (MAXLCODES+MAXDCODES) /* maximum codes lengths to read */
-#define FIXLCODES 288 /* number of fixed literal/length codes */
-
-/* input and output state */
-struct state {
- /* output state */
- unsigned char *out; /* output buffer */
- unsigned long outlen; /* available space at out */
- unsigned long outcnt; /* bytes written to out so far */
-
- /* input state */
- unsigned char *in; /* input buffer */
- unsigned long inlen; /* available input at in */
- unsigned long incnt; /* bytes read so far */
- int bitbuf; /* bit buffer */
- int bitcnt; /* number of bits in bit buffer */
-
- /* input limit error return state for bits() and decode() */
- jmp_buf env;
-};
-
-/*
- * Return need bits from the input stream. This always leaves less than
- * eight bits in the buffer. bits() works properly for need == 0.
- *
- * Format notes:
- *
- * - Bits are stored in bytes from the least significant bit to the most
- * significant bit. Therefore bits are dropped from the bottom of the bit
- * buffer, using shift right, and new bytes are appended to the top of the
- * bit buffer, using shift left.
- */
-local int bits(struct state *s, int need)
-{
- long val; /* bit accumulator (can use up to 20 bits) */
-
- /* load at least need bits into val */
- val = s->bitbuf;
- while (s->bitcnt < need) {
- if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
- val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
- s->bitcnt += 8;
- }
-
- /* drop need bits and update buffer, always zero to seven bits left */
- s->bitbuf = (int)(val >> need);
- s->bitcnt -= need;
-
- /* return need bits, zeroing the bits above that */
- return (int)(val & ((1L << need) - 1));
-}
-
-/*
- * Process a stored block.
- *
- * Format notes:
- *
- * - After the two-bit stored block type (00), the stored block length and
- * stored bytes are byte-aligned for fast copying. Therefore any leftover
- * bits in the byte that has the last bit of the type, as many as seven, are
- * discarded. The value of the discarded bits are not defined and should not
- * be checked against any expectation.
- *
- * - The second inverted copy of the stored block length does not have to be
- * checked, but it's probably a good idea to do so anyway.
- *
- * - A stored block can have zero length. This is sometimes used to byte-align
- * subsets of the compressed data for random access or partial recovery.
- */
-local int stored(struct state *s)
-{
- unsigned len; /* length of stored block */
-
- /* discard leftover bits from current byte (assumes s->bitcnt < 8) */
- s->bitbuf = 0;
- s->bitcnt = 0;
-
- /* get length and check against its one's complement */
- if (s->incnt + 4 > s->inlen) return 2; /* not enough input */
- len = s->in[s->incnt++];
- len |= s->in[s->incnt++] << 8;
- if (s->in[s->incnt++] != (~len & 0xff) ||
- s->in[s->incnt++] != ((~len >> 8) & 0xff))
- return -2; /* didn't match complement! */
-
- /* copy len bytes from in to out */
- if (s->incnt + len > s->inlen) return 2; /* not enough input */
- if (s->out != NIL) {
- if (s->outcnt + len > s->outlen)
- return 1; /* not enough output space */
- while (len--)
- s->out[s->outcnt++] = s->in[s->incnt++];
- }
- else { /* just scanning */
- s->outcnt += len;
- s->incnt += len;
- }
-
- /* done with a valid stored block */
- return 0;
-}
-
-/*
- * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
- * each length, which for a canonical code are stepped through in order.
- * symbol[] are the symbol values in canonical order, where the number of
- * entries is the sum of the counts in count[]. The decoding process can be
- * seen in the function decode() below.
- */
-struct huffman {
- short *count; /* number of symbols of each length */
- short *symbol; /* canonically ordered symbols */
-};
-
-/*
- * Decode a code from the stream s using huffman table h. Return the symbol or
- * a negative value if there is an error. If all of the lengths are zero, i.e.
- * an empty code, or if the code is incomplete and an invalid code is received,
- * then -9 is returned after reading MAXBITS bits.
- *
- * Format notes:
- *
- * - The codes as stored in the compressed data are bit-reversed relative to
- * a simple integer ordering of codes of the same lengths. Hence below the
- * bits are pulled from the compressed data one at a time and used to
- * build the code value reversed from what is in the stream in order to
- * permit simple integer comparisons for decoding. A table-based decoding
- * scheme (as used in zlib) does not need to do this reversal.
- *
- * - The first code for the shortest length is all zeros. Subsequent codes of
- * the same length are simply integer increments of the previous code. When
- * moving up a length, a zero bit is appended to the code. For a complete
- * code, the last code of the longest length will be all ones.
- *
- * - Incomplete codes are handled by this decoder, since they are permitted
- * in the deflate format. See the format notes for fixed() and dynamic().
- */
-#ifdef SLOW
-local int decode(struct state *s, struct huffman *h)
-{
- int len; /* current number of bits in code */
- int code; /* len bits being decoded */
- int first; /* first code of length len */
- int count; /* number of codes of length len */
- int index; /* index of first code of length len in symbol table */
-
- code = first = index = 0;
- for (len = 1; len <= MAXBITS; len++) {
- code |= bits(s, 1); /* get next bit */
- count = h->count[len];
- if (code < first + count) /* if length len, return symbol */
- return h->symbol[index + (code - first)];
- index += count; /* else update for next length */
- first += count;
- first <<= 1;
- code <<= 1;
- }
- return -9; /* ran out of codes */
-}
-
-/*
- * A faster version of decode() for real applications of this code. It's not
- * as readable, but it makes puff() twice as fast. And it only makes the code
- * a few percent larger.
- */
-#else /* !SLOW */
-local int decode(struct state *s, struct huffman *h)
-{
- int len; /* current number of bits in code */
- int code; /* len bits being decoded */
- int first; /* first code of length len */
- int count; /* number of codes of length len */
- int index; /* index of first code of length len in symbol table */
- int bitbuf; /* bits from stream */
- int left; /* bits left in next or left to process */
- short *next; /* next number of codes */
-
- bitbuf = s->bitbuf;
- left = s->bitcnt;
- code = first = index = 0;
- len = 1;
- next = h->count + 1;
- while (1) {
- while (left--) {
- code |= bitbuf & 1;
- bitbuf >>= 1;
- count = *next++;
- if (code < first + count) { /* if length len, return symbol */
- s->bitbuf = bitbuf;
- s->bitcnt = (s->bitcnt - len) & 7;
- return h->symbol[index + (code - first)];
- }
- index += count; /* else update for next length */
- first += count;
- first <<= 1;
- code <<= 1;
- len++;
- }
- left = (MAXBITS+1) - len;
- if (left == 0) break;
- if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
- bitbuf = s->in[s->incnt++];
- if (left > 8) left = 8;
- }
- return -9; /* ran out of codes */
-}
-#endif /* SLOW */
-
-/*
- * Given the list of code lengths length[0..n-1] representing a canonical
- * Huffman code for n symbols, construct the tables required to decode those
- * codes. Those tables are the number of codes of each length, and the symbols
- * sorted by length, retaining their original order within each length. The
- * return value is zero for a complete code set, negative for an over-
- * subscribed code set, and positive for an incomplete code set. The tables
- * can be used if the return value is zero or positive, but they cannot be used
- * if the return value is negative. If the return value is zero, it is not
- * possible for decode() using that table to return an error--any stream of
- * enough bits will resolve to a symbol. If the return value is positive, then
- * it is possible for decode() using that table to return an error for received
- * codes past the end of the incomplete lengths.
- *
- * Not used by decode(), but used for error checking, h->count[0] is the number
- * of the n symbols not in the code. So n - h->count[0] is the number of
- * codes. This is useful for checking for incomplete codes that have more than
- * one symbol, which is an error in a dynamic block.
- *
- * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS
- * This is assured by the construction of the length arrays in dynamic() and
- * fixed() and is not verified by construct().
- *
- * Format notes:
- *
- * - Permitted and expected examples of incomplete codes are one of the fixed
- * codes and any code with a single symbol which in deflate is coded as one
- * bit instead of zero bits. See the format notes for fixed() and dynamic().
- *
- * - Within a given code length, the symbols are kept in ascending order for
- * the code bits definition.
- */
-local int construct(struct huffman *h, short *length, int n)
-{
- int symbol; /* current symbol when stepping through length[] */
- int len; /* current length when stepping through h->count[] */
- int left; /* number of possible codes left of current length */
- short offs[MAXBITS+1]; /* offsets in symbol table for each length */
-
- /* count number of codes of each length */
- for (len = 0; len <= MAXBITS; len++)
- h->count[len] = 0;
- for (symbol = 0; symbol < n; symbol++)
- (h->count[length[symbol]])++; /* assumes lengths are within bounds */
- if (h->count[0] == n) /* no codes! */
- return 0; /* complete, but decode() will fail */
-
- /* check for an over-subscribed or incomplete set of lengths */
- left = 1; /* one possible code of zero length */
- for (len = 1; len <= MAXBITS; len++) {
- left <<= 1; /* one more bit, double codes left */
- left -= h->count[len]; /* deduct count from possible codes */
- if (left < 0) return left; /* over-subscribed--return negative */
- } /* left > 0 means incomplete */
-
- /* generate offsets into symbol table for each length for sorting */
- offs[1] = 0;
- for (len = 1; len < MAXBITS; len++)
- offs[len + 1] = offs[len] + h->count[len];
-
- /*
- * put symbols in table sorted by length, by symbol order within each
- * length
- */
- for (symbol = 0; symbol < n; symbol++)
- if (length[symbol] != 0)
- h->symbol[offs[length[symbol]]++] = symbol;
-
- /* return zero for complete set, positive for incomplete set */
- return left;
-}
-
-/*
- * Decode literal/length and distance codes until an end-of-block code.
- *
- * Format notes:
- *
- * - Compressed data that is after the block type if fixed or after the code
- * description if dynamic is a combination of literals and length/distance
- * pairs terminated by and end-of-block code. Literals are simply Huffman
- * coded bytes. A length/distance pair is a coded length followed by a
- * coded distance to represent a string that occurs earlier in the
- * uncompressed data that occurs again at the current location.
- *
- * - Literals, lengths, and the end-of-block code are combined into a single
- * code of up to 286 symbols. They are 256 literals (0..255), 29 length
- * symbols (257..285), and the end-of-block symbol (256).
- *
- * - There are 256 possible lengths (3..258), and so 29 symbols are not enough
- * to represent all of those. Lengths 3..10 and 258 are in fact represented
- * by just a length symbol. Lengths 11..257 are represented as a symbol and
- * some number of extra bits that are added as an integer to the base length
- * of the length symbol. The number of extra bits is determined by the base
- * length symbol. These are in the static arrays below, lens[] for the base
- * lengths and lext[] for the corresponding number of extra bits.
- *
- * - The reason that 258 gets its own symbol is that the longest length is used
- * often in highly redundant files. Note that 258 can also be coded as the
- * base value 227 plus the maximum extra value of 31. While a good deflate
- * should never do this, it is not an error, and should be decoded properly.
- *
- * - If a length is decoded, including its extra bits if any, then it is
- * followed a distance code. There are up to 30 distance symbols. Again
- * there are many more possible distances (1..32768), so extra bits are added
- * to a base value represented by the symbol. The distances 1..4 get their
- * own symbol, but the rest require extra bits. The base distances and
- * corresponding number of extra bits are below in the static arrays dist[]
- * and dext[].
- *
- * - Literal bytes are simply written to the output. A length/distance pair is
- * an instruction to copy previously uncompressed bytes to the output. The
- * copy is from distance bytes back in the output stream, copying for length
- * bytes.
- *
- * - Distances pointing before the beginning of the output data are not
- * permitted.
- *
- * - Overlapped copies, where the length is greater than the distance, are
- * allowed and common. For example, a distance of one and a length of 258
- * simply copies the last byte 258 times. A distance of four and a length of
- * twelve copies the last four bytes three times. A simple forward copy
- * ignoring whether the length is greater than the distance or not implements
- * this correctly. You should not use memcpy() since its behavior is not
- * defined for overlapped arrays. You should not use memmove() or bcopy()
- * since though their behavior -is- defined for overlapping arrays, it is
- * defined to do the wrong thing in this case.
- */
-local int codes(struct state *s,
- struct huffman *lencode,
- struct huffman *distcode)
-{
- int symbol; /* decoded symbol */
- int len; /* length for copy */
- unsigned dist; /* distance for copy */
- static const short lens[29] = { /* Size base for length codes 257..285 */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
- static const short lext[29] = { /* Extra bits for length codes 257..285 */
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
- 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
- static const short dists[30] = { /* Offset base for distance codes 0..29 */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577};
- static const short dext[30] = { /* Extra bits for distance codes 0..29 */
- 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
- 12, 12, 13, 13};
-
- /* decode literals and length/distance pairs */
- do {
- symbol = decode(s, lencode);
- if (symbol < 0) return symbol; /* invalid symbol */
- if (symbol < 256) { /* literal: symbol is the byte */
- /* write out the literal */
- if (s->out != NIL) {
- if (s->outcnt == s->outlen) return 1;
- s->out[s->outcnt] = symbol;
- }
- s->outcnt++;
- }
- else if (symbol > 256) { /* length */
- /* get and compute length */
- symbol -= 257;
- if (symbol >= 29) return -9; /* invalid fixed code */
- len = lens[symbol] + bits(s, lext[symbol]);
-
- /* get and check distance */
- symbol = decode(s, distcode);
- if (symbol < 0) return symbol; /* invalid symbol */
- dist = dists[symbol] + bits(s, dext[symbol]);
- if (dist > s->outcnt)
- return -10; /* distance too far back */
-
- /* copy length bytes from distance bytes back */
- if (s->out != NIL) {
- if (s->outcnt + len > s->outlen) return 1;
- while (len--) {
- s->out[s->outcnt] = s->out[s->outcnt - dist];
- s->outcnt++;
- }
- }
- else
- s->outcnt += len;
- }
- } while (symbol != 256); /* end of block symbol */
-
- /* done with a valid fixed or dynamic block */
- return 0;
-}
-
-/*
- * Process a fixed codes block.
- *
- * Format notes:
- *
- * - This block type can be useful for compressing small amounts of data for
- * which the size of the code descriptions in a dynamic block exceeds the
- * benefit of custom codes for that block. For fixed codes, no bits are
- * spent on code descriptions. Instead the code lengths for literal/length
- * codes and distance codes are fixed. The specific lengths for each symbol
- * can be seen in the "for" loops below.
- *
- * - The literal/length code is complete, but has two symbols that are invalid
- * and should result in an error if received. This cannot be implemented
- * simply as an incomplete code since those two symbols are in the "middle"
- * of the code. They are eight bits long and the longest literal/length\
- * code is nine bits. Therefore the code must be constructed with those
- * symbols, and the invalid symbols must be detected after decoding.
- *
- * - The fixed distance codes also have two invalid symbols that should result
- * in an error if received. Since all of the distance codes are the same
- * length, this can be implemented as an incomplete code. Then the invalid
- * codes are detected while decoding.
- */
-local int fixed(struct state *s)
-{
- static int virgin = 1;
- static short lencnt[MAXBITS+1], lensym[FIXLCODES];
- static short distcnt[MAXBITS+1], distsym[MAXDCODES];
- static struct huffman lencode = {lencnt, lensym};
- static struct huffman distcode = {distcnt, distsym};
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- int symbol;
- short lengths[FIXLCODES];
-
- /* literal/length table */
- for (symbol = 0; symbol < 144; symbol++)
- lengths[symbol] = 8;
- for (; symbol < 256; symbol++)
- lengths[symbol] = 9;
- for (; symbol < 280; symbol++)
- lengths[symbol] = 7;
- for (; symbol < FIXLCODES; symbol++)
- lengths[symbol] = 8;
- construct(&lencode, lengths, FIXLCODES);
-
- /* distance table */
- for (symbol = 0; symbol < MAXDCODES; symbol++)
- lengths[symbol] = 5;
- construct(&distcode, lengths, MAXDCODES);
-
- /* do this just once */
- virgin = 0;
- }
-
- /* decode data until end-of-block code */
- return codes(s, &lencode, &distcode);
-}
-
-/*
- * Process a dynamic codes block.
- *
- * Format notes:
- *
- * - A dynamic block starts with a description of the literal/length and
- * distance codes for that block. New dynamic blocks allow the compressor to
- * rapidly adapt to changing data with new codes optimized for that data.
- *
- * - The codes used by the deflate format are "canonical", which means that
- * the actual bits of the codes are generated in an unambiguous way simply
- * from the number of bits in each code. Therefore the code descriptions
- * are simply a list of code lengths for each symbol.
- *
- * - The code lengths are stored in order for the symbols, so lengths are
- * provided for each of the literal/length symbols, and for each of the
- * distance symbols.
- *
- * - If a symbol is not used in the block, this is represented by a zero as
- * as the code length. This does not mean a zero-length code, but rather
- * that no code should be created for this symbol. There is no way in the
- * deflate format to represent a zero-length code.
- *
- * - The maximum number of bits in a code is 15, so the possible lengths for
- * any code are 1..15.
- *
- * - The fact that a length of zero is not permitted for a code has an
- * interesting consequence. Normally if only one symbol is used for a given
- * code, then in fact that code could be represented with zero bits. However
- * in deflate, that code has to be at least one bit. So for example, if
- * only a single distance base symbol appears in a block, then it will be
- * represented by a single code of length one, in particular one 0 bit. This
- * is an incomplete code, since if a 1 bit is received, it has no meaning,
- * and should result in an error. So incomplete distance codes of one symbol
- * should be permitted, and the receipt of invalid codes should be handled.
- *
- * - It is also possible to have a single literal/length code, but that code
- * must be the end-of-block code, since every dynamic block has one. This
- * is not the most efficient way to create an empty block (an empty fixed
- * block is fewer bits), but it is allowed by the format. So incomplete
- * literal/length codes of one symbol should also be permitted.
- *
- * - If there are only literal codes and no lengths, then there are no distance
- * codes. This is represented by one distance code with zero bits.
- *
- * - The list of up to 286 length/literal lengths and up to 30 distance lengths
- * are themselves compressed using Huffman codes and run-length encoding. In
- * the list of code lengths, a 0 symbol means no code, a 1..15 symbol means
- * that length, and the symbols 16, 17, and 18 are run-length instructions.
- * Each of 16, 17, and 18 are follwed by extra bits to define the length of
- * the run. 16 copies the last length 3 to 6 times. 17 represents 3 to 10
- * zero lengths, and 18 represents 11 to 138 zero lengths. Unused symbols
- * are common, hence the special coding for zero lengths.
- *
- * - The symbols for 0..18 are Huffman coded, and so that code must be
- * described first. This is simply a sequence of up to 19 three-bit values
- * representing no code (0) or the code length for that symbol (1..7).
- *
- * - A dynamic block starts with three fixed-size counts from which is computed
- * the number of literal/length code lengths, the number of distance code
- * lengths, and the number of code length code lengths (ok, you come up with
- * a better name!) in the code descriptions. For the literal/length and
- * distance codes, lengths after those provided are considered zero, i.e. no
- * code. The code length code lengths are received in a permuted order (see
- * the order[] array below) to make a short code length code length list more
- * likely. As it turns out, very short and very long codes are less likely
- * to be seen in a dynamic code description, hence what may appear initially
- * to be a peculiar ordering.
- *
- * - Given the number of literal/length code lengths (nlen) and distance code
- * lengths (ndist), then they are treated as one long list of nlen + ndist
- * code lengths. Therefore run-length coding can and often does cross the
- * boundary between the two sets of lengths.
- *
- * - So to summarize, the code description at the start of a dynamic block is
- * three counts for the number of code lengths for the literal/length codes,
- * the distance codes, and the code length codes. This is followed by the
- * code length code lengths, three bits each. This is used to construct the
- * code length code which is used to read the remainder of the lengths. Then
- * the literal/length code lengths and distance lengths are read as a single
- * set of lengths using the code length codes. Codes are constructed from
- * the resulting two sets of lengths, and then finally you can start
- * decoding actual compressed data in the block.
- *
- * - For reference, a "typical" size for the code description in a dynamic
- * block is around 80 bytes.
- */
-local int dynamic(struct state *s)
-{
- int nlen, ndist, ncode; /* number of lengths in descriptor */
- int index; /* index of lengths[] */
- int err; /* construct() return value */
- short lengths[MAXCODES]; /* descriptor code lengths */
- short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */
- short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */
- struct huffman lencode = {lencnt, lensym}; /* length code */
- struct huffman distcode = {distcnt, distsym}; /* distance code */
- static const short order[19] = /* permutation of code length codes */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- /* get number of lengths in each table, check lengths */
- nlen = bits(s, 5) + 257;
- ndist = bits(s, 5) + 1;
- ncode = bits(s, 4) + 4;
- if (nlen > MAXLCODES || ndist > MAXDCODES)
- return -3; /* bad counts */
-
- /* read code length code lengths (really), missing lengths are zero */
- for (index = 0; index < ncode; index++)
- lengths[order[index]] = bits(s, 3);
- for (; index < 19; index++)
- lengths[order[index]] = 0;
-
- /* build huffman table for code lengths codes (use lencode temporarily) */
- err = construct(&lencode, lengths, 19);
- if (err != 0) return -4; /* require complete code set here */
-
- /* read length/literal and distance code length tables */
- index = 0;
- while (index < nlen + ndist) {
- int symbol; /* decoded value */
- int len; /* last length to repeat */
-
- symbol = decode(s, &lencode);
- if (symbol < 16) /* length in 0..15 */
- lengths[index++] = symbol;
- else { /* repeat instruction */
- len = 0; /* assume repeating zeros */
- if (symbol == 16) { /* repeat last length 3..6 times */
- if (index == 0) return -5; /* no last length! */
- len = lengths[index - 1]; /* last length */
- symbol = 3 + bits(s, 2);
- }
- else if (symbol == 17) /* repeat zero 3..10 times */
- symbol = 3 + bits(s, 3);
- else /* == 18, repeat zero 11..138 times */
- symbol = 11 + bits(s, 7);
- if (index + symbol > nlen + ndist)
- return -6; /* too many lengths! */
- while (symbol--) /* repeat last or zero symbol times */
- lengths[index++] = len;
- }
- }
-
- /* build huffman table for literal/length codes */
- err = construct(&lencode, lengths, nlen);
- if (err < 0 || (err > 0 && nlen - lencode.count[0] != 1))
- return -7; /* only allow incomplete codes if just one code */
-
- /* build huffman table for distance codes */
- err = construct(&distcode, lengths + nlen, ndist);
- if (err < 0 || (err > 0 && ndist - distcode.count[0] != 1))
- return -8; /* only allow incomplete codes if just one code */
-
- /* decode data until end-of-block code */
- return codes(s, &lencode, &distcode);
-}
-
-/*
- * Inflate source to dest. On return, destlen and sourcelen are updated to the
- * size of the uncompressed data and the size of the deflate data respectively.
- * On success, the return value of puff() is zero. If there is an error in the
- * source data, i.e. it is not in the deflate format, then a negative value is
- * returned. If there is not enough input available or there is not enough
- * output space, then a positive error is returned. In that case, destlen and
- * sourcelen are not updated to facilitate retrying from the beginning with the
- * provision of more input data or more output space. In the case of invalid
- * inflate data (a negative error), the dest and source pointers are updated to
- * facilitate the debugging of deflators.
- *
- * puff() also has a mode to determine the size of the uncompressed output with
- * no output written. For this dest must be (unsigned char *)0. In this case,
- * the input value of *destlen is ignored, and on return *destlen is set to the
- * size of the uncompressed output.
- *
- * The return codes are:
- *
- * 2: available inflate data did not terminate
- * 1: output space exhausted before completing inflate
- * 0: successful inflate
- * -1: invalid block type (type == 3)
- * -2: stored block length did not match one's complement
- * -3: dynamic block code description: too many length or distance codes
- * -4: dynamic block code description: code lengths codes incomplete
- * -5: dynamic block code description: repeat lengths with no first length
- * -6: dynamic block code description: repeat more than specified lengths
- * -7: dynamic block code description: invalid literal/length code lengths
- * -8: dynamic block code description: invalid distance code lengths
- * -9: invalid literal/length or distance code in fixed or dynamic block
- * -10: distance is too far back in fixed or dynamic block
- *
- * Format notes:
- *
- * - Three bits are read for each block to determine the kind of block and
- * whether or not it is the last block. Then the block is decoded and the
- * process repeated if it was not the last block.
- *
- * - The leftover bits in the last byte of the deflate data after the last
- * block (if it was a fixed or dynamic block) are undefined and have no
- * expected values to check.
- */
-int puff(unsigned char *dest, /* pointer to destination pointer */
- unsigned long *destlen, /* amount of output space */
- unsigned char *source, /* pointer to source data pointer */
- unsigned long *sourcelen) /* amount of input available */
-{
- struct state s; /* input/output state */
- int last, type; /* block information */
- int err; /* return value */
-
- /* initialize output state */
- s.out = dest;
- s.outlen = *destlen; /* ignored if dest is NIL */
- s.outcnt = 0;
-
- /* initialize input state */
- s.in = source;
- s.inlen = *sourcelen;
- s.incnt = 0;
- s.bitbuf = 0;
- s.bitcnt = 0;
-
- /* return if bits() or decode() tries to read past available input */
- if (setjmp(s.env) != 0) /* if came back here via longjmp() */
- err = 2; /* then skip do-loop, return error */
- else {
- /* process blocks until last block or error */
- do {
- last = bits(&s, 1); /* one if last block */
- type = bits(&s, 2); /* block type 0..3 */
- err = type == 0 ? stored(&s) :
- (type == 1 ? fixed(&s) :
- (type == 2 ? dynamic(&s) :
- -1)); /* type == 3, invalid */
- if (err != 0) break; /* return with error */
- } while (!last);
- }
-
- /* update the lengths and return */
- if (err <= 0) {
- *destlen = s.outcnt;
- *sourcelen = s.incnt;
- }
- return err;
-}
-
-#ifdef TEST
-/* Example of how to use puff() */
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-local unsigned char *yank(char *name, unsigned long *len)
-{
- unsigned long size;
- unsigned char *buf;
- FILE *in;
- struct stat s;
-
- *len = 0;
- if (stat(name, &s)) return NULL;
- if ((s.st_mode & S_IFMT) != S_IFREG) return NULL;
- size = (unsigned long)(s.st_size);
- if (size == 0 || (off_t)size != s.st_size) return NULL;
- in = fopen(name, "r");
- if (in == NULL) return NULL;
- buf = malloc(size);
- if (buf != NULL && fread(buf, 1, size, in) != size) {
- free(buf);
- buf = NULL;
- }
- fclose(in);
- *len = size;
- return buf;
-}
-
-int main(int argc, char **argv)
-{
- int ret;
- unsigned char *source;
- unsigned long len, sourcelen, destlen;
-
- if (argc < 2) return 2;
- source = yank(argv[1], &len);
- if (source == NULL) return 2;
- sourcelen = len;
- ret = puff(NIL, &destlen, source, &sourcelen);
- if (ret)
- printf("puff() failed with return code %d\n", ret);
- else {
- printf("puff() succeeded uncompressing %lu bytes\n", destlen);
- if (sourcelen < len) printf("%lu compressed bytes unused\n",
- len - sourcelen);
- }
- free(source);
- return ret;
-}
-#endif
diff --git a/cpukit/zlib/contrib/puff/puff.h b/cpukit/zlib/contrib/puff/puff.h
deleted file mode 100644
index ef612520b3..0000000000
--- a/cpukit/zlib/contrib/puff/puff.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* puff.h
- Copyright (C) 2002, 2003 Mark Adler, all rights reserved
- version 1.7, 3 Mar 2002
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Mark Adler madler@alumni.caltech.edu
- */
-
-
-/*
- * See puff.c for purpose and usage.
- */
-int puff(unsigned char *dest, /* pointer to destination pointer */
- unsigned long *destlen, /* amount of output space */
- unsigned char *source, /* pointer to source data pointer */
- unsigned long *sourcelen); /* amount of input available */
diff --git a/cpukit/zlib/contrib/puff/zeros.raw b/cpukit/zlib/contrib/puff/zeros.raw
deleted file mode 100644
index 637b7be6f5..0000000000
--- a/cpukit/zlib/contrib/puff/zeros.raw
+++ /dev/null
Binary files differ
diff --git a/cpukit/zlib/contrib/testzlib/testzlib.c b/cpukit/zlib/contrib/testzlib/testzlib.c
deleted file mode 100644
index fdabc5c192..0000000000
--- a/cpukit/zlib/contrib/testzlib/testzlib.c
+++ /dev/null
@@ -1,149 +0,0 @@
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <windows.h>
-#include "zlib.h"
-
-int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr)
-{
- FILE* stream;
- void* ptr;
- int retVal=1;
- stream=fopen(filename, "rb");
- if (stream==NULL)
- return 0;
-
- fseek(stream,0,SEEK_END);
-
- *plFileSize=ftell(stream);
- fseek(stream,0,SEEK_SET);
- ptr=malloc((*plFileSize)+1);
- if (ptr==NULL)
- retVal=0;
- else
- {
- if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))
- retVal=0;
- }
- fclose(stream);
- *pFilePtr=ptr;
- return retVal;
-}
-
-int main(int argc, char *argv[])
-{
- int BlockSizeCompress=0x8000;
- int BlockSizeUncompress=0x8000;
- int cprLevel=Z_DEFAULT_COMPRESSION ;
- long lFileSize;
- unsigned char* FilePtr;
- long lBufferSizeCpr;
- long lBufferSizeUncpr;
- long lCompressedSize=0;
- unsigned char* CprPtr;
- unsigned char* UncprPtr;
- long lSizeCpr,lSizeUncpr;
- DWORD dwGetTick;
-
- if (argc<=1)
- {
- printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");
- return 0;
- }
-
- if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)
- {
- printf("error reading %s\n",argv[1]);
- return 1;
- }
- else printf("file %s read, %u bytes\n",argv[1],lFileSize);
-
- if (argc>=3)
- BlockSizeCompress=atol(argv[2]);
-
- if (argc>=4)
- BlockSizeUncompress=atol(argv[3]);
-
- if (argc>=5)
- cprLevel=(int)atol(argv[4]);
-
- lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;
- lBufferSizeUncpr = lBufferSizeCpr;
-
- CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);
- UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);
-
- dwGetTick=GetTickCount();
- {
- z_stream zcpr;
- int ret=Z_OK;
- long lOrigToDo = lFileSize;
- long lOrigDone = 0;
- int step=0;
- memset(&zcpr,0,sizeof(z_stream));
- deflateInit(&zcpr,cprLevel);
-
- zcpr.next_in = FilePtr;
- zcpr.next_out = CprPtr;
-
-
- do
- {
- long all_read_before = zcpr.total_in;
- zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);
- zcpr.avail_out = BlockSizeCompress;
- ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);
- lOrigDone += (zcpr.total_in-all_read_before);
- lOrigToDo -= (zcpr.total_in-all_read_before);
- step++;
- } while (ret==Z_OK);
-
- lSizeCpr=zcpr.total_out;
- deflateEnd(&zcpr);
- dwGetTick=GetTickCount()-dwGetTick;
- printf("total compress size = %u, in %u step\n",lSizeCpr,step);
- printf("time = %u msec = %f sec\n\n",dwGetTick,dwGetTick/(double)1000.);
- }
-
- dwGetTick=GetTickCount();
- {
- z_stream zcpr;
- int ret=Z_OK;
- long lOrigToDo = lSizeCpr;
- long lOrigDone = 0;
- int step=0;
- memset(&zcpr,0,sizeof(z_stream));
- inflateInit(&zcpr);
-
- zcpr.next_in = CprPtr;
- zcpr.next_out = UncprPtr;
-
-
- do
- {
- long all_read_before = zcpr.total_in;
- zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);
- zcpr.avail_out = BlockSizeUncompress;
- ret=inflate(&zcpr,Z_SYNC_FLUSH);
- lOrigDone += (zcpr.total_in-all_read_before);
- lOrigToDo -= (zcpr.total_in-all_read_before);
- step++;
- } while (ret==Z_OK);
-
- lSizeUncpr=zcpr.total_out;
- inflateEnd(&zcpr);
- dwGetTick=GetTickCount()-dwGetTick;
- printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);
- printf("time = %u msec = %f sec\n\n",dwGetTick,dwGetTick/(double)1000.);
- }
-
- if (lSizeUncpr==lFileSize)
- {
- if (memcmp(FilePtr,UncprPtr,lFileSize)==0)
- printf("compare ok\n");
-
- }
-
- return 0;
-
-}
diff --git a/cpukit/zlib/contrib/testzlib/testzlib.sln b/cpukit/zlib/contrib/testzlib/testzlib.sln
deleted file mode 100644
index 86da7163d1..0000000000
--- a/cpukit/zlib/contrib/testzlib/testzlib.sln
+++ /dev/null
@@ -1,21 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- ConfigName.0 = Debug
- ConfigName.1 = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug.ActiveCfg = Debug|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug.Build.0 = Debug|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release.ActiveCfg = Release|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/cpukit/zlib/contrib/testzlib/testzlib.txt b/cpukit/zlib/contrib/testzlib/testzlib.txt
deleted file mode 100644
index 62258f1495..0000000000
--- a/cpukit/zlib/contrib/testzlib/testzlib.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-To build testzLib with Visual Studio 2005:
-
-copy to a directory file from :
-- root of zLib tree
-- contrib/testzlib
-- contrib/masmx86
-- contrib/masmx64
-- contrib/vstudio/vc7
-
-and open testzlib8.sln \ No newline at end of file
diff --git a/cpukit/zlib/contrib/testzlib/testzlib.vcproj b/cpukit/zlib/contrib/testzlib/testzlib.vcproj
deleted file mode 100644
index bd9b39bb9d..0000000000
--- a/cpukit/zlib/contrib/testzlib/testzlib.vcproj
+++ /dev/null
@@ -1,124 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="testzlib"
- ProjectGUID="{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="5"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="TRUE"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE"
- StringPooling="TRUE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
- <File
- RelativePath="testzlib.c">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc">
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
- </Filter>
- <File
- RelativePath="zlibwapi.lib">
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cpukit/zlib/contrib/untgz/Makefile b/cpukit/zlib/contrib/untgz/Makefile
deleted file mode 100644
index b54266fba2..0000000000
--- a/cpukit/zlib/contrib/untgz/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-CC=cc
-CFLAGS=-g
-
-untgz: untgz.o ../../libz.a
- $(CC) $(CFLAGS) -o untgz untgz.o -L../.. -lz
-
-untgz.o: untgz.c ../../zlib.h
- $(CC) $(CFLAGS) -c -I../.. untgz.c
-
-../../libz.a:
- cd ../..; ./configure; make
-
-clean:
- rm -f untgz untgz.o *~
diff --git a/cpukit/zlib/contrib/untgz/Makefile.msc b/cpukit/zlib/contrib/untgz/Makefile.msc
deleted file mode 100644
index 77b8602213..0000000000
--- a/cpukit/zlib/contrib/untgz/Makefile.msc
+++ /dev/null
@@ -1,17 +0,0 @@
-CC=cl
-CFLAGS=-MD
-
-untgz.exe: untgz.obj ..\..\zlib.lib
- $(CC) $(CFLAGS) untgz.obj ..\..\zlib.lib
-
-untgz.obj: untgz.c ..\..\zlib.h
- $(CC) $(CFLAGS) -c -I..\.. untgz.c
-
-..\..\zlib.lib:
- cd ..\..
- $(MAKE) -f win32\makefile.msc
- cd contrib\untgz
-
-clean:
- -del untgz.obj
- -del untgz.exe
diff --git a/cpukit/zlib/contrib/untgz/untgz.c b/cpukit/zlib/contrib/untgz/untgz.c
deleted file mode 100644
index 2c391e5986..0000000000
--- a/cpukit/zlib/contrib/untgz/untgz.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * untgz.c -- Display contents and extract files from a gzip'd TAR file
- *
- * written by Pedro A. Aranda Gutierrez <paag@tid.es>
- * adaptation to Unix by Jean-loup Gailly <jloup@gzip.org>
- * various fixes by Cosmin Truta <cosmint@cs.ubbcluj.ro>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-
-#include "zlib.h"
-
-#ifdef unix
-# include <unistd.h>
-#else
-# include <direct.h>
-# include <io.h>
-#endif
-
-#ifdef WIN32
-#include <windows.h>
-# ifndef F_OK
-# define F_OK 0
-# endif
-# define mkdir(dirname,mode) _mkdir(dirname)
-# ifdef _MSC_VER
-# define access(path,mode) _access(path,mode)
-# define chmod(path,mode) _chmod(path,mode)
-# define strdup(str) _strdup(str)
-# endif
-#else
-# include <utime.h>
-#endif
-
-
-/* values used in typeflag field */
-
-#define REGTYPE '0' /* regular file */
-#define AREGTYPE '\0' /* regular file */
-#define LNKTYPE '1' /* link */
-#define SYMTYPE '2' /* reserved */
-#define CHRTYPE '3' /* character special */
-#define BLKTYPE '4' /* block special */
-#define DIRTYPE '5' /* directory */
-#define FIFOTYPE '6' /* FIFO special */
-#define CONTTYPE '7' /* reserved */
-
-/* GNU tar extensions */
-
-#define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */
-#define GNUTYPE_LONGLINK 'K' /* long link name */
-#define GNUTYPE_LONGNAME 'L' /* long file name */
-#define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */
-#define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */
-#define GNUTYPE_SPARSE 'S' /* sparse file */
-#define GNUTYPE_VOLHDR 'V' /* tape/volume header */
-
-
-/* tar header */
-
-#define BLOCKSIZE 512
-#define SHORTNAMESIZE 100
-
-struct tar_header
-{ /* byte offset */
- char name[100]; /* 0 */
- char mode[8]; /* 100 */
- char uid[8]; /* 108 */
- char gid[8]; /* 116 */
- char size[12]; /* 124 */
- char mtime[12]; /* 136 */
- char chksum[8]; /* 148 */
- char typeflag; /* 156 */
- char linkname[100]; /* 157 */
- char magic[6]; /* 257 */
- char version[2]; /* 263 */
- char uname[32]; /* 265 */
- char gname[32]; /* 297 */
- char devmajor[8]; /* 329 */
- char devminor[8]; /* 337 */
- char prefix[155]; /* 345 */
- /* 500 */
-};
-
-union tar_buffer
-{
- char buffer[BLOCKSIZE];
- struct tar_header header;
-};
-
-struct attr_item
-{
- struct attr_item *next;
- char *fname;
- int mode;
- time_t time;
-};
-
-enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID };
-
-char *TGZfname OF((const char *));
-void TGZnotfound OF((const char *));
-
-int getoct OF((char *, int));
-char *strtime OF((time_t *));
-int setfiletime OF((char *, time_t));
-void push_attr OF((struct attr_item **, char *, int, time_t));
-void restore_attr OF((struct attr_item **));
-
-int ExprMatch OF((char *, char *));
-
-int makedir OF((char *));
-int matchname OF((int, int, char **, char *));
-
-void error OF((const char *));
-int tar OF((gzFile, int, int, int, char **));
-
-void help OF((int));
-int main OF((int, char **));
-
-char *prog;
-
-const char *TGZsuffix[] = { "\0", ".tar", ".tar.gz", ".taz", ".tgz", NULL };
-
-/* return the file name of the TGZ archive */
-/* or NULL if it does not exist */
-
-char *TGZfname (const char *arcname)
-{
- static char buffer[1024];
- int origlen,i;
-
- strcpy(buffer,arcname);
- origlen = strlen(buffer);
-
- for (i=0; TGZsuffix[i]; i++)
- {
- strcpy(buffer+origlen,TGZsuffix[i]);
- if (access(buffer,F_OK) == 0)
- return buffer;
- }
- return NULL;
-}
-
-
-/* error message for the filename */
-
-void TGZnotfound (const char *arcname)
-{
- int i;
-
- fprintf(stderr,"%s: Couldn't find ",prog);
- for (i=0;TGZsuffix[i];i++)
- fprintf(stderr,(TGZsuffix[i+1]) ? "%s%s, " : "or %s%s\n",
- arcname,
- TGZsuffix[i]);
- exit(1);
-}
-
-
-/* convert octal digits to int */
-/* on error return -1 */
-
-int getoct (char *p,int width)
-{
- int result = 0;
- char c;
-
- while (width--)
- {
- c = *p++;
- if (c == 0)
- break;
- if (c == ' ')
- continue;
- if (c < '0' || c > '7')
- return -1;
- result = result * 8 + (c - '0');
- }
- return result;
-}
-
-
-/* convert time_t to string */
-/* use the "YYYY/MM/DD hh:mm:ss" format */
-
-char *strtime (time_t *t)
-{
- struct tm *local;
- static char result[32];
-
- local = localtime(t);
- sprintf(result,"%4d/%02d/%02d %02d:%02d:%02d",
- local->tm_year+1900, local->tm_mon+1, local->tm_mday,
- local->tm_hour, local->tm_min, local->tm_sec);
- return result;
-}
-
-
-/* set file time */
-
-int setfiletime (char *fname,time_t ftime)
-{
-#ifdef WIN32
- static int isWinNT = -1;
- SYSTEMTIME st;
- FILETIME locft, modft;
- struct tm *loctm;
- HANDLE hFile;
- int result;
-
- loctm = localtime(&ftime);
- if (loctm == NULL)
- return -1;
-
- st.wYear = (WORD)loctm->tm_year + 1900;
- st.wMonth = (WORD)loctm->tm_mon + 1;
- st.wDayOfWeek = (WORD)loctm->tm_wday;
- st.wDay = (WORD)loctm->tm_mday;
- st.wHour = (WORD)loctm->tm_hour;
- st.wMinute = (WORD)loctm->tm_min;
- st.wSecond = (WORD)loctm->tm_sec;
- st.wMilliseconds = 0;
- if (!SystemTimeToFileTime(&st, &locft) ||
- !LocalFileTimeToFileTime(&locft, &modft))
- return -1;
-
- if (isWinNT < 0)
- isWinNT = (GetVersion() < 0x80000000) ? 1 : 0;
- hFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
- (isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0),
- NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- return -1;
- result = SetFileTime(hFile, NULL, NULL, &modft) ? 0 : -1;
- CloseHandle(hFile);
- return result;
-#else
- struct utimbuf settime;
-
- settime.actime = settime.modtime = ftime;
- return utime(fname,&settime);
-#endif
-}
-
-
-/* push file attributes */
-
-void push_attr(struct attr_item **list,char *fname,int mode,time_t time)
-{
- struct attr_item *item;
-
- item = (struct attr_item *)malloc(sizeof(struct attr_item));
- if (item == NULL)
- error("Out of memory");
- item->fname = strdup(fname);
- item->mode = mode;
- item->time = time;
- item->next = *list;
- *list = item;
-}
-
-
-/* restore file attributes */
-
-void restore_attr(struct attr_item **list)
-{
- struct attr_item *item, *prev;
-
- for (item = *list; item != NULL; )
- {
- setfiletime(item->fname,item->time);
- chmod(item->fname,item->mode);
- prev = item;
- item = item->next;
- free(prev);
- }
- *list = NULL;
-}
-
-
-/* match regular expression */
-
-#define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))
-
-int ExprMatch (char *string,char *expr)
-{
- while (1)
- {
- if (ISSPECIAL(*expr))
- {
- if (*expr == '/')
- {
- if (*string != '\\' && *string != '/')
- return 0;
- string ++; expr++;
- }
- else if (*expr == '*')
- {
- if (*expr ++ == 0)
- return 1;
- while (*++string != *expr)
- if (*string == 0)
- return 0;
- }
- }
- else
- {
- if (*string != *expr)
- return 0;
- if (*expr++ == 0)
- return 1;
- string++;
- }
- }
-}
-
-
-/* recursive mkdir */
-/* abort on ENOENT; ignore other errors like "directory already exists" */
-/* return 1 if OK */
-/* 0 on error */
-
-int makedir (char *newdir)
-{
- char *buffer = strdup(newdir);
- char *p;
- int len = strlen(buffer);
-
- if (len <= 0) {
- free(buffer);
- return 0;
- }
- if (buffer[len-1] == '/') {
- buffer[len-1] = '\0';
- }
- if (mkdir(buffer, 0755) == 0)
- {
- free(buffer);
- return 1;
- }
-
- p = buffer+1;
- while (1)
- {
- char hold;
-
- while(*p && *p != '\\' && *p != '/')
- p++;
- hold = *p;
- *p = 0;
- if ((mkdir(buffer, 0755) == -1) && (errno == ENOENT))
- {
- fprintf(stderr,"%s: Couldn't create directory %s\n",prog,buffer);
- free(buffer);
- return 0;
- }
- if (hold == 0)
- break;
- *p++ = hold;
- }
- free(buffer);
- return 1;
-}
-
-
-int matchname (int arg,int argc,char **argv,char *fname)
-{
- if (arg == argc) /* no arguments given (untgz tgzarchive) */
- return 1;
-
- while (arg < argc)
- if (ExprMatch(fname,argv[arg++]))
- return 1;
-
- return 0; /* ignore this for the moment being */
-}
-
-
-/* tar file list or extract */
-
-int tar (gzFile in,int action,int arg,int argc,char **argv)
-{
- union tar_buffer buffer;
- int len;
- int err;
- int getheader = 1;
- int remaining = 0;
- FILE *outfile = NULL;
- char fname[BLOCKSIZE];
- int tarmode;
- time_t tartime;
- struct attr_item *attributes = NULL;
-
- if (action == TGZ_LIST)
- printf(" date time size file\n"
- " ---------- -------- --------- -------------------------------------\n");
- while (1)
- {
- len = gzread(in, &buffer, BLOCKSIZE);
- if (len < 0)
- error(gzerror(in, &err));
- /*
- * Always expect complete blocks to process
- * the tar information.
- */
- if (len != BLOCKSIZE)
- {
- action = TGZ_INVALID; /* force error exit */
- remaining = 0; /* force I/O cleanup */
- }
-
- /*
- * If we have to get a tar header
- */
- if (getheader >= 1)
- {
- /*
- * if we met the end of the tar
- * or the end-of-tar block,
- * we are done
- */
- if (len == 0 || buffer.header.name[0] == 0)
- break;
-
- tarmode = getoct(buffer.header.mode,8);
- tartime = (time_t)getoct(buffer.header.mtime,12);
- if (tarmode == -1 || tartime == (time_t)-1)
- {
- buffer.header.name[0] = 0;
- action = TGZ_INVALID;
- }
-
- if (getheader == 1)
- {
- strncpy(fname,buffer.header.name,SHORTNAMESIZE);
- if (fname[SHORTNAMESIZE-1] != 0)
- fname[SHORTNAMESIZE] = 0;
- }
- else
- {
- /*
- * The file name is longer than SHORTNAMESIZE
- */
- if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0)
- error("bad long name");
- getheader = 1;
- }
-
- /*
- * Act according to the type flag
- */
- switch (buffer.header.typeflag)
- {
- case DIRTYPE:
- if (action == TGZ_LIST)
- printf(" %s <dir> %s\n",strtime(&tartime),fname);
- if (action == TGZ_EXTRACT)
- {
- makedir(fname);
- push_attr(&attributes,fname,tarmode,tartime);
- }
- break;
- case REGTYPE:
- case AREGTYPE:
- remaining = getoct(buffer.header.size,12);
- if (remaining == -1)
- {
- action = TGZ_INVALID;
- break;
- }
- if (action == TGZ_LIST)
- printf(" %s %9d %s\n",strtime(&tartime),remaining,fname);
- else if (action == TGZ_EXTRACT)
- {
- if (matchname(arg,argc,argv,fname))
- {
- outfile = fopen(fname,"wb");
- if (outfile == NULL) {
- /* try creating directory */
- char *p = strrchr(fname, '/');
- if (p != NULL) {
- *p = '\0';
- makedir(fname);
- *p = '/';
- outfile = fopen(fname,"wb");
- }
- }
- if (outfile != NULL)
- printf("Extracting %s\n",fname);
- else
- fprintf(stderr, "%s: Couldn't create %s",prog,fname);
- }
- else
- outfile = NULL;
- }
- getheader = 0;
- break;
- case GNUTYPE_LONGLINK:
- case GNUTYPE_LONGNAME:
- remaining = getoct(buffer.header.size,12);
- if (remaining < 0 || remaining >= BLOCKSIZE)
- {
- action = TGZ_INVALID;
- break;
- }
- len = gzread(in, fname, BLOCKSIZE);
- if (len < 0)
- error(gzerror(in, &err));
- if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining)
- {
- action = TGZ_INVALID;
- break;
- }
- getheader = 2;
- break;
- default:
- if (action == TGZ_LIST)
- printf(" %s <---> %s\n",strtime(&tartime),fname);
- break;
- }
- }
- else
- {
- unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;
-
- if (outfile != NULL)
- {
- if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
- {
- fprintf(stderr,
- "%s: Error writing %s -- skipping\n",prog,fname);
- fclose(outfile);
- outfile = NULL;
- remove(fname);
- }
- }
- remaining -= bytes;
- }
-
- if (remaining == 0)
- {
- getheader = 1;
- if (outfile != NULL)
- {
- fclose(outfile);
- outfile = NULL;
- if (action != TGZ_INVALID)
- push_attr(&attributes,fname,tarmode,tartime);
- }
- }
-
- /*
- * Abandon if errors are found
- */
- if (action == TGZ_INVALID)
- {
- error("broken archive");
- break;
- }
- }
-
- /*
- * Restore file modes and time stamps
- */
- restore_attr(&attributes);
-
- if (gzclose(in) != Z_OK)
- error("failed gzclose");
-
- return 0;
-}
-
-
-/* ============================================================ */
-
-void help(int exitval)
-{
- printf("untgz version 0.2.1\n"
- " using zlib version %s\n\n",
- zlibVersion());
- printf("Usage: untgz file.tgz extract all files\n"
- " untgz file.tgz fname ... extract selected files\n"
- " untgz -l file.tgz list archive contents\n"
- " untgz -h display this help\n");
- exit(exitval);
-}
-
-void error(const char *msg)
-{
- fprintf(stderr, "%s: %s\n", prog, msg);
- exit(1);
-}
-
-
-/* ============================================================ */
-
-#if defined(WIN32) && defined(__GNUC__)
-int _CRT_glob = 0; /* disable argument globbing in MinGW */
-#endif
-
-int main(int argc,char **argv)
-{
- int action = TGZ_EXTRACT;
- int arg = 1;
- char *TGZfile;
- gzFile *f;
-
- prog = strrchr(argv[0],'\\');
- if (prog == NULL)
- {
- prog = strrchr(argv[0],'/');
- if (prog == NULL)
- {
- prog = strrchr(argv[0],':');
- if (prog == NULL)
- prog = argv[0];
- else
- prog++;
- }
- else
- prog++;
- }
- else
- prog++;
-
- if (argc == 1)
- help(0);
-
- if (strcmp(argv[arg],"-l") == 0)
- {
- action = TGZ_LIST;
- if (argc == ++arg)
- help(0);
- }
- else if (strcmp(argv[arg],"-h") == 0)
- {
- help(0);
- }
-
- if ((TGZfile = TGZfname(argv[arg])) == NULL)
- TGZnotfound(argv[arg]);
-
- ++arg;
- if ((action == TGZ_LIST) && (arg != argc))
- help(1);
-
-/*
- * Process the TGZ file
- */
- switch(action)
- {
- case TGZ_LIST:
- case TGZ_EXTRACT:
- f = gzopen(TGZfile,"rb");
- if (f == NULL)
- {
- fprintf(stderr,"%s: Couldn't gzopen %s\n",prog,TGZfile);
- return 1;
- }
- exit(tar(f, action, arg, argc, argv));
- break;
-
- default:
- error("Unknown option");
- exit(1);
- }
-
- return 0;
-}
diff --git a/cpukit/zlib/contrib/vstudio/readme.txt b/cpukit/zlib/contrib/vstudio/readme.txt
deleted file mode 100644
index e709d1b9d9..0000000000
--- a/cpukit/zlib/contrib/vstudio/readme.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-Building instructions for the DLL versions of Zlib 1.2.x
-=======================================================
-
-This directory contains projects that build zlib and minizip using
-Microsoft Visual C++ 7.0/7.1.
-
-You don't need to build these projects yourself. You can download the
-binaries from:
- http://www.winimage.com/zLibDll
-
-More information can be found at this site.
-
-
-Build instructions
-------------------
-- Unzip zlib*.zip and copy the files from contrib\vstudio\vc7,
- from contrib\vstudio\masmx86 and from contrib\minizip into the same
- directory.
-- Download the crtdll library from
- http://www.winimage.com/zLibDll/crtdll.zip
- Unzip crtdll.zip to extract crtdll.lib.
-- If you are using x86, use the Release target.
-- Open zlibvc.sln with Microsoft Visual C++ 7.0 or 7.1
- (Visual Studio .Net 2002 or 2003).
-
-
-Important
----------
-- To use zlibwapi.dll in your application, you must define the
- macro ZLIB_WINAPI when compiling your application's source files.
-
-
-Additional notes
-----------------
-- This DLL, named zlibwapi.dll, is compatible to the old zlib.dll built
- by Gilles Vollant from the zlib 1.1.x sources, and distributed at
- http://www.winimage.com/zLibDll
- It uses the WINAPI calling convention for the exported functions, and
- includes the minizip functionality. If your application needs that
- particular build of zlib.dll, you can rename zlibwapi.dll to zlib.dll.
-
-- The new DLL was renamed because there exist several incompatible
- versions of zlib.dll on the Internet.
-
-- There is also an official DLL build of zlib, named zlib1.dll. This one
- is exporting the functions using the CDECL convention. See the file
- win32\DLL_FAQ.txt found in this zlib distribution.
-
-- There used to be a ZLIB_DLL macro in zlib 1.1.x, but now this symbol
- has a slightly different effect. To avoid compatibility problems, do
- not define it here.
-
-
-Gilles Vollant
-info@winimage.com
diff --git a/cpukit/zlib/contrib/vstudio/vc7/miniunz.vcproj b/cpukit/zlib/contrib/vstudio/vc7/miniunz.vcproj
deleted file mode 100644
index 935c250e5f..0000000000
--- a/cpukit/zlib/contrib/vstudio/vc7/miniunz.vcproj
+++ /dev/null
@@ -1,124 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="miniunz"
- ProjectGUID="{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="5"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/miniunz.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="TRUE"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE"
- StringPooling="TRUE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/miniunz.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
- <File
- RelativePath="miniunz.c">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc">
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
- </Filter>
- <File
- RelativePath="zlibwapi.lib">
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cpukit/zlib/contrib/vstudio/vc7/minizip.vcproj b/cpukit/zlib/contrib/vstudio/vc7/minizip.vcproj
deleted file mode 100644
index e6f910742c..0000000000
--- a/cpukit/zlib/contrib/vstudio/vc7/minizip.vcproj
+++ /dev/null
@@ -1,124 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="minizip"
- ProjectGUID="{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="5"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/minizip.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/minizip.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="TRUE"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE"
- StringPooling="TRUE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/minizip.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
- <File
- RelativePath="minizip.c">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc">
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
- </Filter>
- <File
- RelativePath="zlibwapi.lib">
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cpukit/zlib/contrib/vstudio/vc7/zlib.rc b/cpukit/zlib/contrib/vstudio/vc7/zlib.rc
deleted file mode 100644
index d35cef0519..0000000000
--- a/cpukit/zlib/contrib/vstudio/vc7/zlib.rc
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <windows.h>
-
-#define IDR_VERSION1 1
-IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
- FILEVERSION 1,2,2,2
- PRODUCTVERSION 1,2,2,2
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS 0
- FILEOS VOS_DOS_WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0 // not used
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904E4"
- //language ID = U.S. English, char set = Windows, Multilingual
-
- BEGIN
- VALUE "FileDescription", "zlib data compression library\0"
- VALUE "FileVersion", "1.2.2.2\0"
- VALUE "InternalName", "zlib\0"
- VALUE "OriginalFilename", "zlib.dll\0"
- VALUE "ProductName", "ZLib.DLL\0"
- VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
- VALUE "LegalCopyright", "(C) 1995-2003 Jean-loup Gailly & Mark Adler\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x0409, 1252
- END
-END
diff --git a/cpukit/zlib/contrib/vstudio/vc7/zlibstat.vcproj b/cpukit/zlib/contrib/vstudio/vc7/zlibstat.vcproj
deleted file mode 100644
index eb182f7a88..0000000000
--- a/cpukit/zlib/contrib/vstudio/vc7/zlibstat.vcproj
+++ /dev/null
@@ -1,242 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="zlibstat"
- SccProjectName=""
- SccLocalPath="">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory=".\zlibstatDebug"
- IntermediateDirectory=".\zlibstatDebug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
- ExceptionHandling="FALSE"
- RuntimeLibrary="5"
- PrecompiledHeaderFile=".\zlibstatDebug/zlibstat.pch"
- AssemblerListingLocation=".\zlibstatDebug/"
- ObjectFile=".\zlibstatDebug/"
- ProgramDataBaseFileName=".\zlibstatDebug/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="1"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/NODEFAULTLIB "
- OutputFile=".\zlibstatDebug\zlibstat.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="ReleaseAxp|Win32"
- OutputDirectory=".\zlibsta0"
- IntermediateDirectory=".\zlibsta0"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibsta0/zlibstat.pch"
- AssemblerListingLocation=".\zlibsta0/"
- ObjectFile=".\zlibsta0/"
- ProgramDataBaseFileName=".\zlibsta0/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/NODEFAULTLIB "
- OutputFile=".\zlibsta0\zlibstat.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory=".\zlibstat"
- IntermediateDirectory=".\zlibstat"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;ASMV;ASMINF"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibstat/zlibstat.pch"
- AssemblerListingLocation=".\zlibstat/"
- ObjectFile=".\zlibstat/"
- ProgramDataBaseFileName=".\zlibstat/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="gvmat32.obj inffas32.obj /NODEFAULTLIB "
- OutputFile=".\zlibstat\zlibstat.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|Win32"
- OutputDirectory="zlibstatWithoutAsm"
- IntermediateDirectory="zlibstatWithoutAsm"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibstat/zlibstat.pch"
- AssemblerListingLocation=".\zlibstatWithoutAsm/"
- ObjectFile=".\zlibstatWithoutAsm/"
- ProgramDataBaseFileName=".\zlibstatWithoutAsm/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions=" /NODEFAULTLIB "
- OutputFile=".\zlibstatWithoutAsm\zlibstat.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="">
- <File
- RelativePath=".\adler32.c">
- </File>
- <File
- RelativePath=".\compress.c">
- </File>
- <File
- RelativePath=".\crc32.c">
- </File>
- <File
- RelativePath=".\deflate.c">
- </File>
- <File
- RelativePath=".\gvmat32c.c">
- </File>
- <File
- RelativePath=".\gzio.c">
- </File>
- <File
- RelativePath=".\infback.c">
- </File>
- <File
- RelativePath=".\inffast.c">
- </File>
- <File
- RelativePath=".\inflate.c">
- </File>
- <File
- RelativePath=".\inftrees.c">
- </File>
- <File
- RelativePath=".\ioapi.c">
- </File>
- <File
- RelativePath=".\trees.c">
- </File>
- <File
- RelativePath=".\uncompr.c">
- </File>
- <File
- RelativePath=".\unzip.c">
- </File>
- <File
- RelativePath=".\zip.c">
- </File>
- <File
- RelativePath=".\zlib.rc">
- </File>
- <File
- RelativePath=".\zlibvc.def">
- </File>
- <File
- RelativePath=".\zutil.c">
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cpukit/zlib/contrib/vstudio/vc7/zlibvc.def b/cpukit/zlib/contrib/vstudio/vc7/zlibvc.def
deleted file mode 100644
index 6bc26c4db4..0000000000
--- a/cpukit/zlib/contrib/vstudio/vc7/zlibvc.def
+++ /dev/null
@@ -1,92 +0,0 @@
-
-VERSION 1.21
-
-HEAPSIZE 1048576,8192
-
-EXPORTS
- adler32 @1
- compress @2
- crc32 @3
- deflate @4
- deflateCopy @5
- deflateEnd @6
- deflateInit2_ @7
- deflateInit_ @8
- deflateParams @9
- deflateReset @10
- deflateSetDictionary @11
- gzclose @12
- gzdopen @13
- gzerror @14
- gzflush @15
- gzopen @16
- gzread @17
- gzwrite @18
- inflate @19
- inflateEnd @20
- inflateInit2_ @21
- inflateInit_ @22
- inflateReset @23
- inflateSetDictionary @24
- inflateSync @25
- uncompress @26
- zlibVersion @27
- gzprintf @28
- gzputc @29
- gzgetc @30
- gzseek @31
- gzrewind @32
- gztell @33
- gzeof @34
- gzsetparams @35
- zError @36
- inflateSyncPoint @37
- get_crc_table @38
- compress2 @39
- gzputs @40
- gzgets @41
- inflateCopy @42
- inflateBackInit_ @43
- inflateBack @44
- inflateBackEnd @45
- compressBound @46
- deflateBound @47
- gzclearerr @48
- gzungetc @49
- zlibCompileFlags @50
- deflatePrime @51
-
- unzOpen @61
- unzClose @62
- unzGetGlobalInfo @63
- unzGetCurrentFileInfo @64
- unzGoToFirstFile @65
- unzGoToNextFile @66
- unzOpenCurrentFile @67
- unzReadCurrentFile @68
- unzOpenCurrentFile3 @69
- unztell @70
- unzeof @71
- unzCloseCurrentFile @72
- unzGetGlobalComment @73
- unzStringFileNameCompare @74
- unzLocateFile @75
- unzGetLocalExtrafield @76
- unzOpen2 @77
- unzOpenCurrentFile2 @78
- unzOpenCurrentFilePassword @79
-
- zipOpen @80
- zipOpenNewFileInZip @81
- zipWriteInFileInZip @82
- zipCloseFileInZip @83
- zipClose @84
- zipOpenNewFileInZip2 @86
- zipCloseFileInZipRaw @87
- zipOpen2 @88
- zipOpenNewFileInZip3 @89
-
- unzGetFilePos @100
- unzGoToFilePos @101
-
- fill_win32_filefunc @110
diff --git a/cpukit/zlib/contrib/vstudio/vc7/zlibvc.sln b/cpukit/zlib/contrib/vstudio/vc7/zlibvc.sln
deleted file mode 100644
index 5a007ff697..0000000000
--- a/cpukit/zlib/contrib/vstudio/vc7/zlibvc.sln
+++ /dev/null
@@ -1,66 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- ConfigName.0 = Debug
- ConfigName.1 = Release
- ConfigName.2 = ReleaseAxp
- ConfigName.3 = ReleaseWithoutAsm
- ConfigName.4 = ReleaseWithoutCrtdll
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug.ActiveCfg = Debug|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug.Build.0 = Debug|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release.ActiveCfg = Release|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release.Build.0 = Release|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseAxp.ActiveCfg = ReleaseAxp|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseAxp.Build.0 = ReleaseAxp|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm.ActiveCfg = ReleaseWithoutAsm|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm.Build.0 = ReleaseWithoutAsm|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutCrtdll.ActiveCfg = ReleaseAxp|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutCrtdll.Build.0 = ReleaseAxp|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug.ActiveCfg = Debug|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug.Build.0 = Debug|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release.ActiveCfg = Release|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release.Build.0 = Release|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseAxp.ActiveCfg = ReleaseAxp|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseAxp.Build.0 = ReleaseAxp|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm.ActiveCfg = ReleaseWithoutAsm|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm.Build.0 = ReleaseWithoutAsm|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutCrtdll.ActiveCfg = ReleaseWithoutCrtdll|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutCrtdll.Build.0 = ReleaseWithoutCrtdll|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug.ActiveCfg = Debug|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug.Build.0 = Debug|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release.ActiveCfg = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release.Build.0 = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAxp.ActiveCfg = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAxp.Build.0 = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm.ActiveCfg = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm.Build.0 = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutCrtdll.ActiveCfg = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutCrtdll.Build.0 = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug.ActiveCfg = Debug|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug.Build.0 = Debug|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release.ActiveCfg = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release.Build.0 = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseAxp.ActiveCfg = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseAxp.Build.0 = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm.ActiveCfg = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm.Build.0 = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutCrtdll.ActiveCfg = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutCrtdll.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/cpukit/zlib/contrib/vstudio/vc7/zlibvc.vcproj b/cpukit/zlib/contrib/vstudio/vc7/zlibvc.vcproj
deleted file mode 100644
index 4e57bcdff6..0000000000
--- a/cpukit/zlib/contrib/vstudio/vc7/zlibvc.vcproj
+++ /dev/null
@@ -1,436 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="zlibvc"
- SccProjectName=""
- SccLocalPath="">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory=".\DebugDll"
- IntermediateDirectory=".\DebugDll"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
- ExceptionHandling="FALSE"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=".\DebugDll/zlibvc.pch"
- AssemblerListingLocation=".\DebugDll/"
- ObjectFile=".\DebugDll/"
- ProgramDataBaseFileName=".\DebugDll/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="gvmat32.obj inffas32.obj"
- OutputFile=".\DebugDll\zlibwapi.dll"
- LinkIncremental="2"
- SuppressStartupBanner="TRUE"
- ModuleDefinitionFile=".\zlibvc.def"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile=".\DebugDll/zlibwapi.pdb"
- SubSystem="2"
- ImportLibrary=".\DebugDll/zlibwapi.lib"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\DebugDll/zlibvc.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|Win32"
- OutputDirectory=".\zlibDllWithoutAsm"
- IntermediateDirectory=".\zlibDllWithoutAsm"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- PreprocessorDefinitions="WIN32,ZLIB_WINAPI"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibDllWithoutAsm/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation=".\zlibDllWithoutAsm/"
- ObjectFile=".\zlibDllWithoutAsm/"
- ProgramDataBaseFileName=".\zlibDllWithoutAsm/"
- BrowseInformation="1"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="crtdll.lib"
- OutputFile=".\zlibDllWithoutAsm\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreAllDefaultLibraries="TRUE"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile=".\zlibDllWithoutAsm/zlibwapi.pdb"
- GenerateMapFile="TRUE"
- MapFileName=".\zlibDllWithoutAsm/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary=".\zlibDllWithoutAsm/zlibwapi.lib"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\zlibDllWithoutAsm/zlibvc.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="ReleaseWithoutCrtdll|Win32"
- OutputDirectory=".\zlibDllWithoutCrtDll"
- IntermediateDirectory=".\zlibDllWithoutCrtDll"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibDllWithoutCrtDll/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation=".\zlibDllWithoutCrtDll/"
- ObjectFile=".\zlibDllWithoutCrtDll/"
- ProgramDataBaseFileName=".\zlibDllWithoutCrtDll/"
- BrowseInformation="1"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="gvmat32.obj inffas32.obj "
- OutputFile=".\zlibDllWithoutCrtDll\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreAllDefaultLibraries="FALSE"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile=".\zlibDllWithoutCrtDll/zlibwapi.pdb"
- GenerateMapFile="TRUE"
- MapFileName=".\zlibDllWithoutCrtDll/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary=".\zlibDllWithoutCrtDll/zlibwapi.lib"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\zlibDllWithoutCrtDll/zlibvc.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="ReleaseAxp|Win32"
- OutputDirectory=".\zlibvc__"
- IntermediateDirectory=".\zlibvc__"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- PreprocessorDefinitions="WIN32,ZLIB_WINAPI"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibvc__/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation=".\zlibvc__/"
- ObjectFile=".\zlibvc__/"
- ProgramDataBaseFileName=".\zlibvc__/"
- BrowseInformation="1"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="crtdll.lib"
- OutputFile="zlibvc__\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreAllDefaultLibraries="TRUE"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile=".\zlibvc__/zlibwapi.pdb"
- GenerateMapFile="TRUE"
- MapFileName=".\zlibvc__/zlibwapi.map"
- SubSystem="2"
- ImportLibrary=".\zlibvc__/zlibwapi.lib"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\zlibvc__/zlibvc.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory=".\ReleaseDll"
- IntermediateDirectory=".\ReleaseDll"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\ReleaseDll/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation=".\ReleaseDll/"
- ObjectFile=".\ReleaseDll/"
- ProgramDataBaseFileName=".\ReleaseDll/"
- BrowseInformation="1"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="gvmat32.obj inffas32.obj crtdll.lib"
- OutputFile=".\ReleaseDll\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreAllDefaultLibraries="TRUE"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile=".\ReleaseDll/zlibwapi.pdb"
- GenerateMapFile="TRUE"
- MapFileName=".\ReleaseDll/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary=".\ReleaseDll/zlibwapi.lib"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\Release/zlibvc.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90">
- <File
- RelativePath=".\adler32.c">
- </File>
- <File
- RelativePath=".\compress.c">
- </File>
- <File
- RelativePath=".\crc32.c">
- </File>
- <File
- RelativePath=".\deflate.c">
- </File>
- <File
- RelativePath=".\gvmat32c.c">
- <FileConfiguration
- Name="ReleaseWithoutAsm|Win32"
- ExcludedFromBuild="TRUE">
- <Tool
- Name="VCCLCompilerTool"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath=".\gzio.c">
- </File>
- <File
- RelativePath=".\infback.c">
- </File>
- <File
- RelativePath=".\inffast.c">
- </File>
- <File
- RelativePath=".\inflate.c">
- </File>
- <File
- RelativePath=".\inftrees.c">
- </File>
- <File
- RelativePath=".\ioapi.c">
- </File>
- <File
- RelativePath=".\iowin32.c">
- </File>
- <File
- RelativePath=".\trees.c">
- </File>
- <File
- RelativePath=".\uncompr.c">
- </File>
- <File
- RelativePath=".\unzip.c">
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions="ZLIB_INTERNAL"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath=".\zip.c">
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions="ZLIB_INTERNAL"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath=".\zlib.rc">
- </File>
- <File
- RelativePath=".\zlibvc.def">
- </File>
- <File
- RelativePath=".\zutil.c">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;fi;fd">
- <File
- RelativePath=".\deflate.h">
- </File>
- <File
- RelativePath=".\infblock.h">
- </File>
- <File
- RelativePath=".\infcodes.h">
- </File>
- <File
- RelativePath=".\inffast.h">
- </File>
- <File
- RelativePath=".\inftrees.h">
- </File>
- <File
- RelativePath=".\infutil.h">
- </File>
- <File
- RelativePath=".\zconf.h">
- </File>
- <File
- RelativePath=".\zlib.h">
- </File>
- <File
- RelativePath=".\zutil.h">
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/cpukit/zlib/crc32.c b/cpukit/zlib/crc32.c
index 62b025f290..51d5504035 100644
--- a/cpukit/zlib/crc32.c
+++ b/cpukit/zlib/crc32.c
@@ -9,7 +9,7 @@
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
*/
-/* @(#) $Id$ */
+/* $Id$ */
/*
Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
@@ -201,13 +201,13 @@ local void write_table(out, table)
/* =========================================================================
* This function can be used by asm versions of crc32()
*/
-const unsigned long FAR * ZEXPORT get_crc_table()
+const uLongf * ZEXPORT get_crc_table()
{
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */
- return (const unsigned long FAR *)crc_table;
+ return (const uLongf *)crc_table;
}
/* ========================================================================= */
@@ -215,10 +215,10 @@ const unsigned long FAR * ZEXPORT get_crc_table()
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
/* ========================================================================= */
-unsigned long ZEXPORT crc32(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
+uLong ZEXPORT crc32(crc, buf, len)
+ uLong crc;
+ const Bytef *buf;
+ uInt len;
{
if (buf == Z_NULL) return 0UL;
diff --git a/cpukit/zlib/deflate.c b/cpukit/zlib/deflate.c
index 159f94660b..660aad479d 100644
--- a/cpukit/zlib/deflate.c
+++ b/cpukit/zlib/deflate.c
@@ -47,7 +47,7 @@
*
*/
-/* @(#) $Id$ */
+/* $Id$ */
#include "deflate.h"
diff --git a/cpukit/zlib/deflate.h b/cpukit/zlib/deflate.h
index c7c3ffdb40..2b74e927f8 100644
--- a/cpukit/zlib/deflate.h
+++ b/cpukit/zlib/deflate.h
@@ -8,7 +8,7 @@
subject to change. Applications should only use zlib.h.
*/
-/* @(#) $Id$ */
+/* $Id$ */
#ifndef DEFLATE_H
#define DEFLATE_H
diff --git a/cpukit/zlib/example.c b/cpukit/zlib/example.c
deleted file mode 100644
index 6c8a0ee763..0000000000
--- a/cpukit/zlib/example.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/* example.c -- usage example of the zlib compression library
- * Copyright (C) 1995-2004 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include <stdio.h>
-#include "zlib.h"
-
-#ifdef STDC
-# include <string.h>
-# include <stdlib.h>
-#endif
-
-#if defined(VMS) || defined(RISCOS)
-# define TESTFILE "foo-gz"
-#else
-# define TESTFILE "foo.gz"
-#endif
-
-#define CHECK_ERR(err, msg) { \
- if (err != Z_OK) { \
- fprintf(stderr, "%s error: %d\n", msg, err); \
- exit(1); \
- } \
-}
-
-const char hello[] = "hello, hello!";
-/* "hello world" would be more standard, but the repeated "hello"
- * stresses the compression code better, sorry...
- */
-
-const char dictionary[] = "hello";
-uLong dictId; /* Adler32 value of the dictionary */
-
-void test_compress OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_gzio OF((const char *fname,
- Byte *uncompr, uLong uncomprLen));
-void test_deflate OF((Byte *compr, uLong comprLen));
-void test_inflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_large_deflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_large_inflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_flush OF((Byte *compr, uLong *comprLen));
-void test_sync OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_dict_deflate OF((Byte *compr, uLong comprLen));
-void test_dict_inflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-int main OF((int argc, char *argv[]));
-
-/* ===========================================================================
- * Test compress() and uncompress()
- */
-void test_compress(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- uLong len = (uLong)strlen(hello)+1;
-
- err = compress(compr, &comprLen, (const Bytef*)hello, len);
- CHECK_ERR(err, "compress");
-
- strcpy((char*)uncompr, "garbage");
-
- err = uncompress(uncompr, &uncomprLen, compr, comprLen);
- CHECK_ERR(err, "uncompress");
-
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad uncompress\n");
- exit(1);
- } else {
- printf("uncompress(): %s\n", (char *)uncompr);
- }
-}
-
-/* ===========================================================================
- * Test read/write of .gz files
- */
-void test_gzio(fname, uncompr, uncomprLen)
- const char *fname; /* compressed file name */
- Byte *uncompr;
- uLong uncomprLen;
-{
-#ifdef NO_GZCOMPRESS
- fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
-#else
- int err;
- int len = (int)strlen(hello)+1;
- gzFile file;
- z_off_t pos;
-
- file = gzopen(fname, "wb");
- if (file == NULL) {
- fprintf(stderr, "gzopen error\n");
- exit(1);
- }
- gzputc(file, 'h');
- if (gzputs(file, "ello") != 4) {
- fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
- exit(1);
- }
- if (gzprintf(file, ", %s!", "hello") != 8) {
- fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
- exit(1);
- }
- gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
- gzclose(file);
-
- file = gzopen(fname, "rb");
- if (file == NULL) {
- fprintf(stderr, "gzopen error\n");
- exit(1);
- }
- strcpy((char*)uncompr, "garbage");
-
- if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
- fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
- exit(1);
- }
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
- exit(1);
- } else {
- printf("gzread(): %s\n", (char*)uncompr);
- }
-
- pos = gzseek(file, -8L, SEEK_CUR);
- if (pos != 6 || gztell(file) != pos) {
- fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
- (long)pos, (long)gztell(file));
- exit(1);
- }
-
- if (gzgetc(file) != ' ') {
- fprintf(stderr, "gzgetc error\n");
- exit(1);
- }
-
- if (gzungetc(' ', file) != ' ') {
- fprintf(stderr, "gzungetc error\n");
- exit(1);
- }
-
- gzgets(file, (char*)uncompr, (int)uncomprLen);
- if (strlen((char*)uncompr) != 7) { /* " hello!" */
- fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
- exit(1);
- }
- if (strcmp((char*)uncompr, hello + 6)) {
- fprintf(stderr, "bad gzgets after gzseek\n");
- exit(1);
- } else {
- printf("gzgets() after gzseek: %s\n", (char*)uncompr);
- }
-
- gzclose(file);
-#endif
-}
-
-/* ===========================================================================
- * Test deflate() with small buffers
- */
-void test_deflate(compr, comprLen)
- Byte *compr;
- uLong comprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
- uLong len = (uLong)strlen(hello)+1;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
- CHECK_ERR(err, "deflateInit");
-
- c_stream.next_in = (Bytef*)hello;
- c_stream.next_out = compr;
-
- while (c_stream.total_in != len && c_stream.total_out < comprLen) {
- c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
- }
- /* Finish the stream, still forcing small buffers: */
- for (;;) {
- c_stream.avail_out = 1;
- err = deflate(&c_stream, Z_FINISH);
- if (err == Z_STREAM_END) break;
- CHECK_ERR(err, "deflate");
- }
-
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-}
-
-/* ===========================================================================
- * Test inflate() with small buffers
- */
-void test_inflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = 0;
- d_stream.next_out = uncompr;
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
- d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
- err = inflate(&d_stream, Z_NO_FLUSH);
- if (err == Z_STREAM_END) break;
- CHECK_ERR(err, "inflate");
- }
-
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad inflate\n");
- exit(1);
- } else {
- printf("inflate(): %s\n", (char *)uncompr);
- }
-}
-
-/* ===========================================================================
- * Test deflate() with large buffers and dynamic change of compression level
- */
-void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_BEST_SPEED);
- CHECK_ERR(err, "deflateInit");
-
- c_stream.next_out = compr;
- c_stream.avail_out = (uInt)comprLen;
-
- /* At this point, uncompr is still mostly zeroes, so it should compress
- * very well:
- */
- c_stream.next_in = uncompr;
- c_stream.avail_in = (uInt)uncomprLen;
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
- if (c_stream.avail_in != 0) {
- fprintf(stderr, "deflate not greedy\n");
- exit(1);
- }
-
- /* Feed in already compressed data and switch to no compression: */
- deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
- c_stream.next_in = compr;
- c_stream.avail_in = (uInt)comprLen/2;
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
-
- /* Switch back to compressing mode: */
- deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
- c_stream.next_in = uncompr;
- c_stream.avail_in = (uInt)uncomprLen;
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
-
- err = deflate(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- fprintf(stderr, "deflate should report Z_STREAM_END\n");
- exit(1);
- }
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-}
-
-/* ===========================================================================
- * Test inflate() with large buffers
- */
-void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = (uInt)comprLen;
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- for (;;) {
- d_stream.next_out = uncompr; /* discard the output */
- d_stream.avail_out = (uInt)uncomprLen;
- err = inflate(&d_stream, Z_NO_FLUSH);
- if (err == Z_STREAM_END) break;
- CHECK_ERR(err, "large inflate");
- }
-
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
- fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
- exit(1);
- } else {
- printf("large_inflate(): OK\n");
- }
-}
-
-/* ===========================================================================
- * Test deflate() with full flush
- */
-void test_flush(compr, comprLen)
- Byte *compr;
- uLong *comprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
- uInt len = (uInt)strlen(hello)+1;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
- CHECK_ERR(err, "deflateInit");
-
- c_stream.next_in = (Bytef*)hello;
- c_stream.next_out = compr;
- c_stream.avail_in = 3;
- c_stream.avail_out = (uInt)*comprLen;
- err = deflate(&c_stream, Z_FULL_FLUSH);
- CHECK_ERR(err, "deflate");
-
- compr[3]++; /* force an error in first compressed block */
- c_stream.avail_in = len - 3;
-
- err = deflate(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- CHECK_ERR(err, "deflate");
- }
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-
- *comprLen = c_stream.total_out;
-}
-
-/* ===========================================================================
- * Test inflateSync()
- */
-void test_sync(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = 2; /* just read the zlib header */
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- d_stream.next_out = uncompr;
- d_stream.avail_out = (uInt)uncomprLen;
-
- inflate(&d_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "inflate");
-
- d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
- err = inflateSync(&d_stream); /* but skip the damaged part */
- CHECK_ERR(err, "inflateSync");
-
- err = inflate(&d_stream, Z_FINISH);
- if (err != Z_DATA_ERROR) {
- fprintf(stderr, "inflate should report DATA_ERROR\n");
- /* Because of incorrect adler32 */
- exit(1);
- }
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- printf("after inflateSync(): hel%s\n", (char *)uncompr);
-}
-
-/* ===========================================================================
- * Test deflate() with preset dictionary
- */
-void test_dict_deflate(compr, comprLen)
- Byte *compr;
- uLong comprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
- CHECK_ERR(err, "deflateInit");
-
- err = deflateSetDictionary(&c_stream,
- (const Bytef*)dictionary, sizeof(dictionary));
- CHECK_ERR(err, "deflateSetDictionary");
-
- dictId = c_stream.adler;
- c_stream.next_out = compr;
- c_stream.avail_out = (uInt)comprLen;
-
- c_stream.next_in = (Bytef*)hello;
- c_stream.avail_in = (uInt)strlen(hello)+1;
-
- err = deflate(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- fprintf(stderr, "deflate should report Z_STREAM_END\n");
- exit(1);
- }
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-}
-
-/* ===========================================================================
- * Test inflate() with a preset dictionary
- */
-void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = (uInt)comprLen;
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- d_stream.next_out = uncompr;
- d_stream.avail_out = (uInt)uncomprLen;
-
- for (;;) {
- err = inflate(&d_stream, Z_NO_FLUSH);
- if (err == Z_STREAM_END) break;
- if (err == Z_NEED_DICT) {
- if (d_stream.adler != dictId) {
- fprintf(stderr, "unexpected dictionary");
- exit(1);
- }
- err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
- sizeof(dictionary));
- }
- CHECK_ERR(err, "inflate with dict");
- }
-
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad inflate with dict\n");
- exit(1);
- } else {
- printf("inflate with dictionary: %s\n", (char *)uncompr);
- }
-}
-
-/* ===========================================================================
- * Usage: example [output.gz [input.gz]]
- */
-
-int main(argc, argv)
- int argc;
- char *argv[];
-{
- Byte *compr, *uncompr;
- uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
- uLong uncomprLen = comprLen;
- static const char* myVersion = ZLIB_VERSION;
-
- if (zlibVersion()[0] != myVersion[0]) {
- fprintf(stderr, "incompatible zlib version\n");
- exit(1);
-
- } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
- fprintf(stderr, "warning: different zlib version\n");
- }
-
- printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
- ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
-
- compr = (Byte*)calloc((uInt)comprLen, 1);
- uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
- /* compr and uncompr are cleared to avoid reading uninitialized
- * data and to ensure that uncompr compresses well.
- */
- if (compr == Z_NULL || uncompr == Z_NULL) {
- printf("out of memory\n");
- exit(1);
- }
- test_compress(compr, comprLen, uncompr, uncomprLen);
-
- test_gzio((argc > 1 ? argv[1] : TESTFILE),
- uncompr, uncomprLen);
-
- test_deflate(compr, comprLen);
- test_inflate(compr, comprLen, uncompr, uncomprLen);
-
- test_large_deflate(compr, comprLen, uncompr, uncomprLen);
- test_large_inflate(compr, comprLen, uncompr, uncomprLen);
-
- test_flush(compr, &comprLen);
- test_sync(compr, comprLen, uncompr, uncomprLen);
- comprLen = uncomprLen;
-
- test_dict_deflate(compr, comprLen);
- test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
-
- free(compr);
- free(uncompr);
-
- return 0;
-}
diff --git a/cpukit/zlib/examples/README.examples b/cpukit/zlib/examples/README.examples
deleted file mode 100644
index 1084525204..0000000000
--- a/cpukit/zlib/examples/README.examples
+++ /dev/null
@@ -1,29 +0,0 @@
-This directory contains examples of the use of zlib.
-
-fitblk.c
- compress just enough input to nearly fill a requested output size
- - zlib isn't designed to do this, but fitblk does it anyway
-
-gzappend.c
- append to a gzip file
- - illustrates the use of the Z_BLOCK flush parameter for inflate()
- - illustrates the use of deflatePrime() to start at any bit
-
-gzjoin.c
- join gzip files without recalculating the crc or recompressing
- - illustrates the use of the Z_BLOCK flush parameter for inflate()
- - illustrates the use of crc32_combine()
-
-gzlog.c
-gzlog.h
- efficiently maintain a message log file in gzip format
- - illustrates use of raw deflate and Z_SYNC_FLUSH
- - illustrates use of gzip header extra field
-
-zlib_how.html
- painfully comprehensive description of zpipe.c (see below)
- - describes in excruciating detail the use of deflate() and inflate()
-
-zpipe.c
- reads and writes zlib streams from stdin to stdout
- - illustrates the proper use of deflate() and inflate()
diff --git a/cpukit/zlib/examples/fitblk.c b/cpukit/zlib/examples/fitblk.c
deleted file mode 100644
index 5f8311489d..0000000000
--- a/cpukit/zlib/examples/fitblk.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/* fitblk.c: example of fitting compressed output to a specified size
- Not copyrighted -- provided to the public domain
- Version 1.1 25 November 2004 Mark Adler */
-
-/* Version history:
- 1.0 24 Nov 2004 First version
- 1.1 25 Nov 2004 Change deflateInit2() to deflateInit()
- Use fixed-size, stack-allocated raw buffers
- Simplify code moving compression to subroutines
- Use assert() for internal errors
- Add detailed description of approach
- */
-
-/* Approach to just fitting a requested compressed size:
-
- fitblk performs three compression passes on a portion of the input
- data in order to determine how much of that input will compress to
- nearly the requested output block size. The first pass generates
- enough deflate blocks to produce output to fill the requested
- output size plus a specfied excess amount (see the EXCESS define
- below). The last deflate block may go quite a bit past that, but
- is discarded. The second pass decompresses and recompresses just
- the compressed data that fit in the requested plus excess sized
- buffer. The deflate process is terminated after that amount of
- input, which is less than the amount consumed on the first pass.
- The last deflate block of the result will be of a comparable size
- to the final product, so that the header for that deflate block and
- the compression ratio for that block will be about the same as in
- the final product. The third compression pass decompresses the
- result of the second step, but only the compressed data up to the
- requested size minus an amount to allow the compressed stream to
- complete (see the MARGIN define below). That will result in a
- final compressed stream whose length is less than or equal to the
- requested size. Assuming sufficient input and a requested size
- greater than a few hundred bytes, the shortfall will typically be
- less than ten bytes.
-
- If the input is short enough that the first compression completes
- before filling the requested output size, then that compressed
- stream is return with no recompression.
-
- EXCESS is chosen to be just greater than the shortfall seen in a
- two pass approach similar to the above. That shortfall is due to
- the last deflate block compressing more efficiently with a smaller
- header on the second pass. EXCESS is set to be large enough so
- that there is enough uncompressed data for the second pass to fill
- out the requested size, and small enough so that the final deflate
- block of the second pass will be close in size to the final deflate
- block of the third and final pass. MARGIN is chosen to be just
- large enough to assure that the final compression has enough room
- to complete in all cases.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include "zlib.h"
-
-#define local static
-
-/* print nastygram and leave */
-local void quit(char *why)
-{
- fprintf(stderr, "fitblk abort: %s\n", why);
- exit(1);
-}
-
-#define RAWLEN 4096 /* intermediate uncompressed buffer size */
-
-/* compress from file to def until provided buffer is full or end of
- input reached; return last deflate() return value, or Z_ERRNO if
- there was read error on the file */
-local int partcompress(FILE *in, z_streamp def)
-{
- int ret, flush;
- char raw[RAWLEN];
-
- flush = Z_NO_FLUSH;
- do {
- def->avail_in = fread(raw, 1, RAWLEN, in);
- if (ferror(in))
- return Z_ERRNO;
- def->next_in = raw;
- if (feof(in))
- flush = Z_FINISH;
- ret = deflate(def, flush);
- assert(ret != Z_STREAM_ERROR);
- } while (def->avail_out != 0 && flush == Z_NO_FLUSH);
- return ret;
-}
-
-/* recompress from inf's input to def's output; the input for inf and
- the output for def are set in those structures before calling;
- return last deflate() return value, or Z_MEM_ERROR if inflate()
- was not able to allocate enough memory when it needed to */
-local int recompress(z_streamp inf, z_streamp def)
-{
- int ret, flush;
- char raw[RAWLEN];
-
- flush = Z_NO_FLUSH;
- do {
- /* decompress */
- inf->avail_out = RAWLEN;
- inf->next_out = raw;
- ret = inflate(inf, Z_NO_FLUSH);
- assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&
- ret != Z_NEED_DICT);
- if (ret == Z_MEM_ERROR)
- return ret;
-
- /* compress what was decompresed until done or no room */
- def->avail_in = RAWLEN - inf->avail_out;
- def->next_in = raw;
- if (inf->avail_out != 0)
- flush = Z_FINISH;
- ret = deflate(def, flush);
- assert(ret != Z_STREAM_ERROR);
- } while (ret != Z_STREAM_END && def->avail_out != 0);
- return ret;
-}
-
-#define EXCESS 256 /* empirically determined stream overage */
-#define MARGIN 8 /* amount to back off for completion */
-
-/* compress from stdin to fixed-size block on stdout */
-int main(int argc, char **argv)
-{
- int ret; /* return code */
- unsigned size; /* requested fixed output block size */
- unsigned have; /* bytes written by deflate() call */
- char *blk; /* intermediate and final stream */
- char *tmp; /* close to desired size stream */
- z_stream def, inf; /* zlib deflate and inflate states */
-
- /* get requested output size */
- if (argc != 2)
- quit("need one argument: size of output block");
- ret = strtol(argv[1], argv + 1, 10);
- if (argv[1][0] != 0)
- quit("argument must be a number");
- if (ret < 8) /* 8 is minimum zlib stream size */
- quit("need positive size of 8 or greater");
- size = (unsigned)ret;
-
- /* allocate memory for buffers and compression engine */
- blk = malloc(size + EXCESS);
- def.zalloc = Z_NULL;
- def.zfree = Z_NULL;
- def.opaque = Z_NULL;
- ret = deflateInit(&def, Z_DEFAULT_COMPRESSION);
- if (ret != Z_OK || blk == NULL)
- quit("out of memory");
-
- /* compress from stdin until output full, or no more input */
- def.avail_out = size + EXCESS;
- def.next_out = blk;
- ret = partcompress(stdin, &def);
- if (ret == Z_ERRNO)
- quit("error reading input");
-
- /* if it all fit, then size was undersubscribed -- done! */
- if (ret == Z_STREAM_END && def.avail_out >= EXCESS) {
- /* write block to stdout */
- have = size + EXCESS - def.avail_out;
- ret = fwrite(blk, 1, have, stdout);
- if (ret != have || ferror(stdout))
- quit("error writing output");
-
- /* clean up and print results to stderr */
- ret = deflateEnd(&def);
- assert(ret != Z_STREAM_ERROR);
- free(blk);
- fprintf(stderr,
- "%u bytes unused out of %u requested (all input)\n",
- size - have, size);
- return 0;
- }
-
- /* it didn't all fit -- set up for recompression */
- inf.zalloc = Z_NULL;
- inf.zfree = Z_NULL;
- inf.opaque = Z_NULL;
- inf.avail_in = 0;
- inf.next_in = Z_NULL;
- ret = inflateInit(&inf);
- tmp = malloc(size + EXCESS);
- if (ret != Z_OK || tmp == NULL)
- quit("out of memory");
- ret = deflateReset(&def);
- assert(ret != Z_STREAM_ERROR);
-
- /* do first recompression close to the right amount */
- inf.avail_in = size + EXCESS;
- inf.next_in = blk;
- def.avail_out = size + EXCESS;
- def.next_out = tmp;
- ret = recompress(&inf, &def);
- if (ret == Z_MEM_ERROR)
- quit("out of memory");
-
- /* set up for next reocmpression */
- ret = inflateReset(&inf);
- assert(ret != Z_STREAM_ERROR);
- ret = deflateReset(&def);
- assert(ret != Z_STREAM_ERROR);
-
- /* do second and final recompression (third compression) */
- inf.avail_in = size - MARGIN; /* assure stream will complete */
- inf.next_in = tmp;
- def.avail_out = size;
- def.next_out = blk;
- ret = recompress(&inf, &def);
- if (ret == Z_MEM_ERROR)
- quit("out of memory");
- assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */
-
- /* done -- write block to stdout */
- have = size - def.avail_out;
- ret = fwrite(blk, 1, have, stdout);
- if (ret != have || ferror(stdout))
- quit("error writing output");
-
- /* clean up and print results to stderr */
- free(tmp);
- ret = inflateEnd(&inf);
- assert(ret != Z_STREAM_ERROR);
- ret = deflateEnd(&def);
- assert(ret != Z_STREAM_ERROR);
- free(blk);
- fprintf(stderr,
- "%u bytes unused out of %u requested (%lu input)\n",
- size - have, size, def.total_in);
- return 0;
-}
diff --git a/cpukit/zlib/examples/gzappend.c b/cpukit/zlib/examples/gzappend.c
deleted file mode 100644
index e9e878e116..0000000000
--- a/cpukit/zlib/examples/gzappend.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/* gzappend -- command to append to a gzip file
-
- Copyright (C) 2003 Mark Adler, all rights reserved
- version 1.1, 4 Nov 2003
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Mark Adler madler@alumni.caltech.edu
- */
-
-/*
- * Change history:
- *
- * 1.0 19 Oct 2003 - First version
- * 1.1 4 Nov 2003 - Expand and clarify some comments and notes
- * - Add version and copyright to help
- * - Send help to stdout instead of stderr
- * - Add some preemptive typecasts
- * - Add L to constants in lseek() calls
- * - Remove some debugging information in error messages
- * - Use new data_type definition for zlib 1.2.1
- * - Simplfy and unify file operations
- * - Finish off gzip file in gztack()
- * - Use deflatePrime() instead of adding empty blocks
- * - Keep gzip file clean on appended file read errors
- * - Use in-place rotate instead of auxiliary buffer
- * (Why you ask? Because it was fun to write!)
- */
-
-/*
- gzappend takes a gzip file and appends to it, compressing files from the
- command line or data from stdin. The gzip file is written to directly, to
- avoid copying that file, in case it's large. Note that this results in the
- unfriendly behavior that if gzappend fails, the gzip file is corrupted.
-
- This program was written to illustrate the use of the new Z_BLOCK option of
- zlib 1.2.x's inflate() function. This option returns from inflate() at each
- block boundary to facilitate locating and modifying the last block bit at
- the start of the final deflate block. Also whether using Z_BLOCK or not,
- another required feature of zlib 1.2.x is that inflate() now provides the
- number of unusued bits in the last input byte used. gzappend will not work
- with versions of zlib earlier than 1.2.1.
-
- gzappend first decompresses the gzip file internally, discarding all but
- the last 32K of uncompressed data, and noting the location of the last block
- bit and the number of unused bits in the last byte of the compressed data.
- The gzip trailer containing the CRC-32 and length of the uncompressed data
- is verified. This trailer will be later overwritten.
-
- Then the last block bit is cleared by seeking back in the file and rewriting
- the byte that contains it. Seeking forward, the last byte of the compressed
- data is saved along with the number of unused bits to initialize deflate.
-
- A deflate process is initialized, using the last 32K of the uncompressed
- data from the gzip file to initialize the dictionary. If the total
- uncompressed data was less than 32K, then all of it is used to initialize
- the dictionary. The deflate output bit buffer is also initialized with the
- last bits from the original deflate stream. From here on, the data to
- append is simply compressed using deflate, and written to the gzip file.
- When that is complete, the new CRC-32 and uncompressed length are written
- as the trailer of the gzip file.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "zlib.h"
-
-#define local static
-#define LGCHUNK 14
-#define CHUNK (1U << LGCHUNK)
-#define DSIZE 32768U
-
-/* print an error message and terminate with extreme prejudice */
-local void bye(char *msg1, char *msg2)
-{
- fprintf(stderr, "gzappend error: %s%s\n", msg1, msg2);
- exit(1);
-}
-
-/* return the greatest common divisor of a and b using Euclid's algorithm,
- modified to be fast when one argument much greater than the other, and
- coded to avoid unnecessary swapping */
-local unsigned gcd(unsigned a, unsigned b)
-{
- unsigned c;
-
- while (a && b)
- if (a > b) {
- c = b;
- while (a - c >= c)
- c <<= 1;
- a -= c;
- }
- else {
- c = a;
- while (b - c >= c)
- c <<= 1;
- b -= c;
- }
- return a + b;
-}
-
-/* rotate list[0..len-1] left by rot positions, in place */
-local void rotate(unsigned char *list, unsigned len, unsigned rot)
-{
- unsigned char tmp;
- unsigned cycles;
- unsigned char *start, *last, *to, *from;
-
- /* normalize rot and handle degenerate cases */
- if (len < 2) return;
- if (rot >= len) rot %= len;
- if (rot == 0) return;
-
- /* pointer to last entry in list */
- last = list + (len - 1);
-
- /* do simple left shift by one */
- if (rot == 1) {
- tmp = *list;
- memcpy(list, list + 1, len - 1);
- *last = tmp;
- return;
- }
-
- /* do simple right shift by one */
- if (rot == len - 1) {
- tmp = *last;
- memmove(list + 1, list, len - 1);
- *list = tmp;
- return;
- }
-
- /* otherwise do rotate as a set of cycles in place */
- cycles = gcd(len, rot); /* number of cycles */
- do {
- start = from = list + cycles; /* start index is arbitrary */
- tmp = *from; /* save entry to be overwritten */
- for (;;) {
- to = from; /* next step in cycle */
- from += rot; /* go right rot positions */
- if (from > last) from -= len; /* (pointer better not wrap) */
- if (from == start) break; /* all but one shifted */
- *to = *from; /* shift left */
- }
- *to = tmp; /* complete the circle */
- } while (--cycles);
-}
-
-/* structure for gzip file read operations */
-typedef struct {
- int fd; /* file descriptor */
- int size; /* 1 << size is bytes in buf */
- unsigned left; /* bytes available at next */
- unsigned char *buf; /* buffer */
- unsigned char *next; /* next byte in buffer */
- char *name; /* file name for error messages */
-} file;
-
-/* reload buffer */
-local int readin(file *in)
-{
- int len;
-
- len = read(in->fd, in->buf, 1 << in->size);
- if (len == -1) bye("error reading ", in->name);
- in->left = (unsigned)len;
- in->next = in->buf;
- return len;
-}
-
-/* read from file in, exit if end-of-file */
-local int readmore(file *in)
-{
- if (readin(in) == 0) bye("unexpected end of ", in->name);
- return 0;
-}
-
-#define read1(in) (in->left == 0 ? readmore(in) : 0, \
- in->left--, *(in->next)++)
-
-/* skip over n bytes of in */
-local void skip(file *in, unsigned n)
-{
- unsigned bypass;
-
- if (n > in->left) {
- n -= in->left;
- bypass = n & ~((1U << in->size) - 1);
- if (bypass) {
- if (lseek(in->fd, (off_t)bypass, SEEK_CUR) == -1)
- bye("seeking ", in->name);
- n -= bypass;
- }
- readmore(in);
- if (n > in->left)
- bye("unexpected end of ", in->name);
- }
- in->left -= n;
- in->next += n;
-}
-
-/* read a four-byte unsigned integer, little-endian, from in */
-unsigned long read4(file *in)
-{
- unsigned long val;
-
- val = read1(in);
- val += (unsigned)read1(in) << 8;
- val += (unsigned long)read1(in) << 16;
- val += (unsigned long)read1(in) << 24;
- return val;
-}
-
-/* skip over gzip header */
-local void gzheader(file *in)
-{
- int flags;
- unsigned n;
-
- if (read1(in) != 31 || read1(in) != 139) bye(in->name, " not a gzip file");
- if (read1(in) != 8) bye("unknown compression method in", in->name);
- flags = read1(in);
- if (flags & 0xe0) bye("unknown header flags set in", in->name);
- skip(in, 6);
- if (flags & 4) {
- n = read1(in);
- n += (unsigned)(read1(in)) << 8;
- skip(in, n);
- }
- if (flags & 8) while (read1(in) != 0) ;
- if (flags & 16) while (read1(in) != 0) ;
- if (flags & 2) skip(in, 2);
-}
-
-/* decompress gzip file "name", return strm with a deflate stream ready to
- continue compression of the data in the gzip file, and return a file
- descriptor pointing to where to write the compressed data -- the deflate
- stream is initialized to compress using level "level" */
-local int gzscan(char *name, z_stream *strm, int level)
-{
- int ret, lastbit, left, full;
- unsigned have;
- unsigned long crc, tot;
- unsigned char *window;
- off_t lastoff, end;
- file gz;
-
- /* open gzip file */
- gz.name = name;
- gz.fd = open(name, O_RDWR, 0);
- if (gz.fd == -1) bye("cannot open ", name);
- gz.buf = malloc(CHUNK);
- if (gz.buf == NULL) bye("out of memory", "");
- gz.size = LGCHUNK;
- gz.left = 0;
-
- /* skip gzip header */
- gzheader(&gz);
-
- /* prepare to decompress */
- window = malloc(DSIZE);
- if (window == NULL) bye("out of memory", "");
- strm->zalloc = Z_NULL;
- strm->zfree = Z_NULL;
- strm->opaque = Z_NULL;
- ret = inflateInit2(strm, -15);
- if (ret != Z_OK) bye("out of memory", " or library mismatch");
-
- /* decompress the deflate stream, saving append information */
- lastbit = 0;
- lastoff = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
- left = 0;
- strm->avail_in = gz.left;
- strm->next_in = gz.next;
- crc = crc32(0L, Z_NULL, 0);
- have = full = 0;
- do {
- /* if needed, get more input */
- if (strm->avail_in == 0) {
- readmore(&gz);
- strm->avail_in = gz.left;
- strm->next_in = gz.next;
- }
-
- /* set up output to next available section of sliding window */
- strm->avail_out = DSIZE - have;
- strm->next_out = window + have;
-
- /* inflate and check for errors */
- ret = inflate(strm, Z_BLOCK);
- if (ret == Z_STREAM_ERROR) bye("internal stream error!", "");
- if (ret == Z_MEM_ERROR) bye("out of memory", "");
- if (ret == Z_DATA_ERROR)
- bye("invalid compressed data--format violated in", name);
-
- /* update crc and sliding window pointer */
- crc = crc32(crc, window + have, DSIZE - have - strm->avail_out);
- if (strm->avail_out)
- have = DSIZE - strm->avail_out;
- else {
- have = 0;
- full = 1;
- }
-
- /* process end of block */
- if (strm->data_type & 128) {
- if (strm->data_type & 64)
- left = strm->data_type & 0x1f;
- else {
- lastbit = strm->data_type & 0x1f;
- lastoff = lseek(gz.fd, 0L, SEEK_CUR) - strm->avail_in;
- }
- }
- } while (ret != Z_STREAM_END);
- inflateEnd(strm);
- gz.left = strm->avail_in;
- gz.next = strm->next_in;
-
- /* save the location of the end of the compressed data */
- end = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
-
- /* check gzip trailer and save total for deflate */
- if (crc != read4(&gz))
- bye("invalid compressed data--crc mismatch in ", name);
- tot = strm->total_out;
- if ((tot & 0xffffffffUL) != read4(&gz))
- bye("invalid compressed data--length mismatch in", name);
-
- /* if not at end of file, warn */
- if (gz.left || readin(&gz))
- fprintf(stderr,
- "gzappend warning: junk at end of gzip file overwritten\n");
-
- /* clear last block bit */
- lseek(gz.fd, lastoff - (lastbit != 0), SEEK_SET);
- if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
- *gz.buf = (unsigned char)(*gz.buf ^ (1 << ((8 - lastbit) & 7)));
- lseek(gz.fd, -1L, SEEK_CUR);
- if (write(gz.fd, gz.buf, 1) != 1) bye("writing after seek to ", name);
-
- /* if window wrapped, build dictionary from window by rotating */
- if (full) {
- rotate(window, DSIZE, have);
- have = DSIZE;
- }
-
- /* set up deflate stream with window, crc, total_in, and leftover bits */
- ret = deflateInit2(strm, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
- if (ret != Z_OK) bye("out of memory", "");
- deflateSetDictionary(strm, window, have);
- strm->adler = crc;
- strm->total_in = tot;
- if (left) {
- lseek(gz.fd, --end, SEEK_SET);
- if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
- deflatePrime(strm, 8 - left, *gz.buf);
- }
- lseek(gz.fd, end, SEEK_SET);
-
- /* clean up and return */
- free(window);
- free(gz.buf);
- return gz.fd;
-}
-
-/* append file "name" to gzip file gd using deflate stream strm -- if last
- is true, then finish off the deflate stream at the end */
-local void gztack(char *name, int gd, z_stream *strm, int last)
-{
- int fd, len, ret;
- unsigned left;
- unsigned char *in, *out;
-
- /* open file to compress and append */
- fd = 0;
- if (name != NULL) {
- fd = open(name, O_RDONLY, 0);
- if (fd == -1)
- fprintf(stderr, "gzappend warning: %s not found, skipping ...\n",
- name);
- }
-
- /* allocate buffers */
- in = fd == -1 ? NULL : malloc(CHUNK);
- out = malloc(CHUNK);
- if (out == NULL) bye("out of memory", "");
-
- /* compress input file and append to gzip file */
- do {
- /* get more input */
- len = fd == -1 ? 0 : read(fd, in, CHUNK);
- if (len == -1) {
- fprintf(stderr,
- "gzappend warning: error reading %s, skipping rest ...\n",
- name);
- len = 0;
- }
- strm->avail_in = (unsigned)len;
- strm->next_in = in;
- if (len) strm->adler = crc32(strm->adler, in, (unsigned)len);
-
- /* compress and write all available output */
- do {
- strm->avail_out = CHUNK;
- strm->next_out = out;
- ret = deflate(strm, last && len == 0 ? Z_FINISH : Z_NO_FLUSH);
- left = CHUNK - strm->avail_out;
- while (left) {
- len = write(gd, out + CHUNK - strm->avail_out - left, left);
- if (len == -1) bye("writing gzip file", "");
- left -= (unsigned)len;
- }
- } while (strm->avail_out == 0 && ret != Z_STREAM_END);
- } while (len != 0);
-
- /* write trailer after last entry */
- if (last) {
- deflateEnd(strm);
- out[0] = (unsigned char)(strm->adler);
- out[1] = (unsigned char)(strm->adler >> 8);
- out[2] = (unsigned char)(strm->adler >> 16);
- out[3] = (unsigned char)(strm->adler >> 24);
- out[4] = (unsigned char)(strm->total_in);
- out[5] = (unsigned char)(strm->total_in >> 8);
- out[6] = (unsigned char)(strm->total_in >> 16);
- out[7] = (unsigned char)(strm->total_in >> 24);
- len = 8;
- do {
- ret = write(gd, out + 8 - len, len);
- if (ret == -1) bye("writing gzip file", "");
- len -= ret;
- } while (len);
- close(gd);
- }
-
- /* clean up and return */
- free(out);
- if (in != NULL) free(in);
- if (fd > 0) close(fd);
-}
-
-/* process the compression level option if present, scan the gzip file, and
- append the specified files, or append the data from stdin if no other file
- names are provided on the command line -- the gzip file must be writable
- and seekable */
-int main(int argc, char **argv)
-{
- int gd, level;
- z_stream strm;
-
- /* ignore command name */
- argv++;
-
- /* provide usage if no arguments */
- if (*argv == NULL) {
- printf("gzappend 1.1 (4 Nov 2003) Copyright (C) 2003 Mark Adler\n");
- printf(
- "usage: gzappend [-level] file.gz [ addthis [ andthis ... ]]\n");
- return 0;
- }
-
- /* set compression level */
- level = Z_DEFAULT_COMPRESSION;
- if (argv[0][0] == '-') {
- if (argv[0][1] < '0' || argv[0][1] > '9' || argv[0][2] != 0)
- bye("invalid compression level", "");
- level = argv[0][1] - '0';
- if (*++argv == NULL) bye("no gzip file name after options", "");
- }
-
- /* prepare to append to gzip file */
- gd = gzscan(*argv++, &strm, level);
-
- /* append files on command line, or from stdin if none */
- if (*argv == NULL)
- gztack(NULL, gd, &strm, 1);
- else
- do {
- gztack(*argv, gd, &strm, argv[1] == NULL);
- } while (*++argv != NULL);
- return 0;
-}
diff --git a/cpukit/zlib/examples/gzjoin.c b/cpukit/zlib/examples/gzjoin.c
deleted file mode 100644
index 7434c5b83f..0000000000
--- a/cpukit/zlib/examples/gzjoin.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/* gzjoin -- command to join gzip files into one gzip file
-
- Copyright (C) 2004 Mark Adler, all rights reserved
- version 1.0, 11 Dec 2004
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Mark Adler madler@alumni.caltech.edu
- */
-
-/*
- * Change history:
- *
- * 1.0 11 Dec 2004 - First version
- */
-
-/*
- gzjoin takes one or more gzip files on the command line and writes out a
- single gzip file that will uncompress to the concatenation of the
- uncompressed data from the individual gzip files. gzjoin does this without
- having to recompress any of the data and without having to calculate a new
- crc32 for the concatenated uncompressed data. gzjoin does however have to
- decompress all of the input data in order to find the bits in the compressed
- data that need to be modified to concatenate the streams.
-
- gzjoin does not do an integrity check on the input gzip files other than
- checking the gzip header and decompressing the compressed data. They are
- otherwise assumed to be complete and correct.
-
- Each joint between gzip files removes at least 18 bytes of previous trailer
- and subsequent header, and inserts an average of about three bytes to the
- compressed data in order to connect the streams. The output gzip file
- has a minimal ten-byte gzip header with no file name or modification time.
-
- This program was written to illustrate the use of the Z_BLOCK option of
- inflate() and the crc32_combine() function. gzjoin will not compile with
- versions of zlib earlier than 1.2.3.
- */
-
-#include <stdio.h> /* fputs(), fprintf(), fwrite(), putc() */
-#include <stdlib.h> /* exit(), malloc(), free() */
-#include <fcntl.h> /* open() */
-#include <unistd.h> /* close(), read(), lseek() */
-#include "zlib.h"
- /* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */
-
-#define local static
-
-/* exit with an error (return a value to allow use in an expression) */
-local int bail(char *why1, char *why2)
-{
- fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2);
- exit(1);
- return 0;
-}
-
-/* -- simple buffered file input with access to the buffer -- */
-
-#define CHUNK 32768 /* must be a power of two and fit in unsigned */
-
-/* bin buffered input file type */
-typedef struct {
- char *name; /* name of file for error messages */
- int fd; /* file descriptor */
- unsigned left; /* bytes remaining at next */
- unsigned char *next; /* next byte to read */
- unsigned char *buf; /* allocated buffer of length CHUNK */
-} bin;
-
-/* close a buffered file and free allocated memory */
-local void bclose(bin *in)
-{
- if (in != NULL) {
- if (in->fd != -1)
- close(in->fd);
- if (in->buf != NULL)
- free(in->buf);
- free(in);
- }
-}
-
-/* open a buffered file for input, return a pointer to type bin, or NULL on
- failure */
-local bin *bopen(char *name)
-{
- bin *in;
-
- in = malloc(sizeof(bin));
- if (in == NULL)
- return NULL;
- in->buf = malloc(CHUNK);
- in->fd = open(name, O_RDONLY, 0);
- if (in->buf == NULL || in->fd == -1) {
- bclose(in);
- return NULL;
- }
- in->left = 0;
- in->next = in->buf;
- in->name = name;
- return in;
-}
-
-/* load buffer from file, return -1 on read error, 0 or 1 on success, with
- 1 indicating that end-of-file was reached */
-local int bload(bin *in)
-{
- ssize_t len;
-
- if (in == NULL)
- return -1;
- if (in->left != 0)
- return 0;
- in->next = in->buf;
- do {
- len = read(in->fd, in->buf + in->left, CHUNK - in->left);
- if (len < 0)
- return -1;
- in->left += (unsigned)len;
- } while (len != 0 && in->left < CHUNK);
- return len == 0 ? 1 : 0;
-}
-
-/* get a byte from the file, bail if end of file */
-#define bget(in) (in->left ? 0 : bload(in), \
- in->left ? (in->left--, *(in->next)++) : \
- bail("unexpected end of file on ", in->name))
-
-/* get a four-byte little-endian unsigned integer from file */
-local unsigned long bget4(bin *in)
-{
- unsigned long val;
-
- val = bget(in);
- val += (unsigned long)(bget(in)) << 8;
- val += (unsigned long)(bget(in)) << 16;
- val += (unsigned long)(bget(in)) << 24;
- return val;
-}
-
-/* skip bytes in file */
-local void bskip(bin *in, unsigned skip)
-{
- /* check pointer */
- if (in == NULL)
- return;
-
- /* easy case -- skip bytes in buffer */
- if (skip <= in->left) {
- in->left -= skip;
- in->next += skip;
- return;
- }
-
- /* skip what's in buffer, discard buffer contents */
- skip -= in->left;
- in->left = 0;
-
- /* seek past multiples of CHUNK bytes */
- if (skip > CHUNK) {
- unsigned left;
-
- left = skip & (CHUNK - 1);
- if (left == 0) {
- /* exact number of chunks: seek all the way minus one byte to check
- for end-of-file with a read */
- lseek(in->fd, skip - 1, SEEK_CUR);
- if (read(in->fd, in->buf, 1) != 1)
- bail("unexpected end of file on ", in->name);
- return;
- }
-
- /* skip the integral chunks, update skip with remainder */
- lseek(in->fd, skip - left, SEEK_CUR);
- skip = left;
- }
-
- /* read more input and skip remainder */
- bload(in);
- if (skip > in->left)
- bail("unexpected end of file on ", in->name);
- in->left -= skip;
- in->next += skip;
-}
-
-/* -- end of buffered input functions -- */
-
-/* skip the gzip header from file in */
-local void gzhead(bin *in)
-{
- int flags;
-
- /* verify gzip magic header and compression method */
- if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8)
- bail(in->name, " is not a valid gzip file");
-
- /* get and verify flags */
- flags = bget(in);
- if ((flags & 0xe0) != 0)
- bail("unknown reserved bits set in ", in->name);
-
- /* skip modification time, extra flags, and os */
- bskip(in, 6);
-
- /* skip extra field if present */
- if (flags & 4) {
- unsigned len;
-
- len = bget(in);
- len += (unsigned)(bget(in)) << 8;
- bskip(in, len);
- }
-
- /* skip file name if present */
- if (flags & 8)
- while (bget(in) != 0)
- ;
-
- /* skip comment if present */
- if (flags & 16)
- while (bget(in) != 0)
- ;
-
- /* skip header crc if present */
- if (flags & 2)
- bskip(in, 2);
-}
-
-/* write a four-byte little-endian unsigned integer to out */
-local void put4(unsigned long val, FILE *out)
-{
- putc(val & 0xff, out);
- putc((val >> 8) & 0xff, out);
- putc((val >> 16) & 0xff, out);
- putc((val >> 24) & 0xff, out);
-}
-
-/* Load up zlib stream from buffered input, bail if end of file */
-local void zpull(z_streamp strm, bin *in)
-{
- if (in->left == 0)
- bload(in);
- if (in->left == 0)
- bail("unexpected end of file on ", in->name);
- strm->avail_in = in->left;
- strm->next_in = in->next;
-}
-
-/* Write header for gzip file to out and initialize trailer. */
-local void gzinit(unsigned long *crc, unsigned long *tot, FILE *out)
-{
- fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out);
- *crc = crc32(0L, Z_NULL, 0);
- *tot = 0;
-}
-
-/* Copy the compressed data from name, zeroing the last block bit of the last
- block if clr is true, and adding empty blocks as needed to get to a byte
- boundary. If clr is false, then the last block becomes the last block of
- the output, and the gzip trailer is written. crc and tot maintains the
- crc and length (modulo 2^32) of the output for the trailer. The resulting
- gzip file is written to out. gzinit() must be called before the first call
- of gzcopy() to write the gzip header and to initialize crc and tot. */
-local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,
- FILE *out)
-{
- int ret; /* return value from zlib functions */
- int pos; /* where the "last block" bit is in byte */
- int last; /* true if processing the last block */
- bin *in; /* buffered input file */
- unsigned char *start; /* start of compressed data in buffer */
- unsigned char *junk; /* buffer for uncompressed data -- discarded */
- z_off_t len; /* length of uncompressed data (support > 4 GB) */
- z_stream strm; /* zlib inflate stream */
-
- /* open gzip file and skip header */
- in = bopen(name);
- if (in == NULL)
- bail("could not open ", name);
- gzhead(in);
-
- /* allocate buffer for uncompressed data and initialize raw inflate
- stream */
- junk = malloc(CHUNK);
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
- ret = inflateInit2(&strm, -15);
- if (junk == NULL || ret != Z_OK)
- bail("out of memory", "");
-
- /* inflate and copy compressed data, clear last-block bit if requested */
- len = 0;
- zpull(&strm, in);
- start = strm.next_in;
- last = start[0] & 1;
- if (last && clr)
- start[0] &= ~1;
- strm.avail_out = 0;
- for (;;) {
- /* if input used and output done, write used input and get more */
- if (strm.avail_in == 0 && strm.avail_out != 0) {
- fwrite(start, 1, strm.next_in - start, out);
- start = in->buf;
- in->left = 0;
- zpull(&strm, in);
- }
-
- /* decompress -- return early when end-of-block reached */
- strm.avail_out = CHUNK;
- strm.next_out = junk;
- ret = inflate(&strm, Z_BLOCK);
- switch (ret) {
- case Z_MEM_ERROR:
- bail("out of memory", "");
- case Z_DATA_ERROR:
- bail("invalid compressed data in ", in->name);
- }
-
- /* update length of uncompressed data */
- len += CHUNK - strm.avail_out;
-
- /* check for block boundary (only get this when block copied out) */
- if (strm.data_type & 128) {
- /* if that was the last block, then done */
- if (last)
- break;
-
- /* number of unused bits in last byte */
- pos = strm.data_type & 7;
-
- /* find the next last-block bit */
- if (pos != 0) {
- /* next last-block bit is in last used byte */
- pos = 0x100 >> pos;
- last = strm.next_in[-1] & pos;
- if (last && clr)
- strm.next_in[-1] &= ~pos;
- }
- else {
- /* next last-block bit is in next unused byte */
- if (strm.avail_in == 0) {
- /* don't have that byte yet -- get it */
- fwrite(start, 1, strm.next_in - start, out);
- start = in->buf;
- in->left = 0;
- zpull(&strm, in);
- }
- last = strm.next_in[0] & 1;
- if (last && clr)
- strm.next_in[0] &= ~1;
- }
- }
- }
-
- /* update buffer with unused input */
- in->left = strm.avail_in;
- in->next = strm.next_in;
-
- /* copy used input, write empty blocks to get to byte boundary */
- pos = strm.data_type & 7;
- fwrite(start, 1, in->next - start - 1, out);
- last = in->next[-1];
- if (pos == 0 || !clr)
- /* already at byte boundary, or last file: write last byte */
- putc(last, out);
- else {
- /* append empty blocks to last byte */
- last &= ((0x100 >> pos) - 1); /* assure unused bits are zero */
- if (pos & 1) {
- /* odd -- append an empty stored block */
- putc(last, out);
- if (pos == 1)
- putc(0, out); /* two more bits in block header */
- fwrite("\0\0\xff\xff", 1, 4, out);
- }
- else {
- /* even -- append 1, 2, or 3 empty fixed blocks */
- switch (pos) {
- case 6:
- putc(last | 8, out);
- last = 0;
- case 4:
- putc(last | 0x20, out);
- last = 0;
- case 2:
- putc(last | 0x80, out);
- putc(0, out);
- }
- }
- }
-
- /* update crc and tot */
- *crc = crc32_combine(*crc, bget4(in), len);
- *tot += (unsigned long)len;
-
- /* clean up */
- inflateEnd(&strm);
- free(junk);
- bclose(in);
-
- /* write trailer if this is the last gzip file */
- if (!clr) {
- put4(*crc, out);
- put4(*tot, out);
- }
-}
-
-/* join the gzip files on the command line, write result to stdout */
-int main(int argc, char **argv)
-{
- unsigned long crc, tot; /* running crc and total uncompressed length */
-
- /* skip command name */
- argc--;
- argv++;
-
- /* show usage if no arguments */
- if (argc == 0) {
- fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n",
- stderr);
- return 0;
- }
-
- /* join gzip files on command line and write to stdout */
- gzinit(&crc, &tot, stdout);
- while (argc--)
- gzcopy(*argv++, argc, &crc, &tot, stdout);
-
- /* done */
- return 0;
-}
diff --git a/cpukit/zlib/examples/gzlog.c b/cpukit/zlib/examples/gzlog.c
deleted file mode 100644
index f71f817c8b..0000000000
--- a/cpukit/zlib/examples/gzlog.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * gzlog.c
- * Copyright (C) 2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in gzlog.h
- * version 1.0, 26 Nov 2004
- *
- */
-
-#include <string.h> /* memcmp() */
-#include <stdlib.h> /* malloc(), free(), NULL */
-#include <sys/types.h> /* size_t, off_t */
-#include <unistd.h> /* read(), close(), sleep(), ftruncate(), */
- /* lseek() */
-#include <fcntl.h> /* open() */
-#include <sys/file.h> /* flock() */
-#include "zlib.h" /* deflateInit2(), deflate(), deflateEnd() */
-
-#include "gzlog.h" /* interface */
-#define local static
-
-/* log object structure */
-typedef struct {
- int id; /* object identifier */
- int fd; /* log file descriptor */
- off_t extra; /* offset of extra "ap" subfield */
- off_t mark_off; /* offset of marked data */
- off_t last_off; /* offset of last block */
- unsigned long crc; /* uncompressed crc */
- unsigned long len; /* uncompressed length (modulo 2^32) */
- unsigned stored; /* length of current stored block */
-} gz_log;
-
-#define GZLOGID 19334 /* gz_log object identifier */
-
-#define LOCK_RETRY 1 /* retry lock once a second */
-#define LOCK_PATIENCE 1200 /* try about twenty minutes before forcing */
-
-/* acquire a lock on a file */
-local int lock(int fd)
-{
- int patience;
-
- /* try to lock every LOCK_RETRY seconds for LOCK_PATIENCE seconds */
- patience = LOCK_PATIENCE;
- do {
- if (flock(fd, LOCK_EX + LOCK_NB) == 0)
- return 0;
- (void)sleep(LOCK_RETRY);
- patience -= LOCK_RETRY;
- } while (patience > 0);
-
- /* we've run out of patience -- give up */
- return -1;
-}
-
-/* release lock */
-local void unlock(int fd)
-{
- (void)flock(fd, LOCK_UN);
-}
-
-/* release a log object */
-local void log_clean(gz_log *log)
-{
- unlock(log->fd);
- (void)close(log->fd);
- free(log);
-}
-
-/* read an unsigned long from a byte buffer little-endian */
-local unsigned long make_ulg(unsigned char *buf)
-{
- int n;
- unsigned long val;
-
- val = (unsigned long)(*buf++);
- for (n = 8; n < 32; n += 8)
- val += (unsigned long)(*buf++) << n;
- return val;
-}
-
-/* read an off_t from a byte buffer little-endian */
-local off_t make_off(unsigned char *buf)
-{
- int n;
- off_t val;
-
- val = (off_t)(*buf++);
- for (n = 8; n < 64; n += 8)
- val += (off_t)(*buf++) << n;
- return val;
-}
-
-/* write an unsigned long little-endian to byte buffer */
-local void dice_ulg(unsigned long val, unsigned char *buf)
-{
- int n;
-
- for (n = 0; n < 4; n++) {
- *buf++ = val & 0xff;
- val >>= 8;
- }
-}
-
-/* write an off_t little-endian to byte buffer */
-local void dice_off(off_t val, unsigned char *buf)
-{
- int n;
-
- for (n = 0; n < 8; n++) {
- *buf++ = val & 0xff;
- val >>= 8;
- }
-}
-
-/* initial, empty gzip file for appending */
-local char empty_gz[] = {
- 0x1f, 0x8b, /* magic gzip id */
- 8, /* compression method is deflate */
- 4, /* there is an extra field */
- 0, 0, 0, 0, /* no modification time provided */
- 0, 0xff, /* no extra flags, no OS */
- 20, 0, 'a', 'p', 16, 0, /* extra field with "ap" subfield */
- 32, 0, 0, 0, 0, 0, 0, 0, /* offset of uncompressed data */
- 32, 0, 0, 0, 0, 0, 0, 0, /* offset of last block */
- 1, 0, 0, 0xff, 0xff, /* empty stored block (last) */
- 0, 0, 0, 0, /* crc */
- 0, 0, 0, 0 /* uncompressed length */
-};
-
-/* initialize a log object with locking */
-void *gzlog_open(char *path)
-{
- unsigned xlen;
- unsigned char temp[20];
- unsigned sub_len;
- int good;
- gz_log *log;
-
- /* allocate log structure */
- log = malloc(sizeof(gz_log));
- if (log == NULL)
- return NULL;
- log->id = GZLOGID;
-
- /* open file, creating it if necessary, and locking it */
- log->fd = open(path, O_RDWR | O_CREAT, 0600);
- if (log->fd < 0) {
- free(log);
- return NULL;
- }
- if (lock(log->fd)) {
- close(log->fd);
- free(log);
- return NULL;
- }
-
- /* if file is empty, write new gzip stream */
- if (lseek(log->fd, 0, SEEK_END) == 0) {
- if (write(log->fd, empty_gz, sizeof(empty_gz)) != sizeof(empty_gz)) {
- log_clean(log);
- return NULL;
- }
- }
-
- /* check gzip header */
- (void)lseek(log->fd, 0, SEEK_SET);
- if (read(log->fd, temp, 12) != 12 || temp[0] != 0x1f ||
- temp[1] != 0x8b || temp[2] != 8 || (temp[3] & 4) == 0) {
- log_clean(log);
- return NULL;
- }
-
- /* process extra field to find "ap" sub-field */
- xlen = temp[10] + (temp[11] << 8);
- good = 0;
- while (xlen) {
- if (xlen < 4 || read(log->fd, temp, 4) != 4)
- break;
- sub_len = temp[2];
- sub_len += temp[3] << 8;
- xlen -= 4;
- if (memcmp(temp, "ap", 2) == 0 && sub_len == 16) {
- good = 1;
- break;
- }
- if (xlen < sub_len)
- break;
- (void)lseek(log->fd, sub_len, SEEK_CUR);
- xlen -= sub_len;
- }
- if (!good) {
- log_clean(log);
- return NULL;
- }
-
- /* read in "ap" sub-field */
- log->extra = lseek(log->fd, 0, SEEK_CUR);
- if (read(log->fd, temp, 16) != 16) {
- log_clean(log);
- return NULL;
- }
- log->mark_off = make_off(temp);
- log->last_off = make_off(temp + 8);
-
- /* get crc, length of gzip file */
- (void)lseek(log->fd, log->last_off, SEEK_SET);
- if (read(log->fd, temp, 13) != 13 ||
- memcmp(temp, "\001\000\000\377\377", 5) != 0) {
- log_clean(log);
- return NULL;
- }
- log->crc = make_ulg(temp + 5);
- log->len = make_ulg(temp + 9);
-
- /* set up to write over empty last block */
- (void)lseek(log->fd, log->last_off + 5, SEEK_SET);
- log->stored = 0;
- return (void *)log;
-}
-
-/* maximum amount to put in a stored block before starting a new one */
-#define MAX_BLOCK 16384
-
-/* write a block to a log object */
-int gzlog_write(void *obj, char *data, size_t len)
-{
- size_t some;
- unsigned char temp[5];
- gz_log *log;
-
- /* check object */
- log = (gz_log *)obj;
- if (log == NULL || log->id != GZLOGID)
- return 1;
-
- /* write stored blocks until all of the input is written */
- do {
- some = MAX_BLOCK - log->stored;
- if (some > len)
- some = len;
- if (write(log->fd, data, some) != some)
- return 1;
- log->crc = crc32(log->crc, data, some);
- log->len += some;
- len -= some;
- data += some;
- log->stored += some;
-
- /* if the stored block is full, end it and start another */
- if (log->stored == MAX_BLOCK) {
- (void)lseek(log->fd, log->last_off, SEEK_SET);
- temp[0] = 0;
- dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16),
- temp + 1);
- if (write(log->fd, temp, 5) != 5)
- return 1;
- log->last_off = lseek(log->fd, log->stored, SEEK_CUR);
- (void)lseek(log->fd, 5, SEEK_CUR);
- log->stored = 0;
- }
- } while (len);
- return 0;
-}
-
-/* recompress the remaining stored deflate data in place */
-local int recomp(gz_log *log)
-{
- z_stream strm;
- size_t len, max;
- unsigned char *in;
- unsigned char *out;
- unsigned char temp[16];
-
- /* allocate space and read it all in (it's around 1 MB) */
- len = log->last_off - log->mark_off;
- max = len + (len >> 12) + (len >> 14) + 11;
- out = malloc(max);
- if (out == NULL)
- return 1;
- in = malloc(len);
- if (in == NULL) {
- free(out);
- return 1;
- }
- (void)lseek(log->fd, log->mark_off, SEEK_SET);
- if (read(log->fd, in, len) != len) {
- free(in);
- free(out);
- return 1;
- }
-
- /* recompress in memory, decoding stored data as we go */
- /* note: this assumes that unsigned is four bytes or more */
- /* consider not making that assumption */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- if (deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 8,
- Z_DEFAULT_STRATEGY) != Z_OK) {
- free(in);
- free(out);
- return 1;
- }
- strm.next_in = in;
- strm.avail_out = max;
- strm.next_out = out;
- while (len >= 5) {
- if (strm.next_in[0] != 0)
- break;
- strm.avail_in = strm.next_in[1] + (strm.next_in[2] << 8);
- strm.next_in += 5;
- len -= 5;
- if (strm.avail_in != 0) {
- if (len < strm.avail_in)
- break;
- len -= strm.avail_in;
- (void)deflate(&strm, Z_NO_FLUSH);
- if (strm.avail_in != 0 || strm.avail_out == 0)
- break;
- }
- }
- (void)deflate(&strm, Z_SYNC_FLUSH);
- (void)deflateEnd(&strm);
- free(in);
- if (len != 0 || strm.avail_out == 0) {
- free(out);
- return 1;
- }
-
- /* overwrite stored data with compressed data */
- (void)lseek(log->fd, log->mark_off, SEEK_SET);
- len = max - strm.avail_out;
- if (write(log->fd, out, len) != len) {
- free(out);
- return 1;
- }
- free(out);
-
- /* write last empty block, crc, and length */
- log->mark_off = log->last_off = lseek(log->fd, 0, SEEK_CUR);
- temp[0] = 1;
- dice_ulg(0xffffL << 16, temp + 1);
- dice_ulg(log->crc, temp + 5);
- dice_ulg(log->len, temp + 9);
- if (write(log->fd, temp, 13) != 13)
- return 1;
-
- /* truncate file to discard remaining stored data and old trailer */
- ftruncate(log->fd, lseek(log->fd, 0, SEEK_CUR));
-
- /* update extra field to point to new last empty block */
- (void)lseek(log->fd, log->extra, SEEK_SET);
- dice_off(log->mark_off, temp);
- dice_off(log->last_off, temp + 8);
- if (write(log->fd, temp, 16) != 16)
- return 1;
- return 0;
-}
-
-/* maximum accumulation of stored blocks before compressing */
-#define MAX_STORED 1048576
-
-/* close log object */
-int gzlog_close(void *obj)
-{
- unsigned char temp[8];
- gz_log *log;
-
- /* check object */
- log = (gz_log *)obj;
- if (log == NULL || log->id != GZLOGID)
- return 1;
-
- /* go to start of most recent block being written */
- (void)lseek(log->fd, log->last_off, SEEK_SET);
-
- /* if some stuff was put there, update block */
- if (log->stored) {
- temp[0] = 0;
- dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16),
- temp + 1);
- if (write(log->fd, temp, 5) != 5)
- return 1;
- log->last_off = lseek(log->fd, log->stored, SEEK_CUR);
- }
-
- /* write last block (empty) */
- if (write(log->fd, "\001\000\000\377\377", 5) != 5)
- return 1;
-
- /* write updated crc and uncompressed length */
- dice_ulg(log->crc, temp);
- dice_ulg(log->len, temp + 4);
- if (write(log->fd, temp, 8) != 8)
- return 1;
-
- /* put offset of that last block in gzip extra block */
- (void)lseek(log->fd, log->extra + 8, SEEK_SET);
- dice_off(log->last_off, temp);
- if (write(log->fd, temp, 8) != 8)
- return 1;
-
- /* if more than 1 MB stored, then time to compress it */
- if (log->last_off - log->mark_off > MAX_STORED) {
- if (recomp(log))
- return 1;
- }
-
- /* unlock and close file */
- log_clean(log);
- return 0;
-}
diff --git a/cpukit/zlib/examples/gzlog.h b/cpukit/zlib/examples/gzlog.h
deleted file mode 100644
index a800bd5391..0000000000
--- a/cpukit/zlib/examples/gzlog.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* gzlog.h
- Copyright (C) 2004 Mark Adler, all rights reserved
- version 1.0, 26 Nov 2004
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Mark Adler madler@alumni.caltech.edu
- */
-
-/*
- The gzlog object allows writing short messages to a gzipped log file,
- opening the log file locked for small bursts, and then closing it. The log
- object works by appending stored data to the gzip file until 1 MB has been
- accumulated. At that time, the stored data is compressed, and replaces the
- uncompressed data in the file. The log file is truncated to its new size at
- that time. After closing, the log file is always valid gzip file that can
- decompressed to recover what was written.
-
- A gzip header "extra" field contains two file offsets for appending. The
- first points to just after the last compressed data. The second points to
- the last stored block in the deflate stream, which is empty. All of the
- data between those pointers is uncompressed.
- */
-
-/* Open a gzlog object, creating the log file if it does not exist. Return
- NULL on error. Note that gzlog_open() could take a long time to return if
- there is difficulty in locking the file. */
-void *gzlog_open(char *path);
-
-/* Write to a gzlog object. Return non-zero on error. This function will
- simply write data to the file uncompressed. Compression of the data
- will not occur until gzlog_close() is called. It is expected that
- gzlog_write() is used for a short message, and then gzlog_close() is
- called. If a large amount of data is to be written, then the application
- should write no more than 1 MB at a time with gzlog_write() before
- calling gzlog_close() and then gzlog_open() again. */
-int gzlog_write(void *log, char *data, size_t len);
-
-/* Close a gzlog object. Return non-zero on error. The log file is locked
- until this function is called. This function will compress stored data
- at the end of the gzip file if at least 1 MB has been accumulated. Note
- that the file will not be a valid gzip file until this function completes.
- */
-int gzlog_close(void *log);
diff --git a/cpukit/zlib/examples/zlib_how.html b/cpukit/zlib/examples/zlib_how.html
deleted file mode 100644
index b2bda6b6d6..0000000000
--- a/cpukit/zlib/examples/zlib_how.html
+++ /dev/null
@@ -1,522 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
- "http://www.w3.org/TR/REC-html40/loose.dtd">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-<title>zlib Usage Example</title>
-<!-- Copyright (c) 2004 Mark Adler. -->
-</head>
-<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#00A000">
-<h2 align="center"> zlib Usage Example </h2>
-We often get questions about how the <tt>deflate()</tt> and <tt>inflate()</tt> functions should be used.
-Users wonder when they should provide more input, when they should use more output,
-what to do with a <tt>Z_BUF_ERROR</tt>, how to make sure the process terminates properly, and
-so on. So for those who have read <tt>zlib.h</tt> (a few times), and
-would like further edification, below is an annotated example in C of simple routines to compress and decompress
-from an input file to an output file using <tt>deflate()</tt> and <tt>inflate()</tt> respectively. The
-annotations are interspersed between lines of the code. So please read between the lines.
-We hope this helps explain some of the intricacies of <em>zlib</em>.
-<p>
-Without further adieu, here is the program <a href="zpipe.c"><tt>zpipe.c</tt></a>:
-<pre><b>
-/* zpipe.c: example of proper use of zlib's inflate() and deflate()
- Not copyrighted -- provided to the public domain
- Version 1.2 9 November 2004 Mark Adler */
-
-/* Version history:
- 1.0 30 Oct 2004 First version
- 1.1 8 Nov 2004 Add void casting for unused return values
- Use switch statement for inflate() return values
- 1.2 9 Nov 2004 Add assertions to document zlib guarantees
- */
-</b></pre><!-- -->
-We now include the header files for the required definitions. From
-<tt>stdio.h</tt> we use <tt>fopen()</tt>, <tt>fread()</tt>, <tt>fwrite()</tt>,
-<tt>feof()</tt>, <tt>ferror()</tt>, and <tt>fclose()</tt> for file i/o, and
-<tt>fputs()</tt> for error messages. From <tt>string.h</tt> we use
-<tt>strcmp()</tt> for command line argument processing.
-From <tt>assert.h</tt> we use the <tt>assert()</tt> macro.
-From <tt>zlib.h</tt>
-we use the basic compression functions <tt>deflateInit()</tt>,
-<tt>deflate()</tt>, and <tt>deflateEnd()</tt>, and the basic decompression
-functions <tt>inflateInit()</tt>, <tt>inflate()</tt>, and
-<tt>inflateEnd()</tt>.
-<pre><b>
-#include &lt;stdio.h&gt;
-#include &lt;string.h&gt;
-#include &lt;assert.h&gt;
-#include "zlib.h"
-</b></pre><!-- -->
-<tt>CHUNK</tt> is simply the buffer size for feeding data to and pulling data
-from the <em>zlib</em> routines. Larger buffer sizes would be more efficient,
-especially for <tt>inflate()</tt>. If the memory is available, buffers sizes
-on the order of 128K or 256K bytes should be used.
-<pre><b>
-#define CHUNK 16384
-</b></pre><!-- -->
-The <tt>def()</tt> routine compresses data from an input file to an output file. The output data
-will be in the <em>zlib</em> format, which is different from the <em>gzip</em> or <em>zip</em>
-formats. The <em>zlib</em> format has a very small header of only two bytes to identify it as
-a <em>zlib</em> stream and to provide decoding information, and a four-byte trailer with a fast
-check value to verify the integrity of the uncompressed data after decoding.
-<pre><b>
-/* Compress from file source to file dest until EOF on source.
- def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
- allocated for processing, Z_STREAM_ERROR if an invalid compression
- level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
- version of the library linked do not match, or Z_ERRNO if there is
- an error reading or writing the files. */
-int def(FILE *source, FILE *dest, int level)
-{
-</b></pre>
-Here are the local variables for <tt>def()</tt>. <tt>ret</tt> will be used for <em>zlib</em>
-return codes. <tt>flush</tt> will keep track of the current flushing state for <tt>deflate()</tt>,
-which is either no flushing, or flush to completion after the end of the input file is reached.
-<tt>have</tt> is the amount of data returned from <tt>deflate()</tt>. The <tt>strm</tt> structure
-is used to pass information to and from the <em>zlib</em> routines, and to maintain the
-<tt>deflate()</tt> state. <tt>in</tt> and <tt>out</tt> are the input and output buffers for
-<tt>deflate()</tt>.
-<pre><b>
- int ret, flush;
- unsigned have;
- z_stream strm;
- char in[CHUNK];
- char out[CHUNK];
-</b></pre><!-- -->
-The first thing we do is to initialize the <em>zlib</em> state for compression using
-<tt>deflateInit()</tt>. This must be done before the first use of <tt>deflate()</tt>.
-The <tt>zalloc</tt>, <tt>zfree</tt>, and <tt>opaque</tt> fields in the <tt>strm</tt>
-structure must be initialized before calling <tt>deflateInit()</tt>. Here they are
-set to the <em>zlib</em> constant <tt>Z_NULL</tt> to request that <em>zlib</em> use
-the default memory allocation routines. An application may also choose to provide
-custom memory allocation routines here. <tt>deflateInit()</tt> will allocate on the
-order of 256K bytes for the internal state.
-(See <a href="zlib_tech.html"><em>zlib Technical Details</em></a>.)
-<p>
-<tt>deflateInit()</tt> is called with a pointer to the structure to be initialized and
-the compression level, which is an integer in the range of -1 to 9. Lower compression
-levels result in faster execution, but less compression. Higher levels result in
-greater compression, but slower execution. The <em>zlib</em> constant Z_DEFAULT_COMPRESSION,
-equal to -1,
-provides a good compromise between compression and speed and is equivalent to level 6.
-Level 0 actually does no compression at all, and in fact expands the data slightly to produce
-the <em>zlib</em> format (it is not a byte-for-byte copy of the input).
-More advanced applications of <em>zlib</em>
-may use <tt>deflateInit2()</tt> here instead. Such an application may want to reduce how
-much memory will be used, at some price in compression. Or it may need to request a
-<em>gzip</em> header and trailer instead of a <em>zlib</em> header and trailer, or raw
-encoding with no header or trailer at all.
-<p>
-We must check the return value of <tt>deflateInit()</tt> against the <em>zlib</em> constant
-<tt>Z_OK</tt> to make sure that it was able to
-allocate memory for the internal state, and that the provided arguments were valid.
-<tt>deflateInit()</tt> will also check that the version of <em>zlib</em> that the <tt>zlib.h</tt>
-file came from matches the version of <em>zlib</em> actually linked with the program. This
-is especially important for environments in which <em>zlib</em> is a shared library.
-<p>
-Note that an application can initialize multiple, independent <em>zlib</em> streams, which can
-operate in parallel. The state information maintained in the structure allows the <em>zlib</em>
-routines to be reentrant.
-<pre><b>
- /* allocate deflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- ret = deflateInit(&amp;strm, level);
- if (ret != Z_OK)
- return ret;
-</b></pre><!-- -->
-With the pleasantries out of the way, now we can get down to business. The outer <tt>do</tt>-loop
-reads all of the input file and exits at the bottom of the loop once end-of-file is reached.
-This loop contains the only call of <tt>deflate()</tt>. So we must make sure that all of the
-input data has been processed and that all of the output data has been generated and consumed
-before we fall out of the loop at the bottom.
-<pre><b>
- /* compress until end of file */
- do {
-</b></pre>
-We start off by reading data from the input file. The number of bytes read is put directly
-into <tt>avail_in</tt>, and a pointer to those bytes is put into <tt>next_in</tt>. We also
-check to see if end-of-file on the input has been reached. If we are at the end of file, then <tt>flush</tt> is set to the
-<em>zlib</em> constant <tt>Z_FINISH</tt>, which is later passed to <tt>deflate()</tt> to
-indicate that this is the last chunk of input data to compress. We need to use <tt>feof()</tt>
-to check for end-of-file as opposed to seeing if fewer than <tt>CHUNK</tt> bytes have been read. The
-reason is that if the input file length is an exact multiple of <tt>CHUNK</tt>, we will miss
-the fact that we got to the end-of-file, and not know to tell <tt>deflate()</tt> to finish
-up the compressed stream. If we are not yet at the end of the input, then the <em>zlib</em>
-constant <tt>Z_NO_FLUSH</tt> will be passed to <tt>deflate</tt> to indicate that we are still
-in the middle of the uncompressed data.
-<p>
-If there is an error in reading from the input file, the process is aborted with
-<tt>deflateEnd()</tt> being called to free the allocated <em>zlib</em> state before returning
-the error. We wouldn't want a memory leak, now would we? <tt>deflateEnd()</tt> can be called
-at any time after the state has been initialized. Once that's done, <tt>deflateInit()</tt> (or
-<tt>deflateInit2()</tt>) would have to be called to start a new compression process. There is
-no point here in checking the <tt>deflateEnd()</tt> return code. The deallocation can't fail.
-<pre><b>
- strm.avail_in = fread(in, 1, CHUNK, source);
- if (ferror(source)) {
- (void)deflateEnd(&amp;strm);
- return Z_ERRNO;
- }
- flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
- strm.next_in = in;
-</b></pre><!-- -->
-The inner <tt>do</tt>-loop passes our chunk of input data to <tt>deflate()</tt>, and then
-keeps calling <tt>deflate()</tt> until it is done producing output. Once there is no more
-new output, <tt>deflate()</tt> is guaranteed to have consumed all of the input, i.e.,
-<tt>avail_in</tt> will be zero.
-<pre><b>
- /* run deflate() on input until output buffer not full, finish
- compression if all of source has been read in */
- do {
-</b></pre>
-Output space is provided to <tt>deflate()</tt> by setting <tt>avail_out</tt> to the number
-of available output bytes and <tt>next_out</tt> to a pointer to that space.
-<pre><b>
- strm.avail_out = CHUNK;
- strm.next_out = out;
-</b></pre>
-Now we call the compression engine itself, <tt>deflate()</tt>. It takes as many of the
-<tt>avail_in</tt> bytes at <tt>next_in</tt> as it can process, and writes as many as
-<tt>avail_out</tt> bytes to <tt>next_out</tt>. Those counters and pointers are then
-updated past the input data consumed and the output data written. It is the amount of
-output space available that may limit how much input is consumed.
-Hence the inner loop to make sure that
-all of the input is consumed by providing more output space each time. Since <tt>avail_in</tt>
-and <tt>next_in</tt> are updated by <tt>deflate()</tt>, we don't have to mess with those
-between <tt>deflate()</tt> calls until it's all used up.
-<p>
-The parameters to <tt>deflate()</tt> are a pointer to the <tt>strm</tt> structure containing
-the input and output information and the internal compression engine state, and a parameter
-indicating whether and how to flush data to the output. Normally <tt>deflate</tt> will consume
-several K bytes of input data before producing any output (except for the header), in order
-to accumulate statistics on the data for optimum compression. It will then put out a burst of
-compressed data, and proceed to consume more input before the next burst. Eventually,
-<tt>deflate()</tt>
-must be told to terminate the stream, complete the compression with provided input data, and
-write out the trailer check value. <tt>deflate()</tt> will continue to compress normally as long
-as the flush parameter is <tt>Z_NO_FLUSH</tt>. Once the <tt>Z_FINISH</tt> parameter is provided,
-<tt>deflate()</tt> will begin to complete the compressed output stream. However depending on how
-much output space is provided, <tt>deflate()</tt> may have to be called several times until it
-has provided the complete compressed stream, even after it has consumed all of the input. The flush
-parameter must continue to be <tt>Z_FINISH</tt> for those subsequent calls.
-<p>
-There are other values of the flush parameter that are used in more advanced applications. You can
-force <tt>deflate()</tt> to produce a burst of output that encodes all of the input data provided
-so far, even if it wouldn't have otherwise, for example to control data latency on a link with
-compressed data. You can also ask that <tt>deflate()</tt> do that as well as erase any history up to
-that point so that what follows can be decompressed independently, for example for random access
-applications. Both requests will degrade compression by an amount depending on how often such
-requests are made.
-<p>
-<tt>deflate()</tt> has a return value that can indicate errors, yet we do not check it here. Why
-not? Well, it turns out that <tt>deflate()</tt> can do no wrong here. Let's go through
-<tt>deflate()</tt>'s return values and dispense with them one by one. The possible values are
-<tt>Z_OK</tt>, <tt>Z_STREAM_END</tt>, <tt>Z_STREAM_ERROR</tt>, or <tt>Z_BUF_ERROR</tt>. <tt>Z_OK</tt>
-is, well, ok. <tt>Z_STREAM_END</tt> is also ok and will be returned for the last call of
-<tt>deflate()</tt>. This is already guaranteed by calling <tt>deflate()</tt> with <tt>Z_FINISH</tt>
-until it has no more output. <tt>Z_STREAM_ERROR</tt> is only possible if the stream is not
-initialized properly, but we did initialize it properly. There is no harm in checking for
-<tt>Z_STREAM_ERROR</tt> here, for example to check for the possibility that some
-other part of the application inadvertently clobbered the memory containing the <em>zlib</em> state.
-<tt>Z_BUF_ERROR</tt> will be explained further below, but
-suffice it to say that this is simply an indication that <tt>deflate()</tt> could not consume
-more input or produce more output. <tt>deflate()</tt> can be called again with more output space
-or more available input, which it will be in this code.
-<pre><b>
- ret = deflate(&amp;strm, flush); /* no bad return value */
- assert(ret != Z_STREAM_ERROR); /* state not clobbered */
-</b></pre>
-Now we compute how much output <tt>deflate()</tt> provided on the last call, which is the
-difference between how much space was provided before the call, and how much output space
-is still available after the call. Then that data, if any, is written to the output file.
-We can then reuse the output buffer for the next call of <tt>deflate()</tt>. Again if there
-is a file i/o error, we call <tt>deflateEnd()</tt> before returning to avoid a memory leak.
-<pre><b>
- have = CHUNK - strm.avail_out;
- if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
- (void)deflateEnd(&amp;strm);
- return Z_ERRNO;
- }
-</b></pre>
-The inner <tt>do</tt>-loop is repeated until the last <tt>deflate()</tt> call fails to fill the
-provided output buffer. Then we know that <tt>deflate()</tt> has done as much as it can with
-the provided input, and that all of that input has been consumed. We can then fall out of this
-loop and reuse the input buffer.
-<p>
-The way we tell that <tt>deflate()</tt> has no more output is by seeing that it did not fill
-the output buffer, leaving <tt>avail_out</tt> greater than zero. However suppose that
-<tt>deflate()</tt> has no more output, but just so happened to exactly fill the output buffer!
-<tt>avail_out</tt> is zero, and we can't tell that <tt>deflate()</tt> has done all it can.
-As far as we know, <tt>deflate()</tt>
-has more output for us. So we call it again. But now <tt>deflate()</tt> produces no output
-at all, and <tt>avail_out</tt> remains unchanged as <tt>CHUNK</tt>. That <tt>deflate()</tt> call
-wasn't able to do anything, either consume input or produce output, and so it returns
-<tt>Z_BUF_ERROR</tt>. (See, I told you I'd cover this later.) However this is not a problem at
-all. Now we finally have the desired indication that <tt>deflate()</tt> is really done,
-and so we drop out of the inner loop to provide more input to <tt>deflate()</tt>.
-<p>
-With <tt>flush</tt> set to <tt>Z_FINISH</tt>, this final set of <tt>deflate()</tt> calls will
-complete the output stream. Once that is done, subsequent calls of <tt>deflate()</tt> would return
-<tt>Z_STREAM_ERROR</tt> if the flush parameter is not <tt>Z_FINISH</tt>, and do no more processing
-until the state is reinitialized.
-<p>
-Some applications of <em>zlib</em> have two loops that call <tt>deflate()</tt>
-instead of the single inner loop we have here. The first loop would call
-without flushing and feed all of the data to <tt>deflate()</tt>. The second loop would call
-<tt>deflate()</tt> with no more
-data and the <tt>Z_FINISH</tt> parameter to complete the process. As you can see from this
-example, that can be avoided by simply keeping track of the current flush state.
-<pre><b>
- } while (strm.avail_out == 0);
- assert(strm.avail_in == 0); /* all input will be used */
-</b></pre><!-- -->
-Now we check to see if we have already processed all of the input file. That information was
-saved in the <tt>flush</tt> variable, so we see if that was set to <tt>Z_FINISH</tt>. If so,
-then we're done and we fall out of the outer loop. We're guaranteed to get <tt>Z_STREAM_END</tt>
-from the last <tt>deflate()</tt> call, since we ran it until the last chunk of input was
-consumed and all of the output was generated.
-<pre><b>
- /* done when last data in file processed */
- } while (flush != Z_FINISH);
- assert(ret == Z_STREAM_END); /* stream will be complete */
-</b></pre><!-- -->
-The process is complete, but we still need to deallocate the state to avoid a memory leak
-(or rather more like a memory hemorrhage if you didn't do this). Then
-finally we can return with a happy return value.
-<pre><b>
- /* clean up and return */
- (void)deflateEnd(&amp;strm);
- return Z_OK;
-}
-</b></pre><!-- -->
-Now we do the same thing for decompression in the <tt>inf()</tt> routine. <tt>inf()</tt>
-decompresses what is hopefully a valid <em>zlib</em> stream from the input file and writes the
-uncompressed data to the output file. Much of the discussion above for <tt>def()</tt>
-applies to <tt>inf()</tt> as well, so the discussion here will focus on the differences between
-the two.
-<pre><b>
-/* Decompress from file source to file dest until stream ends or EOF.
- inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
- allocated for processing, Z_DATA_ERROR if the deflate data is
- invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
- the version of the library linked do not match, or Z_ERRNO if there
- is an error reading or writing the files. */
-int inf(FILE *source, FILE *dest)
-{
-</b></pre>
-The local variables have the same functionality as they do for <tt>def()</tt>. The
-only difference is that there is no <tt>flush</tt> variable, since <tt>inflate()</tt>
-can tell from the <em>zlib</em> stream itself when the stream is complete.
-<pre><b>
- int ret;
- unsigned have;
- z_stream strm;
- char in[CHUNK];
- char out[CHUNK];
-</b></pre><!-- -->
-The initialization of the state is the same, except that there is no compression level,
-of course, and two more elements of the structure are initialized. <tt>avail_in</tt>
-and <tt>next_in</tt> must be initialized before calling <tt>inflateInit()</tt>. This
-is because the application has the option to provide the start of the zlib stream in
-order for <tt>inflateInit()</tt> to have access to information about the compression
-method to aid in memory allocation. In the current implementation of <em>zlib</em>
-(up through versions 1.2.x), the method-dependent memory allocations are deferred to the first call of
-<tt>inflate()</tt> anyway. However those fields must be initialized since later versions
-of <em>zlib</em> that provide more compression methods may take advantage of this interface.
-In any case, no decompression is performed by <tt>inflateInit()</tt>, so the
-<tt>avail_out</tt> and <tt>next_out</tt> fields do not need to be initialized before calling.
-<p>
-Here <tt>avail_in</tt> is set to zero and <tt>next_in</tt> is set to <tt>Z_NULL</tt> to
-indicate that no input data is being provided.
-<pre><b>
- /* allocate inflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
- ret = inflateInit(&amp;strm);
- if (ret != Z_OK)
- return ret;
-</b></pre><!-- -->
-The outer <tt>do</tt>-loop decompresses input until <tt>inflate()</tt> indicates
-that it has reached the end of the compressed data and has produced all of the uncompressed
-output. This is in contrast to <tt>def()</tt> which processes all of the input file.
-If end-of-file is reached before the compressed data self-terminates, then the compressed
-data is incomplete and an error is returned.
-<pre><b>
- /* decompress until deflate stream ends or end of file */
- do {
-</b></pre>
-We read input data and set the <tt>strm</tt> structure accordingly. If we've reached the
-end of the input file, then we leave the outer loop and report an error, since the
-compressed data is incomplete. Note that we may read more data than is eventually consumed
-by <tt>inflate()</tt>, if the input file continues past the <em>zlib</em> stream.
-For applications where <em>zlib</em> streams are embedded in other data, this routine would
-need to be modified to return the unused data, or at least indicate how much of the input
-data was not used, so the application would know where to pick up after the <em>zlib</em> stream.
-<pre><b>
- strm.avail_in = fread(in, 1, CHUNK, source);
- if (ferror(source)) {
- (void)inflateEnd(&amp;strm);
- return Z_ERRNO;
- }
- if (strm.avail_in == 0)
- break;
- strm.next_in = in;
-</b></pre><!-- -->
-The inner <tt>do</tt>-loop has the same function it did in <tt>def()</tt>, which is to
-keep calling <tt>inflate()</tt> until has generated all of the output it can with the
-provided input.
-<pre><b>
- /* run inflate() on input until output buffer not full */
- do {
-</b></pre>
-Just like in <tt>def()</tt>, the same output space is provided for each call of <tt>inflate()</tt>.
-<pre><b>
- strm.avail_out = CHUNK;
- strm.next_out = out;
-</b></pre>
-Now we run the decompression engine itself. There is no need to adjust the flush parameter, since
-the <em>zlib</em> format is self-terminating. The main difference here is that there are
-return values that we need to pay attention to. <tt>Z_DATA_ERROR</tt>
-indicates that <tt>inflate()</tt> detected an error in the <em>zlib</em> compressed data format,
-which means that either the data is not a <em>zlib</em> stream to begin with, or that the data was
-corrupted somewhere along the way since it was compressed. The other error to be processed is
-<tt>Z_MEM_ERROR</tt>, which can occur since memory allocation is deferred until <tt>inflate()</tt>
-needs it, unlike <tt>deflate()</tt>, whose memory is allocated at the start by <tt>deflateInit()</tt>.
-<p>
-Advanced applications may use
-<tt>deflateSetDictionary()</tt> to prime <tt>deflate()</tt> with a set of likely data to improve the
-first 32K or so of compression. This is noted in the <em>zlib</em> header, so <tt>inflate()</tt>
-requests that that dictionary be provided before it can start to decompress. Without the dictionary,
-correct decompression is not possible. For this routine, we have no idea what the dictionary is,
-so the <tt>Z_NEED_DICT</tt> indication is converted to a <tt>Z_DATA_ERROR</tt>.
-<p>
-<tt>inflate()</tt> can also return <tt>Z_STREAM_ERROR</tt>, which should not be possible here,
-but could be checked for as noted above for <tt>def()</tt>. <tt>Z_BUF_ERROR</tt> does not need to be
-checked for here, for the same reasons noted for <tt>def()</tt>. <tt>Z_STREAM_END</tt> will be
-checked for later.
-<pre><b>
- ret = inflate(&amp;strm, Z_NO_FLUSH);
- assert(ret != Z_STREAM_ERROR); /* state not clobbered */
- switch (ret) {
- case Z_NEED_DICT:
- ret = Z_DATA_ERROR; /* and fall through */
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- (void)inflateEnd(&amp;strm);
- return ret;
- }
-</b></pre>
-The output of <tt>inflate()</tt> is handled identically to that of <tt>deflate()</tt>.
-<pre><b>
- have = CHUNK - strm.avail_out;
- if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
- (void)inflateEnd(&amp;strm);
- return Z_ERRNO;
- }
-</b></pre>
-The inner <tt>do</tt>-loop ends when <tt>inflate()</tt> has no more output as indicated
-by not filling the output buffer, just as for <tt>deflate()</tt>.
-<pre><b>
- } while (strm.avail_out == 0);
- assert(strm.avail_in == 0); /* all input will be used */
-</b></pre><!-- -->
-The outer <tt>do</tt>-loop ends when <tt>inflate()</tt> reports that it has reached the
-end of the input <em>zlib</em> stream, has completed the decompression and integrity
-check, and has provided all of the output. This is indicated by the <tt>inflate()</tt>
-return value <tt>Z_STREAM_END</tt>. The inner loop is guaranteed to leave <tt>ret</tt>
-equal to <tt>Z_STREAM_END</tt> if the last chunk of the input file read contained the end
-of the <em>zlib</em> stream. So if the return value is not <tt>Z_STREAM_END</tt>, the
-loop continues to read more input.
-<pre><b>
- /* done when inflate() says it's done */
- } while (ret != Z_STREAM_END);
-</b></pre><!-- -->
-At this point, decompression successfully completed, or we broke out of the loop due to no
-more data being available from the input file. If the last <tt>inflate()</tt> return value
-is not <tt>Z_STREAM_END</tt>, then the <em>zlib</em> stream was incomplete and a data error
-is returned. Otherwise, we return with a happy return value. Of course, <tt>inflateEnd()</tt>
-is called first to avoid a memory leak.
-<pre><b>
- /* clean up and return */
- (void)inflateEnd(&amp;strm);
- return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
-}
-</b></pre><!-- -->
-That ends the routines that directly use <em>zlib</em>. The following routines make this
-a command-line program by running data through the above routines from <tt>stdin</tt> to
-<tt>stdout</tt>, and handling any errors reported by <tt>def()</tt> or <tt>inf()</tt>.
-<p>
-<tt>zerr()</tt> is used to interpret the possible error codes from <tt>def()</tt>
-and <tt>inf()</tt>, as detailed in their comments above, and print out an error message.
-Note that these are only a subset of the possible return values from <tt>deflate()</tt>
-and <tt>inflate()</tt>.
-<pre><b>
-/* report a zlib or i/o error */
-void zerr(int ret)
-{
- fputs("zpipe: ", stderr);
- switch (ret) {
- case Z_ERRNO:
- if (ferror(stdin))
- fputs("error reading stdin\n", stderr);
- if (ferror(stdout))
- fputs("error writing stdout\n", stderr);
- break;
- case Z_STREAM_ERROR:
- fputs("invalid compression level\n", stderr);
- break;
- case Z_DATA_ERROR:
- fputs("invalid or incomplete deflate data\n", stderr);
- break;
- case Z_MEM_ERROR:
- fputs("out of memory\n", stderr);
- break;
- case Z_VERSION_ERROR:
- fputs("zlib version mismatch!\n", stderr);
- }
-}
-</b></pre><!-- -->
-Here is the <tt>main()</tt> routine used to test <tt>def()</tt> and <tt>inf()</tt>. The
-<tt>zpipe</tt> command is simply a compression pipe from <tt>stdin</tt> to <tt>stdout</tt>, if
-no arguments are given, or it is a decompression pipe if <tt>zpipe -d</tt> is used. If any other
-arguments are provided, no compression or decompression is performed. Instead a usage
-message is displayed. Examples are <tt>zpipe < foo.txt > foo.txt.z</tt> to compress, and
-<tt>zpipe -d < foo.txt.z > foo.txt</tt> to decompress.
-<pre><b>
-/* compress or decompress from stdin to stdout */
-int main(int argc, char **argv)
-{
- int ret;
-
- /* do compression if no arguments */
- if (argc == 1) {
- ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
- if (ret != Z_OK)
- zerr(ret);
- return ret;
- }
-
- /* do decompression if -d specified */
- else if (argc == 2 &amp;&amp; strcmp(argv[1], "-d") == 0) {
- ret = inf(stdin, stdout);
- if (ret != Z_OK)
- zerr(ret);
- return ret;
- }
-
- /* otherwise, report usage */
- else {
- fputs("zpipe usage: zpipe [-d] &lt; source &gt; dest\n", stderr);
- return 1;
- }
-}
-</b></pre>
-<hr>
-<i>Copyright (c) 2004 by Mark Adler<br>Last modified 13 November 2004</i>
-</body>
-</html>
diff --git a/cpukit/zlib/examples/zpipe.c b/cpukit/zlib/examples/zpipe.c
deleted file mode 100644
index a602d59f9a..0000000000
--- a/cpukit/zlib/examples/zpipe.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/* zpipe.c: example of proper use of zlib's inflate() and deflate()
- Not copyrighted -- provided to the public domain
- Version 1.2 9 November 2004 Mark Adler */
-
-/* Version history:
- 1.0 30 Oct 2004 First version
- 1.1 8 Nov 2004 Add void casting for unused return values
- Use switch statement for inflate() return values
- 1.2 9 Nov 2004 Add assertions to document zlib guarantees
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include "zlib.h"
-
-#define CHUNK 16384
-
-/* Compress from file source to file dest until EOF on source.
- def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
- allocated for processing, Z_STREAM_ERROR if an invalid compression
- level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
- version of the library linked do not match, or Z_ERRNO if there is
- an error reading or writing the files. */
-int def(FILE *source, FILE *dest, int level)
-{
- int ret, flush;
- unsigned have;
- z_stream strm;
- char in[CHUNK];
- char out[CHUNK];
-
- /* allocate deflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- ret = deflateInit(&strm, level);
- if (ret != Z_OK)
- return ret;
-
- /* compress until end of file */
- do {
- strm.avail_in = fread(in, 1, CHUNK, source);
- if (ferror(source)) {
- (void)deflateEnd(&strm);
- return Z_ERRNO;
- }
- flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
- strm.next_in = in;
-
- /* run deflate() on input until output buffer not full, finish
- compression if all of source has been read in */
- do {
- strm.avail_out = CHUNK;
- strm.next_out = out;
- ret = deflate(&strm, flush); /* no bad return value */
- assert(ret != Z_STREAM_ERROR); /* state not clobbered */
- have = CHUNK - strm.avail_out;
- if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
- (void)deflateEnd(&strm);
- return Z_ERRNO;
- }
- } while (strm.avail_out == 0);
- assert(strm.avail_in == 0); /* all input will be used */
-
- /* done when last data in file processed */
- } while (flush != Z_FINISH);
- assert(ret == Z_STREAM_END); /* stream will be complete */
-
- /* clean up and return */
- (void)deflateEnd(&strm);
- return Z_OK;
-}
-
-/* Decompress from file source to file dest until stream ends or EOF.
- inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
- allocated for processing, Z_DATA_ERROR if the deflate data is
- invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
- the version of the library linked do not match, or Z_ERRNO if there
- is an error reading or writing the files. */
-int inf(FILE *source, FILE *dest)
-{
- int ret;
- unsigned have;
- z_stream strm;
- char in[CHUNK];
- char out[CHUNK];
-
- /* allocate inflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
- ret = inflateInit(&strm);
- if (ret != Z_OK)
- return ret;
-
- /* decompress until deflate stream ends or end of file */
- do {
- strm.avail_in = fread(in, 1, CHUNK, source);
- if (ferror(source)) {
- (void)inflateEnd(&strm);
- return Z_ERRNO;
- }
- if (strm.avail_in == 0)
- break;
- strm.next_in = in;
-
- /* run inflate() on input until output buffer not full */
- do {
- strm.avail_out = CHUNK;
- strm.next_out = out;
- ret = inflate(&strm, Z_NO_FLUSH);
- assert(ret != Z_STREAM_ERROR); /* state not clobbered */
- switch (ret) {
- case Z_NEED_DICT:
- ret = Z_DATA_ERROR; /* and fall through */
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- (void)inflateEnd(&strm);
- return ret;
- }
- have = CHUNK - strm.avail_out;
- if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
- (void)inflateEnd(&strm);
- return Z_ERRNO;
- }
- } while (strm.avail_out == 0);
- assert(strm.avail_in == 0); /* all input will be used */
-
- /* done when inflate() says it's done */
- } while (ret != Z_STREAM_END);
-
- /* clean up and return */
- (void)inflateEnd(&strm);
- return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
-}
-
-/* report a zlib or i/o error */
-void zerr(int ret)
-{
- fputs("zpipe: ", stderr);
- switch (ret) {
- case Z_ERRNO:
- if (ferror(stdin))
- fputs("error reading stdin\n", stderr);
- if (ferror(stdout))
- fputs("error writing stdout\n", stderr);
- break;
- case Z_STREAM_ERROR:
- fputs("invalid compression level\n", stderr);
- break;
- case Z_DATA_ERROR:
- fputs("invalid or incomplete deflate data\n", stderr);
- break;
- case Z_MEM_ERROR:
- fputs("out of memory\n", stderr);
- break;
- case Z_VERSION_ERROR:
- fputs("zlib version mismatch!\n", stderr);
- }
-}
-
-/* compress or decompress from stdin to stdout */
-int main(int argc, char **argv)
-{
- int ret;
-
- /* do compression if no arguments */
- if (argc == 1) {
- ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
- if (ret != Z_OK)
- zerr(ret);
- return ret;
- }
-
- /* do decompression if -d specified */
- else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
- ret = inf(stdin, stdout);
- if (ret != Z_OK)
- zerr(ret);
- return ret;
- }
-
- /* otherwise, report usage */
- else {
- fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
- return 1;
- }
-}
diff --git a/cpukit/zlib/gzio.c b/cpukit/zlib/gzio.c
index 217a4cc410..2e2f85cf1f 100644
--- a/cpukit/zlib/gzio.c
+++ b/cpukit/zlib/gzio.c
@@ -5,7 +5,7 @@
* Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
*/
-/* @(#) $Id$ */
+/* $Id$ */
#include <stdio.h>
diff --git a/cpukit/zlib/inftrees.c b/cpukit/zlib/inftrees.c
index 72c5b75973..e5a934980f 100644
--- a/cpukit/zlib/inftrees.c
+++ b/cpukit/zlib/inftrees.c
@@ -134,7 +134,7 @@ unsigned short FAR *work;
left -= count[len];
if (left < 0) return -1; /* over-subscribed */
}
- if (left > 0 && (type == CODES || (codes - count[0] != 1)))
+ if (left > 0 && (type == CODES || max != 1))
return -1; /* incomplete set */
/* generate offsets into symbol table for each length for sorting */
diff --git a/cpukit/zlib/inftrees.h b/cpukit/zlib/inftrees.h
index 82d365a7e9..424af17356 100644
--- a/cpukit/zlib/inftrees.h
+++ b/cpukit/zlib/inftrees.h
@@ -36,12 +36,12 @@ typedef struct {
*/
/* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1004 code structures (850 for length/literals
- and 154 for distances, the latter actually the result of an
+ exhaustive search was 1444 code structures (852 for length/literals
+ and 592 for distances, the latter actually the result of an
exhaustive search). The true maximum is not known, but the value
below is more than safe. */
-#define ENOUGH 1440
-#define MAXD 154
+#define ENOUGH 2048
+#define MAXD 592
/* Type of code to build for inftable() */
typedef enum {
diff --git a/cpukit/zlib/make_vms.com b/cpukit/zlib/make_vms.com
deleted file mode 100644
index e6587cdfc1..0000000000
--- a/cpukit/zlib/make_vms.com
+++ /dev/null
@@ -1,114 +0,0 @@
-$! make libz under VMS
-$! written by Martin P.J. Zinser <m.zinser@gsi.de>
-$!
-$! Look for the compiler used
-$!
-$ ccopt = ""
-$ if f$getsyi("HW_MODEL").ge.1024
-$ then
-$ ccopt = "/prefix=all"+ccopt
-$ comp = "__decc__=1"
-$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
-$ else
-$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs.""
-$ then
-$ comp = "__vaxc__=1"
-$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
-$ else
-$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include:
-$ ccopt = "/decc/prefix=all"+ccopt
-$ comp = "__decc__=1"
-$ endif
-$ endif
-$!
-$! Build the thing plain or with mms
-$!
-$ write sys$output "Compiling Zlib sources ..."
-$ if f$search("SYS$SYSTEM:MMS.EXE").eqs.""
-$ then
-$ dele example.obj;*,minigzip.obj;*
-$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
- adler32.c zlib.h zconf.h
-$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
- compress.c zlib.h zconf.h
-$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
- crc32.c crc32.h zlib.h zconf.h zutil.h
-$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
- deflate.c deflate.h zutil.h zlib.h zconf.h
-$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio /define=""NO_vsnprintf""" -
- gzio.c zutil.h zlib.h zconf.h
-$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
- infback.c zutil.h zlib.h zconf.h -
- "inftrees.h inflate.h inffast.h inffixed.h"
-$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
- inffast.c zutil.h zlib.h zconf.h -
- "inftrees.h inflate.h inffast.h"
-$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
- inflate.c zutil.h zlib.h zconf.h -
- "inftrees.h inflate.h inffast.h inffixed.h"
-$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
- inftrees.c zutil.h zlib.h zconf.h inftrees.h
-$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
- trees.c trees.h deflate.h zutil.h zlib.h zconf.h
-$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
- uncompr.c zlib.h zconf.h
-$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
- zutil.c zutil.h zlib.h zconf.h
-$ write sys$output "Building Zlib ..."
-$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
-$ write sys$output "Building example..."
-$ CALL MAKE example.OBJ "CC ''CCOPT' example" -
- example.c zlib.h zconf.h
-$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
-$ write sys$output "Building minigzip..."
-$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" -
- minigzip.c zlib.h zconf.h
-$ call make minigzip.exe -
- "LINK minigzip,libz.olb/lib" -
- minigzip.obj libz.olb
-$ else
-$ mms/macro=('comp')
-$ endif
-$ write sys$output "Zlib build completed"
-$ exit
-$!
-$!
-$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES
-$ V = 'F$Verify(0)
-$! P1 = What we are trying to make
-$! P2 = Command to make it
-$! P3 - P8 What it depends on
-$
-$ If F$Search(P1) .Eqs. "" Then Goto Makeit
-$ Time = F$CvTime(F$File(P1,"RDT"))
-$arg=3
-$Loop:
-$ Argument = P'arg
-$ If Argument .Eqs. "" Then Goto Exit
-$ El=0
-$Loop2:
-$ File = F$Element(El," ",Argument)
-$ If File .Eqs. " " Then Goto Endl
-$ AFile = ""
-$Loop3:
-$ OFile = AFile
-$ AFile = F$Search(File)
-$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
-$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
-$ Goto Loop3
-$NextEL:
-$ El = El + 1
-$ Goto Loop2
-$EndL:
-$ arg=arg+1
-$ If arg .Le. 8 Then Goto Loop
-$ Goto Exit
-$
-$Makeit:
-$ VV=F$VERIFY(0)
-$ write sys$output P2
-$ 'P2
-$ VV='F$Verify(VV)
-$Exit:
-$ If V Then Set Verify
-$ENDSUBROUTINE
diff --git a/cpukit/zlib/minigzip.c b/cpukit/zlib/minigzip.c
deleted file mode 100644
index 4ba5e50e46..0000000000
--- a/cpukit/zlib/minigzip.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/* minigzip.c -- simulate gzip using the zlib compression library
- * Copyright (C) 1995-2004 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * minigzip is a minimal implementation of the gzip utility. This is
- * only an example of using zlib and isn't meant to replace the
- * full-featured gzip. No attempt is made to deal with file systems
- * limiting names to 14 or 8+3 characters, etc... Error checking is
- * very limited. So use minigzip only for testing; use gzip for the
- * real thing. On MSDOS, use only on file names without extension
- * or in pipe mode.
- */
-
-/* @(#) $Id$ */
-
-#include <stdio.h>
-#include "zlib.h"
-
-#ifdef STDC
-# include <string.h>
-# include <stdlib.h>
-#endif
-
-#ifdef USE_MMAP
-# include <sys/types.h>
-# include <sys/mman.h>
-# include <sys/stat.h>
-#endif
-
-#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
-# include <fcntl.h>
-# include <io.h>
-# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
-#else
-# define SET_BINARY_MODE(file)
-#endif
-
-#ifdef VMS
-# define unlink delete
-# define GZ_SUFFIX "-gz"
-#endif
-#ifdef RISCOS
-# define unlink remove
-# define GZ_SUFFIX "-gz"
-# define fileno(file) file->__file
-#endif
-#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fileno */
-#endif
-
-#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
- extern int unlink OF((const char *));
-#endif
-
-#ifndef GZ_SUFFIX
-# define GZ_SUFFIX ".gz"
-#endif
-#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
-
-#define BUFLEN 16384
-#define MAX_NAME_LEN 1024
-
-#ifdef MAXSEG_64K
-# define local static
- /* Needed for systems with limitation on stack size. */
-#else
-# define local
-#endif
-
-char *prog;
-
-void error OF((const char *msg));
-void gz_compress OF((FILE *in, gzFile out));
-#ifdef USE_MMAP
-int gz_compress_mmap OF((FILE *in, gzFile out));
-#endif
-void gz_uncompress OF((gzFile in, FILE *out));
-void file_compress OF((char *file, char *mode));
-void file_uncompress OF((char *file));
-int main OF((int argc, char *argv[]));
-
-/* ===========================================================================
- * Display error message and exit
- */
-void error(msg)
- const char *msg;
-{
- fprintf(stderr, "%s: %s\n", prog, msg);
- exit(1);
-}
-
-/* ===========================================================================
- * Compress input to output then close both files.
- */
-
-void gz_compress(in, out)
- FILE *in;
- gzFile out;
-{
- local char buf[BUFLEN];
- int len;
- int err;
-
-#ifdef USE_MMAP
- /* Try first compressing with mmap. If mmap fails (minigzip used in a
- * pipe), use the normal fread loop.
- */
- if (gz_compress_mmap(in, out) == Z_OK) return;
-#endif
- for (;;) {
- len = (int)fread(buf, 1, sizeof(buf), in);
- if (ferror(in)) {
- perror("fread");
- exit(1);
- }
- if (len == 0) break;
-
- if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
- }
- fclose(in);
- if (gzclose(out) != Z_OK) error("failed gzclose");
-}
-
-#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
-
-/* Try compressing the input file at once using mmap. Return Z_OK if
- * if success, Z_ERRNO otherwise.
- */
-int gz_compress_mmap(in, out)
- FILE *in;
- gzFile out;
-{
- int len;
- int err;
- int ifd = fileno(in);
- caddr_t buf; /* mmap'ed buffer for the entire input file */
- off_t buf_len; /* length of the input file */
- struct stat sb;
-
- /* Determine the size of the file, needed for mmap: */
- if (fstat(ifd, &sb) < 0) return Z_ERRNO;
- buf_len = sb.st_size;
- if (buf_len <= 0) return Z_ERRNO;
-
- /* Now do the actual mmap: */
- buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
- if (buf == (caddr_t)(-1)) return Z_ERRNO;
-
- /* Compress the whole file at once: */
- len = gzwrite(out, (char *)buf, (unsigned)buf_len);
-
- if (len != (int)buf_len) error(gzerror(out, &err));
-
- munmap(buf, buf_len);
- fclose(in);
- if (gzclose(out) != Z_OK) error("failed gzclose");
- return Z_OK;
-}
-#endif /* USE_MMAP */
-
-/* ===========================================================================
- * Uncompress input to output then close both files.
- */
-void gz_uncompress(in, out)
- gzFile in;
- FILE *out;
-{
- local char buf[BUFLEN];
- int len;
- int err;
-
- for (;;) {
- len = gzread(in, buf, sizeof(buf));
- if (len < 0) error (gzerror(in, &err));
- if (len == 0) break;
-
- if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
- error("failed fwrite");
- }
- }
- if (fclose(out)) error("failed fclose");
-
- if (gzclose(in) != Z_OK) error("failed gzclose");
-}
-
-
-/* ===========================================================================
- * Compress the given file: create a corresponding .gz file and remove the
- * original.
- */
-void file_compress(file, mode)
- char *file;
- char *mode;
-{
- local char outfile[MAX_NAME_LEN];
- FILE *in;
- gzFile out;
-
- strcpy(outfile, file);
- strcat(outfile, GZ_SUFFIX);
-
- in = fopen(file, "rb");
- if (in == NULL) {
- perror(file);
- exit(1);
- }
- out = gzopen(outfile, mode);
- if (out == NULL) {
- fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
- exit(1);
- }
- gz_compress(in, out);
-
- unlink(file);
-}
-
-
-/* ===========================================================================
- * Uncompress the given file and remove the original.
- */
-void file_uncompress(file)
- char *file;
-{
- local char buf[MAX_NAME_LEN];
- char *infile, *outfile;
- FILE *out;
- gzFile in;
- uInt len = (uInt)strlen(file);
-
- strcpy(buf, file);
-
- if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
- infile = file;
- outfile = buf;
- outfile[len-3] = '\0';
- } else {
- outfile = file;
- infile = buf;
- strcat(infile, GZ_SUFFIX);
- }
- in = gzopen(infile, "rb");
- if (in == NULL) {
- fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
- exit(1);
- }
- out = fopen(outfile, "wb");
- if (out == NULL) {
- perror(file);
- exit(1);
- }
-
- gz_uncompress(in, out);
-
- unlink(infile);
-}
-
-
-/* ===========================================================================
- * Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...]
- * -d : decompress
- * -f : compress with Z_FILTERED
- * -h : compress with Z_HUFFMAN_ONLY
- * -r : compress with Z_RLE
- * -1 to -9 : compression level
- */
-
-int main(argc, argv)
- int argc;
- char *argv[];
-{
- int uncompr = 0;
- gzFile file;
- char outmode[20];
-
- strcpy(outmode, "wb6 ");
-
- prog = argv[0];
- argc--, argv++;
-
- while (argc > 0) {
- if (strcmp(*argv, "-d") == 0)
- uncompr = 1;
- else if (strcmp(*argv, "-f") == 0)
- outmode[3] = 'f';
- else if (strcmp(*argv, "-h") == 0)
- outmode[3] = 'h';
- else if (strcmp(*argv, "-r") == 0)
- outmode[3] = 'R';
- else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
- (*argv)[2] == 0)
- outmode[2] = (*argv)[1];
- else
- break;
- argc--, argv++;
- }
- if (argc == 0) {
- SET_BINARY_MODE(stdin);
- SET_BINARY_MODE(stdout);
- if (uncompr) {
- file = gzdopen(fileno(stdin), "rb");
- if (file == NULL) error("can't gzdopen stdin");
- gz_uncompress(file, stdout);
- } else {
- file = gzdopen(fileno(stdout), outmode);
- if (file == NULL) error("can't gzdopen stdout");
- gz_compress(stdin, file);
- }
- } else {
- do {
- if (uncompr) {
- file_uncompress(*argv);
- } else {
- file_compress(*argv, outmode);
- }
- } while (argv++, --argc);
- }
- return 0;
-}
diff --git a/cpukit/zlib/msdos/Makefile.bor b/cpukit/zlib/msdos/Makefile.bor
deleted file mode 100644
index 8f8132d122..0000000000
--- a/cpukit/zlib/msdos/Makefile.bor
+++ /dev/null
@@ -1,109 +0,0 @@
-# Makefile for zlib
-# Borland C++
-# Last updated: 15-Mar-2003
-
-# To use, do "make -fmakefile.bor"
-# To compile in small model, set below: MODEL=s
-
-# WARNING: the small model is supported but only for small values of
-# MAX_WBITS and MAX_MEM_LEVEL. For example:
-# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3
-# If you wish to reduce the memory requirements (default 256K for big
-# objects plus a few K), you can add to the LOC macro below:
-# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
-# See zconf.h for details about the memory requirements.
-
-# ------------ Turbo C++, Borland C++ ------------
-
-# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
-# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
-# to the declaration of LOC here:
-LOC = $(LOCAL_ZLIB)
-
-# type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
-CPU_TYP = 0
-
-# memory model: one of s, m, c, l (small, medium, compact, large)
-MODEL=l
-
-# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version
-CC=bcc
-LD=bcc
-AR=tlib
-
-# compiler flags
-# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0
-CFLAGS=-O2 -Z -m$(MODEL) $(LOC)
-
-LDFLAGS=-m$(MODEL) -f-
-
-
-# variables
-ZLIB_LIB = zlib_$(MODEL).lib
-
-OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
-OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
-OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infback.obj
-OBJP2 = +inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
-
-
-# targets
-all: $(ZLIB_LIB) example.exe minigzip.exe
-
-.c.obj:
- $(CC) -c $(CFLAGS) $*.c
-
-adler32.obj: adler32.c zlib.h zconf.h
-
-compress.obj: compress.c zlib.h zconf.h
-
-crc32.obj: crc32.c zlib.h zconf.h crc32.h
-
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
-
-gzio.obj: gzio.c zutil.h zlib.h zconf.h
-
-infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h
-
-inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
-
-trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
-
-uncompr.obj: uncompr.c zlib.h zconf.h
-
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
-
-example.obj: example.c zlib.h zconf.h
-
-minigzip.obj: minigzip.c zlib.h zconf.h
-
-
-# the command line is cut to fit in the MS-DOS 128 byte limit:
-$(ZLIB_LIB): $(OBJ1) $(OBJ2)
- -del $(ZLIB_LIB)
- $(AR) $(ZLIB_LIB) $(OBJP1)
- $(AR) $(ZLIB_LIB) $(OBJP2)
-
-example.exe: example.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
-
-minigzip.exe: minigzip.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
-
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-clean:
- -del *.obj
- -del *.lib
- -del *.exe
- -del zlib_*.bak
- -del foo.gz
diff --git a/cpukit/zlib/msdos/Makefile.dj2 b/cpukit/zlib/msdos/Makefile.dj2
deleted file mode 100644
index 283d1d9616..0000000000
--- a/cpukit/zlib/msdos/Makefile.dj2
+++ /dev/null
@@ -1,104 +0,0 @@
-# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96.
-# Copyright (C) 1995-1998 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile, or to compile and test, type:
-#
-# make -fmakefile.dj2; make test -fmakefile.dj2
-#
-# To install libz.a, zconf.h and zlib.h in the djgpp directories, type:
-#
-# make install -fmakefile.dj2
-#
-# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as
-# in the sample below if the pattern of the DJGPP distribution is to
-# be followed. Remember that, while <sp>'es around <=> are ignored in
-# makefiles, they are *not* in batch files or in djgpp.env.
-# - - - - -
-# [make]
-# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include
-# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib
-# BUTT=-m486
-# - - - - -
-# Alternately, these variables may be defined below, overriding the values
-# in djgpp.env, as
-# INCLUDE_PATH=c:\usr\include
-# LIBRARY_PATH=c:\usr\lib
-
-CC=gcc
-
-#CFLAGS=-MMD -O
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-MMD -g -DDEBUG
-CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
- -Wstrict-prototypes -Wmissing-prototypes
-
-# If cp.exe is available, replace "copy /Y" with "cp -fp" .
-CP=copy /Y
-# If gnu install.exe is available, replace $(CP) with ginstall.
-INSTALL=$(CP)
-# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
-RM=del
-LDLIBS=-L. -lz
-LD=$(CC) -s -o
-LDSHARED=$(CC)
-
-INCL=zlib.h zconf.h
-LIBS=libz.a
-
-AR=ar rcs
-
-prefix=/usr/local
-exec_prefix = $(prefix)
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infback.o inftrees.o inffast.o
-
-OBJA =
-# to use the asm code: make OBJA=match.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example.exe minigzip.exe
-
-check: test
-test: all
- ./example
- echo hello world | .\minigzip | .\minigzip -d
-
-%.o : %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-libz.a: $(OBJS) $(OBJA)
- $(AR) $@ $(OBJS) $(OBJA)
-
-%.exe : %.o $(LIBS)
- $(LD) $@ $< $(LDLIBS)
-
-# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env .
-
-.PHONY : uninstall clean
-
-install: $(INCL) $(LIBS)
- -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH)
- -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH)
- $(INSTALL) zlib.h $(INCLUDE_PATH)
- $(INSTALL) zconf.h $(INCLUDE_PATH)
- $(INSTALL) libz.a $(LIBRARY_PATH)
-
-uninstall:
- $(RM) $(INCLUDE_PATH)\zlib.h
- $(RM) $(INCLUDE_PATH)\zconf.h
- $(RM) $(LIBRARY_PATH)\libz.a
-
-clean:
- $(RM) *.d
- $(RM) *.o
- $(RM) *.exe
- $(RM) libz.a
- $(RM) foo.gz
-
-DEPS := $(wildcard *.d)
-ifneq ($(DEPS),)
-include $(DEPS)
-endif
diff --git a/cpukit/zlib/msdos/Makefile.emx b/cpukit/zlib/msdos/Makefile.emx
deleted file mode 100644
index ed4c31fbbd..0000000000
--- a/cpukit/zlib/msdos/Makefile.emx
+++ /dev/null
@@ -1,69 +0,0 @@
-# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98.
-# Copyright (C) 1995-1998 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile, or to compile and test, type:
-#
-# make -fmakefile.emx; make test -fmakefile.emx
-#
-
-CC=gcc
-
-#CFLAGS=-MMD -O
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-MMD -g -DDEBUG
-CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
- -Wstrict-prototypes -Wmissing-prototypes
-
-# If cp.exe is available, replace "copy /Y" with "cp -fp" .
-CP=copy /Y
-# If gnu install.exe is available, replace $(CP) with ginstall.
-INSTALL=$(CP)
-# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
-RM=del
-LDLIBS=-L. -lzlib
-LD=$(CC) -s -o
-LDSHARED=$(CC)
-
-INCL=zlib.h zconf.h
-LIBS=zlib.a
-
-AR=ar rcs
-
-prefix=/usr/local
-exec_prefix = $(prefix)
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infback.o inftrees.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example.exe minigzip.exe
-
-test: all
- ./example
- echo hello world | .\minigzip | .\minigzip -d
-
-%.o : %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-zlib.a: $(OBJS)
- $(AR) $@ $(OBJS)
-
-%.exe : %.o $(LIBS)
- $(LD) $@ $< $(LDLIBS)
-
-
-.PHONY : clean
-
-clean:
- $(RM) *.d
- $(RM) *.o
- $(RM) *.exe
- $(RM) zlib.a
- $(RM) foo.gz
-
-DEPS := $(wildcard *.d)
-ifneq ($(DEPS),)
-include $(DEPS)
-endif
diff --git a/cpukit/zlib/msdos/Makefile.msc b/cpukit/zlib/msdos/Makefile.msc
deleted file mode 100644
index b8fc665efb..0000000000
--- a/cpukit/zlib/msdos/Makefile.msc
+++ /dev/null
@@ -1,106 +0,0 @@
-# Makefile for zlib
-# Microsoft C 5.1 or later
-# Last updated: 19-Mar-2003
-
-# To use, do "make makefile.msc"
-# To compile in small model, set below: MODEL=S
-
-# If you wish to reduce the memory requirements (default 256K for big
-# objects plus a few K), you can add to the LOC macro below:
-# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
-# See zconf.h for details about the memory requirements.
-
-# ------------- Microsoft C 5.1 and later -------------
-
-# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
-# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
-# to the declaration of LOC here:
-LOC = $(LOCAL_ZLIB)
-
-# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
-CPU_TYP = 0
-
-# Memory model: one of S, M, C, L (small, medium, compact, large)
-MODEL=L
-
-CC=cl
-CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC)
-#-Ox generates bad code with MSC 5.1
-LIB_CFLAGS=-Zl $(CFLAGS)
-
-LD=link
-LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode
-# "/farcall/packcode" are only useful for `large code' memory models
-# but should be a "no-op" for small code models.
-
-
-# variables
-ZLIB_LIB = zlib_$(MODEL).lib
-
-OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
-OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
-
-
-# targets
-all: $(ZLIB_LIB) example.exe minigzip.exe
-
-.c.obj:
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-adler32.obj: adler32.c zlib.h zconf.h
-
-compress.obj: compress.c zlib.h zconf.h
-
-crc32.obj: crc32.c zlib.h zconf.h crc32.h
-
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
-
-gzio.obj: gzio.c zutil.h zlib.h zconf.h
-
-infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h
-
-inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
-
-trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
-
-uncompr.obj: uncompr.c zlib.h zconf.h
-
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
-
-example.obj: example.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-minigzip.obj: minigzip.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-
-# the command line is cut to fit in the MS-DOS 128 byte limit:
-$(ZLIB_LIB): $(OBJ1) $(OBJ2)
- if exist $(ZLIB_LIB) del $(ZLIB_LIB)
- lib $(ZLIB_LIB) $(OBJ1);
- lib $(ZLIB_LIB) $(OBJ2);
-
-example.exe: example.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB);
-
-minigzip.exe: minigzip.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB);
-
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-clean:
- -del *.obj
- -del *.lib
- -del *.exe
- -del *.map
- -del zlib_*.bak
- -del foo.gz
diff --git a/cpukit/zlib/msdos/Makefile.tc b/cpukit/zlib/msdos/Makefile.tc
deleted file mode 100644
index 480750ade2..0000000000
--- a/cpukit/zlib/msdos/Makefile.tc
+++ /dev/null
@@ -1,94 +0,0 @@
-# Makefile for zlib
-# Turbo C 2.01, Turbo C++ 1.01
-# Last updated: 15-Mar-2003
-
-# To use, do "make -fmakefile.tc"
-# To compile in small model, set below: MODEL=s
-
-# WARNING: the small model is supported but only for small values of
-# MAX_WBITS and MAX_MEM_LEVEL. For example:
-# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
-# If you wish to reduce the memory requirements (default 256K for big
-# objects plus a few K), you can add to CFLAGS below:
-# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
-# See zconf.h for details about the memory requirements.
-
-# ------------ Turbo C 2.01, Turbo C++ 1.01 ------------
-MODEL=l
-CC=tcc
-LD=tcc
-AR=tlib
-# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
-CFLAGS=-O2 -G -Z -m$(MODEL)
-LDFLAGS=-m$(MODEL) -f-
-
-
-# variables
-ZLIB_LIB = zlib_$(MODEL).lib
-
-OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
-OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
-OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infback.obj
-OBJP2 = +inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
-
-
-# targets
-all: $(ZLIB_LIB) example.exe minigzip.exe
-
-.c.obj:
- $(CC) -c $(CFLAGS) $*.c
-
-adler32.obj: adler32.c zlib.h zconf.h
-
-compress.obj: compress.c zlib.h zconf.h
-
-crc32.obj: crc32.c zlib.h zconf.h crc32.h
-
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
-
-gzio.obj: gzio.c zutil.h zlib.h zconf.h
-
-infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h
-
-inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
-
-trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
-
-uncompr.obj: uncompr.c zlib.h zconf.h
-
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
-
-example.obj: example.c zlib.h zconf.h
-
-minigzip.obj: minigzip.c zlib.h zconf.h
-
-
-# the command line is cut to fit in the MS-DOS 128 byte limit:
-$(ZLIB_LIB): $(OBJ1) $(OBJ2)
- -del $(ZLIB_LIB)
- $(AR) $(ZLIB_LIB) $(OBJP1)
- $(AR) $(ZLIB_LIB) $(OBJP2)
-
-example.exe: example.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
-
-minigzip.exe: minigzip.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
-
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-clean:
- -del *.obj
- -del *.lib
- -del *.exe
- -del zlib_*.bak
- -del foo.gz
diff --git a/cpukit/zlib/old/Makefile.riscos b/cpukit/zlib/old/Makefile.riscos
deleted file mode 100644
index d97f449237..0000000000
--- a/cpukit/zlib/old/Makefile.riscos
+++ /dev/null
@@ -1,151 +0,0 @@
-# Project: zlib_1_03
-# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430
-# test works out-of-the-box, installs `somewhere' on demand
-
-# Toolflags:
-CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah
-C++flags = -c -depend !Depend -IC: -throwback
-Linkflags = -aif -c++ -o $@
-ObjAsmflags = -throwback -NoCache -depend !Depend
-CMHGflags =
-LibFileflags = -c -l -o $@
-Squeezeflags = -o $@
-
-# change the line below to where _you_ want the library installed.
-libdest = lib:zlib
-
-# Final targets:
-@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \
- @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \
- @.o.uncompr @.o.zutil
- LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \
- @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \
- @.o.trees @.o.uncompr @.o.zutil
-test: @.minigzip @.example @.lib
- @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV
- @echo running tests: hang on.
- @/@.minigzip -f -9 libc
- @/@.minigzip -d libc-gz
- @/@.minigzip -f -1 libc
- @/@.minigzip -d libc-gz
- @/@.minigzip -h -9 libc
- @/@.minigzip -d libc-gz
- @/@.minigzip -h -1 libc
- @/@.minigzip -d libc-gz
- @/@.minigzip -9 libc
- @/@.minigzip -d libc-gz
- @/@.minigzip -1 libc
- @/@.minigzip -d libc-gz
- @diff @.lib @.libc
- @echo that should have reported '@.lib and @.libc identical' if you have diff.
- @/@.example @.fred @.fred
- @echo that will have given lots of hello!'s.
-
-@.minigzip: @.o.minigzip @.lib C:o.Stubs
- Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs
-@.example: @.o.example @.lib C:o.Stubs
- Link $(Linkflags) @.o.example @.lib C:o.Stubs
-
-install: @.lib
- cdir $(libdest)
- cdir $(libdest).h
- @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV
- @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV
- @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV
- @echo okay, installed zlib in $(libdest)
-
-clean:; remove @.minigzip
- remove @.example
- remove @.libc
- -wipe @.o.* F~r~cV
- remove @.fred
-
-# User-editable dependencies:
-.c.o:
- cc $(ccflags) -o $@ $<
-
-# Static dependencies:
-
-# Dynamic dependencies:
-o.example: c.example
-o.example: h.zlib
-o.example: h.zconf
-o.minigzip: c.minigzip
-o.minigzip: h.zlib
-o.minigzip: h.zconf
-o.adler32: c.adler32
-o.adler32: h.zlib
-o.adler32: h.zconf
-o.compress: c.compress
-o.compress: h.zlib
-o.compress: h.zconf
-o.crc32: c.crc32
-o.crc32: h.zlib
-o.crc32: h.zconf
-o.deflate: c.deflate
-o.deflate: h.deflate
-o.deflate: h.zutil
-o.deflate: h.zlib
-o.deflate: h.zconf
-o.gzio: c.gzio
-o.gzio: h.zutil
-o.gzio: h.zlib
-o.gzio: h.zconf
-o.infblock: c.infblock
-o.infblock: h.zutil
-o.infblock: h.zlib
-o.infblock: h.zconf
-o.infblock: h.infblock
-o.infblock: h.inftrees
-o.infblock: h.infcodes
-o.infblock: h.infutil
-o.infcodes: c.infcodes
-o.infcodes: h.zutil
-o.infcodes: h.zlib
-o.infcodes: h.zconf
-o.infcodes: h.inftrees
-o.infcodes: h.infblock
-o.infcodes: h.infcodes
-o.infcodes: h.infutil
-o.infcodes: h.inffast
-o.inffast: c.inffast
-o.inffast: h.zutil
-o.inffast: h.zlib
-o.inffast: h.zconf
-o.inffast: h.inftrees
-o.inffast: h.infblock
-o.inffast: h.infcodes
-o.inffast: h.infutil
-o.inffast: h.inffast
-o.inflate: c.inflate
-o.inflate: h.zutil
-o.inflate: h.zlib
-o.inflate: h.zconf
-o.inflate: h.infblock
-o.inftrees: c.inftrees
-o.inftrees: h.zutil
-o.inftrees: h.zlib
-o.inftrees: h.zconf
-o.inftrees: h.inftrees
-o.inftrees: h.inffixed
-o.infutil: c.infutil
-o.infutil: h.zutil
-o.infutil: h.zlib
-o.infutil: h.zconf
-o.infutil: h.infblock
-o.infutil: h.inftrees
-o.infutil: h.infcodes
-o.infutil: h.infutil
-o.trees: c.trees
-o.trees: h.deflate
-o.trees: h.zutil
-o.trees: h.zlib
-o.trees: h.zconf
-o.trees: h.trees
-o.uncompr: c.uncompr
-o.uncompr: h.zlib
-o.uncompr: h.zconf
-o.zutil: c.zutil
-o.zutil: h.zutil
-o.zutil: h.zlib
-o.zutil: h.zconf
diff --git a/cpukit/zlib/old/README b/cpukit/zlib/old/README
deleted file mode 100644
index 800bf07982..0000000000
--- a/cpukit/zlib/old/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This directory contains files that have not been updated for zlib 1.2.x
-
-(Volunteers are encouraged to help clean this up. Thanks.)
diff --git a/cpukit/zlib/old/descrip.mms b/cpukit/zlib/old/descrip.mms
deleted file mode 100644
index 7066da5b55..0000000000
--- a/cpukit/zlib/old/descrip.mms
+++ /dev/null
@@ -1,48 +0,0 @@
-# descrip.mms: MMS description file for building zlib on VMS
-# written by Martin P.J. Zinser <m.zinser@gsi.de>
-
-cc_defs =
-c_deb =
-
-.ifdef __DECC__
-pref = /prefix=all
-.endif
-
-OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\
- deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\
- inftrees.obj, infcodes.obj, infutil.obj, inffast.obj
-
-CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
-
-all : example.exe minigzip.exe
- @ write sys$output " Example applications available"
-libz.olb : libz.olb($(OBJS))
- @ write sys$output " libz available"
-
-example.exe : example.obj libz.olb
- link example,libz.olb/lib
-
-minigzip.exe : minigzip.obj libz.olb
- link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
-
-clean :
- delete *.obj;*,libz.olb;*
-
-
-# Other dependencies.
-adler32.obj : zutil.h zlib.h zconf.h
-compress.obj : zlib.h zconf.h
-crc32.obj : zutil.h zlib.h zconf.h
-deflate.obj : deflate.h zutil.h zlib.h zconf.h
-example.obj : zlib.h zconf.h
-gzio.obj : zutil.h zlib.h zconf.h
-infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
-infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
-inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
-inflate.obj : zutil.h zlib.h zconf.h infblock.h
-inftrees.obj : zutil.h zlib.h zconf.h inftrees.h
-infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h
-minigzip.obj : zlib.h zconf.h
-trees.obj : deflate.h zutil.h zlib.h zconf.h
-uncompr.obj : zlib.h zconf.h
-zutil.obj : zutil.h zlib.h zconf.h
diff --git a/cpukit/zlib/old/os2/Makefile.os2 b/cpukit/zlib/old/os2/Makefile.os2
deleted file mode 100644
index a105aaa5bb..0000000000
--- a/cpukit/zlib/old/os2/Makefile.os2
+++ /dev/null
@@ -1,136 +0,0 @@
-# Makefile for zlib under OS/2 using GCC (PGCC)
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile and test, type:
-# cp Makefile.os2 ..
-# cd ..
-# make -f Makefile.os2 test
-
-# This makefile will build a static library z.lib, a shared library
-# z.dll and a import library zdll.lib. You can use either z.lib or
-# zdll.lib by specifying either -lz or -lzdll on gcc's command line
-
-CC=gcc -Zomf -s
-
-CFLAGS=-O6 -Wall
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-g -DDEBUG
-#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
-# -Wstrict-prototypes -Wmissing-prototypes
-
-#################### BUG WARNING: #####################
-## infcodes.c hits a bug in pgcc-1.0, so you have to use either
-## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem)
-## This bug is reportedly fixed in pgcc >1.0, but this was not tested
-CFLAGS+=-fno-force-mem
-
-LDFLAGS=-s -L. -lzdll -Zcrtdll
-LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll
-
-VER=1.1.0
-ZLIB=z.lib
-SHAREDLIB=z.dll
-SHAREDLIBIMP=zdll.lib
-LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP)
-
-AR=emxomfar cr
-IMPLIB=emximp
-RANLIB=echo
-TAR=tar
-SHELL=bash
-
-prefix=/usr/local
-exec_prefix = $(prefix)
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \
- algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \
- nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \
- contrib/asm386/*.asm contrib/asm386/*.c \
- contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \
- contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \
- contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32
-
-all: example.exe minigzip.exe
-
-test: all
- @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
- echo hello world | ./minigzip | ./minigzip -d || \
- echo ' *** minigzip test FAILED ***' ; \
- if ./example; then \
- echo ' *** zlib test OK ***'; \
- else \
- echo ' *** zlib test FAILED ***'; \
- fi
-
-$(ZLIB): $(OBJS)
- $(AR) $@ $(OBJS)
- -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
-
-$(SHAREDLIB): $(OBJS) os2/z.def
- $(LDSHARED) -o $@ $^
-
-$(SHAREDLIBIMP): os2/z.def
- $(IMPLIB) -o $@ $^
-
-example.exe: example.o $(LIBS)
- $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
-
-minigzip.exe: minigzip.o $(LIBS)
- $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
-
-clean:
- rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
-
-distclean: clean
-
-zip:
- mv Makefile Makefile~; cp -p Makefile.in Makefile
- rm -f test.c ztest*.c
- v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
- zip -ul9 zlib$$v $(DISTFILES)
- mv Makefile~ Makefile
-
-dist:
- mv Makefile Makefile~; cp -p Makefile.in Makefile
- rm -f test.c ztest*.c
- d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
- rm -f $$d.tar.gz; \
- if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
- files=""; \
- for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
- cd ..; \
- GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
- if test ! -d $$d; then rm -f $$d; fi
- mv Makefile~ Makefile
-
-tags:
- etags *.[ch]
-
-depend:
- makedepend -- $(CFLAGS) -- *.[ch]
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-adler32.o: zlib.h zconf.h
-compress.o: zlib.h zconf.h
-crc32.o: zlib.h zconf.h
-deflate.o: deflate.h zutil.h zlib.h zconf.h
-example.o: zlib.h zconf.h
-gzio.o: zutil.h zlib.h zconf.h
-infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
-infcodes.o: zutil.h zlib.h zconf.h
-infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
-inffast.o: zutil.h zlib.h zconf.h inftrees.h
-inffast.o: infblock.h infcodes.h infutil.h inffast.h
-inflate.o: zutil.h zlib.h zconf.h infblock.h
-inftrees.o: zutil.h zlib.h zconf.h inftrees.h
-infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
-minigzip.o: zlib.h zconf.h
-trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
-uncompr.o: zlib.h zconf.h
-zutil.o: zutil.h zlib.h zconf.h
diff --git a/cpukit/zlib/old/os2/zlib.def b/cpukit/zlib/old/os2/zlib.def
deleted file mode 100644
index 4c753f1a3b..0000000000
--- a/cpukit/zlib/old/os2/zlib.def
+++ /dev/null
@@ -1,51 +0,0 @@
-;
-; Slightly modified version of ../nt/zlib.dnt :-)
-;
-
-LIBRARY Z
-DESCRIPTION "Zlib compression library for OS/2"
-CODE PRELOAD MOVEABLE DISCARDABLE
-DATA PRELOAD MOVEABLE MULTIPLE
-
-EXPORTS
- adler32
- compress
- crc32
- deflate
- deflateCopy
- deflateEnd
- deflateInit2_
- deflateInit_
- deflateParams
- deflateReset
- deflateSetDictionary
- gzclose
- gzdopen
- gzerror
- gzflush
- gzopen
- gzread
- gzwrite
- inflate
- inflateEnd
- inflateInit2_
- inflateInit_
- inflateReset
- inflateSetDictionary
- inflateSync
- uncompress
- zlibVersion
- gzprintf
- gzputc
- gzgetc
- gzseek
- gzrewind
- gztell
- gzeof
- gzsetparams
- zError
- inflateSyncPoint
- get_crc_table
- compress2
- gzputs
- gzgets
diff --git a/cpukit/zlib/old/visual-basic.txt b/cpukit/zlib/old/visual-basic.txt
deleted file mode 100644
index 57efe58124..0000000000
--- a/cpukit/zlib/old/visual-basic.txt
+++ /dev/null
@@ -1,160 +0,0 @@
-See below some functions declarations for Visual Basic.
-
-Frequently Asked Question:
-
-Q: Each time I use the compress function I get the -5 error (not enough
- room in the output buffer).
-
-A: Make sure that the length of the compressed buffer is passed by
- reference ("as any"), not by value ("as long"). Also check that
- before the call of compress this length is equal to the total size of
- the compressed buffer and not zero.
-
-
-From: "Jon Caruana" <jon-net@usa.net>
-Subject: Re: How to port zlib declares to vb?
-Date: Mon, 28 Oct 1996 18:33:03 -0600
-
-Got the answer! (I haven't had time to check this but it's what I got, and
-looks correct):
-
-He has the following routines working:
- compress
- uncompress
- gzopen
- gzwrite
- gzread
- gzclose
-
-Declares follow: (Quoted from Carlos Rios <c_rios@sonda.cl>, in Vb4 form)
-
-#If Win16 Then 'Use Win16 calls.
-Declare Function compress Lib "ZLIB.DLL" (ByVal compr As
- String, comprLen As Any, ByVal buf As String, ByVal buflen
- As Long) As Integer
-Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr
- As String, uncomprLen As Any, ByVal compr As String, ByVal
- lcompr As Long) As Integer
-Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As
- String, ByVal mode As String) As Long
-Declare Function gzread Lib "ZLIB.DLL" (ByVal file As
- Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
- As Integer
-Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As
- Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
- As Integer
-Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As
- Long) As Integer
-#Else
-Declare Function compress Lib "ZLIB32.DLL"
- (ByVal compr As String, comprLen As Any, ByVal buf As
- String, ByVal buflen As Long) As Integer
-Declare Function uncompress Lib "ZLIB32.DLL"
- (ByVal uncompr As String, uncomprLen As Any, ByVal compr As
- String, ByVal lcompr As Long) As Long
-Declare Function gzopen Lib "ZLIB32.DLL"
- (ByVal file As String, ByVal mode As String) As Long
-Declare Function gzread Lib "ZLIB32.DLL"
- (ByVal file As Long, ByVal uncompr As String, ByVal
- uncomprLen As Long) As Long
-Declare Function gzwrite Lib "ZLIB32.DLL"
- (ByVal file As Long, ByVal uncompr As String, ByVal
- uncomprLen As Long) As Long
-Declare Function gzclose Lib "ZLIB32.DLL"
- (ByVal file As Long) As Long
-#End If
-
--Jon Caruana
-jon-net@usa.net
-Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member
-
-
-Here is another example from Michael <michael_borgsys@hotmail.com> that he
-says conforms to the VB guidelines, and that solves the problem of not
-knowing the uncompressed size by storing it at the end of the file:
-
-'Calling the functions:
-'bracket meaning: <parameter> [optional] {Range of possible values}
-'Call subCompressFile(<path with filename to compress> [, <path with
-filename to write to>, [level of compression {1..9}]])
-'Call subUncompressFile(<path with filename to compress>)
-
-Option Explicit
-Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller'
-Private Const SUCCESS As Long = 0
-Private Const strFilExt As String = ".cpr"
-Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef
-dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long,
-ByVal level As Integer) As Long
-Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef
-dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long)
-As Long
-
-Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal
-strargCprFilPth As String, Optional ByVal intLvl As Integer = 9)
- Dim strCprPth As String
- Dim lngOriSiz As Long
- Dim lngCprSiz As Long
- Dim bytaryOri() As Byte
- Dim bytaryCpr() As Byte
- lngOriSiz = FileLen(strargOriFilPth)
- ReDim bytaryOri(lngOriSiz - 1)
- Open strargOriFilPth For Binary Access Read As #1
- Get #1, , bytaryOri()
- Close #1
- strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth)
-'Select file path and name
- strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) =
-strFilExt, "", strFilExt) 'Add file extension if not exists
- lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit
-more space then original file size
- ReDim bytaryCpr(lngCprSiz - 1)
- If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) =
-SUCCESS Then
- lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100
- ReDim Preserve bytaryCpr(lngCprSiz - 1)
- Open strCprPth For Binary Access Write As #1
- Put #1, , bytaryCpr()
- Put #1, , lngOriSiz 'Add the the original size value to the end
-(last 4 bytes)
- Close #1
- Else
- MsgBox "Compression error"
- End If
- Erase bytaryCpr
- Erase bytaryOri
-End Sub
-
-Public Sub subUncompressFile(ByVal strargFilPth As String)
- Dim bytaryCpr() As Byte
- Dim bytaryOri() As Byte
- Dim lngOriSiz As Long
- Dim lngCprSiz As Long
- Dim strOriPth As String
- lngCprSiz = FileLen(strargFilPth)
- ReDim bytaryCpr(lngCprSiz - 1)
- Open strargFilPth For Binary Access Read As #1
- Get #1, , bytaryCpr()
- Close #1
- 'Read the original file size value:
- lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _
- + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _
- + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _
- + bytaryCpr(lngCprSiz - 4)
- ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value
- ReDim bytaryOri(lngOriSiz - 1)
- If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS
-Then
- strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt))
- Open strOriPth For Binary Access Write As #1
- Put #1, , bytaryOri()
- Close #1
- Else
- MsgBox "Uncompression error"
- End If
- Erase bytaryCpr
- Erase bytaryOri
-End Sub
-Public Property Get lngPercentSmaller() As Long
- lngPercentSmaller = lngpvtPcnSml
-End Property
diff --git a/cpukit/zlib/old/zlib.html b/cpukit/zlib/old/zlib.html
deleted file mode 100644
index 8c1b190c38..0000000000
--- a/cpukit/zlib/old/zlib.html
+++ /dev/null
@@ -1,971 +0,0 @@
-<html>
-<head>
- <title>
- zlib general purpose compression library version 1.1.4
- </title>
-</head>
-<body bgcolor="White" text="Black" vlink="Red" alink="Navy" link="Red">
-<!-- background="zlibbg.gif" -->
-
-<h1> zlib 1.1.4 Manual </h1>
-<hr>
-<a name="Contents"><h2>Contents</h2>
-<ol type="I">
-<li> <a href="#Prologue">Prologue</a>
-<li> <a href="#Introduction">Introduction</a>
-<li> <a href="#Utility functions">Utility functions</a>
-<li> <a href="#Basic functions">Basic functions</a>
-<li> <a href="#Advanced functions">Advanced functions</a>
-<li> <a href="#Constants">Constants</a>
-<li> <a href="#struct z_stream_s">struct z_stream_s</a>
-<li> <a href="#Checksum functions">Checksum functions</a>
-<li> <a href="#Misc">Misc</a>
-</ol>
-<hr>
-<a name="Prologue"><h2> Prologue </h2>
- 'zlib' general purpose compression library version 1.1.4, March 11th, 2002
- <p>
- Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
- <p>
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- <p>
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- <ol>
- <li> The origin of this software must not be misrepresented ; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- <li> Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- <li> This notice may not be removed or altered from any source distribution.
- </ol>
-
- <dl>
- <dt>Jean-loup Gailly
- <dd><a href="mailto:jloup@gzip.org">jloup@gzip.org</a>
- <dt>Mark Adler
- <dd><a href="mailto:madler@alumni.caltech.edu">madler@alumni.caltech.edu</a>
- </dl>
-
- The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files
- <a href="ftp://ds.internic.net/rfc/rfc1950.txt">
- ftp://ds.internic.net/rfc/rfc1950.txt </a>
- (zlib format),
- <a href="ftp://ds.internic.net/rfc/rfc1951.txt">
- rfc1951.txt </a>
- (<a href="#deflate">deflate</a> format) and
- <a href="ftp://ds.internic.net/rfc/rfc1952.txt">
- rfc1952.txt </a>
- (gzip format).
- <p>
- This manual is converted from zlib.h by
- <a href="mailto:piaip@csie.ntu.edu.tw"> piaip </a>
- <p>
- Visit <a href="http://ftp.cdrom.com/pub/infozip/zlib/">
- http://ftp.cdrom.com/pub/infozip/zlib/</a>
- for the official zlib web page.
- <p>
-
-<hr>
-<a name="Introduction"><h2> Introduction </h2>
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms will be added later and will have the same
- stream interface.
- <p>
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
- <p>
-
- The library also supports reading and writing files in gzip (.gz) format
- with an interface similar to that of stdio.
- <p>
-
- The library does not install any signal handler. The decoder checks
- the consistency of the compressed data, so the library should never
- crash even in case of corrupted input.
- <p>
-
-<hr>
-<a name="Utility functions"><h2> Utility functions </h2>
- The following utility functions are implemented on top of the
- <a href="#Basic functions">basic stream-oriented functions</a>.
- To simplify the interface, some
- default options are assumed (compression level and memory usage,
- standard memory allocation functions). The source code of these
- utility functions can easily be modified if you need special options.
-<h3> Function list </h3>
-<ul>
-<li> int <a href="#compress">compress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
-<li> int <a href="#compress2">compress2</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level);
-<li> int <a href="#uncompress">uncompress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
-<li> typedef voidp gzFile;
-<li> gzFile <a href="#gzopen">gzopen</a> (const char *path, const char *mode);
-<li> gzFile <a href="#gzdopen">gzdopen</a> (int fd, const char *mode);
-<li> int <a href="#gzsetparams">gzsetparams</a> (gzFile file, int level, int strategy);
-<li> int <a href="#gzread">gzread</a> (gzFile file, voidp buf, unsigned len);
-<li> int <a href="#gzwrite">gzwrite</a> (gzFile file, const voidp buf, unsigned len);
-<li> int VA <a href="#gzprintf">gzprintf</a> (gzFile file, const char *format, ...);
-<li> int <a href="#gzputs">gzputs</a> (gzFile file, const char *s);
-<li> char * <a href="#gzgets">gzgets</a> (gzFile file, char *buf, int len);
-<li> int <a href="#gzputc">gzputc</a> (gzFile file, int c);
-<li> int <a href="#gzgetc">gzgetc</a> (gzFile file);
-<li> int <a href="#gzflush">gzflush</a> (gzFile file, int flush);
-<li> z_off_t <a href="#gzseek">gzseek</a> (gzFile file, z_off_t offset, int whence);
-<li> z_off_t <a href="#gztell">gztell</a> (gzFile file);
-<li> int <a href="#gzrewind">gzrewind</a> (gzFile file);
-<li> int <a href="#gzeof">gzeof</a> (gzFile file);
-<li> int <a href="#gzclose">gzclose</a> (gzFile file);
-<li> const char * <a href="#gzerror">gzerror</a> (gzFile file, int *errnum);
-</ul>
-<h3> Function description </h3>
-<dl>
-<font color="Blue"><dt> int <a name="compress">compress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);</font>
-<dd>
- Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least 0.1% larger than
- sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
- compressed buffer.<p>
- This function can be used to <a href="#compress">compress</a> a whole file at once if the
- input file is mmap'ed.<p>
- <a href="#compress">compress</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
- enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output
- buffer.<p>
-
-<font color="Blue"><dt> int <a name="compress2">compress2</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level);</font>
-<dd>
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in <a href="#deflateInit">deflateInit</a>. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
- <p>
-
- <a href="#compress2">compress2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
- memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output buffer,
- <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the level parameter is invalid.
- <p>
-
-<font color="Blue"><dt> int <a name="uncompress">uncompress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);</font>
-<dd>
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer. <p>
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
- <p>
-
- <a href="#uncompress">uncompress</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
- enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output
- buffer, or <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the input data was corrupted.
- <p>
-
-<dt> typedef voidp gzFile;
-<dd> <p>
-
-<font color="Blue"><dt> gzFile <a name="gzopen">gzopen</a> (const char *path, const char *mode);</font>
-<dd>
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb") but can also include a compression level
- ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
- Huffman only compression as in "wb1h". (See the description
- of <a href="#deflateInit2">deflateInit2</a> for more information about the strategy parameter.)
- <p>
-
- <a href="#gzopen">gzopen</a> can be used to read a file which is not in gzip format ; in this
- case <a href="#gzread">gzread</a> will directly read from the file without decompression.
- <p>
-
- <a href="#gzopen">gzopen</a> returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression <a href="#state">state</a> ; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a>).
- <p>
-
-<font color="Blue"><dt> gzFile <a name="gzdopen">gzdopen</a> (int fd, const char *mode);</font>
-<dd>
- <a href="#gzdopen">gzdopen</a>() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in <a href="#gzopen">gzopen</a>.
- <p>
- The next call of <a href="#gzclose">gzclose</a> on the returned gzFile will also close the
- file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
- descriptor fd. If you want to keep fd open, use <a href="#gzdopen">gzdopen</a>(dup(fd), mode).
- <p>
- <a href="#gzdopen">gzdopen</a> returns NULL if there was insufficient memory to allocate
- the (de)compression <a href="#state">state</a>.
- <p>
-
-<font color="Blue"><dt> int <a name="gzsetparams">gzsetparams</a> (gzFile file, int level, int strategy);</font>
-<dd>
- Dynamically update the compression level or strategy. See the description
- of <a href="#deflateInit2">deflateInit2</a> for the meaning of these parameters.
- <p>
- <a href="#gzsetparams">gzsetparams</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the file was not
- opened for writing.
- <p>
-
-<font color="Blue"><dt> int <a name="gzread">gzread</a> (gzFile file, voidp buf, unsigned len);</font>
-<dd>
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, <a href="#gzread">gzread</a> copies the given number
- of bytes into the buffer.
- <p>
- <a href="#gzread">gzread</a> returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error).
- <p>
-
-<font color="Blue"><dt> int <a name="gzwrite">gzwrite</a> (gzFile file, const voidp buf, unsigned len);</font>
-<dd>
- Writes the given number of uncompressed bytes into the compressed file.
- <a href="#gzwrite">gzwrite</a> returns the number of uncompressed bytes actually written
- (0 in case of error).
- <p>
-
-<font color="Blue"><dt> int VA <a name="gzprintf">gzprintf</a> (gzFile file, const char *format, ...);</font>
-<dd>
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. <a href="#gzprintf">gzprintf</a> returns the number of
- uncompressed bytes actually written (0 in case of error).
- <p>
-
-<font color="Blue"><dt> int <a name="gzputs">gzputs</a> (gzFile file, const char *s);</font>
-<dd>
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- <p>
- <a href="#gzputs">gzputs</a> returns the number of characters written, or -1 in case of error.
- <p>
-
-<font color="Blue"><dt> char * <a name="gzgets">gzgets</a> (gzFile file, char *buf, int len);</font>
-<dd>
- Reads bytes from the compressed file until len-1 characters are read, or
- a newline character is read and transferred to buf, or an end-of-file
- condition is encountered. The string is then terminated with a null
- character.
- <p>
- <a href="#gzgets">gzgets</a> returns buf, or <a href="#Z_NULL">Z_NULL</a> in case of error.
- <p>
-
-<font color="Blue"><dt> int <a name="gzputc">gzputc</a> (gzFile file, int c);</font>
-<dd>
- Writes c, converted to an unsigned char, into the compressed file.
- <a href="#gzputc">gzputc</a> returns the value that was written, or -1 in case of error.
- <p>
-
-<font color="Blue"><dt> int <a name="gzgetc">gzgetc</a> (gzFile file);</font>
-<dd>
- Reads one byte from the compressed file. <a href="#gzgetc">gzgetc</a> returns this byte
- or -1 in case of end of file or error.
- <p>
-
-<font color="Blue"><dt> int <a name="gzflush">gzflush</a> (gzFile file, int flush);</font>
-<dd>
- Flushes all pending output into the compressed file. The parameter
- flush is as in the <a href="#deflate">deflate</a>() function. The return value is the zlib
- error number (see function <a href="#gzerror">gzerror</a> below). <a href="#gzflush">gzflush</a> returns <a href="#Z_OK">Z_OK</a> if
- the flush parameter is <a href="#Z_FINISH">Z_FINISH</a> and all output could be flushed.
- <p>
- <a href="#gzflush">gzflush</a> should be called only when strictly necessary because it can
- degrade compression.
- <p>
-
-<font color="Blue"><dt> z_off_t <a name="gzseek">gzseek</a> (gzFile file, z_off_t offset, int whence);</font>
-<dd>
- Sets the starting position for the next <a href="#gzread">gzread</a> or <a href="#gzwrite">gzwrite</a> on the
- given compressed file. The offset represents a number of bytes in the
- uncompressed data stream. The whence parameter is defined as in lseek(2);
- the value SEEK_END is not supported.
- <p>
- If the file is opened for reading, this function is emulated but can be
- extremely slow. If the file is opened for writing, only forward seeks are
- supported ; <a href="#gzseek">gzseek</a> then compresses a sequence of zeroes up to the new
- starting position.
- <p>
- <a href="#gzseek">gzseek</a> returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error, in
- particular if the file is opened for writing and the new starting position
- would be before the current position.
- <p>
-
-<font color="Blue"><dt> int <a name="gzrewind">gzrewind</a> (gzFile file);</font>
-<dd>
- Rewinds the given file. This function is supported only for reading.
- <p>
- <a href="#gzrewind">gzrewind</a>(file) is equivalent to (int)<a href="#gzseek">gzseek</a>(file, 0L, SEEK_SET)
- <p>
-
-<font color="Blue"><dt> z_off_t <a name="gztell">gztell</a> (gzFile file);</font>
-<dd>
- Returns the starting position for the next <a href="#gzread">gzread</a> or <a href="#gzwrite">gzwrite</a> on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
- <p>
-
- <a href="#gztell">gztell</a>(file) is equivalent to <a href="#gzseek">gzseek</a>(file, 0L, SEEK_CUR)
- <p>
-
-<font color="Blue"><dt> int <a name="gzeof">gzeof</a> (gzFile file);</font>
-<dd>
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
- <p>
-
-<font color="Blue"><dt> int <a name="gzclose">gzclose</a> (gzFile file);</font>
-<dd>
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression <a href="#state">state</a>. The return value is the zlib
- error number (see function <a href="#gzerror">gzerror</a> below).
- <p>
-
-<font color="Blue"><dt> const char * <a name="gzerror">gzerror</a> (gzFile file, int *errnum);</font>
-<dd>
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to <a href="#Z_ERRNO">Z_ERRNO</a> and the application may consult errno
- to get the exact error code.
- <p>
-</dl>
-<hr>
-<a name="Basic functions"><h2> Basic functions </h2>
-<h3> Function list </h3>
-<ul>
-<li> const char * <a href="#zlibVersion">zlibVersion</a> (void);
-<li> int <a href="#deflateInit">deflateInit</a> (<a href="#z_streamp">z_streamp</a> strm, int level);
-<li> int <a href="#deflate">deflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);
-<li> int <a href="#deflateEnd">deflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);
-<li> int <a href="#inflateInit">inflateInit</a> (<a href="#z_streamp">z_streamp</a> strm);
-<li> int <a href="#inflate">inflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);
-<li> int <a href="#inflateEnd">inflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);
-</ul>
-
-<h3> Function description </h3>
-<dl>
-<font color="Blue"><dt> const char * <a name="zlibVersion">zlibVersion</a> (void);</font>
-<dd> The application can compare <a href="#zlibVersion">zlibVersion</a> and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- This check is automatically made by <a href="#deflateInit">deflateInit</a> and <a href="#inflateInit">inflateInit</a>.
- <p>
-
-<font color="Blue"><dt> int <a name="deflateInit">deflateInit</a> (<a href="#z_streamp">z_streamp</a> strm, int level);</font>
-<dd>
- Initializes the internal stream <a href="#state">state</a> for compression. The fields
- <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by the caller.
- If <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> are set to <a href="#Z_NULL">Z_NULL</a>, <a href="#deflateInit">deflateInit</a> updates them to
- use default allocation functions.
- <p>
-
- The compression level must be <a href="#Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a>, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at
- all (the input data is simply copied a block at a time).
- <p>
-
- <a href="#Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a> requests a default compromise between speed and
- compression (currently equivalent to level 6).
- <p>
-
- <a href="#deflateInit">deflateInit</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
- enough memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if level is not a valid compression level,
- <a href="#Z_VERSION_ERROR">Z_VERSION_ERROR</a> if the zlib library version (<a href="#zlib_version">zlib_version</a>) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- <a href="#msg">msg</a> is set to null if there is no error message. <a href="#deflateInit">deflateInit</a> does not
- perform any compression: this will be done by <a href="#deflate">deflate</a>().
- <p>
-
-<font color="Blue"><dt> int <a name="deflate">deflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);</font>
-<dd>
- <a href="#deflate">deflate</a> compresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce some
- output latency (reading input without producing any output) except when
- forced to flush.<p>
-
- The detailed semantics are as follows. <a href="#deflate">deflate</a> performs one or both of the
- following actions:
-
- <ul>
- <li> Compress more input starting at <a href="#next_in">next_in</a> and update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a>
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> are updated and
- processing will resume at this point for the next call of <a href="#deflate">deflate</a>().
-
- <li>
- Provide more output starting at <a href="#next_out">next_out</a> and update <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a>
- accordingly. This action is forced if the parameter flush is non zero.
- Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications).
- Some output may be provided even if flush is not set.
- </ul> <p>
-
- Before the call of <a href="#deflate">deflate</a>(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating <a href="#avail_in">avail_in</a> or <a href="#avail_out">avail_out</a> accordingly ; <a href="#avail_out">avail_out</a>
- should never be zero before the call. The application can consume the
- compressed output when it wants, for example when the output buffer is full
- (<a href="#avail_out">avail_out</a> == 0), or after each call of <a href="#deflate">deflate</a>(). If <a href="#deflate">deflate</a> returns <a href="#Z_OK">Z_OK</a>
- and with zero <a href="#avail_out">avail_out</a>, it must be called again after making room in the
- output buffer because there might be more output pending.
- <p>
-
- If the parameter flush is set to <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, all pending output is
- flushed to the output buffer and the output is aligned on a byte boundary, so
- that the decompressor can get all input data available so far. (In particular
- <a href="#avail_in">avail_in</a> is zero after the call if enough output space has been provided
- before the call.) Flushing may degrade compression for some compression
- algorithms and so it should be used only when necessary.
- <p>
-
- If flush is set to <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a>, all output is flushed as with
- <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, and the compression <a href="#state">state</a> is reset so that decompression can
- restart from this point if previous compressed data has been damaged or if
- random access is desired. Using <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a> too often can seriously degrade
- the compression.
- <p>
-
- If <a href="#deflate">deflate</a> returns with <a href="#avail_out">avail_out</a> == 0, this function must be called again
- with the same value of the flush parameter and more output space (updated
- <a href="#avail_out">avail_out</a>), until the flush is complete (<a href="#deflate">deflate</a> returns with non-zero
- <a href="#avail_out">avail_out</a>).
- <p>
-
- If the parameter flush is set to <a href="#Z_FINISH">Z_FINISH</a>, pending input is processed,
- pending output is flushed and <a href="#deflate">deflate</a> returns with <a href="#Z_STREAM_END">Z_STREAM_END</a> if there
- was enough output space ; if <a href="#deflate">deflate</a> returns with <a href="#Z_OK">Z_OK</a>, this function must be
- called again with <a href="#Z_FINISH">Z_FINISH</a> and more output space (updated <a href="#avail_out">avail_out</a>) but no
- more input data, until it returns with <a href="#Z_STREAM_END">Z_STREAM_END</a> or an error. After
- <a href="#deflate">deflate</a> has returned <a href="#Z_STREAM_END">Z_STREAM_END</a>, the only possible operations on the
- stream are <a href="#deflateReset">deflateReset</a> or <a href="#deflateEnd">deflateEnd</a>.
- <p>
-
- <a href="#Z_FINISH">Z_FINISH</a> can be used immediately after <a href="#deflateInit">deflateInit</a> if all the compression
- is to be done in a single step. In this case, <a href="#avail_out">avail_out</a> must be at least
- 0.1% larger than <a href="#avail_in">avail_in</a> plus 12 bytes. If <a href="#deflate">deflate</a> does not return
- <a href="#Z_STREAM_END">Z_STREAM_END</a>, then it must be called again as described above.
- <p>
-
- <a href="#deflate">deflate</a>() sets strm-&gt <a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of all input read
- so far (that is, <a href="#total_in">total_in</a> bytes).
- <p>
-
- <a href="#deflate">deflate</a>() may update <a href="#data_type">data_type</a> if it can make a good guess about
- the input data type (<a href="#Z_ASCII">Z_ASCII</a> or <a href="#Z_BINARY">Z_BINARY</a>). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
- <p>
-
- <a href="#deflate">deflate</a>() returns <a href="#Z_OK">Z_OK</a> if some progress has been made (more input
- processed or more output produced), <a href="#Z_STREAM_END">Z_STREAM_END</a> if all input has been
- consumed and all output has been produced (only when flush is set to
- <a href="#Z_FINISH">Z_FINISH</a>), <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream <a href="#state">state</a> was inconsistent (for example
- if <a href="#next_in">next_in</a> or <a href="#next_out">next_out</a> was NULL), <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if no progress is possible
- (for example <a href="#avail_in">avail_in</a> or <a href="#avail_out">avail_out</a> was zero).
- <p>
-
-<font color="Blue"><dt> int <a name="deflateEnd">deflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-<dd>
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
- <p>
-
- <a href="#deflateEnd">deflateEnd</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the
- stream <a href="#state">state</a> was inconsistent, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- <a href="#msg">msg</a> may be set but then points to a static string (which must not be
- deallocated).
- <p>
-
-<font color="Blue"><dt> int <a name="inflateInit">inflateInit</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-<dd>
- Initializes the internal stream <a href="#state">state</a> for decompression. The fields
- <a href="#next_in">next_in</a>, <a href="#avail_in">avail_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by
- the caller. If <a href="#next_in">next_in</a> is not <a href="#Z_NULL">Z_NULL</a> and <a href="#avail_in">avail_in</a> is large enough (the exact
- value depends on the compression method), <a href="#inflateInit">inflateInit</a> determines the
- compression method from the zlib header and allocates all data structures
- accordingly ; otherwise the allocation will be deferred to the first call of
- <a href="#inflate">inflate</a>. If <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> are set to <a href="#Z_NULL">Z_NULL</a>, <a href="#inflateInit">inflateInit</a> updates them to
- use default allocation functions.
- <p>
-
- <a href="#inflateInit">inflateInit</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
- memory, <a href="#Z_VERSION_ERROR">Z_VERSION_ERROR</a> if the zlib library version is incompatible with the
- version assumed by the caller. <a href="#msg">msg</a> is set to null if there is no error
- message. <a href="#inflateInit">inflateInit</a> does not perform any decompression apart from reading
- the zlib header if present: this will be done by <a href="#inflate">inflate</a>(). (So <a href="#next_in">next_in</a> and
- <a href="#avail_in">avail_in</a> may be modified, but <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> are unchanged.)
- <p>
-
-<font color="Blue"><dt> int <a name="inflate">inflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);</font>
-<dd>
- <a href="#inflate">inflate</a> decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may some
- introduce some output latency (reading input without producing any output)
- except when forced to flush.
- <p>
-
- The detailed semantics are as follows. <a href="#inflate">inflate</a> performs one or both of the
- following actions:
-
- <ul>
- <li> Decompress more input starting at <a href="#next_in">next_in</a> and update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a>
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), <a href="#next_in">next_in</a> is updated and processing
- will resume at this point for the next call of <a href="#inflate">inflate</a>().
-
- <li> Provide more output starting at <a href="#next_out">next_out</a> and update <a href="#next_out">next_out</a> and
- <a href="#avail_out">avail_out</a> accordingly. <a href="#inflate">inflate</a>() provides as much output as possible,
- until there is no more input data or no more space in the output buffer
- (see below about the flush parameter).
- </ul> <p>
-
- Before the call of <a href="#inflate">inflate</a>(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (<a href="#avail_out">avail_out</a> == 0), or after each
- call of <a href="#inflate">inflate</a>(). If <a href="#inflate">inflate</a> returns <a href="#Z_OK">Z_OK</a> and with zero <a href="#avail_out">avail_out</a>, it
- must be called again after making room in the output buffer because there
- might be more output pending.
- <p>
-
- If the parameter flush is set to <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, <a href="#inflate">inflate</a> flushes as much
- output as possible to the output buffer. The flushing behavior of <a href="#inflate">inflate</a> is
- not specified for values of the flush parameter other than <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>
- and <a href="#Z_FINISH">Z_FINISH</a>, but the current implementation actually flushes as much output
- as possible anyway.
- <p>
-
- <a href="#inflate">inflate</a>() should normally be called until it returns <a href="#Z_STREAM_END">Z_STREAM_END</a> or an
- error. However if all decompression is to be performed in a single step
- (a single call of <a href="#inflate">inflate</a>), the parameter flush should be set to
- <a href="#Z_FINISH">Z_FINISH</a>. In this case all pending input is processed and all pending
- output is flushed ; <a href="#avail_out">avail_out</a> must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be <a href="#inflateEnd">inflateEnd</a> to deallocate the decompression <a href="#state">state</a>. The use of <a href="#Z_FINISH">Z_FINISH</a>
- is never required, but can be used to inform <a href="#inflate">inflate</a> that a faster routine
- may be used for the single <a href="#inflate">inflate</a>() call.
- <p>
-
- If a preset dictionary is needed at this point (see <a href="#inflateSetDictionary">inflateSetDictionary</a>
- below), <a href="#inflate">inflate</a> sets strm-<a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of the
- dictionary chosen by the compressor and returns <a href="#Z_NEED_DICT">Z_NEED_DICT</a> ; otherwise
- it sets strm-&gt <a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of all output produced
- so far (that is, <a href="#total_out">total_out</a> bytes) and returns <a href="#Z_OK">Z_OK</a>, <a href="#Z_STREAM_END">Z_STREAM_END</a> or
- an error code as described below. At the end of the stream, <a href="#inflate">inflate</a>()
- checks that its computed <a href="#adler32">adler32</a> checksum is equal to that saved by the
- compressor and returns <a href="#Z_STREAM_END">Z_STREAM_END</a> only if the checksum is correct.
- <p>
-
- <a href="#inflate">inflate</a>() returns <a href="#Z_OK">Z_OK</a> if some progress has been made (more input processed
- or more output produced), <a href="#Z_STREAM_END">Z_STREAM_END</a> if the end of the compressed data has
- been reached and all uncompressed output has been produced, <a href="#Z_NEED_DICT">Z_NEED_DICT</a> if a
- preset dictionary is needed at this point, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the input data was
- corrupted (input stream not conforming to the zlib format or incorrect
- <a href="#adler32">adler32</a> checksum), <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream structure was inconsistent
- (for example if <a href="#next_in">next_in</a> or <a href="#next_out">next_out</a> was NULL), <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
- enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if no progress is possible or if there was not
- enough room in the output buffer when <a href="#Z_FINISH">Z_FINISH</a> is used. In the <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a>
- case, the application may then call <a href="#inflateSync">inflateSync</a> to look for a good
- compression block.
- <p>
-
-<font color="Blue"><dt> int <a name="inflateEnd">inflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-<dd>
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
- <p>
-
- <a href="#inflateEnd">inflateEnd</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream <a href="#state">state</a>
- was inconsistent. In the error case, <a href="#msg">msg</a> may be set but then points to a
- static string (which must not be deallocated).
-</dl>
-<hr>
-<a name="Advanced functions"><h2> Advanced functions </h2>
- The following functions are needed only in some special applications.
-<h3> Function list </h3>
-<ul>
-<li> int <a href="#deflateInit2">deflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm,
-<li> int <a href="#deflateSetDictionary">deflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);
-<li> int <a href="#deflateCopy">deflateCopy</a> (<a href="#z_streamp">z_streamp</a> dest, <a href="#z_streamp">z_streamp</a> source);
-<li> int <a href="#deflateReset">deflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);
-<li> int <a href="#deflateParams">deflateParams</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int strategy);
-<li> int <a href="#inflateInit2">inflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int windowBits);
-<li> int <a href="#inflateSetDictionary">inflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);
-<li> int <a href="#inflateSync">inflateSync</a> (<a href="#z_streamp">z_streamp</a> strm);
-<li> int <a href="#inflateReset">inflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);
-
-</ul>
-<h3> Function description </h3>
-<dl>
-<font color="Blue"><dt> int <a name="deflateInit2">deflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int method, int windowBits, int memLevel, int strategy);</font>
-
-<dd> This is another version of <a href="#deflateInit">deflateInit</a> with more compression options. The
- fields <a href="#next_in">next_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by
- the caller.<p>
-
- The method parameter is the compression method. It must be <a href="#Z_DEFLATED">Z_DEFLATED</a> in
- this version of the library.<p>
-
- The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library. Larger values of this parameter result in better
- compression at the expense of memory usage. The default value is 15 if
- <a href="#deflateInit">deflateInit</a> is used instead.<p>
-
- The memLevel parameter specifies how much memory should be allocated
- for the internal compression <a href="#state">state</a>. memLevel=1 uses minimum memory but
- is slow and reduces compression ratio ; memLevel=9 uses maximum memory
- for optimal speed. The default value is 8. See zconf.h for total memory
- usage as a function of windowBits and memLevel.<p>
-
- The strategy parameter is used to tune the compression algorithm. Use the
- value <a href="#Z_DEFAULT_STRATEGY">Z_DEFAULT_STRATEGY</a> for normal data, <a href="#Z_FILTERED">Z_FILTERED</a> for data produced by a
- filter (or predictor), or <a href="#Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a> to force Huffman encoding only (no
- string match). Filtered data consists mostly of small values with a
- somewhat random distribution. In this case, the compression algorithm is
- tuned to <a href="#compress">compress</a> them better. The effect of <a href="#Z_FILTERED">Z_FILTERED</a> is to force more
- Huffman coding and less string matching ; it is somewhat intermediate
- between Z_DEFAULT and <a href="#Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a>. The strategy parameter only affects
- the compression ratio but not the correctness of the compressed output even
- if it is not set appropriately.<p>
-
- <a href="#deflateInit2">deflateInit2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
- memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a parameter is invalid (such as an invalid
- method). <a href="#msg">msg</a> is set to null if there is no error message. <a href="#deflateInit2">deflateInit2</a> does
- not perform any compression: this will be done by <a href="#deflate">deflate</a>().<p>
-
-<font color="Blue"><dt> int <a name="deflateSetDictionary">deflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);</font>
-<dd>
- Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after <a href="#deflateInit">deflateInit</a>, <a href="#deflateInit2">deflateInit2</a> or <a href="#deflateReset">deflateReset</a>, before any
- call of <a href="#deflate">deflate</a>. The compressor and decompressor must use exactly the same
- dictionary (see <a href="#inflateSetDictionary">inflateSetDictionary</a>).<p>
-
- The dictionary should consist of strings (byte sequences) that are likely
- to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
- dictionary is most useful when the data to be compressed is short and can be
- predicted with good accuracy ; the data can then be compressed better than
- with the default empty dictionary.<p>
-
- Depending on the size of the compression data structures selected by
- <a href="#deflateInit">deflateInit</a> or <a href="#deflateInit2">deflateInit2</a>, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size in
- <a href="#deflate">deflate</a> or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front.<p>
-
- Upon return of this function, strm-&gt <a href="#adler">adler</a> is set to the Adler32 value
- of the dictionary ; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The Adler32 value
- applies to the whole dictionary even if only a subset of the dictionary is
- actually used by the compressor.)<p>
-
- <a href="#deflateSetDictionary">deflateSetDictionary</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a
- parameter is invalid (such as NULL dictionary) or the stream <a href="#state">state</a> is
- inconsistent (for example if <a href="#deflate">deflate</a> has already been called for this stream
- or if the compression method is bsort). <a href="#deflateSetDictionary">deflateSetDictionary</a> does not
- perform any compression: this will be done by <a href="#deflate">deflate</a>().<p>
-
-<font color="Blue"><dt> int <a name="deflateCopy">deflateCopy</a> (<a href="#z_streamp">z_streamp</a> dest, <a href="#z_streamp">z_streamp</a> source);</font>
-<dd>
- Sets the destination stream as a complete copy of the source stream.<p>
-
- This function can be useful when several compression strategies will be
- tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
- by calling <a href="#deflateEnd">deflateEnd</a>. Note that <a href="#deflateCopy">deflateCopy</a> duplicates the internal
- compression <a href="#state">state</a> which can be quite large, so this strategy is slow and
- can consume lots of memory.<p>
-
- <a href="#deflateCopy">deflateCopy</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
- enough memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source stream <a href="#state">state</a> was inconsistent
- (such as <a href="#zalloc">zalloc</a> being NULL). <a href="#msg">msg</a> is left unchanged in both source and
- destination.<p>
-
-<font color="Blue"><dt> int <a name="deflateReset">deflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-<dd> This function is equivalent to <a href="#deflateEnd">deflateEnd</a> followed by <a href="#deflateInit">deflateInit</a>,
- but does not free and reallocate all the internal compression <a href="#state">state</a>.
- The stream will keep the same compression level and any other attributes
- that may have been set by <a href="#deflateInit2">deflateInit2</a>.<p>
-
- <a href="#deflateReset">deflateReset</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source
- stream <a href="#state">state</a> was inconsistent (such as <a href="#zalloc">zalloc</a> or <a href="#state">state</a> being NULL).<p>
-
-<font color="Blue"><dt> int <a name="deflateParams">deflateParams</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int strategy);</font>
-<dd>
- Dynamically update the compression level and compression strategy. The
- interpretation of level and strategy is as in <a href="#deflateInit2">deflateInit2</a>. This can be
- used to switch between compression and straight copy of the input data, or
- to switch to a different kind of input data requiring a different
- strategy. If the compression level is changed, the input available so far
- is compressed with the old level (and may be flushed); the new level will
- take effect only at the next call of <a href="#deflate">deflate</a>().<p>
-
- Before the call of <a href="#deflateParams">deflateParams</a>, the stream <a href="#state">state</a> must be set as for
- a call of <a href="#deflate">deflate</a>(), since the currently available input may have to
- be compressed and flushed. In particular, strm-&gt <a href="#avail_out">avail_out</a> must be
- non-zero.<p>
-
- <a href="#deflateParams">deflateParams</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source
- stream <a href="#state">state</a> was inconsistent or if a parameter was invalid, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a>
- if strm-&gtavail_out was zero.<p>
-
-<font color="Blue"><dt> int <a name="inflateInit2">inflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int windowBits);</font>
-
-<dd> This is another version of <a href="#inflateInit">inflateInit</a> with an extra parameter. The
- fields <a href="#next_in">next_in</a>, <a href="#avail_in">avail_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized
- before by the caller.<p>
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library. The default value is 15 if <a href="#inflateInit">inflateInit</a> is used
- instead. If a compressed stream with a larger window size is given as
- input, <a href="#inflate">inflate</a>() will return with the error code <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> instead of
- trying to allocate a larger window.<p>
-
- <a href="#inflateInit2">inflateInit2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
- memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a parameter is invalid (such as a negative
- memLevel). <a href="#msg">msg</a> is set to null if there is no error message. <a href="#inflateInit2">inflateInit2</a>
- does not perform any decompression apart from reading the zlib header if
- present: this will be done by <a href="#inflate">inflate</a>(). (So <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> may be
- modified, but <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> are unchanged.)<p>
-
-<font color="Blue"><dt> int <a name="inflateSetDictionary">inflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);</font>
-<dd>
- Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of <a href="#inflate">inflate</a>
- if this call returned <a href="#Z_NEED_DICT">Z_NEED_DICT</a>. The dictionary chosen by the compressor
- can be determined from the Adler32 value returned by this call of
- <a href="#inflate">inflate</a>. The compressor and decompressor must use exactly the same
- dictionary (see <a href="#deflateSetDictionary">deflateSetDictionary</a>).<p>
-
- <a href="#inflateSetDictionary">inflateSetDictionary</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a
- parameter is invalid (such as NULL dictionary) or the stream <a href="#state">state</a> is
- inconsistent, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the given dictionary doesn't match the
- expected one (incorrect Adler32 value). <a href="#inflateSetDictionary">inflateSetDictionary</a> does not
- perform any decompression: this will be done by subsequent calls of
- <a href="#inflate">inflate</a>().<p>
-
-<font color="Blue"><dt> int <a name="inflateSync">inflateSync</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-
-<dd> Skips invalid compressed data until a full flush point (see above the
- description of <a href="#deflate">deflate</a> with <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a>) can be found, or until all
- available input is skipped. No output is provided.<p>
-
- <a href="#inflateSync">inflateSync</a> returns <a href="#Z_OK">Z_OK</a> if a full flush point has been found, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a>
- if no more input was provided, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if no flush point has been found,
- or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream structure was inconsistent. In the success
- case, the application may save the current current value of <a href="#total_in">total_in</a> which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call <a href="#inflateSync">inflateSync</a>, providing more input each time,
- until success or end of the input data.<p>
-
-<font color="Blue"><dt> int <a name="inflateReset">inflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-<dd>
- This function is equivalent to <a href="#inflateEnd">inflateEnd</a> followed by <a href="#inflateInit">inflateInit</a>,
- but does not free and reallocate all the internal decompression <a href="#state">state</a>.
- The stream will keep attributes that may have been set by <a href="#inflateInit2">inflateInit2</a>.
- <p>
-
- <a href="#inflateReset">inflateReset</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source
- stream <a href="#state">state</a> was inconsistent (such as <a href="#zalloc">zalloc</a> or <a href="#state">state</a> being NULL).
- <p>
-</dl>
-
-<hr>
-<a name="Checksum functions"><h2> Checksum functions </h2>
- These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
-<h3> Function list </h3>
-<ul>
-<li> uLong <a href="#adler32">adler32</a> (uLong <a href="#adler">adler</a>, const Bytef *buf, uInt len);
-<li> uLong <a href="#crc32">crc32</a> (uLong crc, const Bytef *buf, uInt len);
-</ul>
-<h3> Function description </h3>
-<dl>
-<font color="Blue"><dt> uLong <a name="adler32">adler32</a> (uLong <a href="#adler">adler</a>, const Bytef *buf, uInt len);</font>
-<dd>
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- <p>
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
- <pre>
-
- uLong <a href="#adler">adler</a> = <a href="#adler32">adler32</a>(0L, <a href="#Z_NULL">Z_NULL</a>, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- <a href="#adler">adler</a> = <a href="#adler32">adler32</a>(<a href="#adler">adler</a>, buffer, length);
- }
- if (<a href="#adler">adler</a> != original_adler) error();
- </pre>
-
-<font color="Blue"><dt> uLong <a name="crc32">crc32</a> (uLong crc, const Bytef *buf, uInt len);</font>
-<dd>
- Update a running crc with the bytes buf[0..len-1] and return the updated
- crc. If buf is NULL, this function returns the required initial value
- for the crc. Pre- and post-conditioning (one's complement) is performed
- within this function so it shouldn't be done by the application.
- Usage example:
- <pre>
-
- uLong crc = <a href="#crc32">crc32</a>(0L, <a href="#Z_NULL">Z_NULL</a>, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- crc = <a href="#crc32">crc32</a>(crc, buffer, length);
- }
- if (crc != original_crc) error();
- </pre>
-</dl>
-<hr>
-<a name="struct z_stream_s"><h2> struct z_stream_s </h2>
-<font color="Blue">
-<a name="z_stream_s">
-<pre>
-typedef struct z_stream_s {
- Bytef *<a name="next_in">next_in</a>; /* next input byte */
- uInt <a name="avail_in">avail_in</a>; /* number of bytes available at <a href="#next_in">next_in</a> */
- uLong <a name="total_in">total_in</a>; /* total nb of input bytes read so far */
-
- Bytef *<a name="next_out">next_out</a>; /* next output byte should be put there */
- uInt <a name="avail_out">avail_out</a>; /* remaining free space at <a href="#next_out">next_out</a> */
- uLong <a name="total_out">total_out</a>; /* total nb of bytes output so far */
-
- char *<a name="msg">msg</a>; /* last error message, NULL if no error */
- struct internal_state FAR *<a name="state">state</a>; /* not visible by applications */
-
- alloc_func <a name="zalloc">zalloc</a>; /* used to allocate the internal <a href="#state">state</a> */
- free_func <a name="zfree">zfree</a>; /* used to free the internal <a href="#state">state</a> */
- voidpf <a name="opaque">opaque</a>; /* private data object passed to <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> */
-
- int <a name="data_type">data_type</a>; /* best guess about the data type: ascii or binary */
- uLong <a name="adler">adler</a>; /* <a href="#adler32">adler32</a> value of the uncompressed data */
- uLong <a name="reserved">reserved</a>; /* <a href="#reserved">reserved</a> for future use */
-} <a href="#z_stream_s">z_stream</a> ;
-
-typedef <a href="#z_stream_s">z_stream</a> FAR * <a name="z_streamp">z_streamp</a>; ÿ
-</pre>
-</font>
- The application must update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> when <a href="#avail_in">avail_in</a> has
- dropped to zero. It must update <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> when <a href="#avail_out">avail_out</a>
- has dropped to zero. The application must initialize <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and
- <a href="#opaque">opaque</a> before calling the init function. All other fields are set by the
- compression library and must not be updated by the application. <p>
-
- The <a href="#opaque">opaque</a> value provided by the application will be passed as the first
- parameter for calls of <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a>. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- <a href="#opaque">opaque</a> value. <p>
-
- <a href="#zalloc">zalloc</a> must return <a href="#Z_NULL">Z_NULL</a> if there is not enough memory for the object.
- If zlib is used in a multi-threaded application, <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> must be
- thread safe. <p>
-
- On 16-bit systems, the functions <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by <a href="#zalloc">zalloc</a> for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
- <p>
-
- The fields <a href="#total_in">total_in</a> and <a href="#total_out">total_out</a> can be used for statistics or
- progress reports. After compression, <a href="#total_in">total_in</a> holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step). <p>
-
-<hr>
-<a name="Constants"><h2> Constants </h2>
-<font color="Blue">
-<pre>
-#define <a name="Z_NO_FLUSH">Z_NO_FLUSH</a> 0
-#define <a name="Z_PARTIAL_FLUSH">Z_PARTIAL_FLUSH</a> 1
- /* will be removed, use <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a> instead */
-#define <a name="Z_SYNC_FLUSH">Z_SYNC_FLUSH</a> 2
-#define <a name="Z_FULL_FLUSH">Z_FULL_FLUSH</a> 3
-#define <a name="Z_FINISH">Z_FINISH</a> 4
-/* Allowed flush values ; see <a href="#deflate">deflate</a>() below for details */
-
-#define <a name="Z_OK">Z_OK</a> 0
-#define <a name="Z_STREAM_END">Z_STREAM_END</a> 1
-#define <a name="Z_NEED_DICT">Z_NEED_DICT</a> 2
-#define <a name="Z_ERRNO">Z_ERRNO</a> (-1)
-#define <a name="Z_STREAM_ERROR">Z_STREAM_ERROR</a> (-2)
-#define <a name="Z_DATA_ERROR">Z_DATA_ERROR</a> (-3)
-#define <a name="Z_MEM_ERROR">Z_MEM_ERROR</a> (-4)
-#define <a name="Z_BUF_ERROR">Z_BUF_ERROR</a> (-5)
-#define <a name="Z_VERSION_ERROR">Z_VERSION_ERROR</a> (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define <a name="Z_NO_COMPRESSION">Z_NO_COMPRESSION</a> 0
-#define <a name="Z_BEST_SPEED">Z_BEST_SPEED</a> 1
-#define <a name="Z_BEST_COMPRESSION">Z_BEST_COMPRESSION</a> 9
-#define <a name="Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a> (-1)
-/* compression levels */
-
-#define <a name="Z_FILTERED">Z_FILTERED</a> 1
-#define <a name="Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a> 2
-#define <a name="Z_DEFAULT_STRATEGY">Z_DEFAULT_STRATEGY</a> 0
-/* compression strategy ; see <a href="#deflateInit2">deflateInit2</a>() below for details */
-
-#define <a name="Z_BINARY">Z_BINARY</a> 0
-#define <a name="Z_ASCII">Z_ASCII</a> 1
-#define <a name="Z_UNKNOWN">Z_UNKNOWN</a> 2
-/* Possible values of the <a href="#data_type">data_type</a> field */
-
-#define <a name="Z_DEFLATED">Z_DEFLATED</a> 8
-/* The <a href="#deflate">deflate</a> compression method (the only one supported in this version) */
-
-#define <a name="Z_NULL">Z_NULL</a> 0 /* for initializing <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a>, <a href="#opaque">opaque</a> */
-
-#define <a name="zlib_version">zlib_version</a> <a href="#zlibVersion">zlibVersion</a>()
-/* for compatibility with versions less than 1.0.2 */
-</pre>
-</font>
-
-<hr>
-<a name="Misc"><h2> Misc </h2>
- <a href="#deflateInit">deflateInit</a> and <a href="#inflateInit">inflateInit</a> are macros to allow checking the zlib version
- and the compiler's view of <a href="#z_stream_s">z_stream</a>.
- <p>
- Other functions:
- <dl>
- <font color="Blue"><dt> const char * <a name="zError">zError</a> (int err);</font>
- <font color="Blue"><dt> int <a name="inflateSyncPoint">inflateSyncPoint</a> (<a href="#z_streamp">z_streamp</a> z);</font>
- <font color="Blue"><dt> const uLongf * <a name="get_crc_table">get_crc_table</a> (void);</font>
- </dl>
- <hr>
- <font size="-1">
- Last update: Wed Oct 13 20:42:34 1999<br>
- piapi@csie.ntu.edu.tw
- </font>
-
-</body>
-</html>
diff --git a/cpukit/zlib/preinstall.am b/cpukit/zlib/preinstall.am
new file mode 100644
index 0000000000..926986e5e0
--- /dev/null
+++ b/cpukit/zlib/preinstall.am
@@ -0,0 +1,42 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+ $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+all-local: $(TMPINSTALL_FILES)
+
+TMPINSTALL_FILES =
+CLEANFILES = $(TMPINSTALL_FILES)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES += $(PREINSTALL_FILES)
+
+$(PROJECT_LIB)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_LIB)
+ @: > $(PROJECT_LIB)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)
+ @: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
+
+$(PROJECT_LIB)/libz.a: libz.a $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/libz.a
+TMPINSTALL_FILES += $(PROJECT_LIB)/libz.a
+
+$(PROJECT_INCLUDE)/zlib.h: zlib.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/zlib.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/zlib.h
+
+$(PROJECT_INCLUDE)/zconf.h: zconf.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/zconf.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/zconf.h
+
diff --git a/cpukit/zlib/projects/README.projects b/cpukit/zlib/projects/README.projects
deleted file mode 100644
index 1c029e4a34..0000000000
--- a/cpukit/zlib/projects/README.projects
+++ /dev/null
@@ -1,41 +0,0 @@
-This directory contains project files for building zlib under various
-Integrated Development Environments (IDE).
-
-If you wish to submit a new project to this directory, you should comply
-to the following requirements. Otherwise (e.g. if you wish to integrate
-a custom piece of code that changes the zlib interface or its behavior),
-please consider submitting the project to the contrib directory.
-
-
-Requirements
-============
-
-- The project must build zlib using the source files from the official
- zlib source distribution, exclusively.
-
-- If the project produces redistributable builds (e.g. shared objects
- or DLL files), these builds must be compatible to those produced by
- makefiles, if such makefiles exist in the zlib distribution.
- In particular, if the project produces a DLL build for the Win32
- platform, this build must comply to the officially-ammended Win32 DLL
- Application Binary Interface (ABI), described in win32/DLL_FAQ.txt.
-
-- The project may provide additional build targets, which depend on
- 3rd-party (unofficially-supported) software, present in the contrib
- directory. For example, it is possible to provide an "ASM build",
- besides the officially-supported build, and have ASM source files
- among its dependencies.
-
-- If there are significant differences between the project files created
- by different versions of an IDE (e.g. Visual C++ 6.0 vs. 7.0), the name
- of the project directory should contain the version number of the IDE
- for which the project is intended (e.g. "visualc6" for Visual C++ 6.0,
- or "visualc7" for Visual C++ 7.0 and 7.1).
-
-
-Current projects
-================
-
-visualc6/ by Simon-Pierre Cadieux <methodex@methodex.ca>
- and Cosmin Truta <cosmint@cs.ubbcluj.ro>
- Project for Microsoft Visual C++ 6.0
diff --git a/cpukit/zlib/projects/visualc6/README.txt b/cpukit/zlib/projects/visualc6/README.txt
deleted file mode 100644
index d0296c272c..0000000000
--- a/cpukit/zlib/projects/visualc6/README.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-Microsoft Developer Studio Project Files, Format Version 6.00 for zlib.
-
-Copyright (C) 2000-2004 Simon-Pierre Cadieux.
-Copyright (C) 2004 Cosmin Truta.
-For conditions of distribution and use, see copyright notice in zlib.h.
-
-
-This project builds the zlib binaries as follows:
-
-* Win32_DLL_Release\zlib1.dll DLL build
-* Win32_DLL_Debug\zlib1d.dll DLL build (debug version)
-* Win32_DLL_ASM_Release\zlib1.dll DLL build using ASM code
-* Win32_DLL_ASM_Debug\zlib1d.dll DLL build using ASM code (debug version)
-* Win32_LIB_Release\zlib.lib static build
-* Win32_LIB_Debug\zlibd.lib static build (debug version)
-* Win32_LIB_ASM_Release\zlib.lib static build using ASM code
-* Win32_LIB_ASM_Debug\zlibd.lib static build using ASM code (debug version)
-
-
-For more information regarding the DLL builds, please see the DLL FAQ
-in ..\..\win32\DLL_FAQ.txt.
-
-
-To build and test:
-
-1) On the main menu, select "File | Open Workspace".
- Open "zlib.dsw".
-
-2) Select "Build | Set Active Configuration".
- Choose the configuration you wish to build.
-
-3) Select "Build | Clean".
-
-4) Select "Build | Build ... (F7)". Ignore warning messages about
- not being able to find certain include files (e.g. alloc.h).
-
-5) If you built one of the sample programs (example or minigzip),
- select "Build | Execute ... (Ctrl+F5)".
-
-
-To use:
-
-1) Select "Project | Settings (Alt+F7)".
- Make note of the configuration names used in your project.
- Usually, these names are "Win32 Release" and "Win32 Debug".
-
-2) In the Workspace window, select the "FileView" tab.
- Right-click on the root item "Workspace '...'".
- Select "Insert Project into Workspace".
- Switch on the checkbox "Dependency of:", and select the name
- of your project. Open "zlib.dsp".
-
-3) Select "Build | Configurations".
- For each configuration of your project:
- 3.1) Choose the zlib configuration you wish to use.
- 3.2) Click on "Add".
- 3.3) Set the new zlib configuration name to the name used by
- the configuration from the current iteration.
-
-4) Select "Build | Set Active Configuration".
- Choose the configuration you wish to build.
-
-5) Select "Build | Build ... (F7)".
-
-6) If you built an executable program, select
- "Build | Execute ... (Ctrl+F5)".
-
-
-Note:
-
-To build the ASM-enabled code, you need Microsoft Assembler
-(ML.EXE). You can get it by downloading and installing the
-latest Processor Pack for Visual C++ 6.0.
diff --git a/cpukit/zlib/projects/visualc6/example.dsp b/cpukit/zlib/projects/visualc6/example.dsp
deleted file mode 100644
index d3580525bd..0000000000
--- a/cpukit/zlib/projects/visualc6/example.dsp
+++ /dev/null
@@ -1,278 +0,0 @@
-# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=example - Win32 LIB Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "example.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 LIB Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "example - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 DLL Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 DLL Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 LIB Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 LIB Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "example - Win32 DLL ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "example___Win32_DLL_ASM_Release"
-# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_ASM_Release"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "example - Win32 DLL ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "example___Win32_DLL_ASM_Debug"
-# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_ASM_Debug"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "example - Win32 DLL Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "example___Win32_DLL_Release"
-# PROP BASE Intermediate_Dir "example___Win32_DLL_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_Release"
-# PROP Intermediate_Dir "Win32_DLL_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "example - Win32 DLL Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "example___Win32_DLL_Debug"
-# PROP BASE Intermediate_Dir "example___Win32_DLL_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_Debug"
-# PROP Intermediate_Dir "Win32_DLL_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "example___Win32_LIB_ASM_Release"
-# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_ASM_Release"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "example___Win32_LIB_ASM_Debug"
-# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_ASM_Debug"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "example - Win32 LIB Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "example___Win32_LIB_Release"
-# PROP BASE Intermediate_Dir "example___Win32_LIB_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_Release"
-# PROP Intermediate_Dir "Win32_LIB_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "example - Win32 LIB Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "example___Win32_LIB_Debug"
-# PROP BASE Intermediate_Dir "example___Win32_LIB_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_Debug"
-# PROP Intermediate_Dir "Win32_LIB_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "example - Win32 DLL ASM Release"
-# Name "example - Win32 DLL ASM Debug"
-# Name "example - Win32 DLL Release"
-# Name "example - Win32 DLL Debug"
-# Name "example - Win32 LIB ASM Release"
-# Name "example - Win32 LIB ASM Debug"
-# Name "example - Win32 LIB Release"
-# Name "example - Win32 LIB Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\example.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\zconf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zlib.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/cpukit/zlib/projects/visualc6/minigzip.dsp b/cpukit/zlib/projects/visualc6/minigzip.dsp
deleted file mode 100644
index 71034684d8..0000000000
--- a/cpukit/zlib/projects/visualc6/minigzip.dsp
+++ /dev/null
@@ -1,278 +0,0 @@
-# Microsoft Developer Studio Project File - Name="minigzip" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=minigzip - Win32 LIB Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "minigzip.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "minigzip.mak" CFG="minigzip - Win32 LIB Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "minigzip - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 DLL Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 DLL Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 LIB Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 LIB Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "minigzip - Win32 DLL ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Release"
-# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_ASM_Release"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 DLL ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Debug"
-# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_ASM_Debug"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 DLL Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "minigzip___Win32_DLL_Release"
-# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_Release"
-# PROP Intermediate_Dir "Win32_DLL_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 DLL Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "minigzip___Win32_DLL_Debug"
-# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_Debug"
-# PROP Intermediate_Dir "Win32_DLL_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Release"
-# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_ASM_Release"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Debug"
-# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_ASM_Debug"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "minigzip___Win32_LIB_Release"
-# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_Release"
-# PROP Intermediate_Dir "Win32_LIB_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "minigzip___Win32_LIB_Debug"
-# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_Debug"
-# PROP Intermediate_Dir "Win32_LIB_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "minigzip - Win32 DLL ASM Release"
-# Name "minigzip - Win32 DLL ASM Debug"
-# Name "minigzip - Win32 DLL Release"
-# Name "minigzip - Win32 DLL Debug"
-# Name "minigzip - Win32 LIB ASM Release"
-# Name "minigzip - Win32 LIB ASM Debug"
-# Name "minigzip - Win32 LIB Release"
-# Name "minigzip - Win32 LIB Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\minigzip.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\zconf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zlib.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/cpukit/zlib/projects/visualc6/zlib.dsp b/cpukit/zlib/projects/visualc6/zlib.dsp
deleted file mode 100644
index 0fe0604ccd..0000000000
--- a/cpukit/zlib/projects/visualc6/zlib.dsp
+++ /dev/null
@@ -1,609 +0,0 @@
-# Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=zlib - Win32 LIB Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "zlib.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 LIB Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "zlib - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlib - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlib - Win32 DLL ASM Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlib - Win32 DLL ASM Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlib - Win32 LIB Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "zlib - Win32 LIB Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE "zlib - Win32 LIB ASM Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "zlib - Win32 LIB ASM Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-
-!IF "$(CFG)" == "zlib - Win32 DLL Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlib___Win32_DLL_Release"
-# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_Release"
-# PROP Intermediate_Dir "Win32_DLL_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX /Yc /Yu
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_Release\zlib1.dll"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "zlib___Win32_DLL_Debug"
-# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_Debug"
-# PROP Intermediate_Dir "Win32_DLL_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT CPP /YX /Yc /Yu
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_Debug\zlib1d.dll" /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Release"
-# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_ASM_Release"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c
-# SUBTRACT CPP /YX /Yc /Yu
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_ASM_Release\zlib1.dll"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Debug"
-# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_ASM_Debug"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FD /GZ /c
-# SUBTRACT CPP /YX /Yc /Yu
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_ASM_Debug\zlib1d.dll" /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlib___Win32_LIB_Release"
-# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_Release"
-# PROP Intermediate_Dir "Win32_LIB_Release"
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX /Yc /Yu
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "zlib___Win32_LIB_Debug"
-# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_Debug"
-# PROP Intermediate_Dir "Win32_LIB_Debug"
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT CPP /YX /Yc /Yu
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"Win32_LIB_Debug\zlibd.lib"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Release"
-# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_ASM_Release"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c
-# SUBTRACT CPP /YX /Yc /Yu
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Debug"
-# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_ASM_Debug"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FD /GZ /c
-# SUBTRACT CPP /YX /Yc /Yu
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"Win32_LIB_ASM_Debug\zlibd.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "zlib - Win32 DLL Release"
-# Name "zlib - Win32 DLL Debug"
-# Name "zlib - Win32 DLL ASM Release"
-# Name "zlib - Win32 DLL ASM Debug"
-# Name "zlib - Win32 LIB Release"
-# Name "zlib - Win32 LIB Debug"
-# Name "zlib - Win32 LIB ASM Release"
-# Name "zlib - Win32 LIB ASM Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\adler32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\compress.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\crc32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\deflate.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gzio.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\infback.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inffast.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inflate.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inftrees.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\trees.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\uncompr.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\win32\zlib.def
-
-!IF "$(CFG)" == "zlib - Win32 DLL Release"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
-
-# PROP Exclude_From_Build 1
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zutil.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\crc32.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\deflate.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inffast.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inffixed.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inflate.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inftrees.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\trees.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zconf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zlib.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zutil.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# Begin Source File
-
-SOURCE=..\..\win32\zlib1.rc
-# End Source File
-# End Group
-# Begin Group "Assembler Files (Unsupported)"
-
-# PROP Default_Filter "asm;obj;c;cpp;cxx;h;hpp;hxx"
-# Begin Source File
-
-SOURCE=..\..\contrib\masmx86\gvmat32.asm
-
-!IF "$(CFG)" == "zlib - Win32 DLL Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_DLL_ASM_Release
-InputPath=..\..\contrib\masmx86\gvmat32.asm
-InputName=gvmat32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_DLL_ASM_Debug
-InputPath=..\..\contrib\masmx86\gvmat32.asm
-InputName=gvmat32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_LIB_ASM_Release
-InputPath=..\..\contrib\masmx86\gvmat32.asm
-InputName=gvmat32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_LIB_ASM_Debug
-InputPath=..\..\contrib\masmx86\gvmat32.asm
-InputName=gvmat32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\contrib\masmx86\gvmat32c.c
-
-!IF "$(CFG)" == "zlib - Win32 DLL Release"
-
-# PROP Exclude_From_Build 1
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
-
-# PROP Exclude_From_Build 1
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
-
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
-
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
-
-# PROP Exclude_From_Build 1
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
-
-# PROP Exclude_From_Build 1
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
-
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
-
-# ADD CPP /I "..\.."
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\contrib\masmx86\inffas32.asm
-
-!IF "$(CFG)" == "zlib - Win32 DLL Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_DLL_ASM_Release
-InputPath=..\..\contrib\masmx86\inffas32.asm
-InputName=inffas32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_DLL_ASM_Debug
-InputPath=..\..\contrib\masmx86\inffas32.asm
-InputName=inffas32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_LIB_ASM_Release
-InputPath=..\..\contrib\masmx86\inffas32.asm
-InputName=inffas32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_LIB_ASM_Debug
-InputPath=..\..\contrib\masmx86\inffas32.asm
-InputName=inffas32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ENDIF
-
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=.\README.txt
-# End Source File
-# End Target
-# End Project
diff --git a/cpukit/zlib/projects/visualc6/zlib.dsw b/cpukit/zlib/projects/visualc6/zlib.dsw
deleted file mode 100644
index 3a771fce07..0000000000
--- a/cpukit/zlib/projects/visualc6/zlib.dsw
+++ /dev/null
@@ -1,59 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "example"=.\example.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name zlib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "minigzip"=.\minigzip.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name zlib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "zlib"=.\zlib.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/cpukit/zlib/qnx/package.qpg b/cpukit/zlib/qnx/package.qpg
deleted file mode 100644
index 03cd351740..0000000000
--- a/cpukit/zlib/qnx/package.qpg
+++ /dev/null
@@ -1,141 +0,0 @@
-<QPG:Generation>
- <QPG:Options>
- <QPG:User unattended="no" verbosity="2" listfiles="yes"/>
- <QPG:Defaults type="qnx_package"/>
- <QPG:Source></QPG:Source>
- <QPG:Release number="+"/>
- <QPG:Build></QPG:Build>
- <QPG:FileSorting strip="yes"/>
- <QPG:Package targets="combine"/>
- <QPG:Repository generate="yes"/>
- <QPG:FinalDir></QPG:FinalDir>
- <QPG:Cleanup></QPG:Cleanup>
- </QPG:Options>
-
- <QPG:Responsible>
- <QPG:Company></QPG:Company>
- <QPG:Department></QPG:Department>
- <QPG:Group></QPG:Group>
- <QPG:Team></QPG:Team>
- <QPG:Employee></QPG:Employee>
- <QPG:EmailAddress></QPG:EmailAddress>
- </QPG:Responsible>
-
- <QPG:Values>
- <QPG:Files>
- <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
- <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
- <QPG:Add file="../libz.so.1.2.2.2" install="/opt/lib/" user="root:bin" permission="644"/>
- <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.2.2"/>
- <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.2.2"/>
- <QPG:Add file="../libz.so.1.2.2.2" install="/opt/lib/" component="slib"/>
- </QPG:Files>
-
- <QPG:PackageFilter>
- <QPM:PackageManifest>
- <QPM:PackageDescription>
- <QPM:PackageType>Library</QPM:PackageType>
- <QPM:PackageReleaseNotes></QPM:PackageReleaseNotes>
- <QPM:PackageReleaseUrgency>Medium</QPM:PackageReleaseUrgency>
- <QPM:PackageRepository></QPM:PackageRepository>
- <QPM:FileVersion>2.0</QPM:FileVersion>
- </QPM:PackageDescription>
-
- <QPM:ProductDescription>
- <QPM:ProductName>zlib</QPM:ProductName>
- <QPM:ProductIdentifier>zlib</QPM:ProductIdentifier>
- <QPM:ProductEmail>alain.bonnefoy@icbt.com</QPM:ProductEmail>
- <QPM:VendorName>Public</QPM:VendorName>
- <QPM:VendorInstallName>public</QPM:VendorInstallName>
- <QPM:VendorURL>www.gzip.org/zlib</QPM:VendorURL>
- <QPM:VendorEmbedURL></QPM:VendorEmbedURL>
- <QPM:VendorEmail></QPM:VendorEmail>
- <QPM:AuthorName>Jean-Loup Gailly,Mark Adler</QPM:AuthorName>
- <QPM:AuthorURL>www.gzip.org/zlib</QPM:AuthorURL>
- <QPM:AuthorEmbedURL></QPM:AuthorEmbedURL>
- <QPM:AuthorEmail>zlib@gzip.org</QPM:AuthorEmail>
- <QPM:ProductIconSmall></QPM:ProductIconSmall>
- <QPM:ProductIconLarge></QPM:ProductIconLarge>
- <QPM:ProductDescriptionShort>A massively spiffy yet delicately unobtrusive compression library.</QPM:ProductDescriptionShort>
- <QPM:ProductDescriptionLong>zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system.</QPM:ProductDescriptionLong>
- <QPM:ProductDescriptionURL>http://www.gzip.org/zlib</QPM:ProductDescriptionURL>
- <QPM:ProductDescriptionEmbedURL></QPM:ProductDescriptionEmbedURL>
- </QPM:ProductDescription>
-
- <QPM:ReleaseDescription>
- <QPM:ReleaseVersion>1.2.2.2</QPM:ReleaseVersion>
- <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
- <QPM:ReleaseStability>Stable</QPM:ReleaseStability>
- <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
- <QPM:ReleaseNoteMajor></QPM:ReleaseNoteMajor>
- <QPM:ExcludeCountries>
- <QPM:Country></QPM:Country>
- </QPM:ExcludeCountries>
-
- <QPM:ReleaseCopyright>No License</QPM:ReleaseCopyright>
- </QPM:ReleaseDescription>
-
- <QPM:ContentDescription>
- <QPM:ContentTopic xmlmultiple="true">Software Development/Libraries and Extensions/C Libraries</QPM:ContentTopic>
- <QPM:ContentKeyword>zlib,compression</QPM:ContentKeyword>
- <QPM:TargetOS>qnx6</QPM:TargetOS>
- <QPM:HostOS>qnx6</QPM:HostOS>
- <QPM:DisplayEnvironment xmlmultiple="true">None</QPM:DisplayEnvironment>
- <QPM:TargetAudience xmlmultiple="true">Developer</QPM:TargetAudience>
- </QPM:ContentDescription>
- </QPM:PackageManifest>
- </QPG:PackageFilter>
-
- <QPG:PackageFilter proc="none" target="none">
- <QPM:PackageManifest>
- <QPM:ProductInstallationDependencies>
- <QPM:ProductRequirements></QPM:ProductRequirements>
- </QPM:ProductInstallationDependencies>
-
- <QPM:ProductInstallationProcedure>
- <QPM:Script xmlmultiple="true">
- <QPM:ScriptName></QPM:ScriptName>
- <QPM:ScriptType>Install</QPM:ScriptType>
- <QPM:ScriptTiming>Post</QPM:ScriptTiming>
- <QPM:ScriptBlocking>No</QPM:ScriptBlocking>
- <QPM:ScriptResult>Ignore</QPM:ScriptResult>
- <QPM:ShortDescription></QPM:ShortDescription>
- <QPM:UseBinaries>No</QPM:UseBinaries>
- <QPM:Priority>Optional</QPM:Priority>
- </QPM:Script>
- </QPM:ProductInstallationProcedure>
- </QPM:PackageManifest>
-
- <QPM:Launch>
- </QPM:Launch>
- </QPG:PackageFilter>
-
- <QPG:PackageFilter type="core" component="none">
- <QPM:PackageManifest>
- <QPM:ProductInstallationProcedure>
- <QPM:OrderDependency xmlmultiple="true">
- <QPM:Order>InstallOver</QPM:Order>
- <QPM:Product>zlib</QPM:Product>
- </QPM:OrderDependency>
- </QPM:ProductInstallationProcedure>
- </QPM:PackageManifest>
-
- <QPM:Launch>
- </QPM:Launch>
- </QPG:PackageFilter>
-
- <QPG:PackageFilter type="core" component="dev">
- <QPM:PackageManifest>
- <QPM:ProductInstallationProcedure>
- <QPM:OrderDependency xmlmultiple="true">
- <QPM:Order>InstallOver</QPM:Order>
- <QPM:Product>zlib-dev</QPM:Product>
- </QPM:OrderDependency>
- </QPM:ProductInstallationProcedure>
- </QPM:PackageManifest>
-
- <QPM:Launch>
- </QPM:Launch>
- </QPG:PackageFilter>
- </QPG:Values>
-</QPG:Generation>
diff --git a/cpukit/zlib/trees.c b/cpukit/zlib/trees.c
index 48c651b873..f0b8d1ec38 100644
--- a/cpukit/zlib/trees.c
+++ b/cpukit/zlib/trees.c
@@ -29,7 +29,7 @@
* Addison-Wesley, 1983. ISBN 0-201-06672-6.
*/
-/* @(#) $Id$ */
+/* $Id$ */
/* #define GEN_TREES_H */
diff --git a/cpukit/zlib/uncompr.c b/cpukit/zlib/uncompr.c
index b59e3d0def..fb1202aabe 100644
--- a/cpukit/zlib/uncompr.c
+++ b/cpukit/zlib/uncompr.c
@@ -3,7 +3,7 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id$ */
+/* $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h"
diff --git a/cpukit/zlib/win32/DLL_FAQ.txt b/cpukit/zlib/win32/DLL_FAQ.txt
deleted file mode 100644
index 12c009018c..0000000000
--- a/cpukit/zlib/win32/DLL_FAQ.txt
+++ /dev/null
@@ -1,397 +0,0 @@
-
- Frequently Asked Questions about ZLIB1.DLL
-
-
-This document describes the design, the rationale, and the usage
-of the official DLL build of zlib, named ZLIB1.DLL. If you have
-general questions about zlib, you should see the file "FAQ" found
-in the zlib distribution, or at the following location:
- http://www.gzip.org/zlib/zlib_faq.html
-
-
- 1. What is ZLIB1.DLL, and how can I get it?
-
- - ZLIB1.DLL is the official build of zlib as a DLL.
- (Please remark the character '1' in the name.)
-
- Pointers to a precompiled ZLIB1.DLL can be found in the zlib
- web site at:
- http://www.zlib.net/
-
- Applications that link to ZLIB1.DLL can rely on the following
- specification:
-
- * The exported symbols are exclusively defined in the source
- files "zlib.h" and "zlib.def", found in an official zlib
- source distribution.
- * The symbols are exported by name, not by ordinal.
- * The exported names are undecorated.
- * The calling convention of functions is "C" (CDECL).
- * The ZLIB1.DLL binary is linked to MSVCRT.DLL.
-
- The archive in which ZLIB1.DLL is bundled contains compiled
- test programs that must run with a valid build of ZLIB1.DLL.
- It is recommended to download the prebuilt DLL from the zlib
- web site, instead of building it yourself, to avoid potential
- incompatibilities that could be introduced by your compiler
- and build settings. If you do build the DLL yourself, please
- make sure that it complies with all the above requirements,
- and it runs with the precompiled test programs, bundled with
- the original ZLIB1.DLL distribution.
-
- If, for any reason, you need to build an incompatible DLL,
- please use a different file name.
-
-
- 2. Why did you change the name of the DLL to ZLIB1.DLL?
- What happened to the old ZLIB.DLL?
-
- - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required
- compilation settings that were incompatible to those used by
- a static build. The DLL settings were supposed to be enabled
- by defining the macro ZLIB_DLL, before including "zlib.h".
- Incorrect handling of this macro was silently accepted at
- build time, resulting in two major problems:
-
- * ZLIB_DLL was missing from the old makefile. When building
- the DLL, not all people added it to the build options. In
- consequence, incompatible incarnations of ZLIB.DLL started
- to circulate around the net.
-
- * When switching from using the static library to using the
- DLL, applications had to define the ZLIB_DLL macro and
- to recompile all the sources that contained calls to zlib
- functions. Failure to do so resulted in creating binaries
- that were unable to run with the official ZLIB.DLL build.
-
- The only possible solution that we could foresee was to make
- a binary-incompatible change in the DLL interface, in order to
- remove the dependency on the ZLIB_DLL macro, and to release
- the new DLL under a different name.
-
- We chose the name ZLIB1.DLL, where '1' indicates the major
- zlib version number. We hope that we will not have to break
- the binary compatibility again, at least not as long as the
- zlib-1.x series will last.
-
- There is still a ZLIB_DLL macro, that can trigger a more
- efficient build and use of the DLL, but compatibility no
- longer dependents on it.
-
-
- 3. Can I build ZLIB.DLL from the new zlib sources, and replace
- an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier?
-
- - In principle, you can do it by assigning calling convention
- keywords to the macros ZEXPORT and ZEXPORTVA. In practice,
- it depends on what you mean by "an old ZLIB.DLL", because the
- old DLL exists in several mutually-incompatible versions.
- You have to find out first what kind of calling convention is
- being used in your particular ZLIB.DLL build, and to use the
- same one in the new build. If you don't know what this is all
- about, you might be better off if you would just leave the old
- DLL intact.
-
-
- 4. Can I compile my application using the new zlib interface, and
- link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or
- earlier?
-
- - The official answer is "no"; the real answer depends again on
- what kind of ZLIB.DLL you have. Even if you are lucky, this
- course of action is unreliable.
-
- If you rebuild your application and you intend to use a newer
- version of zlib (post- 1.1.4), it is strongly recommended to
- link it to the new ZLIB1.DLL.
-
-
- 5. Why are the zlib symbols exported by name, and not by ordinal?
-
- - Although exporting symbols by ordinal is a little faster, it
- is risky. Any single glitch in the maintenance or use of the
- DEF file that contains the ordinals can result in incompatible
- builds and frustrating crashes. Simply put, the benefits of
- exporting symbols by ordinal do not justify the risks.
-
- Technically, it should be possible to maintain ordinals in
- the DEF file, and still export the symbols by name. Ordinals
- exist in every DLL, and even if the dynamic linking performed
- at the DLL startup is searching for names, ordinals serve as
- hints, for a faster name lookup. However, if the DEF file
- contains ordinals, the Microsoft linker automatically builds
- an implib that will cause the executables linked to it to use
- those ordinals, and not the names. It is interesting to
- notice that the GNU linker for Win32 does not suffer from this
- problem.
-
- It is possible to avoid the DEF file if the exported symbols
- are accompanied by a "__declspec(dllexport)" attribute in the
- source files. You can do this in zlib by predefining the
- ZLIB_DLL macro.
-
-
- 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling
- convention. Why not use the STDCALL convention?
- STDCALL is the standard convention in Win32, and I need it in
- my Visual Basic project!
-
- (For readability, we use CDECL to refer to the convention
- triggered by the "__cdecl" keyword, STDCALL to refer to
- the convention triggered by "__stdcall", and FASTCALL to
- refer to the convention triggered by "__fastcall".)
-
- - Most of the native Windows API functions (without varargs) use
- indeed the WINAPI convention (which translates to STDCALL in
- Win32), but the standard C functions use CDECL. If a user
- application is intrinsically tied to the Windows API (e.g.
- it calls native Windows API functions such as CreateFile()),
- sometimes it makes sense to decorate its own functions with
- WINAPI. But if ANSI C or POSIX portability is a goal (e.g.
- it calls standard C functions such as fopen()), it is not a
- sound decision to request the inclusion of <windows.h>, or to
- use non-ANSI constructs, for the sole purpose to make the user
- functions STDCALL-able.
-
- The functionality offered by zlib is not in the category of
- "Windows functionality", but is more like "C functionality".
-
- Technically, STDCALL is not bad; in fact, it is slightly
- faster than CDECL, and it works with variable-argument
- functions, just like CDECL. It is unfortunate that, in spite
- of using STDCALL in the Windows API, it is not the default
- convention used by the C compilers that run under Windows.
- The roots of the problem reside deep inside the unsafety of
- the K&R-style function prototypes, where the argument types
- are not specified; but that is another story for another day.
-
- The remaining fact is that CDECL is the default convention.
- Even if an explicit convention is hard-coded into the function
- prototypes inside C headers, problems may appear. The
- necessity to expose the convention in users' callbacks is one
- of these problems.
-
- The calling convention issues are also important when using
- zlib in other programming languages. Some of them, like Ada
- (GNAT) and Fortran (GNU G77), have C bindings implemented
- initially on Unix, and relying on the C calling convention.
- On the other hand, the pre- .NET versions of Microsoft Visual
- Basic require STDCALL, while Borland Delphi prefers, although
- it does not require, FASTCALL.
-
- In fairness to all possible uses of zlib outside the C
- programming language, we choose the default "C" convention.
- Anyone interested in different bindings or conventions is
- encouraged to maintain specialized projects. The "contrib/"
- directory from the zlib distribution already holds a couple
- of foreign bindings, such as Ada, C++, and Delphi.
-
-
- 7. I need a DLL for my Visual Basic project. What can I do?
-
- - Define the ZLIB_WINAPI macro before including "zlib.h", when
- building both the DLL and the user application (except that
- you don't need to define anything when using the DLL in Visual
- Basic). The ZLIB_WINAPI macro will switch on the WINAPI
- (STDCALL) convention. The name of this DLL must be different
- than the official ZLIB1.DLL.
-
- Gilles Vollant has contributed a build named ZLIBWAPI.DLL,
- with the ZLIB_WINAPI macro turned on, and with the minizip
- functionality built in. For more information, please read
- the notes inside "contrib/vstudio/readme.txt", found in the
- zlib distribution.
-
-
- 8. I need to use zlib in my Microsoft .NET project. What can I
- do?
-
- - Henrik Ravn has contributed a .NET wrapper around zlib. Look
- into contrib/dotzlib/, inside the zlib distribution.
-
-
- 9. If my application uses ZLIB1.DLL, should I link it to
- MSVCRT.DLL? Why?
-
- - It is not required, but it is recommended to link your
- application to MSVCRT.DLL, if it uses ZLIB1.DLL.
-
- The executables (.EXE, .DLL, etc.) that are involved in the
- same process and are using the C run-time library (i.e. they
- are calling standard C functions), must link to the same
- library. There are several libraries in the Win32 system:
- CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc.
- Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that
- depend on it should also be linked to MSVCRT.DLL.
-
-
-10. Why are you saying that ZLIB1.DLL and my application should
- be linked to the same C run-time (CRT) library? I linked my
- application and my DLLs to different C libraries (e.g. my
- application to a static library, and my DLLs to MSVCRT.DLL),
- and everything works fine.
-
- - If a user library invokes only pure Win32 API (accessible via
- <windows.h> and the related headers), its DLL build will work
- in any context. But if this library invokes standard C API,
- things get more complicated.
-
- There is a single Win32 library in a Win32 system. Every
- function in this library resides in a single DLL module, that
- is safe to call from anywhere. On the other hand, there are
- multiple versions of the C library, and each of them has its
- own separate internal state. Standalone executables and user
- DLLs that call standard C functions must link to a C run-time
- (CRT) library, be it static or shared (DLL). Intermixing
- occurs when an executable (not necessarily standalone) and a
- DLL are linked to different CRTs, and both are running in the
- same process.
-
- Intermixing multiple CRTs is possible, as long as their
- internal states are kept intact. The Microsoft Knowledge Base
- articles KB94248 "HOWTO: Use the C Run-Time" and KB140584
- "HOWTO: Link with the Correct C Run-Time (CRT) Library"
- mention the potential problems raised by intermixing.
-
- If intermixing works for you, it's because your application
- and DLLs are avoiding the corruption of each of the CRTs'
- internal states, maybe by careful design, or maybe by fortune.
-
- Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such
- as those provided by Borland, raises similar problems.
-
-
-11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?
-
- - MSVCRT.DLL exists on every Windows 95 with a new service pack
- installed, or with Microsoft Internet Explorer 4 or later, and
- on all other Windows 4.x or later (Windows 98, Windows NT 4,
- or later). It is freely distributable; if not present in the
- system, it can be downloaded from Microsoft or from other
- software provider for free.
-
- The fact that MSVCRT.DLL does not exist on a virgin Windows 95
- is not so problematic. Windows 95 is scarcely found nowadays,
- Microsoft ended its support a long time ago, and many recent
- applications from various vendors, including Microsoft, do not
- even run on it. Furthermore, no serious user should run
- Windows 95 without a proper update installed.
-
-
-12. Why are you not linking ZLIB1.DLL to
- <<my favorite C run-time library>> ?
-
- - We considered and abandoned the following alternatives:
-
- * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or
- LIBCMT.LIB) is not a good option. People are using the DLL
- mainly to save disk space. If you are linking your program
- to a static C library, you may as well consider linking zlib
- in statically, too.
-
- * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because
- CRTDLL.DLL is present on every Win32 installation.
- Unfortunately, it has a series of problems: it does not
- work properly with Microsoft's C++ libraries, it does not
- provide support for 64-bit file offsets, (and so on...),
- and Microsoft discontinued its support a long time ago.
-
- * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied
- with the Microsoft .NET platform, and Visual C++ 7.0/7.1,
- raises problems related to the status of ZLIB1.DLL as a
- system component. According to the Microsoft Knowledge Base
- article KB326922 "INFO: Redistribution of the Shared C
- Runtime Component in Visual C++ .NET", MSVCR70.DLL and
- MSVCR71.DLL are not supposed to function as system DLLs,
- because they may clash with MSVCRT.DLL. Instead, the
- application's installer is supposed to put these DLLs
- (if needed) in the application's private directory.
- If ZLIB1.DLL depends on a non-system runtime, it cannot
- function as a redistributable system component.
-
- * Linking ZLIB1.DLL to non-Microsoft runtimes, such as
- Borland's, or Cygwin's, raises problems related to the
- reliable presence of these runtimes on Win32 systems.
- It's easier to let the DLL build of zlib up to the people
- who distribute these runtimes, and who may proceed as
- explained in the answer to Question 14.
-
-
-13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL,
- how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0
- (Visual Studio .NET) or newer?
-
- - Due to the problems explained in the Microsoft Knowledge Base
- article KB326922 (see the previous answer), the C runtime that
- comes with the VC7 environment is no longer considered a
- system component. That is, it should not be assumed that this
- runtime exists, or may be installed in a system directory.
- Since ZLIB1.DLL is supposed to be a system component, it may
- not depend on a non-system component.
-
- In order to link ZLIB1.DLL and your application to MSVCRT.DLL
- in VC7, you need the library of Visual C++ 6.0 or older. If
- you don't have this library at hand, it's probably best not to
- use ZLIB1.DLL.
-
- We are hoping that, in the future, Microsoft will provide a
- way to build applications linked to a proper system runtime,
- from the Visual C++ environment. Until then, you have a
- couple of alternatives, such as linking zlib in statically.
- If your application requires dynamic linking, you may proceed
- as explained in the answer to Question 14.
-
-
-14. I need to link my own DLL build to a CRT different than
- MSVCRT.DLL. What can I do?
-
- - Feel free to rebuild the DLL from the zlib sources, and link
- it the way you want. You should, however, clearly state that
- your build is unofficial. You should give it a different file
- name, and/or install it in a private directory that can be
- accessed by your application only, and is not visible to the
- others (i.e. it's neither in the PATH, nor in the SYSTEM or
- SYSTEM32 directories). Otherwise, your build may clash with
- applications that link to the official build.
-
- For example, in Cygwin, zlib is linked to the Cygwin runtime
- CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.
-
-
-15. May I include additional pieces of code that I find useful,
- link them in ZLIB1.DLL, and export them?
-
- - No. A legitimate build of ZLIB1.DLL must not include code
- that does not originate from the official zlib source code.
- But you can make your own private DLL build, under a different
- file name, as suggested in the previous answer.
-
- For example, zlib is a part of the VCL library, distributed
- with Borland Delphi and C++ Builder. The DLL build of VCL
- is a redistributable file, named VCLxx.DLL.
-
-
-16. May I remove some functionality out of ZLIB1.DLL, by enabling
- macros like NO_GZCOMPRESS or NO_GZIP at compile time?
-
- - No. A legitimate build of ZLIB1.DLL must provide the complete
- zlib functionality, as implemented in the official zlib source
- code. But you can make your own private DLL build, under a
- different file name, as suggested in the previous answer.
-
-
-17. I made my own ZLIB1.DLL build. Can I test it for compliance?
-
- - We prefer that you download the official DLL from the zlib
- web site. If you need something peculiar from this DLL, you
- can send your suggestion to the zlib mailing list.
-
- However, in case you do rebuild the DLL yourself, you can run
- it with the test programs found in the DLL distribution.
- Running these test programs is not a guarantee of compliance,
- but a failure can imply a detected problem.
-
-**
-
-This document is written and maintained by
-Cosmin Truta <cosmint@cs.ubbcluj.ro>
diff --git a/cpukit/zlib/win32/Makefile.bor b/cpukit/zlib/win32/Makefile.bor
deleted file mode 100644
index b802519ca3..0000000000
--- a/cpukit/zlib/win32/Makefile.bor
+++ /dev/null
@@ -1,107 +0,0 @@
-# Makefile for zlib
-# Borland C++ for Win32
-#
-# Updated for zlib 1.2.x by Cosmin Truta, 11-Mar-2003
-# Last updated: 28-Aug-2003
-#
-# Usage:
-# make -f win32/Makefile.bor
-# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj
-
-# ------------ Borland C++ ------------
-
-# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
-# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or
-# added to the declaration of LOC here:
-LOC = $(LOCAL_ZLIB)
-
-CC = bcc32
-AS = bcc32
-LD = bcc32
-AR = tlib
-CFLAGS = -a -d -k- -O2 $(LOC)
-ASFLAGS = $(LOC)
-LDFLAGS = $(LOC)
-
-
-# variables
-ZLIB_LIB = zlib.lib
-
-OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
-OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
-#OBJA =
-OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infback.obj
-OBJP2 = +inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
-#OBJPA=
-
-
-# targets
-all: $(ZLIB_LIB) example.exe minigzip.exe
-
-.c.obj:
- $(CC) -c $(CFLAGS) $<
-
-.asm.obj:
- $(AS) -c $(ASFLAGS) $<
-
-adler32.obj: adler32.c zlib.h zconf.h
-
-compress.obj: compress.c zlib.h zconf.h
-
-crc32.obj: crc32.c zlib.h zconf.h crc32.h
-
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
-
-gzio.obj: gzio.c zutil.h zlib.h zconf.h
-
-infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h
-
-inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
-
-trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
-
-uncompr.obj: uncompr.c zlib.h zconf.h
-
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
-
-example.obj: example.c zlib.h zconf.h
-
-minigzip.obj: minigzip.c zlib.h zconf.h
-
-
-# For the sake of the old Borland make,
-# the command line is cut to fit in the MS-DOS 128 byte limit:
-$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA)
- -del $(ZLIB_LIB)
- $(AR) $(ZLIB_LIB) $(OBJP1)
- $(AR) $(ZLIB_LIB) $(OBJP2)
- $(AR) $(ZLIB_LIB) $(OBJPA)
-
-
-# testing
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-example.exe: example.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
-
-minigzip.exe: minigzip.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
-
-
-# cleanup
-clean:
- -del *.obj
- -del *.lib
- -del *.exe
- -del *.tds
- -del zlib.bak
- -del foo.gz
diff --git a/cpukit/zlib/win32/Makefile.emx b/cpukit/zlib/win32/Makefile.emx
deleted file mode 100644
index 7b08424ced..0000000000
--- a/cpukit/zlib/win32/Makefile.emx
+++ /dev/null
@@ -1,69 +0,0 @@
-# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98.
-# Copyright (C) 1995-1998 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile, or to compile and test, type:
-#
-# make -fmakefile.emx; make test -fmakefile.emx
-#
-
-CC=gcc -Zwin32
-
-#CFLAGS=-MMD -O
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-MMD -g -DDEBUG
-CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
- -Wstrict-prototypes -Wmissing-prototypes
-
-# If cp.exe is available, replace "copy /Y" with "cp -fp" .
-CP=copy /Y
-# If gnu install.exe is available, replace $(CP) with ginstall.
-INSTALL=$(CP)
-# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
-RM=del
-LDLIBS=-L. -lzlib
-LD=$(CC) -s -o
-LDSHARED=$(CC)
-
-INCL=zlib.h zconf.h
-LIBS=zlib.a
-
-AR=ar rcs
-
-prefix=/usr/local
-exec_prefix = $(prefix)
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infback.o inftrees.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example.exe minigzip.exe
-
-test: all
- ./example
- echo hello world | .\minigzip | .\minigzip -d
-
-%.o : %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-zlib.a: $(OBJS)
- $(AR) $@ $(OBJS)
-
-%.exe : %.o $(LIBS)
- $(LD) $@ $< $(LDLIBS)
-
-
-.PHONY : clean
-
-clean:
- $(RM) *.d
- $(RM) *.o
- $(RM) *.exe
- $(RM) zlib.a
- $(RM) foo.gz
-
-DEPS := $(wildcard *.d)
-ifneq ($(DEPS),)
-include $(DEPS)
-endif
diff --git a/cpukit/zlib/win32/Makefile.gcc b/cpukit/zlib/win32/Makefile.gcc
deleted file mode 100644
index 62a8430156..0000000000
--- a/cpukit/zlib/win32/Makefile.gcc
+++ /dev/null
@@ -1,141 +0,0 @@
-# Makefile for zlib, derived from Makefile.dj2.
-# Modified for mingw32 by C. Spieler, 6/16/98.
-# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.
-# Last updated: 1-Aug-2003.
-# Tested under Cygwin and MinGW.
-
-# Copyright (C) 1995-2003 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile, or to compile and test, type:
-#
-# make -fmakefile.gcc; make test testdll -fmakefile.gcc
-#
-# To use the asm code, type:
-# cp contrib/asm?86/match.S ./match.S
-# make LOC=-DASMV OBJA=match.o -fmakefile.gcc
-#
-# To install libz.a, zconf.h and zlib.h in the system directories, type:
-#
-# make install -fmakefile.gcc
-
-# Note:
-# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),
-# the DLL name should be changed from "zlib1.dll".
-
-STATICLIB = libz.a
-SHAREDLIB = zlib1.dll
-IMPLIB = libzdll.a
-
-#LOC = -DASMV
-#LOC = -DDEBUG -g
-
-CC = gcc
-CFLAGS = $(LOC) -O3 -Wall
-
-AS = $(CC)
-ASFLAGS = $(LOC) -Wall
-
-LD = $(CC)
-LDFLAGS = $(LOC) -s
-
-AR = ar
-ARFLAGS = rcs
-
-RC = windres
-RCFLAGS = --define GCC_WINDRES
-
-CP = cp -fp
-# If GNU install is available, replace $(CP) with install.
-INSTALL = $(CP)
-RM = rm -f
-
-prefix = /usr/local
-exec_prefix = $(prefix)
-
-OBJS = adler32.o compress.o crc32.o deflate.o gzio.o infback.o \
- inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
-OBJA =
-
-all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example minigzip example_d minigzip_d
-
-test: example minigzip
- ./example
- echo hello world | ./minigzip | ./minigzip -d
-
-testdll: example_d minigzip_d
- ./example_d
- echo hello world | ./minigzip_d | ./minigzip_d -d
-
-.c.o:
- $(CC) $(CFLAGS) -c -o $@ $<
-
-.S.o:
- $(AS) $(ASFLAGS) -c -o $@ $<
-
-$(STATICLIB): $(OBJS) $(OBJA)
- $(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA)
-
-$(IMPLIB): $(SHAREDLIB)
-
-$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
- dllwrap --driver-name $(CC) --def win32/zlib.def \
- --implib $(IMPLIB) -o $@ $(OBJS) $(OBJA) zlibrc.o
- strip $@
-
-example: example.o $(STATICLIB)
- $(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB)
-
-minigzip: minigzip.o $(STATICLIB)
- $(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB)
-
-example_d: example.o $(IMPLIB)
- $(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB)
-
-minigzip_d: minigzip.o $(IMPLIB)
- $(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB)
-
-zlibrc.o: win32/zlib1.rc
- $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc
-
-
-# INCLUDE_PATH and LIBRARY_PATH must be set.
-
-.PHONY: install uninstall clean
-
-install: zlib.h zconf.h $(LIB)
- -@if not exist $(INCLUDE_PATH)/nul mkdir $(INCLUDE_PATH)
- -@if not exist $(LIBRARY_PATH)/nul mkdir $(LIBRARY_PATH)
- -$(INSTALL) zlib.h $(INCLUDE_PATH)
- -$(INSTALL) zconf.h $(INCLUDE_PATH)
- -$(INSTALL) $(STATICLIB) $(LIBRARY_PATH)
- -$(INSTALL) $(IMPLIB) $(LIBRARY_PATH)
-
-uninstall:
- -$(RM) $(INCLUDE_PATH)/zlib.h
- -$(RM) $(INCLUDE_PATH)/zconf.h
- -$(RM) $(LIBRARY_PATH)/$(STATICLIB)
- -$(RM) $(LIBRARY_PATH)/$(IMPLIB)
-
-clean:
- -$(RM) $(STATICLIB)
- -$(RM) $(SHAREDLIB)
- -$(RM) $(IMPLIB)
- -$(RM) *.o
- -$(RM) *.exe
- -$(RM) foo.gz
-
-adler32.o: zlib.h zconf.h
-compress.o: zlib.h zconf.h
-crc32.o: crc32.h zlib.h zconf.h
-deflate.o: deflate.h zutil.h zlib.h zconf.h
-example.o: zlib.h zconf.h
-gzio.o: zutil.h zlib.h zconf.h
-inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
-inftrees.o: zutil.h zlib.h zconf.h inftrees.h
-minigzip.o: zlib.h zconf.h
-trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
-uncompr.o: zlib.h zconf.h
-zutil.o: zutil.h zlib.h zconf.h
diff --git a/cpukit/zlib/win32/Makefile.msc b/cpukit/zlib/win32/Makefile.msc
deleted file mode 100644
index 528ecaaf24..0000000000
--- a/cpukit/zlib/win32/Makefile.msc
+++ /dev/null
@@ -1,126 +0,0 @@
-# Makefile for zlib -- Microsoft (Visual) C
-#
-# Authors:
-# Cosmin Truta, 11-Mar-2003
-# Christian Spieler, 19-Mar-2003
-#
-# Last updated:
-# Cosmin Truta, 27-Aug-2003
-#
-# Usage:
-# nmake -f win32/Makefile.msc (standard build)
-# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build)
-# nmake -f win32/Makefile.msc LOC=-DASMV OBJA=match.obj (use ASM code)
-
-
-# optional build flags
-LOC =
-
-
-# variables
-STATICLIB = zlib.lib
-SHAREDLIB = zlib1.dll
-IMPLIB = zdll.lib
-
-CC = cl
-AS = ml
-LD = link
-AR = lib
-RC = rc
-CFLAGS = -nologo -MD -O2 $(LOC)
-ASFLAGS = -coff
-LDFLAGS = -nologo -release
-ARFLAGS = -nologo
-RCFLAGS = /dWIN32 /r
-
-OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj \
- inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
-OBJA =
-
-
-# targets
-all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
- example.exe minigzip.exe example_d.exe minigzip_d.exe
-
-$(STATICLIB): $(OBJS) $(OBJA)
- $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA)
-
-$(IMPLIB): $(SHAREDLIB)
-
-$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlib1.res
- $(LD) $(LDFLAGS) -def:win32/zlib.def -dll -implib:$(IMPLIB) \
- -out:$@ $(OBJS) $(OBJA) zlib1.res
-
-example.exe: example.obj $(STATICLIB)
- $(LD) $(LDFLAGS) example.obj $(STATICLIB)
-
-minigzip.exe: minigzip.obj $(STATICLIB)
- $(LD) $(LDFLAGS) minigzip.obj $(STATICLIB)
-
-example_d.exe: example.obj $(IMPLIB)
- $(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB)
-
-minigzip_d.exe: minigzip.obj $(IMPLIB)
- $(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB)
-
-.c.obj:
- $(CC) -c $(CFLAGS) $<
-
-.asm.obj:
- $(AS) -c $(ASFLAGS) $<
-
-adler32.obj: adler32.c zlib.h zconf.h
-
-compress.obj: compress.c zlib.h zconf.h
-
-crc32.obj: crc32.c zlib.h zconf.h crc32.h
-
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
-
-gzio.obj: gzio.c zutil.h zlib.h zconf.h
-
-infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h
-
-inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
-
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
-
-trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
-
-uncompr.obj: uncompr.c zlib.h zconf.h
-
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
-
-example.obj: example.c zlib.h zconf.h
-
-minigzip.obj: minigzip.c zlib.h zconf.h
-
-zlib1.res: win32/zlib1.rc
- $(RC) $(RCFLAGS) /fo$@ win32/zlib1.rc
-
-
-# testing
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-testdll: example_d.exe minigzip_d.exe
- example_d
- echo hello world | minigzip_d | minigzip_d -d
-
-
-# cleanup
-clean:
- -del $(STATICLIB)
- -del $(SHAREDLIB)
- -del $(IMPLIB)
- -del *.obj
- -del *.res
- -del *.exp
- -del *.exe
- -del foo.gz
diff --git a/cpukit/zlib/win32/VisualC.txt b/cpukit/zlib/win32/VisualC.txt
deleted file mode 100644
index 579a5fc9e0..0000000000
--- a/cpukit/zlib/win32/VisualC.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-
-To build zlib using the Microsoft Visual C++ environment,
-use the appropriate project from the projects/ directory.
diff --git a/cpukit/zlib/win32/zlib.def b/cpukit/zlib/win32/zlib.def
deleted file mode 100644
index a47cbc10ca..0000000000
--- a/cpukit/zlib/win32/zlib.def
+++ /dev/null
@@ -1,60 +0,0 @@
-LIBRARY
-; zlib data compression library
-
-EXPORTS
-; basic functions
- zlibVersion
- deflate
- deflateEnd
- inflate
- inflateEnd
-; advanced functions
- deflateSetDictionary
- deflateCopy
- deflateReset
- deflateParams
- deflateBound
- deflatePrime
- inflateSetDictionary
- inflateSync
- inflateCopy
- inflateReset
- inflateBack
- inflateBackEnd
- zlibCompileFlags
-; utility functions
- compress
- compress2
- compressBound
- uncompress
- gzopen
- gzdopen
- gzsetparams
- gzread
- gzwrite
- gzprintf
- gzputs
- gzgets
- gzputc
- gzgetc
- gzungetc
- gzflush
- gzseek
- gzrewind
- gztell
- gzeof
- gzclose
- gzerror
- gzclearerr
-; checksum functions
- adler32
- crc32
-; various hacks, don't look :)
- deflateInit_
- deflateInit2_
- inflateInit_
- inflateInit2_
- inflateBackInit_
- inflateSyncPoint
- get_crc_table
- zError
diff --git a/cpukit/zlib/win32/zlib1.rc b/cpukit/zlib/win32/zlib1.rc
deleted file mode 100644
index 1d37694060..0000000000
--- a/cpukit/zlib/win32/zlib1.rc
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <windows.h>
-
-#ifdef GCC_WINDRES
-VS_VERSION_INFO VERSIONINFO
-#else
-VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
-#endif
- FILEVERSION 1,2,2,2
- PRODUCTVERSION 1,2,2,2
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
-#ifdef _DEBUG
- FILEFLAGS 1
-#else
- FILEFLAGS 0
-#endif
- FILEOS VOS_DOS_WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0 // not used
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904E4"
- //language ID = U.S. English, char set = Windows, Multilingual
- BEGIN
- VALUE "FileDescription", "zlib data compression library\0"
- VALUE "FileVersion", "1.2.2.2\0"
- VALUE "InternalName", "zlib1.dll\0"
- VALUE "LegalCopyright", "(C) 1995-2004 Jean-loup Gailly & Mark Adler\0"
- VALUE "OriginalFilename", "zlib1.dll\0"
- VALUE "ProductName", "zlib\0"
- VALUE "ProductVersion", "1.2.2.2\0"
- VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x0409, 1252
- END
-END
diff --git a/cpukit/zlib/zconf.h b/cpukit/zlib/zconf.h
index 6897bf0235..1060bcdc69 100644
--- a/cpukit/zlib/zconf.h
+++ b/cpukit/zlib/zconf.h
@@ -3,11 +3,13 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id$ */
+/* $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
+#define Z_PREFIX 1
+
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
@@ -255,11 +257,20 @@
# define FAR
#endif
+#if defined(__rtems__)
+#include <rtems/stdint.h>
+
+typedef uint_least8_t Byte;
+typedef uint_least16_t uInt;
+typedef uint_least32_t uLong;
+
+#else
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
+#endif
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
@@ -282,7 +293,7 @@ typedef uLong FAR uLongf;
typedef Byte *voidp;
#endif
-#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
+#if 1 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
diff --git a/cpukit/zlib/zconf.in.h b/cpukit/zlib/zconf.in.h
deleted file mode 100644
index 6897bf0235..0000000000
--- a/cpukit/zlib/zconf.in.h
+++ /dev/null
@@ -1,330 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2004 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZCONF_H
-#define ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
-#ifdef Z_PREFIX
-# define deflateInit_ z_deflateInit_
-# define deflate z_deflate
-# define deflateEnd z_deflateEnd
-# define inflateInit_ z_inflateInit_
-# define inflate z_inflate
-# define inflateEnd z_inflateEnd
-# define deflateInit2_ z_deflateInit2_
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateCopy z_deflateCopy
-# define deflateReset z_deflateReset
-# define deflateParams z_deflateParams
-# define deflateBound z_deflateBound
-# define deflatePrime z_deflatePrime
-# define inflateInit2_ z_inflateInit2_
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateSyncPoint z_inflateSyncPoint
-# define inflateCopy z_inflateCopy
-# define inflateReset z_inflateReset
-# define inflateBack z_inflateBack
-# define inflateBackEnd z_inflateBackEnd
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
-# define uncompress z_uncompress
-# define adler32 z_adler32
-# define crc32 z_crc32
-# define get_crc_table z_get_crc_table
-# define zError z_zError
-
-# define alloc_func z_alloc_func
-# define free_func z_free_func
-# define in_func z_in_func
-# define out_func z_out_func
-# define Byte z_Byte
-# define uInt z_uInt
-# define uLong z_uLong
-# define Bytef z_Bytef
-# define charf z_charf
-# define intf z_intf
-# define uIntf z_uIntf
-# define uLongf z_uLongf
-# define voidpf z_voidpf
-# define voidp z_voidp
-#endif
-
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#endif
-#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
-# define OS2
-#endif
-#if defined(_WINDOWS) && !defined(WINDOWS)
-# define WINDOWS
-#endif
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-# define WIN32
-#endif
-#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
-# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
-# ifndef SYS16BIT
-# define SYS16BIT
-# endif
-# endif
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#ifdef SYS16BIT
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#ifdef __STDC_VERSION__
-# ifndef STDC
-# define STDC
-# endif
-# if __STDC_VERSION__ >= 199901L
-# ifndef STDC99
-# define STDC99
-# endif
-# endif
-#endif
-#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
-# define STDC
-#endif
-
-#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
-# define STDC
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const /* note: need a more gentle solution here */
-# endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
-# define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- (1 << (windowBits+2)) + (1 << (memLevel+9))
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#ifdef SYS16BIT
-# if defined(M_I86SM) || defined(M_I86MM)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-# if (defined(__SMALL__) || defined(__MEDIUM__))
- /* Turbo C small or medium model */
-# define SMALL_MEDIUM
-# ifdef __BORLANDC__
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-#endif
-
-#if defined(WINDOWS) || defined(WIN32)
- /* If building or using zlib as a DLL, define ZLIB_DLL.
- * This is not mandatory, but it offers a little performance increase.
- */
-# ifdef ZLIB_DLL
-# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
-# ifdef ZLIB_INTERNAL
-# define ZEXTERN extern __declspec(dllexport)
-# else
-# define ZEXTERN extern __declspec(dllimport)
-# endif
-# endif
-# endif /* ZLIB_DLL */
- /* If building or using zlib with the WINAPI/WINAPIV calling convention,
- * define ZLIB_WINAPI.
- * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
- */
-# ifdef ZLIB_WINAPI
-# ifdef FAR
-# undef FAR
-# endif
-# include <windows.h>
- /* No need for _export, use ZLIB.DEF instead. */
- /* For complete Windows compatibility, use WINAPI, not __stdcall. */
-# define ZEXPORT WINAPI
-# ifdef WIN32
-# define ZEXPORTVA WINAPIV
-# else
-# define ZEXPORTVA FAR CDECL
-# endif
-# endif
-#endif
-
-#if defined (__BEOS__)
-# ifdef ZLIB_DLL
-# ifdef ZLIB_INTERNAL
-# define ZEXPORT __declspec(dllexport)
-# define ZEXPORTVA __declspec(dllexport)
-# else
-# define ZEXPORT __declspec(dllimport)
-# define ZEXPORTVA __declspec(dllimport)
-# endif
-# endif
-#endif
-
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-#if !defined(__MACTYPES__)
-typedef unsigned char Byte; /* 8 bits */
-#endif
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-#ifdef SMALL_MEDIUM
- /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-# define Bytef Byte FAR
-#else
- typedef Byte FAR Bytef;
-#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void const *voidpc;
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte const *voidpc;
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
-# include <sys/types.h> /* for off_t */
-# include <unistd.h> /* for SEEK_* and off_t */
-# ifdef VMS
-# include <unixio.h> /* for off_t */
-# endif
-# define z_off_t off_t
-#endif
-#ifndef SEEK_SET
-# define SEEK_SET 0 /* Seek from beginning of file. */
-# define SEEK_CUR 1 /* Seek from current position. */
-# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-#endif
-#ifndef z_off_t
-# define z_off_t long
-#endif
-
-#if defined(__OS400__)
-# define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-# define NO_vsnprintf
-# ifdef FAR
-# undef FAR
-# endif
-#endif
-
-/* MVS linker does not support external names larger than 8 bytes */
-#if defined(__MVS__)
-# pragma map(deflateInit_,"DEIN")
-# pragma map(deflateInit2_,"DEIN2")
-# pragma map(deflateEnd,"DEEND")
-# pragma map(deflateBound,"DEBND")
-# pragma map(inflateInit_,"ININ")
-# pragma map(inflateInit2_,"ININ2")
-# pragma map(inflateEnd,"INEND")
-# pragma map(inflateSync,"INSY")
-# pragma map(inflateSetDictionary,"INSEDI")
-# pragma map(compressBound,"CMBND")
-# pragma map(inflate_table,"INTABL")
-# pragma map(inflate_fast,"INFA")
-# pragma map(inflate_copyright,"INCOPY")
-#endif
-
-#endif /* ZCONF_H */
diff --git a/cpukit/zlib/zutil.c b/cpukit/zlib/zutil.c
index 868d42f70d..c7e14bf9fd 100644
--- a/cpukit/zlib/zutil.c
+++ b/cpukit/zlib/zutil.c
@@ -3,7 +3,7 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id$ */
+/* $Id$ */
#include "zutil.h"
@@ -299,8 +299,8 @@ extern void free OF((voidpf ptr));
voidpf zcalloc (opaque, items, size)
voidpf opaque;
- unsigned items;
- unsigned size;
+ uInt items;
+ uInt size;
{
if (opaque) items += size - size; /* make compiler happy */
return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
diff --git a/cpukit/zlib/zutil.h b/cpukit/zlib/zutil.h
index 5209d656cd..601aeb2ccf 100644
--- a/cpukit/zlib/zutil.h
+++ b/cpukit/zlib/zutil.h
@@ -8,7 +8,7 @@
subject to change. Applications should only use zlib.h.
*/
-/* @(#) $Id$ */
+/* $Id$ */
#ifndef ZUTIL_H
#define ZUTIL_H
@@ -251,7 +251,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#endif
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+voidpf zcalloc OF((voidpf opaque, uInt items, uInt size));
void zcfree OF((voidpf opaque, voidpf ptr));
#define ZALLOC(strm, items, size) \