Filewatcher File Search
FTP Search
  
Directory (beta)
  
Content Search (beta)
   
pkg://wampes-991216-485.src.rpm:461420/wampes-991216.tar.gz  info  downloads

HPUX.R000064400010220000764000000103440620342153100117170ustar00deykembo00000000000000_abort			_XOPEN$abort
_access			_$access
_alarm			_$alarm
___assert		_XOPEN$__assert
_catclose		_$catclose
_catgets		_$catgets
_catopen		_$catopen
_cfgetispeed		_$cfgetispeed
_cfgetospeed		_$cfgetospeed
_cfsetispeed		_$cfsetispeed
_cfsetospeed		_$cfsetospeed
_chdir			_$chdir
_chmod			_$chmod
_chown			_$chown
_chroot			_$chroot
_clock			_XOPEN$clock
_close			_$close
_closedir		_$closedir
_creat			_$creat
_crypt			_$crypt
_ctermid		_$ctermid
_cuserid		_$cuserid
_daylight		_XOPEN$daylight
_drand48		_$drand48
__dstzone		_XOPEN$_dstzone
_dup			_$dup
_dup2			_$dup2
_encrypt		_$encrypt
_environ		_$environ
_erand48		_$erand48
_execl			_$execl
_execle			_$execle
_execlp			_$execlp
_execv			_$execv
_execve			_$execve
_execvp			_$execvp
_exit			_XOPEN$exit
_fcntl			_$fcntl
_fdopen			_$fdopen
_fileno			_$fileno
_fork			_$fork
_fpathconf		_$fpathconf
_fstat			_$fstat
_fsync			_$fsync
_ftw			_$ftw
_getcwd			_$getcwd
_getegid		_$getegid
_geteuid		_$geteuid
_getgid			_$getgid
_getgrgid		_$getgrgid
_getgrnam		_$getgrnam
_getgroups		_$getgroups
_getlogin		_$getlogin
_getopt			_$getopt
_getpass		_XOPEN$getpass
_getpgrp		_XOPEN$getpgrp
_getpid			_$getpid
_getppid		_$getppid
_getpwnam		_$getpwnam
_getpwuid		_$getpwuid
_getuid			_$getuid
_getw			_$getw
_hcreate		_$hcreate
_hdestroy		_$hdestroy
_hsearch		_$hsearch
_isascii		_$isascii
_isatty			_$isatty
__isdst			_XOPEN$_isdst
_jrand48		_$jrand48
_kill			_$kill
_lcong48		_$lcong48
_lfind			_$lfind
_link			_$link
_lrand48		_$lrand48
_lsearch		_$lsearch
_lseek			_$lseek
_memccpy		_$memccpy
_mkdir			_$mkdir
_mkfifo			_$mkfifo
_mrand48		_$mrand48
_msgctl			_$msgctl
_msgget			_$msgget
_msgrcv			_$msgrcv
_msgsnd			_$msgsnd
_nice			_XOPEN$nice
_nl_langinfo		_$nl_langinfo
_nrand48		_$nrand48
_open			_$open
_opendir		_XOPEN$opendir
_optarg			_$optarg
_opterr			_$opterr
_optind			_$optind
_pathconf		_$pathconf
_pause			_$pause
_pclose			_$pclose
_pipe			_$pipe
_popen			_$popen
_putenv			_$putenv
_putw			_$putw
_read			_$read
_readdir		_$readdir
#
# rename is an ANSI-specified interface - don't rename (!) it.
#_rename			_$rename
#
_rewinddir		_$rewinddir
_rmdir			_$rmdir
_seed48			_$seed48
_seekdir		_$seekdir
_semctl			_$semctl
_semget			_$semget
_semop			_$semop
_setgid			_$setgid
_setkey			_$setkey
_setpgid		_$setpgid
_setsid			_$setsid
_setuid			_$setuid
_shmat			_$shmat
_shmctl			_$shmctl
_shmdt			_$shmdt
_shmget			_$shmget
_sigaction		_$sigaction
_sigaddset		_$sigaddset
_sigdelset		_$sigdelset
_sigemptyset		_$sigemptyset
_sigfillset		_$sigfillset
_sigismember		_$sigismember
_siglongjmp		_longjmp
_signal			_XOPEN$signal
_sigpending		_$sigpending
_sigprocmask		_$sigprocmask
_sigsuspend		_$sigsuspend
_sleep			_XOPEN$sleep
_srand48		_$srand48
_stat			_$stat
_swab			_$swab
_sysconf		_$sysconf
_tcdrain		_$tcdrain
_tcflow			_$tcflow
_tcflush		_$tcflush
_tcgetattr		_$tcgetattr
_tcgetpgrp		_$tcgetpgrp
_tcsendbreak		_$tcsendbreak
_tcsetattr		_$tcsetattr
_tcsetpgrp		_$tcsetpgrp
_tdelete		_$tdelete
_telldir		_$telldir
_tempnam		_$tempnam
_tfind			_$tfind
_times			_$times
_timezone		_XOPEN$timezone
_toascii		_$toascii
_tsearch		_$tsearch
_ttyname		_$ttyname
_twalk			_$twalk
_tzname			_XOPEN$tzname
_tzset			_XOPEN$tzset
_ulimit			_$ulimit
_umask			_$umask
_uname			_$uname
_unlink			_$unlink
_utime			_$utime
_wait			_$wait
_waitpid		_$waitpid
_write			_$write

_erf			_$erf
_erfc			_$erfc
_gamma			_$lgamma
_hypot			_$hypot
_isnan			_$isnan
_j0			_$j0
_j1			_$j1
_jn			_$jn
_lgamma			_$lgamma
_signgam		_$signgam
_y0			_$y0
_y1			_$y1
_yn			_$yn
# entries by FS 930311 and further on
_mktemp			_$mktemp
_ftruncate		_$ftruncate
_htonl			_$htonl
_htons			_$htons
_sendto			_$sendto
_recvfrom		_$recvfrom
_ntohl			_$ntohl
_socket			_$socket
_sys_errlist		_$sys_errlist
_bind			_$bind
_accept			_$accept
_inet_addr		_$inet_addr
_gethostbyname		_$gethostbyname
_endhostent		_$endhostent
_getservbyname		_$getservbyname
_endservent		_$endservent
_dbm_close		_$dbm_close
_dbm_open		_$dbm_open
_dbm_fetch		_$dbm_fetch
_gethostbyaddr		_$gethostbyaddr
_setregid		_$setregid
_setreuid		_$setreuid
_gettimeofday		_$gettimeofday
_select			_$select
_getpwent		_$getpwent
_endpwent		_$endpwent
_setsockopt		_$setsockopt
_listen			_$listen
_connect		_$connect
_sbrk			_$sbrk
_gethostname		_$gethostname
_initgroups		_$initgroups
_sigsetmask		_$sigsetmask
_sigvec			_$sigvec
ostbyname
_endhostent		_$endhostent
_getservbyname		_$getservbyname
_endservent		_$endservent
_dbm_close		_$dbm_close
_dbm_open		_$dbm_open
_dbm_fetch		_$dbm_fetch
_gethostbyaddr		_$gethostbyaddr
_setregid		_$setregid
_setreuid		_$setreuid
_gettimeofday		_$gettimeofday
_select			_$seWAMPES.R000064400010220000764000000106310620342153100121260ustar00deykembo00000000000000_abort			_XOPEN$abort
_access			_$access
_alarm			_$alarm
___assert		_XOPEN$__assert
_catclose		_$catclose
_catgets		_$catgets
_catopen		_$catopen
_cfgetispeed		_$cfgetispeed
_cfgetospeed		_$cfgetospeed
_cfsetispeed		_$cfsetispeed
_cfsetospeed		_$cfsetospeed
_chdir			_$chdir
_chmod			_$chmod
_chown			_$chown
_chroot			_$chroot
_clock			_XOPEN$clock
_close			_$close
_closedir		_$closedir
_creat			_$creat
_crypt			_$crypt
_ctermid		_$ctermid
_cuserid		_$cuserid
_daylight		_XOPEN$daylight
_drand48		_$drand48
__dstzone		_XOPEN$_dstzone
_dup			_$dup
_dup2			_$dup2
_encrypt		_$encrypt
_environ		_$environ
_erand48		_$erand48
_execl			_$execl
_execle			_$execle
_execlp			_$execlp
_execv			_$execv
_execve			_$execve
_execvp			_$execvp
_exit			_XOPEN$exit
_fcntl			_$fcntl
_fdopen			_$fdopen
_fileno			_$fileno
_fork			_$fork
_fpathconf		_$fpathconf
_fstat			_$fstat
_fsync			_$fsync
_ftw			_$ftw
_getcwd			_$getcwd
_getegid		_$getegid
_geteuid		_$geteuid
_getgid			_$getgid
_getgrgid		_$getgrgid
_getgrnam		_$getgrnam
_getgroups		_$getgroups
_getlogin		_$getlogin
_getopt			_$getopt
_getpass		_XOPEN$getpass
_getpgrp		_XOPEN$getpgrp
_getpid			_$getpid
_getppid		_$getppid
_getpwnam		_$getpwnam
_getpwuid		_$getpwuid
_getuid			_$getuid
_getw			_$getw
_hcreate		_$hcreate
_hdestroy		_$hdestroy
_hsearch		_$hsearch
_isascii		_$isascii
_isatty			_$isatty
__isdst			_XOPEN$_isdst
_jrand48		_$jrand48
_kill			_$kill
_lcong48		_$lcong48
_lfind			_$lfind
_link			_$link
_lrand48		_$lrand48
_lsearch		_$lsearch
_lseek			_$lseek
_memccpy		_$memccpy
_mkdir			_$mkdir
_mkfifo			_$mkfifo
_mrand48		_$mrand48
_msgctl			_$msgctl
_msgget			_$msgget
_msgrcv			_$msgrcv
_msgsnd			_$msgsnd
_nice			_XOPEN$nice
_nl_langinfo		_$nl_langinfo
_nrand48		_$nrand48
_open			_$open
_opendir		_XOPEN$opendir
_optarg			_$optarg
_opterr			_$opterr
_optind			_$optind
_pathconf		_$pathconf
_pause			_$pause
_pclose			_$pclose
_pipe			_$pipe
_popen			_$popen
_putenv			_$putenv
_putw			_$putw
_read			_$read
_readdir		_$readdir
#
# rename is an ANSI-specified interface - don't rename (!) it.
#_rename			_$rename
#
_rewinddir		_$rewinddir
_rmdir			_$rmdir
_seed48			_$seed48
_seekdir		_$seekdir
_semctl			_$semctl
_semget			_$semget
_semop			_$semop
_setgid			_$setgid
_setkey			_$setkey
_setpgid		_$setpgid
_setsid			_$setsid
_setuid			_$setuid
_shmat			_$shmat
_shmctl			_$shmctl
_shmdt			_$shmdt
_shmget			_$shmget
_sigaction		_$sigaction
_sigaddset		_$sigaddset
_sigdelset		_$sigdelset
_sigemptyset		_$sigemptyset
_sigfillset		_$sigfillset
_sigismember		_$sigismember
_siglongjmp		_longjmp
_signal			_XOPEN$signal
_sigpending		_$sigpending
_sigprocmask		_$sigprocmask
_sigsuspend		_$sigsuspend
_sleep			_XOPEN$sleep
_srand48		_$srand48
_stat			_$stat
_swab			_$swab
_sysconf		_$sysconf
_tcdrain		_$tcdrain
_tcflow			_$tcflow
_tcflush		_$tcflush
_tcgetattr		_$tcgetattr
_tcgetpgrp		_$tcgetpgrp
_tcsendbreak		_$tcsendbreak
_tcsetattr		_$tcsetattr
_tcsetpgrp		_$tcsetpgrp
_tdelete		_$tdelete
_telldir		_$telldir
_tempnam		_$tempnam
_tfind			_$tfind
_times			_$times
_timezone		_XOPEN$timezone
_toascii		_$toascii
_tsearch		_$tsearch
_ttyname		_$ttyname
_twalk			_$twalk
_tzname			_XOPEN$tzname
_tzset			_XOPEN$tzset
_ulimit			_$ulimit
_umask			_$umask
_uname			_$uname
_unlink			_$unlink
_utime			_$utime
_wait			_$wait
_waitpid		_$waitpid
_write			_$write

_erf			_$erf
_erfc			_$erfc
_gamma			_$lgamma
_hypot			_$hypot
_isnan			_$isnan
_j0			_$j0
_j1			_$j1
_jn			_$jn
_lgamma			_$lgamma
_signgam		_$signgam
_y0			_$y0
_y1			_$y1
_yn			_$yn
# entries by FS 930311 and further on
_mktemp			_$mktemp
_ftruncate		_$ftruncate
_htonl			_$htonl
_htons			_$htons
_sendto			_$sendto
_recvfrom		_$recvfrom
_ntohl			_$ntohl
_socket			_$socket
_sys_errlist		_$sys_errlist
_bind			_$bind
_accept			_$accept
_inet_addr		_$inet_addr
_gethostbyname		_$gethostbyname
_endhostent		_$endhostent
_getservbyname		_$getservbyname
_endservent		_$endservent
_dbm_close		_$dbm_close
_dbm_open		_$dbm_open
_dbm_fetch		_$dbm_fetch
_gethostbyaddr		_$gethostbyaddr
_setregid		_$setregid
_setreuid		_$setreuid
_gettimeofday		_$gettimeofday
_select			_$select
_getpwent		_$getpwent
_endpwent		_$endpwent
_setsockopt		_$setsockopt
_listen			_$listen
_connect		_$connect
_sbrk			_$sbrk
#temporary entries for Wampes - to be removed afterwards!!
_malloc			_$_malloc
_free			_$_free
_calloc			_$_calloc
_realloc		_$_realloc
_log			_$_log
__free			_$__free
#end of file
_gethostname		_$gethostname
_initgroups		_$initgroups
_sigsetmask		_$sigsetmask
_sigvec			_$sigvec
$gethostbyaddr
_setregid		_$setregid
_setreuid		_$setreuid
_gettimeofday		_$gettimeofday
_select			_$seChangeLog000064400010220000764000000207420702633722200125740ustar00deykembo00000000000000@(#) $Id: ChangeLog,v 1.71 1999/12/17 04:38:13 deyke Exp $

991216 Dieter Deyke <deyke@hotpop.com>

	Fixed bug in IP fragment reassembly

	Calling exit(1) instead of abort() if requesting too much memory
	in malloc()

	Limited ping packet size to 32767 bytes to prevent malloc panic

991201 Dieter Deyke <deyke@hotpop.com>

	Added cvspserver to list of known tcp services

991128 Dieter Deyke <deyke@hotpop.com>

	make distrib now creates the uncompressed tar file
	 "wampes-latest.tar" which can be used for rsync updates

991127 Dieter Deyke <deyke@hotpop.com>

	Added rsync to list of known tcp services

991122 Dieter Deyke <deyke@hotpop.com>

	Removed domain.txt and hosts from distribution
	(You can get domain.txt from ftp://ftp.ucsd.edu/hamradio/ampr.tar.Z)

991120 Dieter Deyke <deyke@hotpop.com>

	Updated domain.txt

991024 Dieter Deyke <deyke@hotpop.com>

	Updated domain.txt

991007 Dieter Deyke <deyke@hotpop.com>

	Added ifconfig <interface> crc command

	Retired netrom_links

990926 Dieter Deyke <deyke@hotpop.com>

	Updated email address and distribution location in README

990925 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt

990828 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt

990710 Dieter Deyke <deyke@fc.hp.com>

	Ported to RedHat Linux 6.0

	Updated domain.txt

990515 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt

990425 Dieter Deyke <deyke@fc.hp.com>

	Extended "route add" command to allow temporary routes

990421 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt

990211 Dieter Deyke <deyke@fc.hp.com>

	Cleaned up code

990201 Dieter Deyke <deyke@fc.hp.com>

	Fixed permissions of convers socket

	Added support for function keys 11 and 12

	Added support for NetBSD (thanks to Berndt Josef Wulf <wulf@ping.net.au>

	Cleaned up code

	Updated domain.txt

990127 Dieter Deyke <deyke@fc.hp.com>

	Removed some dead code

990124 Dieter Deyke <deyke@fc.hp.com>

	Determine byte order at run time

	Reduced warnings for Linux

990122 Dieter Deyke <deyke@fc.hp.com>

	Simplified Makefiles

	Updated domain.txt

990105 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt

981206 Dieter Deyke <deyke@fc.hp.com>

	Removed POP2 and POP3 servers from the distribution

	Updated domain.txt

981001 Dieter Deyke <deyke@fc.hp.com>

	Switched to 4 digit dates in bbs.c

980930 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt

980727 Dieter Deyke <deyke@fc.hp.com>

	Support for Libc6 (Debian 2.0) added

	Removed compiler warnings for Solaris 2.6

	Updated domain.txt

980427 Dieter Deyke <deyke@fc.hp.com>

	Better removal of conflicting files and directories in netupds.c

	Removed some compiler warnings

980424 Dieter Deyke <deyke@fc.hp.com>

	Added switch -h to cnet to support HP terminals, removed
	dependency on curses library

	Added debug code to netupds.c

	Updated domain.txt

980415 Dieter Deyke <deyke@fc.hp.com>

	Better error handling in netupds.c

	Updated domain.txt

980323 Dieter Deyke <deyke@fc.hp.com>

	Added support for AIX 4.3

	Added support for HP-UX 11.xx

	Updated domain.txt

980309 Dieter Deyke <deyke@fc.hp.com>

	Added support for NeXT

	Added new command "ifconfig <interface> autoroute <on|off>"

	Added new options -s, -w, and -u to netupdc

	Added new option -s to netupds

	Used "fd_set" instead of "struct fd_set" where possible

	Updated domain.txt

971229 Dieter Deyke <deyke@fc.hp.com>

	Obsoleted hosts

	Updated domain.txt

971113 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

970911 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

970821 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

970804 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

970625 Dieter Deyke <deyke@fc.hp.com>

	Added new option -n to netupds to specify notification mail
	destination

	Added support for shadow passwd file for linux

	Updated domain.txt and hosts

970609 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

970512 Dieter Deyke <deyke@fc.hp.com>

	Added option -b to bbs to generate Bulletin-IDs

	Updated domain.txt and hosts

970414 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

970317 Dieter Deyke <deyke@fc.hp.com>

	Added option -m (do not call make after update) to netupdc

	Updated domain.txt and hosts

970307 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

970211 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

970113 Dieter Deyke <deyke@fc.hp.com>

	ARP now sends ICMP_HOST_UNREACH if address cannot be resolved

	Updated domain.txt and hosts

961209 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

961124 Dieter Deyke <deyke@fc.hp.com>

	Added special code to bbs.c to translate my unix user name to my
	call sign

	Updated domain.txt and hosts

961028 Dieter Deyke <deyke@fc.hp.com>

	Added BEEP command to convers.c

	Updated domain.txt and hosts

961009 Dieter Deyke <deyke@fc.hp.com>

	Ported krnlif.c to current WAMPES revision

961008 Dieter Deyke <deyke@fc.hp.com>

	Added "attach kernel" for Linux (developed by Thomas Sailer)

	Updated domain.txt and hosts

961001 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

960909 Dieter Deyke <deyke@fc.hp.com>

	Fixed some warnings on HP-UX 10.20

	Updated domain.txt and hosts

960823 Dieter Deyke <deyke@fc.hp.com>

	net:

		Fixed bug in IP checksum calculation

		Removed TCP window scaling

	bbs:

		Extended HELP command to deal with abbreviations and
		aliases

	Updated domain.txt and hosts

960820 Dieter Deyke <deyke@fc.hp.com>

	Fixed configure script for bash, and for BSD based systems

	Updated IP tunnel for FreeBSD (developed by Olaf Erb)

960819 Dieter Deyke <deyke@fc.hp.com>

	net:

		Pulled in changes from "960812 (KA9Q - DJGPP)"

	bbs:

		Added SOURCE command

		Replaced INFO command by built-in alias

		Added automatic execution of /tcp/bbsrc file

		Extended HELP command to list aliases too

		Fixed overflow when using large values for MAXAGE

	udbm:

		Truncated MYBBS information to remove hierarchical part

	Updated domain.txt

960812 Dieter Deyke <deyke@fc.hp.com>

	Switched from using RCS keyword Header to using Id

960811 Dieter Deyke <deyke@fc.hp.com>

	Switched to RCS version 5.7 for development

	Added support for Linux ELF systems

	Added support for IP tunnel for FreeBSD (developed by Olaf Erb)

	Fixed wrong program name in error message in cnet

	Updated domain.txt and hosts

960729 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

960620 Dieter Deyke <deyke@fc.hp.com>

	Added new option '-c <cmd>' to cnet. This allows cnet to
	execute any non-interactive WAMPES command even while another
	cnet is used interactively

	Updated domain.txt and hosts

960528 Dieter Deyke <deyke@fc.hp.com>

	Fixed compiler warnings reported by SunOS 5

	Added -v compile flag for SunOS 5 to generate more warnings

	Removed -O compile flag for SunOS 5 to fix bus error

	Updated domain.txt and hosts

960514 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

960501 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

960408 Dieter Deyke <deyke@fc.hp.com>

	Added doc/index.html

	Updated domain.txt and hosts

960401 Dieter Deyke <deyke@fc.hp.com>

	Allowed multiple concurrent netupds servers

	Added second passwd lock file to udbm.c for HP-UX 10.xx

	Updated domain.txt and hosts

960314 Dieter Deyke <deyke@fc.hp.com>

	Fixed strdup/free interaction problem on AIX

	Fixed curses problem in cnet on HP-UX 10.10

	Fixed free memory read in bbs.c when changing an existing alias

	Updated domain.txt and hosts

960303 Dieter Deyke <deyke@fc.hp.com>

	Changed AX.25 T5 timer handling. The timer is now reset when
	sending I frames to support unidirectional data transfers

	Fixed seg vio in cnet occurring if TERM was not set, or was not
	in termcap/terminfo database

	Updated domain.txt and hosts

960220 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt and hosts

960213 Dieter Deyke <deyke@fc.hp.com>

	Minor cleanup

960208 Dieter Deyke <deyke@fc.hp.com>

	Updated domain.txt

	Reduced cpu load of conversd by only recomputing routes when
	necessary

	Added new command to net: "ax25 ignoretos [on|off]"

	Added new utility /tcp/util/bridge

960204 Dieter Deyke <deyke@fc.hp.com>

	Added support for Linux on 68000 machines

	Ported to HP-UX 10.10

	Added new target 'distrib' to top-level Makefile to generate
	distribution files

	Changed /..DEST send algorithm in conversd to avoid DEST storms
	in loops

	Changed /ROUTE command in conversd to allow specification of
	TTL, and changed default TTL to 16

	Added /..CSTAT command to conversd

	Removed old code which was excluded by #if 0

	Added ChangeLog
n|off]"

	Added new utility /tMakefile000064400010220000764000000040720702135274000124550ustar00deykembo00000000000000# @(#) $Id: Makefile,v 1.45 1999/12/02 02:13:52 deyke Exp $

OBSOLETE   = /usr/local/bin/sfstat \
	     /usr/local/etc/mkhostdb \
	     bbs/bbs.h \
	     bbs/findpath* \
	     bbs/help* \
	     bbs/killdup* \
	     bbs/sfstat* \
	     doc/bbs.2.gif \
	     lib/bbs.h \
	     netrom_links \
	     src/bootp.h \
	     src/cc \
	     src/config.h \
	     src/enet.h \
	     src/hardware.h \
	     src/linux_include/stdlib.h \
	     src/mail_bbs.* \
	     users \
	     util/genupd

DIRS       = lib \
	     aos \
	     NeXT \
	     src \
	     convers \
	     util \
	     bbs

all:;   @-rm -f $(OBSOLETE)
	-chmod 755 cc
	@-for dir in $(DIRS); do ( cd $$dir; $(MAKE) -i all install ); done
	@-$(MAKE) -i /tcp/hostaddr.pag
	@-if [ -d tools ]; then ( cd tools; $(MAKE) -i all install ); fi

/tcp/hosts:
	[ -f /tcp/hosts ] || touch /tcp/hosts

/tcp/domain.txt:
	[ -f /tcp/domain.txt ] || touch /tcp/domain.txt

/tcp/hostaddr.pag: /tcp/hosts /tcp/domain.txt util/mkhostdb
	rm -f /tcp/hostaddr.* /tcp/hostname.*
	util/mkhostdb >/dev/null 2>&1
	if [ -f /tcp/hostaddr.db ]; then ln /tcp/hostaddr.db $@; fi

distrib:
	@-rm -f wampes-*.t*; \
	sources=`find \
		*.R \
		ChangeLog \
		Makefile \
		NeXT/*.[ch] \
		NeXT/*.sh \
		NeXT/Makefile \
		NeXT/README.NeXT \
		NeXT/uname-next \
		README \
		aos/*.[ch] \
		aos/Makefile \
		bbs/*.[ch] \
		bbs/Makefile \
		bbs/bbs.help \
		cc \
		convers/*.[ch] \
		convers/Makefile \
		doc/?*.* \
		examples/?*.* \
		lib/*.[ch] \
		lib/Makefile \
		lib/configure \
		src/*.[ch] \
		src/Makefile \
		src/linux_include/*/*.h \
		util/*.[ch] \
		util/Makefile \
		! -name configure.h -print`; \
	tar cf wampes-latest.tar $$sources; \
	version=`awk -F- '/.#.WAMPES-/ {print substr($$2,1,6)}' < src/version.c`; \
	ln wampes-latest.tar wampes-$$version.tar; \
	ln README wampes-$$version.txt; \
	gzip -9 < wampes-latest.tar > wampes-$$version.tar.gz

clean:; @-for dir in $(DIRS); do ( cd $$dir; $(MAKE) -i clean ); done
	@-if [ -d tools ]; then  ( cd tools; $(MAKE) -i clean ); fi
	@-rm -f wampes-??????.t*
	@-find . -name .pure -exec rm {} \;
	@-find . -name .trimtime -exec rm {} \;
 configure.h -print`; \
	tar cf wampes-latest.tar $$sources; \
	version=`awk -F- '/.#.WAMPES-/ {print substr($$2,1,6)}' < src/version.c`; \
	ln wampes-latest.tar wampes-$$version.tar; \
	ln README wampes-$$version.txt; \
	gzip -9 < wampes-latest.tar > wampes-$$version.tar.gz

clean:; @-for dir in $(DIRS); do ( cd $$dir; $(MAKE) -i clean ); done
	@-if [ -d tools ]; then  ( cd tools; $(MAKE) -i clean ); fi
	@-rm -f wampes-??????.t*
	@-find . -name .purNeXT/next.c000064400010220000764000000003560665271671200127720ustar00deykembo00000000000000/* @(#) $Id: next.c,v 1.2 1999/01/24 22:25:14 deyke Exp $ */

#include <stdio.h>
#include <pwd.h>

#include "next.h"

int setenv(char * arg1, int i, int j)
{
  return -1;
}

int putpwent(const struct passwd *p, FILE *f)
{
  return -1;
}

ar; \
	ln README wampes-$$version.txt; \
	gzip -9 < wampes-latest.tar > wampes-$$version.tar.gz

clean:; @-for dir in $(DIRS); do ( cd $$dir; $(MAKE) -i clean ); done
	@-if [ -d tools ]; then  ( cd tools; $(MAKE) -i clean ); fi
	@-rm -f wampes-??????.t*
	@-find . -name .purNeXT/next.h000064400010220000764000000001500665271671200127670ustar00deykembo00000000000000/* @(#) $Id: next.h,v 1.2 1999/01/24 22:25:14 deyke Exp $ */

#ifdef  notdef
#include <libc.h>

#endif

ude "next.h"

int setenv(char * arg1, int i, int j)
{
  return -1;
}

int putpwent(const struct passwd *p, FILE *f)
{
  return -1;
}

ar; \
	ln README wampes-$$version.txt; \
	gzip -9 < wampes-latest.tar > wampes-$$version.tar.gz

clean:; @-for dir in $(DIRS); do ( cd $$dir; $(MAKE) -i clean ); done
	@-if [ -d tools ]; then  ( cd tools; $(MAKE) -i clean ); fi
	@-rm -f wampes-??????.t*
	@-find . -name .purNeXT/putenv.c000064400010220000764000000044510650102565600133260ustar00deykembo00000000000000/* @(#) $Id: putenv.c,v 1.1 1998/03/09 17:49:34 deyke Exp $ */

/*-
 * Copyright (c) 1988 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.
 */

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)putenv.c    5.4 (Berkeley) 2/23/91";
#endif /* LIBC_SCCS and not lint */

#include <stdlib.h>
#include <string.h>

int
putenv(str)
	const char *str;
{
	register char *p, *equal;
	int rval;

	if (!(p = strdup(str)))
		return(1);
	if (!(equal = index(p, '='))) {
		(void)free(p);
		return(1);
	}
	*equal = '\0';
	rval = setenv(p, equal + 1, 1);
	(void)free(p);
	return(rval);
}
FTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)putenv.c    5.4 (Berkeley) 2/23/91";
#endif /* LIBC_SCCS and not lint */

#inclNeXT/configure_helper.sh000075500010220000764000000005310650102565600155130ustar00deykembo00000000000000#!/bin/sh

# on NeXTstep3.3 there's no uname, but wampes' makefiles depend on uname.
# the easiest way is to link this little program to every subdirectory
# under /tcp/* as uname.  - 980206 dl9sau

chmod 755 ./uname-next

cd ..
ln -fs NeXT/uname uname
for file in `ls -F1 | grep / `
do
  cd $file
  ln -fs ../NeXT/uname-next uname
  cd ..
done
 SUCH DAMAGE.
 */

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)putenv.c    5.4 (Berkeley) 2/23/91";
#endif /* LIBC_SCCS and not lint */

#inclNeXT/make-NeXT-install.sh000075500010220000764000000002060650102565600153670ustar00deykembo00000000000000#! /bin/sh

PATH=$PATH:.

cd /tcp
echo please read /tcp/NeXT/README.NeXT, too.

cd NeXT
sh ./configure_helper.sh

cd ..
bash -c make

to every subdirectory
# under /tcp/* as uname.  - 980206 dl9sau

chmod 755 ./uname-next

cd ..
ln -fs NeXT/uname uname
for file in `ls -F1 | grep / `
do
  cd $file
  ln -fs ../NeXT/uname-next uname
  cd ..
done
 SUCH DAMAGE.
 */

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)putenv.c    5.4 (Berkeley) 2/23/91";
#endif /* LIBC_SCCS and not lint */

#inclNeXT/Makefile000064400010220000764000000006070665365746100133150ustar00deykembo00000000000000# @(#) $Id: Makefile,v 1.4 1999/01/27 18:47:13 deyke Exp $

LIBRARY       = libnext.a

OBJS          = next.o \
		putenv.o

all:;   @case "`uname -sr`" in \
	NeXT*) . ../lib/configure.mak; $(MAKE) -i _all;; \
	esac

_all:   $(LIBRARY)

$(LIBRARY): $(OBJS)
	@echo "Loading $@ ..."
	@ar cru $@ $(OBJS)
	@ranlib $@ >/dev/null 2>&1

install:;

clean:; @rm -f *.o *.a *~ \#*\#
###
next.o: next.h
defined(lint)
static char sccsid[] = "@(#)putenv.c    5.4 (Berkeley) 2/23/91";
#endif /* LIBC_SCCS and not lint */

#inclNeXT/README.NeXT000064400010220000764000000056520665542501000133400ustar00deykembo00000000000000980206 - this files describes the installation of wampes
on NeXT Mach / NeXTstep 3.3 systems.

please read this carefully.

i had 'only' the black hardware, that is with the motorola mk68040 chip,
but i'm shure wampes would compile on i386 plattforms, too.


if
  you know what you are doing, just type /tcp/NeXT/make-NeXT-install.sh
else
  read on.

cheers,
	- thomas  <thomas@x-berg.in-berlin.de> <dl9sau@db0tud.ampr.org>

---------


wampes compiles with either NeXT Developer cc or gcc 2.7.2.2.f.2 for NeXT.

you should have installed at gcc this point to get output from setsp.c,
because cc does not understand option -E:
> src/Makefile:
>         NeXT*) \
>                 gcc -E $< |grep -v ^# > setsp.s; as setsp.s -o $@;; \
		  -> explicit gcc instead of $(CC) 
anyway, you may extract it by hand :)


important notes:
----------------

default creation of new accounts is set to off because NeXTstep uses
netinfo service instead of a local passwd file.

wampes has serious problems to free the pty when a user logs off.
the system does recognice the pty as free, but wampes does not.

the memory allocation routines in wampes should redefine the standard.
but this redefinition does not work: the linker complains that those
functions already exist.. that's why i turned the wampes functions off.

convers/conversd seem to be clear.

not yet testet:
--------------
bbs, netupds, and bridge
but i expect no problems.

udbm may not work properly (missing putpwent()), but makes no sense as long as
netinfo service is not supported.


compilation notes / missing system calls:
-----------------------------------------

libutil.a:
strerror.c and strtoul.c must have a function to get libutil.a
the placeholder
  struct prevent_empty_file_message;
was not sufficient.

NeXT/next.c contains function that are not available opn NeXTstep 3.3:
int setenv(char * arg1, int i, int j)
int putpwent(const struct passwd *p, FILE *f)

while the missing putpwent only affects udbm,
the missing putenv/setenv is a real problem.


you need bash to be able to run mkhostdb for the domain database.

on my system i have the gnu utilities installed, what is recommended.
wampes compilation has not been tested on vanilla systems.

i also suggest to get a new libposix.a library from your favourite ftp
site.

posix hints:
you know helo world [ main() { printf("helo world"); } ]
when you compile as posix,
  cc -lposix -o helo helo.c
is the most wrong way: helo will crash with a floating point exception or
segmentation fault!
you should either compile with
  cc -posix -o helo helo.c
or
  cc -posix -lposix -o helo helo.c

btw: code from the three possibilities is each time different.

i have deceided to compile just with cc -posix.


new files:
----------
/tcp/NeXT/*

changed files:
--------------
/tcp/README
/tcp/Makefile, /tcp/*/Makefile
/tcp/lib/configure
/tcp/lib/strerror.c
/tcp/lib/strtoul.c
/tcp/src/global.h
/tcp/src/ksubr.c
/tcp/src/login.c
/tcp/src/setsp.c
/tcp/util/netupds.c

ating point exception or
segmentation fault!
you should either compile with
  cc -posiNeXT/uname-next000075500010220000764000000012560650102565600136500ustar00deykembo00000000000000#!/bin/sh

sysname=`hostinfo | grep "NeXT" | awk '{print $1 "-" $2}'`

#if [ X$1 = X ]
#then
#  echo $sysname
#  exit 0
#fi

tmp=`hostinfo | grep "NeXT" | cut -d';' -f1`

release=`echo $tmp | awk '{print $3}' | sed 's/://'`
version=`echo $tmp | awk '{print $4 " " $5 " " $6 " " $7 " " $8 " " $9}'`
machine=`hostinfo | grep "^Processor type:" | awk '{print $3}'`
nodename=`hostname`

case $1 in
  -a)
    echo $sysname $nodename $release $version $machine
    exit 1;
	;;
  -m)
    echo $machine
	;;
  -n)
    echo $nodename
	;;
  -r)
    echo $release
	;;
  -s)
    echo $sysname
	;;
  -v)
    echo $version
	;;
  -sr)
    echo $sysname $release
	;;
  *)
    echo $sysname
	;;
esac




ease=`echo $tmp | awk '{print $3}' | sed 's/://'`
version=`echo $tmp | awk '{print $4 " " $5 " " $6 " " $7 " " $8 " " $9}'`
machine=`hostinfo | grep "^Processor type:" | awk '{print $3}'`
nodename=`hostname`

case $1 in
  -a)
    echo $sysname $nodename $release $version $machine
    exit 1;
	;;
  -m)
    echo $machine
	;;
  -n)
    echREADME000064400010220000764000000075620702633730100117050ustar00deykembo00000000000000wampes-991216.tar.gz is a gzipped tar archive of WAMPES, a NET/NOS port
to various flavors of Unix.

WAMPES currently supports the following configurations:

+---------------+-----------------+-------------------------------------------+
| OS:           | Hardware:       | Contact Person:                           |
+---------------+-----------------+-------------------------------------------+
| HP-UX 09.xx   | HP9000/300      | Dieter Deyke <deyke@hotpop.com>           |
| HP-UX 10.xx   | HP9000/400      |                                           |
| HP-UX 11.xx   | HP9000/700      |                                           |
|               | HP9000/800      |                                           |
+---------------+-----------------+-------------------------------------------+
| SunOS 4.x     | SUN SPARC       | Dieter Deyke <deyke@hotpop.com>           |
| SunOS 5.x     | SUN SPARC       |                                           |
+---------------+-----------------+-------------------------------------------+
| AIX 4.x       | IBM RS/6000     | Dieter Deyke <deyke@hotpop.com>           |
+---------------+-----------------+-------------------------------------------+
| IRIX 5.x      | SGI             | Dieter Deyke <deyke@hotpop.com>           |
| IRIX 6.x      | SGI             | Dieter Deyke <deyke@hotpop.com>           |
+---------------+-----------------+-------------------------------------------+
| AOS           | IBM RT          | Jan Jaeger <janj@acci.com.au>             |
+---------------+-----------------+-------------------------------------------+
| 386BSD 0.1.34 | PC              | Dieter Deyke <deyke@hotpop.com>           |
+---------------+-----------------+-------------------------------------------+
| NetBSD 1.3.2  | PC              |                                           |
+---------------+-----------------+-------------------------------------------+
| FreeBSD 1.x   | PC              | Paul Traina <pst@shockwave.com>           |
| FreeBSD 2.x   |                 |                                           |
+---------------+-----------------+-------------------------------------------+
| BSDI 1.0      | PC              | J.R. Westmoreland <jr@upl.com>            |
+---------------+-----------------+-------------------------------------------+
| Linux         | PC              |                                           |
+---------------+-----------------+-------------------------------------------+
| ULTRIX 4.2A   | Decstation 5000 |                                           |
|   gcc 2.3.3   |                 |                                           |
+---------------+-----------------+-------------------------------------------+
| A/UX 3.0      | ?               | Paul Traina <pst@shockwave.com>           |
+---------------+-----------------+-------------------------------------------+
| RISC iX       | Acorn R260      | Felix Schroeter                           |
|               |                 |   <uk1o@rz.uni-karlsruhe.de> or           |
|               |                 |   <felix@snake.pond.sub.org>              |
+---------------+-----------------+-------------------------------------------+
| NeXT MACH     | mc68000, ?:386  | Thomas Osterried                          |
| NeXTStep3.3   |                 |   <thomas@x-berg.in-berlin.de>            |
+---------------+-----------------+-------------------------------------------+

To unpack this archive you have to:

	su
	mkdir /tcp
	cd /tcp
	gzip -d < wampes-991216.tar.gz | tar xvf -

After unpacking please read the file /tcp/doc/intro.txt.  For FreeBSD
2.1 and later, "GNU make (gmake)" must be used instead of /usr/bin/make.
For RISC iX you have to copy *.R to /usr/lib.  Now type "make -i" to
compile and install everything.

wampes-991216.tar.gz can be found at
	http://deyke.tripod.com/

73,
Dieter Deyke - deyke@cocreate.fc.hp.com
	     - deyke@hotpop.com
	     - dk5sg@db0sao.ampr.org
unpack this archive you have to:

	su
	mkdir /tcp
	cd /tcp
	gzip -d < wampes-991216.tar.gz | tar xvf -

After unpacking please read the file /aos/ansi.h000064400010220000764000000051440620367670200127130ustar00deykembo00000000000000/* @(#) $Id: ansi.h,v 1.4 1996/08/12 18:53:54 deyke Exp $ */

/*-
 * 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.
 *
 *      @(#)ansi.h      7.1 (Berkeley) 3/9/91
 */

#ifndef _ANSI_H_
#define _ANSI_H_

/*
 * Types which are fundamental to the implementation and may appear in
 * more than one standard header are defined here.  Standard headers
 * then use:
 *      #ifdef  _SIZE_T_
 *      typedef _SIZE_T_ size_t;
 *      #undef  _SIZE_T_
 *      #endif
 *
 * Thanks, ANSI!
 */
#define _CLOCK_T_       unsigned long           /* clock() */
#define _PTRDIFF_T_     int                     /* ptr1 - ptr2 */
#define _SIZE_T_        unsigned int            /* sizeof() */
#define _TIME_T_        long                    /* time() */
#define _VA_LIST_       char *                  /* va_list */
#define _WCHAR_T_       unsigned short          /* wchar_t */

#endif  /* _ANSI_H_ */
fdef  _SIZE_T_
 *      typedef _SIZE_T_ size_t;
 *      #undef  _SIZE_T_
 *      #endif
 *
 * Thanks, ANSI!
 */
#define _CLOCK_T_       unsigned long           /* clock() */
#define _PTRDIFF_T_     int                     /* ptr1 - ptr2 */
#define _SIZE_T_        unsigned int            /* sizeof() */
#define _TIME_T_        long                    /* time() */
#define _VA_LIST_       char *                  aos/cdefs.h000064400010220000764000000073460620367670200130530ustar00deykembo00000000000000/* @(#) $Id: cdefs.h,v 1.4 1996/08/12 18:53:54 deyke Exp $ */

/*
 * 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.
 *
 *      @(#)cdefs.h     8.1 (Berkeley) 6/2/93
 */

#ifndef _CDEFS_H_
#define _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.
 */
#if defined(__STDC__) || defined(__cplusplus)
#define __P(protos)     protos          /* full-blown ANSI C */
#define __CONCAT(x,y)   x ## y
#define __STRING(x)     #x

#else   /* !(__STDC__ || __cplusplus) */
#define __P(protos)     ()              /* traditional C preprocessor */
#define __CONCAT(x,y)   x/**/y
#define __STRING(x)     "x"

/* delete ANSI C keywords */
#define const
#define inline
#define signed
#define volatile
#endif  /* !(__STDC__ || __cplusplus) */

/*
 * GCC has extensions for declaring functions as const (`pure' - always returns
 * the same value given the same inputs, i.e., has no external state and
 * no side effects) and volatile (nonreturning or `dead').
 * These mainly affect optimization and warnings.
 *
 * To facilitate portability of a non-standard extension we define __pure
 * and __dead and use these for qualifying functions. Non-gcc compilers
 * which have similar extensions can then define these appropriately.
 *
 * Unfortunately, GCC complains if these are used under strict ANSI mode
 * (`gcc -ansi -pedantic'), hence we need to define them only if compiling
 * without this.
 */
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define __dead __volatile
#define __pure __const
#else
#define __dead
#define __pure
#endif

#endif /* !_CDEFS_H_ */
rd extension we define __pure
 * and __dead and use these for qualifying functions. Non-gcc compilers
 * which have similar extensions can then define these appropriately.
 *
 * Unfortunately, GCC complains if these are used under strict ANSI mode
 * (`gcc -ansi -pedantic'), hence aos/ctime.c000064400010220000764000001102740620367670200130560ustar00deykembo00000000000000/* @(#) $Id: ctime.c,v 1.4 1996/08/12 18:53:54 deyke Exp $ */

/*
 * Copyright (c) 1987, 1989 Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Arthur David Olson of the National Cancer Institute.
 *
 * 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[] = "@(#)ctime.c     5.26 (Berkeley) 2/23/91";
#endif /* LIBC_SCCS and not lint */

/*
** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu).
** POSIX-style TZ environment variable handling from Guy Harris
** (guy@auspex.com).
*/

/*LINTLIBRARY*/

/*
#include <sys/param.h>
*/
#include <fcntl.h>
#include "time.h"
#include "tzfile.h"
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <unistd.h>

#ifdef __STDC__
#include <stdlib.h>

#define P(s)            s
#define alloc_size_t    size_t
#define qsort_size_t    size_t
#define fread_size_t    size_t
#define fwrite_size_t   size_t

#else /* !defined __STDC__ */

#define P(s)            ()

typedef char *          genericptr_t;
typedef unsigned        alloc_size_t;
typedef int             qsort_size_t;
typedef int             fread_size_t;
typedef int             fwrite_size_t;

extern char *   calloc();
extern char *   malloc();
extern char *   realloc();
extern char *   getenv();

#endif /* !defined __STDC__ */

#define FILENAME_MAX    80
extern time_t   time();

#define ACCESS_MODE     O_RDONLY
#define OPEN_MODE       O_RDONLY

#ifndef WILDABBR
/*
** Someone might make incorrect use of a time zone abbreviation:
**      1.      They might reference tzname[0] before calling tzset (explicitly
**              or implicitly).
**      2.      They might reference tzname[1] before calling tzset (explicitly
**              or implicitly).
**      3.      They might reference tzname[1] after setting to a time zone
**              in which Daylight Saving Time is never observed.
**      4.      They might reference tzname[0] after setting to a time zone
**              in which Standard Time is never observed.
**      5.      They might reference tm.TM_ZONE after calling offtime.
** What's best to do in the above cases is open to debate;
** for now, we just set things up so that in any of the five cases
** WILDABBR is used.  Another possibility:  initialize tzname[0] to the
** string "tzname[0] used before set", and similarly for the other cases.
** And another:  initialize tzname[0] to "ERA", with an explanation in the
** manual page of what this "time zone abbreviation" means (doing this so
** that tzname[0] has the "normal" length of three characters).
*/
#define WILDABBR        "   "
#endif /* !defined WILDABBR */

#ifndef TRUE
#define TRUE            1
#define FALSE           0
#endif /* !defined TRUE */

static const char GMT[] = "GMT";

struct ttinfo {                         /* time type information */
	long            tt_gmtoff;      /* GMT offset in seconds */
	int             tt_isdst;       /* used to set tm_isdst */
	int             tt_abbrind;     /* abbreviation list index */
	int             tt_ttisstd;     /* TRUE if transition is std time */
};

struct lsinfo {                         /* leap second information */
	time_t          ls_trans;       /* transition time */
	long            ls_corr;        /* correction to apply */
};

struct state {
	int             leapcnt;
	int             timecnt;
	int             typecnt;
	int             charcnt;
	time_t          ats[TZ_MAX_TIMES];
	unsigned char   types[TZ_MAX_TIMES];
	struct ttinfo   ttis[TZ_MAX_TYPES];
	char            chars[(TZ_MAX_CHARS + 1 > sizeof GMT) ?
				TZ_MAX_CHARS + 1 : sizeof GMT];
	struct lsinfo   lsis[TZ_MAX_LEAPS];
};

struct rule {
	int             r_type;         /* type of rule--see below */
	int             r_day;          /* day number of rule */
	int             r_week;         /* week number of rule */
	int             r_mon;          /* month number of rule */
	long            r_time;         /* transition time of rule */
};

#define JULIAN_DAY              0       /* Jn - Julian day */
#define DAY_OF_YEAR             1       /* n - day of year */
#define MONTH_NTH_DAY_OF_WEEK   2       /* Mm.n.d - month, week, day of week */

/*
** Prototypes for static functions.
*/

static long             detzcode P((const char * codep));
static const char *     getzname P((const char * strp));
static const char *     getnum P((const char * strp, int * nump, int min,
				int max));
static const char *     getsecs P((const char * strp, long * secsp));
static const char *     getoffset P((const char * strp, long * offsetp));
static const char *     getrule P((const char * strp, struct rule * rulep));
static void             gmtload P((struct state * sp));
static void             gmtsub P((const time_t * timep, long offset,
				struct tm * tmp));
static void             localsub P((const time_t * timep, long offset,
				struct tm * tmp));
static void             normalize P((int * tensptr, int * unitsptr, int base));
static void             settzname P((void));
static time_t           time1 P((struct tm * tmp, void (* funcp)(),
				long offset));
static time_t           time2 P((struct tm *tmp, void (* funcp)(),
				long offset, int * okayp));
static void             timesub P((const time_t * timep, long offset,
				const struct state * sp, struct tm * tmp));
static int              tmcomp P((const struct tm * atmp,
				const struct tm * btmp));
static time_t           transtime P((time_t janfirst, int year,
				const struct rule * rulep, long offset));
static int              tzload P((const char * name, struct state * sp));
static int              tzparse P((const char * name, struct state * sp,
				int lastditch));

#ifdef ALL_STATE
static struct state *   lclptr;
static struct state *   gmtptr;
#endif /* defined ALL_STATE */

#ifndef ALL_STATE
static struct state     lclmem;
static struct state     gmtmem;
#define lclptr          (&lclmem)
#define gmtptr          (&gmtmem)
#endif /* State Farm */

static int              lcl_is_set;
static int              gmt_is_set;

char *                  tzname[2] = {
	WILDABBR,
	WILDABBR
};

#ifdef USG_COMPAT
time_t                  timezone = 0;
int                     daylight = 0;
#endif /* defined USG_COMPAT */

#ifdef ALTZONE
time_t                  altzone = 0;
#endif /* defined ALTZONE */

static long
detzcode(codep)
const char * const      codep;
{
	register long   result;
	register int    i;

	result = 0;
	for (i = 0; i < 4; ++i)
		result = (result << 8) | (codep[i] & 0xff);
	return result;
}

static void
settzname()
{
	register const struct state * const     sp = lclptr;
	register int                            i;

	tzname[0] = WILDABBR;
	tzname[1] = WILDABBR;
#ifdef USG_COMPAT
	daylight = 0;
	timezone = 0;
#endif /* defined USG_COMPAT */
#ifdef ALTZONE
	altzone = 0;
#endif /* defined ALTZONE */
#ifdef ALL_STATE
	if (sp == NULL) {
		tzname[0] = tzname[1] = GMT;
		return;
	}
#endif /* defined ALL_STATE */
	for (i = 0; i < sp->typecnt; ++i) {
		register const struct ttinfo * const    ttisp = &sp->ttis[i];

		tzname[ttisp->tt_isdst] =
			(char *) &sp->chars[ttisp->tt_abbrind];
#ifdef USG_COMPAT
		if (ttisp->tt_isdst)
			daylight = 1;
		if (i == 0 || !ttisp->tt_isdst)
			timezone = -(ttisp->tt_gmtoff);
#endif /* defined USG_COMPAT */
#ifdef ALTZONE
		if (i == 0 || ttisp->tt_isdst)
			altzone = -(ttisp->tt_gmtoff);
#endif /* defined ALTZONE */
	}
	/*
	** And to get the latest zone names into tzname. . .
	*/
	for (i = 0; i < sp->timecnt; ++i) {
		register const struct ttinfo * const    ttisp =
							&sp->ttis[sp->types[i]];

		tzname[ttisp->tt_isdst] =
			(char *) &sp->chars[ttisp->tt_abbrind];
	}
}

static int
tzload(name, sp)
register const char *           name;
register struct state * const   sp;
{
	register const char *   p;
	register int            i;
	register int            fid;

	if (name == NULL && (name = TZDEFAULT) == NULL)
		return -1;
	{
		char            fullname[FILENAME_MAX + 1];

		if (name[0] == ':')
			++name;
		if (name[0] != '/') {
			if ((p = TZDIR) == NULL)
				return -1;
			if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
				return -1;
			(void) strcpy(fullname, p);
			(void) strcat(fullname, "/");
			(void) strcat(fullname, name);
			name = fullname;
		}
		if ((fid = open(name, OPEN_MODE)) == -1)
			return -1;
	}
	{
		register const struct tzhead *  tzhp;
		char                            buf[sizeof *sp + sizeof *tzhp];
		int                             ttisstdcnt;

		i = read(fid, buf, sizeof buf);
		if (close(fid) != 0 || i < sizeof *tzhp)
			return -1;
		tzhp = (struct tzhead *) buf;
		ttisstdcnt = (int) detzcode(tzhp->tzh_ttisstdcnt);
		sp->leapcnt = (int) detzcode(tzhp->tzh_leapcnt);
		sp->timecnt = (int) detzcode(tzhp->tzh_timecnt);
		sp->typecnt = (int) detzcode(tzhp->tzh_typecnt);
		sp->charcnt = (int) detzcode(tzhp->tzh_charcnt);
		if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
			sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
			sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
			sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
			(ttisstdcnt != sp->typecnt && ttisstdcnt != 0))
				return -1;
		if (i < sizeof *tzhp +
			sp->timecnt * (4 + sizeof (char)) +
			sp->typecnt * (4 + 2 * sizeof (char)) +
			sp->charcnt * sizeof (char) +
			sp->leapcnt * 2 * 4 +
			ttisstdcnt * sizeof (char))
				return -1;
		p = buf + sizeof *tzhp;
		for (i = 0; i < sp->timecnt; ++i) {
			sp->ats[i] = detzcode(p);
			p += 4;
		}
		for (i = 0; i < sp->timecnt; ++i) {
			sp->types[i] = (unsigned char) *p++;
			if (sp->types[i] >= sp->typecnt)
				return -1;
		}
		for (i = 0; i < sp->typecnt; ++i) {
			register struct ttinfo *        ttisp;

			ttisp = &sp->ttis[i];
			ttisp->tt_gmtoff = detzcode(p);
			p += 4;
			ttisp->tt_isdst = (unsigned char) *p++;
			if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
				return -1;
			ttisp->tt_abbrind = (unsigned char) *p++;
			if (ttisp->tt_abbrind < 0 ||
				ttisp->tt_abbrind > sp->charcnt)
					return -1;
		}
		for (i = 0; i < sp->charcnt; ++i)
			sp->chars[i] = *p++;
		sp->chars[i] = '\0';    /* ensure '\0' at end */
		for (i = 0; i < sp->leapcnt; ++i) {
			register struct lsinfo *        lsisp;

			lsisp = &sp->lsis[i];
			lsisp->ls_trans = detzcode(p);
			p += 4;
			lsisp->ls_corr = detzcode(p);
			p += 4;
		}
		for (i = 0; i < sp->typecnt; ++i) {
			register struct ttinfo *        ttisp;

			ttisp = &sp->ttis[i];
			if (ttisstdcnt == 0)
				ttisp->tt_ttisstd = FALSE;
			else {
				ttisp->tt_ttisstd = *p++;
				if (ttisp->tt_ttisstd != TRUE &&
					ttisp->tt_ttisstd != FALSE)
						return -1;
			}
		}
	}
	return 0;
}

static const int        mon_lengths[2][MONSPERYEAR] = {
	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
	31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};

static const int        year_lengths[2] = {
	DAYSPERNYEAR, DAYSPERLYEAR
};

/*
** Given a pointer into a time zone string, scan until a character that is not
** a valid character in a zone name is found.  Return a pointer to that
** character.
*/

static const char *
getzname(strp)
register const char *   strp;
{
	register char   c;

	while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' &&
		c != '+')
			++strp;
	return strp;
}

/*
** Given a pointer into a time zone string, extract a number from that string.
** Check that the number is within a specified range; if it is not, return
** NULL.
** Otherwise, return a pointer to the first character not part of the number.
*/

static const char *
getnum(strp, nump, min, max)
register const char *   strp;
int * const             nump;
const int               min;
const int               max;
{
	register char   c;
	register int    num;

	if (strp == NULL || !isdigit(*strp))
		return NULL;
	num = 0;
	while ((c = *strp) != '\0' && isdigit(c)) {
		num = num * 10 + (c - '0');
		if (num > max)
			return NULL;    /* illegal value */
		++strp;
	}
	if (num < min)
		return NULL;            /* illegal value */
	*nump = num;
	return strp;
}

/*
** Given a pointer into a time zone string, extract a number of seconds,
** in hh[:mm[:ss]] form, from the string.
** If any error occurs, return NULL.
** Otherwise, return a pointer to the first character not part of the number
** of seconds.
*/

static const char *
getsecs(strp, secsp)
register const char *   strp;
long * const            secsp;
{
	int     num;

	strp = getnum(strp, &num, 0, HOURSPERDAY);
	if (strp == NULL)
		return NULL;
	*secsp = num * SECSPERHOUR;
	if (*strp == ':') {
		++strp;
		strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
		if (strp == NULL)
			return NULL;
		*secsp += num * SECSPERMIN;
		if (*strp == ':') {
			++strp;
			strp = getnum(strp, &num, 0, SECSPERMIN - 1);
			if (strp == NULL)
				return NULL;
			*secsp += num;
		}
	}
	return strp;
}

/*
** Given a pointer into a time zone string, extract an offset, in
** [+-]hh[:mm[:ss]] form, from the string.
** If any error occurs, return NULL.
** Otherwise, return a pointer to the first character not part of the time.
*/

static const char *
getoffset(strp, offsetp)
register const char *   strp;
long * const            offsetp;
{
	register int    neg;

	if (*strp == '-') {
		neg = 1;
		++strp;
	} else if (isdigit(*strp) || *strp++ == '+')
		neg = 0;
	else    return NULL;            /* illegal offset */
	strp = getsecs(strp, offsetp);
	if (strp == NULL)
		return NULL;            /* illegal time */
	if (neg)
		*offsetp = -*offsetp;
	return strp;
}

/*
** Given a pointer into a time zone string, extract a rule in the form
** date[/time].  See POSIX section 8 for the format of "date" and "time".
** If a valid rule is not found, return NULL.
** Otherwise, return a pointer to the first character not part of the rule.
*/

static const char *
getrule(strp, rulep)
const char *                    strp;
register struct rule * const    rulep;
{
	if (*strp == 'J') {
		/*
		** Julian day.
		*/
		rulep->r_type = JULIAN_DAY;
		++strp;
		strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
	} else if (*strp == 'M') {
		/*
		** Month, week, day.
		*/
		rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
		++strp;
		strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
		if (strp == NULL)
			return NULL;
		if (*strp++ != '.')
			return NULL;
		strp = getnum(strp, &rulep->r_week, 1, 5);
		if (strp == NULL)
			return NULL;
		if (*strp++ != '.')
			return NULL;
		strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
	} else if (isdigit(*strp)) {
		/*
		** Day of year.
		*/
		rulep->r_type = DAY_OF_YEAR;
		strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
	} else  return NULL;            /* invalid format */
	if (strp == NULL)
		return NULL;
	if (*strp == '/') {
		/*
		** Time specified.
		*/
		++strp;
		strp = getsecs(strp, &rulep->r_time);
	} else  rulep->r_time = 2 * SECSPERHOUR;        /* default = 2:00:00 */
	return strp;
}

/*
** Given the Epoch-relative time of January 1, 00:00:00 GMT, in a year, the
** year, a rule, and the offset from GMT at the time that rule takes effect,
** calculate the Epoch-relative time that rule takes effect.
*/

static time_t
transtime(janfirst, year, rulep, offset)
const time_t                            janfirst;
const int                               year;
register const struct rule * const      rulep;
const long                              offset;
{
	register int    leapyear;
	register time_t value;
	register int    i;
	int             d, m1, yy0, yy1, yy2, dow;

	leapyear = isleap(year);
	switch (rulep->r_type) {

	case JULIAN_DAY:
		/*
		** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
		** years.
		** In non-leap years, or if the day number is 59 or less, just
		** add SECSPERDAY times the day number-1 to the time of
		** January 1, midnight, to get the day.
		*/
		value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
		if (leapyear && rulep->r_day >= 60)
			value += SECSPERDAY;
		break;

	case DAY_OF_YEAR:
		/*
		** n - day of year.
		** Just add SECSPERDAY times the day number to the time of
		** January 1, midnight, to get the day.
		*/
		value = janfirst + rulep->r_day * SECSPERDAY;
		break;

	case MONTH_NTH_DAY_OF_WEEK:
		/*
		** Mm.n.d - nth "dth day" of month m.
		*/
		value = janfirst;
		for (i = 0; i < rulep->r_mon - 1; ++i)
			value += mon_lengths[leapyear][i] * SECSPERDAY;

		/*
		** Use Zeller's Congruence to get day-of-week of first day of
		** month.
		*/
		m1 = (rulep->r_mon + 9) % 12 + 1;
		yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
		yy1 = yy0 / 100;
		yy2 = yy0 % 100;
		dow = ((26 * m1 - 2) / 10 +
			1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
		if (dow < 0)
			dow += DAYSPERWEEK;

		/*
		** "dow" is the day-of-week of the first day of the month.  Get
		** the day-of-month (zero-origin) of the first "dow" day of the
		** month.
		*/
		d = rulep->r_day - dow;
		if (d < 0)
			d += DAYSPERWEEK;
		for (i = 1; i < rulep->r_week; ++i) {
			if (d + DAYSPERWEEK >=
				mon_lengths[leapyear][rulep->r_mon - 1])
					break;
			d += DAYSPERWEEK;
		}

		/*
		** "d" is the day-of-month (zero-origin) of the day we want.
		*/
		value += d * SECSPERDAY;
		break;
	}

	/*
	** "value" is the Epoch-relative time of 00:00:00 GMT on the day in
	** question.  To get the Epoch-relative time of the specified local
	** time on that day, add the transition time and the current offset
	** from GMT.
	*/
	return value + rulep->r_time + offset;
}

/*
** Given a POSIX section 8-style TZ string, fill in the rule tables as
** appropriate.
*/

static int
tzparse(name, sp, lastditch)
const char *                    name;
register struct state * const   sp;
const int                       lastditch;
{
	const char *                    stdname;
	const char *                    dstname;
	int                             stdlen;
	int                             dstlen;
	long                            stdoffset;
	long                            dstoffset;
	register time_t *               atp;
	register unsigned char *        typep;
	register char *                 cp;
	register int                    load_result;

	stdname = name;
	if (lastditch) {
		stdlen = strlen(name);  /* length of standard zone name */
		name += stdlen;
		if (stdlen >= sizeof sp->chars)
			stdlen = (sizeof sp->chars) - 1;
	} else {
		name = getzname(name);
		stdlen = name - stdname;
		if (stdlen < 3)
			return -1;
	}
	if (*name == '\0')
		return -1;
	else {
		name = getoffset(name, &stdoffset);
		if (name == NULL)
			return -1;
	}
	load_result = tzload(TZDEFRULES, sp);
	if (load_result != 0)
		sp->leapcnt = 0;                /* so, we're off a little */
	if (*name != '\0') {
		dstname = name;
		name = getzname(name);
		dstlen = name - dstname;        /* length of DST zone name */
		if (dstlen < 3)
			return -1;
		if (*name != '\0' && *name != ',' && *name != ';') {
			name = getoffset(name, &dstoffset);
			if (name == NULL)
				return -1;
		} else  dstoffset = stdoffset - SECSPERHOUR;
		if (*name == ',' || *name == ';') {
			struct rule     start;
			struct rule     end;
			register int    year;
			register time_t janfirst;
			time_t          starttime;
			time_t          endtime;

			++name;
			if ((name = getrule(name, &start)) == NULL)
				return -1;
			if (*name++ != ',')
				return -1;
			if ((name = getrule(name, &end)) == NULL)
				return -1;
			if (*name != '\0')
				return -1;
			sp->typecnt = 2;        /* standard time and DST */
			/*
			** Two transitions per year, from EPOCH_YEAR to 2037.
			*/
			sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
			if (sp->timecnt > TZ_MAX_TIMES)
				return -1;
			sp->ttis[0].tt_gmtoff = -dstoffset;
			sp->ttis[0].tt_isdst = 1;
			sp->ttis[0].tt_abbrind = stdlen + 1;
			sp->ttis[1].tt_gmtoff = -stdoffset;
			sp->ttis[1].tt_isdst = 0;
			sp->ttis[1].tt_abbrind = 0;
			atp = sp->ats;
			typep = sp->types;
			janfirst = 0;
			for (year = EPOCH_YEAR; year <= 2037; ++year) {
				starttime = transtime(janfirst, year, &start,
					stdoffset);
				endtime = transtime(janfirst, year, &end,
					dstoffset);
				if (starttime > endtime) {
					*atp++ = endtime;
					*typep++ = 1;   /* DST ends */
					*atp++ = starttime;
					*typep++ = 0;   /* DST begins */
				} else {
					*atp++ = starttime;
					*typep++ = 0;   /* DST begins */
					*atp++ = endtime;
					*typep++ = 1;   /* DST ends */
				}
				janfirst +=
					year_lengths[isleap(year)] * SECSPERDAY;
			}
		} else {
			int             sawstd;
			int             sawdst;
			long            stdfix;
			long            dstfix;
			long            oldfix;
			int             isdst;
			register int    i;

			if (*name != '\0')
				return -1;
			if (load_result != 0)
				return -1;
			/*
			** Compute the difference between the real and
			** prototype standard and summer time offsets
			** from GMT, and put the real standard and summer
			** time offsets into the rules in place of the
			** prototype offsets.
			*/
			sawstd = FALSE;
			sawdst = FALSE;
			stdfix = 0;
			dstfix = 0;
			for (i = 0; i < sp->typecnt; ++i) {
				if (sp->ttis[i].tt_isdst) {
					oldfix = dstfix;
					dstfix =
					    sp->ttis[i].tt_gmtoff + dstoffset;
					if (sawdst && (oldfix != dstfix))
						return -1;
					sp->ttis[i].tt_gmtoff = -dstoffset;
					sp->ttis[i].tt_abbrind = stdlen + 1;
					sawdst = TRUE;
				} else {
					oldfix = stdfix;
					stdfix =
					    sp->ttis[i].tt_gmtoff + stdoffset;
					if (sawstd && (oldfix != stdfix))
						return -1;
					sp->ttis[i].tt_gmtoff = -stdoffset;
					sp->ttis[i].tt_abbrind = 0;
					sawstd = TRUE;
				}
			}
			/*
			** Make sure we have both standard and summer time.
			*/
			if (!sawdst || !sawstd)
				return -1;
			/*
			** Now correct the transition times by shifting
			** them by the difference between the real and
			** prototype offsets.  Note that this difference
			** can be different in standard and summer time;
			** the prototype probably has a 1-hour difference
			** between standard and summer time, but a different
			** difference can be specified in TZ.
			*/
			isdst = FALSE;  /* we start in standard time */
			for (i = 0; i < sp->timecnt; ++i) {
				register const struct ttinfo *  ttisp;

				/*
				** If summer time is in effect, and the
				** transition time was not specified as
				** standard time, add the summer time
				** offset to the transition time;
				** otherwise, add the standard time offset
				** to the transition time.
				*/
				ttisp = &sp->ttis[sp->types[i]];
				sp->ats[i] +=
					(isdst && !ttisp->tt_ttisstd) ?
						dstfix : stdfix;
				isdst = ttisp->tt_isdst;
			}
		}
	} else {
		dstlen = 0;
		sp->typecnt = 1;                /* only standard time */
		sp->timecnt = 0;
		sp->ttis[0].tt_gmtoff = -stdoffset;
		sp->ttis[0].tt_isdst = 0;
		sp->ttis[0].tt_abbrind = 0;
	}
	sp->charcnt = stdlen + 1;
	if (dstlen != 0)
		sp->charcnt += dstlen + 1;
	if (sp->charcnt > sizeof sp->chars)
		return -1;
	cp = sp->chars;
	(void) strncpy(cp, stdname, stdlen);
	cp += stdlen;
	*cp++ = '\0';
	if (dstlen != 0) {
		(void) strncpy(cp, dstname, dstlen);
		*(cp + dstlen) = '\0';
	}
	return 0;
}

static void
gmtload(sp)
struct state * const    sp;
{
	if (tzload(GMT, sp) != 0)
		(void) tzparse(GMT, sp, TRUE);
}

void
tzset()
{
	register const char *   name;
	void tzsetwall();

	name = getenv("TZ");
	if (name == NULL) {
		tzsetwall();
		return;
	}
	lcl_is_set = TRUE;
#ifdef ALL_STATE
	if (lclptr == NULL) {
		lclptr = (struct state *) malloc(sizeof *lclptr);
		if (lclptr == NULL) {
			settzname();    /* all we can do */
			return;
		}
	}
#endif /* defined ALL_STATE */
	if (*name == '\0') {
		/*
		** User wants it fast rather than right.
		*/
		lclptr->leapcnt = 0;            /* so, we're off a little */
		lclptr->timecnt = 0;
		lclptr->ttis[0].tt_gmtoff = 0;
		lclptr->ttis[0].tt_abbrind = 0;
		(void) strcpy(lclptr->chars, GMT);
	} else if (tzload(name, lclptr) != 0)
		if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
			(void) gmtload(lclptr);
	settzname();
}

void
tzsetwall()
{
	lcl_is_set = TRUE;
#ifdef ALL_STATE
	if (lclptr == NULL) {
		lclptr = (struct state *) malloc(sizeof *lclptr);
		if (lclptr == NULL) {
			settzname();    /* all we can do */
			return;
		}
	}
#endif /* defined ALL_STATE */
	if (tzload((char *) NULL, lclptr) != 0)
		gmtload(lclptr);
	settzname();
}

/*
** The easy way to behave "as if no library function calls" localtime
** is to not call it--so we drop its guts into "localsub", which can be
** freely called.  (And no, the PANS doesn't require the above behavior--
** but it *is* desirable.)
**
** The unused offset argument is for the benefit of mktime variants.
*/

/*ARGSUSED*/
static void
localsub(timep, offset, tmp)
const time_t * const    timep;
const long              offset;
struct tm * const       tmp;
{
	register struct state * sp;
	register const struct ttinfo *  ttisp;
	register int                    i;
	const time_t                    t = *timep;

	if (!lcl_is_set)
		tzset();
	sp = lclptr;
#ifdef ALL_STATE
	if (sp == NULL) {
		gmtsub(timep, offset, tmp);
		return;
	}
#endif /* defined ALL_STATE */
	if (sp->timecnt == 0 || t < sp->ats[0]) {
		i = 0;
		while (sp->ttis[i].tt_isdst)
			if (++i >= sp->typecnt) {
				i = 0;
				break;
			}
	} else {
		for (i = 1; i < sp->timecnt; ++i)
			if (t < sp->ats[i])
				break;
		i = sp->types[i - 1];
	}
	ttisp = &sp->ttis[i];
	/*
	** To get (wrong) behavior that's compatible with System V Release 2.0
	** you'd replace the statement below with
	**      t += ttisp->tt_gmtoff;
	**      timesub(&t, 0L, sp, tmp);
	*/
	timesub(&t, ttisp->tt_gmtoff, sp, tmp);
	tmp->tm_isdst = ttisp->tt_isdst;
	tzname[tmp->tm_isdst] = (char *) &sp->chars[ttisp->tt_abbrind];
	tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
}

struct tm *
localtime(timep)
const time_t * const    timep;
{
	static struct tm        tm;

	localsub(timep, 0L, &tm);
	return &tm;
}

/*
** gmtsub is to gmtime as localsub is to localtime.
*/

static void
gmtsub(timep, offset, tmp)
const time_t * const    timep;
const long              offset;
struct tm * const       tmp;
{
	if (!gmt_is_set) {
		gmt_is_set = TRUE;
#ifdef ALL_STATE
		gmtptr = (struct state *) malloc(sizeof *gmtptr);
		if (gmtptr != NULL)
#endif /* defined ALL_STATE */
			gmtload(gmtptr);
	}
	timesub(timep, offset, gmtptr, tmp);
	/*
	** Could get fancy here and deliver something such as
	** "GMT+xxxx" or "GMT-xxxx" if offset is non-zero,
	** but this is no time for a treasure hunt.
	*/
	if (offset != 0)
		tmp->tm_zone = WILDABBR;
	else {
#ifdef ALL_STATE
		if (gmtptr == NULL)
			tmp->TM_ZONE = GMT;
		else    tmp->TM_ZONE = gmtptr->chars;
#endif /* defined ALL_STATE */
#ifndef ALL_STATE
		tmp->tm_zone = gmtptr->chars;
#endif /* State Farm */
	}
}

struct tm *
gmtime(timep)
const time_t * const    timep;
{
	static struct tm        tm;

	gmtsub(timep, 0L, &tm);
	return &tm;
}

static void
timesub(timep, offset, sp, tmp)
const time_t * const                    timep;
const long                              offset;
register const struct state * const     sp;
register struct tm * const              tmp;
{
	register const struct lsinfo *  lp;
	register long                   days;
	register long                   rem;
	register int                    y;
	register int                    yleap;
	register const int *            ip;
	register long                   corr;
	register int                    hit;
	register int                    i;

	corr = 0;
	hit = FALSE;
#ifdef ALL_STATE
	i = (sp == NULL) ? 0 : sp->leapcnt;
#endif /* defined ALL_STATE */
#ifndef ALL_STATE
	i = sp->leapcnt;
#endif /* State Farm */
	while (--i >= 0) {
		lp = &sp->lsis[i];
		if (*timep >= lp->ls_trans) {
			if (*timep == lp->ls_trans)
				hit = ((i == 0 && lp->ls_corr > 0) ||
					lp->ls_corr > sp->lsis[i - 1].ls_corr);
			corr = lp->ls_corr;
			break;
		}
	}
	days = *timep / SECSPERDAY;
	rem = *timep % SECSPERDAY;
#ifdef mc68k
	if (*timep == 0x80000000) {
		/*
		** A 3B1 muffs the division on the most negative number.
		*/
		days = -24855;
		rem = -11648;
	}
#endif /* mc68k */
	rem += (offset - corr);
	while (rem < 0) {
		rem += SECSPERDAY;
		--days;
	}
	while (rem >= SECSPERDAY) {
		rem -= SECSPERDAY;
		++days;
	}
	tmp->tm_hour = (int) (rem / SECSPERHOUR);
	rem = rem % SECSPERHOUR;
	tmp->tm_min = (int) (rem / SECSPERMIN);
	tmp->tm_sec = (int) (rem % SECSPERMIN);
	if (hit)
		/*
		** A positive leap second requires a special
		** representation.  This uses "... ??:59:60".
		*/
		++(tmp->tm_sec);
	tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
	if (tmp->tm_wday < 0)
		tmp->tm_wday += DAYSPERWEEK;
	y = EPOCH_YEAR;
	if (days >= 0)
		for ( ; ; ) {
			yleap = isleap(y);
			if (days < (long) year_lengths[yleap])
				break;
			++y;
			days = days - (long) year_lengths[yleap];
		}
	else do {
		--y;
		yleap = isleap(y);
		days = days + (long) year_lengths[yleap];
	} while (days < 0);
	tmp->tm_year = y - TM_YEAR_BASE;
	tmp->tm_yday = (int) days;
	ip = mon_lengths[yleap];
	for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
		days = days - (long) ip[tmp->tm_mon];
	tmp->tm_mday = (int) (days + 1);
	tmp->tm_isdst = 0;
	tmp->tm_gmtoff = offset;
}

/*
** A la X3J11
*/

char *
asctime(timeptr)
register const struct tm *      timeptr;
{
	static const char       wday_name[DAYSPERWEEK][3] = {
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
	};
	static const char       mon_name[MONSPERYEAR][3] = {
		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
	};
	static char     result[26];

	(void) sprintf(result, "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n",
		wday_name[timeptr->tm_wday],
		mon_name[timeptr->tm_mon],
		timeptr->tm_mday, timeptr->tm_hour,
		timeptr->tm_min, timeptr->tm_sec,
		TM_YEAR_BASE + timeptr->tm_year);
	return result;
}

char *
ctime(timep)
const time_t * const    timep;
{
	return asctime(localtime(timep));
}

/*
** Adapted from code provided by Robert Elz, who writes:
**      The "best" way to do mktime I think is based on an idea of Bob
**      Kridle's (so its said...) from a long time ago. (mtxinu!kridle now).
**      It does a binary search of the time_t space.  Since time_t's are
**      just 32 bits, its a max of 32 iterations (even at 64 bits it
**      would still be very reasonable).
*/

#ifndef WRONG
#define WRONG   (-1)
#endif /* !defined WRONG */

static void
normalize(tensptr, unitsptr, base)
int * const     tensptr;
int * const     unitsptr;
const int       base;
{
	if (*unitsptr >= base) {
		*tensptr += *unitsptr / base;
		*unitsptr %= base;
	} else if (*unitsptr < 0) {
		--*tensptr;
		*unitsptr += base;
		if (*unitsptr < 0) {
			*tensptr -= 1 + (-*unitsptr) / base;
			*unitsptr = base - (-*unitsptr) % base;
		}
	}
}

static int
tmcomp(atmp, btmp)
register const struct tm * const atmp;
register const struct tm * const btmp;
{
	register int    result;

	if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
		(result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
		(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
		(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
		(result = (atmp->tm_min - btmp->tm_min)) == 0)
			result = atmp->tm_sec - btmp->tm_sec;
	return result;
}

static time_t
time2(tmp, funcp, offset, okayp)
struct tm * const       tmp;
void (* const           funcp)();
const long              offset;
int * const             okayp;
{
	register const struct state *   sp;
	register int                    dir;
	register int                    bits;
	register int                    i, j ;
	register int                    saved_seconds;
	time_t                          newt;
	time_t                          t;
	struct tm                       yourtm, mytm;

	*okayp = FALSE;
	yourtm = *tmp;
	if (yourtm.tm_sec >= SECSPERMIN + 2 || yourtm.tm_sec < 0)
		normalize(&yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN);
	normalize(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR);
	normalize(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY);
	normalize(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR);
	while (yourtm.tm_mday <= 0) {
		--yourtm.tm_year;
		yourtm.tm_mday +=
			year_lengths[isleap(yourtm.tm_year + TM_YEAR_BASE)];
	}
	for ( ; ; ) {
		i = mon_lengths[isleap(yourtm.tm_year +
			TM_YEAR_BASE)][yourtm.tm_mon];
		if (yourtm.tm_mday <= i)
			break;
		yourtm.tm_mday -= i;
		if (++yourtm.tm_mon >= MONSPERYEAR) {
			yourtm.tm_mon = 0;
			++yourtm.tm_year;
		}
	}
	saved_seconds = yourtm.tm_sec;
	yourtm.tm_sec = 0;
	/*
	** Calculate the number of magnitude bits in a time_t
	** (this works regardless of whether time_t is
	** signed or unsigned, though lint complains if unsigned).
	*/
	for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
		;
	/*
	** If time_t is signed, then 0 is the median value,
	** if time_t is unsigned, then 1 << bits is median.
	*/
	t = (t < 0) ? 0 : ((time_t) 1 << bits);
	for ( ; ; ) {
		(*funcp)(&t, offset, &mytm);
		dir = tmcomp(&mytm, &yourtm);
		if (dir != 0) {
			if (bits-- < 0)
				return WRONG;
			if (bits < 0)
				--t;
			else if (dir > 0)
				t -= (time_t) 1 << bits;
			else    t += (time_t) 1 << bits;
			continue;
		}
		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
			break;
		/*
		** Right time, wrong type.
		** Hunt for right time, right type.
		** It's okay to guess wrong since the guess
		** gets checked.
		*/
		sp = (const struct state *)
			((funcp == localsub) ? lclptr : gmtptr);
#ifdef ALL_STATE
		if (sp == NULL)
			return WRONG;
#endif /* defined ALL_STATE */
		for (i = 0; i < sp->typecnt; ++i) {
			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
				continue;
			for (j = 0; j < sp->typecnt; ++j) {
				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
					continue;
				newt = t + sp->ttis[j].tt_gmtoff -
					sp->ttis[i].tt_gmtoff;
				(*funcp)(&newt, offset, &mytm);
				if (tmcomp(&mytm, &yourtm) != 0)
					continue;
				if (mytm.tm_isdst != yourtm.tm_isdst)
					continue;
				/*
				** We have a match.
				*/
				t = newt;
				goto label;
			}
		}
		return WRONG;
	}
label:
	t += saved_seconds;
	(*funcp)(&t, offset, tmp);
	*okayp = TRUE;
	return t;
}

static time_t
time1(tmp, funcp, offset)
struct tm * const       tmp;
void (* const           funcp)();
const long              offset;
{
	register time_t                 t;
	register const struct state *   sp;
	register int                    samei, otheri;
	int                             okay;

	if (tmp->tm_isdst > 1)
		tmp->tm_isdst = 1;
	t = time2(tmp, funcp, offset, &okay);
	if (okay || tmp->tm_isdst < 0)
		return t;
	/*
	** We're supposed to assume that somebody took a time of one type
	** and did some math on it that yielded a "struct tm" that's bad.
	** We try to divine the type they started from and adjust to the
	** type they need.
	*/
	sp = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr);
#ifdef ALL_STATE
	if (sp == NULL)
		return WRONG;
#endif /* defined ALL_STATE */
	for (samei = 0; samei < sp->typecnt; ++samei) {
		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
			continue;
		for (otheri = 0; otheri < sp->typecnt; ++otheri) {
			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
				continue;
			tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
					sp->ttis[samei].tt_gmtoff;
			tmp->tm_isdst = !tmp->tm_isdst;
			t = time2(tmp, funcp, offset, &okay);
			if (okay)
				return t;
			tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
					sp->ttis[samei].tt_gmtoff;
			tmp->tm_isdst = !tmp->tm_isdst;
		}
	}
	return WRONG;
}

time_t
mktime(tmp)
struct tm * const       tmp;
{
	return time1(tmp, localsub, 0L);
}
 = 0; otheri < sp->typecnt; ++otheri) {
			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
				continue;
			tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
					sp->ttis[samei].tt_gmtoff;
			tmp->tm_isdst = !tmp->tm_isdst;
			t = time2(tmp, funcp, offset, &okay);
			if (okay)
				return t;
			tmp->tm_sec -= sp->ttis[otheri].ttaos/getcwd.c000064400010220000764000000143360620367670200132340ustar00deykembo00000000000000/* @(#) $Id: getcwd.c,v 1.4 1996/08/12 18:53:54 deyke Exp $ */

/*
 * 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.
 */

#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/param.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/dir.h>
#define dirent direct
#define  dirfd(dirp)     ((dirp)->dd_fd)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define ISDOT(dp) \
	(dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
	    dp->d_name[1] == '.' && dp->d_name[2] == '\0'))

char *
getcwd(pt, size)
	char *pt;
	size_t size;
{
	register struct dirent *dp;
	register DIR *dir;
	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 (lstat(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;
			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_fileno == ino)
					break;
			}
		} else
			for (;;) {
				if (!(dp = readdir(dir)))
					goto notfound;
				if (ISDOT(dp))
					continue;
				bcopy(dp->d_name, bup, dp->d_namlen + 1);

				/* Save the first error for later. */
				if (lstat(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 <= dp->d_namlen + (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 -= dp->d_namlen;
		bcopy(dp->d_name, bpt, dp->d_namlen);
		(void)closedir(dir);

		/* 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 (ptsize)
		free(pt);
	free(up);
	return((char *)NULL);
}
n);
			bpt = ept - len;
		}
		if (!first)
			*--bpt = '/';
		bpt -= dp->d_namlen;
		bcopy(dp->d_name, bpt, dp->d_namlen);
		(void)closedir(dir);

		/* Truncate any file name. */
		*bup = '\0';
	}

notfound:
	/*
	 * If readdir set errno, use it, not any saved error; otherwise,
	 * didn't fiaos/putenv.c000064400010220000764000000044510620367670200132750ustar00deykembo00000000000000/* @(#) $Id: putenv.c,v 1.4 1996/08/12 18:53:54 deyke Exp $ */

/*-
 * Copyright (c) 1988 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.
 */

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)putenv.c    5.4 (Berkeley) 2/23/91";
#endif /* LIBC_SCCS and not lint */

#include <stdlib.h>
#include <string.h>

int
putenv(str)
	const char *str;
{
	register char *p, *equal;
	int rval;

	if (!(p = strdup(str)))
		return(1);
	if (!(equal = index(p, '='))) {
		(void)free(p);
		return(1);
	}
	*equal = '\0';
	rval = setenv(p, equal + 1, 1);
	(void)free(p);
	return(rval);
}
FTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)putenv.c    5.4 (Berkeley) 2/23/91";
#endif /* LIBC_SCCS and not lint */

#inclaos/setsid.c000064400010220000764000000004650620367670200132500ustar00deykembo00000000000000/* @(#) $Id: setsid.c,v 1.4 1996/08/12 18:53:54 deyke Exp $ */

/* setsid.c
 * remove tty association
 * 17/01/94 J.Jaeger, PA3EFU.
 */

#include <fcntl.h>
#include <sys/ioctl.h>

setsid()
{
	int fd;

	fd = open("/dev/tty",O_RDWR);

	ioctl(fd, TIOCNOTTY, 0);

	close(fd);

	close(0);
	close(1);
	close(2);

}
 IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)putenv.c    5.4 (Berkeley) 2/23/91";
#endif /* LIBC_SCCS and not lint */

#inclaos/strstr.c000064400010220000764000000050110620367670200133060ustar00deykembo00000000000000/* @(#) $Id: strstr.c,v 1.4 1996/08/12 18:53:54 deyke Exp $ */

/*-
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Chris Torek.
 *
 * 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[] = "@(#)strstr.c    5.2 (Berkeley) 1/26/91";
#endif /* LIBC_SCCS and not lint */

/* #include "cdefs.h" */

#include <sys/types.h>
#define NULL 0
#include <string.h>

/*
 * Find the first occurrence of find in s.
 */
char *
strstr(s, find)
	register const char *s, *find;
{
	register char c, sc;
	register size_t len;

	if ((c = *find++) != 0) {
		len = strlen(find);
		do {
			do {
				if ((sc = *s++) == 0)
					return (NULL);
			} while (sc != c);
		} while (strncmp(s, find, len) != 0);
		s--;
	}
	return ((char *)s);
}
tr.c    5.2 (Berkeley) 1/26/91";
#endif /* LIBC_SCCS and not lint */

/* #include "cdefs.h" */

#include <sys/types.h>
#define NULL 0
#include <string.h>

/*
 * Find the first occurrence of find in s.
 */
char *
strstr(s, find)
	register const char *s, *find;
{
	register char c, sc;
	register size_t len;

	if ((c = *find++) != 0) {
		len = strlen(find);
		do {
			do {
				if ((sc = *s++) == 0)
					return (NULL);
			} while (sc != c);
		} while (strncmp(s, find, len) != 0);
		s--;
	}
	return ((charaos/time.h000064400010220000764000000067500620367670200127230ustar00deykembo00000000000000/* @(#) $Id: time.h,v 1.4 1996/08/12 18:53:54 deyke Exp $ */

/*
 * 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.
 *
 *      @(#)time.h      5.12 (Berkeley) 3/9/91
 */

#ifndef _TIME_H_
#define _TIME_H_

#include "ansi.h"

#ifndef NULL
#define NULL    0
#endif

#ifdef  _CLOCK_T_
typedef _CLOCK_T_       clock_t;
#undef  _CLOCK_T_
#endif

#ifdef  _TIME_T_
typedef _TIME_T_        time_t;
#undef  _TIME_T_
#endif

#ifdef  _SIZE_T_
typedef _SIZE_T_        size_t;
#undef  _SIZE_T_
#endif

struct tm {
	int     tm_sec;         /* seconds after the minute [0-60] */
	int     tm_min;         /* minutes after the hour [0-59] */
	int     tm_hour;        /* hours since midnight [0-23] */
	int     tm_mday;        /* day of the month [1-31] */
	int     tm_mon;         /* months since January [0-11] */
	int     tm_year;        /* years since 1900 */
	int     tm_wday;        /* days since Sunday [0-6] */
	int     tm_yday;        /* days since January 1 [0-365] */
	int     tm_isdst;       /* Daylight Savings Time flag */
	long    tm_gmtoff;      /* offset from CUT in seconds */
	char    *tm_zone;       /* timezone abbreviation */
};

#include "cdefs.h"

__BEGIN_DECLS
char *asctime __P((const struct tm *));
clock_t clock __P((void));
char *ctime __P((const time_t *));
double difftime __P((time_t, time_t));
struct tm *gmtime __P((const time_t *));
struct tm *localtime __P((const time_t *));
time_t mktime __P((struct tm *));
size_t strftime __P((char *, size_t, const char *, const struct tm *));
time_t time __P((time_t *));

#ifndef _ANSI_SOURCE
void tzset __P((void));
#endif /* not ANSI */

#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
char *timezone __P((int, int));
void tzsetwall __P((void));
#endif /* neither ANSI nor POSIX */
__END_DECLS

#endif /* !_TIME_H_ */
uble difftime __P((time_aos/tzfile.h000064400010220000764000000132000620367670200132460ustar00deykembo00000000000000/* @(#) $Id: tzfile.h,v 1.4 1996/08/12 18:53:54 deyke Exp $ */

/*
 * Copyright (c) 1988 Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Arthur David Olson of the National Cancer Institute.
 *
 * 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.
 *
 *      @(#)tzfile.h    5.10 (Berkeley) 4/3/91
 */

#ifndef _TZFILE_H_
#define _TZFILE_H_

/*
 * Information about time zone files.
 */
			/* Time zone object file directory */
#define TZDIR           "/usr/share/zoneinfo"
#define TZDEFAULT       "/etc/localtime"
#define TZDEFRULES      "posixrules"

/*
** Each file begins with. . .
*/

struct tzhead {
	char    tzh_reserved[24];       /* reserved for future use */
	char    tzh_ttisstdcnt[4];      /* coded number of trans. time flags */
	char    tzh_leapcnt[4];         /* coded number of leap seconds */
	char    tzh_timecnt[4];         /* coded number of transition times */
	char    tzh_typecnt[4];         /* coded number of local time types */
	char    tzh_charcnt[4];         /* coded number of abbr. chars */
};

/*
** . . .followed by. . .
**
**      tzh_timecnt (char [4])s         coded transition times a la time(2)
**      tzh_timecnt (unsigned char)s    types of local time starting at above
**      tzh_typecnt repetitions of
**              one (char [4])          coded GMT offset in seconds
**              one (unsigned char)     used to set tm_isdst
**              one (unsigned char)     that's an abbreviation list index
**      tzh_charcnt (char)s             '\0'-terminated zone abbreviations
**      tzh_leapcnt repetitions of
**              one (char [4])          coded leap second transition times
**              one (char [4])          total correction after above
**      tzh_ttisstdcnt (char)s          indexed by type; if TRUE, transition
**                                      time is standard time, if FALSE,
**                                      transition time is wall clock time
**                                      if absent, transition times are
**                                      assumed to be wall clock time
*/

/*
** In the current implementation, "tzset()" refuses to deal with files that
** exceed any of the limits below.
*/

/*
** The TZ_MAX_TIMES value below is enough to handle a bit more than a
** year's worth of solar time (corrected daily to the nearest second) or
** 138 years of Pacific Presidential Election time
** (where there are three time zone transitions every fourth year).
*/
#define TZ_MAX_TIMES    370

#define NOSOLAR                 /* 4BSD doesn't currently handle solar time */

#ifndef NOSOLAR
#define TZ_MAX_TYPES    256     /* Limited by what (unsigned char)'s can hold */
#else
#define TZ_MAX_TYPES    10      /* Maximum number of local time types */
#endif

#define TZ_MAX_CHARS    50      /* Maximum number of abbreviation characters */

#define TZ_MAX_LEAPS    50      /* Maximum number of leap second corrections */

#define SECSPERMIN      60
#define MINSPERHOUR     60
#define HOURSPERDAY     24
#define DAYSPERWEEK     7
#define DAYSPERNYEAR    365
#define DAYSPERLYEAR    366
#define SECSPERHOUR     (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY      ((long) SECSPERHOUR * HOURSPERDAY)
#define MONSPERYEAR     12

#define TM_SUNDAY       0
#define TM_MONDAY       1
#define TM_TUESDAY      2
#define TM_WEDNESDAY    3
#define TM_THURSDAY     4
#define TM_FRIDAY       5
#define TM_SATURDAY     6

#define TM_JANUARY      0
#define TM_FEBRUARY     1
#define TM_MARCH        2
#define TM_APRIL        3
#define TM_MAY          4
#define TM_JUNE         5
#define TM_JULY         6
#define TM_AUGUST       7
#define TM_SEPTEMBER    8
#define TM_OCTOBER      9
#define TM_NOVEMBER     10
#define TM_DECEMBER     11

#define TM_YEAR_BASE    1900

#define EPOCH_YEAR      1970
#define EPOCH_WDAY      TM_THURSDAY

/*
** Accurate only for the past couple of centuries;
** that will probably do.
*/

#define isleap(y) (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0)

#endif /* !_TZFILE_H_ */
e TM_APRIL        3
#define TM_MAY          4
#define TM_JUNE         5
#define TM_JULY         6
#define TM_AUGUST       7
#define TM_SEPTEMBER    8
#define TM_OCTOBER      9
#define TM_NOVEMBER     10
#define TM_DECEMBER     11

#define TM_YEAR_BASE    1900

#define EPOCH_YEAR      1970
#define EPOCH_WDAY      TM_THURSDAY

/*
** Accurate only for the past couple of centuries;
** aos/Makefile000064400010220000764000000007070665365747600132700ustar00deykembo00000000000000# @(#) $Id: Makefile,v 1.13 1999/01/27 18:47:26 deyke Exp $

LIBRARY       = libaos.a

OBJS          = ctime.o \
		getcwd.o \
		putenv.o \
		setsid.o \
		strstr.o

all:;   @case "`uname -sr`" in \
	AOS*) . ../lib/configure.mak; $(MAKE) -i _all;; \
	esac

_all:   $(LIBRARY)

$(LIBRARY): $(OBJS)
	@echo "Loading $@ ..."
	@ar cru $@ $(OBJS)
	@ranlib $@ >/dev/null 2>&1

install:;

clean:; @rm -f *.o *.a *~ \#*\#
###
ctime.o: time.h ansi.h cdefs.h tzfile.h
/*
** Accurate only for the past couple of centuries;
** bbs/bbs.c000064400010220000764000002227410677101626700125160ustar00deykembo00000000000000static const char rcsid[] = "@(#) $Id: bbs.c,v 3.14 1999/09/18 23:13:59 deyke Exp $";

/* Bulletin Board System */

#if defined __cplusplus && defined __hpux
#define volatile
#endif

#include <sys/types.h>

#include <stdio.h>

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#ifdef ibm032

#include <sys/dir.h>
#include <sys/fcntl.h>
#include <sys/file.h>

typedef int pid_t;

#define dirent direct

#else

#include <dirent.h>
#include <sys/time.h>

#endif

extern char *optarg;
extern int optind;

#include "buildsaddr.h"
#include "callvalid.h"
#include "configure.h"
#include "lockfile.h"
#include "seteugid.h"
#include "strdup.h"
#include "strmatch.h"

#define DEBUG_NNTP      0

#define MIDSUFFIX               "@bbs.net"
#define NEWSGROUPSPREFIX        "ampr.bbs."
#define NEWSGROUPSPREFIXLENGTH  9               /* strlen(NEWSGROUPSPREFIX) */

#define BBSCONFIGFILE   "/tcp/bbs.conf"
#define BBSRCFILE       "/tcp/bbsrc"
#define HELPFILE        "/usr/local/lib/bbs.help"
#define LOCKDIR         "/tcp/locks"
#define MAILCONFIGFILE  "/tcp/mail.conf"
#define NEWSRCFILE      ".newsrc.bbs"
#define USERRCFILE      ".bbsrc"

#define BIDLOCKFILE     LOCKDIR "/bbs.bid"
#define FWDLOCKFILE     LOCKDIR "/bbs.fwd."     /* Append name of host */

#define SECONDS         (1L)
#define MINUTES         (60L*SECONDS)
#define HOURS           (60L*MINUTES)
#define DAYS            (24L*HOURS)

#define LEN_BID         12

enum e_level {
  USER,
  MBOX,
  ROOT
};

enum e_type {
  NEWS,
  MAIL
};

enum e_where {
  HEAD,
  TAIL
};

enum e_what {
  HEADER_ONLY,
  HEADER_AND_BODY
};

struct strlist {
  struct strlist *next;
  char str[1];
};

struct mail {
  char fromuser[1024];
  char fromhost[1024];
  char touser[1024];            /* Group, Board */
  char tohost[1024];            /* Distribution, At */
  char subject[1024];
  char bid[1024];
  char mid[1024];
  long date;
  int lifetime;
  struct strlist *head;
  struct strlist *tail;
};

struct group {
  char *name;
  int low;
  int high;
  int subscribed;
  int unread;
  char *bitarray;
  struct group *next;
};

static struct group *current_group;
static struct group *groups;

struct cmdtable {
  const char *name;
  void (*fnc)(int argc, const char **argv);
  int minargs;
  int maxargs;
  enum e_level level;
};

struct alias {
  char *name;
  char *value;
  struct alias *next;
};

static struct alias *aliases;

struct revision {
  char number[16];
  char date[16];
  char time[16];
  char author[16];
  char state[16];
};

static struct revision revision;

struct user {
  char *name;
  int uid;
  int gid;
  char *dir;
  char *shell;
};

static struct user user;

struct nntp_channel {
  int fd;
  int incnt;
  char *inptr;
  char inbuf[1024];
};

static struct nntp_channel nntp_channel = {
  -1
};

static char headers[1024] = "DFS";
static char mydomain[1024];
static char myhostname[1024];
static char prompt[1024] = "\\w:\\c > ";
static const char daynames[] = "SunMonTueWedThuFriSat";
static const char monthnames[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
static enum e_level level;
static int current_article;
static int did_forward;
static int do_forward;
static int errors;
static int export;
static int maxage = 7;
static int output_only;
static int packetcluster;
static volatile int stopped;

static void parse_command_line(const char *line, int add_argc, const char **add_argv, int recursion_level);

/*---------------------------------------------------------------------------*/

static void errorstop(int line)
{
  char buf[80];

  sprintf(buf, "Fatal error in line %d", line);
  perror(buf);
  fprintf(stderr, "Program stopped.\n");
  exit(1);
}

/*---------------------------------------------------------------------------*/

#define halt() errorstop(__LINE__)

/*---------------------------------------------------------------------------*/

static void inc_errors(void)
{
  errors++;
  if (level == MBOX && errors >= 3)
    exit(1);
}

/*---------------------------------------------------------------------------*/

#define set_read(p, i) \
	(p)->bitarray[((i) - (p)->low) >> 3] |= (1 << (((i) - (p)->low) & 7))

/*---------------------------------------------------------------------------*/

#define unset_read(p, i) \
	(p)->bitarray[((i) - (p)->low) >> 3] &= ~(1 << (((i) - (p)->low) & 7))

/*---------------------------------------------------------------------------*/

#define is_read(p, i) \
	((p)->bitarray[((i) - (p)->low) >> 3] & (1 << (((i) - (p)->low) & 7)))

/*---------------------------------------------------------------------------*/

/* Use private function because some platforms are broken, eg 386BSD */

static int Xtolower(int c)
{
  return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
}

/*---------------------------------------------------------------------------*/

/* Use private function because some platforms are broken, eg 386BSD */

static int Xtoupper(int c)
{
  return (c >= 'a' && c <= 'z') ? (c - 'a' + 'A') : c;
}

/*---------------------------------------------------------------------------*/

static char *strupc(char *s)
{
  char *p;

  for (p = s; (*p = Xtoupper(*p)); p++) ;
  return s;
}

/*---------------------------------------------------------------------------*/

static char *strlwc(char *s)
{
  char *p;

  for (p = s; (*p = Xtolower(*p)); p++) ;
  return s;
}

/*---------------------------------------------------------------------------*/

static int Strcasecmp(const char *s1, const char *s2)
{
  while (Xtolower(*s1) == Xtolower(*s2)) {
    if (!*s1) return 0;
    s1++;
    s2++;
  }
  return Xtolower(*s1) - Xtolower(*s2);
}

/*---------------------------------------------------------------------------*/

static int Strncasecmp(const char *s1, const char *s2, int n)
{
  while (--n >= 0 && Xtolower(*s1) == Xtolower(*s2)) {
    if (!*s1) return 0;
    s1++;
    s2++;
  }
  return n < 0 ? 0 : Xtolower(*s1) - Xtolower(*s2);
}

/*---------------------------------------------------------------------------*/

static int stringcasematch(const char *s, const char *p)
{

  char pat[1024];
  char str[1024];
  char *t;
  const char *f;

  t = str;
  for (f = s; *f; f++) {
    *t++ = Xtolower(*f);
  }
  *t = 0;

  t = pat;
  for (f = p; *f; f++) {
    *t++ = Xtolower(*f);
  }
  *t = 0;

  return stringmatch(str, pat);
}

/*---------------------------------------------------------------------------*/

static char *strtrim(char *s)
{
  char *p;

  for (p = s; *p; p++) ;
  while (--p >= s && isspace(*p & 0xff)) ;
  p[1] = 0;
  return s;
}

/*---------------------------------------------------------------------------*/

static char *rip(char *s)
{
  char *p;

  for (p = s; *p; p++) ;
  while (--p >= s && (*p == '\r' || *p == '\n')) ;
  p[1] = 0;
  return s;
}

/*---------------------------------------------------------------------------*/

static struct strlist *alloc_string(const char *s)
{
  s